[pypy-commit] pypy default: (Alex_Gaynor, antocuni): special-case type.__eq__ so that type (and subclasses) are marked as compares_by_identity()
antocuni
noreply at buildbot.pypy.org
Wed Jul 27 14:38:50 CEST 2011
Author: Antonio Cuni <anto.cuni at 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:
More information about the pypy-commit
mailing list