(node: ast.Assign, context: EvaluationContext)
| 593 | |
| 594 | |
| 595 | def _handle_assign(node: ast.Assign, context: EvaluationContext): |
| 596 | value = eval_node(node.value, context) |
| 597 | transient_locals = context.transient_locals |
| 598 | policy = get_policy(context) |
| 599 | class_transients = context.class_transients |
| 600 | for target in node.targets: |
| 601 | if isinstance(target, (ast.Tuple, ast.List)): |
| 602 | # Handle unpacking assignment |
| 603 | values = list(value) |
| 604 | targets = target.elts |
| 605 | starred = [i for i, t in enumerate(targets) if isinstance(t, ast.Starred)] |
| 606 | |
| 607 | # Unified handling: treat no starred as starred at end |
| 608 | star_or_last_idx = starred[0] if starred else len(targets) |
| 609 | |
| 610 | # Before starred |
| 611 | for i in range(star_or_last_idx): |
| 612 | # Check for self.x assignment |
| 613 | if _is_instance_attribute_assignment(targets[i], context): |
| 614 | class_transients[targets[i].attr] = values[i] |
| 615 | else: |
| 616 | transient_locals[targets[i].id] = values[i] |
| 617 | |
| 618 | # Starred if exists |
| 619 | if starred: |
| 620 | end = len(values) - (len(targets) - star_or_last_idx - 1) |
| 621 | if _is_instance_attribute_assignment( |
| 622 | targets[star_or_last_idx], context |
| 623 | ): |
| 624 | class_transients[targets[star_or_last_idx].attr] = values[ |
| 625 | star_or_last_idx:end |
| 626 | ] |
| 627 | else: |
| 628 | transient_locals[targets[star_or_last_idx].value.id] = values[ |
| 629 | star_or_last_idx:end |
| 630 | ] |
| 631 | |
| 632 | # After starred |
| 633 | for i in range(star_or_last_idx + 1, len(targets)): |
| 634 | if _is_instance_attribute_assignment(targets[i], context): |
| 635 | class_transients[targets[i].attr] = values[ |
| 636 | len(values) - (len(targets) - i) |
| 637 | ] |
| 638 | else: |
| 639 | transient_locals[targets[i].id] = values[ |
| 640 | len(values) - (len(targets) - i) |
| 641 | ] |
| 642 | elif isinstance(target, ast.Subscript): |
| 643 | if isinstance(target.value, ast.Name): |
| 644 | name = target.value.id |
| 645 | container = transient_locals.get(name) |
| 646 | if container is None: |
| 647 | container = context.locals.get(name) |
| 648 | if container is None: |
| 649 | container = context.globals.get(name) |
| 650 | if container is None: |
| 651 | raise NameError( |
| 652 | f"{name} not found in locals, globals, nor builtins" |
no test coverage detected
searching dependent graphs…