Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to dynamically create a derived type in the Python C-API
    primarykey
    data
    text
    <p>Assume we have the type <code>Noddy</code> as defined in the <a href="http://docs.python.org/extending/newtypes.html#adding-data-and-methods-to-the-basic-example" rel="noreferrer">tutorial on writing C extension modules for Python</a>. Now we want to create a derived type, overwriting only the <code>__new__()</code> method of <code>Noddy</code>.</p> <p>Currently I use the following approach (error checking stripped for readability):</p> <pre><code>PyTypeObject *BrownNoddyType = (PyTypeObject *)PyType_Type.tp_alloc(&amp;PyType_Type, 0); BrownNoddyType-&gt;tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; BrownNoddyType-&gt;tp_name = "noddy.BrownNoddy"; BrownNoddyType-&gt;tp_doc = "BrownNoddy objects"; BrownNoddyType-&gt;tp_base = &amp;NoddyType; BrownNoddyType-&gt;tp_new = BrownNoddy_new; PyType_Ready(BrownNoddyType); </code></pre> <p>This works, but I'm not sure if it is The Right Way To Do It. I would have expected that I have to set the <a href="http://docs.python.org/c-api/typeobj.html#Py_TPFLAGS_HEAPTYPE" rel="noreferrer"><code>Py_TPFLAGS_HEAPTYPE</code></a> flag, too, because I dynamically allocate the type object on the heap, but doing so leads to a segfault in the interpreter.</p> <p>I also thought about explicitly calling <code>type()</code> using <code>PyObject_Call()</code> or similar, but I discarded the idea. I would need to wrap the function <code>BrownNoddy_new()</code> in a Python function object and create a dictionary mapping <code>__new__</code> to this function object, which seems silly.</p> <p>What is the best way to go about this? Is my approach correct? Is there an interface function I missed?</p> <h2>Update</h2> <p>There are two threads on a related topic on the python-dev mailing list <a href="http://mail.python.org/pipermail/python-dev/2009-July/090875.html" rel="noreferrer">(1)</a> <a href="http://mail.python.org/pipermail/python-dev/2009-August/091192.html" rel="noreferrer">(2)</a>. From these threads and a few experiments I deduce that I shouldn't set <code>Py_TPFLAGS_HEAPTYPE</code> unless the type is allocated by a call to <code>type()</code>. There are different recommendations in these threads whether it is better to allocate the type manually or to call <code>type()</code>. I'd be happy with the latter if only I knew what the recommended way to wrap the C function that is supposed to go in the <code>tp_new</code> slot is. For regular methods this step would be easy -- I could just use <a href="http://docs.python.org/c-api/descriptor.html#PyDescr_NewMethod" rel="noreferrer"><code>PyDescr_NewMethod()</code></a> to get a suitable wrapper object. I don't know how to create such a wrapper object for my <code>__new__()</code> method, though -- maybe I need the undocumented function <code>PyCFunction_New()</code> to create such a wrapper object.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload