Skip to content
This repository was archived by the owner on Jan 21, 2023. It is now read-only.

Commit 575fc94

Browse files
yt-msMidnighter
authored andcommitted
refactor: mark child_elements abstract in Element, so subtypes have to be expicit
1 parent c57d2ce commit 575fc94

File tree

7 files changed

+44
-11
lines changed

7 files changed

+44
-11
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright (c) 2020
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
"""Provide a mixin that indicates an element type does not have children."""
17+
18+
19+
from typing import Iterable
20+
21+
from ..model.element import Element
22+
23+
24+
class ChildlessMixin:
25+
"""Define a mixin for childless element types."""
26+
27+
@property
28+
def child_elements(self) -> Iterable[Element]:
29+
"""Return child elements (from `Element.children`)."""
30+
return []

src/structurizr/model/component.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
from pydantic import Field
2222

23+
from ..mixin.childless_mixin import ChildlessMixin
2324
from .code_element import CodeElement, CodeElementIO
2425
from .static_structure_element import StaticStructureElement, StaticStructureElementIO
2526
from .tags import Tags
@@ -58,7 +59,7 @@ class ComponentIO(StaticStructureElementIO):
5859
size: Optional[int] = None
5960

6061

61-
class Component(StaticStructureElement):
62+
class Component(ChildlessMixin, StaticStructureElement):
6263
"""
6364
Represent a component.
6465

src/structurizr/model/element.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"""Provide a superclass for all model elements."""
1717

1818

19-
from abc import ABC
19+
from abc import ABC, abstractmethod
2020
from typing import Iterable, Iterator, List, Optional
2121

2222
from pydantic import Field, HttpUrl
@@ -83,12 +83,10 @@ def __repr__(self):
8383
return f"{type(self).__name__}(id={self.id}, name={self.name})"
8484

8585
@property
86+
@abstractmethod
8687
def child_elements(self) -> Iterable["Element"]:
87-
"""Return the elements that are children of this one.
88-
89-
Subclasses should override this to provide their specific children.
90-
"""
91-
return []
88+
"""Return the elements that are children of this one."""
89+
... # pragma: no cover
9290

9391
def get_relationships(self) -> Iterator[Relationship]:
9492
"""Return a Iterator over all relationships involving this element."""

src/structurizr/model/infrastructure_node.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
from typing import TYPE_CHECKING, Optional
1717

18+
from ..mixin.childless_mixin import ChildlessMixin
1819
from .deployment_element import DeploymentElement, DeploymentElementIO
1920
from .tags import Tags
2021

@@ -40,7 +41,7 @@ class InfrastructureNodeIO(DeploymentElementIO):
4041
technology: Optional[str] = ""
4142

4243

43-
class InfrastructureNode(DeploymentElement):
44+
class InfrastructureNode(ChildlessMixin, DeploymentElement):
4445
"""
4546
Represent an infrastructure node.
4647

src/structurizr/model/person.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
from pydantic import Field
2222

23+
from ..mixin.childless_mixin import ChildlessMixin
2324
from .location import Location
2425
from .relationship import Relationship
2526
from .static_structure_element import StaticStructureElement, StaticStructureElementIO
@@ -43,7 +44,7 @@ class PersonIO(StaticStructureElementIO):
4344
)
4445

4546

46-
class Person(StaticStructureElement):
47+
class Person(ChildlessMixin, StaticStructureElement):
4748
"""
4849
Represent a person in the C4 model.
4950

src/structurizr/model/static_structure_element_instance.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
from pydantic import Field
2323

24+
from ..mixin.childless_mixin import ChildlessMixin
2425
from .deployment_element import DeploymentElement, DeploymentElementIO
2526
from .http_health_check import HTTPHealthCheck, HTTPHealthCheckIO
2627
from .static_structure_element import StaticStructureElement
@@ -41,7 +42,7 @@ class StaticStructureElementInstanceIO(DeploymentElementIO, ABC):
4142
health_checks: List[HTTPHealthCheckIO] = Field(default=(), alias="healthChecks")
4243

4344

44-
class StaticStructureElementInstance(DeploymentElement, ABC):
45+
class StaticStructureElementInstance(ChildlessMixin, DeploymentElement, ABC):
4546
"""Define a superclass for all deployment instances."""
4647

4748
def __init__(

tests/unit/model/test_element.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@
1818

1919
import pytest
2020

21+
from structurizr.mixin.childless_mixin import ChildlessMixin
2122
from structurizr.model.element import Element
2223

2324

24-
class ConcreteElement(Element):
25+
class ConcreteElement(ChildlessMixin, Element):
2526
"""Implement a concrete `Element` class for testing purposes."""
2627

2728
pass

0 commit comments

Comments
 (0)