diff --git a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI011.py b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI011.py index 7c088352f5..d64cd66fcc 100644 --- a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI011.py +++ b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI011.py @@ -1,79 +1,161 @@ +import math +import os +import sys +from math import inf + +import numpy as np + def f12( x, y: str = os.pathsep, # OK -) -> None: - ... - - -def f11(*, x: str = "x") -> None: # OK - ... - - +) -> None: ... +def f11(*, x: str = "x") -> None: ... # OK def f13( - x: list[str] = [ + x: list[str] = [ # OK "foo", "bar", "baz", - ] # OK -) -> None: - ... - - + ] +) -> None: ... def f14( - x: tuple[str, ...] = ( + x: tuple[str, ...] = ( # OK "foo", "bar", "baz", - ) # OK -) -> None: - ... - - + ) +) -> None: ... def f15( - x: set[str] = { + x: set[str] = { # OK "foo", "bar", "baz", - } # OK -) -> None: - ... - - -def f16(x: frozenset[bytes] = frozenset({b"foo", b"bar", b"baz"})) -> None: # OK - ... - - + } +) -> None: ... +def f151(x: dict[int, int] = {1: 2}) -> None: ... # Ok +def f152( + x: dict[ + int, int + ] = { # OK + 1: 2, + **{3: 4}, + } +) -> None: ... +def f153( + x: list[ + int + ] = [ # OK + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + ] +) -> None: ... +def f154( + x: tuple[ + str, tuple[str, ...] + ] = ( # OK + "foo", + ("bar", "baz"), + ) +) -> None: ... +def f141( + x: list[ + int + ] = [ # OK + *range(10) + ], +) -> None: ... +def f142( + x: list[ + int + ] = list( # OK + range(10) + ), +) -> None: ... +def f16( + x: frozenset[ + bytes + ] = frozenset( # OK + {b"foo", b"bar", b"baz"} + ) +) -> None: ... def f17( - x: str = "foo" + "bar", # OK -) -> None: - ... - - + x: str = "foo" # OK + + "bar", +) -> None: ... def f18( - x: str = b"foo" + b"bar", # OK -) -> None: - ... - - + x: str = b"foo" # OK + + b"bar", +) -> None: ... def f19( - x: object = "foo" + 4, # OK -) -> None: - ... - - + x: object = "foo" # OK + + 4, +) -> None: ... def f20( - x: int = 5 + 5, # OK -) -> None: - ... - - + x: int = 5 + + 5, # OK +) -> None: ... def f21( - x: complex = 3j - 3j, # OK -) -> None: - ... - - + x: complex = 3j + - 3j, # OK +) -> None: ... def f22( - x: complex = -42.5j + 4.3j, # OK -) -> None: - ... + x: complex = -42.5j # OK + + 4.3j, +) -> None: ... +def f23( + x: bool = True, # OK +) -> None: ... +def f24( + x: float = 3.14, # OK +) -> None: ... +def f25( + x: float = -3.14, # OK +) -> None: ... +def f26( + x: complex = -3.14j, # OK +) -> None: ... +def f27( + x: complex = -3 - 3.14j, # OK +) -> None: ... +def f28( + x: float = math.tau, # OK +) -> None: ... +def f29( + x: float = math.inf, # OK +) -> None: ... +def f30( + x: float = -math.inf, # OK +) -> None: ... +def f31( + x: float = inf, # OK +) -> None: ... +def f32( + x: float = np.inf, # OK +) -> None: ... +def f33( + x: float = math.nan, # OK +) -> None: ... +def f34( + x: float = -math.nan, # OK +) -> None: ... +def f35( + x: complex = math.inf # OK + + 1j, +) -> None: ... +def f36( + *, + x: str = sys.version, # OK +) -> None: ... +def f37( + *, + x: str = "" # OK + + "", +) -> None: ... diff --git a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI011.pyi b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI011.pyi index 1a3c7b3c61..0db3a42c4b 100644 --- a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI011.pyi +++ b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI011.pyi @@ -11,32 +11,74 @@ def f12( ) -> None: ... def f11(*, x: str = "x") -> None: ... # OK def f13( - x: list[ - str - ] = [ # Error PYI011 Only simple default values allowed for typed arguments + x: list[str] = [ # OK "foo", "bar", "baz", ] ) -> None: ... def f14( - x: tuple[ - str, ... - ] = ( # Error PYI011 Only simple default values allowed for typed arguments + x: tuple[str, ...] = ( # OK "foo", "bar", "baz", ) ) -> None: ... def f15( - x: set[ - str - ] = { # Error PYI011 Only simple default values allowed for typed arguments + x: set[str] = { # OK "foo", "bar", "baz", } ) -> None: ... +def f151(x: dict[int, int] = {1: 2}) -> None: ... # Ok +def f152( + x: dict[ + int, int + ] = { # Error PYI011 Only simple default values allowed for typed arguments + 1: 2, + **{3: 4}, + } +) -> None: ... +def f153( + x: list[ + int + ] = [ # Error PYI011 Only simple default values allowed for typed arguments + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + ] +) -> None: ... +def f154( + x: tuple[ + str, tuple[str, ...] + ] = ( # Error PYI011 Only simple default values allowed for typed arguments + "foo", + ("bar", "baz"), + ) +) -> None: ... +def f141( + x: list[ + int + ] = [ # Error PYI011 Only simple default values allowed for typed arguments + *range(10) + ], +) -> None: ... +def f142( + x: list[ + int + ] = list( # Error PYI011 Only simple default values allowed for typed arguments + range(10) + ), +) -> None: ... def f16( x: frozenset[ bytes @@ -109,8 +151,11 @@ def f35( + 1j, ) -> None: ... def f36( - *, x: str = sys.version, # OK + *, + x: str = sys.version, # OK ) -> None: ... def f37( - *, x: str = "" + "", # Error PYI011 Only simple default values allowed for typed arguments + *, + x: str = "" # Error PYI011 Only simple default values allowed for typed arguments + + "", ) -> None: ... diff --git a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI014.py b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI014.py index e47f0a365c..dc7da4c275 100644 --- a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI014.py +++ b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI014.py @@ -39,6 +39,58 @@ def f15( ... +def f151(x={1: 2}) -> None: # Ok + ... + + +def f152( + x={ # OK + 1: 2, + **{3: 4}, + } +) -> None: + ... + + +def f153( + x=[ # OK + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + ] +) -> None: + ... + + +def f154( + x=( # OK + "foo", + ("bar", "baz"), + ) +) -> None: + ... + + +def f141( + x=[*range(10)], # OK +) -> None: + ... + + +def f142( + x=list(range(10)), # OK +) -> None: + ... + + def f16(x=frozenset({b"foo", b"bar", b"baz"})) -> None: ... # OK diff --git a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI014.pyi b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI014.pyi index 1aed3543ef..ce736ba55a 100644 --- a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI014.pyi +++ b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI014.pyi @@ -4,26 +4,60 @@ def f12( ) -> None: ... def f11(*, x="x") -> None: ... # OK def f13( - x=[ # Error PYI014 + x=[ # OK "foo", "bar", "baz", ] ) -> None: ... def f14( - x=( # Error PYI014 + x=( # OK "foo", "bar", "baz", ) ) -> None: ... def f15( - x={ # Error PYI014 + x={ # OK "foo", "bar", "baz", } ) -> None: ... +def f151(x={1: 2}) -> None: ... +def f152( + x={ # Error PYI014 + 1: 2, + **{3: 4}, + } +) -> None: ... +def f153( + x=[ # Error PYI014 + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + ] +) -> None: ... +def f154( + x=( # Error PYI014 + "foo", + ("bar", "baz"), + ) +) -> None: ... +def f141( + x=[*range(10)], # Error PYI014 +) -> None: ... +def f142( + x=list(range(10)), # Error PYI014 +) -> None: ... def f16(x=frozenset({b"foo", b"bar", b"baz"})) -> None: ... # Error PYI014 def f17( x="foo" + "bar", # Error PYI014 @@ -44,5 +78,5 @@ def f22( x=-42.5j + 4.3j, # Error PYI014 ) -> None: ... def f23( - x=True, # OK + x=True, # OK ) -> None: ... 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 3d534b3781..126c8ee913 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs @@ -58,8 +58,28 @@ const ALLOWED_ATTRIBUTES_IN_DEFAULTS: &[&[&str]] = &[ &["sys", "winver"], ]; -fn is_valid_default_value_with_annotation(default: &Expr, checker: &Checker) -> bool { +fn is_valid_default_value_with_annotation( + default: &Expr, + checker: &Checker, + allow_container: bool, +) -> bool { match &default.node { + ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } | ExprKind::Set { elts, .. } => { + return allow_container + && elts.len() <= 10 + && elts + .iter() + .all(|e| is_valid_default_value_with_annotation(e, checker, false)); + } + ExprKind::Dict { keys, values, .. } => { + return allow_container + && keys.len() <= 10 + && keys.iter().zip(values).all(|(k, v)| { + k.as_ref().map_or(false, |k| { + is_valid_default_value_with_annotation(k, checker, false) + }) && is_valid_default_value_with_annotation(v, checker, false) + }); + } ExprKind::Constant { value: Constant::Ellipsis | Constant::None, .. @@ -192,7 +212,7 @@ pub fn typed_argument_simple_defaults(checker: &mut Checker, args: &Arguments) { .and_then(|i| args.defaults.get(i)) { if arg.node.annotation.is_some() { - if !is_valid_default_value_with_annotation(default, checker) { + if !is_valid_default_value_with_annotation(default, checker, true) { let mut diagnostic = Diagnostic::new(TypedArgumentDefaultInStub, Range::from(default)); @@ -219,7 +239,7 @@ pub fn typed_argument_simple_defaults(checker: &mut Checker, args: &Arguments) { .and_then(|i| args.kw_defaults.get(i)) { if kwarg.node.annotation.is_some() { - if !is_valid_default_value_with_annotation(default, checker) { + if !is_valid_default_value_with_annotation(default, checker, true) { let mut diagnostic = Diagnostic::new(TypedArgumentDefaultInStub, Range::from(default)); @@ -249,7 +269,7 @@ pub fn argument_simple_defaults(checker: &mut Checker, args: &Arguments) { .and_then(|i| args.defaults.get(i)) { if arg.node.annotation.is_none() { - if !is_valid_default_value_with_annotation(default, checker) { + if !is_valid_default_value_with_annotation(default, checker, true) { checker .diagnostics .push(Diagnostic::new(ArgumentDefaultInStub, Range::from(default))); @@ -267,7 +287,7 @@ pub fn argument_simple_defaults(checker: &mut Checker, args: &Arguments) { .and_then(|i| args.kw_defaults.get(i)) { if kwarg.node.annotation.is_none() { - if !is_valid_default_value_with_annotation(default, checker) { + if !is_valid_default_value_with_annotation(default, checker, true) { checker .diagnostics .push(Diagnostic::new(ArgumentDefaultInStub, Range::from(default))); diff --git a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI011_PYI011.pyi.snap b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI011_PYI011.pyi.snap index 4b6a94efe3..1231f215da 100644 --- a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI011_PYI011.pyi.snap +++ b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI011_PYI011.pyi.snap @@ -28,78 +28,18 @@ expression: diagnostics suggestion: "Replace default value by `...`" fixable: true location: - row: 16 - column: 8 - end_location: - row: 20 - column: 5 - fix: - content: "..." - location: - row: 16 - column: 8 - end_location: - row: 20 - column: 5 - parent: ~ -- kind: - name: TypedArgumentDefaultInStub - body: Only simple default values allowed for typed arguments - suggestion: "Replace default value by `...`" - fixable: true - location: - row: 25 - column: 8 - end_location: - row: 29 - column: 5 - fix: - content: "..." - location: - row: 25 - column: 8 - end_location: - row: 29 - column: 5 - parent: ~ -- kind: - name: TypedArgumentDefaultInStub - body: Only simple default values allowed for typed arguments - suggestion: "Replace default value by `...`" - fixable: true - location: - row: 34 - column: 8 - end_location: row: 38 - column: 5 - fix: - content: "..." - location: - row: 34 - column: 8 - end_location: - row: 38 - column: 5 - parent: ~ -- kind: - name: TypedArgumentDefaultInStub - body: Only simple default values allowed for typed arguments - suggestion: "Replace default value by `...`" - fixable: true - location: - row: 43 column: 8 end_location: - row: 45 + row: 41 column: 5 fix: content: "..." location: - row: 43 + row: 38 column: 8 end_location: - row: 45 + row: 41 column: 5 parent: ~ - kind: @@ -108,18 +48,118 @@ expression: diagnostics suggestion: "Replace default value by `...`" fixable: true location: - row: 48 + row: 46 + column: 8 + end_location: + row: 58 + column: 5 + fix: + content: "..." + location: + row: 46 + column: 8 + end_location: + row: 58 + column: 5 + parent: ~ +- kind: + name: TypedArgumentDefaultInStub + body: Only simple default values allowed for typed arguments + suggestion: "Replace default value by `...`" + fixable: true + location: + row: 63 + column: 8 + end_location: + row: 66 + column: 5 + fix: + content: "..." + location: + row: 63 + column: 8 + end_location: + row: 66 + column: 5 + parent: ~ +- kind: + name: TypedArgumentDefaultInStub + body: Only simple default values allowed for typed arguments + suggestion: "Replace default value by `...`" + fixable: true + location: + row: 71 + column: 8 + end_location: + row: 73 + column: 5 + fix: + content: "..." + location: + row: 71 + column: 8 + end_location: + row: 73 + column: 5 + parent: ~ +- kind: + name: TypedArgumentDefaultInStub + body: Only simple default values allowed for typed arguments + suggestion: "Replace default value by `...`" + fixable: true + location: + row: 78 + column: 8 + end_location: + row: 80 + column: 5 + fix: + content: "..." + location: + row: 78 + column: 8 + end_location: + row: 80 + column: 5 + parent: ~ +- kind: + name: TypedArgumentDefaultInStub + body: Only simple default values allowed for typed arguments + suggestion: "Replace default value by `...`" + fixable: true + location: + row: 85 + column: 8 + end_location: + row: 87 + column: 5 + fix: + content: "..." + location: + row: 85 + column: 8 + end_location: + row: 87 + column: 5 + parent: ~ +- kind: + name: TypedArgumentDefaultInStub + body: Only simple default values allowed for typed arguments + suggestion: "Replace default value by `...`" + fixable: true + location: + row: 90 column: 13 end_location: - row: 49 + row: 91 column: 11 fix: content: "..." location: - row: 48 + row: 90 column: 13 end_location: - row: 49 + row: 91 column: 11 parent: ~ - kind: @@ -128,18 +168,18 @@ expression: diagnostics suggestion: "Replace default value by `...`" fixable: true location: - row: 52 + row: 94 column: 13 end_location: - row: 53 + row: 95 column: 12 fix: content: "..." location: - row: 52 + row: 94 column: 13 end_location: - row: 53 + row: 95 column: 12 parent: ~ - kind: @@ -148,18 +188,18 @@ expression: diagnostics suggestion: "Replace default value by `...`" fixable: true location: - row: 56 + row: 98 column: 16 end_location: - row: 57 + row: 99 column: 7 fix: content: "..." location: - row: 56 + row: 98 column: 16 end_location: - row: 57 + row: 99 column: 7 parent: ~ - kind: @@ -168,18 +208,18 @@ expression: diagnostics suggestion: "Replace default value by `...`" fixable: true location: - row: 60 + row: 102 column: 13 end_location: - row: 61 + row: 103 column: 7 fix: content: "..." location: - row: 60 + row: 102 column: 13 end_location: - row: 61 + row: 103 column: 7 parent: ~ - kind: @@ -188,18 +228,18 @@ expression: diagnostics suggestion: "Replace default value by `...`" fixable: true location: - row: 64 + row: 106 column: 17 end_location: - row: 65 + row: 107 column: 8 fix: content: "..." location: - row: 64 + row: 106 column: 17 end_location: - row: 65 + row: 107 column: 8 parent: ~ - kind: @@ -208,18 +248,18 @@ expression: diagnostics suggestion: "Replace default value by `...`" fixable: true location: - row: 68 + row: 110 column: 17 end_location: - row: 69 + row: 111 column: 10 fix: content: "..." location: - row: 68 + row: 110 column: 17 end_location: - row: 69 + row: 111 column: 10 parent: ~ - kind: @@ -228,18 +268,18 @@ expression: diagnostics suggestion: "Replace default value by `...`" fixable: true location: - row: 96 + row: 138 column: 15 end_location: - row: 96 + row: 138 column: 18 fix: content: "..." location: - row: 96 + row: 138 column: 15 end_location: - row: 96 + row: 138 column: 18 parent: ~ - kind: @@ -248,18 +288,18 @@ expression: diagnostics suggestion: "Replace default value by `...`" fixable: true location: - row: 99 + row: 141 column: 15 end_location: - row: 99 + row: 141 column: 21 fix: content: "..." location: - row: 99 + row: 141 column: 15 end_location: - row: 99 + row: 141 column: 21 parent: ~ - kind: @@ -268,18 +308,18 @@ expression: diagnostics suggestion: "Replace default value by `...`" fixable: true location: - row: 105 + row: 147 column: 15 end_location: - row: 105 + row: 147 column: 24 fix: content: "..." location: - row: 105 + row: 147 column: 15 end_location: - row: 105 + row: 147 column: 24 parent: ~ - kind: @@ -288,18 +328,18 @@ expression: diagnostics suggestion: "Replace default value by `...`" fixable: true location: - row: 108 + row: 150 column: 17 end_location: - row: 109 + row: 151 column: 8 fix: content: "..." location: - row: 108 + row: 150 column: 17 end_location: - row: 109 + row: 151 column: 8 parent: ~ - kind: @@ -308,18 +348,18 @@ expression: diagnostics suggestion: "Replace default value by `...`" fixable: true location: - row: 115 - column: 16 + row: 159 + column: 13 end_location: - row: 115 - column: 23 + row: 160 + column: 8 fix: content: "..." location: - row: 115 - column: 16 + row: 159 + column: 13 end_location: - row: 115 - column: 23 + row: 160 + column: 8 parent: ~ diff --git a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI014_PYI014.pyi.snap b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI014_PYI014.pyi.snap index adbf6d1c85..5d2d13022a 100644 --- a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI014_PYI014.pyi.snap +++ b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI014_PYI014.pyi.snap @@ -15,58 +15,6 @@ expression: diagnostics column: 16 fix: ~ parent: ~ -- kind: - name: ArgumentDefaultInStub - body: Only simple default values allowed for arguments - suggestion: ~ - fixable: false - location: - row: 7 - column: 6 - end_location: - row: 11 - column: 5 - fix: ~ - parent: ~ -- kind: - name: ArgumentDefaultInStub - body: Only simple default values allowed for arguments - suggestion: ~ - fixable: false - location: - row: 14 - column: 6 - end_location: - row: 18 - column: 5 - fix: ~ - parent: ~ -- kind: - name: ArgumentDefaultInStub - body: Only simple default values allowed for arguments - suggestion: ~ - fixable: false - location: - row: 21 - column: 6 - end_location: - row: 25 - column: 5 - fix: ~ - parent: ~ -- kind: - name: ArgumentDefaultInStub - body: Only simple default values allowed for arguments - suggestion: ~ - fixable: false - location: - row: 27 - column: 10 - end_location: - row: 27 - column: 45 - fix: ~ - parent: ~ - kind: name: ArgumentDefaultInStub body: Only simple default values allowed for arguments @@ -76,8 +24,8 @@ expression: diagnostics row: 29 column: 6 end_location: - row: 29 - column: 19 + row: 32 + column: 5 fix: ~ parent: ~ - kind: @@ -86,10 +34,49 @@ expression: diagnostics suggestion: ~ fixable: false location: - row: 32 + row: 35 column: 6 end_location: - row: 32 + row: 47 + column: 5 + fix: ~ + parent: ~ +- kind: + name: ArgumentDefaultInStub + body: Only simple default values allowed for arguments + suggestion: ~ + fixable: false + location: + row: 50 + column: 6 + end_location: + row: 53 + column: 5 + fix: ~ + parent: ~ +- kind: + name: ArgumentDefaultInStub + body: Only simple default values allowed for arguments + suggestion: ~ + fixable: false + location: + row: 56 + column: 6 + end_location: + row: 56 + column: 18 + fix: ~ + parent: ~ +- kind: + name: ArgumentDefaultInStub + body: Only simple default values allowed for arguments + suggestion: ~ + fixable: false + location: + row: 59 + column: 6 + end_location: + row: 59 column: 21 fix: ~ parent: ~ @@ -99,10 +86,49 @@ expression: diagnostics suggestion: ~ fixable: false location: - row: 35 + row: 61 + column: 10 + end_location: + row: 61 + column: 45 + fix: ~ + parent: ~ +- kind: + name: ArgumentDefaultInStub + body: Only simple default values allowed for arguments + suggestion: ~ + fixable: false + location: + row: 63 column: 6 end_location: - row: 35 + row: 63 + column: 19 + fix: ~ + parent: ~ +- kind: + name: ArgumentDefaultInStub + body: Only simple default values allowed for arguments + suggestion: ~ + fixable: false + location: + row: 66 + column: 6 + end_location: + row: 66 + column: 21 + fix: ~ + parent: ~ +- kind: + name: ArgumentDefaultInStub + body: Only simple default values allowed for arguments + suggestion: ~ + fixable: false + location: + row: 69 + column: 6 + end_location: + row: 69 column: 15 fix: ~ parent: ~ @@ -112,10 +138,10 @@ expression: diagnostics suggestion: ~ fixable: false location: - row: 38 + row: 72 column: 6 end_location: - row: 38 + row: 72 column: 11 fix: ~ parent: ~ @@ -125,10 +151,10 @@ expression: diagnostics suggestion: ~ fixable: false location: - row: 41 + row: 75 column: 6 end_location: - row: 41 + row: 75 column: 13 fix: ~ parent: ~ @@ -138,10 +164,10 @@ expression: diagnostics suggestion: ~ fixable: false location: - row: 44 + row: 78 column: 6 end_location: - row: 44 + row: 78 column: 19 fix: ~ parent: ~