fix(i18n): tighten prompt and catalog fallback handling

This commit is contained in:
春河晴
2026-03-13 01:59:16 +09:00
parent d418a8451b
commit 568685758b
3 changed files with 10 additions and 9 deletions

View File

@@ -7,9 +7,7 @@ from babel import Locale
from babel.dates import format_datetime as babel_format_datetime from babel.dates import format_datetime as babel_format_datetime
from babel.numbers import format_decimal as babel_format_decimal from babel.numbers import format_decimal as babel_format_decimal
from .loaders import DEFAULT_LOCALE, extract_placeholders, format_template, to_babel_locale from .loaders import DEFAULT_LOCALE, to_babel_locale
__all__ = ["extract_placeholders", "format_template"]
def select_plural_category(locale: str, count: int | float | Decimal) -> str: def select_plural_category(locale: str, count: int | float | Decimal) -> str:

View File

@@ -10,7 +10,8 @@ import os
import threading import threading
from .exceptions import I18nError, InvalidLocaleError from .exceptions import I18nError, InvalidLocaleError
from .formatting import format_template, select_plural_category from .formatting import select_plural_category
from .loaders import format_template
from .loaders import DEFAULT_LOCALE, TranslationValue, get_locales_root, load_locale_catalog, normalize_locale from .loaders import DEFAULT_LOCALE, TranslationValue, get_locales_root, load_locale_catalog, normalize_locale
logger = logging.getLogger("maibot.i18n") logger = logging.getLogger("maibot.i18n")
@@ -134,7 +135,7 @@ class I18nManager:
return format_template(template, **kwargs) return format_template(template, **kwargs)
except Exception as exc: except Exception as exc:
logger.error("翻译 key '%s' 格式化失败: %s", key, exc) logger.error("翻译 key '%s' 格式化失败: %s", key, exc)
return template or key return template
def _get_translation_value(self, key: str, locale: str | None) -> tuple[TranslationValue | None, str]: def _get_translation_value(self, key: str, locale: str | None) -> tuple[TranslationValue | None, str]:
target_locale = self._resolve_locale(locale) target_locale = self._resolve_locale(locale)
@@ -198,7 +199,7 @@ class I18nManager:
normalized_locale, normalized_locale,
exc, exc,
) )
catalog = {} return {}
with self._cache_lock: with self._cache_lock:
if normalized_locale in self._catalog_cache: if normalized_locale in self._catalog_cache:

View File

@@ -181,8 +181,10 @@ class PromptManager:
self, self,
prompt: Prompt, prompt: Prompt,
recursive_level: int = 0, recursive_level: int = 0,
additional_construction_function_dict: dict[str, Callable[[str], str | Coroutine[Any, Any, str]]] = {}, # noqa: B006 additional_construction_function_dict: dict[str, Callable[[str], str | Coroutine[Any, Any, str]]] | None = None,
) -> str: ) -> str:
if additional_construction_function_dict is None:
additional_construction_function_dict = {}
prompt.template = prompt.template.replace("{{", _LEFT_BRACE).replace("}}", _RIGHT_BRACE) prompt.template = prompt.template.replace("{{", _LEFT_BRACE).replace("}}", _RIGHT_BRACE)
if recursive_level > 10: if recursive_level > 10:
raise RecursionError("递归层级过深,可能存在循环引用") raise RecursionError("递归层级过深,可能存在循环引用")
@@ -191,11 +193,11 @@ class PromptManager:
for field_name in field_block: for field_name in field_block:
if field_name in self.prompts: if field_name in self.prompts:
nested_prompt = self.get_prompt(field_name) nested_prompt = self.get_prompt(field_name)
additional_construction_function_dict |= prompt.prompt_render_context merged_context = additional_construction_function_dict | prompt.prompt_render_context
rendered_fields[field_name] = await self._render( rendered_fields[field_name] = await self._render(
nested_prompt, nested_prompt,
recursive_level + 1, recursive_level + 1,
additional_construction_function_dict, merged_context,
) )
elif field_name in prompt.prompt_render_context: elif field_name in prompt.prompt_render_context:
# 优先使用内部构造函数 # 优先使用内部构造函数