mirror of https://github.com/astral-sh/ruff
Make Arguments boxed
This commit is contained in:
parent
7a349660e4
commit
4e23ee0e1d
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -84,11 +84,7 @@ pub(crate) fn unnecessary_double_cast_or_process(
|
|||
return;
|
||||
};
|
||||
let Expr::Call(ast::ExprCall {
|
||||
func,
|
||||
arguments: Arguments {
|
||||
keywords: inner_kw, ..
|
||||
},
|
||||
..
|
||||
func, arguments, ..
|
||||
}) = arg
|
||||
else {
|
||||
return;
|
||||
|
|
@ -103,10 +99,10 @@ 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 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))
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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, .. }) => {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -303,21 +303,16 @@ 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 {
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,11 +61,9 @@ 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), ..
|
||||
|
|
@ -75,7 +73,7 @@ pub(crate) fn zip_dict_keys_and_values(checker: &mut Checker, expr: &ExprCall) {
|
|||
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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
arguments,
|
||||
range: _,
|
||||
},
|
||||
range: _,
|
||||
}) => args.is_empty() && keywords.is_empty() && is_simple_callee(func),
|
||||
}) => arguments.is_empty() && is_simple_callee(func),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,9 +85,7 @@ 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;
|
||||
|
|
@ -95,7 +93,7 @@ pub(crate) fn repeated_isinstance_calls(
|
|||
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") {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -238,9 +238,9 @@ fn match_fields_and_total(arguments: &Arguments) -> Option<(Vec<Stmt>, Option<&K
|
|||
}) => Some((fields_from_dict_literal(keys, values)?, total)),
|
||||
Expr::Call(ast::ExprCall {
|
||||
func,
|
||||
arguments: Arguments { keywords, .. },
|
||||
arguments,
|
||||
range: _,
|
||||
}) => Some((fields_from_dict_call(func, keywords)?, total)),
|
||||
}) => Some((fields_from_dict_call(func, &arguments.keywords)?, total)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_python_ast::{self as ast, Arguments, Decorator, Expr, Keyword};
|
||||
use ruff_python_ast::{self as ast, Decorator, Expr, Keyword};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||
|
|
@ -59,12 +59,7 @@ pub(crate) fn lru_cache_with_maxsize_none(checker: &mut Checker, decorator_list:
|
|||
for decorator in decorator_list {
|
||||
let Expr::Call(ast::ExprCall {
|
||||
func,
|
||||
arguments:
|
||||
Arguments {
|
||||
args,
|
||||
keywords,
|
||||
range: _,
|
||||
},
|
||||
arguments,
|
||||
range: _,
|
||||
}) = &decorator.expression
|
||||
else {
|
||||
|
|
@ -72,8 +67,8 @@ pub(crate) fn lru_cache_with_maxsize_none(checker: &mut Checker, decorator_list:
|
|||
};
|
||||
|
||||
// Look for, e.g., `import functools; @functools.lru_cache(maxsize=None)`.
|
||||
if args.is_empty()
|
||||
&& keywords.len() == 1
|
||||
if arguments.args.is_empty()
|
||||
&& arguments.keywords.len() == 1
|
||||
&& checker
|
||||
.semantic()
|
||||
.resolve_call_path(func)
|
||||
|
|
@ -83,7 +78,7 @@ pub(crate) fn lru_cache_with_maxsize_none(checker: &mut Checker, decorator_list:
|
|||
arg,
|
||||
value,
|
||||
range: _,
|
||||
} = &keywords[0];
|
||||
} = &arguments.keywords[0];
|
||||
if arg.as_ref().is_some_and(|arg| arg == "maxsize") && value.is_none_literal_expr() {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
LRUCacheWithMaxsizeNone,
|
||||
|
|
|
|||
|
|
@ -141,12 +141,7 @@ pub(crate) fn native_literals(
|
|||
) {
|
||||
let ast::ExprCall {
|
||||
func,
|
||||
arguments:
|
||||
ast::Arguments {
|
||||
args,
|
||||
keywords,
|
||||
range: _,
|
||||
},
|
||||
arguments,
|
||||
range: _,
|
||||
} = call;
|
||||
|
||||
|
|
@ -154,7 +149,7 @@ pub(crate) fn native_literals(
|
|||
return;
|
||||
};
|
||||
|
||||
if !keywords.is_empty() || args.len() > 1 {
|
||||
if !arguments.keywords.is_empty() || arguments.args.len() > 1 {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -179,7 +174,7 @@ pub(crate) fn native_literals(
|
|||
}
|
||||
}
|
||||
|
||||
match args.first() {
|
||||
match arguments.args.first() {
|
||||
None => {
|
||||
let mut diagnostic = Diagnostic::new(NativeLiterals { literal_type }, call.range());
|
||||
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@ pub(super) fn generate_method_call(name: &str, method: &str, generator: Generato
|
|||
// Make it into a call `name.method()`
|
||||
let call = ast::ExprCall {
|
||||
func: Box::new(attr.into()),
|
||||
arguments: ast::Arguments {
|
||||
arguments: Box::new(ast::Arguments {
|
||||
args: Box::from([]),
|
||||
keywords: Box::from([]),
|
||||
range: TextRange::default(),
|
||||
},
|
||||
}),
|
||||
range: TextRange::default(),
|
||||
};
|
||||
// And finally, turn it into a statement.
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ fn match_remove(if_stmt: &ast::StmtIf) -> Option<(&Expr, &ast::ExprName)> {
|
|||
|
||||
let ast::ExprCall {
|
||||
func: attr,
|
||||
arguments: ast::Arguments { args, keywords, .. },
|
||||
arguments,
|
||||
..
|
||||
} = expr.as_call_expr()?;
|
||||
|
||||
|
|
@ -165,11 +165,11 @@ fn match_remove(if_stmt: &ast::StmtIf) -> Option<(&Expr, &ast::ExprName)> {
|
|||
return None;
|
||||
};
|
||||
|
||||
let [arg] = &**args else {
|
||||
let [arg] = &*arguments.args else {
|
||||
return None;
|
||||
};
|
||||
|
||||
if func_name != "remove" || !keywords.is_empty() {
|
||||
if func_name != "remove" || !arguments.keywords.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
@ -190,11 +190,11 @@ fn make_suggestion(set: &ast::ExprName, element: &Expr, generator: Generator) ->
|
|||
// Make the actual call `set.discard(element)`
|
||||
let call = ast::ExprCall {
|
||||
func: Box::new(attr.into()),
|
||||
arguments: ast::Arguments {
|
||||
arguments: Box::new(ast::Arguments {
|
||||
args: Box::from([element.clone()]),
|
||||
keywords: Box::from([]),
|
||||
range: TextRange::default(),
|
||||
},
|
||||
}),
|
||||
range: TextRange::default(),
|
||||
};
|
||||
// And finally, turn it into a statement.
|
||||
|
|
|
|||
|
|
@ -136,9 +136,7 @@ fn find_file_open<'a>(
|
|||
) -> Option<FileOpen<'a>> {
|
||||
// We want to match `open(...) as var`.
|
||||
let ast::ExprCall {
|
||||
func,
|
||||
arguments: ast::Arguments { args, keywords, .. },
|
||||
..
|
||||
func, arguments, ..
|
||||
} = item.context_expr.as_call_expr()?;
|
||||
|
||||
let func = func.as_name_expr()?;
|
||||
|
|
@ -151,17 +149,20 @@ fn find_file_open<'a>(
|
|||
// Ignore calls with `*args` and `**kwargs`. In the exact case of `open(*filename, mode="r")`,
|
||||
// it could be a match; but in all other cases, the call _could_ contain unsupported keyword
|
||||
// arguments, like `buffering`.
|
||||
if args.iter().any(Expr::is_starred_expr)
|
||||
|| keywords.iter().any(|keyword| keyword.arg.is_none())
|
||||
if arguments.args.iter().any(Expr::is_starred_expr)
|
||||
|| arguments
|
||||
.keywords
|
||||
.iter()
|
||||
.any(|keyword| keyword.arg.is_none())
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
// Match positional arguments, get filename and read mode.
|
||||
let (filename, pos_mode) = match_open_args(args)?;
|
||||
let (filename, pos_mode) = match_open_args(&arguments.args)?;
|
||||
|
||||
// Match keyword arguments, get keyword arguments to forward and possibly read mode.
|
||||
let (keywords, kw_mode) = match_open_keywords(keywords)?;
|
||||
let (keywords, kw_mode) = match_open_keywords(&arguments.keywords)?;
|
||||
|
||||
// `pos_mode` could've been assigned default value corresponding to "r", while
|
||||
// keyword mode should override that.
|
||||
|
|
@ -322,11 +323,11 @@ fn make_suggestion(open: &FileOpen<'_>, generator: Generator) -> SourceCodeSnipp
|
|||
};
|
||||
let call = ast::ExprCall {
|
||||
func: Box::new(name.into()),
|
||||
arguments: ast::Arguments {
|
||||
arguments: Box::new(ast::Arguments {
|
||||
args: Box::from([]),
|
||||
keywords: open.keywords.iter().copied().cloned().collect(),
|
||||
range: TextRange::default(),
|
||||
},
|
||||
}),
|
||||
range: TextRange::default(),
|
||||
};
|
||||
SourceCodeSnippet::from_str(&generator.expr(&call.into()))
|
||||
|
|
|
|||
|
|
@ -303,11 +303,11 @@ fn construct_starmap_call(starmap_binding: String, iter: &Expr, func: &Expr) ->
|
|||
};
|
||||
ast::ExprCall {
|
||||
func: Box::new(starmap.into()),
|
||||
arguments: ast::Arguments {
|
||||
arguments: Box::new(ast::Arguments {
|
||||
args: Box::from([func.clone(), iter.clone()]),
|
||||
keywords: Box::from([]),
|
||||
range: TextRange::default(),
|
||||
},
|
||||
}),
|
||||
range: TextRange::default(),
|
||||
}
|
||||
}
|
||||
|
|
@ -321,11 +321,11 @@ fn wrap_with_call_to(call: ast::ExprCall, func_name: &str) -> ast::ExprCall {
|
|||
};
|
||||
ast::ExprCall {
|
||||
func: Box::new(name.into()),
|
||||
arguments: ast::Arguments {
|
||||
arguments: Box::new(ast::Arguments {
|
||||
args: Box::from([call.into()]),
|
||||
keywords: Box::from([]),
|
||||
range: TextRange::default(),
|
||||
},
|
||||
}),
|
||||
range: TextRange::default(),
|
||||
}
|
||||
}
|
||||
|
|
@ -353,14 +353,12 @@ fn match_comprehension_target(comprehension: &ast::Comprehension) -> Option<Comp
|
|||
/// Match that the given expression is `func(x, y, z, ...)`.
|
||||
fn match_call(element: &Expr) -> Option<(&[Expr], &Expr)> {
|
||||
let ast::ExprCall {
|
||||
func,
|
||||
arguments: ast::Arguments { args, keywords, .. },
|
||||
..
|
||||
func, arguments, ..
|
||||
} = element.as_call_expr()?;
|
||||
|
||||
if !keywords.is_empty() {
|
||||
if !arguments.keywords.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some((args, func))
|
||||
Some((&arguments.args, func))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -359,11 +359,11 @@ fn make_suggestion(group: &AppendGroup, generator: Generator) -> String {
|
|||
// Make the actual call `var.extend((elt1, elt2, ..., eltN))`
|
||||
let call = ast::ExprCall {
|
||||
func: Box::new(attr.into()),
|
||||
arguments: ast::Arguments {
|
||||
arguments: Box::new(ast::Arguments {
|
||||
args: Box::from([tuple.into()]),
|
||||
keywords: Box::from([]),
|
||||
range: TextRange::default(),
|
||||
},
|
||||
}),
|
||||
range: TextRange::default(),
|
||||
};
|
||||
// And finally, turn it into a statement.
|
||||
|
|
|
|||
|
|
@ -250,11 +250,11 @@ fn generate_range_len_call(name: &str, generator: Generator) -> String {
|
|||
}
|
||||
.into(),
|
||||
),
|
||||
arguments: Arguments {
|
||||
arguments: Box::new(Arguments {
|
||||
args: Box::from([var.into()]),
|
||||
keywords: Box::from([]),
|
||||
range: TextRange::default(),
|
||||
},
|
||||
}),
|
||||
range: TextRange::default(),
|
||||
};
|
||||
// Construct `range(len(name))`.
|
||||
|
|
@ -267,11 +267,11 @@ fn generate_range_len_call(name: &str, generator: Generator) -> String {
|
|||
}
|
||||
.into(),
|
||||
),
|
||||
arguments: Arguments {
|
||||
arguments: Box::new(Arguments {
|
||||
args: Box::from([len.into()]),
|
||||
keywords: Box::from([]),
|
||||
range: TextRange::default(),
|
||||
},
|
||||
}),
|
||||
range: TextRange::default(),
|
||||
};
|
||||
// And finally, turn it into a statement.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use anyhow::{bail, Result};
|
|||
|
||||
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_python_codegen::Stylist;
|
||||
use ruff_source_file::Locator;
|
||||
use ruff_text_size::Ranged;
|
||||
|
|
@ -69,26 +69,19 @@ pub(crate) fn explicit_f_string_type_conversion(checker: &mut Checker, f_string:
|
|||
}
|
||||
|
||||
let Expr::Call(ast::ExprCall {
|
||||
func,
|
||||
arguments:
|
||||
Arguments {
|
||||
args,
|
||||
keywords,
|
||||
range: _,
|
||||
},
|
||||
..
|
||||
func, arguments, ..
|
||||
}) = expression.as_ref()
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Can't be a conversion otherwise.
|
||||
if !keywords.is_empty() {
|
||||
if !arguments.keywords.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Can't be a conversion otherwise.
|
||||
let [arg] = &**args else {
|
||||
let [arg] = &*arguments.args else {
|
||||
continue;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -99,9 +99,7 @@ fn should_be_fstring(
|
|||
for expr in semantic.current_expressions() {
|
||||
match expr {
|
||||
ast::Expr::Call(ast::ExprCall {
|
||||
arguments: ast::Arguments { keywords, args, .. },
|
||||
func,
|
||||
..
|
||||
arguments, func, ..
|
||||
}) => {
|
||||
if let ast::Expr::Attribute(ast::ExprAttribute { value, .. }) = func.as_ref() {
|
||||
match value.as_ref() {
|
||||
|
|
@ -123,12 +121,12 @@ fn should_be_fstring(
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
for keyword in keywords.iter() {
|
||||
for keyword in arguments.keywords.iter() {
|
||||
if let Some(ident) = keyword.arg.as_ref() {
|
||||
arg_names.insert(ident.as_str());
|
||||
}
|
||||
}
|
||||
for arg in args.iter() {
|
||||
for arg in arguments.args.iter() {
|
||||
if let ast::Expr::Name(ast::ExprName { id, .. }) = arg {
|
||||
arg_names.insert(&**id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,12 +102,10 @@ pub(crate) fn sort_dunder_all_aug_assign(checker: &mut Checker, node: &ast::Stmt
|
|||
pub(crate) fn sort_dunder_all_extend_call(
|
||||
checker: &mut Checker,
|
||||
ast::ExprCall {
|
||||
func,
|
||||
arguments: ast::Arguments { args, keywords, .. },
|
||||
..
|
||||
func, arguments, ..
|
||||
}: &ast::ExprCall,
|
||||
) {
|
||||
let ([value_passed], []) = (&**args, &**keywords) else {
|
||||
let ([value_passed], []) = (&*arguments.args, &*arguments.keywords) else {
|
||||
return;
|
||||
};
|
||||
let ast::Expr::Attribute(ast::ExprAttribute {
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ fn is_constant_like(expr: &Expr) -> bool {
|
|||
/// - Given `{n: 1 for n in [1,2,3]}`, generate `dict.fromkeys([1,2,3], 1)`.
|
||||
fn fix_unnecessary_dict_comprehension(value: &Expr, generator: &Comprehension) -> Expr {
|
||||
let iterable = generator.iter.clone();
|
||||
let args = Arguments {
|
||||
let arguments = Arguments {
|
||||
args: if value.is_none_literal_expr() {
|
||||
Box::from([iterable])
|
||||
} else {
|
||||
|
|
@ -173,7 +173,7 @@ fn fix_unnecessary_dict_comprehension(value: &Expr, generator: &Comprehension) -
|
|||
ctx: ExprContext::Load,
|
||||
range: TextRange::default(),
|
||||
})),
|
||||
arguments: args,
|
||||
arguments: Box::new(arguments),
|
||||
range: TextRange::default(),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::borrow::Cow;
|
|||
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::{self as ast, Arguments, Comprehension, Expr, Int};
|
||||
use ruff_python_ast::{self as ast, Comprehension, Expr, Int};
|
||||
use ruff_python_semantic::SemanticModel;
|
||||
use ruff_python_stdlib::builtins::is_iterator;
|
||||
use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||
|
|
@ -136,9 +136,7 @@ struct IterationTarget {
|
|||
fn match_iteration_target(expr: &Expr, semantic: &SemanticModel) -> Option<IterationTarget> {
|
||||
let result = match expr {
|
||||
Expr::Call(ast::ExprCall {
|
||||
func,
|
||||
arguments: Arguments { args, .. },
|
||||
..
|
||||
func, arguments, ..
|
||||
}) => {
|
||||
let ast::ExprName { id, .. } = func.as_name_expr()?;
|
||||
|
||||
|
|
@ -146,7 +144,7 @@ fn match_iteration_target(expr: &Expr, semantic: &SemanticModel) -> Option<Itera
|
|||
return None;
|
||||
}
|
||||
|
||||
let [arg] = &**args else {
|
||||
let [arg] = &*arguments.args else {
|
||||
return None;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
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;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
|
@ -56,15 +56,13 @@ impl Violation for RaiseVanillaArgs {
|
|||
/// TRY003
|
||||
pub(crate) fn raise_vanilla_args(checker: &mut Checker, expr: &Expr) {
|
||||
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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -909,7 +909,7 @@ impl From<ExprCompare> for Expr {
|
|||
pub struct ExprCall {
|
||||
pub range: TextRange,
|
||||
pub func: Box<Expr>,
|
||||
pub arguments: Arguments,
|
||||
pub arguments: Box<Arguments>,
|
||||
}
|
||||
|
||||
impl From<ExprCall> for Expr {
|
||||
|
|
@ -3891,14 +3891,14 @@ mod tests {
|
|||
// 88 for Rustc < 1.76
|
||||
assert!(matches!(std::mem::size_of::<Pattern>(), 80 | 88));
|
||||
|
||||
assert_eq!(std::mem::size_of::<Expr>(), 64);
|
||||
assert_eq!(std::mem::size_of::<Expr>(), 56);
|
||||
assert_eq!(std::mem::size_of::<ExprAttribute>(), 48);
|
||||
assert_eq!(std::mem::size_of::<ExprAwait>(), 16);
|
||||
assert_eq!(std::mem::size_of::<ExprBinOp>(), 32);
|
||||
assert_eq!(std::mem::size_of::<ExprBoolOp>(), 40);
|
||||
assert_eq!(std::mem::size_of::<ExprBooleanLiteral>(), 12);
|
||||
assert_eq!(std::mem::size_of::<ExprBytesLiteral>(), 40);
|
||||
assert_eq!(std::mem::size_of::<ExprCall>(), 56);
|
||||
assert_eq!(std::mem::size_of::<ExprCall>(), 24);
|
||||
assert_eq!(std::mem::size_of::<ExprCompare>(), 48);
|
||||
assert_eq!(std::mem::size_of::<ExprDict>(), 40);
|
||||
assert_eq!(std::mem::size_of::<ExprDictComp>(), 48);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ fn test_parenthesized_argument() {
|
|||
let expr = parse_expression(source_code).unwrap();
|
||||
|
||||
let call = expr.as_call_expr().unwrap();
|
||||
let arguments = &call.arguments;
|
||||
let arguments = &*call.arguments;
|
||||
let argument = arguments.args.first().unwrap();
|
||||
|
||||
let parenthesized = parenthesized_range(
|
||||
|
|
@ -61,7 +61,7 @@ fn test_non_parenthesized_argument() {
|
|||
let expr = parse_expression(source_code).unwrap();
|
||||
|
||||
let call = expr.as_call_expr().unwrap();
|
||||
let arguments = &call.arguments;
|
||||
let arguments = &*call.arguments;
|
||||
let argument = arguments.args.first().unwrap();
|
||||
|
||||
let parenthesized = parenthesized_range(
|
||||
|
|
@ -130,7 +130,7 @@ fn test_twice_parenthesized_argument() {
|
|||
let expr = parse_expression(source_code).unwrap();
|
||||
|
||||
let call = expr.as_call_expr().unwrap();
|
||||
let arguments = &call.arguments;
|
||||
let arguments = &*call.arguments;
|
||||
let argument = arguments.args.first().unwrap();
|
||||
|
||||
let parenthesized = parenthesized_range(
|
||||
|
|
|
|||
|
|
@ -1549,7 +1549,7 @@ AtomExpr2<Goal>: crate::parser::ParenthesizedExpr = {
|
|||
Atom<Goal>,
|
||||
<location:@L> <func:AtomExpr2<"all">> <arguments:Arguments> <end_location:@R> => ast::ExprCall {
|
||||
func: Box::new(func.into()),
|
||||
arguments,
|
||||
arguments: Box::new(arguments),
|
||||
range: (location..end_location).into(),
|
||||
}.into(),
|
||||
<location:@L> <value:AtomExpr2<"all">> "[" <slice:SubscriptList> "]" <end_location:@R> => ast::ExprSubscript {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// auto-generated: "lalrpop 0.20.0"
|
||||
// sha3: 8f9c419cf07ccd6289047223fa22bb70c6afd0133b58ea606f601340160cab8b
|
||||
// sha3: 06d23132da088f5a6184a546b53be668a940ce6dfd046b5ac08b6e70b7c9eb99
|
||||
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
|
||||
use ruff_python_ast::{self as ast, Int, IpyEscapeKind};
|
||||
use crate::{
|
||||
|
|
@ -41071,7 +41071,7 @@ fn __action541<
|
|||
{
|
||||
ast::ExprCall {
|
||||
func: Box::new(func.into()),
|
||||
arguments,
|
||||
arguments: Box::new(arguments),
|
||||
range: (location..end_location).into(),
|
||||
}.into()
|
||||
}
|
||||
|
|
@ -41868,7 +41868,7 @@ fn __action588<
|
|||
{
|
||||
ast::ExprCall {
|
||||
func: Box::new(func.into()),
|
||||
arguments,
|
||||
arguments: Box::new(arguments),
|
||||
range: (location..end_location).into(),
|
||||
}.into()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue