From 6dd489fe8f2549aa0c37c00c223f7556f3d8dd61 Mon Sep 17 00:00:00 2001 From: jichuanh Date: Sun, 10 May 2026 18:04:47 +0000 Subject: [PATCH 1/3] Drop explicit mujoco/mujoco-warp pins, defer to Newton Newton declares `mujoco` and `mujoco-warp` under its `[sim]` extra, so listing them again in IsaacLab's setup.py was redundant and forced the core `isaaclab` package (used by PhysX and Kit backends too) to pull in MuJoCo even when nothing in IsaacLab core imports it. Switch the Newton install spec to `newton[sim] @ git+...` and remove the direct pins. Mirror the same change in the wheel builder manifest so wheel builds stay in sync with `isaaclab_newton/setup.py`. --- source/isaaclab/changelog.d/jichuanh-drop-mujoco-deps.rst | 8 ++++++++ source/isaaclab/setup.py | 2 -- .../changelog.d/jichuanh-drop-mujoco-deps.rst | 8 ++++++++ source/isaaclab_newton/setup.py | 4 +--- tools/wheel_builder/res/python_packages.toml | 4 +--- 5 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 source/isaaclab/changelog.d/jichuanh-drop-mujoco-deps.rst create mode 100644 source/isaaclab_newton/changelog.d/jichuanh-drop-mujoco-deps.rst diff --git a/source/isaaclab/changelog.d/jichuanh-drop-mujoco-deps.rst b/source/isaaclab/changelog.d/jichuanh-drop-mujoco-deps.rst new file mode 100644 index 000000000000..67e2eef5aa2a --- /dev/null +++ b/source/isaaclab/changelog.d/jichuanh-drop-mujoco-deps.rst @@ -0,0 +1,8 @@ +Removed +^^^^^^^ + +* Removed explicit ``mujoco`` and ``mujoco-warp`` dependencies from + :mod:`isaaclab`. These packages are not used by ``isaaclab`` core and are + now resolved transitively through Newton's ``[sim]`` extra in + :mod:`isaaclab_newton`. Users installing only the PhysX or Kit backends no + longer pull in MuJoCo. diff --git a/source/isaaclab/setup.py b/source/isaaclab/setup.py index cfced25a24aa..1f3be503574e 100644 --- a/source/isaaclab/setup.py +++ b/source/isaaclab/setup.py @@ -30,8 +30,6 @@ # procedural-generation "trimesh", "pyglet>=2.1.6,<3", - "mujoco==3.8.0", - "mujoco-warp==3.8.0.1", # image processing "transformers==4.57.6", "einops", # needed for transformers, doesn't always auto-install diff --git a/source/isaaclab_newton/changelog.d/jichuanh-drop-mujoco-deps.rst b/source/isaaclab_newton/changelog.d/jichuanh-drop-mujoco-deps.rst new file mode 100644 index 000000000000..152b6744d80a --- /dev/null +++ b/source/isaaclab_newton/changelog.d/jichuanh-drop-mujoco-deps.rst @@ -0,0 +1,8 @@ +Changed +^^^^^^^ + +* Switched the Newton install to ``newton[sim]`` so that ``mujoco`` and + ``mujoco-warp`` are pulled in transitively via Newton's ``[sim]`` extra. + The explicit ``mujoco==3.8.0`` and ``mujoco-warp==3.8.0.1`` pins were + removed from :mod:`isaaclab_newton` — Newton is now the single source of + truth for those versions. diff --git a/source/isaaclab_newton/setup.py b/source/isaaclab_newton/setup.py index 4621e77f879b..5ddc4fc343d6 100644 --- a/source/isaaclab_newton/setup.py +++ b/source/isaaclab_newton/setup.py @@ -38,10 +38,8 @@ def run(self): EXTRAS_REQUIRE = { "all": [ "prettytable==3.3.0", - "mujoco==3.8.0", - "mujoco-warp==3.8.0.1", "PyOpenGL-accelerate==3.1.10", - "newton @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", + "newton[sim] @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", ], } diff --git a/tools/wheel_builder/res/python_packages.toml b/tools/wheel_builder/res/python_packages.toml index 9944580034e0..0184d832a756 100644 --- a/tools/wheel_builder/res/python_packages.toml +++ b/tools/wheel_builder/res/python_packages.toml @@ -84,9 +84,7 @@ pyproject.optional-dependencies.all = [ # ================================================================================ { "newton" = [ "warp-lang==1.13.0", - "mujoco==3.8.0", - "mujoco-warp==3.8.0.1", - "newton @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", + "newton[sim] @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", "PyOpenGL-accelerate==3.1.10" ] }, # ================================================================================ From 48018cb319e9cf774e4896071343d81c8e2bdf29 Mon Sep 17 00:00:00 2001 From: jichuanh Date: Mon, 11 May 2026 08:27:54 +0000 Subject: [PATCH 2/3] Use newton[sim] in all Newton declarations CI on isaaclab_tasks / isaaclab_newton failed because pip resolves `newton @ git+url` once per URL: the bare spec in isaaclab_visualizers and isaaclab_physx was processed before the `newton[sim] @ git+url` in isaaclab_newton, so the `[sim]` extra (which carries mujoco and mujoco-warp) was dropped and tests hit `ModuleNotFoundError: mujoco`. Switch every `newton @ git+...` site in source/ to `newton[sim] @ ...` so any install order pulls the MuJoCo solver deps transitively. --- .../changelog.d/jichuanh-drop-mujoco-deps.rst | 8 ++++++++ source/isaaclab_physx/setup.py | 2 +- .../changelog.d/jichuanh-drop-mujoco-deps.rst | 8 ++++++++ source/isaaclab_visualizers/setup.py | 6 +++--- 4 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 source/isaaclab_physx/changelog.d/jichuanh-drop-mujoco-deps.rst create mode 100644 source/isaaclab_visualizers/changelog.d/jichuanh-drop-mujoco-deps.rst diff --git a/source/isaaclab_physx/changelog.d/jichuanh-drop-mujoco-deps.rst b/source/isaaclab_physx/changelog.d/jichuanh-drop-mujoco-deps.rst new file mode 100644 index 000000000000..24821359c927 --- /dev/null +++ b/source/isaaclab_physx/changelog.d/jichuanh-drop-mujoco-deps.rst @@ -0,0 +1,8 @@ +Changed +^^^^^^^ + +* Switched the Newton install spec to ``newton[sim]`` in the ``newton`` + extra so the MuJoCo solver dependencies are pulled in transitively. + Required because pip resolves a git-URL requirement once for the URL; + a bare ``newton @ git+...`` here would shadow the ``[sim]`` extra + requested elsewhere. diff --git a/source/isaaclab_physx/setup.py b/source/isaaclab_physx/setup.py index 9cc172addf50..1850fe9710d7 100644 --- a/source/isaaclab_physx/setup.py +++ b/source/isaaclab_physx/setup.py @@ -20,7 +20,7 @@ EXTRAS_REQUIRE = { "newton": [ - "newton @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", + "newton[sim] @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", ], } diff --git a/source/isaaclab_visualizers/changelog.d/jichuanh-drop-mujoco-deps.rst b/source/isaaclab_visualizers/changelog.d/jichuanh-drop-mujoco-deps.rst new file mode 100644 index 000000000000..043188cbee35 --- /dev/null +++ b/source/isaaclab_visualizers/changelog.d/jichuanh-drop-mujoco-deps.rst @@ -0,0 +1,8 @@ +Changed +^^^^^^^ + +* Switched the Newton install spec to ``newton[sim]`` in the ``newton``, + ``rerun``, and ``viser`` extras so the MuJoCo solver dependencies are + pulled in transitively. Required because pip resolves a git-URL + requirement once for the URL; a bare ``newton @ git+...`` here would + shadow the ``[sim]`` extra requested elsewhere. diff --git a/source/isaaclab_visualizers/setup.py b/source/isaaclab_visualizers/setup.py index 9ad52a712360..277ce884c88c 100644 --- a/source/isaaclab_visualizers/setup.py +++ b/source/isaaclab_visualizers/setup.py @@ -17,16 +17,16 @@ "kit": [], "newton": [ "warp-lang", - "newton @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", + "newton[sim] @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", "PyOpenGL-accelerate", "imgui-bundle>=1.92.5", ], "rerun": [ - "newton @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", + "newton[sim] @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", "rerun-sdk>=0.29.0", ], "viser": [ - "newton @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", + "newton[sim] @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", "viser>=1.0.16", ], } From 037979eb601af027613350f3519b1ef4b6fa55ec Mon Sep 17 00:00:00 2001 From: jichuanh Date: Mon, 11 May 2026 12:42:47 +0000 Subject: [PATCH 3/3] Centralize shared external pins in tools/python_deps.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Six setup.py sites and a wheel-builder TOML each hand-typed the same Newton, Warp, Torch, NumPy, prettytable, and PyOpenGL-accelerate pins. A version bump touched all of them and silently drifted when one site was missed — recent example: only two of six sites switched to `newton[sim] @ git+...`, which let pip resolve the bare `newton` first and drop the requested `[sim]` extra, breaking installs. Move the canonical strings into tools/python_deps.py and have every setup.py import them. The wheel builder's gen_pyproject.py validates that tools/wheel_builder/res/python_packages.toml still matches the constants before emitting the wheel pyproject — drift between Python and TOML now fails the Build Wheel job with a clear message naming the constant and the file out of sync. The dependency graph produced by `pip install` is unchanged from develop; this is pure refactoring. --- .../changelog.d/jichuanh-unify-deps.skip | 1 + source/isaaclab/setup.py | 13 ++-- .../changelog.d/jichuanh-unify-deps.skip | 1 + source/isaaclab_newton/setup.py | 12 +++- .../changelog.d/jichuanh-unify-deps.skip | 1 + source/isaaclab_physx/setup.py | 7 +- .../changelog.d/jichuanh-unify-deps.skip | 1 + source/isaaclab_rl/setup.py | 7 +- .../changelog.d/jichuanh-unify-deps.skip | 1 + source/isaaclab_tasks/setup.py | 9 ++- .../changelog.d/jichuanh-unify-deps.skip | 1 + source/isaaclab_visualizers/setup.py | 18 ++++-- tools/python_deps.py | 37 +++++++++++ tools/wheel_builder/gen_pyproject.py | 64 +++++++++++++++++++ 14 files changed, 157 insertions(+), 16 deletions(-) create mode 100644 source/isaaclab/changelog.d/jichuanh-unify-deps.skip create mode 100644 source/isaaclab_newton/changelog.d/jichuanh-unify-deps.skip create mode 100644 source/isaaclab_physx/changelog.d/jichuanh-unify-deps.skip create mode 100644 source/isaaclab_rl/changelog.d/jichuanh-unify-deps.skip create mode 100644 source/isaaclab_tasks/changelog.d/jichuanh-unify-deps.skip create mode 100644 source/isaaclab_visualizers/changelog.d/jichuanh-unify-deps.skip create mode 100644 tools/python_deps.py diff --git a/source/isaaclab/changelog.d/jichuanh-unify-deps.skip b/source/isaaclab/changelog.d/jichuanh-unify-deps.skip new file mode 100644 index 000000000000..99e09e907d3a --- /dev/null +++ b/source/isaaclab/changelog.d/jichuanh-unify-deps.skip @@ -0,0 +1 @@ +Refactor only — no behaviour change for end users; install graph is identical. diff --git a/source/isaaclab/setup.py b/source/isaaclab/setup.py index 1f3be503574e..58e87d3498f9 100644 --- a/source/isaaclab/setup.py +++ b/source/isaaclab/setup.py @@ -6,6 +6,7 @@ """Installation script for the 'isaaclab' python package.""" import os +import sys import toml from setuptools import setup @@ -15,13 +16,17 @@ # Read the extension.toml file EXTENSION_TOML_DATA = toml.load(os.path.join(EXTENSION_PATH, "config", "extension.toml")) +# Pull shared external version pins from the single source of truth. +sys.path.insert(0, os.path.realpath(os.path.join(EXTENSION_PATH, "..", "..", "tools"))) +from python_deps import NUMPY, PRETTYTABLE, TORCH, WARP_LANG # noqa: E402 + # Minimum dependencies required prior to installation INSTALL_REQUIRES = [ # generic - "numpy>=2", - "torch>=2.10", + NUMPY, + TORCH, "onnx>=1.18.0", # 1.16.2 throws access violation on Windows - "prettytable==3.3.0", + PRETTYTABLE, "toml", # devices "hidapi==0.14.0.post2", @@ -33,7 +38,7 @@ # image processing "transformers==4.57.6", "einops", # needed for transformers, doesn't always auto-install - "warp-lang==1.13.0", + WARP_LANG, "matplotlib>=3.10.3", # minimum version for Python 3.12 support # make sure this is consistent with isaac sim version "pillow==12.1.1", diff --git a/source/isaaclab_newton/changelog.d/jichuanh-unify-deps.skip b/source/isaaclab_newton/changelog.d/jichuanh-unify-deps.skip new file mode 100644 index 000000000000..99e09e907d3a --- /dev/null +++ b/source/isaaclab_newton/changelog.d/jichuanh-unify-deps.skip @@ -0,0 +1 @@ +Refactor only — no behaviour change for end users; install graph is identical. diff --git a/source/isaaclab_newton/setup.py b/source/isaaclab_newton/setup.py index 5ddc4fc343d6..64dcd47139ab 100644 --- a/source/isaaclab_newton/setup.py +++ b/source/isaaclab_newton/setup.py @@ -7,11 +7,17 @@ import os import shutil +import sys import toml from setuptools import setup from setuptools.command.build_py import build_py as _build_py +# Pull shared external version pins from the single source of truth. +_HERE = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.realpath(os.path.join(_HERE, "..", "..", "tools"))) +from python_deps import NEWTON, PRETTYTABLE, PYOPENGL_ACCELERATE # noqa: E402 + class build_py(_build_py): """Custom build command that bundles config/extension.toml into the package. @@ -37,9 +43,9 @@ def run(self): EXTRAS_REQUIRE = { "all": [ - "prettytable==3.3.0", - "PyOpenGL-accelerate==3.1.10", - "newton[sim] @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", + PRETTYTABLE, + PYOPENGL_ACCELERATE, + NEWTON, ], } diff --git a/source/isaaclab_physx/changelog.d/jichuanh-unify-deps.skip b/source/isaaclab_physx/changelog.d/jichuanh-unify-deps.skip new file mode 100644 index 000000000000..99e09e907d3a --- /dev/null +++ b/source/isaaclab_physx/changelog.d/jichuanh-unify-deps.skip @@ -0,0 +1 @@ +Refactor only — no behaviour change for end users; install graph is identical. diff --git a/source/isaaclab_physx/setup.py b/source/isaaclab_physx/setup.py index 1850fe9710d7..beffc54246e5 100644 --- a/source/isaaclab_physx/setup.py +++ b/source/isaaclab_physx/setup.py @@ -6,6 +6,7 @@ """Installation script for the 'isaaclab_physx' python package.""" import os +import sys import toml from setuptools import setup @@ -15,12 +16,16 @@ # Read the extension.toml file EXTENSION_TOML_DATA = toml.load(os.path.join(EXTENSION_PATH, "config", "extension.toml")) +# Pull shared external version pins from the single source of truth. +sys.path.insert(0, os.path.realpath(os.path.join(EXTENSION_PATH, "..", "..", "tools"))) +from python_deps import NEWTON # noqa: E402 + # Minimum dependencies required prior to installation INSTALL_REQUIRES = [] EXTRAS_REQUIRE = { "newton": [ - "newton[sim] @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", + NEWTON, ], } diff --git a/source/isaaclab_rl/changelog.d/jichuanh-unify-deps.skip b/source/isaaclab_rl/changelog.d/jichuanh-unify-deps.skip new file mode 100644 index 000000000000..99e09e907d3a --- /dev/null +++ b/source/isaaclab_rl/changelog.d/jichuanh-unify-deps.skip @@ -0,0 +1 @@ +Refactor only — no behaviour change for end users; install graph is identical. diff --git a/source/isaaclab_rl/setup.py b/source/isaaclab_rl/setup.py index 53255aa55b4f..5125f190aa92 100644 --- a/source/isaaclab_rl/setup.py +++ b/source/isaaclab_rl/setup.py @@ -7,6 +7,7 @@ import itertools import os +import sys import toml from setuptools import setup @@ -16,11 +17,15 @@ # Read the extension.toml file EXTENSION_TOML_DATA = toml.load(os.path.join(EXTENSION_PATH, "config", "extension.toml")) +# Pull shared external version pins from the single source of truth. +sys.path.insert(0, os.path.realpath(os.path.join(EXTENSION_PATH, "..", "..", "tools"))) +from python_deps import TORCH # noqa: E402 + # Minimum dependencies required prior to installation INSTALL_REQUIRES = [ # generic "numpy", - "torch>=2.10", + TORCH, "torchvision>=0.25.0", # ensure compatibility with torch 2.10.0 "protobuf>=4.25.8,!=5.26.0", # configuration management diff --git a/source/isaaclab_tasks/changelog.d/jichuanh-unify-deps.skip b/source/isaaclab_tasks/changelog.d/jichuanh-unify-deps.skip new file mode 100644 index 000000000000..99e09e907d3a --- /dev/null +++ b/source/isaaclab_tasks/changelog.d/jichuanh-unify-deps.skip @@ -0,0 +1 @@ +Refactor only — no behaviour change for end users; install graph is identical. diff --git a/source/isaaclab_tasks/setup.py b/source/isaaclab_tasks/setup.py index a719231ca986..dd1cd070c711 100644 --- a/source/isaaclab_tasks/setup.py +++ b/source/isaaclab_tasks/setup.py @@ -6,6 +6,7 @@ """Installation script for the 'isaaclab_tasks' python package.""" import os +import sys import toml from setuptools import setup @@ -15,11 +16,15 @@ # Read the extension.toml file EXTENSION_TOML_DATA = toml.load(os.path.join(EXTENSION_PATH, "config", "extension.toml")) +# Pull shared external version pins from the single source of truth. +sys.path.insert(0, os.path.realpath(os.path.join(EXTENSION_PATH, "..", "..", "tools"))) +from python_deps import NUMPY, TORCH # noqa: E402 + # Minimum dependencies required prior to installation INSTALL_REQUIRES = [ # generic - "numpy>=2", - "torch>=2.10", + NUMPY, + TORCH, "torchvision>=0.25.0", # ensure compatibility with torch 2.10.0 "protobuf>=4.25.8,!=5.26.0", # basic logger diff --git a/source/isaaclab_visualizers/changelog.d/jichuanh-unify-deps.skip b/source/isaaclab_visualizers/changelog.d/jichuanh-unify-deps.skip new file mode 100644 index 000000000000..99e09e907d3a --- /dev/null +++ b/source/isaaclab_visualizers/changelog.d/jichuanh-unify-deps.skip @@ -0,0 +1 @@ +Refactor only — no behaviour change for end users; install graph is identical. diff --git a/source/isaaclab_visualizers/setup.py b/source/isaaclab_visualizers/setup.py index 277ce884c88c..3063e2368cba 100644 --- a/source/isaaclab_visualizers/setup.py +++ b/source/isaaclab_visualizers/setup.py @@ -5,8 +5,16 @@ """Installation script for the 'isaaclab_visualizers' python package.""" +import os +import sys + from setuptools import setup +# Pull shared external version pins from the single source of truth. +_HERE = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.realpath(os.path.join(_HERE, "..", "..", "tools"))) +from python_deps import NEWTON, PYOPENGL_ACCELERATE, WARP_LANG # noqa: E402 + # Base requirements shared across visualizer backends. INSTALL_REQUIRES = [ "isaaclab", @@ -16,17 +24,17 @@ EXTRAS_REQUIRE = { "kit": [], "newton": [ - "warp-lang", - "newton[sim] @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", - "PyOpenGL-accelerate", + WARP_LANG, + NEWTON, + PYOPENGL_ACCELERATE, "imgui-bundle>=1.92.5", ], "rerun": [ - "newton[sim] @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", + NEWTON, "rerun-sdk>=0.29.0", ], "viser": [ - "newton[sim] @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2", + NEWTON, "viser>=1.0.16", ], } diff --git a/tools/python_deps.py b/tools/python_deps.py new file mode 100644 index 000000000000..39ef40f25b75 --- /dev/null +++ b/tools/python_deps.py @@ -0,0 +1,37 @@ +# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +"""Single source of truth for shared external pip dependencies. + +Every ``setup.py`` in ``source/`` that needs one of these packages imports the +constant from here so a version bump touches one line. The wheel builder's +``tools/wheel_builder/res/python_packages.toml`` mirrors these values and is +kept in sync by :mod:`tools.test_python_deps_sync`. +""" + +# NOTE: keep this file dependency-free (standard library only) so it can be +# imported by ``setup.py`` before pip has resolved anything. + +NEWTON = "newton[sim] @ git+https://github.com/newton-physics/newton.git@v1.2.0rc2" +"""Newton physics engine, pulled via the ``sim`` extra so ``mujoco`` / +``mujoco-warp`` come along transitively. Every ``newton @ ...`` declaration +in the repo must use this exact spec — pip resolves a git-URL requirement +once per URL, so a bare declaration anywhere shadows requested extras +elsewhere.""" + +WARP_LANG = "warp-lang==1.13.0" +"""NVIDIA Warp Python bindings.""" + +TORCH = "torch>=2.10" +"""PyTorch floor for CUDA 12.8/13 wheel compatibility.""" + +NUMPY = "numpy>=2" +"""NumPy 2.x is required for the rest of the stack.""" + +PRETTYTABLE = "prettytable==3.3.0" +"""Tabular formatting; pinned to avoid Isaac Sim prebundle conflicts.""" + +PYOPENGL_ACCELERATE = "PyOpenGL-accelerate==3.1.10" +"""PyOpenGL Cython accelerator; pinned across Newton-side packages.""" diff --git a/tools/wheel_builder/gen_pyproject.py b/tools/wheel_builder/gen_pyproject.py index a8cf3fdd8d5d..e69a6427994f 100644 --- a/tools/wheel_builder/gen_pyproject.py +++ b/tools/wheel_builder/gen_pyproject.py @@ -5,6 +5,7 @@ """Generate pyproject.toml for the isaaclab wheel from python_packages.toml.""" +import os import sys import tomllib @@ -17,10 +18,73 @@ output_path = sys.argv[2] version = sys.argv[3] +# Add `tools/` to sys.path so we can validate that the wheel TOML stays in +# sync with the canonical pins in tools/python_deps.py. +_HERE = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.dirname(_HERE)) +import python_deps # noqa: E402 + with open(packages_toml_path, "rb") as f: data = tomllib.load(f) pkg = data["isaaclab"] + +def _pkg_name(req: str) -> str: + """Extract the lowercase package name from a PEP 508 requirement string.""" + return ( + req.split("[")[0] + .split(";")[0] + .split(">")[0] + .split("<")[0] + .split("=")[0] + .split("!")[0] + .split("~")[0] + .split("@")[0] + .strip() + .lower() + ) + + +# Validate that every shared pin in tools/python_deps.py is the exact spec used in +# this TOML. Catches drift introduced when a version bumps in only one place. +_SHARED = { + "NEWTON": "newton", + "WARP_LANG": "warp-lang", + "TORCH": "torch", + "NUMPY": "numpy", + "PRETTYTABLE": "prettytable", + "PYOPENGL_ACCELERATE": "pyopengl-accelerate", +} +_seen: dict[str, set[str]] = {name: set() for name in _SHARED.values()} + + +def _scan(value): + if isinstance(value, list): + for item in value: + if isinstance(item, str): + name = _pkg_name(item) + if name in _seen: + _seen[name].add(item) + else: + _scan(item) + elif isinstance(value, dict): + for v in value.values(): + _scan(v) + + +_scan(data) +for const_name, pkg_name in _SHARED.items(): + expected = getattr(python_deps, const_name) + found = _seen[pkg_name] + if not found or found != {expected}: + msg = ( + f"Wheel TOML out of sync with tools/python_deps.py:{const_name}.\n" + f" Expected (from python_deps.py): {expected!r}\n" + f" Found in {packages_toml_path}: {sorted(found) or 'none'}\n" + " Update one to match the other; tools/python_deps.py is the source of truth." + ) + raise SystemExit(msg) + # Collect dependencies (deduplicated, preserving order) raw_deps = pkg["pyproject"]["dependencies"]["all"] seen = set()