Defining *class* methods on C code
Thomas Heller
theller at python.net
Fri Feb 6 10:47:16 EST 2004
Thomas Heller <theller at python.net> writes:
[followup to myself, I found it]
> Michael Hudson <mwh at python.net> writes:
>
>> Thomas Heller <theller at python.net> writes:
>>
>>> I once knew how to do it, but I cannot find or remember it anymore:
>>>
>>> How can I attach *class* methods to a type in C code, when I have a
>>> function
>>>
>>> PyObject *func(PyObject *type, PyObject *arg);
>>>
>>> with the METH_O calling convention? The type is already created, I
>>> cannot insert it into the tp_methods array anymore.
>>>
>>> Something like this:
>>>
>>> class X(object):
>>> pass
>>>
>>> def func(cls, arg):
>>> ....
>>>
>>> X.func = classmethod(func)
>>
>> Just stuff it into tp_dict? You'll need to make the method object
>> yourself, but that's easy.
>>
>> I think you probably have to hope that the name of the class method
>> isn't a special method name (you'd want to call
>> typeobject.c:update_slots then, but I don't think you can arrange for
>> that to happen from outside typeobject.c as all the juicy symbols are
>> static).
>
> No special names. Here's the code:
>
> static PyObject *my_method(PyObject *self, PyObject *arg)
> {
> Py_INCREF(arg);
> return arg;
> }
>
> static PyMethodDef my_methods[] = {
> { "my_method", my_method, METH_O },
> { NULL, NULL },
> };
>
> and then ('type' is the type where I want to create the class method on):
>
[snipped non-working code]
I have to call PyDescr_NewClassMethodType:
if (somecondition) {
PyObject *meth;
PyMethodDef *ml = my_methods;
for (; ml->ml_name; ++ml) {
meth = PyDescr_NewClassMethod(type, ml);
if (!meth)
return NULL;
if (-1 == PyDict_SetItemString(type->tp_dict,
ml->ml_name,
meth))
return NULL;
}
}
> I know that there are refcount leaks in this snippet, but that's not the
> point.
Thomas
More information about the Python-list
mailing list