Coverage for src\zapy\templating\eval.py: 84%

32 statements  

« prev     ^ index     » next       coverage.py v7.3.4, created at 2023-12-20 14:17 -0500

1import ast 

2 

3from .traceback import annotate_traceback 

4 

5 

6_python_code = """ 

7async def __exec_wrapper(_globs): 

8 globals().update(**_globs) 

9 __placeholder 

10 return locals() 

11""" 

12 

13async def exec_async(custom_code: str, _globals: dict): 

14 parsed_ast = ast.parse(_python_code) 

15 is_placeholder = lambda node: isinstance(node, ast.Expr) and \ 

16 isinstance(node.value, ast.Name) and \ 

17 node.value.id == "__placeholder" 

18 

19 for node in ast.walk(parsed_ast): 

20 if is_placeholder(node): 

21 custom_ast = ast.parse(custom_code) 

22 new_node = custom_ast 

23 node.value = new_node 

24 

25 unparsed = ast.unparse(parsed_ast) 

26 exec(unparsed) 

27 

28 try: 

29 func = locals()['__exec_wrapper'] 

30 new_locals = await func(_globals) 

31 except BaseException as e: 

32 annotate_traceback(e, unparsed, location='exec_async') 

33 raise 

34 

35 _globals.update(new_locals) 

36 

37 

38def sync_exec(custom_code: str, _globals: dict): 

39 try: 

40 return exec(custom_code, _globals) 

41 except BaseException as e: 

42 annotate_traceback(e, custom_code, location='sync_exec') 

43 raise 

44 

45def sync_eval(custom_code: str, _globals: dict): 

46 try: 

47 return eval(custom_code, _globals) 

48 except BaseException as e: 

49 annotate_traceback(e, custom_code, location='sync_eval') 

50 raise