"""
with _lock:
if hdlr in self.handlers:
- self.handlers.remove(hdlr)
+ # Replace the list instead of mutating it in place, so that
+ # callHandlers() can iterate it without a lock (gh-79366).
+ handlers = self.handlers.copy()
+ handlers.remove(hdlr)
+ self.handlers = handlers
def hasHandlers(self):
"""
support.wait_process(pid, exitcode=0)
+ def test_remove_handler_while_emitting(self):
+ # Removing a handler while callHandlers() iterates over the handlers
+ # should not cause the following handlers to be skipped (gh-79366).
+ logger = logging.Logger('test_remove_handler_while_emitting')
+ calls = []
+ class RemovingHandler(logging.Handler):
+ def emit(self, record):
+ calls.append('removing')
+ logger.removeHandler(self)
+ class CountingHandler(logging.Handler):
+ def emit(self, record):
+ calls.append('counting')
+ logger.addHandler(RemovingHandler())
+ logger.addHandler(CountingHandler())
+ logger.error('spam')
+ self.assertEqual(calls, ['removing', 'counting'])
+
class BadStream(object):
def write(self, data):