mirror of
https://github.com/python/cpython.git
synced 2025-08-11 12:29:34 +00:00
[3.12] gh-110875: Handle '.' properties in logging formatter configuration c… (GH-110943) (GH-111911)
Co-authored-by: Vinay Sajip <vinay_sajip@yahoo.co.uk>
This commit is contained in:
parent
fe7631e558
commit
09df271965
2 changed files with 41 additions and 5 deletions
|
@ -485,10 +485,10 @@ class BaseConfigurator(object):
|
||||||
c = config.pop('()')
|
c = config.pop('()')
|
||||||
if not callable(c):
|
if not callable(c):
|
||||||
c = self.resolve(c)
|
c = self.resolve(c)
|
||||||
props = config.pop('.', None)
|
|
||||||
# Check for valid identifiers
|
# Check for valid identifiers
|
||||||
kwargs = {k: config[k] for k in config if valid_ident(k)}
|
kwargs = {k: config[k] for k in config if (k != '.' and valid_ident(k))}
|
||||||
result = c(**kwargs)
|
result = c(**kwargs)
|
||||||
|
props = config.pop('.', None)
|
||||||
if props:
|
if props:
|
||||||
for name, value in props.items():
|
for name, value in props.items():
|
||||||
setattr(result, name, value)
|
setattr(result, name, value)
|
||||||
|
@ -841,8 +841,7 @@ class DictConfigurator(BaseConfigurator):
|
||||||
factory = functools.partial(self._configure_queue_handler, klass)
|
factory = functools.partial(self._configure_queue_handler, klass)
|
||||||
else:
|
else:
|
||||||
factory = klass
|
factory = klass
|
||||||
props = config.pop('.', None)
|
kwargs = {k: config[k] for k in config if (k != '.' and valid_ident(k))}
|
||||||
kwargs = {k: config[k] for k in config if valid_ident(k)}
|
|
||||||
try:
|
try:
|
||||||
result = factory(**kwargs)
|
result = factory(**kwargs)
|
||||||
except TypeError as te:
|
except TypeError as te:
|
||||||
|
@ -860,6 +859,7 @@ class DictConfigurator(BaseConfigurator):
|
||||||
result.setLevel(logging._checkLevel(level))
|
result.setLevel(logging._checkLevel(level))
|
||||||
if filters:
|
if filters:
|
||||||
self.add_filters(result, filters)
|
self.add_filters(result, filters)
|
||||||
|
props = config.pop('.', None)
|
||||||
if props:
|
if props:
|
||||||
for name, value in props.items():
|
for name, value in props.items():
|
||||||
setattr(result, name, value)
|
setattr(result, name, value)
|
||||||
|
|
|
@ -3014,6 +3014,39 @@ class ConfigDictTest(BaseTest):
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CustomFormatter(logging.Formatter):
|
||||||
|
custom_property = "."
|
||||||
|
|
||||||
|
def format(self, record):
|
||||||
|
return super().format(record)
|
||||||
|
|
||||||
|
config17 = {
|
||||||
|
'version': 1,
|
||||||
|
'formatters': {
|
||||||
|
"custom": {
|
||||||
|
"()": CustomFormatter,
|
||||||
|
"style": "{",
|
||||||
|
"datefmt": "%Y-%m-%d %H:%M:%S",
|
||||||
|
"format": "{message}", # <-- to force an exception when configuring
|
||||||
|
".": {
|
||||||
|
"custom_property": "value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'handlers' : {
|
||||||
|
'hand1' : {
|
||||||
|
'class' : 'logging.StreamHandler',
|
||||||
|
'formatter' : 'custom',
|
||||||
|
'level' : 'NOTSET',
|
||||||
|
'stream' : 'ext://sys.stdout',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'root' : {
|
||||||
|
'level' : 'WARNING',
|
||||||
|
'handlers' : ['hand1'],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
bad_format = {
|
bad_format = {
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"formatters": {
|
"formatters": {
|
||||||
|
@ -3495,7 +3528,10 @@ class ConfigDictTest(BaseTest):
|
||||||
{'msg': 'Hello'}))
|
{'msg': 'Hello'}))
|
||||||
self.assertEqual(result, 'Hello ++ defaultvalue')
|
self.assertEqual(result, 'Hello ++ defaultvalue')
|
||||||
|
|
||||||
|
def test_config17_ok(self):
|
||||||
|
self.apply_config(self.config17)
|
||||||
|
h = logging._handlers['hand1']
|
||||||
|
self.assertEqual(h.formatter.custom_property, 'value')
|
||||||
|
|
||||||
def setup_via_listener(self, text, verify=None):
|
def setup_via_listener(self, text, verify=None):
|
||||||
text = text.encode("utf-8")
|
text = text.encode("utf-8")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue