Improve counting of message arguments when msg is provided as a keyword (#6456)

Closes https://github.com/astral-sh/ruff/issues/6454.
This commit is contained in:
Charlie Marsh 2023-08-09 16:39:10 -04:00 committed by GitHub
parent 3ecd263b4d
commit 395bb31247
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 20 additions and 14 deletions

View File

@ -19,6 +19,10 @@ logging.error("Example log %s, %s", "foo", "bar", "baz", **kwargs)
# do not handle keyword arguments
logging.error("%(objects)d modifications: %(modifications)d errors: %(errors)d")
logging.info(msg="Hello %s")
logging.info(msg="Hello %s %s")
import warning
warning.warning("Hello %s %s", "World!")

View File

@ -15,6 +15,10 @@ logging.error("Example log %s, %s", "foo", "bar", "baz", **kwargs)
# do not handle keyword arguments
logging.error("%(objects)d modifications: %(modifications)d errors: %(errors)d", {"objects": 1, "modifications": 1, "errors": 1})
logging.info(msg="Hello")
logging.info(msg="Hello", something="else")
import warning
warning.warning("Hello %s", "World!", "again")

View File

@ -111,8 +111,8 @@ pub(crate) fn logging_call(checker: &mut Checker, call: &ast::ExprCall) {
let Some(Expr::Constant(ast::ExprConstant {
value: Constant::Str(value),
..
})) = call.arguments.find_argument("msg", 0)
else {
})) = call.arguments
.find_positional( 0) else {
return;
};

View File

@ -2126,23 +2126,21 @@ impl Arguments {
})
}
/// Return the argument with the given name or at the given position, or `None` if no such
/// argument exists. Used to retrieve arguments that can be provided _either_ as keyword or
/// positional arguments.
pub fn find_argument(&self, name: &str, position: usize) -> Option<&Expr> {
self.keywords
.iter()
.find(|keyword| {
let Keyword { arg, .. } = keyword;
arg.as_ref().is_some_and(|arg| arg == name)
})
.map(|keyword| &keyword.value)
.or_else(|| {
/// Return the positional argument at the given index, or `None` if no such argument exists.
pub fn find_positional(&self, position: usize) -> Option<&Expr> {
self.args
.iter()
.take_while(|expr| !expr.is_starred_expr())
.nth(position)
})
}
/// Return the argument with the given name or at the given position, or `None` if no such
/// argument exists. Used to retrieve arguments that can be provided _either_ as keyword or
/// positional arguments.
pub fn find_argument(&self, name: &str, position: usize) -> Option<&Expr> {
self.find_keyword(name)
.map(|keyword| &keyword.value)
.or_else(|| self.find_positional(position))
}
}