Issue #28368: Refuse monitoring processes if the child watcher has no… · python/cpython@9eb6c67 · GitHub
Skip to content

Commit 9eb6c67

Browse files
author
Yury Selivanov
committed
Issue #28368: Refuse monitoring processes if the child watcher has no loop attached.
Patch by Vincent Michel.
1 parent b5bb404 commit 9eb6c67

4 files changed

Lines changed: 42 additions & 6 deletions

File tree

Lib/asyncio/unix_events.py

Lines changed: 18 additions & 5 deletions

Lib/test/test_asyncio/test_subprocess.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,13 @@ def kill_running():
433433
# the transport was not notified yet
434434
self.assertFalse(killed)
435435

436+
# Unlike SafeChildWatcher, FastChildWatcher does not pop the
437+
# callbacks if waitpid() is called elsewhere. Let's clear them
438+
# manually to avoid a warning when the watcher is detached.
439+
if sys.platform != 'win32' and \
440+
isinstance(self, SubprocessFastWatcherTests):
441+
asyncio.get_child_watcher()._callbacks.clear()
442+
436443
def test_popen_error(self):
437444
# Issue #24763: check that the subprocess transport is closed
438445
# when BaseSubprocessTransport fails

Lib/test/test_asyncio/test_unix_events.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import tempfile
1212
import threading
1313
import unittest
14+
import warnings
1415
from unittest import mock
1516

1617
if sys.platform == 'win32':
@@ -1391,7 +1392,9 @@ def test_set_loop_race_condition(self, m):
13911392
with mock.patch.object(
13921393
old_loop, "remove_signal_handler") as m_remove_signal_handler:
13931394

1394-
self.watcher.attach_loop(None)
1395+
with self.assertWarnsRegex(
1396+
RuntimeWarning, 'A loop is being detached'):
1397+
self.watcher.attach_loop(None)
13951398

13961399
m_remove_signal_handler.assert_called_once_with(
13971400
signal.SIGCHLD)
@@ -1463,6 +1466,15 @@ def test_close(self, m):
14631466
if isinstance(self.watcher, asyncio.FastChildWatcher):
14641467
self.assertFalse(self.watcher._zombies)
14651468

1469+
@waitpid_mocks
1470+
def test_add_child_handler_with_no_loop_attached(self, m):
1471+
callback = mock.Mock()
1472+
with self.create_watcher() as watcher:
1473+
with self.assertRaisesRegex(
1474+
RuntimeError,
1475+
'the child watcher does not have a loop attached'):
1476+
watcher.add_child_handler(100, callback)
1477+
14661478

14671479
class SafeChildWatcherTests (ChildWatcherTestsMixin, test_utils.TestCase):
14681480
def create_watcher(self):

Misc/NEWS

Lines changed: 4 additions & 0 deletions

0 commit comments

Comments
 (0)