From 7ab5570cfeafe06b0b07d0f2c709d4b66e448ae3 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Sat, 21 Mar 2020 10:46:54 -0400 Subject: [PATCH 01/15] Add typing to signac.core.json. --- signac/core/json.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/signac/core/json.py b/signac/core/json.py index 0d71f12bd..7c3ff47b0 100644 --- a/signac/core/json.py +++ b/signac/core/json.py @@ -4,6 +4,7 @@ import logging from json import load, loads, JSONEncoder from json.decoder import JSONDecodeError +from typing import Any, Dict, Optional logger = logging.getLogger(__name__) @@ -21,7 +22,7 @@ class CustomJSONEncoder(JSONEncoder): an object that is otherwise not serializable, by calling the object's `_as_dict()` method. """ - def default(self, o): + def default(self, o: Any) -> Dict[str, Any]: if NUMPY: if isinstance(o, numpy.number): return o.item() @@ -35,7 +36,7 @@ def default(self, o): return super(CustomJSONEncoder, self).default(o) -def dumps(o, sort_keys=False, indent=None): +def dumps(o: Any, sort_keys: bool = False, indent: Optional[int] = None) -> str: return CustomJSONEncoder(sort_keys=sort_keys, indent=indent).encode(o) From d594818d0007d06c871fce2669c5f372fc56f5fb Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Fri, 27 Mar 2020 19:56:55 -0500 Subject: [PATCH 02/15] Run mypy in continuous integration. --- .circleci/config.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e13b7c980..4e2041b08 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,7 +19,7 @@ jobs: - run: name: install-dependencies command: | - pip install --progress-bar off --user -U flake8==3.7.1 pydocstyle==5.0.2 + pip install --progress-bar off --user -U flake8==3.7.1 pydocstyle==5.0.2 mypy==0.770 - run: name: style-check-code @@ -31,6 +31,11 @@ jobs: command: | pydocstyle + - run: + name: style-check-type-hints + command: | + mypy -p signac + linux-python-38: &linux-template docker: - image: circleci/python:3.8 From a168649b5221e1fbd775c043836d8f8ea02919a0 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Fri, 27 Mar 2020 19:57:33 -0500 Subject: [PATCH 03/15] Remove unused FileNotFoundError (likely Python 2 legacy compatibility). --- signac/common/errors.py | 4 ---- signac/errors.py | 2 -- 2 files changed, 6 deletions(-) diff --git a/signac/common/errors.py b/signac/common/errors.py index dbcd0454f..6ca7d290f 100644 --- a/signac/common/errors.py +++ b/signac/common/errors.py @@ -22,9 +22,5 @@ class ExportError(Error, RuntimeError): pass -class FileNotFoundError(Error, FileNotFoundError): - pass - - class FetchError(FileNotFoundError): pass diff --git a/signac/errors.py b/signac/errors.py index 8b413d28a..49873ced5 100644 --- a/signac/errors.py +++ b/signac/errors.py @@ -10,7 +10,6 @@ from .common.errors import ConfigError from .common.errors import AuthenticationError from .common.errors import ExportError -from .common.errors import FileNotFoundError from .common.errors import FetchError from .contrib.errors import DestinationExistsError @@ -67,7 +66,6 @@ class KeyTypeError(TypeError): 'ConfigError', 'AuthenticationError', 'ExportError', - 'FileNotFoundError', 'FetchError', 'DestinationExistsError', 'JobsCorruptedError', From af94a5cad9aa6746b0ce40850fc24712c1014e6e Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Fri, 27 Mar 2020 19:58:04 -0500 Subject: [PATCH 04/15] Ignore missing imports in mypy checks. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4e2041b08..30633045f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,7 +34,7 @@ jobs: - run: name: style-check-type-hints command: | - mypy -p signac + mypy -p signac --ignore-missing-imports linux-python-38: &linux-template docker: From 936c6361b8b10c260d159e2b03672cbd964eceb1 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Fri, 27 Mar 2020 21:58:32 -0500 Subject: [PATCH 05/15] Define mypy config. --- .circleci/config.yml | 2 +- setup.cfg | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 30633045f..4e2041b08 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,7 +34,7 @@ jobs: - run: name: style-check-type-hints command: | - mypy -p signac --ignore-missing-imports + mypy -p signac linux-python-38: &linux-template docker: diff --git a/setup.cfg b/setup.cfg index d9858ae0a..86e0a4636 100644 --- a/setup.cfg +++ b/setup.cfg @@ -18,6 +18,9 @@ exclude = configobj,passlib,cite.py,conf.py match = jsondict.py ignore = D105, D107, D203, D213 +[mypy] +ignore_missing_imports = True + [coverage:run] source = signac omit = From 5b275d34b4b6d79740b7e4e4a7e6ca60e2560e38 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Fri, 27 Mar 2020 21:59:18 -0500 Subject: [PATCH 06/15] Ignore typing in syncutil dircmp_deep. --- signac/syncutil.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/signac/syncutil.py b/signac/syncutil.py index 88c728a17..5abc26045 100644 --- a/signac/syncutil.py +++ b/signac/syncutil.py @@ -48,13 +48,13 @@ def copytree(src, dst, copy_function=shutil.copy2, symlinks=False): class dircmp_deep(dircmp): - def phase3(self): # Find out differences between common files xx = filecmp.cmpfiles(self.left, self.right, self.common_files, shallow=False) self.same_files, self.diff_files, self.funny_files = xx methodmap = dict(dircmp.methodmap) - methodmap['samefiles'] = methodmap['diff_files'] = phase3 + # The following line must be ignored: https://github.com/python/mypy/issues/708 + methodmap['same_files'] = methodmap['diff_files'] = phase3 # type: ignore class _DocProxy(object): From f35944d791722f4cf965c7a8f059e6199a88570b Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Fri, 27 Mar 2020 22:01:50 -0500 Subject: [PATCH 07/15] Fix error in print statement parentheses. --- signac/contrib/filterparse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signac/contrib/filterparse.py b/signac/contrib/filterparse.py index af247d57f..b6f480fd5 100644 --- a/signac/contrib/filterparse.py +++ b/signac/contrib/filterparse.py @@ -56,7 +56,7 @@ def _cast(x): "Attempt to interpret x with the correct type." try: if x in CAST_MAPPING_WARNING: - print("Did you mean {}?".format(CAST_MAPPING_WARNING[x], file=sys.stderr)) + print("Did you mean {}?".format(CAST_MAPPING_WARNING[x]), file=sys.stderr) return CAST_MAPPING[x] except KeyError: try: From 6fa5657c052df04fca7d24428fcb114eab908099 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Fri, 27 Mar 2020 22:07:26 -0500 Subject: [PATCH 08/15] Add type ignores. --- signac/common/host.py | 2 +- signac/contrib/indexing.py | 2 +- signac/core/h5store.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/signac/common/host.py b/signac/common/host.py index 299f4bd0f..c131ccfd1 100644 --- a/signac/common/host.py +++ b/signac/common/host.py @@ -17,7 +17,7 @@ SESSION_PASSWORD_HASH_CACHE = SimpleKeyring() -SESSION_USERNAME_CACHE = dict() +SESSION_USERNAME_CACHE = dict() # type: ignore """ THIS MODULE IS DEPRECATED! diff --git a/signac/contrib/indexing.py b/signac/contrib/indexing.py index 0f125bfed..611264cbb 100644 --- a/signac/contrib/indexing.py +++ b/signac/contrib/indexing.py @@ -159,7 +159,7 @@ class RegexFileCrawler(BaseCrawler): MyCrawler.define('.*\/a_(?P\d+)\.txt', 'TextFile') """ "Mapping of compiled regex objects and associated formats." - definitions = dict() + definitions = dict() # type: ignore @classmethod @deprecated(deprecated_in="1.3", removed_in="2.0", current_version=__version__, diff --git a/signac/core/h5store.py b/signac/core/h5store.py index 0171e53dc..e41d02581 100644 --- a/signac/core/h5store.py +++ b/signac/core/h5store.py @@ -507,8 +507,8 @@ class H5StoreManager(DictManager): :param prefix: The directory prefix shared by all stores managed by this class. """ - cls = H5Store - suffix = '.h5' + cls = H5Store # type: ignore + suffix = '.h5' # type: ignore @staticmethod def _validate_key(key): From fdc5d2971a88fa3346817e29a3bf42b0d7c6f44d Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Fri, 27 Mar 2020 22:07:35 -0500 Subject: [PATCH 09/15] Remove unused format argument. --- signac/contrib/project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signac/contrib/project.py b/signac/contrib/project.py index 105c0cc09..00be65260 100644 --- a/signac/contrib/project.py +++ b/signac/contrib/project.py @@ -1195,7 +1195,7 @@ def check(self): if corrupted: logger.error( "At least one job appears to be corrupted. Call Project.repair() " - "to try to fix errors.".format(len(corrupted))) + "to try to fix errors.") raise JobsCorruptedError(corrupted) def repair(self, fn_statepoints=None, index=None, job_ids=None): From 9797582347344afc085ee4f6032e650713048bfe Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Fri, 27 Mar 2020 22:08:32 -0500 Subject: [PATCH 10/15] Ignore errors in custom logging level. --- signac/syncutil.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/signac/syncutil.py b/signac/syncutil.py index 5abc26045..1c8161e32 100644 --- a/signac/syncutil.py +++ b/signac/syncutil.py @@ -11,14 +11,14 @@ logger = logging.getLogger('sync') logging.addLevelName(LEVEL_MORE, 'MORE') -logging.MORE = LEVEL_MORE +logging.MORE = LEVEL_MORE # type: ignore def log_more(msg, *args, **kwargs): logger.log(LEVEL_MORE, msg, *args, **kwargs) -logger.more = log_more +logger.more = log_more # type: ignore def copytree(src, dst, copy_function=shutil.copy2, symlinks=False): From 8a0417a1e31d690174174f4114761e61691d9640 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Fri, 27 Mar 2020 22:11:43 -0500 Subject: [PATCH 11/15] Run mypy on . instead of just signac package. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4e2041b08..3173764d7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,7 +34,7 @@ jobs: - run: name: style-check-type-hints command: | - mypy -p signac + mypy . linux-python-38: &linux-template docker: From ba49a255fb3e959476eb35c9e0a01d8442b88c8c Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Fri, 27 Mar 2020 22:47:26 -0500 Subject: [PATCH 12/15] Update changelog. --- changelog.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/changelog.txt b/changelog.txt index 8d555db16..dae415e26 100644 --- a/changelog.txt +++ b/changelog.txt @@ -10,6 +10,14 @@ Version 1 next ---- +Added ++++++ + +- Type annotations are validated during continuous integration (#313). + +Fixed ++++++ + - Fix the ``signac config verify`` command (previously broken) (#301, #302). [1.4.0] -- 2020-02-28 From 43a638766e6bef524a980342183bd7431e1b592f Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Sun, 29 Mar 2020 14:46:18 -0500 Subject: [PATCH 13/15] Rename style-check to pre-checks. --- .circleci/config.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3173764d7..4642e8c89 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,7 @@ orbs: win: circleci/windows@2.2.0 # Enables Windows executors jobs: - style-check: + pre-checks: docker: - image: circleci/python:3.8 @@ -22,17 +22,17 @@ jobs: pip install --progress-bar off --user -U flake8==3.7.1 pydocstyle==5.0.2 mypy==0.770 - run: - name: style-check-code + name: check-style command: | python -m flake8 --show-source . - run: - name: style-check-doc-strings + name: check-docstyle command: | pydocstyle - run: - name: style-check-type-hints + name: check-type-hints command: | mypy . @@ -185,25 +185,25 @@ workflows: version: 2 test: jobs: - - style-check + - pre-checks - linux-python-38: requires: - - style-check + - pre-checks - linux-python-37: requires: - - style-check + - pre-checks - linux-python-36: requires: - - style-check + - pre-checks - linux-python-35: requires: - - style-check + - pre-checks - linux-pypy-3: requires: - linux-python-36 - windows-python-38: requires: - - style-check + - pre-checks - check-metadata: filters: branches: From 48aa8becd55a10894cbaa0305a917a73f60909a1 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Sun, 29 Mar 2020 14:46:44 -0500 Subject: [PATCH 14/15] Update signac/syncutil.py Co-Authored-By: Carl Simon Adorf --- signac/syncutil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signac/syncutil.py b/signac/syncutil.py index 1c8161e32..0dab05d7d 100644 --- a/signac/syncutil.py +++ b/signac/syncutil.py @@ -53,7 +53,7 @@ def phase3(self): # Find out differences between common files self.same_files, self.diff_files, self.funny_files = xx methodmap = dict(dircmp.methodmap) - # The following line must be ignored: https://github.com/python/mypy/issues/708 + # The type check for the following line must be ignored: https://github.com/python/mypy/issues/708 methodmap['same_files'] = methodmap['diff_files'] = phase3 # type: ignore From 5f406e2ed7c31d91fe12bedd3ec4b64707f06b1f Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Sun, 29 Mar 2020 15:55:16 -0500 Subject: [PATCH 15/15] Update signac/syncutil.py --- signac/syncutil.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/signac/syncutil.py b/signac/syncutil.py index 0dab05d7d..a16d913e7 100644 --- a/signac/syncutil.py +++ b/signac/syncutil.py @@ -53,7 +53,8 @@ def phase3(self): # Find out differences between common files self.same_files, self.diff_files, self.funny_files = xx methodmap = dict(dircmp.methodmap) - # The type check for the following line must be ignored: https://github.com/python/mypy/issues/708 + # The type check for the following line must be ignored. + # See: https://github.com/python/mypy/issues/708 methodmap['same_files'] = methodmap['diff_files'] = phase3 # type: ignore