From ab038ba5a47c94d48a126223b58ab1ddb365e0b5 Mon Sep 17 00:00:00 2001 From: Harry Kwon Date: Fri, 15 Aug 2025 14:29:52 +0900 Subject: [PATCH 1/2] add tests for current formatter behavior on exc_text --- Lib/test/test_logging.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 275f7ce47d09b5..1dc627ff0b5c76 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -4570,6 +4570,9 @@ def setUp(self): self.variants = { 'custom': { 'custom': 1234 + }, + 'exception': { + 'exc_info': ZeroDivisionError() } } @@ -4909,6 +4912,20 @@ def test_relativeCreated_has_higher_precision(self): # After PR gh-102412, precision (places) increases from 3 to 7 self.assertAlmostEqual(relativeCreated, offset_ns / 1e6, places=7) + def test_multiple_formatters_exc_text(self): + # Regression test for current behavior where exc_text is only set if it is None + r = self.get_record() + r.exc_info = (ZeroDivisionError, ZeroDivisionError(), None) + + f = logging.Formatter('${%(message)s}') + f.format(r) + self.assertIsNotNone(r.exc_text) + exc_text = r.exc_text + + f = logging.Formatter('%(asctime)s') + f.format(r) + self.assertEqual(exc_text, r.exc_text) + class TestBufferingFormatter(logging.BufferingFormatter): def formatHeader(self, records): @@ -5010,7 +5027,6 @@ def inner(): class RecordingHandler(logging.NullHandler): - def __init__(self, *args, **kwargs): super(RecordingHandler, self).__init__(*args, **kwargs) self.records = [] From 1f468f129c67ff02d2a7a295b47128964f3ee7e8 Mon Sep 17 00:00:00 2001 From: Harry Kwon Date: Fri, 15 Aug 2025 14:32:21 +0900 Subject: [PATCH 2/2] Add test for proposed override behavior --- Lib/test/test_logging.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 1dc627ff0b5c76..95f0f2494aca7e 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -4926,6 +4926,20 @@ def test_multiple_formatters_exc_text(self): f.format(r) self.assertEqual(exc_text, r.exc_text) + def test_multiple_formatters_set_exc_text(self): + # Tests that exc_text is changed when set_exc_text option is set on the Formatter + r = self.get_record() + r.exc_info = (ZeroDivisionError, ZeroDivisionError(), None) + + f = logging.Formatter('${%(message)s}') + f.format(r) + self.assertIsNotNone(r.exc_text) + exc_text = r.exc_text + + f = logging.Formatter('%(asctime)s', set_exc_text=True) + f.format(r) + self.assertNotEqual(exc_text, r.exc_text) + class TestBufferingFormatter(logging.BufferingFormatter): def formatHeader(self, records):