Skip to content

Commit 6718a9b

Browse files
committed
fix: monkey-patch _ProactorBasePipeTransport to suppress warning
python < 3.10.6 has a bug on proactor-based pipe transport: when a `_ProactorBasePipeTransport` instance is garbage-collected (usually after the associated event loop is closed), it will raise an error. For older versions of python, we apply the same monkey-patchin to suppress warnings (actually these are errors). Ref: python/cpython#83413 and python/cpython#92841 CI output (pytest warnings): ``` ======================= 71 passed, 66 warnings in 6.55s ======================= Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x0000021A9534F700> Traceback (most recent call last): File "C:\hostedtoolcache\windows\Python\3.8.10\x64\lib\asyncio\proactor_events.py", line 115, in __del__ _warn(f"unclosed transport {self!r}", ResourceWarning, source=self) File "C:\hostedtoolcache\windows\Python\3.8.10\x64\lib\asyncio\proactor_events.py", line 79, in __repr__ info.append(f'fd={self._sock.fileno()}') File "C:\hostedtoolcache\windows\Python\3.8.10\x64\lib\asyncio\windows_utils.py", line 102, in fileno raise ValueError("I/O operation on closed pipe") ValueError: I/O operation on closed pipe Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x0000021A9534F700> Traceback (most recent call last): File "C:\hostedtoolcache\windows\Python\3.8.10\x64\lib\asyncio\proactor_events.py", line 115, in __del__ File "C:\hostedtoolcache\windows\Python\3.8.10\x64\lib\asyncio\proactor_events.py", line 79, in __repr__ File "C:\hostedtoolcache\windows\Python\3.8.10\x64\lib\asyncio\windows_utils.py", line 102, in fileno ValueError: I/O operation on closed pipe ```
1 parent 75a3599 commit 6718a9b

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

pynvim/msgpack_rpc/event_loop/asyncio.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import logging
1313
import os
1414
import sys
15+
import warnings
1516
from collections import deque
1617
from signal import Signals
1718
from typing import Any, Callable, Deque, List
@@ -22,15 +23,34 @@
2223
debug, info, warn = (logger.debug, logger.info, logger.warning,)
2324

2425
loop_cls = asyncio.SelectorEventLoop
26+
2527
if os.name == 'nt':
28+
import msvcrt # pylint: disable=import-error
2629
from asyncio.windows_utils import PipeHandle # type: ignore[attr-defined]
27-
import msvcrt
2830

2931
# On windows use ProactorEventLoop which support pipes and is backed by the
3032
# more powerful IOCP facility
3133
# NOTE: we override in the stdio case, because it doesn't work.
3234
loop_cls = asyncio.ProactorEventLoop # type: ignore[attr-defined,misc]
3335

36+
# Workaround for a bug in Proactor-based pipe transport:
37+
# - python/cpython#83413 ("Event loop is closed") which is fixed by
38+
# python/cpython#92841 in python 3.10.6+
39+
# Solution: monkey-patch _ProactorBasePipeTransport.
40+
# pylint: disable=protected-access
41+
if sys.version_info < (3, 10, 6):
42+
from asyncio.proactor_events import _ProactorBasePipeTransport
43+
44+
def __del__(self): # noqa
45+
if self._sock is not None:
46+
warnings.warn(f"unclosed transport {self!r}",
47+
ResourceWarning, source=self)
48+
self._sock.close()
49+
50+
_ProactorBasePipeTransport.__del__ = __del__ # type: ignore # noqa
51+
del __del__, _ProactorBasePipeTransport
52+
# pylint: enable=protected-access
53+
3454

3555
class AsyncioEventLoop(BaseEventLoop, asyncio.Protocol,
3656
asyncio.SubprocessProtocol):

0 commit comments

Comments
 (0)