diff --git a/swh/model/hypothesis_strategies.py b/swh/model/hypothesis_strategies.py --- a/swh/model/hypothesis_strategies.py +++ b/swh/model/hypothesis_strategies.py @@ -3,6 +3,7 @@ # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information +import attr import datetime from hypothesis.strategies import ( @@ -94,9 +95,10 @@ author=none(), date=none(), target=sha1_git())) - rel.date = date - rel.author = author - return rel + return attr.evolve( + rel, + date=date, + author=author) def revision_metadata(): diff --git a/swh/model/model.py b/swh/model/model.py --- a/swh/model/model.py +++ b/swh/model/model.py @@ -51,7 +51,7 @@ return cls(**d) -@attr.s +@attr.s(frozen=True) class Person(BaseModel): """Represents the author/committer of a revision or release.""" name = attr.ib(type=bytes) @@ -59,7 +59,7 @@ fullname = attr.ib(type=bytes) -@attr.s +@attr.s(frozen=True) class Timestamp(BaseModel): """Represents a naive timestamp from a VCS.""" seconds = attr.ib(type=int) @@ -78,7 +78,7 @@ raise ValueError('Microseconds must be in [0, 1000000[.') -@attr.s +@attr.s(frozen=True) class TimestampWithTimezone(BaseModel): """Represents a TZ-aware timestamp from a VCS.""" timestamp = attr.ib(type=Timestamp) @@ -105,7 +105,7 @@ negative_utc=d['negative_utc']) -@attr.s +@attr.s(frozen=True) class Origin(BaseModel): """Represents a software source: a VCS and an URL.""" url = attr.ib(type=str) @@ -117,7 +117,7 @@ return r -@attr.s +@attr.s(frozen=True) class OriginVisit(BaseModel): """Represents a visit of an origin at a given point in time, by a SWH loader.""" @@ -176,7 +176,7 @@ SNAPSHOT = 'snapshot' -@attr.s +@attr.s(frozen=True) class SnapshotBranch(BaseModel): """Represents one of the branches of a snapshot.""" target = attr.ib(type=bytes) @@ -198,7 +198,7 @@ target_type=TargetType(d['target_type'])) -@attr.s +@attr.s(frozen=True) class Snapshot(BaseModel): """Represents the full state of an origin at a given point in time.""" id = attr.ib(type=Sha1Git) @@ -214,7 +214,7 @@ }) -@attr.s +@attr.s(frozen=True) class Release(BaseModel): id = attr.ib(type=Sha1Git) name = attr.ib(type=bytes) @@ -261,7 +261,7 @@ MERCURIAL = 'hg' -@attr.s +@attr.s(frozen=True) class Revision(BaseModel): id = attr.ib(type=Sha1Git) message = attr.ib(type=bytes) @@ -291,7 +291,7 @@ **d) -@attr.s +@attr.s(frozen=True) class DirectoryEntry(BaseModel): name = attr.ib(type=bytes) type = attr.ib(type=str, @@ -301,7 +301,7 @@ """Usually one of the values of `swh.model.from_disk.DentryPerms`.""" -@attr.s +@attr.s(frozen=True) class Directory(BaseModel): id = attr.ib(type=Sha1Git) entries = attr.ib(type=List[DirectoryEntry]) @@ -314,7 +314,7 @@ for entry in d['entries']]) -@attr.s +@attr.s(frozen=True) class Content(BaseModel): sha1 = attr.ib(type=bytes) sha1_git = attr.ib(type=Sha1Git) diff --git a/swh/model/tests/test_model.py b/swh/model/tests/test_model.py --- a/swh/model/tests/test_model.py +++ b/swh/model/tests/test_model.py @@ -3,6 +3,7 @@ # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information +import attr import copy from hypothesis import given @@ -44,8 +45,9 @@ obj = origin_visit.to_dict() assert 'type' not in obj['origin'] - origin_visit.origin.type = None - assert origin_visit == type(origin_visit).from_dict(obj) + origin2 = attr.evolve(origin_visit.origin, type=None) + origin_visit2 = attr.evolve(origin_visit, origin=origin2) + assert origin_visit2 == type(origin_visit).from_dict(obj) def test_content_get_hash():