Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c21c512

Browse filesBrowse files
bpo-40355: Improve error messages in ast.literal_eval with malformed Dict nodes (GH-19868)
Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
1 parent fb2c7c4 commit c21c512
Copy full SHA for c21c512

File tree

Expand file treeCollapse file tree

3 files changed

+15
-4
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+15
-4
lines changed

‎Lib/ast.py

Copy file name to clipboardExpand all lines: Lib/ast.py
+7-4Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,12 @@ def literal_eval(node_or_string):
6262
node_or_string = parse(node_or_string, mode='eval')
6363
if isinstance(node_or_string, Expression):
6464
node_or_string = node_or_string.body
65+
def _raise_malformed_node(node):
66+
raise ValueError(f'malformed node or string: {node!r}')
6567
def _convert_num(node):
66-
if isinstance(node, Constant):
67-
if type(node.value) in (int, float, complex):
68-
return node.value
69-
raise ValueError('malformed node or string: ' + repr(node))
68+
if not isinstance(node, Constant) or type(node.value) not in (int, float, complex):
69+
_raise_malformed_node(node)
70+
return node.value
7071
def _convert_signed_num(node):
7172
if isinstance(node, UnaryOp) and isinstance(node.op, (UAdd, USub)):
7273
operand = _convert_num(node.operand)
@@ -88,6 +89,8 @@ def _convert(node):
8889
node.func.id == 'set' and node.args == node.keywords == []):
8990
return set()
9091
elif isinstance(node, Dict):
92+
if len(node.keys) != len(node.values):
93+
_raise_malformed_node(node)
9194
return dict(zip(map(_convert, node.keys),
9295
map(_convert, node.values)))
9396
elif isinstance(node, BinOp) and isinstance(node.op, (Add, Sub)):

‎Lib/test/test_ast.py

Copy file name to clipboardExpand all lines: Lib/test/test_ast.py
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,12 @@ def test_literal_eval_complex(self):
965965
self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
966966
self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
967967

968+
def test_literal_eval_malformed_dict_nodes(self):
969+
malformed = ast.Dict(keys=[ast.Constant(1), ast.Constant(2)], values=[ast.Constant(3)])
970+
self.assertRaises(ValueError, ast.literal_eval, malformed)
971+
malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)])
972+
self.assertRaises(ValueError, ast.literal_eval, malformed)
973+
968974
def test_bad_integer(self):
969975
# issue13436: Bad error message with invalid numeric values
970976
body = [ast.ImportFrom(module='time',
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Improve error reporting in :func:`ast.literal_eval` in the presence of malformed :class:`ast.Dict`
2+
nodes instead of silently ignoring any non-conforming elements. Patch by Curtis Bucher.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.