From 67d3d0344f129d486540ab0a41c8c820ca835d18 Mon Sep 17 00:00:00 2001 From: VanshAgarwal24036 <148854295+VanshAgarwal24036@users.noreply.github.com> Date: Thu, 8 Jan 2026 09:02:44 +0530 Subject: [PATCH 1/2] gh-143089: Fix ParamSpec default examples to use list instead of tuple (#143179) --- Objects/typevarobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Objects/typevarobject.c b/Objects/typevarobject.c index 8e43962c7e37f4..2ec546aff52c0a 100644 --- a/Objects/typevarobject.c +++ b/Objects/typevarobject.c @@ -1451,13 +1451,13 @@ The following syntax creates a parameter specification that defaults\n\ to a callable accepting two positional-only arguments of types int\n\ and str:\n\ \n\ - type IntFuncDefault[**P = (int, str)] = Callable[P, int]\n\ + type IntFuncDefault[**P = [int, str]] = Callable[P, int]\n\ \n\ For compatibility with Python 3.11 and earlier, ParamSpec objects\n\ can also be created as follows::\n\ \n\ P = ParamSpec('P')\n\ - DefaultP = ParamSpec('DefaultP', default=(int, str))\n\ + DefaultP = ParamSpec('DefaultP', default=[int, str])\n\ \n\ Parameter specification variables exist primarily for the benefit of\n\ static type checkers. They are used to forward the parameter types of\n\ From 6c9f7b4406d507625ff414cddc549d4c630c59c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20S=C5=82awecki?= Date: Thu, 8 Jan 2026 04:41:27 +0100 Subject: [PATCH 2/2] gh-143517: Fix an edge case in rewriting stringified starred annotations (#143518) --- Lib/annotationlib.py | 2 +- Lib/test/test_annotationlib.py | 3 +++ .../Library/2026-01-07-15-49-06.gh-issue-143517.FP5KgL.rst | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-07-15-49-06.gh-issue-143517.FP5KgL.rst diff --git a/Lib/annotationlib.py b/Lib/annotationlib.py index a5788cdbfae3f5..4085cc6bef7954 100644 --- a/Lib/annotationlib.py +++ b/Lib/annotationlib.py @@ -1096,7 +1096,7 @@ def _rewrite_star_unpack(arg): """If the given argument annotation expression is a star unpack e.g. `'*Ts'` rewrite it to a valid expression. """ - if arg.startswith("*"): + if arg.lstrip().startswith("*"): return f"({arg},)[0]" # E.g. (*Ts,)[0] or (*tuple[int, int],)[0] else: return arg diff --git a/Lib/test/test_annotationlib.py b/Lib/test/test_annotationlib.py index 8208d0e9c94819..a8537871d294cf 100644 --- a/Lib/test/test_annotationlib.py +++ b/Lib/test/test_annotationlib.py @@ -885,6 +885,9 @@ def test_stringized_annotations_with_star_unpack(self): def f(*args: "*tuple[int, ...]"): ... self.assertEqual(get_annotations(f, eval_str=True), {'args': (*tuple[int, ...],)[0]}) + def f(*args: " *tuple[int, ...]"): ... + self.assertEqual(get_annotations(f, eval_str=True), + {'args': (*tuple[int, ...],)[0]}) def test_stringized_annotations_on_wrapper(self): diff --git a/Misc/NEWS.d/next/Library/2026-01-07-15-49-06.gh-issue-143517.FP5KgL.rst b/Misc/NEWS.d/next/Library/2026-01-07-15-49-06.gh-issue-143517.FP5KgL.rst new file mode 100644 index 00000000000000..a9936b5d018692 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-07-15-49-06.gh-issue-143517.FP5KgL.rst @@ -0,0 +1,4 @@ +:func:`annotationlib.get_annotations` no longer raises a :exc:`SyntaxError` +when evaluating a stringified starred annotation that starts with one +or more whitespace characters followed by a ``*``. +Patch by Bartosz Sławecki.