On Sun, 20 Nov 2016 15:56:54 -0800
Zac Medico <zmed...@gentoo.org> wrote:

> When selecting packages to determine which choices have upgrades
> or downgrades relative to other choices, make the package selections
> internally consistent by choosing a package that satisfies all atoms
> in the choice which match a package in the same slot.
> 
> Also, fix the Atom.match() method to handle _pkg_str instances,
> since dep_zapdeps can pass in _pkg_str instances instead of Package
> instances.
> 
> X-Gentoo-Bug: 600346
> X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=600346
> ---
> [PATCH v2] fixes incorrect logic in dep_zapdeps
> 
>  pym/portage/dep/__init__.py  | 16 ++++++++++++----
>  pym/portage/dep/dep_check.py | 28 ++++++++++++++++++++++++++--
>  2 files changed, 38 insertions(+), 6 deletions(-)
> 
> diff --git a/pym/portage/dep/__init__.py b/pym/portage/dep/__init__.py
> index 5dd1638..968ff5b 100644
> --- a/pym/portage/dep/__init__.py
> +++ b/pym/portage/dep/__init__.py
> @@ -1603,10 +1603,18 @@ class Atom(_unicode):
>               if pkg.cp == self.cp:
>                       return bool(match_from_list(self, [pkg]))
>               else:
> -                     for provided_cp in pkg.provided_cps:
> -                             if provided_cp == self.cp:
> -                                     return bool(match_from_list(
> -
> self.replace(self.cp, provided_cp, 1), [pkg]))
> +                     try:
> +                             provided_cps = pkg.provided_cps
> +                     except AttributeError:
> +                             # Since _pkg_str instances lack
> PROVIDE metadata,
> +                             # just ignore this case (PROVIDE has
> been deprecated
> +                             # for years).
> +                             pass
> +                     else:
> +                             for provided_cp in provided_cps:
> +                                     if provided_cp == self.cp:
> +                                             return
> bool(match_from_list(
> +
> self.replace(self.cp, provided_cp, 1), [pkg])) return False
>  
>  _extended_cp_re_cache = {}
> diff --git a/pym/portage/dep/dep_check.py
> b/pym/portage/dep/dep_check.py index 9d2ca4b..737d2b1 100644
> --- a/pym/portage/dep/dep_check.py
> +++ b/pym/portage/dep/dep_check.py
> @@ -5,6 +5,7 @@ from __future__ import unicode_literals
>  
>  __all__ = ['dep_check', 'dep_eval', 'dep_wordreduce', 'dep_zapdeps']
>  
> +import collections
>  import logging
>  import operator
>  
> @@ -354,6 +355,7 @@ def dep_zapdeps(unreduced, reduced, myroot,
> use_binaries=0, trees=None): all_use_satisfied = True
>               all_use_unmasked = True
>               conflict_downgrade = False
> +             slot_atoms = collections.defaultdict(list)
>               slot_map = {}
>               cp_map = {}
>               for atom in atoms:
> @@ -418,9 +420,31 @@ def dep_zapdeps(unreduced, reduced, myroot,
> use_binaries=0, trees=None): avail_slot = Atom("%s:%s" % (atom.cp,
> avail_pkg.slot)) 
>                       slot_map[avail_slot] = avail_pkg
> +                     slot_atoms[avail_slot].append(atom)
>                       highest_cpv = cp_map.get(avail_pkg.cp)
> -                     if highest_cpv is None or \
> -                             vercmp(avail_pkg.version,
> highest_cpv.version) > 0:
> +                     all_match_current = None
> +                     all_match_previous = None
> +                     if (highest_cpv is not None and
> +                             highest_cpv.slot == avail_pkg.slot):
> +                             # If possible, make the package
> selection internally
> +                             # consistent by choosing a package
> that satisfies all
> +                             # atoms which match a package in the
> same slot. Later on,
> +                             # the package version chosen here is
> used in the
> +                             # has_upgrade/has_downgrade logic to
> prefer choices with
> +                             # upgrades, and a package choice
> that is not internally
> +                             # consistent will lead the
> has_upgrade/has_downgrade logic
> +                             # to produce invalid results (see
> bug 600346).
> +                             all_match_current =
> all(a.match(avail_pkg)
> +                                     for a in
> slot_atoms[avail_slot])
> +                             all_match_previous =
> all(a.match(highest_cpv)
> +                                     for a in
> slot_atoms[avail_slot])
> +                             if all_match_previous and not
> all_match_current:
> +                                     continue
> +
> +                     current_higher = (highest_cpv is None or
> +                             vercmp(avail_pkg.version,
> highest_cpv.version) > 0) +
> +                     if current_higher or (all_match_current and
> not all_match_previous): cp_map[avail_pkg.cp] = avail_pkg
>  
>               this_choice = _dep_choice(atoms=atoms,
> slot_map=slot_map,


looks good

-- 
Brian Dolbec <dolsen>


Reply via email to