summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinay Sajip <vinay_sajip@yahoo.co.uk>2023-11-09 18:55:22 (GMT)
committerGitHub <noreply@github.com>2023-11-09 18:55:22 (GMT)
commita5f29c9faf046b9ef3e498a0bc63dbc29017b5e3 (patch)
tree9a8586f3b9c25439fb2546f5a81e4a669718de1f
parent7d21e3d5ee9858aee570aa6c5b6a6e87d776f4b5 (diff)
downloadcpython-a5f29c9faf046b9ef3e498a0bc63dbc29017b5e3.zip
cpython-a5f29c9faf046b9ef3e498a0bc63dbc29017b5e3.tar.gz
cpython-a5f29c9faf046b9ef3e498a0bc63dbc29017b5e3.tar.bz2
gh-110875: Handle '.' properties in logging formatter configuration c… (GH-110943)
-rw-r--r--Lib/logging/config.py8
-rw-r--r--Lib/test/test_logging.py38
2 files changed, 41 insertions, 5 deletions
diff --git a/Lib/logging/config.py b/Lib/logging/config.py
index 951bba7..4b520e3 100644
--- a/Lib/logging/config.py
+++ b/Lib/logging/config.py
@@ -482,10 +482,10 @@ class BaseConfigurator(object):
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)
@@ -835,8 +835,7 @@ class DictConfigurator(BaseConfigurator):
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:
@@ -854,6 +853,7 @@ class DictConfigurator(BaseConfigurator):
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)
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index ab969ce..89be432 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -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": {
@@ -3479,7 +3512,10 @@ class ConfigDictTest(BaseTest):
{'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")