On 7 July 2011 22:39, Vitja Makarov <vitja.maka...@gmail.com> wrote: > > > 2011/7/8 mark florisson <markflorisso...@gmail.com> >> >> On 7 July 2011 22:15, Vitja Makarov <vitja.maka...@gmail.com> wrote: >> > >> > >> > 2011/7/7 mark florisson <markflorisso...@gmail.com> >> >> >> >> On 6 July 2011 10:01, Vitja Makarov <vitja.maka...@gmail.com> wrote: >> >> > 2011/7/6 Stefan Behnel <stefan...@behnel.de>: >> >> >> Vitja Makarov, 06.07.2011 09:05: >> >> >>> >> >> >>> 2011/7/6 Stefan Behnel<stefan...@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@python.org > http://mail.python.org/mailman/listinfo/cython-devel > > _______________________________________________ cython-devel mailing list cython-devel@python.org http://mail.python.org/mailman/listinfo/cython-devel