1 |
When selecting packages to determine which choices have upgrades |
2 |
or downgrades relative to other choices, make the package selections |
3 |
internally consistent by choosing a package that satisfies all atoms |
4 |
in the choice which match a package in the same slot. |
5 |
|
6 |
Also, fix the Atom.match() method to handle _pkg_str instances, |
7 |
since dep_zapdeps can pass in _pkg_str instances instead of Package |
8 |
instances. |
9 |
|
10 |
X-Gentoo-Bug: 600346 |
11 |
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=600346 |
12 |
--- |
13 |
[PATCH v2] fixes incorrect logic in dep_zapdeps |
14 |
|
15 |
pym/portage/dep/__init__.py | 16 ++++++++++++---- |
16 |
pym/portage/dep/dep_check.py | 28 ++++++++++++++++++++++++++-- |
17 |
2 files changed, 38 insertions(+), 6 deletions(-) |
18 |
|
19 |
diff --git a/pym/portage/dep/__init__.py b/pym/portage/dep/__init__.py |
20 |
index 5dd1638..968ff5b 100644 |
21 |
--- a/pym/portage/dep/__init__.py |
22 |
+++ b/pym/portage/dep/__init__.py |
23 |
@@ -1603,10 +1603,18 @@ class Atom(_unicode): |
24 |
if pkg.cp == self.cp: |
25 |
return bool(match_from_list(self, [pkg])) |
26 |
else: |
27 |
- for provided_cp in pkg.provided_cps: |
28 |
- if provided_cp == self.cp: |
29 |
- return bool(match_from_list( |
30 |
- self.replace(self.cp, provided_cp, 1), [pkg])) |
31 |
+ try: |
32 |
+ provided_cps = pkg.provided_cps |
33 |
+ except AttributeError: |
34 |
+ # Since _pkg_str instances lack PROVIDE metadata, |
35 |
+ # just ignore this case (PROVIDE has been deprecated |
36 |
+ # for years). |
37 |
+ pass |
38 |
+ else: |
39 |
+ for provided_cp in provided_cps: |
40 |
+ if provided_cp == self.cp: |
41 |
+ return bool(match_from_list( |
42 |
+ self.replace(self.cp, provided_cp, 1), [pkg])) |
43 |
return False |
44 |
|
45 |
_extended_cp_re_cache = {} |
46 |
diff --git a/pym/portage/dep/dep_check.py b/pym/portage/dep/dep_check.py |
47 |
index 9d2ca4b..737d2b1 100644 |
48 |
--- a/pym/portage/dep/dep_check.py |
49 |
+++ b/pym/portage/dep/dep_check.py |
50 |
@@ -5,6 +5,7 @@ from __future__ import unicode_literals |
51 |
|
52 |
__all__ = ['dep_check', 'dep_eval', 'dep_wordreduce', 'dep_zapdeps'] |
53 |
|
54 |
+import collections |
55 |
import logging |
56 |
import operator |
57 |
|
58 |
@@ -354,6 +355,7 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): |
59 |
all_use_satisfied = True |
60 |
all_use_unmasked = True |
61 |
conflict_downgrade = False |
62 |
+ slot_atoms = collections.defaultdict(list) |
63 |
slot_map = {} |
64 |
cp_map = {} |
65 |
for atom in atoms: |
66 |
@@ -418,9 +420,31 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): |
67 |
avail_slot = Atom("%s:%s" % (atom.cp, avail_pkg.slot)) |
68 |
|
69 |
slot_map[avail_slot] = avail_pkg |
70 |
+ slot_atoms[avail_slot].append(atom) |
71 |
highest_cpv = cp_map.get(avail_pkg.cp) |
72 |
- if highest_cpv is None or \ |
73 |
- vercmp(avail_pkg.version, highest_cpv.version) > 0: |
74 |
+ all_match_current = None |
75 |
+ all_match_previous = None |
76 |
+ if (highest_cpv is not None and |
77 |
+ highest_cpv.slot == avail_pkg.slot): |
78 |
+ # If possible, make the package selection internally |
79 |
+ # consistent by choosing a package that satisfies all |
80 |
+ # atoms which match a package in the same slot. Later on, |
81 |
+ # the package version chosen here is used in the |
82 |
+ # has_upgrade/has_downgrade logic to prefer choices with |
83 |
+ # upgrades, and a package choice that is not internally |
84 |
+ # consistent will lead the has_upgrade/has_downgrade logic |
85 |
+ # to produce invalid results (see bug 600346). |
86 |
+ all_match_current = all(a.match(avail_pkg) |
87 |
+ for a in slot_atoms[avail_slot]) |
88 |
+ all_match_previous = all(a.match(highest_cpv) |
89 |
+ for a in slot_atoms[avail_slot]) |
90 |
+ if all_match_previous and not all_match_current: |
91 |
+ continue |
92 |
+ |
93 |
+ current_higher = (highest_cpv is None or |
94 |
+ vercmp(avail_pkg.version, highest_cpv.version) > 0) |
95 |
+ |
96 |
+ if current_higher or (all_match_current and not all_match_previous): |
97 |
cp_map[avail_pkg.cp] = avail_pkg |
98 |
|
99 |
this_choice = _dep_choice(atoms=atoms, slot_map=slot_map, |
100 |
-- |
101 |
2.7.4 |