[pypy-dev] Support for __getitem__ in rpython?

Hakan Ardo hakan at debian.org
Fri Dec 26 11:31:53 CET 2008


On Tue, Dec 23, 2008 at 12:23 PM, Armin Rigo <arigo at tunes.org> wrote:
> On Mon, Dec 15, 2008 at 08:47:26PM +0100, Hakan Ardo wrote:
>> cannot yet handle that the methods return NotImplemented. Would it be
>> possible to handle that in a similar manner to how None is handled?
>
> Not easily.  The annotation framework of PyPy was never meant to handle
> the full Python language, but only a subset reasonable for writing

OK, that makes sens.

On Tue, Dec 23, 2008 at 5:49 PM, Paolo Giarrusso <p.giarrusso at gmail.com> wrote:
> And I also wonder if the
> RPython compiler can inline the __add__ call and optimize the tagging
> away.
>
> That said, I do not know if what I'm suggesting is implementable in
> RPython, or if it would be a good idea. Just my 2 cents, since this
> might be what Hakan is looking for.

Yes, in most cases of interest, the annotator can determined whether
the __add__ method always/never return NotImplemented and thus the
test will be removed. If we'll not  be able to handle the most general
case where the choise between __add__ and __radd__ has to be done at
runtime, that's fine.

If I use None instead of NotImplemented I get the behaviour  I want.
The following code does for example compile:

  class mystr(object):
       def __init__(self,s):
           self.s=str(s)
       def __str__(self):
           return self.s
       def __add__(self,other):
           return mystr(self.s+str(other))
       def __radd__(self,other):
           return mystr(str(other)+self.s)
       __add__._annspecialcase_ = 'specialize:argtype(1)'
       __radd__._annspecialcase_ = 'specialize:argtype(1)'

   class pair(object):
       def __init__(self,a,b):
           self.a=a
           self.b=b
       def __str__(self):
           return "(%d,%d)"%(self.a,self.b)
       def __add__(self,other):
           if isinstance(other,pair):
               return pair(self.a+other.a, self.b+other.b)
           else:
               return None
       __add__._annspecialcase_ = 'specialize:argtype(1)'
       __radd__=__add__

   def dotst_notimplemented():
       a=mystr('a')
       b=pair(1,2)
       return (str(b+a), str(a+b))

If I use the following helper to call the method:

   def do_add_radd(lop,rop):
       if isinstance(rop,lop.__class__) and not isinstance(lop,rop.__class__):
           r=rop.__radd__(lop)
           if r is None:
               return lop.__add__(rop)
           return r
       else:
           r=lop.__add__(rop)
           if r is None:
               return rop.__radd__(lop)
           return r

But if I replace None with NotImplemented, it does not compile
anymore. So, can we get the annotater to treat NotImplemented in a
similar manner as it treats None?

--
Håkan Ardö



More information about the Pypy-dev mailing list