Skip to content

Commit

Permalink
include text and better lineno info for better exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
newville committed Jan 19, 2025
1 parent 6970d89 commit 8e0700e
Showing 1 changed file with 28 additions and 14 deletions.
42 changes: 28 additions & 14 deletions asteval/astutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,10 @@ def get_field(self, field_name, args, kwargs):
else:
obj = obj[i]
return obj, first

def safe_format(_string, raise_exc, node, *args, **kwargs):
formatter = SafeFormatter(raise_exc, node)
return formatter.vformat(_string, args, kwargs)
return formatter.vformat(_string, args, kwargs)

def valid_symbol_name(name):
"""Determine whether the input symbol name is a valid name.
Expand Down Expand Up @@ -364,13 +364,24 @@ def __repr__(self):

class ExceptionHolder:
"""Basic exception handler."""
def __init__(self, node, exc=None, msg='', expr=None, lineno=None):
def __init__(self, node, exc=None, msg='', expr=None,
text=None, lineno=None):
"""TODO: docstring in public method."""
self.node = node
self.expr = expr
self.msg = msg
self.exc = exc
self.text = text
self.lineno = lineno
self.end_lineno = lineno
self.col_offset = 0
if lineno is None:
try:
self.lineno = node.lineno
self.end_lineno = node.end_lineno
self.col_offset = node.col_offset
except:
pass
self.exc_info = exc_info()
if self.exc is None and self.exc_info[0] is not None:
self.exc = self.exc_info[0]
Expand All @@ -379,22 +390,22 @@ def __init__(self, node, exc=None, msg='', expr=None, lineno=None):

def get_error(self):
"""Retrieve error data."""
col_offset = -1
if self.node is not None:
try:
col_offset = self.node.col_offset
except AttributeError:
pass
try:
exc_name = self.exc.__name__
except AttributeError:
exc_name = str(self.exc)
if exc_name in (None, 'None'):
exc_name = 'UnknownError'

out = [f" {self.expr}"]
if col_offset > 0:
out.append(f" {col_offset*' '}^^^^")
out = []
try:
lines = self.text.split('\n')
line = '\n'.join(lines[self.lineno-1:self.end_lineno])
out.append(f"{line}")
except:
out.append(f"{self.expr}")
if self.col_offset > 0:
out.append(f"{self.col_offset*' '}^^^^")
out.append(f"{exc_name}: {self.msg}")
return (exc_name, '\n'.join(out))

Expand Down Expand Up @@ -546,7 +557,7 @@ class Procedure:
"""

def __init__(self, name, interp, doc=None, lineno=0,
def __init__(self, name, interp, doc=None, lineno=None,
body=None, args=None, kwargs=None,
vararg=None, varkws=None):
"""TODO: docstring in public method."""
Expand All @@ -562,6 +573,7 @@ def __init__(self, name, interp, doc=None, lineno=0,
self.__vararg__ = vararg
self.__varkws__ = varkws
self.lineno = lineno
self.__text__ = ast.unparse(self.__body__)
self.__ininit__ = False

def __setattr__(self, attr, val):
Expand Down Expand Up @@ -703,8 +715,9 @@ def __call__(self, *args, **kwargs):
retval = None

# evaluate script of function
self.__asteval__.code_text.append(self.__text__)
for node in self.__body__:
self.__asteval__.run(node, expr='<>', lineno=self.lineno)
self.__asteval__.run(node, lineno=node.lineno)
if len(self.__asteval__.error) > 0:
break
if self.__asteval__.retval is not None:
Expand All @@ -715,6 +728,7 @@ def __call__(self, *args, **kwargs):
break

self.__asteval__.symtable = save_symtable
self.__asteval__.code_text.pop()
self.__asteval__._calldepth -= 1
symlocals = None
return retval

0 comments on commit 8e0700e

Please sign in to comment.