如何让Python类型检查工具识别文档字符串中的类型信息?
我正在使用一个名为client_aiohttp的内部库,该库是通过openapi-generator的python-aiohttp生成器生成的。例如Clusters类中的add_hosts方法代码如下:
# client_aiohttp/api/clusters.py class Clusters: def add_hosts(self, cluster_name, **kwargs): # noqa: E501 """add_hosts # noqa: E501 A human readable description :param cluster_name: (required) :type cluster_name: str :param body: :type body: ApiHostRefList :param async_req: Whether to execute the request asynchronously. :type async_req: bool, optional :return: Returns the result object. :rtype: ApiHostRefList """ return self.add_hosts_with_http_info(cluster_name, **kwargs) # noqa: E501
但VSCode的Pylance语言服务器和mypy无法识别文档字符串中指定的类型信息,导致无法进行正确的类型检查。我尝试寻找从文档字符串生成.pyi存根文件或启用文档字符串类型评估的工具/选项,但未找到合适方案。请问如何让类型检查器识别这些类型信息?
1. 配置类型检查器直接解析文档字符串类型
针对Pylance
在VSCode的settings.json中添加以下配置,开启文档字符串类型解析:
{ "python.analysis.useDocstringTypes": true, "python.analysis.typeCheckingMode": "strict" // 可选,启用严格类型检查模式 }
Pylance原生支持解析示例中这种reStructuredText格式的文档字符串类型定义,开启后会自动提取:param/:type节点的信息用于类型校验。
针对mypy
mypy默认不解析文档字符串类型,需启用实验性功能并指定文档格式:
在mypy.ini或pyproject.toml中添加配置:
[mypy] enable_incomplete_features = docstring-type-annotations docstring_style = restructuredtext
注意:该功能为mypy实验性特性,需使用mypy 1.0及以上版本。
2. 从生成源头添加PEP484类型注解
最彻底的解决方式是修改openapi-generator的生成参数,让它直接生成符合PEP484标准的类型注解,而非仅将类型放在文档字符串中。
生成库时添加参数--additional-properties=pythonUsePEP484TypeAnnotations=true,重新生成client_aiohttp。生成后的代码会直接包含参数和返回值的类型注解,例如:
def add_hosts(self, cluster_name: str, body: Optional[ApiHostRefList] = None, async_req: Optional[bool] = None) -> ApiHostRefList: # 方法实现
这种方式下,类型检查器无需解析文档字符串就能直接识别类型信息。
3. 手动生成包含类型的存根文件
如果无法重新生成库,可通过工具或自定义脚本从文档字符串提取类型,生成.pyi存根文件:
- 使用
docstring-parser库解析reStructuredText格式的文档字符串,提取参数类型和返回值类型,编写脚本生成对应存根。 - 示例存根文件
clusters.pyi:
from typing import Optional, Any from .models import ApiHostRefList class Clusters: def add_hosts(self, cluster_name: str, *, body: Optional[ApiHostRefList] = None, async_req: Optional[bool] = None, **kwargs: Any) -> ApiHostRefList: ...
将存根文件放在库的对应目录下,类型检查器会自动读取并使用其中的类型定义。
内容的提问来源于stack exchange,提问作者tomitheninja

