gh-76785: Handle Legacy Interpreters Properly (gh-117490)

This is similar to the situation with threading._DummyThread.  The methods (incl. __del__()) of interpreters.Interpreter objects must be careful with interpreters not created by interpreters.create().  The simplest thing to start with is to disable any method that modifies or runs in the interpreter.  As part of this, the runtime keeps track of where an interpreter was created.  We also handle interpreter "refcounts" properly.
This commit is contained in:
Eric Snow 2024-04-11 17:23:25 -06:00 committed by GitHub
parent fd2bab9d28
commit fd259fdabe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 454 additions and 200 deletions

View file

@ -509,6 +509,14 @@ class TestBase(unittest.TestCase):
else:
return text
def interp_exists(self, interpid):
try:
_interpreters.whence(interpid)
except _interpreters.InterpreterNotFoundError:
return False
else:
return True
@requires_test_modules
@contextlib.contextmanager
def interpreter_from_capi(self, config=None, whence=None):
@ -545,7 +553,12 @@ class TestBase(unittest.TestCase):
@contextlib.contextmanager
def interpreter_obj_from_capi(self, config='legacy'):
with self.interpreter_from_capi(config) as interpid:
yield interpreters.Interpreter(interpid), interpid
interp = interpreters.Interpreter(
interpid,
_whence=_interpreters.WHENCE_CAPI,
_ownsref=False,
)
yield interp, interpid
@contextlib.contextmanager
def capturing(self, script):