]> granicus.if.org Git - python/commitdiff
bpo-30520: Implemented pickling for loggers. (#1956)
authorVinay Sajip <vinay_sajip@yahoo.co.uk>
Tue, 6 Jun 2017 15:34:29 +0000 (16:34 +0100)
committerGitHub <noreply@github.com>
Tue, 6 Jun 2017 15:34:29 +0000 (16:34 +0100)
Implemented pickling for loggers.

Doc/library/logging.rst
Lib/logging/__init__.py
Lib/test/test_logging.py
Misc/NEWS

index 63059ac20d82c282b097206b3fec89fe7bce430e..1b27241f6f97478636de6fe940daf93fb687b133 100644 (file)
@@ -323,6 +323,8 @@ is the module's name in the Python package namespace.
 
       .. versionadded:: 3.2
 
+   .. versionchanged:: 3.7
+      Loggers can now be picked and unpickled.
 
 .. _levels:
 
index 49203838a99796ec597f6dd078b1864abec17cb1..64e24eef50e75afa783d280f9b53edabcb47a4d7 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved.
+# Copyright 2001-2017 by Vinay Sajip. All Rights Reserved.
 #
 # Permission to use, copy, modify, and distribute this software and its
 # documentation for any purpose and without fee is hereby granted,
@@ -18,7 +18,7 @@
 Logging package for Python. Based on PEP 282 and comments thereto in
 comp.lang.python.
 
-Copyright (C) 2001-2016 Vinay Sajip. All Rights Reserved.
+Copyright (C) 2001-2017 Vinay Sajip. All Rights Reserved.
 
 To use, simply 'import logging' and log away!
 """
@@ -1570,6 +1570,14 @@ class Logger(Filterer):
         level = getLevelName(self.getEffectiveLevel())
         return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level)
 
+    def __reduce__(self):
+        # In general, only the root logger will not be accessible via its name.
+        # However, the root logger's class has its own __reduce__ method.
+        if getLogger(self.name) is not self:
+            import pickle
+            raise pickle.PicklingError('logger cannot be pickled')
+        return getLogger, (self.name,)
+
 
 class RootLogger(Logger):
     """
@@ -1583,6 +1591,9 @@ class RootLogger(Logger):
         """
         Logger.__init__(self, "root", level)
 
+    def __reduce__(self):
+        return getLogger, ()
+
 _loggerClass = Logger
 
 class LoggerAdapter(object):
index ed25d3e920737365c878a28e24004a048d98e644..880f4e89fb03b5157ebbbc4d9fd3d64a732b6ee5 100644 (file)
@@ -4086,6 +4086,14 @@ class LoggerTest(BaseTest):
         self.assertRaises(TypeError, logging.getLogger, any)
         self.assertRaises(TypeError, logging.getLogger, b'foo')
 
+    def test_pickling(self):
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            for name in ('', 'root', 'foo', 'foo.bar', 'baz.bar'):
+                logger = logging.getLogger(name)
+                s = pickle.dumps(logger, proto)
+                unpickled = pickle.loads(s)
+                self.assertIs(unpickled, logger)
+
 
 class BaseFileTest(BaseTest):
     "Base class for handler tests that write log files"
index 1b5794b44f1c0c57df96e449a6024edbd43c0ad4..4b0879bee296eca6aa5b870598cf6a71a5923421 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -345,6 +345,8 @@ Extension Modules
 Library
 -------
 
+- bpo-30520: Loggers are now pickleable.
+
 - bpo-30557: faulthandler now correctly filters and displays exception codes
   on Windows
 
@@ -353,7 +355,7 @@ Library
 
 - bpo-30245: Fix possible overflow when organize struct.pack_into
   error message.  Patch by Yuan Liu.
-  
+
 - bpo-30378: Fix the problem that logging.handlers.SysLogHandler cannot
   handle IPv6 addresses.