From 94ac2c4e1bbb583acc0d03e82c236b1c9398d324 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 3 Jul 2023 00:39:22 -0400 Subject: [PATCH] Reorganize some `flake8-pyi` rules (#5472) --- .../test/fixtures/flake8_pyi/PYI002.py | 19 +- .../test/fixtures/flake8_pyi/PYI002.pyi | 19 +- crates/ruff/src/checkers/ast/mod.rs | 62 +++--- .../rules/bad_version_info_comparison.rs | 27 +-- .../rules/complex_if_statement_in_stub.rs | 80 ++++++++ crates/ruff/src/rules/flake8_pyi/rules/mod.rs | 6 +- .../flake8_pyi/rules/unrecognized_platform.rs | 62 +++--- ...n_info.rs => unrecognized_version_info.rs} | 184 ++++++------------ ..._flake8_pyi__tests__PYI002_PYI002.pyi.snap | 78 +++----- ..._flake8_pyi__tests__PYI005_PYI005.pyi.snap | 4 +- 10 files changed, 257 insertions(+), 284 deletions(-) create mode 100644 crates/ruff/src/rules/flake8_pyi/rules/complex_if_statement_in_stub.rs rename crates/ruff/src/rules/flake8_pyi/rules/{version_info.rs => unrecognized_version_info.rs} (63%) diff --git a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI002.py b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI002.py index 857b029cdc..50cf7c884f 100644 --- a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI002.py +++ b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI002.py @@ -1,17 +1,6 @@ import sys -from sys import platform, version_info -if sys.version == 'Python 2.7.10': ... # PYI002 -if 'linux' == sys.platform: ... # PYI002 -if hasattr(sys, 'maxint'): ... # PYI002 -if sys.maxsize == 42: ... # PYI002 -if (2, 7) < sys.version_info < (3, 5): ... # PYI002 -if sys.version[0] == 'P': ... # PYI002 -if False: ... # PYI002 - -if version_info[0] == 2: ... -if sys.version_info < (3, 5): ... -if version_info >= (3, 5): ... -if sys.version_info[:2] == (2, 7): ... -if sys.version_info[:1] == (2,): ... -if platform == 'linux': ... +if sys.version == 'Python 2.7.10': ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info +if 'linux' == sys.platform: ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info +if hasattr(sys, 'maxint'): ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info +if sys.maxsize == 42: ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info diff --git a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI002.pyi b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI002.pyi index 857b029cdc..50cf7c884f 100644 --- a/crates/ruff/resources/test/fixtures/flake8_pyi/PYI002.pyi +++ b/crates/ruff/resources/test/fixtures/flake8_pyi/PYI002.pyi @@ -1,17 +1,6 @@ import sys -from sys import platform, version_info -if sys.version == 'Python 2.7.10': ... # PYI002 -if 'linux' == sys.platform: ... # PYI002 -if hasattr(sys, 'maxint'): ... # PYI002 -if sys.maxsize == 42: ... # PYI002 -if (2, 7) < sys.version_info < (3, 5): ... # PYI002 -if sys.version[0] == 'P': ... # PYI002 -if False: ... # PYI002 - -if version_info[0] == 2: ... -if sys.version_info < (3, 5): ... -if version_info >= (3, 5): ... -if sys.version_info[:2] == (2, 7): ... -if sys.version_info[:1] == (2,): ... -if platform == 'linux': ... +if sys.version == 'Python 2.7.10': ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info +if 'linux' == sys.platform: ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info +if hasattr(sys, 'maxint'): ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info +if sys.maxsize == 42: ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info diff --git a/crates/ruff/src/checkers/ast/mod.rs b/crates/ruff/src/checkers/ast/mod.rs index d20c1271d6..8d85f2968c 100644 --- a/crates/ruff/src/checkers/ast/mod.rs +++ b/crates/ruff/src/checkers/ast/mod.rs @@ -1373,12 +1373,47 @@ where } if self.is_stub { if self.any_enabled(&[ - Rule::ComplexIfStatementInStub, Rule::UnrecognizedVersionInfoCheck, Rule::PatchVersionComparison, Rule::WrongTupleLengthVersionComparison, ]) { - flake8_pyi::rules::version_info(self, test); + if let Expr::BoolOp(ast::ExprBoolOp { values, .. }) = test.as_ref() { + for value in values { + flake8_pyi::rules::unrecognized_version_info(self, value); + } + } else { + flake8_pyi::rules::unrecognized_version_info(self, test); + } + } + if self.any_enabled(&[ + Rule::UnrecognizedPlatformCheck, + Rule::UnrecognizedPlatformName, + ]) { + if let Expr::BoolOp(ast::ExprBoolOp { values, .. }) = test.as_ref() { + for value in values { + flake8_pyi::rules::unrecognized_platform(self, value); + } + } else { + flake8_pyi::rules::unrecognized_platform(self, test); + } + } + if self.enabled(Rule::BadVersionInfoComparison) { + if let Expr::BoolOp(ast::ExprBoolOp { values, .. }) = test.as_ref() { + for value in values { + flake8_pyi::rules::bad_version_info_comparison(self, value); + } + } else { + flake8_pyi::rules::bad_version_info_comparison(self, test); + } + } + if self.enabled(Rule::ComplexIfStatementInStub) { + if let Expr::BoolOp(ast::ExprBoolOp { values, .. }) = test.as_ref() { + for value in values { + flake8_pyi::rules::complex_if_statement_in_stub(self, value); + } + } else { + flake8_pyi::rules::complex_if_statement_in_stub(self, test); + } } } } @@ -3223,29 +3258,6 @@ where if self.enabled(Rule::YodaConditions) { flake8_simplify::rules::yoda_conditions(self, expr, left, ops, comparators); } - if self.is_stub { - if self.any_enabled(&[ - Rule::UnrecognizedPlatformCheck, - Rule::UnrecognizedPlatformName, - ]) { - flake8_pyi::rules::unrecognized_platform( - self, - expr, - left, - ops, - comparators, - ); - } - if self.enabled(Rule::BadVersionInfoComparison) { - flake8_pyi::rules::bad_version_info_comparison( - self, - expr, - left, - ops, - comparators, - ); - } - } } Expr::Constant(ast::ExprConstant { value: Constant::Int(_) | Constant::Float(_) | Constant::Complex { .. }, diff --git a/crates/ruff/src/rules/flake8_pyi/rules/bad_version_info_comparison.rs b/crates/ruff/src/rules/flake8_pyi/rules/bad_version_info_comparison.rs index 18a8d4e1b1..332ddfc5f7 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/bad_version_info_comparison.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/bad_version_info_comparison.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{CmpOp, Expr, Ranged}; +use rustpython_parser::ast::{self, CmpOp, Expr, Ranged}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -57,14 +57,18 @@ impl Violation for BadVersionInfoComparison { } /// PYI006 -pub(crate) fn bad_version_info_comparison( - checker: &mut Checker, - expr: &Expr, - left: &Expr, - ops: &[CmpOp], - comparators: &[Expr], -) { - let ([op], [_right]) = (ops, comparators) else { +pub(crate) fn bad_version_info_comparison(checker: &mut Checker, test: &Expr) { + let Expr::Compare(ast::ExprCompare { + left, + ops, + comparators, + .. + }) = test + else { + return; + }; + + let ([op], [_right]) = (ops.as_slice(), comparators.as_slice()) else { return; }; @@ -82,6 +86,7 @@ pub(crate) fn bad_version_info_comparison( return; } - let diagnostic = Diagnostic::new(BadVersionInfoComparison, expr.range()); - checker.diagnostics.push(diagnostic); + checker + .diagnostics + .push(Diagnostic::new(BadVersionInfoComparison, test.range())); } diff --git a/crates/ruff/src/rules/flake8_pyi/rules/complex_if_statement_in_stub.rs b/crates/ruff/src/rules/flake8_pyi/rules/complex_if_statement_in_stub.rs new file mode 100644 index 0000000000..a8287ff671 --- /dev/null +++ b/crates/ruff/src/rules/flake8_pyi/rules/complex_if_statement_in_stub.rs @@ -0,0 +1,80 @@ +use rustpython_parser::ast::{self, Expr, Ranged}; + +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for `if` statements with complex conditionals in stubs. +/// +/// ## Why is this bad? +/// Stub files support simple conditionals to test for differences in Python +/// versions and platforms. However, type checkers only understand a limited +/// subset of these conditionals; complex conditionals may result in false +/// positives or false negatives. +/// +/// ## Example +/// ```python +/// import sys +/// +/// if (2, 7) < sys.version_info < (3, 5): +/// ... +/// ``` +/// +/// Use instead: +/// ```python +/// import sys +/// +/// if sys.version_info < (3, 5): +/// ... +/// ``` +#[violation] +pub struct ComplexIfStatementInStub; + +impl Violation for ComplexIfStatementInStub { + #[derive_message_formats] + fn message(&self) -> String { + format!( + "`if`` test must be a simple comparison against `sys.platform` or `sys.version_info`" + ) + } +} + +/// PYI002 +pub(crate) fn complex_if_statement_in_stub(checker: &mut Checker, test: &Expr) { + let Expr::Compare(ast::ExprCompare { + left, comparators, .. + }) = test + else { + checker + .diagnostics + .push(Diagnostic::new(ComplexIfStatementInStub, test.range())); + return; + }; + + if comparators.len() != 1 { + checker + .diagnostics + .push(Diagnostic::new(ComplexIfStatementInStub, test.range())); + return; + } + + if left.is_subscript_expr() { + return; + } + + if checker + .semantic() + .resolve_call_path(left) + .map_or(false, |call_path| { + matches!(call_path.as_slice(), ["sys", "version_info" | "platform"]) + }) + { + return; + } + + checker + .diagnostics + .push(Diagnostic::new(ComplexIfStatementInStub, test.range())); +} diff --git a/crates/ruff/src/rules/flake8_pyi/rules/mod.rs b/crates/ruff/src/rules/flake8_pyi/rules/mod.rs index ed96285dcd..612055db37 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/mod.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/mod.rs @@ -1,6 +1,7 @@ pub(crate) use any_eq_ne_annotation::*; pub(crate) use bad_version_info_comparison::*; pub(crate) use collections_named_tuple::*; +pub(crate) use complex_if_statement_in_stub::*; pub(crate) use docstring_in_stubs::*; pub(crate) use duplicate_union_member::*; pub(crate) use ellipsis_in_non_empty_class_body::*; @@ -22,11 +23,12 @@ pub(crate) use type_alias_naming::*; pub(crate) use type_comment_in_stub::*; pub(crate) use unaliased_collections_abc_set_import::*; pub(crate) use unrecognized_platform::*; -pub(crate) use version_info::*; +pub(crate) use unrecognized_version_info::*; mod any_eq_ne_annotation; mod bad_version_info_comparison; mod collections_named_tuple; +mod complex_if_statement_in_stub; mod docstring_in_stubs; mod duplicate_union_member; mod ellipsis_in_non_empty_class_body; @@ -48,4 +50,4 @@ mod type_alias_naming; mod type_comment_in_stub; mod unaliased_collections_abc_set_import; mod unrecognized_platform; -mod version_info; +mod unrecognized_version_info; diff --git a/crates/ruff/src/rules/flake8_pyi/rules/unrecognized_platform.rs b/crates/ruff/src/rules/flake8_pyi/rules/unrecognized_platform.rs index af876baa0c..418c0c55bf 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/unrecognized_platform.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/unrecognized_platform.rs @@ -89,19 +89,21 @@ impl Violation for UnrecognizedPlatformName { } /// PYI007, PYI008 -pub(crate) fn unrecognized_platform( - checker: &mut Checker, - expr: &Expr, - left: &Expr, - ops: &[CmpOp], - comparators: &[Expr], -) { - let ([op], [right]) = (ops, comparators) else { +pub(crate) fn unrecognized_platform(checker: &mut Checker, test: &Expr) { + let Expr::Compare(ast::ExprCompare { + left, + ops, + comparators, + .. + }) = test + else { + return; + }; + + let ([op], [right]) = (ops.as_slice(), comparators.as_slice()) else { return; }; - let diagnostic_unrecognized_platform_check = - Diagnostic::new(UnrecognizedPlatformCheck, expr.range()); if !checker .semantic() .resolve_call_path(left) @@ -113,23 +115,24 @@ pub(crate) fn unrecognized_platform( } // "in" might also make sense but we don't currently have one. - if !matches!(op, CmpOp::Eq | CmpOp::NotEq) && checker.enabled(Rule::UnrecognizedPlatformCheck) { - checker - .diagnostics - .push(diagnostic_unrecognized_platform_check); + if !matches!(op, CmpOp::Eq | CmpOp::NotEq) { + if checker.enabled(Rule::UnrecognizedPlatformCheck) { + checker + .diagnostics + .push(Diagnostic::new(UnrecognizedPlatformCheck, test.range())); + } return; } - match right { - Expr::Constant(ast::ExprConstant { - value: Constant::Str(value), - .. - }) => { - // Other values are possible but we don't need them right now. - // This protects against typos. - if !["linux", "win32", "cygwin", "darwin"].contains(&value.as_str()) - && checker.enabled(Rule::UnrecognizedPlatformName) - { + if let Expr::Constant(ast::ExprConstant { + value: Constant::Str(value), + .. + }) = right + { + // Other values are possible but we don't need them right now. + // This protects against typos. + if checker.enabled(Rule::UnrecognizedPlatformName) { + if !matches!(value.as_str(), "linux" | "win32" | "cygwin" | "darwin") { checker.diagnostics.push(Diagnostic::new( UnrecognizedPlatformName { platform: value.clone(), @@ -138,12 +141,11 @@ pub(crate) fn unrecognized_platform( )); } } - _ => { - if checker.enabled(Rule::UnrecognizedPlatformCheck) { - checker - .diagnostics - .push(diagnostic_unrecognized_platform_check); - } + } else { + if checker.enabled(Rule::UnrecognizedPlatformCheck) { + checker + .diagnostics + .push(Diagnostic::new(UnrecognizedPlatformCheck, test.range())); } } } diff --git a/crates/ruff/src/rules/flake8_pyi/rules/version_info.rs b/crates/ruff/src/rules/flake8_pyi/rules/unrecognized_version_info.rs similarity index 63% rename from crates/ruff/src/rules/flake8_pyi/rules/version_info.rs rename to crates/ruff/src/rules/flake8_pyi/rules/unrecognized_version_info.rs index 4e2e2d21de..dfb288154c 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/version_info.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/unrecognized_version_info.rs @@ -1,50 +1,14 @@ use num_bigint::BigInt; use num_traits::{One, Zero}; use rustpython_parser::ast::{self, CmpOp, Constant, Expr, Ranged}; -use smallvec::SmallVec; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::helpers::map_subscript; use crate::checkers::ast::Checker; use crate::registry::Rule; -/// ## What it does -/// Checks for `if` statements with complex conditionals in stubs. -/// -/// ## Why is this bad? -/// Stub files support simple conditionals to test for differences in Python -/// versions and platforms. However, type checkers only understand a limited -/// subset of these conditionals; complex conditionals may result in false -/// positives or false negatives. -/// -/// ## Example -/// ```python -/// import sys -/// -/// if (2, 7) < sys.version_info < (3, 5): -/// ... -/// ``` -/// -/// Use instead: -/// ```python -/// import sys -/// -/// if sys.version_info < (3, 5): -/// ... -/// ``` -#[violation] -pub struct ComplexIfStatementInStub; - -impl Violation for ComplexIfStatementInStub { - #[derive_message_formats] - fn message(&self) -> String { - format!( - "`if`` test must be a simple comparison against `sys.platform` or `sys.version_info`" - ) - } -} - /// ## What it does /// Checks for problematic `sys.version_info`-related conditions in stubs. /// @@ -150,104 +114,57 @@ pub struct WrongTupleLengthVersionComparison { impl Violation for WrongTupleLengthVersionComparison { #[derive_message_formats] fn message(&self) -> String { - format!( - "Version comparison must be against a length-{} tuple.", - self.expected_length - ) + let WrongTupleLengthVersionComparison { expected_length } = self; + format!("Version comparison must be against a length-{expected_length} tuple") } } -#[derive(Copy, Clone, Eq, PartialEq)] -enum ExpectedComparator { - MajorDigit, - MajorTuple, - MajorMinorTuple, - AnyTuple, -} - -/// PYI002, PYI003, PYI004, PYI005 -pub(crate) fn version_info(checker: &mut Checker, test: &Expr) { - if let Expr::BoolOp(ast::ExprBoolOp { values, .. }) = test { - for value in values { - version_info(checker, value); - } - return; - } - - let Some((left, op, comparator, is_platform)) = compare_expr_components(checker, test) else { - if checker.enabled(Rule::ComplexIfStatementInStub) { - checker - .diagnostics - .push(Diagnostic::new(ComplexIfStatementInStub, test.range())); - } +/// PYI003, PYI004, PYI005 +pub(crate) fn unrecognized_version_info(checker: &mut Checker, test: &Expr) { + let Expr::Compare(ast::ExprCompare { + left, + ops, + comparators, + .. + }) = test + else { return; }; - // Already covered by PYI007. - if is_platform { + let ([op], [comparator]) = (ops.as_slice(), comparators.as_slice()) else { + return; + }; + + if !checker + .semantic() + .resolve_call_path(map_subscript(left)) + .map_or(false, |call_path| { + matches!(call_path.as_slice(), ["sys", "version_info"]) + }) + { return; } - let Ok(expected_comparator) = ExpectedComparator::try_from(left) else { + if let Some(expected) = ExpectedComparator::try_from(left) { + version_check(checker, expected, test, *op, comparator); + } else { if checker.enabled(Rule::UnrecognizedVersionInfoCheck) { checker .diagnostics .push(Diagnostic::new(UnrecognizedVersionInfoCheck, test.range())); } - return; - }; - - check_version_check(checker, expected_comparator, test, op, comparator); + } } -/// Extracts relevant components of the if test. -fn compare_expr_components<'a>( - checker: &Checker, - test: &'a Expr, -) -> Option<(&'a Expr, CmpOp, &'a Expr, bool)> { - test.as_compare_expr().and_then(|cmp| { - let ast::ExprCompare { - left, - ops, - comparators, - .. - } = cmp; - - if comparators.len() != 1 { - return None; - } - - let name_expr = if let Expr::Subscript(ast::ExprSubscript { value, .. }) = left.as_ref() { - value - } else { - left - }; - - // The only valid comparisons are against sys.platform and sys.version_info. - let is_platform = match checker - .semantic() - .resolve_call_path(name_expr) - .as_ref() - .map(SmallVec::as_slice) - { - Some(["sys", "platform"]) => true, - Some(["sys", "version_info"]) => false, - _ => return None, - }; - - Some((left.as_ref(), ops[0], &comparators[0], is_platform)) - }) -} - -fn check_version_check( +fn version_check( checker: &mut Checker, - expected_comparator: ExpectedComparator, + expected: ExpectedComparator, test: &Expr, op: CmpOp, comparator: &Expr, ) { // Single digit comparison, e.g., `sys.version_info[0] == 2`. - if expected_comparator == ExpectedComparator::MajorDigit { + if expected == ExpectedComparator::MajorDigit { if !is_int_constant(comparator) { if checker.enabled(Rule::UnrecognizedVersionInfoCheck) { checker @@ -288,7 +205,7 @@ fn check_version_check( if checker.enabled(Rule::WrongTupleLengthVersionComparison) { if op == CmpOp::Eq || op == CmpOp::NotEq { - let expected_length = match expected_comparator { + let expected_length = match expected { ExpectedComparator::MajorTuple => 1, ExpectedComparator::MajorMinorTuple => 2, _ => return, @@ -304,32 +221,40 @@ fn check_version_check( } } -impl TryFrom<&Expr> for ExpectedComparator { - type Error = (); +#[derive(Copy, Clone, Eq, PartialEq)] +enum ExpectedComparator { + MajorDigit, + MajorTuple, + MajorMinorTuple, + AnyTuple, +} - fn try_from(value: &Expr) -> Result { - let Expr::Subscript(ast::ExprSubscript { slice, .. }) = value else { - return Ok(ExpectedComparator::AnyTuple) +impl ExpectedComparator { + /// Returns the expected comparator for the given expression, if any. + fn try_from(expr: &Expr) -> Option { + let Expr::Subscript(ast::ExprSubscript { slice, .. }) = expr else { + return Some(ExpectedComparator::AnyTuple); }; - // Only allow simple slices of the form [:n] or explicit indexing into the first element + // Only allow: (1) simple slices of the form `[:n]`, or (2) explicit indexing into the first + // element (major version) of the tuple. match slice.as_ref() { Expr::Slice(ast::ExprSlice { lower: None, - upper: Some(n), + upper: Some(upper), step: None, .. }) => { if let Expr::Constant(ast::ExprConstant { - value: Constant::Int(n), + value: Constant::Int(upper), .. - }) = n.as_ref() + }) = upper.as_ref() { - if *n == BigInt::one() { - return Ok(ExpectedComparator::MajorTuple); + if *upper == BigInt::one() { + return Some(ExpectedComparator::MajorTuple); } - if *n == BigInt::from(2) { - return Ok(ExpectedComparator::MajorMinorTuple); + if *upper == BigInt::from(2) { + return Some(ExpectedComparator::MajorMinorTuple); } } } @@ -337,15 +262,16 @@ impl TryFrom<&Expr> for ExpectedComparator { value: Constant::Int(n), .. }) if n.is_zero() => { - return Ok(ExpectedComparator::MajorDigit); + return Some(ExpectedComparator::MajorDigit); } _ => (), } - Err(()) + None } } +/// Returns `true` if the given expression is an integer constant. fn is_int_constant(expr: &Expr) -> bool { matches!( expr, diff --git a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI002_PYI002.pyi.snap b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI002_PYI002.pyi.snap index bfac1f9b31..103bef4bac 100644 --- a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI002_PYI002.pyi.snap +++ b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI002_PYI002.pyi.snap @@ -1,72 +1,40 @@ --- source: crates/ruff/src/rules/flake8_pyi/mod.rs --- +PYI002.pyi:3:4: PYI002 `if`` test must be a simple comparison against `sys.platform` or `sys.version_info` + | +1 | import sys +2 | +3 | if sys.version == 'Python 2.7.10': ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI002 +4 | if 'linux' == sys.platform: ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info +5 | if hasattr(sys, 'maxint'): ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info + | + PYI002.pyi:4:4: PYI002 `if`` test must be a simple comparison against `sys.platform` or `sys.version_info` | -2 | from sys import platform, version_info -3 | -4 | if sys.version == 'Python 2.7.10': ... # PYI002 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI002 -5 | if 'linux' == sys.platform: ... # PYI002 -6 | if hasattr(sys, 'maxint'): ... # PYI002 +3 | if sys.version == 'Python 2.7.10': ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info +4 | if 'linux' == sys.platform: ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info + | ^^^^^^^^^^^^^^^^^^^^^^^ PYI002 +5 | if hasattr(sys, 'maxint'): ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info +6 | if sys.maxsize == 42: ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info | PYI002.pyi:5:4: PYI002 `if`` test must be a simple comparison against `sys.platform` or `sys.version_info` | -4 | if sys.version == 'Python 2.7.10': ... # PYI002 -5 | if 'linux' == sys.platform: ... # PYI002 - | ^^^^^^^^^^^^^^^^^^^^^^^ PYI002 -6 | if hasattr(sys, 'maxint'): ... # PYI002 -7 | if sys.maxsize == 42: ... # PYI002 +3 | if sys.version == 'Python 2.7.10': ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info +4 | if 'linux' == sys.platform: ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info +5 | if hasattr(sys, 'maxint'): ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info + | ^^^^^^^^^^^^^^^^^^^^^^ PYI002 +6 | if sys.maxsize == 42: ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info | PYI002.pyi:6:4: PYI002 `if`` test must be a simple comparison against `sys.platform` or `sys.version_info` | -4 | if sys.version == 'Python 2.7.10': ... # PYI002 -5 | if 'linux' == sys.platform: ... # PYI002 -6 | if hasattr(sys, 'maxint'): ... # PYI002 - | ^^^^^^^^^^^^^^^^^^^^^^ PYI002 -7 | if sys.maxsize == 42: ... # PYI002 -8 | if (2, 7) < sys.version_info < (3, 5): ... # PYI002 - | - -PYI002.pyi:7:4: PYI002 `if`` test must be a simple comparison against `sys.platform` or `sys.version_info` - | -5 | if 'linux' == sys.platform: ... # PYI002 -6 | if hasattr(sys, 'maxint'): ... # PYI002 -7 | if sys.maxsize == 42: ... # PYI002 +4 | if 'linux' == sys.platform: ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info +5 | if hasattr(sys, 'maxint'): ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info +6 | if sys.maxsize == 42: ... # Y002 If test must be a simple comparison against sys.platform or sys.version_info | ^^^^^^^^^^^^^^^^^ PYI002 -8 | if (2, 7) < sys.version_info < (3, 5): ... # PYI002 -9 | if sys.version[0] == 'P': ... # PYI002 | -PYI002.pyi:8:4: PYI002 `if`` test must be a simple comparison against `sys.platform` or `sys.version_info` - | - 6 | if hasattr(sys, 'maxint'): ... # PYI002 - 7 | if sys.maxsize == 42: ... # PYI002 - 8 | if (2, 7) < sys.version_info < (3, 5): ... # PYI002 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PYI002 - 9 | if sys.version[0] == 'P': ... # PYI002 -10 | if False: ... # PYI002 - | - -PYI002.pyi:9:4: PYI002 `if`` test must be a simple comparison against `sys.platform` or `sys.version_info` - | - 7 | if sys.maxsize == 42: ... # PYI002 - 8 | if (2, 7) < sys.version_info < (3, 5): ... # PYI002 - 9 | if sys.version[0] == 'P': ... # PYI002 - | ^^^^^^^^^^^^^^^^^^^^^ PYI002 -10 | if False: ... # PYI002 - | - -PYI002.pyi:10:4: PYI002 `if`` test must be a simple comparison against `sys.platform` or `sys.version_info` - | - 8 | if (2, 7) < sys.version_info < (3, 5): ... # PYI002 - 9 | if sys.version[0] == 'P': ... # PYI002 -10 | if False: ... # PYI002 - | ^^^^^ PYI002 -11 | -12 | if version_info[0] == 2: ... - | - diff --git a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI005_PYI005.pyi.snap b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI005_PYI005.pyi.snap index 4b11f74662..1641bce44c 100644 --- a/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI005_PYI005.pyi.snap +++ b/crates/ruff/src/rules/flake8_pyi/snapshots/ruff__rules__flake8_pyi__tests__PYI005_PYI005.pyi.snap @@ -1,7 +1,7 @@ --- source: crates/ruff/src/rules/flake8_pyi/mod.rs --- -PYI005.pyi:4:4: PYI005 Version comparison must be against a length-1 tuple. +PYI005.pyi:4:4: PYI005 Version comparison must be against a length-1 tuple | 2 | from sys import platform, version_info 3 | @@ -10,7 +10,7 @@ PYI005.pyi:4:4: PYI005 Version comparison must be against a length-1 tuple. 5 | if sys.version_info[:2] == (2,): ... # Y005 | -PYI005.pyi:5:4: PYI005 Version comparison must be against a length-2 tuple. +PYI005.pyi:5:4: PYI005 Version comparison must be against a length-2 tuple | 4 | if sys.version_info[:1] == (2, 7): ... # Y005 5 | if sys.version_info[:2] == (2,): ... # Y005