From 6199ed79167495740c99b1b44004fe68b5f45703 Mon Sep 17 00:00:00 2001 From: Dima Gerasimov Date: Tue, 29 Sep 2020 16:58:50 +0100 Subject: [PATCH] my.hypothesis: better mypy coverage --- my/core/compat.py | 4 +++- my/core/error.py | 8 ++++---- my/hypothesis.py | 18 ++++++++++++------ 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/my/core/compat.py b/my/core/compat.py index 27786ea..bf63b0c 100644 --- a/my/core/compat.py +++ b/my/core/compat.py @@ -1,6 +1,8 @@ ''' Some backwards compatibility stuff/deprecation helpers ''' +from types import ModuleType + from . import warnings from .common import LazyLogger @@ -13,7 +15,7 @@ def pre_pip_dal_handler( e: ModuleNotFoundError, cfg, requires=[], -) -> None: +) -> ModuleType: ''' https://github.com/karlicoss/HPI/issues/79 ''' diff --git a/my/core/error.py b/my/core/error.py index c0f3f0c..70630f4 100644 --- a/my/core/error.py +++ b/my/core/error.py @@ -4,7 +4,7 @@ See https://beepb00p.xyz/mypy-error-handling.html#kiss for more detail """ from itertools import tee -from typing import Union, TypeVar, Iterable, List, Tuple, Type, Optional +from typing import Union, TypeVar, Iterable, List, Tuple, Type, Optional, Callable, Any T = TypeVar('T') @@ -44,7 +44,7 @@ def split_errors(l: Iterable[ResT[T, E]], ET: Type[E]) -> Tuple[Iterable[T], Ite return (values, errors) -def sort_res_by(items: Iterable[ResT], key) -> List[ResT]: +def sort_res_by(items: Iterable[Res[T]], key: Callable[[T], Any]) -> List[Res[T]]: """ The general idea is: just alaways carry errors with the entry that precedes them """ @@ -58,7 +58,7 @@ def sort_res_by(items: Iterable[ResT], key) -> List[ResT]: groups.append((i, group)) group = [] - results = [] + results: List[Res[T]] = [] for v, errs in sorted(groups, key=lambda p: key(p[0])): results.extend(errs) results.append(v) @@ -125,7 +125,7 @@ def extract_error_datetime(e: Exception) -> Optional[datetime]: return None -def test_datetime_errors(): +def test_datetime_errors() -> None: import pytz dt_notz = datetime.now() dt_tz = datetime.now(tz=pytz.timezone('Europe/Amsterdam')) diff --git a/my/hypothesis.py b/my/hypothesis.py index ddf4239..e73c975 100644 --- a/my/hypothesis.py +++ b/my/hypothesis.py @@ -2,7 +2,8 @@ [[https://hypothes.is][Hypothes.is]] highlights and annotations """ from dataclasses import dataclass -from typing import Optional +from datetime import datetime +from typing import Optional, Callable from .core import Paths @@ -50,12 +51,17 @@ def _dal() -> dal.DAL: def highlights() -> List[Res[Highlight]]: - return sort_res_by(_dal().highlights(), key=lambda h: h.created) + # todo hmm. otherwise mypy complans + key: Callable[[Highlight], datetime] = lambda h: h.created + return sort_res_by(_dal().highlights(), key=key) # TODO eh. always provide iterators? although sort_res_by could be neat too... def pages() -> List[Res[Page]]: - return sort_res_by(_dal().pages(), key=lambda h: h.created) + # note: mypy report shows "No Anys on this line here", apparently a bug with type aliases + # https://github.com/python/mypy/issues/8594 + key: Callable[[Page], datetime] = lambda h: h.created + return sort_res_by(_dal().pages(), key=key) # todo not public api yet @@ -67,12 +73,12 @@ def stats(): } -def _main(): +def _main() -> None: for page in get_pages(): print(page) if __name__ == '__main__': _main() -get_highlights = highlights # TODO deprecate -get_pages = pages # TODO deprecate +get_highlights = highlights # todo deprecate +get_pages = pages # todo deprecate