diff --git a/netcompare/check_types.py b/netcompare/check_types.py index a99c0f0..04e1ef6 100644 --- a/netcompare/check_types.py +++ b/netcompare/check_types.py @@ -146,7 +146,7 @@ def _validate(**kwargs) -> None: """Method to validate arguments.""" # reference_data = getattr(kwargs, "reference_data") - def evaluate(self, value_to_compare: Any, reference_data: Any) -> Tuple[Dict, bool]: + def evaluate(self, value_to_compare: Any, reference_data: Any) -> Tuple[Dict, bool]: # type: ignore[override] """Returns the difference between values and the boolean.""" self._validate(reference_data=reference_data) evaluation_result = diff_generator(reference_data, value_to_compare) @@ -168,7 +168,7 @@ def _validate(**kwargs) -> None: if tolerance < 0: raise ValueError(f"Tolerance value must be greater than 0. You have: {tolerance}.") - def evaluate(self, value_to_compare: Any, reference_data: Any, tolerance: int) -> Tuple[Dict, bool]: + def evaluate(self, value_to_compare: Any, reference_data: Any, tolerance: int) -> Tuple[Dict, bool]: # type: ignore[override] """Returns the difference between values and the boolean. Overwrites method in base class.""" self._validate(reference_data=reference_data, tolerance=tolerance) evaluation_result = diff_generator(reference_data, value_to_compare) @@ -223,7 +223,7 @@ def _validate(**kwargs) -> None: f"'mode' argument should be one of the following: {', '.join(mode_options)}. You have: {mode}" ) - def evaluate(self, value_to_compare: Mapping, params: Dict, mode: str) -> Tuple[Dict, bool]: + def evaluate(self, value_to_compare: Mapping, params: Dict, mode: str) -> Tuple[Dict, bool]: # type: ignore[override] """Parameter Match evaluator implementation.""" self._validate(params=params, mode=mode) # TODO: we don't use the mode? @@ -250,7 +250,7 @@ def _validate(**kwargs) -> None: if mode not in mode_options: raise ValueError(f"'mode' argument should be {mode_options}. You have: {mode}") - def evaluate(self, value_to_compare: Mapping, regex: str, mode: str) -> Tuple[Mapping, bool]: + def evaluate(self, value_to_compare: Mapping, regex: str, mode: str) -> Tuple[Dict, bool]: # type: ignore[override] """Regex Match evaluator implementation.""" self._validate(regex=regex, mode=mode) evaluation_result = regex_evaluator(value_to_compare, regex, mode) @@ -332,7 +332,7 @@ def _validate(**kwargs) -> None: f"check option all-same must have value of type bool. You have: {params_value} of type {type(params_value)}" ) - def evaluate(self, value_to_compare: Any, params: Any) -> Tuple[Dict, bool]: + def evaluate(self, value_to_compare: Any, params: Any) -> Tuple[Dict, bool]: # type: ignore[override] """Operator evaluator implementation.""" self._validate(**params) # For name consistency. diff --git a/netcompare/operator.py b/netcompare/operator.py index 1047a4e..e344305 100644 --- a/netcompare/operator.py +++ b/netcompare/operator.py @@ -15,7 +15,7 @@ def __init__(self, reference_data: Any, value_to_compare: Any) -> None: self.reference_data = reference_data self.value_to_compare = value_to_compare - def _loop_through_wrapper(self, call_ops: str) -> Tuple[bool, List]: + def _loop_through_wrapper(self, call_ops: str) -> Tuple[List, bool]: """Private wrapper method for operator evaluation based on 'operator' lib. Based on value passed to the method, the appropriate operator logic is triggered. @@ -58,7 +58,7 @@ def call_evaluation_logic(): "not_contains": operator.contains, } - result = [] + result = [] # type: List for item in self.value_to_compare: for value in item.values(): for evaluated_value in value.values(): @@ -73,10 +73,8 @@ def all_same(self) -> Tuple[bool, Any]: result = [] for item in self.value_to_compare: - for value in item.values(): - # Create a list for compare values. - list_of_values.append(value) - + # Create a list for compare values. + list_of_values.extend(iter(item.values())) for element in list_of_values: if element != list_of_values[0]: result.append(False) @@ -91,34 +89,34 @@ def all_same(self) -> Tuple[bool, Any]: return (self.value_to_compare, True) return (self.value_to_compare, False) - def contains(self) -> Tuple[bool, List]: + def contains(self) -> Tuple[List, bool]: """Contains operator caller.""" return self._loop_through_wrapper("contains") - def not_contains(self) -> Tuple[bool, List]: + def not_contains(self) -> Tuple[List, bool]: """Not contains operator caller.""" return self._loop_through_wrapper("not_contains") - def is_gt(self) -> Tuple[bool, List]: + def is_gt(self) -> Tuple[List, bool]: """Is greather than operator caller.""" return self._loop_through_wrapper(">") - def is_lt(self) -> Tuple[bool, List]: + def is_lt(self) -> Tuple[List, bool]: """Is lower than operator caller.""" return self._loop_through_wrapper("<") - def is_in(self) -> Tuple[bool, List]: + def is_in(self) -> Tuple[List, bool]: """Is in operator caller.""" return self._loop_through_wrapper("is_in") - def not_in(self) -> Tuple[bool, List]: + def not_in(self) -> Tuple[List, bool]: """Is not in operator caller.""" return self._loop_through_wrapper("not_in") - def in_range(self) -> Tuple[bool, List]: + def in_range(self) -> Tuple[List, bool]: """Is in range operator caller.""" return self._loop_through_wrapper("in_range") - def not_range(self) -> Tuple[bool, List]: + def not_range(self) -> Tuple[List, bool]: """Is not in range operator caller.""" return self._loop_through_wrapper("not_range") diff --git a/netcompare/utils/diff_helpers.py b/netcompare/utils/diff_helpers.py index 18695a7..fd1b70f 100644 --- a/netcompare/utils/diff_helpers.py +++ b/netcompare/utils/diff_helpers.py @@ -2,12 +2,12 @@ import re from collections import defaultdict from functools import partial -from typing import Mapping, Dict, List +from typing import Mapping, Dict, List, DefaultDict REGEX_PATTERN_RELEVANT_KEYS = r"'([A-Za-z0-9_\./\\-]*)'" -def get_diff_iterables_items(diff_result: Mapping) -> Dict: +def get_diff_iterables_items(diff_result: Mapping) -> DefaultDict: """Helper function for diff_generator to postprocess changes reported by DeepDiff for iterables. DeepDiff iterable_items are returned when the source data is a list @@ -24,7 +24,7 @@ def get_diff_iterables_items(diff_result: Mapping) -> Dict: get_dict_keys = re.compile(r"^root((\['\w.*'\])+)\[\d+\]$") defaultdict_list = partial(defaultdict, list) - result = defaultdict(defaultdict_list) + result = defaultdict(defaultdict_list) # type: DefaultDict items_removed = diff_result.get("iterable_item_removed") if items_removed: @@ -59,7 +59,7 @@ def fix_deepdiff_key_names(obj: Mapping) -> Dict: Dict: aggregated output, for example: {'7.7.7.7': {'is_enabled': {'new_value': False, 'old_value': True}, 'is_up': {'new_value': False, 'old_value': True}}} """ - result = {} + result = {} # type: Dict for key, value in obj.items(): key_parts = re.findall(REGEX_PATTERN_RELEVANT_KEYS, key) if not key_parts: # If key parts can't be find, keep original key so data is not lost. diff --git a/poetry.lock b/poetry.lock index 8c907b0..e0afc00 100644 --- a/poetry.lock +++ b/poetry.lock @@ -142,17 +142,17 @@ graph = ["objgraph (>=1.7.2)"] [[package]] name = "flake8" -version = "3.9.2" +version = "4.0.1" description = "the modular source code checker: pep8 pyflakes and co" category = "dev" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.6" [package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +importlib-metadata = {version = "<4.3", markers = "python_version < \"3.8\""} mccabe = ">=0.6.0,<0.7.0" -pycodestyle = ">=2.7.0,<2.8.0" -pyflakes = ">=2.3.0,<2.4.0" +pycodestyle = ">=2.8.0,<2.9.0" +pyflakes = ">=2.4.0,<2.5.0" [[package]] name = "gitdb" @@ -187,20 +187,19 @@ python-versions = ">=3.5" [[package]] name = "importlib-metadata" -version = "4.11.4" +version = "4.2.0" description = "Read metadata from Python packages" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.6" [package.dependencies] typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] -perf = ["ipython"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" @@ -358,11 +357,11 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pycodestyle" -version = "2.7.0" +version = "2.8.0" description = "Python style guide checker" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pydocstyle" @@ -380,7 +379,7 @@ toml = ["toml"] [[package]] name = "pyflakes" -version = "2.3.1" +version = "2.4.0" description = "passive checker of Python programs" category = "dev" optional = false @@ -667,8 +666,8 @@ dill = [ {file = "dill-0.3.5.1.tar.gz", hash = "sha256:d75e41f3eff1eee599d738e76ba8f4ad98ea229db8b085318aa2b3333a208c86"}, ] flake8 = [ - {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, - {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, + {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, + {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"}, ] gitdb = [ {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"}, @@ -683,8 +682,8 @@ idna = [ {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.11.4-py3-none-any.whl", hash = "sha256:c58c8eb8a762858f49e18436ff552e83914778e50e9d2f1660535ffb364552ec"}, - {file = "importlib_metadata-4.11.4.tar.gz", hash = "sha256:5d26852efe48c0a32b0509ffbc583fda1a2266545a78d104a6f4aff3db17d700"}, + {file = "importlib_metadata-4.2.0-py3-none-any.whl", hash = "sha256:057e92c15bc8d9e8109738a48db0ccb31b4d9d5cfbee5a8670879a30be66304b"}, + {file = "importlib_metadata-4.2.0.tar.gz", hash = "sha256:b7e52a1f8dec14a75ea73e0891f3060099ca1d8e6a462a4dff11c3e119ea1b31"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -803,16 +802,16 @@ py = [ {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pycodestyle = [ - {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, - {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, + {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"}, + {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"}, ] pydocstyle = [ {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"}, {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"}, ] pyflakes = [ - {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, - {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, + {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"}, + {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, ] pylint = [ {file = "pylint-2.13.9-py3-none-any.whl", hash = "sha256:705c620d388035bdd9ff8b44c5bcdd235bfb49d276d488dd2c8ff1736aa42526"}, diff --git a/pyproject.toml b/pyproject.toml index 0bd1ca5..400c9e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -107,3 +107,19 @@ testpaths = [ "tests" ] addopts = "-vv --doctest-modules" + +[tool.mypy] +exclude = [ + '^tasks\.py', +] + +[[tool.mypy.overrides]] +module = [ + "deepdiff", + "jmespath", +] +ignore_missing_imports = true + +[[tool.mypy.overrides]] +module = "tests.*" +ignore_errors = true diff --git a/tasks.py b/tasks.py index 08917b8..3d05546 100644 --- a/tasks.py +++ b/tasks.py @@ -172,5 +172,5 @@ def tests(context, path=".", local=INVOKE_LOCAL): pydocstyle(context, path, local) bandit(context, path, local) pytest(context, local) - # mypy(context, local) + mypy(context, path, local) print("All tests have passed!")