diff --git a/src/ytdl_sub/config/preset.py b/src/ytdl_sub/config/preset.py index fbbbe161..93681817 100644 --- a/src/ytdl_sub/config/preset.py +++ b/src/ytdl_sub/config/preset.py @@ -278,8 +278,9 @@ class Preset(StrictDictValidator): if parent_preset_validator is None: return + presets_to_merge: List[Dict] = [] for parent_preset in [preset.value for preset in parent_preset_validator.list]: - parent_presets = set() + sub_parent_presets: Dict[str, Dict] = {} while parent_preset: # Make sure the parent preset actually exists @@ -290,20 +291,25 @@ class Preset(StrictDictValidator): ) # Make sure we do not hit an infinite loop - if parent_preset in parent_presets: + if parent_preset in sub_parent_presets: raise self._validation_exception( f"preset loop detected with the preset '{parent_preset}'" ) parent_preset_dict = copy.deepcopy(config.presets.dict[parent_preset]) - parent_presets.add(parent_preset) + sub_parent_presets[parent_preset] = parent_preset_dict parent_preset = parent_preset_dict.get("preset") - # Override the parent preset with the contents of this preset - self._value = mergedeep.merge( - parent_preset_dict, self._value, strategy=mergedeep.Strategy.REPLACE - ) + # Extend reversed, so top-most parents are first + if sub_parent_presets: + presets_to_merge.extend(reversed(sub_parent_presets.values())) + + # Append this preset (the subscription) last + presets_to_merge.append(copy.deepcopy(self._value)) + + # Merge all of the presets + self._value = mergedeep.merge({}, *presets_to_merge, strategy=mergedeep.Strategy.REPLACE) def __init__(self, config: ConfigFile, name: str, value: Any): super().__init__(name=name, value=value) diff --git a/tests/unit/config/test_preset.py b/tests/unit/config/test_preset.py index 54729004..643f1284 100644 --- a/tests/unit/config/test_preset.py +++ b/tests/unit/config/test_preset.py @@ -133,7 +133,7 @@ class TestPreset: assert tags_string_dict == { "key-1": "preset_0", - "key-2": "preset_1", + "key-2": "preset_2", "key-3": "this-preset", }