Completed
Pull Request — master (#2609)
by Udayan
02:12
created

Dependencies._resolve()   B

Complexity

Conditions 5

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
c 1
b 0
f 0
dl 0
loc 21
rs 8.439
1
class CircularDependencyError(Exception):
2
3
    def __init__(self, bears):
4
        """
5
        Creates the CircularDependencyError with a helpful message about the
6
        dependency.
7
        """
8
        bear_names = (bear.name for bear in bears)
9
        super(CircularDependencyError, self).__init__(
10
            "Circular dependency detected: " + " -> ".join(bear_names))
11
12
13
class Dependencies:
14
15
    @classmethod
16
    def _resolve(cls, bears, resolved_bears, seen):
17
        for bear in bears:
18
            if bear in resolved_bears:
19
                continue
20
21
            missing = bear.missing_dependencies(resolved_bears)
22
            if not missing:
23
                resolved_bears.append(bear)
24
                continue
25
26
            if bear in seen:
27
                seen.append(bear)
28
                raise CircularDependencyError(seen)
29
30
            seen.append(bear)
31
            resolved_bears = cls._resolve(missing, resolved_bears, seen)
32
            resolved_bears.append(bear)
33
            seen.remove(bear)  # Already resolved, no candidate for circular dep
34
35
        return resolved_bears
36
37
    @classmethod
38
    def check_circular_dependency(cls, bears):
39
        """
40
        Collects all dependencies of the given bears. This will also remove
41
        duplicates.
42
43
        :param bears: The given bears. Will not be modified.
44
        :return:      The new list of bears, sorted so that it can be executed
45
                      sequentially without dependency issues.
46
        """
47
        return cls._resolve(bears, [], [])
48