-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
In Flask, functions can be decorated with @app.route to register them as views that return responses. The return value of a view function can be many, many different things. In particular for this bug, the return type can be tuple[str, dict[str, str | list[str]]], where that union is defined as a separate alias.
I've reduced this down to a minimal example. Perhaps I'm doing something wrong, but it's very hard to tell if this is a problem with my annotations or with mypy. Sorry for the confusing title, it's hard to even know what's going on here to summarize.
from __future__ import annotations
import typing as t
HeaderValue = str | list[str]
# HeaderValue = t.TypeVar("HeaderValue", str, list[str])
ResponseReturnType = tuple[str, dict[str, HeaderValue]]
ViewCallable = t.Callable[..., ResponseReturnType]
RouteCallable = t.TypeVar("RouteCallable", bound=ViewCallable)
def route() -> t.Callable[[RouteCallable], RouteCallable]:
def wrapped(f: RouteCallable) -> RouteCallable:
return f
return wrapped
@route()
def view() -> tuple[str, dict[str, str]]:
return "hello", {"content-type": "text/plain"}> mypy example.py
example.py:18: error: Value of type variable "RouteCallable" of function cannot be "Callable[[], Tuple[str, Dict[str, str]]]" [type-var]
Found 1 error in 1 file (checked 1 source file)
Even though the view is annotated with a return type that matches one of the union items, mypy doesn't allow it. This is the primary bug I'm reporting. In trying to work around it, I discovered some other weird behavior.
You'll notice that an alternative TypeVar is commented out. If you switch to that definition, mypy passes. Additionally, if the view is annotated to return dict[str, str | list[str]] (the full union instead of one of the types), it still passes. Neither of these (and especially the second) behaviors seem correct. A type var is supposed to be "one of these types", and yet it's acting like a union "any combination of these types" here when the union itself isn't working.