(
class_def: ast.ClassDef,
state: dict[str, Any],
static_tools: dict[str, Callable],
custom_tools: dict[str, Callable],
authorized_imports: list[str],
)
| 538 | |
| 539 | |
| 540 | def evaluate_class_def( |
| 541 | class_def: ast.ClassDef, |
| 542 | state: dict[str, Any], |
| 543 | static_tools: dict[str, Callable], |
| 544 | custom_tools: dict[str, Callable], |
| 545 | authorized_imports: list[str], |
| 546 | ) -> type: |
| 547 | class_name = class_def.name |
| 548 | bases = [evaluate_ast(base, state, static_tools, custom_tools, authorized_imports) for base in class_def.bases] |
| 549 | |
| 550 | # Determine the metaclass to use |
| 551 | # If any base class has a custom metaclass, use it |
| 552 | metaclass = type |
| 553 | for base in bases: |
| 554 | base_metaclass = type(base) |
| 555 | if base_metaclass is not type: |
| 556 | metaclass = base_metaclass |
| 557 | break |
| 558 | |
| 559 | # Use __prepare__ if the metaclass provides it (e.g., Enum uses _EnumDict) |
| 560 | if hasattr(metaclass, "__prepare__"): |
| 561 | class_dict = metaclass.__prepare__(class_name, bases) |
| 562 | else: |
| 563 | class_dict = {} |
| 564 | |
| 565 | for stmt in class_def.body: |
| 566 | if isinstance(stmt, ast.FunctionDef): |
| 567 | class_dict[stmt.name] = evaluate_ast(stmt, state, static_tools, custom_tools, authorized_imports) |
| 568 | elif isinstance(stmt, ast.AnnAssign): |
| 569 | if stmt.value: |
| 570 | value = evaluate_ast(stmt.value, state, static_tools, custom_tools, authorized_imports) |
| 571 | target = stmt.target |
| 572 | # Handle target types for annotation |
| 573 | if isinstance(target, ast.Name): |
| 574 | # Simple variable annotation like "x: int" |
| 575 | annotation = evaluate_ast(stmt.annotation, state, static_tools, custom_tools, authorized_imports) |
| 576 | class_dict.setdefault("__annotations__", {})[target.id] = annotation |
| 577 | # Assign value if provided |
| 578 | if stmt.value: |
| 579 | class_dict[target.id] = value |
| 580 | elif isinstance(target, ast.Attribute): |
| 581 | # Attribute annotation like "obj.attr: int" |
| 582 | obj = evaluate_ast(target.value, class_dict, static_tools, custom_tools, authorized_imports) |
| 583 | # If there's a value assignment, set the attribute |
| 584 | if stmt.value: |
| 585 | setattr(obj, target.attr, value) |
| 586 | elif isinstance(target, ast.Subscript): |
| 587 | # Subscript annotation like "dict[key]: int" |
| 588 | container = evaluate_ast(target.value, class_dict, static_tools, custom_tools, authorized_imports) |
| 589 | index = evaluate_ast(target.slice, state, static_tools, custom_tools, authorized_imports) |
| 590 | # If there's a value assignment, set the item |
| 591 | if stmt.value: |
| 592 | container[index] = value |
| 593 | else: |
| 594 | raise InterpreterError(f"Unsupported AnnAssign target in class body: {type(target).__name__}") |
| 595 | elif isinstance(stmt, ast.Assign): |
| 596 | value = evaluate_ast(stmt.value, state, static_tools, custom_tools, authorized_imports) |
| 597 | for target in stmt.targets: |
no test coverage detected
searching dependent graphs…