-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Seen in Ruff 0.5.7
In the following code, from __future__ import annotations causes the KW_ONLY to become a string.
The dataclasses module can deal with that, but only if the object isn’t in a if TYPE_CHECKING block.
Ruff supports this for things like ClassVar¹, i.e. if a ClassVar is used in a dataclass, Ruff knows the from typing import ClassVar needs to come out of the if TYPE_CHECKING block. However the same doesn’t seem to be true here.
from __future__ import annotations
from dataclasses import KW_ONLY, dataclass
@dataclass
class Test:
a: int
_: KW_ONLY
b: str¹This is probably the place that should handle KW_ONLY
ruff/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs
Lines 108 to 139 in 82a3e69
| /// Returns `true` if an annotation will be inspected at runtime by the `dataclasses` module. | |
| /// | |
| /// Specifically, detects whether an annotation is to either `dataclasses.InitVar` or | |
| /// `typing.ClassVar` within a `@dataclass` class definition. | |
| /// | |
| /// See: <https://docs.python.org/3/library/dataclasses.html#init-only-variables> | |
| pub(crate) fn is_dataclass_meta_annotation(annotation: &Expr, semantic: &SemanticModel) -> bool { | |
| if !semantic.seen_module(Modules::DATACLASSES) { | |
| return false; | |
| } | |
| // Determine whether the assignment is in a `@dataclass` class definition. | |
| if let ScopeKind::Class(class_def) = semantic.current_scope().kind { | |
| if class_def.decorator_list.iter().any(|decorator| { | |
| semantic | |
| .resolve_qualified_name(map_callable(&decorator.expression)) | |
| .is_some_and(|qualified_name| { | |
| matches!(qualified_name.segments(), ["dataclasses", "dataclass"]) | |
| }) | |
| }) { | |
| // Determine whether the annotation is `typing.ClassVar` or `dataclasses.InitVar`. | |
| return semantic | |
| .resolve_qualified_name(map_subscript(annotation)) | |
| .is_some_and(|qualified_name| { | |
| matches!(qualified_name.segments(), ["dataclasses", "InitVar"]) | |
| || semantic.match_typing_qualified_name(&qualified_name, "ClassVar") | |
| }); | |
| } | |
| } | |
| false | |
| } |
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working