From 011c6ac1a4efa41ce82fb230ca06f97ae50d662e Mon Sep 17 00:00:00 2001 From: "Yilei \"Dolee\" Yang" Date: Fri, 7 Apr 2023 00:06:54 -0700 Subject: Do not emit `logging-not-lazy` for explicitly concatenated strings. (#8546) (cherry picked from commit eeddd667a6e73ef58fb47cdda154c1751f0ffe71) --- doc/whatsnew/fragments/8410.false_positive | 3 +++ pylint/checkers/logging.py | 15 ++++++++++++++- tests/functional/l/logging/logging_not_lazy.py | 7 ++++++- tests/functional/l/logging/logging_not_lazy.txt | 12 ++++++------ 4 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 doc/whatsnew/fragments/8410.false_positive diff --git a/doc/whatsnew/fragments/8410.false_positive b/doc/whatsnew/fragments/8410.false_positive new file mode 100644 index 000000000..264542a7d --- /dev/null +++ b/doc/whatsnew/fragments/8410.false_positive @@ -0,0 +1,3 @@ +`logging-not-lazy` is not longer emitted for explicitly concatenated string arguments. + +Closes #8410 diff --git a/pylint/checkers/logging.py b/pylint/checkers/logging.py index f7568a3a4..3064dc926 100644 --- a/pylint/checkers/logging.py +++ b/pylint/checkers/logging.py @@ -246,7 +246,7 @@ class LoggingChecker(checkers.BaseChecker): if isinstance(format_arg, nodes.BinOp): binop = format_arg emit = binop.op == "%" - if binop.op == "+": + if binop.op == "+" and not self._is_node_explicit_str_concatenation(binop): total_number_of_strings = sum( 1 for operand in (binop.left, binop.right) @@ -294,6 +294,19 @@ class LoggingChecker(checkers.BaseChecker): """Return True if the operand in argument is a literal string.""" return isinstance(operand, nodes.Const) and operand.name == "str" + @staticmethod + def _is_node_explicit_str_concatenation(node: nodes.NodeNG) -> bool: + """Return True if the node represents an explicitly concatenated string.""" + if not isinstance(node, nodes.BinOp): + return False + return ( + LoggingChecker._is_operand_literal_str(node.left) + or LoggingChecker._is_node_explicit_str_concatenation(node.left) + ) and ( + LoggingChecker._is_operand_literal_str(node.right) + or LoggingChecker._is_node_explicit_str_concatenation(node.right) + ) + def _check_call_func(self, node: nodes.Call) -> None: """Checks that function call is not format_string.format().""" func = utils.safe_infer(node.func) diff --git a/tests/functional/l/logging/logging_not_lazy.py b/tests/functional/l/logging/logging_not_lazy.py index ab1ce008c..aa2401dbc 100644 --- a/tests/functional/l/logging/logging_not_lazy.py +++ b/tests/functional/l/logging/logging_not_lazy.py @@ -9,10 +9,10 @@ var = "123" var_name = "Var:" # Statements that should be flagged: renamed_logging.warn("%s, %s" % (4, 5)) # [logging-not-lazy] +renamed_logging.warn("Var: " + var) # [logging-not-lazy] renamed_logging.exception("%s" % "Exceptional!") # [logging-not-lazy] renamed_logging.log(renamed_logging.INFO, "msg: %s" % "Run!") # [logging-not-lazy] renamed_logging.log(renamed_logging.INFO, "Var: " + var) # [logging-not-lazy] -renamed_logging.warn("%s" + " the rest of a single string") # [logging-not-lazy] renamed_logging.log(renamed_logging.INFO, var_name + var) # [logging-not-lazy] # Statements that should not be flagged: @@ -21,6 +21,11 @@ renamed_logging.log(renamed_logging.INFO, "msg: %s", "Run!") logging.warn("%s, %s" % (4, 5)) logging.log(logging.INFO, "msg: %s" % "Run!") logging.log("Var: " + var) +# Explicit string concatenations are fine: +renamed_logging.warn("%s" + " the rest of a single string") +renamed_logging.warn("Msg: " + "%s", "first piece " + "second piece") +renamed_logging.warn("first" + "second" + "third %s", "parameter") +renamed_logging.warn(("first" + "second" + "third %s")) # Regression crash test for incorrect format call renamed_logging.error( diff --git a/tests/functional/l/logging/logging_not_lazy.txt b/tests/functional/l/logging/logging_not_lazy.txt index 564fa65c3..774082eb7 100644 --- a/tests/functional/l/logging/logging_not_lazy.txt +++ b/tests/functional/l/logging/logging_not_lazy.txt @@ -1,8 +1,8 @@ logging-not-lazy:11:0:11:39::Use lazy % formatting in logging functions:UNDEFINED -logging-not-lazy:12:0:12:48::Use lazy % formatting in logging functions:UNDEFINED -logging-not-lazy:13:0:13:61::Use lazy % formatting in logging functions:UNDEFINED -logging-not-lazy:14:0:14:56::Use lazy % formatting in logging functions:UNDEFINED -logging-not-lazy:15:0:15:59::Use lazy % formatting in logging functions:UNDEFINED +logging-not-lazy:12:0:12:35::Use lazy % formatting in logging functions:UNDEFINED +logging-not-lazy:13:0:13:48::Use lazy % formatting in logging functions:UNDEFINED +logging-not-lazy:14:0:14:61::Use lazy % formatting in logging functions:UNDEFINED +logging-not-lazy:15:0:15:56::Use lazy % formatting in logging functions:UNDEFINED logging-not-lazy:16:0:16:57::Use lazy % formatting in logging functions:UNDEFINED -bad-format-string:27:4:27:27::Invalid format string:UNDEFINED -logging-format-interpolation:27:4:27:27::Use lazy % formatting in logging functions:UNDEFINED +bad-format-string:32:4:32:27::Invalid format string:UNDEFINED +logging-format-interpolation:32:4:32:27::Use lazy % formatting in logging functions:UNDEFINED -- cgit v1.2.1