我正在努力使用 Pyright 进行严格的类型检查,但我遇到了 Flask 错误处理程序的问题。我对类型提示还不够熟悉,无法知道这是否是我的代码、Pyright 或 Flask 的类型提示中的错误。
这是引起我问题的代码:
from werkzeug.exceptions import NotFound
def init_app(app: Flask):
app.register_error_handler(NotFound, page_not_found_handler)
def page_not_found_handler(e: Exception):
return render_template("404.html"), 404
上面的代码在 VSCode 中生成了这种类型的错误:
Argument of type "(e: Exception) -> tuple[str, Literal[404]]" cannot be assigned to parameter "f" of type "ErrorHandlerCallable" in function "register_error_handler"
Type "(e: Exception) -> tuple[str, Literal[404]]" cannot be assigned to type "ErrorHandlerCallable"
Function return type "tuple[str, Literal[404]]" is incompatible with type "ResponseReturnValue[Unknown]"
Type "tuple[str, Literal[404]]" cannot be assigned to type "ResponseReturnValue[Unknown]"
"tuple[str, Literal[404]]" is incompatible with "Response"
Type "tuple[str, Literal[404]]" cannot be assigned to type "AnyStr@ResponseValue"
"tuple[str, Literal[404]]" is incompatible with "Dict[str, Any]"
"tuple[str, Literal[404]]" is incompatible with "Generator[AnyStr@ResponseValue, None, None]"
Tuple entry 1 is incorrect typePylancereportGeneralTypeIssues
我可以通过向我的错误处理程序添加显式返回类型来改进问题:
def page_not_found_handler(e: Exception) -> flask.typing.ResponseReturnValue:
....
这将删除先前的错误并将其替换为以下错误:
Expression of type "tuple[str, Literal[404]]" cannot be assigned to return type "ResponseReturnValue[Unknown]"
Type "tuple[str, Literal[404]]" cannot be assigned to type "ResponseReturnValue[Unknown]"
"tuple[str, Literal[404]]" is incompatible with "Response"
Type "tuple[str, Literal[404]]" cannot be assigned to type "AnyStr@ResponseValue"
"tuple[str, Literal[404]]" is incompatible with "Dict[str, Any]"
"tuple[str, Literal[404]]" is incompatible with "Generator[AnyStr@ResponseValue, None, None]"
Tuple entry 1 is incorrect type
Type "str" cannot be assigned to type "ResponseValue[Unknown]"
"str" is incompatible with "Response"
所以我查看了 flask.typing.ResponseValue 类型。它是这样定义的联合类型:
# The possible types that are directly convertible or are a Response object.
ResponseValue = t.Union[
"Response",
t.AnyStr,
t.Dict[str, t.Any], # any jsonify-able dict
t.Generator[t.AnyStr, None, None],
]
作为一个实验,我flask.typing
在我的虚拟环境中修改了版本并添加str
了可能的值。这消除了所有错误。
为什么 str 和 AnyStr 在这里不兼容?在我看来, AnyStr 应该能够接受 str 值。
如果这不是我的代码的问题,是 Flask 还是 Pyright 问题?
谢谢!