From 97618564f4588879acd3ee69dabb3eea6c0c812d Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Wed, 27 May 2020 09:14:02 +1000 Subject: [PATCH] fix typechecking breaking with latest mypy_protobuf the change that caused it: https://github.com/dropbox/mypy-protobuf/issues/118 This is more awkward to handle now, as the types are only available at type-checking time. Python's static typing is such a mess :-( --- pylib/anki/collection.py | 9 ++++++--- pylib/anki/rsbackend.py | 15 +++++++++++---- pylib/anki/stdmodels.py | 10 ++++++++-- pylib/requirements.dev | 2 +- pylib/tools/genbackend.py | 4 +++- qt/aqt/utils.py | 9 ++++++--- 6 files changed, 35 insertions(+), 14 deletions(-) diff --git a/pylib/anki/collection.py b/pylib/anki/collection.py index 0acecaafc..483e2d30f 100644 --- a/pylib/anki/collection.py +++ b/pylib/anki/collection.py @@ -10,7 +10,7 @@ import re import time import traceback import weakref -from typing import Any, Iterable, List, Optional, Sequence, Tuple, Union +from typing import TYPE_CHECKING, Any, Iterable, List, Optional, Sequence, Tuple, Union import anki.find import anki.latex # sets up hook @@ -32,6 +32,9 @@ from anki.schedv2 import Scheduler as V2Scheduler from anki.tags import TagManager from anki.utils import devMode, ids2str, intTime +if TYPE_CHECKING: + from anki.rsbackend import TRValue, FormatTimeSpanContextValue + class Collection: sched: Union[V1Scheduler, V2Scheduler] @@ -72,13 +75,13 @@ class Collection: # I18n/messages ########################################################################## - def tr(self, key: TR, **kwargs: Union[str, int, float]) -> str: + def tr(self, key: TRValue, **kwargs: Union[str, int, float]) -> str: return self.backend.translate(key, **kwargs) def format_timespan( self, seconds: float, - context: FormatTimeSpanContext = FormatTimeSpanContext.INTERVALS, + context: FormatTimeSpanContextValue = FormatTimeSpanContext.INTERVALS, ) -> str: return self.backend.format_timespan(seconds=seconds, context=context) diff --git a/pylib/anki/rsbackend.py b/pylib/anki/rsbackend.py index 23b7fa9bd..023fec20c 100644 --- a/pylib/anki/rsbackend.py +++ b/pylib/anki/rsbackend.py @@ -11,11 +11,13 @@ instead. Eg, don't use col.backend.all_deck_config(), instead use col.decks.all_config() """ +from __future__ import annotations + import enum import json import os from dataclasses import dataclass -from typing import Any, Dict, List, Optional, Sequence, Union +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Union import ankirspy # pytype: disable=import-error @@ -35,6 +37,11 @@ except ImportError: pass +if TYPE_CHECKING: + from anki.fluent_pb2 import FluentStringValue as TRValue + + FormatTimeSpanContextValue = pb.FormatTimespanIn.ContextValue + assert ankirspy.buildhash() == anki.buildinfo.buildhash SchedTimingToday = pb.SchedTimingTodayOut @@ -213,13 +220,13 @@ class RustBackend(RustBackendGenerated): def _db_command(self, input: Dict[str, Any]) -> Any: return from_json_bytes(self._backend.db_command(to_json_bytes(input))) - def translate(self, key: TR, **kwargs: Union[str, int, float]) -> str: + def translate(self, key: TRValue, **kwargs: Union[str, int, float]) -> str: return self.translate_string(translate_string_in(key, **kwargs)) def format_time_span( self, seconds: float, - context: FormatTimeSpanContext = FormatTimeSpanContext.INTERVALS, + context: FormatTimeSpanContextValue = FormatTimeSpanContext.INTERVALS, ) -> str: print( "please use col.format_timespan() instead of col.backend.format_time_span()" @@ -238,7 +245,7 @@ class RustBackend(RustBackendGenerated): def translate_string_in( - key: TR, **kwargs: Union[str, int, float] + key: TRValue, **kwargs: Union[str, int, float] ) -> pb.TranslateStringIn: args = {} for (k, v) in kwargs.items(): diff --git a/pylib/anki/stdmodels.py b/pylib/anki/stdmodels.py index de5fdd7c1..e4db1eaf6 100644 --- a/pylib/anki/stdmodels.py +++ b/pylib/anki/stdmodels.py @@ -1,18 +1,24 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from typing import Callable, List, Tuple +from __future__ import annotations + +from typing import TYPE_CHECKING, Callable, List, Tuple from anki.collection import Collection from anki.models import NoteType from anki.rsbackend import StockNoteType, from_json_bytes +if TYPE_CHECKING: + from anki.backend_pb2 import StockNoteTypeValue # pylint: disable=no-name-in-module + + # add-on authors can add ("note type name", function_like_addBasicModel) # to this list to have it shown in the add/clone note type screen models: List[Tuple] = [] -def add_stock_notetype(col: Collection, kind: StockNoteType) -> NoteType: +def add_stock_notetype(col: Collection, kind: StockNoteTypeValue) -> NoteType: m = from_json_bytes(col.backend.get_stock_notetype_legacy(kind)) col.models.add(m) return m diff --git a/pylib/requirements.dev b/pylib/requirements.dev index 443b0f7ec..e3eb84758 100644 --- a/pylib/requirements.dev +++ b/pylib/requirements.dev @@ -1,6 +1,6 @@ wheel mypy -mypy_protobuf +mypy_protobuf>=1.21 black pytest # fixme: when isort 5.0 is released, switch to pypi diff --git a/pylib/tools/genbackend.py b/pylib/tools/genbackend.py index 3ee8c37ce..6cdb60afd 100755 --- a/pylib/tools/genbackend.py +++ b/pylib/tools/genbackend.py @@ -55,7 +55,7 @@ def python_type_inner(field): elif type == TYPE_MESSAGE: return fullname(field.message_type.full_name) elif type == TYPE_ENUM: - return fullname(field.enum_type.full_name) + return fullname(field.enum_type.full_name) + "Value" else: raise Exception(f"unknown type: {type}") @@ -138,6 +138,8 @@ with open(path, "wb") as file: # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html # pylint: skip-file +from __future__ import annotations + """ THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT. diff --git a/qt/aqt/utils.py b/qt/aqt/utils.py index d92476268..46b20bbcf 100644 --- a/qt/aqt/utils.py +++ b/qt/aqt/utils.py @@ -8,16 +8,19 @@ import os import re import subprocess import sys -from typing import Any, Optional, Union +from typing import TYPE_CHECKING, Any, Optional, Union import anki import aqt from anki.lang import _ -from anki.rsbackend import TR +from anki.rsbackend import TR # pylint: disable=unused-import from anki.utils import invalidFilename, isMac, isWin, noBundledLibs, versionWithBuild from aqt.qt import * from aqt.theme import theme_manager +if TYPE_CHECKING: + from anki.rsbackend import TRValue + def aqt_data_folder() -> str: # wheel install? @@ -32,7 +35,7 @@ def locale_dir() -> str: return os.path.join(aqt_data_folder(), "locale") -def tr(key: TR, **kwargs: Union[str, int, float]) -> str: +def tr(key: TRValue, **kwargs: Union[str, int, float]) -> str: "Shortcut to access Fluent translations." return anki.lang.current_i18n.translate(key, **kwargs)