From 398f4a455f0d65c0a6f05561415bdbd8133edfb1 Mon Sep 17 00:00:00 2001
From: Daniel <d.hornung@indiscale.com>
Date: Mon, 17 Jun 2024 11:28:48 +0200
Subject: [PATCH] MAINT: Typing

---
 Makefile                                             | 12 ++++++++----
 setup.cfg                                            |  6 ++++++
 .../serverside/examples/example_script.py            |  4 ++--
 unittests/table_json_conversion/create_jsonschema.py |  3 ++-
 unittests/table_json_conversion/test_fill_xlsx.py    |  3 ++-
 unittests/table_json_conversion/test_read_xlsx.py    | 12 +++++-------
 .../test_table_template_generator.py                 |  6 ++++--
 unittests/table_json_conversion/utils.py             |  6 +++---
 unittests/test_cfood.py                              |  2 +-
 9 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/Makefile b/Makefile
index 26f5c818..88fe5405 100644
--- a/Makefile
+++ b/Makefile
@@ -35,11 +35,15 @@ install:
 unittest:
 	pytest-3 unittests
 
+lint:
+	pylint --unsafe-load-any-extension=y --fail-under=9.72 -d R,C --ignore=swagger_client src/caosadvancedtools
+.PHONY: lint
+
+typing:
+	mypy src unittests
+	mypy integrationtests
+
 style:
 	pycodestyle --count --exclude=swagger_client src unittests
 	autopep8 -ar --diff --exit-code --exclude swagger_client src unittests
 .PHONY: style
-
-lint:
-	pylint --unsafe-load-any-extension=y --fail-under=9.72 -d R,C --ignore=swagger_client src/caosadvancedtools
-.PHONY: lint
diff --git a/setup.cfg b/setup.cfg
index 74c5620b..021733bd 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,2 +1,8 @@
 [pycodestyle]
 ignore=E501,E121,E123,E126,E226,E24,E704,W503,W504
+
+[mypy]
+ignore_missing_imports = True
+exclude = (?x)(
+    /extroot/    # Integration test data
+  )
\ No newline at end of file
diff --git a/src/caosadvancedtools/serverside/examples/example_script.py b/src/caosadvancedtools/serverside/examples/example_script.py
index d97d2d0d..138354c8 100755
--- a/src/caosadvancedtools/serverside/examples/example_script.py
+++ b/src/caosadvancedtools/serverside/examples/example_script.py
@@ -50,7 +50,7 @@ import matplotlib.pyplot as plt
 import numpy as np
 from caosadvancedtools.cfood import assure_property_is
 from caosadvancedtools.crawler import apply_list_of_updates
-from caosadvancedtools.guard import INSERT, UPDATE
+from caosadvancedtools.guard import UPDATE
 from caosadvancedtools.guard import global_guard as guard
 from caosadvancedtools.serverside.helper import send_mail as main_send_mail
 
@@ -62,7 +62,7 @@ logger = logging.getLogger(__name__)
 guard.set_level(level=UPDATE)
 
 
-def send_mail(changes: [db.Entity], receipient: str):
+def send_mail(changes: list[db.Entity], receipient: str):
     """ calls sendmail in order to send a mail to the curator about pending
     changes
 
diff --git a/unittests/table_json_conversion/create_jsonschema.py b/unittests/table_json_conversion/create_jsonschema.py
index 8ab4ad2d..4efd6bb2 100755
--- a/unittests/table_json_conversion/create_jsonschema.py
+++ b/unittests/table_json_conversion/create_jsonschema.py
@@ -24,6 +24,7 @@ from __future__ import annotations
 
 import argparse
 import json
+from typing import Optional
 
 import caosadvancedtools.json_schema_exporter as jsex
 from caosadvancedtools.models import parser
@@ -31,7 +32,7 @@ from caosadvancedtools.models import parser
 
 
 def prepare_datamodel(modelfile, recordtypes: list[str], outfile: str,
-                      do_not_create: list[str] = None):
+                      do_not_create: Optional[list[str]] = None):
     if do_not_create is None:
         do_not_create = []
     model = parser.parse_model_from_yaml(modelfile)
diff --git a/unittests/table_json_conversion/test_fill_xlsx.py b/unittests/table_json_conversion/test_fill_xlsx.py
index 899bb81e..7e9a79c6 100644
--- a/unittests/table_json_conversion/test_fill_xlsx.py
+++ b/unittests/table_json_conversion/test_fill_xlsx.py
@@ -24,6 +24,7 @@ import json
 import os
 import re
 import tempfile
+from typing import Optional
 
 import jsonschema.exceptions as schema_exc
 import pytest
@@ -49,7 +50,7 @@ def rfp(*pathcomponents):
 
 
 def fill_and_compare(json_file: str, template_file: str, known_good: str,
-                     schema: str = None, custom_output: str = None):
+                     schema: Optional[str] = None, custom_output: Optional[str] = None):
     """Fill the data into a template and compare to a known good.
 
 Parameters:
diff --git a/unittests/table_json_conversion/test_read_xlsx.py b/unittests/table_json_conversion/test_read_xlsx.py
index 0eec2e9c..17574d8a 100644
--- a/unittests/table_json_conversion/test_read_xlsx.py
+++ b/unittests/table_json_conversion/test_read_xlsx.py
@@ -20,17 +20,15 @@
 """Testing the conversion from XLSX to JSON"""
 
 
+from .utils import assert_equal_jsons
+from caosadvancedtools.table_json_conversion import convert
+import pytest
 import datetime
 import json
 import os
 import re
-
 from types import SimpleNamespace
-
-import pytest
-from caosadvancedtools.table_json_conversion import convert
-
-from .utils import assert_equal_jsons
+from typing import Optional
 
 
 def rfp(*pathcomponents):
@@ -40,7 +38,7 @@ def rfp(*pathcomponents):
 
 
 def convert_and_compare(xlsx_file: str, schema_file: str, known_good_file: str,
-                        known_good_data: dict = None, strict: bool = False,
+                        known_good_data: Optional[dict] = None, strict: bool = False,
                         validate: bool = True) -> dict:
     """Convert an XLSX file and compare to a known result.
 
diff --git a/unittests/table_json_conversion/test_table_template_generator.py b/unittests/table_json_conversion/test_table_template_generator.py
index d9a84dcf..24a77ddc 100644
--- a/unittests/table_json_conversion/test_table_template_generator.py
+++ b/unittests/table_json_conversion/test_table_template_generator.py
@@ -22,6 +22,7 @@
 import json
 import os
 import tempfile
+from typing import Optional
 
 import pytest
 from caosadvancedtools.table_json_conversion.table_generator import XLSXTemplateGenerator
@@ -39,8 +40,9 @@ def rfp(*pathcomponents):
     return os.path.join(os.path.dirname(__file__), *pathcomponents)
 
 
-def _compare_generated_to_known_good(schema_file: str, known_good: str, foreign_keys: dict = None,
-                                     outfile: str = None) -> tuple:
+def _compare_generated_to_known_good(schema_file: str, known_good: str,
+                                     foreign_keys: Optional[dict] = None,
+                                     outfile: Optional[str] = None) -> tuple:
     """Generate an XLSX from the schema, then compare to known good output.
 
 Returns
diff --git a/unittests/table_json_conversion/utils.py b/unittests/table_json_conversion/utils.py
index b95715f7..86f6d95f 100644
--- a/unittests/table_json_conversion/utils.py
+++ b/unittests/table_json_conversion/utils.py
@@ -21,13 +21,13 @@
 """Utilities for the tests.
 """
 
-from typing import Iterable, Union
+from typing import Iterable, Optional, Union
 
 from openpyxl import Workbook
 
 
 def assert_equal_jsons(json1, json2, allow_none: bool = True, allow_empty: bool = True,
-                       path: list = None) -> None:
+                       path: Optional[list] = None) -> None:
     """Compare two json objects for near equality.
 
 Raise an assertion exception if they are not equal."""
@@ -100,7 +100,7 @@ hidden: bool, optional
                 )
 
 
-def _is_recursively_none(obj: Union[list, dict] = None):
+def _is_recursively_none(obj: Optional[Union[list, dict]] = None):
     """Test if ``obj`` is None or recursively consists only of None-like objects."""
     if obj is None:
         return True
diff --git a/unittests/test_cfood.py b/unittests/test_cfood.py
index e2f15ffd..3332306a 100644
--- a/unittests/test_cfood.py
+++ b/unittests/test_cfood.py
@@ -85,7 +85,7 @@ class SimpleCFood(AbstractFileCFood):
 
 
 class DependendCFood(AbstractCFood):
-    existing = []
+    existing: list[DependendCFood] = []
 
     @classmethod
     def match_item(cls, item):
-- 
GitLab