Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH v2] dep_zapdeps: make package selections internally consistent (bug 600346)
Date: Sun, 20 Nov 2016 23:57:08
Message-Id: 1479686214-20585-1-git-send-email-zmedico@gentoo.org
In Reply to: [gentoo-portage-dev] [PATCH] dep_zapdeps: make package selections internally consistent (bug 600346) by Zac Medico
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

Replies