Skip to content

Commit 345ffd3

Browse files
Pull in main
2 parents 471ae9f + 36b139a commit 345ffd3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+3891
-2897
lines changed

Include/cpython/initconfig.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ typedef struct {
248248
int allow_exec;
249249
int allow_threads;
250250
int allow_daemon_threads;
251+
int check_multi_interp_extensions;
251252
} _PyInterpreterConfig;
252253

253254
#define _PyInterpreterConfig_INIT \
@@ -256,6 +257,7 @@ typedef struct {
256257
.allow_exec = 0, \
257258
.allow_threads = 1, \
258259
.allow_daemon_threads = 0, \
260+
.check_multi_interp_extensions = 1, \
259261
}
260262

261263
#define _PyInterpreterConfig_LEGACY_INIT \
@@ -264,6 +266,7 @@ typedef struct {
264266
.allow_exec = 1, \
265267
.allow_threads = 1, \
266268
.allow_daemon_threads = 1, \
269+
.check_multi_interp_extensions = 0, \
267270
}
268271

269272
/* --- Helper functions --------------------------------------- */

Include/cpython/pystate.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ is available in a given context. For example, forking the process
1111
might not be allowed in the current interpreter (i.e. os.fork() would fail).
1212
*/
1313

14+
/* Set if import should check a module for subinterpreter support. */
15+
#define Py_RTFLAGS_MULTI_INTERP_EXTENSIONS (1UL << 8)
16+
1417
/* Set if threads are allowed. */
1518
#define Py_RTFLAGS_THREADS (1UL << 10)
1619

Include/internal/pycore_import.h

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,113 @@ struct _import_runtime_state {
3636
const char * pkgcontext;
3737
};
3838

39+
struct _import_state {
40+
/* cached sys.modules dictionary */
41+
PyObject *modules;
42+
/* This is the list of module objects for all legacy (single-phase init)
43+
extension modules ever loaded in this process (i.e. imported
44+
in this interpreter or in any other). Py_None stands in for
45+
modules that haven't actually been imported in this interpreter.
46+
47+
A module's index (PyModuleDef.m_base.m_index) is used to look up
48+
the corresponding module object for this interpreter, if any.
49+
(See PyState_FindModule().) When any extension module
50+
is initialized during import, its moduledef gets initialized by
51+
PyModuleDef_Init(), and the first time that happens for each
52+
PyModuleDef, its index gets set to the current value of
53+
a global counter (see _PyRuntimeState.imports.last_module_index).
54+
The entry for that index in this interpreter remains unset until
55+
the module is actually imported here. (Py_None is used as
56+
a placeholder.) Note that multi-phase init modules always get
57+
an index for which there will never be a module set.
58+
59+
This is initialized lazily in PyState_AddModule(), which is also
60+
where modules get added. */
61+
PyObject *modules_by_index;
62+
/* importlib module._bootstrap */
63+
PyObject *importlib;
64+
/* override for config->use_frozen_modules (for tests)
65+
(-1: "off", 1: "on", 0: no override) */
66+
int override_frozen_modules;
67+
int override_multi_interp_extensions_check;
68+
#ifdef HAVE_DLOPEN
69+
int dlopenflags;
70+
#endif
71+
PyObject *import_func;
72+
};
73+
74+
#ifdef HAVE_DLOPEN
75+
# include <dlfcn.h>
76+
# if HAVE_DECL_RTLD_NOW
77+
# define _Py_DLOPEN_FLAGS RTLD_NOW
78+
# else
79+
# define _Py_DLOPEN_FLAGS RTLD_LAZY
80+
# endif
81+
# define DLOPENFLAGS_INIT .dlopenflags = _Py_DLOPEN_FLAGS,
82+
#else
83+
# define _Py_DLOPEN_FLAGS 0
84+
# define DLOPENFLAGS_INIT
85+
#endif
86+
87+
#define IMPORTS_INIT \
88+
{ \
89+
.override_frozen_modules = 0, \
90+
DLOPENFLAGS_INIT \
91+
}
92+
93+
extern void _PyImport_ClearCore(PyInterpreterState *interp);
94+
95+
extern Py_ssize_t _PyImport_GetNextModuleIndex(void);
96+
extern const char * _PyImport_ResolveNameWithPackageContext(const char *name);
97+
extern const char * _PyImport_SwapPackageContext(const char *newcontext);
98+
99+
extern int _PyImport_GetDLOpenFlags(PyInterpreterState *interp);
100+
extern void _PyImport_SetDLOpenFlags(PyInterpreterState *interp, int new_val);
101+
102+
extern PyObject * _PyImport_InitModules(PyInterpreterState *interp);
103+
extern PyObject * _PyImport_GetModules(PyInterpreterState *interp);
104+
extern void _PyImport_ClearModules(PyInterpreterState *interp);
105+
106+
extern void _PyImport_ClearModulesByIndex(PyInterpreterState *interp);
107+
108+
extern int _PyImport_InitDefaultImportFunc(PyInterpreterState *interp);
109+
extern int _PyImport_IsDefaultImportFunc(
110+
PyInterpreterState *interp,
111+
PyObject *func);
112+
113+
extern PyObject * _PyImport_GetImportlibLoader(
114+
PyInterpreterState *interp,
115+
const char *loader_name);
116+
extern PyObject * _PyImport_GetImportlibExternalLoader(
117+
PyInterpreterState *interp,
118+
const char *loader_name);
119+
extern PyObject * _PyImport_BlessMyLoader(
120+
PyInterpreterState *interp,
121+
PyObject *module_globals);
122+
extern PyObject * _PyImport_ImportlibModuleRepr(
123+
PyInterpreterState *interp,
124+
PyObject *module);
125+
126+
127+
extern PyStatus _PyImport_Init(void);
128+
extern void _PyImport_Fini(void);
129+
extern void _PyImport_Fini2(void);
130+
131+
extern PyStatus _PyImport_InitCore(
132+
PyThreadState *tstate,
133+
PyObject *sysmod,
134+
int importlib);
135+
extern PyStatus _PyImport_InitExternal(PyThreadState *tstate);
136+
extern void _PyImport_FiniCore(PyInterpreterState *interp);
137+
extern void _PyImport_FiniExternal(PyInterpreterState *interp);
138+
39139

40140
#ifdef HAVE_FORK
41141
extern PyStatus _PyImport_ReInitLock(void);
42142
#endif
43-
extern PyObject* _PyImport_BootstrapImp(PyThreadState *tstate);
143+
144+
145+
extern PyObject* _PyImport_GetBuiltinModuleNames(void);
44146

45147
struct _module_alias {
46148
const char *name; /* ASCII encoded string */
@@ -52,6 +154,13 @@ PyAPI_DATA(const struct _frozen *) _PyImport_FrozenStdlib;
52154
PyAPI_DATA(const struct _frozen *) _PyImport_FrozenTest;
53155
extern const struct _module_alias * _PyImport_FrozenAliases;
54156

157+
PyAPI_FUNC(int) _PyImport_CheckSubinterpIncompatibleExtensionAllowed(
158+
const char *name);
159+
160+
161+
// for testing
162+
PyAPI_FUNC(int) _PyImport_ClearExtension(PyObject *name, PyObject *filename);
163+
55164
#ifdef __cplusplus
56165
}
57166
#endif

Include/internal/pycore_interp.h

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ extern "C" {
2121
#include "pycore_function.h" // FUNC_MAX_WATCHERS
2222
#include "pycore_genobject.h" // struct _Py_async_gen_state
2323
#include "pycore_gc.h" // struct _gc_runtime_state
24+
#include "pycore_import.h" // struct _import_state
2425
#include "pycore_list.h" // struct _Py_list_state
2526
#include "pycore_global_objects.h" // struct _Py_interp_static_objects
2627
#include "pycore_tuple.h" // struct _Py_tuple_state
@@ -92,53 +93,24 @@ struct _is {
9293
struct _ceval_state ceval;
9394
struct _gc_runtime_state gc;
9495

95-
// sys.modules dictionary
96-
PyObject *modules;
97-
/* This is the list of module objects for all legacy (single-phase init)
98-
extension modules ever loaded in this process (i.e. imported
99-
in this interpreter or in any other). Py_None stands in for
100-
modules that haven't actually been imported in this interpreter.
101-
102-
A module's index (PyModuleDef.m_base.m_index) is used to look up
103-
the corresponding module object for this interpreter, if any.
104-
(See PyState_FindModule().) When any extension module
105-
is initialized during import, its moduledef gets initialized by
106-
PyModuleDef_Init(), and the first time that happens for each
107-
PyModuleDef, its index gets set to the current value of
108-
a global counter (see _PyRuntimeState.imports.last_module_index).
109-
The entry for that index in this interpreter remains unset until
110-
the module is actually imported here. (Py_None is used as
111-
a placeholder.) Note that multi-phase init modules always get
112-
an index for which there will never be a module set.
113-
114-
This is initialized lazily in _PyState_AddModule(), which is also
115-
where modules get added. */
116-
PyObject *modules_by_index;
96+
struct _import_state imports;
97+
11798
// Dictionary of the sys module
11899
PyObject *sysdict;
119100
// Dictionary of the builtins module
120101
PyObject *builtins;
121-
// importlib module
122-
PyObject *importlib;
123-
// override for config->use_frozen_modules (for tests)
124-
// (-1: "off", 1: "on", 0: no override)
125-
int override_frozen_modules;
126102

127103
PyObject *codec_search_path;
128104
PyObject *codec_search_cache;
129105
PyObject *codec_error_registry;
130106
int codecs_initialized;
131107

132108
PyConfig config;
133-
#ifdef HAVE_DLOPEN
134-
int dlopenflags;
135-
#endif
136109
unsigned long feature_flags;
137110

138111
PyObject *dict; /* Stores per-interpreter state */
139112

140113
PyObject *builtins_copy;
141-
PyObject *import_func;
142114
// Initialized to _PyEval_EvalFrameDefault().
143115
_PyFrameEvalFunction eval_frame;
144116

@@ -205,7 +177,6 @@ struct _is {
205177

206178
/* other API */
207179

208-
extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp);
209180
extern void _PyInterpreterState_Clear(PyThreadState *tstate);
210181

211182

Include/internal/pycore_pylifecycle.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc);
3030
/* Various one-time initializers */
3131

3232
extern void _Py_InitVersion(void);
33-
extern PyStatus _PyImport_Init(void);
3433
extern PyStatus _PyFaulthandler_Init(int enable);
3534
extern int _PyTraceMalloc_Init(int enable);
3635
extern PyObject * _PyBuiltin_Init(PyInterpreterState *interp);
@@ -45,7 +44,6 @@ extern int _PyBuiltins_AddExceptions(PyObject * bltinmod);
4544
extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
4645

4746
extern PyStatus _PyTime_Init(void);
48-
extern PyStatus _PyImportZip_Init(PyThreadState *tstate);
4947
extern PyStatus _PyGC_Init(PyInterpreterState *interp);
5048
extern PyStatus _PyAtExit_Init(PyInterpreterState *interp);
5149
extern int _Py_Deepfreeze_Init(void);
@@ -55,8 +53,6 @@ extern int _Py_Deepfreeze_Init(void);
5553
extern int _PySignal_Init(int install_signal_handlers);
5654
extern void _PySignal_Fini(void);
5755

58-
extern void _PyImport_Fini(void);
59-
extern void _PyImport_Fini2(void);
6056
extern void _PyGC_Fini(PyInterpreterState *interp);
6157
extern void _Py_HashRandomization_Fini(void);
6258
extern void _PyFaulthandler_Fini(void);

Include/internal/pycore_pystate.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,6 @@ extern void _PySignal_AfterFork(void);
152152
#endif
153153

154154

155-
PyAPI_FUNC(int) _PyState_AddModule(
156-
PyThreadState *tstate,
157-
PyObject* module,
158-
PyModuleDef* def);
159-
160-
161155
PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate);
162156

163157
#define HEAD_LOCK(runtime) \

Include/internal/pycore_runtime_init.h

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -97,23 +97,10 @@ extern "C" {
9797
._main_interpreter = _PyInterpreterState_INIT, \
9898
}
9999

100-
#ifdef HAVE_DLOPEN
101-
# include <dlfcn.h>
102-
# if HAVE_DECL_RTLD_NOW
103-
# define _Py_DLOPEN_FLAGS RTLD_NOW
104-
# else
105-
# define _Py_DLOPEN_FLAGS RTLD_LAZY
106-
# endif
107-
# define DLOPENFLAGS_INIT .dlopenflags = _Py_DLOPEN_FLAGS,
108-
#else
109-
# define _Py_DLOPEN_FLAGS 0
110-
# define DLOPENFLAGS_INIT
111-
#endif
112-
113100
#define _PyInterpreterState_INIT \
114101
{ \
115102
.id_refcount = -1, \
116-
DLOPENFLAGS_INIT \
103+
.imports = IMPORTS_INIT, \
117104
.ceval = { \
118105
.recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \
119106
}, \

Include/internal/pycore_sysmodule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ extern void _PySys_ClearAuditHooks(PyThreadState *tstate);
2020

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

23+
extern int _PySys_ClearAttrString(PyInterpreterState *interp,
24+
const char *name, int verbose);
25+
2326
#ifdef __cplusplus
2427
}
2528
#endif

Lib/hashlib.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,13 @@ def __get_builtin_constructor(name):
9292
import _md5
9393
cache['MD5'] = cache['md5'] = _md5.md5
9494
elif name in {'SHA256', 'sha256', 'SHA224', 'sha224'}:
95-
import _sha256
96-
cache['SHA224'] = cache['sha224'] = _sha256.sha224
97-
cache['SHA256'] = cache['sha256'] = _sha256.sha256
95+
import _sha2
96+
cache['SHA224'] = cache['sha224'] = _sha2.sha224
97+
cache['SHA256'] = cache['sha256'] = _sha2.sha256
9898
elif name in {'SHA512', 'sha512', 'SHA384', 'sha384'}:
99-
import _sha512
100-
cache['SHA384'] = cache['sha384'] = _sha512.sha384
101-
cache['SHA512'] = cache['sha512'] = _sha512.sha512
99+
import _sha2
100+
cache['SHA384'] = cache['sha384'] = _sha2.sha384
101+
cache['SHA512'] = cache['sha512'] = _sha2.sha512
102102
elif name in {'blake2b', 'blake2s'}:
103103
import _blake2
104104
cache['blake2b'] = _blake2.blake2b

Lib/test/support/import_helper.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,24 @@ def frozen_modules(enabled=True):
105105
_imp._override_frozen_modules_for_tests(0)
106106

107107

108+
@contextlib.contextmanager
109+
def multi_interp_extensions_check(enabled=True):
110+
"""Force legacy modules to be allowed in subinterpreters (or not).
111+
112+
("legacy" == single-phase init)
113+
114+
This only applies to modules that haven't been imported yet.
115+
It overrides the PyInterpreterConfig.check_multi_interp_extensions
116+
setting (see support.run_in_subinterp_with_config() and
117+
_xxsubinterpreters.create()).
118+
"""
119+
old = _imp._override_multi_interp_extensions_check(1 if enabled else -1)
120+
try:
121+
yield
122+
finally:
123+
_imp._override_multi_interp_extensions_check(old)
124+
125+
108126
def import_fresh_module(name, fresh=(), blocked=(), *,
109127
deprecated=False,
110128
usefrozen=False,

0 commit comments

Comments
 (0)