From 25dbbe29e9eef47e1c7515c3b9f9c24ac7841790 Mon Sep 17 00:00:00 2001 From: Michael Manganiello Date: Sat, 17 Sep 2022 15:41:18 -0300 Subject: [PATCH] misc: Add initial support for Mypy checks (#469) This is the initial change to start adding typing hints to the project. It includes: * Adding `mypy` checks to GitHub actions, and Tox. * Adding `mypy` command to `run.sh` script. * Initial `mypy` configuration options in `setup.cfg`. * Small fixes for existing typing issues. --- .github/workflows/python-package.yml | 21 +++++++++++++++++++++ CONTRIBUTING.rst | 4 +++- requirements.txt | 1 + run.sh | 3 +++ setup.cfg | 8 ++++++++ tox.ini | 7 +++++++ waffle/jinja.py | 2 +- waffle/mixins.py | 7 ++++--- 8 files changed, 48 insertions(+), 5 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 24b21f0b..223a7ac3 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -63,6 +63,27 @@ jobs: # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + typecheck: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + - uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: ${{ matrix.python-version }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ matrix.python-version }}-pip- + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install tox-gh-actions + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Type-check + run: | + tox -e typecheck + i18n: runs-on: ubuntu-latest diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index f49c8e37..5686c179 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -61,15 +61,17 @@ To be mergable, patches must: - add tests for new code (bug fixes should include regression tests, new features should have relevant tests), - not introduce any new flake8_ errors (run ``./run.sh lint``), +- not introduce any new mypy_ errors (run ``./run.sh typecheck``), - include updated source translations (run ``./run.sh makemessages`` and ``./run.sh compilemessages``), - document any new features, and - have a `good commit message`_. Regressions tests should fail without the rest of the patch and pass -with it. +with it. .. _open a new issue: https://github.com/django-waffle/django-waffle/issues/new .. _Fork: https://github.com/django-waffle/django-waffle/fork .. _flake8: https://pypi.python.org/pypi/flake8 +.. _mypy: https://www.mypy-lang.org/ .. _good commit message: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html diff --git a/requirements.txt b/requirements.txt index 8c1ca854..277e1c3f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,5 @@ transifex-client flake8 mock==1.3.0 +mypy tox diff --git a/run.sh b/run.sh index 99fe47b3..36c86ec1 100755 --- a/run.sh +++ b/run.sh @@ -7,6 +7,7 @@ usage() { echo "USAGE: $0 [command]" echo " test - run the waffle tests" echo " lint - run flake8" + echo " typecheck - run mypy" echo " shell - open the Django shell" echo " makemigrations - create a schema migration" exit 1 @@ -20,6 +21,8 @@ case "$CMD" in DJANGO_SETTINGS_MODULE=test_settings django-admin test waffle $@ ;; "lint" ) flake8 waffle $@ ;; + "typecheck" ) + mypy waffle $@ ;; "shell" ) django-admin shell $@ ;; "makemigrations" ) diff --git a/setup.cfg b/setup.cfg index 5840e7ac..dc57f6af 100644 --- a/setup.cfg +++ b/setup.cfg @@ -6,3 +6,11 @@ max-line-length = 120 # - docs: contains autogenerated code that doesn't need a check exclude = */migrations/*,docs ignore = E731 + +[mypy] +python_version = 3.7 +disallow_incomplete_defs = True +disallow_untyped_decorators = True +strict_equality = True +[mypy-django.*] +ignore_missing_imports = True diff --git a/tox.ini b/tox.ini index 28ef9c7f..1312dfb3 100644 --- a/tox.ini +++ b/tox.ini @@ -28,3 +28,10 @@ commands = ./run.sh makemessages ./run.sh compilemessages ./run.sh find_uncommitted_translations + +[testenv:typecheck] +deps = + Django>=3.2,<4.2 + -r{toxinidir}/requirements.txt +commands = + ./run.sh typecheck diff --git a/waffle/jinja.py b/waffle/jinja.py index 9ae7c347..2e0ba413 100644 --- a/waffle/jinja.py +++ b/waffle/jinja.py @@ -8,7 +8,7 @@ from jinja2 import pass_context except ImportError: # NOTE: We can get rid of this when we stop supporting Jinja2 < 3. - from jinja2 import contextfunction as pass_context + from jinja2 import contextfunction as pass_context # type: ignore @pass_context diff --git a/waffle/mixins.py b/waffle/mixins.py index 590aa524..a42ef7da 100644 --- a/waffle/mixins.py +++ b/waffle/mixins.py @@ -1,4 +1,5 @@ from functools import partial +from typing import Optional from django.http import Http404 @@ -24,7 +25,7 @@ class WaffleFlagMixin(BaseWaffleMixin): waffle_flag """ - waffle_flag = None + waffle_flag: Optional[str] = None def dispatch(self, request, *args, **kwargs): func = partial(flag_is_active, request) @@ -42,7 +43,7 @@ class WaffleSampleMixin(BaseWaffleMixin): waffle_sample. """ - waffle_sample = None + waffle_sample: Optional[str] = None def dispatch(self, request, *args, **kwargs): active = self.validate_waffle(self.waffle_sample, sample_is_active) @@ -59,7 +60,7 @@ class WaffleSwitchMixin(BaseWaffleMixin): waffle_switch. """ - waffle_switch = None + waffle_switch: Optional[str] = None def dispatch(self, request, *args, **kwargs): active = self.validate_waffle(self.waffle_switch, switch_is_active)