Page MenuHomeSoftware Heritage

D3152.id11206.diff
No OneTemporary

D3152.id11206.diff

diff --git a/requirements.txt b/requirements.txt
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,9 +1,10 @@
# Add here external Python modules dependencies, one per line. Module names
# should match https://pypi.python.org/pypi names. For the full spec or
# dependency lines, see https://pip.readthedocs.org/en/1.1/requirements.html
-vcversioner
attrs
attrs_strict
hypothesis
-python-dateutil
iso8601
+python-dateutil
+typing_extensions
+vcversioner
diff --git a/swh/model/model.py b/swh/model/model.py
--- a/swh/model/model.py
+++ b/swh/model/model.py
@@ -8,6 +8,7 @@
from abc import ABCMeta, abstractmethod
from enum import Enum
from typing import Dict, List, Optional, Union
+from typing_extensions import Final
import attr
from attrs_strict import type_validator
@@ -90,6 +91,8 @@
class Person(BaseModel):
"""Represents the author/committer of a revision or release."""
+ object_type: Final = "person"
+
fullname = attr.ib(type=bytes, validator=type_validator())
name = attr.ib(type=Optional[bytes], validator=type_validator())
email = attr.ib(type=Optional[bytes], validator=type_validator())
@@ -134,6 +137,8 @@
class Timestamp(BaseModel):
"""Represents a naive timestamp from a VCS."""
+ object_type: Final = "timestamp"
+
seconds = attr.ib(type=int, validator=type_validator())
microseconds = attr.ib(type=int, validator=type_validator())
@@ -154,6 +159,8 @@
class TimestampWithTimezone(BaseModel):
"""Represents a TZ-aware timestamp from a VCS."""
+ object_type: Final = "timestamp_with_timezone"
+
timestamp = attr.ib(type=Timestamp, validator=type_validator())
offset = attr.ib(type=int, validator=type_validator())
negative_utc = attr.ib(type=bool, validator=type_validator())
@@ -204,6 +211,8 @@
class Origin(BaseModel):
"""Represents a software source: a VCS and an URL."""
+ object_type: Final = "origin"
+
url = attr.ib(type=str, validator=type_validator())
@@ -212,6 +221,8 @@
"""Represents a visit of an origin at a given point in time, by a
SWH loader."""
+ object_type: Final = "origin_visit"
+
origin = attr.ib(type=str, validator=type_validator())
date = attr.ib(type=datetime.datetime, validator=type_validator())
status = attr.ib(
@@ -248,6 +259,8 @@
"""
+ object_type: Final = "origin_visit_status"
+
origin = attr.ib(type=str, validator=type_validator())
visit = attr.ib(type=int, validator=type_validator())
@@ -287,6 +300,8 @@
class SnapshotBranch(BaseModel):
"""Represents one of the branches of a snapshot."""
+ object_type: Final = "snapshot_branch"
+
target = attr.ib(type=bytes, validator=type_validator())
target_type = attr.ib(type=TargetType, validator=type_validator())
@@ -307,6 +322,8 @@
class Snapshot(BaseModel, HashableObject):
"""Represents the full state of an origin at a given point in time."""
+ object_type: Final = "snapshot"
+
branches = attr.ib(
type=Dict[bytes, Optional[SnapshotBranch]], validator=type_validator()
)
@@ -330,6 +347,8 @@
@attr.s(frozen=True)
class Release(BaseModel, HashableObject):
+ object_type: Final = "release"
+
name = attr.ib(type=bytes, validator=type_validator())
message = attr.ib(type=Optional[bytes], validator=type_validator())
target = attr.ib(type=Optional[Sha1Git], validator=type_validator())
@@ -380,6 +399,8 @@
@attr.s(frozen=True)
class Revision(BaseModel, HashableObject):
+ object_type: Final = "revision"
+
message = attr.ib(type=bytes, validator=type_validator())
author = attr.ib(type=Person, validator=type_validator())
committer = attr.ib(type=Person, validator=type_validator())
@@ -425,6 +446,8 @@
@attr.s(frozen=True)
class DirectoryEntry(BaseModel):
+ object_type: Final = "directory_entry"
+
name = attr.ib(type=bytes, validator=type_validator())
type = attr.ib(type=str, validator=attr.validators.in_(["file", "dir", "rev"]))
target = attr.ib(type=Sha1Git, validator=type_validator())
@@ -434,6 +457,8 @@
@attr.s(frozen=True)
class Directory(BaseModel, HashableObject):
+ object_type: Final = "directory"
+
entries = attr.ib(type=List[DirectoryEntry], validator=type_validator())
id = attr.ib(type=Sha1Git, validator=type_validator(), default=b"")
@@ -487,6 +512,8 @@
@attr.s(frozen=True)
class Content(BaseContent):
+ object_type: Final = "content"
+
sha1 = attr.ib(type=bytes, validator=type_validator())
sha1_git = attr.ib(type=Sha1Git, validator=type_validator())
sha256 = attr.ib(type=bytes, validator=type_validator())
@@ -550,6 +577,8 @@
@attr.s(frozen=True)
class SkippedContent(BaseContent):
+ object_type: Final = "skipped_content"
+
sha1 = attr.ib(type=Optional[bytes], validator=type_validator())
sha1_git = attr.ib(type=Optional[Sha1Git], validator=type_validator())
sha256 = attr.ib(type=Optional[bytes], validator=type_validator())
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
@@ -13,6 +13,7 @@
import pytest
from swh.model.model import (
+ BaseModel,
Content,
SkippedContent,
Directory,
@@ -437,3 +438,23 @@
snp_id = hash_to_bytes(snapshot_identifier(snp_dict))
snp_model = Snapshot.from_dict(snp_dict)
assert snp_model.id == snp_id
+
+
+@given(strategies.objects(split_content=True))
+def test_object_type(objtype_and_obj):
+ obj_type, obj = objtype_and_obj
+ assert obj_type == obj.object_type
+
+
+def test_object_type_is_final():
+ object_types = set()
+
+ def check_final(cls):
+ if not cls.__subclasses__():
+ assert cls.object_type not in object_types
+ object_types.add(cls.object_type)
+ else:
+ for subcls in cls.__subclasses__():
+ check_final(subcls)
+
+ check_final(BaseModel)

File Metadata

Mime Type
text/plain
Expires
Nov 5 2024, 8:58 AM (11 w, 18 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3225465

Event Timeline