Skip to content

Commit 856bf92

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 4d3fbdc commit 856bf92

File tree

1 file changed

+37
-4
lines changed

1 file changed

+37
-4
lines changed

pynvim/msgpack_rpc/event_loop/asyncio.py

Lines changed: 37 additions & 4 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 import PidfdChildWatcher
210+
return PidfdChildWatcher()
211+
except ImportError:
212+
pass
213+
214+
try:
215+
from asyncio 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
@@ -250,7 +282,8 @@ def _close_transport(transport):
250282
# Windows: for ProactorBasePipeTransport, close() doesn't take in
251283
# effect immediately (closing happens asynchronously inside the
252284
# event loop), need to wait a bit for completing graceful shutdown.
253-
if os.name == 'nt' and hasattr(transport, '_sock'):
285+
if (sys.version_info < (3, 13) and
286+
os.name == 'nt' and hasattr(transport, '_sock')):
254287
async def wait_until_closed():
255288
# pylint: disable-next=protected-access
256289
while transport._sock is not None:

0 commit comments

Comments
 (0)