Skip to content

Commit 3166281

Browse files
authored
Merge branch 'python:main' into patch-4
2 parents fab014e + ee72c95 commit 3166281

6 files changed

Lines changed: 109 additions & 32 deletions

File tree

.github/CODEOWNERS

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,23 @@
44
# It uses the same pattern rule for gitignore file
55
# https://git-scm.com/docs/gitignore#_pattern_format
66

7-
# GitHub
7+
# Azure Pipelines
8+
.azure-pipelines/ @AA-Turner
9+
10+
# GitHub & related scripts
811
.github/** @ezio-melotti @hugovk @AA-Turner
12+
Tools/build/compute-changes.py @AA-Turner
13+
Tools/build/verify_ensurepip_wheels.py @AA-Turner
914

1015
# pre-commit
1116
.pre-commit-config.yaml @hugovk
1217
.ruff.toml @hugovk @AlexWaygood @AA-Turner
1318

14-
# Build system
15-
configure* @erlend-aasland @corona10
16-
Makefile.pre.in @erlend-aasland
17-
Modules/Setup* @erlend-aasland
19+
# Build system (autotools)
20+
configure* @erlend-aasland @corona10 @AA-Turner
21+
Makefile.pre.in @erlend-aasland @AA-Turner
22+
Modules/Setup* @erlend-aasland @AA-Turner
23+
Tools/build/regen-configure.sh @AA-Turner
1824

1925
# argparse
2026
**/*argparse* @savannahostrowski
@@ -67,6 +73,7 @@ Doc/make.bat @AA-Turner @hugovk
6773
Doc/requirements.txt @AA-Turner @hugovk
6874
Doc/_static/** @AA-Turner @hugovk
6975
Doc/tools/** @AA-Turner @hugovk
76+
.readthedocs.yml @AA-Turner
7077

7178
# runtime state/lifecycle
7279
**/*pylifecycle* @ericsnowcurrently @ZeroIntensity
@@ -155,6 +162,10 @@ Doc/c-api/module.rst @ericsnowcurrently
155162
**/*importlib/resources/* @jaraco @warsaw @FFY00
156163
**/*importlib/metadata/* @jaraco @warsaw
157164

165+
# Calendar
166+
Lib/calendar.py @AA-Turner
167+
Lib/test/test_calendar.py @AA-Turner
168+
158169
# Dates and times
159170
**/*datetime* @pganssle @abalkin
160171
**/*str*time* @pganssle @abalkin
@@ -205,6 +216,11 @@ Lib/test/test_ast/ @eclips4 @tomasr8
205216
# multiprocessing
206217
**/*multiprocessing* @gpshead
207218

219+
# pydoc
220+
Lib/pydoc.py @AA-Turner
221+
Lib/pydoc_data/ @AA-Turner
222+
Lib/test/test_pydoc/ @AA-Turner
223+
208224
# SQLite 3
209225
**/*sqlite* @berkerpeksag @erlend-aasland
210226

@@ -217,6 +233,11 @@ Lib/test/test_ast/ @eclips4 @tomasr8
217233
**/*pdb* @gaogaotiantian
218234
**/*bdb* @gaogaotiantian
219235

236+
# types
237+
Lib/test/test_types.py @AA-Turner
238+
Lib/types.py @AA-Turner
239+
Modules/_typesmodule.c @AA-Turner
240+
220241
# Limited C API & stable ABI
221242
Tools/build/stable_abi.py @encukou
222243
Misc/stable_abi.toml @encukou
@@ -234,6 +255,11 @@ Doc/c-api/stable.rst @encukou
234255
/Tools/msi/ @python/windows-team
235256
/Tools/nuget/ @python/windows-team
236257

258+
# Zstandard
259+
Lib/compression/zstd/ @AA-Turner
260+
Lib/test/test_zstd.py @AA-Turner
261+
Modules/_zstd/ @AA-Turner
262+
237263
# Misc
238264
**/*itertools* @rhettinger
239265
**/*collections* @rhettinger
@@ -266,6 +292,9 @@ Doc/c-api/stable.rst @encukou
266292

267293
**/*cjkcodecs* @corona10
268294

295+
# Patchcheck
296+
Tools/patchcheck/ @AA-Turner
297+
269298
# macOS
270299
/Mac/ @python/macos-team
271300
**/*osx_support* @python/macos-team
@@ -277,9 +306,9 @@ Doc/c-api/stable.rst @encukou
277306
**/*zipfile/_path/* @jaraco
278307

279308
# Argument Clinic
280-
/Tools/clinic/** @erlend-aasland
281-
/Lib/test/test_clinic.py @erlend-aasland
282-
Doc/howto/clinic.rst @erlend-aasland
309+
/Tools/clinic/** @erlend-aasland @AA-Turner
310+
/Lib/test/test_clinic.py @erlend-aasland @AA-Turner
311+
Doc/howto/clinic.rst @erlend-aasland @AA-Turner
283312

284313
# Subinterpreters
285314
**/*interpreteridobject.* @ericsnowcurrently
@@ -323,6 +352,7 @@ Lib/test/test_configparser.py @jaraco
323352

324353
# Doc sections
325354
Doc/reference/ @willingc @AA-Turner
355+
Doc/whatsnew/ @AA-Turner
326356

327357
**/*weakref* @kumaraditya303
328358

@@ -336,7 +366,7 @@ Modules/_xxtestfuzz/ @ammaraskar
336366
# t-strings
337367
**/*interpolationobject* @lysnikolaou
338368
**/*templateobject* @lysnikolaou
339-
**/*templatelib* @lysnikolaou
369+
**/*templatelib* @lysnikolaou @AA-Turner
340370
**/*tstring* @lysnikolaou
341371

342372
# Remote debugging
@@ -346,3 +376,6 @@ Modules/_remote_debugging_module.c @pablogsal @ambv @1st1
346376

347377
# gettext
348378
**/*gettext* @tomasr8
379+
380+
# Internal Docs
381+
InternalDocs/ @AA-Turner

Lib/asyncio/__main__.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import argparse
22
import ast
33
import asyncio
4-
import asyncio.tools
54
import concurrent.futures
65
import contextvars
76
import inspect
@@ -11,6 +10,9 @@
1110
import threading
1211
import types
1312
import warnings
13+
from asyncio.tools import (TaskTableOutputFormat,
14+
display_awaited_by_tasks_table,
15+
display_awaited_by_tasks_tree)
1416

1517
from _colorize import get_theme
1618
from _pyrepl.console import InteractiveColoredConsole
@@ -153,17 +155,22 @@ def interrupt(self) -> None:
153155
"ps", help="Display a table of all pending tasks in a process"
154156
)
155157
ps.add_argument("pid", type=int, help="Process ID to inspect")
158+
formats = [fmt.value for fmt in TaskTableOutputFormat]
159+
formats_to_show = [fmt for fmt in formats
160+
if fmt != TaskTableOutputFormat.bsv.value]
161+
ps.add_argument("--format", choices=formats, default="table",
162+
metavar=f"{{{','.join(formats_to_show)}}}")
156163
pstree = subparsers.add_parser(
157164
"pstree", help="Display a tree of all pending tasks in a process"
158165
)
159166
pstree.add_argument("pid", type=int, help="Process ID to inspect")
160167
args = parser.parse_args()
161168
match args.command:
162169
case "ps":
163-
asyncio.tools.display_awaited_by_tasks_table(args.pid)
170+
display_awaited_by_tasks_table(args.pid, format=args.format)
164171
sys.exit(0)
165172
case "pstree":
166-
asyncio.tools.display_awaited_by_tasks_tree(args.pid)
173+
display_awaited_by_tasks_tree(args.pid)
167174
sys.exit(0)
168175
case None:
169176
pass # continue to the interactive shell

Lib/asyncio/tools.py

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"""Tools to analyze tasks running in asyncio programs."""
22

3-
from collections import defaultdict, namedtuple
3+
from collections import defaultdict
4+
import csv
45
from itertools import count
5-
from enum import Enum
6+
from enum import Enum, StrEnum, auto
67
import sys
78
from _remote_debugging import RemoteUnwinder, FrameInfo
89

@@ -232,18 +233,56 @@ def _get_awaited_by_tasks(pid: int) -> list:
232233
sys.exit(1)
233234

234235

235-
def display_awaited_by_tasks_table(pid: int) -> None:
236+
class TaskTableOutputFormat(StrEnum):
237+
table = auto()
238+
csv = auto()
239+
bsv = auto()
240+
# 🍌SV is not just a format. It's a lifestyle. A philosophy.
241+
# https://www.youtube.com/watch?v=RrsVi1P6n0w
242+
243+
244+
def display_awaited_by_tasks_table(pid, *, format=TaskTableOutputFormat.table):
236245
"""Build and print a table of all pending tasks under `pid`."""
237246

238247
tasks = _get_awaited_by_tasks(pid)
239248
table = build_task_table(tasks)
240-
# Print the table in a simple tabular format
241-
print(
242-
f"{'tid':<10} {'task id':<20} {'task name':<20} {'coroutine stack':<50} {'awaiter chain':<50} {'awaiter name':<15} {'awaiter id':<15}"
243-
)
244-
print("-" * 180)
249+
format = TaskTableOutputFormat(format)
250+
if format == TaskTableOutputFormat.table:
251+
_display_awaited_by_tasks_table(table)
252+
else:
253+
_display_awaited_by_tasks_csv(table, format=format)
254+
255+
256+
_row_header = ('tid', 'task id', 'task name', 'coroutine stack',
257+
'awaiter chain', 'awaiter name', 'awaiter id')
258+
259+
260+
def _display_awaited_by_tasks_table(table):
261+
"""Print the table in a simple tabular format."""
262+
print(_fmt_table_row(*_row_header))
263+
print('-' * 180)
245264
for row in table:
246-
print(f"{row[0]:<10} {row[1]:<20} {row[2]:<20} {row[3]:<50} {row[4]:<50} {row[5]:<15} {row[6]:<15}")
265+
print(_fmt_table_row(*row))
266+
267+
268+
def _fmt_table_row(tid, task_id, task_name, coro_stack,
269+
awaiter_chain, awaiter_name, awaiter_id):
270+
# Format a single row for the table format
271+
return (f'{tid:<10} {task_id:<20} {task_name:<20} {coro_stack:<50} '
272+
f'{awaiter_chain:<50} {awaiter_name:<15} {awaiter_id:<15}')
273+
274+
275+
def _display_awaited_by_tasks_csv(table, *, format):
276+
"""Print the table in CSV format"""
277+
if format == TaskTableOutputFormat.csv:
278+
delimiter = ','
279+
elif format == TaskTableOutputFormat.bsv:
280+
delimiter = '\N{BANANA}'
281+
else:
282+
raise ValueError(f"Unknown output format: {format}")
283+
csv_writer = csv.writer(sys.stdout, delimiter=delimiter)
284+
csv_writer.writerow(_row_header)
285+
csv_writer.writerows(table)
247286

248287

249288
def display_awaited_by_tasks_tree(pid: int) -> None:
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add CSV as an output format for :program:`python -m asyncio ps`.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Have ``Tools/wasm/wasi`` put the build Python into a directory named after
2+
the build triple instead of "build".

Tools/wasm/wasi/__main__.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
assert (CHECKOUT / "configure").is_file(), "Please update the location of the file"
2121

2222
CROSS_BUILD_DIR = CHECKOUT / "cross-build"
23-
BUILD_DIR = CROSS_BUILD_DIR / "build"
23+
# Build platform can also be found via `config.guess`.
24+
BUILD_DIR = CROSS_BUILD_DIR / sysconfig.get_config_var("BUILD_GNU_TYPE")
2425

2526
LOCAL_SETUP = CHECKOUT / "Modules" / "Setup.local"
2627
LOCAL_SETUP_MARKER = ("# Generated by Tools/wasm/wasi .\n"
@@ -80,7 +81,7 @@ def wrapper(context):
8081
print("📁", working_dir)
8182
if (clean_ok and getattr(context, "clean", False) and
8283
working_dir.exists()):
83-
print(f"🚮 Deleting directory (--clean)...")
84+
print("🚮 Deleting directory (--clean)...")
8485
shutil.rmtree(working_dir)
8586

8687
working_dir.mkdir(parents=True, exist_ok=True)
@@ -120,12 +121,6 @@ def call(command, *, context=None, quiet=False, logdir=None, **kwargs):
120121
subprocess.check_call(command, **kwargs, stdout=stdout, stderr=stderr)
121122

122123

123-
def build_platform():
124-
"""The name of the build/host platform."""
125-
# Can also be found via `config.guess`.
126-
return sysconfig.get_config_var("BUILD_GNU_TYPE")
127-
128-
129124
def build_python_path():
130125
"""The path to the build Python binary."""
131126
binary = BUILD_DIR / "python"
@@ -274,7 +269,7 @@ def configure_wasi_python(context, working_dir):
274269
# executed from within a checkout.
275270
configure = [os.path.relpath(CHECKOUT / 'configure', working_dir),
276271
f"--host={context.host_triple}",
277-
f"--build={build_platform()}",
272+
f"--build={BUILD_DIR.name}",
278273
f"--with-build-python={build_python}"]
279274
if build_python_is_pydebug():
280275
configure.append("--with-pydebug")
@@ -357,8 +352,8 @@ def main():
357352
"Python)")
358353
make_host = subcommands.add_parser("make-host",
359354
help="Run `make` for the host/WASI")
360-
clean = subcommands.add_parser("clean", help="Delete files and directories "
361-
"created by this script")
355+
subcommands.add_parser("clean", help="Delete files and directories "
356+
"created by this script")
362357
for subcommand in build, configure_build, make_build, configure_host, make_host:
363358
subcommand.add_argument("--quiet", action="store_true", default=False,
364359
dest="quiet",

0 commit comments

Comments
 (0)