-
-
Notifications
You must be signed in to change notification settings - Fork 29.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
_PyType_GetModuleByDef optimization is incorrect #90591
Comments
I'm looking at the _PyType_GetModuleByDef optimization in https://github.com/python/cpython/pull/25504/files -- previously I assumed it's OK since it passed review.
It also adds a precondition that's not feasible public API, which this was meant to become: it should be callable with any type object. That's possible to do by keeping faster internal API and adding a public version with checks, but the diamond inheritance problem remains. Py_TPFLAGS_HEAPTYPE needs to be checked at runtime (except for the first iteration, if we're sure we're handling a static type). Does that analysis sound right? |
Oh, it seems like I misunderstood type_ready_mro() change. The check is only done on static types type. The MRO of heap types is not checked. -- In my change, I wrote:
based on this function: static int
type_ready_mro(PyTypeObject *type)
{
/* Calculate method resolution order */
if (mro_internal(type, NULL) < 0) {
return -1;
}
assert(type->tp_mro != NULL);
assert(PyTuple_Check(type->tp_mro));
/* All bases of statically allocated type should be statically allocated */
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
PyObject *mro = type->tp_mro;
Py_ssize_t n = PyTuple_GET_SIZE(mro);
for (Py_ssize_t i = 0; i < n; i++) {
PyTypeObject *base = (PyTypeObject *)PyTuple_GET_ITEM(mro, i);
if (PyType_Check(base) && (base->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
PyErr_Format(PyExc_TypeError,
"type '%.100s' is not dynamically allocated but "
"its base type '%.100s' is dynamically allocated",
type->tp_name, base->tp_name);
return -1;
}
}
}
return 0;
} This code comes from bpo-22079: commit e09bcc8
Rationale: https://bugs.python.org/issue22079#msg236830 -- Note: PyType_Ready() function was very big and complex. I splitted this huge function into sub-functions in bpo-43770. I hope that it's a little bit more readable yet. I tried but failed to find a bug about tp_getattro and tp_setattro inheritance |
An alternative would be to merge PyHeapTypeObject members into PyTypeObject. I don't get why there is a separated struture: PyTypeObject is excluded from the stable ABI. See my remark about that: Having a separated structure just static types make the code more complex and more error prone. |
It looks like this can be closed. Petr? |
Almost. It's a bugfix so it needs backports to 3.10 & 3.9. |
Right, this of course affects 3.10 and 3.9. Let me know if you want me to do the backports :) (Updating version field for this ticket) |
Just 3.10, after all. 3.9 doesn't have the function yet. I did the backport, but I'd welcome a review by a fresh set of eyes! |
Do you plan to make the function public? It would be nice! |
See #31081 |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: