Skip to content

Commit 06c8f5f

Browse files
committed
Replace deprecated asyncio.get_child_watcher()
Use PidfdChildWatcher if os.pidfd_open is available and otherwise use ThreadedChildWatcher which should work in any case. Fixes #583
1 parent eb14e83 commit 06c8f5f

File tree

1 file changed

+35
-3
lines changed

1 file changed

+35
-3
lines changed

pynvim/msgpack_rpc/event_loop/asyncio.py

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,42 @@ async def connect_stdout():
188188

189189
@override
190190
def _connect_child(self, argv: List[str]) -> None:
191+
def can_use_pidfd():
192+
# Unix system without pidfd_open?
193+
if not hasattr(os, 'pidfd_open'):
194+
return False
195+
196+
# Check that we are not blocked by security policy like SECCOMP
197+
try:
198+
pid = os.getpid()
199+
fd = os.pidfd_open(pid, 0)
200+
os.close(fd)
201+
except OSError:
202+
return False
203+
204+
return True
205+
206+
def get_child_watcher():
207+
if can_use_pidfd():
208+
try:
209+
from asyncio.unix_events import PidfdChildWatcher
210+
return PidfdChildWatcher()
211+
except ImportError:
212+
pass
213+
214+
try:
215+
from asyncio.unix_events import ThreadedChildWatcher
216+
return ThreadedChildWatcher()
217+
except ImportError:
218+
pass
219+
220+
# FIXME Python 3.7, return None if we drop support
221+
return asyncio.get_child_watcher()
222+
191223
if os.name != 'nt':
192-
# see #238, #241
193-
self._child_watcher = asyncio.get_child_watcher()
194-
self._child_watcher.attach_loop(self._loop)
224+
watcher = get_child_watcher()
225+
watcher.attach_loop(self._loop)
226+
self._child_watcher = watcher
195227

196228
async def create_subprocess():
197229
transport: asyncio.SubprocessTransport # type: ignore

0 commit comments

Comments
 (0)