Skip to content

BUG: with statement crashes when #2090

@Lukasbygmal

Description

@Lukasbygmal

Problem
LocalPythonExecutor crashes when a with statement is used with threading.Lock. The bug is in evaluate_with in local_python_executor.py: it calls exit on the return value of enter instead of on the original context manager object.

Steps to reproduce

  1. install smolagents
  2. run the following python code
from smolagents.local_python_executor import LocalPythonExecutor

executor = LocalPythonExecutor(additional_authorized_imports=["threading"])
result = executor("""
import threading
lock = threading.Lock()
with lock:
    x = 1
x
""")

Error logs

Traceback (most recent call last):
  File ".../smolagents/local_python_executor.py", line 1637, in _execute_code
    result = evaluate_ast(node, state, static_tools, custom_tools, authorized_imports)
  File ".../smolagents/local_python_executor.py", line 204, in _check_return
    result = func(expression, state, static_tools, custom_tools, authorized_imports=authorized_imports)
  File ".../smolagents/local_python_executor.py", line 1552, in evaluate_ast
    return evaluate_with(expression, *common_params)
  File ".../smolagents/local_python_executor.py", line 1262, in evaluate_with
    context.__exit__(None, None, None)
    ^^^^^^^^^^^^^^^^
AttributeError: 'bool' object has no attribute '__exit__'. Did you mean: '__init__'?

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "repro.py", line 28, in <module>
    result = executor("""
    import threading
    ...<3 lines>...
    x
    """)
  File ".../smolagents/local_python_executor.py", line 1742, in __call__
    output, is_final_answer = evaluate_python_code(...)
  File ".../smolagents/local_python_executor.py", line 1661, in evaluate_python_code
    return _execute_code()
  File ".../smolagents/local_python_executor.py", line 311, in wrapper
    result = future.result(timeout=timeout_seconds)
  File ".../concurrent/futures/_base.py", line 449, in result
    return self.__get_result()
  File ".../concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File ".../concurrent/futures/thread.py", line 59, in run
    result = self.fn(*self.args, **self.kwargs)
  File ".../smolagents/local_python_executor.py", line 1653, in _execute_code
    raise InterpreterError(
        f"Code execution failed at line '{ast.get_source_segment(code, node)}' due to: {type(e).__name__}: {e}"
    )
smolagents.local_python_executor.InterpreterError: Code execution failed at line 'with lock:
    x = 1' due to: AttributeError: 'bool' object has no attribute '__exit__'

Expected behavior
with lock: should work identically to lock.acquire() / lock.release(). The Python with statement protocol requires that exit is called on the original context manager, not on the value returned by enter.

Environment:
Please complete the following information:

  • OS: windows 11
  • Python version: 3.13.12
  • Package version:
    Name: smolagents
    Version: 1.24.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions