Skip to content

Commit 9eb4b2c

Browse files
miss-islingtonvsajip
authored andcommitted
bpo-37258: Not a bug, but added a unit test and updated documentation. (GH-14229) (GH-14231)
(cherry picked from commit 0150001)
1 parent f532fe5 commit 9eb4b2c

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

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

11961198

11971199
.. function:: setLogRecordFactory(factory)

Lib/test/test_logging.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3877,6 +3877,37 @@ class MyLogger(logging.Logger):
38773877
logging.setLoggerClass(logging.Logger)
38783878
self.assertEqual(logging.getLoggerClass(), logging.Logger)
38793879

3880+
def test_subclass_logger_cache(self):
3881+
# bpo-37258
3882+
message = []
3883+
3884+
class MyLogger(logging.getLoggerClass()):
3885+
def __init__(self, name='MyLogger', level=logging.NOTSET):
3886+
super().__init__(name, level)
3887+
message.append('initialized')
3888+
3889+
logging.setLoggerClass(MyLogger)
3890+
logger = logging.getLogger('just_some_logger')
3891+
self.assertEqual(message, ['initialized'])
3892+
stream = io.StringIO()
3893+
h = logging.StreamHandler(stream)
3894+
logger.addHandler(h)
3895+
try:
3896+
logger.setLevel(logging.DEBUG)
3897+
logger.debug("hello")
3898+
self.assertEqual(stream.getvalue().strip(), "hello")
3899+
3900+
stream.truncate(0)
3901+
stream.seek(0)
3902+
3903+
logger.setLevel(logging.INFO)
3904+
logger.debug("hello")
3905+
self.assertEqual(stream.getvalue(), "")
3906+
finally:
3907+
logger.removeHandler(h)
3908+
h.close()
3909+
logging.setLoggerClass(logging.Logger)
3910+
38803911
@support.requires_type_collecting
38813912
def test_logging_at_shutdown(self):
38823913
# Issue #20037

0 commit comments

Comments
 (0)