Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src/smolagents/local_python_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import math
import re
from abc import ABC, abstractmethod
from collections import ChainMap
from collections.abc import Callable, Generator, Mapping
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import TimeoutError as FuturesTimeoutError
Expand Down Expand Up @@ -594,12 +595,14 @@ def evaluate_class_def(
raise InterpreterError(f"Unsupported AnnAssign target in class body: {type(target).__name__}")
elif isinstance(stmt, ast.Assign):
value = evaluate_ast(stmt.value, state, static_tools, custom_tools, authorized_imports)
# Class-body scoping: names defined earlier in the body take
# precedence, then enclosing scopes — as in native Python.
# Reuse set_value so class bodies support the same targets as
# regular assignments (Name, Attribute, Tuple unpacking, Subscript);
# writes always land in class_dict.
class_state = ChainMap(class_dict, state)
for target in stmt.targets:
if isinstance(target, ast.Name):
class_dict[target.id] = value
elif isinstance(target, ast.Attribute):
obj = evaluate_ast(target.value, class_dict, static_tools, custom_tools, authorized_imports)
setattr(obj, target.attr, value)
set_value(target, value, class_state, static_tools, custom_tools, authorized_imports)
elif isinstance(stmt, ast.Pass):
pass
elif (
Expand Down
19 changes: 19 additions & 0 deletions tests/test_local_python_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,25 @@ class TestClass:
assert state["TestClass"].data.attr1 == "value1"
assert state["TestClass"].data.attr2 == "value2"

def test_evaluate_class_def_with_assign_tuple_and_subscript_targets(self):
"""
Test evaluate_class_def function when stmt is an instance of ast.Assign with ast.Tuple or ast.Subscript targets.
"""
code = dedent("""
table = {"value": 2}
class Settings:
lower, upper = (2, 7)
table["value"] = 7
registry = {}
registry["n"] = 9
result = (Settings.lower, Settings.upper, table["value"], Settings.registry["n"])
""")

state = {}
result, _ = evaluate_python_code(code, BASE_PYTHON_TOOLS, state=state)

assert result == (2, 7, 7, 9)

def test_evaluate_constant(self):
code = "x = 3"
state = {}
Expand Down