[pypy-commit] pypy py3k: Implement sys.hash_info. Initial patch by chronitis, thanks!
amauryfa
noreply at buildbot.pypy.org
Wed Nov 23 00:18:48 CET 2011
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3k
Changeset: r49675:aa1d34b5a927
Date: 2011-11-23 00:10 +0100
http://bitbucket.org/pypy/pypy/changeset/aa1d34b5a927/
Log: Implement sys.hash_info. Initial patch by chronitis, thanks!
diff --git a/pypy/module/sys/__init__.py b/pypy/module/sys/__init__.py
--- a/pypy/module/sys/__init__.py
+++ b/pypy/module/sys/__init__.py
@@ -78,6 +78,7 @@
'float_info' : 'system.get_float_info(space)',
'int_info' : 'system.get_int_info(space)',
+ 'hash_info' : 'system.get_hash_info(space)',
'float_repr_style' : 'system.get_float_repr_style(space)'
}
diff --git a/pypy/module/sys/system.py b/pypy/module/sys/system.py
--- a/pypy/module/sys/system.py
+++ b/pypy/module/sys/system.py
@@ -1,8 +1,8 @@
"""Information about the current system."""
from pypy.interpreter import gateway
from pypy.rlib import rfloat, rbigint
-from pypy.rpython.lltypesystem import rffi
-
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.rlib.objectmodel import HASH_INF, HASH_NAN, HASH_IMAG
app = gateway.applevel("""
"NOT_RPYTHON"
@@ -24,6 +24,13 @@
class int_info(metaclass=structseqtype):
bits_per_digit = structseqfield(0)
sizeof_digit = structseqfield(1)
+
+class hash_info(metaclass=structseqtype):
+ width = structseqfield(0)
+ modulus = structseqfield(1)
+ inf = structseqfield(2)
+ nan = structseqfield(3)
+ imag = structseqfield(4)
""")
@@ -55,6 +62,19 @@
w_int_info = app.wget(space, "int_info")
return space.call_function(w_int_info, space.newtuple(info_w))
+def get_hash_info(space):
+ # XXX our _hash_float() always give values that fit in 32bit
+ modulus = (1 << 31) - 1 # Must be a prime number
+ info_w = [
+ space.wrap(8 * rffi.sizeof(lltype.Signed)),
+ space.wrap(modulus),
+ space.wrap(HASH_INF),
+ space.wrap(HASH_NAN),
+ space.wrap(HASH_IMAG),
+ ]
+ w_hash_info = app.wget(space, "hash_info")
+ return space.call_function(w_hash_info, space.newtuple(info_w))
+
def get_float_repr_style(space):
if rfloat.USE_SHORT_FLOAT_REPR:
return space.wrap("short")
diff --git a/pypy/module/sys/test/test_sysmodule.py b/pypy/module/sys/test/test_sysmodule.py
--- a/pypy/module/sys/test/test_sysmodule.py
+++ b/pypy/module/sys/test/test_sysmodule.py
@@ -127,6 +127,18 @@
assert isinstance(li.bits_per_digit, int)
assert isinstance(li.sizeof_digit, int)
+ def test_hash_info(self):
+ import sys
+ li = sys.hash_info
+ assert isinstance(li.width, int)
+ assert isinstance(li.modulus, int)
+ assert isinstance(li.inf, int)
+ assert isinstance(li.nan, int)
+ assert isinstance(li.imag, int)
+ print(li)
+ sys.stdout.flush()
+ assert 0
+
class AppTestSysModulePortedFromCPython:
def setup_class(cls):
diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py
--- a/pypy/objspace/std/complexobject.py
+++ b/pypy/objspace/std/complexobject.py
@@ -7,6 +7,7 @@
from pypy.objspace.std.longobject import W_LongObject
from pypy.rlib.rfloat import (
formatd, DTSF_STR_PRECISION, isinf, isnan, copysign)
+from pypy.rlib.objectmodel import HASH_IMAG
import math
@@ -127,7 +128,7 @@
def hash__Complex(space, w_value):
hashreal = _hash_float(space, w_value.realval)
hashimg = _hash_float(space, w_value.imagval)
- combined = hashreal + 1000003 * hashimg
+ combined = hashreal + HASH_IMAG * hashimg
return space.newint(combined)
def add__Complex_Complex(space, w_complex1, w_complex2):
diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py
--- a/pypy/objspace/std/floatobject.py
+++ b/pypy/objspace/std/floatobject.py
@@ -14,6 +14,7 @@
DTSF_ADD_DOT_0, DTSF_STR_PRECISION)
from pypy.rlib.rbigint import rbigint
from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib.objectmodel import HASH_INF, HASH_NAN
from pypy.rlib import rfloat
from pypy.tool.sourcetools import func_with_new_name
@@ -272,7 +273,7 @@
from pypy.objspace.std.longobject import hash__Long
if isnan(v):
- return 0
+ return HASH_NAN
# This is designed so that Python numbers of different types
# that compare equal hash to the same value; otherwise comparisons
@@ -292,9 +293,9 @@
except OverflowError:
# can't convert to long int -- arbitrary
if v < 0:
- return -271828
+ return -HASH_INF
else:
- return 314159
+ return HASH_INF
return space.int_w(space.hash(w_lval))
# The fractional part is non-zero, so we don't have to worry about
diff --git a/pypy/objspace/std/test/test_floatobject.py b/pypy/objspace/std/test/test_floatobject.py
--- a/pypy/objspace/std/test/test_floatobject.py
+++ b/pypy/objspace/std/test/test_floatobject.py
@@ -104,7 +104,7 @@
# testing special overflow values
inf = 1e200 * 1e200
assert hash(inf) == 314159
- assert hash(-inf) == -271828
+ assert hash(-inf) == -314159
assert hash(inf/inf) == 0
def test_int_float(self):
diff --git a/pypy/rlib/objectmodel.py b/pypy/rlib/objectmodel.py
--- a/pypy/rlib/objectmodel.py
+++ b/pypy/rlib/objectmodel.py
@@ -321,6 +321,10 @@
x ^= length
return intmask(x)
+HASH_INF = 314159
+HASH_NAN = 0
+HASH_IMAG = 1000003
+
def _hash_float(f):
"""The algorithm behind compute_hash() for a float.
This implementation is identical to the CPython implementation,
@@ -332,11 +336,11 @@
if not isfinite(f):
if isinf(f):
if f < 0.0:
- return -271828
+ return -HASH_INF
else:
- return 314159
+ return HASH_INF
else: #isnan(f):
- return 0
+ return HASH_NAN
v, expo = math.frexp(f)
v *= TAKE_NEXT
hipart = int(v)
More information about the pypy-commit
mailing list