diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f972cd9cf2c0ab3a94442a9ae373962f75042954..33a226de603535a6347f7fd1c5a5ec7f4a7e8765 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,7 +30,7 @@ repos: types: [python] - repo: https://github.com/PyCQA/isort - rev: 5.10.1 + rev: 5.11.5 hooks: - id: isort diff --git a/PKG-INFO b/PKG-INFO index 0bffcf849391d681e7acd8b374f63e92b09fe374..849ef42ab9d4871e6b8807c9f75df4e8031a764d 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: swh.model -Version: 6.6.1 +Version: 6.6.2 Summary: Software Heritage data model Home-page: https://forge.softwareheritage.org/diffusion/DMOD/ Author: Software Heritage developers diff --git a/docs/index.rst b/docs/index.rst index 8ad09ac003e8efc69d4682cb57a1e531cffcd3c9..23ef1e453ce71f491b6683663d7c1bc399b8e52b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,4 +12,12 @@ Implementation of the :ref:`data-model` to archive source code artifacts. data-model persistent-identifiers cli - /apidoc/swh.model + +.. only:: standalone_package_doc + + Indices and tables + ------------------ + + * :ref:`genindex` + * :ref:`modindex` + * :ref:`search` diff --git a/swh.model.egg-info/PKG-INFO b/swh.model.egg-info/PKG-INFO index 0bffcf849391d681e7acd8b374f63e92b09fe374..849ef42ab9d4871e6b8807c9f75df4e8031a764d 100644 --- a/swh.model.egg-info/PKG-INFO +++ b/swh.model.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: swh.model -Version: 6.6.1 +Version: 6.6.2 Summary: Software Heritage data model Home-page: https://forge.softwareheritage.org/diffusion/DMOD/ Author: Software Heritage developers diff --git a/swh/model/collections.py b/swh/model/collections.py index 2a5195746187eaaea38fca78b8784b6596e9309e..d7150fa9c2477d2297c175bee37d67da2a5f8408 100644 --- a/swh/model/collections.py +++ b/swh/model/collections.py @@ -1,11 +1,14 @@ -# Copyright (C) 2020 The Software Heritage developers +# Copyright (C) 2020-2023 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information +from __future__ import annotations + """Utility data structures.""" from collections.abc import Mapping +import copy from typing import Dict, Generic, Iterable, Optional, Tuple, TypeVar, Union KT = TypeVar("KT") @@ -18,36 +21,35 @@ class ImmutableDict(Mapping, Generic[KT, VT]): This class behaves like a dictionary, but internally stores objects in a tuple, so it is both immutable and hashable.""" - data: Tuple[Tuple[KT, VT], ...] + _data: Dict[KT, VT] def __init__( self, - data: Union[ - Iterable[Tuple[KT, VT]], "ImmutableDict[KT, VT]", Dict[KT, VT] - ] = {}, + data: Union[Iterable[Tuple[KT, VT]], ImmutableDict[KT, VT], Dict[KT, VT]] = {}, ): if isinstance(data, dict): - self.data = tuple(item for item in data.items()) + self._data = data elif isinstance(data, ImmutableDict): - self.data = data.data + self._data = data._data else: - self.data = tuple(data) + self._data = {k: v for k, v in data} + + @property + def data(self): + return tuple(self._data.items()) def __repr__(self): return f"ImmutableDict({dict(self.data)!r})" def __getitem__(self, key): - for (k, v) in self.data: - if k == key: - return v - raise KeyError(key) + return self._data[key] def __iter__(self): for (k, v) in self.data: yield k def __len__(self): - return len(self.data) + return len(self._data) def items(self): yield from self.data @@ -55,15 +57,9 @@ class ImmutableDict(Mapping, Generic[KT, VT]): def __hash__(self): return hash(tuple(sorted(self.data))) - def copy_pop(self, popped_key) -> Tuple[Optional[VT], "ImmutableDict[KT, VT]"]: + def copy_pop(self, popped_key) -> Tuple[Optional[VT], ImmutableDict[KT, VT]]: """Returns a copy of this ImmutableDict without the given key, as well as the value associated to the key.""" - popped_value = None - new_items = [] - for (key, value) in self.data: - if key == popped_key: - popped_value = value - else: - new_items.append((key, value)) - + new_items = copy.deepcopy(self._data) + popped_value = new_items.pop(popped_key, None) # type: ignore return (popped_value, ImmutableDict(new_items))