[pypy-dev] patch for __getattribute__()

Samuele Pedroni pedronis at strakt.com
Sat Jul 1 10:03:25 CEST 2006


Richard Emslie wrote:
> 
> Hi!
> 
> The following patch initiated by a chat with Runar Petursson about 
> descriptors - increases pypy-c/pypy-llvm by 25% on richards.py.

well, it breaks this:

Python 2.4.1 (#2, Mar 31 2005, 00:05:10)
[GCC 3.3 20030304 (Apple Computer, Inc. build 1666)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
 >>> class C(object):
...    def m(self):
...       return "class"
...
 >>> c=C()
 >>> c.m = lambda: "instance"
 >>>
 >>> c.m()
'instance'
 >>>

vs. patched PyPy

PyPy 0.9.0 in StdObjSpace on top of Python 2.4.1 (startuptime: 4.97 secs)
 >>>> class C(object):
....    def m(self):
....        return "class"
....
 >>>> c=C()
 >>>> c.m = lambda: "instance"
 >>>> c.m()
'class'

functions are not data descriptors, this feature makes increasing the 
performance of method lookup more involved that one would like but
Python semantics expect this kind of overriding to work.

I have added a test about this.


> 
> I couldnt be bothered creating a branch - but if someone wants to sanity 
> check it and fix the method repr and check it in, you are more than 
> welcome! :-)
> 
> Cheers,
> Richard
> 
> 
> ------------------------------------------------------------------------
> 
> Index: objspace/descroperation.py
> ===================================================================
> --- objspace/descroperation.py	(revision 29539)
> +++ objspace/descroperation.py	(working copy)
> @@ -1,7 +1,7 @@
>  import operator
>  from pypy.interpreter.error import OperationError
>  from pypy.interpreter.baseobjspace import ObjSpace
> -from pypy.interpreter.function import Function, Method
> +from pypy.interpreter.function import Function, Method, descr_function_get
>  from pypy.interpreter.argument import Arguments
>  from pypy.interpreter.typedef import default_identity_hash
>  from pypy.tool.sourcetools import compile2, func_with_new_name
> @@ -19,6 +19,10 @@
>          name = space.str_w(w_name)
>          w_descr = space.lookup(w_obj, name)
>          if w_descr is not None:
> +            # XXX test performance
> +            descr = space.interpclass_w(w_descr)
> +            if type(descr) is Function:
> +                return descr_function_get(space, w_descr, w_obj)
>              if space.is_data_descr(w_descr):
>                  return space.get(w_descr, w_obj)
>          w_value = w_obj.getdictvalue(space, w_name)
> Index: objspace/cpy/objspace.py
> ===================================================================
> --- objspace/cpy/objspace.py	(revision 29539)
> +++ objspace/cpy/objspace.py	(working copy)
> @@ -62,8 +62,8 @@
>              return PyString_FromStringAndSize(x, len(x))
>          if isinstance(x, float): 
>              return PyFloat_FromDouble(x)
> -        if isinstance(x, r_uint):
> -            return PyLong_FromUnsignedLong(x)
> +        #if isinstance(x, r_uint):
> +        #    return PyLong_FromUnsignedLong(x)
>          # if we arrive here during RTyping, then the problem is *not* the %r
>          # in the format string, but it's that someone is calling space.wrap()
>          # on a strange object.
> Index: interpreter/function.py
> ===================================================================
> --- interpreter/function.py	(revision 29539)
> +++ interpreter/function.py	(working copy)
> @@ -385,6 +385,16 @@
>              w_class = space.type(self.w_instance)
>          else:
>              w_class = self.w_class
> +        if w_class is None:
> +            if self.w_instance is None:
> +                s = "<unbound method %s>" % (name)
> +                return space.wrap(s)
> +            else:
> +                objrepr = space.str_w(space.repr(self.w_instance))
> +                info = 'bound method %s of %s' % (name, objrepr)
> +                # info = "method %s of %s object" % (name, typename)
> +                return self.w_instance.getrepr(self.space, info)
> +
>          typename = w_class.getname(self.space, '?')
>          if self.w_instance is None:
>              s = "<unbound method %s.%s>" % (typename, name)
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> pypy-dev at codespeak.net
> http://codespeak.net/mailman/listinfo/pypy-dev



More information about the pypy-dev mailing list