1

我正在努力使用 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 问题?

谢谢!

4

0 回答 0