Skip to content

Commit af34310

Browse files
committed
Preserve bundled Newton during installation
1 parent 03a73b8 commit af34310

6 files changed

Lines changed: 106 additions & 12 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fixed
2+
^^^^^
3+
4+
* Preserved Isaac Sim's compatible bundled Newton distribution during installation and allowed the required Warp 1.x release.

source/isaaclab/isaaclab/cli/commands/install.py

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,34 @@ def _discover_prebundle_dirs() -> set[Path]:
755755
return prebundle_dirs
756756

757757

758+
def _filter_pip_prebundle_pythonpath(pythonpath: str) -> tuple[str, int]:
759+
"""Hide prebundles from pip while preserving bundled Newton metadata.
760+
761+
Newton is an Isaac Sim runtime component whose version differs between Sim
762+
releases. Keeping its wheel root visible lets pip satisfy Isaac Lab's
763+
compatible version range with the bundled distribution instead of
764+
replacing it and damaging the shared prebundle symlink farm.
765+
766+
Args:
767+
pythonpath: The original ``PYTHONPATH`` value.
768+
769+
Returns:
770+
The filtered ``PYTHONPATH`` and number of removed entries.
771+
"""
772+
paths = pythonpath.split(os.pathsep)
773+
filtered_paths = []
774+
for path in paths:
775+
if not path:
776+
continue
777+
if "pip_prebundle" not in path:
778+
filtered_paths.append(path)
779+
continue
780+
if any(dist_info.is_dir() for dist_info in Path(path).glob("newton-[0-9]*.dist-info")):
781+
filtered_paths.append(path)
782+
783+
return os.pathsep.join(filtered_paths), len(paths) - len(filtered_paths)
784+
785+
758786
def _find_dangling_prebundle_symlinks() -> set[Path]:
759787
"""Find symlinks under Isaac Sim prebundles whose targets do not resolve.
760788
@@ -1027,21 +1055,16 @@ def append_submodules_once(package_dirs: tuple[str, ...]) -> None:
10271055
saved_ld_preload = os.environ.pop("LD_PRELOAD")
10281056

10291057
# Temporarily filter Isaac Sim pre-bundled package paths from PYTHONPATH during all pip operations.
1030-
# This prevents pip from scanning and managing packages in Isaac Sim's pip_prebundle directories,
1031-
# which can cause those packages to be deleted or modified. This is especially important
1032-
# in conda environments where Isaac Sim setup scripts add these paths to PYTHONPATH.
1058+
# Keep the bundled Newton wheel root visible so a compatible version is treated as installed rather
1059+
# than replaced. Other prebundles remain hidden to prevent pip from deleting or modifying them.
10331060
saved_pythonpath = None
10341061
filtered_pythonpath = None
10351062
if "PYTHONPATH" in os.environ:
10361063
saved_pythonpath = os.environ["PYTHONPATH"]
1037-
# Filter out any paths containing pip_prebundle (pre-bundled packages that pip shouldn't manage)
1038-
paths = saved_pythonpath.split(os.pathsep)
1039-
filtered_paths = [p for p in paths if p and "pip_prebundle" not in p]
1064+
filtered_pythonpath, filtered_count = _filter_pip_prebundle_pythonpath(saved_pythonpath)
10401065

1041-
if len(filtered_paths) != len(paths):
1042-
filtered_pythonpath = os.pathsep.join(filtered_paths)
1066+
if filtered_count:
10431067
os.environ["PYTHONPATH"] = filtered_pythonpath
1044-
filtered_count = len(paths) - len(filtered_paths)
10451068
print_info(
10461069
f"Temporarily filtering {filtered_count} Isaac Sim pre-bundled package path(s) from PYTHONPATH "
10471070
"during pip operations to prevent interference with pre-bundled packages."

source/isaaclab/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
# image processing
3434
"transformers==4.57.6",
3535
"einops", # needed for transformers, doesn't always auto-install
36-
"warp-lang==1.13.0",
36+
"warp-lang>=1.13.0,<2",
3737
"matplotlib>=3.10.3", # minimum version for Python 3.12 support
3838
# pillow: floor, not exact — an exact pin below Isaac Sim's prebundled version forces a
3939
# downgrade that deletes the prebundled copy other extensions symlink into (nvbugs 6410989).

source/isaaclab/test/cli/test_install_commands.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from isaaclab.cli.commands.install import (
2323
_PREBUNDLE_REPOINT_PACKAGES,
2424
_ensure_cuda_torch,
25+
_filter_pip_prebundle_pythonpath,
2526
_maybe_uninstall_prebundled_torch,
2627
_repoint_prebundle_packages,
2728
_torch_first_on_sys_path_is_prebundle,
@@ -70,6 +71,27 @@ def _make_site_packages(
7071
return site_pkgs
7172

7273

74+
# ---------------------------------------------------------------------------
75+
# pip prebundle filtering
76+
# ---------------------------------------------------------------------------
77+
78+
79+
def test_prebundle_filter_preserves_newton_distribution_metadata(tmp_path):
80+
"""Bundled Newton remains visible while unrelated prebundles are hidden from pip."""
81+
other_prebundle = tmp_path / "other.ext" / "pip_prebundle"
82+
other_prebundle.mkdir(parents=True)
83+
newton_prebundle = tmp_path / "isaacsim.pip.newton" / "pip_prebundle" / "newton-wheel"
84+
(newton_prebundle / "newton-1.5.0.dist-info").mkdir(parents=True)
85+
site_packages = tmp_path / "kit" / "site-packages"
86+
site_packages.mkdir(parents=True)
87+
pythonpath = os.pathsep.join((str(other_prebundle), str(newton_prebundle), str(site_packages)))
88+
89+
filtered, removed_count = _filter_pip_prebundle_pythonpath(pythonpath)
90+
91+
assert filtered.split(os.pathsep) == [str(newton_prebundle), str(site_packages)]
92+
assert removed_count == 1
93+
94+
7395
# ---------------------------------------------------------------------------
7496
# _arm_cmake_policy_compatibility
7597
# ---------------------------------------------------------------------------

source/isaaclab/test/cli/test_wheel_builder_metadata.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,26 @@ def _requirements_from_setup(package_name: str, extra_name: str, dependency_name
6161
raise AssertionError(f"Could not find EXTRAS_REQUIRE in {setup_path}")
6262

6363

64+
def _install_requirements_from_setup(package_name: str, dependency_name: str) -> list[Requirement]:
65+
"""Return matching install requirements from a source package."""
66+
setup_path = _repo_root() / f"source/{package_name}/setup.py"
67+
module = ast.parse(setup_path.read_text(encoding="utf-8"))
68+
69+
for node in module.body:
70+
if not isinstance(node, ast.Assign):
71+
continue
72+
if not any(isinstance(target, ast.Name) and target.id == "INSTALL_REQUIRES" for target in node.targets):
73+
continue
74+
install_requires = ast.literal_eval(node.value)
75+
return [
76+
requirement
77+
for dependency in install_requires
78+
if (requirement := Requirement(dependency)).name == dependency_name
79+
]
80+
81+
raise AssertionError(f"Could not find INSTALL_REQUIRES in {setup_path}")
82+
83+
6484
def test_wheel_builder_rsl_rl_pin_matches_source_package():
6585
"""The bundled wheel metadata must install the RSL-RL version required by training scripts."""
6686
expected_pin = _rsl_rl_pin_from_setup()
@@ -103,6 +123,31 @@ def test_newton_requirements_support_isaac_sim_6_0_and_6_1():
103123
assert Version("2.0.0") not in requirement.specifier
104124

105125

126+
def test_warp_requirements_support_newton_bundled_by_isaac_sim_6_0_and_6_1():
127+
"""Core Warp requirements must accept the releases needed by bundled Newton versions."""
128+
requirements = _install_requirements_from_setup("isaaclab", "warp-lang")
129+
130+
packages_path = _repo_root() / "tools/wheel_builder/res/python_packages.toml"
131+
with packages_path.open("rb") as f:
132+
packages = tomllib.load(f)
133+
requirements.extend(
134+
Requirement(dependency)
135+
for dependency in packages["isaaclab"]["pyproject"]["dependencies"]["all"]
136+
if dependency.startswith("warp-lang")
137+
)
138+
optional_dependencies = packages["isaaclab"]["pyproject"]["optional-dependencies"]["all"]
139+
dependencies_by_extra = {name: deps for entry in optional_dependencies for name, deps in entry.items()}
140+
requirements.extend(
141+
Requirement(dependency) for dependency in dependencies_by_extra["newton"] if dependency.startswith("warp-lang")
142+
)
143+
144+
assert len(requirements) == 3
145+
for requirement in requirements:
146+
assert Version("1.13.0") in requirement.specifier
147+
assert Version("1.17.0") in requirement.specifier
148+
assert Version("2.0.0") not in requirement.specifier
149+
150+
106151
def test_rl_games_aiohttp_requirement_supports_isaac_sim_6_0_and_6_1():
107152
"""RL-Games must not downgrade the aiohttp release bundled by Isaac Sim 6.1."""
108153
requirements = _requirements_from_setup("isaaclab_rl", "rl-games", "aiohttp")

tools/wheel_builder/res/python_packages.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pyproject.dependencies.all = [
2222
# image processing
2323
"transformers==4.57.6",
2424
"einops", # needed for transformers, doesn't always auto-install
25-
"warp-lang==1.13.0",
25+
"warp-lang>=1.13.0,<2",
2626
"matplotlib>=3.10.3",
2727
# pillow: floor, not exact — an exact pin below Isaac Sim's prebundled version forces a
2828
# downgrade that deletes the prebundled copy other extensions symlink into (nvbugs 6410989).
@@ -94,7 +94,7 @@ pyproject.optional-dependencies.all = [
9494
# https://github.com/isaac-sim/IsaacLab/blob/main/source/isaaclab_newton/setup.py
9595
# ================================================================================
9696
{ "newton" = [
97-
"warp-lang==1.13.0",
97+
"warp-lang>=1.13.0,<2",
9898
"newton[sim]>=1.2.1,<2",
9999
"PyOpenGL-accelerate==3.1.10"
100100
] },

0 commit comments

Comments
 (0)