From: Jack Danger Date: Thu, 26 Mar 2026 12:41:14 +0000 (-0700) Subject: gh-145650: Add `logging.{Formatter,Filter}.__repr__` (GH-145652) X-Git-Tag: v3.15.0a8~166 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e1d48237973f0257f84cb5682014b38d18f3d76d;p=thirdparty%2FPython%2Fcpython.git gh-145650: Add `logging.{Formatter,Filter}.__repr__` (GH-145652) --- diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 39689a57e6ec..6eef90ae5cd9 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -622,6 +622,9 @@ class Formatter(object): self._fmt = self._style._fmt self.datefmt = datefmt + def __repr__(self): + return '<%s (%s)>' % (self.__class__.__name__, self._fmt) + default_time_format = '%Y-%m-%d %H:%M:%S' default_msec_format = '%s,%03d' @@ -794,6 +797,9 @@ class Filter(object): self.name = name self.nlen = len(name) + def __repr__(self): + return '<%s (%s)>' % (self.__class__.__name__, self.name) + def filter(self, record): """ Determine if the specified record is to be logged. diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 05dcea6ce0e9..1a76c2173a30 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -404,6 +404,20 @@ class BasicFilterTest(BaseTest): r = logging.makeLogRecord({'name': 'spam.eggs'}) self.assertTrue(f.filter(r)) + def test_filter_repr(self): + f = logging.Filter('myapp') + self.assertEqual(repr(f), '') + + def test_filter_repr_empty(self): + f = logging.Filter() + self.assertEqual(repr(f), '') + + def test_filter_repr_subclass(self): + class MyFilter(logging.Filter): + pass + f = MyFilter('myapp') + self.assertEqual(repr(f), '') + # # First, we define our levels. There can be as many as you want - the only # limitations are that they should be integers, the lowest should be > 0 and @@ -4914,6 +4928,20 @@ class FormatterTest(unittest.TestCase, AssertErrorMessage): # After PR gh-102412, precision (places) increases from 3 to 7 self.assertAlmostEqual(relativeCreated, offset_ns / 1e6, places=7) + def test_formatter_repr(self): + f = logging.Formatter('%(message)s') + self.assertEqual(repr(f), '') + + def test_formatter_repr_default(self): + f = logging.Formatter() + self.assertEqual(repr(f), '') + + def test_formatter_repr_subclass(self): + class MyFormatter(logging.Formatter): + pass + f = MyFormatter('%(message)s') + self.assertEqual(repr(f), '') + class TestBufferingFormatter(logging.BufferingFormatter): def formatHeader(self, records): diff --git a/Misc/NEWS.d/next/Library/2026-03-08-00-00-00.gh-issue-145650.LgRepr.rst b/Misc/NEWS.d/next/Library/2026-03-08-00-00-00.gh-issue-145650.LgRepr.rst new file mode 100644 index 000000000000..243834d0bbd5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-08-00-00-00.gh-issue-145650.LgRepr.rst @@ -0,0 +1,3 @@ +Add :meth:`~object.__repr__` support to :class:`logging.Formatter` and +:class:`logging.Filter`, showing the format string and filter name +respectively.