Skip to content

Commit 6260d9f

Browse files
authored
bpo-30520: Implemented pickling for loggers. (#1956)
Implemented pickling for loggers.
1 parent b87c0df commit 6260d9f

4 files changed

Lines changed: 26 additions & 3 deletions

File tree

Doc/library/logging.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ is the module's name in the Python package namespace.
323323

324324
.. versionadded:: 3.2
325325

326+
.. versionchanged:: 3.7
327+
Loggers can now be picked and unpickled.
326328

327329
.. _levels:
328330

Lib/logging/__init__.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved.
1+
# Copyright 2001-2017 by Vinay Sajip. All Rights Reserved.
22
#
33
# Permission to use, copy, modify, and distribute this software and its
44
# documentation for any purpose and without fee is hereby granted,
@@ -18,7 +18,7 @@
1818
Logging package for Python. Based on PEP 282 and comments thereto in
1919
comp.lang.python.
2020
21-
Copyright (C) 2001-2016 Vinay Sajip. All Rights Reserved.
21+
Copyright (C) 2001-2017 Vinay Sajip. All Rights Reserved.
2222
2323
To use, simply 'import logging' and log away!
2424
"""
@@ -1570,6 +1570,14 @@ def __repr__(self):
15701570
level = getLevelName(self.getEffectiveLevel())
15711571
return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level)
15721572

1573+
def __reduce__(self):
1574+
# In general, only the root logger will not be accessible via its name.
1575+
# However, the root logger's class has its own __reduce__ method.
1576+
if getLogger(self.name) is not self:
1577+
import pickle
1578+
raise pickle.PicklingError('logger cannot be pickled')
1579+
return getLogger, (self.name,)
1580+
15731581

15741582
class RootLogger(Logger):
15751583
"""
@@ -1583,6 +1591,9 @@ def __init__(self, level):
15831591
"""
15841592
Logger.__init__(self, "root", level)
15851593

1594+
def __reduce__(self):
1595+
return getLogger, ()
1596+
15861597
_loggerClass = Logger
15871598

15881599
class LoggerAdapter(object):

Lib/test/test_logging.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4086,6 +4086,14 @@ def test_invalid_names(self):
40864086
self.assertRaises(TypeError, logging.getLogger, any)
40874087
self.assertRaises(TypeError, logging.getLogger, b'foo')
40884088

4089+
def test_pickling(self):
4090+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
4091+
for name in ('', 'root', 'foo', 'foo.bar', 'baz.bar'):
4092+
logger = logging.getLogger(name)
4093+
s = pickle.dumps(logger, proto)
4094+
unpickled = pickle.loads(s)
4095+
self.assertIs(unpickled, logger)
4096+
40894097

40904098
class BaseFileTest(BaseTest):
40914099
"Base class for handler tests that write log files"

Misc/NEWS

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,8 @@ Extension Modules
345345
Library
346346
-------
347347

348+
- bpo-30520: Loggers are now pickleable.
349+
348350
- bpo-30557: faulthandler now correctly filters and displays exception codes
349351
on Windows
350352

@@ -353,7 +355,7 @@ Library
353355

354356
- bpo-30245: Fix possible overflow when organize struct.pack_into
355357
error message. Patch by Yuan Liu.
356-
358+
357359
- bpo-30378: Fix the problem that logging.handlers.SysLogHandler cannot
358360
handle IPv6 addresses.
359361

0 commit comments

Comments
 (0)