From 02e7949906cb0720d1e5ab2757f44f060fd1ec2f Mon Sep 17 00:00:00 2001
From: Pierre-Yves David <pierre-yves.david@ens-lyon.org>
Date: Fri, 26 Jan 2024 01:59:17 +0100
Subject: [PATCH] from_disk: introduce a FromDiskType enum

This is part of a wider effort to differentiate the various type of
"object_type" attribute around the model code base.
---
 swh/model/from_disk.py            | 41 ++++++++++++++++++++++++-------
 swh/model/tests/test_from_disk.py | 15 ++++++++---
 2 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/swh/model/from_disk.py b/swh/model/from_disk.py
index 6ce71cbc..015f7c42 100644
--- a/swh/model/from_disk.py
+++ b/swh/model/from_disk.py
@@ -41,7 +41,30 @@ from .exceptions import InvalidDirectoryPath
 from .git_objects import directory_entry_sort_key
 from .hashutil import MultiHash, hash_to_hex
 from .merkle import MerkleLeaf, MerkleNode
-from .swhids import CoreSWHID, ObjectType
+from .swhids import CoreSWHID
+from .swhids import ObjectType as SWHIDType
+
+
+class FromDiskType(enum.Enum):
+    """Possible object types for "from disk" object."""
+
+    CONTENT = "content"
+    DIRECTORY = "directory"
+
+    def __eq__(self, other):
+        # stay compatible with legacy string comparison (for now)
+        if isinstance(other, str):
+            # note: we should issue deprecation warning at some point
+            return self.value == other
+        return super().__eq__(other)
+
+    def __str__(self):
+        # preserve interpolation property (for now)
+        return self.value
+
+    def __hash__(self):
+        # make sure we don't confuse dictionary key matching (for now)
+        return hash(str(self.value))
 
 
 @attr.s(frozen=True, slots=True)
@@ -141,7 +164,7 @@ class Content(MerkleLeaf):
     """
 
     __slots__: List[str] = []
-    object_type: Final = "content"
+    object_type: Final = FromDiskType.CONTENT
 
     @classmethod
     def from_bytes(cls, *, mode, data):
@@ -230,7 +253,7 @@ class Content(MerkleLeaf):
 
     def swhid(self) -> CoreSWHID:
         """Return node identifier as a SWHID"""
-        return CoreSWHID(object_type=ObjectType.CONTENT, object_id=self.hash)
+        return CoreSWHID(object_type=SWHIDType.CONTENT, object_id=self.hash)
 
     def __repr__(self):
         return "Content(id=%s)" % hash_to_hex(self.hash)
@@ -442,7 +465,7 @@ class Directory(MerkleNode):
     """
 
     __slots__ = ["__entries", "__model_object"]
-    object_type: Final = "directory"
+    object_type: Final = FromDiskType.DIRECTORY
 
     @classmethod
     def from_disk(
@@ -539,14 +562,14 @@ class Directory(MerkleNode):
 
     @staticmethod
     def child_to_directory_entry(name, child):
-        if child.object_type == "directory":
+        if child.object_type == FromDiskType.DIRECTORY:
             return {
                 "type": "dir",
                 "perms": DentryPerms.directory,
                 "target": child.hash,
                 "name": name,
             }
-        elif child.object_type == "content":
+        elif child.object_type == FromDiskType.CONTENT:
             return {
                 "type": "file",
                 "perms": child.data["perms"],
@@ -579,7 +602,7 @@ class Directory(MerkleNode):
 
     def swhid(self) -> CoreSWHID:
         """Return node identifier as a SWHID"""
-        return CoreSWHID(object_type=ObjectType.DIRECTORY, object_id=self.hash)
+        return CoreSWHID(object_type=SWHIDType.DIRECTORY, object_id=self.hash)
 
     def compute_hash(self):
         return self.to_model().id
@@ -592,14 +615,14 @@ class Directory(MerkleNode):
 
             entries = []
             for name, child in self.items():
-                if child.object_type == "directory":
+                if child.object_type == FromDiskType.DIRECTORY:
                     e = DirectoryEntry(
                         type="dir",
                         perms=DentryPerms.directory,
                         target=child.hash,
                         name=name,
                     )
-                elif child.object_type == "content":
+                elif child.object_type == FromDiskType.CONTENT:
                     e = DirectoryEntry(
                         type="file",
                         perms=child.data["perms"],
diff --git a/swh/model/tests/test_from_disk.py b/swh/model/tests/test_from_disk.py
index e1b455ac..44991bd6 100644
--- a/swh/model/tests/test_from_disk.py
+++ b/swh/model/tests/test_from_disk.py
@@ -13,7 +13,13 @@ import unittest
 import pytest
 
 from swh.model import from_disk, model
-from swh.model.from_disk import Content, DentryPerms, Directory, DiskBackedContent
+from swh.model.from_disk import (
+    Content,
+    DentryPerms,
+    Directory,
+    DiskBackedContent,
+    FromDiskType,
+)
 from swh.model.hashutil import DEFAULT_ALGORITHMS, hash_to_bytes, hash_to_hex
 
 TEST_DATA = os.path.join(os.path.dirname(__file__), "data")
@@ -965,9 +971,12 @@ class TarballIterDirectory(DataMixin, unittest.TestCase):
             obj = directory[name]
             expected_nb[obj.object_type] += 1
 
-        assert len(contents) == expected_nb["content"] and len(contents) > 0
+        assert len(contents) == expected_nb[FromDiskType.CONTENT] and len(contents) > 0
         assert len(skipped_contents) == 0
-        assert len(directories) == expected_nb["directory"] and len(directories) > 0
+        assert (
+            len(directories) == expected_nb[FromDiskType.DIRECTORY]
+            and len(directories) > 0
+        )
 
 
 class DirectoryManipulation(DataMixin, unittest.TestCase):
-- 
GitLab