]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-110875: Handle '.' properties in logging formatter configuration c… (GH...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 9 Nov 2023 19:34:10 +0000 (20:34 +0100)
committerGitHub <noreply@github.com>
Thu, 9 Nov 2023 19:34:10 +0000 (19:34 +0000)
Co-authored-by: Vinay Sajip <vinay_sajip@yahoo.co.uk>
Lib/logging/config.py
Lib/test/test_logging.py

index a68281d3e359fd5649cf3b948b35e4f7c31998b0..8eae263a500453015d77d5cd09bcd23d35fc33c9 100644 (file)
@@ -485,10 +485,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)
@@ -841,8 +841,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:
@@ -860,6 +859,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)
index a2300daff9c735bd7c9ecba662b6182dc57f5184..fdae35b5dff3541c41931babdf31fcbe71a162dd 100644 (file)
@@ -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 = {
         "version": 1,
         "formatters": {
@@ -3495,7 +3528,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")