Defining *class* methods on C code

Thomas Heller theller at python.net
Fri Feb 6 16:47:16 CET 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