[Cython] PEP 3135 -- New Super

mark florisson markflorisson88 at gmail.com
Thu Jul 7 22:50:20 CEST 2011


On 7 July 2011 22:39, Vitja Makarov <vitja.makarov at gmail.com> wrote:
>
>
> 2011/7/8 mark florisson <markflorisson88 at gmail.com>
>>
>> On 7 July 2011 22:15, Vitja Makarov <vitja.makarov at gmail.com> wrote:
>> >
>> >
>> > 2011/7/7 mark florisson <markflorisson88 at gmail.com>
>> >>
>> >> On 6 July 2011 10:01, Vitja Makarov <vitja.makarov at gmail.com> wrote:
>> >> > 2011/7/6 Stefan Behnel <stefan_ml at behnel.de>:
>> >> >> Vitja Makarov, 06.07.2011 09:05:
>> >> >>>
>> >> >>> 2011/7/6 Stefan Behnel<stefan_ml at behnel.de>:
>> >> >>>>
>> >> >>>> Stefan Behnel, 05.07.2011 10:04:
>> >> >>>>>
>> >> >>>>> Vitja Makarov, 05.07.2011 09:17:
>> >> >>>>>>
>> >> >>>>>> 2011/7/5 Stefan Behnel:
>> >> >>>>>>>
>> >> >>>>>>> Vitja Makarov, 05.07.2011 08:21:
>> >> >>>>>>>>
>> >> >>>>>>>> I was thinking about implementing new super() with no
>> >> >>>>>>>> arguments.
>> >> >>>>>>>
>> >> >>>>>>> http://trac.cython.org/cython_trac/ticket/696
>> >> >>>>>>>
>> >> >>>>>>>> The problem is where to store __class__, I see two options
>> >> >>>>>>>> here:
>> >> >>>>>>>>
>> >> >>>>>>>> 1. Add func_class member to CyFunction, this way __class__
>> >> >>>>>>>> will
>> >> >>>>>>>> be
>> >> >>>>>>>> private and not visible for inner functions:
>> >> >>>>>>>> 2. Put it into closure
>> >> >>>>>>>
>> >> >>>>>>> The second option has the advantage of requiring the field only
>> >> >>>>>>> when
>> >> >>>>>>> super()
>> >> >>>>>>> is used, whereas the first impacts all functions.
>> >> >>>>>>>
>> >> >>>>>>> I would expect that programs commonly have a lot more functions
>> >> >>>>>>> than
>> >> >>>>>>> specifically methods that use a no-argument call to super(), so
>> >> >>>>>>> this
>> >> >>>>>>> may
>> >> >>>>>>> make a difference.
>> >> >>>>>>>
>> >> >>>>>>
>> >> >>>>>> So, now classes are created the following way:
>> >> >>>>>>
>> >> >>>>>> class_dict = {}
>> >> >>>>>> class_dict.foo = foo_func
>> >> >>>>>> class = CreateClass(class_dict)
>> >> >>>>>>
>> >> >>>>>> So after class is created I should check its dict for CyFunction
>> >> >>>>>> members (maybe only ones that actually require __class__)
>> >> >>>>>> and set __class__:
>> >> >>>>>>
>> >> >>>>>> for value in class.__dict__.itervalues():
>> >> >>>>>> if isinstance(value, CyFunction) and value.func_class is
>> >> >>>>>> WantClass:
>> >> >>>>>> value.func_class = class
>> >> >>>>>>
>> >> >>>>>> Btw, first way requires cyfunction signature change, it would
>> >> >>>>>> accept
>> >> >>>>>> cyfunction object as first argument.
>> >> >>>>>
>> >> >>>>> We currently pass the binding (i.e. owning) object, right?
>> >> >>>>
>> >> >>>> So, how would this work for methods? We need to pass the 'self'
>> >> >>>> object
>> >> >>>> there, which the CyFunction doesn't know. If anything, it only
>> >> >>>> knows
>> >> >>>> the
>> >> >>>> class it was defined in, which doesn't help here.
>> >> >>>
>> >> >>> From PEP: "super() is equivalent to: super(__class__,<firstarg>)"
>> >> >>
>> >> >> I wasn't speaking of super(). What I meant, was: how do we pass
>> >> >> 'self'
>> >> >> when
>> >> >> we pass the CyFunction object as the first argument?
>> >> >>
>> >> >
>> >> >
>> >> > Oh, ok. Now we pass closure or nothing in self. So method's self is
>> >> > passed via tuple.
>> >> > Instancemethod do this for us. Now CyFucntion uses PyCFunction_Call
>> >> > we
>> >> > can override this and change signature of cyfunction to:
>> >> >
>> >> > PyObject func(CyFunction *func, PyObject *self, PyObject *args,
>> >> > PyObject *kwargs);
>> >> >
>> >> > This way we should implement new instancemethod type.
>> >>
>> >> Would it be easier to make scope objects attributes of functions? Then
>> >> you could still utilize PyCFunction_Call without needing to check the
>> >> argument flags and such right?
>> >>
>> >
>> > Sure, scope object is already functions attribute now it's stored inside
>> > self.
>> > But, instancemethods desc_get builds new args tuple with self as first
>> > element.
>> > We can implement cython version of instance method and change method
>> > signature a little bit.
>>
>> Right, and you pass it in as the first argument to the C function.
>> However, if you want to change the signature, you have to override
>> PyCFunction_Call, which, if I'm not mistaken, means you will have to
>> interpret the flags from the PyMethodDef and call the C function in
>> the right way (e.g. with or without the args tuple and kwargs) and
>> check if it's being called correctly. If you leave it as an attribute
>> of the function, you can pass in the function and access the scope
>> object from the function object in the closure C function. So I think
>> changing the signature might be a bit harder?
>>
>
> Yes, but how to handle instantmethods self arg?
> We can't store it inside function object as it is different for each
> instance.

In descr_get you create and return a new CyFunction with a __self__
set (note, not m_self) and in __call__ you put __self__ in the args
tuple and the function as m_self, and then call the CyFunction using
PyCFunction_Call. But copying and modifying PyCFunction_Call works
just as well I suppose :)
Anyway, the important question was whether I could pull from your
branch or whether I should wait for the merge.

> btw I've already moved pycyfunction_call into cython..
> --
> vitja.
>
>
> _______________________________________________
> cython-devel mailing list
> cython-devel at python.org
> http://mail.python.org/mailman/listinfo/cython-devel
>
>


More information about the cython-devel mailing list