Skip to content

Commit f7a4d0a

Browse files
authored
Merge branch 'main' into issue-155966
2 parents 216f1da + af49df9 commit f7a4d0a

69 files changed

Lines changed: 2985 additions & 1639 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Doc/library/asyncio-task.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -843,17 +843,13 @@ Timeouts
843843
Wait for the *fut* :ref:`awaitable <asyncio-awaitables>`
844844
to complete with a timeout.
845845

846-
If *fut* is a coroutine it is automatically scheduled as a Task.
847-
848846
*timeout* can either be ``None`` or a float or int number of seconds
849847
to wait for. If *timeout* is ``None``, block until the future
850848
completes.
851849

852-
If a timeout occurs, it cancels the task and raises
853-
:exc:`TimeoutError`.
850+
If a timeout occurs, it cancels *fut* and raises :exc:`TimeoutError`.
854851

855-
To avoid the task :meth:`cancellation <Task.cancel>`,
856-
wrap it in :func:`shield`.
852+
To prevent *fut* from being cancelled, wrap it in :func:`shield`.
857853

858854
The function will wait until the future is actually cancelled,
859855
so the total wait time may exceed the *timeout*. If an exception
@@ -894,6 +890,10 @@ Timeouts
894890
.. versionchanged:: 3.11
895891
Raises :exc:`TimeoutError` instead of :exc:`asyncio.TimeoutError`.
896892

893+
.. versionchanged:: 3.12
894+
Implemented using :func:`asyncio.timeout`, a coroutine passed as *fut*
895+
is no longer wrapped in a :class:`Task` when *timeout* is positive.
896+
897897

898898
Waiting primitives
899899
==================

Lib/asyncio/streams.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,17 @@ def connection_made(self, transport):
239239
self._over_ssl = transport.get_extra_info('sslcontext') is not None
240240
if self._client_connected_cb is not None:
241241
writer = StreamWriter(transport, self, reader, self._loop)
242-
res = self._client_connected_cb(reader, writer)
242+
try:
243+
res = self._client_connected_cb(reader, writer)
244+
except Exception as exc:
245+
self._loop.call_exception_handler({
246+
'message': 'Unhandled exception in client_connected_cb',
247+
'exception': exc,
248+
'transport': transport,
249+
})
250+
transport.close()
251+
self._strong_reader = None
252+
return
243253
if coroutines.iscoroutine(res):
244254
def callback(task):
245255
if task.cancelled():

Lib/asyncio/tasks.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -440,15 +440,13 @@ def _release_waiter(waiter, *args):
440440
async def wait_for(fut, timeout):
441441
"""Wait for the single Future or coroutine to complete, with timeout.
442442
443-
Coroutine will be wrapped in Task.
444-
445443
Returns result of the Future or coroutine. When a timeout occurs,
446-
it cancels the task and raises TimeoutError. To avoid the task
447-
cancellation, wrap it in shield().
444+
it cancels fut and raises TimeoutError. To prevent fut from being
445+
cancelled, wrap it in shield().
448446
449-
If the wait is cancelled, the task is also cancelled.
447+
If the wait is cancelled, fut is also cancelled.
450448
451-
If the task suppresses the cancellation and returns a value instead,
449+
If fut suppresses the cancellation and returns a value instead,
452450
that value is returned.
453451
454452
This function is a coroutine.

Lib/concurrent/interpreters/__init__.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,14 @@ def create():
6868

6969
def list_all():
7070
"""Return all existing interpreters."""
71-
return [Interpreter(id, _whence=whence)
72-
for id, whence in _interpreters.list_all(require_ready=True)]
71+
interps = []
72+
for id, whence in _interpreters.list_all(require_ready=True):
73+
try:
74+
interps.append(Interpreter(id, _whence=whence))
75+
except InterpreterNotFoundError:
76+
# It was destroyed after it was listed.
77+
pass
78+
return interps
7379

7480

7581
def get_current():

Lib/importlib/_bootstrap_external.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,10 @@ def _bless_my_loader(module_globals):
634634
loader = module_globals.get('__loader__', None)
635635
spec = module_globals.get('__spec__', missing)
636636

637+
# The __main__ module of a script or the REPL has __spec__ set to None.
638+
if spec is None and module_globals.get('__name__') == '__main__':
639+
return loader
640+
637641
if loader is None:
638642
if spec is missing:
639643
# If working with a module:

Lib/platform.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -427,11 +427,16 @@ def _win32_ver(version, csd, ptype):
427427

428428
winver = getwindowsversion()
429429
is_client = (getattr(winver, 'product_type', 1) == 1)
430-
try:
431-
version = _syscmd_ver()[2]
432-
major, minor, build = map(int, version.split('.'))
433-
except ValueError:
434-
major, minor, build = winver.platform_version or winver[:3]
430+
431+
if winver.device_family == "Desktop":
432+
try:
433+
version = _syscmd_ver()[2]
434+
major, minor, build = map(int, version.split('.'))
435+
except ValueError:
436+
major, minor, build = winver.platform_version or winver[:3]
437+
version = '{0}.{1}.{2}'.format(major, minor, build)
438+
else:
439+
major, minor, build = winver[:3]
435440
version = '{0}.{1}.{2}'.format(major, minor, build)
436441

437442
# getwindowsversion() reflect the compatibility mode Python is

0 commit comments

Comments
 (0)