home · contact · privacy
Enhance BaseModel comparisons by hashing versioned and relations attributes.
authorChristian Heller <c.heller@plomlompom.de>
Fri, 14 Jun 2024 18:37:44 +0000 (20:37 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Fri, 14 Jun 2024 18:37:44 +0000 (20:37 +0200)
plomtask/db.py
plomtask/versioned_attributes.py

index b2f2142c9c6957c19e90674270a1635082050f59..a47dff15917651940483afe83f41152399bedf7f 100644 (file)
@@ -250,14 +250,19 @@ class BaseModel(Generic[BaseModelId]):
             raise HandledException(msg)
         self.id_ = id_
 
+    def __hash__(self) -> int:
+        hashable = [self.id_] + [getattr(self, name) for name in self.to_save]
+        for definition in self.to_save_relations:
+            attr = getattr(self, definition[2])
+            hashable += [tuple(rel.id_ for rel in attr)]
+        for name in self.to_save_versioned:
+            hashable += [hash(getattr(self, name))]
+        return hash(tuple(hashable))
+
     def __eq__(self, other: object) -> bool:
         if not isinstance(other, self.__class__):
             return False
-        to_hash_me = tuple([self.id_] +
-                           [getattr(self, name) for name in self.to_save])
-        to_hash_other = tuple([other.id_] +
-                              [getattr(other, name) for name in other.to_save])
-        return hash(to_hash_me) == hash(to_hash_other)
+        return hash(self) == hash(other)
 
     def __lt__(self, other: Any) -> bool:
         if not isinstance(other, self.__class__):
index d3c364942e3d76edf0eb9618df8366866c603709..cbd1c8e348a9230b10176d55b4b6a490fe11ff33 100644 (file)
@@ -19,6 +19,12 @@ class VersionedAttribute:
         self.default = default
         self.history: dict[str, str | float] = {}
 
+    def __hash__(self) -> int:
+        history_tuples = tuple((k, v) for k, v in self.history.items())
+        hashable = (self.parent.id_, self.table_name, self.default,
+                    history_tuples)
+        return hash(hashable)
+
     @property
     def _newest_timestamp(self) -> str:
         """Return most recent timestamp."""