summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2020-03-21 19:39:22 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2020-03-21 19:48:55 +0900
commit6f60864d03d3744c7cf8906c8808a3c8f17117f1 (patch)
treec2dba5f08981b12741543c9221342bfc8828074c
parent0c45776c07583ca237a134f176d9be2e0aa7043f (diff)
downloadsphinx-git-6f60864d03d3744c7cf8906c8808a3c8f17117f1.tar.gz
Add "once" option to logger.warning()
-rw-r--r--sphinx/util/logging.py23
-rw-r--r--tests/test_util_logging.py11
2 files changed, 33 insertions, 1 deletions
diff --git a/sphinx/util/logging.py b/sphinx/util/logging.py
index 6827fd5cd..fbf161ec0 100644
--- a/sphinx/util/logging.py
+++ b/sphinx/util/logging.py
@@ -118,7 +118,7 @@ class SphinxWarningLogRecord(SphinxLogRecord):
class SphinxLoggerAdapter(logging.LoggerAdapter):
"""LoggerAdapter allowing ``type`` and ``subtype`` keywords."""
- KEYWORDS = ['type', 'subtype', 'location', 'nonl', 'color']
+ KEYWORDS = ['type', 'subtype', 'location', 'nonl', 'color', 'once']
def log(self, level: Union[int, str], msg: str, *args: Any, **kwargs: Any) -> None:
if isinstance(level, int):
@@ -440,6 +440,26 @@ class MessagePrefixFilter(logging.Filter):
return True
+class OnceFilter(logging.Filter):
+ """Show the message only once."""
+
+ def __init__(self, name: str = '') -> None:
+ super().__init__(name)
+ self.messages = {} # type: Dict[str, List]
+
+ def filter(self, record: logging.LogRecord) -> bool:
+ once = getattr(record, 'once', '')
+ if not once:
+ return True
+ else:
+ params = self.messages.setdefault(record.msg, [])
+ if record.args in params:
+ return False
+
+ params.append(record.args)
+ return True
+
+
class SphinxLogRecordTranslator(logging.Filter):
"""Converts a log record to one Sphinx expects
@@ -557,6 +577,7 @@ def setup(app: "Sphinx", status: IO, warning: IO) -> None:
warning_handler.addFilter(WarningSuppressor(app))
warning_handler.addFilter(WarningLogRecordTranslator(app))
warning_handler.addFilter(WarningIsErrorFilter(app))
+ warning_handler.addFilter(OnceFilter())
warning_handler.setLevel(logging.WARNING)
warning_handler.setFormatter(ColorizeFormatter())
diff --git a/tests/test_util_logging.py b/tests/test_util_logging.py
index 85646112d..337782d87 100644
--- a/tests/test_util_logging.py
+++ b/tests/test_util_logging.py
@@ -103,6 +103,17 @@ def test_nonl_info_log(app, status, warning):
assert 'message1message2\nmessage3' in status.getvalue()
+def test_once_warning_log(app, status, warning):
+ logging.setup(app, status, warning)
+ logger = logging.getLogger(__name__)
+
+ logger.warning('message: %d', 1, once=True)
+ logger.warning('message: %d', 1, once=True)
+ logger.warning('message: %d', 2, once=True)
+
+ assert 'WARNING: message: 1\nWARNING: message: 2\n' in strip_escseq(warning.getvalue())
+
+
def test_is_suppressed_warning():
suppress_warnings = ["ref", "files.*", "rest.duplicated_labels"]