diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index 2ec94bfe138..0545267bfa3 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -497,6 +497,10 @@ functions. .. versionchanged:: 3.2 Added context manager support. + .. versionchanged:: 3.6 + Popen destructor now emits a :exc:`ResourceWarning` warning if the child + process is still running. + Exceptions ^^^^^^^^^^ diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst index 67fd50f486e..2ec8f004b26 100644 --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -330,6 +330,16 @@ protocol. (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 --------- diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 41a9de10f5e..b853f4d5932 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1006,6 +1006,9 @@ class Popen(object): if not self._child_created: # We didn't get to successfully create a child process. 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. self._internal_poll(_deadstate=_maxsize) if self.returncode is None and _active is not None: diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 5239e5aa4e0..a8f0a64e96e 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -2286,7 +2286,9 @@ class POSIXProcessTestCase(BaseTestCase): self.addCleanup(p.stderr.close) ident = id(p) pid = p.pid - del p + with support.check_warnings(('', ResourceWarning)): + p = None + # check that p is in the active processes list self.assertIn(ident, [id(o) for o in subprocess._active]) @@ -2305,7 +2307,9 @@ class POSIXProcessTestCase(BaseTestCase): self.addCleanup(p.stderr.close) ident = id(p) pid = p.pid - del p + with support.check_warnings(('', ResourceWarning)): + p = None + os.kill(pid, signal.SIGKILL) # check that p is in the active processes list self.assertIn(ident, [id(o) for o in subprocess._active]) diff --git a/Misc/NEWS b/Misc/NEWS index ba66c4e5d59..5dccc5c5ba7 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,6 +16,9 @@ Core and Builtins 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 to deserialize a lot of small objects.