Replace .map_or(false, $closure) with .is_some_and(closure) (#6244)

**Summary**
[Option::is_some_and](https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.is_some_and)
and
[Result::is_ok_and](https://doc.rust-lang.org/std/result/enum.Result.html#method.is_ok_and)
are new methods is rust 1.70. I find them way more readable than
`.map_or(false, ...)`.

The changes are `s/.map_or(false,/.is_some_and(/g`, then manually
switching to `is_ok_and` where the value is a Result rather than an
Option.

**Test Plan** n/a^
This commit is contained in:
konsti 2023-08-01 19:29:42 +02:00 committed by GitHub
parent 2e1754e5fc
commit 1df7e9831b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
162 changed files with 344 additions and 476 deletions

View file

@ -76,7 +76,7 @@ fn apply_fixes<'a>(
} }
// If this fix overlaps with a fix we've already applied, skip it. // If this fix overlaps with a fix we've already applied, skip it.
if last_pos.map_or(false, |last_pos| last_pos >= first.start()) { if last_pos.is_some_and(|last_pos| last_pos >= first.start()) {
continue; continue;
} }
} }

View file

@ -117,7 +117,7 @@ pub(crate) fn definitions(checker: &mut Checker) {
// interfaces, without any AST nodes in between. Right now, we // interfaces, without any AST nodes in between. Right now, we
// only error when traversing definition boundaries (functions, // only error when traversing definition boundaries (functions,
// classes, etc.). // classes, etc.).
if !overloaded_name.map_or(false, |overloaded_name| { if !overloaded_name.is_some_and(|overloaded_name| {
flake8_annotations::helpers::is_overload_impl( flake8_annotations::helpers::is_overload_impl(
definition, definition,
&overloaded_name, &overloaded_name,

View file

@ -201,14 +201,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
if checker.enabled(Rule::NonLowercaseVariableInFunction) { if checker.enabled(Rule::NonLowercaseVariableInFunction) {
if checker.semantic.scope().kind.is_any_function() { if checker.semantic.scope().kind.is_any_function() {
// Ignore globals. // Ignore globals.
if !checker if !checker.semantic.scope().get(id).is_some_and(|binding_id| {
.semantic checker.semantic.binding(binding_id).is_global()
.scope() }) {
.get(id)
.map_or(false, |binding_id| {
checker.semantic.binding(binding_id).is_global()
})
{
pep8_naming::rules::non_lowercase_variable_in_function( pep8_naming::rules::non_lowercase_variable_in_function(
checker, expr, id, checker, expr, id,
); );

View file

@ -339,7 +339,7 @@ where
if alias if alias
.asname .asname
.as_ref() .as_ref()
.map_or(false, |asname| asname.as_str() == alias.name.as_str()) .is_some_and(|asname| asname.as_str() == alias.name.as_str())
{ {
flags |= BindingFlags::EXPLICIT_EXPORT; flags |= BindingFlags::EXPLICIT_EXPORT;
} }
@ -384,7 +384,7 @@ where
if alias if alias
.asname .asname
.as_ref() .as_ref()
.map_or(false, |asname| asname.as_str() == alias.name.as_str()) .is_some_and(|asname| asname.as_str() == alias.name.as_str())
{ {
flags |= BindingFlags::EXPLICIT_EXPORT; flags |= BindingFlags::EXPLICIT_EXPORT;
} }
@ -1103,7 +1103,7 @@ where
arg, arg,
range: _, range: _,
} = keyword; } = keyword;
if arg.as_ref().map_or(false, |arg| arg == "type") { if arg.as_ref().is_some_and(|arg| arg == "type") {
self.visit_type_definition(value); self.visit_type_definition(value);
} else { } else {
self.visit_non_type_definition(value); self.visit_non_type_definition(value);

View file

@ -402,7 +402,7 @@ fn is_docstring_section(
} }
// Determine whether the next line is an underline, e.g., "-----". // Determine whether the next line is an underline, e.g., "-----".
let next_line_is_underline = next_line.map_or(false, |next_line| { let next_line_is_underline = next_line.is_some_and(|next_line| {
let next_line = next_line.trim(); let next_line = next_line.trim();
if next_line.is_empty() { if next_line.is_empty() {
false false

View file

@ -305,7 +305,7 @@ impl<'a> Importer<'a> {
}) = stmt }) = stmt
{ {
if level.map_or(true, |level| level.to_u32() == 0) if level.map_or(true, |level| level.to_u32() == 0)
&& name.as_ref().map_or(false, |name| name == module) && name.as_ref().is_some_and(|name| name == module)
{ {
import_from = Some(*stmt); import_from = Some(*stmt);
} }

View file

@ -376,7 +376,7 @@ impl Notebook {
1 1
} else { } else {
let trailing_newline = let trailing_newline =
usize::from(string_array.last().map_or(false, |s| s.ends_with('\n'))); usize::from(string_array.last().is_some_and(|s| s.ends_with('\n')));
u32::try_from(string_array.len() + trailing_newline).unwrap() u32::try_from(string_array.len() + trailing_newline).unwrap()
} }
} }

View file

@ -141,7 +141,7 @@ impl<'a> EmitterContext<'a> {
pub fn is_jupyter_notebook(&self, name: &str) -> bool { pub fn is_jupyter_notebook(&self, name: &str) -> bool {
self.source_kind self.source_kind
.get(name) .get(name)
.map_or(false, SourceKind::is_jupyter) .is_some_and(SourceKind::is_jupyter)
} }
pub fn source_kind(&self, name: &str) -> Option<&SourceKind> { pub fn source_kind(&self, name: &str) -> Option<&SourceKind> {

View file

@ -60,7 +60,7 @@ impl<'a> Directive<'a> {
if text[..comment_start] if text[..comment_start]
.chars() .chars()
.last() .last()
.map_or(false, |c| c != '#') .is_some_and(|c| c != '#')
{ {
continue; continue;
} }

View file

@ -304,7 +304,7 @@ pub fn python_files_in_path(
if let Ok(entry) = &result { if let Ok(entry) = &result {
if entry if entry
.file_type() .file_type()
.map_or(false, |file_type| file_type.is_dir()) .is_some_and(|file_type| file_type.is_dir())
{ {
match settings_toml(entry.path()) { match settings_toml(entry.path()) {
Ok(Some(pyproject)) => match resolve_scoped_settings( Ok(Some(pyproject)) => match resolve_scoped_settings(

View file

@ -68,7 +68,7 @@ pub(crate) fn variable_name_task_id(
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| matches!(call_path[0], "airflow")) .is_some_and(|call_path| matches!(call_path[0], "airflow"))
{ {
return None; return None;
} }

View file

@ -5,5 +5,5 @@ use ruff_python_semantic::SemanticModel;
pub(super) fn is_sys(expr: &Expr, target: &str, semantic: &SemanticModel) -> bool { pub(super) fn is_sys(expr: &Expr, target: &str, semantic: &SemanticModel) -> bool {
semantic semantic
.resolve_call_path(expr) .resolve_call_path(expr)
.map_or(false, |call_path| call_path.as_slice() == ["sys", target]) .is_some_and(|call_path| call_path.as_slice() == ["sys", target])
} }

View file

@ -49,9 +49,7 @@ pub(crate) fn name_or_attribute(checker: &mut Checker, expr: &Expr) {
if checker if checker
.semantic() .semantic()
.resolve_call_path(expr) .resolve_call_path(expr)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["six", "PY3"]))
matches!(call_path.as_slice(), ["six", "PY3"])
})
{ {
checker checker
.diagnostics .diagnostics

View file

@ -68,7 +68,7 @@ pub(crate) fn blocking_http_call(checker: &mut Checker, expr: &Expr) {
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.as_ref() .as_ref()
.map_or(false, is_blocking_http_call) .is_some_and(is_blocking_http_call)
{ {
checker.diagnostics.push(Diagnostic::new( checker.diagnostics.push(Diagnostic::new(
BlockingHttpCallInAsyncFunction, BlockingHttpCallInAsyncFunction,

View file

@ -48,7 +48,7 @@ pub(crate) fn blocking_os_call(checker: &mut Checker, expr: &Expr) {
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.as_ref() .as_ref()
.map_or(false, is_unsafe_os_method) .is_some_and(is_unsafe_os_method)
{ {
checker checker
.diagnostics .diagnostics

View file

@ -48,7 +48,7 @@ pub(crate) fn open_sleep_or_subprocess_call(checker: &mut Checker, expr: &Expr)
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.as_ref() .as_ref()
.map_or(false, is_open_sleep_or_subprocess_call) .is_some_and(is_open_sleep_or_subprocess_call)
{ {
checker.diagnostics.push(Diagnostic::new( checker.diagnostics.push(Diagnostic::new(
OpenSleepOrSubprocessInAsyncFunction, OpenSleepOrSubprocessInAsyncFunction,

View file

@ -26,18 +26,14 @@ pub(super) fn is_untyped_exception(type_: Option<&Expr>, semantic: &SemanticMode
type_.map_or(true, |type_| { type_.map_or(true, |type_| {
if let Expr::Tuple(ast::ExprTuple { elts, .. }) = &type_ { if let Expr::Tuple(ast::ExprTuple { elts, .. }) = &type_ {
elts.iter().any(|type_| { elts.iter().any(|type_| {
semantic semantic.resolve_call_path(type_).is_some_and(|call_path| {
.resolve_call_path(type_)
.map_or(false, |call_path| {
matches!(call_path.as_slice(), ["", "Exception" | "BaseException"])
})
})
} else {
semantic
.resolve_call_path(type_)
.map_or(false, |call_path| {
matches!(call_path.as_slice(), ["", "Exception" | "BaseException"]) matches!(call_path.as_slice(), ["", "Exception" | "BaseException"])
}) })
})
} else {
semantic.resolve_call_path(type_).is_some_and(|call_path| {
matches!(call_path.as_slice(), ["", "Exception" | "BaseException"])
})
} }
}) })
} }

View file

@ -57,9 +57,7 @@ pub(crate) fn bad_file_permissions(
if checker if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["os", "chmod"]))
matches!(call_path.as_slice(), ["os", "chmod"])
})
{ {
let call_args = CallArguments::new(args, keywords); let call_args = CallArguments::new(args, keywords);
if let Some(mode_arg) = call_args.argument("mode", 1) { if let Some(mode_arg) = call_args.argument("mode", 1) {

View file

@ -35,9 +35,7 @@ pub(crate) fn exec_used(checker: &mut Checker, func: &Expr) {
if checker if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["" | "builtin", "exec"]))
matches!(call_path.as_slice(), ["" | "builtin", "exec"])
})
{ {
checker checker
.diagnostics .diagnostics

View file

@ -63,9 +63,7 @@ pub(crate) fn jinja2_autoescape_false(checker: &mut Checker, func: &Expr, keywor
if checker if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["jinja2", "Environment"]))
matches!(call_path.as_slice(), ["jinja2", "Environment"])
})
{ {
if let Some(keyword) = find_keyword(keywords, "autoescape") { if let Some(keyword) = find_keyword(keywords, "autoescape") {
match &keyword.value { match &keyword.value {

View file

@ -43,9 +43,7 @@ pub(crate) fn logging_config_insecure_listen(
if checker if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["logging", "config", "listen"]))
matches!(call_path.as_slice(), ["logging", "config", "listen"])
})
{ {
if find_keyword(keywords, "verify").is_some() { if find_keyword(keywords, "verify").is_some() {
return; return;

View file

@ -39,9 +39,7 @@ pub(crate) fn paramiko_call(checker: &mut Checker, func: &Expr) {
if checker if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["paramiko", "exec_command"]))
matches!(call_path.as_slice(), ["paramiko", "exec_command"])
})
{ {
checker checker
.diagnostics .diagnostics

View file

@ -53,7 +53,7 @@ pub(crate) fn request_without_timeout(checker: &mut Checker, func: &Expr, keywor
if checker if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),
[ [

View file

@ -379,7 +379,7 @@ fn is_partial_path(expr: &Expr) -> bool {
Expr::List(ast::ExprList { elts, .. }) => elts.first().and_then(string_literal), Expr::List(ast::ExprList { elts, .. }) => elts.first().and_then(string_literal),
_ => string_literal(expr), _ => string_literal(expr),
}; };
string_literal.map_or(false, |text| !is_full_path(text)) string_literal.is_some_and(|text| !is_full_path(text))
} }
/// Return `true` if the [`Expr`] is a wildcard command. /// Return `true` if the [`Expr`] is a wildcard command.
@ -410,7 +410,7 @@ fn is_wildcard_command(expr: &Expr) -> bool {
has_star && has_command has_star && has_command
} else { } else {
let string_literal = string_literal(expr); let string_literal = string_literal(expr);
string_literal.map_or(false, |text| { string_literal.is_some_and(|text| {
text.contains('*') text.contains('*')
&& (text.contains("chown") && (text.contains("chown")
|| text.contains("chmod") || text.contains("chmod")

View file

@ -47,7 +47,7 @@ pub(crate) fn snmp_insecure_version(checker: &mut Checker, func: &Expr, keywords
if checker if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!(call_path.as_slice(), ["pysnmp", "hlapi", "CommunityData"]) matches!(call_path.as_slice(), ["pysnmp", "hlapi", "CommunityData"])
}) })
{ {

View file

@ -51,9 +51,7 @@ pub(crate) fn snmp_weak_cryptography(
if checker if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["pysnmp", "hlapi", "UsmUserData"]))
matches!(call_path.as_slice(), ["pysnmp", "hlapi", "UsmUserData"])
})
{ {
if CallArguments::new(args, keywords).len() < 3 { if CallArguments::new(args, keywords).len() < 3 {
checker checker

View file

@ -69,16 +69,14 @@ pub(crate) fn unsafe_yaml_load(
if checker if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["yaml", "load"]))
matches!(call_path.as_slice(), ["yaml", "load"])
})
{ {
let call_args = CallArguments::new(args, keywords); let call_args = CallArguments::new(args, keywords);
if let Some(loader_arg) = call_args.argument("Loader", 1) { if let Some(loader_arg) = call_args.argument("Loader", 1) {
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(loader_arg) .resolve_call_path(loader_arg)
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!(call_path.as_slice(), ["yaml", "SafeLoader" | "CSafeLoader"]) matches!(call_path.as_slice(), ["yaml", "SafeLoader" | "CSafeLoader"])
}) })
{ {

View file

@ -77,7 +77,7 @@ pub(crate) fn blind_except(
if let Stmt::Raise(ast::StmtRaise { exc, .. }) = stmt { if let Stmt::Raise(ast::StmtRaise { exc, .. }) = stmt {
if let Some(exc) = exc { if let Some(exc) = exc {
if let Expr::Name(ast::ExprName { id, .. }) = exc.as_ref() { if let Expr::Name(ast::ExprName { id, .. }) = exc.as_ref() {
name.map_or(false, |name| id == name) name.is_some_and(|name| id == name)
} else { } else {
false false
} }

View file

@ -67,7 +67,7 @@ pub(crate) fn check_boolean_default_value_in_function_definition(
if decorator_list.iter().any(|decorator| { if decorator_list.iter().any(|decorator| {
collect_call_path(&decorator.expression) collect_call_path(&decorator.expression)
.map_or(false, |call_path| call_path.as_slice() == [name, "setter"]) .is_some_and(|call_path| call_path.as_slice() == [name, "setter"])
}) { }) {
return; return;
} }

View file

@ -88,7 +88,7 @@ pub(crate) fn check_positional_boolean_in_def(
if decorator_list.iter().any(|decorator| { if decorator_list.iter().any(|decorator| {
collect_call_path(&decorator.expression) collect_call_path(&decorator.expression)
.map_or(false, |call_path| call_path.as_slice() == [name, "setter"]) .is_some_and(|call_path| call_path.as_slice() == [name, "setter"])
}) { }) {
return; return;
} }

View file

@ -106,16 +106,14 @@ impl Violation for EmptyMethodWithoutAbstractDecorator {
fn is_abc_class(bases: &[Expr], keywords: &[Keyword], semantic: &SemanticModel) -> bool { fn is_abc_class(bases: &[Expr], keywords: &[Keyword], semantic: &SemanticModel) -> bool {
keywords.iter().any(|keyword| { keywords.iter().any(|keyword| {
keyword.arg.as_ref().map_or(false, |arg| arg == "metaclass") keyword.arg.as_ref().is_some_and(|arg| arg == "metaclass")
&& semantic && semantic
.resolve_call_path(&keyword.value) .resolve_call_path(&keyword.value)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["abc", "ABCMeta"]))
matches!(call_path.as_slice(), ["abc", "ABCMeta"])
})
}) || bases.iter().any(|base| { }) || bases.iter().any(|base| {
semantic.resolve_call_path(base).map_or(false, |call_path| { semantic
matches!(call_path.as_slice(), ["abc", "ABC"]) .resolve_call_path(base)
}) .is_some_and(|call_path| matches!(call_path.as_slice(), ["abc", "ABC"]))
}) })
} }

View file

@ -113,9 +113,7 @@ pub(crate) fn assert_raises_exception(checker: &mut Checker, items: &[WithItem])
} else if checker } else if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["pytest", "raises"]))
matches!(call_path.as_slice(), ["pytest", "raises"])
})
&& find_keyword(keywords, "match").is_none() && find_keyword(keywords, "match").is_none()
{ {
AssertionKind::PytestRaises AssertionKind::PytestRaises

View file

@ -70,7 +70,7 @@ impl Violation for CachedInstanceMethod {
} }
fn is_cache_func(expr: &Expr, semantic: &SemanticModel) -> bool { fn is_cache_func(expr: &Expr, semantic: &SemanticModel) -> bool {
semantic.resolve_call_path(expr).map_or(false, |call_path| { semantic.resolve_call_path(expr).is_some_and(|call_path| {
matches!(call_path.as_slice(), ["functools", "lru_cache" | "cache"]) matches!(call_path.as_slice(), ["functools", "lru_cache" | "cache"])
}) })
} }

View file

@ -157,7 +157,7 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> {
} }
for keyword in keywords { for keyword in keywords {
if keyword.arg.as_ref().map_or(false, |arg| arg == "key") if keyword.arg.as_ref().is_some_and(|arg| arg == "key")
&& keyword.value.is_lambda_expr() && keyword.value.is_lambda_expr()
{ {
self.safe_functions.push(&keyword.value); self.safe_functions.push(&keyword.value);

View file

@ -74,9 +74,10 @@ pub(crate) fn mutable_argument_default(checker: &mut Checker, arguments: &Argume
}; };
if is_mutable_expr(default, checker.semantic()) if is_mutable_expr(default, checker.semantic())
&& !def.annotation.as_ref().map_or(false, |expr| { && !def
is_immutable_annotation(expr, checker.semantic()) .annotation
}) .as_ref()
.is_some_and(|expr| is_immutable_annotation(expr, checker.semantic()))
{ {
checker checker
.diagnostics .diagnostics

View file

@ -42,9 +42,7 @@ pub(crate) fn no_explicit_stacklevel(checker: &mut Checker, func: &Expr, keyword
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["warnings", "warn"]))
matches!(call_path.as_slice(), ["warnings", "warn"])
})
{ {
return; return;
} }

View file

@ -87,7 +87,7 @@ pub(crate) fn raise_without_from_inside_except(
if let Some(name) = name { if let Some(name) = name {
if exc if exc
.as_name_expr() .as_name_expr()
.map_or(false, |ast::ExprName { id, .. }| name == id) .is_some_and(|ast::ExprName { id, .. }| name == id)
{ {
continue; continue;
} }

View file

@ -313,9 +313,7 @@ pub(crate) fn reuse_of_groupby_generator(
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["itertools", "groupby"]))
matches!(call_path.as_slice(), ["itertools", "groupby"])
})
{ {
return; return;
} }

View file

@ -59,9 +59,7 @@ pub(crate) fn useless_contextlib_suppress(
&& checker && checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["contextlib", "suppress"]))
matches!(call_path.as_slice(), ["contextlib", "suppress"])
})
{ {
checker checker
.diagnostics .diagnostics

View file

@ -76,7 +76,7 @@ fn is_infinite_iterator(arg: &Expr, semantic: &SemanticModel) -> bool {
return false; return false;
}; };
semantic.resolve_call_path(func).map_or(false, |call_path| { semantic.resolve_call_path(func).is_some_and(|call_path| {
match call_path.as_slice() { match call_path.as_slice() {
["itertools", "cycle" | "count"] => true, ["itertools", "cycle" | "count"] => true,
["itertools", "repeat"] => { ["itertools", "repeat"] => {
@ -92,7 +92,7 @@ fn is_infinite_iterator(arg: &Expr, semantic: &SemanticModel) -> bool {
// Ex) `iterools.repeat(1, times=None)` // Ex) `iterools.repeat(1, times=None)`
for keyword in keywords { for keyword in keywords {
if keyword.arg.as_ref().map_or(false, |name| name == "times") { if keyword.arg.as_ref().is_some_and(|name| name == "times") {
if is_const_none(&keyword.value) { if is_const_none(&keyword.value) {
return true; return true;
} }

View file

@ -136,15 +136,15 @@ fn is_standard_library_override(
match name { match name {
// Ex) `Event#set` // Ex) `Event#set`
"set" => class_def.bases.iter().any(|base| { "set" => class_def.bases.iter().any(|base| {
model.resolve_call_path(base).map_or(false, |call_path| { model
matches!(call_path.as_slice(), ["threading", "Event"]) .resolve_call_path(base)
}) .is_some_and(|call_path| matches!(call_path.as_slice(), ["threading", "Event"]))
}), }),
// Ex) `Filter#filter` // Ex) `Filter#filter`
"filter" => class_def.bases.iter().any(|base| { "filter" => class_def.bases.iter().any(|base| {
model.resolve_call_path(base).map_or(false, |call_path| { model
matches!(call_path.as_slice(), ["logging", "Filter"]) .resolve_call_path(base)
}) .is_some_and(|call_path| matches!(call_path.as_slice(), ["logging", "Filter"]))
}), }),
_ => false, _ => false,
} }

View file

@ -1018,7 +1018,7 @@ pub(crate) fn fix_unnecessary_map(
// If the expression is embedded in an f-string, surround it with spaces to avoid // If the expression is embedded in an f-string, surround it with spaces to avoid
// syntax errors. // syntax errors.
if matches!(object_type, ObjectType::Set | ObjectType::Dict) { if matches!(object_type, ObjectType::Set | ObjectType::Dict) {
if parent.map_or(false, ruff_python_ast::Expr::is_formatted_value_expr) { if parent.is_some_and(ruff_python_ast::Expr::is_formatted_value_expr) {
content = format!(" {content} "); content = format!(" {content} ");
} }
} }

View file

@ -29,7 +29,7 @@ pub(crate) fn call_date_fromtimestamp(checker: &mut Checker, func: &Expr, locati
if checker if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!(call_path.as_slice(), ["datetime", "date", "fromtimestamp"]) matches!(call_path.as_slice(), ["datetime", "date", "fromtimestamp"])
}) })
{ {

View file

@ -29,9 +29,7 @@ pub(crate) fn call_date_today(checker: &mut Checker, func: &Expr, location: Text
if checker if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["datetime", "date", "today"]))
matches!(call_path.as_slice(), ["datetime", "date", "today"])
})
{ {
checker checker
.diagnostics .diagnostics

View file

@ -32,7 +32,7 @@ pub(crate) fn call_datetime_fromtimestamp(
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),
["datetime", "datetime", "fromtimestamp"] ["datetime", "datetime", "fromtimestamp"]

View file

@ -30,9 +30,7 @@ pub(crate) fn call_datetime_now_without_tzinfo(
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["datetime", "datetime", "now"]))
matches!(call_path.as_slice(), ["datetime", "datetime", "now"])
})
{ {
return; return;
} }

View file

@ -30,7 +30,7 @@ pub(crate) fn call_datetime_strptime_without_zone(
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!(call_path.as_slice(), ["datetime", "datetime", "strptime"]) matches!(call_path.as_slice(), ["datetime", "datetime", "strptime"])
}) })
{ {

View file

@ -59,9 +59,7 @@ pub(crate) fn call_datetime_today(checker: &mut Checker, func: &Expr, location:
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["datetime", "datetime", "today"]))
matches!(call_path.as_slice(), ["datetime", "datetime", "today"])
})
{ {
return; return;
} }

View file

@ -38,7 +38,7 @@ pub(crate) fn call_datetime_utcfromtimestamp(
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),
["datetime", "datetime", "utcfromtimestamp"] ["datetime", "datetime", "utcfromtimestamp"]

View file

@ -33,9 +33,7 @@ pub(crate) fn call_datetime_utcnow(checker: &mut Checker, func: &Expr, location:
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["datetime", "datetime", "utcnow"]))
matches!(call_path.as_slice(), ["datetime", "datetime", "utcnow"])
})
{ {
return; return;
} }

View file

@ -54,9 +54,7 @@ pub(crate) fn call_datetime_without_tzinfo(
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["datetime", "datetime"]))
matches!(call_path.as_slice(), ["datetime", "datetime"])
})
{ {
return; return;
} }

View file

@ -5,7 +5,7 @@ use crate::checkers::ast::Checker;
/// Check if the parent expression is a call to `astimezone`. This assumes that /// Check if the parent expression is a call to `astimezone`. This assumes that
/// the current expression is a `datetime.datetime` object. /// the current expression is a `datetime.datetime` object.
pub(crate) fn parent_expr_is_astimezone(checker: &Checker) -> bool { pub(crate) fn parent_expr_is_astimezone(checker: &Checker) -> bool {
checker.semantic().expr_parent().map_or(false, |parent| { checker.semantic().expr_parent().is_some_and( |parent| {
matches!(parent, Expr::Attribute(ExprAttribute { attr, .. }) if attr.as_str() == "astimezone") matches!(parent, Expr::Attribute(ExprAttribute { attr, .. }) if attr.as_str() == "astimezone")
}) })
} }

View file

@ -4,14 +4,14 @@ use ruff_python_semantic::SemanticModel;
/// Return `true` if a Python class appears to be a Django model, based on its base classes. /// Return `true` if a Python class appears to be a Django model, based on its base classes.
pub(super) fn is_model(base: &Expr, semantic: &SemanticModel) -> bool { pub(super) fn is_model(base: &Expr, semantic: &SemanticModel) -> bool {
semantic.resolve_call_path(base).map_or(false, |call_path| { semantic.resolve_call_path(base).is_some_and(|call_path| {
matches!(call_path.as_slice(), ["django", "db", "models", "Model"]) matches!(call_path.as_slice(), ["django", "db", "models", "Model"])
}) })
} }
/// Return `true` if a Python class appears to be a Django model form, based on its base classes. /// Return `true` if a Python class appears to be a Django model form, based on its base classes.
pub(super) fn is_model_form(base: &Expr, semantic: &SemanticModel) -> bool { pub(super) fn is_model_form(base: &Expr, semantic: &SemanticModel) -> bool {
semantic.resolve_call_path(base).map_or(false, |call_path| { semantic.resolve_call_path(base).is_some_and(|call_path| {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),
["django", "forms", "ModelForm"] | ["django", "forms", "models", "ModelForm"] ["django", "forms", "ModelForm"] | ["django", "forms", "models", "ModelForm"]
@ -21,7 +21,7 @@ pub(super) fn is_model_form(base: &Expr, semantic: &SemanticModel) -> bool {
/// Return `true` if the expression is constructor for a Django model field. /// Return `true` if the expression is constructor for a Django model field.
pub(super) fn is_model_field(expr: &Expr, semantic: &SemanticModel) -> bool { pub(super) fn is_model_field(expr: &Expr, semantic: &SemanticModel) -> bool {
semantic.resolve_call_path(expr).map_or(false, |call_path| { semantic.resolve_call_path(expr).is_some_and(|call_path| {
call_path call_path
.as_slice() .as_slice()
.starts_with(&["django", "db", "models"]) .starts_with(&["django", "db", "models"])

View file

@ -54,9 +54,7 @@ pub(crate) fn locals_in_render_function(
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["django", "shortcuts", "render"]))
matches!(call_path.as_slice(), ["django", "shortcuts", "render"])
})
{ {
return; return;
} }
@ -85,7 +83,7 @@ fn is_locals_call(expr: &Expr, semantic: &SemanticModel) -> bool {
let Expr::Call(ast::ExprCall { func, .. }) = expr else { let Expr::Call(ast::ExprCall { func, .. }) = expr else {
return false; return false;
}; };
semantic.resolve_call_path(func).map_or(false, |call_path| { semantic
matches!(call_path.as_slice(), ["", "locals"]) .resolve_call_path(func)
}) .is_some_and(|call_path| matches!(call_path.as_slice(), ["", "locals"]))
} }

View file

@ -52,11 +52,11 @@ impl Violation for DjangoNonLeadingReceiverDecorator {
pub(crate) fn non_leading_receiver_decorator(checker: &mut Checker, decorator_list: &[Decorator]) { pub(crate) fn non_leading_receiver_decorator(checker: &mut Checker, decorator_list: &[Decorator]) {
let mut seen_receiver = false; let mut seen_receiver = false;
for (i, decorator) in decorator_list.iter().enumerate() { for (i, decorator) in decorator_list.iter().enumerate() {
let is_receiver = decorator.expression.as_call_expr().map_or(false, |call| { let is_receiver = decorator.expression.as_call_expr().is_some_and(|call| {
checker checker
.semantic() .semantic()
.resolve_call_path(&call.func) .resolve_call_path(&call.func)
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!(call_path.as_slice(), ["django", "dispatch", "receiver"]) matches!(call_path.as_slice(), ["django", "dispatch", "receiver"])
}) })
}); });

View file

@ -112,9 +112,7 @@ fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) {
if checker if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["", "dict"]))
matches!(call_path.as_slice(), ["", "dict"])
})
{ {
for keyword in keywords { for keyword in keywords {
if let Some(attr) = &keyword.arg { if let Some(attr) = &keyword.arg {

View file

@ -47,15 +47,15 @@ pub(crate) fn implicit_namespace_package(
) -> Option<Diagnostic> { ) -> Option<Diagnostic> {
if package.is_none() if package.is_none()
// Ignore non-`.py` files, which don't require an `__init__.py`. // Ignore non-`.py` files, which don't require an `__init__.py`.
&& path.extension().map_or(false, |ext| ext == "py") && path.extension().is_some_and( |ext| ext == "py")
// Ignore any files that are direct children of the project root. // Ignore any files that are direct children of the project root.
&& !path && !path
.parent() .parent()
.map_or(false, |parent| parent == project_root) .is_some_and( |parent| parent == project_root)
// Ignore any files that are direct children of a source directory (e.g., `src/manage.py`). // Ignore any files that are direct children of a source directory (e.g., `src/manage.py`).
&& !path && !path
.parent() .parent()
.map_or(false, |parent| src.iter().any(|src| src == parent)) .is_some_and( |parent| src.iter().any(|src| src == parent))
{ {
#[cfg(all(test, windows))] #[cfg(all(test, windows))]
let path = path let path = path

View file

@ -62,9 +62,7 @@ pub(crate) fn non_unique_enums(checker: &mut Checker, parent: &Stmt, body: &[Stm
checker checker
.semantic() .semantic()
.resolve_call_path(expr) .resolve_call_path(expr)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["enum", "Enum"]))
matches!(call_path.as_slice(), ["enum", "Enum"])
})
}) { }) {
return; return;
} }
@ -79,9 +77,7 @@ pub(crate) fn non_unique_enums(checker: &mut Checker, parent: &Stmt, body: &[Stm
if checker if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["enum", "auto"]))
matches!(call_path.as_slice(), ["enum", "auto"])
})
{ {
continue; continue;
} }

View file

@ -53,7 +53,7 @@ pub(crate) fn unnecessary_dict_kwargs(checker: &mut Checker, expr: &Expr, kwargs
if kw.arg.is_none() { if kw.arg.is_none() {
if let Expr::Dict(ast::ExprDict { keys, .. }) = &kw.value { if let Expr::Dict(ast::ExprDict { keys, .. }) = &kw.value {
// ensure foo(**{"bar-bar": 1}) doesn't error // ensure foo(**{"bar-bar": 1}) doesn't error
if keys.iter().all(|expr| expr.as_ref().map_or(false, is_valid_kwarg_name)) || if keys.iter().all(|expr| expr.as_ref().is_some_and( is_valid_kwarg_name)) ||
// handle case of foo(**{**bar}) // handle case of foo(**{**bar})
(keys.len() == 1 && keys[0].is_none()) (keys.len() == 1 && keys[0].is_none())
{ {

View file

@ -79,9 +79,10 @@ impl Violation for PPrint {
pub(crate) fn print_call(checker: &mut Checker, func: &Expr, keywords: &[Keyword]) { pub(crate) fn print_call(checker: &mut Checker, func: &Expr, keywords: &[Keyword]) {
let diagnostic = { let diagnostic = {
let call_path = checker.semantic().resolve_call_path(func); let call_path = checker.semantic().resolve_call_path(func);
if call_path.as_ref().map_or(false, |call_path| { if call_path
matches!(call_path.as_slice(), ["", "print"]) .as_ref()
}) { .is_some_and(|call_path| matches!(call_path.as_slice(), ["", "print"]))
{
// If the print call has a `file=` argument (that isn't `None`, `"sys.stdout"`, // If the print call has a `file=` argument (that isn't `None`, `"sys.stdout"`,
// or `"sys.stderr"`), don't trigger T201. // or `"sys.stderr"`), don't trigger T201.
if let Some(keyword) = find_keyword(keywords, "file") { if let Some(keyword) = find_keyword(keywords, "file") {
@ -98,9 +99,10 @@ pub(crate) fn print_call(checker: &mut Checker, func: &Expr, keywords: &[Keyword
} }
} }
Diagnostic::new(Print, func.range()) Diagnostic::new(Print, func.range())
} else if call_path.as_ref().map_or(false, |call_path| { } else if call_path
matches!(call_path.as_slice(), ["pprint", "pprint"]) .as_ref()
}) { .is_some_and(|call_path| matches!(call_path.as_slice(), ["pprint", "pprint"]))
{
Diagnostic::new(PPrint, func.range()) Diagnostic::new(PPrint, func.range())
} else { } else {
return; return;

View file

@ -75,9 +75,7 @@ pub(crate) fn bad_version_info_comparison(checker: &mut Checker, test: &Expr) {
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(left) .resolve_call_path(left)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["sys", "version_info"]))
matches!(call_path.as_slice(), ["sys", "version_info"])
})
{ {
return; return;
} }

View file

@ -53,9 +53,7 @@ pub(crate) fn collections_named_tuple(checker: &mut Checker, expr: &Expr) {
if checker if checker
.semantic() .semantic()
.resolve_call_path(expr) .resolve_call_path(expr)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["collections", "namedtuple"]))
matches!(call_path.as_slice(), ["collections", "namedtuple"])
})
{ {
checker checker
.diagnostics .diagnostics

View file

@ -67,7 +67,7 @@ pub(crate) fn complex_if_statement_in_stub(checker: &mut Checker, test: &Expr) {
if checker if checker
.semantic() .semantic()
.resolve_call_path(left) .resolve_call_path(left)
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!(call_path.as_slice(), ["sys", "version_info" | "platform"]) matches!(call_path.as_slice(), ["sys", "version_info" | "platform"])
}) })
{ {

View file

@ -220,7 +220,7 @@ fn check_positional_args(
// If there's an annotation that's not `object` or `Unused`, check that the annotated type // If there's an annotation that's not `object` or `Unused`, check that the annotated type
// matches the predicate. // matches the predicate.
if non_none_annotation_element(annotation, checker.semantic()) if non_none_annotation_element(annotation, checker.semantic())
.map_or(false, |elem| predicate(elem, checker.semantic())) .is_some_and(|elem| predicate(elem, checker.semantic()))
{ {
continue; continue;
} }
@ -297,7 +297,7 @@ fn is_object_or_unused(expr: &Expr, model: &SemanticModel) -> bool {
model model
.resolve_call_path(expr) .resolve_call_path(expr)
.as_ref() .as_ref()
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),
["" | "builtins", "object"] | ["_typeshed", "Unused"] ["" | "builtins", "object"] | ["_typeshed", "Unused"]
@ -310,9 +310,7 @@ fn is_base_exception(expr: &Expr, model: &SemanticModel) -> bool {
model model
.resolve_call_path(expr) .resolve_call_path(expr)
.as_ref() .as_ref()
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["" | "builtins", "BaseException"]))
matches!(call_path.as_slice(), ["" | "builtins", "BaseException"])
})
} }
/// Return `true` if the [`Expr`] is the `types.TracebackType` type. /// Return `true` if the [`Expr`] is the `types.TracebackType` type.
@ -320,9 +318,7 @@ fn is_traceback_type(expr: &Expr, model: &SemanticModel) -> bool {
model model
.resolve_call_path(expr) .resolve_call_path(expr)
.as_ref() .as_ref()
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["types", "TracebackType"]))
matches!(call_path.as_slice(), ["types", "TracebackType"])
})
} }
/// Return `true` if the [`Expr`] is, e.g., `Type[BaseException]`. /// Return `true` if the [`Expr`] is, e.g., `Type[BaseException]`.
@ -335,9 +331,7 @@ fn is_base_exception_type(expr: &Expr, model: &SemanticModel) -> bool {
|| model || model
.resolve_call_path(value) .resolve_call_path(value)
.as_ref() .as_ref()
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["" | "builtins", "type"]))
matches!(call_path.as_slice(), ["" | "builtins", "type"])
})
{ {
is_base_exception(slice, model) is_base_exception(slice, model)
} else { } else {

View file

@ -100,7 +100,7 @@ pub(crate) fn iter_method_return_iterable(checker: &mut Checker, definition: &De
if checker if checker
.semantic() .semantic()
.resolve_call_path(annotation) .resolve_call_path(annotation)
.map_or(false, |call_path| { .is_some_and(|call_path| {
if async_ { if async_ {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),

View file

@ -252,7 +252,7 @@ fn is_iterator(bases: &[Expr], semantic: &SemanticModel) -> bool {
bases.iter().any(|expr| { bases.iter().any(|expr| {
semantic semantic
.resolve_call_path(map_subscript(expr)) .resolve_call_path(map_subscript(expr))
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),
["typing", "Iterator"] | ["collections", "abc", "Iterator"] ["typing", "Iterator"] | ["collections", "abc", "Iterator"]
@ -265,7 +265,7 @@ fn is_iterator(bases: &[Expr], semantic: &SemanticModel) -> bool {
fn is_iterable(expr: &Expr, semantic: &SemanticModel) -> bool { fn is_iterable(expr: &Expr, semantic: &SemanticModel) -> bool {
semantic semantic
.resolve_call_path(map_subscript(expr)) .resolve_call_path(map_subscript(expr))
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),
["typing", "Iterable" | "Iterator"] ["typing", "Iterable" | "Iterator"]
@ -279,7 +279,7 @@ fn is_async_iterator(bases: &[Expr], semantic: &SemanticModel) -> bool {
bases.iter().any(|expr| { bases.iter().any(|expr| {
semantic semantic
.resolve_call_path(map_subscript(expr)) .resolve_call_path(map_subscript(expr))
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),
["typing", "AsyncIterator"] | ["collections", "abc", "AsyncIterator"] ["typing", "AsyncIterator"] | ["collections", "abc", "AsyncIterator"]
@ -292,7 +292,7 @@ fn is_async_iterator(bases: &[Expr], semantic: &SemanticModel) -> bool {
fn is_async_iterable(expr: &Expr, semantic: &SemanticModel) -> bool { fn is_async_iterable(expr: &Expr, semantic: &SemanticModel) -> bool {
semantic semantic
.resolve_call_path(map_subscript(expr)) .resolve_call_path(map_subscript(expr))
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),
["typing", "AsyncIterable" | "AsyncIterator"] ["typing", "AsyncIterable" | "AsyncIterator"]

View file

@ -194,7 +194,7 @@ fn is_valid_default_value_with_annotation(
return allow_container return allow_container
&& keys.len() <= 10 && keys.len() <= 10
&& keys.iter().zip(values).all(|(k, v)| { && keys.iter().zip(values).all(|(k, v)| {
k.as_ref().map_or(false, |k| { k.as_ref().is_some_and(|k| {
is_valid_default_value_with_annotation(k, false, locator, semantic) is_valid_default_value_with_annotation(k, false, locator, semantic)
}) && is_valid_default_value_with_annotation(v, false, locator, semantic) }) && is_valid_default_value_with_annotation(v, false, locator, semantic)
}); });
@ -215,7 +215,7 @@ fn is_valid_default_value_with_annotation(
if semantic if semantic
.resolve_call_path(operand) .resolve_call_path(operand)
.as_ref() .as_ref()
.map_or(false, is_allowed_negated_math_attribute) .is_some_and(is_allowed_negated_math_attribute)
{ {
return true; return true;
} }
@ -264,7 +264,7 @@ fn is_valid_default_value_with_annotation(
if semantic if semantic
.resolve_call_path(default) .resolve_call_path(default)
.as_ref() .as_ref()
.map_or(false, is_allowed_math_attribute) .is_some_and(is_allowed_math_attribute)
{ {
return true; return true;
} }
@ -332,7 +332,7 @@ fn is_type_var_like_call(expr: &Expr, semantic: &SemanticModel) -> bool {
let Expr::Call(ast::ExprCall { func, .. }) = expr else { let Expr::Call(ast::ExprCall { func, .. }) = expr else {
return false; return false;
}; };
semantic.resolve_call_path(func).map_or(false, |call_path| { semantic.resolve_call_path(func).is_some_and(|call_path| {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),
[ [
@ -370,7 +370,7 @@ fn is_final_assignment(annotation: &Expr, value: &Expr, semantic: &SemanticModel
/// Returns `true` if the a class is an enum, based on its base classes. /// Returns `true` if the a class is an enum, based on its base classes.
fn is_enum(bases: &[Expr], semantic: &SemanticModel) -> bool { fn is_enum(bases: &[Expr], semantic: &SemanticModel) -> bool {
return bases.iter().any(|expr| { return bases.iter().any(|expr| {
semantic.resolve_call_path(expr).map_or(false, |call_path| { semantic.resolve_call_path(expr).is_some_and(|call_path| {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),
[ [

View file

@ -107,9 +107,7 @@ pub(crate) fn unrecognized_platform(checker: &mut Checker, test: &Expr) {
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(left) .resolve_call_path(left)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["sys", "platform"]))
matches!(call_path.as_slice(), ["sys", "platform"])
})
{ {
return; return;
} }

View file

@ -138,9 +138,7 @@ pub(crate) fn unrecognized_version_info(checker: &mut Checker, test: &Expr) {
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(map_subscript(left)) .resolve_call_path(map_subscript(left))
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["sys", "version_info"]))
matches!(call_path.as_slice(), ["sys", "version_info"])
})
{ {
return; return;
} }

View file

@ -433,7 +433,7 @@ where
} }
} }
Expr::Call(ast::ExprCall { func, .. }) => { Expr::Call(ast::ExprCall { func, .. }) => {
if collect_call_path(func).map_or(false, |call_path| { if collect_call_path(func).is_some_and(|call_path| {
matches!(call_path.as_slice(), ["request", "addfinalizer"]) matches!(call_path.as_slice(), ["request", "addfinalizer"])
}) { }) {
self.addfinalizer_call = Some(expr); self.addfinalizer_call = Some(expr);

View file

@ -21,33 +21,27 @@ pub(super) fn get_mark_decorators(
} }
pub(super) fn is_pytest_fail(call: &Expr, semantic: &SemanticModel) -> bool { pub(super) fn is_pytest_fail(call: &Expr, semantic: &SemanticModel) -> bool {
semantic.resolve_call_path(call).map_or(false, |call_path| { semantic
matches!(call_path.as_slice(), ["pytest", "fail"]) .resolve_call_path(call)
}) .is_some_and(|call_path| matches!(call_path.as_slice(), ["pytest", "fail"]))
} }
pub(super) fn is_pytest_fixture(decorator: &Decorator, semantic: &SemanticModel) -> bool { pub(super) fn is_pytest_fixture(decorator: &Decorator, semantic: &SemanticModel) -> bool {
semantic semantic
.resolve_call_path(map_callable(&decorator.expression)) .resolve_call_path(map_callable(&decorator.expression))
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["pytest", "fixture"]))
matches!(call_path.as_slice(), ["pytest", "fixture"])
})
} }
pub(super) fn is_pytest_yield_fixture(decorator: &Decorator, semantic: &SemanticModel) -> bool { pub(super) fn is_pytest_yield_fixture(decorator: &Decorator, semantic: &SemanticModel) -> bool {
semantic semantic
.resolve_call_path(map_callable(&decorator.expression)) .resolve_call_path(map_callable(&decorator.expression))
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["pytest", "yield_fixture"]))
matches!(call_path.as_slice(), ["pytest", "yield_fixture"])
})
} }
pub(super) fn is_pytest_parametrize(decorator: &Decorator, semantic: &SemanticModel) -> bool { pub(super) fn is_pytest_parametrize(decorator: &Decorator, semantic: &SemanticModel) -> bool {
semantic semantic
.resolve_call_path(map_callable(&decorator.expression)) .resolve_call_path(map_callable(&decorator.expression))
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["pytest", "mark", "parametrize"]))
matches!(call_path.as_slice(), ["pytest", "mark", "parametrize"])
})
} }
pub(super) fn keyword_is_literal(keyword: &Keyword, literal: &str) -> bool { pub(super) fn keyword_is_literal(keyword: &Keyword, literal: &str) -> bool {

View file

@ -78,9 +78,9 @@ impl Violation for PytestRaisesWithoutException {
} }
fn is_pytest_raises(func: &Expr, semantic: &SemanticModel) -> bool { fn is_pytest_raises(func: &Expr, semantic: &SemanticModel) -> bool {
semantic.resolve_call_path(func).map_or(false, |call_path| { semantic
matches!(call_path.as_slice(), ["pytest", "raises"]) .resolve_call_path(func)
}) .is_some_and(|call_path| matches!(call_path.as_slice(), ["pytest", "raises"]))
} }
const fn is_non_trivial_with_body(body: &[Stmt]) -> bool { const fn is_non_trivial_with_body(body: &[Stmt]) -> bool {

View file

@ -218,7 +218,7 @@ impl UnittestAssert {
if keywords.iter().any(|kw| { if keywords.iter().any(|kw| {
kw.arg kw.arg
.as_ref() .as_ref()
.map_or(false, |kwarg_name| !arg_spec.contains(&kwarg_name.as_str())) .is_some_and(|kwarg_name| !arg_spec.contains(&kwarg_name.as_str()))
}) { }) {
bail!("Unknown keyword argument"); bail!("Unknown keyword argument");
} }
@ -240,7 +240,7 @@ impl UnittestAssert {
if keyword if keyword
.arg .arg
.as_ref() .as_ref()
.map_or(false, |kwarg_name| &kwarg_name == arg_name) .is_some_and(|kwarg_name| &kwarg_name == arg_name)
{ {
Some(&keyword.value) Some(&keyword.value)
} else { } else {

View file

@ -59,9 +59,7 @@ pub(crate) fn unnecessary_paren_on_raise_exception(checker: &mut Checker, expr:
if checker if checker
.semantic() .semantic()
.lookup_attribute(func) .lookup_attribute(func)
.map_or(false, |id| { .is_some_and(|id| checker.semantic().binding(id).kind.is_function_definition())
checker.semantic().binding(id).kind.is_function_definition()
})
{ {
return; return;
} }

View file

@ -8,7 +8,7 @@ use ruff_source_file::{Locator, UniversalNewlines};
/// non-`None` value. /// non-`None` value.
pub(super) fn result_exists(returns: &[&ast::StmtReturn]) -> bool { pub(super) fn result_exists(returns: &[&ast::StmtReturn]) -> bool {
returns.iter().any(|stmt| { returns.iter().any(|stmt| {
stmt.value.as_deref().map_or(false, |value| { stmt.value.as_deref().is_some_and(|value| {
!matches!( !matches!(
value, value,
Expr::Constant(constant) if constant.value.is_none() Expr::Constant(constant) if constant.value.is_none()

View file

@ -373,7 +373,7 @@ fn implicit_return_value(checker: &mut Checker, stack: &Stack) {
/// Return `true` if the `func` is a known function that never returns. /// Return `true` if the `func` is a known function that never returns.
fn is_noreturn_func(func: &Expr, semantic: &SemanticModel) -> bool { fn is_noreturn_func(func: &Expr, semantic: &SemanticModel) -> bool {
semantic.resolve_call_path(func).map_or(false, |call_path| { semantic.resolve_call_path(func).is_some_and(|call_path| {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),
["" | "builtins" | "sys" | "_thread" | "pytest", "exit"] ["" | "builtins" | "sys" | "_thread" | "pytest", "exit"]
@ -552,7 +552,7 @@ fn unnecessary_assign(checker: &mut Checker, stack: &Stack) {
if content[after_equals..] if content[after_equals..]
.chars() .chars()
.next() .next()
.map_or(false, char::is_alphabetic) .is_some_and(char::is_alphabetic)
{ {
"return ".to_string() "return ".to_string()
} else { } else {

View file

@ -156,12 +156,12 @@ pub(crate) fn private_member_access(checker: &mut Checker, expr: &Expr) {
ScopeKind::Class(ast::StmtClassDef { name, .. }) => Some(name), ScopeKind::Class(ast::StmtClassDef { name, .. }) => Some(name),
_ => None, _ => None,
}) })
.map_or(false, |name| { .is_some_and(|name| {
if call_path.as_slice() == [name.as_str()] { if call_path.as_slice() == [name.as_str()] {
checker checker
.semantic() .semantic()
.find_binding(name) .find_binding(name)
.map_or(false, |binding| { .is_some_and(|binding| {
// TODO(charlie): Could the name ever be bound to a // TODO(charlie): Could the name ever be bound to a
// _different_ class here? // _different_ class here?
binding.kind.is_class_definition() binding.kind.is_class_definition()

View file

@ -119,7 +119,7 @@ pub(crate) fn use_capital_environment_variables(checker: &mut Checker, expr: &Ex
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),
["os", "environ", "get"] | ["os", "getenv"] ["os", "environ", "get"] | ["os", "getenv"]

View file

@ -574,9 +574,9 @@ fn ternary(target_var: &Expr, body_value: &Expr, test: &Expr, orelse_value: &Exp
/// Return `true` if the `Expr` contains a reference to any of the given `${module}.${target}`. /// Return `true` if the `Expr` contains a reference to any of the given `${module}.${target}`.
fn contains_call_path(expr: &Expr, targets: &[&[&str]], semantic: &SemanticModel) -> bool { fn contains_call_path(expr: &Expr, targets: &[&[&str]], semantic: &SemanticModel) -> bool {
any_over_expr(expr, &|expr| { any_over_expr(expr, &|expr| {
semantic.resolve_call_path(expr).map_or(false, |call_path| { semantic
targets.iter().any(|target| &call_path.as_slice() == target) .resolve_call_path(expr)
}) .is_some_and(|call_path| targets.iter().any(|target| &call_path.as_slice() == target))
}) })
} }
@ -767,9 +767,10 @@ pub(crate) fn manual_dict_lookup(checker: &mut Checker, stmt_if: &StmtIf) {
let [Stmt::Return(ast::StmtReturn { value, range: _ })] = body.as_slice() else { let [Stmt::Return(ast::StmtReturn { value, range: _ })] = body.as_slice() else {
return; return;
}; };
if value.as_ref().map_or(false, |value| { if value
contains_effect(value, |id| checker.semantic().is_builtin(id)) .as_ref()
}) { .is_some_and(|value| contains_effect(value, |id| checker.semantic().is_builtin(id)))
{
return; return;
} }
@ -789,7 +790,7 @@ pub(crate) fn manual_dict_lookup(checker: &mut Checker, stmt_if: &StmtIf) {
let [Stmt::Return(ast::StmtReturn { value, range: _ })] = body.as_slice() else { let [Stmt::Return(ast::StmtReturn { value, range: _ })] = body.as_slice() else {
return; return;
}; };
if value.as_ref().map_or(false, |value| { if value.as_ref().is_some_and(|value| {
contains_effect(value, |id| checker.semantic().is_builtin(id)) contains_effect(value, |id| checker.semantic().is_builtin(id))
}) { }) {
return; return;
@ -815,7 +816,7 @@ pub(crate) fn manual_dict_lookup(checker: &mut Checker, stmt_if: &StmtIf) {
return; return;
}; };
if value.as_ref().map_or(false, |value| { if value.as_ref().is_some_and(|value| {
contains_effect(value, |id| checker.semantic().is_builtin(id)) contains_effect(value, |id| checker.semantic().is_builtin(id))
}) { }) {
return; return;

View file

@ -96,7 +96,7 @@ fn key_in_dict(
// ``` // ```
if value if value
.as_name_expr() .as_name_expr()
.map_or(false, |name| matches!(name.id.as_str(), "self")) .is_some_and(|name| matches!(name.id.as_str(), "self"))
{ {
return; return;
} }

View file

@ -62,7 +62,7 @@ fn match_async_exit_stack(semantic: &SemanticModel) -> bool {
if let Stmt::With(ast::StmtWith { items, .. }) = parent { if let Stmt::With(ast::StmtWith { items, .. }) = parent {
for item in items { for item in items {
if let Expr::Call(ast::ExprCall { func, .. }) = &item.context_expr { if let Expr::Call(ast::ExprCall { func, .. }) = &item.context_expr {
if semantic.resolve_call_path(func).map_or(false, |call_path| { if semantic.resolve_call_path(func).is_some_and(|call_path| {
matches!(call_path.as_slice(), ["contextlib", "AsyncExitStack"]) matches!(call_path.as_slice(), ["contextlib", "AsyncExitStack"])
}) { }) {
return true; return true;
@ -93,7 +93,7 @@ fn match_exit_stack(semantic: &SemanticModel) -> bool {
if let Stmt::With(ast::StmtWith { items, .. }) = parent { if let Stmt::With(ast::StmtWith { items, .. }) = parent {
for item in items { for item in items {
if let Expr::Call(ast::ExprCall { func, .. }) = &item.context_expr { if let Expr::Call(ast::ExprCall { func, .. }) = &item.context_expr {
if semantic.resolve_call_path(func).map_or(false, |call_path| { if semantic.resolve_call_path(func).is_some_and(|call_path| {
matches!(call_path.as_slice(), ["contextlib", "ExitStack"]) matches!(call_path.as_slice(), ["contextlib", "ExitStack"])
}) { }) {
return true; return true;
@ -114,9 +114,7 @@ fn is_open(checker: &mut Checker, func: &Expr) -> bool {
Expr::Call(ast::ExprCall { func, .. }) => checker Expr::Call(ast::ExprCall { func, .. }) => checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["pathlib", "Path"])),
matches!(call_path.as_slice(), ["pathlib", "Path"])
}),
_ => false, _ => false,
} }
} }

View file

@ -70,9 +70,7 @@ pub(crate) fn no_slots_in_namedtuple_subclass(
checker checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["collections", "namedtuple"]))
matches!(call_path.as_slice(), ["collections", "namedtuple"])
})
}) { }) {
if !has_slots(&class.body) { if !has_slots(&class.body) {
checker.diagnostics.push(Diagnostic::new( checker.diagnostics.push(Diagnostic::new(

View file

@ -55,7 +55,7 @@ pub(crate) fn no_slots_in_tuple_subclass(checker: &mut Checker, stmt: &Stmt, cla
checker checker
.semantic() .semantic()
.resolve_call_path(map_subscript(base)) .resolve_call_path(map_subscript(base))
.map_or(false, |call_path| { .is_some_and(|call_path| {
matches!(call_path.as_slice(), ["" | "builtins", "tuple"]) matches!(call_path.as_slice(), ["" | "builtins", "tuple"])
|| checker || checker
.semantic() .semantic()

View file

@ -104,7 +104,7 @@ pub(crate) fn runtime_import_in_type_checking_block(
}; };
if checker.rule_is_ignored(Rule::RuntimeImportInTypeCheckingBlock, import.range.start()) if checker.rule_is_ignored(Rule::RuntimeImportInTypeCheckingBlock, import.range.start())
|| import.parent_range.map_or(false, |parent_range| { || import.parent_range.is_some_and(|parent_range| {
checker.rule_is_ignored( checker.rule_is_ignored(
Rule::RuntimeImportInTypeCheckingBlock, Rule::RuntimeImportInTypeCheckingBlock,
parent_range.start(), parent_range.start(),

View file

@ -283,7 +283,7 @@ pub(crate) fn typing_only_runtime_import(
}; };
if checker.rule_is_ignored(rule_for(import_type), import.range.start()) if checker.rule_is_ignored(rule_for(import_type), import.range.start())
|| import.parent_range.map_or(false, |parent_range| { || import.parent_range.is_some_and(|parent_range| {
checker.rule_is_ignored(rule_for(import_type), parent_range.start()) checker.rule_is_ignored(rule_for(import_type), parent_range.start())
}) })
{ {

View file

@ -85,9 +85,7 @@ pub(crate) fn os_sep_split(
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(sep) .resolve_call_path(sep)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["os", "sep"]))
matches!(call_path.as_slice(), ["os", "sep"])
})
{ {
return; return;
} }

View file

@ -49,9 +49,7 @@ pub(crate) fn path_constructor_current_directory(checker: &mut Checker, expr: &E
if !checker if !checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["pathlib", "Path" | "PurePath"]))
matches!(call_path.as_slice(), ["pathlib", "Path" | "PurePath"])
})
{ {
return; return;
} }

View file

@ -71,7 +71,7 @@ pub(crate) fn annotate_imports<'a>(
// import bar # noqa`). // import bar # noqa`).
let mut inline = vec![]; let mut inline = vec![];
if names.len() > 1 if names.len() > 1
|| names.first().map_or(false, |alias| { || names.first().is_some_and(|alias| {
locator locator
.contains_line_break(TextRange::new(import.start(), alias.start())) .contains_line_break(TextRange::new(import.start(), alias.start()))
}) })

View file

@ -144,7 +144,7 @@ where
while self while self
.splits .splits
.peek() .peek()
.map_or(false, |split| stmt.start() >= **split) .is_some_and(|split| stmt.start() >= **split)
{ {
self.splits.next(); self.splits.next();
} }
@ -165,7 +165,7 @@ where
// the case of multiple empty cells). // the case of multiple empty cells).
while cell_offsets while cell_offsets
.peek() .peek()
.map_or(false, |split| stmt.start() >= **split) .is_some_and(|split| stmt.start() >= **split)
{ {
cell_offsets.next(); cell_offsets.next();
} }

View file

@ -74,7 +74,7 @@ pub(crate) fn categorize<'a>(
) -> &'a ImportSection { ) -> &'a ImportSection {
let module_base = module_name.split('.').next().unwrap(); let module_base = module_name.split('.').next().unwrap();
let (import_type, reason) = { let (import_type, reason) = {
if level.map_or(false, |level| level > 0) { if level.is_some_and(|level| level > 0) {
( (
&ImportSection::Known(ImportType::LocalFolder), &ImportSection::Known(ImportType::LocalFolder),
Reason::NonZeroLevel, Reason::NonZeroLevel,
@ -113,7 +113,7 @@ pub(crate) fn categorize<'a>(
} }
fn same_package(package: Option<&Path>, module_base: &str) -> bool { fn same_package(package: Option<&Path>, module_base: &str) -> bool {
package.map_or(false, |package| package.ends_with(module_base)) package.is_some_and(|package| package.ends_with(module_base))
} }
fn match_sources<'a>(paths: &'a [PathBuf], base: &str) -> Option<&'a Path> { fn match_sources<'a>(paths: &'a [PathBuf], base: &str) -> Option<&'a Path> {

View file

@ -58,7 +58,7 @@ pub(crate) fn normalize_imports<'a>(
// Whether to track each member of the import as a separate entry. // Whether to track each member of the import as a separate entry.
let isolate_aliases = force_single_line let isolate_aliases = force_single_line
&& module.map_or(true, |module| !single_line_exclusions.contains(module)) && module.map_or(true, |module| !single_line_exclusions.contains(module))
&& !names.first().map_or(false, |alias| alias.name == "*"); && !names.first().is_some_and(|alias| alias.name == "*");
// Insert comments on the statement itself. // Insert comments on the statement itself.
if isolate_aliases { if isolate_aliases {

View file

@ -35,7 +35,7 @@ fn prefix(
} else if name.len() > 1 && str::is_cased_uppercase(name) { } else if name.len() > 1 && str::is_cased_uppercase(name) {
// Ex) `CONSTANT` // Ex) `CONSTANT`
Prefix::Constants Prefix::Constants
} else if name.chars().next().map_or(false, char::is_uppercase) { } else if name.chars().next().is_some_and(char::is_uppercase) {
// Ex) `Class` // Ex) `Class`
Prefix::Classes Prefix::Classes
} else { } else {

View file

@ -64,7 +64,7 @@ pub(crate) fn inplace_argument(
if !call_path if !call_path
.first() .first()
.and_then(|module| checker.semantic().find_binding(module)) .and_then(|module| checker.semantic().find_binding(module))
.map_or(false, |binding| { .is_some_and(|binding| {
matches!( matches!(
binding.kind, binding.kind,
BindingKind::Import(Import { BindingKind::Import(Import {

View file

@ -50,9 +50,7 @@ pub(crate) fn use_of_read_table(checker: &mut Checker, func: &Expr, keywords: &[
if checker if checker
.semantic() .semantic()
.resolve_call_path(func) .resolve_call_path(func)
.map_or(false, |call_path| { .is_some_and(|call_path| matches!(call_path.as_slice(), ["pandas", "read_table"]))
matches!(call_path.as_slice(), ["pandas", "read_table"])
})
{ {
if let Some(Expr::Constant(ast::ExprConstant { if let Some(Expr::Constant(ast::ExprConstant {
value: Constant::Str(value), value: Constant::Str(value),

View file

@ -29,7 +29,7 @@ pub(super) fn is_named_tuple_assignment(stmt: &Stmt, semantic: &SemanticModel) -
let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() else { let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() else {
return false; return false;
}; };
semantic.resolve_call_path(func).map_or(false, |call_path| { semantic.resolve_call_path(func).is_some_and(|call_path| {
matches!( matches!(
call_path.as_slice(), call_path.as_slice(),
["collections", "namedtuple"] | ["typing", "NamedTuple"] ["collections", "namedtuple"] | ["typing", "NamedTuple"]
@ -44,9 +44,9 @@ pub(super) fn is_typed_dict_assignment(stmt: &Stmt, semantic: &SemanticModel) ->
let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() else { let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() else {
return false; return false;
}; };
semantic.resolve_call_path(func).map_or(false, |call_path| { semantic
matches!(call_path.as_slice(), ["typing", "TypedDict"]) .resolve_call_path(func)
}) .is_some_and(|call_path| matches!(call_path.as_slice(), ["typing", "TypedDict"]))
} }
pub(super) fn is_type_var_assignment(stmt: &Stmt, semantic: &SemanticModel) -> bool { pub(super) fn is_type_var_assignment(stmt: &Stmt, semantic: &SemanticModel) -> bool {
@ -56,9 +56,9 @@ pub(super) fn is_type_var_assignment(stmt: &Stmt, semantic: &SemanticModel) -> b
let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() else { let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() else {
return false; return false;
}; };
semantic.resolve_call_path(func).map_or(false, |call_path| { semantic
matches!(call_path.as_slice(), ["typing", "TypeVar" | "NewType"]) .resolve_call_path(func)
}) .is_some_and(|call_path| matches!(call_path.as_slice(), ["typing", "TypeVar" | "NewType"]))
} }
pub(super) fn is_typed_dict_class(bases: &[Expr], semantic: &SemanticModel) -> bool { pub(super) fn is_typed_dict_class(bases: &[Expr], semantic: &SemanticModel) -> bool {

View file

@ -62,7 +62,7 @@ pub(crate) fn invalid_class_name(
} }
let stripped = name.strip_prefix('_').unwrap_or(name); let stripped = name.strip_prefix('_').unwrap_or(name);
if !stripped.chars().next().map_or(false, char::is_uppercase) || stripped.contains('_') { if !stripped.chars().next().is_some_and(char::is_uppercase) || stripped.contains('_') {
return Some(Diagnostic::new( return Some(Diagnostic::new(
InvalidClassName { InvalidClassName {
name: name.to_string(), name: name.to_string(),

View file

@ -55,7 +55,7 @@ pub(crate) fn invalid_module_name(
) -> Option<Diagnostic> { ) -> Option<Diagnostic> {
if !path if !path
.extension() .extension()
.map_or(false, |ext| ext == "py" || ext == "pyi") .is_some_and(|ext| ext == "py" || ext == "pyi")
{ {
return None; return None;
} }
@ -97,7 +97,7 @@ pub(crate) fn invalid_module_name(
/// Return `true` if a [`Path`] should use the name of its parent directory as its module name. /// Return `true` if a [`Path`] should use the name of its parent directory as its module name.
fn is_module_file(path: &Path) -> bool { fn is_module_file(path: &Path) -> bool {
path.file_name().map_or(false, |file_name| { path.file_name().is_some_and(|file_name| {
file_name == "__init__.py" file_name == "__init__.py"
|| file_name == "__init__.pyi" || file_name == "__init__.pyi"
|| file_name == "__main__.py" || file_name == "__main__.py"
@ -110,5 +110,5 @@ fn is_migration_file(path: &Path) -> bool {
path.parent() path.parent()
.and_then(Path::file_name) .and_then(Path::file_name)
.and_then(OsStr::to_str) .and_then(OsStr::to_str)
.map_or(false, |parent| matches!(parent, "versions" | "migrations")) .is_some_and(|parent| matches!(parent, "versions" | "migrations"))
} }

View file

@ -110,7 +110,7 @@ pub(crate) fn manual_list_comprehension(checker: &mut Checker, target: &Expr, bo
// Ignore direct list copies (e.g., `for x in y: filtered.append(x)`). // Ignore direct list copies (e.g., `for x in y: filtered.append(x)`).
if if_test.is_none() { if if_test.is_none() {
if arg.as_name_expr().map_or(false, |arg| arg.id == *id) { if arg.as_name_expr().is_some_and(|arg| arg.id == *id) {
return; return;
} }
} }
@ -125,7 +125,7 @@ pub(crate) fn manual_list_comprehension(checker: &mut Checker, target: &Expr, bo
// Avoid, e.g., `for x in y: filtered[x].append(x * x)`. // Avoid, e.g., `for x in y: filtered[x].append(x * x)`.
if any_over_expr(value, &|expr| { if any_over_expr(value, &|expr| {
expr.as_name_expr().map_or(false, |expr| expr.id == *id) expr.as_name_expr().is_some_and(|expr| expr.id == *id)
}) { }) {
return; return;
} }
@ -152,10 +152,10 @@ pub(crate) fn manual_list_comprehension(checker: &mut Checker, target: &Expr, bo
// filtered = [x for x in y if x in filtered] // filtered = [x for x in y if x in filtered]
// ``` // ```
if let Some(value_name) = value.as_name_expr() { if let Some(value_name) = value.as_name_expr() {
if if_test.map_or(false, |test| { if if_test.is_some_and(|test| {
any_over_expr(test, &|expr| { any_over_expr(test, &|expr| {
expr.as_name_expr() expr.as_name_expr()
.map_or(false, |expr| expr.id == value_name.id) .is_some_and(|expr| expr.id == value_name.id)
}) })
}) { }) {
return; return;

View file

@ -76,7 +76,7 @@ pub(crate) fn manual_list_copy(checker: &mut Checker, target: &Expr, body: &[Stm
}; };
// Only flag direct list copies (e.g., `for x in y: filtered.append(x)`). // Only flag direct list copies (e.g., `for x in y: filtered.append(x)`).
if !arg.as_name_expr().map_or(false, |arg| arg.id == *id) { if !arg.as_name_expr().is_some_and(|arg| arg.id == *id) {
return; return;
} }
@ -90,7 +90,7 @@ pub(crate) fn manual_list_copy(checker: &mut Checker, target: &Expr, body: &[Stm
// Avoid, e.g., `for x in y: filtered[x].append(x)`. // Avoid, e.g., `for x in y: filtered[x].append(x)`.
if any_over_expr(value, &|expr| { if any_over_expr(value, &|expr| {
expr.as_name_expr().map_or(false, |expr| expr.id == *id) expr.as_name_expr().is_some_and(|expr| expr.id == *id)
}) { }) {
return; return;
} }

View file

@ -68,7 +68,7 @@ pub(crate) fn invalid_escape_sequence(
let bytes = body.as_bytes(); let bytes = body.as_bytes();
for i in memchr_iter(b'\\', bytes) { for i in memchr_iter(b'\\', bytes) {
// If the previous character was also a backslash, skip. // If the previous character was also a backslash, skip.
if prev.map_or(false, |prev| prev == i - 1) { if prev.is_some_and(|prev| prev == i - 1) {
prev = None; prev = None;
continue; continue;
} }
@ -142,7 +142,7 @@ pub(crate) fn invalid_escape_sequence(
.slice(TextRange::up_to(range.start())) .slice(TextRange::up_to(range.start()))
.chars() .chars()
.last() .last()
.map_or(false, |char| char.is_ascii_alphabetic()); .is_some_and(|char| char.is_ascii_alphabetic());
diagnostic.set_fix(Fix::automatic(Edit::insertion( diagnostic.set_fix(Fix::automatic(Edit::insertion(
if requires_space { if requires_space {

Some files were not shown because too many files have changed in this diff Show more