def getattr(self, w_obj, w_name): if not self.config.objspace.std.getattributeshortcut: return DescrOperation.getattr(self, w_obj, w_name) # an optional shortcut for performance from pypy.objspace.descroperation import raiseattrerror from pypy.objspace.descroperation import object_getattribute w_type = self.type(w_obj) if not w_type.uses_object_getattribute: # slow path: look for a custom __getattribute__ on the class w_descr = w_type.lookup('__getattribute__') # if it was not actually overriden in the class, we remember this # fact for the next time. if w_descr is object_getattribute(self): w_type.uses_object_getattribute = True return self._handle_getattribute(w_descr, w_obj, w_name) # fast path: XXX this is duplicating most of the logic # from the default __getattribute__ and the getattr() method... name = self.str_w(w_name) w_descr = w_type.lookup(name) e = None if w_descr is not None: if not self.is_data_descr(w_descr): w_value = w_obj.getdictvalue_attr_is_in_class(self, w_name) if w_value is not None: return w_value try: return self.get(w_descr, w_obj) except OperationError, e: if not e.match(self, self.w_AttributeError): raise
def LOOKUP_METHOD(f, nameindex, *ignored): # stack before after # -------------- --fast-method----fallback-case------------ # # w_object None # w_object => w_function w_boundmethod_or_whatever # (more stuff) (more stuff) (more stuff) # space = f.space w_obj = f.popvalue() w_name = f.getname_w(nameindex) w_value = None w_getattribute = space.lookup(w_obj, '__getattribute__') if w_getattribute is object_getattribute(space): name = space.str_w(w_name) w_descr = space.lookup(w_obj, name) if w_descr is None: # this handles directly the common case # module.function(args..) w_value = w_obj.getdictvalue(space, w_name) elif type(w_descr) is function.Function: w_value = w_obj.getdictvalue_attr_is_in_class(space, w_name) if w_value is None: # fast method path: a function object in the class, # nothing in the instance f.pushvalue(w_descr) f.pushvalue(w_obj) return if w_value is None: w_value = space.getattr(w_obj, w_name) f.pushvalue(w_value) f.pushvalue(None)
def getattribute(self, space, attr): # XXX fixme: this is a workaround. It's hard but not impossible # to have both a __doc__ on the 'property' type, and a __doc__ # descriptor that can read the docstring of 'property' instances. if attr == '__doc__': return self.w_doc # shortcuts return space.call_function(object_getattribute(space), space.wrap(self), space.wrap(attr))
def PyObject_GenericGetAttr(space, w_obj, w_name): """Generic attribute getter function that is meant to be put into a type object's tp_getattro slot. It looks for a descriptor in the dictionary of classes in the object's MRO as well as an attribute in the object's __dict__ (if present). As outlined in descriptors, data descriptors take preference over instance attributes, while non-data descriptors don't. Otherwise, an AttributeError is raised.""" from pypy.objspace.descroperation import object_getattribute w_descr = object_getattribute(space) return space.get_and_call_function(w_descr, w_obj, w_name)
def getattribute_if_not_from_object(w_self): """ this method returns the applevel __getattribute__ if that is not the one from object, in which case it returns None """ from pypy.objspace.descroperation import object_getattribute if not we_are_jitted(): shortcut = w_self.space.config.objspace.std.getattributeshortcut if not shortcut or not w_self.uses_object_getattribute: # slow path: look for a custom __getattribute__ on the class w_descr = w_self.lookup('__getattribute__') # if it was not actually overriden in the class, we remember this # fact for the next time. if w_descr is object_getattribute(w_self.space): if shortcut: w_self.uses_object_getattribute = True else: return w_descr return None # in the JIT case, just use a lookup, because it is folded away # correctly using the version_tag w_descr = w_self.lookup('__getattribute__') if w_descr is not object_getattribute(w_self.space): return w_descr
def descr_getattribute(self, space, w_attr): from pypy.objspace.descroperation import object_getattribute try: return space.call_function(object_getattribute(space), self, w_attr) except OperationError as e: if not e.match(space, space.w_AttributeError): raise w_name = space.finditem(self.w_dict, space.newtext('__name__')) if w_name is None: raise oefmt(space.w_AttributeError, "module has no attribute %R", w_attr) else: raise oefmt(space.w_AttributeError, "module %R has no attribute %R", w_name, w_attr)
def call_method_opt(space, w_obj, methname, *arg_w): """An optimized version of space.call_method() based on the same principle as above. """ w_name = space.wrap(methname) w_getattribute = space.lookup(w_obj, '__getattribute__') if w_getattribute is object_getattribute(space): w_descr = space.lookup(w_obj, methname) if type(w_descr) is function.Function: w_value = w_obj.getdictvalue_attr_is_in_class(space, w_name) if w_value is None: # fast method path: a function object in the class, # nothing in the instance return space.call_function(w_descr, w_obj, *arg_w) w_meth = space.getattr(w_obj, w_name) return space.call_function(w_meth, *arg_w)
def LOOKUP_METHOD(f, nameindex, *ignored): # stack before after # -------------- --fast-method----fallback-case------------ # # w_object None # w_object => w_function w_boundmethod_or_whatever # (more stuff) (more stuff) (more stuff) # space = f.space w_obj = f.popvalue() w_name = f.getname_w(nameindex) w_value = None if space.config.objspace.std.getattributeshortcut: w_type = space.type(w_obj) fastpath = w_type.uses_object_getattribute # conservatively, 'uses_object_getattribute' can be False # even if __getattribute__ was not overridden. In this # case, the code below calls space.getattr(), which will # set 'uses_object_getattribute' to True for the next time. else: w_getattribute = space.lookup(w_obj, '__getattribute__') if w_getattribute is object_getattribute(space): w_type = space.type(w_obj) fastpath = True else: fastpath = False if fastpath: name = space.str_w(w_name) w_descr = w_type.lookup(name) if w_descr is None: # this handles directly the common case # module.function(args..) w_value = w_obj.getdictvalue(space, w_name) elif type(w_descr) is function.Function: w_value = w_obj.getdictvalue_attr_is_in_class(space, w_name) if w_value is None: # fast method path: a function object in the class, # nothing in the instance f.pushvalue(w_descr) f.pushvalue(w_obj) return if w_value is None: w_value = space.getattr(w_obj, w_name) f.pushvalue(w_value) f.pushvalue(None)
def getattribute(self, space, name): w = space.wrap # only use a special logic for bound super objects and not for # getting the __class__ of the super object itself. if self.w_objtype is not None and name != "__class__": w_value = space.lookup_in_type_starting_at(self.w_objtype, self.w_starttype, name) if w_value is not None: w_get = space.lookup(w_value, "__get__") if w_get is None: return w_value # Only pass 'obj' param if this is instance-mode super # (see CPython sourceforge id #743627) if self.w_self is self.w_objtype: w_obj = space.w_None else: w_obj = self.w_self return space.get_and_call_function(w_get, w_value, w_obj, self.w_objtype) # fallback to object.__getattribute__() return space.call_function(object_getattribute(space), w(self), w(name))
def getattribute(self, space, name): w = space.wrap if name == "__class__": return self.w_selftype if self.w_type is None: return space.call_function(object_getattribute(space), w(self), w(name)) w_value = space.lookup_in_type_starting_at(self.w_type, self.w_starttype, name) if w_value is None: return space.getattr(w(self), w(name)) try: w_get = space.getattr(w_value, space.wrap("__get__")) if space.is_w(self.w_self, self.w_type): w_self = space.w_None else: w_self = self.w_self except OperationError, o: if not o.match(space, space.w_AttributeError): raise return w_value
def getattribute(self, space, w_name): name = space.text_w(w_name) # only use a special logic for bound super objects and not for # getting the __class__ of the super object itself. if self.w_objtype is not None and name != '__class__': assert self.w_starttype is not None w_value = space.lookup_in_type_starting_at(self.w_objtype, self.w_starttype, name) if w_value is not None: w_get = space.lookup(w_value, '__get__') if w_get is None: return w_value # Only pass 'obj' param if this is instance-mode super # (see CPython sourceforge id #743627) w_obj = self.w_self if w_obj is None or w_obj is self.w_objtype: w_obj = space.w_None return space.get_and_call_function(w_get, w_value, w_obj, self.w_objtype) # fallback to object.__getattribute__() return space.call_function(object_getattribute(space), self, w_name)
def getattribute(self, space, name): w = space.wrap if name == '__class__': return self.w_selftype if self.w_type is None: return space.call_function(object_getattribute(space), w(self), w(name)) w_value = space.lookup_in_type_starting_at(self.w_type, self.w_starttype, name) if w_value is None: return space.getattr(w(self), w(name)) try: w_get = space.getattr(w_value, space.wrap('__get__')) if space.is_w(self.w_self, self.w_type): w_self = space.w_None else: w_self = self.w_self except OperationError, o: if not o.match(space, space.w_AttributeError): raise return w_value
def getattribute(self, space, attr): if attr == "__doc__": return self.w_doc # shortcuts return space.call_function(object_getattribute(space), space.wrap(self), space.wrap(attr))
def getattribute(self, space, attr): if attr == '__doc__': return self.w_doc # shortcuts return space.call_function(object_getattribute(space), space.wrap(self), space.wrap(attr))