From d2f2544f6e0d4ee6eba96e9cfd3d45badf471b55 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Mon, 3 Apr 2023 18:28:46 +0300 Subject: [PATCH] flake8-pyi: fix PYI015 false positive on assignment of TypeVar & friends (#3861) --- .../test/fixtures/flake8_pyi/PYI015.pyi | 6 +- .../rules/flake8_pyi/rules/simple_defaults.rs | 20 +++++ ..._flake8_pyi__tests__PYI015_PYI015.pyi.snap | 88 +++++++++---------- 3 files changed, 69 insertions(+), 45 deletions(-) diff --git a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI015.pyi b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI015.pyi index 9330b6b6e1..7d893c9146 100644 --- a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI015.pyi +++ b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI015.pyi @@ -1,6 +1,6 @@ import builtins import typing -from typing import TypeAlias, Final +from typing import TypeAlias, Final, NewType, TypeVar, TypeVarTuple, ParamSpec # We shouldn't emit Y015 for simple default values field1: int @@ -26,6 +26,10 @@ field9 = None # Y026 Use typing_extensions.TypeAlias for type aliases, e.g. "fi Field95: TypeAlias = None Field96: TypeAlias = int | None Field97: TypeAlias = None | typing.SupportsInt | builtins.str | float | bool +Field98 = NewType('MyInt', int) +Field99 = TypeVar('Field99') +Field100 = TypeVarTuple('Field100') +Field101 = ParamSpec('Field101') field19 = [1, 2, 3] # Y052 Need type annotation for "field19" field191: list[int] = [1, 2, 3] field20 = (1, 2, 3) # Y052 Need type annotation for "field20" diff --git a/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs b/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs index f04aad113a..a2f97762c3 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs @@ -221,6 +221,23 @@ fn is_valid_default_value_with_annotation( false } +pub fn is_type_var_call(checker: &Checker, expr: &Expr) -> bool { + let ExprKind::Call {func, ..} = &expr.node else { + return false; + }; + checker + .ctx + .resolve_call_path(func) + .map_or(false, |call_path| { + call_path.as_slice() == ["typing", "TypeVar"] + || call_path.as_slice() == ["typing", "TypeVarTuple"] + || call_path.as_slice() == ["typing_extensions", "TypeVarTuple"] + || call_path.as_slice() == ["typing", "NewType"] + || call_path.as_slice() == ["typing", "ParamSpec"] + || call_path.as_slice() == ["typing_extensions", "ParamSpec"] + }) +} + /// PYI011 pub fn typed_argument_simple_defaults(checker: &mut Checker, args: &Arguments) { if !args.defaults.is_empty() { @@ -342,6 +359,9 @@ pub fn assignment_default_in_stub(checker: &mut Checker, value: &Expr, annotatio }) { return; } + if is_type_var_call(checker, value) { + return; + } if !is_valid_default_value_with_annotation(value, checker, true) { let mut diagnostic = Diagnostic::new(AssignmentDefaultInStub, Range::from(value)); diff --git a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI015_PYI015.pyi.snap b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI015_PYI015.pyi.snap index 90222cb269..adb7184ae3 100644 --- a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI015_PYI015.pyi.snap +++ b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI015_PYI015.pyi.snap @@ -8,19 +8,19 @@ expression: diagnostics suggestion: "Replace default value with `...`" fixable: true location: - row: 40 + row: 44 column: 22 end_location: - row: 40 + row: 44 column: 57 fix: edits: - content: "..." location: - row: 40 + row: 44 column: 22 end_location: - row: 40 + row: 44 column: 57 parent: ~ - kind: @@ -29,19 +29,19 @@ expression: diagnostics suggestion: "Replace default value with `...`" fixable: true location: - row: 41 + row: 45 column: 22 end_location: - row: 41 + row: 45 column: 34 fix: edits: - content: "..." location: - row: 41 + row: 45 column: 22 end_location: - row: 41 + row: 45 column: 34 parent: ~ - kind: @@ -50,19 +50,19 @@ expression: diagnostics suggestion: "Replace default value with `...`" fixable: true location: - row: 42 + row: 46 column: 22 end_location: - row: 42 + row: 46 column: 37 fix: edits: - content: "..." location: - row: 42 + row: 46 column: 22 end_location: - row: 42 + row: 46 column: 37 parent: ~ - kind: @@ -71,19 +71,19 @@ expression: diagnostics suggestion: "Replace default value with `...`" fixable: true location: - row: 43 + row: 47 column: 25 end_location: - row: 43 + row: 47 column: 35 fix: edits: - content: "..." location: - row: 43 + row: 47 column: 25 end_location: - row: 43 + row: 47 column: 35 parent: ~ - kind: @@ -92,19 +92,19 @@ expression: diagnostics suggestion: "Replace default value with `...`" fixable: true location: - row: 44 + row: 48 column: 46 end_location: - row: 44 + row: 48 column: 69 fix: edits: - content: "..." location: - row: 44 + row: 48 column: 46 end_location: - row: 44 + row: 48 column: 69 parent: ~ - kind: @@ -113,19 +113,19 @@ expression: diagnostics suggestion: "Replace default value with `...`" fixable: true location: - row: 45 + row: 49 column: 30 end_location: - row: 45 + row: 49 column: 53 fix: edits: - content: "..." location: - row: 45 + row: 49 column: 30 end_location: - row: 45 + row: 49 column: 53 parent: ~ - kind: @@ -134,19 +134,19 @@ expression: diagnostics suggestion: "Replace default value with `...`" fixable: true location: - row: 46 + row: 50 column: 36 end_location: - row: 46 + row: 50 column: 47 fix: edits: - content: "..." location: - row: 46 + row: 50 column: 36 end_location: - row: 46 + row: 50 column: 47 parent: ~ - kind: @@ -155,19 +155,19 @@ expression: diagnostics suggestion: "Replace default value with `...`" fixable: true location: - row: 48 + row: 52 column: 27 end_location: - row: 48 + row: 52 column: 43 fix: edits: - content: "..." location: - row: 48 + row: 52 column: 27 end_location: - row: 48 + row: 52 column: 43 parent: ~ - kind: @@ -176,19 +176,19 @@ expression: diagnostics suggestion: "Replace default value with `...`" fixable: true location: - row: 49 + row: 53 column: 10 end_location: - row: 49 + row: 53 column: 23 fix: edits: - content: "..." location: - row: 49 + row: 53 column: 10 end_location: - row: 49 + row: 53 column: 23 parent: ~ - kind: @@ -197,19 +197,19 @@ expression: diagnostics suggestion: "Replace default value with `...`" fixable: true location: - row: 50 + row: 54 column: 10 end_location: - row: 50 + row: 54 column: 25 fix: edits: - content: "..." location: - row: 50 + row: 54 column: 10 end_location: - row: 50 + row: 54 column: 25 parent: ~ - kind: @@ -218,19 +218,19 @@ expression: diagnostics suggestion: "Replace default value with `...`" fixable: true location: - row: 51 + row: 55 column: 10 end_location: - row: 51 + row: 55 column: 15 fix: edits: - content: "..." location: - row: 51 + row: 55 column: 10 end_location: - row: 51 + row: 55 column: 15 parent: ~