gh-134567: Add the formatter parameter in unittest.TestCase.assertLog… · python/cpython@51ab66b · GitHub | Latest TMZ Celebrity News & Gossip | Watch TMZ Live
Skip to content

Commit 51ab66b

Browse files
authored
gh-134567: Add the formatter parameter in unittest.TestCase.assertLogs (GH-134570)
1 parent b19c9da commit 51ab66b

File tree

6 files changed

+42
-5
lines changed

6 files changed

+42
-5
lines changed

Doc/library/unittest.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,7 @@ Test cases
11311131
.. versionchanged:: 3.3
11321132
Added the *msg* keyword argument when used as a context manager.
11331133

1134-
.. method:: assertLogs(logger=None, level=None)
1134+
.. method:: assertLogs(logger=None, level=None, formatter=None)
11351135

11361136
A context manager to test that at least one message is logged on
11371137
the *logger* or one of its children, with at least the given
@@ -1146,6 +1146,10 @@ Test cases
11461146
its string equivalent (for example either ``"ERROR"`` or
11471147
:const:`logging.ERROR`). The default is :const:`logging.INFO`.
11481148

1149+
If given, *formatter* should be a :class:`logging.Formatter` object.
1150+
The default is a formatter with format string
1151+
``"%(levelname)s:%(name)s:%(message)s"``
1152+
11491153
The test passes if at least one message emitted inside the ``with``
11501154
block matches the *logger* and *level* conditions, otherwise it fails.
11511155

@@ -1173,6 +1177,9 @@ Test cases
11731177

11741178
.. versionadded:: 3.4
11751179

1180+
.. versionchanged:: next
1181+
Now accepts a *formatter* to control how messages are formatted.
1182+
11761183
.. method:: assertNoLogs(logger=None, level=None)
11771184

11781185
A context manager to test that no messages are logged on

Doc/whatsnew/3.15.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,15 @@ typing
291291
(Contributed by Bénédikt Tran in :gh:`133823`.)
292292

293293

294+
unittest
295+
--------
296+
297+
* Lets users specify formatter in TestCase.assertLogs.
298+
:func:`unittest.TestCase.assertLogs` will now accept a formatter
299+
to control how messages are formatted.
300+
(Contributed by Garry Cairns in :gh:`134567`.)
301+
302+
294303
wave
295304
----
296305

Lib/test/test_unittest/test_case.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,6 +1920,22 @@ def testAssertLogsUnexpectedException(self):
19201920
with self.assertLogs():
19211921
raise ZeroDivisionError("Unexpected")
19221922

1923+
def testAssertLogsWithFormatter(self):
1924+
# Check alternative formats will be respected
1925+
format = "[No.1: the larch] %(levelname)s:%(name)s:%(message)s"
1926+
formatter = logging.Formatter(format)
1927+
with self.assertNoStderr():
1928+
with self.assertLogs() as cm:
1929+
log_foo.info("1")
1930+
log_foobar.debug("2")
1931+
self.assertEqual(cm.output, ["INFO:foo:1"])
1932+
self.assertLogRecords(cm.records, [{'name': 'foo'}])
1933+
with self.assertLogs(formatter=formatter) as cm:
1934+
log_foo.info("1")
1935+
log_foobar.debug("2")
1936+
self.assertEqual(cm.output, ["[No.1: the larch] INFO:foo:1"])
1937+
self.assertLogRecords(cm.records, [{'name': 'foo'}])
1938+
19231939
def testAssertNoLogsDefault(self):
19241940
with self.assertRaises(self.failureException) as cm:
19251941
with self.assertNoLogs():

Lib/unittest/_log.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class _AssertLogsContext(_BaseTestCaseContext):
3030

3131
LOGGING_FORMAT = "%(levelname)s:%(name)s:%(message)s"
3232

33-
def __init__(self, test_case, logger_name, level, no_logs):
33+
def __init__(self, test_case, logger_name, level, no_logs, formatter=None):
3434
_BaseTestCaseContext.__init__(self, test_case)
3535
self.logger_name = logger_name
3636
if level:
@@ -39,13 +39,14 @@ def __init__(self, test_case, logger_name, level, no_logs):
3939
self.level = logging.INFO
4040
self.msg = None
4141
self.no_logs = no_logs
42+
self.formatter = formatter
4243

4344
def __enter__(self):
4445
if isinstance(self.logger_name, logging.Logger):
4546
logger = self.logger = self.logger_name
4647
else:
4748
logger = self.logger = logging.getLogger(self.logger_name)
48-
formatter = logging.Formatter(self.LOGGING_FORMAT)
49+
formatter = self.formatter or logging.Formatter(self.LOGGING_FORMAT)
4950
handler = _CapturingHandler()
5051
handler.setLevel(self.level)
5152
handler.setFormatter(formatter)

Lib/unittest/case.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,7 @@ def _assertNotWarns(self, expected_warning, *args, **kwargs):
849849
context = _AssertNotWarnsContext(expected_warning, self)
850850
return context.handle('_assertNotWarns', args, kwargs)
851851

852-
def assertLogs(self, logger=None, level=None):
852+
def assertLogs(self, logger=None, level=None, formatter=None):
853853
"""Fail unless a log message of level *level* or higher is emitted
854854
on *logger_name* or its children. If omitted, *level* defaults to
855855
INFO and *logger* defaults to the root logger.
@@ -861,6 +861,8 @@ def assertLogs(self, logger=None, level=None):
861861
`records` attribute will be a list of the corresponding LogRecord
862862
objects.
863863
864+
Optionally supply `formatter` to control how messages are formatted.
865+
864866
Example::
865867
866868
with self.assertLogs('foo', level='INFO') as cm:
@@ -871,7 +873,7 @@ def assertLogs(self, logger=None, level=None):
871873
"""
872874
# Lazy import to avoid importing logging if it is not needed.
873875
from ._log import _AssertLogsContext
874-
return _AssertLogsContext(self, logger, level, no_logs=False)
876+
return _AssertLogsContext(self, logger, level, no_logs=False, formatter=formatter)
875877

876878
def assertNoLogs(self, logger=None, level=None):
877879
""" Fail unless no log messages of level *level* or higher are emitted
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Expose log formatter to users in TestCase.assertLogs.
2+
:func:`unittest.TestCase.assertLogs` will now optionally accept a formatter that will be used to format the strings in output if provided.

0 commit comments

Comments
 (0)

TMZ Celebrity News – Breaking Stories, Videos & Gossip

Looking for the latest TMZ celebrity news? You've come to the right place. From shocking Hollywood scandals to exclusive videos, TMZ delivers it all in real time.

Whether it’s a red carpet slip-up, a viral paparazzi moment, or a legal drama involving your favorite stars, TMZ news is always first to break the story. Stay in the loop with daily updates, insider tips, and jaw-dropping photos.

🎥 Watch TMZ Live

TMZ Live brings you daily celebrity news and interviews straight from the TMZ newsroom. Don’t miss a beat—watch now and see what’s trending in Hollywood.