Author: Armin Rigo <ar...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit