def __init__(
self,
edges: dict[str, set[str]],
deferred_edges: dict[str, set[str]] | None = None,
) -> None:
for label in edges:
if not label:
message = 'edges must not contain empty labels'
raise InvalidParameterError(message)
self._edges = {
label: set(dependencies)
for label, dependencies in edges.items()
}
all_labels = set(self._edges)
for label, dependencies in self._edges.items():
unknown = dependencies - all_labels
if unknown:
message = (
f'Model {label!r} declares dependencies on '
f'unknown models: {unknown}'
)
raise UnknownDependencyError(message)
self._deferred_edges: dict[str, set[str]] = {}
if deferred_edges:
for label, targets in deferred_edges.items():
if not targets:
continue
if label not in all_labels:
message = (
f'Deferred edge source {label!r} '
f'is not a known model'
)
raise InvalidParameterError(message)
unknown = targets - all_labels
if unknown:
message = (
f'Deferred edges from {label!r} reference '
f'unknown models: {unknown}'
)
raise UnknownDependencyError(message)
self._deferred_edges[label] = set(targets)
self._dependents: dict[str, set[str]] = {
label: set() for label in self._edges
}
for label, dependencies in self._edges.items():
for dependency in dependencies:
self._dependents[dependency].add(label)
self._order = self._compute_order()