FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-117578: Introduce _PyType_GetModuleByDef2 private function by neonene · Pull Request #117661 · python/cpython · GitHub

/ cpython Public
1 change: 1 addition & 0 deletions Include/internal/pycore_typeobject.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ extern PyObject * _PyType_GetBases(PyTypeObject *type);
extern PyObject * _PyType_GetMRO(PyTypeObject *type);
extern PyObject* _PyType_GetSubclasses(PyTypeObject *);
extern int _PyType_HasSubclasses(PyTypeObject *);
PyAPI_FUNC(PyObject *) _PyType_GetModuleByDef2(PyTypeObject *, PyTypeObject *, PyModuleDef *);

// PyType_Ready() must be called if _PyType_IsReady() is false.
// See also the Py_TPFLAGS_READY flag.
Expand Down
8 changes: 3 additions & 5 deletions Modules/_decimal/_decimal.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <Python.h>
#include "pycore_long.h" // _PyLong_IsZero()
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_typeobject.h"
#include "complexobject.h"
#include "mpdecimal.h"

Expand Down Expand Up @@ -120,11 +121,8 @@ get_module_state_by_def(PyTypeObject *tp)
static inline decimal_state *
find_state_left_or_right(PyObject *left, PyObject *right)
{
PyObject *mod = PyType_GetModuleByDef(Py_TYPE(left), &_decimal_module);
if (mod == NULL) {
PyErr_Clear();
mod = PyType_GetModuleByDef(Py_TYPE(right), &_decimal_module);
}
PyObject *mod = _PyType_GetModuleByDef2(Py_TYPE(left), Py_TYPE(right),
&_decimal_module);
assert(mod != NULL);
return get_module_state(mod);
}
Expand Down
52 changes: 45 additions & 7 deletions Objects/typeobject.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -4825,24 +4825,39 @@ PyType_GetModuleState(PyTypeObject *type)
/* Get the module of the first superclass where the module has the
* given PyModuleDef.
*/
PyObject *
PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def)
static inline PyObject *
get_module_by_def(PyTypeObject *type, PyModuleDef *def)
{
assert(PyType_Check(type));

if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) {
// type_ready_mro() ensures that no heap type is
// contained in a static type MRO.
return NULL;
}
else {
PyHeapTypeObject *ht = (PyHeapTypeObject*)type;
PyObject *module = ht->ht_module;
if (module && _PyModule_GetDef(module) == def) {
return module;
}
Comment thread
encukou marked this conversation as resolved.
}

PyObject *res = NULL;
BEGIN_TYPE_LOCK()

PyObject *mro = lookup_tp_mro(type);
// The type must be ready
assert(mro != NULL);
assert(PyTuple_Check(mro));
// mro_invoke() ensures that the type MRO cannot be empty, so we don't have
// to check i < PyTuple_GET_SIZE(mro) at the first loop iteration.
// mro_invoke() ensures that the type MRO cannot be empty.
assert(PyTuple_GET_SIZE(mro) >= 1);
// Also, the first item in the MRO is the type itself, which
// we already checked above. We skip it in the loop.
assert(PyTuple_GET_ITEM(mro, 0) == (PyObject *)type);

Py_ssize_t n = PyTuple_GET_SIZE(mro);
for (Py_ssize_t i = 0; i < n; i++) {
for (Py_ssize_t i = 1; i < n; i++) {
PyObject *super = PyTuple_GET_ITEM(mro, i);
if(!_PyType_HasFeature((PyTypeObject *)super, Py_TPFLAGS_HEAPTYPE)) {
// Static types in the MRO need to be skipped
Expand All @@ -4857,14 +4872,37 @@ PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def)
}
}
END_TYPE_LOCK()
return res;
}

if (res == NULL) {
PyObject *
PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def)
{
PyObject *module = get_module_by_def(type, def);
if (module == NULL) {
PyErr_Format(
PyExc_TypeError,
"PyType_GetModuleByDef: No superclass of '%s' has the given module",
type->tp_name);
}
return res;
return module;
}

PyObject *
_PyType_GetModuleByDef2(PyTypeObject *left, PyTypeObject *right,
PyModuleDef *def)
{
PyObject *module = get_module_by_def(left, def);
if (module == NULL) {
module = get_module_by_def(right, def);
if (module == NULL) {
PyErr_Format(
PyExc_TypeError,
"PyType_GetModuleByDef: No superclass of '%s' nor '%s' has "
"the given module", left->tp_name, right->tp_name);
}
}
return module;
}

void *
Expand Down

Back | FazBrowse Home | New Git URL