From fc462bb6ea31fb0b5926cddfc5ee58f9b58aa5ba Mon Sep 17 00:00:00 2001 From: Loren Eteval Date: Wed, 19 Aug 2026 08:52:05 +0800 Subject: [PATCH] Improve static translation extraction Signed-off-by: Loren Eteval --- Translation.py | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/Translation.py b/Translation.py index a496976..cd6d02e 100644 --- a/Translation.py +++ b/Translation.py @@ -68,8 +68,44 @@ def getAppConstantsByName(name): APPLICATION_SOURCE_CODE_PATH = getAppSourceCodePath(PACKAGE_DIR) +def _staticTranslationSource(node): + """Return a static translation key, including constant-only f-strings.""" + if isinstance(node, ast.Constant) and isinstance(node.value, str): + return node.value + + if not isinstance(node, ast.JoinedStr): + return None + + parts = [] + + for value in node.values: + if isinstance(value, ast.Constant) and isinstance(value.value, str): + parts.append(value.value) + + continue + + if ( + isinstance(value, ast.FormattedValue) + and isinstance(value.value, ast.Name) + and value.conversion == -1 + and value.format_spec is None + ): + try: + getAppConstantsByName(value.value.id) + except AttributeError: + return None + + parts.append(f'{{{value.value.id}}}') + + continue + + return None + + return ''.join(parts) + + def getTranslationKeys(content): - """Return literal strings passed directly to the translation function.""" + """Return static strings passed directly to the translation function.""" syntaxTree = ast.parse(content) for node in ast.walk(syntaxTree): @@ -82,10 +118,10 @@ def getTranslationKeys(content): if not node.args: continue - source = node.args[0] + source = _staticTranslationSource(node.args[0]) - if isinstance(source, ast.Constant) and isinstance(source.value, str): - yield source.value + if source is not None: + yield source def resolveAppConstants(source):