From df0bb6fe503297f961bbf75fc0fbf5c006188a3d Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Thu, 27 Aug 2009 07:14:37 +0000 Subject: [PATCH] Bug #278729 - Inside dep_zapdeps(), account for USE dependencies in some cases where USE settings can adversely affect || preference evaluation. This requires invalid atoms to be dropped inside _expand_new_virtuals() since we only want real Atom instances inside dep_zapdeps(). Unlike previous attempts to solve this bug, cases such as || ( foo[a] foo[b] ) should now be correctly handled. svn path=/main/trunk/; revision=14165 --- pym/portage/__init__.py | 71 +++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 20 deletions(-) diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 8669dd7f8..9f251882b 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -7452,6 +7452,9 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", if portage.dep._dep_check_strict: raise portage.exception.ParseError( _("invalid atom: '%s'") % x) + else: + # Only real Atom instances are allowed past this point. + continue else: if x.blocker and x.blocker.overlap.forbid and \ eapi in ("0", "1") and portage.dep._dep_check_strict: @@ -7638,6 +7641,7 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): preferred_installed = [] preferred_in_graph = [] + preferred_unsatisfied_use = [] preferred_any_slot = [] preferred_non_installed = [] other = [] @@ -7669,19 +7673,35 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): continue all_available = True + all_use_satisfied = True versions = {} for atom in atoms: if atom[:1] == "!": continue - avail_pkg = mydbapi.match(atom) + # Ignore USE dependencies here since we don't want USE + # settings to adversely affect || preference evaluation. + avail_pkg = mydbapi.match(atom.without_use) if avail_pkg: avail_pkg = avail_pkg[-1] # highest (ascending order) avail_slot = "%s:%s" % (dep_getkey(atom), mydbapi.aux_get(avail_pkg, ["SLOT"])[0]) if not avail_pkg: all_available = False + all_use_satisfied = False break + if atom.use: + avail_pkg_use = mydbapi.match(atom) + if not avail_pkg_use: + all_use_satisfied = False + else: + # highest (ascending order) + avail_pkg_use = avail_pkg_use[-1] + if avail_pkg_use != avail_pkg: + avail_pkg = avail_pkg_use + avail_slot = "%s:%s" % (dep_getkey(atom), + mydbapi.aux_get(avail_pkg, ["SLOT"])[0]) + versions[avail_slot] = avail_pkg this_choice = (atoms, versions, all_available) @@ -7705,13 +7725,17 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): not slot_atom.startswith("virtual/"): all_installed_slots = False break - if graph_db is None and all_installed: - if all_installed_slots: - preferred_installed.append(this_choice) + if graph_db is None: + if all_use_satisfied: + if all_installed: + if all_installed_slots: + preferred_installed.append(this_choice) + else: + preferred_any_slot.append(this_choice) + else: + preferred_non_installed.append(this_choice) else: - preferred_any_slot.append(this_choice) - elif graph_db is None: - preferred_non_installed.append(this_choice) + other.append(this_choice) else: all_in_graph = True for slot_atom in versions: @@ -7720,9 +7744,10 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): not slot_atom.startswith("virtual/"): all_in_graph = False break + circular_atom = None if all_in_graph: if parent is None or priority is None: - preferred_in_graph.append(this_choice) + pass elif priority.buildtime: # Check if the atom would result in a direct circular # dependency and try to avoid that if it seems likely @@ -7730,7 +7755,6 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): # buildtime deps that aren't already satisfied by an # installed package. cpv_slot_list = [parent] - circular_atom = None for atom in atoms: if "!" == atom[:1]: continue @@ -7743,25 +7767,32 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None): if match_from_list(atom, cpv_slot_list): circular_atom = atom break - if circular_atom is None: + if circular_atom is not None: + other.append(this_choice) + else: + if all_use_satisfied: + if all_in_graph: preferred_in_graph.append(this_choice) + elif all_installed: + if all_installed_slots: + preferred_installed.append(this_choice) + else: + preferred_any_slot.append(this_choice) else: - other.append(this_choice) + preferred_non_installed.append(this_choice) else: - preferred_in_graph.append(this_choice) - else: - if all_installed: - if all_installed_slots: - preferred_installed.append(this_choice) + if all_in_graph or all_installed: + preferred_unsatisfied_use.append(this_choice) else: - preferred_any_slot.append(this_choice) - else: - preferred_non_installed.append(this_choice) + other.append(this_choice) else: other.append(this_choice) + # preferred_unsatisfied_use must come after preferred_non_installed + # for correct ordering in cases like || ( foo[a] foo[b] ). preferred = preferred_in_graph + preferred_installed + \ - preferred_any_slot + preferred_non_installed + other + preferred_any_slot + preferred_non_installed + \ + preferred_unsatisfied_use + other for allow_masked in (False, True): for atoms, versions, all_available in preferred: -- 2.26.2