Author: Antonio Cuni <anto.c...@gmail.com> Branch: Changeset: r46015:bb9c6a2bd529 Date: 2011-07-27 14:39 +0200 http://bitbucket.org/pypy/pypy/changeset/bb9c6a2bd529/
Log: (Alex_Gaynor, antocuni): special-case type.__eq__ so that type (and subclasses) are marked as compares_by_identity() diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -35,6 +35,13 @@ return w_hash object_hash._annspecialcase_ = 'specialize:memo' +def type_eq(space): + "Utility that returns the app-level descriptor type.__eq__." + w_src, w_eq = space.lookup_in_type_where(space.w_type, + '__eq__') + return w_eq +type_eq._annspecialcase_ = 'specialize:memo' + def raiseattrerror(space, w_obj, name, w_descr=None): w_type = space.type(w_obj) typename = w_type.getname(space) diff --git a/pypy/objspace/std/test/test_identitydict.py b/pypy/objspace/std/test/test_identitydict.py --- a/pypy/objspace/std/test/test_identitydict.py +++ b/pypy/objspace/std/test/test_identitydict.py @@ -32,10 +32,20 @@ def __hash__(self): return 0 + class TypeSubclass(type): + pass + + class TypeSubclassCustomCmp(type): + def __cmp__(self, other): + return 0 + assert self.compares_by_identity(Plain) assert not self.compares_by_identity(CustomEq) assert not self.compares_by_identity(CustomCmp) assert not self.compares_by_identity(CustomHash) + assert self.compares_by_identity(type) + assert self.compares_by_identity(TypeSubclass) + assert not self.compares_by_identity(TypeSubclassCustomCmp) def test_modify_class(self): class X(object): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -173,8 +173,6 @@ # ^^^ conservative default, fixed during real usage if space.config.objspace.std.withidentitydict: - did_compare_by_identity = ( - w_self.compares_by_identity_status == COMPARES_BY_IDENTITY) if (key is None or key == '__eq__' or key == '__cmp__' or key == '__hash__'): w_self.compares_by_identity_status = UNKNOWN @@ -229,7 +227,7 @@ return w_self.getattribute_if_not_from_object() is None def compares_by_identity(w_self): - from pypy.objspace.descroperation import object_hash + from pypy.objspace.descroperation import object_hash, type_eq if not w_self.space.config.objspace.std.withidentitydict: return False # conservative # @@ -238,7 +236,9 @@ return w_self.compares_by_identity_status == COMPARES_BY_IDENTITY # default_hash = object_hash(w_self.space) - overrides_eq_cmp_or_hash = (w_self.lookup('__eq__') or + my_eq = w_self.lookup('__eq__') + overrides_eq = (my_eq and my_eq is not type_eq(w_self.space)) + overrides_eq_cmp_or_hash = (overrides_eq or w_self.lookup('__cmp__') or w_self.lookup('__hash__') is not default_hash) if overrides_eq_cmp_or_hash: _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit