https://github.com/python/cpython/commit/bc92e7878f252fffbabfce6a0a453f99248b5f94
commit: bc92e7878f252fffbabfce6a0a453f99248b5f94
branch: 3.13
author: Jelle Zijlstra <[email protected]>
committer: JelleZijlstra <[email protected]>
date: 2026-01-27T20:37:35-08:00
summary:

[3.13] gh-144169: Fix three crashes in AST objects with non-str kwargs 
(GH-144178) (#144260)


(cherry picked from commit 639c1ad4f1ef5c2409a62fa8ed16e6aa3a6f9ab8)

Co-authored-by: Jelle Zijlstra <[email protected]>
Co-authored-by: Victor Stinner <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-01-23-06-43-21.gh-issue-144169.LFy9yi.rst
M Lib/test/test_ast/test_ast.py
M Parser/asdl_c.py
M Python/Python-ast.c

diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py
index a8d111a4afe797..38dfc533c7eb2c 100644
--- a/Lib/test/test_ast/test_ast.py
+++ b/Lib/test/test_ast/test_ast.py
@@ -3141,6 +3141,27 @@ class _AllFieldTypes(ast.AST):
         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
index 00000000000000..e2ef3d7c051d14
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-01-23-06-43-21.gh-issue-144169.LFy9yi.rst
@@ -0,0 +1,2 @@
+Fix three crashes when non-string keyword arguments are supplied to objects
+in the :mod:`ast` module.
diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py
index 99312b36cd33c3..b69f7f0f0727d2 100755
--- a/Parser/asdl_c.py
+++ b/Parser/asdl_c.py
@@ -939,7 +939,7 @@ def visitModule(self, mod):
                 }
                 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 @@ def visitModule(self, mod):
                 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
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index a71262c7f84abe..1871ca3fb3dd65 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -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

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to