mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
gh-132106: Allow logging.handlers.QueueListener
to be used as a context manager (#132107)
This commit is contained in:
parent
ad3bbe8fbc
commit
517e96b9ed
6 changed files with 54 additions and 6 deletions
|
@ -626,6 +626,19 @@ which, when run, will produce:
|
|||
of each message with the handler's level, and only passes a message to a
|
||||
handler if it's appropriate to do so.
|
||||
|
||||
.. versionchanged:: next
|
||||
The :class:`QueueListener` can be started (and stopped) via the
|
||||
:keyword:`with` statement. For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
with QueueListener(que, handler) as listener:
|
||||
# The queue listener automatically starts
|
||||
# when the 'with' block is entered.
|
||||
pass
|
||||
# The queue listener automatically stops once
|
||||
# the 'with' block is exited.
|
||||
|
||||
.. _network-logging:
|
||||
|
||||
Sending and receiving logging events across a network
|
||||
|
|
|
@ -1148,6 +1148,13 @@ possible, while any potentially slow operations (such as sending an email via
|
|||
.. versionchanged:: 3.5
|
||||
The ``respect_handler_level`` argument was added.
|
||||
|
||||
.. versionchanged:: next
|
||||
:class:`QueueListener` can now be used as a context manager via
|
||||
:keyword:`with`. When entering the context, the listener is started. When
|
||||
exiting the context, the listener is stopped.
|
||||
:meth:`~contextmanager.__enter__` returns the
|
||||
:class:`QueueListener` object.
|
||||
|
||||
.. method:: dequeue(block)
|
||||
|
||||
Dequeues a record and return it, optionally blocking.
|
||||
|
|
|
@ -812,6 +812,14 @@ linecache
|
|||
(Contributed by Tian Gao in :gh:`131638`.)
|
||||
|
||||
|
||||
logging.handlers
|
||||
----------------
|
||||
|
||||
* :class:`logging.handlers.QueueListener` now implements the context
|
||||
manager protocol, allowing it to be used in a :keyword:`with` statement.
|
||||
(Contributed by Charles Machalow in :gh:`132106`.)
|
||||
|
||||
|
||||
mimetypes
|
||||
---------
|
||||
|
||||
|
|
|
@ -1532,6 +1532,19 @@ class QueueListener(object):
|
|||
self._thread = None
|
||||
self.respect_handler_level = respect_handler_level
|
||||
|
||||
def __enter__(self):
|
||||
"""
|
||||
For use as a context manager. Starts the listener.
|
||||
"""
|
||||
self.start()
|
||||
return self
|
||||
|
||||
def __exit__(self, *args):
|
||||
"""
|
||||
For use as a context manager. Stops the listener.
|
||||
"""
|
||||
self.stop()
|
||||
|
||||
def dequeue(self, block):
|
||||
"""
|
||||
Dequeue a record and return it, optionally blocking.
|
||||
|
|
|
@ -4311,8 +4311,6 @@ class QueueHandlerTest(BaseTest):
|
|||
self.assertEqual(formatted_msg, log_record.msg)
|
||||
self.assertEqual(formatted_msg, log_record.message)
|
||||
|
||||
@unittest.skipUnless(hasattr(logging.handlers, 'QueueListener'),
|
||||
'logging.handlers.QueueListener required for this test')
|
||||
def test_queue_listener(self):
|
||||
handler = TestHandler(support.Matcher())
|
||||
listener = logging.handlers.QueueListener(self.queue, handler)
|
||||
|
@ -4347,8 +4345,17 @@ class QueueHandlerTest(BaseTest):
|
|||
self.assertTrue(handler.matches(levelno=logging.CRITICAL, message='6'))
|
||||
handler.close()
|
||||
|
||||
@unittest.skipUnless(hasattr(logging.handlers, 'QueueListener'),
|
||||
'logging.handlers.QueueListener required for this test')
|
||||
def test_queue_listener_context_manager(self):
|
||||
handler = TestHandler(support.Matcher())
|
||||
with logging.handlers.QueueListener(self.queue, handler) as listener:
|
||||
self.assertIsInstance(listener, logging.handlers.QueueListener)
|
||||
self.assertIsNotNone(listener._thread)
|
||||
self.assertIsNone(listener._thread)
|
||||
|
||||
# doesn't hurt to call stop() more than once.
|
||||
listener.stop()
|
||||
self.assertIsNone(listener._thread)
|
||||
|
||||
def test_queue_listener_with_StreamHandler(self):
|
||||
# Test that traceback and stack-info only appends once (bpo-34334, bpo-46755).
|
||||
listener = logging.handlers.QueueListener(self.queue, self.root_hdlr)
|
||||
|
@ -4363,8 +4370,6 @@ class QueueHandlerTest(BaseTest):
|
|||
self.assertEqual(self.stream.getvalue().strip().count('Traceback'), 1)
|
||||
self.assertEqual(self.stream.getvalue().strip().count('Stack'), 1)
|
||||
|
||||
@unittest.skipUnless(hasattr(logging.handlers, 'QueueListener'),
|
||||
'logging.handlers.QueueListener required for this test')
|
||||
def test_queue_listener_with_multiple_handlers(self):
|
||||
# Test that queue handler format doesn't affect other handler formats (bpo-35726).
|
||||
self.que_hdlr.setFormatter(self.root_formatter)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
:class:`logging.handlers.QueueListener` now implements the context
|
||||
manager protocol, allowing it to be used in a :keyword:`with` statement.
|
Loading…
Add table
Add a link
Reference in a new issue