Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
 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))
Ejemplo n.º 5
0
 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))
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
 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
Ejemplo n.º 9
0
 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
Ejemplo n.º 10
0
 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)
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
 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))
Ejemplo n.º 14
0
    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
Ejemplo n.º 15
0
 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)
Ejemplo n.º 16
0
    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
Ejemplo n.º 17
0
 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))
Ejemplo n.º 18
0
 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))