Fix AttributeError in Renderer.__del__ on partial construction.
If Renderer.__init__ raises before the rendering contexts are assigned (e.g. width > offwidth raises ValueError, or MjrContext construction fails), __del__ calls close() which accesses self._gl_context and self._mjr_context unconditionally, raising AttributeError. This masks the real __init__ failure with a noisy "Exception ignored in..." message during garbage collection. Pre-initialize both attributes to None at the top of __init__ so that close() is safe on a partially-constructed instance. Add a regression test that captures sys.unraisablehook and asserts that __del__ raises nothing when __init__ fails via the width > offwidth path. Fixes #3213.
This commit is contained in:
@@ -49,6 +49,11 @@ class Renderer:
|
||||
ValueError: If `camera_id` is outside the valid range, or if `width` or
|
||||
`height` exceed the dimensions of MuJoCo's offscreen framebuffer.
|
||||
"""
|
||||
# Pre-initialize context attributes so __del__ -> close() is safe even if
|
||||
# __init__ raises below before they are assigned. See #3213.
|
||||
self._gl_context = None # type: ignore
|
||||
self._mjr_context = None
|
||||
|
||||
buffer_width = model.vis.global_.offwidth
|
||||
buffer_height = model.vis.global_.offheight
|
||||
if width > buffer_width:
|
||||
@@ -80,9 +85,8 @@ the clause:
|
||||
|
||||
# Create render contexts.
|
||||
# TODO(nimrod): Figure out why pytype doesn't like gl_context.GLContext
|
||||
self._gl_context = None # type: ignore
|
||||
if gl_context.GLContext is not None:
|
||||
self._gl_context = gl_context.GLContext(width, height)
|
||||
self._gl_context = gl_context.GLContext(width, height) # type: ignore
|
||||
if self._gl_context:
|
||||
self._gl_context.make_current()
|
||||
self._mjr_context = mujoco.MjrContext(model, font_scale.value)
|
||||
|
||||
Reference in New Issue
Block a user