Re: Pyrex Digest, Vol 58, Issue 5
John Arbash Meinel <[email protected]> Wed, 14 Oct 2009 09:28:22 -0500
| Newsgroups | gmane.comp.python.pyrex |
|---|---|
| Message-ID | <[email protected]> |
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Claudio Freire wrote: > = > = > From: John Arbash Meinel <[email protected] > <mailto:[email protected]>> > = > It seems pyrex 0.9.8.5 has a bug with how it handles "hash()". I have > this code: > = > cdef long the_hash > = > the_hash =3D hash(my_object) > = > = > Shouldn't that be cdef long long the_hash ? > = Well, if you look at the api: http://docs.python.org/c-api/object.html#PyObject_Hash long PyObject_Hash(PyObject *o) I'm pretty sure that is just a 'long'. On the platforms *I* have compiled on. The types are: 32-bit: int 32-bits long 32-bits long long 64-bits 64-bit: int 32-bits long 64-bits long long ? (I think 64-bits) hashes are defined to be 'long' types, not 'long long'. The issue is that pyrex 0.9.7.2 and cython 0.11.3 properly translate: hash(my_object) into long __pyx_1; long __pyx_v_the_hash; __pyx_1 =3D PyObject_Hash(obj); __pyx_v_the_hash =3D __pyx_1; However, in pyrex 0.9.8.5 it changes the above definition to: int __pyx_1; ... # the rest is the same Which means that it propagates the 'long' hash value through an 'int' before placing it back in a 'long'. And on the 64-bit machines I've tested on, this truncates the value, such that: cdef extern from "Python.h": long PyObject_Hash(object) def test_hash(obj): cdef long the_hash the_hash =3D hash(obj) assert the_hash =3D=3D PyObject_Hash(obj) ^- This fails w/ pyrex 0.9.8.5 on a 64-bit machine, and say a 'tuple' which uses >32-bits for its hash if available. John =3D:-> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (Cygwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkrV4AYACgkQJdeBCYSNAAO3QQCg2WAwUrlUCxGiWWbybOIrQpTT ek4AoIQeW4WYKnd1QrsGoeBhCGO839+k =3Db6r+ -----END PGP SIGNATURE-----