Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Set m_copy to None for sys and builtins.
  • Loading branch information
ericsnowcurrently committed Mar 13, 2023
commit 617f03a934d7e19c13df6f670e4771726e9bffbe
3 changes: 3 additions & 0 deletions Python/bltinmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3098,6 +3098,9 @@ _PyBuiltin_Init(PyInterpreterState *interp)
}
Py_DECREF(debug);

/* m_copy of Py_None means it is copied some other way. */
builtinsmodule.m_base.m_copy = Py_NewRef(Py_None);

return mod;
#undef ADD_TO_ALL
#undef SETBUILTIN
Expand Down
35 changes: 31 additions & 4 deletions Python/import.c
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,16 @@ _PyImport_CheckSubinterpIncompatibleExtensionAllowed(const char *name)
return 0;
}

static inline int
match_mod_name(PyObject *actual, const char *expected)
{
if (PyUnicode_CompareWithASCIIString(actual, expected) == 0) {
return 1;
}
assert(!PyErr_Occurred());
return 0;
}

static int
fix_up_extension(PyObject *mod, PyObject *name, PyObject *filename)
{
Expand All @@ -996,7 +1006,8 @@ fix_up_extension(PyObject *mod, PyObject *name, PyObject *filename)
// when the extension module doesn't support sub-interpreters.
// XXX Why special-case the main interpreter?
if (_Py_IsMainInterpreter(tstate->interp) || def->m_size == -1) {
if (def->m_size == -1) {
/* m_copy of Py_None means it is copied some other way. */
if (def->m_size == -1 && def->m_base.m_copy != Py_None) {
if (def->m_base.m_copy) {
/* Somebody already imported the module,
likely under a different name.
Expand Down Expand Up @@ -1050,18 +1061,34 @@ import_find_extension(PyThreadState *tstate, PyObject *name,
PyObject *modules = MODULES(tstate->interp);

if (def->m_size == -1) {
PyObject *m_copy = def->m_base.m_copy;
/* Module does not support repeated initialization */
if (def->m_base.m_copy == NULL)
if (m_copy == NULL) {
return NULL;
}
else if (m_copy == Py_None) {
if (match_mod_name(name, "sys")) {
m_copy = tstate->interp->sysdict_copy;
}
else if (match_mod_name(name, "builtins")) {
m_copy = tstate->interp->builtins_copy;
}
else {
_PyErr_SetString(tstate, PyExc_ImportError, "missing m_copy");
return NULL;
}
}
/* m_copy of Py_None means it is copied some other way. */
mod = import_add_module(tstate, name);
if (mod == NULL)
if (mod == NULL) {
return NULL;
}
mdict = PyModule_GetDict(mod);
if (mdict == NULL) {
Py_DECREF(mod);
return NULL;
}
if (PyDict_Update(mdict, def->m_base.m_copy)) {
if (PyDict_Update(mdict, m_copy)) {
Py_DECREF(mod);
return NULL;
}
Expand Down
3 changes: 3 additions & 0 deletions Python/sysmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3421,6 +3421,9 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
return _PyStatus_ERR("failed to create a module object");
}

/* m_copy of Py_None means it is copied some other way. */
sysmodule.m_base.m_copy = Py_NewRef(Py_None);

PyObject *sysdict = PyModule_GetDict(sysmod);
if (sysdict == NULL) {
goto error;
Expand Down