8000 gh-101758: Clean Up Uses of Import State by ericsnowcurrently · Pull Request #101919 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-101758: Clean Up Uses of Import State #101919

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

Merged
merged 22 commits into from
Feb 15, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4433124
Group code in import.c.
ericsnowcurrently Feb 14, 2023
7626bab
Move PyState_*() to import.c.
ericsnowcurrently Feb 14, 2023
5836e93
Add _PyImport_GetNextModuleIndex().
ericsnowcurrently Feb 14, 2023
bc031c1
Add _PyImport_SwapPackageContext() and _PyImport_ResolveNameWithPacka…
ericsnowcurrently Feb 14, 2023
f67c299
Add _PyImport_GetBuiltinModuleNames().
ericsnowcurrently Feb 14, 2023
9b312e1
Add an "extension modules" section.
ericsnowcurrently Feb 14, 2023
24ec4de
Move the "extension modules" section down.
ericsnowcurrently Feb 14, 2023
b2043e4
Add _PyImport_GetDLOpenFlags() and _PyImport_SetDLOpenFlags().
ericsnowcurrently Feb 14, 2023
43d8de7
Hide sys.modules.
ericsnowcurrently Feb 14, 2023
b7cabeb
_PyInterpreterState_ClearModules() -> _PyImport_ClearModulesByIndex().
ericsnowcurrently Feb 14, 2023
d4693ea
Hide interp->import_func.
ericsnowcurrently Feb 14, 2023
7120be2
Hide interp->importlib.
ericsnowcurrently Feb 14, 2023
1935ee5
Add _PyImport_InitCore() and _PyImport_InitExternal(). 8000
ericsnowcurrently Feb 14, 2023
7e29b7c
Re-order import.c sections.
ericsnowcurrently Feb 14, 2023
66de41d
Add _PyImport_FiniExternal() and _PyImport_FiniCore().
ericsnowcurrently Feb 14, 2023
384bd69
Factor out init_builtin_modules_table() and fini_builtin_builtins_tab…
ericsnowcurrently Feb 14, 2023
e4777b7
Add PyInterpreterState.imports.
ericsnowcurrently Feb 14, 2023
48fb47c
Move the lifecycle sections to the bottom.
ericsnowcurrently Feb 14, 2023
e8930c8
Add macros for runtime-global import state.
ericsnowcurrently Feb 14, 2023
79a72c4
minor fixes
ericsnowcurrently Feb 14, 2023
0527913
Drop _PyState_AddModule().
ericsnowcurrently Feb 15, 2023
a4deb8a
Drop a wrong assert.
ericsnowcurrently Feb 15, 2023
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
Next Next commit
Add _PyImport_FiniExternal() and _PyImport_FiniCore().
  • Loading branch information
ericsnowcurrently committed Feb 14, 2023
commit 66de41d8f326358a1d0b5a86d6fcfe3905d33a33
7 changes: 7 additions & 0 deletions Include/internal/pycore_import.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,18 @@ extern PyObject * _PyImport_ImportlibModuleRepr(
PyObject *module);


extern PyStatus _PyImport_Init(void);
extern void _PyImport_Fini(void);
extern void _PyImport_Fini2(void);

extern PyStatus _PyImport_InitCore(
PyThreadState *tstate,
PyObject *sysmod,
int importlib);
extern PyStatus _PyImport_InitExternal(PyThreadState *tstate);
extern void _PyImport_FiniCore(PyInterpreterState *interp);
extern void _PyImport_FiniExternal(PyInterpreterState *interp);


#ifdef HAVE_FORK
extern PyStatus _PyImport_ReInitLock(void);
Expand Down
3 changes: 0 additions & 3 deletions Include/internal/pycore_pylifecycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc);
/* Various one-time initializers */

extern void _Py_InitVersion(void);
extern PyStatus _PyImport_Init(void);
extern PyStatus _PyFaulthandler_Init(int enable);
extern int _PyTraceMalloc_Init(int enable);
extern PyObject * _PyBuiltin_Init(PyInterpreterState *interp);
Expand All @@ -54,8 +53,6 @@ extern int _Py_Deepfreeze_Init(void);
extern int _PySignal_Init(int install_signal_handlers);
extern void _PySignal_Fini(void);

extern void _PyImport_Fini(void);
extern void _PyImport_Fini2(void);
extern void _PyGC_Fini(PyInterpreterState *interp);
extern void _Py_HashRandomization_Fini(void);
extern void _PyFaulthandler_Fini(void);
Expand Down
3 changes: 3 additions & 0 deletions Include/internal/pycore_sysmodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ extern void _PySys_ClearAuditHooks(PyThreadState *tstate);

PyAPI_FUNC(int) _PySys_SetAttr(PyObject *, PyObject *);

extern int _PySys_ClearAttrString(PyInterpreterState *interp,
const char *name, int verbose);

#ifdef __cplusplus
}
#endif
Expand Down
43 changes: 43 additions & 0 deletions Python/import.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ static inline void _extensions_cache_clear(void);
void
_PyImport_Fini(void)
{
/* Destroy the database used by _PyImport_{Fixup,Find}Extension */
_extensions_cache_clear();
if (import_lock != NULL) {
PyThread_free_lock(import_lock);
Expand Down Expand Up @@ -145,6 +146,9 @@ static int init_importlib(PyThreadState *tstate, PyObject *sysmod);
PyStatus
_PyImport_InitCore(PyThreadState *tstate, PyObject *sysmod, int importlib)
{
// XXX Initialize here: interp->modules and interp->import_func.
// XXX Initialize here: sys.modules and sys.meta_path.

if (importlib) {
/* This call sets up builtin and frozen import support */
if (init_importlib(tstate, sysmod) < 0) {
Expand All @@ -167,15 +171,38 @@ _PyImport_IsInitialized(PyInterpreterState *interp)
return 1;
}

/* Clear the direct per-interpreter import state, if not cleared already. */
void
_PyImport_ClearCore(PyInterpreterState *interp)
{
/* interp->modules should have been cleaned up and cleared already
by _PyImport_FiniCore(). */
Py_CLEAR(interp->modules);
Py_CLEAR(interp->modules_by_index);
Py_CLEAR(interp->importlib);
Py_CLEAR(interp->import_func);
}

void
_PyImport_FiniCore(PyInterpreterState *interp)
{
int verbose = _PyInterpreterState_GetConfig(interp)->verbose;

if (_PySys_ClearAttrString(interp, "meta_path", verbose) < 0) {
PyErr_WriteUnraisable(NULL);
}

// XXX Pull in most of finalize_modules() in pylifecycle.c.

if (_PySys_ClearAttrString(interp, "modules", verbose) < 0) {
PyErr_WriteUnraisable(NULL);
}

_PyImport_ClearCore(interp);
}

// XXX Add something like _PyImport_Disable() for use early in interp fini?


/* "external" imports */

Expand Down Expand Up @@ -222,6 +249,8 @@ _PyImport_InitExternal(PyThreadState *tstate)
{
int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose;

// XXX Initialize here: sys.path_hooks and sys.path_importer_cache.

if (init_importlib_external(tstate->interp) != 0) {
_PyErr_Print(tstate);
return _PyStatus_ERR("external importer setup failed");
Expand All @@ -235,6 +264,20 @@ _PyImport_InitExternal(PyThreadState *tstate)
return _PyStatus_OK();
}

void
_PyImport_FiniExternal(PyInterpreterState *interp)
{
int verbose = _PyInterpreterState_GetConfig(interp)->verbose;

// XXX Uninstall importlib metapath importers here?

if (_PySys_ClearAttrString(interp, "path_importer_cache", verbose) < 0) {
PyErr_WriteUnraisable(NULL);
}
if (_PySys_ClearAttrString(interp, "path_hooks", verbose) < 0) {
PyErr_WriteUnraisable(NULL);
}
}

/*******************/
/* the import lock */
Expand Down
22 changes: 16 additions & 6 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -1306,8 +1306,11 @@ finalize_modules_delete_special(PyThreadState *tstate, int verbose)
static const char * const sys_deletes[] = {
"path", "argv", "ps1", "ps2",
"last_type", "last_value", "last_traceback",
"path_hooks", "path_importer_cache", "meta_path",
"__interactivehook__",
// path_hooks and path_importer_cache are cleared
// by _PyImport_FiniExternal().
// XXX Clear meta_path in _PyImport_FiniCore().
"meta_path",
NULL
};

Expand All @@ -1328,10 +1331,7 @@ finalize_modules_delete_special(PyThreadState *tstate, int verbose)

const char * const *p;
for (p = sys_deletes; *p != NULL; p++) {
if (verbose) {
PySys_WriteStderr("# clear sys.%s\n", *p);
}
if (PyDict_SetItemString(interp->sysdict, *p, Py_None) < 0) {
if (_PySys_ClearAttrString(interp, *p, verbose) < 0) {
PyErr_WriteUnraisable(NULL);
}
}
Expand Down Expand Up @@ -1503,6 +1503,7 @@ finalize_clear_sys_builtins_dict(PyInterpreterState *interp, int verbose)


/* Clear modules, as good as we can */
// XXX Move most of this to import.c.
static void
finalize_modules(PyThreadState *tstate)
{
Expand Down Expand Up @@ -1788,6 +1789,8 @@ Py_FinalizeEx(void)
runtime->initialized = 0;
runtime->core_initialized = 0;

// XXX Call something like _PyImport_Disable() here?

/* Destroy the state of all threads of the interpreter, except of the
current thread. In practice, only daemon threads should still be alive,
except if wait_for_thread_shutdown() has been cancelled by CTRL+C.
Expand Down Expand Up @@ -1837,6 +1840,7 @@ Py_FinalizeEx(void)
PyGC_Collect();

/* Destroy all modules */
_PyImport_FiniExternal(tstate->interp);
finalize_modules(tstate);

/* Print debug stats if any */
Expand Down Expand Up @@ -1870,7 +1874,9 @@ Py_FinalizeEx(void)
so it is possible to use tracemalloc in objects destructor. */
_PyTraceMalloc_Fini();

/* Destroy the database used by _PyImport_{Fixup,Find}Extension */
/* Finalize any remaining import state */
// XXX Move these up to where finalize_modules() is currently.
_PyImport_FiniCore(tstate->interp);
_PyImport_Fini();

/* unload faulthandler module */
Expand Down Expand Up @@ -2110,6 +2116,10 @@ Py_EndInterpreter(PyThreadState *tstate)
Py_FatalError("not the last thread");
}

// XXX Call something like _PyImport_Disable() here?

_PyImport_FiniExternal(tstate->interp);
_PyImport_FiniCore(tstate->interp);
finalize_modules(tstate);

finalize_interp_clear(tstate);
Expand Down
14 changes: 14 additions & 0 deletions Python/sysmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,20 @@ PySys_SetObject(const char *name, PyObject *v)
return sys_set_object_str(interp, name, v);
}

int
_PySys_ClearAttrString(PyInterpreterState *interp,
const char *name, int verbose)
{
if (verbose) {
PySys_WriteStderr("# clear sys.%s\n", name);
}
/* To play it safe, we set the attr to None instead of deleting it. */
if (PyDict_SetItemString(interp->sysdict, name, Py_None) < 0) {
return -1;
}
return 0;
}


static int
should_audit(PyInterpreterState *interp)
Expand Down
0