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-----