Skip to content

Evaluation Structures

evaluable_architecture

Abstract interface of evaluable objects.

EvaluableArchitecture

Bases: Protocol

modules: list[str] property

Return names of all modules that are present in this architecture.

any_dependencies_from_dependents_to_modules_other_than_dependent_upons(dependents, dependent_upons)

Returns list of depending modules per dependent module if the dependent module has any dependency to a module other than the dependent_upon modules or any of their submodules.

If a dependent module is defined via a parent module, this parent module is not taken into account. If a dependent upon module is defined via a parent module, this parent module counts as an 'other' dependency. Reason behind this: If we want to know whether there are any dependencies from X to any non-Y modules, Y's parent is such a module, as this parent module can and usually will also contain other modules than Y.

Parameters:

Name Type Description Default
dependent

Module

required
dependent_upon

Module

required

Returns:

Type Description
NotExplicitlyRequestedDependenciesByBaseModule

All modules other than dependent_upon on which dependent module as any dependency per dependent module

any_other_dependencies_on_dependent_upons_than_from_dependents(dependents, dependent_upons)

Returns list of depending modules per dependent_upon module if any module other than the dependent module and its submodules has any dependency to the dependent_upon module. If the dependent module is defined via a parent module, this parent module is taken into account. This means that if the dependent module's parent module has a dependency to the dependent upon module, this will be contained in the returned list. If the dependent upon module is defined via a parent module, this parent module is not taken into account.

Parameters:

Name Type Description Default
dependent

Module

required
dependent_upon

Module

required

Returns:

Type Description
NotExplicitlyRequestedDependenciesByBaseModule

All modules other than dependent that have any dependency on the dependent upon module per dependent_upon module

get_dependencies(dependents, dependent_upons)

Returns tuple of importer and importee per dependent and depending module if the dependent module is indeed depending on the dependent_upon module. In short: find all dependencies between dependent and dependent_upons.

Submodules of dependent and dependent upon are taken into account. If X.A depends on Y, then X also depends on Y, as X.A is part of X. If X depends on Y.Z, then it also depends on Y.

If one or both of the modules are defined by their parent module, this parent module is excluded from possible matches.

Parameters:

Name Type Description Default
dependent

Module(s)

required
dependent_upon

Module(s)

required

Returns:

Type Description
ExplicitlyRequestedDependenciesByBaseModules

Importer and importee per pair of dependent and dependent_upon module if there are any

ExplicitlyRequestedDependenciesByBaseModules

that are sub modules of dependent and dependent_upon respectively.

visualize(**kwargs)

Uses matplotlib to draw the underlying dependency structure.

Parameters:

Name Type Description Default
**kwargs Any

Any formatting options available for networkx' drawing function, as this is currently the only available backend. Exception: If 'spacing' is set, this will be interpreted as the parameter 'k' of the spring layout (https://networkx.org/documentation/stable/reference/generated/networkx.drawing.layout.spring_layout.html#networkx.drawing.layout.spring_layout).

{}

LayerMapping

get_layer_for_module_name(module_name)

Attempts to find the layer the given module belongs to. If the module does not appear in the layer definition itself, it is checked whether the module is a submodule of one of the modules in the layer definition. If so, the layer of the parent module is returned. Otherwise, None is returned. This assumes that if a module is in layer X, all of its submodules are as well.

Module dataclass

Represents an actual python module found in the dependency graph.

ModuleFilter

Bases: ABC

Represents a way to identify a python module in the dependency graph.

ModuleGroup dataclass

Bases: Module

Represents a group of actual python module found in the dependency graph. This is only needed if a group of modules is specified via their parent module's name, and only for not explicitly requested dependencies. For these, the original module filter is not converted to actual modules, as this would clutter the return type and the user output. Instead, this filter will be converted to a module group.

The name is the name of the parent module of all modules in this group.

ModuleNameFilter dataclass

Bases: ModuleFilter

Represents a way to identify a python module in the dependency graph by its name.

ModuleNameRegexFilter dataclass

Bases: ModuleFilter

Represents a way to identify a python module in the dependency graph. The module is identified by a regex pattern for its name.

ParentModuleNameFilter dataclass

Bases: ModuleFilter

Represents a way to identify a python module in the dependency graph by the name of its parent module.

evaluable_graph

Base class for different graph implementations of an evaluable structure. Delegates direct access to graph nodes and edges to its subclasses in a template pattern.

EvaluableArchitectureGraph

Bases: EvaluableArchitecture

Abstract implementation of an evaluable object that is based on a graph structure.

module_name_converter

ModuleNameConverter

Converts module names specified via regex pattern to module names based on which modules in the architecture match the regex pattern.

convert(modules, arch) classmethod

Converts each regex pattern that serves to identify module names into actual modules that match this pattern.

Parameters:

Name Type Description Default
- modules

list of modules, some of which may need converting since their names are regex patterns

required
- arch

architecture that contains actual modules

required

Returns:

Type Description
Sequence[ModuleFilter]
  • list of module filters, now without any regex patterns. Will be used for later dependency graph queries.
dict[str, list[Module]]
  • mapping between a regex pattern and the actual modules it was replaced by

networkxgraph

Encapsulation of networkx graph functionality.

NetworkxGraph

Bases: AbstractGraph

Constructs eval_structure from list of imports.

Each module passed to this object will be added as a node. Importing and imported module are connected via a direct edge. Edges are added between each successive level in the module hierarchy.

E.g. Import('A.B', 'C.D.E') results in - nodes: ['A', 'A.B', 'C', 'C.D', 'C.D.E'] - edges: [('A', 'A.B'), ('C', 'C.D'), ('C.D', 'C.D.E'), ('A.B', 'C.D.E')]

__init__(all_modules, imports, level_limit=None)

Parameters:

Name Type Description Default
all_modules list[Node]

list of all nodes in the graph, which can be connected by imports.

required
imports Sequence[Import]

all dependencies between the graph's nodes.

required
level_limit int | None

if not None, specifies the depth of the graph

None

direct_predecessor_nodes(node)

Returns all nodes that have a directed edge towards the given node.

Parameters:

Name Type Description Default
node Node

node for which to retrieve predecessor nodes

required

Returns:

Type Description
list[Node]

all predecessor nodes

direct_successor_nodes(node)

Returns all nodes that the given node has a directed edge towards.

Parameters:

Name Type Description Default
node Node

node for which to retrieve successor nodes

required

Returns:

Type Description
list[Node]

all successor nodes

draw(**kwargs)

Creates a matplotlib plot representing the graph.

Other Parameters:

Name Type Description
spacing float

optimal distance between nodes

aliases Dict[str, str]

module name aliases for plot labels. Keys are module names and values the aliases. If no alias is specified the module name is used a node label. If a module name has an alias, the module name is replaced by the alias for the module and all its submodules, e.g. for modules a, a.b, a.c, a.c.d and aliases == {'a', 'A'}, the plot labels for these modules will be A, A.b, A.c, A.c.d. If a submodule also has an alias, the alias for the submodule takes priority, e.g. with the same modules as above and aliases == {'a': 'A', 'a.c': 'C'} the plot labels will be A, A.b, C, C.d.

parent_child_relationship(supposed_parent_node, supposed_child_node)

Returns True if the given nodes are marked as a parent-child hierarchy.

Parameters:

Name Type Description Default
supposed_parent_node Node
required
supposed_child_node Node
required

Returns:

Type Description
bool

True if supposed parent is actually parent of supposed child node

types

Import

Bases: ABC

importee() abstractmethod

Returns name of a module that is being imported.

Returns:

Type Description
str

module name

importee_parent_modules() abstractmethod

Returns names of all parent modules of the imported module.

Returns:

Type Description
list[str]

list of module names

importer()

Returns name of the module that imports something.

Returns:

Type Description
str

module name

importer_parent_modules()

Returns names of all parent modules of the importing module.

Returns:

Type Description
list[str]

list of module names

get_parent_modules(module)

Calculates all parent modules of a given module.

Example: source root is a module: a.b.c returned: [a, a.b]

Parameters:

Name Type Description Default
module str

module to calculate parent modules for

required

Returns:

Type Description
list[str]

List of all parent modules, containing their full names up to the source code root.