mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-02 18:02:23 +00:00
Treat all typing_extensions
members as typing aliases (#9335)
## Summary Historically, we encoded this list by extracting the `__all__`. I went to update it, but... is there really any value in it? Seems easier to just treat `typing_extensions` as an alias for `typing`. Closes https://github.com/astral-sh/ruff/issues/9334.
This commit is contained in:
parent
772e5d587d
commit
195f7c097a
7 changed files with 33 additions and 72 deletions
5
crates/ruff_linter/resources/test/fixtures/ruff/RUF013_2.py
vendored
Normal file
5
crates/ruff_linter/resources/test/fixtures/ruff/RUF013_2.py
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
from typing_extensions import Optional
|
||||
|
||||
|
||||
def f(arg: Optional[int] = None):
|
||||
pass
|
|
@ -8,6 +8,15 @@ PYI050.py:13:24: PYI050 Prefer `typing.Never` over `NoReturn` for argument annot
|
|||
14 | ...
|
||||
|
|
||||
|
||||
PYI050.py:18:10: PYI050 Prefer `typing.Never` over `NoReturn` for argument annotations
|
||||
|
|
||||
17 | def foo_no_return_typing_extensions(
|
||||
18 | arg: typing_extensions.NoReturn,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI050
|
||||
19 | ):
|
||||
20 | ...
|
||||
|
|
||||
|
||||
PYI050.py:23:44: PYI050 Prefer `typing.Never` over `NoReturn` for argument annotations
|
||||
|
|
||||
23 | def foo_no_return_kwarg(arg: int, *, arg2: NoReturn):
|
||||
|
|
|
@ -11,6 +11,16 @@ PYI050.pyi:6:24: PYI050 Prefer `typing.Never` over `NoReturn` for argument annot
|
|||
8 | arg: typing_extensions.NoReturn,
|
||||
|
|
||||
|
||||
PYI050.pyi:8:10: PYI050 Prefer `typing.Never` over `NoReturn` for argument annotations
|
||||
|
|
||||
6 | def foo_no_return(arg: NoReturn): ... # Error: PYI050
|
||||
7 | def foo_no_return_typing_extensions(
|
||||
8 | arg: typing_extensions.NoReturn,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI050
|
||||
9 | ): ... # Error: PYI050
|
||||
10 | def foo_no_return_kwarg(arg: int, *, arg2: NoReturn): ... # Error: PYI050
|
||||
|
|
||||
|
||||
PYI050.pyi:10:44: PYI050 Prefer `typing.Never` over `NoReturn` for argument annotations
|
||||
|
|
||||
8 | arg: typing_extensions.NoReturn,
|
||||
|
|
|
@ -27,6 +27,7 @@ mod tests {
|
|||
#[test_case(Rule::FunctionCallInDataclassDefaultArgument, Path::new("RUF009.py"))]
|
||||
#[test_case(Rule::ImplicitOptional, Path::new("RUF013_0.py"))]
|
||||
#[test_case(Rule::ImplicitOptional, Path::new("RUF013_1.py"))]
|
||||
#[test_case(Rule::ImplicitOptional, Path::new("RUF013_2.py"))]
|
||||
#[test_case(Rule::MutableClassDefault, Path::new("RUF012.py"))]
|
||||
#[test_case(Rule::MutableDataclassDefault, Path::new("RUF008.py"))]
|
||||
#[test_case(Rule::PairwiseOverZipped, Path::new("RUF007.py"))]
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/mod.rs
|
||||
---
|
||||
|
|
@ -8,7 +8,6 @@ use ruff_python_ast::call_path::{collect_call_path, from_unqualified_name, CallP
|
|||
use ruff_python_ast::helpers::from_relative_import;
|
||||
use ruff_python_ast::{self as ast, Expr, Operator, Stmt};
|
||||
use ruff_python_stdlib::path::is_python_stub_file;
|
||||
use ruff_python_stdlib::typing::is_typing_extension;
|
||||
use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||
|
||||
use crate::binding::{
|
||||
|
@ -175,20 +174,13 @@ impl<'a> SemanticModel<'a> {
|
|||
|
||||
/// Return `true` if the call path is a reference to `typing.${target}`.
|
||||
pub fn match_typing_call_path(&self, call_path: &CallPath, target: &str) -> bool {
|
||||
if call_path.as_slice() == ["typing", target] {
|
||||
if matches!(
|
||||
call_path.as_slice(),
|
||||
["typing" | "_typeshed" | "typing_extensions", member] if *member == target
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if call_path.as_slice() == ["_typeshed", target] {
|
||||
return true;
|
||||
}
|
||||
|
||||
if is_typing_extension(target) {
|
||||
if call_path.as_slice() == ["typing_extensions", target] {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if self.typing_modules.iter().any(|module| {
|
||||
let mut module: CallPath = from_unqualified_name(module);
|
||||
module.push(target);
|
||||
|
|
|
@ -1,63 +1,3 @@
|
|||
/// Returns `true` if a name is a member of Python's `typing_extensions` module.
|
||||
///
|
||||
/// See: <https://pypi.org/project/typing-extensions/>
|
||||
pub fn is_typing_extension(member: &str) -> bool {
|
||||
matches!(
|
||||
member,
|
||||
"Annotated"
|
||||
| "Any"
|
||||
| "AsyncContextManager"
|
||||
| "AsyncGenerator"
|
||||
| "AsyncIterable"
|
||||
| "AsyncIterator"
|
||||
| "Awaitable"
|
||||
| "ChainMap"
|
||||
| "ClassVar"
|
||||
| "Concatenate"
|
||||
| "ContextManager"
|
||||
| "Coroutine"
|
||||
| "Counter"
|
||||
| "DefaultDict"
|
||||
| "Deque"
|
||||
| "Final"
|
||||
| "Literal"
|
||||
| "LiteralString"
|
||||
| "NamedTuple"
|
||||
| "Never"
|
||||
| "NewType"
|
||||
| "NotRequired"
|
||||
| "OrderedDict"
|
||||
| "ParamSpec"
|
||||
| "ParamSpecArgs"
|
||||
| "ParamSpecKwargs"
|
||||
| "Protocol"
|
||||
| "Required"
|
||||
| "Self"
|
||||
| "TYPE_CHECKING"
|
||||
| "Text"
|
||||
| "Type"
|
||||
| "TypeAlias"
|
||||
| "TypeGuard"
|
||||
| "TypeVar"
|
||||
| "TypeVarTuple"
|
||||
| "TypedDict"
|
||||
| "Unpack"
|
||||
| "assert_never"
|
||||
| "assert_type"
|
||||
| "clear_overloads"
|
||||
| "final"
|
||||
| "get_type_hints"
|
||||
| "get_args"
|
||||
| "get_origin"
|
||||
| "get_overloads"
|
||||
| "is_typeddict"
|
||||
| "overload"
|
||||
| "override"
|
||||
| "reveal_type"
|
||||
| "runtime_checkable"
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns `true` if a call path is a generic from the Python standard library (e.g. `list`, which
|
||||
/// can be used as `list[int]`).
|
||||
///
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue