def getdesc(self, pyobj): # get the XxxDesc wrapper for the given Python object, which must be # one of: # * a user-defined Python function # * a Python type or class (but not a built-in one like 'int') # * a user-defined bound or unbound method object # * a frozen pre-built constant (with _freeze_() == True) # * a bound method of a frozen pre-built constant obj_key = Constant(pyobj) try: return self.descs[obj_key] except KeyError: if isinstance(pyobj, types.FunctionType): result = description.FunctionDesc(self, pyobj) elif isinstance(pyobj, (type, types.ClassType)): if pyobj is object: raise Exception("ClassDesc for object not supported") if pyobj.__module__ == '__builtin__': # avoid making classdefs for builtin types result = self.getfrozen(pyobj) else: result = ClassDesc(self, pyobj) elif isinstance(pyobj, types.MethodType): if pyobj.im_self is None: # unbound return self.getdesc(pyobj.im_func) if hasattr(pyobj.im_self, '_cleanup_'): pyobj.im_self._cleanup_() if hasattr(pyobj.im_self, '_freeze_'): # method of frozen assert pyobj.im_self._freeze_() is True result = description.MethodOfFrozenDesc( self, self.getdesc(pyobj.im_func), # funcdesc self.getdesc(pyobj.im_self)) # frozendesc else: # regular method origincls, name = origin_of_meth(pyobj) classdef = self.getuniqueclassdef(pyobj.im_class) classdef.see_instance(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.find_attribute(name) result = self.getmethoddesc( self.getdesc(pyobj.im_func), # funcdesc self.getuniqueclassdef(origincls), # originclassdef classdef, # selfclassdef name) else: # must be a frozen pre-built constant, but let's check if hasattr(pyobj, '_freeze_'): assert pyobj._freeze_() is True else: if hasattr(pyobj, '__call__'): msg = "object with a __call__ is not RPython" else: msg = "unexpected prebuilt constant" raise Exception("%s: %r" % (msg, pyobj)) result = self.getfrozen(pyobj) self.descs[obj_key] = result return result
def newfuncdesc(self, pyfunc): name = pyfunc.__name__ if hasattr(pyfunc, '_generator_next_method_of_'): from rpython.flowspace.argument import Signature signature = Signature(['entry']) # haaaaaack defaults = () else: signature = cpython_code_signature(pyfunc.__code__) defaults = pyfunc.__defaults__ # get the specializer based on the tag of the 'pyobj' # (if any), according to the current policy tag = getattr(pyfunc, '_annspecialcase_', None) specializer = self.annotator.policy.get_specializer(tag) if specializer is memo: return description.MemoDesc(self, pyfunc, name, signature, defaults, specializer) return description.FunctionDesc(self, pyfunc, name, signature, defaults, specializer)