-
-
Notifications
You must be signed in to change notification settings - Fork 971
Description
After upgrading one of our projects to 4.2, our type checker had a small nervous breakdown.
In our testing suite, we have some fixtures that return an App instance, annotated as bare falcon.App. With the generics introduced in #2513 these now need to be annotated as falcon.App[falcon.Request, falcon.Response] which is slightly cumbersome.
This also applies to other things like In our case the SyncMiddleWare type which appears to have become impossible to use as it lacks a way to inject generics (we're still annotating a list of middlewares as list[falcon._typing.SyncMiddleWare] but that is just for documentation I guess.)
It looks like it is possible to make those _ReqT etc typevars have a default value of Request, which would remove the need to explicitly add those types to the annotation when referring to falcon.App with default request/response types, but that default argument is only available with Python 3.13+ so not in all versions supported by falcon.
One solution that does not require waiting for 3.13 to be baseline is to implement a version check and add these defaults only when on 3.13+, so something like
if sys.version >= (3,13):
_ExcT = TypeVar('_ExcT', bound=Exception, default=Exception)
_ReqT = TypeVar('_ReqT', bound=Request, contravariant=True, default=Request)
_RespT = TypeVar('_RespT', bound=Response, contravariant=True, default=Response)
else:
_ExcT = TypeVar('_ExcT', bound=Exception)
_ReqT = TypeVar('_ReqT', bound=Request, contravariant=True)
_RespT = TypeVar('_RespT', bound=Response, contravariant=True)
I also saw that identical typevars exist in _typing.py ; maybe it is a good idea to import them from there in app.py so they only need to be defined once -- or is there some coding style rule in place that forbids importing types marked as private?
Anyway, I'll whip up one or a bunch of PRs addressing these things.