bpo-30522: Implemented a method to allow setting a logging.StreamHander's stream...
authorVinay Sajip <vinay_sajip@yahoo.co.uk>
Sun, 30 Jul 2017 09:41:45 +0000 (10:41 +0100)
committerGitHub <noreply@github.com>
Sun, 30 Jul 2017 09:41:45 +0000 (10:41 +0100)
Doc/library/logging.handlers.rst
Lib/logging/__init__.py
Lib/test/test_logging.py
Misc/NEWS.d/next/Library/2017-07-30-10-07-58.bpo-30522.gAX1N-.rst [new file with mode: 0644]

index f13f765c019374cbab1bf3dd900bcd0b2c7d518c..0974286e55dc10b3e048f0a98bfb503302dabbeb 100644 (file)
@@ -59,6 +59,18 @@ and :meth:`flush` methods).
       :meth:`close` method is inherited from :class:`~logging.Handler` and so
       does no output, so an explicit :meth:`flush` call may be needed at times.
 
+   .. method:: setStream(stream)
+
+      Sets the instance's stream to the specified value, if it is different.
+      The old stream is flushed before the new stream is set.
+
+      :param stream: The stream that the handler should use.
+
+      :return: the old stream, if the stream was changed, or *None* if it wasn't.
+
+   .. versionadded:: 3.7
+
+
 .. versionchanged:: 3.2
    The ``StreamHandler`` class now has a ``terminator`` attribute, default
    value ``'\n'``, which is used as the terminator when writing a formatted
@@ -66,6 +78,7 @@ and :meth:`flush` methods).
    set the handler instance's ``terminator`` attribute to the empty string.
    In earlier versions, the terminator was hardcoded as ``'\n'``.
 
+
 .. _file-handler:
 
 FileHandler
index f9bfb79ae66b8088afa79c888540fad714387725..54d4e883d973cf66750251c7955583c82d7eeb30 100644 (file)
@@ -997,6 +997,26 @@ class StreamHandler(Handler):
         except Exception:
             self.handleError(record)
 
+    def setStream(self, stream):
+        """
+        Sets the StreamHandler's stream to the specified value,
+        if it is different.
+
+        Returns the old stream, if the stream was changed, or None
+        if it wasn't.
+        """
+        if stream is self.stream:
+            result = None
+        else:
+            result = self.stream
+            self.acquire()
+            try:
+                self.flush()
+                self.stream = stream
+            finally:
+                self.release()
+        return result
+
     def __repr__(self):
         level = getLevelName(self.level)
         name = getattr(self.stream, 'name', '')
index 88845629614a3e692c941c90ba9ef009427d8d0a..6d0b23441ba71d44ea12a481d3b096d41bf8445a 100644 (file)
@@ -698,6 +698,20 @@ class StreamHandlerTest(BaseTest):
         finally:
             logging.raiseExceptions = old_raise
 
+    def test_stream_setting(self):
+        """
+        Test setting the handler's stream
+        """
+        h = logging.StreamHandler()
+        stream = io.StringIO()
+        old = h.setStream(stream)
+        self.assertIs(old, sys.stderr)
+        actual = h.setStream(old)
+        self.assertIs(actual, stream)
+        # test that setting to existing value returns None
+        actual = h.setStream(old)
+        self.assertIsNone(actual)
+
 # -- The following section could be moved into a server_helper.py module
 # -- if it proves to be of wider utility than just test_logging
 
diff --git a/Misc/NEWS.d/next/Library/2017-07-30-10-07-58.bpo-30522.gAX1N-.rst b/Misc/NEWS.d/next/Library/2017-07-30-10-07-58.bpo-30522.gAX1N-.rst
new file mode 100644 (file)
index 0000000..214f98e
--- /dev/null
@@ -0,0 +1,2 @@
+Added a ``setStream`` method to ``logging.StreamHandler`` to allow the
+stream to be set after creation.