Commit 5a48e21f authored by Victor Stinner's avatar Victor Stinner

subprocess now emits a ResourceWarning warning

Issue #26741: subprocess.Popen destructor now emits a ResourceWarning warning
if the child process is still running.
parent a58e2c5c
...@@ -497,6 +497,10 @@ functions. ...@@ -497,6 +497,10 @@ functions.
.. versionchanged:: 3.2 .. versionchanged:: 3.2
Added context manager support. Added context manager support.
.. versionchanged:: 3.6
Popen destructor now emits a :exc:`ResourceWarning` warning if the child
process is still running.
Exceptions Exceptions
^^^^^^^^^^ ^^^^^^^^^^
......
...@@ -330,6 +330,16 @@ protocol. ...@@ -330,6 +330,16 @@ protocol.
(Contributed by Aviv Palivoda in :issue:`26404`.) (Contributed by Aviv Palivoda in :issue:`26404`.)
subprocess
----------
:class:`subprocess.Popen` destructor now emits a :exc:`ResourceWarning` warning
if the child process is still running. Use the context manager protocol (``with
proc: ...``) or call explicitly the :meth:`~subprocess.Popen.wait` method to
read the exit status of the child process (Contributed by Victor Stinner in
:issue:`26741`).
telnetlib telnetlib
--------- ---------
......
...@@ -1006,6 +1006,9 @@ class Popen(object): ...@@ -1006,6 +1006,9 @@ class Popen(object):
if not self._child_created: if not self._child_created:
# We didn't get to successfully create a child process. # We didn't get to successfully create a child process.
return return
if self.returncode is None:
warnings.warn("running subprocess %r" % self, ResourceWarning,
source=self)
# In case the child hasn't been waited on, check if it's done. # In case the child hasn't been waited on, check if it's done.
self._internal_poll(_deadstate=_maxsize) self._internal_poll(_deadstate=_maxsize)
if self.returncode is None and _active is not None: if self.returncode is None and _active is not None:
......
...@@ -2286,7 +2286,9 @@ class POSIXProcessTestCase(BaseTestCase): ...@@ -2286,7 +2286,9 @@ class POSIXProcessTestCase(BaseTestCase):
self.addCleanup(p.stderr.close) self.addCleanup(p.stderr.close)
ident = id(p) ident = id(p)
pid = p.pid pid = p.pid
del p with support.check_warnings(('', ResourceWarning)):
p = None
# check that p is in the active processes list # check that p is in the active processes list
self.assertIn(ident, [id(o) for o in subprocess._active]) self.assertIn(ident, [id(o) for o in subprocess._active])
...@@ -2305,7 +2307,9 @@ class POSIXProcessTestCase(BaseTestCase): ...@@ -2305,7 +2307,9 @@ class POSIXProcessTestCase(BaseTestCase):
self.addCleanup(p.stderr.close) self.addCleanup(p.stderr.close)
ident = id(p) ident = id(p)
pid = p.pid pid = p.pid
del p with support.check_warnings(('', ResourceWarning)):
p = None
os.kill(pid, signal.SIGKILL) os.kill(pid, signal.SIGKILL)
# check that p is in the active processes list # check that p is in the active processes list
self.assertIn(ident, [id(o) for o in subprocess._active]) self.assertIn(ident, [id(o) for o in subprocess._active])
......
...@@ -16,6 +16,9 @@ Core and Builtins ...@@ -16,6 +16,9 @@ Core and Builtins
Library Library
------- -------
- Issue #26741: subprocess.Popen destructor now emits a ResourceWarning warning
if the child process is still running.
- Issue #27056: Optimize pickle.load() and pickle.loads(), up to 10% faster - Issue #27056: Optimize pickle.load() and pickle.loads(), up to 10% faster
to deserialize a lot of small objects. to deserialize a lot of small objects.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment