Fix MDL module dependency retrieval#6034
Conversation
There was a problem hiding this comment.
🤖 Isaac Lab Review Bot
PR #6034 — Fix MDL module dependency retrieval
Summary
This PR correctly extends the MDL dependency scanner to handle relative module imports (.::Module) in addition to the existing texture resource handling. The Hospital environment materials reference sibling MDL modules via import .::OmniUe4Function etc., which were previously not collected during local asset mirroring.
✅ Findings
Correctness: Good
- The approach of stripping comments/strings first (via
_MDL_RESOURCE_RE.sub) before scanning forimportstatements correctly prevents false positives from commented-out or string-embedded imports. - The
\bword boundary in_MDL_IMPORT_REcorrectly prevents matchingreimportor similar tokens. - Multi-import statements (comma-separated) are handled.
export import .::Module;(valid MDL) is correctly captured.- Global imports (
::nvidia::...) are properly skipped since they only match.::prefixes.
Design: Clean
- Extracting
_find_mdl_dependencies()as a separate function improves testability and readability. - The logic for mapping
::path separators to filesystem/viaposixpath.joinis correct for this use case.
Tests: Comprehensive
- Tests cover: simple relative imports, nested modules (
Shared::OmniUe4Base), wildcard imports, global imports (correctly excluded), line comments, block comments, and quoted strings containing import-like text.
💭 Minor Observations (non-blocking)
-
Wildcard-only import edge case:
import .::*;would result inmodule_name = ""after.removesuffix("::*"), andcomponentswould be empty, so nothing is added. This is correct behavior (package-level wildcard has no single file to fetch). -
Multi-level relative imports: MDL supports
..::(parent-level) imports. The current code only handles.::(sibling). This is fine for the Hospital use case but could be extended if other environments use parent-relative imports.
Verdict
LGTM — Clean, focused fix with good test coverage. CI passing (pre-commit ✓, build ✓). No correctness issues found.
0 blocking findings | Reviewed at 465ee10
🔄 Update — reviewed be50acf
New commits refactor the import parsing logic:
_MDL_IMPORT_REand_MDL_RELATIVE_IMPORT_REmoved to module-level compiled constants (good for performance).- Import resolution extracted into
_find_mdl_import_dependencies()with improved ambiguity handling:import .::A::B;now correctly emits candidates for both interpretations (moduleA/B.mdland symbolBfromA.mdl), while wildcard imports (::*) unambiguously resolve to a single module path. - Tests updated to reflect the new candidate-based output.
This is cleaner and more correct than the previous approach. No new issues found. Still LGTM.
Reviewed at be50acf
Greptile SummaryThis PR fixes MDL module dependency resolution by extending the existing MDL scanner to also collect relative module imports (e.g.,
Confidence Score: 4/5Safe to merge; the change is additive, has no impact on existing texture-dependency or USD-layer paths, and the new import-scanning logic is well-guarded against comments and string literals. The implementation correctly strips comments and quoted strings before running the import regex, handles wildcard suffixes, and resolves nested module paths to sibling file paths that integrate cleanly with the existing URL-resolution logic. The two minor gaps — MDL source/isaaclab/isaaclab/utils/assets.py — worth a second look for coverage of the MDL Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[_find_asset_dependencies\nlocal_asset_path] --> B{suffix == .mdl?}
B -- Yes --> C[Open & read MDL source]
C --> D[_find_mdl_dependencies\nsource]
D --> E[Scan _MDL_RESOURCE_RE\nfor quoted strings]
E --> F{Matches\n_MDL_TEXTURE_RE?}
F -- Yes --> G[Add texture path to refs]
F -- No --> H[Continue]
D --> I[Strip strings + comments\n_MDL_RESOURCE_RE.sub]
I --> J[Scan _MDL_IMPORT_RE\non cleaned source]
J --> K{Starts with '.::' ?}
K -- No --> L[Skip - absolute or non-relative import]
K -- Yes --> M[Strip leading '.::'\nremove trailing '::*']
M --> N[Split '::' into path components\nfilter empty and '*']
N --> O[Add component/path.mdl to refs]
D --> P[Return refs set]
B -- No --> Q{suffix in _USD_EXTENSIONS?}
Q -- No --> R[Return empty set]
Q -- Yes --> S[Parse USD layer\nUsdUtils.ModifyAssetPaths]
S --> T[Return USD asset refs]
Reviews (1): Last reviewed commit: "Fix MDL module dependency retrieval" | Re-trigger Greptile |
| for match in _MDL_IMPORT_RE.finditer(source_code): | ||
| for ref in match.group(1).split(","): | ||
| ref = ref.strip() | ||
| if not ref.startswith(".::"): | ||
| continue | ||
|
|
||
| module_name = ref[3:].removesuffix("::*") | ||
| components = [component for component in module_name.split("::") if component and component != "*"] | ||
| if components: | ||
| refs.add(posixpath.join(*components) + ".mdl") |
There was a problem hiding this comment.
MDL
using statement not scanned for relative imports
MDL supports two interchangeable forms for module imports: import .::Foo; and using .::Foo::*;. The new scanner only matches the import keyword via _MDL_IMPORT_RE. Any MDL material that uses using .::Foo::*; for relative sibling imports would silently drop those dependencies, leaving the mirrored asset tree incomplete. If other environments (beyond Hospital) rely on using for relative imports, those files won't be downloaded.
| def test_find_asset_dependencies_collects_mdl_relative_import_modules(tmp_path): | ||
| """Test collecting sibling MDL modules imported by material files.""" | ||
| mdl_path = tmp_path / "material.mdl" | ||
| mdl_path.write_text( | ||
| """ | ||
| import .::OmniUe4Function; | ||
| import .::OmniUe4Translucent::*; | ||
| import .::Shared::OmniUe4Base; | ||
| import ::nvidia::core_definitions::*; | ||
| export material Example(*) = OmniPBR(); | ||
| // import .::CommentedLine; | ||
| /* import .::CommentedBlock; */ | ||
| string ignored = "import .::QuotedString;"; | ||
| """, | ||
| encoding="utf-8", | ||
| ) | ||
|
|
||
| assert assets_utils._find_asset_dependencies(str(mdl_path)) == { | ||
| "OmniUe4Function.mdl", | ||
| "OmniUe4Translucent.mdl", | ||
| "Shared/OmniUe4Base.mdl", | ||
| } |
There was a problem hiding this comment.
Multi-import single-line form not covered by tests
The splitting logic in _find_mdl_dependencies correctly handles comma-separated imports on one line (e.g., import .::Foo, .::Bar;), but this form has no test case. Adding a case like import .::A, .::B; would verify the comma-split path and guard against future regressions on that branch.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
465ee10 to
be50acf
Compare
be50acf to
781b06b
Compare
🔄 Incremental Review Update (be50acf)Thanks for the update! The commit was amended with improvements: ✅ Refactored parsing logic - The import parsing was extracted to a dedicated ✅ Improved symbol/module ambiguity handling - The new code correctly handles cases like ✅ Test expanded - Added test case for the ambiguous symbol case with Outstanding items from initial review:
|
|
🔄 Re-review after new commits ( The new changes address both previous review comments:
New changes summary:
Implementation looks clean and well-structured. No new concerns. 👍 |
|
Incremental Review Update (781b06b) ✅ Previous concern addressed: The
📝 The multi-import test case suggestion (P2) remains as an optional enhancement, but the implementation is correct since No new issues introduced in the incremental changes. LGTM 👍 |
## Summary - Cherry-pick #6034 / 781b06b onto release/3.0.0-beta2 - Collect relative MDL module imports alongside texture resources when retrieving local asset dependencies - Adds regression coverage for Hospital-style sibling MDL module imports ## Validation - python3 -m py_compile source/isaaclab/isaaclab/utils/assets.py source/isaaclab/test/utils/test_assets.py - git diff --check refs/remotes/upstream/release/3.0.0-beta2...HEAD - isolated parser check for _find_mdl_dependencies passed - focused pytest attempted, but local system Python is missing lazy_loader, so package import collection fails before tests run
Summary
importand[export] using ... import ...forms, including current-package.::imports and parent-package..::imports.Validation
python3 -m py_compile source/isaaclab/isaaclab/utils/assets.py source/isaaclab/test/utils/test_assets.py_find_mdl_dependencieswith Hospital-style relative imports, using-imports, and parent-relative importspython3 tools/changelog/cli.py check developpre-commit run --files source/isaaclab/isaaclab/utils/assets.py source/isaaclab/test/utils/test_assets.py source/isaaclab/changelog.d/fix-mdl-module-dependencies.rstFocused pytest was not runnable in this shell because the local Python environment is missing
lazy_loader. Full Kit/Hospital viewport repro was not run locally.