[pypy-dev] Support for __getitem__ in rpython?

Armin Rigo arigo at tunes.org
Sun Dec 7 18:04:59 CET 2008


Hi Hakan,

On Thu, Dec 04, 2008 at 10:15:34AM +0100, Hakan Ardo wrote:
> I've started to play around with the pypy codebase with the intention
> to make obj[i] act like obj.__getitem__(i) for rpython objects.  The
> approach I tried was to add:

Calling __getitem__ in this way is not really supported, but here is how
I managed to get it work anyway.  It's only slightly more complicated:

    class __extend__(pairtype(SomeInstance, SomeObject)):
        def getitem((s_array, s_index)):
            # first generate a pseudo call to the helper
            bk = getbookkeeper()
            s_callable = bk.immutablevalue(do_getitem)
            args_s = [s_array, s_index]
            bk.emulate_pbc_call(('instance_getitem', s_array.knowntype),
                                s_callable, args_s)
            # then use your own trick to get the correct result
            s=SomeString()
            s.const="__getitem__"
            p=s_array.getattr(s)
            return p.simple_call(s_index)

    # this is the helper
    def do_getitem(array, key):
        return array.__getitem__(key)
    do_getitem._annspecialcase_ = 'specialize:argtype(0)'
    # ^^^ specialization; not sure I have done it right...    

and then for the code in rclass:

    from pypy.annotation import binaryop
    from pypy.objspace.flow.model import Constant

    class __extend__(pairtype(AbstractInstanceRepr, Repr)):
        def rtype_getitem((r_array, r_key), hop):
            # call the helper do_getitem...
            hop2 = hop.copy()
            bk = r_array.rtyper.annotator.bookkeeper
            v_func = Constant(binaryop.do_getitem)
            s_func = bk.immutablevalue(v_func.value)
            hop2.v_s_insertfirstarg(v_func, s_func)
            hop2.forced_opname = 'simple_call'
            return hop2.dispatch()

I think the _annspecialcase_ should be able to sort out between multiple
unrelated calls to the helper.  The code for the annotator is a bit
bogus, btw, because it emulates a call to the function but also computes
the result explicitly; but I couldn't figure out a better way.


A bientot,

Armin.



More information about the Pypy-dev mailing list