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 |
|
| ``stream`` | Use the specified stream to initialize the |
|
||||||
| | StreamHandler. Note that this argument is |
|
| | StreamHandler. Note that this argument is |
|
||||||
| | incompatible with 'filename' - if both are |
|
| | 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
|
.. versionchanged:: 3.2
|
||||||
The ``style`` argument was added.
|
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()
|
.. function:: shutdown()
|
||||||
|
|
||||||
|
@ -1650,6 +1650,10 @@ def basicConfig(**kwargs):
|
|||||||
stream Use the specified stream to initialize the StreamHandler. Note
|
stream Use the specified stream to initialize the StreamHandler. Note
|
||||||
that this argument is incompatible with 'filename' - if both
|
that this argument is incompatible with 'filename' - if both
|
||||||
are present, 'stream' is ignored.
|
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)
|
Note that you could specify a stream created using open(filename, mode)
|
||||||
rather than passing the filename and mode in. However, it should be
|
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
|
using sys.stdout or sys.stderr), whereas FileHandler closes its stream
|
||||||
when the handler is closed.
|
when the handler is closed.
|
||||||
|
|
||||||
.. versionchanged: 3.2
|
.. versionchanged:: 3.2
|
||||||
Added the ``style`` parameter.
|
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
|
# Add thread safety in case someone mistakenly calls
|
||||||
# basicConfig() from multiple threads
|
# basicConfig() from multiple threads
|
||||||
_acquireLock()
|
_acquireLock()
|
||||||
try:
|
try:
|
||||||
if len(root.handlers) == 0:
|
if len(root.handlers) == 0:
|
||||||
filename = kwargs.get("filename")
|
handlers = kwargs.get("handlers")
|
||||||
if filename:
|
if handlers is None:
|
||||||
mode = kwargs.get("filemode", 'a')
|
if "stream" in kwargs and "filename" in kwargs:
|
||||||
hdlr = FileHandler(filename, mode)
|
raise ValueError("'stream' and 'filename' should not be "
|
||||||
|
"specified together")
|
||||||
else:
|
else:
|
||||||
stream = kwargs.get("stream")
|
if "stream" in kwargs or "filename" in kwargs:
|
||||||
hdlr = StreamHandler(stream)
|
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)
|
fs = kwargs.get("format", BASIC_FORMAT)
|
||||||
dfs = kwargs.get("datefmt", None)
|
dfs = kwargs.get("datefmt", None)
|
||||||
style = kwargs.get("style", '%')
|
style = kwargs.get("style", '%')
|
||||||
fmt = Formatter(fs, dfs, style)
|
fmt = Formatter(fs, dfs, style)
|
||||||
hdlr.setFormatter(fmt)
|
for h in handlers:
|
||||||
root.addHandler(hdlr)
|
if h.formatter is None:
|
||||||
|
h.setFormatter(fmt)
|
||||||
|
root.addHandler(h)
|
||||||
level = kwargs.get("level")
|
level = kwargs.get("level")
|
||||||
if level is not None:
|
if level is not None:
|
||||||
root.setLevel(level)
|
root.setLevel(level)
|
||||||
|
@ -2482,6 +2482,26 @@ class BasicConfigTest(unittest.TestCase):
|
|||||||
logging.basicConfig(level=57)
|
logging.basicConfig(level=57)
|
||||||
self.assertEqual(logging.root.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):
|
def _test_log(self, method, level=None):
|
||||||
# logging.root has no handlers so basicConfig should be called
|
# logging.root has no handlers so basicConfig should be called
|
||||||
called = []
|
called = []
|
||||||
|
@ -103,6 +103,10 @@ Core and Builtins
|
|||||||
Library
|
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 #11814: Fix likely typo in multiprocessing.Pool._terminate().
|
||||||
|
|
||||||
- Issue #8428: Fix a race condition in multiprocessing.Pool when terminating
|
- Issue #8428: Fix a race condition in multiprocessing.Pool when terminating
|
||||||
|
Loading…
Reference in New Issue
Block a user