如何在pip包中分发pythonnet的DLL类型信息?
问题:PythonNet加载C# DLL后,打包pip包时类型存根无法被解释器识别
问题背景
- 已通过PythonNet加载C# DLL,核心代码如下:
from importlib.resources import path import sys with path('pyrp.lib', '') as lib_path: sys.path.append(str(lib_path)) from pythonnet import load load('coreclr') import clr def load_APIStandard(): clr.AddReference("myDLL") from myDLL import APIStandard return APIStandard - 使用pythonnet-stub-generator生成了类型存根,示例存根文件
__init__.pyi内容:from System import Array_1 from myDLL import AnalysisResult class APIStandard(abc.ABC): @staticmethod def AnalyzeData(data: Array_1[int]) -> AnalysisResult: ... - 本地开发时,在VSCode的
settings.json中添加"python.analysis.extraPaths": ["./pyrp/lib/PythonTypes"]后,类型提示正常,但将类型存根打包到pip包后,解释器无法自动识别这些类型信息。
解决方案建议
1. 调整存根文件的目录结构与包打包配置
- 将生成的
.pyi存根文件移至对应Python包的同目录下(比如pyrp/lib/文件夹内),而非单独的PythonTypes目录,确保存根与加载DLL的代码处于同一命名空间。 - 在打包配置文件中明确包含存根文件:
- 若使用
setup.py,添加package_data配置:setup( # 其他包配置信息 package_data={ "pyrp.lib": ["*.pyi"] }, include_package_data=True ) - 若使用
pyproject.toml(推荐),添加如下配置:[tool.setuptools.package-data] "pyrp.lib" = ["*.pyi"]
- 若使用
2. 遵循Python类型存根查找规则
- Python解释器优先匹配与模块同名的
.pyi文件,或typings目录下的对应结构。可在包根目录创建typings文件夹,按包结构存放存根(如typings/pyrp/lib/__init__.pyi),并在pyproject.toml中配置:[tool.setuptools.data-files] "typings/pyrp/lib" = ["typings/pyrp/lib/*.pyi"] - 若上述方法无效,可在包的
__init__.py中临时将存根目录加入sys.path(兜底方案):import sys from importlib.resources import path with path('pyrp.lib', 'typings') as typings_path: sys.path.append(str(typings_path))
3. 验证存根文件的正确性
- 确保存根文件名与导入的模块名完全匹配:例如代码中
from myDLL import APIStandard,对应的存根应为myDLL.pyi。 - 检查存根内的类型引用:比如
Array_1[int]需确保Python类型检查器可识别,必要时替换为标准Python类型(如list[int]),或确保System相关类型的存根也被正确打包。
4. 配置VSCode的全局/工作区设置(针对安装后的包)
- 若安装打包后的包后VSCode仍无法识别类型,需在
settings.json中添加包安装路径下的存根目录到python.analysis.extraPaths,或切换VSCode的Python解释器为已安装该包的环境,让其自动读取包内的存根信息。
内容的提问来源于stack exchange,提问作者joshp
相关产品推荐
相关产品推荐

