Skip to content

Clean up sub module packaging and remove setup.py#5785

Merged
StafaH merged 13 commits into
isaac-sim:developfrom
StafaH:mh/pyproject_rework
May 28, 2026
Merged

Clean up sub module packaging and remove setup.py#5785
StafaH merged 13 commits into
isaac-sim:developfrom
StafaH:mh/pyproject_rework

Conversation

@StafaH
Copy link
Copy Markdown
Contributor

@StafaH StafaH commented May 26, 2026

Description

Migrates all IsaacLab packages from setup.py to pyproject.toml as the sole build system declaration, and introduces uv as the recommended package manager for development installs.

What changed:

  • Removed setup.py from all 15 source packages (isaaclab, isaaclab_assets, isaaclab_contrib, isaaclab_experimental, isaaclab_mimic, isaaclab_newton, isaaclab_ov, isaaclab_ovphysx, isaaclab_physx, isaaclab_ppisp, isaaclab_rl, isaaclab_tasks, isaaclab_tasks_experimental, isaaclab_teleop, isaaclab_visualizers). All metadata (dependencies, extras, entry points, classifiers) is now declared exclusively in each package's pyproject.toml.
  • Added a root pyproject.toml (isaaclab-dev) that wires all source packages together as editable path dependencies via [tool.uv.sources], enabling a single uv sync to install the full development environment. isaaclab-ppisp is included in both the default dependencies and the [all] extra so that pip install isaaclab[all] and uv sync install the same set of packages.
  • Replaced the third-party toml import in simulation_context.py and its test with stdlib tomllib (available since Python 3.11), removing an undeclared dependency. Module-level constants (ISAACLAB_EXT_DIR, ISAACLAB_METADATA, ISAACLAB_ASSETS_EXT_DIR, etc.) are preserved and continue to read from config/extension.toml via tomllib.
  • Normalized extra names in isaaclab_rl to their PEP 685 canonical hyphenated forms — the underscore aliases rsl_rl and rl_games are removed. Migration: use pip install isaaclab-rl[rsl-rl] and pip install isaaclab-rl[rl-games] going forward.
  • Fixed isaaclab_ovphysx/pyproject.toml declaring requires-python = ">=3.11" — corrected to >=3.12 to match the rest of the project.
  • Added a version-parity assertion to tools/changelog/cli.py: current_version() now raises immediately if config/extension.toml and pyproject.toml disagree, preventing silent version drift from corrupting future changelog bumps.
  • Simplified __init__.py version detection across packages — the importlib.metadata lookup is now a clean try/except with a "0.0.0" fallback, removing boilerplate that was previously spread across every package.
  • Moved test dependencies (pytest, pytest-mock, junitparser, flatdict, flaky) out of base install_requires and into a new test optional extra (pip install isaaclab[test]). The run-tests CI action now installs these unconditionally before invoking pytest, fixing the No module named pytest failure that occurred when running against the Isaac Sim bundled Python.
  • Fixed the isaacsim and all extras in source/isaaclab/pyproject.toml pinning isaacsim==5.1.0 — updated to >=6.0.0 to match the version targeted by isaaclab.sh -i and install.py.
  • Updated the install.py CLI command and benchmark test utilities to match the new package naming conventions.

Fixes # (issue)

Type of change

  • New feature (non-breaking change which adds functionality)
  • Breaking change (existing functionality will not work without user modification)

Breaking changes

  • isaaclab_rl[rsl_rl] and isaaclab_rl[rl_games] extras no longer exist. Use isaaclab_rl[rsl-rl] and isaaclab_rl[rl-games] respectively.

Screenshots

N/A — build system change only.

Checklist

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with ./isaaclab.sh --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the changelog and the corresponding version in the extension's config/extension.toml file
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

@github-actions github-actions Bot added asset New asset feature or request isaac-mimic Related to Isaac Mimic team infrastructure labels May 26, 2026
Copy link
Copy Markdown

@isaaclab-review-bot isaaclab-review-bot Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

This is a well-structured migration from setup.py to pyproject.toml for all 15 Isaac Lab packages. The changes follow modern Python packaging standards and simplify dependency management.

✅ What Looks Good

  1. Consistent build system: All packages use setuptools>=70.0,<82.0.0 with wheel — good for reproducibility.

  2. tomllib migration: Replacing the third-party toml package with stdlib tomllib (Python 3.11+) removes an undeclared dependency. The binary mode file handling ("rb") is correctly implemented.

  3. Simplified version detection: The importlib.metadata approach is the modern standard and eliminates the need to parse extension.toml at import time.

  4. Root pyproject.toml enhancement: The [tool.uv.sources] section for editable path dependencies enables clean uv sync workflows.

  5. Missing package fix: Adding isaaclab-ppisp to the root dependencies addresses a gap in the previous setup.

  6. Test updates: Tests correctly updated to reference pyproject.toml instead of setup.py.

📋 Observations (Non-Blocking)

  1. Python version inconsistency: Most packages require >=3.12, but isaaclab_ovphysx/pyproject.toml specifies requires-python = ">=3.11". Is this intentional for broader ovphysx compatibility, or should it align with >=3.12?

  2. Removed module constants: Several packages previously exported constants like:

    • ISAACLAB_EXT_DIR, ISAACLAB_ASSETS_EXT_DIR, etc.
    • ISAACLAB_METADATA, ISAACLAB_ASSETS_METADATA, etc.

    These are no longer available. If any external code or user scripts depended on these constants, they'll encounter AttributeError. Consider documenting this as a breaking change in the changelog, or adding deprecation stubs that emit warnings.

  3. Dependency flexibility changes: Some exact pins became ranges:

    • hidapi==0.14.0.post2hidapi>=0.14.0
    • gymnasium==1.2.1gymnasium>=1.2.0
    • prettytable==3.3.0prettytable>=3.3.0
    • h5py==3.15.1h5py>=3.15.0
    • etc.

    This is generally a positive change for compatibility, but worth noting for the release notes.

  4. install.py backward compatibility: The updated check at line 518:

    if not item.is_dir() or not ((item / "pyproject.toml").exists() or (item / "setup.py").exists()):

    This maintains backward compatibility — nice touch for transitional installs.

  5. Silent version fallback: The "0.0.0" fallback on PackageNotFoundError is fine for development, but could silently mask installation issues in production. Consider logging a warning when falling back.

⚠️ CI Note

The "Check changelog fragments" check is failing. Make sure to add a changelog fragment for this PR before merging.

Verdict

The migration is clean and follows best practices. The pending Installation Tests (conda/uv) will be important to verify the new packaging works end-to-end. Once CI is green and the changelog fragment is added, this should be good to merge.


Update (b71929a): The author has addressed the CI changelog fragment issue by adding:

  1. mh-pyproject_rework.rst in source/isaaclab/changelog.d/ — Documents the key changes:

    • Replacing third-party toml dependency with stdlib tomllib
    • Migrating package build from setup.py to pyproject.toml only
  2. .skip files added to 11 other submodules (isaaclab_assets, isaaclab_contrib, isaaclab_experimental, isaaclab_mimic, isaaclab_newton, isaaclab_ov, isaaclab_ovphysx, isaaclab_physx, isaaclab_rl, isaaclab_tasks, isaaclab_teleop) — indicating no changelog entry needed for these packages as the changes are internal build-only.

✅ The changelog concern from my initial review is now resolved. This should unblock the CI check.


Update (f1d427e): Significant improvements in this push! The author has addressed my earlier observation about removed module constants:

✅ Module Constants Restored

The ISAACLAB_EXT_DIR and ISAACLAB_METADATA constants (and equivalents in other packages) are now restored with the new tomllib-based implementation:

Package Constants Restored
isaaclab ISAACLAB_EXT_DIR, ISAACLAB_METADATA
isaaclab_assets ISAACLAB_ASSETS_EXT_DIR, ISAACLAB_ASSETS_DATA_DIR, ISAACLAB_ASSETS_METADATA
isaaclab_contrib ISAACLAB_CONTRIB_EXT_DIR, ISAACLAB_CONTRIB_METADATA
isaaclab_tasks ISAACLAB_TASKS_EXT_DIR, ISAACLAB_TASKS_METADATA

This addresses the backward compatibility concern from my initial review. 👍

Other Changes

  1. Python version fixed: isaaclab_ovphysx now requires >=3.12 (was >=3.11) — aligns with the rest of the packages ✅

  2. Extra names normalized (Breaking): The underscore aliases for extras are removed:

    • rsl_rl → use rsl-rl
    • rl_games → use rl-games

    A changelog fragment (isaaclab_rl/changelog.d/mh-pyproject_rework.rst) properly documents this PEP 685 normalization. Users will need to update their install commands.

  3. Test cleanup: Removed redundant test cases checking for underscore-aliased extras.

  4. Version mismatch safety: The changelog CLI (tools/changelog/cli.py) now validates that config/extension.toml and pyproject.toml versions match before compiling — good safeguard against accidental version drift.

  5. Changelog updated: The main isaaclab changelog entry now documents that ISAACLAB_EXT_DIR and ISAACLAB_METADATA are preserved using tomllib.

Verdict

This push resolves all my previous observations. The migration is now complete with proper backward compatibility for exported constants. Ready to merge once CI passes.


Update (449f409): This push refines CI and dependency management:

Changes

  1. Test dependencies moved to optional extra: Test packages (pytest, pytest-mock, junitparser, flatdict>=4.1.0, flaky) are now in [project.optional-dependencies.test] instead of base dependencies. Install with pip install isaaclab[test] for the full test environment.

  2. CI workflow updated: The GitHub Actions workflow (.github/actions/run-tests/action.yml) now explicitly installs test dependencies before running tests, ensuring CI works with the slimmer base package.

  3. Isaac Sim version bump: isaacsim[all,extscache] constraint changed from ==5.1.0 to >=6.0.0 — prepares for upcoming Isaac Sim 6.x compatibility.

  4. Removed typing_extensions: The typing_extensions>=4.14.0 dependency was removed from base requirements.

  5. Changelog updated: Documents the test extras change with install instructions.

✅ Good Practice

Moving test dependencies to an optional extra is the right call — it keeps the base install lean for production deployments while still making the full test suite available via pip install isaaclab[test].

Verdict

Clean incremental update. The Isaac Sim 6.x version bump is notable for downstream compatibility. Ready to merge once CI passes.


Update (b4d5c38): This push removes legacy OVRTX 0.2.x code paths from the isaaclab_ov package:

Changes

  1. License metadata update: typing_extensions license updated from PSF-2.0 to Python Software Foundation License with corrected comment PSFL / OSRB.

  2. OVRTX 0.3.0+ now required: The renderer now assumes OVRTX ≥0.3.0:

    • Removed _OVRTX_VERSION and _IS_OVRTX_0_3_0_OR_NEWER version checks
    • read_gpu_transforms=True is now unconditional
    • open_usd_from_string() is the only USD loading path (removed add_usd() file-based fallback)
    • reset_stage() replaces manual remove_usd() handle cleanup
  3. Removed legacy kernels from ovrtx_renderer_kernels.py:

    • extract_all_depth_tiles_kernel_legacy (2D depth buffer)
    • generate_random_colors_from_ids_kernel_legacy (2D ID buffer)

    The 3D-buffer variants are now the only implementation.

  4. Simplified create_scene_partition_attributes(): Removed enable_scene_partition_workaround parameter (was for OVRTX 0.2.x primvar inheritance issues). Now only sets omni:scenePartition on Camera prims.

  5. Changelog fragment added: remove-legacy-ovrtx-code-path.rst documents the removal.

  6. Test cleanup: Removed test classes TestExtractAllDepthTilesKernelLegacy and TestRandomColorsFromIdsKernelLegacy (~160 lines).

✅ Assessment

This is a clean deprecation of legacy code paths. The version gating was adding maintenance overhead with minimal benefit since OVRTX 0.3.0+ is the supported baseline. Removing ~300 lines of compatibility code improves maintainability.

Verdict

Ready to merge once CI passes. The changes are all internal to isaaclab_ov and don't affect the public API.


Update (ee4b962): Minor CI fix:

Changes

  1. flatdict version pin relaxed: In .github/actions/run-tests/action.yml, the test dependency flatdict>=4.1.0 changed to just flatdict (unpinned).

Assessment

This is a trivial cleanup — the minimum version constraint was unnecessary since flatdict has been stable for years. Reduces potential pip resolver friction.

Verdict

No impact on functionality. Ready to merge once CI passes.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 26, 2026

Greptile Summary

This PR migrates all 15 IsaacLab sub-packages from setup.py to pyproject.toml as the sole build system declaration, replaces the third-party toml dependency with stdlib tomllib throughout, and standardizes __version__ detection across all packages using importlib.metadata.

  • All setup.py files are removed; metadata (dependencies, extras, entry points) is now declared exclusively in each package's pyproject.toml. A root pyproject.toml (isaaclab-dev) wires all packages as editable path dependencies for uv sync.
  • simulation_context.py and its test are updated to use tomllib with binary-mode file opens, eliminating the undeclared toml runtime dependency.
  • tools/changelog/cli.py is extended to keep pyproject.toml version fields in sync when the changelog tool bumps a package version.

Confidence Score: 3/5

The build-system migration is mechanically sound, but removing previously exported module-level constants from isaaclab_assets without updating the documented usage example leaves an ImportError landmine for any user following the README.

The ISAACLAB_ASSETS_DATA_DIR/ISAACLAB_ASSETS_EXT_DIR/ISAACLAB_ASSETS_METADATA removal is a real breaking-API change: source/isaaclab_assets/docs/README.md still shows from isaaclab_assets import ISAACLAB_ASSETS_DATA_DIR as the canonical pattern for referring to local assets, and no Python file in the repo was updated to remove that import, meaning downstream users following the docs will hit an immediate ImportError. Additionally, duplicate normalized extra names in isaaclab_rl/pyproject.toml and the two-source-of-truth version scheme in the changelog tool introduce correctness risks.

source/isaaclab_assets/isaaclab_assets/init.py and source/isaaclab_assets/docs/README.md (removed public symbols, stale docs); source/isaaclab_rl/pyproject.toml (duplicate extras); tools/changelog/cli.py (dual version sources); source/isaaclab/pyproject.toml (missing isaaclab-ppisp in [all]).

Important Files Changed

Filename Overview
source/isaaclab/isaaclab/init.py Simplified version detection using importlib.metadata; removes toml/tomllib dependency and the ISAACLAB_EXT_DIR/ISAACLAB_METADATA module-level constants (not referenced by any Python code in the repo).
source/isaaclab_assets/isaaclab_assets/init.py Removes ISAACLAB_ASSETS_DATA_DIR, ISAACLAB_ASSETS_EXT_DIR, and ISAACLAB_ASSETS_METADATA without updating the README that documents them as the public API for locating assets.
source/isaaclab/isaaclab/sim/simulation_context.py Correctly replaces third-party toml with stdlib tomllib, opening .kit files in binary mode as required by tomllib.load().
source/isaaclab/pyproject.toml Migrates all metadata from setup.py; isaaclab-ppisp is missing from the [all] optional-dependencies group, and underscore-named sub-packages in all differ stylistically from the hyphenated names in the root pyproject.toml.
source/isaaclab_rl/pyproject.toml Full metadata migration from setup.py; duplicates rsl-rl/rsl_rl and rl-games/rl_games extras which have identical content and the same PEP 685 normalized name.
tools/changelog/cli.py Extends write_version() to also update pyproject.toml, but current_version() still reads exclusively from extension.toml, creating two sources of truth with no drift-detection guard.
source/isaaclab/isaaclab/cli/commands/install.py Updated to check for pyproject.toml OR setup.py for backward compatibility; warning message slightly misleading as it only mentions pyproject.toml.
source/isaaclab/test/cli/test_wheel_builder_metadata.py Correctly migrated from AST-parsing setup.py to tomllib-parsing pyproject.toml; iterates both rsl-rl and rsl_rl keys as a workaround for the duplicated extras.
pyproject.toml Root dev workspace pyproject.toml updated to add isaaclab-ppisp as a dependency and wire its editable path source.

Comments Outside Diff (2)

  1. source/isaaclab_assets/isaaclab_assets/__init__.py, line 1-12 (link)

    P1 Breaking removal of public API symbols

    ISAACLAB_ASSETS_DATA_DIR, ISAACLAB_ASSETS_EXT_DIR, and ISAACLAB_ASSETS_METADATA were previously exported from this module and are documented as the public way to locate asset files (see source/isaaclab_assets/docs/README.md, which still shows from isaaclab_assets import ISAACLAB_ASSETS_DATA_DIR). Any code or downstream project following that documentation will now receive an ImportError at import time. The README was not updated as part of this PR, leaving a stale usage example that produces a runtime error.

  2. tools/changelog/cli.py, line 536-588 (link)

    P2 Two version sources of truth with no drift guard

    current_version() still reads the authoritative version from config/extension.toml, while write_version() now writes to both extension.toml and pyproject.toml. If the two files ever diverge (e.g., a manual edit to one file, or a partial write failure), future changelog bumps will silently use the stale extension.toml value as the base version and write it back to pyproject.toml, clobbering the diverged value without warning. A startup assertion comparing the two versions would prevent silent drift.

Reviews (1): Last reviewed commit: "Refactor to remove setup.py" | Re-trigger Greptile

Comment thread source/isaaclab_rl/pyproject.toml Outdated
Comment on lines +43 to +56
rl-games = [
"aiohttp==3.13.3",
"rl-games @ git+https://github.com/isaac-sim/rl_games.git@python3.11",
"gym",
"standard-distutils",
]
rl_games = [
"aiohttp==3.13.3",
"rl-games @ git+https://github.com/isaac-sim/rl_games.git@python3.11",
"gym",
"standard-distutils",
]
rsl-rl = ["rsl-rl-lib==5.0.1", "onnxscript>=0.5"]
rsl_rl = ["rsl-rl-lib==5.0.1", "onnxscript>=0.5"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Duplicate normalized extra names

Both rsl-rl / rsl_rl and rl-games / rl_games are defined as separate extras with identical content. Per PEP 685, extra names are normalized (underscores and hyphens collapse to hyphens), so these pairs refer to the same extra. Some pip/uv versions will raise an error or emit a warning when duplicate normalized extras are declared. The test in test_wheel_builder_metadata.py already works around this by iterating both names, which is a signal that this duplication is unintentional. Keeping only the hyphenated canonical forms (rsl-rl, rl-games) is sufficient.

Comment on lines +70 to +87
[project.optional-dependencies]
isaacsim = ["isaacsim[all,extscache]==5.1.0"]
all = [
"isaacsim[all,extscache]==5.1.0",
"isaaclab_assets",
"isaaclab_contrib",
"isaaclab_experimental",
"isaaclab_mimic",
"isaaclab_newton[all]",
"isaaclab_ov",
"isaaclab_ovphysx",
"isaaclab_physx[newton]",
"isaaclab_rl[all]",
"isaaclab_tasks",
"isaaclab_tasks_experimental",
"isaaclab_teleop",
"isaaclab_visualizers[all]",
]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 isaaclab-ppisp absent from isaaclab[all]

isaaclab-ppisp was added to the root dev environment's dependencies (and [tool.uv.sources]) in this PR, but it is not listed in [project.optional-dependencies] all here. Users installing pip install isaaclab[all] will not receive isaaclab-ppisp, while uv sync from the repo root will. This inconsistency means the [all] extra no longer installs the full set of sub-packages.

Comment on lines +64 to +67
[project.scripts]
isaaclab = "isaaclab.cli:cli"
play = "isaaclab.cli:play"
train = "isaaclab.cli:train"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to use less generic names for these executables? In larger virtual environments, binaries like play and train could both confuse users and potentially clash with executables provided by other packages.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We like the simple naming, what would be the alternative? isaaclab_train?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's consider the extreme case where IsaacLab eventually becomes part of the official Ubuntu repositories as a python3-isaaclab deb package. In that scenario, users would end up with generic play and train executables in their PATH, which would be highly ambiguous and likely conflict-prone.

While this may sound hypothetical, it is already a practical concern in ecosystems such as conda-forge. Those environments can grow to the scale of a Linux distribution and may contain IsaacLab alongside other frameworks like mjlab and many additional ML/RL toolchains. Generic executable names do not scale well in such shared environments.

I would strongly recommend addressing this upstream rather than leaving it to downstream packagers. Otherwise, distributions will likely introduce their own ad-hoc renaming conventions, leading to fragmentation and inconsistent UX across ecosystems.

Two approaches seem reasonable here:

  1. Rename the executables to something namespaced, e.g.:

    • isaaclab-play
    • isaaclab-train
  2. Introduce a single top-level isaaclab CLI with subcommands:

    • isaaclab train [...]
    • isaaclab play [...]

Personally, I think option 2 is the cleanest long-term design, especially since implementing subcommands with argparse is straightforward and scales better as the CLI surface grows. However, even option 1 would already avoid the namespace collision problem.

@StafaH StafaH merged commit 7364ba8 into isaac-sim:develop May 28, 2026
37 checks passed
@StafaH StafaH deleted the mh/pyproject_rework branch May 28, 2026 01:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

asset New asset feature or request infrastructure isaac-mimic Related to Isaac Mimic team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants