def assign_to_target(self, target: AssignmentTarget, rvalue: Expression, rvalue_type: RType, needs_box: bool) -> Register: rvalue_type = rvalue_type or self.node_type(rvalue) if isinstance(target, AssignmentTargetRegister): if needs_box: unboxed = self.accept(rvalue) return self.box(unboxed, rvalue_type, target=target.register) else: return self.accept(rvalue, target=target.register) elif isinstance(target, AssignmentTargetAttr): rvalue_reg = self.accept(rvalue) if needs_box: rvalue_reg = self.box(rvalue_reg, rvalue_type) self.add( SetAttr(target.obj_reg, target.attr, rvalue_reg, target.obj_type)) return INVALID_REGISTER elif isinstance(target, AssignmentTargetIndex): item_reg = self.accept(rvalue) boxed_item_reg = self.box(item_reg, rvalue_type) if isinstance(target.rtype, ListRType): op = PrimitiveOp.LIST_SET elif isinstance(target.rtype, DictRType): op = PrimitiveOp.DICT_SET else: assert False, target.rtype self.add( PrimitiveOp(None, op, target.base_reg, target.index_reg, boxed_item_reg)) return INVALID_REGISTER assert False, 'Unsupported assignment target'
def test_set_attr(self) -> None: self.assert_emit( SetAttr(self.r, 'y', self.m, 1), "cpy_r_r0 = native_A_sety((AObject *)cpy_r_r, cpy_r_m); /* y */")
def generate_attr_defaults(self, cdef: ClassDef) -> None: """Generate an initialization method for default attr values (from class vars)""" cls = self.mapper.type_to_ir[cdef.info] if cls.builtin_base: return # Pull out all assignments in classes in the mro so we can initialize them # TODO: Support nested statements default_assignments = [] for info in reversed(cdef.info.mro): if info not in self.mapper.type_to_ir: continue for stmt in info.defn.defs.body: if (isinstance(stmt, AssignmentStmt) and isinstance(stmt.lvalues[0], NameExpr) and not is_class_var(stmt.lvalues[0]) and not isinstance(stmt.rvalue, TempNode)): if stmt.lvalues[0].name == '__slots__': continue # Skip type annotated assignments in dataclasses if is_dataclass(cdef) and stmt.type: continue default_assignments.append(stmt) if not default_assignments: return self.builder.enter() self.builder.ret_types[-1] = bool_rprimitive rt_args = (RuntimeArg(SELF_NAME, RInstance(cls)),) self_var = self.builder.read(add_self_to_env(self.builder.environment, cls), -1) for stmt in default_assignments: lvalue = stmt.lvalues[0] assert isinstance(lvalue, NameExpr) if not stmt.is_final_def and not is_constant(stmt.rvalue): self.builder.warning('Unsupported default attribute value', stmt.rvalue.line) # If the attribute is initialized to None and type isn't optional, # don't initialize it to anything. attr_type = cls.attr_type(lvalue.name) if isinstance(stmt.rvalue, RefExpr) and stmt.rvalue.fullname == 'builtins.None': if (not is_optional_type(attr_type) and not is_object_rprimitive(attr_type) and not is_none_rprimitive(attr_type)): continue val = self.builder.coerce(self.accept(stmt.rvalue), attr_type, stmt.line) self.add(SetAttr(self_var, lvalue.name, val, -1)) self.add(Return(self.primitive_op(true_op, [], -1))) blocks, env, ret_type, _ = self.builder.leave() ir = FuncIR( FuncDecl('__mypyc_defaults_setup', cls.name, self.module_name, FuncSignature(rt_args, ret_type)), blocks, env) self.builder.functions.append(ir) cls.methods[ir.name] = ir
def test_set_attr(self) -> None: ir = ClassIR('A', [('x', BoolRType()), ('y', IntRType())]) rtype = UserRType(ir) self.assert_emit( SetAttr(self.n, 'y', self.m, rtype), """CPY_SET_ATTR(cpy_r_n, 3, cpy_r_m, AObject, CPyTagged);""")
def test_set_attr(self) -> None: self.assert_emit( SetAttr(self.r, 'y', self.m, 1), """cpy_r_r0 = CPY_SET_ATTR(cpy_r_r, &CPyType_A, 3, cpy_r_m, AObject, CPyTagged);""")