1111from pathlib import Path
1212
1313import tomllib
14+ from packaging .requirements import Requirement
15+ from packaging .version import Version
1416
1517
1618def _repo_root () -> Path :
@@ -39,6 +41,26 @@ def _rsl_rl_pin_from_setup() -> str:
3941 raise AssertionError ("Could not find rsl-rl-lib pin in source/isaaclab_rl/setup.py" )
4042
4143
44+ def _requirements_from_setup (package_name : str , extra_name : str , dependency_name : str ) -> list [Requirement ]:
45+ """Return matching requirements from a source package extra."""
46+ setup_path = _repo_root () / f"source/{ package_name } /setup.py"
47+ module = ast .parse (setup_path .read_text (encoding = "utf-8" ))
48+
49+ for node in module .body :
50+ if not isinstance (node , ast .Assign ):
51+ continue
52+ if not any (isinstance (target , ast .Name ) and target .id == "EXTRAS_REQUIRE" for target in node .targets ):
53+ continue
54+ extras_require = ast .literal_eval (node .value )
55+ return [
56+ requirement
57+ for dependency in extras_require [extra_name ]
58+ if (requirement := Requirement (dependency )).name == dependency_name
59+ ]
60+
61+ raise AssertionError (f"Could not find EXTRAS_REQUIRE in { setup_path } " )
62+
63+
4264def test_wheel_builder_rsl_rl_pin_matches_source_package ():
4365 """The bundled wheel metadata must install the RSL-RL version required by training scripts."""
4466 expected_pin = _rsl_rl_pin_from_setup ()
@@ -52,3 +74,40 @@ def test_wheel_builder_rsl_rl_pin_matches_source_package():
5274 for extra_name in ("rsl-rl" , "rsl_rl" , "all" ):
5375 rsl_rl_pins = [dep for dep in dependencies_by_extra [extra_name ] if dep .startswith ("rsl-rl-lib==" )]
5476 assert rsl_rl_pins == [expected_pin ]
77+
78+
79+ def test_newton_requirements_support_isaac_sim_6_0_and_6_1 ():
80+ """Newton extras must accept the releases bundled by Isaac Sim 6.0 and 6.1."""
81+ requirements = []
82+ for package_name , extra_names in {
83+ "isaaclab_newton" : ("all" ,),
84+ "isaaclab_physx" : ("newton" ,),
85+ "isaaclab_visualizers" : ("newton" , "rerun" , "viser" ),
86+ }.items ():
87+ for extra_name in extra_names :
88+ requirements .extend (_requirements_from_setup (package_name , extra_name , "newton" ))
89+
90+ packages_path = _repo_root () / "tools/wheel_builder/res/python_packages.toml"
91+ with packages_path .open ("rb" ) as f :
92+ packages = tomllib .load (f )
93+ optional_dependencies = packages ["isaaclab" ]["pyproject" ]["optional-dependencies" ]["all" ]
94+ dependencies_by_extra = {name : deps for entry in optional_dependencies for name , deps in entry .items ()}
95+ requirements .extend (
96+ Requirement (dependency ) for dependency in dependencies_by_extra ["newton" ] if dependency .startswith ("newton[" )
97+ )
98+
99+ assert len (requirements ) == 6
100+ for requirement in requirements :
101+ assert Version ("1.2.1" ) in requirement .specifier
102+ assert Version ("1.5.0" ) in requirement .specifier
103+ assert Version ("2.0.0" ) not in requirement .specifier
104+
105+
106+ def test_rl_games_aiohttp_requirement_supports_isaac_sim_6_0_and_6_1 ():
107+ """RL-Games must not downgrade the aiohttp release bundled by Isaac Sim 6.1."""
108+ requirements = _requirements_from_setup ("isaaclab_rl" , "rl-games" , "aiohttp" )
109+
110+ assert len (requirements ) == 1
111+ assert Version ("3.13.3" ) in requirements [0 ].specifier
112+ assert Version ("3.14.1" ) in requirements [0 ].specifier
113+ assert Version ("4.0.0" ) not in requirements [0 ].specifier
0 commit comments