False positive on Starlette middleware registration
Summary
Register any FastAPI middleware, custom or built-in:
app = FastAPI()
app.add_middleware(NoStoreAuthMiddleware) # custom, subclass of BaseHTTPMiddleware
app.add_middleware(RateLimitMiddleware) # custom, subclass of BaseHTTPMiddleware
app.add_middleware(
CORSMiddleware, # built-in middleware, from fastapi.middleware.cors
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
run:
ty check, without any specified rules at pyproject.toml
No issue until [email protected] (expected result) But for versions [email protected] and [email protected] (current latest):
error[invalid-argument-type]: Argument to bound method `add_middleware` is incorrect
--> main.py:31:20
|
30 | app = FastAPI(default_response_class=ORJSONResponse, lifespan=lifespan)
31 | app.add_middleware(NoStoreAuthMiddleware)
| ^^^^^^^^^^^^^^^^^^^^^ Expected `_MiddlewareFactory[Unknown]`, found `<class 'NoStoreAuthMiddleware'>`
32 | app.add_middleware(RateLimitMiddleware)
33 | app.add_middleware(ExceptionHandlerMiddleware)
|
info: Method defined here
--> .venv/lib/python3.14/site-packages/starlette/applications.py:118:9
|
116 | self.router.host(host, app=app, name=name) # pragma: no cover
117 |
118 | def add_middleware(
| ^^^^^^^^^^^^^^
119 | self,
120 | middleware_class: _MiddlewareFactory[P],
| --------------------------------------- Parameter declared here
121 | *args: P.args,
122 | **kwargs: P.kwargs,
|
info: rule `invalid-argument-type` is enabled by default
same error for all 3 middlewares registered here.
this is also mentioned at issue #1564 by @dmytro-GL here
Version
ty 0.0.1-alpha.27
Thanks for the report! It looks like _MiddlewareFactory is a protocol which is generic over a ParamSpec, so I think we should revisit this once #157 is done.
Putting this in beta milestone as I think we should ensure it's either fixed or suppressed in some way for the beta.
Update: same behaviour on 0.0.1-alpha.28
For context, this is same as https://github.com/astral-sh/ty/issues/157#issuecomment-3554317390 which is a self-contained example to reproduce this. This possibly requires #1714.
Didn't get this into the beta, but it's a high priority follow-up.
(as far as examples goes, it doesn't get much smaller than this)
#!/usr/bin/env -S uv run --with starlette==0.50.0,ty==0.0.2 ty check --
from starlette_context.middleware import RawContextMiddleware
from starlette.middleware import Middleware
Middleware(RawContextMiddleware)