fix(i18n): tighten prompt and catalog fallback handling
This commit is contained in:
@@ -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:
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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:
|
||||||
# 优先使用内部构造函数
|
# 优先使用内部构造函数
|
||||||
|
|||||||
Reference in New Issue
Block a user