注意:这个答案并没有回答我的问题。它只是重申我已经读过的内容。
这应该如何运作?我读到的所有内容都与第三方库typeshed捆绑在一起并包含第三方库的存根。MyPy我已经MyPy在 virtualenv 中安装并运行,我正在尝试使用它来键入Flask代码,但我只是不明白。
我有 TypeScript 背景,我一直在寻找类似的东西,但我不明白我们应该如何将存根与MyPy. 例如我有这样的功能:
def create_app(config_name="default"):
app: Flask = Flask(__name__)
app.config.from_object(Configuration)
CORS(app)
register_extensions(app)
register_blueprints(app)
@app.route("/health")
def health_check():
return json.dumps({"status": "up"})
return app
Run Code Online (Sandbox Code Playgroud)
Flask 相当标准,但严格禁止任何设置,这会变成无法挽救的混乱。应用程序的类型是什么?我知道它typeshed 有烧瓶存根,但我不知道如何实际利用这些存根。文档typeshed说:
如果您只是使用 mypy(或 pytype 或 PyCharm),而不是开发它,则根本不需要与 typeshed 存储库进行交互:typeshed 的副本与 mypy 捆绑在一起。
所以我假设我不需要导入类型,文档也没有提到导入它们。
例如,有一个名为的存根app.pyi,但如果我像这样注释该函数:
def create_app(config_name="default") -> app:
Run Code Online (Sandbox Code Playgroud)
我得到了错误name app is not defined。如果我导入它:
from typeshed import app
Run Code Online (Sandbox Code Playgroud)
我收到错误Return type becomes any due to an unfollowed import,据我所知,这意味着不存在这样的模块typeshed或者它没有名为 的成员app。
那么我如何真正访问这些typeshed存根呢?我的最后一招是简单地克隆typeshed存储库并将mypy其指向自定义 typeshed 目录,但我真的很想以正确的方式做事。
虽然对于这个特定的实例,您可以只使用来自包本身的导入,但在某些情况下,您确实需要从typeshed注释中导入类型(在我的例子中,它尝试使用 wsgi 类型StartResponse.
这些是重要的,但只能在一个if TYPE_CHECKING:块内,如下所示:
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from _typeshed.wsgi import StartResponse
def application(environ: Dict, start_response: "StartResponse"):
# etc
Run Code Online (Sandbox Code Playgroud)
这只适用于(并且应该只需要)在mypy/typeshed/stdlib/_typeshed目录中找到的类型。