mirror of
https://github.com/huggingface/lerobot.git
synced 2026-05-21 19:49:49 +00:00
fix(processors): make sure nested dict are also shallow copied (#1939)
This commit is contained in:
@@ -844,10 +844,10 @@ class ObservationProcessorStep(ProcessorStep, ABC):
|
|||||||
new_transition = self._current_transition
|
new_transition = self._current_transition
|
||||||
|
|
||||||
observation = new_transition.get(TransitionKey.OBSERVATION)
|
observation = new_transition.get(TransitionKey.OBSERVATION)
|
||||||
if observation is None:
|
if observation is None or not isinstance(observation, dict):
|
||||||
raise ValueError("ObservationProcessorStep requires an observation in the transition.")
|
raise ValueError("ObservationProcessorStep requires an observation in the transition.")
|
||||||
|
|
||||||
processed_observation = self.observation(observation)
|
processed_observation = self.observation(observation.copy())
|
||||||
new_transition[TransitionKey.OBSERVATION] = processed_observation
|
new_transition[TransitionKey.OBSERVATION] = processed_observation
|
||||||
return new_transition
|
return new_transition
|
||||||
|
|
||||||
@@ -904,10 +904,10 @@ class RobotActionProcessorStep(ProcessorStep, ABC):
|
|||||||
new_transition = self._current_transition
|
new_transition = self._current_transition
|
||||||
|
|
||||||
action = new_transition.get(TransitionKey.ACTION)
|
action = new_transition.get(TransitionKey.ACTION)
|
||||||
if not isinstance(action, dict):
|
if action is None or not isinstance(action, dict):
|
||||||
raise ValueError(f"Action should be a RobotAction type (dict), but got {type(action)}")
|
raise ValueError(f"Action should be a RobotAction type (dict), but got {type(action)}")
|
||||||
|
|
||||||
processed_action = self.action(action=action)
|
processed_action = self.action(action.copy())
|
||||||
new_transition[TransitionKey.ACTION] = processed_action
|
new_transition[TransitionKey.ACTION] = processed_action
|
||||||
return new_transition
|
return new_transition
|
||||||
|
|
||||||
@@ -1049,10 +1049,10 @@ class InfoProcessorStep(ProcessorStep, ABC):
|
|||||||
new_transition = self._current_transition
|
new_transition = self._current_transition
|
||||||
|
|
||||||
info = new_transition.get(TransitionKey.INFO)
|
info = new_transition.get(TransitionKey.INFO)
|
||||||
if info is None:
|
if info is None or not isinstance(info, dict):
|
||||||
raise ValueError("InfoProcessorStep requires an info dictionary in the transition.")
|
raise ValueError("InfoProcessorStep requires an info dictionary in the transition.")
|
||||||
|
|
||||||
processed_info = self.info(info)
|
processed_info = self.info(info.copy())
|
||||||
new_transition[TransitionKey.INFO] = processed_info
|
new_transition[TransitionKey.INFO] = processed_info
|
||||||
return new_transition
|
return new_transition
|
||||||
|
|
||||||
@@ -1078,10 +1078,10 @@ class ComplementaryDataProcessorStep(ProcessorStep, ABC):
|
|||||||
new_transition = self._current_transition
|
new_transition = self._current_transition
|
||||||
|
|
||||||
complementary_data = new_transition.get(TransitionKey.COMPLEMENTARY_DATA)
|
complementary_data = new_transition.get(TransitionKey.COMPLEMENTARY_DATA)
|
||||||
if complementary_data is None:
|
if complementary_data is None or not isinstance(complementary_data, dict):
|
||||||
raise ValueError("ComplementaryDataProcessorStep requires complementary data in the transition.")
|
raise ValueError("ComplementaryDataProcessorStep requires complementary data in the transition.")
|
||||||
|
|
||||||
processed_complementary_data = self.complementary_data(complementary_data)
|
processed_complementary_data = self.complementary_data(complementary_data.copy())
|
||||||
new_transition[TransitionKey.COMPLEMENTARY_DATA] = processed_complementary_data
|
new_transition[TransitionKey.COMPLEMENTARY_DATA] = processed_complementary_data
|
||||||
return new_transition
|
return new_transition
|
||||||
|
|
||||||
|
|||||||
@@ -1172,8 +1172,6 @@ def test_task_processing_creates_new_transition():
|
|||||||
|
|
||||||
# Should be different transition object (functional design)
|
# Should be different transition object (functional design)
|
||||||
assert result is not original_transition
|
assert result is not original_transition
|
||||||
# But complementary_data is the same reference (current implementation behavior)
|
|
||||||
assert result[TransitionKey.COMPLEMENTARY_DATA] is original_comp_data
|
|
||||||
# The task should be processed correctly (wrapped in list)
|
# The task should be processed correctly (wrapped in list)
|
||||||
assert result[TransitionKey.COMPLEMENTARY_DATA]["task"] == ["sort_objects"]
|
assert result[TransitionKey.COMPLEMENTARY_DATA]["task"] == ["sort_objects"]
|
||||||
# Original complementary data is also modified (current behavior)
|
# Original complementary data is also modified (current behavior)
|
||||||
|
|||||||
Reference in New Issue
Block a user