mirror of
https://github.com/python/cpython.git
synced 2024-12-15 12:54:31 +08:00
Added 'handlers' argument to logging.basicConfig.
This commit is contained in:
parent
98707c2ced
commit
4a0a31df5c
@ -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()
|
||||
|
||||
|
@ -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:
|
||||
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:
|
||||
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')
|
||||
hdlr = FileHandler(filename, mode)
|
||||
h = FileHandler(filename, mode)
|
||||
else:
|
||||
stream = kwargs.get("stream")
|
||||
hdlr = StreamHandler(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)
|
||||
|
@ -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 = []
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user