[Pyrex] Pyrex Digest, Vol 58, Issue 5

John Arbash Meinel john at arbash-meinel.com
Wed Oct 14 16:28:22 CEST 2009


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Claudio Freire wrote:
> 
> 
>     From: John Arbash Meinel <john at arbash-meinel.com
>     <mailto:john at arbash-meinel.com>>
> 
>     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 = 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 = PyObject_Hash(obj);
__pyx_v_the_hash = __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 = hash(obj)
  assert the_hash == 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
=:->

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkrV4AYACgkQJdeBCYSNAAO3QQCg2WAwUrlUCxGiWWbybOIrQpTT
ek4AoIQeW4WYKnd1QrsGoeBhCGO839+k
=b6r+
-----END PGP SIGNATURE-----



More information about the Pyrex mailing list