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 :-(
This commit is contained in:
Damien Elmes 2020-05-27 09:14:02 +10:00
parent f9f07a7d55
commit 97618564f4
6 changed files with 35 additions and 14 deletions

View file

@ -10,7 +10,7 @@ import re
import time import time
import traceback import traceback
import weakref 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.find
import anki.latex # sets up hook import anki.latex # sets up hook
@ -32,6 +32,9 @@ from anki.schedv2 import Scheduler as V2Scheduler
from anki.tags import TagManager from anki.tags import TagManager
from anki.utils import devMode, ids2str, intTime from anki.utils import devMode, ids2str, intTime
if TYPE_CHECKING:
from anki.rsbackend import TRValue, FormatTimeSpanContextValue
class Collection: class Collection:
sched: Union[V1Scheduler, V2Scheduler] sched: Union[V1Scheduler, V2Scheduler]
@ -72,13 +75,13 @@ class Collection:
# I18n/messages # 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) return self.backend.translate(key, **kwargs)
def format_timespan( def format_timespan(
self, self,
seconds: float, seconds: float,
context: FormatTimeSpanContext = FormatTimeSpanContext.INTERVALS, context: FormatTimeSpanContextValue = FormatTimeSpanContext.INTERVALS,
) -> str: ) -> str:
return self.backend.format_timespan(seconds=seconds, context=context) return self.backend.format_timespan(seconds=seconds, context=context)

View file

@ -11,11 +11,13 @@ instead. Eg, don't use col.backend.all_deck_config(), instead use
col.decks.all_config() col.decks.all_config()
""" """
from __future__ import annotations
import enum import enum
import json import json
import os import os
from dataclasses import dataclass 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 import ankirspy # pytype: disable=import-error
@ -35,6 +37,11 @@ except ImportError:
pass pass
if TYPE_CHECKING:
from anki.fluent_pb2 import FluentStringValue as TRValue
FormatTimeSpanContextValue = pb.FormatTimespanIn.ContextValue
assert ankirspy.buildhash() == anki.buildinfo.buildhash assert ankirspy.buildhash() == anki.buildinfo.buildhash
SchedTimingToday = pb.SchedTimingTodayOut SchedTimingToday = pb.SchedTimingTodayOut
@ -213,13 +220,13 @@ class RustBackend(RustBackendGenerated):
def _db_command(self, input: Dict[str, Any]) -> Any: def _db_command(self, input: Dict[str, Any]) -> Any:
return from_json_bytes(self._backend.db_command(to_json_bytes(input))) 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)) return self.translate_string(translate_string_in(key, **kwargs))
def format_time_span( def format_time_span(
self, self,
seconds: float, seconds: float,
context: FormatTimeSpanContext = FormatTimeSpanContext.INTERVALS, context: FormatTimeSpanContextValue = FormatTimeSpanContext.INTERVALS,
) -> str: ) -> str:
print( print(
"please use col.format_timespan() instead of col.backend.format_time_span()" "please use col.format_timespan() instead of col.backend.format_time_span()"
@ -238,7 +245,7 @@ class RustBackend(RustBackendGenerated):
def translate_string_in( def translate_string_in(
key: TR, **kwargs: Union[str, int, float] key: TRValue, **kwargs: Union[str, int, float]
) -> pb.TranslateStringIn: ) -> pb.TranslateStringIn:
args = {} args = {}
for (k, v) in kwargs.items(): for (k, v) in kwargs.items():

View file

@ -1,18 +1,24 @@
# Copyright: Ankitects Pty Ltd and contributors # Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html # 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.collection import Collection
from anki.models import NoteType from anki.models import NoteType
from anki.rsbackend import StockNoteType, from_json_bytes 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) # 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 # to this list to have it shown in the add/clone note type screen
models: List[Tuple] = [] 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)) m = from_json_bytes(col.backend.get_stock_notetype_legacy(kind))
col.models.add(m) col.models.add(m)
return m return m

View file

@ -1,6 +1,6 @@
wheel wheel
mypy mypy
mypy_protobuf mypy_protobuf>=1.21
black black
pytest pytest
# fixme: when isort 5.0 is released, switch to pypi # fixme: when isort 5.0 is released, switch to pypi

View file

@ -55,7 +55,7 @@ def python_type_inner(field):
elif type == TYPE_MESSAGE: elif type == TYPE_MESSAGE:
return fullname(field.message_type.full_name) return fullname(field.message_type.full_name)
elif type == TYPE_ENUM: elif type == TYPE_ENUM:
return fullname(field.enum_type.full_name) return fullname(field.enum_type.full_name) + "Value"
else: else:
raise Exception(f"unknown type: {type}") 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 # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
# pylint: skip-file # pylint: skip-file
from __future__ import annotations
""" """
THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT. THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT.

View file

@ -8,16 +8,19 @@ import os
import re import re
import subprocess import subprocess
import sys import sys
from typing import Any, Optional, Union from typing import TYPE_CHECKING, Any, Optional, Union
import anki import anki
import aqt import aqt
from anki.lang import _ 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 anki.utils import invalidFilename, isMac, isWin, noBundledLibs, versionWithBuild
from aqt.qt import * from aqt.qt import *
from aqt.theme import theme_manager from aqt.theme import theme_manager
if TYPE_CHECKING:
from anki.rsbackend import TRValue
def aqt_data_folder() -> str: def aqt_data_folder() -> str:
# wheel install? # wheel install?
@ -32,7 +35,7 @@ def locale_dir() -> str:
return os.path.join(aqt_data_folder(), "locale") 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." "Shortcut to access Fluent translations."
return anki.lang.current_i18n.translate(key, **kwargs) return anki.lang.current_i18n.translate(key, **kwargs)