vscode 不会从使用 pybind11 制作的模块自动完成 python

cat*_*dog 6 python autocomplete visual-studio-code

我有一个名为的 python 模块relatpy.cpython-38-x86_64-linux-gnu.so,是我使用 pybind11 和自定义 C++ 库创建的。当我使用类似的东西在终端中导入这个模块时,ipython我得到了如图所示的功能自动完成功能。

自动补全在终端中工作

但是在 vscode 中我没有得到任何自动完成功能,我只是得到了消息Import "relatpy" could not be resolved。导入这个模块的python文件在vscode中仍然可以正常运行,只是没有自动补全。

我是否必须将此模块添加到我的 PYTHONPATH 中,或者我该如何执行此操作?这个模块也经常被重建,所以有没有办法让自动补全工作,即使模块发生变化?

我在 vscode 中使用 pylance 作为 python 语言服务器。

我使用以下 CMakeLists.txt 创建了 pybind11 模块:

project(relatpy)

find_package(pybind11 REQUIRED)

file(GLOB SOURCES "../relativity/src/*.cpp")
file(GLOB HEADERS "../relativity/include/*.h")
file(GLOB BINDINGS "*.cpp")

pybind11_add_module(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${BINDINGS})

set_target_properties(${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PYTHON_DIR})
Run Code Online (Sandbox Code Playgroud)

Too*_*one 1

根据关于pybind 问题从 pybind 项目自动创建存根 pyi 文件的评论,您可以使用mypy中的Stubgen来生成Pylance 可以读取的存根文件。

pip install mypy
Run Code Online (Sandbox Code Playgroud)

然后

PYTHONPATH=<path to your python module> stubgen -m <your python module name>
Run Code Online (Sandbox Code Playgroud)

(在你的情况下,路径应该是包含 的目录relatpy.cpython-38-x86_64-linux-gnu.so,并且你的 python 模块名称是relatpy

Stubgen 会告诉您 .pyi 文件的放置位置(在我的例子中)out/<python module name>.pyi。您需要将 .pyi 文件移动到 Python 模块旁边,即relatpy.cpython-38-x86_64-linux-gnu.so.

当我查看生成的 .pyi 文件时,它有一行import flags,VS Code 在该行下划了线。所以我也这样做了:

pip install flags
Run Code Online (Sandbox Code Playgroud)

(不久前,我尝试过 pybind 问题中提到的另一个解决方案 pybind11-stubgen,但无法让它工作,而 Stubgen 工作没有错误。)

编辑:所需的 CMake 代码非常简单:构建模块后,只需找出stubgen(在我的情况下,在我的虚拟环境中,因为我通过requirements.txt 文件 pip 安装它)的位置,然后使用自定义命令。

pybind11_add_module(${PYMODULE_NAME} ...)
target_link_libraries(${PYMODULE_NAME} PRIVATE ... pybind11::pybind11)

# Use stubgen to create .pyi files to sit alongside the just-built python module
set(Stubgen_Executable "${CMAKE_SOURCE_DIR}/venv/bin/stubgen")
if(WIN32)
    set(Stubgen_Executable "${CMAKE_SOURCE_DIR}/venv/Scripts/stubgen.exe")
endif()
add_custom_command(TARGET ${PYMODULE_NAME} POST_BUILD
    COMMAND ${Stubgen_Executable} -m ${PYMODULE_NAME} -o .
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    COMMENT "Use stubgen to create .pyi for statement completion"
Run Code Online (Sandbox Code Playgroud)