diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0233a4a..f400594 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,5 +29,4 @@ jobs: - run: ruff check . - - name: mypy (advisory, not gating) - run: mypy velocix --ignore-missing-imports || true + - run: mypy velocix diff --git a/pyproject.toml b/pyproject.toml index fe5085f..e2ba789 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,6 +48,7 @@ dev = [ "ruff>=0.5.0", "black>=23.0.0", "isort>=5.12.0", + "types-aiofiles>=23.0.0", ] [tool.black] @@ -77,4 +78,11 @@ python_version = "3.11" check_untyped_defs = true warn_return_any = true warn_unused_configs = true + +# yaml (openapi/models.py, generator.py) and redis (security/base.py's +# RedisBackend) are both genuinely optional, try/except-ImportError-guarded +# integrations, not real requirements — not installed by default, so no +# blanket ignore_missing_imports for the whole codebase. +[[tool.mypy.overrides]] +module = ["yaml", "redis", "redis.*"] ignore_missing_imports = true diff --git a/requirements.txt b/requirements.txt index 81d1846..5f2e85d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,6 +13,8 @@ click>=8.1.8 xxhash>=3.6.0 itsdangerous>=2.0.0 nh3>=0.2.0 +aiofiles>=23.0.0 pytest>=7.4.0 mypy>=1.7.0 ruff>=0.5.0 +types-aiofiles>=23.0.0 diff --git a/velocix/core/app.py b/velocix/core/app.py index bf50269..e26baae 100644 --- a/velocix/core/app.py +++ b/velocix/core/app.py @@ -86,7 +86,8 @@ def _request_if_none_match( if request is not None: return request.headers.get(b"if-none-match") if scope is not None: - for k, v in scope.get("headers", []): + headers: list[tuple[bytes, bytes]] = scope.get("headers", []) + for k, v in headers: if k == b"if-none-match": return v return None @@ -974,6 +975,7 @@ async def openapi_handler(request: Request) -> Response: async def swagger_handler(request: Request) -> HTMLResponse: openapi_url = self.openapi_url + assert openapi_url is not None # guaranteed by the enclosing `if` above from velocix.openapi.generator import ( SWAGGER_CSS_SRI, SWAGGER_CSS_URL, @@ -1024,6 +1026,8 @@ async def swagger_handler(request: Request) -> HTMLResponse: if self.openapi_url and self.redoc_url: async def redoc_handler(request: Request) -> HTMLResponse: + openapi_url = self.openapi_url + assert openapi_url is not None # guaranteed by the enclosing `if` above from velocix.openapi.generator import REDOC_JS_SRI, REDOC_JS_URL js_integrity = f' integrity="{REDOC_JS_SRI}" crossorigin="anonymous"' if REDOC_JS_SRI else "" @@ -1038,7 +1042,7 @@ async def redoc_handler(request: Request) -> HTMLResponse:
-