From 684cde9fba351622aae601414423527f352c0e09 Mon Sep 17 00:00:00 2001 From: Tim Ohliger Date: Wed, 1 Apr 2026 15:55:03 +0200 Subject: [PATCH 1/2] Add WITH_STUBGEN option to generate typing stubs using pybind11-stubgen Add PEP 561 typing stub generation to the build system, gated behind WITH_STUBGEN (OFF by default) and IGNORE_STUBGEN_ERRORS (ON by default). When enabled, pybind11-stubgen runs after the python package is assembled, generating .pyi stub files and a py.typed marker that are included in the wheel. This enables type checking support in mypy, pyright, and IDEs. No CI workflow changes - this is opt-in for local/custom builds. --- CMakeLists.txt | 2 ++ cmake/Open3DPrintConfigurationSummary.cmake | 4 ++++ cpp/pybind/CMakeLists.txt | 2 ++ cpp/pybind/make_python_package.cmake | 16 ++++++++++++++++ python/open3d/__init__.py | 2 +- python/pyproject.toml | 1 + python/requirements_build.txt | 1 + 7 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c9a87bc4c4a..8dccfa65bfa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,8 @@ option(BUILD_EXAMPLES "Build Open3D examples programs" ON option(BUILD_UNIT_TESTS "Build Open3D unit tests" OFF) option(BUILD_BENCHMARKS "Build the micro benchmarks" OFF) option(BUILD_PYTHON_MODULE "Build the python module" ON ) +option(WITH_STUBGEN "Use pybind11-stubgen to generate stubs" OFF) +option(IGNORE_STUBGEN_ERRORS "Ignore all errors during stub generation" ON ) option(BUILD_CUDA_MODULE "Build the CUDA module" OFF) option(BUILD_WITH_CUDA_STATIC "Build with static CUDA libraries" ON ) option(BUILD_COMMON_CUDA_ARCHS "Build for common CUDA GPUs (for release)" OFF) diff --git a/cmake/Open3DPrintConfigurationSummary.cmake b/cmake/Open3DPrintConfigurationSummary.cmake index c12946af62c..f9274280fec 100644 --- a/cmake/Open3DPrintConfigurationSummary.cmake +++ b/cmake/Open3DPrintConfigurationSummary.cmake @@ -37,6 +37,10 @@ function(open3d_print_configuration_summary) open3d_aligned_print("Build Unit Tests" "${BUILD_UNIT_TESTS}") open3d_aligned_print("Build Examples" "${BUILD_EXAMPLES}") open3d_aligned_print("Build Python Module" "${BUILD_PYTHON_MODULE}") + open3d_aligned_print("Generate Typing Stubs" "${WITH_STUBGEN}") + if(WITH_STUBGEN) + open3d_aligned_print("Ignore All Stubgen Errors" "${IGNORE_STUBGEN_ERRORS}") + endif() open3d_aligned_print("Build Jupyter Extension" "${BUILD_JUPYTER_EXTENSION}") open3d_aligned_print("Build TensorFlow Ops" "${BUILD_TENSORFLOW_OPS}") open3d_aligned_print("Build PyTorch Ops" "${BUILD_PYTORCH_OPS}") diff --git a/cpp/pybind/CMakeLists.txt b/cpp/pybind/CMakeLists.txt index 4da6d51aebd..528eee1d0f6 100644 --- a/cpp/pybind/CMakeLists.txt +++ b/cpp/pybind/CMakeLists.txt @@ -223,6 +223,8 @@ add_custom_target(python-package -DPYTHON_VERSION=${PYTHON_VERSION} "-DCOMPILED_MODULE_PATH_LIST=${COMPILED_MODULE_PATH_LIST}" "-DPYTHON_EXTRA_LIBRARIES=${PYTHON_EXTRA_LIBRARIES}" + -DWITH_STUBGEN=${WITH_STUBGEN} + -DIGNORE_STUBGEN_ERRORS=${IGNORE_STUBGEN_ERRORS} -DBUILD_JUPYTER_EXTENSION=${BUILD_JUPYTER_EXTENSION} -DBUILD_TENSORFLOW_OPS=${BUILD_TENSORFLOW_OPS} -DBUILD_PYTORCH_OPS=${BUILD_PYTORCH_OPS} diff --git a/cpp/pybind/make_python_package.cmake b/cpp/pybind/make_python_package.cmake index aa4171414b0..fd7d79d9b93 100644 --- a/cpp/pybind/make_python_package.cmake +++ b/cpp/pybind/make_python_package.cmake @@ -139,3 +139,19 @@ file(COPY "${PYTHON_PACKAGE_SRC_DIR}/../examples/python/" DESTINATION "${PYTHON_PACKAGE_DST_DIR}/open3d/examples") file(COPY "${PYTHON_PACKAGE_SRC_DIR}/../examples/python/" DESTINATION "${PYTHON_PACKAGE_DST_DIR}/open3d/examples") + +# Generate typing stub files (.pyi) and py.typed marker file. +if(WITH_STUBGEN) + if(NOT IGNORE_STUBGEN_ERRORS) + list(APPEND PYBIND11_STUBGEN_FLAGS "--exit-code") + endif() + message(STATUS "Generating typing stubs...") + execute_process( + COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${PYTHON_PACKAGE_DST_DIR} + pybind11-stubgen open3d -o ${PYTHON_PACKAGE_DST_DIR} + ${PYBIND11_STUBGEN_FLAGS} + COMMAND_ECHO STDOUT + COMMAND_ERROR_IS_FATAL ANY + ) + file(WRITE "${PYTHON_PACKAGE_DST_DIR}/open3d/py.typed" "") +endif() diff --git a/python/open3d/__init__.py b/python/open3d/__init__.py index 87608701d5c..0a1a00af3a9 100644 --- a/python/open3d/__init__.py +++ b/python/open3d/__init__.py @@ -211,4 +211,4 @@ def _jupyter_nbextension_paths(): if sys.platform == "win32": _win32_dll_dir.close() -del os, sys, CDLL, find_library, Path, warnings, _insert_pybind_names +del os, sys, CDLL, find_library, Path, warnings, _insert_pybind_names, open3d diff --git a/python/pyproject.toml b/python/pyproject.toml index 0fe60ad8e30..8736aa72da0 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -6,5 +6,6 @@ requires = [ "jupyterlab==4.*", "setuptools>=67.3.2", "wheel==0.46.3", + "pybind11-stubgen>=2.5", ] build-backend = "setuptools.build_meta" diff --git a/python/requirements_build.txt b/python/requirements_build.txt index b4890d2c14b..ee6b301abf5 100644 --- a/python/requirements_build.txt +++ b/python/requirements_build.txt @@ -1,3 +1,4 @@ setuptools>=67.3.2 wheel==0.46.* yapf==0.43.* +pybind11-stubgen>=2.5 From 5bb16dab901bbc809d4012d89fec1e6c4a9bcb79 Mon Sep 17 00:00:00 2001 From: Tim Ohliger Date: Wed, 1 Apr 2026 15:57:47 +0200 Subject: [PATCH 2/2] Move pybind11-stubgen to separate requirements_stubgen.txt Avoid CI installing pybind11-stubgen unnecessarily since stub generation is disabled by default. Users who enable WITH_STUBGEN install deps via: pip install -r python/requirements_stubgen.txt --- python/pyproject.toml | 1 - python/requirements_build.txt | 1 - python/requirements_stubgen.txt | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) create mode 100644 python/requirements_stubgen.txt diff --git a/python/pyproject.toml b/python/pyproject.toml index 8736aa72da0..0fe60ad8e30 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -6,6 +6,5 @@ requires = [ "jupyterlab==4.*", "setuptools>=67.3.2", "wheel==0.46.3", - "pybind11-stubgen>=2.5", ] build-backend = "setuptools.build_meta" diff --git a/python/requirements_build.txt b/python/requirements_build.txt index ee6b301abf5..b4890d2c14b 100644 --- a/python/requirements_build.txt +++ b/python/requirements_build.txt @@ -1,4 +1,3 @@ setuptools>=67.3.2 wheel==0.46.* yapf==0.43.* -pybind11-stubgen>=2.5 diff --git a/python/requirements_stubgen.txt b/python/requirements_stubgen.txt new file mode 100644 index 00000000000..da78393bcf0 --- /dev/null +++ b/python/requirements_stubgen.txt @@ -0,0 +1 @@ +pybind11-stubgen==2.5.*