From 2ee4e485da086530d7a8e8652beb57fed76cc8b4 Mon Sep 17 00:00:00 2001 From: Justin Prieto Date: Wed, 31 May 2023 23:50:53 -0400 Subject: [PATCH 1/9] Implement PYI054 --- .../test/fixtures/flake8_pyi/PYI054.py | 20 +++++ .../test/fixtures/flake8_pyi/PYI054.pyi | 20 +++++ crates/ruff/src/checkers/ast/mod.rs | 9 +++ crates/ruff/src/codes.rs | 1 + crates/ruff/src/registry.rs | 1 + crates/ruff/src/rules/flake8_pyi/mod.rs | 2 + .../rules/long_numeric_literals_in_stubs.rs | 30 +++++++ crates/ruff/src/rules/flake8_pyi/rules/mod.rs | 4 + ...__flake8_pyi__tests__PYI054_PYI054.py.snap | 4 + ..._flake8_pyi__tests__PYI054_PYI054.pyi.snap | 79 +++++++++++++++++++ ruff.schema.json | 1 + 11 files changed, 171 insertions(+) create mode 100644 crates/ruff/resources/test/fixtures/flake8_pyi/PYI054.py create mode 100644 crates/ruff/resources/test/fixtures/flake8_pyi/PYI054.pyi create mode 100644 crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stubs.rs create mode 100644 crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI054_PYI054.py.snap create mode 100644 crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI054_PYI054.pyi.snap diff --git a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI054.py b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI054.py new file mode 100644 index 0000000000000..9ea9eec654165 --- /dev/null +++ b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI054.py @@ -0,0 +1,20 @@ +field01: int = 0xFFFFFFFF +field02: int = 0xFFFFFFFFF +field03: int = -0xFFFFFFFF +field04: int = -0xFFFFFFFFF + +field05: int = 1234567890 +field06: int = 12_456_890 +field07: int = 12345678901 +field08: int = -1234567801 +field09: int = -234_567_890 + +field10: float = 123.456789 +field11: float = 123.4567890 +field12: float = -123.456789 +field13: float = -123.567_890 + +field14: complex = 1e1234567j +field15: complex = 1e12345678j +field16: complex = -1e1234567j +field17: complex = 1e123456789j diff --git a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI054.pyi b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI054.pyi new file mode 100644 index 0000000000000..73c9a37347761 --- /dev/null +++ b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI054.pyi @@ -0,0 +1,20 @@ +field01: int = 0xFFFFFFFF +field02: int = 0xFFFFFFFFF # Error: PYI054 +field03: int = -0xFFFFFFFF +field04: int = -0xFFFFFFFFF # Error: PYI054 + +field05: int = 1234567890 +field06: int = 12_456_890 +field07: int = 12345678901 # Error: PYI054 +field08: int = -1234567801 +field09: int = -234_567_890 # Error: PYI054 + +field10: float = 123.456789 +field11: float = 123.4567890 # Error: PYI054 +field12: float = -123.456789 +field13: float = -123.567_890 # Error: PYI054 + +field14: complex = 1e1234567j +field15: complex = 1e12345678j # Error: PYI054 +field16: complex = -1e1234567j +field17: complex = 1e123456789j # Error: PYI054 diff --git a/crates/ruff/src/checkers/ast/mod.rs b/crates/ruff/src/checkers/ast/mod.rs index 8fb77b4e9615a..b3d0dd29b3a23 100644 --- a/crates/ruff/src/checkers/ast/mod.rs +++ b/crates/ruff/src/checkers/ast/mod.rs @@ -3393,6 +3393,15 @@ where } } } + Expr::Constant(ast::ExprConstant { + value: Constant::Int(_) | Constant::Float(_) | Constant::Complex { .. }, + range, + .. + }) => { + if self.is_stub && self.enabled(Rule::LongNumericLiteralsInStub) { + flake8_pyi::rules::long_numeric_literals_in_stubs(self, *range); + } + } Expr::Constant(ast::ExprConstant { value: Constant::Str(value), kind, diff --git a/crates/ruff/src/codes.rs b/crates/ruff/src/codes.rs index c5ee5769e6fc7..e895a4e75a628 100644 --- a/crates/ruff/src/codes.rs +++ b/crates/ruff/src/codes.rs @@ -599,6 +599,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Flake8Pyi, "045") => (RuleGroup::Unspecified, Rule::IterMethodReturnIterable), (Flake8Pyi, "048") => (RuleGroup::Unspecified, Rule::StubBodyMultipleStatements), (Flake8Pyi, "052") => (RuleGroup::Unspecified, Rule::UnannotatedAssignmentInStub), + (Flake8Pyi, "054") => (RuleGroup::Unspecified, Rule::LongNumericLiteralsInStub), // flake8-pytest-style (Flake8PytestStyle, "001") => (RuleGroup::Unspecified, Rule::PytestFixtureIncorrectParenthesesStyle), diff --git a/crates/ruff/src/registry.rs b/crates/ruff/src/registry.rs index 197d0de0a12eb..5565d485fd920 100644 --- a/crates/ruff/src/registry.rs +++ b/crates/ruff/src/registry.rs @@ -522,6 +522,7 @@ ruff_macros::register_rules!( rules::flake8_pyi::rules::NonEmptyStubBody, rules::flake8_pyi::rules::PassInClassBody, rules::flake8_pyi::rules::PassStatementStubBody, + rules::flake8_pyi::rules::LongNumericLiteralsInStub, rules::flake8_pyi::rules::QuotedAnnotationInStub, rules::flake8_pyi::rules::SnakeCaseTypeAlias, rules::flake8_pyi::rules::StubBodyMultipleStatements, diff --git a/crates/ruff/src/rules/flake8_pyi/mod.rs b/crates/ruff/src/rules/flake8_pyi/mod.rs index 5d242bb333411..00212b6fbc288 100644 --- a/crates/ruff/src/rules/flake8_pyi/mod.rs +++ b/crates/ruff/src/rules/flake8_pyi/mod.rs @@ -30,6 +30,8 @@ mod tests { #[test_case(Rule::CollectionsNamedTuple, Path::new("PYI024.pyi"))] #[test_case(Rule::IterMethodReturnIterable, Path::new("PYI045.py"))] #[test_case(Rule::IterMethodReturnIterable, Path::new("PYI045.pyi"))] + #[test_case(Rule::LongNumericLiteralsInStub, Path::new("PYI054.py"))] + #[test_case(Rule::LongNumericLiteralsInStub, Path::new("PYI054.pyi"))] #[test_case(Rule::NonEmptyStubBody, Path::new("PYI010.py"))] #[test_case(Rule::NonEmptyStubBody, Path::new("PYI010.pyi"))] #[test_case(Rule::PassInClassBody, Path::new("PYI012.py"))] diff --git a/crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stubs.rs b/crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stubs.rs new file mode 100644 index 0000000000000..94055a9dc9886 --- /dev/null +++ b/crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stubs.rs @@ -0,0 +1,30 @@ +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_text_size::{TextRange, TextSize}; + +use ruff_macros::{derive_message_formats, violation}; + +use crate::checkers::ast::Checker; + +#[violation] +pub struct LongNumericLiteralsInStub; + +/// ## What it does +/// Checks for numeric literals longer than 10 characters +/// +/// ## Why is this bad? +/// Long hardcoded numeric values are unlikely to be useful for users. Consider replacing them with ellipses. +impl Violation for LongNumericLiteralsInStub { + #[derive_message_formats] + fn message(&self) -> String { + format!("Numeric literals with a string representation longer than ten characters are not permitted") + } +} + +/// PYI054 +pub(crate) fn long_numeric_literals_in_stubs(checker: &mut Checker, range: TextRange) { + if range.len() > TextSize::new(10) { + checker + .diagnostics + .push(Diagnostic::new(LongNumericLiteralsInStub, range)); + } +} diff --git a/crates/ruff/src/rules/flake8_pyi/rules/mod.rs b/crates/ruff/src/rules/flake8_pyi/rules/mod.rs index 2fe699df83808..c0046b0852c91 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/mod.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/mod.rs @@ -11,6 +11,9 @@ pub(crate) use ellipsis_in_non_empty_class_body::{ pub(crate) use iter_method_return_iterable::{ iter_method_return_iterable, IterMethodReturnIterable, }; +pub(crate) use long_numeric_literals_in_stubs::{ + long_numeric_literals_in_stubs, LongNumericLiteralsInStub, +}; pub(crate) use non_empty_stub_body::{non_empty_stub_body, NonEmptyStubBody}; pub(crate) use pass_in_class_body::{pass_in_class_body, PassInClassBody}; pub(crate) use pass_statement_stub_body::{pass_statement_stub_body, PassStatementStubBody}; @@ -39,6 +42,7 @@ mod docstring_in_stubs; mod duplicate_union_member; mod ellipsis_in_non_empty_class_body; mod iter_method_return_iterable; +mod long_numeric_literals_in_stubs; mod non_empty_stub_body; mod pass_in_class_body; mod pass_statement_stub_body; diff --git a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI054_PYI054.py.snap b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI054_PYI054.py.snap new file mode 100644 index 0000000000000..d1aa2e9116558 --- /dev/null +++ b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI054_PYI054.py.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff/src/rules/flake8_pyi/mod.rs +--- + diff --git a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI054_PYI054.pyi.snap b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI054_PYI054.pyi.snap new file mode 100644 index 0000000000000..b663d28f23c08 --- /dev/null +++ b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI054_PYI054.pyi.snap @@ -0,0 +1,79 @@ +--- +source: crates/ruff/src/rules/flake8_pyi/mod.rs +--- +PYI054.pyi:2:16: PYI054 Numeric literals with a string representation longer than ten characters are not permitted + | +2 | field01: int = 0xFFFFFFFF +3 | field02: int = 0xFFFFFFFFF # Error: PYI054 + | ^^^^^^^^^^^ PYI054 +4 | field03: int = -0xFFFFFFFF +5 | field04: int = -0xFFFFFFFFF # Error: PYI054 + | + +PYI054.pyi:4:17: PYI054 Numeric literals with a string representation longer than ten characters are not permitted + | +4 | field02: int = 0xFFFFFFFFF # Error: PYI054 +5 | field03: int = -0xFFFFFFFF +6 | field04: int = -0xFFFFFFFFF # Error: PYI054 + | ^^^^^^^^^^^ PYI054 +7 | +8 | field05: int = 1234567890 + | + +PYI054.pyi:8:16: PYI054 Numeric literals with a string representation longer than ten characters are not permitted + | + 8 | field05: int = 1234567890 + 9 | field06: int = 12_456_890 +10 | field07: int = 12345678901 # Error: PYI054 + | ^^^^^^^^^^^ PYI054 +11 | field08: int = -1234567801 +12 | field09: int = -234_567_890 # Error: PYI054 + | + +PYI054.pyi:10:17: PYI054 Numeric literals with a string representation longer than ten characters are not permitted + | +10 | field07: int = 12345678901 # Error: PYI054 +11 | field08: int = -1234567801 +12 | field09: int = -234_567_890 # Error: PYI054 + | ^^^^^^^^^^^ PYI054 +13 | +14 | field10: float = 123.456789 + | + +PYI054.pyi:13:18: PYI054 Numeric literals with a string representation longer than ten characters are not permitted + | +13 | field10: float = 123.456789 +14 | field11: float = 123.4567890 # Error: PYI054 + | ^^^^^^^^^^^ PYI054 +15 | field12: float = -123.456789 +16 | field13: float = -123.567_890 # Error: PYI054 + | + +PYI054.pyi:15:19: PYI054 Numeric literals with a string representation longer than ten characters are not permitted + | +15 | field11: float = 123.4567890 # Error: PYI054 +16 | field12: float = -123.456789 +17 | field13: float = -123.567_890 # Error: PYI054 + | ^^^^^^^^^^^ PYI054 +18 | +19 | field14: complex = 1e1234567j + | + +PYI054.pyi:18:20: PYI054 Numeric literals with a string representation longer than ten characters are not permitted + | +18 | field14: complex = 1e1234567j +19 | field15: complex = 1e12345678j # Error: PYI054 + | ^^^^^^^^^^^ PYI054 +20 | field16: complex = -1e1234567j +21 | field17: complex = 1e123456789j # Error: PYI054 + | + +PYI054.pyi:20:20: PYI054 Numeric literals with a string representation longer than ten characters are not permitted + | +20 | field15: complex = 1e12345678j # Error: PYI054 +21 | field16: complex = -1e1234567j +22 | field17: complex = 1e123456789j # Error: PYI054 + | ^^^^^^^^^^^^ PYI054 + | + + diff --git a/ruff.schema.json b/ruff.schema.json index bd19906af2b99..af005efdcbdba 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -2220,6 +2220,7 @@ "PYI048", "PYI05", "PYI052", + "PYI054", "Q", "Q0", "Q00", From 618d97dc060f9ec664ac5ad3cc9a7e0cc3b64bb9 Mon Sep 17 00:00:00 2001 From: Justin Prieto Date: Wed, 31 May 2023 23:54:08 -0400 Subject: [PATCH 2/9] remove s --- crates/ruff/src/checkers/ast/mod.rs | 2 +- ...iterals_in_stubs.rs => long_numeric_literals_in_stub.rs} | 2 +- crates/ruff/src/rules/flake8_pyi/rules/mod.rs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) rename crates/ruff/src/rules/flake8_pyi/rules/{long_numeric_literals_in_stubs.rs => long_numeric_literals_in_stub.rs} (90%) diff --git a/crates/ruff/src/checkers/ast/mod.rs b/crates/ruff/src/checkers/ast/mod.rs index b3d0dd29b3a23..6344fc0f268da 100644 --- a/crates/ruff/src/checkers/ast/mod.rs +++ b/crates/ruff/src/checkers/ast/mod.rs @@ -3399,7 +3399,7 @@ where .. }) => { if self.is_stub && self.enabled(Rule::LongNumericLiteralsInStub) { - flake8_pyi::rules::long_numeric_literals_in_stubs(self, *range); + flake8_pyi::rules::long_numeric_literals_in_stub(self, *range); } } Expr::Constant(ast::ExprConstant { diff --git a/crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stubs.rs b/crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stub.rs similarity index 90% rename from crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stubs.rs rename to crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stub.rs index 94055a9dc9886..fd5fe5e353f5d 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stubs.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stub.rs @@ -21,7 +21,7 @@ impl Violation for LongNumericLiteralsInStub { } /// PYI054 -pub(crate) fn long_numeric_literals_in_stubs(checker: &mut Checker, range: TextRange) { +pub(crate) fn long_numeric_literals_in_stub(checker: &mut Checker, range: TextRange) { if range.len() > TextSize::new(10) { checker .diagnostics diff --git a/crates/ruff/src/rules/flake8_pyi/rules/mod.rs b/crates/ruff/src/rules/flake8_pyi/rules/mod.rs index c0046b0852c91..777e26abb1b65 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/mod.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/mod.rs @@ -11,8 +11,8 @@ pub(crate) use ellipsis_in_non_empty_class_body::{ pub(crate) use iter_method_return_iterable::{ iter_method_return_iterable, IterMethodReturnIterable, }; -pub(crate) use long_numeric_literals_in_stubs::{ - long_numeric_literals_in_stubs, LongNumericLiteralsInStub, +pub(crate) use long_numeric_literals_in_stub::{ + long_numeric_literals_in_stub, LongNumericLiteralsInStub, }; pub(crate) use non_empty_stub_body::{non_empty_stub_body, NonEmptyStubBody}; pub(crate) use pass_in_class_body::{pass_in_class_body, PassInClassBody}; @@ -42,7 +42,7 @@ mod docstring_in_stubs; mod duplicate_union_member; mod ellipsis_in_non_empty_class_body; mod iter_method_return_iterable; -mod long_numeric_literals_in_stubs; +mod long_numeric_literals_in_stub; mod non_empty_stub_body; mod pass_in_class_body; mod pass_statement_stub_body; From d70b15eb6c4a185c03b07f873872de46b83d4ede Mon Sep 17 00:00:00 2001 From: Justin Prieto Date: Thu, 1 Jun 2023 00:44:55 -0400 Subject: [PATCH 3/9] Remove check for long numeric literals from PYI015 since it is now handled by PYI054 --- .../rules/flake8_pyi/rules/simple_defaults.rs | 59 +++++++------------ 1 file changed, 20 insertions(+), 39 deletions(-) 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 49b2b7cd1f8d2..89dcd378b8a05 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs @@ -132,55 +132,36 @@ fn is_valid_default_value_with_annotation( value: Constant::Bytes(..), .. }) => return locator.slice(default.range()).len() <= 50, - // Ex) `123`, `True`, `False`, `3.14` + // Ex) `123`, `True`, `False`, `3.14`, `2j` Expr::Constant(ast::ExprConstant { - value: Constant::Int(..) | Constant::Bool(..) | Constant::Float(..), + value: + Constant::Int(..) | Constant::Bool(..) | Constant::Float(..) | Constant::Complex { .. }, .. }) => { - return locator.slice(default.range()).len() <= 10; - } - // Ex) `2j` - Expr::Constant(ast::ExprConstant { - value: Constant::Complex { real, .. }, - .. - }) => { - if *real == 0.0 { - return locator.slice(default.range()).len() <= 10; - } + return true; } Expr::UnaryOp(ast::ExprUnaryOp { op: Unaryop::USub, operand, range: _, }) => { - // Ex) `-1`, `-3.14` - if let Expr::Constant(ast::ExprConstant { - value: Constant::Int(..) | Constant::Float(..), - .. - }) = operand.as_ref() - { - return locator.slice(operand.range()).len() <= 10; - } - // Ex) `-2j` - if let Expr::Constant(ast::ExprConstant { - value: Constant::Complex { real, .. }, - .. - }) = operand.as_ref() - { - if *real == 0.0 { - return locator.slice(operand.range()).len() <= 10; - } - } - // Ex) `-math.inf`, `-math.pi`, etc. - if let Expr::Attribute(_) = operand.as_ref() { - if model.resolve_call_path(operand).map_or(false, |call_path| { - ALLOWED_MATH_ATTRIBUTES_IN_DEFAULTS.iter().any(|target| { - // reject `-math.nan` - call_path.as_slice() == *target && *target != ["math", "nan"] - }) - }) { - return true; + match operand.as_ref() { + Expr::Constant(ast::ExprConstant { + value: Constant::Int(..) | Constant::Float(..) | Constant::Complex { .. }, + .. + }) => return true, + Expr::Attribute(_) => { + // Ex) `-math.inf`, `-math.pi`, etc. + if model.resolve_call_path(operand).map_or(false, |call_path| { + ALLOWED_MATH_ATTRIBUTES_IN_DEFAULTS.iter().any(|target| { + // reject `-math.nan` + call_path.as_slice() == *target && *target != ["math", "nan"] + }) + }) { + return true; + } } + _ => {} } } Expr::BinOp(ast::ExprBinOp { From 67f799ef696c34bfe1b214930f11310bb0066b8c Mon Sep 17 00:00:00 2001 From: Justin Prieto Date: Thu, 1 Jun 2023 00:46:47 -0400 Subject: [PATCH 4/9] fix comments --- crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 89dcd378b8a05..ac3ba81ded7d8 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs @@ -146,12 +146,13 @@ fn is_valid_default_value_with_annotation( range: _, }) => { match operand.as_ref() { + // Ex) `-1`, `-3.14`, `2j` Expr::Constant(ast::ExprConstant { value: Constant::Int(..) | Constant::Float(..) | Constant::Complex { .. }, .. }) => return true, + // Ex) `-math.inf`, `-math.pi`, etc. Expr::Attribute(_) => { - // Ex) `-math.inf`, `-math.pi`, etc. if model.resolve_call_path(operand).map_or(false, |call_path| { ALLOWED_MATH_ATTRIBUTES_IN_DEFAULTS.iter().any(|target| { // reject `-math.nan` From 7d84af7776785aecc8d55142e55513782b52d70d Mon Sep 17 00:00:00 2001 From: Justin Prieto Date: Thu, 1 Jun 2023 00:50:24 -0400 Subject: [PATCH 5/9] update reasoning --- .../rules/long_numeric_literals_in_stub.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stub.rs b/crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stub.rs index fd5fe5e353f5d..3d678e74c7ad3 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stub.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stub.rs @@ -1,6 +1,6 @@ -use ruff_diagnostics::{Diagnostic, Violation}; use ruff_text_size::{TextRange, TextSize}; +use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use crate::checkers::ast::Checker; @@ -12,7 +12,19 @@ pub struct LongNumericLiteralsInStub; /// Checks for numeric literals longer than 10 characters /// /// ## Why is this bad? -/// Long hardcoded numeric values are unlikely to be useful for users. Consider replacing them with ellipses. +/// If a function has a default value where the string representation is greater than 10 +/// characters, it is likely to be an implementation detail or a constant that varies depending on +/// the system you're running on, such as `sys.maxsize`. Consider replacing them with ellipses. +/// +/// ## Example +/// ```python +/// def foo(arg: int = 12345678901) -> None: ... +/// ``` +/// +/// Use instead: +/// ```python +/// def foo(arg: int = ...) -> None: ... +/// ``` impl Violation for LongNumericLiteralsInStub { #[derive_message_formats] fn message(&self) -> String { From 95e32d89cd9e07af9999be3f667d3d2de0c701be Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Thu, 1 Jun 2023 18:52:19 -0400 Subject: [PATCH 6/9] Rename rule --- crates/ruff/src/checkers/ast/mod.rs | 4 ++-- crates/ruff/src/codes.rs | 2 +- crates/ruff/src/registry.rs | 2 +- crates/ruff/src/rules/flake8_pyi/mod.rs | 4 ++-- crates/ruff/src/rules/flake8_pyi/rules/mod.rs | 6 ++---- ...ic_literals_in_stub.rs => numeric_literal_too_long.rs} | 8 ++++---- 6 files changed, 12 insertions(+), 14 deletions(-) rename crates/ruff/src/rules/flake8_pyi/rules/{long_numeric_literals_in_stub.rs => numeric_literal_too_long.rs} (81%) diff --git a/crates/ruff/src/checkers/ast/mod.rs b/crates/ruff/src/checkers/ast/mod.rs index 876642400dff5..3bf8b779a891e 100644 --- a/crates/ruff/src/checkers/ast/mod.rs +++ b/crates/ruff/src/checkers/ast/mod.rs @@ -3415,8 +3415,8 @@ where range, .. }) => { - if self.is_stub && self.enabled(Rule::LongNumericLiteralsInStub) { - flake8_pyi::rules::long_numeric_literals_in_stub(self, *range); + if self.is_stub && self.enabled(Rule::NumericLiteralTooLong) { + flake8_pyi::rules::numeric_literal_too_long(self, *range); } } Expr::Constant(ast::ExprConstant { diff --git a/crates/ruff/src/codes.rs b/crates/ruff/src/codes.rs index 6ae037b005ccc..005cb29796f72 100644 --- a/crates/ruff/src/codes.rs +++ b/crates/ruff/src/codes.rs @@ -601,7 +601,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Flake8Pyi, "045") => (RuleGroup::Unspecified, Rule::IterMethodReturnIterable), (Flake8Pyi, "048") => (RuleGroup::Unspecified, Rule::StubBodyMultipleStatements), (Flake8Pyi, "052") => (RuleGroup::Unspecified, Rule::UnannotatedAssignmentInStub), - (Flake8Pyi, "054") => (RuleGroup::Unspecified, Rule::LongNumericLiteralsInStub), + (Flake8Pyi, "054") => (RuleGroup::Unspecified, Rule::NumericLiteralTooLong), // flake8-pytest-style (Flake8PytestStyle, "001") => (RuleGroup::Unspecified, Rule::PytestFixtureIncorrectParenthesesStyle), diff --git a/crates/ruff/src/registry.rs b/crates/ruff/src/registry.rs index bac10deed512c..651e5ea8f0e32 100644 --- a/crates/ruff/src/registry.rs +++ b/crates/ruff/src/registry.rs @@ -523,7 +523,7 @@ ruff_macros::register_rules!( rules::flake8_pyi::rules::NonEmptyStubBody, rules::flake8_pyi::rules::PassInClassBody, rules::flake8_pyi::rules::PassStatementStubBody, - rules::flake8_pyi::rules::LongNumericLiteralsInStub, + rules::flake8_pyi::rules::NumericLiteralTooLong, rules::flake8_pyi::rules::QuotedAnnotationInStub, rules::flake8_pyi::rules::SnakeCaseTypeAlias, rules::flake8_pyi::rules::StubBodyMultipleStatements, diff --git a/crates/ruff/src/rules/flake8_pyi/mod.rs b/crates/ruff/src/rules/flake8_pyi/mod.rs index 931a59109163c..2f246263d65f7 100644 --- a/crates/ruff/src/rules/flake8_pyi/mod.rs +++ b/crates/ruff/src/rules/flake8_pyi/mod.rs @@ -30,8 +30,8 @@ mod tests { #[test_case(Rule::CollectionsNamedTuple, Path::new("PYI024.pyi"))] #[test_case(Rule::IterMethodReturnIterable, Path::new("PYI045.py"))] #[test_case(Rule::IterMethodReturnIterable, Path::new("PYI045.pyi"))] - #[test_case(Rule::LongNumericLiteralsInStub, Path::new("PYI054.py"))] - #[test_case(Rule::LongNumericLiteralsInStub, Path::new("PYI054.pyi"))] + #[test_case(Rule::NumericLiteralTooLong, Path::new("PYI054.py"))] + #[test_case(Rule::NumericLiteralTooLong, Path::new("PYI054.pyi"))] #[test_case(Rule::NonEmptyStubBody, Path::new("PYI010.py"))] #[test_case(Rule::NonEmptyStubBody, Path::new("PYI010.pyi"))] #[test_case(Rule::PassInClassBody, Path::new("PYI012.py"))] diff --git a/crates/ruff/src/rules/flake8_pyi/rules/mod.rs b/crates/ruff/src/rules/flake8_pyi/rules/mod.rs index 7a7d3152e05cd..9b70edf2af77c 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/mod.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/mod.rs @@ -11,10 +11,8 @@ pub(crate) use ellipsis_in_non_empty_class_body::{ pub(crate) use iter_method_return_iterable::{ iter_method_return_iterable, IterMethodReturnIterable, }; -pub(crate) use long_numeric_literals_in_stub::{ - long_numeric_literals_in_stub, LongNumericLiteralsInStub, -}; pub(crate) use non_empty_stub_body::{non_empty_stub_body, NonEmptyStubBody}; +pub(crate) use numeric_literal_too_long::{numeric_literal_too_long, NumericLiteralTooLong}; pub(crate) use pass_in_class_body::{pass_in_class_body, PassInClassBody}; pub(crate) use pass_statement_stub_body::{pass_statement_stub_body, PassStatementStubBody}; pub(crate) use prefix_type_params::{prefix_type_params, UnprefixedTypeParam}; @@ -45,8 +43,8 @@ mod docstring_in_stubs; mod duplicate_union_member; mod ellipsis_in_non_empty_class_body; mod iter_method_return_iterable; -mod long_numeric_literals_in_stub; mod non_empty_stub_body; +mod numeric_literal_too_long; mod pass_in_class_body; mod pass_statement_stub_body; mod prefix_type_params; diff --git a/crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stub.rs b/crates/ruff/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs similarity index 81% rename from crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stub.rs rename to crates/ruff/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs index 3d678e74c7ad3..8df9a1245b8b8 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/long_numeric_literals_in_stub.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs @@ -6,7 +6,7 @@ use ruff_macros::{derive_message_formats, violation}; use crate::checkers::ast::Checker; #[violation] -pub struct LongNumericLiteralsInStub; +pub struct NumericLiteralTooLong; /// ## What it does /// Checks for numeric literals longer than 10 characters @@ -25,7 +25,7 @@ pub struct LongNumericLiteralsInStub; /// ```python /// def foo(arg: int = ...) -> None: ... /// ``` -impl Violation for LongNumericLiteralsInStub { +impl Violation for NumericLiteralTooLong { #[derive_message_formats] fn message(&self) -> String { format!("Numeric literals with a string representation longer than ten characters are not permitted") @@ -33,10 +33,10 @@ impl Violation for LongNumericLiteralsInStub { } /// PYI054 -pub(crate) fn long_numeric_literals_in_stub(checker: &mut Checker, range: TextRange) { +pub(crate) fn numeric_literal_too_long(checker: &mut Checker, range: TextRange) { if range.len() > TextSize::new(10) { checker .diagnostics - .push(Diagnostic::new(LongNumericLiteralsInStub, range)); + .push(Diagnostic::new(NumericLiteralTooLong, range)); } } From b0790df1eb1ac71d457256f344b8e424a6d9f1a4 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Thu, 1 Jun 2023 21:00:59 -0400 Subject: [PATCH 7/9] Merge --- crates/ruff/src/checkers/ast/mod.rs | 9 +++++---- .../rules/numeric_literal_too_long.rs | 20 +++++++++++-------- .../rules/flake8_pyi/rules/simple_defaults.rs | 3 +++ 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/crates/ruff/src/checkers/ast/mod.rs b/crates/ruff/src/checkers/ast/mod.rs index 1acba359de72e..a28bccfa122c8 100644 --- a/crates/ruff/src/checkers/ast/mod.rs +++ b/crates/ruff/src/checkers/ast/mod.rs @@ -3412,16 +3412,17 @@ where } Expr::Constant(ast::ExprConstant { value: Constant::Int(_) | Constant::Float(_) | Constant::Complex { .. }, - range, - .. + kind: _, + range: _, }) => { if self.is_stub && self.enabled(Rule::NumericLiteralTooLong) { - flake8_pyi::rules::numeric_literal_too_long(self, *range); + flake8_pyi::rules::numeric_literal_too_long(self, expr); } } Expr::Constant(ast::ExprConstant { value: Constant::Bytes(_), - .. + kind: _, + range: _, }) => { if self.is_stub && self.enabled(Rule::StringOrBytesTooLong) { flake8_pyi::rules::string_or_bytes_too_long(self, expr); diff --git a/crates/ruff/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs b/crates/ruff/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs index 8df9a1245b8b8..e75dae05cda2e 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs @@ -1,4 +1,5 @@ -use ruff_text_size::{TextRange, TextSize}; +use ruff_text_size::TextSize; +use rustpython_parser::ast::{Expr, Ranged}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -9,12 +10,15 @@ use crate::checkers::ast::Checker; pub struct NumericLiteralTooLong; /// ## What it does -/// Checks for numeric literals longer than 10 characters +/// Checks for numeric literals with a string representation longer than ten +/// characters. /// /// ## Why is this bad? -/// If a function has a default value where the string representation is greater than 10 -/// characters, it is likely to be an implementation detail or a constant that varies depending on -/// the system you're running on, such as `sys.maxsize`. Consider replacing them with ellipses. +/// If a function has a default value where the literal representation is +/// greater than 50 characters, it is likely to be an implementation detail or +/// a constant that varies depending on the system you're running on. +/// +/// Consider replacing such constants with ellipses (`...`). /// /// ## Example /// ```python @@ -33,10 +37,10 @@ impl Violation for NumericLiteralTooLong { } /// PYI054 -pub(crate) fn numeric_literal_too_long(checker: &mut Checker, range: TextRange) { - if range.len() > TextSize::new(10) { +pub(crate) fn numeric_literal_too_long(checker: &mut Checker, expr: &Expr) { + if expr.range().len() > TextSize::new(10) { checker .diagnostics - .push(Diagnostic::new(NumericLiteralTooLong, range)); + .push(Diagnostic::new(NumericLiteralTooLong, expr.range())); } } 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 66f39451080dd..933d6d377fe61 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs @@ -96,6 +96,9 @@ fn is_valid_default_value_with_annotation( model: &SemanticModel, ) -> bool { match default { + Expr::Constant(_) => { + return true; + } Expr::List(ast::ExprList { elts, .. }) | Expr::Tuple(ast::ExprTuple { elts, .. }) | Expr::Set(ast::ExprSet { elts, range: _ }) => { From 17a09b372d86055281acb5c54e7ca2965a787e42 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Thu, 1 Jun 2023 21:02:26 -0400 Subject: [PATCH 8/9] Add fix --- .../rules/numeric_literal_too_long.rs | 24 +++-- .../rules/string_or_bytes_too_long.rs | 9 +- ..._flake8_pyi__tests__PYI054_PYI054.pyi.snap | 98 +++++++++++++++++-- 3 files changed, 114 insertions(+), 17 deletions(-) diff --git a/crates/ruff/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs b/crates/ruff/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs index e75dae05cda2e..28a49c0547fbc 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/numeric_literal_too_long.rs @@ -1,10 +1,11 @@ use ruff_text_size::TextSize; use rustpython_parser::ast::{Expr, Ranged}; -use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use crate::checkers::ast::Checker; +use crate::registry::AsRule; #[violation] pub struct NumericLiteralTooLong; @@ -29,18 +30,29 @@ pub struct NumericLiteralTooLong; /// ```python /// def foo(arg: int = ...) -> None: ... /// ``` -impl Violation for NumericLiteralTooLong { +impl AlwaysAutofixableViolation for NumericLiteralTooLong { #[derive_message_formats] fn message(&self) -> String { format!("Numeric literals with a string representation longer than ten characters are not permitted") } + + fn autofix_title(&self) -> String { + "Replace with `...`".to_string() + } } /// PYI054 pub(crate) fn numeric_literal_too_long(checker: &mut Checker, expr: &Expr) { - if expr.range().len() > TextSize::new(10) { - checker - .diagnostics - .push(Diagnostic::new(NumericLiteralTooLong, expr.range())); + if expr.range().len() <= TextSize::new(10) { + return; + } + + let mut diagnostic = Diagnostic::new(NumericLiteralTooLong, expr.range()); + if checker.patch(diagnostic.kind.rule()) { + diagnostic.set_fix(Fix::suggested(Edit::range_replacement( + "...".to_string(), + expr.range(), + ))); } + checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs b/crates/ruff/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs index 459f17f489170..bfe676e8aa73d 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs @@ -1,6 +1,6 @@ use rustpython_parser::ast::{self, Constant, Expr, Ranged}; -use ruff_diagnostics::{Diagnostic, Edit, Fix, Violation}; +use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use crate::checkers::ast::Checker; @@ -28,11 +28,15 @@ pub struct StringOrBytesTooLong; /// ```python /// def foo(arg: str = ...) -> None: ... /// ``` -impl Violation for StringOrBytesTooLong { +impl AlwaysAutofixableViolation for StringOrBytesTooLong { #[derive_message_formats] fn message(&self) -> String { format!("String and bytes literals longer than 50 characters are not permitted") } + + fn autofix_title(&self) -> String { + "Replace with `...`".to_string() + } } /// PYI053 @@ -48,7 +52,6 @@ pub(crate) fn string_or_bytes_too_long(checker: &mut Checker, expr: &Expr) { }) => bytes.len(), _ => return, }; - if length <= 50 { return; } diff --git a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI054_PYI054.pyi.snap b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI054_PYI054.pyi.snap index b663d28f23c08..b31422cdda1f8 100644 --- a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI054_PYI054.pyi.snap +++ b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI054_PYI054.pyi.snap @@ -1,7 +1,7 @@ --- source: crates/ruff/src/rules/flake8_pyi/mod.rs --- -PYI054.pyi:2:16: PYI054 Numeric literals with a string representation longer than ten characters are not permitted +PYI054.pyi:2:16: PYI054 [*] Numeric literals with a string representation longer than ten characters are not permitted | 2 | field01: int = 0xFFFFFFFF 3 | field02: int = 0xFFFFFFFFF # Error: PYI054 @@ -9,8 +9,17 @@ PYI054.pyi:2:16: PYI054 Numeric literals with a string representation longer tha 4 | field03: int = -0xFFFFFFFF 5 | field04: int = -0xFFFFFFFFF # Error: PYI054 | + = help: Replace with `...` -PYI054.pyi:4:17: PYI054 Numeric literals with a string representation longer than ten characters are not permitted +ℹ Suggested fix +1 1 | field01: int = 0xFFFFFFFF +2 |-field02: int = 0xFFFFFFFFF # Error: PYI054 + 2 |+field02: int = ... # Error: PYI054 +3 3 | field03: int = -0xFFFFFFFF +4 4 | field04: int = -0xFFFFFFFFF # Error: PYI054 +5 5 | + +PYI054.pyi:4:17: PYI054 [*] Numeric literals with a string representation longer than ten characters are not permitted | 4 | field02: int = 0xFFFFFFFFF # Error: PYI054 5 | field03: int = -0xFFFFFFFF @@ -19,8 +28,19 @@ PYI054.pyi:4:17: PYI054 Numeric literals with a string representation longer tha 7 | 8 | field05: int = 1234567890 | + = help: Replace with `...` + +ℹ Suggested fix +1 1 | field01: int = 0xFFFFFFFF +2 2 | field02: int = 0xFFFFFFFFF # Error: PYI054 +3 3 | field03: int = -0xFFFFFFFF +4 |-field04: int = -0xFFFFFFFFF # Error: PYI054 + 4 |+field04: int = -... # Error: PYI054 +5 5 | +6 6 | field05: int = 1234567890 +7 7 | field06: int = 12_456_890 -PYI054.pyi:8:16: PYI054 Numeric literals with a string representation longer than ten characters are not permitted +PYI054.pyi:8:16: PYI054 [*] Numeric literals with a string representation longer than ten characters are not permitted | 8 | field05: int = 1234567890 9 | field06: int = 12_456_890 @@ -29,8 +49,19 @@ PYI054.pyi:8:16: PYI054 Numeric literals with a string representation longer tha 11 | field08: int = -1234567801 12 | field09: int = -234_567_890 # Error: PYI054 | + = help: Replace with `...` -PYI054.pyi:10:17: PYI054 Numeric literals with a string representation longer than ten characters are not permitted +ℹ Suggested fix +5 5 | +6 6 | field05: int = 1234567890 +7 7 | field06: int = 12_456_890 +8 |-field07: int = 12345678901 # Error: PYI054 + 8 |+field07: int = ... # Error: PYI054 +9 9 | field08: int = -1234567801 +10 10 | field09: int = -234_567_890 # Error: PYI054 +11 11 | + +PYI054.pyi:10:17: PYI054 [*] Numeric literals with a string representation longer than ten characters are not permitted | 10 | field07: int = 12345678901 # Error: PYI054 11 | field08: int = -1234567801 @@ -39,8 +70,19 @@ PYI054.pyi:10:17: PYI054 Numeric literals with a string representation longer th 13 | 14 | field10: float = 123.456789 | + = help: Replace with `...` + +ℹ Suggested fix +7 7 | field06: int = 12_456_890 +8 8 | field07: int = 12345678901 # Error: PYI054 +9 9 | field08: int = -1234567801 +10 |-field09: int = -234_567_890 # Error: PYI054 + 10 |+field09: int = -... # Error: PYI054 +11 11 | +12 12 | field10: float = 123.456789 +13 13 | field11: float = 123.4567890 # Error: PYI054 -PYI054.pyi:13:18: PYI054 Numeric literals with a string representation longer than ten characters are not permitted +PYI054.pyi:13:18: PYI054 [*] Numeric literals with a string representation longer than ten characters are not permitted | 13 | field10: float = 123.456789 14 | field11: float = 123.4567890 # Error: PYI054 @@ -48,8 +90,19 @@ PYI054.pyi:13:18: PYI054 Numeric literals with a string representation longer th 15 | field12: float = -123.456789 16 | field13: float = -123.567_890 # Error: PYI054 | + = help: Replace with `...` -PYI054.pyi:15:19: PYI054 Numeric literals with a string representation longer than ten characters are not permitted +ℹ Suggested fix +10 10 | field09: int = -234_567_890 # Error: PYI054 +11 11 | +12 12 | field10: float = 123.456789 +13 |-field11: float = 123.4567890 # Error: PYI054 + 13 |+field11: float = ... # Error: PYI054 +14 14 | field12: float = -123.456789 +15 15 | field13: float = -123.567_890 # Error: PYI054 +16 16 | + +PYI054.pyi:15:19: PYI054 [*] Numeric literals with a string representation longer than ten characters are not permitted | 15 | field11: float = 123.4567890 # Error: PYI054 16 | field12: float = -123.456789 @@ -58,8 +111,19 @@ PYI054.pyi:15:19: PYI054 Numeric literals with a string representation longer th 18 | 19 | field14: complex = 1e1234567j | + = help: Replace with `...` + +ℹ Suggested fix +12 12 | field10: float = 123.456789 +13 13 | field11: float = 123.4567890 # Error: PYI054 +14 14 | field12: float = -123.456789 +15 |-field13: float = -123.567_890 # Error: PYI054 + 15 |+field13: float = -... # Error: PYI054 +16 16 | +17 17 | field14: complex = 1e1234567j +18 18 | field15: complex = 1e12345678j # Error: PYI054 -PYI054.pyi:18:20: PYI054 Numeric literals with a string representation longer than ten characters are not permitted +PYI054.pyi:18:20: PYI054 [*] Numeric literals with a string representation longer than ten characters are not permitted | 18 | field14: complex = 1e1234567j 19 | field15: complex = 1e12345678j # Error: PYI054 @@ -67,13 +131,31 @@ PYI054.pyi:18:20: PYI054 Numeric literals with a string representation longer th 20 | field16: complex = -1e1234567j 21 | field17: complex = 1e123456789j # Error: PYI054 | + = help: Replace with `...` -PYI054.pyi:20:20: PYI054 Numeric literals with a string representation longer than ten characters are not permitted +ℹ Suggested fix +15 15 | field13: float = -123.567_890 # Error: PYI054 +16 16 | +17 17 | field14: complex = 1e1234567j +18 |-field15: complex = 1e12345678j # Error: PYI054 + 18 |+field15: complex = ... # Error: PYI054 +19 19 | field16: complex = -1e1234567j +20 20 | field17: complex = 1e123456789j # Error: PYI054 + +PYI054.pyi:20:20: PYI054 [*] Numeric literals with a string representation longer than ten characters are not permitted | 20 | field15: complex = 1e12345678j # Error: PYI054 21 | field16: complex = -1e1234567j 22 | field17: complex = 1e123456789j # Error: PYI054 | ^^^^^^^^^^^^ PYI054 | + = help: Replace with `...` + +ℹ Suggested fix +17 17 | field14: complex = 1e1234567j +18 18 | field15: complex = 1e12345678j # Error: PYI054 +19 19 | field16: complex = -1e1234567j +20 |-field17: complex = 1e123456789j # Error: PYI054 + 20 |+field17: complex = ... # Error: PYI054 From 3360343e368fc1b9ec664ad4aa610a7b682063cf Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Thu, 1 Jun 2023 21:14:45 -0400 Subject: [PATCH 9/9] Fix always --- .../rules/string_or_bytes_too_long.rs | 4 +- ..._flake8_pyi__tests__PYI053_PYI053.pyi.snap | 61 +++++++++++++++++-- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/crates/ruff/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs b/crates/ruff/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs index bfe676e8aa73d..cecaed2685707 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/string_or_bytes_too_long.rs @@ -63,7 +63,5 @@ pub(crate) fn string_or_bytes_too_long(checker: &mut Checker, expr: &Expr) { expr.range(), ))); } - checker - .diagnostics - .push(Diagnostic::new(StringOrBytesTooLong, expr.range())); + checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI053_PYI053.pyi.snap b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI053_PYI053.pyi.snap index 04eb3a9799ed5..8c3fa6898c535 100644 --- a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI053_PYI053.pyi.snap +++ b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI053_PYI053.pyi.snap @@ -1,7 +1,7 @@ --- source: crates/ruff/src/rules/flake8_pyi/mod.rs --- -PYI053.pyi:3:14: PYI053 String and bytes literals longer than 50 characters are not permitted +PYI053.pyi:3:14: PYI053 [*] String and bytes literals longer than 50 characters are not permitted | 3 | def f1(x: str = "50 character stringggggggggggggggggggggggggggggggg") -> None: ... # OK 4 | def f2( @@ -10,8 +10,18 @@ PYI053.pyi:3:14: PYI053 String and bytes literals longer than 50 characters are 6 | ) -> None: ... 7 | def f3( | + = help: Replace with `...` -PYI053.pyi:9:14: PYI053 String and bytes literals longer than 50 characters are not permitted +ℹ Suggested fix +1 1 | def f1(x: str = "50 character stringggggggggggggggggggggggggggggggg") -> None: ... # OK +2 2 | def f2( +3 |- x: str = "51 character stringgggggggggggggggggggggggggggggggg", # Error: PYI053 + 3 |+ x: str = ..., # Error: PYI053 +4 4 | ) -> None: ... +5 5 | def f3( +6 6 | x: str = "50 character stringgggggggggggggggggggggggggggggg\U0001f600", # OK + +PYI053.pyi:9:14: PYI053 [*] String and bytes literals longer than 50 characters are not permitted | 9 | ) -> None: ... 10 | def f4( @@ -20,8 +30,19 @@ PYI053.pyi:9:14: PYI053 String and bytes literals longer than 50 characters are 12 | ) -> None: ... 13 | def f5( | + = help: Replace with `...` + +ℹ Suggested fix +6 6 | x: str = "50 character stringgggggggggggggggggggggggggggggg\U0001f600", # OK +7 7 | ) -> None: ... +8 8 | def f4( +9 |- x: str = "51 character stringggggggggggggggggggggggggggggggg\U0001f600", # Error: PYI053 + 9 |+ x: str = ..., # Error: PYI053 +10 10 | ) -> None: ... +11 11 | def f5( +12 12 | x: bytes = b"50 character byte stringgggggggggggggggggggggggggg", # OK -PYI053.pyi:21:16: PYI053 String and bytes literals longer than 50 characters are not permitted +PYI053.pyi:21:16: PYI053 [*] String and bytes literals longer than 50 characters are not permitted | 21 | ) -> None: ... 22 | def f8( @@ -29,8 +50,19 @@ PYI053.pyi:21:16: PYI053 String and bytes literals longer than 50 characters are | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI053 24 | ) -> None: ... | + = help: Replace with `...` + +ℹ Suggested fix +18 18 | x: bytes = b"50 character byte stringggggggggggggggggggggggggg\xff", # OK +19 19 | ) -> None: ... +20 20 | def f8( +21 |- x: bytes = b"51 character byte stringgggggggggggggggggggggggggg\xff", # Error: PYI053 + 21 |+ x: bytes = ..., # Error: PYI053 +22 22 | ) -> None: ... +23 23 | +24 24 | foo: str = "50 character stringggggggggggggggggggggggggggggggg" # OK -PYI053.pyi:26:12: PYI053 String and bytes literals longer than 50 characters are not permitted +PYI053.pyi:26:12: PYI053 [*] String and bytes literals longer than 50 characters are not permitted | 26 | foo: str = "50 character stringggggggggggggggggggggggggggggggg" # OK 27 | @@ -39,13 +71,32 @@ PYI053.pyi:26:12: PYI053 String and bytes literals longer than 50 characters are 29 | 30 | baz: bytes = b"50 character byte stringgggggggggggggggggggggggggg" # OK | + = help: Replace with `...` -PYI053.pyi:30:14: PYI053 String and bytes literals longer than 50 characters are not permitted +ℹ Suggested fix +23 23 | +24 24 | foo: str = "50 character stringggggggggggggggggggggggggggggggg" # OK +25 25 | +26 |-bar: str = "51 character stringgggggggggggggggggggggggggggggggg" # Error: PYI053 + 26 |+bar: str = ... # Error: PYI053 +27 27 | +28 28 | baz: bytes = b"50 character byte stringgggggggggggggggggggggggggg" # OK +29 29 | + +PYI053.pyi:30:14: PYI053 [*] String and bytes literals longer than 50 characters are not permitted | 30 | baz: bytes = b"50 character byte stringgggggggggggggggggggggggggg" # OK 31 | 32 | qux: bytes = b"51 character byte stringggggggggggggggggggggggggggg\xff" # Error: PYI053 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI053 | + = help: Replace with `...` + +ℹ Suggested fix +27 27 | +28 28 | baz: bytes = b"50 character byte stringgggggggggggggggggggggggggg" # OK +29 29 | +30 |-qux: bytes = b"51 character byte stringggggggggggggggggggggggggggg\xff" # Error: PYI053 + 30 |+qux: bytes = ... # Error: PYI053