Return this attribute as an argument to __init__.
(self, ctx: mypy.plugin.ClassDefContext)
| 133 | self.init_type = init_type |
| 134 | |
| 135 | def argument(self, ctx: mypy.plugin.ClassDefContext) -> Argument: |
| 136 | """Return this attribute as an argument to __init__.""" |
| 137 | assert self.init |
| 138 | init_type: Type | None = None |
| 139 | if self.converter: |
| 140 | if self.converter.init_type: |
| 141 | init_type = self.converter.init_type |
| 142 | if init_type and self.init_type and self.converter.ret_type: |
| 143 | # The converter return type should be the same type as the attribute type. |
| 144 | # Copy type vars from attr type to converter. |
| 145 | converter_vars = get_type_vars(self.converter.ret_type) |
| 146 | init_vars = get_type_vars(self.init_type) |
| 147 | if converter_vars and len(converter_vars) == len(init_vars): |
| 148 | variables = { |
| 149 | binder.id: arg for binder, arg in zip(converter_vars, init_vars) |
| 150 | } |
| 151 | init_type = expand_type(init_type, variables) |
| 152 | else: |
| 153 | ctx.api.fail("Cannot determine __init__ type from converter", self.context) |
| 154 | init_type = AnyType(TypeOfAny.from_error) |
| 155 | else: # There is no converter, the init type is the normal type. |
| 156 | init_type = self.init_type or self.info[self.name].type |
| 157 | |
| 158 | unannotated = False |
| 159 | if init_type is None: |
| 160 | unannotated = True |
| 161 | # Convert type not set to Any. |
| 162 | init_type = AnyType(TypeOfAny.unannotated) |
| 163 | else: |
| 164 | proper_type = get_proper_type(init_type) |
| 165 | if isinstance(proper_type, AnyType): |
| 166 | if proper_type.type_of_any == TypeOfAny.unannotated: |
| 167 | unannotated = True |
| 168 | |
| 169 | if unannotated and ctx.api.options.disallow_untyped_defs: |
| 170 | # This is a compromise. If you don't have a type here then the |
| 171 | # __init__ will be untyped. But since the __init__ is added it's |
| 172 | # pointing at the decorator. So instead we also show the error in the |
| 173 | # assignment, which is where you would fix the issue. |
| 174 | node = self.info[self.name].node |
| 175 | assert node is not None |
| 176 | ctx.api.msg.need_annotation_for_var(node, self.context) |
| 177 | |
| 178 | if self.kw_only: |
| 179 | arg_kind = ARG_NAMED_OPT if self.has_default else ARG_NAMED |
| 180 | else: |
| 181 | arg_kind = ARG_OPT if self.has_default else ARG_POS |
| 182 | |
| 183 | # Attrs removes leading underscores when creating the __init__ arguments. |
| 184 | name = self.alias or self.name.lstrip("_") |
| 185 | return Argument(Var(name, init_type), init_type, None, arg_kind) |
| 186 | |
| 187 | def serialize(self) -> JsonDict: |
| 188 | """Serialize this object so it can be saved and restored.""" |
no test coverage detected