Closes #17508: Merged fix from 3.3.
This commit is contained in:
commit
5a63fe6813
|
@ -1,4 +1,4 @@
|
||||||
# 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
|
# Permission to use, copy, modify, and distribute this software and its
|
||||||
# documentation for any purpose and without fee is hereby granted,
|
# 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
|
is based on PEP 282 and comments thereto in comp.lang.python, and influenced
|
||||||
by Apache's log4j system.
|
by Apache's log4j system.
|
||||||
|
|
||||||
Copyright (C) 2001-2012 Vinay Sajip. All Rights Reserved.
|
Copyright (C) 2001-2013 Vinay Sajip. All Rights Reserved.
|
||||||
|
|
||||||
To use, simply 'import logging' and log away!
|
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
|
# As handlers can refer to other handlers, sort the keys
|
||||||
# to allow a deterministic order of configuration
|
# to allow a deterministic order of configuration
|
||||||
handlers = config.get('handlers', EMPTY_DICT)
|
handlers = config.get('handlers', EMPTY_DICT)
|
||||||
|
deferred = []
|
||||||
for name in sorted(handlers):
|
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:
|
try:
|
||||||
handler = self.configure_handler(handlers[name])
|
handler = self.configure_handler(handlers[name])
|
||||||
handler.name = name
|
handler.name = name
|
||||||
|
@ -572,6 +586,7 @@ class DictConfigurator(BaseConfigurator):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ValueError('Unable to configure handler '
|
raise ValueError('Unable to configure handler '
|
||||||
'%r: %s' % (name, e))
|
'%r: %s' % (name, e))
|
||||||
|
|
||||||
# Next, do loggers - they refer to handlers and filters
|
# Next, do loggers - they refer to handlers and filters
|
||||||
|
|
||||||
#we don't want to lose the existing loggers,
|
#we don't want to lose the existing loggers,
|
||||||
|
@ -694,12 +709,17 @@ class DictConfigurator(BaseConfigurator):
|
||||||
c = self.resolve(c)
|
c = self.resolve(c)
|
||||||
factory = c
|
factory = c
|
||||||
else:
|
else:
|
||||||
klass = self.resolve(config.pop('class'))
|
cname = config.pop('class')
|
||||||
|
klass = self.resolve(cname)
|
||||||
#Special case for handler which refers to another handler
|
#Special case for handler which refers to another handler
|
||||||
if issubclass(klass, logging.handlers.MemoryHandler) and\
|
if issubclass(klass, logging.handlers.MemoryHandler) and\
|
||||||
'target' in config:
|
'target' in config:
|
||||||
try:
|
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:
|
except Exception as e:
|
||||||
raise ValueError('Unable to set target handler '
|
raise ValueError('Unable to set target handler '
|
||||||
'%r: %s' % (config['target'], e))
|
'%r: %s' % (config['target'], e))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env python
|
#!/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
|
# Permission to use, copy, modify, and distribute this software and its
|
||||||
# documentation for any purpose and without fee is hereby granted,
|
# documentation for any purpose and without fee is hereby granted,
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
"""Test harness for the logging module. Run all tests.
|
"""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
|
import logging
|
||||||
|
@ -2415,6 +2415,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):
|
def apply_config(self, conf):
|
||||||
logging.config.dictConfig(conf)
|
logging.config.dictConfig(conf)
|
||||||
|
|
||||||
|
@ -2787,6 +2817,11 @@ class ConfigDictTest(BaseTest):
|
||||||
('ERROR', '2'),
|
('ERROR', '2'),
|
||||||
], pat=r"^[\w.]+ -> (\w+): (\d+)$")
|
], pat=r"^[\w.]+ -> (\w+): (\d+)$")
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
def test_baseconfig(self):
|
def test_baseconfig(self):
|
||||||
d = {
|
d = {
|
||||||
'atuple': (1, 2, 3),
|
'atuple': (1, 2, 3),
|
||||||
|
|
Loading…
Reference in New Issue