Repository navigation
[Proposal] Unify how warnings are emitted across Isaac Lab #8192
Description
Proposal
Adopt one documented convention for emitting warnings across Isaac Lab, add it to the contribution guide's coding style, and migrate existing call sites to it.
A possible convention, following the standard library's own guidance (logging HOWTO: when to use logging):
| Situation | Mechanism |
|---|---|
| The caller should change their code (deprecated API, ignored or conflicting config, misuse) | warnings.warn(..., <Category>, stacklevel=...), e.g. DeprecationWarning / FutureWarning / UserWarning |
| A runtime event the user should know about that their code can't avoid (fallback taken, device changed, optional feature unavailable, degraded performance) | logger.warning(...) with logger = logging.getLogger(__name__) |
| Scripts / CLI user-facing output | logger.warning(...) as well, so --verbose / --info and log capture apply; no print("[WARNING]...") |
Motivation
Develop (9c572e4) currently uses three mechanisms for the same purpose, excluding tests:
| Mechanism | Calls | Files |
|---|---|---|
warnings.warn(...) |
341 | 81 |
logger.warning(...) |
271 | 112 |
print("[WARNING]: ...") / print("[WARN] ...") |
21 | 10 |
Most warnings.warn calls (306) are deprecations, which is consistent. The rest is not:
-
The same kind of event uses different mechanisms.
isaaclab_physx/sensors/contact_sensor/contact_sensor.py:688reports a visualization limitation withwarnings.warn(no category) and a hand-rolled_warned_*flag to avoid repeats.- The same file (
:483) and the other PhysX sensors report their CUDA-graph fallback withlogger.warning.
-
printwarnings bypass logging. Examples:isaaclab_rl/rsl_rl/utils.py(5 calls)isaaclab/cli/multigpu.pyisaaclab/benchmark/.../benchmark_train_rl_games.pyscripts/reinforcement_learning/ray/*
These ignore log levels and
--verbose/--info, can't be filtered or captured withcaplog, and use inconsistent prefixes ([WARNING]:,[WARNING],[WARN],[WARN]:). -
Tests can't assert warnings uniformly. Some need
pytest.warns, somecaplog, somecapsys. -
New code has no reference to follow. This came up while reviewing a device fallback in [Mac OS] [RL] Run RL agents on the simulation device and raise without CUDA #8188.
Alternatives
- Only
warnings.warn. This routes everything through the warnings filter. Runtime notices would then show once per call site by default, which suits deprecations but hides repeated runtime events. It also loses log levels and handlers. - Only
logging. Deprecations would loseDeprecationWarningsemantics: they couldn't be turned into errors with-W error/ pytestfilterwarnings, and they'd have nostacklevelattribution to the caller. - Status quo, documented. This lowers churn but keeps three idioms.
Build Info
- Isaac Lab Version:
develop@9c572e4 - Isaac Sim Version: n/a (code-style proposal)
Checklist
- I have checked that there is no similar issue in the repo (required)
Acceptance Criteria
- The convention is documented in
docs/source/refs/contributing.rst(Coding Style). -
print-based warnings insource/andscripts/are migrated tologger.warning(orwarnings.warnwhere the caller must act). - Non-deprecation
warnings.warncalls are reviewed and either given an explicit category or moved tologger.warningper the convention. - Optional: a lint check (e.g. a pre-commit grep or ruff rule) rejects new
print("[WARNcalls insource/.
Activity
Unify how warnings and log messages are emitted across Isaac Lab (isa…