Skip to content
Open
Show file tree
Hide file tree
Changes from 250 commits
Commits
Show all changes
465 commits
Select commit Hold shift + click to select a range
30e9e47
[pydrake] Move Expression and Formula pickling to C++
jwnimmer-tri Jun 22, 2026
a165f1d
Merge branch 'nanobind-getstate-cxx' into nanobind-only
jwnimmer-tri Jun 23, 2026
45cbab7
get pybind11 building again
jwnimmer-tri Jun 23, 2026
b24ff3e
get pybind11 passing most tests again
jwnimmer-tri Jun 23, 2026
6caeaea
re-enable all linters
jwnimmer-tri Jun 23, 2026
971201f
re-enable some math tests
jwnimmer-tri Jun 23, 2026
878ce62
fix the remaining pybind11 tests
jwnimmer-tri Jun 23, 2026
5b1cc21
fix stubgen for pybind11
jwnimmer-tri Jun 23, 2026
11b0b33
un-nerf mixed_integer_rotation_constraint
jwnimmer-tri Jun 23, 2026
02ea324
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jun 23, 2026
b3d078c
un-nerf eigen_geometry_test
jwnimmer-tri Jun 23, 2026
aed8e83
un-nerf primitives_py
jwnimmer-tri Jun 23, 2026
8c22041
un-nerf math test
jwnimmer-tri Jun 23, 2026
f7bdaa9
un-nerf optimization_py
jwnimmer-tri Jun 23, 2026
97b9cc1
un-nerf inverse_kinematics_py
jwnimmer-tri Jun 23, 2026
66be0c9
un-nerf plant (all) and tree (a little bit)
jwnimmer-tri Jun 23, 2026
575dd0a
clean up the build system a bit
jwnimmer-tri Jun 23, 2026
261778d
remove troublesome private NVI
jwnimmer-tri Jun 23, 2026
6cb656f
fix geometry.optimization
jwnimmer-tri Jun 23, 2026
5485a05
un-nerf graph_algorithms
jwnimmer-tri Jun 23, 2026
a703070
wip arithmetic enum
jwnimmer-tri Jun 23, 2026
9d8a5f2
wip solver_option double to bool
jwnimmer-tri Jun 23, 2026
9538fd8
TODO on weak_referenceable
jwnimmer-tri Jun 23, 2026
be3ba8f
wip shape debugging
jwnimmer-tri Jun 24, 2026
5bce2e2
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jun 24, 2026
e15edb4
lint
jwnimmer-tri Jun 24, 2026
3db980e
revert unnecessary symbolic changes
jwnimmer-tri Jun 24, 2026
3a3fef9
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jun 24, 2026
b543676
stubgen works now
jwnimmer-tri Jun 24, 2026
dfa4224
fix SetCustomProjectionFunction
jwnimmer-tri Jun 24, 2026
1b509f2
un-nerf SetDecisionVariableValueInVector
jwnimmer-tri Jun 24, 2026
f5b5826
eigen caster fixes cross-shape
jwnimmer-tri Jun 24, 2026
cbedb02
un-nerf print_symbol_collisions_test
jwnimmer-tri Jun 24, 2026
d3673b8
[pydrake] Align with nanobind py::bytes API
jwnimmer-tri Jun 24, 2026
2d898c3
Merge branch 'nanobind-bytes2' into nanobind-only
jwnimmer-tri Jun 24, 2026
c558e10
wip on solvers pyfunctions
jwnimmer-tri Jun 24, 2026
e74dc69
wip is_weak_referenceable
jwnimmer-tri Jun 24, 2026
281bb22
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jun 25, 2026
0db1042
lint
jwnimmer-tri Jun 25, 2026
c253705
un-nerf trajectories_py building
jwnimmer-tri Jun 25, 2026
4483a0c
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 6, 2026
93a55d1
fixup merge error
jwnimmer-tri Jul 6, 2026
01db7fd
wip fixing pybind11
jwnimmer-tri Jul 6, 2026
082b935
[pydrake] Align with nanobind py::callable API
jwnimmer-tri Jul 6, 2026
ed33dba
Merge branch 'nanobind-callable' into nanobind-only
jwnimmer-tri Jul 6, 2026
947c0a0
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 7, 2026
eea710a
un-nerf StaticZip
jwnimmer-tri Jul 7, 2026
799db27
trajectories_py revert unnecessary change
jwnimmer-tri Jul 7, 2026
a25bc26
eigen_geometry_py revert unnecessary changes
jwnimmer-tri Jul 7, 2026
0064533
ref_cycle_test_util_py revert unnecessary change
jwnimmer-tri Jul 7, 2026
989828b
planning_py_trajectory_optimization revert unnecessary changes
jwnimmer-tri Jul 7, 2026
0a25dcb
geometry_py_optimization revert unnecessary change
jwnimmer-tri Jul 7, 2026
c987cb5
[geometry] Improve GeometrySet ctor type deduction
jwnimmer-tri Jul 7, 2026
e58f121
geometry_py_common revert unnecessary changes
jwnimmer-tri Jul 7, 2026
f9babef
builder_life_support: implement for nanobind
rpoyner-tri Jul 7, 2026
ac229a9
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 7, 2026
2c82abc
lint cleanups for builder_life_support
rpoyner-tri Jul 7, 2026
08d2029
add missed file for builder_life_support
rpoyner-tri Jul 7, 2026
1e6e152
fix DefAttributesUsingSerialize on enums
jwnimmer-tri Jul 7, 2026
17f2d91
fix odr
jwnimmer-tri Jul 7, 2026
917a633
Implement Simulator ctor for nanobind
rpoyner-tri Jul 7, 2026
287d2c0
upstream robin_map patch
jwnimmer-tri Jul 7, 2026
8cc4438
Merge remote-tracking branch 'rpoyner-tri/nanobind-only' into nanobin…
jwnimmer-tri Jul 7, 2026
561cbec
wip: implement lcm_py CreateDefaultValue trampoline
rpoyner-tri Jul 7, 2026
d22d4a8
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 8, 2026
2d53b47
Merge remote-tracking branch 'rpoyner-tri/nanobind-only' into nanobin…
jwnimmer-tri Jul 8, 2026
6287f4e
Transcribe reviewable TODO discussions back into the code
jwnimmer-tri Jul 8, 2026
732a925
lint
jwnimmer-tri Jul 8, 2026
4a32d6c
docstrings
jwnimmer-tri Jul 8, 2026
204f487
fix rational_py
jwnimmer-tri Jul 8, 2026
9488811
framework_py narrower nerfing
jwnimmer-tri Jul 8, 2026
da6b5ab
hydro contact enums compare as equal
jwnimmer-tri Jul 8, 2026
ba7e654
tree_py less nerfing
jwnimmer-tri Jul 8, 2026
ae6129e
PyRenderEngine can be cloned
jwnimmer-tri Jul 8, 2026
4ff07f0
fix DofMask constructor
jwnimmer-tri Jul 8, 2026
aad72c6
Narrow porting goop in value_producer_pybind
rpoyner-tri Jul 8, 2026
7cb822a
wip: Hack past a baffling self arg type mismatch
rpoyner-tri Jul 8, 2026
52286d0
lint
jwnimmer-tri Jul 9, 2026
144ea05
link nanobind shared by default
jwnimmer-tri Jul 9, 2026
2ddd7db
add more scipy stubbing needed by nanobind
jwnimmer-tri Jul 9, 2026
dbe634c
more Eigen::Map respelling of copying
jwnimmer-tri Jul 9, 2026
96e1d9c
comment consistency
jwnimmer-tri Jul 9, 2026
c5d668e
custom evaluator array shape checks ported to python
jwnimmer-tri Jul 9, 2026
d21a8c0
lint
jwnimmer-tri Jul 9, 2026
317a30b
clean up custom evaluator to be suitable to merge
jwnimmer-tri Jul 9, 2026
93faeab
more eval cleanups
jwnimmer-tri Jul 9, 2026
d73be4f
Fix alias class access in framework_py_systems
rpoyner-tri Jul 9, 2026
6c2e086
[pydrake] Remove gratuitous IrisParameterizationFunction wrapping
jwnimmer-tri Jul 9, 2026
6030882
PR [pydrake] Remove gratuitous IrisParameterizationFunction wrapping
jwnimmer-tri Jul 9, 2026
d6d80ee
[pydrake] Rewrite custom evaluator error-checking
jwnimmer-tri Jul 9, 2026
7777a07
Merge remote-tracking branch 'rpoyner-tri/nanobind-only' into nanobin…
jwnimmer-tri Jul 9, 2026
587f0eb
Merge branch 'nanobind-iris-functors' into nanobind-only
jwnimmer-tri Jul 9, 2026
80025af
Merge branch 'nanobind-evaluators' into nanobind-only
jwnimmer-tri Jul 9, 2026
13e6e85
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 9, 2026
bbe137e
fix trajectory tests
jwnimmer-tri Jul 9, 2026
b223605
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 9, 2026
ad4474b
fix BasicVector size constructor
jwnimmer-tri Jul 9, 2026
1f66617
nerf some aborts
jwnimmer-tri Jul 10, 2026
9853e96
ugh, fluent setters need reference_internal
jwnimmer-tri Jul 10, 2026
33977be
un-nerf viz test cart_pole
jwnimmer-tri Jul 10, 2026
e43c16f
fix IrisNp2Options
jwnimmer-tri Jul 10, 2026
4c8bc0a
fix trajectory_optimization_test.py (work around eigen casting)
jwnimmer-tri Jul 10, 2026
4ae159d
parser ctor allow none
jwnimmer-tri Jul 10, 2026
cca0d1d
GetParentPlant ref internal
jwnimmer-tri Jul 10, 2026
af9ecfe
geometry tests passing
jwnimmer-tri Jul 10, 2026
0190622
some progress on VectorSystem
jwnimmer-tri Jul 10, 2026
0b564fa
fix vectorlog unblocks several tests
jwnimmer-tri Jul 10, 2026
98fe70d
primitives_test shape fixes
jwnimmer-tri Jul 10, 2026
b715c51
add missing stl list for DynamicProgrammingOptions
jwnimmer-tri Jul 10, 2026
ed29fbb
get analysis_test running
jwnimmer-tri Jul 10, 2026
32dad64
small cleanups to trampoline counts
jwnimmer-tri Jul 10, 2026
ee9cbfb
wip: get lcm_test working with nanobind
rpoyner-tri Jul 9, 2026
eb82aa2
implement ValueProducer ctor
rpoyner-tri Jul 10, 2026
ad593e6
fix wrong api call in value_producer_pybind
rpoyner-tri Jul 10, 2026
20644f8
Merge remote-tracking branch 'rpoyner-tri/nanobind-only' into nanobin…
jwnimmer-tri Jul 10, 2026
038bc86
docstrings
jwnimmer-tri Jul 10, 2026
20196ba
fix acrobot yaml to not have strings for controller params
jwnimmer-tri Jul 10, 2026
934e55e
more eigen caster work-arounds
jwnimmer-tri Jul 10, 2026
6caa5d9
finish ForceDensityField
jwnimmer-tri Jul 10, 2026
3498c3b
drop error message check of pybind11 internal details
jwnimmer-tri Jul 10, 2026
52b253e
skip one EigenPtr test case until later
jwnimmer-tri Jul 10, 2026
0527a9e
start to add categories to XXX todos
jwnimmer-tri Jul 11, 2026
fe2d8f2
XXX(nice-type-name)
jwnimmer-tri Jul 11, 2026
2ae0b38
test_discrete_value_api one new cast works with nanobind?
jwnimmer-tri Jul 11, 2026
f416a81
nerf BatchEvalUniquePeriodicDiscreteUpdate test
jwnimmer-tri Jul 11, 2026
7077535
simulator.reset_context allows nullptr
jwnimmer-tri Jul 11, 2026
d9c9416
more fluent setters
jwnimmer-tri Jul 11, 2026
92b7b2a
integrator.get_context no copy
jwnimmer-tri Jul 11, 2026
775f383
wip interpreter aborts
jwnimmer-tri Jul 11, 2026
efccbf2
draft fix for nice type name
rpoyner-tri Jul 11, 2026
4a002fe
nice type name: fix refcount issue
rpoyner-tri Jul 11, 2026
2ddad38
[pydrake] Align with nanobind py::foo_error API
jwnimmer-tri Jul 12, 2026
628b1b0
Merge branch 'nanobind-exception-ctor' into nanobind-only
jwnimmer-tri Jul 12, 2026
fe0e748
fix bug in nanobind nice type name implementation
rpoyner-tri Jul 12, 2026
f0b6ed2
Merge remote-tracking branch 'rpoyner-tri/nanobind-only' into nanobin…
jwnimmer-tri Jul 12, 2026
5a416f8
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 13, 2026
214aaf0
wip: more complete fix for nice type name
rpoyner-tri Jul 13, 2026
8a6de91
wip: remove an incorrect dynamic cast check
rpoyner-tri Jul 13, 2026
b6aa67a
fix ref_cycle error checking and re-enable tests
rpoyner-tri Jul 13, 2026
0cbe34f
[pydrake] Add regression tests for nullptr arguments
jwnimmer-tri Jul 13, 2026
07e9ae3
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 13, 2026
8ce7f01
Merge branch 'nanobind-nulls' into nanobind-only
jwnimmer-tri Jul 13, 2026
afbb41d
add more missing `.none()` annotations
jwnimmer-tri Jul 13, 2026
db9fffc
Merge remote-tracking branch 'rpoyner-tri/nanobind-only' into nanobin…
jwnimmer-tri Jul 13, 2026
a428391
rm chaff
jwnimmer-tri Jul 13, 2026
b9ffb3b
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 14, 2026
3365f0d
Use robin-map from BCR
jwnimmer-tri Jul 14, 2026
cbaa00e
Upgrade to nanobind 2.13.0
jwnimmer-tri Jul 14, 2026
11ab2ff
cleanup: remove obsolete simulator init machinery
rpoyner-tri Jul 13, 2026
3e5cfd0
wip: attempt to clarify porting issues wrap pybind test
rpoyner-tri Jul 14, 2026
58fe40f
Use nanobind from BCR
jwnimmer-tri Jul 14, 2026
9d7b6bb
Revert "Use nanobind from BCR"
jwnimmer-tri Jul 14, 2026
9e0b10c
Merge remote-tracking branch 'rpoyner-tri/nanobind-only' into nanobin…
jwnimmer-tri Jul 14, 2026
a7c7913
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 14, 2026
9d16903
docstrings
jwnimmer-tri Jul 14, 2026
8dd82dc
explain GetAlias assumptions
rpoyner-tri Jul 14, 2026
c8b66f4
Use forked nanobind_eigen for desired casting
jwnimmer-tri Jul 14, 2026
ee5fd44
Merge remote-tracking branch 'rpoyner-tri/nanobind-only' into nanobin…
jwnimmer-tri Jul 14, 2026
c15f27a
Use nanobind from BCR
jwnimmer-tri Jul 14, 2026
2893826
add nanobind_eigen vendoring regression test
jwnimmer-tri Jul 14, 2026
b806dd8
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 14, 2026
a11e3d9
add automatic squeezing into 1d vectors
jwnimmer-tri Jul 14, 2026
a710f72
get custom_test passing
rpoyner-tri Jul 14, 2026
543de5f
RotationMatrix::row and ::col always copy
jwnimmer-tri Jul 15, 2026
f088339
code cleanup is_pyobject
jwnimmer-tri Jul 15, 2026
b25b9c8
fix patch file for "add automatic squeezing into 1d vectors"
jwnimmer-tri Jul 15, 2026
1371b8c
work around a nanobind bug with mutable eigen output arguments
jwnimmer-tri Jul 15, 2026
d0cb761
upgrade nanobind to 2.13.0
jwnimmer-tri Jul 15, 2026
58a2731
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 15, 2026
e0cdd2d
lcm_py cleanups
rpoyner-tri Jul 15, 2026
c586271
fix one more eigen dtype=object porting issue
jwnimmer-tri Jul 15, 2026
72fba66
Merge remote-tracking branch 'rpoyner-tri/nanobind-only' into nanobin…
jwnimmer-tri Jul 15, 2026
3714d81
value_producer_pybind cleanups
rpoyner-tri Jul 15, 2026
5af56bc
tidy up render diffs
jwnimmer-tri Jul 15, 2026
8274863
simplify tree inertia getitem
jwnimmer-tri Jul 15, 2026
591df7b
Merge remote-tracking branch 'rpoyner-tri/nanobind-only' into nanobin…
jwnimmer-tri Jul 15, 2026
6b4cc28
remove unused alias
jwnimmer-tri Jul 15, 2026
8c2d63d
add dense caster comments
jwnimmer-tri Jul 15, 2026
f253e79
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 15, 2026
121b11e
small cleanup
jwnimmer-tri Jul 15, 2026
285639b
fix system visitor test
rpoyner-tri Jul 15, 2026
9af06fb
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 16, 2026
fd72adf
Merge remote-tracking branch 'rpoyner-tri/nanobind-only' into nanobin…
jwnimmer-tri Jul 16, 2026
c8e2ee2
docstrings
jwnimmer-tri Jul 16, 2026
45216de
add nanobind.so to install, fixing install_test
jwnimmer-tri Jul 16, 2026
8de4698
lol, stop using pybind11/eval.h in nanobind
jwnimmer-tri Jul 16, 2026
bd46853
use limited api
jwnimmer-tri Jul 16, 2026
e99832d
start to add wheel_builder support
jwnimmer-tri Jul 16, 2026
034671e
small cleanups
jwnimmer-tri Jul 16, 2026
89b3049
better fix for VectorLog.data w/o copying
jwnimmer-tri Jul 16, 2026
8be739c
add some eigen todos
jwnimmer-tri Jul 16, 2026
73fbba1
make SerializerInterface.init simpler
jwnimmer-tri Jul 16, 2026
8190b07
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 16, 2026
ecb2a73
WIP on multi-config tests
jwnimmer-tri Jul 16, 2026
d21eaa5
Revert "WIP on multi-config tests"
jwnimmer-tri Jul 16, 2026
0ca83c4
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 16, 2026
2cdd257
un-nerf test
jwnimmer-tri Jul 16, 2026
815db3e
[workspace] Add nanobind as a dependency
jwnimmer-tri Jul 16, 2026
ab9b3f3
Merge branch 'nanobind-build' into nanobind-only
jwnimmer-tri Jul 16, 2026
53f95d7
[tools] Remove py_test isolation
jwnimmer-tri Jul 17, 2026
8c33192
add multi-config tests
jwnimmer-tri Jul 17, 2026
0ef7005
add drake to select label, for anzu
jwnimmer-tri Jul 17, 2026
ac639ae
pydrake_pybind.h is not allowed to use drake nor libdrake
jwnimmer-tri Jul 17, 2026
382d5b5
drop pybind11_version from nanobind build
jwnimmer-tri Jul 17, 2026
cd20ec9
tutorials should be dual-tested, too
jwnimmer-tri Jul 17, 2026
d85f1de
Reduce binder differences in wrap_pybind
rpoyner-tri Jul 17, 2026
a0bf9ec
Merge remote-tracking branch 'upstream/master' into nanobind-only
jwnimmer-tri Jul 17, 2026
89f3af9
rm dead code (clang complains)
jwnimmer-tri Jul 17, 2026
d86522c
rm dead build code
jwnimmer-tri Jul 18, 2026
b70a1aa
move Simulator.__init__ details back inline now that there's no #ifdef
jwnimmer-tri Jul 18, 2026
927e97e
[workspace] Add nanobind as a dependency
jwnimmer-tri Jul 18, 2026
2b9252f
Merge branch 'nanobind-build' into nanobind-transition
jwnimmer-tri Jul 18, 2026
7c1dae6
skip alt_binder during sanitizier, memcheck, and kcov
jwnimmer-tri Jul 19, 2026
86dd5aa
move eval.h to pydrake_pybind.h
jwnimmer-tri Jul 19, 2026
616063a
Use our class_ wrapper to cull the holder type parameters
jwnimmer-tri Jul 19, 2026
03abb6c
revert wrong whitespace change
jwnimmer-tri Jul 19, 2026
b22744d
revert to master
jwnimmer-tri Jul 19, 2026
6dd0761
revert unnecessary whitespace chagne vs master
jwnimmer-tri Jul 19, 2026
cb489ae
revert unnecessary cleanups
jwnimmer-tri Jul 19, 2026
9918d59
clean up nice type name nanobind fixes
rpoyner-tri Jul 19, 2026
a9a6055
better fixes for enums
jwnimmer-tri Jul 19, 2026
49218de
Merge remote-tracking branch 'rpoyner-tri/nanobind-transition' into n…
jwnimmer-tri Jul 19, 2026
b420778
lint
jwnimmer-tri Jul 19, 2026
f1c27e7
align NB_TRAMPOLINE polyfill with nanobind semantics
jwnimmer-tri Jul 19, 2026
8370b39
Merge remote-tracking branch 'upstream/master' into nanobind-transition
jwnimmer-tri Jul 20, 2026
16e3784
fix Eigen::Map dtype=object casting
jwnimmer-tri Jul 20, 2026
2d369e7
exclude one acrobot C++ test from alt_binder
jwnimmer-tri Jul 20, 2026
b8f1f16
hoist system_visitor changes back into pydrake
jwnimmer-tri Jul 21, 2026
97ed8fb
typo
rpoyner-tri Jul 21, 2026
550220d
Merge remote-tracking branch 'upstream/master' into nanobind-transition
jwnimmer-tri Jul 21, 2026
d4cf635
clean up python trampoline for SerializerInterface
rpoyner-tri Jul 21, 2026
843bb1a
Merge remote-tracking branch 'rpoyner-tri/nanobind-transition' into n…
jwnimmer-tri Jul 21, 2026
edfdf44
revert formatting changes vs master
jwnimmer-tri Jul 21, 2026
19a5a08
cleanup: remove unused argument names
rpoyner-tri Jul 21, 2026
c49e5c5
lint
rpoyner-tri Jul 21, 2026
d0b4089
docstrings
rpoyner-tri Jul 21, 2026
835e438
Merge remote-tracking branch 'rpoyner-tri/nanobind-transition' into n…
jwnimmer-tri Jul 21, 2026
7f4ba2d
[pydrake] Add missing tests for non-pure override trampolines
jwnimmer-tri Jul 21, 2026
b6fa39d
Merge remote-tracking branch 'upstream/master' into nanobind-transition
jwnimmer-tri Jul 21, 2026
9cb5914
[pydrake] Fix ForceDensityField virtual method overrides
jwnimmer-tri Jul 21, 2026
51111f9
Merge branch 'nanobind-force-density-field-backfill' into nanobind-tr…
jwnimmer-tri Jul 21, 2026
410fddd
Merge branch 'nanobind-override-test-backfill' into nanobind-transition
jwnimmer-tri Jul 21, 2026
48f63b5
fix DoGetParameterYaml override
jwnimmer-tri Jul 21, 2026
2141c35
fix ForceDensityField
jwnimmer-tri Jul 21, 2026
c7792ad
Solve clang ODR madness with a Python global instead
rpoyner-tri Jul 21, 2026
359fff1
[workspace] Patch nanobind to allow list inputs for Eigens
jwnimmer-tri Jul 21, 2026
d49b767
Merge branch 'nanobind-dense-caster-lists' into nanobind-transition
jwnimmer-tri Jul 21, 2026
9efdbb2
Merge remote-tracking branch 'upstream/master' into nanobind-transition
jwnimmer-tri Jul 21, 2026
a5094ac
tidy up BusValues::key_iterator name
jwnimmer-tri Jul 22, 2026
8d3df45
Merge remote-tracking branch 'upstream/master' into nanobind-transition
jwnimmer-tri Jul 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# This file is named BUILD.bazel instead of the more typical BUILD, so that on
# OSX it won't conflict with a build artifacts directory named "build".

load("//tools/flags/internal:multi_config.bzl", "python_binder_reset")
load("//tools/install:install.bzl", "install", "install_test")
load("//tools/lint:lint.bzl", "add_lint_tests")
load("//tools/skylark:drake_py.bzl", "drake_py_library")
Expand Down Expand Up @@ -37,10 +38,13 @@ drake_py_library(

# Expose shared library for (a) installed binaries, (b) Drake Python bindings,
# and (c) downstream C++ libraries which will also provide Python bindings.
alias(
# We use 'python_binder_reset' so that our multi-config test suite (which runs
# tests using both pybind11 and nanobind) doesn't recompile libdrake for both
# configs -- it resets the binder flag to its default value for this target.
python_binder_reset(
name = "drake_shared_library",
actual = "//tools/install/libdrake:drake_shared_library",
visibility = ["//visibility:public"],
exports = "//tools/install/libdrake:drake_shared_library",
)

# A manually-curated collection of most model files in Drake, so that we can
Expand Down
19 changes: 13 additions & 6 deletions bindings/pydrake/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ drake_py_library(

drake_cc_library(
name = "pydrake_pybind",
hdrs = ["pydrake_pybind.h"],
hdrs = [
"pydrake_numpy_dtype_object_type_caster.h",
"pydrake_pybind.h",
],
declare_installed_headers = 0,
defines = select({
"//tools/workspace/nanobind:enabled": [
Expand All @@ -68,11 +71,14 @@ drake_cc_library(
],
}),
visibility = ["//visibility:public"],
deps = [
# TODO(#21572) Using pybind11 unconditionally here is wrong, but is
# easier for now until all/most binding code has been ported.
"@drake//tools/workspace/pybind11",
],
deps = select({
"//tools/workspace/nanobind:enabled": [
"@drake//tools/workspace/nanobind",
],
"//conditions:default": [
"@drake//tools/workspace/pybind11",
],
}),
)

drake_cc_library(
Expand Down Expand Up @@ -380,6 +386,7 @@ drake_py_unittest(
"//:.clang-format",
],
tags = ["lint"],
test_alt_binder = False,
)

drake_py_unittest(
Expand Down
9 changes: 7 additions & 2 deletions bindings/pydrake/common/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,13 @@ drake_pybind_library(
"cpp_template.py",
"deprecation.py",
"jupyter.py",
"pybind11_version.py",
"yaml.py",
],
] + select({
"//tools/workspace/nanobind:enabled": [],
"//conditions:default": [
"pybind11_version.py",
],
}),
visibility = [
"//bindings/pydrake:__pkg__",
],
Expand Down Expand Up @@ -518,6 +522,7 @@ drake_py_unittest(

drake_py_unittest(
name = "pybind11_version_test",
opt_out_conditions = ["//tools/workspace/nanobind:enabled"],
deps = [
":common",
],
Expand Down
4 changes: 0 additions & 4 deletions bindings/pydrake/common/all.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,3 @@
from .schema import *
from .yaml import *
from .value import *

# N.B. Since this is generic and relatively scoped, we import the module as a
# symbol.
from . import pybind11_version
12 changes: 10 additions & 2 deletions bindings/pydrake/common/cpp_param_pybind.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ template <typename T>
void RegisterType(
py::module_ m, py::object param_aliases, const std::string& canonical_str) {
// Create an object that is a unique hash.
py::object canonical =
py::eval(py::str(canonical_str.c_str()), m.attr("__dict__"));
py::object canonical = py::eval(
py::str(canonical_str.c_str()), m.attr("__dict__"), py::globals());
py::list aliases;
aliases.append(GetPyHash(typeid(T)));
param_aliases.attr("register")(canonical, aliases);
Expand Down Expand Up @@ -106,15 +106,23 @@ py::object GetPyParamScalarImpl(const std::type_info& tinfo) {
// This type is not aliased. Get the pybind-registered type,
// erroring out if it's not registered.
// WARNING: Internal API :(
#ifdef PYDRAKE_USE_PYBIND11
auto* info = py::detail::get_type_info(tinfo);
#else // PYDRAKE_USE_NANOBIND
auto* info = py::detail::nb_type_lookup(&tinfo);
#endif
if (!info) {
// TODO(eric.cousineau): Use NiceTypeName::Canonicalize(...Demangle(...))
// once simpler dependencies are used (or something else is used to
// justify linking in `libdrake.so`).
const std::string name = tinfo.name();
throw std::runtime_error("C++ type is not registered in pybind: " + name);
}
#ifdef PYDRAKE_USE_PYBIND11
py::handle h(reinterpret_cast<PyObject*>(info->type));
#else // PYDRAKE_USE_NANOBIND
py::handle h(reinterpret_cast<PyObject*>(info));
#endif
return py::borrow<py::object>(h);
}
}
Expand Down
10 changes: 5 additions & 5 deletions bindings/pydrake/common/cpp_param_pybind.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ py::object GetPyParamScalarImpl(const std::type_info& tinfo);
// Gets Python type for a C++ type (base case).
template <typename T>
inline py::object GetPyParamScalarImpl(type_pack<T> = {}) {
static_assert(!py::detail::is_pyobject<T>::value,
static_assert(!internal::is_pyobject<T>::value,
"You cannot use `pybind11` types (e.g. `py::object`). Use a publicly "
"visible replacement type instead (e.g. `drake::pydrake::Object`).");
return GetPyParamScalarImpl(typeid(T));
Expand All @@ -114,12 +114,12 @@ inline py::object GetPyParamScalarImpl(
}

// Gets Python type for a C++ vector that is not registered using
// PYBIND11_MAKE_OPAQUE.
// {PYBIND11,NB}_MAKE_OPAQUE.
template <typename T>
inline py::object GetPyParamScalarImpl(type_pack<std::vector<T>> = {}) {
// Get inner type for validation.
py::object py_T = GetPyParamScalarImpl(type_pack<T>{});
if constexpr (!internal::is_generic_pybind_v<std::vector<T>>) {
if constexpr (!internal::is_generic_caster_v<std::vector<T>>) {
return py::module_::import_("pydrake.common.cpp_param").attr("List")[py_T];
} else {
return GetPyParamScalarImpl(typeid(std::vector<T>));
Expand All @@ -146,7 +146,7 @@ inline py::tuple GetPyParam(type_pack<Ts...> = {}) {
} // namespace pydrake
} // namespace drake

namespace pybind11 {
namespace PYDRAKE_BINDER_NAMESPACE {
namespace detail {

template <>
Expand All @@ -155,4 +155,4 @@ struct type_caster<drake::pydrake::Object>
drake::pydrake::internal::wrapper_pydrake_object> {};

} // namespace detail
} // namespace pybind11
} // namespace PYDRAKE_BINDER_NAMESPACE
20 changes: 14 additions & 6 deletions bindings/pydrake/common/cpp_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,14 +439,22 @@ def _rename_callable(f, scope, name, cls=None):
qualname = cls.__qualname__ + "." + name
else:
qualname = name

# If Python2, we have to wrap instancemethods + built-in functions to spoof
# the metadata.
type_requires_wrap = (
types.MethodType,
types.BuiltinMethodType,
types.BuiltinFunctionType,
)
if isinstance(f, type_requires_wrap):
def needs_wrap(f):
type_requires_wrap = (
types.MethodType,
types.BuiltinMethodType,
types.BuiltinFunctionType,
)
return (
isinstance(f, type_requires_wrap)
or "nb_method" in f.__class__.__name__
or "nb_func" in f.__class__.__name__
)

if needs_wrap(f):
orig = f

def f(*args, **kwargs):
Expand Down
8 changes: 7 additions & 1 deletion bindings/pydrake/common/cpp_template_pybind.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ inline py::object GetOrInitTemplate( // BR
py::tuple args = py::tuple(), py::dict kwargs = py::dict()) {
const char module_name[] = "pydrake.common.cpp_template";
py::handle m = py::module_::import_(module_name);
py::gil_scoped_acquire guard;
return m.attr("get_or_init")(
scope, name, m.attr(template_cls_name.c_str()), *args, **kwargs);
}
Expand Down Expand Up @@ -153,7 +154,12 @@ py::object AddTemplateMethod( // BR
const std::string instantiation_name =
internal::GetInstantiationName(py_template, param, mangle);
py::object py_func = py::cpp_function(std::forward<Method>(method),
py::name(instantiation_name.c_str()), py::is_method(scope),
py::name(instantiation_name.c_str()),
#ifdef PYDRAKE_USE_PYBIND11
py::is_method(scope),
#else // PYDRAKE_USE_NANOBIND
py::is_method(),
#endif
std::forward<Extra>(extra)...);
internal::AddInstantiation(py_template, py_func, param);
return py_template;
Expand Down
71 changes: 71 additions & 0 deletions bindings/pydrake/common/deprecation_pybind.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "drake/bindings/pydrake/common/wrap_function.h"
#include "drake/bindings/pydrake/pydrake_pybind.h"
#include "drake/common/drake_export.h"

namespace drake {
namespace pydrake {
Expand Down Expand Up @@ -79,26 +80,76 @@ auto WrapDeprecated(std::string message, Func&& func) {
internal::infer_function_info(std::forward<Func>(func)));
}

#ifdef PYDRAKE_USE_NANOBIND
namespace internal {

/// Deprecated wrapping of `py::init<>`.
template <typename CppClass, typename... Args>
struct DRAKE_NO_EXPORT PyInitDeprecatedCtorImpl
: py::def_visitor<PyInitDeprecatedCtorImpl<CppClass, Args...>> {
explicit PyInitDeprecatedCtorImpl(std::string message)
: message_(std::move(message)) {}
template <typename Class, typename... Extra>
void execute(Class& cl, const Extra&...) {
cl.def("__init__",
[message = std::move(message_)](CppClass* self, Args... args) {
WarnDeprecated(message);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
new (self) CppClass(std::forward<Args>(args)...);
#pragma GCC diagnostic pop
});
}
std::string message_;
};

/// Deprecated wrapping of `py::init(placement-new-callable)`.
template <typename Func>
struct PyInitDeprecatedCustomImpl
: py::def_visitor<PyInitDeprecatedCustomImpl<Func>> {
PyInitDeprecatedCustomImpl(std::string message, Func&& func)
: message_(std::move(message)), func_(std::forward<Func>(func)) {}
template <typename Class, typename... Extra>
void execute(Class& cl, const Extra&...) {
cl.def("__init__",
WrapDeprecated(std::move(message_), std::forward<Func>(func_)));
}
std::string message_;
Func&& func_;
};

} // namespace internal
#endif // PYDRAKE_USE_NANOBIND

/// Deprecated wrapping of `py::init<>`.
/// @note Only for `unique_ptr` holders. If using `shared_ptr`, talk to Eric.
template <typename Class, typename... Args>
auto py_init_deprecated(std::string message) {
// N.B. For simplicity, require that Class be passed up front, rather than
// trying to figure out how to pipe code into / mock `py::detail::initimpl`
// classes.
#ifdef PYDRAKE_USE_PYBIND11
return py::init([message = std::move(message)](Args... args) {
WarnDeprecated(message);
return std::make_unique<Class>(std::forward<Args>(args)...);
});
#else // PYDRAKE_USE_NANOBIND
return internal::PyInitDeprecatedCtorImpl<Class, Args...>(message);
#endif
}

/// Deprecated wrapping of `py::init(factory)`.
template <typename Func>
auto py_init_deprecated(std::string message, Func&& func) {
#ifdef PYDRAKE_USE_PYBIND11
return py::init(WrapDeprecated(std::move(message), std::forward<Func>(func)));
#else // PYDRAKE_USE_NANOBIND
return internal::PyInitDeprecatedCustomImpl<Func>(message, std::move(func));
#endif
}

/// The deprecated flavor of ParamInit<>.
#ifdef PYDRAKE_USE_PYBIND11
template <typename Class>
auto DeprecatedParamInit(std::string message) {
return py::init(WrapDeprecated(std::move(message), [](py::kwargs kwargs) {
Expand All @@ -113,6 +164,26 @@ auto DeprecatedParamInit(std::string message) {
return obj;
}));
}
#else // PYDRAKE_USE_NANOBIND
template <typename CppClass>
struct DRAKE_NO_EXPORT DeprecatedParamInit
: py::def_visitor<DeprecatedParamInit<CppClass>> {
explicit DeprecatedParamInit(std::string message)
: message_(std::move(message)) {}
template <typename Class, typename... Extra>
void execute(Class& cl, const Extra&...) {
cl.def("__init__", WrapDeprecated(std::move(message_),
[](CppClass* self, py::kwargs kwargs) {
new (self) Class();
py::object py_obj =
py::cast(self, py_rvp::reference);
py::module_::import_("pydrake").attr(
"_setattr_kwargs")(py_obj, kwargs);
}));
}
std::string message_;
};
#endif // PYDRAKE_USE_PYBIND11

} // namespace pydrake
} // namespace drake
2 changes: 1 addition & 1 deletion bindings/pydrake/common/eigen_geometry_py.cc
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ void DoScalarDependentDefinitions(py::module_ m, T) {
.def(
"multiply",
[](const Class& self, const Class& other) { return self * other; },
py::arg("other"), "RigidTransform multiplication")
py::arg("other").noconvert(), "RigidTransform multiplication")
.def(
"multiply",
[](const Class& self, const Vector3<T>& position) {
Expand Down
Loading