Skip to content

Commit 9b39285

Browse files
authored
Replace pybind11 dartpy with nanobind (#2249)
1 parent 94a5d5b commit 9b39285

File tree

294 files changed

+9064
-34485
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

294 files changed

+9064
-34485
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ docs/doxygen/html/
5959
docs/readthedocs/site
6060
docs/readthedocs/_build/
6161
docs/readthedocs/_generated/
62+
docs/readthedocs/_generated_stubs/
6263
docs/python_api/_build/
6364

6465
# Data files

Brewfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,3 @@ brew 'urdfdom'
3737

3838
# dartpy dependencies
3939
brew 'python3'
40-
brew 'pybind11'

CMakeLists.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ dart_option(DART_USE_SYSTEM_IMGUI
247247
"Use system-installed ImGui instead of fetching from GitHub (recommended for package distributions)" OFF CATEGORY system)
248248
dart_option(DART_USE_SYSTEM_GOOGLEBENCHMARK "Use system GoogleBenchmark" OFF CATEGORY system)
249249
dart_option(DART_USE_SYSTEM_GOOGLETEST "Use system GoogleTest" OFF CATEGORY system)
250-
dart_option(DART_USE_SYSTEM_PYBIND11 "Use system pybind11" OFF CATEGORY system)
250+
dart_option(DART_USE_SYSTEM_NANOBIND "Use system nanobind" OFF CATEGORY system)
251251
dart_option(DART_USE_SYSTEM_TRACY "Use system Tracy" OFF CATEGORY system)
252252
dart_option(DART_VERBOSE "Whether print detailed information in CMake process" OFF CATEGORY diagnostics)
253253
dart_option(DART_BUILD_DART8 "Build experimental DART8 library" OFF CATEGORY build)
@@ -674,7 +674,10 @@ endif()
674674
add_subdirectory(python)
675675

676676
# Add 'ALL' target that builds everything
677-
set(all_target_candidates dartpy)
677+
set(all_target_candidates)
678+
if(DART_BUILD_DARTPY)
679+
list(APPEND all_target_candidates dartpy)
680+
endif()
678681
if(DART_BUILD_TESTS AND BUILD_TESTING)
679682
list(APPEND all_target_candidates tests_and_run pytest)
680683
endif()
@@ -1003,8 +1006,7 @@ message(STATUS "Run '${DART_CMAKE_BUILD_CMD} --target tutorials' to build all th
10031006
message(STATUS "Run '${DART_CMAKE_BUILD_CMD} --target view_docs' to see the API documentation")
10041007
message(STATUS "Run '${DART_CMAKE_BUILD_CMD} --target install' to install all the C++ components")
10051008
if(TARGET dartpy)
1006-
message(STATUS "Run '${DART_CMAKE_BUILD_CMD} --target dartpy' to build dartpy")
1007-
message(STATUS "Run '${DART_CMAKE_BUILD_CMD} --target install' to install dartpy")
1009+
message(STATUS "Run '${DART_CMAKE_BUILD_CMD} --target dartpy' to build the python bindings")
10081010
endif()
10091011
if(TARGET coverage)
10101012
message(STATUS "- 'coverage' : generate coverage report")

docker/dev/v6.16/Dockerfile.ubuntu.jammy

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,14 @@ RUN apt-get install -y --no-install-recommends \
5555

5656
RUN apt-get install -y --no-install-recommends \
5757
libpython3-dev \
58-
pybind11-dev \
5958
python3 \
6059
python3-dev \
6160
python3-distutils \
6261
python3-numpy \
6362
python3-pip \
6463
python3-setuptools
6564

66-
RUN pip3 install pytest -U
65+
RUN pip3 install --no-cache-dir nanobind pytest -U
6766

6867
# ==============================================================================
6968
# Clean up

docker/dev/v6.16/Dockerfile.ubuntu.noble

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,15 @@ RUN apt-get install -y --no-install-recommends \
5555

5656
RUN apt-get install -y --no-install-recommends \
5757
libpython3-dev \
58-
pybind11-dev \
5958
python3 \
6059
python3-dev \
6160
python3-numpy \
6261
python3-pip \
6362
python3-pytest \
6463
python3-setuptools
6564

65+
RUN pip3 install --no-cache-dir nanobind pytest -U
66+
6667
# ==============================================================================
6768
# Clean up
6869
# ==============================================================================

docker/dev/v6.16/Dockerfile.ubuntu.plucky

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,15 @@ RUN apt-get install -y --no-install-recommends \
5555

5656
RUN apt-get install -y --no-install-recommends \
5757
libpython3-dev \
58-
pybind11-dev \
5958
python3 \
6059
python3-dev \
6160
python3-numpy \
6261
python3-pip \
6362
python3-pytest \
6463
python3-setuptools
6564

65+
RUN pip3 install --no-cache-dir nanobind pytest -U
66+
6667
# ==============================================================================
6768
# Clean up
6869
# ==============================================================================

docker/dev/v6.16/Dockerfile.ubuntu.questing

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,15 @@ RUN apt-get install -y --no-install-recommends \
5555

5656
RUN apt-get install -y --no-install-recommends \
5757
libpython3-dev \
58-
pybind11-dev \
5958
python3 \
6059
python3-dev \
6160
python3-numpy \
6261
python3-pip \
6362
python3-pytest \
6463
python3-setuptools
6564

65+
RUN pip3 install --no-cache-dir nanobind pytest -U
66+
6667
# ==============================================================================
6768
# Clean up
6869
# ==============================================================================

docs/readthedocs/README.md

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pixi run docs-serve-ko
4343

4444
### How It Works
4545

46-
The Python API documentation is generated using Sphinx autodoc, which requires the `dartpy` module to be importable.
46+
The Python API documentation is generated using Sphinx autodoc, which requires the `dartpy` module (nanobind extension) to be importable.
4747

4848
**Local builds:**
4949

@@ -53,9 +53,8 @@ The Python API documentation is generated using Sphinx autodoc, which requires t
5353

5454
**Read the Docs builds:**
5555

56-
- dartpy is a C++ extension built with pybind11 and cannot be compiled on Read the Docs
57-
- API documentation pages will be empty until we implement pre-built wheels
58-
- The documentation structure and navigation will still work correctly
56+
- Read the Docs cannot compile the C++ extension, so `conf.py` falls back to generated stubs under `python/stubs/dartpy`.
57+
- If compatible wheels are available for RTD’s image, the requirements file pins one so autodoc can use the real module; otherwise the stubs keep the API pages rendering.
5958

6059
### Generating Stub Files
6160

@@ -91,14 +90,10 @@ The `docs-build` task:
9190

9291
### Read the Docs ✅
9392

94-
Read the Docs now installs `dartpy` prior to running Sphinx so the Python API pages
95-
render there as well. RTD's Ubuntu 22.04 images are still on glibc 2.35, so the
96-
requirements file pins `dartpy==6.16.0`, the last release whose wheels remain compatible
97-
with glibc 2.27. That wheel set only targets CPython 3.12+ (cp312–cp314), so `.readthedocs.yml`
98-
now pins the RTD runtime to Python 3.12. Local builds can continue using the
99-
`pip install --pre dartpy` flow for the bleeding-edge bindings. Once RTD upgrades
100-
(or we ship compatible wheels), update `docs/readthedocs/requirements.txt` and
101-
`.readthedocs.yml` to match and remove these temporary pins.
93+
Read the Docs currently relies on prebuilt `dartpy` wheels when they match the RTD
94+
image; otherwise it uses the shipped stubs. The requirements pin may change as RTD
95+
images and wheel compatibility evolve—adjust `docs/readthedocs/requirements.txt` and
96+
`.readthedocs.yml` when newer wheels are usable so autodoc can introspect the live module.
10297

10398
### Future: keep wheels fresh 🎯
10499

docs/readthedocs/conf.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@ def _render_doxyfile(output_path: Path):
169169

170170
output_path.write_text(doxyfile_contents)
171171

172-
173172
def _read_dart_semver():
174173
"""Return the DART semantic version as read from package.xml."""
175174
import xml.etree.ElementTree as ET
@@ -194,14 +193,44 @@ def get_dart_version(prefix_with_v: bool = True):
194193
return f"v{semver}" if prefix_with_v else semver
195194

196195

196+
def _read_api_versions():
197+
"""Return the list of published documentation versions."""
198+
199+
versions_file = REPO_ROOT / "scripts" / "docs_versions.txt"
200+
versions = []
201+
try:
202+
for line in versions_file.read_text().splitlines():
203+
line = line.strip()
204+
if line and not line.startswith("DART "):
205+
versions.append(line)
206+
except FileNotFoundError:
207+
# Fallback to a safe default when running locally without the helper.
208+
versions = ["v6.16.0"]
209+
return versions
210+
211+
197212
# Get current DART version from package.xml
198213
current_version = get_dart_version()
214+
api_versions = _read_api_versions()
215+
if current_version in api_versions:
216+
api_version_to_link = current_version
217+
else:
218+
api_version_to_link = api_versions[0] if api_versions else current_version
199219

200-
# Make these available to RST files via html_context
201220
html_context = {
202221
"current_version": current_version,
222+
"api_versions": api_versions,
223+
"api_version_to_link": api_version_to_link,
224+
"cpp_api_url": f"https://dartsim.github.io/dart/{api_version_to_link}/",
225+
"python_api_url": f"https://dartsim.github.io/dart/{api_version_to_link}-py/",
226+
"gh_pages_url": "https://github.com/dartsim/dart/tree/gh-pages",
203227
}
204228

229+
# Provide easy-to-reuse substitutions in the RST files.
230+
rst_epilog = f"""
231+
.. |python_api_url| replace:: {html_context['python_api_url']}
232+
"""
233+
205234
# -- Project information -----------------------------------------------------
206235
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
207236

@@ -254,7 +283,13 @@ def get_dart_version(prefix_with_v: bool = True):
254283
# The master toctree document.
255284
root_doc = "index"
256285

257-
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "README.md"]
286+
exclude_patterns = [
287+
"_build",
288+
"Thumbs.db",
289+
".DS_Store",
290+
"README.md",
291+
"dartpy/api/*",
292+
]
258293

259294

260295
# -- Options for HTML output -------------------------------------------------
@@ -283,7 +318,6 @@ def get_dart_version(prefix_with_v: bool = True):
283318
"""
284319
}
285320

286-
287321
def build_cpp_api_docs(app):
288322
"""Generate the Doxygen HTML bundle so RTD serves versioned C++ docs."""
289323

Lines changed: 21 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
Python API Reference
2-
=====================
2+
====================
33

4-
The full dartpy API reference now builds directly on Read the Docs, so you no
5-
longer need to leave the site or rely on a separate GitHub Pages deployment.
6-
This page renders the documentation straight from the published ``dartpy``
7-
wheel, which means the members, signatures, and type hints always match the
8-
latest PyPI release.
4+
The full ``dartpy`` API reference is built directly on Read the Docs using the
5+
wheel pinned in ``docs/readthedocs/requirements.txt``. Sphinx imports the
6+
modules under ``docs/python_api/`` and auto-documents them using the installed
7+
package. Local builds use the compiled extension in ``build/.../python`` so the
8+
API pages always reflect the current nanobind bindings.
99

10-
.. admonition:: How these docs are generated
11-
12-
* RTD installs the ``dartpy`` wheel listed in :file:`docs/readthedocs/requirements.txt`.
13-
* Sphinx loads the modules under :file:`docs/python_api/` and auto-documents
14-
them using the installed package.
15-
* Local builds can use ``pixi run docs-build`` or ``pixi run api-docs-py``
16-
for the same result.
10+
.. note::
11+
If a compatible wheel is unavailable, ``conf.py`` falls back to the stub
12+
package in ``python/stubs/dartpy`` so RTD still renders the module layout.
13+
Local builds can always use ``pixi run docs-build`` or ``pixi run api-docs-py``.
1714

1815
Getting Started
1916
---------------
@@ -29,28 +26,17 @@ To explore the bindings locally:
2926
print(world.getGravity())
3027
PY
3128
32-
The sections below mirror the module layout from :file:`docs/python_api/`.
33-
3429
Module Reference
3530
----------------
3631
37-
.. toctree::
38-
:maxdepth: 2
39-
:titlesonly:
40-
41-
/dartpy/api/modules/common
42-
/dartpy/api/modules/math
43-
/dartpy/api/modules/dynamics
44-
/dartpy/api/modules/simulation
45-
/dartpy/api/modules/collision
46-
/dartpy/api/modules/constraint
47-
/dartpy/api/modules/optimizer
48-
/dartpy/api/modules/utils
49-
/dartpy/api/modules/gui
50-
51-
Indices and tables
52-
------------------
53-
54-
* :ref:`genindex`
55-
* :ref:`modindex`
56-
* :ref:`search`
32+
The sections below mirror the module layout from ``docs/python_api/``.
33+
34+
* :doc:`dartpy.common <modules/common>`
35+
* :doc:`dartpy.math <modules/math>`
36+
* :doc:`dartpy.dynamics <modules/dynamics>`
37+
* :doc:`dartpy.simulation <modules/simulation>`
38+
* :doc:`dartpy.collision <modules/collision>`
39+
* :doc:`dartpy.constraint <modules/constraint>`
40+
* :doc:`dartpy.optimizer <modules/optimizer>`
41+
* :doc:`dartpy.utils <modules/utils>`
42+
* :doc:`dartpy.gui <modules/gui>`

0 commit comments

Comments
 (0)