Another workaround (with a nested class, which is a specific kind of class attribute):
from cpython.object cimport PyTypeObject, PyObject
from cpython.dict cimport PyDict_SetItem
cdef class Test1:
pass
cdef class Test2:
pass
# Building something close to:
#
# class Test1:
# class Test2:
# pass
PyDict_SetItem(<object>(<PyTypeObject*>Test1).tp_dict, 'Test2', Test2)
del globals()['Test2']
Which seems to work (the exception is expected):
>>> import mymodule
>>> mymodule.Test1
<class 'mymodule.Test1'>
>>> mymodule.Test2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'mymodule' has no attribute 'Test2'
>>> mymodule.Test1.Test2
<class 'mymodule.Test2'>
I'm using a nested class here, but it could be anything.
It's not 100% clean:
- I would have expected
<class 'mymodule.Test1.Test2'>
as a result to my last query (could be fixed, but do we want more tricks?)
- Modifying tp_dict after PyType_Ready is not clean (is it?). But, in our specific use case, I think it doesn't matter.