Author: Carl Friedrich Bolz <cfb...@gmx.de> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit