Skip to content

Commit dbf40e7

Browse files
raise error in safe_eval instead of returning sentinal
1 parent 9a6f047 commit dbf40e7

File tree

2 files changed

+21
-18
lines changed

2 files changed

+21
-18
lines changed

bpython/autocomplete.py

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,10 @@ def matches(cls, cursor_offset, line, locals_, **kwargs):
205205
return None
206206
start, end, orig = r
207207
_, _, dexpr = lineparts.current_dict(cursor_offset, line)
208-
obj = safe_eval(dexpr, locals_)
209-
if obj is SafeEvalFailed:
208+
209+
try:
210+
obj = safe_eval(dexpr, locals_)
211+
except EvaluationError:
210212
return []
211213
if obj and isinstance(obj, type({})) and obj.keys():
212214
return ["{!r}]".format(k) for k in obj.keys() if repr(k).startswith(orig)]
@@ -328,23 +330,17 @@ def matches(cls, cursor_offset, line, **kwargs):
328330
return [match for match in matches if not match.startswith('_')]
329331
return matches
330332

331-
class SafeEvalFailed(Exception):
332-
"""If this object is returned, safe_eval failed"""
333-
# Because every normal Python value is a possible return value of safe_eval
333+
class EvaluationError(Exception):
334+
"""safe_eval failed"""
334335

335336
def safe_eval(expr, namespace):
336337
"""Not all that safe, just catches some errors"""
337-
if expr.isdigit():
338-
# Special case: float literal, using attrs here will result in
339-
# a SyntaxError
340-
return SafeEvalFailed
341338
try:
342-
obj = eval(expr, namespace)
343-
return obj
344-
except (NameError, AttributeError, SyntaxError) as e:
345-
# If debugging safe_eval, raise this!
346-
# raise e
347-
return SafeEvalFailed
339+
return eval(expr, namespace)
340+
except (NameError, AttributeError, SyntaxError):
341+
# If debugging safe_eval, reraise!
342+
# raise
343+
raise EvaluationError
348344

349345
def attr_matches(text, namespace, autocomplete_mode):
350346
"""Taken from rlcompleter.py and bent to my will.
@@ -358,8 +354,13 @@ def attr_matches(text, namespace, autocomplete_mode):
358354
return []
359355

360356
expr, attr = m.group(1, 3)
361-
obj = safe_eval(expr, namespace)
362-
if obj is SafeEvalFailed:
357+
if expr.isdigit():
358+
# Special case: float literal, using attrs here will result in
359+
# a SyntaxError
360+
return []
361+
try:
362+
obj = safe_eval(expr, namespace)
363+
except EvaluationError:
363364
return []
364365
with inspection.AttrCleaner(obj):
365366
matches = attr_lookup(obj, expr, attr, autocomplete_mode)

bpython/test/test_autocomplete.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ class TestSafeEval(unittest.TestCase):
1818
def test_catches_syntax_error(self):
1919
try:
2020
autocomplete.safe_eval('1re',{})
21-
except:
21+
except SyntaxError:
2222
self.fail('safe_eval raises an error')
23+
except autocomplete.EvaluationError as e:
24+
pass
2325

2426
class TestFormatters(unittest.TestCase):
2527

0 commit comments

Comments
 (0)