[Python-3000] Method descriptors
Guido van Rossum
guido at python.org
Mon Dec 10 20:01:50 CET 2007
On Dec 8, 2007 9:45 AM, Marcin 'Qrczak' Kowalczyk <qrczak at knm.org.pl> wrote:
> I'm confused about storing methods in class dictionaries from the point
> of view of the C API.
>
> 1. Let's say that I have a callable PyObject called f, of my type
> defined in C. I want to store something derived from f as A.m
> for some class A, such that for an object a of class A, calling
> a.m(*args) ends up calling f(a, *args).
>
> In Python2 PyMethod_New(f, NULL, a) seems to be the right to store
> in the class. How to do the equivalent thing in Python3?
Add a __get__ (instance) method to f's class, and store f directly in
A. Your __get__ method should return a bound object using
PyMethod_New(f, a).
> BTW, applying PyMethod_Type to 3 arguments crashes Python3. I think
> this line is the culprit (classobject.c):
>
> if (!PyArg_UnpackTuple(args, "method", 2, 3,
> &func, &self))
>
> Should be 2 instead of 3. There used to be an extra parameter.
Thanks for noting! Christian Heimes fixed this already.
> 2. As above, but f is to be implemented as a C function. I found the
> following working for a new-style class:
>
> - make PyMethodDef struct for the method
> - use PyDescr_NewMethod
> - store the resulting object in the class
>
> but it does not work for a classic class (such that an exception
> class in Python 2.4 and below) to which I want to add a method.
> Here it seems to be doable differently:
>
> - make PyMethodDef struct for the method, but with an unused first
> parameter
> - use PyCFunction_New, with NULL as 'self'
> - use PyMethod_New on the resulting function, NULL, and the class
> - store the resulting object in the class
>
> Can this be done simpler? Having separate variants for different
> Python versions is OK.
Unsure how this differs from the previous case. I'd recommend wrapping
f in another class defined in C.
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-3000
mailing list