mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:24 +00:00
This commit is contained in:
parent
76d2e56501
commit
f96dfc179f
9 changed files with 3 additions and 135 deletions
|
@ -1,21 +0,0 @@
|
||||||
"""Regression test for #13824.
|
|
||||||
|
|
||||||
Don't report an error when the function being annotated has the
|
|
||||||
`@no_type_check` decorator.
|
|
||||||
|
|
||||||
However, we still want to ignore this annotation on classes. See
|
|
||||||
https://github.com/python/typing/pull/1615/files and the discussion on #14615.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from typing import no_type_check
|
|
||||||
|
|
||||||
|
|
||||||
@no_type_check
|
|
||||||
def f(arg: "this isn't python") -> "this isn't python either":
|
|
||||||
x: "this also isn't python" = 0
|
|
||||||
|
|
||||||
|
|
||||||
@no_type_check
|
|
||||||
class C:
|
|
||||||
def f(arg: "this isn't python") -> "this isn't python either":
|
|
||||||
x: "this also isn't python" = 1
|
|
|
@ -1,21 +0,0 @@
|
||||||
"""Regression test for #13824.
|
|
||||||
|
|
||||||
Don't report an error when the function being annotated has the
|
|
||||||
`@no_type_check` decorator.
|
|
||||||
|
|
||||||
However, we still want to ignore this annotation on classes. See
|
|
||||||
https://github.com/python/typing/pull/1615/files and the discussion on #14615.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import typing
|
|
||||||
|
|
||||||
|
|
||||||
@typing.no_type_check
|
|
||||||
def f(arg: "A") -> "R":
|
|
||||||
x: "A" = 1
|
|
||||||
|
|
||||||
|
|
||||||
@typing.no_type_check
|
|
||||||
class C:
|
|
||||||
def f(self, arg: "B") -> "S":
|
|
||||||
x: "B" = 1
|
|
|
@ -723,12 +723,6 @@ impl<'a> Visitor<'a> for Checker<'a> {
|
||||||
// Visit the decorators and arguments, but avoid the body, which will be
|
// Visit the decorators and arguments, but avoid the body, which will be
|
||||||
// deferred.
|
// deferred.
|
||||||
for decorator in decorator_list {
|
for decorator in decorator_list {
|
||||||
if self
|
|
||||||
.semantic
|
|
||||||
.match_typing_expr(&decorator.expression, "no_type_check")
|
|
||||||
{
|
|
||||||
self.semantic.flags |= SemanticModelFlags::NO_TYPE_CHECK;
|
|
||||||
}
|
|
||||||
self.visit_decorator(decorator);
|
self.visit_decorator(decorator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1897,9 +1891,6 @@ impl<'a> Checker<'a> {
|
||||||
|
|
||||||
/// Visit an [`Expr`], and treat it as a type definition.
|
/// Visit an [`Expr`], and treat it as a type definition.
|
||||||
fn visit_type_definition(&mut self, expr: &'a Expr) {
|
fn visit_type_definition(&mut self, expr: &'a Expr) {
|
||||||
if self.semantic.in_no_type_check() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let snapshot = self.semantic.flags;
|
let snapshot = self.semantic.flags;
|
||||||
self.semantic.flags |= SemanticModelFlags::TYPE_DEFINITION;
|
self.semantic.flags |= SemanticModelFlags::TYPE_DEFINITION;
|
||||||
self.visit_expr(expr);
|
self.visit_expr(expr);
|
||||||
|
|
|
@ -94,8 +94,7 @@ mod tests {
|
||||||
#[test_case(Rule::YieldOutsideFunction, Path::new("F704.py"))]
|
#[test_case(Rule::YieldOutsideFunction, Path::new("F704.py"))]
|
||||||
#[test_case(Rule::ReturnOutsideFunction, Path::new("F706.py"))]
|
#[test_case(Rule::ReturnOutsideFunction, Path::new("F706.py"))]
|
||||||
#[test_case(Rule::DefaultExceptNotLast, Path::new("F707.py"))]
|
#[test_case(Rule::DefaultExceptNotLast, Path::new("F707.py"))]
|
||||||
#[test_case(Rule::ForwardAnnotationSyntaxError, Path::new("F722_0.py"))]
|
#[test_case(Rule::ForwardAnnotationSyntaxError, Path::new("F722.py"))]
|
||||||
#[test_case(Rule::ForwardAnnotationSyntaxError, Path::new("F722_1.py"))]
|
|
||||||
#[test_case(Rule::RedefinedWhileUnused, Path::new("F811_0.py"))]
|
#[test_case(Rule::RedefinedWhileUnused, Path::new("F811_0.py"))]
|
||||||
#[test_case(Rule::RedefinedWhileUnused, Path::new("F811_1.py"))]
|
#[test_case(Rule::RedefinedWhileUnused, Path::new("F811_1.py"))]
|
||||||
#[test_case(Rule::RedefinedWhileUnused, Path::new("F811_2.py"))]
|
#[test_case(Rule::RedefinedWhileUnused, Path::new("F811_2.py"))]
|
||||||
|
@ -160,7 +159,6 @@ mod tests {
|
||||||
#[test_case(Rule::UndefinedName, Path::new("F821_26.pyi"))]
|
#[test_case(Rule::UndefinedName, Path::new("F821_26.pyi"))]
|
||||||
#[test_case(Rule::UndefinedName, Path::new("F821_27.py"))]
|
#[test_case(Rule::UndefinedName, Path::new("F821_27.py"))]
|
||||||
#[test_case(Rule::UndefinedName, Path::new("F821_28.py"))]
|
#[test_case(Rule::UndefinedName, Path::new("F821_28.py"))]
|
||||||
#[test_case(Rule::UndefinedName, Path::new("F821_30.py"))]
|
|
||||||
#[test_case(Rule::UndefinedExport, Path::new("F822_0.py"))]
|
#[test_case(Rule::UndefinedExport, Path::new("F822_0.py"))]
|
||||||
#[test_case(Rule::UndefinedExport, Path::new("F822_0.pyi"))]
|
#[test_case(Rule::UndefinedExport, Path::new("F822_0.pyi"))]
|
||||||
#[test_case(Rule::UndefinedExport, Path::new("F822_1.py"))]
|
#[test_case(Rule::UndefinedExport, Path::new("F822_1.py"))]
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
source: crates/ruff_linter/src/rules/pyflakes/mod.rs
|
source: crates/ruff_linter/src/rules/pyflakes/mod.rs
|
||||||
snapshot_kind: text
|
snapshot_kind: text
|
||||||
---
|
---
|
||||||
F722_0.py:9:12: F722 Syntax error in forward annotation: `///`
|
F722.py:9:12: F722 Syntax error in forward annotation: `///`
|
||||||
|
|
|
|
||||||
9 | def g() -> "///":
|
9 | def g() -> "///":
|
||||||
| ^^^^^ F722
|
| ^^^^^ F722
|
||||||
10 | pass
|
10 | pass
|
||||||
|
|
|
|
||||||
|
|
||||||
F722_0.py:13:4: F722 Syntax error in forward annotation: `List[int]☃`
|
F722.py:13:4: F722 Syntax error in forward annotation: `List[int]☃`
|
||||||
|
|
|
|
||||||
13 | X: """List[int]"""'☃' = []
|
13 | X: """List[int]"""'☃' = []
|
||||||
| ^^^^^^^^^^^^^^^^^^ F722
|
| ^^^^^^^^^^^^^^^^^^ F722
|
|
@ -1,29 +0,0 @@
|
||||||
---
|
|
||||||
source: crates/ruff_linter/src/rules/pyflakes/mod.rs
|
|
||||||
snapshot_kind: text
|
|
||||||
---
|
|
||||||
F722_1.py:20:16: F722 Syntax error in forward annotation: `this isn't python`
|
|
||||||
|
|
|
||||||
18 | @no_type_check
|
|
||||||
19 | class C:
|
|
||||||
20 | def f(arg: "this isn't python") -> "this isn't python either":
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ F722
|
|
||||||
21 | x: "this also isn't python" = 1
|
|
||||||
|
|
|
||||||
|
|
||||||
F722_1.py:20:40: F722 Syntax error in forward annotation: `this isn't python either`
|
|
||||||
|
|
|
||||||
18 | @no_type_check
|
|
||||||
19 | class C:
|
|
||||||
20 | def f(arg: "this isn't python") -> "this isn't python either":
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ F722
|
|
||||||
21 | x: "this also isn't python" = 1
|
|
||||||
|
|
|
||||||
|
|
||||||
F722_1.py:21:12: F722 Syntax error in forward annotation: `this also isn't python`
|
|
||||||
|
|
|
||||||
19 | class C:
|
|
||||||
20 | def f(arg: "this isn't python") -> "this isn't python either":
|
|
||||||
21 | x: "this also isn't python" = 1
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ F722
|
|
||||||
|
|
|
|
@ -1,29 +0,0 @@
|
||||||
---
|
|
||||||
source: crates/ruff_linter/src/rules/pyflakes/mod.rs
|
|
||||||
snapshot_kind: text
|
|
||||||
---
|
|
||||||
F821_30.py:20:23: F821 Undefined name `B`
|
|
||||||
|
|
|
||||||
18 | @typing.no_type_check
|
|
||||||
19 | class C:
|
|
||||||
20 | def f(self, arg: "B") -> "S":
|
|
||||||
| ^ F821
|
|
||||||
21 | x: "B" = 1
|
|
||||||
|
|
|
||||||
|
|
||||||
F821_30.py:20:31: F821 Undefined name `S`
|
|
||||||
|
|
|
||||||
18 | @typing.no_type_check
|
|
||||||
19 | class C:
|
|
||||||
20 | def f(self, arg: "B") -> "S":
|
|
||||||
| ^ F821
|
|
||||||
21 | x: "B" = 1
|
|
||||||
|
|
|
||||||
|
|
||||||
F821_30.py:21:13: F821 Undefined name `B`
|
|
||||||
|
|
|
||||||
19 | class C:
|
|
||||||
20 | def f(self, arg: "B") -> "S":
|
|
||||||
21 | x: "B" = 1
|
|
||||||
| ^ F821
|
|
||||||
|
|
|
|
@ -1717,11 +1717,6 @@ impl<'a> SemanticModel<'a> {
|
||||||
self.flags.intersects(SemanticModelFlags::ANNOTATION)
|
self.flags.intersects(SemanticModelFlags::ANNOTATION)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return `true` if the model is in a `@no_type_check` context.
|
|
||||||
pub const fn in_no_type_check(&self) -> bool {
|
|
||||||
self.flags.intersects(SemanticModelFlags::NO_TYPE_CHECK)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return `true` if the model is in a typing-only type annotation.
|
/// Return `true` if the model is in a typing-only type annotation.
|
||||||
pub const fn in_typing_only_annotation(&self) -> bool {
|
pub const fn in_typing_only_annotation(&self) -> bool {
|
||||||
self.flags
|
self.flags
|
||||||
|
@ -2403,22 +2398,6 @@ bitflags! {
|
||||||
/// [PEP 257]: https://peps.python.org/pep-0257/#what-is-a-docstring
|
/// [PEP 257]: https://peps.python.org/pep-0257/#what-is-a-docstring
|
||||||
const ATTRIBUTE_DOCSTRING = 1 << 25;
|
const ATTRIBUTE_DOCSTRING = 1 << 25;
|
||||||
|
|
||||||
/// The model is in a [no_type_check] context.
|
|
||||||
///
|
|
||||||
/// This is used to skip type checking when the `@no_type_check` decorator is found.
|
|
||||||
///
|
|
||||||
/// For example (adapted from [#13824]):
|
|
||||||
/// ```python
|
|
||||||
/// from typing import no_type_check
|
|
||||||
///
|
|
||||||
/// @no_type_check
|
|
||||||
/// def fn(arg: "A") -> "R":
|
|
||||||
/// pass
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// [no_type_check]: https://docs.python.org/3/library/typing.html#typing.no_type_check
|
|
||||||
/// [#13824]: https://github.com/astral-sh/ruff/issues/13824
|
|
||||||
const NO_TYPE_CHECK = 1 << 26;
|
|
||||||
/// The model is in the value expression of a [PEP 613] explicit type alias.
|
/// The model is in the value expression of a [PEP 613] explicit type alias.
|
||||||
///
|
///
|
||||||
/// For example:
|
/// For example:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue