4
4
_testcapi = import_helper .import_module ('_testcapi' )
5
5
6
6
7
- SIZEOF_PY_HASH_T = _testcapi .SIZEOF_VOID_P
7
+ SIZEOF_VOID_P = _testcapi .SIZEOF_VOID_P
8
+ SIZEOF_PY_HASH_T = SIZEOF_VOID_P
8
9
9
10
10
11
class CAPITest (unittest .TestCase ):
@@ -36,10 +37,8 @@ def test_hash_pointer(self):
36
37
# Test PyHash_Pointer()
37
38
hash_pointer = _testcapi .hash_pointer
38
39
39
- HASH_BITS = 8 * _testcapi .SIZEOF_VOID_P
40
- UHASH_T_MASK = ((2 ** HASH_BITS ) - 1 )
41
- HASH_T_MAX = (2 ** (HASH_BITS - 1 ) - 1 )
42
- MAX_PTR = UHASH_T_MASK
40
+ UHASH_T_MASK = ((2 ** (8 * SIZEOF_PY_HASH_T )) - 1 )
41
+ HASH_T_MAX = (2 ** (8 * SIZEOF_PY_HASH_T - 1 ) - 1 )
43
42
44
43
def uhash_to_hash (x ):
45
44
# Convert unsigned Py_uhash_t to signed Py_hash_t
@@ -49,12 +48,25 @@ def uhash_to_hash(x):
49
48
x = (~ x ) + 1
50
49
return x
51
50
52
- # Known values
51
+ # PyHash_Pointer() rotates the pointer bits by 4 bits to the right
52
+ if SIZEOF_VOID_P == 8 :
53
+ self .assertEqual (hash_pointer (0xABCDEF1234567890 ),
54
+ 0x0ABCDEF123456789 )
55
+ self .assertEqual (hash_pointer (0x1234567890ABCDEF ),
56
+ uhash_to_hash (0xF1234567890ABCDE ))
57
+ self .assertEqual (hash_pointer (0xFEE4ABEDD1CECA5E ),
58
+ uhash_to_hash (0xEFEE4ABEDD1CECA5 ))
59
+ else :
60
+ self .assertEqual (hash_pointer (0x12345678 ),
61
+ uhash_to_hash (0x81234567 ))
62
+ self .assertEqual (hash_pointer (0x1234ABCD ),
63
+ uhash_to_hash (0xD1234ABC ))
64
+ self .assertEqual (hash_pointer (0xDEADCAFE ),
65
+ uhash_to_hash (0xEDEADCAF ))
66
+
67
+ # PyHash_Pointer(NULL) returns 0
53
68
self .assertEqual (hash_pointer (0 ), 0 )
54
- self .assertEqual (hash_pointer (MAX_PTR ), - 2 )
55
- self .assertEqual (hash_pointer (0xABCDEF1234567890 ),
56
- 0x0ABCDEF123456789 )
57
- self .assertEqual (hash_pointer (0x1234567890ABCDEF ),
58
- uhash_to_hash (0xF1234567890ABCDE ))
59
- self .assertEqual (hash_pointer (0xFEE4ABEDD1CECA5E ),
60
- uhash_to_hash (0xEFEE4ABEDD1CECA5 ))
69
+
70
+ # PyHash_Pointer((void*)(uintptr_t)-1) doesn't return -1 but -2
71
+ VOID_P_MAX = - 1 & (2 ** (8 * SIZEOF_VOID_P ) - 1 )
72
+ self .assertEqual (hash_pointer (VOID_P_MAX ), - 2 )
0 commit comments