Josh Haberman <haber...@google.com> added the comment:
I found a way to use metaclasses with the limited API. I found that I can access PyType_Type.tp_new by creating a heap type derived from PyType_Type: static PyType_Slot dummy_slots[] = { {0, NULL} }; static PyType_Spec dummy_spec = { "module.DummyClass", 0, 0, Py_TPFLAGS_DEFAULT, dummy_slots, }; PyObject *bases = Py_BuildValue("(O)", &PyType_Type); PyObject *type = PyType_FromSpecWithBases(&dummy_spec, bases); Py_DECREF(bases); type_new = PyType_GetSlot((PyTypeObject*)type, Py_tp_new); Py_DECREF(type); #ifndef Py_LIMITED_API assert(type_new == PyType_Type.tp_new); #endif // Creates a type using a metaclass. PyObject *uses_metaclass = type_new(metaclass, args, NULL); PyType_GetSlot() can't be used on PyType_Type directly, since it is not a heap type. But a heap type derived from PyType_Type will inherit tp_new, and we can call PyType_GetSlot() on that. Once we have PyType_Type.tp_new, we can use it to create a new type using a metaclass. This avoids any of the class-switching tricks I was trying before. We can also get other slots of PyType_Type like tp_getattro to do the equivalent of super(). The PyType_FromSpecEx() function proposed in this bug would still be a nicer solution to my problem. Calling type_new() doesn't let you specify object size or slots. To work around this, I derive from a type I created with PyType_FromSpec(), relying on the fact that the size and slots will be inherited. This works, but it introduces an extra class into the hierarchy that ideally could be avoided. But I do have a workaround that appears to work, and avoids the problems associated with setting ob_type directly (like PyPy incompatibility). ---------- nosy: +haberman2 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue15870> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com