aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Objects/moduleobject.c
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.com>2024-02-12 07:53:52 +0300
committershadchin <shadchin@yandex-team.com>2024-02-12 08:07:36 +0300
commitce1b7ca3171f9158180640c6a02a74b4afffedea (patch)
treee47c1e8391b1b0128262c1e9b1e6ed4c8fff2348 /contrib/tools/python3/src/Objects/moduleobject.c
parent57350d96f030db90f220ce50ee591d5c5d403df7 (diff)
downloadydb-ce1b7ca3171f9158180640c6a02a74b4afffedea.tar.gz
Update Python from 3.11.8 to 3.12.2
Diffstat (limited to 'contrib/tools/python3/src/Objects/moduleobject.c')
-rw-r--r--contrib/tools/python3/src/Objects/moduleobject.c200
1 files changed, 127 insertions, 73 deletions
diff --git a/contrib/tools/python3/src/Objects/moduleobject.c b/contrib/tools/python3/src/Objects/moduleobject.c
index d18f2060f2..4daf1a929e 100644
--- a/contrib/tools/python3/src/Objects/moduleobject.c
+++ b/contrib/tools/python3/src/Objects/moduleobject.c
@@ -9,7 +9,6 @@
#include "pycore_moduleobject.h" // _PyModule_GetDef()
#include "structmember.h" // PyMemberDef
-static Py_ssize_t max_module_number;
static PyMemberDef module_members[] = {
{"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
@@ -43,10 +42,9 @@ PyModuleDef_Init(PyModuleDef* def)
{
assert(PyModuleDef_Type.tp_flags & Py_TPFLAGS_READY);
if (def->m_base.m_index == 0) {
- max_module_number++;
Py_SET_REFCNT(def, 1);
Py_SET_TYPE(def, &PyModuleDef_Type);
- def->m_base.m_index = max_module_number;
+ def->m_base.m_index = _PyImport_GetNextModuleIndex();
}
return (PyObject*)def;
}
@@ -70,8 +68,7 @@ module_init_dict(PyModuleObject *mod, PyObject *md_dict,
if (PyDict_SetItem(md_dict, &_Py_ID(__spec__), Py_None) != 0)
return -1;
if (PyUnicode_CheckExact(name)) {
- Py_INCREF(name);
- Py_XSETREF(mod->md_name, name);
+ Py_XSETREF(mod->md_name, Py_NewRef(name));
}
return 0;
@@ -211,22 +208,7 @@ _PyModule_CreateInitialized(PyModuleDef* module, int module_api_version)
"module %s: PyModule_Create is incompatible with m_slots", name);
return NULL;
}
- /* Make sure name is fully qualified.
-
- This is a bit of a hack: when the shared library is loaded,
- the module name is "package.module", but the module calls
- PyModule_Create*() with just "module" for the name. The shared
- library loader squirrels away the true name of the module in
- _Py_PackageContext, and PyModule_Create*() will substitute this
- (if the name actually matches).
- */
- if (_Py_PackageContext != NULL) {
- const char *p = strrchr(_Py_PackageContext, '.');
- if (p != NULL && strcmp(module->m_name, p+1) == 0) {
- name = _Py_PackageContext;
- _Py_PackageContext = NULL;
- }
- }
+ name = _PyImport_ResolveNameWithPackageContext(name);
if ((m = (PyModuleObject*)PyModule_New(name)) == NULL)
return NULL;
@@ -263,9 +245,12 @@ PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_versio
PyObject *(*create)(PyObject *, PyModuleDef*) = NULL;
PyObject *nameobj;
PyObject *m = NULL;
+ int has_multiple_interpreters_slot = 0;
+ void *multiple_interpreters = (void *)0;
int has_execution_slots = 0;
const char *name;
int ret;
+ PyInterpreterState *interp = _PyInterpreterState_GET();
PyModuleDef_Init(def);
@@ -291,25 +276,60 @@ PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_versio
}
for (cur_slot = def->m_slots; cur_slot && cur_slot->slot; cur_slot++) {
- if (cur_slot->slot == Py_mod_create) {
- if (create) {
+ switch (cur_slot->slot) {
+ case Py_mod_create:
+ if (create) {
+ PyErr_Format(
+ PyExc_SystemError,
+ "module %s has multiple create slots",
+ name);
+ goto error;
+ }
+ create = cur_slot->value;
+ break;
+ case Py_mod_exec:
+ has_execution_slots = 1;
+ break;
+ case Py_mod_multiple_interpreters:
+ if (has_multiple_interpreters_slot) {
+ PyErr_Format(
+ PyExc_SystemError,
+ "module %s has more than one 'multiple interpreters' slots",
+ name);
+ goto error;
+ }
+ multiple_interpreters = cur_slot->value;
+ has_multiple_interpreters_slot = 1;
+ break;
+ default:
+ assert(cur_slot->slot < 0 || cur_slot->slot > _Py_mod_LAST_SLOT);
PyErr_Format(
PyExc_SystemError,
- "module %s has multiple create slots",
- name);
+ "module %s uses unknown slot ID %i",
+ name, cur_slot->slot);
goto error;
- }
- create = cur_slot->value;
- } else if (cur_slot->slot < 0 || cur_slot->slot > _Py_mod_LAST_SLOT) {
- PyErr_Format(
- PyExc_SystemError,
- "module %s uses unknown slot ID %i",
- name, cur_slot->slot);
+ }
+ }
+
+ /* By default, multi-phase init modules are expected
+ to work under multiple interpreters. */
+ if (!has_multiple_interpreters_slot) {
+ multiple_interpreters = Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED;
+ }
+ if (multiple_interpreters == Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED) {
+ if (!_Py_IsMainInterpreter(interp)
+ && _PyImport_CheckSubinterpIncompatibleExtensionAllowed(name) < 0)
+ {
goto error;
- } else {
- has_execution_slots = 1;
}
}
+ else if (multiple_interpreters != Py_MOD_PER_INTERPRETER_GIL_SUPPORTED
+ && interp->ceval.own_gil
+ && !_Py_IsMainInterpreter(interp)
+ && _PyImport_CheckSubinterpIncompatibleExtensionAllowed(name) < 0)
+ {
+ goto error;
+ }
if (create) {
m = create(spec, def);
@@ -323,9 +343,10 @@ PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_versio
goto error;
} else {
if (PyErr_Occurred()) {
- PyErr_Format(PyExc_SystemError,
- "creation of module %s raised unreported exception",
- name);
+ _PyErr_FormatFromCause(
+ PyExc_SystemError,
+ "creation of module %s raised unreported exception",
+ name);
goto error;
}
}
@@ -427,13 +448,16 @@ PyModule_ExecDef(PyObject *module, PyModuleDef *def)
return -1;
}
if (PyErr_Occurred()) {
- PyErr_Format(
+ _PyErr_FormatFromCause(
PyExc_SystemError,
"execution of module %s raised unreported exception",
name);
return -1;
}
break;
+ case Py_mod_multiple_interpreters:
+ /* handled in PyModule_FromDefAndSpec2 */
+ break;
default:
PyErr_Format(
PyExc_SystemError,
@@ -502,8 +526,7 @@ PyModule_GetNameObject(PyObject *m)
}
return NULL;
}
- Py_INCREF(name);
- return name;
+ return Py_NewRef(name);
}
const char *
@@ -537,8 +560,7 @@ PyModule_GetFilenameObject(PyObject *m)
}
return NULL;
}
- Py_INCREF(fileobj);
- return fileobj;
+ return Py_NewRef(fileobj);
}
const char *
@@ -707,8 +729,7 @@ static PyObject *
module_repr(PyModuleObject *m)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
-
- return PyObject_CallMethod(interp->importlib, "_module_repr", "O", m);
+ return _PyImport_ImportlibModuleRepr(interp, (PyObject *)m);
}
/* Check if the "_initializing" attribute of the module spec is set to true.
@@ -718,7 +739,11 @@ int
_PyModuleSpec_IsInitializing(PyObject *spec)
{
if (spec != NULL) {
- PyObject *value = PyObject_GetAttr(spec, &_Py_ID(_initializing));
+ PyObject *value;
+ int ok = _PyObject_LookupAttr(spec, &_Py_ID(_initializing), &value);
+ if (ok == 0) {
+ return 0;
+ }
if (value != NULL) {
int initializing = PyObject_IsTrue(value);
Py_DECREF(value);
@@ -754,19 +779,37 @@ _PyModuleSpec_IsUninitializedSubmodule(PyObject *spec, PyObject *name)
return is_uninitialized;
}
-static PyObject*
-module_getattro(PyModuleObject *m, PyObject *name)
+PyObject*
+_Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress)
{
+ // When suppress=1, this function suppresses AttributeError.
PyObject *attr, *mod_name, *getattr;
- attr = PyObject_GenericGetAttr((PyObject *)m, name);
- if (attr || !PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ attr = _PyObject_GenericGetAttrWithDict((PyObject *)m, name, NULL, suppress);
+ if (attr) {
return attr;
}
- PyErr_Clear();
+ if (suppress == 1) {
+ if (PyErr_Occurred()) {
+ // pass up non-AttributeError exception
+ return NULL;
+ }
+ }
+ else {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ // pass up non-AttributeError exception
+ return NULL;
+ }
+ PyErr_Clear();
+ }
assert(m->md_dict != NULL);
getattr = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__getattr__));
if (getattr) {
- return PyObject_CallOneArg(getattr, name);
+ PyObject *result = PyObject_CallOneArg(getattr, name);
+ if (result == NULL && suppress == 1 && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ // suppress AttributeError
+ PyErr_Clear();
+ }
+ return result;
}
if (PyErr_Occurred()) {
return NULL;
@@ -779,37 +822,48 @@ module_getattro(PyModuleObject *m, PyObject *name)
Py_DECREF(mod_name);
return NULL;
}
- Py_XINCREF(spec);
- if (_PyModuleSpec_IsInitializing(spec)) {
- PyErr_Format(PyExc_AttributeError,
- "partially initialized "
- "module '%U' has no attribute '%U' "
- "(most likely due to a circular import)",
- mod_name, name);
- }
- else if (_PyModuleSpec_IsUninitializedSubmodule(spec, name)) {
- PyErr_Format(PyExc_AttributeError,
- "cannot access submodule '%U' of module '%U' "
- "(most likely due to a circular import)",
- name, mod_name);
- }
- else {
- PyErr_Format(PyExc_AttributeError,
- "module '%U' has no attribute '%U'",
- mod_name, name);
+ if (suppress != 1) {
+ Py_XINCREF(spec);
+ if (_PyModuleSpec_IsInitializing(spec)) {
+ PyErr_Format(PyExc_AttributeError,
+ "partially initialized "
+ "module '%U' has no attribute '%U' "
+ "(most likely due to a circular import)",
+ mod_name, name);
+ }
+ else if (_PyModuleSpec_IsUninitializedSubmodule(spec, name)) {
+ PyErr_Format(PyExc_AttributeError,
+ "cannot access submodule '%U' of module '%U' "
+ "(most likely due to a circular import)",
+ name, mod_name);
+ }
+ else {
+ PyErr_Format(PyExc_AttributeError,
+ "module '%U' has no attribute '%U'",
+ mod_name, name);
+ }
+ Py_XDECREF(spec);
}
- Py_XDECREF(spec);
Py_DECREF(mod_name);
return NULL;
}
else if (PyErr_Occurred()) {
return NULL;
}
- PyErr_Format(PyExc_AttributeError,
- "module has no attribute '%U'", name);
+ if (suppress != 1) {
+ PyErr_Format(PyExc_AttributeError,
+ "module has no attribute '%U'", name);
+ }
return NULL;
}
+
+PyObject*
+_Py_module_getattro(PyModuleObject *m, PyObject *name)
+{
+ return _Py_module_getattro_impl(m, name, 0);
+}
+
static int
module_traverse(PyModuleObject *m, visitproc visit, void *arg)
{
@@ -961,7 +1015,7 @@ PyTypeObject PyModule_Type = {
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
- (getattrofunc)module_getattro, /* tp_getattro */
+ (getattrofunc)_Py_module_getattro, /* tp_getattro */
PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |