Skip to content

Commit 0df6a92

Browse files
gh-71019: Document which objects connect_read_pipe/connect_write_pipe accept
The docs described *pipe* as simply a file-like object, which suggested that regular files and the standard streams would work. They do not: on Unix only pipes, sockets and character devices are accepted (anything else raises ValueError), and on Windows only handles opened for overlapped I/O can be associated with an I/O completion port, so console handles and file handles fail asynchronously rather than at call time. Spell out what is accepted on each platform and note that regular files are never supported.
1 parent 1fece44 commit 0df6a92

2 files changed

Lines changed: 62 additions & 2 deletions

File tree

Doc/library/asyncio-eventloop.rst

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,7 +1263,9 @@ Working with pipes
12631263
*protocol_factory* must be a callable returning an
12641264
:ref:`asyncio protocol <asyncio-protocol>` implementation.
12651265

1266-
*pipe* is a :term:`file-like object <file object>`.
1266+
*pipe* is a :term:`file-like object <file object>`. Not every file-like
1267+
object is accepted; see :ref:`Supported pipe objects
1268+
<asyncio-pipe-objects>` below.
12671269

12681270
Return pair ``(transport, protocol)``, where *transport* supports
12691271
the :class:`ReadTransport` interface and *protocol* is an object
@@ -1280,7 +1282,9 @@ Working with pipes
12801282
*protocol_factory* must be a callable returning an
12811283
:ref:`asyncio protocol <asyncio-protocol>` implementation.
12821284

1283-
*pipe* is :term:`file-like object <file object>`.
1285+
*pipe* is a :term:`file-like object <file object>`. Not every file-like
1286+
object is accepted; see :ref:`Supported pipe objects
1287+
<asyncio-pipe-objects>` below.
12841288

12851289
Return pair ``(transport, protocol)``, where *transport* supports
12861290
:class:`WriteTransport` interface and *protocol* is an object
@@ -1289,6 +1293,44 @@ Working with pipes
12891293
With :class:`SelectorEventLoop` event loop, the *pipe* is set to
12901294
non-blocking mode.
12911295

1296+
.. _asyncio-pipe-objects:
1297+
1298+
.. rubric:: Supported pipe objects
1299+
1300+
Even though the *pipe* argument is a :term:`file-like object <file object>`,
1301+
these methods only work with objects the operating system can poll for
1302+
readiness or perform overlapped I/O on. Regular files on disk are **not**
1303+
supported on any platform, and neither are :data:`sys.stdin`,
1304+
:data:`sys.stdout` and :data:`sys.stderr` when they have been redirected to
1305+
or from a regular file. There is no asynchronous file I/O in asyncio; use
1306+
:meth:`loop.run_in_executor` to read and write regular files without
1307+
blocking the event loop.
1308+
1309+
On Unix, with :class:`SelectorEventLoop`, *pipe* must wrap one of the
1310+
following:
1311+
1312+
* a pipe, such as an end of an :func:`os.pipe` pair or a FIFO created with
1313+
:func:`os.mkfifo`;
1314+
* a socket;
1315+
* a character device, such as a terminal. This is why :data:`sys.stdin`
1316+
works when the program is run interactively but fails when its input is
1317+
redirected from a file.
1318+
1319+
Anything else, a regular file in particular, raises :exc:`ValueError`.
1320+
1321+
On Windows, where only :class:`ProactorEventLoop` implements these methods,
1322+
*pipe* must wrap a handle opened for overlapped I/O, since the handle has to
1323+
be associated with an I/O completion port. In practice this means a named
1324+
pipe, such as the ones created by :func:`!asyncio.windows_utils.pipe` and
1325+
used for the standard streams of a subprocess started by
1326+
:meth:`loop.subprocess_exec`. Console handles and regular file handles
1327+
cannot be associated with a completion port, so :data:`sys.stdin` and files
1328+
opened with :func:`open` do not work. Unlike on Unix, this is not reported
1329+
by the method itself: it returns successfully and the resulting
1330+
:exc:`OSError` is later passed to the
1331+
:meth:`event loop exception handler <loop.call_exception_handler>` when the
1332+
transport first reads or writes.
1333+
12921334
.. note::
12931335

12941336
:class:`SelectorEventLoop` does not support the above methods on

Doc/library/asyncio-platforms.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ All Platforms
1919
* :meth:`loop.add_reader` and :meth:`loop.add_writer`
2020
cannot be used to monitor file I/O.
2121

22+
* :meth:`loop.connect_read_pipe` and :meth:`loop.connect_write_pipe`
23+
cannot be used with regular files, nor with :data:`sys.stdin`,
24+
:data:`sys.stdout` or :data:`sys.stderr` when these are redirected to or
25+
from a regular file. See :ref:`Supported pipe objects
26+
<asyncio-pipe-objects>` for the objects that are accepted on each
27+
platform.
28+
2229

2330
Windows
2431
=======
@@ -62,6 +69,17 @@ All event loops on Windows do not support the following methods:
6269
* The :meth:`loop.add_reader` and :meth:`loop.add_writer`
6370
methods are not supported.
6471

72+
* :meth:`loop.connect_read_pipe` and :meth:`loop.connect_write_pipe` only
73+
accept a handle opened for overlapped I/O, which in practice means a named
74+
pipe such as those created by :func:`!asyncio.windows_utils.pipe`.
75+
Console handles and regular file handles cannot be associated with an I/O
76+
completion port, so :data:`sys.stdin`, :data:`sys.stdout`,
77+
:data:`sys.stderr` and files opened with :func:`open` are not supported.
78+
These methods do not fail immediately in that case: the resulting
79+
:exc:`OSError` is passed to the
80+
:meth:`event loop exception handler <loop.call_exception_handler>` when the
81+
transport first reads or writes.
82+
6583
The resolution of the monotonic clock on Windows is usually around 15.6
6684
milliseconds. The best resolution is 0.5 milliseconds. The resolution depends on the
6785
hardware (availability of `HPET

0 commit comments

Comments
 (0)