Skip to content

Commit cda6397

Browse files
author
EnliteAI Bot
committed
Refine observation handling logic across wrappers: enforce stricter validation for None inputs in ObservationStackWrapper, maintain passthrough behavior in ObservationVisualizationWrapper and DictObservationWrapper, and update tests accordingly.
(Issue - null)
1 parent 249baa6 commit cda6397

3 files changed

Lines changed: 7 additions & 35 deletions

File tree

maze/core/wrappers/monitoring_wrapper.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ def step(self, action: ActionType) -> tuple[ObservationType, float, bool, bool,
7474
if self.action_logging:
7575
self._log_action(substep_name, agent_name, action)
7676

77+
# Each event type is tracked independently, so a missing obs entry for one step
78+
# does not misalign action or reward stats. It is just missing from observation distribution visualization.
7779
if self.observation_logging and obs is not None:
7880
self._log_observation(substep_name, agent_name, obs)
7981

maze/core/wrappers/observation_stack_wrapper.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,9 @@ def observation(self, observation: dict[str, np.ndarray] | None) -> dict[str, np
8383
:param observation: The observation to be stacked.
8484
:return: The sacked observation.
8585
"""
86-
# ObservationStackWrapper is stateful: every call must push a real observation onto the stack.
87-
# A None observation (whole or per-key) would silently break temporal alignment, so we raise
88-
# immediately rather than returning None like stateless wrappers do.
86+
# None indicates the absence of an observation; pass through without processing.
8987
if observation is None:
90-
raise ValueError('ObservationStackWrapper requires a valid observation dict, got None.')
91-
92-
none_keys = [k for k, v in observation.items() if v is None]
93-
if none_keys:
94-
raise ValueError(f'Observation contains None values for keys: {none_keys}')
88+
return None
9589

9690
actor_id = self.actor_id()
9791

maze/test/core/wrappers/test_observation_stack_wrapper.py

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -166,35 +166,11 @@ def test_stack_reset_on_trajectory_load(stack_mode: str):
166166

167167

168168
@pytest.mark.parametrize('stack_mode', ['flatten_history', 'group_by_actor_id'])
169-
def test_observation_stack_wrapper_none_raises(stack_mode):
170-
"""A None observation must raise ValueError — unlike stateless wrappers,
171-
the stack requires a real obs every step."""
169+
def test_observation_stack_wrapper_none_passthrough(stack_mode):
170+
"""None observations must be returned as None without raising."""
172171
env = build_dummy_structured_environment()
173172
config = [
174173
{'observation': 'observation_0', 'keep_original': False, 'tag': None, 'delta': False, 'stack_steps': 2},
175174
]
176175
env = ObservationStackWrapper.wrap(env, stack_config=config, stack_mode=stack_mode)
177-
with pytest.raises(ValueError):
178-
env.observation(None)
179-
180-
181-
@pytest.mark.parametrize('stack_mode', ['flatten_history', 'group_by_actor_id'])
182-
def test_observation_stack_wrapper_none_value_in_dict_raises(stack_mode):
183-
"""A None value for any key in the observation dict must raise a ValueError immediately.
184-
185-
Sub-step 0 of the dummy env has both 'observation_0' and 'action_0_0_mask' — two keys that appear
186-
together in the same observation dict, making them suitable for this test.
187-
"""
188-
env = build_dummy_structured_environment()
189-
config = [
190-
{'observation': 'observation_0', 'keep_original': True, 'tag': 'stacked', 'delta': False, 'stack_steps': 2},
191-
]
192-
env = ObservationStackWrapper.wrap(env, stack_config=config, stack_mode=stack_mode)
193-
env.reset()
194-
195-
valid_obs = env.env.observation_space.sample()
196-
mixed_obs = dict(valid_obs)
197-
mixed_obs['observation_0'] = None
198-
199-
with pytest.raises(ValueError, match='observation_0'):
200-
env.observation(mixed_obs)
176+
assert env.observation(None) is None

0 commit comments

Comments
 (0)