From d59d4e747c76d39a6ac80025cff4686a9fa96eaf Mon Sep 17 00:00:00 2001 From: David Vo Date: Sun, 30 Aug 2026 22:02:59 +1000 Subject: [PATCH 1/5] Enable linting of lazy import tests (#156624) --- Lib/test/.ruff.toml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Lib/test/.ruff.toml b/Lib/test/.ruff.toml index dca74eb6e14bbd..da4f32a01bccf5 100644 --- a/Lib/test/.ruff.toml +++ b/Lib/test/.ruff.toml @@ -14,10 +14,8 @@ extend-exclude = [ # New grammar constructions may not yet be recognized by Ruff, # and tests re-use the same names as only the grammar is being checked. "test_grammar.py", - # Lazy import syntax (PEP 810) is not yet supported by Ruff - "test_lazy_import/__init__.py", - "test_lazy_import/data/*.py", - "test_lazy_import/data/**/*.py", + # Intentional bad lazy import syntax + "test_lazy_import/data/badsyntax/*.py", # Unary plus literal pattern is not yet supported by Ruff (GH-145239) "test_patma.py", ] @@ -32,4 +30,5 @@ select = [ "*/**/__main__.py" = ["F401"] # Unused import "test_import/*.py" = ["F401"] # Unused import "test_importlib/*.py" = ["F401"] # Unused import +"test_lazy_import/**/*.py" = ["F401"] # Unused import "typinganndata/partialexecution/*.py" = ["F401"] # Unused import From b3ddde433e69166ecdf40095349f69e08997e9cb Mon Sep 17 00:00:00 2001 From: Vyron Vasileiadis Date: Sun, 30 Aug 2026 17:47:53 +0300 Subject: [PATCH 2/5] gh-156500: Reject non-positional parameters in `ctypes.util.wrap_dll_function` (GH-156501) argtypes was built from every annotated parameter, so an annotated keyword-only, *args, or **kwargs parameter contributed an extra positional entry. Such a parameter has no positional counterpart to describe, so it now raises ValueError at decoration time. --- Doc/library/ctypes.rst | 7 +++-- Lib/ctypes/util.py | 8 ++++++ Lib/test/test_ctypes/test_funcptr.py | 41 ++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index acd6c2f97348e1..d76c449626fab4 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -715,8 +715,11 @@ Specifying function pointers using type annotations and do not have to match the underlying C implementation. If the decorated function does not have a return type annotation, a - :exc:`ValueError` is raised. If the name of the function does not exist - in *dll*, an :exc:`AttributeError` is raised. + :exc:`ValueError` is raised. A :exc:`ValueError` is also raised if it has a + keyword-only, ``*args``, or ``**kwargs`` parameter, since + :attr:`~ctypes._CFuncPtr.argtypes` describes positional arguments only. If + the name of the function does not exist in *dll*, an :exc:`AttributeError` + is raised. For example:: diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index 141d3fbe938247..2b01506f3d4ffa 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -4,6 +4,7 @@ from dataclasses import dataclass lazy import functools +lazy import inspect lazy import shutil lazy import subprocess @@ -509,6 +510,13 @@ def decorator(func): except KeyError as error: raise ValueError(f"{name!r} missing return type annotation") from error + for param in inspect.signature(func).parameters.values(): + if param.kind not in (param.POSITIONAL_ONLY, + param.POSITIONAL_OR_KEYWORD): + raise ValueError(f"{name!r} has non-positional parameter " + f"{param.name!r}; argtypes describes " + f"positional arguments only") + ptr.restype = restype ptr.argtypes = tuple(annotations.values()) functools.update_wrapper(ptr, func, updated=()) diff --git a/Lib/test/test_ctypes/test_funcptr.py b/Lib/test/test_ctypes/test_funcptr.py index 28ff34f9048454..b4c27809b5333d 100644 --- a/Lib/test/test_ctypes/test_funcptr.py +++ b/Lib/test/test_ctypes/test_funcptr.py @@ -153,6 +153,47 @@ def noexist(): def PyObject_GetAttrString(op: ctypes.py_object, attr: ctypes.c_char_p): pass + def test_wrap_dll_function_non_positional(self): + # argtypes describes positional arguments only, so a parameter that + # cannot be passed positionally is rejected. + regex = "'PyObject_GetAttr' has non-positional parameter" + + with self.assertRaisesRegex(ValueError, regex): + @wrap_dll_function(ctypes.pythonapi) + def PyObject_GetAttr(op: ctypes.py_object, attr: ctypes.py_object, + *args: ctypes.c_int) -> ctypes.py_object: + pass + + with self.assertRaisesRegex(ValueError, regex): + @wrap_dll_function(ctypes.pythonapi) + def PyObject_GetAttr(op: ctypes.py_object, attr: ctypes.py_object, + **kwargs: ctypes.c_int) -> ctypes.py_object: + pass + + with self.assertRaisesRegex(ValueError, regex): + @wrap_dll_function(ctypes.pythonapi) + def PyObject_GetAttr(op: ctypes.py_object, attr: ctypes.py_object, + *, kwonly: ctypes.c_int) -> ctypes.py_object: + pass + + with self.assertRaisesRegex(ValueError, regex): + @wrap_dll_function(ctypes.pythonapi) + def PyObject_GetAttr(op: ctypes.py_object, attr: ctypes.py_object, + *, kwonly) -> ctypes.py_object: + pass + + # Positional-only parameters have a positional counterpart, so they + # are accepted. + @wrap_dll_function(ctypes.pythonapi) + def PyObject_GetAttr(op: ctypes.py_object, attr: ctypes.py_object, + /) -> ctypes.py_object: + pass + + class Foo: + a = "abc" + + self.assertEqual(PyObject_GetAttr(Foo, "a"), "abc") + def test_wrap_dll_function_str_ann(self): from test.test_ctypes import wrap_str_ann version = wrap_str_ann.Py_GetVersion() From 26d9b25580159abeb69b80ae6fbf511385eb6e99 Mon Sep 17 00:00:00 2001 From: Timofei Ivankov <128279579+deadlovelll@users.noreply.github.com> Date: Sun, 30 Aug 2026 18:20:54 +0300 Subject: [PATCH 3/5] gh-156662: Note that TaskGroup.create_task() raises RuntimeError (#156663) --- Doc/library/asyncio-task.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 689a6a6d2e0bd9..1a13ad387f89b2 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -356,7 +356,7 @@ and reliable way to wait for all tasks in the group to finish. The signature matches that of :func:`asyncio.create_task`. If the task group is inactive (e.g. not yet entered, already finished, or in the process of shutting down), - we will close the given ``coro``. + we will close the given ``coro`` and raise :exc:`RuntimeError`. .. versionchanged:: 3.13 From aad42883d6c49235a977c7203f4874ec69a9f262 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 30 Aug 2026 19:36:00 +0300 Subject: [PATCH 4/5] gh-123299: What's New: Link to compression and compression.zstd (#156661) --- Doc/whatsnew/3.14.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 64c6888d994770..6e3e6331a1b7e8 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -648,7 +648,7 @@ Improved error messages :pep:`784`: Zstandard support in the standard library ----------------------------------------------------- -The new :mod:`!compression` package contains modules :mod:`!compression.lzma`, +The new :mod:`compression` package contains modules :mod:`!compression.lzma`, :mod:`!compression.bz2`, :mod:`!compression.gzip` and :mod:`!compression.zlib` which re-export the :mod:`lzma`, :mod:`bz2`, :mod:`gzip` and :mod:`zlib` modules respectively. The new import names under :mod:`!compression` are the @@ -657,7 +657,7 @@ the existing modules names have not been deprecated. Any deprecation or removal of the existing compression modules will occur no sooner than five years after the release of 3.14. -The new :mod:`!compression.zstd` module provides compression and decompression +The new :mod:`compression.zstd` module provides compression and decompression APIs for the Zstandard format via bindings to `Meta's zstd library `__. Zstandard is a widely adopted, highly efficient, and fast compression format. In addition to the APIs introduced in From 852381efeecdb5ddd9e77250d9467d0af0d0acea Mon Sep 17 00:00:00 2001 From: Aradhya Gupta Date: Sun, 30 Aug 2026 22:38:35 +0530 Subject: [PATCH 5/5] gh-156614: Fix the parameter list grammar in the language reference (#156622) --- 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 e74f3262ed540c..28850ba801138f 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -1235,7 +1235,7 @@ A function definition defines a user-defined function object (see section : | `parameter_list_no_posonly` parameter_list_no_posonly: `defparameter` ("," `defparameter`)* ["," [`parameter_list_starargs`]] : | `parameter_list_starargs` - parameter_list_starargs: "*" [`star_parameter`] ("," `defparameter`)* ["," [`parameter_star_kwargs`]] + parameter_list_starargs: "*" `star_parameter` ("," `defparameter`)* ["," [`parameter_star_kwargs`]] : | "*" ("," `defparameter`)+ ["," [`parameter_star_kwargs`]] : | `parameter_star_kwargs` parameter_star_kwargs: "**" `parameter` [","]