1 |
--- |
2 |
pym/_emerge/depgraph.py | 59 ++++++++++++---------------------- |
3 |
pym/_emerge/resolver/slot_collision.py | 22 ++++++------- |
4 |
2 files changed, 31 insertions(+), 50 deletions(-) |
5 |
|
6 |
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py |
7 |
index 9d234c2..484ac14 100644 |
8 |
--- a/pym/_emerge/depgraph.py |
9 |
+++ b/pym/_emerge/depgraph.py |
10 |
@@ -378,11 +378,6 @@ class _dynamic_depgraph_config(object): |
11 |
# This use used to check if we have accounted for blockers |
12 |
# relevant to a package. |
13 |
self._traversed_pkg_deps = set() |
14 |
- # This should be ordered such that the backtracker will |
15 |
- # attempt to solve conflicts which occurred earlier first, |
16 |
- # since an earlier conflict can be the cause of a conflict |
17 |
- # which occurs later. |
18 |
- self._slot_collision_info = OrderedDict() |
19 |
# Slot collision nodes are not allowed to block other packages since |
20 |
# blocker validation is only able to account for one package per slot. |
21 |
self._slot_collision_nodes = set() |
22 |
@@ -915,7 +910,7 @@ class depgraph(object): |
23 |
cases. |
24 |
""" |
25 |
|
26 |
- if not self._dynamic_config._slot_collision_info: |
27 |
+ if not any(self._dynamic_config._package_tracker.slot_conflicts()): |
28 |
return |
29 |
|
30 |
self._show_merge_list() |
31 |
@@ -971,16 +966,18 @@ class depgraph(object): |
32 |
is called, so that all relevant reverse dependencies are |
33 |
available for use in backtracking decisions. |
34 |
""" |
35 |
- for (slot_atom, root), slot_nodes in \ |
36 |
- self._dynamic_config._slot_collision_info.items(): |
37 |
- self._process_slot_conflict(root, slot_atom, slot_nodes) |
38 |
+ for conflict in self._dynamic_config._package_tracker.slot_conflicts(): |
39 |
+ self._process_slot_conflict(conflict) |
40 |
|
41 |
- def _process_slot_conflict(self, root, slot_atom, slot_nodes): |
42 |
+ def _process_slot_conflict(self, conflict): |
43 |
""" |
44 |
Process slot conflict data to identify specific atoms which |
45 |
lead to conflict. These atoms only match a subset of the |
46 |
packages that have been pulled into a given slot. |
47 |
""" |
48 |
+ root = conflict.root |
49 |
+ slot_atom = conflict.atom |
50 |
+ slot_nodes = conflict.pkgs |
51 |
|
52 |
debug = "--debug" in self._frozen_config.myopts |
53 |
|
54 |
@@ -1999,7 +1996,6 @@ class depgraph(object): |
55 |
|
56 |
existing_node, existing_node_matches = \ |
57 |
self._check_slot_conflict(pkg, dep.atom) |
58 |
- slot_collision = False |
59 |
if existing_node: |
60 |
if existing_node_matches: |
61 |
# The existing node can be reused. |
62 |
@@ -2032,19 +2028,7 @@ class depgraph(object): |
63 |
modified_use=self._pkg_use_enabled(existing_node))), |
64 |
level=logging.DEBUG, noiselevel=-1) |
65 |
|
66 |
- slot_collision = True |
67 |
- |
68 |
- if slot_collision: |
69 |
- # Now add this node to the graph so that self.display() |
70 |
- # can show use flags and --tree portage.output. This node is |
71 |
- # only being partially added to the graph. It must not be |
72 |
- # allowed to interfere with the other nodes that have been |
73 |
- # added. |
74 |
- # Even though the graph is now invalid, continue to process |
75 |
- # dependencies so that things like --fetchonly can still |
76 |
- # function despite collisions. |
77 |
- pass |
78 |
- elif not previously_added: |
79 |
+ if not previously_added: |
80 |
self._dynamic_config._package_tracker.add_pkg(pkg) |
81 |
self._dynamic_config._filtered_trees[pkg.root]["porttree"].dbapi._clear_cache() |
82 |
self._dynamic_config._highest_pkg_cache.clear() |
83 |
@@ -2156,14 +2140,6 @@ class depgraph(object): |
84 |
|
85 |
def _add_slot_conflict(self, pkg): |
86 |
self._dynamic_config._slot_collision_nodes.add(pkg) |
87 |
- slot_key = (pkg.slot_atom, pkg.root) |
88 |
- slot_nodes = self._dynamic_config._slot_collision_info.get(slot_key) |
89 |
- if slot_nodes is None: |
90 |
- slot_nodes = set() |
91 |
- slot_nodes.update(self._dynamic_config._package_tracker.match( |
92 |
- pkg.root, pkg.slot_atom, installed=False)) |
93 |
- self._dynamic_config._slot_collision_info[slot_key] = slot_nodes |
94 |
- slot_nodes.add(pkg) |
95 |
|
96 |
def _add_pkg_deps(self, pkg, allow_unsatisfied=False): |
97 |
|
98 |
@@ -3284,7 +3260,8 @@ class depgraph(object): |
99 |
except self._unknown_internal_error: |
100 |
return False, myfavorites |
101 |
|
102 |
- if (self._dynamic_config._slot_collision_info and |
103 |
+ have_slot_conflict = any(self._dynamic_config._package_tracker.slot_conflicts()) |
104 |
+ if (have_slot_conflict and |
105 |
not self._accept_blocker_conflicts()) or \ |
106 |
(self._dynamic_config._allow_backtracking and |
107 |
"slot conflict" in self._dynamic_config._backtrack_infos): |
108 |
@@ -6806,7 +6783,8 @@ class depgraph(object): |
109 |
# conflicts (or by blind luck). |
110 |
raise self._unknown_internal_error() |
111 |
|
112 |
- if self._dynamic_config._slot_collision_info and \ |
113 |
+ have_slot_conflict = any(self._dynamic_config._package_tracker.slot_conflicts()) |
114 |
+ if have_slot_conflict and \ |
115 |
not self._accept_blocker_conflicts(): |
116 |
self._dynamic_config._serialized_tasks_cache = retlist |
117 |
self._dynamic_config._scheduler_graph = scheduler_graph |
118 |
@@ -6881,13 +6859,17 @@ class depgraph(object): |
119 |
# the reasons are not apparent from the normal merge list |
120 |
# display. |
121 |
|
122 |
- slot_collision_info = self._dynamic_config._slot_collision_info |
123 |
- |
124 |
conflict_pkgs = {} |
125 |
for blocker in blockers: |
126 |
for pkg in chain(self._dynamic_config._blocked_pkgs.child_nodes(blocker), \ |
127 |
self._dynamic_config._blocker_parents.parent_nodes(blocker)): |
128 |
- if (pkg.slot_atom, pkg.root) in slot_collision_info: |
129 |
+ |
130 |
+ is_slot_conflict_pkg = False |
131 |
+ for conflict in self._dynamic_config._package_tracker.slot_conflicts(): |
132 |
+ if conflict.root == pkg.root and conflict.atom == pkg.slot_atom: |
133 |
+ is_slot_conflict_pkg = True |
134 |
+ break |
135 |
+ if is_slot_conflict_pkg: |
136 |
# The slot conflict display has better noise reduction |
137 |
# than the unsatisfied blockers display, so skip |
138 |
# unsatisfied blockers display for packages involved |
139 |
@@ -7370,7 +7352,8 @@ class depgraph(object): |
140 |
self._dynamic_config._circular_deps_for_display) |
141 |
|
142 |
unresolved_conflicts = False |
143 |
- if self._dynamic_config._slot_collision_info: |
144 |
+ have_slot_conflict = any(self._dynamic_config._package_tracker.slot_conflicts()) |
145 |
+ if have_slot_conflict: |
146 |
unresolved_conflicts = True |
147 |
self._show_slot_collision_notice() |
148 |
if self._dynamic_config._unsatisfied_blockers_for_display is not None: |
149 |
diff --git a/pym/_emerge/resolver/slot_collision.py b/pym/_emerge/resolver/slot_collision.py |
150 |
index a193baa..ca3fb74 100644 |
151 |
--- a/pym/_emerge/resolver/slot_collision.py |
152 |
+++ b/pym/_emerge/resolver/slot_collision.py |
153 |
@@ -89,10 +89,11 @@ class slot_conflict_handler(object): |
154 |
self.debug = "--debug" in self.myopts |
155 |
if self.debug: |
156 |
writemsg("Starting slot conflict handler\n", noiselevel=-1) |
157 |
- #slot_collision_info is a dict mapping (slot atom, root) to set |
158 |
- #of packages. The packages in the set all belong to the same |
159 |
- #slot. |
160 |
- self.slot_collision_info = depgraph._dynamic_config._slot_collision_info |
161 |
+ |
162 |
+ # List of tuples, where each tuple represents a slot conflict. |
163 |
+ self.all_conflicts = [] |
164 |
+ for conflict in depgraph._dynamic_config._package_tracker.slot_conflicts(): |
165 |
+ self.all_conflicts.append((conflict.root, conflict.atom, conflict.pkgs)) |
166 |
|
167 |
#A dict mapping packages to pairs of parent package |
168 |
#and parent atom |
169 |
@@ -109,8 +110,7 @@ class slot_conflict_handler(object): |
170 |
all_conflict_atoms_by_slotatom = [] |
171 |
|
172 |
#fill conflict_pkgs, all_conflict_atoms_by_slotatom |
173 |
- for (atom, root), pkgs \ |
174 |
- in self.slot_collision_info.items(): |
175 |
+ for root, atom, pkgs in self.all_conflicts: |
176 |
conflict_pkgs.append(list(pkgs)) |
177 |
all_conflict_atoms_by_slotatom.append(set()) |
178 |
|
179 |
@@ -249,8 +249,7 @@ class slot_conflict_handler(object): |
180 |
msg.append("!!! into the dependency graph, resulting" + \ |
181 |
" in a slot conflict:\n\n") |
182 |
|
183 |
- for (slot_atom, root), pkgs \ |
184 |
- in self.slot_collision_info.items(): |
185 |
+ for root, slot_atom, pkgs in self.all_conflicts: |
186 |
msg.append("%s" % (slot_atom,)) |
187 |
if root != self.depgraph._frozen_config._running_root.root: |
188 |
msg.append(" for %s" % (root,)) |
189 |
@@ -536,13 +535,13 @@ class slot_conflict_handler(object): |
190 |
return None |
191 |
|
192 |
if len(solutions)==1: |
193 |
- if len(self.slot_collision_info)==1: |
194 |
+ if len(self.all_conflicts) == 1: |
195 |
msg += "It might be possible to solve this slot collision\n" |
196 |
else: |
197 |
msg += "It might be possible to solve these slot collisions\n" |
198 |
msg += "by applying all of the following changes:\n" |
199 |
else: |
200 |
- if len(self.slot_collision_info)==1: |
201 |
+ if len(self.all_conflicts) == 1: |
202 |
msg += "It might be possible to solve this slot collision\n" |
203 |
else: |
204 |
msg += "It might be possible to solve these slot collisions\n" |
205 |
@@ -583,8 +582,7 @@ class slot_conflict_handler(object): |
206 |
if not pkg.installed: |
207 |
continue |
208 |
|
209 |
- for (atom, root), pkgs \ |
210 |
- in self.slot_collision_info.items(): |
211 |
+ for root, atom, pkgs in self.all_conflicts: |
212 |
if pkg not in pkgs: |
213 |
continue |
214 |
for other_pkg in pkgs: |
215 |
-- |
216 |
1.8.3.2 |