(
self, lvalue: Lvalue, line: int = -1, *, for_read: bool = False
)
| 704 | assert False, "Unsupported literal value" |
| 705 | |
| 706 | def get_assignment_target( |
| 707 | self, lvalue: Lvalue, line: int = -1, *, for_read: bool = False |
| 708 | ) -> AssignmentTarget: |
| 709 | if line == -1: |
| 710 | line = lvalue.line |
| 711 | if isinstance(lvalue, NameExpr): |
| 712 | # If we are visiting a decorator, then the SymbolNode we really want to be looking at |
| 713 | # is the function that is decorated, not the entire Decorator node itself. |
| 714 | symbol = lvalue.node |
| 715 | if isinstance(symbol, Decorator): |
| 716 | symbol = symbol.func |
| 717 | if symbol is None: |
| 718 | # Semantic analyzer doesn't create ad-hoc Vars for special forms. |
| 719 | assert lvalue.is_special_form |
| 720 | symbol = Var(lvalue.name) |
| 721 | if not for_read and isinstance(symbol, Var) and symbol.is_cls: |
| 722 | self.error("Cannot assign to the first argument of classmethod", line) |
| 723 | if lvalue.kind == LDEF: |
| 724 | if symbol not in self.symtables[-1]: |
| 725 | if isinstance(symbol, Var) and not isinstance(symbol.type, DeletedType): |
| 726 | reg_type = self.type_to_rtype(symbol.type) |
| 727 | else: |
| 728 | reg_type = self.node_type(lvalue) |
| 729 | # If the function is a generator function, then first define a new variable |
| 730 | # in the current function's environment class. Next, define a target that |
| 731 | # refers to the newly defined variable in that environment class. Add the |
| 732 | # target to the table containing class environment variables, as well as the |
| 733 | # current environment. |
| 734 | if self.fn_info.is_generator or self.fn_info.is_coroutine: |
| 735 | return self.add_var_to_env_class( |
| 736 | symbol, |
| 737 | reg_type, |
| 738 | self.fn_info.generator_class, |
| 739 | reassign=False, |
| 740 | prefix=GENERATOR_ATTRIBUTE_PREFIX, |
| 741 | ) |
| 742 | |
| 743 | # Otherwise define a new local variable. |
| 744 | return self.add_local_reg(symbol, reg_type) |
| 745 | else: |
| 746 | # Assign to a previously defined variable. |
| 747 | return self.lookup(symbol) |
| 748 | elif lvalue.kind == GDEF: |
| 749 | globals_dict = self.load_globals_dict() |
| 750 | name = self.load_str(lvalue.name, line) |
| 751 | return AssignmentTargetIndex(globals_dict, name) |
| 752 | else: |
| 753 | assert False, lvalue.kind |
| 754 | elif isinstance(lvalue, IndexExpr): |
| 755 | # Indexed assignment x[y] = e |
| 756 | base = self.accept(lvalue.base) |
| 757 | index = self.accept(lvalue.index) |
| 758 | return AssignmentTargetIndex(base, index) |
| 759 | elif isinstance(lvalue, MemberExpr): |
| 760 | # Attribute assignment x.y = e |
| 761 | can_borrow = self.is_native_attr_ref(lvalue) |
| 762 | obj = self.accept(lvalue.expr, can_borrow=can_borrow) |
| 763 | return AssignmentTargetAttr(obj, lvalue.name, can_borrow=can_borrow) |
no test coverage detected