From 509f2fcee95c0f1ac0e15c127366856476c7d303 Mon Sep 17 00:00:00 2001 From: vlorentz <vlorentz@softwareheritage.org> Date: Wed, 15 Nov 2023 09:14:20 +0000 Subject: [PATCH] Rename HashableObject to BaseHashableModel and make it a subclass of BaseModel instead of a mix-in class. A future commit will add a method implemented by both with different signatures that mypy cannot unify yet. --- swh/model/model.py | 19 +++++++++++-------- swh/model/tests/test_model.py | 4 ++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/swh/model/model.py b/swh/model/model.py index c919df0d..0170bcaf 100644 --- a/swh/model/model.py +++ b/swh/model/model.py @@ -382,7 +382,7 @@ def _compute_hash_from_manifest(manifest: bytes) -> Sha1Git: return hashlib.new("sha1", manifest).digest() -class HashableObject(metaclass=ABCMeta): +class BaseHashableModel(BaseModel, metaclass=ABCMeta): """Mixin to automatically compute object identifier hash when the associated model is instantiated.""" @@ -412,14 +412,17 @@ class HashableObject(metaclass=ABCMeta): return self.id def check(self) -> None: - super().check() # type: ignore + super().check() if self.id != self.compute_hash(): raise ValueError("'id' does not match recomputed hash.") -class HashableObjectWithManifest(HashableObject): - """Derived class of HashableObject, for objects that may need to store +HashableObject = BaseHashableModel # deprecated alias + + +class HashableObjectWithManifest(BaseHashableModel): + """Derived class of BaseHashableModel, for objects that may need to store verbatim git objects as ``raw_manifest`` to preserve original hashes.""" __slots__ = () @@ -767,7 +770,7 @@ class TimestampWithTimezone(BaseModel): @attr.s(frozen=True, slots=True, field_transformer=optimize_all_validators) -class Origin(HashableObject, BaseModel): +class Origin(BaseHashableModel): """Represents a software source: a VCS and an URL.""" object_type: Final = "origin" @@ -933,7 +936,7 @@ class SnapshotBranch(BaseModel): @attr.s(frozen=True, slots=True, field_transformer=optimize_all_validators) -class Snapshot(HashableObject, BaseModel): +class Snapshot(BaseHashableModel): """Represents the full state of an origin at a given point in time.""" object_type: Final = "snapshot" @@ -1651,7 +1654,7 @@ def normalize_discovery_date(value: Any) -> datetime.datetime: @attr.s(frozen=True, slots=True, field_transformer=optimize_all_validators) -class RawExtrinsicMetadata(HashableObject, BaseModel): +class RawExtrinsicMetadata(BaseHashableModel): object_type: Final = "raw_extrinsic_metadata" # target object @@ -1897,7 +1900,7 @@ class RawExtrinsicMetadata(HashableObject, BaseModel): @attr.s(frozen=True, slots=True, field_transformer=optimize_all_validators) -class ExtID(HashableObject, BaseModel): +class ExtID(BaseHashableModel): object_type: Final = "extid" extid_type = attr.ib(type=str, validator=generic_type_validator) diff --git a/swh/model/tests/test_model.py b/swh/model/tests/test_model.py index f2adc629..248410f9 100644 --- a/swh/model/tests/test_model.py +++ b/swh/model/tests/test_model.py @@ -1509,9 +1509,13 @@ def test_object_type(objtype_and_obj): def test_object_type_is_final(): + checked_classes = set() object_types = set() def check_final(cls): + if cls in checked_classes: + return + checked_classes.add(cls) if hasattr(cls, "object_type"): assert cls.object_type not in object_types object_types.add(cls.object_type) -- GitLab