diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 9fa76c4ce59d00..d123d132420c02 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -706,6 +706,12 @@ The :mod:`multiprocessing` package mostly replicates the API of the >>> p.exitcode == -signal.SIGTERM True + .. attribute:: closed + + Boolean indicating whether the process has been closed via :meth:`close`. + + .. versionadded:: 3.14 + .. exception:: ProcessError The base class of all :mod:`multiprocessing` exceptions. diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 83c13e6fb64d1d..5140f465850b8e 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -171,6 +171,15 @@ See the :ref:`JSON command-line interface ` documentation. (Contributed by Trey Hunner in :gh:`122873`.) +multiprocessing +--------------- + +* Add the :attr:`~multiprocessing.Process.closed` property to + :class:`multiprocessing.Process` objects to determine whether + they have been closed or not. + (Contributed by James Roy in :gh:`87063`.) + + operator -------- diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py index b45f7df476f7d8..89b100d3b063f2 100644 --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -169,6 +169,13 @@ def is_alive(self): _children.discard(self) return False + @property + def closed(self): + ''' + Return whether process is closed + ''' + return self._closed + def close(self): ''' Close the Process object. diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 4b3a0645cfc84a..fc5d91691d086e 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -657,6 +657,7 @@ def test_close(self): p.daemon = True p.start() self.assertEqual(p.is_alive(), True) + self.assertFalse(p.closed) # Child is still alive, cannot close with self.assertRaises(ValueError): p.close() @@ -665,7 +666,9 @@ def test_close(self): p.join() self.assertEqual(p.is_alive(), False) self.assertEqual(p.exitcode, 0) + self.assertFalse(p.closed) p.close() + self.assertTrue(p.closed) with self.assertRaises(ValueError): p.is_alive() with self.assertRaises(ValueError): @@ -673,6 +676,7 @@ def test_close(self): with self.assertRaises(ValueError): p.terminate() p.close() + self.assertTrue(p.closed) wr = weakref.ref(p) del p diff --git a/Misc/NEWS.d/next/Library/2024-10-22-19-52-15.gh-issue-87063.fR-wJa.rst b/Misc/NEWS.d/next/Library/2024-10-22-19-52-15.gh-issue-87063.fR-wJa.rst new file mode 100644 index 00000000000000..50b43c42149a92 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-22-19-52-15.gh-issue-87063.fR-wJa.rst @@ -0,0 +1,3 @@ +Add the :attr:`~multiprocessing.Process.closed` property to +:class:`multiprocessing.Process` objects to determine whether +they have been closed or not.