[Python-checkins] bpo-40355: Improve error messages in ast.literal_eval with malformed Dict nodes (GH-19868)
Miss Islington (bot)
webhook-mailer at python.org
Tue May 5 16:01:05 EDT 2020
https://github.com/python/cpython/commit/2a3b876b0286b22a9058510d9e51dc4d60eeb89a
commit: 2a3b876b0286b22a9058510d9e51dc4d60eeb89a
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2020-05-05T13:00:57-07:00
summary:
bpo-40355: Improve error messages in ast.literal_eval with malformed Dict nodes (GH-19868)
Co-authored-by: Pablo Galindo <Pablogsal at gmail.com>
(cherry picked from commit c21c51235aa8061da6b0593d6f857f42fd92fd8b)
Co-authored-by: Curtis Bucher <cpbucher5 at gmail.com>
files:
A Misc/NEWS.d/next/Library/2020-05-02-14-24-48.bpo-40355.xTujaB.rst
M Lib/ast.py
M Lib/test/test_ast.py
diff --git a/Lib/ast.py b/Lib/ast.py
index 157a8332ebcc5..0c88bcf4c821e 100644
--- a/Lib/ast.py
+++ b/Lib/ast.py
@@ -59,11 +59,12 @@ def literal_eval(node_or_string):
node_or_string = parse(node_or_string, mode='eval')
if isinstance(node_or_string, Expression):
node_or_string = node_or_string.body
+ def _raise_malformed_node(node):
+ raise ValueError(f'malformed node or string: {node!r}')
def _convert_num(node):
- if isinstance(node, Constant):
- if type(node.value) in (int, float, complex):
- return node.value
- raise ValueError('malformed node or string: ' + repr(node))
+ if not isinstance(node, Constant) or type(node.value) not in (int, float, complex):
+ _raise_malformed_node(node)
+ return node.value
def _convert_signed_num(node):
if isinstance(node, UnaryOp) and isinstance(node.op, (UAdd, USub)):
operand = _convert_num(node.operand)
@@ -82,6 +83,8 @@ def _convert(node):
elif isinstance(node, Set):
return set(map(_convert, node.elts))
elif isinstance(node, Dict):
+ if len(node.keys) != len(node.values):
+ _raise_malformed_node(node)
return dict(zip(map(_convert, node.keys),
map(_convert, node.values)))
elif isinstance(node, BinOp) and isinstance(node.op, (Add, Sub)):
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
index 3e8a39dc41047..8887558ce4c31 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -869,6 +869,12 @@ def test_literal_eval_complex(self):
self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
+ def test_literal_eval_malformed_dict_nodes(self):
+ malformed = ast.Dict(keys=[ast.Constant(1), ast.Constant(2)], values=[ast.Constant(3)])
+ self.assertRaises(ValueError, ast.literal_eval, malformed)
+ malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)])
+ self.assertRaises(ValueError, ast.literal_eval, malformed)
+
def test_bad_integer(self):
# issue13436: Bad error message with invalid numeric values
body = [ast.ImportFrom(module='time',
diff --git a/Misc/NEWS.d/next/Library/2020-05-02-14-24-48.bpo-40355.xTujaB.rst b/Misc/NEWS.d/next/Library/2020-05-02-14-24-48.bpo-40355.xTujaB.rst
new file mode 100644
index 0000000000000..81f9e937a2bff
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-05-02-14-24-48.bpo-40355.xTujaB.rst
@@ -0,0 +1,2 @@
+Improve error reporting in :func:`ast.literal_eval` in the presence of malformed :class:`ast.Dict`
+nodes instead of silently ignoring any non-conforming elements. Patch by Curtis Bucher.
More information about the Python-checkins
mailing list