diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml new file mode 100644 index 000000000..1a641edd2 --- /dev/null +++ b/.github/workflows/mypy.yml @@ -0,0 +1,50 @@ +name: Mypy + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.9 + uses: actions/setup-python@v4 + with: + python-version: 3.9 + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Analysing the code with mypy + env: + SECRET_KEY: beepbeep + DEBUG: false + USE_HTTPS: true + DOMAIN: your.domain.here + BOOKWYRM_DATABASE_BACKEND: postgres + MEDIA_ROOT: images/ + POSTGRES_PASSWORD: hunter2 + POSTGRES_USER: postgres + POSTGRES_DB: github_actions + POSTGRES_HOST: 127.0.0.1 + CELERY_BROKER: "" + REDIS_BROKER_PORT: 6379 + REDIS_BROKER_PASSWORD: beep + USE_DUMMY_CACHE: true + FLOWER_PORT: 8888 + EMAIL_HOST: "smtp.mailgun.org" + EMAIL_PORT: 587 + EMAIL_HOST_USER: "" + EMAIL_HOST_PASSWORD: "" + EMAIL_USE_TLS: true + ENABLE_PREVIEW_IMAGES: false + ENABLE_THUMBNAIL_GENERATION: true + HTTP_X_FORWARDED_PROTO: false + run: | + mypy bookwyrm celerywyrm diff --git a/bookwyrm/telemetry/open_telemetry.py b/bookwyrm/telemetry/open_telemetry.py index 00b24d4b0..2a0168ff3 100644 --- a/bookwyrm/telemetry/open_telemetry.py +++ b/bookwyrm/telemetry/open_telemetry.py @@ -1,6 +1,6 @@ from opentelemetry import trace from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter -from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace import TracerProvider, Tracer from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter from bookwyrm import settings @@ -16,19 +16,19 @@ elif settings.OTEL_EXPORTER_OTLP_ENDPOINT: ) -def instrumentDjango(): +def instrumentDjango() -> None: from opentelemetry.instrumentation.django import DjangoInstrumentor DjangoInstrumentor().instrument() -def instrumentPostgres(): +def instrumentPostgres() -> None: from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor Psycopg2Instrumentor().instrument() -def instrumentCelery(): +def instrumentCelery() -> None: from opentelemetry.instrumentation.celery import CeleryInstrumentor from celery.signals import worker_process_init @@ -37,5 +37,5 @@ def instrumentCelery(): CeleryInstrumentor().instrument() -def tracer(): +def tracer() -> Tracer: return trace.get_tracer(__name__) diff --git a/bw-dev b/bw-dev index df88b06c6..3b30d901b 100755 --- a/bw-dev +++ b/bw-dev @@ -209,6 +209,10 @@ case "$CMD" in bookwyrm/static/css/bookwyrm.scss bookwyrm/static/css/bookwyrm/**/*.scss --fix \ --config dev-tools/.stylelintrc.js ;; + mypy) + prod_error + runweb mypy celerywyrm bookwyrm + ;; collectstatic_watch) prod_error npm run --prefix dev-tools watch:static @@ -316,6 +320,7 @@ case "$CMD" in echo " eslint" echo " stylelint" echo " formatters" + echo " mypy" echo " collectstatic_watch" echo " populate_streams [--stream=]" echo " populate_lists_streams" diff --git a/celerywyrm/apps.py b/celerywyrm/apps.py index bf443afdb..fac1c6e78 100644 --- a/celerywyrm/apps.py +++ b/celerywyrm/apps.py @@ -6,7 +6,7 @@ class CelerywyrmConfig(AppConfig): name = "celerywyrm" verbose_name = "BookWyrm Celery" - def ready(self): + def ready(self) -> None: if settings.OTEL_EXPORTER_OTLP_ENDPOINT or settings.OTEL_EXPORTER_CONSOLE: from bookwyrm.telemetry import open_telemetry diff --git a/celerywyrm/settings.py b/celerywyrm/settings.py index aa08a2417..20f194a12 100644 --- a/celerywyrm/settings.py +++ b/celerywyrm/settings.py @@ -6,7 +6,7 @@ from bookwyrm.settings import * QUERY_TIMEOUT = env.int("CELERY_QUERY_TIMEOUT", env.int("QUERY_TIMEOUT", 30)) # pylint: disable=line-too-long -REDIS_BROKER_PASSWORD = requests.utils.quote(env("REDIS_BROKER_PASSWORD", "")) +REDIS_BROKER_PASSWORD = requests.compat.quote(env("REDIS_BROKER_PASSWORD", "")) REDIS_BROKER_HOST = env("REDIS_BROKER_HOST", "redis_broker") REDIS_BROKER_PORT = env.int("REDIS_BROKER_PORT", 6379) REDIS_BROKER_DB_INDEX = env.int("REDIS_BROKER_DB_INDEX", 0) diff --git a/complete_bwdev.fish b/complete_bwdev.fish index 61a8fb3b2..f700dee1b 100644 --- a/complete_bwdev.fish +++ b/complete_bwdev.fish @@ -26,6 +26,7 @@ prettier \ eslint \ stylelint \ formatters \ +mypy \ collectstatic_watch \ populate_streams \ populate_lists_streams \ diff --git a/complete_bwdev.sh b/complete_bwdev.sh index 749737564..c3f705ffc 100644 --- a/complete_bwdev.sh +++ b/complete_bwdev.sh @@ -23,6 +23,7 @@ prettier eslint stylelint formatters +mypy collectstatic_watch populate_streams populate_lists_streams diff --git a/complete_bwdev.zsh b/complete_bwdev.zsh index 26ff6a553..72e9654ac 100644 --- a/complete_bwdev.zsh +++ b/complete_bwdev.zsh @@ -25,6 +25,7 @@ prettier eslint stylelint formatters +mypy collectstatic_watch populate_streams populate_lists_streams diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 000000000..39f6863fe --- /dev/null +++ b/mypy.ini @@ -0,0 +1,15 @@ +[mypy] +plugins = mypy_django_plugin.main +namespace_packages = True +strict = True + +[mypy.plugins.django-stubs] +django_settings_module = "bookwyrm.settings" + +[mypy-bookwyrm.*] +ignore_errors = True +implicit_reexport = True + +[mypy-celerywyrm.*] +ignore_errors = False + diff --git a/requirements.txt b/requirements.txt index 755d3e0ac..e8328b170 100644 --- a/requirements.txt +++ b/requirements.txt @@ -43,3 +43,13 @@ pytest-env==0.6.2 pytest-xdist==2.3.0 pytidylib==0.3.2 pylint==2.14.0 +mypy==1.4.1 +celery-types==0.18.0 +django-stubs[compatible-mypy]==4.2.3 +types-bleach==6.0.0.3 +types-dataclasses==0.6.6 +types-Markdown==3.4.2.9 +types-Pillow==10.0.0.1 +types-psycopg2==2.9.21.10 +types-python-dateutil==2.8.19.13 +types-requests==2.31.0.1