From 2dc5d61cd40022b69806d581739a1b72bb6aab4a Mon Sep 17 00:00:00 2001
From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Date: Wed, 12 Oct 2022 10:41:15 +0000
Subject: [PATCH 1/6] deprecate config methods

---
 Lib/asyncio/unix_events.py                | 59 +++++++++++++----------
 Lib/test/test_asyncio/test_events.py      | 16 +++---
 Lib/test/test_asyncio/test_streams.py     |  8 ++-
 Lib/test/test_asyncio/test_subprocess.py  | 29 +++++++----
 Lib/test/test_asyncio/test_unix_events.py | 21 ++++----
 Lib/test/test_asyncio/utils.py            |  6 ++-
 6 files changed, 85 insertions(+), 54 deletions(-)

diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index bdffc032e318fd..670057cf7a3f8d 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -195,32 +195,34 @@ def _make_write_pipe_transport(self, pipe, protocol, waiter=None,
     async def _make_subprocess_transport(self, protocol, args, shell,
                                          stdin, stdout, stderr, bufsize,
                                          extra=None, **kwargs):
-        with events.get_child_watcher() as watcher:
-            if not watcher.is_active():
-                # Check early.
-                # Raising exception before process creation
-                # prevents subprocess execution if the watcher
-                # is not ready to handle it.
-                raise RuntimeError("asyncio.get_child_watcher() is not activated, "
-                                   "subprocess support is not installed.")
-            waiter = self.create_future()
-            transp = _UnixSubprocessTransport(self, protocol, args, shell,
-                                              stdin, stdout, stderr, bufsize,
-                                              waiter=waiter, extra=extra,
-                                              **kwargs)
-
-            watcher.add_child_handler(transp.get_pid(),
-                                      self._child_watcher_callback, transp)
-            try:
-                await waiter
-            except (SystemExit, KeyboardInterrupt):
-                raise
-            except BaseException:
-                transp.close()
-                await transp._wait()
-                raise
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', DeprecationWarning)
+            with events.get_child_watcher() as watcher:
+                if not watcher.is_active():
+                    # Check early.
+                    # Raising exception before process creation
+                    # prevents subprocess execution if the watcher
+                    # is not ready to handle it.
+                    raise RuntimeError("asyncio.get_child_watcher() is not activated, "
+                                    "subprocess support is not installed.")
+                waiter = self.create_future()
+                transp = _UnixSubprocessTransport(self, protocol, args, shell,
+                                                stdin, stdout, stderr, bufsize,
+                                                waiter=waiter, extra=extra,
+                                                **kwargs)
+
+                watcher.add_child_handler(transp.get_pid(),
+                                        self._child_watcher_callback, transp)
+                try:
+                    await waiter
+                except (SystemExit, KeyboardInterrupt):
+                    raise
+                except BaseException:
+                    transp.close()
+                    await transp._wait()
+                    raise
 
-        return transp
+            return transp
 
     def _child_watcher_callback(self, pid, returncode, transp):
         # Skip one iteration for callbacks to be executed
@@ -1470,17 +1472,22 @@ def get_child_watcher(self):
         if self._watcher is None:
             self._init_watcher()
 
+        warnings._deprecated("get_child_watcher",
+                            "{name!r} is deprecated as of Python 3.12 and will be "
+                            "removed in Python {remove}.", remove=(3, 14))
         return self._watcher
 
     def set_child_watcher(self, watcher):
         """Set the watcher for child processes."""
 
         assert watcher is None or isinstance(watcher, AbstractChildWatcher)
-
         if self._watcher is not None:
             self._watcher.close()
 
         self._watcher = watcher
+        warnings._deprecated("set_child_watcher",
+                            "{name!r} is deprecated as of Python 3.12 and will be "
+                            "removed in Python {remove}.", remove=(3, 14))
 
 
 SelectorEventLoop = _UnixSelectorEventLoop
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
index 98b55dec37f478..cabe75f56d9fb0 100644
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -2058,11 +2058,13 @@ def setUp(self):
             with warnings.catch_warnings():
                 warnings.simplefilter('ignore', DeprecationWarning)
                 watcher = asyncio.SafeChildWatcher()
-            watcher.attach_loop(self.loop)
-            asyncio.set_child_watcher(watcher)
+                watcher.attach_loop(self.loop)
+                asyncio.set_child_watcher(watcher)
 
         def tearDown(self):
-            asyncio.set_child_watcher(None)
+            with warnings.catch_warnings():
+                warnings.simplefilter('ignore', DeprecationWarning)
+                asyncio.set_child_watcher(None)
             super().tearDown()
 
 
@@ -2657,13 +2659,15 @@ def setUp(self):
             with warnings.catch_warnings():
                 warnings.simplefilter('ignore', DeprecationWarning)
                 watcher = asyncio.SafeChildWatcher()
-            watcher.attach_loop(self.loop)
-            asyncio.set_child_watcher(watcher)
+                watcher.attach_loop(self.loop)
+                asyncio.set_child_watcher(watcher)
 
     def tearDown(self):
         try:
             if sys.platform != 'win32':
-                asyncio.set_child_watcher(None)
+                with warnings.catch_warnings():
+                    warnings.simplefilter('ignore', DeprecationWarning)
+                    asyncio.set_child_watcher(None)
 
             super().tearDown()
         finally:
diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py
index 8fb9313e09dd0e..01d5407a497a04 100644
--- a/Lib/test/test_asyncio/test_streams.py
+++ b/Lib/test/test_asyncio/test_streams.py
@@ -797,7 +797,9 @@ def test_read_all_from_pipe_reader(self):
             watcher = asyncio.SafeChildWatcher()
         watcher.attach_loop(self.loop)
         try:
-            asyncio.set_child_watcher(watcher)
+            with warnings.catch_warnings():
+                warnings.simplefilter('ignore', DeprecationWarning)
+                asyncio.set_child_watcher(watcher)
             create = asyncio.create_subprocess_exec(
                 *args,
                 pass_fds={wfd},
@@ -805,7 +807,9 @@ def test_read_all_from_pipe_reader(self):
             proc = self.loop.run_until_complete(create)
             self.loop.run_until_complete(proc.wait())
         finally:
-            asyncio.set_child_watcher(None)
+            with warnings.catch_warnings():
+                warnings.simplefilter('ignore', DeprecationWarning)
+                asyncio.set_child_watcher(None)
 
         os.close(wfd)
         data = self.loop.run_until_complete(reader.read(-1))
diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py
index 915ad5587f0a48..5ac1dad3186b55 100644
--- a/Lib/test/test_asyncio/test_subprocess.py
+++ b/Lib/test/test_asyncio/test_subprocess.py
@@ -562,7 +562,9 @@ async def kill_running():
         # manually to avoid a warning when the watcher is detached.
         if (sys.platform != 'win32' and
                 isinstance(self, SubprocessFastWatcherTests)):
-            asyncio.get_child_watcher()._callbacks.clear()
+            with warnings.catch_warnings():
+                warnings.simplefilter('ignore', DeprecationWarning)
+                asyncio.get_child_watcher()._callbacks.clear()
 
     async def _test_popen_error(self, stdin):
         if sys.platform == 'win32':
@@ -676,13 +678,17 @@ def setUp(self):
 
             watcher = self._get_watcher()
             watcher.attach_loop(self.loop)
-            policy.set_child_watcher(watcher)
+            with warnings.catch_warnings():
+                warnings.simplefilter('ignore', DeprecationWarning)
+                policy.set_child_watcher(watcher)
 
         def tearDown(self):
             super().tearDown()
             policy = asyncio.get_event_loop_policy()
-            watcher = policy.get_child_watcher()
-            policy.set_child_watcher(None)
+            with warnings.catch_warnings():
+                warnings.simplefilter('ignore', DeprecationWarning)
+                watcher = policy.get_child_watcher()
+                policy.set_child_watcher(None)
             watcher.attach_loop(None)
             watcher.close()
 
@@ -732,7 +738,9 @@ def test_create_subprocess_fails_with_inactive_watcher(self):
             )
 
             async def execute():
-                asyncio.set_child_watcher(watcher)
+                with warnings.catch_warnings():
+                    warnings.simplefilter('ignore', DeprecationWarning)
+                    asyncio.set_child_watcher(watcher)
 
                 with self.assertRaises(RuntimeError):
                     await subprocess.create_subprocess_exec(
@@ -741,7 +749,9 @@ async def execute():
                 watcher.add_child_handler.assert_not_called()
 
             with asyncio.Runner(loop_factory=asyncio.new_event_loop) as runner:
-                self.assertIsNone(runner.run(execute()))
+                with warnings.catch_warnings():
+                    warnings.simplefilter('ignore', DeprecationWarning)
+                    self.assertIsNone(runner.run(execute()))
             self.assertListEqual(watcher.mock_calls, [
                 mock.call.__enter__(),
                 mock.call.__enter__().is_active(),
@@ -768,15 +778,16 @@ async def main():
                 with self.assertRaises(RuntimeError):
                     asyncio.get_event_loop_policy().get_event_loop()
                 return await asyncio.to_thread(asyncio.run, in_thread())
-
-            asyncio.set_child_watcher(asyncio.PidfdChildWatcher())
+            with self.assertWarns(DeprecationWarning):
+                asyncio.set_child_watcher(asyncio.PidfdChildWatcher())
             try:
                 with asyncio.Runner(loop_factory=asyncio.new_event_loop) as runner:
                     returncode, stdout = runner.run(main())
                 self.assertEqual(returncode, 0)
                 self.assertEqual(stdout, b'some data')
             finally:
-                asyncio.set_child_watcher(None)
+                with self.assertWarns(DeprecationWarning):
+                    asyncio.set_child_watcher(None)
 else:
     # Windows
     class SubprocessProactorTests(SubprocessMixin, test_utils.TestCase):
diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py
index 025da0f20ed47e..d806ed497aaab4 100644
--- a/Lib/test/test_asyncio/test_unix_events.py
+++ b/Lib/test/test_asyncio/test_unix_events.py
@@ -1709,33 +1709,36 @@ def test_get_default_child_watcher(self):
         self.assertIsNone(policy._watcher)
         unix_events.can_use_pidfd = mock.Mock()
         unix_events.can_use_pidfd.return_value = False
-        watcher = policy.get_child_watcher()
+        with self.assertWarns(DeprecationWarning):
+            watcher = policy.get_child_watcher()
         self.assertIsInstance(watcher, asyncio.ThreadedChildWatcher)
 
         self.assertIs(policy._watcher, watcher)
-
-        self.assertIs(watcher, policy.get_child_watcher())
+        with self.assertWarns(DeprecationWarning):
+            self.assertIs(watcher, policy.get_child_watcher())
 
         policy = self.create_policy()
         self.assertIsNone(policy._watcher)
         unix_events.can_use_pidfd = mock.Mock()
         unix_events.can_use_pidfd.return_value = True
-        watcher = policy.get_child_watcher()
+        with self.assertWarns(DeprecationWarning):
+            watcher = policy.get_child_watcher()
         self.assertIsInstance(watcher, asyncio.PidfdChildWatcher)
 
         self.assertIs(policy._watcher, watcher)
-
-        self.assertIs(watcher, policy.get_child_watcher())
+        with self.assertWarns(DeprecationWarning):
+            self.assertIs(watcher, policy.get_child_watcher())
 
     def test_get_child_watcher_after_set(self):
         policy = self.create_policy()
         with warnings.catch_warnings():
             warnings.simplefilter("ignore", DeprecationWarning)
             watcher = asyncio.FastChildWatcher()
+            policy.set_child_watcher(watcher)
 
-        policy.set_child_watcher(watcher)
         self.assertIs(policy._watcher, watcher)
-        self.assertIs(watcher, policy.get_child_watcher())
+        with self.assertWarns(DeprecationWarning):
+            self.assertIs(watcher, policy.get_child_watcher())
 
     def test_get_child_watcher_thread(self):
 
@@ -1769,7 +1772,7 @@ def test_child_watcher_replace_mainloop_existing(self):
         with warnings.catch_warnings():
             warnings.simplefilter("ignore", DeprecationWarning)
             watcher = asyncio.SafeChildWatcher()
-        policy.set_child_watcher(watcher)
+            policy.set_child_watcher(watcher)
         watcher.attach_loop(loop)
 
         self.assertIs(watcher._loop, loop)
diff --git a/Lib/test/test_asyncio/utils.py b/Lib/test/test_asyncio/utils.py
index 96be5a1c3bcf77..5b9c86eb9859a0 100644
--- a/Lib/test/test_asyncio/utils.py
+++ b/Lib/test/test_asyncio/utils.py
@@ -14,7 +14,7 @@
 import threading
 import unittest
 import weakref
-
+import warnings
 from unittest import mock
 
 from http.server import HTTPServer
@@ -544,7 +544,9 @@ def close_loop(loop):
         policy = support.maybe_get_event_loop_policy()
         if policy is not None:
             try:
-                watcher = policy.get_child_watcher()
+                with warnings.catch_warnings():
+                    warnings.simplefilter('ignore', DeprecationWarning)
+                    watcher = policy.get_child_watcher()
             except NotImplementedError:
                 # watcher is not implemented by EventLoopPolicy, e.g. Windows
                 pass

From 96a464d104f4fb3145a0fbe2aa91ff76fd6e1400 Mon Sep 17 00:00:00 2001
From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Date: Wed, 12 Oct 2022 11:17:49 +0000
Subject: [PATCH 2/6] whitespace

---
 Lib/asyncio/unix_events.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index 670057cf7a3f8d..2bd2ac6f4cf398 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -1481,6 +1481,7 @@ def set_child_watcher(self, watcher):
         """Set the watcher for child processes."""
 
         assert watcher is None or isinstance(watcher, AbstractChildWatcher)
+
         if self._watcher is not None:
             self._watcher.close()
 

From 9020f36e52c63bcec14f213927172112e2f857c7 Mon Sep 17 00:00:00 2001
From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com>
Date: Wed, 12 Oct 2022 11:20:55 +0000
Subject: [PATCH 3/6] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?=
 =?UTF-8?q?rb=5Fit.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../next/Library/2022-10-12-11-20-54.gh-issue-94597.GYJZlb.rst   | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 Misc/NEWS.d/next/Library/2022-10-12-11-20-54.gh-issue-94597.GYJZlb.rst

diff --git a/Misc/NEWS.d/next/Library/2022-10-12-11-20-54.gh-issue-94597.GYJZlb.rst b/Misc/NEWS.d/next/Library/2022-10-12-11-20-54.gh-issue-94597.GYJZlb.rst
new file mode 100644
index 00000000000000..5ea1358b7d8a35
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-10-12-11-20-54.gh-issue-94597.GYJZlb.rst
@@ -0,0 +1 @@
+Deprecated :meth:`asyncio.AbstractEventLoopPolicy.get_child_watcher` and :meth:`asyncio.AbstractEventLoopPolicy.set_child_watcher` methods to be removed in Python 3.14. Patch by Kumar Aditya.

From acc1378644b76234be87900e8ccdd2ac5dea67e3 Mon Sep 17 00:00:00 2001
From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Date: Sat, 15 Oct 2022 13:30:33 +0000
Subject: [PATCH 4/6] fix return indent

---
 Lib/asyncio/unix_events.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index 5ebdeb914eff5d..ea7010ee107322 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -222,7 +222,7 @@ async def _make_subprocess_transport(self, protocol, args, shell,
                     await transp._wait()
                     raise
 
-            return transp
+        return transp
 
     def _child_watcher_callback(self, pid, returncode, transp):
         # Skip one iteration for callbacks to be executed

From be66c371c78f062bc24e52e427faee1336f86428 Mon Sep 17 00:00:00 2001
From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Date: Sat, 15 Oct 2022 13:37:46 +0000
Subject: [PATCH 5/6] add whatsnew

---
 Doc/library/asyncio-policy.rst | 15 +++++++++++++++
 Doc/whatsnew/3.12.rst          |  6 ++++++
 2 files changed, 21 insertions(+)

diff --git a/Doc/library/asyncio-policy.rst b/Doc/library/asyncio-policy.rst
index bfc3e3090fdcdf..96dd162762de1e 100644
--- a/Doc/library/asyncio-policy.rst
+++ b/Doc/library/asyncio-policy.rst
@@ -88,12 +88,16 @@ The abstract event loop policy base class is defined as follows:
 
       This function is Unix specific.
 
+      .. deprecated:: 3.12
+
    .. method:: set_child_watcher(watcher)
 
       Set the current child process watcher to *watcher*.
 
       This function is Unix specific.
 
+      .. deprecated:: 3.12
+
 
 .. _asyncio-policy-builtin:
 
@@ -158,12 +162,16 @@ implementation used by the asyncio event loop:
 
    Return the current child watcher for the current policy.
 
+   .. deprecated:: 3.12
+
 .. function:: set_child_watcher(watcher)
 
    Set the current child watcher to *watcher* for the current
    policy.  *watcher* must implement methods defined in the
    :class:`AbstractChildWatcher` base class.
 
+   .. deprecated:: 3.12
+
 .. note::
    Third-party event loops implementations might not support
    custom child watchers.  For such event loops, using
@@ -245,6 +253,9 @@ implementation used by the asyncio event loop:
 
    .. versionadded:: 3.8
 
+   .. deprecated:: 3.12
+
+
 .. class:: SafeChildWatcher
 
    This implementation uses active event loop from the main thread to handle
@@ -257,6 +268,8 @@ implementation used by the asyncio event loop:
    This solution is as safe as :class:`MultiLoopChildWatcher` and has the same *O(N)*
    complexity but requires a running event loop in the main thread to work.
 
+   .. deprecated:: 3.12
+
 .. class:: FastChildWatcher
 
    This implementation reaps every terminated processes by calling
@@ -269,6 +282,8 @@ implementation used by the asyncio event loop:
    This solution requires a running event loop in the main thread to work, as
    :class:`SafeChildWatcher`.
 
+   .. deprecated:: 3.12
+
 .. class:: PidfdChildWatcher
 
    This implementation polls process file descriptors (pidfds) to await child
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index ebc490691e308b..ecc74e9beba264 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -126,6 +126,12 @@ asyncio
   if supported and :class:`~asyncio.ThreadedChildWatcher` otherwise).
   (Contributed by Kumar Aditya in :gh:`94597`.)
 
+* :func:`asyncio.set_child_watcher`, :func:`asyncio.get_child_watcher`,
+  :meth:`asyncio.AbstractEventLoopPolicy.set_child_watcher` and
+  :meth:`asyncio.AbstractEventLoopPolicy.get_child_watcher` are deprecated
+  and will be removed in Python 3.14.
+  (Contributed by Kumar Aditya in :gh:`94597`.)
+
 
 pathlib
 -------

From d15f5a5737c397619e92900c72940e19ace32fd5 Mon Sep 17 00:00:00 2001
From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Date: Sat, 15 Oct 2022 13:38:57 +0000
Subject: [PATCH 6/6] nl

---
 Doc/library/asyncio-policy.rst | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Doc/library/asyncio-policy.rst b/Doc/library/asyncio-policy.rst
index 96dd162762de1e..052378ef32743b 100644
--- a/Doc/library/asyncio-policy.rst
+++ b/Doc/library/asyncio-policy.rst
@@ -255,7 +255,6 @@ implementation used by the asyncio event loop:
 
    .. deprecated:: 3.12
 
-
 .. class:: SafeChildWatcher
 
    This implementation uses active event loop from the main thread to handle