Author: Carl Friedrich Bolz <[email protected]>
Branch:
Changeset: r82793:666871b885d9
Date: 2016-03-05 17:58 +0100
http://bitbucket.org/pypy/pypy/changeset/666871b885d9/
Log: make method identity the same as equality (since people seem to do
stuff like cls.__repr__ is object.__repr__, see issue #2253)
diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py
--- a/pypy/interpreter/function.py
+++ b/pypy/interpreter/function.py
@@ -13,6 +13,9 @@
from pypy.interpreter.argument import Arguments
from rpython.rlib import jit
+from rpython.rlib.rarithmetic import LONG_BIT
+from rpython.rlib.rbigint import rbigint
+
funccallunrolling = unrolling_iterable(range(4))
@@ -557,6 +560,26 @@
return space.w_False
return space.eq(self.w_function, w_other.w_function)
+ def is_w(self, space, other):
+ if not isinstance(other, Method):
+ return False
+ return (self.w_instance is other.w_instance and
+ self.w_function is other.w_function and
+ self.w_class is other.w_class)
+
+ def immutable_unique_id(self, space):
+ from pypy.objspace.std.util import IDTAG_METHOD as tag
+ from pypy.objspace.std.util import IDTAG_SHIFT
+ if self.w_instance is not None:
+ id = space.bigint_w(space.id(self.w_instance))
+ id.lshift(LONG_BIT)
+ else:
+ id = rbigint.fromint(0)
+ id = id.or_(space.bigint_w(space.id(self.w_function)))
+ id = id.lshift(LONG_BIT).or_(space.bigint_w(space.id(self.w_class)))
+ id = id.lshift(IDTAG_SHIFT).int_or_(tag)
+ return space.newlong_from_rbigint(id)
+
def descr_method_hash(self):
space = self.space
w_result = space.hash(self.w_function)
diff --git a/pypy/interpreter/test/test_function.py
b/pypy/interpreter/test/test_function.py
--- a/pypy/interpreter/test/test_function.py
+++ b/pypy/interpreter/test/test_function.py
@@ -552,6 +552,37 @@
assert A().m == X()
assert X() == A().m
+ @pytest.mark.skipif("config.option.runappdirect")
+ def test_method_identity(self):
+ class A(object):
+ def m(self):
+ pass
+ def n(self):
+ pass
+
+ class B(A):
+ pass
+
+ class X(object):
+ def __eq__(self, other):
+ return True
+
+ a = A()
+ a2 = A()
+ assert a.m is a.m
+ assert id(a.m) == id(a.m)
+ assert a.m is not a.n
+ assert id(a.m) != id(a.n)
+ assert a.m is not a2.m
+ assert id(a.m) != id(a2.m)
+
+ assert A.m is A.m
+ assert id(A.m) == id(A.m)
+ assert A.m is not A.n
+ assert id(A.m) != id(A.n)
+ assert A.m is not B.m
+ assert id(A.m) != id(B.m)
+
class TestMethod:
def setup_method(self, method):
diff --git a/pypy/objspace/std/util.py b/pypy/objspace/std/util.py
--- a/pypy/objspace/std/util.py
+++ b/pypy/objspace/std/util.py
@@ -2,12 +2,13 @@
from pypy.interpreter.error import OperationError, oefmt
-IDTAG_SHIFT = 3
+IDTAG_SHIFT = 4
IDTAG_INT = 1
IDTAG_LONG = 3
IDTAG_FLOAT = 5
IDTAG_COMPLEX = 7
+IDTAG_METHOD = 9
CMP_OPS = dict(lt='<', le='<=', eq='==', ne='!=', gt='>', ge='>=')
BINARY_BITWISE_OPS = {'and': '&', 'lshift': '<<', 'or': '|', 'rshift': '>>',
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit