Check if assignment defines a class variable.
(self, s: AssignmentStmt)
| 5209 | return result |
| 5210 | |
| 5211 | def check_classvar(self, s: AssignmentStmt) -> None: |
| 5212 | """Check if assignment defines a class variable.""" |
| 5213 | lvalue = s.lvalues[0] |
| 5214 | if len(s.lvalues) != 1 or not isinstance(lvalue, RefExpr): |
| 5215 | return |
| 5216 | if not s.type or not self.is_classvar(s.type): |
| 5217 | return |
| 5218 | assert isinstance(s.type, UnboundType) |
| 5219 | if self.is_class_scope() and isinstance(lvalue, NameExpr): |
| 5220 | node = lvalue.node |
| 5221 | if isinstance(node, Var): |
| 5222 | node.is_classvar = True |
| 5223 | analyzed = self.anal_type(s.type) |
| 5224 | assert self.type is not None |
| 5225 | if ( |
| 5226 | analyzed is not None |
| 5227 | and self.type.self_type in get_type_vars(analyzed) |
| 5228 | and self.type.defn.type_vars |
| 5229 | ): |
| 5230 | self.fail(message_registry.CLASS_VAR_WITH_GENERIC_SELF, s) |
| 5231 | elif not isinstance(lvalue, MemberExpr) or self.is_self_member_ref(lvalue): |
| 5232 | # In case of member access, report error only when assigning to self |
| 5233 | # Other kinds of member assignments should be already reported |
| 5234 | self.fail_invalid_classvar(lvalue) |
| 5235 | if not s.type.args: |
| 5236 | if isinstance(s.rvalue, TempNode) and s.rvalue.no_rhs: |
| 5237 | if self.options.disallow_any_generics: |
| 5238 | self.fail("ClassVar without type argument becomes Any", s, code=codes.TYPE_ARG) |
| 5239 | return |
| 5240 | s.type = None |
| 5241 | |
| 5242 | def is_classvar(self, typ: Type) -> bool: |
| 5243 | if not isinstance(typ, UnboundType): |
no test coverage detected