Skip to content

Commit

Permalink
Make Configuration.load() an instance method
Browse files Browse the repository at this point in the history
  • Loading branch information
bartfeenstra committed May 19, 2024
1 parent 598731d commit f8812f4
Show file tree
Hide file tree
Showing 14 changed files with 149 additions and 312 deletions.
12 changes: 2 additions & 10 deletions betty/app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,25 +139,17 @@ def update(self, other: Self) -> None:
self._locale = other._locale
self._dispatch_change()

@classmethod
def load(
cls,
dump: Dump,
configuration: Self | None = None,
) -> Self:
if configuration is None:
configuration = cls()
def load(self, dump: Dump) -> None:
asserter = Asserter()
asserter.assert_record(
Fields(
OptionalField(
"locale",
Assertions(asserter.assert_str())
| asserter.assert_setattr(configuration, "locale"),
| asserter.assert_setattr(self, "locale"),
),
),
)(dump)
return configuration

def dump(self) -> VoidableDump:
return minimize({"locale": void_none(self.locale)}, True)
Expand Down
73 changes: 20 additions & 53 deletions betty/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,28 +82,14 @@ def remove_on_change(self, listener: ConfigurationListener) -> None:
def update(self, other: Self) -> None:
raise NotImplementedError(repr(self))

@classmethod
def load(
cls,
self,
dump: Dump,
configuration: Self | None = None,
) -> Self:
) -> None:
"""
Load dumped configuration into a new configuration instance.
Load dumped configuration.
"""
raise NotImplementedError(repr(cls))

@classmethod
def assert_load(
cls: type[ConfigurationT], configuration: ConfigurationT | None = None
) -> Assertion[Dump, ConfigurationT]:
def _assert_load(dump: Dump) -> ConfigurationT:
return cls.load(dump, configuration)

_assert_load.__qualname__ = (
f"{_assert_load.__qualname__} for {cls.__module__}.{cls.__qualname__}.load"
)
return _assert_load
raise NotImplementedError(repr(self))


ConfigurationT = TypeVar("ConfigurationT", bound=Configuration)
Expand Down Expand Up @@ -170,11 +156,13 @@ async def read(self, configuration_file_path: Path | None = None) -> None:
),
)
):
# @todo `loaded_configuration` should be created as a new instance of self
# @todo Do we need a new API method like Configuration.copy()?
# @todo
loaded_configuration = self.load(
formats.format_for(
self.configuration_file_path.suffix[1:]
).load(read_configuration),
self,
).load(read_configuration)
)
self.update(loaded_configuration)

Expand Down Expand Up @@ -307,9 +295,8 @@ def to_keys(self, *indices: int | slice) -> Iterator[ConfigurationKeyT]:
for index in sorted(unique_indices):
yield self.to_key(index)

@classmethod
def _item_type(cls) -> type[ConfigurationT]:
raise NotImplementedError(repr(cls))
def _item_type(self) -> type[ConfigurationT]:
raise NotImplementedError(repr(self))

def keys(self) -> Iterator[ConfigurationKeyT]:
raise NotImplementedError(repr(self))
Expand Down Expand Up @@ -381,24 +368,13 @@ def update(self, other: Self) -> None:
self._clear_without_dispatch()
self.append(*other)

@classmethod
def load(
cls,
dump: Dump,
configuration: Self | None = None,
) -> Self:
if configuration is None:
configuration = cls()
else:
configuration._clear_without_dispatch()
def load(self, dump: Dump) -> None:
self._clear_without_dispatch()
asserter = Asserter()
with SerdeErrorCollection().assert_valid():
configuration.append(
*asserter.assert_sequence(Assertions(cls._item_type().assert_load()))(
dump
)
self.append(
*asserter.assert_sequence(Assertions(self._item_type().load))(dump)
)
return configuration

def dump(self) -> VoidableDump:
return minimize(
Expand Down Expand Up @@ -519,21 +495,13 @@ def replace(self, *values: ConfigurationT) -> None:
# Ensure everything is in the correct order. This will also trigger reactors.
self.move_to_beginning(*other_keys)

@classmethod
def load(
cls,
dump: Dump,
configuration: Self | None = None,
) -> Self:
if configuration is None:
configuration = cls()
def load(self, dump: Dump) -> None:
asserter = Asserter()
dict_dump = asserter.assert_dict()(dump)
mapping = asserter.assert_mapping(Assertions(cls._item_type().load))(
{key: cls._load_key(value, key) for key, value in dict_dump.items()}
mapping = asserter.assert_mapping(Assertions(self._item_type().load))(
{key: self._load_key(value, key) for key, value in dict_dump.items()}
)
configuration.replace(*mapping.values())
return configuration
self.replace(*mapping.values())

def dump(self) -> VoidableDump:
dump = {}
Expand Down Expand Up @@ -617,13 +585,12 @@ def _move_by_offset(
def _get_key(self, configuration: ConfigurationT) -> ConfigurationKeyT:
raise NotImplementedError(repr(self))

@classmethod
def _load_key(
cls,
self,
item_dump: Dump,
key_dump: str,
) -> Dump:
raise NotImplementedError(repr(cls))
raise NotImplementedError(repr(self))

def _dump_key(self, item_dump: VoidableDump) -> tuple[VoidableDump, str]:
raise NotImplementedError(repr(self))
Expand Down
54 changes: 8 additions & 46 deletions betty/extension/cotton_candy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,9 @@ def hex(self, hex_value: str) -> None:
def update(self, other: Self) -> None:
self.hex = other.hex

@classmethod
def load(
cls,
dump: Dump,
configuration: Self | None = None,
) -> Self:
def load(self, dump: Dump) -> None:
asserter = Asserter()
hex_value = asserter.assert_str()(dump)
if configuration is None:
configuration = cls(hex_value)
else:
configuration.hex = hex_value
return configuration
self.hex = asserter.assert_str()(dump)

def dump(self) -> VoidableDump:
return self._hex
Expand Down Expand Up @@ -148,60 +138,32 @@ def link_inactive_color(self) -> _ColorConfiguration:
def link_active_color(self) -> _ColorConfiguration:
return self._link_active_color

@classmethod
def load(
cls,
dump: Dump,
configuration: Self | None = None,
) -> Self:
if configuration is None:
configuration = cls()
def load(self, dump: Dump) -> None:
asserter = Asserter()
asserter.assert_record(
Fields(
OptionalField(
"featured_entities",
Assertions(
configuration._featured_entities.assert_load(
configuration._featured_entities
)
),
Assertions(self._featured_entities.load),
),
OptionalField(
"primary_inactive_color",
Assertions(
configuration._primary_inactive_color.assert_load(
configuration._primary_inactive_color
)
),
Assertions(self._primary_inactive_color.load),
),
OptionalField(
"primary_active_color",
Assertions(
configuration._primary_active_color.assert_load(
configuration._primary_active_color
)
),
Assertions(self._primary_active_color.load),
),
OptionalField(
"link_inactive_color",
Assertions(
configuration._link_inactive_color.assert_load(
configuration._link_inactive_color
)
),
Assertions(self._link_inactive_color.load),
),
OptionalField(
"link_active_color",
Assertions(
configuration._link_active_color.assert_load(
configuration._link_active_color
)
),
Assertions(self._link_active_color.load),
),
)
)(dump)
return configuration

def dump(self) -> VoidableDump:
return minimize(
Expand Down
31 changes: 5 additions & 26 deletions betty/extension/gramps/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,17 @@ def file_path(self) -> Path | None:
def file_path(self, file_path: Path | None) -> None:
self._file_path = file_path

@classmethod
def load(
cls,
dump: Dump,
configuration: Self | None = None,
) -> Self:
if configuration is None:
configuration = cls()
def load(self, dump: Dump) -> None:
asserter = Asserter()
asserter.assert_record(
Fields(
RequiredField(
"file",
Assertions(asserter.assert_path())
| asserter.assert_setattr(configuration, "file_path"),
| asserter.assert_setattr(self, "file_path"),
),
)
)(dump)
return configuration

def dump(self) -> VoidableDump:
return {"file": str(self.file_path) if self.file_path else None}
Expand All @@ -63,8 +55,7 @@ def update(self, other: Self) -> None:


class FamilyTreeConfigurationSequence(ConfigurationSequence[FamilyTreeConfiguration]):
@classmethod
def _item_type(cls) -> type[FamilyTreeConfiguration]:
def _item_type(self) -> type[FamilyTreeConfiguration]:
return FamilyTreeConfiguration


Expand All @@ -85,28 +76,16 @@ def family_trees(self) -> FamilyTreeConfigurationSequence:
def update(self, other: Self) -> None:
self._family_trees.update(other._family_trees)

@classmethod
def load(
cls,
dump: Dump,
configuration: Self | None = None,
) -> Self:
if configuration is None:
configuration = cls()
def load(self, dump: Dump) -> None:
asserter = Asserter()
asserter.assert_record(
Fields(
OptionalField(
"family_trees",
Assertions(
configuration._family_trees.assert_load(
configuration.family_trees
)
),
Assertions(self._family_trees.load),
),
)
)(dump)
return configuration

def dump(self) -> VoidableDump:
return minimize(
Expand Down
14 changes: 3 additions & 11 deletions betty/extension/nginx/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,7 @@ def update(self, other: Self) -> None:
self._www_directory_path = other._www_directory_path
self._dispatch_change()

@classmethod
def load(
cls,
dump: Dump,
configuration: Self | None = None,
) -> Self:
if configuration is None:
configuration = cls()
def load(self, dump: Dump) -> None:
asserter = Asserter()
asserter.assert_record(
Fields(
Expand All @@ -59,16 +52,15 @@ def load(
asserter.assert_bool(), asserter.assert_none()
)
)
| asserter.assert_setattr(configuration, "https"),
| asserter.assert_setattr(self, "https"),
),
OptionalField(
"www_directory_path",
Assertions(asserter.assert_str())
| asserter.assert_setattr(configuration, "www_directory_path"),
| asserter.assert_setattr(self, "www_directory_path"),
),
)
)(dump)
return configuration

def dump(self) -> VoidableDump:
dump: VoidableDictDump[VoidableDump] = {
Expand Down
12 changes: 2 additions & 10 deletions betty/extension/wikipedia/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,17 @@ def update(self, other: Self) -> None:
self._populate_images = other._populate_images
self._dispatch_change()

@classmethod
def load(
cls,
dump: Dump,
configuration: Self | None = None,
) -> Self:
if configuration is None:
configuration = cls()
def load(self, dump: Dump) -> None:
asserter = Asserter()
asserter.assert_record(
Fields(
OptionalField(
"populate_images",
Assertions(asserter.assert_bool())
| asserter.assert_setattr(configuration, "populate_images"),
| asserter.assert_setattr(self, "populate_images"),
),
)
)(dump)
return configuration

def dump(self) -> VoidableDump:
dump: VoidableDictDump[VoidableDump] = {
Expand Down
Loading

0 comments on commit f8812f4

Please sign in to comment.