diff --git a/pylib/anki/_backend/__init__.py b/pylib/anki/_backend/__init__.py index ec233f8ea..8a274e403 100644 --- a/pylib/anki/_backend/__init__.py +++ b/pylib/anki/_backend/__init__.py @@ -118,14 +118,14 @@ def translate_string_in( class Translations(GeneratedTranslations): - def __init__(self, backend: ref["anki._backend.RustBackend"]): - self._backend = backend + def __init__(self, backend: ref[RustBackend]): + self.backend = backend def __call__(self, *args: Any, **kwargs: Any) -> str: "Mimic the old col.tr / TR interface" - return self._backend().translate(*args, **kwargs) + return self.backend().translate(*args, **kwargs) def _translate( self, module: int, translation: int, args: Dict[str, Union[str, int, float]] ) -> str: - return self._backend().translate(module * 1000 + translation, **args) + return self.backend().translate(module * 1000 + translation, **args) diff --git a/pylib/anki/collection.py b/pylib/anki/collection.py index 710d4834e..b272a4e73 100644 --- a/pylib/anki/collection.py +++ b/pylib/anki/collection.py @@ -40,7 +40,7 @@ from anki.consts import * from anki.dbproxy import DBProxy from anki.decks import DeckID, DeckManager from anki.errors import AnkiError, DBError -from anki.lang import TR, FormatTimeSpan +from anki.lang import FormatTimeSpan from anki.media import MediaManager, media_paths_from_col_path from anki.models import ModelManager, NoteType, NoteTypeID from anki.notes import Note, NoteID diff --git a/pylib/anki/consts.py b/pylib/anki/consts.py index 18cb2aa59..4f9a765eb 100644 --- a/pylib/anki/consts.py +++ b/pylib/anki/consts.py @@ -3,10 +3,10 @@ from __future__ import annotations +import sys from typing import Any, Dict, NewType, Optional import anki -from anki.lang import TR # whether new cards should be mixed with reviews, or shown first or last NEW_CARDS_DISTRIBUTE = 0 @@ -99,6 +99,9 @@ def _tr(col: Optional[anki.collection.Collection]) -> Any: return col.tr else: print("routine in consts.py should be passed col") + import traceback + + traceback.print_stack(file=sys.stdout) from anki.lang import tr_legacyglobal return tr_legacyglobal @@ -107,8 +110,8 @@ def _tr(col: Optional[anki.collection.Collection]) -> Any: def newCardOrderLabels(col: Optional[anki.collection.Collection]) -> Dict[int, Any]: tr = _tr(col) return { - 0: tr(TR.SCHEDULING_SHOW_NEW_CARDS_IN_RANDOM_ORDER), - 1: tr(TR.SCHEDULING_SHOW_NEW_CARDS_IN_ORDER_ADDED), + 0: tr.scheduling_show_new_cards_in_random_order(), + 1: tr.scheduling_show_new_cards_in_order_added(), } @@ -117,22 +120,22 @@ def newCardSchedulingLabels( ) -> Dict[int, Any]: tr = _tr(col) return { - 0: tr(TR.SCHEDULING_MIX_NEW_CARDS_AND_REVIEWS), - 1: tr(TR.SCHEDULING_SHOW_NEW_CARDS_AFTER_REVIEWS), - 2: tr(TR.SCHEDULING_SHOW_NEW_CARDS_BEFORE_REVIEWS), + 0: tr.scheduling_mix_new_cards_and_reviews(), + 1: tr.scheduling_show_new_cards_after_reviews(), + 2: tr.scheduling_show_new_cards_before_reviews(), } def dynOrderLabels(col: Optional[anki.collection.Collection]) -> Dict[int, Any]: tr = _tr(col) return { - 0: tr(TR.DECKS_OLDEST_SEEN_FIRST), - 1: tr(TR.DECKS_RANDOM), - 2: tr(TR.DECKS_INCREASING_INTERVALS), - 3: tr(TR.DECKS_DECREASING_INTERVALS), - 4: tr(TR.DECKS_MOST_LAPSES), - 5: tr(TR.DECKS_ORDER_ADDED), - 6: tr(TR.DECKS_ORDER_DUE), - 7: tr(TR.DECKS_LATEST_ADDED_FIRST), - 8: tr(TR.DECKS_RELATIVE_OVERDUENESS), + 0: tr.decks_oldest_seen_first(), + 1: tr.decks_random(), + 2: tr.decks_increasing_intervals(), + 3: tr.decks_decreasing_intervals(), + 4: tr.decks_most_lapses(), + 5: tr.decks_order_added(), + 6: tr.decks_order_due(), + 7: tr.decks_latest_added_first(), + 8: tr.decks_relative_overdueness(), } diff --git a/pylib/anki/importing/__init__.py b/pylib/anki/importing/__init__.py index 5a8f928c1..d2f434938 100644 --- a/pylib/anki/importing/__init__.py +++ b/pylib/anki/importing/__init__.py @@ -16,12 +16,12 @@ from anki.lang import TR def importers(col: Collection) -> Sequence[Tuple[str, Type[Importer]]]: return ( - (col.tr(TR.IMPORTING_TEXT_SEPARATED_BY_TABS_OR_SEMICOLONS), TextImporter), + (col.tr.importing_text_separated_by_tabs_or_semicolons(), TextImporter), ( - col.tr(TR.IMPORTING_PACKAGED_ANKI_DECKCOLLECTION_APKG_COLPKG_ZIP), + col.tr.importing_packaged_anki_deckcollection_apkg_colpkg_zip(), AnkiPackageImporter, ), - (col.tr(TR.IMPORTING_MNEMOSYNE_20_DECK_DB), MnemosyneImporter), - (col.tr(TR.IMPORTING_SUPERMEMO_XML_EXPORT_XML), SupermemoXmlImporter), - (col.tr(TR.IMPORTING_PAUKER_18_LESSON_PAUGZ), PaukerImporter), + (col.tr.importing_mnemosyne_20_deck_db(), MnemosyneImporter), + (col.tr.importing_supermemo_xml_export_xml(), SupermemoXmlImporter), + (col.tr.importing_pauker_18_lesson_paugz(), PaukerImporter), ) diff --git a/pylib/anki/lang.py b/pylib/anki/lang.py index 11a10c5a9..537ca5db2 100644 --- a/pylib/anki/lang.py +++ b/pylib/anki/lang.py @@ -5,7 +5,8 @@ from __future__ import annotations import locale import re -from typing import Any, Optional, Tuple +import weakref +from typing import Optional, Tuple import anki import anki._backend.backend_pb2 as _pb @@ -147,8 +148,12 @@ def lang_to_disk_lang(lang: str) -> str: # the currently set interface language currentLang = "en" -# the current Fluent translation instance +# the current Fluent translation instance. Code in pylib/ should +# not reference this, and should use col.tr instead. The global +# instance exists for legacy reasons, and as a convenience for the +# Qt code. current_i18n: Optional[anki._backend.RustBackend] = None +tr_legacyglobal: Optional[anki._backend.Translations] = None def _(str: str) -> str: @@ -161,18 +166,11 @@ def ngettext(single: str, plural: str, n: int) -> str: return plural -def tr_legacyglobal(*args: Any, **kwargs: Any) -> str: - "Should use col.tr() instead." - if current_i18n: - return current_i18n.translate(*args, **kwargs) - else: - return "tr_legacyglobal() called without active backend" - - def set_lang(lang: str) -> None: - global currentLang, current_i18n + global currentLang, current_i18n, tr_legacyglobal currentLang = lang current_i18n = anki._backend.RustBackend(langs=[lang]) + tr_legacyglobal = anki._backend.Translations(weakref.ref(current_i18n)) def get_def_lang(lang: Optional[str] = None) -> Tuple[int, str]: diff --git a/pylib/tools/rewrite_tr.py b/pylib/tools/rewrite_tr.py index 875bdf5ac..a6f7856b8 100644 --- a/pylib/tools/rewrite_tr.py +++ b/pylib/tools/rewrite_tr.py @@ -9,12 +9,12 @@ from re import Match import stringcase -TR_REF = re.compile(r"\.tr\(TR.([^,)]+)\)") +TR_REF = re.compile(r"tr\(TR.([^,)]+)\)") def repl(m: Match) -> str: name = m.group(1).lower() - return f".tr.{name}()" + return f"tr.{name}()" def update_py(path: str) -> None: @@ -23,6 +23,7 @@ def update_py(path: str) -> None: for line in open(path): line2 = TR_REF.sub(repl, line) if line != line2: + print(line2) buf.append(line2) changed = True else: