{% endblock %}
From b79112fb349ccc0b807610dd31a50712a8bbf6d8 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Fri, 22 May 2026 16:44:08 +0200
Subject: [PATCH 112/213] [3.15] CI: Move Homebrew dependencies into Brewfile
(GH-148335) (#149882)
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Co-authored-by: Brett Cannon
---
.github/workflows/reusable-macos.yml | 5 ++---
Misc/Brewfile | 14 ++++++++++++++
2 files changed, 16 insertions(+), 3 deletions(-)
create mode 100644 Misc/Brewfile
diff --git a/.github/workflows/reusable-macos.yml b/.github/workflows/reusable-macos.yml
index f10503055b2259..93b419159fa817 100644
--- a/.github/workflows/reusable-macos.yml
+++ b/.github/workflows/reusable-macos.yml
@@ -38,9 +38,8 @@ jobs:
run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
- name: Install Homebrew dependencies
run: |
- brew install pkg-config openssl@3.5 xz gdbm tcl-tk@9 make
- # Because alternate versions are not symlinked into place by default:
- brew link --overwrite tcl-tk@9
+ brew bundle --file=Misc/Brewfile
+ brew install make
- name: Configure CPython
run: |
MACOSX_DEPLOYMENT_TARGET=10.15 \
diff --git a/Misc/Brewfile b/Misc/Brewfile
new file mode 100644
index 00000000000000..c799f099957f75
--- /dev/null
+++ b/Misc/Brewfile
@@ -0,0 +1,14 @@
+brew "gdbm"
+brew "mpdecimal"
+brew "openssl@3.5"
+brew "pkg-config"
+brew "tcl-tk@9"
+brew "xz"
+brew "zstd"
+
+brew "bzip2" if OS.linux?
+brew "libedit" if OS.linux?
+brew "libffi" if OS.linux?
+brew "ncurses" if OS.linux?
+brew "unzip" if OS.linux?
+brew "zlib-ng-compat" if OS.linux?
From f5231469b5516015de93553977303610ceb405cd Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Fri, 22 May 2026 16:44:34 +0200
Subject: [PATCH 113/213] [3.15] gh-148829: Make sentinels' repr and module
customizable (GH-149654) (#150092)
Implementation of python/peps#4968.
(cherry picked from commit 08218030a507b2ef38db9696216bf3eb24d9a6a1)
Co-authored-by: Jelle Zijlstra
---
Doc/c-api/sentinel.rst | 4 +-
Doc/data/python3.15.abi | 2171 +++++++++--------
Doc/data/refcounts.dat | 1 +
Doc/library/functions.rst | 12 +-
Include/cpython/sentinelobject.h | 3 +-
.../pycore_global_objects_fini_generated.h | 1 +
Include/internal/pycore_global_strings.h | 1 +
.../internal/pycore_runtime_init_generated.h | 1 +
.../internal/pycore_unicodeobject_generated.h | 4 +
Lib/test/test_builtin.py | 23 +-
Lib/test/test_capi/test_object.py | 6 +
...-05-10-16-43-50.gh-issue-148829.gscS14.rst | 2 +
Modules/_testcapi/object.c | 5 +-
Objects/clinic/sentinelobject.c.h | 62 +-
Objects/sentinelobject.c | 42 +-
15 files changed, 1228 insertions(+), 1110 deletions(-)
create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-10-16-43-50.gh-issue-148829.gscS14.rst
diff --git a/Doc/c-api/sentinel.rst b/Doc/c-api/sentinel.rst
index 937cae18e86f50..b1b7329a5d42c5 100644
--- a/Doc/c-api/sentinel.rst
+++ b/Doc/c-api/sentinel.rst
@@ -31,12 +31,12 @@ Sentinel objects
.. versionadded:: 3.15
-.. c:function:: PyObject* PySentinel_New(const char *name, const char *module_name)
+.. c:function:: PyObject* PySentinel_New(const char *name, const char *module_name, const char *repr)
Return a new :class:`sentinel` object with :attr:`~sentinel.__name__` set to
*name* and :attr:`~sentinel.__module__` set to *module_name*.
*name* must not be ``NULL``. If *module_name* is ``NULL``, :attr:`~sentinel.__module__`
- is set to ``None``.
+ is set to ``None``. If *repr* is ``NULL``, ``repr()`` returns :attr:`~sentinel.__name__`.
Return ``NULL`` with an exception set on failure.
For pickling to work, *module_name* must be the name of an importable
diff --git a/Doc/data/python3.15.abi b/Doc/data/python3.15.abi
index 04211b6e4e274a..aea9ff48a62763 100644
--- a/Doc/data/python3.15.abi
+++ b/Doc/data/python3.15.abi
@@ -1996,7 +1996,7 @@
-
+
@@ -2020,13 +2020,13 @@
-
+
-
+
@@ -2983,7 +2983,7 @@
-
+
@@ -5844,6 +5844,11 @@
+
+
+
+
+
@@ -5893,115 +5898,115 @@
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
@@ -7569,295 +7574,295 @@
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
@@ -9154,11 +9159,6 @@
-
-
-
-
-
@@ -11398,9 +11398,10 @@
-
-
-
+
+
+
+
@@ -11811,7 +11812,7 @@
-
+
@@ -11917,135 +11918,135 @@
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
@@ -12456,7 +12457,7 @@
-
+
@@ -15603,10 +15604,10 @@
-
+
-
+
@@ -18594,7 +18595,7 @@
-
+
@@ -19086,8 +19087,14 @@
+
+
+
+
+
+
-
+
@@ -19308,18 +19315,18 @@
-
+
-
+
-
-
+
+
-
-
+
+
@@ -19503,7 +19510,7 @@
-
+
@@ -21593,427 +21600,430 @@
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
+
+
+
@@ -22136,20 +22146,20 @@
-
+
-
+
-
+
-
+
-
+
-
+
@@ -22556,7 +22566,7 @@
-
+
@@ -22591,306 +22601,309 @@
-
+
-
+
-
-
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -22902,405 +22915,405 @@
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
-
+
+
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
+
+
-
+
+
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -23721,12 +23734,12 @@
-
+
-
+
@@ -23739,19 +23752,19 @@
-
+
-
+
-
+
-
+
-
+
@@ -23763,7 +23776,7 @@
-
+
@@ -23887,7 +23900,7 @@
-
+
@@ -27444,108 +27457,108 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
@@ -30145,128 +30158,128 @@
-
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
+
-
-
+
+
-
+
@@ -32221,7 +32234,7 @@
-
+
@@ -32481,147 +32494,147 @@
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
@@ -33164,7 +33177,7 @@
-
+
@@ -33192,13 +33205,13 @@
-
+
-
+
diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat
index 663b79e45eec17..60c02aabeb89c5 100644
--- a/Doc/data/refcounts.dat
+++ b/Doc/data/refcounts.dat
@@ -2040,6 +2040,7 @@ PySeqIter_New:PyObject*:seq:0:
PySentinel_New:PyObject*::+1:
PySentinel_New:const char*:name::
PySentinel_New:const char*:module_name::
+PySentinel_New:const char*:repr::
PySequence_Check:int:::
PySequence_Check:PyObject*:o:0:
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 1fed142d81b4f7..0393e2dc776db4 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -1827,15 +1827,21 @@ are always available. They are listed here in alphabetical order.
:func:`setattr`.
-.. class:: sentinel(name, /)
+.. class:: sentinel(name, /, *, repr=None)
Return a new unique sentinel object. *name* must be a :class:`str`, and is
- used as the returned object's representation::
+ used by default as the returned object's representation::
>>> MISSING = sentinel("MISSING")
>>> MISSING
MISSING
+ The optional *repr* argument can be used to specify a different representation::
+
+ >>> MISSING = sentinel("MISSING", repr="")
+ >>> MISSING
+
+
Sentinel objects are truthy and compare equal only to themselves. They are
intended to be compared with the :keyword:`is` operator.
@@ -1879,7 +1885,7 @@ are always available. They are listed here in alphabetical order.
.. attribute:: __module__
- The name of the module where the sentinel was created.
+ The name of the module where the sentinel was created. This attribute is writable.
.. versionadded:: 3.15
diff --git a/Include/cpython/sentinelobject.h b/Include/cpython/sentinelobject.h
index 15643ef966af86..e621d6abbfed8a 100644
--- a/Include/cpython/sentinelobject.h
+++ b/Include/cpython/sentinelobject.h
@@ -16,7 +16,8 @@ PyAPI_DATA(PyTypeObject) PySentinel_Type;
PyAPI_FUNC(PyObject *) PySentinel_New(
const char *name,
- const char *module_name);
+ const char *module_name,
+ const char *repr);
#ifdef __cplusplus
}
diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h
index f7d3dcd440aaf1..f8bab372f1e505 100644
--- a/Include/internal/pycore_global_objects_fini_generated.h
+++ b/Include/internal/pycore_global_objects_fini_generated.h
@@ -2031,6 +2031,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(repeat));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(repl));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(replace));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(repr));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reqrefs));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(require_ready));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reserved));
diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h
index 22494b1798cc53..32dfb9677ecdfe 100644
--- a/Include/internal/pycore_global_strings.h
+++ b/Include/internal/pycore_global_strings.h
@@ -754,6 +754,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(repeat)
STRUCT_FOR_ID(repl)
STRUCT_FOR_ID(replace)
+ STRUCT_FOR_ID(repr)
STRUCT_FOR_ID(reqrefs)
STRUCT_FOR_ID(require_ready)
STRUCT_FOR_ID(reserved)
diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h
index 892c3cdd9623a2..b5ec50968db222 100644
--- a/Include/internal/pycore_runtime_init_generated.h
+++ b/Include/internal/pycore_runtime_init_generated.h
@@ -2029,6 +2029,7 @@ extern "C" {
INIT_ID(repeat), \
INIT_ID(repl), \
INIT_ID(replace), \
+ INIT_ID(repr), \
INIT_ID(reqrefs), \
INIT_ID(require_ready), \
INIT_ID(reserved), \
diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h
index f0fc3c4f5b0900..00915c23f4b75c 100644
--- a/Include/internal/pycore_unicodeobject_generated.h
+++ b/Include/internal/pycore_unicodeobject_generated.h
@@ -2796,6 +2796,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(repr);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(reqrefs);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 81967fb8a83740..d62a3a4f17f85e 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -1956,16 +1956,33 @@ def test_sentinel(self):
with self.assertRaises(TypeError):
class SubSentinel(sentinel):
pass
+
+ def test_sentinel_attributes(self):
+ missing = sentinel("MISSING")
with self.assertRaises(TypeError):
sentinel.attribute = "value"
with self.assertRaises(AttributeError):
- missing.__name__ = "CHANGED"
+ missing.attribute = "value"
with self.assertRaises(AttributeError):
- missing.__module__ = "changed"
+ missing.__name__ = "CHANGED"
+ missing.__module__ = "changed"
+ self.assertEqual(missing.__module__, "changed")
with self.assertRaises(AttributeError):
del missing.__name__
+ del missing.__module__
with self.assertRaises(AttributeError):
- del missing.__module__
+ missing.__module__
+
+ def test_sentinel_repr(self):
+ with_repr = sentinel("WITH_REPR", repr="custom")
+ without_repr = sentinel("WITHOUT_REPR", repr=None)
+ self.assertEqual(repr(with_repr), "custom")
+ self.assertEqual(repr(without_repr), "WITHOUT_REPR")
+ self.assertEqual(str(with_repr), "custom")
+ self.assertEqual(str(without_repr), "WITHOUT_REPR")
+
+ with self.assertRaisesRegex(TypeError, "repr.*str or None"):
+ sentinel("BAD_REPR", repr=42)
def test_sentinel_pickle(self):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
diff --git a/Lib/test/test_capi/test_object.py b/Lib/test/test_capi/test_object.py
index e6fd068dc20d8d..e5c50902a0118d 100644
--- a/Lib/test/test_capi/test_object.py
+++ b/Lib/test/test_capi/test_object.py
@@ -82,6 +82,12 @@ def test_pysentinel_new(self):
self.assertEqual(no_module.__name__, "NO_MODULE")
self.assertIs(no_module.__module__, None)
+ with_repr = _testcapi.pysentinel_new("WITH_REPR", __name__, "custom repr")
+ self.assertIs(type(with_repr), sentinel)
+ self.assertEqual(with_repr.__name__, "WITH_REPR")
+ self.assertEqual(with_repr.__module__, __name__)
+ self.assertEqual(repr(with_repr), "custom repr")
+
globals()["CAPI_SENTINEL"] = marker
self.addCleanup(globals().pop, "CAPI_SENTINEL", None)
self.assertIs(pickle.loads(pickle.dumps(marker)), marker)
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-10-16-43-50.gh-issue-148829.gscS14.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-10-16-43-50.gh-issue-148829.gscS14.rst
new file mode 100644
index 00000000000000..3f9b1ccb518787
--- /dev/null
+++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-10-16-43-50.gh-issue-148829.gscS14.rst
@@ -0,0 +1,2 @@
+:class:`sentinel` objects now support a ``repr=`` argument and their
+:attr:`~sentinel.__module__` attribute is writable.
diff --git a/Modules/_testcapi/object.c b/Modules/_testcapi/object.c
index c62dc1144df688..09a548fd2e2448 100644
--- a/Modules/_testcapi/object.c
+++ b/Modules/_testcapi/object.c
@@ -560,10 +560,11 @@ pysentinel_new(PyObject *self, PyObject *args)
{
const char *name;
const char *module_name = NULL;
- if (!PyArg_ParseTuple(args, "s|s", &name, &module_name)) {
+ const char *repr = NULL;
+ if (!PyArg_ParseTuple(args, "s|ss", &name, &module_name, &repr)) {
return NULL;
}
- return PySentinel_New(name, module_name);
+ return PySentinel_New(name, module_name, repr);
}
static PyObject *
diff --git a/Objects/clinic/sentinelobject.c.h b/Objects/clinic/sentinelobject.c.h
index 51fd35a5979e31..f8503194ae5c74 100644
--- a/Objects/clinic/sentinelobject.c.h
+++ b/Objects/clinic/sentinelobject.c.h
@@ -2,33 +2,71 @@
preserve
[clinic start generated code]*/
-#include "pycore_modsupport.h" // _PyArg_CheckPositional()
+#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+# include "pycore_gc.h" // PyGC_Head
+# include "pycore_runtime.h" // _Py_ID()
+#endif
+#include "pycore_modsupport.h" // _PyArg_UnpackKeywords()
static PyObject *
-sentinel_new_impl(PyTypeObject *type, PyObject *name);
+sentinel_new_impl(PyTypeObject *type, PyObject *name, PyObject *repr);
static PyObject *
sentinel_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
PyObject *return_value = NULL;
- PyTypeObject *base_tp = &PySentinel_Type;
+ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ #define NUM_KEYWORDS 1
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ Py_hash_t ob_hash;
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_hash = -1,
+ .ob_item = { &_Py_ID(repr), },
+ };
+ #undef NUM_KEYWORDS
+ #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ #else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ #endif // !Py_BUILD_CORE
+
+ static const char * const _keywords[] = {"", "repr", NULL};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "sentinel",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
+ PyObject *argsbuf[2];
+ PyObject * const *fastargs;
+ Py_ssize_t nargs = PyTuple_GET_SIZE(args);
+ Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1;
PyObject *name;
+ PyObject *repr = Py_None;
- if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
- !_PyArg_NoKeywords("sentinel", kwargs)) {
+ fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser,
+ /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+ if (!fastargs) {
goto exit;
}
- if (!_PyArg_CheckPositional("sentinel", PyTuple_GET_SIZE(args), 1, 1)) {
+ if (!PyUnicode_Check(fastargs[0])) {
+ _PyArg_BadArgument("sentinel", "argument 1", "str", fastargs[0]);
goto exit;
}
- if (!PyUnicode_Check(PyTuple_GET_ITEM(args, 0))) {
- _PyArg_BadArgument("sentinel", "argument 1", "str", PyTuple_GET_ITEM(args, 0));
- goto exit;
+ name = fastargs[0];
+ if (!noptargs) {
+ goto skip_optional_kwonly;
}
- name = PyTuple_GET_ITEM(args, 0);
- return_value = sentinel_new_impl(type, name);
+ repr = fastargs[1];
+skip_optional_kwonly:
+ return_value = sentinel_new_impl(type, name, repr);
exit:
return return_value;
}
-/*[clinic end generated code: output=7f28fc0bf0259cba input=a9049054013a1b77]*/
+/*[clinic end generated code: output=958842ece254c82f input=a9049054013a1b77]*/
diff --git a/Objects/sentinelobject.c b/Objects/sentinelobject.c
index e7e9f60e3edfbe..77bffbc397be58 100644
--- a/Objects/sentinelobject.c
+++ b/Objects/sentinelobject.c
@@ -14,6 +14,7 @@ typedef struct {
PyObject_HEAD
PyObject *name;
PyObject *module;
+ PyObject *repr;
} sentinelobject;
#define sentinelobject_CAST(op) \
@@ -46,7 +47,7 @@ caller(void)
}
static PyObject *
-sentinel_new_with_module(PyTypeObject *type, PyObject *name, PyObject *module)
+sentinel_new_with_module(PyTypeObject *type, PyObject *name, PyObject *module, PyObject *repr)
{
assert(PyUnicode_Check(name));
@@ -56,6 +57,7 @@ sentinel_new_with_module(PyTypeObject *type, PyObject *name, PyObject *module)
}
self->name = Py_NewRef(name);
self->module = Py_NewRef(module);
+ self->repr = Py_XNewRef(repr);
_PyObject_GC_TRACK(self);
return (PyObject *)self;
}
@@ -66,37 +68,56 @@ sentinel.__new__ as sentinel_new
name: object(subclass_of='&PyUnicode_Type')
/
+ *
+ repr: object = None
[clinic start generated code]*/
static PyObject *
-sentinel_new_impl(PyTypeObject *type, PyObject *name)
-/*[clinic end generated code: output=4af55c6048bed30d input=3ab75704f39c119c]*/
+sentinel_new_impl(PyTypeObject *type, PyObject *name, PyObject *repr)
+/*[clinic end generated code: output=1eb7fab52e57d8c8 input=28cab6c468997b35]*/
{
+ if (repr == Py_None) {
+ repr = NULL;
+ }
+ else if (!PyUnicode_Check(repr)) {
+ _PyArg_BadArgument("sentinel", "argument 'repr'", "str or None", repr);
+ return NULL;
+ }
PyObject *module = caller();
- PyObject *self = sentinel_new_with_module(type, name, module);
+ PyObject *self = sentinel_new_with_module(type, name, module, repr);
Py_DECREF(module);
return self;
}
PyObject *
-PySentinel_New(const char *name, const char *module_name)
+PySentinel_New(const char *name, const char *module_name, const char *repr)
{
PyObject *name_obj = PyUnicode_FromString(name);
if (name_obj == NULL) {
return NULL;
}
+ PyObject *repr_obj = NULL;
+ if (repr != NULL) {
+ repr_obj = PyUnicode_FromString(repr);
+ if (repr_obj == NULL) {
+ Py_DECREF(name_obj);
+ return NULL;
+ }
+ }
PyObject *module_obj = module_name == NULL
? Py_None
: PyUnicode_FromString(module_name);
if (module_obj == NULL) {
Py_DECREF(name_obj);
+ Py_XDECREF(repr_obj);
return NULL;
}
PyObject *sentinel = sentinel_new_with_module(
- &PySentinel_Type, name_obj, module_obj);
+ &PySentinel_Type, name_obj, module_obj, repr_obj);
Py_DECREF(module_obj);
Py_DECREF(name_obj);
+ Py_XDECREF(repr_obj);
return sentinel;
}
@@ -106,6 +127,7 @@ sentinel_clear(PyObject *op)
sentinelobject *self = sentinelobject_CAST(op);
Py_CLEAR(self->name);
Py_CLEAR(self->module);
+ Py_CLEAR(self->repr);
return 0;
}
@@ -123,6 +145,7 @@ sentinel_traverse(PyObject *op, visitproc visit, void *arg)
sentinelobject *self = sentinelobject_CAST(op);
Py_VISIT(self->name);
Py_VISIT(self->module);
+ Py_VISIT(self->repr);
return 0;
}
@@ -130,6 +153,9 @@ static PyObject *
sentinel_repr(PyObject *op)
{
sentinelobject *self = sentinelobject_CAST(op);
+ if (self->repr != NULL) {
+ return Py_NewRef(self->repr);
+ }
return Py_NewRef(self->name);
}
@@ -161,7 +187,7 @@ static PyMethodDef sentinel_methods[] = {
static PyMemberDef sentinel_members[] = {
{"__name__", Py_T_OBJECT_EX, offsetof(sentinelobject, name), Py_READONLY},
- {"__module__", Py_T_OBJECT_EX, offsetof(sentinelobject, module), Py_READONLY},
+ {"__module__", Py_T_OBJECT_EX, offsetof(sentinelobject, module), 0},
{NULL}
};
@@ -170,7 +196,7 @@ static PyNumberMethods sentinel_as_number = {
};
PyDoc_STRVAR(sentinel_doc,
-"sentinel(name, /)\n"
+"sentinel(name, /, *, repr=None)\n"
"--\n\n"
"Create a unique sentinel object with the given name.");
From 3daf1fad7ad926ef0ba7bbc5f468fa9501df8cde Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Fri, 22 May 2026 22:49:36 +0200
Subject: [PATCH 114/213] [3.15] gh-149189: Revert "Modern defaults for
`pprint` (GH-149190)" (GH-150249) (#150268)
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
---
Doc/library/difflib.rst | 22 +-
Doc/library/pprint.rst | 396 ++++++----
Doc/library/ssl.rst | 122 ++-
Doc/library/unittest.mock.rst | 10 +-
Doc/tutorial/stdlib2.rst | 21 +-
Doc/whatsnew/3.15.rst | 9 +-
Lib/difflib.py | 42 +-
Lib/pprint.py | 178 +++--
Lib/test/test_descrtut.py | 98 ++-
Lib/test/test_pickle.py | 6 +-
Lib/test/test_pprint.py | 693 ++++++++++--------
Lib/test/test_stable_abi_ctypes.py | 28 +-
.../test_unittest/testmock/testhelpers.py | 4 +-
...-05-18-17-17-20.gh-issue-149189.a8IooK.rst | 1 +
14 files changed, 868 insertions(+), 762 deletions(-)
create mode 100644 Misc/NEWS.d/next/Library/2026-05-18-17-17-20.gh-issue-149189.a8IooK.rst
diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst
index e5afa174413541..8b812c173b5953 100644
--- a/Doc/library/difflib.rst
+++ b/Doc/library/difflib.rst
@@ -728,18 +728,16 @@ Finally, we compare the two:
>>> from pprint import pprint
>>> pprint(result)
- [
- ' 1. Beautiful is better than ugly.\n',
- '- 2. Explicit is better than implicit.\n',
- '- 3. Simple is better than complex.\n',
- '+ 3. Simple is better than complex.\n',
- '? ++\n',
- '- 4. Complex is better than complicated.\n',
- '? ^ ---- ^\n',
- '+ 4. Complicated is better than complex.\n',
- '? ++++ ^ ^\n',
- '+ 5. Flat is better than nested.\n',
- ]
+ [' 1. Beautiful is better than ugly.\n',
+ '- 2. Explicit is better than implicit.\n',
+ '- 3. Simple is better than complex.\n',
+ '+ 3. Simple is better than complex.\n',
+ '? ++\n',
+ '- 4. Complex is better than complicated.\n',
+ '? ^ ---- ^\n',
+ '+ 4. Complicated is better than complex.\n',
+ '? ++++ ^ ^\n',
+ '+ 5. Flat is better than nested.\n']
As a single multi-line string it looks like this:
diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst
index d62ef1f4d1e6b1..4f043fbb3a46df 100644
--- a/Doc/library/pprint.rst
+++ b/Doc/library/pprint.rst
@@ -17,7 +17,7 @@ objects which are not representable as Python literals.
The formatted representation keeps objects on a single line if it can, and
breaks them onto multiple lines if they don't fit within the allowed width,
-adjustable by the *width* parameter defaulting to 88 characters.
+adjustable by the *width* parameter defaulting to 80 characters.
.. versionchanged:: 3.9
Added support for pretty-printing :class:`types.SimpleNamespace`.
@@ -30,8 +30,9 @@ adjustable by the *width* parameter defaulting to 88 characters.
Functions
---------
-.. function:: pp(object, stream=None, indent=4, width=88, depth=None, *, \
- compact=False, sort_dicts=False, underscore_numbers=False)
+.. function:: pp(object, stream=None, indent=1, width=80, depth=None, *, \
+ compact=False, expand=False, sort_dicts=False, \
+ underscore_numbers=False)
Prints the formatted representation of *object*, followed by a newline.
This function may be used in the interactive interpreter
@@ -66,11 +67,16 @@ Functions
:param bool compact:
Control the way long :term:`sequences ` are formatted.
If ``False`` (the default),
+ each item of a sequence will be formatted on a separate line,
+ otherwise as many items as will fit within the *width*
+ will be formatted on each output line.
+ Incompatible with *expand*.
+
+ :param bool expand:
+ If ``True``,
opening parentheses and brackets will be followed by a newline and the
following content will be indented by one level, similar to
- pretty-printed JSON.
- If ``True``, as many items as will fit within the *width*
- will be formatted on each output line.
+ pretty-printed JSON. Incompatible with *compact*.
:param bool sort_dicts:
If ``True``, dictionaries will be formatted with
@@ -85,25 +91,32 @@ Functions
>>> import pprint
>>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
>>> stuff.insert(0, stuff)
- >>> pprint.pp(stuff, width=100)
- [, 'spam', 'eggs', 'lumberjack', 'knights', 'ni']
+ >>> pprint.pp(stuff)
+ [,
+ 'spam',
+ 'eggs',
+ 'lumberjack',
+ 'knights',
+ 'ni']
.. versionadded:: 3.8
-.. function:: pprint(object, stream=None, indent=4, width=88, depth=None, *, \
- compact=False, sort_dicts=True, underscore_numbers=False)
+.. function:: pprint(object, stream=None, indent=1, width=80, depth=None, *, \
+ compact=False, expand=False, sort_dicts=True, \
+ underscore_numbers=False)
Alias for :func:`~pprint.pp` with *sort_dicts* set to ``True`` by default,
which would automatically sort the dictionaries' keys,
you might want to use :func:`~pprint.pp` instead where it is ``False`` by default.
-.. function:: pformat(object, indent=4, width=88, depth=None, *, \
- compact=False, sort_dicts=True, underscore_numbers=False)
+.. function:: pformat(object, indent=1, width=80, depth=None, *, \
+ compact=False, expand=False, sort_dicts=True, \
+ underscore_numbers=False)
Return the formatted representation of *object* as a string. *indent*,
- *width*, *depth*, *compact*, *sort_dicts* and *underscore_numbers* are
+ *width*, *depth*, *compact*, *expand*, *sort_dicts* and *underscore_numbers* are
passed to the :class:`PrettyPrinter` constructor as formatting parameters
and their meanings are as described in the documentation above.
@@ -141,13 +154,13 @@ Functions
.. _prettyprinter-objects:
-PrettyPrinter objects
+PrettyPrinter Objects
---------------------
.. index:: single: ...; placeholder
-.. class:: PrettyPrinter(indent=4, width=88, depth=None, stream=None, *, \
- compact=False, sort_dicts=True, \
+.. class:: PrettyPrinter(indent=1, width=80, depth=None, stream=None, *, \
+ compact=False, expand=False, sort_dicts=True, \
underscore_numbers=False)
Construct a :class:`PrettyPrinter` instance.
@@ -158,23 +171,21 @@ PrettyPrinter objects
>>> import pprint
>>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
>>> stuff.insert(0, stuff[:])
- >>> pp = pprint.PrettyPrinter()
+ >>> pp = pprint.PrettyPrinter(indent=4)
>>> pp.pprint(stuff)
- [
- ['spam', 'eggs', 'lumberjack', 'knights', 'ni'],
+ [ ['spam', 'eggs', 'lumberjack', 'knights', 'ni'],
'spam',
'eggs',
'lumberjack',
'knights',
- 'ni',
- ]
- >>> pp = pprint.PrettyPrinter(indent=1, width=41, compact=True)
+ 'ni']
+ >>> pp = pprint.PrettyPrinter(width=41, compact=True)
>>> pp.pprint(stuff)
[['spam', 'eggs', 'lumberjack',
'knights', 'ni'],
'spam', 'eggs', 'lumberjack', 'knights',
'ni']
- >>> pp = pprint.PrettyPrinter(width=41, indent=3)
+ >>> pp = pprint.PrettyPrinter(width=41, expand=True, indent=3)
>>> pp.pprint(stuff)
[
[
@@ -210,11 +221,7 @@ PrettyPrinter objects
No longer attempts to write to :data:`!sys.stdout` if it is ``None``.
.. versionchanged:: 3.15
- Changed default *indent* from 1 to 4
- and default *width* from 80 to 88.
- The default ``compact=False`` layout is now similar to
- pretty-printed JSON, with opening parentheses and brackets
- followed by a newline and the contents indented by one level.
+ Added the *expand* parameter.
:class:`PrettyPrinter` instances have the following methods:
@@ -291,144 +298,219 @@ let's fetch information about a project from `PyPI `_::
In its basic form, :func:`~pprint.pp` shows the whole object::
>>> pprint.pp(project_info)
- {
- 'author': 'The Python Packaging Authority',
- 'author_email': 'pypa-dev@googlegroups.com',
- 'bugtrack_url': None,
- 'classifiers': [
- 'Development Status :: 3 - Alpha',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: MIT License',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.6',
- 'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.2',
- 'Programming Language :: Python :: 3.3',
- 'Programming Language :: Python :: 3.4',
- 'Topic :: Software Development :: Build Tools',
- ],
- 'description': 'A sample Python project\n'
- '=======================\n'
- '\n'
- 'This is the description file for the project.\n'
- '\n'
- 'The file should use UTF-8 encoding and be written using ReStructured Text. It\n'
- 'will be used to generate the project webpage on PyPI, and should be written for\n'
- 'that purpose.\n'
- '\n'
- 'Typical contents for this file would include an overview of the project, basic\n'
- 'usage examples, etc. Generally, including the project changelog in here is not\n'
- 'a good idea, although a simple "What\'s New" section for the most recent version\n'
- 'may be appropriate.',
- 'description_content_type': None,
- 'docs_url': None,
- 'download_url': 'UNKNOWN',
- 'downloads': {'last_day': -1, 'last_month': -1, 'last_week': -1},
- 'home_page': 'https://github.com/pypa/sampleproject',
- 'keywords': 'sample setuptools development',
- 'license': 'MIT',
- 'maintainer': None,
- 'maintainer_email': None,
- 'name': 'sampleproject',
- 'package_url': 'https://pypi.org/project/sampleproject/',
- 'platform': 'UNKNOWN',
- 'project_url': 'https://pypi.org/project/sampleproject/',
- 'project_urls': {'Download': 'UNKNOWN', 'Homepage': 'https://github.com/pypa/sampleproject'},
- 'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
- 'requires_dist': None,
- 'requires_python': None,
- 'summary': 'A sample Python project',
- 'version': '1.2.0',
- }
+ {'author': 'The Python Packaging Authority',
+ 'author_email': 'pypa-dev@googlegroups.com',
+ 'bugtrack_url': None,
+ 'classifiers': ['Development Status :: 3 - Alpha',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: MIT License',
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 2.6',
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.2',
+ 'Programming Language :: Python :: 3.3',
+ 'Programming Language :: Python :: 3.4',
+ 'Topic :: Software Development :: Build Tools'],
+ 'description': 'A sample Python project\n'
+ '=======================\n'
+ '\n'
+ 'This is the description file for the project.\n'
+ '\n'
+ 'The file should use UTF-8 encoding and be written using '
+ 'ReStructured Text. It\n'
+ 'will be used to generate the project webpage on PyPI, and '
+ 'should be written for\n'
+ 'that purpose.\n'
+ '\n'
+ 'Typical contents for this file would include an overview of '
+ 'the project, basic\n'
+ 'usage examples, etc. Generally, including the project '
+ 'changelog in here is not\n'
+ 'a good idea, although a simple "What\'s New" section for the '
+ 'most recent version\n'
+ 'may be appropriate.',
+ 'description_content_type': None,
+ 'docs_url': None,
+ 'download_url': 'UNKNOWN',
+ 'downloads': {'last_day': -1, 'last_month': -1, 'last_week': -1},
+ 'home_page': 'https://github.com/pypa/sampleproject',
+ 'keywords': 'sample setuptools development',
+ 'license': 'MIT',
+ 'maintainer': None,
+ 'maintainer_email': None,
+ 'name': 'sampleproject',
+ 'package_url': 'https://pypi.org/project/sampleproject/',
+ 'platform': 'UNKNOWN',
+ 'project_url': 'https://pypi.org/project/sampleproject/',
+ 'project_urls': {'Download': 'UNKNOWN',
+ 'Homepage': 'https://github.com/pypa/sampleproject'},
+ 'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
+ 'requires_dist': None,
+ 'requires_python': None,
+ 'summary': 'A sample Python project',
+ 'version': '1.2.0'}
The result can be limited to a certain *depth* (ellipsis is used for deeper
contents)::
>>> pprint.pp(project_info, depth=1)
- {
- 'author': 'The Python Packaging Authority',
- 'author_email': 'pypa-dev@googlegroups.com',
- 'bugtrack_url': None,
- 'classifiers': [...],
- 'description': 'A sample Python project\n'
- '=======================\n'
- '\n'
- 'This is the description file for the project.\n'
- '\n'
- 'The file should use UTF-8 encoding and be written using ReStructured Text. It\n'
- 'will be used to generate the project webpage on PyPI, and should be written for\n'
- 'that purpose.\n'
- '\n'
- 'Typical contents for this file would include an overview of the project, basic\n'
- 'usage examples, etc. Generally, including the project changelog in here is not\n'
- 'a good idea, although a simple "What\'s New" section for the most recent version\n'
- 'may be appropriate.',
- 'description_content_type': None,
- 'docs_url': None,
- 'download_url': 'UNKNOWN',
- 'downloads': {...},
- 'home_page': 'https://github.com/pypa/sampleproject',
- 'keywords': 'sample setuptools development',
- 'license': 'MIT',
- 'maintainer': None,
- 'maintainer_email': None,
- 'name': 'sampleproject',
- 'package_url': 'https://pypi.org/project/sampleproject/',
- 'platform': 'UNKNOWN',
- 'project_url': 'https://pypi.org/project/sampleproject/',
- 'project_urls': {...},
- 'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
- 'requires_dist': None,
- 'requires_python': None,
- 'summary': 'A sample Python project',
- 'version': '1.2.0',
- }
+ {'author': 'The Python Packaging Authority',
+ 'author_email': 'pypa-dev@googlegroups.com',
+ 'bugtrack_url': None,
+ 'classifiers': [...],
+ 'description': 'A sample Python project\n'
+ '=======================\n'
+ '\n'
+ 'This is the description file for the project.\n'
+ '\n'
+ 'The file should use UTF-8 encoding and be written using '
+ 'ReStructured Text. It\n'
+ 'will be used to generate the project webpage on PyPI, and '
+ 'should be written for\n'
+ 'that purpose.\n'
+ '\n'
+ 'Typical contents for this file would include an overview of '
+ 'the project, basic\n'
+ 'usage examples, etc. Generally, including the project '
+ 'changelog in here is not\n'
+ 'a good idea, although a simple "What\'s New" section for the '
+ 'most recent version\n'
+ 'may be appropriate.',
+ 'description_content_type': None,
+ 'docs_url': None,
+ 'download_url': 'UNKNOWN',
+ 'downloads': {...},
+ 'home_page': 'https://github.com/pypa/sampleproject',
+ 'keywords': 'sample setuptools development',
+ 'license': 'MIT',
+ 'maintainer': None,
+ 'maintainer_email': None,
+ 'name': 'sampleproject',
+ 'package_url': 'https://pypi.org/project/sampleproject/',
+ 'platform': 'UNKNOWN',
+ 'project_url': 'https://pypi.org/project/sampleproject/',
+ 'project_urls': {...},
+ 'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
+ 'requires_dist': None,
+ 'requires_python': None,
+ 'summary': 'A sample Python project',
+ 'version': '1.2.0'}
Additionally, maximum character *width* can be suggested. If a long object
cannot be split, the specified width will be exceeded::
>>> pprint.pp(project_info, depth=1, width=60)
+ {'author': 'The Python Packaging Authority',
+ 'author_email': 'pypa-dev@googlegroups.com',
+ 'bugtrack_url': None,
+ 'classifiers': [...],
+ 'description': 'A sample Python project\n'
+ '=======================\n'
+ '\n'
+ 'This is the description file for the '
+ 'project.\n'
+ '\n'
+ 'The file should use UTF-8 encoding and be '
+ 'written using ReStructured Text. It\n'
+ 'will be used to generate the project '
+ 'webpage on PyPI, and should be written '
+ 'for\n'
+ 'that purpose.\n'
+ '\n'
+ 'Typical contents for this file would '
+ 'include an overview of the project, '
+ 'basic\n'
+ 'usage examples, etc. Generally, including '
+ 'the project changelog in here is not\n'
+ 'a good idea, although a simple "What\'s '
+ 'New" section for the most recent version\n'
+ 'may be appropriate.',
+ 'description_content_type': None,
+ 'docs_url': None,
+ 'download_url': 'UNKNOWN',
+ 'downloads': {...},
+ 'home_page': 'https://github.com/pypa/sampleproject',
+ 'keywords': 'sample setuptools development',
+ 'license': 'MIT',
+ 'maintainer': None,
+ 'maintainer_email': None,
+ 'name': 'sampleproject',
+ 'package_url': 'https://pypi.org/project/sampleproject/',
+ 'platform': 'UNKNOWN',
+ 'project_url': 'https://pypi.org/project/sampleproject/',
+ 'project_urls': {...},
+ 'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
+ 'requires_dist': None,
+ 'requires_python': None,
+ 'summary': 'A sample Python project',
+ 'version': '1.2.0'}
+
+Lastly, we can format like pretty-printed JSON with the *expand* parameter.
+Best results are achieved with a higher *indent* value::
+
+ >>> pprint.pp(project_info, indent=4, expand=True)
{
- 'author': 'The Python Packaging Authority',
- 'author_email': 'pypa-dev@googlegroups.com',
- 'bugtrack_url': None,
- 'classifiers': [...],
- 'description': 'A sample Python project\n'
- '=======================\n'
- '\n'
- 'This is the description file for the project.\n'
- '\n'
- 'The file should use UTF-8 encoding and be written '
- 'using ReStructured Text. It\n'
- 'will be used to generate the project webpage on PyPI, '
- 'and should be written for\n'
- 'that purpose.\n'
- '\n'
- 'Typical contents for this file would include an '
- 'overview of the project, basic\n'
- 'usage examples, etc. Generally, including the project '
- 'changelog in here is not\n'
- 'a good idea, although a simple "What\'s New" section '
- 'for the most recent version\n'
- 'may be appropriate.',
- 'description_content_type': None,
- 'docs_url': None,
- 'download_url': 'UNKNOWN',
- 'downloads': {...},
- 'home_page': 'https://github.com/pypa/sampleproject',
- 'keywords': 'sample setuptools development',
- 'license': 'MIT',
- 'maintainer': None,
- 'maintainer_email': None,
- 'name': 'sampleproject',
- 'package_url': 'https://pypi.org/project/sampleproject/',
- 'platform': 'UNKNOWN',
- 'project_url': 'https://pypi.org/project/sampleproject/',
- 'project_urls': {...},
- 'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
- 'requires_dist': None,
- 'requires_python': None,
- 'summary': 'A sample Python project',
- 'version': '1.2.0',
+ 'author': 'The Python Packaging Authority',
+ 'author_email': 'pypa-dev@googlegroups.com',
+ 'bugtrack_url': None,
+ 'classifiers': [
+ 'Development Status :: 3 - Alpha',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: MIT License',
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 2.6',
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.2',
+ 'Programming Language :: Python :: 3.3',
+ 'Programming Language :: Python :: 3.4',
+ 'Topic :: Software Development :: Build Tools',
+ ],
+ 'description': 'A sample Python project\n'
+ '=======================\n'
+ '\n'
+ 'This is the description file for the project.\n'
+ '\n'
+ 'The file should use UTF-8 encoding and be written using ReStructured '
+ 'Text. It\n'
+ 'will be used to generate the project webpage on PyPI, and should be '
+ 'written for\n'
+ 'that purpose.\n'
+ '\n'
+ 'Typical contents for this file would include an overview of the project, '
+ 'basic\n'
+ 'usage examples, etc. Generally, including the project changelog in here '
+ 'is not\n'
+ 'a good idea, although a simple "What\'s New" section for the most recent '
+ 'version\n'
+ 'may be appropriate.',
+ 'description_content_type': None,
+ 'docs_url': None,
+ 'download_url': 'UNKNOWN',
+ 'downloads': {'last_day': -1, 'last_month': -1, 'last_week': -1},
+ 'dynamic': None,
+ 'home_page': 'https://github.com/pypa/sampleproject',
+ 'keywords': 'sample setuptools development',
+ 'license': 'MIT',
+ 'license_expression': None,
+ 'license_files': None,
+ 'maintainer': None,
+ 'maintainer_email': None,
+ 'name': 'sampleproject',
+ 'package_url': 'https://pypi.org/project/sampleproject/',
+ 'platform': 'UNKNOWN',
+ 'project_url': 'https://pypi.org/project/sampleproject/',
+ 'project_urls': {
+ 'Download': 'UNKNOWN',
+ 'Homepage': 'https://github.com/pypa/sampleproject',
+ },
+ 'provides_extra': None,
+ 'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
+ 'requires_dist': None,
+ 'requires_python': None,
+ 'summary': 'A sample Python project',
+ 'version': '1.2.0',
+ 'yanked': False,
+ 'yanked_reason': None,
}
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
index b180673f22973e..c0f3757e583e95 100644
--- a/Doc/library/ssl.rst
+++ b/Doc/library/ssl.rst
@@ -2473,79 +2473,67 @@ Visual inspection shows that the certificate does identify the desired service
(that is, the HTTPS host ``www.python.org``)::
>>> pprint.pprint(cert)
- {
- 'OCSP': ('http://ocsp.digicert.com',),
- 'caIssuers': ('http://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt',),
- 'crlDistributionPoints': (
- 'http://crl3.digicert.com/sha2-ev-server-g1.crl',
- 'http://crl4.digicert.com/sha2-ev-server-g1.crl',
- ),
- 'issuer': (
- (('countryName', 'US'),),
- (('organizationName', 'DigiCert Inc'),),
- (('organizationalUnitName', 'www.digicert.com'),),
- (('commonName', 'DigiCert SHA2 Extended Validation Server CA'),),
- ),
- 'notAfter': 'Sep 9 12:00:00 2016 GMT',
- 'notBefore': 'Sep 5 00:00:00 2014 GMT',
- 'serialNumber': '01BB6F00122B177F36CAB49CEA8B6B26',
- 'subject': (
- (('businessCategory', 'Private Organization'),),
- (('1.3.6.1.4.1.311.60.2.1.3', 'US'),),
- (('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),),
- (('serialNumber', '3359300'),),
- (('streetAddress', '16 Allen Rd'),),
- (('postalCode', '03894-4801'),),
- (('countryName', 'US'),),
- (('stateOrProvinceName', 'NH'),),
- (('localityName', 'Wolfeboro'),),
- (('organizationName', 'Python Software Foundation'),),
- (('commonName', 'www.python.org'),),
- ),
- 'subjectAltName': (
- ('DNS', 'www.python.org'),
- ('DNS', 'python.org'),
- ('DNS', 'pypi.org'),
- ('DNS', 'docs.python.org'),
- ('DNS', 'testpypi.org'),
- ('DNS', 'bugs.python.org'),
- ('DNS', 'wiki.python.org'),
- ('DNS', 'hg.python.org'),
- ('DNS', 'mail.python.org'),
- ('DNS', 'packaging.python.org'),
- ('DNS', 'pythonhosted.org'),
- ('DNS', 'www.pythonhosted.org'),
- ('DNS', 'test.pythonhosted.org'),
- ('DNS', 'us.pycon.org'),
- ('DNS', 'id.python.org'),
- ),
- 'version': 3,
- }
+ {'OCSP': ('http://ocsp.digicert.com',),
+ 'caIssuers': ('http://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt',),
+ 'crlDistributionPoints': ('http://crl3.digicert.com/sha2-ev-server-g1.crl',
+ 'http://crl4.digicert.com/sha2-ev-server-g1.crl'),
+ 'issuer': ((('countryName', 'US'),),
+ (('organizationName', 'DigiCert Inc'),),
+ (('organizationalUnitName', 'www.digicert.com'),),
+ (('commonName', 'DigiCert SHA2 Extended Validation Server CA'),)),
+ 'notAfter': 'Sep 9 12:00:00 2016 GMT',
+ 'notBefore': 'Sep 5 00:00:00 2014 GMT',
+ 'serialNumber': '01BB6F00122B177F36CAB49CEA8B6B26',
+ 'subject': ((('businessCategory', 'Private Organization'),),
+ (('1.3.6.1.4.1.311.60.2.1.3', 'US'),),
+ (('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),),
+ (('serialNumber', '3359300'),),
+ (('streetAddress', '16 Allen Rd'),),
+ (('postalCode', '03894-4801'),),
+ (('countryName', 'US'),),
+ (('stateOrProvinceName', 'NH'),),
+ (('localityName', 'Wolfeboro'),),
+ (('organizationName', 'Python Software Foundation'),),
+ (('commonName', 'www.python.org'),)),
+ 'subjectAltName': (('DNS', 'www.python.org'),
+ ('DNS', 'python.org'),
+ ('DNS', 'pypi.org'),
+ ('DNS', 'docs.python.org'),
+ ('DNS', 'testpypi.org'),
+ ('DNS', 'bugs.python.org'),
+ ('DNS', 'wiki.python.org'),
+ ('DNS', 'hg.python.org'),
+ ('DNS', 'mail.python.org'),
+ ('DNS', 'packaging.python.org'),
+ ('DNS', 'pythonhosted.org'),
+ ('DNS', 'www.pythonhosted.org'),
+ ('DNS', 'test.pythonhosted.org'),
+ ('DNS', 'us.pycon.org'),
+ ('DNS', 'id.python.org')),
+ 'version': 3}
Now the SSL channel is established and the certificate verified, you can
proceed to talk with the server::
>>> conn.sendall(b"HEAD / HTTP/1.0\r\nHost: linuxfr.org\r\n\r\n")
>>> pprint.pprint(conn.recv(1024).split(b"\r\n"))
- [
- b'HTTP/1.1 200 OK',
- b'Date: Sat, 18 Oct 2014 18:27:20 GMT',
- b'Server: nginx',
- b'Content-Type: text/html; charset=utf-8',
- b'X-Frame-Options: SAMEORIGIN',
- b'Content-Length: 45679',
- b'Accept-Ranges: bytes',
- b'Via: 1.1 varnish',
- b'Age: 2188',
- b'X-Served-By: cache-lcy1134-LCY',
- b'X-Cache: HIT',
- b'X-Cache-Hits: 11',
- b'Vary: Cookie',
- b'Strict-Transport-Security: max-age=63072000; includeSubDomains',
- b'Connection: close',
- b'',
- b'',
- ]
+ [b'HTTP/1.1 200 OK',
+ b'Date: Sat, 18 Oct 2014 18:27:20 GMT',
+ b'Server: nginx',
+ b'Content-Type: text/html; charset=utf-8',
+ b'X-Frame-Options: SAMEORIGIN',
+ b'Content-Length: 45679',
+ b'Accept-Ranges: bytes',
+ b'Via: 1.1 varnish',
+ b'Age: 2188',
+ b'X-Served-By: cache-lcy1134-LCY',
+ b'X-Cache: HIT',
+ b'X-Cache-Hits: 11',
+ b'Vary: Cookie',
+ b'Strict-Transport-Security: max-age=63072000; includeSubDomains',
+ b'Connection: close',
+ b'',
+ b'']
See the discussion of :ref:`ssl-security` below.
diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst
index 5b9f9eec93aa28..2ff1015af7a86e 100644
--- a/Doc/library/unittest.mock.rst
+++ b/Doc/library/unittest.mock.rst
@@ -2347,12 +2347,10 @@ chained call:
>>> kall = call(1).method(arg='foo').other('bar')(2.0)
>>> kall.call_list()
- [
- call(1),
- call().method(arg='foo'),
- call().method().other('bar'),
- call().method().other()(2.0),
- ]
+ [call(1),
+ call().method(arg='foo'),
+ call().method().other('bar'),
+ call().method().other()(2.0)]
>>> m.mock_calls == kall.call_list()
True
diff --git a/Doc/tutorial/stdlib2.rst b/Doc/tutorial/stdlib2.rst
index 2c3ec71cd3de39..6c68ba01081379 100644
--- a/Doc/tutorial/stdlib2.rst
+++ b/Doc/tutorial/stdlib2.rst
@@ -30,22 +30,11 @@ and indentation to more clearly reveal data structure::
... 'yellow'], 'blue']]]
...
>>> pprint.pprint(t, width=30)
- [
- [
- [
- ['black', 'cyan'],
- 'white',
- ['green', 'red'],
- ],
- [
- [
- 'magenta',
- 'yellow',
- ],
- 'blue',
- ],
- ],
- ]
+ [[[['black', 'cyan'],
+ 'white',
+ ['green', 'red']],
+ [['magenta', 'yellow'],
+ 'blue']]]
The :mod:`textwrap` module formats paragraphs of text to fit a given screen
width::
diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst
index 1670f033401f2b..5ef4e36241af2c 100644
--- a/Doc/whatsnew/3.15.rst
+++ b/Doc/whatsnew/3.15.rst
@@ -1344,11 +1344,12 @@ pickletools
pprint
------
-* :mod:`pprint` now uses modern defaults: ``indent=4, width=88``,
- and the default ``compact=False`` output is now formatted similar to
- pretty-printed :func:`json.dumps`.
+* Add an *expand* keyword argument for :func:`pprint.pprint`,
+ :func:`pprint.pformat`, :func:`pprint.pp`. If true, the output will be
+ formatted similar to pretty-printed :func:`json.dumps` when
+ *indent* is supplied.
(Contributed by Stefan Todoran, Semyon Moroz and Hugo van Kemenade in
- :gh:`112632` and :gh:`149189`.)
+ :gh:`112632`.)
* Add t-string support to :mod:`pprint`.
(Contributed by Loïc Simon and Hugo van Kemenade in :gh:`134551`.)
diff --git a/Lib/difflib.py b/Lib/difflib.py
index 7a4ff15c34267b..ae8b284b4d3647 100644
--- a/Lib/difflib.py
+++ b/Lib/difflib.py
@@ -559,17 +559,15 @@ def get_grouped_opcodes(self, n=3):
>>> b[23:28] = [] # Make a deletion
>>> b[30] += 'y' # Make another replacement
>>> pprint(list(SequenceMatcher(None,a,b).get_grouped_opcodes()))
- [
- [('equal', 5, 8, 5, 8), ('insert', 8, 8, 8, 9), ('equal', 8, 11, 9, 12)],
- [
- ('equal', 16, 19, 17, 20),
- ('replace', 19, 20, 20, 21),
- ('equal', 20, 22, 21, 23),
- ('delete', 22, 27, 23, 23),
- ('equal', 27, 30, 23, 26),
- ],
- [('equal', 31, 34, 27, 30), ('replace', 34, 35, 30, 31), ('equal', 35, 38, 31, 34)],
- ]
+ [[('equal', 5, 8, 5, 8), ('insert', 8, 8, 8, 9), ('equal', 8, 11, 9, 12)],
+ [('equal', 16, 19, 17, 20),
+ ('replace', 19, 20, 20, 21),
+ ('equal', 20, 22, 21, 23),
+ ('delete', 22, 27, 23, 23),
+ ('equal', 27, 30, 23, 26)],
+ [('equal', 31, 34, 27, 30),
+ ('replace', 34, 35, 30, 31),
+ ('equal', 35, 38, 31, 34)]]
"""
codes = self.get_opcodes()
@@ -786,18 +784,16 @@ class Differ:
>>> from pprint import pprint as _pprint
>>> _pprint(result)
- [
- ' 1. Beautiful is better than ugly.\n',
- '- 2. Explicit is better than implicit.\n',
- '- 3. Simple is better than complex.\n',
- '+ 3. Simple is better than complex.\n',
- '? ++\n',
- '- 4. Complex is better than complicated.\n',
- '? ^ ---- ^\n',
- '+ 4. Complicated is better than complex.\n',
- '? ++++ ^ ^\n',
- '+ 5. Flat is better than nested.\n',
- ]
+ [' 1. Beautiful is better than ugly.\n',
+ '- 2. Explicit is better than implicit.\n',
+ '- 3. Simple is better than complex.\n',
+ '+ 3. Simple is better than complex.\n',
+ '? ++\n',
+ '- 4. Complex is better than complicated.\n',
+ '? ^ ---- ^\n',
+ '+ 4. Complicated is better than complex.\n',
+ '? ++++ ^ ^\n',
+ '+ 5. Flat is better than nested.\n']
As a single multi-line string it looks like this:
diff --git a/Lib/pprint.py b/Lib/pprint.py
index 1fd7e3ec95a073..7355021998081d 100644
--- a/Lib/pprint.py
+++ b/Lib/pprint.py
@@ -43,38 +43,23 @@
"PrettyPrinter", "pp"]
-def pprint(
- object,
- stream=None,
- indent=4,
- width=88,
- depth=None,
- *,
- compact=False,
- sort_dicts=True,
- underscore_numbers=False,
-):
+def pprint(object, stream=None, indent=1, width=80, depth=None, *,
+ compact=False, expand=False, sort_dicts=True,
+ underscore_numbers=False):
"""Pretty-print a Python object to a stream [default is sys.stdout]."""
printer = PrettyPrinter(
stream=stream, indent=indent, width=width, depth=depth,
- compact=compact, sort_dicts=sort_dicts,
+ compact=compact, expand=expand, sort_dicts=sort_dicts,
underscore_numbers=underscore_numbers)
printer.pprint(object)
-def pformat(
- object,
- indent=4,
- width=88,
- depth=None,
- *,
- compact=False,
- sort_dicts=True,
- underscore_numbers=False,
-):
+def pformat(object, indent=1, width=80, depth=None, *,
+ compact=False, expand=False, sort_dicts=True,
+ underscore_numbers=False):
"""Format a Python object into a pretty-printed representation."""
return PrettyPrinter(indent=indent, width=width, depth=depth,
- compact=compact, sort_dicts=sort_dicts,
+ compact=compact, expand=expand, sort_dicts=sort_dicts,
underscore_numbers=underscore_numbers).pformat(object)
@@ -127,17 +112,9 @@ def _safe_tuple(t):
class PrettyPrinter:
- def __init__(
- self,
- indent=4,
- width=88,
- depth=None,
- stream=None,
- *,
- compact=False,
- sort_dicts=True,
- underscore_numbers=False,
- ):
+ def __init__(self, indent=1, width=80, depth=None, stream=None, *,
+ compact=False, expand=False, sort_dicts=True,
+ underscore_numbers=False):
"""Handle pretty printing operations onto a stream using a set of
configured parameters.
@@ -156,6 +133,12 @@ def __init__(
compact
If true, several items will be combined in one line.
+ Incompatible with expand mode.
+
+ expand
+ If true, the output will be formatted similar to
+ pretty-printed json.dumps() when ``indent`` is supplied.
+ Incompatible with compact mode.
sort_dicts
If true, dict keys are sorted.
@@ -172,6 +155,8 @@ def __init__(
raise ValueError('depth must be > 0')
if not width:
raise ValueError('width must be != 0')
+ if compact and expand:
+ raise ValueError('compact and expand are incompatible')
self._depth = depth
self._indent_per_level = indent
self._width = width
@@ -180,6 +165,7 @@ def __init__(
else:
self._stream = _sys.stdout
self._compact = bool(compact)
+ self._expand = bool(expand)
self._sort_dicts = sort_dicts
self._underscore_numbers = underscore_numbers
@@ -232,36 +218,36 @@ def _format(self, object, stream, indent, allowance, context, level):
stream.write(rep)
def _format_block_start(self, start_str, indent):
- if self._compact:
- return start_str
- return f"{start_str}\n{' ' * indent}"
+ if self._expand:
+ return f"{start_str}\n{' ' * indent}"
+ return start_str
def _format_block_end(self, end_str, indent):
- if self._compact:
- return end_str
- return f"\n{' ' * indent}{end_str}"
+ if self._expand:
+ return f"\n{' ' * indent}{end_str}"
+ return end_str
def _child_indent(self, indent, prefix_len):
- if self._compact:
- return indent + prefix_len
- return indent
+ if self._expand:
+ return indent
+ return indent + prefix_len
def _write_indent_padding(self, write):
- if self._compact:
- if self._indent_per_level > 1:
- write((self._indent_per_level - 1) * " ")
- elif self._indent_per_level > 0:
- write(self._indent_per_level * " ")
+ if self._expand:
+ if self._indent_per_level > 0:
+ write(self._indent_per_level * " ")
+ elif self._indent_per_level > 1:
+ write((self._indent_per_level - 1) * " ")
def _pprint_dataclass(self, object, stream, indent, allowance, context, level):
# Lazy import to improve module import time
from dataclasses import fields as dataclass_fields
cls_name = object.__class__.__name__
- if self._compact:
- indent += len(cls_name) + 1
- else:
+ if self._expand:
indent += self._indent_per_level
+ else:
+ indent += len(cls_name) + 1
items = [(f.name, getattr(object, f.name)) for f in dataclass_fields(object) if f.repr]
stream.write(self._format_block_start(cls_name + '(', indent))
self._format_namespace_items(items, stream, indent, allowance, context, level)
@@ -384,7 +370,7 @@ def _pprint_list(self, object, stream, indent, allowance, context, level):
def _pprint_tuple(self, object, stream, indent, allowance, context, level):
stream.write(self._format_block_start('(', indent))
- if len(object) == 1 and self._compact:
+ if len(object) == 1 and not self._expand:
endchar = ',)'
else:
endchar = ')'
@@ -405,7 +391,7 @@ def _pprint_set(self, object, stream, indent, allowance, context, level):
else:
stream.write(self._format_block_start(typ.__name__ + '({', indent))
endchar = '})'
- if self._compact:
+ if not self._expand:
indent += len(typ.__name__) + 1
object = sorted(object, key=_safe_key)
self._format_items(object, stream, indent, allowance + len(endchar),
@@ -423,10 +409,10 @@ def _pprint_str(self, object, stream, indent, allowance, context, level):
chunks = []
lines = object.splitlines(True)
if level == 1:
- if self._compact:
- indent += 1
- else:
+ if self._expand:
indent += self._indent_per_level
+ else:
+ indent += 1
allowance += 1
max_width1 = max_width = self._width - indent
for i, line in enumerate(lines):
@@ -479,10 +465,10 @@ def _pprint_bytes(self, object, stream, indent, allowance, context, level):
return
parens = level == 1
if parens:
- if self._compact:
- indent += 1
- else:
+ if self._expand:
indent += self._indent_per_level
+ else:
+ indent += 1
allowance += 1
write(self._format_block_start('(', indent))
delim = ''
@@ -499,11 +485,11 @@ def _pprint_bytes(self, object, stream, indent, allowance, context, level):
def _pprint_bytearray(self, object, stream, indent, allowance, context, level):
write = stream.write
write(self._format_block_start('bytearray(', indent))
- if self._compact:
- recursive_indent = indent + 10
- else:
+ if self._expand:
write(' ' * self._indent_per_level)
recursive_indent = indent + self._indent_per_level
+ else:
+ recursive_indent = indent + 10
self._pprint_bytes(bytes(object), stream, recursive_indent,
allowance + 1, context, level + 1)
write(self._format_block_end(')', indent))
@@ -531,10 +517,10 @@ def _pprint_simplenamespace(self, object, stream, indent, allowance, context, le
cls_name = 'namespace'
else:
cls_name = object.__class__.__name__
- if self._compact:
- indent += len(cls_name) + 1
- else:
+ if self._expand:
indent += self._indent_per_level
+ else:
+ indent += len(cls_name) + 1
items = object.__dict__.items()
stream.write(self._format_block_start(cls_name + '(', indent))
self._format_namespace_items(items, stream, indent, allowance, context,
@@ -564,7 +550,7 @@ def _format_dict_items(self, items, stream, indent, allowance, context,
)
if not last:
write(delimnl)
- elif not self._compact:
+ elif self._expand:
write(',')
def _format_namespace_items(self, items, stream, indent, allowance, context, level):
@@ -590,7 +576,7 @@ def _format_namespace_items(self, items, stream, indent, allowance, context, lev
)
if not last:
write(delimnl)
- elif not self._compact:
+ elif self._expand:
write(',')
def _format_items(self, items, stream, indent, allowance, context, level):
@@ -632,7 +618,7 @@ def _format_items(self, items, stream, indent, allowance, context, level):
self._format(ent, stream, indent,
allowance if last else 1,
context, level)
- if last and not self._compact:
+ if last and self._expand:
write(',')
def _repr(self, object, context, level):
@@ -657,11 +643,11 @@ def _pprint_default_dict(self, object, stream, indent, allowance, context, level
return
rdf = self._repr(object.default_factory, context, level)
cls = object.__class__
- if self._compact:
+ if self._expand:
+ stream.write('%s(%s, ' % (cls.__name__, rdf))
+ else:
indent += len(cls.__name__) + 1
stream.write('%s(%s,\n%s' % (cls.__name__, rdf, ' ' * indent))
- else:
- stream.write('%s(%s, ' % (cls.__name__, rdf))
self._pprint_dict(object, stream, indent, allowance + 1, context,
level)
stream.write(')')
@@ -695,14 +681,14 @@ def _pprint_chain_map(self, object, stream, indent, allowance, context, level):
cls = object.__class__
stream.write(self._format_block_start(cls.__name__ + '(',
indent + self._indent_per_level))
- if self._compact:
- indent += len(cls.__name__) + 1
- else:
+ if self._expand:
indent += self._indent_per_level
+ else:
+ indent += len(cls.__name__) + 1
for i, m in enumerate(object.maps):
if i == len(object.maps) - 1:
self._format(m, stream, indent, allowance + 1, context, level)
- if not self._compact:
+ if self._expand:
stream.write(',')
stream.write(self._format_block_end(')', indent - self._indent_per_level))
else:
@@ -717,7 +703,7 @@ def _pprint_deque(self, object, stream, indent, allowance, context, level):
return
cls = object.__class__
stream.write(self._format_block_start(cls.__name__ + '([', indent))
- if self._compact:
+ if not self._expand:
indent += len(cls.__name__) + 1
if object.maxlen is None:
self._format_items(object, stream, indent, allowance + 2,
@@ -727,10 +713,10 @@ def _pprint_deque(self, object, stream, indent, allowance, context, level):
self._format_items(object, stream, indent, 2,
context, level)
rml = self._repr(object.maxlen, context, level)
- if self._compact:
- stream.write('],\n%smaxlen=%s)' % (' ' * indent, rml))
- else:
+ if self._expand:
stream.write('%s], maxlen=%s)' % ('\n' + ' ' * indent, rml))
+ else:
+ stream.write('],\n%smaxlen=%s)' % (' ' * indent, rml))
_dispatch[_collections.deque.__repr__] = _pprint_deque
@@ -751,10 +737,10 @@ def _pprint_user_string(self, object, stream, indent, allowance, context, level)
def _pprint_template(self, object, stream, indent, allowance, context, level):
cls_name = object.__class__.__name__
- if self._compact:
- indent += len(cls_name) + 1
- else:
+ if self._expand:
indent += self._indent_per_level
+ else:
+ indent += len(cls_name) + 1
items = (
("strings", object.strings),
@@ -770,20 +756,7 @@ def _pprint_template(self, object, stream, indent, allowance, context, level):
def _pprint_interpolation(self, object, stream, indent, allowance, context, level):
cls_name = object.__class__.__name__
- if self._compact:
- indent += len(cls_name)
- items = (
- object.value,
- object.expression,
- object.conversion,
- object.format_spec,
- )
- stream.write(cls_name + "(")
- self._format_items(
- items, stream, indent, allowance, context, level
- )
- stream.write(")")
- else:
+ if self._expand:
indent += self._indent_per_level
items = (
("value", object.value),
@@ -798,6 +771,19 @@ def _pprint_interpolation(self, object, stream, indent, allowance, context, leve
stream.write(
self._format_block_end(")", indent - self._indent_per_level)
)
+ else:
+ indent += len(cls_name)
+ items = (
+ object.value,
+ object.expression,
+ object.conversion,
+ object.format_spec,
+ )
+ stream.write(cls_name + "(")
+ self._format_items(
+ items, stream, indent, allowance, context, level
+ )
+ stream.write(")")
t = t"{0}"
_dispatch[type(t).__repr__] = _pprint_template
diff --git a/Lib/test/test_descrtut.py b/Lib/test/test_descrtut.py
index 425fb85e93558d..828440a993a975 100644
--- a/Lib/test/test_descrtut.py
+++ b/Lib/test/test_descrtut.py
@@ -168,56 +168,54 @@ def merge(self, other):
>>> import pprint
>>> pprint.pprint(dir(list)) # like list.__dict__.keys(), but sorted
- [
- '__add__',
- '__class__',
- '__class_getitem__',
- '__contains__',
- '__delattr__',
- '__delitem__',
- '__dir__',
- '__doc__',
- '__eq__',
- '__format__',
- '__ge__',
- '__getattribute__',
- '__getitem__',
- '__getstate__',
- '__gt__',
- '__hash__',
- '__iadd__',
- '__imul__',
- '__init__',
- '__init_subclass__',
- '__iter__',
- '__le__',
- '__len__',
- '__lt__',
- '__mul__',
- '__ne__',
- '__new__',
- '__reduce__',
- '__reduce_ex__',
- '__repr__',
- '__reversed__',
- '__rmul__',
- '__setattr__',
- '__setitem__',
- '__sizeof__',
- '__str__',
- '__subclasshook__',
- 'append',
- 'clear',
- 'copy',
- 'count',
- 'extend',
- 'index',
- 'insert',
- 'pop',
- 'remove',
- 'reverse',
- 'sort',
- ]
+ ['__add__',
+ '__class__',
+ '__class_getitem__',
+ '__contains__',
+ '__delattr__',
+ '__delitem__',
+ '__dir__',
+ '__doc__',
+ '__eq__',
+ '__format__',
+ '__ge__',
+ '__getattribute__',
+ '__getitem__',
+ '__getstate__',
+ '__gt__',
+ '__hash__',
+ '__iadd__',
+ '__imul__',
+ '__init__',
+ '__init_subclass__',
+ '__iter__',
+ '__le__',
+ '__len__',
+ '__lt__',
+ '__mul__',
+ '__ne__',
+ '__new__',
+ '__reduce__',
+ '__reduce_ex__',
+ '__repr__',
+ '__reversed__',
+ '__rmul__',
+ '__setattr__',
+ '__setitem__',
+ '__sizeof__',
+ '__str__',
+ '__subclasshook__',
+ 'append',
+ 'clear',
+ 'copy',
+ 'count',
+ 'extend',
+ 'index',
+ 'insert',
+ 'pop',
+ 'remove',
+ 'reverse',
+ 'sort']
The new introspection API gives more information than the old one: in
addition to the regular methods, it also shows the methods that are
diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py
index 55a3c654aa0a47..48375cf459ea0b 100644
--- a/Lib/test/test_pickle.py
+++ b/Lib/test/test_pickle.py
@@ -786,7 +786,11 @@ def test_invocation(self):
'b': ('character string', b'byte string'),
'c': 'string'
}
- expect = "{'a': [1, 2.0, (3+4j)], 'b': ('character string', b'byte string'), 'c': 'string'}"
+ expect = '''
+ {'a': [1, 2.0, (3+4j)],
+ 'b': ('character string', b'byte string'),
+ 'c': 'string'}
+ '''
self.set_pickle_data(data)
with self.subTest(data=data):
diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py
index f439782f53e6fb..041c2072b9e253 100644
--- a/Lib/test/test_pprint.py
+++ b/Lib/test/test_pprint.py
@@ -3,7 +3,6 @@
import collections
import contextlib
import dataclasses
-import functools
import io
import itertools
import pprint
@@ -16,10 +15,6 @@
from test.support import cpython_only
from test.support.import_helper import ensure_lazy_imports
-# Pin pre-3.15 width/indent for existing formatting tests.
-# compact=True keeps the legacy non-JSON-style container wrapping.
-_pformat = functools.partial(pprint.pformat, indent=1, width=80, compact=True)
-
# list, tuple and dict subclasses that do or don't overwrite __repr__
class list2(list):
pass
@@ -169,6 +164,7 @@ def test_init(self):
self.assertRaises(ValueError, pprint.PrettyPrinter, depth=0)
self.assertRaises(ValueError, pprint.PrettyPrinter, depth=-1)
self.assertRaises(ValueError, pprint.PrettyPrinter, width=0)
+ self.assertRaises(ValueError, pprint.PrettyPrinter, compact=True, expand=True)
def test_basic(self):
# Verify .isrecursive() and .isreadable() w/o recursion
@@ -288,10 +284,10 @@ def test_same_as_repr(self):
True, False, None, ...,
):
native = repr(simple)
- self.assertEqual(_pformat(simple), native)
- self.assertEqual(_pformat(simple, width=1, indent=0)
+ self.assertEqual(pprint.pformat(simple), native)
+ self.assertEqual(pprint.pformat(simple, width=1, indent=0)
.replace('\n', ' '), native)
- self.assertEqual(_pformat(simple, underscore_numbers=True), native)
+ self.assertEqual(pprint.pformat(simple, underscore_numbers=True), native)
self.assertEqual(pprint.saferepr(simple), native)
def test_container_repr_override_called(self):
@@ -322,8 +318,8 @@ def test_container_repr_override_called(self):
):
native = repr(cont)
expected = '*' * len(native)
- self.assertEqual(_pformat(cont), expected)
- self.assertEqual(_pformat(cont, width=1, indent=0), expected)
+ self.assertEqual(pprint.pformat(cont), expected)
+ self.assertEqual(pprint.pformat(cont, width=1, indent=0), expected)
self.assertEqual(pprint.saferepr(cont), expected)
def test_basic_line_wrap(self):
@@ -344,7 +340,7 @@ def test_basic_line_wrap(self):
'read_io_runtime_us': 0,
'write_io_runtime_us': 43690}"""
for type in [dict, dict2]:
- self.assertEqual(_pformat(type(o)), exp)
+ self.assertEqual(pprint.pformat(type(o)), exp)
exp = """\
frozendict({'RPM_cal': 0,
@@ -354,7 +350,7 @@ def test_basic_line_wrap(self):
'main_code_runtime_us': 0,
'read_io_runtime_us': 0,
'write_io_runtime_us': 43690})"""
- self.assertEqual(_pformat(frozendict(o)), exp)
+ self.assertEqual(pprint.pformat(frozendict(o)), exp)
exp = """\
frozendict2({'RPM_cal': 0,
'RPM_cal2': 48059,
@@ -363,79 +359,79 @@ def test_basic_line_wrap(self):
'main_code_runtime_us': 0,
'read_io_runtime_us': 0,
'write_io_runtime_us': 43690})"""
- self.assertEqual(_pformat(frozendict2(o)), exp)
+ self.assertEqual(pprint.pformat(frozendict2(o)), exp)
o = range(100)
exp = 'dict_keys([%s])' % ',\n '.join(map(str, o))
keys = dict.fromkeys(o).keys()
- self.assertEqual(_pformat(keys, width=1), exp)
+ self.assertEqual(pprint.pformat(keys), exp)
keys = frozendict.fromkeys(o).keys()
- self.assertEqual(_pformat(keys, width=1), exp)
+ self.assertEqual(pprint.pformat(keys), exp)
o = range(100)
exp = 'dict_values([%s])' % ',\n '.join(map(str, o))
values = {v: v for v in o}.values()
- self.assertEqual(_pformat(values, width=1), exp)
+ self.assertEqual(pprint.pformat(values), exp)
values = frozendict({v: v for v in o}).values()
- self.assertEqual(_pformat(values, width=1), exp)
+ self.assertEqual(pprint.pformat(values), exp)
o = range(100)
exp = 'dict_items([%s])' % ',\n '.join("(%s, %s)" % (i, i) for i in o)
items = {v: v for v in o}.items()
- self.assertEqual(_pformat(items, width=11), exp)
+ self.assertEqual(pprint.pformat(items), exp)
items = frozendict({v: v for v in o}).items()
- self.assertEqual(_pformat(items, width=11), exp)
+ self.assertEqual(pprint.pformat(items), exp)
o = range(100)
exp = 'odict_keys([%s])' % ',\n '.join(map(str, o))
keys = collections.OrderedDict.fromkeys(o).keys()
- self.assertEqual(_pformat(keys, width=1), exp)
+ self.assertEqual(pprint.pformat(keys), exp)
o = range(100)
exp = 'odict_values([%s])' % ',\n '.join(map(str, o))
values = collections.OrderedDict({v: v for v in o}).values()
- self.assertEqual(_pformat(values, width=1), exp)
+ self.assertEqual(pprint.pformat(values), exp)
o = range(100)
exp = 'odict_items([%s])' % ',\n '.join("(%s, %s)" % (i, i) for i in o)
items = collections.OrderedDict({v: v for v in o}).items()
- self.assertEqual(_pformat(items, width=11), exp)
+ self.assertEqual(pprint.pformat(items), exp)
o = range(100)
exp = 'KeysView({%s})' % (': None,\n '.join(map(str, o)) + ': None')
keys_view = KeysView(dict.fromkeys(o))
- self.assertEqual(_pformat(keys_view), exp)
+ self.assertEqual(pprint.pformat(keys_view), exp)
o = range(100)
exp = 'ItemsView({%s})' % (': None,\n '.join(map(str, o)) + ': None')
items_view = ItemsView(dict.fromkeys(o))
- self.assertEqual(_pformat(items_view), exp)
+ self.assertEqual(pprint.pformat(items_view), exp)
o = range(100)
exp = 'MappingView({%s})' % (': None,\n '.join(map(str, o)) + ': None')
mapping_view = MappingView(dict.fromkeys(o))
- self.assertEqual(_pformat(mapping_view), exp)
+ self.assertEqual(pprint.pformat(mapping_view), exp)
o = range(100)
exp = 'ValuesView({%s})' % (': None,\n '.join(map(str, o)) + ': None')
values_view = ValuesView(dict.fromkeys(o))
- self.assertEqual(_pformat(values_view), exp)
+ self.assertEqual(pprint.pformat(values_view), exp)
o = range(100)
exp = '[%s]' % ',\n '.join(map(str, o))
for type in [list, list2]:
- self.assertEqual(_pformat(type(o), width=1), exp)
+ self.assertEqual(pprint.pformat(type(o)), exp)
o = tuple(range(100))
exp = '(%s)' % ',\n '.join(map(str, o))
for type in [tuple, tuple2]:
- self.assertEqual(_pformat(type(o), width=1), exp)
+ self.assertEqual(pprint.pformat(type(o)), exp)
# indent parameter
o = range(100)
exp = '[ %s]' % ',\n '.join(map(str, o))
for type in [list, list2]:
- self.assertEqual(_pformat(type(o), indent=4, width=1), exp)
+ self.assertEqual(pprint.pformat(type(o), indent=4), exp)
def test_nested_indentations(self):
o1 = list(range(10))
@@ -444,13 +440,13 @@ def test_nested_indentations(self):
expected = """\
[ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
{'first': 1, 'second': 2, 'third': 3}]"""
- self.assertEqual(pprint.pformat(o, indent=4, width=42, compact=True), expected)
+ self.assertEqual(pprint.pformat(o, indent=4, width=42), expected)
expected = """\
[ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
{ 'first': 1,
'second': 2,
'third': 3}]"""
- self.assertEqual(pprint.pformat(o, indent=4, width=41, compact=True), expected)
+ self.assertEqual(pprint.pformat(o, indent=4, width=41), expected)
def test_width(self):
expected = """\
@@ -464,15 +460,17 @@ def test_width(self):
[[[[[1, 2, 3],
'1 2']]]]]"""
o = eval(expected)
- self.assertEqual(_pformat(o, width=15), expected)
- self.assertEqual(_pformat(o, width=16), expected)
- self.assertEqual(_pformat(o, width=25), expected)
- self.assertEqual(_pformat(o, width=14), """\
-[[[[[[1, 2,
+ self.assertEqual(pprint.pformat(o, width=15), expected)
+ self.assertEqual(pprint.pformat(o, width=16), expected)
+ self.assertEqual(pprint.pformat(o, width=25), expected)
+ self.assertEqual(pprint.pformat(o, width=14), """\
+[[[[[[1,
+ 2,
3],
'1 '
'2']]]],
- {1: [1, 2,
+ {1: [1,
+ 2,
3],
2: [12,
34]},
@@ -482,14 +480,15 @@ def test_width(self):
'ef',),
set2({1,
23}),
- [[[[[1, 2,
+ [[[[[1,
+ 2,
3],
'1 '
'2']]]]]""")
def test_integer(self):
- self.assertEqual(_pformat(1234567), '1234567')
- self.assertEqual(_pformat(1234567, underscore_numbers=True), '1_234_567')
+ self.assertEqual(pprint.pformat(1234567), '1234567')
+ self.assertEqual(pprint.pformat(1234567, underscore_numbers=True), '1_234_567')
class Temperature(int):
def __new__(cls, celsius_degrees):
@@ -497,7 +496,7 @@ def __new__(cls, celsius_degrees):
def __repr__(self):
kelvin_degrees = self + 273.15
return f"{kelvin_degrees:.2f}°K"
- self.assertEqual(_pformat(Temperature(1000)), '1273.15°K')
+ self.assertEqual(pprint.pformat(Temperature(1000)), '1273.15°K')
def test_sorted_dict(self):
# Starting in Python 2.5, pprint sorts dict displays by key regardless
@@ -505,8 +504,8 @@ def test_sorted_dict(self):
# Before the change, on 32-bit Windows pformat() gave order
# 'a', 'c', 'b' here, so this test failed.
d = {'a': 1, 'b': 1, 'c': 1}
- self.assertEqual(_pformat(d), "{'a': 1, 'b': 1, 'c': 1}")
- self.assertEqual(_pformat([d, d]),
+ self.assertEqual(pprint.pformat(d), "{'a': 1, 'b': 1, 'c': 1}")
+ self.assertEqual(pprint.pformat([d, d]),
"[{'a': 1, 'b': 1, 'c': 1}, {'a': 1, 'b': 1, 'c': 1}]")
# The next one is kind of goofy. The sorted order depends on the
@@ -514,42 +513,63 @@ def test_sorted_dict(self):
# Python 2.5, this was in the test_same_as_repr() test. It's worth
# keeping around for now because it's one of few tests of pprint
# against a crazy mix of types.
- self.assertEqual(_pformat({"xy\tab\n": (3,), 5: [[]], (): {}}),
+ self.assertEqual(pprint.pformat({"xy\tab\n": (3,), 5: [[]], (): {}}),
r"{5: [[]], 'xy\tab\n': (3,), (): {}}")
def test_sort_dict(self):
d = dict.fromkeys('cba')
- self.assertEqual(_pformat(d, sort_dicts=False), "{'c': None, 'b': None, 'a': None}")
- self.assertEqual(_pformat([d, d], sort_dicts=False),
+ self.assertEqual(pprint.pformat(d, sort_dicts=False), "{'c': None, 'b': None, 'a': None}")
+ self.assertEqual(pprint.pformat([d, d], sort_dicts=False),
"[{'c': None, 'b': None, 'a': None}, {'c': None, 'b': None, 'a': None}]")
def test_ordered_dict(self):
d = collections.OrderedDict()
- self.assertEqual(_pformat(d, width=1), 'OrderedDict()')
+ self.assertEqual(pprint.pformat(d, width=1), 'OrderedDict()')
d = collections.OrderedDict([])
- self.assertEqual(_pformat(d, width=1), 'OrderedDict()')
+ self.assertEqual(pprint.pformat(d, width=1), 'OrderedDict()')
words = 'the quick brown fox jumped over a lazy dog'.split()
d = collections.OrderedDict(zip(words, itertools.count()))
- self.assertEqual(_pformat(d),
+ self.assertEqual(pprint.pformat(d),
"""\
-OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3), ('jumped', 4),
- ('over', 5), ('a', 6), ('lazy', 7), ('dog', 8)])""")
- self.assertEqual(
- _pformat(d.keys(), sort_dicts=False),
- "odict_keys(['the', 'quick', 'brown', 'fox', 'jumped', 'over', 'a', 'lazy', 'dog'])",
- )
- self.assertEqual(_pformat(d.items(), sort_dicts=False),
+OrderedDict([('the', 0),
+ ('quick', 1),
+ ('brown', 2),
+ ('fox', 3),
+ ('jumped', 4),
+ ('over', 5),
+ ('a', 6),
+ ('lazy', 7),
+ ('dog', 8)])""")
+ self.assertEqual(pprint.pformat(d.keys(), sort_dicts=False),
+"""\
+odict_keys(['the',
+ 'quick',
+ 'brown',
+ 'fox',
+ 'jumped',
+ 'over',
+ 'a',
+ 'lazy',
+ 'dog'])""")
+ self.assertEqual(pprint.pformat(d.items(), sort_dicts=False),
"""\
-odict_items([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3), ('jumped', 4), ('over', 5),
- ('a', 6), ('lazy', 7), ('dog', 8)])""")
- self.assertEqual(_pformat(d.values(), sort_dicts=False),
+odict_items([('the', 0),
+ ('quick', 1),
+ ('brown', 2),
+ ('fox', 3),
+ ('jumped', 4),
+ ('over', 5),
+ ('a', 6),
+ ('lazy', 7),
+ ('dog', 8)])""")
+ self.assertEqual(pprint.pformat(d.values(), sort_dicts=False),
"odict_values([0, 1, 2, 3, 4, 5, 6, 7, 8])")
def test_mapping_proxy(self):
words = 'the quick brown fox jumped over a lazy dog'.split()
d = dict(zip(words, itertools.count()))
m = types.MappingProxyType(d)
- self.assertEqual(_pformat(m), """\
+ self.assertEqual(pprint.pformat(m), """\
mappingproxy({'a': 6,
'brown': 2,
'dog': 8,
@@ -561,81 +581,49 @@ def test_mapping_proxy(self):
'the': 0})""")
d = collections.OrderedDict(zip(words, itertools.count()))
m = types.MappingProxyType(d)
- self.assertEqual(_pformat(m), """\
-mappingproxy(OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
- ('jumped', 4), ('over', 5), ('a', 6), ('lazy', 7),
+ self.assertEqual(pprint.pformat(m), """\
+mappingproxy(OrderedDict([('the', 0),
+ ('quick', 1),
+ ('brown', 2),
+ ('fox', 3),
+ ('jumped', 4),
+ ('over', 5),
+ ('a', 6),
+ ('lazy', 7),
('dog', 8)]))""")
def test_dict_views(self):
for dict_class in (dict, collections.OrderedDict, collections.Counter):
empty = dict_class({})
short = dict_class(dict(zip('edcba', 'edcba')))
- lengths = {"empty": empty, "short": short}
+ long = dict_class(dict((chr(x), chr(x)) for x in range(90, 64, -1)))
+ lengths = {"empty": empty, "short": short, "long": long}
prefix = "odict" if dict_class is collections.OrderedDict else "dict"
for name, d in lengths.items():
with self.subTest(length=name, prefix=prefix):
+ is_short = len(d) < 6
+ joiner = ", " if is_short else ",\n "
k = d.keys()
v = d.values()
i = d.items()
- self.assertEqual(_pformat(k, sort_dicts=True),
+ self.assertEqual(pprint.pformat(k, sort_dicts=True),
prefix + "_keys([%s])" %
- ", ".join(repr(key) for key in sorted(k)))
- self.assertEqual(_pformat(v, sort_dicts=True),
+ joiner.join(repr(key) for key in sorted(k)))
+ self.assertEqual(pprint.pformat(v, sort_dicts=True),
prefix + "_values([%s])" %
- ", ".join(repr(val) for val in sorted(v)))
- self.assertEqual(_pformat(i, sort_dicts=True),
+ joiner.join(repr(val) for val in sorted(v)))
+ self.assertEqual(pprint.pformat(i, sort_dicts=True),
prefix + "_items([%s])" %
- ", ".join(repr(item) for item in sorted(i)))
- self.assertEqual(_pformat(k, sort_dicts=False),
+ joiner.join(repr(item) for item in sorted(i)))
+ self.assertEqual(pprint.pformat(k, sort_dicts=False),
prefix + "_keys([%s])" %
- ", ".join(repr(key) for key in k))
- self.assertEqual(_pformat(v, sort_dicts=False),
+ joiner.join(repr(key) for key in k))
+ self.assertEqual(pprint.pformat(v, sort_dicts=False),
prefix + "_values([%s])" %
- ", ".join(repr(val) for val in v))
- self.assertEqual(_pformat(i, sort_dicts=False),
+ joiner.join(repr(val) for val in v))
+ self.assertEqual(pprint.pformat(i, sort_dicts=False),
prefix + "_items([%s])" %
- ", ".join(repr(item) for item in i))
-
- # Long case: views wrap with compact-mode packing.
- long = dict((chr(x), chr(x)) for x in range(90, 64, -1))
- sorted_keys = (
- "['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',\n"
- " 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']"
- )
- unsorted_keys = (
- "['Z', 'Y', 'X', 'W', 'V', 'U', 'T', 'S', 'R', 'Q', 'P', 'O', 'N', 'M', 'L', 'K',\n"
- " 'J', 'I', 'H', 'G', 'F', 'E', 'D', 'C', 'B', 'A']"
- )
- sorted_items = (
- "[('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D'), ('E', 'E'), ('F', 'F'),\n"
- " ('G', 'G'), ('H', 'H'), ('I', 'I'), ('J', 'J'), ('K', 'K'), ('L', 'L'),\n"
- " ('M', 'M'), ('N', 'N'), ('O', 'O'), ('P', 'P'), ('Q', 'Q'), ('R', 'R'),\n"
- " ('S', 'S'), ('T', 'T'), ('U', 'U'), ('V', 'V'), ('W', 'W'), ('X', 'X'),\n"
- " ('Y', 'Y'), ('Z', 'Z')]"
- )
- unsorted_items = (
- "[('Z', 'Z'), ('Y', 'Y'), ('X', 'X'), ('W', 'W'), ('V', 'V'), ('U', 'U'),\n"
- " ('T', 'T'), ('S', 'S'), ('R', 'R'), ('Q', 'Q'), ('P', 'P'), ('O', 'O'),\n"
- " ('N', 'N'), ('M', 'M'), ('L', 'L'), ('K', 'K'), ('J', 'J'), ('I', 'I'),\n"
- " ('H', 'H'), ('G', 'G'), ('F', 'F'), ('E', 'E'), ('D', 'D'), ('C', 'C'),\n"
- " ('B', 'B'), ('A', 'A')]"
- )
- for dict_class in (dict, collections.OrderedDict, collections.Counter):
- d = dict_class(long)
- prefix = "odict" if dict_class is collections.OrderedDict else "dict"
- with self.subTest(length="long", prefix=prefix):
- self.assertEqual(_pformat(d.keys(), sort_dicts=True),
- f"{prefix}_keys({sorted_keys})")
- self.assertEqual(_pformat(d.values(), sort_dicts=True),
- f"{prefix}_values({sorted_keys})")
- self.assertEqual(_pformat(d.items(), sort_dicts=True),
- f"{prefix}_items({sorted_items})")
- self.assertEqual(_pformat(d.keys(), sort_dicts=False),
- f"{prefix}_keys({unsorted_keys})")
- self.assertEqual(_pformat(d.values(), sort_dicts=False),
- f"{prefix}_values({unsorted_keys})")
- self.assertEqual(_pformat(d.items(), sort_dicts=False),
- f"{prefix}_items({unsorted_items})")
+ joiner.join(repr(item) for item in i))
def test_abc_views(self):
empty = {}
@@ -653,55 +641,55 @@ class MV(MappingView): pass
s = sorted(i)
joined_items = "({%s})" % joiner.join(["%r: %r" % (k, v) for (k, v) in i])
sorted_items = "({%s})" % joiner.join(["%r: %r" % (k, v) for (k, v) in s])
- self.assertEqual(_pformat(KeysView(d), sort_dicts=True),
+ self.assertEqual(pprint.pformat(KeysView(d), sort_dicts=True),
KeysView.__name__ + sorted_items)
- self.assertEqual(_pformat(ItemsView(d), sort_dicts=True),
+ self.assertEqual(pprint.pformat(ItemsView(d), sort_dicts=True),
ItemsView.__name__ + sorted_items)
- self.assertEqual(_pformat(MappingView(d), sort_dicts=True),
+ self.assertEqual(pprint.pformat(MappingView(d), sort_dicts=True),
MappingView.__name__ + sorted_items)
- self.assertEqual(_pformat(MV(d), sort_dicts=True),
+ self.assertEqual(pprint.pformat(MV(d), sort_dicts=True),
MV.__name__ + sorted_items)
- self.assertEqual(_pformat(ValuesView(d), sort_dicts=True),
+ self.assertEqual(pprint.pformat(ValuesView(d), sort_dicts=True),
ValuesView.__name__ + sorted_items)
- self.assertEqual(_pformat(KeysView(d), sort_dicts=False),
+ self.assertEqual(pprint.pformat(KeysView(d), sort_dicts=False),
KeysView.__name__ + joined_items)
- self.assertEqual(_pformat(ItemsView(d), sort_dicts=False),
+ self.assertEqual(pprint.pformat(ItemsView(d), sort_dicts=False),
ItemsView.__name__ + joined_items)
- self.assertEqual(_pformat(MappingView(d), sort_dicts=False),
+ self.assertEqual(pprint.pformat(MappingView(d), sort_dicts=False),
MappingView.__name__ + joined_items)
- self.assertEqual(_pformat(MV(d), sort_dicts=False),
+ self.assertEqual(pprint.pformat(MV(d), sort_dicts=False),
MV.__name__ + joined_items)
- self.assertEqual(_pformat(ValuesView(d), sort_dicts=False),
+ self.assertEqual(pprint.pformat(ValuesView(d), sort_dicts=False),
ValuesView.__name__ + joined_items)
def test_nested_views(self):
d = {1: MappingView({1: MappingView({1: MappingView({1: 2})})})}
self.assertEqual(repr(d),
"{1: MappingView({1: MappingView({1: MappingView({1: 2})})})}")
- self.assertEqual(_pformat(d),
+ self.assertEqual(pprint.pformat(d),
"{1: MappingView({1: MappingView({1: MappingView({1: 2})})})}")
- self.assertEqual(_pformat(d, depth=2),
+ self.assertEqual(pprint.pformat(d, depth=2),
"{1: MappingView({1: {...}})}")
d = {}
d1 = {1: d.values()}
d2 = {1: d1.values()}
d3 = {1: d2.values()}
- self.assertEqual(_pformat(d3),
+ self.assertEqual(pprint.pformat(d3),
"{1: dict_values([dict_values([dict_values([])])])}")
- self.assertEqual(_pformat(d3, depth=2),
+ self.assertEqual(pprint.pformat(d3, depth=2),
"{1: dict_values([{...}])}")
def test_unorderable_items_views(self):
"""Check that views with unorderable items have stable sorting."""
d = dict((((3+1j), 3), ((1+1j), (1+0j)), (1j, 0j), (500, None), (499, None)))
iv = ItemsView(d)
- self.assertEqual(_pformat(iv),
- _pformat(iv))
- self.assertTrue(_pformat(iv).endswith(", 499: None, 500: None})"),
- _pformat(iv))
- self.assertEqual(_pformat(d.items()), # Won't be equal unless _safe_tuple
- _pformat(d.items())) # is used in _safe_repr
- self.assertTrue(_pformat(d.items()).endswith(", (499, None), (500, None)])"))
+ self.assertEqual(pprint.pformat(iv),
+ pprint.pformat(iv))
+ self.assertTrue(pprint.pformat(iv).endswith(", 499: None, 500: None})"),
+ pprint.pformat(iv))
+ self.assertEqual(pprint.pformat(d.items()), # Won't be equal unless _safe_tuple
+ pprint.pformat(d.items())) # is used in _safe_repr
+ self.assertTrue(pprint.pformat(d.items()).endswith(", (499, None), (500, None)])"))
def test_mapping_view_subclass_no_mapping(self):
class BMV(MappingView):
@@ -710,7 +698,7 @@ def __init__(self, d):
self.mapping = self._mapping
del self._mapping
- self.assertRaises(AttributeError, _pformat, BMV({}))
+ self.assertRaises(AttributeError, pprint.pformat, BMV({}))
def test_mapping_subclass_repr(self):
"""Test that mapping ABC views use their ._mapping's __repr__."""
@@ -734,10 +722,10 @@ def __repr__(self):
self.assertEqual(repr(m), "MyMapping(['test', 1])")
short_view_repr = "%s(MyMapping(['test', 1]))"
self.assertEqual(repr(m.keys()), short_view_repr % "KeysView")
- self.assertEqual(_pformat(m.items()), short_view_repr % "ItemsView")
- self.assertEqual(_pformat(m.keys()), short_view_repr % "KeysView")
- self.assertEqual(_pformat(MappingView(m)), short_view_repr % "MappingView")
- self.assertEqual(_pformat(m.values()), short_view_repr % "ValuesView")
+ self.assertEqual(pprint.pformat(m.items()), short_view_repr % "ItemsView")
+ self.assertEqual(pprint.pformat(m.keys()), short_view_repr % "KeysView")
+ self.assertEqual(pprint.pformat(MappingView(m)), short_view_repr % "MappingView")
+ self.assertEqual(pprint.pformat(m.values()), short_view_repr % "ValuesView")
alpha = "abcdefghijklmnopqrstuvwxyz"
m = MyMapping(alpha)
@@ -745,19 +733,19 @@ def __repr__(self):
long_view_repr = "%%s(MyMapping([%s]))" % alpha_repr
self.assertEqual(repr(m), "MyMapping([%s])" % alpha_repr)
self.assertEqual(repr(m.keys()), long_view_repr % "KeysView")
- self.assertEqual(_pformat(m.items()), long_view_repr % "ItemsView")
- self.assertEqual(_pformat(m.keys()), long_view_repr % "KeysView")
- self.assertEqual(_pformat(MappingView(m)), long_view_repr % "MappingView")
- self.assertEqual(_pformat(m.values()), long_view_repr % "ValuesView")
+ self.assertEqual(pprint.pformat(m.items()), long_view_repr % "ItemsView")
+ self.assertEqual(pprint.pformat(m.keys()), long_view_repr % "KeysView")
+ self.assertEqual(pprint.pformat(MappingView(m)), long_view_repr % "MappingView")
+ self.assertEqual(pprint.pformat(m.values()), long_view_repr % "ValuesView")
def test_empty_simple_namespace(self):
ns = types.SimpleNamespace()
- formatted = _pformat(ns)
+ formatted = pprint.pformat(ns)
self.assertEqual(formatted, "namespace()")
def test_small_simple_namespace(self):
ns = types.SimpleNamespace(a=1, b=2)
- formatted = _pformat(ns)
+ formatted = pprint.pformat(ns)
self.assertEqual(formatted, "namespace(a=1, b=2)")
def test_simple_namespace(self):
@@ -772,7 +760,7 @@ def test_simple_namespace(self):
lazy=7,
dog=8,
)
- formatted = pprint.pformat(ns, width=60, indent=4, compact=True)
+ formatted = pprint.pformat(ns, width=60, indent=4)
self.assertEqual(formatted, """\
namespace(the=0,
quick=1,
@@ -797,7 +785,7 @@ class AdvancedNamespace(types.SimpleNamespace): pass
lazy=7,
dog=8,
)
- formatted = _pformat(ns, width=60)
+ formatted = pprint.pformat(ns, width=60)
self.assertEqual(formatted, """\
AdvancedNamespace(the=0,
quick=1,
@@ -811,17 +799,17 @@ class AdvancedNamespace(types.SimpleNamespace): pass
def test_empty_dataclass(self):
dc = dataclasses.make_dataclass("MyDataclass", ())()
- formatted = _pformat(dc)
+ formatted = pprint.pformat(dc)
self.assertEqual(formatted, "MyDataclass()")
def test_small_dataclass(self):
dc = dataclass1("text", 123)
- formatted = _pformat(dc)
+ formatted = pprint.pformat(dc)
self.assertEqual(formatted, "dataclass1(field1='text', field2=123, field3=False)")
def test_larger_dataclass(self):
dc = dataclass1("some fairly long text", int(1e10), True)
- formatted = pprint.pformat([dc, dc], width=60, indent=4, compact=True)
+ formatted = pprint.pformat([dc, dc], width=60, indent=4)
self.assertEqual(formatted, """\
[ dataclass1(field1='some fairly long text',
field2=10000000000,
@@ -832,12 +820,12 @@ def test_larger_dataclass(self):
def test_dataclass_with_repr(self):
dc = dataclass2()
- formatted = _pformat(dc, width=20)
+ formatted = pprint.pformat(dc, width=20)
self.assertEqual(formatted, "custom repr that doesn't fit within pprint width")
def test_dataclass_no_repr(self):
dc = dataclass3()
- formatted = _pformat(dc, width=10)
+ formatted = pprint.pformat(dc, width=10)
self.assertRegex(
formatted,
fr"<{re.escape(__name__)}.dataclass3 object at \w+>",
@@ -846,7 +834,7 @@ def test_dataclass_no_repr(self):
def test_recursive_dataclass(self):
dc = dataclass4(None)
dc.a = dc
- formatted = _pformat(dc, width=10)
+ formatted = pprint.pformat(dc, width=10)
self.assertEqual(formatted, """\
dataclass4(a=...,
b=1)""")
@@ -856,7 +844,7 @@ def test_cyclic_dataclass(self):
dc6 = dataclass6(None)
dc5.a = dc6
dc6.c = dc5
- formatted = _pformat(dc5, width=10)
+ formatted = pprint.pformat(dc5, width=10)
self.assertEqual(formatted, """\
dataclass5(a=dataclass6(c=...,
d=1),
@@ -870,7 +858,7 @@ def test_subclassing(self):
{'names with spaces': 'should be presented using repr()',
others.should.not.be: like.this}"""
- dotted_printer = DottedPrettyPrinter(indent=1, compact=True)
+ dotted_printer = DottedPrettyPrinter()
self.assertEqual(dotted_printer.pformat(o), exp)
# length(repr(obj)) < width
@@ -882,29 +870,47 @@ def test_subclassing(self):
self.assertEqual(dotted_printer.pformat(o2), exp2)
def test_set_reprs(self):
- self.assertEqual(_pformat(set()), 'set()')
- self.assertEqual(_pformat(set(range(3))), '{0, 1, 2}')
- self.assertEqual(_pformat(set(range(7)), width=20), '''\
-{0, 1, 2, 3, 4, 5,
+ self.assertEqual(pprint.pformat(set()), 'set()')
+ self.assertEqual(pprint.pformat(set(range(3))), '{0, 1, 2}')
+ self.assertEqual(pprint.pformat(set(range(7)), width=20), '''\
+{0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
6}''')
- self.assertEqual(_pformat(set2(range(7)), width=20), '''\
-set2({0, 1, 2, 3, 4,
- 5, 6})''')
- self.assertEqual(_pformat(set3(range(7)), width=20),
+ self.assertEqual(pprint.pformat(set2(range(7)), width=20), '''\
+set2({0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6})''')
+ self.assertEqual(pprint.pformat(set3(range(7)), width=20),
'set3({0, 1, 2, 3, 4, 5, 6})')
- self.assertEqual(_pformat(frozenset()), 'frozenset()')
- self.assertEqual(_pformat(frozenset(range(3))),
+ self.assertEqual(pprint.pformat(frozenset()), 'frozenset()')
+ self.assertEqual(pprint.pformat(frozenset(range(3))),
'frozenset({0, 1, 2})')
- self.assertEqual(_pformat(frozenset(range(7)), width=20), '''\
-frozenset({0, 1, 2,
- 3, 4, 5,
+ self.assertEqual(pprint.pformat(frozenset(range(7)), width=20), '''\
+frozenset({0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
6})''')
- self.assertEqual(_pformat(frozenset2(range(7)), width=20), '''\
-frozenset2({0, 1, 2,
- 3, 4, 5,
+ self.assertEqual(pprint.pformat(frozenset2(range(7)), width=20), '''\
+frozenset2({0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
6})''')
- self.assertEqual(_pformat(frozenset3(range(7)), width=20),
+ self.assertEqual(pprint.pformat(frozenset3(range(7)), width=20),
'frozenset3({0, 1, 2, 3, 4, 5, 6})')
def test_set_of_sets_reprs(self):
@@ -936,21 +942,21 @@ def test_set_of_sets_reprs(self):
fs0 = frozenset()
fs1 = frozenset(('abc', 'xyz'))
data = frozenset((fs0, fs1))
- self.assertEqual(_pformat(data),
+ self.assertEqual(pprint.pformat(data),
'frozenset({%r, %r})' % (fs0, fs1))
- self.assertEqual(_pformat(data), repr(data))
+ self.assertEqual(pprint.pformat(data), repr(data))
fs2 = frozenset(('one', 'two'))
data = {fs2: frozenset((fs0, fs1))}
- self.assertEqual(_pformat(data),
+ self.assertEqual(pprint.pformat(data),
"{%r: frozenset({%r, %r})}" % (fs2, fs0, fs1))
- self.assertEqual(_pformat(data), repr(data))
+ self.assertEqual(pprint.pformat(data), repr(data))
# Single-line, unordered:
fs1 = frozenset(("xyz", "qwerty"))
fs2 = frozenset(("abcd", "spam"))
fs = frozenset((fs1, fs2))
- self.assertEqual(_pformat(fs), repr(fs))
+ self.assertEqual(pprint.pformat(fs), repr(fs))
# Multiline, unordered:
def check(res, invariants):
@@ -960,7 +966,7 @@ def check(res, invariants):
fs1 = frozenset(('regular string', 'other string'))
fs2 = frozenset(('third string', 'one more string'))
check(
- _pformat(frozenset((fs1, fs2))),
+ pprint.pformat(frozenset((fs1, fs2))),
[
"""
frozenset({%r,
@@ -975,7 +981,7 @@ def check(res, invariants):
# Everything is multiline, unordered:
check(
- _pformat(
+ pprint.pformat(
frozenset((
frozenset((
"xyz very-very long string",
@@ -1022,16 +1028,16 @@ def test_depth(self):
nested_tuple = (1, (2, (3, (4, (5, 6)))))
nested_dict = {1: {2: {3: {4: {5: {6: 6}}}}}}
nested_list = [1, [2, [3, [4, [5, [6, []]]]]]]
- self.assertEqual(_pformat(nested_tuple), repr(nested_tuple))
- self.assertEqual(_pformat(nested_dict), repr(nested_dict))
- self.assertEqual(_pformat(nested_list), repr(nested_list))
+ self.assertEqual(pprint.pformat(nested_tuple), repr(nested_tuple))
+ self.assertEqual(pprint.pformat(nested_dict), repr(nested_dict))
+ self.assertEqual(pprint.pformat(nested_list), repr(nested_list))
lv1_tuple = '(1, (...))'
lv1_dict = '{1: {...}}'
lv1_list = '[1, [...]]'
- self.assertEqual(_pformat(nested_tuple, depth=1), lv1_tuple)
- self.assertEqual(_pformat(nested_dict, depth=1), lv1_dict)
- self.assertEqual(_pformat(nested_list, depth=1), lv1_list)
+ self.assertEqual(pprint.pformat(nested_tuple, depth=1), lv1_tuple)
+ self.assertEqual(pprint.pformat(nested_dict, depth=1), lv1_dict)
+ self.assertEqual(pprint.pformat(nested_list, depth=1), lv1_list)
def test_sort_unorderable_values(self):
# Issue 3976: sorted pprints fail for unorderable values.
@@ -1041,24 +1047,24 @@ def test_sort_unorderable_values(self):
skeys = sorted(keys, key=id)
clean = lambda s: s.replace(' ', '').replace('\n','')
- self.assertEqual(clean(_pformat(set(keys))),
+ self.assertEqual(clean(pprint.pformat(set(keys))),
'{' + ','.join(map(repr, skeys)) + '}')
- self.assertEqual(clean(_pformat(frozenset(keys))),
+ self.assertEqual(clean(pprint.pformat(frozenset(keys))),
'frozenset({' + ','.join(map(repr, skeys)) + '})')
- self.assertEqual(clean(_pformat(dict.fromkeys(keys))),
+ self.assertEqual(clean(pprint.pformat(dict.fromkeys(keys))),
'{' + ','.join('%r:None' % k for k in skeys) + '}')
- self.assertEqual(clean(_pformat(dict.fromkeys(keys).keys())),
+ self.assertEqual(clean(pprint.pformat(dict.fromkeys(keys).keys())),
'dict_keys([' + ','.join('%r' % k for k in skeys) + '])')
- self.assertEqual(clean(_pformat(dict.fromkeys(keys).items())),
+ self.assertEqual(clean(pprint.pformat(dict.fromkeys(keys).items())),
'dict_items([' + ','.join('(%r,None)' % k for k in skeys) + '])')
# Issue 10017: TypeError on user-defined types as dict keys.
- self.assertEqual(_pformat({Unorderable: 0, 1: 0}),
+ self.assertEqual(pprint.pformat({Unorderable: 0, 1: 0}),
'{1: 0, ' + repr(Unorderable) +': 0}')
# Issue 14998: TypeError on tuples with NoneTypes as dict keys.
keys = [(1,), (None,)]
- self.assertEqual(_pformat(dict.fromkeys(keys, 0)),
+ self.assertEqual(pprint.pformat(dict.fromkeys(keys, 0)),
'{%r: 0, %r: 0}' % tuple(sorted(keys, key=id)))
def test_sort_orderable_and_unorderable_values(self):
@@ -1071,24 +1077,24 @@ def test_sort_orderable_and_unorderable_values(self):
self.assertEqual(sorted([b, a]), [a, b])
self.assertEqual(sorted([a, b]), [a, b])
# set
- self.assertEqual(_pformat(set([b, a]), width=1),
+ self.assertEqual(pprint.pformat(set([b, a]), width=1),
'{%r,\n %r}' % (a, b))
- self.assertEqual(_pformat(set([a, b]), width=1),
+ self.assertEqual(pprint.pformat(set([a, b]), width=1),
'{%r,\n %r}' % (a, b))
# dict
- self.assertEqual(_pformat(dict.fromkeys([b, a]), width=1),
+ self.assertEqual(pprint.pformat(dict.fromkeys([b, a]), width=1),
'{%r: None,\n %r: None}' % (a, b))
- self.assertEqual(_pformat(dict.fromkeys([a, b]), width=1),
+ self.assertEqual(pprint.pformat(dict.fromkeys([a, b]), width=1),
'{%r: None,\n %r: None}' % (a, b))
def test_str_wrap(self):
# pprint tries to wrap strings intelligently
fox = 'the quick brown fox jumped over a lazy dog'
- self.assertEqual(_pformat(fox, width=19), """\
+ self.assertEqual(pprint.pformat(fox, width=19), """\
('the quick brown '
'fox jumped over '
'a lazy dog')""")
- self.assertEqual(_pformat({'a': 1, 'b': fox, 'c': 2},
+ self.assertEqual(pprint.pformat({'a': 1, 'b': fox, 'c': 2},
width=25), """\
{'a': 1,
'b': 'the quick brown '
@@ -1101,28 +1107,28 @@ def test_str_wrap(self):
# - non-ASCII is allowed
# - an apostrophe doesn't disrupt the pprint
special = "Portons dix bons \"whiskys\"\nà l'avocat goujat\t qui fumait au zoo"
- self.assertEqual(_pformat(special, width=68), repr(special))
- self.assertEqual(_pformat(special, width=31), """\
+ self.assertEqual(pprint.pformat(special, width=68), repr(special))
+ self.assertEqual(pprint.pformat(special, width=31), """\
('Portons dix bons "whiskys"\\n'
"à l'avocat goujat\\t qui "
'fumait au zoo')""")
- self.assertEqual(_pformat(special, width=20), """\
+ self.assertEqual(pprint.pformat(special, width=20), """\
('Portons dix bons '
'"whiskys"\\n'
"à l'avocat "
'goujat\\t qui '
'fumait au zoo')""")
- self.assertEqual(_pformat([[[[[special]]]]], width=35), """\
+ self.assertEqual(pprint.pformat([[[[[special]]]]], width=35), """\
[[[[['Portons dix bons "whiskys"\\n'
"à l'avocat goujat\\t qui "
'fumait au zoo']]]]]""")
- self.assertEqual(_pformat([[[[[special]]]]], width=25), """\
+ self.assertEqual(pprint.pformat([[[[[special]]]]], width=25), """\
[[[[['Portons dix bons '
'"whiskys"\\n'
"à l'avocat "
'goujat\\t qui '
'fumait au zoo']]]]]""")
- self.assertEqual(_pformat([[[[[special]]]]], width=23), """\
+ self.assertEqual(pprint.pformat([[[[[special]]]]], width=23), """\
[[[[['Portons dix '
'bons "whiskys"\\n'
"à l'avocat "
@@ -1131,14 +1137,14 @@ def test_str_wrap(self):
'zoo']]]]]""")
# An unwrappable string is formatted as its repr
unwrappable = "x" * 100
- self.assertEqual(_pformat(unwrappable, width=80), repr(unwrappable))
- self.assertEqual(_pformat(''), "''")
+ self.assertEqual(pprint.pformat(unwrappable, width=80), repr(unwrappable))
+ self.assertEqual(pprint.pformat(''), "''")
# Check that the pprint is a usable repr
special *= 10
for width in range(3, 40):
- formatted = _pformat(special, width=width)
+ formatted = pprint.pformat(special, width=width)
self.assertEqual(eval(formatted), special)
- formatted = _pformat([special] * 2, width=width)
+ formatted = pprint.pformat([special] * 2, width=width)
self.assertEqual(eval(formatted), [special] * 2)
def test_compact(self):
@@ -1151,7 +1157,7 @@ def test_compact(self):
14, 15],
[], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3],
[0, 1, 2, 3, 4]]"""
- self.assertEqual(_pformat(o, width=47, compact=True), expected)
+ self.assertEqual(pprint.pformat(o, width=47, compact=True), expected)
def test_compact_width(self):
levels = 20
@@ -1160,117 +1166,117 @@ def test_compact_width(self):
for i in range(levels - 1):
o = [o]
for w in range(levels * 2 + 1, levels + 3 * number - 1):
- lines = _pformat(o, width=w, compact=True).splitlines()
+ lines = pprint.pformat(o, width=w, compact=True).splitlines()
maxwidth = max(map(len, lines))
self.assertLessEqual(maxwidth, w)
self.assertGreater(maxwidth, w - 3)
def test_bytes_wrap(self):
- self.assertEqual(_pformat(b'', width=1), "b''")
- self.assertEqual(_pformat(b'abcd', width=1), "b'abcd'")
+ self.assertEqual(pprint.pformat(b'', width=1), "b''")
+ self.assertEqual(pprint.pformat(b'abcd', width=1), "b'abcd'")
letters = b'abcdefghijklmnopqrstuvwxyz'
- self.assertEqual(_pformat(letters, width=29), repr(letters))
- self.assertEqual(_pformat(letters, width=19), """\
+ self.assertEqual(pprint.pformat(letters, width=29), repr(letters))
+ self.assertEqual(pprint.pformat(letters, width=19), """\
(b'abcdefghijkl'
b'mnopqrstuvwxyz')""")
- self.assertEqual(_pformat(letters, width=18), """\
+ self.assertEqual(pprint.pformat(letters, width=18), """\
(b'abcdefghijkl'
b'mnopqrstuvwx'
b'yz')""")
- self.assertEqual(_pformat(letters, width=16), """\
+ self.assertEqual(pprint.pformat(letters, width=16), """\
(b'abcdefghijkl'
b'mnopqrstuvwx'
b'yz')""")
special = bytes(range(16))
- self.assertEqual(_pformat(special, width=61), repr(special))
- self.assertEqual(_pformat(special, width=48), """\
+ self.assertEqual(pprint.pformat(special, width=61), repr(special))
+ self.assertEqual(pprint.pformat(special, width=48), """\
(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
b'\\x0c\\r\\x0e\\x0f')""")
- self.assertEqual(_pformat(special, width=32), """\
+ self.assertEqual(pprint.pformat(special, width=32), """\
(b'\\x00\\x01\\x02\\x03'
b'\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
b'\\x0c\\r\\x0e\\x0f')""")
- self.assertEqual(_pformat(special, width=1), """\
+ self.assertEqual(pprint.pformat(special, width=1), """\
(b'\\x00\\x01\\x02\\x03'
b'\\x04\\x05\\x06\\x07'
b'\\x08\\t\\n\\x0b'
b'\\x0c\\r\\x0e\\x0f')""")
- self.assertEqual(_pformat({'a': 1, 'b': letters, 'c': 2},
+ self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2},
width=21), """\
{'a': 1,
'b': b'abcdefghijkl'
b'mnopqrstuvwx'
b'yz',
'c': 2}""")
- self.assertEqual(_pformat({'a': 1, 'b': letters, 'c': 2},
+ self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2},
width=20), """\
{'a': 1,
'b': b'abcdefgh'
b'ijklmnop'
b'qrstuvwxyz',
'c': 2}""")
- self.assertEqual(_pformat([[[[[[letters]]]]]], width=25), """\
+ self.assertEqual(pprint.pformat([[[[[[letters]]]]]], width=25), """\
[[[[[[b'abcdefghijklmnop'
b'qrstuvwxyz']]]]]]""")
- self.assertEqual(_pformat([[[[[[special]]]]]], width=41), """\
+ self.assertEqual(pprint.pformat([[[[[[special]]]]]], width=41), """\
[[[[[[b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07'
b'\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f']]]]]]""")
# Check that the pprint is a usable repr
for width in range(1, 64):
- formatted = _pformat(special, width=width)
+ formatted = pprint.pformat(special, width=width)
self.assertEqual(eval(formatted), special)
- formatted = _pformat([special] * 2, width=width)
+ formatted = pprint.pformat([special] * 2, width=width)
self.assertEqual(eval(formatted), [special] * 2)
def test_bytearray_wrap(self):
- self.assertEqual(_pformat(bytearray(), width=1), "bytearray(b'')")
+ self.assertEqual(pprint.pformat(bytearray(), width=1), "bytearray(b'')")
letters = bytearray(b'abcdefghijklmnopqrstuvwxyz')
- self.assertEqual(_pformat(letters, width=40), repr(letters))
- self.assertEqual(_pformat(letters, width=28), """\
+ self.assertEqual(pprint.pformat(letters, width=40), repr(letters))
+ self.assertEqual(pprint.pformat(letters, width=28), """\
bytearray(b'abcdefghijkl'
b'mnopqrstuvwxyz')""")
- self.assertEqual(_pformat(letters, width=27), """\
+ self.assertEqual(pprint.pformat(letters, width=27), """\
bytearray(b'abcdefghijkl'
b'mnopqrstuvwx'
b'yz')""")
- self.assertEqual(_pformat(letters, width=25), """\
+ self.assertEqual(pprint.pformat(letters, width=25), """\
bytearray(b'abcdefghijkl'
b'mnopqrstuvwx'
b'yz')""")
special = bytearray(range(16))
- self.assertEqual(_pformat(special, width=72), repr(special))
- self.assertEqual(_pformat(special, width=57), """\
+ self.assertEqual(pprint.pformat(special, width=72), repr(special))
+ self.assertEqual(pprint.pformat(special, width=57), """\
bytearray(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
b'\\x0c\\r\\x0e\\x0f')""")
- self.assertEqual(_pformat(special, width=41), """\
+ self.assertEqual(pprint.pformat(special, width=41), """\
bytearray(b'\\x00\\x01\\x02\\x03'
b'\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
b'\\x0c\\r\\x0e\\x0f')""")
- self.assertEqual(_pformat(special, width=1), """\
+ self.assertEqual(pprint.pformat(special, width=1), """\
bytearray(b'\\x00\\x01\\x02\\x03'
b'\\x04\\x05\\x06\\x07'
b'\\x08\\t\\n\\x0b'
b'\\x0c\\r\\x0e\\x0f')""")
- self.assertEqual(_pformat({'a': 1, 'b': letters, 'c': 2},
+ self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2},
width=31), """\
{'a': 1,
'b': bytearray(b'abcdefghijkl'
b'mnopqrstuvwx'
b'yz'),
'c': 2}""")
- self.assertEqual(_pformat([[[[[letters]]]]], width=37), """\
+ self.assertEqual(pprint.pformat([[[[[letters]]]]], width=37), """\
[[[[[bytearray(b'abcdefghijklmnop'
b'qrstuvwxyz')]]]]]""")
- self.assertEqual(_pformat([[[[[special]]]]], width=50), """\
+ self.assertEqual(pprint.pformat([[[[[special]]]]], width=50), """\
[[[[[bytearray(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07'
b'\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f')]]]]]""")
def test_default_dict(self):
d = collections.defaultdict(int)
- self.assertEqual(_pformat(d, width=1), "defaultdict(, {})")
+ self.assertEqual(pprint.pformat(d, width=1), "defaultdict(, {})")
words = 'the quick brown fox jumped over a lazy dog'.split()
d = collections.defaultdict(int, zip(words, itertools.count()))
- self.assertEqual(_pformat(d),
+ self.assertEqual(pprint.pformat(d),
"""\
defaultdict(,
{'a': 6,
@@ -1285,15 +1291,15 @@ def test_default_dict(self):
def test_counter(self):
d = collections.Counter()
- self.assertEqual(_pformat(d, width=1), "Counter()")
+ self.assertEqual(pprint.pformat(d, width=1), "Counter()")
d = collections.Counter('senselessness')
- self.assertEqual(_pformat(d, width=40),
+ self.assertEqual(pprint.pformat(d, width=40),
"""\
Counter({'s': 6,
'e': 4,
'n': 2,
'l': 1})""")
- self.assertEqual(_pformat(d, indent=2, width=1),
+ self.assertEqual(pprint.pformat(d, indent=2, width=1),
"""\
Counter({ 's': 6,
'e': 4,
@@ -1302,11 +1308,11 @@ def test_counter(self):
def test_chainmap(self):
d = collections.ChainMap()
- self.assertEqual(_pformat(d, width=1), "ChainMap({})")
+ self.assertEqual(pprint.pformat(d, width=1), "ChainMap({})")
words = 'the quick brown fox jumped over a lazy dog'.split()
items = list(zip(words, itertools.count()))
d = collections.ChainMap(dict(items))
- self.assertEqual(_pformat(d),
+ self.assertEqual(pprint.pformat(d),
"""\
ChainMap({'a': 6,
'brown': 2,
@@ -1318,7 +1324,7 @@ def test_chainmap(self):
'quick': 1,
'the': 0})""")
d = collections.ChainMap(dict(items), collections.OrderedDict(items))
- self.assertEqual(_pformat(d),
+ self.assertEqual(pprint.pformat(d),
"""\
ChainMap({'a': 6,
'brown': 2,
@@ -1329,10 +1335,16 @@ def test_chainmap(self):
'over': 5,
'quick': 1,
'the': 0},
- OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
- ('jumped', 4), ('over', 5), ('a', 6), ('lazy', 7),
+ OrderedDict([('the', 0),
+ ('quick', 1),
+ ('brown', 2),
+ ('fox', 3),
+ ('jumped', 4),
+ ('over', 5),
+ ('a', 6),
+ ('lazy', 7),
('dog', 8)]))""")
- self.assertEqual(_pformat(d.keys()),
+ self.assertEqual(pprint.pformat(d.keys()),
"""\
KeysView(ChainMap({'a': 6,
'brown': 2,
@@ -1343,10 +1355,16 @@ def test_chainmap(self):
'over': 5,
'quick': 1,
'the': 0},
- OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
- ('jumped', 4), ('over', 5), ('a', 6), ('lazy', 7),
+ OrderedDict([('the', 0),
+ ('quick', 1),
+ ('brown', 2),
+ ('fox', 3),
+ ('jumped', 4),
+ ('over', 5),
+ ('a', 6),
+ ('lazy', 7),
('dog', 8)])))""")
- self.assertEqual(_pformat(d.items()),
+ self.assertEqual(pprint.pformat(d.items()),
"""\
ItemsView(ChainMap({'a': 6,
'brown': 2,
@@ -1357,10 +1375,16 @@ def test_chainmap(self):
'over': 5,
'quick': 1,
'the': 0},
- OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
- ('jumped', 4), ('over', 5), ('a', 6), ('lazy', 7),
+ OrderedDict([('the', 0),
+ ('quick', 1),
+ ('brown', 2),
+ ('fox', 3),
+ ('jumped', 4),
+ ('over', 5),
+ ('a', 6),
+ ('lazy', 7),
('dog', 8)])))""")
- self.assertEqual(_pformat(d.values()),
+ self.assertEqual(pprint.pformat(d.values()),
"""\
ValuesView(ChainMap({'a': 6,
'brown': 2,
@@ -1371,34 +1395,52 @@ def test_chainmap(self):
'over': 5,
'quick': 1,
'the': 0},
- OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
- ('jumped', 4), ('over', 5), ('a', 6), ('lazy', 7),
+ OrderedDict([('the', 0),
+ ('quick', 1),
+ ('brown', 2),
+ ('fox', 3),
+ ('jumped', 4),
+ ('over', 5),
+ ('a', 6),
+ ('lazy', 7),
('dog', 8)])))""")
def test_deque(self):
d = collections.deque()
- self.assertEqual(_pformat(d, width=1), "deque([])")
+ self.assertEqual(pprint.pformat(d, width=1), "deque([])")
d = collections.deque(maxlen=7)
- self.assertEqual(_pformat(d, width=1), "deque([], maxlen=7)")
+ self.assertEqual(pprint.pformat(d, width=1), "deque([], maxlen=7)")
words = 'the quick brown fox jumped over a lazy dog'.split()
d = collections.deque(zip(words, itertools.count()))
- self.assertEqual(_pformat(d),
+ self.assertEqual(pprint.pformat(d),
"""\
-deque([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3), ('jumped', 4),
- ('over', 5), ('a', 6), ('lazy', 7), ('dog', 8)])""")
+deque([('the', 0),
+ ('quick', 1),
+ ('brown', 2),
+ ('fox', 3),
+ ('jumped', 4),
+ ('over', 5),
+ ('a', 6),
+ ('lazy', 7),
+ ('dog', 8)])""")
d = collections.deque(zip(words, itertools.count()), maxlen=7)
- self.assertEqual(_pformat(d),
+ self.assertEqual(pprint.pformat(d),
"""\
-deque([('brown', 2), ('fox', 3), ('jumped', 4), ('over', 5), ('a', 6),
- ('lazy', 7), ('dog', 8)],
+deque([('brown', 2),
+ ('fox', 3),
+ ('jumped', 4),
+ ('over', 5),
+ ('a', 6),
+ ('lazy', 7),
+ ('dog', 8)],
maxlen=7)""")
def test_user_dict(self):
d = collections.UserDict()
- self.assertEqual(_pformat(d, width=1), "{}")
+ self.assertEqual(pprint.pformat(d, width=1), "{}")
words = 'the quick brown fox jumped over a lazy dog'.split()
d = collections.UserDict(zip(words, itertools.count()))
- self.assertEqual(_pformat(d),
+ self.assertEqual(pprint.pformat(d),
"""\
{'a': 6,
'brown': 2,
@@ -1409,7 +1451,7 @@ def test_user_dict(self):
'over': 5,
'quick': 1,
'the': 0}""")
- self.assertEqual(_pformat(d.keys()), """\
+ self.assertEqual(pprint.pformat(d.keys()), """\
KeysView({'a': 6,
'brown': 2,
'dog': 8,
@@ -1419,7 +1461,7 @@ def test_user_dict(self):
'over': 5,
'quick': 1,
'the': 0})""")
- self.assertEqual(_pformat(d.items()), """\
+ self.assertEqual(pprint.pformat(d.items()), """\
ItemsView({'a': 6,
'brown': 2,
'dog': 8,
@@ -1429,7 +1471,7 @@ def test_user_dict(self):
'over': 5,
'quick': 1,
'the': 0})""")
- self.assertEqual(_pformat(d.values()), """\
+ self.assertEqual(pprint.pformat(d.values()), """\
ValuesView({'a': 6,
'brown': 2,
'dog': 8,
@@ -1442,24 +1484,31 @@ def test_user_dict(self):
def test_user_list(self):
d = collections.UserList()
- self.assertEqual(_pformat(d, width=1), "[]")
+ self.assertEqual(pprint.pformat(d, width=1), "[]")
words = 'the quick brown fox jumped over a lazy dog'.split()
d = collections.UserList(zip(words, itertools.count()))
- self.assertEqual(_pformat(d),
+ self.assertEqual(pprint.pformat(d),
"""\
-[('the', 0), ('quick', 1), ('brown', 2), ('fox', 3), ('jumped', 4), ('over', 5),
- ('a', 6), ('lazy', 7), ('dog', 8)]""")
+[('the', 0),
+ ('quick', 1),
+ ('brown', 2),
+ ('fox', 3),
+ ('jumped', 4),
+ ('over', 5),
+ ('a', 6),
+ ('lazy', 7),
+ ('dog', 8)]""")
def test_user_string(self):
d = collections.UserString('')
- self.assertEqual(_pformat(d, width=1), "''")
+ self.assertEqual(pprint.pformat(d, width=1), "''")
d = collections.UserString('the quick brown fox jumped over a lazy dog')
- self.assertEqual(_pformat(d, width=20),
+ self.assertEqual(pprint.pformat(d, width=20),
"""\
('the quick brown '
'fox jumped over '
'a lazy dog')""")
- self.assertEqual(_pformat({1: d}, width=20),
+ self.assertEqual(pprint.pformat({1: d}, width=20),
"""\
{1: 'the quick '
'brown fox '
@@ -1468,22 +1517,22 @@ def test_user_string(self):
def test_template(self):
d = t""
- self.assertEqual(_pformat(d),
+ self.assertEqual(pprint.pformat(d),
"Template(strings=('',), interpolations=())")
- self.assertEqual(_pformat(d), repr(d))
- self.assertEqual(_pformat(d, width=1),
+ self.assertEqual(pprint.pformat(d), repr(d))
+ self.assertEqual(pprint.pformat(d, width=1),
"""\
Template(strings=('',),
interpolations=())""")
name = "World"
d = t"Hello {name}"
- self.assertEqual(_pformat(d),
+ self.assertEqual(pprint.pformat(d),
"""\
Template(strings=('Hello ', ''),
interpolations=(Interpolation('World', 'name', None, ''),))""")
ver = {3.13: False, 3.14: True}
d = t"Hello { {"name": "Python", "version": ver}!s:z}!"
- self.assertEqual(_pformat(d, width=1),
+ self.assertEqual(pprint.pformat(d, width=1),
"""\
Template(strings=('Hello ',
'!'),
@@ -1501,13 +1550,13 @@ def test_template(self):
def test_expand_template(self):
d = t""
self.assertEqual(
- pprint.pformat(d),
+ pprint.pformat(d, expand=True),
"Template(strings=('',), interpolations=())",
)
name = "World"
d = t"Hello {name}"
self.assertEqual(
- pprint.pformat(d, width=40, indent=4),
+ pprint.pformat(d, width=40, indent=4, expand=True),
"""\
Template(
strings=('Hello ', ''),
@@ -1524,7 +1573,7 @@ def test_expand_template(self):
ver = {3.13: False, 3.14: True}
d = t"Hello { {"name": "Python", "version": ver}!s:z}!"
self.assertEqual(
- pprint.pformat(d, width=40, indent=4),
+ pprint.pformat(d, width=40, indent=4, expand=True),
"""\
Template(
strings=('Hello ', '!'),
@@ -1565,7 +1614,8 @@ class DummyDataclass:
corge=7,
garply=(1, 2, 3, 4),
)
- self.assertEqual(pprint.pformat(dummy_dataclass, width=40, indent=4),
+ self.assertEqual(pprint.pformat(dummy_dataclass, width=40, indent=4,
+ expand=True),
"""\
DummyDataclass(
foo='foo',
@@ -1585,7 +1635,8 @@ def test_expand_dict(self):
"quux": ["foo", "bar", "baz"],
"corge": 7,
}
- self.assertEqual(pprint.pformat(dummy_dict, width=40, indent=4, sort_dicts=False),
+ self.assertEqual(pprint.pformat(dummy_dict, width=40, indent=4,
+ expand=True, sort_dicts=False),
"""\
{
'foo': 'bar',
@@ -1603,7 +1654,8 @@ def test_expand_ordered_dict(self):
("baz", 123),
]
)
- self.assertEqual(pprint.pformat(dummy_ordered_dict, width=20, indent=4),
+ self.assertEqual(pprint.pformat(dummy_ordered_dict, width=20, indent=4,
+ expand=True),
"""\
OrderedDict([
('foo', 1),
@@ -1618,7 +1670,8 @@ def test_expand_list(self):
"baz",
"qux",
]
- self.assertEqual(pprint.pformat(dummy_list, width=20, indent=4),
+ self.assertEqual(pprint.pformat(dummy_list, width=20, indent=4,
+ expand=True),
"""\
[
'foo',
@@ -1636,7 +1689,8 @@ def test_expand_tuple(self):
5,
6,
)
- self.assertEqual(pprint.pformat(dummy_tuple, width=20, indent=4),
+ self.assertEqual(pprint.pformat(dummy_tuple, width=20, indent=4,
+ expand=True),
"""\
(
'foo',
@@ -1649,7 +1703,7 @@ def test_expand_tuple(self):
def test_expand_single_element_tuple(self):
self.assertEqual(
- pprint.pformat((1,), width=1, indent=4),
+ pprint.pformat((1,), width=1, indent=4, expand=True),
"""\
(
1,
@@ -1663,7 +1717,8 @@ def test_expand_set(self):
"qux",
(1, 2, 3),
}
- self.assertEqual(pprint.pformat(dummy_set, width=20, indent=4),
+ self.assertEqual(pprint.pformat(dummy_set, width=20, indent=4,
+ expand=True),
"""\
{
'bar',
@@ -1686,7 +1741,8 @@ def test_expand_frozenset(self):
frozenset(dummy_set),
}
)
- self.assertEqual(pprint.pformat(dummy_frozenset, width=40, indent=4),
+ self.assertEqual(pprint.pformat(dummy_frozenset, width=40, indent=4,
+ expand=True),
"""\
frozenset({
frozenset({(1, 2, 3)}),
@@ -1701,7 +1757,7 @@ def test_expand_frozendict(self):
{"foo": "bar", "baz": 123, "qux": [1, 2]}
)
self.assertEqual(
- pprint.pformat(dummy_frozendict, width=20, indent=4),
+ pprint.pformat(dummy_frozendict, width=20, indent=4, expand=True),
"""\
frozendict({
'baz': 123,
@@ -1712,7 +1768,8 @@ def test_expand_frozendict(self):
def test_expand_bytes(self):
dummy_bytes = b"Hello world! foo bar baz 123 456 789"
- self.assertEqual(pprint.pformat(dummy_bytes, width=20, indent=4),
+ self.assertEqual(pprint.pformat(dummy_bytes, width=20, indent=4,
+ expand=True),
"""\
(
b'Hello world!'
@@ -1723,7 +1780,8 @@ def test_expand_bytes(self):
def test_expand_bytearray(self):
dummy_bytes = b"Hello world! foo bar baz 123 456 789"
dummy_byte_array = bytearray(dummy_bytes)
- self.assertEqual(pprint.pformat(dummy_byte_array, width=40, indent=4),
+ self.assertEqual(pprint.pformat(dummy_byte_array, width=40, indent=4,
+ expand=True),
"""\
bytearray(
b'Hello world! foo bar baz 123 456'
@@ -1739,7 +1797,8 @@ def test_expand_mappingproxy(self):
"corge": 7,
}
dummy_mappingproxy = types.MappingProxyType(dummy_dict)
- self.assertEqual(pprint.pformat(dummy_mappingproxy, width=40, indent=4),
+ self.assertEqual(pprint.pformat(dummy_mappingproxy, width=40, indent=4,
+ expand=True),
"""\
mappingproxy({
'baz': 123,
@@ -1760,7 +1819,8 @@ def test_expand_namespace(self):
),
)
- self.assertEqual(pprint.pformat(dummy_namespace, width=40, indent=4),
+ self.assertEqual(pprint.pformat(dummy_namespace, width=40, indent=4,
+ expand=True),
"""\
namespace(
foo='bar',
@@ -1778,7 +1838,8 @@ def test_expand_defaultdict(self):
dummy_defaultdict["foo"].append("baz")
dummy_defaultdict["foo"].append("qux")
dummy_defaultdict["bar"] = {"foo": "bar", "baz": None}
- self.assertEqual(pprint.pformat(dummy_defaultdict, width=40, indent=4),
+ self.assertEqual(pprint.pformat(dummy_defaultdict, width=40, indent=4,
+ expand=True),
"""\
defaultdict(, {
'bar': {'baz': None, 'foo': 'bar'},
@@ -1795,7 +1856,8 @@ def test_expand_counter(self):
'd': 2,
'e': 1,
})"""
- self.assertEqual(pprint.pformat(dummy_counter, width=40, indent=4), expected)
+ self.assertEqual(pprint.pformat(dummy_counter, width=40, indent=4,
+ expand=True), expected)
expected2 = """\
Counter({
@@ -1805,7 +1867,8 @@ def test_expand_counter(self):
'd': 2,
'e': 1,
})"""
- self.assertEqual(pprint.pformat(dummy_counter, width=20, indent=2), expected2)
+ self.assertEqual(pprint.pformat(dummy_counter, width=20, indent=2,
+ expand=True), expected2)
def test_expand_chainmap(self):
dummy_dict = {
@@ -1821,7 +1884,8 @@ def test_expand_chainmap(self):
{"corge": dummy_dict},
)
dummy_chainmap.maps.append({"garply": "waldo"})
- self.assertEqual(pprint.pformat(dummy_chainmap, width=40, indent=4),
+ self.assertEqual(pprint.pformat(dummy_chainmap, width=40, indent=4,
+ expand=True),
"""\
ChainMap(
{'foo': 'bar'},
@@ -1863,7 +1927,8 @@ def test_expand_deque(self):
dummy_deque.append(dummy_dict)
dummy_deque.extend(dummy_list)
dummy_deque.appendleft(dummy_set)
- self.assertEqual(pprint.pformat(dummy_deque, width=40, indent=4),
+ self.assertEqual(pprint.pformat(dummy_deque, width=40, indent=4,
+ expand=True),
"""\
deque([
{(1, 2, 3)},
@@ -1894,7 +1959,8 @@ def __init__(self, *args, **kwargs):
"corge": 7 })
dummy_userdict.access_count = 5
- self.assertEqual(pprint.pformat(dummy_userdict, width=40, indent=4),
+ self.assertEqual(pprint.pformat(dummy_userdict, width=40, indent=4,
+ expand=True),
"""\
{
'baz': 123,
@@ -1914,7 +1980,8 @@ def __init__(self, *args, **kwargs):
dummy_userlist = DummyUserList(["first", 2, {"key": "value"},
[4, 5, 6]])
- self.assertEqual(pprint.pformat(dummy_userlist, width=40, indent=4),
+ self.assertEqual(pprint.pformat(dummy_userlist, width=40, indent=4,
+ expand=True),
"""\
[
'first',
@@ -1926,7 +1993,7 @@ def __init__(self, *args, **kwargs):
def test_expand_dict_keys(self):
d = {"foo": 1, "bar": 2, "baz": 3, "qux": 4, "quux": 5}
self.assertEqual(
- pprint.pformat(d.keys(), width=20, indent=4),
+ pprint.pformat(d.keys(), width=20, indent=4, expand=True),
"""\
dict_keys([
'bar',
@@ -1940,7 +2007,7 @@ def test_expand_dict_keys(self):
def test_expand_dict_values(self):
d = {"foo": 1, "bar": 2, "baz": 3, "qux": 4, "quux": 5}
self.assertEqual(
- pprint.pformat(d.values(), width=20, indent=4),
+ pprint.pformat(d.values(), width=20, indent=4, expand=True),
"""\
dict_values([
1,
@@ -1954,7 +2021,7 @@ def test_expand_dict_values(self):
def test_expand_dict_items(self):
d = {"foo": 1, "bar": 2, "baz": 3, "qux": 4, "quux": 5}
self.assertEqual(
- pprint.pformat(d.items(), width=20, indent=4),
+ pprint.pformat(d.items(), width=20, indent=4, expand=True),
"""\
dict_items([
('bar', 2),
@@ -1968,7 +2035,7 @@ def test_expand_dict_items(self):
def test_expand_str(self):
s = "The quick brown fox jumped over the lazy dog " * 3
self.assertEqual(
- pprint.pformat(s, width=40, indent=4),
+ pprint.pformat(s, width=40, indent=4, expand=True),
"""\
(
'The quick brown fox jumped over '
diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py
index ac5c4296c663d0..09ee2d53f98f58 100644
--- a/Lib/test/test_stable_abi_ctypes.py
+++ b/Lib/test/test_stable_abi_ctypes.py
@@ -1032,19 +1032,15 @@ def test_windows_feature_macros(self):
'PyOS_CheckStack',
)
-EXPECTED_FEATURE_MACROS = set([
- 'HAVE_FORK',
- 'MS_WINDOWS',
- 'PY_HAVE_THREAD_NATIVE_ID',
- 'Py_REF_DEBUG',
- 'Py_TRACE_REFS',
- 'USE_STACKCHECK',
-])
-WINDOWS_FEATURE_MACROS = {
- 'HAVE_FORK': False,
- 'MS_WINDOWS': True,
- 'PY_HAVE_THREAD_NATIVE_ID': True,
- 'Py_REF_DEBUG': 'maybe',
- 'Py_TRACE_REFS': 'maybe',
- 'USE_STACKCHECK': 'maybe',
-}
+EXPECTED_FEATURE_MACROS = set(['HAVE_FORK',
+ 'MS_WINDOWS',
+ 'PY_HAVE_THREAD_NATIVE_ID',
+ 'Py_REF_DEBUG',
+ 'Py_TRACE_REFS',
+ 'USE_STACKCHECK'])
+WINDOWS_FEATURE_MACROS = {'HAVE_FORK': False,
+ 'MS_WINDOWS': True,
+ 'PY_HAVE_THREAD_NATIVE_ID': True,
+ 'Py_REF_DEBUG': 'maybe',
+ 'Py_TRACE_REFS': 'maybe',
+ 'USE_STACKCHECK': 'maybe'}
diff --git a/Lib/test/test_unittest/testmock/testhelpers.py b/Lib/test/test_unittest/testmock/testhelpers.py
index f8643552011f4e..0e82c723ec3eaa 100644
--- a/Lib/test/test_unittest/testmock/testhelpers.py
+++ b/Lib/test/test_unittest/testmock/testhelpers.py
@@ -1162,7 +1162,9 @@ def test_call_list_str(self):
mock.foo.bar().baz('fish', cat='dog')
expected = (
- "[call(1, 2), call.foo(a=3), call.foo.bar(),"
+ "[call(1, 2),\n"
+ " call.foo(a=3),\n"
+ " call.foo.bar(),\n"
" call.foo.bar().baz('fish', cat='dog')]"
)
self.assertEqual(str(mock.mock_calls), expected)
diff --git a/Misc/NEWS.d/next/Library/2026-05-18-17-17-20.gh-issue-149189.a8IooK.rst b/Misc/NEWS.d/next/Library/2026-05-18-17-17-20.gh-issue-149189.a8IooK.rst
new file mode 100644
index 00000000000000..bad027f2c71c6f
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-05-18-17-17-20.gh-issue-149189.a8IooK.rst
@@ -0,0 +1 @@
+Revert the changes to :mod:`pprint` defaults. Patch by Hugo van Kemenade.
From 081187f169556fb1b2d6a9b96f7b7e509f6ad985 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Fri, 22 May 2026 23:17:51 +0200
Subject: [PATCH 115/213] [3.15] gh-82907: Document mtime=0 for reproducible
tarfile gzip output (GH-150269) (GH-150271)
(cherry picked from commit 9df2b6ccc719b0bc0167da65b72b57f9da39398b)
Co-authored-by: Omkar Kabde
---
Doc/library/tarfile.rst | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst
index 6f1e01cf5aa6ee..9b9783d8e58013 100644
--- a/Doc/library/tarfile.rst
+++ b/Doc/library/tarfile.rst
@@ -144,7 +144,9 @@ Some facts and figures:
For modes ``'w:gz'`` and ``'w|gz'``, :func:`tarfile.open` accepts the
keyword argument *mtime* to create a gzip archive header with that mtime. By
- default, the mtime is set to the time of creation of the archive.
+ default, the mtime is set to the time of creation of the archive. Use
+ *mtime* ``0`` to generate a compressed stream that does not depend on
+ creation time, for reproducible output.
For special purposes, there is a second format for *mode*:
``'filemode|[compression]'``. :func:`tarfile.open` will return a :class:`TarFile`
From 795dd3bd3500c49c6a08281a15a9472a28f416d3 Mon Sep 17 00:00:00 2001
From: Victor Stinner
Date: Sat, 23 May 2026 08:57:27 +0200
Subject: [PATCH 116/213] [3.15] Revert "[3.15] gh-146452: Improve locking
granularity in pickle's batch_dict_exact and fix race condition (GH-150025)
(#150039)" (#150262)
Revert "[3.15] gh-146452: Improve locking granularity in pickle's batch_dict_exact and fix race condition (GH-150025) (#150039)"
This reverts commit 66ade2861fec1d6c18998710938a1c71fde5f76b.
---
...-05-18-15-30-34.gh-issue-146452.RM0EVJ.rst | 2 --
Modules/_pickle.c | 35 ++++---------------
2 files changed, 7 insertions(+), 30 deletions(-)
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-18-15-30-34.gh-issue-146452.RM0EVJ.rst
diff --git a/Misc/NEWS.d/next/Library/2026-05-18-15-30-34.gh-issue-146452.RM0EVJ.rst b/Misc/NEWS.d/next/Library/2026-05-18-15-30-34.gh-issue-146452.RM0EVJ.rst
deleted file mode 100644
index 66f9acf6c710a7..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-18-15-30-34.gh-issue-146452.RM0EVJ.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix race condition when pickling dictionaries in free threaded builds. Also
-reduce critical section cover.
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index 15d95c658d6f90..9874f9475ac029 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -3450,9 +3450,6 @@ batch_dict(PickleState *state, PicklerObject *self, PyObject *iter, PyObject *or
* Returns 0 on success, -1 on error.
*
* Note that this currently doesn't work for protocol 0.
-
- * gh-146452: Wrap the dict iteration in a critical sections to prevent
- * concurrent mutation from invalidating PyDict_Next() iteration state.
*/
static int
batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj)
@@ -3469,24 +3466,15 @@ batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj)
assert(self->proto > 0);
dict_size = PyDict_GET_SIZE(obj);
+ assert(dict_size);
/* Write in batches of BATCHSIZE. */
Py_ssize_t total = 0;
do {
if (dict_size - total == 1) {
- int next;
- Py_BEGIN_CRITICAL_SECTION(obj);
- next = PyDict_Next(obj, &ppos, &key, &value);
- if (next) {
- Py_INCREF(key);
- Py_INCREF(value);
- }
- Py_END_CRITICAL_SECTION();
- if (!next) {
- PyErr_SetString(PyExc_RuntimeError,
- "dictionary changed size during iteration");
- goto error;
- }
+ PyDict_Next(obj, &ppos, &key, &value);
+ Py_INCREF(key);
+ Py_INCREF(value);
if (save(state, self, key, 0) < 0) {
goto error;
}
@@ -3504,18 +3492,9 @@ batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj)
i = 0;
if (_Pickler_Write(self, &mark_op, 1) < 0)
return -1;
- int next;
- while (1) {
- Py_BEGIN_CRITICAL_SECTION(obj);
- next = PyDict_Next(obj, &ppos, &key, &value);
- if (next) {
- Py_INCREF(key);
- Py_INCREF(value);
- }
- Py_END_CRITICAL_SECTION();
- if (!next) {
- break;
- }
+ while (PyDict_Next(obj, &ppos, &key, &value)) {
+ Py_INCREF(key);
+ Py_INCREF(value);
if (save(state, self, key, 0) < 0) {
goto error;
}
From 77cc4428a772b190ce10ec4d383594de09a03a45 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sat, 23 May 2026 09:33:21 +0200
Subject: [PATCH 117/213] [3.15] gh-146452: Fix pickle segfault on concurrent
mutation of dict in pickle (GH-146470) (#150292)
gh-146452: Fix pickle segfault on concurrent mutation of dict in pickle (GH-146470)
(cherry picked from commit e62a61177f8b793d787e337034a740ca75c1ab44)
Co-authored-by: Farhan Saif
Co-authored-by: Kumar Aditya
---
Lib/test/test_free_threading/test_pickle.py | 44 +++++++++++++++++++
...3-26-09-30-00.gh-issue-146452.Y2N6qZ8J.rst | 2 +
Modules/_pickle.c | 14 +++++-
3 files changed, 59 insertions(+), 1 deletion(-)
create mode 100644 Lib/test/test_free_threading/test_pickle.py
create mode 100644 Misc/NEWS.d/next/Library/2026-03-26-09-30-00.gh-issue-146452.Y2N6qZ8J.rst
diff --git a/Lib/test/test_free_threading/test_pickle.py b/Lib/test/test_free_threading/test_pickle.py
new file mode 100644
index 00000000000000..85a644dc72ecb4
--- /dev/null
+++ b/Lib/test/test_free_threading/test_pickle.py
@@ -0,0 +1,44 @@
+import pickle
+import threading
+import unittest
+
+from test.support import threading_helper
+
+
+@threading_helper.requires_working_threading()
+class TestPickleFreeThreading(unittest.TestCase):
+
+ def test_pickle_dumps_with_concurrent_dict_mutation(self):
+ # gh-146452: Pickling a dict while another thread mutates it
+ # used to segfault. batch_dict_exact() iterated dict items via
+ # PyDict_Next() which returns borrowed references, and a
+ # concurrent pop/replace could free the value before Py_INCREF
+ # got to it.
+ shared = {str(i): list(range(20)) for i in range(50)}
+
+ def dumper():
+ for _ in range(1000):
+ try:
+ pickle.dumps(shared)
+ except RuntimeError:
+ # "dictionary changed size during iteration" is expected
+ pass
+
+ def mutator():
+ for j in range(1000):
+ key = str(j % 50)
+ shared[key] = list(range(j % 20))
+ if j % 10 == 0:
+ shared.pop(key, None)
+ shared[key] = [j]
+
+ threads = []
+ for _ in range(10):
+ threads.append(threading.Thread(target=dumper))
+ threads.append(threading.Thread(target=mutator))
+
+ with threading_helper.start_threads(threads):
+ pass
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/Misc/NEWS.d/next/Library/2026-03-26-09-30-00.gh-issue-146452.Y2N6qZ8J.rst b/Misc/NEWS.d/next/Library/2026-03-26-09-30-00.gh-issue-146452.Y2N6qZ8J.rst
new file mode 100644
index 00000000000000..99f3cce33497a1
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-03-26-09-30-00.gh-issue-146452.Y2N6qZ8J.rst
@@ -0,0 +1,2 @@
+Fix segfault in :mod:`pickle` when pickling a dictionary concurrently
+mutated by another thread in the free-threaded build.
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index 9874f9475ac029..7b87be23269d40 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -3452,7 +3452,7 @@ batch_dict(PickleState *state, PicklerObject *self, PyObject *iter, PyObject *or
* Note that this currently doesn't work for protocol 0.
*/
static int
-batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj)
+batch_dict_exact_impl(PickleState *state, PicklerObject *self, PyObject *obj)
{
PyObject *key = NULL, *value = NULL;
int i;
@@ -3525,6 +3525,18 @@ batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj)
return -1;
}
+/* gh-146452: Wrap the dict iteration in a critical section to prevent
+ concurrent mutation from invalidating PyDict_Next() iteration state. */
+static int
+batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj)
+{
+ int ret;
+ Py_BEGIN_CRITICAL_SECTION(obj);
+ ret = batch_dict_exact_impl(state, self, obj);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
static int
save_dict(PickleState *state, PicklerObject *self, PyObject *obj)
{
From d9d8ee503a729f34d7ffc4585ecb4fc0a3445825 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sat, 23 May 2026 10:34:48 +0200
Subject: [PATCH 118/213] [3.15] gh-150232: update Thread group parameter doc
(GH-150283) (#150297)
gh-150232: update Thread group parameter doc (GH-150283)
(cherry picked from commit 82191c6d2cdacad6751262a40a44d2cd6d390977)
Co-authored-by: My-ABC <569817555@qq.com>
---
Doc/library/threading.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst
index eca3e76d84a1cf..5d9a7b6314b166 100644
--- a/Doc/library/threading.rst
+++ b/Doc/library/threading.rst
@@ -515,7 +515,7 @@ since it is impossible to detect the termination of alien threads.
This constructor should always be called with keyword arguments. Arguments
are:
- *group* should be ``None``; reserved for future extension when a
+ *group* must be ``None`` as it is reserved for future extension when a
:class:`!ThreadGroup` class is implemented.
*target* is the callable object to be invoked by the :meth:`run` method.
From 8a162b2e270bc371f0c229e8511e7c19b3742f52 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sat, 23 May 2026 10:53:12 +0200
Subject: [PATCH 119/213] [3.15] gh-148450: `abc.register` needs to update
`type_version` when `tp_flags` is changed (GH-148623) (#150300)
gh-148450: `abc.register` needs to update `type_version` when `tp_flags` is changed (GH-148623)
(cherry picked from commit e7eaed56149aa08f7fd5012784cc1deef8e483de)
Co-authored-by: Hai Zhu
---
Lib/test/test_type_cache.py | 20 +++++++++++++++++++
...-04-15-15-48-04.gh-issue-148450.2MEVqH.rst | 1 +
Objects/typeobject.c | 16 +++++++++++++++
3 files changed, 37 insertions(+)
create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-04-15-15-48-04.gh-issue-148450.2MEVqH.rst
diff --git a/Lib/test/test_type_cache.py b/Lib/test/test_type_cache.py
index 22ad9f6243eda9..849a2afd8ed798 100644
--- a/Lib/test/test_type_cache.py
+++ b/Lib/test/test_type_cache.py
@@ -1,4 +1,5 @@
""" Tests for the internal type cache in CPython. """
+import collections.abc
import dis
import unittest
import warnings
@@ -114,6 +115,25 @@ class HolderSub(Holder):
Holder.set_value()
HolderSub.value
+ def test_abc_register_invalidates_subclass_versions(self):
+ class Parent:
+ pass
+
+ class Child(Parent):
+ pass
+
+ type_assign_version(Parent)
+ type_assign_version(Child)
+ parent_version = type_get_version(Parent)
+ child_version = type_get_version(Child)
+ if parent_version == 0 or child_version == 0:
+ self.skipTest("Could not assign valid type versions")
+
+ collections.abc.Mapping.register(Parent)
+
+ self.assertEqual(type_get_version(Parent), 0)
+ self.assertEqual(type_get_version(Child), 0)
+
@support.cpython_only
class TypeCacheWithSpecializationTests(unittest.TestCase):
def tearDown(self):
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-04-15-15-48-04.gh-issue-148450.2MEVqH.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-15-15-48-04.gh-issue-148450.2MEVqH.rst
new file mode 100644
index 00000000000000..2a7d0d9bb3a7f7
--- /dev/null
+++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-15-15-48-04.gh-issue-148450.2MEVqH.rst
@@ -0,0 +1 @@
+Fix ``abc.register()`` so it invalidates type version tags for registered classes.
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 7cca137f74be58..fc679ef747e856 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -6490,9 +6490,25 @@ set_flags_recursive(PyTypeObject *self, unsigned long mask, unsigned long flags)
void
_PyType_SetFlagsRecursive(PyTypeObject *self, unsigned long mask, unsigned long flags)
{
+ BEGIN_TYPE_LOCK();
+ /* Ideally, changing flags and invalidating the old version tag would
+ happen in one step. But type_modified_unlocked() is re-entrant and
+ cannot run with the world stopped, so we must invalidate first.
+ Immutable/static-builtin types are skipped because
+ set_flags_recursive() does not modify them. */
+ if (!PyType_HasFeature(self, Py_TPFLAGS_IMMUTABLETYPE) &&
+ (self->tp_flags & mask) != flags)
+ {
+ type_modified_unlocked(self);
+ }
+ /* Keep TYPE_LOCK held while waiting for stop-the-world so no thread
+ can reassign a version tag before the flag update. */
+ type_lock_prevent_release();
types_stop_world();
set_flags_recursive(self, mask, flags);
types_start_world();
+ type_lock_allow_release();
+ END_TYPE_LOCK();
}
/* This is similar to PyObject_GenericGetAttr(),
From ca59d7511e2484fc55b1686b5a8e745322db73ec Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sat, 23 May 2026 11:25:56 +0200
Subject: [PATCH 120/213] [3.15] gh-149816: add missing critical section on
self in buffered_iternext (GH-150295) (#150305)
gh-149816: add missing critical section on self in buffered_iternext (GH-150295)
(cherry picked from commit e8545ed3eafbf349b51ea308126a67dc70416a62)
Co-authored-by: Kumar Aditya
---
Modules/_io/bufferedio.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c
index 0fdae7b2d21004..5537947f6a51c1 100644
--- a/Modules/_io/bufferedio.c
+++ b/Modules/_io/bufferedio.c
@@ -1509,7 +1509,9 @@ buffered_iternext(PyObject *op)
tp == state->PyBufferedRandom_Type)
{
/* Skip method call overhead for speed */
+ Py_BEGIN_CRITICAL_SECTION(self);
line = _buffered_readline(self, -1);
+ Py_END_CRITICAL_SECTION();
}
else {
line = PyObject_CallMethodNoArgs((PyObject *)self,
From 6f993631501eef77ab4bad6a4f9b5ea1f6351c89 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sat, 23 May 2026 17:30:19 +0200
Subject: [PATCH 121/213] [3.15] gh-150258: Show relative percentage on Tachyon
flamegraph (GH-150266) (#150312)
gh-150258: Show relative percentage on Tachyon flamegraph (GH-150266)
When running profiling, users rarely care about the global percentage of
the runtime. Often, they want to select a function and measure child
percentages relative to that.
This PR updates the flamegraph tooltips to show both "Percentage" and
"Relative Percentage" when the user clicks a specific function.
(cherry picked from commit fad06746051f6bd95a255d49e38ebf049e965109)
Co-authored-by: Eduardo Villalpando Mello
---
.../sampling/_flamegraph_assets/flamegraph.js | 12 ++++++++++++
.../2026-05-22-18-51-09.gh-issue-150258.dh8GVK.rst | 1 +
2 files changed, 13 insertions(+)
create mode 100644 Misc/NEWS.d/next/Tools-Demos/2026-05-22-18-51-09.gh-issue-150258.dh8GVK.rst
diff --git a/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js b/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js
index 1611bf754424c1..840acf2c27d120 100644
--- a/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js
+++ b/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js
@@ -7,6 +7,7 @@ let invertedData = null;
let currentThreadFilter = 'all';
let isInverted = false;
let useModuleNames = true;
+let zoomedNodeValue = null;
// Heat colors are now defined in CSS variables (--heat-1 through --heat-8)
// and automatically switch with theme changes - no JS color arrays needed!
@@ -316,6 +317,7 @@ function createPythonTooltip(data) {
const selfSamples = d.data.self || 0;
const selfMs = (selfSamples / 1000).toFixed(2);
const percentage = ((d.data.value / data.value) * 100).toFixed(2);
+ const relativePercentage = Math.min(100, ((d.data.value / (zoomedNodeValue ?? data.value)) * 100)).toFixed(2);
const calls = d.data.calls || 0;
const childCount = d.children ? d.children.length : 0;
const source = d.data.source;
@@ -439,6 +441,11 @@ function createPythonTooltip(data) {
Percentage:${percentage}%
+ ${relativePercentage != percentage && relativePercentage != "100.00" ? `
+ Relative Percentage:
+ ${relativePercentage}%
+ ` : ''}
+
${calls > 0 ? `
Function Calls:${calls.toLocaleString()}
@@ -620,6 +627,9 @@ function createFlamegraph(tooltip, rootValue, data) {
const percentage = d.data.value / rootValue;
const level = getHeatLevel(percentage);
return heatColors[level];
+ })
+ .onClick(function (d) {
+ zoomedNodeValue = d.data.value;
});
return chart;
@@ -629,6 +639,7 @@ function renderFlamegraph(chart, data) {
d3.select("#chart").datum(data).call(chart);
window.flamegraphChart = chart;
window.flamegraphData = data;
+ zoomedNodeValue = null;
populateStats(data);
}
@@ -1269,6 +1280,7 @@ function filterDataByThread(data, threadId) {
function resetZoom() {
if (window.flamegraphChart) {
+ zoomedNodeValue = null;
window.flamegraphChart.resetZoom();
}
}
diff --git a/Misc/NEWS.d/next/Tools-Demos/2026-05-22-18-51-09.gh-issue-150258.dh8GVK.rst b/Misc/NEWS.d/next/Tools-Demos/2026-05-22-18-51-09.gh-issue-150258.dh8GVK.rst
new file mode 100644
index 00000000000000..02cad6c4f53d92
--- /dev/null
+++ b/Misc/NEWS.d/next/Tools-Demos/2026-05-22-18-51-09.gh-issue-150258.dh8GVK.rst
@@ -0,0 +1 @@
+Update the tooltip on the Tachyon flame graph to show both absolute and relative percentages.
From 6b17d1a783d3c0a9c8a35a94e24a2987807728ef Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sat, 23 May 2026 21:27:27 +0200
Subject: [PATCH 122/213] [3.15] gh-150178: Fix refcount leaks in hamt
allocation failure paths (GH-150179) (#150303)
gh-150178: Fix refcount leaks in hamt allocation failure paths (GH-150179)
(cherry picked from commit 32823af153b76b7042fbce28ea8a6e0c3c4f1ca8)
Co-authored-by: pengyu lee
---
Python/hamt.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Python/hamt.c b/Python/hamt.c
index e4719e71a5259a..95998ae5062ac7 100644
--- a/Python/hamt.c
+++ b/Python/hamt.c
@@ -702,6 +702,7 @@ hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self,
PyHamtNode_Bitmap *ret = hamt_node_bitmap_clone(self);
if (ret == NULL) {
+ Py_DECREF(sub_node);
return NULL;
}
Py_SETREF(ret->b_array[val_idx], (PyObject*)sub_node);
@@ -994,6 +995,7 @@ hamt_node_bitmap_without(PyHamtNode_Bitmap *self,
PyHamtNode_Bitmap *clone = hamt_node_bitmap_clone(self);
if (clone == NULL) {
+ Py_DECREF(sub_node);
return W_ERROR;
}
From 22c994cc928a18fd3d92b8901417e84ebcd9a5e8 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 24 May 2026 09:18:58 +0200
Subject: [PATCH 123/213] [3.15] gh-149335: Avoid JIT trace buffer asserts with
overhead above `FITNESS_INITIAL` (GH-149633) (#150245)
gh-149335: Avoid JIT trace buffer asserts with overhead above `FITNESS_INITIAL` (GH-149633)
(cherry picked from commit 441af3a93426c5e7e3c056fee27e6f4505988584)
Co-authored-by: Hai Zhu
---
Include/internal/pycore_optimizer.h | 3 +--
Include/internal/pycore_uop.h | 10 +++++---
Lib/test/test_capi/test_opt.py | 38 +++++++++++++++++++++++++++++
Python/pystate.c | 2 +-
4 files changed, 47 insertions(+), 6 deletions(-)
diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h
index 69f913ec9c3038..8c35c4416fe3c8 100644
--- a/Include/internal/pycore_optimizer.h
+++ b/Include/internal/pycore_optimizer.h
@@ -31,9 +31,8 @@ extern "C" {
* 4. A push followed by a matching return is net-zero on frame-specific
* fitness, excluding per-slot costs.
*/
-#define MAX_TARGET_LENGTH (UOP_MAX_TRACE_LENGTH / 2)
#define OPTIMIZER_EFFECTIVENESS 2
-#define FITNESS_INITIAL (MAX_TARGET_LENGTH * OPTIMIZER_EFFECTIVENESS)
+#define MAX_TARGET_LENGTH (FITNESS_INITIAL / OPTIMIZER_EFFECTIVENESS)
/* Exit quality thresholds: trace stops when fitness < exit_quality.
* Higher = trace is more willing to stop here. */
diff --git a/Include/internal/pycore_uop.h b/Include/internal/pycore_uop.h
index 320508e8b7a95e..e7f0d2c214a764 100644
--- a/Include/internal/pycore_uop.h
+++ b/Include/internal/pycore_uop.h
@@ -36,14 +36,18 @@ typedef struct _PyUOpInstruction{
#endif
} _PyUOpInstruction;
-// This is the length of the trace we translate initially.
+// Fitness is the target length of the trace we translate initially. The uop
+// buffer has a small amount of extra space for entry/loop-closing overhead.
#if defined(Py_DEBUG) && defined(_Py_JIT)
// With asserts, the stencils are a lot larger
-#define UOP_MAX_TRACE_LENGTH 1000
+#define FITNESS_INITIAL 1000
#else
-#define UOP_MAX_TRACE_LENGTH 2500
+#define FITNESS_INITIAL 2500
#endif
+#define UOP_TRACE_BUFFER_OVERHEAD 10
+#define UOP_MAX_TRACE_LENGTH (FITNESS_INITIAL + UOP_TRACE_BUFFER_OVERHEAD)
+
/* Bloom filter with m = 256
* https://en.wikipedia.org/wiki/Bloom_filter */
#ifdef HAVE_GCC_UINT128_T
diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py
index 2f606c2c6eba2d..9f0427172b5048 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -5922,6 +5922,44 @@ def __next__(self):
"""), PYTHON_JIT="1", PYTHON_JIT_STRESS="1")
self.assertEqual(result[0].rc, 0, result)
+ def test_149335_trace_buffer_guard(self):
+ # https://github.com/python/cpython/issues/149335
+
+ result = script_helper.run_python_until_end('-c', textwrap.dedent("""
+ import sys
+
+ def f1():
+ for i_3178 in 0, 2, 10:
+ mv162 = 162
+
+ mv3 = mv1 = mv_165 = mv16 = \
+ mv167 = mv168 = \
+ mv169 = \
+ mv_1403_170 = \
+ 169
+
+ mv_1403_170
+
+ mv_172 = mv_3 = mv_4 = mv175 = mv176 = mv17 = mv178 = mv179 = mv0 = mv1 = mv182 = (
+ mv3
+ ) = mv4 = mv185 = mv186 = mv187 = mv18 = mv189 = mv0 = mv1 = mv192 = mv3 = mv4 = (
+ mv195
+ ) = mv196 = mv197 = mv_198 = mv19 = mv0 = mv1 = mv2 = mv3 = mv4 = mv05 = mv06 = (
+ mv07
+ ) = mv08 = mv09 = mv0 = mv1 = mv2 = mv3 = mv4 = mv15 = mv16 = mv17 = mv18 = mv19 = (
+ mv0
+ ) = mv1 = mv_2 = mv3 = mv4 = mv_25 = mv_26 = mv_27 = mv_28 = mv_29 = mv0 = mv1 = (
+ mv2
+ ) = mv_1403 = mv4 = mv35 = mv36 = mv37 = mv38 = mv39 = mv0 = -sys.maxsize / 3
+
+ mv1 = mv_12 = mv3 = mv_14 = mv45 = sys.float_info.epsilon
+ mv46 = sys.float_info.epsilon
+
+ for i in range(15000):
+ f1()
+ """), PYTHON_JIT="1")
+ self.assertEqual(result[0].rc, 0, result)
+
def test_144068_daemon_thread_jit_cleanup(self):
result = script_helper.run_python_until_end('-c', textwrap.dedent("""
import threading
diff --git a/Python/pystate.c b/Python/pystate.c
index ff712019affbf9..530bd567b770be 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -634,7 +634,7 @@ init_interpreter(PyInterpreterState *interp,
// Trace fitness configuration
init_policy(&interp->opt_config.fitness_initial,
"PYTHON_JIT_FITNESS_INITIAL",
- FITNESS_INITIAL, EXIT_QUALITY_CLOSE_LOOP, UOP_MAX_TRACE_LENGTH - 1);
+ FITNESS_INITIAL, EXIT_QUALITY_CLOSE_LOOP, FITNESS_INITIAL);
interp->opt_config.specialization_enabled = !is_env_enabled("PYTHON_SPECIALIZATION_OFF");
interp->opt_config.uops_optimize_enabled = !is_env_disabled("PYTHON_UOPS_OPTIMIZE");
From c3d21e5a11769ae318cb5c4c96a381a22629654e Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 24 May 2026 14:02:45 +0200
Subject: [PATCH 124/213] [3.15] gh-148932: Docs / `profiling.sampling` Windows
limitations (GH-150272) (#150330)
gh-148932: Docs / `profiling.sampling` Windows limitations (GH-150272)
(cherry picked from commit 0f32750fe26428de5e439803cf57f51847c81ce8)
Co-authored-by: Eduardo Villalpando Mello
---
Doc/library/profiling.sampling.rst | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Doc/library/profiling.sampling.rst b/Doc/library/profiling.sampling.rst
index aeb1a429b58515..39b6ea4e31cde7 100644
--- a/Doc/library/profiling.sampling.rst
+++ b/Doc/library/profiling.sampling.rst
@@ -387,6 +387,11 @@ This requires one of:
On Windows, the profiler requires administrative privileges or the
``SeDebugPrivilege`` privilege to read another process's memory.
+*Note*: On Windows, ``python -m profiling.sampling`` fails inside a virtual
+environment because the venv's ``python.exe`` is just a launcher shim that
+re-executes the base interpreter as a child process. The shim itself isn't
+a Python process and has no ``PyRuntime`` section to attach to. Instead,
+run it from the global Python installation.
Version compatibility
---------------------
From 1b7ab11cd68b645e8be5f18730644a0245d76b47 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 24 May 2026 15:09:13 +0200
Subject: [PATCH 125/213] [3.15] gh-150285: Fix too long docstrings in the
_remote_debugging module (GH-150289) (#150334)
gh-150285: Fix too long docstrings in the _remote_debugging module (GH-150289)
(cherry picked from commit cdc499ae775e5204ef6bbb0a63bb00e85b0b6b72)
Co-authored-by: Serhiy Storchaka
---
Modules/_remote_debugging/clinic/module.c.h | 197 +++++++++-------
Modules/_remote_debugging/module.c | 235 +++++++++++---------
2 files changed, 251 insertions(+), 181 deletions(-)
diff --git a/Modules/_remote_debugging/clinic/module.c.h b/Modules/_remote_debugging/clinic/module.c.h
index 78b1d3e8d80962..d01f3d13e85f09 100644
--- a/Modules/_remote_debugging/clinic/module.c.h
+++ b/Modules/_remote_debugging/clinic/module.c.h
@@ -21,33 +21,37 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder___init____doc__,
"\n"
"Args:\n"
" pid: Process ID of the target Python process to debug\n"
-" all_threads: If True, initialize state for all threads in the process.\n"
-" If False, only initialize for the main thread.\n"
+" all_threads: If True, initialize state for all threads in the\n"
+" process. If False, only initialize for the main thread.\n"
" only_active_thread: If True, only sample the thread holding the GIL.\n"
-" mode: Profiling mode: 0=WALL (wall-time), 1=CPU (cpu-time), 2=GIL (gil-time).\n"
-" Cannot be used together with all_threads=True.\n"
-" debug: If True, chain exceptions to explain the sequence of events that\n"
-" lead to the exception.\n"
-" skip_non_matching_threads: If True, skip threads that don\'t match the selected mode.\n"
-" If False, include all threads regardless of mode.\n"
-" native: If True, include artificial \"\" frames to denote calls to\n"
-" non-Python code.\n"
-" gc: If True, include artificial \"\" frames to denote active garbage\n"
-" collection.\n"
-" opcodes: If True, gather bytecode opcode information for instruction-level\n"
-" profiling.\n"
-" cache_frames: If True, enable frame caching optimization to avoid re-reading\n"
-" unchanged parent frames between samples.\n"
-" stats: If True, collect statistics about cache hits, memory reads, etc.\n"
-" Use get_stats() to retrieve the collected statistics.\n"
-"\n"
-"The RemoteUnwinder provides functionality to inspect and debug a running Python\n"
-"process, including examining thread states, stack frames and other runtime data.\n"
+" mode: Profiling mode: 0=WALL (wall-time), 1=CPU (cpu-time), 2=GIL\n"
+" (gil-time). Cannot be used together with all_threads=True.\n"
+" debug: If True, chain exceptions to explain the sequence of events\n"
+" that lead to the exception.\n"
+" skip_non_matching_threads: If True, skip threads that don\'t match\n"
+" the selected mode. If False, include all threads regardless of\n"
+" mode.\n"
+" native: If True, include artificial \"\" frames to denote\n"
+" calls to non-Python code.\n"
+" gc: If True, include artificial \"\" frames to denote active\n"
+" garbage collection.\n"
+" opcodes: If True, gather bytecode opcode information for\n"
+" instruction-level profiling.\n"
+" cache_frames: If True, enable frame caching optimization to avoid\n"
+" re-reading unchanged parent frames between samples.\n"
+" stats: If True, collect statistics about cache hits, memory reads,\n"
+" etc. Use get_stats() to retrieve the collected statistics.\n"
+"\n"
+"The RemoteUnwinder provides functionality to inspect and debug a running\n"
+"Python process, including examining thread states, stack frames and\n"
+"other runtime data.\n"
"\n"
"Raises:\n"
" PermissionError: If access to the target process is denied\n"
-" OSError: If unable to attach to the target process or access its memory\n"
-" RuntimeError: If unable to read debug information from the target process\n"
+" OSError: If unable to attach to the target process or access its\n"
+" memory\n"
+" RuntimeError: If unable to read debug information from the target\n"
+" process\n"
" ValueError: If both all_threads and only_active_thread are True");
static int
@@ -217,16 +221,21 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder_get_stack_trace__doc__,
"\n"
"Returns stack traces for all interpreters and threads in process.\n"
"\n"
-"Each element in the returned list is a tuple of (interpreter_id, thread_list), where:\n"
+"Each element in the returned list is a tuple of (interpreter_id,\n"
+"thread_list), where:\n"
"- interpreter_id is the interpreter identifier\n"
-"- thread_list is a list of tuples (thread_id, frame_list) for threads in that interpreter\n"
+"- thread_list is a list of tuples (thread_id, frame_list) for\n"
+" threads in that interpreter\n"
" - thread_id is the OS thread identifier\n"
-" - frame_list is a list of tuples (function_name, filename, line_number) representing\n"
-" the Python stack frames for that thread, ordered from most recent to oldest\n"
+" - frame_list is a list of tuples (function_name, filename,\n"
+" line_number) representing the Python stack frames for that\n"
+" thread, ordered from most recent to oldest\n"
"\n"
"The threads returned depend on the initialization parameters:\n"
-"- If only_active_thread was True: returns only the thread holding the GIL across all interpreters\n"
-"- If all_threads was True: returns all threads across all interpreters\n"
+"- If only_active_thread was True: returns only the thread holding\n"
+" the GIL across all interpreters\n"
+"- If all_threads was True: returns all threads across all\n"
+" interpreters\n"
"- Otherwise: returns only the main thread of each interpreter\n"
"\n"
"Example:\n"
@@ -250,10 +259,12 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder_get_stack_trace__doc__,
" ]\n"
"\n"
"Raises:\n"
-" RuntimeError: If there is an error copying memory from the target process\n"
+" RuntimeError: If there is an error copying memory from the\n"
+" target process\n"
" OSError: If there is an error accessing the target process\n"
" PermissionError: If access to the target process is denied\n"
-" UnicodeDecodeError: If there is an error decoding strings from the target process");
+" UnicodeDecodeError: If there is an error decoding strings from\n"
+" the target process");
#define _REMOTE_DEBUGGING_REMOTEUNWINDER_GET_STACK_TRACE_METHODDEF \
{"get_stack_trace", (PyCFunction)_remote_debugging_RemoteUnwinder_get_stack_trace, METH_NOARGS, _remote_debugging_RemoteUnwinder_get_stack_trace__doc__},
@@ -279,20 +290,25 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder_get_all_awaited_by__doc__,
"\n"
"Get all tasks and their awaited_by relationships from the remote process.\n"
"\n"
-"This provides a tree structure showing which tasks are waiting for other tasks.\n"
+"This provides a tree structure showing which tasks are waiting for\n"
+"other tasks.\n"
"\n"
"For each task, returns:\n"
-"1. The call stack frames leading to where the task is currently executing\n"
+"1. The call stack frames leading to where the task is currently\n"
+" executing\n"
"2. The name of the task\n"
-"3. A list of tasks that this task is waiting for, with their own frames/names/etc\n"
+"3. A list of tasks that this task is waiting for, with their own\n"
+" frames/names/etc\n"
"\n"
"Returns a list of [frames, task_name, subtasks] where:\n"
-"- frames: List of (func_name, filename, lineno) showing the call stack\n"
+"- frames: List of (func_name, filename, lineno) showing the call\n"
+" stack\n"
"- task_name: String identifier for the task\n"
"- subtasks: List of tasks being awaited by this task, in same format\n"
"\n"
"Raises:\n"
-" RuntimeError: If AsyncioDebug section is not available in the remote process\n"
+" RuntimeError: If AsyncioDebug section is not available in the\n"
+" remote process\n"
" MemoryError: If memory allocation fails\n"
" OSError: If reading from the remote process fails\n"
"\n"
@@ -336,14 +352,16 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder_get_async_stack_trace__doc__,
"\n"
"Get the currently running async tasks and their dependency graphs from the remote process.\n"
"\n"
-"This returns information about running tasks and all tasks that are waiting for them,\n"
-"forming a complete dependency graph for each thread\'s active task.\n"
+"This returns information about running tasks and all tasks that are\n"
+"waiting for them, forming a complete dependency graph for each\n"
+"thread\'s active task.\n"
"\n"
-"For each thread with a running task, returns the running task plus all tasks that\n"
-"transitively depend on it (tasks waiting for the running task, tasks waiting for\n"
-"those tasks, etc.).\n"
+"For each thread with a running task, returns the running task plus\n"
+"all tasks that transitively depend on it (tasks waiting for the\n"
+"running task, tasks waiting for those tasks, etc.).\n"
"\n"
-"Returns a list of per-thread results, where each thread result contains:\n"
+"Returns a list of per-thread results, where each thread result\n"
+"contains:\n"
"- Thread ID\n"
"- List of task information for the running task and all its waiters\n"
"\n"
@@ -354,11 +372,13 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder_get_async_stack_trace__doc__,
"- List of tasks waiting for this task (recursive structure)\n"
"\n"
"Raises:\n"
-" RuntimeError: If AsyncioDebug section is not available in the target process\n"
+" RuntimeError: If AsyncioDebug section is not available in the\n"
+" target process\n"
" MemoryError: If memory allocation fails\n"
" OSError: If reading from the remote process fails\n"
"\n"
-"Example output (similar structure to get_all_awaited_by but only for running tasks):\n"
+"Example output (similar structure to get_all_awaited_by but only for\n"
+"running tasks):\n"
"[\n"
" (140234, [\n"
" (4345585712, \'main_task\',\n"
@@ -403,23 +423,34 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder_get_stats__doc__,
" - total_samples: Total number of get_stack_trace calls\n"
" - frame_cache_hits: Full cache hits (entire stack unchanged)\n"
" - frame_cache_misses: Cache misses requiring full walk\n"
-" - frame_cache_partial_hits: Partial hits (stopped at cached frame)\n"
+" - frame_cache_partial_hits: Partial hits (stopped at cached\n"
+" frame)\n"
" - frames_read_from_cache: Total frames retrieved from cache\n"
-" - frames_read_from_memory: Total frames read from remote memory\n"
+" - frames_read_from_memory: Total frames read from remote\n"
+" memory\n"
" - memory_reads: Total remote memory read operations\n"
" - memory_bytes_read: Total bytes read from remote memory\n"
" - code_object_cache_hits: Code object cache hits\n"
" - code_object_cache_misses: Code object cache misses\n"
-" - stale_cache_invalidations: Times stale cache entries were cleared\n"
+" - stale_cache_invalidations: Times stale cache entries were\n"
+" cleared\n"
" - batched_read_attempts: Batched remote-read attempts\n"
-" - batched_read_successes: Attempts that read all requested segments\n"
-" - batched_read_misses: Attempts that fell back or partially read\n"
-" - batched_read_segments_requested: Segments requested by batched reads\n"
-" - batched_read_segments_completed: Segments completed by batched reads\n"
-" - frame_cache_hit_rate: Percentage of samples that hit the cache\n"
-" - code_object_cache_hit_rate: Percentage of code object lookups that hit cache\n"
-" - batched_read_success_rate: Percentage of batched reads that completed all segments\n"
-" - batched_read_segment_completion_rate: Percentage of requested segments read by batched reads\n"
+" - batched_read_successes: Attempts that read all requested\n"
+" segments\n"
+" - batched_read_misses: Attempts that fell back or partially\n"
+" read\n"
+" - batched_read_segments_requested: Segments requested by\n"
+" batched reads\n"
+" - batched_read_segments_completed: Segments completed by\n"
+" batched reads\n"
+" - frame_cache_hit_rate: Percentage of samples that hit the\n"
+" cache\n"
+" - code_object_cache_hit_rate: Percentage of code object\n"
+" lookups that hit cache\n"
+" - batched_read_success_rate: Percentage of batched reads\n"
+" that completed all segments\n"
+" - batched_read_segment_completion_rate: Percentage of\n"
+" requested segments read by batched reads\n"
"\n"
"Raises:\n"
" RuntimeError: If stats collection was not enabled (stats=False)");
@@ -449,9 +480,11 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder_pause_threads__doc__,
"Pause all threads in the target process.\n"
"\n"
"This stops all threads in the target process to allow for consistent\n"
-"memory reads during sampling. Must be paired with a call to resume_threads().\n"
+"memory reads during sampling. Must be paired with a call to\n"
+"resume_threads().\n"
"\n"
-"Returns True if threads were successfully paused, False if they were already paused.\n"
+"Returns True if threads were successfully paused, False if they were\n"
+"already paused.\n"
"\n"
"Raises:\n"
" RuntimeError: If there is an error stopping the threads");
@@ -480,9 +513,11 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder_resume_threads__doc__,
"\n"
"Resume all threads in the target process.\n"
"\n"
-"This resumes threads that were previously paused with pause_threads().\n"
+"This resumes threads that were previously paused with\n"
+"pause_threads().\n"
"\n"
-"Returns True if threads were successfully resumed, False if they were not paused.");
+"Returns True if threads were successfully resumed, False if they\n"
+"were not paused.");
#define _REMOTE_DEBUGGING_REMOTEUNWINDER_RESUME_THREADS_METHODDEF \
{"resume_threads", (PyCFunction)_remote_debugging_RemoteUnwinder_resume_threads, METH_NOARGS, _remote_debugging_RemoteUnwinder_resume_threads__doc__},
@@ -510,16 +545,18 @@ PyDoc_STRVAR(_remote_debugging_GCMonitor___init____doc__,
"\n"
"Args:\n"
" pid: Process ID of the target Python process to monitor\n"
-" debug: If True, chain exceptions to explain the sequence of events that\n"
-" lead to the exception.\n"
+" debug: If True, chain exceptions to explain the sequence of\n"
+" events that lead to the exception.\n"
"\n"
-"The GCMonitor provides functionality to read GC statistics from a running\n"
-"Python process.\n"
+"The GCMonitor provides functionality to read GC statistics from\n"
+"a running Python process.\n"
"\n"
"Raises:\n"
" PermissionError: If access to the target process is denied\n"
-" OSError: If unable to attach to the target process or access its memory\n"
-" RuntimeError: If unable to read debug information from the target process");
+" OSError: If unable to attach to the target process or access\n"
+" its memory\n"
+" RuntimeError: If unable to read debug information from the\n"
+" target process");
static int
_remote_debugging_GCMonitor___init___impl(GCMonitorObject *self, int pid,
@@ -612,8 +649,8 @@ PyDoc_STRVAR(_remote_debugging_GCMonitor_get_gc_stats__doc__,
" - duration: Total collection time, in seconds.\n"
"\n"
"Raises:\n"
-" RuntimeError: If the target process cannot be inspected or if its\n"
-" debug offsets or GC stats layout are incompatible.");
+" RuntimeError: If the target process cannot be inspected or if\n"
+" its debug offsets or GC stats layout are incompatible.");
#define _REMOTE_DEBUGGING_GCMONITOR_GET_GC_STATS_METHODDEF \
{"get_gc_stats", _PyCFunction_CAST(_remote_debugging_GCMonitor_get_gc_stats), METH_FASTCALL|METH_KEYWORDS, _remote_debugging_GCMonitor_get_gc_stats__doc__},
@@ -688,7 +725,8 @@ PyDoc_STRVAR(_remote_debugging_BinaryWriter___init____doc__,
"Arguments:\n"
" filename: Path to output file\n"
" sample_interval_us: Sampling interval in microseconds\n"
-" start_time_us: Start timestamp in microseconds (from time.monotonic() * 1e6)\n"
+" start_time_us: Start timestamp in microseconds (from\n"
+" time.monotonic() * 1e6)\n"
" compression: 0=none, 1=zstd (default: 0)\n"
"\n"
"Use as a context manager or call finalize() when done.");
@@ -774,7 +812,8 @@ PyDoc_STRVAR(_remote_debugging_BinaryWriter_write_sample__doc__,
"\n"
"Arguments:\n"
" stack_frames: List of InterpreterInfo objects\n"
-" timestamp_us: Current timestamp in microseconds (from time.monotonic() * 1e6)");
+" timestamp_us: Current timestamp in microseconds (from\n"
+" time.monotonic() * 1e6)");
#define _REMOTE_DEBUGGING_BINARYWRITER_WRITE_SAMPLE_METHODDEF \
{"write_sample", _PyCFunction_CAST(_remote_debugging_BinaryWriter_write_sample), METH_FASTCALL|METH_KEYWORDS, _remote_debugging_BinaryWriter_write_sample__doc__},
@@ -976,8 +1015,9 @@ PyDoc_STRVAR(_remote_debugging_BinaryWriter_get_stats__doc__,
"\n"
"Get encoding statistics for the writer.\n"
"\n"
-"Returns a dict with encoding statistics including repeat/full/suffix/pop-push\n"
-"record counts, frames written/saved, and compression ratio.");
+"Returns a dict with encoding statistics including\n"
+"repeat/full/suffix/pop-push record counts, frames written/saved, and\n"
+"compression ratio.");
#define _REMOTE_DEBUGGING_BINARYWRITER_GET_STATS_METHODDEF \
{"get_stats", (PyCFunction)_remote_debugging_BinaryWriter_get_stats, METH_NOARGS, _remote_debugging_BinaryWriter_get_stats__doc__},
@@ -1155,8 +1195,8 @@ PyDoc_STRVAR(_remote_debugging_BinaryReader_get_stats__doc__,
"\n"
"Get reconstruction statistics from replay.\n"
"\n"
-"Returns a dict with statistics about record types decoded and samples\n"
-"reconstructed during replay.");
+"Returns a dict with statistics about record types decoded and\n"
+"samples reconstructed during replay.");
#define _REMOTE_DEBUGGING_BINARYREADER_GET_STATS_METHODDEF \
{"get_stats", (PyCFunction)_remote_debugging_BinaryReader_get_stats, METH_NOARGS, _remote_debugging_BinaryReader_get_stats__doc__},
@@ -1319,11 +1359,12 @@ PyDoc_STRVAR(_remote_debugging_get_child_pids__doc__,
" If True, return all descendants (children, grandchildren, etc.).\n"
" If False, return only direct children.\n"
"\n"
-"Returns a list of child process IDs. Returns an empty list if no children\n"
-"are found.\n"
+"Returns a list of child process IDs. Returns an empty list if no\n"
+"children are found.\n"
"\n"
-"This function provides a snapshot of child processes at a moment in time.\n"
-"Child processes may exit or new ones may be created after the list is returned.\n"
+"This function provides a snapshot of child processes at a moment in\n"
+"time. Child processes may exit or new ones may be created after the\n"
+"list is returned.\n"
"\n"
"Raises:\n"
" OSError: If unable to enumerate processes\n"
@@ -1547,4 +1588,4 @@ _remote_debugging_get_gc_stats(PyObject *module, PyObject *const *args, Py_ssize
exit:
return return_value;
}
-/*[clinic end generated code: output=884914b100e9c90c input=a9049054013a1b77]*/
+/*[clinic end generated code: output=a3df14a6ab7f2998 input=a9049054013a1b77]*/
diff --git a/Modules/_remote_debugging/module.c b/Modules/_remote_debugging/module.c
index ae2f7e7f31ba77..3e60a7c2f794ad 100644
--- a/Modules/_remote_debugging/module.c
+++ b/Modules/_remote_debugging/module.c
@@ -280,7 +280,6 @@ class _remote_debugging.RemoteUnwinder "RemoteUnwinderObject *" "&RemoteUnwinder
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
_remote_debugging.RemoteUnwinder.__init__
pid: int
*
@@ -299,33 +298,37 @@ Initialize a new RemoteUnwinder object for debugging a remote Python process.
Args:
pid: Process ID of the target Python process to debug
- all_threads: If True, initialize state for all threads in the process.
- If False, only initialize for the main thread.
+ all_threads: If True, initialize state for all threads in the
+ process. If False, only initialize for the main thread.
only_active_thread: If True, only sample the thread holding the GIL.
- mode: Profiling mode: 0=WALL (wall-time), 1=CPU (cpu-time), 2=GIL (gil-time).
- Cannot be used together with all_threads=True.
- debug: If True, chain exceptions to explain the sequence of events that
- lead to the exception.
- skip_non_matching_threads: If True, skip threads that don't match the selected mode.
- If False, include all threads regardless of mode.
- native: If True, include artificial "" frames to denote calls to
- non-Python code.
- gc: If True, include artificial "" frames to denote active garbage
- collection.
- opcodes: If True, gather bytecode opcode information for instruction-level
- profiling.
- cache_frames: If True, enable frame caching optimization to avoid re-reading
- unchanged parent frames between samples.
- stats: If True, collect statistics about cache hits, memory reads, etc.
- Use get_stats() to retrieve the collected statistics.
-
-The RemoteUnwinder provides functionality to inspect and debug a running Python
-process, including examining thread states, stack frames and other runtime data.
+ mode: Profiling mode: 0=WALL (wall-time), 1=CPU (cpu-time), 2=GIL
+ (gil-time). Cannot be used together with all_threads=True.
+ debug: If True, chain exceptions to explain the sequence of events
+ that lead to the exception.
+ skip_non_matching_threads: If True, skip threads that don't match
+ the selected mode. If False, include all threads regardless of
+ mode.
+ native: If True, include artificial "" frames to denote
+ calls to non-Python code.
+ gc: If True, include artificial "" frames to denote active
+ garbage collection.
+ opcodes: If True, gather bytecode opcode information for
+ instruction-level profiling.
+ cache_frames: If True, enable frame caching optimization to avoid
+ re-reading unchanged parent frames between samples.
+ stats: If True, collect statistics about cache hits, memory reads,
+ etc. Use get_stats() to retrieve the collected statistics.
+
+The RemoteUnwinder provides functionality to inspect and debug a running
+Python process, including examining thread states, stack frames and
+other runtime data.
Raises:
PermissionError: If access to the target process is denied
- OSError: If unable to attach to the target process or access its memory
- RuntimeError: If unable to read debug information from the target process
+ OSError: If unable to attach to the target process or access its
+ memory
+ RuntimeError: If unable to read debug information from the target
+ process
ValueError: If both all_threads and only_active_thread are True
[clinic start generated code]*/
@@ -338,7 +341,7 @@ _remote_debugging_RemoteUnwinder___init___impl(RemoteUnwinderObject *self,
int native, int gc,
int opcodes, int cache_frames,
int stats)
-/*[clinic end generated code: output=0031f743f4b9ad52 input=8fb61b24102dec6e]*/
+/*[clinic end generated code: output=0031f743f4b9ad52 input=9d25ae328d62626d]*/
{
// Validate that all_threads and only_active_thread are not both True
if (all_threads && only_active_thread) {
@@ -645,22 +648,26 @@ read_interp_state_and_maybe_thread_frame(
}
/*[clinic input]
-@permit_long_docstring_body
@critical_section
_remote_debugging.RemoteUnwinder.get_stack_trace
Returns stack traces for all interpreters and threads in process.
-Each element in the returned list is a tuple of (interpreter_id, thread_list), where:
+Each element in the returned list is a tuple of (interpreter_id,
+thread_list), where:
- interpreter_id is the interpreter identifier
-- thread_list is a list of tuples (thread_id, frame_list) for threads in that interpreter
+- thread_list is a list of tuples (thread_id, frame_list) for
+ threads in that interpreter
- thread_id is the OS thread identifier
- - frame_list is a list of tuples (function_name, filename, line_number) representing
- the Python stack frames for that thread, ordered from most recent to oldest
+ - frame_list is a list of tuples (function_name, filename,
+ line_number) representing the Python stack frames for that
+ thread, ordered from most recent to oldest
The threads returned depend on the initialization parameters:
-- If only_active_thread was True: returns only the thread holding the GIL across all interpreters
-- If all_threads was True: returns all threads across all interpreters
+- If only_active_thread was True: returns only the thread holding
+ the GIL across all interpreters
+- If all_threads was True: returns all threads across all
+ interpreters
- Otherwise: returns only the main thread of each interpreter
Example:
@@ -684,16 +691,18 @@ The threads returned depend on the initialization parameters:
]
Raises:
- RuntimeError: If there is an error copying memory from the target process
+ RuntimeError: If there is an error copying memory from the
+ target process
OSError: If there is an error accessing the target process
PermissionError: If access to the target process is denied
- UnicodeDecodeError: If there is an error decoding strings from the target process
+ UnicodeDecodeError: If there is an error decoding strings from
+ the target process
[clinic start generated code]*/
static PyObject *
_remote_debugging_RemoteUnwinder_get_stack_trace_impl(RemoteUnwinderObject *self)
-/*[clinic end generated code: output=666192b90c69d567 input=bcff01c73cccc1c0]*/
+/*[clinic end generated code: output=666192b90c69d567 input=86a992b853f48aa9]*/
{
STATS_INC(self, total_samples);
@@ -893,26 +902,30 @@ _remote_debugging_RemoteUnwinder_get_stack_trace_impl(RemoteUnwinderObject *self
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
@critical_section
_remote_debugging.RemoteUnwinder.get_all_awaited_by
Get all tasks and their awaited_by relationships from the remote process.
-This provides a tree structure showing which tasks are waiting for other tasks.
+This provides a tree structure showing which tasks are waiting for
+other tasks.
For each task, returns:
-1. The call stack frames leading to where the task is currently executing
+1. The call stack frames leading to where the task is currently
+ executing
2. The name of the task
-3. A list of tasks that this task is waiting for, with their own frames/names/etc
+3. A list of tasks that this task is waiting for, with their own
+ frames/names/etc
Returns a list of [frames, task_name, subtasks] where:
-- frames: List of (func_name, filename, lineno) showing the call stack
+- frames: List of (func_name, filename, lineno) showing the call
+ stack
- task_name: String identifier for the task
- subtasks: List of tasks being awaited by this task, in same format
Raises:
- RuntimeError: If AsyncioDebug section is not available in the remote process
+ RuntimeError: If AsyncioDebug section is not available in the
+ remote process
MemoryError: If memory allocation fails
OSError: If reading from the remote process fails
@@ -939,7 +952,7 @@ Example output:
static PyObject *
_remote_debugging_RemoteUnwinder_get_all_awaited_by_impl(RemoteUnwinderObject *self)
-/*[clinic end generated code: output=6a49cd345e8aec53 input=307f754cbe38250c]*/
+/*[clinic end generated code: output=6a49cd345e8aec53 input=c22bfee0612e0b69]*/
{
if (ensure_async_debug_offsets(self) < 0) {
return NULL;
@@ -984,20 +997,21 @@ _remote_debugging_RemoteUnwinder_get_all_awaited_by_impl(RemoteUnwinderObject *s
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
@critical_section
_remote_debugging.RemoteUnwinder.get_async_stack_trace
Get the currently running async tasks and their dependency graphs from the remote process.
-This returns information about running tasks and all tasks that are waiting for them,
-forming a complete dependency graph for each thread's active task.
+This returns information about running tasks and all tasks that are
+waiting for them, forming a complete dependency graph for each
+thread's active task.
-For each thread with a running task, returns the running task plus all tasks that
-transitively depend on it (tasks waiting for the running task, tasks waiting for
-those tasks, etc.).
+For each thread with a running task, returns the running task plus
+all tasks that transitively depend on it (tasks waiting for the
+running task, tasks waiting for those tasks, etc.).
-Returns a list of per-thread results, where each thread result contains:
+Returns a list of per-thread results, where each thread result
+contains:
- Thread ID
- List of task information for the running task and all its waiters
@@ -1008,11 +1022,13 @@ Each task info contains:
- List of tasks waiting for this task (recursive structure)
Raises:
- RuntimeError: If AsyncioDebug section is not available in the target process
+ RuntimeError: If AsyncioDebug section is not available in the
+ target process
MemoryError: If memory allocation fails
OSError: If reading from the remote process fails
-Example output (similar structure to get_all_awaited_by but only for running tasks):
+Example output (similar structure to get_all_awaited_by but only for
+running tasks):
[
# Thread 140234 results
(140234, [
@@ -1031,7 +1047,7 @@ Example output (similar structure to get_all_awaited_by but only for running tas
static PyObject *
_remote_debugging_RemoteUnwinder_get_async_stack_trace_impl(RemoteUnwinderObject *self)
-/*[clinic end generated code: output=6433d52b55e87bbe input=6129b7d509a887c9]*/
+/*[clinic end generated code: output=6433d52b55e87bbe input=bc802e4221c99399]*/
{
if (ensure_async_debug_offsets(self) < 0) {
return NULL;
@@ -1060,7 +1076,6 @@ _remote_debugging_RemoteUnwinder_get_async_stack_trace_impl(RemoteUnwinderObject
}
/*[clinic input]
-@permit_long_docstring_body
@critical_section
_remote_debugging.RemoteUnwinder.get_stats
@@ -1075,23 +1090,34 @@ RemoteUnwinder was created with stats=True.
- total_samples: Total number of get_stack_trace calls
- frame_cache_hits: Full cache hits (entire stack unchanged)
- frame_cache_misses: Cache misses requiring full walk
- - frame_cache_partial_hits: Partial hits (stopped at cached frame)
+ - frame_cache_partial_hits: Partial hits (stopped at cached
+ frame)
- frames_read_from_cache: Total frames retrieved from cache
- - frames_read_from_memory: Total frames read from remote memory
+ - frames_read_from_memory: Total frames read from remote
+ memory
- memory_reads: Total remote memory read operations
- memory_bytes_read: Total bytes read from remote memory
- code_object_cache_hits: Code object cache hits
- code_object_cache_misses: Code object cache misses
- - stale_cache_invalidations: Times stale cache entries were cleared
+ - stale_cache_invalidations: Times stale cache entries were
+ cleared
- batched_read_attempts: Batched remote-read attempts
- - batched_read_successes: Attempts that read all requested segments
- - batched_read_misses: Attempts that fell back or partially read
- - batched_read_segments_requested: Segments requested by batched reads
- - batched_read_segments_completed: Segments completed by batched reads
- - frame_cache_hit_rate: Percentage of samples that hit the cache
- - code_object_cache_hit_rate: Percentage of code object lookups that hit cache
- - batched_read_success_rate: Percentage of batched reads that completed all segments
- - batched_read_segment_completion_rate: Percentage of requested segments read by batched reads
+ - batched_read_successes: Attempts that read all requested
+ segments
+ - batched_read_misses: Attempts that fell back or partially
+ read
+ - batched_read_segments_requested: Segments requested by
+ batched reads
+ - batched_read_segments_completed: Segments completed by
+ batched reads
+ - frame_cache_hit_rate: Percentage of samples that hit the
+ cache
+ - code_object_cache_hit_rate: Percentage of code object
+ lookups that hit cache
+ - batched_read_success_rate: Percentage of batched reads
+ that completed all segments
+ - batched_read_segment_completion_rate: Percentage of
+ requested segments read by batched reads
Raises:
RuntimeError: If stats collection was not enabled (stats=False)
@@ -1099,7 +1125,7 @@ RemoteUnwinder was created with stats=True.
static PyObject *
_remote_debugging_RemoteUnwinder_get_stats_impl(RemoteUnwinderObject *self)
-/*[clinic end generated code: output=21e36477122be2a0 input=0392d62b278e9c35]*/
+/*[clinic end generated code: output=21e36477122be2a0 input=87905c65038fb06e]*/
{
if (!self->collect_stats) {
PyErr_SetString(PyExc_RuntimeError,
@@ -1192,16 +1218,17 @@ _remote_debugging_RemoteUnwinder_get_stats_impl(RemoteUnwinderObject *self)
}
/*[clinic input]
-@permit_long_docstring_body
@critical_section
_remote_debugging.RemoteUnwinder.pause_threads
Pause all threads in the target process.
This stops all threads in the target process to allow for consistent
-memory reads during sampling. Must be paired with a call to resume_threads().
+memory reads during sampling. Must be paired with a call to
+resume_threads().
-Returns True if threads were successfully paused, False if they were already paused.
+Returns True if threads were successfully paused, False if they were
+already paused.
Raises:
RuntimeError: If there is an error stopping the threads
@@ -1209,7 +1236,7 @@ Returns True if threads were successfully paused, False if they were already pau
static PyObject *
_remote_debugging_RemoteUnwinder_pause_threads_impl(RemoteUnwinderObject *self)
-/*[clinic end generated code: output=aaf2bdc0a725750c input=d8a266f19a81c67e]*/
+/*[clinic end generated code: output=aaf2bdc0a725750c input=b91dde5517c9dde2]*/
{
#ifdef Py_REMOTE_DEBUG_SUPPORTS_BLOCKING
if (self->threads_stopped) {
@@ -1231,20 +1258,21 @@ _remote_debugging_RemoteUnwinder_pause_threads_impl(RemoteUnwinderObject *self)
}
/*[clinic input]
-@permit_long_docstring_body
@critical_section
_remote_debugging.RemoteUnwinder.resume_threads
Resume all threads in the target process.
-This resumes threads that were previously paused with pause_threads().
+This resumes threads that were previously paused with
+pause_threads().
-Returns True if threads were successfully resumed, False if they were not paused.
+Returns True if threads were successfully resumed, False if they
+were not paused.
[clinic start generated code]*/
static PyObject *
_remote_debugging_RemoteUnwinder_resume_threads_impl(RemoteUnwinderObject *self)
-/*[clinic end generated code: output=8d6781ea37095536 input=16baaaab007f4259]*/
+/*[clinic end generated code: output=8d6781ea37095536 input=130758d55d46897a]*/
{
#ifdef Py_REMOTE_DEBUG_SUPPORTS_BLOCKING
if (!self->threads_stopped) {
@@ -1382,7 +1410,6 @@ class _remote_debugging.GCMonitor "GCMonitorObject *" "&GCMonitor_Type"
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
_remote_debugging.GCMonitor.__init__
pid: int
*
@@ -1392,22 +1419,24 @@ Initialize a new GCMonitor object for monitoring GC events from remote process.
Args:
pid: Process ID of the target Python process to monitor
- debug: If True, chain exceptions to explain the sequence of events that
- lead to the exception.
+ debug: If True, chain exceptions to explain the sequence of
+ events that lead to the exception.
-The GCMonitor provides functionality to read GC statistics from a running
-Python process.
+The GCMonitor provides functionality to read GC statistics from
+a running Python process.
Raises:
PermissionError: If access to the target process is denied
- OSError: If unable to attach to the target process or access its memory
- RuntimeError: If unable to read debug information from the target process
+ OSError: If unable to attach to the target process or access
+ its memory
+ RuntimeError: If unable to read debug information from the
+ target process
[clinic start generated code]*/
static int
_remote_debugging_GCMonitor___init___impl(GCMonitorObject *self, int pid,
int debug)
-/*[clinic end generated code: output=2cdf351c2f6335db input=1185a48535b808be]*/
+/*[clinic end generated code: output=2cdf351c2f6335db input=03da0b2d3282ae1b]*/
{
return init_runtime_offsets(&self->offsets, pid, debug);
}
@@ -1438,14 +1467,14 @@ Returns a list of GCStatsInfo objects with GC statistics data.
- duration: Total collection time, in seconds.
Raises:
- RuntimeError: If the target process cannot be inspected or if its
- debug offsets or GC stats layout are incompatible.
+ RuntimeError: If the target process cannot be inspected or if
+ its debug offsets or GC stats layout are incompatible.
[clinic start generated code]*/
static PyObject *
_remote_debugging_GCMonitor_get_gc_stats_impl(GCMonitorObject *self,
int all_interpreters)
-/*[clinic end generated code: output=f73f365725224f7a input=12f7c1a288cf2741]*/
+/*[clinic end generated code: output=f73f365725224f7a input=ec016bc4be6dd003]*/
{
RemoteDebuggingState *st = RemoteDebugging_GetStateFromType(Py_TYPE(self));
return get_gc_stats(&self->offsets, all_interpreters, st->GCStatsInfo_Type);
@@ -1682,7 +1711,6 @@ class _remote_debugging.BinaryWriter "BinaryWriterObject *" "&PyBinaryWriter_Typ
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e948838b90a2003c]*/
/*[clinic input]
-@permit_long_docstring_body
_remote_debugging.BinaryWriter.__init__
filename: object
sample_interval_us: unsigned_long_long
@@ -1695,7 +1723,8 @@ High-performance binary writer for profiling data.
Arguments:
filename: Path to output file
sample_interval_us: Sampling interval in microseconds
- start_time_us: Start timestamp in microseconds (from time.monotonic() * 1e6)
+ start_time_us: Start timestamp in microseconds (from
+ time.monotonic() * 1e6)
compression: 0=none, 1=zstd (default: 0)
Use as a context manager or call finalize() when done.
@@ -1707,7 +1736,7 @@ _remote_debugging_BinaryWriter___init___impl(BinaryWriterObject *self,
unsigned long long sample_interval_us,
unsigned long long start_time_us,
int compression)
-/*[clinic end generated code: output=00446656ea2e5986 input=b92f0c77ba4cd274]*/
+/*[clinic end generated code: output=00446656ea2e5986 input=2e3f298c69fc7666]*/
{
if (self->writer) {
binary_writer_destroy(self->writer);
@@ -1722,7 +1751,6 @@ _remote_debugging_BinaryWriter___init___impl(BinaryWriterObject *self,
}
/*[clinic input]
-@permit_long_docstring_body
_remote_debugging.BinaryWriter.write_sample
stack_frames: object
timestamp_us: unsigned_long_long
@@ -1731,14 +1759,15 @@ Write a sample to the binary file.
Arguments:
stack_frames: List of InterpreterInfo objects
- timestamp_us: Current timestamp in microseconds (from time.monotonic() * 1e6)
+ timestamp_us: Current timestamp in microseconds (from
+ time.monotonic() * 1e6)
[clinic start generated code]*/
static PyObject *
_remote_debugging_BinaryWriter_write_sample_impl(BinaryWriterObject *self,
PyObject *stack_frames,
unsigned long long timestamp_us)
-/*[clinic end generated code: output=24d5b86679b4128f input=4e6d832d360bea46]*/
+/*[clinic end generated code: output=24d5b86679b4128f input=5033f1ae7fa135f1]*/
{
if (!self->writer) {
PyErr_SetString(PyExc_ValueError, "Writer is closed");
@@ -1861,18 +1890,18 @@ _remote_debugging_BinaryWriter___exit___impl(BinaryWriterObject *self,
}
/*[clinic input]
-@permit_long_docstring_body
_remote_debugging.BinaryWriter.get_stats
Get encoding statistics for the writer.
-Returns a dict with encoding statistics including repeat/full/suffix/pop-push
-record counts, frames written/saved, and compression ratio.
+Returns a dict with encoding statistics including
+repeat/full/suffix/pop-push record counts, frames written/saved, and
+compression ratio.
[clinic start generated code]*/
static PyObject *
_remote_debugging_BinaryWriter_get_stats_impl(BinaryWriterObject *self)
-/*[clinic end generated code: output=06522cd52544df89 input=837c874ffdebd24c]*/
+/*[clinic end generated code: output=06522cd52544df89 input=a8bb8c8682ccd34b]*/
{
if (!self->writer) {
PyErr_SetString(PyExc_ValueError, "Writer is closed");
@@ -2037,13 +2066,13 @@ _remote_debugging.BinaryReader.get_stats
Get reconstruction statistics from replay.
-Returns a dict with statistics about record types decoded and samples
-reconstructed during replay.
+Returns a dict with statistics about record types decoded and
+samples reconstructed during replay.
[clinic start generated code]*/
static PyObject *
_remote_debugging_BinaryReader_get_stats_impl(BinaryReaderObject *self)
-/*[clinic end generated code: output=628b9ab5e4c4fd36 input=d8dd6654abd6c3c0]*/
+/*[clinic end generated code: output=628b9ab5e4c4fd36 input=15b8d8f89ccf3726]*/
{
if (!self->reader) {
PyErr_SetString(PyExc_ValueError, "Reader is closed");
@@ -2195,7 +2224,6 @@ _remote_debugging_zstd_available_impl(PyObject *module)
* ============================================================================ */
/*[clinic input]
-@permit_long_docstring_body
_remote_debugging.get_child_pids
pid: int
@@ -2207,11 +2235,12 @@ _remote_debugging.get_child_pids
Get all child process IDs of the given process.
-Returns a list of child process IDs. Returns an empty list if no children
-are found.
+Returns a list of child process IDs. Returns an empty list if no
+children are found.
-This function provides a snapshot of child processes at a moment in time.
-Child processes may exit or new ones may be created after the list is returned.
+This function provides a snapshot of child processes at a moment in
+time. Child processes may exit or new ones may be created after the
+list is returned.
Raises:
OSError: If unable to enumerate processes
@@ -2221,7 +2250,7 @@ Child processes may exit or new ones may be created after the list is returned.
static PyObject *
_remote_debugging_get_child_pids_impl(PyObject *module, int pid,
int recursive)
-/*[clinic end generated code: output=1ae2289c6b953e4b input=19d8d5d6e2b59e6e]*/
+/*[clinic end generated code: output=1ae2289c6b953e4b input=c6437b52e2fdd880]*/
{
return enumerate_child_pids((pid_t)pid, recursive);
}
From 29cbb44200be6f4fdcea676ffaf6935f4cabf66e Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 24 May 2026 15:23:25 +0200
Subject: [PATCH 126/213] [3.15] gh-150285: Fix too long docstrings in the
curses module (GH-150286) (GH-150331)
(cherry picked from commit 4c0fe2d134f6ddaa4c705ffba073d9d5874b7fe4)
Co-authored-by: Serhiy Storchaka
---
Lib/curses/textpad.py | 12 +-
Modules/_curses_panel.c | 11 +-
Modules/_cursesmodule.c | 415 ++++++++++++++++---------------
Modules/clinic/_curses_panel.c.h | 8 +-
Modules/clinic/_cursesmodule.c.h | 282 +++++++++++----------
5 files changed, 381 insertions(+), 347 deletions(-)
diff --git a/Lib/curses/textpad.py b/Lib/curses/textpad.py
index aa87061b8d749e..3a98fd6043a124 100644
--- a/Lib/curses/textpad.py
+++ b/Lib/curses/textpad.py
@@ -23,7 +23,8 @@ class Textbox:
Ctrl-A Go to left edge of window.
Ctrl-B Cursor left, wrapping to previous line if appropriate.
Ctrl-D Delete character under cursor.
- Ctrl-E Go to right edge (stripspaces off) or end of line (stripspaces on).
+ Ctrl-E Go to right edge (stripspaces off) or end of line
+ (stripspaces on).
Ctrl-F Cursor right, wrapping to next line when appropriate.
Ctrl-G Terminate, returning the window contents.
Ctrl-H Delete character backward.
@@ -34,11 +35,12 @@ class Textbox:
Ctrl-O Insert a blank line at cursor location.
Ctrl-P Cursor up; move up one line.
- Move operations do nothing if the cursor is at an edge where the movement
- is not possible. The following synonyms are supported where possible:
+ Move operations do nothing if the cursor is at an edge where the
+ movement is not possible. The following synonyms are supported where
+ possible:
- KEY_LEFT = Ctrl-B, KEY_RIGHT = Ctrl-F, KEY_UP = Ctrl-P, KEY_DOWN = Ctrl-N
- KEY_BACKSPACE = Ctrl-h
+ KEY_LEFT = Ctrl-B, KEY_RIGHT = Ctrl-F, KEY_UP = Ctrl-P,
+ KEY_DOWN = Ctrl-N, KEY_BACKSPACE = Ctrl-h
"""
def __init__(self, win, insert_mode=False):
self.win = win
diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c
index 83802605e1f4dc..52411e413533ce 100644
--- a/Modules/_curses_panel.c
+++ b/Modules/_curses_panel.c
@@ -360,17 +360,17 @@ _curses_panel_panel_bottom_impl(PyCursesPanelObject *self)
}
/*[clinic input]
-@permit_long_docstring_body
_curses_panel.panel.hide
Hide the panel.
-This does not delete the object, it just makes the window on screen invisible.
+This does not delete the object, it just makes the window on screen
+invisible.
[clinic start generated code]*/
static PyObject *
_curses_panel_panel_hide_impl(PyCursesPanelObject *self)
-/*[clinic end generated code: output=a7bbbd523e1eab49 input=9071b463a39a1a6a]*/
+/*[clinic end generated code: output=a7bbbd523e1eab49 input=9456aca9b264dde1]*/
{
int rtn = hide_panel(self->pan);
return curses_panel_panel_check_err(self, rtn, "hide_panel", "hide");
@@ -772,12 +772,13 @@ _curses_panel.update_panels
Updates the virtual screen after changes in the panel stack.
-This does not call curses.doupdate(), so you'll have to do this yourself.
+This does not call curses.doupdate(), so you'll have to do this
+yourself.
[clinic start generated code]*/
static PyObject *
_curses_panel_update_panels_impl(PyObject *module)
-/*[clinic end generated code: output=2f3b4c2e03d90ded input=5299624c9a708621]*/
+/*[clinic end generated code: output=2f3b4c2e03d90ded input=0d0db79f05ec3ef4]*/
{
PyCursesInitialised;
update_panels();
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index 000d7318557a6e..4438e384aab9b2 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -1359,7 +1359,6 @@ _curses_window_bkgdset_impl(PyCursesWindowObject *self, PyObject *ch,
}
/*[clinic input]
-@permit_long_docstring_body
_curses.window.border
ls: object(c_default="NULL") = _curses.ACS_VLINE
@@ -1382,10 +1381,10 @@ _curses.window.border
Draw a border around the edges of the window.
-Each parameter specifies the character to use for a specific part of the
-border. The characters can be specified as integers or as one-character
-strings. A 0 value for any parameter will cause the default character to be
-used for that parameter.
+Each parameter specifies the character to use for a specific part of
+the border. The characters can be specified as integers or as
+one-character strings. A 0 value for any parameter will cause the
+default character to be used for that parameter.
[clinic start generated code]*/
static PyObject *
@@ -1393,7 +1392,7 @@ _curses_window_border_impl(PyCursesWindowObject *self, PyObject *ls,
PyObject *rs, PyObject *ts, PyObject *bs,
PyObject *tl, PyObject *tr, PyObject *bl,
PyObject *br)
-/*[clinic end generated code: output=670ef38d3d7c2aa3 input=adaafca87488ee35]*/
+/*[clinic end generated code: output=670ef38d3d7c2aa3 input=42568c1458221d24]*/
{
chtype ch[8];
int i, rtn;
@@ -1436,14 +1435,15 @@ _curses.window.box
Draw a border around the edges of the window.
-Similar to border(), but both ls and rs are verch and both ts and bs are
-horch. The default corner characters are always used by this function.
+Similar to border(), but both ls and rs are verch and both ts and bs
+are horch. The default corner characters are always used by this
+function.
[clinic start generated code]*/
static PyObject *
_curses_window_box_impl(PyCursesWindowObject *self, int group_right_1,
PyObject *verch, PyObject *horch)
-/*[clinic end generated code: output=f3fcb038bb287192 input=f00435f9c8c98f60]*/
+/*[clinic end generated code: output=f3fcb038bb287192 input=e11acb7dbf6790b6]*/
{
chtype ch1 = 0, ch2 = 0;
if (group_right_1) {
@@ -1596,7 +1596,6 @@ _curses_window_delch_impl(PyCursesWindowObject *self, int group_right_1,
}
/*[clinic input]
-@permit_long_docstring_body
_curses.window.derwin
[
@@ -1613,15 +1612,15 @@ _curses.window.derwin
Create a sub-window (window-relative coordinates).
-derwin() is the same as calling subwin(), except that begin_y and begin_x
-are relative to the origin of the window, rather than relative to the entire
-screen.
+derwin() is the same as calling subwin(), except that begin_y and
+begin_x are relative to the origin of the window, rather than
+relative to the entire screen.
[clinic start generated code]*/
static PyObject *
_curses_window_derwin_impl(PyCursesWindowObject *self, int group_left_1,
int nlines, int ncols, int begin_y, int begin_x)
-/*[clinic end generated code: output=7924b112d9f70d6e input=ebe95ded1c284c8e]*/
+/*[clinic end generated code: output=7924b112d9f70d6e input=6efb50722be444ba]*/
{
WINDOW *win;
@@ -1731,7 +1730,6 @@ curses_check_signals_on_input_error(PyCursesWindowObject *self,
}
/*[clinic input]
-@permit_long_docstring_body
_curses.window.getch
[
@@ -1744,15 +1742,16 @@ _curses.window.getch
Get a character code from terminal keyboard.
-The integer returned does not have to be in ASCII range: function keys,
-keypad keys and so on return numbers higher than 256. In no-delay mode, -1
-is returned if there is no input, else getch() waits until a key is pressed.
+The integer returned does not have to be in ASCII range: function
+keys, keypad keys and so on return numbers higher than 256. In
+no-delay mode, -1 is returned if there is no input, else getch()
+waits until a key is pressed.
[clinic start generated code]*/
static PyObject *
_curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1,
int y, int x)
-/*[clinic end generated code: output=e1639e87d545e676 input=9a053077373e2a30]*/
+/*[clinic end generated code: output=e1639e87d545e676 input=0dc5ff40e079787a]*/
{
int rtn;
@@ -1779,7 +1778,6 @@ _curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1,
}
/*[clinic input]
-@permit_long_docstring_body
_curses.window.getkey
[
@@ -1792,15 +1790,16 @@ _curses.window.getkey
Get a character (string) from terminal keyboard.
-Returning a string instead of an integer, as getch() does. Function keys,
-keypad keys and other special keys return a multibyte string containing the
-key name. In no-delay mode, an exception is raised if there is no input.
+Returning a string instead of an integer, as getch() does. Function
+keys, keypad keys and other special keys return a multibyte string
+containing the key name. In no-delay mode, an exception is raised
+if there is no input.
[clinic start generated code]*/
static PyObject *
_curses_window_getkey_impl(PyCursesWindowObject *self, int group_right_1,
int y, int x)
-/*[clinic end generated code: output=8490a182db46b10f input=5177f03fb6c31ea6]*/
+/*[clinic end generated code: output=8490a182db46b10f input=bd24a7da1ed9c73b]*/
{
int rtn;
@@ -2021,7 +2020,6 @@ _curses_window_hline_impl(PyCursesWindowObject *self, int group_left_1,
}
/*[clinic input]
-@permit_long_docstring_body
_curses.window.insch
[
@@ -2042,15 +2040,15 @@ _curses.window.insch
Insert a character before the current or specified position.
-All characters to the right of the cursor are shifted one position right, with
-the rightmost characters on the line being lost.
+All characters to the right of the cursor are shifted one position
+right, with the rightmost characters on the line being lost.
[clinic start generated code]*/
static PyObject *
_curses_window_insch_impl(PyCursesWindowObject *self, int group_left_1,
int y, int x, PyObject *ch, int group_right_1,
long attr)
-/*[clinic end generated code: output=ade8cfe3a3bf3e34 input=3f2a230cb09fed5a]*/
+/*[clinic end generated code: output=ade8cfe3a3bf3e34 input=d662a0f96f33e15a]*/
{
int rtn;
chtype ch_ = 0;
@@ -2072,7 +2070,6 @@ _curses_window_insch_impl(PyCursesWindowObject *self, int group_left_1,
}
/*[clinic input]
-@permit_long_docstring_body
_curses.window.inch
[
@@ -2085,13 +2082,14 @@ _curses.window.inch
Return the character at the given position in the window.
-The bottom 8 bits are the character proper, and upper bits are the attributes.
+The bottom 8 bits are the character proper, and upper bits are the
+attributes.
[clinic start generated code]*/
static PyObject *
_curses_window_inch_impl(PyCursesWindowObject *self, int group_right_1,
int y, int x)
-/*[clinic end generated code: output=97ca8581baaafd06 input=a5846f315464dc86]*/
+/*[clinic end generated code: output=97ca8581baaafd06 input=7a03956d94dc9a69]*/
{
chtype rtn;
const char *funcname;
@@ -2183,18 +2181,18 @@ _curses.window.insstr
Insert the string before the current or specified position.
-Insert a character string (as many characters as will fit on the line)
-before the character under the cursor. All characters to the right of
-the cursor are shifted right, with the rightmost characters on the line
-being lost. The cursor position does not change (after moving to y, x,
-if specified).
+Insert a character string (as many characters as will fit on the
+line) before the character under the cursor. All characters to the
+right of the cursor are shifted right, with the rightmost characters
+on the line being lost. The cursor position does not change (after
+moving to y, x, if specified).
[clinic start generated code]*/
static PyObject *
_curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1,
int y, int x, PyObject *str, int group_right_1,
long attr)
-/*[clinic end generated code: output=c259a5265ad0b777 input=6827cddc6340a7f3]*/
+/*[clinic end generated code: output=c259a5265ad0b777 input=dbfbdd3892155ea6]*/
{
int rtn;
int strtype;
@@ -2260,7 +2258,6 @@ _curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1,
}
/*[clinic input]
-@permit_long_docstring_body
_curses.window.insnstr
[
@@ -2284,19 +2281,19 @@ _curses.window.insnstr
Insert at most n characters of the string.
-Insert a character string (as many characters as will fit on the line)
-before the character under the cursor, up to n characters. If n is zero
-or negative, the entire string is inserted. All characters to the right
-of the cursor are shifted right, with the rightmost characters on the line
-being lost. The cursor position does not change (after moving to y, x, if
-specified).
+Insert a character string (as many characters as will fit on the
+line) before the character under the cursor, up to n characters. If
+n is zero or negative, the entire string is inserted. All
+characters to the right of the cursor are shifted right, with the
+rightmost characters on the line being lost. The cursor position
+does not change (after moving to y, x, if specified).
[clinic start generated code]*/
static PyObject *
_curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1,
int y, int x, PyObject *str, int n,
int group_right_1, long attr)
-/*[clinic end generated code: output=971a32ea6328ec8b input=dcdc554102fbcd5d]*/
+/*[clinic end generated code: output=971a32ea6328ec8b input=fd0a9b65b84b385f]*/
{
int rtn;
int strtype;
@@ -2361,7 +2358,7 @@ _curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1,
}
/*[clinic input]
-@permit_long_docstring_body
+@permit_long_summary
_curses.window.is_linetouched
line: int
@@ -2370,12 +2367,13 @@ _curses.window.is_linetouched
Return True if the specified line was modified, otherwise return False.
-Raise a curses.error exception if line is not valid for the given window.
+Raise a curses.error exception if line is not valid for the given
+window.
[clinic start generated code]*/
static PyObject *
_curses_window_is_linetouched_impl(PyCursesWindowObject *self, int line)
-/*[clinic end generated code: output=ad4a4edfee2db08c input=af71c040b951c467]*/
+/*[clinic end generated code: output=ad4a4edfee2db08c input=18924dfac25ab7f1]*/
{
int erg;
erg = is_linetouched(self->win, line);
@@ -2388,7 +2386,6 @@ _curses_window_is_linetouched_impl(PyCursesWindowObject *self, int line)
#ifdef py_is_pad
/*[clinic input]
-@permit_long_docstring_body
_curses.window.noutrefresh
[
@@ -2403,9 +2400,9 @@ _curses.window.noutrefresh
Mark for refresh but wait.
-This function updates the data structure representing the desired state of the
-window, but does not force an update of the physical screen. To accomplish
-that, call doupdate().
+This function updates the data structure representing the desired
+state of the window, but does not force an update of the physical
+screen. To accomplish that, call doupdate().
[clinic start generated code]*/
static PyObject *
@@ -2413,22 +2410,21 @@ _curses_window_noutrefresh_impl(PyCursesWindowObject *self,
int group_right_1, int pminrow, int pmincol,
int sminrow, int smincol, int smaxrow,
int smaxcol)
-/*[clinic end generated code: output=809a1f3c6a03e23e input=b39fe8fc79b9980b]*/
+/*[clinic end generated code: output=809a1f3c6a03e23e input=8b4c74bf55008803]*/
#else
/*[clinic input]
-@permit_long_docstring_body
_curses.window.noutrefresh
Mark for refresh but wait.
-This function updates the data structure representing the desired state of the
-window, but does not force an update of the physical screen. To accomplish
-that, call doupdate().
+This function updates the data structure representing the desired
+state of the window, but does not force an update of the physical
+screen. To accomplish that, call doupdate().
[clinic start generated code]*/
static PyObject *
_curses_window_noutrefresh_impl(PyCursesWindowObject *self)
-/*[clinic end generated code: output=6ef6dec666643fee input=6a9f59ae5e4c139e]*/
+/*[clinic end generated code: output=6ef6dec666643fee input=a7c6306f8af9d0dd]*/
#endif
{
int rtn;
@@ -2461,7 +2457,6 @@ _curses_window_noutrefresh_impl(PyCursesWindowObject *self)
}
/*[clinic input]
-@permit_long_docstring_body
_curses.window.overlay
destwin: object(type="PyCursesWindowObject *", subclass_of="clinic_state()->window_type")
@@ -2478,14 +2473,15 @@ _curses.window.overlay
Overlay the window on top of destwin.
-The windows need not be the same size, only the overlapping region is copied.
-This copy is non-destructive, which means that the current background
-character does not overwrite the old contents of destwin.
+The windows need not be the same size, only the overlapping region
+is copied. This copy is non-destructive, which means that the
+current background character does not overwrite the old contents of
+destwin.
-To get fine-grained control over the copied region, the second form of
-overlay() can be used. sminrow and smincol are the upper-left coordinates
-of the source window, and the other variables mark a rectangle in the
-destination window.
+To get fine-grained control over the copied region, the second form
+of overlay() can be used. sminrow and smincol are the upper-left
+coordinates of the source window, and the other variables mark
+a rectangle in the destination window.
[clinic start generated code]*/
static PyObject *
@@ -2493,7 +2489,7 @@ _curses_window_overlay_impl(PyCursesWindowObject *self,
PyCursesWindowObject *destwin, int group_right_1,
int sminrow, int smincol, int dminrow,
int dmincol, int dmaxrow, int dmaxcol)
-/*[clinic end generated code: output=82bb2c4cb443ca58 input=dd6af34deb892a65]*/
+/*[clinic end generated code: output=82bb2c4cb443ca58 input=da0cec7f7bda1b3f]*/
{
int rtn;
@@ -2509,7 +2505,6 @@ _curses_window_overlay_impl(PyCursesWindowObject *self,
}
/*[clinic input]
-@permit_long_docstring_body
_curses.window.overwrite
destwin: object(type="PyCursesWindowObject *", subclass_of="clinic_state()->window_type")
@@ -2526,14 +2521,15 @@ _curses.window.overwrite
Overwrite the window on top of destwin.
-The windows need not be the same size, in which case only the overlapping
-region is copied. This copy is destructive, which means that the current
-background character overwrites the old contents of destwin.
+The windows need not be the same size, in which case only the
+overlapping region is copied. This copy is destructive, which means
+that the current background character overwrites the old contents of
+destwin.
-To get fine-grained control over the copied region, the second form of
-overwrite() can be used. sminrow and smincol are the upper-left coordinates
-of the source window, the other variables mark a rectangle in the destination
-window.
+To get fine-grained control over the copied region, the second form
+of overwrite() can be used. sminrow and smincol are the upper-left
+coordinates of the source window, the other variables mark
+a rectangle in the destination window.
[clinic start generated code]*/
static PyObject *
@@ -2542,7 +2538,7 @@ _curses_window_overwrite_impl(PyCursesWindowObject *self,
int group_right_1, int sminrow, int smincol,
int dminrow, int dmincol, int dmaxrow,
int dmaxcol)
-/*[clinic end generated code: output=12ae007d1681be28 input=e84d8ebdf1c09596]*/
+/*[clinic end generated code: output=12ae007d1681be28 input=4244ab8a97087898]*/
{
int rtn;
@@ -2558,6 +2554,7 @@ _curses_window_overwrite_impl(PyCursesWindowObject *self,
}
/*[clinic input]
+@permit_long_summary
_curses.window.putwin
file: object
@@ -2570,7 +2567,7 @@ This information can be later retrieved using the getwin() function.
static PyObject *
_curses_window_putwin_impl(PyCursesWindowObject *self, PyObject *file)
-/*[clinic end generated code: output=fdae68ac59b0281b input=0608648e09c8ea0a]*/
+/*[clinic end generated code: output=fdae68ac59b0281b input=959fc85a9e4a31c2]*/
{
/* We have to simulate this by writing to a temporary FILE*,
then reading back, then writing to the argument file. */
@@ -2626,7 +2623,6 @@ _curses_window_redrawln_impl(PyCursesWindowObject *self, int beg, int num)
}
/*[clinic input]
-@permit_long_docstring_body
_curses.window.refresh
[
@@ -2642,23 +2638,24 @@ _curses.window.refresh
Update the display immediately.
Synchronize actual screen with previous drawing/deleting methods.
-The 6 optional arguments can only be specified when the window is a pad
-created with newpad(). The additional parameters are needed to indicate
-what part of the pad and screen are involved. pminrow and pmincol specify
-the upper left-hand corner of the rectangle to be displayed in the pad.
-sminrow, smincol, smaxrow, and smaxcol specify the edges of the rectangle to
-be displayed on the screen. The lower right-hand corner of the rectangle to
-be displayed in the pad is calculated from the screen coordinates, since the
-rectangles must be the same size. Both rectangles must be entirely contained
-within their respective structures. Negative values of pminrow, pmincol,
-sminrow, or smincol are treated as if they were zero.
+The 6 optional arguments can only be specified when the window is
+a pad created with newpad(). The additional parameters are needed
+to indicate what part of the pad and screen are involved. pminrow
+and pmincol specify the upper left-hand corner of the rectangle to
+be displayed in the pad. sminrow, smincol, smaxrow, and smaxcol
+specify the edges of the rectangle to be displayed on the screen.
+The lower right-hand corner of the rectangle to be displayed in the
+pad is calculated from the screen coordinates, since the rectangles
+must be the same size. Both rectangles must be entirely contained
+within their respective structures. Negative values of pminrow,
+pmincol, sminrow, or smincol are treated as if they were zero.
[clinic start generated code]*/
static PyObject *
_curses_window_refresh_impl(PyCursesWindowObject *self, int group_right_1,
int pminrow, int pmincol, int sminrow,
int smincol, int smaxrow, int smaxcol)
-/*[clinic end generated code: output=42199543115e6e63 input=65405c03290496a6]*/
+/*[clinic end generated code: output=42199543115e6e63 input=ff2e900c6b2696b1]*/
{
int rtn;
@@ -2711,7 +2708,6 @@ _curses_window_setscrreg_impl(PyCursesWindowObject *self, int top,
}
/*[clinic input]
-@permit_long_docstring_body
_curses.window.subwin
[
@@ -2728,14 +2724,14 @@ _curses.window.subwin
Create a sub-window (screen-relative coordinates).
-By default, the sub-window will extend from the specified position to the
-lower right corner of the window.
+By default, the sub-window will extend from the specified position
+to the lower right corner of the window.
[clinic start generated code]*/
static PyObject *
_curses_window_subwin_impl(PyCursesWindowObject *self, int group_left_1,
int nlines, int ncols, int begin_y, int begin_x)
-/*[clinic end generated code: output=93e898afc348f59a input=5292cf610e2f3585]*/
+/*[clinic end generated code: output=93e898afc348f59a input=07b5058cb8820595]*/
{
WINDOW *win;
const char *funcname;
@@ -2763,7 +2759,6 @@ _curses_window_subwin_impl(PyCursesWindowObject *self, int group_left_1,
}
/*[clinic input]
-@permit_long_docstring_body
_curses.window.scroll
[
@@ -2774,13 +2769,14 @@ _curses.window.scroll
Scroll the screen or scrolling region.
-Scroll upward if the argument is positive and downward if it is negative.
+Scroll upward if the argument is positive and downward if it is
+negative.
[clinic start generated code]*/
static PyObject *
_curses_window_scroll_impl(PyCursesWindowObject *self, int group_right_1,
int lines)
-/*[clinic end generated code: output=4541a8a11852d360 input=386456524c550113]*/
+/*[clinic end generated code: output=4541a8a11852d360 input=d8d81a5b52b9b40f]*/
{
int rtn;
const char *funcname;
@@ -2796,7 +2792,6 @@ _curses_window_scroll_impl(PyCursesWindowObject *self, int group_right_1,
}
/*[clinic input]
-@permit_long_docstring_body
_curses.window.touchline
start: int
@@ -2808,14 +2803,15 @@ _curses.window.touchline
Pretend count lines have been changed, starting with line start.
-If changed is supplied, it specifies whether the affected lines are marked
-as having been changed (changed=True) or unchanged (changed=False).
+If changed is supplied, it specifies whether the affected lines are
+marked as having been changed (changed=True) or unchanged
+(changed=False).
[clinic start generated code]*/
static PyObject *
_curses_window_touchline_impl(PyCursesWindowObject *self, int start,
int count, int group_right_1, int changed)
-/*[clinic end generated code: output=65d05b3f7438c61d input=36e13b6f5eb591f5]*/
+/*[clinic end generated code: output=65d05b3f7438c61d input=e0dc62f90d9dea55]*/
{
int rtn;
const char *funcname;
@@ -3182,20 +3178,20 @@ _curses.cbreak
Enter cbreak mode.
-In cbreak mode (sometimes called "rare" mode) normal tty line buffering is
-turned off and characters are available to be read one by one. However,
-unlike raw mode, special characters (interrupt, quit, suspend, and flow
-control) retain their effects on the tty driver and calling program.
-Calling first raw() then cbreak() leaves the terminal in cbreak mode.
+In cbreak mode (sometimes called "rare" mode) normal tty line buffering
+is turned off and characters are available to be read one by one.
+However, unlike raw mode, special characters (interrupt, quit, suspend,
+and flow control) retain their effects on the tty driver and calling
+program. Calling first raw() then cbreak() leaves the terminal in
+cbreak mode.
[clinic start generated code]*/
static PyObject *
_curses_cbreak_impl(PyObject *module, int flag)
-/*[clinic end generated code: output=9f9dee9664769751 input=c7d0bddda93016c1]*/
+/*[clinic end generated code: output=9f9dee9664769751 input=42d81687f11ddbf3]*/
NoArgOrFlagNoReturnFunctionBody(cbreak, flag)
/*[clinic input]
-@permit_long_docstring_body
_curses.color_content
color_number: color
@@ -3204,13 +3200,14 @@ _curses.color_content
Return the red, green, and blue (RGB) components of the specified color.
-A 3-tuple is returned, containing the R, G, B values for the given color,
-which will be between 0 (no component) and 1000 (maximum amount of component).
+A 3-tuple is returned, containing the R, G, B values for the given
+color, which will be between 0 (no component) and 1000 (maximum amount
+of component).
[clinic start generated code]*/
static PyObject *
_curses_color_content_impl(PyObject *module, int color_number)
-/*[clinic end generated code: output=17b466df7054e0de input=baffe25b351eb916]*/
+/*[clinic end generated code: output=17b466df7054e0de input=c95fb50093fa0be0]*/
{
_CURSES_COLOR_VAL_TYPE r,g,b;
@@ -3236,12 +3233,13 @@ _curses.color_pair
Return the attribute value for displaying text in the specified color.
This attribute value can be combined with A_STANDOUT, A_REVERSE, and the
-other A_* attributes. pair_number() is the counterpart to this function.
+other A_* attributes. pair_number() is the counterpart to this
+function.
[clinic start generated code]*/
static PyObject *
_curses_color_pair_impl(PyObject *module, int pair_number)
-/*[clinic end generated code: output=60718abb10ce9feb input=6034e9146f343802]*/
+/*[clinic end generated code: output=60718abb10ce9feb input=cf74bb81d3cc3370]*/
{
PyCursesStatefulInitialised(module);
PyCursesStatefulInitialisedColor(module);
@@ -3259,14 +3257,14 @@ _curses.curs_set
Set the cursor state.
If the terminal supports the visibility requested, the previous cursor
-state is returned; otherwise, an exception is raised. On many terminals,
-the "visible" mode is an underline cursor and the "very visible" mode is
-a block cursor.
+state is returned; otherwise, an exception is raised. On many
+terminals, the "visible" mode is an underline cursor and the "very
+visible" mode is a block cursor.
[clinic start generated code]*/
static PyObject *
_curses_curs_set_impl(PyObject *module, int visibility)
-/*[clinic end generated code: output=ee8e62483b1d6cd4 input=81a7924a65d29504]*/
+/*[clinic end generated code: output=ee8e62483b1d6cd4 input=e010767a328f322b]*/
{
int erg;
@@ -3301,14 +3299,15 @@ _curses.def_shell_mode
Save the current terminal mode as the "shell" mode.
-The "shell" mode is the mode when the running program is not using curses.
+The "shell" mode is the mode when the running program is not using
+curses.
Subsequent calls to reset_shell_mode() will restore this mode.
[clinic start generated code]*/
static PyObject *
_curses_def_shell_mode_impl(PyObject *module)
-/*[clinic end generated code: output=d6e42f5c768f860f input=5ead21f6f0baa894]*/
+/*[clinic end generated code: output=d6e42f5c768f860f input=3809f85615c0b693]*/
NoArgNoReturnFunctionBody(def_shell_mode)
/*[clinic input]
@@ -3350,12 +3349,13 @@ _curses.echo
Enter echo mode.
-In echo mode, each character input is echoed to the screen as it is entered.
+In echo mode, each character input is echoed to the screen as it is
+entered.
[clinic start generated code]*/
static PyObject *
_curses_echo_impl(PyObject *module, int flag)
-/*[clinic end generated code: output=03acb2ddfa6c8729 input=86cd4d5bb1d569c0]*/
+/*[clinic end generated code: output=03acb2ddfa6c8729 input=b4e9064326da9da4]*/
NoArgOrFlagNoReturnFunctionBody(echo, flag)
/*[clinic input]
@@ -3389,17 +3389,17 @@ _curses_erasechar_impl(PyObject *module)
}
/*[clinic input]
-@permit_long_docstring_body
_curses.flash
Flash the screen.
-That is, change it to reverse-video and then change it back in a short interval.
+That is, change it to reverse-video and then change it back in a short
+interval.
[clinic start generated code]*/
static PyObject *
_curses_flash_impl(PyObject *module)
-/*[clinic end generated code: output=488b8a0ebd9ea9b8 input=dd33d718e6edf436]*/
+/*[clinic end generated code: output=488b8a0ebd9ea9b8 input=90878e305432add9]*/
NoArgNoReturnFunctionBody(flash)
/*[clinic input]
@@ -3407,13 +3407,13 @@ _curses.flushinp
Flush all input buffers.
-This throws away any typeahead that has been typed by the user and has not
-yet been processed by the program.
+This throws away any typeahead that has been typed by the user and has
+not yet been processed by the program.
[clinic start generated code]*/
static PyObject *
_curses_flushinp_impl(PyObject *module)
-/*[clinic end generated code: output=7e7a1fc1473960f5 input=59d042e705cef5ec]*/
+/*[clinic end generated code: output=7e7a1fc1473960f5 input=3a63c7213be8043c]*/
NoArgNoReturnVoidFunctionBody(flushinp)
#ifdef getsyx
@@ -3599,6 +3599,7 @@ _curses_has_colors_impl(PyObject *module)
NoArgTrueFalseFunctionBody(has_colors)
/*[clinic input]
+@permit_long_summary
_curses.has_ic
Return True if the terminal has insert- and delete-character capabilities.
@@ -3606,7 +3607,7 @@ Return True if the terminal has insert- and delete-character capabilities.
static PyObject *
_curses_has_ic_impl(PyObject *module)
-/*[clinic end generated code: output=6be24da9cb1268fe input=9bc2d3a797cc7324]*/
+/*[clinic end generated code: output=6be24da9cb1268fe input=e37fa080d879f7a9]*/
NoArgTrueFalseFunctionBody(has_ic)
/*[clinic input]
@@ -3622,6 +3623,7 @@ NoArgTrueFalseFunctionBody(has_il)
#ifdef HAVE_CURSES_HAS_KEY
/*[clinic input]
+@permit_long_summary
_curses.has_key
key: int
@@ -3633,7 +3635,7 @@ Return True if the current terminal type recognizes a key with that value.
static PyObject *
_curses_has_key_impl(PyObject *module, int key)
-/*[clinic end generated code: output=19ad48319414d0b1 input=78bd44acf1a4997c]*/
+/*[clinic end generated code: output=19ad48319414d0b1 input=046ac6c72bbc9587]*/
{
PyCursesStatefulInitialised(module);
@@ -3688,13 +3690,14 @@ _curses.init_pair
Change the definition of a color-pair.
-If the color-pair was previously initialized, the screen is refreshed and
-all occurrences of that color-pair are changed to the new definition.
+If the color-pair was previously initialized, the screen is refreshed
+and all occurrences of that color-pair are changed to the new
+definition.
[clinic start generated code]*/
static PyObject *
_curses_init_pair_impl(PyObject *module, int pair_number, int fg, int bg)
-/*[clinic end generated code: output=a0bba03d2bbc3ee6 input=54b421b44c12c389]*/
+/*[clinic end generated code: output=a0bba03d2bbc3ee6 input=5486c3a105130dae]*/
{
PyCursesStatefulInitialised(module);
PyCursesStatefulInitialisedColor(module);
@@ -3914,14 +3917,14 @@ _curses.get_escdelay
Gets the curses ESCDELAY setting.
-Gets the number of milliseconds to wait after reading an escape character,
-to distinguish between an individual escape character entered on the
-keyboard from escape sequences sent by cursor and function keys.
+Gets the number of milliseconds to wait after reading an escape
+character, to distinguish between an individual escape character entered
+on the keyboard from escape sequences sent by cursor and function keys.
[clinic start generated code]*/
static PyObject *
_curses_get_escdelay_impl(PyObject *module)
-/*[clinic end generated code: output=222fa1a822555d60 input=be2d5b3dd974d0a4]*/
+/*[clinic end generated code: output=222fa1a822555d60 input=b39eeae4b8f169ab]*/
{
return PyLong_FromLong(ESCDELAY);
}
@@ -3933,14 +3936,14 @@ _curses.set_escdelay
Sets the curses ESCDELAY setting.
-Sets the number of milliseconds to wait after reading an escape character,
-to distinguish between an individual escape character entered on the
-keyboard from escape sequences sent by cursor and function keys.
+Sets the number of milliseconds to wait after reading an escape
+character, to distinguish between an individual escape character entered
+on the keyboard from escape sequences sent by cursor and function keys.
[clinic start generated code]*/
static PyObject *
_curses_set_escdelay_impl(PyObject *module, int ms)
-/*[clinic end generated code: output=43818efbf7980ac4 input=7796fe19f111e250]*/
+/*[clinic end generated code: output=43818efbf7980ac4 input=cc2529bcdda3b06c]*/
{
if (ms <= 0) {
PyErr_SetString(PyExc_ValueError, "ms must be > 0");
@@ -3955,13 +3958,13 @@ _curses.get_tabsize
Gets the curses TABSIZE setting.
-Gets the number of columns used by the curses library when converting a tab
-character to spaces as it adds the tab to a window.
+Gets the number of columns used by the curses library when converting
+a tab character to spaces as it adds the tab to a window.
[clinic start generated code]*/
static PyObject *
_curses_get_tabsize_impl(PyObject *module)
-/*[clinic end generated code: output=7e9e51fb6126fbdf input=74af86bf6c9f5d7e]*/
+/*[clinic end generated code: output=7e9e51fb6126fbdf input=58bdaacb337c103b]*/
{
return PyLong_FromLong(TABSIZE);
}
@@ -3973,13 +3976,13 @@ _curses.set_tabsize
Sets the curses TABSIZE setting.
-Sets the number of columns used by the curses library when converting a tab
-character to spaces as it adds the tab to a window.
+Sets the number of columns used by the curses library when converting
+a tab character to spaces as it adds the tab to a window.
[clinic start generated code]*/
static PyObject *
_curses_set_tabsize_impl(PyObject *module, int size)
-/*[clinic end generated code: output=c1de5a76c0daab1e input=78cba6a3021ad061]*/
+/*[clinic end generated code: output=c1de5a76c0daab1e input=34c1be9a78cd28a2]*/
{
if (size <= 0) {
PyErr_SetString(PyExc_ValueError, "size must be > 0");
@@ -4087,18 +4090,17 @@ _curses_killchar_impl(PyObject *module)
}
/*[clinic input]
-@permit_long_docstring_body
_curses.longname
Return the terminfo long name field describing the current terminal.
-The maximum length of a verbose description is 128 characters. It is defined
-only after the call to initscr().
+The maximum length of a verbose description is 128 characters. It is
+defined only after the call to initscr().
[clinic start generated code]*/
static PyObject *
_curses_longname_impl(PyObject *module)
-/*[clinic end generated code: output=fdf30433727ef568 input=5de06852f2230ddb]*/
+/*[clinic end generated code: output=fdf30433727ef568 input=a924fabba0de78a6]*/
NoArgReturnStringFunctionBody(longname)
/*[clinic input]
@@ -4133,13 +4135,13 @@ _curses.mouseinterval
Set and retrieve the maximum time between press and release in a click.
Set the maximum time that can elapse between press and release events in
-order for them to be recognized as a click, and return the previous interval
-value.
+order for them to be recognized as a click, and return the previous
+interval value.
[clinic start generated code]*/
static PyObject *
_curses_mouseinterval_impl(PyObject *module, int interval)
-/*[clinic end generated code: output=c4f5ff04354634c5 input=75aaa3f0db10ac4e]*/
+/*[clinic end generated code: output=c4f5ff04354634c5 input=b90249254389c080]*/
{
PyCursesStatefulInitialised(module);
int value = mouseinterval(interval);
@@ -4160,14 +4162,15 @@ _curses.mousemask
Set the mouse events to be reported, and return a tuple (availmask, oldmask).
Return a tuple (availmask, oldmask). availmask indicates which of the
-specified mouse events can be reported; on complete failure it returns 0.
-oldmask is the previous value of the given window's mouse event mask.
-If this function is never called, no mouse events are ever reported.
+specified mouse events can be reported; on complete failure it returns
+0. oldmask is the previous value of the given window's mouse event
+mask. If this function is never called, no mouse events are ever
+reported.
[clinic start generated code]*/
static PyObject *
_curses_mousemask_impl(PyObject *module, unsigned long newmask)
-/*[clinic end generated code: output=9406cf1b8a36e485 input=b92ff4fbe5ce61b1]*/
+/*[clinic end generated code: output=9406cf1b8a36e485 input=78990ec6c52aa888]*/
{
mmask_t oldmask, availmask;
@@ -4249,14 +4252,14 @@ _curses.newwin
Return a new window.
-By default, the window will extend from the specified position to the lower
-right corner of the screen.
+By default, the window will extend from the specified position to the
+lower right corner of the screen.
[clinic start generated code]*/
static PyObject *
_curses_newwin_impl(PyObject *module, int nlines, int ncols,
int group_right_1, int begin_y, int begin_x)
-/*[clinic end generated code: output=c1e0a8dc8ac2826c input=29312c15a72a003d]*/
+/*[clinic end generated code: output=c1e0a8dc8ac2826c input=a1517cbfea4ab24b]*/
{
WINDOW *win;
@@ -4281,13 +4284,14 @@ _curses.nl
Enter newline mode.
-This mode translates the return key into newline on input, and translates
-newline into return and line-feed on output. Newline mode is initially on.
+This mode translates the return key into newline on input, and
+translates newline into return and line-feed on output. Newline mode
+is initially on.
[clinic start generated code]*/
static PyObject *
_curses_nl_impl(PyObject *module, int flag)
-/*[clinic end generated code: output=b39cc0ffc9015003 input=18e3e9c6e8cfcf6f]*/
+/*[clinic end generated code: output=b39cc0ffc9015003 input=3fb21dcf55521ee4]*/
NoArgOrFlagNoReturnFunctionBody(nl, flag)
/*[clinic input]
@@ -4321,13 +4325,13 @@ _curses.nonl
Leave newline mode.
-Disable translation of return into newline on input, and disable low-level
-translation of newline into newline/return on output.
+Disable translation of return into newline on input, and disable
+low-level translation of newline into newline/return on output.
[clinic start generated code]*/
static PyObject *
_curses_nonl_impl(PyObject *module)
-/*[clinic end generated code: output=99e917e9715770c6 input=9d37dd122d3022fc]*/
+/*[clinic end generated code: output=99e917e9715770c6 input=75cce08e4b6b3ef1]*/
NoArgNoReturnFunctionBody(nonl)
/*[clinic input]
@@ -4358,6 +4362,7 @@ _curses_noraw_impl(PyObject *module)
NoArgNoReturnFunctionBody(noraw)
/*[clinic input]
+@permit_long_summary
_curses.pair_content
pair_number: pair
@@ -4369,7 +4374,7 @@ Return a tuple (fg, bg) containing the colors for the requested color pair.
static PyObject *
_curses_pair_content_impl(PyObject *module, int pair_number)
-/*[clinic end generated code: output=4a726dd0e6885f3f input=03970f840fc7b739]*/
+/*[clinic end generated code: output=4a726dd0e6885f3f input=faede9e26f1f2ca4]*/
{
_CURSES_COLOR_NUM_TYPE f, b;
@@ -4393,6 +4398,7 @@ _curses_pair_content_impl(PyObject *module, int pair_number)
}
/*[clinic input]
+@permit_long_summary
_curses.pair_number
attr: int
@@ -4405,7 +4411,7 @@ color_pair() is the counterpart to this function.
static PyObject *
_curses_pair_number_impl(PyObject *module, int attr)
-/*[clinic end generated code: output=85bce7d65c0aa3f4 input=d478548e33f5e61a]*/
+/*[clinic end generated code: output=85bce7d65c0aa3f4 input=b11152a78c2f9abf]*/
{
PyCursesStatefulInitialised(module);
PyCursesStatefulInitialisedColor(module);
@@ -4414,6 +4420,7 @@ _curses_pair_number_impl(PyObject *module, int attr)
}
/*[clinic input]
+@permit_long_summary
_curses.putp
string: str(accept={robuffer})
@@ -4426,7 +4433,7 @@ Note that the output of putp() always goes to standard output.
static PyObject *
_curses_putp_impl(PyObject *module, const char *string)
-/*[clinic end generated code: output=e98081d1b8eb5816 input=1601faa828b44cb3]*/
+/*[clinic end generated code: output=e98081d1b8eb5816 input=2f3b9e0f22829ee7]*/
{
return curses_check_err(module, putp(string), "putp", NULL);
}
@@ -4539,13 +4546,13 @@ _curses.raw
Enter raw mode.
In raw mode, normal line buffering and processing of interrupt, quit,
-suspend, and flow control keys are turned off; characters are presented to
-curses input functions one by one.
+suspend, and flow control keys are turned off; characters are presented
+to curses input functions one by one.
[clinic start generated code]*/
static PyObject *
_curses_raw_impl(PyObject *module, int flag)
-/*[clinic end generated code: output=a750e4b342be015b input=4b447701389fb4df]*/
+/*[clinic end generated code: output=a750e4b342be015b input=18a7de7eef16987a]*/
NoArgOrFlagNoReturnFunctionBody(raw, flag)
/*[clinic input]
@@ -4595,13 +4602,13 @@ _curses.resizeterm
Resize the standard and current windows to the specified dimensions.
-Adjusts other bookkeeping data used by the curses library that record the
-window dimensions (in particular the SIGWINCH handler).
+Adjusts other bookkeeping data used by the curses library that record
+the window dimensions (in particular the SIGWINCH handler).
[clinic start generated code]*/
static PyObject *
_curses_resizeterm_impl(PyObject *module, short nlines, short ncols)
-/*[clinic end generated code: output=4de3abab50c67f02 input=414e92a63e3e9899]*/
+/*[clinic end generated code: output=4de3abab50c67f02 input=7f0f077df2da1cf5]*/
{
PyObject *result;
int code;
@@ -4623,7 +4630,6 @@ _curses_resizeterm_impl(PyObject *module, short nlines, short ncols)
#ifdef HAVE_CURSES_RESIZE_TERM
/*[clinic input]
-@permit_long_docstring_body
_curses.resize_term
nlines: short
@@ -4635,15 +4641,16 @@ _curses.resize_term
Backend function used by resizeterm(), performing most of the work.
When resizing the windows, resize_term() blank-fills the areas that are
-extended. The calling application should fill in these areas with appropriate
-data. The resize_term() function attempts to resize all windows. However,
-due to the calling convention of pads, it is not possible to resize these
-without additional interaction with the application.
+extended. The calling application should fill in these areas with
+appropriate data. The resize_term() function attempts to resize all
+windows. However, due to the calling convention of pads, it is not
+possible to resize these without additional interaction with the
+application.
[clinic start generated code]*/
static PyObject *
_curses_resize_term_impl(PyObject *module, short nlines, short ncols)
-/*[clinic end generated code: output=46c6d749fa291dbd input=ebfa840f6b5f03fa]*/
+/*[clinic end generated code: output=46c6d749fa291dbd input=ff4baaf2320c8ac9]*/
{
PyObject *result;
int code;
@@ -4701,21 +4708,22 @@ _curses_setsyx_impl(PyObject *module, int y, int x)
#endif
/*[clinic input]
+@permit_long_summary
_curses.start_color
Initializes eight basic colors and global variables COLORS and COLOR_PAIRS.
-Must be called if the programmer wants to use colors, and before any other
-color manipulation routine is called. It is good practice to call this
-routine right after initscr().
+Must be called if the programmer wants to use colors, and before any
+other color manipulation routine is called. It is good practice to call
+this routine right after initscr().
-It also restores the colors on the terminal to the values they had when the
-terminal was just turned on.
+It also restores the colors on the terminal to the values they had when
+the terminal was just turned on.
[clinic start generated code]*/
static PyObject *
_curses_start_color_impl(PyObject *module)
-/*[clinic end generated code: output=8b772b41d8090ede input=0ca0ecb2b77e1a12]*/
+/*[clinic end generated code: output=8b772b41d8090ede input=7daacc6b6baba643]*/
{
PyCursesStatefulInitialised(module);
@@ -4804,13 +4812,13 @@ _curses.tigetnum
Return the value of the numeric capability.
-The value -2 is returned if capname is not a numeric capability, or -1 if
-it is canceled or absent from the terminal description.
+The value -2 is returned if capname is not a numeric capability, or -1
+if it is canceled or absent from the terminal description.
[clinic start generated code]*/
static PyObject *
_curses_tigetnum_impl(PyObject *module, const char *capname)
-/*[clinic end generated code: output=46f8b0a1b5dff42f input=5cdf2f410b109720]*/
+/*[clinic end generated code: output=46f8b0a1b5dff42f input=87a64beec16ae077]*/
{
PyCursesStatefulSetupTermCalled(module);
@@ -4826,13 +4834,13 @@ _curses.tigetstr
Return the value of the string capability.
-None is returned if capname is not a string capability, or is canceled or
-absent from the terminal description.
+None is returned if capname is not a string capability, or is canceled
+or absent from the terminal description.
[clinic start generated code]*/
static PyObject *
_curses_tigetstr_impl(PyObject *module, const char *capname)
-/*[clinic end generated code: output=f22b576ad60248f3 input=36644df25c73c0a7]*/
+/*[clinic end generated code: output=f22b576ad60248f3 input=00bf0feda2207724]*/
{
PyCursesStatefulSetupTermCalled(module);
@@ -5030,7 +5038,6 @@ _curses_unget_wch(PyObject *module, PyObject *ch)
#ifdef HAVE_CURSES_USE_ENV
/*[clinic input]
-@permit_long_docstring_body
_curses.use_env
flag: bool
@@ -5038,19 +5045,19 @@ _curses.use_env
Use environment variables LINES and COLUMNS.
-If used, this function should be called before initscr() or newterm() are
-called.
+If used, this function should be called before initscr() or newterm()
+are called.
-When flag is False, the values of lines and columns specified in the terminfo
-database will be used, even if environment variables LINES and COLUMNS (used
-by default) are set, or if curses is running in a window (in which case
-default behavior would be to use the window size if LINES and COLUMNS are
-not set).
+When flag is False, the values of lines and columns specified in the
+terminfo database will be used, even if environment variables LINES and
+COLUMNS (used by default) are set, or if curses is running in a window
+(in which case default behavior would be to use the window size if LINES
+and COLUMNS are not set).
[clinic start generated code]*/
static PyObject *
_curses_use_env_impl(PyObject *module, int flag)
-/*[clinic end generated code: output=b2c445e435c0b164 input=eaa9047ec73c27d3]*/
+/*[clinic end generated code: output=b2c445e435c0b164 input=8e8feed746cf7fc1]*/
{
use_env(flag);
Py_RETURN_NONE;
@@ -5078,6 +5085,7 @@ _curses_use_default_colors_impl(PyObject *module)
}
/*[clinic input]
+@permit_long_summary
_curses.assume_default_colors
fg: int
bg: int
@@ -5093,7 +5101,7 @@ Use this to support transparency in your application.
static PyObject *
_curses_assume_default_colors_impl(PyObject *module, int fg, int bg)
-/*[clinic end generated code: output=54985397a7d2b3a5 input=7fe301712ef3e9fb]*/
+/*[clinic end generated code: output=54985397a7d2b3a5 input=8945333c09893cf2]*/
{
int code;
@@ -5162,6 +5170,7 @@ make_ncurses_version(PyTypeObject *type)
#endif /* NCURSES_VERSION */
/*[clinic input]
+@permit_long_summary
_curses.has_extended_color_support
Return True if the module supports extended colors; otherwise, return False.
@@ -5172,7 +5181,7 @@ that support more than 16 colors (e.g. xterm-256color).
static PyObject *
_curses_has_extended_color_support_impl(PyObject *module)
-/*[clinic end generated code: output=68f1be2b57d92e22 input=4b905f046e35ee9f]*/
+/*[clinic end generated code: output=68f1be2b57d92e22 input=40d673471c5056f0]*/
{
return PyBool_FromLong(_NCURSES_EXTENDED_COLOR_FUNCS);
}
diff --git a/Modules/clinic/_curses_panel.c.h b/Modules/clinic/_curses_panel.c.h
index 75cf067c8aa822..d8b2cba7fd3f89 100644
--- a/Modules/clinic/_curses_panel.c.h
+++ b/Modules/clinic/_curses_panel.c.h
@@ -28,7 +28,8 @@ PyDoc_STRVAR(_curses_panel_panel_hide__doc__,
"\n"
"Hide the panel.\n"
"\n"
-"This does not delete the object, it just makes the window on screen invisible.");
+"This does not delete the object, it just makes the window on screen\n"
+"invisible.");
#define _CURSES_PANEL_PANEL_HIDE_METHODDEF \
{"hide", (PyCFunction)_curses_panel_panel_hide, METH_NOARGS, _curses_panel_panel_hide__doc__},
@@ -328,7 +329,8 @@ PyDoc_STRVAR(_curses_panel_update_panels__doc__,
"\n"
"Updates the virtual screen after changes in the panel stack.\n"
"\n"
-"This does not call curses.doupdate(), so you\'ll have to do this yourself.");
+"This does not call curses.doupdate(), so you\'ll have to do this\n"
+"yourself.");
#define _CURSES_PANEL_UPDATE_PANELS_METHODDEF \
{"update_panels", (PyCFunction)_curses_panel_update_panels, METH_NOARGS, _curses_panel_update_panels__doc__},
@@ -341,4 +343,4 @@ _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored))
{
return _curses_panel_update_panels_impl(module);
}
-/*[clinic end generated code: output=db2fe491582784aa input=a9049054013a1b77]*/
+/*[clinic end generated code: output=62f20ef03eefdf44 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h
index e6f9798cdf1249..eec9e82739b778 100644
--- a/Modules/clinic/_cursesmodule.c.h
+++ b/Modules/clinic/_cursesmodule.c.h
@@ -422,10 +422,10 @@ PyDoc_STRVAR(_curses_window_border__doc__,
" br\n"
" Bottom-right corner.\n"
"\n"
-"Each parameter specifies the character to use for a specific part of the\n"
-"border. The characters can be specified as integers or as one-character\n"
-"strings. A 0 value for any parameter will cause the default character to be\n"
-"used for that parameter.");
+"Each parameter specifies the character to use for a specific part of\n"
+"the border. The characters can be specified as integers or as\n"
+"one-character strings. A 0 value for any parameter will cause the\n"
+"default character to be used for that parameter.");
#define _CURSES_WINDOW_BORDER_METHODDEF \
{"border", _PyCFunction_CAST(_curses_window_border), METH_FASTCALL, _curses_window_border__doc__},
@@ -500,8 +500,9 @@ PyDoc_STRVAR(_curses_window_box__doc__,
" horch\n"
" Top and bottom side.\n"
"\n"
-"Similar to border(), but both ls and rs are verch and both ts and bs are\n"
-"horch. The default corner characters are always used by this function.");
+"Similar to border(), but both ls and rs are verch and both ts and bs\n"
+"are horch. The default corner characters are always used by this\n"
+"function.");
#define _CURSES_WINDOW_BOX_METHODDEF \
{"box", (PyCFunction)_curses_window_box, METH_VARARGS, _curses_window_box__doc__},
@@ -593,9 +594,9 @@ PyDoc_STRVAR(_curses_window_derwin__doc__,
" begin_x\n"
" Left side x-coordinate.\n"
"\n"
-"derwin() is the same as calling subwin(), except that begin_y and begin_x\n"
-"are relative to the origin of the window, rather than relative to the entire\n"
-"screen.");
+"derwin() is the same as calling subwin(), except that begin_y and\n"
+"begin_x are relative to the origin of the window, rather than\n"
+"relative to the entire screen.");
#define _CURSES_WINDOW_DERWIN_METHODDEF \
{"derwin", (PyCFunction)_curses_window_derwin, METH_VARARGS, _curses_window_derwin__doc__},
@@ -751,9 +752,10 @@ PyDoc_STRVAR(_curses_window_getch__doc__,
" x\n"
" X-coordinate.\n"
"\n"
-"The integer returned does not have to be in ASCII range: function keys,\n"
-"keypad keys and so on return numbers higher than 256. In no-delay mode, -1\n"
-"is returned if there is no input, else getch() waits until a key is pressed.");
+"The integer returned does not have to be in ASCII range: function\n"
+"keys, keypad keys and so on return numbers higher than 256. In\n"
+"no-delay mode, -1 is returned if there is no input, else getch()\n"
+"waits until a key is pressed.");
#define _CURSES_WINDOW_GETCH_METHODDEF \
{"getch", (PyCFunction)_curses_window_getch, METH_VARARGS, _curses_window_getch__doc__},
@@ -798,9 +800,10 @@ PyDoc_STRVAR(_curses_window_getkey__doc__,
" x\n"
" X-coordinate.\n"
"\n"
-"Returning a string instead of an integer, as getch() does. Function keys,\n"
-"keypad keys and other special keys return a multibyte string containing the\n"
-"key name. In no-delay mode, an exception is raised if there is no input.");
+"Returning a string instead of an integer, as getch() does. Function\n"
+"keys, keypad keys and other special keys return a multibyte string\n"
+"containing the key name. In no-delay mode, an exception is raised\n"
+"if there is no input.");
#define _CURSES_WINDOW_GETKEY_METHODDEF \
{"getkey", (PyCFunction)_curses_window_getkey, METH_VARARGS, _curses_window_getkey__doc__},
@@ -969,8 +972,8 @@ PyDoc_STRVAR(_curses_window_insch__doc__,
" attr\n"
" Attributes for the character.\n"
"\n"
-"All characters to the right of the cursor are shifted one position right, with\n"
-"the rightmost characters on the line being lost.");
+"All characters to the right of the cursor are shifted one position\n"
+"right, with the rightmost characters on the line being lost.");
#define _CURSES_WINDOW_INSCH_METHODDEF \
{"insch", (PyCFunction)_curses_window_insch, METH_VARARGS, _curses_window_insch__doc__},
@@ -1035,7 +1038,8 @@ PyDoc_STRVAR(_curses_window_inch__doc__,
" x\n"
" X-coordinate.\n"
"\n"
-"The bottom 8 bits are the character proper, and upper bits are the attributes.");
+"The bottom 8 bits are the character proper, and upper bits are the\n"
+"attributes.");
#define _CURSES_WINDOW_INCH_METHODDEF \
{"inch", (PyCFunction)_curses_window_inch, METH_VARARGS, _curses_window_inch__doc__},
@@ -1084,11 +1088,11 @@ PyDoc_STRVAR(_curses_window_insstr__doc__,
" attr\n"
" Attributes for characters.\n"
"\n"
-"Insert a character string (as many characters as will fit on the line)\n"
-"before the character under the cursor. All characters to the right of\n"
-"the cursor are shifted right, with the rightmost characters on the line\n"
-"being lost. The cursor position does not change (after moving to y, x,\n"
-"if specified).");
+"Insert a character string (as many characters as will fit on the\n"
+"line) before the character under the cursor. All characters to the\n"
+"right of the cursor are shifted right, with the rightmost characters\n"
+"on the line being lost. The cursor position does not change (after\n"
+"moving to y, x, if specified).");
#define _CURSES_WINDOW_INSSTR_METHODDEF \
{"insstr", (PyCFunction)_curses_window_insstr, METH_VARARGS, _curses_window_insstr__doc__},
@@ -1159,12 +1163,12 @@ PyDoc_STRVAR(_curses_window_insnstr__doc__,
" attr\n"
" Attributes for characters.\n"
"\n"
-"Insert a character string (as many characters as will fit on the line)\n"
-"before the character under the cursor, up to n characters. If n is zero\n"
-"or negative, the entire string is inserted. All characters to the right\n"
-"of the cursor are shifted right, with the rightmost characters on the line\n"
-"being lost. The cursor position does not change (after moving to y, x, if\n"
-"specified).");
+"Insert a character string (as many characters as will fit on the\n"
+"line) before the character under the cursor, up to n characters. If\n"
+"n is zero or negative, the entire string is inserted. All\n"
+"characters to the right of the cursor are shifted right, with the\n"
+"rightmost characters on the line being lost. The cursor position\n"
+"does not change (after moving to y, x, if specified).");
#define _CURSES_WINDOW_INSNSTR_METHODDEF \
{"insnstr", (PyCFunction)_curses_window_insnstr, METH_VARARGS, _curses_window_insnstr__doc__},
@@ -1230,7 +1234,8 @@ PyDoc_STRVAR(_curses_window_is_linetouched__doc__,
" line\n"
" Line number.\n"
"\n"
-"Raise a curses.error exception if line is not valid for the given window.");
+"Raise a curses.error exception if line is not valid for the given\n"
+"window.");
#define _CURSES_WINDOW_IS_LINETOUCHED_METHODDEF \
{"is_linetouched", (PyCFunction)_curses_window_is_linetouched, METH_O, _curses_window_is_linetouched__doc__},
@@ -1260,9 +1265,9 @@ PyDoc_STRVAR(_curses_window_noutrefresh__doc__,
"noutrefresh([pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol])\n"
"Mark for refresh but wait.\n"
"\n"
-"This function updates the data structure representing the desired state of the\n"
-"window, but does not force an update of the physical screen. To accomplish\n"
-"that, call doupdate().");
+"This function updates the data structure representing the desired\n"
+"state of the window, but does not force an update of the physical\n"
+"screen. To accomplish that, call doupdate().");
#define _CURSES_WINDOW_NOUTREFRESH_METHODDEF \
{"noutrefresh", (PyCFunction)_curses_window_noutrefresh, METH_VARARGS, _curses_window_noutrefresh__doc__},
@@ -1314,9 +1319,9 @@ PyDoc_STRVAR(_curses_window_noutrefresh__doc__,
"\n"
"Mark for refresh but wait.\n"
"\n"
-"This function updates the data structure representing the desired state of the\n"
-"window, but does not force an update of the physical screen. To accomplish\n"
-"that, call doupdate().");
+"This function updates the data structure representing the desired\n"
+"state of the window, but does not force an update of the physical\n"
+"screen. To accomplish that, call doupdate().");
#define _CURSES_WINDOW_NOUTREFRESH_METHODDEF \
{"noutrefresh", (PyCFunction)_curses_window_noutrefresh, METH_NOARGS, _curses_window_noutrefresh__doc__},
@@ -1336,14 +1341,15 @@ PyDoc_STRVAR(_curses_window_overlay__doc__,
"overlay(destwin, [sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol])\n"
"Overlay the window on top of destwin.\n"
"\n"
-"The windows need not be the same size, only the overlapping region is copied.\n"
-"This copy is non-destructive, which means that the current background\n"
-"character does not overwrite the old contents of destwin.\n"
+"The windows need not be the same size, only the overlapping region\n"
+"is copied. This copy is non-destructive, which means that the\n"
+"current background character does not overwrite the old contents of\n"
+"destwin.\n"
"\n"
-"To get fine-grained control over the copied region, the second form of\n"
-"overlay() can be used. sminrow and smincol are the upper-left coordinates\n"
-"of the source window, and the other variables mark a rectangle in the\n"
-"destination window.");
+"To get fine-grained control over the copied region, the second form\n"
+"of overlay() can be used. sminrow and smincol are the upper-left\n"
+"coordinates of the source window, and the other variables mark\n"
+"a rectangle in the destination window.");
#define _CURSES_WINDOW_OVERLAY_METHODDEF \
{"overlay", (PyCFunction)_curses_window_overlay, METH_VARARGS, _curses_window_overlay__doc__},
@@ -1394,14 +1400,15 @@ PyDoc_STRVAR(_curses_window_overwrite__doc__,
" dmaxcol])\n"
"Overwrite the window on top of destwin.\n"
"\n"
-"The windows need not be the same size, in which case only the overlapping\n"
-"region is copied. This copy is destructive, which means that the current\n"
-"background character overwrites the old contents of destwin.\n"
+"The windows need not be the same size, in which case only the\n"
+"overlapping region is copied. This copy is destructive, which means\n"
+"that the current background character overwrites the old contents of\n"
+"destwin.\n"
"\n"
-"To get fine-grained control over the copied region, the second form of\n"
-"overwrite() can be used. sminrow and smincol are the upper-left coordinates\n"
-"of the source window, the other variables mark a rectangle in the destination\n"
-"window.");
+"To get fine-grained control over the copied region, the second form\n"
+"of overwrite() can be used. sminrow and smincol are the upper-left\n"
+"coordinates of the source window, the other variables mark\n"
+"a rectangle in the destination window.");
#define _CURSES_WINDOW_OVERWRITE_METHODDEF \
{"overwrite", (PyCFunction)_curses_window_overwrite, METH_VARARGS, _curses_window_overwrite__doc__},
@@ -1520,16 +1527,17 @@ PyDoc_STRVAR(_curses_window_refresh__doc__,
"Update the display immediately.\n"
"\n"
"Synchronize actual screen with previous drawing/deleting methods.\n"
-"The 6 optional arguments can only be specified when the window is a pad\n"
-"created with newpad(). The additional parameters are needed to indicate\n"
-"what part of the pad and screen are involved. pminrow and pmincol specify\n"
-"the upper left-hand corner of the rectangle to be displayed in the pad.\n"
-"sminrow, smincol, smaxrow, and smaxcol specify the edges of the rectangle to\n"
-"be displayed on the screen. The lower right-hand corner of the rectangle to\n"
-"be displayed in the pad is calculated from the screen coordinates, since the\n"
-"rectangles must be the same size. Both rectangles must be entirely contained\n"
-"within their respective structures. Negative values of pminrow, pmincol,\n"
-"sminrow, or smincol are treated as if they were zero.");
+"The 6 optional arguments can only be specified when the window is\n"
+"a pad created with newpad(). The additional parameters are needed\n"
+"to indicate what part of the pad and screen are involved. pminrow\n"
+"and pmincol specify the upper left-hand corner of the rectangle to\n"
+"be displayed in the pad. sminrow, smincol, smaxrow, and smaxcol\n"
+"specify the edges of the rectangle to be displayed on the screen.\n"
+"The lower right-hand corner of the rectangle to be displayed in the\n"
+"pad is calculated from the screen coordinates, since the rectangles\n"
+"must be the same size. Both rectangles must be entirely contained\n"
+"within their respective structures. Negative values of pminrow,\n"
+"pmincol, sminrow, or smincol are treated as if they were zero.");
#define _CURSES_WINDOW_REFRESH_METHODDEF \
{"refresh", (PyCFunction)_curses_window_refresh, METH_VARARGS, _curses_window_refresh__doc__},
@@ -1627,8 +1635,8 @@ PyDoc_STRVAR(_curses_window_subwin__doc__,
" begin_x\n"
" Left side x-coordinate.\n"
"\n"
-"By default, the sub-window will extend from the specified position to the\n"
-"lower right corner of the window.");
+"By default, the sub-window will extend from the specified position\n"
+"to the lower right corner of the window.");
#define _CURSES_WINDOW_SUBWIN_METHODDEF \
{"subwin", (PyCFunction)_curses_window_subwin, METH_VARARGS, _curses_window_subwin__doc__},
@@ -1676,7 +1684,8 @@ PyDoc_STRVAR(_curses_window_scroll__doc__,
" lines\n"
" Number of lines to scroll.\n"
"\n"
-"Scroll upward if the argument is positive and downward if it is negative.");
+"Scroll upward if the argument is positive and downward if it is\n"
+"negative.");
#define _CURSES_WINDOW_SCROLL_METHODDEF \
{"scroll", (PyCFunction)_curses_window_scroll, METH_VARARGS, _curses_window_scroll__doc__},
@@ -1715,8 +1724,9 @@ PyDoc_STRVAR(_curses_window_touchline__doc__,
"touchline(start, count, [changed=True])\n"
"Pretend count lines have been changed, starting with line start.\n"
"\n"
-"If changed is supplied, it specifies whether the affected lines are marked\n"
-"as having been changed (changed=True) or unchanged (changed=False).");
+"If changed is supplied, it specifies whether the affected lines are\n"
+"marked as having been changed (changed=True) or unchanged\n"
+"(changed=False).");
#define _CURSES_WINDOW_TOUCHLINE_METHODDEF \
{"touchline", (PyCFunction)_curses_window_touchline, METH_VARARGS, _curses_window_touchline__doc__},
@@ -1910,11 +1920,12 @@ PyDoc_STRVAR(_curses_cbreak__doc__,
" flag\n"
" If false, the effect is the same as calling nocbreak().\n"
"\n"
-"In cbreak mode (sometimes called \"rare\" mode) normal tty line buffering is\n"
-"turned off and characters are available to be read one by one. However,\n"
-"unlike raw mode, special characters (interrupt, quit, suspend, and flow\n"
-"control) retain their effects on the tty driver and calling program.\n"
-"Calling first raw() then cbreak() leaves the terminal in cbreak mode.");
+"In cbreak mode (sometimes called \"rare\" mode) normal tty line buffering\n"
+"is turned off and characters are available to be read one by one.\n"
+"However, unlike raw mode, special characters (interrupt, quit, suspend,\n"
+"and flow control) retain their effects on the tty driver and calling\n"
+"program. Calling first raw() then cbreak() leaves the terminal in\n"
+"cbreak mode.");
#define _CURSES_CBREAK_METHODDEF \
{"cbreak", _PyCFunction_CAST(_curses_cbreak), METH_FASTCALL, _curses_cbreak__doc__},
@@ -1954,8 +1965,9 @@ PyDoc_STRVAR(_curses_color_content__doc__,
" color_number\n"
" The number of the color (0 - (COLORS-1)).\n"
"\n"
-"A 3-tuple is returned, containing the R, G, B values for the given color,\n"
-"which will be between 0 (no component) and 1000 (maximum amount of component).");
+"A 3-tuple is returned, containing the R, G, B values for the given\n"
+"color, which will be between 0 (no component) and 1000 (maximum amount\n"
+"of component).");
#define _CURSES_COLOR_CONTENT_METHODDEF \
{"color_content", (PyCFunction)_curses_color_content, METH_O, _curses_color_content__doc__},
@@ -1988,7 +2000,8 @@ PyDoc_STRVAR(_curses_color_pair__doc__,
" The number of the color pair.\n"
"\n"
"This attribute value can be combined with A_STANDOUT, A_REVERSE, and the\n"
-"other A_* attributes. pair_number() is the counterpart to this function.");
+"other A_* attributes. pair_number() is the counterpart to this\n"
+"function.");
#define _CURSES_COLOR_PAIR_METHODDEF \
{"color_pair", (PyCFunction)_curses_color_pair, METH_O, _curses_color_pair__doc__},
@@ -2022,9 +2035,9 @@ PyDoc_STRVAR(_curses_curs_set__doc__,
" 0 for invisible, 1 for normal visible, or 2 for very visible.\n"
"\n"
"If the terminal supports the visibility requested, the previous cursor\n"
-"state is returned; otherwise, an exception is raised. On many terminals,\n"
-"the \"visible\" mode is an underline cursor and the \"very visible\" mode is\n"
-"a block cursor.");
+"state is returned; otherwise, an exception is raised. On many\n"
+"terminals, the \"visible\" mode is an underline cursor and the \"very\n"
+"visible\" mode is a block cursor.");
#define _CURSES_CURS_SET_METHODDEF \
{"curs_set", (PyCFunction)_curses_curs_set, METH_O, _curses_curs_set__doc__},
@@ -2076,7 +2089,8 @@ PyDoc_STRVAR(_curses_def_shell_mode__doc__,
"\n"
"Save the current terminal mode as the \"shell\" mode.\n"
"\n"
-"The \"shell\" mode is the mode when the running program is not using curses.\n"
+"The \"shell\" mode is the mode when the running program is not using\n"
+"curses.\n"
"\n"
"Subsequent calls to reset_shell_mode() will restore this mode.");
@@ -2150,7 +2164,8 @@ PyDoc_STRVAR(_curses_echo__doc__,
" flag\n"
" If false, the effect is the same as calling noecho().\n"
"\n"
-"In echo mode, each character input is echoed to the screen as it is entered.");
+"In echo mode, each character input is echoed to the screen as it is\n"
+"entered.");
#define _CURSES_ECHO_METHODDEF \
{"echo", _PyCFunction_CAST(_curses_echo), METH_FASTCALL, _curses_echo__doc__},
@@ -2223,7 +2238,8 @@ PyDoc_STRVAR(_curses_flash__doc__,
"\n"
"Flash the screen.\n"
"\n"
-"That is, change it to reverse-video and then change it back in a short interval.");
+"That is, change it to reverse-video and then change it back in a short\n"
+"interval.");
#define _CURSES_FLASH_METHODDEF \
{"flash", (PyCFunction)_curses_flash, METH_NOARGS, _curses_flash__doc__},
@@ -2243,8 +2259,8 @@ PyDoc_STRVAR(_curses_flushinp__doc__,
"\n"
"Flush all input buffers.\n"
"\n"
-"This throws away any typeahead that has been typed by the user and has not\n"
-"yet been processed by the program.");
+"This throws away any typeahead that has been typed by the user and has\n"
+"not yet been processed by the program.");
#define _CURSES_FLUSHINP_METHODDEF \
{"flushinp", (PyCFunction)_curses_flushinp, METH_NOARGS, _curses_flushinp__doc__},
@@ -2614,8 +2630,9 @@ PyDoc_STRVAR(_curses_init_pair__doc__,
" bg\n"
" Background color number (-1 - (COLORS-1)).\n"
"\n"
-"If the color-pair was previously initialized, the screen is refreshed and\n"
-"all occurrences of that color-pair are changed to the new definition.");
+"If the color-pair was previously initialized, the screen is refreshed\n"
+"and all occurrences of that color-pair are changed to the new\n"
+"definition.");
#define _CURSES_INIT_PAIR_METHODDEF \
{"init_pair", _PyCFunction_CAST(_curses_init_pair), METH_FASTCALL, _curses_init_pair__doc__},
@@ -2774,9 +2791,9 @@ PyDoc_STRVAR(_curses_get_escdelay__doc__,
"\n"
"Gets the curses ESCDELAY setting.\n"
"\n"
-"Gets the number of milliseconds to wait after reading an escape character,\n"
-"to distinguish between an individual escape character entered on the\n"
-"keyboard from escape sequences sent by cursor and function keys.");
+"Gets the number of milliseconds to wait after reading an escape\n"
+"character, to distinguish between an individual escape character entered\n"
+"on the keyboard from escape sequences sent by cursor and function keys.");
#define _CURSES_GET_ESCDELAY_METHODDEF \
{"get_escdelay", (PyCFunction)_curses_get_escdelay, METH_NOARGS, _curses_get_escdelay__doc__},
@@ -2803,9 +2820,9 @@ PyDoc_STRVAR(_curses_set_escdelay__doc__,
" ms\n"
" length of the delay in milliseconds.\n"
"\n"
-"Sets the number of milliseconds to wait after reading an escape character,\n"
-"to distinguish between an individual escape character entered on the\n"
-"keyboard from escape sequences sent by cursor and function keys.");
+"Sets the number of milliseconds to wait after reading an escape\n"
+"character, to distinguish between an individual escape character entered\n"
+"on the keyboard from escape sequences sent by cursor and function keys.");
#define _CURSES_SET_ESCDELAY_METHODDEF \
{"set_escdelay", (PyCFunction)_curses_set_escdelay, METH_O, _curses_set_escdelay__doc__},
@@ -2839,8 +2856,8 @@ PyDoc_STRVAR(_curses_get_tabsize__doc__,
"\n"
"Gets the curses TABSIZE setting.\n"
"\n"
-"Gets the number of columns used by the curses library when converting a tab\n"
-"character to spaces as it adds the tab to a window.");
+"Gets the number of columns used by the curses library when converting\n"
+"a tab character to spaces as it adds the tab to a window.");
#define _CURSES_GET_TABSIZE_METHODDEF \
{"get_tabsize", (PyCFunction)_curses_get_tabsize, METH_NOARGS, _curses_get_tabsize__doc__},
@@ -2867,8 +2884,8 @@ PyDoc_STRVAR(_curses_set_tabsize__doc__,
" size\n"
" rendered cell width of a tab character.\n"
"\n"
-"Sets the number of columns used by the curses library when converting a tab\n"
-"character to spaces as it adds the tab to a window.");
+"Sets the number of columns used by the curses library when converting\n"
+"a tab character to spaces as it adds the tab to a window.");
#define _CURSES_SET_TABSIZE_METHODDEF \
{"set_tabsize", (PyCFunction)_curses_set_tabsize, METH_O, _curses_set_tabsize__doc__},
@@ -3039,8 +3056,8 @@ PyDoc_STRVAR(_curses_longname__doc__,
"\n"
"Return the terminfo long name field describing the current terminal.\n"
"\n"
-"The maximum length of a verbose description is 128 characters. It is defined\n"
-"only after the call to initscr().");
+"The maximum length of a verbose description is 128 characters. It is\n"
+"defined only after the call to initscr().");
#define _CURSES_LONGNAME_METHODDEF \
{"longname", (PyCFunction)_curses_longname, METH_NOARGS, _curses_longname__doc__},
@@ -3097,8 +3114,8 @@ PyDoc_STRVAR(_curses_mouseinterval__doc__,
" Time in milliseconds.\n"
"\n"
"Set the maximum time that can elapse between press and release events in\n"
-"order for them to be recognized as a click, and return the previous interval\n"
-"value.");
+"order for them to be recognized as a click, and return the previous\n"
+"interval value.");
#define _CURSES_MOUSEINTERVAL_METHODDEF \
{"mouseinterval", (PyCFunction)_curses_mouseinterval, METH_O, _curses_mouseinterval__doc__},
@@ -3133,9 +3150,10 @@ PyDoc_STRVAR(_curses_mousemask__doc__,
"Set the mouse events to be reported, and return a tuple (availmask, oldmask).\n"
"\n"
"Return a tuple (availmask, oldmask). availmask indicates which of the\n"
-"specified mouse events can be reported; on complete failure it returns 0.\n"
-"oldmask is the previous value of the given window\'s mouse event mask.\n"
-"If this function is never called, no mouse events are ever reported.");
+"specified mouse events can be reported; on complete failure it returns\n"
+"0. oldmask is the previous value of the given window\'s mouse event\n"
+"mask. If this function is never called, no mouse events are ever\n"
+"reported.");
#define _CURSES_MOUSEMASK_METHODDEF \
{"mousemask", (PyCFunction)_curses_mousemask, METH_O, _curses_mousemask__doc__},
@@ -3267,8 +3285,8 @@ PyDoc_STRVAR(_curses_newwin__doc__,
" begin_x\n"
" Left side x-coordinate.\n"
"\n"
-"By default, the window will extend from the specified position to the lower\n"
-"right corner of the screen.");
+"By default, the window will extend from the specified position to the\n"
+"lower right corner of the screen.");
#define _CURSES_NEWWIN_METHODDEF \
{"newwin", (PyCFunction)_curses_newwin, METH_VARARGS, _curses_newwin__doc__},
@@ -3318,8 +3336,9 @@ PyDoc_STRVAR(_curses_nl__doc__,
" flag\n"
" If false, the effect is the same as calling nonl().\n"
"\n"
-"This mode translates the return key into newline on input, and translates\n"
-"newline into return and line-feed on output. Newline mode is initially on.");
+"This mode translates the return key into newline on input, and\n"
+"translates newline into return and line-feed on output. Newline mode\n"
+"is initially on.");
#define _CURSES_NL_METHODDEF \
{"nl", _PyCFunction_CAST(_curses_nl), METH_FASTCALL, _curses_nl__doc__},
@@ -3396,8 +3415,8 @@ PyDoc_STRVAR(_curses_nonl__doc__,
"\n"
"Leave newline mode.\n"
"\n"
-"Disable translation of return into newline on input, and disable low-level\n"
-"translation of newline into newline/return on output.");
+"Disable translation of return into newline on input, and disable\n"
+"low-level translation of newline into newline/return on output.");
#define _CURSES_NONL_METHODDEF \
{"nonl", (PyCFunction)_curses_nonl, METH_NOARGS, _curses_nonl__doc__},
@@ -3613,8 +3632,8 @@ PyDoc_STRVAR(_curses_raw__doc__,
" If false, the effect is the same as calling noraw().\n"
"\n"
"In raw mode, normal line buffering and processing of interrupt, quit,\n"
-"suspend, and flow control keys are turned off; characters are presented to\n"
-"curses input functions one by one.");
+"suspend, and flow control keys are turned off; characters are presented\n"
+"to curses input functions one by one.");
#define _CURSES_RAW_METHODDEF \
{"raw", _PyCFunction_CAST(_curses_raw), METH_FASTCALL, _curses_raw__doc__},
@@ -3712,8 +3731,8 @@ PyDoc_STRVAR(_curses_resizeterm__doc__,
" ncols\n"
" Width.\n"
"\n"
-"Adjusts other bookkeeping data used by the curses library that record the\n"
-"window dimensions (in particular the SIGWINCH handler).");
+"Adjusts other bookkeeping data used by the curses library that record\n"
+"the window dimensions (in particular the SIGWINCH handler).");
#define _CURSES_RESIZETERM_METHODDEF \
{"resizeterm", _PyCFunction_CAST(_curses_resizeterm), METH_FASTCALL, _curses_resizeterm__doc__},
@@ -3791,10 +3810,11 @@ PyDoc_STRVAR(_curses_resize_term__doc__,
" Width.\n"
"\n"
"When resizing the windows, resize_term() blank-fills the areas that are\n"
-"extended. The calling application should fill in these areas with appropriate\n"
-"data. The resize_term() function attempts to resize all windows. However,\n"
-"due to the calling convention of pads, it is not possible to resize these\n"
-"without additional interaction with the application.");
+"extended. The calling application should fill in these areas with\n"
+"appropriate data. The resize_term() function attempts to resize all\n"
+"windows. However, due to the calling convention of pads, it is not\n"
+"possible to resize these without additional interaction with the\n"
+"application.");
#define _CURSES_RESIZE_TERM_METHODDEF \
{"resize_term", _PyCFunction_CAST(_curses_resize_term), METH_FASTCALL, _curses_resize_term__doc__},
@@ -3929,12 +3949,12 @@ PyDoc_STRVAR(_curses_start_color__doc__,
"\n"
"Initializes eight basic colors and global variables COLORS and COLOR_PAIRS.\n"
"\n"
-"Must be called if the programmer wants to use colors, and before any other\n"
-"color manipulation routine is called. It is good practice to call this\n"
-"routine right after initscr().\n"
+"Must be called if the programmer wants to use colors, and before any\n"
+"other color manipulation routine is called. It is good practice to call\n"
+"this routine right after initscr().\n"
"\n"
-"It also restores the colors on the terminal to the values they had when the\n"
-"terminal was just turned on.");
+"It also restores the colors on the terminal to the values they had when\n"
+"the terminal was just turned on.");
#define _CURSES_START_COLOR_METHODDEF \
{"start_color", (PyCFunction)_curses_start_color, METH_NOARGS, _curses_start_color__doc__},
@@ -4036,8 +4056,8 @@ PyDoc_STRVAR(_curses_tigetnum__doc__,
" capname\n"
" The terminfo capability name.\n"
"\n"
-"The value -2 is returned if capname is not a numeric capability, or -1 if\n"
-"it is canceled or absent from the terminal description.");
+"The value -2 is returned if capname is not a numeric capability, or -1\n"
+"if it is canceled or absent from the terminal description.");
#define _CURSES_TIGETNUM_METHODDEF \
{"tigetnum", (PyCFunction)_curses_tigetnum, METH_O, _curses_tigetnum__doc__},
@@ -4079,8 +4099,8 @@ PyDoc_STRVAR(_curses_tigetstr__doc__,
" capname\n"
" The terminfo capability name.\n"
"\n"
-"None is returned if capname is not a string capability, or is canceled or\n"
-"absent from the terminal description.");
+"None is returned if capname is not a string capability, or is canceled\n"
+"or absent from the terminal description.");
#define _CURSES_TIGETSTR_METHODDEF \
{"tigetstr", (PyCFunction)_curses_tigetstr, METH_O, _curses_tigetstr__doc__},
@@ -4234,14 +4254,14 @@ PyDoc_STRVAR(_curses_use_env__doc__,
"\n"
"Use environment variables LINES and COLUMNS.\n"
"\n"
-"If used, this function should be called before initscr() or newterm() are\n"
-"called.\n"
+"If used, this function should be called before initscr() or newterm()\n"
+"are called.\n"
"\n"
-"When flag is False, the values of lines and columns specified in the terminfo\n"
-"database will be used, even if environment variables LINES and COLUMNS (used\n"
-"by default) are set, or if curses is running in a window (in which case\n"
-"default behavior would be to use the window size if LINES and COLUMNS are\n"
-"not set).");
+"When flag is False, the values of lines and columns specified in the\n"
+"terminfo database will be used, even if environment variables LINES and\n"
+"COLUMNS (used by default) are set, or if curses is running in a window\n"
+"(in which case default behavior would be to use the window size if LINES\n"
+"and COLUMNS are not set).");
#define _CURSES_USE_ENV_METHODDEF \
{"use_env", (PyCFunction)_curses_use_env, METH_O, _curses_use_env__doc__},
@@ -4450,4 +4470,4 @@ _curses_has_extended_color_support(PyObject *module, PyObject *Py_UNUSED(ignored
#ifndef _CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
#define _CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
#endif /* !defined(_CURSES_ASSUME_DEFAULT_COLORS_METHODDEF) */
-/*[clinic end generated code: output=135246e29163510c input=a9049054013a1b77]*/
+/*[clinic end generated code: output=e7c7932f4a4e9bce input=a9049054013a1b77]*/
From cfb2e431cd367ec49098b62048dfd719de38c6fb Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 24 May 2026 15:23:45 +0200
Subject: [PATCH 127/213] [3.15] gh-150285: Fix too long docstrings in the io
module (GH-150287) (GH-150332)
(cherry picked from commit 160dc74122ed4e31540b2ef2c77bda122b02c94a)
Co-authored-by: Serhiy Storchaka
---
Lib/_pyio.py | 130 +++++++++++++++-------------
Modules/_io/_iomodule.c | 89 ++++++++++---------
Modules/_io/bytesio.c | 12 +--
Modules/_io/clinic/_iomodule.c.h | 85 +++++++++---------
Modules/_io/clinic/bytesio.c.h | 10 +--
Modules/_io/clinic/fileio.c.h | 66 +++++++-------
Modules/_io/clinic/iobase.c.h | 16 ++--
Modules/_io/clinic/stringio.c.h | 5 +-
Modules/_io/clinic/textio.c.h | 13 +--
Modules/_io/clinic/winconsoleio.c.h | 8 +-
Modules/_io/fileio.c | 82 +++++++++---------
Modules/_io/iobase.c | 19 ++--
Modules/_io/stringio.c | 5 +-
Modules/_io/textio.c | 18 ++--
Modules/_io/winconsoleio.c | 8 +-
15 files changed, 296 insertions(+), 270 deletions(-)
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index 3306c8a274760b..9739b6d37fb21b 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -83,27 +83,28 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None,
wrapped. (If a file descriptor is given, it is closed when the
returned I/O object is closed, unless closefd is set to False.)
- mode is an optional string that specifies the mode in which the file is
- opened. It defaults to 'r' which means open for reading in text mode. Other
- common values are 'w' for writing (truncating the file if it already
- exists), 'x' for exclusive creation of a new file, and 'a' for appending
- (which on some Unix systems, means that all writes append to the end of the
- file regardless of the current seek position). In text mode, if encoding is
- not specified the encoding used is platform dependent. (For reading and
- writing raw bytes use binary mode and leave encoding unspecified.) The
- available modes are:
-
- ========= ===============================================================
+ mode is an optional string that specifies the mode in which the file
+ is opened. It defaults to 'r' which means open for reading in text
+ mode. Other common values are 'w' for writing (truncating the file if
+ it already exists), 'x' for exclusive creation of a new file, and
+ 'a' for appending (which on some Unix systems, means that all writes
+ append to the end of the file regardless of the current seek position).
+ In text mode, if encoding is not specified the encoding used is platform
+ dependent. (For reading and writing raw bytes use binary mode and leave
+ encoding unspecified.) The available modes are:
+
+ ========= ==========================================================
Character Meaning
- --------- ---------------------------------------------------------------
+ --------- ----------------------------------------------------------
'r' open for reading (default)
'w' open for writing, truncating the file first
'x' create a new file and open it for writing
- 'a' open for writing, appending to the end of the file if it exists
+ 'a' open for writing, appending to the end of the file if it
+ exists
'b' binary mode
't' text mode (default)
'+' open a disk file for updating (reading and writing)
- ========= ===============================================================
+ ========= ==========================================================
The default mode is 'rt' (open for reading text). For binary random
access, the mode 'w+b' opens and truncates the file to 0 bytes, while
@@ -111,23 +112,23 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None,
raises an `FileExistsError` if the file already exists.
Python distinguishes between files opened in binary and text modes,
- even when the underlying operating system doesn't. Files opened in
+ even when the underlying operating system doesn't. Files opened in
binary mode (appending 'b' to the mode argument) return contents as
- bytes objects without any decoding. In text mode (the default, or when
+ bytes objects without any decoding. In text mode (the default, or when
't' is appended to the mode argument), the contents of the file are
returned as strings, the bytes having been first decoded using a
platform-dependent encoding or using the specified encoding if given.
buffering is an optional integer used to set the buffering policy.
- Pass 0 to switch buffering off (only allowed in binary mode), 1 to select
- line buffering (only usable in text mode), and an integer > 1 to indicate
- the size of a fixed-size chunk buffer. When no buffering argument is
- given, the default buffering policy works as follows:
+ Pass 0 to switch buffering off (only allowed in binary mode), 1 to
+ select line buffering (only usable in text mode), and an integer > 1 to
+ indicate the size of a fixed-size chunk buffer. When no buffering
+ argument is given, the default buffering policy works as follows:
- * Binary files are buffered in fixed-size chunks; the size of the buffer
- is max(min(blocksize, 8 MiB), DEFAULT_BUFFER_SIZE)
- when the device block size is available.
- On most systems, the buffer will typically be 128 kilobytes long.
+ * Binary files are buffered in fixed-size chunks; the size of the buffer
+ is max(min(blocksize, 8 MiB), DEFAULT_BUFFER_SIZE) when the device
+ block size is available.
+ On most systems, the buffer will typically be 128 kilobytes long.
* "Interactive" text files (files for which isatty() returns True)
use line buffering. Other text files use the policy described above
@@ -147,8 +148,8 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None,
encoding error strings.
newline is a string controlling how universal newlines works (it only
- applies to text mode). It can be None, '', '\n', '\r', and '\r\n'. It works
- as follows:
+ applies to text mode). It can be None, '', '\n', '\r', and '\r\n'. It
+ works as follows:
* On input, if newline is None, universal newlines mode is
enabled. Lines in the input can end in '\n', '\r', or '\r\n', and
@@ -164,17 +165,17 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None,
other legal values, any '\n' characters written are translated to
the given string.
- closedfd is a bool. If closefd is False, the underlying file descriptor will
- be kept open when the file is closed. This does not work when a file name is
- given and must be True in that case.
+ closedfd is a bool. If closefd is False, the underlying file descriptor
+ will be kept open when the file is closed. This does not work when
+ a file name is given and must be True in that case.
The newly created file is non-inheritable.
A custom opener can be used by passing a callable as *opener*. The
- underlying file descriptor for the file object is then obtained by calling
- *opener* with (*file*, *flags*). *opener* must return an open file
- descriptor (passing os.open as *opener* results in functionality similar to
- passing None).
+ underlying file descriptor for the file object is then obtained by
+ calling *opener* with (*file*, *flags*). *opener* must return an open
+ file descriptor (passing os.open as *opener* results in functionality
+ similar to passing None).
open() returns a file object whose type depends on the mode, and
through which the standard file operations such as reading and writing
@@ -351,10 +352,12 @@ def seek(self, pos, whence=0):
interpreted relative to the position indicated by whence. Values
for whence are ints:
- * 0 -- start of stream (the default); offset should be zero or positive
+ * 0 -- start of stream (the default); offset should be zero or
+ positive
* 1 -- current stream position; offset may be negative
* 2 -- end of stream; offset is usually negative
- Some operating systems / file systems could provide additional values.
+ Some operating systems / file systems could provide additional
+ values.
Return an int indicating the new absolute position.
"""
@@ -367,8 +370,8 @@ def tell(self):
def truncate(self, pos=None):
"""Truncate file to size bytes.
- Size defaults to the current IO position as reported by tell(). Return
- the new size.
+ Size defaults to the current IO position as reported by tell().
+ Return the new size.
"""
self._unsupported("truncate")
@@ -492,7 +495,8 @@ def __exit__(self, *args):
def fileno(self):
"""Returns underlying file descriptor (an int) if one exists.
- An OSError is raised if the IO object does not use a file descriptor.
+ An OSError is raised if the IO object does not use a file
+ descriptor.
"""
self._unsupported("fileno")
@@ -1505,17 +1509,22 @@ class FileIO(RawIOBase):
_closefd = True
def __init__(self, file, mode='r', closefd=True, opener=None):
- """Open a file. The mode can be 'r' (default), 'w', 'x' or 'a' for reading,
- writing, exclusive creation or appending. The file will be created if it
- doesn't exist when opened for writing or appending; it will be truncated
- when opened for writing. A FileExistsError will be raised if it already
- exists when opened for creating. Opening a file for creating implies
- writing so this mode behaves in a similar way to 'w'. Add a '+' to the mode
- to allow simultaneous reading and writing. A custom opener can be used by
- passing a callable as *opener*. The underlying file descriptor for the file
- object is then obtained by calling opener with (*name*, *flags*).
- *opener* must return an open file descriptor (passing os.open as *opener*
- results in functionality similar to passing None).
+ """Open a file.
+
+ The mode can be 'r' (default), 'w', 'x' or 'a' for reading,
+ writing, exclusive creation or appending. The file will be created
+ if it doesn't exist when opened for writing or appending; it will be
+ truncated when opened for writing. A FileExistsError will be raised
+ if it already exists when opened for creating. Opening a file for
+ creating implies writing so this mode behaves in a similar way to
+ 'w'. Add a '+' to the mode to allow simultaneous reading and
+ writing.
+
+ A custom opener can be used by passing a callable as *opener*.
+ The underlying file descriptor for the file object is then obtained
+ by calling opener with (*name*, *flags*). *opener* must return
+ an open file descriptor (passing os.open as *opener* results in
+ functionality similar to passing None).
"""
if self._fd >= 0:
# Have to close the existing file first.
@@ -1754,8 +1763,8 @@ def write(self, b):
"""Write bytes b to file, return number written.
Only makes one system call, so not all of the data may be written.
- The number of bytes actually written is returned. In non-blocking mode,
- returns None if the write would block.
+ The number of bytes actually written is returned. In non-blocking
+ mode, returns None if the write would block.
"""
self._checkClosed()
self._checkWritable()
@@ -1767,11 +1776,12 @@ def write(self, b):
def seek(self, pos, whence=SEEK_SET):
"""Move to new file position.
- Argument offset is a byte count. Optional argument whence defaults to
- SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values
- are SEEK_CUR or 1 (move relative to current position, positive or negative),
- and SEEK_END or 2 (move relative to end of file, usually negative, although
- many platforms allow seeking beyond the end of a file).
+ Argument offset is a byte count. Optional argument whence defaults
+ to SEEK_SET or 0 (offset from start of file, offset should be >= 0);
+ other values are SEEK_CUR or 1 (move relative to current position,
+ positive or negative), and SEEK_END or 2 (move relative to end of
+ file, usually negative, although many platforms allow seeking beyond
+ the end of a file).
Note that not all file objects are seekable.
"""
@@ -1804,8 +1814,8 @@ def truncate(self, size=None):
def close(self):
"""Close the file.
- A closed file cannot be used for further I/O operations. close() may be
- called more than once without error.
+ A closed file cannot be used for further I/O operations.
+ close() may be called more than once without error.
"""
if not self.closed:
self._stat_atopen = None
@@ -1903,8 +1913,8 @@ class TextIOBase(IOBase):
def read(self, size=-1):
"""Read at most size characters from stream, where size is an int.
- Read from underlying buffer until we have size characters or we hit EOF.
- If size is negative or omitted, read until EOF.
+ Read from underlying buffer until we have size characters or we hit
+ EOF. If size is negative or omitted, read until EOF.
Returns a string.
"""
diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c
index 32c55f8e225ed9..03e6fbe08889d4 100644
--- a/Modules/_io/_iomodule.c
+++ b/Modules/_io/_iomodule.c
@@ -70,7 +70,6 @@ PyDoc_STRVAR(module_doc,
/*[clinic input]
module _io
-@permit_long_docstring_body
_io.open
file: object
mode: str = "r"
@@ -86,112 +85,113 @@ Open file and return a stream. Raise OSError upon failure.
file is either a text or byte string giving the name (and the path
if the file isn't in the current working directory) of the file to
be opened or an integer file descriptor of the file to be
-wrapped. (If a file descriptor is given, it is closed when the
+wrapped. (If a file descriptor is given, it is closed when the
returned I/O object is closed, unless closefd is set to False.)
mode is an optional string that specifies the mode in which the file
-is opened. It defaults to 'r' which means open for reading in text
+is opened. It defaults to 'r' which means open for reading in text
mode. Other common values are 'w' for writing (truncating the file if
it already exists), 'x' for creating and writing to a new file, and
'a' for appending (which on some Unix systems, means that all writes
append to the end of the file regardless of the current seek position).
In text mode, if encoding is not specified the encoding used is platform
-dependent: locale.getencoding() is called to get the current locale encoding.
-(For reading and writing raw bytes use binary mode and leave encoding
-unspecified.) The available modes are:
+dependent: locale.getencoding() is called to get the current locale
+encoding. (For reading and writing raw bytes use binary mode and leave
+encoding unspecified.) The available modes are:
-========= ===============================================================
+========= ==========================================================
Character Meaning
---------- ---------------------------------------------------------------
+--------- ----------------------------------------------------------
'r' open for reading (default)
'w' open for writing, truncating the file first
'x' create a new file and open it for writing
-'a' open for writing, appending to the end of the file if it exists
+'a' open for writing, appending to the end of the file if it
+ exists
'b' binary mode
't' text mode (default)
'+' open a disk file for updating (reading and writing)
-========= ===============================================================
+========= ==========================================================
-The default mode is 'rt' (open for reading text). For binary random
+The default mode is 'rt' (open for reading text). For binary random
access, the mode 'w+b' opens and truncates the file to 0 bytes, while
-'r+b' opens the file without truncation. The 'x' mode implies 'w' and
+'r+b' opens the file without truncation. The 'x' mode implies 'w' and
raises an `FileExistsError` if the file already exists.
Python distinguishes between files opened in binary and text modes,
-even when the underlying operating system doesn't. Files opened in
+even when the underlying operating system doesn't. Files opened in
binary mode (appending 'b' to the mode argument) return contents as
-bytes objects without any decoding. In text mode (the default, or when
+bytes objects without any decoding. In text mode (the default, or when
't' is appended to the mode argument), the contents of the file are
returned as strings, the bytes having been first decoded using a
platform-dependent encoding or using the specified encoding if given.
buffering is an optional integer used to set the buffering policy.
-Pass 0 to switch buffering off (only allowed in binary mode), 1 to select
-line buffering (only usable in text mode), and an integer > 1 to indicate
-the size of a fixed-size chunk buffer. When no buffering argument is
-given, the default buffering policy works as follows:
+Pass 0 to switch buffering off (only allowed in binary mode), 1 to
+select line buffering (only usable in text mode), and an integer > 1 to
+indicate the size of a fixed-size chunk buffer. When no buffering
+argument is given, the default buffering policy works as follows:
* Binary files are buffered in fixed-size chunks; the size of the buffer
- is max(min(blocksize, 8 MiB), DEFAULT_BUFFER_SIZE)
- when the device block size is available.
- On most systems, the buffer will typically be 128 kilobytes long.
+ is max(min(blocksize, 8 MiB), DEFAULT_BUFFER_SIZE) when the device
+ block size is available.
+ On most systems, the buffer will typically be 128 kilobytes long.
* "Interactive" text files (files for which isatty() returns True)
use line buffering. Other text files use the policy described above
for binary files.
encoding is the name of the encoding used to decode or encode the
-file. This should only be used in text mode. The default encoding is
+file. This should only be used in text mode. The default encoding is
platform dependent, but any encoding supported by Python can be
passed. See the codecs module for the list of supported encodings.
errors is an optional string that specifies how encoding errors are to
-be handled---this argument should not be used in binary mode. Pass
+be handled---this argument should not be used in binary mode. Pass
'strict' to raise a ValueError exception if there is an encoding error
(the default of None has the same effect), or pass 'ignore' to ignore
-errors. (Note that ignoring encoding errors can lead to data loss.)
+errors. (Note that ignoring encoding errors can lead to data loss.)
See the documentation for codecs.register or run 'help(codecs.Codec)'
for a list of the permitted encoding error strings.
newline controls how universal newlines works (it only applies to text
-mode). It can be None, '', '\n', '\r', and '\r\n'. It works as
+mode). It can be None, '', '\n', '\r', and '\r\n'. It works as
follows:
-* On input, if newline is None, universal newlines mode is
- enabled. Lines in the input can end in '\n', '\r', or '\r\n', and
- these are translated into '\n' before being returned to the
- caller. If it is '', universal newline mode is enabled, but line
- endings are returned to the caller untranslated. If it has any of
- the other legal values, input lines are only terminated by the given
- string, and the line ending is returned to the caller untranslated.
+* On input, if newline is None, universal newlines mode is enabled.
+ Lines in the input can end in '\n', '\r', or '\r\n', and these are
+ translated into '\n' before being returned to the caller. If it is
+ '', universal newline mode is enabled, but line endings are returned
+ to the caller untranslated. If it has any of the other legal values,
+ input lines are only terminated by the given string, and the line
+ ending is returned to the caller untranslated.
* On output, if newline is None, any '\n' characters written are
- translated to the system default line separator, os.linesep. If
- newline is '' or '\n', no translation takes place. If newline is any
+ translated to the system default line separator, os.linesep. If
+ newline is '' or '\n', no translation takes place. If newline is any
of the other legal values, any '\n' characters written are translated
to the given string.
If closefd is False, the underlying file descriptor will be kept open
-when the file is closed. This does not work when a file name is given
+when the file is closed. This does not work when a file name is given
and must be True in that case.
-A custom opener can be used by passing a callable as *opener*. The
+A custom opener can be used by passing a callable as *opener*. The
underlying file descriptor for the file object is then obtained by
-calling *opener* with (*file*, *flags*). *opener* must return an open
+calling *opener* with (*file*, *flags*). *opener* must return an open
file descriptor (passing os.open as *opener* results in functionality
similar to passing None).
open() returns a file object whose type depends on the mode, and
through which the standard file operations such as reading and writing
-are performed. When open() is used to open a file in a text mode ('w',
-'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open
+are performed. When open() is used to open a file in a text mode ('w',
+'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open
a file in a binary mode, the returned class varies: in read binary
mode, it returns a BufferedReader; in write binary and append binary
modes, it returns a BufferedWriter, and in read/write mode, it returns
a BufferedRandom.
It is also possible to use a string or bytearray as a file for both
-reading and writing. For strings StringIO can be used like a file
+reading and writing. For strings StringIO can be used like a file
opened in a text mode, and for bytes a BytesIO can be used like a file
opened in a binary mode.
[clinic start generated code]*/
@@ -200,7 +200,7 @@ static PyObject *
_io_open_impl(PyObject *module, PyObject *file, const char *mode,
int buffering, const char *encoding, const char *errors,
const char *newline, int closefd, PyObject *opener)
-/*[clinic end generated code: output=aefafc4ce2b46dc0 input=8629579a442a99e3]*/
+/*[clinic end generated code: output=aefafc4ce2b46dc0 input=b3cefa70bef404b3]*/
{
size_t i;
@@ -499,21 +499,20 @@ _io_text_encoding_impl(PyObject *module, PyObject *encoding, int stacklevel)
/*[clinic input]
-@permit_long_docstring_body
_io.open_code
path : unicode
Opens the provided file with the intent to import the contents.
-This may perform extra validation beyond open(), but is otherwise interchangeable
-with calling open(path, 'rb').
+This may perform extra validation beyond open(), but is otherwise
+interchangeable with calling open(path, 'rb').
[clinic start generated code]*/
static PyObject *
_io_open_code_impl(PyObject *module, PyObject *path)
-/*[clinic end generated code: output=2fe4ecbd6f3d6844 input=53d38a37d780d034]*/
+/*[clinic end generated code: output=2fe4ecbd6f3d6844 input=2803c35aeb63c719]*/
{
return PyFile_OpenCodeObject(path);
}
diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c
index d088bb0efac797..8cdcbd0d89c718 100644
--- a/Modules/_io/bytesio.c
+++ b/Modules/_io/bytesio.c
@@ -488,13 +488,13 @@ _io.BytesIO.read1
Read at most size bytes, returned as a bytes object.
-If the size argument is negative or omitted, read until EOF is reached.
-Return an empty bytes object at EOF.
+If the size argument is negative or omitted, read until EOF is
+reached. Return an empty bytes object at EOF.
[clinic start generated code]*/
static PyObject *
_io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size)
-/*[clinic end generated code: output=d0f843285aa95f1c input=a08fc9e507ab380c]*/
+/*[clinic end generated code: output=d0f843285aa95f1c input=796ff4e0efccc4d9]*/
{
return _io_BytesIO_read_impl(self, size);
}
@@ -792,13 +792,13 @@ _io.BytesIO.writelines
Write lines to the file.
Note that newlines are not added. lines can be any iterable object
-producing bytes-like objects. This is equivalent to calling write() for
-each element.
+producing bytes-like objects. This is equivalent to calling write()
+for each element.
[clinic start generated code]*/
static PyObject *
_io_BytesIO_writelines_impl(bytesio *self, PyObject *lines)
-/*[clinic end generated code: output=03a43a75773bc397 input=5d6a616ae39dc9ca]*/
+/*[clinic end generated code: output=03a43a75773bc397 input=d265f76533b058e7]*/
{
PyObject *it, *item;
diff --git a/Modules/_io/clinic/_iomodule.c.h b/Modules/_io/clinic/_iomodule.c.h
index 90b80af3018fb0..f03638064385e2 100644
--- a/Modules/_io/clinic/_iomodule.c.h
+++ b/Modules/_io/clinic/_iomodule.c.h
@@ -18,112 +18,113 @@ PyDoc_STRVAR(_io_open__doc__,
"file is either a text or byte string giving the name (and the path\n"
"if the file isn\'t in the current working directory) of the file to\n"
"be opened or an integer file descriptor of the file to be\n"
-"wrapped. (If a file descriptor is given, it is closed when the\n"
+"wrapped. (If a file descriptor is given, it is closed when the\n"
"returned I/O object is closed, unless closefd is set to False.)\n"
"\n"
"mode is an optional string that specifies the mode in which the file\n"
-"is opened. It defaults to \'r\' which means open for reading in text\n"
+"is opened. It defaults to \'r\' which means open for reading in text\n"
"mode. Other common values are \'w\' for writing (truncating the file if\n"
"it already exists), \'x\' for creating and writing to a new file, and\n"
"\'a\' for appending (which on some Unix systems, means that all writes\n"
"append to the end of the file regardless of the current seek position).\n"
"In text mode, if encoding is not specified the encoding used is platform\n"
-"dependent: locale.getencoding() is called to get the current locale encoding.\n"
-"(For reading and writing raw bytes use binary mode and leave encoding\n"
-"unspecified.) The available modes are:\n"
+"dependent: locale.getencoding() is called to get the current locale\n"
+"encoding. (For reading and writing raw bytes use binary mode and leave\n"
+"encoding unspecified.) The available modes are:\n"
"\n"
-"========= ===============================================================\n"
+"========= ==========================================================\n"
"Character Meaning\n"
-"--------- ---------------------------------------------------------------\n"
+"--------- ----------------------------------------------------------\n"
"\'r\' open for reading (default)\n"
"\'w\' open for writing, truncating the file first\n"
"\'x\' create a new file and open it for writing\n"
-"\'a\' open for writing, appending to the end of the file if it exists\n"
+"\'a\' open for writing, appending to the end of the file if it\n"
+" exists\n"
"\'b\' binary mode\n"
"\'t\' text mode (default)\n"
"\'+\' open a disk file for updating (reading and writing)\n"
-"========= ===============================================================\n"
+"========= ==========================================================\n"
"\n"
-"The default mode is \'rt\' (open for reading text). For binary random\n"
+"The default mode is \'rt\' (open for reading text). For binary random\n"
"access, the mode \'w+b\' opens and truncates the file to 0 bytes, while\n"
-"\'r+b\' opens the file without truncation. The \'x\' mode implies \'w\' and\n"
+"\'r+b\' opens the file without truncation. The \'x\' mode implies \'w\' and\n"
"raises an `FileExistsError` if the file already exists.\n"
"\n"
"Python distinguishes between files opened in binary and text modes,\n"
-"even when the underlying operating system doesn\'t. Files opened in\n"
+"even when the underlying operating system doesn\'t. Files opened in\n"
"binary mode (appending \'b\' to the mode argument) return contents as\n"
-"bytes objects without any decoding. In text mode (the default, or when\n"
+"bytes objects without any decoding. In text mode (the default, or when\n"
"\'t\' is appended to the mode argument), the contents of the file are\n"
"returned as strings, the bytes having been first decoded using a\n"
"platform-dependent encoding or using the specified encoding if given.\n"
"\n"
"buffering is an optional integer used to set the buffering policy.\n"
-"Pass 0 to switch buffering off (only allowed in binary mode), 1 to select\n"
-"line buffering (only usable in text mode), and an integer > 1 to indicate\n"
-"the size of a fixed-size chunk buffer. When no buffering argument is\n"
-"given, the default buffering policy works as follows:\n"
+"Pass 0 to switch buffering off (only allowed in binary mode), 1 to\n"
+"select line buffering (only usable in text mode), and an integer > 1 to\n"
+"indicate the size of a fixed-size chunk buffer. When no buffering\n"
+"argument is given, the default buffering policy works as follows:\n"
"\n"
"* Binary files are buffered in fixed-size chunks; the size of the buffer\n"
-" is max(min(blocksize, 8 MiB), DEFAULT_BUFFER_SIZE)\n"
-" when the device block size is available.\n"
-" On most systems, the buffer will typically be 128 kilobytes long.\n"
+" is max(min(blocksize, 8 MiB), DEFAULT_BUFFER_SIZE) when the device\n"
+" block size is available.\n"
+" On most systems, the buffer will typically be 128 kilobytes long.\n"
"\n"
"* \"Interactive\" text files (files for which isatty() returns True)\n"
" use line buffering. Other text files use the policy described above\n"
" for binary files.\n"
"\n"
"encoding is the name of the encoding used to decode or encode the\n"
-"file. This should only be used in text mode. The default encoding is\n"
+"file. This should only be used in text mode. The default encoding is\n"
"platform dependent, but any encoding supported by Python can be\n"
"passed. See the codecs module for the list of supported encodings.\n"
"\n"
"errors is an optional string that specifies how encoding errors are to\n"
-"be handled---this argument should not be used in binary mode. Pass\n"
+"be handled---this argument should not be used in binary mode. Pass\n"
"\'strict\' to raise a ValueError exception if there is an encoding error\n"
"(the default of None has the same effect), or pass \'ignore\' to ignore\n"
-"errors. (Note that ignoring encoding errors can lead to data loss.)\n"
+"errors. (Note that ignoring encoding errors can lead to data loss.)\n"
"See the documentation for codecs.register or run \'help(codecs.Codec)\'\n"
"for a list of the permitted encoding error strings.\n"
"\n"
"newline controls how universal newlines works (it only applies to text\n"
-"mode). It can be None, \'\', \'\\n\', \'\\r\', and \'\\r\\n\'. It works as\n"
+"mode). It can be None, \'\', \'\\n\', \'\\r\', and \'\\r\\n\'. It works as\n"
"follows:\n"
"\n"
-"* On input, if newline is None, universal newlines mode is\n"
-" enabled. Lines in the input can end in \'\\n\', \'\\r\', or \'\\r\\n\', and\n"
-" these are translated into \'\\n\' before being returned to the\n"
-" caller. If it is \'\', universal newline mode is enabled, but line\n"
-" endings are returned to the caller untranslated. If it has any of\n"
-" the other legal values, input lines are only terminated by the given\n"
-" string, and the line ending is returned to the caller untranslated.\n"
+"* On input, if newline is None, universal newlines mode is enabled.\n"
+" Lines in the input can end in \'\\n\', \'\\r\', or \'\\r\\n\', and these are\n"
+" translated into \'\\n\' before being returned to the caller. If it is\n"
+" \'\', universal newline mode is enabled, but line endings are returned\n"
+" to the caller untranslated. If it has any of the other legal values,\n"
+" input lines are only terminated by the given string, and the line\n"
+" ending is returned to the caller untranslated.\n"
"\n"
"* On output, if newline is None, any \'\\n\' characters written are\n"
-" translated to the system default line separator, os.linesep. If\n"
-" newline is \'\' or \'\\n\', no translation takes place. If newline is any\n"
+" translated to the system default line separator, os.linesep. If\n"
+" newline is \'\' or \'\\n\', no translation takes place. If newline is any\n"
" of the other legal values, any \'\\n\' characters written are translated\n"
" to the given string.\n"
"\n"
"If closefd is False, the underlying file descriptor will be kept open\n"
-"when the file is closed. This does not work when a file name is given\n"
+"when the file is closed. This does not work when a file name is given\n"
"and must be True in that case.\n"
"\n"
-"A custom opener can be used by passing a callable as *opener*. The\n"
+"A custom opener can be used by passing a callable as *opener*. The\n"
"underlying file descriptor for the file object is then obtained by\n"
-"calling *opener* with (*file*, *flags*). *opener* must return an open\n"
+"calling *opener* with (*file*, *flags*). *opener* must return an open\n"
"file descriptor (passing os.open as *opener* results in functionality\n"
"similar to passing None).\n"
"\n"
"open() returns a file object whose type depends on the mode, and\n"
"through which the standard file operations such as reading and writing\n"
-"are performed. When open() is used to open a file in a text mode (\'w\',\n"
-"\'r\', \'wt\', \'rt\', etc.), it returns a TextIOWrapper. When used to open\n"
+"are performed. When open() is used to open a file in a text mode (\'w\',\n"
+"\'r\', \'wt\', \'rt\', etc.), it returns a TextIOWrapper. When used to open\n"
"a file in a binary mode, the returned class varies: in read binary\n"
"mode, it returns a BufferedReader; in write binary and append binary\n"
"modes, it returns a BufferedWriter, and in read/write mode, it returns\n"
"a BufferedRandom.\n"
"\n"
"It is also possible to use a string or bytearray as a file for both\n"
-"reading and writing. For strings StringIO can be used like a file\n"
+"reading and writing. For strings StringIO can be used like a file\n"
"opened in a text mode, and for bytes a BytesIO can be used like a file\n"
"opened in a binary mode.");
@@ -352,8 +353,8 @@ PyDoc_STRVAR(_io_open_code__doc__,
"\n"
"Opens the provided file with the intent to import the contents.\n"
"\n"
-"This may perform extra validation beyond open(), but is otherwise interchangeable\n"
-"with calling open(path, \'rb\').");
+"This may perform extra validation beyond open(), but is otherwise\n"
+"interchangeable with calling open(path, \'rb\').");
#define _IO_OPEN_CODE_METHODDEF \
{"open_code", _PyCFunction_CAST(_io_open_code), METH_FASTCALL|METH_KEYWORDS, _io_open_code__doc__},
@@ -410,4 +411,4 @@ _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec
exit:
return return_value;
}
-/*[clinic end generated code: output=7a8e032c0424bce2 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=5190d11f0803bfe8 input=a9049054013a1b77]*/
diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h
index 6595dc937bbcf0..fad11ea6c9f6cf 100644
--- a/Modules/_io/clinic/bytesio.c.h
+++ b/Modules/_io/clinic/bytesio.c.h
@@ -254,8 +254,8 @@ PyDoc_STRVAR(_io_BytesIO_read1__doc__,
"\n"
"Read at most size bytes, returned as a bytes object.\n"
"\n"
-"If the size argument is negative or omitted, read until EOF is reached.\n"
-"Return an empty bytes object at EOF.");
+"If the size argument is negative or omitted, read until EOF is\n"
+"reached. Return an empty bytes object at EOF.");
#define _IO_BYTESIO_READ1_METHODDEF \
{"read1", _PyCFunction_CAST(_io_BytesIO_read1), METH_FASTCALL, _io_BytesIO_read1__doc__},
@@ -529,8 +529,8 @@ PyDoc_STRVAR(_io_BytesIO_writelines__doc__,
"Write lines to the file.\n"
"\n"
"Note that newlines are not added. lines can be any iterable object\n"
-"producing bytes-like objects. This is equivalent to calling write() for\n"
-"each element.");
+"producing bytes-like objects. This is equivalent to calling write()\n"
+"for each element.");
#define _IO_BYTESIO_WRITELINES_METHODDEF \
{"writelines", (PyCFunction)_io_BytesIO_writelines, METH_O, _io_BytesIO_writelines__doc__},
@@ -637,4 +637,4 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=daa81dfdae5ccc57 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=eac3911e207aaf45 input=a9049054013a1b77]*/
diff --git a/Modules/_io/clinic/fileio.c.h b/Modules/_io/clinic/fileio.c.h
index 96c31ce8d6f415..890b6bc3fac9d5 100644
--- a/Modules/_io/clinic/fileio.c.h
+++ b/Modules/_io/clinic/fileio.c.h
@@ -15,8 +15,8 @@ PyDoc_STRVAR(_io_FileIO_close__doc__,
"\n"
"Close the file.\n"
"\n"
-"A closed file cannot be used for further I/O operations. close() may be\n"
-"called more than once without error.");
+"A closed file cannot be used for further I/O operations. close()\n"
+"may be called more than once without error.");
#define _IO_FILEIO_CLOSE_METHODDEF \
{"close", _PyCFunction_CAST(_io_FileIO_close), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_close__doc__},
@@ -41,16 +41,19 @@ PyDoc_STRVAR(_io_FileIO___init____doc__,
"Open a file.\n"
"\n"
"The mode can be \'r\' (default), \'w\', \'x\' or \'a\' for reading,\n"
-"writing, exclusive creation or appending. The file will be created if it\n"
-"doesn\'t exist when opened for writing or appending; it will be truncated\n"
-"when opened for writing. A FileExistsError will be raised if it already\n"
-"exists when opened for creating. Opening a file for creating implies\n"
-"writing so this mode behaves in a similar way to \'w\'.Add a \'+\' to the mode\n"
-"to allow simultaneous reading and writing. A custom opener can be used by\n"
-"passing a callable as *opener*. The underlying file descriptor for the file\n"
-"object is then obtained by calling opener with (*name*, *flags*).\n"
-"*opener* must return an open file descriptor (passing os.open as *opener*\n"
-"results in functionality similar to passing None).");
+"writing, exclusive creation or appending. The file will be created\n"
+"if it doesn\'t exist when opened for writing or appending; it will be\n"
+"truncated when opened for writing. A FileExistsError will be raised\n"
+"if it already exists when opened for creating. Opening a file for\n"
+"creating implies writing so this mode behaves in a similar way to\n"
+"\'w\'. Add a \'+\' to the mode to allow simultaneous reading and\n"
+"writing.\n"
+"\n"
+"A custom opener can be used by passing a callable as *opener*.\n"
+"The underlying file descriptor for the file object is then obtained\n"
+"by calling opener with (*name*, *flags*). *opener* must return\n"
+"an open file descriptor (passing os.open as *opener* results in\n"
+"functionality similar to passing None).");
static int
_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
@@ -270,11 +273,13 @@ PyDoc_STRVAR(_io_FileIO_readall__doc__,
"\n"
"Read all data from the file, returned as bytes.\n"
"\n"
-"Reads until either there is an error or read() returns size 0 (indicates EOF).\n"
-"If the file is already at EOF, returns an empty bytes object.\n"
+"Reads until either there is an error or read() returns size 0\n"
+"(indicates EOF). If the file is already at EOF, returns an empty\n"
+"bytes object.\n"
"\n"
-"In non-blocking mode, returns as much data as could be read before EAGAIN. If no\n"
-"data is available (EAGAIN is returned before bytes are read) returns None.");
+"In non-blocking mode, returns as much data as could be read before\n"
+"EAGAIN. If no data is available (EAGAIN is returned before bytes\n"
+"are read) returns None.");
#define _IO_FILEIO_READALL_METHODDEF \
{"readall", _PyCFunction_CAST(_io_FileIO_readall), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_readall__doc__},
@@ -298,14 +303,14 @@ PyDoc_STRVAR(_io_FileIO_read__doc__,
"\n"
"Read at most size bytes, returned as bytes.\n"
"\n"
-"If size is less than 0, read all bytes in the file making multiple read calls.\n"
-"See ``FileIO.readall``.\n"
+"If size is less than 0, read all bytes in the file making multiple\n"
+"read calls. See ``FileIO.readall``.\n"
"\n"
-"Attempts to make only one system call, retrying only per PEP 475 (EINTR). This\n"
-"means less data may be returned than requested.\n"
+"Attempts to make only one system call, retrying only per PEP 475\n"
+"(EINTR). This means less data may be returned than requested.\n"
"\n"
-"In non-blocking mode, returns None if no data is available. Return an empty\n"
-"bytes object at EOF.");
+"In non-blocking mode, returns None if no data is available. Return\n"
+"an empty bytes object at EOF.");
#define _IO_FILEIO_READ_METHODDEF \
{"read", _PyCFunction_CAST(_io_FileIO_read), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_read__doc__},
@@ -358,8 +363,8 @@ PyDoc_STRVAR(_io_FileIO_write__doc__,
"Write buffer b to file, return number of bytes written.\n"
"\n"
"Only makes one system call, so not all of the data may be written.\n"
-"The number of bytes actually written is returned. In non-blocking mode,\n"
-"returns None if the write would block.");
+"The number of bytes actually written is returned. In non-blocking\n"
+"mode, returns None if the write would block.");
#define _IO_FILEIO_WRITE_METHODDEF \
{"write", _PyCFunction_CAST(_io_FileIO_write), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_write__doc__},
@@ -412,11 +417,12 @@ PyDoc_STRVAR(_io_FileIO_seek__doc__,
"\n"
"Move to new file position and return the file position.\n"
"\n"
-"Argument offset is a byte count. Optional argument whence defaults to\n"
-"SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values\n"
-"are SEEK_CUR or 1 (move relative to current position, positive or negative),\n"
-"and SEEK_END or 2 (move relative to end of file, usually negative, although\n"
-"many platforms allow seeking beyond the end of a file).\n"
+"Argument offset is a byte count. Optional argument whence defaults\n"
+"to SEEK_SET or 0 (offset from start of file, offset should be >= 0);\n"
+"other values are SEEK_CUR or 1 (move relative to current position,\n"
+"positive or negative), and SEEK_END or 2 (move relative to end of\n"
+"file, usually negative, although many platforms allow seeking beyond\n"
+"the end of a file).\n"
"\n"
"Note that not all file objects are seekable.");
@@ -547,4 +553,4 @@ _io_FileIO_isatty(PyObject *self, PyObject *Py_UNUSED(ignored))
#ifndef _IO_FILEIO_TRUNCATE_METHODDEF
#define _IO_FILEIO_TRUNCATE_METHODDEF
#endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */
-/*[clinic end generated code: output=2e48f3df2f189170 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=453d584e2e72f986 input=a9049054013a1b77]*/
diff --git a/Modules/_io/clinic/iobase.c.h b/Modules/_io/clinic/iobase.c.h
index 402448545dfc51..e4438c26431aa8 100644
--- a/Modules/_io/clinic/iobase.c.h
+++ b/Modules/_io/clinic/iobase.c.h
@@ -19,11 +19,13 @@ PyDoc_STRVAR(_io__IOBase_seek__doc__,
" whence\n"
" The relative position to seek from.\n"
"\n"
-"The offset is interpreted relative to the position indicated by whence.\n"
-"Values for whence are:\n"
+"The offset is interpreted relative to the position indicated by\n"
+"whence. Values for whence are:\n"
"\n"
-"* os.SEEK_SET or 0 -- start of stream (the default); offset should be zero or positive\n"
-"* os.SEEK_CUR or 1 -- current stream position; offset may be negative\n"
+"* os.SEEK_SET or 0 -- start of stream (the default); offset should\n"
+" be zero or positive\n"
+"* os.SEEK_CUR or 1 -- current stream position; offset may be\n"
+" negative\n"
"* os.SEEK_END or 2 -- end of stream; offset is usually negative\n"
"\n"
"Return the new absolute position.");
@@ -103,8 +105,8 @@ PyDoc_STRVAR(_io__IOBase_truncate__doc__,
"\n"
"Truncate file to size bytes.\n"
"\n"
-"File pointer is left unchanged. Size defaults to the current IO position\n"
-"as reported by tell(). Return the new size.");
+"File pointer is left unchanged. Size defaults to the current IO\n"
+"position as reported by tell(). Return the new size.");
#define _IO__IOBASE_TRUNCATE_METHODDEF \
{"truncate", _PyCFunction_CAST(_io__IOBase_truncate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__IOBase_truncate__doc__},
@@ -443,4 +445,4 @@ _io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored))
{
return _io__RawIOBase_readall_impl(self);
}
-/*[clinic end generated code: output=9359e74d95534bef input=a9049054013a1b77]*/
+/*[clinic end generated code: output=28c06bb6db32c096 input=a9049054013a1b77]*/
diff --git a/Modules/_io/clinic/stringio.c.h b/Modules/_io/clinic/stringio.c.h
index 83165e5f7ad08b..d6d4afb9b63c62 100644
--- a/Modules/_io/clinic/stringio.c.h
+++ b/Modules/_io/clinic/stringio.c.h
@@ -179,7 +179,8 @@ PyDoc_STRVAR(_io_StringIO_seek__doc__,
"\n"
"Change stream position.\n"
"\n"
-"Seek to character offset pos relative to position indicated by whence:\n"
+"Seek to character offset pos relative to position indicated by\n"
+"whence:\n"
" 0 Start of stream (the default). pos should be >= 0;\n"
" 1 Current position - pos must be 0;\n"
" 2 End of stream - pos must be 0.\n"
@@ -550,4 +551,4 @@ _io_StringIO_newlines_get(PyObject *self, void *Py_UNUSED(context))
return return_value;
}
-/*[clinic end generated code: output=bccc25ef8e6ce9ef input=a9049054013a1b77]*/
+/*[clinic end generated code: output=730c34b2a6c0500b input=a9049054013a1b77]*/
diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h
index 3898a9c2982436..9407076b850cee 100644
--- a/Modules/_io/clinic/textio.c.h
+++ b/Modules/_io/clinic/textio.c.h
@@ -16,7 +16,8 @@ PyDoc_STRVAR(_io__TextIOBase_detach__doc__,
"\n"
"Separate the underlying buffer from the TextIOBase and return it.\n"
"\n"
-"After the underlying buffer has been detached, the TextIO is in an unusable state.");
+"After the underlying buffer has been detached, the TextIO is in\n"
+"an unusable state.");
#define _IO__TEXTIOBASE_DETACH_METHODDEF \
{"detach", _PyCFunction_CAST(_io__TextIOBase_detach), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__TextIOBase_detach__doc__},
@@ -40,8 +41,8 @@ PyDoc_STRVAR(_io__TextIOBase_read__doc__,
"\n"
"Read at most size characters from stream.\n"
"\n"
-"Read from underlying buffer until we have size characters or we hit EOF.\n"
-"If size is negative or omitted, read until EOF.");
+"Read from underlying buffer until we have size characters or we hit\n"
+"EOF. If size is negative or omitted, read until EOF.");
#define _IO__TEXTIOBASE_READ_METHODDEF \
{"read", _PyCFunction_CAST(_io__TextIOBase_read), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__TextIOBase_read__doc__},
@@ -964,8 +965,8 @@ PyDoc_STRVAR(_io_TextIOWrapper_tell__doc__,
"\n"
"Return the stream position as an opaque number.\n"
"\n"
-"The return value of tell() can be given as input to seek(), to restore a\n"
-"previous stream position.");
+"The return value of tell() can be given as input to seek(), to\n"
+"restore a previous stream position.");
#define _IO_TEXTIOWRAPPER_TELL_METHODDEF \
{"tell", (PyCFunction)_io_TextIOWrapper_tell, METH_NOARGS, _io_TextIOWrapper_tell__doc__},
@@ -1328,4 +1329,4 @@ _io_TextIOWrapper__CHUNK_SIZE_set(PyObject *self, PyObject *value, void *Py_UNUS
return return_value;
}
-/*[clinic end generated code: output=c38e6cd5ff4b7eea input=a9049054013a1b77]*/
+/*[clinic end generated code: output=f900b42090c9781c input=a9049054013a1b77]*/
diff --git a/Modules/_io/clinic/winconsoleio.c.h b/Modules/_io/clinic/winconsoleio.c.h
index 7af5923b6c1747..bd8073cd0af3f6 100644
--- a/Modules/_io/clinic/winconsoleio.c.h
+++ b/Modules/_io/clinic/winconsoleio.c.h
@@ -46,9 +46,9 @@ PyDoc_STRVAR(_io__WindowsConsoleIO___init____doc__,
"\n"
"Open a console buffer by file descriptor.\n"
"\n"
-"The mode can be \'rb\' (default), or \'wb\' for reading or writing bytes. All\n"
-"other mode characters will be ignored. Mode \'b\' will be assumed if it is\n"
-"omitted. The *opener* parameter is always ignored.");
+"The mode can be \'rb\' (default), or \'wb\' for reading or writing\n"
+"bytes. All other mode characters will be ignored. Mode \'b\' will be\n"
+"assumed if it is omitted. The *opener* parameter is always ignored.");
static int
_io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
@@ -463,4 +463,4 @@ _io__WindowsConsoleIO_isatty(PyObject *self, PyObject *Py_UNUSED(ignored))
#ifndef _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF
#define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF
#endif /* !defined(_IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF) */
-/*[clinic end generated code: output=ce50bcd905f1f213 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=dfe49dd71f4f4b1d input=a9049054013a1b77]*/
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
index 5d7741fdd830a5..3aeb30dfe24a35 100644
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -153,13 +153,13 @@ _io.FileIO.close
Close the file.
-A closed file cannot be used for further I/O operations. close() may be
-called more than once without error.
+A closed file cannot be used for further I/O operations. close()
+may be called more than once without error.
[clinic start generated code]*/
static PyObject *
_io_FileIO_close_impl(fileio *self, PyTypeObject *cls)
-/*[clinic end generated code: output=c30cbe9d1f23ca58 input=70da49e63db7c64d]*/
+/*[clinic end generated code: output=c30cbe9d1f23ca58 input=b405751dc4163da3]*/
{
PyObject *res;
int rc;
@@ -231,22 +231,25 @@ _io.FileIO.__init__
Open a file.
The mode can be 'r' (default), 'w', 'x' or 'a' for reading,
-writing, exclusive creation or appending. The file will be created if it
-doesn't exist when opened for writing or appending; it will be truncated
-when opened for writing. A FileExistsError will be raised if it already
-exists when opened for creating. Opening a file for creating implies
-writing so this mode behaves in a similar way to 'w'.Add a '+' to the mode
-to allow simultaneous reading and writing. A custom opener can be used by
-passing a callable as *opener*. The underlying file descriptor for the file
-object is then obtained by calling opener with (*name*, *flags*).
-*opener* must return an open file descriptor (passing os.open as *opener*
-results in functionality similar to passing None).
+writing, exclusive creation or appending. The file will be created
+if it doesn't exist when opened for writing or appending; it will be
+truncated when opened for writing. A FileExistsError will be raised
+if it already exists when opened for creating. Opening a file for
+creating implies writing so this mode behaves in a similar way to
+'w'. Add a '+' to the mode to allow simultaneous reading and
+writing.
+
+A custom opener can be used by passing a callable as *opener*.
+The underlying file descriptor for the file object is then obtained
+by calling opener with (*name*, *flags*). *opener* must return
+an open file descriptor (passing os.open as *opener* results in
+functionality similar to passing None).
[clinic start generated code]*/
static int
_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
int closefd, PyObject *opener)
-/*[clinic end generated code: output=23413f68e6484bbd input=588aac967e0ba74b]*/
+/*[clinic end generated code: output=23413f68e6484bbd input=bac4efcd8f930bf3]*/
{
#ifdef MS_WINDOWS
wchar_t *widename = NULL;
@@ -725,7 +728,6 @@ new_buffersize(fileio *self, size_t currentsize)
}
/*[clinic input]
-@permit_long_docstring_body
_io.FileIO.readall
cls: defining_class
@@ -733,16 +735,18 @@ _io.FileIO.readall
Read all data from the file, returned as bytes.
-Reads until either there is an error or read() returns size 0 (indicates EOF).
-If the file is already at EOF, returns an empty bytes object.
+Reads until either there is an error or read() returns size 0
+(indicates EOF). If the file is already at EOF, returns an empty
+bytes object.
-In non-blocking mode, returns as much data as could be read before EAGAIN. If no
-data is available (EAGAIN is returned before bytes are read) returns None.
+In non-blocking mode, returns as much data as could be read before
+EAGAIN. If no data is available (EAGAIN is returned before bytes
+are read) returns None.
[clinic start generated code]*/
static PyObject *
_io_FileIO_readall_impl(fileio *self, PyTypeObject *cls)
-/*[clinic end generated code: output=d546737ec895c462 input=cecda40bf9961299]*/
+/*[clinic end generated code: output=d546737ec895c462 input=65d05bd0169f2df5]*/
{
Py_off_t pos, end;
PyBytesWriter *writer;
@@ -850,7 +854,6 @@ _io_FileIO_readall_impl(fileio *self, PyTypeObject *cls)
}
/*[clinic input]
-@permit_long_docstring_body
_io.FileIO.read
cls: defining_class
size: Py_ssize_t(accept={int, NoneType}) = -1
@@ -858,19 +861,19 @@ _io.FileIO.read
Read at most size bytes, returned as bytes.
-If size is less than 0, read all bytes in the file making multiple read calls.
-See ``FileIO.readall``.
+If size is less than 0, read all bytes in the file making multiple
+read calls. See ``FileIO.readall``.
-Attempts to make only one system call, retrying only per PEP 475 (EINTR). This
-means less data may be returned than requested.
+Attempts to make only one system call, retrying only per PEP 475
+(EINTR). This means less data may be returned than requested.
-In non-blocking mode, returns None if no data is available. Return an empty
-bytes object at EOF.
+In non-blocking mode, returns None if no data is available. Return
+an empty bytes object at EOF.
[clinic start generated code]*/
static PyObject *
_io_FileIO_read_impl(fileio *self, PyTypeObject *cls, Py_ssize_t size)
-/*[clinic end generated code: output=bbd749c7c224143e input=752d1ad3db8564a5]*/
+/*[clinic end generated code: output=bbd749c7c224143e input=c7baa3b440af9337]*/
{
if (self->fd < 0)
return err_closed();
@@ -916,13 +919,13 @@ _io.FileIO.write
Write buffer b to file, return number of bytes written.
Only makes one system call, so not all of the data may be written.
-The number of bytes actually written is returned. In non-blocking mode,
-returns None if the write would block.
+The number of bytes actually written is returned. In non-blocking
+mode, returns None if the write would block.
[clinic start generated code]*/
static PyObject *
_io_FileIO_write_impl(fileio *self, PyTypeObject *cls, Py_buffer *b)
-/*[clinic end generated code: output=927e25be80f3b77b input=2776314f043088f5]*/
+/*[clinic end generated code: output=927e25be80f3b77b input=233f1f70f9e8b09e]*/
{
Py_ssize_t n;
int err;
@@ -1016,7 +1019,6 @@ portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_er
}
/*[clinic input]
-@permit_long_docstring_body
_io.FileIO.seek
pos: object
whence: int = 0
@@ -1024,18 +1026,19 @@ _io.FileIO.seek
Move to new file position and return the file position.
-Argument offset is a byte count. Optional argument whence defaults to
-SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values
-are SEEK_CUR or 1 (move relative to current position, positive or negative),
-and SEEK_END or 2 (move relative to end of file, usually negative, although
-many platforms allow seeking beyond the end of a file).
+Argument offset is a byte count. Optional argument whence defaults
+to SEEK_SET or 0 (offset from start of file, offset should be >= 0);
+other values are SEEK_CUR or 1 (move relative to current position,
+positive or negative), and SEEK_END or 2 (move relative to end of
+file, usually negative, although many platforms allow seeking beyond
+the end of a file).
Note that not all file objects are seekable.
[clinic start generated code]*/
static PyObject *
_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence)
-/*[clinic end generated code: output=c976acdf054e6655 input=f077c492a84c9e62]*/
+/*[clinic end generated code: output=c976acdf054e6655 input=f165a1b4f5d494ad]*/
{
if (self->fd < 0)
return err_closed();
@@ -1063,6 +1066,7 @@ _io_FileIO_tell_impl(fileio *self)
#ifdef HAVE_FTRUNCATE
/*[clinic input]
+@permit_long_summary
_io.FileIO.truncate
cls: defining_class
size as posobj: object = None
@@ -1076,7 +1080,7 @@ The current file position is changed to the value of size.
static PyObject *
_io_FileIO_truncate_impl(fileio *self, PyTypeObject *cls, PyObject *posobj)
-/*[clinic end generated code: output=d936732a49e8d5a2 input=c367fb45d6bb2c18]*/
+/*[clinic end generated code: output=d936732a49e8d5a2 input=8f22152bcf900ed2]*/
{
Py_off_t pos;
int ret;
diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c
index f036ea503b11e8..1253f124108bdb 100644
--- a/Modules/_io/iobase.c
+++ b/Modules/_io/iobase.c
@@ -93,7 +93,6 @@ iobase_unsupported(_PyIO_State *state, const char *message)
/* Positioning */
/*[clinic input]
-@permit_long_docstring_body
_io._IOBase.seek
cls: defining_class
offset: int(unused=True)
@@ -104,11 +103,13 @@ _io._IOBase.seek
Change the stream position to the given byte offset.
-The offset is interpreted relative to the position indicated by whence.
-Values for whence are:
+The offset is interpreted relative to the position indicated by
+whence. Values for whence are:
-* os.SEEK_SET or 0 -- start of stream (the default); offset should be zero or positive
-* os.SEEK_CUR or 1 -- current stream position; offset may be negative
+* os.SEEK_SET or 0 -- start of stream (the default); offset should
+ be zero or positive
+* os.SEEK_CUR or 1 -- current stream position; offset may be
+ negative
* os.SEEK_END or 2 -- end of stream; offset is usually negative
Return the new absolute position.
@@ -117,7 +118,7 @@ Return the new absolute position.
static PyObject *
_io__IOBase_seek_impl(PyObject *self, PyTypeObject *cls,
int Py_UNUSED(offset), int Py_UNUSED(whence))
-/*[clinic end generated code: output=8bd74ea6538ded53 input=a21b5aad416ff6a9]*/
+/*[clinic end generated code: output=8bd74ea6538ded53 input=22eaf07a7a0ee289]*/
{
_PyIO_State *state = get_io_state_by_cls(cls);
return iobase_unsupported(state, "seek");
@@ -144,14 +145,14 @@ _io._IOBase.truncate
Truncate file to size bytes.
-File pointer is left unchanged. Size defaults to the current IO position
-as reported by tell(). Return the new size.
+File pointer is left unchanged. Size defaults to the current IO
+position as reported by tell(). Return the new size.
[clinic start generated code]*/
static PyObject *
_io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls,
PyObject *Py_UNUSED(size))
-/*[clinic end generated code: output=2013179bff1fe8ef input=660ac20936612c27]*/
+/*[clinic end generated code: output=2013179bff1fe8ef input=5b3b6ab3c7abd806]*/
{
_PyIO_State *state = get_io_state_by_cls(cls);
return iobase_unsupported(state, "truncate");
diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c
index 5debae5b42480b..0d9196f3647dde 100644
--- a/Modules/_io/stringio.c
+++ b/Modules/_io/stringio.c
@@ -497,7 +497,8 @@ _io.StringIO.seek
Change stream position.
-Seek to character offset pos relative to position indicated by whence:
+Seek to character offset pos relative to position indicated by
+whence:
0 Start of stream (the default). pos should be >= 0;
1 Current position - pos must be 0;
2 End of stream - pos must be 0.
@@ -506,7 +507,7 @@ Returns the new absolute position.
static PyObject *
_io_StringIO_seek_impl(stringio *self, Py_ssize_t pos, int whence)
-/*[clinic end generated code: output=e9e0ac9a8ae71c25 input=c75ced09343a00d7]*/
+/*[clinic end generated code: output=e9e0ac9a8ae71c25 input=ffef24668fd71a5d]*/
{
CHECK_INITIALIZED(self);
CHECK_CLOSED(self);
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index 347bfe976619e8..e80b75066c59a6 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -53,19 +53,19 @@ _unsupported(_PyIO_State *state, const char *message)
}
/*[clinic input]
-@permit_long_docstring_body
_io._TextIOBase.detach
cls: defining_class
/
Separate the underlying buffer from the TextIOBase and return it.
-After the underlying buffer has been detached, the TextIO is in an unusable state.
+After the underlying buffer has been detached, the TextIO is in
+an unusable state.
[clinic start generated code]*/
static PyObject *
_io__TextIOBase_detach_impl(PyObject *self, PyTypeObject *cls)
-/*[clinic end generated code: output=50915f40c609eaa4 input=8cd0652c17d7f015]*/
+/*[clinic end generated code: output=50915f40c609eaa4 input=8099c088abcb87d8]*/
{
_PyIO_State *state = get_io_state_by_cls(cls);
return _unsupported(state, "detach");
@@ -79,14 +79,14 @@ _io._TextIOBase.read
Read at most size characters from stream.
-Read from underlying buffer until we have size characters or we hit EOF.
-If size is negative or omitted, read until EOF.
+Read from underlying buffer until we have size characters or we hit
+EOF. If size is negative or omitted, read until EOF.
[clinic start generated code]*/
static PyObject *
_io__TextIOBase_read_impl(PyObject *self, PyTypeObject *cls,
int Py_UNUSED(size))
-/*[clinic end generated code: output=51a5178a309ce647 input=f5e37720f9fc563f]*/
+/*[clinic end generated code: output=51a5178a309ce647 input=c9fd4cc1cf1b4614]*/
{
_PyIO_State *state = get_io_state_by_cls(cls);
return _unsupported(state, "read");
@@ -2727,13 +2727,13 @@ _io.TextIOWrapper.tell
Return the stream position as an opaque number.
-The return value of tell() can be given as input to seek(), to restore a
-previous stream position.
+The return value of tell() can be given as input to seek(), to
+restore a previous stream position.
[clinic start generated code]*/
static PyObject *
_io_TextIOWrapper_tell_impl(textio *self)
-/*[clinic end generated code: output=4f168c08bf34ad5f input=415d6b4e4f8e6e8c]*/
+/*[clinic end generated code: output=4f168c08bf34ad5f input=aeece020f747fd92]*/
{
PyObject *res;
PyObject *posobj = NULL;
diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c
index 4a3fc586fa3a14..4cd71094e8f459 100644
--- a/Modules/_io/winconsoleio.c
+++ b/Modules/_io/winconsoleio.c
@@ -315,16 +315,16 @@ _io._WindowsConsoleIO.__init__
Open a console buffer by file descriptor.
-The mode can be 'rb' (default), or 'wb' for reading or writing bytes. All
-other mode characters will be ignored. Mode 'b' will be assumed if it is
-omitted. The *opener* parameter is always ignored.
+The mode can be 'rb' (default), or 'wb' for reading or writing
+bytes. All other mode characters will be ignored. Mode 'b' will be
+assumed if it is omitted. The *opener* parameter is always ignored.
[clinic start generated code]*/
static int
_io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
const char *mode, int closefd,
PyObject *opener)
-/*[clinic end generated code: output=3fd9cbcdd8d95429 input=7a3eed6bbe998fd9]*/
+/*[clinic end generated code: output=3fd9cbcdd8d95429 input=f31100e2cd724617]*/
{
const char *s;
wchar_t *name = NULL;
From e8f534d1af4ff925d7f1d90c63f2faf34198d597 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 24 May 2026 15:24:08 +0200
Subject: [PATCH 128/213] [3.15] gh-150285: Fix too long docstrings in the
decimal module (GH-150288) (GH-150333)
(cherry picked from commit 6bed57a3b659a34c4a7d75e76f4fe840f762bf7f)
Co-authored-by: Serhiy Storchaka
---
Lib/_pydecimal.py | 107 ++++++++--------
Modules/_decimal/_decimal.c | 175 ++++++++++++++-------------
Modules/_decimal/clinic/_decimal.c.h | 122 ++++++++++---------
3 files changed, 213 insertions(+), 191 deletions(-)
diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py
index ef889ea0cc834c..8c0afd14d616e8 100644
--- a/Lib/_pydecimal.py
+++ b/Lib/_pydecimal.py
@@ -107,8 +107,8 @@ class DecimalException(ArithmeticError):
anything, though.
handle -- Called when context._raise_error is called and the
- trap_enabler is not set. First argument is self, second is the
- context. More arguments can be given, those being after
+ trap_enabler is not set. First argument is self, second is
+ the context. More arguments can be given, those being after
the explanation in _raise_error (For example,
context._raise_error(NewError, '(-x)!', self._sign) would
call NewError().handle(context, self._sign).)
@@ -225,11 +225,12 @@ class InvalidContext(InvalidOperation):
"""Invalid context. Unknown rounding, for example.
This occurs and signals invalid-operation if an invalid context was
- detected during an operation. This can occur if contexts are not checked
- on creation and either the precision exceeds the capability of the
- underlying concrete representation or an unknown or unsupported rounding
- was specified. These aspects of the context need only be checked when
- the values are required to be used. The result is [0,qNaN].
+ detected during an operation. This can occur if contexts are not
+ checked on creation and either the precision exceeds the capability of
+ the underlying concrete representation or an unknown or unsupported
+ rounding was specified. These aspects of the context need only be
+ checked when the values are required to be used. The result is
+ [0,qNaN].
"""
def handle(self, context, *args):
@@ -322,8 +323,9 @@ class FloatOperation(DecimalException, TypeError):
Decimal.from_float() or context.create_decimal_from_float() do not
set the flag.
- Otherwise (the signal is trapped), only equality comparisons and explicit
- conversions are silent. All other mixed operations raise FloatOperation.
+ Otherwise (the signal is trapped), only equality comparisons and
+ explicit conversions are silent. All other mixed operations raise
+ FloatOperation.
"""
# List of public traps and flags
@@ -2901,8 +2903,8 @@ def compare_total(self, other, context=None):
"""Compares self to other using the abstract representations.
This is not like the standard compare, which use their numerical
- value. Note that a total ordering is defined for all possible abstract
- representations.
+ value. Note that a total ordering is defined for all possible
+ abstract representations.
"""
other = _convert_other(other, raiseit=True)
@@ -2973,7 +2975,8 @@ def compare_total(self, other, context=None):
def compare_total_mag(self, other, context=None):
"""Compares self to other using abstract repr., ignoring sign.
- Like compare_total, but with operand's sign ignored and assumed to be 0.
+ Like compare_total, but with operand's sign ignored and assumed to
+ be 0.
"""
other = _convert_other(other, raiseit=True)
@@ -4110,9 +4113,9 @@ def create_decimal_from_float(self, f):
def abs(self, a):
"""Returns the absolute value of the operand.
- If the operand is negative, the result is the same as using the minus
- operation on the operand. Otherwise, the result is the same as using
- the plus operation on the operand.
+ If the operand is negative, the result is the same as using the
+ minus operation on the operand. Otherwise, the result is the same
+ as using the plus operation on the operand.
>>> ExtendedContext.abs(Decimal('2.1'))
Decimal('2.1')
@@ -4168,16 +4171,17 @@ def canonical(self, a):
def compare(self, a, b):
"""Compares values numerically.
- If the signs of the operands differ, a value representing each operand
- ('-1' if the operand is less than zero, '0' if the operand is zero or
- negative zero, or '1' if the operand is greater than zero) is used in
- place of that operand for the comparison instead of the actual
- operand.
+ If the signs of the operands differ, a value representing each
+ operand ('-1' if the operand is less than zero, '0' if the operand
+ is zero or negative zero, or '1' if the operand is greater than
+ zero) is used in place of that operand for the comparison instead of
+ the actual operand.
- The comparison is then effected by subtracting the second operand from
- the first and then returning a value according to the result of the
- subtraction: '-1' if the result is less than zero, '0' if the result is
- zero or negative zero, or '1' if the result is greater than zero.
+ The comparison is then effected by subtracting the second operand
+ from the first and then returning a value according to the result of
+ the subtraction: '-1' if the result is less than zero, '0' if the
+ result is zero or negative zero, or '1' if the result is greater
+ than zero.
>>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
Decimal('-1')
@@ -4240,8 +4244,8 @@ def compare_total(self, a, b):
"""Compares two operands using their abstract representation.
This is not like the standard compare, which use their numerical
- value. Note that a total ordering is defined for all possible abstract
- representations.
+ value. Note that a total ordering is defined for all possible
+ abstract representations.
>>> ExtendedContext.compare_total(Decimal('12.73'), Decimal('127.9'))
Decimal('-1')
@@ -4268,7 +4272,8 @@ def compare_total(self, a, b):
def compare_total_mag(self, a, b):
"""Compares two operands using their abstract representation ignoring sign.
- Like compare_total, but with operand's sign ignored and assumed to be 0.
+ Like compare_total, but with operand's sign ignored and assumed to
+ be 0.
"""
a = _convert_other(a, raiseit=True)
return a.compare_total_mag(b)
@@ -4926,8 +4931,8 @@ def multiply(self, a, b):
If either operand is a special value then the general rules apply.
Otherwise, the operands are multiplied together
- ('long multiplication'), resulting in a number which may be as long as
- the sum of the lengths of the two operands.
+ ('long multiplication'), resulting in a number which may be as long
+ as the sum of the lengths of the two operands.
>>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
Decimal('3.60')
@@ -5203,19 +5208,19 @@ def quantize(self, a, b):
"""Returns a value equal to 'a' (rounded), having the exponent of 'b'.
The coefficient of the result is derived from that of the left-hand
- operand. It may be rounded using the current rounding setting (if the
- exponent is being increased), multiplied by a positive power of ten (if
- the exponent is being decreased), or is unchanged (if the exponent is
- already equal to that of the right-hand operand).
+ operand. It may be rounded using the current rounding setting (if
+ the exponent is being increased), multiplied by a positive power of
+ ten (if the exponent is being decreased), or is unchanged (if the
+ exponent is already equal to that of the right-hand operand).
Unlike other operations, if the length of the coefficient after the
quantize operation would be greater than precision then an Invalid
- operation condition is raised. This guarantees that, unless there is
- an error condition, the exponent of the result of a quantize is always
- equal to that of the right-hand operand.
+ operation condition is raised. This guarantees that, unless there
+ is an error condition, the exponent of the result of a quantize is
+ always equal to that of the right-hand operand.
- Also unlike other operations, quantize will never raise Underflow, even
- if the result is subnormal and inexact.
+ Also unlike other operations, quantize will never raise Underflow,
+ even if the result is subnormal and inexact.
>>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
Decimal('2.170')
@@ -5269,13 +5274,13 @@ def remainder(self, a, b):
"""Returns the remainder from integer division.
The result is the residue of the dividend after the operation of
- calculating integer division as described for divide-integer, rounded
- to precision digits if necessary. The sign of the result, if
- non-zero, is the same as that of the original dividend.
+ calculating integer division as described for divide-integer,
+ rounded to precision digits if necessary. The sign of the result,
+ if non-zero, is the same as that of the original dividend.
- This operation will fail under the same conditions as integer division
- (that is, if integer division on the same two operands would fail, the
- remainder cannot be calculated).
+ This operation will fail under the same conditions as integer
+ division (that is, if integer division on the same two operands
+ would fail, the remainder cannot be calculated).
>>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
Decimal('2.1')
@@ -5309,9 +5314,9 @@ def remainder_near(self, a, b):
is chosen). If the result is equal to 0 then its sign will be the
sign of a.
- This operation will fail under the same conditions as integer division
- (that is, if integer division on the same two operands would fail, the
- remainder cannot be calculated).
+ This operation will fail under the same conditions as integer
+ division (that is, if integer division on the same two operands
+ would fail, the remainder cannot be calculated).
>>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
Decimal('-0.9')
@@ -5369,8 +5374,8 @@ def rotate(self, a, b):
def same_quantum(self, a, b):
"""Returns True if the two operands have the same exponent.
- The result is never affected by either the sign or the coefficient of
- either operand.
+ The result is never affected by either the sign or the coefficient
+ of either operand.
>>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
False
@@ -5442,8 +5447,8 @@ def shift(self, a, b):
def sqrt(self, a):
"""Square root of a non-negative number to context precision.
- If the result must be inexact, it is rounded using the round-half-even
- algorithm.
+ If the result must be inexact, it is rounded using the
+ round-half-even algorithm.
>>> ExtendedContext.sqrt(Decimal('0'))
Decimal('0')
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c
index 0a8308d9ebce7a..2760792a3fe18e 100644
--- a/Modules/_decimal/_decimal.c
+++ b/Modules/_decimal/_decimal.c
@@ -939,13 +939,13 @@ _decimal.Context.Etop
Return a value equal to Emax - prec + 1.
-This is the maximum exponent if the _clamp field of the context is set
-to 1 (IEEE clamp mode). Etop() must not be negative.
+This is the maximum exponent if the _clamp field of the context is
+set to 1 (IEEE clamp mode). Etop() must not be negative.
[clinic start generated code]*/
static PyObject *
_decimal_Context_Etop_impl(PyObject *self)
-/*[clinic end generated code: output=f0a3f6e1b829074e input=838a4409316ec728]*/
+/*[clinic end generated code: output=f0a3f6e1b829074e input=35b9defc69d5e5d1]*/
{
return PyLong_FromSsize_t(mpd_etop(CTX(self)));
}
@@ -2997,6 +2997,7 @@ PyDecType_FromSequenceExact(PyTypeObject *type, PyObject *v,
PyDecType_FromSequenceExact((st)->PyDec_Type, sequence, context)
/*[clinic input]
+@permit_long_docstring_body
@classmethod
_decimal.Decimal.from_float
@@ -3022,7 +3023,7 @@ Decimal.from_float(0.1) is not the same as Decimal('0.1').
static PyObject *
_decimal_Decimal_from_float_impl(PyTypeObject *type, PyTypeObject *cls,
PyObject *pyfloat)
-/*[clinic end generated code: output=fcb7d55d2f9dc790 input=03bc8dbe963e52ca]*/
+/*[clinic end generated code: output=fcb7d55d2f9dc790 input=29abf05dd8fe79e4]*/
{
PyObject *context;
PyObject *result;
@@ -3068,6 +3069,8 @@ PyDecType_FromNumberExact(PyTypeObject *type, PyTypeObject *cls,
}
/*[clinic input]
+@permit_long_summary
+@permit_long_docstring_body
@classmethod
_decimal.Decimal.from_number
@@ -3088,7 +3091,7 @@ Class method that converts a real number to a decimal number, exactly.
static PyObject *
_decimal_Decimal_from_number_impl(PyTypeObject *type, PyTypeObject *cls,
PyObject *number)
-/*[clinic end generated code: output=4d3ec722b7acfd8b input=271cb4feb3148804]*/
+/*[clinic end generated code: output=4d3ec722b7acfd8b input=34ff3696955d3def]*/
{
PyObject *context;
PyObject *result;
@@ -3959,6 +3962,7 @@ dec_as_long(PyObject *dec, PyObject *context, int round)
}
/*[clinic input]
+@permit_long_summary
_decimal.Decimal.as_integer_ratio
cls: defining_class
@@ -3971,7 +3975,7 @@ Raise OverflowError on infinities and a ValueError on NaNs.
static PyObject *
_decimal_Decimal_as_integer_ratio_impl(PyObject *self, PyTypeObject *cls)
-/*[clinic end generated code: output=eb49c512701f844b input=07e33d8852184761]*/
+/*[clinic end generated code: output=eb49c512701f844b input=136f1dc585ca8d80]*/
{
PyObject *numerator = NULL;
PyObject *denominator = NULL;
@@ -4146,17 +4150,17 @@ _decimal.Decimal.to_integral_exact = _decimal.Decimal.to_integral_value
Round to the nearest integer.
-Decimal.to_integral_exact() signals Inexact or Rounded as appropriate
-if rounding occurs. The rounding mode is determined by the rounding
-parameter if given, else by the given context. If neither parameter is
-given, then the rounding mode of the current default context is used.
+This method signals Inexact or Rounded as appropriate if rounding
+occurs. The rounding mode is determined by the rounding parameter
+if given, else by the given context. If neither parameter is given,
+then the rounding mode of the current default context is used.
[clinic start generated code]*/
static PyObject *
_decimal_Decimal_to_integral_exact_impl(PyObject *self, PyTypeObject *cls,
PyObject *rounding,
PyObject *context)
-/*[clinic end generated code: output=543a39a02eea9917 input=fabce7a744b8087c]*/
+/*[clinic end generated code: output=543a39a02eea9917 input=d4d8abe543393de1]*/
{
PyObject *result;
uint32_t status = 0;
@@ -4791,13 +4795,14 @@ _decimal.Decimal.sqrt = _decimal.Decimal.exp
Return the square root of the argument to full precision.
-The result is correctly rounded using the ROUND_HALF_EVEN rounding mode.
+The result is correctly rounded using the ROUND_HALF_EVEN rounding
+mode.
[clinic start generated code]*/
static PyObject *
_decimal_Decimal_sqrt_impl(PyObject *self, PyTypeObject *cls,
PyObject *context)
-/*[clinic end generated code: output=deb1280077b5e586 input=3a76afbd39dc20b9]*/
+/*[clinic end generated code: output=deb1280077b5e586 input=c565a7216e9605e7]*/
Dec_UnaryFuncVA(mpd_qsqrt)
/* Binary arithmetic functions, optional context arg */
@@ -4853,6 +4858,7 @@ _decimal_Decimal_max_impl(PyObject *self, PyTypeObject *cls, PyObject *other,
Dec_BinaryFuncVA(mpd_qmax)
/*[clinic input]
+@permit_long_summary
_decimal.Decimal.max_mag = _decimal.Decimal.compare
As the max() method, but compares the absolute values of the operands.
@@ -4861,7 +4867,7 @@ As the max() method, but compares the absolute values of the operands.
static PyObject *
_decimal_Decimal_max_mag_impl(PyObject *self, PyTypeObject *cls,
PyObject *other, PyObject *context)
-/*[clinic end generated code: output=f71f2c27d9bc7cac input=88b105e66cf138c5]*/
+/*[clinic end generated code: output=f71f2c27d9bc7cac input=5f81b9da49b45e5d]*/
Dec_BinaryFuncVA(mpd_qmax_mag)
/*[clinic input]
@@ -4880,6 +4886,7 @@ _decimal_Decimal_min_impl(PyObject *self, PyTypeObject *cls, PyObject *other,
Dec_BinaryFuncVA(mpd_qmin)
/*[clinic input]
+@permit_long_summary
_decimal.Decimal.min_mag = _decimal.Decimal.compare
As the min() method, but compares the absolute values of the operands.
@@ -4888,7 +4895,7 @@ As the min() method, but compares the absolute values of the operands.
static PyObject *
_decimal_Decimal_min_mag_impl(PyObject *self, PyTypeObject *cls,
PyObject *other, PyObject *context)
-/*[clinic end generated code: output=018562ad1c22aae3 input=351fa3c0e592746a]*/
+/*[clinic end generated code: output=018562ad1c22aae3 input=94c29817c7f16db7]*/
Dec_BinaryFuncVA(mpd_qmin_mag)
/*[clinic input]
@@ -4896,16 +4903,16 @@ _decimal.Decimal.next_toward = _decimal.Decimal.compare
Returns the number closest to self, in the direction towards other.
-If the two operands are unequal, return the number closest to the first
-operand in the direction of the second operand. If both operands are
-numerically equal, return a copy of the first operand with the sign set
-to be the same as the sign of the second operand.
+If the two operands are unequal, return the number closest to the
+first operand in the direction of the second operand. If both
+operands are numerically equal, return a copy of the first operand
+with the sign set to be the same as the sign of the second operand.
[clinic start generated code]*/
static PyObject *
_decimal_Decimal_next_toward_impl(PyObject *self, PyTypeObject *cls,
PyObject *other, PyObject *context)
-/*[clinic end generated code: output=71d879bca8bc1019 input=fdf0091ea6e9e416]*/
+/*[clinic end generated code: output=71d879bca8bc1019 input=adc5d453fc140341]*/
Dec_BinaryFuncVA(mpd_qnext_toward)
/*[clinic input]
@@ -4914,10 +4921,10 @@ _decimal.Decimal.remainder_near = _decimal.Decimal.compare
Return the remainder from dividing self by other.
This differs from self % other in that the sign of the remainder is
-chosen so as to minimize its absolute value. More precisely, the return
-value is self - n * other where n is the integer nearest to the exact
-value of self / other, and if two integers are equally near then the
-even one is chosen.
+chosen so as to minimize its absolute value. More precisely, the
+return value is self - n * other where n is the integer nearest to
+the exact value of self / other, and if two integers are equally
+near then the even one is chosen.
If the result is zero then its sign will be the sign of self.
[clinic start generated code]*/
@@ -4925,7 +4932,7 @@ If the result is zero then its sign will be the sign of self.
static PyObject *
_decimal_Decimal_remainder_near_impl(PyObject *self, PyTypeObject *cls,
PyObject *other, PyObject *context)
-/*[clinic end generated code: output=d3fbb4985f2077fa input=eb5a8dfe3470b794]*/
+/*[clinic end generated code: output=d3fbb4985f2077fa input=dcb66d4afa0c77c3]*/
Dec_BinaryFuncVA(mpd_qrem_near)
/* Ternary arithmetic functions, optional context arg */
@@ -4992,6 +4999,7 @@ _decimal_Decimal_is_infinite_impl(PyObject *self)
Dec_BoolFunc(mpd_isinfinite)
/*[clinic input]
+@permit_long_summary
_decimal.Decimal.is_nan
Return True if the argument is a (quiet or signaling) NaN, else False.
@@ -4999,7 +5007,7 @@ Return True if the argument is a (quiet or signaling) NaN, else False.
static PyObject *
_decimal_Decimal_is_nan_impl(PyObject *self)
-/*[clinic end generated code: output=b704e8b49a164388 input=795e5dac85976994]*/
+/*[clinic end generated code: output=b704e8b49a164388 input=b7d8f0d59fe2332a]*/
Dec_BoolFunc(mpd_isnan)
/*[clinic input]
@@ -5153,13 +5161,13 @@ _decimal.Decimal.radix
Return Decimal(10).
-This is the radix (base) in which the Decimal class does
-all its arithmetic. Included for compatibility with the specification.
+This is the radix (base) in which the Decimal class does all its
+arithmetic. Included for compatibility with the specification.
[clinic start generated code]*/
static PyObject *
_decimal_Decimal_radix_impl(PyObject *self, PyTypeObject *cls)
-/*[clinic end generated code: output=40a3bc7ec3d99228 input=b0d4cb9f870bbac1]*/
+/*[clinic end generated code: output=40a3bc7ec3d99228 input=d1cdbdbbbdefdec2]*/
{
decimal_state *state = PyType_GetModuleState(cls);
return _dec_mpd_radix(state);
@@ -5250,15 +5258,15 @@ _decimal.Decimal.logb = _decimal.Decimal.exp
Return the adjusted exponent of the operand as a Decimal instance.
-If the operand is a zero, then Decimal('-Infinity') is returned and the
-DivisionByZero condition is raised. If the operand is an infinity then
-Decimal('Infinity') is returned.
+If the operand is a zero, then Decimal('-Infinity') is returned and
+the DivisionByZero condition is raised. If the operand is an
+infinity then Decimal('Infinity') is returned.
[clinic start generated code]*/
static PyObject *
_decimal_Decimal_logb_impl(PyObject *self, PyTypeObject *cls,
PyObject *context)
-/*[clinic end generated code: output=36b0bda09e934245 input=a8df027d1b8a2b17]*/
+/*[clinic end generated code: output=36b0bda09e934245 input=eeafa6bbf8d8a013]*/
Dec_UnaryFuncVA(mpd_qlogb)
/*[clinic input]
@@ -5280,14 +5288,15 @@ The returned value is one of the following ten strings:
* '+Normal', indicating that the operand is a positive normal
number.
* '+Infinity', indicating that the operand is positive infinity.
- * 'NaN', indicating that the operand is a quiet NaN (Not a Number).
+ * 'NaN', indicating that the operand is a quiet NaN (Not a
+ Number).
* 'sNaN', indicating that the operand is a signaling NaN.
[clinic start generated code]*/
static PyObject *
_decimal_Decimal_number_class_impl(PyObject *self, PyTypeObject *cls,
PyObject *context)
-/*[clinic end generated code: output=1ac82412e0849c52 input=447095d2677fa0ca]*/
+/*[clinic end generated code: output=1ac82412e0849c52 input=0b59852b43c521aa]*/
{
const char *cp;
@@ -5303,19 +5312,19 @@ _decimal.Decimal.to_eng_string = _decimal.Decimal.exp
Convert to an engineering-type string.
-Engineering notation has an exponent which is a multiple of 3, so there
-are up to 3 digits left of the decimal place. For example,
+Engineering notation has an exponent which is a multiple of 3, so
+there are up to 3 digits left of the decimal place. For example,
Decimal('123E+1') is converted to Decimal('1.23E+3').
-The value of context.capitals determines whether the exponent sign is
-lower or upper case. Otherwise, the context does not affect the
+The value of context.capitals determines whether the exponent sign
+is lower or upper case. Otherwise, the context does not affect the
operation.
[clinic start generated code]*/
static PyObject *
_decimal_Decimal_to_eng_string_impl(PyObject *self, PyTypeObject *cls,
PyObject *context)
-/*[clinic end generated code: output=901f128d437ae5c0 input=b2cb7e01e268e45d]*/
+/*[clinic end generated code: output=901f128d437ae5c0 input=111db4de6561f211]*/
{
PyObject *result;
mpd_ssize_t size;
@@ -5343,31 +5352,31 @@ _decimal.Decimal.compare_total = _decimal.Decimal.compare
Compare two operands using their abstract representation.
-Similar to the compare() method, but the result
-gives a total ordering on Decimal instances. Two Decimal instances with
-the same numeric value but different representations compare unequal
-in this ordering:
+Similar to the compare() method, but the result gives a total
+ordering on Decimal instances. Two Decimal instances with the same
+numeric value but different representations compare unequal in this
+ordering:
>>> Decimal('12.0').compare_total(Decimal('12'))
Decimal('-1')
-Quiet and signaling NaNs are also included in the total ordering. The
-result of this function is Decimal('0') if both operands have the same
-representation, Decimal('-1') if the first operand is lower in the
-total order than the second, and Decimal('1') if the first operand is
-higher in the total order than the second operand. See the
-specification for details of the total order.
+Quiet and signaling NaNs are also included in the total ordering.
+The result of this function is Decimal('0') if both operands have
+the same representation, Decimal('-1') if the first operand is lower
+in the total order than the second, and Decimal('1') if the first
+operand is higher in the total order than the second operand. See
+the specification for details of the total order.
This operation is unaffected by context and is quiet: no flags are
-changed and no rounding is performed. As an exception, the C version
-may raise InvalidOperation if the second operand cannot be converted
-exactly.
+changed and no rounding is performed. As an exception, the C
+version may raise InvalidOperation if the second operand cannot be
+converted exactly.
[clinic start generated code]*/
static PyObject *
_decimal_Decimal_compare_total_impl(PyObject *self, PyTypeObject *cls,
PyObject *other, PyObject *context)
-/*[clinic end generated code: output=83649010bad7815f input=6f3111ec5fdbf3c1]*/
+/*[clinic end generated code: output=83649010bad7815f input=d795bf204b9ff2a8]*/
Dec_BinaryFuncVA_NO_CTX(mpd_compare_total)
/*[clinic input]
@@ -5516,18 +5525,19 @@ _decimal.Decimal.rotate = _decimal.Decimal.compare
Returns a rotated copy of self's digits, value-of-other times.
-The second operand must be an integer in the range -precision through
-precision. The absolute value of the second operand gives the number of
-places to rotate. If the second operand is positive then rotation is to
-the left; otherwise rotation is to the right. The coefficient of the
-first operand is padded on the left with zeros to length precision if
-necessary. The sign and exponent of the first operand are unchanged.
+The second operand must be an integer in the range -precision
+through precision. The absolute value of the second operand gives
+the number of places to rotate. If the second operand is positive
+then rotation is to the left; otherwise rotation is to the right.
+The coefficient of the first operand is padded on the left with
+zeros to length precision if necessary. The sign and exponent of
+the first operand are unchanged.
[clinic start generated code]*/
static PyObject *
_decimal_Decimal_rotate_impl(PyObject *self, PyTypeObject *cls,
PyObject *other, PyObject *context)
-/*[clinic end generated code: output=09f2737082882b83 input=cde7b032eac43f0b]*/
+/*[clinic end generated code: output=09f2737082882b83 input=4bc840d51842934c]*/
Dec_BinaryFuncVA(mpd_qrotate)
/*[clinic input]
@@ -5550,18 +5560,18 @@ _decimal.Decimal.shift = _decimal.Decimal.compare
Returns a shifted copy of self's digits, value-of-other times.
-The second operand must be an integer in the range -precision through
-precision. The absolute value of the second operand gives the number
-of places to shift. If the second operand is positive, then the shift
-is to the left; otherwise the shift is to the right. Digits shifted
-into the coefficient are zeros. The sign and exponent of the first
-operand are unchanged.
+The second operand must be an integer in the range -precision
+through precision. The absolute value of the second operand gives
+the number of places to shift. If the second operand is positive,
+then the shift is to the left; otherwise the shift is to the right.
+Digits shifted into the coefficient are zeros. The sign and
+exponent of the first operand are unchanged.
[clinic start generated code]*/
static PyObject *
_decimal_Decimal_shift_impl(PyObject *self, PyTypeObject *cls,
PyObject *other, PyObject *context)
-/*[clinic end generated code: output=82e061a0d9ecc4f5 input=501759c2522cb78e]*/
+/*[clinic end generated code: output=82e061a0d9ecc4f5 input=c05f3fd69fc1f9f9]*/
Dec_BinaryFuncVA(mpd_qshift)
/*[clinic input]
@@ -5589,18 +5599,18 @@ that of the right-hand operand.
Also unlike other operations, quantize never signals Underflow, even
if the result is subnormal and inexact.
-If the exponent of the second operand is larger than that of the first,
-then rounding may be necessary. In this case, the rounding mode is
-determined by the rounding argument if given, else by the given context
-argument; if neither argument is given, the rounding mode of the
-current thread's context is used.
+If the exponent of the second operand is larger than that of the
+first, then rounding may be necessary. In this case, the rounding
+mode is determined by the rounding argument if given, else by the
+given context argument; if neither argument is given, the rounding
+mode of the current thread's context is used.
[clinic start generated code]*/
static PyObject *
_decimal_Decimal_quantize_impl(PyObject *self, PyTypeObject *cls,
PyObject *w, PyObject *rounding,
PyObject *context)
-/*[clinic end generated code: output=fc51edf458559913 input=1166e6311e047b74]*/
+/*[clinic end generated code: output=fc51edf458559913 input=7838b0a5f684adb8]*/
{
PyObject *a, *b;
PyObject *result;
@@ -6629,14 +6639,14 @@ _decimal.Context.remainder_near = _decimal.Context.add
Return x - y * n.
-Here n is the integer nearest the exact value of x / y (if the result
-is 0 then its sign will be the sign of x).
+Here n is the integer nearest the exact value of x / y (if the
+result is 0 then its sign will be the sign of x).
[clinic start generated code]*/
static PyObject *
_decimal_Context_remainder_near_impl(PyObject *context, PyTypeObject *cls,
PyObject *x, PyObject *y)
-/*[clinic end generated code: output=7f18c535a12cf8ac input=bafb6327bb314c5c]*/
+/*[clinic end generated code: output=7f18c535a12cf8ac input=60342558000d4be6]*/
DecCtx_BinaryFunc(mpd_qrem_near)
/*[clinic input]
@@ -6723,13 +6733,14 @@ restrictions hold:
* all three arguments must be integral
* 'b' must be nonnegative
* at least one of 'a' or 'b' must be nonzero
- * modulo must be nonzero and less than 10**prec in absolute value
+ * modulo must be nonzero and less than 10**prec in absolute
+ value
[clinic start generated code]*/
static PyObject *
_decimal_Context_power_impl(PyObject *context, PyTypeObject *cls,
PyObject *base, PyObject *exp, PyObject *mod)
-/*[clinic end generated code: output=d06d40c37cdd69dc input=2a70edd03317c666]*/
+/*[clinic end generated code: output=d06d40c37cdd69dc input=178a254468ec189b]*/
{
PyObject *a, *b, *c = NULL;
PyObject *result;
@@ -7276,6 +7287,7 @@ _decimal_Context_copy_sign_impl(PyObject *context, PyTypeObject *cls,
}
/*[clinic input]
+@permit_long_docstring_body
_decimal.Context.logical_and = _decimal.Context.add
Applies the logical operation 'and' between each operand's digits.
@@ -7305,7 +7317,7 @@ The operands must be both logical numbers.
static PyObject *
_decimal_Context_logical_and_impl(PyObject *context, PyTypeObject *cls,
PyObject *x, PyObject *y)
-/*[clinic end generated code: output=009dfa08ecaa2ac8 input=bcb7d3d6ab7530de]*/
+/*[clinic end generated code: output=009dfa08ecaa2ac8 input=9f8a93a31b9d7088]*/
DecCtx_BinaryFunc(mpd_qand)
/*[clinic input]
@@ -7342,6 +7354,7 @@ _decimal_Context_logical_or_impl(PyObject *context, PyTypeObject *cls,
DecCtx_BinaryFunc(mpd_qor)
/*[clinic input]
+@permit_long_docstring_body
_decimal.Context.logical_xor = _decimal.Context.add
Applies the logical operation 'xor' between each operand's digits.
@@ -7371,7 +7384,7 @@ The operands must be both logical numbers.
static PyObject *
_decimal_Context_logical_xor_impl(PyObject *context, PyTypeObject *cls,
PyObject *x, PyObject *y)
-/*[clinic end generated code: output=23cd81fdcd865d5a input=fcaaf828c1d2d089]*/
+/*[clinic end generated code: output=23cd81fdcd865d5a input=119412854ae58440]*/
DecCtx_BinaryFunc(mpd_qxor)
/*[clinic input]
diff --git a/Modules/_decimal/clinic/_decimal.c.h b/Modules/_decimal/clinic/_decimal.c.h
index b09200845d12e9..c803006ad44382 100644
--- a/Modules/_decimal/clinic/_decimal.c.h
+++ b/Modules/_decimal/clinic/_decimal.c.h
@@ -36,8 +36,8 @@ PyDoc_STRVAR(_decimal_Context_Etop__doc__,
"\n"
"Return a value equal to Emax - prec + 1.\n"
"\n"
-"This is the maximum exponent if the _clamp field of the context is set\n"
-"to 1 (IEEE clamp mode). Etop() must not be negative.");
+"This is the maximum exponent if the _clamp field of the context is\n"
+"set to 1 (IEEE clamp mode). Etop() must not be negative.");
#define _DECIMAL_CONTEXT_ETOP_METHODDEF \
{"Etop", (PyCFunction)_decimal_Context_Etop, METH_NOARGS, _decimal_Context_Etop__doc__},
@@ -1092,10 +1092,10 @@ PyDoc_STRVAR(_decimal_Decimal_to_integral_exact__doc__,
"\n"
"Round to the nearest integer.\n"
"\n"
-"Decimal.to_integral_exact() signals Inexact or Rounded as appropriate\n"
-"if rounding occurs. The rounding mode is determined by the rounding\n"
-"parameter if given, else by the given context. If neither parameter is\n"
-"given, then the rounding mode of the current default context is used.");
+"This method signals Inexact or Rounded as appropriate if rounding\n"
+"occurs. The rounding mode is determined by the rounding parameter\n"
+"if given, else by the given context. If neither parameter is given,\n"
+"then the rounding mode of the current default context is used.");
#define _DECIMAL_DECIMAL_TO_INTEGRAL_EXACT_METHODDEF \
{"to_integral_exact", _PyCFunction_CAST(_decimal_Decimal_to_integral_exact), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_integral_exact__doc__},
@@ -1638,7 +1638,8 @@ PyDoc_STRVAR(_decimal_Decimal_sqrt__doc__,
"\n"
"Return the square root of the argument to full precision.\n"
"\n"
-"The result is correctly rounded using the ROUND_HALF_EVEN rounding mode.");
+"The result is correctly rounded using the ROUND_HALF_EVEN rounding\n"
+"mode.");
#define _DECIMAL_DECIMAL_SQRT_METHODDEF \
{"sqrt", _PyCFunction_CAST(_decimal_Decimal_sqrt), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_sqrt__doc__},
@@ -2113,10 +2114,10 @@ PyDoc_STRVAR(_decimal_Decimal_next_toward__doc__,
"\n"
"Returns the number closest to self, in the direction towards other.\n"
"\n"
-"If the two operands are unequal, return the number closest to the first\n"
-"operand in the direction of the second operand. If both operands are\n"
-"numerically equal, return a copy of the first operand with the sign set\n"
-"to be the same as the sign of the second operand.");
+"If the two operands are unequal, return the number closest to the\n"
+"first operand in the direction of the second operand. If both\n"
+"operands are numerically equal, return a copy of the first operand\n"
+"with the sign set to be the same as the sign of the second operand.");
#define _DECIMAL_DECIMAL_NEXT_TOWARD_METHODDEF \
{"next_toward", _PyCFunction_CAST(_decimal_Decimal_next_toward), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_next_toward__doc__},
@@ -2185,10 +2186,10 @@ PyDoc_STRVAR(_decimal_Decimal_remainder_near__doc__,
"Return the remainder from dividing self by other.\n"
"\n"
"This differs from self % other in that the sign of the remainder is\n"
-"chosen so as to minimize its absolute value. More precisely, the return\n"
-"value is self - n * other where n is the integer nearest to the exact\n"
-"value of self / other, and if two integers are equally near then the\n"
-"even one is chosen.\n"
+"chosen so as to minimize its absolute value. More precisely, the\n"
+"return value is self - n * other where n is the integer nearest to\n"
+"the exact value of self / other, and if two integers are equally\n"
+"near then the even one is chosen.\n"
"\n"
"If the result is zero then its sign will be the sign of self.");
@@ -2671,8 +2672,8 @@ PyDoc_STRVAR(_decimal_Decimal_radix__doc__,
"\n"
"Return Decimal(10).\n"
"\n"
-"This is the radix (base) in which the Decimal class does\n"
-"all its arithmetic. Included for compatibility with the specification.");
+"This is the radix (base) in which the Decimal class does all its\n"
+"arithmetic. Included for compatibility with the specification.");
#define _DECIMAL_DECIMAL_RADIX_METHODDEF \
{"radix", _PyCFunction_CAST(_decimal_Decimal_radix), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_radix__doc__},
@@ -2812,9 +2813,9 @@ PyDoc_STRVAR(_decimal_Decimal_logb__doc__,
"\n"
"Return the adjusted exponent of the operand as a Decimal instance.\n"
"\n"
-"If the operand is a zero, then Decimal(\'-Infinity\') is returned and the\n"
-"DivisionByZero condition is raised. If the operand is an infinity then\n"
-"Decimal(\'Infinity\') is returned.");
+"If the operand is a zero, then Decimal(\'-Infinity\') is returned and\n"
+"the DivisionByZero condition is raised. If the operand is an\n"
+"infinity then Decimal(\'Infinity\') is returned.");
#define _DECIMAL_DECIMAL_LOGB_METHODDEF \
{"logb", _PyCFunction_CAST(_decimal_Decimal_logb), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logb__doc__},
@@ -2894,7 +2895,8 @@ PyDoc_STRVAR(_decimal_Decimal_number_class__doc__,
" * \'+Normal\', indicating that the operand is a positive normal\n"
" number.\n"
" * \'+Infinity\', indicating that the operand is positive infinity.\n"
-" * \'NaN\', indicating that the operand is a quiet NaN (Not a Number).\n"
+" * \'NaN\', indicating that the operand is a quiet NaN (Not a\n"
+" Number).\n"
" * \'sNaN\', indicating that the operand is a signaling NaN.");
#define _DECIMAL_DECIMAL_NUMBER_CLASS_METHODDEF \
@@ -2961,12 +2963,12 @@ PyDoc_STRVAR(_decimal_Decimal_to_eng_string__doc__,
"\n"
"Convert to an engineering-type string.\n"
"\n"
-"Engineering notation has an exponent which is a multiple of 3, so there\n"
-"are up to 3 digits left of the decimal place. For example,\n"
+"Engineering notation has an exponent which is a multiple of 3, so\n"
+"there are up to 3 digits left of the decimal place. For example,\n"
"Decimal(\'123E+1\') is converted to Decimal(\'1.23E+3\').\n"
"\n"
-"The value of context.capitals determines whether the exponent sign is\n"
-"lower or upper case. Otherwise, the context does not affect the\n"
+"The value of context.capitals determines whether the exponent sign\n"
+"is lower or upper case. Otherwise, the context does not affect the\n"
"operation.");
#define _DECIMAL_DECIMAL_TO_ENG_STRING_METHODDEF \
@@ -3033,25 +3035,25 @@ PyDoc_STRVAR(_decimal_Decimal_compare_total__doc__,
"\n"
"Compare two operands using their abstract representation.\n"
"\n"
-"Similar to the compare() method, but the result\n"
-"gives a total ordering on Decimal instances. Two Decimal instances with\n"
-"the same numeric value but different representations compare unequal\n"
-"in this ordering:\n"
+"Similar to the compare() method, but the result gives a total\n"
+"ordering on Decimal instances. Two Decimal instances with the same\n"
+"numeric value but different representations compare unequal in this\n"
+"ordering:\n"
"\n"
" >>> Decimal(\'12.0\').compare_total(Decimal(\'12\'))\n"
" Decimal(\'-1\')\n"
"\n"
-"Quiet and signaling NaNs are also included in the total ordering. The\n"
-"result of this function is Decimal(\'0\') if both operands have the same\n"
-"representation, Decimal(\'-1\') if the first operand is lower in the\n"
-"total order than the second, and Decimal(\'1\') if the first operand is\n"
-"higher in the total order than the second operand. See the\n"
-"specification for details of the total order.\n"
+"Quiet and signaling NaNs are also included in the total ordering.\n"
+"The result of this function is Decimal(\'0\') if both operands have\n"
+"the same representation, Decimal(\'-1\') if the first operand is lower\n"
+"in the total order than the second, and Decimal(\'1\') if the first\n"
+"operand is higher in the total order than the second operand. See\n"
+"the specification for details of the total order.\n"
"\n"
"This operation is unaffected by context and is quiet: no flags are\n"
-"changed and no rounding is performed. As an exception, the C version\n"
-"may raise InvalidOperation if the second operand cannot be converted\n"
-"exactly.");
+"changed and no rounding is performed. As an exception, the C\n"
+"version may raise InvalidOperation if the second operand cannot be\n"
+"converted exactly.");
#define _DECIMAL_DECIMAL_COMPARE_TOTAL_METHODDEF \
{"compare_total", _PyCFunction_CAST(_decimal_Decimal_compare_total), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_compare_total__doc__},
@@ -3544,12 +3546,13 @@ PyDoc_STRVAR(_decimal_Decimal_rotate__doc__,
"\n"
"Returns a rotated copy of self\'s digits, value-of-other times.\n"
"\n"
-"The second operand must be an integer in the range -precision through\n"
-"precision. The absolute value of the second operand gives the number of\n"
-"places to rotate. If the second operand is positive then rotation is to\n"
-"the left; otherwise rotation is to the right. The coefficient of the\n"
-"first operand is padded on the left with zeros to length precision if\n"
-"necessary. The sign and exponent of the first operand are unchanged.");
+"The second operand must be an integer in the range -precision\n"
+"through precision. The absolute value of the second operand gives\n"
+"the number of places to rotate. If the second operand is positive\n"
+"then rotation is to the left; otherwise rotation is to the right.\n"
+"The coefficient of the first operand is padded on the left with\n"
+"zeros to length precision if necessary. The sign and exponent of\n"
+"the first operand are unchanged.");
#define _DECIMAL_DECIMAL_ROTATE_METHODDEF \
{"rotate", _PyCFunction_CAST(_decimal_Decimal_rotate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_rotate__doc__},
@@ -3686,12 +3689,12 @@ PyDoc_STRVAR(_decimal_Decimal_shift__doc__,
"\n"
"Returns a shifted copy of self\'s digits, value-of-other times.\n"
"\n"
-"The second operand must be an integer in the range -precision through\n"
-"precision. The absolute value of the second operand gives the number\n"
-"of places to shift. If the second operand is positive, then the shift\n"
-"is to the left; otherwise the shift is to the right. Digits shifted\n"
-"into the coefficient are zeros. The sign and exponent of the first\n"
-"operand are unchanged.");
+"The second operand must be an integer in the range -precision\n"
+"through precision. The absolute value of the second operand gives\n"
+"the number of places to shift. If the second operand is positive,\n"
+"then the shift is to the left; otherwise the shift is to the right.\n"
+"Digits shifted into the coefficient are zeros. The sign and\n"
+"exponent of the first operand are unchanged.");
#define _DECIMAL_DECIMAL_SHIFT_METHODDEF \
{"shift", _PyCFunction_CAST(_decimal_Decimal_shift), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_shift__doc__},
@@ -3774,11 +3777,11 @@ PyDoc_STRVAR(_decimal_Decimal_quantize__doc__,
"Also unlike other operations, quantize never signals Underflow, even\n"
"if the result is subnormal and inexact.\n"
"\n"
-"If the exponent of the second operand is larger than that of the first,\n"
-"then rounding may be necessary. In this case, the rounding mode is\n"
-"determined by the rounding argument if given, else by the given context\n"
-"argument; if neither argument is given, the rounding mode of the\n"
-"current thread\'s context is used.");
+"If the exponent of the second operand is larger than that of the\n"
+"first, then rounding may be necessary. In this case, the rounding\n"
+"mode is determined by the rounding argument if given, else by the\n"
+"given context argument; if neither argument is given, the rounding\n"
+"mode of the current thread\'s context is used.");
#define _DECIMAL_DECIMAL_QUANTIZE_METHODDEF \
{"quantize", _PyCFunction_CAST(_decimal_Decimal_quantize), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_quantize__doc__},
@@ -5197,8 +5200,8 @@ PyDoc_STRVAR(_decimal_Context_remainder_near__doc__,
"\n"
"Return x - y * n.\n"
"\n"
-"Here n is the integer nearest the exact value of x / y (if the result\n"
-"is 0 then its sign will be the sign of x).");
+"Here n is the integer nearest the exact value of x / y (if the\n"
+"result is 0 then its sign will be the sign of x).");
#define _DECIMAL_CONTEXT_REMAINDER_NEAR_METHODDEF \
{"remainder_near", _PyCFunction_CAST(_decimal_Context_remainder_near), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_remainder_near__doc__},
@@ -5336,7 +5339,8 @@ PyDoc_STRVAR(_decimal_Context_power__doc__,
" * all three arguments must be integral\n"
" * \'b\' must be nonnegative\n"
" * at least one of \'a\' or \'b\' must be nonzero\n"
-" * modulo must be nonzero and less than 10**prec in absolute value");
+" * modulo must be nonzero and less than 10**prec in absolute\n"
+" value");
#define _DECIMAL_CONTEXT_POWER_METHODDEF \
{"power", _PyCFunction_CAST(_decimal_Context_power), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_power__doc__},
@@ -6980,4 +6984,4 @@ _decimal_Context_same_quantum(PyObject *context, PyTypeObject *cls, PyObject *co
#ifndef _DECIMAL_CONTEXT_APPLY_METHODDEF
#define _DECIMAL_CONTEXT_APPLY_METHODDEF
#endif /* !defined(_DECIMAL_CONTEXT_APPLY_METHODDEF) */
-/*[clinic end generated code: output=b288181c82fdc9f1 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=0eb835634388294e input=a9049054013a1b77]*/
From d3e2a133d23d7ed3a4acc2ee71757281b1f282cd Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 24 May 2026 15:24:34 +0200
Subject: [PATCH 129/213] [3.15] gh-150285: Fix too long docstrings in the zstd
module (GH-150291) (GH-150335)
(cherry picked from commit 9fceb1c0c5c5ad527bc257b115bcf45995daf631)
Co-authored-by: Serhiy Storchaka
---
Lib/compression/zstd/__init__.py | 28 +++++++++---------
Lib/compression/zstd/_zstdfile.py | 39 ++++++++++++-------------
Modules/_zstd/clinic/compressor.c.h | 31 ++++++++++----------
Modules/_zstd/clinic/decompressor.c.h | 30 +++++++++++---------
Modules/_zstd/clinic/zstddict.c.h | 30 +++++++++++---------
Modules/_zstd/compressor.c | 41 +++++++++++++--------------
Modules/_zstd/decompressor.c | 37 ++++++++++++------------
Modules/_zstd/zstddict.c | 40 +++++++++++++-------------
8 files changed, 140 insertions(+), 136 deletions(-)
diff --git a/Lib/compression/zstd/__init__.py b/Lib/compression/zstd/__init__.py
index 84b25914b0aa93..5326cf9b19cf88 100644
--- a/Lib/compression/zstd/__init__.py
+++ b/Lib/compression/zstd/__init__.py
@@ -61,8 +61,9 @@ def __setattr__(self, name, _):
def get_frame_info(frame_buffer):
"""Get Zstandard frame information from a frame header.
- *frame_buffer* is a bytes-like object. It should start from the beginning
- of a frame, and needs to include at least the frame header (6 to 18 bytes).
+ *frame_buffer* is a bytes-like object. It should start from the
+ beginning of a frame, and needs to include at least the frame header
+ (6 to 18 bytes).
The returned FrameInfo object has two attributes.
'decompressed_size' is the size in bytes of the data in the frame when
@@ -103,16 +104,17 @@ def finalize_dict(zstd_dict, /, samples, dict_size, level):
finalize *zstd_dict* by adding headers and statistics according to the
Zstandard dictionary format.
- You may compose an effective dictionary content by hand, which is used as
- basis dictionary, and use some samples to finalize a dictionary. The basis
- dictionary may be a "raw content" dictionary. See *is_raw* in ZstdDict.
+ You may compose an effective dictionary content by hand, which is used
+ as basis dictionary, and use some samples to finalize a dictionary. The
+ basis dictionary may be a "raw content" dictionary. See *is_raw* in
+ ZstdDict.
- *samples* is an iterable of samples, where a sample is a bytes-like object
- representing a file.
+ *samples* is an iterable of samples, where a sample is a bytes-like
+ object representing a file.
*dict_size* is the dictionary's maximum size, in bytes.
*level* is the expected compression level. The statistics for each
- compression level differ, so tuning the dictionary to the compression level
- can provide improvements.
+ compression level differ, so tuning the dictionary to the compression
+ level can provide improvements.
"""
if not isinstance(zstd_dict, ZstdDict):
@@ -140,8 +142,8 @@ def compress(data, level=None, options=None, zstd_dict=None):
COMPRESSION_LEVEL_DEFAULT ('3').
*options* is a dict object that contains advanced compression
parameters. See CompressionParameter for more on options.
- *zstd_dict* is a ZstdDict object, a pre-trained Zstandard dictionary. See
- the function train_dict for how to train a ZstdDict on sample data.
+ *zstd_dict* is a ZstdDict object, a pre-trained Zstandard dictionary.
+ See the function train_dict for how to train a ZstdDict on sample data.
For incremental compression, use a ZstdCompressor instead.
"""
@@ -152,8 +154,8 @@ def compress(data, level=None, options=None, zstd_dict=None):
def decompress(data, zstd_dict=None, options=None):
"""Decompress one or more frames of Zstandard compressed *data*.
- *zstd_dict* is a ZstdDict object, a pre-trained Zstandard dictionary. See
- the function train_dict for how to train a ZstdDict on sample data.
+ *zstd_dict* is a ZstdDict object, a pre-trained Zstandard dictionary.
+ See the function train_dict for how to train a ZstdDict on sample data.
*options* is a dict object that contains advanced compression
parameters. See DecompressionParameter for more on options.
diff --git a/Lib/compression/zstd/_zstdfile.py b/Lib/compression/zstd/_zstdfile.py
index d709f5efc658fa..8d3358152e9a88 100644
--- a/Lib/compression/zstd/_zstdfile.py
+++ b/Lib/compression/zstd/_zstdfile.py
@@ -36,9 +36,9 @@ def __init__(self, file, /, mode='r', *,
*file* can be either an file-like object, or a file name to open.
- *mode* can be 'r' for reading (default), 'w' for (over)writing, 'x' for
- creating exclusively, or 'a' for appending. These can equivalently be
- given as 'rb', 'wb', 'xb' and 'ab' respectively.
+ *mode* can be 'r' for reading (default), 'w' for (over)writing, 'x'
+ for creating exclusively, or 'a' for appending. These can
+ equivalently be given as 'rb', 'wb', 'xb' and 'ab' respectively.
*level* is an optional int specifying the compression level to use,
or COMPRESSION_LEVEL_DEFAULT if not given.
@@ -296,26 +296,27 @@ def open(file, /, mode='rb', *, level=None, options=None, zstd_dict=None,
encoding=None, errors=None, newline=None):
"""Open a Zstandard compressed file in binary or text mode.
- file can be either a file name (given as a str, bytes, or PathLike object),
- in which case the named file is opened, or it can be an existing file object
- to read from or write to.
+ file can be either a file name (given as a str, bytes, or PathLike
+ object), in which case the named file is opened, or it can be
+ an existing file object to read from or write to.
- The mode parameter can be 'r', 'rb' (default), 'w', 'wb', 'x', 'xb', 'a',
- 'ab' for binary mode, or 'rt', 'wt', 'xt', 'at' for text mode.
+ The mode parameter can be 'r', 'rb' (default), 'w', 'wb', 'x', 'xb',
+ 'a', 'ab' for binary mode, or 'rt', 'wt', 'xt', 'at' for text mode.
- The level, options, and zstd_dict parameters specify the settings the same
- as ZstdFile.
+ The level, options, and zstd_dict parameters specify the settings the
+ same as ZstdFile.
When using read mode (decompression), the options parameter is a dict
- representing advanced decompression options. The level parameter is not
- supported in this case. When using write mode (compression), only one of
- level, an int representing the compression level, or options, a dict
- representing advanced compression options, may be passed. In both modes,
- zstd_dict is a ZstdDict instance containing a trained Zstandard dictionary.
-
- For binary mode, this function is equivalent to the ZstdFile constructor:
- ZstdFile(filename, mode, ...). In this case, the encoding, errors and
- newline parameters must not be provided.
+ representing advanced decompression options. The level parameter is not
+ supported in this case. When using write mode (compression), only one
+ of level, an int representing the compression level, or options, a dict
+ representing advanced compression options, may be passed. In both
+ modes, zstd_dict is a ZstdDict instance containing a trained Zstandard
+ dictionary.
+
+ For binary mode, this function is equivalent to the ZstdFile
+ constructor: ZstdFile(filename, mode, ...). In this case, the encoding,
+ errors and newline parameters must not be provided.
For text mode, an ZstdFile object is created, and wrapped in an
io.TextIOWrapper instance with the specified encoding, error handling
diff --git a/Modules/_zstd/clinic/compressor.c.h b/Modules/_zstd/clinic/compressor.c.h
index 4f8d93fd9e867c..6775ba4826a652 100644
--- a/Modules/_zstd/clinic/compressor.c.h
+++ b/Modules/_zstd/clinic/compressor.c.h
@@ -21,8 +21,8 @@ PyDoc_STRVAR(_zstd_ZstdCompressor_new__doc__,
" zstd_dict\n"
" A ZstdDict object, a pre-trained Zstandard dictionary.\n"
"\n"
-"Thread-safe at method level. For one-shot compression, use the compress()\n"
-"function instead.");
+"Thread-safe at method level. For one-shot compression, use the\n"
+"compress() function instead.");
static PyObject *
_zstd_ZstdCompressor_new_impl(PyTypeObject *type, PyObject *level,
@@ -105,9 +105,9 @@ PyDoc_STRVAR(_zstd_ZstdCompressor_compress__doc__,
" Can be these 3 values ZstdCompressor.CONTINUE,\n"
" ZstdCompressor.FLUSH_BLOCK, ZstdCompressor.FLUSH_FRAME\n"
"\n"
-"Return a chunk of compressed data if possible, or b\'\' otherwise. When you have\n"
-"finished providing data to the compressor, call the flush() method to finish\n"
-"the compression process.");
+"Return a chunk of compressed data if possible, or b\'\' otherwise.\n"
+"When you have finished providing data to the compressor, call the\n"
+"flush() method to finish the compression process.");
#define _ZSTD_ZSTDCOMPRESSOR_COMPRESS_METHODDEF \
{"compress", _PyCFunction_CAST(_zstd_ZstdCompressor_compress), METH_FASTCALL|METH_KEYWORDS, _zstd_ZstdCompressor_compress__doc__},
@@ -189,9 +189,9 @@ PyDoc_STRVAR(_zstd_ZstdCompressor_flush__doc__,
" Can be these 2 values ZstdCompressor.FLUSH_FRAME,\n"
" ZstdCompressor.FLUSH_BLOCK\n"
"\n"
-"Flush any remaining data left in internal buffers. Since Zstandard data\n"
-"consists of one or more independent frames, the compressor object can still\n"
-"be used after this method is called.");
+"Flush any remaining data left in internal buffers. Since Zstandard\n"
+"data consists of one or more independent frames, the compressor\n"
+"object can still be used after this method is called.");
#define _ZSTD_ZSTDCOMPRESSOR_FLUSH_METHODDEF \
{"flush", _PyCFunction_CAST(_zstd_ZstdCompressor_flush), METH_FASTCALL|METH_KEYWORDS, _zstd_ZstdCompressor_flush__doc__},
@@ -262,13 +262,14 @@ PyDoc_STRVAR(_zstd_ZstdCompressor_set_pledged_input_size__doc__,
" size\n"
" The size of the uncompressed data to be provided to the compressor.\n"
"\n"
-"This method can be used to ensure the header of the frame about to be written\n"
-"includes the size of the data, unless the CompressionParameter.content_size_flag\n"
-"is set to False. If last_mode != FLUSH_FRAME, then a RuntimeError is raised.\n"
+"This method can be used to ensure the header of the frame about to\n"
+"be written includes the size of the data, unless the\n"
+"CompressionParameter.content_size_flag is set to False.\n"
+"If last_mode != FLUSH_FRAME, then a RuntimeError is raised.\n"
"\n"
-"It is important to ensure that the pledged data size matches the actual data\n"
-"size. If they do not match the compressed output data may be corrupted and the\n"
-"final chunk written may be lost.");
+"It is important to ensure that the pledged data size matches the\n"
+"actual data size. If they do not match the compressed output data\n"
+"may be corrupted and the final chunk written may be lost.");
#define _ZSTD_ZSTDCOMPRESSOR_SET_PLEDGED_INPUT_SIZE_METHODDEF \
{"set_pledged_input_size", (PyCFunction)_zstd_ZstdCompressor_set_pledged_input_size, METH_O, _zstd_ZstdCompressor_set_pledged_input_size__doc__},
@@ -291,4 +292,4 @@ _zstd_ZstdCompressor_set_pledged_input_size(PyObject *self, PyObject *arg)
exit:
return return_value;
}
-/*[clinic end generated code: output=c1d5c2cf06a8becd input=a9049054013a1b77]*/
+/*[clinic end generated code: output=1a5e21476885866c input=a9049054013a1b77]*/
diff --git a/Modules/_zstd/clinic/decompressor.c.h b/Modules/_zstd/clinic/decompressor.c.h
index c6fdae74ab0447..fe3b76b8bb369d 100644
--- a/Modules/_zstd/clinic/decompressor.c.h
+++ b/Modules/_zstd/clinic/decompressor.c.h
@@ -20,8 +20,8 @@ PyDoc_STRVAR(_zstd_ZstdDecompressor_new__doc__,
" options\n"
" A dict object that contains advanced decompression parameters.\n"
"\n"
-"Thread-safe at method level. For one-shot decompression, use the decompress()\n"
-"function instead.");
+"Thread-safe at method level. For one-shot decompression, use the\n"
+"decompress() function instead.");
static PyObject *
_zstd_ZstdDecompressor_new_impl(PyTypeObject *type, PyObject *zstd_dict,
@@ -91,7 +91,8 @@ PyDoc_STRVAR(_zstd_ZstdDecompressor_unused_data__doc__,
"A bytes object of un-consumed input data.\n"
"\n"
"When ZstdDecompressor object stops after a frame is\n"
-"decompressed, unused input data after the frame. Otherwise this will be b\'\'.");
+"decompressed, unused input data after the frame. Otherwise this\n"
+"will be b\'\'.");
#if defined(_zstd_ZstdDecompressor_unused_data_DOCSTR)
# undef _zstd_ZstdDecompressor_unused_data_DOCSTR
#endif
@@ -129,18 +130,19 @@ PyDoc_STRVAR(_zstd_ZstdDecompressor_decompress__doc__,
" output buffer is unlimited. When it is nonnegative, returns at\n"
" most max_length bytes of decompressed data.\n"
"\n"
-"If *max_length* is nonnegative, returns at most *max_length* bytes of\n"
-"decompressed data. If this limit is reached and further output can be\n"
-"produced, *self.needs_input* will be set to ``False``. In this case, the next\n"
-"call to *decompress()* may provide *data* as b\'\' to obtain more of the output.\n"
+"If *max_length* is nonnegative, returns at most *max_length* bytes\n"
+"of decompressed data. If this limit is reached and further output\n"
+"can be produced, *self.needs_input* will be set to ``False``. In\n"
+"this case, the next call to *decompress()* may provide *data* as b\'\'\n"
+"to obtain more of the output.\n"
"\n"
-"If all of the input data was decompressed and returned (either because this\n"
-"was less than *max_length* bytes, or because *max_length* was negative),\n"
-"*self.needs_input* will be set to True.\n"
+"If all of the input data was decompressed and returned (either\n"
+"because this was less than *max_length* bytes, or because\n"
+"*max_length* was negative), *self.needs_input* will be set to True.\n"
"\n"
-"Attempting to decompress data after the end of a frame is reached raises an\n"
-"EOFError. Any data found after the end of the frame is ignored and saved in\n"
-"the self.unused_data attribute.");
+"Attempting to decompress data after the end of a frame is reached\n"
+"raises an EOFError. Any data found after the end of the frame is\n"
+"ignored and saved in the self.unused_data attribute.");
#define _ZSTD_ZSTDDECOMPRESSOR_DECOMPRESS_METHODDEF \
{"decompress", _PyCFunction_CAST(_zstd_ZstdDecompressor_decompress), METH_FASTCALL|METH_KEYWORDS, _zstd_ZstdDecompressor_decompress__doc__},
@@ -220,4 +222,4 @@ _zstd_ZstdDecompressor_decompress(PyObject *self, PyObject *const *args, Py_ssiz
return return_value;
}
-/*[clinic end generated code: output=30c12ef047027ede input=a9049054013a1b77]*/
+/*[clinic end generated code: output=70bc308e86463751 input=a9049054013a1b77]*/
diff --git a/Modules/_zstd/clinic/zstddict.c.h b/Modules/_zstd/clinic/zstddict.c.h
index 166d925a542352..18b049e3cbe37e 100644
--- a/Modules/_zstd/clinic/zstddict.c.h
+++ b/Modules/_zstd/clinic/zstddict.c.h
@@ -21,8 +21,8 @@ PyDoc_STRVAR(_zstd_ZstdDict_new__doc__,
" advanced cases. Otherwise, check that the content represents\n"
" a Zstandard dictionary created by the zstd library or CLI.\n"
"\n"
-"The dictionary can be used for compression or decompression, and can be shared\n"
-"by multiple ZstdCompressor or ZstdDecompressor objects.");
+"The dictionary can be used for compression or decompression, and can be\n"
+"shared by multiple ZstdCompressor or ZstdDecompressor objects.");
static PyObject *
_zstd_ZstdDict_new_impl(PyTypeObject *type, Py_buffer *dict_content,
@@ -125,11 +125,11 @@ PyDoc_STRVAR(_zstd_ZstdDict_as_digested_dict__doc__,
"Pass this attribute as zstd_dict argument:\n"
"compress(dat, zstd_dict=zd.as_digested_dict)\n"
"\n"
-"1. Some advanced compression parameters of compressor may be overridden\n"
-" by parameters of digested dictionary.\n"
-"2. ZstdDict has a digested dictionaries cache for each compression level.\n"
-" It\'s faster when loading again a digested dictionary with the same\n"
-" compression level.\n"
+"1. Some advanced compression parameters of compressor may be\n"
+" overridden by parameters of digested dictionary.\n"
+"2. ZstdDict has a digested dictionaries cache for each compression\n"
+" level. It\'s faster when loading again a digested dictionary with\n"
+" the same compression level.\n"
"3. No need to use this for decompression.");
#if defined(_zstd_ZstdDict_as_digested_dict_DOCSTR)
# undef _zstd_ZstdDict_as_digested_dict_DOCSTR
@@ -161,9 +161,10 @@ PyDoc_STRVAR(_zstd_ZstdDict_as_undigested_dict__doc__,
"Pass this attribute as zstd_dict argument:\n"
"compress(dat, zstd_dict=zd.as_undigested_dict)\n"
"\n"
-"1. The advanced compression parameters of compressor will not be overridden.\n"
-"2. Loading an undigested dictionary is costly. If load an undigested dictionary\n"
-" multiple times, consider reusing a compressor object.\n"
+"1. The advanced compression parameters of compressor will not be\n"
+" overridden.\n"
+"2. Loading an undigested dictionary is costly. If load an undigested\n"
+" dictionary multiple times, consider reusing a compressor object.\n"
"3. No need to use this for decompression.");
#if defined(_zstd_ZstdDict_as_undigested_dict_DOCSTR)
# undef _zstd_ZstdDict_as_undigested_dict_DOCSTR
@@ -195,9 +196,10 @@ PyDoc_STRVAR(_zstd_ZstdDict_as_prefix__doc__,
"Pass this attribute as zstd_dict argument:\n"
"compress(dat, zstd_dict=zd.as_prefix)\n"
"\n"
-"1. Prefix is compatible with long distance matching, while dictionary is not.\n"
-"2. It only works for the first frame, then the compressor/decompressor will\n"
-" return to no prefix state.\n"
+"1. Prefix is compatible with long distance matching, while\n"
+" dictionary is not.\n"
+"2. It only works for the first frame, then the\n"
+" compressor/decompressor will return to no prefix state.\n"
"3. When decompressing, must use the same prefix as when compressing.");
#if defined(_zstd_ZstdDict_as_prefix_DOCSTR)
# undef _zstd_ZstdDict_as_prefix_DOCSTR
@@ -222,4 +224,4 @@ _zstd_ZstdDict_as_prefix_get(PyObject *self, void *Py_UNUSED(context))
{
return _zstd_ZstdDict_as_prefix_get_impl((ZstdDict *)self);
}
-/*[clinic end generated code: output=f41d9e2e2cc2928f input=a9049054013a1b77]*/
+/*[clinic end generated code: output=49b66061b4fcdb5f input=a9049054013a1b77]*/
diff --git a/Modules/_zstd/compressor.c b/Modules/_zstd/compressor.c
index 8a3cd182ab1516..b2eb22d9ec8add 100644
--- a/Modules/_zstd/compressor.c
+++ b/Modules/_zstd/compressor.c
@@ -332,14 +332,14 @@ _zstd.ZstdCompressor.__new__ as _zstd_ZstdCompressor_new
Create a compressor object for compressing data incrementally.
-Thread-safe at method level. For one-shot compression, use the compress()
-function instead.
+Thread-safe at method level. For one-shot compression, use the
+compress() function instead.
[clinic start generated code]*/
static PyObject *
_zstd_ZstdCompressor_new_impl(PyTypeObject *type, PyObject *level,
PyObject *options, PyObject *zstd_dict)
-/*[clinic end generated code: output=cdef61eafecac3d7 input=92de0211ae20ffdc]*/
+/*[clinic end generated code: output=cdef61eafecac3d7 input=bbfeeaa06fd3bd4d]*/
{
ZstdCompressor* self = PyObject_GC_New(ZstdCompressor, type);
if (self == NULL) {
@@ -583,7 +583,6 @@ compress_mt_continue_lock_held(ZstdCompressor *self, Py_buffer *data)
}
/*[clinic input]
-@permit_long_docstring_body
_zstd.ZstdCompressor.compress
data: Py_buffer
@@ -593,15 +592,15 @@ _zstd.ZstdCompressor.compress
Provide data to the compressor object.
-Return a chunk of compressed data if possible, or b'' otherwise. When you have
-finished providing data to the compressor, call the flush() method to finish
-the compression process.
+Return a chunk of compressed data if possible, or b'' otherwise.
+When you have finished providing data to the compressor, call the
+flush() method to finish the compression process.
[clinic start generated code]*/
static PyObject *
_zstd_ZstdCompressor_compress_impl(ZstdCompressor *self, Py_buffer *data,
int mode)
-/*[clinic end generated code: output=ed7982d1cf7b4f98 input=6018ed6cc729cea6]*/
+/*[clinic end generated code: output=ed7982d1cf7b4f98 input=11726dff64d7b2f9]*/
{
PyObject *ret;
@@ -643,7 +642,6 @@ _zstd_ZstdCompressor_compress_impl(ZstdCompressor *self, Py_buffer *data,
}
/*[clinic input]
-@permit_long_docstring_body
_zstd.ZstdCompressor.flush
mode: int(c_default="ZSTD_e_end") = ZstdCompressor.FLUSH_FRAME
@@ -652,14 +650,14 @@ _zstd.ZstdCompressor.flush
Finish the compression process.
-Flush any remaining data left in internal buffers. Since Zstandard data
-consists of one or more independent frames, the compressor object can still
-be used after this method is called.
+Flush any remaining data left in internal buffers. Since Zstandard
+data consists of one or more independent frames, the compressor
+object can still be used after this method is called.
[clinic start generated code]*/
static PyObject *
_zstd_ZstdCompressor_flush_impl(ZstdCompressor *self, int mode)
-/*[clinic end generated code: output=b7cf2c8d64dcf2e3 input=a9871ec742d79003]*/
+/*[clinic end generated code: output=b7cf2c8d64dcf2e3 input=130e0b1eddf0f498]*/
{
PyObject *ret;
@@ -693,7 +691,7 @@ _zstd_ZstdCompressor_flush_impl(ZstdCompressor *self, int mode)
/*[clinic input]
-@permit_long_docstring_body
+@permit_long_summary
_zstd.ZstdCompressor.set_pledged_input_size
size: zstd_contentsize
@@ -702,19 +700,20 @@ _zstd.ZstdCompressor.set_pledged_input_size
Set the uncompressed content size to be written into the frame header.
-This method can be used to ensure the header of the frame about to be written
-includes the size of the data, unless the CompressionParameter.content_size_flag
-is set to False. If last_mode != FLUSH_FRAME, then a RuntimeError is raised.
+This method can be used to ensure the header of the frame about to
+be written includes the size of the data, unless the
+CompressionParameter.content_size_flag is set to False.
+If last_mode != FLUSH_FRAME, then a RuntimeError is raised.
-It is important to ensure that the pledged data size matches the actual data
-size. If they do not match the compressed output data may be corrupted and the
-final chunk written may be lost.
+It is important to ensure that the pledged data size matches the
+actual data size. If they do not match the compressed output data
+may be corrupted and the final chunk written may be lost.
[clinic start generated code]*/
static PyObject *
_zstd_ZstdCompressor_set_pledged_input_size_impl(ZstdCompressor *self,
unsigned long long size)
-/*[clinic end generated code: output=3a09e55cc0e3b4f9 input=b4c87bcbd5ce6111]*/
+/*[clinic end generated code: output=3a09e55cc0e3b4f9 input=714cd7a9aa10e2a8]*/
{
// Error occurred while converting argument, should be unreachable
assert(size != ZSTD_CONTENTSIZE_ERROR);
diff --git a/Modules/_zstd/decompressor.c b/Modules/_zstd/decompressor.c
index 46682b483ad06a..cb95ba89eb650a 100644
--- a/Modules/_zstd/decompressor.c
+++ b/Modules/_zstd/decompressor.c
@@ -469,7 +469,6 @@ stream_decompress_lock_held(ZstdDecompressor *self, Py_buffer *data,
/*[clinic input]
-@permit_long_docstring_body
@classmethod
_zstd.ZstdDecompressor.__new__ as _zstd_ZstdDecompressor_new
zstd_dict: object = None
@@ -479,14 +478,14 @@ _zstd.ZstdDecompressor.__new__ as _zstd_ZstdDecompressor_new
Create a decompressor object for decompressing data incrementally.
-Thread-safe at method level. For one-shot decompression, use the decompress()
-function instead.
+Thread-safe at method level. For one-shot decompression, use the
+decompress() function instead.
[clinic start generated code]*/
static PyObject *
_zstd_ZstdDecompressor_new_impl(PyTypeObject *type, PyObject *zstd_dict,
PyObject *options)
-/*[clinic end generated code: output=590ca65c1102ff4a input=ed8891edfd14cdaa]*/
+/*[clinic end generated code: output=590ca65c1102ff4a input=73879de69bf89f59]*/
{
ZstdDecompressor* self = PyObject_GC_New(ZstdDecompressor, type);
if (self == NULL) {
@@ -571,19 +570,19 @@ ZstdDecompressor_dealloc(PyObject *ob)
}
/*[clinic input]
-@permit_long_docstring_body
@getter
_zstd.ZstdDecompressor.unused_data
A bytes object of un-consumed input data.
When ZstdDecompressor object stops after a frame is
-decompressed, unused input data after the frame. Otherwise this will be b''.
+decompressed, unused input data after the frame. Otherwise this
+will be b''.
[clinic start generated code]*/
static PyObject *
_zstd_ZstdDecompressor_unused_data_get_impl(ZstdDecompressor *self)
-/*[clinic end generated code: output=f3a20940f11b6b09 input=37c2c531ab56f914]*/
+/*[clinic end generated code: output=f3a20940f11b6b09 input=0462065c5e60ba01]*/
{
PyObject *ret;
@@ -613,7 +612,6 @@ _zstd_ZstdDecompressor_unused_data_get_impl(ZstdDecompressor *self)
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
_zstd.ZstdDecompressor.decompress
data: Py_buffer
@@ -625,25 +623,26 @@ _zstd.ZstdDecompressor.decompress
Decompress *data*, returning uncompressed bytes if possible, or b'' otherwise.
-If *max_length* is nonnegative, returns at most *max_length* bytes of
-decompressed data. If this limit is reached and further output can be
-produced, *self.needs_input* will be set to ``False``. In this case, the next
-call to *decompress()* may provide *data* as b'' to obtain more of the output.
+If *max_length* is nonnegative, returns at most *max_length* bytes
+of decompressed data. If this limit is reached and further output
+can be produced, *self.needs_input* will be set to ``False``. In
+this case, the next call to *decompress()* may provide *data* as b''
+to obtain more of the output.
-If all of the input data was decompressed and returned (either because this
-was less than *max_length* bytes, or because *max_length* was negative),
-*self.needs_input* will be set to True.
+If all of the input data was decompressed and returned (either
+because this was less than *max_length* bytes, or because
+*max_length* was negative), *self.needs_input* will be set to True.
-Attempting to decompress data after the end of a frame is reached raises an
-EOFError. Any data found after the end of the frame is ignored and saved in
-the self.unused_data attribute.
+Attempting to decompress data after the end of a frame is reached
+raises an EOFError. Any data found after the end of the frame is
+ignored and saved in the self.unused_data attribute.
[clinic start generated code]*/
static PyObject *
_zstd_ZstdDecompressor_decompress_impl(ZstdDecompressor *self,
Py_buffer *data,
Py_ssize_t max_length)
-/*[clinic end generated code: output=a4302b3c940dbec6 input=e5c905a774df1553]*/
+/*[clinic end generated code: output=a4302b3c940dbec6 input=4ddda5a0bdd00673]*/
{
PyObject *ret;
/* Thread-safe code */
diff --git a/Modules/_zstd/zstddict.c b/Modules/_zstd/zstddict.c
index b0bfbdc886e04f..e1b9d998e697fb 100644
--- a/Modules/_zstd/zstddict.c
+++ b/Modules/_zstd/zstddict.c
@@ -23,7 +23,6 @@ class _zstd.ZstdDict "ZstdDict *" "&zstd_dict_type_spec"
#define ZstdDict_CAST(op) ((ZstdDict *)op)
/*[clinic input]
-@permit_long_docstring_body
@classmethod
_zstd.ZstdDict.__new__ as _zstd_ZstdDict_new
dict_content: Py_buffer
@@ -37,14 +36,14 @@ _zstd.ZstdDict.__new__ as _zstd_ZstdDict_new
Represents a Zstandard dictionary.
-The dictionary can be used for compression or decompression, and can be shared
-by multiple ZstdCompressor or ZstdDecompressor objects.
+The dictionary can be used for compression or decompression, and can be
+shared by multiple ZstdCompressor or ZstdDecompressor objects.
[clinic start generated code]*/
static PyObject *
_zstd_ZstdDict_new_impl(PyTypeObject *type, Py_buffer *dict_content,
int is_raw)
-/*[clinic end generated code: output=685b7406a48b0949 input=b132ee40b784c293]*/
+/*[clinic end generated code: output=685b7406a48b0949 input=3bb66063c0240433]*/
{
/* All dictionaries must be at least 8 bytes */
if (dict_content->len < 8) {
@@ -154,7 +153,6 @@ _zstd_ZstdDict_dict_content_get_impl(ZstdDict *self)
}
/*[clinic input]
-@permit_long_docstring_body
@getter
_zstd.ZstdDict.as_digested_dict
@@ -163,23 +161,22 @@ Load as a digested dictionary to compressor.
Pass this attribute as zstd_dict argument:
compress(dat, zstd_dict=zd.as_digested_dict)
-1. Some advanced compression parameters of compressor may be overridden
- by parameters of digested dictionary.
-2. ZstdDict has a digested dictionaries cache for each compression level.
- It's faster when loading again a digested dictionary with the same
- compression level.
+1. Some advanced compression parameters of compressor may be
+ overridden by parameters of digested dictionary.
+2. ZstdDict has a digested dictionaries cache for each compression
+ level. It's faster when loading again a digested dictionary with
+ the same compression level.
3. No need to use this for decompression.
[clinic start generated code]*/
static PyObject *
_zstd_ZstdDict_as_digested_dict_get_impl(ZstdDict *self)
-/*[clinic end generated code: output=09b086e7a7320dbb input=8d01ff0b8b043f2e]*/
+/*[clinic end generated code: output=09b086e7a7320dbb input=a9417d40f1d7fedd]*/
{
return Py_BuildValue("Oi", self, DICT_TYPE_DIGESTED);
}
/*[clinic input]
-@permit_long_docstring_body
@getter
_zstd.ZstdDict.as_undigested_dict
@@ -188,21 +185,21 @@ Load as an undigested dictionary to compressor.
Pass this attribute as zstd_dict argument:
compress(dat, zstd_dict=zd.as_undigested_dict)
-1. The advanced compression parameters of compressor will not be overridden.
-2. Loading an undigested dictionary is costly. If load an undigested dictionary
- multiple times, consider reusing a compressor object.
+1. The advanced compression parameters of compressor will not be
+ overridden.
+2. Loading an undigested dictionary is costly. If load an undigested
+ dictionary multiple times, consider reusing a compressor object.
3. No need to use this for decompression.
[clinic start generated code]*/
static PyObject *
_zstd_ZstdDict_as_undigested_dict_get_impl(ZstdDict *self)
-/*[clinic end generated code: output=43c7a989e6d4253a input=b1bdb306c3798ad4]*/
+/*[clinic end generated code: output=43c7a989e6d4253a input=56443c9c4e589cd5]*/
{
return Py_BuildValue("Oi", self, DICT_TYPE_UNDIGESTED);
}
/*[clinic input]
-@permit_long_docstring_body
@getter
_zstd.ZstdDict.as_prefix
@@ -211,15 +208,16 @@ Load as a prefix to compressor/decompressor.
Pass this attribute as zstd_dict argument:
compress(dat, zstd_dict=zd.as_prefix)
-1. Prefix is compatible with long distance matching, while dictionary is not.
-2. It only works for the first frame, then the compressor/decompressor will
- return to no prefix state.
+1. Prefix is compatible with long distance matching, while
+ dictionary is not.
+2. It only works for the first frame, then the
+ compressor/decompressor will return to no prefix state.
3. When decompressing, must use the same prefix as when compressing.
[clinic start generated code]*/
static PyObject *
_zstd_ZstdDict_as_prefix_get_impl(ZstdDict *self)
-/*[clinic end generated code: output=6f7130c356595a16 input=77966c012d15e6ab]*/
+/*[clinic end generated code: output=6f7130c356595a16 input=192681a899c6fad0]*/
{
return Py_BuildValue("Oi", self, DICT_TYPE_PREFIX);
}
From ef89cf56cc1150b2078ab4467813a378e31b9743 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 24 May 2026 15:24:57 +0200
Subject: [PATCH 130/213] [3.15] gh-150285: Fix too long docstrings in builtins
(GH-150293) (GH-150336)
(cherry picked from commit e1e06be11908ddb6935e8df35f972879dd1bc3d8)
Co-authored-by: Serhiy Storchaka
---
Objects/bytearrayobject.c | 98 ++++++------
Objects/bytes_methods.c | 4 +-
Objects/bytesobject.c | 105 +++++++------
Objects/clinic/bytearrayobject.c.h | 73 +++++----
Objects/clinic/bytesobject.c.h | 75 ++++-----
Objects/clinic/codeobject.c.h | 5 +-
Objects/clinic/floatobject.c.h | 6 +-
Objects/clinic/listobject.c.h | 10 +-
Objects/clinic/longobject.c.h | 45 +++---
Objects/clinic/memoryobject.c.h | 17 +-
Objects/clinic/odictobject.c.h | 5 +-
Objects/clinic/unicodeobject.c.h | 162 +++++++++----------
Objects/codeobject.c | 5 +-
Objects/dictobject.c | 3 +-
Objects/floatobject.c | 7 +-
Objects/frameobject.c | 3 +-
Objects/listobject.c | 11 +-
Objects/longobject.c | 53 ++++---
Objects/memoryobject.c | 20 +--
Objects/odictobject.c | 5 +-
Objects/setobject.c | 6 +-
Objects/sliceobject.c | 4 +-
Objects/typeobject.c | 3 +-
Objects/unicodeobject.c | 239 ++++++++++++++---------------
Python/bltinmodule.c | 139 +++++++++--------
Python/clinic/bltinmodule.c.h | 63 ++++----
26 files changed, 613 insertions(+), 553 deletions(-)
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index c583193b5a252c..ca7956579e80bb 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -1620,6 +1620,7 @@ bytearray_take_bytes_impl(PyByteArrayObject *self, PyObject *n)
/*[clinic input]
+@permit_long_summary
@critical_section
bytearray.translate
@@ -1630,14 +1631,15 @@ bytearray.translate
Return a copy with each character mapped by the given translation table.
-All characters occurring in the optional argument delete are removed.
-The remaining characters are mapped through the given translation table.
+All characters occurring in the optional argument delete are
+removed. The remaining characters are mapped through the given
+translation table.
[clinic start generated code]*/
static PyObject *
bytearray_translate_impl(PyByteArrayObject *self, PyObject *table,
PyObject *deletechars)
-/*[clinic end generated code: output=b6a8f01c2a74e446 input=cd6fa93ca04e05bc]*/
+/*[clinic end generated code: output=b6a8f01c2a74e446 input=e30d2ae004365ed9]*/
{
char *input, *output;
const char *table_chars;
@@ -1727,7 +1729,6 @@ bytearray_translate_impl(PyByteArrayObject *self, PyObject *table,
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
@staticmethod
bytearray.maketrans
@@ -1737,15 +1738,15 @@ bytearray.maketrans
Return a translation table usable for the bytes or bytearray translate method.
-The returned table will be one where each byte in frm is mapped to the byte at
-the same position in to.
+The returned table will be one where each byte in frm is mapped to
+the byte at the same position in to.
The bytes objects frm and to must be of the same length.
[clinic start generated code]*/
static PyObject *
bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to)
-/*[clinic end generated code: output=1df267d99f56b15e input=1146b43a592eca13]*/
+/*[clinic end generated code: output=1df267d99f56b15e input=c2f5f6e7e6b0221d]*/
{
return _Py_bytes_maketrans(frm, to);
}
@@ -1785,8 +1786,8 @@ bytearray.split
sep: object = None
The delimiter according which to split the bytearray.
- None (the default value) means split on ASCII whitespace characters
- (space, tab, return, newline, formfeed, vertical tab).
+ None (the default value) means split on ASCII whitespace
+ characters (space, tab, return, newline, formfeed, vertical tab).
maxsplit: Py_ssize_t = -1
Maximum number of splits to do.
-1 (the default value) means no limit.
@@ -1797,7 +1798,7 @@ Return a list of the sections in the bytearray, using sep as the delimiter.
static PyObject *
bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
Py_ssize_t maxsplit)
-/*[clinic end generated code: output=833e2cf385d9a04d input=dd9f6e2910cc3a34]*/
+/*[clinic end generated code: output=833e2cf385d9a04d input=45605178023b52ac]*/
{
PyObject *list = NULL;
@@ -1829,7 +1830,6 @@ bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
}
/*[clinic input]
-@permit_long_docstring_body
@critical_section
bytearray.partition
@@ -1838,17 +1838,18 @@ bytearray.partition
Partition the bytearray into three parts using the given separator.
-This will search for the separator sep in the bytearray. If the separator is
-found, returns a 3-tuple containing the part before the separator, the
-separator itself, and the part after it as new bytearray objects.
+This will search for the separator sep in the bytearray. If the
+separator is found, returns a 3-tuple containing the part before the
+separator, the separator itself, and the part after it as new
+bytearray objects.
-If the separator is not found, returns a 3-tuple containing the copy of the
-original bytearray object and two empty bytearray objects.
+If the separator is not found, returns a 3-tuple containing the copy
+of the original bytearray object and two empty bytearray objects.
[clinic start generated code]*/
static PyObject *
bytearray_partition_impl(PyByteArrayObject *self, PyObject *sep)
-/*[clinic end generated code: output=b5fa1e03f10cfccb input=b87276af883f39d9]*/
+/*[clinic end generated code: output=b5fa1e03f10cfccb input=d76673ed03acf5dd]*/
{
PyObject *bytesep, *result;
@@ -1868,7 +1869,6 @@ bytearray_partition_impl(PyByteArrayObject *self, PyObject *sep)
}
/*[clinic input]
-@permit_long_docstring_body
@critical_section
bytearray.rpartition
@@ -1877,18 +1877,19 @@ bytearray.rpartition
Partition the bytearray into three parts using the given separator.
-This will search for the separator sep in the bytearray, starting at the end.
-If the separator is found, returns a 3-tuple containing the part before the
-separator, the separator itself, and the part after it as new bytearray
-objects.
+This will search for the separator sep in the bytearray, starting at
+the end. If the separator is found, returns a 3-tuple containing
+the part before the separator, the separator itself, and the part
+after it as new bytearray objects.
-If the separator is not found, returns a 3-tuple containing two empty bytearray
-objects and the copy of the original bytearray object.
+If the separator is not found, returns a 3-tuple containing two
+empty bytearray objects and the copy of the original bytearray
+object.
[clinic start generated code]*/
static PyObject *
bytearray_rpartition_impl(PyByteArrayObject *self, PyObject *sep)
-/*[clinic end generated code: output=0186ce7b1ef61289 input=5bdcfc4c333bcfab]*/
+/*[clinic end generated code: output=0186ce7b1ef61289 input=b9216a2074174a36]*/
{
PyObject *bytesep, *result;
@@ -1909,19 +1910,19 @@ bytearray_rpartition_impl(PyByteArrayObject *self, PyObject *sep)
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
@critical_section
bytearray.rsplit = bytearray.split
Return a list of the sections in the bytearray, using sep as the delimiter.
-Splitting is done starting at the end of the bytearray and working to the front.
+Splitting is done starting at the end of the bytearray and working
+to the front.
[clinic start generated code]*/
static PyObject *
bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
Py_ssize_t maxsplit)
-/*[clinic end generated code: output=a55e0b5a03cb6190 input=60e9abf305128ff4]*/
+/*[clinic end generated code: output=a55e0b5a03cb6190 input=e201671c9a0c19ee]*/
{
PyObject *list = NULL;
@@ -2392,7 +2393,6 @@ bytearray_strip_impl_helper(PyByteArrayObject* self, PyObject* bytes, int stript
}
/*[clinic input]
-@permit_long_docstring_body
@critical_section
bytearray.strip
@@ -2401,12 +2401,13 @@ bytearray.strip
Strip leading and trailing bytes contained in the argument.
-If the argument is omitted or None, strip leading and trailing ASCII whitespace.
+If the argument is omitted or None, strip leading and trailing ASCII
+whitespace.
[clinic start generated code]*/
static PyObject *
bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
-/*[clinic end generated code: output=760412661a34ad5a input=6acaf88b2ec9daa7]*/
+/*[clinic end generated code: output=760412661a34ad5a input=f4ec5fa609df7d14]*/
{
return bytearray_strip_impl_helper(self, bytes, BOTHSTRIP);
}
@@ -2506,11 +2507,11 @@ bytearray.decode
encoding: str(c_default="NULL") = 'utf-8'
The encoding with which to decode the bytearray.
errors: str(c_default="NULL") = 'strict'
- The error handling scheme to use for the handling of decoding errors.
- The default is 'strict' meaning that decoding errors raise a
- UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
- as well as any other name registered with codecs.register_error that
- can handle UnicodeDecodeErrors.
+ The error handling scheme to use for the handling of decoding
+ errors. The default is 'strict' meaning that decoding errors
+ raise a UnicodeDecodeError. Other possible values are 'ignore'
+ and 'replace' as well as any other name registered with
+ codecs.register_error that can handle UnicodeDecodeErrors.
Decode the bytearray using the codec registered for encoding.
[clinic start generated code]*/
@@ -2518,7 +2519,7 @@ Decode the bytearray using the codec registered for encoding.
static PyObject *
bytearray_decode_impl(PyByteArrayObject *self, const char *encoding,
const char *errors)
-/*[clinic end generated code: output=f57d43f4a00b42c5 input=86c303ee376b8453]*/
+/*[clinic end generated code: output=f57d43f4a00b42c5 input=e51ce9b82b51e2ca]*/
{
if (encoding == NULL)
encoding = PyUnicode_GetDefaultEncoding();
@@ -2550,14 +2551,15 @@ bytearray.join
Concatenate any number of bytes/bytearray objects.
-The bytearray whose method is called is inserted in between each pair.
+The bytearray whose method is called is inserted in between each
+pair.
The result is returned as a new bytearray object.
[clinic start generated code]*/
static PyObject *
bytearray_join_impl(PyByteArrayObject *self, PyObject *iterable_of_bytes)
-/*[clinic end generated code: output=0ced382b5846a7ee input=49627e07ca31ca26]*/
+/*[clinic end generated code: output=0ced382b5846a7ee input=0a31db349efcd7fa]*/
{
PyObject *ret;
self->ob_exports++; // this protects `self` from being cleared/resized if `iterable_of_bytes` is a custom iterator
@@ -2588,7 +2590,6 @@ bytearray_rjust(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
@critical_section
bytearray.splitlines
@@ -2596,13 +2597,13 @@ bytearray.splitlines
Return a list of the lines in the bytearray, breaking at line boundaries.
-Line breaks are not included in the resulting list unless keepends is given and
-true.
+Line breaks are not included in the resulting list unless keepends
+is given and true.
[clinic start generated code]*/
static PyObject *
bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
-/*[clinic end generated code: output=4223c94b895f6ad9 input=21bc3f02bf1be832]*/
+/*[clinic end generated code: output=4223c94b895f6ad9 input=cc2bb740eed19f27]*/
{
return stringlib_splitlines(
(PyObject*) self, PyByteArray_AS_STRING(self),
@@ -2620,12 +2621,13 @@ bytearray.fromhex
Create a bytearray object from a string of hexadecimal numbers.
Spaces between two numbers are accepted.
-Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
+Example:
+ bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
[clinic start generated code]*/
static PyObject *
bytearray_fromhex_impl(PyTypeObject *type, PyObject *string)
-/*[clinic end generated code: output=8f0f0b6d30fb3ba0 input=7e314e5b2d7ab484]*/
+/*[clinic end generated code: output=8f0f0b6d30fb3ba0 input=2243a8b0b9e66cd5]*/
{
PyObject *result = _PyBytes_FromHex(string, type == &PyByteArray_Type);
if (type != &PyByteArray_Type && result != NULL) {
@@ -2641,8 +2643,8 @@ bytearray.hex
sep: object = NULL
An optional single character or byte to separate hex bytes.
bytes_per_sep: Py_ssize_t = 1
- How many bytes between separators. Positive values count from the
- right, negative values count from the left.
+ How many bytes between separators. Positive values count from
+ the right, negative values count from the left.
Create a string of hexadecimal numbers from a bytearray object.
@@ -2661,7 +2663,7 @@ Create a string of hexadecimal numbers from a bytearray object.
static PyObject *
bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep,
Py_ssize_t bytes_per_sep)
-/*[clinic end generated code: output=c9563921aff1262b input=d2b23ef057cfcad5]*/
+/*[clinic end generated code: output=c9563921aff1262b input=9ed746203691e894]*/
{
char* argbuf = PyByteArray_AS_STRING(self);
Py_ssize_t arglen = PyByteArray_GET_SIZE(self);
diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c
index 56a461d0dd08a7..414afeb7bb003c 100644
--- a/Objects/bytes_methods.c
+++ b/Objects/bytes_methods.c
@@ -277,8 +277,8 @@ _Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len)
PyDoc_STRVAR_shared(_Py_title__doc__,
"B.title() -> copy of B\n\
\n\
-Return a titlecased version of B, i.e. ASCII words start with uppercase\n\
-characters, all remaining cased characters have lowercase.");
+Return a titlecased version of B, i.e. ASCII words start with\n\
+uppercase characters, all remaining cased characters have lowercase.");
void
_Py_bytes_title(char *result, const char *s, Py_ssize_t len)
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 2d694922557429..1135770549c017 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -1849,12 +1849,13 @@ bytes___bytes___impl(PyBytesObject *self)
#define BOTHSTRIP 2
/*[clinic input]
+@permit_long_summary
bytes.split
sep: object = None
The delimiter according which to split the bytes.
- None (the default value) means split on ASCII whitespace characters
- (space, tab, return, newline, formfeed, vertical tab).
+ None (the default value) means split on ASCII whitespace
+ characters (space, tab, return, newline, formfeed, vertical tab).
maxsplit: Py_ssize_t = -1
Maximum number of splits to do.
-1 (the default value) means no limit.
@@ -1864,7 +1865,7 @@ Return a list of the sections in the bytes, using sep as the delimiter.
static PyObject *
bytes_split_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t maxsplit)
-/*[clinic end generated code: output=52126b5844c1d8ef input=8b809b39074abbfa]*/
+/*[clinic end generated code: output=52126b5844c1d8ef input=330ff95d92544b05]*/
{
Py_ssize_t len = PyBytes_GET_SIZE(self), n;
const char *s = PyBytes_AS_STRING(self), *sub;
@@ -1886,7 +1887,6 @@ bytes_split_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t maxsplit)
}
/*[clinic input]
-@permit_long_docstring_body
bytes.partition
sep: Py_buffer
@@ -1894,17 +1894,17 @@ bytes.partition
Partition the bytes into three parts using the given separator.
-This will search for the separator sep in the bytes. If the separator is found,
-returns a 3-tuple containing the part before the separator, the separator
-itself, and the part after it.
+This will search for the separator sep in the bytes. If the
+separator is found, returns a 3-tuple containing the part before the
+separator, the separator itself, and the part after it.
-If the separator is not found, returns a 3-tuple containing the original bytes
-object and two empty bytes objects.
+If the separator is not found, returns a 3-tuple containing the
+original bytes object and two empty bytes objects.
[clinic start generated code]*/
static PyObject *
bytes_partition_impl(PyBytesObject *self, Py_buffer *sep)
-/*[clinic end generated code: output=f532b392a17ff695 input=31c55a0cebaf7722]*/
+/*[clinic end generated code: output=f532b392a17ff695 input=2e6e551ea4f8b95a]*/
{
return stringlib_partition(
(PyObject*) self,
@@ -1914,7 +1914,6 @@ bytes_partition_impl(PyBytesObject *self, Py_buffer *sep)
}
/*[clinic input]
-@permit_long_docstring_body
bytes.rpartition
sep: Py_buffer
@@ -1922,17 +1921,18 @@ bytes.rpartition
Partition the bytes into three parts using the given separator.
-This will search for the separator sep in the bytes, starting at the end. If
-the separator is found, returns a 3-tuple containing the part before the
-separator, the separator itself, and the part after it.
+This will search for the separator sep in the bytes, starting at the
+end. If the separator is found, returns a 3-tuple containing the
+part before the separator, the separator itself, and the part after
+it.
-If the separator is not found, returns a 3-tuple containing two empty bytes
-objects and the original bytes object.
+If the separator is not found, returns a 3-tuple containing two
+empty bytes objects and the original bytes object.
[clinic start generated code]*/
static PyObject *
bytes_rpartition_impl(PyBytesObject *self, Py_buffer *sep)
-/*[clinic end generated code: output=191b114cbb028e50 input=9ea5a3ab0b02bf52]*/
+/*[clinic end generated code: output=191b114cbb028e50 input=f7d24f722a5470a4]*/
{
return stringlib_rpartition(
(PyObject*) self,
@@ -1942,17 +1942,18 @@ bytes_rpartition_impl(PyBytesObject *self, Py_buffer *sep)
}
/*[clinic input]
-@permit_long_docstring_body
+@permit_long_summary
bytes.rsplit = bytes.split
Return a list of the sections in the bytes, using sep as the delimiter.
-Splitting is done starting at the end of the bytes and working to the front.
+Splitting is done starting at the end of the bytes and working to
+the front.
[clinic start generated code]*/
static PyObject *
bytes_rsplit_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t maxsplit)
-/*[clinic end generated code: output=ba698d9ea01e1c8f input=55b6eaea1f3d7046]*/
+/*[clinic end generated code: output=ba698d9ea01e1c8f input=ba9bee56285f43e4]*/
{
Py_ssize_t len = PyBytes_GET_SIZE(self), n;
const char *s = PyBytes_AS_STRING(self), *sub;
@@ -2172,7 +2173,6 @@ do_argstrip(PyBytesObject *self, int striptype, PyObject *bytes)
}
/*[clinic input]
-@permit_long_docstring_body
bytes.strip
bytes: object = None
@@ -2180,12 +2180,13 @@ bytes.strip
Strip leading and trailing bytes contained in the argument.
-If the argument is omitted or None, strip leading and trailing ASCII whitespace.
+If the argument is omitted or None, strip leading and trailing ASCII
+whitespace.
[clinic start generated code]*/
static PyObject *
bytes_strip_impl(PyBytesObject *self, PyObject *bytes)
-/*[clinic end generated code: output=c7c228d3bd104a1b input=71904cd278c0ee03]*/
+/*[clinic end generated code: output=c7c228d3bd104a1b input=9ffea5f752032bd0]*/
{
return do_argstrip(self, BOTHSTRIP, bytes);
}
@@ -2245,6 +2246,7 @@ bytes_count_impl(PyBytesObject *self, PyObject *sub, Py_ssize_t start,
/*[clinic input]
+@permit_long_summary
bytes.translate
table: object
@@ -2254,14 +2256,15 @@ bytes.translate
Return a copy with each character mapped by the given translation table.
-All characters occurring in the optional argument delete are removed.
-The remaining characters are mapped through the given translation table.
+All characters occurring in the optional argument delete are
+removed. The remaining characters are mapped through the given
+translation table.
[clinic start generated code]*/
static PyObject *
bytes_translate_impl(PyBytesObject *self, PyObject *table,
PyObject *deletechars)
-/*[clinic end generated code: output=43be3437f1956211 input=0ecdf159f654233c]*/
+/*[clinic end generated code: output=43be3437f1956211 input=bddcdef0a87895d2]*/
{
const char *input;
char *output;
@@ -2379,7 +2382,6 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table,
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
@staticmethod
bytes.maketrans
@@ -2389,15 +2391,15 @@ bytes.maketrans
Return a translation table usable for the bytes or bytearray translate method.
-The returned table will be one where each byte in frm is mapped to the byte at
-the same position in to.
+The returned table will be one where each byte in frm is mapped to
+the byte at the same position in to.
The bytes objects frm and to must be of the same length.
[clinic start generated code]*/
static PyObject *
bytes_maketrans_impl(Py_buffer *frm, Py_buffer *to)
-/*[clinic end generated code: output=a36f6399d4b77f6f input=a06b75f44d933fb3]*/
+/*[clinic end generated code: output=a36f6399d4b77f6f input=3a577e5badfea8f7]*/
{
return _Py_bytes_maketrans(frm, to);
}
@@ -2432,6 +2434,7 @@ bytes_replace_impl(PyBytesObject *self, Py_buffer *old, Py_buffer *new,
/** End DALKE **/
/*[clinic input]
+@permit_long_summary
bytes.removeprefix as bytes_removeprefix
prefix: Py_buffer
@@ -2439,13 +2442,14 @@ bytes.removeprefix as bytes_removeprefix
Return a bytes object with the given prefix string removed if present.
-If the bytes starts with the prefix string, return bytes[len(prefix):].
-Otherwise, return a copy of the original bytes.
+If the bytes starts with the prefix string, return
+bytes[len(prefix):]. Otherwise, return a copy of the original
+bytes.
[clinic start generated code]*/
static PyObject *
bytes_removeprefix_impl(PyBytesObject *self, Py_buffer *prefix)
-/*[clinic end generated code: output=f006865331a06ab6 input=0c93bac817a8502c]*/
+/*[clinic end generated code: output=f006865331a06ab6 input=3a2672bcee61d7a7]*/
{
const char *self_start = PyBytes_AS_STRING(self);
Py_ssize_t self_len = PyBytes_GET_SIZE(self);
@@ -2468,6 +2472,7 @@ bytes_removeprefix_impl(PyBytesObject *self, Py_buffer *prefix)
}
/*[clinic input]
+@permit_long_summary
bytes.removesuffix as bytes_removesuffix
suffix: Py_buffer
@@ -2475,14 +2480,14 @@ bytes.removesuffix as bytes_removesuffix
Return a bytes object with the given suffix string removed if present.
-If the bytes ends with the suffix string and that suffix is not empty,
-return bytes[:-len(prefix)]. Otherwise, return a copy of the original
-bytes.
+If the bytes ends with the suffix string and that suffix is not
+empty, return bytes[:-len(prefix)]. Otherwise, return a copy of the
+original bytes.
[clinic start generated code]*/
static PyObject *
bytes_removesuffix_impl(PyBytesObject *self, Py_buffer *suffix)
-/*[clinic end generated code: output=d887d308e3242eeb input=9f4e1da8c637bbf1]*/
+/*[clinic end generated code: output=d887d308e3242eeb input=04df5f18a36f69d7]*/
{
const char *self_start = PyBytes_AS_STRING(self);
Py_ssize_t self_len = PyBytes_GET_SIZE(self);
@@ -2562,11 +2567,11 @@ bytes.decode
encoding: str(c_default="NULL") = 'utf-8'
The encoding with which to decode the bytes.
errors: str(c_default="NULL") = 'strict'
- The error handling scheme to use for the handling of decoding errors.
- The default is 'strict' meaning that decoding errors raise a
- UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
- as well as any other name registered with codecs.register_error that
- can handle UnicodeDecodeErrors.
+ The error handling scheme to use for the handling of decoding
+ errors. The default is 'strict' meaning that decoding errors
+ raise a UnicodeDecodeError. Other possible values are 'ignore'
+ and 'replace' as well as any other name registered with
+ codecs.register_error that can handle UnicodeDecodeErrors.
Decode the bytes using the codec registered for encoding.
[clinic start generated code]*/
@@ -2574,27 +2579,27 @@ Decode the bytes using the codec registered for encoding.
static PyObject *
bytes_decode_impl(PyBytesObject *self, const char *encoding,
const char *errors)
-/*[clinic end generated code: output=5649a53dde27b314 input=958174769d2a40ca]*/
+/*[clinic end generated code: output=5649a53dde27b314 input=94e9b8524f1d7f37]*/
{
return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors);
}
/*[clinic input]
-@permit_long_docstring_body
+@permit_long_summary
bytes.splitlines
keepends: bool = False
Return a list of the lines in the bytes, breaking at line boundaries.
-Line breaks are not included in the resulting list unless keepends is given and
-true.
+Line breaks are not included in the resulting list unless keepends
+is given and true.
[clinic start generated code]*/
static PyObject *
bytes_splitlines_impl(PyBytesObject *self, int keepends)
-/*[clinic end generated code: output=3484149a5d880ffb input=d17968d2a355fe55]*/
+/*[clinic end generated code: output=3484149a5d880ffb input=8734672f34430514]*/
{
return stringlib_splitlines(
(PyObject*) self, PyBytes_AS_STRING(self),
@@ -2745,8 +2750,8 @@ bytes.hex
sep: object = NULL
An optional single character or byte to separate hex bytes.
bytes_per_sep: Py_ssize_t = 1
- How many bytes between separators. Positive values count from the
- right, negative values count from the left.
+ How many bytes between separators. Positive values count from
+ the right, negative values count from the left.
Create a string of hexadecimal numbers from a bytes object.
@@ -2764,7 +2769,7 @@ Create a string of hexadecimal numbers from a bytes object.
static PyObject *
bytes_hex_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t bytes_per_sep)
-/*[clinic end generated code: output=588821f02cb9d8f5 input=bd8eceb755d8230f]*/
+/*[clinic end generated code: output=588821f02cb9d8f5 input=b8d40cf203d172dc]*/
{
const char *argbuf = PyBytes_AS_STRING(self);
Py_ssize_t arglen = PyBytes_GET_SIZE(self);
diff --git a/Objects/clinic/bytearrayobject.c.h b/Objects/clinic/bytearrayobject.c.h
index 64603adcc1124b..41ce82c05c57d9 100644
--- a/Objects/clinic/bytearrayobject.c.h
+++ b/Objects/clinic/bytearrayobject.c.h
@@ -679,8 +679,9 @@ PyDoc_STRVAR(bytearray_translate__doc__,
" table\n"
" Translation table, which must be a bytes object of length 256.\n"
"\n"
-"All characters occurring in the optional argument delete are removed.\n"
-"The remaining characters are mapped through the given translation table.");
+"All characters occurring in the optional argument delete are\n"
+"removed. The remaining characters are mapped through the given\n"
+"translation table.");
#define BYTEARRAY_TRANSLATE_METHODDEF \
{"translate", _PyCFunction_CAST(bytearray_translate), METH_FASTCALL|METH_KEYWORDS, bytearray_translate__doc__},
@@ -750,8 +751,8 @@ PyDoc_STRVAR(bytearray_maketrans__doc__,
"\n"
"Return a translation table usable for the bytes or bytearray translate method.\n"
"\n"
-"The returned table will be one where each byte in frm is mapped to the byte at\n"
-"the same position in to.\n"
+"The returned table will be one where each byte in frm is mapped to\n"
+"the byte at the same position in to.\n"
"\n"
"The bytes objects frm and to must be of the same length.");
@@ -901,8 +902,8 @@ PyDoc_STRVAR(bytearray_split__doc__,
"\n"
" sep\n"
" The delimiter according which to split the bytearray.\n"
-" None (the default value) means split on ASCII whitespace characters\n"
-" (space, tab, return, newline, formfeed, vertical tab).\n"
+" None (the default value) means split on ASCII whitespace\n"
+" characters (space, tab, return, newline, formfeed, vertical tab).\n"
" maxsplit\n"
" Maximum number of splits to do.\n"
" -1 (the default value) means no limit.");
@@ -991,12 +992,13 @@ PyDoc_STRVAR(bytearray_partition__doc__,
"\n"
"Partition the bytearray into three parts using the given separator.\n"
"\n"
-"This will search for the separator sep in the bytearray. If the separator is\n"
-"found, returns a 3-tuple containing the part before the separator, the\n"
-"separator itself, and the part after it as new bytearray objects.\n"
+"This will search for the separator sep in the bytearray. If the\n"
+"separator is found, returns a 3-tuple containing the part before the\n"
+"separator, the separator itself, and the part after it as new\n"
+"bytearray objects.\n"
"\n"
-"If the separator is not found, returns a 3-tuple containing the copy of the\n"
-"original bytearray object and two empty bytearray objects.");
+"If the separator is not found, returns a 3-tuple containing the copy\n"
+"of the original bytearray object and two empty bytearray objects.");
#define BYTEARRAY_PARTITION_METHODDEF \
{"partition", (PyCFunction)bytearray_partition, METH_O, bytearray_partition__doc__},
@@ -1022,13 +1024,14 @@ PyDoc_STRVAR(bytearray_rpartition__doc__,
"\n"
"Partition the bytearray into three parts using the given separator.\n"
"\n"
-"This will search for the separator sep in the bytearray, starting at the end.\n"
-"If the separator is found, returns a 3-tuple containing the part before the\n"
-"separator, the separator itself, and the part after it as new bytearray\n"
-"objects.\n"
+"This will search for the separator sep in the bytearray, starting at\n"
+"the end. If the separator is found, returns a 3-tuple containing\n"
+"the part before the separator, the separator itself, and the part\n"
+"after it as new bytearray objects.\n"
"\n"
-"If the separator is not found, returns a 3-tuple containing two empty bytearray\n"
-"objects and the copy of the original bytearray object.");
+"If the separator is not found, returns a 3-tuple containing two\n"
+"empty bytearray objects and the copy of the original bytearray\n"
+"object.");
#define BYTEARRAY_RPARTITION_METHODDEF \
{"rpartition", (PyCFunction)bytearray_rpartition, METH_O, bytearray_rpartition__doc__},
@@ -1056,13 +1059,14 @@ PyDoc_STRVAR(bytearray_rsplit__doc__,
"\n"
" sep\n"
" The delimiter according which to split the bytearray.\n"
-" None (the default value) means split on ASCII whitespace characters\n"
-" (space, tab, return, newline, formfeed, vertical tab).\n"
+" None (the default value) means split on ASCII whitespace\n"
+" characters (space, tab, return, newline, formfeed, vertical tab).\n"
" maxsplit\n"
" Maximum number of splits to do.\n"
" -1 (the default value) means no limit.\n"
"\n"
-"Splitting is done starting at the end of the bytearray and working to the front.");
+"Splitting is done starting at the end of the bytearray and working\n"
+"to the front.");
#define BYTEARRAY_RSPLIT_METHODDEF \
{"rsplit", _PyCFunction_CAST(bytearray_rsplit), METH_FASTCALL|METH_KEYWORDS, bytearray_rsplit__doc__},
@@ -1364,7 +1368,8 @@ PyDoc_STRVAR(bytearray_strip__doc__,
"\n"
"Strip leading and trailing bytes contained in the argument.\n"
"\n"
-"If the argument is omitted or None, strip leading and trailing ASCII whitespace.");
+"If the argument is omitted or None, strip leading and trailing ASCII\n"
+"whitespace.");
#define BYTEARRAY_STRIP_METHODDEF \
{"strip", _PyCFunction_CAST(bytearray_strip), METH_FASTCALL, bytearray_strip__doc__},
@@ -1475,11 +1480,11 @@ PyDoc_STRVAR(bytearray_decode__doc__,
" encoding\n"
" The encoding with which to decode the bytearray.\n"
" errors\n"
-" The error handling scheme to use for the handling of decoding errors.\n"
-" The default is \'strict\' meaning that decoding errors raise a\n"
-" UnicodeDecodeError. Other possible values are \'ignore\' and \'replace\'\n"
-" as well as any other name registered with codecs.register_error that\n"
-" can handle UnicodeDecodeErrors.");
+" The error handling scheme to use for the handling of decoding\n"
+" errors. The default is \'strict\' meaning that decoding errors\n"
+" raise a UnicodeDecodeError. Other possible values are \'ignore\'\n"
+" and \'replace\' as well as any other name registered with\n"
+" codecs.register_error that can handle UnicodeDecodeErrors.");
#define BYTEARRAY_DECODE_METHODDEF \
{"decode", _PyCFunction_CAST(bytearray_decode), METH_FASTCALL|METH_KEYWORDS, bytearray_decode__doc__},
@@ -1578,7 +1583,8 @@ PyDoc_STRVAR(bytearray_join__doc__,
"\n"
"Concatenate any number of bytes/bytearray objects.\n"
"\n"
-"The bytearray whose method is called is inserted in between each pair.\n"
+"The bytearray whose method is called is inserted in between each\n"
+"pair.\n"
"\n"
"The result is returned as a new bytearray object.");
@@ -1606,8 +1612,8 @@ PyDoc_STRVAR(bytearray_splitlines__doc__,
"\n"
"Return a list of the lines in the bytearray, breaking at line boundaries.\n"
"\n"
-"Line breaks are not included in the resulting list unless keepends is given and\n"
-"true.");
+"Line breaks are not included in the resulting list unless keepends\n"
+"is given and true.");
#define BYTEARRAY_SPLITLINES_METHODDEF \
{"splitlines", _PyCFunction_CAST(bytearray_splitlines), METH_FASTCALL|METH_KEYWORDS, bytearray_splitlines__doc__},
@@ -1678,7 +1684,8 @@ PyDoc_STRVAR(bytearray_fromhex__doc__,
"Create a bytearray object from a string of hexadecimal numbers.\n"
"\n"
"Spaces between two numbers are accepted.\n"
-"Example: bytearray.fromhex(\'B9 01EF\') -> bytearray(b\'\\\\xb9\\\\x01\\\\xef\')");
+"Example:\n"
+" bytearray.fromhex(\'B9 01EF\') -> bytearray(b\'\\\\xb9\\\\x01\\\\xef\')");
#define BYTEARRAY_FROMHEX_METHODDEF \
{"fromhex", (PyCFunction)bytearray_fromhex, METH_O|METH_CLASS, bytearray_fromhex__doc__},
@@ -1705,8 +1712,8 @@ PyDoc_STRVAR(bytearray_hex__doc__,
" sep\n"
" An optional single character or byte to separate hex bytes.\n"
" bytes_per_sep\n"
-" How many bytes between separators. Positive values count from the\n"
-" right, negative values count from the left.\n"
+" How many bytes between separators. Positive values count from\n"
+" the right, negative values count from the left.\n"
"\n"
"Example:\n"
">>> value = bytearray([0xb9, 0x01, 0xef])\n"
@@ -1875,4 +1882,4 @@ bytearray_sizeof(PyObject *self, PyObject *Py_UNUSED(ignored))
{
return bytearray_sizeof_impl((PyByteArrayObject *)self);
}
-/*[clinic end generated code: output=2cacb323147202b9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=6dc315d35de3e670 input=a9049054013a1b77]*/
diff --git a/Objects/clinic/bytesobject.c.h b/Objects/clinic/bytesobject.c.h
index 4ff696be91b12d..ee2b737f9e63f9 100644
--- a/Objects/clinic/bytesobject.c.h
+++ b/Objects/clinic/bytesobject.c.h
@@ -35,8 +35,8 @@ PyDoc_STRVAR(bytes_split__doc__,
"\n"
" sep\n"
" The delimiter according which to split the bytes.\n"
-" None (the default value) means split on ASCII whitespace characters\n"
-" (space, tab, return, newline, formfeed, vertical tab).\n"
+" None (the default value) means split on ASCII whitespace\n"
+" characters (space, tab, return, newline, formfeed, vertical tab).\n"
" maxsplit\n"
" Maximum number of splits to do.\n"
" -1 (the default value) means no limit.");
@@ -122,12 +122,12 @@ PyDoc_STRVAR(bytes_partition__doc__,
"\n"
"Partition the bytes into three parts using the given separator.\n"
"\n"
-"This will search for the separator sep in the bytes. If the separator is found,\n"
-"returns a 3-tuple containing the part before the separator, the separator\n"
-"itself, and the part after it.\n"
+"This will search for the separator sep in the bytes. If the\n"
+"separator is found, returns a 3-tuple containing the part before the\n"
+"separator, the separator itself, and the part after it.\n"
"\n"
-"If the separator is not found, returns a 3-tuple containing the original bytes\n"
-"object and two empty bytes objects.");
+"If the separator is not found, returns a 3-tuple containing the\n"
+"original bytes object and two empty bytes objects.");
#define BYTES_PARTITION_METHODDEF \
{"partition", (PyCFunction)bytes_partition, METH_O, bytes_partition__doc__},
@@ -161,12 +161,13 @@ PyDoc_STRVAR(bytes_rpartition__doc__,
"\n"
"Partition the bytes into three parts using the given separator.\n"
"\n"
-"This will search for the separator sep in the bytes, starting at the end. If\n"
-"the separator is found, returns a 3-tuple containing the part before the\n"
-"separator, the separator itself, and the part after it.\n"
+"This will search for the separator sep in the bytes, starting at the\n"
+"end. If the separator is found, returns a 3-tuple containing the\n"
+"part before the separator, the separator itself, and the part after\n"
+"it.\n"
"\n"
-"If the separator is not found, returns a 3-tuple containing two empty bytes\n"
-"objects and the original bytes object.");
+"If the separator is not found, returns a 3-tuple containing two\n"
+"empty bytes objects and the original bytes object.");
#define BYTES_RPARTITION_METHODDEF \
{"rpartition", (PyCFunction)bytes_rpartition, METH_O, bytes_rpartition__doc__},
@@ -202,13 +203,14 @@ PyDoc_STRVAR(bytes_rsplit__doc__,
"\n"
" sep\n"
" The delimiter according which to split the bytes.\n"
-" None (the default value) means split on ASCII whitespace characters\n"
-" (space, tab, return, newline, formfeed, vertical tab).\n"
+" None (the default value) means split on ASCII whitespace\n"
+" characters (space, tab, return, newline, formfeed, vertical tab).\n"
" maxsplit\n"
" Maximum number of splits to do.\n"
" -1 (the default value) means no limit.\n"
"\n"
-"Splitting is done starting at the end of the bytes and working to the front.");
+"Splitting is done starting at the end of the bytes and working to\n"
+"the front.");
#define BYTES_RSPLIT_METHODDEF \
{"rsplit", _PyCFunction_CAST(bytes_rsplit), METH_FASTCALL|METH_KEYWORDS, bytes_rsplit__doc__},
@@ -523,7 +525,8 @@ PyDoc_STRVAR(bytes_strip__doc__,
"\n"
"Strip leading and trailing bytes contained in the argument.\n"
"\n"
-"If the argument is omitted or None, strip leading and trailing ASCII whitespace.");
+"If the argument is omitted or None, strip leading and trailing ASCII\n"
+"whitespace.");
#define BYTES_STRIP_METHODDEF \
{"strip", _PyCFunction_CAST(bytes_strip), METH_FASTCALL, bytes_strip__doc__},
@@ -677,8 +680,9 @@ PyDoc_STRVAR(bytes_translate__doc__,
" table\n"
" Translation table, which must be a bytes object of length 256.\n"
"\n"
-"All characters occurring in the optional argument delete are removed.\n"
-"The remaining characters are mapped through the given translation table.");
+"All characters occurring in the optional argument delete are\n"
+"removed. The remaining characters are mapped through the given\n"
+"translation table.");
#define BYTES_TRANSLATE_METHODDEF \
{"translate", _PyCFunction_CAST(bytes_translate), METH_FASTCALL|METH_KEYWORDS, bytes_translate__doc__},
@@ -746,8 +750,8 @@ PyDoc_STRVAR(bytes_maketrans__doc__,
"\n"
"Return a translation table usable for the bytes or bytearray translate method.\n"
"\n"
-"The returned table will be one where each byte in frm is mapped to the byte at\n"
-"the same position in to.\n"
+"The returned table will be one where each byte in frm is mapped to\n"
+"the byte at the same position in to.\n"
"\n"
"The bytes objects frm and to must be of the same length.");
@@ -893,8 +897,9 @@ PyDoc_STRVAR(bytes_removeprefix__doc__,
"\n"
"Return a bytes object with the given prefix string removed if present.\n"
"\n"
-"If the bytes starts with the prefix string, return bytes[len(prefix):].\n"
-"Otherwise, return a copy of the original bytes.");
+"If the bytes starts with the prefix string, return\n"
+"bytes[len(prefix):]. Otherwise, return a copy of the original\n"
+"bytes.");
#define BYTES_REMOVEPREFIX_METHODDEF \
{"removeprefix", (PyCFunction)bytes_removeprefix, METH_O, bytes_removeprefix__doc__},
@@ -928,9 +933,9 @@ PyDoc_STRVAR(bytes_removesuffix__doc__,
"\n"
"Return a bytes object with the given suffix string removed if present.\n"
"\n"
-"If the bytes ends with the suffix string and that suffix is not empty,\n"
-"return bytes[:-len(prefix)]. Otherwise, return a copy of the original\n"
-"bytes.");
+"If the bytes ends with the suffix string and that suffix is not\n"
+"empty, return bytes[:-len(prefix)]. Otherwise, return a copy of the\n"
+"original bytes.");
#define BYTES_REMOVESUFFIX_METHODDEF \
{"removesuffix", (PyCFunction)bytes_removesuffix, METH_O, bytes_removesuffix__doc__},
@@ -1069,11 +1074,11 @@ PyDoc_STRVAR(bytes_decode__doc__,
" encoding\n"
" The encoding with which to decode the bytes.\n"
" errors\n"
-" The error handling scheme to use for the handling of decoding errors.\n"
-" The default is \'strict\' meaning that decoding errors raise a\n"
-" UnicodeDecodeError. Other possible values are \'ignore\' and \'replace\'\n"
-" as well as any other name registered with codecs.register_error that\n"
-" can handle UnicodeDecodeErrors.");
+" The error handling scheme to use for the handling of decoding\n"
+" errors. The default is \'strict\' meaning that decoding errors\n"
+" raise a UnicodeDecodeError. Other possible values are \'ignore\'\n"
+" and \'replace\' as well as any other name registered with\n"
+" codecs.register_error that can handle UnicodeDecodeErrors.");
#define BYTES_DECODE_METHODDEF \
{"decode", _PyCFunction_CAST(bytes_decode), METH_FASTCALL|METH_KEYWORDS, bytes_decode__doc__},
@@ -1170,8 +1175,8 @@ PyDoc_STRVAR(bytes_splitlines__doc__,
"\n"
"Return a list of the lines in the bytes, breaking at line boundaries.\n"
"\n"
-"Line breaks are not included in the resulting list unless keepends is given and\n"
-"true.");
+"Line breaks are not included in the resulting list unless keepends\n"
+"is given and true.");
#define BYTES_SPLITLINES_METHODDEF \
{"splitlines", _PyCFunction_CAST(bytes_splitlines), METH_FASTCALL|METH_KEYWORDS, bytes_splitlines__doc__},
@@ -1267,8 +1272,8 @@ PyDoc_STRVAR(bytes_hex__doc__,
" sep\n"
" An optional single character or byte to separate hex bytes.\n"
" bytes_per_sep\n"
-" How many bytes between separators. Positive values count from the\n"
-" right, negative values count from the left.\n"
+" How many bytes between separators. Positive values count from\n"
+" the right, negative values count from the left.\n"
"\n"
"Example:\n"
">>> value = b\'\\xb9\\x01\\xef\'\n"
@@ -1450,4 +1455,4 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=b252801ff04a89b3 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=c20458db7a2123db input=a9049054013a1b77]*/
diff --git a/Objects/clinic/codeobject.c.h b/Objects/clinic/codeobject.c.h
index 0cd6e0b56620e8..88333e9d3363eb 100644
--- a/Objects/clinic/codeobject.c.h
+++ b/Objects/clinic/codeobject.c.h
@@ -414,7 +414,8 @@ PyDoc_STRVAR(code__varname_from_oparg__doc__,
"\n"
"(internal-only) Return the local variable name for the given oparg.\n"
"\n"
-"WARNING: this method is for internal use only and may change or go away.");
+"WARNING: this method is for internal use only and may change or go\n"
+"away.");
#define CODE__VARNAME_FROM_OPARG_METHODDEF \
{"_varname_from_oparg", _PyCFunction_CAST(code__varname_from_oparg), METH_FASTCALL|METH_KEYWORDS, code__varname_from_oparg__doc__},
@@ -470,4 +471,4 @@ code__varname_from_oparg(PyObject *self, PyObject *const *args, Py_ssize_t nargs
exit:
return return_value;
}
-/*[clinic end generated code: output=c5c6e40fc357defe input=a9049054013a1b77]*/
+/*[clinic end generated code: output=5c22e29e430401b4 input=a9049054013a1b77]*/
diff --git a/Objects/clinic/floatobject.c.h b/Objects/clinic/floatobject.c.h
index c0ae9d3ff9b8d3..8768555c909257 100644
--- a/Objects/clinic/floatobject.c.h
+++ b/Objects/clinic/floatobject.c.h
@@ -291,8 +291,8 @@ PyDoc_STRVAR(float___getformat____doc__,
"It exists mainly to be used in Python\'s test suite.\n"
"\n"
"This function returns whichever of \'IEEE, big-endian\' or \'IEEE,\n"
-"little-endian\' best describes the format of floating-point numbers used by the\n"
-"C type named by typestr.");
+"little-endian\' best describes the format of floating-point numbers\n"
+"used by the C type named by typestr.");
#define FLOAT___GETFORMAT___METHODDEF \
{"__getformat__", (PyCFunction)float___getformat__, METH_O|METH_CLASS, float___getformat____doc__},
@@ -353,4 +353,4 @@ float___format__(PyObject *self, PyObject *arg)
exit:
return return_value;
}
-/*[clinic end generated code: output=f0b2af257213c8b0 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=5d7b0bf9e47ff997 input=a9049054013a1b77]*/
diff --git a/Objects/clinic/listobject.c.h b/Objects/clinic/listobject.c.h
index 26ba5b954336da..f3821ef5f70c21 100644
--- a/Objects/clinic/listobject.c.h
+++ b/Objects/clinic/listobject.c.h
@@ -200,11 +200,11 @@ PyDoc_STRVAR(list_sort__doc__,
"\n"
"Sort the list in ascending order and return None.\n"
"\n"
-"The sort is in-place (i.e. the list itself is modified) and stable (i.e. the\n"
-"order of two equal elements is maintained).\n"
+"The sort is in-place (i.e. the list itself is modified) and stable\n"
+"(i.e. the order of two equal elements is maintained).\n"
"\n"
-"If a key function is given, apply it once to each list item and sort them,\n"
-"ascending or descending, according to their function values.\n"
+"If a key function is given, apply it once to each list item and sort\n"
+"them, ascending or descending, according to their function values.\n"
"\n"
"The reverse flag can be set to sort in descending order.");
@@ -468,4 +468,4 @@ list___reversed__(PyObject *self, PyObject *Py_UNUSED(ignored))
{
return list___reversed___impl((PyListObject *)self);
}
-/*[clinic end generated code: output=ae13fc2b56dc27c2 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=06c21b0bffbe8d84 input=a9049054013a1b77]*/
diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h
index c88772030ec283..52ecaffa1f4cf3 100644
--- a/Objects/clinic/longobject.c.h
+++ b/Objects/clinic/longobject.c.h
@@ -262,19 +262,20 @@ PyDoc_STRVAR(int_to_bytes__doc__,
"Return an array of bytes representing an integer.\n"
"\n"
" length\n"
-" Length of bytes object to use. An OverflowError is raised if the\n"
-" integer is not representable with the given number of bytes. Default\n"
-" is length 1.\n"
+" Length of bytes object to use. An OverflowError is raised if\n"
+" the integer is not representable with the given number of bytes.\n"
+" Default is length 1.\n"
" byteorder\n"
-" The byte order used to represent the integer. If byteorder is \'big\',\n"
-" the most significant byte is at the beginning of the byte array. If\n"
-" byteorder is \'little\', the most significant byte is at the end of the\n"
-" byte array. To request the native byte order of the host system, use\n"
-" sys.byteorder as the byte order value. Default is to use \'big\'.\n"
+" The byte order used to represent the integer. If byteorder is\n"
+" \'big\', the most significant byte is at the beginning of the byte\n"
+" array. If byteorder is \'little\', the most significant byte is at\n"
+" the end of the byte array. To request the native byte order of\n"
+" the host system, use sys.byteorder as the byte order value.\n"
+" Default is to use \'big\'.\n"
" signed\n"
-" Determines whether two\'s complement is used to represent the integer.\n"
-" If signed is False and a negative integer is given, an OverflowError\n"
-" is raised.");
+" Determines whether two\'s complement is used to represent the\n"
+" integer. If signed is False and a negative integer is given,\n"
+" an OverflowError is raised.");
#define INT_TO_BYTES_METHODDEF \
{"to_bytes", _PyCFunction_CAST(int_to_bytes), METH_FASTCALL|METH_KEYWORDS, int_to_bytes__doc__},
@@ -383,17 +384,19 @@ PyDoc_STRVAR(int_from_bytes__doc__,
"\n"
" bytes\n"
" Holds the array of bytes to convert. The argument must either\n"
-" support the buffer protocol or be an iterable object producing bytes.\n"
-" Bytes and bytearray are examples of built-in objects that support the\n"
-" buffer protocol.\n"
+" support the buffer protocol or be an iterable object producing\n"
+" bytes. Bytes and bytearray are examples of built-in objects that\n"
+" support the buffer protocol.\n"
" byteorder\n"
-" The byte order used to represent the integer. If byteorder is \'big\',\n"
-" the most significant byte is at the beginning of the byte array. If\n"
-" byteorder is \'little\', the most significant byte is at the end of the\n"
-" byte array. To request the native byte order of the host system, use\n"
-" sys.byteorder as the byte order value. Default is to use \'big\'.\n"
+" The byte order used to represent the integer. If byteorder is\n"
+" \'big\', the most significant byte is at the beginning of the byte\n"
+" array. If byteorder is \'little\', the most significant byte is at\n"
+" the end of the byte array. To request the native byte order of\n"
+" the host system, use sys.byteorder as the byte order value.\n"
+" Default is to use \'big\'.\n"
" signed\n"
-" Indicates whether two\'s complement is used to represent the integer.");
+" Indicates whether two\'s complement is used to represent the\n"
+" integer.");
#define INT_FROM_BYTES_METHODDEF \
{"from_bytes", _PyCFunction_CAST(int_from_bytes), METH_FASTCALL|METH_KEYWORDS|METH_CLASS, int_from_bytes__doc__},
@@ -490,4 +493,4 @@ int_is_integer(PyObject *self, PyObject *Py_UNUSED(ignored))
{
return int_is_integer_impl(self);
}
-/*[clinic end generated code: output=e68f4e23ead3f649 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=d95766fb7ff46963 input=a9049054013a1b77]*/
diff --git a/Objects/clinic/memoryobject.c.h b/Objects/clinic/memoryobject.c.h
index d97c626532c803..a0cf3243edc08a 100644
--- a/Objects/clinic/memoryobject.c.h
+++ b/Objects/clinic/memoryobject.c.h
@@ -259,11 +259,12 @@ PyDoc_STRVAR(memoryview_tobytes__doc__,
"\n"
"Return the data in the buffer as a byte string.\n"
"\n"
-"Order can be {\'C\', \'F\', \'A\'}. When order is \'C\' or \'F\', the data of the\n"
-"original array is converted to C or Fortran order. For contiguous views,\n"
-"\'A\' returns an exact copy of the physical memory. In particular, in-memory\n"
-"Fortran order is preserved. For non-contiguous views, the data is converted\n"
-"to C first. order=None is the same as order=\'C\'.");
+"Order can be {\'C\', \'F\', \'A\'}. When order is \'C\' or \'F\', the data of\n"
+"the original array is converted to C or Fortran order. For\n"
+"contiguous views, \'A\' returns an exact copy of the physical memory.\n"
+"In particular, in-memory Fortran order is preserved. For\n"
+"non-contiguous views, the data is converted to C first. order=None\n"
+"is the same as order=\'C\'.");
#define MEMORYVIEW_TOBYTES_METHODDEF \
{"tobytes", _PyCFunction_CAST(memoryview_tobytes), METH_FASTCALL|METH_KEYWORDS, memoryview_tobytes__doc__},
@@ -348,8 +349,8 @@ PyDoc_STRVAR(memoryview_hex__doc__,
" sep\n"
" An optional single character or byte to separate hex bytes.\n"
" bytes_per_sep\n"
-" How many bytes between separators. Positive values count from the\n"
-" right, negative values count from the left.\n"
+" How many bytes between separators. Positive values count from\n"
+" the right, negative values count from the left.\n"
"\n"
"Example:\n"
">>> value = memoryview(b\'\\xb9\\x01\\xef\')\n"
@@ -505,4 +506,4 @@ memoryview_index(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=348b6ddb98a1f412 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=3abf9c80cd49229a input=a9049054013a1b77]*/
diff --git a/Objects/clinic/odictobject.c.h b/Objects/clinic/odictobject.c.h
index 894e9be91bbdce..92129e6444810f 100644
--- a/Objects/clinic/odictobject.c.h
+++ b/Objects/clinic/odictobject.c.h
@@ -268,7 +268,8 @@ PyDoc_STRVAR(OrderedDict_popitem__doc__,
"\n"
"Remove and return a (key, value) pair from the dictionary.\n"
"\n"
-"Pairs are returned in LIFO order if last is true or FIFO order if false.");
+"Pairs are returned in LIFO order if last is true or FIFO order if\n"
+"false.");
#define ORDEREDDICT_POPITEM_METHODDEF \
{"popitem", _PyCFunction_CAST(OrderedDict_popitem), METH_FASTCALL|METH_KEYWORDS, OrderedDict_popitem__doc__},
@@ -451,4 +452,4 @@ OrderedDict_move_to_end(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
exit:
return return_value;
}
-/*[clinic end generated code: output=7bc997ca7900f06f input=a9049054013a1b77]*/
+/*[clinic end generated code: output=89f7e92de998f9a4 input=a9049054013a1b77]*/
diff --git a/Objects/clinic/unicodeobject.c.h b/Objects/clinic/unicodeobject.c.h
index 4b53e24fb7d649..d0753b38843fcc 100644
--- a/Objects/clinic/unicodeobject.c.h
+++ b/Objects/clinic/unicodeobject.c.h
@@ -33,8 +33,8 @@ PyDoc_STRVAR(unicode_title__doc__,
"\n"
"Return a version of the string where each word is titlecased.\n"
"\n"
-"More specifically, words start with uppercased characters and all remaining\n"
-"cased characters have lower case.");
+"More specifically, words start with uppercased characters and all\n"
+"remaining cased characters have lower case.");
#define UNICODE_TITLE_METHODDEF \
{"title", (PyCFunction)unicode_title, METH_NOARGS, unicode_title__doc__},
@@ -54,8 +54,8 @@ PyDoc_STRVAR(unicode_capitalize__doc__,
"\n"
"Return a capitalized version of the string.\n"
"\n"
-"More specifically, make the first character have upper case and the rest lower\n"
-"case.");
+"More specifically, make the first character have upper case and the\n"
+"rest lower case.");
#define UNICODE_CAPITALIZE_METHODDEF \
{"capitalize", (PyCFunction)unicode_capitalize, METH_NOARGS, unicode_capitalize__doc__},
@@ -93,7 +93,8 @@ PyDoc_STRVAR(unicode_center__doc__,
"\n"
"Return a centered string of length width.\n"
"\n"
-"Padding is done using the specified fill character (default is a space).");
+"Padding is done using the specified fill character (default is\n"
+"a space).");
#define UNICODE_CENTER_METHODDEF \
{"center", _PyCFunction_CAST(unicode_center), METH_FASTCALL, unicode_center__doc__},
@@ -142,7 +143,8 @@ PyDoc_STRVAR(unicode_count__doc__,
"\n"
"Return the number of non-overlapping occurrences of substring sub in string S[start:end].\n"
"\n"
-"Optional arguments start and end are interpreted as in slice notation.");
+"Optional arguments start and end are interpreted as in slice\n"
+"notation.");
#define UNICODE_COUNT_METHODDEF \
{"count", _PyCFunction_CAST(unicode_count), METH_FASTCALL, unicode_count__doc__},
@@ -202,8 +204,8 @@ PyDoc_STRVAR(unicode_encode__doc__,
" errors\n"
" The error handling scheme to use for encoding errors.\n"
" The default is \'strict\' meaning that encoding errors raise a\n"
-" UnicodeEncodeError. Other possible values are \'ignore\', \'replace\' and\n"
-" \'xmlcharrefreplace\' as well as any other name registered with\n"
+" UnicodeEncodeError. Other possible values are \'ignore\', \'replace\'\n"
+" and \'xmlcharrefreplace\' as well as any other name registered with\n"
" codecs.register_error that can handle UnicodeEncodeErrors.");
#define UNICODE_ENCODE_METHODDEF \
@@ -368,8 +370,8 @@ PyDoc_STRVAR(unicode_find__doc__,
"\n"
"Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end].\n"
"\n"
-"Optional arguments start and end are interpreted as in slice notation.\n"
-"Return -1 on failure.");
+"Optional arguments start and end are interpreted as in slice\n"
+"notation. Return -1 on failure.");
#define UNICODE_FIND_METHODDEF \
{"find", _PyCFunction_CAST(unicode_find), METH_FASTCALL, unicode_find__doc__},
@@ -424,8 +426,8 @@ PyDoc_STRVAR(unicode_index__doc__,
"\n"
"Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end].\n"
"\n"
-"Optional arguments start and end are interpreted as in slice notation.\n"
-"Raises ValueError when the substring is not found.");
+"Optional arguments start and end are interpreted as in slice\n"
+"notation. Raises ValueError when the substring is not found.");
#define UNICODE_INDEX_METHODDEF \
{"index", _PyCFunction_CAST(unicode_index), METH_FASTCALL, unicode_index__doc__},
@@ -501,8 +503,8 @@ PyDoc_STRVAR(unicode_islower__doc__,
"\n"
"Return True if the string is a lowercase string, False otherwise.\n"
"\n"
-"A string is lowercase if all cased characters in the string are lowercase and\n"
-"there is at least one cased character in the string.");
+"A string is lowercase if all cased characters in the string are\n"
+"lowercase and there is at least one cased character in the string.");
#define UNICODE_ISLOWER_METHODDEF \
{"islower", (PyCFunction)unicode_islower, METH_NOARGS, unicode_islower__doc__},
@@ -522,8 +524,8 @@ PyDoc_STRVAR(unicode_isupper__doc__,
"\n"
"Return True if the string is an uppercase string, False otherwise.\n"
"\n"
-"A string is uppercase if all cased characters in the string are uppercase and\n"
-"there is at least one cased character in the string.");
+"A string is uppercase if all cased characters in the string are\n"
+"uppercase and there is at least one cased character in the string.");
#define UNICODE_ISUPPER_METHODDEF \
{"isupper", (PyCFunction)unicode_isupper, METH_NOARGS, unicode_isupper__doc__},
@@ -564,8 +566,8 @@ PyDoc_STRVAR(unicode_isspace__doc__,
"\n"
"Return True if the string is a whitespace string, False otherwise.\n"
"\n"
-"A string is whitespace if all characters in the string are whitespace and there\n"
-"is at least one character in the string.");
+"A string is whitespace if all characters in the string are\n"
+"whitespace and there is at least one character in the string.");
#define UNICODE_ISSPACE_METHODDEF \
{"isspace", (PyCFunction)unicode_isspace, METH_NOARGS, unicode_isspace__doc__},
@@ -585,8 +587,8 @@ PyDoc_STRVAR(unicode_isalpha__doc__,
"\n"
"Return True if the string is an alphabetic string, False otherwise.\n"
"\n"
-"A string is alphabetic if all characters in the string are alphabetic and there\n"
-"is at least one character in the string.");
+"A string is alphabetic if all characters in the string are\n"
+"alphabetic and there is at least one character in the string.");
#define UNICODE_ISALPHA_METHODDEF \
{"isalpha", (PyCFunction)unicode_isalpha, METH_NOARGS, unicode_isalpha__doc__},
@@ -606,8 +608,8 @@ PyDoc_STRVAR(unicode_isalnum__doc__,
"\n"
"Return True if the string is an alpha-numeric string, False otherwise.\n"
"\n"
-"A string is alpha-numeric if all characters in the string are alpha-numeric and\n"
-"there is at least one character in the string.");
+"A string is alpha-numeric if all characters in the string are\n"
+"alpha-numeric and there is at least one character in the string.");
#define UNICODE_ISALNUM_METHODDEF \
{"isalnum", (PyCFunction)unicode_isalnum, METH_NOARGS, unicode_isalnum__doc__},
@@ -627,8 +629,8 @@ PyDoc_STRVAR(unicode_isdecimal__doc__,
"\n"
"Return True if the string is a decimal string, False otherwise.\n"
"\n"
-"A string is a decimal string if all characters in the string are decimal and\n"
-"there is at least one character in the string.");
+"A string is a decimal string if all characters in the string are\n"
+"decimal and there is at least one character in the string.");
#define UNICODE_ISDECIMAL_METHODDEF \
{"isdecimal", (PyCFunction)unicode_isdecimal, METH_NOARGS, unicode_isdecimal__doc__},
@@ -648,8 +650,8 @@ PyDoc_STRVAR(unicode_isdigit__doc__,
"\n"
"Return True if the string is a digit string, False otherwise.\n"
"\n"
-"A string is a digit string if all characters in the string are digits and there\n"
-"is at least one character in the string.");
+"A string is a digit string if all characters in the string are\n"
+"digits and there is at least one character in the string.");
#define UNICODE_ISDIGIT_METHODDEF \
{"isdigit", (PyCFunction)unicode_isdigit, METH_NOARGS, unicode_isdigit__doc__},
@@ -669,8 +671,8 @@ PyDoc_STRVAR(unicode_isnumeric__doc__,
"\n"
"Return True if the string is a numeric string, False otherwise.\n"
"\n"
-"A string is numeric if all characters in the string are numeric and there is at\n"
-"least one character in the string.");
+"A string is numeric if all characters in the string are numeric and\n"
+"there is at least one character in the string.");
#define UNICODE_ISNUMERIC_METHODDEF \
{"isnumeric", (PyCFunction)unicode_isnumeric, METH_NOARGS, unicode_isnumeric__doc__},
@@ -690,8 +692,8 @@ PyDoc_STRVAR(unicode_isidentifier__doc__,
"\n"
"Return True if the string is a valid Python identifier, False otherwise.\n"
"\n"
-"Call keyword.iskeyword(s) to test whether string s is a reserved identifier,\n"
-"such as \"def\" or \"class\".");
+"Call keyword.iskeyword(s) to test whether string s is a reserved\n"
+"identifier, such as \"def\" or \"class\".");
#define UNICODE_ISIDENTIFIER_METHODDEF \
{"isidentifier", (PyCFunction)unicode_isidentifier, METH_NOARGS, unicode_isidentifier__doc__},
@@ -731,8 +733,8 @@ PyDoc_STRVAR(unicode_join__doc__,
"\n"
"Concatenate any number of strings.\n"
"\n"
-"The string whose method is called is inserted in between each given string.\n"
-"The result is returned as a new string.\n"
+"The string whose method is called is inserted in between each given\n"
+"string. The result is returned as a new string.\n"
"\n"
"Example: \'.\'.join([\'ab\', \'pq\', \'rs\']) -> \'ab.pq.rs\'");
@@ -745,7 +747,8 @@ PyDoc_STRVAR(unicode_ljust__doc__,
"\n"
"Return a left-justified string of length width.\n"
"\n"
-"Padding is done using the specified fill character (default is a space).");
+"Padding is done using the specified fill character (default is\n"
+"a space).");
#define UNICODE_LJUST_METHODDEF \
{"ljust", _PyCFunction_CAST(unicode_ljust), METH_FASTCALL, unicode_ljust__doc__},
@@ -1008,8 +1011,9 @@ PyDoc_STRVAR(unicode_removeprefix__doc__,
"\n"
"Return a str with the given prefix string removed if present.\n"
"\n"
-"If the string starts with the prefix string, return string[len(prefix):].\n"
-"Otherwise, return a copy of the original string.");
+"If the string starts with the prefix string, return\n"
+"string[len(prefix):]. Otherwise, return a copy of the original\n"
+"string.");
#define UNICODE_REMOVEPREFIX_METHODDEF \
{"removeprefix", (PyCFunction)unicode_removeprefix, METH_O, unicode_removeprefix__doc__},
@@ -1040,9 +1044,9 @@ PyDoc_STRVAR(unicode_removesuffix__doc__,
"\n"
"Return a str with the given suffix string removed if present.\n"
"\n"
-"If the string ends with the suffix string and that suffix is not empty,\n"
-"return string[:-len(suffix)]. Otherwise, return a copy of the original\n"
-"string.");
+"If the string ends with the suffix string and that suffix is not\n"
+"empty, return string[:-len(suffix)]. Otherwise, return a copy of\n"
+"the original string.");
#define UNICODE_REMOVESUFFIX_METHODDEF \
{"removesuffix", (PyCFunction)unicode_removesuffix, METH_O, unicode_removesuffix__doc__},
@@ -1073,8 +1077,8 @@ PyDoc_STRVAR(unicode_rfind__doc__,
"\n"
"Return the highest index in S where substring sub is found, such that sub is contained within S[start:end].\n"
"\n"
-"Optional arguments start and end are interpreted as in slice notation.\n"
-"Return -1 on failure.");
+"Optional arguments start and end are interpreted as in slice\n"
+"notation. Return -1 on failure.");
#define UNICODE_RFIND_METHODDEF \
{"rfind", _PyCFunction_CAST(unicode_rfind), METH_FASTCALL, unicode_rfind__doc__},
@@ -1129,8 +1133,8 @@ PyDoc_STRVAR(unicode_rindex__doc__,
"\n"
"Return the highest index in S where substring sub is found, such that sub is contained within S[start:end].\n"
"\n"
-"Optional arguments start and end are interpreted as in slice notation.\n"
-"Raises ValueError when the substring is not found.");
+"Optional arguments start and end are interpreted as in slice\n"
+"notation. Raises ValueError when the substring is not found.");
#define UNICODE_RINDEX_METHODDEF \
{"rindex", _PyCFunction_CAST(unicode_rindex), METH_FASTCALL, unicode_rindex__doc__},
@@ -1185,7 +1189,8 @@ PyDoc_STRVAR(unicode_rjust__doc__,
"\n"
"Return a right-justified string of length width.\n"
"\n"
-"Padding is done using the specified fill character (default is a space).");
+"Padding is done using the specified fill character (default is\n"
+"a space).");
#define UNICODE_RJUST_METHODDEF \
{"rjust", _PyCFunction_CAST(unicode_rjust), METH_FASTCALL, unicode_rjust__doc__},
@@ -1237,18 +1242,18 @@ PyDoc_STRVAR(unicode_split__doc__,
" sep\n"
" The separator used to split the string.\n"
"\n"
-" When set to None (the default value), will split on any whitespace\n"
-" character (including \\n \\r \\t \\f and spaces) and will discard\n"
-" empty strings from the result.\n"
+" When set to None (the default value), will split on any\n"
+" whitespace character (including \\n \\r \\t \\f and spaces) and\n"
+" will discard empty strings from the result.\n"
" maxsplit\n"
" Maximum number of splits.\n"
" -1 (the default value) means no limit.\n"
"\n"
"Splitting starts at the front of the string and works to the end.\n"
"\n"
-"Note, str.split() is mainly useful for data that has been intentionally\n"
-"delimited. With natural text that includes punctuation, consider using\n"
-"the regular expression module.");
+"Note, str.split() is mainly useful for data that has been\n"
+"intentionally delimited. With natural text that includes\n"
+"punctuation, consider using the regular expression module.");
#define UNICODE_SPLIT_METHODDEF \
{"split", _PyCFunction_CAST(unicode_split), METH_FASTCALL|METH_KEYWORDS, unicode_split__doc__},
@@ -1331,12 +1336,12 @@ PyDoc_STRVAR(unicode_partition__doc__,
"\n"
"Partition the string into three parts using the given separator.\n"
"\n"
-"This will search for the separator in the string. If the separator is found,\n"
-"returns a 3-tuple containing the part before the separator, the separator\n"
-"itself, and the part after it.\n"
+"This will search for the separator in the string. If the separator\n"
+"is found, returns a 3-tuple containing the part before the\n"
+"separator, the separator itself, and the part after it.\n"
"\n"
-"If the separator is not found, returns a 3-tuple containing the original string\n"
-"and two empty strings.");
+"If the separator is not found, returns a 3-tuple containing\n"
+"the original string and two empty strings.");
#define UNICODE_PARTITION_METHODDEF \
{"partition", (PyCFunction)unicode_partition, METH_O, unicode_partition__doc__},
@@ -1347,12 +1352,13 @@ PyDoc_STRVAR(unicode_rpartition__doc__,
"\n"
"Partition the string into three parts using the given separator.\n"
"\n"
-"This will search for the separator in the string, starting at the end. If\n"
-"the separator is found, returns a 3-tuple containing the part before the\n"
-"separator, the separator itself, and the part after it.\n"
+"This will search for the separator in the string, starting at the\n"
+"end. If the separator is found, returns a 3-tuple containing the\n"
+"part before the separator, the separator itself, and the part after\n"
+"it.\n"
"\n"
-"If the separator is not found, returns a 3-tuple containing two empty strings\n"
-"and the original string.");
+"If the separator is not found, returns a 3-tuple containing two\n"
+"empty strings and the original string.");
#define UNICODE_RPARTITION_METHODDEF \
{"rpartition", (PyCFunction)unicode_rpartition, METH_O, unicode_rpartition__doc__},
@@ -1366,9 +1372,9 @@ PyDoc_STRVAR(unicode_rsplit__doc__,
" sep\n"
" The separator used to split the string.\n"
"\n"
-" When set to None (the default value), will split on any whitespace\n"
-" character (including \\n \\r \\t \\f and spaces) and will discard\n"
-" empty strings from the result.\n"
+" When set to None (the default value), will split on any\n"
+" whitespace character (including \\n \\r \\t \\f and spaces) and\n"
+" will discard empty strings from the result.\n"
" maxsplit\n"
" Maximum number of splits.\n"
" -1 (the default value) means no limit.\n"
@@ -1456,8 +1462,8 @@ PyDoc_STRVAR(unicode_splitlines__doc__,
"\n"
"Return a list of the lines in the string, breaking at line boundaries.\n"
"\n"
-"Line breaks are not included in the resulting list unless keepends is given and\n"
-"true.");
+"Line breaks are not included in the resulting list unless keepends\n"
+"is given and true.");
#define UNICODE_SPLITLINES_METHODDEF \
{"splitlines", _PyCFunction_CAST(unicode_splitlines), METH_FASTCALL|METH_KEYWORDS, unicode_splitlines__doc__},
@@ -1543,13 +1549,14 @@ PyDoc_STRVAR(unicode_maketrans__doc__,
"\n"
"Return a translation table usable for str.translate().\n"
"\n"
-"If there is only one argument, it must be a dictionary mapping Unicode\n"
-"ordinals (integers) or characters to Unicode ordinals, strings or None.\n"
-"Character keys will be then converted to ordinals.\n"
-"If there are two arguments, they must be strings of equal length, and\n"
-"in the resulting dictionary, each character in x will be mapped to the\n"
-"character at the same position in y. If there is a third argument, it\n"
-"must be a string, whose characters will be mapped to None in the result.");
+"If there is only one argument, it must be a dictionary mapping\n"
+"Unicode ordinals (integers) or characters to Unicode ordinals,\n"
+"strings or None. Character keys will be then converted to ordinals.\n"
+"If there are two arguments, they must be strings of equal length,\n"
+"and in the resulting dictionary, each character in x will be mapped\n"
+"to the character at the same position in y. If there is a third\n"
+"argument, it must be a string, whose characters will be mapped to\n"
+"None in the result.");
#define UNICODE_MAKETRANS_METHODDEF \
{"maketrans", _PyCFunction_CAST(unicode_maketrans), METH_FASTCALL|METH_STATIC, unicode_maketrans__doc__},
@@ -1599,12 +1606,13 @@ PyDoc_STRVAR(unicode_translate__doc__,
"Replace each character in the string using the given translation table.\n"
"\n"
" table\n"
-" Translation table, which must be a mapping of Unicode ordinals to\n"
-" Unicode ordinals, strings, or None.\n"
+" Translation table, which must be a mapping of Unicode ordinals\n"
+" to Unicode ordinals, strings, or None.\n"
"\n"
-"The table must implement lookup/indexing via __getitem__, for instance a\n"
-"dictionary or list. If this operation raises LookupError, the character is\n"
-"left untouched. Characters mapped to None are deleted.");
+"The table must implement lookup/indexing via __getitem__, for\n"
+"instance a dictionary or list. If this operation raises\n"
+"LookupError, the character is left untouched. Characters mapped to\n"
+"None are deleted.");
#define UNICODE_TRANSLATE_METHODDEF \
{"translate", (PyCFunction)unicode_translate, METH_O, unicode_translate__doc__},
@@ -1908,4 +1916,4 @@ unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=13eaf65699ea9fc9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=9d243c63e951e31d input=a9049054013a1b77]*/
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index 8be85b1accbdca..4ede8de6e8adc5 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -2840,12 +2840,13 @@ code._varname_from_oparg
(internal-only) Return the local variable name for the given oparg.
-WARNING: this method is for internal use only and may change or go away.
+WARNING: this method is for internal use only and may change or go
+away.
[clinic start generated code]*/
static PyObject *
code__varname_from_oparg_impl(PyCodeObject *self, int oparg)
-/*[clinic end generated code: output=1fd1130413184206 input=c5fa3ee9bac7d4ca]*/
+/*[clinic end generated code: output=1fd1130413184206 input=6ba7d6df0d566463]*/
{
PyObject *name = PyTuple_GetItem(self->co_localsplusnames, oparg);
if (name == NULL) {
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 3830fedd42bd27..66546b72130dd0 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -3892,6 +3892,7 @@ PyDict_Items(PyObject *dict)
}
/*[clinic input]
+@permit_long_summary
@classmethod
dict.fromkeys
iterable: object
@@ -3903,7 +3904,7 @@ Create a new dictionary with keys from iterable and values set to value.
static PyObject *
dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value)
-/*[clinic end generated code: output=8fb98e4b10384999 input=382ba4855d0f74c3]*/
+/*[clinic end generated code: output=8fb98e4b10384999 input=3903715eb48b287e]*/
{
return _PyDict_FromKeys((PyObject *)type, iterable, value);
}
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index d91468dddded9b..17e6a729dcd83f 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -1670,7 +1670,6 @@ float___getnewargs___impl(PyObject *self)
/*[clinic input]
-@permit_long_docstring_body
@classmethod
float.__getformat__
@@ -1683,13 +1682,13 @@ You probably don't want to use this function.
It exists mainly to be used in Python's test suite.
This function returns whichever of 'IEEE, big-endian' or 'IEEE,
-little-endian' best describes the format of floating-point numbers used by the
-C type named by typestr.
+little-endian' best describes the format of floating-point numbers
+used by the C type named by typestr.
[clinic start generated code]*/
static PyObject *
float___getformat___impl(PyTypeObject *type, const char *typestr)
-/*[clinic end generated code: output=2bfb987228cc9628 input=0ae1ba35d192f704]*/
+/*[clinic end generated code: output=2bfb987228cc9628 input=eb1cf45e9bddab72]*/
{
if (strcmp(typestr, "double") != 0 && strcmp(typestr, "float") != 0) {
PyErr_SetString(PyExc_ValueError,
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 5ae85c5bca61b9..f60cdb2dd1bf20 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -1890,6 +1890,7 @@ frame_trace_set_impl(PyFrameObject *self, PyObject *value)
}
/*[clinic input]
+@permit_long_summary
@critical_section
@getter
frame.f_generator as frame_generator
@@ -1899,7 +1900,7 @@ Return the generator or coroutine associated with this frame, or None.
static PyObject *
frame_generator_get_impl(PyFrameObject *self)
-/*[clinic end generated code: output=97aeb2392562e55b input=00a2bd008b239ab0]*/
+/*[clinic end generated code: output=97aeb2392562e55b input=3ffba57ba10f84be]*/
{
if (self->f_frame->owner == FRAME_OWNED_BY_GENERATOR) {
PyObject *gen = (PyObject *)_PyGen_GetGeneratorFromFrame(self->f_frame);
diff --git a/Objects/listobject.c b/Objects/listobject.c
index c76721c5d2ac9e..38dc38dd277b97 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -2922,7 +2922,6 @@ unsafe_tuple_compare(PyObject *v, PyObject *w, MergeState *ms)
* duplicated).
*/
/*[clinic input]
-@permit_long_docstring_body
@critical_section
list.sort
@@ -2932,18 +2931,18 @@ list.sort
Sort the list in ascending order and return None.
-The sort is in-place (i.e. the list itself is modified) and stable (i.e. the
-order of two equal elements is maintained).
+The sort is in-place (i.e. the list itself is modified) and stable
+(i.e. the order of two equal elements is maintained).
-If a key function is given, apply it once to each list item and sort them,
-ascending or descending, according to their function values.
+If a key function is given, apply it once to each list item and sort
+them, ascending or descending, according to their function values.
The reverse flag can be set to sort in descending order.
[clinic start generated code]*/
static PyObject *
list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
-/*[clinic end generated code: output=57b9f9c5e23fbe42 input=e4f6b6069181ad7d]*/
+/*[clinic end generated code: output=57b9f9c5e23fbe42 input=c145526281e1fb9f]*/
{
MergeState ms;
Py_ssize_t nremaining;
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 549cf0b8f12b4e..6e6011cb19aab5 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -6367,20 +6367,21 @@ int_as_integer_ratio_impl(PyObject *self)
int.to_bytes
length: Py_ssize_t(allow_negative=False) = 1
- Length of bytes object to use. An OverflowError is raised if the
- integer is not representable with the given number of bytes. Default
- is length 1.
+ Length of bytes object to use. An OverflowError is raised if
+ the integer is not representable with the given number of bytes.
+ Default is length 1.
byteorder: unicode(c_default="NULL") = "big"
- The byte order used to represent the integer. If byteorder is 'big',
- the most significant byte is at the beginning of the byte array. If
- byteorder is 'little', the most significant byte is at the end of the
- byte array. To request the native byte order of the host system, use
- sys.byteorder as the byte order value. Default is to use 'big'.
+ The byte order used to represent the integer. If byteorder is
+ 'big', the most significant byte is at the beginning of the byte
+ array. If byteorder is 'little', the most significant byte is at
+ the end of the byte array. To request the native byte order of
+ the host system, use sys.byteorder as the byte order value.
+ Default is to use 'big'.
*
signed as is_signed: bool = False
- Determines whether two's complement is used to represent the integer.
- If signed is False and a negative integer is given, an OverflowError
- is raised.
+ Determines whether two's complement is used to represent the
+ integer. If signed is False and a negative integer is given,
+ an OverflowError is raised.
Return an array of bytes representing an integer.
[clinic start generated code]*/
@@ -6388,7 +6389,7 @@ Return an array of bytes representing an integer.
static PyObject *
int_to_bytes_impl(PyObject *self, Py_ssize_t length, PyObject *byteorder,
int is_signed)
-/*[clinic end generated code: output=89c801df114050a3 input=66f9d0c20529b44f]*/
+/*[clinic end generated code: output=89c801df114050a3 input=c74a93c07b2f6526]*/
{
int little_endian;
if (byteorder == NULL)
@@ -6424,18 +6425,20 @@ int.from_bytes
bytes as bytes_obj: object
Holds the array of bytes to convert. The argument must either
- support the buffer protocol or be an iterable object producing bytes.
- Bytes and bytearray are examples of built-in objects that support the
- buffer protocol.
+ support the buffer protocol or be an iterable object producing
+ bytes. Bytes and bytearray are examples of built-in objects that
+ support the buffer protocol.
byteorder: unicode(c_default="NULL") = "big"
- The byte order used to represent the integer. If byteorder is 'big',
- the most significant byte is at the beginning of the byte array. If
- byteorder is 'little', the most significant byte is at the end of the
- byte array. To request the native byte order of the host system, use
- sys.byteorder as the byte order value. Default is to use 'big'.
+ The byte order used to represent the integer. If byteorder is
+ 'big', the most significant byte is at the beginning of the byte
+ array. If byteorder is 'little', the most significant byte is at
+ the end of the byte array. To request the native byte order of
+ the host system, use sys.byteorder as the byte order value.
+ Default is to use 'big'.
*
signed as is_signed: bool = False
- Indicates whether two's complement is used to represent the integer.
+ Indicates whether two's complement is used to represent the
+ integer.
Return the integer represented by the given array of bytes.
[clinic start generated code]*/
@@ -6443,7 +6446,7 @@ Return the integer represented by the given array of bytes.
static PyObject *
int_from_bytes_impl(PyTypeObject *type, PyObject *bytes_obj,
PyObject *byteorder, int is_signed)
-/*[clinic end generated code: output=efc5d68e31f9314f input=2ff527997fe7b0c5]*/
+/*[clinic end generated code: output=efc5d68e31f9314f input=95801e50b942e164]*/
{
int little_endian;
PyObject *long_obj, *bytes;
@@ -6508,6 +6511,7 @@ long_long_getter(PyObject *self, void *Py_UNUSED(ignored))
}
/*[clinic input]
+@permit_long_summary
int.is_integer
Returns True. Exists for duck type compatibility with float.is_integer.
@@ -6515,7 +6519,7 @@ Returns True. Exists for duck type compatibility with float.is_integer.
static PyObject *
int_is_integer_impl(PyObject *self)
-/*[clinic end generated code: output=90f8e794ce5430ef input=7e41c4d4416e05f2]*/
+/*[clinic end generated code: output=90f8e794ce5430ef input=aacf01a2c81c0244]*/
{
Py_RETURN_TRUE;
}
@@ -6597,7 +6601,8 @@ If x is not a number or if base is given, then x must be a string,\n\
bytes, or bytearray instance representing an integer literal in the\n\
given base. The literal can be preceded by '+' or '-' and be surrounded\n\
by whitespace. The base defaults to 10. Valid bases are 0 and 2-36.\n\
-Base 0 means to interpret the base from the string as an integer literal.\n\
+Base 0 means to interpret the base from the string as an integer\n\
+iteral.\n\
>>> int('0b100', base=0)\n\
4");
diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c
index 9d1ca633780f92..3cfee04d80bb74 100644
--- a/Objects/memoryobject.c
+++ b/Objects/memoryobject.c
@@ -2339,23 +2339,23 @@ memoryview_tolist_impl(PyMemoryViewObject *self)
}
/*[clinic input]
-@permit_long_docstring_body
memoryview.tobytes
order: str(accept={str, NoneType}, c_default="NULL") = 'C'
Return the data in the buffer as a byte string.
-Order can be {'C', 'F', 'A'}. When order is 'C' or 'F', the data of the
-original array is converted to C or Fortran order. For contiguous views,
-'A' returns an exact copy of the physical memory. In particular, in-memory
-Fortran order is preserved. For non-contiguous views, the data is converted
-to C first. order=None is the same as order='C'.
+Order can be {'C', 'F', 'A'}. When order is 'C' or 'F', the data of
+the original array is converted to C or Fortran order. For
+contiguous views, 'A' returns an exact copy of the physical memory.
+In particular, in-memory Fortran order is preserved. For
+non-contiguous views, the data is converted to C first. order=None
+is the same as order='C'.
[clinic start generated code]*/
static PyObject *
memoryview_tobytes_impl(PyMemoryViewObject *self, const char *order)
-/*[clinic end generated code: output=1288b62560a32a23 input=23c9faf372cfdbcc]*/
+/*[clinic end generated code: output=1288b62560a32a23 input=119c70aa91791dc8]*/
{
Py_buffer *src = VIEW_ADDR(self);
char ord = 'C';
@@ -2396,8 +2396,8 @@ memoryview.hex
sep: object = NULL
An optional single character or byte to separate hex bytes.
bytes_per_sep: Py_ssize_t = 1
- How many bytes between separators. Positive values count from the
- right, negative values count from the left.
+ How many bytes between separators. Positive values count from
+ the right, negative values count from the left.
Return the data in the buffer as a str of hexadecimal numbers.
@@ -2416,7 +2416,7 @@ Return the data in the buffer as a str of hexadecimal numbers.
static PyObject *
memoryview_hex_impl(PyMemoryViewObject *self, PyObject *sep,
Py_ssize_t bytes_per_sep)
-/*[clinic end generated code: output=c9bb00c7a8e86056 input=dc48a56ed3b058ae]*/
+/*[clinic end generated code: output=c9bb00c7a8e86056 input=3f1c5d08906e3b70]*/
{
Py_buffer *src = VIEW_ADDR(self);
diff --git a/Objects/odictobject.c b/Objects/odictobject.c
index b391283e83795d..6f05395b18d781 100644
--- a/Objects/odictobject.c
+++ b/Objects/odictobject.c
@@ -1149,12 +1149,13 @@ OrderedDict.popitem
Remove and return a (key, value) pair from the dictionary.
-Pairs are returned in LIFO order if last is true or FIFO order if false.
+Pairs are returned in LIFO order if last is true or FIFO order if
+false.
[clinic start generated code]*/
static PyObject *
OrderedDict_popitem_impl(PyODictObject *self, int last)
-/*[clinic end generated code: output=98e7d986690d49eb input=8aafc7433e0a40e7]*/
+/*[clinic end generated code: output=98e7d986690d49eb input=ebf1cc91579c9e54]*/
{
PyObject *key, *value;
_ODictNode *node;
diff --git a/Objects/setobject.c b/Objects/setobject.c
index 1e630563604552..642baef3544d36 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -2111,6 +2111,7 @@ set_difference(PySetObject *so, PyObject *other)
}
/*[clinic input]
+@permit_long_summary
set.difference as set_difference_multi
so: setobject
*others: array
@@ -2121,7 +2122,7 @@ Return a new set with elements in the set that are not in the others.
static PyObject *
set_difference_multi_impl(PySetObject *so, PyObject * const *others,
Py_ssize_t others_length)
-/*[clinic end generated code: output=b0d33fb05d5477a7 input=c1eb448d483416ad]*/
+/*[clinic end generated code: output=b0d33fb05d5477a7 input=e0fbedbf79d91d4e]*/
{
Py_ssize_t i;
PyObject *result, *other;
@@ -2293,6 +2294,7 @@ set_symmetric_difference_update_impl(PySetObject *so, PyObject *other)
}
/*[clinic input]
+@permit_long_summary
@critical_section so other
set.symmetric_difference
so: setobject
@@ -2304,7 +2306,7 @@ Return a new set with elements in either the set or other but not both.
static PyObject *
set_symmetric_difference_impl(PySetObject *so, PyObject *other)
-/*[clinic end generated code: output=270ee0b5d42b0797 input=624f6e7bbdf70db1]*/
+/*[clinic end generated code: output=270ee0b5d42b0797 input=8c29b0be90d47feb]*/
{
PySetObject *result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
if (result == NULL) {
diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c
index 95f10815687757..dbb509b06ecbba 100644
--- a/Objects/sliceobject.c
+++ b/Objects/sliceobject.c
@@ -342,7 +342,9 @@ PyDoc_STRVAR(slice_doc,
"slice(stop)\n\
slice(start, stop[, step])\n\
\n\
-Create a slice object. This is used for extended slicing (e.g. a[0:10:2]).");
+Create a slice object.\n\
+\n\
+This is used for extended slicing (e.g. a[0:10:2]).");
static void
slice_dealloc(PyObject *op)
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index fc679ef747e856..e0464fe6475cfd 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -12941,7 +12941,8 @@ PyDoc_STRVAR(super_doc,
"super() -> same as super(__class__, )\n"
"super(type) -> unbound super object\n"
"super(type, obj) -> bound super object; requires isinstance(obj, type)\n"
-"super(type, type2) -> bound super object; requires issubclass(type2, type)\n"
+"super(type, type2) -> bound super object; requires\n"
+" issubclass(type2, type)\n"
"Typical use to call a cooperative superclass method:\n"
"class C(B):\n"
" def meth(self, arg):\n"
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 9aee7120c811de..74d6ba4db9f2b8 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -10794,35 +10794,33 @@ replace(PyObject *self, PyObject *str1,
/* --- Unicode Object Methods --------------------------------------------- */
/*[clinic input]
-@permit_long_docstring_body
str.title as unicode_title
Return a version of the string where each word is titlecased.
-More specifically, words start with uppercased characters and all remaining
-cased characters have lower case.
+More specifically, words start with uppercased characters and all
+remaining cased characters have lower case.
[clinic start generated code]*/
static PyObject *
unicode_title_impl(PyObject *self)
-/*[clinic end generated code: output=c75ae03809574902 input=533ce0eb6a7f5d1b]*/
+/*[clinic end generated code: output=c75ae03809574902 input=2a07e2c7df94627a]*/
{
return case_operation(self, do_title);
}
/*[clinic input]
-@permit_long_docstring_body
str.capitalize as unicode_capitalize
Return a capitalized version of the string.
-More specifically, make the first character have upper case and the rest lower
-case.
+More specifically, make the first character have upper case and the
+rest lower case.
[clinic start generated code]*/
static PyObject *
unicode_capitalize_impl(PyObject *self)
-/*[clinic end generated code: output=e49a4c333cdb7667 input=a4a15ade41f6f9e9]*/
+/*[clinic end generated code: output=e49a4c333cdb7667 input=e50e50ed45a654cf]*/
{
if (PyUnicode_GET_LENGTH(self) == 0)
return unicode_result_unchanged(self);
@@ -10876,12 +10874,13 @@ str.center as unicode_center
Return a centered string of length width.
-Padding is done using the specified fill character (default is a space).
+Padding is done using the specified fill character (default is
+a space).
[clinic start generated code]*/
static PyObject *
unicode_center_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar)
-/*[clinic end generated code: output=420c8859effc7c0c input=b42b247eb26e6519]*/
+/*[clinic end generated code: output=420c8859effc7c0c input=df91017dfd186a78]*/
{
Py_ssize_t marg, left;
@@ -11441,13 +11440,14 @@ str.count as unicode_count -> Py_ssize_t
Return the number of non-overlapping occurrences of substring sub in string S[start:end].
-Optional arguments start and end are interpreted as in slice notation.
+Optional arguments start and end are interpreted as in slice
+notation.
[clinic start generated code]*/
static Py_ssize_t
unicode_count_impl(PyObject *str, PyObject *substr, Py_ssize_t start,
Py_ssize_t end)
-/*[clinic end generated code: output=8fcc3aef0b18edbf input=8590716ee228b935]*/
+/*[clinic end generated code: output=8fcc3aef0b18edbf input=c9209e05438cc352]*/
{
assert(PyUnicode_Check(str));
assert(PyUnicode_Check(substr));
@@ -11520,8 +11520,8 @@ str.encode as unicode_encode
errors: str(c_default="NULL") = 'strict'
The error handling scheme to use for encoding errors.
The default is 'strict' meaning that encoding errors raise a
- UnicodeEncodeError. Other possible values are 'ignore', 'replace' and
- 'xmlcharrefreplace' as well as any other name registered with
+ UnicodeEncodeError. Other possible values are 'ignore', 'replace'
+ and 'xmlcharrefreplace' as well as any other name registered with
codecs.register_error that can handle UnicodeEncodeErrors.
Encode the string using the codec registered for encoding.
@@ -11529,7 +11529,7 @@ Encode the string using the codec registered for encoding.
static PyObject *
unicode_encode_impl(PyObject *self, const char *encoding, const char *errors)
-/*[clinic end generated code: output=bf78b6e2a9470e3c input=f0a9eb293d08fe02]*/
+/*[clinic end generated code: output=bf78b6e2a9470e3c input=b85a9645cb33b729]*/
{
return PyUnicode_AsEncodedString(self, encoding, errors);
}
@@ -11626,14 +11626,14 @@ str.find as unicode_find = str.count
Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end].
-Optional arguments start and end are interpreted as in slice notation.
-Return -1 on failure.
+Optional arguments start and end are interpreted as in slice
+notation. Return -1 on failure.
[clinic start generated code]*/
static Py_ssize_t
unicode_find_impl(PyObject *str, PyObject *substr, Py_ssize_t start,
Py_ssize_t end)
-/*[clinic end generated code: output=51dbe6255712e278 input=3a9d650fe4c24695]*/
+/*[clinic end generated code: output=51dbe6255712e278 input=f57e93c59d1ee927]*/
{
Py_ssize_t result = any_find_slice(str, substr, start, end, 1);
if (result < 0) {
@@ -11690,14 +11690,14 @@ str.index as unicode_index = str.count
Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end].
-Optional arguments start and end are interpreted as in slice notation.
-Raises ValueError when the substring is not found.
+Optional arguments start and end are interpreted as in slice
+notation. Raises ValueError when the substring is not found.
[clinic start generated code]*/
static Py_ssize_t
unicode_index_impl(PyObject *str, PyObject *substr, Py_ssize_t start,
Py_ssize_t end)
-/*[clinic end generated code: output=77558288837cdf40 input=ae5e48f69ed75b06]*/
+/*[clinic end generated code: output=77558288837cdf40 input=5900ab84de55e628]*/
{
Py_ssize_t result = any_find_slice(str, substr, start, end, 1);
if (result == -1) {
@@ -11710,6 +11710,7 @@ unicode_index_impl(PyObject *str, PyObject *substr, Py_ssize_t start,
}
/*[clinic input]
+@permit_long_summary
str.isascii as unicode_isascii
Return True if all characters in the string are ASCII, False otherwise.
@@ -11720,24 +11721,23 @@ Empty string is ASCII too.
static PyObject *
unicode_isascii_impl(PyObject *self)
-/*[clinic end generated code: output=c5910d64b5a8003f input=5a43cbc6399621d5]*/
+/*[clinic end generated code: output=c5910d64b5a8003f input=dc74e1ced821159f]*/
{
return PyBool_FromLong(PyUnicode_IS_ASCII(self));
}
/*[clinic input]
-@permit_long_docstring_body
str.islower as unicode_islower
Return True if the string is a lowercase string, False otherwise.
-A string is lowercase if all cased characters in the string are lowercase and
-there is at least one cased character in the string.
+A string is lowercase if all cased characters in the string are
+lowercase and there is at least one cased character in the string.
[clinic start generated code]*/
static PyObject *
unicode_islower_impl(PyObject *self)
-/*[clinic end generated code: output=dbd41995bd005b81 input=c6fc0295241a1aaa]*/
+/*[clinic end generated code: output=dbd41995bd005b81 input=1879b48dfc628366]*/
{
Py_ssize_t i, length;
int kind;
@@ -11770,18 +11770,17 @@ unicode_islower_impl(PyObject *self)
}
/*[clinic input]
-@permit_long_docstring_body
str.isupper as unicode_isupper
Return True if the string is an uppercase string, False otherwise.
-A string is uppercase if all cased characters in the string are uppercase and
-there is at least one cased character in the string.
+A string is uppercase if all cased characters in the string are
+uppercase and there is at least one cased character in the string.
[clinic start generated code]*/
static PyObject *
unicode_isupper_impl(PyObject *self)
-/*[clinic end generated code: output=049209c8e7f15f59 input=8d5cb33e67efde72]*/
+/*[clinic end generated code: output=049209c8e7f15f59 input=77d29904aef0e3a0]*/
{
Py_ssize_t i, length;
int kind;
@@ -11870,18 +11869,17 @@ unicode_istitle_impl(PyObject *self)
}
/*[clinic input]
-@permit_long_docstring_body
str.isspace as unicode_isspace
Return True if the string is a whitespace string, False otherwise.
-A string is whitespace if all characters in the string are whitespace and there
-is at least one character in the string.
+A string is whitespace if all characters in the string are
+whitespace and there is at least one character in the string.
[clinic start generated code]*/
static PyObject *
unicode_isspace_impl(PyObject *self)
-/*[clinic end generated code: output=163a63bfa08ac2b9 input=44fe05e248c6e159]*/
+/*[clinic end generated code: output=163a63bfa08ac2b9 input=29e09560fc23fbeb]*/
{
Py_ssize_t i, length;
int kind;
@@ -11909,18 +11907,17 @@ unicode_isspace_impl(PyObject *self)
}
/*[clinic input]
-@permit_long_docstring_body
str.isalpha as unicode_isalpha
Return True if the string is an alphabetic string, False otherwise.
-A string is alphabetic if all characters in the string are alphabetic and there
-is at least one character in the string.
+A string is alphabetic if all characters in the string are
+alphabetic and there is at least one character in the string.
[clinic start generated code]*/
static PyObject *
unicode_isalpha_impl(PyObject *self)
-/*[clinic end generated code: output=cc81b9ac3883ec4f input=c233000624a56e0d]*/
+/*[clinic end generated code: output=cc81b9ac3883ec4f input=9906a07f3e04892e]*/
{
Py_ssize_t i, length;
int kind;
@@ -11947,18 +11944,18 @@ unicode_isalpha_impl(PyObject *self)
}
/*[clinic input]
-@permit_long_docstring_body
+@permit_long_summary
str.isalnum as unicode_isalnum
Return True if the string is an alpha-numeric string, False otherwise.
-A string is alpha-numeric if all characters in the string are alpha-numeric and
-there is at least one character in the string.
+A string is alpha-numeric if all characters in the string are
+alpha-numeric and there is at least one character in the string.
[clinic start generated code]*/
static PyObject *
unicode_isalnum_impl(PyObject *self)
-/*[clinic end generated code: output=a5a23490ffc3660c input=5d63ba9c9bafdb6b]*/
+/*[clinic end generated code: output=a5a23490ffc3660c input=892f64ebc171fd4f]*/
{
int kind;
const void *data;
@@ -11987,18 +11984,17 @@ unicode_isalnum_impl(PyObject *self)
}
/*[clinic input]
-@permit_long_docstring_body
str.isdecimal as unicode_isdecimal
Return True if the string is a decimal string, False otherwise.
-A string is a decimal string if all characters in the string are decimal and
-there is at least one character in the string.
+A string is a decimal string if all characters in the string are
+decimal and there is at least one character in the string.
[clinic start generated code]*/
static PyObject *
unicode_isdecimal_impl(PyObject *self)
-/*[clinic end generated code: output=fb2dcdb62d3fc548 input=8e84a58b414935a3]*/
+/*[clinic end generated code: output=fb2dcdb62d3fc548 input=63b0453c48cad0af]*/
{
Py_ssize_t i, length;
int kind;
@@ -12025,18 +12021,17 @@ unicode_isdecimal_impl(PyObject *self)
}
/*[clinic input]
-@permit_long_docstring_body
str.isdigit as unicode_isdigit
Return True if the string is a digit string, False otherwise.
-A string is a digit string if all characters in the string are digits and there
-is at least one character in the string.
+A string is a digit string if all characters in the string are
+digits and there is at least one character in the string.
[clinic start generated code]*/
static PyObject *
unicode_isdigit_impl(PyObject *self)
-/*[clinic end generated code: output=10a6985311da6858 input=99e284affb54d4a0]*/
+/*[clinic end generated code: output=10a6985311da6858 input=353b03747b062e4b]*/
{
Py_ssize_t i, length;
int kind;
@@ -12064,18 +12059,17 @@ unicode_isdigit_impl(PyObject *self)
}
/*[clinic input]
-@permit_long_docstring_body
str.isnumeric as unicode_isnumeric
Return True if the string is a numeric string, False otherwise.
-A string is numeric if all characters in the string are numeric and there is at
-least one character in the string.
+A string is numeric if all characters in the string are numeric and
+there is at least one character in the string.
[clinic start generated code]*/
static PyObject *
unicode_isnumeric_impl(PyObject *self)
-/*[clinic end generated code: output=9172a32d9013051a input=e9f5b6b8b29b0ee6]*/
+/*[clinic end generated code: output=9172a32d9013051a input=83b2a072ed7aff48]*/
{
Py_ssize_t i, length;
int kind;
@@ -12145,18 +12139,18 @@ PyUnicode_IsIdentifier(PyObject *self)
}
/*[clinic input]
-@permit_long_docstring_body
+@permit_long_summary
str.isidentifier as unicode_isidentifier
Return True if the string is a valid Python identifier, False otherwise.
-Call keyword.iskeyword(s) to test whether string s is a reserved identifier,
-such as "def" or "class".
+Call keyword.iskeyword(s) to test whether string s is a reserved
+identifier, such as "def" or "class".
[clinic start generated code]*/
static PyObject *
unicode_isidentifier_impl(PyObject *self)
-/*[clinic end generated code: output=fe585a9666572905 input=86315dd889d7bd04]*/
+/*[clinic end generated code: output=fe585a9666572905 input=cabde62c20a3be6b]*/
{
return PyBool_FromLong(PyUnicode_IsIdentifier(self));
}
@@ -12196,7 +12190,6 @@ unicode_isprintable_impl(PyObject *self)
}
/*[clinic input]
-@permit_long_docstring_body
str.join as unicode_join
iterable: object
@@ -12204,15 +12197,15 @@ str.join as unicode_join
Concatenate any number of strings.
-The string whose method is called is inserted in between each given string.
-The result is returned as a new string.
+The string whose method is called is inserted in between each given
+string. The result is returned as a new string.
Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'
[clinic start generated code]*/
static PyObject *
unicode_join(PyObject *self, PyObject *iterable)
-/*[clinic end generated code: output=6857e7cecfe7bf98 input=bac724ed412ef3f8]*/
+/*[clinic end generated code: output=6857e7cecfe7bf98 input=fd330a11ee845fb2]*/
{
return PyUnicode_Join(self, iterable);
}
@@ -12232,12 +12225,13 @@ str.ljust as unicode_ljust
Return a left-justified string of length width.
-Padding is done using the specified fill character (default is a space).
+Padding is done using the specified fill character (default is
+a space).
[clinic start generated code]*/
static PyObject *
unicode_ljust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar)
-/*[clinic end generated code: output=1cce0e0e0a0b84b3 input=3ab599e335e60a32]*/
+/*[clinic end generated code: output=1cce0e0e0a0b84b3 input=8a55f06694c20ed6]*/
{
if (PyUnicode_GET_LENGTH(self) >= width)
return unicode_result_unchanged(self);
@@ -12593,7 +12587,6 @@ unicode_replace_impl(PyObject *self, PyObject *old, PyObject *new,
}
/*[clinic input]
-@permit_long_docstring_body
str.removeprefix as unicode_removeprefix
prefix: unicode
@@ -12601,13 +12594,14 @@ str.removeprefix as unicode_removeprefix
Return a str with the given prefix string removed if present.
-If the string starts with the prefix string, return string[len(prefix):].
-Otherwise, return a copy of the original string.
+If the string starts with the prefix string, return
+string[len(prefix):]. Otherwise, return a copy of the original
+string.
[clinic start generated code]*/
static PyObject *
unicode_removeprefix_impl(PyObject *self, PyObject *prefix)
-/*[clinic end generated code: output=f1e5945e9763bcb9 input=1989a856dbb813f1]*/
+/*[clinic end generated code: output=f1e5945e9763bcb9 input=90d162724944bfa7]*/
{
int match = tailmatch(self, prefix, 0, PY_SSIZE_T_MAX, -1);
if (match == -1) {
@@ -12628,14 +12622,14 @@ str.removesuffix as unicode_removesuffix
Return a str with the given suffix string removed if present.
-If the string ends with the suffix string and that suffix is not empty,
-return string[:-len(suffix)]. Otherwise, return a copy of the original
-string.
+If the string ends with the suffix string and that suffix is not
+empty, return string[:-len(suffix)]. Otherwise, return a copy of
+the original string.
[clinic start generated code]*/
static PyObject *
unicode_removesuffix_impl(PyObject *self, PyObject *suffix)
-/*[clinic end generated code: output=d36629e227636822 input=12cc32561e769be4]*/
+/*[clinic end generated code: output=d36629e227636822 input=6efc96152d4bfcd5]*/
{
int match = tailmatch(self, suffix, 0, PY_SSIZE_T_MAX, +1);
if (match == -1) {
@@ -12745,14 +12739,14 @@ str.rfind as unicode_rfind = str.count
Return the highest index in S where substring sub is found, such that sub is contained within S[start:end].
-Optional arguments start and end are interpreted as in slice notation.
-Return -1 on failure.
+Optional arguments start and end are interpreted as in slice
+notation. Return -1 on failure.
[clinic start generated code]*/
static Py_ssize_t
unicode_rfind_impl(PyObject *str, PyObject *substr, Py_ssize_t start,
Py_ssize_t end)
-/*[clinic end generated code: output=880b29f01dd014c8 input=7f7e97d5cd3299a2]*/
+/*[clinic end generated code: output=880b29f01dd014c8 input=2e67789533baf2f5]*/
{
Py_ssize_t result = any_find_slice(str, substr, start, end, -1);
if (result < 0) {
@@ -12767,14 +12761,14 @@ str.rindex as unicode_rindex = str.count
Return the highest index in S where substring sub is found, such that sub is contained within S[start:end].
-Optional arguments start and end are interpreted as in slice notation.
-Raises ValueError when the substring is not found.
+Optional arguments start and end are interpreted as in slice
+notation. Raises ValueError when the substring is not found.
[clinic start generated code]*/
static Py_ssize_t
unicode_rindex_impl(PyObject *str, PyObject *substr, Py_ssize_t start,
Py_ssize_t end)
-/*[clinic end generated code: output=5f3aef124c867fe1 input=0363a324740b3e62]*/
+/*[clinic end generated code: output=5f3aef124c867fe1 input=e29d446c8234c9d9]*/
{
Py_ssize_t result = any_find_slice(str, substr, start, end, -1);
if (result == -1) {
@@ -12795,12 +12789,13 @@ str.rjust as unicode_rjust
Return a right-justified string of length width.
-Padding is done using the specified fill character (default is a space).
+Padding is done using the specified fill character (default is
+a space).
[clinic start generated code]*/
static PyObject *
unicode_rjust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar)
-/*[clinic end generated code: output=804a1a57fbe8d5cf input=d05f550b5beb1f72]*/
+/*[clinic end generated code: output=804a1a57fbe8d5cf input=1256a8d659589907]*/
{
if (PyUnicode_GET_LENGTH(self) >= width)
return unicode_result_unchanged(self);
@@ -12824,9 +12819,9 @@ str.split as unicode_split
sep: object = None
The separator used to split the string.
- When set to None (the default value), will split on any whitespace
- character (including \n \r \t \f and spaces) and will discard
- empty strings from the result.
+ When set to None (the default value), will split on any
+ whitespace character (including \n \r \t \f and spaces) and
+ will discard empty strings from the result.
maxsplit: Py_ssize_t = -1
Maximum number of splits.
-1 (the default value) means no limit.
@@ -12835,15 +12830,15 @@ Return a list of the substrings in the string, using sep as the separator string
Splitting starts at the front of the string and works to the end.
-Note, str.split() is mainly useful for data that has been intentionally
-delimited. With natural text that includes punctuation, consider using
-the regular expression module.
+Note, str.split() is mainly useful for data that has been
+intentionally delimited. With natural text that includes
+punctuation, consider using the regular expression module.
[clinic start generated code]*/
static PyObject *
unicode_split_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit)
-/*[clinic end generated code: output=3a65b1db356948dc input=2c1fd08a78e038b8]*/
+/*[clinic end generated code: output=3a65b1db356948dc input=288cfd6bc8828f5a]*/
{
if (sep == Py_None)
return split(self, NULL, maxsplit);
@@ -12960,7 +12955,6 @@ PyUnicode_RPartition(PyObject *str_obj, PyObject *sep_obj)
}
/*[clinic input]
-@permit_long_docstring_body
str.partition as unicode_partition
sep: object
@@ -12968,38 +12962,38 @@ str.partition as unicode_partition
Partition the string into three parts using the given separator.
-This will search for the separator in the string. If the separator is found,
-returns a 3-tuple containing the part before the separator, the separator
-itself, and the part after it.
+This will search for the separator in the string. If the separator
+is found, returns a 3-tuple containing the part before the
+separator, the separator itself, and the part after it.
-If the separator is not found, returns a 3-tuple containing the original string
-and two empty strings.
+If the separator is not found, returns a 3-tuple containing
+the original string and two empty strings.
[clinic start generated code]*/
static PyObject *
unicode_partition(PyObject *self, PyObject *sep)
-/*[clinic end generated code: output=e4ced7bd253ca3c4 input=4d854b520d7b0e97]*/
+/*[clinic end generated code: output=e4ced7bd253ca3c4 input=e45faa8c26270cb1]*/
{
return PyUnicode_Partition(self, sep);
}
/*[clinic input]
-@permit_long_docstring_body
str.rpartition as unicode_rpartition = str.partition
Partition the string into three parts using the given separator.
-This will search for the separator in the string, starting at the end. If
-the separator is found, returns a 3-tuple containing the part before the
-separator, the separator itself, and the part after it.
+This will search for the separator in the string, starting at the
+end. If the separator is found, returns a 3-tuple containing the
+part before the separator, the separator itself, and the part after
+it.
-If the separator is not found, returns a 3-tuple containing two empty strings
-and the original string.
+If the separator is not found, returns a 3-tuple containing two
+empty strings and the original string.
[clinic start generated code]*/
static PyObject *
unicode_rpartition(PyObject *self, PyObject *sep)
-/*[clinic end generated code: output=1aa13cf1156572aa input=a6adabe91e75b486]*/
+/*[clinic end generated code: output=1aa13cf1156572aa input=53a7f8cb19975b7c]*/
{
return PyUnicode_RPartition(self, sep);
}
@@ -13038,20 +13032,20 @@ unicode_rsplit_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit)
}
/*[clinic input]
-@permit_long_docstring_body
+@permit_long_summary
str.splitlines as unicode_splitlines
keepends: bool = False
Return a list of the lines in the string, breaking at line boundaries.
-Line breaks are not included in the resulting list unless keepends is given and
-true.
+Line breaks are not included in the resulting list unless keepends
+is given and true.
[clinic start generated code]*/
static PyObject *
unicode_splitlines_impl(PyObject *self, int keepends)
-/*[clinic end generated code: output=f664dcdad153ec40 input=39eeafbfef61c827]*/
+/*[clinic end generated code: output=f664dcdad153ec40 input=b45ea0f87645a06d]*/
{
return PyUnicode_Splitlines(self, keepends);
}
@@ -13130,18 +13124,19 @@ str.maketrans as unicode_maketrans
Return a translation table usable for str.translate().
-If there is only one argument, it must be a dictionary mapping Unicode
-ordinals (integers) or characters to Unicode ordinals, strings or None.
-Character keys will be then converted to ordinals.
-If there are two arguments, they must be strings of equal length, and
-in the resulting dictionary, each character in x will be mapped to the
-character at the same position in y. If there is a third argument, it
-must be a string, whose characters will be mapped to None in the result.
+If there is only one argument, it must be a dictionary mapping
+Unicode ordinals (integers) or characters to Unicode ordinals,
+strings or None. Character keys will be then converted to ordinals.
+If there are two arguments, they must be strings of equal length,
+and in the resulting dictionary, each character in x will be mapped
+to the character at the same position in y. If there is a third
+argument, it must be a string, whose characters will be mapped to
+None in the result.
[clinic start generated code]*/
static PyObject *
unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z)
-/*[clinic end generated code: output=a925c89452bd5881 input=7bfbf529a293c6c5]*/
+/*[clinic end generated code: output=a925c89452bd5881 input=66bc00a1b4258a6e]*/
{
PyObject *new = NULL, *key, *value;
Py_ssize_t i = 0;
@@ -13221,24 +13216,25 @@ unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z)
}
/*[clinic input]
-@permit_long_docstring_body
+@permit_long_summary
str.translate as unicode_translate
table: object
- Translation table, which must be a mapping of Unicode ordinals to
- Unicode ordinals, strings, or None.
+ Translation table, which must be a mapping of Unicode ordinals
+ to Unicode ordinals, strings, or None.
/
Replace each character in the string using the given translation table.
-The table must implement lookup/indexing via __getitem__, for instance a
-dictionary or list. If this operation raises LookupError, the character is
-left untouched. Characters mapped to None are deleted.
+The table must implement lookup/indexing via __getitem__, for
+instance a dictionary or list. If this operation raises
+LookupError, the character is left untouched. Characters mapped to
+None are deleted.
[clinic start generated code]*/
static PyObject *
unicode_translate(PyObject *self, PyObject *table)
-/*[clinic end generated code: output=3cb448ff2fd96bf3 input=699e5fa0ebf9f5e9]*/
+/*[clinic end generated code: output=3cb448ff2fd96bf3 input=48cf0efe06bc1b75]*/
{
return _PyUnicode_TranslateCharmap(self, table, "ignore");
}
@@ -13434,6 +13430,7 @@ Return a formatted version of the string, using substitutions from mapping.\n\
The substitutions are identified by braces ('{' and '}').");
/*[clinic input]
+@permit_long_summary
str.__format__ as unicode___format__
format_spec: unicode
@@ -13444,7 +13441,7 @@ Return a formatted version of the string as described by format_spec.
static PyObject *
unicode___format___impl(PyObject *self, PyObject *format_spec)
-/*[clinic end generated code: output=45fceaca6d2ba4c8 input=5e135645d167a214]*/
+/*[clinic end generated code: output=45fceaca6d2ba4c8 input=77a2a19f3f7969f2]*/
{
_PyUnicodeWriter writer;
int ret;
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 35b30a243318cc..d5129bf6a5a6bc 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -252,7 +252,6 @@ PyDoc_STRVAR(build_class_doc,
Internal helper function used by the class statement.");
/*[clinic input]
-@permit_long_docstring_body
__import__ as builtin___import__
name: object
@@ -273,15 +272,16 @@ should be a list of names to emulate ``from name import ...``, or an
empty list to emulate ``import name``.
When importing a module from a package, note that __import__('A.B', ...)
returns package A when fromlist is empty, but its submodule B when
-fromlist is not empty. The level argument is used to determine whether to
-perform absolute or relative imports: 0 is absolute, while a positive number
-is the number of parent directories to search relative to the current module.
+fromlist is not empty. The level argument is used to determine whether
+to perform absolute or relative imports: 0 is absolute, while a positive
+number is the number of parent directories to search relative to the
+current module.
[clinic start generated code]*/
static PyObject *
builtin___import___impl(PyObject *module, PyObject *name, PyObject *globals,
PyObject *locals, PyObject *fromlist, int level)
-/*[clinic end generated code: output=4febeda88a0cd245 input=01a3283590eae93a]*/
+/*[clinic end generated code: output=4febeda88a0cd245 input=e3096a230383f72d]*/
{
return PyImport_ImportModuleLevelObject(name, globals, locals,
fromlist, level);
@@ -299,15 +299,15 @@ __lazy_import__ as builtin___lazy_import__
Lazily imports a module.
-Returns either the module to be imported or a imp.lazy_module object which
-indicates the module to be lazily imported.
+Returns either the module to be imported or a imp.lazy_module object
+which indicates the module to be lazily imported.
[clinic start generated code]*/
static PyObject *
builtin___lazy_import___impl(PyObject *module, PyObject *name,
PyObject *globals, PyObject *locals,
PyObject *fromlist, int level)
-/*[clinic end generated code: output=300f1771094b9e8c input=9394874f340b2948]*/
+/*[clinic end generated code: output=300f1771094b9e8c input=9c85cccd6a885b9b]*/
{
PyObject *builtins;
PyThreadState *tstate = PyThreadState_GET();
@@ -696,8 +696,9 @@ PyDoc_STRVAR(filter_doc,
"filter(function, iterable, /)\n\
--\n\
\n\
-Return an iterator yielding those items of iterable for which function(item)\n\
-is true. If function is None, return the items that are true.");
+Return an iterator yielding those items of iterable for which\n\
+function(item) is true. If function is None, return the items that\n\
+are true.");
PyTypeObject PyFilter_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
@@ -770,6 +771,7 @@ builtin_format_impl(PyObject *module, PyObject *value, PyObject *format_spec)
}
/*[clinic input]
+@permit_long_summary
chr as builtin_chr
i: object
@@ -780,7 +782,7 @@ Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.
static PyObject *
builtin_chr(PyObject *module, PyObject *i)
-/*[clinic end generated code: output=d34f25b8035a9b10 input=f919867f0ba2f496]*/
+/*[clinic end generated code: output=d34f25b8035a9b10 input=a9b255f2d2e503f0]*/
{
int overflow;
long v = PyLong_AsLongAndOverflow(i, &overflow);
@@ -804,6 +806,7 @@ builtin_chr(PyObject *module, PyObject *i)
/*[clinic input]
+@permit_long_summary
compile as builtin_compile
source: object
@@ -818,23 +821,24 @@ compile as builtin_compile
Compile source into a code object that can be executed by exec() or eval().
-The source code may represent a Python module, statement or expression.
+The source code may represent a Python module, statement or
+expression.
The filename will be used for run-time error messages.
The mode must be 'exec' to compile a module, 'single' to compile a
single (interactive) statement, or 'eval' to compile an expression.
-The flags argument, if present, controls which future statements influence
-the compilation of the code.
+The flags argument, if present, controls which future statements
+influence the compilation of the code.
The dont_inherit argument, if true, stops the compilation inheriting
the effects of any future statements in effect in the code calling
-compile; if absent or false these statements do influence the compilation,
-in addition to any features explicitly specified.
+compile; if absent or false these statements do influence the
+compilation, in addition to any features explicitly specified.
[clinic start generated code]*/
static PyObject *
builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename,
const char *mode, int flags, int dont_inherit,
int optimize, PyObject *modname, int feature_version)
-/*[clinic end generated code: output=9a0dce1945917a86 input=ddeae1e0253459dc]*/
+/*[clinic end generated code: output=9a0dce1945917a86 input=444c4fe466a97279]*/
{
PyObject *source_copy;
const char *str;
@@ -982,10 +986,10 @@ PyDoc_STRVAR(dir_doc,
"dir([object]) -> list of strings\n"
"\n"
"If called without an argument, return the names in the current scope.\n"
-"Else, return an alphabetized list of names comprising (some of) the attributes\n"
-"of the given object, and of attributes reachable from it.\n"
-"If the object supplies a method named __dir__, it will be used; otherwise\n"
-"the default dir() logic is used and returns:\n"
+"Else, return an alphabetized list of names comprising (some of) the\n"
+"attributes of the given object, and of attributes reachable from it.\n"
+"If the object supplies a method named __dir__, it will be used;\n"
+"otherwise the default dir() logic is used and returns:\n"
" for a module object: the module's attributes.\n"
" for a class object: its attributes, and recursively the attributes\n"
" of its bases.\n"
@@ -1326,9 +1330,11 @@ builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
PyDoc_STRVAR(getattr_doc,
"getattr(object, name[, default]) -> value\n\
\n\
-Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.\n\
-When a default argument is given, it is returned when the attribute doesn't\n\
-exist; without it, an exception is raised in that case.");
+Get a named attribute from an object.\n\
+\n\
+getattr(x, 'y') is equivalent to x.y.\n\
+When a default argument is given, it is returned when the attribute\n\
+doesn't exist; without it, an exception is raised in that case.");
/*[clinic input]
@@ -1336,13 +1342,13 @@ globals as builtin_globals
Return the dictionary containing the current scope's global variables.
-NOTE: Updates to this dictionary *will* affect name lookups in the current
-global scope and vice-versa.
+NOTE: Updates to this dictionary *will* affect name lookups in the
+current global scope and vice-versa.
[clinic start generated code]*/
static PyObject *
builtin_globals_impl(PyObject *module)
-/*[clinic end generated code: output=e5dd1527067b94d2 input=9327576f92bb48ba]*/
+/*[clinic end generated code: output=e5dd1527067b94d2 input=6d725a9b48d1eaeb]*/
{
PyObject *globals;
if (_PyEval_GetFrame() != NULL) {
@@ -1695,8 +1701,8 @@ PyDoc_STRVAR(map_doc,
Make an iterator that computes the function using arguments from\n\
each of the iterables. Stops when the shortest iterable is exhausted.\n\
\n\
-If strict is true and one of the arguments is exhausted before the others,\n\
-raise a ValueError.");
+If strict is true and one of the arguments is exhausted before the\n\
+others, raise a ValueError.");
PyTypeObject PyMap_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
@@ -1783,8 +1789,8 @@ builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
PyDoc_STRVAR(next_doc,
"next(iterator[, default])\n\
\n\
-Return the next item from the iterator. If default is given and the iterator\n\
-is exhausted, it is returned instead of raising StopIteration.");
+Return the next item from the iterator. If default is given and the\n\
+iterator is exhausted, it is returned instead of raising StopIteration.");
/*[clinic input]
@@ -1907,7 +1913,8 @@ iter(callable, sentinel) -> iterator\n\
\n\
Get an iterator from an object. In the first form, the argument must\n\
supply its own iterator, or be a sequence.\n\
-In the second form, the callable is called until it returns the sentinel.");
+In the second form, the callable is called until it returns the\n\
+sentinel.");
/*[clinic input]
@@ -2001,14 +2008,15 @@ locals as builtin_locals
Return a dictionary containing the current scope's local variables.
-NOTE: Whether or not updates to this dictionary will affect name lookups in
-the local scope and vice-versa is *implementation dependent* and not
-covered by any backwards compatibility guarantees.
+NOTE: Whether or not updates to this dictionary will affect name
+lookups in the local scope and vice-versa is *implementation
+dependent* and not covered by any backwards compatibility
+guarantees.
[clinic start generated code]*/
static PyObject *
builtin_locals_impl(PyObject *module)
-/*[clinic end generated code: output=b46c94015ce11448 input=7874018d478d5c4b]*/
+/*[clinic end generated code: output=b46c94015ce11448 input=989cc75c22167c42]*/
{
PyObject *locals;
if (_PyEval_GetFrame() != NULL) {
@@ -2260,6 +2268,7 @@ builtin_ord(PyObject *module, PyObject *c)
/*[clinic input]
+@permit_long_summary
pow as builtin_pow
base: object
@@ -2268,14 +2277,14 @@ pow as builtin_pow
Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments
-Some types, such as ints, are able to use a more efficient algorithm when
-invoked using the three argument form.
+Some types, such as ints, are able to use a more efficient algorithm
+when invoked using the three argument form.
[clinic start generated code]*/
static PyObject *
builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp,
PyObject *mod)
-/*[clinic end generated code: output=3ca1538221bbf15f input=435dbd48a12efb23]*/
+/*[clinic end generated code: output=3ca1538221bbf15f input=0cd5c3ecc8003aec]*/
{
return PyNumber_Power(base, exp, mod);
}
@@ -2396,13 +2405,14 @@ Read a string from standard input. The trailing newline is stripped.
The prompt string, if given, is printed to standard output without a
trailing newline before reading input.
-If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
+If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise
+EOFError.
On *nix systems, readline is used if available.
[clinic start generated code]*/
static PyObject *
builtin_input_impl(PyObject *module, PyObject *prompt)
-/*[clinic end generated code: output=83db5a191e7a0d60 input=159c46d4ae40977e]*/
+/*[clinic end generated code: output=83db5a191e7a0d60 input=ebb939c954639427]*/
{
PyObject *fin = NULL;
PyObject *fout = NULL;
@@ -2670,13 +2680,14 @@ round as builtin_round
Round a number to a given precision in decimal digits.
-The return value is an integer if ndigits is omitted or None. Otherwise
-the return value has the same type as the number. ndigits may be negative.
+The return value is an integer if ndigits is omitted or None.
+Otherwise the return value has the same type as the number. ndigits
+may be negative.
[clinic start generated code]*/
static PyObject *
builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits)
-/*[clinic end generated code: output=ff0d9dd176c02ede input=275678471d7aca15]*/
+/*[clinic end generated code: output=ff0d9dd176c02ede input=bdcb7c67bf4a4320]*/
{
PyObject *result;
if (ndigits == Py_None) {
@@ -2708,8 +2719,8 @@ sorted as builtin_sorted
Return a new list containing all items from the iterable in ascending order.
-A custom key function can be supplied to customize the sort order, and the
-reverse flag can be set to request the result in descending order.
+A custom key function can be supplied to customize the sort order, and
+the reverse flag can be set to request the result in descending order.
[end disabled clinic input]*/
PyDoc_STRVAR(builtin_sorted__doc__,
@@ -2843,6 +2854,7 @@ cs_to_double(CompensatedSum total)
}
/*[clinic input]
+@permit_long_summary
sum as builtin_sum
iterable: object
@@ -2852,13 +2864,13 @@ sum as builtin_sum
Return the sum of a 'start' value (default: 0) plus an iterable of numbers
When the iterable is empty, return the start value.
-This function is intended specifically for use with numeric values and may
-reject non-numeric types.
+This function is intended specifically for use with numeric values and
+may reject non-numeric types.
[clinic start generated code]*/
static PyObject *
builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
-/*[clinic end generated code: output=df758cec7d1d302f input=162b50765250d222]*/
+/*[clinic end generated code: output=df758cec7d1d302f input=d464d57815196b73]*/
{
PyObject *result = start;
PyObject *temp, *item, *iter;
@@ -3094,6 +3106,7 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
/*[clinic input]
+@permit_long_summary
isinstance as builtin_isinstance
obj: object
@@ -3102,15 +3115,15 @@ isinstance as builtin_isinstance
Return whether an object is an instance of a class or of a subclass thereof.
-A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to
-check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B)
-or ...`` etc.
+A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the
+target to check against. This is equivalent to ``isinstance(x, A) or
+isinstance(x, B) or ...`` etc.
[clinic start generated code]*/
static PyObject *
builtin_isinstance_impl(PyObject *module, PyObject *obj,
PyObject *class_or_tuple)
-/*[clinic end generated code: output=6faf01472c13b003 input=ffa743db1daf7549]*/
+/*[clinic end generated code: output=6faf01472c13b003 input=5d74d547df498f38]*/
{
int retval;
@@ -3130,15 +3143,15 @@ issubclass as builtin_issubclass
Return whether 'cls' is derived from another class or is the same class.
-A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to
-check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B)
-or ...``.
+A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the
+target to check against. This is equivalent to ``issubclass(x, A) or
+issubclass(x, B) or ...``.
[clinic start generated code]*/
static PyObject *
builtin_issubclass_impl(PyObject *module, PyObject *cls,
PyObject *class_or_tuple)
-/*[clinic end generated code: output=358412410cd7a250 input=a24b9f3d58c370d6]*/
+/*[clinic end generated code: output=358412410cd7a250 input=a91ce96345a6705d]*/
{
int retval;
@@ -3368,13 +3381,13 @@ PyDoc_STRVAR(zip_doc,
"zip(*iterables, strict=False)\n\
--\n\
\n\
-The zip object yields n-length tuples, where n is the number of iterables\n\
-passed as positional arguments to zip(). The i-th element in every tuple\n\
-comes from the i-th iterable argument to zip(). This continues until the\n\
-shortest argument is exhausted.\n\
+The zip object yields n-length tuples, where n is the number of\n\
+iterables passed as positional arguments to zip(). The i-th element\n\
+in every tuple comes from the i-th iterable argument to zip(). This\n\
+continues until the shortest argument is exhausted.\n\
\n\
-If strict is true and one of the arguments is exhausted before the others,\n\
-raise a ValueError.\n\
+If strict is true and one of the arguments is exhausted before the\n\
+others, raise a ValueError.\n\
\n\
>>> list(zip('abcdefg', range(3), range(4)))\n\
[('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]");
diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h
index e6b845cd375d73..4a38e0df61708c 100644
--- a/Python/clinic/bltinmodule.c.h
+++ b/Python/clinic/bltinmodule.c.h
@@ -25,9 +25,10 @@ PyDoc_STRVAR(builtin___import____doc__,
"empty list to emulate ``import name``.\n"
"When importing a module from a package, note that __import__(\'A.B\', ...)\n"
"returns package A when fromlist is empty, but its submodule B when\n"
-"fromlist is not empty. The level argument is used to determine whether to\n"
-"perform absolute or relative imports: 0 is absolute, while a positive number\n"
-"is the number of parent directories to search relative to the current module.");
+"fromlist is not empty. The level argument is used to determine whether\n"
+"to perform absolute or relative imports: 0 is absolute, while a positive\n"
+"number is the number of parent directories to search relative to the\n"
+"current module.");
#define BUILTIN___IMPORT___METHODDEF \
{"__import__", _PyCFunction_CAST(builtin___import__), METH_FASTCALL|METH_KEYWORDS, builtin___import____doc__},
@@ -120,8 +121,8 @@ PyDoc_STRVAR(builtin___lazy_import____doc__,
"\n"
"Lazily imports a module.\n"
"\n"
-"Returns either the module to be imported or a imp.lazy_module object which\n"
-"indicates the module to be lazily imported.");
+"Returns either the module to be imported or a imp.lazy_module object\n"
+"which indicates the module to be lazily imported.");
#define BUILTIN___LAZY_IMPORT___METHODDEF \
{"__lazy_import__", _PyCFunction_CAST(builtin___lazy_import__), METH_FASTCALL|METH_KEYWORDS, builtin___lazy_import____doc__},
@@ -339,16 +340,17 @@ PyDoc_STRVAR(builtin_compile__doc__,
"\n"
"Compile source into a code object that can be executed by exec() or eval().\n"
"\n"
-"The source code may represent a Python module, statement or expression.\n"
+"The source code may represent a Python module, statement or\n"
+"expression.\n"
"The filename will be used for run-time error messages.\n"
"The mode must be \'exec\' to compile a module, \'single\' to compile a\n"
"single (interactive) statement, or \'eval\' to compile an expression.\n"
-"The flags argument, if present, controls which future statements influence\n"
-"the compilation of the code.\n"
+"The flags argument, if present, controls which future statements\n"
+"influence the compilation of the code.\n"
"The dont_inherit argument, if true, stops the compilation inheriting\n"
"the effects of any future statements in effect in the code calling\n"
-"compile; if absent or false these statements do influence the compilation,\n"
-"in addition to any features explicitly specified.");
+"compile; if absent or false these statements do influence the\n"
+"compilation, in addition to any features explicitly specified.");
#define BUILTIN_COMPILE_METHODDEF \
{"compile", _PyCFunction_CAST(builtin_compile), METH_FASTCALL|METH_KEYWORDS, builtin_compile__doc__},
@@ -683,8 +685,8 @@ PyDoc_STRVAR(builtin_globals__doc__,
"\n"
"Return the dictionary containing the current scope\'s global variables.\n"
"\n"
-"NOTE: Updates to this dictionary *will* affect name lookups in the current\n"
-"global scope and vice-versa.");
+"NOTE: Updates to this dictionary *will* affect name lookups in the\n"
+"current global scope and vice-versa.");
#define BUILTIN_GLOBALS_METHODDEF \
{"globals", (PyCFunction)builtin_globals, METH_NOARGS, builtin_globals__doc__},
@@ -910,9 +912,10 @@ PyDoc_STRVAR(builtin_locals__doc__,
"\n"
"Return a dictionary containing the current scope\'s local variables.\n"
"\n"
-"NOTE: Whether or not updates to this dictionary will affect name lookups in\n"
-"the local scope and vice-versa is *implementation dependent* and not\n"
-"covered by any backwards compatibility guarantees.");
+"NOTE: Whether or not updates to this dictionary will affect name\n"
+"lookups in the local scope and vice-versa is *implementation\n"
+"dependent* and not covered by any backwards compatibility\n"
+"guarantees.");
#define BUILTIN_LOCALS_METHODDEF \
{"locals", (PyCFunction)builtin_locals, METH_NOARGS, builtin_locals__doc__},
@@ -959,8 +962,8 @@ PyDoc_STRVAR(builtin_pow__doc__,
"\n"
"Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments\n"
"\n"
-"Some types, such as ints, are able to use a more efficient algorithm when\n"
-"invoked using the three argument form.");
+"Some types, such as ints, are able to use a more efficient algorithm\n"
+"when invoked using the three argument form.");
#define BUILTIN_POW_METHODDEF \
{"pow", _PyCFunction_CAST(builtin_pow), METH_FASTCALL|METH_KEYWORDS, builtin_pow__doc__},
@@ -1136,7 +1139,8 @@ PyDoc_STRVAR(builtin_input__doc__,
"The prompt string, if given, is printed to standard output without a\n"
"trailing newline before reading input.\n"
"\n"
-"If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.\n"
+"If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise\n"
+"EOFError.\n"
"On *nix systems, readline is used if available.");
#define BUILTIN_INPUT_METHODDEF \
@@ -1182,8 +1186,9 @@ PyDoc_STRVAR(builtin_round__doc__,
"\n"
"Round a number to a given precision in decimal digits.\n"
"\n"
-"The return value is an integer if ndigits is omitted or None. Otherwise\n"
-"the return value has the same type as the number. ndigits may be negative.");
+"The return value is an integer if ndigits is omitted or None.\n"
+"Otherwise the return value has the same type as the number. ndigits\n"
+"may be negative.");
#define BUILTIN_ROUND_METHODDEF \
{"round", _PyCFunction_CAST(builtin_round), METH_FASTCALL|METH_KEYWORDS, builtin_round__doc__},
@@ -1251,8 +1256,8 @@ PyDoc_STRVAR(builtin_sum__doc__,
"Return the sum of a \'start\' value (default: 0) plus an iterable of numbers\n"
"\n"
"When the iterable is empty, return the start value.\n"
-"This function is intended specifically for use with numeric values and may\n"
-"reject non-numeric types.");
+"This function is intended specifically for use with numeric values and\n"
+"may reject non-numeric types.");
#define BUILTIN_SUM_METHODDEF \
{"sum", _PyCFunction_CAST(builtin_sum), METH_FASTCALL|METH_KEYWORDS, builtin_sum__doc__},
@@ -1319,9 +1324,9 @@ PyDoc_STRVAR(builtin_isinstance__doc__,
"\n"
"Return whether an object is an instance of a class or of a subclass thereof.\n"
"\n"
-"A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to\n"
-"check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B)\n"
-"or ...`` etc.");
+"A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the\n"
+"target to check against. This is equivalent to ``isinstance(x, A) or\n"
+"isinstance(x, B) or ...`` etc.");
#define BUILTIN_ISINSTANCE_METHODDEF \
{"isinstance", _PyCFunction_CAST(builtin_isinstance), METH_FASTCALL, builtin_isinstance__doc__},
@@ -1354,9 +1359,9 @@ PyDoc_STRVAR(builtin_issubclass__doc__,
"\n"
"Return whether \'cls\' is derived from another class or is the same class.\n"
"\n"
-"A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to\n"
-"check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B)\n"
-"or ...``.");
+"A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the\n"
+"target to check against. This is equivalent to ``issubclass(x, A) or\n"
+"issubclass(x, B) or ...``.");
#define BUILTIN_ISSUBCLASS_METHODDEF \
{"issubclass", _PyCFunction_CAST(builtin_issubclass), METH_FASTCALL, builtin_issubclass__doc__},
@@ -1382,4 +1387,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=f1fc836a63d89826 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=84efa9c5cc737ce5 input=a9049054013a1b77]*/
From 3573b3b1ecbd99030a0b18658e1bfece771b2566 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 24 May 2026 15:36:30 +0200
Subject: [PATCH 131/213] [3.15] gh-149018: Use `XML_SetHashSalt16Bytes` in
`pyexpat`/`_elementtree` when possible (#149645)
(cherry picked from commit 24b8f12544468e4cedf5bfbe25442fcd495391e4)
Co-authored-by: Stan Ulbrych
---
Include/internal/pycore_pyhash.h | 8 +++++---
Include/pyexpat.h | 3 +++
.../2026-04-26-19-30-45.gh-issue-149018.a9SqWb.rst | 3 +++
Modules/_elementtree.c | 8 ++++++--
Modules/pyexpat.c | 10 +++++++++-
5 files changed, 26 insertions(+), 6 deletions(-)
create mode 100644 Misc/NEWS.d/next/Security/2026-04-26-19-30-45.gh-issue-149018.a9SqWb.rst
diff --git a/Include/internal/pycore_pyhash.h b/Include/internal/pycore_pyhash.h
index 84cb72fa6fd1b2..3056dc44cc0f1b 100644
--- a/Include/internal/pycore_pyhash.h
+++ b/Include/internal/pycore_pyhash.h
@@ -27,14 +27,14 @@ _Py_HashPointerRaw(const void *ptr)
* pppppppp ssssssss ........ fnv -- two Py_hash_t
* k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t
* ........ ........ ssssssss djbx33a -- 16 bytes padding + one Py_hash_t
- * ........ ........ eeeeeeee pyexpat XML hash salt
+ * eeeeeeee eeeeeeee eeeeeeee pyexpat XML hash salt
*
* memory layout on 32 bit systems
* cccccccc cccccccc cccccccc uc
* ppppssss ........ ........ fnv -- two Py_hash_t
* k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t (*)
* ........ ........ ssss.... djbx33a -- 16 bytes padding + one Py_hash_t
- * ........ ........ eeee.... pyexpat XML hash salt
+ * eeeeeeee eeeeeeee eeee.... pyexpat XML hash salt
*
* (*) The siphash member may not be available on 32 bit platforms without
* an unsigned int64 data type.
@@ -58,7 +58,9 @@ typedef union {
Py_hash_t suffix;
} djbx33a;
struct {
- unsigned char padding[16];
+ /* 16 bytes for XML_SetHashSalt16Bytes */
+ uint8_t hashsalt16[16];
+ /* 4/8 bytes for legacy XML_SetHashSalt */
Py_hash_t hashsalt;
} expat;
} _Py_HashSecret_t;
diff --git a/Include/pyexpat.h b/Include/pyexpat.h
index f523f8bb273983..a676e16a7a457e 100644
--- a/Include/pyexpat.h
+++ b/Include/pyexpat.h
@@ -62,6 +62,9 @@ struct PyExpat_CAPI
XML_Parser parser, unsigned long long activationThresholdBytes);
XML_Bool (*SetBillionLaughsAttackProtectionMaximumAmplification)(
XML_Parser parser, float maxAmplificationFactor);
+ /* might be NULL for expat < 2.8.0 */
+ XML_Bool (*SetHashSalt16Bytes)(
+ XML_Parser parser, const uint8_t entropy[16]);
/* always add new stuff to the end! */
};
diff --git a/Misc/NEWS.d/next/Security/2026-04-26-19-30-45.gh-issue-149018.a9SqWb.rst b/Misc/NEWS.d/next/Security/2026-04-26-19-30-45.gh-issue-149018.a9SqWb.rst
new file mode 100644
index 00000000000000..d1b5b368684e6a
--- /dev/null
+++ b/Misc/NEWS.d/next/Security/2026-04-26-19-30-45.gh-issue-149018.a9SqWb.rst
@@ -0,0 +1,3 @@
+Improved protection against XML hash-flooding attacks in
+:mod:`xml.parsers.expat` and :mod:`xml.etree.ElementTree` when Python is
+compiled with libExpat 2.8.0 or later.
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index cbd1e026df2722..9e794be5c109ba 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -3735,8 +3735,12 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target,
PyErr_NoMemory();
return -1;
}
- /* expat < 2.1.0 has no XML_SetHashSalt() */
- if (EXPAT(st, SetHashSalt) != NULL) {
+ // Prefer 16-byte entropy, only expat >= 2.8.0. See gh-149018
+ if (EXPAT(st, SetHashSalt16Bytes) != NULL) {
+ EXPAT(st, SetHashSalt16Bytes)(self->parser,
+ _Py_HashSecret.expat.hashsalt16);
+ }
+ else if (EXPAT(st, SetHashSalt) != NULL) {
EXPAT(st, SetHashSalt)(self->parser,
(unsigned long)_Py_HashSecret.expat.hashsalt);
}
diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
index c01f7babe74527..64314e5dff93a1 100644
--- a/Modules/pyexpat.c
+++ b/Modules/pyexpat.c
@@ -1533,7 +1533,10 @@ newxmlparseobject(pyexpat_state *state, const char *encoding,
Py_DECREF(self);
return NULL;
}
-#if XML_COMBINED_VERSION >= 20100
+#if XML_COMBINED_VERSION >= 20800
+ /* This feature was added upstream in libexpat 2.8.0. */
+ XML_SetHashSalt16Bytes(self->itself, _Py_HashSecret.expat.hashsalt16);
+#elif XML_COMBINED_VERSION >= 20100
/* This feature was added upstream in libexpat 2.1.0. */
XML_SetHashSalt(self->itself,
(unsigned long)_Py_HashSecret.expat.hashsalt);
@@ -2427,6 +2430,11 @@ pyexpat_exec(PyObject *mod)
#else
capi->SetHashSalt = NULL;
#endif
+#if XML_COMBINED_VERSION >= 20800
+ capi->SetHashSalt16Bytes = XML_SetHashSalt16Bytes;
+#else
+ capi->SetHashSalt16Bytes = NULL;
+#endif
#if XML_COMBINED_VERSION >= 20600
capi->SetReparseDeferralEnabled = XML_SetReparseDeferralEnabled;
#else
From d52dad6989eb79fd01378654954cd79c363c1179 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 24 May 2026 15:39:29 +0200
Subject: [PATCH 132/213] [3.15] gh-149619: Fix `_remote_debugging` permissions
error on Linux (GH-150012) (#150339)
gh-149619: Fix `_remote_debugging` permissions error on Linux (GH-150012)
When running profiling on Linux without sudo, attempts to read
process memory would fail with the misleading error 'Failed to find
the PyRuntime section in process on Linux platform'.
The actual issue is a permissions error because profiling was not
run with sudo. We were clearing the exception on Linux when trying
to read memory, instead, we should bubble up the permissions error
and show it properly.
(cherry picked from commit 0563890872b3c63f94953e983fe396615b708540)
Co-authored-by: ivonastojanovic <80911834+ivonastojanovic@users.noreply.github.com>
---
Python/remote_debug.h | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/Python/remote_debug.h b/Python/remote_debug.h
index 7b2c4f3bcb8077..53bbd571ad3cef 100644
--- a/Python/remote_debug.h
+++ b/Python/remote_debug.h
@@ -170,7 +170,9 @@ _Py_RemoteDebug_ValidatePyRuntimeCookie(proc_handle_t *handle, uintptr_t address
}
char buf[sizeof(_Py_Debug_Cookie) - 1];
if (_Py_RemoteDebug_ReadRemoteMemory(handle, address, sizeof(buf), buf) != 0) {
- PyErr_Clear();
+ if (!PyErr_ExceptionMatches(PyExc_PermissionError)) {
+ PyErr_Clear();
+ }
return 0;
}
return memcmp(buf, _Py_Debug_Cookie, sizeof(buf)) == 0;
@@ -785,6 +787,10 @@ search_linux_map_for_section(proc_handle_t *handle, const char* secname, const c
}
if (strstr(filename, substr)) {
+ if (PyErr_ExceptionMatches(PyExc_PermissionError)) {
+ retval = 0;
+ break;
+ }
PyErr_Clear();
retval = search_elf_file_for_section(handle, secname, start, path);
if (retval
@@ -960,12 +966,14 @@ _Py_RemoteDebug_GetPyRuntimeAddress(proc_handle_t* handle)
address = search_linux_map_for_section(handle, "PyRuntime", "python",
_Py_RemoteDebug_ValidatePyRuntimeCookie);
if (address == 0) {
- // Error out: 'python' substring covers both executable and DLL
- PyObject *exc = PyErr_GetRaisedException();
- PyErr_Format(PyExc_RuntimeError,
- "Failed to find the PyRuntime section in process %d on Linux platform",
- handle->pid);
- _PyErr_ChainExceptions1(exc);
+ if (!PyErr_ExceptionMatches(PyExc_PermissionError)) {
+ // Error out: 'python' substring covers both executable and DLL
+ PyObject *exc = PyErr_GetRaisedException();
+ PyErr_Format(PyExc_RuntimeError,
+ "Failed to find the PyRuntime section in process %d on Linux platform",
+ handle->pid);
+ _PyErr_ChainExceptions1(exc);
+ }
}
#elif defined(__APPLE__) && defined(TARGET_OS_OSX) && TARGET_OS_OSX
// On macOS, try libpython first, then fall back to python
From baf22f34cab477faa007c4ebc04841db3a727af9 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 24 May 2026 15:41:40 +0200
Subject: [PATCH 133/213] [3.15] gh-150285: Fix too long docstrings in the
pyexpat module (GH-150294) (GH-150337)
(cherry picked from commit 9da7923835a4c72e738551bbd78b8179a81286ad)
Co-authored-by: Serhiy Storchaka
---
Modules/clinic/pyexpat.c.h | 73 +++++++++++++++++-------------
Modules/pyexpat.c | 93 ++++++++++++++++++++------------------
2 files changed, 90 insertions(+), 76 deletions(-)
diff --git a/Modules/clinic/pyexpat.c.h b/Modules/clinic/pyexpat.c.h
index ff2e28269dc927..1a07726d303eca 100644
--- a/Modules/clinic/pyexpat.c.h
+++ b/Modules/clinic/pyexpat.c.h
@@ -218,8 +218,9 @@ PyDoc_STRVAR(pyexpat_xmlparser_GetInputContext__doc__,
"\n"
"Return the untranslated text of the input that caused the current event.\n"
"\n"
-"If the event was generated by a large amount of text (such as a start tag\n"
-"for an element with many attributes), not all of the text may be available.");
+"If the event was generated by a large amount of text (such as\n"
+"a start tag for an element with many attributes), not all of the\n"
+"text may be available.");
#define PYEXPAT_XMLPARSER_GETINPUTCONTEXT_METHODDEF \
{"GetInputContext", (PyCFunction)pyexpat_xmlparser_GetInputContext, METH_NOARGS, pyexpat_xmlparser_GetInputContext__doc__},
@@ -357,9 +358,10 @@ PyDoc_STRVAR(pyexpat_xmlparser_UseForeignDTD__doc__,
"\n"
"Allows the application to provide an artificial external subset if one is not specified as part of the document instance.\n"
"\n"
-"This readily allows the use of a \'default\' document type controlled by the\n"
-"application, while still getting the advantage of providing document type\n"
-"information to the parser. \'flag\' defaults to True if not provided.");
+"This readily allows the use of a \'default\' document type controlled\n"
+"by the application, while still getting the advantage of providing\n"
+"document type information to the parser. \'flag\' defaults to True if\n"
+"not provided.");
#define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF \
{"UseForeignDTD", _PyCFunction_CAST(pyexpat_xmlparser_UseForeignDTD), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_UseForeignDTD__doc__},
@@ -417,14 +419,15 @@ PyDoc_STRVAR(pyexpat_xmlparser_SetBillionLaughsAttackProtectionActivationThresho
"\n"
"Sets the number of output bytes needed to activate protection against billion laughs attacks.\n"
"\n"
-"The number of output bytes includes amplification from entity expansion\n"
-"and reading DTD files.\n"
+"The number of output bytes includes amplification from entity\n"
+"expansion and reading DTD files.\n"
"\n"
-"Parser objects usually have a protection activation threshold of 8 MiB,\n"
-"but the actual default value depends on the underlying Expat library.\n"
+"Parser objects usually have a protection activation threshold of\n"
+"8 MiB, but the actual default value depends on the underlying Expat\n"
+"library.\n"
"\n"
-"Activation thresholds below 4 MiB are known to break support for DITA 1.3\n"
-"payload and are hence not recommended.");
+"Activation thresholds below 4 MiB are known to break support for\n"
+"DITA 1.3 payload and are hence not recommended.");
#define PYEXPAT_XMLPARSER_SETBILLIONLAUGHSATTACKPROTECTIONACTIVATIONTHRESHOLD_METHODDEF \
{"SetBillionLaughsAttackProtectionActivationThreshold", _PyCFunction_CAST(pyexpat_xmlparser_SetBillionLaughsAttackProtectionActivationThreshold), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_SetBillionLaughsAttackProtectionActivationThreshold__doc__},
@@ -479,18 +482,21 @@ PyDoc_STRVAR(pyexpat_xmlparser_SetBillionLaughsAttackProtectionMaximumAmplificat
"\n"
"Sets the maximum tolerated amplification factor for protection against billion laughs attacks.\n"
"\n"
-"The amplification factor is calculated as \"(direct + indirect) / direct\"\n"
-"while parsing, where \"direct\" is the number of bytes read from the primary\n"
-"document in parsing and \"indirect\" is the number of bytes added by expanding\n"
-"entities and reading external DTD files, combined.\n"
+"The amplification factor is calculated as \"(direct + indirect) /\n"
+"direct\" while parsing, where \"direct\" is the number of bytes read\n"
+"from the primary document in parsing and \"indirect\" is the number of\n"
+"bytes added by expanding entities and reading external DTD files,\n"
+"combined.\n"
"\n"
-"The \'max_factor\' value must be a non-NaN floating point value greater than\n"
-"or equal to 1.0. Amplification factors greater than 30,000 can be observed\n"
-"in the middle of parsing even with benign files in practice. In particular,\n"
-"the activation threshold should be carefully chosen to avoid false positives.\n"
+"The \'max_factor\' value must be a non-NaN floating point value\n"
+"greater than or equal to 1.0. Amplification factors greater than\n"
+"30,000 can be observed in the middle of parsing even with benign\n"
+"files in practice. In particular, the activation threshold should\n"
+"be carefully chosen to avoid false positives.\n"
"\n"
"Parser objects usually have a maximum amplification factor of 100,\n"
-"but the actual default value depends on the underlying Expat library.");
+"but the actual default value depends on the underlying Expat\n"
+"library.");
#define PYEXPAT_XMLPARSER_SETBILLIONLAUGHSATTACKPROTECTIONMAXIMUMAMPLIFICATION_METHODDEF \
{"SetBillionLaughsAttackProtectionMaximumAmplification", _PyCFunction_CAST(pyexpat_xmlparser_SetBillionLaughsAttackProtectionMaximumAmplification), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_SetBillionLaughsAttackProtectionMaximumAmplification__doc__},
@@ -551,8 +557,9 @@ PyDoc_STRVAR(pyexpat_xmlparser_SetAllocTrackerActivationThreshold__doc__,
"\n"
"Sets the number of allocated bytes of dynamic memory needed to activate protection against disproportionate use of RAM.\n"
"\n"
-"Parser objects usually have an allocation activation threshold of 64 MiB,\n"
-"but the actual default value depends on the underlying Expat library.");
+"Parser objects usually have an allocation activation threshold of\n"
+"64 MiB, but the actual default value depends on the underlying Expat\n"
+"library.");
#define PYEXPAT_XMLPARSER_SETALLOCTRACKERACTIVATIONTHRESHOLD_METHODDEF \
{"SetAllocTrackerActivationThreshold", _PyCFunction_CAST(pyexpat_xmlparser_SetAllocTrackerActivationThreshold), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_SetAllocTrackerActivationThreshold__doc__},
@@ -606,18 +613,20 @@ PyDoc_STRVAR(pyexpat_xmlparser_SetAllocTrackerMaximumAmplification__doc__,
"\n"
"Sets the maximum amplification factor between direct input and bytes of dynamic memory allocated.\n"
"\n"
-"The amplification factor is calculated as \"allocated / direct\" while parsing,\n"
-"where \"direct\" is the number of bytes read from the primary document in parsing\n"
-"and \"allocated\" is the number of bytes of dynamic memory allocated in the parser\n"
-"hierarchy.\n"
+"The amplification factor is calculated as \"allocated / direct\" while\n"
+"parsing, where \"direct\" is the number of bytes read from the primary\n"
+"document in parsing and \"allocated\" is the number of bytes of\n"
+"dynamic memory allocated in the parser hierarchy.\n"
"\n"
-"The \'max_factor\' value must be a non-NaN floating point value greater than\n"
-"or equal to 1.0. Amplification factors greater than 100.0 can be observed\n"
-"near the start of parsing even with benign files in practice. In particular,\n"
-"the activation threshold should be carefully chosen to avoid false positives.\n"
+"The \'max_factor\' value must be a non-NaN floating point value\n"
+"greater than or equal to 1.0. Amplification factors greater than\n"
+"100.0 can be observed near the start of parsing even with benign\n"
+"files in practice. In particular, the activation threshold should\n"
+"be carefully chosen to avoid false positives.\n"
"\n"
"Parser objects usually have a maximum amplification factor of 100,\n"
-"but the actual default value depends on the underlying Expat library.");
+"but the actual default value depends on the underlying Expat\n"
+"library.");
#define PYEXPAT_XMLPARSER_SETALLOCTRACKERMAXIMUMAMPLIFICATION_METHODDEF \
{"SetAllocTrackerMaximumAmplification", _PyCFunction_CAST(pyexpat_xmlparser_SetAllocTrackerMaximumAmplification), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_SetAllocTrackerMaximumAmplification__doc__},
@@ -830,4 +839,4 @@ pyexpat_ErrorString(PyObject *module, PyObject *arg)
#ifndef PYEXPAT_XMLPARSER_SETALLOCTRACKERMAXIMUMAMPLIFICATION_METHODDEF
#define PYEXPAT_XMLPARSER_SETALLOCTRACKERMAXIMUMAMPLIFICATION_METHODDEF
#endif /* !defined(PYEXPAT_XMLPARSER_SETALLOCTRACKERMAXIMUMAMPLIFICATION_METHODDEF) */
-/*[clinic end generated code: output=81101a16a409daf6 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=270a0bfe3300e8a1 input=a9049054013a1b77]*/
diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
index 64314e5dff93a1..d204b6f27d9908 100644
--- a/Modules/pyexpat.c
+++ b/Modules/pyexpat.c
@@ -830,6 +830,7 @@ get_parse_result(pyexpat_state *state, xmlparseobject *self, int rv)
#define MAX_CHUNK_SIZE (1 << 20)
/*[clinic input]
+@permit_long_summary
pyexpat.xmlparser.SetReparseDeferralEnabled
enabled: bool
@@ -841,7 +842,7 @@ Enable/Disable reparse deferral; enabled by default with Expat >=2.6.0.
static PyObject *
pyexpat_xmlparser_SetReparseDeferralEnabled_impl(xmlparseobject *self,
int enabled)
-/*[clinic end generated code: output=5ec539e3b63c8c49 input=021eb9e0bafc32c5]*/
+/*[clinic end generated code: output=5ec539e3b63c8c49 input=6d3743500dcee799]*/
{
#if XML_COMBINED_VERSION >= 20600
XML_SetReparseDeferralEnabled(self->itself, enabled ? XML_TRUE : XML_FALSE);
@@ -1053,18 +1054,19 @@ pyexpat_xmlparser_GetBase_impl(xmlparseobject *self)
}
/*[clinic input]
-@permit_long_docstring_body
+@permit_long_summary
pyexpat.xmlparser.GetInputContext
Return the untranslated text of the input that caused the current event.
-If the event was generated by a large amount of text (such as a start tag
-for an element with many attributes), not all of the text may be available.
+If the event was generated by a large amount of text (such as
+a start tag for an element with many attributes), not all of the
+text may be available.
[clinic start generated code]*/
static PyObject *
pyexpat_xmlparser_GetInputContext_impl(xmlparseobject *self)
-/*[clinic end generated code: output=a88026d683fc22cc input=925cea010fdfa682]*/
+/*[clinic end generated code: output=a88026d683fc22cc input=a672f48f09bb73d2]*/
{
if (self->in_callback) {
int offset, size;
@@ -1191,7 +1193,6 @@ pyexpat_xmlparser_SetParamEntityParsing_impl(xmlparseobject *self, int flag)
#if XML_COMBINED_VERSION >= 19505
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
pyexpat.xmlparser.UseForeignDTD
cls: defining_class
@@ -1200,15 +1201,16 @@ pyexpat.xmlparser.UseForeignDTD
Allows the application to provide an artificial external subset if one is not specified as part of the document instance.
-This readily allows the use of a 'default' document type controlled by the
-application, while still getting the advantage of providing document type
-information to the parser. 'flag' defaults to True if not provided.
+This readily allows the use of a 'default' document type controlled
+by the application, while still getting the advantage of providing
+document type information to the parser. 'flag' defaults to True if
+not provided.
[clinic start generated code]*/
static PyObject *
pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, PyTypeObject *cls,
int flag)
-/*[clinic end generated code: output=d7d98252bd25a20f input=c2264845d8c0029c]*/
+/*[clinic end generated code: output=d7d98252bd25a20f input=2920baa5bf24714d]*/
{
pyexpat_state *state = PyType_GetModuleState(cls);
enum XML_Error rc;
@@ -1268,7 +1270,6 @@ set_maximum_amplification(xmlparseobject *self,
#if XML_COMBINED_VERSION >= 20400
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
pyexpat.xmlparser.SetBillionLaughsAttackProtectionActivationThreshold
cls: defining_class
@@ -1277,21 +1278,22 @@ pyexpat.xmlparser.SetBillionLaughsAttackProtectionActivationThreshold
Sets the number of output bytes needed to activate protection against billion laughs attacks.
-The number of output bytes includes amplification from entity expansion
-and reading DTD files.
+The number of output bytes includes amplification from entity
+expansion and reading DTD files.
-Parser objects usually have a protection activation threshold of 8 MiB,
-but the actual default value depends on the underlying Expat library.
+Parser objects usually have a protection activation threshold of
+8 MiB, but the actual default value depends on the underlying Expat
+library.
-Activation thresholds below 4 MiB are known to break support for DITA 1.3
-payload and are hence not recommended.
+Activation thresholds below 4 MiB are known to break support for
+DITA 1.3 payload and are hence not recommended.
[clinic start generated code]*/
static PyObject *
pyexpat_xmlparser_SetBillionLaughsAttackProtectionActivationThreshold_impl(xmlparseobject *self,
PyTypeObject *cls,
unsigned long long threshold)
-/*[clinic end generated code: output=0c082342f1c78114 input=fa2f91f26b62a42a]*/
+/*[clinic end generated code: output=0c082342f1c78114 input=8d84b0e3a873cdba]*/
{
return set_activation_threshold(
self, cls, threshold,
@@ -1303,7 +1305,6 @@ pyexpat_xmlparser_SetBillionLaughsAttackProtectionActivationThreshold_impl(xmlpa
#if XML_COMBINED_VERSION >= 20400
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
pyexpat.xmlparser.SetBillionLaughsAttackProtectionMaximumAmplification
cls: defining_class
@@ -1312,25 +1313,28 @@ pyexpat.xmlparser.SetBillionLaughsAttackProtectionMaximumAmplification
Sets the maximum tolerated amplification factor for protection against billion laughs attacks.
-The amplification factor is calculated as "(direct + indirect) / direct"
-while parsing, where "direct" is the number of bytes read from the primary
-document in parsing and "indirect" is the number of bytes added by expanding
-entities and reading external DTD files, combined.
+The amplification factor is calculated as "(direct + indirect) /
+direct" while parsing, where "direct" is the number of bytes read
+from the primary document in parsing and "indirect" is the number of
+bytes added by expanding entities and reading external DTD files,
+combined.
-The 'max_factor' value must be a non-NaN floating point value greater than
-or equal to 1.0. Amplification factors greater than 30,000 can be observed
-in the middle of parsing even with benign files in practice. In particular,
-the activation threshold should be carefully chosen to avoid false positives.
+The 'max_factor' value must be a non-NaN floating point value
+greater than or equal to 1.0. Amplification factors greater than
+30,000 can be observed in the middle of parsing even with benign
+files in practice. In particular, the activation threshold should
+be carefully chosen to avoid false positives.
Parser objects usually have a maximum amplification factor of 100,
-but the actual default value depends on the underlying Expat library.
+but the actual default value depends on the underlying Expat
+library.
[clinic start generated code]*/
static PyObject *
pyexpat_xmlparser_SetBillionLaughsAttackProtectionMaximumAmplification_impl(xmlparseobject *self,
PyTypeObject *cls,
float max_factor)
-/*[clinic end generated code: output=c590439eadf463fa input=cc1e97c1fd2bd950]*/
+/*[clinic end generated code: output=c590439eadf463fa input=d0f11971c5b9e98b]*/
{
return set_maximum_amplification(
self, cls, max_factor,
@@ -1342,7 +1346,6 @@ pyexpat_xmlparser_SetBillionLaughsAttackProtectionMaximumAmplification_impl(xmlp
#if XML_COMBINED_VERSION >= 20702
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
pyexpat.xmlparser.SetAllocTrackerActivationThreshold
cls: defining_class
@@ -1351,15 +1354,16 @@ pyexpat.xmlparser.SetAllocTrackerActivationThreshold
Sets the number of allocated bytes of dynamic memory needed to activate protection against disproportionate use of RAM.
-Parser objects usually have an allocation activation threshold of 64 MiB,
-but the actual default value depends on the underlying Expat library.
+Parser objects usually have an allocation activation threshold of
+64 MiB, but the actual default value depends on the underlying Expat
+library.
[clinic start generated code]*/
static PyObject *
pyexpat_xmlparser_SetAllocTrackerActivationThreshold_impl(xmlparseobject *self,
PyTypeObject *cls,
unsigned long long threshold)
-/*[clinic end generated code: output=bed7e93207ba08c5 input=b7a7a3e3d054286a]*/
+/*[clinic end generated code: output=bed7e93207ba08c5 input=4728360b545de87a]*/
{
return set_activation_threshold(
self, cls, threshold,
@@ -1371,7 +1375,6 @@ pyexpat_xmlparser_SetAllocTrackerActivationThreshold_impl(xmlparseobject *self,
#if XML_COMBINED_VERSION >= 20702
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
pyexpat.xmlparser.SetAllocTrackerMaximumAmplification
cls: defining_class
@@ -1380,25 +1383,27 @@ pyexpat.xmlparser.SetAllocTrackerMaximumAmplification
Sets the maximum amplification factor between direct input and bytes of dynamic memory allocated.
-The amplification factor is calculated as "allocated / direct" while parsing,
-where "direct" is the number of bytes read from the primary document in parsing
-and "allocated" is the number of bytes of dynamic memory allocated in the parser
-hierarchy.
+The amplification factor is calculated as "allocated / direct" while
+parsing, where "direct" is the number of bytes read from the primary
+document in parsing and "allocated" is the number of bytes of
+dynamic memory allocated in the parser hierarchy.
-The 'max_factor' value must be a non-NaN floating point value greater than
-or equal to 1.0. Amplification factors greater than 100.0 can be observed
-near the start of parsing even with benign files in practice. In particular,
-the activation threshold should be carefully chosen to avoid false positives.
+The 'max_factor' value must be a non-NaN floating point value
+greater than or equal to 1.0. Amplification factors greater than
+100.0 can be observed near the start of parsing even with benign
+files in practice. In particular, the activation threshold should
+be carefully chosen to avoid false positives.
Parser objects usually have a maximum amplification factor of 100,
-but the actual default value depends on the underlying Expat library.
+but the actual default value depends on the underlying Expat
+library.
[clinic start generated code]*/
static PyObject *
pyexpat_xmlparser_SetAllocTrackerMaximumAmplification_impl(xmlparseobject *self,
PyTypeObject *cls,
float max_factor)
-/*[clinic end generated code: output=6e44bd48c9b112a0 input=c6af7ccb76ae5c6b]*/
+/*[clinic end generated code: output=6e44bd48c9b112a0 input=dd23ea3ef2069b69]*/
{
return set_maximum_amplification(
self, cls, max_factor,
From 79937e3cf12ca9700da28389dd357014e9ae6a3b Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 24 May 2026 15:43:38 +0200
Subject: [PATCH 134/213] [3.15] gh-150285: Fix too long docstrings in the
sqlite3 module (GH-150290) (GH-150340)
(cherry picked from commit 0466560b310fa74c38270328d66d6a16df95ec34)
Co-authored-by: Serhiy Storchaka
---
Modules/_sqlite/blob.c | 26 ++++++-------
Modules/_sqlite/clinic/blob.c.h | 19 ++++-----
Modules/_sqlite/clinic/connection.c.h | 41 +++++++++++---------
Modules/_sqlite/connection.c | 56 +++++++++++++--------------
4 files changed, 72 insertions(+), 70 deletions(-)
diff --git a/Modules/_sqlite/blob.c b/Modules/_sqlite/blob.c
index 8dad94556236bd..2cc62751054278 100644
--- a/Modules/_sqlite/blob.c
+++ b/Modules/_sqlite/blob.c
@@ -166,7 +166,6 @@ read_multiple(pysqlite_Blob *self, Py_ssize_t length, Py_ssize_t offset)
/*[clinic input]
-@permit_long_docstring_body
_sqlite3.Blob.read as blob_read
length: int = -1
@@ -175,14 +174,14 @@ _sqlite3.Blob.read as blob_read
Read data at the current offset position.
-If the end of the blob is reached, the data up to end of file will be returned.
-When length is not specified, or is negative, Blob.read() will read until the
-end of the blob.
+If the end of the blob is reached, the data up to end of file will
+be returned. When length is not specified, or is negative,
+Blob.read() will read until the end of the blob.
[clinic start generated code]*/
static PyObject *
blob_read_impl(pysqlite_Blob *self, int length)
-/*[clinic end generated code: output=1fc99b2541360dde input=e5715bcddbcfca5a]*/
+/*[clinic end generated code: output=1fc99b2541360dde input=6b745ad37720e556]*/
{
if (!check_blob(self)) {
return NULL;
@@ -235,7 +234,6 @@ inner_write(pysqlite_Blob *self, const void *buf, Py_ssize_t len,
/*[clinic input]
-@permit_long_docstring_body
_sqlite3.Blob.write as blob_write
data: Py_buffer
@@ -243,13 +241,13 @@ _sqlite3.Blob.write as blob_write
Write data at the current offset.
-This function cannot change the blob length. Writing beyond the end of the
-blob will result in an exception being raised.
+This function cannot change the blob length. Writing beyond the end
+of the blob will result in an exception being raised.
[clinic start generated code]*/
static PyObject *
blob_write_impl(pysqlite_Blob *self, Py_buffer *data)
-/*[clinic end generated code: output=b34cf22601b570b2 input=203d3458f244814b]*/
+/*[clinic end generated code: output=b34cf22601b570b2 input=0d372cb0240a5d49]*/
{
if (!check_blob(self)) {
return NULL;
@@ -265,7 +263,6 @@ blob_write_impl(pysqlite_Blob *self, Py_buffer *data)
/*[clinic input]
-@permit_long_docstring_body
_sqlite3.Blob.seek as blob_seek
offset: int
@@ -274,14 +271,15 @@ _sqlite3.Blob.seek as blob_seek
Set the current access position to offset.
-The origin argument defaults to os.SEEK_SET (absolute blob positioning).
-Other values for origin are os.SEEK_CUR (seek relative to the current position)
-and os.SEEK_END (seek relative to the blob's end).
+The origin argument defaults to os.SEEK_SET (absolute blob
+positioning). Other values for origin are os.SEEK_CUR (seek
+relative to the current position) and os.SEEK_END (seek relative to
+the blob's end).
[clinic start generated code]*/
static PyObject *
blob_seek_impl(pysqlite_Blob *self, int offset, int origin)
-/*[clinic end generated code: output=854c5a0e208547a5 input=ee4d88e1dc0b1048]*/
+/*[clinic end generated code: output=854c5a0e208547a5 input=84aea1b6b48607dd]*/
{
if (!check_blob(self)) {
return NULL;
diff --git a/Modules/_sqlite/clinic/blob.c.h b/Modules/_sqlite/clinic/blob.c.h
index 921e7cbd7ffcab..929703257f04be 100644
--- a/Modules/_sqlite/clinic/blob.c.h
+++ b/Modules/_sqlite/clinic/blob.c.h
@@ -31,9 +31,9 @@ PyDoc_STRVAR(blob_read__doc__,
" length\n"
" Read length in bytes.\n"
"\n"
-"If the end of the blob is reached, the data up to end of file will be returned.\n"
-"When length is not specified, or is negative, Blob.read() will read until the\n"
-"end of the blob.");
+"If the end of the blob is reached, the data up to end of file will\n"
+"be returned. When length is not specified, or is negative,\n"
+"Blob.read() will read until the end of the blob.");
#define BLOB_READ_METHODDEF \
{"read", _PyCFunction_CAST(blob_read), METH_FASTCALL, blob_read__doc__},
@@ -70,8 +70,8 @@ PyDoc_STRVAR(blob_write__doc__,
"\n"
"Write data at the current offset.\n"
"\n"
-"This function cannot change the blob length. Writing beyond the end of the\n"
-"blob will result in an exception being raised.");
+"This function cannot change the blob length. Writing beyond the end\n"
+"of the blob will result in an exception being raised.");
#define BLOB_WRITE_METHODDEF \
{"write", (PyCFunction)blob_write, METH_O, blob_write__doc__},
@@ -105,9 +105,10 @@ PyDoc_STRVAR(blob_seek__doc__,
"\n"
"Set the current access position to offset.\n"
"\n"
-"The origin argument defaults to os.SEEK_SET (absolute blob positioning).\n"
-"Other values for origin are os.SEEK_CUR (seek relative to the current position)\n"
-"and os.SEEK_END (seek relative to the blob\'s end).");
+"The origin argument defaults to os.SEEK_SET (absolute blob\n"
+"positioning). Other values for origin are os.SEEK_CUR (seek\n"
+"relative to the current position) and os.SEEK_END (seek relative to\n"
+"the blob\'s end).");
#define BLOB_SEEK_METHODDEF \
{"seek", _PyCFunction_CAST(blob_seek), METH_FASTCALL, blob_seek__doc__},
@@ -211,4 +212,4 @@ blob_exit(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=f03f4ba622b67ae0 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=b0e3d38063739b17 input=a9049054013a1b77]*/
diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h
index abb864eb030757..b645bf3464bcea 100644
--- a/Modules/_sqlite/clinic/connection.c.h
+++ b/Modules/_sqlite/clinic/connection.c.h
@@ -685,13 +685,14 @@ PyDoc_STRVAR(pysqlite_connection_set_progress_handler__doc__,
"\n"
" progress_handler\n"
" A callable that takes no arguments.\n"
-" If the callable returns non-zero, the current query is terminated,\n"
-" and an exception is raised.\n"
+" If the callable returns non-zero, the current query is\n"
+" terminated, and an exception is raised.\n"
" n\n"
" The number of SQLite virtual machine instructions that are\n"
" executed between invocations of \'progress_handler\'.\n"
"\n"
-"If \'progress_handler\' is None or \'n\' is 0, the progress handler is disabled.");
+"If \'progress_handler\' is None or \'n\' is 0, the progress handler is\n"
+"disabled.");
#define PYSQLITE_CONNECTION_SET_PROGRESS_HANDLER_METHODDEF \
{"set_progress_handler", _PyCFunction_CAST(pysqlite_connection_set_progress_handler), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_progress_handler__doc__},
@@ -1303,10 +1304,10 @@ PyDoc_STRVAR(serialize__doc__,
" name\n"
" Which database to serialize.\n"
"\n"
-"For an ordinary on-disk database file, the serialization is just a copy of the\n"
-"disk file. For an in-memory database or a \"temp\" database, the serialization is\n"
-"the same sequence of bytes which would be written to disk if that database\n"
-"were backed up to disk.");
+"For an ordinary on-disk database file, the serialization is just\n"
+"a copy of the disk file. For an in-memory database or a \"temp\"\n"
+"database, the serialization is the same sequence of bytes which\n"
+"would be written to disk if that database were backed up to disk.");
#define SERIALIZE_METHODDEF \
{"serialize", _PyCFunction_CAST(serialize), METH_FASTCALL|METH_KEYWORDS, serialize__doc__},
@@ -1392,12 +1393,13 @@ PyDoc_STRVAR(deserialize__doc__,
" name\n"
" Which database to reopen with the deserialization.\n"
"\n"
-"The deserialize interface causes the database connection to disconnect from the\n"
-"target database, and then reopen it as an in-memory database based on the given\n"
-"serialized data.\n"
+"The deserialize interface causes the database connection to\n"
+"disconnect from the target database, and then reopen it as\n"
+"an in-memory database based on the given serialized data.\n"
"\n"
-"The deserialize interface will fail with SQLITE_BUSY if the database is\n"
-"currently in a read transaction or is involved in a backup operation.");
+"The deserialize interface will fail with SQLITE_BUSY if the database\n"
+"is currently in a read transaction or is involved in a backup\n"
+"operation.");
#define DESERIALIZE_METHODDEF \
{"deserialize", _PyCFunction_CAST(deserialize), METH_FASTCALL|METH_KEYWORDS, deserialize__doc__},
@@ -1518,7 +1520,8 @@ PyDoc_STRVAR(pysqlite_connection_exit__doc__,
"\n"
"Called when the connection is used as a context manager.\n"
"\n"
-"If there was any exception, a rollback takes place; otherwise we commit.");
+"If there was any exception, a rollback takes place; otherwise we\n"
+"commit.");
#define PYSQLITE_CONNECTION_EXIT_METHODDEF \
{"__exit__", _PyCFunction_CAST(pysqlite_connection_exit), METH_FASTCALL, pysqlite_connection_exit__doc__},
@@ -1556,12 +1559,12 @@ PyDoc_STRVAR(setlimit__doc__,
" category\n"
" The limit category to be set.\n"
" limit\n"
-" The new limit. If the new limit is a negative number, the limit is\n"
-" unchanged.\n"
+" The new limit. If the new limit is a negative number, the limit\n"
+" is unchanged.\n"
"\n"
-"Attempts to increase a limit above its hard upper bound are silently truncated\n"
-"to the hard upper bound. Regardless of whether or not the limit was changed,\n"
-"the prior value of the limit is returned.");
+"Attempts to increase a limit above its hard upper bound are silently\n"
+"truncated to the hard upper bound. Regardless of whether or not the\n"
+"limit was changed, the prior value of the limit is returned.");
#define SETLIMIT_METHODDEF \
{"setlimit", _PyCFunction_CAST(setlimit), METH_FASTCALL, setlimit__doc__},
@@ -1722,4 +1725,4 @@ getconfig(PyObject *self, PyObject *arg)
#ifndef DESERIALIZE_METHODDEF
#define DESERIALIZE_METHODDEF
#endif /* !defined(DESERIALIZE_METHODDEF) */
-/*[clinic end generated code: output=16d44c1d8a45e622 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=1418b72751ef68fc input=a9049054013a1b77]*/
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index bd44ff31b87c67..f596cc1ab36a19 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -1561,14 +1561,13 @@ pysqlite_connection_set_authorizer_impl(pysqlite_Connection *self,
}
/*[clinic input]
-@permit_long_docstring_body
_sqlite3.Connection.set_progress_handler as pysqlite_connection_set_progress_handler
cls: defining_class
progress_handler as callable: object
A callable that takes no arguments.
- If the callable returns non-zero, the current query is terminated,
- and an exception is raised.
+ If the callable returns non-zero, the current query is
+ terminated, and an exception is raised.
/
n: int
The number of SQLite virtual machine instructions that are
@@ -1576,14 +1575,15 @@ _sqlite3.Connection.set_progress_handler as pysqlite_connection_set_progress_han
Set progress handler callback.
-If 'progress_handler' is None or 'n' is 0, the progress handler is disabled.
+If 'progress_handler' is None or 'n' is 0, the progress handler is
+disabled.
[clinic start generated code]*/
static PyObject *
pysqlite_connection_set_progress_handler_impl(pysqlite_Connection *self,
PyTypeObject *cls,
PyObject *callable, int n)
-/*[clinic end generated code: output=0739957fd8034a50 input=3ecce6c915922ad4]*/
+/*[clinic end generated code: output=0739957fd8034a50 input=fd0d5abb004f370f]*/
{
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
return NULL;
@@ -1606,6 +1606,7 @@ pysqlite_connection_set_progress_handler_impl(pysqlite_Connection *self,
}
/*[clinic input]
+@permit_long_summary
_sqlite3.Connection.set_trace_callback as pysqlite_connection_set_trace_callback
cls: defining_class
@@ -1619,7 +1620,7 @@ static PyObject *
pysqlite_connection_set_trace_callback_impl(pysqlite_Connection *self,
PyTypeObject *cls,
PyObject *callable)
-/*[clinic end generated code: output=d91048c03bfcee05 input=f4f59bf2f87f2026]*/
+/*[clinic end generated code: output=d91048c03bfcee05 input=edfd7d890200a9cb]*/
{
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
return NULL;
@@ -2212,7 +2213,6 @@ pysqlite_connection_create_collation_impl(pysqlite_Connection *self,
#ifdef PY_SQLITE_HAVE_SERIALIZE
/*[clinic input]
-@permit_long_docstring_body
_sqlite3.Connection.serialize as serialize
*
@@ -2221,15 +2221,15 @@ _sqlite3.Connection.serialize as serialize
Serialize a database into a byte string.
-For an ordinary on-disk database file, the serialization is just a copy of the
-disk file. For an in-memory database or a "temp" database, the serialization is
-the same sequence of bytes which would be written to disk if that database
-were backed up to disk.
+For an ordinary on-disk database file, the serialization is just
+a copy of the disk file. For an in-memory database or a "temp"
+database, the serialization is the same sequence of bytes which
+would be written to disk if that database were backed up to disk.
[clinic start generated code]*/
static PyObject *
serialize_impl(pysqlite_Connection *self, const char *name)
-/*[clinic end generated code: output=97342b0e55239dd3 input=963e617cdf75c747]*/
+/*[clinic end generated code: output=97342b0e55239dd3 input=7e48654e8e082fa8]*/
{
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
return NULL;
@@ -2263,7 +2263,6 @@ serialize_impl(pysqlite_Connection *self, const char *name)
}
/*[clinic input]
-@permit_long_docstring_body
_sqlite3.Connection.deserialize as deserialize
data: Py_buffer(accept={buffer, str})
@@ -2275,18 +2274,19 @@ _sqlite3.Connection.deserialize as deserialize
Load a serialized database.
-The deserialize interface causes the database connection to disconnect from the
-target database, and then reopen it as an in-memory database based on the given
-serialized data.
+The deserialize interface causes the database connection to
+disconnect from the target database, and then reopen it as
+an in-memory database based on the given serialized data.
-The deserialize interface will fail with SQLITE_BUSY if the database is
-currently in a read transaction or is involved in a backup operation.
+The deserialize interface will fail with SQLITE_BUSY if the database
+is currently in a read transaction or is involved in a backup
+operation.
[clinic start generated code]*/
static PyObject *
deserialize_impl(pysqlite_Connection *self, Py_buffer *data,
const char *name)
-/*[clinic end generated code: output=e394c798b98bad89 input=037e94599aaa5b5c]*/
+/*[clinic end generated code: output=e394c798b98bad89 input=5d20e028d98c0686]*/
{
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
return NULL;
@@ -2359,13 +2359,14 @@ _sqlite3.Connection.__exit__ as pysqlite_connection_exit
Called when the connection is used as a context manager.
-If there was any exception, a rollback takes place; otherwise we commit.
+If there was any exception, a rollback takes place; otherwise we
+commit.
[clinic start generated code]*/
static PyObject *
pysqlite_connection_exit_impl(pysqlite_Connection *self, PyObject *exc_type,
PyObject *exc_value, PyObject *exc_tb)
-/*[clinic end generated code: output=0705200e9321202a input=bd66f1532c9c54a7]*/
+/*[clinic end generated code: output=0705200e9321202a input=8fdb0392ee6f3466]*/
{
int commit = 0;
PyObject* result;
@@ -2400,26 +2401,25 @@ pysqlite_connection_exit_impl(pysqlite_Connection *self, PyObject *exc_type,
}
/*[clinic input]
-@permit_long_docstring_body
_sqlite3.Connection.setlimit as setlimit
category: int
The limit category to be set.
limit: int
- The new limit. If the new limit is a negative number, the limit is
- unchanged.
+ The new limit. If the new limit is a negative number, the limit
+ is unchanged.
/
Set connection run-time limits.
-Attempts to increase a limit above its hard upper bound are silently truncated
-to the hard upper bound. Regardless of whether or not the limit was changed,
-the prior value of the limit is returned.
+Attempts to increase a limit above its hard upper bound are silently
+truncated to the hard upper bound. Regardless of whether or not the
+limit was changed, the prior value of the limit is returned.
[clinic start generated code]*/
static PyObject *
setlimit_impl(pysqlite_Connection *self, int category, int limit)
-/*[clinic end generated code: output=0d208213f8d68ccd input=bf06e06a21eb37e2]*/
+/*[clinic end generated code: output=0d208213f8d68ccd input=5c2e430091206677]*/
{
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
return NULL;
From 739552caae245ddafd42a3641765aa0961419bce Mon Sep 17 00:00:00 2001
From: Serhiy Storchaka
Date: Sun, 24 May 2026 16:53:29 +0300
Subject: [PATCH 135/213] [3.15] gh-150285: Fix too long docstrings in the os
module (GH-150296) (GH-150341)
(cherry picked from commit a5cb7c34dd25aaa639a512f0dbbaaa6c9e03f1a1)
---
Lib/os.py | 46 +--
Modules/clinic/posixmodule.c.h | 389 +++++++++++++-----------
Modules/posixmodule.c | 534 +++++++++++++++++----------------
3 files changed, 511 insertions(+), 458 deletions(-)
diff --git a/Lib/os.py b/Lib/os.py
index 1ca4648cc95c3e..a5e1d805556998 100644
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -222,14 +222,14 @@ def _add(str, fn):
def makedirs(name, mode=0o777, exist_ok=False, *, parent_mode=None):
"""makedirs(name [, mode=0o777][, exist_ok=False][, parent_mode=None])
- Super-mkdir; create a leaf directory and all intermediate ones. Works like
- mkdir, except that any intermediate path segment (not just the rightmost)
- will be created if it does not exist. If the target directory already
- exists, raise an OSError if exist_ok is False. Otherwise no exception is
- raised. If parent_mode is not None, it will be used as the mode for any
- newly-created, intermediate-level directories. Otherwise, intermediate
- directories are created with the default permissions (respecting umask).
- This is recursive.
+ Super-mkdir; create a leaf directory and all intermediate ones. Works
+ like mkdir, except that any intermediate path segment (not just the
+ rightmost) will be created if it does not exist. If the target
+ directory already exists, raise an OSError if exist_ok is False.
+ Otherwise no exception is raised. If parent_mode is not None, it will
+ be used as the mode for any newly-created, intermediate-level
+ directories. Otherwise, intermediate directories are created with the
+ default permissions (respecting umask). This is recursive.
"""
head, tail = path.split(name)
@@ -321,12 +321,12 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
dirpath, dirnames, filenames
dirpath is a string, the path to the directory. dirnames is a list of
- the names of the subdirectories in dirpath (including symlinks to directories,
- and excluding '.' and '..').
+ the names of the subdirectories in dirpath (including symlinks to
+ directories, and excluding '.' and '..').
filenames is a list of the names of the non-directory files in dirpath.
- Note that the names in the lists are just names, with no path components.
- To get a full path (which begins with top) to a file or directory in
- dirpath, do os.path.join(dirpath, name).
+ Note that the names in the lists are just names, with no path
+ components. To get a full path (which begins with top) to a file or
+ directory in dirpath, do os.path.join(dirpath, name).
If optional arg 'topdown' is true or not specified, the triple for a
directory is generated before the triples for any of its subdirectories
@@ -336,13 +336,13 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
When topdown is true, the caller can modify the dirnames list in-place
(e.g., via del or slice assignment), and walk will only recurse into the
- subdirectories whose names remain in dirnames; this can be used to prune the
- search, or to impose a specific order of visiting. Modifying dirnames when
- topdown is false has no effect on the behavior of os.walk(), since the
- directories in dirnames have already been generated by the time dirnames
- itself is generated. No matter the value of topdown, the list of
- subdirectories is retrieved before the tuples for the directory and its
- subdirectories are generated.
+ subdirectories whose names remain in dirnames; this can be used to prune
+ the search, or to impose a specific order of visiting. Modifying
+ dirnames when topdown is false has no effect on the behavior of
+ os.walk(), since the directories in dirnames have already been generated
+ by the time dirnames itself is generated. No matter the value of
+ topdown, the list of subdirectories is retrieved before the tuples for
+ the directory and its subdirectories are generated.
By default errors from the os.scandir() call are ignored. If
optional arg 'onerror' is specified, it should be a function; it
@@ -469,9 +469,9 @@ def fwalk(top=".", topdown=True, onerror=None, *, follow_symlinks=False, dir_fd=
The advantage of fwalk() over walk() is that it's safe against symlink
races (when follow_symlinks is False).
- If dir_fd is not None, it should be a file descriptor open to a directory,
- and top should be relative; top will then be relative to that directory.
- (dir_fd is always supported for fwalk.)
+ If dir_fd is not None, it should be a file descriptor open to
+ a directory, and top should be relative; top will then be relative to
+ that directory. (dir_fd is always supported for fwalk.)
Caution:
Since fwalk() yields file descriptors, those are only valid until the
diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h
index ad4c5dd1c9bc08..45e509d003085b 100644
--- a/Modules/clinic/posixmodule.c.h
+++ b/Modules/clinic/posixmodule.c.h
@@ -512,9 +512,9 @@ PyDoc_STRVAR(os_chdir__doc__,
"\n"
"Change the current working directory to the specified path.\n"
"\n"
-"path may always be specified as a string.\n"
-"On some platforms, path may also be specified as an open file descriptor.\n"
-"If this functionality is unavailable, using it raises an exception.");
+"path may always be specified as a string. On some platforms, path may\n"
+"also be specified as an open file descriptor. If this functionality is\n"
+"unavailable, using it raises an exception.");
#define OS_CHDIR_METHODDEF \
{"chdir", _PyCFunction_CAST(os_chdir), METH_FASTCALL|METH_KEYWORDS, os_chdir__doc__},
@@ -649,14 +649,15 @@ PyDoc_STRVAR(os_chmod__doc__,
"Change the access permissions of a file.\n"
"\n"
" path\n"
-" Path to be modified. May always be specified as a str, bytes, or a path-like object.\n"
-" On some platforms, path may also be specified as an open file descriptor.\n"
-" If this functionality is unavailable, using it raises an exception.\n"
+" Path to be modified. May always be specified as a str, bytes, or\n"
+" a path-like object. On some platforms, path may also be specified\n"
+" as an open file descriptor. If this functionality is unavailable,\n"
+" using it raises an exception.\n"
" mode\n"
" Operating-system mode bitfield.\n"
-" Be careful when using number literals for *mode*. The conventional UNIX notation for\n"
-" numeric modes uses an octal base, which needs to be indicated with a ``0o`` prefix in\n"
-" Python.\n"
+" Be careful when using number literals for *mode*. The conventional\n"
+" UNIX notation for numeric modes uses an octal base, which needs to\n"
+" be indicated with a ``0o`` prefix in Python.\n"
" dir_fd\n"
" If not None, it should be a file descriptor open to a directory,\n"
" and path should be relative; path will then be relative to that\n"
@@ -765,9 +766,9 @@ PyDoc_STRVAR(os_fchmod__doc__,
" The file descriptor of the file to be modified.\n"
" mode\n"
" Operating-system mode bitfield.\n"
-" Be careful when using number literals for *mode*. The conventional UNIX notation for\n"
-" numeric modes uses an octal base, which needs to be indicated with a ``0o`` prefix in\n"
-" Python.\n"
+" Be careful when using number literals for *mode*. The conventional\n"
+" UNIX notation for numeric modes uses an octal base, which needs to\n"
+" be indicated with a ``0o`` prefix in Python.\n"
"\n"
"Equivalent to os.chmod(fd, mode).");
@@ -841,8 +842,8 @@ PyDoc_STRVAR(os_lchmod__doc__,
"\n"
"Change the access permissions of a file, without following symbolic links.\n"
"\n"
-"If path is a symlink, this affects the link itself rather than the target.\n"
-"Equivalent to chmod(path, mode, follow_symlinks=False).\"");
+"If path is a symlink, this affects the link itself rather than the\n"
+"target. Equivalent to chmod(path, mode, follow_symlinks=False).");
#define OS_LCHMOD_METHODDEF \
{"lchmod", _PyCFunction_CAST(os_lchmod), METH_FASTCALL|METH_KEYWORDS, os_lchmod__doc__},
@@ -916,9 +917,9 @@ PyDoc_STRVAR(os_chflags__doc__,
"\n"
"Set file flags.\n"
"\n"
-"If follow_symlinks is False, and the last element of the path is a symbolic\n"
-" link, chflags will change flags on the symbolic link itself instead of the\n"
-" file the link points to.\n"
+"If follow_symlinks is False, and the last element of the path is\n"
+"a symbolic link, chflags() will change flags on the symbolic link itself\n"
+"instead of the file the link points to.\n"
"follow_symlinks may not be implemented on your platform. If it is\n"
"unavailable, using it will raise a NotImplementedError.");
@@ -1329,10 +1330,11 @@ PyDoc_STRVAR(os_chown__doc__,
"chown($module, /, path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n"
"--\n"
"\n"
-"Change the owner and group id of path to the numeric uid and gid.\\\n"
+"Change the owner and group id of path to the numeric uid and gid.\n"
"\n"
" path\n"
-" Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.\n"
+" Path to be examined; can be string, bytes, a path-like object, or\n"
+" open-file-descriptor int.\n"
" dir_fd\n"
" If not None, it should be a file descriptor open to a directory,\n"
" and path should be relative; path will then be relative to that\n"
@@ -1342,18 +1344,19 @@ PyDoc_STRVAR(os_chown__doc__,
" stat will examine the symbolic link itself instead of the file\n"
" the link points to.\n"
"\n"
-"path may always be specified as a string.\n"
-"On some platforms, path may also be specified as an open file descriptor.\n"
-" If this functionality is unavailable, using it raises an exception.\n"
-"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
-" and path should be relative; path will then be relative to that directory.\n"
-"If follow_symlinks is False, and the last element of the path is a symbolic\n"
-" link, chown will modify the symbolic link itself instead of the file the\n"
-" link points to.\n"
+"path may always be specified as a string. On some platforms, path may\n"
+"also be specified as an open file descriptor. If this functionality is\n"
+"unavailable, using it raises an exception.\n"
+"If dir_fd is not None, it should be a file descriptor open to\n"
+"a directory, and path should be relative; path will then be relative to\n"
+"that directory.\n"
+"If follow_symlinks is False, and the last element of the path is\n"
+"a symbolic link, chown will modify the symbolic link itself instead of\n"
+"the file the link points to.\n"
"It is an error to use dir_fd or follow_symlinks when specifying path as\n"
-" an open file descriptor.\n"
-"dir_fd and follow_symlinks may not be implemented on your platform.\n"
-" If they are unavailable, using them will raise a NotImplementedError.");
+"an open file descriptor.\n"
+"dir_fd and follow_symlinks may not be implemented on your platform. If\n"
+"they are unavailable, using them will raise a NotImplementedError.");
#define OS_CHOWN_METHODDEF \
{"chown", _PyCFunction_CAST(os_chown), METH_FASTCALL|METH_KEYWORDS, os_chown__doc__},
@@ -1641,14 +1644,15 @@ PyDoc_STRVAR(os_link__doc__,
"Create a hard link to a file.\n"
"\n"
"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n"
-" descriptor open to a directory, and the respective path string (src or dst)\n"
-" should be relative; the path will then be relative to that directory.\n"
+"descriptor open to a directory, and the respective path string (src or\n"
+"dst) should be relative; the path will then be relative to that\n"
+"directory.\n"
"If follow_symlinks is False, and the last element of src is a symbolic\n"
-" link, link will create a link to the symbolic link itself instead of the\n"
-" file the link points to.\n"
-"src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n"
-" platform. If they are unavailable, using them will raise a\n"
-" NotImplementedError.");
+"link, link will create a link to the symbolic link itself instead of the\n"
+"file the link points to.\n"
+"src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on\n"
+"your platform. If they are unavailable, using them will raise\n"
+"a NotImplementedError.");
#define OS_LINK_METHODDEF \
{"link", _PyCFunction_CAST(os_link), METH_FASTCALL|METH_KEYWORDS, os_link__doc__},
@@ -1750,13 +1754,13 @@ PyDoc_STRVAR(os_listdir__doc__,
"\n"
"Return a list containing the names of the files in the directory.\n"
"\n"
-"path can be specified as either str, bytes, or a path-like object. If path is bytes,\n"
-" the filenames returned will also be bytes; in all other circumstances\n"
-" the filenames returned will be str.\n"
+"path can be specified as either str, bytes, or a path-like object. If\n"
+"path is bytes, the filenames returned will also be bytes; in all other\n"
+"circumstances the filenames returned will be str.\n"
"If path is None, uses the path=\'.\'.\n"
-"On some platforms, path may also be specified as an open file descriptor;\\\n"
-" the file descriptor must refer to a directory.\n"
-" If this functionality is unavailable, using it raises NotImplementedError.\n"
+"On some platforms, path may also be specified as an open file\n"
+"descriptor; the file descriptor must refer to a directory. If this\n"
+"functionality is unavailable, using it raises NotImplementedError.\n"
"\n"
"The list is in arbitrary order. It does not include the special\n"
"entries \'.\' and \'..\' even if they are present in the directory.");
@@ -2709,13 +2713,14 @@ PyDoc_STRVAR(os_mkdir__doc__,
"\n"
"Create a directory.\n"
"\n"
-"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
-" and path should be relative; path will then be relative to that directory.\n"
-"dir_fd may not be implemented on your platform.\n"
-" If it is unavailable, using it will raise a NotImplementedError.\n"
+"If dir_fd is not None, it should be a file descriptor open to\n"
+"a directory, and path should be relative; path will then be relative to\n"
+"that directory.\n"
+"dir_fd may not be implemented on your platform. If it is unavailable,\n"
+"using it will raise a NotImplementedError.\n"
"\n"
-"The mode argument is ignored on Windows. Where it is used, the current umask\n"
-"value is first masked out.");
+"The mode argument is ignored on Windows. Where it is used, the current\n"
+"umask value is first masked out.");
#define OS_MKDIR_METHODDEF \
{"mkdir", _PyCFunction_CAST(os_mkdir), METH_FASTCALL|METH_KEYWORDS, os_mkdir__doc__},
@@ -2981,10 +2986,11 @@ PyDoc_STRVAR(os_rename__doc__,
"Rename a file or directory.\n"
"\n"
"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n"
-" descriptor open to a directory, and the respective path string (src or dst)\n"
-" should be relative; the path will then be relative to that directory.\n"
+"descriptor open to a directory, and the respective path string (src or\n"
+"dst) should be relative; the path will then be relative to that\n"
+"directory.\n"
"src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n"
-" If they are unavailable, using them will raise a NotImplementedError.");
+"If they are unavailable, using them will raise a NotImplementedError.");
#define OS_RENAME_METHODDEF \
{"rename", _PyCFunction_CAST(os_rename), METH_FASTCALL|METH_KEYWORDS, os_rename__doc__},
@@ -3075,10 +3081,11 @@ PyDoc_STRVAR(os_replace__doc__,
"Rename a file or directory, overwriting the destination.\n"
"\n"
"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n"
-" descriptor open to a directory, and the respective path string (src or dst)\n"
-" should be relative; the path will then be relative to that directory.\n"
+"descriptor open to a directory, and the respective path string (src or\n"
+"dst) should be relative; the path will then be relative to that\n"
+"directory.\n"
"src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n"
-" If they are unavailable, using them will raise a NotImplementedError.");
+"If they are unavailable, using them will raise a NotImplementedError.");
#define OS_REPLACE_METHODDEF \
{"replace", _PyCFunction_CAST(os_replace), METH_FASTCALL|METH_KEYWORDS, os_replace__doc__},
@@ -3168,10 +3175,11 @@ PyDoc_STRVAR(os_rmdir__doc__,
"\n"
"Remove a directory.\n"
"\n"
-"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
-" and path should be relative; path will then be relative to that directory.\n"
+"If dir_fd is not None, it should be a file descriptor open to\n"
+"a directory, and path should be relative; path will then be relative\n"
+"to that directory.\n"
"dir_fd may not be implemented on your platform.\n"
-" If it is unavailable, using it will raise a NotImplementedError.");
+"If it is unavailable, using it will raise a NotImplementedError.");
#define OS_RMDIR_METHODDEF \
{"rmdir", _PyCFunction_CAST(os_rmdir), METH_FASTCALL|METH_KEYWORDS, os_rmdir__doc__},
@@ -3426,10 +3434,11 @@ PyDoc_STRVAR(os_unlink__doc__,
"\n"
"Remove a file (same as remove()).\n"
"\n"
-"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
-" and path should be relative; path will then be relative to that directory.\n"
+"If dir_fd is not None, it should be a file descriptor open to\n"
+"a directory, and path should be relative; path will then be relative to\n"
+"that directory.\n"
"dir_fd may not be implemented on your platform.\n"
-" If it is unavailable, using it will raise a NotImplementedError.");
+"If it is unavailable, using it will raise a NotImplementedError.");
#define OS_UNLINK_METHODDEF \
{"unlink", _PyCFunction_CAST(os_unlink), METH_FASTCALL|METH_KEYWORDS, os_unlink__doc__},
@@ -3503,10 +3512,11 @@ PyDoc_STRVAR(os_remove__doc__,
"\n"
"Remove a file (same as unlink()).\n"
"\n"
-"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
-" and path should be relative; path will then be relative to that directory.\n"
+"If dir_fd is not None, it should be a file descriptor open to\n"
+"a directory, and path should be relative; path will then be relative\n"
+"to that directory.\n"
"dir_fd may not be implemented on your platform.\n"
-" If it is unavailable, using it will raise a NotImplementedError.");
+"If it is unavailable, using it will raise a NotImplementedError.");
#define OS_REMOVE_METHODDEF \
{"remove", _PyCFunction_CAST(os_remove), METH_FASTCALL|METH_KEYWORDS, os_remove__doc__},
@@ -3606,27 +3616,28 @@ PyDoc_STRVAR(os_utime__doc__,
"\n"
"Set the access and modified time of path.\n"
"\n"
-"path may always be specified as a string.\n"
-"On some platforms, path may also be specified as an open file descriptor.\n"
-" If this functionality is unavailable, using it raises an exception.\n"
+"path may always be specified as a string. On some platforms, path may\n"
+"also be specified as an open file descriptor. If this functionality is\n"
+"unavailable, using it raises an exception.\n"
"\n"
"If times is not None, it must be a tuple (atime, mtime);\n"
-" atime and mtime should be expressed as float seconds since the epoch.\n"
+"atime and mtime should be expressed as float seconds since the epoch.\n"
"If ns is specified, it must be a tuple (atime_ns, mtime_ns);\n"
-" atime_ns and mtime_ns should be expressed as integer nanoseconds\n"
-" since the epoch.\n"
+"atime_ns and mtime_ns should be expressed as integer nanoseconds\n"
+"since the epoch.\n"
"If times is None and ns is unspecified, utime uses the current time.\n"
"Specifying tuples for both times and ns is an error.\n"
"\n"
-"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
-" and path should be relative; path will then be relative to that directory.\n"
-"If follow_symlinks is False, and the last element of the path is a symbolic\n"
-" link, utime will modify the symbolic link itself instead of the file the\n"
-" link points to.\n"
-"It is an error to use dir_fd or follow_symlinks when specifying path\n"
-" as an open file descriptor.\n"
+"If dir_fd is not None, it should be a file descriptor open to\n"
+"a directory, and path should be relative; path will then be relative to\n"
+"that directory.\n"
+"If follow_symlinks is False, and the last element of the path is\n"
+"a symbolic link, utime will modify the symbolic link itself instead of\n"
+"the file the link points to.\n"
+"It is an error to use dir_fd or follow_symlinks when specifying path as\n"
+"an open file descriptor.\n"
"dir_fd and follow_symlinks may not be available on your platform.\n"
-" If they are unavailable, using them will raise a NotImplementedError.");
+"If they are unavailable, using them will raise a NotImplementedError.");
#define OS_UTIME_METHODDEF \
{"utime", _PyCFunction_CAST(os_utime), METH_FASTCALL|METH_KEYWORDS, os_utime__doc__},
@@ -3929,7 +3940,8 @@ PyDoc_STRVAR(os_posix_spawn__doc__,
" resetids\n"
" If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.\n"
" setsid\n"
-" If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.\n"
+" If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP\n"
+" will be activated.\n"
" setsigmask\n"
" The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.\n"
" setsigdef\n"
@@ -4082,7 +4094,8 @@ PyDoc_STRVAR(os_posix_spawnp__doc__,
" resetids\n"
" If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.\n"
" setsid\n"
-" If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.\n"
+" If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP\n"
+" will be activated.\n"
" setsigmask\n"
" The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.\n"
" setsigdef\n"
@@ -4953,8 +4966,8 @@ PyDoc_STRVAR(os_posix_openpt__doc__,
"Open and return a file descriptor for a master pseudo-terminal device.\n"
"\n"
"Performs a posix_openpt() C function call. The oflag argument is used to\n"
-"set file status flags and file access modes as specified in the manual page\n"
-"of posix_openpt() of your system.");
+"set file status flags and file access modes as specified in the manual\n"
+"page of posix_openpt() of your system.");
#define OS_POSIX_OPENPT_METHODDEF \
{"posix_openpt", (PyCFunction)os_posix_openpt, METH_O, os_posix_openpt__doc__},
@@ -5411,9 +5424,9 @@ PyDoc_STRVAR(os_initgroups__doc__,
"\n"
"Initialize the group access list.\n"
"\n"
-"Call the system initgroups() to initialize the group access list with all of\n"
-"the groups of which the specified username is a member, plus the specified\n"
-"group id.");
+"Call the system initgroups() to initialize the group access list with\n"
+"all of the groups of which the specified username is a member, plus the\n"
+"specified group id.");
#define OS_INITGROUPS_METHODDEF \
{"initgroups", _PyCFunction_CAST(os_initgroups), METH_FASTCALL, os_initgroups__doc__},
@@ -5457,9 +5470,9 @@ PyDoc_STRVAR(os_initgroups__doc__,
"\n"
"Initialize the group access list.\n"
"\n"
-"Call the system initgroups() to initialize the group access list with all of\n"
-"the groups of which the specified username is a member, plus the specified\n"
-"group id.");
+"Call the system initgroups() to initialize the group access list with\n"
+"all of the groups of which the specified username is a member, plus the\n"
+"specified group id.");
#define OS_INITGROUPS_METHODDEF \
{"initgroups", _PyCFunction_CAST(os_initgroups), METH_FASTCALL, os_initgroups__doc__},
@@ -5612,7 +5625,8 @@ PyDoc_STRVAR(os_getppid__doc__,
"Return the parent\'s process id.\n"
"\n"
"If the parent process has already exited, Windows machines will still\n"
-"return its id; others systems will return the id of the \'init\' process (1).");
+"return its id; others systems will return the id of the \'init\' proces\n"
+"(1).");
#define OS_GETPPID_METHODDEF \
{"getppid", (PyCFunction)os_getppid, METH_NOARGS, os_getppid__doc__},
@@ -6162,8 +6176,8 @@ PyDoc_STRVAR(os_waitid__doc__,
" Constructed from the ORing of one or more of WEXITED, WSTOPPED\n"
" or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n"
"\n"
-"Returns either waitid_result or None if WNOHANG is specified and there are\n"
-"no children in a waitable state.");
+"Returns either waitid_result or None if WNOHANG is specified and there\n"
+"are no children in a waitable state.");
#define OS_WAITID_METHODDEF \
{"waitid", _PyCFunction_CAST(os_waitid), METH_FASTCALL, os_waitid__doc__},
@@ -6324,8 +6338,8 @@ PyDoc_STRVAR(os_pidfd_open__doc__,
"\n"
"Return a file descriptor referring to the process *pid*.\n"
"\n"
-"The descriptor can be used to perform process management without races and\n"
-"signals.");
+"The descriptor can be used to perform process management without races\n"
+"and signals.");
#define OS_PIDFD_OPEN_METHODDEF \
{"pidfd_open", _PyCFunction_CAST(os_pidfd_open), METH_FASTCALL|METH_KEYWORDS, os_pidfd_open__doc__},
@@ -6549,8 +6563,9 @@ PyDoc_STRVAR(os_readlink__doc__,
"\n"
"Return a string representing the path to which the symbolic link points.\n"
"\n"
-"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
-"and path should be relative; path will then be relative to that directory.\n"
+"If dir_fd is not None, it should be a file descriptor open to\n"
+"a directory, and path should be relative; path will then be relative to\n"
+"that directory.\n"
"\n"
"dir_fd may not be implemented on your platform. If it is unavailable,\n"
"using it will raise a NotImplementedError.");
@@ -6632,14 +6647,15 @@ PyDoc_STRVAR(os_symlink__doc__,
"Create a symbolic link pointing to src named dst.\n"
"\n"
"target_is_directory is required on Windows if the target is to be\n"
-" interpreted as a directory. (On Windows, symlink requires\n"
-" Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n"
-" target_is_directory is ignored on non-Windows platforms.\n"
+"interpreted as a directory. (On Windows, symlink requires Windows 6.0\n"
+"or greater, and raises a NotImplementedError otherwise.)\n"
+"target_is_directory is ignored on non-Windows platforms.\n"
"\n"
-"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
-" and path should be relative; path will then be relative to that directory.\n"
-"dir_fd may not be implemented on your platform.\n"
-" If it is unavailable, using it will raise a NotImplementedError.");
+"If dir_fd is not None, it should be a file descriptor open to\n"
+"a directory, and path should be relative; path will then be relative\n"
+"to that directory.\n"
+"dir_fd may not be implemented on your platform. If it is unavailable,\n"
+"using it will raise a NotImplementedError.");
#define OS_SYMLINK_METHODDEF \
{"symlink", _PyCFunction_CAST(os_symlink), METH_FASTCALL|METH_KEYWORDS, os_symlink__doc__},
@@ -7307,10 +7323,11 @@ PyDoc_STRVAR(os_open__doc__,
"\n"
"Open a file for low level IO. Returns a file descriptor (integer).\n"
"\n"
-"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
-" and path should be relative; path will then be relative to that directory.\n"
-"dir_fd may not be implemented on your platform.\n"
-" If it is unavailable, using it will raise a NotImplementedError.");
+"If dir_fd is not None, it should be a file descriptor open to\n"
+"a directory, and path should be relative; path will then be relative to\n"
+"that directory.\n"
+"dir_fd may not be implemented on your platform. If it is unavailable,\n"
+"using it will raise a NotImplementedError.");
#define OS_OPEN_METHODDEF \
{"open", _PyCFunction_CAST(os_open), METH_FASTCALL|METH_KEYWORDS, os_open__doc__},
@@ -7684,7 +7701,8 @@ PyDoc_STRVAR(os_lseek__doc__,
" - SEEK_CUR: seek from the current file position.\n"
" - SEEK_END: seek from the end of the file.\n"
"\n"
-"The return value is the number of bytes relative to the beginning of the file.");
+"The return value is the number of bytes relative to the beginning of\n"
+"the file.");
#define OS_LSEEK_METHODDEF \
{"lseek", _PyCFunction_CAST(os_lseek), METH_FASTCALL, os_lseek__doc__},
@@ -7775,15 +7793,15 @@ PyDoc_STRVAR(os_readinto__doc__,
"\n"
"Read into a buffer object from a file descriptor.\n"
"\n"
-"The buffer should be mutable and bytes-like. On success, returns the number of\n"
-"bytes read. Less bytes may be read than the size of the buffer. The underlying\n"
-"system call will be retried when interrupted by a signal, unless the signal\n"
-"handler raises an exception. Other errors will not be retried and an error will\n"
-"be raised.\n"
+"The buffer should be mutable and bytes-like. On success, returns the\n"
+"number of bytes read. Less bytes may be read than the size of the\n"
+"buffer. The underlying system call will be retried when interrupted by\n"
+"a signal, unless the signal handler raises an exception. Other errors\n"
+"will not be retried and an error will be raised.\n"
"\n"
-"Returns 0 if *fd* is at end of file or if the provided *buffer* has length 0\n"
-"(which can be used to check for errors without reading data). Never returns\n"
-"negative.");
+"Returns 0 if *fd* is at end of file or if the provided *buffer* has\n"
+"length 0 (which can be used to check for errors without reading data).\n"
+"Never returns negative.");
#define OS_READINTO_METHODDEF \
{"readinto", _PyCFunction_CAST(os_readinto), METH_FASTCALL, os_readinto__doc__},
@@ -7938,14 +7956,15 @@ PyDoc_STRVAR(os_preadv__doc__,
"\n"
"Reads from a file descriptor into a number of mutable bytes-like objects.\n"
"\n"
-"Combines the functionality of readv() and pread(). As readv(), it will\n"
-"transfer data into each buffer until it is full and then move on to the next\n"
-"buffer in the sequence to hold the rest of the data. Its fourth argument,\n"
-"specifies the file offset at which the input operation is to be performed. It\n"
-"will return the total number of bytes read (which can be less than the total\n"
-"capacity of all the objects).\n"
+"Combines the functionality of readv() and pread(). As readv(), it will\n"
+"transfer data into each buffer until it is full and then move on to the\n"
+"next buffer in the sequence to hold the rest of the data. Its fourth\n"
+"argument, specifies the file offset at which the input operation is to\n"
+"be performed. It will return the total number of bytes read (which can\n"
+"be less than the total capacity of all the objects).\n"
"\n"
-"The flags argument contains a bitwise OR of zero or more of the following flags:\n"
+"The flags argument contains a bitwise OR of zero or more of the\n"
+"following flags:\n"
"\n"
"- RWF_HIPRI\n"
"- RWF_NOWAIT\n"
@@ -8679,14 +8698,16 @@ PyDoc_STRVAR(os_pwritev__doc__,
"\n"
"Writes the contents of bytes-like objects to a file descriptor at a given offset.\n"
"\n"
-"Combines the functionality of writev() and pwrite(). All buffers must be a sequence\n"
-"of bytes-like objects. Buffers are processed in array order. Entire contents of first\n"
-"buffer is written before proceeding to second, and so on. The operating system may\n"
-"set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.\n"
-"This function writes the contents of each object to the file descriptor and returns\n"
-"the total number of bytes written.\n"
+"Combines the functionality of writev() and pwrite(). All buffers must be\n"
+"a sequence of bytes-like objects. Buffers are processed in array order.\n"
+"Entire contents of first buffer is written before proceeding to second,\n"
+"and so on. The operating system may set a limit (sysconf() value\n"
+"SC_IOV_MAX) on the number of buffers that can be used.\n"
+"This function writes the contents of each object to the file descriptor\n"
+"and returns the total number of bytes written.\n"
"\n"
-"The flags argument contains a bitwise OR of zero or more of the following flags:\n"
+"The flags argument contains a bitwise OR of zero or more of the\n"
+"following flags:\n"
"\n"
"- RWF_DSYNC\n"
"- RWF_SYNC\n"
@@ -9001,10 +9022,11 @@ PyDoc_STRVAR(os_mkfifo__doc__,
"\n"
"Create a \"fifo\" (a POSIX named pipe).\n"
"\n"
-"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
-" and path should be relative; path will then be relative to that directory.\n"
-"dir_fd may not be implemented on your platform.\n"
-" If it is unavailable, using it will raise a NotImplementedError.");
+"If dir_fd is not None, it should be a file descriptor open to\n"
+"a directory, and path should be relative; path will then be relative to\n"
+"that directory.\n"
+"dir_fd may not be implemented on your platform. If it is unavailable,\n"
+"using it will raise a NotImplementedError.");
#define OS_MKFIFO_METHODDEF \
{"mkfifo", _PyCFunction_CAST(os_mkfifo), METH_FASTCALL|METH_KEYWORDS, os_mkfifo__doc__},
@@ -9096,17 +9118,18 @@ PyDoc_STRVAR(os_mknod__doc__,
"\n"
"Create a node in the file system.\n"
"\n"
-"Create a node in the file system (file, device special file or named pipe)\n"
-"at path. mode specifies both the permissions to use and the\n"
+"Create a node in the file system (file, device special file or named\n"
+"pipe) at path. mode specifies both the permissions to use and the\n"
"type of node to be created, being combined (bitwise OR) with one of\n"
-"S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,\n"
-"device defines the newly created device special file (probably using\n"
-"os.makedev()). Otherwise device is ignored.\n"
+"S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set\n"
+"on mode, device defines the newly created device special file (probably\n"
+"using os.makedev()). Otherwise device is ignored.\n"
"\n"
-"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
-" and path should be relative; path will then be relative to that directory.\n"
-"dir_fd may not be implemented on your platform.\n"
-" If it is unavailable, using it will raise a NotImplementedError.");
+"If dir_fd is not None, it should be a file descriptor open to\n"
+"a directory, and path should be relative; path will then be relative\n"
+"to that directory.\n"
+"dir_fd may not be implemented on your platform. If it is unavailable,\n"
+"using it will raise a NotImplementedError.");
#define OS_MKNOD_METHODDEF \
{"mknod", _PyCFunction_CAST(os_mknod), METH_FASTCALL|METH_KEYWORDS, os_mknod__doc__},
@@ -9352,8 +9375,9 @@ PyDoc_STRVAR(os_truncate__doc__,
"\n"
"Truncate a file, specified by path, to a specific length.\n"
"\n"
-"On some platforms, path may also be specified as an open file descriptor.\n"
-" If this functionality is unavailable, using it raises an exception.");
+"On some platforms, path may also be specified as an open file\n"
+"descriptor. If this functionality is unavailable, using it raises\n"
+"an exception.");
#define OS_TRUNCATE_METHODDEF \
{"truncate", _PyCFunction_CAST(os_truncate), METH_FASTCALL|METH_KEYWORDS, os_truncate__doc__},
@@ -9427,7 +9451,8 @@ PyDoc_STRVAR(os_posix_fallocate__doc__,
"Ensure a file has allocated at least a particular number of bytes on disk.\n"
"\n"
"Ensure that the file specified by fd encompasses a range of bytes\n"
-"starting at offset bytes from the beginning and continuing for length bytes.");
+"starting at offset bytes from the beginning and continuing for length\n"
+"bytes.");
#define OS_POSIX_FALLOCATE_METHODDEF \
{"posix_fallocate", _PyCFunction_CAST(os_posix_fallocate), METH_FASTCALL, os_posix_fallocate__doc__},
@@ -9473,8 +9498,8 @@ PyDoc_STRVAR(os_posix_fadvise__doc__,
"\n"
"Announce an intention to access data in a specific pattern.\n"
"\n"
-"Announce an intention to access data in a specific pattern, thus allowing\n"
-"the kernel to make optimizations.\n"
+"Announce an intention to access data in a specific pattern, thus\n"
+"allowing the kernel to make optimizations.\n"
"The advice applies to the region of the file specified by fd starting at\n"
"offset and continuing for length bytes.\n"
"advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n"
@@ -10296,8 +10321,9 @@ PyDoc_STRVAR(os_statvfs__doc__,
"Perform a statvfs system call on the given path.\n"
"\n"
"path may always be specified as a string.\n"
-"On some platforms, path may also be specified as an open file descriptor.\n"
-" If this functionality is unavailable, using it raises an exception.");
+"On some platforms, path may also be specified as an open file\n"
+"descriptor. If this functionality is unavailable, using it raises\n"
+"an exception.");
#define OS_STATVFS_METHODDEF \
{"statvfs", _PyCFunction_CAST(os_statvfs), METH_FASTCALL|METH_KEYWORDS, os_statvfs__doc__},
@@ -10480,8 +10506,9 @@ PyDoc_STRVAR(os_pathconf__doc__,
"Return the configuration limit name for the file or directory path.\n"
"\n"
"If there is no limit, return -1.\n"
-"On some platforms, path may also be specified as an open file descriptor.\n"
-" If this functionality is unavailable, using it raises an exception.");
+"On some platforms, path may also be specified as an open file\n"
+"descriptor. If this functionality is unavailable, using it raises\n"
+"an exception.");
#define OS_PATHCONF_METHODDEF \
{"pathconf", _PyCFunction_CAST(os_pathconf), METH_FASTCALL|METH_KEYWORDS, os_pathconf__doc__},
@@ -10624,8 +10651,8 @@ PyDoc_STRVAR(os_abort__doc__,
"\n"
"Abort the interpreter immediately.\n"
"\n"
-"This function \'dumps core\' or otherwise fails in the hardest way possible\n"
-"on the hosting operating system. This function never returns.");
+"This function \'dumps core\' or otherwise fails in the hardest way\n"
+"possible on the hosting operating system. This function never returns.");
#define OS_ABORT_METHODDEF \
{"abort", (PyCFunction)os_abort, METH_NOARGS, os_abort__doc__},
@@ -11013,10 +11040,11 @@ PyDoc_STRVAR(os_getxattr__doc__,
"\n"
"Return the value of extended attribute attribute on path.\n"
"\n"
-"path may be either a string, a path-like object, or an open file descriptor.\n"
-"If follow_symlinks is False, and the last element of the path is a symbolic\n"
-" link, getxattr will examine the symbolic link itself instead of the file\n"
-" the link points to.");
+"path may be either a string, a path-like object, or an open file\n"
+"descriptor.\n"
+"If follow_symlinks is False, and the last element of the path is\n"
+"a symbolic link, getxattr will examine the symbolic link itself\n"
+"instead of the file the link points to.");
#define OS_GETXATTR_METHODDEF \
{"getxattr", _PyCFunction_CAST(os_getxattr), METH_FASTCALL|METH_KEYWORDS, os_getxattr__doc__},
@@ -11103,10 +11131,11 @@ PyDoc_STRVAR(os_setxattr__doc__,
"\n"
"Set extended attribute attribute on path to value.\n"
"\n"
-"path may be either a string, a path-like object, or an open file descriptor.\n"
-"If follow_symlinks is False, and the last element of the path is a symbolic\n"
-" link, setxattr will modify the symbolic link itself instead of the file\n"
-" the link points to.");
+"path may be either a string, a path-like object, or an open file\n"
+"descriptor.\n"
+"If follow_symlinks is False, and the last element of the path is\n"
+"a symbolic link, setxattr will modify the symbolic link itself instead\n"
+"of the file the link points to.");
#define OS_SETXATTR_METHODDEF \
{"setxattr", _PyCFunction_CAST(os_setxattr), METH_FASTCALL|METH_KEYWORDS, os_setxattr__doc__},
@@ -11214,10 +11243,11 @@ PyDoc_STRVAR(os_removexattr__doc__,
"\n"
"Remove extended attribute attribute on path.\n"
"\n"
-"path may be either a string, a path-like object, or an open file descriptor.\n"
-"If follow_symlinks is False, and the last element of the path is a symbolic\n"
-" link, removexattr will modify the symbolic link itself instead of the file\n"
-" the link points to.");
+"path may be either a string, a path-like object, or an open file\n"
+"descriptor.\n"
+"If follow_symlinks is False, and the last element of the path is\n"
+"a symbolic link, removexattr will modify the symbolic link itself\n"
+"instead of the file the link points to.");
#define OS_REMOVEXATTR_METHODDEF \
{"removexattr", _PyCFunction_CAST(os_removexattr), METH_FASTCALL|METH_KEYWORDS, os_removexattr__doc__},
@@ -11303,11 +11333,12 @@ PyDoc_STRVAR(os_listxattr__doc__,
"\n"
"Return a list of extended attributes on path.\n"
"\n"
-"path may be either None, a string, a path-like object, or an open file descriptor.\n"
-"if path is None, listxattr will examine the current directory.\n"
-"If follow_symlinks is False, and the last element of the path is a symbolic\n"
-" link, listxattr will examine the symbolic link itself instead of the file\n"
-" the link points to.");
+"path may be either None, a string, a path-like object, or an open file\n"
+"descriptor. If path is None, listxattr will examine the current\n"
+"directory.\n"
+"If follow_symlinks is False, and the last element of the path is\n"
+"a symbolic link, listxattr will examine the symbolic link itself instead\n"
+"of the file the link points to.");
#define OS_LISTXATTR_METHODDEF \
{"listxattr", _PyCFunction_CAST(os_listxattr), METH_FASTCALL|METH_KEYWORDS, os_listxattr__doc__},
@@ -12329,9 +12360,9 @@ PyDoc_STRVAR(os_scandir__doc__,
"\n"
"Return an iterator of DirEntry objects for given path.\n"
"\n"
-"path can be specified as either str, bytes, or a path-like object. If path\n"
-"is bytes, the names of yielded DirEntry objects will also be bytes; in\n"
-"all other circumstances they will be str.\n"
+"path can be specified as either str, bytes, or a path-like object. If\n"
+"path is bytes, the names of yielded DirEntry objects will also be bytes;\n"
+"in all other circumstances they will be str.\n"
"\n"
"If path is None, uses the path=\'.\'.");
@@ -12403,9 +12434,9 @@ PyDoc_STRVAR(os_fspath__doc__,
"\n"
"Return the file system path representation of the object.\n"
"\n"
-"If the object is str or bytes, then allow it to pass through as-is. If the\n"
-"object defines __fspath__(), then return the result of that method. All other\n"
-"types raise a TypeError.");
+"If the object is str or bytes, then allow it to pass through as-is. If\n"
+"the object defines __fspath__(), then return the result of that method.\n"
+"All other types raise a TypeError.");
#define OS_FSPATH_METHODDEF \
{"fspath", _PyCFunction_CAST(os_fspath), METH_FASTCALL|METH_KEYWORDS, os_fspath__doc__},
@@ -12699,8 +12730,8 @@ PyDoc_STRVAR(os_waitstatus_to_exitcode__doc__,
"On Windows, return status shifted right by 8 bits.\n"
"\n"
"On Unix, if the process is being traced or if waitpid() was called with\n"
-"WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.\n"
-"This function must not be called if WIFSTOPPED(status) is true.");
+"WUNTRACED option, the caller must first check if WIFSTOPPED(status) is\n"
+"true. This function must not be called if WIFSTOPPED(status) is true.");
#define OS_WAITSTATUS_TO_EXITCODE_METHODDEF \
{"waitstatus_to_exitcode", _PyCFunction_CAST(os_waitstatus_to_exitcode), METH_FASTCALL|METH_KEYWORDS, os_waitstatus_to_exitcode__doc__},
@@ -13611,4 +13642,4 @@ os__emscripten_log(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py
#ifndef OS__EMSCRIPTEN_LOG_METHODDEF
#define OS__EMSCRIPTEN_LOG_METHODDEF
#endif /* !defined(OS__EMSCRIPTEN_LOG_METHODDEF) */
-/*[clinic end generated code: output=e709b8b783fbc261 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=d6889ab281d7676f input=a9049054013a1b77]*/
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 5bd53c2146a822..4f745c504a066a 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -2365,7 +2365,7 @@ PyDoc_STRVAR(stat_result__doc__,
"stat_result: Result from stat, fstat, or lstat.\n\n\
This object may be accessed either as a tuple of\n\
(mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
-or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
+or via the attributes st_mode, st_ino, st_dev, st_nlink, and so on.\n\
\n\
Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
or st_flags, they are available as attributes only.\n\
@@ -3925,14 +3925,14 @@ os.chdir
Change the current working directory to the specified path.
-path may always be specified as a string.
-On some platforms, path may also be specified as an open file descriptor.
-If this functionality is unavailable, using it raises an exception.
+path may always be specified as a string. On some platforms, path may
+also be specified as an open file descriptor. If this functionality is
+unavailable, using it raises an exception.
[clinic start generated code]*/
static PyObject *
os_chdir_impl(PyObject *module, path_t *path)
-/*[clinic end generated code: output=3be6400eee26eaae input=a74ceab5d72adf74]*/
+/*[clinic end generated code: output=3be6400eee26eaae input=64673c342e4369f1]*/
{
int result;
@@ -4045,15 +4045,16 @@ win32_fchmod(int fd, int mode)
os.chmod
path: path_t(allow_fd='PATH_HAVE_FCHMOD')
- Path to be modified. May always be specified as a str, bytes, or a path-like object.
- On some platforms, path may also be specified as an open file descriptor.
- If this functionality is unavailable, using it raises an exception.
+ Path to be modified. May always be specified as a str, bytes, or
+ a path-like object. On some platforms, path may also be specified
+ as an open file descriptor. If this functionality is unavailable,
+ using it raises an exception.
mode: int
Operating-system mode bitfield.
- Be careful when using number literals for *mode*. The conventional UNIX notation for
- numeric modes uses an octal base, which needs to be indicated with a ``0o`` prefix in
- Python.
+ Be careful when using number literals for *mode*. The conventional
+ UNIX notation for numeric modes uses an octal base, which needs to
+ be indicated with a ``0o`` prefix in Python.
*
@@ -4080,7 +4081,7 @@ dir_fd and follow_symlinks may not be implemented on your platform.
static PyObject *
os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
int follow_symlinks)
-/*[clinic end generated code: output=5cf6a94915cc7bff input=fcf115d174b9f3d8]*/
+/*[clinic end generated code: output=5cf6a94915cc7bff input=7b6e2eeadd8bf199]*/
{
int result;
@@ -4216,9 +4217,9 @@ os.fchmod
The file descriptor of the file to be modified.
mode: int
Operating-system mode bitfield.
- Be careful when using number literals for *mode*. The conventional UNIX notation for
- numeric modes uses an octal base, which needs to be indicated with a ``0o`` prefix in
- Python.
+ Be careful when using number literals for *mode*. The conventional
+ UNIX notation for numeric modes uses an octal base, which needs to
+ be indicated with a ``0o`` prefix in Python.
Change the access permissions of the file given by file descriptor fd.
@@ -4227,7 +4228,7 @@ Equivalent to os.chmod(fd, mode).
static PyObject *
os_fchmod_impl(PyObject *module, int fd, int mode)
-/*[clinic end generated code: output=afd9bc05b4e426b3 input=b5594618bbbc22df]*/
+/*[clinic end generated code: output=afd9bc05b4e426b3 input=d24331f9fdc17f49]*/
{
int res;
@@ -4261,6 +4262,7 @@ os_fchmod_impl(PyObject *module, int fd, int mode)
#if defined(HAVE_LCHMOD) || defined(MS_WINDOWS)
/*[clinic input]
+@permit_long_summary
os.lchmod
path: path_t
@@ -4268,13 +4270,13 @@ os.lchmod
Change the access permissions of a file, without following symbolic links.
-If path is a symlink, this affects the link itself rather than the target.
-Equivalent to chmod(path, mode, follow_symlinks=False)."
+If path is a symlink, this affects the link itself rather than the
+target. Equivalent to chmod(path, mode, follow_symlinks=False).
[clinic start generated code]*/
static PyObject *
os_lchmod_impl(PyObject *module, path_t *path, int mode)
-/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
+/*[clinic end generated code: output=082344022b51a1d5 input=13110fb62911b015]*/
{
int res;
if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) {
@@ -4312,9 +4314,9 @@ os.chflags
Set file flags.
-If follow_symlinks is False, and the last element of the path is a symbolic
- link, chflags will change flags on the symbolic link itself instead of the
- file the link points to.
+If follow_symlinks is False, and the last element of the path is
+a symbolic link, chflags() will change flags on the symbolic link itself
+instead of the file the link points to.
follow_symlinks may not be implemented on your platform. If it is
unavailable, using it will raise a NotImplementedError.
@@ -4323,7 +4325,7 @@ unavailable, using it will raise a NotImplementedError.
static PyObject *
os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
int follow_symlinks)
-/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
+/*[clinic end generated code: output=85571c6737661ce9 input=31391927707be1de]*/
{
int result;
@@ -4473,7 +4475,8 @@ os_fdatasync_impl(PyObject *module, int fd)
os.chown
path : path_t(allow_fd='PATH_HAVE_FCHOWN')
- Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
+ Path to be examined; can be string, bytes, a path-like object, or
+ open-file-descriptor int.
uid: uid_t
@@ -4481,7 +4484,7 @@ os.chown
*
- dir_fd : dir_fd(requires='fchownat') = None
+ dir_fd: dir_fd(requires='fchownat') = None
If not None, it should be a file descriptor open to a directory,
and path should be relative; path will then be relative to that
directory.
@@ -4491,27 +4494,28 @@ os.chown
stat will examine the symbolic link itself instead of the file
the link points to.
-Change the owner and group id of path to the numeric uid and gid.\
+Change the owner and group id of path to the numeric uid and gid.
-path may always be specified as a string.
-On some platforms, path may also be specified as an open file descriptor.
- If this functionality is unavailable, using it raises an exception.
-If dir_fd is not None, it should be a file descriptor open to a directory,
- and path should be relative; path will then be relative to that directory.
-If follow_symlinks is False, and the last element of the path is a symbolic
- link, chown will modify the symbolic link itself instead of the file the
- link points to.
+path may always be specified as a string. On some platforms, path may
+also be specified as an open file descriptor. If this functionality is
+unavailable, using it raises an exception.
+If dir_fd is not None, it should be a file descriptor open to
+a directory, and path should be relative; path will then be relative to
+that directory.
+If follow_symlinks is False, and the last element of the path is
+a symbolic link, chown will modify the symbolic link itself instead of
+the file the link points to.
It is an error to use dir_fd or follow_symlinks when specifying path as
- an open file descriptor.
-dir_fd and follow_symlinks may not be implemented on your platform.
- If they are unavailable, using them will raise a NotImplementedError.
+an open file descriptor.
+dir_fd and follow_symlinks may not be implemented on your platform. If
+they are unavailable, using them will raise a NotImplementedError.
[clinic start generated code]*/
static PyObject *
os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
int dir_fd, int follow_symlinks)
-/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
+/*[clinic end generated code: output=4beadab0db5f70cd input=509c91b7a0e72f52]*/
{
int result;
@@ -4795,7 +4799,6 @@ os_getcwdb_impl(PyObject *module)
#ifdef HAVE_LINK
/*[clinic input]
-@permit_long_docstring_body
os.link
src : path_t
@@ -4808,20 +4811,21 @@ os.link
Create a hard link to a file.
If either src_dir_fd or dst_dir_fd is not None, it should be a file
- descriptor open to a directory, and the respective path string (src or dst)
- should be relative; the path will then be relative to that directory.
+descriptor open to a directory, and the respective path string (src or
+dst) should be relative; the path will then be relative to that
+directory.
If follow_symlinks is False, and the last element of src is a symbolic
- link, link will create a link to the symbolic link itself instead of the
- file the link points to.
-src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
- platform. If they are unavailable, using them will raise a
- NotImplementedError.
+link, link will create a link to the symbolic link itself instead of the
+file the link points to.
+src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on
+your platform. If they are unavailable, using them will raise
+a NotImplementedError.
[clinic start generated code]*/
static PyObject *
os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
int dst_dir_fd, int follow_symlinks)
-/*[clinic end generated code: output=7f00f6007fd5269a input=e2a50a6497050e44]*/
+/*[clinic end generated code: output=7f00f6007fd5269a input=a28e6866fbd20a01]*/
{
#ifdef MS_WINDOWS
BOOL result = FALSE;
@@ -5115,30 +5119,28 @@ _posix_listdir(path_t *path, PyObject *list)
/*[clinic input]
-@permit_long_docstring_body
os.listdir
path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Return a list containing the names of the files in the directory.
-path can be specified as either str, bytes, or a path-like object. If path is bytes,
- the filenames returned will also be bytes; in all other circumstances
- the filenames returned will be str.
+path can be specified as either str, bytes, or a path-like object. If
+path is bytes, the filenames returned will also be bytes; in all other
+circumstances the filenames returned will be str.
If path is None, uses the path='.'.
-On some platforms, path may also be specified as an open file descriptor;\
- the file descriptor must refer to a directory.
- If this functionality is unavailable, using it raises NotImplementedError.
+On some platforms, path may also be specified as an open file
+descriptor; the file descriptor must refer to a directory. If this
+functionality is unavailable, using it raises NotImplementedError.
The list is in arbitrary order. It does not include the special
entries '.' and '..' even if they are present in the directory.
-
[clinic start generated code]*/
static PyObject *
os_listdir_impl(PyObject *module, path_t *path)
-/*[clinic end generated code: output=293045673fcd1a75 input=0bd1728387391b9a]*/
+/*[clinic end generated code: output=293045673fcd1a75 input=4eefe7c6a42ec9b2]*/
{
if (PySys_Audit("os.listdir", "O",
path->object ? path->object : Py_None) < 0) {
@@ -5597,6 +5599,7 @@ os__getfinalpathname_impl(PyObject *module, path_t *path)
}
/*[clinic input]
+@permit_long_summary
os._findfirstfile
path: path_t
/
@@ -5605,7 +5608,7 @@ A function to get the real file name without accessing the file in Windows.
static PyObject *
os__findfirstfile_impl(PyObject *module, path_t *path)
-/*[clinic end generated code: output=106dd3f0779c83dd input=0734dff70f60e1a8]*/
+/*[clinic end generated code: output=106dd3f0779c83dd input=48c319aaa48d05d4]*/
{
PyObject *result;
HANDLE hFindFile;
@@ -6159,22 +6162,21 @@ os.mkdir
dir_fd : dir_fd(requires='mkdirat') = None
-# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
-
Create a directory.
-If dir_fd is not None, it should be a file descriptor open to a directory,
- and path should be relative; path will then be relative to that directory.
-dir_fd may not be implemented on your platform.
- If it is unavailable, using it will raise a NotImplementedError.
+If dir_fd is not None, it should be a file descriptor open to
+a directory, and path should be relative; path will then be relative to
+that directory.
+dir_fd may not be implemented on your platform. If it is unavailable,
+using it will raise a NotImplementedError.
-The mode argument is ignored on Windows. Where it is used, the current umask
-value is first masked out.
+The mode argument is ignored on Windows. Where it is used, the current
+umask value is first masked out.
[clinic start generated code]*/
static PyObject *
os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
-/*[clinic end generated code: output=a70446903abe821f input=a61722e1576fab03]*/
+/*[clinic end generated code: output=a70446903abe821f input=30270d369599634b]*/
{
int result;
#ifdef MS_WINDOWS
@@ -6428,7 +6430,6 @@ internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is
/*[clinic input]
-@permit_long_docstring_body
os.rename
src : path_t
@@ -6440,38 +6441,39 @@ os.rename
Rename a file or directory.
If either src_dir_fd or dst_dir_fd is not None, it should be a file
- descriptor open to a directory, and the respective path string (src or dst)
- should be relative; the path will then be relative to that directory.
+descriptor open to a directory, and the respective path string (src or
+dst) should be relative; the path will then be relative to that
+directory.
src_dir_fd and dst_dir_fd, may not be implemented on your platform.
- If they are unavailable, using them will raise a NotImplementedError.
+If they are unavailable, using them will raise a NotImplementedError.
[clinic start generated code]*/
static PyObject *
os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
int dst_dir_fd)
-/*[clinic end generated code: output=59e803072cf41230 input=11aae8c091162766]*/
+/*[clinic end generated code: output=59e803072cf41230 input=7d320d687c715fd6]*/
{
return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
}
/*[clinic input]
-@permit_long_docstring_body
os.replace = os.rename
Rename a file or directory, overwriting the destination.
If either src_dir_fd or dst_dir_fd is not None, it should be a file
- descriptor open to a directory, and the respective path string (src or dst)
- should be relative; the path will then be relative to that directory.
+descriptor open to a directory, and the respective path string (src or
+dst) should be relative; the path will then be relative to that
+directory.
src_dir_fd and dst_dir_fd, may not be implemented on your platform.
- If they are unavailable, using them will raise a NotImplementedError.
+If they are unavailable, using them will raise a NotImplementedError.
[clinic start generated code]*/
static PyObject *
os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
int dst_dir_fd)
-/*[clinic end generated code: output=1968c02e7857422b input=78d6c8087e90994c]*/
+/*[clinic end generated code: output=1968c02e7857422b input=44ed6b762d5953fc]*/
{
return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
}
@@ -6486,15 +6488,16 @@ os.rmdir
Remove a directory.
-If dir_fd is not None, it should be a file descriptor open to a directory,
- and path should be relative; path will then be relative to that directory.
+If dir_fd is not None, it should be a file descriptor open to
+a directory, and path should be relative; path will then be relative
+to that directory.
dir_fd may not be implemented on your platform.
- If it is unavailable, using it will raise a NotImplementedError.
+If it is unavailable, using it will raise a NotImplementedError.
[clinic start generated code]*/
static PyObject *
os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
-/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
+/*[clinic end generated code: output=080eb54f506e8301 input=84325211e33a98e0]*/
{
int result;
#ifdef HAVE_UNLINKAT
@@ -6665,16 +6668,17 @@ os.unlink
Remove a file (same as remove()).
-If dir_fd is not None, it should be a file descriptor open to a directory,
- and path should be relative; path will then be relative to that directory.
+If dir_fd is not None, it should be a file descriptor open to
+a directory, and path should be relative; path will then be relative to
+that directory.
dir_fd may not be implemented on your platform.
- If it is unavailable, using it will raise a NotImplementedError.
+If it is unavailable, using it will raise a NotImplementedError.
[clinic start generated code]*/
static PyObject *
os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
-/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
+/*[clinic end generated code: output=621797807b9963b1 input=1a2ef2579207eab1]*/
{
int result;
#ifdef HAVE_UNLINKAT
@@ -6726,15 +6730,16 @@ os.remove = os.unlink
Remove a file (same as unlink()).
-If dir_fd is not None, it should be a file descriptor open to a directory,
- and path should be relative; path will then be relative to that directory.
+If dir_fd is not None, it should be a file descriptor open to
+a directory, and path should be relative; path will then be relative
+to that directory.
dir_fd may not be implemented on your platform.
- If it is unavailable, using it will raise a NotImplementedError.
+If it is unavailable, using it will raise a NotImplementedError.
[clinic start generated code]*/
static PyObject *
os_remove_impl(PyObject *module, path_t *path, int dir_fd)
-/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
+/*[clinic end generated code: output=a8535b28f0068883 input=9f6e66912126bd56]*/
{
return os_unlink_impl(module, path, dir_fd);
}
@@ -7056,38 +7061,37 @@ os.utime
dir_fd: dir_fd(requires='futimensat') = None
follow_symlinks: bool=True
-# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
-
Set the access and modified time of path.
-path may always be specified as a string.
-On some platforms, path may also be specified as an open file descriptor.
- If this functionality is unavailable, using it raises an exception.
+path may always be specified as a string. On some platforms, path may
+also be specified as an open file descriptor. If this functionality is
+unavailable, using it raises an exception.
If times is not None, it must be a tuple (atime, mtime);
- atime and mtime should be expressed as float seconds since the epoch.
+atime and mtime should be expressed as float seconds since the epoch.
If ns is specified, it must be a tuple (atime_ns, mtime_ns);
- atime_ns and mtime_ns should be expressed as integer nanoseconds
- since the epoch.
+atime_ns and mtime_ns should be expressed as integer nanoseconds
+since the epoch.
If times is None and ns is unspecified, utime uses the current time.
Specifying tuples for both times and ns is an error.
-If dir_fd is not None, it should be a file descriptor open to a directory,
- and path should be relative; path will then be relative to that directory.
-If follow_symlinks is False, and the last element of the path is a symbolic
- link, utime will modify the symbolic link itself instead of the file the
- link points to.
-It is an error to use dir_fd or follow_symlinks when specifying path
- as an open file descriptor.
+If dir_fd is not None, it should be a file descriptor open to
+a directory, and path should be relative; path will then be relative to
+that directory.
+If follow_symlinks is False, and the last element of the path is
+a symbolic link, utime will modify the symbolic link itself instead of
+the file the link points to.
+It is an error to use dir_fd or follow_symlinks when specifying path as
+an open file descriptor.
dir_fd and follow_symlinks may not be available on your platform.
- If they are unavailable, using them will raise a NotImplementedError.
+If they are unavailable, using them will raise a NotImplementedError.
[clinic start generated code]*/
static PyObject *
os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
int dir_fd, int follow_symlinks)
-/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
+/*[clinic end generated code: output=cfcac69d027b82cf input=5ab470b2bc250788]*/
{
#ifdef MS_WINDOWS
HANDLE hFile;
@@ -7244,6 +7248,7 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
/*[clinic input]
+@permit_long_summary
os._exit
status: int
@@ -7253,7 +7258,7 @@ Exit to the system with specified status, without normal exit processing.
static PyObject *
os__exit_impl(PyObject *module, int status)
-/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
+/*[clinic end generated code: output=116e52d9c2260d54 input=c35d282acfebe8fd]*/
{
_exit(status);
return NULL; /* Make gcc -Wall happy */
@@ -8057,7 +8062,8 @@ os.posix_spawn
resetids: bool = False
If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
setsid: bool = False
- If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
+ If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP
+ will be activated.
setsigmask: object(c_default='NULL') = ()
The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
setsigdef: object(c_default='NULL') = ()
@@ -8074,7 +8080,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
PyObject *setpgroup, int resetids, int setsid,
PyObject *setsigmask, PyObject *setsigdef,
PyObject *scheduler)
-/*[clinic end generated code: output=14a1098c566bc675 input=69e7c9ebbdcf94a5]*/
+/*[clinic end generated code: output=14a1098c566bc675 input=c7592dcbc96e8114]*/
{
return py_posix_spawn(0, module, path, argv, env, file_actions,
setpgroup, resetids, setsid, setsigmask, setsigdef,
@@ -8103,7 +8109,8 @@ os.posix_spawnp
resetids: bool = False
If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
setsid: bool = False
- If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
+ If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP
+ will be activated.
setsigmask: object(c_default='NULL') = ()
The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
setsigdef: object(c_default='NULL') = ()
@@ -8120,7 +8127,7 @@ os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
PyObject *setpgroup, int resetids, int setsid,
PyObject *setsigmask, PyObject *setsigdef,
PyObject *scheduler)
-/*[clinic end generated code: output=7b9aaefe3031238d input=a5c057527c6881a5]*/
+/*[clinic end generated code: output=7b9aaefe3031238d input=43ccc1452cae2be3]*/
{
return py_posix_spawn(1, module, path, argv, env, file_actions,
setpgroup, resetids, setsid, setsigmask, setsigdef,
@@ -9156,13 +9163,13 @@ os.posix_openpt -> int
Open and return a file descriptor for a master pseudo-terminal device.
Performs a posix_openpt() C function call. The oflag argument is used to
-set file status flags and file access modes as specified in the manual page
-of posix_openpt() of your system.
+set file status flags and file access modes as specified in the manual
+page of posix_openpt() of your system.
[clinic start generated code]*/
static int
os_posix_openpt_impl(PyObject *module, int oflag)
-/*[clinic end generated code: output=ee0bc2624305fc79 input=0de33d0e29693caa]*/
+/*[clinic end generated code: output=ee0bc2624305fc79 input=3ce4eb297fa64307]*/
{
int fd;
@@ -9437,6 +9444,7 @@ os_openpty_impl(PyObject *module)
#if defined(HAVE_LOGIN_TTY) || defined(HAVE_FALLBACK_LOGIN_TTY)
/*[clinic input]
+@permit_long_summary
os.login_tty
fd: fildes
@@ -9451,7 +9459,7 @@ calling process; close fd.
static PyObject *
os_login_tty_impl(PyObject *module, int fd)
-/*[clinic end generated code: output=495a79911b4cc1bc input=5f298565099903a2]*/
+/*[clinic end generated code: output=495a79911b4cc1bc input=b102a7c36e8baf00]*/
{
#ifdef HAVE_LOGIN_TTY
if (login_tty(fd) == -1) {
@@ -9806,14 +9814,14 @@ os.initgroups
Initialize the group access list.
-Call the system initgroups() to initialize the group access list with all of
-the groups of which the specified username is a member, plus the specified
-group id.
+Call the system initgroups() to initialize the group access list with
+all of the groups of which the specified username is a member, plus the
+specified group id.
[clinic start generated code]*/
static PyObject *
os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
-/*[clinic end generated code: output=7f074d30a425fd3a input=984e60c7fed88cb4]*/
+/*[clinic end generated code: output=7f074d30a425fd3a input=35f2d4fb7fcc0bdf]*/
#else
/*[clinic input]
os.initgroups
@@ -9824,14 +9832,14 @@ os.initgroups
Initialize the group access list.
-Call the system initgroups() to initialize the group access list with all of
-the groups of which the specified username is a member, plus the specified
-group id.
+Call the system initgroups() to initialize the group access list with
+all of the groups of which the specified username is a member, plus the
+specified group id.
[clinic start generated code]*/
static PyObject *
os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
-/*[clinic end generated code: output=59341244521a9e3f input=17d8fbe2dea42ca4]*/
+/*[clinic end generated code: output=59341244521a9e3f input=7e4514dff4526a95]*/
#endif
{
const char *username = PyBytes_AS_STRING(oname);
@@ -10028,12 +10036,13 @@ os.getppid
Return the parent's process id.
If the parent process has already exited, Windows machines will still
-return its id; others systems will return the id of the 'init' process (1).
+return its id; others systems will return the id of the 'init' proces
+(1).
[clinic start generated code]*/
static PyObject *
os_getppid_impl(PyObject *module)
-/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
+/*[clinic end generated code: output=43b2a946a8c603b4 input=e17c1de18f41316b]*/
{
#ifdef MS_WINDOWS
return win32_getppid();
@@ -10587,13 +10596,13 @@ os.waitid
Returns the result of waiting for a process or processes.
-Returns either waitid_result or None if WNOHANG is specified and there are
-no children in a waitable state.
+Returns either waitid_result or None if WNOHANG is specified and there
+are no children in a waitable state.
[clinic start generated code]*/
static PyObject *
os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
-/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
+/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=14956bc8d102b5db]*/
{
PyObject *result;
int res;
@@ -10760,13 +10769,13 @@ os.pidfd_open
Return a file descriptor referring to the process *pid*.
-The descriptor can be used to perform process management without races and
-signals.
+The descriptor can be used to perform process management without races
+and signals.
[clinic start generated code]*/
static PyObject *
os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
-/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
+/*[clinic end generated code: output=5c7252698947dc41 input=03058b32c389f874]*/
{
int fd = syscall(__NR_pidfd_open, pid, flags);
if (fd < 0) {
@@ -10845,8 +10854,9 @@ os.readlink
Return a string representing the path to which the symbolic link points.
-If dir_fd is not None, it should be a file descriptor open to a directory,
-and path should be relative; path will then be relative to that directory.
+If dir_fd is not None, it should be a file descriptor open to
+a directory, and path should be relative; path will then be relative to
+that directory.
dir_fd may not be implemented on your platform. If it is unavailable,
using it will raise a NotImplementedError.
@@ -10854,7 +10864,7 @@ using it will raise a NotImplementedError.
static PyObject *
os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
-/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
+/*[clinic end generated code: output=d21b732a2e814030 input=03d10130870dbca8]*/
{
#if defined(HAVE_READLINK)
char buffer[MAXPATHLEN+1];
@@ -11049,26 +11059,25 @@ os.symlink
*
dir_fd: dir_fd(requires='symlinkat')=None
-# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
-
Create a symbolic link pointing to src named dst.
target_is_directory is required on Windows if the target is to be
- interpreted as a directory. (On Windows, symlink requires
- Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
- target_is_directory is ignored on non-Windows platforms.
+interpreted as a directory. (On Windows, symlink requires Windows 6.0
+or greater, and raises a NotImplementedError otherwise.)
+target_is_directory is ignored on non-Windows platforms.
-If dir_fd is not None, it should be a file descriptor open to a directory,
- and path should be relative; path will then be relative to that directory.
-dir_fd may not be implemented on your platform.
- If it is unavailable, using it will raise a NotImplementedError.
+If dir_fd is not None, it should be a file descriptor open to
+a directory, and path should be relative; path will then be relative
+to that directory.
+dir_fd may not be implemented on your platform. If it is unavailable,
+using it will raise a NotImplementedError.
[clinic start generated code]*/
static PyObject *
os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
int target_is_directory, int dir_fd)
-/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
+/*[clinic end generated code: output=08ca9f3f3cf960f6 input=71b75467b31c45f7]*/
{
#ifdef MS_WINDOWS
DWORD result;
@@ -11627,19 +11636,18 @@ os.open -> int
*
dir_fd: dir_fd(requires='openat') = None
-# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
-
Open a file for low level IO. Returns a file descriptor (integer).
-If dir_fd is not None, it should be a file descriptor open to a directory,
- and path should be relative; path will then be relative to that directory.
-dir_fd may not be implemented on your platform.
- If it is unavailable, using it will raise a NotImplementedError.
+If dir_fd is not None, it should be a file descriptor open to
+a directory, and path should be relative; path will then be relative to
+that directory.
+dir_fd may not be implemented on your platform. If it is unavailable,
+using it will raise a NotImplementedError.
[clinic start generated code]*/
static int
os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
-/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
+/*[clinic end generated code: output=abc7227888c8bc73 input=75f7b4eaf92f2225]*/
{
int fd;
int async_err = 0;
@@ -11913,7 +11921,6 @@ os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
/*[clinic input]
-@permit_long_docstring_body
os.lseek -> Py_off_t
fd: int
@@ -11929,12 +11936,13 @@ os.lseek -> Py_off_t
Set the position of a file descriptor. Return the new position.
-The return value is the number of bytes relative to the beginning of the file.
+The return value is the number of bytes relative to the beginning of
+the file.
[clinic start generated code]*/
static Py_off_t
os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
-/*[clinic end generated code: output=971e1efb6b30bd2f input=4a3de549f07e1c40]*/
+/*[clinic end generated code: output=971e1efb6b30bd2f input=32ea0788da7cb44b]*/
{
Py_off_t result;
@@ -11998,7 +12006,6 @@ os_read_impl(PyObject *module, int fd, Py_ssize_t length)
}
/*[clinic input]
-@permit_long_docstring_body
os.readinto -> Py_ssize_t
fd: int
buffer: Py_buffer(accept={rwbuffer})
@@ -12006,20 +12013,20 @@ os.readinto -> Py_ssize_t
Read into a buffer object from a file descriptor.
-The buffer should be mutable and bytes-like. On success, returns the number of
-bytes read. Less bytes may be read than the size of the buffer. The underlying
-system call will be retried when interrupted by a signal, unless the signal
-handler raises an exception. Other errors will not be retried and an error will
-be raised.
+The buffer should be mutable and bytes-like. On success, returns the
+number of bytes read. Less bytes may be read than the size of the
+buffer. The underlying system call will be retried when interrupted by
+a signal, unless the signal handler raises an exception. Other errors
+will not be retried and an error will be raised.
-Returns 0 if *fd* is at end of file or if the provided *buffer* has length 0
-(which can be used to check for errors without reading data). Never returns
-negative.
+Returns 0 if *fd* is at end of file or if the provided *buffer* has
+length 0 (which can be used to check for errors without reading data).
+Never returns negative.
[clinic start generated code]*/
static Py_ssize_t
os_readinto_impl(PyObject *module, int fd, Py_buffer *buffer)
-/*[clinic end generated code: output=8091a3513c683a80 input=a770382bd3d32f9a]*/
+/*[clinic end generated code: output=8091a3513c683a80 input=2a5f8b212cb5730c]*/
{
assert(buffer->len >= 0);
Py_ssize_t result = _Py_read(fd, buffer->buf, buffer->len);
@@ -12203,7 +12210,7 @@ os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
/*[clinic input]
-@permit_long_docstring_body
+@permit_long_summary
os.preadv -> Py_ssize_t
fd: int
@@ -12214,14 +12221,15 @@ os.preadv -> Py_ssize_t
Reads from a file descriptor into a number of mutable bytes-like objects.
-Combines the functionality of readv() and pread(). As readv(), it will
-transfer data into each buffer until it is full and then move on to the next
-buffer in the sequence to hold the rest of the data. Its fourth argument,
-specifies the file offset at which the input operation is to be performed. It
-will return the total number of bytes read (which can be less than the total
-capacity of all the objects).
+Combines the functionality of readv() and pread(). As readv(), it will
+transfer data into each buffer until it is full and then move on to the
+next buffer in the sequence to hold the rest of the data. Its fourth
+argument, specifies the file offset at which the input operation is to
+be performed. It will return the total number of bytes read (which can
+be less than the total capacity of all the objects).
-The flags argument contains a bitwise OR of zero or more of the following flags:
+The flags argument contains a bitwise OR of zero or more of the
+following flags:
- RWF_HIPRI
- RWF_NOWAIT
@@ -12233,7 +12241,7 @@ Using non-zero flags requires Linux 4.6 or newer.
static Py_ssize_t
os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
int flags)
-/*[clinic end generated code: output=26fc9c6e58e7ada5 input=34fb3b9ca06f7ba7]*/
+/*[clinic end generated code: output=26fc9c6e58e7ada5 input=bbc70c63b4f4e877]*/
{
Py_ssize_t cnt, n;
int async_err = 0;
@@ -12570,6 +12578,7 @@ os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
#if defined(__APPLE__)
/*[clinic input]
+@permit_long_summary
os._fcopyfile
in_fd: int
@@ -12582,7 +12591,7 @@ Efficiently copy content or metadata of 2 regular file descriptors (macOS).
static PyObject *
os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
-/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
+/*[clinic end generated code: output=c9d1a35a992e401b input=80b53ad8863c9101]*/
{
int ret;
@@ -12771,6 +12780,7 @@ os_pipe2_impl(PyObject *module, int flags)
#ifdef HAVE_WRITEV
/*[clinic input]
+@permit_long_summary
os.writev -> Py_ssize_t
fd: int
buffers: object
@@ -12784,7 +12794,7 @@ buffers must be a sequence of bytes-like objects.
static Py_ssize_t
os_writev_impl(PyObject *module, int fd, PyObject *buffers)
-/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
+/*[clinic end generated code: output=56565cfac3aac15b input=5771a0f0c2b326f2]*/
{
Py_ssize_t cnt;
Py_ssize_t result;
@@ -12860,7 +12870,6 @@ os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
os.pwritev -> Py_ssize_t
fd: int
@@ -12871,14 +12880,16 @@ os.pwritev -> Py_ssize_t
Writes the contents of bytes-like objects to a file descriptor at a given offset.
-Combines the functionality of writev() and pwrite(). All buffers must be a sequence
-of bytes-like objects. Buffers are processed in array order. Entire contents of first
-buffer is written before proceeding to second, and so on. The operating system may
-set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
-This function writes the contents of each object to the file descriptor and returns
-the total number of bytes written.
+Combines the functionality of writev() and pwrite(). All buffers must be
+a sequence of bytes-like objects. Buffers are processed in array order.
+Entire contents of first buffer is written before proceeding to second,
+and so on. The operating system may set a limit (sysconf() value
+SC_IOV_MAX) on the number of buffers that can be used.
+This function writes the contents of each object to the file descriptor
+and returns the total number of bytes written.
-The flags argument contains a bitwise OR of zero or more of the following flags:
+The flags argument contains a bitwise OR of zero or more of the
+following flags:
- RWF_DSYNC
- RWF_SYNC
@@ -12892,7 +12903,7 @@ Using non-zero flags requires Linux 4.7 or newer.
static Py_ssize_t
os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
int flags)
-/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=7de72245873f56bf]*/
+/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=b2e352a22f030e9a]*/
{
Py_ssize_t cnt;
Py_ssize_t result;
@@ -13105,15 +13116,16 @@ os.mkfifo
Create a "fifo" (a POSIX named pipe).
-If dir_fd is not None, it should be a file descriptor open to a directory,
- and path should be relative; path will then be relative to that directory.
-dir_fd may not be implemented on your platform.
- If it is unavailable, using it will raise a NotImplementedError.
+If dir_fd is not None, it should be a file descriptor open to
+a directory, and path should be relative; path will then be relative to
+that directory.
+dir_fd may not be implemented on your platform. If it is unavailable,
+using it will raise a NotImplementedError.
[clinic start generated code]*/
static PyObject *
os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
-/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
+/*[clinic end generated code: output=ce41cfad0e68c940 input=d2fb917c01e888d6]*/
{
int result;
int async_err = 0;
@@ -13156,7 +13168,6 @@ os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
/*[clinic input]
-@permit_long_docstring_body
os.mknod
path: path_t
@@ -13167,23 +13178,24 @@ os.mknod
Create a node in the file system.
-Create a node in the file system (file, device special file or named pipe)
-at path. mode specifies both the permissions to use and the
+Create a node in the file system (file, device special file or named
+pipe) at path. mode specifies both the permissions to use and the
type of node to be created, being combined (bitwise OR) with one of
-S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
-device defines the newly created device special file (probably using
-os.makedev()). Otherwise device is ignored.
+S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set
+on mode, device defines the newly created device special file (probably
+using os.makedev()). Otherwise device is ignored.
-If dir_fd is not None, it should be a file descriptor open to a directory,
- and path should be relative; path will then be relative to that directory.
-dir_fd may not be implemented on your platform.
- If it is unavailable, using it will raise a NotImplementedError.
+If dir_fd is not None, it should be a file descriptor open to
+a directory, and path should be relative; path will then be relative
+to that directory.
+dir_fd may not be implemented on your platform. If it is unavailable,
+using it will raise a NotImplementedError.
[clinic start generated code]*/
static PyObject *
os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
int dir_fd)
-/*[clinic end generated code: output=92e55d3ca8917461 input=7121c4723d22545b]*/
+/*[clinic end generated code: output=92e55d3ca8917461 input=7d0099e85c6b4cba]*/
{
int result;
int async_err = 0;
@@ -13352,13 +13364,14 @@ os.truncate
Truncate a file, specified by path, to a specific length.
-On some platforms, path may also be specified as an open file descriptor.
- If this functionality is unavailable, using it raises an exception.
+On some platforms, path may also be specified as an open file
+descriptor. If this functionality is unavailable, using it raises
+an exception.
[clinic start generated code]*/
static PyObject *
os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
-/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
+/*[clinic end generated code: output=43009c8df5c0a12b input=ce33fd7808a511c4]*/
{
int result;
#ifdef MS_WINDOWS
@@ -13401,6 +13414,7 @@ os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
OSs, support was dropped in WASI preview2. */
#if defined(HAVE_POSIX_FALLOCATE) && !defined(__wasi__)
/*[clinic input]
+@permit_long_summary
os.posix_fallocate
fd: int
@@ -13411,13 +13425,14 @@ os.posix_fallocate
Ensure a file has allocated at least a particular number of bytes on disk.
Ensure that the file specified by fd encompasses a range of bytes
-starting at offset bytes from the beginning and continuing for length bytes.
+starting at offset bytes from the beginning and continuing for length
+bytes.
[clinic start generated code]*/
static PyObject *
os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Py_off_t length)
-/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
+/*[clinic end generated code: output=73f107139564aa9d input=c718971d18b96896]*/
{
int result;
int async_err = 0;
@@ -13452,8 +13467,8 @@ os.posix_fadvise
Announce an intention to access data in a specific pattern.
-Announce an intention to access data in a specific pattern, thus allowing
-the kernel to make optimizations.
+Announce an intention to access data in a specific pattern, thus
+allowing the kernel to make optimizations.
The advice applies to the region of the file specified by fd starting at
offset and continuing for length bytes.
advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
@@ -13464,7 +13479,7 @@ POSIX_FADV_DONTNEED.
static PyObject *
os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Py_off_t length, int advice)
-/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
+/*[clinic end generated code: output=412ef4aa70c98642 input=961b01a4518ef727]*/
{
int result;
int async_err = 0;
@@ -13720,6 +13735,7 @@ os_WCOREDUMP_impl(PyObject *module, int status)
#ifdef WIFCONTINUED
/*[clinic input]
+@permit_long_summary
os.WIFCONTINUED -> bool
status: int
@@ -13732,7 +13748,7 @@ job control stop.
static int
os_WIFCONTINUED_impl(PyObject *module, int status)
-/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
+/*[clinic end generated code: output=1e35295d844364bd input=7b577845a0f8b12f]*/
{
WAIT_TYPE wait_status;
WAIT_STATUS_INT(wait_status) = status;
@@ -13845,6 +13861,7 @@ os_WTERMSIG_impl(PyObject *module, int status)
#ifdef WSTOPSIG
/*[clinic input]
+@permit_long_summary
os.WSTOPSIG -> int
status: int
@@ -13854,7 +13871,7 @@ Return the signal that stopped the process that provided the status value.
static int
os_WSTOPSIG_impl(PyObject *module, int status)
-/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
+/*[clinic end generated code: output=0ab7586396f5d82b input=4698db1a6a320433]*/
{
WAIT_TYPE wait_status;
WAIT_STATUS_INT(wait_status) = status;
@@ -14045,13 +14062,14 @@ os.statvfs
Perform a statvfs system call on the given path.
path may always be specified as a string.
-On some platforms, path may also be specified as an open file descriptor.
- If this functionality is unavailable, using it raises an exception.
+On some platforms, path may also be specified as an open file
+descriptor. If this functionality is unavailable, using it raises
+an exception.
[clinic start generated code]*/
static PyObject *
os_statvfs_impl(PyObject *module, path_t *path)
-/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
+/*[clinic end generated code: output=87106dd1beb8556e input=1cfd9a4fd36f7425]*/
{
int result;
@@ -14100,6 +14118,7 @@ os_statvfs_impl(PyObject *module, path_t *path)
#ifdef MS_WINDOWS
/*[clinic input]
+@permit_long_summary
os._getdiskusage
path: path_t
@@ -14109,7 +14128,7 @@ Return disk usage statistics about the given path as a (total, free) tuple.
static PyObject *
os__getdiskusage_impl(PyObject *module, path_t *path)
-/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
+/*[clinic end generated code: output=3bd3991f5e5c5dfb input=aee7e38bc3e7fb08]*/
{
BOOL retval;
ULARGE_INTEGER _, total, free;
@@ -14330,13 +14349,14 @@ os.pathconf -> long
Return the configuration limit name for the file or directory path.
If there is no limit, return -1.
-On some platforms, path may also be specified as an open file descriptor.
- If this functionality is unavailable, using it raises an exception.
+On some platforms, path may also be specified as an open file
+descriptor. If this functionality is unavailable, using it raises
+an exception.
[clinic start generated code]*/
static long
os_pathconf_impl(PyObject *module, path_t *path, int name)
-/*[clinic end generated code: output=5bedee35b293a089 input=6f6072f57b10c787]*/
+/*[clinic end generated code: output=5bedee35b293a089 input=e86f6eacfa006426]*/
{
long limit;
@@ -15141,13 +15161,13 @@ os.abort
Abort the interpreter immediately.
-This function 'dumps core' or otherwise fails in the hardest way possible
-on the hosting operating system. This function never returns.
+This function 'dumps core' or otherwise fails in the hardest way
+possible on the hosting operating system. This function never returns.
[clinic start generated code]*/
static PyObject *
os_abort_impl(PyObject *module)
-/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
+/*[clinic end generated code: output=dcf52586dad2467c input=ee8bd0ed690440ab]*/
{
abort();
/*NOTREACHED*/
@@ -15356,6 +15376,7 @@ os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
#ifdef HAVE_GETRESUID
/*[clinic input]
+@permit_long_summary
os.getresuid
Return a tuple of the current process's real, effective, and saved user ids.
@@ -15363,7 +15384,7 @@ Return a tuple of the current process's real, effective, and saved user ids.
static PyObject *
os_getresuid_impl(PyObject *module)
-/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
+/*[clinic end generated code: output=8e0becff5dece5bf input=ddf95881f492cb97]*/
{
uid_t ruid, euid, suid;
if (getresuid(&ruid, &euid, &suid) < 0)
@@ -15408,17 +15429,18 @@ os.getxattr
Return the value of extended attribute attribute on path.
-path may be either a string, a path-like object, or an open file descriptor.
-If follow_symlinks is False, and the last element of the path is a symbolic
- link, getxattr will examine the symbolic link itself instead of the file
- the link points to.
+path may be either a string, a path-like object, or an open file
+descriptor.
+If follow_symlinks is False, and the last element of the path is
+a symbolic link, getxattr will examine the symbolic link itself
+instead of the file the link points to.
[clinic start generated code]*/
static PyObject *
os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
int follow_symlinks)
-/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
+/*[clinic end generated code: output=5f2f44200a43cff2 input=db1021ed738d9754]*/
{
if (fd_and_follow_symlinks_invalid("getxattr", path->is_fd, follow_symlinks))
return NULL;
@@ -15465,7 +15487,6 @@ os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
/*[clinic input]
-@permit_long_docstring_body
os.setxattr
path: path_t(allow_fd=True)
@@ -15477,17 +15498,18 @@ os.setxattr
Set extended attribute attribute on path to value.
-path may be either a string, a path-like object, or an open file descriptor.
-If follow_symlinks is False, and the last element of the path is a symbolic
- link, setxattr will modify the symbolic link itself instead of the file
- the link points to.
+path may be either a string, a path-like object, or an open file
+descriptor.
+If follow_symlinks is False, and the last element of the path is
+a symbolic link, setxattr will modify the symbolic link itself instead
+of the file the link points to.
[clinic start generated code]*/
static PyObject *
os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Py_buffer *value, int flags, int follow_symlinks)
-/*[clinic end generated code: output=98b83f63fdde26bb input=4098e6f68699f3d7]*/
+/*[clinic end generated code: output=98b83f63fdde26bb input=6c4ee6724e8947a4]*/
{
ssize_t result;
@@ -15530,17 +15552,18 @@ os.removexattr
Remove extended attribute attribute on path.
-path may be either a string, a path-like object, or an open file descriptor.
-If follow_symlinks is False, and the last element of the path is a symbolic
- link, removexattr will modify the symbolic link itself instead of the file
- the link points to.
+path may be either a string, a path-like object, or an open file
+descriptor.
+If follow_symlinks is False, and the last element of the path is
+a symbolic link, removexattr will modify the symbolic link itself
+instead of the file the link points to.
[clinic start generated code]*/
static PyObject *
os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
int follow_symlinks)
-/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
+/*[clinic end generated code: output=521a51817980cda6 input=a7ec62a86aa83f01]*/
{
ssize_t result;
@@ -15569,7 +15592,6 @@ os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
/*[clinic input]
-@permit_long_docstring_body
os.listxattr
path: path_t(allow_fd=True, nullable=True) = None
@@ -15578,16 +15600,17 @@ os.listxattr
Return a list of extended attributes on path.
-path may be either None, a string, a path-like object, or an open file descriptor.
-if path is None, listxattr will examine the current directory.
-If follow_symlinks is False, and the last element of the path is a symbolic
- link, listxattr will examine the symbolic link itself instead of the file
- the link points to.
+path may be either None, a string, a path-like object, or an open file
+descriptor. If path is None, listxattr will examine the current
+directory.
+If follow_symlinks is False, and the last element of the path is
+a symbolic link, listxattr will examine the symbolic link itself instead
+of the file the link points to.
[clinic start generated code]*/
static PyObject *
os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
-/*[clinic end generated code: output=bebdb4e2ad0ce435 input=48aa9ac8be47dea1]*/
+/*[clinic end generated code: output=bebdb4e2ad0ce435 input=cb4a6414afaa99bd]*/
{
Py_ssize_t i;
PyObject *result = NULL;
@@ -16490,7 +16513,7 @@ static PyMemberDef DirEntry_members[] = {
{"name", Py_T_OBJECT_EX, offsetof(DirEntry, name), Py_READONLY,
"the entry's base filename, relative to scandir() \"path\" argument"},
{"path", Py_T_OBJECT_EX, offsetof(DirEntry, path), Py_READONLY,
- "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
+ "the entry's full path name; equivalent to\nos.path.join(scandir_path, entry.name)"},
{NULL}
};
@@ -16984,16 +17007,16 @@ os.scandir
Return an iterator of DirEntry objects for given path.
-path can be specified as either str, bytes, or a path-like object. If path
-is bytes, the names of yielded DirEntry objects will also be bytes; in
-all other circumstances they will be str.
+path can be specified as either str, bytes, or a path-like object. If
+path is bytes, the names of yielded DirEntry objects will also be bytes;
+in all other circumstances they will be str.
If path is None, uses the path='.'.
[clinic start generated code]*/
static PyObject *
os_scandir_impl(PyObject *module, path_t *path)
-/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
+/*[clinic end generated code: output=6eb2668b675ca89e input=6ab9600993f51577]*/
{
ScandirIterator *iterator;
#ifdef MS_WINDOWS
@@ -17140,21 +17163,20 @@ PyOS_FSPath(PyObject *path)
}
/*[clinic input]
-@permit_long_docstring_body
os.fspath
path: object
Return the file system path representation of the object.
-If the object is str or bytes, then allow it to pass through as-is. If the
-object defines __fspath__(), then return the result of that method. All other
-types raise a TypeError.
+If the object is str or bytes, then allow it to pass through as-is. If
+the object defines __fspath__(), then return the result of that method.
+All other types raise a TypeError.
[clinic start generated code]*/
static PyObject *
os_fspath_impl(PyObject *module, PyObject *path)
-/*[clinic end generated code: output=c3c3b78ecff2914f input=f608743e60a3211e]*/
+/*[clinic end generated code: output=c3c3b78ecff2914f input=d3c54404240d5da0]*/
{
return PyOS_FSPath(path);
}
@@ -17331,13 +17353,13 @@ On Unix:
On Windows, return status shifted right by 8 bits.
On Unix, if the process is being traced or if waitpid() was called with
-WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.
-This function must not be called if WIFSTOPPED(status) is true.
+WUNTRACED option, the caller must first check if WIFSTOPPED(status) is
+true. This function must not be called if WIFSTOPPED(status) is true.
[clinic start generated code]*/
static PyObject *
os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
-/*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/
+/*[clinic end generated code: output=db50b1b0ba3c7153 input=3b44a23f5090006c]*/
{
#ifndef MS_WINDOWS
int status = PyLong_AsInt(status_obj);
From d02c2dfc1125d84a6ba867fabaf9401732ec0be9 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 24 May 2026 17:47:29 +0200
Subject: [PATCH 136/213] [3.15] gh-110704: Recommend `distclean` target over
`clean` when source tree is not clean (GH-112610) (#150342)
gh-110704: Recommend `distclean` target over `clean` when source tree is not clean (GH-112610)
Recommend `distclean` target over `clean` when source tree is not clean
(cherry picked from commit 34631058f2aec6752ebfc50d40958b247532f536)
Co-authored-by: James <6125322+SnoopJ@users.noreply.github.com>
Co-authored-by: Gregory P. Smith
---
Makefile.pre.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile.pre.in b/Makefile.pre.in
index dce0139d8d6e35..669a2c9527075c 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -835,7 +835,7 @@ check-clean-src:
echo "Building Python out of the source tree (in $(abs_builddir)) requires a clean source tree ($(abs_srcdir))" ; \
echo "Build artifacts such as .o files, executables, and Python/frozen_modules/*.h must not exist within $(srcdir)." ; \
echo "Try to run:" ; \
- echo " (cd \"$(srcdir)\" && make clean || git clean -fdx -e Doc/venv)" ; \
+ echo " (cd \"$(srcdir)\" && make distclean || git clean -fdx -e Doc/venv)" ; \
exit 1; \
fi
From cf73b17adfd102a34a01efbad89a83dffdec2806 Mon Sep 17 00:00:00 2001
From: Serhiy Storchaka
Date: Sun, 24 May 2026 22:31:19 +0300
Subject: [PATCH 137/213] [3.15] gh-150285: Fix too long docstrings in Argument
Clinic code (GH-150338) (GH-150350)
(cherry picked from commit 287c98f4cb40c15d638651de4b29ae98b92589aa)
---
Modules/_abc.c | 8 +-
Modules/_asynciomodule.c | 28 ++++---
Modules/_bisectmodule.c | 12 +--
Modules/_bz2module.c | 24 +++---
Modules/_codecsmodule.c | 42 +++++-----
Modules/_collectionsmodule.c | 3 +-
Modules/_datetimemodule.c | 38 ++++-----
Modules/_dbmmodule.c | 5 +-
Modules/_elementtree.c | 3 +-
Modules/_functoolsmodule.c | 9 +--
Modules/_gdbmmodule.c | 22 +++---
Modules/_hashopenssl.c | 13 ++-
Modules/_heapqmodule.c | 9 ++-
Modules/_interpqueuesmodule.c | 5 +-
Modules/_interpretersmodule.c | 16 ++--
Modules/_json.c | 6 +-
Modules/_lzmamodule.c | 24 +++---
.../_multiprocessing/clinic/posixshmem.c.h | 8 +-
Modules/_multiprocessing/posixshmem.c | 8 +-
Modules/_opcode.c | 4 +-
Modules/_posixsubprocess.c | 17 ++--
Modules/_queuemodule.c | 18 +++--
Modules/_sre/sre.c | 3 +-
Modules/_ssl.c | 79 +++++++++----------
Modules/_struct.c | 6 +-
Modules/_testlimitedcapi/clinic/long.c.h | 6 +-
Modules/_testlimitedcapi/long.c | 6 +-
Modules/_testmultiphase.c | 6 +-
Modules/_threadmodule.c | 18 ++---
Modules/_tkinter.c | 6 +-
Modules/_tracemalloc.c | 6 +-
Modules/arraymodule.c | 32 ++++----
Modules/cjkcodecs/clinic/multibytecodec.c.h | 18 +++--
Modules/cjkcodecs/multibytecodec.c | 22 +++---
Modules/clinic/_abc.c.h | 8 +-
Modules/clinic/_asynciomodule.c.h | 19 ++---
Modules/clinic/_bisectmodule.c.h | 10 +--
Modules/clinic/_bz2module.c.h | 23 +++---
Modules/clinic/_codecsmodule.c.h | 34 ++++----
Modules/clinic/_datetimemodule.c.h | 21 ++---
Modules/clinic/_dbmmodule.c.h | 5 +-
Modules/clinic/_functoolsmodule.c.h | 8 +-
Modules/clinic/_gdbmmodule.c.h | 18 ++---
Modules/clinic/_hashopenssl.c.h | 10 +--
Modules/clinic/_heapqmodule.c.h | 6 +-
Modules/clinic/_interpqueuesmodule.c.h | 5 +-
Modules/clinic/_interpretersmodule.c.h | 10 ++-
Modules/clinic/_json.c.h | 6 +-
Modules/clinic/_lzmamodule.c.h | 23 +++---
Modules/clinic/_posixsubprocess.c.h | 16 ++--
Modules/clinic/_queuemodule.c.h | 16 ++--
Modules/clinic/_ssl.c.h | 55 +++++++------
Modules/clinic/_testmultiphase.c.h | 6 +-
Modules/clinic/_threadmodule.c.h | 16 ++--
Modules/clinic/_tkinter.c.h | 5 +-
Modules/clinic/arraymodule.c.h | 23 +++---
Modules/clinic/cmathmodule.c.h | 14 ++--
Modules/clinic/faulthandler.c.h | 8 +-
Modules/clinic/gcmodule.c.h | 13 +--
Modules/clinic/hmacmodule.c.h | 6 +-
Modules/clinic/itertoolsmodule.c.h | 6 +-
Modules/clinic/mathmodule.c.h | 6 +-
Modules/clinic/overlapped.c.h | 7 +-
Modules/clinic/selectmodule.c.h | 35 ++++----
Modules/clinic/signalmodule.c.h | 17 ++--
Modules/clinic/socketmodule.c.h | 22 +++---
Modules/clinic/termios.c.h | 5 +-
Modules/clinic/zlibmodule.c.h | 27 ++++---
Modules/cmathmodule.c | 17 ++--
Modules/faulthandler.c | 8 +-
Modules/gcmodule.c | 17 ++--
Modules/hmacmodule.c | 7 +-
Modules/itertoolsmodule.c | 15 ++--
Modules/mathmodule.c | 11 +--
Modules/overlapped.c | 7 +-
Modules/readline.c | 6 +-
Modules/selectmodule.c | 51 ++++++------
Modules/signalmodule.c | 23 +++---
Modules/socketmodule.c | 30 +++----
Modules/termios.c | 9 ++-
Modules/unicodedata.c | 15 ++--
Modules/zlibmodule.c | 32 ++++----
Python/clinic/context.c.h | 27 ++++---
Python/clinic/import.c.h | 7 +-
Python/clinic/marshal.c.h | 10 +--
Python/clinic/sysmodule.c.h | 26 +++---
Python/context.c | 38 ++++-----
Python/import.c | 14 ++--
Python/marshal.c | 13 ++-
Python/sysmodule.c | 40 +++++-----
Tools/clinic/libclinic/function.py | 8 +-
91 files changed, 768 insertions(+), 702 deletions(-)
diff --git a/Modules/_abc.c b/Modules/_abc.c
index 3c4e0280525e1e..5826efbfecb690 100644
--- a/Modules/_abc.c
+++ b/Modules/_abc.c
@@ -915,14 +915,14 @@ _abc.get_cache_token
Returns the current ABC cache token.
-The token is an opaque object (supporting equality testing) identifying the
-current version of the ABC cache for virtual subclasses. The token changes
-with every call to register() on any ABC.
+The token is an opaque object (supporting equality testing) identifying
+the current version of the ABC cache for virtual subclasses. The token
+changes with every call to register() on any ABC.
[clinic start generated code]*/
static PyObject *
_abc_get_cache_token_impl(PyObject *module)
-/*[clinic end generated code: output=c7d87841e033dacc input=70413d1c423ad9f9]*/
+/*[clinic end generated code: output=c7d87841e033dacc input=d87acc04492f6bf3]*/
{
_abcmodule_state *state = get_abc_state(module);
return PyLong_FromUnsignedLongLong(get_invalidation_counter(state));
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index 9679a7dde31b0d..7fa415a08b1551 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -955,12 +955,13 @@ Return the result this future represents.
If the future has been cancelled, raises CancelledError. If the
future's result isn't yet available, raises InvalidStateError. If
-the future is done and has an exception set, this exception is raised.
+the future is done and has an exception set, this exception is
+raised.
[clinic start generated code]*/
static PyObject *
_asyncio_Future_result_impl(FutureObj *self)
-/*[clinic end generated code: output=f35f940936a4b1e5 input=61d89f48e4c8b670]*/
+/*[clinic end generated code: output=f35f940936a4b1e5 input=ee20e126776cbb04]*/
{
asyncio_state *state = get_asyncio_state_by_def((PyObject *)self);
PyObject *result;
@@ -1095,15 +1096,15 @@ _asyncio.Future.add_done_callback
Add a callback to be run when the future becomes done.
-The callback is called with a single argument - the future object. If
-the future is already done when this is called, the callback is
+The callback is called with a single argument - the future object.
+If the future is already done when this is called, the callback is
scheduled with call_soon.
[clinic start generated code]*/
static PyObject *
_asyncio_Future_add_done_callback_impl(FutureObj *self, PyTypeObject *cls,
PyObject *fn, PyObject *context)
-/*[clinic end generated code: output=922e9a4cbd601167 input=37d97f941beb7b3e]*/
+/*[clinic end generated code: output=922e9a4cbd601167 input=f4f6adb074cd3e0f]*/
{
asyncio_state *state = get_asyncio_state_by_cls(cls);
if (context == NULL) {
@@ -1252,15 +1253,15 @@ _asyncio.Future.cancel
Cancel the future and schedule callbacks.
-If the future is already done or cancelled, return False. Otherwise,
-change the future's state to cancelled, schedule the callbacks and
-return True.
+If the future is already done or cancelled, return False.
+Otherwise, change the future's state to cancelled, schedule the
+callbacks and return True.
[clinic start generated code]*/
static PyObject *
_asyncio_Future_cancel_impl(FutureObj *self, PyTypeObject *cls,
PyObject *msg)
-/*[clinic end generated code: output=074956f35904b034 input=44ab4003da839970]*/
+/*[clinic end generated code: output=074956f35904b034 input=0c9157547a964c4c]*/
{
asyncio_state *state = get_asyncio_state_by_cls(cls);
ENSURE_FUTURE_ALIVE(state, self)
@@ -1292,13 +1293,13 @@ _asyncio.Future.done
Return True if the future is done.
-Done means either that a result / exception are available, or that the
-future was cancelled.
+Done means either that a result / exception are available, or that
+the future was cancelled.
[clinic start generated code]*/
static PyObject *
_asyncio_Future_done_impl(FutureObj *self)
-/*[clinic end generated code: output=244c5ac351145096 input=7204d3cc63bef7f3]*/
+/*[clinic end generated code: output=244c5ac351145096 input=acf2c2347f3c01d8]*/
{
if (!future_is_alive(self) || self->fut_state == STATE_PENDING) {
Py_RETURN_FALSE;
@@ -3844,6 +3845,7 @@ _asyncio__leave_task_impl(PyObject *module, PyObject *loop, PyObject *task)
/*[clinic input]
+@permit_long_summary
_asyncio._swap_current_task
loop: object
@@ -3858,7 +3860,7 @@ This is intended for use during eager coroutine execution.
static PyObject *
_asyncio__swap_current_task_impl(PyObject *module, PyObject *loop,
PyObject *task)
-/*[clinic end generated code: output=9f88de958df74c7e input=c9c72208d3d38b6c]*/
+/*[clinic end generated code: output=9f88de958df74c7e input=ec14ed25855e3068]*/
{
_PyThreadStateImpl *ts = (_PyThreadStateImpl *)_PyThreadState_GET();
return swap_current_task(ts, loop, task);
diff --git a/Modules/_bisectmodule.c b/Modules/_bisectmodule.c
index 329aa8e117ec3c..a953f8bfa11aea 100644
--- a/Modules/_bisectmodule.c
+++ b/Modules/_bisectmodule.c
@@ -157,8 +157,8 @@ _bisect.bisect_right -> Py_ssize_t
Return the index where to insert item x in list a, assuming a is sorted.
The return value i is such that all e in a[:i] have e <= x, and all e in
-a[i:] have e > x. So if x already appears in the list, a.insert(i, x) will
-insert just after the rightmost x already there.
+a[i:] have e > x. So if x already appears in the list, a.insert(i, x)
+will insert just after the rightmost x already there.
Optional args lo (default 0) and hi (default len(a)) bound the
slice of a to be searched.
@@ -169,7 +169,7 @@ A custom key function can be supplied to customize the sort order.
static Py_ssize_t
_bisect_bisect_right_impl(PyObject *module, PyObject *a, PyObject *x,
Py_ssize_t lo, Py_ssize_t hi, PyObject *key)
-/*[clinic end generated code: output=3a4bc09cc7c8a73d input=b476bc45667273ac]*/
+/*[clinic end generated code: output=3a4bc09cc7c8a73d input=27717afe1a61bfaa]*/
{
return internal_bisect_right(a, x, lo, hi, key);
}
@@ -338,8 +338,8 @@ _bisect.bisect_left -> Py_ssize_t
Return the index where to insert item x in list a, assuming a is sorted.
The return value i is such that all e in a[:i] have e < x, and all e in
-a[i:] have e >= x. So if x already appears in the list, a.insert(i, x) will
-insert just before the leftmost x already there.
+a[i:] have e >= x. So if x already appears in the list, a.insert(i, x)
+will insert just before the leftmost x already there.
Optional args lo (default 0) and hi (default len(a)) bound the
slice of a to be searched.
@@ -350,7 +350,7 @@ A custom key function can be supplied to customize the sort order.
static Py_ssize_t
_bisect_bisect_left_impl(PyObject *module, PyObject *a, PyObject *x,
Py_ssize_t lo, Py_ssize_t hi, PyObject *key)
-/*[clinic end generated code: output=70749d6e5cae9284 input=9b4d49b5ddecfad7]*/
+/*[clinic end generated code: output=70749d6e5cae9284 input=259fedbe35e882e1]*/
{
return internal_bisect_left(a, x, lo, hi, key);
}
diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c
index 4bff90e6fd2b2e..4cf8beed9ee3eb 100644
--- a/Modules/_bz2module.c
+++ b/Modules/_bz2module.c
@@ -577,7 +577,6 @@ decompress(BZ2Decompressor *d, char *data, size_t len, Py_ssize_t max_length)
}
/*[clinic input]
-@permit_long_docstring_body
_bz2.BZ2Decompressor.decompress
data: Py_buffer
@@ -585,24 +584,25 @@ _bz2.BZ2Decompressor.decompress
Decompress *data*, returning uncompressed data as bytes.
-If *max_length* is nonnegative, returns at most *max_length* bytes of
-decompressed data. If this limit is reached and further output can be
-produced, *self.needs_input* will be set to ``False``. In this case, the next
-call to *decompress()* may provide *data* as b'' to obtain more of the output.
+If *max_length* is nonnegative, returns at most *max_length* bytes
+of decompressed data. If this limit is reached and further output
+can be produced, *self.needs_input* will be set to ``False``. In
+this case, the next call to *decompress()* may provide *data* as b''
+to obtain more of the output.
-If all of the input data was decompressed and returned (either because this
-was less than *max_length* bytes, or because *max_length* was negative),
-*self.needs_input* will be set to True.
+If all of the input data was decompressed and returned (either
+because this was less than *max_length* bytes, or because
+*max_length* was negative), *self.needs_input* will be set to True.
-Attempting to decompress data after the end of stream is reached raises an
-EOFError. Any data found after the end of the stream is ignored and saved in
-the unused_data attribute.
+Attempting to decompress data after the end of stream is reached
+raises an EOFError. Any data found after the end of the stream is
+ignored and saved in the unused_data attribute.
[clinic start generated code]*/
static PyObject *
_bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data,
Py_ssize_t max_length)
-/*[clinic end generated code: output=23e41045deb240a3 input=3703e78f91757655]*/
+/*[clinic end generated code: output=23e41045deb240a3 input=7f68faa9ff7a1b51]*/
{
PyObject *result = NULL;
diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c
index ff52bfd8291ac1..272182f7bf49ac 100644
--- a/Modules/_codecsmodule.c
+++ b/Modules/_codecsmodule.c
@@ -55,14 +55,15 @@ _codecs.register
Register a codec search function.
-Search functions are expected to take one argument, the encoding name in
-all lower case letters, and either return None, or a tuple of functions
-(encoder, decoder, stream_reader, stream_writer) (or a CodecInfo object).
+Search functions are expected to take one argument, the encoding
+name in all lower case letters, and either return None, or a tuple
+of functions (encoder, decoder, stream_reader, stream_writer) (or
+a CodecInfo object).
[clinic start generated code]*/
static PyObject *
_codecs_register(PyObject *module, PyObject *search_function)
-/*[clinic end generated code: output=d1bf21e99db7d6d3 input=369578467955cae4]*/
+/*[clinic end generated code: output=d1bf21e99db7d6d3 input=2321d8c8c0420dfc]*/
{
if (PyCodec_Register(search_function))
return NULL;
@@ -116,16 +117,16 @@ _codecs.encode
Encodes obj using the codec registered for encoding.
The default encoding is 'utf-8'. errors may be given to set a
-different error handling scheme. Default is 'strict' meaning that encoding
-errors raise a ValueError. Other possible values are 'ignore', 'replace'
-and 'backslashreplace' as well as any other name registered with
-codecs.register_error that can handle ValueErrors.
+different error handling scheme. Default is 'strict' meaning that
+encoding errors raise a ValueError. Other possible values are 'ignore',
+'replace' and 'backslashreplace' as well as any other name registered
+with codecs.register_error that can handle ValueErrors.
[clinic start generated code]*/
static PyObject *
_codecs_encode_impl(PyObject *module, PyObject *obj, const char *encoding,
const char *errors)
-/*[clinic end generated code: output=385148eb9a067c86 input=cd5b685040ff61f0]*/
+/*[clinic end generated code: output=385148eb9a067c86 input=e5271d443e391d7f]*/
{
if (encoding == NULL)
encoding = PyUnicode_GetDefaultEncoding();
@@ -143,16 +144,16 @@ _codecs.decode
Decodes obj using the codec registered for encoding.
Default encoding is 'utf-8'. errors may be given to set a
-different error handling scheme. Default is 'strict' meaning that encoding
-errors raise a ValueError. Other possible values are 'ignore', 'replace'
-and 'backslashreplace' as well as any other name registered with
-codecs.register_error that can handle ValueErrors.
+different error handling scheme. Default is 'strict' meaning that
+encoding errors raise a ValueError. Other possible values are 'ignore',
+'replace' and 'backslashreplace' as well as any other name registered
+with codecs.register_error that can handle ValueErrors.
[clinic start generated code]*/
static PyObject *
_codecs_decode_impl(PyObject *module, PyObject *obj, const char *encoding,
const char *errors)
-/*[clinic end generated code: output=679882417dc3a0bd input=7702c0cc2fa1add6]*/
+/*[clinic end generated code: output=679882417dc3a0bd input=3e6254628f9ca538]*/
{
if (encoding == NULL)
encoding = PyUnicode_GetDefaultEncoding();
@@ -962,14 +963,15 @@ _codecs.register_error
Register the specified error handler under the name errors.
handler must be a callable object, that will be called with an exception
-instance containing information about the location of the encoding/decoding
-error and must return a (replacement, new position) tuple.
+instance containing information about the location of the
+encoding/decoding error and must return a (replacement, new position)
+tuple.
[clinic start generated code]*/
static PyObject *
_codecs_register_error_impl(PyObject *module, const char *errors,
PyObject *handler)
-/*[clinic end generated code: output=fa2f7d1879b3067d input=5e6709203c2e33fe]*/
+/*[clinic end generated code: output=fa2f7d1879b3067d input=5bea01dfe835d9d8]*/
{
if (PyCodec_RegisterError(errors, handler))
return NULL;
@@ -1007,13 +1009,13 @@ _codecs.lookup_error
lookup_error(errors) -> handler
-Return the error handler for the specified error handling name or raise a
-LookupError, if no handler exists under this name.
+Return the error handler for the specified error handling name or raise
+a LookupError, if no handler exists under this name.
[clinic start generated code]*/
static PyObject *
_codecs_lookup_error_impl(PyObject *module, const char *name)
-/*[clinic end generated code: output=087f05dc0c9a98cc input=4775dd65e6235aba]*/
+/*[clinic end generated code: output=087f05dc0c9a98cc input=86cfb6a7a9c67113]*/
{
return PyCodec_LookupError(name);
}
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c
index 4ff05727ebc8ce..d702d655a406b6 100644
--- a/Modules/_collectionsmodule.c
+++ b/Modules/_collectionsmodule.c
@@ -1077,6 +1077,7 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n)
}
/*[clinic input]
+@permit_long_summary
@critical_section
_collections.deque.rotate as deque_rotate
@@ -1089,7 +1090,7 @@ Rotate the deque n steps to the right. If n is negative, rotates left.
static PyObject *
deque_rotate_impl(dequeobject *deque, Py_ssize_t n)
-/*[clinic end generated code: output=96c2402a371eb15d input=5bf834296246e002]*/
+/*[clinic end generated code: output=96c2402a371eb15d input=3543c3b2297de8f1]*/
{
if (!_deque_rotate(deque, n))
Py_RETURN_NONE;
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index 163e499d957b2e..59af7afcfcc644 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -3325,7 +3325,6 @@ datetime_date_today_impl(PyTypeObject *type)
}
/*[clinic input]
-@permit_long_docstring_body
@classmethod
datetime.date.fromtimestamp
@@ -3334,13 +3333,13 @@ datetime.date.fromtimestamp
Create a date from a POSIX timestamp.
-The timestamp is a number, e.g. created via time.time(), that is interpreted
-as local time.
+The timestamp is a number, e.g. created via time.time(), that is
+interpreted as local time.
[clinic start generated code]*/
static PyObject *
datetime_date_fromtimestamp_impl(PyTypeObject *type, PyObject *timestamp)
-/*[clinic end generated code: output=59def4e32c028fb6 input=55ff6940f0a8339f]*/
+/*[clinic end generated code: output=59def4e32c028fb6 input=15720eef43b169a1]*/
{
return date_fromtimestamp(type, timestamp);
}
@@ -3476,6 +3475,7 @@ datetime_date_fromisocalendar_impl(PyTypeObject *type, int year, int week,
}
/*[clinic input]
+@permit_long_summary
@classmethod
datetime.date.strptime
@@ -3492,7 +3492,7 @@ For a list of supported format codes, see the documentation:
static PyObject *
datetime_date_strptime_impl(PyTypeObject *type, PyObject *string,
PyObject *format)
-/*[clinic end generated code: output=454d473bee2d5161 input=31d57bb789433e99]*/
+/*[clinic end generated code: output=454d473bee2d5161 input=2db8f0b2b5242deb]*/
{
PyObject *result;
@@ -4744,6 +4744,7 @@ datetime_time_impl(PyTypeObject *type, int hour, int minute, int second,
}
/*[clinic input]
+@permit_long_summary
@classmethod
datetime.time.strptime
@@ -4760,7 +4761,7 @@ For a list of supported format codes, see the documentation:
static PyObject *
datetime_time_strptime_impl(PyTypeObject *type, PyObject *string,
PyObject *format)
-/*[clinic end generated code: output=ae05a9bc0241d3bf input=82ba425ecacc54aa]*/
+/*[clinic end generated code: output=ae05a9bc0241d3bf input=f01d0b9eb5383da5]*/
{
PyObject *result;
@@ -4856,8 +4857,8 @@ datetime.time.isoformat
Return the time formatted according to ISO.
-The full format is 'HH:MM:SS.mmmmmm+zz:zz'. By default, the fractional
-part is omitted if self.microsecond == 0.
+The full format is 'HH:MM:SS.mmmmmm+zz:zz'. By default, the
+fractional part is omitted if self.microsecond == 0.
The optional argument timespec specifies the number of additional
terms of the time to include. Valid options are 'auto', 'hours',
@@ -4866,7 +4867,7 @@ terms of the time to include. Valid options are 'auto', 'hours',
static PyObject *
datetime_time_isoformat_impl(PyDateTime_Time *self, const char *timespec)
-/*[clinic end generated code: output=2bcc7cab65c35545 input=afbbbd953d10ad07]*/
+/*[clinic end generated code: output=2bcc7cab65c35545 input=0efae103081060f4]*/
{
char buf[100];
@@ -4927,14 +4928,14 @@ datetime_time_isoformat_impl(PyDateTime_Time *self, const char *timespec)
}
/*[clinic input]
-@permit_long_docstring_body
datetime.time.strftime
format: unicode
Format using strftime().
-The date part of the timestamp passed to underlying strftime should not be used.
+The date part of the timestamp passed to underlying strftime should
+not be used.
For a list of supported format codes, see the documentation:
https://docs.python.org/3/library/datetime.html#format-codes
@@ -4942,7 +4943,7 @@ For a list of supported format codes, see the documentation:
static PyObject *
datetime_time_strftime_impl(PyDateTime_Time *self, PyObject *format)
-/*[clinic end generated code: output=10f65af20e2a78c7 input=c4a5bbecd798654b]*/
+/*[clinic end generated code: output=10f65af20e2a78c7 input=184e1c0d7d356c5d]*/
{
PyObject *result;
PyObject *tuple;
@@ -5510,15 +5511,15 @@ datetime.datetime.__new__
A combination of a date and a time.
-The year, month and day arguments are required. tzinfo may be None, or an
-instance of a tzinfo subclass. The remaining arguments may be ints.
+The year, month and day arguments are required. tzinfo may be None, or
+an instance of a tzinfo subclass. The remaining arguments may be ints.
[clinic start generated code]*/
static PyObject *
datetime_datetime_impl(PyTypeObject *type, int year, int month, int day,
int hour, int minute, int second, int microsecond,
PyObject *tzinfo, int fold)
-/*[clinic end generated code: output=47983ddb47d36037 input=2af468d7a9c1e568]*/
+/*[clinic end generated code: output=47983ddb47d36037 input=c7fd85dcf6fe9691]*/
{
return new_datetime_ex2(year, month, day,
hour, minute, second, microsecond,
@@ -5735,7 +5736,6 @@ datetime_datetime_utcnow_impl(PyTypeObject *type)
}
/*[clinic input]
-@permit_long_docstring_body
@classmethod
datetime.datetime.fromtimestamp
@@ -5744,14 +5744,14 @@ datetime.datetime.fromtimestamp
Create a datetime from a POSIX timestamp.
-The timestamp is a number, e.g. created via time.time(), that is interpreted
-as local time.
+The timestamp is a number, e.g. created via time.time(), that is
+interpreted as local time.
[clinic start generated code]*/
static PyObject *
datetime_datetime_fromtimestamp_impl(PyTypeObject *type, PyObject *timestamp,
PyObject *tzinfo)
-/*[clinic end generated code: output=9c47ea2b2ebdaded input=d6b5b2095c5a34b2]*/
+/*[clinic end generated code: output=9c47ea2b2ebdaded input=7a2bc81a049ea287]*/
{
PyObject *self;
if (check_tzinfo_subclass(tzinfo) < 0)
diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c
index 6b07ef74cfa51d..a9f4f27d9eb742 100644
--- a/Modules/_dbmmodule.c
+++ b/Modules/_dbmmodule.c
@@ -431,13 +431,14 @@ _dbm.dbm.setdefault
Return the value for key if present, otherwise default.
-If key is not in the database, it is inserted with default as the value.
+If key is not in the database, it is inserted with default as the
+value.
[clinic start generated code]*/
static PyObject *
_dbm_dbm_setdefault_impl(dbmobject *self, PyTypeObject *cls, const char *key,
Py_ssize_t key_length, PyObject *default_value)
-/*[clinic end generated code: output=9c2f6ea6d0fb576c input=c01510ef7571e13b]*/
+/*[clinic end generated code: output=9c2f6ea6d0fb576c input=81224965c110f830]*/
{
datum dbm_key, val;
Py_ssize_t tmp_size;
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index 9e794be5c109ba..eb69df22c6ef0a 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -2570,6 +2570,7 @@ treebuilder_dealloc(PyObject *self)
/* helpers for handling of arbitrary element-like objects */
/*[clinic input]
+@permit_long_summary
_elementtree._set_factories
comment_factory: object
@@ -2584,7 +2585,7 @@ For internal use only.
static PyObject *
_elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory,
PyObject *pi_factory)
-/*[clinic end generated code: output=813b408adee26535 input=99d17627aea7fb3b]*/
+/*[clinic end generated code: output=813b408adee26535 input=0f415cb6b821f768]*/
{
elementtreestate *st = get_elementtree_state(module);
PyObject *old;
diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c
index c702eecc700ac8..393b59883e89f3 100644
--- a/Modules/_functoolsmodule.c
+++ b/Modules/_functoolsmodule.c
@@ -1060,7 +1060,6 @@ _functools_cmp_to_key_impl(PyObject *module, PyObject *mycmp)
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
_functools.reduce
function as func: object
@@ -1070,9 +1069,9 @@ _functools.reduce
Apply a function of two arguments cumulatively to the items of an iterable, from left to right.
-This effectively reduces the iterable to a single value. If initial is present,
-it is placed before the items of the iterable in the calculation, and serves as
-a default when the iterable is empty.
+This effectively reduces the iterable to a single value. If initial is
+present, it is placed before the items of the iterable in the
+calculation, and serves as a default when the iterable is empty.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
calculates ((((1 + 2) + 3) + 4) + 5).
@@ -1081,7 +1080,7 @@ calculates ((((1 + 2) + 3) + 4) + 5).
static PyObject *
_functools_reduce_impl(PyObject *module, PyObject *func, PyObject *seq,
PyObject *result)
-/*[clinic end generated code: output=30d898fe1267c79d input=5c9088c98ffe2793]*/
+/*[clinic end generated code: output=30d898fe1267c79d input=ff4d5c73100e72e8]*/
{
PyObject *args, *it;
diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c
index faffe8d28c5b5e..20d482021656a5 100644
--- a/Modules/_gdbmmodule.c
+++ b/Modules/_gdbmmodule.c
@@ -520,14 +520,14 @@ _gdbm.gdbm.firstkey
Return the starting key for the traversal.
-It's possible to loop over every key in the database using this method
-and the nextkey() method. The traversal is ordered by GDBM's internal
-hash values, and won't be sorted by the key values.
+It's possible to loop over every key in the database using this
+method and the nextkey() method. The traversal is ordered by GDBM's
+internal hash values, and won't be sorted by the key values.
[clinic start generated code]*/
static PyObject *
_gdbm_gdbm_firstkey_impl(gdbmobject *self, PyTypeObject *cls)
-/*[clinic end generated code: output=139275e9c8b60827 input=aad5a7c886c542f5]*/
+/*[clinic end generated code: output=139275e9c8b60827 input=ba40f0d81eae0f35]*/
{
PyObject *v;
datum key;
@@ -556,8 +556,8 @@ _gdbm.gdbm.nextkey
Returns the key that follows key in the traversal.
-The following code prints every key in the database db, without having
-to create a list in memory that contains them all:
+The following code prints every key in the database db, without
+having to create a list in memory that contains them all:
k = db.firstkey()
while k is not None:
@@ -568,7 +568,7 @@ to create a list in memory that contains them all:
static PyObject *
_gdbm_gdbm_nextkey_impl(gdbmobject *self, PyTypeObject *cls, const char *key,
Py_ssize_t key_length)
-/*[clinic end generated code: output=c81a69300ef41766 input=181f1130d5bfeb1e]*/
+/*[clinic end generated code: output=c81a69300ef41766 input=78293a913b02387e]*/
{
PyObject *v;
datum dbm_key, nextkey;
@@ -599,14 +599,14 @@ Reorganize the database.
If you have carried out a lot of deletions and would like to shrink
the space used by the GDBM file, this routine will reorganize the
-database. GDBM will not shorten the length of a database file except
-by using this reorganization; otherwise, deleted file space will be
-kept and reused as new (key,value) pairs are added.
+database. GDBM will not shorten the length of a database file
+except by using this reorganization; otherwise, deleted file space
+will be kept and reused as new (key,value) pairs are added.
[clinic start generated code]*/
static PyObject *
_gdbm_gdbm_reorganize_impl(gdbmobject *self, PyTypeObject *cls)
-/*[clinic end generated code: output=d77c69e8e3dd644a input=3e3ca0d2ea787861]*/
+/*[clinic end generated code: output=d77c69e8e3dd644a input=d7fcf03051c6f7cd]*/
{
_gdbm_state *state = PyType_GetModuleState(cls);
assert(state != NULL);
diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c
index fa3eceb74d1694..f895c9037485c4 100644
--- a/Modules/_hashopenssl.c
+++ b/Modules/_hashopenssl.c
@@ -2369,18 +2369,17 @@ _hashlib_HMAC_digest_impl(HMACobject *self)
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
_hashlib.HMAC.hexdigest
Return hexadecimal digest of the bytes passed to the update() method so far.
-This may be used to exchange the value safely in email or other non-binary
-environments.
+This may be used to exchange the value safely in email or other
+non-binary environments.
[clinic start generated code]*/
static PyObject *
_hashlib_HMAC_hexdigest_impl(HMACobject *self)
-/*[clinic end generated code: output=80d825be1eaae6a7 input=5e48db83ab1a4d19]*/
+/*[clinic end generated code: output=80d825be1eaae6a7 input=e37a84c36a43787c]*/
{
unsigned char buf[EVP_MAX_MD_SIZE];
Py_ssize_t n = _hmac_digest(self, buf);
@@ -2540,8 +2539,8 @@ _hashlib.get_fips_mode -> int
Determine the OpenSSL FIPS mode of operation.
For OpenSSL 3.0.0 and newer it returns the state of the default provider
-in the default OSSL context. It's not quite the same as FIPS_mode() but good
-enough for unittests.
+in the default OSSL context. It's not quite the same as FIPS_mode() but
+good enough for unittests.
Effectively any non-zero return value indicates FIPS mode;
values other than 1 may have additional significance.
@@ -2549,7 +2548,7 @@ values other than 1 may have additional significance.
static int
_hashlib_get_fips_mode_impl(PyObject *module)
-/*[clinic end generated code: output=87eece1bab4d3fa9 input=2db61538c41c6fef]*/
+/*[clinic end generated code: output=87eece1bab4d3fa9 input=a6cdb6901421d122]*/
{
#ifdef Py_HAS_OPENSSL3_SUPPORT
diff --git a/Modules/_heapqmodule.c b/Modules/_heapqmodule.c
index c705376f4edbf0..014c838694975d 100644
--- a/Modules/_heapqmodule.c
+++ b/Modules/_heapqmodule.c
@@ -247,6 +247,7 @@ _heapq_heapreplace_impl(PyObject *module, PyObject *heap, PyObject *item)
}
/*[clinic input]
+@permit_long_summary
@critical_section heap
_heapq.heappushpop
@@ -262,7 +263,7 @@ a separate call to heappop().
static PyObject *
_heapq_heappushpop_impl(PyObject *module, PyObject *heap, PyObject *item)
-/*[clinic end generated code: output=67231dc98ed5774f input=db05c81b1dd92c44]*/
+/*[clinic end generated code: output=67231dc98ed5774f input=491178a1c7d417ba]*/
{
PyObject *returnitem;
int cmp;
@@ -593,13 +594,13 @@ _heapq.heappushpop_max
Maxheap variant of heappushpop.
-The combined action runs more efficiently than heappush_max() followed by
-a separate call to heappop_max().
+The combined action runs more efficiently than heappush_max()
+followed by a separate call to heappop_max().
[clinic start generated code]*/
static PyObject *
_heapq_heappushpop_max_impl(PyObject *module, PyObject *heap, PyObject *item)
-/*[clinic end generated code: output=ff0019f0941aca0d input=24d0defa6fd6df4a]*/
+/*[clinic end generated code: output=ff0019f0941aca0d input=52030929667a4c08]*/
{
PyObject *returnitem;
int cmp;
diff --git a/Modules/_interpqueuesmodule.c b/Modules/_interpqueuesmodule.c
index b23aa5f39489d9..9979cd3457e101 100644
--- a/Modules/_interpqueuesmodule.c
+++ b/Modules/_interpqueuesmodule.c
@@ -1553,12 +1553,13 @@ _interpqueues.destroy
Clear and destroy the queue.
-Afterward attempts to use the queue will behave as though it never existed.
+Afterward attempts to use the queue will behave as though it never
+existed.
[clinic start generated code]*/
static PyObject *
_interpqueues_destroy_impl(PyObject *module, int64_t qid)
-/*[clinic end generated code: output=46b35623f080cbff input=8632bba87f81e3e9]*/
+/*[clinic end generated code: output=46b35623f080cbff input=75136ad807e28677]*/
{
int err = queue_destroy(&_globals.queues, qid);
if (handle_queue_error(err, module, qid)) {
diff --git a/Modules/_interpretersmodule.c b/Modules/_interpretersmodule.c
index 4c9be1d525d587..e7a91ced48f176 100644
--- a/Modules/_interpretersmodule.c
+++ b/Modules/_interpretersmodule.c
@@ -1219,7 +1219,8 @@ _interpreters.run_func
Execute the body of the provided function in the identified interpreter.
Code objects are also supported. In both cases, closures and args
-are not supported. Methods and other callables are not supported either.
+are not supported. Methods and other callables are not supported
+either.
(See _interpreters.exec().)
[clinic start generated code]*/
@@ -1227,7 +1228,7 @@ are not supported. Methods and other callables are not supported either.
static PyObject *
_interpreters_run_func_impl(PyObject *module, PyObject *id, PyObject *func,
PyObject *shared, int restricted)
-/*[clinic end generated code: output=131f7202ca4a0c5e input=2d62bb9b9eaf4948]*/
+/*[clinic end generated code: output=131f7202ca4a0c5e input=162b29823b33d5cc]*/
{
#define FUNCNAME MODULE_NAME_STR ".run_func"
PyThreadState *tstate = _PyThreadState_GET();
@@ -1374,6 +1375,7 @@ _interpreters_is_running_impl(PyObject *module, PyObject *id, int restricted)
/*[clinic input]
+@permit_long_summary
_interpreters.get_config
id: object
*
@@ -1384,7 +1386,7 @@ Return a representation of the config used to initialize the interpreter.
static PyObject *
_interpreters_get_config_impl(PyObject *module, PyObject *id, int restricted)
-/*[clinic end generated code: output=56773353b9b7224a input=59519a01c22d96d1]*/
+/*[clinic end generated code: output=56773353b9b7224a input=8272d9ea9e4fb42a]*/
{
if (id == Py_None) {
id = NULL;
@@ -1490,19 +1492,19 @@ _interpreters_decref_impl(PyObject *module, PyObject *id, int restricted)
/*[clinic input]
-@permit_long_docstring_body
_interpreters.capture_exception
exc as exc_arg: object = None
Return a snapshot of an exception.
-If "exc" is None then the current exception, if any, is used (but not cleared).
-The returned snapshot is the same as what _interpreters.exec() returns.
+If "exc" is None then the current exception, if any, is used (but not
+cleared). The returned snapshot is the same as what
+_interpreters.exec() returns.
[clinic start generated code]*/
static PyObject *
_interpreters_capture_exception_impl(PyObject *module, PyObject *exc_arg)
-/*[clinic end generated code: output=ef3f5393ef9c88a6 input=6c4dcb78fb722217]*/
+/*[clinic end generated code: output=ef3f5393ef9c88a6 input=4e6289f8f2a47b5b]*/
{
PyObject *exc = exc_arg;
if (exc == NULL || exc == Py_None) {
diff --git a/Modules/_json.c b/Modules/_json.c
index 1f454768355cc0..6c4f38834631d3 100644
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -657,14 +657,14 @@ JSON string. Unescapes all valid JSON string escape sequences and raises
ValueError on attempt to decode an invalid string. If strict is False
then literal control characters are allowed in the string.
-Returns a tuple of the decoded string and the index of the character in s
-after the end quote.
+Returns a tuple of the decoded string and the index of the character in
+s after the end quote.
[clinic start generated code]*/
static PyObject *
py_scanstring_impl(PyObject *module, PyObject *pystr, Py_ssize_t end,
int strict)
-/*[clinic end generated code: output=961740cfae07cdb3 input=cff59e47498f4d8e]*/
+/*[clinic end generated code: output=961740cfae07cdb3 input=6d5abb5947ccc297]*/
{
Py_ssize_t next_end = -1;
PyObject *rval = scanstring_unicode(pystr, end, strict, &next_end);
diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c
index 00ee68dcea2d0d..237aae544a847b 100644
--- a/Modules/_lzmamodule.c
+++ b/Modules/_lzmamodule.c
@@ -1106,7 +1106,6 @@ decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length)
}
/*[clinic input]
-@permit_long_docstring_body
_lzma.LZMADecompressor.decompress
data: Py_buffer
@@ -1114,24 +1113,25 @@ _lzma.LZMADecompressor.decompress
Decompress *data*, returning uncompressed data as bytes.
-If *max_length* is nonnegative, returns at most *max_length* bytes of
-decompressed data. If this limit is reached and further output can be
-produced, *self.needs_input* will be set to ``False``. In this case, the next
-call to *decompress()* may provide *data* as b'' to obtain more of the output.
+If *max_length* is nonnegative, returns at most *max_length* bytes
+of decompressed data. If this limit is reached and further output
+can be produced, *self.needs_input* will be set to ``False``. In
+this case, the next call to *decompress()* may provide *data* as b''
+to obtain more of the output.
-If all of the input data was decompressed and returned (either because this
-was less than *max_length* bytes, or because *max_length* was negative),
-*self.needs_input* will be set to True.
+If all of the input data was decompressed and returned (either
+because this was less than *max_length* bytes, or because
+*max_length* was negative), *self.needs_input* will be set to True.
-Attempting to decompress data after the end of stream is reached raises an
-EOFError. Any data found after the end of the stream is ignored and saved in
-the unused_data attribute.
+Attempting to decompress data after the end of stream is reached
+raises an EOFError. Any data found after the end of the stream is
+ignored and saved in the unused_data attribute.
[clinic start generated code]*/
static PyObject *
_lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data,
Py_ssize_t max_length)
-/*[clinic end generated code: output=ef4e20ec7122241d input=d5cbd45801b4b8b0]*/
+/*[clinic end generated code: output=ef4e20ec7122241d input=0eb62669c4315dee]*/
{
PyObject *result = NULL;
diff --git a/Modules/_multiprocessing/clinic/posixshmem.c.h b/Modules/_multiprocessing/clinic/posixshmem.c.h
index a545ff4d80f067..a4d7273aea718a 100644
--- a/Modules/_multiprocessing/clinic/posixshmem.c.h
+++ b/Modules/_multiprocessing/clinic/posixshmem.c.h
@@ -50,9 +50,9 @@ PyDoc_STRVAR(_posixshmem_shm_unlink__doc__,
"\n"
"Remove a shared memory object (similar to unlink()).\n"
"\n"
-"Remove a shared memory object name, and, once all processes have unmapped\n"
-"the object, de-allocates and destroys the contents of the associated memory\n"
-"region.");
+"Remove a shared memory object name, and, once all processes have\n"
+"unmapped the object, de-allocates and destroys the contents of the\n"
+"associated memory region.");
#define _POSIXSHMEM_SHM_UNLINK_METHODDEF \
{"shm_unlink", (PyCFunction)_posixshmem_shm_unlink, METH_O, _posixshmem_shm_unlink__doc__},
@@ -86,4 +86,4 @@ _posixshmem_shm_unlink(PyObject *module, PyObject *arg)
#ifndef _POSIXSHMEM_SHM_UNLINK_METHODDEF
#define _POSIXSHMEM_SHM_UNLINK_METHODDEF
#endif /* !defined(_POSIXSHMEM_SHM_UNLINK_METHODDEF) */
-/*[clinic end generated code: output=74588a5abba6e36c input=a9049054013a1b77]*/
+/*[clinic end generated code: output=e69afacce7b0595e input=a9049054013a1b77]*/
diff --git a/Modules/_multiprocessing/posixshmem.c b/Modules/_multiprocessing/posixshmem.c
index ab45e4136c7d46..22b4af212662b3 100644
--- a/Modules/_multiprocessing/posixshmem.c
+++ b/Modules/_multiprocessing/posixshmem.c
@@ -81,15 +81,15 @@ _posixshmem.shm_unlink
Remove a shared memory object (similar to unlink()).
-Remove a shared memory object name, and, once all processes have unmapped
-the object, de-allocates and destroys the contents of the associated memory
-region.
+Remove a shared memory object name, and, once all processes have
+unmapped the object, de-allocates and destroys the contents of the
+associated memory region.
[clinic start generated code]*/
static PyObject *
_posixshmem_shm_unlink_impl(PyObject *module, PyObject *path)
-/*[clinic end generated code: output=42f8b23d134b9ff5 input=298369d013dcad63]*/
+/*[clinic end generated code: output=42f8b23d134b9ff5 input=cf7a30ec6503cf78]*/
{
int rv;
int async_err = 0;
diff --git a/Modules/_opcode.c b/Modules/_opcode.c
index dedf17f76dfc9b..2a34559fd1f437 100644
--- a/Modules/_opcode.c
+++ b/Modules/_opcode.c
@@ -119,7 +119,7 @@ _opcode_has_const_impl(PyObject *module, int opcode)
}
/*[clinic input]
-
+@permit_long_summary
_opcode.has_name -> bool
opcode: int
@@ -129,7 +129,7 @@ Return True if the opcode accesses an attribute by name, False otherwise.
static int
_opcode_has_name_impl(PyObject *module, int opcode)
-/*[clinic end generated code: output=b49a83555c2fa517 input=448aa5e4bcc947ba]*/
+/*[clinic end generated code: output=b49a83555c2fa517 input=8faf669024d97fad]*/
{
return IS_VALID_OPCODE(opcode) && OPCODE_HAS_NAME(opcode);
}
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c
index b7f39ea3d499e4..bcee5633987797 100644
--- a/Modules/_posixsubprocess.c
+++ b/Modules/_posixsubprocess.c
@@ -962,7 +962,6 @@ do_fork_exec(char *const exec_array[],
}
/*[clinic input]
-@permit_long_docstring_body
_posixsubprocess.fork_exec as subprocess_fork_exec
args as process_args: object
executable_list: object
@@ -990,15 +989,15 @@ _posixsubprocess.fork_exec as subprocess_fork_exec
Spawn a fresh new child process.
-Fork a child process, close parent file descriptors as appropriate in the
-child and duplicate the few that are needed before calling exec() in the
-child process.
+Fork a child process, close parent file descriptors as appropriate in
+the child and duplicate the few that are needed before calling exec() in
+the child process.
-If close_fds is True, close file descriptors 3 and higher, except those listed
-in the sorted tuple pass_fds.
+If close_fds is True, close file descriptors 3 and higher, except those
+listed in the sorted tuple pass_fds.
-The preexec_fn, if supplied, will be called immediately before closing file
-descriptors and exec.
+The preexec_fn, if supplied, will be called immediately before closing
+file descriptors and exec.
WARNING: preexec_fn is NOT SAFE if your application uses threads.
It may trigger infrequent, difficult to debug deadlocks.
@@ -1023,7 +1022,7 @@ subprocess_fork_exec_impl(PyObject *module, PyObject *process_args,
PyObject *extra_groups_packed,
PyObject *uid_object, int child_umask,
PyObject *preexec_fn)
-/*[clinic end generated code: output=288464dc56e373c7 input=58e0db771686f4f6]*/
+/*[clinic end generated code: output=288464dc56e373c7 input=5e56eac3e036e349]*/
{
PyObject *converted_args = NULL, *fast_args = NULL;
PyObject *preexec_fn_args_tuple = NULL;
diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c
index d5ba36273c8262..7205c095cc87b8 100644
--- a/Modules/_queuemodule.c
+++ b/Modules/_queuemodule.c
@@ -291,15 +291,16 @@ _queue.SimpleQueue.put
Put the item on the queue.
-The optional 'block' and 'timeout' arguments are ignored, as this method
-never blocks. They are provided for compatibility with the Queue class.
+The optional 'block' and 'timeout' arguments are ignored, as this
+method never blocks. They are provided for compatibility with the
+Queue class.
[clinic start generated code]*/
static PyObject *
_queue_SimpleQueue_put_impl(simplequeueobject *self, PyObject *item,
int block, PyObject *timeout)
-/*[clinic end generated code: output=4333136e88f90d8b input=a16dbb33363c0fa8]*/
+/*[clinic end generated code: output=4333136e88f90d8b input=9f9ff270a74670c3]*/
{
if (self->has_threads_waiting) {
HandoffData data = {
@@ -360,10 +361,11 @@ _queue.SimpleQueue.get
Remove and return an item from the queue.
-If optional args 'block' is true and 'timeout' is None (the default),
-block if necessary until an item is available. If 'timeout' is
-a non-negative number, it blocks at most 'timeout' seconds and raises
-the Empty exception if no item was available within that time.
+If optional args 'block' is true and 'timeout' is None (the
+default), block if necessary until an item is available. If
+'timeout' is a non-negative number, it blocks at most 'timeout'
+seconds and raises the Empty exception if no item was available
+within that time.
Otherwise ('block' is false), return an item if one is immediately
available, else raise the Empty exception ('timeout' is ignored
in that case).
@@ -373,7 +375,7 @@ in that case).
static PyObject *
_queue_SimpleQueue_get_impl(simplequeueobject *self, PyTypeObject *cls,
int block, PyObject *timeout_obj)
-/*[clinic end generated code: output=5c2cca914cd1e55b input=f7836c65e5839c51]*/
+/*[clinic end generated code: output=5c2cca914cd1e55b input=afa0889bbc6b4761]*/
{
PyTime_t endtime = 0;
diff --git a/Modules/_sre/sre.c b/Modules/_sre/sre.c
index 044eb6e5f1fb66..7a07ed1d7aca20 100644
--- a/Modules/_sre/sre.c
+++ b/Modules/_sre/sre.c
@@ -2587,6 +2587,7 @@ _pair(Py_ssize_t i1, Py_ssize_t i2)
}
/*[clinic input]
+@permit_long_summary
_sre.SRE_Match.span
group: object(c_default="NULL") = 0
@@ -2597,7 +2598,7 @@ For match object m, return the 2-tuple (m.start(group), m.end(group)).
static PyObject *
_sre_SRE_Match_span_impl(MatchObject *self, PyObject *group)
-/*[clinic end generated code: output=f02ae40594d14fe6 input=8fa6014e982d71d4]*/
+/*[clinic end generated code: output=f02ae40594d14fe6 input=834cfe444f0f55cf]*/
{
Py_ssize_t index = match_getindex(self, group);
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 3224ca7d0f93b9..69472ae01a5016 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -2357,27 +2357,26 @@ _ssl__SSLSocket_compression_impl(PySSLSocket *self)
}
/*[clinic input]
-@permit_long_docstring_body
@critical_section
@getter
_ssl._SSLSocket.context
This changes the context associated with the SSLSocket.
-This is typically used from within a callback function set by the sni_callback
-on the SSLContext to change the certificate information associated with the
-SSLSocket before the cryptographic exchange handshake messages.
+This is typically used from within a callback function set by the
+sni_callback on the SSLContext to change the certificate information
+associated with the SSLSocket before the cryptographic exchange
+handshake messages.
[clinic start generated code]*/
static PyObject *
_ssl__SSLSocket_context_get_impl(PySSLSocket *self)
-/*[clinic end generated code: output=d23e82f72f32e3d7 input=0cc8e773a079295e]*/
+/*[clinic end generated code: output=d23e82f72f32e3d7 input=b845dea1f9710ebe]*/
{
return Py_NewRef(self->ctx);
}
/*[clinic input]
-@permit_long_docstring_body
@critical_section
@setter
_ssl._SSLSocket.context
@@ -2385,7 +2384,7 @@ _ssl._SSLSocket.context
static int
_ssl__SSLSocket_context_set_impl(PySSLSocket *self, PyObject *value)
-/*[clinic end generated code: output=6b0a6cc5cf33d9fe input=f7fc1674b660df96]*/
+/*[clinic end generated code: output=6b0a6cc5cf33d9fe input=48ece77724fd9dd4]*/
{
if (PyObject_TypeCheck(value, self->ctx->state->PySSLContext_Type)) {
Py_SETREF(self->ctx, (PySSLContext *)Py_NewRef(value));
@@ -2635,7 +2634,6 @@ _ssl__SSLSocket_uses_ktls_for_recv_impl(PySSLSocket *self)
#ifdef BIO_get_ktls_send
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
@critical_section
_ssl._SSLSocket.sendfile
fd: int
@@ -2646,9 +2644,9 @@ _ssl._SSLSocket.sendfile
Write size bytes from offset in the file descriptor fd to the SSL connection.
-This method uses the zero-copy technique and returns the number of bytes
-written. It should be called only when Kernel TLS is used for sending data in
-the connection.
+This method uses the zero-copy technique and returns the number of
+bytes written. It should be called only when Kernel TLS is used for
+sending data in the connection.
The meaning of flags is platform dependent.
[clinic start generated code]*/
@@ -2656,7 +2654,7 @@ The meaning of flags is platform dependent.
static PyObject *
_ssl__SSLSocket_sendfile_impl(PySSLSocket *self, int fd, Py_off_t offset,
size_t size, int flags)
-/*[clinic end generated code: output=0c6815b0719ca8d5 input=1f193e681bbae664]*/
+/*[clinic end generated code: output=0c6815b0719ca8d5 input=68c7fbf90c9a8a1b]*/
{
Py_ssize_t retval;
int sockstate;
@@ -3175,22 +3173,22 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self)
}
/*[clinic input]
-@permit_long_docstring_body
@critical_section
_ssl._SSLSocket.get_channel_binding
cb_type: str = "tls-unique"
Get channel binding data for current connection.
-Raise ValueError if the requested `cb_type` is not supported. Return bytes
-of the data or None if the data is not available (e.g. before the handshake).
+Raise ValueError if the requested `cb_type` is not supported.
+Return bytes of the data or None if the data is not available (e.g.
+before the handshake).
Only 'tls-unique' channel binding data from RFC 5929 is supported.
[clinic start generated code]*/
static PyObject *
_ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self,
const char *cb_type)
-/*[clinic end generated code: output=34bac9acb6a61d31 input=26fad522435ecca1]*/
+/*[clinic end generated code: output=34bac9acb6a61d31 input=bed81ef7936535a0]*/
{
char buf[PySSL_CB_MAXLEN];
size_t len;
@@ -5260,22 +5258,22 @@ _servername_callback(SSL *s, int *al, void *args)
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
@critical_section
@getter
_ssl._SSLContext.sni_callback
Set a callback that will be called when a server name is provided by the SSL/TLS client in the SNI extension.
-If the argument is None then the callback is disabled. The method is called
-with the SSLSocket, the server name as a string, and the SSLContext object.
+If the argument is None then the callback is disabled. The method
+is called with the SSLSocket, the server name as a string, and the
+SSLContext object.
See RFC 6066 for details of the SNI extension.
[clinic start generated code]*/
static PyObject *
_ssl__SSLContext_sni_callback_get_impl(PySSLContext *self)
-/*[clinic end generated code: output=961e6575cdfaf036 input=3aee06696b0874d9]*/
+/*[clinic end generated code: output=961e6575cdfaf036 input=a319bc8fc15d6fc8]*/
{
PyObject *cb = self->set_sni_cb;
if (cb == NULL) {
@@ -5286,7 +5284,6 @@ _ssl__SSLContext_sni_callback_get_impl(PySSLContext *self)
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
@critical_section
@setter
_ssl._SSLContext.sni_callback
@@ -5294,7 +5291,7 @@ _ssl._SSLContext.sni_callback
static int
_ssl__SSLContext_sni_callback_set_impl(PySSLContext *self, PyObject *value)
-/*[clinic end generated code: output=b32736c6b891f61a input=332def1d8c81d549]*/
+/*[clinic end generated code: output=b32736c6b891f61a input=402b43fb06c1139e]*/
{
if (self->protocol == PY_SSL_VERSION_TLS_CLIENT) {
PyErr_SetString(PyExc_ValueError,
@@ -5369,16 +5366,16 @@ _ssl._SSLContext.cert_store_stats
Returns quantities of loaded X.509 certificates.
-X.509 certificates with a CA extension and certificate revocation lists
-inside the context's cert store.
+X.509 certificates with a CA extension and certificate revocation
+lists inside the context's cert store.
-NOTE: Certificates in a capath directory aren't loaded unless they have
-been used at least once.
+NOTE: Certificates in a capath directory aren't loaded unless they
+have been used at least once.
[clinic start generated code]*/
static PyObject *
_ssl__SSLContext_cert_store_stats_impl(PySSLContext *self)
-/*[clinic end generated code: output=5f356f4d9cca874d input=d13c6e3f2b48539b]*/
+/*[clinic end generated code: output=5f356f4d9cca874d input=9e5094e094b892a3]*/
{
X509_STORE *store;
STACK_OF(X509_OBJECT) *objs;
@@ -5421,16 +5418,16 @@ _ssl._SSLContext.get_ca_certs
Returns a list of dicts with information of loaded CA certs.
-If the optional argument is True, returns a DER-encoded copy of the CA
-certificate.
+If the optional argument is True, returns a DER-encoded copy of the
+CA certificate.
-NOTE: Certificates in a capath directory aren't loaded unless they have
-been used at least once.
+NOTE: Certificates in a capath directory aren't loaded unless they
+have been used at least once.
[clinic start generated code]*/
static PyObject *
_ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form)
-/*[clinic end generated code: output=0d58f148f37e2938 input=eb0592909c9ad6e7]*/
+/*[clinic end generated code: output=0d58f148f37e2938 input=9f71af5aa4e67076]*/
{
X509_STORE *store;
STACK_OF(X509_OBJECT) *objs;
@@ -6319,13 +6316,13 @@ _ssl.RAND_status
Returns True if the OpenSSL PRNG has been seeded with enough data and False if not.
-It is necessary to seed the PRNG with RAND_add() on some platforms before
-using the ssl() function.
+It is necessary to seed the PRNG with RAND_add() on some platforms
+before using the ssl() function.
[clinic start generated code]*/
static PyObject *
_ssl_RAND_status_impl(PyObject *module)
-/*[clinic end generated code: output=7e0aaa2d39fdc1ad input=aba24a3f3af3b184]*/
+/*[clinic end generated code: output=7e0aaa2d39fdc1ad input=52b061f4a24ff3a1]*/
{
return PyBool_FromLong(RAND_status());
}
@@ -6621,16 +6618,16 @@ _ssl.enum_certificates
Retrieve certificates from Windows' cert store.
-store_name may be one of 'CA', 'ROOT' or 'MY'. The system may provide
-more cert storages, too. The function returns a list of (bytes,
-encoding_type, trust) tuples. The encoding_type flag can be interpreted
-with X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. The trust setting is either
-a set of OIDs or the boolean True.
+store_name may be one of 'CA', 'ROOT' or 'MY'. The system may
+provide more cert storages, too. The function returns a list of
+(bytes, encoding_type, trust) tuples. The encoding_type flag can be
+interpreted with X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. The
+trust setting is either a set of OIDs or the boolean True.
[clinic start generated code]*/
static PyObject *
_ssl_enum_certificates_impl(PyObject *module, const char *store_name)
-/*[clinic end generated code: output=5134dc8bb3a3c893 input=263c22e6c6988cf3]*/
+/*[clinic end generated code: output=5134dc8bb3a3c893 input=ef81b4bd1b7ab8e9]*/
{
HCERTSTORE hCollectionStore = NULL;
PCCERT_CONTEXT pCertCtx = NULL;
diff --git a/Modules/_struct.c b/Modules/_struct.c
index 3a970d99bb3d6d..8c611a708d02a9 100644
--- a/Modules/_struct.c
+++ b/Modules/_struct.c
@@ -2721,6 +2721,7 @@ pack_into_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer,
}
/*[clinic input]
+@permit_long_summary
unpack
format as s_object: cache_struct
@@ -2735,12 +2736,13 @@ for more on format strings.
static PyObject *
unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
-/*[clinic end generated code: output=48ddd4d88eca8551 input=7df28c5d0b5b6f4e]*/
+/*[clinic end generated code: output=48ddd4d88eca8551 input=53a60a65830bd1e1]*/
{
return Struct_unpack_impl(s_object, buffer);
}
/*[clinic input]
+@permit_long_summary
unpack_from
format as s_object: cache_struct
@@ -2757,7 +2759,7 @@ help(struct) for more on format strings.
static PyObject *
unpack_from_impl(PyObject *module, PyStructObject *s_object,
Py_buffer *buffer, Py_ssize_t offset)
-/*[clinic end generated code: output=1042631674c6e0d3 input=599262b23559f6c5]*/
+/*[clinic end generated code: output=1042631674c6e0d3 input=3e46619756fb0293]*/
{
return Struct_unpack_from_impl(s_object, buffer, offset);
}
diff --git a/Modules/_testlimitedcapi/clinic/long.c.h b/Modules/_testlimitedcapi/clinic/long.c.h
index ebaeb53921a82f..f9852aba266a57 100644
--- a/Modules/_testlimitedcapi/clinic/long.c.h
+++ b/Modules/_testlimitedcapi/clinic/long.c.h
@@ -84,8 +84,8 @@ PyDoc_STRVAR(_testlimitedcapi_test_long_as_size_t__doc__,
"\n"
"Test the PyLong_As{Size,Ssize}_t API.\n"
"\n"
-"At present this just tests that non-integer arguments are handled correctly.\n"
-"It should be extended to test overflow handling.");
+"At present this just tests that non-integer arguments are handled\n"
+"correctly. It should be extended to test overflow handling.");
#define _TESTLIMITEDCAPI_TEST_LONG_AS_SIZE_T_METHODDEF \
{"test_long_as_size_t", (PyCFunction)_testlimitedcapi_test_long_as_size_t, METH_NOARGS, _testlimitedcapi_test_long_as_size_t__doc__},
@@ -140,4 +140,4 @@ PyDoc_STRVAR(_testlimitedcapi_PyLong_AsInt__doc__,
#define _TESTLIMITEDCAPI_PYLONG_ASINT_METHODDEF \
{"PyLong_AsInt", (PyCFunction)_testlimitedcapi_PyLong_AsInt, METH_O, _testlimitedcapi_PyLong_AsInt__doc__},
-/*[clinic end generated code: output=bc52b73c599f96c2 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=fb5c95bd0a4bdad8 input=a9049054013a1b77]*/
diff --git a/Modules/_testlimitedcapi/long.c b/Modules/_testlimitedcapi/long.c
index 34bc7331da9247..99b9e96760d50d 100644
--- a/Modules/_testlimitedcapi/long.c
+++ b/Modules/_testlimitedcapi/long.c
@@ -451,13 +451,13 @@ _testlimitedcapi.test_long_as_size_t
Test the PyLong_As{Size,Ssize}_t API.
-At present this just tests that non-integer arguments are handled correctly.
-It should be extended to test overflow handling.
+At present this just tests that non-integer arguments are handled
+correctly. It should be extended to test overflow handling.
[clinic start generated code]*/
static PyObject *
_testlimitedcapi_test_long_as_size_t_impl(PyObject *module)
-/*[clinic end generated code: output=297a9f14a42f55af input=8923d8f2038c46f4]*/
+/*[clinic end generated code: output=297a9f14a42f55af input=692e73744b35bf6e]*/
{
size_t out_u;
Py_ssize_t out_s;
diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c
index 128e3f79ecd99c..57ba61e67f1d7f 100644
--- a/Modules/_testmultiphase.c
+++ b/Modules/_testmultiphase.c
@@ -141,14 +141,14 @@ _testmultiphase.StateAccessType.get_defining_module
Return the module of the defining class.
-Also tests that result of PyType_GetModuleByDef matches defining_class's
-module.
+Also tests that result of PyType_GetModuleByDef matches
+defining_class's module.
[clinic start generated code]*/
static PyObject *
_testmultiphase_StateAccessType_get_defining_module_impl(StateAccessTypeObject *self,
PyTypeObject *cls)
-/*[clinic end generated code: output=ba2a14284a5d0921 input=d2c7245c8a9d06f8]*/
+/*[clinic end generated code: output=ba2a14284a5d0921 input=903e7f66555d65ae]*/
{
PyObject *retval;
retval = PyType_GetModule(cls);
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index 135b53111014d1..7a34c5a5a0ef6b 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -820,8 +820,8 @@ _thread.lock.acquire
Lock the lock.
-Without argument, this blocks if the lock is already
-locked (even by the same thread), waiting for another thread to release
+Without argument, this blocks if the lock is already locked
+(even by the same thread), waiting for another thread to release
the lock, and return True once the lock is acquired.
With an argument, this will only block if the argument is true,
and the return value reflects whether the lock is acquired.
@@ -831,7 +831,7 @@ The blocking operation is interruptible.
static PyObject *
_thread_lock_acquire_impl(lockobject *self, int blocking,
PyObject *timeoutobj)
-/*[clinic end generated code: output=569d6b25d508bf6f input=13e999649bc1c798]*/
+/*[clinic end generated code: output=569d6b25d508bf6f input=73e75b3d2ec32677]*/
{
PyTime_t timeout;
@@ -1131,19 +1131,19 @@ _thread.RLock.release
Release the lock.
-Allows another thread that is blocked waiting for
-the lock to acquire the lock. The lock must be in the locked state,
+Allows another thread that is blocked waiting for the lock
+to acquire the lock. The lock must be in the locked state,
and must be locked by the same thread that unlocks it; otherwise a
`RuntimeError` is raised.
-Do note that if the lock was acquire()d several times in a row by the
-current thread, release() needs to be called as many times for the lock
-to be available for other threads.
+Do note that if the lock was acquire()d several times in a row by
+the current thread, release() needs to be called as many times for
+the lock to be available for other threads.
[clinic start generated code]*/
static PyObject *
_thread_RLock_release_impl(rlockobject *self)
-/*[clinic end generated code: output=51f4a013c5fae2c5 input=d425daf1a5782e63]*/
+/*[clinic end generated code: output=51f4a013c5fae2c5 input=7c188f60189be13a]*/
{
if (_PyRecursiveMutex_TryUnlock(&self->lock) < 0) {
PyErr_SetString(PyExc_RuntimeError,
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
index bbe2a428454e0c..58fdabecf16ada 100644
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -3219,7 +3219,6 @@ _tkinter_create_impl(PyObject *module, const char *screenName,
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
_tkinter.setbusywaitinterval
new_val: int
@@ -3227,12 +3226,13 @@ _tkinter.setbusywaitinterval
Set the busy-wait interval in milliseconds between successive calls to Tcl_DoOneEvent in a threaded Python interpreter.
-It should be set to a divisor of the maximum time between frames in an animation.
+It should be set to a divisor of the maximum time between frames in
+an animation.
[clinic start generated code]*/
static PyObject *
_tkinter_setbusywaitinterval_impl(PyObject *module, int new_val)
-/*[clinic end generated code: output=42bf7757dc2d0ab6 input=07b82a04b56625e1]*/
+/*[clinic end generated code: output=42bf7757dc2d0ab6 input=0360dd95c8bd8619]*/
{
if (new_val < 0) {
PyErr_SetString(PyExc_ValueError,
diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c
index 56d83ea0dcb2a7..a97b0e0bfeefba 100644
--- a/Modules/_tracemalloc.c
+++ b/Modules/_tracemalloc.c
@@ -11,6 +11,7 @@ module _tracemalloc
/*[clinic input]
+@permit_long_summary
_tracemalloc.is_tracing
Return True if the tracemalloc module is tracing Python memory allocations.
@@ -18,7 +19,7 @@ Return True if the tracemalloc module is tracing Python memory allocations.
static PyObject *
_tracemalloc_is_tracing_impl(PyObject *module)
-/*[clinic end generated code: output=2d763b42601cd3ef input=af104b0a00192f63]*/
+/*[clinic end generated code: output=2d763b42601cd3ef input=cac4fc9096babeac]*/
{
return PyBool_FromLong(_PyTraceMalloc_IsTracing());
}
@@ -153,6 +154,7 @@ _tracemalloc_get_tracemalloc_memory_impl(PyObject *module)
/*[clinic input]
+@permit_long_summary
_tracemalloc.get_traced_memory
Get the current size and peak size of memory blocks traced by tracemalloc.
@@ -162,7 +164,7 @@ Returns a tuple: (current: int, peak: int).
static PyObject *
_tracemalloc_get_traced_memory_impl(PyObject *module)
-/*[clinic end generated code: output=5b167189adb9e782 input=61ddb5478400ff66]*/
+/*[clinic end generated code: output=5b167189adb9e782 input=b06e7a1a4914fc21]*/
{
return _PyTraceMalloc_GetTracedMemory();
}
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index 472c59ea8c9882..7f367d639983ae 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -1534,13 +1534,13 @@ array.array.buffer_info
Return a tuple (address, length) giving the current memory address and the length in items of the buffer used to hold array's contents.
-The length should be multiplied by the itemsize attribute to calculate
-the buffer length in bytes.
+The length should be multiplied by the itemsize attribute to
+calculate the buffer length in bytes.
[clinic start generated code]*/
static PyObject *
array_array_buffer_info_impl(arrayobject *self)
-/*[clinic end generated code: output=9b2a4ec3ae7e98e7 input=63d9ad83ba60cda8]*/
+/*[clinic end generated code: output=9b2a4ec3ae7e98e7 input=c2771b9f6a8e1c86]*/
{
PyObject* item1 = PyLong_FromVoidPtr(self->ob_item);
if (item1 == NULL) {
@@ -1572,19 +1572,18 @@ array_array_append_impl(arrayobject *self, PyObject *v)
}
/*[clinic input]
-@permit_long_docstring_body
array.array.byteswap
Byteswap all items of the array.
-If the items in the array are not 1, 2, 4, 8 or 16 bytes in size, RuntimeError
-is raised. Note, that for complex types the order of
+If the items in the array are not 1, 2, 4, 8 or 16 bytes in size,
+RuntimeError is raised. Note, that for complex types the order of
components (the real part, followed by imaginary part) is preserved.
[clinic start generated code]*/
static PyObject *
array_array_byteswap_impl(arrayobject *self)
-/*[clinic end generated code: output=5f8236cbdf0d90b5 input=aafda275f48191d0]*/
+/*[clinic end generated code: output=5f8236cbdf0d90b5 input=8732f800e1b47bac]*/
{
char *p;
Py_ssize_t i;
@@ -1967,7 +1966,6 @@ array_array_tobytes_impl(arrayobject *self)
}
/*[clinic input]
-@permit_long_docstring_body
array.array.fromunicode
ustr: unicode
@@ -1975,14 +1973,14 @@ array.array.fromunicode
Extends this array with data from the unicode string ustr.
-The array must be a unicode type array; otherwise a ValueError is raised.
-Use array.frombytes(ustr.encode(...)) to append Unicode data to an array of
-some other type.
+The array must be a unicode type array; otherwise a ValueError is
+raised. Use array.frombytes(ustr.encode(...)) to append Unicode
+data to an array of some other type.
[clinic start generated code]*/
static PyObject *
array_array_fromunicode_impl(arrayobject *self, PyObject *ustr)
-/*[clinic end generated code: output=24359f5e001a7f2b input=158d47c302f27ca1]*/
+/*[clinic end generated code: output=24359f5e001a7f2b input=01fa592ec7b948b6]*/
{
const char *typecode = self->ob_descr->typecode;
if (strcmp(typecode, "u") != 0 && strcmp(typecode, "w") != 0) {
@@ -2030,19 +2028,19 @@ array_array_fromunicode_impl(arrayobject *self, PyObject *ustr)
}
/*[clinic input]
-@permit_long_docstring_body
array.array.tounicode
Extends this array with data from the unicode string ustr.
-Convert the array to a unicode string. The array must be a unicode type array;
-otherwise a ValueError is raised. Use array.tobytes().decode() to obtain a
-unicode string from an array of some other type.
+Convert the array to a unicode string. The array must be a unicode
+type array; otherwise a ValueError is raised. Use
+array.tobytes().decode() to obtain a unicode string from an array of
+some other type.
[clinic start generated code]*/
static PyObject *
array_array_tounicode_impl(arrayobject *self)
-/*[clinic end generated code: output=08e442378336e1ef input=6690997213d219db]*/
+/*[clinic end generated code: output=08e442378336e1ef input=d4d5f398aa71a2be]*/
{
const char *typecode = self->ob_descr->typecode;
if (strcmp(typecode, "u") != 0 && strcmp(typecode, "w") != 0) {
diff --git a/Modules/cjkcodecs/clinic/multibytecodec.c.h b/Modules/cjkcodecs/clinic/multibytecodec.c.h
index b3663180d726e5..32588b0561e1ac 100644
--- a/Modules/cjkcodecs/clinic/multibytecodec.c.h
+++ b/Modules/cjkcodecs/clinic/multibytecodec.c.h
@@ -14,10 +14,11 @@ PyDoc_STRVAR(_multibytecodec_MultibyteCodec_encode__doc__,
"\n"
"Return an encoded string version of \'input\'.\n"
"\n"
-"\'errors\' may be given to set a different error handling scheme. Default is\n"
-"\'strict\' meaning that encoding errors raise a UnicodeEncodeError. Other possible\n"
-"values are \'ignore\', \'replace\' and \'xmlcharrefreplace\' as well as any other name\n"
-"registered with codecs.register_error that can handle UnicodeEncodeErrors.");
+"\'errors\' may be given to set a different error handling scheme.\n"
+"Default is \'strict\' meaning that encoding errors raise\n"
+"a UnicodeEncodeError. Other possible values are \'ignore\', \'replace\'\n"
+"and \'xmlcharrefreplace\' as well as any other name registered with\n"
+"codecs.register_error that can handle UnicodeEncodeErrors.");
#define _MULTIBYTECODEC_MULTIBYTECODEC_ENCODE_METHODDEF \
{"encode", _PyCFunction_CAST(_multibytecodec_MultibyteCodec_encode), METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteCodec_encode__doc__},
@@ -103,9 +104,10 @@ PyDoc_STRVAR(_multibytecodec_MultibyteCodec_decode__doc__,
"\n"
"Decodes \'input\'.\n"
"\n"
-"\'errors\' may be given to set a different error handling scheme. Default is\n"
-"\'strict\' meaning that encoding errors raise a UnicodeDecodeError. Other possible\n"
-"values are \'ignore\' and \'replace\' as well as any other name registered with\n"
+"\'errors\' may be given to set a different error handling scheme.\n"
+"Default is \'strict\' meaning that encoding errors raise\n"
+"a UnicodeDecodeError. Other possible values are \'ignore\' and\n"
+"\'replace\' as well as any other name registered with\n"
"codecs.register_error that is able to handle UnicodeDecodeErrors.\"");
#define _MULTIBYTECODEC_MULTIBYTECODEC_DECODE_METHODDEF \
@@ -696,4 +698,4 @@ PyDoc_STRVAR(_multibytecodec___create_codec__doc__,
#define _MULTIBYTECODEC___CREATE_CODEC_METHODDEF \
{"__create_codec", (PyCFunction)_multibytecodec___create_codec, METH_O, _multibytecodec___create_codec__doc__},
-/*[clinic end generated code: output=014f4f6bb9d29594 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=a84b1544d7d01abb input=a9049054013a1b77]*/
diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c
index f1124147e2b0a7..32c96c9d2cb3cd 100644
--- a/Modules/cjkcodecs/multibytecodec.c
+++ b/Modules/cjkcodecs/multibytecodec.c
@@ -582,7 +582,6 @@ multibytecodec_encode(const MultibyteCodec *codec,
}
/*[clinic input]
-@permit_long_docstring_body
_multibytecodec.MultibyteCodec.encode
input: object
@@ -590,17 +589,18 @@ _multibytecodec.MultibyteCodec.encode
Return an encoded string version of 'input'.
-'errors' may be given to set a different error handling scheme. Default is
-'strict' meaning that encoding errors raise a UnicodeEncodeError. Other possible
-values are 'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name
-registered with codecs.register_error that can handle UnicodeEncodeErrors.
+'errors' may be given to set a different error handling scheme.
+Default is 'strict' meaning that encoding errors raise
+a UnicodeEncodeError. Other possible values are 'ignore', 'replace'
+and 'xmlcharrefreplace' as well as any other name registered with
+codecs.register_error that can handle UnicodeEncodeErrors.
[clinic start generated code]*/
static PyObject *
_multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self,
PyObject *input,
const char *errors)
-/*[clinic end generated code: output=7b26652045ba56a9 input=0980aede2c564df8]*/
+/*[clinic end generated code: output=7b26652045ba56a9 input=980002ed1447697b]*/
{
MultibyteCodec_State state;
PyObject *errorcb, *r, *ucvt;
@@ -648,7 +648,6 @@ _multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self,
}
/*[clinic input]
-@permit_long_docstring_body
_multibytecodec.MultibyteCodec.decode
input: Py_buffer
@@ -656,9 +655,10 @@ _multibytecodec.MultibyteCodec.decode
Decodes 'input'.
-'errors' may be given to set a different error handling scheme. Default is
-'strict' meaning that encoding errors raise a UnicodeDecodeError. Other possible
-values are 'ignore' and 'replace' as well as any other name registered with
+'errors' may be given to set a different error handling scheme.
+Default is 'strict' meaning that encoding errors raise
+a UnicodeDecodeError. Other possible values are 'ignore' and
+'replace' as well as any other name registered with
codecs.register_error that is able to handle UnicodeDecodeErrors."
[clinic start generated code]*/
@@ -666,7 +666,7 @@ static PyObject *
_multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self,
Py_buffer *input,
const char *errors)
-/*[clinic end generated code: output=ff419f65bad6cc77 input=2c657ef914600c7c]*/
+/*[clinic end generated code: output=ff419f65bad6cc77 input=dbf93d8bb98ca440]*/
{
MultibyteCodec_State state;
MultibyteDecodeBuffer buf;
diff --git a/Modules/clinic/_abc.c.h b/Modules/clinic/_abc.c.h
index 04681fa2206a2a..fa1c57dc26bf85 100644
--- a/Modules/clinic/_abc.c.h
+++ b/Modules/clinic/_abc.c.h
@@ -146,9 +146,9 @@ PyDoc_STRVAR(_abc_get_cache_token__doc__,
"\n"
"Returns the current ABC cache token.\n"
"\n"
-"The token is an opaque object (supporting equality testing) identifying the\n"
-"current version of the ABC cache for virtual subclasses. The token changes\n"
-"with every call to register() on any ABC.");
+"The token is an opaque object (supporting equality testing) identifying\n"
+"the current version of the ABC cache for virtual subclasses. The token\n"
+"changes with every call to register() on any ABC.");
#define _ABC_GET_CACHE_TOKEN_METHODDEF \
{"get_cache_token", (PyCFunction)_abc_get_cache_token, METH_NOARGS, _abc_get_cache_token__doc__},
@@ -161,4 +161,4 @@ _abc_get_cache_token(PyObject *module, PyObject *Py_UNUSED(ignored))
{
return _abc_get_cache_token_impl(module);
}
-/*[clinic end generated code: output=1989b6716c950e17 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=b05d599656aeb1e1 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h
index 66953d74213b66..f07a09df5ac7ae 100644
--- a/Modules/clinic/_asynciomodule.c.h
+++ b/Modules/clinic/_asynciomodule.c.h
@@ -90,7 +90,8 @@ PyDoc_STRVAR(_asyncio_Future_result__doc__,
"\n"
"If the future has been cancelled, raises CancelledError. If the\n"
"future\'s result isn\'t yet available, raises InvalidStateError. If\n"
-"the future is done and has an exception set, this exception is raised.");
+"the future is done and has an exception set, this exception is\n"
+"raised.");
#define _ASYNCIO_FUTURE_RESULT_METHODDEF \
{"result", (PyCFunction)_asyncio_Future_result, METH_NOARGS, _asyncio_Future_result__doc__},
@@ -250,8 +251,8 @@ PyDoc_STRVAR(_asyncio_Future_add_done_callback__doc__,
"\n"
"Add a callback to be run when the future becomes done.\n"
"\n"
-"The callback is called with a single argument - the future object. If\n"
-"the future is already done when this is called, the callback is\n"
+"The callback is called with a single argument - the future object.\n"
+"If the future is already done when this is called, the callback is\n"
"scheduled with call_soon.");
#define _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF \
@@ -371,9 +372,9 @@ PyDoc_STRVAR(_asyncio_Future_cancel__doc__,
"\n"
"Cancel the future and schedule callbacks.\n"
"\n"
-"If the future is already done or cancelled, return False. Otherwise,\n"
-"change the future\'s state to cancelled, schedule the callbacks and\n"
-"return True.");
+"If the future is already done or cancelled, return False.\n"
+"Otherwise, change the future\'s state to cancelled, schedule the\n"
+"callbacks and return True.");
#define _ASYNCIO_FUTURE_CANCEL_METHODDEF \
{"cancel", _PyCFunction_CAST(_asyncio_Future_cancel), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_cancel__doc__},
@@ -465,8 +466,8 @@ PyDoc_STRVAR(_asyncio_Future_done__doc__,
"\n"
"Return True if the future is done.\n"
"\n"
-"Done means either that a result / exception are available, or that the\n"
-"future was cancelled.");
+"Done means either that a result / exception are available, or that\n"
+"the future was cancelled.");
#define _ASYNCIO_FUTURE_DONE_METHODDEF \
{"done", (PyCFunction)_asyncio_Future_done, METH_NOARGS, _asyncio_Future_done__doc__},
@@ -2232,4 +2233,4 @@ _asyncio_future_discard_from_awaited_by(PyObject *module, PyObject *const *args,
exit:
return return_value;
}
-/*[clinic end generated code: output=b69948ed810591d9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=32996fb47c48245b input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_bisectmodule.c.h b/Modules/clinic/_bisectmodule.c.h
index 8f3492cd54b5f2..454131faf4112b 100644
--- a/Modules/clinic/_bisectmodule.c.h
+++ b/Modules/clinic/_bisectmodule.c.h
@@ -16,8 +16,8 @@ PyDoc_STRVAR(_bisect_bisect_right__doc__,
"Return the index where to insert item x in list a, assuming a is sorted.\n"
"\n"
"The return value i is such that all e in a[:i] have e <= x, and all e in\n"
-"a[i:] have e > x. So if x already appears in the list, a.insert(i, x) will\n"
-"insert just after the rightmost x already there.\n"
+"a[i:] have e > x. So if x already appears in the list, a.insert(i, x)\n"
+"will insert just after the rightmost x already there.\n"
"\n"
"Optional args lo (default 0) and hi (default len(a)) bound the\n"
"slice of a to be searched.\n"
@@ -245,8 +245,8 @@ PyDoc_STRVAR(_bisect_bisect_left__doc__,
"Return the index where to insert item x in list a, assuming a is sorted.\n"
"\n"
"The return value i is such that all e in a[:i] have e < x, and all e in\n"
-"a[i:] have e >= x. So if x already appears in the list, a.insert(i, x) will\n"
-"insert just before the leftmost x already there.\n"
+"a[i:] have e >= x. So if x already appears in the list, a.insert(i, x)\n"
+"will insert just before the leftmost x already there.\n"
"\n"
"Optional args lo (default 0) and hi (default len(a)) bound the\n"
"slice of a to be searched.\n"
@@ -466,4 +466,4 @@ _bisect_insort_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P
exit:
return return_value;
}
-/*[clinic end generated code: output=a3c44ed440dd6d81 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=62345f14c5c01639 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h
index 2bc6524b6a973b..30f2c7965e73ae 100644
--- a/Modules/clinic/_bz2module.c.h
+++ b/Modules/clinic/_bz2module.c.h
@@ -116,18 +116,19 @@ PyDoc_STRVAR(_bz2_BZ2Decompressor_decompress__doc__,
"\n"
"Decompress *data*, returning uncompressed data as bytes.\n"
"\n"
-"If *max_length* is nonnegative, returns at most *max_length* bytes of\n"
-"decompressed data. If this limit is reached and further output can be\n"
-"produced, *self.needs_input* will be set to ``False``. In this case, the next\n"
-"call to *decompress()* may provide *data* as b\'\' to obtain more of the output.\n"
+"If *max_length* is nonnegative, returns at most *max_length* bytes\n"
+"of decompressed data. If this limit is reached and further output\n"
+"can be produced, *self.needs_input* will be set to ``False``. In\n"
+"this case, the next call to *decompress()* may provide *data* as b\'\'\n"
+"to obtain more of the output.\n"
"\n"
-"If all of the input data was decompressed and returned (either because this\n"
-"was less than *max_length* bytes, or because *max_length* was negative),\n"
-"*self.needs_input* will be set to True.\n"
+"If all of the input data was decompressed and returned (either\n"
+"because this was less than *max_length* bytes, or because\n"
+"*max_length* was negative), *self.needs_input* will be set to True.\n"
"\n"
-"Attempting to decompress data after the end of stream is reached raises an\n"
-"EOFError. Any data found after the end of the stream is ignored and saved in\n"
-"the unused_data attribute.");
+"Attempting to decompress data after the end of stream is reached\n"
+"raises an EOFError. Any data found after the end of the stream is\n"
+"ignored and saved in the unused_data attribute.");
#define _BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF \
{"decompress", _PyCFunction_CAST(_bz2_BZ2Decompressor_decompress), METH_FASTCALL|METH_KEYWORDS, _bz2_BZ2Decompressor_decompress__doc__},
@@ -237,4 +238,4 @@ _bz2_BZ2Decompressor(PyTypeObject *type, PyObject *args, PyObject *kwargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=552ac6d4c5a101b7 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=1dce5396d592bad7 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_codecsmodule.c.h b/Modules/clinic/_codecsmodule.c.h
index 9e2a7950ebde64..4a40dc660b621c 100644
--- a/Modules/clinic/_codecsmodule.c.h
+++ b/Modules/clinic/_codecsmodule.c.h
@@ -14,9 +14,10 @@ PyDoc_STRVAR(_codecs_register__doc__,
"\n"
"Register a codec search function.\n"
"\n"
-"Search functions are expected to take one argument, the encoding name in\n"
-"all lower case letters, and either return None, or a tuple of functions\n"
-"(encoder, decoder, stream_reader, stream_writer) (or a CodecInfo object).");
+"Search functions are expected to take one argument, the encoding\n"
+"name in all lower case letters, and either return None, or a tuple\n"
+"of functions (encoder, decoder, stream_reader, stream_writer) (or\n"
+"a CodecInfo object).");
#define _CODECS_REGISTER_METHODDEF \
{"register", (PyCFunction)_codecs_register, METH_O, _codecs_register__doc__},
@@ -76,10 +77,10 @@ PyDoc_STRVAR(_codecs_encode__doc__,
"Encodes obj using the codec registered for encoding.\n"
"\n"
"The default encoding is \'utf-8\'. errors may be given to set a\n"
-"different error handling scheme. Default is \'strict\' meaning that encoding\n"
-"errors raise a ValueError. Other possible values are \'ignore\', \'replace\'\n"
-"and \'backslashreplace\' as well as any other name registered with\n"
-"codecs.register_error that can handle ValueErrors.");
+"different error handling scheme. Default is \'strict\' meaning that\n"
+"encoding errors raise a ValueError. Other possible values are \'ignore\',\n"
+"\'replace\' and \'backslashreplace\' as well as any other name registered\n"
+"with codecs.register_error that can handle ValueErrors.");
#define _CODECS_ENCODE_METHODDEF \
{"encode", _PyCFunction_CAST(_codecs_encode), METH_FASTCALL|METH_KEYWORDS, _codecs_encode__doc__},
@@ -179,10 +180,10 @@ PyDoc_STRVAR(_codecs_decode__doc__,
"Decodes obj using the codec registered for encoding.\n"
"\n"
"Default encoding is \'utf-8\'. errors may be given to set a\n"
-"different error handling scheme. Default is \'strict\' meaning that encoding\n"
-"errors raise a ValueError. Other possible values are \'ignore\', \'replace\'\n"
-"and \'backslashreplace\' as well as any other name registered with\n"
-"codecs.register_error that can handle ValueErrors.");
+"different error handling scheme. Default is \'strict\' meaning that\n"
+"encoding errors raise a ValueError. Other possible values are \'ignore\',\n"
+"\'replace\' and \'backslashreplace\' as well as any other name registered\n"
+"with codecs.register_error that can handle ValueErrors.");
#define _CODECS_DECODE_METHODDEF \
{"decode", _PyCFunction_CAST(_codecs_decode), METH_FASTCALL|METH_KEYWORDS, _codecs_decode__doc__},
@@ -2649,8 +2650,9 @@ PyDoc_STRVAR(_codecs_register_error__doc__,
"Register the specified error handler under the name errors.\n"
"\n"
"handler must be a callable object, that will be called with an exception\n"
-"instance containing information about the location of the encoding/decoding\n"
-"error and must return a (replacement, new position) tuple.");
+"instance containing information about the location of the\n"
+"encoding/decoding error and must return a (replacement, new position)\n"
+"tuple.");
#define _CODECS_REGISTER_ERROR_METHODDEF \
{"register_error", _PyCFunction_CAST(_codecs_register_error), METH_FASTCALL, _codecs_register_error__doc__},
@@ -2745,8 +2747,8 @@ PyDoc_STRVAR(_codecs_lookup_error__doc__,
"\n"
"lookup_error(errors) -> handler\n"
"\n"
-"Return the error handler for the specified error handling name or raise a\n"
-"LookupError, if no handler exists under this name.");
+"Return the error handler for the specified error handling name or raise\n"
+"a LookupError, if no handler exists under this name.");
#define _CODECS_LOOKUP_ERROR_METHODDEF \
{"lookup_error", (PyCFunction)_codecs_lookup_error, METH_O, _codecs_lookup_error__doc__},
@@ -2866,4 +2868,4 @@ _codecs__normalize_encoding(PyObject *module, PyObject *const *args, Py_ssize_t
#ifndef _CODECS_CODE_PAGE_ENCODE_METHODDEF
#define _CODECS_CODE_PAGE_ENCODE_METHODDEF
#endif /* !defined(_CODECS_CODE_PAGE_ENCODE_METHODDEF) */
-/*[clinic end generated code: output=a968c493bb28be3e input=a9049054013a1b77]*/
+/*[clinic end generated code: output=505edef891a06329 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_datetimemodule.c.h b/Modules/clinic/_datetimemodule.c.h
index ee621c150c31e4..fac41e7aefc7f4 100644
--- a/Modules/clinic/_datetimemodule.c.h
+++ b/Modules/clinic/_datetimemodule.c.h
@@ -214,8 +214,8 @@ PyDoc_STRVAR(datetime_date_fromtimestamp__doc__,
"\n"
"Create a date from a POSIX timestamp.\n"
"\n"
-"The timestamp is a number, e.g. created via time.time(), that is interpreted\n"
-"as local time.");
+"The timestamp is a number, e.g. created via time.time(), that is\n"
+"interpreted as local time.");
#define DATETIME_DATE_FROMTIMESTAMP_METHODDEF \
{"fromtimestamp", (PyCFunction)datetime_date_fromtimestamp, METH_O|METH_CLASS, datetime_date_fromtimestamp__doc__},
@@ -897,8 +897,8 @@ PyDoc_STRVAR(datetime_time_isoformat__doc__,
"\n"
"Return the time formatted according to ISO.\n"
"\n"
-"The full format is \'HH:MM:SS.mmmmmm+zz:zz\'. By default, the fractional\n"
-"part is omitted if self.microsecond == 0.\n"
+"The full format is \'HH:MM:SS.mmmmmm+zz:zz\'. By default, the\n"
+"fractional part is omitted if self.microsecond == 0.\n"
"\n"
"The optional argument timespec specifies the number of additional\n"
"terms of the time to include. Valid options are \'auto\', \'hours\',\n"
@@ -979,7 +979,8 @@ PyDoc_STRVAR(datetime_time_strftime__doc__,
"\n"
"Format using strftime().\n"
"\n"
-"The date part of the timestamp passed to underlying strftime should not be used.\n"
+"The date part of the timestamp passed to underlying strftime should\n"
+"not be used.\n"
"\n"
"For a list of supported format codes, see the documentation:\n"
" https://docs.python.org/3/library/datetime.html#format-codes");
@@ -1269,8 +1270,8 @@ PyDoc_STRVAR(datetime_datetime__doc__,
"\n"
"A combination of a date and a time.\n"
"\n"
-"The year, month and day arguments are required. tzinfo may be None, or an\n"
-"instance of a tzinfo subclass. The remaining arguments may be ints.");
+"The year, month and day arguments are required. tzinfo may be None, or\n"
+"an instance of a tzinfo subclass. The remaining arguments may be ints.");
static PyObject *
datetime_datetime_impl(PyTypeObject *type, int year, int month, int day,
@@ -1491,8 +1492,8 @@ PyDoc_STRVAR(datetime_datetime_fromtimestamp__doc__,
"\n"
"Create a datetime from a POSIX timestamp.\n"
"\n"
-"The timestamp is a number, e.g. created via time.time(), that is interpreted\n"
-"as local time.");
+"The timestamp is a number, e.g. created via time.time(), that is\n"
+"interpreted as local time.");
#define DATETIME_DATETIME_FROMTIMESTAMP_METHODDEF \
{"fromtimestamp", _PyCFunction_CAST(datetime_datetime_fromtimestamp), METH_FASTCALL|METH_KEYWORDS|METH_CLASS, datetime_datetime_fromtimestamp__doc__},
@@ -2090,4 +2091,4 @@ datetime_datetime___reduce__(PyObject *self, PyObject *Py_UNUSED(ignored))
{
return datetime_datetime___reduce___impl((PyDateTime_DateTime *)self);
}
-/*[clinic end generated code: output=69658acff6a43ac4 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=8f63509398651723 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_dbmmodule.c.h b/Modules/clinic/_dbmmodule.c.h
index 091ce9edc43d4b..6c979a4b0081df 100644
--- a/Modules/clinic/_dbmmodule.c.h
+++ b/Modules/clinic/_dbmmodule.c.h
@@ -113,7 +113,8 @@ PyDoc_STRVAR(_dbm_dbm_setdefault__doc__,
"\n"
"Return the value for key if present, otherwise default.\n"
"\n"
-"If key is not in the database, it is inserted with default as the value.");
+"If key is not in the database, it is inserted with default as the\n"
+"value.");
#define _DBM_DBM_SETDEFAULT_METHODDEF \
{"setdefault", _PyCFunction_CAST(_dbm_dbm_setdefault), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_setdefault__doc__},
@@ -246,4 +247,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=279511ea7cda38dd input=a9049054013a1b77]*/
+/*[clinic end generated code: output=677deecf525167a5 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_functoolsmodule.c.h b/Modules/clinic/_functoolsmodule.c.h
index 87cdef2ad3cff3..5f350c864f057b 100644
--- a/Modules/clinic/_functoolsmodule.c.h
+++ b/Modules/clinic/_functoolsmodule.c.h
@@ -77,9 +77,9 @@ PyDoc_STRVAR(_functools_reduce__doc__,
"\n"
"Apply a function of two arguments cumulatively to the items of an iterable, from left to right.\n"
"\n"
-"This effectively reduces the iterable to a single value. If initial is present,\n"
-"it is placed before the items of the iterable in the calculation, and serves as\n"
-"a default when the iterable is empty.\n"
+"This effectively reduces the iterable to a single value. If initial is\n"
+"present, it is placed before the items of the iterable in the\n"
+"calculation, and serves as a default when the iterable is empty.\n"
"\n"
"For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])\n"
"calculates ((((1 + 2) + 3) + 4) + 5).");
@@ -193,4 +193,4 @@ _functools__lru_cache_wrapper_cache_clear(PyObject *self, PyObject *Py_UNUSED(ig
return return_value;
}
-/*[clinic end generated code: output=ac9e26d0a5a23d40 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=6d8fdaeba4b520fa input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_gdbmmodule.c.h b/Modules/clinic/_gdbmmodule.c.h
index 6fd6aa3da50335..fe993cc328fbd2 100644
--- a/Modules/clinic/_gdbmmodule.c.h
+++ b/Modules/clinic/_gdbmmodule.c.h
@@ -138,9 +138,9 @@ PyDoc_STRVAR(_gdbm_gdbm_firstkey__doc__,
"\n"
"Return the starting key for the traversal.\n"
"\n"
-"It\'s possible to loop over every key in the database using this method\n"
-"and the nextkey() method. The traversal is ordered by GDBM\'s internal\n"
-"hash values, and won\'t be sorted by the key values.");
+"It\'s possible to loop over every key in the database using this\n"
+"method and the nextkey() method. The traversal is ordered by GDBM\'s\n"
+"internal hash values, and won\'t be sorted by the key values.");
#define _GDBM_GDBM_FIRSTKEY_METHODDEF \
{"firstkey", _PyCFunction_CAST(_gdbm_gdbm_firstkey), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_firstkey__doc__},
@@ -171,8 +171,8 @@ PyDoc_STRVAR(_gdbm_gdbm_nextkey__doc__,
"\n"
"Returns the key that follows key in the traversal.\n"
"\n"
-"The following code prints every key in the database db, without having\n"
-"to create a list in memory that contains them all:\n"
+"The following code prints every key in the database db, without\n"
+"having to create a list in memory that contains them all:\n"
"\n"
" k = db.firstkey()\n"
" while k is not None:\n"
@@ -226,9 +226,9 @@ PyDoc_STRVAR(_gdbm_gdbm_reorganize__doc__,
"\n"
"If you have carried out a lot of deletions and would like to shrink\n"
"the space used by the GDBM file, this routine will reorganize the\n"
-"database. GDBM will not shorten the length of a database file except\n"
-"by using this reorganization; otherwise, deleted file space will be\n"
-"kept and reused as new (key,value) pairs are added.");
+"database. GDBM will not shorten the length of a database file\n"
+"except by using this reorganization; otherwise, deleted file space\n"
+"will be kept and reused as new (key,value) pairs are added.");
#define _GDBM_GDBM_REORGANIZE_METHODDEF \
{"reorganize", _PyCFunction_CAST(_gdbm_gdbm_reorganize), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_reorganize__doc__},
@@ -389,4 +389,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=8bca34ce9d4493dd input=a9049054013a1b77]*/
+/*[clinic end generated code: output=429b5db24568292e input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_hashopenssl.c.h b/Modules/clinic/_hashopenssl.c.h
index 7ae7be185eceb5..17ed37bbd3b619 100644
--- a/Modules/clinic/_hashopenssl.c.h
+++ b/Modules/clinic/_hashopenssl.c.h
@@ -1865,8 +1865,8 @@ PyDoc_STRVAR(_hashlib_HMAC_hexdigest__doc__,
"\n"
"Return hexadecimal digest of the bytes passed to the update() method so far.\n"
"\n"
-"This may be used to exchange the value safely in email or other non-binary\n"
-"environments.");
+"This may be used to exchange the value safely in email or other\n"
+"non-binary environments.");
#define _HASHLIB_HMAC_HEXDIGEST_METHODDEF \
{"hexdigest", (PyCFunction)_hashlib_HMAC_hexdigest, METH_NOARGS, _hashlib_HMAC_hexdigest__doc__},
@@ -1887,8 +1887,8 @@ PyDoc_STRVAR(_hashlib_get_fips_mode__doc__,
"Determine the OpenSSL FIPS mode of operation.\n"
"\n"
"For OpenSSL 3.0.0 and newer it returns the state of the default provider\n"
-"in the default OSSL context. It\'s not quite the same as FIPS_mode() but good\n"
-"enough for unittests.\n"
+"in the default OSSL context. It\'s not quite the same as FIPS_mode() but\n"
+"good enough for unittests.\n"
"\n"
"Effectively any non-zero return value indicates FIPS mode;\n"
"values other than 1 may have additional significance.");
@@ -1986,4 +1986,4 @@ _hashlib_compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t narg
#ifndef _HASHLIB_OPENSSL_SHAKE_256_METHODDEF
#define _HASHLIB_OPENSSL_SHAKE_256_METHODDEF
#endif /* !defined(_HASHLIB_OPENSSL_SHAKE_256_METHODDEF) */
-/*[clinic end generated code: output=9ba35fcc33795b1e input=a9049054013a1b77]*/
+/*[clinic end generated code: output=cf405e652a340bb2 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_heapqmodule.c.h b/Modules/clinic/_heapqmodule.c.h
index b43155b6c24e3c..f3b8256efc0221 100644
--- a/Modules/clinic/_heapqmodule.c.h
+++ b/Modules/clinic/_heapqmodule.c.h
@@ -326,8 +326,8 @@ PyDoc_STRVAR(_heapq_heappushpop_max__doc__,
"\n"
"Maxheap variant of heappushpop.\n"
"\n"
-"The combined action runs more efficiently than heappush_max() followed by\n"
-"a separate call to heappop_max().");
+"The combined action runs more efficiently than heappush_max()\n"
+"followed by a separate call to heappop_max().");
#define _HEAPQ_HEAPPUSHPOP_MAX_METHODDEF \
{"heappushpop_max", _PyCFunction_CAST(_heapq_heappushpop_max), METH_FASTCALL, _heapq_heappushpop_max__doc__},
@@ -358,4 +358,4 @@ _heapq_heappushpop_max(PyObject *module, PyObject *const *args, Py_ssize_t nargs
exit:
return return_value;
}
-/*[clinic end generated code: output=e83d50002c29a96d input=a9049054013a1b77]*/
+/*[clinic end generated code: output=21e4f248ef6e83d6 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_interpqueuesmodule.c.h b/Modules/clinic/_interpqueuesmodule.c.h
index 3f08a0cb6d36ab..6f27ea73b8866f 100644
--- a/Modules/clinic/_interpqueuesmodule.c.h
+++ b/Modules/clinic/_interpqueuesmodule.c.h
@@ -109,7 +109,8 @@ PyDoc_STRVAR(_interpqueues_destroy__doc__,
"\n"
"Clear and destroy the queue.\n"
"\n"
-"Afterward attempts to use the queue will behave as though it never existed.");
+"Afterward attempts to use the queue will behave as though it never\n"
+"existed.");
#define _INTERPQUEUES_DESTROY_METHODDEF \
{"destroy", _PyCFunction_CAST(_interpqueues_destroy), METH_FASTCALL|METH_KEYWORDS, _interpqueues_destroy__doc__},
@@ -762,4 +763,4 @@ _interpqueues__register_heap_types(PyObject *module, PyObject *const *args, Py_s
exit:
return return_value;
}
-/*[clinic end generated code: output=64cea8e1063429b6 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=7e56e5b0c684d294 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_interpretersmodule.c.h b/Modules/clinic/_interpretersmodule.c.h
index d70ffcea527895..72792f9b583a66 100644
--- a/Modules/clinic/_interpretersmodule.c.h
+++ b/Modules/clinic/_interpretersmodule.c.h
@@ -541,7 +541,8 @@ PyDoc_STRVAR(_interpreters_run_func__doc__,
"Execute the body of the provided function in the identified interpreter.\n"
"\n"
"Code objects are also supported. In both cases, closures and args\n"
-"are not supported. Methods and other callables are not supported either.\n"
+"are not supported. Methods and other callables are not supported\n"
+"either.\n"
"\n"
"(See _interpreters.exec().)");
@@ -1139,8 +1140,9 @@ PyDoc_STRVAR(_interpreters_capture_exception__doc__,
"\n"
"Return a snapshot of an exception.\n"
"\n"
-"If \"exc\" is None then the current exception, if any, is used (but not cleared).\n"
-"The returned snapshot is the same as what _interpreters.exec() returns.");
+"If \"exc\" is None then the current exception, if any, is used (but not\n"
+"cleared). The returned snapshot is the same as what\n"
+"_interpreters.exec() returns.");
#define _INTERPRETERS_CAPTURE_EXCEPTION_METHODDEF \
{"capture_exception", _PyCFunction_CAST(_interpreters_capture_exception), METH_FASTCALL|METH_KEYWORDS, _interpreters_capture_exception__doc__},
@@ -1198,4 +1200,4 @@ _interpreters_capture_exception(PyObject *module, PyObject *const *args, Py_ssiz
exit:
return return_value;
}
-/*[clinic end generated code: output=c80f73761f860f6c input=a9049054013a1b77]*/
+/*[clinic end generated code: output=8c3ca09c304378ad input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_json.c.h b/Modules/clinic/_json.c.h
index cd37a236c7611a..d3ed1dfe0515a0 100644
--- a/Modules/clinic/_json.c.h
+++ b/Modules/clinic/_json.c.h
@@ -16,8 +16,8 @@ PyDoc_STRVAR(py_scanstring__doc__,
"ValueError on attempt to decode an invalid string. If strict is False\n"
"then literal control characters are allowed in the string.\n"
"\n"
-"Returns a tuple of the decoded string and the index of the character in s\n"
-"after the end quote.");
+"Returns a tuple of the decoded string and the index of the character in\n"
+"s after the end quote.");
#define PY_SCANSTRING_METHODDEF \
{"scanstring", _PyCFunction_CAST(py_scanstring), METH_FASTCALL, py_scanstring__doc__},
@@ -125,4 +125,4 @@ py_encode_basestring(PyObject *module, PyObject *arg)
exit:
return return_value;
}
-/*[clinic end generated code: output=5bdd16375c95a4d9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=ea6e9a271d4ceaf2 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_lzmamodule.c.h b/Modules/clinic/_lzmamodule.c.h
index ebdc81a0dac2f0..bba107e8f806da 100644
--- a/Modules/clinic/_lzmamodule.c.h
+++ b/Modules/clinic/_lzmamodule.c.h
@@ -74,18 +74,19 @@ PyDoc_STRVAR(_lzma_LZMADecompressor_decompress__doc__,
"\n"
"Decompress *data*, returning uncompressed data as bytes.\n"
"\n"
-"If *max_length* is nonnegative, returns at most *max_length* bytes of\n"
-"decompressed data. If this limit is reached and further output can be\n"
-"produced, *self.needs_input* will be set to ``False``. In this case, the next\n"
-"call to *decompress()* may provide *data* as b\'\' to obtain more of the output.\n"
+"If *max_length* is nonnegative, returns at most *max_length* bytes\n"
+"of decompressed data. If this limit is reached and further output\n"
+"can be produced, *self.needs_input* will be set to ``False``. In\n"
+"this case, the next call to *decompress()* may provide *data* as b\'\'\n"
+"to obtain more of the output.\n"
"\n"
-"If all of the input data was decompressed and returned (either because this\n"
-"was less than *max_length* bytes, or because *max_length* was negative),\n"
-"*self.needs_input* will be set to True.\n"
+"If all of the input data was decompressed and returned (either\n"
+"because this was less than *max_length* bytes, or because\n"
+"*max_length* was negative), *self.needs_input* will be set to True.\n"
"\n"
-"Attempting to decompress data after the end of stream is reached raises an\n"
-"EOFError. Any data found after the end of the stream is ignored and saved in\n"
-"the unused_data attribute.");
+"Attempting to decompress data after the end of stream is reached\n"
+"raises an EOFError. Any data found after the end of the stream is\n"
+"ignored and saved in the unused_data attribute.");
#define _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF \
{"decompress", _PyCFunction_CAST(_lzma_LZMADecompressor_decompress), METH_FASTCALL|METH_KEYWORDS, _lzma_LZMADecompressor_decompress__doc__},
@@ -333,4 +334,4 @@ _lzma__decode_filter_properties(PyObject *module, PyObject *const *args, Py_ssiz
return return_value;
}
-/*[clinic end generated code: output=6386084cb43d2533 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=ffc6d673d858048c input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_posixsubprocess.c.h b/Modules/clinic/_posixsubprocess.c.h
index d52629cf6eaa5b..e7e9707f182a2e 100644
--- a/Modules/clinic/_posixsubprocess.c.h
+++ b/Modules/clinic/_posixsubprocess.c.h
@@ -14,15 +14,15 @@ PyDoc_STRVAR(subprocess_fork_exec__doc__,
"\n"
"Spawn a fresh new child process.\n"
"\n"
-"Fork a child process, close parent file descriptors as appropriate in the\n"
-"child and duplicate the few that are needed before calling exec() in the\n"
-"child process.\n"
+"Fork a child process, close parent file descriptors as appropriate in\n"
+"the child and duplicate the few that are needed before calling exec() in\n"
+"the child process.\n"
"\n"
-"If close_fds is True, close file descriptors 3 and higher, except those listed\n"
-"in the sorted tuple pass_fds.\n"
+"If close_fds is True, close file descriptors 3 and higher, except those\n"
+"listed in the sorted tuple pass_fds.\n"
"\n"
-"The preexec_fn, if supplied, will be called immediately before closing file\n"
-"descriptors and exec.\n"
+"The preexec_fn, if supplied, will be called immediately before closing\n"
+"file descriptors and exec.\n"
"\n"
"WARNING: preexec_fn is NOT SAFE if your application uses threads.\n"
" It may trigger infrequent, difficult to debug deadlocks.\n"
@@ -150,4 +150,4 @@ subprocess_fork_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=942bc2748a9c2785 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=138941c284792aa1 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_queuemodule.c.h b/Modules/clinic/_queuemodule.c.h
index c9482f40acb9d4..b67dd23f260c9e 100644
--- a/Modules/clinic/_queuemodule.c.h
+++ b/Modules/clinic/_queuemodule.c.h
@@ -44,8 +44,9 @@ PyDoc_STRVAR(_queue_SimpleQueue_put__doc__,
"\n"
"Put the item on the queue.\n"
"\n"
-"The optional \'block\' and \'timeout\' arguments are ignored, as this method\n"
-"never blocks. They are provided for compatibility with the Queue class.");
+"The optional \'block\' and \'timeout\' arguments are ignored, as this\n"
+"method never blocks. They are provided for compatibility with the\n"
+"Queue class.");
#define _QUEUE_SIMPLEQUEUE_PUT_METHODDEF \
{"put", _PyCFunction_CAST(_queue_SimpleQueue_put), METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_put__doc__},
@@ -188,10 +189,11 @@ PyDoc_STRVAR(_queue_SimpleQueue_get__doc__,
"\n"
"Remove and return an item from the queue.\n"
"\n"
-"If optional args \'block\' is true and \'timeout\' is None (the default),\n"
-"block if necessary until an item is available. If \'timeout\' is\n"
-"a non-negative number, it blocks at most \'timeout\' seconds and raises\n"
-"the Empty exception if no item was available within that time.\n"
+"If optional args \'block\' is true and \'timeout\' is None (the\n"
+"default), block if necessary until an item is available. If\n"
+"\'timeout\' is a non-negative number, it blocks at most \'timeout\'\n"
+"seconds and raises the Empty exception if no item was available\n"
+"within that time.\n"
"Otherwise (\'block\' is false), return an item if one is immediately\n"
"available, else raise the Empty exception (\'timeout\' is ignored\n"
"in that case).");
@@ -388,4 +390,4 @@ _queue_SimpleQueue___sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored))
exit:
return return_value;
}
-/*[clinic end generated code: output=4af5d1b1ea31ac7d input=a9049054013a1b77]*/
+/*[clinic end generated code: output=8219fe2f2ed5f068 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h
index 8c35c8443b775a..e337ed2390a1fc 100644
--- a/Modules/clinic/_ssl.c.h
+++ b/Modules/clinic/_ssl.c.h
@@ -334,9 +334,10 @@ _ssl__SSLSocket_compression(PyObject *self, PyObject *Py_UNUSED(ignored))
PyDoc_STRVAR(_ssl__SSLSocket_context__doc__,
"This changes the context associated with the SSLSocket.\n"
"\n"
-"This is typically used from within a callback function set by the sni_callback\n"
-"on the SSLContext to change the certificate information associated with the\n"
-"SSLSocket before the cryptographic exchange handshake messages.");
+"This is typically used from within a callback function set by the\n"
+"sni_callback on the SSLContext to change the certificate information\n"
+"associated with the SSLSocket before the cryptographic exchange\n"
+"handshake messages.");
#if defined(_ssl__SSLSocket_context_DOCSTR)
# undef _ssl__SSLSocket_context_DOCSTR
#endif
@@ -571,9 +572,9 @@ PyDoc_STRVAR(_ssl__SSLSocket_sendfile__doc__,
"\n"
"Write size bytes from offset in the file descriptor fd to the SSL connection.\n"
"\n"
-"This method uses the zero-copy technique and returns the number of bytes\n"
-"written. It should be called only when Kernel TLS is used for sending data in\n"
-"the connection.\n"
+"This method uses the zero-copy technique and returns the number of\n"
+"bytes written. It should be called only when Kernel TLS is used for\n"
+"sending data in the connection.\n"
"\n"
"The meaning of flags is platform dependent.");
@@ -762,8 +763,9 @@ PyDoc_STRVAR(_ssl__SSLSocket_get_channel_binding__doc__,
"\n"
"Get channel binding data for current connection.\n"
"\n"
-"Raise ValueError if the requested `cb_type` is not supported. Return bytes\n"
-"of the data or None if the data is not available (e.g. before the handshake).\n"
+"Raise ValueError if the requested `cb_type` is not supported.\n"
+"Return bytes of the data or None if the data is not available (e.g.\n"
+"before the handshake).\n"
"Only \'tls-unique\' channel binding data from RFC 5929 is supported.");
#define _SSL__SSLSOCKET_GET_CHANNEL_BINDING_METHODDEF \
@@ -2210,8 +2212,9 @@ _ssl__SSLContext_set_ecdh_curve(PyObject *self, PyObject *name)
PyDoc_STRVAR(_ssl__SSLContext_sni_callback__doc__,
"Set a callback that will be called when a server name is provided by the SSL/TLS client in the SNI extension.\n"
"\n"
-"If the argument is None then the callback is disabled. The method is called\n"
-"with the SSLSocket, the server name as a string, and the SSLContext object.\n"
+"If the argument is None then the callback is disabled. The method\n"
+"is called with the SSLSocket, the server name as a string, and the\n"
+"SSLContext object.\n"
"\n"
"See RFC 6066 for details of the SNI extension.");
#if defined(_ssl__SSLContext_sni_callback_DOCSTR)
@@ -2275,11 +2278,11 @@ PyDoc_STRVAR(_ssl__SSLContext_cert_store_stats__doc__,
"\n"
"Returns quantities of loaded X.509 certificates.\n"
"\n"
-"X.509 certificates with a CA extension and certificate revocation lists\n"
-"inside the context\'s cert store.\n"
+"X.509 certificates with a CA extension and certificate revocation\n"
+"lists inside the context\'s cert store.\n"
"\n"
-"NOTE: Certificates in a capath directory aren\'t loaded unless they have\n"
-"been used at least once.");
+"NOTE: Certificates in a capath directory aren\'t loaded unless they\n"
+"have been used at least once.");
#define _SSL__SSLCONTEXT_CERT_STORE_STATS_METHODDEF \
{"cert_store_stats", (PyCFunction)_ssl__SSLContext_cert_store_stats, METH_NOARGS, _ssl__SSLContext_cert_store_stats__doc__},
@@ -2305,11 +2308,11 @@ PyDoc_STRVAR(_ssl__SSLContext_get_ca_certs__doc__,
"\n"
"Returns a list of dicts with information of loaded CA certs.\n"
"\n"
-"If the optional argument is True, returns a DER-encoded copy of the CA\n"
-"certificate.\n"
+"If the optional argument is True, returns a DER-encoded copy of the\n"
+"CA certificate.\n"
"\n"
-"NOTE: Certificates in a capath directory aren\'t loaded unless they have\n"
-"been used at least once.");
+"NOTE: Certificates in a capath directory aren\'t loaded unless they\n"
+"have been used at least once.");
#define _SSL__SSLCONTEXT_GET_CA_CERTS_METHODDEF \
{"get_ca_certs", _PyCFunction_CAST(_ssl__SSLContext_get_ca_certs), METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext_get_ca_certs__doc__},
@@ -2970,8 +2973,8 @@ PyDoc_STRVAR(_ssl_RAND_status__doc__,
"\n"
"Returns True if the OpenSSL PRNG has been seeded with enough data and False if not.\n"
"\n"
-"It is necessary to seed the PRNG with RAND_add() on some platforms before\n"
-"using the ssl() function.");
+"It is necessary to seed the PRNG with RAND_add() on some platforms\n"
+"before using the ssl() function.");
#define _SSL_RAND_STATUS_METHODDEF \
{"RAND_status", (PyCFunction)_ssl_RAND_status, METH_NOARGS, _ssl_RAND_status__doc__},
@@ -3157,11 +3160,11 @@ PyDoc_STRVAR(_ssl_enum_certificates__doc__,
"\n"
"Retrieve certificates from Windows\' cert store.\n"
"\n"
-"store_name may be one of \'CA\', \'ROOT\' or \'MY\'. The system may provide\n"
-"more cert storages, too. The function returns a list of (bytes,\n"
-"encoding_type, trust) tuples. The encoding_type flag can be interpreted\n"
-"with X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. The trust setting is either\n"
-"a set of OIDs or the boolean True.");
+"store_name may be one of \'CA\', \'ROOT\' or \'MY\'. The system may\n"
+"provide more cert storages, too. The function returns a list of\n"
+"(bytes, encoding_type, trust) tuples. The encoding_type flag can be\n"
+"interpreted with X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. The\n"
+"trust setting is either a set of OIDs or the boolean True.");
#define _SSL_ENUM_CERTIFICATES_METHODDEF \
{"enum_certificates", _PyCFunction_CAST(_ssl_enum_certificates), METH_FASTCALL|METH_KEYWORDS, _ssl_enum_certificates__doc__},
@@ -3323,4 +3326,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje
#ifndef _SSL_ENUM_CRLS_METHODDEF
#define _SSL_ENUM_CRLS_METHODDEF
#endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */
-/*[clinic end generated code: output=e29d5ada294f97bb input=a9049054013a1b77]*/
+/*[clinic end generated code: output=aef2e74b706c6106 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_testmultiphase.c.h b/Modules/clinic/_testmultiphase.c.h
index 311b6409476711..a0e4c66451101e 100644
--- a/Modules/clinic/_testmultiphase.c.h
+++ b/Modules/clinic/_testmultiphase.c.h
@@ -14,8 +14,8 @@ PyDoc_STRVAR(_testmultiphase_StateAccessType_get_defining_module__doc__,
"\n"
"Return the module of the defining class.\n"
"\n"
-"Also tests that result of PyType_GetModuleByDef matches defining_class\'s\n"
-"module.");
+"Also tests that result of PyType_GetModuleByDef matches\n"
+"defining_class\'s module.");
#define _TESTMULTIPHASE_STATEACCESSTYPE_GET_DEFINING_MODULE_METHODDEF \
{"get_defining_module", _PyCFunction_CAST(_testmultiphase_StateAccessType_get_defining_module), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _testmultiphase_StateAccessType_get_defining_module__doc__},
@@ -165,4 +165,4 @@ _testmultiphase_StateAccessType_get_count(PyObject *self, PyTypeObject *cls, PyO
}
return _testmultiphase_StateAccessType_get_count_impl((StateAccessTypeObject *)self, cls);
}
-/*[clinic end generated code: output=8eed2f14292ec986 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=aff91f6219a7baca input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_threadmodule.c.h b/Modules/clinic/_threadmodule.c.h
index 8455f9929babc1..926bea8e1e419a 100644
--- a/Modules/clinic/_threadmodule.c.h
+++ b/Modules/clinic/_threadmodule.c.h
@@ -14,8 +14,8 @@ PyDoc_STRVAR(_thread_lock_acquire__doc__,
"\n"
"Lock the lock.\n"
"\n"
-"Without argument, this blocks if the lock is already\n"
-"locked (even by the same thread), waiting for another thread to release\n"
+"Without argument, this blocks if the lock is already locked\n"
+"(even by the same thread), waiting for another thread to release\n"
"the lock, and return True once the lock is acquired.\n"
"With an argument, this will only block if the argument is true,\n"
"and the return value reflects whether the lock is acquired.\n"
@@ -445,14 +445,14 @@ PyDoc_STRVAR(_thread_RLock_release__doc__,
"\n"
"Release the lock.\n"
"\n"
-"Allows another thread that is blocked waiting for\n"
-"the lock to acquire the lock. The lock must be in the locked state,\n"
+"Allows another thread that is blocked waiting for the lock\n"
+"to acquire the lock. The lock must be in the locked state,\n"
"and must be locked by the same thread that unlocks it; otherwise a\n"
"`RuntimeError` is raised.\n"
"\n"
-"Do note that if the lock was acquire()d several times in a row by the\n"
-"current thread, release() needs to be called as many times for the lock\n"
-"to be available for other threads.");
+"Do note that if the lock was acquire()d several times in a row by\n"
+"the current thread, release() needs to be called as many times for\n"
+"the lock to be available for other threads.");
#define _THREAD_RLOCK_RELEASE_METHODDEF \
{"release", (PyCFunction)_thread_RLock_release, METH_NOARGS, _thread_RLock_release__doc__},
@@ -740,4 +740,4 @@ _thread_set_name(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb
#ifndef _THREAD_SET_NAME_METHODDEF
#define _THREAD_SET_NAME_METHODDEF
#endif /* !defined(_THREAD_SET_NAME_METHODDEF) */
-/*[clinic end generated code: output=1255a1520f43f97a input=a9049054013a1b77]*/
+/*[clinic end generated code: output=0f1707cbafc0e8f2 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_tkinter.c.h b/Modules/clinic/_tkinter.c.h
index 352c2b9e3d410c..3147cf7f9d2cff 100644
--- a/Modules/clinic/_tkinter.c.h
+++ b/Modules/clinic/_tkinter.c.h
@@ -907,7 +907,8 @@ PyDoc_STRVAR(_tkinter_setbusywaitinterval__doc__,
"\n"
"Set the busy-wait interval in milliseconds between successive calls to Tcl_DoOneEvent in a threaded Python interpreter.\n"
"\n"
-"It should be set to a divisor of the maximum time between frames in an animation.");
+"It should be set to a divisor of the maximum time between frames in\n"
+"an animation.");
#define _TKINTER_SETBUSYWAITINTERVAL_METHODDEF \
{"setbusywaitinterval", (PyCFunction)_tkinter_setbusywaitinterval, METH_O, _tkinter_setbusywaitinterval__doc__},
@@ -966,4 +967,4 @@ _tkinter_getbusywaitinterval(PyObject *module, PyObject *Py_UNUSED(ignored))
#ifndef _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF
#define _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF
#endif /* !defined(_TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF) */
-/*[clinic end generated code: output=052c067aa69237be input=a9049054013a1b77]*/
+/*[clinic end generated code: output=c807adb73e305725 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h
index eec47ab2b1f9e1..1e9f317853d6c2 100644
--- a/Modules/clinic/arraymodule.c.h
+++ b/Modules/clinic/arraymodule.c.h
@@ -292,8 +292,8 @@ PyDoc_STRVAR(array_array_buffer_info__doc__,
"\n"
"Return a tuple (address, length) giving the current memory address and the length in items of the buffer used to hold array\'s contents.\n"
"\n"
-"The length should be multiplied by the itemsize attribute to calculate\n"
-"the buffer length in bytes.");
+"The length should be multiplied by the itemsize attribute to\n"
+"calculate the buffer length in bytes.");
#define ARRAY_ARRAY_BUFFER_INFO_METHODDEF \
{"buffer_info", (PyCFunction)array_array_buffer_info, METH_NOARGS, array_array_buffer_info__doc__},
@@ -335,8 +335,8 @@ PyDoc_STRVAR(array_array_byteswap__doc__,
"\n"
"Byteswap all items of the array.\n"
"\n"
-"If the items in the array are not 1, 2, 4, 8 or 16 bytes in size, RuntimeError\n"
-"is raised. Note, that for complex types the order of\n"
+"If the items in the array are not 1, 2, 4, 8 or 16 bytes in size,\n"
+"RuntimeError is raised. Note, that for complex types the order of\n"
"components (the real part, followed by imaginary part) is preserved.");
#define ARRAY_ARRAY_BYTESWAP_METHODDEF \
@@ -572,9 +572,9 @@ PyDoc_STRVAR(array_array_fromunicode__doc__,
"\n"
"Extends this array with data from the unicode string ustr.\n"
"\n"
-"The array must be a unicode type array; otherwise a ValueError is raised.\n"
-"Use array.frombytes(ustr.encode(...)) to append Unicode data to an array of\n"
-"some other type.");
+"The array must be a unicode type array; otherwise a ValueError is\n"
+"raised. Use array.frombytes(ustr.encode(...)) to append Unicode\n"
+"data to an array of some other type.");
#define ARRAY_ARRAY_FROMUNICODE_METHODDEF \
{"fromunicode", (PyCFunction)array_array_fromunicode, METH_O, array_array_fromunicode__doc__},
@@ -605,9 +605,10 @@ PyDoc_STRVAR(array_array_tounicode__doc__,
"\n"
"Extends this array with data from the unicode string ustr.\n"
"\n"
-"Convert the array to a unicode string. The array must be a unicode type array;\n"
-"otherwise a ValueError is raised. Use array.tobytes().decode() to obtain a\n"
-"unicode string from an array of some other type.");
+"Convert the array to a unicode string. The array must be a unicode\n"
+"type array; otherwise a ValueError is raised. Use\n"
+"array.tobytes().decode() to obtain a unicode string from an array of\n"
+"some other type.");
#define ARRAY_ARRAY_TOUNICODE_METHODDEF \
{"tounicode", (PyCFunction)array_array_tounicode, METH_NOARGS, array_array_tounicode__doc__},
@@ -780,4 +781,4 @@ array_arrayiterator___setstate__(PyObject *self, PyObject *state)
return return_value;
}
-/*[clinic end generated code: output=8699475b51151247 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=32784678e77ac658 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/cmathmodule.c.h b/Modules/clinic/cmathmodule.c.h
index 7f9e65baf120ea..ecb5257cf6b240 100644
--- a/Modules/clinic/cmathmodule.c.h
+++ b/Modules/clinic/cmathmodule.c.h
@@ -644,7 +644,8 @@ PyDoc_STRVAR(cmath_log__doc__,
"\n"
"log(z[, base]) -> the logarithm of z to the given base.\n"
"\n"
-"If the base is not specified, returns the natural logarithm (base e) of z.");
+"If the base is not specified, returns the natural logarithm (base e)\n"
+"of z.");
#define CMATH_LOG_METHODDEF \
{"log", _PyCFunction_CAST(cmath_log), METH_FASTCALL, cmath_log__doc__},
@@ -882,11 +883,12 @@ PyDoc_STRVAR(cmath_isclose__doc__,
"\n"
"Return True if a is close in value to b, and False otherwise.\n"
"\n"
-"For the values to be considered close, the difference between them must be\n"
-"smaller than at least one of the tolerances.\n"
+"For the values to be considered close, the difference between them must\n"
+"be smaller than at least one of the tolerances.\n"
"\n"
-"-inf, inf and NaN behave similarly to the IEEE 754 Standard. That is, NaN is\n"
-"not close to anything, even itself. inf and -inf are only close to themselves.");
+"-inf, inf and NaN behave similarly to the IEEE 754 Standard. That is,\n"
+"NaN is not close to anything, even itself. inf and -inf are only close\n"
+"to themselves.");
#define CMATH_ISCLOSE_METHODDEF \
{"isclose", _PyCFunction_CAST(cmath_isclose), METH_FASTCALL|METH_KEYWORDS, cmath_isclose__doc__},
@@ -985,4 +987,4 @@ cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec
exit:
return return_value;
}
-/*[clinic end generated code: output=631db17fb1c79d66 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=7d5ad4cf258526cd input=a9049054013a1b77]*/
diff --git a/Modules/clinic/faulthandler.c.h b/Modules/clinic/faulthandler.c.h
index e06cfdcfba2993..07a9dd7dc561e1 100644
--- a/Modules/clinic/faulthandler.c.h
+++ b/Modules/clinic/faulthandler.c.h
@@ -334,9 +334,9 @@ PyDoc_STRVAR(faulthandler_dump_traceback_later__doc__,
"\n"
"Dump the traceback of all threads in timeout seconds.\n"
"\n"
-"If repeat is true, the tracebacks of all threads are dumped every timeout\n"
-"seconds. If exit is true, call _exit(1) which is not safe. max_threads\n"
-"caps the number of threads dumped.");
+"If repeat is true, the tracebacks of all threads are dumped every\n"
+"timeout seconds. If exit is true, call _exit(1) which is not safe.\n"
+"max_threads caps the number of threads dumped.");
#define FAULTHANDLER_DUMP_TRACEBACK_LATER_METHODDEF \
{"dump_traceback_later", _PyCFunction_CAST(faulthandler_dump_traceback_later), METH_FASTCALL|METH_KEYWORDS, faulthandler_dump_traceback_later__doc__},
@@ -782,4 +782,4 @@ faulthandler__raise_exception(PyObject *module, PyObject *const *args, Py_ssize_
#ifndef FAULTHANDLER__RAISE_EXCEPTION_METHODDEF
#define FAULTHANDLER__RAISE_EXCEPTION_METHODDEF
#endif /* !defined(FAULTHANDLER__RAISE_EXCEPTION_METHODDEF) */
-/*[clinic end generated code: output=2452d767c85130a6 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=14815a5f8afe813f input=a9049054013a1b77]*/
diff --git a/Modules/clinic/gcmodule.c.h b/Modules/clinic/gcmodule.c.h
index 08275e35413f66..aa743c8f40a565 100644
--- a/Modules/clinic/gcmodule.c.h
+++ b/Modules/clinic/gcmodule.c.h
@@ -376,8 +376,8 @@ PyDoc_STRVAR(gc_get_objects__doc__,
" generation\n"
" Generation to extract the objects from.\n"
"\n"
-"If generation is not None, return only the objects tracked by the collector\n"
-"that are in that generation.");
+"If generation is not None, return only the objects tracked by the\n"
+"collector that are in that generation.");
#define GC_GET_OBJECTS_METHODDEF \
{"get_objects", _PyCFunction_CAST(gc_get_objects), METH_FASTCALL|METH_KEYWORDS, gc_get_objects__doc__},
@@ -520,9 +520,10 @@ PyDoc_STRVAR(gc_freeze__doc__,
"\n"
"Freeze all current tracked objects and ignore them for future collections.\n"
"\n"
-"This can be used before a POSIX fork() call to make the gc copy-on-write friendly.\n"
-"Note: collection before a POSIX fork() call may free pages for future allocation\n"
-"which can cause copy-on-write.");
+"This can be used before a POSIX fork() call to make the gc copy-on-write\n"
+"friendly.\n"
+"Note: collection before a POSIX fork() call may free pages for future\n"
+"allocation which can cause copy-on-write.");
#define GC_FREEZE_METHODDEF \
{"freeze", (PyCFunction)gc_freeze, METH_NOARGS, gc_freeze__doc__},
@@ -583,4 +584,4 @@ gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored))
exit:
return return_value;
}
-/*[clinic end generated code: output=19738854607938db input=a9049054013a1b77]*/
+/*[clinic end generated code: output=756c0e7719b76971 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/hmacmodule.c.h b/Modules/clinic/hmacmodule.c.h
index 1ceb2d809e830a..a31d2ab7f04463 100644
--- a/Modules/clinic/hmacmodule.c.h
+++ b/Modules/clinic/hmacmodule.c.h
@@ -187,8 +187,8 @@ PyDoc_STRVAR(_hmac_HMAC_hexdigest__doc__,
"\n"
"Return hexadecimal digest of the bytes passed to the update() method so far.\n"
"\n"
-"This may be used to exchange the value safely in email or other non-binary\n"
-"environments.\n"
+"This may be used to exchange the value safely in email or other\n"
+"non-binary environments.\n"
"\n"
"This method may raise a MemoryError.");
@@ -670,4 +670,4 @@ _hmac_compute_blake2b_32(PyObject *module, PyObject *const *args, Py_ssize_t nar
exit:
return return_value;
}
-/*[clinic end generated code: output=30c0614482d963f5 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=6ec5948df1c5569a input=a9049054013a1b77]*/
diff --git a/Modules/clinic/itertoolsmodule.c.h b/Modules/clinic/itertoolsmodule.c.h
index 49816bfcb42fec..d9917b47dc9037 100644
--- a/Modules/clinic/itertoolsmodule.c.h
+++ b/Modules/clinic/itertoolsmodule.c.h
@@ -814,8 +814,8 @@ PyDoc_STRVAR(itertools_compress__doc__,
"\n"
"Return data elements corresponding to true selector elements.\n"
"\n"
-"Forms a shorter iterator from selected data elements using the selectors to\n"
-"choose the data elements.");
+"Forms a shorter iterator from selected data elements using the selectors\n"
+"to choose the data elements.");
static PyObject *
itertools_compress_impl(PyTypeObject *type, PyObject *seq1, PyObject *seq2);
@@ -980,4 +980,4 @@ itertools_count(PyTypeObject *type, PyObject *args, PyObject *kwargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=7f385837b13edbeb input=a9049054013a1b77]*/
+/*[clinic end generated code: output=a34a31f60100e0ff input=a9049054013a1b77]*/
diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h
index b023299dd9cb2d..6a1b1a45d1d93a 100644
--- a/Modules/clinic/mathmodule.c.h
+++ b/Modules/clinic/mathmodule.c.h
@@ -1043,8 +1043,8 @@ PyDoc_STRVAR(math_nextafter__doc__,
"\n"
"If steps is not specified or is None, it defaults to 1.\n"
"\n"
-"Raises a TypeError, if x or y is not a double, or if steps is not an integer.\n"
-"Raises ValueError if steps is negative.");
+"Raises a TypeError, if x or y is not a double, or if steps is not\n"
+"an integer. Raises ValueError if steps is negative.");
#define MATH_NEXTAFTER_METHODDEF \
{"nextafter", _PyCFunction_CAST(math_nextafter), METH_FASTCALL|METH_KEYWORDS, math_nextafter__doc__},
@@ -1163,4 +1163,4 @@ math_ulp(PyObject *module, PyObject *arg)
exit:
return return_value;
}
-/*[clinic end generated code: output=23b2453ba77453e5 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=80c666aef8d2df36 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/overlapped.c.h b/Modules/clinic/overlapped.c.h
index 7e2480bdace38d..ba41eab15650e8 100644
--- a/Modules/clinic/overlapped.c.h
+++ b/Modules/clinic/overlapped.c.h
@@ -529,8 +529,9 @@ PyDoc_STRVAR(_overlapped_Overlapped_getresult__doc__,
"\n"
"Retrieve result of operation.\n"
"\n"
-"If wait is true then it blocks until the operation is finished. If wait\n"
-"is false and the operation is still pending then an error is raised.");
+"If wait is true then it blocks until the operation is finished. If\n"
+"wait is false and the operation is still pending then an error is\n"
+"raised.");
#define _OVERLAPPED_OVERLAPPED_GETRESULT_METHODDEF \
{"getresult", _PyCFunction_CAST(_overlapped_Overlapped_getresult), METH_FASTCALL, _overlapped_Overlapped_getresult__doc__},
@@ -1242,4 +1243,4 @@ _overlapped_Overlapped_WSARecvFromInto(PyObject *self, PyObject *const *args, Py
return return_value;
}
-/*[clinic end generated code: output=3e4cb2b55342cd96 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=0ecaf45a09539599 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h
index 3952054e9e32bf..c1c8ad40e724f5 100644
--- a/Modules/clinic/selectmodule.c.h
+++ b/Modules/clinic/selectmodule.c.h
@@ -16,7 +16,8 @@ PyDoc_STRVAR(select_select__doc__,
"\n"
"Wait until one or more file descriptors are ready for some kind of I/O.\n"
"\n"
-"The first three arguments are iterables of file descriptors to be waited for:\n"
+"The first three arguments are iterables of file descriptors to be waited\n"
+"for:\n"
"rlist -- wait until ready for reading\n"
"wlist -- wait until ready for writing\n"
"xlist -- wait for an \"exceptional condition\"\n"
@@ -29,9 +30,9 @@ PyDoc_STRVAR(select_select__doc__,
"a non-integer to specify fractions of seconds. If it is absent\n"
"or None, the call will never time out.\n"
"\n"
-"The return value is a tuple of three lists corresponding to the first three\n"
-"arguments; each contains the subset of the corresponding file descriptors\n"
-"that are ready.\n"
+"The return value is a tuple of three lists corresponding to the first\n"
+"three arguments; each contains the subset of the corresponding file\n"
+"descriptors that are ready.\n"
"\n"
"*** IMPORTANT NOTICE ***\n"
"On Windows, only sockets are supported; on Unix, all file\n"
@@ -214,8 +215,8 @@ PyDoc_STRVAR(select_poll_poll__doc__,
" The maximum time to wait in milliseconds, or else None (or a negative\n"
" value) to wait indefinitely.\n"
"\n"
-"Returns a list containing any descriptors that have events or errors to\n"
-"report, as a list of (fd, event) 2-tuples.");
+"Returns a list containing any descriptors that have events or errors\n"
+"to report, as a list of (fd, event) 2-tuples.");
#define SELECT_POLL_POLL_METHODDEF \
{"poll", _PyCFunction_CAST(select_poll_poll), METH_FASTCALL, select_poll_poll__doc__},
@@ -396,11 +397,11 @@ PyDoc_STRVAR(select_devpoll_poll__doc__,
"Polls the set of registered file descriptors.\n"
"\n"
" timeout\n"
-" The maximum time to wait in milliseconds, or else None (or a negative\n"
-" value) to wait indefinitely.\n"
+" The maximum time to wait in milliseconds, or else None (or\n"
+" a negative value) to wait indefinitely.\n"
"\n"
-"Returns a list containing any descriptors that have events or errors to\n"
-"report, as a list of (fd, event) 2-tuples.");
+"Returns a list containing any descriptors that have events or errors\n"
+"to report, as a list of (fd, event) 2-tuples.");
#define SELECT_DEVPOLL_POLL_METHODDEF \
{"poll", _PyCFunction_CAST(select_devpoll_poll), METH_FASTCALL, select_devpoll_poll__doc__},
@@ -498,8 +499,8 @@ PyDoc_STRVAR(select_poll__doc__,
"\n"
"Returns a polling object.\n"
"\n"
-"This object supports registering and unregistering file descriptors, and then\n"
-"polling them for I/O events.");
+"This object supports registering and unregistering file descriptors, and\n"
+"then polling them for I/O events.");
#define SELECT_POLL_METHODDEF \
{"poll", (PyCFunction)select_poll, METH_NOARGS, select_poll__doc__},
@@ -523,8 +524,8 @@ PyDoc_STRVAR(select_devpoll__doc__,
"\n"
"Returns a polling object.\n"
"\n"
-"This object supports registering and unregistering file descriptors, and then\n"
-"polling them for I/O events.");
+"This object supports registering and unregistering file descriptors, and\n"
+"then polling them for I/O events.");
#define SELECT_DEVPOLL_METHODDEF \
{"devpoll", (PyCFunction)select_devpoll, METH_NOARGS, select_devpoll__doc__},
@@ -978,8 +979,8 @@ PyDoc_STRVAR(select_epoll_poll__doc__,
" maxevents\n"
" the maximum number of events returned; -1 means no limit\n"
"\n"
-"Returns a list containing any descriptors that have events to report,\n"
-"as a list of (fd, events) 2-tuples.");
+"Returns a list containing any descriptors that have events to\n"
+"report, as a list of (fd, events) 2-tuples.");
#define SELECT_EPOLL_POLL_METHODDEF \
{"poll", _PyCFunction_CAST(select_epoll_poll), METH_FASTCALL|METH_KEYWORDS, select_epoll_poll__doc__},
@@ -1399,4 +1400,4 @@ select_kqueue_control(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
#ifndef SELECT_KQUEUE_CONTROL_METHODDEF
#define SELECT_KQUEUE_CONTROL_METHODDEF
#endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */
-/*[clinic end generated code: output=52e3be5cc66cf1b6 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=a1ac666294fd14bd input=a9049054013a1b77]*/
diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h
index 9fd24d15bf2500..ca47033446074c 100644
--- a/Modules/clinic/signalmodule.c.h
+++ b/Modules/clinic/signalmodule.c.h
@@ -138,11 +138,12 @@ PyDoc_STRVAR(signal_signal__doc__,
"Set the action for the given signal.\n"
"\n"
"The action can be SIG_DFL, SIG_IGN, or a callable Python object.\n"
-"The previous action is returned. See getsignal() for possible return values.\n"
+"The previous action is returned. See getsignal() for possible return\n"
+"values.\n"
"\n"
"*** IMPORTANT NOTICE ***\n"
-"A signal handler function is called with two arguments:\n"
-"the first is the signal number, the second is the interrupted stack frame.");
+"A signal handler function is called with two arguments: the first is\n"
+"the signal number, the second is the interrupted stack frame.");
#define SIGNAL_SIGNAL_METHODDEF \
{"signal", _PyCFunction_CAST(signal_signal), METH_FASTCALL, signal_signal__doc__},
@@ -362,8 +363,8 @@ PyDoc_STRVAR(signal_setitimer__doc__,
"\n"
"Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).\n"
"\n"
-"The timer will fire after value seconds and after that every interval seconds.\n"
-"The itimer can be cleared by setting seconds to zero.\n"
+"The timer will fire after value seconds and after that every interval\n"
+"seconds. The itimer can be cleared by setting seconds to zero.\n"
"\n"
"Returns old values as a tuple: (delay, interval).");
@@ -508,8 +509,8 @@ PyDoc_STRVAR(signal_sigwait__doc__,
"Wait for a signal.\n"
"\n"
"Suspend execution of the calling thread until the delivery of one of the\n"
-"signals specified in the signal set sigset. The function accepts the signal\n"
-"and returns the signal number.");
+"signals specified in the signal set sigset. The function accepts the\n"
+"signal and returns the signal number.");
#define SIGNAL_SIGWAIT_METHODDEF \
{"sigwait", (PyCFunction)signal_sigwait, METH_O, signal_sigwait__doc__},
@@ -794,4 +795,4 @@ signal_pidfd_send_signal(PyObject *module, PyObject *const *args, Py_ssize_t nar
#ifndef SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF
#define SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF
#endif /* !defined(SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF) */
-/*[clinic end generated code: output=42e20d118435d7fa input=a9049054013a1b77]*/
+/*[clinic end generated code: output=0731d6f05c42c09a input=a9049054013a1b77]*/
diff --git a/Modules/clinic/socketmodule.c.h b/Modules/clinic/socketmodule.c.h
index e0cc1c50dcbac3..b565e7516d50f3 100644
--- a/Modules/clinic/socketmodule.c.h
+++ b/Modules/clinic/socketmodule.c.h
@@ -36,7 +36,8 @@ PyDoc_STRVAR(_socket_socket_send__doc__,
"Send a data string to the socket.\n"
"\n"
"For the optional flags argument, see the Unix manual.\n"
-"Return the number of bytes sent; this may be less than len(data) if the network is busy.");
+"Return the number of bytes sent; this may be less than len(data) if\n"
+"the network is busy.");
#define _SOCKET_SOCKET_SEND_METHODDEF \
{"send", _PyCFunction_CAST(_socket_socket_send), METH_FASTCALL, _socket_socket_send__doc__},
@@ -84,7 +85,8 @@ PyDoc_STRVAR(_socket_socket_sendall__doc__,
"\n"
"For the optional flags argument, see the Unix manual.\n"
"This calls send() repeatedly until all data is sent.\n"
-"If an error occurs, it\'s impossible to tell how much data has been sent.");
+"If an error occurs, it\'s impossible to tell how much data has been\n"
+"sent.");
#define _SOCKET_SOCKET_SENDALL_METHODDEF \
{"sendall", _PyCFunction_CAST(_socket_socket_sendall), METH_FASTCALL, _socket_socket_sendall__doc__},
@@ -140,13 +142,13 @@ PyDoc_STRVAR(_socket_socket_sendmsg__doc__,
"data as an iterable of bytes-like objects (e.g. bytes objects).\n"
"The ancdata argument specifies the ancillary data (control messages)\n"
"as an iterable of zero or more tuples (cmsg_level, cmsg_type,\n"
-"cmsg_data), where cmsg_level and cmsg_type are integers specifying the\n"
-"protocol level and protocol-specific type respectively, and cmsg_data\n"
-"is a bytes-like object holding the associated data. The flags\n"
-"argument defaults to 0 and has the same meaning as for send(). If\n"
-"address is supplied and not None, it sets a destination address for\n"
-"the message. The return value is the number of bytes of non-ancillary\n"
-"data sent.");
+"cmsg_data), where cmsg_level and cmsg_type are integers specifying\n"
+"the protocol level and protocol-specific type respectively, and\n"
+"cmsg_data is a bytes-like object holding the associated data. The\n"
+"flags argument defaults to 0 and has the same meaning as for send().\n"
+"If address is supplied and not None, it sets a destination address\n"
+"for the message. The return value is the number of bytes of\n"
+"non-ancillary data sent.");
#define _SOCKET_SOCKET_SENDMSG_METHODDEF \
{"sendmsg", _PyCFunction_CAST(_socket_socket_sendmsg), METH_FASTCALL, _socket_socket_sendmsg__doc__},
@@ -541,4 +543,4 @@ _socket_if_indextoname(PyObject *module, PyObject *arg)
#ifndef _SOCKET_IF_INDEXTONAME_METHODDEF
#define _SOCKET_IF_INDEXTONAME_METHODDEF
#endif /* !defined(_SOCKET_IF_INDEXTONAME_METHODDEF) */
-/*[clinic end generated code: output=36051ebf6ad1e6f8 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=0b1fa78ac6589353 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/termios.c.h b/Modules/clinic/termios.c.h
index 83f5a4f6e9f882..35522bef1dcae9 100644
--- a/Modules/clinic/termios.c.h
+++ b/Modules/clinic/termios.c.h
@@ -270,7 +270,8 @@ PyDoc_STRVAR(termios_tcsetwinsize__doc__,
"Set the tty winsize for file descriptor fd.\n"
"\n"
"The winsize to be set is taken from the winsize argument, which\n"
-"is a two-item tuple (ws_row, ws_col) like the one returned by tcgetwinsize().");
+"is a two-item tuple (ws_row, ws_col) like the one returned by\n"
+"tcgetwinsize().");
#define TERMIOS_TCSETWINSIZE_METHODDEF \
{"tcsetwinsize", (PyCFunction)(void(*)(void))termios_tcsetwinsize, METH_FASTCALL, termios_tcsetwinsize__doc__},
@@ -299,4 +300,4 @@ termios_tcsetwinsize(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=c6c6192583b0da36 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=d2176c4d9043d3cc input=a9049054013a1b77]*/
diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h
index f8fd111754a894..620e483d5a759a 100644
--- a/Modules/clinic/zlibmodule.c.h
+++ b/Modules/clinic/zlibmodule.c.h
@@ -503,8 +503,8 @@ PyDoc_STRVAR(zlib_Decompress_decompress__doc__,
" Unconsumed input data will be stored in\n"
" the unconsumed_tail attribute.\n"
"\n"
-"After calling this function, some of the input data may still be stored in\n"
-"internal buffers for later processing.\n"
+"After calling this function, some of the input data may still be\n"
+"stored in internal buffers for later processing.\n"
"Call the flush() method to clear these buffers.");
#define ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF \
@@ -914,18 +914,19 @@ PyDoc_STRVAR(zlib__ZlibDecompressor_decompress__doc__,
"\n"
"Decompress *data*, returning uncompressed data as bytes.\n"
"\n"
-"If *max_length* is nonnegative, returns at most *max_length* bytes of\n"
-"decompressed data. If this limit is reached and further output can be\n"
-"produced, *self.needs_input* will be set to ``False``. In this case, the next\n"
-"call to *decompress()* may provide *data* as b\'\' to obtain more of the output.\n"
+"If *max_length* is nonnegative, returns at most *max_length* bytes\n"
+"of decompressed data. If this limit is reached and further output\n"
+"can be produced, *self.needs_input* will be set to ``False``. In\n"
+"this case, the next call to *decompress()* may provide *data* as b\'\'\n"
+"to obtain more of the output.\n"
"\n"
-"If all of the input data was decompressed and returned (either because this\n"
-"was less than *max_length* bytes, or because *max_length* was negative),\n"
-"*self.needs_input* will be set to True.\n"
+"If all of the input data was decompressed and returned (either\n"
+"because this was less than *max_length* bytes, or because\n"
+"*max_length* was negative), *self.needs_input* will be set to True.\n"
"\n"
-"Attempting to decompress data after the end of stream is reached raises an\n"
-"EOFError. Any data found after the end of the stream is ignored and saved in\n"
-"the unused_data attribute.");
+"Attempting to decompress data after the end of stream is reached\n"
+"raises an EOFError. Any data found after the end of the stream is\n"
+"ignored and saved in the unused_data attribute.");
#define ZLIB__ZLIBDECOMPRESSOR_DECOMPRESS_METHODDEF \
{"decompress", _PyCFunction_CAST(zlib__ZlibDecompressor_decompress), METH_FASTCALL|METH_KEYWORDS, zlib__ZlibDecompressor_decompress__doc__},
@@ -1402,4 +1403,4 @@ zlib_crc32_combine(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
#ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF
#define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF
#endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */
-/*[clinic end generated code: output=13627e14206d3552 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=c9a60fe6600a2e4d input=a9049054013a1b77]*/
diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c
index 1e9f9ae051a0b1..7c736f4610bb98 100644
--- a/Modules/cmathmodule.c
+++ b/Modules/cmathmodule.c
@@ -948,12 +948,13 @@ cmath.log
log(z[, base]) -> the logarithm of z to the given base.
-If the base is not specified, returns the natural logarithm (base e) of z.
+If the base is not specified, returns the natural logarithm (base e)
+of z.
[clinic start generated code]*/
static PyObject *
cmath_log_impl(PyObject *module, Py_complex x, PyObject *y_obj)
-/*[clinic end generated code: output=4effdb7d258e0d94 input=e1f81d4fcfd26497]*/
+/*[clinic end generated code: output=4effdb7d258e0d94 input=eb25de0757baf4a0]*/
{
Py_complex y;
@@ -1162,7 +1163,6 @@ cmath_isinf_impl(PyObject *module, Py_complex z)
}
/*[clinic input]
-@permit_long_docstring_body
cmath.isclose -> bool
a: Py_complex
@@ -1179,17 +1179,18 @@ Determine whether two complex numbers are close in value.
Return True if a is close in value to b, and False otherwise.
-For the values to be considered close, the difference between them must be
-smaller than at least one of the tolerances.
+For the values to be considered close, the difference between them must
+be smaller than at least one of the tolerances.
--inf, inf and NaN behave similarly to the IEEE 754 Standard. That is, NaN is
-not close to anything, even itself. inf and -inf are only close to themselves.
+-inf, inf and NaN behave similarly to the IEEE 754 Standard. That is,
+NaN is not close to anything, even itself. inf and -inf are only close
+to themselves.
[clinic start generated code]*/
static int
cmath_isclose_impl(PyObject *module, Py_complex a, Py_complex b,
double rel_tol, double abs_tol)
-/*[clinic end generated code: output=8a2486cc6e0014d1 input=0d45feea7c626f47]*/
+/*[clinic end generated code: output=8a2486cc6e0014d1 input=301b56c90d9a79de]*/
{
double diff;
diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c
index fa7fb7085d7e8b..7c727d8c2d4ff0 100644
--- a/Modules/faulthandler.c
+++ b/Modules/faulthandler.c
@@ -795,9 +795,9 @@ faulthandler.dump_traceback_later
Dump the traceback of all threads in timeout seconds.
-If repeat is true, the tracebacks of all threads are dumped every timeout
-seconds. If exit is true, call _exit(1) which is not safe. max_threads
-caps the number of threads dumped.
+If repeat is true, the tracebacks of all threads are dumped every
+timeout seconds. If exit is true, call _exit(1) which is not safe.
+max_threads caps the number of threads dumped.
[clinic start generated code]*/
static PyObject *
@@ -805,7 +805,7 @@ faulthandler_dump_traceback_later_impl(PyObject *module,
PyObject *timeout_obj, int repeat,
PyObject *file, int exit,
Py_ssize_t max_threads)
-/*[clinic end generated code: output=543a0f3807113394 input=6836555ee157ddb4]*/
+/*[clinic end generated code: output=543a0f3807113394 input=32aaf7437d0928db]*/
{
PyTime_t timeout, timeout_us;
int fd;
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 18bddf46a7466b..12f93ac0fdea14 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -326,13 +326,13 @@ gc.get_objects
Return a list of objects tracked by the collector (excluding the list returned).
-If generation is not None, return only the objects tracked by the collector
-that are in that generation.
+If generation is not None, return only the objects tracked by the
+collector that are in that generation.
[clinic start generated code]*/
static PyObject *
gc_get_objects_impl(PyObject *module, Py_ssize_t generation)
-/*[clinic end generated code: output=48b35fea4ba6cb0e input=a887f1d9924be7cf]*/
+/*[clinic end generated code: output=48b35fea4ba6cb0e input=89bca0d4a64e0135]*/
{
if (PySys_Audit("gc.get_objects", "n", generation) < 0) {
return NULL;
@@ -440,19 +440,20 @@ gc_is_finalized_impl(PyObject *module, PyObject *obj)
}
/*[clinic input]
-@permit_long_docstring_body
+@permit_long_summary
gc.freeze
Freeze all current tracked objects and ignore them for future collections.
-This can be used before a POSIX fork() call to make the gc copy-on-write friendly.
-Note: collection before a POSIX fork() call may free pages for future allocation
-which can cause copy-on-write.
+This can be used before a POSIX fork() call to make the gc copy-on-write
+friendly.
+Note: collection before a POSIX fork() call may free pages for future
+allocation which can cause copy-on-write.
[clinic start generated code]*/
static PyObject *
gc_freeze_impl(PyObject *module)
-/*[clinic end generated code: output=502159d9cdc4c139 input=11fb59b0a75dcf3d]*/
+/*[clinic end generated code: output=502159d9cdc4c139 input=02674706fc9c0de6]*/
{
PyInterpreterState *interp = _PyInterpreterState_GET();
_PyGC_Freeze(interp);
diff --git a/Modules/hmacmodule.c b/Modules/hmacmodule.c
index b39a8f99ed91e8..0f9eca2f73bd0c 100644
--- a/Modules/hmacmodule.c
+++ b/Modules/hmacmodule.c
@@ -942,20 +942,19 @@ _hmac_HMAC_digest_impl(HMACObject *self)
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
_hmac.HMAC.hexdigest
Return hexadecimal digest of the bytes passed to the update() method so far.
-This may be used to exchange the value safely in email or other non-binary
-environments.
+This may be used to exchange the value safely in email or other
+non-binary environments.
This method may raise a MemoryError.
[clinic start generated code]*/
static PyObject *
_hmac_HMAC_hexdigest_impl(HMACObject *self)
-/*[clinic end generated code: output=6659807a09ae14ec input=6e0e796e38d82fc8]*/
+/*[clinic end generated code: output=6659807a09ae14ec input=9097dce732ed808f]*/
{
assert(self->digest_size <= Py_hmac_hash_max_digest_size);
uint8_t digest[Py_hmac_hash_max_digest_size];
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index a6bfa78a461bb0..68ac810eaad237 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -107,6 +107,7 @@ typedef struct {
#define batchedobject_CAST(op) ((batchedobject *)(op))
/*[clinic input]
+@permit_long_summary
@classmethod
itertools.batched.__new__ as batched_new
iterable: object
@@ -136,7 +137,7 @@ than n.
static PyObject *
batched_new_impl(PyTypeObject *type, PyObject *iterable, Py_ssize_t n,
int strict)
-/*[clinic end generated code: output=c6de11b061529d3e input=7814b47e222f5467]*/
+/*[clinic end generated code: output=c6de11b061529d3e input=b31d8be8e8577a34]*/
{
PyObject *it;
batchedobject *bo;
@@ -437,6 +438,7 @@ typedef struct {
static PyObject *_grouper_create(groupbyobject *, PyObject *);
/*[clinic input]
+@permit_long_summary
@classmethod
itertools.groupby.__new__
@@ -452,7 +454,7 @@ make an iterator that returns consecutive keys and groups from the iterable
static PyObject *
itertools_groupby_impl(PyTypeObject *type, PyObject *it, PyObject *keyfunc)
-/*[clinic end generated code: output=cbb1ae3a90fd4141 input=6b3d123e87ff65a1]*/
+/*[clinic end generated code: output=cbb1ae3a90fd4141 input=9f89fe625b20ef1a]*/
{
groupbyobject *gbo;
@@ -3163,13 +3165,13 @@ itertools.compress.__new__
selectors as seq2: object
Return data elements corresponding to true selector elements.
-Forms a shorter iterator from selected data elements using the selectors to
-choose the data elements.
+Forms a shorter iterator from selected data elements using the selectors
+to choose the data elements.
[clinic start generated code]*/
static PyObject *
itertools_compress_impl(PyTypeObject *type, PyObject *seq1, PyObject *seq2)
-/*[clinic end generated code: output=7e67157212ed09e0 input=79596d7cd20c77e5]*/
+/*[clinic end generated code: output=7e67157212ed09e0 input=32ca4347dbc46749]*/
{
PyObject *data=NULL, *selectors=NULL;
compressobject *lz;
@@ -3427,6 +3429,7 @@ slow_mode: when cnt == PY_SSIZE_T_MAX, step is not int(1), or cnt is a float.
*/
/*[clinic input]
+@permit_long_summary
@classmethod
itertools.count.__new__
start as long_cnt: object(c_default="NULL") = 0
@@ -3444,7 +3447,7 @@ Equivalent to:
static PyObject *
itertools_count_impl(PyTypeObject *type, PyObject *long_cnt,
PyObject *long_step)
-/*[clinic end generated code: output=09a9250aebd00b1c input=d7a85eec18bfcd94]*/
+/*[clinic end generated code: output=09a9250aebd00b1c input=91e4b12c0e88b9f4]*/
{
countobject *lz;
int fast_mode;
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index 6b7fc004d0d858..a7616ad70e4afe 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -2541,6 +2541,7 @@ math_isnan_impl(PyObject *module, double x)
/*[clinic input]
+@permit_long_summary
math.isinf
x: double
@@ -2551,7 +2552,7 @@ Return True if x is a positive or negative infinity, and False otherwise.
static PyObject *
math_isinf_impl(PyObject *module, double x)
-/*[clinic end generated code: output=9f00cbec4de7b06b input=32630e4212cf961f]*/
+/*[clinic end generated code: output=9f00cbec4de7b06b input=8584152a71a3aea9]*/
{
return PyBool_FromLong((long)isinf(x));
}
@@ -2831,7 +2832,7 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start)
/*[clinic input]
-@permit_long_docstring_body
+@permit_long_summary
math.nextafter
x: double
@@ -2844,13 +2845,13 @@ Return the floating-point value the given number of steps after x towards y.
If steps is not specified or is None, it defaults to 1.
-Raises a TypeError, if x or y is not a double, or if steps is not an integer.
-Raises ValueError if steps is negative.
+Raises a TypeError, if x or y is not a double, or if steps is not
+an integer. Raises ValueError if steps is negative.
[clinic start generated code]*/
static PyObject *
math_nextafter_impl(PyObject *module, double x, double y, PyObject *steps)
-/*[clinic end generated code: output=cc6511f02afc099e input=cc8f0dad1b27a8a4]*/
+/*[clinic end generated code: output=cc6511f02afc099e input=3a9151e6b1e9f346]*/
{
#if defined(_AIX)
if (x == y) {
diff --git a/Modules/overlapped.c b/Modules/overlapped.c
index 51aee5afd35b6d..255576cc057cdd 100644
--- a/Modules/overlapped.c
+++ b/Modules/overlapped.c
@@ -885,13 +885,14 @@ _overlapped.Overlapped.getresult
Retrieve result of operation.
-If wait is true then it blocks until the operation is finished. If wait
-is false and the operation is still pending then an error is raised.
+If wait is true then it blocks until the operation is finished. If
+wait is false and the operation is still pending then an error is
+raised.
[clinic start generated code]*/
static PyObject *
_overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait)
-/*[clinic end generated code: output=8c9bd04d08994f6c input=aa5b03e9897ca074]*/
+/*[clinic end generated code: output=8c9bd04d08994f6c input=852fbd817cbd2b3d]*/
{
DWORD transferred = 0;
BOOL ret;
diff --git a/Modules/readline.c b/Modules/readline.c
index 488332f548e5fe..2cc3d40baa3aba 100644
--- a/Modules/readline.c
+++ b/Modules/readline.c
@@ -432,6 +432,7 @@ readline_append_history_file_impl(PyObject *module, int nelements,
/* Set history length */
/*[clinic input]
+@permit_long_summary
readline.set_history_length
length: int
@@ -444,7 +445,7 @@ A negative length is used to inhibit history truncation.
static PyObject *
readline_set_history_length_impl(PyObject *module, int length)
-/*[clinic end generated code: output=e161a53e45987dc7 input=b8901bf16488b760]*/
+/*[clinic end generated code: output=e161a53e45987dc7 input=8d02c81b38ef81ec]*/
{
FT_ATOMIC_STORE_INT_RELAXED(_history_length, length);
Py_RETURN_NONE;
@@ -453,6 +454,7 @@ readline_set_history_length_impl(PyObject *module, int length)
/* Get history length */
/*[clinic input]
+@permit_long_summary
readline.get_history_length
Return the maximum number of lines that will be written to the history file.
@@ -460,7 +462,7 @@ Return the maximum number of lines that will be written to the history file.
static PyObject *
readline_get_history_length_impl(PyObject *module)
-/*[clinic end generated code: output=83a2eeae35b6d2b9 input=5dce2eeba4327817]*/
+/*[clinic end generated code: output=83a2eeae35b6d2b9 input=a65823e732ebfa9d]*/
{
int history_length = FT_ATOMIC_LOAD_INT_RELAXED(_history_length);
return PyLong_FromLong(history_length);
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index eb3148ef24631b..2c56dbc6a541f7 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -242,7 +242,6 @@ set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
#endif /* FD_SETSIZE > 1024 */
/*[clinic input]
-@permit_long_docstring_body
select.select
rlist: object
@@ -253,7 +252,8 @@ select.select
Wait until one or more file descriptors are ready for some kind of I/O.
-The first three arguments are iterables of file descriptors to be waited for:
+The first three arguments are iterables of file descriptors to be waited
+for:
rlist -- wait until ready for reading
wlist -- wait until ready for writing
xlist -- wait for an "exceptional condition"
@@ -266,9 +266,9 @@ The optional 4th argument specifies a timeout in seconds; it may be
a non-integer to specify fractions of seconds. If it is absent
or None, the call will never time out.
-The return value is a tuple of three lists corresponding to the first three
-arguments; each contains the subset of the corresponding file descriptors
-that are ready.
+The return value is a tuple of three lists corresponding to the first
+three arguments; each contains the subset of the corresponding file
+descriptors that are ready.
*** IMPORTANT NOTICE ***
On Windows, only sockets are supported; on Unix, all file
@@ -278,7 +278,7 @@ descriptors can be used.
static PyObject *
select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist,
PyObject *xlist, PyObject *timeout_obj)
-/*[clinic end generated code: output=2b3cfa824f7ae4cf input=b0403de75cd11cc1]*/
+/*[clinic end generated code: output=2b3cfa824f7ae4cf input=cc93e9bb9ffacbaf]*/
{
#ifdef SELECT_USES_HEAP
pylist *rfd2obj, *wfd2obj, *efd2obj;
@@ -616,13 +616,13 @@ select.poll.poll
Polls the set of registered file descriptors.
-Returns a list containing any descriptors that have events or errors to
-report, as a list of (fd, event) 2-tuples.
+Returns a list containing any descriptors that have events or errors
+to report, as a list of (fd, event) 2-tuples.
[clinic start generated code]*/
static PyObject *
select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
-/*[clinic end generated code: output=876e837d193ed7e4 input=54310631457efdec]*/
+/*[clinic end generated code: output=876e837d193ed7e4 input=e0a9c0aa283de8c8]*/
{
PyObject *result_list = NULL;
int poll_result, i, j;
@@ -975,19 +975,19 @@ select_devpoll_unregister_impl(devpollObject *self, int fd)
@critical_section
select.devpoll.poll
timeout as timeout_obj: object = None
- The maximum time to wait in milliseconds, or else None (or a negative
- value) to wait indefinitely.
+ The maximum time to wait in milliseconds, or else None (or
+ a negative value) to wait indefinitely.
/
Polls the set of registered file descriptors.
-Returns a list containing any descriptors that have events or errors to
-report, as a list of (fd, event) 2-tuples.
+Returns a list containing any descriptors that have events or errors
+to report, as a list of (fd, event) 2-tuples.
[clinic start generated code]*/
static PyObject *
select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
-/*[clinic end generated code: output=2654e5457cca0b3c input=fe7a3f6dcbc118c5]*/
+/*[clinic end generated code: output=2654e5457cca0b3c input=9e1672658d728539]*/
{
struct dvpoll dvp;
PyObject *result_list = NULL;
@@ -1233,18 +1233,17 @@ static PyType_Spec devpoll_Type_spec = {
/*[clinic input]
-@permit_long_docstring_body
select.poll
Returns a polling object.
-This object supports registering and unregistering file descriptors, and then
-polling them for I/O events.
+This object supports registering and unregistering file descriptors, and
+then polling them for I/O events.
[clinic start generated code]*/
static PyObject *
select_poll_impl(PyObject *module)
-/*[clinic end generated code: output=16a665a4e1d228c5 input=5e07eea8ad564e7f]*/
+/*[clinic end generated code: output=16a665a4e1d228c5 input=0aefd4527e99e0aa]*/
{
return (PyObject *)newPollObject(module);
}
@@ -1252,18 +1251,17 @@ select_poll_impl(PyObject *module)
#ifdef HAVE_SYS_DEVPOLL_H
/*[clinic input]
-@permit_long_docstring_body
select.devpoll
Returns a polling object.
-This object supports registering and unregistering file descriptors, and then
-polling them for I/O events.
+This object supports registering and unregistering file descriptors, and
+then polling them for I/O events.
[clinic start generated code]*/
static PyObject *
select_devpoll_impl(PyObject *module)
-/*[clinic end generated code: output=ea9213cc87fd9581 input=048506faef19d947]*/
+/*[clinic end generated code: output=ea9213cc87fd9581 input=4c2ac27d10248526]*/
{
return (PyObject *)newDevPollObject(module);
}
@@ -1540,6 +1538,7 @@ pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
}
/*[clinic input]
+@permit_long_summary
select.epoll.register
fd: fildes
@@ -1555,7 +1554,7 @@ The epoll interface supports all file descriptors that support poll.
static PyObject *
select_epoll_register_impl(pyEpoll_Object *self, int fd,
unsigned int eventmask)
-/*[clinic end generated code: output=318e5e6386520599 input=a5071b71edfe3578]*/
+/*[clinic end generated code: output=318e5e6386520599 input=9f0c9ebb25a4fc8f]*/
{
return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
}
@@ -1606,14 +1605,14 @@ select.epoll.poll
Wait for events on the epoll file descriptor.
-Returns a list containing any descriptors that have events to report,
-as a list of (fd, events) 2-tuples.
+Returns a list containing any descriptors that have events to
+report, as a list of (fd, events) 2-tuples.
[clinic start generated code]*/
static PyObject *
select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
int maxevents)
-/*[clinic end generated code: output=e02d121a20246c6c input=deafa7f04a60ebe0]*/
+/*[clinic end generated code: output=e02d121a20246c6c input=911ddc16978a9159]*/
{
int nfds, i;
PyObject *elist = NULL, *etuple = NULL;
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index fb548b8ca00f24..8456239dee202d 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -450,7 +450,6 @@ signal_raise_signal_impl(PyObject *module, int signalnum)
}
/*[clinic input]
-@permit_long_docstring_body
signal.signal
signalnum: int
@@ -460,16 +459,17 @@ signal.signal
Set the action for the given signal.
The action can be SIG_DFL, SIG_IGN, or a callable Python object.
-The previous action is returned. See getsignal() for possible return values.
+The previous action is returned. See getsignal() for possible return
+values.
*** IMPORTANT NOTICE ***
-A signal handler function is called with two arguments:
-the first is the signal number, the second is the interrupted stack frame.
+A signal handler function is called with two arguments: the first is
+the signal number, the second is the interrupted stack frame.
[clinic start generated code]*/
static PyObject *
signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
-/*[clinic end generated code: output=b44cfda43780f3a1 input=7608656f34fa378b]*/
+/*[clinic end generated code: output=b44cfda43780f3a1 input=99ce4035ec56ffc1]*/
{
_signal_module_state *modstate = get_signal_state(module);
PyObject *old_handler;
@@ -839,7 +839,6 @@ PySignal_SetWakeupFd(int fd)
#ifdef HAVE_SETITIMER
/*[clinic input]
-@permit_long_docstring_body
signal.setitimer
which: int
@@ -849,8 +848,8 @@ signal.setitimer
Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).
-The timer will fire after value seconds and after that every interval seconds.
-The itimer can be cleared by setting seconds to zero.
+The timer will fire after value seconds and after that every interval
+seconds. The itimer can be cleared by setting seconds to zero.
Returns old values as a tuple: (delay, interval).
[clinic start generated code]*/
@@ -858,7 +857,7 @@ Returns old values as a tuple: (delay, interval).
static PyObject *
signal_setitimer_impl(PyObject *module, int which, PyObject *seconds,
PyObject *interval)
-/*[clinic end generated code: output=65f9dcbddc35527b input=ab5bf2b8f5cff3f4]*/
+/*[clinic end generated code: output=65f9dcbddc35527b input=bd9f0d2ed8614193]*/
{
_signal_module_state *modstate = get_signal_state(module);
@@ -1019,13 +1018,13 @@ signal.sigwait
Wait for a signal.
Suspend execution of the calling thread until the delivery of one of the
-signals specified in the signal set sigset. The function accepts the signal
-and returns the signal number.
+signals specified in the signal set sigset. The function accepts the
+signal and returns the signal number.
[clinic start generated code]*/
static PyObject *
signal_sigwait_impl(PyObject *module, sigset_t sigset)
-/*[clinic end generated code: output=f43770699d682f96 input=a6fbd47b1086d119]*/
+/*[clinic end generated code: output=f43770699d682f96 input=91773742dd416a3e]*/
{
int err, signum;
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index f5993fc8fdaab2..722287fbb134c3 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -4620,7 +4620,6 @@ sock_send_impl(PySocketSockObject *s, void *data)
}
/*[clinic input]
-@permit_long_docstring_body
_socket.socket.send
self as s: self(type="PySocketSockObject *")
data as pbuf: Py_buffer
@@ -4630,12 +4629,13 @@ _socket.socket.send
Send a data string to the socket.
For the optional flags argument, see the Unix manual.
-Return the number of bytes sent; this may be less than len(data) if the network is busy.
+Return the number of bytes sent; this may be less than len(data) if
+the network is busy.
[clinic start generated code]*/
static PyObject *
_socket_socket_send_impl(PySocketSockObject *s, Py_buffer *pbuf, int flags)
-/*[clinic end generated code: output=3ddf83f17d0c875b input=e776a48af2e3d615]*/
+/*[clinic end generated code: output=3ddf83f17d0c875b input=d2b8af9bf99cfafb]*/
{
struct sock_send ctx;
@@ -4665,13 +4665,14 @@ Send a data string to the socket.
For the optional flags argument, see the Unix manual.
This calls send() repeatedly until all data is sent.
-If an error occurs, it's impossible to tell how much data has been sent.
+If an error occurs, it's impossible to tell how much data has been
+sent.
[clinic start generated code]*/
static PyObject *
_socket_socket_sendall_impl(PySocketSockObject *s, Py_buffer *pbuf,
int flags)
-/*[clinic end generated code: output=ec92861424d3faa8 input=732b15b9ca64dce6]*/
+/*[clinic end generated code: output=ec92861424d3faa8 input=2600de13b4614893]*/
{
char *buf;
@@ -4921,20 +4922,20 @@ The buffers argument specifies the non-ancillary
data as an iterable of bytes-like objects (e.g. bytes objects).
The ancdata argument specifies the ancillary data (control messages)
as an iterable of zero or more tuples (cmsg_level, cmsg_type,
-cmsg_data), where cmsg_level and cmsg_type are integers specifying the
-protocol level and protocol-specific type respectively, and cmsg_data
-is a bytes-like object holding the associated data. The flags
-argument defaults to 0 and has the same meaning as for send(). If
-address is supplied and not None, it sets a destination address for
-the message. The return value is the number of bytes of non-ancillary
-data sent.
+cmsg_data), where cmsg_level and cmsg_type are integers specifying
+the protocol level and protocol-specific type respectively, and
+cmsg_data is a bytes-like object holding the associated data. The
+flags argument defaults to 0 and has the same meaning as for send().
+If address is supplied and not None, it sets a destination address
+for the message. The return value is the number of bytes of
+non-ancillary data sent.
[clinic start generated code]*/
static PyObject *
_socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg,
PyObject *cmsg_arg, int flags,
PyObject *addr_arg)
-/*[clinic end generated code: output=3b4cb1110644ce39 input=479c13d90bd2f88b]*/
+/*[clinic end generated code: output=3b4cb1110644ce39 input=8ae408971a3aa329]*/
{
Py_ssize_t i, ndatabufs = 0, ncmsgs, ncmsgbufs = 0;
@@ -7310,6 +7311,7 @@ _socket_if_nametoindex_impl(PyObject *module, PyObject *oname)
/*[clinic input]
+@permit_long_summary
_socket.if_indextoname
if_index as index: NET_IFINDEX
/
@@ -7319,7 +7321,7 @@ Returns the interface name corresponding to the interface index if_index.
static PyObject *
_socket_if_indextoname_impl(PyObject *module, NET_IFINDEX index)
-/*[clinic end generated code: output=e48bc324993052e0 input=c93f753d0cf6d7d1]*/
+/*[clinic end generated code: output=e48bc324993052e0 input=2a0026b271cd43ae]*/
{
errno = ENXIO; // in case 'if_indextoname' does not set errno
char name[IF_NAMESIZE + 1];
diff --git a/Modules/termios.c b/Modules/termios.c
index 95b9c920f39c12..38743e176f0bf6 100644
--- a/Modules/termios.c
+++ b/Modules/termios.c
@@ -312,6 +312,7 @@ termios_tcsendbreak_impl(PyObject *module, int fd, int duration)
}
/*[clinic input]
+@permit_long_summary
termios.tcdrain
fd: fildes
@@ -322,7 +323,7 @@ Wait until all output written to file descriptor fd has been transmitted.
static PyObject *
termios_tcdrain_impl(PyObject *module, int fd)
-/*[clinic end generated code: output=5fd86944c6255955 input=c99241b140b32447]*/
+/*[clinic end generated code: output=5fd86944c6255955 input=d1557e60b5ec66c5]*/
{
termiosmodulestate *state = PyModule_GetState(module);
int r;
@@ -474,7 +475,6 @@ termios_tcgetwinsize_impl(PyObject *module, int fd)
}
/*[clinic input]
-@permit_long_docstring_body
termios.tcsetwinsize
fd: fildes
@@ -484,12 +484,13 @@ termios.tcsetwinsize
Set the tty winsize for file descriptor fd.
The winsize to be set is taken from the winsize argument, which
-is a two-item tuple (ws_row, ws_col) like the one returned by tcgetwinsize().
+is a two-item tuple (ws_row, ws_col) like the one returned by
+tcgetwinsize().
[clinic start generated code]*/
static PyObject *
termios_tcsetwinsize_impl(PyObject *module, int fd, PyObject *winsz)
-/*[clinic end generated code: output=2ac3c9bb6eda83e1 input=9a163c4e06fc4a41]*/
+/*[clinic end generated code: output=2ac3c9bb6eda83e1 input=efc9beb16d06382a]*/
{
if (!PySequence_Check(winsz) || PySequence_Size(winsz) != 2) {
PyErr_SetString(PyExc_TypeError,
diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c
index 55b33a76e7af8a..31ad916b2c5c26 100644
--- a/Modules/unicodedata.c
+++ b/Modules/unicodedata.c
@@ -291,6 +291,7 @@ unicodedata_UCD_numeric_impl(PyObject *self, int chr,
}
/*[clinic input]
+@permit_long_summary
unicodedata.UCD.category
self: self
@@ -302,7 +303,7 @@ Returns the general category assigned to the character chr as string.
static PyObject *
unicodedata_UCD_category_impl(PyObject *self, int chr)
-/*[clinic end generated code: output=8571539ee2e6783a input=27d6f3d85050bc06]*/
+/*[clinic end generated code: output=8571539ee2e6783a input=1d729c67299e8a31]*/
{
int index;
Py_UCS4 c = (Py_UCS4)chr;
@@ -316,6 +317,7 @@ unicodedata_UCD_category_impl(PyObject *self, int chr)
}
/*[clinic input]
+@permit_long_summary
unicodedata.UCD.bidirectional
self: self
@@ -329,7 +331,7 @@ If no such value is defined, an empty string is returned.
static PyObject *
unicodedata_UCD_bidirectional_impl(PyObject *self, int chr)
-/*[clinic end generated code: output=d36310ce2039bb92 input=b3d8f42cebfcf475]*/
+/*[clinic end generated code: output=d36310ce2039bb92 input=838f8a2203bd2990]*/
{
int index;
Py_UCS4 c = (Py_UCS4)chr;
@@ -373,6 +375,7 @@ unicodedata_UCD_combining_impl(PyObject *self, int chr)
}
/*[clinic input]
+@permit_long_summary
unicodedata.UCD.mirrored -> int
self: self
@@ -387,7 +390,7 @@ character in bidirectional text, 0 otherwise.
static int
unicodedata_UCD_mirrored_impl(PyObject *self, int chr)
-/*[clinic end generated code: output=2532dbf8121b50e6 input=5dd400d351ae6f3b]*/
+/*[clinic end generated code: output=2532dbf8121b50e6 input=6db28989e49cd9c8]*/
{
int index;
Py_UCS4 c = (Py_UCS4)chr;
@@ -403,6 +406,7 @@ unicodedata_UCD_mirrored_impl(PyObject *self, int chr)
}
/*[clinic input]
+@permit_long_summary
unicodedata.UCD.east_asian_width
self: self
@@ -414,7 +418,7 @@ Returns the east asian width assigned to the character chr as string.
static PyObject *
unicodedata_UCD_east_asian_width_impl(PyObject *self, int chr)
-/*[clinic end generated code: output=484e8537d9ee8197 input=c4854798aab026e0]*/
+/*[clinic end generated code: output=484e8537d9ee8197 input=207c5f68fa475516]*/
{
int index;
Py_UCS4 c = (Py_UCS4)chr;
@@ -911,6 +915,7 @@ is_normalized_quickcheck(PyObject *self, PyObject *input, bool nfc, bool k,
}
/*[clinic input]
+@permit_long_summary
unicodedata.UCD.is_normalized
self: self
@@ -926,7 +931,7 @@ Valid values for form are 'NFC', 'NFKC', 'NFD', and 'NFKD'.
static PyObject *
unicodedata_UCD_is_normalized_impl(PyObject *self, PyObject *form,
PyObject *input)
-/*[clinic end generated code: output=11e5a3694e723ca5 input=a544f14cea79e508]*/
+/*[clinic end generated code: output=11e5a3694e723ca5 input=de66aa679265300b]*/
{
if (PyUnicode_GET_LENGTH(input) == 0) {
/* special case empty input strings. */
diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c
index 9c5820fbe97a6b..0a6732835eb51f 100644
--- a/Modules/zlibmodule.c
+++ b/Modules/zlibmodule.c
@@ -858,7 +858,7 @@ save_unconsumed_input(compobject *self, Py_buffer *data, int err)
}
/*[clinic input]
-@permit_long_docstring_body
+@permit_long_summary
zlib.Decompress.decompress
cls: defining_class
@@ -872,15 +872,15 @@ zlib.Decompress.decompress
Return a bytes object containing the decompressed version of the data.
-After calling this function, some of the input data may still be stored in
-internal buffers for later processing.
+After calling this function, some of the input data may still be
+stored in internal buffers for later processing.
Call the flush() method to clear these buffers.
[clinic start generated code]*/
static PyObject *
zlib_Decompress_decompress_impl(compobject *self, PyTypeObject *cls,
Py_buffer *data, Py_ssize_t max_length)
-/*[clinic end generated code: output=b024a93c2c922d57 input=77de124bd2a2ecc0]*/
+/*[clinic end generated code: output=b024a93c2c922d57 input=9035027c9e4be7fd]*/
{
int err = Z_OK;
Py_ssize_t ibuflen;
@@ -1675,7 +1675,6 @@ decompress(ZlibDecompressor *self, uint8_t *data,
}
/*[clinic input]
-@permit_long_docstring_body
zlib._ZlibDecompressor.decompress
data: Py_buffer
@@ -1683,25 +1682,26 @@ zlib._ZlibDecompressor.decompress
Decompress *data*, returning uncompressed data as bytes.
-If *max_length* is nonnegative, returns at most *max_length* bytes of
-decompressed data. If this limit is reached and further output can be
-produced, *self.needs_input* will be set to ``False``. In this case, the next
-call to *decompress()* may provide *data* as b'' to obtain more of the output.
+If *max_length* is nonnegative, returns at most *max_length* bytes
+of decompressed data. If this limit is reached and further output
+can be produced, *self.needs_input* will be set to ``False``. In
+this case, the next call to *decompress()* may provide *data* as b''
+to obtain more of the output.
-If all of the input data was decompressed and returned (either because this
-was less than *max_length* bytes, or because *max_length* was negative),
-*self.needs_input* will be set to True.
+If all of the input data was decompressed and returned (either
+because this was less than *max_length* bytes, or because
+*max_length* was negative), *self.needs_input* will be set to True.
-Attempting to decompress data after the end of stream is reached raises an
-EOFError. Any data found after the end of the stream is ignored and saved in
-the unused_data attribute.
+Attempting to decompress data after the end of stream is reached
+raises an EOFError. Any data found after the end of the stream is
+ignored and saved in the unused_data attribute.
[clinic start generated code]*/
static PyObject *
zlib__ZlibDecompressor_decompress_impl(ZlibDecompressor *self,
Py_buffer *data,
Py_ssize_t max_length)
-/*[clinic end generated code: output=ac00dcf73e843e99 input=c9278e791be1152b]*/
+/*[clinic end generated code: output=ac00dcf73e843e99 input=d7862eade3f29d56]*/
{
PyObject *result = NULL;
diff --git a/Python/clinic/context.c.h b/Python/clinic/context.c.h
index 5ed74e6e6ddb6b..ece7341d65d5fb 100644
--- a/Python/clinic/context.c.h
+++ b/Python/clinic/context.c.h
@@ -10,8 +10,8 @@ PyDoc_STRVAR(_contextvars_Context_get__doc__,
"\n"
"Return the value for `key` if `key` has the value in the context object.\n"
"\n"
-"If `key` does not exist, return `default`. If `default` is not given,\n"
-"return None.");
+"If `key` does not exist, return `default`. If `default` is not\n"
+"given, return None.");
#define _CONTEXTVARS_CONTEXT_GET_METHODDEF \
{"get", _PyCFunction_CAST(_contextvars_Context_get), METH_FASTCALL, _contextvars_Context_get__doc__},
@@ -122,10 +122,12 @@ PyDoc_STRVAR(_contextvars_ContextVar_get__doc__,
"\n"
"Return a value for the context variable for the current context.\n"
"\n"
-"If there is no value for the variable in the current context, the method will:\n"
-" * return the value of the default argument of the method, if provided; or\n"
-" * return the default value for the context variable, if it was created\n"
-" with one; or\n"
+"If there is no value for the variable in the current context, the\n"
+"method will:\n"
+" * return the value of the default argument of the method, if\n"
+" provided; or\n"
+" * return the default value for the context variable, if it was\n"
+" created with one; or\n"
" * raise a LookupError.");
#define _CONTEXTVARS_CONTEXTVAR_GET_METHODDEF \
@@ -160,10 +162,11 @@ PyDoc_STRVAR(_contextvars_ContextVar_set__doc__,
"\n"
"Call to set a new value for the context variable in the current context.\n"
"\n"
-"The required value argument is the new value for the context variable.\n"
+"The required value argument is the new value for the context\n"
+"variable.\n"
"\n"
-"Returns a Token object that can be used to restore the variable to its previous\n"
-"value via the `ContextVar.reset()` method.");
+"Returns a Token object that can be used to restore the variable to\n"
+"its previous value via the `ContextVar.reset()` method.");
#define _CONTEXTVARS_CONTEXTVAR_SET_METHODDEF \
{"set", (PyCFunction)_contextvars_ContextVar_set, METH_O, _contextvars_ContextVar_set__doc__},
@@ -187,8 +190,8 @@ PyDoc_STRVAR(_contextvars_ContextVar_reset__doc__,
"\n"
"Reset the context variable.\n"
"\n"
-"The variable is reset to the value it had before the `ContextVar.set()` that\n"
-"created the token was used.");
+"The variable is reset to the value it had before the\n"
+"`ContextVar.set()` that created the token was used.");
#define _CONTEXTVARS_CONTEXTVAR_RESET_METHODDEF \
{"reset", (PyCFunction)_contextvars_ContextVar_reset, METH_O, _contextvars_ContextVar_reset__doc__},
@@ -256,4 +259,4 @@ token_exit(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=3a04b2fddf24c3e9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=90ec3e4375804e9b input=a9049054013a1b77]*/
diff --git a/Python/clinic/import.c.h b/Python/clinic/import.c.h
index de62714ebddafa..2e4e178b308406 100644
--- a/Python/clinic/import.c.h
+++ b/Python/clinic/import.c.h
@@ -34,8 +34,9 @@ PyDoc_STRVAR(_imp_acquire_lock__doc__,
"\n"
"Acquires the interpreter\'s import lock for the current thread.\n"
"\n"
-"This lock should be used by import hooks to ensure thread-safety when importing\n"
-"modules. On platforms without threads, this function does nothing.");
+"This lock should be used by import hooks to ensure thread-safety when\n"
+"importing modules. On platforms without threads, this function does\n"
+"nothing.");
#define _IMP_ACQUIRE_LOCK_METHODDEF \
{"acquire_lock", (PyCFunction)_imp_acquire_lock, METH_NOARGS, _imp_acquire_lock__doc__},
@@ -664,4 +665,4 @@ _imp__set_lazy_attributes(PyObject *module, PyObject *const *args, Py_ssize_t na
#ifndef _IMP_EXEC_DYNAMIC_METHODDEF
#define _IMP_EXEC_DYNAMIC_METHODDEF
#endif /* !defined(_IMP_EXEC_DYNAMIC_METHODDEF) */
-/*[clinic end generated code: output=5fa42f580441b3fa input=a9049054013a1b77]*/
+/*[clinic end generated code: output=0974db098d601372 input=a9049054013a1b77]*/
diff --git a/Python/clinic/marshal.c.h b/Python/clinic/marshal.c.h
index 6c00b2b31b007f..ec0d2eb8a2af54 100644
--- a/Python/clinic/marshal.c.h
+++ b/Python/clinic/marshal.c.h
@@ -195,8 +195,8 @@ PyDoc_STRVAR(marshal_dumps__doc__,
" allow_code\n"
" Allow to write code objects.\n"
"\n"
-"Raise a ValueError exception if value has (or contains an object that has) an\n"
-"unsupported type.");
+"Raise a ValueError exception if value has (or contains an object that\n"
+"has) an unsupported type.");
#define MARSHAL_DUMPS_METHODDEF \
{"dumps", _PyCFunction_CAST(marshal_dumps), METH_FASTCALL|METH_KEYWORDS, marshal_dumps__doc__},
@@ -280,8 +280,8 @@ PyDoc_STRVAR(marshal_loads__doc__,
" allow_code\n"
" Allow to load code objects.\n"
"\n"
-"If no valid value is found, raise EOFError, ValueError or TypeError. Extra\n"
-"bytes in the input are ignored.");
+"If no valid value is found, raise EOFError, ValueError or TypeError.\n"
+"Extra bytes in the input are ignored.");
#define MARSHAL_LOADS_METHODDEF \
{"loads", _PyCFunction_CAST(marshal_loads), METH_FASTCALL|METH_KEYWORDS, marshal_loads__doc__},
@@ -351,4 +351,4 @@ marshal_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec
return return_value;
}
-/*[clinic end generated code: output=3e4bfc070a3c78ac input=a9049054013a1b77]*/
+/*[clinic end generated code: output=a574570c3717f60e input=a9049054013a1b77]*/
diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h
index 86e942ec2b8afb..75ce493f8688d6 100644
--- a/Python/clinic/sysmodule.c.h
+++ b/Python/clinic/sysmodule.c.h
@@ -1395,7 +1395,8 @@ PyDoc_STRVAR(sys__stats_dump__doc__,
"\n"
"Dump stats to file, and clears the stats.\n"
"\n"
-"Return False if no statistics were not dumped because stats gathering was off.");
+"Return False if no statistics were not dumped because stats gathering\n"
+"was off.");
#define SYS__STATS_DUMP_METHODDEF \
{"_stats_dump", (PyCFunction)sys__stats_dump, METH_NOARGS, sys__stats_dump__doc__},
@@ -1543,16 +1544,16 @@ PyDoc_STRVAR(sys_remote_exec__doc__,
"Executes a file containing Python code in a given remote Python process.\n"
"\n"
"This function returns immediately, and the code will be executed by the\n"
-"target process\'s main thread at the next available opportunity, similarly\n"
-"to how signals are handled. There is no interface to determine when the\n"
-"code has been executed. The caller is responsible for making sure that\n"
-"the file still exists whenever the remote process tries to read it and that\n"
-"it hasn\'t been overwritten.\n"
+"target process\'s main thread at the next available opportunity,\n"
+"similarly to how signals are handled. There is no interface to\n"
+"determine when the code has been executed. The caller is responsible\n"
+"for making sure that the file still exists whenever the remote process\n"
+"tries to read it and that it hasn\'t been overwritten.\n"
"\n"
-"The remote process must be running a CPython interpreter of the same major\n"
-"and minor version as the local process. If either the local or remote\n"
-"interpreter is pre-release (alpha, beta, or release candidate) then the\n"
-"local and remote interpreters must be the same exact version.\n"
+"The remote process must be running a CPython interpreter of the same\n"
+"major and minor version as the local process. If either the local or\n"
+"remote interpreter is pre-release (alpha, beta, or release candidate)\n"
+"then the local and remote interpreters must be the same exact version.\n"
"\n"
"Args:\n"
" pid (int): The process ID of the target Python process.\n"
@@ -1915,7 +1916,8 @@ PyDoc_STRVAR(sys_set_lazy_imports__doc__,
"The mode parameter must be one of the following strings:\n"
"- \"all\": All top-level imports become potentially lazy\n"
"- \"none\": All lazy imports are suppressed (even explicitly marked ones)\n"
-"- \"normal\": Only explicitly marked imports (with \'lazy\' keyword) are lazy\n"
+"- \"normal\": Only explicitly marked imports (with \'lazy\' keyword) are\n"
+" lazy\n"
"\n"
"In addition to the mode, lazy imports can be controlled via the filter\n"
"provided to sys.set_lazy_imports_filter");
@@ -2121,4 +2123,4 @@ _jit_is_active(PyObject *module, PyObject *Py_UNUSED(ignored))
#ifndef SYS_GETANDROIDAPILEVEL_METHODDEF
#define SYS_GETANDROIDAPILEVEL_METHODDEF
#endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */
-/*[clinic end generated code: output=e8333fe10c01ae66 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=94838be2d96b4522 input=a9049054013a1b77]*/
diff --git a/Python/context.c b/Python/context.c
index 62b582f271ffe5..3170018da8c1c9 100644
--- a/Python/context.c
+++ b/Python/context.c
@@ -618,6 +618,7 @@ context_tp_contains(PyObject *op, PyObject *key)
/*[clinic input]
+@permit_long_summary
_contextvars.Context.get
key: object
default: object = None
@@ -625,14 +626,14 @@ _contextvars.Context.get
Return the value for `key` if `key` has the value in the context object.
-If `key` does not exist, return `default`. If `default` is not given,
-return None.
+If `key` does not exist, return `default`. If `default` is not
+given, return None.
[clinic start generated code]*/
static PyObject *
_contextvars_Context_get_impl(PyContext *self, PyObject *key,
PyObject *default_value)
-/*[clinic end generated code: output=0c54aa7664268189 input=c8eeb81505023995]*/
+/*[clinic end generated code: output=0c54aa7664268189 input=d669a0d56fabb0a5]*/
{
if (context_check_key_type(key)) {
return NULL;
@@ -1006,23 +1007,24 @@ contextvar_tp_repr(PyObject *op)
/*[clinic input]
-@permit_long_docstring_body
_contextvars.ContextVar.get
default: object = NULL
/
Return a value for the context variable for the current context.
-If there is no value for the variable in the current context, the method will:
- * return the value of the default argument of the method, if provided; or
- * return the default value for the context variable, if it was created
- with one; or
+If there is no value for the variable in the current context, the
+method will:
+ * return the value of the default argument of the method, if
+ provided; or
+ * return the default value for the context variable, if it was
+ created with one; or
* raise a LookupError.
[clinic start generated code]*/
static PyObject *
_contextvars_ContextVar_get_impl(PyContextVar *self, PyObject *default_value)
-/*[clinic end generated code: output=0746bd0aa2ced7bf input=da66664d5d0af4ad]*/
+/*[clinic end generated code: output=0746bd0aa2ced7bf input=83814c6aef4a9fe3]*/
{
PyObject *val;
if (PyContextVar_Get((PyObject *)self, default_value, &val) < 0) {
@@ -1038,41 +1040,41 @@ _contextvars_ContextVar_get_impl(PyContextVar *self, PyObject *default_value)
}
/*[clinic input]
-@permit_long_docstring_body
+@permit_long_summary
_contextvars.ContextVar.set
value: object
/
Call to set a new value for the context variable in the current context.
-The required value argument is the new value for the context variable.
+The required value argument is the new value for the context
+variable.
-Returns a Token object that can be used to restore the variable to its previous
-value via the `ContextVar.reset()` method.
+Returns a Token object that can be used to restore the variable to
+its previous value via the `ContextVar.reset()` method.
[clinic start generated code]*/
static PyObject *
_contextvars_ContextVar_set_impl(PyContextVar *self, PyObject *value)
-/*[clinic end generated code: output=1b562d35cc79c806 input=73ebbbfc7c98f6cd]*/
+/*[clinic end generated code: output=1b562d35cc79c806 input=04ef8dcd810f5be6]*/
{
return PyContextVar_Set((PyObject *)self, value);
}
/*[clinic input]
-@permit_long_docstring_body
_contextvars.ContextVar.reset
token: object
/
Reset the context variable.
-The variable is reset to the value it had before the `ContextVar.set()` that
-created the token was used.
+The variable is reset to the value it had before the
+`ContextVar.set()` that created the token was used.
[clinic start generated code]*/
static PyObject *
_contextvars_ContextVar_reset_impl(PyContextVar *self, PyObject *token)
-/*[clinic end generated code: output=3205d2bdff568521 input=b8bc514a9245242a]*/
+/*[clinic end generated code: output=3205d2bdff568521 input=dd33cfcb18c00e37]*/
{
if (!PyContextToken_CheckExact(token)) {
PyErr_Format(PyExc_TypeError,
diff --git a/Python/import.c b/Python/import.c
index 352941a836ef21..aa4ee660fa75da 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -5025,18 +5025,18 @@ _imp_lock_held_impl(PyObject *module)
}
/*[clinic input]
-@permit_long_docstring_body
_imp.acquire_lock
Acquires the interpreter's import lock for the current thread.
-This lock should be used by import hooks to ensure thread-safety when importing
-modules. On platforms without threads, this function does nothing.
+This lock should be used by import hooks to ensure thread-safety when
+importing modules. On platforms without threads, this function does
+nothing.
[clinic start generated code]*/
static PyObject *
_imp_acquire_lock_impl(PyObject *module)
-/*[clinic end generated code: output=1aff58cb0ee1b026 input=e1a4ef049d34e7dd]*/
+/*[clinic end generated code: output=1aff58cb0ee1b026 input=60e9c1b4ab471ead]*/
{
PyInterpreterState *interp = _PyInterpreterState_GET();
_PyImport_AcquireLock(interp);
@@ -5194,6 +5194,7 @@ _imp_init_frozen_impl(PyObject *module, PyObject *name)
}
/*[clinic input]
+@permit_long_summary
_imp.find_frozen
name: unicode
@@ -5214,7 +5215,7 @@ The returned info (a 2-tuple):
static PyObject *
_imp_find_frozen_impl(PyObject *module, PyObject *name, int withdata)
-/*[clinic end generated code: output=8c1c3c7f925397a5 input=22a8847c201542fd]*/
+/*[clinic end generated code: output=8c1c3c7f925397a5 input=30a7a50da49eca97]*/
{
struct frozen_info info;
frozen_status status = find_frozen(name, &info);
@@ -5401,6 +5402,7 @@ _imp__override_frozen_modules_for_tests_impl(PyObject *module, int override)
}
/*[clinic input]
+@permit_long_summary
_imp._override_multi_interp_extensions_check
override: int
@@ -5414,7 +5416,7 @@ _imp._override_multi_interp_extensions_check
static PyObject *
_imp__override_multi_interp_extensions_check_impl(PyObject *module,
int override)
-/*[clinic end generated code: output=3ff043af52bbf280 input=e086a2ea181f92ae]*/
+/*[clinic end generated code: output=3ff043af52bbf280 input=24f23f8510a7f6e7]*/
{
PyInterpreterState *interp = _PyInterpreterState_GET();
if (_Py_IsMainInterpreter(interp)) {
diff --git a/Python/marshal.c b/Python/marshal.c
index 990afefe0d3b41..9688d426419c2f 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -2061,7 +2061,6 @@ marshal_load_impl(PyObject *module, PyObject *file, int allow_code)
/*[clinic input]
@permit_long_summary
-@permit_long_docstring_body
marshal.dumps
value: object
@@ -2075,14 +2074,14 @@ marshal.dumps
Return the bytes object that would be written to a file by dump(value, file).
-Raise a ValueError exception if value has (or contains an object that has) an
-unsupported type.
+Raise a ValueError exception if value has (or contains an object that
+has) an unsupported type.
[clinic start generated code]*/
static PyObject *
marshal_dumps_impl(PyObject *module, PyObject *value, int version,
int allow_code)
-/*[clinic end generated code: output=115f90da518d1d49 input=80cd3f30c1637ade]*/
+/*[clinic end generated code: output=115f90da518d1d49 input=dc1edcafd43124c5]*/
{
return _PyMarshal_WriteObjectToString(value, version, allow_code);
}
@@ -2098,13 +2097,13 @@ marshal.loads
Convert the bytes-like object to a value.
-If no valid value is found, raise EOFError, ValueError or TypeError. Extra
-bytes in the input are ignored.
+If no valid value is found, raise EOFError, ValueError or TypeError.
+Extra bytes in the input are ignored.
[clinic start generated code]*/
static PyObject *
marshal_loads_impl(PyObject *module, Py_buffer *bytes, int allow_code)
-/*[clinic end generated code: output=62c0c538d3edc31f input=14de68965b45aaa7]*/
+/*[clinic end generated code: output=62c0c538d3edc31f input=286f1dbd6811d2ad]*/
{
RFILE rf;
char *s = bytes->buf;
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index c6447d03369a94..b2f33d4e809d26 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -1893,6 +1893,7 @@ sys_mdebug_impl(PyObject *module, int flag)
/*[clinic input]
+@permit_long_summary
sys.get_int_max_str_digits
Return the maximum string digits limit for non-binary int<->str conversions.
@@ -1900,7 +1901,7 @@ Return the maximum string digits limit for non-binary int<->str conversions.
static PyObject *
sys_get_int_max_str_digits_impl(PyObject *module)
-/*[clinic end generated code: output=0042f5e8ae0e8631 input=61bf9f99bc8b112d]*/
+/*[clinic end generated code: output=0042f5e8ae0e8631 input=77fb74e987ba7ecb]*/
{
PyInterpreterState *interp = _PyInterpreterState_GET();
return PyLong_FromLong(interp->long_state.max_str_digits);
@@ -1908,6 +1909,7 @@ sys_get_int_max_str_digits_impl(PyObject *module)
/*[clinic input]
+@permit_long_summary
sys.set_int_max_str_digits
maxdigits: int
@@ -1917,7 +1919,7 @@ Set the maximum string digits limit for non-binary int<->str conversions.
static PyObject *
sys_set_int_max_str_digits_impl(PyObject *module, int maxdigits)
-/*[clinic end generated code: output=734d4c2511f2a56d input=d7e3f325db6910c5]*/
+/*[clinic end generated code: output=734d4c2511f2a56d input=d4c0bf50c466d57a]*/
{
if (_PySys_SetIntMaxStrDigits(maxdigits) < 0) {
return NULL;
@@ -2129,6 +2131,7 @@ sys__getframe_impl(PyObject *module, int depth)
}
/*[clinic input]
+@permit_long_summary
sys._current_frames
Return a dict mapping each thread's thread id to its current stack frame.
@@ -2138,7 +2141,7 @@ This function should be used for specialized purposes only.
static PyObject *
sys__current_frames_impl(PyObject *module)
-/*[clinic end generated code: output=d2a41ac0a0a3809a input=2a9049c5f5033691]*/
+/*[clinic end generated code: output=d2a41ac0a0a3809a input=e1ce34f43501e0d6]*/
{
return _PyThread_CurrentFrames();
}
@@ -2317,17 +2320,17 @@ sys__stats_clear_impl(PyObject *module)
}
/*[clinic input]
-@permit_long_docstring_body
sys._stats_dump -> bool
Dump stats to file, and clears the stats.
-Return False if no statistics were not dumped because stats gathering was off.
+Return False if no statistics were not dumped because stats gathering
+was off.
[clinic start generated code]*/
static int
sys__stats_dump_impl(PyObject *module)
-/*[clinic end generated code: output=6e346b4ba0de4489 input=5a3ab40d2fb5af47]*/
+/*[clinic end generated code: output=6e346b4ba0de4489 input=7f3b7758cb59d2ff]*/
{
int res = _Py_PrintSpecializationStats(1);
_Py_StatsClear();
@@ -2471,16 +2474,16 @@ sys.remote_exec
Executes a file containing Python code in a given remote Python process.
This function returns immediately, and the code will be executed by the
-target process's main thread at the next available opportunity, similarly
-to how signals are handled. There is no interface to determine when the
-code has been executed. The caller is responsible for making sure that
-the file still exists whenever the remote process tries to read it and that
-it hasn't been overwritten.
+target process's main thread at the next available opportunity,
+similarly to how signals are handled. There is no interface to
+determine when the code has been executed. The caller is responsible
+for making sure that the file still exists whenever the remote process
+tries to read it and that it hasn't been overwritten.
-The remote process must be running a CPython interpreter of the same major
-and minor version as the local process. If either the local or remote
-interpreter is pre-release (alpha, beta, or release candidate) then the
-local and remote interpreters must be the same exact version.
+The remote process must be running a CPython interpreter of the same
+major and minor version as the local process. If either the local or
+remote interpreter is pre-release (alpha, beta, or release candidate)
+then the local and remote interpreters must be the same exact version.
Args:
pid (int): The process ID of the target Python process.
@@ -2490,7 +2493,7 @@ local and remote interpreters must be the same exact version.
static PyObject *
sys_remote_exec_impl(PyObject *module, int pid, PyObject *script)
-/*[clinic end generated code: output=7d94c56afe4a52c0 input=39908ca2c5fe1eb0]*/
+/*[clinic end generated code: output=7d94c56afe4a52c0 input=7bd58f8da20cb74c]*/
{
PyObject *path;
const char *debugger_script_path;
@@ -2843,7 +2846,8 @@ Sets the global lazy imports mode.
The mode parameter must be one of the following strings:
- "all": All top-level imports become potentially lazy
- "none": All lazy imports are suppressed (even explicitly marked ones)
-- "normal": Only explicitly marked imports (with 'lazy' keyword) are lazy
+- "normal": Only explicitly marked imports (with 'lazy' keyword) are
+ lazy
In addition to the mode, lazy imports can be controlled via the filter
provided to sys.set_lazy_imports_filter
@@ -2852,7 +2856,7 @@ provided to sys.set_lazy_imports_filter
static PyObject *
sys_set_lazy_imports_impl(PyObject *module, PyObject *mode)
-/*[clinic end generated code: output=1ff34ba6c4feaf73 input=f04e70d8bf9fe4f6]*/
+/*[clinic end generated code: output=1ff34ba6c4feaf73 input=cb6df28a51844a31]*/
{
PyImport_LazyImportsMode lazy_mode;
if (!PyUnicode_Check(mode)) {
diff --git a/Tools/clinic/libclinic/function.py b/Tools/clinic/libclinic/function.py
index f981f0bcaf89f0..1c643caea98e3b 100644
--- a/Tools/clinic/libclinic/function.py
+++ b/Tools/clinic/libclinic/function.py
@@ -173,12 +173,12 @@ def docstring_line_width(self) -> int:
Pydoc adds indentation when displaying functions and methods.
To keep the total width of within 80 characters, we use a
- maximum of 76 characters for global functions and classes,
- and 72 characters for methods.
+ maximum of 72 characters for global functions and classes,
+ and 68 characters for methods.
"""
if self.cls is not None and not self.kind.new_or_init:
- return 72
- return 76
+ return 68
+ return 72
def __repr__(self) -> str:
return f''
From c95aa3aeb1a86e8f2e08da8868a0e622790ee98b Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Mon, 25 May 2026 09:05:24 +0200
Subject: [PATCH 138/213] [3.15] gh-149449: Fix use-after-free in
`_PyUnicode_GetNameCAPI` (GH-150323) (#150352)
gh-149449: Fix use-after-free in `_PyUnicode_GetNameCAPI` (GH-150323)
(cherry picked from commit 43c60ec2fddd316a4a6b7b6c68eae7cb66df0850)
Co-authored-by: Pieter Eendebak
Co-authored-by: Kumar Aditya
---
Lib/test/test_unicodedata.py | 16 ++++++++++
...-05-23-22-08-01.gh-issue-149449.2lhQFF.rst | 3 ++
Modules/unicodedata.c | 31 +++++--------------
Tools/c-analyzer/cpython/ignored.tsv | 1 +
4 files changed, 28 insertions(+), 23 deletions(-)
create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-23-22-08-01.gh-issue-149449.2lhQFF.rst
diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py
index 8ecb0df2f8e5dd..060d81415aa1f1 100644
--- a/Lib/test/test_unicodedata.py
+++ b/Lib/test/test_unicodedata.py
@@ -1106,6 +1106,22 @@ def test_failed_import_during_compiling(self):
"(can't load unicodedata module)"
self.assertIn(error, result.err.decode("ascii"))
+ def test_unicodedata_unload_reload(self):
+ # gh-149449: dropping unicodedata and running gc must not leave the
+ # cached _ucnhash_CAPI pointer dangling.
+ code = (
+ "import gc, sys\n"
+ "assert '\\N{GRINNING FACE}'.encode("
+ " 'ascii', errors='namereplace') == b'\\\\N{GRINNING FACE}'\n"
+ "compile(r\"x = '\\\\N{LATIN CAPITAL LETTER A}'\", '', 'exec')\n"
+ "del sys.modules['unicodedata']\n"
+ "gc.collect()\n"
+ "assert '\\N{WINKING FACE}'.encode("
+ " 'ascii', errors='namereplace') == b'\\\\N{WINKING FACE}'\n"
+ "compile(r\"x = '\\\\N{LATIN CAPITAL LETTER B}'\", '', 'exec')\n"
+ )
+ script_helper.assert_python_ok("-c", code)
+
def test_decimal_numeric_consistent(self):
# Test that decimal and numeric are consistent,
# i.e. if a character has a decimal value,
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-23-22-08-01.gh-issue-149449.2lhQFF.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-23-22-08-01.gh-issue-149449.2lhQFF.rst
new file mode 100644
index 00000000000000..7d11442468d207
--- /dev/null
+++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-23-22-08-01.gh-issue-149449.2lhQFF.rst
@@ -0,0 +1,3 @@
+Fix a use-after-free crash when the :mod:`unicodedata` module was removed
+from :data:`sys.modules` and garbage-collected between calls that decode
+``\N{...}`` escapes or use the ``namereplace`` codec error handler.
diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c
index 31ad916b2c5c26..6bb25fc0b63781 100644
--- a/Modules/unicodedata.c
+++ b/Modules/unicodedata.c
@@ -1548,32 +1548,17 @@ capi_getcode(const char* name, int namelen, Py_UCS4* code,
return _check_alias_and_seq(code, with_named_seq);
}
-static void
-unicodedata_destroy_capi(PyObject *capsule)
-{
- void *capi = PyCapsule_GetPointer(capsule, PyUnicodeData_CAPSULE_NAME);
- PyMem_Free(capi);
-}
-
static PyObject *
unicodedata_create_capi(void)
{
- _PyUnicode_Name_CAPI *capi = PyMem_Malloc(sizeof(_PyUnicode_Name_CAPI));
- if (capi == NULL) {
- PyErr_NoMemory();
- return NULL;
- }
- capi->getname = capi_getucname;
- capi->getcode = capi_getcode;
-
- PyObject *capsule = PyCapsule_New(capi,
- PyUnicodeData_CAPSULE_NAME,
- unicodedata_destroy_capi);
- if (capsule == NULL) {
- PyMem_Free(capi);
- }
- return capsule;
-};
+ // Statically allocated so that any cached pointers stay valid after unicodedata
+ // is removed from sys.modules and the capsule is gc'd (gh-149449).
+ static _PyUnicode_Name_CAPI capi = {
+ .getname = capi_getucname,
+ .getcode = capi_getcode,
+ };
+ return PyCapsule_New(&capi, PyUnicodeData_CAPSULE_NAME, NULL);
+}
/* -------------------------------------------------------------------- */
diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv
index ddfb93a424c018..bf08e5568205e7 100644
--- a/Tools/c-analyzer/cpython/ignored.tsv
+++ b/Tools/c-analyzer/cpython/ignored.tsv
@@ -327,6 +327,7 @@ Modules/pyexpat.c - error_info_of -
Modules/pyexpat.c - handler_info -
Modules/termios.c - termios_constants -
Modules/timemodule.c init_timezone YEAR -
+Modules/unicodedata.c unicodedata_create_capi capi -
Objects/bytearrayobject.c - _PyByteArray_empty_string -
Objects/complexobject.c - c_1 -
Objects/exceptions.c - static_exceptions -
From 5292bb45d95dd27e92229d94ab3471264ddf0121 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Mon, 25 May 2026 10:19:05 +0200
Subject: [PATCH 139/213] [3.15] gh-150285: Fix too long docstrings in
_wmi.exec_query (GH-150373) (GH-150377)
(cherry picked from commit fbeafc062e55a52ba7369c36be0b3eb34eabb560)
Co-authored-by: Serhiy Storchaka
---
PC/_wmimodule.cpp | 7 +++----
PC/clinic/_wmimodule.cpp.h | 6 +++---
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/PC/_wmimodule.cpp b/PC/_wmimodule.cpp
index 86df2c7183c30d..b9a229b1398ec8 100644
--- a/PC/_wmimodule.cpp
+++ b/PC/_wmimodule.cpp
@@ -224,20 +224,19 @@ wait_event(HANDLE event, DWORD timeout)
/*[clinic input]
-@permit_long_docstring_body
_wmi.exec_query
query: unicode
Runs a WMI query against the local machine.
-This returns a single string with 'name=value' pairs in a flat array separated
-by null characters.
+This returns a single string with 'name=value' pairs in a flat array
+separated by null characters.
[clinic start generated code]*/
static PyObject *
_wmi_exec_query_impl(PyObject *module, PyObject *query)
-/*[clinic end generated code: output=a62303d5bb5e003f input=621f5c50c56d06d0]*/
+/*[clinic end generated code: output=a62303d5bb5e003f input=a8d5710acdfbf515]*/
/*[clinic end generated code]*/
{
diff --git a/PC/clinic/_wmimodule.cpp.h b/PC/clinic/_wmimodule.cpp.h
index 38d52d0329dcc0..6c18990f056b5f 100644
--- a/PC/clinic/_wmimodule.cpp.h
+++ b/PC/clinic/_wmimodule.cpp.h
@@ -14,8 +14,8 @@ PyDoc_STRVAR(_wmi_exec_query__doc__,
"\n"
"Runs a WMI query against the local machine.\n"
"\n"
-"This returns a single string with \'name=value\' pairs in a flat array separated\n"
-"by null characters.");
+"This returns a single string with \'name=value\' pairs in a flat array\n"
+"separated by null characters.");
#define _WMI_EXEC_QUERY_METHODDEF \
{"exec_query", _PyCFunction_CAST(_wmi_exec_query), METH_FASTCALL|METH_KEYWORDS, _wmi_exec_query__doc__},
@@ -72,4 +72,4 @@ _wmi_exec_query(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj
exit:
return return_value;
}
-/*[clinic end generated code: output=802bcbcba69e8d0e input=a9049054013a1b77]*/
+/*[clinic end generated code: output=f246d0e568cc2d2c input=a9049054013a1b77]*/
From 03244b9f043a31eaa9243d90d01139294155e1f3 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Mon, 25 May 2026 10:19:36 +0200
Subject: [PATCH 140/213] [3.15] gh-150285: Fix too long docstrings in some
Python modules (GH-150366) (GH-150375)
(cherry picked from commit 01c6d3d76bf222d8b847c97e0a3d3fad0c1b1fe3)
Co-authored-by: Serhiy Storchaka
---
Lib/_collections_abc.py | 29 +++++++-----
Lib/enum.py | 25 +++++-----
Lib/functools.py | 12 ++---
Lib/glob.py | 34 +++++++-------
Lib/gzip.py | 65 +++++++++++++-------------
Lib/json/__init__.py | 26 ++++++-----
Lib/ntpath.py | 16 ++++---
Lib/tarfile.py | 33 +++++++------
Lib/test/test_enum.py | 4 +-
Lib/types.py | 25 +++++-----
Lib/xml/etree/ElementTree.py | 89 +++++++++++++++++++++---------------
Lib/zipfile/__init__.py | 47 +++++++++----------
12 files changed, 220 insertions(+), 185 deletions(-)
diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py
index 23cc6d8faae2da..0e1d8ccf44a435 100644
--- a/Lib/_collections_abc.py
+++ b/Lib/_collections_abc.py
@@ -461,8 +461,8 @@ def __subclasshook__(cls, C):
class _CallableGenericAlias(GenericAlias):
""" Represent `Callable[argtypes, resulttype]`.
- This sets ``__args__`` to a tuple containing the flattened ``argtypes``
- followed by ``resulttype``.
+ This sets ``__args__`` to a tuple containing the flattened
+ ``argtypes`` followed by ``resulttype``.
Example: ``Callable[[int, str], float]`` sets ``__args__`` to
``(int, str, float)``.
@@ -928,8 +928,9 @@ def __delitem__(self, key):
__marker = object()
def pop(self, key, default=__marker):
- '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
- If key is not found, d is returned if given, otherwise KeyError is raised.
+ '''D.pop(k[,d]) -> v, remove specified key and return the corresponding
+ value. If key is not found, d is returned if given, otherwise
+ KeyError is raised.
'''
try:
value = self[key]
@@ -963,9 +964,12 @@ def clear(self):
def update(self, other=(), /, **kwds):
''' D.update([E, ]**F) -> None. Update D from mapping/iterable E and F.
- If E present and has a .keys() method, does: for k in E.keys(): D[k] = E[k]
- If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v
- In either case, this is followed by: for k, v in F.items(): D[k] = v
+ If E present and has a .keys() method, does:
+ for k in E.keys(): D[k] = E[k]
+ If E present and lacks .keys() method, does:
+ for (k, v) in E: D[k] = v
+ In either case, this is followed by:
+ for k, v in F.items(): D[k] = v
'''
if isinstance(other, Mapping):
for key in other:
@@ -1030,8 +1034,8 @@ def __reversed__(self):
yield self[i]
def index(self, value, start=0, stop=None):
- '''S.index(value, [start, [stop]]) -> integer -- return first index of value.
- Raises ValueError if the value is not present.
+ '''S.index(value, [start, [stop]]) -> integer -- return first index of
+ value. Raises ValueError if the value is not present.
Supporting start and stop arguments is optional, but
recommended.
@@ -1139,15 +1143,16 @@ def reverse(self):
self[i], self[n-i-1] = self[n-i-1], self[i]
def extend(self, values):
- 'S.extend(iterable) -- extend sequence by appending elements from the iterable'
+ """S.extend(iterable) -- extend sequence by appending elements from the
+ iterable"""
if values is self:
values = list(values)
for v in values:
self.append(v)
def pop(self, index=-1):
- '''S.pop([index]) -> item -- remove and return item at index (default last).
- Raise IndexError if list is empty or index is out of range.
+ '''S.pop([index]) -> item -- remove and return item at index (default
+ last). Raise IndexError if list is empty or index is out of range.
'''
v = self[index]
del self[index]
diff --git a/Lib/enum.py b/Lib/enum.py
index 025e973446d88d..f536a3eae2b6e3 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -702,9 +702,9 @@ def __call__(cls, value, names=_not_given, *values, module=None, qualname=None,
"""
Either returns an existing member, or creates a new enum class.
- This method is used both when an enum class is given a value to match
- to an enumeration member (i.e. Color(3)) and for the functional API
- (i.e. Color = Enum('Color', names='RED GREEN BLUE')).
+ This method is used both when an enum class is given a value to
+ match to an enumeration member (i.e. Color(3)) and for the
+ functional API (i.e. Color = Enum('Color', names='RED GREEN BLUE')).
The value lookup branch is chosen if the enum is final.
@@ -712,16 +712,17 @@ def __call__(cls, value, names=_not_given, *values, module=None, qualname=None,
`value` will be the name of the new class.
- `names` should be either a string of white-space/comma delimited names
- (values will start at `start`), or an iterator/mapping of name, value pairs.
+ `names` should be either a string of white-space/comma delimited
+ names (values will start at `start`), or an iterator/mapping of
+ name, value pairs.
`module` should be set to the module this class is being created in;
- if it is not set, an attempt to find that module will be made, but if
- it fails the class will not be picklable.
+ if it is not set, an attempt to find that module will be made, but
+ if it fails the class will not be picklable.
- `qualname` should be set to the actual location this class can be found
- at in its module; by default it is set to the global scope. If this is
- not correct, unpickling will fail in some circumstances.
+ `qualname` should be set to the actual location this class can be
+ found at in its module; by default it is set to the global scope.
+ If this is not correct, unpickling will fail in some circumstances.
`type`, if set, will be mixed in as the first base class.
"""
@@ -819,8 +820,8 @@ def __members__(cls):
"""
Returns a mapping of member name->value.
- This mapping lists all enum members, including aliases. Note that this
- is a read-only view of the internal mapping.
+ This mapping lists all enum members, including aliases. Note that
+ this is a read-only view of the internal mapping.
"""
return MappingProxyType(cls._member_map_)
diff --git a/Lib/functools.py b/Lib/functools.py
index e03a77f204b544..c5aaa15f3d5e33 100644
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -558,16 +558,16 @@ def lru_cache(maxsize=128, typed=False):
If *maxsize* is set to None, the LRU features are disabled and the cache
can grow without bound.
- If *typed* is True, arguments of different types will be cached separately.
- For example, f(decimal.Decimal("3.0")) and f(3.0) will be treated as
- distinct calls with distinct results. Some types such as str and int may
- be cached separately even when typed is false.
+ If *typed* is True, arguments of different types will be cached
+ separately. For example, f(decimal.Decimal("3.0")) and f(3.0) will be
+ treated as distinct calls with distinct results. Some types such as
+ str and int may be cached separately even when typed is false.
Arguments to the cached function must be hashable.
View the cache statistics named tuple (hits, misses, maxsize, currsize)
- with f.cache_info(). Clear the cache and statistics with f.cache_clear().
- Access the underlying function with f.__wrapped__.
+ with f.cache_info(). Clear the cache and statistics with
+ f.cache_clear(). Access the underlying function with f.__wrapped__.
See: https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)
diff --git a/Lib/glob.py b/Lib/glob.py
index 575e4bcba5be0d..5a8ff46137ba5e 100644
--- a/Lib/glob.py
+++ b/Lib/glob.py
@@ -25,17 +25,17 @@ def glob(pathname, *, root_dir=None, dir_fd=None, recursive=False,
The order of the returned list is undefined. Sort it if you need a
particular order.
- If `root_dir` is not None, it should be a path-like object specifying the
- root directory for searching. It has the same effect as changing the
- current directory before calling it (without actually
- changing it). If pathname is relative, the result will contain
- paths relative to `root_dir`.
+ If `root_dir` is not None, it should be a path-like object specifying
+ the root directory for searching. It has the same effect as changing
+ the current directory before calling it (without actually changing it).
+ If pathname is relative, the result will contain paths relative to
+ `root_dir`.
If `dir_fd` is not None, it should be a file descriptor referring to a
directory, and paths will then be relative to that directory.
- If `include_hidden` is true, the patterns '*', '?', '**' will match hidden
- directories.
+ If `include_hidden` is true, the patterns '*', '?', '**' will match
+ hidden directories.
If `recursive` is true, the pattern '**' will match any files and
zero or more directories and subdirectories.
@@ -56,16 +56,16 @@ def iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False,
particular order.
If `root_dir` is not None, it should be a path-like object specifying
- the root directory for searching. It has the same effect as changing
- the current directory before calling it (without actually
- changing it). If pathname is relative, the result will contain
- paths relative to `root_dir`.
+ the root directory for searching. It has the same effect as changing
+ the current directory before calling it (without actually changing it).
+ If pathname is relative, the result will contain paths relative to
+ `root_dir`.
If `dir_fd` is not None, it should be a file descriptor referring to a
directory, and paths will then be relative to that directory.
- If `include_hidden` is true, the patterns '*', '?', '**' will match hidden
- directories.
+ If `include_hidden` is true, the patterns '*', '?', '**' will match
+ hidden directories.
If `recursive` is true, the pattern '**' will match any files and
zero or more directories and subdirectories.
@@ -279,15 +279,15 @@ def escape(pathname):
def translate(pat, *, recursive=False, include_hidden=False, seps=None):
"""Translate a pathname with shell wildcards to a regular expression.
- If `recursive` is true, the pattern segment '**' will match any number of
- path segments.
+ If `recursive` is true, the pattern segment '**' will match any number
+ of path segments.
If `include_hidden` is true, wildcards can match path segments beginning
with a dot ('.').
If a sequence of separator characters is given to `seps`, they will be
- used to split the pattern into segments and match path separators. If not
- given, os.path.sep and os.path.altsep (where available) are used.
+ used to split the pattern into segments and match path separators. If
+ not given, os.path.sep and os.path.altsep (where available) are used.
"""
if not seps:
if os.path.altsep:
diff --git a/Lib/gzip.py b/Lib/gzip.py
index 0713b922522ee1..c7b4563fdfe991 100644
--- a/Lib/gzip.py
+++ b/Lib/gzip.py
@@ -34,16 +34,16 @@ def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_TRADEOFF,
encoding=None, errors=None, newline=None):
"""Open a gzip-compressed file in binary or text mode.
- The filename argument can be an actual filename (a str or bytes object), or
- an existing file object to read from or write to.
+ The filename argument can be an actual filename (a str or bytes object),
+ or an existing file object to read from or write to.
- The mode argument can be "r", "rb", "w", "wb", "x", "xb", "a" or "ab" for
- binary mode, or "rt", "wt", "xt" or "at" for text mode. The default mode is
- "rb", and the default compresslevel is 9.
+ The mode argument can be "r", "rb", "w", "wb", "x", "xb", "a" or "ab"
+ for binary mode, or "rt", "wt", "xt" or "at" for text mode. The default
+ mode is "rb", and the default compresslevel is 9.
- For binary mode, this function is equivalent to the GzipFile constructor:
- GzipFile(filename, mode, compresslevel). In this case, the encoding, errors
- and newline arguments must not be provided.
+ For binary mode, this function is equivalent to the GzipFile
+ constructor: GzipFile(filename, mode, compresslevel). In this case,
+ the encoding, errors and newline arguments must not be provided.
For text mode, a GzipFile object is created, and wrapped in an
io.TextIOWrapper instance with the specified encoding, error handling
@@ -148,8 +148,8 @@ class GzipFile(_streams.BaseStream):
"""The GzipFile class simulates most of the methods of a file object with
the exception of the truncate() method.
- This class only supports opening files in binary mode. If you need to open a
- compressed file in text mode, use the gzip.open() function.
+ This class only supports opening files in binary mode. If you need to
+ open a compressed file in text mode, use the gzip.open() function.
"""
@@ -165,33 +165,34 @@ def __init__(self, filename=None, mode=None,
non-trivial value.
The new class instance is based on fileobj, which can be a regular
- file, an io.BytesIO object, or any other object which simulates a file.
- It defaults to None, in which case filename is opened to provide
- a file object.
+ file, an io.BytesIO object, or any other object which simulates
+ a file. It defaults to None, in which case filename is opened to
+ provide a file object.
When fileobj is not None, the filename argument is only used to be
included in the gzip file header, which may include the original
filename of the uncompressed file. It defaults to the filename of
fileobj, if discernible; otherwise, it defaults to the empty string,
- and in this case the original filename is not included in the header.
-
- The mode argument can be any of 'r', 'rb', 'a', 'ab', 'w', 'wb', 'x', or
- 'xb' depending on whether the file will be read or written. The default
- is the mode of fileobj if discernible; otherwise, the default is 'rb'.
- A mode of 'r' is equivalent to one of 'rb', and similarly for 'w' and
- 'wb', 'a' and 'ab', and 'x' and 'xb'.
-
- The compresslevel argument is an integer from 0 to 9 controlling the
- level of compression; 1 is fastest and produces the least compression,
- and 9 is slowest and produces the most compression. 0 is no compression
- at all. The default is 9.
-
- The optional mtime argument is the timestamp requested by gzip. The time
- is in Unix format, i.e., seconds since 00:00:00 UTC, January 1, 1970.
- Set mtime to 0 to generate a compressed stream that does not depend on
- creation time. If mtime is omitted or None, the current time is used.
- If the resulting mtime is outside the range 0 to 2**32-1, then the
- value 0 is used instead.
+ and in this case the original filename is not included in the
+ header.
+
+ The mode argument can be any of 'r', 'rb', 'a', 'ab', 'w', 'wb',
+ 'x', or 'xb' depending on whether the file will be read or written.
+ The default is the mode of fileobj if discernible; otherwise, the
+ default is 'rb'. A mode of 'r' is equivalent to one of 'rb', and
+ similarly for 'w' and 'wb', 'a' and 'ab', and 'x' and 'xb'.
+
+ The compresslevel argument is an integer from 0 to 9 controlling
+ the level of compression; 1 is fastest and produces the least
+ compression, and 9 is slowest and produces the most compression.
+ 0 is no compression at all. The default is 9.
+
+ The optional mtime argument is the timestamp requested by gzip.
+ The time is in Unix format, i.e., seconds since 00:00:00 UTC,
+ January 1, 1970. Set mtime to 0 to generate a compressed stream
+ that does not depend on creation time. If mtime is omitted or None,
+ the current time is used. If the resulting mtime is outside the
+ range 0 to 2**32-1, then the value 0 is used instead.
"""
diff --git a/Lib/json/__init__.py b/Lib/json/__init__.py
index 94c177cafa0294..9681a8fe53ec48 100644
--- a/Lib/json/__init__.py
+++ b/Lib/json/__init__.py
@@ -292,12 +292,13 @@ def load(fp, *, cls=None, object_hook=None, parse_float=None,
``object_hook`` is also defined, the ``object_pairs_hook`` takes
priority.
- ``array_hook`` is an optional function that will be called with the result
- of any literal array decode (a ``list``). The return value of this function will
- be used instead of the ``list``. This feature can be used along
- ``object_pairs_hook`` to customize the resulting data structure - for example,
- by setting that to ``frozendict`` and ``array_hook`` to ``tuple``, one can get
- a deep immutable data structute from any JSON data.
+ ``array_hook`` is an optional function that will be called with the
+ result of any literal array decode (a ``list``). The return value of
+ this function will be used instead of the ``list``. This feature can
+ be used along ``object_pairs_hook`` to customize the resulting data
+ structure - for example, by setting that to ``frozendict`` and
+ ``array_hook`` to ``tuple``, one can get a deep immutable data structure
+ from any JSON data.
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
kwarg; otherwise ``JSONDecoder`` is used.
@@ -327,12 +328,13 @@ def loads(s, *, cls=None, object_hook=None, parse_float=None,
``object_hook`` is also defined, the ``object_pairs_hook`` takes
priority.
- ``array_hook`` is an optional function that will be called with the result
- of any literal array decode (a ``list``). The return value of this function will
- be used instead of the ``list``. This feature can be used along
- ``object_pairs_hook`` to customize the resulting data structure - for example,
- by setting that to ``frozendict`` and ``array_hook`` to ``tuple``, one can get
- a deep immutable data structute from any JSON data.
+ ``array_hook`` is an optional function that will be called with the
+ result of any literal array decode (a ``list``). The return value of
+ this function will be used instead of the ``list``. This feature can
+ be used along ``object_pairs_hook`` to customize the resulting data
+ structure - for example, by setting that to ``frozendict`` and
+ ``array_hook`` to ``tuple``, one can get a deep immutable data structure
+ from any JSON data.
``parse_float``, if specified, will be called with the string
of every JSON float to be decoded. By default this is equivalent to
diff --git a/Lib/ntpath.py b/Lib/ntpath.py
index 7d637325240f1c..811e796f7766e9 100644
--- a/Lib/ntpath.py
+++ b/Lib/ntpath.py
@@ -152,12 +152,14 @@ def splitdrive(p, /):
It is always true that:
result[0] + result[1] == p
- If the path contained a drive letter, drive_or_unc will contain everything
- up to and including the colon. e.g. splitdrive("c:/dir") returns ("c:", "/dir")
+ If the path contained a drive letter, drive_or_unc will contain
+ everything up to and including the colon. e.g. splitdrive("c:/dir")
+ returns ("c:", "/dir")
- If the path contained a UNC path, the drive_or_unc will contain the host name
- and share up to but not including the fourth directory separator character.
- e.g. splitdrive("//host/computer/dir") returns ("//host/computer", "/dir")
+ If the path contained a UNC path, the drive_or_unc will contain the
+ host name and share up to but not including the fourth directory
+ separator character. e.g. splitdrive("//host/computer/dir") returns
+ ("//host/computer", "/dir")
Paths cannot contain both a drive letter and a UNC path.
@@ -222,8 +224,8 @@ def splitroot(p, /):
def split(p, /):
"""Split a pathname.
- Return tuple (head, tail) where tail is everything after the final slash.
- Either part may be empty."""
+ Return tuple (head, tail) where tail is everything after the final
+ slash. Either part may be empty."""
p = os.fspath(p)
seps = _get_bothseps(p)
d, r, p = splitroot(p)
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index 5e43b4c19c0a8a..5bf2ede090100a 100644
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -899,11 +899,14 @@ class TarInfo(object):
size = 'Size in bytes.',
mtime = 'Time of last modification.',
chksum = 'Header checksum.',
- type = ('File type. type is usually one of these constants: '
- 'REGTYPE, AREGTYPE, LNKTYPE, SYMTYPE, DIRTYPE, FIFOTYPE, '
- 'CONTTYPE, CHRTYPE, BLKTYPE, GNUTYPE_SPARSE.'),
+ type = ('File type. type is usually one of these constants: '
+ 'REGTYPE,\n'
+ 'AREGTYPE, LNKTYPE, SYMTYPE, DIRTYPE, FIFOTYPE, '
+ 'CONTTYPE, CHRTYPE,\n'
+ 'BLKTYPE, GNUTYPE_SPARSE.'),
linkname = ('Name of the target file name, which is only present '
- 'in TarInfo objects of type LNKTYPE and SYMTYPE.'),
+ 'in TarInfo\n'
+ 'objects of type LNKTYPE and SYMTYPE.'),
uname = 'User name.',
gname = 'Group name.',
devmajor = 'Device major number.',
@@ -911,7 +914,8 @@ class TarInfo(object):
offset = 'The tar header starts here.',
offset_data = "The file's data starts here.",
pax_headers = ('A dictionary containing key-value pairs of an '
- 'associated pax extended header.'),
+ 'associated pax\n'
+ 'extended header.'),
sparse = 'Sparse member information.',
_tarfile = None,
_sparse_structs = None,
@@ -2275,10 +2279,11 @@ def gettarinfo(self, name=None, arcname=None, fileobj=None):
return tarinfo
def list(self, verbose=True, *, members=None):
- """Print a table of contents to sys.stdout. If 'verbose' is False, only
- the names of the members are printed. If it is True, an 'ls -l'-like
- output is produced. 'members' is optional and must be a subset of the
- list returned by getmembers().
+ """Print a table of contents to sys.stdout.
+
+ If 'verbose' is False, only the names of the members are printed.
+ If it is True, an 'ls -l'-like output is produced. 'members' is
+ optional and must be a subset of the list returned by getmembers().
"""
# Convert tarinfo type to stat type.
type2mode = {REGTYPE: stat.S_IFREG, SYMTYPE: stat.S_IFLNK,
@@ -2369,10 +2374,12 @@ def add(self, name, arcname=None, recursive=True, *, filter=None):
self.addfile(tarinfo)
def addfile(self, tarinfo, fileobj=None):
- """Add the TarInfo object 'tarinfo' to the archive. If 'tarinfo' represents
- a non zero-size regular file, the 'fileobj' argument should be a binary file,
- and tarinfo.size bytes are read from it and added to the archive.
- You can create TarInfo objects directly, or by using gettarinfo().
+ """Add the TarInfo object 'tarinfo' to the archive.
+
+ If 'tarinfo' represents a non zero-size regular file, the 'fileobj'
+ argument should be a binary file, and tarinfo.size bytes are read
+ from it and added to the archive. You can create TarInfo objects
+ directly, or by using gettarinfo().
"""
self._check("awx")
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index 779457119e8f0e..e0dcc6b8a519e7 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -5021,8 +5021,8 @@ class Color(enum.Enum)
| __members__
| Returns a mapping of member name->value.
|
- | This mapping lists all enum members, including aliases. Note that this
- | is a read-only view of the internal mapping."""
+ | This mapping lists all enum members, including aliases. Note that
+ | this is a read-only view of the internal mapping."""
expected_help_output_without_docs = """\
Help on class Color in module %s:
diff --git a/Lib/types.py b/Lib/types.py
index b4f9a5c5140860..6c069591ab26ef 100644
--- a/Lib/types.py
+++ b/Lib/types.py
@@ -195,18 +195,19 @@ class Baz(list[str]): ...
class DynamicClassAttribute:
"""Route attribute access on a class to __getattr__.
- This is a descriptor, used to define attributes that act differently when
- accessed through an instance and through a class. Instance access remains
- normal, but access to an attribute through a class will be routed to the
- class's __getattr__ method; this is done by raising AttributeError.
-
- This allows one to have properties active on an instance, and have virtual
- attributes on the class with the same name. (Enum used this between Python
- versions 3.4 - 3.9 .)
-
- Subclass from this to use a different method of accessing virtual attributes
- and still be treated properly by the inspect module. (Enum uses this since
- Python 3.10 .)
+ This is a descriptor, used to define attributes that act differently
+ when accessed through an instance and through a class. Instance access
+ remains normal, but access to an attribute through a class will be
+ routed to the class's __getattr__ method; this is done by raising
+ AttributeError.
+
+ This allows one to have properties active on an instance, and have
+ virtual attributes on the class with the same name. (Enum used this
+ between Python versions 3.4 - 3.9 .)
+
+ Subclass from this to use a different method of accessing virtual
+ attributes and still be treated properly by the inspect module. (Enum
+ uses this since Python 3.10 .)
"""
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py
index 85766e02b531ce..75bebc0b1668ab 100644
--- a/Lib/xml/etree/ElementTree.py
+++ b/Lib/xml/etree/ElementTree.py
@@ -8,8 +8,8 @@
2. Element represents a single node in this tree.
Interactions with the whole document (reading and writing to/from files) are
- usually done on the ElementTree level. Interactions with a single XML element
- and its sub-elements are done on the Element level.
+ usually done on the ElementTree level. Interactions with a single XML
+ element and its sub-elements are done on the Element level.
Element is a flexible container object designed to store hierarchical data
structures in memory. It can be described as a cross between a list and a
@@ -277,7 +277,8 @@ def find(self, path, namespaces=None):
"""Find first matching element by tag name or path.
*path* is a string having either an element tag or an XPath,
- *namespaces* is an optional mapping from namespace prefix to full name.
+ *namespaces* is an optional mapping from namespace prefix to full
+ name.
Return the first matching element, or None if no element was found.
@@ -289,7 +290,8 @@ def findtext(self, path, default=None, namespaces=None):
*path* is a string having either an element tag or an XPath,
*default* is the value to return if the element was not found,
- *namespaces* is an optional mapping from namespace prefix to full name.
+ *namespaces* is an optional mapping from namespace prefix to full
+ name.
Return text content of first matching element, or default value if
none was found. Note that if an element is found having no text
@@ -302,7 +304,8 @@ def findall(self, path, namespaces=None):
"""Find all matching subelements by tag name or path.
*path* is a string having either an element tag or an XPath,
- *namespaces* is an optional mapping from namespace prefix to full name.
+ *namespaces* is an optional mapping from namespace prefix to full
+ name.
Returns list containing all matching elements in document order.
@@ -313,7 +316,8 @@ def iterfind(self, path, namespaces=None):
"""Find all matching subelements by tag name or path.
*path* is a string having either an element tag or an XPath,
- *namespaces* is an optional mapping from namespace prefix to full name.
+ *namespaces* is an optional mapping from namespace prefix to full
+ name.
Return an iterable yielding all matching elements in document order.
@@ -553,8 +557,8 @@ def _setroot(self, element):
def parse(self, source, parser=None):
"""Load external XML document into element tree.
- *source* is a file name or file object, *parser* is an optional parser
- instance that defaults to XMLParser.
+ *source* is a file name or file object, *parser* is an optional
+ parser instance that defaults to XMLParser.
ParseError is raised if the parser fails to parse the document.
@@ -587,7 +591,8 @@ def parse(self, source, parser=None):
def iter(self, tag=None):
"""Create and return tree iterator for the root element.
- The iterator loops over all elements in this tree, in document order.
+ The iterator loops over all elements in this tree, in document
+ order.
*tag* is a string with the tag name to iterate over
(default is to return all elements).
@@ -602,7 +607,8 @@ def find(self, path, namespaces=None):
Same as getroot().find(path), which is Element.find()
*path* is a string having either an element tag or an XPath,
- *namespaces* is an optional mapping from namespace prefix to full name.
+ *namespaces* is an optional mapping from namespace prefix to full
+ name.
Return the first matching element, or None if no element was found.
@@ -624,7 +630,8 @@ def findtext(self, path, default=None, namespaces=None):
Same as getroot().findtext(path), which is Element.findtext()
*path* is a string having either an element tag or an XPath,
- *namespaces* is an optional mapping from namespace prefix to full name.
+ *namespaces* is an optional mapping from namespace prefix to full
+ name.
Return the first matching element, or None if no element was found.
@@ -646,7 +653,8 @@ def findall(self, path, namespaces=None):
Same as getroot().findall(path), which is Element.findall().
*path* is a string having either an element tag or an XPath,
- *namespaces* is an optional mapping from namespace prefix to full name.
+ *namespaces* is an optional mapping from namespace prefix to full
+ name.
Return list containing all matching elements in document order.
@@ -693,24 +701,26 @@ def write(self, file_or_filename,
"""Write element tree to a file as XML.
Arguments:
- *file_or_filename* -- file name or a file object opened for writing
+ *file_or_filename* -- file name or a file object opened for
+ writing
*encoding* -- the output encoding (default: US-ASCII)
- *xml_declaration* -- bool indicating if an XML declaration should be
- added to the output. If None, an XML declaration
- is added if encoding IS NOT either of:
- US-ASCII, UTF-8, or Unicode
+ *xml_declaration* -- bool indicating if an XML declaration should
+ be added to the output. If None, an XML
+ declaration is added if encoding IS NOT
+ either of: US-ASCII, UTF-8, or Unicode
- *default_namespace* -- sets the default XML namespace (for "xmlns")
+ *default_namespace* -- sets the default XML namespace (for
+ "xmlns")
*method* -- either "xml" (default), "html, "text", or "c14n"
*short_empty_elements* -- controls the formatting of elements
- that contain no content. If True (default)
- they are emitted as a single self-closed
- tag, otherwise they are emitted as a pair
- of start/end tags
+ that contain no content. If True
+ (default) they are emitted as a single
+ self-closed tag, otherwise they are
+ emitted as a pair of start/end tags
"""
if self._root is None:
@@ -1083,9 +1093,9 @@ def tostring(element, encoding=None, method=None, *,
is returned. Otherwise a bytestring is returned.
*element* is an Element instance, *encoding* is an optional output
- encoding defaulting to US-ASCII, *method* is an optional output which can
- be one of "xml" (default), "html", "text" or "c14n", *default_namespace*
- sets the default XML namespace (for "xmlns").
+ encoding defaulting to US-ASCII, *method* is an optional output which
+ can be one of "xml" (default), "html", "text" or "c14n",
+ *default_namespace* sets the default XML namespace (for "xmlns").
Returns an (optionally) encoded string containing the XML data.
@@ -1225,7 +1235,8 @@ def iterparse(source, events=None, parser=None):
"end" events are reported.
*source* is a filename or file object containing XML data, *events* is
- a list of events to report back, *parser* is an optional parser instance.
+ a list of events to report back, *parser* is an optional parser
+ instance.
Returns an iterator providing (event, elem) pairs.
@@ -1761,10 +1772,11 @@ def flush(self):
def canonicalize(xml_data=None, *, out=None, from_file=None, **options):
"""Convert XML to its C14N 2.0 serialised form.
- If *out* is provided, it must be a file or file-like object that receives
- the serialised canonical XML output (text, not bytes) through its ``.write()``
- method. To write to a file, open it in text mode with encoding "utf-8".
- If *out* is not provided, this function returns the output as text string.
+ If *out* is provided, it must be a file or file-like object that
+ receives the serialised canonical XML output (text, not bytes) through
+ its ``.write()`` method. To write to a file, open it in text mode with
+ encoding "utf-8". If *out* is not provided, this function returns the
+ output as text string.
Either *xml_data* (an XML string) or *from_file* (a file path or
file-like object) must be provided as input.
@@ -1798,19 +1810,22 @@ class C14NWriterTarget:
Serialises parse events to XML C14N 2.0.
The *write* function is used for writing out the resulting data stream
- as text (not bytes). To write to a file, open it in text mode with encoding
- "utf-8" and pass its ``.write`` method.
+ as text (not bytes). To write to a file, open it in text mode with
+ encoding "utf-8" and pass its ``.write`` method.
Configuration options:
- *with_comments*: set to true to include comments
- - *strip_text*: set to true to strip whitespace before and after text content
- - *rewrite_prefixes*: set to true to replace namespace prefixes by "n{number}"
+ - *strip_text*: set to true to strip whitespace before and after text
+ content
+ - *rewrite_prefixes*: set to true to replace namespace prefixes by
+ "n{number}"
- *qname_aware_tags*: a set of qname aware tag names in which prefixes
should be replaced in text content
- - *qname_aware_attrs*: a set of qname aware attribute names in which prefixes
- should be replaced in text content
- - *exclude_attrs*: a set of attribute names that should not be serialised
+ - *qname_aware_attrs*: a set of qname aware attribute names in which
+ prefixes should be replaced in text content
+ - *exclude_attrs*: a set of attribute names that should not be
+ serialised
- *exclude_tags*: a set of tag names that should not be serialised
"""
def __init__(self, write, *,
diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py
index c5c6ac03fb7b8c..d91cb509a6ff4f 100644
--- a/Lib/zipfile/__init__.py
+++ b/Lib/zipfile/__init__.py
@@ -620,11 +620,12 @@ def _decodeExtra(self, filename_crc):
def from_file(cls, filename, arcname=None, *, strict_timestamps=True):
"""Construct an appropriate ZipInfo for a file on the filesystem.
- filename should be the path to a file or directory on the filesystem.
+ filename should be the path to a file or directory on the
+ filesystem.
- arcname is the name which it will have within the archive (by default,
- this will be the same as filename, but without a drive letter and with
- leading path separators removed).
+ arcname is the name which it will have within the archive (by
+ default, this will be the same as filename, but without a drive
+ letter and with leading path separators removed).
"""
if isinstance(filename, os.PathLike):
filename = os.fspath(filename)
@@ -1395,19 +1396,19 @@ class ZipFile:
mode: The mode can be either read 'r', write 'w', exclusive create 'x',
or append 'a'.
compression: ZIP_STORED (no compression), ZIP_DEFLATED (requires zlib),
- ZIP_BZIP2 (requires bz2), ZIP_LZMA (requires lzma), or
- ZIP_ZSTANDARD (requires compression.zstd).
- allowZip64: if True ZipFile will create files with ZIP64 extensions when
- needed, otherwise it will raise an exception when this would
- be necessary.
- compresslevel: None (default for the given compression type) or an integer
- specifying the level to pass to the compressor.
- When using ZIP_STORED or ZIP_LZMA this keyword has no effect.
- When using ZIP_DEFLATED integers 0 through 9 are accepted.
- When using ZIP_BZIP2 integers 1 through 9 are accepted.
- When using ZIP_ZSTANDARD integers -7 though 22 are common,
- see the CompressionParameter enum in compression.zstd for
- details.
+ ZIP_BZIP2 (requires bz2), ZIP_LZMA (requires lzma), or
+ ZIP_ZSTANDARD (requires compression.zstd).
+ allowZip64: if True ZipFile will create files with ZIP64 extensions
+ when needed, otherwise it will raise an exception when this
+ would be necessary.
+ compresslevel: None (default for the given compression type) or
+ an integer specifying the level to pass to the compressor.
+ When using ZIP_STORED or ZIP_LZMA this keyword has no effect.
+ When using ZIP_DEFLATED integers 0 through 9 are accepted.
+ When using ZIP_BZIP2 integers 1 through 9 are accepted.
+ When using ZIP_ZSTANDARD integers -7 though 22 are common,
+ see the CompressionParameter enum in compression.zstd for
+ details.
"""
@@ -1417,8 +1418,8 @@ class ZipFile:
def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True,
compresslevel=None, *, strict_timestamps=True, metadata_encoding=None):
- """Open the ZIP file with mode read 'r', write 'w', exclusive create 'x',
- or append 'a'."""
+ """Open the ZIP file with mode read 'r', write 'w', exclusive create
+ 'x', or append 'a'."""
if mode not in ('r', 'w', 'x', 'a'):
raise ValueError("ZipFile requires mode 'r', 'w', 'x', or 'a'")
@@ -1696,10 +1697,10 @@ def open(self, name, mode="r", pwd=None, *, force_zip64=False):
pwd is the password to decrypt files (only used for reading).
- When writing, if the file size is not known in advance but may exceed
- 2 GiB, pass force_zip64 to use the ZIP64 format, which can handle large
- files. If the size is known in advance, it is best to pass a ZipInfo
- instance for name, with zinfo.file_size set.
+ When writing, if the file size is not known in advance but may
+ exceed 2 GiB, pass force_zip64 to use the ZIP64 format, which can
+ handle large files. If the size is known in advance, it is best to
+ pass a ZipInfo instance for name, with zinfo.file_size set.
"""
if mode not in {"r", "w"}:
raise ValueError('open() requires mode "r" or "w"')
From acd402ecdb7d04d8730d2d10352fa22823b0bd1c Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Mon, 25 May 2026 11:36:22 +0200
Subject: [PATCH 141/213] [3.15] gh-150374: Fix double release of import lock
in lazy import reification (GH-150376) (#150378)
gh-150374: Fix double release of import lock in lazy import reification (GH-150376)
(cherry picked from commit 5498eba545e950c7550c924f2e458c740a689c69)
Co-authored-by: pengyu lee
---
.../2026-05-25-16-00-22.gh-issue-150374.Emu6d8.rst | 1 +
Python/import.c | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-25-16-00-22.gh-issue-150374.Emu6d8.rst
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-25-16-00-22.gh-issue-150374.Emu6d8.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-25-16-00-22.gh-issue-150374.Emu6d8.rst
new file mode 100644
index 00000000000000..7189ca186d2b7e
--- /dev/null
+++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-25-16-00-22.gh-issue-150374.Emu6d8.rst
@@ -0,0 +1 @@
+Fix double release of the import lock on lazy import reification errors.
diff --git a/Python/import.c b/Python/import.c
index aa4ee660fa75da..fc1b3f1acbe063 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -3934,7 +3934,6 @@ _PyImport_LoadLazyImportTstate(PyThreadState *tstate, PyObject *lazy_import)
return NULL;
}
else if (PySet_Add(importing, lazy_import) < 0) {
- _PyImport_ReleaseLock(interp);
goto error;
}
From 28037c2d11be131588efcd22c17c6bafa824cc8d Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Mon, 25 May 2026 12:13:01 +0200
Subject: [PATCH 142/213] [3.15] gh-145896: Fix typos and stale docstrings in
the traceback module (GH-145897) (GH-150383)
(cherry picked from commit 832afeddcea78e40d39c47cd1893f8137e588e72)
Co-authored-by: devdanzin <74280297+devdanzin@users.noreply.github.com>
---
Doc/library/traceback.rst | 10 ++++------
Lib/traceback.py | 19 +++++++++----------
2 files changed, 13 insertions(+), 16 deletions(-)
diff --git a/Doc/library/traceback.rst b/Doc/library/traceback.rst
index b5464ac55ddfa9..aa48cea357cfd3 100644
--- a/Doc/library/traceback.rst
+++ b/Doc/library/traceback.rst
@@ -147,9 +147,7 @@ Module-Level Functions
:ref:`traceback object ` *tb*. It is useful
for alternate formatting of stack traces. The optional *limit* argument has
the same meaning as for :func:`print_tb`. A "pre-processed" stack trace
- entry is a :class:`FrameSummary` object containing attributes
- :attr:`~FrameSummary.filename`, :attr:`~FrameSummary.lineno`,
- :attr:`~FrameSummary.name`, and :attr:`~FrameSummary.line` representing the
+ entry is a :class:`FrameSummary` object with attributes representing the
information that is usually printed for a stack trace.
@@ -181,7 +179,7 @@ Module-Level Functions
.. function:: format_exception_only(exc, /[, value], *, show_group=False)
Format the exception part of a traceback using an exception value such as
- given by :data:`sys.last_value`. The return value is a list of strings, each
+ given by :data:`sys.last_exc`. The return value is a list of strings, each
ending in a newline. The list contains the exception's message, which is
normally a single string; however, for :exc:`SyntaxError` exceptions, it
contains several lines that (when printed) display detailed information
@@ -347,7 +345,7 @@ the module-level functions described above.
.. attribute:: exc_type
- The class of the original traceback.
+ The class of the original exception.
.. deprecated:: 3.13
@@ -391,7 +389,7 @@ the module-level functions described above.
For syntax errors - the compiler error message.
- .. classmethod:: from_exception(exc, *, limit=None, lookup_lines=True, capture_locals=False)
+ .. classmethod:: from_exception(exc, *, limit=None, lookup_lines=True, capture_locals=False, compact=False, max_group_width=15, max_group_depth=10)
Capture an exception for later rendering. *limit*, *lookup_lines* and
*capture_locals* are as for the :class:`StackSummary` class.
diff --git a/Lib/traceback.py b/Lib/traceback.py
index 88529e1c259a29..d16ab468db9962 100644
--- a/Lib/traceback.py
+++ b/Lib/traceback.py
@@ -115,10 +115,10 @@ def extract_tb(tb, limit=None):
This is useful for alternate formatting of stack traces. If
'limit' is omitted or None, all entries are extracted. A
pre-processed stack trace entry is a FrameSummary object
- containing attributes filename, lineno, name, and line
- representing the information that is usually printed for a stack
- trace. The line is a string with leading and trailing
- whitespace stripped; if the source is not available it is None.
+ representing the information that is usually printed for a
+ stack trace. The line attribute is a string with
+ leading and trailing whitespace stripped; if the source is not
+ available the corresponding attribute is None.
"""
return StackSummary._extract_from_extended_frame_gen(
_walk_tb_with_full_positions(tb), limit=limit)
@@ -295,9 +295,8 @@ def extract_stack(f=None, limit=None):
The return value has the same format as for extract_tb(). The
optional 'f' and 'limit' arguments have the same meaning as for
- print_stack(). Each item in the list is a quadruple (filename,
- line number, function name, text), and the entries are in order
- from oldest to newest stack frame.
+ print_stack(). Each item in the list is a FrameSummary object,
+ and the entries are in order from oldest to newest stack frame.
"""
if f is None:
f = sys._getframe().f_back
@@ -325,7 +324,7 @@ class FrameSummary:
active when the frame was captured.
- :attr:`name` The name of the function or method that was executing
when the frame was captured.
- - :attr:`line` The text from the linecache module for the
+ - :attr:`line` The text from the linecache module for the line
of code that was running when the frame was captured.
- :attr:`locals` Either None if locals were not supplied, or a dict
mapping the name to the repr() of the variable.
@@ -1053,7 +1052,7 @@ def _wlen(s: str) -> int:
def _display_width(line, offset=None):
- """Calculate the extra amount of width space the given source
+ """Calculate the amount of width space the given source
code segment might take if it were to be displayed on a fixed
width output device. Supports wide unicode characters and emojis."""
@@ -1134,7 +1133,7 @@ class TracebackException:
def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None,
lookup_lines=True, capture_locals=False, compact=False,
max_group_width=15, max_group_depth=10, save_exc_type=True, _seen=None):
- # NB: we need to accept exc_traceback, exc_value, exc_traceback to
+ # NB: we need to accept exc_type, exc_value, exc_traceback to
# permit backwards compat with the existing API, otherwise we
# need stub thunk objects just to glue it together.
# Handle loops in __cause__ or __context__.
From e2362aac3470a23ea048384024ec16f2bf866a6b Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Mon, 25 May 2026 20:19:22 +0200
Subject: [PATCH 143/213] [3.15] gh-149156: Fix perf trampoline crash after
fork (GH-150347) (#150394)
---
...26-05-24-14-45-00.gh-issue-149156.NP73rB.rst | 3 +++
Python/perf_trampoline.c | 17 ++++++++++++-----
2 files changed, 15 insertions(+), 5 deletions(-)
create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-24-14-45-00.gh-issue-149156.NP73rB.rst
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-24-14-45-00.gh-issue-149156.NP73rB.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-24-14-45-00.gh-issue-149156.NP73rB.rst
new file mode 100644
index 00000000000000..2cb091e2b162f6
--- /dev/null
+++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-24-14-45-00.gh-issue-149156.NP73rB.rst
@@ -0,0 +1,3 @@
+Fix an intermittent crash after :func:`os.fork` when perf trampoline
+profiling is enabled and the child returns through trampoline frames
+inherited from the parent process.
diff --git a/Python/perf_trampoline.c b/Python/perf_trampoline.c
index 58c61e64bfc4e9..d90b789c2b5712 100644
--- a/Python/perf_trampoline.c
+++ b/Python/perf_trampoline.c
@@ -210,9 +210,8 @@ enum perf_trampoline_type {
static void free_code_arenas(void);
static void
-perf_trampoline_reset_state(void)
+perf_trampoline_clear_code_watcher(void)
{
- free_code_arenas();
if (code_watcher_id >= 0) {
PyCode_ClearWatcher(code_watcher_id);
code_watcher_id = -1;
@@ -220,6 +219,13 @@ perf_trampoline_reset_state(void)
extra_code_index = -1;
}
+static void
+perf_trampoline_reset_state(void)
+{
+ free_code_arenas();
+ perf_trampoline_clear_code_watcher();
+}
+
static int
perf_trampoline_code_watcher(PyCodeEvent event, PyCodeObject *co)
{
@@ -621,9 +627,10 @@ _PyPerfTrampoline_AfterFork_Child(void)
// After fork, Fini may leave the old code watcher registered
// if trampolined code objects from the parent still exist
// (trampoline_refcount > 0). Clear it unconditionally before
- // Init registers a new one, to prevent two watchers sharing
- // the same globals and double-decrementing trampoline_refcount.
- perf_trampoline_reset_state();
+ // Init registers a new one, but keep the old arenas mapped: the
+ // child may still need to return through trampoline frames that
+ // were on the C stack at fork().
+ perf_trampoline_clear_code_watcher();
_PyPerfTrampoline_Init(1);
}
}
From 4bdff2cc89dad8f3fa63b98dd12ba22a8b3eb6e0 Mon Sep 17 00:00:00 2001
From: Serhiy Storchaka
Date: Mon, 25 May 2026 21:43:23 +0300
Subject: [PATCH 144/213] [3.15] gh-80198: Improve test_pwd and test_grp
(GH-150380) (GH-150398)
Fix tests for non-existing names and ids when getpwall()/getgrall()
don't return all users/groups.
Add tests for out-of-range uids, integer float ids, bytes names,
null-terminated names, names with surrogates, empty names, excessive
arguments.
(cherry picked from commit 46e8f7a9e794bfb0fdc5ee82348623eb2b91a0b5)
---
Lib/test/test_grp.py | 90 +++++++++++++++++++-----------------------
Lib/test/test_pwd.py | 94 ++++++++++++++++++++++----------------------
2 files changed, 88 insertions(+), 96 deletions(-)
diff --git a/Lib/test/test_grp.py b/Lib/test/test_grp.py
index e52e17b8dc7366..ed86802f069e0f 100644
--- a/Lib/test/test_grp.py
+++ b/Lib/test/test_grp.py
@@ -1,5 +1,7 @@
"""Test script for the grp module."""
+import random
+import string
import unittest
from test.support import import_helper
@@ -50,61 +52,51 @@ def test_values_extended(self):
def test_errors(self):
self.assertRaises(TypeError, grp.getgrgid)
self.assertRaises(TypeError, grp.getgrgid, 3.14)
+ self.assertRaises(TypeError, grp.getgrgid, 0.0)
+ self.assertRaises(TypeError, grp.getgrgid, 0, 0)
+ # should be out of gid_t range
+ self.assertRaises(OverflowError, grp.getgrgid, 2**128)
+ self.assertRaises(OverflowError, grp.getgrgid, -2**128)
self.assertRaises(TypeError, grp.getgrnam)
self.assertRaises(TypeError, grp.getgrnam, 42)
- self.assertRaises(TypeError, grp.getgrall, 42)
+ self.assertRaises(TypeError, grp.getgrnam, b'root')
+ self.assertRaises(TypeError, grp.getgrnam, 'root', 0)
# embedded null character
self.assertRaisesRegex(ValueError, 'null', grp.getgrnam, 'a\x00b')
+ self.assertRaisesRegex(ValueError, 'null', grp.getgrnam, 'root\x00')
+ self.assertRaises(UnicodeEncodeError, grp.getgrnam, 'roo\udc74')
+ self.assertRaises(KeyError, grp.getgrnam, '')
+ self.assertRaises(TypeError, grp.getgrall, 42)
- # try to get some errors
- bynames = {}
- bygids = {}
- for (n, p, g, mem) in grp.getgrall():
- if not n or n == '+':
- continue # skip NIS entries etc.
- bynames[n] = g
- bygids[g] = n
-
- allnames = list(bynames.keys())
- namei = 0
- fakename = allnames[namei]
- while fakename in bynames:
- chars = list(fakename)
- for i in range(len(chars)):
- if chars[i] == 'z':
- chars[i] = 'A'
- break
- elif chars[i] == 'Z':
- continue
+ # Find a non-existent group name.
+ # getgrall() will not necessarily report all existing groups
+ # (typical for LDAP based directories in big organizations).
+ for _ in range(30):
+ fakename = ''.join(random.choices(string.ascii_lowercase, k=6))
+ try:
+ grp.getgrnam(fakename)
+ except KeyError:
+ break
+ else:
+ self.fail('Cannot find non-existent group name')
+
+ # Find a non-existent gid.
+ maxgid = 2**31
+ for _ in range(30):
+ fakegid = random.randrange(maxgid)
+ try:
+ grp.getgrgid(fakegid)
+ except KeyError:
+ break
+ except OverflowError:
+ if maxgid == 2**31:
+ maxgid = 2**16-1
+ elif maxgid == 2**16-1:
+ maxgid = 2**15
else:
- chars[i] = chr(ord(chars[i]) + 1)
- break
- else:
- namei = namei + 1
- try:
- fakename = allnames[namei]
- except IndexError:
- # should never happen... if so, just forget it
- break
- fakename = ''.join(chars)
-
- self.assertRaises(KeyError, grp.getgrnam, fakename)
-
- # Choose a non-existent gid.
- fakegid = 4127
- while fakegid in bygids:
- fakegid = (fakegid * 3) % 0x10000
-
- self.assertRaises(KeyError, grp.getgrgid, fakegid)
-
- def test_noninteger_gid(self):
- entries = grp.getgrall()
- if not entries:
- self.skipTest('no groups')
- # Choose an existent gid.
- gid = entries[0][2]
- self.assertRaises(TypeError, grp.getgrgid, float(gid))
- self.assertRaises(TypeError, grp.getgrgid, str(gid))
+ raise
+ else:
+ self.fail('Cannot find non-existent gid')
if __name__ == "__main__":
diff --git a/Lib/test/test_pwd.py b/Lib/test/test_pwd.py
index aa090b464a7222..bdf57776c82be1 100644
--- a/Lib/test/test_pwd.py
+++ b/Lib/test/test_pwd.py
@@ -1,3 +1,5 @@
+import random
+import string
import sys
import unittest
from test.support import import_helper
@@ -56,59 +58,57 @@ def test_values_extended(self):
def test_errors(self):
self.assertRaises(TypeError, pwd.getpwuid)
self.assertRaises(TypeError, pwd.getpwuid, 3.14)
+ self.assertRaises(TypeError, pwd.getpwuid, 0.0)
+ self.assertRaises(TypeError, pwd.getpwuid, 0, 0)
+ # should be out of uid_t range
+ self.assertRaises(KeyError, pwd.getpwuid, 2**128)
+ self.assertRaises(KeyError, pwd.getpwuid, -2**128)
self.assertRaises(TypeError, pwd.getpwnam)
self.assertRaises(TypeError, pwd.getpwnam, 42)
- self.assertRaises(TypeError, pwd.getpwall, 42)
+ self.assertRaises(TypeError, pwd.getpwnam, b'root')
+ self.assertRaises(TypeError, pwd.getpwnam, 'root', 0)
# embedded null character
self.assertRaisesRegex(ValueError, 'null', pwd.getpwnam, 'a\x00b')
+ self.assertRaisesRegex(ValueError, 'null', pwd.getpwnam, 'root\x00')
+ self.assertRaises(UnicodeEncodeError, pwd.getpwnam, 'roo\udc74')
+ self.assertRaises(KeyError, pwd.getpwnam, '')
+ self.assertRaises(TypeError, pwd.getpwall, 42)
- # try to get some errors
- bynames = {}
- byuids = {}
- for (n, p, u, g, gecos, d, s) in pwd.getpwall():
- bynames[n] = u
- byuids[u] = n
-
- allnames = list(bynames.keys())
- namei = 0
- fakename = allnames[namei] if allnames else "invaliduser"
- while fakename in bynames:
- chars = list(fakename)
- for i in range(len(chars)):
- if chars[i] == 'z':
- chars[i] = 'A'
- break
- elif chars[i] == 'Z':
- continue
- else:
- chars[i] = chr(ord(chars[i]) + 1)
- break
- else:
- namei = namei + 1
- try:
- fakename = allnames[namei]
- except IndexError:
- # should never happen... if so, just forget it
- break
- fakename = ''.join(chars)
-
- self.assertRaises(KeyError, pwd.getpwnam, fakename)
-
- # In some cases, byuids isn't a complete list of all users in the
- # system, so if we try to pick a value not in byuids (via a perturbing
- # loop, say), pwd.getpwuid() might still be able to find data for that
- # uid. Using sys.maxint may provoke the same problems, but hopefully
- # it will be a more repeatable failure.
- fakeuid = sys.maxsize
- self.assertNotIn(fakeuid, byuids)
- self.assertRaises(KeyError, pwd.getpwuid, fakeuid)
+ # Find a non-existent user name.
+ # getpwall() will not necessarily report all existing users
+ # (typical for LDAP based directories in big organizations).
+ for _ in range(30):
+ fakename = ''.join(random.choices(string.ascii_lowercase, k=6))
+ try:
+ pwd.getpwnam(fakename)
+ except KeyError:
+ break
+ else:
+ self.fail('Cannot find non-existent user name')
+
+ # Find a non-existent uid.
+ maxuid = max(e.pw_uid for e in pwd.getpwall())
+ if maxuid < 2**15:
+ maxuid = 2**15
+ elif maxuid < 2**16:
+ maxuid = 2**16-1
+ else:
+ maxuid = 2**31
+ for _ in range(30):
+ fakeuid = random.randrange(maxuid)
+ try:
+ pwd.getpwuid(fakeuid)
+ except KeyError:
+ break
+ else:
+ self.fail('Cannot find non-existent uid')
+
+ # On Cygwin, getpwuid(-1) returns 'Unknown+User' user
+ if sys.platform != 'cygwin':
+ # -1 shouldn't be a valid uid because it has a special meaning in many
+ # uid-related functions
+ self.assertRaises(KeyError, pwd.getpwuid, -1)
- # -1 shouldn't be a valid uid because it has a special meaning in many
- # uid-related functions
- self.assertRaises(KeyError, pwd.getpwuid, -1)
- # should be out of uid_t range
- self.assertRaises(KeyError, pwd.getpwuid, 2**128)
- self.assertRaises(KeyError, pwd.getpwuid, -2**128)
if __name__ == "__main__":
unittest.main()
From d23b06b2a8becc6619e3112468f8c94500d7e470 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Mon, 25 May 2026 20:46:19 +0200
Subject: [PATCH 145/213] [3.15] gh-150387: Fix hang in
test_run_failed_script_live on slow buildbots (GH-150405) (#150420)
---
.../test_sampling_profiler/test_live_collector_ui.py | 3 +--
.../Tests/2026-05-25-15-39-53.gh-issue-150387.yzZ7jq.rst | 5 +++++
2 files changed, 6 insertions(+), 2 deletions(-)
create mode 100644 Misc/NEWS.d/next/Tests/2026-05-25-15-39-53.gh-issue-150387.yzZ7jq.rst
diff --git a/Lib/test/test_profiling/test_sampling_profiler/test_live_collector_ui.py b/Lib/test/test_profiling/test_sampling_profiler/test_live_collector_ui.py
index c0d39f487c8cbd..59373a8d00c03c 100644
--- a/Lib/test/test_profiling/test_sampling_profiler/test_live_collector_ui.py
+++ b/Lib/test/test_profiling/test_sampling_profiler/test_live_collector_ui.py
@@ -835,8 +835,7 @@ def mock_init_curses_side_effect(self, n_times, mock_self, stdscr):
# still failing
for _ in range(n_times):
mock_self.display.simulate_input(-1)
- if n_times >= 500:
- mock_self.display.simulate_input(ord('q'))
+ mock_self.display.simulate_input(ord('q'))
def test_run_failed_module_live(self):
"""Test that running a existing module that fails exits with clean error."""
diff --git a/Misc/NEWS.d/next/Tests/2026-05-25-15-39-53.gh-issue-150387.yzZ7jq.rst b/Misc/NEWS.d/next/Tests/2026-05-25-15-39-53.gh-issue-150387.yzZ7jq.rst
new file mode 100644
index 00000000000000..663a357a179204
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2026-05-25-15-39-53.gh-issue-150387.yzZ7jq.rst
@@ -0,0 +1,5 @@
+Fix hang in
+``test.test_profiling.test_sampling_profiler.test_live_collector_ui.TestLiveModeErrors.test_run_failed_script_live``
+on slow buildbots. The test now always queues a final ``q`` keystroke so the
+live TUI loop exits even when the profiler collects enough samples to enter
+the post-finished input loop.
From d5381e18b85c6781e4961e5d98e2ef23781f654c Mon Sep 17 00:00:00 2001
From: Pablo Galindo Salgado
Date: Tue, 26 May 2026 00:02:37 +0100
Subject: [PATCH 146/213] [3.15] gh-149619: Harden _remote_debugging error
paths (GH-150349) (#150435)
(cherry picked from commit a5be25d3bdc1b3cbc9638a3249c0e3db5a97ebc6)
---
.../test_binary_format.py | 41 ++
Modules/_remote_debugging/_remote_debugging.h | 2 +-
Modules/_remote_debugging/asyncio.c | 41 +-
Modules/_remote_debugging/binary_io_reader.c | 72 +++-
Modules/_remote_debugging/binary_io_writer.c | 42 +-
Modules/_remote_debugging/code_objects.c | 2 -
Modules/_remote_debugging/module.c | 3 +
Modules/_remote_debugging/object_reading.c | 58 +--
Modules/_remote_debugging/subprocess.c | 51 ++-
Modules/_remote_debugging/threads.c | 91 ++--
Python/remote_debug.h | 390 +++++++++++++-----
11 files changed, 597 insertions(+), 196 deletions(-)
diff --git a/Lib/test/test_profiling/test_sampling_profiler/test_binary_format.py b/Lib/test/test_profiling/test_sampling_profiler/test_binary_format.py
index 1fbb4e2d6c6fbb..5efc60a9211175 100644
--- a/Lib/test/test_profiling/test_sampling_profiler/test_binary_format.py
+++ b/Lib/test/test_profiling/test_sampling_profiler/test_binary_format.py
@@ -975,7 +975,11 @@ def test_writer_total_samples_after_close_returns_zero(self):
class TestBinaryFormatValidation(BinaryFormatTestBase):
"""Tests for malformed binary files."""
+ HDR_OFF_SAMPLES = 28
HDR_OFF_THREADS = 32
+ HDR_OFF_STR_TABLE = 36
+ HDR_OFF_FRAME_TABLE = 44
+ FILE_HEADER_PLACEHOLDER_SIZE = 64
def test_replay_rejects_more_threads_than_declared(self):
"""Replay rejects files with more unique threads than the header declares."""
@@ -1000,6 +1004,43 @@ def test_replay_rejects_more_threads_than_declared(self):
"threads than declared in header (declared 1, found at least 2)",
)
+ def test_replay_rejects_sample_count_mismatch(self):
+ """Replay rejects files whose decoded samples disagree with the header."""
+ samples = [[make_interpreter(0, [
+ make_thread(1, [make_frame("sample.py", 10, "sample")])
+ ])]]
+ filename = self.create_binary_file(samples, compression="none")
+
+ with open(filename, "r+b") as raw:
+ raw.seek(self.HDR_OFF_SAMPLES)
+ raw.write(struct.pack("=I", 2))
+
+ with BinaryReader(filename) as reader:
+ self.assertEqual(reader.get_info()["sample_count"], 2)
+ with self.assertRaises(ValueError) as cm:
+ reader.replay_samples(RawCollector())
+ self.assertEqual(
+ str(cm.exception),
+ "Sample count mismatch: header declares 2 samples "
+ "but replay decoded 1",
+ )
+
+ def test_replay_rejects_trailing_partial_sample_header(self):
+ """Replay rejects partial sample bytes instead of silently stopping."""
+ filename = self.create_binary_file([], compression="none")
+ sample_data_end = self.FILE_HEADER_PLACEHOLDER_SIZE + 1
+
+ with open(filename, "r+b") as raw:
+ raw.seek(self.HDR_OFF_STR_TABLE)
+ raw.write(struct.pack("=Q", sample_data_end))
+ raw.seek(self.HDR_OFF_FRAME_TABLE)
+ raw.write(struct.pack("=Q", sample_data_end))
+
+ with BinaryReader(filename) as reader:
+ with self.assertRaises(ValueError) as cm:
+ reader.replay_samples(RawCollector())
+ self.assertEqual(str(cm.exception), "Truncated sample data: 1 trailing bytes")
+
class TestBinaryEncodings(BinaryFormatTestBase):
"""Tests specifically targeting different stack encodings."""
diff --git a/Modules/_remote_debugging/_remote_debugging.h b/Modules/_remote_debugging/_remote_debugging.h
index d91ce54a18c813..635e6e208902af 100644
--- a/Modules/_remote_debugging/_remote_debugging.h
+++ b/Modules/_remote_debugging/_remote_debugging.h
@@ -180,7 +180,7 @@ typedef enum _WIN32_THREADSTATE {
#define set_exception_cause(unwinder, exc_type, message) \
do { \
assert(PyErr_Occurred() && "function returned -1 without setting exception"); \
- if (unwinder->debug) { \
+ if (unwinder->debug && !_Py_RemoteDebug_HasPermissionError()) { \
_set_debug_exception_cause(exc_type, message); \
} \
} while (0)
diff --git a/Modules/_remote_debugging/asyncio.c b/Modules/_remote_debugging/asyncio.c
index fc7487d4044bfb..44a9a3cbce0061 100644
--- a/Modules/_remote_debugging/asyncio.c
+++ b/Modules/_remote_debugging/asyncio.c
@@ -22,35 +22,38 @@ _Py_RemoteDebug_GetAsyncioDebugAddress(proc_handle_t* handle)
address = search_windows_map_for_section(handle, "AsyncioD", L"_asyncio",
NULL);
if (address == 0) {
- // Error out: 'python' substring covers both executable and DLL
- PyObject *exc = PyErr_GetRaisedException();
- PyErr_SetString(PyExc_RuntimeError, "Failed to find the AsyncioDebug section in the process.");
- _PyErr_ChainExceptions1(exc);
+ if (!_Py_RemoteDebug_HasPermissionError()) {
+ PyObject *exc = PyErr_GetRaisedException();
+ PyErr_SetString(PyExc_RuntimeError, "Failed to find the AsyncioDebug section in the process.");
+ _PyErr_ChainExceptions1(exc);
+ }
}
#elif defined(__linux__) && HAVE_PROCESS_VM_READV
// On Linux, search for asyncio debug in executable or DLL
address = search_linux_map_for_section(handle, "AsyncioDebug", "python",
NULL);
if (address == 0) {
- // Error out: 'python' substring covers both executable and DLL
- PyObject *exc = PyErr_GetRaisedException();
- PyErr_SetString(PyExc_RuntimeError, "Failed to find the AsyncioDebug section in the process.");
- _PyErr_ChainExceptions1(exc);
+ if (!_Py_RemoteDebug_HasPermissionError()) {
+ PyObject *exc = PyErr_GetRaisedException();
+ PyErr_SetString(PyExc_RuntimeError, "Failed to find the AsyncioDebug section in the process.");
+ _PyErr_ChainExceptions1(exc);
+ }
}
#elif defined(__APPLE__) && TARGET_OS_OSX
// On macOS, try libpython first, then fall back to python
address = search_map_for_section(handle, "AsyncioDebug", "libpython",
NULL);
- if (address == 0) {
+ if (address == 0 && !_Py_RemoteDebug_HasPermissionError()) {
PyErr_Clear();
address = search_map_for_section(handle, "AsyncioDebug", "python",
NULL);
}
if (address == 0) {
- // Error out: 'python' substring covers both executable and DLL
- PyObject *exc = PyErr_GetRaisedException();
- PyErr_SetString(PyExc_RuntimeError, "Failed to find the AsyncioDebug section in the process.");
- _PyErr_ChainExceptions1(exc);
+ if (!_Py_RemoteDebug_HasPermissionError()) {
+ PyObject *exc = PyErr_GetRaisedException();
+ PyErr_SetString(PyExc_RuntimeError, "Failed to find the AsyncioDebug section in the process.");
+ _PyErr_ChainExceptions1(exc);
+ }
}
#else
Py_UNREACHABLE();
@@ -96,10 +99,12 @@ ensure_async_debug_offsets(RemoteUnwinderObject *unwinder)
return -1;
}
if (result < 0) {
- PyErr_Clear();
- PyErr_SetString(PyExc_RuntimeError, "AsyncioDebug section not available");
- set_exception_cause(unwinder, PyExc_RuntimeError,
- "AsyncioDebug section unavailable - asyncio module may not be loaded in target process");
+ if (!_Py_RemoteDebug_HasPermissionError()) {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_RuntimeError, "AsyncioDebug section not available");
+ set_exception_cause(unwinder, PyExc_RuntimeError,
+ "AsyncioDebug section unavailable - asyncio module may not be loaded in target process");
+ }
return -1;
}
@@ -218,7 +223,7 @@ parse_task_name(
if ((GET_MEMBER(unsigned long, type_obj, unwinder->debug_offsets.type_object.tp_flags) & Py_TPFLAGS_LONG_SUBCLASS)) {
long res = read_py_long(unwinder, task_name_addr);
- if (res == -1) {
+ if (res == -1 && PyErr_Occurred()) {
set_exception_cause(unwinder, PyExc_RuntimeError, "Task name PyLong parsing failed");
return NULL;
}
diff --git a/Modules/_remote_debugging/binary_io_reader.c b/Modules/_remote_debugging/binary_io_reader.c
index 972b197cfbad86..ce1c3d232c94e0 100644
--- a/Modules/_remote_debugging/binary_io_reader.c
+++ b/Modules/_remote_debugging/binary_io_reader.c
@@ -380,7 +380,22 @@ binary_reader_open(PyObject *path)
Py_fclose(fp);
goto error;
}
+ if (st.st_size < 0) {
+ PyErr_SetString(PyExc_IOError, "Invalid negative file size");
+ Py_fclose(fp);
+ goto error;
+ }
+ if ((uintmax_t)st.st_size > SIZE_MAX) {
+ PyErr_SetString(PyExc_OverflowError, "File is too large to map");
+ Py_fclose(fp);
+ goto error;
+ }
reader->mapped_size = st.st_size;
+ if (reader->mapped_size == 0) {
+ PyErr_SetString(PyExc_ValueError, "File too small for header");
+ Py_fclose(fp);
+ goto error;
+ }
/* Map the file into memory.
* MAP_POPULATE (Linux-only) pre-faults all pages at mmap time, which:
@@ -424,7 +439,10 @@ binary_reader_open(PyObject *path)
}
#endif
- (void)Py_fclose(fp);
+ if (Py_fclose(fp) != 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ goto error;
+ }
uint8_t *data = reader->mapped_data;
size_t file_size = reader->mapped_size;
@@ -444,7 +462,15 @@ binary_reader_open(PyObject *path)
PyErr_SetFromErrno(PyExc_IOError);
goto error;
}
+ if ((uint64_t)file_size_off > SIZE_MAX) {
+ PyErr_SetString(PyExc_OverflowError, "File is too large to read");
+ goto error;
+ }
reader->file_size = (size_t)file_size_off;
+ if (reader->file_size == 0) {
+ PyErr_SetString(PyExc_ValueError, "File too small for header");
+ goto error;
+ }
if (FSEEK64(reader->fp, 0, SEEK_SET) != 0) {
PyErr_SetFromErrno(PyExc_IOError);
goto error;
@@ -456,8 +482,18 @@ binary_reader_open(PyObject *path)
goto error;
}
- if (fread(reader->file_data, 1, reader->file_size, reader->fp) != reader->file_size) {
- PyErr_SetFromErrno(PyExc_IOError);
+ size_t nread = fread(reader->file_data, 1, reader->file_size, reader->fp);
+ if (nread != reader->file_size) {
+ int err = errno;
+ if (ferror(reader->fp) && err != 0) {
+ errno = err;
+ PyErr_SetFromErrno(PyExc_IOError);
+ }
+ else {
+ PyErr_Format(PyExc_ValueError,
+ "Unexpected end of file: read %zu of %zu bytes",
+ nread, reader->file_size);
+ }
goto error;
}
@@ -944,10 +980,16 @@ invoke_progress_callback(PyObject *callback, Py_ssize_t current, uint32_t total)
Py_ssize_t
binary_reader_replay(BinaryReader *reader, PyObject *collector, PyObject *progress_callback)
{
- if (!PyObject_HasAttrString(collector, "collect")) {
+ PyObject *collect_method;
+ int has_collect = PyObject_GetOptionalAttrString(collector, "collect", &collect_method);
+ if (has_collect < 0) {
+ return -1;
+ }
+ if (has_collect == 0) {
PyErr_SetString(PyExc_TypeError, "Collector must have a collect() method");
return -1;
}
+ Py_DECREF(collect_method);
/* Get module state for struct sequence types */
PyObject *module = PyImport_ImportModule("_remote_debugging");
@@ -973,7 +1015,10 @@ binary_reader_replay(BinaryReader *reader, PyObject *collector, PyObject *progre
while (offset < reader->sample_data_size) {
/* Read thread_id (8 bytes) + interpreter_id (4 bytes) + encoding byte */
if (reader->sample_data_size - offset < SAMPLE_HEADER_FIXED_SIZE) {
- break; /* End of data */
+ PyErr_Format(PyExc_ValueError,
+ "Truncated sample data: %zu trailing bytes",
+ reader->sample_data_size - offset);
+ return -1;
}
/* Use memcpy to avoid strict aliasing violations, then byte-swap if needed */
@@ -1019,6 +1064,11 @@ binary_reader_replay(BinaryReader *reader, PyObject *collector, PyObject *progre
count, max_possible_samples);
return -1;
}
+ if ((uint64_t)count > (uint64_t)PY_SSIZE_T_MAX - (uint64_t)replayed) {
+ PyErr_SetString(PyExc_OverflowError,
+ "Sample count exceeds Py_ssize_t maximum");
+ return -1;
+ }
reader->stats.repeat_records++;
reader->stats.repeat_samples += count;
@@ -1149,6 +1199,11 @@ binary_reader_replay(BinaryReader *reader, PyObject *collector, PyObject *progre
return -1;
}
Py_DECREF(timestamps_list);
+ if (replayed == PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "Sample count exceeds Py_ssize_t maximum");
+ return -1;
+ }
replayed++;
reader->stats.total_samples++;
break;
@@ -1167,6 +1222,13 @@ binary_reader_replay(BinaryReader *reader, PyObject *collector, PyObject *progre
}
}
+ if ((uint64_t)replayed != reader->sample_count) {
+ PyErr_Format(PyExc_ValueError,
+ "Sample count mismatch: header declares %u samples but replay decoded %zd",
+ reader->sample_count, replayed);
+ return -1;
+ }
+
/* Final progress callback at 100% */
if (invoke_progress_callback(progress_callback, replayed, reader->sample_count) < 0) {
return -1;
diff --git a/Modules/_remote_debugging/binary_io_writer.c b/Modules/_remote_debugging/binary_io_writer.c
index c31ed7d746466f..341f9f7dc8ac45 100644
--- a/Modules/_remote_debugging/binary_io_writer.c
+++ b/Modules/_remote_debugging/binary_io_writer.c
@@ -108,7 +108,15 @@ fwrite_checked_allow_threads(const void *data, size_t size, FILE *fp)
written = fwrite(data, 1, size, fp);
Py_END_ALLOW_THREADS
if (written != size) {
- PyErr_SetFromErrno(PyExc_IOError);
+ int err = errno;
+ if (ferror(fp) && err != 0) {
+ errno = err;
+ PyErr_SetFromErrno(PyExc_IOError);
+ }
+ else {
+ PyErr_Format(PyExc_IOError,
+ "short write: wrote %zu of %zu bytes", written, size);
+ }
return -1;
}
return 0;
@@ -366,6 +374,11 @@ writer_intern_string(BinaryWriter *writer, PyObject *string, uint32_t *index)
return 0;
}
+ if (writer->string_count >= UINT32_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "too many strings for binary format");
+ return -1;
+ }
if (writer->string_count >= writer->string_capacity) {
if (grow_parallel_arrays((void **)&writer->strings,
(void **)&writer->string_lengths,
@@ -380,6 +393,12 @@ writer_intern_string(BinaryWriter *writer, PyObject *string, uint32_t *index)
if (!str_data) {
return -1;
}
+ if ((uintmax_t)str_len > UINT32_MAX) {
+ PyErr_Format(PyExc_OverflowError,
+ "string length %zd exceeds binary format maximum %u",
+ str_len, UINT32_MAX);
+ return -1;
+ }
char *str_copy = PyMem_Malloc(str_len + 1);
if (!str_copy) {
@@ -422,6 +441,11 @@ writer_intern_frame(BinaryWriter *writer, const FrameEntry *entry, uint32_t *ind
return 0;
}
+ if (writer->frame_count >= UINT32_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "too many frames for binary format");
+ return -1;
+ }
if (GROW_ARRAY(writer->frame_entries, writer->frame_count,
writer->frame_capacity, FrameEntry) < 0) {
return -1;
@@ -466,6 +490,11 @@ writer_get_or_create_thread_entry(BinaryWriter *writer, uint64_t thread_id,
}
}
+ if (writer->thread_count >= UINT32_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "too many threads for binary format");
+ return NULL;
+ }
if (writer->thread_count >= writer->thread_capacity) {
ThreadEntry *new_entries = grow_array(writer->thread_entries,
&writer->thread_capacity,
@@ -600,6 +629,11 @@ flush_pending_rle(BinaryWriter *writer, ThreadEntry *entry)
if (!entry->has_pending_rle || entry->pending_rle_count == 0) {
return 0;
}
+ if (entry->pending_rle_count > UINT32_MAX - writer->total_samples) {
+ PyErr_SetString(PyExc_OverflowError,
+ "too many samples for binary format");
+ return -1;
+ }
/* Write RLE record:
* [thread_id: 8] [interpreter_id: 4] [STACK_REPEAT: 1] [count: varint]
@@ -644,6 +678,12 @@ write_sample_with_encoding(BinaryWriter *writer, ThreadEntry *entry,
const uint32_t *frame_indices, size_t stack_depth,
size_t shared_count, size_t pop_count, size_t push_count)
{
+ if (writer->total_samples == UINT32_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "too many samples for binary format");
+ return -1;
+ }
+
/* Header: thread_id(8) + interpreter_id(4) + encoding(1) + delta(varint) + status(1) */
uint8_t header_buf[SAMPLE_HEADER_MAX_SIZE];
memcpy(header_buf + SMP_OFF_THREAD_ID, &entry->thread_id, SMP_SIZE_THREAD_ID);
diff --git a/Modules/_remote_debugging/code_objects.c b/Modules/_remote_debugging/code_objects.c
index 3af58f2b3c379e..ab889a130ee4e7 100644
--- a/Modules/_remote_debugging/code_objects.c
+++ b/Modules/_remote_debugging/code_objects.c
@@ -47,7 +47,6 @@ cache_tlbc_array(RemoteUnwinderObject *unwinder, uintptr_t code_addr, uintptr_t
// Read the TLBC array pointer
if (read_ptr(unwinder, tlbc_array_addr, &tlbc_array_ptr) != 0) {
- PyErr_SetString(PyExc_RuntimeError, "Failed to read TLBC array pointer");
set_exception_cause(unwinder, PyExc_RuntimeError, "Failed to read TLBC array pointer");
return 0; // Read error
}
@@ -61,7 +60,6 @@ cache_tlbc_array(RemoteUnwinderObject *unwinder, uintptr_t code_addr, uintptr_t
// Read the TLBC array size
Py_ssize_t tlbc_size;
if (_Py_RemoteDebug_PagedReadRemoteMemory(&unwinder->handle, tlbc_array_ptr, sizeof(tlbc_size), &tlbc_size) != 0) {
- PyErr_SetString(PyExc_RuntimeError, "Failed to read TLBC array size");
set_exception_cause(unwinder, PyExc_RuntimeError, "Failed to read TLBC array size");
return 0; // Read error
}
diff --git a/Modules/_remote_debugging/module.c b/Modules/_remote_debugging/module.c
index 3e60a7c2f794ad..984213d1881752 100644
--- a/Modules/_remote_debugging/module.c
+++ b/Modules/_remote_debugging/module.c
@@ -411,6 +411,9 @@ _remote_debugging_RemoteUnwinder___init___impl(RemoteUnwinderObject *self,
return -1;
}
if (async_debug_result < 0) {
+ if (_Py_RemoteDebug_HasPermissionError()) {
+ return -1;
+ }
PyErr_Clear();
memset(&self->async_debug_offsets, 0, sizeof(self->async_debug_offsets));
self->async_debug_offsets_available = 0;
diff --git a/Modules/_remote_debugging/object_reading.c b/Modules/_remote_debugging/object_reading.c
index b63b103a2617ac..1cea96a2151fcc 100644
--- a/Modules/_remote_debugging/object_reading.c
+++ b/Modules/_remote_debugging/object_reading.c
@@ -6,6 +6,7 @@
******************************************************************************/
#include "_remote_debugging.h"
+#include
/* ============================================================================
* MEMORY READING FUNCTIONS
@@ -264,26 +265,16 @@ read_py_long(
Py_ssize_t inline_digits_space = SIZEOF_LONG_OBJ - ob_digit_offset;
Py_ssize_t max_inline_digits = inline_digits_space / (Py_ssize_t)sizeof(digit);
- // If the long object has inline digits that fit in our buffer, use them directly
- digit *digits;
+ digit *digits = (digit *)PyMem_RawMalloc(size * sizeof(digit));
+ if (!digits) {
+ PyErr_NoMemory();
+ set_exception_cause(unwinder, PyExc_MemoryError, "Failed to allocate digits for PyLong");
+ return -1;
+ }
+
if (size <= max_inline_digits && size <= _PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS) {
- // For small integers, digits are inline in the long_value.ob_digit array
- digits = (digit *)PyMem_RawMalloc(size * sizeof(digit));
- if (!digits) {
- PyErr_NoMemory();
- set_exception_cause(unwinder, PyExc_MemoryError, "Failed to allocate digits for small PyLong");
- return -1;
- }
memcpy(digits, long_obj + ob_digit_offset, size * sizeof(digit));
} else {
- // For larger integers, we need to read the digits separately
- digits = (digit *)PyMem_RawMalloc(size * sizeof(digit));
- if (!digits) {
- PyErr_NoMemory();
- set_exception_cause(unwinder, PyExc_MemoryError, "Failed to allocate digits for large PyLong");
- return -1;
- }
-
bytes_read = _Py_RemoteDebug_PagedReadRemoteMemory(
&unwinder->handle,
address + (uintptr_t)unwinder->debug_offsets.long_object.ob_digit,
@@ -296,19 +287,34 @@ read_py_long(
}
}
- long long value = 0;
+ unsigned long limit = negative
+ ? (unsigned long)LONG_MAX + 1UL
+ : (unsigned long)LONG_MAX;
+ unsigned long value = 0;
- // In theory this can overflow, but because of llvm/llvm-project#16778
- // we can't use __builtin_mul_overflow because it fails to link with
- // __muloti4 on aarch64. In practice this is fine because all we're
- // testing here are task numbers that would fit in a single byte.
- for (Py_ssize_t i = 0; i < size; ++i) {
- long long factor = digits[i] * (1UL << (Py_ssize_t)(shift * i));
- value += factor;
+ for (Py_ssize_t i = size; i-- > 0;) {
+ if (digits[i] >= PyLong_BASE) {
+ PyErr_Format(PyExc_RuntimeError,
+ "Invalid PyLong digit: %u (base %u)", digits[i], PyLong_BASE);
+ set_exception_cause(unwinder, PyExc_RuntimeError,
+ "Invalid PyLong digit (corrupted remote memory)");
+ goto error;
+ }
+ if (value > ((limit - (unsigned long)digits[i]) >> shift)) {
+ PyErr_SetString(PyExc_OverflowError,
+ "Remote PyLong value does not fit in C long");
+ set_exception_cause(unwinder, PyExc_OverflowError,
+ "Remote PyLong value is too large");
+ goto error;
+ }
+ value = (value << shift) | (unsigned long)digits[i];
}
PyMem_RawFree(digits);
if (negative) {
- value *= -1;
+ if (value == (unsigned long)LONG_MAX + 1UL) {
+ return LONG_MIN;
+ }
+ return -(long)value;
}
return (long)value;
error:
diff --git a/Modules/_remote_debugging/subprocess.c b/Modules/_remote_debugging/subprocess.c
index 1b16dd8343f2a5..cdad75e318be91 100644
--- a/Modules/_remote_debugging/subprocess.c
+++ b/Modules/_remote_debugging/subprocess.c
@@ -223,8 +223,19 @@ get_child_pids_platform(pid_t target_pid, int recursive, pid_array_t *result)
}
/* Single pass: collect PIDs and their PPIDs together */
- struct dirent *entry;
- while ((entry = readdir(proc_dir)) != NULL) {
+ for (;;) {
+ errno = 0;
+ struct dirent *entry = readdir(proc_dir);
+ if (entry == NULL) {
+ if (errno != 0) {
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, "/proc",
+ "Failed to read process directory '/proc': %s",
+ strerror(err));
+ goto done;
+ }
+ break;
+ }
/* Skip non-numeric entries (also skips . and ..) */
if (entry->d_name[0] < '1' || entry->d_name[0] > '9') {
continue;
@@ -245,7 +256,14 @@ get_child_pids_platform(pid_t target_pid, int recursive, pid_array_t *result)
}
}
- closedir(proc_dir);
+ if (closedir(proc_dir) != 0) {
+ int err = errno;
+ proc_dir = NULL;
+ _set_debug_oserror_from_errno_with_filename(err, "/proc",
+ "Failed to close process directory '/proc': %s",
+ strerror(err));
+ goto done;
+ }
proc_dir = NULL;
if (find_children_bfs(target_pid, recursive,
@@ -358,7 +376,8 @@ get_child_pids_platform(pid_t target_pid, int recursive, pid_array_t *result)
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot == INVALID_HANDLE_VALUE) {
- PyErr_SetFromWindowsErr(0);
+ DWORD error = GetLastError();
+ PyErr_SetFromWindowsErr(error);
goto done;
}
@@ -373,13 +392,23 @@ get_child_pids_platform(pid_t target_pid, int recursive, pid_array_t *result)
/* Single pass: collect PIDs and PPIDs together */
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
- if (Process32First(snapshot, &pe)) {
- do {
- if (pid_array_append(&all_pids, (pid_t)pe.th32ProcessID) < 0 ||
- pid_array_append(&ppids, (pid_t)pe.th32ParentProcessID) < 0) {
- goto done;
- }
- } while (Process32Next(snapshot, &pe));
+ if (!Process32First(snapshot, &pe)) {
+ DWORD error = GetLastError();
+ PyErr_SetFromWindowsErr(error);
+ goto done;
+ }
+
+ do {
+ if (pid_array_append(&all_pids, (pid_t)pe.th32ProcessID) < 0 ||
+ pid_array_append(&ppids, (pid_t)pe.th32ParentProcessID) < 0) {
+ goto done;
+ }
+ } while (Process32Next(snapshot, &pe));
+
+ DWORD error = GetLastError();
+ if (error != ERROR_NO_MORE_FILES) {
+ PyErr_SetFromWindowsErr(error);
+ goto done;
}
CloseHandle(snapshot);
diff --git a/Modules/_remote_debugging/threads.c b/Modules/_remote_debugging/threads.c
index ae120a26d5f4ec..5176c4cf0671bb 100644
--- a/Modules/_remote_debugging/threads.c
+++ b/Modules/_remote_debugging/threads.c
@@ -658,8 +658,7 @@ read_thread_ids(RemoteUnwinderObject *unwinder, _Py_RemoteDebug_ThreadsState *st
DIR *dir = opendir(task_path);
if (dir == NULL) {
- st->tids = NULL;
- st->count = 0;
+ _Py_RemoteDebug_InitThreadsState(unwinder, st);
if (errno == ENOENT || errno == ESRCH) {
PyErr_Format(PyExc_ProcessLookupError,
"Process %d has terminated", unwinder->handle.pid);
@@ -671,8 +670,21 @@ read_thread_ids(RemoteUnwinderObject *unwinder, _Py_RemoteDebug_ThreadsState *st
st->count = 0;
- struct dirent *entry;
- while ((entry = readdir(dir)) != NULL) {
+ for (;;) {
+ errno = 0;
+ struct dirent *entry = readdir(dir);
+ if (entry == NULL) {
+ if (errno != 0) {
+ int err = errno;
+ closedir(dir);
+ _Py_RemoteDebug_InitThreadsState(unwinder, st);
+ _set_debug_oserror_from_errno_with_filename(err, task_path,
+ "Failed to read process task directory '%s': %s",
+ task_path, strerror(err));
+ return -1;
+ }
+ break;
+ }
if (entry->d_name[0] < '1' || entry->d_name[0] > '9') {
continue;
}
@@ -686,8 +698,7 @@ read_thread_ids(RemoteUnwinderObject *unwinder, _Py_RemoteDebug_ThreadsState *st
pid_t *new_tids = PyMem_RawRealloc(unwinder->thread_tids, new_cap * sizeof(pid_t));
if (new_tids == NULL) {
closedir(dir);
- st->tids = NULL;
- st->count = 0;
+ _Py_RemoteDebug_InitThreadsState(unwinder, st);
PyErr_NoMemory();
return -1;
}
@@ -697,8 +708,15 @@ read_thread_ids(RemoteUnwinderObject *unwinder, _Py_RemoteDebug_ThreadsState *st
unwinder->thread_tids[st->count++] = (pid_t)tid;
}
+ if (closedir(dir) != 0) {
+ int err = errno;
+ _Py_RemoteDebug_InitThreadsState(unwinder, st);
+ _set_debug_oserror_from_errno_with_filename(err, task_path,
+ "Failed to close process task directory '%s': %s",
+ task_path, strerror(err));
+ return -1;
+ }
st->tids = unwinder->thread_tids;
- closedir(dir);
return 0;
}
@@ -711,28 +729,30 @@ detach_threads(_Py_RemoteDebug_ThreadsState *st, size_t up_to)
}
static int
-seize_thread(pid_t tid)
+seize_thread(pid_t tid, int *err)
{
if (ptrace(PTRACE_SEIZE, tid, NULL, 0) == 0) {
return 0;
}
- if (errno == ESRCH) {
+ *err = errno;
+ if (*err == ESRCH) {
return 1; // Thread gone, skip
}
- if (errno == EPERM) {
+ if (*err == EPERM) {
// Thread may have exited, be in a special state, or already be traced.
// Skip rather than fail - this avoids endless retry loops when
// threads transiently become inaccessible.
return 1;
}
- if (errno == EINVAL || errno == EIO) {
+ if (*err == EINVAL || *err == EIO) {
// Fallback for older kernels
if (ptrace(PTRACE_ATTACH, tid, NULL, NULL) == 0) {
int status;
waitpid(tid, &status, __WALL);
return 0;
}
- if (errno == ESRCH || errno == EPERM) {
+ *err = errno;
+ if (*err == ESRCH || *err == EPERM) {
return 1; // Thread gone or inaccessible
}
}
@@ -746,39 +766,50 @@ _Py_RemoteDebug_StopAllThreads(RemoteUnwinderObject *unwinder, _Py_RemoteDebug_T
return -1;
}
- for (size_t i = 0; i < st->count; i++) {
+ size_t n_tids = st->count;
+ size_t seized = 0;
+ for (size_t i = 0; i < n_tids; i++) {
pid_t tid = st->tids[i];
- int ret = seize_thread(tid);
+ int err = 0;
+ int ret = seize_thread(tid, &err);
if (ret == 1) {
continue; // Thread gone, skip
}
if (ret < 0) {
- detach_threads(st, i);
- PyErr_Format(PyExc_RuntimeError, "Failed to seize thread %d: %s", tid, strerror(errno));
- st->tids = NULL;
- st->count = 0;
+ detach_threads(st, seized);
+ _set_debug_oserror_from_errno(err,
+ "Failed to seize thread %d: %s", tid, strerror(err));
+ _Py_RemoteDebug_InitThreadsState(unwinder, st);
return -1;
}
+ st->tids[seized++] = tid;
- if (ptrace(PTRACE_INTERRUPT, tid, NULL, NULL) == -1 && errno != ESRCH) {
- detach_threads(st, i + 1);
- PyErr_Format(PyExc_RuntimeError, "Failed to interrupt thread %d: %s", tid, strerror(errno));
- st->tids = NULL;
- st->count = 0;
- return -1;
+ if (ptrace(PTRACE_INTERRUPT, tid, NULL, NULL) == -1) {
+ err = errno;
+ if (err != ESRCH) {
+ detach_threads(st, seized);
+ _set_debug_oserror_from_errno(err,
+ "Failed to interrupt thread %d: %s", tid, strerror(err));
+ _Py_RemoteDebug_InitThreadsState(unwinder, st);
+ return -1;
+ }
}
int status;
- if (waitpid(tid, &status, __WALL) == -1 && errno != ECHILD && errno != ESRCH) {
- detach_threads(st, i + 1);
- PyErr_Format(PyExc_RuntimeError, "waitpid failed for thread %d: %s", tid, strerror(errno));
- st->tids = NULL;
- st->count = 0;
- return -1;
+ if (waitpid(tid, &status, __WALL) == -1) {
+ err = errno;
+ if (err != ECHILD && err != ESRCH) {
+ detach_threads(st, seized);
+ _set_debug_oserror_from_errno(err,
+ "waitpid failed for thread %d: %s", tid, strerror(err));
+ _Py_RemoteDebug_InitThreadsState(unwinder, st);
+ return -1;
+ }
}
}
+ st->count = seized;
return 0;
}
diff --git a/Python/remote_debug.h b/Python/remote_debug.h
index 53bbd571ad3cef..6fecc23502b46e 100644
--- a/Python/remote_debug.h
+++ b/Python/remote_debug.h
@@ -100,9 +100,16 @@ extern "C" {
# define HAVE_PROCESS_VM_READV 0
#endif
+static inline int
+_Py_RemoteDebug_HasPermissionError(void)
+{
+ return PyErr_Occurred()
+ && PyErr_ExceptionMatches(PyExc_PermissionError);
+}
+
#define _set_debug_exception_cause(exception, format, ...) \
do { \
- if (!PyErr_ExceptionMatches(PyExc_PermissionError)) { \
+ if (!_Py_RemoteDebug_HasPermissionError()) { \
PyThreadState *tstate = _PyThreadState_GET(); \
if (!_PyErr_Occurred(tstate)) { \
_PyErr_Format(tstate, exception, format, ##__VA_ARGS__); \
@@ -112,6 +119,20 @@ extern "C" {
} \
} while (0)
+#define _set_debug_oserror_from_errno(err, format, ...) \
+ do { \
+ errno = (err); \
+ PyErr_SetFromErrno(PyExc_OSError); \
+ _set_debug_exception_cause(PyExc_OSError, format, ##__VA_ARGS__); \
+ } while (0)
+
+#define _set_debug_oserror_from_errno_with_filename(err, filename, format, ...) \
+ do { \
+ errno = (err); \
+ PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename); \
+ _set_debug_exception_cause(PyExc_OSError, format, ##__VA_ARGS__); \
+ } while (0)
+
static inline size_t
get_page_size(void) {
size_t page_size = 0;
@@ -170,7 +191,7 @@ _Py_RemoteDebug_ValidatePyRuntimeCookie(proc_handle_t *handle, uintptr_t address
}
char buf[sizeof(_Py_Debug_Cookie) - 1];
if (_Py_RemoteDebug_ReadRemoteMemory(handle, address, sizeof(buf), buf) != 0) {
- if (!PyErr_ExceptionMatches(PyExc_PermissionError)) {
+ if (!_Py_RemoteDebug_HasPermissionError()) {
PyErr_Clear();
}
return 0;
@@ -207,6 +228,21 @@ static mach_port_t pid_to_task(pid_t pid);
// Initialize the process handle
UNUSED static int
_Py_RemoteDebug_InitProcHandle(proc_handle_t *handle, pid_t pid) {
+ handle->pid = 0;
+#if defined(__APPLE__) && defined(TARGET_OS_OSX) && TARGET_OS_OSX
+ handle->task = 0;
+#elif defined(MS_WINDOWS)
+ handle->hProcess = NULL;
+#elif defined(__linux__)
+ handle->memfd = -1;
+#endif
+ handle->page_size = get_page_size();
+ handle->page_cache_count = 0;
+ for (int i = 0; i < MAX_PAGES; i++) {
+ handle->pages[i].data = NULL;
+ handle->pages[i].valid = 0;
+ }
+
handle->pid = pid;
#if defined(__APPLE__) && defined(TARGET_OS_OSX) && TARGET_OS_OSX
handle->task = pid_to_task(handle->pid);
@@ -219,19 +255,12 @@ _Py_RemoteDebug_InitProcHandle(proc_handle_t *handle, pid_t pid) {
PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION | PROCESS_SUSPEND_RESUME,
FALSE, pid);
if (handle->hProcess == NULL) {
- PyErr_SetFromWindowsErr(0);
+ DWORD error = GetLastError();
+ PyErr_SetFromWindowsErr(error);
_set_debug_exception_cause(PyExc_RuntimeError, "Failed to initialize Windows process handle");
return -1;
}
-#elif defined(__linux__)
- handle->memfd = -1;
#endif
- handle->page_size = get_page_size();
- handle->page_cache_count = 0;
- for (int i = 0; i < MAX_PAGES; i++) {
- handle->pages[i].data = NULL;
- handle->pages[i].valid = 0;
- }
return 0;
}
@@ -396,17 +425,19 @@ return_section_address_fat(
size_t cpu_size = sizeof(cpu), abi64_size = sizeof(is_abi64);
if (sysctlbyname("hw.cputype", &cpu, &cpu_size, NULL, 0) != 0) {
- PyErr_Format(PyExc_OSError,
+ int err = errno;
+ _set_debug_oserror_from_errno(err,
"Failed to determine CPU type via sysctlbyname "
"for fat binary analysis at 0x%lx: %s",
- base, strerror(errno));
+ base, strerror(err));
return 0;
}
if (sysctlbyname("hw.cpu64bit_capable", &is_abi64, &abi64_size, NULL, 0) != 0) {
- PyErr_Format(PyExc_OSError,
+ int err = errno;
+ _set_debug_oserror_from_errno(err,
"Failed to determine CPU ABI capability via sysctlbyname "
"for fat binary analysis at 0x%lx: %s",
- base, strerror(errno));
+ base, strerror(err));
return 0;
}
@@ -459,26 +490,29 @@ search_section_in_file(const char* secname, char* path, uintptr_t base, mach_vm_
{
int fd = open(path, O_RDONLY);
if (fd == -1) {
- PyErr_Format(PyExc_OSError,
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, path,
"Cannot open binary file '%s' for section '%s' search: %s",
- path, secname, strerror(errno));
+ path, secname, strerror(err));
return 0;
}
struct stat fs;
if (fstat(fd, &fs) == -1) {
- PyErr_Format(PyExc_OSError,
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, path,
"Cannot get file size for binary '%s' during section '%s' search: %s",
- path, secname, strerror(errno));
+ path, secname, strerror(err));
close(fd);
return 0;
}
void* map = mmap(0, fs.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (map == MAP_FAILED) {
- PyErr_Format(PyExc_OSError,
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, path,
"Cannot memory map binary file '%s' (size: %lld bytes) for section '%s' search: %s",
- path, (long long)fs.st_size, secname, strerror(errno));
+ path, (long long)fs.st_size, secname, strerror(err));
close(fd);
return 0;
}
@@ -507,15 +541,21 @@ search_section_in_file(const char* secname, char* path, uintptr_t base, mach_vm_
}
if (munmap(map, fs.st_size) != 0) {
- PyErr_Format(PyExc_OSError,
- "Failed to unmap binary file '%s' (size: %lld bytes): %s",
- path, (long long)fs.st_size, strerror(errno));
+ if (!PyErr_Occurred()) {
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, path,
+ "Failed to unmap binary file '%s' (size: %lld bytes): %s",
+ path, (long long)fs.st_size, strerror(err));
+ }
result = 0;
}
if (close(fd) != 0) {
- PyErr_Format(PyExc_OSError,
- "Failed to close binary file '%s': %s",
- path, strerror(errno));
+ if (!PyErr_Occurred()) {
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, path,
+ "Failed to close binary file '%s': %s",
+ path, strerror(err));
+ }
result = 0;
}
return result;
@@ -560,14 +600,15 @@ search_map_for_section(proc_handle_t *handle, const char* secname, const char* s
char map_filename[MAXPATHLEN + 1];
- while (mach_vm_region(
- proc_ref,
- &address,
- &size,
- VM_REGION_BASIC_INFO_64,
- (vm_region_info_t)®ion_info,
- &count,
- &object_name) == KERN_SUCCESS)
+ kern_return_t kr;
+ while ((kr = mach_vm_region(
+ proc_ref,
+ &address,
+ &size,
+ VM_REGION_BASIC_INFO_64,
+ (vm_region_info_t)®ion_info,
+ &count,
+ &object_name)) == KERN_SUCCESS)
{
if ((region_info.protection & VM_PROT_READ) == 0
@@ -591,18 +632,32 @@ search_map_for_section(proc_handle_t *handle, const char* secname, const char* s
}
if (strncmp(filename, substr, strlen(substr)) == 0) {
+ PyErr_Clear();
uintptr_t result = search_section_in_file(
secname, map_filename, address, size, proc_ref);
- if (result != 0
- && (validator == NULL || validator(handle, result)))
- {
- return result;
+ if (result != 0) {
+ if (validator == NULL || validator(handle, result)) {
+ return result;
+ }
+ if (_Py_RemoteDebug_HasPermissionError()) {
+ return 0;
+ }
+ }
+ else if (_Py_RemoteDebug_HasPermissionError()) {
+ return 0;
}
}
address += size;
}
+ if (kr != KERN_INVALID_ADDRESS && !PyErr_Occurred()) {
+ PyErr_Format(PyExc_RuntimeError,
+ "mach_vm_region failed while searching PID %d for section '%s' "
+ "(kern_return_t: %d)",
+ handle->pid, secname, kr);
+ }
+
return 0;
}
@@ -625,25 +680,29 @@ search_elf_file_for_section(
int fd = open(elf_file, O_RDONLY);
if (fd < 0) {
- PyErr_Format(PyExc_OSError,
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, elf_file,
"Cannot open ELF file '%s' for section '%s' search: %s",
- elf_file, secname, strerror(errno));
+ elf_file, secname, strerror(err));
goto exit;
}
struct stat file_stats;
if (fstat(fd, &file_stats) != 0) {
- PyErr_Format(PyExc_OSError,
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, elf_file,
"Cannot get file size for ELF file '%s' during section '%s' search: %s",
- elf_file, secname, strerror(errno));
+ elf_file, secname, strerror(err));
goto exit;
}
file_memory = mmap(NULL, file_stats.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (file_memory == MAP_FAILED) {
- PyErr_Format(PyExc_OSError,
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, elf_file,
"Cannot memory map ELF file '%s' (size: %lld bytes) for section '%s' search: %s",
- elf_file, (long long)file_stats.st_size, secname, strerror(errno));
+ elf_file, (long long)file_stats.st_size, secname, strerror(err));
+ file_memory = NULL;
goto exit;
}
@@ -700,12 +759,23 @@ search_elf_file_for_section(
exit:
if (file_memory != NULL) {
- munmap(file_memory, file_stats.st_size);
+ if (munmap(file_memory, file_stats.st_size) != 0) {
+ if (!PyErr_Occurred()) {
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, elf_file,
+ "Failed to unmap ELF file '%s' (size: %lld bytes): %s",
+ elf_file, (long long)file_stats.st_size, strerror(err));
+ }
+ result = 0;
+ }
}
if (fd >= 0 && close(fd) != 0) {
- PyErr_Format(PyExc_OSError,
- "Failed to close ELF file '%s': %s",
- elf_file, strerror(errno));
+ if (!PyErr_Occurred()) {
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, elf_file,
+ "Failed to close ELF file '%s': %s",
+ elf_file, strerror(err));
+ }
result = 0;
}
return result;
@@ -720,9 +790,10 @@ search_linux_map_for_section(proc_handle_t *handle, const char* secname, const c
FILE* maps_file = fopen(maps_file_path, "r");
if (maps_file == NULL) {
- PyErr_Format(PyExc_OSError,
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, maps_file_path,
"Cannot open process memory map file '%s' for PID %d section search: %s",
- maps_file_path, handle->pid, strerror(errno));
+ maps_file_path, handle->pid, strerror(err));
return 0;
}
@@ -787,26 +858,39 @@ search_linux_map_for_section(proc_handle_t *handle, const char* secname, const c
}
if (strstr(filename, substr)) {
- if (PyErr_ExceptionMatches(PyExc_PermissionError)) {
- retval = 0;
- break;
- }
PyErr_Clear();
retval = search_elf_file_for_section(handle, secname, start, path);
- if (retval
- && (validator == NULL || validator(handle, retval)))
- {
+ if (retval) {
+ if (validator == NULL || validator(handle, retval)) {
+ break;
+ }
+ if (_Py_RemoteDebug_HasPermissionError()) {
+ retval = 0;
+ break;
+ }
+ }
+ else if (_Py_RemoteDebug_HasPermissionError()) {
break;
}
retval = 0;
}
}
+ if (retval == 0 && !PyErr_Occurred() && ferror(maps_file)) {
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, maps_file_path,
+ "Failed to read process map file '%s' for PID %d section search: %s",
+ maps_file_path, handle->pid, strerror(err));
+ }
+
PyMem_Free(line);
if (fclose(maps_file) != 0) {
- PyErr_Format(PyExc_OSError,
- "Failed to close process map file '%s': %s",
- maps_file_path, strerror(errno));
+ if (!PyErr_Occurred()) {
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, maps_file_path,
+ "Failed to close process map file '%s': %s",
+ maps_file_path, strerror(err));
+ }
retval = 0;
}
@@ -829,9 +913,9 @@ static int is_process_alive(HANDLE hProcess) {
static void* analyze_pe(const wchar_t* mod_path, BYTE* remote_base, const char* secname) {
HANDLE hFile = CreateFileW(mod_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
- PyErr_SetFromWindowsErr(0);
DWORD error = GetLastError();
- PyErr_Format(PyExc_OSError,
+ PyErr_SetFromWindowsErr(error);
+ _set_debug_exception_cause(PyExc_OSError,
"Cannot open PE file for section '%s' analysis (error %lu)",
secname, error);
return NULL;
@@ -839,9 +923,9 @@ static void* analyze_pe(const wchar_t* mod_path, BYTE* remote_base, const char*
HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, 0);
if (!hMap) {
- PyErr_SetFromWindowsErr(0);
DWORD error = GetLastError();
- PyErr_Format(PyExc_OSError,
+ PyErr_SetFromWindowsErr(error);
+ _set_debug_exception_cause(PyExc_OSError,
"Cannot create file mapping for PE file section '%s' analysis (error %lu)",
secname, error);
CloseHandle(hFile);
@@ -850,9 +934,9 @@ static void* analyze_pe(const wchar_t* mod_path, BYTE* remote_base, const char*
BYTE* mapView = (BYTE*)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
if (!mapView) {
- PyErr_SetFromWindowsErr(0);
DWORD error = GetLastError();
- PyErr_Format(PyExc_OSError,
+ PyErr_SetFromWindowsErr(error);
+ _set_debug_exception_cause(PyExc_OSError,
"Cannot map view of PE file for section '%s' analysis (error %lu)",
secname, error);
CloseHandle(hMap);
@@ -910,9 +994,9 @@ search_windows_map_for_section(proc_handle_t* handle, const char* secname, const
} while (hProcSnap == INVALID_HANDLE_VALUE && GetLastError() == ERROR_BAD_LENGTH);
if (hProcSnap == INVALID_HANDLE_VALUE) {
- PyErr_SetFromWindowsErr(0);
DWORD error = GetLastError();
- PyErr_Format(PyExc_PermissionError,
+ PyErr_SetFromWindowsErr(error);
+ _set_debug_exception_cause(PyExc_OSError,
"Unable to create module snapshot for PID %d section '%s' "
"search (error %lu). Check permissions or PID validity",
handle->pid, secname, error);
@@ -923,17 +1007,46 @@ search_windows_map_for_section(proc_handle_t* handle, const char* secname, const
moduleEntry.dwSize = sizeof(moduleEntry);
void* runtime_addr = NULL;
- for (BOOL hasModule = Module32FirstW(hProcSnap, &moduleEntry); hasModule; hasModule = Module32NextW(hProcSnap, &moduleEntry)) {
+ if (!Module32FirstW(hProcSnap, &moduleEntry)) {
+ DWORD error = GetLastError();
+ PyErr_SetFromWindowsErr(error);
+ _set_debug_exception_cause(PyExc_OSError,
+ "Unable to enumerate modules for PID %d section '%s' "
+ "search (error %lu)",
+ handle->pid, secname, error);
+ CloseHandle(hProcSnap);
+ return 0;
+ }
+
+ do {
// Look for either python executable or DLL
if (wcsstr(moduleEntry.szModule, substr)) {
+ PyErr_Clear();
void *candidate = analyze_pe(moduleEntry.szExePath, moduleEntry.modBaseAddr, secname);
- if (candidate != NULL
- && (validator == NULL || validator(handle, (uintptr_t)candidate)))
- {
- runtime_addr = candidate;
+ if (candidate != NULL) {
+ if (validator == NULL || validator(handle, (uintptr_t)candidate)) {
+ runtime_addr = candidate;
+ break;
+ }
+ if (_Py_RemoteDebug_HasPermissionError()) {
+ break;
+ }
+ }
+ else if (_Py_RemoteDebug_HasPermissionError()) {
break;
}
}
+ } while (Module32NextW(hProcSnap, &moduleEntry));
+
+ if (runtime_addr == NULL && !PyErr_Occurred()) {
+ DWORD error = GetLastError();
+ if (error != ERROR_NO_MORE_FILES) {
+ PyErr_SetFromWindowsErr(error);
+ _set_debug_exception_cause(PyExc_OSError,
+ "Module enumeration failed for PID %d section '%s' "
+ "search (error %lu)",
+ handle->pid, secname, error);
+ }
}
CloseHandle(hProcSnap);
@@ -954,19 +1067,21 @@ _Py_RemoteDebug_GetPyRuntimeAddress(proc_handle_t* handle)
address = search_windows_map_for_section(handle, "PyRuntime", L"python",
_Py_RemoteDebug_ValidatePyRuntimeCookie);
if (address == 0) {
- // Error out: 'python' substring covers both executable and DLL
- PyObject *exc = PyErr_GetRaisedException();
- PyErr_Format(PyExc_RuntimeError,
- "Failed to find the PyRuntime section in process %d on Windows platform",
- handle->pid);
- _PyErr_ChainExceptions1(exc);
+ if (!_Py_RemoteDebug_HasPermissionError()) {
+ // Error out: 'python' substring covers both executable and DLL
+ PyObject *exc = PyErr_GetRaisedException();
+ PyErr_Format(PyExc_RuntimeError,
+ "Failed to find the PyRuntime section in process %d on Windows platform",
+ handle->pid);
+ _PyErr_ChainExceptions1(exc);
+ }
}
#elif defined(__linux__) && HAVE_PROCESS_VM_READV
// On Linux, search for 'python' in executable or DLL
address = search_linux_map_for_section(handle, "PyRuntime", "python",
_Py_RemoteDebug_ValidatePyRuntimeCookie);
if (address == 0) {
- if (!PyErr_ExceptionMatches(PyExc_PermissionError)) {
+ if (!_Py_RemoteDebug_HasPermissionError()) {
// Error out: 'python' substring covers both executable and DLL
PyObject *exc = PyErr_GetRaisedException();
PyErr_Format(PyExc_RuntimeError,
@@ -982,17 +1097,19 @@ _Py_RemoteDebug_GetPyRuntimeAddress(proc_handle_t* handle)
PyErr_Clear();
address = search_map_for_section(handle, "PyRuntime", *candidate,
_Py_RemoteDebug_ValidatePyRuntimeCookie);
- if (address != 0) {
+ if (address != 0 || _Py_RemoteDebug_HasPermissionError()) {
break;
}
}
if (address == 0) {
- PyObject *exc = PyErr_GetRaisedException();
- PyErr_Format(PyExc_RuntimeError,
- "Failed to find the PyRuntime section in process %d "
- "on macOS platform (tried both libpython and python)",
- handle->pid);
- _PyErr_ChainExceptions1(exc);
+ if (!_Py_RemoteDebug_HasPermissionError()) {
+ PyObject *exc = PyErr_GetRaisedException();
+ PyErr_Format(PyExc_RuntimeError,
+ "Failed to find the PyRuntime section in process %d "
+ "on macOS platform (tried both libpython and python)",
+ handle->pid);
+ _PyErr_ChainExceptions1(exc);
+ }
}
#else
_set_debug_exception_cause(PyExc_RuntimeError,
@@ -1013,9 +1130,9 @@ open_proc_mem_fd(proc_handle_t *handle)
handle->memfd = open(mem_file_path, O_RDWR);
if (handle->memfd == -1) {
- PyErr_SetFromErrno(PyExc_OSError);
- _set_debug_exception_cause(PyExc_OSError,
- "failed to open file %s: %s", mem_file_path, strerror(errno));
+ int err = errno;
+ _set_debug_oserror_from_errno_with_filename(err, mem_file_path,
+ "failed to open file %s: %s", mem_file_path, strerror(err));
return -1;
}
return 0;
@@ -1026,6 +1143,9 @@ open_proc_mem_fd(proc_handle_t *handle)
static int
read_remote_memory_fallback(proc_handle_t *handle, uintptr_t remote_address, size_t len, void* dst)
{
+ if (len == 0) {
+ return 0;
+ }
if (handle->memfd == -1) {
if (open_proc_mem_fd(handle) < 0) {
return -1;
@@ -1043,14 +1163,23 @@ read_remote_memory_fallback(proc_handle_t *handle, uintptr_t remote_address, siz
read_bytes = preadv(handle->memfd, local, 1, offset);
if (read_bytes < 0) {
+ int err = errno;
+ errno = err;
PyErr_SetFromErrno(PyExc_OSError);
_set_debug_exception_cause(PyExc_OSError,
"preadv failed for PID %d at address 0x%lx "
"(size %zu, partial read %zd bytes): %s",
- handle->pid, remote_address + result, len - result, result, strerror(errno));
+ handle->pid, remote_address + result, len - result, result, strerror(err));
return -1;
}
+ if (read_bytes == 0) {
+ PyErr_Format(PyExc_OSError,
+ "preadv returned 0 bytes for PID %d at address 0x%lx "
+ "(size %zu, partial read %zd bytes)",
+ handle->pid, remote_address + result, len - result, result);
+ return -1;
+ }
result += read_bytes;
} while ((size_t)read_bytes != local[0].iov_len);
return 0;
@@ -1062,11 +1191,15 @@ read_remote_memory_fallback(proc_handle_t *handle, uintptr_t remote_address, siz
static int
_Py_RemoteDebug_ReadRemoteMemory(proc_handle_t *handle, uintptr_t remote_address, size_t len, void* dst)
{
+ if (len == 0) {
+ return 0;
+ }
#ifdef MS_WINDOWS
SIZE_T read_bytes = 0;
SIZE_T result = 0;
do {
if (!ReadProcessMemory(handle->hProcess, (LPCVOID)(remote_address + result), (char*)dst + result, len - result, &read_bytes)) {
+ DWORD error = GetLastError();
// Check if the process is still alive: we need to be able to tell our caller
// that the process is dead and not just that the read failed.
if (!is_process_alive(handle->hProcess)) {
@@ -1074,14 +1207,20 @@ _Py_RemoteDebug_ReadRemoteMemory(proc_handle_t *handle, uintptr_t remote_address
PyErr_SetFromErrno(PyExc_OSError);
return -1;
}
- PyErr_SetFromWindowsErr(0);
- DWORD error = GetLastError();
+ PyErr_SetFromWindowsErr(error);
_set_debug_exception_cause(PyExc_OSError,
"ReadProcessMemory failed for PID %d at address 0x%lx "
"(size %zu, partial read %zu bytes): Windows error %lu",
handle->pid, remote_address + result, len - result, result, error);
return -1;
}
+ if (read_bytes == 0) {
+ PyErr_Format(PyExc_OSError,
+ "ReadProcessMemory returned 0 bytes for PID %d at address 0x%lx "
+ "(size %zu, partial read %zu bytes)",
+ handle->pid, remote_address + result, len - result, result);
+ return -1;
+ }
result += read_bytes;
} while (result < len);
return 0;
@@ -1102,31 +1241,40 @@ _Py_RemoteDebug_ReadRemoteMemory(proc_handle_t *handle, uintptr_t remote_address
read_bytes = process_vm_readv(handle->pid, local, 1, remote, 1, 0);
if (read_bytes < 0) {
- if (errno == ENOSYS) {
+ int err = errno;
+ if (err == ENOSYS) {
return read_remote_memory_fallback(handle, remote_address, len, dst);
}
+ errno = err;
PyErr_SetFromErrno(PyExc_OSError);
- if (errno == ESRCH) {
+ if (err == ESRCH) {
return -1;
}
_set_debug_exception_cause(PyExc_OSError,
"process_vm_readv failed for PID %d at address 0x%lx "
"(size %zu, partial read %zd bytes): %s",
- handle->pid, remote_address + result, len - result, result, strerror(errno));
+ handle->pid, remote_address + result, len - result, result, strerror(err));
return -1;
}
+ if (read_bytes == 0) {
+ PyErr_Format(PyExc_OSError,
+ "process_vm_readv returned 0 bytes for PID %d at address 0x%lx "
+ "(size %zu, partial read %zd bytes)",
+ handle->pid, remote_address + result, len - result, result);
+ return -1;
+ }
result += read_bytes;
} while ((size_t)read_bytes != local[0].iov_len);
return 0;
#elif defined(__APPLE__) && defined(TARGET_OS_OSX) && TARGET_OS_OSX
- Py_ssize_t result = -1;
+ mach_vm_size_t bytes_read = 0;
kern_return_t kr = mach_vm_read_overwrite(
handle->task,
(mach_vm_address_t)remote_address,
len,
(mach_vm_address_t)dst,
- (mach_vm_size_t*)&result);
+ &bytes_read);
if (kr != KERN_SUCCESS) {
switch (err_get_code(kr)) {
@@ -1170,6 +1318,13 @@ _Py_RemoteDebug_ReadRemoteMemory(proc_handle_t *handle, uintptr_t remote_address
}
return -1;
}
+ if (bytes_read != (mach_vm_size_t)len) {
+ PyErr_Format(PyExc_OSError,
+ "mach_vm_read_overwrite read %llu of %zu bytes for PID %d at "
+ "address 0x%lx",
+ (unsigned long long)bytes_read, len, handle->pid, remote_address);
+ return -1;
+ }
return 0;
#else
Py_UNREACHABLE();
@@ -1181,6 +1336,9 @@ _Py_RemoteDebug_ReadRemoteMemory(proc_handle_t *handle, uintptr_t remote_address
static int
_Py_RemoteDebug_WriteRemoteMemoryFallback(proc_handle_t *handle, uintptr_t remote_address, size_t len, const void* src)
{
+ if (len == 0) {
+ return 0;
+ }
if (handle->memfd == -1) {
if (open_proc_mem_fd(handle) < 0) {
return -1;
@@ -1198,10 +1356,19 @@ _Py_RemoteDebug_WriteRemoteMemoryFallback(proc_handle_t *handle, uintptr_t remot
written = pwritev(handle->memfd, local, 1, offset);
if (written < 0) {
+ int err = errno;
+ errno = err;
PyErr_SetFromErrno(PyExc_OSError);
return -1;
}
+ if (written == 0) {
+ PyErr_Format(PyExc_OSError,
+ "pwritev wrote 0 bytes for PID %d at address 0x%lx "
+ "(size %zu, partial write %zd bytes)",
+ handle->pid, remote_address + result, len - result, result);
+ return -1;
+ }
result += written;
} while ((size_t)written != local[0].iov_len);
return 0;
@@ -1212,19 +1379,29 @@ _Py_RemoteDebug_WriteRemoteMemoryFallback(proc_handle_t *handle, uintptr_t remot
UNUSED static int
_Py_RemoteDebug_WriteRemoteMemory(proc_handle_t *handle, uintptr_t remote_address, size_t len, const void* src)
{
+ if (len == 0) {
+ return 0;
+ }
#ifdef MS_WINDOWS
SIZE_T written = 0;
SIZE_T result = 0;
do {
if (!WriteProcessMemory(handle->hProcess, (LPVOID)(remote_address + result), (const char*)src + result, len - result, &written)) {
- PyErr_SetFromWindowsErr(0);
DWORD error = GetLastError();
+ PyErr_SetFromWindowsErr(error);
_set_debug_exception_cause(PyExc_OSError,
"WriteProcessMemory failed for PID %d at address 0x%lx "
"(size %zu, partial write %zu bytes): Windows error %lu",
handle->pid, remote_address + result, len - result, result, error);
return -1;
}
+ if (written == 0) {
+ PyErr_Format(PyExc_OSError,
+ "WriteProcessMemory wrote 0 bytes for PID %d at address 0x%lx "
+ "(size %zu, partial write %zu bytes)",
+ handle->pid, remote_address + result, len - result, result);
+ return -1;
+ }
result += written;
} while (result < len);
return 0;
@@ -1245,17 +1422,26 @@ _Py_RemoteDebug_WriteRemoteMemory(proc_handle_t *handle, uintptr_t remote_addres
written = process_vm_writev(handle->pid, local, 1, remote, 1, 0);
if (written < 0) {
- if (errno == ENOSYS) {
+ int err = errno;
+ if (err == ENOSYS) {
return _Py_RemoteDebug_WriteRemoteMemoryFallback(handle, remote_address, len, src);
}
+ errno = err;
PyErr_SetFromErrno(PyExc_OSError);
_set_debug_exception_cause(PyExc_OSError,
"process_vm_writev failed for PID %d at address 0x%lx "
"(size %zu, partial write %zd bytes): %s",
- handle->pid, remote_address + result, len - result, result, strerror(errno));
+ handle->pid, remote_address + result, len - result, result, strerror(err));
return -1;
}
+ if (written == 0) {
+ PyErr_Format(PyExc_OSError,
+ "process_vm_writev wrote 0 bytes for PID %d at address 0x%lx "
+ "(size %zu, partial write %zd bytes)",
+ handle->pid, remote_address + result, len - result, result);
+ return -1;
+ }
result += written;
} while ((size_t)written != local[0].iov_len);
return 0;
From 340b4dd6ffaeec92498a21d36949703e986dc2f6 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Tue, 26 May 2026 01:15:56 +0200
Subject: [PATCH 147/213] [3.15] gh-149619: Harden _remote_debugging error
paths (GH-150349) (#150434)
gh-149619: Harden _remote_debugging error paths (GH-150349)
(cherry picked from commit a5be25d3bdc1b3cbc9638a3249c0e3db5a97ebc6)
Co-authored-by: Pablo Galindo Salgado
From d73e43317e08e6d2ce693c61ca6e751996da2d43 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Tue, 26 May 2026 03:04:49 +0200
Subject: [PATCH 148/213] [3.15] gh-149931: Fix memory leaks on failed realloc
(GH-149932) (#150439)
---
Modules/_remote_debugging/frames.c | 6 ++++--
Modules/timemodule.c | 9 ++++++---
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/Modules/_remote_debugging/frames.c b/Modules/_remote_debugging/frames.c
index 8d8019396b3e31..d73cd080dc477f 100644
--- a/Modules/_remote_debugging/frames.c
+++ b/Modules/_remote_debugging/frames.c
@@ -56,12 +56,14 @@ process_single_stack_chunk(
return -1;
}
- this_chunk = PyMem_RawRealloc(this_chunk, actual_size);
- if (!this_chunk) {
+ char *tmp = PyMem_RawRealloc(this_chunk, actual_size);
+ if (!tmp) {
+ PyMem_RawFree(this_chunk);
PyErr_NoMemory();
set_exception_cause(unwinder, PyExc_MemoryError, "Failed to reallocate stack chunk buffer");
return -1;
}
+ this_chunk = tmp;
if (_Py_RemoteDebug_PagedReadRemoteMemory(&unwinder->handle, chunk_addr, actual_size, this_chunk) < 0) {
PyMem_RawFree(this_chunk);
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 25e744d7da25c7..d90bf1f2ef90ed 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -820,12 +820,15 @@ time_strftime1(time_char **outbuf, size_t *bufsize,
PyErr_NoMemory();
return NULL;
}
- *outbuf = (time_char *)PyMem_Realloc(*outbuf,
- *bufsize*sizeof(time_char));
- if (*outbuf == NULL) {
+ time_char *tmp = (time_char *)PyMem_Realloc(*outbuf,
+ *bufsize*sizeof(time_char));
+ if (tmp == NULL) {
+ PyMem_Free(*outbuf);
+ *outbuf = NULL;
PyErr_NoMemory();
return NULL;
}
+ *outbuf = tmp;
#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
errno = 0;
#endif
From 413663b26a48ff0218987b216043d677d7a01397 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Tue, 26 May 2026 06:03:35 +0200
Subject: [PATCH 149/213] [3.15] gh-150443: Exclude explicit dup3 and pipe2
checks on iOS builds. (GH-150444) (#150446)
Exclude explicit dup3 and pipe2 checks on iOS builds.
(cherry picked from commit 629da5c914b4407e01c1dc06cbcbd8dce825fef3)
Co-authored-by: Russell Keith-Magee
---
configure | 26 +++++++++++++-------------
configure.ac | 6 +++---
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/configure b/configure
index 9ad2171460f7ac..7abc41648b3c45 100755
--- a/configure
+++ b/configure
@@ -20020,12 +20020,6 @@ if test "x$ac_cv_func_dup" = xyes
then :
printf "%s\n" "#define HAVE_DUP 1" >>confdefs.h
-fi
-ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
-if test "x$ac_cv_func_dup3" = xyes
-then :
- printf "%s\n" "#define HAVE_DUP3 1" >>confdefs.h
-
fi
ac_fn_c_check_func "$LINENO" "execv" "ac_cv_func_execv"
if test "x$ac_cv_func_execv" = xyes
@@ -20500,12 +20494,6 @@ if test "x$ac_cv_func_pipe" = xyes
then :
printf "%s\n" "#define HAVE_PIPE 1" >>confdefs.h
-fi
-ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
-if test "x$ac_cv_func_pipe2" = xyes
-then :
- printf "%s\n" "#define HAVE_PIPE2 1" >>confdefs.h
-
fi
ac_fn_c_check_func "$LINENO" "plock" "ac_cv_func_plock"
if test "x$ac_cv_func_plock" = xyes
@@ -21173,7 +21161,13 @@ fi
# header definition prevents usage - autoconf doesn't use the headers), or
# raise an error if used at runtime. Force these symbols off.
if test "$ac_sys_system" != "iOS" ; then
- ac_fn_c_check_func "$LINENO" "getentropy" "ac_cv_func_getentropy"
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf "%s\n" "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "getentropy" "ac_cv_func_getentropy"
if test "x$ac_cv_func_getentropy" = xyes
then :
printf "%s\n" "#define HAVE_GETENTROPY 1" >>confdefs.h
@@ -21184,6 +21178,12 @@ if test "x$ac_cv_func_getgroups" = xyes
then :
printf "%s\n" "#define HAVE_GETGROUPS 1" >>confdefs.h
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf "%s\n" "#define HAVE_PIPE2 1" >>confdefs.h
+
fi
ac_fn_c_check_func "$LINENO" "system" "ac_cv_func_system"
if test "x$ac_cv_func_system" = xyes
diff --git a/configure.ac b/configure.ac
index a51e173e5293f2..47a6e59623b830 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5469,7 +5469,7 @@ fi
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clearenv \
clock closefrom close_range confstr \
- copy_file_range ctermid dladdr dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dladdr dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid geteuid getgid getgrent getgrgid getgrgid_r \
@@ -5479,7 +5479,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd grantpt if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll ppoll posix_fadvise posix_fallocate posix_openpt posix_spawn posix_spawnp \
+ plock poll ppoll posix_fadvise posix_fallocate posix_openpt posix_spawn posix_spawnp \
posix_spawn_file_actions_addclosefrom_np \
pread preadv preadv2 process_vm_readv \
pthread_cond_timedwait_relative_np pthread_condattr_setclock pthread_init \
@@ -5516,7 +5516,7 @@ fi
# header definition prevents usage - autoconf doesn't use the headers), or
# raise an error if used at runtime. Force these symbols off.
if test "$ac_sys_system" != "iOS" ; then
- AC_CHECK_FUNCS([getentropy getgroups system])
+ AC_CHECK_FUNCS([dup3 getentropy getgroups pipe2 system])
fi
AC_CHECK_DECL([dirfd],
From 16a31fac483b5ad035908855c1ed4544eadab542 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Tue, 26 May 2026 19:05:11 +0200
Subject: [PATCH 150/213] [3.15] gh-148557: Use em-config to locate trampoline
clang (GH-148556) (#150481)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When CC is wrapped by ccache, the Emscripten trampoline rule cannot derive the
matching clang path by treating CC as a single executable path. Query the active
LLVM toolchain path with em-config instead.
(cherry picked from commit 1310d2c25242041f0a218012426fba14e756eef8)
Co-authored-by: Clément Péron
---
Makefile.pre.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 669a2c9527075c..9c358bc6fbc681 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -3211,7 +3211,7 @@ Python/asm_trampoline.o: $(srcdir)/Python/asm_trampoline.S
Python/emscripten_trampoline_inner.wasm: $(srcdir)/Python/emscripten_trampoline_inner.c
# emcc has a path that ends with emsdk/upstream/emscripten/emcc, we're looking for emsdk/upstream/bin/clang.
- $$(dirname $$(dirname $(CC)))/bin/clang -o $@ $< -mgc -O2 -Wl,--no-entry -Wl,--import-table -Wl,--import-memory -target wasm32-unknown-unknown -nostdlib
+ $$(em-config LLVM_ROOT)/clang -o $@ $< -mgc -O2 -Wl,--no-entry -Wl,--import-table -Wl,--import-memory -target wasm32-unknown-unknown -nostdlib
Python/emscripten_trampoline_wasm.c: Python/emscripten_trampoline_inner.wasm
$(PYTHON_FOR_REGEN) $(srcdir)/Platforms/emscripten/prepare_external_wasm.py $< $@ getWasmTrampolineModule
From 79e17d7fa5bbd0e83e6d32ba3076633a2f8df3ea Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Tue, 26 May 2026 21:21:36 +0200
Subject: [PATCH 151/213] [3.15] gh-88726: Stop using non-standard charset
names eucgb2312_cn and big5_tw in email (GH-149959) (GH-150491)
(cherry picked from commit 5e467f4331d4cb7a8e2986c27af7eb68ccaccb37)
Co-authored-by: Serhiy Storchaka
---
Lib/email/charset.py | 2 -
Lib/test/test_email/test_asian_codecs.py | 56 +++++++++++++++++++
...6-05-17-22-37-02.gh-issue-88726.BAoL6j.rst | 2 +
3 files changed, 58 insertions(+), 2 deletions(-)
create mode 100644 Misc/NEWS.d/next/Library/2026-05-17-22-37-02.gh-issue-88726.BAoL6j.rst
diff --git a/Lib/email/charset.py b/Lib/email/charset.py
index 5036c3f58a5633..c4b246455f86c6 100644
--- a/Lib/email/charset.py
+++ b/Lib/email/charset.py
@@ -93,8 +93,6 @@
# Map charsets to their Unicode codec strings.
CODEC_MAP = {
- 'gb2312': 'eucgb2312_cn',
- 'big5': 'big5_tw',
# Hack: We don't want *any* conversion for stuff marked us-ascii, as all
# sorts of garbage might be sent to us in the guise of 7-bit us-ascii.
# Let that stuff pass through without conversion to/from Unicode.
diff --git a/Lib/test/test_email/test_asian_codecs.py b/Lib/test/test_email/test_asian_codecs.py
index ca44f54c69b39b..85979ffd8169a7 100644
--- a/Lib/test/test_email/test_asian_codecs.py
+++ b/Lib/test/test_email/test_asian_codecs.py
@@ -58,6 +58,62 @@ def test_japanese_codecs(self):
# TK: full decode comparison
eq(str(h).encode(jcode), subject_bytes)
+ h = Header("Japanese")
+ s = '\u65e5\u672c\u8a9e' # 日本語
+ h.append(s, Charset('euc-jp'))
+ h.append(s, Charset('iso-2022-jp'))
+ h.append(s, Charset('shift_jis'))
+ eq(h.encode(), """\
+Japanese =?iso-2022-jp?b?GyRCRnxLXDhsGyhC?= =?iso-2022-jp?b?GyRCRnxLXDhsGyhC?=
+ =?iso-2022-jp?b?GyRCRnxLXDhsGyhC?=""")
+ eq(decode_header(h.encode()),
+ [(b'Japanese ', None),
+ (b'\x1b$BF|K\\8l\x1b(B\x1b$BF|K\\8l\x1b(B\x1b$BF|K\\8l\x1b(B', 'iso-2022-jp'),
+ ])
+
+ def test_chinese_codecs(self):
+ eq = self.ndiffAssertEqual
+ h = Header("Chinese")
+ s = '\u4e2d\u6587' # 中文
+ h.append(s, Charset('gb2312'))
+ h.append(s, Charset('gbk'))
+ h.append(s, Charset('gb18030'))
+ h.append(s, Charset('hz'))
+ h.append(s, Charset('big5'))
+ h.append(s, Charset('big5hkscs'))
+ eq(h.encode(), """\
+Chinese =?gb2312?b?1tDOxA==?= =?gbk?b?1tDOxA==?= =?gb18030?b?1tDOxA==?=
+ =?hz?b?fntWUE5Efn0=?= =?big5?b?pKSk5Q==?= =?big5hkscs?b?pKSk5Q==?=""")
+ eq(decode_header(h.encode()),
+ [(b'Chinese ', None),
+ (b'\xd6\xd0\xce\xc4', 'gb2312'),
+ (b'\xd6\xd0\xce\xc4', 'gbk'),
+ (b'\xd6\xd0\xce\xc4', 'gb18030'),
+ (b'~{VPND~}', 'hz'),
+ (b'\xa4\xa4\xa4\xe5', 'big5'),
+ (b'\xa4\xa4\xa4\xe5', 'big5hkscs'),
+ ])
+
+ def test_korean_codecs(self):
+ eq = self.ndiffAssertEqual
+ h = Header("Korean")
+ s = '\ud55c\uad6d\uc5b4' # 한국어
+ h.append(s, Charset('euc-kr'))
+ h.append(s, Charset('ks_c_5601-1987'))
+ h.append(s, Charset('cp949'))
+ h.append(s, Charset('iso-2022-kr'))
+ h.append(s, Charset('johab'))
+ eq(h.encode(), """\
+Korean =?euc-kr?b?x9Gxub7u?= =?ks_c_5601-1987?b?x9Gxub7uIMfRsbm+7g==?=
+ =?iso-2022-kr?b?GyQpQw5HUTE5Pm4P?= =?johab?b?0GWKgrTh?=""")
+ eq(decode_header(h.encode()),
+ [(b'Korean ', None),
+ (b'\xc7\xd1\xb1\xb9\xbe\xee', 'euc-kr'),
+ (b'\xc7\xd1\xb1\xb9\xbe\xee \xc7\xd1\xb1\xb9\xbe\xee', 'ks_c_5601-1987'),
+ (b'\x1b$)C\x0eGQ19>n\x0f', 'iso-2022-kr'),
+ (b'\xd0e\x8a\x82\xb4\xe1', 'johab'),
+ ])
+
def test_payload_encoding_utf8(self):
jhello = str(b'\xa5\xcf\xa5\xed\xa1\xbc\xa5\xef\xa1\xbc'
b'\xa5\xeb\xa5\xc9\xa1\xaa', 'euc-jp')
diff --git a/Misc/NEWS.d/next/Library/2026-05-17-22-37-02.gh-issue-88726.BAoL6j.rst b/Misc/NEWS.d/next/Library/2026-05-17-22-37-02.gh-issue-88726.BAoL6j.rst
new file mode 100644
index 00000000000000..ba9058d79c9873
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-05-17-22-37-02.gh-issue-88726.BAoL6j.rst
@@ -0,0 +1,2 @@
+The :mod:`email` package now uses standard MIME charset names "gb2312" and
+"big5" instead of non-standard names "eucgb2312_cn" and "big5_tw".
From 528356eac0adf70fed0cf37dbb04c8fd529672d8 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Tue, 26 May 2026 21:46:16 +0200
Subject: [PATCH 152/213] [3.15] gh-150175: Fix ThreadingMock call_count race
condition (GH-150176) (#150182)
gh-150175: Fix ThreadingMock call_count race condition (GH-150176)
ThreadingMock._increment_mock_call() was not thread-safe.
Multiple threads calling the mock simultaneously could lose
increments due to race conditions on call_count and other
attributes.
Fix by overriding _increment_mock_call in ThreadingMixin
and wrapping it with the existing _mock_calls_events_lock.
(cherry picked from commit 388e023fe1197c1ffed374520ed45df4ac72b8f5)
Co-authored-by: saisneha196 <156835592+saisneha196@users.noreply.github.com>
---
Lib/unittest/mock.py | 4 ++++
.../Library/2026-05-21-11-25-58.gh-issue-150175.8H4Caz.rst | 3 +++
2 files changed, 7 insertions(+)
create mode 100644 Misc/NEWS.d/next/Library/2026-05-21-11-25-58.gh-issue-150175.8H4Caz.rst
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 1cee67fa5d7094..2f6f03c7a11ae6 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -3121,6 +3121,10 @@ def _mock_call(self, *args, **kwargs):
return ret_value
+ def _increment_mock_call(self, /, *args, **kwargs):
+ with self._mock_calls_events_lock:
+ super()._increment_mock_call(*args, **kwargs)
+
def wait_until_called(self, *, timeout=_timeout_unset):
"""Wait until the mock object is called.
diff --git a/Misc/NEWS.d/next/Library/2026-05-21-11-25-58.gh-issue-150175.8H4Caz.rst b/Misc/NEWS.d/next/Library/2026-05-21-11-25-58.gh-issue-150175.8H4Caz.rst
new file mode 100644
index 00000000000000..80fc80d4d50a63
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-05-21-11-25-58.gh-issue-150175.8H4Caz.rst
@@ -0,0 +1,3 @@
+Fix race condition in :class:`unittest.mock.ThreadingMock` where
+concurrent calls could lose increments to ``call_count`` and other
+attributes due to a missing lock in ``_increment_mock_call``.
From d2b10e75c7093fd9637dc8428d94cb8c723f808d Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Wed, 27 May 2026 12:52:02 +0200
Subject: [PATCH 153/213] [3.15] gh-149571: Fix the C implementation of
Element.itertext() (GH-149929) (GH-150509)
It no longer emits text for comments and processing instructions.
(cherry picked from commit 7de4fcd44585f572acbcee23f5c7018b2b3f0983)
Co-authored-by: Serhiy Storchaka
---
Lib/test/test_xml_etree.py | 26 +++++++++++++++++++
...-05-17-02-25-56.gh-issue-149571.LNyuWJ.rst | 2 ++
Modules/_elementtree.c | 4 +++
3 files changed, 32 insertions(+)
create mode 100644 Misc/NEWS.d/next/Library/2026-05-17-02-25-56.gh-issue-149571.LNyuWJ.rst
diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py
index 3a41ea97a2e0a2..f43f1708a0fabd 100644
--- a/Lib/test/test_xml_etree.py
+++ b/Lib/test/test_xml_etree.py
@@ -3657,6 +3657,32 @@ def test_basic(self):
doc = ET.XML("a&b&c&")
self.assertEqual(''.join(doc.itertext()), 'a&b&c&')
+ def test_comment(self):
+ e = ET.Element('root')
+ e.text = 'before'
+ comment = ET.Comment('comment')
+ self.assertEqual(comment.text, 'comment')
+ comment.tail = 'after'
+ e.append(comment)
+ self.assertEqual(''.join(e.itertext()), 'beforeafter')
+ self.assertEqual(list(e.iter()), [e, comment])
+ self.assertEqual(list(e.iter('root')), [e])
+ self.assertEqual(''.join(comment.itertext()), '')
+ self.assertEqual(list(comment.iter()), [comment])
+
+ def test_processinginstruction(self):
+ e = ET.Element('root')
+ e.text = 'before'
+ pi = ET.PI('test', 'instruction')
+ self.assertEqual(pi.text, 'test instruction')
+ pi.tail = 'after'
+ e.append(pi)
+ self.assertEqual(''.join(e.itertext()), 'beforeafter')
+ self.assertEqual(list(e.iter()), [e, pi])
+ self.assertEqual(list(e.iter('root')), [e])
+ self.assertEqual(''.join(pi.itertext()), '')
+ self.assertEqual(list(pi.iter()), [pi])
+
def test_corners(self):
# single root, no subelements
a = ET.Element('a')
diff --git a/Misc/NEWS.d/next/Library/2026-05-17-02-25-56.gh-issue-149571.LNyuWJ.rst b/Misc/NEWS.d/next/Library/2026-05-17-02-25-56.gh-issue-149571.LNyuWJ.rst
new file mode 100644
index 00000000000000..2b71d9cf2200be
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-05-17-02-25-56.gh-issue-149571.LNyuWJ.rst
@@ -0,0 +1,2 @@
+Fix the C implementation of :meth:`xml.etree.ElementTree.Element.itertext`:
+it no longer emits text for comments and processing instructions.
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index eb69df22c6ef0a..f827274eeffba8 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -2297,6 +2297,10 @@ elementiter_next(PyObject *op)
return NULL;
}
if (it->gettext) {
+ if (elem->tag != Py_None && !PyUnicode_Check(elem->tag)) {
+ Py_DECREF(elem);
+ continue;
+ }
text = element_get_text(elem);
goto gettext;
}
From cc6fea844f614fb0ac779f84f5e83a260359b2de Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Wed, 27 May 2026 14:52:48 +0200
Subject: [PATCH 154/213] [3.15] gh-150389: Make perf profiler tests resilient
(GH-150437) (#150515)
---
Lib/test/test_perf_profiler.py | 166 +++++++++++++++++++++------------
1 file changed, 104 insertions(+), 62 deletions(-)
diff --git a/Lib/test/test_perf_profiler.py b/Lib/test/test_perf_profiler.py
index 597e6599352049..425c76dd01ed7c 100644
--- a/Lib/test/test_perf_profiler.py
+++ b/Lib/test/test_perf_profiler.py
@@ -34,6 +34,21 @@ def supports_trampoline_profiling():
raise unittest.SkipTest("perf trampoline profiling not supported")
+def _perf_env(**env_vars):
+ env = os.environ.copy()
+ # Keep perf's output stable regardless of the builder's perf config.
+ env.update(
+ {
+ "DEBUGINFOD_URLS": "",
+ "PERF_CONFIG": os.devnull,
+ }
+ )
+ if env_vars:
+ env.update(env_vars)
+ env["PYTHON_JIT"] = "0"
+ return env
+
+
class TestPerfTrampoline(unittest.TestCase):
def setUp(self):
super().setUp()
@@ -63,13 +78,12 @@ def baz():
"""
with temp_dir() as script_dir:
script = make_script(script_dir, "perftest", code)
- env = {**os.environ, "PYTHON_JIT": "0"}
with subprocess.Popen(
[sys.executable, "-Xperf", script],
text=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
- env=env,
+ env=_perf_env(),
) as process:
stdout, stderr = process.communicate()
@@ -132,13 +146,12 @@ def baz():
"""
with temp_dir() as script_dir:
script = make_script(script_dir, "perftest", code)
- env = {**os.environ, "PYTHON_JIT": "0"}
with subprocess.Popen(
[sys.executable, "-Xperf", script],
text=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
- env=env,
+ env=_perf_env(),
) as process:
stdout, stderr = process.communicate()
@@ -198,13 +211,12 @@ def test_trampoline_works_after_fork_with_many_code_objects(self):
"""
with temp_dir() as script_dir:
script = make_script(script_dir, "perftest", code)
- env = {**os.environ, "PYTHON_JIT": "0"}
with subprocess.Popen(
[sys.executable, "-Xperf", script],
text=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
- env=env,
+ env=_perf_env(),
) as process:
stdout, stderr = process.communicate()
@@ -242,13 +254,12 @@ def baz():
code = set_eval_hook + code
with temp_dir() as script_dir:
script = make_script(script_dir, "perftest", code)
- env = {**os.environ, "PYTHON_JIT": "0"}
with subprocess.Popen(
[sys.executable, script],
text=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
- env=env,
+ env=_perf_env(),
) as process:
stdout, stderr = process.communicate()
@@ -345,9 +356,12 @@ def perf_command_works():
"-c",
'print("hello")',
)
- env = {**os.environ, "PYTHON_JIT": "0"}
stdout = subprocess.check_output(
- cmd, cwd=script_dir, text=True, stderr=subprocess.STDOUT, env=env
+ cmd,
+ cwd=script_dir,
+ text=True,
+ stderr=subprocess.STDOUT,
+ env=_perf_env(),
)
except (subprocess.SubprocessError, OSError):
return False
@@ -359,43 +373,49 @@ def perf_command_works():
def run_perf(cwd, *args, use_jit=False, **env_vars):
- env = os.environ.copy()
- if env_vars:
- env.update(env_vars)
- env["PYTHON_JIT"] = "0"
+ env = _perf_env(**env_vars)
output_file = cwd + "/perf_output.perf"
- if not use_jit:
- base_cmd = (
- "perf",
- "record",
- "--no-buildid",
- "--no-buildid-cache",
- "-g",
- "--call-graph=fp",
- "-o", output_file,
- "--"
- )
+ base_cmd = [
+ "perf",
+ "record",
+ "--no-buildid",
+ "--no-buildid-cache",
+ "-g",
+ "--call-graph=dwarf,65528" if use_jit else "--call-graph=fp",
+ ]
+ if use_jit:
+ perf_commands = []
+ # Some builders have low perf_event_mlock_kb limits.
+ mmap_sizes = ("4M", "2M", "1M", "512K", "256K", "128K", None)
+ for mmap_size in mmap_sizes:
+ command = base_cmd.copy()
+ if mmap_size is not None:
+ command += ["-F99", "-k1", "-m", mmap_size]
+ else:
+ command += ["-F99", "-k1"]
+ command += ["-o", output_file, "--"]
+ perf_commands.append(command)
else:
- base_cmd = (
- "perf",
- "record",
- "--no-buildid",
- "--no-buildid-cache",
- "-g",
- "--call-graph=dwarf,65528",
- "-F99",
- "-k1",
- "-o",
- output_file,
- "--",
+ perf_commands = [base_cmd + ["-o", output_file, "--"]]
+
+ mmap_pages_error = "try again with a smaller value of -m/--mmap_pages"
+ for index, base_cmd in enumerate(perf_commands):
+ proc = subprocess.run(
+ base_cmd + list(args),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ env=env,
+ text=True,
)
- proc = subprocess.run(
- base_cmd + args,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- env=env,
- text=True,
- )
+ if (
+ proc.returncode
+ and use_jit
+ and index != len(perf_commands) - 1
+ and mmap_pages_error in proc.stderr
+ ):
+ continue
+ break
+
if proc.returncode:
print(proc.stderr, file=sys.stderr)
raise ValueError(f"Perf failed with return code {proc.returncode}")
@@ -425,16 +445,34 @@ def run_perf(cwd, *args, use_jit=False, **env_vars):
class TestPerfProfilerMixin:
- def run_perf(self, script_dir, perf_mode, script):
+ PERF_CAPTURE_ATTEMPTS = 3
+
+ def run_perf(self, script_dir, script, activate_trampoline=True):
raise NotImplementedError()
+ def run_perf_with_retries(
+ self, script_dir, script, expected_symbols=(), activate_trampoline=True
+ ):
+ stdout = stderr = ""
+ for _ in range(self.PERF_CAPTURE_ATTEMPTS):
+ stdout, stderr = self.run_perf(
+ script_dir, script, activate_trampoline=activate_trampoline
+ )
+ if activate_trampoline and any(
+ symbol not in stdout for symbol in expected_symbols
+ ):
+ continue
+ break
+ return stdout, stderr
+
def test_python_calls_appear_in_the_stack_if_perf_activated(self):
with temp_dir() as script_dir:
code = """if 1:
+ from itertools import repeat
+
def foo(n):
- x = 0
- for i in range(n):
- x += i
+ for _ in repeat(None, n):
+ pass
def bar(n):
foo(n)
@@ -442,23 +480,29 @@ def bar(n):
def baz(n):
bar(n)
- baz(10000000)
+ baz(40000000)
"""
script = make_script(script_dir, "perftest", code)
- stdout, stderr = self.run_perf(script_dir, script)
- self.assertEqual(stderr, "")
+ expected_symbols = [
+ f"py::foo:{script}",
+ f"py::bar:{script}",
+ f"py::baz:{script}",
+ ]
+ stdout, _ = self.run_perf_with_retries(
+ script_dir, script, expected_symbols
+ )
- self.assertIn(f"py::foo:{script}", stdout)
- self.assertIn(f"py::bar:{script}", stdout)
- self.assertIn(f"py::baz:{script}", stdout)
+ for expected_symbol in expected_symbols:
+ self.assertIn(expected_symbol, stdout)
def test_python_calls_do_not_appear_in_the_stack_if_perf_deactivated(self):
with temp_dir() as script_dir:
code = """if 1:
+ from itertools import repeat
+
def foo(n):
- x = 0
- for i in range(n):
- x += i
+ for _ in repeat(None, n):
+ pass
def bar(n):
foo(n)
@@ -466,13 +510,12 @@ def bar(n):
def baz(n):
bar(n)
- baz(10000000)
+ baz(40000000)
"""
script = make_script(script_dir, "perftest", code)
- stdout, stderr = self.run_perf(
+ stdout, _ = self.run_perf_with_retries(
script_dir, script, activate_trampoline=False
)
- self.assertEqual(stderr, "")
self.assertNotIn(f"py::foo:{script}", stdout)
self.assertNotIn(f"py::bar:{script}", stdout)
@@ -542,13 +585,12 @@ def compile_trampolines_for_all_functions():
with temp_dir() as script_dir:
script = make_script(script_dir, "perftest", code)
- env = {**os.environ, "PYTHON_JIT": "0"}
with subprocess.Popen(
[sys.executable, "-Xperf", script],
universal_newlines=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
- env=env,
+ env=_perf_env(),
) as process:
stdout, stderr = process.communicate()
From e565d12acb8fd14ad4432c25daf79882794cca60 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Wed, 27 May 2026 17:24:47 +0200
Subject: [PATCH 155/213] [3.15] gh-149861: Fix rule in match statement
`case_block` PEG grammar (GH-149908)
(cherry picked from commit 99c254e2f79a4197524bef61bf0d12251ee273e6)
Co-authored-by: Ivy Xu
---
Doc/reference/compound_stmts.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst
index a819c41d834aa7..63baefd33e88c5 100644
--- a/Doc/reference/compound_stmts.rst
+++ b/Doc/reference/compound_stmts.rst
@@ -620,7 +620,7 @@ The match statement is used for pattern matching. Syntax:
match_stmt: 'match' `subject_expr` ":" NEWLINE INDENT `case_block`+ DEDENT
subject_expr: `flexible_expression` "," [`flexible_expression_list` [',']]
: | `assignment_expression`
- case_block: 'case' `patterns` [`guard`] ":" `!block`
+ case_block: 'case' `patterns` [`guard`] ":" `suite`
.. note::
This section uses single quotes to denote
From f216c8963139bf858415e2d09cf938d3e29558df Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Wed, 27 May 2026 23:47:03 +0200
Subject: [PATCH 156/213] [3.15] gh-84353: Preserve non-UTF-8 filenames when
appending to ZipFile (GH-150091) (GH-150527)
Preserve non-UTF-8 filenames when appending to a ZipFile.
---------
(cherry picked from commit 24c6bbc92b6dd0ce9b7ff799049498299f70f97d)
Co-authored-by: Serhiy Storchaka
Co-authored-by: Gregory P. Smith
---
Lib/test/test_zipfile/test_core.py | 40 +++++++++++--------
Lib/zipfile/__init__.py | 8 +++-
...6-05-19-19-00-49.gh-issue-84353.ZU5zaQ.rst | 5 +++
3 files changed, 35 insertions(+), 18 deletions(-)
create mode 100644 Misc/NEWS.d/next/Library/2026-05-19-19-00-49.gh-issue-84353.ZU5zaQ.rst
diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py
index 30550263ad50aa..ffed328b171fda 100644
--- a/Lib/test/test_zipfile/test_core.py
+++ b/Lib/test/test_zipfile/test_core.py
@@ -3640,29 +3640,23 @@ def test_read_with_unsuitable_metadata_encoding(self):
def test_read_after_append(self):
newname = '\u56db' # Han 'four'
- expected_names = [name.encode('shift_jis').decode('cp437')
- for name in self.file_names[:2]] + self.file_names[2:]
- expected_names.append(newname)
- expected_content = (*self.file_content, b"newcontent")
+ newname2 = 'fünf' # representable in cp437, but still stored as UTF-8
+ expected_names = [*self.file_names, newname, newname2]
+ mojibake_expected_names = [name.encode('shift_jis').decode('cp437')
+ if i < 2 else name
+ for i, name in enumerate(expected_names)]
+ expected_content = (*self.file_content, b"newcontent", b"newcontent2")
with zipfile.ZipFile(TESTFN, "a") as zipfp:
zipfp.writestr(newname, "newcontent")
- self.assertEqual(sorted(zipfp.namelist()), sorted(expected_names))
+ zipfp.writestr(newname2, "newcontent2")
+ self.assertEqual(sorted(zipfp.namelist()), sorted(mojibake_expected_names))
with zipfile.ZipFile(TESTFN, "r") as zipfp:
- self._test_read(zipfp, expected_names, expected_content)
+ self._test_read(zipfp, mojibake_expected_names, expected_content)
with zipfile.ZipFile(TESTFN, "r", metadata_encoding='shift_jis') as zipfp:
- self.assertEqual(sorted(zipfp.namelist()), sorted(expected_names))
- for i, (name, content) in enumerate(zip(expected_names, expected_content)):
- info = zipfp.getinfo(name)
- self.assertEqual(info.filename, name)
- self.assertEqual(info.file_size, len(content))
- if i < 2:
- with self.assertRaises(zipfile.BadZipFile):
- zipfp.read(name)
- else:
- self.assertEqual(zipfp.read(name), content)
+ self._test_read(zipfp, expected_names, expected_content)
def test_write_with_metadata_encoding(self):
ZF = zipfile.ZipFile
@@ -3671,6 +3665,20 @@ def test_write_with_metadata_encoding(self):
"^metadata_encoding is only"):
ZF("nonesuch.zip", mode, metadata_encoding="shift_jis")
+ def test_add_comment(self):
+ with zipfile.ZipFile(TESTFN, "r") as zipfp:
+ mojibake_expected_names = zipfp.namelist()
+
+ with zipfile.ZipFile(TESTFN, "a") as zipfp:
+ zipfp.comment = b'comment'
+ self.assertEqual(zipfp.namelist(), mojibake_expected_names)
+
+ with zipfile.ZipFile(TESTFN, "r") as zipfp:
+ self._test_read(zipfp, mojibake_expected_names, self.file_content)
+
+ with zipfile.ZipFile(TESTFN, "r", metadata_encoding='shift_jis') as zipfp:
+ self._test_read(zipfp, self.file_names, self.file_content)
+
def test_cli_with_metadata_encoding(self):
errmsg = "Non-conforming encodings not supported with -c."
args = ["--metadata-encoding=shift_jis", "-c", "nonesuch", "nonesuch"]
diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py
index d91cb509a6ff4f..71e4dd4f6f625c 100644
--- a/Lib/zipfile/__init__.py
+++ b/Lib/zipfile/__init__.py
@@ -566,8 +566,12 @@ def FileHeader(self, zip64=None):
return header + filename + extra
def _encodeFilenameFlags(self):
+ if self.flag_bits & _MASK_UTF_FILENAME:
+ encoding = 'ascii'
+ else:
+ encoding = 'cp437'
try:
- return self.filename.encode('ascii'), self.flag_bits
+ return self.filename.encode(encoding), self.flag_bits & ~_MASK_UTF_FILENAME
except UnicodeEncodeError:
return self.filename.encode('utf-8'), self.flag_bits | _MASK_UTF_FILENAME
@@ -1812,7 +1816,7 @@ def _open_to_write(self, zinfo, force_zip64=False):
zinfo.compress_size = 0
zinfo.CRC = 0
- zinfo.flag_bits = 0x00
+ zinfo.flag_bits = _MASK_UTF_FILENAME
if zinfo.compress_type == ZIP_LZMA:
# Compressed data includes an end-of-stream (EOS) marker
zinfo.flag_bits |= _MASK_COMPRESS_OPTION_1
diff --git a/Misc/NEWS.d/next/Library/2026-05-19-19-00-49.gh-issue-84353.ZU5zaQ.rst b/Misc/NEWS.d/next/Library/2026-05-19-19-00-49.gh-issue-84353.ZU5zaQ.rst
new file mode 100644
index 00000000000000..84fb12e2abd81a
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-05-19-19-00-49.gh-issue-84353.ZU5zaQ.rst
@@ -0,0 +1,5 @@
+Preserve non-UTF-8 encoded filenames when appending to a
+:class:`zipfile.ZipFile`. Previously, non-ASCII names stored in a legacy
+encoding (without the UTF-8 flag bit set) could be corrupted when the
+central directory was rewritten: they were decoded as cp437 and then
+re-stored as UTF-8.
From 0e08bba32eb78b46493bd200879655d2d02e6b9d Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Thu, 28 May 2026 12:23:56 +0200
Subject: [PATCH 157/213] [3.15] Add prominent crash warning to `ctypes` docs
(GH-150410) (GH-150547)
(cherry picked from commit b53f6ca850b500621474e82931c3e7216d9a1cb1)
Co-authored-by: Stan Ulbrych
Co-authored-by: Petr Viktorin
---
Doc/library/ctypes.rst | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
index 438afa04c6630d..618ae89921c348 100644
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -14,6 +14,14 @@ used to wrap these libraries in pure Python.
.. include:: ../includes/optional-module.rst
+.. warning::
+
+ :mod:`!ctypes` provides low-level access to native libraries and the
+ process's memory, bypassing Python's safety mechanisms and allowing
+ execution of arbitrary native code.
+ Incorrect use can corrupt data and objects, reveal sensitive information,
+ cause crashes, or otherwise compromise the running process.
+
.. _ctypes-ctypes-tutorial:
@@ -198,10 +206,8 @@ argument values::
OSError: exception: access violation reading 0x00000020
>>>
-There are, however, enough ways to crash Python with :mod:`!ctypes`, so you
-should be careful anyway. The :mod:`faulthandler` module can be helpful in
-debugging crashes (e.g. from segmentation faults produced by erroneous C library
-calls).
+The :mod:`faulthandler` module can help debug crashes,
+such as segmentation faults produced by erroneous C library calls.
``None``, integers, bytes objects and (unicode) strings are the only native
Python objects that can directly be used as parameters in these function calls.
From 77666483b71561116f922b3847c044c631d8e647 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Thu, 28 May 2026 19:15:27 +0200
Subject: [PATCH 158/213] [3.15] gh-150046: Fix `test_add_python_opts` to
ignore `PYTHON*` env vars (GH-150089) (#150561)
gh-150046: Fix `test_add_python_opts` to ignore `PYTHON*` env vars (GH-150089)
Avoid the runtime environment from affecting the tests' behaviours,
which notably checks the warning filters which can be controlled by
various PYTHON environment variables.
(cherry picked from commit ef2246f788832a64ba7c5215c8e72f8e539e59b4)
Co-authored-by: Pradyun Gedam
---
Lib/test/test_regrtest.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py
index 02f6e0c74b5ce8..874c6bb76b1afe 100644
--- a/Lib/test/test_regrtest.py
+++ b/Lib/test/test_regrtest.py
@@ -2283,7 +2283,8 @@ def test_python_opts(self):
proc = subprocess.run(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
- text=True)
+ text=True,
+ env=support.make_clean_env())
self.assertEqual(proc.returncode, 0, proc)
def test_add_python_opts(self):
From 21fa311c044704a1638b2ae0dc480fd9f7f68159 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Fri, 29 May 2026 00:57:04 +0200
Subject: [PATCH 159/213] [3.15] gh-149029: Update SQLite to 3.53.1 for binary
releases (GH-149767) (#150559)
(cherry picked from commit 9242700c149c490c56d2a415b395b5f51d94a49a)
Co-authored-by: Adam Johnson
Co-authored-by: Ned Deily
---
Mac/BuildScript/build-installer.py | 6 +++---
.../2026-04-26-23-14-45.gh-issue-149029.oPTXP4.rst | 1 +
.../macOS/2026-04-26-23-15-09.gh-issue-149029.Lsx--T.rst | 1 +
Misc/externals.spdx.json | 8 ++++----
PCbuild/get_externals.bat | 2 +-
PCbuild/python.props | 2 +-
PCbuild/readme.txt | 2 +-
Platforms/Android/__main__.py | 2 +-
8 files changed, 13 insertions(+), 11 deletions(-)
create mode 100644 Misc/NEWS.d/next/Windows/2026-04-26-23-14-45.gh-issue-149029.oPTXP4.rst
create mode 100644 Misc/NEWS.d/next/macOS/2026-04-26-23-15-09.gh-issue-149029.Lsx--T.rst
diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py
index c5f92a99a1e076..e0e7076d681887 100755
--- a/Mac/BuildScript/build-installer.py
+++ b/Mac/BuildScript/build-installer.py
@@ -359,9 +359,9 @@ def library_recipes():
),
),
dict(
- name="SQLite 3.50.4",
- url="https://www.sqlite.org/2025/sqlite-autoconf-3500400.tar.gz",
- checksum="a3db587a1b92ee5ddac2f66b3edb41b26f9c867275782d46c3a088977d6a5b18",
+ name="SQLite 3.53.1",
+ url="https://www.sqlite.org/2026/sqlite-autoconf-3530100.tar.gz",
+ checksum="83e6b2020a034e9a7ad4a72feea59e1ad52f162e09cbd26735a3ffb98359fc4f",
extra_cflags=('-Os '
'-DSQLITE_ENABLE_FTS5 '
'-DSQLITE_ENABLE_FTS4 '
diff --git a/Misc/NEWS.d/next/Windows/2026-04-26-23-14-45.gh-issue-149029.oPTXP4.rst b/Misc/NEWS.d/next/Windows/2026-04-26-23-14-45.gh-issue-149029.oPTXP4.rst
new file mode 100644
index 00000000000000..6c4c6403b98984
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2026-04-26-23-14-45.gh-issue-149029.oPTXP4.rst
@@ -0,0 +1 @@
+Update Windows installer to ship with SQLite 3.53.1.
diff --git a/Misc/NEWS.d/next/macOS/2026-04-26-23-15-09.gh-issue-149029.Lsx--T.rst b/Misc/NEWS.d/next/macOS/2026-04-26-23-15-09.gh-issue-149029.Lsx--T.rst
new file mode 100644
index 00000000000000..157a70f5e3cefc
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-04-26-23-15-09.gh-issue-149029.Lsx--T.rst
@@ -0,0 +1 @@
+Update macOS installer to ship with SQLite version 3.53.1.
diff --git a/Misc/externals.spdx.json b/Misc/externals.spdx.json
index 9a571fba732ab4..080330c1cb75a5 100644
--- a/Misc/externals.spdx.json
+++ b/Misc/externals.spdx.json
@@ -91,21 +91,21 @@
"checksums": [
{
"algorithm": "SHA256",
- "checksumValue": "fb5ab81f27612b0a7b4861ba655906c76dc85ee969e7a4905d2075aff931e8d0"
+ "checksumValue": "15e8fc7dc059f7b156e53629540951c2691acd71e027f6f8f66dacab5c66c884"
}
],
- "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/sqlite-3.50.4.0.tar.gz",
+ "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/sqlite-3.53.1.0.tar.gz",
"externalRefs": [
{
"referenceCategory": "SECURITY",
- "referenceLocator": "cpe:2.3:a:sqlite:sqlite:3.50.4.0:*:*:*:*:*:*:*",
+ "referenceLocator": "cpe:2.3:a:sqlite:sqlite:3.53.1.0:*:*:*:*:*:*:*",
"referenceType": "cpe23Type"
}
],
"licenseConcluded": "NOASSERTION",
"name": "sqlite",
"primaryPackagePurpose": "SOURCE",
- "versionInfo": "3.50.4.0"
+ "versionInfo": "3.53.1.0"
},
{
"SPDXID": "SPDXRef-PACKAGE-tcl",
diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat
index 368bc489bfa968..f6ba3d0fef3a60 100644
--- a/PCbuild/get_externals.bat
+++ b/PCbuild/get_externals.bat
@@ -56,7 +56,7 @@ set libraries=%libraries% bzip2-1.0.8
if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.4.4
if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-3.5.6
set libraries=%libraries% mpdecimal-4.0.0
-set libraries=%libraries% sqlite-3.50.4.0
+set libraries=%libraries% sqlite-3.53.1.0
if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-9.0.3.0
if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-9.0.3.1
set libraries=%libraries% xz-5.8.1.1
diff --git a/PCbuild/python.props b/PCbuild/python.props
index f70321f887ef8c..edcda8fd8fc55d 100644
--- a/PCbuild/python.props
+++ b/PCbuild/python.props
@@ -98,7 +98,7 @@
- $(ExternalsDir)sqlite-3.50.4.0\
+ $(ExternalsDir)sqlite-3.53.1.0\$(ExternalsDir)bzip2-1.0.8\$(ExternalsDir)xz-5.8.1.1\$(ExternalsDir)libffi-3.4.4\
diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt
index 6aecbfff182dcb..ea8adf21c279a6 100644
--- a/PCbuild/readme.txt
+++ b/PCbuild/readme.txt
@@ -242,7 +242,7 @@ _ssl
again when building.
_sqlite3
- Wraps SQLite 3.50.4, which is itself built by sqlite3.vcxproj
+ Wraps SQLite 3.53.1, which is itself built by sqlite3.vcxproj
Homepage:
https://www.sqlite.org/
diff --git a/Platforms/Android/__main__.py b/Platforms/Android/__main__.py
index d2546cf76c206b..5c41aaca6ebf0b 100755
--- a/Platforms/Android/__main__.py
+++ b/Platforms/Android/__main__.py
@@ -220,7 +220,7 @@ def unpack_deps(host, prefix_dir, cache_dir):
"bzip2-1.0.8-3",
"libffi-3.4.4-3",
"openssl-3.5.6-0",
- "sqlite-3.50.4-0",
+ "sqlite-3.53.1-0",
"xz-5.4.6-1",
"zstd-1.5.7-2"
]:
From d842895a9d01dc34c448ca3e65d28aae469c8c23 Mon Sep 17 00:00:00 2001
From: Petr Viktorin
Date: Fri, 29 May 2026 10:09:38 +0200
Subject: [PATCH 160/213] [3.15] gh-141984: Reword docs on "enclosed" atom
grammar (GH-148622) (GH-150552)
Reorganize and reword the docs on atoms in parentheses, brackets and braces:
parenthesized groups, list/set/dict/tuple displays, and comprehensions.
(Generator expressions and yield atoms are left for later.)
In the spirit of better matching the underlying grammar, *comprehensions* are
covered separately from non-comprehension displays. Also, parenthesized forms
(with a single expression) and tuple displays are separated.
All sections are rewritten to start with simple cases and build up to the full
formal grammar.
(cherry picked from commit 55f25183263b9a52fa246817344cdb32d6c3d722)
Co-authored-by: Blaise Pabon
Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com>
---
Doc/reference/expressions.rst | 754 ++++++++++++++++++++++++++--------
Doc/tools/removed-ids.txt | 13 +
2 files changed, 592 insertions(+), 175 deletions(-)
diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst
index 68dcfc00bbd99c..12c1446e071240 100644
--- a/Doc/reference/expressions.rst
+++ b/Doc/reference/expressions.rst
@@ -48,9 +48,16 @@ Atoms
.. index:: atom
Atoms are the most basic elements of expressions.
-The simplest atoms are :ref:`names ` or literals.
-Forms enclosed in parentheses, brackets or braces are also categorized
-syntactically as atoms.
+The simplest atoms are :ref:`builtin constants `,
+:ref:`names ` and :ref:`literals `.
+More complex atoms are enclosed in paired delimiters:
+
+- ``()`` (parentheses): :ref:`groups `,
+ :ref:`tuple displays `,
+ :ref:`yield atoms `, and
+ :ref:`generator expressions `;
+- ``[]`` (square brackets): :ref:`list displays `;
+- ``{}`` (curly braces): :ref:`dictionary ` and :ref:`set ` displays.
Formally, the syntax for atoms is:
@@ -58,21 +65,25 @@ Formally, the syntax for atoms is:
:group: python-grammar
atom:
- | 'True'
- | 'False'
- | 'None'
- | '...'
+ | `builtin_constant`
| `identifier`
| `literal`
- | `enclosure`
- enclosure:
- | `parenth_form`
- | `list_display`
- | `dict_display`
- | `set_display`
- | `generator_expression`
+ | `parenthesized_enclosure`
+ | `bracketed_enclosure`
+ | `braced_enclosure`
+ parenthesized_enclosure:
+ | `group`
+ | `tuple`
| `yield_atom`
-
+ | `generator_expression`
+ bracketed_enclosure:
+ | `listcomp`
+ | `list`
+ braced_enclosure:
+ | `dictcomp`
+ | `dict`
+ | `setcomp`
+ | `set`
.. _atom-singletons:
@@ -99,6 +110,13 @@ Evaluation of these atoms yields the corresponding value.
^^^^^
SyntaxError: cannot assign to False
+Formally, the syntax for built-in constants is:
+
+.. grammar-snippet::
+ :group: python-grammar
+
+ builtin_constant: 'True' | 'False' | 'None' | '...'
+
.. _atom-identifiers:
Identifiers (Names)
@@ -201,6 +219,7 @@ The formal grammar for literals is:
literal: `strings` | `NUMBER`
+.. _literals-identity:
.. index::
triple: immutable; data; type
@@ -309,128 +328,134 @@ Formally:
strings: (`STRING` | `fstring`)+ | `tstring`+
-.. _parenthesized:
-
-Parenthesized forms
--------------------
-
.. index::
single: parenthesized form
- single: () (parentheses); tuple display
+ single: () (parentheses)
-A parenthesized form is an optional expression list enclosed in parentheses:
+.. _parenthesized-forms:
+.. _parenthesized:
-.. productionlist:: python-grammar
- parenth_form: "(" [`starred_expression`] ")"
+Parenthesized groups
+--------------------
-A parenthesized expression list yields whatever that expression list yields: if
-the list contains at least one comma, it yields a tuple; otherwise, it yields
-the single expression that makes up the expression list.
+A :dfn:`parenthesized group` is an expression enclosed in parentheses.
+The group evaluates to the same value as the expression inside.
-.. index:: pair: empty; tuple
+Groups are used to override or clarify
+:ref:`operator precedence `,
+in the same way as in math notation.
+For example::
-An empty pair of parentheses yields an empty tuple object. Since tuples are
-immutable, the same rules as for literals apply (i.e., two occurrences of the empty
-tuple may or may not yield the same object).
+ >>> 3 << 2 | 4
+ 12
+ >>> 3 << (2 | 4) # Override precedence of the | (bitwise OR)
+ 192
+ >>> (3 << 2) | 4 # Same as without parentheses (but more clear)
+ 12
-.. index::
- single: comma
- single: , (comma)
+Note that not everything in parentheses is a *group*.
+Specifically, a parenthesized group must include exactly one expression,
+and cannot end with a comma.
+See :ref:`tuple displays ` and
+:ref:`generator expressions ` for other parenthesized forms.
-Note that tuples are not formed by the parentheses, but rather by use of the
-comma. The exception is the empty tuple, for which parentheses *are*
-required --- allowing unparenthesized "nothing" in expressions would cause
-ambiguities and allow common typos to pass uncaught.
+Formally, the syntax for groups is:
+.. grammar-snippet::
+ :group: python-grammar
-.. _comprehensions:
+ group: '(' `assignment_expression` ')'
-Displays for lists, sets and dictionaries
------------------------------------------
+.. _displays-for-lists-sets-and-dictionaries:
+.. _displays:
+
+Container displays
+------------------
.. index:: single: comprehensions
-For constructing a list, a set or a dictionary Python provides special syntax
-called "displays", each of them in two flavors:
+For constructing builtin containers (lists, sets, tuples or dictionaries),
+Python provides special syntax called :dfn:`displays`.
+There are subtle differences between the four kinds of displays,
+detailed in the following sections.
+All displays, however, consist of comma-separated items enclosed in paired
+delimiters.
-* either the container contents are listed explicitly, or
+For example, a *list display* is a series of expressions enclosed in
+square brackets::
-* they are computed via a set of looping and filtering instructions, called a
- :dfn:`comprehension`.
+ >>> ["one", "two", "three"]
+ ['one', 'two', 'three']
+ >>> [1 + 2, 2 + 3]
+ [3, 5]
-.. index::
- single: for; in comprehensions
- single: if; in comprehensions
- single: async for; in comprehensions
+In list, tuple and dictionary (but not set) displays, the series may be empty::
-Common syntax elements for comprehensions are:
+ >>> [] # empty list
+ []
+ >>> () # empty tuple
+ ()
+ >>> {} # empty dictionary
+ {}
-.. productionlist:: python-grammar
- comprehension: `flexible_expression` `comp_for`
- comp_for: ["async"] "for" `target_list` "in" `or_test` [`comp_iter`]
- comp_iter: `comp_for` | `comp_if`
- comp_if: "if" `or_test` [`comp_iter`]
-
-The comprehension consists of a single expression followed by at least one
-:keyword:`!for` clause and zero or more :keyword:`!for` or :keyword:`!if`
-clauses. In this case, the elements of the new container are those that would
-be produced by considering each of the :keyword:`!for` or :keyword:`!if`
-clauses a block, nesting from left to right, and evaluating the expression to
-produce an element each time the innermost block is reached. If the expression
-is starred, the result will instead be unpacked to produce zero or more
-elements.
-
-However, aside from the iterable expression in the leftmost :keyword:`!for` clause,
-the comprehension is executed in a separate implicitly nested scope. This ensures
-that names assigned to in the target list don't "leak" into the enclosing scope.
+.. index:: pair: trailing; comma
-The iterable expression in the leftmost :keyword:`!for` clause is evaluated
-directly in the enclosing scope and then passed as an argument to the implicitly
-nested scope. Subsequent :keyword:`!for` clauses and any filter condition in the
-leftmost :keyword:`!for` clause cannot be evaluated in the enclosing scope as
-they may depend on the values obtained from the leftmost iterable. For example:
-``[x*y for x in range(10) for y in range(x, x+10)]``.
+If the series is not empty, the items may be followed by an additional comma,
+which has no effect::
-To ensure the comprehension always results in a container of the appropriate
-type, ``yield`` and ``yield from`` expressions are prohibited in the implicitly
-nested scope.
+ >>> ["one", "two", "three",] # note comma after "three"
+ ['one', 'two', 'three']
-.. index::
- single: await; in comprehensions
+.. note::
-Since Python 3.6, in an :keyword:`async def` function, an :keyword:`!async for`
-clause may be used to iterate over a :term:`asynchronous iterator`.
-A comprehension in an :keyword:`!async def` function may consist of either a
-:keyword:`!for` or :keyword:`!async for` clause following the leading
-expression, may contain additional :keyword:`!for` or :keyword:`!async for`
-clauses, and may also use :keyword:`await` expressions.
+ The trailing comma is often used for displays that span multiple lines
+ (using :ref:`implicit line joining `),
+ so when a future programmer adds a new entry at the end, they do not
+ need to modify an existing line::
-If a comprehension contains :keyword:`!async for` clauses, or if it contains
-:keyword:`!await` expressions or other asynchronous comprehensions anywhere except
-the iterable expression in the leftmost :keyword:`!for` clause, it is called an
-:dfn:`asynchronous comprehension`. An asynchronous comprehension may suspend the
-execution of the coroutine function in which it appears.
-See also :pep:`530`.
+ >>> [
+ ... 'one',
+ ... 'two',
+ ... 'three',
+ ... ]
+ ['one', 'two', 'three']
-.. versionadded:: 3.6
- Asynchronous comprehensions were introduced.
+At runtime, when a display is evaluated, the listed items are evaluated from
+left to right and placed into a new container of the appropriate type.
-.. versionchanged:: 3.8
- ``yield`` and ``yield from`` prohibited in the implicitly nested scope.
+.. index::
+ pair: iterable; unpacking
+ single: * (asterisk); in expression lists
-.. versionchanged:: 3.11
- Asynchronous comprehensions are now allowed inside comprehensions in
- asynchronous functions. Outer comprehensions implicitly become
- asynchronous.
+For tuple, list and set (but not dict) displays, any item in the display may
+be prefixed with an asterisk (``*``).
+This denotes :ref:`iterable unpacking `.
+At runtime, the asterisk-prefixed expression must evaluate to an iterable,
+whose contents are inserted into the container at the location of
+the unpacking. For example::
+
+ >>> numbers = (1, 2)
+ >>> [*numbers, 'word', *numbers]
+ [1, 2, 'word', 1, 2]
+
+Dictionary displays use a similar mechanism called
+*dictionary unpacking*, denoted with a double
+asterisk (``**``).
+See :ref:`dict` for details.
+
+A more advanced form of displays are :dfn:`comprehensions`, where items are
+computed via a set of looping and filtering instructions.
+See the :ref:`comprehensions` section for details.
-.. versionchanged:: 3.15
- Unpacking with the ``*`` operator is now allowed in the expression.
+.. versionadded:: 3.5
+ Iterable and dictionary unpacking in displays, originally proposed
+ by :pep:`448`.
.. _lists:
List displays
--------------
+^^^^^^^^^^^^^
.. index::
pair: list; display
@@ -440,23 +465,30 @@ List displays
single: [] (square brackets); list expression
single: , (comma); expression list
-A list display is a possibly empty series of expressions enclosed in square
-brackets:
+A :dfn:`list display` is a possibly empty series of expressions enclosed in
+square brackets. For example::
-.. productionlist:: python-grammar
- list_display: "[" [`flexible_expression_list` | `comprehension`] "]"
+ >>> ["one", "two", "three"]
+ ['one', 'two', 'three']
+ >>> ["one"] # One-element list
+ ['one']
+ >>> [] # empty list
+ []
+
+See :ref:`displays` for general information on displays.
+
+The formal grammar for list displays is:
-A list display yields a new list object, the contents being specified by either
-a list of expressions or a comprehension. When a comma-separated list of
-expressions is supplied, its elements are evaluated from left to right and
-placed into the list object in that order. When a comprehension is supplied,
-the list is constructed from the elements resulting from the comprehension.
+.. grammar-snippet::
+ :group: python-grammar
+
+ list: '[' [`flexible_expression_list`] ']'
.. _set:
Set displays
-------------
+^^^^^^^^^^^^
.. index::
pair: set; display
@@ -465,26 +497,94 @@ Set displays
single: {} (curly brackets); set expression
single: , (comma); expression list
-A set display is denoted by curly braces and distinguishable from dictionary
-displays by the lack of colons separating keys and values:
+A :dfn:`set display` is a *non-empty* series of expressions enclosed in
+curly braces. For example::
+
+ >>> {"one", "two", "three"}
+ {'one', 'three', 'two'}
+ >>> {"one"} # One-element set
+ {'one'}
+
+See :ref:`displays` for general information on displays.
+
+There is no special syntax for the empty set.
+The ``{}`` literal is a :ref:`dictionary display ` that constructs an
+empty dictionary.
+Call :class:`set() ` with no arguments to get an empty set.
+
+The formal grammar for set displays is:
+
+.. grammar-snippet::
+ :group: python-grammar
+
+ set: '{' `flexible_expression_list` '}'
-.. productionlist:: python-grammar
- set_display: "{" (`flexible_expression_list` | `comprehension`) "}"
-A set display yields a new mutable set object, the contents being specified by
-either a sequence of expressions or a comprehension. When a comma-separated
-list of expressions is supplied, its elements are evaluated from left to right
-and added to the set object. When a comprehension is supplied, the set is
-constructed from the elements resulting from the comprehension.
+.. index::
+ single: tuple display
+ single: comma
+ single: , (comma)
+
+.. _tuple-display:
+
+.. index:: pair: empty; tuple
+
+Tuple displays
+^^^^^^^^^^^^^^
+
+A :dfn:`tuple display` is a series of expressions enclosed in
+parentheses. For example::
-An empty set cannot be constructed with ``{}``; this literal constructs an empty
-dictionary.
+ >>> (1, 2)
+ (1, 2)
+ >>> () # an empty tuple
+ ()
+
+See :ref:`displays` for general information on displays.
+
+To avoid ambiguity, if a tuple display has exactly one element,
+it requires a trailing comma.
+Without it, you get a :ref:`parenthesized group `::
+
+ >>> ('single',) # single-element tuple
+ ('single',)
+ >>> ('single') # no comma: single string
+ 'single'
+
+To put it in other words, a tuple display is a parenthesized list of either:
+
+- two or more comma-separated expressions, or
+- zero or more expressions, each followed by a comma.
+
+Since tuples are immutable, :ref:`object identity rules for literals `
+also apply to tuples: at runtime, two occurrences of tuples with the same
+values may or may not yield the same object.
+
+.. note::
+ Python's syntax also includes :ref:`expression lists `,
+ where a comma-separated list of expressions is *not* enclosed in parentheses
+ but evaluates to tuple.
+
+ In other words, when it comes to tuple syntax, the comma is more important
+ that the use of parentheses.
+ Only the empty tuple is spelled without a comma.
+
+
+The formal grammar for tuple displays is:
+
+.. grammar-snippet::
+ :group: python-grammar
+
+ tuple:
+ | '(' `flexible_expression` (',' `flexible_expression`)+ [','] ')'
+ | '(' `flexible_expression` ',' ')'
+ | '(' ')'
.. _dict:
Dictionary displays
--------------------
+^^^^^^^^^^^^^^^^^^^
.. index::
pair: dictionary; display
@@ -495,59 +595,149 @@ Dictionary displays
single: : (colon); in dictionary expressions
single: , (comma); in dictionary displays
-A dictionary display is a possibly empty series of dict items (key/value pairs)
-enclosed in curly braces:
+A :dfn:`dictionary display` is a possibly empty series of :dfn:`dict items`
+enclosed in curly braces.
+Each dict item is a colon-separated pair of expressions: the :dfn:`key`
+and its associated :dfn:`value`.
+For example::
-.. productionlist:: python-grammar
- dict_display: "{" [`dict_item_list` | `dict_comprehension`] "}"
- dict_item_list: `dict_item` ("," `dict_item`)* [","]
- dict_comprehension: `dict_item` `comp_for`
- dict_item: `expression` ":" `expression` | "**" `or_expr`
+ >>> {1: 'one', 2: 'two'}
+ {1: 'one', 2: 'two'}
-A dictionary display yields a new dictionary object.
+At runtime, when a dictionary comprehension is evaluated, the expressions
+are evaluated from left to right.
+Each key object is used as a key into the dictionary to store the
+corresponding value.
+This means that you can specify the same key multiple times in the
+comprehension, and the final dictionary's value for a given key will be the
+last one given.
+For example::
-If a comma-separated sequence of dict items is given, they are evaluated
-from left to right to define the entries of the dictionary: each key object is
-used as a key into the dictionary to store the corresponding value. This means
-that you can specify the same key multiple times in the dict item list, and the
-final dictionary's value for that key will be the last one given.
+ >>> {
+ ... 1: 'this will be overridden',
+ ... 2: 'two',
+ ... 1: 'also overridden',
+ ... 1: 'one',
+ ... }
+ {1: 'one', 2: 'two'}
.. index::
unpacking; dictionary
single: **; in dictionary displays
-A double asterisk ``**`` denotes :dfn:`dictionary unpacking`.
-Its operand must be a :term:`mapping`. Each mapping item is added
-to the new dictionary. Later values replace values already set by
-earlier dict items and earlier dictionary unpackings.
+.. _dict-unpacking:
+
+Instead of a key-value pair, a dict item may be an expression prefixed by
+a double asterisk ``**``. This denotes :dfn:`dictionary unpacking`.
+At runtime, the expression must evaluate to a :term:`mapping`;
+each item of the mapping is added to the new dictionary.
+As with key-value pairs, later values replace values already set by
+earlier items and unpackings.
+This may be used to override a set of defaults::
+
+ >>> defaults = {'color': 'blue', 'count': 8}
+ >>> overrides = {'color': 'yellow'}
+ >>> {**defaults, **overrides}
+ {'color': 'yellow', 'count': 8}
.. versionadded:: 3.5
Unpacking into dictionary displays, originally proposed by :pep:`448`.
-A dict comprehension may take one of two forms:
+The formal grammar for dict displays is:
-- The first form uses two expressions separated with a colon followed by the
- usual "for" and "if" clauses. When the comprehension is run, the resulting
- key and value elements are inserted in the new dictionary in the order they
- are produced.
+.. grammar-snippet::
+ :group: python-grammar
-- The second form uses a single expression prefixed by the ``**`` dictionary
- unpacking operator followed by the usual "for" and "if" clauses. When the
- comprehension is evaluated, the expression is evaluated and then unpacked,
- inserting zero or more key/value pairs into the new dictionary.
+ dict: '{' [`double_starred_kvpairs`] '}'
+ double_starred_kvpairs: ','.`double_starred_kvpair`+ [',']
+ double_starred_kvpair: '**' `or_expr` | `kvpair`
+ kvpair: `expression` ':' `expression`
-Both forms of dictionary comprehension retain the property that if the same key
-is specified multiple times, the associated value in the resulting dictionary
-will be the last one specified.
-.. index:: pair: immutable; object
- hashable
+.. index::
+ single: comprehensions
+ single: for; in comprehensions
+
+.. _comprehensions:
+
+Comprehensions
+--------------
+
+List, set and dictionary :dfn:`comprehensions` are a form of
+:ref:`container displays ` where items are computed via a set of
+looping and filtering instructions rather than listed explicitly.
+
+In its simplest form, a comprehension consists of a single expression
+followed by a :keyword:`!for` clause.
+The :keyword:`!for` clause has the same syntax as the header of a
+:ref:`for statement `, without a trailing colon.
+
+For example, a list of the first ten squares is::
+
+ >>> [x**2 for x in range(10)]
+ [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
+
+At run time, a list comprehension creates a new list.
+The expression after :keyword:`!in` must evaluate to an :term:`iterable`.
+For each element of this iterable, the element is bound to the :keyword:`!for`
+clause's target as in a :keyword:`!for` statement, then the expression
+before :keyword:`!for` is evaluated with the target in scope and the result
+is added to the new list.
+Thus, the example above is roughly equivalent to defining and calling
+the following function::
+
+ def make_list_of_squares(iterable):
+ result = []
+ for x in iterable:
+ result.append(x**2)
+ return result
+
+ make_list_of_squares(range(10))
+
+Set comprehensions work similarly.
+For example, here is a set of lowercase letters::
+
+ >>> {x.lower() for x in ['a', 'A', 'b', 'C']}
+ {'c', 'a', 'b'}
+
+At run time, this corresponds roughly to calling this function::
-Restrictions on the types of the key values are listed earlier in section
-:ref:`types`. (To summarize, the key type should be :term:`hashable`, which excludes
-all mutable objects.) Clashes between duplicate keys are not detected; the last
-value (textually rightmost in the display) stored for a given key value
-prevails.
+ def make_lowercase_set(iterable):
+ result = set(iterable)
+ for x in iterable:
+ result.append(x.lower())
+ return result
+
+ make_lowercase_set(['a', 'A', 'b', 'C'])
+
+Dictionary comprehensions start with a colon-separated key-value pair instead
+of an expression. For example::
+
+ >>> {func.__name__: func for func in [print, hex, any]}
+ {'print': ,
+ 'hex': ,
+ 'any': }
+
+At run time, this corresponds roughly to::
+
+ def make_dict_mapping_names_to_functions(iterable):
+ result = {}
+ for func in iterable:
+ result[func.__name__] = func
+ return result
+
+ iterable([print, hex, any])
+
+As in other kinds of dictionary displays, the same key may be specified
+multiple times.
+Earlier values are overwritten by ones that are evaluated later.
+
+There are no *tuple comprehensions*.
+A similar syntax is instead used for :ref:`generator expressions `,
+from which you can construct a tuple like this::
+
+ >>> tuple(x**2 for x in range(10))
+ (0, 1, 4, 9, 16, 25, 36, 49, 64, 81)
.. versionchanged:: 3.8
Prior to Python 3.8, in dict comprehensions, the evaluation order of key
@@ -555,8 +745,206 @@ prevails.
the key. Starting with 3.8, the key is evaluated before the value, as
proposed by :pep:`572`.
-.. versionchanged:: 3.15
- Unpacking with the ``**`` operator is now allowed in dictionary comprehensions.
+
+.. index:: single: if; in comprehensions
+
+Filtering in comprehensions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The :keyword:`!for` clause may be followed by an :keyword:`!if` clause
+with an expression.
+
+For example, a list of names from the :mod:`math` module
+that start with ``f`` is::
+
+ >>> [name for name in vars(math) if name.startswith('f')]
+ ['fabs', 'factorial', 'floor', 'fma', 'fmod', 'frexp', 'fsum']
+
+At run time, the expression after :keyword:`!if` is evaluated before
+each element is added to the resulting container, and if it is false,
+the element is skipped.
+Thus, the above example roughly corresponds to defining and calling the
+following function::
+
+ def get_math_f_names(iterable):
+ result = []
+ for name in iterable:
+ if name.startswith('f'):
+ result.append(name)
+ return result
+
+ get_math_f_names(vars(math))
+
+Filtering is a special case of more complex comprehensions.
+See the next section for a more formal description.
+
+
+.. _complex-comprehensions:
+
+Complex comprehensions
+^^^^^^^^^^^^^^^^^^^^^^
+
+Generally, a comprehension's initial :keyword:`!for` clause may be followed by
+zero or more additional :keyword:`!for` or :keyword:`!if` clauses.
+For example, here is a list of names exposed by two Python modules,
+filtered to only include names that start with ``a``::
+
+ >>> import array
+ >>> import math
+ >>> [
+ ... name
+ ... for module in [array, math]
+ ... for name in vars(module)
+ ... if name.startswith('a')
+ ... ]
+ ['array', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh']
+
+At run time, this roughly corresponds to defining and calling::
+
+ def get_a_names(iterable):
+ result = []
+ for module in iterable:
+ for name in vars(module):
+ if name.startswith('a'):
+ result.append(name)
+ return result
+
+ get_a_names([array, math])
+
+The elements of the new container are those that would be produced by
+considering each of the :keyword:`!for` or :keyword:`!if` clauses a block,
+nesting from left to right, and evaluating the expression to produce an
+element (or dictionary entry) each time the innermost block is reached.
+
+Aside from the iterable expression in the leftmost :keyword:`!for` clause,
+the comprehension is executed in a separate implicitly nested scope.
+This ensures that names assigned to in the target list don't "leak" into
+the enclosing scope.
+For example::
+
+ >>> x = 'old value'
+ >>> [x**2 for x in range(10)] # this `x` is local to the comprehension
+ >>> x
+ 'old value'
+
+The iterable expression in the leftmost :keyword:`!for` clause is evaluated
+directly in the enclosing scope and then passed as an argument to the implicitly
+nested scope.
+
+Subsequent :keyword:`!for` clauses and any filter condition in the
+leftmost :keyword:`!for` clause cannot be evaluated in the enclosing scope as
+they may depend on the values obtained from the leftmost iterable.
+
+To ensure the comprehension always results in a container of the appropriate
+type, ``yield`` and ``yield from`` expressions are prohibited in the implicitly
+nested scope.
+
+:ref:`Assignment expressions ` are not allowed
+inside comprehension iterable expressions (that is, the expressions after
+the :keyword:`!in` keyword), nor anywhere within comprehensions that
+appear directly in a class definition.
+
+.. versionchanged:: 3.8
+ ``yield`` and ``yield from`` prohibited in the implicitly nested scope.
+
+
+Unpacking in comprehensions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If the expression of a list or set comprehension is starred, the result will
+be :ref:`unpacked ` to produce
+zero or more elements.
+
+This is often used for "flattening" lists, for example::
+
+ >>> students = ['Petr', 'Blaise', 'Jarka']
+ >>> teachers = ['Salim', 'Bartosz']
+ >>> lists_of_people = [students, teachers]
+ >>> [*people for people in lists_of_people]
+ ['Petr', 'Blaise', 'Jarka', 'Salim', 'Bartosz']
+
+At run time, this comprehension roughly corresponds to::
+
+ def flatten_names(lists_of_people):
+ result = []
+ for people in lists_of_people:
+ result.extend(people)
+ return result
+
+In dict comprehensions, a double-starred expression will be evaluated and
+then unpacked using :ref:`dictionary unpacking `,
+inserting zero or more key/value pairs into the new dictionary.
+As in other kinds of dictionary displays, if the same key is specified
+multiple times, the associated value in the resulting dictionary
+will be the last one specified.
+
+For example::
+
+ >>> system_defaults = {'color': 'blue', 'count': 8}
+ >>> user_defaults = {'color': 'yellow'}
+ >>> overrides = {'count': 5}
+
+ >>> configuration_sets = [system_defaults, user_defaults, overrides]
+
+ >>> {**d for d in configuration_sets}
+ {'color': 'yellow', 'count': 5}
+
+.. versionadded:: 3.15
+
+ Unpacking in comprehensions using the ``*`` and ``**`` operators
+ was introduced in :pep:`798`.
+
+
+.. index::
+ single: async for; in comprehensions
+ single: await; in comprehensions
+
+Asynchronous comprehensions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In an :keyword:`async def` function, an :keyword:`!async for`
+clause may be used to iterate over a :term:`asynchronous iterator`.
+A comprehension in an :keyword:`!async def` function may consist of either a
+:keyword:`!for` or :keyword:`!async for` clause following the leading
+expression, may contain additional :keyword:`!for` or :keyword:`!async for`
+clauses, and may also use :keyword:`await` expressions.
+
+If a comprehension contains :keyword:`!async for` clauses, or if it contains
+:keyword:`!await` expressions or other asynchronous comprehensions anywhere except
+the iterable expression in the leftmost :keyword:`!for` clause, it is called an
+:dfn:`asynchronous comprehension`. An asynchronous comprehension may suspend the
+execution of the coroutine function in which it appears.
+
+.. versionadded:: 3.6
+
+ Asynchronous comprehensions were introduced in :pep:`530`.
+
+.. versionchanged:: 3.11
+ Asynchronous comprehensions are now allowed inside comprehensions in
+ asynchronous functions. Outer comprehensions implicitly become
+ asynchronous.
+
+.. _comprehension-grammar:
+
+Formal grammar for comprehensions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The formal grammar for comprehensions is:
+
+.. grammar-snippet::
+ :group: python-grammar
+
+ listcomp: '[' `comprehension` ']'
+ setcomp: '{' `comprehension` '}'
+ comprehension: `flexible_expression` `for_if_clause`+
+
+ dictcomp:
+ | '{' `kvpair` `for_if_clause`+ '}'
+ | '{' '**' `expression` `for_if_clause`+ '}'
+
+ for_if_clause:
+ | ['async'] 'for' `target_list` 'in' `or_test` ('if' `or_test`)*
+
.. _genexpr:
@@ -571,7 +959,7 @@ Generator expressions
A generator expression is a compact generator notation in parentheses:
.. productionlist:: python-grammar
- generator_expression: "(" `flexible_expression` `comp_for` ")"
+ generator_expression: "(" `comprehension` ")"
A generator expression yields a new generator object. Its syntax is the same as
for comprehensions, except that it is enclosed in parentheses instead of
@@ -2178,6 +2566,10 @@ functions created with lambda expressions cannot contain statements or
annotations.
+.. index::
+ single: comma
+ single: , (comma)
+
.. _exprlists:
Expression lists
@@ -2202,12 +2594,32 @@ containing at least one comma yields a tuple. The length of
the tuple is the number of expressions in the list. The expressions are
evaluated from left to right.
+.. index:: pair: trailing; comma
+
+A trailing comma is required only to create a one-item tuple,
+such as ``1,``; it is optional in all other cases.
+A single expression without a
+trailing comma doesn't create a tuple, but rather yields the value of that
+expression. (To create an empty tuple, use an empty pair of parentheses:
+``()``.)
+
+
+.. _iterable-unpacking:
+
.. index::
pair: iterable; unpacking
single: * (asterisk); in expression lists
-An asterisk ``*`` denotes :dfn:`iterable unpacking`. Its operand must be
-an :term:`iterable`. The iterable is expanded into a sequence of items,
+Iterable unpacking
+------------------
+
+In an expression list or tuple, list or set display, any expression
+may be prefixed with an asterisk (``*``).
+This denotes :dfn:`iterable unpacking`.
+
+At runtime, the asterisk-prefixed expression must evaluate
+to an :term:`iterable`.
+The iterable is expanded into a sequence of items,
which are included in the new tuple, list, or set, at the site of
the unpacking.
@@ -2217,15 +2629,6 @@ the unpacking.
.. versionadded:: 3.11
Any item in an expression list may be starred. See :pep:`646`.
-.. index:: pair: trailing; comma
-
-A trailing comma is required only to create a one-item tuple,
-such as ``1,``; it is optional in all other cases.
-A single expression without a
-trailing comma doesn't create a tuple, but rather yields the value of that
-expression. (To create an empty tuple, use an empty pair of parentheses:
-``()``.)
-
.. _evalorder:
@@ -2249,6 +2652,7 @@ their suffixes::
.. _operator-summary:
+.. _operator-precedence:
Operator precedence
===================
diff --git a/Doc/tools/removed-ids.txt b/Doc/tools/removed-ids.txt
index 5e3ef2efe271fd..2d5917f4d240f5 100644
--- a/Doc/tools/removed-ids.txt
+++ b/Doc/tools/removed-ids.txt
@@ -5,3 +5,16 @@ c-api/allocation.html: deprecated-aliases
c-api/file.html: deprecated-api
library/asyncio-task.html: terminating-a-task-group
+
+## Old names for grammar tokens
+reference/expressions.html: grammar-token-python-grammar-comp_for
+reference/expressions.html: grammar-token-python-grammar-comp_if
+reference/expressions.html: grammar-token-python-grammar-comp_iter
+reference/expressions.html: grammar-token-python-grammar-dict_comprehension
+reference/expressions.html: grammar-token-python-grammar-dict_display
+reference/expressions.html: grammar-token-python-grammar-dict_item
+reference/expressions.html: grammar-token-python-grammar-dict_item_list
+reference/expressions.html: grammar-token-python-grammar-enclosure
+reference/expressions.html: grammar-token-python-grammar-list_display
+reference/expressions.html: grammar-token-python-grammar-parenth_form
+reference/expressions.html: grammar-token-python-grammar-set_display
From b980552f348aa4a9648280e10cd82362f0434204 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Fri, 29 May 2026 15:10:56 +0200
Subject: [PATCH 161/213] [3.15] gh-150107: Fix asyncio sendfile fallback
ignoring non-zero offset (GH-150270) (#150570)
gh-150107: Fix asyncio sendfile fallback ignoring non-zero offset (GH-150270)
(cherry picked from commit c72d5ea638731ec29723ded2d26ec7f997f06f17)
Co-authored-by: Grant Herman
Co-authored-by: Victor Stinner
---
Lib/asyncio/base_events.py | 5 +-
Lib/asyncio/proactor_events.py | 3 +-
Lib/asyncio/unix_events.py | 18 +++---
Lib/asyncio/windows_events.py | 3 +
Lib/test/test_asyncio/test_sendfile.py | 55 +++++++++++++++++++
...-05-22-17-09-28.gh-issue-150107.GD72-D.rst | 3 +
6 files changed, 73 insertions(+), 14 deletions(-)
create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-22-17-09-28.gh-issue-150107.GD72-D.rst
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index 7a6837546d930f..b651f40dc4a1ec 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -968,7 +968,7 @@ async def _sock_sendfile_native(self, sock, file, offset, count):
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)
@@ -1285,7 +1285,6 @@ async def sendfile(self, transport, file, offset=0, count=None,
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)
@@ -1294,7 +1293,7 @@ async def _sendfile_native(self, transp, file, offset, count):
"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)
diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py
index 2dc1569d780791..cf2902b4c76559 100644
--- a/Lib/asyncio/proactor_events.py
+++ b/Lib/asyncio/proactor_events.py
@@ -756,8 +756,7 @@ async def _sock_sendfile_native(self, sock, file, offset, count):
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/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index 49e8067ee7b4e5..ab57efd48fce65 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -384,12 +384,12 @@ def _sock_sendfile_native_impl(self, fut, registered_fd, sock, fileno,
# 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
@@ -423,20 +423,20 @@ def _sock_sendfile_native_impl(self, fut, registered_fd, sock, fileno,
# 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
@@ -447,9 +447,9 @@ def _sock_sendfile_native_impl(self, fut, registered_fd, sock, fileno,
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/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py
index 5f75b17d8ca649..0bf7732136f1f8 100644
--- a/Lib/asyncio/windows_events.py
+++ b/Lib/asyncio/windows_events.py
@@ -610,6 +610,9 @@ def sendfile(self, sock, file, offset, count):
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/Lib/test/test_asyncio/test_sendfile.py b/Lib/test/test_asyncio/test_sendfile.py
index dcd963b3355ef8..7afd7de3bb936e 100644
--- a/Lib/test/test_asyncio/test_sendfile.py
+++ b/Lib/test/test_asyncio/test_sendfile.py
@@ -228,6 +228,61 @@ def test_sock_sendfile_zero_size(self):
self.assertEqual(ret, 0)
self.assertEqual(self.file.tell(), 0)
+ def check_sock_sendfile_offset(self, data, offset, force_fallback=False):
+ sock, proto = self.prepare_socksendfile()
+ with tempfile.TemporaryFile() as f:
+ f.write(data)
+ f.flush()
+ self.assertEqual(f.tell(), len(data))
+
+ if force_fallback:
+ async def _sock_sendfile_fail(sock, file, offset, count):
+ raise asyncio.exceptions.SendfileNotAvailableError()
+ with support.swap_attr(self.loop, '_sock_sendfile_native', _sock_sendfile_fail):
+ ret = self.run_loop(self.loop.sock_sendfile(sock, f, offset, None))
+ else:
+ ret = self.run_loop(self.loop.sock_sendfile(sock, f, offset, None))
+
+ self.assertEqual(f.tell(), len(data))
+
+ sock.close()
+ self.run_loop(proto.wait_closed())
+
+ self.assertEqual(ret, len(data) - offset)
+
+
+ def test_sock_sendfile_offset(self):
+ data = b'abcdef'
+ for offset in (0, len(data) // 2, len(data)):
+ for force_fallback in (False, True):
+ with self.subTest(offset=offset, force_fallback=force_fallback):
+ self.check_sock_sendfile_offset(data, offset, force_fallback)
+
+ def check_sendfile_offset(self, offset, fallback):
+ srv_proto, cli_proto = self.prepare_sendfile()
+ self.file.seek(123)
+ coro = self.loop.sendfile(cli_proto.transport, self.file, offset, fallback=fallback)
+ try:
+ ret = self.run_loop(coro)
+ except asyncio.SendfileNotAvailableError:
+ if fallback:
+ raise
+ cli_proto.transport.close()
+ self.run_loop(srv_proto.done)
+ return
+ cli_proto.transport.close()
+ self.run_loop(srv_proto.done)
+ self.assertEqual(ret, len(self.DATA) - offset)
+ self.assertEqual(srv_proto.nbytes, len(self.DATA) - offset)
+ self.assertEqual(srv_proto.data, self.DATA[offset:])
+ self.assertEqual(self.file.tell(), len(self.DATA))
+
+ def test_sendfile_offset(self):
+ for offset in (0, len(self.DATA) // 2, len(self.DATA)):
+ for fallback in (False, True):
+ with self.subTest(offset=offset, fallback=fallback):
+ self.check_sendfile_offset(offset, fallback)
+
def test_sock_sendfile_mix_with_regular_send(self):
buf = b"mix_regular_send" * (4 * 1024) # 64 KiB
sock, proto = self.prepare_socksendfile()
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-22-17-09-28.gh-issue-150107.GD72-D.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-22-17-09-28.gh-issue-150107.GD72-D.rst
new file mode 100644
index 00000000000000..a13f249e48cc02
--- /dev/null
+++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-22-17-09-28.gh-issue-150107.GD72-D.rst
@@ -0,0 +1,3 @@
+:mod:`asyncio`: ``sendfile()`` and ``sock_sendfile()`` event loop methods
+now call ``file.seek(offset)`` if *file* has a ``seek()`` method,
+even if *offset* is ``0`` (default value).
From 59e709b17ee84aa407ca9e0a3994916cb48ff909 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Fri, 29 May 2026 21:07:29 +0200
Subject: [PATCH 162/213] [3.15] Add a security warning about `pydoc`'s HTTP
server (#150573)
(cherry picked from commit 5535c1f9c08e929f96fa5d798277e3a2c91ed12a)
Co-authored-by: Stan Ulbrych
---
Doc/library/pydoc.rst | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Doc/library/pydoc.rst b/Doc/library/pydoc.rst
index f236eba8457657..a0cfb440a36ffa 100644
--- a/Doc/library/pydoc.rst
+++ b/Doc/library/pydoc.rst
@@ -68,6 +68,11 @@ will start a HTTP server on port 1234, allowing you to browse the
documentation at ``http://localhost:1234/`` in your preferred web browser.
Specifying ``0`` as the port number will select an arbitrary unused port.
+.. warning::
+
+ The :mod:`!pydoc` HTTP server is intended for local use during
+ development and is not suitable for production use.
+
:program:`python -m pydoc -n ` will start the server listening at the given
hostname. By default the hostname is 'localhost' but if you want the server to
be reached from other machines, you may want to change the host name that the
From a2ba8b192ed6c02e3a3943ad1551c1b38d1cc599 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Fri, 29 May 2026 21:48:48 +0200
Subject: [PATCH 163/213] [3.15] gh-150403: Document frozendict in language
reference Mappings section (GH-150404) (GH-150590)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
(cherry picked from commit 779694faba3e80b944f528a56e9b756b55637541)
Co-authored-by: Oral Ersoy Dokumacı
---
Doc/reference/datamodel.rst | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index aef5bbe151cfeb..e13b2c9db490a1 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -496,7 +496,7 @@ subscript notation ``a[k]`` selects the item indexed by ``k`` from the mapping
:keyword:`del` statements. The built-in function :func:`len` returns the number
of items in a mapping.
-There is currently a single intrinsic mapping type:
+There are two intrinsic mapping types:
Dictionaries
@@ -535,6 +535,20 @@ module.
an implementation detail at that time rather than a language guarantee.
+Frozen dictionaries
+^^^^^^^^^^^^^^^^^^^
+
+.. index:: pair: object; frozendict
+
+These represent an immutable dictionary. They are created by the built-in
+:func:`frozendict` constructor. A frozendict is :term:`hashable` if all of
+its keys and values are hashable, in which case it can be used as an element
+of a set, or as a key in another mapping. :class:`!frozendict` is not a
+subclass of :class:`dict`; it inherits directly from :class:`object`.
+
+.. versionadded:: 3.15
+
+
Callable types
--------------
From 863c7e0f9f9d72b8a2b87759b1ab51a0c4293de9 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Fri, 29 May 2026 23:30:50 +0200
Subject: [PATCH 164/213] [3.15] gh-149056: Properly pass array_hook in
json.load() to json.loads() (GH-149057) (GH-150591)
(cherry picked from commit f87d9605d3f9489d33aaf97a97fa9cb81cd7cc40)
Co-authored-by: Thomas Kowalski
---
Lib/json/__init__.py | 2 +-
Lib/test/test_json/test_decode.py | 7 +++++++
.../Library/2026-04-29-08-10-17.gh-issue-149056.jnaD4W.rst | 2 ++
3 files changed, 10 insertions(+), 1 deletion(-)
create mode 100644 Misc/NEWS.d/next/Library/2026-04-29-08-10-17.gh-issue-149056.jnaD4W.rst
diff --git a/Lib/json/__init__.py b/Lib/json/__init__.py
index 9681a8fe53ec48..37a86831ff9483 100644
--- a/Lib/json/__init__.py
+++ b/Lib/json/__init__.py
@@ -307,7 +307,7 @@ def load(fp, *, cls=None, object_hook=None, parse_float=None,
cls=cls, object_hook=object_hook,
parse_float=parse_float, parse_int=parse_int,
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook,
- array_hook=None, **kw)
+ array_hook=array_hook, **kw)
def loads(s, *, cls=None, object_hook=None, parse_float=None,
diff --git a/Lib/test/test_json/test_decode.py b/Lib/test/test_json/test_decode.py
index d846c8af7ec434..1d51fb2de0e69e 100644
--- a/Lib/test/test_json/test_decode.py
+++ b/Lib/test/test_json/test_decode.py
@@ -87,6 +87,13 @@ def test_array_hook(self):
self.assertEqual(self.loads('[]', array_hook=tuple), ())
+ def test_load_array_hook(self):
+ # json.load must forward array_hook to loads
+ fp = StringIO('[10, 20, 30]')
+ result = self.json.load(fp, array_hook=tuple)
+ self.assertEqual(result, (10, 20, 30))
+ self.assertEqual(type(result), tuple)
+
def test_decoder_optimizations(self):
# Several optimizations were made that skip over calls to
# the whitespace regex, so this test is designed to try and
diff --git a/Misc/NEWS.d/next/Library/2026-04-29-08-10-17.gh-issue-149056.jnaD4W.rst b/Misc/NEWS.d/next/Library/2026-04-29-08-10-17.gh-issue-149056.jnaD4W.rst
new file mode 100644
index 00000000000000..0026d02c876257
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-04-29-08-10-17.gh-issue-149056.jnaD4W.rst
@@ -0,0 +1,2 @@
+Fix :func:`json.load` not forwarding the *array_hook* argument to
+:func:`json.loads`. Patch by Thomas Kowalski.
From 2f9131575b611dfc749242e8bbc6805bbc14683b Mon Sep 17 00:00:00 2001
From: Serhiy Storchaka
Date: Sat, 30 May 2026 00:48:10 +0300
Subject: [PATCH 165/213] [3.15] gh-149489: Fix ElementTree serialization to
HTML (GH-149490) (GH-150595)
* The content of comments, processing instructions and elements "xmp",
"iframe", "noembed", "noframes", and "plaintext" is no longer escaped.
* The "plaintext" element no longer have the closing tag.
* Add support of empty attributes (with value None).
(cherry picked from commit bcd29e466f55d8b4e3849ed6ada8ce86a46f5072)
---
Lib/test/test_xml_etree.py | 40 ++++++++++++++++++-
Lib/xml/etree/ElementTree.py | 24 ++++++-----
...-05-07-14-18-47.gh-issue-149489.bX9iHe.rst | 5 +++
3 files changed, 58 insertions(+), 11 deletions(-)
create mode 100644 Misc/NEWS.d/next/Library/2026-05-07-14-18-47.gh-issue-149489.bX9iHe.rst
diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py
index f43f1708a0fabd..27ea3c8c32fd8a 100644
--- a/Lib/test/test_xml_etree.py
+++ b/Lib/test/test_xml_etree.py
@@ -1281,7 +1281,15 @@ def check(p, expected, namespaces=None):
{'': 'http://www.w3.org/2001/XMLSchema',
'ns': 'http://www.w3.org/2001/XMLSchema'})
- def test_processinginstruction(self):
+ def test_comment_serialization(self):
+ comm = ET.Comment(' & ham')
+ # comments are not escaped
+ self.assertEqual(ET.tostring(comm), b'')
+ self.assertEqual(ET.tostring(comm, method='html'), b'')
+ # no comments in text serialization
+ self.assertEqual(ET.tostring(comm, method='text'), b'')
+
+ def test_processinginstruction_serialization(self):
# Test ProcessingInstruction directly
self.assertEqual(ET.tostring(ET.ProcessingInstruction('test', 'instruction')),
@@ -1290,12 +1298,32 @@ def test_processinginstruction(self):
b'')
# Issue #2746
-
+ # processing instructions are not escaped
self.assertEqual(ET.tostring(ET.PI('test', '')),
b'?>')
self.assertEqual(ET.tostring(ET.PI('test', '\xe3'), 'latin-1'),
b"\n"
b"\xe3?>")
+ pi = ET.PI('test', 'ham & eggs < spam')
+ self.assertEqual(ET.tostring(pi), b'')
+ self.assertEqual(ET.tostring(pi, method='html'), b'')
+ # no processing instructions in text serialization
+ self.assertEqual(ET.tostring(pi, method='text'), b'')
+
+ def test_empty_attribute_serialization(self):
+ # empty attrs only work in html
+ elem = ET.Element('tag', attrib={'attr': None})
+ self.assertRaises(TypeError, ET.tostring, elem)
+ self.assertEqual(ET.tostring(elem, method='html'), b'')
+
+ @support.subTests('tag', ("script", "style", "xmp", "iframe", "noembed", "noframes"))
+ def test_html_cdata_elems_serialization(self, tag):
+ # content of raw text elements is not escaped in html
+ tag = tag.title()
+ elem = ET.Element(tag)
+ elem.text = '&ham'
+ self.assertEqual(ET.tostring(elem, method='html'),
+ ('<%s>&ham%s>' % (tag, tag)).encode())
def test_html_empty_elems_serialization(self):
# issue 15970
@@ -1311,6 +1339,14 @@ def test_html_empty_elems_serialization(self):
method='html')
self.assertEqual(serialized, expected)
+ def test_html_plaintext_serialization(self):
+ # content of plaintext is not escaped in html
+ # no end tag for plaintext
+ elem = ET.Element('PlainText')
+ elem.text = '&ham'
+ self.assertEqual(ET.tostring(elem, method='html'),
+ b'&ham')
+
def test_dump_attribute_order(self):
# See BPO 34160
e = ET.Element('cirriculum', status='public', company='example')
diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py
index 75bebc0b1668ab..53727d7940b3f2 100644
--- a/Lib/xml/etree/ElementTree.py
+++ b/Lib/xml/etree/ElementTree.py
@@ -917,17 +917,20 @@ def _serialize_xml(write, elem, qnames, namespaces,
if elem.tail:
write(_escape_cdata(elem.tail))
+_CDATA_CONTENT_ELEMENTS = {"script", "style", "xmp", "iframe", "noembed",
+ "noframes", "plaintext"}
+
HTML_EMPTY = {"area", "base", "basefont", "br", "col", "embed", "frame", "hr",
"img", "input", "isindex", "link", "meta", "param", "source",
- "track", "wbr"}
+ "track", "wbr", "plaintext"}
def _serialize_html(write, elem, qnames, namespaces, **kwargs):
tag = elem.tag
text = elem.text
if tag is Comment:
- write("" % _escape_cdata(text))
+ write("" % text)
elif tag is ProcessingInstruction:
- write("%s?>" % _escape_cdata(text))
+ write("%s?>" % text)
else:
tag = qnames[tag]
if tag is None:
@@ -951,16 +954,19 @@ def _serialize_html(write, elem, qnames, namespaces, **kwargs):
for k, v in items:
if isinstance(k, QName):
k = k.text
- if isinstance(v, QName):
- v = qnames[v.text]
+ k = qnames[k]
+ if v is None:
+ write(" %s" % k) # empty attr
else:
- v = _escape_attrib_html(v)
- # FIXME: handle boolean attributes
- write(" %s=\"%s\"" % (qnames[k], v))
+ if isinstance(v, QName):
+ v = qnames[v.text]
+ else:
+ v = _escape_attrib_html(v)
+ write(" %s=\"%s\"" % (k, v))
write(">")
ltag = tag.lower()
if text:
- if ltag == "script" or ltag == "style":
+ if ltag in _CDATA_CONTENT_ELEMENTS:
write(text)
else:
write(_escape_cdata(text))
diff --git a/Misc/NEWS.d/next/Library/2026-05-07-14-18-47.gh-issue-149489.bX9iHe.rst b/Misc/NEWS.d/next/Library/2026-05-07-14-18-47.gh-issue-149489.bX9iHe.rst
new file mode 100644
index 00000000000000..1550c893fd7c45
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-05-07-14-18-47.gh-issue-149489.bX9iHe.rst
@@ -0,0 +1,5 @@
+Fix :mod:`~xml.etree.ElementTree` serialization to HTML. The content of
+comments, processing instructions and elements "xmp", "iframe", "noembed",
+"noframes", and "plaintext" is no longer escaped. The "plaintext" element no
+longer have the closing tag. Add support of empty attributes (with value
+``None``).
From 187982aa7d61ec00378498a483c0f92b3992f4be Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sat, 30 May 2026 11:25:38 +0200
Subject: [PATCH 166/213] [3.15] gh-150501: Correct `inspect.getattr_static`
docs signature (GH-150504) (#150601)
gh-150501: Correct `inspect.getattr_static` docs signature (GH-150504)
(cherry picked from commit 678fd8452cc2d7f9a50cb5d4e5ae44a60b724248)
Co-authored-by: Jonathan Dung
---
Doc/library/inspect.rst | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst
index 92840e702fbbfe..a0f7379b12a8a6 100644
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -1614,10 +1614,11 @@ properties, will be invoked and :meth:`~object.__getattr__` and
may be called.
For cases where you want passive introspection, like documentation tools, this
-can be inconvenient. :func:`getattr_static` has the same signature as :func:`getattr`
+can be inconvenient. :func:`getattr_static` has a similar signature as :func:`getattr`
but avoids executing code when it fetches attributes.
-.. function:: getattr_static(obj, attr, default=None)
+.. function:: getattr_static(obj, attr)
+ getattr_static(obj, attr, default)
Retrieve attributes without triggering dynamic lookup via the
descriptor protocol, :meth:`~object.__getattr__`
From b952986ced6dbf48e77c951a1245343a32c08006 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sat, 30 May 2026 12:49:26 +0200
Subject: [PATCH 167/213] [3.15] gh-135898: Add section to free-threading howto
about memory usage (GH-143279) (#150607)
gh-135898: Add section to free-threading howto about memory usage (GH-143279)
(cherry picked from commit 62a45fa91c64bd1e1ad46ed66c07b65a7971042e)
Co-authored-by: Neil Schemenauer
Co-authored-by: Kumar Aditya
---
Doc/howto/free-threading-python.rst | 129 ++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
diff --git a/Doc/howto/free-threading-python.rst b/Doc/howto/free-threading-python.rst
index 380c2be04957d5..53bea1db191d76 100644
--- a/Doc/howto/free-threading-python.rst
+++ b/Doc/howto/free-threading-python.rst
@@ -165,3 +165,132 @@ to false. If the flag is true then the :class:`warnings.catch_warnings`
context manager uses a context variable for warning filters. If the flag is
false then :class:`~warnings.catch_warnings` modifies the global filters list,
which is not thread-safe. See the :mod:`warnings` module for more details.
+
+
+Increased memory usage
+----------------------
+
+The free-threaded build will typically use more memory compared to the default
+build. There are multiple reasons for this, mostly due to design decisions.
+
+
+All interned strings are immortal
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For modern Python versions (since version 2.3), interning a string (e.g. with
+:func:`sys.intern`) does not cause it to become immortal. Instead, if the last
+reference to that string disappears, it will be removed from the interned
+string table. This is not the case for the free-threaded build and any interned
+string will become immortal, surviving until interpreter shutdown.
+
+
+Non-GC objects have a larger object header
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The free-threaded build uses a different :c:type:`PyObject` structure. Instead
+of having the GC related information allocated before the :c:type:`PyObject`
+structure, like in the default build, the GC related info is part of the normal
+object header. For example, on the AMD64 platform, ``None`` uses 32 bytes on
+the free-threaded build vs 16 bytes for the default build. GC objects (such as
+dicts and lists) are the same size for both builds since the free-threaded
+build does not use additional space for the GC info.
+
+
+QSBR can delay freeing of memory
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In order to safely implement lock-free data structures, a safe memory
+reclamation (SMR) scheme is used, known as quiescent state-based reclamation
+(QSBR). This means that the memory backing data structures allowing lock-free
+access will use QSBR, which defers the free operation, rather than immediately
+freeing the memory. Two examples of these data structures are the list object
+and the dictionary keys object. See ``InternalDocs/qsbr.md`` in the CPython
+source tree for more details on how QSBR is implemented. Running
+:func:`gc.collect` should cause all memory being held by QSBR to be actually
+freed. Note that even when QSBR frees the memory, the underlying memory
+allocator may not immediately return that memory to the OS and so the resident
+set size (RSS) of the process might not decrease.
+
+
+mimalloc allocator vs pymalloc
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The default build will normally use the "pymalloc" memory allocator for small
+allocations (512 bytes or smaller). The free-threaded build does not use
+pymalloc and allocates all Python objects using the "mimalloc" allocator. The
+pymalloc allocator has the following properties that help keep memory usage
+low: small per-allocated-block overhead, effective memory fragmentation
+prevention, and quick return of free memory to the operating system. The
+mimalloc allocator does quite well in these respects as well but can have some
+more overhead.
+
+In the free-threaded build, mimalloc manages memory in a number of separate
+heaps (currently four). For example, all GC supporting objects are allocated
+from their own heap. Using separate heaps means that free memory in one heap
+cannot be used for an allocation that uses another heap. Also, some heaps are
+configured to use QSBR (quiescent-state based reclamation) when freeing the
+memory that backs up the heap (known as "pages" in mimalloc terminology). The
+use of QSBR creates a delay between all memory blocks for a page being freed
+and the memory page being released, either for new allocations or back to the
+OS.
+
+The mimalloc allocator also defers returning freed memory back to the OS. You
+can reduce that delay by setting the environment variable
+:envvar:`!MIMALLOC_PURGE_DELAY` to ``0``. Note that this will likely reduce
+the performance of the allocator.
+
+
+Free-threaded reference counting can cause objects to live longer
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In the default build, when an object's reference count reaches zero, it is
+normally deallocated. The free-threaded build uses "biased reference
+counting", with a fast-path for objects "owned" by the current thread and a
+slow path for other objects. See :pep:`703` for additional details. Any time
+an object's reference count ends up in a "queued" state, deallocation can be
+deferred. The queued state is cleared from the "eval breaker" section of the
+bytecode evaluator.
+
+The free-threaded build also allows a different mode of reference counting,
+known as "deferred reference counting". This mode is enabled by setting a flag
+on a per-object basis. Deferred reference counting is enabled for the
+following types:
+
+* module objects
+* module top-level functions
+* class methods defined in the class scope
+* descriptor objects
+* thread-local objects, created by :class:`threading.local`
+
+When deferred reference counting is enabled, references from Python function
+stacks are not added to the reference count. This scheme reduces the overhead
+of reference counting, especially for objects used from multiple threads.
+Because the stack references are not counted, objects with deferred reference
+counting are not immediately freed when their internal reference count goes to
+zero. Instead, they are examined by the next GC run and, if no stack
+references to them are found, they are freed. This means these objects are
+freed by the GC and not when their reference count goes to zero, as is typical.
+
+
+Per-thread reference counting can delay freeing objects
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To avoid contention on the reference count fields of frequently shared
+objects, the free-threaded build also uses "per-thread reference counting"
+for a few selected object types. Rather than updating a single shared
+reference count, each thread maintains its own local reference count array,
+indexed by a unique id assigned to the object. The true reference count is
+only computed by summing the per-thread counts when the object's local
+count drops to zero. Per-thread reference counting is currently used for:
+
+* heap type objects (classes created in Python)
+* code objects
+* the ``__dict__`` of module objects
+
+Because the per-thread counts must be merged back to the object before it
+can be deallocated, objects using per-thread reference counting are
+typically freed later than they would be in the default build. In
+particular, such an object is usually not freed until the thread that
+referenced it reaches a safe point (for example, in the "eval breaker"
+section of the bytecode evaluator) or exits. Running :func:`gc.collect`
+will merge the per-thread counts and allow these objects to be freed.
From e4cdee6c19aba3cb086b255858f6d7b953dddba4 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sat, 30 May 2026 19:03:58 +0200
Subject: [PATCH 168/213] [3.15] gh-129851: Fix the documentation for -m
command (GH-129862) (GH-150614)
(cherry picked from commit 9baa7c63bee1ad2b243f16109a3fd206a1f13a6a)
Co-authored-by: Dhruv Singla <68206552+d-s-dc@users.noreply.github.com>
---
Doc/using/cmdline.rst | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst
index 59e8f4f9f5a3e4..d84cd42062a678 100644
--- a/Doc/using/cmdline.rst
+++ b/Doc/using/cmdline.rst
@@ -50,8 +50,8 @@ additional methods of invocation:
* When called with ``-c command``, it executes the Python statement(s) given as
*command*. Here *command* may contain multiple statements separated by
newlines.
-* When called with ``-m module-name``, the given module is located on the
- Python module path and executed as a script.
+* When called with ``-m module-name``, the given module is located using the standard
+ import mechanism and executed as a script.
In non-interactive mode, the entire input is parsed before it is executed.
@@ -78,8 +78,8 @@ source.
.. option:: -m
- Search :data:`sys.path` for the named module and execute its contents as
- the :mod:`__main__` module.
+ Locate the module using the standard import mechanism and execute its contents
+ as the :mod:`__main__` module.
Since the argument is a *module* name, you must not give a file extension
(``.py``). The module name should be a valid absolute Python module name, but
From 7cf2b37b66f681e1a61916b8b83b67771582fa93 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sat, 30 May 2026 19:15:02 +0200
Subject: [PATCH 169/213] [3.15] gh-150406: Check result of
PyThread_allocate_lock() for netdb_lock (GH-150407) (GH-150616)
(cherry picked from commit 1e18c45495185cb547d43c3dd4c1cbdd8482867b)
Co-authored-by: Thomas Kowalski
---
.../Library/2026-05-25-17-00-00.gh-issue-150406.jF3g63.rst | 3 +++
Modules/socketmodule.c | 3 +++
2 files changed, 6 insertions(+)
create mode 100644 Misc/NEWS.d/next/Library/2026-05-25-17-00-00.gh-issue-150406.jF3g63.rst
diff --git a/Misc/NEWS.d/next/Library/2026-05-25-17-00-00.gh-issue-150406.jF3g63.rst b/Misc/NEWS.d/next/Library/2026-05-25-17-00-00.gh-issue-150406.jF3g63.rst
new file mode 100644
index 00000000000000..230e961abd3f58
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-05-25-17-00-00.gh-issue-150406.jF3g63.rst
@@ -0,0 +1,3 @@
+Fix a possible crash occurring during :mod:`socket` module initialization
+when the system is out of memory on platforms without a reentrant
+``gethostbyname``.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 722287fbb134c3..cf7aadfe95a721 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -9285,6 +9285,9 @@ socket_exec(PyObject *m)
/* Initialize gethostbyname lock */
#if defined(USE_GETHOSTBYNAME_LOCK)
netdb_lock = PyThread_allocate_lock();
+ if (netdb_lock == NULL) {
+ goto error;
+ }
#endif
#ifdef MS_WINDOWS
From ccfa50a0782a1d1ea504e8d5bc78ace57d99d968 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 31 May 2026 06:08:20 +0200
Subject: [PATCH 170/213] [3.15] gh-141444:fix broken URLs and examples in
urllib.request.rst (GH-144863) (#150642)
gh-141444:fix broken URLs and examples in urllib.request.rst (GH-144863)
* Doc: fix broken URLs and examples in urllib.request.rst (gh-141444)
* Doc: update urllib.request examples to handle gzip compression
---------
(cherry picked from commit 0f1f7c7889873deb7c2e2c3f18695bf636e7752c)
Co-authored-by: Paper Moon
Co-authored-by: Senthil Kumaran
---
Doc/library/urllib.request.rst | 54 +++++++++++++++++++---------------
1 file changed, 31 insertions(+), 23 deletions(-)
diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst
index 64e915d042d4a0..03518d49d437ce 100644
--- a/Doc/library/urllib.request.rst
+++ b/Doc/library/urllib.request.rst
@@ -1051,7 +1051,7 @@ AbstractBasicAuthHandler Objects
*headers* should be the error headers.
*host* is either an authority (e.g. ``"python.org"``) or a URL containing an
- authority component (e.g. ``"http://python.org/"``). In either case, the
+ authority component (e.g. ``"https://python.org/"``). In either case, the
authority must not contain a userinfo component (so, ``"python.org"`` and
``"python.org:80"`` are fine, ``"joe:password@python.org"`` is not).
@@ -1247,10 +1247,14 @@ This example gets the python.org main page and displays the first 300 bytes of
it::
>>> import urllib.request
- >>> with urllib.request.urlopen('http://www.python.org/') as f:
- ... print(f.read(300))
- ...
- b'\n\n\n
- >> import urllib.request
- >>> f = urllib.request.urlopen('http://www.python.org/')
+ >>> f = urllib.request.urlopen('https://www.python.org/')
>>> try:
- ... print(f.read(100).decode('utf-8'))
+ ... enc = f.headers.get('Content-Encoding')
+ ... data = f.read()
+ ... if enc == 'gzip':
+ ... import gzip
+ ... data = gzip.decompress(data)
+ ... print(data[:100].decode('utf-8', errors='replace'))
... finally:
... f.close()
- ...
-
-
-
+
+
+
+.. class:: LockType
-.. method:: lock.acquire(blocking=True, timeout=-1)
+ This is the type of lock objects.
- Without any optional argument, this method acquires the lock unconditionally, if
- necessary waiting until it is released by another thread (only one thread at a
- time can acquire a lock --- that's their reason for existence).
+ Lock objects have the following methods:
- If the *blocking* argument is present, the action depends on its
- value: if it is false, the lock is only acquired if it can be acquired
- immediately without waiting, while if it is true, the lock is acquired
- unconditionally as above.
+ .. method:: acquire(blocking=True, timeout=-1)
- If the floating-point *timeout* argument is present and positive, it
- specifies the maximum wait time in seconds before returning. A negative
- *timeout* argument specifies an unbounded wait. You cannot specify
- a *timeout* if *blocking* is false.
+ Without any optional argument, this method acquires the lock unconditionally, if
+ necessary waiting until it is released by another thread (only one thread at a
+ time can acquire a lock --- that's their reason for existence).
- The return value is ``True`` if the lock is acquired successfully,
- ``False`` if not.
+ If the *blocking* argument is present, the action depends on its
+ value: if it is false, the lock is only acquired if it can be acquired
+ immediately without waiting, while if it is true, the lock is acquired
+ unconditionally as above.
- .. versionchanged:: 3.2
- The *timeout* parameter is new.
+ If the floating-point *timeout* argument is present and positive, it
+ specifies the maximum wait time in seconds before returning. A negative
+ *timeout* argument specifies an unbounded wait. You cannot specify
+ a *timeout* if *blocking* is false.
- .. versionchanged:: 3.2
- Lock acquires can now be interrupted by signals on POSIX.
+ The return value is ``True`` if the lock is acquired successfully,
+ ``False`` if not.
- .. versionchanged:: 3.14
- Lock acquires can now be interrupted by signals on Windows.
+ .. versionchanged:: 3.2
+ The *timeout* parameter is new.
+ .. versionchanged:: 3.2
+ Lock acquires can now be interrupted by signals on POSIX.
-.. method:: lock.release()
+ .. versionchanged:: 3.14
+ Lock acquires can now be interrupted by signals on Windows.
- Releases the lock. The lock must have been acquired earlier, but not
- necessarily by the same thread.
+ .. method:: release()
+ Releases the lock. The lock must have been acquired earlier, but not
+ necessarily by the same thread.
-.. method:: lock.locked()
+ .. method:: locked()
- Return the status of the lock: ``True`` if it has been acquired by some thread,
- ``False`` if not.
+ Return the status of the lock: ``True`` if it has been acquired by some thread,
+ ``False`` if not.
-In addition to these methods, lock objects can also be used via the
-:keyword:`with` statement, e.g.::
+ In addition to these methods, lock objects can also be used via the
+ :keyword:`with` statement, e.g.::
- import _thread
+ import _thread
- a_lock = _thread.allocate_lock()
+ a_lock = _thread.allocate_lock()
- with a_lock:
- print("a_lock is locked while this executes")
+ with a_lock:
+ print("a_lock is locked while this executes")
**Caveats:**
From b17bcfdf7e716809254ba4e9168164bc81e8a2ca Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Tue, 2 Jun 2026 15:36:52 +0200
Subject: [PATCH 204/213] [3.15] gh-150766: export `_PyGC_VisitFrameStack` and
`_PyGC_VisitStackRef` functions (GH-150767) (#150787)
gh-150766: export `_PyGC_VisitFrameStack` and `_PyGC_VisitStackRef` functions (GH-150767)
(cherry picked from commit df34a2f7122dcc6d230493b138e301675a290c49)
Co-authored-by: Kumar Aditya
---
Include/internal/pycore_gc.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index bfe52f42f1141c..84cbb56a919215 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -335,8 +335,9 @@ extern void _Py_RunGC(PyThreadState *tstate);
union _PyStackRef;
// GC visit callback for tracked interpreter frames
-extern int _PyGC_VisitFrameStack(_PyInterpreterFrame *frame, visitproc visit, void *arg);
-extern int _PyGC_VisitStackRef(union _PyStackRef *ref, visitproc visit, void *arg);
+// GH-150766: exported for greenlet
+PyAPI_FUNC(int) _PyGC_VisitFrameStack(_PyInterpreterFrame *frame, visitproc visit, void *arg);
+PyAPI_FUNC(int) _PyGC_VisitStackRef(union _PyStackRef *ref, visitproc visit, void *arg);
#ifdef Py_GIL_DISABLED
extern void _PyGC_VisitObjectsWorldStopped(PyInterpreterState *interp,
From 33b2879c3aeb6d4c6995bf6cda848f5731091a8d Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Tue, 2 Jun 2026 16:18:03 +0200
Subject: [PATCH 205/213] [3.15] gh-149187: Document `frozendict()` under
'Built-in Functions' (GH-149185)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
(cherry picked from commit 86867edb84a53d60e3ec9d3d2e83f4ed09692b95)
Co-authored-by: Øyvind Rønningstad
---
Doc/library/functions.rst | 57 +++++++++++++++++++++++++--------------
1 file changed, 37 insertions(+), 20 deletions(-)
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 0393e2dc776db4..def2a211d1b3b4 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -19,24 +19,25 @@ are always available. They are listed here in alphabetical order.
| | :func:`ascii` | | :func:`filter` | | :func:`map` | | **S** |
| | | | :func:`float` | | :func:`max` | | |func-set|_ |
| | **B** | | :func:`format` | | |func-memoryview|_ | | :func:`setattr` |
-| | :func:`bin` | | |func-frozenset|_ | | :func:`min` | | :func:`sentinel` |
-| | :func:`bool` | | | | | | :func:`slice` |
-| | :func:`breakpoint` | | **G** | | **N** | | :func:`sorted` |
-| | |func-bytearray|_ | | :func:`getattr` | | :func:`next` | | :func:`staticmethod` |
-| | |func-bytes|_ | | :func:`globals` | | | | |func-str|_ |
-| | | | | | **O** | | :func:`sum` |
-| | **C** | | **H** | | :func:`object` | | :func:`super` |
-| | :func:`callable` | | :func:`hasattr` | | :func:`oct` | | **T** |
-| | :func:`chr` | | :func:`hash` | | :func:`open` | | |func-tuple|_ |
-| | :func:`classmethod` | | :func:`help` | | :func:`ord` | | :func:`type` |
-| | :func:`compile` | | :func:`hex` | | | | |
-| | :func:`complex` | | | | **P** | | **V** |
-| | | | **I** | | :func:`pow` | | :func:`vars` |
-| | **D** | | :func:`id` | | :func:`print` | | |
-| | :func:`delattr` | | :func:`input` | | :func:`property` | | **Z** |
-| | |func-dict|_ | | :func:`int` | | | | :func:`zip` |
-| | :func:`dir` | | :func:`isinstance` | | | | |
-| | :func:`divmod` | | :func:`issubclass` | | | | **_** |
+| | :func:`bin` | | |func-frozendict|_ | | :func:`min` | | :func:`sentinel` |
+| | :func:`bool` | | |func-frozenset|_ | | | | :func:`slice` |
+| | :func:`breakpoint` | | | | **N** | | :func:`sorted` |
+| | |func-bytearray|_ | | **G** | | :func:`next` | | :func:`staticmethod` |
+| | |func-bytes|_ | | :func:`getattr` | | | | |func-str|_ |
+| | | | :func:`globals` | | **O** | | :func:`sum` |
+| | **C** | | | | :func:`object` | | :func:`super` |
+| | :func:`callable` | | **H** | | :func:`oct` | | |
+| | :func:`chr` | | :func:`hasattr` | | :func:`open` | | **T** |
+| | :func:`classmethod` | | :func:`hash` | | :func:`ord` | | |func-tuple|_ |
+| | :func:`compile` | | :func:`help` | | | | :func:`type` |
+| | :func:`complex` | | :func:`hex` | | **P** | | |
+| | | | | | :func:`pow` | | **V** |
+| | **D** | | **I** | | :func:`print` | | :func:`vars` |
+| | :func:`delattr` | | :func:`id` | | :func:`property` | | |
+| | |func-dict|_ | | :func:`input` | | | | **Z** |
+| | :func:`dir` | | :func:`int` | | | | :func:`zip` |
+| | :func:`divmod` | | :func:`isinstance` | | | | |
+| | | | :func:`issubclass` | | | | **_** |
| | | | :func:`iter` | | | | :func:`__import__` |
+-------------------------+-----------------------+-----------------------+-------------------------+
@@ -44,6 +45,7 @@ are always available. They are listed here in alphabetical order.
used, with replacement texts to make the output in the table consistent
.. |func-dict| replace:: ``dict()``
+.. |func-frozendict| replace:: ``frozendict()``
.. |func-frozenset| replace:: ``frozenset()``
.. |func-memoryview| replace:: ``memoryview()``
.. |func-set| replace:: ``set()``
@@ -485,8 +487,8 @@ are always available. They are listed here in alphabetical order.
Create a new dictionary. The :class:`dict` object is the dictionary class.
See :class:`dict` and :ref:`typesmapping` for documentation about this class.
- For other containers see the built-in :class:`list`, :class:`set`, and
- :class:`tuple` classes, as well as the :mod:`collections` module.
+ For other containers see the built-in :class:`frozendict`, :class:`list`,
+ :class:`set`, and :class:`tuple` classes, as well as the :mod:`collections` module.
.. function:: dir()
@@ -864,6 +866,21 @@ are always available. They are listed here in alphabetical order.
if *format_spec* is not an empty string.
+.. _func-frozendict:
+.. class:: frozendict(**kwargs)
+ frozendict(mapping, /, **kwargs)
+ frozendict(iterable, /, **kwargs)
+ :noindex:
+
+ Create a new frozen dictionary. The :class:`frozendict` object is a built-in class.
+ See :class:`frozendict` and :ref:`typesmapping` for documentation about this class.
+
+ For other containers see the built-in :class:`dict`, :class:`list`, :class:`set`,
+ and :class:`tuple` classes, as well as the :mod:`collections` module.
+
+ .. versionadded:: 3.15
+
+
.. _func-frozenset:
.. class:: frozenset(iterable=(), /)
:noindex:
From 13a7cce3638a11f59872925f37e398876a3c003e Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Tue, 2 Jun 2026 17:20:39 +0200
Subject: [PATCH 206/213] [3.15] Silence experimental coroutine deprecation
warnings (GH-150788) (#150794)
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Co-authored-by: Zachary Ware
---
PC/python_uwp.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/PC/python_uwp.cpp b/PC/python_uwp.cpp
index 8cdb8d722cdb9a..1b44216dc20d1e 100644
--- a/PC/python_uwp.cpp
+++ b/PC/python_uwp.cpp
@@ -13,6 +13,7 @@
#if defined(__clang__)
#define _SILENCE_CLANG_COROUTINE_MESSAGE
#endif
+#define _SILENCE_EXPERIMENTAL_COROUTINE_DEPRECATION_WARNINGS
#include
#include
From 94a64bbc6ce89644cf02b82c723d9cc37f6a1870 Mon Sep 17 00:00:00 2001
From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Date: Tue, 2 Jun 2026 18:28:30 +0300
Subject: [PATCH 207/213] Python 3.15.0b2
---
Doc/library/sqlite3.rst | 6 +-
Include/patchlevel.h | 4 +-
Lib/pydoc_data/module_docs.py | 2 +-
Lib/pydoc_data/topics.py | 261 ++++--
Misc/NEWS.d/3.15.0b2.rst | 795 ++++++++++++++++++
...-05-18-16-00-41.gh-issue-148260.UwFiIX.rst | 3 -
...-05-21-15-14-59.gh-issue-148294.VtFaW4.rst | 2 -
...-02-25-13-37-10.gh-issue-145235.-1ySNR.rst | 3 -
...-05-12-16-47-21.gh-issue-149725.HZLBTZ.rst | 2 -
...-04-15-15-48-04.gh-issue-148450.2MEVqH.rst | 1 -
...-05-07-03-18-59.gh-issue-149459.5fhAqP.rst | 1 -
...-05-09-15-22-32.gh-issue-144957.u1F2aQ.rst | 2 -
...-05-10-07-42-36.gh-issue-149642.6ZksML.rst | 2 -
...-05-10-16-43-50.gh-issue-148829.gscS14.rst | 2 -
...-05-11-14-48-56.gh-issue-149676.6aTrw1.rst | 1 -
...-05-12-16-47-23.gh-issue-139808.iIs7_E.rst | 2 -
...-05-13-06-54-41.gh-issue-149738.4BLFoH.rst | 2 -
...-05-14-19-41-03.gh-issue-149807.IwGaCo.rst | 2 -
...-05-15-11-31-57.gh-issue-149816.ugN2rx.rst | 1 -
...-05-16-11-03-54.gh-issue-149816.X_gqMT.rst | 1 -
...-05-18-13-47-17.gh-issue-149590.IPBeQx.rst | 1 -
...-05-18-16-54-54.gh-issue-150042.LSr5W8.rst | 1 -
...-05-18-18-36-28.gh-issue-148587.-RD3z5.rst | 1 -
...-05-20-13-06-17.gh-issue-150146.i5m_SL.rst | 5 -
...-05-22-17-09-28.gh-issue-150107.GD72-D.rst | 3 -
...-05-23-22-08-01.gh-issue-149449.2lhQFF.rst | 3 -
...-05-24-14-45-00.gh-issue-149156.NP73rB.rst | 3 -
...-05-25-16-00-22.gh-issue-150374.Emu6d8.rst | 1 -
.../2021-10-18-13-46-55.bpo-45509.Upwb60.rst | 1 -
...-07-02-20-57-43.gh-issue-121109.Tp6R2s.rst | 2 -
...-11-02-02-02-31.gh-issue-107398.uUtA6Q.rst | 1 -
...-03-01-13-36-02.gh-issue-128110.9wx_G0.rst | 5 -
...-05-19-20-29-35.gh-issue-133998.KmElUw.rst | 5 -
...-05-19-21-08-25.gh-issue-134261.ravGYm.rst | 1 -
...-08-30-07-44-30.gh-issue-86533.pathlib.rst | 4 -
...3-26-09-30-00.gh-issue-146452.Y2N6qZ8J.rst | 2 -
...-04-23-12-50-15.gh-issue-148441.zvpCkR.rst | 4 -
...-04-27-11-12-00.gh-issue-149046.74shDd.rst | 2 -
...-04-29-08-10-17.gh-issue-149056.jnaD4W.rst | 2 -
...-05-07-14-18-47.gh-issue-149489.bX9iHe.rst | 5 -
...-05-07-21-58-17.gh-issue-149388.DDBPeA.rst | 1 -
...-05-08-09-11-48.gh-issue-149534.Tw7eeY.rst | 1 -
...-05-08-15-08-35.gh-issue-112821.t9T1YD.rst | 4 -
...-05-09-21-02-08.gh-issue-149614.U4snj3.rst | 1 -
...-05-10-07-21-51.gh-issue-139489.rS7LTA.rst | 1 -
...-05-10-19-26-50.gh-issue-149584.x7Qm9A.rst | 4 -
...-05-10-23-51-23.gh-issue-149504.pDSCbn.rst | 5 -
...-05-12-06-24-54.gh-issue-149701.8v9RTm.rst | 1 -
...-05-12-13-03-45.gh-issue-149718.SaM1NJ.rst | 4 -
...-05-13-23-18-39.gh-issue-149801.S_FfGr.rst | 2 -
...-05-14-15-55-28.gh-issue-149816.ZaXQ0q.rst | 2 -
...-05-15-16-28-00.gh-issue-149819.fixpth.rst | 4 -
...-05-15-18-44-20.gh-issue-142349.fHK3v1.rst | 1 -
...-05-16-21-08-33.gh-issue-149921.I1yNML.rst | 2 -
...-05-17-02-25-56.gh-issue-149571.LNyuWJ.rst | 2 -
...6-05-17-22-37-02.gh-issue-88726.BAoL6j.rst | 2 -
...-05-18-07-44-46.gh-issue-149995.vvtFHn.rst | 1 -
...-05-18-17-17-20.gh-issue-149189.a8IooK.rst | 1 -
...6-05-19-19-00-49.gh-issue-84353.ZU5zaQ.rst | 5 -
...-05-21-11-25-58.gh-issue-150175.8H4Caz.rst | 3 -
...5-21-20-47-45.gh-issue-150157.ZvmO-bQZ.rst | 3 -
...-05-25-07-22-05.gh-issue-150372.9hLqhe.rst | 2 -
...-05-25-17-00-00.gh-issue-150406.jF3g63.rst | 3 -
...-05-27-11-18-36.gh-issue-150228.pNPiO-.rst | 11 -
...-05-31-17-47-30.gh-issue-150685.EBB2mU.rst | 1 -
...-04-26-19-30-45.gh-issue-149018.a9SqWb.rst | 3 -
...-04-27-16-36-11.gh-issue-149079.vKl-LM.rst | 5 -
...-05-03-21-00-00.gh-issue-149486.tarflt.rst | 5 -
...-05-08-02-18-54.gh-issue-149474.ujQ-mu.rst | 3 -
...6-05-10-18-05-32.gh-issue-87451.XkKB6M.rst | 6 -
...-05-11-21-15-07.gh-issue-149698.OudOcW.rst | 2 -
...-05-13-14-53-23.gh-issue-149776.orqgsn.rst | 2 -
...-05-25-15-39-53.gh-issue-150387.yzZ7jq.rst | 5 -
...-05-22-18-51-09.gh-issue-150258.dh8GVK.rst | 1 -
...-04-26-23-14-45.gh-issue-149029.oPTXP4.rst | 1 -
...-04-29-14-44-51.gh-issue-138489.234aj6.rst | 4 -
...-05-06-21-36-53.gh-issue-124111.m4OBX8.rst | 1 -
...-05-14-22-09-46.gh-issue-149786.UI-HZM.rst | 1 -
...-04-26-23-15-09.gh-issue-149029.Lsx--T.rst | 1 -
...-05-31-10-40-00.gh-issue-150644.zLWyjj.rst | 3 -
README.rst | 2 +-
81 files changed, 987 insertions(+), 272 deletions(-)
create mode 100644 Misc/NEWS.d/3.15.0b2.rst
delete mode 100644 Misc/NEWS.d/next/Build/2026-05-18-16-00-41.gh-issue-148260.UwFiIX.rst
delete mode 100644 Misc/NEWS.d/next/Build/2026-05-21-15-14-59.gh-issue-148294.VtFaW4.rst
delete mode 100644 Misc/NEWS.d/next/C_API/2026-02-25-13-37-10.gh-issue-145235.-1ySNR.rst
delete mode 100644 Misc/NEWS.d/next/C_API/2026-05-12-16-47-21.gh-issue-149725.HZLBTZ.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-04-15-15-48-04.gh-issue-148450.2MEVqH.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-07-03-18-59.gh-issue-149459.5fhAqP.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-09-15-22-32.gh-issue-144957.u1F2aQ.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-10-07-42-36.gh-issue-149642.6ZksML.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-10-16-43-50.gh-issue-148829.gscS14.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-11-14-48-56.gh-issue-149676.6aTrw1.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-12-16-47-23.gh-issue-139808.iIs7_E.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-13-06-54-41.gh-issue-149738.4BLFoH.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-14-19-41-03.gh-issue-149807.IwGaCo.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-15-11-31-57.gh-issue-149816.ugN2rx.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-16-11-03-54.gh-issue-149816.X_gqMT.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-18-13-47-17.gh-issue-149590.IPBeQx.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-18-16-54-54.gh-issue-150042.LSr5W8.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-18-18-36-28.gh-issue-148587.-RD3z5.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-20-13-06-17.gh-issue-150146.i5m_SL.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-22-17-09-28.gh-issue-150107.GD72-D.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-23-22-08-01.gh-issue-149449.2lhQFF.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-24-14-45-00.gh-issue-149156.NP73rB.rst
delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-05-25-16-00-22.gh-issue-150374.Emu6d8.rst
delete mode 100644 Misc/NEWS.d/next/Library/2021-10-18-13-46-55.bpo-45509.Upwb60.rst
delete mode 100644 Misc/NEWS.d/next/Library/2024-07-02-20-57-43.gh-issue-121109.Tp6R2s.rst
delete mode 100644 Misc/NEWS.d/next/Library/2024-11-02-02-02-31.gh-issue-107398.uUtA6Q.rst
delete mode 100644 Misc/NEWS.d/next/Library/2025-03-01-13-36-02.gh-issue-128110.9wx_G0.rst
delete mode 100644 Misc/NEWS.d/next/Library/2025-05-19-20-29-35.gh-issue-133998.KmElUw.rst
delete mode 100644 Misc/NEWS.d/next/Library/2025-05-19-21-08-25.gh-issue-134261.ravGYm.rst
delete mode 100644 Misc/NEWS.d/next/Library/2025-08-30-07-44-30.gh-issue-86533.pathlib.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-03-26-09-30-00.gh-issue-146452.Y2N6qZ8J.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-04-23-12-50-15.gh-issue-148441.zvpCkR.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-04-27-11-12-00.gh-issue-149046.74shDd.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-04-29-08-10-17.gh-issue-149056.jnaD4W.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-07-14-18-47.gh-issue-149489.bX9iHe.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-07-21-58-17.gh-issue-149388.DDBPeA.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-08-09-11-48.gh-issue-149534.Tw7eeY.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-08-15-08-35.gh-issue-112821.t9T1YD.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-09-21-02-08.gh-issue-149614.U4snj3.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-10-07-21-51.gh-issue-139489.rS7LTA.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-10-19-26-50.gh-issue-149584.x7Qm9A.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-10-23-51-23.gh-issue-149504.pDSCbn.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-12-06-24-54.gh-issue-149701.8v9RTm.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-12-13-03-45.gh-issue-149718.SaM1NJ.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-13-23-18-39.gh-issue-149801.S_FfGr.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-14-15-55-28.gh-issue-149816.ZaXQ0q.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-15-16-28-00.gh-issue-149819.fixpth.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-15-18-44-20.gh-issue-142349.fHK3v1.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-16-21-08-33.gh-issue-149921.I1yNML.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-17-02-25-56.gh-issue-149571.LNyuWJ.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-17-22-37-02.gh-issue-88726.BAoL6j.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-18-07-44-46.gh-issue-149995.vvtFHn.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-18-17-17-20.gh-issue-149189.a8IooK.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-19-19-00-49.gh-issue-84353.ZU5zaQ.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-21-11-25-58.gh-issue-150175.8H4Caz.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-21-20-47-45.gh-issue-150157.ZvmO-bQZ.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-25-07-22-05.gh-issue-150372.9hLqhe.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-25-17-00-00.gh-issue-150406.jF3g63.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-27-11-18-36.gh-issue-150228.pNPiO-.rst
delete mode 100644 Misc/NEWS.d/next/Library/2026-05-31-17-47-30.gh-issue-150685.EBB2mU.rst
delete mode 100644 Misc/NEWS.d/next/Security/2026-04-26-19-30-45.gh-issue-149018.a9SqWb.rst
delete mode 100644 Misc/NEWS.d/next/Security/2026-04-27-16-36-11.gh-issue-149079.vKl-LM.rst
delete mode 100644 Misc/NEWS.d/next/Security/2026-05-03-21-00-00.gh-issue-149486.tarflt.rst
delete mode 100644 Misc/NEWS.d/next/Security/2026-05-08-02-18-54.gh-issue-149474.ujQ-mu.rst
delete mode 100644 Misc/NEWS.d/next/Security/2026-05-10-18-05-32.gh-issue-87451.XkKB6M.rst
delete mode 100644 Misc/NEWS.d/next/Security/2026-05-11-21-15-07.gh-issue-149698.OudOcW.rst
delete mode 100644 Misc/NEWS.d/next/Tests/2026-05-13-14-53-23.gh-issue-149776.orqgsn.rst
delete mode 100644 Misc/NEWS.d/next/Tests/2026-05-25-15-39-53.gh-issue-150387.yzZ7jq.rst
delete mode 100644 Misc/NEWS.d/next/Tools-Demos/2026-05-22-18-51-09.gh-issue-150258.dh8GVK.rst
delete mode 100644 Misc/NEWS.d/next/Windows/2026-04-26-23-14-45.gh-issue-149029.oPTXP4.rst
delete mode 100644 Misc/NEWS.d/next/Windows/2026-04-29-14-44-51.gh-issue-138489.234aj6.rst
delete mode 100644 Misc/NEWS.d/next/Windows/2026-05-06-21-36-53.gh-issue-124111.m4OBX8.rst
delete mode 100644 Misc/NEWS.d/next/Windows/2026-05-14-22-09-46.gh-issue-149786.UI-HZM.rst
delete mode 100644 Misc/NEWS.d/next/macOS/2026-04-26-23-15-09.gh-issue-149029.Lsx--T.rst
delete mode 100644 Misc/NEWS.d/next/macOS/2026-05-31-10-40-00.gh-issue-150644.zLWyjj.rst
diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst
index 3a75d44f3f7d21..36f080b56ffea7 100644
--- a/Doc/library/sqlite3.rst
+++ b/Doc/library/sqlite3.rst
@@ -1417,7 +1417,7 @@ Connection objects
See :ref:`sqlite3-howto-row-factory` for more details.
- .. versionchanged:: next
+ .. versionchanged:: 3.15
Deleting the ``row_factory`` attribute is no longer allowed.
.. attribute:: text_factory
@@ -1429,7 +1429,7 @@ Connection objects
See :ref:`sqlite3-howto-encoding` for more details.
- .. versionchanged:: next
+ .. versionchanged:: 3.15
Deleting the ``text_factory`` attribute is no longer allowed.
.. attribute:: total_changes
@@ -1715,7 +1715,7 @@ Cursor objects
See :ref:`sqlite3-howto-row-factory` for more details.
- .. versionchanged:: next
+ .. versionchanged:: 3.15
Deleting the ``row_factory`` attribute is no longer allowed.
diff --git a/Include/patchlevel.h b/Include/patchlevel.h
index cdca931566577f..649609136fec80 100644
--- a/Include/patchlevel.h
+++ b/Include/patchlevel.h
@@ -24,10 +24,10 @@
#define PY_MINOR_VERSION 15
#define PY_MICRO_VERSION 0
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA
-#define PY_RELEASE_SERIAL 1
+#define PY_RELEASE_SERIAL 2
/* Version as a string */
-#define PY_VERSION "3.15.0b1+"
+#define PY_VERSION "3.15.0b2"
/*--end constants--*/
diff --git a/Lib/pydoc_data/module_docs.py b/Lib/pydoc_data/module_docs.py
index 1a3126d3db9590..0505210b0bfe0d 100644
--- a/Lib/pydoc_data/module_docs.py
+++ b/Lib/pydoc_data/module_docs.py
@@ -1,4 +1,4 @@
-# Autogenerated by Sphinx on Thu May 7 16:26:23 2026
+# Autogenerated by Sphinx on Tue Jun 2 18:28:34 2026
# as part of the release process.
module_docs = {
diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py
index 5f61001c46b79c..3ab289ebed6a6f 100644
--- a/Lib/pydoc_data/topics.py
+++ b/Lib/pydoc_data/topics.py
@@ -1,4 +1,4 @@
-# Autogenerated by Sphinx on Thu May 7 16:26:23 2026
+# Autogenerated by Sphinx on Tue Jun 2 18:28:34 2026
# as part of the release process.
topics = {
@@ -2344,9 +2344,9 @@ def foo():
The match statement is used for pattern matching. Syntax:
match_stmt: 'match' subject_expr ":" NEWLINE INDENT case_block+ DEDENT
- subject_expr: `!star_named_expression` "," `!star_named_expressions`?
- | `!named_expression`
- case_block: 'case' patterns [guard] ":" `!block`
+ subject_expr: flexible_expression "," [flexible_expression_list [',']]
+ | assignment_expression
+ case_block: 'case' patterns [guard] ":" suite
Note:
@@ -2437,7 +2437,7 @@ def foo():
Guards
------
- guard: "if" `!named_expression`
+ guard: "if" assignment_expression
A "guard" (which is part of the "case") must succeed for code inside
the "case" block to execute. It takes the form: "if" followed by an
@@ -4971,61 +4971,49 @@ def inner(x):
'dict': r'''Dictionary displays
*******************
-A dictionary display is a possibly empty series of dict items
-(key/value pairs) enclosed in curly braces:
-
- dict_display: "{" [dict_item_list | dict_comprehension] "}"
- dict_item_list: dict_item ("," dict_item)* [","]
- dict_comprehension: dict_item comp_for
- dict_item: expression ":" expression | "**" or_expr
-
-A dictionary display yields a new dictionary object.
-
-If a comma-separated sequence of dict items is given, they are
-evaluated from left to right to define the entries of the dictionary:
-each key object is used as a key into the dictionary to store the
-corresponding value. This means that you can specify the same key
-multiple times in the dict item list, and the final dictionary’s value
-for that key will be the last one given.
-
-A double asterisk "**" denotes *dictionary unpacking*. Its operand
-must be a *mapping*. Each mapping item is added to the new
-dictionary. Later values replace values already set by earlier dict
-items and earlier dictionary unpackings.
+A *dictionary display* is a possibly empty series of *dict items*
+enclosed in curly braces. Each dict item is a colon-separated pair of
+expressions: the *key* and its associated *value*. For example:
+
+ >>> {1: 'one', 2: 'two'}
+ {1: 'one', 2: 'two'}
+
+At runtime, when a dictionary comprehension is evaluated, the
+expressions are evaluated from left to right. Each key object is used
+as a key into the dictionary to store the corresponding value. This
+means that you can specify the same key multiple times in the
+comprehension, and the final dictionary’s value for a given key will
+be the last one given. For example:
+
+ >>> {
+ ... 1: 'this will be overridden',
+ ... 2: 'two',
+ ... 1: 'also overridden',
+ ... 1: 'one',
+ ... }
+ {1: 'one', 2: 'two'}
+
+Instead of a key-value pair, a dict item may be an expression prefixed
+by a double asterisk "**". This denotes *dictionary unpacking*. At
+runtime, the expression must evaluate to a *mapping*; each item of the
+mapping is added to the new dictionary. As with key-value pairs, later
+values replace values already set by earlier items and unpackings.
+This may be used to override a set of defaults:
+
+ >>> defaults = {'color': 'blue', 'count': 8}
+ >>> overrides = {'color': 'yellow'}
+ >>> {**defaults, **overrides}
+ {'color': 'yellow', 'count': 8}
Added in version 3.5: Unpacking into dictionary displays, originally
proposed by **PEP 448**.
-A dict comprehension may take one of two forms:
-
-* The first form uses two expressions separated with a colon followed
- by the usual “for” and “if” clauses. When the comprehension is run,
- the resulting key and value elements are inserted in the new
- dictionary in the order they are produced.
-
-* The second form uses a single expression prefixed by the "**"
- dictionary unpacking operator followed by the usual “for” and “if”
- clauses. When the comprehension is evaluated, the expression is
- evaluated and then unpacked, inserting zero or more key/value pairs
- into the new dictionary.
-
-Both forms of dictionary comprehension retain the property that if the
-same key is specified multiple times, the associated value in the
-resulting dictionary will be the last one specified.
-
-Restrictions on the types of the key values are listed earlier in
-section The standard type hierarchy. (To summarize, the key type
-should be *hashable*, which excludes all mutable objects.) Clashes
-between duplicate keys are not detected; the last value (textually
-rightmost in the display) stored for a given key value prevails.
+The formal grammar for dict displays is:
-Changed in version 3.8: Prior to Python 3.8, in dict comprehensions,
-the evaluation order of key and value was not well-defined. In
-CPython, the value was evaluated before the key. Starting with 3.8,
-the key is evaluated before the value, as proposed by **PEP 572**.
-
-Changed in version 3.15: Unpacking with the "**" operator is now
-allowed in dictionary comprehensions.
+ dict: '{' [double_starred_kvpairs] '}'
+ double_starred_kvpairs: ','.double_starred_kvpair+ [',']
+ double_starred_kvpair: '**' or_expr | kvpair
+ kvpair: expression ':' expression
''',
'dynamic-features': r'''Interaction with dynamic features
*********************************
@@ -5655,8 +5643,22 @@ class of the instance or a *non-virtual base class* thereof. The
is the number of expressions in the list. The expressions are
evaluated from left to right.
-An asterisk "*" denotes *iterable unpacking*. Its operand must be an
-*iterable*. The iterable is expanded into a sequence of items, which
+A trailing comma is required only to create a one-item tuple, such as
+"1,"; it is optional in all other cases. A single expression without a
+trailing comma doesn’t create a tuple, but rather yields the value of
+that expression. (To create an empty tuple, use an empty pair of
+parentheses: "()".)
+
+
+Iterable unpacking
+==================
+
+In an expression list or tuple, list or set display, any expression
+may be prefixed with an asterisk ("*"). This denotes *iterable
+unpacking*.
+
+At runtime, the asterisk-prefixed expression must evaluate to an
+*iterable*. The iterable is expanded into a sequence of items, which
are included in the new tuple, list, or set, at the site of the
unpacking.
@@ -5665,12 +5667,6 @@ class of the instance or a *non-virtual base class* thereof. The
Added in version 3.11: Any item in an expression list may be starred.
See **PEP 646**.
-
-A trailing comma is required only to create a one-item tuple, such as
-"1,"; it is optional in all other cases. A single expression without a
-trailing comma doesn’t create a tuple, but rather yields the value of
-that expression. (To create an empty tuple, use an empty pair of
-parentheses: "()".)
''',
'floating': r'''Floating-point literals
***********************
@@ -6015,7 +6011,8 @@ class of the instance or a *non-virtual base class* thereof. The
| | is not supported. |
+-----------+------------------------------------------------------------+
-For a locale aware separator, use the "'n'" presentation type instead.
+For a locale-aware separator, use the "'n'" float presentation type or
+integer presentation type instead.
Changed in version 3.1: Added the "','" option (see also **PEP 378**).
@@ -6061,7 +6058,10 @@ class of the instance or a *non-virtual base class* thereof. The
+-----------+------------------------------------------------------------+
| "'n'" | Number. This is the same as "'d'", except that it uses the |
| | current locale setting to insert the appropriate digit |
- | | group separators. |
+ | | group separators. Note that the default locale is not the |
+ | | system locale. Depending on your use case, you may wish to |
+ | | set "LC_NUMERIC" with "locale.setlocale()" before using |
+ | | "'n'". |
+-----------+------------------------------------------------------------+
| None | The same as "'d'". |
+-----------+------------------------------------------------------------+
@@ -6135,7 +6135,10 @@ class of the instance or a *non-virtual base class* thereof. The
+-----------+------------------------------------------------------------+
| "'n'" | Number. This is the same as "'g'", except that it uses the |
| | current locale setting to insert the appropriate digit |
- | | group separators for the integral part of a number. |
+ | | group separators for the integral part of a number. Note |
+ | | that the default locale is not the system locale. |
+ | | Depending on your use case, you may wish to set |
+ | | "LC_NUMERIC" with "locale.setlocale()" before using "'n'". |
+-----------+------------------------------------------------------------+
| "'%'" | Percentage. Multiplies the number by 100 and displays in |
| | fixed ("'f'") format, followed by a percent sign. |
@@ -7231,21 +7234,113 @@ def (parameters):
See section Function definitions for the syntax of parameter lists.
Note that functions created with lambda expressions cannot contain
statements or annotations.
+''',
+ 'lazy': r'''Lazy imports
+************
+
+The "lazy" keyword is a soft keyword that only has special meaning
+when it appears immediately before an "import" or "from" statement.
+When an import statement is preceded by the "lazy" keyword, the import
+becomes *lazy*: the module is not loaded immediately at the import
+statement. Instead, a lazy proxy object is created and bound to the
+name. The actual module is loaded on first use of that name.
+
+Lazy imports are only permitted at module scope. Using "lazy" inside a
+function, class body, or "try"/"except"/"finally" block raises a
+"SyntaxError". Star imports cannot be lazy ("lazy from module import
+*" is a syntax error), and future statements cannot be lazy.
+
+When using "lazy from ... import", each imported name is bound to a
+lazy proxy object. The first access to any of these names triggers
+loading of the entire module and resolves only that specific name to
+its actual value. Other names remain as lazy proxies until they are
+accessed.
+
+Example:
+
+ lazy import json
+ import sys
+
+ print('json' in sys.modules) # False - json module not yet loaded
+
+ # First use triggers loading
+ result = json.dumps({"hello": "world"})
+
+ print('json' in sys.modules) # True - now loaded
+
+If an error occurs during module loading (such as "ImportError" or
+"SyntaxError"), it is raised at the point where the lazy import is
+first used, not at the import statement itself.
+
+See **PEP 810** for the full specification of lazy imports.
+
+Added in version 3.15.
+
+
+Compatibility via "__lazy_modules__"
+====================================
+
+As an alternative to using the "lazy" keyword, a module can opt into
+lazy loading for specific imports by defining a module-level
+"__lazy_modules__" variable. When present, it must be a container of
+fully qualified module name strings. Any regular (non-"lazy")
+"import" statement at module scope whose target appears in
+"__lazy_modules__" is treated as a lazy import, exactly as if the
+"lazy" keyword had been used.
+
+This provides a way to enable lazy loading for specific dependencies
+without changing individual "import" statements. This is useful when
+supporting Python versions older than 3.15 while using lazy imports in
+3.15+:
+
+ __lazy_modules__ = ["json", "pathlib"]
+
+ import json # loaded lazily (name is in __lazy_modules__)
+ import os # loaded eagerly (name not in __lazy_modules__)
+
+ import pathlib # loaded lazily
+
+Relative imports are resolved to their absolute name before the
+lookup, so "__lazy_modules__" must always contain fully qualified
+module names.
+
+For "from"-style imports, the relevant name is the module following
+"from", not the names of its members:
+
+ # In mypackage/mymodule.py
+ __lazy_modules__ = ["mypackage", "mypackage.sub.utils"]
+
+ from . import helper # loaded lazily: . resolves to mypackage
+ from .sub.utils import func # loaded lazily: .sub.utils resolves to mypackage.sub.utils
+ import json # loaded eagerly (not in __lazy_modules__)
+
+Imports inside functions, class bodies, or "try"/"except"/"finally"
+blocks are always eager, regardless of "__lazy_modules__".
+
+Setting "-X lazy_imports=none" (or the "PYTHON_LAZY_IMPORTS"
+environment variable to "none") overrides "__lazy_modules__" and
+forces all imports to be eager.
+
+Added in version 3.15.
''',
'lists': r'''List displays
*************
-A list display is a possibly empty series of expressions enclosed in
-square brackets:
+A *list display* is a possibly empty series of expressions enclosed in
+square brackets. For example:
+
+ >>> ["one", "two", "three"]
+ ['one', 'two', 'three']
+ >>> ["one"] # One-element list
+ ['one']
+ >>> [] # empty list
+ []
- list_display: "[" [flexible_expression_list | comprehension] "]"
+See Container displays for general information on displays.
-A list display yields a new list object, the contents being specified
-by either a list of expressions or a comprehension. When a comma-
-separated list of expressions is supplied, its elements are evaluated
-from left to right and placed into the list object in that order.
-When a comprehension is supplied, the list is constructed from the
-elements resulting from the comprehension.
+The formal grammar for list displays is:
+
+ list: '[' [flexible_expression_list] ']'
''',
'naming': r'''Naming and binding
******************
@@ -11059,6 +11154,8 @@ class is used in a class pattern with positional arguments, each
not a prefix or suffix; rather, all combinations of its values are
stripped.
+ Whitespace characters are defined by "str.isspace()".
+
For example:
>>> ' spacious '.strip()
@@ -12447,7 +12544,7 @@ def foo():
target of assignments or "del" statements. The built-in function
"len()" returns the number of items in a mapping.
-There is currently a single intrinsic mapping type:
+There are two intrinsic mapping types:
Dictionaries
@@ -12481,6 +12578,18 @@ def foo():
rather than a language guarantee.
+Frozen dictionaries
+-------------------
+
+These represent an immutable dictionary. They are created by the
+built-in "frozendict()" constructor. A frozendict is *hashable* if
+all of its keys and values are hashable, in which case it can be used
+as an element of a set, or as a key in another mapping. "frozendict"
+is not a subclass of "dict"; it inherits directly from "object".
+
+Added in version 3.15.
+
+
Callable types
==============
diff --git a/Misc/NEWS.d/3.15.0b2.rst b/Misc/NEWS.d/3.15.0b2.rst
new file mode 100644
index 00000000000000..24fef1907d5122
--- /dev/null
+++ b/Misc/NEWS.d/3.15.0b2.rst
@@ -0,0 +1,795 @@
+.. date: 2026-05-11-21-15-07
+.. gh-issue: 149698
+.. nonce: OudOcW
+.. release date: 2026-06-02
+.. section: Security
+
+Update bundled `libexpat `_ to version 2.8.1
+for the fix for :cve:`2026-45186`.
+
+..
+
+.. date: 2026-05-10-18-05-32
+.. gh-issue: 87451
+.. nonce: XkKB6M
+.. section: Security
+
+The :mod:`ftplib` module's undocumented ``ftpcp`` function no longer trusts
+the IPv4 address value returned from the source server in response to the
+``PASV`` command by default, completing the fix for CVE-2021-4189. As with
+:class:`ftplib.FTP`, the former behavior can be re-enabled by setting the
+``trust_server_pasv_ipv4_address`` attribute on the source
+:class:`ftplib.FTP` instance to ``True``. Thanks to Qi Deng at Aurascape AI
+for the report.
+
+..
+
+.. date: 2026-05-08-02-18-54
+.. gh-issue: 149474
+.. nonce: ujQ-mu
+.. section: Security
+
+Fix the binary writer in :mod:`profiling.sampling` not firing the audit
+(:pep:`578`) when creating the output file. The writer and the reader now
+accept any path-like object. Patch by Maurycy Pawłowski-Wieroński.
+
+..
+
+.. date: 2026-05-03-21-00-00
+.. gh-issue: 149486
+.. nonce: tarflt
+.. section: Security
+
+:func:`tarfile.data_filter` now validates link targets using the same
+normalised value that is written to disk, strips trailing separators from
+the member name when resolving a symlink's directory, and rejects link
+members that would replace the destination directory itself. This closes
+several path-traversal bypasses of the ``data`` extraction filter.
+
+..
+
+.. date: 2026-04-27-16-36-11
+.. gh-issue: 149079
+.. nonce: vKl-LM
+.. section: Security
+
+Fix a potential denial of service in :func:`unicodedata.normalize`. The
+canonical ordering step of Unicode normalization used a quadratic-time
+insertion sort for reordering combining characters, which could be exploited
+with crafted input containing many combining characters in non-canonical
+order. Replaced with a linear-time counting sort for long runs.
+
+..
+
+.. date: 2026-04-26-19-30-45
+.. gh-issue: 149018
+.. nonce: a9SqWb
+.. section: Security
+
+Improved protection against XML hash-flooding attacks in
+:mod:`xml.parsers.expat` and :mod:`xml.etree.ElementTree` when Python is
+compiled with libExpat 2.8.0 or later.
+
+..
+
+.. date: 2026-05-25-16-00-22
+.. gh-issue: 150374
+.. nonce: Emu6d8
+.. section: Core and Builtins
+
+Fix double release of the import lock on lazy import reification errors.
+
+..
+
+.. date: 2026-05-24-14-45-00
+.. gh-issue: 149156
+.. nonce: NP73rB
+.. section: Core and Builtins
+
+Fix an intermittent crash after :func:`os.fork` when perf trampoline
+profiling is enabled and the child returns through trampoline frames
+inherited from the parent process.
+
+..
+
+.. date: 2026-05-23-22-08-01
+.. gh-issue: 149449
+.. nonce: 2lhQFF
+.. section: Core and Builtins
+
+Fix a use-after-free crash when the :mod:`unicodedata` module was removed
+from :data:`sys.modules` and garbage-collected between calls that decode
+``\N{...}`` escapes or use the ``namereplace`` codec error handler.
+
+..
+
+.. date: 2026-05-22-17-09-28
+.. gh-issue: 150107
+.. nonce: GD72-D
+.. section: Core and Builtins
+
+:mod:`asyncio`: ``sendfile()`` and ``sock_sendfile()`` event loop methods
+now call ``file.seek(offset)`` if *file* has a ``seek()`` method, even if
+*offset* is ``0`` (default value).
+
+..
+
+.. date: 2026-05-20-13-06-17
+.. gh-issue: 150146
+.. nonce: i5m_SL
+.. section: Core and Builtins
+
+Fix a crash on a complex type variable substitution.
+
+``from typing import TypeVar; memoryview[TypeVar("")][*typing.Mapping[...,
+...]]`` used to fail due to missing ``NULL`` check on ``_unpack_args`` C
+function call.
+
+..
+
+.. date: 2026-05-18-18-36-28
+.. gh-issue: 148587
+.. nonce: -RD3z5
+.. section: Core and Builtins
+
+``sys.lazy_modules`` is now a set instead of a dict as initially spelled out
+in PEP 810.
+
+..
+
+.. date: 2026-05-18-16-54-54
+.. gh-issue: 150042
+.. nonce: LSr5W8
+.. section: Core and Builtins
+
+Fix refleak in queue.SimpleQueue.put if memory allocation fails.
+
+..
+
+.. date: 2026-05-18-13-47-17
+.. gh-issue: 149590
+.. nonce: IPBeQx
+.. section: Core and Builtins
+
+Fix crash when faulthandler is imported more than once.
+
+..
+
+.. date: 2026-05-16-11-03-54
+.. gh-issue: 149816
+.. nonce: X_gqMT
+.. section: Core and Builtins
+
+Fix a race condition in ``_PyBytes_FromList`` in free-threading mode.
+
+..
+
+.. date: 2026-05-15-11-31-57
+.. gh-issue: 149816
+.. nonce: ugN2rx
+.. section: Core and Builtins
+
+Fix a race condition in :class:`memoryview` with free-threading.
+
+..
+
+.. date: 2026-05-14-19-41-03
+.. gh-issue: 149807
+.. nonce: IwGaCo
+.. section: Core and Builtins
+
+Fix ``hash(frozendict)``: compute the hash of each ``(key, value)`` pair
+correctly. Patch by Victor Stinner.
+
+..
+
+.. date: 2026-05-13-06-54-41
+.. gh-issue: 149738
+.. nonce: 4BLFoH
+.. section: Core and Builtins
+
+:mod:`sqlite3`: Disallow removing ``row_factory`` and ``text_factory``
+attributes of a connection to prevent a crash on a query.
+
+..
+
+.. date: 2026-05-12-16-47-23
+.. gh-issue: 139808
+.. nonce: iIs7_E
+.. section: Core and Builtins
+
+Add branch protections for AArch64 (BTI/PAC) in assembly code used by
+:option:`-X perf_jit <-X>` (Linux perf profiler integration).
+
+..
+
+.. date: 2026-05-11-14-48-56
+.. gh-issue: 149676
+.. nonce: 6aTrw1
+.. section: Core and Builtins
+
+Fix ``frozendict | frozendict`` hash.
+
+..
+
+.. date: 2026-05-10-16-43-50
+.. gh-issue: 148829
+.. nonce: gscS14
+.. section: Core and Builtins
+
+:class:`sentinel` objects now support a ``repr=`` argument and their
+:attr:`~sentinel.__module__` attribute is writable.
+
+..
+
+.. date: 2026-05-10-07-42-36
+.. gh-issue: 149642
+.. nonce: 6ZksML
+.. section: Core and Builtins
+
+Allow imports inside ``exec()`` calls within functions under
+``PYTHON_LAZY_IMPORTS=all``.
+
+..
+
+.. date: 2026-05-09-15-22-32
+.. gh-issue: 144957
+.. nonce: u1F2aQ
+.. section: Core and Builtins
+
+Fix lazy ``from`` imports of module attributes provided by module-level
+``__getattr__``.
+
+..
+
+.. date: 2026-05-07-03-18-59
+.. gh-issue: 149459
+.. nonce: 5fhAqP
+.. section: Core and Builtins
+
+Fix a crash in the JIT optimizer when a specialized ``LOAD_SPECIAL`` guard
+deoptimized after inserting the synthetic ``NULL`` stack entry.
+
+..
+
+.. date: 2026-04-15-15-48-04
+.. gh-issue: 148450
+.. nonce: 2MEVqH
+.. section: Core and Builtins
+
+Fix ``abc.register()`` so it invalidates type version tags for registered
+classes.
+
+..
+
+.. date: 2026-05-31-17-47-30
+.. gh-issue: 150685
+.. nonce: EBB2mU
+.. section: Library
+
+Update bundled pip to 26.1.2
+
+..
+
+.. date: 2026-05-27-11-18-36
+.. gh-issue: 150228
+.. nonce: pNPiO-
+.. section: Library
+
+The new :class:`site.StartupState` class lets callers batch-process
+:pep:`829` startup configuration files across multiple site directories
+before any startup code runs, with public
+:meth:`~site.StartupState.addsitedir`,
+:meth:`~site.StartupState.addusersitepackages`,
+:meth:`~site.StartupState.addsitepackages`, and
+:meth:`~site.StartupState.process` methods. The signature of
+:func:`site.addsitedir` is unchanged from Python 3.14. The
+:data:`!defer_processing_start_files` argument and the
+``process_startup_files()`` function added earlier in the 3.15 cycle have
+been removed; use :class:`!site.StartupState` instead.
+
+..
+
+.. date: 2026-05-25-17-00-00
+.. gh-issue: 150406
+.. nonce: jF3g63
+.. section: Library
+
+Fix a possible crash occurring during :mod:`socket` module initialization
+when the system is out of memory on platforms without a reentrant
+``gethostbyname``.
+
+..
+
+.. date: 2026-05-25-07-22-05
+.. gh-issue: 150372
+.. nonce: 9hLqhe
+.. section: Library
+
+:mod:`readline`: Fix a potential crash during tab completion caused by an
+out-of-memory error during module initialization.
+
+..
+
+.. date: 2026-05-21-20-47-45
+.. gh-issue: 150157
+.. nonce: ZvmO-bQZ
+.. section: Library
+
+Fix a crash in free-threaded builds that occurs when pickling by name
+objects without a ``__module__`` attribute while :data:`sys.modules` is
+concurrently being modified.
+
+..
+
+.. date: 2026-05-21-11-25-58
+.. gh-issue: 150175
+.. nonce: 8H4Caz
+.. section: Library
+
+Fix race condition in :class:`unittest.mock.ThreadingMock` where concurrent
+calls could lose increments to ``call_count`` and other attributes due to a
+missing lock in ``_increment_mock_call``.
+
+..
+
+.. date: 2026-05-19-19-00-49
+.. gh-issue: 84353
+.. nonce: ZU5zaQ
+.. section: Library
+
+Preserve non-UTF-8 encoded filenames when appending to a
+:class:`zipfile.ZipFile`. Previously, non-ASCII names stored in a legacy
+encoding (without the UTF-8 flag bit set) could be corrupted when the
+central directory was rewritten: they were decoded as cp437 and then
+re-stored as UTF-8.
+
+..
+
+.. date: 2026-05-18-17-17-20
+.. gh-issue: 149189
+.. nonce: a8IooK
+.. section: Library
+
+Revert the changes to :mod:`pprint` defaults. Patch by Hugo van Kemenade.
+
+..
+
+.. date: 2026-05-18-07-44-46
+.. gh-issue: 149995
+.. nonce: vvtFHn
+.. section: Library
+
+Update various docstrings in :mod:`typing`.
+
+..
+
+.. date: 2026-05-17-22-37-02
+.. gh-issue: 88726
+.. nonce: BAoL6j
+.. section: Library
+
+The :mod:`email` package now uses standard MIME charset names "gb2312" and
+"big5" instead of non-standard names "eucgb2312_cn" and "big5_tw".
+
+..
+
+.. date: 2026-05-17-02-25-56
+.. gh-issue: 149571
+.. nonce: LNyuWJ
+.. section: Library
+
+Fix the C implementation of :meth:`xml.etree.ElementTree.Element.itertext`:
+it no longer emits text for comments and processing instructions.
+
+..
+
+.. date: 2026-05-16-21-08-33
+.. gh-issue: 149921
+.. nonce: I1yNML
+.. section: Library
+
+Fix reference leaks in error paths of the :mod:`!_interpchannels` and
+:mod:`!_interpqueues` extension modules.
+
+..
+
+.. date: 2026-05-15-18-44-20
+.. gh-issue: 142349
+.. nonce: fHK3v1
+.. section: Library
+
+Add :keyword:`lazy` to the list of support topic by :func:`help`.
+
+..
+
+.. date: 2026-05-15-16-28-00
+.. gh-issue: 149819
+.. nonce: fixpth
+.. section: Library
+
+Fix regression in :func:`site.addsitedir` where ``.pth`` files were no
+longer processed in Python subprocesses. This happened because
+:func:`site.main` seeded ``known_paths`` with entries inherited from the
+parent process, causing ``addsitedir`` to skip ``.pth`` processing.
+
+..
+
+.. date: 2026-05-14-15-55-28
+.. gh-issue: 149816
+.. nonce: ZaXQ0q
+.. section: Library
+
+Fix a race condition in ``_random.Random.__init__`` method in free-threading
+mode.
+
+..
+
+.. date: 2026-05-13-23-18-39
+.. gh-issue: 149801
+.. nonce: S_FfGr
+.. section: Library
+
+Add IANA registered names and aliases with leading zeros before number (like
+IBM00858, CP00858, IBM01140, CP01140) for corresponding codecs.
+
+..
+
+.. date: 2026-05-12-13-03-45
+.. gh-issue: 149718
+.. nonce: SaM1NJ
+.. section: Library
+
+Coalesce consecutive identical stack frames in Tachyon, so aggregating
+collectors (pstats, collapsed, flamegraph, gecko) receive one collect.
+Improves sample rate 3x, error rate and missed rate drop by 70%. Patch by
+Maurycy Pawłowski-Wieroński.
+
+..
+
+.. date: 2026-05-12-06-24-54
+.. gh-issue: 149701
+.. nonce: 8v9RTm
+.. section: Library
+
+Fix bad return code from Lib/venv/bin/activate if hashing is disabled
+
+..
+
+.. date: 2026-05-10-23-51-23
+.. gh-issue: 149504
+.. nonce: pDSCbn
+.. section: Library
+
+Fix :func:`site.addsitedir` to allow re-entrant calls from within startup
+files. Previously, a ``.pth`` file containing an ``import`` line that
+called :func:`site.addsitedir` (or a ``.start`` entry point doing the same)
+could crash with ``RuntimeError: dictionary changed size during iteration``
+during site initialization, breaking tools such as ``uv run --with``.
+
+..
+
+.. date: 2026-05-10-19-26-50
+.. gh-issue: 149584
+.. nonce: x7Qm9A
+.. section: Library
+
+Fix excessive overhead in the Tachyon profiler when inspecting a remote
+process by avoiding repeated remote page-cache scans, batching predicted
+remote reads, and reusing cached profiler result objects. Patch by Pablo
+Galindo and Maurycy Pawłowski-Wieroński.
+
+..
+
+.. date: 2026-05-10-07-21-51
+.. gh-issue: 139489
+.. nonce: rS7LTA
+.. section: Library
+
+Add :func:`xml.is_valid_text` to ``xml.__all__``.
+
+..
+
+.. date: 2026-05-09-21-02-08
+.. gh-issue: 149614
+.. nonce: U4snj3
+.. section: Library
+
+Fix a regression that broke the ability to deepcopy
+:class:`argparse.ArgumentParser` instances.
+
+..
+
+.. date: 2026-05-08-15-08-35
+.. gh-issue: 112821
+.. nonce: t9T1YD
+.. section: Library
+
+In the REPL, autocompletion might run arbitrary code in the getter of a
+descriptor. If that getter raised an exception, autocompletion would fail to
+present any options for the entire object. Autocompletion now works as
+expected for these objects.
+
+..
+
+.. date: 2026-05-08-09-11-48
+.. gh-issue: 149534
+.. nonce: Tw7eeY
+.. section: Library
+
+Fix merging of :class:`collections.defaultdict` and :class:`frozendict`.
+
+..
+
+.. date: 2026-05-07-21-58-17
+.. gh-issue: 149388
+.. nonce: DDBPeA
+.. section: Library
+
+Make :class:`!asyncio.windows_utils.PipeHandle` closing idempotent.
+
+..
+
+.. date: 2026-05-07-14-18-47
+.. gh-issue: 149489
+.. nonce: bX9iHe
+.. section: Library
+
+Fix :mod:`~xml.etree.ElementTree` serialization to HTML. The content of
+comments, processing instructions and elements "xmp", "iframe", "noembed",
+"noframes", and "plaintext" is no longer escaped. The "plaintext" element no
+longer have the closing tag. Add support of empty attributes (with value
+``None``).
+
+..
+
+.. date: 2026-04-29-08-10-17
+.. gh-issue: 149056
+.. nonce: jnaD4W
+.. section: Library
+
+Fix :func:`json.load` not forwarding the *array_hook* argument to
+:func:`json.loads`. Patch by Thomas Kowalski.
+
+..
+
+.. date: 2026-04-27-11-12-00
+.. gh-issue: 149046
+.. nonce: 74shDd
+.. section: Library
+
+:mod:`io`: Fix :class:`io.StringIO` serialization: no longer call
+``str(obj)`` on :class:`str` subclasses. Patch by Thomas Kowalski.
+
+..
+
+.. date: 2026-04-23-12-50-15
+.. gh-issue: 148441
+.. nonce: zvpCkR
+.. section: Library
+
+:mod:`xml.parsers.expat`: prevent a crash in
+:meth:`~xml.parsers.expat.xmlparser.CharacterDataHandler` when the character
+data size exceeds the parser's :attr:`buffer size
+`.
+
+..
+
+.. date: 2026-03-26-09-30-00
+.. gh-issue: 146452
+.. nonce: Y2N6qZ8J
+.. section: Library
+
+Fix segfault in :mod:`pickle` when pickling a dictionary concurrently
+mutated by another thread in the free-threaded build.
+
+..
+
+.. date: 2025-08-30-07-44-30
+.. gh-issue: 86533
+.. nonce: pathlib
+.. section: Library
+
+The :func:`os.makedirs` function and :meth:`pathlib.Path.mkdir` method now
+have a *parent_mode* parameter to specify the mode for intermediate
+directories when creating parent directories. This allows one to match the
+behavior from Python 3.6 and earlier for :func:`os.makedirs`.
+
+..
+
+.. date: 2025-05-19-21-08-25
+.. gh-issue: 134261
+.. nonce: ravGYm
+.. section: Library
+
+zip: On reproducible builds, ZipFile uses UTC instead of the local time when
+writing file datetimes to avoid underflows.
+
+..
+
+.. date: 2025-05-19-20-29-35
+.. gh-issue: 133998
+.. nonce: KmElUw
+.. section: Library
+
+Fix :exc:`struct.error` exception when creating a file with
+:class:`gzip.GzipFile` or compressing data with :func:`gzip.compress` if the
+system time is outside the range 00:00:00 UTC, January 1, 1970 through
+06:28:15 UTC, February 7, 2106, or explicitly passed *mtime* argument is
+outside the range ``0`` to ``2**32-1``.
+
+..
+
+.. date: 2025-03-01-13-36-02
+.. gh-issue: 128110
+.. nonce: 9wx_G0
+.. section: Library
+
+Fix bug in the parsing of :mod:`email` address headers that could result in
+extraneous spaces in the decoded text when using a modern email policy.
+Space between pairs of adjacent :rfc:`2047` encoded-words is now ignored,
+per section 6.2 (and consistent with existing parsing of unstructured
+headers like *Subject*).
+
+..
+
+.. date: 2024-11-02-02-02-31
+.. gh-issue: 107398
+.. nonce: uUtA6Q
+.. section: Library
+
+Fix :mod:`tarfile` stream mode exception when process the file with the gzip
+extra field.
+
+..
+
+.. date: 2024-07-02-20-57-43
+.. gh-issue: 121109
+.. nonce: Tp6R2s
+.. section: Library
+
+Fix :mod:`tarfile` performance issue when reading archives in streaming mode
+(e.g. ``r|*``).
+
+..
+
+.. bpo: 45509
+.. date: 2021-10-18-13-46-55
+.. nonce: Upwb60
+.. section: Library
+
+Gzip headers are now checked for corrupted NAME, COMMENT and HCRC fields.
+
+..
+
+.. date: 2026-05-25-15-39-53
+.. gh-issue: 150387
+.. nonce: yzZ7jq
+.. section: Tests
+
+Fix hang in
+``test.test_profiling.test_sampling_profiler.test_live_collector_ui.TestLiveModeErrors.test_run_failed_script_live``
+on slow buildbots. The test now always queues a final ``q`` keystroke so the
+live TUI loop exits even when the profiler collects enough samples to enter
+the post-finished input loop.
+
+..
+
+.. date: 2026-05-13-14-53-23
+.. gh-issue: 149776
+.. nonce: orqgsn
+.. section: Tests
+
+Fix test_socket on Linux kernel 7.1 and newer: skip UDP Lite tests if it's
+not supported. Patch by Victor Stinner.
+
+..
+
+.. date: 2026-05-21-15-14-59
+.. gh-issue: 148294
+.. nonce: VtFaW4
+.. section: Build
+
+Corrected the use of ``AC_PATH_TOOL`` in ``configure.ac`` to allow a C++
+compiler to be found on :envvar:`!PATH`.
+
+..
+
+.. date: 2026-05-18-16-00-41
+.. gh-issue: 148260
+.. nonce: UwFiIX
+.. section: Build
+
+On Linux when Python is linked to the musl C library, use a thread stack
+size of at least 1 MiB instead of musl default which is 128 kiB. Patch by
+Victor Stinner.
+
+..
+
+.. date: 2026-05-14-22-09-46
+.. gh-issue: 149786
+.. nonce: UI-HZM
+.. section: Windows
+
+Fixes virtual environment launchers on Windows free-threaded builds.
+
+..
+
+.. date: 2026-05-06-21-36-53
+.. gh-issue: 124111
+.. nonce: m4OBX8
+.. section: Windows
+
+Updated Windows builds to use Tcl/Tk 9.0.3.
+
+..
+
+.. date: 2026-04-29-14-44-51
+.. gh-issue: 138489
+.. nonce: 234aj6
+.. section: Windows
+
+Windows distributions now include a :file:`build-details.json` file (see
+:pep:`739`). The legacy installer does not install it, but all other
+distributions from python.org and all preset configurations in the
+``PC\layout`` script will include one.
+
+..
+
+.. date: 2026-04-26-23-14-45
+.. gh-issue: 149029
+.. nonce: oPTXP4
+.. section: Windows
+
+Update Windows installer to ship with SQLite 3.53.1.
+
+..
+
+.. date: 2026-05-31-10-40-00
+.. gh-issue: 150644
+.. nonce: zLWyjj
+.. section: macOS
+
+When system logging is enabled (with ``config.use_system_logger``, messages
+are now tagged as public. This allows the macOS 26 system logger to view
+messages without special configuration.
+
+..
+
+.. date: 2026-04-26-23-15-09
+.. gh-issue: 149029
+.. nonce: Lsx--T
+.. section: macOS
+
+Update macOS installer to ship with SQLite version 3.53.1.
+
+..
+
+.. date: 2026-05-22-18-51-09
+.. gh-issue: 150258
+.. nonce: dh8GVK
+.. section: Tools/Demos
+
+Update the tooltip on the Tachyon flame graph to show both absolute and
+relative percentages.
+
+..
+
+.. date: 2026-05-12-16-47-21
+.. gh-issue: 149725
+.. nonce: HZLBTZ
+.. section: C API
+
+Add :c:func:`PySentinel_CheckExact` for exact :class:`sentinel` type tests
+to accompany the existing :c:func:`PySentinel_Check`.
+
+..
+
+.. date: 2026-02-25-13-37-10
+.. gh-issue: 145235
+.. nonce: -1ySNR
+.. section: C API
+
+Made :c:func:`PyDict_AddWatcher`, :c:func:`PyDict_ClearWatcher`,
+:c:func:`PyDict_Watch`, and :c:func:`PyDict_Unwatch` thread-safe on the
+:term:`free threaded ` build.
diff --git a/Misc/NEWS.d/next/Build/2026-05-18-16-00-41.gh-issue-148260.UwFiIX.rst b/Misc/NEWS.d/next/Build/2026-05-18-16-00-41.gh-issue-148260.UwFiIX.rst
deleted file mode 100644
index 8248c24cbd511a..00000000000000
--- a/Misc/NEWS.d/next/Build/2026-05-18-16-00-41.gh-issue-148260.UwFiIX.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-On Linux when Python is linked to the musl C library, use a thread stack
-size of at least 1 MiB instead of musl default which is 128 kiB. Patch by
-Victor Stinner.
diff --git a/Misc/NEWS.d/next/Build/2026-05-21-15-14-59.gh-issue-148294.VtFaW4.rst b/Misc/NEWS.d/next/Build/2026-05-21-15-14-59.gh-issue-148294.VtFaW4.rst
deleted file mode 100644
index 861261dd97269f..00000000000000
--- a/Misc/NEWS.d/next/Build/2026-05-21-15-14-59.gh-issue-148294.VtFaW4.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Corrected the use of ``AC_PATH_TOOL`` in ``configure.ac`` to allow a C++
-compiler to be found on :envvar:`!PATH`.
diff --git a/Misc/NEWS.d/next/C_API/2026-02-25-13-37-10.gh-issue-145235.-1ySNR.rst b/Misc/NEWS.d/next/C_API/2026-02-25-13-37-10.gh-issue-145235.-1ySNR.rst
deleted file mode 100644
index 98a8c268735726..00000000000000
--- a/Misc/NEWS.d/next/C_API/2026-02-25-13-37-10.gh-issue-145235.-1ySNR.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Made :c:func:`PyDict_AddWatcher`, :c:func:`PyDict_ClearWatcher`,
-:c:func:`PyDict_Watch`, and :c:func:`PyDict_Unwatch` thread-safe on the
-:term:`free threaded ` build.
diff --git a/Misc/NEWS.d/next/C_API/2026-05-12-16-47-21.gh-issue-149725.HZLBTZ.rst b/Misc/NEWS.d/next/C_API/2026-05-12-16-47-21.gh-issue-149725.HZLBTZ.rst
deleted file mode 100644
index 97721430edbd69..00000000000000
--- a/Misc/NEWS.d/next/C_API/2026-05-12-16-47-21.gh-issue-149725.HZLBTZ.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Add :c:func:`PySentinel_CheckExact` for exact :class:`sentinel` type tests
-to accompany the existing :c:func:`PySentinel_Check`.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-04-15-15-48-04.gh-issue-148450.2MEVqH.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-15-15-48-04.gh-issue-148450.2MEVqH.rst
deleted file mode 100644
index 2a7d0d9bb3a7f7..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-04-15-15-48-04.gh-issue-148450.2MEVqH.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix ``abc.register()`` so it invalidates type version tags for registered classes.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-07-03-18-59.gh-issue-149459.5fhAqP.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-07-03-18-59.gh-issue-149459.5fhAqP.rst
deleted file mode 100644
index 4cd0a148df3c70..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-07-03-18-59.gh-issue-149459.5fhAqP.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix a crash in the JIT optimizer when a specialized ``LOAD_SPECIAL`` guard deoptimized after inserting the synthetic ``NULL`` stack entry.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-09-15-22-32.gh-issue-144957.u1F2aQ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-09-15-22-32.gh-issue-144957.u1F2aQ.rst
deleted file mode 100644
index 3063f1a3c0e6d3..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-09-15-22-32.gh-issue-144957.u1F2aQ.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix lazy ``from`` imports of module attributes provided by module-level
-``__getattr__``.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-10-07-42-36.gh-issue-149642.6ZksML.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-10-07-42-36.gh-issue-149642.6ZksML.rst
deleted file mode 100644
index 815a084db69d8d..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-10-07-42-36.gh-issue-149642.6ZksML.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Allow imports inside ``exec()`` calls within functions under
-``PYTHON_LAZY_IMPORTS=all``.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-10-16-43-50.gh-issue-148829.gscS14.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-10-16-43-50.gh-issue-148829.gscS14.rst
deleted file mode 100644
index 3f9b1ccb518787..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-10-16-43-50.gh-issue-148829.gscS14.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-:class:`sentinel` objects now support a ``repr=`` argument and their
-:attr:`~sentinel.__module__` attribute is writable.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-11-14-48-56.gh-issue-149676.6aTrw1.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-11-14-48-56.gh-issue-149676.6aTrw1.rst
deleted file mode 100644
index 96f407cf5ad25a..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-11-14-48-56.gh-issue-149676.6aTrw1.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix ``frozendict | frozendict`` hash.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-12-16-47-23.gh-issue-139808.iIs7_E.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-12-16-47-23.gh-issue-139808.iIs7_E.rst
deleted file mode 100644
index 3e9d930bf1de89..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-12-16-47-23.gh-issue-139808.iIs7_E.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Add branch protections for AArch64 (BTI/PAC) in assembly code used by
-:option:`-X perf_jit <-X>` (Linux perf profiler integration).
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-13-06-54-41.gh-issue-149738.4BLFoH.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-13-06-54-41.gh-issue-149738.4BLFoH.rst
deleted file mode 100644
index e62b681d716650..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-13-06-54-41.gh-issue-149738.4BLFoH.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-:mod:`sqlite3`: Disallow removing ``row_factory`` and ``text_factory`` attributes
-of a connection to prevent a crash on a query.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-14-19-41-03.gh-issue-149807.IwGaCo.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-14-19-41-03.gh-issue-149807.IwGaCo.rst
deleted file mode 100644
index a94c737e73619d..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-14-19-41-03.gh-issue-149807.IwGaCo.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix ``hash(frozendict)``: compute the hash of each ``(key, value)`` pair
-correctly. Patch by Victor Stinner.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-15-11-31-57.gh-issue-149816.ugN2rx.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-15-11-31-57.gh-issue-149816.ugN2rx.rst
deleted file mode 100644
index 016c17dd66b19e..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-15-11-31-57.gh-issue-149816.ugN2rx.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix a race condition in :class:`memoryview` with free-threading.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-16-11-03-54.gh-issue-149816.X_gqMT.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-16-11-03-54.gh-issue-149816.X_gqMT.rst
deleted file mode 100644
index d35f0857a1aefe..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-16-11-03-54.gh-issue-149816.X_gqMT.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix a race condition in ``_PyBytes_FromList`` in free-threading mode.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-18-13-47-17.gh-issue-149590.IPBeQx.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-18-13-47-17.gh-issue-149590.IPBeQx.rst
deleted file mode 100644
index 8d3b29d69cc857..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-18-13-47-17.gh-issue-149590.IPBeQx.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix crash when faulthandler is imported more than once.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-18-16-54-54.gh-issue-150042.LSr5W8.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-18-16-54-54.gh-issue-150042.LSr5W8.rst
deleted file mode 100644
index 18a4fbd9dadd60..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-18-16-54-54.gh-issue-150042.LSr5W8.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix refleak in queue.SimpleQueue.put if memory allocation fails.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-18-18-36-28.gh-issue-148587.-RD3z5.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-18-18-36-28.gh-issue-148587.-RD3z5.rst
deleted file mode 100644
index 61bfdcdd37362c..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-18-18-36-28.gh-issue-148587.-RD3z5.rst
+++ /dev/null
@@ -1 +0,0 @@
-``sys.lazy_modules`` is now a set instead of a dict as initially spelled out in PEP 810.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-20-13-06-17.gh-issue-150146.i5m_SL.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-20-13-06-17.gh-issue-150146.i5m_SL.rst
deleted file mode 100644
index f373f0bee7023e..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-20-13-06-17.gh-issue-150146.i5m_SL.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Fix a crash on a complex type variable substitution.
-
-``from typing import TypeVar; memoryview[TypeVar("")][*typing.Mapping[...,
-...]]`` used to fail due to missing ``NULL`` check on ``_unpack_args`` C
-function call.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-22-17-09-28.gh-issue-150107.GD72-D.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-22-17-09-28.gh-issue-150107.GD72-D.rst
deleted file mode 100644
index a13f249e48cc02..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-22-17-09-28.gh-issue-150107.GD72-D.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-:mod:`asyncio`: ``sendfile()`` and ``sock_sendfile()`` event loop methods
-now call ``file.seek(offset)`` if *file* has a ``seek()`` method,
-even if *offset* is ``0`` (default value).
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-23-22-08-01.gh-issue-149449.2lhQFF.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-23-22-08-01.gh-issue-149449.2lhQFF.rst
deleted file mode 100644
index 7d11442468d207..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-23-22-08-01.gh-issue-149449.2lhQFF.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Fix a use-after-free crash when the :mod:`unicodedata` module was removed
-from :data:`sys.modules` and garbage-collected between calls that decode
-``\N{...}`` escapes or use the ``namereplace`` codec error handler.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-24-14-45-00.gh-issue-149156.NP73rB.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-24-14-45-00.gh-issue-149156.NP73rB.rst
deleted file mode 100644
index 2cb091e2b162f6..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-24-14-45-00.gh-issue-149156.NP73rB.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Fix an intermittent crash after :func:`os.fork` when perf trampoline
-profiling is enabled and the child returns through trampoline frames
-inherited from the parent process.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-25-16-00-22.gh-issue-150374.Emu6d8.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-25-16-00-22.gh-issue-150374.Emu6d8.rst
deleted file mode 100644
index 7189ca186d2b7e..00000000000000
--- a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-25-16-00-22.gh-issue-150374.Emu6d8.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix double release of the import lock on lazy import reification errors.
diff --git a/Misc/NEWS.d/next/Library/2021-10-18-13-46-55.bpo-45509.Upwb60.rst b/Misc/NEWS.d/next/Library/2021-10-18-13-46-55.bpo-45509.Upwb60.rst
deleted file mode 100644
index 80c38c03f8fe78..00000000000000
--- a/Misc/NEWS.d/next/Library/2021-10-18-13-46-55.bpo-45509.Upwb60.rst
+++ /dev/null
@@ -1 +0,0 @@
-Gzip headers are now checked for corrupted NAME, COMMENT and HCRC fields.
diff --git a/Misc/NEWS.d/next/Library/2024-07-02-20-57-43.gh-issue-121109.Tp6R2s.rst b/Misc/NEWS.d/next/Library/2024-07-02-20-57-43.gh-issue-121109.Tp6R2s.rst
deleted file mode 100644
index eca6014e4a0aed..00000000000000
--- a/Misc/NEWS.d/next/Library/2024-07-02-20-57-43.gh-issue-121109.Tp6R2s.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix :mod:`tarfile` performance issue when reading archives in streaming mode
-(e.g. ``r|*``).
diff --git a/Misc/NEWS.d/next/Library/2024-11-02-02-02-31.gh-issue-107398.uUtA6Q.rst b/Misc/NEWS.d/next/Library/2024-11-02-02-02-31.gh-issue-107398.uUtA6Q.rst
deleted file mode 100644
index d5af322d68d309..00000000000000
--- a/Misc/NEWS.d/next/Library/2024-11-02-02-02-31.gh-issue-107398.uUtA6Q.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix :mod:`tarfile` stream mode exception when process the file with the gzip extra field.
diff --git a/Misc/NEWS.d/next/Library/2025-03-01-13-36-02.gh-issue-128110.9wx_G0.rst b/Misc/NEWS.d/next/Library/2025-03-01-13-36-02.gh-issue-128110.9wx_G0.rst
deleted file mode 100644
index b08b1886cff9cf..00000000000000
--- a/Misc/NEWS.d/next/Library/2025-03-01-13-36-02.gh-issue-128110.9wx_G0.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Fix bug in the parsing of :mod:`email` address headers that could result in
-extraneous spaces in the decoded text when using a modern email policy.
-Space between pairs of adjacent :rfc:`2047` encoded-words is now ignored, per
-section 6.2 (and consistent with existing parsing of unstructured
-headers like *Subject*).
diff --git a/Misc/NEWS.d/next/Library/2025-05-19-20-29-35.gh-issue-133998.KmElUw.rst b/Misc/NEWS.d/next/Library/2025-05-19-20-29-35.gh-issue-133998.KmElUw.rst
deleted file mode 100644
index 77d92628beefac..00000000000000
--- a/Misc/NEWS.d/next/Library/2025-05-19-20-29-35.gh-issue-133998.KmElUw.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Fix :exc:`struct.error` exception when creating a file with
-:class:`gzip.GzipFile` or compressing data with :func:`gzip.compress`
-if the system time is outside the range 00:00:00 UTC, January 1, 1970
-through 06:28:15 UTC, February 7, 2106, or explicitly passed *mtime*
-argument is outside the range ``0`` to ``2**32-1``.
diff --git a/Misc/NEWS.d/next/Library/2025-05-19-21-08-25.gh-issue-134261.ravGYm.rst b/Misc/NEWS.d/next/Library/2025-05-19-21-08-25.gh-issue-134261.ravGYm.rst
deleted file mode 100644
index bf552fee814acb..00000000000000
--- a/Misc/NEWS.d/next/Library/2025-05-19-21-08-25.gh-issue-134261.ravGYm.rst
+++ /dev/null
@@ -1 +0,0 @@
-zip: On reproducible builds, ZipFile uses UTC instead of the local time when writing file datetimes to avoid underflows.
diff --git a/Misc/NEWS.d/next/Library/2025-08-30-07-44-30.gh-issue-86533.pathlib.rst b/Misc/NEWS.d/next/Library/2025-08-30-07-44-30.gh-issue-86533.pathlib.rst
deleted file mode 100644
index 9c32671173e0ad..00000000000000
--- a/Misc/NEWS.d/next/Library/2025-08-30-07-44-30.gh-issue-86533.pathlib.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-The :func:`os.makedirs` function and :meth:`pathlib.Path.mkdir` method now have
-a *parent_mode* parameter to specify the mode for intermediate directories when
-creating parent directories. This allows one to match the behavior from Python
-3.6 and earlier for :func:`os.makedirs`.
diff --git a/Misc/NEWS.d/next/Library/2026-03-26-09-30-00.gh-issue-146452.Y2N6qZ8J.rst b/Misc/NEWS.d/next/Library/2026-03-26-09-30-00.gh-issue-146452.Y2N6qZ8J.rst
deleted file mode 100644
index 99f3cce33497a1..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-03-26-09-30-00.gh-issue-146452.Y2N6qZ8J.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix segfault in :mod:`pickle` when pickling a dictionary concurrently
-mutated by another thread in the free-threaded build.
diff --git a/Misc/NEWS.d/next/Library/2026-04-23-12-50-15.gh-issue-148441.zvpCkR.rst b/Misc/NEWS.d/next/Library/2026-04-23-12-50-15.gh-issue-148441.zvpCkR.rst
deleted file mode 100644
index 762815270e4d40..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-04-23-12-50-15.gh-issue-148441.zvpCkR.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-:mod:`xml.parsers.expat`: prevent a crash in
-:meth:`~xml.parsers.expat.xmlparser.CharacterDataHandler`
-when the character data size exceeds the parser's
-:attr:`buffer size `.
diff --git a/Misc/NEWS.d/next/Library/2026-04-27-11-12-00.gh-issue-149046.74shDd.rst b/Misc/NEWS.d/next/Library/2026-04-27-11-12-00.gh-issue-149046.74shDd.rst
deleted file mode 100644
index b05c4222e30fcd..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-04-27-11-12-00.gh-issue-149046.74shDd.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-:mod:`io`: Fix :class:`io.StringIO` serialization: no longer call ``str(obj)`` on :class:`str`
-subclasses. Patch by Thomas Kowalski.
diff --git a/Misc/NEWS.d/next/Library/2026-04-29-08-10-17.gh-issue-149056.jnaD4W.rst b/Misc/NEWS.d/next/Library/2026-04-29-08-10-17.gh-issue-149056.jnaD4W.rst
deleted file mode 100644
index 0026d02c876257..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-04-29-08-10-17.gh-issue-149056.jnaD4W.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix :func:`json.load` not forwarding the *array_hook* argument to
-:func:`json.loads`. Patch by Thomas Kowalski.
diff --git a/Misc/NEWS.d/next/Library/2026-05-07-14-18-47.gh-issue-149489.bX9iHe.rst b/Misc/NEWS.d/next/Library/2026-05-07-14-18-47.gh-issue-149489.bX9iHe.rst
deleted file mode 100644
index 1550c893fd7c45..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-07-14-18-47.gh-issue-149489.bX9iHe.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Fix :mod:`~xml.etree.ElementTree` serialization to HTML. The content of
-comments, processing instructions and elements "xmp", "iframe", "noembed",
-"noframes", and "plaintext" is no longer escaped. The "plaintext" element no
-longer have the closing tag. Add support of empty attributes (with value
-``None``).
diff --git a/Misc/NEWS.d/next/Library/2026-05-07-21-58-17.gh-issue-149388.DDBPeA.rst b/Misc/NEWS.d/next/Library/2026-05-07-21-58-17.gh-issue-149388.DDBPeA.rst
deleted file mode 100644
index 4a1c6f3f5b4e57..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-07-21-58-17.gh-issue-149388.DDBPeA.rst
+++ /dev/null
@@ -1 +0,0 @@
-Make :class:`!asyncio.windows_utils.PipeHandle` closing idempotent.
diff --git a/Misc/NEWS.d/next/Library/2026-05-08-09-11-48.gh-issue-149534.Tw7eeY.rst b/Misc/NEWS.d/next/Library/2026-05-08-09-11-48.gh-issue-149534.Tw7eeY.rst
deleted file mode 100644
index 0938935a75d8c1..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-08-09-11-48.gh-issue-149534.Tw7eeY.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix merging of :class:`collections.defaultdict` and :class:`frozendict`.
diff --git a/Misc/NEWS.d/next/Library/2026-05-08-15-08-35.gh-issue-112821.t9T1YD.rst b/Misc/NEWS.d/next/Library/2026-05-08-15-08-35.gh-issue-112821.t9T1YD.rst
deleted file mode 100644
index cfbcde81493e22..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-08-15-08-35.gh-issue-112821.t9T1YD.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-In the REPL, autocompletion might run arbitrary code in the getter of a
-descriptor. If that getter raised an exception, autocompletion would fail to
-present any options for the entire object. Autocompletion now works as
-expected for these objects.
diff --git a/Misc/NEWS.d/next/Library/2026-05-09-21-02-08.gh-issue-149614.U4snj3.rst b/Misc/NEWS.d/next/Library/2026-05-09-21-02-08.gh-issue-149614.U4snj3.rst
deleted file mode 100644
index 5169c6c203fc1b..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-09-21-02-08.gh-issue-149614.U4snj3.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix a regression that broke the ability to deepcopy :class:`argparse.ArgumentParser` instances.
diff --git a/Misc/NEWS.d/next/Library/2026-05-10-07-21-51.gh-issue-139489.rS7LTA.rst b/Misc/NEWS.d/next/Library/2026-05-10-07-21-51.gh-issue-139489.rS7LTA.rst
deleted file mode 100644
index 40fe7e9fd6a008..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-10-07-21-51.gh-issue-139489.rS7LTA.rst
+++ /dev/null
@@ -1 +0,0 @@
-Add :func:`xml.is_valid_text` to ``xml.__all__``.
diff --git a/Misc/NEWS.d/next/Library/2026-05-10-19-26-50.gh-issue-149584.x7Qm9A.rst b/Misc/NEWS.d/next/Library/2026-05-10-19-26-50.gh-issue-149584.x7Qm9A.rst
deleted file mode 100644
index 6734250fdd6af3..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-10-19-26-50.gh-issue-149584.x7Qm9A.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-Fix excessive overhead in the Tachyon profiler when inspecting a remote
-process by avoiding repeated remote page-cache scans, batching predicted
-remote reads, and reusing cached profiler result objects. Patch by Pablo
-Galindo and Maurycy Pawłowski-Wieroński.
diff --git a/Misc/NEWS.d/next/Library/2026-05-10-23-51-23.gh-issue-149504.pDSCbn.rst b/Misc/NEWS.d/next/Library/2026-05-10-23-51-23.gh-issue-149504.pDSCbn.rst
deleted file mode 100644
index 88bf268123bbec..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-10-23-51-23.gh-issue-149504.pDSCbn.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Fix :func:`site.addsitedir` to allow re-entrant calls from within startup
-files. Previously, a ``.pth`` file containing an ``import`` line that
-called :func:`site.addsitedir` (or a ``.start`` entry point doing the same)
-could crash with ``RuntimeError: dictionary changed size during iteration``
-during site initialization, breaking tools such as ``uv run --with``.
diff --git a/Misc/NEWS.d/next/Library/2026-05-12-06-24-54.gh-issue-149701.8v9RTm.rst b/Misc/NEWS.d/next/Library/2026-05-12-06-24-54.gh-issue-149701.8v9RTm.rst
deleted file mode 100644
index 676d788cbce62a..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-12-06-24-54.gh-issue-149701.8v9RTm.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fix bad return code from Lib/venv/bin/activate if hashing is disabled
diff --git a/Misc/NEWS.d/next/Library/2026-05-12-13-03-45.gh-issue-149718.SaM1NJ.rst b/Misc/NEWS.d/next/Library/2026-05-12-13-03-45.gh-issue-149718.SaM1NJ.rst
deleted file mode 100644
index 25344e5a90f022..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-12-13-03-45.gh-issue-149718.SaM1NJ.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-Coalesce consecutive identical stack frames in Tachyon, so aggregating
-collectors (pstats, collapsed, flamegraph, gecko) receive one collect.
-Improves sample rate 3x, error rate and missed rate drop by 70%. Patch by
-Maurycy Pawłowski-Wieroński.
diff --git a/Misc/NEWS.d/next/Library/2026-05-13-23-18-39.gh-issue-149801.S_FfGr.rst b/Misc/NEWS.d/next/Library/2026-05-13-23-18-39.gh-issue-149801.S_FfGr.rst
deleted file mode 100644
index f9e8538527d204..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-13-23-18-39.gh-issue-149801.S_FfGr.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Add IANA registered names and aliases with leading zeros before number (like
-IBM00858, CP00858, IBM01140, CP01140) for corresponding codecs.
diff --git a/Misc/NEWS.d/next/Library/2026-05-14-15-55-28.gh-issue-149816.ZaXQ0q.rst b/Misc/NEWS.d/next/Library/2026-05-14-15-55-28.gh-issue-149816.ZaXQ0q.rst
deleted file mode 100644
index 3ea70071ec3c75..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-14-15-55-28.gh-issue-149816.ZaXQ0q.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix a race condition in ``_random.Random.__init__`` method in free-threading
-mode.
diff --git a/Misc/NEWS.d/next/Library/2026-05-15-16-28-00.gh-issue-149819.fixpth.rst b/Misc/NEWS.d/next/Library/2026-05-15-16-28-00.gh-issue-149819.fixpth.rst
deleted file mode 100644
index 66e6da0ecf0d87..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-15-16-28-00.gh-issue-149819.fixpth.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-Fix regression in :func:`site.addsitedir` where ``.pth`` files were no
-longer processed in Python subprocesses. This happened because
-:func:`site.main` seeded ``known_paths`` with entries inherited from
-the parent process, causing ``addsitedir`` to skip ``.pth`` processing.
diff --git a/Misc/NEWS.d/next/Library/2026-05-15-18-44-20.gh-issue-142349.fHK3v1.rst b/Misc/NEWS.d/next/Library/2026-05-15-18-44-20.gh-issue-142349.fHK3v1.rst
deleted file mode 100644
index fa667c4110941e..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-15-18-44-20.gh-issue-142349.fHK3v1.rst
+++ /dev/null
@@ -1 +0,0 @@
-Add :keyword:`lazy` to the list of support topic by :func:`help`.
diff --git a/Misc/NEWS.d/next/Library/2026-05-16-21-08-33.gh-issue-149921.I1yNML.rst b/Misc/NEWS.d/next/Library/2026-05-16-21-08-33.gh-issue-149921.I1yNML.rst
deleted file mode 100644
index 113bd1a802f799..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-16-21-08-33.gh-issue-149921.I1yNML.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix reference leaks in error paths of the :mod:`!_interpchannels` and
-:mod:`!_interpqueues` extension modules.
diff --git a/Misc/NEWS.d/next/Library/2026-05-17-02-25-56.gh-issue-149571.LNyuWJ.rst b/Misc/NEWS.d/next/Library/2026-05-17-02-25-56.gh-issue-149571.LNyuWJ.rst
deleted file mode 100644
index 2b71d9cf2200be..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-17-02-25-56.gh-issue-149571.LNyuWJ.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix the C implementation of :meth:`xml.etree.ElementTree.Element.itertext`:
-it no longer emits text for comments and processing instructions.
diff --git a/Misc/NEWS.d/next/Library/2026-05-17-22-37-02.gh-issue-88726.BAoL6j.rst b/Misc/NEWS.d/next/Library/2026-05-17-22-37-02.gh-issue-88726.BAoL6j.rst
deleted file mode 100644
index ba9058d79c9873..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-17-22-37-02.gh-issue-88726.BAoL6j.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-The :mod:`email` package now uses standard MIME charset names "gb2312" and
-"big5" instead of non-standard names "eucgb2312_cn" and "big5_tw".
diff --git a/Misc/NEWS.d/next/Library/2026-05-18-07-44-46.gh-issue-149995.vvtFHn.rst b/Misc/NEWS.d/next/Library/2026-05-18-07-44-46.gh-issue-149995.vvtFHn.rst
deleted file mode 100644
index a8e412b578da37..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-18-07-44-46.gh-issue-149995.vvtFHn.rst
+++ /dev/null
@@ -1 +0,0 @@
-Update various docstrings in :mod:`typing`.
diff --git a/Misc/NEWS.d/next/Library/2026-05-18-17-17-20.gh-issue-149189.a8IooK.rst b/Misc/NEWS.d/next/Library/2026-05-18-17-17-20.gh-issue-149189.a8IooK.rst
deleted file mode 100644
index bad027f2c71c6f..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-18-17-17-20.gh-issue-149189.a8IooK.rst
+++ /dev/null
@@ -1 +0,0 @@
-Revert the changes to :mod:`pprint` defaults. Patch by Hugo van Kemenade.
diff --git a/Misc/NEWS.d/next/Library/2026-05-19-19-00-49.gh-issue-84353.ZU5zaQ.rst b/Misc/NEWS.d/next/Library/2026-05-19-19-00-49.gh-issue-84353.ZU5zaQ.rst
deleted file mode 100644
index 84fb12e2abd81a..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-19-19-00-49.gh-issue-84353.ZU5zaQ.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Preserve non-UTF-8 encoded filenames when appending to a
-:class:`zipfile.ZipFile`. Previously, non-ASCII names stored in a legacy
-encoding (without the UTF-8 flag bit set) could be corrupted when the
-central directory was rewritten: they were decoded as cp437 and then
-re-stored as UTF-8.
diff --git a/Misc/NEWS.d/next/Library/2026-05-21-11-25-58.gh-issue-150175.8H4Caz.rst b/Misc/NEWS.d/next/Library/2026-05-21-11-25-58.gh-issue-150175.8H4Caz.rst
deleted file mode 100644
index 80fc80d4d50a63..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-21-11-25-58.gh-issue-150175.8H4Caz.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Fix race condition in :class:`unittest.mock.ThreadingMock` where
-concurrent calls could lose increments to ``call_count`` and other
-attributes due to a missing lock in ``_increment_mock_call``.
diff --git a/Misc/NEWS.d/next/Library/2026-05-21-20-47-45.gh-issue-150157.ZvmO-bQZ.rst b/Misc/NEWS.d/next/Library/2026-05-21-20-47-45.gh-issue-150157.ZvmO-bQZ.rst
deleted file mode 100644
index 3a12e26cf736f7..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-21-20-47-45.gh-issue-150157.ZvmO-bQZ.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Fix a crash in free-threaded builds that occurs when pickling by name
-objects without a ``__module__`` attribute while :data:`sys.modules`
-is concurrently being modified.
diff --git a/Misc/NEWS.d/next/Library/2026-05-25-07-22-05.gh-issue-150372.9hLqhe.rst b/Misc/NEWS.d/next/Library/2026-05-25-07-22-05.gh-issue-150372.9hLqhe.rst
deleted file mode 100644
index 7b83bd8fe73f11..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-25-07-22-05.gh-issue-150372.9hLqhe.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-:mod:`readline`: Fix a potential crash during tab completion caused by an
-out-of-memory error during module initialization.
diff --git a/Misc/NEWS.d/next/Library/2026-05-25-17-00-00.gh-issue-150406.jF3g63.rst b/Misc/NEWS.d/next/Library/2026-05-25-17-00-00.gh-issue-150406.jF3g63.rst
deleted file mode 100644
index 230e961abd3f58..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-25-17-00-00.gh-issue-150406.jF3g63.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Fix a possible crash occurring during :mod:`socket` module initialization
-when the system is out of memory on platforms without a reentrant
-``gethostbyname``.
diff --git a/Misc/NEWS.d/next/Library/2026-05-27-11-18-36.gh-issue-150228.pNPiO-.rst b/Misc/NEWS.d/next/Library/2026-05-27-11-18-36.gh-issue-150228.pNPiO-.rst
deleted file mode 100644
index 8c03989e90b240..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-27-11-18-36.gh-issue-150228.pNPiO-.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-The new :class:`site.StartupState` class lets callers batch-process
-:pep:`829` startup configuration files across multiple site directories
-before any startup code runs, with public
-:meth:`~site.StartupState.addsitedir`,
-:meth:`~site.StartupState.addusersitepackages`,
-:meth:`~site.StartupState.addsitepackages`, and
-:meth:`~site.StartupState.process` methods. The signature of
-:func:`site.addsitedir` is unchanged from Python 3.14. The
-:data:`!defer_processing_start_files` argument and the
-``process_startup_files()`` function added earlier in the 3.15 cycle have
-been removed; use :class:`!site.StartupState` instead.
diff --git a/Misc/NEWS.d/next/Library/2026-05-31-17-47-30.gh-issue-150685.EBB2mU.rst b/Misc/NEWS.d/next/Library/2026-05-31-17-47-30.gh-issue-150685.EBB2mU.rst
deleted file mode 100644
index eb7f31112d004c..00000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-31-17-47-30.gh-issue-150685.EBB2mU.rst
+++ /dev/null
@@ -1 +0,0 @@
-Update bundled pip to 26.1.2
diff --git a/Misc/NEWS.d/next/Security/2026-04-26-19-30-45.gh-issue-149018.a9SqWb.rst b/Misc/NEWS.d/next/Security/2026-04-26-19-30-45.gh-issue-149018.a9SqWb.rst
deleted file mode 100644
index d1b5b368684e6a..00000000000000
--- a/Misc/NEWS.d/next/Security/2026-04-26-19-30-45.gh-issue-149018.a9SqWb.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Improved protection against XML hash-flooding attacks in
-:mod:`xml.parsers.expat` and :mod:`xml.etree.ElementTree` when Python is
-compiled with libExpat 2.8.0 or later.
diff --git a/Misc/NEWS.d/next/Security/2026-04-27-16-36-11.gh-issue-149079.vKl-LM.rst b/Misc/NEWS.d/next/Security/2026-04-27-16-36-11.gh-issue-149079.vKl-LM.rst
deleted file mode 100644
index 4ed22b58f7405f..00000000000000
--- a/Misc/NEWS.d/next/Security/2026-04-27-16-36-11.gh-issue-149079.vKl-LM.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Fix a potential denial of service in :func:`unicodedata.normalize`. The
-canonical ordering step of Unicode normalization used a quadratic-time insertion
-sort for reordering combining characters, which could be exploited with
-crafted input containing many combining characters in non-canonical order.
-Replaced with a linear-time counting sort for long runs.
diff --git a/Misc/NEWS.d/next/Security/2026-05-03-21-00-00.gh-issue-149486.tarflt.rst b/Misc/NEWS.d/next/Security/2026-05-03-21-00-00.gh-issue-149486.tarflt.rst
deleted file mode 100644
index 7c69edb683cf80..00000000000000
--- a/Misc/NEWS.d/next/Security/2026-05-03-21-00-00.gh-issue-149486.tarflt.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-:func:`tarfile.data_filter` now validates link targets using the same
-normalised value that is written to disk, strips trailing separators from
-the member name when resolving a symlink's directory, and rejects link
-members that would replace the destination directory itself. This closes
-several path-traversal bypasses of the ``data`` extraction filter.
diff --git a/Misc/NEWS.d/next/Security/2026-05-08-02-18-54.gh-issue-149474.ujQ-mu.rst b/Misc/NEWS.d/next/Security/2026-05-08-02-18-54.gh-issue-149474.ujQ-mu.rst
deleted file mode 100644
index 48e718b95ebe3a..00000000000000
--- a/Misc/NEWS.d/next/Security/2026-05-08-02-18-54.gh-issue-149474.ujQ-mu.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-Fix the binary writer in :mod:`profiling.sampling` not firing the audit
-(:pep:`578`) when creating the output file. The writer and the reader now
-accept any path-like object. Patch by Maurycy Pawłowski-Wieroński.
diff --git a/Misc/NEWS.d/next/Security/2026-05-10-18-05-32.gh-issue-87451.XkKB6M.rst b/Misc/NEWS.d/next/Security/2026-05-10-18-05-32.gh-issue-87451.XkKB6M.rst
deleted file mode 100644
index 21a79c3e0e7db7..00000000000000
--- a/Misc/NEWS.d/next/Security/2026-05-10-18-05-32.gh-issue-87451.XkKB6M.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-The :mod:`ftplib` module's undocumented ``ftpcp`` function no longer trusts
-the IPv4 address value returned from the source server in response to the
-``PASV`` command by default, completing the fix for CVE-2021-4189. As with
-:class:`ftplib.FTP`, the former behavior can be re-enabled by setting the
-``trust_server_pasv_ipv4_address`` attribute on the source :class:`ftplib.FTP`
-instance to ``True``. Thanks to Qi Deng at Aurascape AI for the report.
diff --git a/Misc/NEWS.d/next/Security/2026-05-11-21-15-07.gh-issue-149698.OudOcW.rst b/Misc/NEWS.d/next/Security/2026-05-11-21-15-07.gh-issue-149698.OudOcW.rst
deleted file mode 100644
index 3c8671b9a5adc4..00000000000000
--- a/Misc/NEWS.d/next/Security/2026-05-11-21-15-07.gh-issue-149698.OudOcW.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Update bundled `libexpat `_ to version 2.8.1
-for the fix for :cve:`2026-45186`.
diff --git a/Misc/NEWS.d/next/Tests/2026-05-13-14-53-23.gh-issue-149776.orqgsn.rst b/Misc/NEWS.d/next/Tests/2026-05-13-14-53-23.gh-issue-149776.orqgsn.rst
deleted file mode 100644
index e86a9130ff9bfb..00000000000000
--- a/Misc/NEWS.d/next/Tests/2026-05-13-14-53-23.gh-issue-149776.orqgsn.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix test_socket on Linux kernel 7.1 and newer: skip UDP Lite tests if it's
-not supported. Patch by Victor Stinner.
diff --git a/Misc/NEWS.d/next/Tests/2026-05-25-15-39-53.gh-issue-150387.yzZ7jq.rst b/Misc/NEWS.d/next/Tests/2026-05-25-15-39-53.gh-issue-150387.yzZ7jq.rst
deleted file mode 100644
index 663a357a179204..00000000000000
--- a/Misc/NEWS.d/next/Tests/2026-05-25-15-39-53.gh-issue-150387.yzZ7jq.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Fix hang in
-``test.test_profiling.test_sampling_profiler.test_live_collector_ui.TestLiveModeErrors.test_run_failed_script_live``
-on slow buildbots. The test now always queues a final ``q`` keystroke so the
-live TUI loop exits even when the profiler collects enough samples to enter
-the post-finished input loop.
diff --git a/Misc/NEWS.d/next/Tools-Demos/2026-05-22-18-51-09.gh-issue-150258.dh8GVK.rst b/Misc/NEWS.d/next/Tools-Demos/2026-05-22-18-51-09.gh-issue-150258.dh8GVK.rst
deleted file mode 100644
index 02cad6c4f53d92..00000000000000
--- a/Misc/NEWS.d/next/Tools-Demos/2026-05-22-18-51-09.gh-issue-150258.dh8GVK.rst
+++ /dev/null
@@ -1 +0,0 @@
-Update the tooltip on the Tachyon flame graph to show both absolute and relative percentages.
diff --git a/Misc/NEWS.d/next/Windows/2026-04-26-23-14-45.gh-issue-149029.oPTXP4.rst b/Misc/NEWS.d/next/Windows/2026-04-26-23-14-45.gh-issue-149029.oPTXP4.rst
deleted file mode 100644
index 6c4c6403b98984..00000000000000
--- a/Misc/NEWS.d/next/Windows/2026-04-26-23-14-45.gh-issue-149029.oPTXP4.rst
+++ /dev/null
@@ -1 +0,0 @@
-Update Windows installer to ship with SQLite 3.53.1.
diff --git a/Misc/NEWS.d/next/Windows/2026-04-29-14-44-51.gh-issue-138489.234aj6.rst b/Misc/NEWS.d/next/Windows/2026-04-29-14-44-51.gh-issue-138489.234aj6.rst
deleted file mode 100644
index 4afb8f737b692e..00000000000000
--- a/Misc/NEWS.d/next/Windows/2026-04-29-14-44-51.gh-issue-138489.234aj6.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-Windows distributions now include a :file:`build-details.json` file (see
-:pep:`739`). The legacy installer does not install it, but all other
-distributions from python.org and all preset configurations in the
-``PC\layout`` script will include one.
diff --git a/Misc/NEWS.d/next/Windows/2026-05-06-21-36-53.gh-issue-124111.m4OBX8.rst b/Misc/NEWS.d/next/Windows/2026-05-06-21-36-53.gh-issue-124111.m4OBX8.rst
deleted file mode 100644
index 9a57536f1dc96b..00000000000000
--- a/Misc/NEWS.d/next/Windows/2026-05-06-21-36-53.gh-issue-124111.m4OBX8.rst
+++ /dev/null
@@ -1 +0,0 @@
-Updated Windows builds to use Tcl/Tk 9.0.3.
diff --git a/Misc/NEWS.d/next/Windows/2026-05-14-22-09-46.gh-issue-149786.UI-HZM.rst b/Misc/NEWS.d/next/Windows/2026-05-14-22-09-46.gh-issue-149786.UI-HZM.rst
deleted file mode 100644
index 64ca91a01f41af..00000000000000
--- a/Misc/NEWS.d/next/Windows/2026-05-14-22-09-46.gh-issue-149786.UI-HZM.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fixes virtual environment launchers on Windows free-threaded builds.
diff --git a/Misc/NEWS.d/next/macOS/2026-04-26-23-15-09.gh-issue-149029.Lsx--T.rst b/Misc/NEWS.d/next/macOS/2026-04-26-23-15-09.gh-issue-149029.Lsx--T.rst
deleted file mode 100644
index 157a70f5e3cefc..00000000000000
--- a/Misc/NEWS.d/next/macOS/2026-04-26-23-15-09.gh-issue-149029.Lsx--T.rst
+++ /dev/null
@@ -1 +0,0 @@
-Update macOS installer to ship with SQLite version 3.53.1.
diff --git a/Misc/NEWS.d/next/macOS/2026-05-31-10-40-00.gh-issue-150644.zLWyjj.rst b/Misc/NEWS.d/next/macOS/2026-05-31-10-40-00.gh-issue-150644.zLWyjj.rst
deleted file mode 100644
index 7452a7c765c0a8..00000000000000
--- a/Misc/NEWS.d/next/macOS/2026-05-31-10-40-00.gh-issue-150644.zLWyjj.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-When system logging is enabled (with ``config.use_system_logger``, messages
-are now tagged as public. This allows the macOS 26 system logger to view
-messages without special configuration.
diff --git a/README.rst b/README.rst
index e9dd44382972d5..ac84a8a7d054bd 100644
--- a/README.rst
+++ b/README.rst
@@ -1,4 +1,4 @@
-This is Python version 3.15.0 beta 1
+This is Python version 3.15.0 beta 2
====================================
.. image:: https://github.com/python/cpython/actions/workflows/build.yml/badge.svg?branch=main&event=push
From fd0a7fd5ba19986bbb9bb22c5d80811e648f7396 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Tue, 2 Jun 2026 17:31:56 +0200
Subject: [PATCH 208/213] [3.15] gh-101913: changed wording of docstring for
_parsedate_tz (GH-134446) (#150796)
Fixed incorrect word.
(cherry picked from commit f7e0fb60cfaf31373c0b78e6eb954a0351e92f09)
Co-authored-by: Gustaf <79180496+gostak-dd@users.noreply.github.com>
Co-authored-by: Gustaf <79180496+GGyll@users.noreply.github.com>
---
Lib/email/_parseaddr.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Lib/email/_parseaddr.py b/Lib/email/_parseaddr.py
index 6a7c5fa06d20b6..e311948cb09a7d 100644
--- a/Lib/email/_parseaddr.py
+++ b/Lib/email/_parseaddr.py
@@ -59,7 +59,7 @@ def _parsedate_tz(data):
The last (additional) element is the time zone offset in seconds, except if
the timezone was specified as -0000. In that case the last element is
- None. This indicates a UTC timestamp that explicitly declaims knowledge of
+ None. This indicates a UTC timestamp that explicitly disclaims knowledge of
the source timezone, as opposed to a +0000 timestamp that indicates the
source timezone really was UTC.
From a1387695946b17002c2b97b7690e14dc6efc5924 Mon Sep 17 00:00:00 2001
From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Date: Tue, 2 Jun 2026 20:34:33 +0300
Subject: [PATCH 209/213] Post 3.15.0b2
---
Include/patchlevel.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Include/patchlevel.h b/Include/patchlevel.h
index 649609136fec80..e474c56e101e1b 100644
--- a/Include/patchlevel.h
+++ b/Include/patchlevel.h
@@ -27,7 +27,7 @@
#define PY_RELEASE_SERIAL 2
/* Version as a string */
-#define PY_VERSION "3.15.0b2"
+#define PY_VERSION "3.15.0b2+dev"
/*--end constants--*/
From 0aa9f434ad878bbbdf50e66ad484bae1a2085e92 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Tue, 2 Jun 2026 21:20:49 +0200
Subject: [PATCH 210/213] [3.15] Fix description of the function parameter of
shutil.register_archive_format() (GH-145087) (GH-150804)
(cherry picked from commit 18c6d3ccc32232a28a5288708818ef9c4fecba1a)
Co-authored-by: Brian Schubert
---
Doc/library/shutil.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst
index e0300a38e2f357..6a734966d1e0a4 100644
--- a/Doc/library/shutil.rst
+++ b/Doc/library/shutil.rst
@@ -696,7 +696,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules.
Register an archiver for the format *name*.
- *function* is the callable that will be used to unpack archives. The callable
+ *function* is the callable that will be used to create archives. The callable
will receive the *base_name* of the file to create, followed by the
*base_dir* (which defaults to :data:`os.curdir`) to start archiving from.
Further arguments are passed as keyword arguments: *owner*, *group*,
From d5f93ce15601d887bb6fd562ea33fd48dad33960 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Tue, 2 Jun 2026 21:23:15 +0200
Subject: [PATCH 211/213] [3.15] gh-141627: Fix BufferedRandom inheritance
documentation (GH-141629) (GH-150801)
BufferedRandom does not inherit from BufferedReader and BufferedWriter
in the C implementation.
(cherry picked from commit 551bc2cb5ed4719c35ca3ea0f320167dd750389e)
Co-authored-by: Mohsin Mehmood <55545648+mohsinm-dev@users.noreply.github.com>
---
Doc/library/io.rst | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Doc/library/io.rst b/Doc/library/io.rst
index 494e57fe1c0474..8c0eed592dd49e 100644
--- a/Doc/library/io.rst
+++ b/Doc/library/io.rst
@@ -824,9 +824,9 @@ than raw I/O does.
.. class:: BufferedRandom(raw, buffer_size=DEFAULT_BUFFER_SIZE)
- A buffered binary stream providing higher-level access to a seekable
- :class:`RawIOBase` raw binary stream. It inherits from :class:`BufferedReader`
- and :class:`BufferedWriter`.
+ A buffered binary stream implementing :class:`BufferedIOBase` interfaces
+ providing higher-level access to a seekable :class:`RawIOBase` raw binary
+ stream.
The constructor creates a reader and writer for a seekable raw stream, given
in the first argument. If the *buffer_size* is omitted it defaults to
From 1c2daa08fb8b802e6057378d78e8e2b38b14abdb Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Tue, 2 Jun 2026 22:40:52 +0200
Subject: [PATCH 212/213] [3.15] gh-150319: Replace all documentation which
says "See PEP 585" (GH-150325) (#150808)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
gh-150319: Replace all documentation which says "See PEP 585" (GH-150325)
* Replace all documentation which says "See PEP 585"
The following classes in the stdlib get simple updates:
- array.array
- asyncio.Future
- asyncio.Task
- collections.defaultdict
- collections.deque
- contextvars.ContextVar
- contextvars.Token
- ctypes.Array
- os.DirEntry
- re.Match
- re.Pattern
- string.templatelib.Interpolation
- string.templatelib.Template
- types.MappingProxyType
- queue.SimpleQueue
- weakref.ref
The following classes are documented publicly as functions, and are
therefore updated internally (`__class_getitem__.__doc__`) but not in the
public docs:
- functools.partial
- itertools.chain
The following builtin types have updates to `__class_getitem__.__doc__`
but not to any documentation pages:
- BaseExceptionGroup
- coroutines (from generators)
- dict
- enumerate
- frozendict
- frozenset
- generators (and async generators)
- list
- memoryview
- set
- slice
- tuple
Special cases:
- union objects are now documented as "supporting class-level []",
rather than anything to do with generics.
- Templates might be generic over a single type (union, in theory) or
over a TypeVarTuple. As this is not currently fully settled, it is
marked with a comment and a mild hint that it is a single type is used
(namely, "type" is singular rather than "types", plural)
* Apply suggestions from code review
* Correct several class getitem docs
And expand the text for tuples.
* Add notes on generic typing of builtins
* Fix typo in tuple.__class_getitem__ docstring
* Typo fix: malformed refs
Fix `generic` links which weren't marked as `:ref:`.
* Strike unnecessary docs on generic-ness
* Apply suggestions from code review
These are applied at both the originally indicated locations and in the
corresponding docstring definitions.
* Update Doc/library/re.rst
* Update Objects/enumobject.c
* Remove tuple generic doc in 'stdtypes' page
This is covered in more detail in the cross-linked typing documentation.
The other copy of this documentation -- in the docstring for
`tuple.__class_getitem__` -- is left in place.
* Fix whitespace around new doc of generics
Per review, do not introduce or remove whitespace such that section
breaks are altered by the introduction of doc on various generic types.
In most cases, this is a removal of an extra line.
In one case (Arrays), it is the reintroduction of a line.
Additionally, two other minor fixes are included:
- incorrect indent on 'defaultdicts'
- make `mappingproxy.__class_getitem__.__doc__` consistent with other
mapping type generic docs
* Move placement of memoryview generic note
Previous placement was at the end of the main docstring, which is
consistent with other types but places it after a section on various
methods (which makes it read somewhat inconsistently). Moving it up
helps resolve.
* Ensure sphinxdoc does not start sentences lowercase
Lowercase class names at the start of sentences are marked out with the
`class` role. In the case of `deque`, documentation already refers to
these as `Deques`, so this form is preferred.
* Apply suggestions from code review
* Fix line endings and wrap more tightly
Line endings fixed by pre-commit ; also re-wrapped the MappingProxyType
text which was too long.
* Use 'ContextVars' style in sphinx doc
---------
(cherry picked from commit 50fe49c879af352914da3baa40c7fd1fb170028c)
Co-authored-by: Stephen Rosen
Co-authored-by: Jelle Zijlstra
Co-authored-by: Jelle Zijlstra <906600+JelleZijlstra@users.noreply.github.com>
Co-authored-by: Alex Waygood <66076021+AlexWaygood@users.noreply.github.com>
Co-authored-by: Alex Waygood
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
---
Doc/c-api/typehints.rst | 2 +-
Doc/library/array.rst | 2 ++
Doc/library/asyncio-future.rst | 2 ++
Doc/library/asyncio-task.rst | 3 +++
Doc/library/collections.rst | 5 +++++
Doc/library/contextvars.rst | 6 ++++++
Doc/library/ctypes.rst | 2 ++
Doc/library/exceptions.rst | 3 +++
Doc/library/os.rst | 3 +++
Doc/library/queue.rst | 2 ++
Doc/library/re.rst | 6 ++++++
Doc/library/stdtypes.rst | 17 +++++++++++++++++
Doc/library/string.templatelib.rst | 2 ++
Doc/library/types.rst | 4 ++++
Doc/library/weakref.rst | 3 +++
Doc/reference/datamodel.rst | 3 +++
...26-05-23-17-27-41.gh-issue-150319.ol9tWK.rst | 2 ++
Modules/_asynciomodule.c | 6 ++++--
Modules/_collectionsmodule.c | 10 ++++++++--
Modules/_ctypes/_ctypes.c | 2 +-
Modules/_functoolsmodule.c | 3 ++-
Modules/_queuemodule.c | 2 +-
Modules/_sre/sre.c | 4 ++--
Modules/arraymodule.c | 3 ++-
Modules/itertoolsmodule.c | 6 +++++-
Modules/posixmodule.c | 2 +-
Objects/descrobject.c | 2 +-
Objects/dictobject.c | 6 ++++--
Objects/enumobject.c | 2 +-
Objects/exceptions.c | 3 ++-
Objects/genobject.c | 8 +++++---
Objects/interpolationobject.c | 2 +-
Objects/listobject.c | 3 ++-
Objects/memoryobject.c | 3 ++-
Objects/setobject.c | 6 ++++--
Objects/sliceobject.c | 3 ++-
Objects/templateobject.c | 6 +++++-
Objects/tupleobject.c | 8 +++++++-
Objects/unionobject.c | 3 ++-
Objects/weakrefobject.c | 3 ++-
Python/context.c | 6 ++++--
41 files changed, 136 insertions(+), 33 deletions(-)
create mode 100644 Misc/NEWS.d/next/Documentation/2026-05-23-17-27-41.gh-issue-150319.ol9tWK.rst
diff --git a/Doc/c-api/typehints.rst b/Doc/c-api/typehints.rst
index 98fe68737deb81..ec2fba6da8b043 100644
--- a/Doc/c-api/typehints.rst
+++ b/Doc/c-api/typehints.rst
@@ -31,7 +31,7 @@ two types exist -- :ref:`GenericAlias ` and
static PyMethodDef my_obj_methods[] = {
// Other methods.
...
- {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, "See PEP 585"}
+ {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, "my_obj is generic over its contained type"}
...
}
diff --git a/Doc/library/array.rst b/Doc/library/array.rst
index ca7c055285aa82..da9b3fa2fe8a5d 100644
--- a/Doc/library/array.rst
+++ b/Doc/library/array.rst
@@ -134,6 +134,8 @@ The module defines the following type:
:exc:`TypeError` is raised. Array objects also implement the buffer interface,
and may be used wherever :term:`bytes-like objects ` are supported.
+ Arrays are :ref:`generic ` over the type of their contents.
+
.. audit-event:: array.__new__ typecode,initializer array.array
diff --git a/Doc/library/asyncio-future.rst b/Doc/library/asyncio-future.rst
index 43977de273e61f..195d99123dbd36 100644
--- a/Doc/library/asyncio-future.rst
+++ b/Doc/library/asyncio-future.rst
@@ -101,6 +101,8 @@ Future Object
implementations can inject their own optimized implementations
of a Future object.
+ Futures are :ref:`generic ` over the type of their results.
+
.. versionchanged:: 3.7
Added support for the :mod:`contextvars` module.
diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst
index cc833b80d52542..64f0810777e41b 100644
--- a/Doc/library/asyncio-task.rst
+++ b/Doc/library/asyncio-task.rst
@@ -1230,6 +1230,9 @@ Task object
blocks. If the coroutine returns or raises without blocking, the task
will be finished eagerly and will skip scheduling to the event loop.
+ Tasks are :ref:`generic ` over the return type of their wrapped
+ coroutines.
+
.. versionchanged:: 3.7
Added support for the :mod:`contextvars` module.
diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst
index e42bdc06be09ff..25e4a71b03c6c8 100644
--- a/Doc/library/collections.rst
+++ b/Doc/library/collections.rst
@@ -484,6 +484,8 @@ or subtracting from an empty counter.
Unix. They are also useful for tracking transactions and other pools of data
where only the most recent activity is of interest.
+ Deques are :ref:`generic