Treat callables within type definitions as default-non-types (#3329)
This commit is contained in:
23
crates/ruff/resources/test/fixtures/pyflakes/F821_11.py
vendored
Normal file
23
crates/ruff/resources/test/fixtures/pyflakes/F821_11.py
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
"""Test case: strings used within calls within type annotations."""
|
||||
|
||||
from typing import Callable
|
||||
|
||||
import bpy
|
||||
from mypy_extensions import VarArg
|
||||
|
||||
from foo import Bar
|
||||
|
||||
|
||||
class LightShow(bpy.types.Operator):
|
||||
label = "Create Character"
|
||||
name = "lightshow.letter_creation"
|
||||
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH") # OK
|
||||
|
||||
|
||||
def f(x: Callable[[VarArg("os")], None]): # F821
|
||||
pass
|
||||
|
||||
|
||||
f(Callable[["Bar"], None])
|
||||
f(Callable[["Baz"], None])
|
||||
25
crates/ruff/resources/test/fixtures/pyflakes/F821_12.py
vendored
Normal file
25
crates/ruff/resources/test/fixtures/pyflakes/F821_12.py
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
"""Test case: strings used within calls within type annotations."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Callable
|
||||
|
||||
import bpy
|
||||
from mypy_extensions import VarArg
|
||||
|
||||
from foo import Bar
|
||||
|
||||
|
||||
class LightShow(bpy.types.Operator):
|
||||
label = "Create Character"
|
||||
name = "lightshow.letter_creation"
|
||||
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH") # OK
|
||||
|
||||
|
||||
def f(x: Callable[[VarArg("os")], None]): # F821
|
||||
pass
|
||||
|
||||
|
||||
f(Callable[["Bar"], None])
|
||||
f(Callable[["Baz"], None])
|
||||
@@ -3635,9 +3635,16 @@ where
|
||||
Some(Callable::NamedTuple)
|
||||
} else if self.match_typing_call_path(&call_path, "TypedDict") {
|
||||
Some(Callable::TypedDict)
|
||||
} else if ["Arg", "DefaultArg", "NamedArg", "DefaultNamedArg"]
|
||||
.iter()
|
||||
.any(|target| call_path.as_slice() == ["mypy_extensions", target])
|
||||
} else if [
|
||||
"Arg",
|
||||
"DefaultArg",
|
||||
"NamedArg",
|
||||
"DefaultNamedArg",
|
||||
"VarArg",
|
||||
"KwArg",
|
||||
]
|
||||
.iter()
|
||||
.any(|target| call_path.as_slice() == ["mypy_extensions", target])
|
||||
{
|
||||
Some(Callable::MypyExtension)
|
||||
} else {
|
||||
@@ -3760,7 +3767,17 @@ where
|
||||
}
|
||||
}
|
||||
None => {
|
||||
visitor::walk_expr(self, expr);
|
||||
// If we're in a type definition, we need to treat the arguments to any
|
||||
// other callables as non-type definitions (i.e., we don't want to treat
|
||||
// any strings as deferred type definitions).
|
||||
self.visit_expr(func);
|
||||
for arg in args {
|
||||
visit_non_type_definition!(self, arg);
|
||||
}
|
||||
for keyword in keywords {
|
||||
let KeywordData { value, .. } = &keyword.node;
|
||||
visit_non_type_definition!(self, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +104,8 @@ mod tests {
|
||||
#[test_case(Rule::UndefinedName, Path::new("F821_8.pyi"); "F821_8")]
|
||||
#[test_case(Rule::UndefinedName, Path::new("F821_9.py"); "F821_9")]
|
||||
#[test_case(Rule::UndefinedName, Path::new("F821_10.py"); "F821_10")]
|
||||
#[test_case(Rule::UndefinedName, Path::new("F821_11.py"); "F821_11")]
|
||||
#[test_case(Rule::UndefinedName, Path::new("F821_12.py"); "F821_12")]
|
||||
#[test_case(Rule::UndefinedExport, Path::new("F822_0.py"); "F822_0")]
|
||||
#[test_case(Rule::UndefinedExport, Path::new("F822_1.py"); "F822_1")]
|
||||
#[test_case(Rule::UndefinedExport, Path::new("F822_2.py"); "F822_2")]
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/pyflakes/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
UndefinedName:
|
||||
name: os
|
||||
location:
|
||||
row: 18
|
||||
column: 26
|
||||
end_location:
|
||||
row: 18
|
||||
column: 30
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
UndefinedName:
|
||||
name: Baz
|
||||
location:
|
||||
row: 23
|
||||
column: 12
|
||||
end_location:
|
||||
row: 23
|
||||
column: 17
|
||||
fix: ~
|
||||
parent: ~
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/pyflakes/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
UndefinedName:
|
||||
name: os
|
||||
location:
|
||||
row: 20
|
||||
column: 26
|
||||
end_location:
|
||||
row: 20
|
||||
column: 30
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
UndefinedName:
|
||||
name: Baz
|
||||
location:
|
||||
row: 25
|
||||
column: 12
|
||||
end_location:
|
||||
row: 25
|
||||
column: 17
|
||||
fix: ~
|
||||
parent: ~
|
||||
|
||||
@@ -478,21 +478,4 @@ expression: diagnostics
|
||||
row: 67
|
||||
column: 49
|
||||
parent: ~
|
||||
- kind:
|
||||
QuotedAnnotation: ~
|
||||
location:
|
||||
row: 69
|
||||
column: 14
|
||||
end_location:
|
||||
row: 69
|
||||
column: 17
|
||||
fix:
|
||||
content: X
|
||||
location:
|
||||
row: 69
|
||||
column: 14
|
||||
end_location:
|
||||
row: 69
|
||||
column: 17
|
||||
parent: ~
|
||||
|
||||
|
||||
Reference in New Issue
Block a user