Skip to content

Commit d1b55f5

Browse files
authored
Merge pull request #6902 from youknowone/asyncio
Update asyncio to 3.14.2
2 parents d8e582e + 7258a4a commit d1b55f5

Some content is hidden

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

66 files changed

+4695
-2109
lines changed

Lib/asyncio/__init__.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from .events import *
1111
from .exceptions import *
1212
from .futures import *
13+
from .graph import *
1314
from .locks import *
1415
from .protocols import *
1516
from .runners import *
@@ -27,6 +28,7 @@
2728
events.__all__ +
2829
exceptions.__all__ +
2930
futures.__all__ +
31+
graph.__all__ +
3032
locks.__all__ +
3133
protocols.__all__ +
3234
runners.__all__ +
@@ -45,3 +47,28 @@
4547
else:
4648
from .unix_events import * # pragma: no cover
4749
__all__ += unix_events.__all__
50+
51+
def __getattr__(name: str):
52+
import warnings
53+
54+
match name:
55+
case "AbstractEventLoopPolicy":
56+
warnings._deprecated(f"asyncio.{name}", remove=(3, 16))
57+
return events._AbstractEventLoopPolicy
58+
case "DefaultEventLoopPolicy":
59+
warnings._deprecated(f"asyncio.{name}", remove=(3, 16))
60+
if sys.platform == 'win32':
61+
return windows_events._DefaultEventLoopPolicy
62+
return unix_events._DefaultEventLoopPolicy
63+
case "WindowsSelectorEventLoopPolicy":
64+
if sys.platform == 'win32':
65+
warnings._deprecated(f"asyncio.{name}", remove=(3, 16))
66+
return windows_events._WindowsSelectorEventLoopPolicy
67+
# Else fall through to the AttributeError below.
68+
case "WindowsProactorEventLoopPolicy":
69+
if sys.platform == 'win32':
70+
warnings._deprecated(f"asyncio.{name}", remove=(3, 16))
71+
return windows_events._WindowsProactorEventLoopPolicy
72+
# Else fall through to the AttributeError below.
73+
74+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

Lib/asyncio/__main__.py

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import argparse
12
import ast
23
import asyncio
4+
import asyncio.tools
35
import concurrent.futures
46
import contextvars
57
import inspect
@@ -10,7 +12,7 @@
1012
import types
1113
import warnings
1214

13-
from _colorize import can_colorize, ANSIColors # type: ignore[import-not-found]
15+
from _colorize import get_theme
1416
from _pyrepl.console import InteractiveColoredConsole
1517

1618
from . import futures
@@ -102,8 +104,9 @@ def run(self):
102104
exec(startup_code, console.locals)
103105

104106
ps1 = getattr(sys, "ps1", ">>> ")
105-
if can_colorize() and CAN_USE_PYREPL:
106-
ps1 = f"{ANSIColors.BOLD_MAGENTA}{ps1}{ANSIColors.RESET}"
107+
if CAN_USE_PYREPL:
108+
theme = get_theme().syntax
109+
ps1 = f"{theme.prompt}{ps1}{theme.reset}"
107110
console.write(f"{ps1}import asyncio\n")
108111

109112
if CAN_USE_PYREPL:
@@ -141,6 +144,37 @@ def interrupt(self) -> None:
141144

142145

143146
if __name__ == '__main__':
147+
parser = argparse.ArgumentParser(
148+
prog="python3 -m asyncio",
149+
description="Interactive asyncio shell and CLI tools",
150+
color=True,
151+
)
152+
subparsers = parser.add_subparsers(help="sub-commands", dest="command")
153+
ps = subparsers.add_parser(
154+
"ps", help="Display a table of all pending tasks in a process"
155+
)
156+
ps.add_argument("pid", type=int, help="Process ID to inspect")
157+
pstree = subparsers.add_parser(
158+
"pstree", help="Display a tree of all pending tasks in a process"
159+
)
160+
pstree.add_argument("pid", type=int, help="Process ID to inspect")
161+
args = parser.parse_args()
162+
match args.command:
163+
case "ps":
164+
asyncio.tools.display_awaited_by_tasks_table(args.pid)
165+
sys.exit(0)
166+
case "pstree":
167+
asyncio.tools.display_awaited_by_tasks_tree(args.pid)
168+
sys.exit(0)
169+
case None:
170+
pass # continue to the interactive shell
171+
case _:
172+
# shouldn't happen as an invalid command-line wouldn't parse
173+
# but let's keep it for the next person adding a command
174+
print(f"error: unhandled command {args.command}", file=sys.stderr)
175+
parser.print_usage(file=sys.stderr)
176+
sys.exit(1)
177+
144178
sys.audit("cpython.run_stdin")
145179

146180
if os.getenv('PYTHON_BASIC_REPL'):

Lib/asyncio/base_events.py

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -458,24 +458,18 @@ def create_future(self):
458458
"""Create a Future object attached to the loop."""
459459
return futures.Future(loop=self)
460460

461-
def create_task(self, coro, *, name=None, context=None, **kwargs):
462-
"""Schedule a coroutine object.
461+
def create_task(self, coro, **kwargs):
462+
"""Schedule or begin executing a coroutine object.
463463
464464
Return a task object.
465465
"""
466466
self._check_closed()
467467
if self._task_factory is not None:
468-
if context is not None:
469-
kwargs["context"] = context
470-
471-
task = self._task_factory(self, coro, **kwargs)
472-
task.set_name(name)
473-
474-
else:
475-
task = tasks.Task(coro, loop=self, name=name, context=context, **kwargs)
476-
if task._source_traceback:
477-
del task._source_traceback[-1]
468+
return self._task_factory(self, coro, **kwargs)
478469

470+
task = tasks.Task(coro, loop=self, **kwargs)
471+
if task._source_traceback:
472+
del task._source_traceback[-1]
479473
try:
480474
return task
481475
finally:
@@ -841,7 +835,7 @@ def call_soon(self, callback, *args, context=None):
841835

842836
def _check_callback(self, callback, method):
843837
if (coroutines.iscoroutine(callback) or
844-
coroutines.iscoroutinefunction(callback)):
838+
coroutines._iscoroutinefunction(callback)):
845839
raise TypeError(
846840
f"coroutines cannot be used with {method}()")
847841
if not callable(callback):
@@ -878,7 +872,10 @@ def call_soon_threadsafe(self, callback, *args, context=None):
878872
self._check_closed()
879873
if self._debug:
880874
self._check_callback(callback, 'call_soon_threadsafe')
881-
handle = self._call_soon(callback, args, context)
875+
handle = events._ThreadSafeHandle(callback, args, self, context)
876+
self._ready.append(handle)
877+
if handle._source_traceback:
878+
del handle._source_traceback[-1]
882879
if handle._source_traceback:
883880
del handle._source_traceback[-1]
884881
self._write_to_self()
@@ -1677,8 +1674,7 @@ async def connect_accepted_socket(
16771674
raise ValueError(
16781675
'ssl_shutdown_timeout is only meaningful with ssl')
16791676

1680-
if sock is not None:
1681-
_check_ssl_socket(sock)
1677+
_check_ssl_socket(sock)
16821678

16831679
transport, protocol = await self._create_connection_transport(
16841680
sock, protocol_factory, ssl, '', server_side=True,

Lib/asyncio/coroutines.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,16 @@ def _is_debug_mode():
1818

1919

2020
def iscoroutinefunction(func):
21+
import warnings
2122
"""Return True if func is a decorated coroutine function."""
23+
warnings._deprecated("asyncio.iscoroutinefunction",
24+
f"{warnings._DEPRECATED_MSG}; "
25+
"use inspect.iscoroutinefunction() instead",
26+
remove=(3,16))
27+
return _iscoroutinefunction(func)
28+
29+
30+
def _iscoroutinefunction(func):
2231
return (inspect.iscoroutinefunction(func) or
2332
getattr(func, '_is_coroutine', None) is _is_coroutine)
2433

0 commit comments

Comments
 (0)