gh-111615: Fix regression in QueueHandler configuration. (GH-111638)

This commit is contained in:
Vinay Sajip 2023-12-27 09:35:15 +00:00 committed by GitHub
parent 00cdd416fc
commit 67655d8ad5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 17 deletions

View file

@ -1,4 +1,4 @@
# Copyright 2001-2022 by Vinay Sajip. All Rights Reserved.
# Copyright 2001-2023 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
@ -734,7 +734,7 @@ def _configure_queue_handler(self, klass, **kwargs):
lklass = kwargs['listener']
else:
lklass = logging.handlers.QueueListener
listener = lklass(q, *kwargs['handlers'], respect_handler_level=rhl)
listener = lklass(q, *kwargs.get('handlers', []), respect_handler_level=rhl)
handler = klass(q)
handler.listener = listener
return handler
@ -776,11 +776,12 @@ def configure_handler(self, config):
raise ValueError('Unable to set target handler %r' % tn) from e
elif issubclass(klass, logging.handlers.QueueHandler):
# Another special case for handler which refers to other handlers
if 'handlers' not in config:
raise ValueError('No handlers specified for a QueueHandler')
# if 'handlers' not in config:
# raise ValueError('No handlers specified for a QueueHandler')
if 'queue' in config:
from multiprocessing.queues import Queue as MPQueue
qspec = config['queue']
if not isinstance(qspec, queue.Queue):
if not isinstance(qspec, (queue.Queue, MPQueue)):
if isinstance(qspec, str):
q = self.resolve(qspec)
if not callable(q):
@ -813,18 +814,19 @@ def configure_handler(self, config):
if not callable(listener):
raise TypeError('Invalid listener specifier %r' % lspec)
config['listener'] = listener
hlist = []
try:
for hn in config['handlers']:
h = self.config['handlers'][hn]
if not isinstance(h, logging.Handler):
config.update(config_copy) # restore for deferred cfg
raise TypeError('Required handler %r '
'is not configured yet' % hn)
hlist.append(h)
except Exception as e:
raise ValueError('Unable to set required handler %r' % hn) from e
config['handlers'] = hlist
if 'handlers' in config:
hlist = []
try:
for hn in config['handlers']:
h = self.config['handlers'][hn]
if not isinstance(h, logging.Handler):
config.update(config_copy) # restore for deferred cfg
raise TypeError('Required handler %r '
'is not configured yet' % hn)
hlist.append(h)
except Exception as e:
raise ValueError('Unable to set required handler %r' % hn) from e
config['handlers'] = hlist
elif issubclass(klass, logging.handlers.SMTPHandler) and\
'mailhost' in config:
config['mailhost'] = self.as_tuple(config['mailhost'])

View file

@ -3922,6 +3922,25 @@ def test_90195(self):
# Logger should be enabled, since explicitly mentioned
self.assertFalse(logger.disabled)
def test_111615(self):
# See gh-111615
import multiprocessing as mp
config = {
'version': 1,
'handlers': {
'sink': {
'class': 'logging.handlers.QueueHandler',
'queue': mp.get_context('spawn').Queue(),
},
},
'root': {
'handlers': ['sink'],
'level': 'DEBUG',
},
}
logging.config.dictConfig(config)
class ManagerTest(BaseTest):
def test_manager_loggerclass(self):
logged = []

View file

@ -0,0 +1,2 @@
Fix a regression caused by a fix to gh-93162 whereby you couldn't configure
a :class:`QueueHandler` without specifying handlers.