Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
eb9d241
Add tests for extension module subinterpreter compatibility.
ericsnowcurrently Oct 24, 2022
49b4895
Add _PyInterpreterConfig.check_multi_interp_extensions and Py_RTFLAGS…
ericsnowcurrently Oct 22, 2022
ed505a6
Add _PyImport_CheckSubinterpIncompatibleExtensionAllowed().
ericsnowcurrently Oct 24, 2022
64e1dc8
Raise ImportError in subinterpreters for incompatible single-phase in…
ericsnowcurrently Oct 24, 2022
72ab9b6
Add a NEWS entry.
ericsnowcurrently Nov 3, 2022
9c24b34
Add PyInterpreterState.override_multi_interp_extensions_check.
ericsnowcurrently Nov 21, 2022
3c084eb
Add check_multi_interp_extensions().
ericsnowcurrently Nov 21, 2022
a3d3a65
Add _imp._override_multi_interp_extensions_check().
ericsnowcurrently Nov 21, 2022
ad3fe36
Add test.support.import_helper.multi_interp_extensions_check().
ericsnowcurrently Nov 21, 2022
1defec3
Add a test.
ericsnowcurrently Nov 21, 2022
99f3371
Merge branch 'main' into HEAD
ericsnowcurrently Jan 12, 2023
3c3ed2b
Fix a typo.
ericsnowcurrently Jan 12, 2023
de6c791
Add some extra diagnostic info.
ericsnowcurrently Jan 12, 2023
af114f2
Clarify various names (e.g. data keys) in the test.
ericsnowcurrently Jan 12, 2023
282e6d3
Allow long test output.
ericsnowcurrently Jan 12, 2023
3cb8645
Do not show the noop values unless different.
ericsnowcurrently Jan 12, 2023
81abbfb
Add comments to the expected values.
ericsnowcurrently Jan 12, 2023
db5d35a
Tweak the subtest labels.
ericsnowcurrently Jan 12, 2023
e0c55ad
Fix the expected results.
ericsnowcurrently Jan 12, 2023
3b2dd6d
Add a test just for how the setting is used.
ericsnowcurrently Jan 12, 2023
d648a7b
Revert "Add a test just for how the setting is used."
ericsnowcurrently Jan 12, 2023
dc8d877
Add a test for the various settings and overrides for a singlephase e…
ericsnowcurrently Jan 12, 2023
5fba674
Fix check_config.py.
ericsnowcurrently Feb 3, 2023
35d322d
Merge branch 'main' into interpreter-multi-interp-extensions-check
ericsnowcurrently Feb 6, 2023
ddf01fb
Merge branch 'main' into interpreter-multi-interp-extensions-check
ericsnowcurrently Feb 15, 2023
ee2cd3c
Merge branch 'main' into interpreter-multi-interp-extensions-check
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
Raise ImportError in subinterpreters for incompatible single-phase in…
…it extensions.
  • Loading branch information
ericsnowcurrently committed Jan 11, 2023
commit 64e1dc88e3789d70764154618a3835a2936689f9
40 changes: 38 additions & 2 deletions Lib/test/test_import/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1456,6 +1456,22 @@ def check_compatible_shared(self, name, *, strict=False):
out = os.read(r, 100)
self.assertEqual(out, b'okay')

def check_incompatible_shared(self, name):
# Differences from check_compatible_shared():
# * verify that import fails
# * "strict" is always True
__import__(name)

r, w = self.pipe()
ret = run_in_subinterp_with_config(
self.import_script(name, w),
**self.RUN_KWARGS,
check_multi_interp_extensions=True,
)
self.assertEqual(ret, 0)
out = os.read(r, 100).decode('utf-8')
self.assertEqual(out, f'ImportError: module {name} does not support loading in subinterpreters')

def check_compatible_isolated(self, name, *, strict=False):
# Differences from check_compatible_shared():
# * subinterpreter in a new process
Expand All @@ -1477,6 +1493,26 @@ def check_compatible_isolated(self, name, *, strict=False):
self.assertEqual(err, b'')
self.assertEqual(out, b'okay')

def check_incompatible_isolated(self, name):
# Differences from check_compatible_isolated():
# * verify that import fails
# * "strict" is always True
_, out, err = script_helper.assert_python_ok('-c', textwrap.dedent(f'''
import _testcapi, sys
assert {name!r} not in sys.modules, {name!r}
ret = _testcapi.run_in_subinterp_with_config(
{self.import_script(name, "sys.stdout.fileno()")!r},
**{self.RUN_KWARGS},
check_multi_interp_extensions=True,
)
assert ret == 0, ret
'''))
self.assertEqual(err, b'')
self.assertEqual(
out.decode('utf-8'),
f'ImportError: module {name} does not support loading in subinterpreters',
)

def test_builtin_compat(self):
module = 'sys'
with self.subTest(f'{module}: not strict'):
Expand All @@ -1500,9 +1536,9 @@ def test_single_init_extension_compat(self):
with self.subTest(f'{module}: not strict'):
self.check_compatible_shared(module, strict=False)
with self.subTest(f'{module}: strict, shared'):
self.check_compatible_shared(module)
self.check_incompatible_shared(module)
with self.subTest(f'{module}: strict, isolated'):
self.check_compatible_isolated(module)
self.check_incompatible_isolated(module)

@unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module")
def test_multi_init_extension_compat(self):
Expand Down
25 changes: 16 additions & 9 deletions Python/import.c
Original file line number Diff line number Diff line change
Expand Up @@ -2442,29 +2442,36 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)

PyThreadState *tstate = _PyThreadState_GET();
mod = import_find_extension(tstate, name, path);
if (mod != NULL || PyErr_Occurred()) {
Py_DECREF(name);
Py_DECREF(path);
return mod;
if (mod != NULL) {
const char *name_buf = PyUnicode_AsUTF8(name);
assert(name_buf != NULL);
if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) {
Py_DECREF(mod);
mod = NULL;
}
goto finally;
}
else if (PyErr_Occurred()) {
goto finally;
}

if (file != NULL) {
fp = _Py_fopen_obj(path, "r");
if (fp == NULL) {
Py_DECREF(name);
Py_DECREF(path);
return NULL;
goto finally;
}
}
else
fp = NULL;

mod = _PyImport_LoadDynamicModuleWithSpec(spec, fp);

Py_DECREF(name);
Py_DECREF(path);
if (fp)
fclose(fp);

finally:
Py_DECREF(name);
Py_DECREF(path);
return mod;
}

Expand Down
5 changes: 5 additions & 0 deletions Python/importdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "Python.h"
#include "pycore_call.h"
#include "pycore_import.h"
#include "pycore_pystate.h"
#include "pycore_runtime.h"

Expand Down Expand Up @@ -206,6 +207,10 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)

/* Fall back to single-phase init mechanism */

if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) {
goto error;
}

if (hook_prefix == nonascii_prefix) {
/* don't allow legacy init for non-ASCII module names */
PyErr_Format(
Expand Down