Skip to content

Commit c16c2f2

Browse files
remove ast star import, fix builtin import
1 parent b0951cd commit c16c2f2

File tree

2 files changed

+28
-25
lines changed

2 files changed

+28
-25
lines changed

bpython/simpleeval.py

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
66
"""
77

8-
from ast import *
8+
import ast
99
from six import string_types
10+
from six.moves import builtins
1011

1112
from bpython import line as line_properties
1213

@@ -23,6 +24,7 @@ def safe_eval(expr, namespace):
2324
# raise
2425
raise EvaluationError
2526

27+
# taken from Python 2 stdlib ast.literal_eval
2628
def simple_eval(node_or_string, namespace=None):
2729
"""
2830
Safely evaluate an expression node or a string containing a Python
@@ -37,43 +39,44 @@ def simple_eval(node_or_string, namespace=None):
3739
3840
The optional namespace dict-like ought not to cause side effects on lookup
3941
"""
42+
# Based heavily on stdlib ast.literal_eval
4043
if namespace is None:
4144
namespace = {}
4245
if isinstance(node_or_string, string_types):
43-
node_or_string = parse(node_or_string, mode='eval')
44-
if isinstance(node_or_string, Expression):
46+
node_or_string = ast.parse(node_or_string, mode='eval')
47+
if isinstance(node_or_string, ast.Expression):
4548
node_or_string = node_or_string.body
4649
def _convert(node):
47-
if isinstance(node, Str):
50+
if isinstance(node, ast.Str):
4851
return node.s
49-
elif isinstance(node, Num):
52+
elif isinstance(node, ast.Num):
5053
return node.n
51-
elif isinstance(node, Tuple):
54+
elif isinstance(node, ast.Tuple):
5255
return tuple(map(_convert, node.elts))
53-
elif isinstance(node, List):
56+
elif isinstance(node, ast.List):
5457
return list(map(_convert, node.elts))
55-
elif isinstance(node, Dict):
58+
elif isinstance(node, ast.Dict):
5659
return dict((_convert(k), _convert(v)) for k, v
5760
in zip(node.keys, node.values))
58-
elif isinstance(node, Name):
61+
elif isinstance(node, ast.Name):
5962
try:
6063
return namespace[node.id]
6164
except KeyError:
62-
return __builtins__[node.id]
63-
elif isinstance(node, BinOp) and \
64-
isinstance(node.op, (Add, Sub)) and \
65-
isinstance(node.right, Num) and \
65+
return getattr(builtins, node.id)
66+
elif isinstance(node, ast.BinOp) and \
67+
isinstance(node.op, (ast.Add, ast.Sub)) and \
68+
isinstance(node.right, ast.Num) and \
6669
isinstance(node.right.n, complex) and \
67-
isinstance(node.left, Num) and \
70+
isinstance(node.left, ast.Num) and \
6871
isinstance(node.left.n, (int, long, float)):
6972
left = node.left.n
7073
right = node.right.n
71-
if isinstance(node.op, Add):
74+
if isinstance(node.op, ast.Add):
7275
return left + right
7376
else:
7477
return left - right
75-
elif isinstance(node, Subscript) and \
76-
isinstance(node.slice, Index):
78+
elif isinstance(node, ast.Subscript) and \
79+
isinstance(node.slice, ast.Index):
7780
obj = _convert(node.value)
7881
index = _convert(node.slice.value)
7982
return safe_getitem(obj, index)
@@ -90,16 +93,16 @@ def safe_getitem(obj, index):
9093

9194
def find_attribute_with_name(node, name):
9295
"""Based on ast.NodeVisitor"""
93-
if isinstance(node, Attribute) and node.attr == name:
96+
if isinstance(node, ast.Attribute) and node.attr == name:
9497
return node
95-
for field, value in iter_fields(node):
98+
for field, value in ast.iter_fields(node):
9699
if isinstance(value, list):
97100
for item in value:
98-
if isinstance(item, AST):
101+
if isinstance(item, ast.AST):
99102
r = find_attribute_with_name(item, name)
100103
if r:
101104
return r
102-
elif isinstance(value, AST):
105+
elif isinstance(value, ast.AST):
103106
r = find_attribute_with_name(value, name)
104107
if r:
105108
return r
@@ -126,8 +129,8 @@ def evaluate_current_expression(cursor_offset, line, namespace={}):
126129
def parse_trees(cursor_offset, line):
127130
for i in range(cursor_offset-1, -1, -1):
128131
try:
129-
ast = parse(line[i:cursor_offset])
130-
yield ast
132+
tree = ast.parse(line[i:cursor_offset])
133+
yield tree
131134
except SyntaxError:
132135
continue
133136

@@ -141,5 +144,5 @@ def parse_trees(cursor_offset, line):
141144
raise EvaluationError("Corresponding ASTs to right of cursor are invalid")
142145
try:
143146
return simple_eval(largest_ast, namespace)
144-
except (ValueError, KeyError, IndexError):
147+
except (ValueError, KeyError, IndexError, AttributeError):
145148
raise EvaluationError("Could not safely evaluate")

bpython/test/test_simpleeval.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def test_function_calls_raise(self):
6565
simple_eval('1()')
6666

6767
def test_nonexistant_names_raise(self):
68-
with self.assertRaises(KeyError):
68+
with self.assertRaises((KeyError, AttributeError)):
6969
simple_eval('a')
7070

7171
class TestEvaluateCurrentExpression(unittest.TestCase):

0 commit comments

Comments
 (0)