Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This project uses semantic versioning and follows [keep a changelog](https://kee
### Fixed
- Straightforward error message when using wildcards in `are_named` rules.
- Typo in docstring of `get_evaluable_architecture(..)`.
- Module filter uses regex when activated instead of only if last module.

## 4.0.1 -- 2025-08-08
### Fixed
Expand Down
24 changes: 14 additions & 10 deletions src/pytestarch/eval_structure/breadth_first_searches.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from pytestarch.eval_structure.evaluable_architecture import Dependency, ModuleFilter
from pytestarch.eval_structure.evaluable_structures import AbstractGraph, AbstractNode
from pytestarch.eval_structure.utils import get_node, get_parent_nodes, to_modules
from pytestarch.eval_structure.utils import get_node, get_parent_nodes, to_module


def get_dependency_between_modules(
Expand All @@ -16,7 +16,7 @@ def get_dependency_between_modules(
nodes_to_check = [dependent_node]
checked_nodes = set()

dependencies = []
dependencies: list[Dependency] = []

while nodes_to_check:
node = nodes_to_check.pop()
Expand All @@ -37,8 +37,8 @@ def get_dependency_between_modules(
and node not in nodes_to_exclude
and child not in nodes_to_exclude
):
dependencies.append(tuple(to_modules([node, child])))
return dependencies # type: ignore
dependencies.append((to_module(node), to_module(child)))
return dependencies


def any_dependency_to_module_other_than(
Expand All @@ -51,7 +51,7 @@ def any_dependency_to_module_other_than(
continue
nodes_to_exclude.update(get_all_submodules_of(graph, dependent_upon))

nodes_fulfilling_criteria = []
nodes_fulfilling_criteria: list[Dependency] = []

# nodes that count as not fulfilling the criterion are nodes that would technically fulfill the criterion,
# but have to be excluded for consistency reasons. For example, if the dependent is called A and has two
Expand Down Expand Up @@ -102,11 +102,13 @@ def any_dependency_to_module_other_than(
child not in nodes_to_exclude
and child not in nodes_that_do_not_fulfill_criterion
):
nodes_fulfilling_criteria.append(tuple(to_modules([node, child])))
nodes_fulfilling_criteria.append(
(to_module(node), to_module(child))
)
else:
nodes_to_check.append(child)

return nodes_fulfilling_criteria # type: ignore
return nodes_fulfilling_criteria


def any_other_dependency_to_module_than(
Expand All @@ -122,7 +124,7 @@ def any_other_dependency_to_module_than(
continue
nodes_to_exclude.update(get_all_submodules_of(graph, dependent))

nodes_fulfilling_criteria = []
nodes_fulfilling_criteria: list[Dependency] = []

# nodes that count as not fulfilling the criterion are nodes that would technically fulfill the criterion,
# but have to be excluded for consistency reasons. For example, if the dependent upon is called A and has two
Expand Down Expand Up @@ -171,12 +173,14 @@ def any_other_dependency_to_module_than(
parent not in nodes_to_exclude
and parent not in nodes_that_count_as_not_fulfilling_criterion
):
nodes_fulfilling_criteria.append(tuple(to_modules([parent, node])))
nodes_fulfilling_criteria.append(
(to_module(parent), to_module(node))
)

if parent not in nodes_to_exclude:
nodes_to_check.append(parent)

return nodes_fulfilling_criteria # type: ignore
return nodes_fulfilling_criteria


def get_all_submodules_of(
Expand Down
6 changes: 5 additions & 1 deletion src/pytestarch/eval_structure/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@
from pytestarch.eval_structure.evaluable_structures import AbstractNode


def to_module(node: AbstractNode) -> Module:
return Module(identifier=node)


def to_modules(nodes: list[AbstractNode]) -> list[Module]:
return list(map(lambda node: Module(identifier=node), nodes))
return list(map(to_module, nodes))


def filter_to_module(filter: ModuleFilter) -> Module:
Expand Down
10 changes: 2 additions & 8 deletions src/pytestarch/query_language/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,7 @@ def _add_modules(
for module, name_is_regex in modules:
module_names.append(module)
module_creation_fn.append(
lambda name: (
ModuleNameFilter(name=name)
if not name_is_regex
else ModuleNameRegexFilter(name=name)
)
ModuleNameRegexFilter if name_is_regex else ModuleNameFilter
)

self._append_modules(module_names, module_creation_fn)
Expand Down Expand Up @@ -299,9 +295,7 @@ def _assert_required_configuration_present(self) -> None:
object_message,
]

error_message = (
f"Specify {', '.join(filter(lambda m: len(m) > 0, messages))}."
)
error_message = f"Specify {', '.join(filter(None, messages))}."

raise ImproperlyConfigured(error_message)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,6 @@ def _get_violating_rule_subjects_and_objects(

return rule_objects_for_rule_subject, violating_rule_subjects

def _convert_to_names(
self, violating_dependencies: list[Dependency]
) -> list[tuple[str, str]]:
return [
(dependency[0].identifier, dependency[1].identifier)
for dependency in violating_dependencies
]

def _create_should_only_import_violated_messages(
self, rule_violations: RuleViolations
) -> list[RuleViolatedMessage]:
Expand Down