summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Lib/asyncio
diff options
context:
space:
mode:
authorshadchin <[email protected]>2026-06-24 07:09:14 +0300
committershadchin <[email protected]>2026-06-24 07:31:09 +0300
commit280914cd46f4411a2e01150bf9d9c53dff19fa66 (patch)
tree841d7b8330cb51e86f2ea6e915e4904563321aca /contrib/tools/python3/Lib/asyncio
parent1100ced6faf1d14f48cb041f885882d3b37491a2 (diff)
Update Python 3 to 3.13.14
commit_hash:9913a0288f56b5ddd0f99e5b2ff1569d491cbe5d
Diffstat (limited to 'contrib/tools/python3/Lib/asyncio')
-rw-r--r--contrib/tools/python3/Lib/asyncio/__main__.py12
-rw-r--r--contrib/tools/python3/Lib/asyncio/base_events.py37
-rw-r--r--contrib/tools/python3/Lib/asyncio/events.py21
-rw-r--r--contrib/tools/python3/Lib/asyncio/locks.py18
-rw-r--r--contrib/tools/python3/Lib/asyncio/proactor_events.py3
-rw-r--r--contrib/tools/python3/Lib/asyncio/queues.py36
-rw-r--r--contrib/tools/python3/Lib/asyncio/runners.py3
-rw-r--r--contrib/tools/python3/Lib/asyncio/selector_events.py31
-rw-r--r--contrib/tools/python3/Lib/asyncio/streams.py14
-rw-r--r--contrib/tools/python3/Lib/asyncio/tasks.py57
-rw-r--r--contrib/tools/python3/Lib/asyncio/threads.py3
-rw-r--r--contrib/tools/python3/Lib/asyncio/timeouts.py3
-rw-r--r--contrib/tools/python3/Lib/asyncio/unix_events.py21
-rw-r--r--contrib/tools/python3/Lib/asyncio/windows_events.py3
-rw-r--r--contrib/tools/python3/Lib/asyncio/windows_utils.py3
15 files changed, 143 insertions, 122 deletions
diff --git a/contrib/tools/python3/Lib/asyncio/__main__.py b/contrib/tools/python3/Lib/asyncio/__main__.py
index 42bfcdbf50f..2effdbc38da 100644
--- a/contrib/tools/python3/Lib/asyncio/__main__.py
+++ b/contrib/tools/python3/Lib/asyncio/__main__.py
@@ -96,11 +96,15 @@ class REPLThread(threading.Thread):
if not sys.flags.isolated and (startup_path := os.getenv("PYTHONSTARTUP")):
sys.audit("cpython.run_startup", startup_path)
-
- import tokenize
- with tokenize.open(startup_path) as f:
- startup_code = compile(f.read(), startup_path, "exec")
+ try:
+ import tokenize
+ with tokenize.open(startup_path) as f:
+ startup_code = compile(f.read(), startup_path, "exec")
exec(startup_code, console.locals)
+ except SystemExit:
+ raise
+ except BaseException:
+ console.showtraceback()
ps1 = getattr(sys, "ps1", ">>> ")
if can_colorize() and CAN_USE_PYREPL:
diff --git a/contrib/tools/python3/Lib/asyncio/base_events.py b/contrib/tools/python3/Lib/asyncio/base_events.py
index 84cad10636f..ec8e3b6f79f 100644
--- a/contrib/tools/python3/Lib/asyncio/base_events.py
+++ b/contrib/tools/python3/Lib/asyncio/base_events.py
@@ -489,10 +489,10 @@ class BaseEventLoop(events.AbstractEventLoop):
If factory is None the default task factory will be set.
If factory is a callable, it should have a signature matching
- '(loop, coro, **kwargs)', where 'loop' will be a reference to the active
- event loop, 'coro' will be a coroutine object, and **kwargs will be
- arbitrary keyword arguments that should be passed on to Task.
- The callable must return a Task.
+ '(loop, coro, **kwargs)', where 'loop' will be a reference to the
+ active event loop, 'coro' will be a coroutine object, and **kwargs
+ will be arbitrary keyword arguments that should be passed on to
+ Task. The callable must return a Task.
"""
if factory is not None and not callable(factory):
raise TypeError('task factory must be a callable or None')
@@ -727,8 +727,8 @@ class BaseEventLoop(events.AbstractEventLoop):
def stop(self):
"""Stop running the event loop.
- Every callback already scheduled will still run. This simply informs
- run_forever to stop looping after a complete iteration.
+ Every callback already scheduled will still run. This simply
+ informs run_forever to stop looping after a complete iteration.
"""
self._stopping = True
@@ -966,7 +966,7 @@ class BaseEventLoop(events.AbstractEventLoop):
f"and file {file!r} combination")
async def _sock_sendfile_fallback(self, sock, file, offset, count):
- if offset:
+ if hasattr(file, 'seek'):
file.seek(offset)
blocksize = (
min(count, constants.SENDFILE_FALLBACK_READBUFFER_SIZE)
@@ -1073,12 +1073,12 @@ class BaseEventLoop(events.AbstractEventLoop):
Create a streaming transport connection to a given internet host and
port: socket family AF_INET or socket.AF_INET6 depending on host (or
- family if specified), socket type SOCK_STREAM. protocol_factory must be
- a callable returning a protocol instance.
+ family if specified), socket type SOCK_STREAM. protocol_factory must
+ be a callable returning a protocol instance.
- This method is a coroutine which will try to establish the connection
- in the background. When successful, the coroutine returns a
- (transport, protocol) pair.
+ This method is a coroutine which will try to establish the
+ connection in the background. When successful, the coroutine
+ returns a (transport, protocol) pair.
"""
if server_hostname is not None and not ssl:
raise ValueError('server_hostname is only meaningful with ssl')
@@ -1281,7 +1281,6 @@ class BaseEventLoop(events.AbstractEventLoop):
raise RuntimeError(
f"fallback is disabled and native sendfile is not "
f"supported for transport {transport!r}")
-
return await self._sendfile_fallback(transport, file,
offset, count)
@@ -1290,7 +1289,7 @@ class BaseEventLoop(events.AbstractEventLoop):
"sendfile syscall is not supported")
async def _sendfile_fallback(self, transp, file, offset, count):
- if offset:
+ if hasattr(file, 'seek'):
file.seek(offset)
blocksize = min(count, 16384) if count else 16384
buf = bytearray(blocksize)
@@ -1546,11 +1545,11 @@ class BaseEventLoop(events.AbstractEventLoop):
The host parameter can be a string, in that case the TCP server is
bound to host and port.
- The host parameter can also be a sequence of strings and in that case
- the TCP server is bound to all hosts of the sequence. If a host
- appears multiple times (possibly indirectly e.g. when hostnames
- resolve to the same IP address), the server is only bound once to that
- host.
+ The host parameter can also be a sequence of strings and in that
+ case the TCP server is bound to all hosts of the sequence. If
+ a host appears multiple times (possibly indirectly e.g. when
+ hostnames resolve to the same IP address), the server is only bound
+ once to that host.
Return a Server object which can be used to stop the service.
diff --git a/contrib/tools/python3/Lib/asyncio/events.py b/contrib/tools/python3/Lib/asyncio/events.py
index 3b740b9b905..24e49d561e6 100644
--- a/contrib/tools/python3/Lib/asyncio/events.py
+++ b/contrib/tools/python3/Lib/asyncio/events.py
@@ -341,8 +341,8 @@ class AbstractEventLoop:
If host is an empty string or None all interfaces are assumed
and a list of multiple sockets will be returned (most likely
- one for IPv4 and another one for IPv6). The host parameter can also be
- a sequence (e.g. list) of hosts to bind to.
+ one for IPv4 and another one for IPv6). The host parameter can also
+ be a sequence (e.g. list) of hosts to bind to.
family can be set to either AF_INET or AF_INET6 to force the
socket to use IPv4 or IPv6. If not set it will be determined
@@ -382,8 +382,9 @@ class AbstractEventLoop:
start_serving set to True (default) causes the created server
to start accepting connections immediately. When set to False,
- the user should await Server.start_serving() or Server.serve_forever()
- to make the server to start accepting connections.
+ the user should await Server.start_serving() or
+ Server.serve_forever() to make the server to start accepting
+ connections.
"""
raise NotImplementedError
@@ -446,8 +447,9 @@ class AbstractEventLoop:
start_serving set to True (default) causes the created server
to start accepting connections immediately. When set to False,
- the user should await Server.start_serving() or Server.serve_forever()
- to make the server to start accepting connections.
+ the user should await Server.start_serving() or
+ Server.serve_forever() to make the server to start accepting
+ connections.
"""
raise NotImplementedError
@@ -478,8 +480,8 @@ class AbstractEventLoop:
protocol_factory must be a callable returning a protocol instance.
- socket family AF_INET, socket.AF_INET6 or socket.AF_UNIX depending on
- host (or family if specified), socket type SOCK_DGRAM.
+ socket family AF_INET, socket.AF_INET6 or socket.AF_UNIX depending
+ on host (or family if specified), socket type SOCK_DGRAM.
reuse_address tells the kernel to reuse a local socket in
TIME_WAIT state, without waiting for its natural timeout to
@@ -519,7 +521,8 @@ class AbstractEventLoop:
async def connect_write_pipe(self, protocol_factory, pipe):
"""Register write pipe in event loop.
- protocol_factory should instantiate object with BaseProtocol interface.
+ protocol_factory should instantiate object with BaseProtocol
+ interface.
Pipe is file-like object already switched to nonblocking.
Return pair (transport, protocol), where transport support
WriteTransport interface."""
diff --git a/contrib/tools/python3/Lib/asyncio/locks.py b/contrib/tools/python3/Lib/asyncio/locks.py
index 3df4c693a91..22af506d497 100644
--- a/contrib/tools/python3/Lib/asyncio/locks.py
+++ b/contrib/tools/python3/Lib/asyncio/locks.py
@@ -158,10 +158,10 @@ class Lock(_ContextManagerMixin, mixins._LoopBoundMixin):
class Event(mixins._LoopBoundMixin):
"""Asynchronous equivalent to threading.Event.
- Class implementing event objects. An event manages a flag that can be set
- to true with the set() method and reset to false with the clear() method.
- The wait() method blocks until the flag is true. The flag is initially
- false.
+ Class implementing event objects. An event manages a flag that can be
+ set to true with the set() method and reset to false with the clear()
+ method. The wait() method blocks until the flag is true. The flag is
+ initially false.
"""
def __init__(self):
@@ -353,9 +353,9 @@ class Semaphore(_ContextManagerMixin, mixins._LoopBoundMixin):
"""A Semaphore implementation.
A semaphore manages an internal counter which is decremented by each
- acquire() call and incremented by each release() call. The counter
- can never go below zero; when acquire() finds that it is zero, it blocks,
- waiting until some other thread calls release().
+ acquire() call and incremented by each release() call. The counter
+ can never go below zero; when acquire() finds that it is zero, it
+ blocks, waiting until some other thread calls release().
Semaphores also support the context management protocol.
@@ -511,8 +511,8 @@ class Barrier(mixins._LoopBoundMixin):
async def wait(self):
"""Wait for the barrier.
- When the specified number of tasks have started waiting, they are all
- simultaneously awoken.
+ When the specified number of tasks have started waiting, they are
+ all simultaneously awoken.
Returns an unique and individual index number from 0 to 'parties-1'.
"""
async with self._cond:
diff --git a/contrib/tools/python3/Lib/asyncio/proactor_events.py b/contrib/tools/python3/Lib/asyncio/proactor_events.py
index f404273c3ae..6b94975d004 100644
--- a/contrib/tools/python3/Lib/asyncio/proactor_events.py
+++ b/contrib/tools/python3/Lib/asyncio/proactor_events.py
@@ -756,8 +756,7 @@ class BaseProactorEventLoop(base_events.BaseEventLoop):
offset += blocksize
total_sent += blocksize
finally:
- if total_sent > 0:
- file.seek(offset)
+ file.seek(offset)
async def _sendfile_native(self, transp, file, offset, count):
resume_reading = transp.is_reading()
diff --git a/contrib/tools/python3/Lib/asyncio/queues.py b/contrib/tools/python3/Lib/asyncio/queues.py
index 756216fac80..30004f2bc9b 100644
--- a/contrib/tools/python3/Lib/asyncio/queues.py
+++ b/contrib/tools/python3/Lib/asyncio/queues.py
@@ -33,9 +33,9 @@ class QueueShutDown(Exception):
class Queue(mixins._LoopBoundMixin):
"""A queue, useful for coordinating producer and consumer coroutines.
- If maxsize is less than or equal to zero, the queue size is infinite. If it
- is an integer greater than 0, then "await put()" will block when the
- queue reaches maxsize, until an item is removed by get().
+ If maxsize is less than or equal to zero, the queue size is infinite.
+ If it is an integer greater than 0, then "await put()" will block when
+ the queue reaches maxsize, until an item is removed by get().
Unlike queue.Queue, you can reliably know this Queue's size
with qsize(), since your single-threaded asyncio application won't be
@@ -174,8 +174,8 @@ class Queue(mixins._LoopBoundMixin):
If queue is empty, wait until an item is available.
- Raises QueueShutDown if the queue has been shut down and is empty, or
- if the queue has been shut down immediately.
+ Raises QueueShutDown if the queue has been shut down and is empty,
+ or if the queue has been shut down immediately.
"""
while self.empty():
if self._is_shutdown and self.empty():
@@ -203,10 +203,11 @@ class Queue(mixins._LoopBoundMixin):
def get_nowait(self):
"""Remove and return an item from the queue.
- Return an item if one is immediately available, else raise QueueEmpty.
+ Return an item if one is immediately available, else raise
+ QueueEmpty.
- Raises QueueShutDown if the queue has been shut down and is empty, or
- if the queue has been shut down immediately.
+ Raises QueueShutDown if the queue has been shut down and is empty,
+ or if the queue has been shut down immediately.
"""
if self.empty():
if self._is_shutdown:
@@ -223,12 +224,12 @@ class Queue(mixins._LoopBoundMixin):
a subsequent call to task_done() tells the queue that the processing
on the task is complete.
- If a join() is currently blocking, it will resume when all items have
- been processed (meaning that a task_done() call was received for every
- item that had been put() into the queue).
+ If a join() is currently blocking, it will resume when all items
+ have been processed (meaning that a task_done() call was received
+ for every item that had been put() into the queue).
- Raises ValueError if called more times than there were items placed in
- the queue.
+ Raises ValueError if called more times than there were items placed
+ in the queue.
"""
if self._unfinished_tasks <= 0:
raise ValueError('task_done() called too many times')
@@ -239,10 +240,11 @@ class Queue(mixins._LoopBoundMixin):
async def join(self):
"""Block until all items in the queue have been gotten and processed.
- The count of unfinished tasks goes up whenever an item is added to the
- queue. The count goes down whenever a consumer calls task_done() to
- indicate that the item was retrieved and all work on it is complete.
- When the count of unfinished tasks drops to zero, join() unblocks.
+ The count of unfinished tasks goes up whenever an item is added to
+ the queue. The count goes down whenever a consumer calls
+ task_done() to indicate that the item was retrieved and all work on
+ it is complete. When the count of unfinished tasks drops to zero,
+ join() unblocks.
"""
if self._unfinished_tasks > 0:
await self._finished.wait()
diff --git a/contrib/tools/python3/Lib/asyncio/runners.py b/contrib/tools/python3/Lib/asyncio/runners.py
index 102ae78021b..c7bfdad319f 100644
--- a/contrib/tools/python3/Lib/asyncio/runners.py
+++ b/contrib/tools/python3/Lib/asyncio/runners.py
@@ -34,7 +34,8 @@ class Runner:
with asyncio.Runner(debug=True) as runner:
runner.run(main())
- The run() method can be called multiple times within the runner's context.
+ The run() method can be called multiple times within the runner's
+ context.
This can be useful for interactive console (e.g. IPython),
unittest runners, console tools, -- everywhere when async code
diff --git a/contrib/tools/python3/Lib/asyncio/selector_events.py b/contrib/tools/python3/Lib/asyncio/selector_events.py
index ff7e16df3c6..7c2062e3dd5 100644
--- a/contrib/tools/python3/Lib/asyncio/selector_events.py
+++ b/contrib/tools/python3/Lib/asyncio/selector_events.py
@@ -530,11 +530,12 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
async def sock_sendall(self, sock, data):
"""Send data to the socket.
- The socket must be connected to a remote socket. This method continues
- to send data from data until either all data has been sent or an
- error occurs. None is returned on success. On error, an exception is
- raised, and there is no way to determine how much data, if any, was
- successfully processed by the receiving end of the connection.
+ The socket must be connected to a remote socket. This method
+ continues to send data from data until either all data has been
+ sent or an error occurs. None is returned on success. On error,
+ an exception is raised, and there is no way to determine how much
+ data, if any, was successfully processed by the receiving end of
+ the connection.
"""
base_events._check_ssl_socket(sock)
if self._debug and sock.gettimeout() != 0:
@@ -583,11 +584,12 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
async def sock_sendto(self, sock, data, address):
"""Send data to the socket.
- The socket must be connected to a remote socket. This method continues
- to send data from data until either all data has been sent or an
- error occurs. None is returned on success. On error, an exception is
- raised, and there is no way to determine how much data, if any, was
- successfully processed by the receiving end of the connection.
+ The socket must be connected to a remote socket. This method
+ continues to send data from data until either all data has been
+ sent or an error occurs. None is returned on success. On error,
+ an exception is raised, and there is no way to determine how much
+ data, if any, was successfully processed by the receiving end of
+ the connection.
"""
base_events._check_ssl_socket(sock)
if self._debug and sock.gettimeout() != 0:
@@ -698,10 +700,11 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
async def sock_accept(self, sock):
"""Accept a connection.
- The socket must be bound to an address and listening for connections.
- The return value is a pair (conn, address) where conn is a new socket
- object usable to send and receive data on the connection, and address
- is the address bound to the socket on the other end of the connection.
+ The socket must be bound to an address and listening for
+ connections. The return value is a pair (conn, address) where
+ conn is a new socket object usable to send and receive data on the
+ connection, and address is the address bound to the socket on the
+ other end of the connection.
"""
base_events._check_ssl_socket(sock)
if self._debug and sock.gettimeout() != 0:
diff --git a/contrib/tools/python3/Lib/asyncio/streams.py b/contrib/tools/python3/Lib/asyncio/streams.py
index 64aac4cc50d..dd8f6618623 100644
--- a/contrib/tools/python3/Lib/asyncio/streams.py
+++ b/contrib/tools/python3/Lib/asyncio/streams.py
@@ -541,17 +541,17 @@ class StreamReader:
self._waiter = None
async def readline(self):
- """Read chunk of data from the stream until newline (b'\n') is found.
+ r"""Read chunk of data from the stream until newline (b'\n') is found.
- On success, return chunk that ends with newline. If only partial
+ On success, return chunk that ends with newline. If only partial
line can be read due to EOF, return incomplete line without
- terminating newline. When EOF was reached while no bytes read, empty
- bytes object is returned.
+ terminating newline. When EOF was reached while no bytes read,
+ empty bytes object is returned.
- If limit is reached, ValueError will be raised. In that case, if
+ If limit is reached, ValueError will be raised. In that case, if
newline was found, complete line including newline will be removed
- from internal buffer. Else, internal buffer will be cleared. Limit is
- compared against part of the line without newline.
+ from internal buffer. Else, internal buffer will be cleared.
+ Limit is compared against part of the line without newline.
If stream was paused, this function will automatically resume it if
needed.
diff --git a/contrib/tools/python3/Lib/asyncio/tasks.py b/contrib/tools/python3/Lib/asyncio/tasks.py
index dadcb5b5f36..e5e7d3e4aa9 100644
--- a/contrib/tools/python3/Lib/asyncio/tasks.py
+++ b/contrib/tools/python3/Lib/asyncio/tasks.py
@@ -640,10 +640,11 @@ def as_completed(fs, *, timeout=None):
Run the supplied awaitables concurrently. The returned object can be
iterated to obtain the results of the awaitables as they finish.
- The object returned can be iterated as an asynchronous iterator or a plain
- iterator. When asynchronous iteration is used, the originally-supplied
- awaitables are yielded if they are tasks or futures. This makes it easy to
- correlate previously-scheduled tasks with their results:
+ The object returned can be iterated as an asynchronous iterator or
+ a plain iterator. When asynchronous iteration is used, the
+ originally-supplied awaitables are yielded if they are tasks or
+ futures. This makes it easy to correlate previously-scheduled tasks
+ with their results:
ipv4_connect = create_task(open_connection("127.0.0.1", 80))
ipv6_connect = create_task(open_connection("::1", 80))
@@ -659,26 +660,27 @@ def as_completed(fs, *, timeout=None):
else:
print("IPv4 connection established.")
- During asynchronous iteration, implicitly-created tasks will be yielded for
- supplied awaitables that aren't tasks or futures.
+ During asynchronous iteration, implicitly-created tasks will be
+ yielded for supplied awaitables that aren't tasks or futures.
- When used as a plain iterator, each iteration yields a new coroutine that
- returns the result or raises the exception of the next completed awaitable.
- This pattern is compatible with Python versions older than 3.13:
+ When used as a plain iterator, each iteration yields a new coroutine
+ that returns the result or raises the exception of the next completed
+ awaitable. This pattern is compatible with Python versions older than
+ 3.13:
ipv4_connect = create_task(open_connection("127.0.0.1", 80))
ipv6_connect = create_task(open_connection("::1", 80))
tasks = [ipv4_connect, ipv6_connect]
for next_connect in as_completed(tasks):
- # next_connect is not one of the original task objects. It must be
- # awaited to obtain the result value or raise the exception of the
- # awaitable that finishes next.
+ # next_connect is not one of the original task objects. It must
+ # be awaited to obtain the result value or raise the exception
+ # of the awaitable that finishes next.
reader, writer = await next_connect
- A TimeoutError is raised if the timeout occurs before all awaitables are
- done. This is raised by the async for loop during asynchronous iteration or
- by the coroutines yielded during plain iteration.
+ A TimeoutError is raised if the timeout occurs before all awaitables
+ are done. This is raised by the async for loop during asynchronous
+ iteration or by the coroutines yielded during plain iteration.
"""
if inspect.isawaitable(fs):
raise TypeError(
@@ -1007,21 +1009,22 @@ def run_coroutine_threadsafe(coro, loop):
def create_eager_task_factory(custom_task_constructor):
"""Create a function suitable for use as a task factory on an event-loop.
- Example usage:
+ Example usage:
- loop.set_task_factory(
- asyncio.create_eager_task_factory(my_task_constructor))
+ loop.set_task_factory(
+ asyncio.create_eager_task_factory(my_task_constructor))
- Now, tasks created will be started immediately (rather than being first
- scheduled to an event loop). The constructor argument can be any callable
- that returns a Task-compatible object and has a signature compatible
- with `Task.__init__`; it must have the `eager_start` keyword argument.
+ Now, tasks created will be started immediately (rather than being first
+ scheduled to an event loop). The constructor argument can be any
+ callable that returns a Task-compatible object and has a signature
+ compatible with `Task.__init__`; it must have the `eager_start`
+ keyword argument.
- Most applications will use `Task` for `custom_task_constructor` and in
- this case there's no need to call `create_eager_task_factory()`
- directly. Instead the global `eager_task_factory` instance can be
- used. E.g. `loop.set_task_factory(asyncio.eager_task_factory)`.
- """
+ Most applications will use `Task` for `custom_task_constructor` and in
+ this case there's no need to call `create_eager_task_factory()`
+ directly. Instead the global `eager_task_factory` instance can be
+ used. E.g. `loop.set_task_factory(asyncio.eager_task_factory)`.
+ """
def factory(loop, coro, *, name=None, context=None):
return custom_task_constructor(
diff --git a/contrib/tools/python3/Lib/asyncio/threads.py b/contrib/tools/python3/Lib/asyncio/threads.py
index db048a8231d..5001351b097 100644
--- a/contrib/tools/python3/Lib/asyncio/threads.py
+++ b/contrib/tools/python3/Lib/asyncio/threads.py
@@ -17,7 +17,8 @@ async def to_thread(func, /, *args, **kwargs):
allowing context variables from the main thread to be accessed in the
separate thread.
- Return a coroutine that can be awaited to get the eventual result of *func*.
+ Return a coroutine that can be awaited to get the eventual result of
+ *func*.
"""
loop = events.get_running_loop()
ctx = contextvars.copy_context()
diff --git a/contrib/tools/python3/Lib/asyncio/timeouts.py b/contrib/tools/python3/Lib/asyncio/timeouts.py
index e6f5100691d..7ac664be47c 100644
--- a/contrib/tools/python3/Lib/asyncio/timeouts.py
+++ b/contrib/tools/python3/Lib/asyncio/timeouts.py
@@ -27,7 +27,8 @@ class _State(enum.Enum):
class Timeout:
"""Asynchronous context manager for cancelling overdue coroutines.
- Use `timeout()` or `timeout_at()` rather than instantiating this class directly.
+ Use `timeout()` or `timeout_at()` rather than instantiating this class
+ directly.
"""
def __init__(self, when: Optional[float]) -> None:
diff --git a/contrib/tools/python3/Lib/asyncio/unix_events.py b/contrib/tools/python3/Lib/asyncio/unix_events.py
index 41ccf1b78fb..9222a8769e9 100644
--- a/contrib/tools/python3/Lib/asyncio/unix_events.py
+++ b/contrib/tools/python3/Lib/asyncio/unix_events.py
@@ -58,7 +58,8 @@ def waitstatus_to_exitcode(status):
class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
"""Unix event loop.
- Adds signal handling and UNIX Domain Socket support to SelectorEventLoop.
+ Adds signal handling and UNIX Domain Socket support to
+ SelectorEventLoop.
"""
def __init__(self, selector=None):
@@ -395,12 +396,12 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
# order to simplify the common case.
self.remove_writer(registered_fd)
if fut.cancelled():
- self._sock_sendfile_update_filepos(fileno, offset, total_sent)
+ self._sock_sendfile_update_filepos(fileno, offset)
return
if count:
blocksize = count - total_sent
if blocksize <= 0:
- self._sock_sendfile_update_filepos(fileno, offset, total_sent)
+ self._sock_sendfile_update_filepos(fileno, offset)
fut.set_result(total_sent)
return
@@ -434,20 +435,20 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
# plain send().
err = exceptions.SendfileNotAvailableError(
"os.sendfile call failed")
- self._sock_sendfile_update_filepos(fileno, offset, total_sent)
+ self._sock_sendfile_update_filepos(fileno, offset)
fut.set_exception(err)
else:
- self._sock_sendfile_update_filepos(fileno, offset, total_sent)
+ self._sock_sendfile_update_filepos(fileno, offset)
fut.set_exception(exc)
except (SystemExit, KeyboardInterrupt):
raise
except BaseException as exc:
- self._sock_sendfile_update_filepos(fileno, offset, total_sent)
+ self._sock_sendfile_update_filepos(fileno, offset)
fut.set_exception(exc)
else:
if sent == 0:
# EOF
- self._sock_sendfile_update_filepos(fileno, offset, total_sent)
+ self._sock_sendfile_update_filepos(fileno, offset)
fut.set_result(total_sent)
else:
offset += sent
@@ -458,9 +459,9 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
fd, sock, fileno,
offset, count, blocksize, total_sent)
- def _sock_sendfile_update_filepos(self, fileno, offset, total_sent):
- if total_sent > 0:
- os.lseek(fileno, offset, os.SEEK_SET)
+ def _sock_sendfile_update_filepos(self, fileno, offset):
+ # After this helper runs, the source fd's lseek pointer is at offset."
+ os.lseek(fileno, offset, os.SEEK_SET)
def _sock_add_cancellation_callback(self, fut, sock):
def cb(fut):
diff --git a/contrib/tools/python3/Lib/asyncio/windows_events.py b/contrib/tools/python3/Lib/asyncio/windows_events.py
index bf99bc271c7..a36832f7f9f 100644
--- a/contrib/tools/python3/Lib/asyncio/windows_events.py
+++ b/contrib/tools/python3/Lib/asyncio/windows_events.py
@@ -610,6 +610,9 @@ class IocpProactor:
ov = _overlapped.Overlapped(NULL)
offset_low = offset & 0xffff_ffff
offset_high = (offset >> 32) & 0xffff_ffff
+ # TransmitFile ignores OVERLAPPED.Offset for handles not opened with
+ # FILE_FLAG_OVERLAPPED, so seek the CRT file pointer to match.
+ file.seek(offset)
ov.TransmitFile(sock.fileno(),
msvcrt.get_osfhandle(file.fileno()),
offset_low, offset_high,
diff --git a/contrib/tools/python3/Lib/asyncio/windows_utils.py b/contrib/tools/python3/Lib/asyncio/windows_utils.py
index acd49441131..d6393f0b1ff 100644
--- a/contrib/tools/python3/Lib/asyncio/windows_utils.py
+++ b/contrib/tools/python3/Lib/asyncio/windows_utils.py
@@ -111,8 +111,9 @@ class PipeHandle:
def close(self, *, CloseHandle=_winapi.CloseHandle):
if self._handle is not None:
- CloseHandle(self._handle)
+ handle = self._handle
self._handle = None
+ CloseHandle(handle)
def __del__(self, _warn=warnings.warn):
if self._handle is not None: