mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 10:48:32 +00:00
Reorganize some flake8-pyi
rules (#5472)
This commit is contained in:
parent
93b2bd7184
commit
94ac2c4e1b
10 changed files with 257 additions and 284 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 { .. },
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Self, Self::Error> {
|
||||
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<Self> {
|
||||
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,
|
|
@ -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: ...
|
||||
|
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue