summaryrefslogtreecommitdiffstats
path: root/pym
diff options
context:
space:
mode:
Diffstat (limited to 'pym')
-rw-r--r--pym/portage.py39
1 files changed, 38 insertions, 1 deletions
diff --git a/pym/portage.py b/pym/portage.py
index 063acc5f7..3bb6451ee 100644
--- a/pym/portage.py
+++ b/pym/portage.py
@@ -5464,6 +5464,8 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
other = []
# Alias the trees we'll be checking availability against
+ parent = trees[myroot].get("parent")
+ graph_db = trees[myroot].get("graph_db")
vardb = None
if "vartree" in trees[myroot]:
vardb = trees[myroot]["vartree"].dbapi
@@ -5525,8 +5527,43 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
preferred.append(this_choice)
else:
preferred_any_slot.append(this_choice)
- else:
+ elif graph_db is None:
possible_upgrades.append(this_choice)
+ else:
+ all_in_graph = True
+ for slot_atom in versions:
+ # New-style virtuals have zero cost to install.
+ if not graph_db.match(slot_atom) and \
+ not slot_atom.startswith("virtual/"):
+ all_in_graph = False
+ break
+ if all_in_graph:
+ if parent is None:
+ preferred.append(this_choice)
+ else:
+ # Check if the atom would result in a direct circular
+ # dependency and try to avoid that if it seems likely
+ # to be unresolvable.
+ cpv_slot_list = [parent.cpv_slot]
+ circular_atom = None
+ for atom in atoms:
+ if "!" == atom[:1]:
+ continue
+ if vardb.match(atom):
+ # If the atom is satisfied by an installed
+ # version then it's not a circular dep.
+ continue
+ if dep_getkey(atom) != parent.cp:
+ continue
+ if match_from_list(atom, cpv_slot_list):
+ circular_atom = atom
+ break
+ if circular_atom is None:
+ preferred.append(this_choice)
+ else:
+ other.append(this_choice)
+ else:
+ possible_upgrades.append(this_choice)
else:
other.append(this_choice)