Author: Ronan Lamy <ronan.l...@gmail.com> Branch: online-transforms Changeset: r74194:8cff090d32af Date: 2014-10-24 22:57 +0200 http://bitbucket.org/pypy/pypy/changeset/8cff090d32af/
Log: Use normalize_method in bk.immutablevalue() diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -21,6 +21,7 @@ from rpython.annotator.argument import simple_args from rpython.rlib.objectmodel import r_dict, Symbolic from rpython.tool.algo.unionfind import UnionFind +from rpython.tool.descriptor import normalize_method, InstanceMethod from rpython.rtyper import extregistry @@ -223,6 +224,11 @@ def immutablevalue(self, x): """The most precise SomeValue instance that contains the immutable value x.""" + if callable(x): + try: + x = normalize_method(x) + except ValueError: + pass tp = type(x) if issubclass(tp, Symbolic): # symbolic constants support result = x.annotation() @@ -314,19 +320,15 @@ elif tp is type: result = SomeConstantType(x, self) elif callable(x): - if hasattr(x, '__self__'): - if x.__self__ is not None: + if isinstance(x, InstanceMethod): + if x.im_self is not None: # bound instance method - s_self = self.immutablevalue(x.__self__) - result = s_self.find_method(x.__name__) + s_self = self.immutablevalue(x.im_self) + result = s_self.find_method(x.im_func.__name__) else: # unbound method cls_s = self.annotationclass(x.im_class) - result = cls_s.find_unboundmethod(x.__name__) - elif hasattr(x, '__objclass__'): - # builtin unbound method on CPython (aka 'method_descriptor') - cls_s = self.annotationclass(x.__objclass__) - result = cls_s.find_unboundmethod(x.__name__) + result = cls_s.find_unboundmethod(x.im_func.__name__) else: result = None if result is None: @@ -371,7 +373,7 @@ result = self.getfrozen(pyobj) else: result = description.ClassDesc(self, pyobj) - elif isinstance(pyobj, types.MethodType): + elif isinstance(pyobj, InstanceMethod): if pyobj.im_self is None: # unbound return self.getdesc(pyobj.im_func) if hasattr(pyobj.im_self, '_cleanup_'): @@ -382,10 +384,9 @@ self.getdesc(pyobj.im_func), # funcdesc self.getdesc(pyobj.im_self)) # frozendesc else: # regular method - origincls, name = origin_of_meth(pyobj) + origincls = pyobj.im_class + name = pyobj.im_func.__name__ self.see_mutable(pyobj.im_self) - assert pyobj == getattr(pyobj.im_self, name), ( - "%r is not %s.%s ??" % (pyobj, pyobj.im_self, name)) # emulate a getattr to make sure it's on the classdef classdef = self.getuniqueclassdef(pyobj.im_class) classdef.find_attribute(name) diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py --- a/rpython/annotator/builtin.py +++ b/rpython/annotator/builtin.py @@ -3,6 +3,7 @@ """ import sys +from rpython.tool.descriptor import normalize_method from rpython.annotator.model import ( SomeInteger, SomeObject, SomeChar, SomeBool, SomeString, SomeTuple, SomeUnicodeCodePoint, SomeFloat, unionof, SomeUnicodeString, @@ -255,12 +256,12 @@ BUILTIN_ANALYZERS[original] = value -@analyzer_for(getattr(object.__init__, 'im_func', object.__init__)) +@analyzer_for(normalize_method(object.__init__)) def object_init(s_self, *args): # ignore - mostly used for abstract classes initialization pass -@analyzer_for(getattr(EnvironmentError.__init__, 'im_func', EnvironmentError.__init__)) +@analyzer_for(normalize_method(EnvironmentError.__init__)) def EnvironmentError_init(s_self, *args): pass @@ -269,7 +270,7 @@ except NameError: pass else: - @analyzer_for(getattr(WindowsError.__init__, 'im_func', WindowsError.__init__)) + @analyzer_for(normalize_method(WindowsError.__init__)) def WindowsError_init(s_self, *args): pass diff --git a/rpython/tool/descriptor.py b/rpython/tool/descriptor.py --- a/rpython/tool/descriptor.py +++ b/rpython/tool/descriptor.py @@ -30,6 +30,10 @@ def __hash__(self): return hash((self.im_func, self.im_self)) + @property + def __name__(self): + return self.im_func.__name__ + if '__pypy__' in sys.modules: def normalize_method(method): '''Turn everything that behaves like a method into an InstanceMethod object''' @@ -49,8 +53,9 @@ return InstanceMethod(method.__func__, method.__self__, method.im_class) elif isinstance(method, types.BuiltinMethodType): im_self = method.__self__ - desc = getattr(type(im_self), method.__name__) - return InstanceMethod(desc, im_self, type(im_self)) + if im_self is not None: + desc = getattr(type(im_self), method.__name__) + return InstanceMethod(desc, im_self, type(im_self)) elif isinstance(method, slot_wrapper): baseslot = getattr(method.__objclass__, method.__name__) cls = method.__objclass__ @@ -61,7 +66,6 @@ elif isinstance(method, method_descriptor): cls = method.__objclass__ return InstanceMethod(method, None, method.__objclass__) - else: - raise ValueError('Not a method') + raise ValueError('Not a method') _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit