[docs] [issue26979] The danger of PyType_FromSpec()

Christian Tismer report at bugs.python.org
Sat Sep 15 04:46:29 EDT 2018


Christian Tismer <tismer at stackless.com> added the comment:

> 1) If I understand correctly, this problem could be solved by
> per-class C storage? Something like PyModuleDef.m_size /
> PyModule_GetState, but for classes?

No. To obtain sizeof(PyType_Type), we simply used the Python code

    type.__basicsize__

It is a simple trick, but probably very few people know this path
to get that info. At least, for me it took way too long ;-)


> 2) Making PyType_GetSlot work for static types would not be trivial.
>  All types do have the same *basic* structure (the tp_* fields), but
> the nb_*/sq_*/etc. fields don't need to be in the same order, and
> might not exist at all. Even making it work for the tp_* fields only
> would bake in some assumptions I do want to get rid of.

That's my question. Do you want to hide the fact that some fields
are direct and others are indirect? I don't think that will ever be 
changed before Python 4.0, so why put this burden on every user, then?

I would simply give access to tp_* for all types and that's it.

> I'd like to
> understand your use case better. Do you have a specific example
> here?

Yes. I need access to PyType_Type's tp_new field.

PyType_Type is a very central structure in Python, and it really hurts
to hide every attribute away.

You can see the use of this field here:
https://github.com/pyside/pyside2-setup/blob/5.11/sources/shiboken2/libshiboken/basewrapper.cpp#L319

    // The meta type creates a new type when the Python programmer extends a wrapped C++ class.
    newfunc type_new = reinterpret_cast<newfunc>(PyType_Type.tp_new);
    SbkObjectType *newType = reinterpret_cast<SbkObjectType*>(type_new(metatype, args, kwds));
    if (!newType)
        return 0;

Not being able to use this field led to many weird workaround attempts, 
which did not really work. We tried to call this function from Python code, 
but then there are several checks which make it impossible to use.

We could maybe generate a heaptype clone of PyType_Type and grab the function
from there. But this is quite obscure and cannot be the recommended way to
get at the tp_new function?

Maybe there also is a way to avoid the use of this function all together.
But we did not want to re-implement a central function of a huge project
that we only understood good enough to change it a bit.

Maybe we approach it again. At that time, it was not even clear that we
would succeed with the limited API. Now that we know, we can try more.

----------

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


More information about the docs mailing list