导入模块的 Python 类型提示

I'l*_*Hat 8 python type-hinting pycharm flask python-3.7

我发现,对瓶自动完成有点欠缺-这是因为在内部,上下文特定的对象,如current_apprequestlogger实际上LocalProxy秒。因此 PyCharm 不知道如何处理这种类型。

所以对我来说,显而易见的解决方案是在导入的模块上应用类型提示。除非你不能这样做!从 Python 3.7 开始,似乎没有这样的语法来促进这一点。

因此,下一个显而易见的解决方案是使用显式设置的类型制作每个特定于上下文的模块的本地副本,如下所示:

from logging import Logger
from flask import Flask, Request, Blueprint, request, current_app as app

app: Flask = app
logger: Logger = app.logger
request: Request = request
Run Code Online (Sandbox Code Playgroud)

...在您实际尝试启动服务器之前一直有效,在这种情况下,应用程序因以下原因崩溃 RuntimeError: Working outside of application context.

事实证明,我们实际上可以将相关类型提示封装在应用程序上下文内的类或其他范围内。

@foo_blueprint.route('/foo', methods=['GET'])
def foo(cls):
    _app: Flask = app
    _logger: Logger = app.logger
    _request: Request = request
    # ...
Run Code Online (Sandbox Code Playgroud)

...这有效,但在任何可以想象的意义上都非常尴尬。

是否有合理的解决方案可以在 Flask 的应用程序上下文中获取正确的类型提示?

Chr*_*ert 3

2022 年更新

从Flask 版本 2.0.0开始,类型提示现在内置于库中。(参见拉取请求#3973

Flask 2.0.0 之前的版本

对于旧版本的 Flask,一种解决方法是使用类型转换,如下所示:

from typing import cast

from flask import request
from flask import Request
from flask import Response


@app.route('/')
def index() -> Response:
    # Can't use `assert isinstance(request, Request)`, since `request` is `LocalProxy` object.
    global request
    request = cast(Request, request)

    token = request.headers.get('authorization')
    ... 
    return 'API is working', 200
Run Code Online (Sandbox Code Playgroud)