From 99d0929fb711bdc20ad2f706c1f548bef7113d01 Mon Sep 17 00:00:00 2001 From: ruang Date: Tue, 22 Oct 2024 20:06:13 +0800 Subject: [PATCH 01/17] Add is_closed method to Process class --- Lib/multiprocessing/process.py | 6 ++++++ Lib/test/_test_multiprocessing.py | 15 +++++++++++++++ .../2024-10-22-19-52-15.gh-issue-87063.fR-wJa.rst | 2 ++ 3 files changed, 23 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-10-22-19-52-15.gh-issue-87063.fR-wJa.rst diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py index b45f7df476f7d8..01a5655117b14d 100644 --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -169,6 +169,12 @@ def is_alive(self): _children.discard(self) return False + def is_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..b247cebc4b0bda 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -649,6 +649,21 @@ def _test_close(cls, rc=0, q=None): q.get() sys.exit(rc) + def test_is_close(self): + if self.TYPE == "threads": + self.skipTest('test not appropriate for {}'.format(self.TYPE)) + q = self.Queue() + p = self.Process(target=self._test_close, kwargs={'q': q}) + self.assertFalse(p.is_closed()) + p.close() + self.assertTrue(p.is_closed()) + + wr = weakref.ref(p) + del p + gc.collect() + self.assertIs(wr(), None) + close_queue(q) + def test_close(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) 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..8331c081af04a7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-22-19-52-15.gh-issue-87063.fR-wJa.rst @@ -0,0 +1,2 @@ +Add the :meth:`.is_closed()` in the :class:`multiprocessing.Process` to +determine whether the process is closed. From 9d1b78a9a8c09d871c98c6aacf42a1acb3cdf0b2 Mon Sep 17 00:00:00 2001 From: "RUANG (Roy James)" Date: Tue, 22 Oct 2024 20:41:14 +0800 Subject: [PATCH 02/17] Change NEWS --- .../next/Library/2024-10-22-19-52-15.gh-issue-87063.fR-wJa.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 8331c081af04a7..b8356f7a08115f 100644 --- 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 @@ -1,2 +1,2 @@ -Add the :meth:`.is_closed()` in the :class:`multiprocessing.Process` to +Add the ``is_closed()`` in the :class:`multiprocessing.Process` to determine whether the process is closed. From 1da383f94c04d5569f921e515a0ce3bdeb48a2aa Mon Sep 17 00:00:00 2001 From: ruang Date: Tue, 22 Oct 2024 20:50:07 +0800 Subject: [PATCH 03/17] Remove Queue --- Lib/test/_test_multiprocessing.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index b247cebc4b0bda..ad5786686c91a4 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -652,8 +652,9 @@ def _test_close(cls, rc=0, q=None): def test_is_close(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) - q = self.Queue() - p = self.Process(target=self._test_close, kwargs={'q': q}) + def _test_task(): + pass + p = self.Process(target=_test_task) self.assertFalse(p.is_closed()) p.close() self.assertTrue(p.is_closed()) @@ -662,7 +663,6 @@ def test_is_close(self): del p gc.collect() self.assertIs(wr(), None) - close_queue(q) def test_close(self): if self.TYPE == "threads": From ef00cd899c75dfa195938c7cfe5a86a740fec599 Mon Sep 17 00:00:00 2001 From: ruang Date: Tue, 22 Oct 2024 21:05:10 +0800 Subject: [PATCH 04/17] Add docs --- Doc/library/multiprocessing.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 9fa76c4ce59d00..e06dbfacf7b555 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -673,6 +673,15 @@ The :mod:`multiprocessing` package mostly replicates the API of the .. versionadded:: 3.7 + .. method:: is_closed() + + Return whether the process is closed. + + Roughly, a process object is considered closed when :meth:`close` + is called on it. + + .. versionadded:: 3.14 + .. method:: close() Close the :class:`Process` object, releasing all resources associated From 31381ae053aa9fed49cfc4fc487b575c9316e582 Mon Sep 17 00:00:00 2001 From: ruang Date: Tue, 22 Oct 2024 21:06:48 +0800 Subject: [PATCH 05/17] Add property --- Lib/multiprocessing/process.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py index 01a5655117b14d..d16b8c7c78b90c 100644 --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -169,6 +169,7 @@ def is_alive(self): _children.discard(self) return False + @property def is_closed(self): ''' Return whether process is closed From 43562beef3247f48cb8aab41f945e2230bea7ea9 Mon Sep 17 00:00:00 2001 From: "RUANG (Roy James)" Date: Tue, 22 Oct 2024 21:24:55 +0800 Subject: [PATCH 06/17] Change test --- Lib/test/_test_multiprocessing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index ad5786686c91a4..232b6d5da84c88 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -655,9 +655,9 @@ def test_is_close(self): def _test_task(): pass p = self.Process(target=_test_task) - self.assertFalse(p.is_closed()) + self.assertFalse(p.is_closed) p.close() - self.assertTrue(p.is_closed()) + self.assertTrue(p.is_closed) wr = weakref.ref(p) del p From b86cb403133bf6d274fea13e5f11295d707066bc Mon Sep 17 00:00:00 2001 From: "RUANG (Roy James)" Date: Tue, 22 Oct 2024 21:35:10 +0800 Subject: [PATCH 07/17] is_closed rename to closed --- Doc/library/multiprocessing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index e06dbfacf7b555..0daed0ae2fa9d2 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -673,7 +673,7 @@ The :mod:`multiprocessing` package mostly replicates the API of the .. versionadded:: 3.7 - .. method:: is_closed() + .. method:: closed() Return whether the process is closed. From 50490d66698f10e701c98f40a4fe217131c997cb Mon Sep 17 00:00:00 2001 From: ruang Date: Tue, 22 Oct 2024 21:37:55 +0800 Subject: [PATCH 08/17] is_closed rename to closed --- Lib/multiprocessing/process.py | 2 +- Lib/test/_test_multiprocessing.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py index d16b8c7c78b90c..89b100d3b063f2 100644 --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -170,7 +170,7 @@ def is_alive(self): return False @property - def is_closed(self): + def closed(self): ''' Return whether process is closed ''' diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 232b6d5da84c88..9374abbeaf4fb7 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -655,9 +655,9 @@ def test_is_close(self): def _test_task(): pass p = self.Process(target=_test_task) - self.assertFalse(p.is_closed) + self.assertFalse(p.closed) p.close() - self.assertTrue(p.is_closed) + self.assertTrue(p.closed) wr = weakref.ref(p) del p From b2eac3c5b4340a4aafc6c011aeb18fe221630e43 Mon Sep 17 00:00:00 2001 From: "RUANG (Roy James)" Date: Tue, 22 Oct 2024 21:38:44 +0800 Subject: [PATCH 09/17] Change NEWS --- .../next/Library/2024-10-22-19-52-15.gh-issue-87063.fR-wJa.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index b8356f7a08115f..9bd53f38b22bc1 100644 --- 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 @@ -1,2 +1,2 @@ -Add the ``is_closed()`` in the :class:`multiprocessing.Process` to +Add the ``closed()`` in the :class:`multiprocessing.Process` to determine whether the process is closed. From 5b43f0210fb78f516546e9d2258e942e02c86849 Mon Sep 17 00:00:00 2001 From: "RUANG (Roy James)" Date: Thu, 24 Oct 2024 19:51:06 +0800 Subject: [PATCH 10/17] Change NEWS --- .../Library/2024-10-22-19-52-15.gh-issue-87063.fR-wJa.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 index 9bd53f38b22bc1..40476066ffeb14 100644 --- 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 @@ -1,2 +1,2 @@ -Add the ``closed()`` in the :class:`multiprocessing.Process` to -determine whether the process is closed. +Allow to determine whether a :class:`multiprocessing.Process` has been closed +via the :attr:`~multiprocessing.Process.closed` attribute. From 6898906b5854c8b03175029cadc159f113875b10 Mon Sep 17 00:00:00 2001 From: "RUANG (Roy James)" Date: Thu, 24 Oct 2024 19:54:20 +0800 Subject: [PATCH 11/17] Change test --- Lib/test/_test_multiprocessing.py | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 9374abbeaf4fb7..612d327fc187a6 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -649,21 +649,6 @@ def _test_close(cls, rc=0, q=None): q.get() sys.exit(rc) - def test_is_close(self): - if self.TYPE == "threads": - self.skipTest('test not appropriate for {}'.format(self.TYPE)) - def _test_task(): - pass - p = self.Process(target=_test_task) - self.assertFalse(p.closed) - p.close() - self.assertTrue(p.closed) - - wr = weakref.ref(p) - del p - gc.collect() - self.assertIs(wr(), None) - def test_close(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -687,7 +672,9 @@ def test_close(self): p.join() with self.assertRaises(ValueError): p.terminate() + self.assertFalse(p.closed) p.close() + self.assertTrue(p.closed) wr = weakref.ref(p) del p From e92ea6d1098b2c28f3bdb10c29b1304a139b0500 Mon Sep 17 00:00:00 2001 From: "RUANG (Roy James)" Date: Thu, 24 Oct 2024 19:59:07 +0800 Subject: [PATCH 12/17] Change docs --- Doc/library/multiprocessing.rst | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 0daed0ae2fa9d2..d123d132420c02 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -673,15 +673,6 @@ The :mod:`multiprocessing` package mostly replicates the API of the .. versionadded:: 3.7 - .. method:: closed() - - Return whether the process is closed. - - Roughly, a process object is considered closed when :meth:`close` - is called on it. - - .. versionadded:: 3.14 - .. method:: close() Close the :class:`Process` object, releasing all resources associated @@ -715,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. From caa3ab49bd134bd31a1ead1eb23394bfae50d09f Mon Sep 17 00:00:00 2001 From: "RUANG (Roy James)" Date: Thu, 24 Oct 2024 20:35:51 +0800 Subject: [PATCH 13/17] Change test --- Lib/test/_test_multiprocessing.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 612d327fc187a6..4191325cf588c2 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -659,20 +659,22 @@ def test_close(self): self.assertEqual(p.is_alive(), True) # Child is still alive, cannot close with self.assertRaises(ValueError): + self.assertFalse(p.closed) p.close() + self.assertTrue(p.closed) q.put(None) p.join() self.assertEqual(p.is_alive(), False) self.assertEqual(p.exitcode, 0) p.close() + self.assertTrue(p.closed) with self.assertRaises(ValueError): p.is_alive() with self.assertRaises(ValueError): p.join() with self.assertRaises(ValueError): p.terminate() - self.assertFalse(p.closed) p.close() self.assertTrue(p.closed) From 3975bd4a50d00e4293ebe2476436e4afe3c3f0a9 Mon Sep 17 00:00:00 2001 From: RUANG Date: Sat, 26 Oct 2024 10:08:31 +0800 Subject: [PATCH 14/17] Change NEWS --- .../Library/2024-10-22-19-52-15.gh-issue-87063.fR-wJa.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 index 40476066ffeb14..22fdcdc8bb7056 100644 --- 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 @@ -1,2 +1,3 @@ -Allow to determine whether a :class:`multiprocessing.Process` has been closed -via the :attr:`~multiprocessing.Process.closed` attribute. +Add attribute :attr:`!closed` to :class:`multiprocessing.Process`, +It is used to check whether the process is closed. +(Contributed by James Roy in :gh:`87063`.) From a907454d29ae91b63e5b0cbcf76d4bc780f2c277 Mon Sep 17 00:00:00 2001 From: RUANG Date: Sat, 26 Oct 2024 15:58:39 +0800 Subject: [PATCH 15/17] Add what's NEWS --- Doc/whatsnew/3.14.rst | 8 ++++++++ .../Library/2024-10-22-19-52-15.gh-issue-87063.fR-wJa.rst | 5 ++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 83c13e6fb64d1d..5d7826b601c0c7 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -222,6 +222,14 @@ pickle For more details, please see :ref:`pickle protocols `. +multiprocessing +--------------- + +* Add attribute :attr:`!closed` to :class:`multiprocessing.Process`, + It is used to check whether the process is closed. + (Contributed by James Roy in :gh:`87063`.) + + symtable -------- 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 index 22fdcdc8bb7056..1929baf21c7011 100644 --- 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 @@ -1,3 +1,2 @@ -Add attribute :attr:`!closed` to :class:`multiprocessing.Process`, -It is used to check whether the process is closed. -(Contributed by James Roy in :gh:`87063`.) +Allow to determine whether a :class:`multiprocessing.Process` has been closed +via the :attr:`!closed` attribute. From 5cda5b41cc96f10d8d4a9eb5ccae248697e4e555 Mon Sep 17 00:00:00 2001 From: "RUANG (James Roy)" Date: Sat, 26 Oct 2024 19:20:00 +0800 Subject: [PATCH 16/17] Change docs --- .../next/Library/2024-10-22-19-52-15.gh-issue-87063.fR-wJa.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 1929baf21c7011..877619ea3b7dc5 100644 --- 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 @@ -1,2 +1,2 @@ Allow to determine whether a :class:`multiprocessing.Process` has been closed -via the :attr:`!closed` attribute. +via the :attr:`~multiprocessing.Process.closed` property. From 1c84bb27c9647c4fd3766d5fc2a0f58d1f32a3e2 Mon Sep 17 00:00:00 2001 From: "RUANG (James Roy)" Date: Sat, 26 Oct 2024 19:22:35 +0800 Subject: [PATCH 17/17] Change what's NEWS --- Doc/whatsnew/3.14.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 5d7826b601c0c7..566c8065f5792c 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -171,6 +171,14 @@ 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. + + operator -------- @@ -222,14 +230,6 @@ pickle For more details, please see :ref:`pickle protocols `. -multiprocessing ---------------- - -* Add attribute :attr:`!closed` to :class:`multiprocessing.Process`, - It is used to check whether the process is closed. - (Contributed by James Roy in :gh:`87063`.) - - symtable --------