[docs]
class ConfigurationCollection(
Configuration, Generic[_ConfigurationKeyT, _ConfigurationT]
):
"""
Any collection of :py:class:`betty.config.Configuration` values.
"""
_configurations: (
MutableSequence[_ConfigurationT]
| MutableMapping[_ConfigurationKeyT, _ConfigurationT]
)
[docs]
def __init__(
self,
configurations: Iterable[_ConfigurationT] | None = None,
):
super().__init__()
if configurations is not None:
self.append(*configurations)
@abstractmethod
def __iter__(self) -> Iterator[_ConfigurationKeyT] | Iterator[_ConfigurationT]:
pass
def __contains__(self, item: Any) -> bool:
return item in self._configurations
@abstractmethod
def __getitem__(self, configuration_key: _ConfigurationKeyT) -> _ConfigurationT:
pass
def __delitem__(self, configuration_key: _ConfigurationKeyT) -> None:
self.remove(configuration_key)
def __len__(self) -> int:
return len(self._configurations)
@override # type: ignore[callable-functiontype]
@recursive_repr()
def __repr__(self) -> str:
return repr_instance(self, configurations=list(self.values()))
[docs]
@abstractmethod
def replace(self, *configurations: _ConfigurationT) -> None:
"""
Replace any existing values with the given ones.
"""
pass
[docs]
def remove(self, *configuration_keys: _ConfigurationKeyT) -> None:
"""
Remove the given keys from the collection.
"""
for configuration_key in configuration_keys:
configuration = self._configurations[configuration_key] # type: ignore[call-overload]
del self._configurations[configuration_key] # type: ignore[call-overload]
self._post_remove(configuration)
[docs]
def clear(self) -> None:
"""
Clear all items from the collection.
"""
self.remove(*self.keys())
def _pre_add(self, configuration: _ConfigurationT) -> None:
pass
def _post_remove(self, configuration: _ConfigurationT) -> None:
pass
[docs]
@abstractmethod
def to_index(self, configuration_key: _ConfigurationKeyT) -> int:
"""
Get the index for the given key.
"""
pass
[docs]
def to_indices(self, *configuration_keys: _ConfigurationKeyT) -> Iterator[int]:
"""
Get the indices for the given keys.
"""
for configuration_key in configuration_keys:
yield self.to_index(configuration_key)
[docs]
@abstractmethod
def to_key(self, index: int) -> _ConfigurationKeyT:
"""
Get the key for the item at the given index.
"""
pass
[docs]
def to_keys(self, *indices: int | slice) -> Iterator[_ConfigurationKeyT]:
"""
Get the keys for the items at the given indices.
"""
unique_indices = set()
for index in indices:
if isinstance(index, slice):
for slice_index in slice_to_range(index, self._configurations):
unique_indices.add(slice_index)
else:
unique_indices.add(index)
for index in sorted(unique_indices):
yield self.to_key(index)
[docs]
@abstractmethod
def load_item(self, dump: Dump) -> _ConfigurationT:
"""
Create and load a new item from the given dump, or raise an assertion error.
:raise betty.assertion.error.AssertionFailed: Raised when the dump is invalid and cannot be loaded.
"""
pass
[docs]
@abstractmethod
def keys(self) -> Iterator[_ConfigurationKeyT]:
"""
Get all keys in this collection.
"""
pass
[docs]
@abstractmethod
def values(self) -> Iterator[_ConfigurationT]:
"""
Get all values in this collection.
"""
pass
[docs]
@abstractmethod
def prepend(self, *configurations: _ConfigurationT) -> None:
"""
Prepend the given values to the beginning of the sequence.
"""
pass
[docs]
@abstractmethod
def append(self, *configurations: _ConfigurationT) -> None:
"""
Append the given values to the end of the sequence.
"""
pass
[docs]
@abstractmethod
def insert(self, index: int, *configurations: _ConfigurationT) -> None:
"""
Insert the given values at the given index.
"""
pass
[docs]
@abstractmethod
def move_to_beginning(self, *configuration_keys: _ConfigurationKeyT) -> None:
"""
Move the given keys (and their values) to the beginning of the sequence.
"""
pass
[docs]
@abstractmethod
def move_towards_beginning(self, *configuration_keys: _ConfigurationKeyT) -> None:
"""
Move the given keys (and their values) one place towards the beginning of the sequence.
"""
pass
[docs]
@abstractmethod
def move_to_end(self, *configuration_keys: _ConfigurationKeyT) -> None:
"""
Move the given keys (and their values) to the end of the sequence.
"""
pass
[docs]
@abstractmethod
def move_towards_end(self, *configuration_keys: _ConfigurationKeyT) -> None:
"""
Move the given keys (and their values) one place towards the end of the sequence.
"""
pass