Author: Ronan Lamy <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit