diff --git a/crossenv/scripts/site.py.tmpl b/crossenv/scripts/site.py.tmpl index 14ee185..7b20cd0 100644 --- a/crossenv/scripts/site.py.tmpl +++ b/crossenv/scripts/site.py.tmpl @@ -9,7 +9,21 @@ import sys import posix -_sentinel = posix.environ.get(b"PYTHON_CROSSENV") +# Handle subinterpreters -- everything should already be ready to go, but +# the PYTHON_CROSSENV environment variable won't be set because we're running +# in the same process +_sentinel = None +try: + import concurrent.interpreters +except ImportError: + pass +else: + if concurrent.interpreters.get_current() != concurrent.interpreters.get_main(): + _sentinel = b"{{context.sentinel}}" + + +if _sentinel is None: + _sentinel = posix.environ.get(b"PYTHON_CROSSENV") if _sentinel != b"{{context.sentinel}}": print("*******************************************************", file=sys.stderr) print("* Crossenv has leaked into another Python interpreter!", file=sys.stderr) diff --git a/tests/test_environment.py b/tests/test_environment.py index 5cb11b5..d9a4e80 100644 --- a/tests/test_environment.py +++ b/tests/test_environment.py @@ -1,5 +1,6 @@ import os import re +import subprocess from textwrap import dedent import pytest @@ -218,6 +219,30 @@ def test_environment_leak(crossenv): ), ], universal_newlines=True, + stderr=subprocess.STDOUT, + ) + assert "Crossenv has leaked" not in out + + +def test_environment_subinterpreter_leak(crossenv): + pytest.importorskip("concurrent.interpreters") + out = crossenv.check_output( + [ + "python", + "-c", + dedent( + """\ + import concurrent.interpreters + + def fn(): + print("ok") + + concurrent.interpreters.create().call(fn) + """ + ), + ], + universal_newlines=True, + stderr=subprocess.STDOUT, ) assert "Crossenv has leaked" not in out