[pypy-commit] pypy online-transforms: Use normalised class attributes in add_source_attribute(), instead of raw values from the class dict
rlamy
noreply at buildbot.pypy.org
Sun Nov 2 23:41:08 CET 2014
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: online-transforms
Changeset: r74329:9c33a580d088
Date: 2014-11-02 22:40 +0000
http://bitbucket.org/pypy/pypy/changeset/9c33a580d088/
Log: Use normalised class attributes in add_source_attribute(), instead
of raw values from the class dict
diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py
--- a/rpython/annotator/description.py
+++ b/rpython/annotator/description.py
@@ -8,7 +8,7 @@
from rpython.tool.sourcetools import valid_identifier, func_with_new_name
from rpython.tool.pairtype import extendabletype
from rpython.annotator.model import AnnotatorError
-from rpython.tool.descriptor import normalize_method
+from rpython.tool.descriptor import normalize_method, InstanceMethod
class CallFamily(object):
"""A family of Desc objects that could be called from common call sites.
@@ -483,25 +483,35 @@
self.all_enforced_attrs = [] # no attribute allowed
def add_source_attribute(self, cls, name, mixin=False):
- value = cls.__dict__[name]
- if isinstance(value, types.FunctionType):
- # for debugging
- if not hasattr(value, 'class_'):
- value.class_ = self.pyobj
+ try:
+ value = getattr(cls, name)
+ except:
+ if name in cls.__dict__:
+ return # ignore misbehaving descriptors and the like
+ raise
+ try:
+ value = normalize_method(value)
+ except ValueError:
+ pass
+ if isinstance(value, InstanceMethod):
+ func = value.im_func
+ if isinstance(func, types.FunctionType):
+ if not hasattr(func, 'class_'):
+ func.class_ = cls
if self.specialize:
# make a custom funcdesc that specializes on its first
# argument (i.e. 'self').
from rpython.annotator.specialize import specialize_argtype
def argtype0(funcdesc, args_s):
return specialize_argtype(funcdesc, args_s, 0)
- funcdesc = FunctionDesc(self.bookkeeper, value,
+ funcdesc = FunctionDesc(self.bookkeeper, func,
specializer=argtype0)
self.classdict[name] = funcdesc
return
if mixin:
# make a new copy of the FunctionDesc for this class,
# but don't specialize further for all subclasses
- funcdesc = FunctionDesc(self.bookkeeper, value)
+ funcdesc = FunctionDesc(self.bookkeeper, func)
self.classdict[name] = funcdesc
return
# NB. if value is, say, AssertionError.__init__, then we
@@ -509,10 +519,9 @@
# that the py lib has its own AssertionError.__init__ which
# is of type FunctionType. But bookkeeper.immutablevalue()
# will do the right thing in s_get_value().
- if isinstance(value, staticmethod) and mixin:
+ if isinstance(value, types.FunctionType) and mixin:
# make a new copy of staticmethod
- func = value.__get__(42)
- value = staticmethod(func_with_new_name(func, func.__name__))
+ value = func_with_new_name(value, value.__name__)
if type(value) in MemberDescriptorTypes:
# skip __slots__, showing up in the class as 'member' objects
@@ -521,10 +530,6 @@
# pretend that built-in exceptions have no __init__,
# unless explicitly specified in builtin.py
from rpython.annotator.builtin import BUILTIN_ANALYZERS
- try:
- value = normalize_method(value)
- except ValueError:
- pass
if value not in BUILTIN_ANALYZERS:
return
self.classdict[name] = Constant(value)
@@ -686,10 +691,11 @@
obj = self.classdict[name]
if isinstance(obj, Constant):
value = obj.value
- if isinstance(value, staticmethod): # special case
- value = value.__get__(42)
+ if isinstance(value, types.FunctionType): # staticmethod
classdef = None # don't bind
- elif isinstance(value, classmethod):
+ elif (isinstance(value, InstanceMethod) and
+ value.im_self is not None):
+ # This is a method bound to the class, i.e. a classmethod
raise AnnotatorError("classmethods are not supported")
s_value = self.bookkeeper.immutablevalue(value)
if classdef is not None:
More information about the pypy-commit
mailing list