summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshley Whetter <ashley@awhetter.co.uk>2020-04-05 18:11:08 -0700
committerClaudiu Popa <pcmanticore@gmail.com>2020-04-27 10:34:18 +0200
commitfb59ed86d5e463ebfdeb5d0af8539b7a8431aa15 (patch)
tree460a7553ace1d0b8b6dde264cd97d6b4b0dd3d6f
parentdb0d55bcb19db4d8a9b7dd339d6ab554a4a1f017 (diff)
downloadpylint-git-fb59ed86d5e463ebfdeb5d0af8539b7a8431aa15.tar.gz
Brought back logging-fstring-interpolation
-rw-r--r--ChangeLog7
-rw-r--r--doc/whatsnew/2.5.rst8
-rw-r--r--pylint/checkers/logging.py102
-rw-r--r--tests/functional/l/logging_format_interpolation.txt10
-rw-r--r--tests/functional/l/logging_format_interpolation_py36.py4
-rw-r--r--tests/functional/l/logging_format_interpolation_py36.txt2
-rw-r--r--tests/functional/l/logging_fstring_interpolation_py36.py12
-rw-r--r--tests/functional/l/logging_fstring_interpolation_py36.txt10
-rw-r--r--tests/functional/l/logging_not_lazy.txt12
-rw-r--r--tests/messages/func_bug113231.txt4
-rw-r--r--tests/messages/func_logging_not_lazy_with_logger.txt8
-rw-r--r--tests/unittest_checker_logging.py46
12 files changed, 113 insertions, 112 deletions
diff --git a/ChangeLog b/ChangeLog
index f8d322ef6..22d2cf50e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -275,6 +275,13 @@ Release date: TBA
Close #1482
Close #1553
+* Multiple types of string formatting are allowed in logging functions.
+
+ The `logging-fstring-interpolation` message has been brought back to allow
+ multiple types of string formatting to be used.
+
+ Close #3361
+
What's New in Pylint 2.4.4?
===========================
Release date: 2019-11-13
diff --git a/doc/whatsnew/2.5.rst b/doc/whatsnew/2.5.rst
index 178b8c34b..35ffbbdcc 100644
--- a/doc/whatsnew/2.5.rst
+++ b/doc/whatsnew/2.5.rst
@@ -92,3 +92,11 @@ Other Changes
This command lists all extensions present in ``pylint.extensions``.
* Various false positives have been fixed which you can read more about in the Changelog files.
+
+* Multiple types of string formatting are allowed in logging functions.
+
+The `logging-fstring-interpolation` message has been brought back to allow
+multiple types of string formatting to be used.
+The type of formatting to use is chosen through enabling and disabling messages
+rather than through the logging-format-style option.
+The fstr value of the logging-format-style option is not valid.
diff --git a/pylint/checkers/logging.py b/pylint/checkers/logging.py
index 9a2ab95d3..5de0340d5 100644
--- a/pylint/checkers/logging.py
+++ b/pylint/checkers/logging.py
@@ -26,25 +26,43 @@ from pylint.checkers.utils import check_messages
MSGS = {
"W1201": (
- "Specify string format arguments as logging function parameters",
+ "Use %s formatting in logging functions",
"logging-not-lazy",
"Used when a logging statement has a call form of "
'"logging.<logging method>(format_string % (format_args...))". '
- "Such calls should leave string interpolation to the logging "
- "method itself and be written "
- '"logging.<logging method>(format_string, format_args...)" '
- "so that the program may avoid incurring the cost of the "
- "interpolation in those cases in which no message will be "
- "logged. For more, see "
- "http://www.python.org/dev/peps/pep-0282/.",
+ "Use another type of string formatting instead. "
+ "You can use % formatting but leave interpolation to "
+ "the logging function by passing the parameters as arguments. "
+ "If logging-fstring-interpolation is disabled then "
+ "you can use fstring formatting. "
+ "If logging-format-interpolation is disabled then "
+ "you can use str.format.",
),
"W1202": (
- "Use %s formatting in logging functions%s",
+ "Use %s formatting in logging functions",
"logging-format-interpolation",
"Used when a logging statement has a call form of "
- '"logging.<logging method>(<string formatting>)".'
- " with invalid string formatting. "
- "Use another way for format the string instead.",
+ '"logging.<logging method>(format_string.format(format_args...))". '
+ "Use another type of string formatting instead. "
+ "You can use % formatting but leave interpolation to "
+ "the logging function by passing the parameters as arguments. "
+ "If logging-fstring-interpolation is disabled then "
+ "you can use fstring formatting. "
+ "If logging-not-lazy is disabled then "
+ "you can use % formatting as normal.",
+ ),
+ "W1203": (
+ "Use %s formatting in logging functions",
+ "logging-fstring-interpolation",
+ "Used when a logging statement has a call form of "
+ '"logging.<logging method>(f"...")".'
+ "Use another type of string formatting instead. "
+ "You can use % formatting but leave interpolation to "
+ "the logging function by passing the parameters as arguments. "
+ "If logging-format-interpolation is disabled then "
+ "you can use str.format. "
+ "If logging-not-lazy is disabled then "
+ "you can use % formatting as normal.",
),
"E1200": (
"Unsupported logging format character %r (%#02x) at index %d",
@@ -126,11 +144,10 @@ class LoggingChecker(checkers.BaseChecker):
{
"default": "old",
"type": "choice",
- "metavar": "<old (%) or new ({) or fstr (f'')>",
- "choices": ["old", "new", "fstr"],
- "help": "Format style used to check logging format string. "
- "`old` means using % formatting, `new` is for `{}` formatting,"
- "and `fstr` is for f-strings.",
+ "metavar": "<old (%) or new ({)>",
+ "choices": ["old", "new"],
+ "help": "The type of string formatting that logging methods do. "
+ "`old` means using % formatting, `new` is for `{}` formatting.",
},
),
)
@@ -144,12 +161,6 @@ class LoggingChecker(checkers.BaseChecker):
logging_mods = self.config.logging_modules
self._format_style = self.config.logging_format_style
- format_styles = {"old": "%", "new": "{", "fstr": "f-string"}
- format_style_help = ""
- if self._format_style == "old":
- format_style_help = " and pass the % parameters as arguments"
-
- self._format_style_args = (format_styles[self._format_style], format_style_help)
self._logging_modules = set(logging_mods)
self._from_imports = {}
@@ -238,20 +249,36 @@ class LoggingChecker(checkers.BaseChecker):
)
emit = total_number_of_strings > 0
if emit:
- self.add_message("logging-not-lazy", node=node)
+ self.add_message(
+ "logging-not-lazy", node=node, args=(self._helper_string(node),),
+ )
elif isinstance(node.args[format_pos], astroid.Call):
self._check_call_func(node.args[format_pos])
elif isinstance(node.args[format_pos], astroid.Const):
self._check_format_string(node, format_pos)
- elif isinstance(
- node.args[format_pos], (astroid.FormattedValue, astroid.JoinedStr)
+ elif isinstance(node.args[format_pos], astroid.JoinedStr):
+ self.add_message(
+ "logging-fstring-interpolation",
+ node=node,
+ args=(self._helper_string(node),),
+ )
+
+ def _helper_string(self, node):
+ """Create a string that lists the valid types of formatting for this node."""
+ valid_types = ["lazy %"]
+
+ if not self.linter.is_message_enabled(
+ "logging-fstring-formatting", node.fromlineno
):
- if self._format_style != "fstr":
- self.add_message(
- "logging-format-interpolation",
- node=node,
- args=self._format_style_args,
- )
+ valid_types.append("fstring")
+ if not self.linter.is_message_enabled(
+ "logging-format-formatting", node.fromlineno
+ ):
+ valid_types.append(".format()")
+ if not self.linter.is_message_enabled("logging-not-lazy", node.fromlineno):
+ valid_types.append("%")
+
+ return " or ".join(valid_types)
@staticmethod
def _is_operand_literal_str(operand):
@@ -274,7 +301,9 @@ class LoggingChecker(checkers.BaseChecker):
func.bound
):
self.add_message(
- "logging-format-interpolation", node=node, args=self._format_style_args
+ "logging-format-interpolation",
+ node=node,
+ args=(self._helper_string(node),),
)
def _check_format_string(self, node, format_arg):
@@ -317,13 +346,6 @@ class LoggingChecker(checkers.BaseChecker):
required_num_args = (
keyword_args_cnt + implicit_pos_args + explicit_pos_args
)
- else:
- self.add_message(
- "logging-format-interpolation",
- node=node,
- args=self._format_style_args,
- )
- return
except utils.UnsupportedFormatCharacter as ex:
char = format_string[ex.index]
self.add_message(
diff --git a/tests/functional/l/logging_format_interpolation.txt b/tests/functional/l/logging_format_interpolation.txt
index 36051253c..1b27530b7 100644
--- a/tests/functional/l/logging_format_interpolation.txt
+++ b/tests/functional/l/logging_format_interpolation.txt
@@ -1,5 +1,5 @@
-logging-format-interpolation:16::Use % formatting in logging functions and pass the % parameters as arguments
-logging-format-interpolation:17::Use % formatting in logging functions and pass the % parameters as arguments
-logging-format-interpolation:18::Use % formatting in logging functions and pass the % parameters as arguments
-logging-format-interpolation:19::Use % formatting in logging functions and pass the % parameters as arguments
-logging-format-interpolation:20::Use % formatting in logging functions and pass the % parameters as arguments
+logging-format-interpolation:16::Use lazy % formatting in logging functions
+logging-format-interpolation:17::Use lazy % formatting in logging functions
+logging-format-interpolation:18::Use lazy % formatting in logging functions
+logging-format-interpolation:19::Use lazy % formatting in logging functions
+logging-format-interpolation:20::Use lazy % formatting in logging functions
diff --git a/tests/functional/l/logging_format_interpolation_py36.py b/tests/functional/l/logging_format_interpolation_py36.py
index 92958ae5a..2601c5bfc 100644
--- a/tests/functional/l/logging_format_interpolation_py36.py
+++ b/tests/functional/l/logging_format_interpolation_py36.py
@@ -1,5 +1,5 @@
-"""Test logging-format-interpolation for Python 3.6"""
+"""Test logging-fstring-interpolation for Python 3.6"""
import logging as renamed_logging
-renamed_logging.info(f'Read {renamed_logging} from globals') # [logging-format-interpolation]
+renamed_logging.info(f'Read {renamed_logging} from globals') # [logging-fstring-interpolation]
diff --git a/tests/functional/l/logging_format_interpolation_py36.txt b/tests/functional/l/logging_format_interpolation_py36.txt
index 7a7dc06c0..bc185c975 100644
--- a/tests/functional/l/logging_format_interpolation_py36.txt
+++ b/tests/functional/l/logging_format_interpolation_py36.txt
@@ -1 +1 @@
-logging-format-interpolation:5::Use % formatting in logging functions and pass the % parameters as arguments
+logging-fstring-interpolation:5::Use lazy % formatting in logging functions
diff --git a/tests/functional/l/logging_fstring_interpolation_py36.py b/tests/functional/l/logging_fstring_interpolation_py36.py
index 68eaba22f..5aebb7dd2 100644
--- a/tests/functional/l/logging_fstring_interpolation_py36.py
+++ b/tests/functional/l/logging_fstring_interpolation_py36.py
@@ -1,4 +1,4 @@
-"""Test logging-format-interpolation for Python 3.6"""
+"""Test logging-fstring-interpolation for Python 3.6"""
# pylint: disable=invalid-name
from datetime import datetime
@@ -14,8 +14,8 @@ pi = 3.14159265
may_14 = datetime(year=2018, month=5, day=14)
# Statements that should be flagged:
-renamed_logging.debug(f'{local_var_1} {local_var_2}') # [logging-format-interpolation]
-renamed_logging.log(renamed_logging.DEBUG, f'msg: {local_var_2}') # [logging-format-interpolation]
-renamed_logging.log(renamed_logging.DEBUG, f'pi: {pi:.3f}') # [logging-format-interpolation]
-renamed_logging.info(f"{local_var_2.upper()}") # [logging-format-interpolation]
-renamed_logging.info(f"{may_14:'%b %d: %Y'}") # [logging-format-interpolation]
+renamed_logging.debug(f'{local_var_1} {local_var_2}') # [logging-fstring-interpolation]
+renamed_logging.log(renamed_logging.DEBUG, f'msg: {local_var_2}') # [logging-fstring-interpolation]
+renamed_logging.log(renamed_logging.DEBUG, f'pi: {pi:.3f}') # [logging-fstring-interpolation]
+renamed_logging.info(f"{local_var_2.upper()}") # [logging-fstring-interpolation]
+renamed_logging.info(f"{may_14:'%b %d: %Y'}") # [logging-fstring-interpolation]
diff --git a/tests/functional/l/logging_fstring_interpolation_py36.txt b/tests/functional/l/logging_fstring_interpolation_py36.txt
index a8c6fd5cd..e0c445c4b 100644
--- a/tests/functional/l/logging_fstring_interpolation_py36.txt
+++ b/tests/functional/l/logging_fstring_interpolation_py36.txt
@@ -1,5 +1,5 @@
-logging-format-interpolation:17::Use % formatting in logging functions and pass the % parameters as arguments
-logging-format-interpolation:18::Use % formatting in logging functions and pass the % parameters as arguments
-logging-format-interpolation:19::Use % formatting in logging functions and pass the % parameters as arguments
-logging-format-interpolation:20::Use % formatting in logging functions and pass the % parameters as arguments
-logging-format-interpolation:21::Use % formatting in logging functions and pass the % parameters as arguments
+logging-fstring-interpolation:17::Use lazy % formatting in logging functions
+logging-fstring-interpolation:18::Use lazy % formatting in logging functions
+logging-fstring-interpolation:19::Use lazy % formatting in logging functions
+logging-fstring-interpolation:20::Use lazy % formatting in logging functions
+logging-fstring-interpolation:21::Use lazy % formatting in logging functions
diff --git a/tests/functional/l/logging_not_lazy.txt b/tests/functional/l/logging_not_lazy.txt
index 31e7cc448..95ef675b2 100644
--- a/tests/functional/l/logging_not_lazy.txt
+++ b/tests/functional/l/logging_not_lazy.txt
@@ -1,6 +1,6 @@
-logging-not-lazy:10::Specify string format arguments as logging function parameters
-logging-not-lazy:11::Specify string format arguments as logging function parameters
-logging-not-lazy:12::Specify string format arguments as logging function parameters
-logging-not-lazy:13::Specify string format arguments as logging function parameters
-logging-not-lazy:14::Specify string format arguments as logging function parameters
-logging-not-lazy:15::Specify string format arguments as logging function parameters
+logging-not-lazy:10::Use lazy % formatting in logging functions
+logging-not-lazy:11::Use lazy % formatting in logging functions
+logging-not-lazy:12::Use lazy % formatting in logging functions
+logging-not-lazy:13::Use lazy % formatting in logging functions
+logging-not-lazy:14::Use lazy % formatting in logging functions
+logging-not-lazy:15::Use lazy % formatting in logging functions
diff --git a/tests/messages/func_bug113231.txt b/tests/messages/func_bug113231.txt
index a9d3f7ef3..f05f16020 100644
--- a/tests/messages/func_bug113231.txt
+++ b/tests/messages/func_bug113231.txt
@@ -1,2 +1,2 @@
-W: 20: Specify string format arguments as logging function parameters
-W: 21: Specify string format arguments as logging function parameters
+W: 20: Use lazy % formatting in logging functions
+W: 21: Use lazy % formatting in logging functions
diff --git a/tests/messages/func_logging_not_lazy_with_logger.txt b/tests/messages/func_logging_not_lazy_with_logger.txt
index 04823cf33..22e7bc6af 100644
--- a/tests/messages/func_logging_not_lazy_with_logger.txt
+++ b/tests/messages/func_logging_not_lazy_with_logger.txt
@@ -1,4 +1,4 @@
-W: 8: Specify string format arguments as logging function parameters
-W: 9: Specify string format arguments as logging function parameters
-W: 11: Specify string format arguments as logging function parameters
-W: 13: Specify string format arguments as logging function parameters
+W: 8: Use lazy % formatting in logging functions
+W: 9: Use lazy % formatting in logging functions
+W: 11: Use lazy % formatting in logging functions
+W: 13: Use lazy % formatting in logging functions
diff --git a/tests/unittest_checker_logging.py b/tests/unittest_checker_logging.py
index 50ba2100f..a025fb6a2 100644
--- a/tests/unittest_checker_logging.py
+++ b/tests/unittest_checker_logging.py
@@ -30,7 +30,7 @@ class TestLoggingModuleDetection(CheckerTestCase):
)
self.checker.visit_module(None)
self.checker.visit_import(stmts[0])
- with self.assertAddsMessages(Message("logging-not-lazy", node=stmts[1])):
+ with self.assertAddsMessages(Message("logging-not-lazy", node=stmts[1], args=("lazy %",))):
self.checker.visit_call(stmts[1])
def test_dont_crash_on_invalid_format_string(self):
@@ -51,7 +51,7 @@ class TestLoggingModuleDetection(CheckerTestCase):
)
self.checker.visit_module(None)
self.checker.visit_import(stmts[0])
- with self.assertAddsMessages(Message("logging-not-lazy", node=stmts[1])):
+ with self.assertAddsMessages(Message("logging-not-lazy", node=stmts[1], args=("lazy %",))):
self.checker.visit_call(stmts[1])
@set_config(logging_modules=["logging", "my.logging"])
@@ -64,7 +64,7 @@ class TestLoggingModuleDetection(CheckerTestCase):
)
self.checker.visit_module(None)
self.checker.visit_import(stmts[0])
- with self.assertAddsMessages(Message("logging-not-lazy", node=stmts[1])):
+ with self.assertAddsMessages(Message("logging-not-lazy", node=stmts[1], args=("lazy %",))):
self.checker.visit_call(stmts[1])
def _assert_logging_format_no_messages(self, stmt):
@@ -140,42 +140,6 @@ class TestLoggingModuleDetection(CheckerTestCase):
@pytest.mark.skipif(sys.version_info < (3, 6), reason="F-string require >=3.6")
@set_config(logging_format_style="new")
def test_fstr_not_new_format_style_matching_arguments(self):
- msg = "logging-format-interpolation"
- args = ("{", "")
+ msg = "logging-fstring-interpolation"
+ args = ("lazy %",)
self._assert_logging_format_message(msg, "(f'{named}')", args)
-
- @set_config(logging_format_style="fstr")
- def test_modulo_not_fstr_format_style_matching_arguments(self):
- msg = "logging-format-interpolation"
- args = ("f-string", "")
- with_too_many = False
- self._assert_logging_format_message(msg, "('%s', 1)", args, with_too_many)
- self._assert_logging_format_message(
- msg, "('%(named)s', {'named': 1})", args, with_too_many
- )
- self._assert_logging_format_message(
- msg, "('%s %(named)s', 1, {'named': 1})", args, with_too_many
- )
-
- @set_config(logging_format_style="fstr")
- def test_brace_not_fstr_format_style_matching_arguments(self):
- msg = "logging-format-interpolation"
- args = ("f-string", "")
- with_too_many = False
- self._assert_logging_format_message(msg, "('{}', 1)", args, with_too_many)
- self._assert_logging_format_message(msg, "('{0}', 1)", args, with_too_many)
- self._assert_logging_format_message(
- msg, "('{named}', {'named': 1})", args, with_too_many
- )
- self._assert_logging_format_message(
- msg, "('{} {named}', 1, {'named': 1})", args, with_too_many
- )
- self._assert_logging_format_message(
- msg, "('{0} {named}', 1, {'named': 1})", args, with_too_many
- )
-
- @pytest.mark.skipif(sys.version_info < (3, 6), reason="F-string require >=3.6")
- @set_config(logging_format_style="fstr")
- def test_fstr_format_style_matching_arguments(self):
- self._assert_logging_format_no_messages("(f'constant string')")
- self._assert_logging_format_no_messages("(f'{named}')")