|
12 | 12 | import logging
|
13 | 13 | import os
|
14 | 14 | import sys
|
| 15 | +import warnings |
15 | 16 | from collections import deque
|
16 | 17 | from signal import Signals
|
17 | 18 | from typing import Any, Callable, Deque, List
|
|
22 | 23 | debug, info, warn = (logger.debug, logger.info, logger.warning,)
|
23 | 24 |
|
24 | 25 | loop_cls = asyncio.SelectorEventLoop
|
| 26 | + |
25 | 27 | if os.name == 'nt':
|
| 28 | + import msvcrt # pylint: disable=import-error |
26 | 29 | from asyncio.windows_utils import PipeHandle # type: ignore[attr-defined]
|
27 |
| - import msvcrt |
28 | 30 |
|
29 | 31 | # On windows use ProactorEventLoop which support pipes and is backed by the
|
30 | 32 | # more powerful IOCP facility
|
31 | 33 | # NOTE: we override in the stdio case, because it doesn't work.
|
32 | 34 | loop_cls = asyncio.ProactorEventLoop # type: ignore[attr-defined,misc]
|
33 | 35 |
|
| 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 | + |
34 | 54 |
|
35 | 55 | class AsyncioEventLoop(BaseEventLoop, asyncio.Protocol,
|
36 | 56 | asyncio.SubprocessProtocol):
|
|
0 commit comments