Skip to content

Commit 2a3b876

Browse files
bpo-40355: Improve error messages in ast.literal_eval with malformed Dict nodes (GH-19868)
Co-authored-by: Pablo Galindo <Pablogsal@gmail.com> (cherry picked from commit c21c512) Co-authored-by: Curtis Bucher <cpbucher5@gmail.com>
1 parent a6a116c commit 2a3b876

File tree

3 files changed

+15
-4
lines changed

3 files changed

+15
-4
lines changed

Lib/ast.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,12 @@ def literal_eval(node_or_string):
5959
node_or_string = parse(node_or_string, mode='eval')
6060
if isinstance(node_or_string, Expression):
6161
node_or_string = node_or_string.body
62+
def _raise_malformed_node(node):
63+
raise ValueError(f'malformed node or string: {node!r}')
6264
def _convert_num(node):
63-
if isinstance(node, Constant):
64-
if type(node.value) in (int, float, complex):
65-
return node.value
66-
raise ValueError('malformed node or string: ' + repr(node))
65+
if not isinstance(node, Constant) or type(node.value) not in (int, float, complex):
66+
_raise_malformed_node(node)
67+
return node.value
6768
def _convert_signed_num(node):
6869
if isinstance(node, UnaryOp) and isinstance(node.op, (UAdd, USub)):
6970
operand = _convert_num(node.operand)
@@ -82,6 +83,8 @@ def _convert(node):
8283
elif isinstance(node, Set):
8384
return set(map(_convert, node.elts))
8485
elif isinstance(node, Dict):
86+
if len(node.keys) != len(node.values):
87+
_raise_malformed_node(node)
8588
return dict(zip(map(_convert, node.keys),
8689
map(_convert, node.values)))
8790
elif isinstance(node, BinOp) and isinstance(node.op, (Add, Sub)):

Lib/test/test_ast.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,12 @@ def test_literal_eval_complex(self):
869869
self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
870870
self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
871871

872+
def test_literal_eval_malformed_dict_nodes(self):
873+
malformed = ast.Dict(keys=[ast.Constant(1), ast.Constant(2)], values=[ast.Constant(3)])
874+
self.assertRaises(ValueError, ast.literal_eval, malformed)
875+
malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)])
876+
self.assertRaises(ValueError, ast.literal_eval, malformed)
877+
872878
def test_bad_integer(self):
873879
# issue13436: Bad error message with invalid numeric values
874880
body = [ast.ImportFrom(module='time',
Lines 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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy