Skip to content

Commit 5b7dab7

Browse files
[3.13] gh-144169: Fix three crashes in AST objects with non-str kwargs (GH-144178)
(cherry picked from commit 639c1ad) Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com> Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent f9f0a78 commit 5b7dab7

4 files changed

Lines changed: 34 additions & 4 deletions

File tree

Lib/test/test_ast/test_ast.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,13 @@ def test_copy_with_parents(self):
11411141
self.assertEqual(to_tuple(child.parent), to_tuple(node))
11421142

11431143

1144+
def test_replace_non_str_kwarg(self):
1145+
node = ast.Name(id="x")
1146+
errmsg = "got an unexpected keyword argument <object object"
1147+
with self.assertRaisesRegex(TypeError, errmsg):
1148+
node.__replace__(**{object(): "y"})
1149+
1150+
11441151
class ASTHelpers_Test(unittest.TestCase):
11451152
maxDiff = None
11461153

@@ -3141,6 +3148,27 @@ class _AllFieldTypes(ast.AST):
31413148
self.assertIs(obj.a, None)
31423149
self.assertEqual(obj.b, [])
31433150

3151+
def test_non_str_kwarg(self):
3152+
warn_msg = "got an unexpected keyword argument <object object"
3153+
with (
3154+
self.assertRaises(TypeError),
3155+
self.assertWarnsRegex(DeprecationWarning, warn_msg),
3156+
):
3157+
ast.Name(**{object(): 'y'})
3158+
3159+
class FakeStr:
3160+
def __init__(self, value):
3161+
self.value = value
3162+
3163+
def __hash__(self):
3164+
return hash(self.value)
3165+
3166+
def __eq__(self, other):
3167+
return isinstance(other, str) and self.value == other
3168+
3169+
with self.assertRaisesRegex(TypeError, "got multiple values for argument"):
3170+
ast.Name("x", **{FakeStr('id'): 'y'})
3171+
31443172

31453173
@support.cpython_only
31463174
class ModuleStateTests(unittest.TestCase):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix three crashes when non-string keyword arguments are supplied to objects
2+
in the :mod:`ast` module.

Parser/asdl_c.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,7 @@ def visitModule(self, mod):
939939
}
940940
if (p == 0) {
941941
PyErr_Format(PyExc_TypeError,
942-
"%.400s got multiple values for argument '%U'",
942+
"%.400s got multiple values for argument %R",
943943
Py_TYPE(self)->tp_name, key);
944944
res = -1;
945945
goto cleanup;
@@ -962,7 +962,7 @@ def visitModule(self, mod):
962962
else if (contains == 0) {
963963
if (PyErr_WarnFormat(
964964
PyExc_DeprecationWarning, 1,
965-
"%.400s.__init__ got an unexpected keyword argument '%U'. "
965+
"%.400s.__init__ got an unexpected keyword argument %R. "
966966
"Support for arbitrary keyword arguments is deprecated "
967967
"and will be removed in Python 3.15.",
968968
Py_TYPE(self)->tp_name, key

Python/Python-ast.c

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)