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))