[issue45383] PyType_FromSpec API fails to use metaclass of bases

Petr Viktorin report at bugs.python.org
Fri Dec 17 10:18:40 EST 2021


Petr Viktorin <encukou at gmail.com> added the comment:

I don't see how instantiating a metaclass with non-default tp_new would work if you don't know some details about the specific metaclass. So IMO we can we limit ourselves to scenarios where either:
1) the metaclass uses default tp_new, or
2) the code that creates the class knows about the metaclass

For case 2), we could leave allocation to the calling code, and add an API function that does the rest of the work of applying the spec. Something like:

    /* Create a metaclass */
    metatype_spec = {stuff};
    metatype = PyType_FromSpecAndBases(&metatype_spec, &PyType_Type);
    /* Create a type */
    type_spec = {other_stuff};
    newtype = alloc_metatype();
    PyType_ApplySpec(newtype, &type_spec);

PyType_ApplySpec would assert PyType_Ready wasn't called before, and call it after filling in the name, slots, etc.
The metatype could disable its tp_new to disallow PyType_FromSpec (and Python __new__), effectively enforcing "using_metaclass_cinit_pretty_promise_please".

There could be a slot for code to run at the end of PyType_ApplySpec -- the "PyArray_InitDTypeFromSpec" in your pseudocode.


That seems better than calling the metaclass, but to answer questions on that idea:

>> - basicsize/itemsize could be allowed with __basicsize__/__itemsize__ in the dict.
>Do we need this?  I need the basicsize of the metaclass, but that of the class seems fixed/OK?

That's the size of the instance. One more level down :)

>> - members could theoretically be copied to individual descriptors; there doesn't seem much need for keeping tp_members around.
> But a Python MetaClass (that the author may not even realize about) might need access to these to work properly?
> A bit far fetched, but...

Seems very far-fetched to me. IMO these, like e.g. tp_methods, should only be used as arguments for the code that puts the descriptors in __dict__. How the descriptors got there is a detail, the class doesn't need to use tp_members (nor advertise that it does).

----------

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue45383>
_______________________________________


More information about the Python-bugs-list mailing list