diff --git a/crates/ruff/src/rules/flake8_bandit/rules/request_with_no_cert_validation.rs b/crates/ruff/src/rules/flake8_bandit/rules/request_with_no_cert_validation.rs index 3a11042da2..b03020e7eb 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/request_with_no_cert_validation.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/request_with_no_cert_validation.rs @@ -1,8 +1,8 @@ -use rustpython_parser::ast::{self, Constant, Expr, Keyword, Ranged}; +use rustpython_parser::ast::{Expr, Keyword, Ranged}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::SimpleCallArgs; +use ruff_python_ast::helpers::{is_const_false, SimpleCallArgs}; use crate::checkers::ast::Checker; @@ -60,11 +60,7 @@ pub(crate) fn request_with_no_cert_validation( { let call_args = SimpleCallArgs::new(args, keywords); if let Some(verify_arg) = call_args.keyword_argument("verify") { - if let Expr::Constant(ast::ExprConstant { - value: Constant::Bool(false), - .. - }) = &verify_arg - { + if is_const_false(verify_arg) { checker.diagnostics.push(Diagnostic::new( RequestWithNoCertValidation { string: target.to_string(), diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/assert_false.rs b/crates/ruff/src/rules/flake8_bugbear/rules/assert_false.rs index 290fefdfa2..54b9912265 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/assert_false.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/assert_false.rs @@ -1,8 +1,9 @@ use ruff_text_size::TextRange; -use rustpython_parser::ast::{self, Constant, Expr, ExprContext, Ranged, Stmt}; +use rustpython_parser::ast::{self, Expr, ExprContext, Ranged, Stmt}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::helpers::is_const_false; use crate::checkers::ast::Checker; use crate::registry::AsRule; @@ -44,12 +45,9 @@ fn assertion_error(msg: Option<&Expr>) -> Stmt { /// B011 pub(crate) fn assert_false(checker: &mut Checker, stmt: &Stmt, test: &Expr, msg: Option<&Expr>) { - let Expr::Constant(ast::ExprConstant { - value: Constant::Bool(false), - .. - } )= &test else { + if !is_const_false(test) { return; - }; + } let mut diagnostic = Diagnostic::new(AssertFalse, test.range()); if checker.patch(diagnostic.kind.rule()) { diff --git a/crates/ruff/src/rules/flake8_django/rules/model_without_dunder_str.rs b/crates/ruff/src/rules/flake8_django/rules/model_without_dunder_str.rs index c0ca4d99e9..a02992757e 100644 --- a/crates/ruff/src/rules/flake8_django/rules/model_without_dunder_str.rs +++ b/crates/ruff/src/rules/flake8_django/rules/model_without_dunder_str.rs @@ -1,7 +1,8 @@ -use rustpython_parser::ast::{self, Constant, Expr, Ranged, Stmt}; +use rustpython_parser::ast::{self, Expr, Ranged, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::helpers::is_const_true; use ruff_python_semantic::SemanticModel; use crate::checkers::ast::Checker; @@ -112,9 +113,9 @@ fn is_model_abstract(body: &[Stmt]) -> bool { if id != "abstract" { continue; } - let Expr::Constant(ast::ExprConstant{value: Constant::Bool(true), ..}) = value.as_ref() else { + if !is_const_true(value) { continue; - }; + } return true; } } diff --git a/crates/ruff/src/rules/flake8_django/rules/nullable_model_string_field.rs b/crates/ruff/src/rules/flake8_django/rules/nullable_model_string_field.rs index 35b8d66c14..a6ed90c648 100644 --- a/crates/ruff/src/rules/flake8_django/rules/nullable_model_string_field.rs +++ b/crates/ruff/src/rules/flake8_django/rules/nullable_model_string_field.rs @@ -1,8 +1,8 @@ -use rustpython_parser::ast::Constant::Bool; use rustpython_parser::ast::{self, Expr, Ranged, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::helpers::is_const_true; use crate::checkers::ast::Checker; @@ -96,12 +96,12 @@ fn is_nullable_field<'a>(checker: &'a Checker, value: &'a Expr) -> Option<&'a st let mut blank_key = false; let mut unique_key = false; for keyword in keywords.iter() { - let Expr::Constant(ast::ExprConstant {value: Bool(true), ..}) = &keyword.value else { - continue - }; let Some(argument) = &keyword.arg else { continue }; + if !is_const_true(&keyword.value) { + continue; + } match argument.as_str() { "blank" => blank_key = true, "null" => null_key = true, diff --git a/crates/ruff/src/rules/flake8_return/rules/function.rs b/crates/ruff/src/rules/flake8_return/rules/function.rs index 502f76d7ed..cae9574f5b 100644 --- a/crates/ruff/src/rules/flake8_return/rules/function.rs +++ b/crates/ruff/src/rules/flake8_return/rules/function.rs @@ -1,13 +1,13 @@ use std::ops::Add; use ruff_text_size::{TextRange, TextSize}; -use rustpython_parser::ast::{self, Constant, Expr, Ranged, Stmt}; +use rustpython_parser::ast::{self, Expr, Ranged, Stmt}; use ruff_diagnostics::{AlwaysAutofixableViolation, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::elif_else_range; use ruff_python_ast::helpers::is_const_none; +use ruff_python_ast::helpers::{elif_else_range, is_const_false, is_const_true}; use ruff_python_ast::visitor::Visitor; use ruff_python_ast::whitespace::indentation; use ruff_python_semantic::SemanticModel; @@ -339,13 +339,7 @@ fn unnecessary_return_none(checker: &mut Checker, stack: &Stack) { let Some(expr) = stmt.value.as_deref() else { continue; }; - if !matches!( - expr, - Expr::Constant(ast::ExprConstant { - value: Constant::None, - .. - }) - ) { + if !is_const_none(expr) { continue; } let mut diagnostic = Diagnostic::new(UnnecessaryReturnNone, stmt.range); @@ -433,22 +427,8 @@ fn implicit_return(checker: &mut Checker, stmt: &Stmt) { checker.diagnostics.push(diagnostic); } } - Stmt::Assert(ast::StmtAssert { test, .. }) - if matches!( - test.as_ref(), - Expr::Constant(ast::ExprConstant { - value: Constant::Bool(false), - .. - }) - ) => {} - Stmt::While(ast::StmtWhile { test, .. }) - if matches!( - test.as_ref(), - Expr::Constant(ast::ExprConstant { - value: Constant::Bool(true), - .. - }) - ) => {} + Stmt::Assert(ast::StmtAssert { test, .. }) if is_const_false(test) => {} + Stmt::While(ast::StmtWhile { test, .. }) if is_const_true(test) => {} Stmt::For(ast::StmtFor { orelse, .. }) | Stmt::AsyncFor(ast::StmtAsyncFor { orelse, .. }) | Stmt::While(ast::StmtWhile { orelse, .. }) => { diff --git a/crates/ruff/src/rules/flake8_simplify/rules/ast_expr.rs b/crates/ruff/src/rules/flake8_simplify/rules/ast_expr.rs index d8de3b0e8a..45424d41a9 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/ast_expr.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/ast_expr.rs @@ -3,6 +3,7 @@ use rustpython_parser::ast::{self, Constant, Expr, Ranged}; use ruff_diagnostics::{AlwaysAutofixableViolation, AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::helpers::is_const_none; use crate::checkers::ast::Checker; use crate::registry::AsRule; @@ -208,15 +209,9 @@ pub(crate) fn dict_get_with_none_default(checker: &mut Checker, expr: &Expr) { let Some(default) = args.get(1) else { return; }; - if !matches!( - default, - Expr::Constant(ast::ExprConstant { - value: Constant::None, - .. - }) - ) { + if !is_const_none(default) { return; - }; + } let expected = format!( "{}({})", diff --git a/crates/ruff/src/rules/pycodestyle/rules/literal_comparisons.rs b/crates/ruff/src/rules/pycodestyle/rules/literal_comparisons.rs index b3cfcddc30..53c67aaca9 100644 --- a/crates/ruff/src/rules/pycodestyle/rules/literal_comparisons.rs +++ b/crates/ruff/src/rules/pycodestyle/rules/literal_comparisons.rs @@ -5,6 +5,7 @@ use rustpython_parser::ast::{self, Cmpop, Constant, Expr, Ranged}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers; +use ruff_python_ast::helpers::is_const_none; use crate::checkers::ast::Checker; use crate::registry::AsRule; @@ -153,16 +154,7 @@ pub(crate) fn literal_comparisons( if !helpers::is_constant_non_singleton(next) { if let Some(op) = EqCmpop::try_from(*op) { - if check_none_comparisons - && matches!( - comparator, - Expr::Constant(ast::ExprConstant { - value: Constant::None, - kind: None, - range: _ - }) - ) - { + if check_none_comparisons && is_const_none(comparator) { match op { EqCmpop::Eq => { let diagnostic = Diagnostic::new(NoneComparison(op), comparator.range()); @@ -223,16 +215,7 @@ pub(crate) fn literal_comparisons( } if let Some(op) = EqCmpop::try_from(*op) { - if check_none_comparisons - && matches!( - next, - Expr::Constant(ast::ExprConstant { - value: Constant::None, - kind: None, - range: _ - }) - ) - { + if check_none_comparisons && is_const_none(next) { match op { EqCmpop::Eq => { let diagnostic = Diagnostic::new(NoneComparison(op), next.range()); diff --git a/crates/ruff/src/rules/pylint/rules/return_in_init.rs b/crates/ruff/src/rules/pylint/rules/return_in_init.rs index dbffa82463..0a6a81ebdc 100644 --- a/crates/ruff/src/rules/pylint/rules/return_in_init.rs +++ b/crates/ruff/src/rules/pylint/rules/return_in_init.rs @@ -1,7 +1,8 @@ -use rustpython_parser::ast::{self, Constant, Expr, Ranged, Stmt}; +use rustpython_parser::ast::{self, Ranged, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::helpers::is_const_none; use crate::checkers::ast::Checker; use crate::rules::pylint::helpers::in_dunder_init; @@ -46,13 +47,7 @@ impl Violation for ReturnInInit { pub(crate) fn return_in_init(checker: &mut Checker, stmt: &Stmt) { if let Stmt::Return(ast::StmtReturn { value, range: _ }) = stmt { if let Some(expr) = value { - if matches!( - expr.as_ref(), - Expr::Constant(ast::ExprConstant { - value: Constant::None, - .. - }) - ) { + if is_const_none(expr) { // Explicit `return None`. return; } diff --git a/crates/ruff/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs b/crates/ruff/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs index 277d472f0c..d6717f3cce 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs @@ -1,8 +1,9 @@ use ruff_text_size::TextRange; -use rustpython_parser::ast::{self, Constant, Decorator, Expr, Keyword, Ranged}; +use rustpython_parser::ast::{self, Decorator, Expr, Keyword, Ranged}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::helpers::is_const_none; use crate::checkers::ast::Checker; use crate::importer::ImportRequest; @@ -82,16 +83,7 @@ pub(crate) fn lru_cache_with_maxsize_none(checker: &mut Checker, decorator_list: value, range: _, } = &keywords[0]; - if arg.as_ref().map_or(false, |arg| arg == "maxsize") - && matches!( - value, - Expr::Constant(ast::ExprConstant { - value: Constant::None, - kind: None, - range: _, - }) - ) - { + if arg.as_ref().map_or(false, |arg| arg == "maxsize") && is_const_none(value) { let mut diagnostic = Diagnostic::new( LRUCacheWithMaxsizeNone, TextRange::new(func.end(), decorator.end()), diff --git a/crates/ruff/src/rules/ruff/rules/implicit_optional.rs b/crates/ruff/src/rules/ruff/rules/implicit_optional.rs index b95a9051bd..573122e469 100644 --- a/crates/ruff/src/rules/ruff/rules/implicit_optional.rs +++ b/crates/ruff/src/rules/ruff/rules/implicit_optional.rs @@ -5,6 +5,7 @@ use rustpython_parser::ast::{self, Arguments, Constant, Expr, Operator, Ranged}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::helpers::is_const_none; use ruff_python_semantic::SemanticModel; use ruff_text_size::TextRange; @@ -320,13 +321,7 @@ pub(crate) fn implicit_optional(checker: &mut Checker, arguments: &Arguments) { .zip(arguments.defaults.iter().rev()), ); for (arg, default) in arguments_with_defaults { - if !matches!( - default, - Expr::Constant(ast::ExprConstant { - value: Constant::None, - .. - }), - ) { + if !is_const_none(default) { continue; } let Some(annotation) = &arg.annotation else { diff --git a/crates/ruff_python_semantic/src/analyze/typing.rs b/crates/ruff_python_semantic/src/analyze/typing.rs index 30078a4d1e..8dea42177e 100644 --- a/crates/ruff_python_semantic/src/analyze/typing.rs +++ b/crates/ruff_python_semantic/src/analyze/typing.rs @@ -1,9 +1,10 @@ //! Analysis rules for the `typing` module. +use num_traits::identities::Zero; use rustpython_parser::ast::{self, Constant, Expr, Operator}; -use num_traits::identities::Zero; use ruff_python_ast::call_path::{from_qualified_name, from_unqualified_name, CallPath}; +use ruff_python_ast::helpers::is_const_false; use ruff_python_stdlib::typing::{ IMMUTABLE_GENERIC_TYPES, IMMUTABLE_TYPES, PEP_585_GENERICS, PEP_593_SUBSCRIPTS, SUBSCRIPTS, }; @@ -267,13 +268,7 @@ pub fn is_type_checking_block(stmt: &ast::StmtIf, semantic: &SemanticModel) -> b let ast::StmtIf { test, .. } = stmt; // Ex) `if False:` - if matches!( - test.as_ref(), - Expr::Constant(ast::ExprConstant { - value: Constant::Bool(false), - .. - }) - ) { + if is_const_false(test) { return true; }