mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 12:29:28 +00:00
Treat type aliases as typing-only expressions (#7968)
## Summary Given `type RecordOrThings = Record | int | str`, the right-hand side won't be evaluated at runtime. Same goes for `Record` in `type RecordCallback[R: Record] = Callable[[R], None]`. This PR modifies the visitation logic to treat them as typing-only. Closes https://github.com/astral-sh/ruff/issues/7966.
This commit is contained in:
parent
8061894af6
commit
b6e75e58c9
4 changed files with 28 additions and 2 deletions
19
crates/ruff_linter/resources/test/fixtures/flake8_type_checking/TCH004_15.py
vendored
Normal file
19
crates/ruff_linter/resources/test/fixtures/flake8_type_checking/TCH004_15.py
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .foo import Record
|
||||||
|
|
||||||
|
type RecordOrThings = Record | int | str
|
||||||
|
type RecordCallback[R: Record] = Callable[[R], None]
|
||||||
|
|
||||||
|
|
||||||
|
def process_record[R: Record](record: R) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class RecordContainer[R: Record]:
|
||||||
|
def add_record(self, record: R) -> None:
|
||||||
|
...
|
|
@ -580,7 +580,9 @@ where
|
||||||
if let Some(type_params) = type_params {
|
if let Some(type_params) = type_params {
|
||||||
self.visit_type_params(type_params);
|
self.visit_type_params(type_params);
|
||||||
}
|
}
|
||||||
self.visit_expr(value);
|
// The value in a `type` alias has annotation semantics, in that it's never
|
||||||
|
// evaluated at runtime.
|
||||||
|
self.visit_annotation(value);
|
||||||
self.semantic.pop_scope();
|
self.semantic.pop_scope();
|
||||||
self.visit_expr(name);
|
self.visit_expr(name);
|
||||||
}
|
}
|
||||||
|
@ -1766,7 +1768,7 @@ impl<'a> Checker<'a> {
|
||||||
bound: Some(bound), ..
|
bound: Some(bound), ..
|
||||||
}) = type_param
|
}) = type_param
|
||||||
{
|
{
|
||||||
self.visit_expr(bound);
|
self.visit_annotation(bound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ mod tests {
|
||||||
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_12.py"))]
|
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_12.py"))]
|
||||||
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_13.py"))]
|
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_13.py"))]
|
||||||
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_14.pyi"))]
|
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_14.pyi"))]
|
||||||
|
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_15.py"))]
|
||||||
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_2.py"))]
|
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_2.py"))]
|
||||||
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_3.py"))]
|
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_3.py"))]
|
||||||
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_4.py"))]
|
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("TCH004_4.py"))]
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_linter/src/rules/flake8_type_checking/mod.rs
|
||||||
|
---
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue