In Python, it’s straightforward to define an inner class:
class MyClass(object):
class MyInnerClass(object):
pass
… which the inner class can be accessed as one would expect, e.g. by doing MyClass.MyInnerClass.
I am trying to set up something similar with an extension module. Typically one adds the extension types one defines to the extension module object in the modules’ <modulename>init() function with code like this:
/// …
if (PyType_Ready(&BufferModel_Type) < 0) { return; }
/// Add the BufferModel type object to the module
Py_INCREF(&BufferModel_Type);
PyModule_AddObject(module,
"Buffer",
(PyObject*)&BufferModel_Type);
/// …
In order to set up the inner class, I varied this approach to try and add a PyTypeObject* as an attribute of another PyTypeObject*, like so:
/// …
if (PyType_Ready(&ImageBufferModel_Type) < 0) { return; }
if (PyType_Ready(&ImageModel_Type) < 0) { return; }
/// Add the ImageBufferModel type object to im.Image
Py_INCREF(&ImageBufferModel_Type);
PyObject_SetAttrString((PyObject*)&ImageModel_Type,
"ImageBuffer",
(PyObject*)&ImageBufferModel_Type);
PyType_Modified((PyTypeObject*)&ImageModel_Type);
/// Add the ImageModel type object to the module
Py_INCREF(&ImageModel_Type);
PyModule_AddObject(module,
"Image",
(PyObject*)&ImageModel_Type);
/// …
… I figured PyObject_SetAttrString() would work as the introduction to “Type Objects” in the C-API docs specifically says:
Type objects can be handled using any of the
PyObject_*()orPyType_*()functions […]
… and I added the call PyType_Modified() based on its description in the docs. But so: when I compile everything and try to load the extension, I get this error:
>>> import im
Traceback (most recent call last):
File "<input>", line 1, in <module>
import im
File "im/__init__.py", line 2, in <module>
from im import (
TypeError: can't set attributes of built-in/extension type 'im.Image'
… I presume I am going about this the wrong way; what should I try instead?