summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinay Sajip <vinay_sajip@yahoo.co.uk>2011-04-11 07:42:07 (GMT)
committerVinay Sajip <vinay_sajip@yahoo.co.uk>2011-04-11 07:42:07 (GMT)
commit4a0a31df5c6ab79dd7dc8ee828379dca1d1f632f (patch)
tree0246d7ef13a693a1194cbed38f1df9697f720735
parent98707c2cede1aa697a1338ea8f7c9a59da42dfe9 (diff)
downloadcpython-4a0a31df5c6ab79dd7dc8ee828379dca1d1f632f.zip
cpython-4a0a31df5c6ab79dd7dc8ee828379dca1d1f632f.tar.gz
cpython-4a0a31df5c6ab79dd7dc8ee828379dca1d1f632f.tar.bz2
Added 'handlers' argument to logging.basicConfig.
-rw-r--r--Doc/library/logging.rst17
-rw-r--r--Lib/logging/__init__.py42
-rw-r--r--Lib/test/test_logging.py20
-rw-r--r--Misc/NEWS4
4 files changed, 73 insertions, 10 deletions
diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst
index 32f762d..eb2c718 100644
--- a/Doc/library/logging.rst
+++ b/Doc/library/logging.rst
@@ -983,12 +983,27 @@ functions.
| ``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
index 7757a82..ef88d0a 100644
--- a/Lib/logging/__init__.py
+++ b/Lib/logging/__init__.py
@@ -1650,6 +1650,10 @@ def basicConfig(**kwargs):
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 @@ def basicConfig(**kwargs):
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
index 18222ea..88f0ebc 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -2482,6 +2482,26 @@ class BasicConfigTest(unittest.TestCase):
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
index 8df6f4b..d02a22e 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -103,6 +103,10 @@ Core and Builtins
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