Author: Armin Rigo <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit