FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-134567: Exposes log format to users in unittest.TestCase.assertLogs by garry-cairns · Pull Request #134570 · python/cpython · GitHub

Repository navigation

Merged
9 changes: 8 additions & 1 deletion Doc/library/unittest.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1131,7 +1131,7 @@ Test cases
.. versionchanged:: 3.3
Added the *msg* keyword argument when used as a context manager.

.. method:: assertLogs(logger=None, level=None)
.. method:: assertLogs(logger=None, level=None, formatter=None)

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

If given, *formatter* should be a :class:`logging.Formatter` object.
The default is a formatter with format string
``"%(levelname)s:%(name)s:%(message)s"``

The test passes if at least one message emitted inside the ``with``
block matches the *logger* and *level* conditions, otherwise it fails.

Expand Down Expand Up @@ -1173,6 +1177,9 @@ Test cases

.. versionadded:: 3.4

.. versionchanged:: next
Now accepts a *formatter* to control how messages are formatted.

.. method:: assertNoLogs(logger=None, level=None)

A context manager to test that no messages are logged on
Expand Down
9 changes: 9 additions & 0 deletions Doc/whatsnew/3.15.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,15 @@ typing
(Contributed by Bénédikt Tran in :gh:`133823`.)


unittest
--------

* Lets users specify formatter in TestCase.assertLogs.
:func:`unittest.TestCase.assertLogs` will now accept a formatter
to control how messages are formatted.
(Contributed by Garry Cairns in :gh:`134567`.)
Comment on lines +294 to +300

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

@garry-cairns This is under the "Removed" section:

https://docs.python.org/3.15/whatsnew/3.15.html#removed

Please could you move it to the "Improved modules" section above?

https://docs.python.org/3.15/whatsnew/3.15.html#improved-modules

(We could also remove the first sentence "Lets users specify formatter in TestCase.assertLogs", as the next sentence essentially repeats it.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Apologies for the noise on this. I've created #136630 to resolve this.



wave
----

Expand Down
16 changes: 16 additions & 0 deletions Lib/test/test_unittest/test_case.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1920,6 +1920,22 @@ def testAssertLogsUnexpectedException(self):
with self.assertLogs():
raise ZeroDivisionError("Unexpected")

def testAssertLogsWithFormatter(self):
# Check alternative formats will be respected
format = "[No.1: the larch] %(levelname)s:%(name)s:%(message)s"
formatter = logging.Formatter(format)
with self.assertNoStderr():
with self.assertLogs() as cm:
log_foo.info("1")
log_foobar.debug("2")
self.assertEqual(cm.output, ["INFO:foo:1"])
self.assertLogRecords(cm.records, [{'name': 'foo'}])
with self.assertLogs(formatter=formatter) as cm:
log_foo.info("1")
log_foobar.debug("2")
self.assertEqual(cm.output, ["[No.1: the larch] INFO:foo:1"])
self.assertLogRecords(cm.records, [{'name': 'foo'}])

def testAssertNoLogsDefault(self):
with self.assertRaises(self.failureException) as cm:
with self.assertNoLogs():
Expand Down
5 changes: 3 additions & 2 deletions Lib/unittest/_log.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class _AssertLogsContext(_BaseTestCaseContext):

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

def __init__(self, test_case, logger_name, level, no_logs):
def __init__(self, test_case, logger_name, level, no_logs, formatter=None):
_BaseTestCaseContext.__init__(self, test_case)
self.logger_name = logger_name
if level:
Expand All @@ -39,13 +39,14 @@ def __init__(self, test_case, logger_name, level, no_logs):
self.level = logging.INFO
self.msg = None
self.no_logs = no_logs
self.formatter = formatter

def __enter__(self):
if isinstance(self.logger_name, logging.Logger):
logger = self.logger = self.logger_name
else:
logger = self.logger = logging.getLogger(self.logger_name)
formatter = logging.Formatter(self.LOGGING_FORMAT)
formatter = self.formatter or logging.Formatter(self.LOGGING_FORMAT)
handler = _CapturingHandler()
handler.setLevel(self.level)
handler.setFormatter(formatter)
Expand Down
6 changes: 4 additions & 2 deletions Lib/unittest/case.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ def _assertNotWarns(self, expected_warning, *args, **kwargs):
context = _AssertNotWarnsContext(expected_warning, self)
return context.handle('_assertNotWarns', args, kwargs)

def assertLogs(self, logger=None, level=None):
def assertLogs(self, logger=None, level=None, formatter=None):
"""Fail unless a log message of level *level* or higher is emitted
on *logger_name* or its children. If omitted, *level* defaults to
INFO and *logger* defaults to the root logger.
Expand All @@ -861,6 +861,8 @@ def assertLogs(self, logger=None, level=None):
`records` attribute will be a list of the corresponding LogRecord
objects.

Optionally supply `formatter` to control how messages are formatted.

Example::

with self.assertLogs('foo', level='INFO') as cm:
Expand All @@ -871,7 +873,7 @@ def assertLogs(self, logger=None, level=None):
"""
# Lazy import to avoid importing logging if it is not needed.
from ._log import _AssertLogsContext
return _AssertLogsContext(self, logger, level, no_logs=False)
return _AssertLogsContext(self, logger, level, no_logs=False, formatter=formatter)

def assertNoLogs(self, logger=None, level=None):
""" Fail unless no log messages of level *level* or higher are emitted
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Expose log formatter to users in TestCase.assertLogs.
:func:`unittest.TestCase.assertLogs` will now optionally accept a formatter that will be used to format the strings in output if provided.

Back | FazBrowse Home | New Git URL