diff --git a/copier.yml b/copier.yml
index 8398b862..e57a7fad 100644
--- a/copier.yml
+++ b/copier.yml
@@ -62,6 +62,15 @@ use_isort:
no: false
when: "{{ custom_install }}"
+mypy_type_checking:
+ help: Would you like to include mypy to perform static type checking for type hints?
+ type: str
+ default: none
+ choices:
+ No type checking: none
+ Add basic type checking for code that has type hints: basic
+ Add strict type checking to enforce that type hints are used: strict
+
create_example_module:
help: Do you want to create some example module code?
type: bool
diff --git a/docs/source/new_project.rst b/docs/source/new_project.rst
index f2b34213..093dd6f1 100644
--- a/docs/source/new_project.rst
+++ b/docs/source/new_project.rst
@@ -34,6 +34,8 @@ Copier will ask you questions for how to set up the project. These questions wil
- A linter is a tool to automatically format for consistency (see :doc:`Linting <../practices/linting>`). We provide options for `black `_, `pylint `_, or no linter. Choosing a linter will include it as a project dependency and include it in the :doc:`pre-commit <../practices/precommit>` hooks. Defaults to ``pylint`` during simple installation.
* - *Do you want to use a tool to maintain a specific ordering for module imports?*
- `isort `_ is a tool for ordering imports in a standard order. Enabling the option will include ``isort`` as part of github's :doc:`pre-commit <../practices/precommit>`. Defaults to ``True`` during simple installation.
+ * - *Would you like to include mypy to perform static type checking for type hints?*
+ - `mypy `_ performs static type checking on python code that uses `type hints `_. This type checking makes sure that the correct data types are being used where type hints are defined. If basic or strict type checking is selected, a pre-commit hook and GitHub actions workflow that perform the type checking are added. Basic type checking performs type checks but ignores code or imports for which type hints are not written. Strict type checking enforces type hints are used by giving errors where no type hints are found.
* - *Do you want to create some example module code?*
- If this option is selected the template will create a model in ``src/{{module_name}}`` and create a corresponding example test file. Defaults to ``True`` during simple installation.
diff --git a/python-project-template/.github/workflows/{% if mypy_type_checking != 'none' %}type-checking.yml{% endif %}.jinja b/python-project-template/.github/workflows/{% if mypy_type_checking != 'none' %}type-checking.yml{% endif %}.jinja
new file mode 100644
index 00000000..aa8ce8a9
--- /dev/null
+++ b/python-project-template/.github/workflows/{% if mypy_type_checking != 'none' %}type-checking.yml{% endif %}.jinja
@@ -0,0 +1,35 @@
+# This workflow will install Python dependencies, then perform static type checking analysis.
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
+
+name: mypy Type checking
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Python 3.10
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.10'
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ python -m pip install --upgrade pip
+ pip install .
+ pip install .[dev]
+ if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+ - name: Analyze code with mypy
+{% if mypy_type_checking == 'basic' %}
+ run: |
+ mypy ./src ./tests --ignore-missing-imports
+{% elif mypy_type_checking == 'strict' %}
+ run: |
+ mypy ./src ./tests --strict
+{% endif %}
diff --git a/python-project-template/.pre-commit-config.yaml.jinja b/python-project-template/.pre-commit-config.yaml.jinja
index 6f2613a4..eb1eb37e 100644
--- a/python-project-template/.pre-commit-config.yaml.jinja
+++ b/python-project-template/.pre-commit-config.yaml.jinja
@@ -84,6 +84,25 @@ repos:
# pre-commit's default_language_version, see
# https://pre-commit.com/#top_level-default_language_version
language_version: python3.10
+{% endif %}
+{% if mypy_type_checking != 'none' %}
+ # Analyze type hints and report errors.
+ - repo: local
+ hooks:
+ - id: mypy
+ name: mypy (python files in src/ and tests/)
+ entry: mypy
+ language: system
+ types: [python]
+ files: ^(src|tests)/
+ args:
+ [
+ {% if mypy_type_checking == 'basic' %}
+ "--ignore-missing-imports", # Ignore imports without type hints
+ {% elif mypy_type_checking == 'strict' %}
+ "--strict", # Use mypy strict mode to enforce type hints
+ {% endif %}
+ ]
{% endif %}
- repo: local
hooks:
diff --git a/python-project-template/pyproject.toml.jinja b/python-project-template/pyproject.toml.jinja
index 19f0cb5f..57490136 100644
--- a/python-project-template/pyproject.toml.jinja
+++ b/python-project-template/pyproject.toml.jinja
@@ -38,6 +38,9 @@ dev = [
{%- elif preferred_linter == 'black' %}
"black", # Used for static linting of files
{%- endif %}
+{%- if mypy_type_checking != 'none' %}
+ "mypy", # Used for static type checking of files
+{%- endif %}
]
[build-system]