ty icon indicating copy to clipboard operation
ty copied to clipboard

False positive on Starlette middleware registration

Open Asaf31214 opened this issue 3 months ago • 7 comments

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

Asaf31214 avatar Nov 25 '25 21:11 Asaf31214

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.

carljm avatar Nov 25 '25 21:11 carljm

Putting this in beta milestone as I think we should ensure it's either fixed or suppressed in some way for the beta.

carljm avatar Nov 25 '25 23:11 carljm

Update: same behaviour on 0.0.1-alpha.28

Asaf31214 avatar Nov 26 '25 00:11 Asaf31214

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.

dhruvmanila avatar Dec 04 '25 05:12 dhruvmanila

Didn't get this into the beta, but it's a high priority follow-up.

carljm avatar Dec 16 '25 21:12 carljm

(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)

thejcannon avatar Dec 17 '25 16:12 thejcannon