mirror of https://github.com/python/cpython
Issue #17508: Handled out-of-order handler configuration correctly.
This commit is contained in:
parent
d5537d071c
commit
3f885b5432
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2001-2010 by Vinay Sajip. All Rights Reserved.
|
||||
# Copyright 2001-2013 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,
|
||||
|
@ -19,7 +19,7 @@ Configuration functions for the logging package for Python. The core package
|
|||
is based on PEP 282 and comments thereto in comp.lang.python, and influenced
|
||||
by Apache's log4j system.
|
||||
|
||||
Copyright (C) 2001-2010 Vinay Sajip. All Rights Reserved.
|
||||
Copyright (C) 2001-2013 Vinay Sajip. All Rights Reserved.
|
||||
|
||||
To use, simply 'import logging' and log away!
|
||||
"""
|
||||
|
@ -564,7 +564,21 @@ class DictConfigurator(BaseConfigurator):
|
|||
# As handlers can refer to other handlers, sort the keys
|
||||
# to allow a deterministic order of configuration
|
||||
handlers = config.get('handlers', EMPTY_DICT)
|
||||
deferred = []
|
||||
for name in sorted(handlers):
|
||||
try:
|
||||
handler = self.configure_handler(handlers[name])
|
||||
handler.name = name
|
||||
handlers[name] = handler
|
||||
except Exception as e:
|
||||
if 'target not configured yet' in str(e):
|
||||
deferred.append(name)
|
||||
else:
|
||||
raise ValueError('Unable to configure handler '
|
||||
'%r: %s' % (name, e))
|
||||
|
||||
# Now do any that were deferred
|
||||
for name in deferred:
|
||||
try:
|
||||
handler = self.configure_handler(handlers[name])
|
||||
handler.name = name
|
||||
|
@ -572,6 +586,7 @@ class DictConfigurator(BaseConfigurator):
|
|||
except Exception as e:
|
||||
raise ValueError('Unable to configure handler '
|
||||
'%r: %s' % (name, e))
|
||||
|
||||
# Next, do loggers - they refer to handlers and filters
|
||||
|
||||
#we don't want to lose the existing loggers,
|
||||
|
@ -694,12 +709,17 @@ class DictConfigurator(BaseConfigurator):
|
|||
c = self.resolve(c)
|
||||
factory = c
|
||||
else:
|
||||
klass = self.resolve(config.pop('class'))
|
||||
cname = config.pop('class')
|
||||
klass = self.resolve(cname)
|
||||
#Special case for handler which refers to another handler
|
||||
if issubclass(klass, logging.handlers.MemoryHandler) and\
|
||||
'target' in config:
|
||||
try:
|
||||
config['target'] = self.config['handlers'][config['target']]
|
||||
th = self.config['handlers'][config['target']]
|
||||
if not isinstance(th, logging.Handler):
|
||||
config['class'] = cname # restore for deferred configuration
|
||||
raise TypeError('target not configured yet')
|
||||
config['target'] = th
|
||||
except Exception as e:
|
||||
raise ValueError('Unable to set target handler '
|
||||
'%r: %s' % (config['target'], e))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2012 by Vinay Sajip. All Rights Reserved.
|
||||
# Copyright 2001-2013 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,
|
||||
|
@ -18,7 +18,7 @@
|
|||
|
||||
"""Test harness for the logging module. Run all tests.
|
||||
|
||||
Copyright (C) 2001-2012 Vinay Sajip. All Rights Reserved.
|
||||
Copyright (C) 2001-2013 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
@ -1696,6 +1696,36 @@ class ConfigDictTest(BaseTest):
|
|||
},
|
||||
}
|
||||
|
||||
out_of_order = {
|
||||
"version": 1,
|
||||
"formatters": {
|
||||
"mySimpleFormatter": {
|
||||
"format": "%(asctime)s (%(name)s) %(levelname)s: %(message)s"
|
||||
}
|
||||
},
|
||||
"handlers": {
|
||||
"fileGlobal": {
|
||||
"class": "logging.StreamHandler",
|
||||
"level": "DEBUG",
|
||||
"formatter": "mySimpleFormatter"
|
||||
},
|
||||
"bufferGlobal": {
|
||||
"class": "logging.handlers.MemoryHandler",
|
||||
"capacity": 5,
|
||||
"formatter": "mySimpleFormatter",
|
||||
"target": "fileGlobal",
|
||||
"level": "DEBUG"
|
||||
}
|
||||
},
|
||||
"loggers": {
|
||||
"mymodule": {
|
||||
"level": "DEBUG",
|
||||
"handlers": ["bufferGlobal"],
|
||||
"propagate": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def apply_config(self, conf):
|
||||
logging.config.dictConfig(conf)
|
||||
|
||||
|
@ -1994,6 +2024,10 @@ class ConfigDictTest(BaseTest):
|
|||
# Original logger output is empty.
|
||||
self.assert_log_lines([])
|
||||
|
||||
def test_out_of_order(self):
|
||||
self.apply_config(self.out_of_order)
|
||||
handler = logging.getLogger('mymodule').handlers[0]
|
||||
self.assertIsInstance(handler.target, logging.Handler)
|
||||
|
||||
class ManagerTest(BaseTest):
|
||||
def test_manager_loggerclass(self):
|
||||
|
|
Loading…
Reference in New Issue