__init__.py

Last source

View documentation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
"""Package defining the :obj:`Namespace` entity."""

import enum
from typing import Any, Optional

from isshub.domain.utils.entity import (
    BaseEntityWithIdentifier,
    field_validator,
    optional_field,
    required_field,
    validated,
)


class NamespaceKind(enum.Enum):
    """All the available kinds of namespace."""

    ORGANIZATION = "Organization"
    TEAM = "Team"
    GROUP = "Group"


@validated()
class Namespace(BaseEntityWithIdentifier):
    """A namespace can contain namespaces and repositories.

    Attributes
    ----------
    identifier : UUID
        The unique identifier of the namespace
    name : str
        The name of the namespace. Unique in its parent namespace.
    namespace : Optional[Namespace]
        Where the namespace can be found.
    kind : NamespaceKind
        The kind of namespace.
    description : Optional[str]
        The description of the namespace.

    """

    name: str = required_field(str)
    kind: NamespaceKind = required_field(NamespaceKind, relation_verbose_name="is a")
    namespace: Optional["Namespace"] = optional_field(
        "self", relation_verbose_name="may belongs to"
    )
    description: Optional[str] = optional_field(str)

    @field_validator(namespace)
    def validate_namespace_is_not_in_a_loop(  # noqa  # pylint: disable=unused-argument
        self, field: Any, value: Any
    ) -> None:
        """Validate that the :obj:`Namespace.namespace` field is not in a loop.

        Being in a loop means that one of the descendants is the parent of one of the ascendants.

        Parameters
        ----------
        field : Any
            The field to validate.
        value : Any
            The value to validate for the `field`.

        Raises
        ------
        ValueError
            If the given namespace (`value`) is in a loop

        """
        if not value:
            return

        parent = value
        while parent := parent.namespace:
            if parent == value:
                raise ValueError(
                    f"{self.__class__.__name__}.namespace cannot be in a loop"
                )

Changes

feat(repository): Add domain repositories

Commit
Hash

27f013e2a3722926a9bbe300a77a493604f0993c

Date

2020-10-06 17:30:45 +0200

Type

Modified

Stats

+3 -3

@@ -1,4 +1,4 @@
-"""Package defining the ``Namespace`` entity."""
+"""Package defining the :obj:`Namespace` entity."""

 import enum
 from typing import Any, Optional
@@ -50,14 +50,14 @@ class Namespace(BaseEntityWithIdentifier):
     def validate_namespace_is_not_in_a_loop(  # noqa  # pylint: disable=unused-argument
         self, field: Any, value: Any
     ) -> None:
-        """Validate that the ``namespace`` field is not in a loop.
+        """Validate that the :obj:`Namespace.namespace` field is not in a loop.

         Being in a loop means that one of the descendants is the parent of one of the ascendants.

         Parameters
         ----------
         field : Any
-            The field to validate. Passed via the ``@field_validator`` decorator.
+            The field to validate.
         value : Any
             The value to validate for the `field`.

fix(entity): id changed from int to uuid4, renamed to identifier

Commit
Hash

79f704bde4575a9ddeb623d67d8965a62138adc9

Date

2020-10-05 10:51:49 +0200

Type

Modified

Stats

+3 -3

@@ -4,7 +4,7 @@ import enum
 from typing import Any, Optional

 from isshub.domain.utils.entity import (
-    BaseEntityWithId,
+    BaseEntityWithIdentifier,
     field_validator,
     optional_field,
     required_field,
@@ -21,12 +21,12 @@ class NamespaceKind(enum.Enum):


 @validated()
-class Namespace(BaseEntityWithId):
+class Namespace(BaseEntityWithIdentifier):
     """A namespace can contain namespaces and repositories.

     Attributes
     ----------
-    id : int
+    identifier : UUID
         The unique identifier of the namespace
     name : str
         The name of the namespace. Unique in its parent namespace.

style(entity): Change the world “model” by “entity”

Commit
Hash

c2dd0fc606636dd72c1b55d30095bbeb622b788d

Date

2020-10-04 21:07:00 +0200

Type

Modified

Stats

+2 -2

@@ -4,7 +4,7 @@ import enum
 from typing import Any, Optional

 from isshub.domain.utils.entity import (
-    BaseModelWithId,
+    BaseEntityWithId,
     field_validator,
     optional_field,
     required_field,
@@ -21,7 +21,7 @@ class NamespaceKind(enum.Enum):


 @validated()
-class Namespace(BaseModelWithId):
+class Namespace(BaseEntityWithId):
     """A namespace can contain namespaces and repositories.

     Attributes

style(mypy): Remove most “type: ignore” pragmas

Commit
Hash

76638c3d09c47d58febbc9e2e2cc80e84c98ac33

Date

2020-10-04 20:36:50 +0200

Type

Modified

Stats

+6 -8

@@ -20,7 +20,7 @@ class NamespaceKind(enum.Enum):
     GROUP = "Group"


-@validated()  # type: ignore
+@validated()
 class Namespace(BaseModelWithId):
     """A namespace can contain namespaces and repositories.

@@ -39,16 +39,14 @@ class Namespace(BaseModelWithId):

     """

-    name: str = required_field(str)  # type: ignore
-    kind: NamespaceKind = required_field(  # type: ignore
-        NamespaceKind, relation_verbose_name="is a"
-    )
-    namespace: Optional["Namespace"] = optional_field(  # type: ignore
+    name: str = required_field(str)
+    kind: NamespaceKind = required_field(NamespaceKind, relation_verbose_name="is a")
+    namespace: Optional["Namespace"] = optional_field(
         "self", relation_verbose_name="may belongs to"
     )
-    description: Optional[str] = optional_field(str)  # type: ignore
+    description: Optional[str] = optional_field(str)

-    @field_validator(namespace)  # type: ignore
+    @field_validator(namespace)
     def validate_namespace_is_not_in_a_loop(  # noqa  # pylint: disable=unused-argument
         self, field: Any, value: Any
     ) -> None:

docs(domain): Add diagram of entities for each domain context

Commit
Hash

bb5e73eb3d816d563f2a58fe65c6bd57b045dbde

Date

2020-10-04 11:50:37 +0200

Type

Modified

Stats

+7 -3

@@ -40,9 +40,13 @@ class Namespace(BaseModelWithId):
     """

     name: str = required_field(str)  # type: ignore
-    namespace: Optional["Namespace"] = optional_field("self")  # type: ignore
-    kind: NamespaceKind = required_field(NamespaceKind)  # type: ignore
-    description: str = optional_field(str)  # type: ignore
+    kind: NamespaceKind = required_field(  # type: ignore
+        NamespaceKind, relation_verbose_name="is a"
+    )
+    namespace: Optional["Namespace"] = optional_field(  # type: ignore
+        "self", relation_verbose_name="may belongs to"
+    )
+    description: Optional[str] = optional_field(str)  # type: ignore

     @field_validator(namespace)  # type: ignore
     def validate_namespace_is_not_in_a_loop(  # noqa  # pylint: disable=unused-argument

refactor(namespace): Remove the intermediary _Namespace model

Commit
Hash

27e4ea0aef91c7e16f966afdb6973f1b29ef6e9f

Date

2020-09-28 18:05:22 +0200

Type

Modified

Stats

+2 -29

@@ -21,14 +21,9 @@ class NamespaceKind(enum.Enum):


 @validated()  # type: ignore
-class _Namespace(BaseModelWithId):
+class Namespace(BaseModelWithId):
     """A namespace can contain namespaces and repositories.

-    Notes
-    -----
-    This is a base class, used by `Namespace` to be able to have a self-reference for the type
-    of the `namespace` field.
-
     Attributes
     ----------
     id : int
@@ -45,32 +40,10 @@ class _Namespace(BaseModelWithId):
     """

     name: str = required_field(str)  # type: ignore
-    namespace = None
+    namespace: Optional["Namespace"] = optional_field("self")  # type: ignore
     kind: NamespaceKind = required_field(NamespaceKind)  # type: ignore
     description: str = optional_field(str)  # type: ignore

-
-@validated()  # type: ignore
-class Namespace(_Namespace):
-    """A namespace can contain namespaces and repositories.
-
-    Attributes
-    ----------
-    id : int
-        The unique identifier of the namespace
-    name : str
-        The name of the namespace. Unique in its parent namespace.
-    namespace : Optional[Namespace]
-        Where the namespace can be found.
-    kind : NamespaceKind
-        The kind of namespace.
-    description : Optional[str]
-        The description of the namespace.
-
-    """
-
-    namespace: Optional[_Namespace] = optional_field(_Namespace)  # type: ignore
-
     @field_validator(namespace)  # type: ignore
     def validate_namespace_is_not_in_a_loop(  # noqa  # pylint: disable=unused-argument
         self, field: Any, value: Any

fix(namespace): Namespaces relationships should not create a loop

Commit
Hash

afeb5f86809b05cf3ef131a59de1ed9235d59a8d

Date

2020-09-26 22:38:26 +0200

Type

Modified

Stats

+33 -1

@@ -1,10 +1,11 @@
 """Package defining the ``Namespace`` entity."""

 import enum
-from typing import Optional
+from typing import Any, Optional

 from isshub.domain.utils.entity import (
     BaseModelWithId,
+    field_validator,
     optional_field,
     required_field,
     validated,
@@ -69,3 +70,34 @@ class Namespace(_Namespace):
     """

     namespace: Optional[_Namespace] = optional_field(_Namespace)  # type: ignore
+
+    @field_validator(namespace)  # type: ignore
+    def validate_namespace_is_not_in_a_loop(  # noqa  # pylint: disable=unused-argument
+        self, field: Any, value: Any
+    ) -> None:
+        """Validate that the ``namespace`` field is not in a loop.
+
+        Being in a loop means that one of the descendants is the parent of one of the ascendants.
+
+        Parameters
+        ----------
+        field : Any
+            The field to validate. Passed via the ``@field_validator`` decorator.
+        value : Any
+            The value to validate for the `field`.
+
+        Raises
+        ------
+        ValueError
+            If the given namespace (`value`) is in a loop
+
+        """
+        if not value:
+            return
+
+        parent = value
+        while parent := parent.namespace:
+            if parent == value:
+                raise ValueError(
+                    f"{self.__class__.__name__}.namespace cannot be in a loop"
+                )

chore: Fix breaking changes from updated dependencies

Commit
Hash

7c6dfe01ac4ffbaac21d5d3836d5fda9c8391cf7

Date

2020-09-25 22:54:00 +0200

Type

Modified

Stats

+3 -3

@@ -21,7 +21,7 @@ class NamespaceKind(enum.Enum):

 @validated()  # type: ignore
 class _Namespace(BaseModelWithId):
-    """A namespace can contain namespace and repositories.
+    """A namespace can contain namespaces and repositories.

     Notes
     -----
@@ -51,7 +51,7 @@ class _Namespace(BaseModelWithId):

 @validated()  # type: ignore
 class Namespace(_Namespace):
-    """A namespace can contain namespace and repositories.
+    """A namespace can contain namespaces and repositories.

     Attributes
     ----------
@@ -59,7 +59,7 @@ class Namespace(_Namespace):
         The unique identifier of the namespace
     name : str
         The name of the namespace. Unique in its parent namespace.
-    namespace : Optional[str]
+    namespace : Optional[Namespace]
         Where the namespace can be found.
     kind : NamespaceKind
         The kind of namespace.