Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/pip/_vendor/resolvelib/structs.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author | shellac |
---|---|
date | Mon, 22 Mar 2021 18:12:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4f3585e2f14b |
---|---|
1 from .compat import collections_abc | |
2 | |
3 | |
4 class DirectedGraph(object): | |
5 """A graph structure with directed edges.""" | |
6 | |
7 def __init__(self): | |
8 self._vertices = set() | |
9 self._forwards = {} # <key> -> Set[<key>] | |
10 self._backwards = {} # <key> -> Set[<key>] | |
11 | |
12 def __iter__(self): | |
13 return iter(self._vertices) | |
14 | |
15 def __len__(self): | |
16 return len(self._vertices) | |
17 | |
18 def __contains__(self, key): | |
19 return key in self._vertices | |
20 | |
21 def copy(self): | |
22 """Return a shallow copy of this graph.""" | |
23 other = DirectedGraph() | |
24 other._vertices = set(self._vertices) | |
25 other._forwards = {k: set(v) for k, v in self._forwards.items()} | |
26 other._backwards = {k: set(v) for k, v in self._backwards.items()} | |
27 return other | |
28 | |
29 def add(self, key): | |
30 """Add a new vertex to the graph.""" | |
31 if key in self._vertices: | |
32 raise ValueError("vertex exists") | |
33 self._vertices.add(key) | |
34 self._forwards[key] = set() | |
35 self._backwards[key] = set() | |
36 | |
37 def remove(self, key): | |
38 """Remove a vertex from the graph, disconnecting all edges from/to it.""" | |
39 self._vertices.remove(key) | |
40 for f in self._forwards.pop(key): | |
41 self._backwards[f].remove(key) | |
42 for t in self._backwards.pop(key): | |
43 self._forwards[t].remove(key) | |
44 | |
45 def connected(self, f, t): | |
46 return f in self._backwards[t] and t in self._forwards[f] | |
47 | |
48 def connect(self, f, t): | |
49 """Connect two existing vertices. | |
50 | |
51 Nothing happens if the vertices are already connected. | |
52 """ | |
53 if t not in self._vertices: | |
54 raise KeyError(t) | |
55 self._forwards[f].add(t) | |
56 self._backwards[t].add(f) | |
57 | |
58 def iter_edges(self): | |
59 for f, children in self._forwards.items(): | |
60 for t in children: | |
61 yield f, t | |
62 | |
63 def iter_children(self, key): | |
64 return iter(self._forwards[key]) | |
65 | |
66 def iter_parents(self, key): | |
67 return iter(self._backwards[key]) | |
68 | |
69 | |
70 class _FactoryIterableView(object): | |
71 """Wrap an iterator factory returned by `find_matches()`. | |
72 | |
73 Calling `iter()` on this class would invoke the underlying iterator | |
74 factory, making it a "collection with ordering" that can be iterated | |
75 through multiple times, but lacks random access methods presented in | |
76 built-in Python sequence types. | |
77 """ | |
78 | |
79 def __init__(self, factory): | |
80 self._factory = factory | |
81 | |
82 def __repr__(self): | |
83 return "{}({})".format(type(self).__name__, list(self._factory())) | |
84 | |
85 def __bool__(self): | |
86 try: | |
87 next(self._factory()) | |
88 except StopIteration: | |
89 return False | |
90 return True | |
91 | |
92 __nonzero__ = __bool__ # XXX: Python 2. | |
93 | |
94 def __iter__(self): | |
95 return self._factory() | |
96 | |
97 def for_preference(self): | |
98 """Provide an candidate iterable for `get_preference()`""" | |
99 return self._factory() | |
100 | |
101 def excluding(self, candidates): | |
102 """Create a new instance excluding specified candidates.""" | |
103 | |
104 def factory(): | |
105 return (c for c in self._factory() if c not in candidates) | |
106 | |
107 return type(self)(factory) | |
108 | |
109 | |
110 class _SequenceIterableView(object): | |
111 """Wrap an iterable returned by find_matches(). | |
112 | |
113 This is essentially just a proxy to the underlying sequence that provides | |
114 the same interface as `_FactoryIterableView`. | |
115 """ | |
116 | |
117 def __init__(self, sequence): | |
118 self._sequence = sequence | |
119 | |
120 def __repr__(self): | |
121 return "{}({})".format(type(self).__name__, self._sequence) | |
122 | |
123 def __bool__(self): | |
124 return bool(self._sequence) | |
125 | |
126 __nonzero__ = __bool__ # XXX: Python 2. | |
127 | |
128 def __iter__(self): | |
129 return iter(self._sequence) | |
130 | |
131 def __len__(self): | |
132 return len(self._sequence) | |
133 | |
134 def for_preference(self): | |
135 """Provide an candidate iterable for `get_preference()`""" | |
136 return self._sequence | |
137 | |
138 def excluding(self, candidates): | |
139 """Create a new instance excluding specified candidates.""" | |
140 return type(self)([c for c in self._sequence if c not in candidates]) | |
141 | |
142 | |
143 def build_iter_view(matches): | |
144 """Build an iterable view from the value returned by `find_matches()`.""" | |
145 if callable(matches): | |
146 return _FactoryIterableView(matches) | |
147 if not isinstance(matches, collections_abc.Sequence): | |
148 matches = list(matches) | |
149 return _SequenceIterableView(matches) |