Skip to content

Commit bc95973

Browse files
committed
Fix handling on negative numbers in ast.literal_eval().
1 parent 4f3abb0 commit bc95973

File tree

3 files changed

+20
-8
lines changed

3 files changed

+20
-8
lines changed

Lib/ast.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,25 @@ def _convert(node):
6565
elif isinstance(node, Name):
6666
if node.id in _safe_names:
6767
return _safe_names[node.id]
68+
elif isinstance(node, UnaryOp) and \
69+
isinstance(node.op, (UAdd, USub)) and \
70+
isinstance(node.operand, (Num, UnaryOp, BinOp)):
71+
operand = _convert(node.operand)
72+
if isinstance(node.op, UAdd):
73+
return + operand
74+
else:
75+
return - operand
6876
elif isinstance(node, BinOp) and \
6977
isinstance(node.op, (Add, Sub)) and \
70-
isinstance(node.right, Num) and \
71-
isinstance(node.right.n, complex) and \
72-
isinstance(node.left, Num) and \
73-
isinstance(node.left.n, (int, float)):
74-
left = node.left.n
75-
right = node.right.n
78+
isinstance(node.right, (Num, UnaryOp, BinOp)) and \
79+
isinstance(node.left, (Num, UnaryOp, BinOp)):
80+
left = _convert(node.left)
81+
right = _convert(node.right)
7682
if isinstance(node.op, Add):
7783
return left + right
7884
else:
7985
return left - right
80-
raise ValueError('malformed string')
86+
raise ValueError('malformed node or string: ' + repr(node))
8187
return _convert(node_or_string)
8288

8389

Lib/test/test_ast.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,12 +288,14 @@ def test_literal_eval(self):
288288
self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
289289
self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
290290
self.assertRaises(ValueError, ast.literal_eval, 'foo()')
291+
self.assertEqual(ast.literal_eval('-6'), -6)
292+
self.assertEqual(ast.literal_eval('-6j+3'), 3-6j)
293+
self.assertEqual(ast.literal_eval('3.25'), 3.25)
291294

292295
def test_literal_eval_issue4907(self):
293296
self.assertEqual(ast.literal_eval('2j'), 2j)
294297
self.assertEqual(ast.literal_eval('10 + 2j'), 10 + 2j)
295298
self.assertEqual(ast.literal_eval('1.5 - 2j'), 1.5 - 2j)
296-
self.assertRaises(ValueError, ast.literal_eval, '2 + (3 + 4j)')
297299

298300

299301
def test_main():

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ What's New in Python 3.2 Alpha 3?
1010
Core and Builtins
1111
-----------------
1212

13+
- ast.literal_eval() can now handle negative numbers. It is also a little
14+
more liberal in what it accepts without compromising the safety of the
15+
evaluation. For example, 3j+4 and 3+4+5 are both accepted.
16+
1317
- Issue #10006: type.__abstractmethods__ now raises an AttributeError. As a
1418
result metaclasses can now be ABCs (see #9533).
1519

0 commit comments

Comments
 (0)