From c17a505263e4de3a4bbd6a73cdbf730c647c160b Mon Sep 17 00:00:00 2001 From: Albert Tugushev Date: Sat, 26 Oct 2019 12:05:37 +0700 Subject: [PATCH 1/3] Add mypy hook to pre-commit config --- .pre-commit-config.yaml | 7 +++++++ setup.cfg | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8fa258ac5..85268fee4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,3 +20,10 @@ repos: - id: bandit language_version: python3 exclude: ^tests/ + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v0.740 + hooks: + - id: mypy + language_version: python3 + # To prevent "Duplicate module named 'setup'" error + exclude: ^tests/test_data/packages/ diff --git a/setup.cfg b/setup.cfg index 5b598a2de..8ee679e81 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,3 +25,10 @@ line_length = 88 multi_line_output = 3 default_section=THIRDPARTY known_first_party = piptools, tests, examples + +[mypy] +follow_imports = silent +ignore_missing_imports = True + +[mypy-tests.*] +ignore_errors = True From 21b713018d2dba6efef0e3d4e71facac1c4f0b38 Mon Sep 17 00:00:00 2001 From: Albert Tugushev Date: Tue, 27 Aug 2019 01:27:25 +0300 Subject: [PATCH 2/3] Add typings for the cache module --- piptools/_compat/typing.py | 2 ++ piptools/cache.py | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 piptools/_compat/typing.py diff --git a/piptools/_compat/typing.py b/piptools/_compat/typing.py new file mode 100644 index 000000000..0f829064b --- /dev/null +++ b/piptools/_compat/typing.py @@ -0,0 +1,2 @@ +# The pattern is taken from https://github.com/python/mypy/issues/3216 +MYPY = False diff --git a/piptools/cache.py b/piptools/cache.py index f31f74250..5c5fb3454 100644 --- a/piptools/cache.py +++ b/piptools/cache.py @@ -7,16 +7,23 @@ from pip._vendor.packaging.requirements import Requirement +from ._compat.typing import MYPY from .exceptions import PipToolsError from .locations import CACHE_DIR from .utils import as_tuple, key_from_req, lookup_table +if MYPY: + from typing import Dict, List, Optional, Set, Tuple + from ._compat import InstallRequirement + class CorruptCacheError(PipToolsError): def __init__(self, path): + # type: (str) -> None self.path = path def __str__(self): + # type: () -> str lines = [ "The dependency cache seems to have been corrupted.", "Inspect, or delete, the following file:", @@ -26,6 +33,7 @@ def __str__(self): def read_cache_file(cache_file_path): + # type: (str) -> Dict[str, dict] with open(cache_file_path, "r") as cache_file: try: doc = json.load(cache_file) @@ -49,7 +57,10 @@ class DependencyCache(object): Where X.Y indicates the Python version. """ + _cache = None # type: Dict[str, dict] + def __init__(self, cache_dir=None): + # type: (Optional[str]) -> None if cache_dir is None: cache_dir = CACHE_DIR if not os.path.isdir(cache_dir): @@ -58,10 +69,10 @@ def __init__(self, cache_dir=None): cache_filename = "depcache-py{}.json".format(py_version) self._cache_file = os.path.join(cache_dir, cache_filename) - self._cache = None @property def cache(self): + # type: () -> Dict[str, dict] """ The dictionary that is the actual in-memory cache. This property lazily loads the cache from disk. @@ -71,6 +82,7 @@ def cache(self): return self._cache def as_cache_key(self, ireq): + # type: (InstallRequirement) -> Tuple[str, str] """ Given a requirement, return its cache key. This behavior is a little weird in order to allow backwards compatibility with cache files. For a requirement @@ -91,6 +103,7 @@ def as_cache_key(self, ireq): return name, "{}{}".format(version, extras_string) def read_cache(self): + # type: () -> None """Reads the cached contents into memory.""" if os.path.exists(self._cache_file): self._cache = read_cache_file(self._cache_file) @@ -98,30 +111,36 @@ def read_cache(self): self._cache = {} def write_cache(self): + # type: () -> None """Writes the cache to disk as JSON.""" doc = {"__format__": 1, "dependencies": self._cache} with open(self._cache_file, "w") as f: json.dump(doc, f, sort_keys=True) def clear(self): + # type: () -> None self._cache = {} self.write_cache() def __contains__(self, ireq): + # type: (InstallRequirement) -> bool pkgname, pkgversion_and_extras = self.as_cache_key(ireq) return pkgversion_and_extras in self.cache.get(pkgname, {}) def __getitem__(self, ireq): + # type: (InstallRequirement) -> List[str] pkgname, pkgversion_and_extras = self.as_cache_key(ireq) return self.cache[pkgname][pkgversion_and_extras] def __setitem__(self, ireq, values): + # type: (InstallRequirement, List[str]) -> None pkgname, pkgversion_and_extras = self.as_cache_key(ireq) self.cache.setdefault(pkgname, {}) self.cache[pkgname][pkgversion_and_extras] = values self.write_cache() def reverse_dependencies(self, ireqs): + # type: (List[InstallRequirement]) -> Dict[str, Set[str]] """ Returns a lookup table of reverse dependencies for all the given ireqs. @@ -134,6 +153,7 @@ def reverse_dependencies(self, ireqs): return self._reverse_dependencies(ireqs_as_cache_values) def _reverse_dependencies(self, cache_keys): + # type: (List[Tuple[str, str]]) -> Dict[str, Set[str]] """ Returns a lookup table of reverse dependencies for all the given cache keys. From 1a9b4bee0f5c4ec25dcf6b9ce20af99cae113cd0 Mon Sep 17 00:00:00 2001 From: Albert Tugushev Date: Sun, 27 Oct 2019 01:32:33 +0700 Subject: [PATCH 3/3] Exclude typing imports from coverage --- .coveragerc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.coveragerc b/.coveragerc index 5bac98ea1..d6c1ccb12 100644 --- a/.coveragerc +++ b/.coveragerc @@ -7,3 +7,6 @@ omit = [report] include = piptools/*, tests/* +exclude_lines = + # Don't complain about typing imports + if MYPY: