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(
|
Expr::Call(
|
||||||
call @ ast::ExprCall {
|
call @ ast::ExprCall {
|
||||||
func,
|
func,
|
||||||
arguments:
|
arguments,
|
||||||
Arguments {
|
|
||||||
args,
|
|
||||||
keywords,
|
|
||||||
range: _,
|
|
||||||
},
|
|
||||||
range: _,
|
range: _,
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
|
let Arguments {
|
||||||
|
args,
|
||||||
|
keywords,
|
||||||
|
range: _,
|
||||||
|
} = &**arguments;
|
||||||
|
|
||||||
if checker.any_enabled(&[
|
if checker.any_enabled(&[
|
||||||
// pylint
|
// pylint
|
||||||
Rule::BadStringFormatCharacter,
|
Rule::BadStringFormatCharacter,
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ fn assertion_error(msg: Option<&Expr>) -> Stmt {
|
||||||
ctx: ExprContext::Load,
|
ctx: ExprContext::Load,
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
})),
|
})),
|
||||||
arguments: Arguments {
|
arguments: Box::new(Arguments {
|
||||||
args: if let Some(msg) = msg {
|
args: if let Some(msg) = msg {
|
||||||
Box::from([msg.clone()])
|
Box::from([msg.clone()])
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -65,7 +65,7 @@ fn assertion_error(msg: Option<&Expr>) -> Stmt {
|
||||||
},
|
},
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
}))),
|
}))),
|
||||||
cause: None,
|
cause: None,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use ruff_diagnostics::{AlwaysFixableViolation, Applicability, Diagnostic, Fix};
|
use ruff_diagnostics::{AlwaysFixableViolation, Applicability, Diagnostic, Fix};
|
||||||
use ruff_macros::{derive_message_formats, 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_python_semantic::SemanticModel;
|
use ruff_python_semantic::SemanticModel;
|
||||||
use ruff_text_size::Ranged;
|
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).
|
/// `itertools.cycle` or similar).
|
||||||
fn is_infinite_iterator(arg: &Expr, semantic: &SemanticModel) -> bool {
|
fn is_infinite_iterator(arg: &Expr, semantic: &SemanticModel) -> bool {
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: Arguments { args, keywords, .. },
|
|
||||||
..
|
|
||||||
}) = &arg
|
}) = &arg
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -104,17 +102,17 @@ fn is_infinite_iterator(arg: &Expr, semantic: &SemanticModel) -> bool {
|
||||||
["itertools", "cycle" | "count"] => true,
|
["itertools", "cycle" | "count"] => true,
|
||||||
["itertools", "repeat"] => {
|
["itertools", "repeat"] => {
|
||||||
// Ex) `itertools.repeat(1)`
|
// Ex) `itertools.repeat(1)`
|
||||||
if keywords.is_empty() && args.len() == 1 {
|
if arguments.keywords.is_empty() && arguments.args.len() == 1 {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ex) `itertools.repeat(1, None)`
|
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ex) `iterools.repeat(1, times=None)`
|
// 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.arg.as_ref().is_some_and(|name| name == "times") {
|
||||||
if keyword.value.is_none_literal_expr() {
|
if keyword.value.is_none_literal_expr() {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix};
|
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast::comparable::ComparableKeyword;
|
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 ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -84,11 +84,7 @@ pub(crate) fn unnecessary_double_cast_or_process(
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: Arguments {
|
|
||||||
keywords: inner_kw, ..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
}) = arg
|
}) = arg
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
|
|
@ -103,10 +99,10 @@ pub(crate) fn unnecessary_double_cast_or_process(
|
||||||
// Avoid collapsing nested `sorted` calls with non-identical keyword arguments
|
// Avoid collapsing nested `sorted` calls with non-identical keyword arguments
|
||||||
// (i.e., `key`, `reverse`).
|
// (i.e., `key`, `reverse`).
|
||||||
if &*inner.id == "sorted" && &*outer.id == "sorted" {
|
if &*inner.id == "sorted" && &*outer.id == "sorted" {
|
||||||
if inner_kw.len() != outer_kw.len() {
|
if arguments.keywords.len() != outer_kw.len() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if !inner_kw.iter().all(|inner| {
|
if !arguments.keywords.iter().all(|inner| {
|
||||||
outer_kw
|
outer_kw
|
||||||
.iter()
|
.iter()
|
||||||
.any(|outer| ComparableKeyword::from(inner) == ComparableKeyword::from(outer))
|
.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_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast::visitor;
|
use ruff_python_ast::visitor;
|
||||||
use ruff_python_ast::visitor::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 ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -125,23 +125,22 @@ pub(crate) fn unnecessary_map(
|
||||||
ObjectType::List | ObjectType::Set => {
|
ObjectType::List | ObjectType::Set => {
|
||||||
// Only flag, e.g., `list(map(lambda x: x + 1, iterable))`.
|
// Only flag, e.g., `list(map(lambda x: x + 1, iterable))`.
|
||||||
let [Expr::Call(ast::ExprCall {
|
let [Expr::Call(ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: Arguments { args, keywords, .. },
|
|
||||||
..
|
|
||||||
})] = args
|
})] = args
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if args.len() != 2 {
|
if arguments.args.len() != 2 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !keywords.is_empty() {
|
if !arguments.keywords.is_empty() {
|
||||||
return;
|
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 {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
@ -170,23 +169,22 @@ pub(crate) fn unnecessary_map(
|
||||||
ObjectType::Dict => {
|
ObjectType::Dict => {
|
||||||
// Only flag, e.g., `dict(map(lambda v: (v, v ** 2), values))`.
|
// Only flag, e.g., `dict(map(lambda v: (v, v ** 2), values))`.
|
||||||
let [Expr::Call(ast::ExprCall {
|
let [Expr::Call(ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: Arguments { args, keywords, .. },
|
|
||||||
..
|
|
||||||
})] = args
|
})] = args
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if args.len() != 2 {
|
if arguments.args.len() != 2 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !keywords.is_empty() {
|
if !arguments.keywords.is_empty() {
|
||||||
return;
|
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 {
|
else {
|
||||||
return;
|
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_source_file::Locator;
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
|
|
@ -175,12 +175,8 @@ impl Violation for DotFormatInException {
|
||||||
|
|
||||||
/// EM101, EM102, EM103
|
/// EM101, EM102, EM103
|
||||||
pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr) {
|
pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr) {
|
||||||
if let Expr::Call(ast::ExprCall {
|
if let Expr::Call(ast::ExprCall { arguments, .. }) = exc {
|
||||||
arguments: Arguments { args, .. },
|
if let Some(first) = arguments.args.first() {
|
||||||
..
|
|
||||||
}) = exc
|
|
||||||
{
|
|
||||||
if let Some(first) = args.first() {
|
|
||||||
match first {
|
match first {
|
||||||
// Check for string literals.
|
// Check for string literals.
|
||||||
Expr::StringLiteral(ast::ExprStringLiteral { value: string, .. }) => {
|
Expr::StringLiteral(ast::ExprStringLiteral { value: string, .. }) => {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_diagnostics::{Diagnostic, Edit, Fix};
|
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_semantic::analyze::logging;
|
||||||
use ruff_python_stdlib::logging::LoggingLevel;
|
use ruff_python_stdlib::logging::LoggingLevel;
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
@ -104,16 +104,14 @@ fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::Call(ast::ExprCall {
|
Expr::Call(ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: Arguments { keywords, .. },
|
|
||||||
..
|
|
||||||
}) => {
|
}) => {
|
||||||
if checker
|
if checker
|
||||||
.semantic()
|
.semantic()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.is_some_and(|call_path| matches!(call_path.as_slice(), ["", "dict"]))
|
.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 let Some(attr) = &keyword.arg {
|
||||||
if is_reserved_attr(attr) {
|
if is_reserved_attr(attr) {
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
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() {
|
for (index, call) in values.iter().enumerate() {
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func,
|
||||||
arguments:
|
arguments,
|
||||||
Arguments {
|
|
||||||
args,
|
|
||||||
keywords,
|
|
||||||
range: _,
|
|
||||||
},
|
|
||||||
range: _,
|
range: _,
|
||||||
}) = &call
|
}) = &call
|
||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
if !keywords.is_empty() {
|
if !arguments.keywords.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let [arg] = &**args else {
|
let [arg] = &*arguments.args else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -140,12 +135,7 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
|
||||||
.map(|expr| {
|
.map(|expr| {
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall {
|
||||||
func: _,
|
func: _,
|
||||||
arguments:
|
arguments,
|
||||||
Arguments {
|
|
||||||
args,
|
|
||||||
keywords: _,
|
|
||||||
range: _,
|
|
||||||
},
|
|
||||||
range: _,
|
range: _,
|
||||||
}) = expr
|
}) = expr
|
||||||
else {
|
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")
|
format!("Indices should only contain `{attr_name}` calls")
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
args.first()
|
arguments
|
||||||
|
.args
|
||||||
|
.first()
|
||||||
.unwrap_or_else(|| panic!("`{attr_name}` should have one argument"))
|
.unwrap_or_else(|| panic!("`{attr_name}` should have one argument"))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
@ -187,11 +179,11 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
|
||||||
});
|
});
|
||||||
let node3 = Expr::Call(ast::ExprCall {
|
let node3 = Expr::Call(ast::ExprCall {
|
||||||
func: Box::new(node2),
|
func: Box::new(node2),
|
||||||
arguments: Arguments {
|
arguments: Box::new(Arguments {
|
||||||
args: Box::from([node]),
|
args: Box::from([node]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
});
|
});
|
||||||
let call = node3;
|
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_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
|
@ -137,18 +137,10 @@ fn check_mark_parentheses(checker: &mut Checker, decorator: &Decorator, marker:
|
||||||
match &decorator.expression {
|
match &decorator.expression {
|
||||||
Expr::Call(ast::ExprCall {
|
Expr::Call(ast::ExprCall {
|
||||||
func,
|
func,
|
||||||
arguments:
|
arguments,
|
||||||
Arguments {
|
|
||||||
args,
|
|
||||||
keywords,
|
|
||||||
range: _,
|
|
||||||
},
|
|
||||||
range: _,
|
range: _,
|
||||||
}) => {
|
}) => {
|
||||||
if !checker.settings.flake8_pytest_style.mark_parentheses
|
if !checker.settings.flake8_pytest_style.mark_parentheses && arguments.is_empty() {
|
||||||
&& args.is_empty()
|
|
||||||
&& keywords.is_empty()
|
|
||||||
{
|
|
||||||
let fix = Fix::safe_edit(Edit::deletion(func.end(), decorator.end()));
|
let fix = Fix::safe_edit(Edit::deletion(func.end(), decorator.end()));
|
||||||
pytest_mark_parentheses(checker, decorator, marker, fix, "", "()");
|
pytest_mark_parentheses(checker, decorator, marker, fix, "", "()");
|
||||||
}
|
}
|
||||||
|
|
@ -171,11 +163,8 @@ fn check_useless_usefixtures(checker: &mut Checker, decorator: &Decorator, marke
|
||||||
// @pytest.mark.usefixtures
|
// @pytest.mark.usefixtures
|
||||||
Expr::Attribute(..) => {}
|
Expr::Attribute(..) => {}
|
||||||
// @pytest.mark.usefixtures(...)
|
// @pytest.mark.usefixtures(...)
|
||||||
Expr::Call(ast::ExprCall {
|
Expr::Call(ast::ExprCall { arguments, .. }) => {
|
||||||
arguments: Arguments { args, keywords, .. },
|
if !arguments.is_empty() {
|
||||||
..
|
|
||||||
}) => {
|
|
||||||
if !args.is_empty() || !keywords.is_empty() {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast::comparable::ComparableExpr;
|
use ruff_python_ast::comparable::ComparableExpr;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::parenthesize::parenthesized_range;
|
||||||
use ruff_python_ast::AstNode;
|
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_codegen::Generator;
|
||||||
use ruff_python_trivia::CommentRanges;
|
use ruff_python_trivia::CommentRanges;
|
||||||
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
|
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
|
||||||
|
|
@ -632,23 +632,19 @@ fn handle_value_rows(
|
||||||
pub(crate) fn parametrize(checker: &mut Checker, decorators: &[Decorator]) {
|
pub(crate) fn parametrize(checker: &mut Checker, decorators: &[Decorator]) {
|
||||||
for decorator in decorators {
|
for decorator in decorators {
|
||||||
if is_pytest_parametrize(decorator, checker.semantic()) {
|
if is_pytest_parametrize(decorator, checker.semantic()) {
|
||||||
if let Expr::Call(ast::ExprCall {
|
if let Expr::Call(ast::ExprCall { arguments, .. }) = &decorator.expression {
|
||||||
arguments: Arguments { args, .. },
|
|
||||||
..
|
|
||||||
}) = &decorator.expression
|
|
||||||
{
|
|
||||||
if checker.enabled(Rule::PytestParametrizeNamesWrongType) {
|
if checker.enabled(Rule::PytestParametrizeNamesWrongType) {
|
||||||
if let [names, ..] = &**args {
|
if let [names, ..] = &*arguments.args {
|
||||||
check_names(checker, decorator, names);
|
check_names(checker, decorator, names);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::PytestParametrizeValuesWrongType) {
|
if checker.enabled(Rule::PytestParametrizeValuesWrongType) {
|
||||||
if let [names, values, ..] = &**args {
|
if let [names, values, ..] = &*arguments.args {
|
||||||
check_values(checker, names, values);
|
check_values(checker, names, values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::PytestDuplicateParametrizeTestCases) {
|
if checker.enabled(Rule::PytestDuplicateParametrizeTestCases) {
|
||||||
if let [_, values, ..] = &**args {
|
if let [_, values, ..] = &*arguments.args {
|
||||||
check_duplicates(checker, values);
|
check_duplicates(checker, values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -389,11 +389,11 @@ impl UnittestAssert {
|
||||||
};
|
};
|
||||||
let node1 = ast::ExprCall {
|
let node1 = ast::ExprCall {
|
||||||
func: Box::new(node.into()),
|
func: Box::new(node.into()),
|
||||||
arguments: Arguments {
|
arguments: Box::new(Arguments {
|
||||||
args: Box::from([(**obj).clone(), (**cls).clone()]),
|
args: Box::from([(**obj).clone(), (**cls).clone()]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
let isinstance = node1.into();
|
let isinstance = node1.into();
|
||||||
|
|
@ -433,11 +433,11 @@ impl UnittestAssert {
|
||||||
};
|
};
|
||||||
let node2 = ast::ExprCall {
|
let node2 = ast::ExprCall {
|
||||||
func: Box::new(node1.into()),
|
func: Box::new(node1.into()),
|
||||||
arguments: Arguments {
|
arguments: Box::new(Arguments {
|
||||||
args: Box::from([(**regex).clone(), (**text).clone()]),
|
args: Box::from([(**regex).clone(), (**text).clone()]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
let re_search = node2.into();
|
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.
|
// Verify that this is an `isinstance` call.
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func,
|
||||||
arguments:
|
arguments,
|
||||||
Arguments {
|
|
||||||
args,
|
|
||||||
keywords,
|
|
||||||
range: _,
|
|
||||||
},
|
|
||||||
range: _,
|
range: _,
|
||||||
}) = &call
|
}) = &call
|
||||||
else {
|
else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
if args.len() != 2 {
|
if !arguments.keywords.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if !keywords.is_empty() {
|
if arguments.args.len() != 2 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let Expr::Name(ast::ExprName { id: func_name, .. }) = func.as_ref() else {
|
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)`).
|
// Collect the target (e.g., `obj` in `isinstance(obj, int)`).
|
||||||
Some(&args[0])
|
Some(&arguments.args[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SIM101
|
/// SIM101
|
||||||
|
|
@ -374,12 +369,10 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
|
||||||
if indices.len() > 1 {
|
if indices.len() > 1 {
|
||||||
// Grab the target used in each duplicate `isinstance` call (e.g., `obj` in
|
// Grab the target used in each duplicate `isinstance` call (e.g., `obj` in
|
||||||
// `isinstance(obj, int)`).
|
// `isinstance(obj, int)`).
|
||||||
let target = if let Expr::Call(ast::ExprCall {
|
let target = if let Expr::Call(ast::ExprCall { arguments, .. }) = &values[indices[0]] {
|
||||||
arguments: Arguments { args, .. },
|
arguments
|
||||||
..
|
.args
|
||||||
}) = &values[indices[0]]
|
.first()
|
||||||
{
|
|
||||||
args.first()
|
|
||||||
.expect("`isinstance` should have two arguments")
|
.expect("`isinstance` should have two arguments")
|
||||||
} else {
|
} else {
|
||||||
unreachable!("Indices should only contain `isinstance` calls")
|
unreachable!("Indices should only contain `isinstance` calls")
|
||||||
|
|
@ -401,14 +394,13 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|index| &values[*index])
|
.map(|index| &values[*index])
|
||||||
.map(|expr| {
|
.map(|expr| {
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall { arguments, .. }) = expr else {
|
||||||
arguments: Arguments { args, .. },
|
|
||||||
..
|
|
||||||
}) = expr
|
|
||||||
else {
|
|
||||||
unreachable!("Indices should only contain `isinstance` calls")
|
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();
|
.collect();
|
||||||
|
|
||||||
|
|
@ -436,11 +428,11 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
|
||||||
};
|
};
|
||||||
let node2 = ast::ExprCall {
|
let node2 = ast::ExprCall {
|
||||||
func: Box::new(node1.into()),
|
func: Box::new(node1.into()),
|
||||||
arguments: Arguments {
|
arguments: Box::new(Arguments {
|
||||||
args: Box::from([target.clone(), node.into()]),
|
args: Box::from([target.clone(), node.into()]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
let call = node2.into();
|
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 ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::fix::snippet::SourceCodeSnippet;
|
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')`
|
// Ex) `os.environ.get('foo')`, `os.getenv('foo')`
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: Arguments { args, .. },
|
|
||||||
..
|
|
||||||
}) = expr
|
}) = expr
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(arg) = args.first() else {
|
let Some(arg) = arguments.args.first() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Expr::StringLiteral(ast::ExprStringLiteral { value: env_var, .. }) = arg else {
|
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) {
|
pub(crate) fn dict_get_with_none_default(checker: &mut Checker, expr: &Expr) {
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func,
|
||||||
arguments: Arguments { args, keywords, .. },
|
arguments,
|
||||||
range: _,
|
range: _,
|
||||||
}) = expr
|
}) = expr
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !keywords.is_empty() {
|
if !arguments.keywords.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Expr::Attribute(ast::ExprAttribute { value, attr, .. }) = func.as_ref() else {
|
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" {
|
if attr != "get" {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Some(key) = args.first() else {
|
let Some(key) = arguments.args.first() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !(key.is_literal_expr() || key.is_name_expr()) {
|
if !(key.is_literal_expr() || key.is_name_expr()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Some(default) = args.get(1) else {
|
let Some(default) = arguments.args.get(1) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !default.is_none_literal_expr() {
|
if !default.is_none_literal_expr() {
|
||||||
|
|
|
||||||
|
|
@ -184,11 +184,11 @@ pub(crate) fn if_expr_with_true_false(
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
arguments: Arguments {
|
arguments: Box::new(Arguments {
|
||||||
args: Box::from([test.clone()]),
|
args: Box::from([test.clone()]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
|
|
||||||
|
|
@ -278,11 +278,11 @@ pub(crate) fn double_negation(checker: &mut Checker, expr: &Expr, op: UnaryOp, o
|
||||||
};
|
};
|
||||||
let node1 = ast::ExprCall {
|
let node1 = ast::ExprCall {
|
||||||
func: Box::new(node.into()),
|
func: Box::new(node.into()),
|
||||||
arguments: Arguments {
|
arguments: Box::new(Arguments {
|
||||||
args: Box::from([*operand.clone()]),
|
args: Box::from([*operand.clone()]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
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 {
|
let node3 = ast::ExprCall {
|
||||||
func: Box::new(node2.into()),
|
func: Box::new(node2.into()),
|
||||||
arguments: Arguments {
|
arguments: Box::new(Arguments {
|
||||||
args: Box::from([node1, node]),
|
args: Box::from([node1, node]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
let node4 = expected_var.clone();
|
let node4 = expected_var.clone();
|
||||||
|
|
@ -275,11 +275,11 @@ pub(crate) fn if_exp_instead_of_dict_get(
|
||||||
};
|
};
|
||||||
let fixed_node = ast::ExprCall {
|
let fixed_node = ast::ExprCall {
|
||||||
func: Box::new(dict_get_node.into()),
|
func: Box::new(dict_get_node.into()),
|
||||||
arguments: Arguments {
|
arguments: Box::new(Arguments {
|
||||||
args: Box::from([dict_key_node, default_value_node]),
|
args: Box::from([dict_key_node, default_value_node]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
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 {
|
let value_node = ast::ExprCall {
|
||||||
func: Box::new(func_node.into()),
|
func: Box::new(func_node.into()),
|
||||||
arguments: Arguments {
|
arguments: Box::new(Arguments {
|
||||||
args: Box::from([if_test.clone()]),
|
args: Box::from([if_test.clone()]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
let return_node = ast::StmtReturn {
|
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 {
|
let node2 = ast::ExprCall {
|
||||||
func: Box::new(node1.into()),
|
func: Box::new(node1.into()),
|
||||||
arguments: Arguments {
|
arguments: Box::new(Arguments {
|
||||||
args: Box::from([node.into()]),
|
args: Box::from([node.into()]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
let node3 = ast::StmtReturn {
|
let node3 = ast::StmtReturn {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use ast::{ExprAttribute, ExprName, Identifier};
|
use ast::{ExprAttribute, ExprName, Identifier};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
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 ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::{checkers::ast::Checker, fix::snippet::SourceCodeSnippet};
|
use crate::{checkers::ast::Checker, fix::snippet::SourceCodeSnippet};
|
||||||
|
|
@ -61,11 +61,9 @@ impl AlwaysFixableViolation for ZipDictKeysAndValues {
|
||||||
/// SIM911
|
/// SIM911
|
||||||
pub(crate) fn zip_dict_keys_and_values(checker: &mut Checker, expr: &ExprCall) {
|
pub(crate) fn zip_dict_keys_and_values(checker: &mut Checker, expr: &ExprCall) {
|
||||||
let ExprCall {
|
let ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: Arguments { args, keywords, .. },
|
|
||||||
..
|
|
||||||
} = expr;
|
} = expr;
|
||||||
match &keywords[..] {
|
match &*arguments.keywords {
|
||||||
[] => {}
|
[] => {}
|
||||||
[ast::Keyword {
|
[ast::Keyword {
|
||||||
arg: Some(name), ..
|
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") {
|
if matches!(func.as_ref(), Expr::Name(ExprName { id, .. }) if &**id != "zip") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let [arg1, arg2] = &args[..] else {
|
let [arg1, arg2] = &*arguments.args else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some((var1, attr1)) = get_var_attr(arg1) else {
|
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;
|
use ruff_text_size::TextRange;
|
||||||
|
|
||||||
/// Wrap an expression in a [`ast::FStringElement::Expression`] with no special formatting.
|
/// 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 {
|
match expr {
|
||||||
Expr::Call(ast::ExprCall {
|
Expr::Call(ast::ExprCall {
|
||||||
func,
|
func,
|
||||||
arguments:
|
arguments,
|
||||||
Arguments {
|
|
||||||
args,
|
|
||||||
keywords,
|
|
||||||
range: _,
|
|
||||||
},
|
|
||||||
range: _,
|
range: _,
|
||||||
}) => args.is_empty() && keywords.is_empty() && is_simple_callee(func),
|
}) => arguments.is_empty() && is_simple_callee(func),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use itertools::Itertools;
|
||||||
use crate::fix::edits::pad;
|
use crate::fix::edits::pad;
|
||||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, 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, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -103,20 +103,16 @@ fn build_fstring(joiner: &str, joinees: &[Expr]) -> Option<Expr> {
|
||||||
|
|
||||||
/// FLY002
|
/// FLY002
|
||||||
pub(crate) fn static_join_to_fstring(checker: &mut Checker, expr: &Expr, joiner: &str) {
|
pub(crate) fn static_join_to_fstring(checker: &mut Checker, expr: &Expr, joiner: &str) {
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall { arguments, .. }) = expr else {
|
||||||
arguments: Arguments { args, keywords, .. },
|
|
||||||
..
|
|
||||||
}) = expr
|
|
||||||
else {
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
// If there are kwargs or more than one argument, this is some non-standard
|
// If there are kwargs or more than one argument, this is some non-standard
|
||||||
// string join call.
|
// string join call.
|
||||||
if !keywords.is_empty() {
|
if !arguments.keywords.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let [arg] = &**args else {
|
let [arg] = &*arguments.args else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::fmt;
|
||||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast as ast;
|
use ruff_python_ast as ast;
|
||||||
use ruff_python_ast::{Arguments, Expr};
|
use ruff_python_ast::Expr;
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -70,14 +70,12 @@ pub(crate) fn incorrect_dict_iterator(checker: &mut Checker, stmt_for: &ast::Stm
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: Arguments { args, .. },
|
|
||||||
..
|
|
||||||
}) = stmt_for.iter.as_ref()
|
}) = stmt_for.iter.as_ref()
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !args.is_empty() {
|
if !arguments.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Expr::Attribute(ast::ExprAttribute { attr, .. }) = func.as_ref() else {
|
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_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, 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 {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func,
|
||||||
arguments:
|
arguments,
|
||||||
Arguments {
|
|
||||||
args,
|
|
||||||
keywords,
|
|
||||||
range: _,
|
|
||||||
},
|
|
||||||
range,
|
range,
|
||||||
}) = value.as_ref()
|
}) = value.as_ref()
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if !keywords.is_empty() {
|
if !arguments.keywords.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let [arg] = &**args else {
|
let [arg] = &*arguments.args else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast::helpers::any_over_expr;
|
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 ruff_python_semantic::analyze::typing::is_list;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
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 {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func,
|
||||||
arguments:
|
arguments,
|
||||||
Arguments {
|
|
||||||
args,
|
|
||||||
keywords,
|
|
||||||
range: _,
|
|
||||||
},
|
|
||||||
range,
|
range,
|
||||||
}) = value.as_ref()
|
}) = value.as_ref()
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if !keywords.is_empty() {
|
if !arguments.keywords.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let [arg] = &**args else {
|
let [arg] = &*arguments.args else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
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_python_semantic::analyze::typing::find_assigned_value;
|
||||||
use ruff_text_size::TextRange;
|
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]) {
|
pub(crate) fn unnecessary_list_cast(checker: &mut Checker, iter: &Expr, body: &[Stmt]) {
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func,
|
||||||
arguments:
|
arguments,
|
||||||
Arguments {
|
|
||||||
args,
|
|
||||||
keywords: _,
|
|
||||||
range: _,
|
|
||||||
},
|
|
||||||
range: list_range,
|
range: list_range,
|
||||||
}) = iter
|
}) = iter
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let [arg] = &**args else {
|
let [arg] = &*arguments.args else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,16 +97,11 @@ fn collect_nested_args(min_max: MinMax, args: &[Expr], semantic: &SemanticModel)
|
||||||
for arg in args {
|
for arg in args {
|
||||||
if let Expr::Call(ast::ExprCall {
|
if let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func,
|
||||||
arguments:
|
arguments,
|
||||||
Arguments {
|
|
||||||
args,
|
|
||||||
keywords,
|
|
||||||
range: _,
|
|
||||||
},
|
|
||||||
range: _,
|
range: _,
|
||||||
}) = arg
|
}) = arg
|
||||||
{
|
{
|
||||||
if let [arg] = &**args {
|
if let [arg] = &*arguments.args {
|
||||||
if arg.as_starred_expr().is_none() {
|
if arg.as_starred_expr().is_none() {
|
||||||
let new_arg = Expr::Starred(ast::ExprStarred {
|
let new_arg = Expr::Starred(ast::ExprStarred {
|
||||||
value: Box::new(arg.clone()),
|
value: Box::new(arg.clone()),
|
||||||
|
|
@ -117,8 +112,8 @@ fn collect_nested_args(min_max: MinMax, args: &[Expr], semantic: &SemanticModel)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if MinMax::try_from_call(func, keywords, semantic) == Some(min_max) {
|
if MinMax::try_from_call(func, &arguments.keywords, semantic) == Some(min_max) {
|
||||||
inner(min_max, args, semantic, new_args);
|
inner(min_max, &arguments.args, semantic, new_args);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -143,31 +138,29 @@ pub(crate) fn nested_min_max(
|
||||||
return;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.iter().any(|arg| {
|
if args.iter().any(|arg| {
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: Arguments { keywords, .. },
|
|
||||||
..
|
|
||||||
}) = arg
|
}) = arg
|
||||||
else {
|
else {
|
||||||
return false;
|
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());
|
let mut diagnostic = Diagnostic::new(NestedMinMax { func: min_max }, expr.range());
|
||||||
if !checker.indexer().has_comments(expr, checker.locator()) {
|
if !checker.indexer().has_comments(expr, checker.locator()) {
|
||||||
let flattened_expr = Expr::Call(ast::ExprCall {
|
let flattened_expr = Expr::Call(ast::ExprCall {
|
||||||
func: Box::new(func.clone()),
|
func: Box::new(func.clone()),
|
||||||
arguments: Arguments {
|
arguments: Box::new(Arguments {
|
||||||
args: collect_nested_args(min_max, args, checker.semantic()).into_boxed_slice(),
|
args: collect_nested_args(min_max, args, checker.semantic()).into_boxed_slice(),
|
||||||
keywords: Box::from(keywords),
|
keywords: Box::from(keywords),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
});
|
});
|
||||||
diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement(
|
diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement(
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{fmt, iter};
|
use std::{fmt, iter};
|
||||||
|
|
||||||
use regex::Regex;
|
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_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, 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 {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: Arguments { args, .. },
|
|
||||||
..
|
|
||||||
}) = value
|
}) = value
|
||||||
else {
|
else {
|
||||||
return false;
|
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 {
|
let Expr::Name(ast::ExprName { id: target_id, .. }) = target else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
if args.len() != 2 {
|
if arguments.args.len() != 2 {
|
||||||
return false;
|
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;
|
return false;
|
||||||
};
|
};
|
||||||
if arg_id != target_id {
|
if arg_id != target_id {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use itertools::Itertools;
|
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 rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
|
||||||
use crate::fix::edits::pad;
|
use crate::fix::edits::pad;
|
||||||
|
|
@ -85,9 +85,7 @@ pub(crate) fn repeated_isinstance_calls(
|
||||||
FxHashMap::default();
|
FxHashMap::default();
|
||||||
for value in values {
|
for value in values {
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: Arguments { args, .. },
|
|
||||||
..
|
|
||||||
}) = value
|
}) = value
|
||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -95,7 +93,7 @@ pub(crate) fn repeated_isinstance_calls(
|
||||||
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;
|
continue;
|
||||||
}
|
}
|
||||||
let [obj, types] = &args[..] else {
|
let [obj, types] = &*arguments.args else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if !checker.semantic().is_builtin("isinstance") {
|
if !checker.semantic().is_builtin("isinstance") {
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ fn match_named_tuple_assign<'a>(
|
||||||
};
|
};
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func,
|
||||||
arguments: Arguments { args, keywords, .. },
|
arguments,
|
||||||
range: _,
|
range: _,
|
||||||
}) = value
|
}) = value
|
||||||
else {
|
else {
|
||||||
|
|
@ -144,7 +144,7 @@ fn match_named_tuple_assign<'a>(
|
||||||
if !semantic.match_typing_expr(func, "NamedTuple") {
|
if !semantic.match_typing_expr(func, "NamedTuple") {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some((typename, args, keywords, func))
|
Some((typename, &arguments.args, &arguments.keywords, func))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate a [`Stmt::AnnAssign`] representing the provided field definition.
|
/// 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)),
|
}) => Some((fields_from_dict_literal(keys, values)?, total)),
|
||||||
Expr::Call(ast::ExprCall {
|
Expr::Call(ast::ExprCall {
|
||||||
func,
|
func,
|
||||||
arguments: Arguments { keywords, .. },
|
arguments,
|
||||||
range: _,
|
range: _,
|
||||||
}) => Some((fields_from_dict_call(func, keywords)?, total)),
|
}) => Some((fields_from_dict_call(func, &arguments.keywords)?, total)),
|
||||||
_ => None,
|
_ => 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_text_size::{Ranged, TextRange};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
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 {
|
for decorator in decorator_list {
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func,
|
||||||
arguments:
|
arguments,
|
||||||
Arguments {
|
|
||||||
args,
|
|
||||||
keywords,
|
|
||||||
range: _,
|
|
||||||
},
|
|
||||||
range: _,
|
range: _,
|
||||||
}) = &decorator.expression
|
}) = &decorator.expression
|
||||||
else {
|
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)`.
|
// Look for, e.g., `import functools; @functools.lru_cache(maxsize=None)`.
|
||||||
if args.is_empty()
|
if arguments.args.is_empty()
|
||||||
&& keywords.len() == 1
|
&& arguments.keywords.len() == 1
|
||||||
&& checker
|
&& checker
|
||||||
.semantic()
|
.semantic()
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
|
|
@ -83,7 +78,7 @@ pub(crate) fn lru_cache_with_maxsize_none(checker: &mut Checker, decorator_list:
|
||||||
arg,
|
arg,
|
||||||
value,
|
value,
|
||||||
range: _,
|
range: _,
|
||||||
} = &keywords[0];
|
} = &arguments.keywords[0];
|
||||||
if arg.as_ref().is_some_and(|arg| arg == "maxsize") && value.is_none_literal_expr() {
|
if arg.as_ref().is_some_and(|arg| arg == "maxsize") && value.is_none_literal_expr() {
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
LRUCacheWithMaxsizeNone,
|
LRUCacheWithMaxsizeNone,
|
||||||
|
|
|
||||||
|
|
@ -141,12 +141,7 @@ pub(crate) fn native_literals(
|
||||||
) {
|
) {
|
||||||
let ast::ExprCall {
|
let ast::ExprCall {
|
||||||
func,
|
func,
|
||||||
arguments:
|
arguments,
|
||||||
ast::Arguments {
|
|
||||||
args,
|
|
||||||
keywords,
|
|
||||||
range: _,
|
|
||||||
},
|
|
||||||
range: _,
|
range: _,
|
||||||
} = call;
|
} = call;
|
||||||
|
|
||||||
|
|
@ -154,7 +149,7 @@ pub(crate) fn native_literals(
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if !keywords.is_empty() || args.len() > 1 {
|
if !arguments.keywords.is_empty() || arguments.args.len() > 1 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,7 +174,7 @@ pub(crate) fn native_literals(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match args.first() {
|
match arguments.args.first() {
|
||||||
None => {
|
None => {
|
||||||
let mut diagnostic = Diagnostic::new(NativeLiterals { literal_type }, call.range());
|
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()`
|
// Make it into a call `name.method()`
|
||||||
let call = ast::ExprCall {
|
let call = ast::ExprCall {
|
||||||
func: Box::new(attr.into()),
|
func: Box::new(attr.into()),
|
||||||
arguments: ast::Arguments {
|
arguments: Box::new(ast::Arguments {
|
||||||
args: Box::from([]),
|
args: Box::from([]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
// And finally, turn it into a statement.
|
// 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 {
|
let ast::ExprCall {
|
||||||
func: attr,
|
func: attr,
|
||||||
arguments: ast::Arguments { args, keywords, .. },
|
arguments,
|
||||||
..
|
..
|
||||||
} = expr.as_call_expr()?;
|
} = expr.as_call_expr()?;
|
||||||
|
|
||||||
|
|
@ -165,11 +165,11 @@ fn match_remove(if_stmt: &ast::StmtIf) -> Option<(&Expr, &ast::ExprName)> {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let [arg] = &**args else {
|
let [arg] = &*arguments.args else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
if func_name != "remove" || !keywords.is_empty() {
|
if func_name != "remove" || !arguments.keywords.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,11 +190,11 @@ fn make_suggestion(set: &ast::ExprName, element: &Expr, generator: Generator) ->
|
||||||
// Make the actual call `set.discard(element)`
|
// Make the actual call `set.discard(element)`
|
||||||
let call = ast::ExprCall {
|
let call = ast::ExprCall {
|
||||||
func: Box::new(attr.into()),
|
func: Box::new(attr.into()),
|
||||||
arguments: ast::Arguments {
|
arguments: Box::new(ast::Arguments {
|
||||||
args: Box::from([element.clone()]),
|
args: Box::from([element.clone()]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
// And finally, turn it into a statement.
|
// And finally, turn it into a statement.
|
||||||
|
|
|
||||||
|
|
@ -136,9 +136,7 @@ fn find_file_open<'a>(
|
||||||
) -> Option<FileOpen<'a>> {
|
) -> Option<FileOpen<'a>> {
|
||||||
// We want to match `open(...) as var`.
|
// We want to match `open(...) as var`.
|
||||||
let ast::ExprCall {
|
let ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: ast::Arguments { args, keywords, .. },
|
|
||||||
..
|
|
||||||
} = item.context_expr.as_call_expr()?;
|
} = item.context_expr.as_call_expr()?;
|
||||||
|
|
||||||
let func = func.as_name_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")`,
|
// 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
|
// it could be a match; but in all other cases, the call _could_ contain unsupported keyword
|
||||||
// arguments, like `buffering`.
|
// arguments, like `buffering`.
|
||||||
if args.iter().any(Expr::is_starred_expr)
|
if arguments.args.iter().any(Expr::is_starred_expr)
|
||||||
|| keywords.iter().any(|keyword| keyword.arg.is_none())
|
|| arguments
|
||||||
|
.keywords
|
||||||
|
.iter()
|
||||||
|
.any(|keyword| keyword.arg.is_none())
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match positional arguments, get filename and read mode.
|
// 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.
|
// 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
|
// `pos_mode` could've been assigned default value corresponding to "r", while
|
||||||
// keyword mode should override that.
|
// keyword mode should override that.
|
||||||
|
|
@ -322,11 +323,11 @@ fn make_suggestion(open: &FileOpen<'_>, generator: Generator) -> SourceCodeSnipp
|
||||||
};
|
};
|
||||||
let call = ast::ExprCall {
|
let call = ast::ExprCall {
|
||||||
func: Box::new(name.into()),
|
func: Box::new(name.into()),
|
||||||
arguments: ast::Arguments {
|
arguments: Box::new(ast::Arguments {
|
||||||
args: Box::from([]),
|
args: Box::from([]),
|
||||||
keywords: open.keywords.iter().copied().cloned().collect(),
|
keywords: open.keywords.iter().copied().cloned().collect(),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
SourceCodeSnippet::from_str(&generator.expr(&call.into()))
|
SourceCodeSnippet::from_str(&generator.expr(&call.into()))
|
||||||
|
|
|
||||||
|
|
@ -303,11 +303,11 @@ fn construct_starmap_call(starmap_binding: String, iter: &Expr, func: &Expr) ->
|
||||||
};
|
};
|
||||||
ast::ExprCall {
|
ast::ExprCall {
|
||||||
func: Box::new(starmap.into()),
|
func: Box::new(starmap.into()),
|
||||||
arguments: ast::Arguments {
|
arguments: Box::new(ast::Arguments {
|
||||||
args: Box::from([func.clone(), iter.clone()]),
|
args: Box::from([func.clone(), iter.clone()]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
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 {
|
ast::ExprCall {
|
||||||
func: Box::new(name.into()),
|
func: Box::new(name.into()),
|
||||||
arguments: ast::Arguments {
|
arguments: Box::new(ast::Arguments {
|
||||||
args: Box::from([call.into()]),
|
args: Box::from([call.into()]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
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, ...)`.
|
/// Match that the given expression is `func(x, y, z, ...)`.
|
||||||
fn match_call(element: &Expr) -> Option<(&[Expr], &Expr)> {
|
fn match_call(element: &Expr) -> Option<(&[Expr], &Expr)> {
|
||||||
let ast::ExprCall {
|
let ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: ast::Arguments { args, keywords, .. },
|
|
||||||
..
|
|
||||||
} = element.as_call_expr()?;
|
} = element.as_call_expr()?;
|
||||||
|
|
||||||
if !keywords.is_empty() {
|
if !arguments.keywords.is_empty() {
|
||||||
return None;
|
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))`
|
// Make the actual call `var.extend((elt1, elt2, ..., eltN))`
|
||||||
let call = ast::ExprCall {
|
let call = ast::ExprCall {
|
||||||
func: Box::new(attr.into()),
|
func: Box::new(attr.into()),
|
||||||
arguments: ast::Arguments {
|
arguments: Box::new(ast::Arguments {
|
||||||
args: Box::from([tuple.into()]),
|
args: Box::from([tuple.into()]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
// And finally, turn it into a statement.
|
// And finally, turn it into a statement.
|
||||||
|
|
|
||||||
|
|
@ -250,11 +250,11 @@ fn generate_range_len_call(name: &str, generator: Generator) -> String {
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
arguments: Arguments {
|
arguments: Box::new(Arguments {
|
||||||
args: Box::from([var.into()]),
|
args: Box::from([var.into()]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
// Construct `range(len(name))`.
|
// Construct `range(len(name))`.
|
||||||
|
|
@ -267,11 +267,11 @@ fn generate_range_len_call(name: &str, generator: Generator) -> String {
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
arguments: Arguments {
|
arguments: Box::new(Arguments {
|
||||||
args: Box::from([len.into()]),
|
args: Box::from([len.into()]),
|
||||||
keywords: Box::from([]),
|
keywords: Box::from([]),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
},
|
}),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
// And finally, turn it into a statement.
|
// And finally, turn it into a statement.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use anyhow::{bail, Result};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, 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_python_codegen::Stylist;
|
use ruff_python_codegen::Stylist;
|
||||||
use ruff_source_file::Locator;
|
use ruff_source_file::Locator;
|
||||||
use ruff_text_size::Ranged;
|
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 {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments:
|
|
||||||
Arguments {
|
|
||||||
args,
|
|
||||||
keywords,
|
|
||||||
range: _,
|
|
||||||
},
|
|
||||||
..
|
|
||||||
}) = expression.as_ref()
|
}) = expression.as_ref()
|
||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Can't be a conversion otherwise.
|
// Can't be a conversion otherwise.
|
||||||
if !keywords.is_empty() {
|
if !arguments.keywords.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't be a conversion otherwise.
|
// Can't be a conversion otherwise.
|
||||||
let [arg] = &**args else {
|
let [arg] = &*arguments.args else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,9 +99,7 @@ fn should_be_fstring(
|
||||||
for expr in semantic.current_expressions() {
|
for expr in semantic.current_expressions() {
|
||||||
match expr {
|
match expr {
|
||||||
ast::Expr::Call(ast::ExprCall {
|
ast::Expr::Call(ast::ExprCall {
|
||||||
arguments: ast::Arguments { keywords, args, .. },
|
arguments, func, ..
|
||||||
func,
|
|
||||||
..
|
|
||||||
}) => {
|
}) => {
|
||||||
if let ast::Expr::Attribute(ast::ExprAttribute { value, .. }) = func.as_ref() {
|
if let ast::Expr::Attribute(ast::ExprAttribute { value, .. }) = func.as_ref() {
|
||||||
match value.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() {
|
if let Some(ident) = keyword.arg.as_ref() {
|
||||||
arg_names.insert(ident.as_str());
|
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 {
|
if let ast::Expr::Name(ast::ExprName { id, .. }) = arg {
|
||||||
arg_names.insert(&**id);
|
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(
|
pub(crate) fn sort_dunder_all_extend_call(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
ast::ExprCall {
|
ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: ast::Arguments { args, keywords, .. },
|
|
||||||
..
|
|
||||||
}: &ast::ExprCall,
|
}: &ast::ExprCall,
|
||||||
) {
|
) {
|
||||||
let ([value_passed], []) = (&**args, &**keywords) else {
|
let ([value_passed], []) = (&*arguments.args, &*arguments.keywords) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let ast::Expr::Attribute(ast::ExprAttribute {
|
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)`.
|
/// - 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 {
|
fn fix_unnecessary_dict_comprehension(value: &Expr, generator: &Comprehension) -> Expr {
|
||||||
let iterable = generator.iter.clone();
|
let iterable = generator.iter.clone();
|
||||||
let args = Arguments {
|
let arguments = Arguments {
|
||||||
args: if value.is_none_literal_expr() {
|
args: if value.is_none_literal_expr() {
|
||||||
Box::from([iterable])
|
Box::from([iterable])
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -173,7 +173,7 @@ fn fix_unnecessary_dict_comprehension(value: &Expr, generator: &Comprehension) -
|
||||||
ctx: ExprContext::Load,
|
ctx: ExprContext::Load,
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
})),
|
})),
|
||||||
arguments: args,
|
arguments: Box::new(arguments),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use std::borrow::Cow;
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
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_semantic::SemanticModel;
|
||||||
use ruff_python_stdlib::builtins::is_iterator;
|
use ruff_python_stdlib::builtins::is_iterator;
|
||||||
use ruff_text_size::{Ranged, TextRange, TextSize};
|
use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||||
|
|
@ -136,9 +136,7 @@ struct IterationTarget {
|
||||||
fn match_iteration_target(expr: &Expr, semantic: &SemanticModel) -> Option<IterationTarget> {
|
fn match_iteration_target(expr: &Expr, semantic: &SemanticModel) -> Option<IterationTarget> {
|
||||||
let result = match expr {
|
let result = match expr {
|
||||||
Expr::Call(ast::ExprCall {
|
Expr::Call(ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: Arguments { args, .. },
|
|
||||||
..
|
|
||||||
}) => {
|
}) => {
|
||||||
let ast::ExprName { id, .. } = func.as_name_expr()?;
|
let ast::ExprName { id, .. } = func.as_name_expr()?;
|
||||||
|
|
||||||
|
|
@ -146,7 +144,7 @@ fn match_iteration_target(expr: &Expr, semantic: &SemanticModel) -> Option<Itera
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let [arg] = &**args else {
|
let [arg] = &*arguments.args else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, 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 ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -56,15 +56,13 @@ impl Violation for RaiseVanillaArgs {
|
||||||
/// TRY003
|
/// TRY003
|
||||||
pub(crate) fn raise_vanilla_args(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn raise_vanilla_args(checker: &mut Checker, expr: &Expr) {
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ast::ExprCall {
|
||||||
func,
|
func, arguments, ..
|
||||||
arguments: Arguments { args, .. },
|
|
||||||
..
|
|
||||||
}) = expr
|
}) = expr
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(arg) = args.first() else {
|
let Some(arg) = arguments.args.first() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -909,7 +909,7 @@ impl From<ExprCompare> for Expr {
|
||||||
pub struct ExprCall {
|
pub struct ExprCall {
|
||||||
pub range: TextRange,
|
pub range: TextRange,
|
||||||
pub func: Box<Expr>,
|
pub func: Box<Expr>,
|
||||||
pub arguments: Arguments,
|
pub arguments: Box<Arguments>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ExprCall> for Expr {
|
impl From<ExprCall> for Expr {
|
||||||
|
|
@ -3891,14 +3891,14 @@ mod tests {
|
||||||
// 88 for Rustc < 1.76
|
// 88 for Rustc < 1.76
|
||||||
assert!(matches!(std::mem::size_of::<Pattern>(), 80 | 88));
|
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::<ExprAttribute>(), 48);
|
||||||
assert_eq!(std::mem::size_of::<ExprAwait>(), 16);
|
assert_eq!(std::mem::size_of::<ExprAwait>(), 16);
|
||||||
assert_eq!(std::mem::size_of::<ExprBinOp>(), 32);
|
assert_eq!(std::mem::size_of::<ExprBinOp>(), 32);
|
||||||
assert_eq!(std::mem::size_of::<ExprBoolOp>(), 40);
|
assert_eq!(std::mem::size_of::<ExprBoolOp>(), 40);
|
||||||
assert_eq!(std::mem::size_of::<ExprBooleanLiteral>(), 12);
|
assert_eq!(std::mem::size_of::<ExprBooleanLiteral>(), 12);
|
||||||
assert_eq!(std::mem::size_of::<ExprBytesLiteral>(), 40);
|
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::<ExprCompare>(), 48);
|
||||||
assert_eq!(std::mem::size_of::<ExprDict>(), 40);
|
assert_eq!(std::mem::size_of::<ExprDict>(), 40);
|
||||||
assert_eq!(std::mem::size_of::<ExprDictComp>(), 48);
|
assert_eq!(std::mem::size_of::<ExprDictComp>(), 48);
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ fn test_parenthesized_argument() {
|
||||||
let expr = parse_expression(source_code).unwrap();
|
let expr = parse_expression(source_code).unwrap();
|
||||||
|
|
||||||
let call = expr.as_call_expr().unwrap();
|
let call = expr.as_call_expr().unwrap();
|
||||||
let arguments = &call.arguments;
|
let arguments = &*call.arguments;
|
||||||
let argument = arguments.args.first().unwrap();
|
let argument = arguments.args.first().unwrap();
|
||||||
|
|
||||||
let parenthesized = parenthesized_range(
|
let parenthesized = parenthesized_range(
|
||||||
|
|
@ -61,7 +61,7 @@ fn test_non_parenthesized_argument() {
|
||||||
let expr = parse_expression(source_code).unwrap();
|
let expr = parse_expression(source_code).unwrap();
|
||||||
|
|
||||||
let call = expr.as_call_expr().unwrap();
|
let call = expr.as_call_expr().unwrap();
|
||||||
let arguments = &call.arguments;
|
let arguments = &*call.arguments;
|
||||||
let argument = arguments.args.first().unwrap();
|
let argument = arguments.args.first().unwrap();
|
||||||
|
|
||||||
let parenthesized = parenthesized_range(
|
let parenthesized = parenthesized_range(
|
||||||
|
|
@ -130,7 +130,7 @@ fn test_twice_parenthesized_argument() {
|
||||||
let expr = parse_expression(source_code).unwrap();
|
let expr = parse_expression(source_code).unwrap();
|
||||||
|
|
||||||
let call = expr.as_call_expr().unwrap();
|
let call = expr.as_call_expr().unwrap();
|
||||||
let arguments = &call.arguments;
|
let arguments = &*call.arguments;
|
||||||
let argument = arguments.args.first().unwrap();
|
let argument = arguments.args.first().unwrap();
|
||||||
|
|
||||||
let parenthesized = parenthesized_range(
|
let parenthesized = parenthesized_range(
|
||||||
|
|
|
||||||
|
|
@ -1549,7 +1549,7 @@ AtomExpr2<Goal>: crate::parser::ParenthesizedExpr = {
|
||||||
Atom<Goal>,
|
Atom<Goal>,
|
||||||
<location:@L> <func:AtomExpr2<"all">> <arguments:Arguments> <end_location:@R> => ast::ExprCall {
|
<location:@L> <func:AtomExpr2<"all">> <arguments:Arguments> <end_location:@R> => ast::ExprCall {
|
||||||
func: Box::new(func.into()),
|
func: Box::new(func.into()),
|
||||||
arguments,
|
arguments: Box::new(arguments),
|
||||||
range: (location..end_location).into(),
|
range: (location..end_location).into(),
|
||||||
}.into(),
|
}.into(),
|
||||||
<location:@L> <value:AtomExpr2<"all">> "[" <slice:SubscriptList> "]" <end_location:@R> => ast::ExprSubscript {
|
<location:@L> <value:AtomExpr2<"all">> "[" <slice:SubscriptList> "]" <end_location:@R> => ast::ExprSubscript {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// auto-generated: "lalrpop 0.20.0"
|
// auto-generated: "lalrpop 0.20.0"
|
||||||
// sha3: 8f9c419cf07ccd6289047223fa22bb70c6afd0133b58ea606f601340160cab8b
|
// sha3: 06d23132da088f5a6184a546b53be668a940ce6dfd046b5ac08b6e70b7c9eb99
|
||||||
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
|
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
|
||||||
use ruff_python_ast::{self as ast, Int, IpyEscapeKind};
|
use ruff_python_ast::{self as ast, Int, IpyEscapeKind};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -41071,7 +41071,7 @@ fn __action541<
|
||||||
{
|
{
|
||||||
ast::ExprCall {
|
ast::ExprCall {
|
||||||
func: Box::new(func.into()),
|
func: Box::new(func.into()),
|
||||||
arguments,
|
arguments: Box::new(arguments),
|
||||||
range: (location..end_location).into(),
|
range: (location..end_location).into(),
|
||||||
}.into()
|
}.into()
|
||||||
}
|
}
|
||||||
|
|
@ -41868,7 +41868,7 @@ fn __action588<
|
||||||
{
|
{
|
||||||
ast::ExprCall {
|
ast::ExprCall {
|
||||||
func: Box::new(func.into()),
|
func: Box::new(func.into()),
|
||||||
arguments,
|
arguments: Box::new(arguments),
|
||||||
range: (location..end_location).into(),
|
range: (location..end_location).into(),
|
||||||
}.into()
|
}.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue