]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-144169: Fix three crashes in AST objects with non-str kwargs (GH-144178...
authorJelle Zijlstra <jelle.zijlstra@gmail.com>
Wed, 28 Jan 2026 04:37:35 +0000 (20:37 -0800)
committerGitHub <noreply@github.com>
Wed, 28 Jan 2026 04:37:35 +0000 (20:37 -0800)
(cherry picked from commit 639c1ad4f1ef5c2409a62fa8ed16e6aa3a6f9ab8)

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
Lib/test/test_ast/test_ast.py
Misc/NEWS.d/next/Library/2026-01-23-06-43-21.gh-issue-144169.LFy9yi.rst [new file with mode: 0644]
Parser/asdl_c.py
Python/Python-ast.c

index a8d111a4afe79731606f7799296ac951c8fe1ebb..38dfc533c7eb2c4b39b69ec704e6fb6fb9557411 100644 (file)
@@ -3141,6 +3141,27 @@ class ASTConstructorTests(unittest.TestCase):
         self.assertIs(obj.a, None)
         self.assertEqual(obj.b, [])
 
+    def test_non_str_kwarg(self):
+        warn_msg = "got an unexpected keyword argument <object object"
+        with (
+            self.assertRaises(TypeError),
+            self.assertWarnsRegex(DeprecationWarning, warn_msg),
+        ):
+            ast.Name(**{object(): 'y'})
+
+        class FakeStr:
+            def __init__(self, value):
+                self.value = value
+
+            def __hash__(self):
+                return hash(self.value)
+
+            def __eq__(self, other):
+                return isinstance(other, str) and self.value == other
+
+        with self.assertRaisesRegex(TypeError, "got multiple values for argument"):
+            ast.Name("x", **{FakeStr('id'): 'y'})
+
 
 @support.cpython_only
 class ModuleStateTests(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/Library/2026-01-23-06-43-21.gh-issue-144169.LFy9yi.rst b/Misc/NEWS.d/next/Library/2026-01-23-06-43-21.gh-issue-144169.LFy9yi.rst
new file mode 100644 (file)
index 0000000..e2ef3d7
--- /dev/null
@@ -0,0 +1,2 @@
+Fix three crashes when non-string keyword arguments are supplied to objects
+in the :mod:`ast` module.
index 99312b36cd33c37001735e4b60216f1f283a783c..b69f7f0f0727d2dc4ab3d4a19a5452c2fb5c34dc 100755 (executable)
@@ -939,7 +939,7 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
                 }
                 if (p == 0) {
                     PyErr_Format(PyExc_TypeError,
-                        "%.400s got multiple values for argument '%U'",
+                        "%.400s got multiple values for argument %R",
                         Py_TYPE(self)->tp_name, key);
                     res = -1;
                     goto cleanup;
@@ -962,7 +962,7 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
                 else if (contains == 0) {
                     if (PyErr_WarnFormat(
                         PyExc_DeprecationWarning, 1,
-                        "%.400s.__init__ got an unexpected keyword argument '%U'. "
+                        "%.400s.__init__ got an unexpected keyword argument %R. "
                         "Support for arbitrary keyword arguments is deprecated "
                         "and will be removed in Python 3.15.",
                         Py_TYPE(self)->tp_name, key
index a71262c7f84abe824eb8253979e7b37f151eb64d..1871ca3fb3dd659fa89167f7ae3ee4c34de1d319 100644 (file)
@@ -5136,7 +5136,7 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
                 }
                 if (p == 0) {
                     PyErr_Format(PyExc_TypeError,
-                        "%.400s got multiple values for argument '%U'",
+                        "%.400s got multiple values for argument %R",
                         Py_TYPE(self)->tp_name, key);
                     res = -1;
                     goto cleanup;
@@ -5159,7 +5159,7 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
                 else if (contains == 0) {
                     if (PyErr_WarnFormat(
                         PyExc_DeprecationWarning, 1,
-                        "%.400s.__init__ got an unexpected keyword argument '%U'. "
+                        "%.400s.__init__ got an unexpected keyword argument %R. "
                         "Support for arbitrary keyword arguments is deprecated "
                         "and will be removed in Python 3.15.",
                         Py_TYPE(self)->tp_name, key