https://github.com/python/cpython/commit/239808c1896e879c8cd58150630325b8d0b0fb65
commit: 239808c1896e879c8cd58150630325b8d0b0fb65
branch: main
author: Peter Bierma <[email protected]>
committer: ZeroIntensity <[email protected]>
date: 2026-10-21T17:16:40-04:00
summary:

gh-158370: Implement the context manager protocol for `Interpreter` objects 
(GH-158372)

files:
A Misc/NEWS.d/next/Library/2026-09-28-00-00-00.gh-issue-158370.ctxmgr.rst
M Doc/library/concurrent.interpreters.rst
M Doc/whatsnew/3.16.rst
M Lib/concurrent/interpreters/__init__.py
M Lib/test/test_interpreters/test_api.py

diff --git a/Doc/library/concurrent.interpreters.rst 
b/Doc/library/concurrent.interpreters.rst
index 05bf497b68a2082..058e59b32fd15a6 100644
--- a/Doc/library/concurrent.interpreters.rst
+++ b/Doc/library/concurrent.interpreters.rst
@@ -244,6 +244,16 @@ Interpreter objects
    Generally, :class:`Interpreter` shouldn't be called directly.
    Instead, use :func:`create` or one of the other module functions.
 
+   :class:`!Interpreter` objects support the :term:`context manager`
+   protocol. Exiting the :keyword:`with` block calls :meth:`close`::
+
+      with interpreters.create() as interp:
+          interp.exec('print("hello")')
+
+   .. versionchanged:: next
+      Added support for using :class:`!Interpreter` objects in
+      a :term:`context manager`.
+
    .. attribute:: id
 
       (read-only)
diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst
index b29170b5b0b93da..a0275c9932a282d 100644
--- a/Doc/whatsnew/3.16.rst
+++ b/Doc/whatsnew/3.16.rst
@@ -192,6 +192,13 @@ concurrent.futures
   Use the :meth:`!close` method to explicitly close the iterator.
   (Contributed by xzmeng and Serhiy Storchaka in :gh:`108518`.)
 
+concurrent.interpreters
+-----------------------
+
+* :class:`~concurrent.interpreters.Interpreter` objects now support the
+  :term:`context manager` protocol. Exiting the :keyword:`with` block calls
+  :meth:`~concurrent.interpreters.Interpreter.close`.
+  (Contributed by Peter Bierma in :gh:`158370`.)
 
 csv
 ---
diff --git a/Lib/concurrent/interpreters/__init__.py 
b/Lib/concurrent/interpreters/__init__.py
index 335a744b727d100..3053bfbcb122771 100644
--- a/Lib/concurrent/interpreters/__init__.py
+++ b/Lib/concurrent/interpreters/__init__.py
@@ -192,6 +192,12 @@ def close(self):
         """
         return _interpreters.destroy(self._id, restrict=True)
 
+    def __enter__(self):
+        return self
+
+    def __exit__(self, *exc_info):
+        self.close()
+
     def prepare_main(self, ns=None, /, **kwargs):
         """Bind the given values into the interpreter's __main__.
 
diff --git a/Lib/test/test_interpreters/test_api.py 
b/Lib/test/test_interpreters/test_api.py
index aac3cdd717668ca..a9e296891bb8705 100644
--- a/Lib/test/test_interpreters/test_api.py
+++ b/Lib/test/test_interpreters/test_api.py
@@ -832,6 +832,31 @@ def task():
         assert_python_ok('-c', code)
 
 
+class TestInterpreterContextManager(TestBase):
+
+    def test_basic(self):
+        main, = interpreters.list_all()
+        with interpreters.create() as interp:
+            self.assertIsInstance(interp, interpreters.Interpreter)
+            self.assertEqual(interpreters.list_all(), [main, interp])
+        self.assertEqual(interpreters.list_all(), [main])
+        with self.assertRaises(InterpreterNotFoundError):
+            interp.exec('pass')
+
+    def test_exception(self):
+        main, = interpreters.list_all()
+        with self.assertRaises(ZeroDivisionError):
+            with interpreters.create() as interp:
+                1/0
+        self.assertEqual(interpreters.list_all(), [main])
+
+    def test_main(self):
+        main, = interpreters.list_all()
+        with self.assertRaises(InterpreterError):
+            with main:
+                pass
+
+
 class TestInterpreterPrepareMain(TestBase):
 
     def test_empty(self):
diff --git 
a/Misc/NEWS.d/next/Library/2026-09-28-00-00-00.gh-issue-158370.ctxmgr.rst 
b/Misc/NEWS.d/next/Library/2026-09-28-00-00-00.gh-issue-158370.ctxmgr.rst
new file mode 100644
index 000000000000000..f4b9e2469daa3ed
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-09-28-00-00-00.gh-issue-158370.ctxmgr.rst
@@ -0,0 +1,2 @@
+:class:`concurrent.interpreters.Interpreter` objects now support the
+:term:`context manager` protocol.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to