Skip to content

Commit 732c3a3

Browse files
vsajiplisroach
authored andcommitted
bpo-37258: Not a bug, but added a unit test and updated documentation. (pythonGH-14229)
1 parent 29b7e52 commit 732c3a3

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

Doc/library/logging.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ listed below.
5050
Logger Objects
5151
--------------
5252

53-
Loggers have the following attributes and methods. Note that Loggers are never
54-
instantiated directly, but always through the module-level function
53+
Loggers have the following attributes and methods. Note that Loggers should
54+
*NEVER* be instantiated directly, but always through the module-level function
5555
``logging.getLogger(name)``. Multiple calls to :func:`getLogger` with the same
5656
name will always return a reference to the same Logger object.
5757

@@ -1244,7 +1244,9 @@ functions.
12441244
The class should define :meth:`__init__` such that only a name argument is
12451245
required, and the :meth:`__init__` should call :meth:`Logger.__init__`. This
12461246
function is typically called before any loggers are instantiated by applications
1247-
which need to use custom logger behavior.
1247+
which need to use custom logger behavior. After this call, as at any other
1248+
time, do not instantiate loggers directly using the subclass: continue to use
1249+
the :func:`logging.getLogger` API to get your loggers.
12481250

12491251

12501252
.. function:: setLogRecordFactory(factory)

Lib/test/test_logging.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4172,6 +4172,37 @@ class MyLogger(logging.Logger):
41724172
logging.setLoggerClass(logging.Logger)
41734173
self.assertEqual(logging.getLoggerClass(), logging.Logger)
41744174

4175+
def test_subclass_logger_cache(self):
4176+
# bpo-37258
4177+
message = []
4178+
4179+
class MyLogger(logging.getLoggerClass()):
4180+
def __init__(self, name='MyLogger', level=logging.NOTSET):
4181+
super().__init__(name, level)
4182+
message.append('initialized')
4183+
4184+
logging.setLoggerClass(MyLogger)
4185+
logger = logging.getLogger('just_some_logger')
4186+
self.assertEqual(message, ['initialized'])
4187+
stream = io.StringIO()
4188+
h = logging.StreamHandler(stream)
4189+
logger.addHandler(h)
4190+
try:
4191+
logger.setLevel(logging.DEBUG)
4192+
logger.debug("hello")
4193+
self.assertEqual(stream.getvalue().strip(), "hello")
4194+
4195+
stream.truncate(0)
4196+
stream.seek(0)
4197+
4198+
logger.setLevel(logging.INFO)
4199+
logger.debug("hello")
4200+
self.assertEqual(stream.getvalue(), "")
4201+
finally:
4202+
logger.removeHandler(h)
4203+
h.close()
4204+
logging.setLoggerClass(logging.Logger)
4205+
41754206
@support.requires_type_collecting
41764207
def test_logging_at_shutdown(self):
41774208
# Issue #20037

0 commit comments

Comments
 (0)