Adds release version to benchmark output#5188
Conversation
…tput The VersionInfoRecorder now reads: 1. The top-level VERSION file (e.g. '3.0.0') and records it as 'isaaclab_release' — this is the overall Isaac Lab release version. 2. Each sub-package's config/extension.toml version, recorded as '<package>_ext' (e.g. 'isaaclab_tasks_ext: 1.5.18'). This supplements the existing pip metadata versions (which reflect what's installed in the current environment) with the source-of-truth versions from the repository files. This is useful for: - Tracking benchmark results against specific releases - Detecting version mismatches between installed packages and source - Reproducing benchmark results from a specific codebase state The extension.toml versions are read using tomllib (Python 3.11+) with a fallback to the tomli backport for older Python versions.
Greptile SummaryThis PR adds the Isaac Lab release version (from the root Confidence Score: 4/5Mostly safe to merge, but the bare The prior review threads already flagged the source/isaaclab/isaaclab/test/benchmark/recorders/record_version_info.py — top-level
|
| Filename | Overview |
|---|---|
| source/isaaclab/isaaclab/test/benchmark/recorders/record_version_info.py | Adds VERSION file and extension.toml version collection; uses top-level import tomllib (Python 3.11+ only) with no fallback, while setup.py sets python_requires=">=3.10", breaking module import on Python 3.10. |
| source/isaaclab/docs/CHANGELOG.rst | New 4.5.27 version entry added with correct date, category, and RST formatting; consistent with extension.toml bump. |
| source/isaaclab/config/extension.toml | Version bumped to 4.5.27 matching the new CHANGELOG entry; no other changes. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[VersionInfoRecorder.__init__] --> B[_get_version_info]
B --> C[Module imports and importlib.metadata]
B --> D[Open root VERSION file]
B --> E[Iterate source subdirectories]
E --> F[_get_ext_version for each package]
F --> G{tomllib.load binary mode}
G -->|success| H[record entry_ext key]
G -->|exception| I[return None and skip]
D -->|success| J[record isaaclab_release]
D -->|exception| I
C --> K[record isaaclab, warp, torch, etc.]
H --> L[_version_info dict]
J --> L
K --> L
L --> M[get_data converts to StringMetadata list]
Reviews (2): Last reviewed commit: "Add changelog entry and bump version to ..." | Re-trigger Greptile
| try: | ||
| import tomllib | ||
| except ModuleNotFoundError: | ||
| import tomli as tomllib # Python < 3.11 |
There was a problem hiding this comment.
Unguarded
tomli fallback crashes module import
If running Python < 3.11 and tomli is not installed (it is not declared in any dependency manifest — setup.py, pyproject.toml, or config/extension.toml), the bare import tomli as tomllib raises ModuleNotFoundError at module load time. This makes the entire record_version_info module unimportable, silently disabling all benchmark recording — not just the new version fields. The toml package is already a declared required dependency and parses the same format; a nested try/except using it as a final fallback would fix this.
| try: | |
| import tomllib | |
| except ModuleNotFoundError: | |
| import tomli as tomllib # Python < 3.11 | |
| try: | |
| import tomllib | |
| except ModuleNotFoundError: | |
| try: | |
| import tomli as tomllib # Python < 3.11 with tomli installed | |
| except ModuleNotFoundError: | |
| import toml as tomllib # type: ignore[no-redef] # fallback: already-required dep |
Note:
toml.load()requires a text-mode file handle, whiletomllib.load()requires binary mode. If using thetomlfallback you will also need to conditionally change theopen(toml_path, "rb")call on line 86 to text mode, or restructure_get_release_versionto detect which library is active.
| try: | ||
| import tomllib | ||
| except ModuleNotFoundError: | ||
| import tomli as tomllib # Python < 3.11 |
There was a problem hiding this comment.
New undeclared optional dependency
The tomli package is not listed in setup.py, pyproject.toml, or config/extension.toml. Project guidelines explicitly say to avoid new optional dependencies when existing ones suffice. Since toml is already required everywhere in this package (it is used in setup.py itself to read extension.toml), it can replace tomli here without adding any new dependency.
AntoineRichard
left a comment
There was a problem hiding this comment.
I feel like this could be better structured.
| try: | ||
| import tomllib | ||
| except ModuleNotFoundError: | ||
| import tomli as tomllib # Python < 3.11 |
There was a problem hiding this comment.
We should be using python3.11 at minimum. So none of this is needed.
| try: | ||
| import tomllib | ||
| except ModuleNotFoundError: | ||
| import tomli as tomllib # Python < 3.11 |
There was a problem hiding this comment.
Remove and import tomllib only.
| def _get_release_version(self) -> None: | ||
| """Read the top-level VERSION file and each sub-package's extension.toml version. | ||
|
|
||
| The VERSION file at the repository root contains the Isaac Lab release version | ||
| (e.g. ``3.0.0``). Each sub-package under ``source/`` has its own version in | ||
| ``config/extension.toml``. | ||
| """ | ||
| # Read root VERSION file | ||
| version_file = os.path.join(_REPO_ROOT, "VERSION") | ||
| if os.path.isfile(version_file): | ||
| try: | ||
| with open(version_file) as f: | ||
| version = f.read().strip() | ||
| if version: | ||
| self._record("isaaclab_release", version) | ||
| except Exception: | ||
| pass | ||
|
|
||
| # Read extension.toml versions from each source sub-package | ||
| source_dir = os.path.join(_REPO_ROOT, "source") | ||
| if os.path.isdir(source_dir): | ||
| for entry in sorted(os.listdir(source_dir)): | ||
| toml_path = os.path.join(source_dir, entry, "config", "extension.toml") | ||
| if os.path.isfile(toml_path): | ||
| try: | ||
| with open(toml_path, "rb") as f: | ||
| data = tomllib.load(f) | ||
| version = data.get("package", {}).get("version") | ||
| if version: | ||
| self._record(f"{entry}_ext", version) | ||
| except Exception: | ||
| pass |
There was a problem hiding this comment.
Why not use get_version directly?
I.e.
if os.path.isdir(source_dir):
for entry in sorted(os.listdir(source_dir)):
version = get_version(entry)
if version:
self._record(f"{entry}_ext", versionThere was a problem hiding this comment.
Also could this not be done in _get_version_info directly?
…ion_info - Remove tomli fallback since Python 3.11+ is minimum - Replace _get_release_version with _get_ext_version helper - Integrate release version and extension.toml reads into _get_version_info
- Remove fragile level-count from _REPO_ROOT comment - Wrap os.listdir loop in try-except for consistency with the rest of the file's defensive error handling
Document the addition of release version and extension.toml versions to VersionInfoRecorder benchmark output.
|
@greptile |
|
Tip: Greploops — Automatically fix all review issues by running Use the Greptile plugin for Claude Code to query reviews, search comments, and manage custom context directly from your terminal. |
Signed-off-by: Kelly Guo <kellyg@nvidia.com>
There was a problem hiding this comment.
LGTM — clean, additive change.
What it does: Reads the top-level VERSION file (e.g. 3.0.0) at benchmark time and records it as isaaclab_release. This fills the gap where pip metadata versions reflect the installed environment but not the actual release tag of the source tree.
Review notes:
_REPO_ROOTpath traversal (6 levels up) is correct forsource/isaaclab/isaaclab/test/benchmark/recorders/→ repo root ✅- Bare
except Exception: passis consistent with the file's existing defensive style (all version reads silently degrade) ✅ - Purely additive — no existing benchmark output fields are modified, so backward compatibility is preserved ✅
- Changelog and version bump look good ✅
Minor nit (non-blocking): _get_git_info() still computes its own script_dir = os.path.dirname(os.path.abspath(__file__)) on L112. Could reuse _REPO_ROOT as cwd for the subprocess.run calls there too, but that's cosmetic — the git commands work from any directory in the repo.
Note: The PR title mentions "extension.toml versions" but those were removed in the latest commit — might want to update the title to just "Add release version to benchmark output" to match the current scope.
Adds the Isaac Lab release version (from the root `VERSION` file) to the benchmark output files. The `VersionInfoRecorder` currently collects package versions via `importlib.metadata` (pip) and module `__version__` attributes. These reflect what is *installed* in the current environment, but do not capture the **release version** of Isaac Lab itself (e.g. `3.0.0` from the root `VERSION` file). This makes it hard to correlate benchmark results with specific releases, especially when the installed pip version does not match the source tree (e.g. editable installs during development). - `source/isaaclab/isaaclab/test/benchmark/recorders/record_version_info.py`: - Added reading of the top-level `VERSION` file → recorded as `isaaclab_release` Before (existing fields preserved): ``` isaaclab: 4.5.25 isaaclab_tasks: 1.5.15 ``` After (new field added): ``` isaaclab_release: 3.0.0 # ← from VERSION file ``` Verified the recorder produces correct output with the expected field populated. No existing fields are modified — this is purely additive. --------- Signed-off-by: Kelly Guo <kellyg@nvidia.com> Co-authored-by: Kelly Guo <kellyguo11@users.noreply.github.com> Co-authored-by: Antoine RICHARD <antoiner@nvidia.com>
Description
Adds the Isaac Lab release version (from the root
VERSIONfile) to the benchmark output files.Motivation
The
VersionInfoRecordercurrently collects package versions viaimportlib.metadata(pip) and module__version__attributes. These reflect what is installed in the current environment, but do not capture the release version of Isaac Lab itself (e.g.3.0.0from the rootVERSIONfile).This makes it hard to correlate benchmark results with specific releases, especially when the installed pip version does not match the source tree (e.g. editable installs during development).
Changes
source/isaaclab/isaaclab/test/benchmark/recorders/record_version_info.py:VERSIONfile → recorded asisaaclab_releaseExample Output
Before (existing fields preserved):
After (new field added):
Testing
Verified the recorder produces correct output with the expected field populated. No existing fields are modified — this is purely additive.