Skip to content

Commit

Permalink
pythongh-110875: Handle '.' properties in logging formatter configura…
Browse files Browse the repository at this point in the history
…tion c… (pythonGH-110943)
  • Loading branch information
vsajip authored Nov 9, 2023
1 parent 7d21e3d commit a5f29c9
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
8 changes: 4 additions & 4 deletions Lib/logging/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,10 +482,10 @@ def configure_custom(self, config):
c = config.pop('()')
if not callable(c):
c = self.resolve(c)
props = config.pop('.', None)
# 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)
props = config.pop('.', None)
if props:
for name, value in props.items():
setattr(result, name, value)
Expand Down Expand Up @@ -835,8 +835,7 @@ def configure_handler(self, config):
factory = functools.partial(self._configure_queue_handler, klass)
else:
factory = klass
props = config.pop('.', None)
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))}
try:
result = factory(**kwargs)
except TypeError as te:
Expand All @@ -854,6 +853,7 @@ def configure_handler(self, config):
result.setLevel(logging._checkLevel(level))
if filters:
self.add_filters(result, filters)
props = config.pop('.', None)
if props:
for name, value in props.items():
setattr(result, name, value)
Expand Down
38 changes: 37 additions & 1 deletion Lib/test/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -2998,6 +2998,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 = {
"version": 1,
"formatters": {
Expand Down Expand Up @@ -3479,7 +3512,10 @@ def test_config16_ok(self):
{'msg': 'Hello'}))
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):
text = text.encode("utf-8")
Expand Down

0 comments on commit a5f29c9

Please sign in to comment.