Python:从 C 模块生成函数存根

Lor*_*rin 8 python-c-api python-3.x

我使用 Python C API 用 C/C++ 创建了一个 Python 模块。我在 setup.py 中使用 setuptools.Extension 。

它创建一个 .py 文件,该文件从某些已编译的 .pyd 文件加载 python 模块:

def __bootstrap__():
    global __bootstrap__, __loader__, __file__
    import sys, pkg_resources, imp
    __file__ = pkg_resources.resource_filename(__name__, 'zroya.cp36-win32.pyd')
    __loader__ = None; del __bootstrap__, __loader__
    imp.load_dynamic(__name__,__file__)
__bootstrap__()
Run Code Online (Sandbox Code Playgroud)

但它不会为 IDE 自动完成功能生成 python 存根。我希望所有导出的函数和类都可以从 .py 文件中可见:

def myfunction_stub(*args, **kwargs):
    """
    ... function docstring
    """
    pass
Run Code Online (Sandbox Code Playgroud)

是否可以?或者我是否必须创建一些 python“预处理器”来从 .pyd 文件加载数据并生成带有文档字符串的存根?

源代码可在github上获取。

小智 2

这个问题很旧,但由于我在研究这个问题时它没有包含答案,我想我会提供对我的案例有用的内容。

\n

我使用 c-api 开发了一个 python 模块,其结构如下:

\n
my_package/\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 docs\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 source\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package_libs\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 linux\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 win\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 amd64\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 i386\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package_src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 include\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 source\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tests\n
Run Code Online (Sandbox Code Playgroud)\n

mypy 包的 typegen 命令可以很好地生成包的存根。\n使用的步骤是首先像平常使用现有的 setup.py 一样编译包。\n然后为生成的 .pyd 或 .pyd 生成存根。 \n在我的例子中,最简单的方法是使用 pip 安装整个包,然后在整个模块上调用 Stubgen,例如:

\n
my_package/\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 docs\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 source\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package_libs\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 linux\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 win\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 amd64\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 i386\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package_src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 include\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 source\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tests\n
Run Code Online (Sandbox Code Playgroud)\n

这会生成一个my_package.pyi文件,然后可以将其包含在文件的包数据中,setup.py如下所示:

\n
pip install my_package\npip install mypy\nstubgen my_package\n
Run Code Online (Sandbox Code Playgroud)\n

我在其中包含一个空py.typed文件,让实用程序知道该包包含类型存根、生成的my_package.pyi文件和一个__init__.pyi仅包含存根导入的文件,以使它们在我的包的顶层可用,就像它们在模块中一样。

\n
.\n.\n.\nsetup(\n      .\n      .\n      .\n        package=["my_package"],\n        package_data={"my_package": ["py.typed", "my_package.pyi", "__init__.pyi"]},\n      .\n      .\n      .\n)\n\n.\n.\n.\n
Run Code Online (Sandbox Code Playgroud)\n

这对我有用,甚至在 CI 环境中也是可重现的,在 CI 环境中我们在发布包之前生成存根,这样就不需要手动更新或检查差异。

\n

最终的源存储库与添加的文件如下所示:

\n
my_package/\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 docs\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 source\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 my_package\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.pyi\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 my_package.pyi # generated by stubgen upon successful CI build in my case\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 py.typed\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package_libs\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 linux\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 win\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 amd64\n\xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 i386\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package_src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 include\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 source\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tests\n\n
Run Code Online (Sandbox Code Playgroud)\n