Skip to content

Commit

Permalink
Adapt python find_illegal_dependencies_for_layers
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter554 committed Nov 28, 2023
1 parent 8554474 commit c6d120f
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 6 deletions.
18 changes: 15 additions & 3 deletions src/grimp/adaptors/_layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@

if TYPE_CHECKING:
from grimp.adaptors.graph import ImportGraph
from grimp.application.ports.graph import Level

from grimp.domain.analysis import PackageDependency
from grimp.exceptions import NoSuchContainer


def find_illegal_dependencies(
graph: ImportGraph,
layers: Sequence[Union[str, set[str]]],
layers: Sequence[Union[str, set[str], Level]],
containers: set[str],
) -> set[PackageDependency]:
"""
Expand Down Expand Up @@ -52,11 +53,22 @@ class _RustPackageDependency(TypedDict):
routes: tuple[_RustRoute, ...]


def _layers_to_levels(layers: Sequence[Union[str, set[str]]]) -> tuple[set[str], ...]:
def _layers_to_levels(layers: Sequence[Union[str, set[str], Level]]) -> tuple[Level, ...]:
"""
Convert any standalone layers to a one-element level.
"""
return tuple({layer} if isinstance(layer, str) else set(layer) for layer in layers)
out_layers = []
for layer in layers:
if isinstance(layer, dict):
out_layers.append(dict(
independent=layer["independent"],
layers=set(layer["layers"]),
))
if isinstance(layer, str):
out_layers.append(dict(independent=True, layers={layer}))
else:
out_layers.append(dict(independent=True, layers=set(layer)))
return tuple(out_layers)


def _dependencies_from_tuple(
Expand Down
2 changes: 1 addition & 1 deletion src/grimp/adaptors/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ def chain_exists(self, importer: str, imported: str, as_packages: bool = False)

def find_illegal_dependencies_for_layers(
self,
layers: Sequence[str | set[str]],
layers: Sequence[str | set[str] | graph.Level],
containers: Optional[set[str]] = None,
) -> set[PackageDependency]:
return _layers.find_illegal_dependencies(
Expand Down
7 changes: 6 additions & 1 deletion src/grimp/application/ports/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ class DetailedImport(TypedDict):
line_contents: str


class Level(TypedDict):
independent: bool
layers: set[str]


class ImportGraph(abc.ABC):
"""
A Directed Graph of imports between Python modules.
Expand Down Expand Up @@ -271,7 +276,7 @@ def chain_exists(self, importer: str, imported: str, as_packages: bool = False)

def find_illegal_dependencies_for_layers(
self,
layers: Sequence[Union[str, set[str]]],
layers: Sequence[Union[str, set[str], Level]],
containers: Optional[set[str]] = None,
) -> set[PackageDependency]:
"""
Expand Down
22 changes: 21 additions & 1 deletion tests/unit/adaptors/graph/test_layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,6 @@ def _analyze(
layers=("mypackage.high", "mypackage.medium", "mypackage.low"),
)


class TestIndependentLayers:
@pytest.mark.parametrize("specify_container", (True, False))
def test_no_illegal_imports(self, specify_container: bool):
Expand All @@ -401,6 +400,9 @@ def test_no_illegal_imports(self, specify_container: bool):
frozenset,
tuple,
list,
lambda layers: dict(independent=True, layers=set(layers)),
lambda layers: dict(independent=True, layers=tuple(layers)),
lambda layers: dict(independent=True, layers=list(layers)),
),
)
@pytest.mark.parametrize(
Expand Down Expand Up @@ -435,6 +437,24 @@ def test_direct_illegal_between_sibling_layers(
),
}

def test_imports_between_sibling_layers_illegal_if_and_only_if_level_is_independent(self):
graph = self._build_legal_graph()
graph.add_import(importer="mypackage.foo", imported="mypackage.bar")

# Layer is independent => import is forbidden.
results = graph.find_illegal_dependencies_for_layers(
layers=("high", dict(independent=True, layers={"foo", "bar"}), "low"),
containers={"mypackage"},
)
assert results

# Layer is not independent => import is allowed.
results = graph.find_illegal_dependencies_for_layers(
layers=("high", dict(independent=False, layers={"foo", "bar"}), "low"),
containers={"mypackage"},
)
assert not results

@pytest.mark.parametrize("specify_container", (True, False))
@pytest.mark.parametrize(
"start",
Expand Down

0 comments on commit c6d120f

Please sign in to comment.