Skip to content

typing changes in 4.2 require code changes #2586

@jap

Description

@jap

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions