@@ -310,10 +310,10 @@ def get_field(self, field_name, args, kwargs):
310310            else :
311311                obj  =  obj [i ]
312312        return  obj , first 
313-      
313+ 
314314def  safe_format (_string , raise_exc , node , * args , ** kwargs ):
315315    formatter  =  SafeFormatter (raise_exc , node )
316-     return  formatter .vformat (_string , args , kwargs )                     
316+     return  formatter .vformat (_string , args , kwargs )
317317
318318def  valid_symbol_name (name ):
319319    """Determine whether the input symbol name is a valid name. 
@@ -364,13 +364,24 @@ def __repr__(self):
364364
365365class  ExceptionHolder :
366366    """Basic exception handler.""" 
367-     def  __init__ (self , node , exc = None , msg = '' , expr = None , lineno = None ):
367+     def  __init__ (self , node , exc = None , msg = '' , expr = None ,
368+                      text = None , lineno = None ):
368369        """TODO: docstring in public method.""" 
369370        self .node  =  node 
370371        self .expr  =  expr 
371372        self .msg  =  msg 
372373        self .exc  =  exc 
374+         self .text  =  text 
373375        self .lineno  =  lineno 
376+         self .end_lineno  =  lineno 
377+         self .col_offset  =  0 
378+         if  lineno  is  None :
379+             try :
380+                 self .lineno  =  node .lineno 
381+                 self .end_lineno  =  node .end_lineno 
382+                 self .col_offset  =  node .col_offset 
383+             except :
384+                 pass 
374385        self .exc_info  =  exc_info ()
375386        if  self .exc  is  None  and  self .exc_info [0 ] is  not   None :
376387            self .exc  =  self .exc_info [0 ]
@@ -379,22 +390,22 @@ def __init__(self, node, exc=None, msg='', expr=None, lineno=None):
379390
380391    def  get_error (self ):
381392        """Retrieve error data.""" 
382-         col_offset  =  - 1 
383-         if  self .node  is  not   None :
384-             try :
385-                 col_offset  =  self .node .col_offset 
386-             except  AttributeError :
387-                 pass 
388393        try :
389394            exc_name  =  self .exc .__name__ 
390395        except  AttributeError :
391396            exc_name  =  str (self .exc )
392397        if  exc_name  in  (None , 'None' ):
393398            exc_name  =  'UnknownError' 
394399
395-         out  =  [f"   { self .expr }  " ]
396-         if  col_offset  >  0 :
397-             out .append (f"    { col_offset * ' ' }  ^^^^" )
400+         out  =  []
401+         try :
402+             lines  =  self .text .split ('\n ' )
403+             line  =  '\n ' .join (lines [self .lineno - 1 :self .end_lineno ])
404+             out .append (f"{ line }  " )
405+         except :
406+             out .append (f"{ self .expr }  " )
407+         if  self .col_offset  >  0 :
408+             out .append (f"{ self .col_offset * ' ' }  ^^^^" )
398409        out .append (f"{ exc_name }  : { self .msg }  " )
399410        return  (exc_name , '\n ' .join (out ))
400411
@@ -546,7 +557,7 @@ class Procedure:
546557
547558    """ 
548559
549-     def  __init__ (self , name , interp , doc = None , lineno = 0 ,
560+     def  __init__ (self , name , interp , doc = None , lineno = None ,
550561                 body = None , args = None , kwargs = None ,
551562                 vararg = None , varkws = None ):
552563        """TODO: docstring in public method.""" 
@@ -562,6 +573,7 @@ def __init__(self, name, interp, doc=None, lineno=0,
562573        self .__vararg__  =  vararg 
563574        self .__varkws__  =  varkws 
564575        self .lineno  =  lineno 
576+         self .__text__  =  ast .unparse (self .__body__ )
565577        self .__ininit__  =  False 
566578
567579    def  __setattr__ (self , attr , val ):
@@ -703,8 +715,9 @@ def __call__(self, *args, **kwargs):
703715        retval  =  None 
704716
705717        # evaluate script of function 
718+         self .__asteval__ .code_text .append (self .__text__ )
706719        for  node  in  self .__body__ :
707-             self .__asteval__ .run (node , expr = '<>' ,  lineno = self .lineno )
720+             self .__asteval__ .run (node , lineno = node .lineno )
708721            if  len (self .__asteval__ .error ) >  0 :
709722                break 
710723            if  self .__asteval__ .retval  is  not   None :
@@ -715,6 +728,7 @@ def __call__(self, *args, **kwargs):
715728                break 
716729
717730        self .__asteval__ .symtable  =  save_symtable 
731+         self .__asteval__ .code_text .pop ()
718732        self .__asteval__ ._calldepth  -=  1 
719733        symlocals  =  None 
720734        return  retval 
0 commit comments