From 12138050674da516d3797841c7830d4004d880c0 Mon Sep 17 00:00:00 2001 From: Bart Feenstra Date: Sat, 19 Oct 2024 12:06:53 +0100 Subject: [PATCH] Reintroduce Configuration.update() (#2147) --- betty/config/__init__.py | 8 ++++++-- betty/project/__init__.py | 10 +++++----- betty/project/extension/gramps/config.py | 2 +- betty/tests/config/test___init__.py | 23 +++++++++++++++++++++++ betty/tests/coverage/test_coverage.py | 3 --- 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/betty/config/__init__.py b/betty/config/__init__.py index 1e5327f4b..964df7e2a 100644 --- a/betty/config/__init__.py +++ b/betty/config/__init__.py @@ -6,7 +6,7 @@ from collections.abc import Callable from contextlib import chdir -from typing import Generic, TypeVar, TypeAlias, TYPE_CHECKING +from typing import Generic, TypeVar, TypeAlias, TYPE_CHECKING, Self import aiofiles from aiofiles.os import makedirs @@ -31,7 +31,11 @@ class Configuration(Loadable, Dumpable): Any configuration object. """ - pass + def update(self, other: Self) -> None: + """ + Update this configuration with the values from ``other``. + """ + self.load(other.dump()) _ConfigurationT = TypeVar("_ConfigurationT", bound=Configuration) diff --git a/betty/project/__init__.py b/betty/project/__init__.py index 1df858a41..4c841cbbd 100644 --- a/betty/project/__init__.py +++ b/betty/project/__init__.py @@ -363,11 +363,11 @@ async def _init_extensions(self) -> ProjectExtensions: isinstance(extension, ConfigurableExtension) and extension_type in self.configuration.extensions ): - # This is a hack because we do not yet have a way to inject configuration into extensions **when - # initializing them**. - extension._configuration = self.configuration.extensions[ - extension_type - ].extension_configuration + extension.configuration.update( + self.configuration.extensions[ + extension_type + ].extension_configuration + ) if isinstance(extension, Theme): theme_count += 1 extensions_batch.append(extension) diff --git a/betty/project/extension/gramps/config.py b/betty/project/extension/gramps/config.py index f1596666d..63560b0fa 100644 --- a/betty/project/extension/gramps/config.py +++ b/betty/project/extension/gramps/config.py @@ -299,7 +299,7 @@ class FamilyTreeConfigurationSequence(ConfigurationSequence[FamilyTreeConfigurat @override def load_item(self, dump: Dump) -> FamilyTreeConfiguration: # Use a dummy path to satisfy initializer arguments. - # It will be overridden when loading the fump. + # It will be overridden when loading the dump. item = FamilyTreeConfiguration(Path()) item.load(dump) return item diff --git a/betty/tests/config/test___init__.py b/betty/tests/config/test___init__.py index 3a61dffbf..6a0285a91 100644 --- a/betty/tests/config/test___init__.py +++ b/betty/tests/config/test___init__.py @@ -5,17 +5,40 @@ import pytest from typing_extensions import override +from betty.assertion import assert_int from betty.assertion.error import AssertionFailed from betty.config import ( Configurable, assert_configuration_file, write_configuration_file, + Configuration, ) from betty.error import FileNotFound from betty.serde.dump import Dump from betty.test_utils.config import DummyConfiguration +class TestConfiguration: + class _DummyConfiguration(Configuration): + def __init__(self, value: int): + self.value = value + + @override + def load(self, dump: Dump) -> None: + self.value = assert_int()(dump) + + @override + def dump(self) -> Dump: + return self.value + + def test_update(self) -> None: + sut = self._DummyConfiguration(123) + value = 456 + other = self._DummyConfiguration(value) + sut.update(other) + assert sut.value == value + + class TestConfigurable: class _DummyConfigurable(Configurable[DummyConfiguration]): def __init__(self, configuration: DummyConfiguration | None = None): diff --git a/betty/tests/coverage/test_coverage.py b/betty/tests/coverage/test_coverage.py index 829435207..3edbe5f32 100644 --- a/betty/tests/coverage/test_coverage.py +++ b/betty/tests/coverage/test_coverage.py @@ -114,9 +114,6 @@ class MissingReason(Enum): "__aexit__": MissingReason.SHOULD_BE_COVERED, }, }, - "betty/config/__init__.py": { - "Configuration": MissingReason.ABSTRACT, - }, "betty/config/collections/__init__.py": MissingReason.ABSTRACT, "betty/contextlib.py": { "SynchronizedContextManager": {