diff options
author | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2023-11-09 19:51:43 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-09 19:51:43 (GMT) |
commit | 078cdccc2ae343ed66cfc044c8150575f8d6cf94 (patch) | |
tree | 16c8937672a4e67b0b19a85ab2c1c60f4c27aa97 | |
parent | 316221c23ff1b8acfe5c51298373464191c7d47f (diff) | |
download | cpython-078cdccc2ae343ed66cfc044c8150575f8d6cf94.zip cpython-078cdccc2ae343ed66cfc044c8150575f8d6cf94.tar.gz cpython-078cdccc2ae343ed66cfc044c8150575f8d6cf94.tar.bz2 |
[3.11] gh-110875: Handle '.' properties in logging formatter configuration correctly. (GH-110943) (GH-111914)
Co-authored-by: Vinay Sajip <vinay_sajip@yahoo.co.uk>
-rw-r--r-- | Lib/logging/config.py | 12 | ||||
-rw-r--r-- | Lib/test/test_logging.py | 42 |
2 files changed, 46 insertions, 8 deletions
diff --git a/Lib/logging/config.py b/Lib/logging/config.py index 7e78a64..735ffbe 100644 --- a/Lib/logging/config.py +++ b/Lib/logging/config.py @@ -1,4 +1,4 @@ -# Copyright 2001-2019 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2023 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # 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 by Apache's log4j system. -Copyright (C) 2001-2019 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2023 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ @@ -477,10 +477,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) @@ -752,8 +752,7 @@ class DictConfigurator(BaseConfigurator): 'address' in config: config['address'] = self.as_tuple(config['address']) 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: @@ -771,6 +770,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 e097acd..757cdc7 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1,4 +1,4 @@ -# Copyright 2001-2022 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2023 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -16,7 +16,7 @@ """Test harness for the logging module. Run all tests. -Copyright (C) 2001-2022 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2023 Vinay Sajip. All Rights Reserved. """ import logging @@ -2881,6 +2881,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'], + }, + } + out_of_order = { "version": 1, "formatters": { @@ -3295,6 +3328,11 @@ class ConfigDictTest(BaseTest): handler = logging.root.handlers[0] self.addCleanup(cleanup, handler, fn) + 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") # Ask for a randomly assigned port (by using port 0) |