From 8977b6ae11e09be24b6a09df98a12546b6ebaaba Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Tue, 31 Oct 2023 16:36:54 +0530 Subject: [PATCH] Inline AST helpers for new literal nodes (#8374) A small refactor to inline the `is_const_none` now that there's a dedicated `ExprNoneLiteral` node. --- .../rules/request_without_timeout.rs | 4 ++-- .../rules/zip_without_explicit_strict.rs | 6 ++--- .../rules/call_datetime_fromtimestamp.rs | 4 ++-- .../rules/call_datetime_now_without_tzinfo.rs | 11 ++++++--- .../rules/call_datetime_without_tzinfo.rs | 11 ++++++--- .../rules/flake8_datetimez/rules/helpers.rs | 3 +-- .../rules/flake8_print/rules/print_call.rs | 4 ++-- .../flake8_pyi/rules/exit_annotations.rs | 10 ++++---- .../src/rules/flake8_return/rules/function.rs | 6 ++--- .../rules/flake8_simplify/rules/ast_expr.rs | 3 +-- .../pycodestyle/rules/literal_comparisons.rs | 6 ++--- .../pycodestyle/rules/type_comparison.rs | 6 ++--- .../src/rules/pylint/rules/eq_without_hash.rs | 4 ++-- .../src/rules/pylint/rules/return_in_init.rs | 4 ++-- .../rules/subprocess_popen_preexec_fn.rs | 4 ++-- .../src/rules/pylint/rules/useless_return.rs | 9 ++++--- .../rules/lru_cache_with_maxsize_none.rs | 3 +-- .../src/rules/ruff/rules/implicit_optional.rs | 4 ++-- crates/ruff_python_ast/src/helpers.rs | 24 ++++++------------- 19 files changed, 63 insertions(+), 63 deletions(-) diff --git a/crates/ruff_linter/src/rules/flake8_bandit/rules/request_without_timeout.rs b/crates/ruff_linter/src/rules/flake8_bandit/rules/request_without_timeout.rs index 423e4a9026..5e37a2b693 100644 --- a/crates/ruff_linter/src/rules/flake8_bandit/rules/request_without_timeout.rs +++ b/crates/ruff_linter/src/rules/flake8_bandit/rules/request_without_timeout.rs @@ -1,7 +1,7 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast as ast; -use ruff_python_ast::helpers::is_const_none; + use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -64,7 +64,7 @@ pub(crate) fn request_without_timeout(checker: &mut Checker, call: &ast::ExprCal }) { if let Some(keyword) = call.arguments.find_keyword("timeout") { - if is_const_none(&keyword.value) { + if keyword.value.is_none_literal_expr() { checker.diagnostics.push(Diagnostic::new( RequestWithoutTimeout { implicit: false }, keyword.range(), diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs index c7a807a50c..b92168b348 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs @@ -1,6 +1,6 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::is_const_none; + use ruff_python_ast::{self as ast, Arguments, Expr}; use ruff_python_semantic::SemanticModel; use ruff_text_size::Ranged; @@ -81,14 +81,14 @@ fn is_infinite_iterator(arg: &Expr, semantic: &SemanticModel) -> bool { } // Ex) `itertools.repeat(1, None)` - if args.len() == 2 && is_const_none(&args[1]) { + if args.len() == 2 && args[1].is_none_literal_expr() { return true; } // Ex) `iterools.repeat(1, times=None)` for keyword in keywords { if keyword.arg.as_ref().is_some_and(|name| name == "times") { - if is_const_none(&keyword.value) { + if keyword.value.is_none_literal_expr() { return true; } } diff --git a/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_fromtimestamp.rs b/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_fromtimestamp.rs index 1db65f233e..d7942cb6be 100644 --- a/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_fromtimestamp.rs +++ b/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_fromtimestamp.rs @@ -1,6 +1,6 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::is_const_none; + use ruff_python_ast::{self as ast}; use ruff_text_size::Ranged; @@ -86,7 +86,7 @@ pub(crate) fn call_datetime_fromtimestamp(checker: &mut Checker, call: &ast::Exp } // none args - if call.arguments.args.len() > 1 && is_const_none(&call.arguments.args[1]) { + if call.arguments.args.len() > 1 && call.arguments.args[1].is_none_literal_expr() { checker .diagnostics .push(Diagnostic::new(CallDatetimeFromtimestamp, call.range())); diff --git a/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_now_without_tzinfo.rs b/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_now_without_tzinfo.rs index 1d7b839fd9..b2db88e8ff 100644 --- a/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_now_without_tzinfo.rs +++ b/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_now_without_tzinfo.rs @@ -1,7 +1,7 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::is_const_none; -use ruff_python_ast::{self as ast}; + +use ruff_python_ast::{self as ast, Expr}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -77,7 +77,12 @@ pub(crate) fn call_datetime_now_without_tzinfo(checker: &mut Checker, call: &ast } // none args - if call.arguments.args.first().is_some_and(is_const_none) { + if call + .arguments + .args + .first() + .is_some_and(Expr::is_none_literal_expr) + { checker .diagnostics .push(Diagnostic::new(CallDatetimeNowWithoutTzinfo, call.range())); diff --git a/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_without_tzinfo.rs b/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_without_tzinfo.rs index 4de1f85ac8..874bfde36b 100644 --- a/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_without_tzinfo.rs +++ b/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_without_tzinfo.rs @@ -1,7 +1,7 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::is_const_none; -use ruff_python_ast::{self as ast}; + +use ruff_python_ast::{self as ast, Expr}; use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -73,7 +73,12 @@ pub(crate) fn call_datetime_without_tzinfo(checker: &mut Checker, call: &ast::Ex } // Positional arg: is constant None. - if call.arguments.args.get(7).is_some_and(is_const_none) { + if call + .arguments + .args + .get(7) + .is_some_and(Expr::is_none_literal_expr) + { checker .diagnostics .push(Diagnostic::new(CallDatetimeWithoutTzinfo, call.range())); diff --git a/crates/ruff_linter/src/rules/flake8_datetimez/rules/helpers.rs b/crates/ruff_linter/src/rules/flake8_datetimez/rules/helpers.rs index 21ab64dc75..21912044d1 100644 --- a/crates/ruff_linter/src/rules/flake8_datetimez/rules/helpers.rs +++ b/crates/ruff_linter/src/rules/flake8_datetimez/rules/helpers.rs @@ -1,4 +1,3 @@ -use ruff_python_ast::helpers::is_const_none; use ruff_python_ast::{Arguments, Expr, ExprAttribute}; use crate::checkers::ast::Checker; @@ -15,5 +14,5 @@ pub(super) fn parent_expr_is_astimezone(checker: &Checker) -> bool { pub(super) fn has_non_none_keyword(arguments: &Arguments, keyword: &str) -> bool { arguments .find_keyword(keyword) - .is_some_and(|keyword| !is_const_none(&keyword.value)) + .is_some_and(|keyword| !keyword.value.is_none_literal_expr()) } diff --git a/crates/ruff_linter/src/rules/flake8_print/rules/print_call.rs b/crates/ruff_linter/src/rules/flake8_print/rules/print_call.rs index 5ce49ce83e..8cfa0a6f5c 100644 --- a/crates/ruff_linter/src/rules/flake8_print/rules/print_call.rs +++ b/crates/ruff_linter/src/rules/flake8_print/rules/print_call.rs @@ -1,6 +1,6 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::is_const_none; + use ruff_python_ast::{self as ast}; use ruff_text_size::Ranged; @@ -86,7 +86,7 @@ pub(crate) fn print_call(checker: &mut Checker, call: &ast::ExprCall) { // If the print call has a `file=` argument (that isn't `None`, `"sys.stdout"`, // or `"sys.stderr"`), don't trigger T201. if let Some(keyword) = call.arguments.find_keyword("file") { - if !is_const_none(&keyword.value) { + if !keyword.value.is_none_literal_expr() { if checker.semantic().resolve_call_path(&keyword.value).map_or( true, |call_path| { diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/exit_annotations.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/exit_annotations.rs index 4e21bb5641..64c78394b8 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/exit_annotations.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/exit_annotations.rs @@ -8,7 +8,7 @@ use smallvec::SmallVec; use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::is_const_none; + use ruff_python_semantic::SemanticModel; use ruff_text_size::Ranged; @@ -245,7 +245,7 @@ fn non_none_annotation_element<'a>( // E.g., `typing.Union` or `typing.Optional` if let Expr::Subscript(ExprSubscript { value, slice, .. }) = annotation { if semantic.match_typing_expr(value, "Optional") { - return if is_const_none(slice) { + return if slice.is_none_literal_expr() { None } else { Some(slice) @@ -264,7 +264,7 @@ fn non_none_annotation_element<'a>( return None; }; - return match (is_const_none(left), is_const_none(right)) { + return match (left.is_none_literal_expr(), right.is_none_literal_expr()) { (false, true) => Some(left), (true, false) => Some(right), (true, true) => None, @@ -280,11 +280,11 @@ fn non_none_annotation_element<'a>( .. }) = annotation { - if !is_const_none(left) { + if !left.is_none_literal_expr() { return Some(left); } - if !is_const_none(right) { + if !right.is_none_literal_expr() { return Some(right); } diff --git a/crates/ruff_linter/src/rules/flake8_return/rules/function.rs b/crates/ruff_linter/src/rules/flake8_return/rules/function.rs index eed24b12d6..396a157e9c 100644 --- a/crates/ruff_linter/src/rules/flake8_return/rules/function.rs +++ b/crates/ruff_linter/src/rules/flake8_return/rules/function.rs @@ -6,7 +6,7 @@ use ruff_text_size::{Ranged, TextRange, TextSize}; use ruff_diagnostics::{AlwaysFixableViolation, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::is_const_none; + use ruff_python_ast::helpers::{is_const_false, is_const_true}; use ruff_python_ast::stmt_if::elif_else_range; use ruff_python_ast::visitor::Visitor; @@ -341,7 +341,7 @@ fn unnecessary_return_none(checker: &mut Checker, stack: &Stack) { let Some(expr) = stmt.value.as_deref() else { continue; }; - if !is_const_none(expr) { + if !expr.is_none_literal_expr() { continue; } let mut diagnostic = Diagnostic::new(UnnecessaryReturnNone, stmt.range); @@ -682,7 +682,7 @@ pub(crate) fn function(checker: &mut Checker, body: &[Stmt], returns: Option<&Ex } else { if checker.enabled(Rule::UnnecessaryReturnNone) { // Skip functions that have a return annotation that is not `None`. - if returns.map_or(true, is_const_none) { + if returns.map_or(true, Expr::is_none_literal_expr) { unnecessary_return_none(checker, &stack); } } diff --git a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs index b0e85b4f27..d9f6657215 100644 --- a/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs +++ b/crates/ruff_linter/src/rules/flake8_simplify/rules/ast_expr.rs @@ -4,7 +4,6 @@ use ruff_text_size::Ranged; use crate::fix::snippet::SourceCodeSnippet; use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::is_const_none; use crate::checkers::ast::Checker; @@ -260,7 +259,7 @@ pub(crate) fn dict_get_with_none_default(checker: &mut Checker, expr: &Expr) { let Some(default) = args.get(1) else { return; }; - if !is_const_none(default) { + if !default.is_none_literal_expr() { return; } diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/literal_comparisons.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/literal_comparisons.rs index 3af9eb4e1a..8d650d4a25 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/literal_comparisons.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/literal_comparisons.rs @@ -3,7 +3,7 @@ use rustc_hash::FxHashMap; use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers; -use ruff_python_ast::helpers::{generate_comparison, is_const_none}; +use ruff_python_ast::helpers::generate_comparison; use ruff_python_ast::{self as ast, CmpOp, Expr}; use ruff_text_size::Ranged; @@ -148,7 +148,7 @@ pub(crate) fn literal_comparisons(checker: &mut Checker, compare: &ast::ExprComp if !helpers::is_constant_non_singleton(next) { if let Some(op) = EqCmpOp::try_from(*op) { - if checker.enabled(Rule::NoneComparison) && is_const_none(comparator) { + if checker.enabled(Rule::NoneComparison) && comparator.is_none_literal_expr() { match op { EqCmpOp::Eq => { let diagnostic = Diagnostic::new(NoneComparison(op), comparator.range()); @@ -204,7 +204,7 @@ pub(crate) fn literal_comparisons(checker: &mut Checker, compare: &ast::ExprComp continue; }; - if checker.enabled(Rule::NoneComparison) && is_const_none(next) { + if checker.enabled(Rule::NoneComparison) && next.is_none_literal_expr() { match op { EqCmpOp::Eq => { let diagnostic = Diagnostic::new(NoneComparison(op), next.range()); diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/type_comparison.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/type_comparison.rs index 1a7c3a67c7..73fdd6c8d8 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/type_comparison.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/type_comparison.rs @@ -1,7 +1,7 @@ use itertools::Itertools; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::is_const_none; + use ruff_python_ast::{self as ast, CmpOp, Expr}; use ruff_python_semantic::SemanticModel; use ruff_text_size::Ranged; @@ -99,7 +99,7 @@ fn deprecated_type_comparison(checker: &mut Checker, compare: &ast::ExprCompare) if arguments .args .first() - .is_some_and(|arg| !arg.is_name_expr() && !is_const_none(arg)) + .is_some_and(|arg| !arg.is_name_expr() && !arg.is_none_literal_expr()) { checker.diagnostics.push(Diagnostic::new( TypeComparison { @@ -191,7 +191,7 @@ fn is_type(expr: &Expr, semantic: &SemanticModel) -> bool { arguments .args .first() - .is_some_and(|arg| !arg.is_name_expr() && !is_const_none(arg)) + .is_some_and(|arg| !arg.is_name_expr() && !arg.is_none_literal_expr()) } Expr::Name(ast::ExprName { id, .. }) => { // Ex) `type(obj) == int` diff --git a/crates/ruff_linter/src/rules/pylint/rules/eq_without_hash.rs b/crates/ruff_linter/src/rules/pylint/rules/eq_without_hash.rs index 8add44f2c2..e8c3b1ad14 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/eq_without_hash.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/eq_without_hash.rs @@ -1,6 +1,6 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::is_const_none; + use ruff_python_ast::{self as ast, Expr, Stmt}; use ruff_text_size::Ranged; @@ -80,7 +80,7 @@ fn has_eq_without_hash(body: &[Stmt]) -> bool { // // __hash__ = None // ``` - if id == "__hash__" && is_const_none(value) { + if id == "__hash__" && value.is_none_literal_expr() { has_hash = true; } } diff --git a/crates/ruff_linter/src/rules/pylint/rules/return_in_init.rs b/crates/ruff_linter/src/rules/pylint/rules/return_in_init.rs index 2357527254..52e3ecfc5f 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/return_in_init.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/return_in_init.rs @@ -2,7 +2,7 @@ use ruff_python_ast::{self as ast, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::is_const_none; + use ruff_text_size::Ranged; use crate::checkers::ast::Checker; @@ -48,7 +48,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 is_const_none(expr) { + if expr.is_none_literal_expr() { // Explicit `return None`. return; } diff --git a/crates/ruff_linter/src/rules/pylint/rules/subprocess_popen_preexec_fn.rs b/crates/ruff_linter/src/rules/pylint/rules/subprocess_popen_preexec_fn.rs index a5cf3ad75d..bb93faa0bd 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/subprocess_popen_preexec_fn.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/subprocess_popen_preexec_fn.rs @@ -1,6 +1,6 @@ use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::is_const_none; + use ruff_python_ast::{self as ast}; use ruff_text_size::Ranged; @@ -58,7 +58,7 @@ pub(crate) fn subprocess_popen_preexec_fn(checker: &mut Checker, call: &ast::Exp if let Some(keyword) = call .arguments .find_keyword("preexec_fn") - .filter(|keyword| !is_const_none(&keyword.value)) + .filter(|keyword| !keyword.value.is_none_literal_expr()) { checker .diagnostics diff --git a/crates/ruff_linter/src/rules/pylint/rules/useless_return.rs b/crates/ruff_linter/src/rules/pylint/rules/useless_return.rs index 581b2036f5..f9ba04041c 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/useless_return.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/useless_return.rs @@ -2,7 +2,7 @@ use ruff_python_ast::{self as ast, Expr, Stmt}; use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::{is_const_none, ReturnStatementVisitor}; +use ruff_python_ast::helpers::ReturnStatementVisitor; use ruff_python_ast::statement_visitor::StatementVisitor; use ruff_text_size::Ranged; @@ -51,7 +51,7 @@ pub(crate) fn useless_return( returns: Option<&Expr>, ) { // Skip functions that have a return annotation that is not `None`. - if !returns.map_or(true, is_const_none) { + if !returns.map_or(true, Expr::is_none_literal_expr) { return; } @@ -84,7 +84,10 @@ pub(crate) fn useless_return( }; // Verify that the return statement is either bare or returns `None`. - if !value.as_ref().map_or(true, |expr| is_const_none(expr)) { + if !value + .as_ref() + .map_or(true, |expr| expr.is_none_literal_expr()) + { return; }; diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs index 837a7bafdf..3a32210ee6 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs @@ -3,7 +3,6 @@ use ruff_text_size::{Ranged, TextRange}; use ruff_diagnostics::{AlwaysFixableViolation, 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; @@ -85,7 +84,7 @@ pub(crate) fn lru_cache_with_maxsize_none(checker: &mut Checker, decorator_list: value, range: _, } = &keywords[0]; - if arg.as_ref().is_some_and(|arg| arg == "maxsize") && is_const_none(value) { + if arg.as_ref().is_some_and(|arg| arg == "maxsize") && value.is_none_literal_expr() { let mut diagnostic = Diagnostic::new( LRUCacheWithMaxsizeNone, TextRange::new(func.end(), decorator.end()), diff --git a/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs b/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs index 0707c57bb0..db23de636b 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs @@ -4,7 +4,7 @@ use anyhow::Result; use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_macros::{derive_message_formats, violation}; -use ruff_python_ast::helpers::is_const_none; + use ruff_python_ast::{self as ast, Expr, Operator, ParameterWithDefault, Parameters}; use ruff_python_parser::typing::parse_type_annotation; use ruff_text_size::{Ranged, TextRange}; @@ -174,7 +174,7 @@ pub(crate) fn implicit_optional(checker: &mut Checker, parameters: &Parameters) .chain(¶meters.kwonlyargs) { let Some(default) = default else { continue }; - if !is_const_none(default) { + if !default.is_none_literal_expr() { continue; } let Some(annotation) = ¶meter.annotation else { diff --git a/crates/ruff_python_ast/src/helpers.rs b/crates/ruff_python_ast/src/helpers.rs index e182403605..c3c2b71254 100644 --- a/crates/ruff_python_ast/src/helpers.rs +++ b/crates/ruff_python_ast/src/helpers.rs @@ -576,17 +576,12 @@ pub const fn is_singleton(expr: &Expr) -> bool { ) } -/// Return `true` if the [`Expr`] is a constant or tuple of constants. +/// Return `true` if the [`Expr`] is a literal or tuple of literals. pub fn is_constant(expr: &Expr) -> bool { - match expr { - Expr::StringLiteral(_) - | Expr::BytesLiteral(_) - | Expr::NumberLiteral(_) - | Expr::BooleanLiteral(_) - | Expr::NoneLiteral(_) - | Expr::EllipsisLiteral(_) => true, - Expr::Tuple(ast::ExprTuple { elts, .. }) => elts.iter().all(is_constant), - _ => false, + if let Expr::Tuple(ast::ExprTuple { elts, .. }) = expr { + elts.iter().all(is_constant) + } else { + expr.is_literal_expr() } } @@ -595,12 +590,7 @@ pub fn is_constant_non_singleton(expr: &Expr) -> bool { is_constant(expr) && !is_singleton(expr) } -/// Return `true` if an [`Expr`] is `None`. -pub const fn is_const_none(expr: &Expr) -> bool { - expr.is_none_literal_expr() -} - -/// Return `true` if an [`Expr`] is `True`. +/// Return `true` if an [`Expr`] is a literal `True`. pub const fn is_const_true(expr: &Expr) -> bool { matches!( expr, @@ -608,7 +598,7 @@ pub const fn is_const_true(expr: &Expr) -> bool { ) } -/// Return `true` if an [`Expr`] is `False`. +/// Return `true` if an [`Expr`] is a literal `False`. pub const fn is_const_false(expr: &Expr) -> bool { matches!( expr,