Created
January 15, 2024 04:16
-
-
Save tanbro/7a7cb09c7dbf69d2aa321ce180eb00e6 to your computer and use it in GitHub Desktop.
exec and eval a Python code snippet with return expression, as if it's in a non-arguments function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SnippetFuncExecutor: | |
""" | |
exec and eval a Python code snippet with return expression, as if it's in a non-arguments function | |
""" | |
def __init__( | |
self, | |
*, | |
prefix: Optional[str] = None, | |
optimize: int = -1, | |
cache: Optional[Callable] = None, | |
): | |
self._prefix = prefix if prefix else hex(id(self)) | |
self._optimize = int(optimize) | |
self._make_def = self.make_def if cache is None else cache(self.make_def) | |
def make_def(self, source: str, filename: str, compiling=True): | |
source = dedent(source).strip() | |
name_ = ( | |
f"__SnippetAsFuncExecutor_{self._prefix}_{md5(source.encode()).hexdigest()}" | |
) | |
body = ast.unparse(ast.parse(source)) | |
src_str = f"def {name_}():\n{indent(body, ' ')}" | |
src_code = compile(src_str, filename, "exec") if compiling else None | |
return name_, src_str, src_code | |
def exec( | |
self, | |
source: str, | |
filename: Union[str, Tuple[str, str]] = ("<func_def>", "<func_eval>"), | |
globals_: Optional[Dict[str, Any]] = None, | |
locals_: Optional[Mapping[str, Any]] = None, | |
*, | |
optimize: int = -1, | |
): | |
if isinstance(filename, str): | |
exec_filename = eval_filename = filename | |
else: | |
exec_filename, eval_filename = filename | |
globals_ = globals_ if globals_ is not None else dict() | |
locals_ = locals_ if locals_ is not None else dict() | |
func_name, _, func_code = self._make_def(source, exec_filename) | |
assert func_code is not None | |
exec(func_code, globals_, locals_) | |
return eval( | |
compile(f"{func_name}()", eval_filename, "eval", optimize=optimize), | |
globals_, | |
locals_, | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment