mirror of
https://github.com/python/cpython.git
synced 2025-07-25 12:14:38 +00:00
bpo-33897: Add a 'force' keyword argument to logging.basicConfig(). (GH-7873)
This commit is contained in:
parent
2af9f5d334
commit
cf67d6a934
4 changed files with 46 additions and 3 deletions
|
@ -1131,7 +1131,7 @@ functions.
|
||||||
if no handlers are defined for the root logger.
|
if no handlers are defined for the root logger.
|
||||||
|
|
||||||
This function does nothing if the root logger already has handlers
|
This function does nothing if the root logger already has handlers
|
||||||
configured for it.
|
configured, unless the keyword argument *force* is set to ``True``.
|
||||||
|
|
||||||
.. note:: This function should be called from the main thread
|
.. note:: This function should be called from the main thread
|
||||||
before other threads are started. In versions of Python prior to
|
before other threads are started. In versions of Python prior to
|
||||||
|
@ -1183,6 +1183,15 @@ functions.
|
||||||
| | with 'filename' or 'stream' - if both are |
|
| | with 'filename' or 'stream' - if both are |
|
||||||
| | present, a ``ValueError`` is raised. |
|
| | present, a ``ValueError`` is raised. |
|
||||||
+--------------+---------------------------------------------+
|
+--------------+---------------------------------------------+
|
||||||
|
| ``force`` | If this keyword argument is specified as |
|
||||||
|
| | true, any existing handlers attached to the |
|
||||||
|
| | root logger are removed and closed, before |
|
||||||
|
| | carrying out the configuration as specified |
|
||||||
|
| | by the other arguments. |
|
||||||
|
+--------------+---------------------------------------------+
|
||||||
|
|
||||||
|
.. versionchanged:: 3.8
|
||||||
|
The ``force`` argument was added.
|
||||||
|
|
||||||
.. versionchanged:: 3.2
|
.. versionchanged:: 3.2
|
||||||
The ``style`` argument was added.
|
The ``style`` argument was added.
|
||||||
|
|
|
@ -1793,7 +1793,8 @@ def basicConfig(**kwargs):
|
||||||
Do basic configuration for the logging system.
|
Do basic configuration for the logging system.
|
||||||
|
|
||||||
This function does nothing if the root logger already has handlers
|
This function does nothing if the root logger already has handlers
|
||||||
configured. It is a convenience method intended for use by simple scripts
|
configured, unless the keyword argument *force* is set to ``True``.
|
||||||
|
It is a convenience method intended for use by simple scripts
|
||||||
to do one-shot configuration of the logging package.
|
to do one-shot configuration of the logging package.
|
||||||
|
|
||||||
The default behaviour is to create a StreamHandler which writes to
|
The default behaviour is to create a StreamHandler which writes to
|
||||||
|
@ -1821,13 +1822,19 @@ def basicConfig(**kwargs):
|
||||||
handlers, which will be added to the root handler. Any handler
|
handlers, which will be added to the root handler. Any handler
|
||||||
in the list which does not have a formatter assigned will be
|
in the list which does not have a formatter assigned will be
|
||||||
assigned the formatter created in this function.
|
assigned the formatter created in this function.
|
||||||
|
force If this keyword is specified as true, any existing handlers
|
||||||
|
attached to the root logger are removed and closed, before
|
||||||
|
carrying out the configuration as specified by the other
|
||||||
|
arguments.
|
||||||
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
|
||||||
remembered that StreamHandler does not close its stream (since it may be
|
remembered that StreamHandler does not close its stream (since it may be
|
||||||
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.8
|
||||||
|
Added the ``force`` parameter.
|
||||||
|
|
||||||
.. versionchanged:: 3.2
|
.. versionchanged:: 3.2
|
||||||
Added the ``style`` parameter.
|
Added the ``style`` parameter.
|
||||||
|
|
||||||
|
@ -1842,6 +1849,11 @@ def basicConfig(**kwargs):
|
||||||
# basicConfig() from multiple threads
|
# basicConfig() from multiple threads
|
||||||
_acquireLock()
|
_acquireLock()
|
||||||
try:
|
try:
|
||||||
|
force = kwargs.pop('force', False)
|
||||||
|
if force:
|
||||||
|
for h in root.handlers[:]:
|
||||||
|
root.removeHandler(h)
|
||||||
|
h.close()
|
||||||
if len(root.handlers) == 0:
|
if len(root.handlers) == 0:
|
||||||
handlers = kwargs.pop("handlers", None)
|
handlers = kwargs.pop("handlers", None)
|
||||||
if handlers is None:
|
if handlers is None:
|
||||||
|
|
|
@ -3901,6 +3901,27 @@ class BasicConfigTest(unittest.TestCase):
|
||||||
self.assertIs(handlers[2].formatter, f)
|
self.assertIs(handlers[2].formatter, f)
|
||||||
self.assertIs(handlers[0].formatter, handlers[1].formatter)
|
self.assertIs(handlers[0].formatter, handlers[1].formatter)
|
||||||
|
|
||||||
|
def test_force(self):
|
||||||
|
old_string_io = io.StringIO()
|
||||||
|
new_string_io = io.StringIO()
|
||||||
|
old_handlers = [logging.StreamHandler(old_string_io)]
|
||||||
|
new_handlers = [logging.StreamHandler(new_string_io)]
|
||||||
|
logging.basicConfig(level=logging.WARNING, handlers=old_handlers)
|
||||||
|
logging.warning('warn')
|
||||||
|
logging.info('info')
|
||||||
|
logging.debug('debug')
|
||||||
|
self.assertEqual(len(logging.root.handlers), 1)
|
||||||
|
logging.basicConfig(level=logging.INFO, handlers=new_handlers,
|
||||||
|
force=True)
|
||||||
|
logging.warning('warn')
|
||||||
|
logging.info('info')
|
||||||
|
logging.debug('debug')
|
||||||
|
self.assertEqual(len(logging.root.handlers), 1)
|
||||||
|
self.assertEqual(old_string_io.getvalue().strip(),
|
||||||
|
'WARNING:root:warn')
|
||||||
|
self.assertEqual(new_string_io.getvalue().strip(),
|
||||||
|
'WARNING:root:warn\nINFO:root:info')
|
||||||
|
|
||||||
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 = []
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Added a 'force' keyword argument to logging.basicConfig().
|
Loading…
Add table
Add a link
Reference in a new issue