sanic-org / sanic

Accelerate your web app development | Build fast. Run fast.
https://sanic.dev
MIT License
18.01k stars 1.54k forks source link

Improve type of `MiddlewareType` #2753

Closed guacs closed 1 year ago

guacs commented 1 year ago

Is there an existing issue for this?

Is your feature request related to a problem? Please describe.

When using a custom Request class and type hinting the middleware with that custom Request class, type checkers complain that the argument types of the middleware function is invalid.


from sanic import Request, Sanic

class MyRequest(Request):
    ...

async def some_middleware(request: MyRequest) -> None:
    ...

app = Sanic("trial-app")

# This raises a type error.
app.register_middleware(some_middleware, "request")

# Pyright Error
# Argument of type "(request: MyRequest) -> Coroutine[Any, Any, None]" cannot be assigned to parameter
# "middleware" of type "MiddlewareType | Middleware" in function "register_middleware"
# Type "(request: MyRequest) -> Coroutine[Any, Any, None]" cannot be assigned to type "MiddlewareType | Middleware"
#  Type "(request: MyRequest) -> Coroutine[Any, Any, None]" cannot be assigned to type "RequestMiddlewareType"
#      Parameter 1: type "Request" cannot be assigned to type "MyRequest"
#        "Request" is incompatible with "MyRequest"
#    Type "(request: MyRequest) -> Coroutine[Any, Any, None]" cannot be assigned to type "ResponseMiddlewareType"
#      Function accepts too many positional parameters; expected 1 but received 2
#        Parameter 1: type "Request" cannot be assigned to type "MyRequest"
#          "Request" is incompatible with "MyRequest"

Describe the solution you'd like

Using a subclass of Request shouldn't raise this error by the type checkers.

Additional context

I think the fix is to make the Request type in MiddlewareType in handler_types a generic with the generic being bound to Request like it's done for the Sanic type.

ahopkins commented 1 year ago

Thanks. Do you think you can create the PR for this? 😎

guacs commented 1 year ago

Yeah I would love to. I'll get it ready in a day or two.