On 7 July 2011 23:13, Vitja Makarov <vitja.maka...@gmail.com> wrote: > > > 2011/7/8 mark florisson <markflorisso...@gmail.com> >> >> 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 :) > > Yes, that would work) But I think CyFunction is too heavy for methods. I thought the python-like behaviour of them was appealing enough to consider defaulting to it? Otherwise you'd only have to use them for super(), __class__ and closures.
> I've just realized that descr_get is called each time you access method, > each time you call it and so on. > >> >> Anyway, the important question was whether I could pull from your >> branch or whether I should wait for the merge. >> > > It's better not to use my branch this way as it's marked with underscore and > sometimes I do forced pushes. > I hope it will be merged soon. > There is one more thing left CPython uses pool for frequently used objects > to avoid unnecessary memory allocations. > Probably we should implement something like that too. > > You are going to subclass cyfunction and then override its tp_call method, > right? Yes, exactly. The thing is that I only need to use it in extension methods, where the self for the method is passed in as m_self instead of in the args tuple. But I don't think a signature change will inconvenience that, so I think it's fine :) > -- > 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