]> granicus.if.org Git - python/commitdiff
bpo-33897: Add a 'force' keyword argument to logging.basicConfig(). (GH-7873)
authorDong-hee Na <donghee.na92@gmail.com>
Mon, 25 Jun 2018 04:11:09 +0000 (13:11 +0900)
committerVinay Sajip <vinay_sajip@yahoo.co.uk>
Mon, 25 Jun 2018 04:11:09 +0000 (05:11 +0100)
Doc/library/logging.rst
Lib/logging/__init__.py
Lib/test/test_logging.py
Misc/NEWS.d/next/Library/2018-06-23-18-09-28.bpo-33897.Hu0yvt.rst [new file with mode: 0644]

index 774bd83f41035c15ca4d76d5428b0b6ba4c39d8c..90fe92b501a0eb346d9926dc82780805c601830e 100644 (file)
@@ -1131,7 +1131,7 @@ functions.
    if no handlers are defined for the root logger.
 
    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
       before other threads are started. In versions of Python prior to
@@ -1183,6 +1183,15 @@ functions.
    |              | with 'filename' or 'stream' - if both are   |
    |              | 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
       The ``style`` argument was added.
index e6c9f3280e1024aa21559a4c626da0faff202e6d..29a7d464decf98438f26d7cd56c0cfac0bc424c1 100644 (file)
@@ -1793,7 +1793,8 @@ def basicConfig(**kwargs):
     Do basic configuration for the logging system.
 
     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.
 
     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
               in the list which does not have a formatter assigned will be
               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)
     rather than passing the filename and mode in. However, it should be
     remembered that StreamHandler does not close its stream (since it may be
     using sys.stdout or sys.stderr), whereas FileHandler closes its stream
     when the handler is closed.
 
+    .. versionchanged:: 3.8
+       Added the ``force`` parameter.
+
     .. versionchanged:: 3.2
        Added the ``style`` parameter.
 
@@ -1842,6 +1849,11 @@ def basicConfig(**kwargs):
     # basicConfig() from multiple threads
     _acquireLock()
     try:
+        force = kwargs.pop('force', False)
+        if force:
+            for h in root.handlers[:]:
+                root.removeHandler(h)
+                h.close()
         if len(root.handlers) == 0:
             handlers = kwargs.pop("handlers", None)
             if handlers is None:
index ba70b117d1e69cf208fb2af557788739cbc48373..b3618bd2ad993ac5deff8a7287753e0b8c6bf195 100644 (file)
@@ -3901,6 +3901,27 @@ class BasicConfigTest(unittest.TestCase):
         self.assertIs(handlers[2].formatter, f)
         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):
         # logging.root has no handlers so basicConfig should be called
         called = []
diff --git a/Misc/NEWS.d/next/Library/2018-06-23-18-09-28.bpo-33897.Hu0yvt.rst b/Misc/NEWS.d/next/Library/2018-06-23-18-09-28.bpo-33897.Hu0yvt.rst
new file mode 100644 (file)
index 0000000..64ec3a1
--- /dev/null
@@ -0,0 +1 @@
+Added a 'force' keyword argument to logging.basicConfig().