Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r49790:0bb2bc25fcfc Date: 2011-11-25 16:22 +0100 http://bitbucket.org/pypy/pypy/changeset/0bb2bc25fcfc/
Log: (cfbolz, arigo) Un- and re-hack the implementation of space.is_w(). This version might be faster. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -188,6 +188,9 @@ # ------------------------------------------------------------------- + def is_w(self, space, w_other): + return self is w_other + def str_w(self, space): w_msg = typed_unwrap_error_msg(space, "string", self) raise OperationError(space.w_TypeError, w_msg) @@ -681,9 +684,14 @@ """shortcut for space.is_true(space.eq(w_obj1, w_obj2))""" return self.is_w(w_obj1, w_obj2) or self.is_true(self.eq(w_obj1, w_obj2)) - def is_w(self, w_obj1, w_obj2): - """shortcut for space.is_true(space.is_(w_obj1, w_obj2))""" - return self.is_true(self.is_(w_obj1, w_obj2)) + def is_(self, w_one, w_two): + return self.newbool(self.is_w(w_one, w_two)) + + def is_w(self, w_one, w_two): + # done by a method call on w_two (and not on w_one, because of the + # expected programming style where we say "if x is None" or + # "if x is object"). + return w_two.is_w(self, w_one) def hash_w(self, w_obj): """shortcut for space.int_w(space.hash(w_obj))""" 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 @@ -10,7 +10,28 @@ import math -class W_ComplexObject(W_Object): + +class W_AbstractComplexObject(W_Object): + __slots__ = () + + def is_w(self, space, w_other): + from pypy.rlib.longlong2float import float2longlong + if not isinstance(w_other, W_AbstractComplexObject): + return False + if self.user_overridden_class or w_other.user_overridden_class: + return self is w_other + real1 = space.float_w(space.getattr(self, space.wrap("real"))) + real2 = space.float_w(space.getattr(w_other, space.wrap("real"))) + imag1 = space.float_w(space.getattr(self, space.wrap("imag"))) + imag2 = space.float_w(space.getattr(w_other, space.wrap("imag"))) + real1 = float2longlong(real1) + real2 = float2longlong(real2) + imag1 = float2longlong(imag1) + imag2 = float2longlong(imag2) + return real1 == real2 and imag1 == imag2 + + +class W_ComplexObject(W_AbstractComplexObject): """This is a reimplementation of the CPython "PyComplexObject" """ from pypy.objspace.std.complextype import complex_typedef as typedef 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 @@ -21,7 +21,21 @@ import math from pypy.objspace.std.intobject import W_IntObject -class W_FloatObject(W_Object): +class W_AbstractFloatObject(W_Object): + __slots__ = () + + def is_w(self, space, w_other): + from pypy.rlib.longlong2float import float2longlong + if not isinstance(w_other, W_AbstractFloatObject): + return False + if self.user_overridden_class or w_other.user_overridden_class: + return self is w_other + one = float2longlong(space.float_w(self)) + two = float2longlong(space.float_w(w_other)) + return one == two + + +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""" 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 @@ -19,6 +19,14 @@ class W_AbstractIntObject(W_Object): __slots__ = () + def is_w(self, space, w_other): + if not isinstance(w_other, W_AbstractIntObject): + return False + if self.user_overridden_class or w_other.user_overridden_class: + return self is w_other + return space.int_w(self) == space.int_w(w_other) + + class W_IntObject(W_AbstractIntObject): __slots__ = 'intval' _immutable_fields_ = ['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 @@ -11,6 +11,14 @@ class W_AbstractLongObject(W_Object): __slots__ = () + def is_w(self, space, w_other): + if not isinstance(w_other, W_AbstractLongObject): + return False + if self.user_overridden_class or w_other.user_overridden_class: + return self is w_other + return space.bigint_w(self).eq(space.bigint_w(w_other)) + + class W_LongObject(W_AbstractLongObject): """This is a wrapper of rbigint.""" from pypy.objspace.std.longtype import long_typedef as typedef 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,45 +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 is_(self, w_one, w_two): - return self.newbool(self.is_w(w_one, w_two)) - - def is_w(self, w_one, w_two): - from pypy.rlib.longlong2float import float2longlong - w_typeone = self.type(w_one) - # cannot use self.is_w here to not get infinite recursion - if w_typeone is self.w_int: - return (self.type(w_two) is self.w_int and - self.int_w(w_one) == self.int_w(w_two)) - elif w_typeone is self.w_float: - if self.type(w_two) is not self.w_float: - return False - one = float2longlong(self.float_w(w_one)) - two = float2longlong(self.float_w(w_two)) - return one == two - elif w_typeone is self.w_long: - return (self.type(w_two) is self.w_long and - self.bigint_w(w_one).eq(self.bigint_w(w_two))) - elif w_typeone is self.w_complex: - if self.type(w_two) is not self.w_complex: - return False - real1 = self.float_w(self.getattr(w_one, self.wrap("real"))) - real2 = self.float_w(self.getattr(w_two, self.wrap("real"))) - imag1 = self.float_w(self.getattr(w_one, self.wrap("imag"))) - imag2 = self.float_w(self.getattr(w_two, self.wrap("imag"))) - real1 = float2longlong(real1) - real2 = float2longlong(real2) - imag1 = float2longlong(imag1) - imag2 = float2longlong(imag2) - return real1 == real2 and imag1 == imag2 - elif w_typeone is self.w_str: - return (self.type(w_two) is self.w_str and - self.str_w(w_one) is self.str_w(w_two)) - elif w_typeone is self.w_unicode: - return (self.type(w_two) is self.w_unicode and - self.unicode_w(w_one) is self.unicode_w(w_two)) - return w_one is w_two - def id(self, w_obj): from pypy.rlib.rbigint import rbigint from pypy.rlib import objectmodel 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 @@ -22,6 +22,16 @@ class W_AbstractStringObject(W_Object): __slots__ = () + def is_w(self, space, w_other): + if not isinstance(w_other, W_AbstractStringObject): + return False + if self is w_other: + return True + if self.user_overridden_class or w_other.user_overridden_class: + return False + return space.str_w(self) is space.str_w(w_other) + + class W_StringObject(W_AbstractStringObject): from pypy.objspace.std.stringtype import str_typedef as typedef _immutable_fields_ = ['_value'] 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 @@ -147,6 +147,28 @@ s = "a" assert self.unwrap_wrap_str(s) is s + def test_is_on_subclasses(self): + for typ in [int, long, float, complex, str, unicode]: + class mytyp(typ): + pass + if not self.cpython_apptest and typ not in (str, unicode): + assert typ(42) is typ(42) + assert mytyp(42) is not mytyp(42) + assert mytyp(42) is not typ(42) + assert typ(42) is not mytyp(42) + x = mytyp(42) + assert x is x + assert x is not "43" + assert x is not None + assert "43" is not x + assert None is not x + x = typ(42) + assert x is x + assert x is not "43" + assert x is not None + assert "43" is not x + assert None is not x + def test_id_on_primitives(self): if self.cpython_apptest: skip("cpython behaves differently") 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 @@ -22,6 +22,16 @@ class W_AbstractUnicodeObject(W_Object): __slots__ = () + def is_w(self, space, w_other): + if not isinstance(w_other, W_AbstractUnicodeObject): + return False + if self is w_other: + return True + if self.user_overridden_class or w_other.user_overridden_class: + return False + return space.unicode_w(self) is space.unicode_w(w_other) + + class W_UnicodeObject(W_AbstractUnicodeObject): from pypy.objspace.std.unicodetype import unicode_typedef as typedef _immutable_fields_ = ['_value'] _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit