From cbe0eafea1f9b3c41a56f2cb00470dda8faa1bb6 Mon Sep 17 00:00:00 2001 From: cherith <315844584+Cherith1222@users.noreply.github.com> Date: Mon, 19 Oct 2026 05:04:06 +0800 Subject: [PATCH 1/2] Show that subscript strings are extracted as messages. --- tests/messages/test_extract_python.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/messages/test_extract_python.py b/tests/messages/test_extract_python.py index be1cf970f..0c649bd01 100644 --- a/tests/messages/test_extract_python.py +++ b/tests/messages/test_extract_python.py @@ -505,3 +505,26 @@ def test_nested_messages(): assert messages[6][3] == [] assert messages[7][2] == 'Armin' assert messages[7][3] == [] + + +def test_strings_inside_subscripts_and_literals_are_not_messages(): + buf = BytesIO(b"""\ +pgettext(context, dictionary["key"]) +_(foo["a"], "b") +_({"a": "b"}) +_(["a", "b"]) +_(dictionary[_("inner")]) +pgettext("navigation", "Guide") +_("hello" "world") +""") + messages = list(extract.extract_python(buf, extract.DEFAULT_KEYWORDS, [], {})) + assert messages == [ + (1, 'pgettext', (None, None), []), + (2, '_', (None, 'b'), []), + (3, '_', None, []), + (4, '_', None, []), + (5, '_', None, []), + (5, '_', 'inner', []), + (6, 'pgettext', ('navigation', 'Guide'), []), + (7, '_', 'helloworld', []), + ] From 983e93726bb4fbebfac7f5b35bca7f204f430b07 Mon Sep 17 00:00:00 2001 From: cherith <315844584+Cherith1222@users.noreply.github.com> Date: Mon, 19 Oct 2026 05:08:33 +0800 Subject: [PATCH 2/2] Ignore strings nested in brackets while extracting messages. --- babel/messages/extract.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/babel/messages/extract.py b/babel/messages/extract.py index 6fad84304..ca3befe9a 100644 --- a/babel/messages/extract.py +++ b/babel/messages/extract.py @@ -567,6 +567,8 @@ def extract_python( """ funcname = lineno = message_lineno = None call_stack = [] # line numbers of calls + # Strings inside subscripts, lists, dicts, and sets are not arguments. + bracket_depth = 0 buf = [] messages = [] translator_comments = [] @@ -640,11 +642,22 @@ def extract_python( funcname = lineno = message_lineno = None call_stack.clear() + bracket_depth = 0 messages = [] translator_comments = [] in_translator_comments = False if nested: funcname = value + elif tok == OP and value in {'[', '{'}: + if not message_lineno: + message_lineno = lineno + bracket_depth += 1 + elif tok == OP and value in {']', '}'}: + if bracket_depth: + bracket_depth -= 1 + elif bracket_depth: + # The string belongs to the bracketed expression, not the call. + pass elif tok == STRING: val = _parse_python_string(value, encoding, future_flags) if val is not None: