mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +00:00
136 lines
4.1 KiB
Python
136 lines
4.1 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
import pickle
|
|
import sys
|
|
|
|
import pytest
|
|
|
|
|
|
@pytest.mark.skipif(
|
|
sys.platform.startswith("emscripten"), reason="Requires loadable modules"
|
|
)
|
|
def test_independent_subinterpreters():
|
|
"""Makes sure the internals object differs across independent subinterpreters"""
|
|
|
|
sys.path.append(".")
|
|
|
|
# This is supposed to be added in 3.14.0b3
|
|
if sys.version_info >= (3, 15):
|
|
import interpreters
|
|
elif sys.version_info >= (3, 13):
|
|
import _interpreters as interpreters
|
|
elif sys.version_info >= (3, 12):
|
|
import _xxsubinterpreters as interpreters
|
|
else:
|
|
pytest.skip("Test requires a the interpreters stdlib module")
|
|
|
|
import mod_per_interpreter_gil as m
|
|
|
|
code = """
|
|
import mod_per_interpreter_gil as m
|
|
import pickle
|
|
with open(pipeo, 'wb') as f:
|
|
pickle.dump(m.internals_at(), f)
|
|
"""
|
|
|
|
interp1 = interpreters.create()
|
|
interp2 = interpreters.create()
|
|
try:
|
|
try:
|
|
res0 = interpreters.run_string(interp1, "import mod_shared_interpreter_gil")
|
|
if res0 is not None:
|
|
res0 = res0.msg
|
|
except Exception as e:
|
|
res0 = str(e)
|
|
|
|
pipei, pipeo = os.pipe()
|
|
interpreters.run_string(interp1, code, shared={"pipeo": pipeo})
|
|
with open(pipei, "rb") as f:
|
|
res1 = pickle.load(f)
|
|
|
|
pipei, pipeo = os.pipe()
|
|
interpreters.run_string(interp2, code, shared={"pipeo": pipeo})
|
|
with open(pipei, "rb") as f:
|
|
res2 = pickle.load(f)
|
|
|
|
# do this while the two interpreters are active
|
|
import mod_per_interpreter_gil as m2
|
|
|
|
assert m.internals_at() == m2.internals_at(), (
|
|
"internals should be the same within the main interpreter"
|
|
)
|
|
finally:
|
|
interpreters.destroy(interp1)
|
|
interpreters.destroy(interp2)
|
|
|
|
assert "does not support loading in subinterpreters" in res0, (
|
|
"cannot use shared_gil in a default subinterpreter"
|
|
)
|
|
assert res1 != m.internals_at(), "internals should differ from main interpreter"
|
|
assert res2 != m.internals_at(), "internals should differ from main interpreter"
|
|
assert res1 != res2, "internals should differ between interpreters"
|
|
|
|
# do this after the two interpreters are destroyed and only one remains
|
|
import mod_per_interpreter_gil as m3
|
|
|
|
assert m.internals_at() == m3.internals_at(), (
|
|
"internals should be the same within the main interpreter"
|
|
)
|
|
|
|
|
|
@pytest.mark.skipif(
|
|
sys.platform.startswith("emscripten"), reason="Requires loadable modules"
|
|
)
|
|
def test_dependent_subinterpreters():
|
|
"""Makes sure the internals object differs across subinterpreters"""
|
|
|
|
sys.path.append(".")
|
|
|
|
if sys.version_info >= (3, 15):
|
|
import interpreters
|
|
elif sys.version_info >= (3, 13):
|
|
import _interpreters as interpreters
|
|
elif sys.version_info >= (3, 12):
|
|
import _xxsubinterpreters as interpreters
|
|
else:
|
|
pytest.skip("Test requires a the interpreters stdlib module")
|
|
|
|
import mod_shared_interpreter_gil as m
|
|
|
|
code = """
|
|
import mod_shared_interpreter_gil as m
|
|
import pickle
|
|
with open(pipeo, 'wb') as f:
|
|
pickle.dump(m.internals_at(), f)
|
|
"""
|
|
|
|
try:
|
|
interp1 = interpreters.create("legacy")
|
|
except TypeError:
|
|
pytest.skip("interpreters module needs to support legacy config")
|
|
|
|
try:
|
|
pipei, pipeo = os.pipe()
|
|
interpreters.run_string(interp1, code, shared={"pipeo": pipeo})
|
|
with open(pipei, "rb") as f:
|
|
res1 = pickle.load(f)
|
|
|
|
# do this while the other interpreter is active
|
|
import mod_shared_interpreter_gil as m2
|
|
|
|
assert m.internals_at() == m2.internals_at(), (
|
|
"internals should be the same within the main interpreter"
|
|
)
|
|
finally:
|
|
interpreters.destroy(interp1)
|
|
|
|
assert res1 != m.internals_at(), "internals should differ from main interpreter"
|
|
|
|
# do this after the other interpreters are destroyed and only one remains
|
|
import mod_shared_interpreter_gil as m3
|
|
|
|
assert m.internals_at() == m3.internals_at(), (
|
|
"internals should be the same within the main interpreter"
|
|
)
|