Compare commits

...

3 Commits

Author SHA1 Message Date
Charlie Marsh
4e23ee0e1d Make Arguments boxed 2024-02-09 22:06:05 -05:00
Charlie Marsh
7a349660e4 Reduce expression size 2024-02-09 21:37:28 -05:00
Charlie Marsh
a9d13e6bc9 Box identifier 2024-02-09 21:29:43 -05:00
149 changed files with 523 additions and 630 deletions

View File

@@ -343,15 +343,16 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
Expr::Call(
call @ ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range: _,
},
) => {
let Arguments {
args,
keywords,
range: _,
} = &**arguments;
if checker.any_enabled(&[
// pylint
Rule::BadStringFormatCharacter,

View File

@@ -904,7 +904,7 @@ where
range: _,
}) => {
if let Expr::Name(ast::ExprName { id, ctx, range: _ }) = func.as_ref() {
if id == "locals" && ctx.is_load() {
if &**id == "locals" && ctx.is_load() {
let scope = self.semantic.current_scope_mut();
scope.set_uses_locals();
}
@@ -1073,7 +1073,7 @@ where
range: _,
} = keyword;
if let Some(id) = arg {
if id.as_str() == "bound" {
if &**id == "bound" {
self.visit_type_definition(value);
} else {
self.visit_non_type_definition(value);
@@ -1117,7 +1117,7 @@ where
match (arg.as_ref(), value) {
// Ex) NamedTuple("a", **{"a": int})
(None, Expr::Dict(ast::ExprDict { keys, values, .. })) => {
for (key, value) in keys.iter().zip(values) {
for (key, value) in keys.iter().zip(values.iter()) {
if let Some(key) = key.as_ref() {
self.visit_non_type_definition(key);
self.visit_type_definition(value);
@@ -1153,7 +1153,7 @@ where
for key in keys.iter().flatten() {
self.visit_non_type_definition(key);
}
for value in values {
for value in values.iter() {
self.visit_type_definition(value);
}
} else {
@@ -1755,21 +1755,21 @@ impl<'a> Checker<'a> {
&& match parent {
Stmt::Assign(ast::StmtAssign { targets, .. }) => {
if let Some(Expr::Name(ast::ExprName { id, .. })) = targets.first() {
id == "__all__"
&**id == "__all__"
} else {
false
}
}
Stmt::AugAssign(ast::StmtAugAssign { target, .. }) => {
if let Expr::Name(ast::ExprName { id, .. }) = target.as_ref() {
id == "__all__"
&**id == "__all__"
} else {
false
}
}
Stmt::AnnAssign(ast::StmtAnnAssign { target, .. }) => {
if let Expr::Name(ast::ExprName { id, .. }) = target.as_ref() {
id == "__all__"
&**id == "__all__"
} else {
false
}

View File

@@ -46,7 +46,7 @@ fn extract_import_map(path: &Path, package: Option<&Path>, blocks: &[&Block]) ->
}) => {
let level = level.unwrap_or_default() as usize;
let module = if let Some(module) = module {
let module: &String = module.as_ref();
let module: &str = module.as_str();
if level == 0 {
Cow::Borrowed(module)
} else {

View File

@@ -81,7 +81,7 @@ pub(crate) fn variable_name_task_id(
let ast::ExprStringLiteral { value: task_id, .. } = keyword.value.as_string_literal_expr()?;
// If the target name is the same as the task_id, no violation.
if task_id == id {
if task_id == &**id {
return None;
}

View File

@@ -137,7 +137,7 @@ impl AutoPythonType {
)
.ok()?;
let expr = Expr::Name(ast::ExprName {
id: binding,
id: binding.into_boxed_str(),
range: TextRange::default(),
ctx: ExprContext::Load,
});

View File

@@ -52,7 +52,7 @@ impl Violation for HardcodedPasswordString {
fn password_target(target: &Expr) -> Option<&str> {
let target_name = match target {
// variable = "s3cr3t"
Expr::Name(ast::ExprName { id, .. }) => id.as_str(),
Expr::Name(ast::ExprName { id, .. }) => &**id,
// d["password"] = "s3cr3t"
Expr::Subscript(ast::ExprSubscript { slice, .. }) => match slice.as_ref() {
Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => value.to_str(),

View File

@@ -69,7 +69,7 @@ pub(crate) fn jinja2_autoescape_false(checker: &mut Checker, call: &ast::ExprCal
Expr::BooleanLiteral(ast::ExprBooleanLiteral { value: true, .. }) => (),
Expr::Call(ast::ExprCall { func, .. }) => {
if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() {
if id != "select_autoescape" {
if &**id != "select_autoescape" {
checker.diagnostics.push(Diagnostic::new(
Jinja2AutoescapeFalse { value: true },
keyword.range(),

View File

@@ -64,7 +64,7 @@ pub(crate) fn ssl_with_bad_defaults(checker: &mut Checker, function_def: &StmtFu
if let Some(default) = &param.default {
match default.as_ref() {
Expr::Name(ast::ExprName { id, range, .. }) => {
if is_insecure_protocol(id.as_str()) {
if is_insecure_protocol(id) {
checker.diagnostics.push(Diagnostic::new(
SslWithBadDefaults {
protocol: id.to_string(),

View File

@@ -83,7 +83,7 @@ pub(crate) fn blind_except(
return;
};
if !matches!(id.as_str(), "BaseException" | "Exception") {
if !matches!(&**id, "BaseException" | "Exception") {
return;
}
@@ -96,7 +96,7 @@ pub(crate) fn blind_except(
if let Stmt::Raise(ast::StmtRaise { exc, .. }) = stmt {
if let Some(exc) = exc {
if let Expr::Name(ast::ExprName { id, .. }) = exc.as_ref() {
name.is_some_and(|name| id == name)
name.is_some_and(|name| &**id == name)
} else {
false
}

View File

@@ -54,7 +54,7 @@ pub(super) fn is_allowed_func_def(name: &str) -> bool {
pub(super) fn allow_boolean_trap(call: &ast::ExprCall) -> bool {
let func_name = match call.func.as_ref() {
Expr::Attribute(ast::ExprAttribute { attr, .. }) => attr.as_str(),
Expr::Name(ast::ExprName { id, .. }) => id.as_str(),
Expr::Name(ast::ExprName { id, .. }) => &**id,
_ => return false,
};

View File

@@ -164,7 +164,7 @@ pub(crate) fn boolean_type_hint_positional_argument(
fn match_annotation_to_literal_bool(annotation: &Expr) -> bool {
match annotation {
// Ex) `True`
Expr::Name(name) => &name.id == "bool",
Expr::Name(name) => &*name.id == "bool",
// Ex) `"True"`
Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => value == "bool",
_ => false,
@@ -176,7 +176,7 @@ fn match_annotation_to_literal_bool(annotation: &Expr) -> bool {
fn match_annotation_to_complex_bool(annotation: &Expr, semantic: &SemanticModel) -> bool {
match annotation {
// Ex) `bool`
Expr::Name(name) => &name.id == "bool",
Expr::Name(name) => &*name.id == "bool",
// Ex) `"bool"`
Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => value == "bool",
// Ex) `bool | int`

View File

@@ -57,7 +57,7 @@ fn assertion_error(msg: Option<&Expr>) -> Stmt {
ctx: ExprContext::Load,
range: TextRange::default(),
})),
arguments: Arguments {
arguments: Box::new(Arguments {
args: if let Some(msg) = msg {
Box::from([msg.clone()])
} else {
@@ -65,7 +65,7 @@ fn assertion_error(msg: Option<&Expr>) -> Stmt {
},
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
}))),
cause: None,

View File

@@ -63,7 +63,7 @@ pub(crate) fn assignment_to_os_environ(checker: &mut Checker, targets: &[Expr])
let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() else {
return;
};
if id != "os" {
if &**id != "os" {
return;
}
checker

View File

@@ -85,7 +85,7 @@ pub(crate) fn cached_instance_method(checker: &mut Checker, decorator_list: &[De
// TODO(charlie): This should take into account `classmethod-decorators` and
// `staticmethod-decorators`.
if let Expr::Name(ast::ExprName { id, .. }) = &decorator.expression {
if id == "classmethod" || id == "staticmethod" {
if &**id == "classmethod" || &**id == "staticmethod" {
return;
}
}

View File

@@ -131,7 +131,7 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> {
}) => {
match func.as_ref() {
Expr::Name(ast::ExprName { id, .. }) => {
if matches!(id.as_str(), "filter" | "reduce" | "map") {
if matches!(&**id, "filter" | "reduce" | "map") {
for arg in arguments.args.iter() {
if arg.is_lambda_expr() {
self.safe_functions.push(arg);
@@ -142,7 +142,7 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> {
Expr::Attribute(ast::ExprAttribute { value, attr, .. }) => {
if attr == "reduce" {
if let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() {
if id == "functools" {
if &**id == "functools" {
for arg in arguments.args.iter() {
if arg.is_lambda_expr() {
self.safe_functions.push(arg);
@@ -209,7 +209,7 @@ impl<'a> Visitor<'a> for NamesFromAssignmentsVisitor<'a> {
fn visit_expr(&mut self, expr: &'a Expr) {
match expr {
Expr::Name(ast::ExprName { id, .. }) => {
self.names.push(id.as_str());
self.names.push(id);
}
Expr::Starred(ast::ExprStarred { value, .. }) => {
self.visit_expr(value);
@@ -303,7 +303,7 @@ pub(crate) fn function_uses_loop_variable(checker: &mut Checker, node: &Node) {
// If a variable was used in a function or lambda body, and assigned in the
// loop, flag it.
for name in suspicious_variables {
if reassigned_in_loop.contains(&name.id.as_str()) {
if reassigned_in_loop.contains(&&*name.id) {
if !checker.flake8_bugbear_seen.contains(&name.range()) {
checker.flake8_bugbear_seen.push(name.range());
checker.diagnostics.push(Diagnostic::new(

View File

@@ -57,7 +57,7 @@ pub(crate) fn getattr_with_constant(
let Expr::Name(ast::ExprName { id, .. }) = func else {
return;
};
if id != "getattr" {
if &**id != "getattr" {
return;
}
let [obj, arg] = args else {

View File

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

View File

@@ -83,7 +83,7 @@ impl<'a> GroupNameFinder<'a> {
fn name_matches(&self, expr: &Expr) -> bool {
if let Expr::Name(ast::ExprName { id, .. }) = expr {
id == self.group_name
&**id == self.group_name
} else {
false
}

View File

@@ -71,7 +71,7 @@ pub(crate) fn setattr_with_constant(
let Expr::Name(ast::ExprName { id, .. }) = func else {
return;
};
if id != "setattr" {
if &**id != "setattr" {
return;
}
let [obj, name, value] = args else {

View File

@@ -73,7 +73,7 @@ pub(crate) fn static_key_dict_comprehension(checker: &mut Checker, dict_comp: &a
fn is_constant(key: &Expr, names: &FxHashMap<&str, &ast::ExprName>) -> bool {
match key {
Expr::Tuple(ast::ExprTuple { elts, .. }) => elts.iter().all(|elt| is_constant(elt, names)),
Expr::Name(ast::ExprName { id, .. }) => !names.contains_key(id.as_str()),
Expr::Name(ast::ExprName { id, .. }) => !names.contains_key(&**id),
Expr::Attribute(ast::ExprAttribute { value, .. }) => is_constant(value, names),
Expr::Subscript(ast::ExprSubscript { value, slice, .. }) => {
is_constant(value, names) && is_constant(slice, names)

View File

@@ -54,7 +54,7 @@ pub(crate) fn unintentional_type_annotation(
}
Expr::Attribute(ast::ExprAttribute { value, .. }) => {
if let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() {
if id != "self" {
if &**id != "self" {
checker
.diagnostics
.push(Diagnostic::new(UnintentionalTypeAnnotation, stmt.range()));

View File

@@ -61,7 +61,7 @@ pub(crate) fn unreliable_callable_check(
let Expr::Name(ast::ExprName { id, .. }) = func else {
return;
};
if !matches!(id.as_str(), "hasattr" | "getattr") {
if !matches!(&**id, "hasattr" | "getattr") {
return;
}
let [obj, attr, ..] = args else {
@@ -75,7 +75,7 @@ pub(crate) fn unreliable_callable_check(
}
let mut diagnostic = Diagnostic::new(UnreliableCallableCheck, expr.range());
if id == "hasattr" {
if &**id == "hasattr" {
if checker.semantic().is_builtin("callable") {
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
format!("callable({})", checker.locator().slice(obj)),

View File

@@ -1,7 +1,7 @@
use ruff_diagnostics::{AlwaysFixableViolation, Applicability, Diagnostic, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, Arguments, Expr};
use ruff_python_ast::{self as ast, Expr};
use ruff_python_semantic::SemanticModel;
use ruff_text_size::Ranged;
@@ -53,7 +53,7 @@ impl AlwaysFixableViolation for ZipWithoutExplicitStrict {
/// B905
pub(crate) fn zip_without_explicit_strict(checker: &mut Checker, call: &ast::ExprCall) {
if let Expr::Name(ast::ExprName { id, .. }) = call.func.as_ref() {
if id == "zip"
if &**id == "zip"
&& checker.semantic().is_builtin("zip")
&& call.arguments.find_keyword("strict").is_none()
&& !call
@@ -91,9 +91,7 @@ pub(crate) fn zip_without_explicit_strict(checker: &mut Checker, call: &ast::Exp
/// `itertools.cycle` or similar).
fn is_infinite_iterator(arg: &Expr, semantic: &SemanticModel) -> bool {
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, keywords, .. },
..
func, arguments, ..
}) = &arg
else {
return false;
@@ -104,17 +102,17 @@ fn is_infinite_iterator(arg: &Expr, semantic: &SemanticModel) -> bool {
["itertools", "cycle" | "count"] => true,
["itertools", "repeat"] => {
// Ex) `itertools.repeat(1)`
if keywords.is_empty() && args.len() == 1 {
if arguments.keywords.is_empty() && arguments.args.len() == 1 {
return true;
}
// Ex) `itertools.repeat(1, None)`
if args.len() == 2 && args[1].is_none_literal_expr() {
if arguments.args.len() == 2 && arguments.args[1].is_none_literal_expr() {
return true;
}
// Ex) `iterools.repeat(1, times=None)`
for keyword in keywords.iter() {
for keyword in arguments.keywords.iter() {
if keyword.arg.as_ref().is_some_and(|name| name == "times") {
if keyword.value.is_none_literal_expr() {
return true;

View File

@@ -13,7 +13,7 @@ pub(super) fn exactly_one_argument_with_matching_function<'a>(
return None;
}
let func = func.as_name_expr()?;
if func.id != name {
if &*func.id != name {
return None;
}
Some(arg)
@@ -24,7 +24,7 @@ pub(super) fn first_argument_with_matching_function<'a>(
func: &Expr,
args: &'a [Expr],
) -> Option<&'a Expr> {
if func.as_name_expr().is_some_and(|func| func.id == name) {
if func.as_name_expr().is_some_and(|func| &*func.id == name) {
args.first()
} else {
None

View File

@@ -66,7 +66,7 @@ pub(crate) fn unnecessary_call_around_sorted(
let Some(outer) = func.as_name_expr() else {
return;
};
if !matches!(outer.id.as_str(), "list" | "reversed") {
if !matches!(&*outer.id, "list" | "reversed") {
return;
}
let Some(arg) = args.first() else {
@@ -78,7 +78,7 @@ pub(crate) fn unnecessary_call_around_sorted(
let Some(inner) = func.as_name_expr() else {
return;
};
if inner.id != "sorted" {
if &*inner.id != "sorted" {
return;
}
if !checker.semantic().is_builtin(&inner.id) || !checker.semantic().is_builtin(&outer.id) {
@@ -93,7 +93,7 @@ pub(crate) fn unnecessary_call_around_sorted(
diagnostic.try_set_fix(|| {
Ok(Fix::applicable_edit(
fixes::fix_unnecessary_call_around_sorted(expr, checker.locator(), checker.stylist())?,
if outer.id == "reversed" {
if &*outer.id == "reversed" {
Applicability::Unsafe
} else {
Applicability::Safe

View File

@@ -68,7 +68,7 @@ pub(crate) fn unnecessary_collection_call(
let Some(func) = call.func.as_name_expr() else {
return;
};
let collection = match func.id.as_str() {
let collection = match &*func.id {
"dict"
if call.arguments.keywords.is_empty()
|| (!settings.allow_dict_calls_with_keyword_arguments
@@ -87,7 +87,7 @@ pub(crate) fn unnecessary_collection_call(
}
_ => return,
};
if !checker.semantic().is_builtin(func.id.as_str()) {
if !checker.semantic().is_builtin(&func.id) {
return;
}

View File

@@ -75,7 +75,7 @@ pub(crate) fn unnecessary_comprehension_any_all(
let Expr::Name(ast::ExprName { id, .. }) = func else {
return;
};
if !matches!(id.as_str(), "all" | "any") {
if !matches!(&**id, "all" | "any") {
return;
}
let [arg] = args else {

View File

@@ -1,7 +1,7 @@
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::comparable::ComparableKeyword;
use ruff_python_ast::{self as ast, Arguments, Expr, Keyword};
use ruff_python_ast::{self as ast, Expr, Keyword};
use ruff_text_size::Ranged;
use crate::checkers::ast::Checker;
@@ -77,21 +77,14 @@ pub(crate) fn unnecessary_double_cast_or_process(
let Some(outer) = func.as_name_expr() else {
return;
};
if !matches!(
outer.id.as_str(),
"list" | "tuple" | "set" | "reversed" | "sorted"
) {
if !matches!(&*outer.id, "list" | "tuple" | "set" | "reversed" | "sorted") {
return;
}
let Some(arg) = args.first() else {
return;
};
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments {
keywords: inner_kw, ..
},
..
func, arguments, ..
}) = arg
else {
return;
@@ -105,11 +98,11 @@ pub(crate) fn unnecessary_double_cast_or_process(
// Avoid collapsing nested `sorted` calls with non-identical keyword arguments
// (i.e., `key`, `reverse`).
if inner.id == "sorted" && outer.id == "sorted" {
if inner_kw.len() != outer_kw.len() {
if &*inner.id == "sorted" && &*outer.id == "sorted" {
if arguments.keywords.len() != outer_kw.len() {
return;
}
if !inner_kw.iter().all(|inner| {
if !arguments.keywords.iter().all(|inner| {
outer_kw
.iter()
.any(|outer| ComparableKeyword::from(inner) == ComparableKeyword::from(outer))
@@ -122,7 +115,7 @@ pub(crate) fn unnecessary_double_cast_or_process(
// Ex) `list(tuple(...))`
// Ex) `set(set(...))`
if matches!(
(outer.id.as_str(), inner.id.as_str()),
(&*outer.id, &*inner.id),
("set" | "sorted", "list" | "tuple" | "reversed" | "sorted")
| ("set", "set")
| ("list" | "tuple", "list" | "tuple")

View File

@@ -5,7 +5,7 @@ use ruff_diagnostics::{FixAvailability, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::visitor;
use ruff_python_ast::visitor::Visitor;
use ruff_python_ast::{self as ast, Arguments, Expr, ExprContext, Parameters, Stmt};
use ruff_python_ast::{self as ast, Expr, ExprContext, Parameters, Stmt};
use ruff_text_size::Ranged;
use crate::checkers::ast::Checker;
@@ -77,7 +77,7 @@ pub(crate) fn unnecessary_map(
return;
};
let object_type = match func.id.as_str() {
let object_type = match &*func.id {
"map" => ObjectType::Generator,
"list" => ObjectType::List,
"set" => ObjectType::Set,
@@ -95,7 +95,7 @@ pub(crate) fn unnecessary_map(
if parent
.and_then(Expr::as_call_expr)
.and_then(|call| call.func.as_name_expr())
.is_some_and(|name| matches!(name.id.as_str(), "list" | "set" | "dict"))
.is_some_and(|name| matches!(&*name.id, "list" | "set" | "dict"))
{
return;
}
@@ -125,23 +125,22 @@ pub(crate) fn unnecessary_map(
ObjectType::List | ObjectType::Set => {
// Only flag, e.g., `list(map(lambda x: x + 1, iterable))`.
let [Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, keywords, .. },
..
func, arguments, ..
})] = args
else {
return;
};
if args.len() != 2 {
if arguments.args.len() != 2 {
return;
}
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
return;
}
let Some(argument) = helpers::first_argument_with_matching_function("map", func, args)
let Some(argument) =
helpers::first_argument_with_matching_function("map", func, &arguments.args)
else {
return;
};
@@ -170,23 +169,22 @@ pub(crate) fn unnecessary_map(
ObjectType::Dict => {
// Only flag, e.g., `dict(map(lambda v: (v, v ** 2), values))`.
let [Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, keywords, .. },
..
func, arguments, ..
})] = args
else {
return;
};
if args.len() != 2 {
if arguments.args.len() != 2 {
return;
}
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
return;
}
let Some(argument) = helpers::first_argument_with_matching_function("map", func, args)
let Some(argument) =
helpers::first_argument_with_matching_function("map", func, &arguments.args)
else {
return;
};

View File

@@ -47,7 +47,7 @@ pub(crate) fn unnecessary_subscript_reversal(checker: &mut Checker, call: &ast::
let Some(func) = call.func.as_name_expr() else {
return;
};
if !matches!(func.id.as_str(), "reversed" | "set" | "sorted") {
if !matches!(&*func.id, "reversed" | "set" | "sorted") {
return;
}
if !checker.semantic().is_builtin(&func.id) {

View File

@@ -72,7 +72,7 @@ pub(crate) fn all_with_model_form(checker: &mut Checker, class_def: &ast::StmtCl
let Expr::Name(ast::ExprName { id, .. }) = target else {
continue;
};
if id != "fields" {
if &**id != "fields" {
continue;
}
match value.as_ref() {

View File

@@ -70,7 +70,7 @@ pub(crate) fn exclude_with_model_form(checker: &mut Checker, class_def: &ast::St
let Expr::Name(ast::ExprName { id, .. }) = target else {
continue;
};
if id == "exclude" {
if &**id == "exclude" {
checker
.diagnostics
.push(Diagnostic::new(DjangoExcludeWithModelForm, target.range()));

View File

@@ -106,7 +106,7 @@ fn is_model_abstract(class_def: &ast::StmtClassDef) -> bool {
let Expr::Name(ast::ExprName { id, .. }) = target else {
continue;
};
if id != "abstract" {
if &**id != "abstract" {
continue;
}
if !is_const_true(value) {

View File

@@ -165,7 +165,7 @@ fn get_element_type(element: &Stmt, semantic: &SemanticModel) -> Option<ContentT
let Expr::Name(ast::ExprName { id, .. }) = expr else {
return None;
};
if id == "objects" {
if &**id == "objects" {
Some(ContentType::ManagerDeclaration)
} else {
None

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Arguments, Expr, Stmt};
use ruff_python_ast::{self as ast, Expr, Stmt};
use ruff_source_file::Locator;
use ruff_text_size::Ranged;
@@ -175,12 +175,8 @@ impl Violation for DotFormatInException {
/// EM101, EM102, EM103
pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr) {
if let Expr::Call(ast::ExprCall {
arguments: Arguments { args, .. },
..
}) = exc
{
if let Some(first) = args.first() {
if let Expr::Call(ast::ExprCall { arguments, .. }) = exc {
if let Some(first) = arguments.args.first() {
match first {
// Check for string literals.
Expr::StringLiteral(ast::ExprStringLiteral { value: string, .. }) => {

View File

@@ -7,7 +7,7 @@ pub mod settings;
/// Returns true if the [`Expr`] is an internationalization function call.
pub(crate) fn is_gettext_func_call(func: &Expr, functions_names: &[String]) -> bool {
if let Expr::Name(ast::ExprName { id, .. }) = func {
functions_names.contains(id)
functions_names.iter().any(|name| name == &**id)
} else {
false
}

View File

@@ -1,5 +1,5 @@
use ruff_diagnostics::{Diagnostic, Edit, Fix};
use ruff_python_ast::{self as ast, Arguments, Expr, Keyword, Operator};
use ruff_python_ast::{self as ast, Expr, Keyword, Operator};
use ruff_python_semantic::analyze::logging;
use ruff_python_stdlib::logging::LoggingLevel;
use ruff_text_size::Ranged;
@@ -90,7 +90,7 @@ fn check_msg(checker: &mut Checker, msg: &Expr) {
fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) {
match &extra.value {
Expr::Dict(ast::ExprDict { keys, .. }) => {
for key in keys {
for key in keys.iter() {
if let Some(key) = &key {
if let Expr::StringLiteral(ast::ExprStringLiteral { value: attr, .. }) = key {
if is_reserved_attr(attr.to_str()) {
@@ -104,16 +104,14 @@ fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) {
}
}
Expr::Call(ast::ExprCall {
func,
arguments: Arguments { keywords, .. },
..
func, arguments, ..
}) => {
if checker
.semantic()
.resolve_call_path(func)
.is_some_and(|call_path| matches!(call_path.as_slice(), ["", "dict"]))
{
for keyword in keywords.iter() {
for keyword in arguments.keywords.iter() {
if let Some(attr) = &keyword.arg {
if is_reserved_attr(attr) {
checker.diagnostics.push(Diagnostic::new(

View File

@@ -93,7 +93,7 @@ pub(crate) fn duplicate_class_field_definition(checker: &mut Checker, body: &[St
_ => continue,
}
if !seen_targets.insert(target.id.as_str()) {
if !seen_targets.insert(&*target.id) {
let mut diagnostic = Diagnostic::new(
DuplicateClassFieldDefinition {
name: target.id.to_string(),

View File

@@ -81,23 +81,18 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
for (index, call) in values.iter().enumerate() {
let Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range: _,
}) = &call
else {
continue;
};
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
continue;
}
let [arg] = &**args else {
let [arg] = &*arguments.args else {
continue;
};
@@ -120,7 +115,7 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
}
duplicates
.entry((attr.as_str(), arg_name.as_str()))
.entry((&**attr, &**arg_name))
.or_insert_with(Vec::new)
.push(index);
}
@@ -140,12 +135,7 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
.map(|expr| {
let Expr::Call(ast::ExprCall {
func: _,
arguments:
Arguments {
args,
keywords: _,
range: _,
},
arguments,
range: _,
}) = expr
else {
@@ -154,7 +144,9 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
format!("Indices should only contain `{attr_name}` calls")
)
};
args.first()
arguments
.args
.first()
.unwrap_or_else(|| panic!("`{attr_name}` should have one argument"))
})
.collect();
@@ -187,11 +179,11 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
});
let node3 = Expr::Call(ast::ExprCall {
func: Box::new(node2),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([node]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
});
let call = node3;
@@ -229,7 +221,7 @@ fn is_bound_to_tuple(arg: &Expr, semantic: &SemanticModel) -> bool {
return false;
};
let Some(binding_id) = semantic.lookup_symbol(id.as_str()) else {
let Some(binding_id) = semantic.lookup_symbol(id) else {
return false;
};

View File

@@ -70,7 +70,7 @@ pub(crate) fn unnecessary_dict_kwargs(checker: &mut Checker, call: &ast::ExprCal
};
// Ex) `foo(**{**bar})`
if matches!(keys.as_slice(), [None]) {
if matches!(&**keys, [None]) {
let mut diagnostic = Diagnostic::new(UnnecessaryDictKwargs, keyword.range());
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
@@ -151,7 +151,7 @@ fn duplicates(call: &ast::ExprCall) -> FxHashSet<&str> {
duplicates.insert(name.as_str());
}
} else if let Expr::Dict(ast::ExprDict { keys, .. }) = &keyword.value {
for key in keys {
for key in keys.iter() {
if let Some(name) = key.as_ref().and_then(as_kwarg) {
if !seen.insert(name) {
duplicates.insert(name);

View File

@@ -47,7 +47,7 @@ pub(crate) fn unnecessary_range_start(checker: &mut Checker, call: &ast::ExprCal
let Expr::Name(ast::ExprName { id, .. }) = call.func.as_ref() else {
return;
};
if id != "range" {
if &**id != "range" {
return;
};
if !checker.semantic().is_builtin("range") {

View File

@@ -142,7 +142,7 @@ fn class_method(
// Don't error if the first argument is annotated with typing.Type[T].
// These are edge cases, and it's hard to give good error messages for them.
if value.id != "type" {
if &*value.id != "type" {
return false;
};

View File

@@ -264,7 +264,7 @@ fn is_name(expr: &Expr, name: &str) -> bool {
let Expr::Name(ast::ExprName { id, .. }) = expr else {
return false;
};
id.as_str() == name
&**id == name
}
/// Return `true` if the given expression resolves to `typing.Self`.

View File

@@ -132,7 +132,7 @@ impl fmt::Display for ExprType {
/// `str`, `bytes`, or `complex`).
fn match_builtin_type(expr: &Expr, semantic: &SemanticModel) -> Option<ExprType> {
let name = expr.as_name_expr()?;
let result = match name.id.as_str() {
let result = match &*name.id {
"int" => ExprType::Int,
"bool" => ExprType::Bool,
"str" => ExprType::Str,
@@ -141,7 +141,7 @@ fn match_builtin_type(expr: &Expr, semantic: &SemanticModel) -> Option<ExprType>
"complex" => ExprType::Complex,
_ => return None,
};
if !semantic.is_builtin(name.id.as_str()) {
if !semantic.is_builtin(&name.id) {
return None;
}
Some(result)

View File

@@ -307,7 +307,7 @@ fn is_valid_default_value_with_annotation(
}) => {
return allow_container
&& keys.len() <= 10
&& keys.iter().zip(values).all(|(k, v)| {
&& keys.iter().zip(values.iter()).all(|(k, v)| {
k.as_ref().is_some_and(|k| {
is_valid_default_value_with_annotation(k, false, locator, semantic)
}) && is_valid_default_value_with_annotation(v, false, locator, semantic)
@@ -450,7 +450,7 @@ fn is_type_var_like_call(expr: &Expr, semantic: &SemanticModel) -> bool {
/// `__all__`).
fn is_special_assignment(target: &Expr, semantic: &SemanticModel) -> bool {
if let Expr::Name(ast::ExprName { id, .. }) = target {
match id.as_str() {
match &**id {
"__all__" => semantic.current_scope().kind.is_module(),
"__match_args__" | "__slots__" => semantic.current_scope().kind.is_class(),
_ => false,

View File

@@ -122,7 +122,7 @@ pub(crate) fn unnecessary_type_union<'a>(checker: &mut Checker, union: &'a Expr)
.into_iter()
.map(|type_member| {
Expr::Name(ast::ExprName {
id: type_member,
id: type_member.into_boxed_str(),
ctx: ExprContext::Load,
range: TextRange::default(),
})

View File

@@ -47,7 +47,7 @@ pub(crate) fn unsupported_method_call_on_all(checker: &mut Checker, func: &Expr)
let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() else {
return;
};
if id.as_str() != "__all__" {
if &**id != "__all__" {
return;
}
if !is_unsupported_method(attr.as_str()) {

View File

@@ -242,7 +242,7 @@ where
match expr {
Expr::Name(ast::ExprName { id, .. }) => {
if let Some(current_assert) = self.current_assert {
if id.as_str() == self.exception_name {
if &**id == self.exception_name {
self.errors.push(Diagnostic::new(
PytestAssertInExcept {
name: id.to_string(),
@@ -419,7 +419,7 @@ fn to_pytest_raises_args<'a>(
if kwarg
.arg
.as_ref()
.is_some_and(|id| id.as_str() == "expected_exception") =>
.is_some_and(|id| &**id == "expected_exception") =>
{
Cow::Borrowed(checker.locator().slice(kwarg.value.range()))
}
@@ -452,11 +452,11 @@ fn to_pytest_raises_args<'a>(
if kwarg1
.arg
.as_ref()
.is_some_and(|id| id.as_str() == "expected_exception")
.is_some_and(|id| &**id == "expected_exception")
&& kwarg2
.arg
.as_ref()
.is_some_and(|id| id.as_str() == "expected_regex") =>
.is_some_and(|id| &**id == "expected_regex") =>
{
Cow::Owned(format!(
"{}, match={}",
@@ -469,11 +469,11 @@ fn to_pytest_raises_args<'a>(
if kwarg1
.arg
.as_ref()
.is_some_and(|id| id.as_str() == "expected_regex")
.is_some_and(|id| &**id == "expected_regex")
&& kwarg2
.arg
.as_ref()
.is_some_and(|id| id.as_str() == "expected_exception") =>
.is_some_and(|id| &**id == "expected_exception") =>
{
Cow::Owned(format!(
"{}, match={}",

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Arguments, Decorator, Expr};
use ruff_python_ast::{self as ast, Decorator, Expr};
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
@@ -137,18 +137,10 @@ fn check_mark_parentheses(checker: &mut Checker, decorator: &Decorator, marker:
match &decorator.expression {
Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range: _,
}) => {
if !checker.settings.flake8_pytest_style.mark_parentheses
&& args.is_empty()
&& keywords.is_empty()
{
if !checker.settings.flake8_pytest_style.mark_parentheses && arguments.is_empty() {
let fix = Fix::safe_edit(Edit::deletion(func.end(), decorator.end()));
pytest_mark_parentheses(checker, decorator, marker, fix, "", "()");
}
@@ -171,11 +163,8 @@ fn check_useless_usefixtures(checker: &mut Checker, decorator: &Decorator, marke
// @pytest.mark.usefixtures
Expr::Attribute(..) => {}
// @pytest.mark.usefixtures(...)
Expr::Call(ast::ExprCall {
arguments: Arguments { args, keywords, .. },
..
}) => {
if !args.is_empty() || !keywords.is_empty() {
Expr::Call(ast::ExprCall { arguments, .. }) => {
if !arguments.is_empty() {
return;
}
}

View File

@@ -7,7 +7,7 @@ use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::comparable::ComparableExpr;
use ruff_python_ast::parenthesize::parenthesized_range;
use ruff_python_ast::AstNode;
use ruff_python_ast::{self as ast, Arguments, Decorator, Expr, ExprContext};
use ruff_python_ast::{self as ast, Decorator, Expr, ExprContext};
use ruff_python_codegen::Generator;
use ruff_python_trivia::CommentRanges;
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
@@ -632,23 +632,19 @@ fn handle_value_rows(
pub(crate) fn parametrize(checker: &mut Checker, decorators: &[Decorator]) {
for decorator in decorators {
if is_pytest_parametrize(decorator, checker.semantic()) {
if let Expr::Call(ast::ExprCall {
arguments: Arguments { args, .. },
..
}) = &decorator.expression
{
if let Expr::Call(ast::ExprCall { arguments, .. }) = &decorator.expression {
if checker.enabled(Rule::PytestParametrizeNamesWrongType) {
if let [names, ..] = &**args {
if let [names, ..] = &*arguments.args {
check_names(checker, decorator, names);
}
}
if checker.enabled(Rule::PytestParametrizeValuesWrongType) {
if let [names, values, ..] = &**args {
if let [names, values, ..] = &*arguments.args {
check_values(checker, names, values);
}
}
if checker.enabled(Rule::PytestDuplicateParametrizeTestCases) {
if let [_, values, ..] = &**args {
if let [_, values, ..] = &*arguments.args {
check_duplicates(checker, values);
}
}

View File

@@ -389,11 +389,11 @@ impl UnittestAssert {
};
let node1 = ast::ExprCall {
func: Box::new(node.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([(**obj).clone(), (**cls).clone()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
let isinstance = node1.into();
@@ -433,11 +433,11 @@ impl UnittestAssert {
};
let node2 = ast::ExprCall {
func: Box::new(node1.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([(**regex).clone(), (**text).clone()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
let re_search = node2.into();

View File

@@ -564,7 +564,7 @@ fn unnecessary_assign(checker: &mut Checker, stack: &Stack) {
continue;
}
if stack.non_locals.contains(assigned_id.as_str()) {
if stack.non_locals.contains(&**assigned_id) {
continue;
}

View File

@@ -77,7 +77,8 @@ pub(crate) fn private_member_access(checker: &mut Checker, expr: &Expr) {
.settings
.flake8_self
.ignore_names
.contains(attr.as_ref())
.iter()
.any(|name| name == attr.as_str())
{
return;
}

View File

@@ -303,27 +303,22 @@ fn isinstance_target<'a>(call: &'a Expr, semantic: &'a SemanticModel) -> Option<
// Verify that this is an `isinstance` call.
let Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range: _,
}) = &call
else {
return None;
};
if args.len() != 2 {
if !arguments.keywords.is_empty() {
return None;
}
if !keywords.is_empty() {
if arguments.args.len() != 2 {
return None;
}
let Expr::Name(ast::ExprName { id: func_name, .. }) = func.as_ref() else {
return None;
};
if func_name != "isinstance" {
if &**func_name != "isinstance" {
return None;
}
if !semantic.is_builtin("isinstance") {
@@ -331,7 +326,7 @@ fn isinstance_target<'a>(call: &'a Expr, semantic: &'a SemanticModel) -> Option<
}
// Collect the target (e.g., `obj` in `isinstance(obj, int)`).
Some(&args[0])
Some(&arguments.args[0])
}
/// SIM101
@@ -374,12 +369,10 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
if indices.len() > 1 {
// Grab the target used in each duplicate `isinstance` call (e.g., `obj` in
// `isinstance(obj, int)`).
let target = if let Expr::Call(ast::ExprCall {
arguments: Arguments { args, .. },
..
}) = &values[indices[0]]
{
args.first()
let target = if let Expr::Call(ast::ExprCall { arguments, .. }) = &values[indices[0]] {
arguments
.args
.first()
.expect("`isinstance` should have two arguments")
} else {
unreachable!("Indices should only contain `isinstance` calls")
@@ -401,14 +394,13 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
.iter()
.map(|index| &values[*index])
.map(|expr| {
let Expr::Call(ast::ExprCall {
arguments: Arguments { args, .. },
..
}) = expr
else {
let Expr::Call(ast::ExprCall { arguments, .. }) = expr else {
unreachable!("Indices should only contain `isinstance` calls")
};
args.get(1).expect("`isinstance` should have two arguments")
arguments
.args
.get(1)
.expect("`isinstance` should have two arguments")
})
.collect();
@@ -436,11 +428,11 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
};
let node2 = ast::ExprCall {
func: Box::new(node1.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([target.clone(), node.into()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
let call = node2.into();

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Arguments, Expr};
use ruff_python_ast::{self as ast, Expr};
use ruff_text_size::Ranged;
use crate::fix::snippet::SourceCodeSnippet;
@@ -134,14 +134,12 @@ pub(crate) fn use_capital_environment_variables(checker: &mut Checker, expr: &Ex
// Ex) `os.environ.get('foo')`, `os.getenv('foo')`
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, .. },
..
func, arguments, ..
}) = expr
else {
return;
};
let Some(arg) = args.first() else {
let Some(arg) = arguments.args.first() else {
return;
};
let Expr::StringLiteral(ast::ExprStringLiteral { value: env_var, .. }) = arg else {
@@ -193,7 +191,7 @@ fn check_os_environ_subscript(checker: &mut Checker, expr: &Expr) {
let Expr::Name(ast::ExprName { id, .. }) = attr_value.as_ref() else {
return;
};
if id != "os" || attr != "environ" {
if &**id != "os" || attr != "environ" {
return;
}
let Expr::StringLiteral(ast::ExprStringLiteral { value: env_var, .. }) = slice.as_ref() else {
@@ -233,13 +231,13 @@ fn check_os_environ_subscript(checker: &mut Checker, expr: &Expr) {
pub(crate) fn dict_get_with_none_default(checker: &mut Checker, expr: &Expr) {
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, keywords, .. },
arguments,
range: _,
}) = expr
else {
return;
};
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
return;
}
let Expr::Attribute(ast::ExprAttribute { value, attr, .. }) = func.as_ref() else {
@@ -248,13 +246,13 @@ pub(crate) fn dict_get_with_none_default(checker: &mut Checker, expr: &Expr) {
if attr != "get" {
return;
}
let Some(key) = args.first() else {
let Some(key) = arguments.args.first() else {
return;
};
if !(key.is_literal_expr() || key.is_name_expr()) {
return;
}
let Some(default) = args.get(1) else {
let Some(default) = arguments.args.get(1) else {
return;
};
if !default.is_none_literal_expr() {

View File

@@ -184,11 +184,11 @@ pub(crate) fn if_expr_with_true_false(
}
.into(),
),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([test.clone()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
}
.into(),

View File

@@ -278,11 +278,11 @@ pub(crate) fn double_negation(checker: &mut Checker, expr: &Expr, op: UnaryOp, o
};
let node1 = ast::ExprCall {
func: Box::new(node.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([*operand.clone()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(

View File

@@ -252,7 +252,7 @@ fn is_main_check(expr: &Expr) -> bool {
}) = expr
{
if let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() {
if id == "__name__" {
if &**id == "__name__" {
if let [Expr::StringLiteral(ast::ExprStringLiteral { value, .. })] = &**comparators
{
if value == "__main__" {

View File

@@ -175,11 +175,11 @@ pub(crate) fn if_else_block_instead_of_dict_get(checker: &mut Checker, stmt_if:
};
let node3 = ast::ExprCall {
func: Box::new(node2.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([node1, node]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
let node4 = expected_var.clone();
@@ -275,11 +275,11 @@ pub(crate) fn if_exp_instead_of_dict_get(
};
let fixed_node = ast::ExprCall {
func: Box::new(dict_get_node.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([dict_key_node, default_value_node]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};

View File

@@ -3,7 +3,7 @@ use ruff_diagnostics::{Applicability, Edit};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::parenthesize::parenthesized_range;
use ruff_python_ast::AnyNodeRef;
use ruff_python_ast::{self as ast, Arguments, CmpOp, Comprehension, Expr};
use ruff_python_ast::{self as ast, CmpOp, Comprehension, Expr};
use ruff_python_semantic::analyze::typing;
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
use ruff_text_size::{Ranged, TextRange};
@@ -67,20 +67,21 @@ fn key_in_dict(
) {
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, keywords, .. },
arguments,
range: _,
}) = &right
else {
return;
};
if !(args.is_empty() && keywords.is_empty()) {
if !arguments.is_empty() {
return;
}
let Expr::Attribute(ast::ExprAttribute { attr, value, .. }) = func.as_ref() else {
return;
};
if attr != "keys" {
if &**attr != "keys" {
return;
}
@@ -89,10 +90,7 @@ fn key_in_dict(
// def __contains__(self, key: object) -> bool:
// return key in self.keys()
// ```
if value
.as_name_expr()
.is_some_and(|name| matches!(name.id.as_str(), "self"))
{
if value.as_name_expr().is_some_and(|name| &*name.id == "self") {
return;
}

View File

@@ -160,11 +160,11 @@ pub(crate) fn needless_bool(checker: &mut Checker, stmt_if: &ast::StmtIf) {
};
let value_node = ast::ExprCall {
func: Box::new(func_node.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([if_test.clone()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
let return_node = ast::StmtReturn {

View File

@@ -121,7 +121,7 @@ fn is_open(checker: &mut Checker, func: &Expr) -> bool {
}
// open(...)
Expr::Name(ast::ExprName { id, .. }) => {
id.as_str() == "open" && checker.semantic().is_builtin("open")
&**id == "open" && checker.semantic().is_builtin("open")
}
_ => false,
}

View File

@@ -390,11 +390,11 @@ fn return_stmt(id: &str, test: &Expr, target: &Expr, iter: &Expr, generator: Gen
};
let node2 = ast::ExprCall {
func: Box::new(node1.into()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: Box::from([node.into()]),
keywords: Box::from([]),
range: TextRange::default(),
},
}),
range: TextRange::default(),
};
let node3 = ast::StmtReturn {

View File

@@ -1,6 +1,6 @@
use ast::{ExprAttribute, ExprName, Identifier};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, Arguments, Expr, ExprCall};
use ruff_python_ast::{self as ast, Expr, ExprCall};
use ruff_text_size::Ranged;
use crate::{checkers::ast::Checker, fix::snippet::SourceCodeSnippet};
@@ -61,21 +61,19 @@ impl AlwaysFixableViolation for ZipDictKeysAndValues {
/// SIM911
pub(crate) fn zip_dict_keys_and_values(checker: &mut Checker, expr: &ExprCall) {
let ExprCall {
func,
arguments: Arguments { args, keywords, .. },
..
func, arguments, ..
} = expr;
match &keywords[..] {
match &*arguments.keywords {
[] => {}
[ast::Keyword {
arg: Some(name), ..
}] if name.as_str() == "strict" => {}
_ => return,
};
if matches!(func.as_ref(), Expr::Name(ExprName { id, .. }) if id != "zip") {
if matches!(func.as_ref(), Expr::Name(ExprName { id, .. }) if &**id != "zip") {
return;
}
let [arg1, arg2] = &args[..] else {
let [arg1, arg2] = &*arguments.args else {
return;
};
let Some((var1, attr1)) = get_var_attr(arg1) else {

View File

@@ -7,7 +7,7 @@ pub(super) fn has_slots(body: &[Stmt]) -> bool {
Stmt::Assign(ast::StmtAssign { targets, .. }) => {
for target in targets {
if let Expr::Name(ast::ExprName { id, .. }) = target {
if id.as_str() == "__slots__" {
if &**id == "__slots__" {
return true;
}
}
@@ -15,7 +15,7 @@ pub(super) fn has_slots(body: &[Stmt]) -> bool {
}
Stmt::AnnAssign(ast::StmtAnnAssign { target, .. }) => {
if let Expr::Name(ast::ExprName { id, .. }) = target.as_ref() {
if id.as_str() == "__slots__" {
if &**id == "__slots__" {
return true;
}
}

View File

@@ -13,11 +13,11 @@ fn is_empty_stmt(stmt: &Stmt) -> bool {
if let Some(exc) = exc {
match exc.as_ref() {
Expr::Name(ast::ExprName { id, .. }) => {
return id == "NotImplementedError" || id == "NotImplemented";
return &**id == "NotImplementedError" || &**id == "NotImplemented";
}
Expr::Call(ast::ExprCall { func, .. }) => {
if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() {
return id == "NotImplementedError" || id == "NotImplemented";
return &**id == "NotImplementedError" || &**id == "NotImplemented";
}
}
_ => {}

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Arguments, ConversionFlag, Expr};
use ruff_python_ast::{self as ast, ConversionFlag, Expr};
use ruff_text_size::TextRange;
/// Wrap an expression in a [`ast::FStringElement::Expression`] with no special formatting.
@@ -26,14 +26,9 @@ fn is_simple_call(expr: &Expr) -> bool {
match expr {
Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range: _,
}) => args.is_empty() && keywords.is_empty() && is_simple_callee(func),
}) => arguments.is_empty() && is_simple_callee(func),
_ => false,
}
}

View File

@@ -3,7 +3,7 @@ use itertools::Itertools;
use crate::fix::edits::pad;
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, Arguments, Expr};
use ruff_python_ast::{self as ast, Expr};
use ruff_text_size::{Ranged, TextRange};
use crate::checkers::ast::Checker;
@@ -103,20 +103,16 @@ fn build_fstring(joiner: &str, joinees: &[Expr]) -> Option<Expr> {
/// FLY002
pub(crate) fn static_join_to_fstring(checker: &mut Checker, expr: &Expr, joiner: &str) {
let Expr::Call(ast::ExprCall {
arguments: Arguments { args, keywords, .. },
..
}) = expr
else {
let Expr::Call(ast::ExprCall { arguments, .. }) = expr else {
return;
};
// If there are kwargs or more than one argument, this is some non-standard
// string join call.
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
return;
}
let [arg] = &**args else {
let [arg] = &*arguments.args else {
return;
};

View File

@@ -37,7 +37,7 @@ pub(super) fn test_expression(expr: &Expr, semantic: &SemanticModel) -> Resoluti
match &semantic.binding(id).kind {
BindingKind::Argument => {
// Avoid, e.g., `self.values`.
if matches!(name.id.as_str(), "self" | "cls") {
if matches!(&*name.id, "self" | "cls") {
Resolution::IrrelevantBinding
} else {
Resolution::RelevantLocal

View File

@@ -45,7 +45,7 @@ pub(crate) fn assignment_to_df(targets: &[Expr]) -> Option<Diagnostic> {
let Expr::Name(ast::ExprName { id, .. }) = target else {
return None;
};
if id != "df" {
if &**id != "df" {
return None;
}
Some(Diagnostic::new(PandasDfVariableName, target.range()))

View File

@@ -58,7 +58,7 @@ impl Violation for PandasUseOfPdMerge {
pub(crate) fn use_of_pd_merge(checker: &mut Checker, func: &Expr) {
if let Expr::Attribute(ast::ExprAttribute { attr, value, .. }) = func {
if let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() {
if id == "pd" && attr == "merge" {
if &**id == "pd" && attr == "merge" {
checker
.diagnostics
.push(Diagnostic::new(PandasUseOfPdMerge, func.range()));

View File

@@ -56,7 +56,7 @@ pub(crate) fn error_suffix_on_exception_name(
if !arguments.is_some_and(|arguments| {
arguments.args.iter().any(|base| {
if let Expr::Name(ast::ExprName { id, .. }) = &base {
id == "Exception" || id.ends_with("Error")
&**id == "Exception" || id.ends_with("Error")
} else {
false
}

View File

@@ -3,7 +3,7 @@ use std::fmt;
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast as ast;
use ruff_python_ast::{Arguments, Expr};
use ruff_python_ast::Expr;
use ruff_text_size::Ranged;
use crate::checkers::ast::Checker;
@@ -70,14 +70,12 @@ pub(crate) fn incorrect_dict_iterator(checker: &mut Checker, stmt_for: &ast::Stm
return;
};
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, .. },
..
func, arguments, ..
}) = stmt_for.iter.as_ref()
else {
return;
};
if !args.is_empty() {
if !arguments.is_empty() {
return;
}
let Expr::Attribute(ast::ExprAttribute { attr, .. }) = func.as_ref() else {

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Arguments, Expr, Stmt};
use ruff_python_ast::{self as ast, Expr, Stmt};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
@@ -93,23 +93,18 @@ pub(crate) fn manual_list_comprehension(checker: &mut Checker, target: &Expr, bo
let Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range,
}) = value.as_ref()
else {
return;
};
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
return;
}
let [arg] = &**args else {
let [arg] = &*arguments.args else {
return;
};

View File

@@ -1,7 +1,7 @@
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::any_over_expr;
use ruff_python_ast::{self as ast, Arguments, Expr, Stmt};
use ruff_python_ast::{self as ast, Expr, Stmt};
use ruff_python_semantic::analyze::typing::is_list;
use crate::checkers::ast::Checker;
@@ -60,23 +60,18 @@ pub(crate) fn manual_list_copy(checker: &mut Checker, target: &Expr, body: &[Stm
let Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range,
}) = value.as_ref()
else {
return;
};
if !keywords.is_empty() {
if !arguments.keywords.is_empty() {
return;
}
let [arg] = &**args else {
let [arg] = &*arguments.args else {
return;
};

View File

@@ -1,6 +1,6 @@
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, Arguments, Expr, Stmt};
use ruff_python_ast::{self as ast, Expr, Stmt};
use ruff_python_semantic::analyze::typing::find_assigned_value;
use ruff_text_size::TextRange;
@@ -52,19 +52,14 @@ impl AlwaysFixableViolation for UnnecessaryListCast {
pub(crate) fn unnecessary_list_cast(checker: &mut Checker, iter: &Expr, body: &[Stmt]) {
let Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords: _,
range: _,
},
arguments,
range: list_range,
}) = iter
else {
return;
};
let [arg] = &**args else {
let [arg] = &*arguments.args else {
return;
};
@@ -72,7 +67,7 @@ pub(crate) fn unnecessary_list_cast(checker: &mut Checker, iter: &Expr, body: &[
return;
};
if !(id == "list" && checker.semantic().is_builtin("list")) {
if &**id != "list" || !checker.semantic().is_builtin("list") {
return;
}
@@ -142,7 +137,7 @@ fn match_append(stmt: &Stmt, id: &str) -> bool {
let Some(ast::ExprName { id: target_id, .. }) = value.as_name_expr() else {
return false;
};
target_id == id
&**target_id == id
}
/// Generate a [`Fix`] to remove a `list` cast from an expression.

View File

@@ -80,7 +80,7 @@ fn deprecated_type_comparison(checker: &mut Checker, compare: &ast::ExprCompare)
continue;
};
if !(id == "type" && checker.semantic().is_builtin("type")) {
if &**id != "type" || !checker.semantic().is_builtin("type") {
continue;
}
@@ -94,7 +94,7 @@ fn deprecated_type_comparison(checker: &mut Checker, compare: &ast::ExprCompare)
continue;
};
if id == "type" && checker.semantic().is_builtin("type") {
if &**id == "type" && checker.semantic().is_builtin("type") {
// Allow comparison for types which are not obvious.
if arguments
.args
@@ -128,7 +128,7 @@ fn deprecated_type_comparison(checker: &mut Checker, compare: &ast::ExprCompare)
Expr::Name(ast::ExprName { id, .. }) => {
// Ex) `type(obj) is int`
if matches!(
id.as_str(),
&**id,
"int"
| "str"
| "float"
@@ -191,7 +191,7 @@ fn is_type(expr: &Expr, semantic: &SemanticModel) -> bool {
return false;
};
if !(id == "type" && semantic.is_builtin("type")) {
if &**id != "type" || !semantic.is_builtin("type") {
return false;
};
@@ -204,7 +204,7 @@ fn is_type(expr: &Expr, semantic: &SemanticModel) -> bool {
Expr::Name(ast::ExprName { id, .. }) => {
// Ex) `type(obj) == int`
matches!(
id.as_str(),
&**id,
"bool"
| "bytearray"
| "bytes"

View File

@@ -61,7 +61,7 @@ pub(crate) fn invalid_print_syntax(checker: &mut Checker, left: &Expr) {
let Expr::Name(ast::ExprName { id, .. }) = &left else {
return;
};
if id != "print" {
if &**id != "print" {
return;
}
if !checker.semantic().is_builtin("print") {

View File

@@ -54,13 +54,13 @@ fn match_not_implemented(expr: &Expr) -> Option<&Expr> {
match expr {
Expr::Call(ast::ExprCall { func, .. }) => {
if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() {
if id == "NotImplemented" {
if &**id == "NotImplemented" {
return Some(func);
}
}
}
Expr::Name(ast::ExprName { id, .. }) => {
if id == "NotImplemented" {
if &**id == "NotImplemented" {
return Some(expr);
}
}

View File

@@ -747,7 +747,7 @@ pub(crate) fn string_dot_format_extra_named_arguments(
let missing: Vec<(usize, &str)> = keywords
.enumerate()
.filter_map(|(index, keyword)| {
if summary.keywords.contains(keyword.as_ref()) {
if summary.keywords.iter().any(|k| k == keyword.as_str()) {
None
} else {
Some((index, keyword.as_str()))

View File

@@ -122,17 +122,17 @@ impl SequenceIndexVisitor<'_> {
// diagnostics.
match expr {
Expr::Name(ast::ExprName { id, .. }) => {
id == self.sequence_name || id == self.index_name || id == self.value_name
&**id == self.sequence_name || &**id == self.index_name || &**id == self.value_name
}
Expr::Subscript(ast::ExprSubscript { value, slice, .. }) => {
let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() else {
return false;
};
if id == self.sequence_name {
if &**id == self.sequence_name {
let Expr::Name(ast::ExprName { id, .. }) = slice.as_ref() else {
return false;
};
if id == self.index_name {
if &**id == self.index_name {
return true;
}
}
@@ -184,11 +184,11 @@ impl<'a> Visitor<'_> for SequenceIndexVisitor<'a> {
let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() else {
return;
};
if id == self.sequence_name {
if &**id == self.sequence_name {
let Expr::Name(ast::ExprName { id, .. }) = slice.as_ref() else {
return;
};
if id == self.index_name {
if &**id == self.index_name {
self.accesses.push(*range);
}
}

View File

@@ -98,7 +98,7 @@ fn is_open(func: &Expr, semantic: &SemanticModel) -> Option<Kind> {
}
// Ex) `open(...)`
Expr::Name(ast::ExprName { id, .. }) => {
(id.as_str() == "open" && semantic.is_builtin("open")).then_some(Kind::Builtin)
(&**id == "open" && semantic.is_builtin("open")).then_some(Kind::Builtin)
}
_ => None,
}

View File

@@ -193,7 +193,7 @@ fn is_valid_dict(
.map(|mapping_key| (mapping_key.as_str(), format))
})
.collect();
for (key, value) in keys.iter().zip(values) {
for (key, value) in keys.iter().zip(values.iter()) {
let Some(key) = key else {
return true;
};

View File

@@ -107,7 +107,7 @@ pub(crate) fn comparison_with_itself(
// The call must be to pure function, like `id`.
if matches!(
left_func.id.as_str(),
&*left_func.id,
"id" | "len" | "type" | "int" | "bool" | "str" | "repr" | "bytes"
) && checker.semantic().is_builtin(&left_func.id)
{

View File

@@ -80,7 +80,7 @@ fn has_eq_without_hash(body: &[Stmt]) -> bool {
//
// __hash__ = None
// ```
if id == "__hash__" && value.is_none_literal_expr() {
if &**id == "__hash__" && value.is_none_literal_expr() {
has_hash = true;
}
}

View File

@@ -71,9 +71,9 @@ impl MinMax {
let Expr::Name(ast::ExprName { id, .. }) = func else {
return None;
};
if id.as_str() == "min" && semantic.is_builtin("min") {
if &**id == "min" && semantic.is_builtin("min") {
Some(MinMax::Min)
} else if id.as_str() == "max" && semantic.is_builtin("max") {
} else if &**id == "max" && semantic.is_builtin("max") {
Some(MinMax::Max)
} else {
None
@@ -97,16 +97,11 @@ fn collect_nested_args(min_max: MinMax, args: &[Expr], semantic: &SemanticModel)
for arg in args {
if let Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
},
arguments,
range: _,
}) = arg
{
if let [arg] = &**args {
if let [arg] = &*arguments.args {
if arg.as_starred_expr().is_none() {
let new_arg = Expr::Starred(ast::ExprStarred {
value: Box::new(arg.clone()),
@@ -117,8 +112,8 @@ fn collect_nested_args(min_max: MinMax, args: &[Expr], semantic: &SemanticModel)
continue;
}
}
if MinMax::try_from_call(func, keywords, semantic) == Some(min_max) {
inner(min_max, args, semantic, new_args);
if MinMax::try_from_call(func, &arguments.keywords, semantic) == Some(min_max) {
inner(min_max, &arguments.args, semantic, new_args);
continue;
}
}
@@ -143,31 +138,29 @@ pub(crate) fn nested_min_max(
return;
};
if matches!(&args, [Expr::Call(ast::ExprCall { arguments: Arguments {args, .. }, .. })] if args.len() == 1)
{
if matches!(&args, [Expr::Call(ast::ExprCall { arguments, .. })] if arguments.args.len() == 1) {
return;
}
if args.iter().any(|arg| {
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { keywords, .. },
..
func, arguments, ..
}) = arg
else {
return false;
};
MinMax::try_from_call(func.as_ref(), keywords.as_ref(), checker.semantic()) == Some(min_max)
let keywords = arguments.keywords.as_ref();
MinMax::try_from_call(func.as_ref(), keywords, checker.semantic()) == Some(min_max)
}) {
let mut diagnostic = Diagnostic::new(NestedMinMax { func: min_max }, expr.range());
if !checker.indexer().has_comments(expr, checker.locator()) {
let flattened_expr = Expr::Call(ast::ExprCall {
func: Box::new(func.clone()),
arguments: Arguments {
arguments: Box::new(Arguments {
args: collect_nested_args(min_max, args, checker.semantic()).into_boxed_slice(),
keywords: Box::from(keywords),
range: TextRange::default(),
},
}),
range: TextRange::default(),
});
diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement(

View File

@@ -100,7 +100,7 @@ fn get_undecorated_methods(
class_def: &ast::StmtClassDef,
method_type: &MethodType,
) {
let mut explicit_decorator_calls: HashMap<String, TextRange> = HashMap::default();
let mut explicit_decorator_calls: HashMap<Box<str>, TextRange> = HashMap::default();
let (method_name, diagnostic_type): (&str, DiagnosticKind) = match method_type {
MethodType::Classmethod => ("classmethod", NoClassmethodDecorator.into()),
@@ -115,7 +115,7 @@ fn get_undecorated_methods(
}) = value.as_ref()
{
if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() {
if id == method_name && checker.semantic().is_builtin(method_name) {
if &**id == method_name && checker.semantic().is_builtin(method_name) {
if arguments.args.len() != 1 {
continue;
}
@@ -130,7 +130,7 @@ fn get_undecorated_methods(
};
if let Expr::Name(ast::ExprName { id, .. }) = &arguments.args[0] {
if target_name == *id {
if target_name == **id {
explicit_decorator_calls.insert(id.clone(), stmt.range());
}
};
@@ -158,7 +158,7 @@ fn get_undecorated_methods(
// if we find the decorator we're looking for, skip
if decorator_list.iter().any(|decorator| {
if let Expr::Name(ast::ExprName { id, .. }) = &decorator.expression {
if id == method_name && checker.semantic().is_builtin(method_name) {
if &**id == method_name && checker.semantic().is_builtin(method_name) {
return true;
}
}

View File

@@ -108,7 +108,7 @@ fn is_attributes_not_in_slots(body: &[Stmt]) -> Vec<AttributeAssignment> {
continue;
};
if id == "__slots__" {
if &**id == "__slots__" {
slots.extend(slots_attributes(value));
}
}
@@ -123,7 +123,7 @@ fn is_attributes_not_in_slots(body: &[Stmt]) -> Vec<AttributeAssignment> {
continue;
};
if id == "__slots__" {
if &**id == "__slots__" {
slots.extend(slots_attributes(value));
}
}
@@ -134,7 +134,7 @@ fn is_attributes_not_in_slots(body: &[Stmt]) -> Vec<AttributeAssignment> {
continue;
};
if id == "__slots__" {
if &**id == "__slots__" {
slots.extend(slots_attributes(value));
}
}
@@ -164,7 +164,7 @@ fn is_attributes_not_in_slots(body: &[Stmt]) -> Vec<AttributeAssignment> {
let Expr::Name(ast::ExprName { id, .. }) = attribute.value.as_ref() else {
continue;
};
if id == "self" && !slots.contains(attribute.attr.as_str()) {
if &**id == "self" && !slots.contains(attribute.attr.as_str()) {
assignments.push(AttributeAssignment {
name: &attribute.attr,
range: attribute.range(),
@@ -180,7 +180,7 @@ fn is_attributes_not_in_slots(body: &[Stmt]) -> Vec<AttributeAssignment> {
let Expr::Name(ast::ExprName { id, .. }) = attribute.value.as_ref() else {
continue;
};
if id == "self" && !slots.contains(attribute.attr.as_str()) {
if &**id == "self" && !slots.contains(attribute.attr.as_str()) {
assignments.push(AttributeAssignment {
name: &attribute.attr,
range: attribute.range(),
@@ -196,7 +196,7 @@ fn is_attributes_not_in_slots(body: &[Stmt]) -> Vec<AttributeAssignment> {
let Expr::Name(ast::ExprName { id, .. }) = attribute.value.as_ref() else {
continue;
};
if id == "self" && !slots.contains(attribute.attr.as_str()) {
if &**id == "self" && !slots.contains(attribute.attr.as_str()) {
assignments.push(AttributeAssignment {
name: &attribute.attr,
range: attribute.range(),

View File

@@ -55,7 +55,7 @@ pub(crate) fn property_with_parameters(
) {
if !decorator_list
.iter()
.any(|decorator| matches!(&decorator.expression, Expr::Name(ast::ExprName { id, .. }) if id == "property"))
.any(|decorator| matches!(&decorator.expression, Expr::Name(ast::ExprName { id, .. }) if &**id =="property"))
{
return;
}

View File

@@ -1,7 +1,7 @@
use std::{fmt, iter};
use regex::Regex;
use ruff_python_ast::{self as ast, Arguments, Expr, ExprContext, Stmt, WithItem};
use ruff_python_ast::{self as ast, Expr, ExprContext, Stmt, WithItem};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
@@ -238,9 +238,7 @@ fn assignment_is_cast_expr(value: &Expr, target: &Expr, semantic: &SemanticModel
}
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, .. },
..
func, arguments, ..
}) = value
else {
return false;
@@ -248,10 +246,10 @@ fn assignment_is_cast_expr(value: &Expr, target: &Expr, semantic: &SemanticModel
let Expr::Name(ast::ExprName { id: target_id, .. }) = target else {
return false;
};
if args.len() != 2 {
if arguments.args.len() != 2 {
return false;
}
let Expr::Name(ast::ExprName { id: arg_id, .. }) = &args[1] else {
let Expr::Name(ast::ExprName { id: arg_id, .. }) = &arguments.args[1] else {
return false;
};
if arg_id != target_id {

View File

@@ -1,5 +1,5 @@
use itertools::Itertools;
use ruff_python_ast::{self as ast, Arguments, BoolOp, Expr};
use ruff_python_ast::{self as ast, BoolOp, Expr};
use rustc_hash::{FxHashMap, FxHashSet};
use crate::fix::edits::pad;
@@ -85,17 +85,15 @@ pub(crate) fn repeated_isinstance_calls(
FxHashMap::default();
for value in values {
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, .. },
..
func, arguments, ..
}) = value
else {
continue;
};
if !matches!(func.as_ref(), Expr::Name(ast::ExprName { id, .. }) if id == "isinstance") {
if !matches!(func.as_ref(), Expr::Name(ast::ExprName { id, .. }) if &**id =="isinstance") {
continue;
}
let [obj, types] = &args[..] else {
let [obj, types] = &*arguments.args else {
continue;
};
if !checker.semantic().is_builtin("isinstance") {

View File

@@ -64,7 +64,7 @@ pub(crate) fn single_string_slots(checker: &mut Checker, class: &StmtClassDef) {
Stmt::Assign(ast::StmtAssign { targets, value, .. }) => {
for target in targets {
if let Expr::Name(ast::ExprName { id, .. }) = target {
if id.as_str() == "__slots__" {
if &**id == "__slots__" {
if matches!(value.as_ref(), Expr::StringLiteral(_) | Expr::FString(_)) {
checker
.diagnostics
@@ -80,7 +80,7 @@ pub(crate) fn single_string_slots(checker: &mut Checker, class: &StmtClassDef) {
..
}) => {
if let Expr::Name(ast::ExprName { id, .. }) = target.as_ref() {
if id.as_str() == "__slots__" {
if &**id == "__slots__" {
if matches!(value.as_ref(), Expr::StringLiteral(_) | Expr::FString(_)) {
checker
.diagnostics

View File

@@ -68,11 +68,11 @@ pub(crate) fn super_without_brackets(checker: &mut Checker, func: &Expr) {
return;
};
if id.as_str() != "super" {
if &**id != "super" {
return;
}
if !checker.semantic().is_builtin(id.as_str()) {
if !checker.semantic().is_builtin(id) {
return;
}

View File

@@ -62,11 +62,11 @@ pub(crate) fn sys_exit_alias(checker: &mut Checker, func: &Expr) {
return;
};
if !matches!(id.as_str(), "exit" | "quit") {
if !matches!(&**id, "exit" | "quit") {
return;
}
if !checker.semantic().is_builtin(id.as_str()) {
if !checker.semantic().is_builtin(id) {
return;
}

View File

@@ -83,7 +83,7 @@ pub(crate) fn type_param_name_mismatch(checker: &mut Checker, value: &Expr, targ
return;
};
if var_name == param_name {
if &**var_name == param_name {
return;
}

View File

@@ -128,7 +128,7 @@ fn dict_items<'a>(
let Expr::Attribute(ast::ExprAttribute { value, attr, .. }) = func.as_ref() else {
return None;
};
if attr != "items" {
if &**attr != "items" {
return None;
}
@@ -154,7 +154,7 @@ fn dict_items<'a>(
// If either of the variable names are intentionally ignored by naming them `_`, then don't
// emit.
if index_name.id == "_" || value_name.id == "_" {
if &*index_name.id == "_" || &*value_name.id == "_" {
return None;
}

View File

@@ -95,7 +95,7 @@ pub(crate) fn unnecessary_dunder_call(checker: &mut Checker, call: &ast::ExprCal
if let Expr::Call(ast::ExprCall { func, .. }) = value.as_ref() {
if checker.semantic().is_builtin("super") {
if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() {
if id == "super" {
if &**id == "super" {
return;
}
}

View File

@@ -135,7 +135,7 @@ pub(crate) fn unnecessary_lambda(checker: &mut Checker, lambda: &ExprLambda) {
return;
};
if id.as_str() != kwarg.name.as_str() {
if **id != *kwarg.name {
return;
}
}
@@ -157,7 +157,7 @@ pub(crate) fn unnecessary_lambda(checker: &mut Checker, lambda: &ExprLambda) {
return;
};
if id.as_str() != vararg.name.as_str() {
if **id != *vararg.name {
return;
}
}
@@ -176,7 +176,7 @@ pub(crate) fn unnecessary_lambda(checker: &mut Checker, lambda: &ExprLambda) {
let Expr::Name(ast::ExprName { id, .. }) = arg else {
return;
};
if id.as_str() != param.name.as_str() {
if **id != *param.name {
return;
}
}

View File

@@ -150,7 +150,7 @@ fn enumerate_items<'a>(
// If either of the variable names are intentionally ignored by naming them `_`, then don't
// emit.
if index_name.id == "_" || value_name.id == "_" {
if &*index_name.id == "_" || &*value_name.id == "_" {
return None;
}

View File

@@ -135,7 +135,7 @@ fn match_named_tuple_assign<'a>(
};
let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, keywords, .. },
arguments,
range: _,
}) = value
else {
@@ -144,7 +144,7 @@ fn match_named_tuple_assign<'a>(
if !semantic.match_typing_expr(func, "NamedTuple") {
return None;
}
Some((typename, args, keywords, func))
Some((typename, &arguments.args, &arguments.keywords, func))
}
/// Generate a [`Stmt::AnnAssign`] representing the provided field definition.

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