[pypy-commit] pypy default: (cfbolz, arigo)

arigo noreply at buildbot.pypy.org
Fri Nov 25 17:11:02 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r49791:b78a605fb452
Date: 2011-11-25 17:04 +0100
http://bitbucket.org/pypy/pypy/changeset/b78a605fb452/

Log:	(cfbolz, arigo)

	An equivalent refactoring for id(). Also fixes an extremely obscure
	failure.

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -191,6 +191,9 @@
     def is_w(self, space, w_other):
         return self is w_other
 
+    def id(self, space):
+        return space.wrap(compute_unique_id(self))
+
     def str_w(self, space):
         w_msg = typed_unwrap_error_msg(space, "string", self)
         raise OperationError(space.w_TypeError, w_msg)
@@ -693,6 +696,9 @@
         # "if x is object").
         return w_two.is_w(self, w_one)
 
+    def id(self, w_obj):
+        return w_obj.id(self)
+
     def hash_w(self, w_obj):
         """shortcut for space.int_w(space.hash(w_obj))"""
         return self.int_w(self.hash(w_obj))
@@ -1031,9 +1037,6 @@
     def isinstance_w(self, w_obj, w_type):
         return self.is_true(self.isinstance(w_obj, w_type))
 
-    def id(self, w_obj):
-        return self.wrap(compute_unique_id(w_obj))
-
     # The code below only works
     # for the simple case (new-style instance).
     # These methods are patched with the full logic by the __builtin__
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
@@ -5,6 +5,7 @@
 from pypy.objspace.std.register_all import register_all
 from pypy.objspace.std.floatobject import W_FloatObject, _hash_float
 from pypy.objspace.std.longobject import W_LongObject
+from pypy.rlib.rbigint import rbigint
 from pypy.rlib.rfloat import (
     formatd, DTSF_STR_PRECISION, isinf, isnan, copysign)
 
@@ -30,6 +31,18 @@
         imag2 = float2longlong(imag2)
         return real1 == real2 and imag1 == imag2
 
+    def id(self, space):
+        if self.user_overridden_class:
+            return W_Object.id(self, space)
+        from pypy.rlib.longlong2float import float2longlong
+        from pypy.objspace.std.model import IDTAG_COMPLEX as tag
+        real = space.float_w(space.getattr(self, space.wrap("real")))
+        imag = space.float_w(space.getattr(self, space.wrap("imag")))
+        real_b = rbigint.fromrarith_int(float2longlong(real))
+        imag_b = rbigint.fromrarith_int(float2longlong(imag))
+        val = real_b.lshift(64).or_(imag_b).lshift(3).or_(rbigint.fromint(tag))
+        return space.newlong_from_rbigint(val)
+
 
 class W_ComplexObject(W_AbstractComplexObject):
     """This is a reimplementation of the CPython "PyComplexObject"
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
@@ -34,11 +34,20 @@
         two = float2longlong(space.float_w(w_other))
         return one == two
 
+    def id(self, space):
+        if self.user_overridden_class:
+            return W_Object.id(self, space)
+        from pypy.rlib.longlong2float import float2longlong
+        from pypy.objspace.std.model import IDTAG_FLOAT as tag
+        val = float2longlong(space.float_w(self))
+        b = rbigint.fromrarith_int(val)
+        b = b.lshift(3).or_(rbigint.fromint(tag))
+        return space.newlong_from_rbigint(b)
+
 
 class W_FloatObject(W_AbstractFloatObject):
-    """This is a reimplementation of the CPython "PyFloatObject"
-       it is assumed that the constructor takes a real Python float as
-       an argument"""
+    """This is a implementation of the app-level 'float' type.
+    The constructor takes an RPython float as an argument."""
     from pypy.objspace.std.floattype import float_typedef as typedef
     _immutable_fields_ = ['floatval']
 
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -26,6 +26,14 @@
             return self is w_other
         return space.int_w(self) == space.int_w(w_other)
 
+    def id(self, space):
+        if self.user_overridden_class:
+            return W_Object.id(self, space)
+        from pypy.objspace.std.model import IDTAG_INT as tag
+        b = space.bigint_w(self)
+        b = b.lshift(3).or_(rbigint.fromint(tag))
+        return space.newlong_from_rbigint(b)
+
 
 class W_IntObject(W_AbstractIntObject):
     __slots__ = 'intval'
diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py
--- a/pypy/objspace/std/longobject.py
+++ b/pypy/objspace/std/longobject.py
@@ -18,6 +18,14 @@
             return self is w_other
         return space.bigint_w(self).eq(space.bigint_w(w_other))
 
+    def id(self, space):
+        if self.user_overridden_class:
+            return W_Object.id(self, space)
+        from pypy.objspace.std.model import IDTAG_LONG as tag
+        b = space.bigint_w(self)
+        b = b.lshift(3).or_(rbigint.fromint(tag))
+        return space.newlong_from_rbigint(b)
+
 
 class W_LongObject(W_AbstractLongObject):
     """This is a wrapper of rbigint."""
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -29,6 +29,11 @@
                     "proxyobject.W_TransparentDict"],
 }
 
+IDTAG_INT     = 1
+IDTAG_LONG    = 3
+IDTAG_FLOAT   = 5
+IDTAG_COMPLEX = 7
+
 class StdTypeModel:
 
     def __init__(self, config):
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -453,38 +453,6 @@
                                  self.wrap("Expected tuple of length 3"))
         return self.int_w(l_w[0]), self.int_w(l_w[1]), self.int_w(l_w[2])
 
-    def id(self, w_obj):
-        from pypy.rlib.rbigint import rbigint
-        from pypy.rlib import objectmodel
-        from pypy.rlib.longlong2float import float2longlong
-        w_type = self.type(w_obj)
-        if w_type is self.w_int:
-            tag = 1
-            return self.or_(self.lshift(w_obj, self.wrap(3)), self.wrap(tag))
-        elif w_type is self.w_long:
-            tag = 3
-            return self.or_(self.lshift(w_obj, self.wrap(3)), self.wrap(tag))
-        elif w_type is self.w_float:
-            tag = 5
-            val = float2longlong(self.float_w(w_obj))
-            w_obj = self.newlong_from_rbigint(rbigint.fromrarith_int(val))
-            return self.or_(self.lshift(w_obj, self.wrap(3)), self.wrap(tag))
-        elif w_type is self.w_complex:
-            real = self.float_w(self.getattr(w_obj, self.wrap("real")))
-            imag = self.float_w(self.getattr(w_obj, self.wrap("imag")))
-            tag = 5
-            real_b = rbigint.fromrarith_int(float2longlong(real))
-            imag_b = rbigint.fromrarith_int(float2longlong(imag))
-            val = real_b.lshift(8 * 8).or_(imag_b).lshift(3).or_(rbigint.fromint(3))
-            return self.newlong_from_rbigint(val)
-        elif w_type is self.w_str:
-            res = objectmodel.compute_unique_id(self.str_w(w_obj))
-        elif w_type is self.w_unicode:
-            res = objectmodel.compute_unique_id(self.unicode_w(w_obj))
-        else:
-            res = objectmodel.compute_unique_id(w_obj)
-        return self.wrap(res)
-
     def is_true(self, w_obj):
         # a shortcut for performance
         # NOTE! this method is typically overridden by builtinshortcut.py.
diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -5,6 +5,7 @@
 from pypy.interpreter import gateway
 from pypy.rlib.rarithmetic import ovfcheck
 from pypy.rlib.objectmodel import we_are_translated, compute_hash, specialize
+from pypy.rlib.objectmodel import compute_unique_id
 from pypy.objspace.std.inttype import wrapint
 from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
 from pypy.objspace.std import slicetype, newformat
@@ -31,6 +32,11 @@
             return False
         return space.str_w(self) is space.str_w(w_other)
 
+    def id(self, space):
+        if self.user_overridden_class:
+            return W_Object.id(self, space)
+        return space.wrap(compute_unique_id(space.str_w(self)))
+
 
 class W_StringObject(W_AbstractStringObject):
     from pypy.objspace.std.stringtype import str_typedef as typedef
diff --git a/pypy/objspace/std/test/test_obj.py b/pypy/objspace/std/test/test_obj.py
--- a/pypy/objspace/std/test/test_obj.py
+++ b/pypy/objspace/std/test/test_obj.py
@@ -248,6 +248,12 @@
                 if a is b:
                     assert a == b
 
+    def test_identity_bug(self):
+        x = 0x4000000000000000L
+        y = 2j
+        assert id(x) != id(y)
+
+
 def test_isinstance_shortcut():
     from pypy.objspace.std import objspace
     space = objspace.StdObjSpace()
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -11,6 +11,7 @@
 from pypy.objspace.std.tupleobject import W_TupleObject
 from pypy.rlib.rarithmetic import intmask, ovfcheck
 from pypy.rlib.objectmodel import compute_hash, specialize
+from pypy.rlib.objectmodel import compute_unique_id
 from pypy.rlib.rstring import UnicodeBuilder
 from pypy.rlib.runicode import unicode_encode_unicode_escape
 from pypy.module.unicodedata import unicodedb
@@ -31,6 +32,11 @@
             return False
         return space.unicode_w(self) is space.unicode_w(w_other)
 
+    def id(self, space):
+        if self.user_overridden_class:
+            return W_Object.id(self, space)
+        return space.wrap(compute_unique_id(space.unicode_w(self)))
+
 
 class W_UnicodeObject(W_AbstractUnicodeObject):
     from pypy.objspace.std.unicodetype import unicode_typedef as typedef


More information about the pypy-commit mailing list