From: Peeyush Aggarwal Date: Fri, 25 Aug 2023 08:15:26 +0000 (+0530) Subject: gh-103384: Generalize the regex pattern `BaseConfigurator.INDEX_PATTERN` to allow... X-Git-Tag: v3.13.0a1~781 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8d4052075ec43ac1ded7d2fa55c474295410bbdc;p=thirdparty%2FPython%2Fcpython.git gh-103384: Generalize the regex pattern `BaseConfigurator.INDEX_PATTERN` to allow spaces and non-alphanumeric characters in keys. (GH-103391) Co-authored-by: Vinay Sajip Co-authored-by: Alex Waygood Co-authored-by: Erlend E. Aasland --- diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst index 448978f43b6d..53fbd073c267 100644 --- a/Doc/library/logging.config.rst +++ b/Doc/library/logging.config.rst @@ -685,7 +685,8 @@ resolve to ``'dev_team@domain.tld'`` and the string ``'support_team@domain.tld'``. The ``subject`` value could be accessed using either ``'cfg://handlers.email.subject'`` or, equivalently, ``'cfg://handlers.email[subject]'``. The latter form only needs to be -used if the key contains spaces or non-alphanumeric characters. If an +used if the key contains spaces or non-alphanumeric characters. Please note +that the characters ``[`` and ``]`` are not allowed in the keys. If an index value consists only of decimal digits, access will be attempted using the corresponding integer value, falling back to the string value if needed. diff --git a/Lib/logging/config.py b/Lib/logging/config.py index a68281d3e359..41283f4d6272 100644 --- a/Lib/logging/config.py +++ b/Lib/logging/config.py @@ -378,7 +378,7 @@ class BaseConfigurator(object): WORD_PATTERN = re.compile(r'^\s*(\w+)\s*') DOT_PATTERN = re.compile(r'^\.\s*(\w+)\s*') - INDEX_PATTERN = re.compile(r'^\[\s*(\w+)\s*\]\s*') + INDEX_PATTERN = re.compile(r'^\[([^\[\]]*)\]\s*') DIGIT_PATTERN = re.compile(r'^\d+$') value_converters = { diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index f26846f9663e..c2e8ff5d4636 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -3662,7 +3662,28 @@ class ConfigDictTest(BaseTest): d = { 'atuple': (1, 2, 3), 'alist': ['a', 'b', 'c'], - 'adict': {'d': 'e', 'f': 3 }, + 'adict': { + 'd': 'e', 'f': 3 , + 'alpha numeric 1 with spaces' : 5, + 'aplha numeric 1 %( - © ©ß¯' : 9, + 'alpha numeric ] 1 with spaces' : 15, + 'aplha ]] numeric 1 %( - © ©ß¯]' : 19, + ' aplha [ numeric 1 %( - © ©ß¯] ' : 11, + ' aplha ' : 32, + '' : 10, + 'nest4' : { + 'd': 'e', 'f': 3 , + 'alpha numeric 1 with spaces' : 5, + 'aplha numeric 1 %( - © ©ß¯' : 9, + '' : 10, + 'somelist' : ('g', ('h', 'i'), 'j'), + 'somedict' : { + 'a' : 1, + 'a with 1 and space' : 3, + 'a with ( and space' : 4, + } + } + }, 'nest1': ('g', ('h', 'i'), 'j'), 'nest2': ['k', ['l', 'm'], 'n'], 'nest3': ['o', 'cfg://alist', 'p'], @@ -3674,11 +3695,36 @@ class ConfigDictTest(BaseTest): self.assertEqual(bc.convert('cfg://nest2[1][1]'), 'm') self.assertEqual(bc.convert('cfg://adict.d'), 'e') self.assertEqual(bc.convert('cfg://adict[f]'), 3) + self.assertEqual(bc.convert('cfg://adict[alpha numeric 1 with spaces]'), 5) + self.assertEqual(bc.convert('cfg://adict[aplha numeric 1 %( - © ©ß¯]'), 9) + self.assertEqual(bc.convert('cfg://adict[]'), 10) + self.assertEqual(bc.convert('cfg://adict.nest4.d'), 'e') + self.assertEqual(bc.convert('cfg://adict.nest4[d]'), 'e') + self.assertEqual(bc.convert('cfg://adict[nest4].d'), 'e') + self.assertEqual(bc.convert('cfg://adict[nest4][f]'), 3) + self.assertEqual(bc.convert('cfg://adict[nest4][alpha numeric 1 with spaces]'), 5) + self.assertEqual(bc.convert('cfg://adict[nest4][aplha numeric 1 %( - © ©ß¯]'), 9) + self.assertEqual(bc.convert('cfg://adict[nest4][]'), 10) + self.assertEqual(bc.convert('cfg://adict[nest4][somelist][0]'), 'g') + self.assertEqual(bc.convert('cfg://adict[nest4][somelist][1][0]'), 'h') + self.assertEqual(bc.convert('cfg://adict[nest4][somelist][1][1]'), 'i') + self.assertEqual(bc.convert('cfg://adict[nest4][somelist][2]'), 'j') + self.assertEqual(bc.convert('cfg://adict[nest4].somedict.a'), 1) + self.assertEqual(bc.convert('cfg://adict[nest4].somedict[a]'), 1) + self.assertEqual(bc.convert('cfg://adict[nest4].somedict[a with 1 and space]'), 3) + self.assertEqual(bc.convert('cfg://adict[nest4].somedict[a with ( and space]'), 4) + self.assertEqual(bc.convert('cfg://adict.nest4.somelist[1][1]'), 'i') + self.assertEqual(bc.convert('cfg://adict.nest4.somelist[2]'), 'j') + self.assertEqual(bc.convert('cfg://adict.nest4.somedict.a'), 1) + self.assertEqual(bc.convert('cfg://adict.nest4.somedict[a]'), 1) v = bc.convert('cfg://nest3') self.assertEqual(v.pop(1), ['a', 'b', 'c']) self.assertRaises(KeyError, bc.convert, 'cfg://nosuch') self.assertRaises(ValueError, bc.convert, 'cfg://!') self.assertRaises(KeyError, bc.convert, 'cfg://adict[2]') + self.assertRaises(KeyError, bc.convert, 'cfg://adict[alpha numeric ] 1 with spaces]') + self.assertRaises(ValueError, bc.convert, 'cfg://adict[ aplha ]] numeric 1 %( - © ©ß¯] ]') + self.assertRaises(ValueError, bc.convert, 'cfg://adict[ aplha [ numeric 1 %( - © ©ß¯] ]') def test_namedtuple(self): # see bpo-39142 diff --git a/Misc/NEWS.d/next/Library/2023-04-09-05-30-41.gh-issue-103384.zAV7iB.rst b/Misc/NEWS.d/next/Library/2023-04-09-05-30-41.gh-issue-103384.zAV7iB.rst new file mode 100644 index 000000000000..3e9d3cf9ae92 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-04-09-05-30-41.gh-issue-103384.zAV7iB.rst @@ -0,0 +1 @@ +Generalize the regex pattern ``BaseConfigurator.INDEX_PATTERN`` to allow spaces and non-alphanumeric characters in keys.