Evaluate a python expression using the content of the variables stored in a state and only evaluating a given set of functions. This function will recurse through the nodes of the tree provided. Args: code (`str`): The code to evaluate. static_tools (`D
(
code: str,
static_tools: Optional[Dict[str, Callable]] = None,
custom_tools: Optional[Dict[str, Callable]] = None,
state: Optional[Dict[str, Any]] = None,
authorized_imports: List[str] = BASE_BUILTIN_MODULES,
max_print_outputs_length: int = DEFAULT_MAX_LEN_OUTPUT,
timeout_length: float = 10.0,
set_timeout: bool = False,
)
| 1513 | |
| 1514 | |
| 1515 | def evaluate_python_code( |
| 1516 | code: str, |
| 1517 | static_tools: Optional[Dict[str, Callable]] = None, |
| 1518 | custom_tools: Optional[Dict[str, Callable]] = None, |
| 1519 | state: Optional[Dict[str, Any]] = None, |
| 1520 | authorized_imports: List[str] = BASE_BUILTIN_MODULES, |
| 1521 | max_print_outputs_length: int = DEFAULT_MAX_LEN_OUTPUT, |
| 1522 | timeout_length: float = 10.0, |
| 1523 | set_timeout: bool = False, |
| 1524 | ): |
| 1525 | """ |
| 1526 | Evaluate a python expression using the content of the variables stored in a state and only evaluating a given set |
| 1527 | of functions. |
| 1528 | |
| 1529 | This function will recurse through the nodes of the tree provided. |
| 1530 | |
| 1531 | Args: |
| 1532 | code (`str`): |
| 1533 | The code to evaluate. |
| 1534 | static_tools (`Dict[str, Callable]`): |
| 1535 | The functions that may be called during the evaluation. These can also be agents in a multiagent setting. |
| 1536 | These tools cannot be overwritten in the code: any assignment to their name will raise an error. |
| 1537 | custom_tools (`Dict[str, Callable]`): |
| 1538 | The functions that may be called during the evaluation. |
| 1539 | These tools can be overwritten in the code: any assignment to their name will overwrite them. |
| 1540 | state (`Dict[str, Any]`): |
| 1541 | A dictionary mapping variable names to values. The `state` should contain the initial inputs but will be |
| 1542 | updated by this function to contain all variables as they are evaluated. |
| 1543 | The print outputs will be stored in the state under the key "_print_outputs". |
| 1544 | """ |
| 1545 | try: |
| 1546 | expression = ast.parse(code) |
| 1547 | except SyntaxError as e: |
| 1548 | raise InterpreterError( |
| 1549 | f"Code parsing failed on line {e.lineno} due to: {type(e).__name__}\n" |
| 1550 | f"{e.text}" |
| 1551 | f"{' ' * (e.offset or 0)}^\n" |
| 1552 | f"Error: {str(e)}" |
| 1553 | ) |
| 1554 | |
| 1555 | # # Prevent running OOM-sensitive codes |
| 1556 | max_loop_depth = [0] |
| 1557 | count_loop_depth(expression, current_depth=0, max_depth=max_loop_depth) |
| 1558 | if max_loop_depth[0] > 1: |
| 1559 | raise InterpreterError("too many for loops - not running the code to prevent out-of-memory error") |
| 1560 | detect_dangerous_calls(expression, state) |
| 1561 | |
| 1562 | if state is None: |
| 1563 | state = {} |
| 1564 | static_tools = static_tools.copy() if static_tools is not None else {} |
| 1565 | custom_tools = custom_tools if custom_tools is not None else {} |
| 1566 | result = None |
| 1567 | state["_print_outputs"] = PrintContainer() |
| 1568 | state["_operations_count"] = {"counter": 0} |
| 1569 | |
| 1570 | if "final_answer" in static_tools: |
| 1571 | previous_final_answer = static_tools["final_answer"] |
| 1572 |
no test coverage detected