[Python-checkins] cpython: Added 'handlers' argument to logging.basicConfig.

vinay.sajip python-checkins at python.org
Mon Apr 11 09:44:03 CEST 2011


http://hg.python.org/cpython/rev/fbf5e4b1e52a
changeset:   69248:fbf5e4b1e52a
user:        Vinay Sajip <vinay_sajip at yahoo.co.uk>
date:        Mon Apr 11 08:42:07 2011 +0100
summary:
  Added 'handlers' argument to logging.basicConfig.

files:
  Doc/library/logging.rst  |  17 ++++++++++-
  Lib/logging/__init__.py  |  42 ++++++++++++++++++++++------
  Lib/test/test_logging.py |  20 +++++++++++++
  Misc/NEWS                |   4 ++
  4 files changed, 73 insertions(+), 10 deletions(-)


diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst
--- a/Doc/library/logging.rst
+++ b/Doc/library/logging.rst
@@ -983,12 +983,27 @@
    | ``stream``   | Use the specified stream to initialize the  |
    |              | StreamHandler. Note that this argument is   |
    |              | incompatible with 'filename' - if both are  |
-   |              | present, 'stream' is ignored.               |
+   |              | present, a ``ValueError`` is raised.        |
+   +--------------+---------------------------------------------+
+   | ``handlers`` | If specified, this should be an iterable of |
+   |              | already created handlers to add to the root |
+   |              | logger. Any handlers which don't already    |
+   |              | have a formatter set will be assigned the   |
+   |              | default formatter created in this function. |
+   |              | Note that this argument is incompatible     |
+   |              | with 'filename' or 'stream' - if both are   |
+   |              | present, a ``ValueError`` is raised.        |
    +--------------+---------------------------------------------+
 
    .. versionchanged:: 3.2
       The ``style`` argument was added.
 
+   .. versionchanged:: 3.3
+      The ``handlers`` argument was added. Additional checks were added to
+      catch situations where incompatible arguments are specified (e.g.
+      ``handlers`` together with ``stream`` or ``filename``, or ``stream``
+      together with ``filename``).
+
 
 .. function:: shutdown()
 
diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py
--- a/Lib/logging/__init__.py
+++ b/Lib/logging/__init__.py
@@ -1650,6 +1650,10 @@
     stream    Use the specified stream to initialize the StreamHandler. Note
               that this argument is incompatible with 'filename' - if both
               are present, 'stream' is ignored.
+    handlers  If specified, this should be an iterable of already created
+              handlers, which will be added to the root handler. Any handler
+              in the list which does not have a formatter assigned will be
+              assigned the formatter created in this function.
 
     Note that you could specify a stream created using open(filename, mode)
     rather than passing the filename and mode in. However, it should be
@@ -1657,27 +1661,47 @@
     using sys.stdout or sys.stderr), whereas FileHandler closes its stream
     when the handler is closed.
 
-    .. versionchanged: 3.2
+    .. versionchanged:: 3.2
        Added the ``style`` parameter.
+       
+    .. versionchanged:: 3.3
+       Added the ``handlers`` parameter. A ``ValueError`` is now thrown for
+       incompatible arguments (e.g. ``handlers`` specified together with
+       ``filename``/``filemode``, or ``filename``/``filemode`` specified
+       together with ``stream``, or ``handlers`` specified together with
+       ``stream``.
     """
     # Add thread safety in case someone mistakenly calls
     # basicConfig() from multiple threads
     _acquireLock()
     try:
         if len(root.handlers) == 0:
-            filename = kwargs.get("filename")
-            if filename:
-                mode = kwargs.get("filemode", 'a')
-                hdlr = FileHandler(filename, mode)
+            handlers = kwargs.get("handlers")
+            if handlers is None:
+                if "stream" in kwargs and "filename" in kwargs:
+                    raise ValueError("'stream' and 'filename' should not be "
+                                     "specified together")
             else:
-                stream = kwargs.get("stream")
-                hdlr = StreamHandler(stream)
+                if "stream" in kwargs or "filename" in kwargs:
+                    raise ValueError("'stream' or 'filename' should not be "
+                                     "specified together with 'handlers'")
+            if handlers is None:
+                filename = kwargs.get("filename")
+                if filename:
+                    mode = kwargs.get("filemode", 'a')
+                    h = FileHandler(filename, mode)
+                else:
+                    stream = kwargs.get("stream")
+                    h = StreamHandler(stream)
+                handlers = [h]
             fs = kwargs.get("format", BASIC_FORMAT)
             dfs = kwargs.get("datefmt", None)
             style = kwargs.get("style", '%')
             fmt = Formatter(fs, dfs, style)
-            hdlr.setFormatter(fmt)
-            root.addHandler(hdlr)
+            for h in handlers:
+                if h.formatter is None:
+                    h.setFormatter(fmt)
+                root.addHandler(h)
             level = kwargs.get("level")
             if level is not None:
                 root.setLevel(level)
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -2482,6 +2482,26 @@
         logging.basicConfig(level=57)
         self.assertEqual(logging.root.level, 57)
 
+    def test_incompatible(self):
+        assertRaises = self.assertRaises
+        handlers = [logging.StreamHandler()]
+        stream = sys.stderr
+        assertRaises(ValueError, logging.basicConfig, filename='test.log',
+                                                     stream=stream)
+        assertRaises(ValueError, logging.basicConfig, filename='test.log',
+                                                     handlers=handlers)
+        assertRaises(ValueError, logging.basicConfig, stream=stream,
+                                                     handlers=handlers)
+
+    def test_handlers(self):
+        handlers = [logging.StreamHandler(), logging.StreamHandler(sys.stdout)]
+        logging.basicConfig(handlers=handlers)
+        self.assertIs(handlers[0], logging.root.handlers[0])
+        self.assertIs(handlers[1], logging.root.handlers[1])
+        self.assertIsNotNone(handlers[0].formatter)
+        self.assertIsNotNone(handlers[1].formatter)
+        self.assertIs(handlers[0].formatter, handlers[1].formatter)
+
     def _test_log(self, method, level=None):
         # logging.root has no handlers so basicConfig should be called
         called = []
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -103,6 +103,10 @@
 Library
 -------
 
+- logging.basicConfig now supports an optional 'handlers' argument taking an
+  iterable of handlers to be added to the root logger. Additional parameter
+  checks were also added to basicConfig.
+
 - Issue #11814: Fix likely typo in multiprocessing.Pool._terminate().
 
 - Issue #8428: Fix a race condition in multiprocessing.Pool when terminating

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list