Added 'handlers' argument to logging.basicConfig.

This commit is contained in:
Vinay Sajip 2011-04-11 08:42:07 +01:00
parent 98707c2ced
commit 4a0a31df5c
4 changed files with 73 additions and 10 deletions

View File

@ -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()

View File

@ -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)

View File

@ -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 = []

View File

@ -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