Author: Ronan Lamy <ronan.l...@gmail.com> Branch: online-transforms Changeset: r74232:7530733a07f0 Date: 2014-10-25 18:04 +0200 http://bitbucket.org/pypy/pypy/changeset/7530733a07f0/
Log: Normalize methods and avoid using weakrefs in extregistry diff --git a/rpython/rtyper/extregistry.py b/rpython/rtyper/extregistry.py --- a/rpython/rtyper/extregistry.py +++ b/rpython/rtyper/extregistry.py @@ -1,6 +1,7 @@ import weakref import UserDict from rpython.tool.uid import Hashable +from rpython.tool.descriptor import normalize_method class AutoRegisteringType(type): @@ -21,6 +22,10 @@ else: if key in dict: raise ValueError("duplicate extregistry entry %r" % (selfcls,)) + try: + key = normalize_method(key) + except ValueError: + pass dict[key] = selfcls def _register_value(selfcls, key): @@ -73,13 +78,10 @@ # ____________________________________________________________ -class FlexibleWeakDict(UserDict.DictMixin): - """A WeakKeyDictionary that accepts more or less anything as keys: - weakly referenceable objects or not, hashable objects or not. - """ +class FlexibleDict(UserDict.DictMixin): + """A dictionary that accepts unhashable objects as keys""" def __init__(self): self._regdict = {} - self._weakdict = weakref.WeakKeyDictionary() self._iddict = {} def ref(self, key): @@ -87,12 +89,7 @@ hash(key) except TypeError: return self._iddict, Hashable(key) # key is not hashable - try: - weakref.ref(key) - except TypeError: - return self._regdict, key # key cannot be weakly ref'ed - else: - return self._weakdict, key # normal case + return self._regdict, key def __getitem__(self, key): d, key = self.ref(key) @@ -108,11 +105,10 @@ def keys(self): return (self._regdict.keys() + - self._weakdict.keys() + [hashable.value for hashable in self._iddict]) -EXT_REGISTRY_BY_VALUE = FlexibleWeakDict() +EXT_REGISTRY_BY_VALUE = FlexibleDict() EXT_REGISTRY_BY_TYPE = weakref.WeakKeyDictionary() # ____________________________________________________________ @@ -135,6 +131,10 @@ return _lookup_type_cls(type(instance)) def lookup(instance): + try: + instance = normalize_method(instance) + except ValueError: + pass Entry = _lookup_cls(instance) return Entry(type(instance), instance) diff --git a/rpython/rtyper/test/test_extregistry.py b/rpython/rtyper/test/test_extregistry.py --- a/rpython/rtyper/test/test_extregistry.py +++ b/rpython/rtyper/test/test_extregistry.py @@ -134,3 +134,17 @@ _about_ = n1 assert isinstance(extregistry.lookup(n1), Entry) assert isinstance(extregistry.lookup(n2), Entry) + +def test_register_method_of_frozen(): + class Frozen(object): + def _freeze_(self): + return True + def foo(self): + pass + + f = Frozen() + + class Entry(ExtRegistryEntry): + _about_ = f.foo + + assert isinstance(extregistry.lookup(f.foo), Entry) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit