Pybind11 Type Stub Generator
pybind11-stubgen is a PEP 561 type stubs generator for pybind11 modules. It creates `.pyi` files, making C++ extensions more understandable to static analysis tools and IDEs for improved type checking. The project is actively maintained, with regular releases (currently at version 2.5.5) providing bug fixes and new features.
Warnings
- gotcha The target pybind11 module (for which stubs are being generated) must be discoverable and importable by Python at runtime. If the module is not formally installed (e.g., a development build), you may need to adjust `PYTHONPATH` or `LD_LIBRARY_PATH` (on Linux) to ensure it can be found.
- breaking Older versions of `pybind11-stubgen` (prior to 2.5.5) may generate incorrect or malformed stubs for modules built with `pybind11 3.0.0` due to changes in how `qualname` prefixes are handled within `pybind11` itself.
- gotcha Handling of NumPy array type annotations can be inconsistent in older versions. Before v2.4, or without explicitly using the `--numpy-array-use-type-var` flag, NumPy array types like `numpy.ndarray[numpy.float32[m, 1]]` might not be formatted optimally for static analysis.
Install
-
pip install pybind11-stubgen
Imports
- main
from pybind11_stubgen import main
Quickstart
import os
import subprocess
import shutil
# To generate stubs for a pybind11 module named 'my_module':
# 1. Ensure 'my_module' is installed and importable in your Python environment.
# 2. This example demonstrates generating stubs for the 'numpy' module.
# (Requires numpy to be installed: `pip install numpy`)
# Create a temporary directory for output
output_dir = "temp_stubs"
os.makedirs(output_dir, exist_ok=True)
try:
print(f"Generating stubs for 'numpy' into '{output_dir}'...")
# Execute the command-line tool
result = subprocess.run(
["pybind11-stubgen", "numpy", "-o", output_dir],
capture_output=True,
text=True,
check=True
)
print("STDOUT:", result.stdout)
print("STDERR:", result.stderr)
print(f"\nStubs generated in '{output_dir}'. Contents:")
for root, _, files in os.walk(output_dir):
for f in files:
print(os.path.join(root, f))
except subprocess.CalledProcessError as e:
print(f"Error generating stubs: {e}")
print("STDOUT:", e.stdout)
print("STDERR:", e.stderr)
except FileNotFoundError:
print("Error: 'pybind11-stubgen' command not found. Is it installed and in your PATH?")
except Exception as e:
print(f"An unexpected error occurred: {e}")
finally:
# Clean up the temporary directory
if os.path.exists(output_dir):
print(f"\nCleaning up '{output_dir}'...")
shutil.rmtree(output_dir)