in gym_hil/wrappers/viewer_wrapper.py [0:0]
def close(self) -> None: # type: ignore[override]
"""Close both the passive viewer and the underlying gym environment.
MuJoCo's `Renderer` gained a `close()` method only in recent versions
(>= 2.3.0). When running with an older MuJoCo build the renderer
instance stored inside `env.unwrapped._viewer` does not provide this
method which causes `AttributeError` when the environment is closed.
To remain version-agnostic we:
1. Manually dispose of the underlying viewer *only* if it exposes a
`close` method.
2. Remove the reference from the environment so that a subsequent
call to `env.close()` will not fail.
3. Close our own passive viewer handle.
4. Finally forward the `close()` call to the wrapped environment so
that any other resources are released.
"""
# 1. Tidy up the renderer managed by the wrapped environment (if any).
base_env = self.env.unwrapped # type: ignore[attr-defined]
if hasattr(base_env, "_viewer"):
viewer = base_env._viewer
if viewer is not None and hasattr(viewer, "close") and callable(viewer.close):
try: # noqa: SIM105
viewer.close()
except Exception:
# Ignore errors coming from older MuJoCo versions or
# already-freed contexts.
pass
# Prevent the underlying env from trying to close it again.
base_env._viewer = None
# 2. Close the passive viewer launched by this wrapper.
try: # noqa: SIM105
self._viewer.close()
except Exception: # pragma: no cover
# Defensive: avoid propagating viewer shutdown errors.
pass
# 3. Let the wrapped environment perform its own cleanup.
self.env.close()