Repository: DataBiosphere/toil

Issue:
Add type hints to memoize.py
Add type hints to `src/toil/lib/memoize.py` so it can be checked under mypy during linting.

Refers to #3568.

┆Issue is synchronized with this [Jira Task](https://ucsc-cgl.atlassian.net/browse/TOIL-944)
┆Issue Number: TOIL-944



Discussion:

Resolving patch:
diff --git a/contrib/admin/mypy-with-ignore.py b/contrib/admin/mypy-with-ignore.py
--- a/contrib/admin/mypy-with-ignore.py
+++ b/contrib/admin/mypy-with-ignore.py
@@ -90,7 +90,6 @@ def main():
         'src/toil/jobStores/aws/__init__.py',
         'src/toil/utils/toilStats.py',
         'src/toil/utils/__init__.py',
-        'src/toil/lib/memoize.py',
         'src/toil/lib/throttle.py',
         'src/toil/lib/humanize.py',
         'src/toil/lib/iterables.py',
diff --git a/src/toil/lib/memoize.py b/src/toil/lib/memoize.py
--- a/src/toil/lib/memoize.py
+++ b/src/toil/lib/memoize.py
@@ -15,21 +15,23 @@
 # 5.14.2018: copied into Toil from https://github.com/BD2KGenomics/bd2k-python-lib
 import datetime
 import re
+
 from functools import wraps
 from threading import Lock
+from typing import Dict, Any, Callable, Tuple
 
 
-def memoize(f):
+def memoize(f: Callable[..., Any]) -> Callable[..., Any]:
     """
     A decorator that memoizes a function result based on its parameters. For example, this can be
     used in place of lazy initialization. If the decorating function is invoked by multiple
     threads, the decorated function may be called more than once with the same arguments.
     """
     # TODO: Recommend that f's arguments be immutable
-    memory = {}
+    memory: Dict[Tuple[Any, ...], Any] = {}
 
     @wraps(f)
-    def new_f(*args):
+    def new_f(*args: Any) -> Any:
         try:
             return memory[args]
         except KeyError:
@@ -40,17 +42,17 @@ def new_f(*args):
     return new_f
 
 
-def sync_memoize(f):
+def sync_memoize(f: Callable[..., Any]) -> Callable[..., Any]:
     """
     Like memoize, but guarantees that decorated function is only called once, even when multiple
     threads are calling the decorating function with multiple parameters.
     """
     # TODO: Think about an f that is recursive
-    memory = {}
+    memory: Dict[Tuple[Any, ...], Any] = {}
     lock = Lock()
 
     @wraps(f)
-    def new_f(*args):
+    def new_f(*args: Any) -> Any:
         try:
             return memory[args]
         except KeyError:
@@ -65,16 +67,14 @@ def new_f(*args):
     return new_f
 
 
-def parse_iso_utc(s):
+def parse_iso_utc(s: str) -> datetime.datetime:
     """
     Parses an ISO time with a hard-coded Z for zulu-time (UTC) at the end. Other timezones are
-    not supported.
-
-    :param str s: the ISO-formatted time
+    not supported. Returns a timezone-naive datetime object. 
 
-    :rtype: datetime.datetime
+    :param s: The ISO-formatted time
 
-    :return: an timezone-naive datetime object
+    :return: A timezone-naive datetime object
 
     >>> parse_iso_utc('2016-04-27T00:28:04.000Z')
     datetime.datetime(2016, 4, 27, 0, 28, 4)
@@ -94,7 +94,7 @@ def parse_iso_utc(s):
         return datetime.datetime.strptime(s, fmt)
 
 
-def strict_bool(s):
+def strict_bool(s: str) -> bool:
     """Variant of bool() that only accepts two possible string values."""
     if s == 'True':
         return True


Test patch: