mirror of https://github.com/astral-sh/ruff
Merge eae8f6f5e7 into b0bc990cbf
This commit is contained in:
commit
4d7775d66d
|
|
@ -1039,13 +1039,13 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
|||
&checker.settings().flake8_gettext.functions_names,
|
||||
) {
|
||||
if checker.is_rule_enabled(Rule::FStringInGetTextFuncCall) {
|
||||
flake8_gettext::rules::f_string_in_gettext_func_call(checker, args);
|
||||
flake8_gettext::rules::f_string_in_gettext_func_call(checker, func, args);
|
||||
}
|
||||
if checker.is_rule_enabled(Rule::FormatInGetTextFuncCall) {
|
||||
flake8_gettext::rules::format_in_gettext_func_call(checker, args);
|
||||
flake8_gettext::rules::format_in_gettext_func_call(checker, func, args);
|
||||
}
|
||||
if checker.is_rule_enabled(Rule::PrintfInGetTextFuncCall) {
|
||||
flake8_gettext::rules::printf_in_gettext_func_call(checker, args);
|
||||
flake8_gettext::rules::printf_in_gettext_func_call(checker, func, args);
|
||||
}
|
||||
}
|
||||
if checker.is_rule_enabled(Rule::UncapitalizedEnvironmentVariables) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
use crate::checkers::ast::Checker;
|
||||
use ruff_python_ast::Expr;
|
||||
|
||||
/// Returns true if the function call is ngettext
|
||||
pub(crate) fn is_ngettext_call(checker: &Checker, func: &Expr) -> bool {
|
||||
let semantic = checker.semantic();
|
||||
|
||||
// Check if it's a direct name reference to ngettext
|
||||
if let Some(name) = func.as_name_expr() {
|
||||
if name.id == "ngettext" {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if it's a qualified name ending with ngettext
|
||||
if let Some(qualified_name) = semantic.resolve_qualified_name(func) {
|
||||
return matches!(qualified_name.segments(), [.., "ngettext"]);
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ use ruff_python_ast::name::Name;
|
|||
use ruff_python_ast::{self as ast, Expr};
|
||||
use ruff_python_semantic::Modules;
|
||||
|
||||
pub(crate) mod helpers;
|
||||
pub(crate) mod rules;
|
||||
pub mod settings;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use ruff_text_size::Ranged;
|
|||
|
||||
use crate::Violation;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::rules::flake8_gettext::helpers;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for f-strings in `gettext` function calls.
|
||||
|
|
@ -52,10 +53,20 @@ impl Violation for FStringInGetTextFuncCall {
|
|||
}
|
||||
|
||||
/// INT001
|
||||
pub(crate) fn f_string_in_gettext_func_call(checker: &Checker, args: &[Expr]) {
|
||||
pub(crate) fn f_string_in_gettext_func_call(checker: &Checker, func: &Expr, args: &[Expr]) {
|
||||
// Check first argument (singular)
|
||||
if let Some(first) = args.first() {
|
||||
if first.is_f_string_expr() {
|
||||
checker.report_diagnostic(FStringInGetTextFuncCall {}, first.range());
|
||||
}
|
||||
}
|
||||
|
||||
// Check second argument (plural) for ngettext calls
|
||||
if helpers::is_ngettext_call(checker, func) {
|
||||
if let Some(second) = args.get(1) {
|
||||
if second.is_f_string_expr() {
|
||||
checker.report_diagnostic(FStringInGetTextFuncCall {}, second.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use ruff_text_size::Ranged;
|
|||
|
||||
use crate::Violation;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::rules::flake8_gettext::helpers;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for `str.format` calls in `gettext` function calls.
|
||||
|
|
@ -52,7 +53,8 @@ impl Violation for FormatInGetTextFuncCall {
|
|||
}
|
||||
|
||||
/// INT002
|
||||
pub(crate) fn format_in_gettext_func_call(checker: &Checker, args: &[Expr]) {
|
||||
pub(crate) fn format_in_gettext_func_call(checker: &Checker, func: &Expr, args: &[Expr]) {
|
||||
// Check first argument (singular)
|
||||
if let Some(first) = args.first() {
|
||||
if let Expr::Call(ast::ExprCall { func, .. }) = &first {
|
||||
if let Expr::Attribute(ast::ExprAttribute { attr, .. }) = func.as_ref() {
|
||||
|
|
@ -62,4 +64,17 @@ pub(crate) fn format_in_gettext_func_call(checker: &Checker, args: &[Expr]) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check second argument (plural) for ngettext calls
|
||||
if helpers::is_ngettext_call(checker, func) {
|
||||
if let Some(second) = args.get(1) {
|
||||
if let Expr::Call(ast::ExprCall { func, .. }) = &second {
|
||||
if let Expr::Attribute(ast::ExprAttribute { attr, .. }) = func.as_ref() {
|
||||
if attr == "format" {
|
||||
checker.report_diagnostic(FormatInGetTextFuncCall {}, second.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use ruff_text_size::Ranged;
|
|||
|
||||
use crate::Violation;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::rules::flake8_gettext::helpers;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for printf-style formatted strings in `gettext` function calls.
|
||||
|
|
@ -52,7 +53,8 @@ impl Violation for PrintfInGetTextFuncCall {
|
|||
}
|
||||
|
||||
/// INT003
|
||||
pub(crate) fn printf_in_gettext_func_call(checker: &Checker, args: &[Expr]) {
|
||||
pub(crate) fn printf_in_gettext_func_call(checker: &Checker, func: &Expr, args: &[Expr]) {
|
||||
// Check first argument (singular)
|
||||
if let Some(first) = args.first() {
|
||||
if let Expr::BinOp(ast::ExprBinOp {
|
||||
op: Operator::Mod,
|
||||
|
|
@ -65,4 +67,20 @@ pub(crate) fn printf_in_gettext_func_call(checker: &Checker, args: &[Expr]) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check second argument (plural) for ngettext calls
|
||||
if helpers::is_ngettext_call(checker, func) {
|
||||
if let Some(second) = args.get(1) {
|
||||
if let Expr::BinOp(ast::ExprBinOp {
|
||||
op: Operator::Mod,
|
||||
left,
|
||||
..
|
||||
}) = &second
|
||||
{
|
||||
if left.is_string_literal_expr() {
|
||||
checker.report_diagnostic(PrintfInGetTextFuncCall {}, second.range());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,16 @@ INT001 f-string is resolved before function call; consider `_("string %s") % arg
|
|||
9 | _gettext(f"{'value'}") # no lint
|
||||
|
|
||||
|
||||
INT001 f-string is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT001.py:7:24
|
||||
|
|
||||
6 | gettext(f"{'value'}")
|
||||
7 | ngettext(f"{'value'}", f"{'values'}", 2)
|
||||
| ^^^^^^^^^^^^^
|
||||
8 |
|
||||
9 | _gettext(f"{'value'}") # no lint
|
||||
|
|
||||
|
||||
INT001 f-string is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT001.py:31:14
|
||||
|
|
||||
|
|
|
|||
|
|
@ -30,6 +30,17 @@ INT002 `format` method argument is resolved before function call; consider `_("s
|
|||
5 | _gettext("{}".format("line")) # no lint
|
||||
|
|
||||
|
||||
INT002 `format` method argument is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT002.py:3:31
|
||||
|
|
||||
1 | _("{}".format("line"))
|
||||
2 | gettext("{}".format("line"))
|
||||
3 | ngettext("{}".format("line"), "{}".format("lines"), 2)
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
4 |
|
||||
5 | _gettext("{}".format("line")) # no lint
|
||||
|
|
||||
|
||||
INT002 `format` method argument is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT002.py:27:14
|
||||
|
|
||||
|
|
|
|||
|
|
@ -30,6 +30,16 @@ INT001 f-string is resolved before function call; consider `_("string %s") % arg
|
|||
9 | _gettext(f"{'value'}") # no lint
|
||||
|
|
||||
|
||||
INT001 f-string is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT001.py:7:24
|
||||
|
|
||||
6 | gettext(f"{'value'}")
|
||||
7 | ngettext(f"{'value'}", f"{'values'}", 2)
|
||||
| ^^^^^^^^^^^^^
|
||||
8 |
|
||||
9 | _gettext(f"{'value'}") # no lint
|
||||
|
|
||||
|
||||
INT001 f-string is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT001.py:22:21
|
||||
|
|
||||
|
|
@ -51,6 +61,16 @@ INT001 f-string is resolved before function call; consider `_("string %s") % arg
|
|||
25 | ngettext_fn(f"Hello, {name}!", f"Hello, {name}s!", 2)
|
||||
|
|
||||
|
||||
INT001 f-string is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT001.py:23:41
|
||||
|
|
||||
22 | gettext_mod.gettext(f"Hello, {name}!")
|
||||
23 | gettext_mod.ngettext(f"Hello, {name}!", f"Hello, {name}s!", 2)
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
24 | gettext_fn(f"Hello, {name}!")
|
||||
25 | ngettext_fn(f"Hello, {name}!", f"Hello, {name}s!", 2)
|
||||
|
|
||||
|
||||
INT001 f-string is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT001.py:24:12
|
||||
|
|
||||
|
|
@ -70,6 +90,15 @@ INT001 f-string is resolved before function call; consider `_("string %s") % arg
|
|||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
|
||||
INT001 f-string is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT001.py:25:32
|
||||
|
|
||||
23 | gettext_mod.ngettext(f"Hello, {name}!", f"Hello, {name}s!", 2)
|
||||
24 | gettext_fn(f"Hello, {name}!")
|
||||
25 | ngettext_fn(f"Hello, {name}!", f"Hello, {name}s!", 2)
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
|
||||
INT001 f-string is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT001.py:31:14
|
||||
|
|
||||
|
|
@ -160,3 +189,12 @@ INT001 f-string is resolved before function call; consider `_("string %s") % arg
|
|||
53 | builtins.ngettext(f"{'value'}", f"{'values'}", 2)
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
|
||||
INT001 f-string is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT001.py:53:33
|
||||
|
|
||||
51 | builtins._(f"{'value'}")
|
||||
52 | builtins.gettext(f"{'value'}")
|
||||
53 | builtins.ngettext(f"{'value'}", f"{'values'}", 2)
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -30,6 +30,17 @@ INT002 `format` method argument is resolved before function call; consider `_("s
|
|||
5 | _gettext("{}".format("line")) # no lint
|
||||
|
|
||||
|
||||
INT002 `format` method argument is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT002.py:3:31
|
||||
|
|
||||
1 | _("{}".format("line"))
|
||||
2 | gettext("{}".format("line"))
|
||||
3 | ngettext("{}".format("line"), "{}".format("lines"), 2)
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
4 |
|
||||
5 | _gettext("{}".format("line")) # no lint
|
||||
|
|
||||
|
||||
INT002 `format` method argument is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT002.py:18:21
|
||||
|
|
||||
|
|
@ -51,6 +62,16 @@ INT002 `format` method argument is resolved before function call; consider `_("s
|
|||
21 | ngettext_fn("Hello, {}!".format(name), "Hello, {}s!".format(name), 2)
|
||||
|
|
||||
|
||||
INT002 `format` method argument is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT002.py:19:49
|
||||
|
|
||||
18 | gettext_mod.gettext("Hello, {}!".format(name))
|
||||
19 | gettext_mod.ngettext("Hello, {}!".format(name), "Hello, {}s!".format(name), 2)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
20 | gettext_fn("Hello, {}!".format(name))
|
||||
21 | ngettext_fn("Hello, {}!".format(name), "Hello, {}s!".format(name), 2)
|
||||
|
|
||||
|
||||
INT002 `format` method argument is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT002.py:20:12
|
||||
|
|
||||
|
|
@ -70,6 +91,15 @@ INT002 `format` method argument is resolved before function call; consider `_("s
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
|
||||
INT002 `format` method argument is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT002.py:21:40
|
||||
|
|
||||
19 | gettext_mod.ngettext("Hello, {}!".format(name), "Hello, {}s!".format(name), 2)
|
||||
20 | gettext_fn("Hello, {}!".format(name))
|
||||
21 | ngettext_fn("Hello, {}!".format(name), "Hello, {}s!".format(name), 2)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
|
||||
INT002 `format` method argument is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT002.py:27:14
|
||||
|
|
||||
|
|
@ -160,3 +190,12 @@ INT002 `format` method argument is resolved before function call; consider `_("s
|
|||
49 | builtins.ngettext("{}".format("line"), "{}".format("lines"), 2)
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
|
||||
INT002 `format` method argument is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT002.py:49:40
|
||||
|
|
||||
47 | builtins._("{}".format("line"))
|
||||
48 | builtins.gettext("{}".format("line"))
|
||||
49 | builtins.ngettext("{}".format("line"), "{}".format("lines"), 2)
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -30,6 +30,17 @@ INT003 printf-style format is resolved before function call; consider `_("string
|
|||
5 | _gettext("%s" % "line") # no lint
|
||||
|
|
||||
|
||||
INT003 printf-style format is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT003.py:3:25
|
||||
|
|
||||
1 | _("%s" % "line")
|
||||
2 | gettext("%s" % "line")
|
||||
3 | ngettext("%s" % "line", "%s" % "lines", 2)
|
||||
| ^^^^^^^^^^^^^^
|
||||
4 |
|
||||
5 | _gettext("%s" % "line") # no lint
|
||||
|
|
||||
|
||||
INT003 printf-style format is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT003.py:18:21
|
||||
|
|
||||
|
|
@ -51,6 +62,16 @@ INT003 printf-style format is resolved before function call; consider `_("string
|
|||
21 | ngettext_fn("Hello, %s!" % name, "Hello, %ss!" % name, 2)
|
||||
|
|
||||
|
||||
INT003 printf-style format is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT003.py:19:43
|
||||
|
|
||||
18 | gettext_mod.gettext("Hello, %s!" % name)
|
||||
19 | gettext_mod.ngettext("Hello, %s!" % name, "Hello, %ss!" % name, 2)
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
20 | gettext_fn("Hello, %s!" % name)
|
||||
21 | ngettext_fn("Hello, %s!" % name, "Hello, %ss!" % name, 2)
|
||||
|
|
||||
|
||||
INT003 printf-style format is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT003.py:20:12
|
||||
|
|
||||
|
|
@ -70,6 +91,15 @@ INT003 printf-style format is resolved before function call; consider `_("string
|
|||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
|
||||
INT003 printf-style format is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT003.py:21:34
|
||||
|
|
||||
19 | gettext_mod.ngettext("Hello, %s!" % name, "Hello, %ss!" % name, 2)
|
||||
20 | gettext_fn("Hello, %s!" % name)
|
||||
21 | ngettext_fn("Hello, %s!" % name, "Hello, %ss!" % name, 2)
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
|
||||
INT003 printf-style format is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT003.py:27:14
|
||||
|
|
||||
|
|
@ -160,3 +190,12 @@ INT003 printf-style format is resolved before function call; consider `_("string
|
|||
49 | builtins.ngettext("%s" % "line", "%s" % "lines", 2)
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
|
||||
INT003 printf-style format is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT003.py:49:34
|
||||
|
|
||||
47 | builtins._("%s" % "line")
|
||||
48 | builtins.gettext("%s" % "line")
|
||||
49 | builtins.ngettext("%s" % "line", "%s" % "lines", 2)
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
|
|
|
|||
|
|
@ -30,6 +30,17 @@ INT003 printf-style format is resolved before function call; consider `_("string
|
|||
5 | _gettext("%s" % "line") # no lint
|
||||
|
|
||||
|
||||
INT003 printf-style format is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT003.py:3:25
|
||||
|
|
||||
1 | _("%s" % "line")
|
||||
2 | gettext("%s" % "line")
|
||||
3 | ngettext("%s" % "line", "%s" % "lines", 2)
|
||||
| ^^^^^^^^^^^^^^
|
||||
4 |
|
||||
5 | _gettext("%s" % "line") # no lint
|
||||
|
|
||||
|
||||
INT003 printf-style format is resolved before function call; consider `_("string %s") % arg`
|
||||
--> INT003.py:27:14
|
||||
|
|
||||
|
|
|
|||
Loading…
Reference in New Issue