class Blocker(Task):
__hash__ = Task.__hash__
- __slots__ = ("root", "atom", "cp", "satisfied")
+ __slots__ = ("root", "atom", "cp", "eapi", "satisfied")
def __init__(self, **kwargs):
Task.__init__(self, **kwargs)
hash_key = getattr(self, "_hash_key", None)
if hash_key is None:
self._hash_key = \
- ("blocks", self.root, self.atom)
+ ("blocks", self.root, self.atom, self.eapi)
return self._hash_key
class Package(Task):
return 1
# The blocker applies to the root where
# the parent is or will be installed.
- blocker = Blocker(atom=dep.atom, root=dep.parent.root)
+ blocker = Blocker(atom=dep.atom,
+ eapi=dep.parent.metadata["EAPI"],
+ root=dep.parent.root)
self._blocker_parents.add(blocker, dep.parent)
return 1
dep_pkg, existing_node = self._select_package(dep.root, dep.atom,
for atom in selected_atoms:
try:
- blocker = atom.startswith("!")
- if blocker:
- atom = atom[1:]
+ atom = portage.dep.Atom(atom)
+
mypriority = dep_priority.copy()
- if not blocker and vardb.match(atom):
+ if not atom.blocker and vardb.match(atom):
mypriority.satisfied = True
if not self._add_dep(Dependency(atom=atom,
- blocker=blocker, depth=depth, parent=pkg,
+ blocker=atom.blocker, depth=depth, parent=pkg,
priority=mypriority, root=dep_root),
allow_unsatisfied=allow_unsatisfied):
return 0
except KeyError:
pass
if blockers is not None:
- blockers = set("!" + blocker.atom \
+ blockers = set(str(blocker.atom) \
for blocker in blockers)
# If this node has any blockers, create a "nomerge"
blocker_cache.BlockerData(counter, blocker_atoms)
if blocker_atoms:
for myatom in blocker_atoms:
- blocker = Blocker(atom=myatom[1:], root=myroot)
+ blocker = Blocker(atom=portage.dep.Atom(myatom),
+ eapi=pkg.metadata["EAPI"], root=myroot)
self._blocker_parents.add(blocker, pkg)
for cpv in stale_cache:
del blocker_cache[cpv]
self.spinner.update()
root_config = self.roots[blocker.root]
virtuals = root_config.settings.getvirtuals()
- mytype, myroot, mydep = blocker
+ myroot = blocker.root
initial_db = self.trees[myroot]["vartree"].dbapi
final_db = self.mydbapi[myroot]
if self.digraph.contains(inst_pkg):
continue
- if running_root == task.root:
+ forbid_overlap = False
+ heuristic_overlap = False
+ for blocker in myblocker_uninstalls.parent_nodes(task):
+ if blocker.eapi in ("0", "1"):
+ heuristic_overlap = True
+ elif blocker.atom.blocker.overlap.forbid:
+ forbid_overlap = True
+ break
+ if forbid_overlap and running_root == task.root:
+ continue
+
+ if heuristic_overlap and running_root == task.root:
# Never uninstall sys-apps/portage or it's essential
# dependencies, except through replacement.
try:
# will be temporarily installed simultaneously.
for blocker in solved_blockers:
retlist.append(Blocker(atom=blocker.atom,
- root=blocker.root, satisfied=True))
+ root=blocker.root, eapi=blocker.eapi,
+ satisfied=True))
unsolvable_blockers = set(self._unsolvable_blockers.leaf_nodes())
for node in myblocker_uninstalls.root_nodes():
if x.satisfied:
counters.blocks_satisfied += 1
resolved = portage.key_expand(
- pkg_key, mydb=vardb, settings=pkgsettings)
+ str(x.atom).lstrip("!"), mydb=vardb, settings=pkgsettings)
if "--columns" in self.myopts and "--quiet" in self.myopts:
addl += " " + colorize(blocker_style, resolved)
else:
if resolved!=x[2]:
addl += colorize(blocker_style,
" (\"%s\" is blocking %s)") % \
- (pkg_key, block_parents)
+ (str(x.atom).lstrip("!"), block_parents)
else:
addl += colorize(blocker_style,
" (is blocking %s)") % block_parents
__slots__ = ("__weakref__", "blocker", "cp", "cpv", "operator",
"slot", "use") + _str_methods
+ class _blocker(object):
+ __slots__ = ("overlap",)
+
+ class _overlap(object):
+ __slots__ = ("forbid",)
+
+ def __init__(self, forbid=False):
+ self.forbid = forbid
+
+ def __init__(self, forbid_overlap=False):
+ self.overlap = self._overlap(forbid=forbid_overlap)
+
def __init__(self, s):
if not isvalidatom(s, allow_blockers=True):
raise InvalidAtom(s)
for x in self._str_methods:
setattr(self, x, getattr(s, x))
- self.blocker = "!" == s[:1]
- if self.blocker:
- s = s[1:]
+
+ blocker = "!" == s[:1]
+ if blocker:
+ self.blocker = self._blocker(forbid_overlap=("!" == s[1:2]))
+ if self.blocker.overlap.forbid:
+ s = s[2:]
+ else:
+ s = s[1:]
+ else:
+ self.blocker = False
+
self.cp = dep_getkey(s)
self.cpv = dep_getcpv(s)
self.slot = dep_getslot(s)
if mydep and mydep[-1] == "*":
mydep = mydep[:-1]
if mydep and mydep[0] == "!":
- mydep = mydep[1:]
+ if mydep[1:2] == "!":
+ mydep = mydep[2:]
+ else:
+ mydep = mydep[1:]
if mydep[:2] in [">=", "<="]:
mydep = mydep[2:]
elif mydep[:1] in "=<>~":
global _invalid_atom_chars_regexp
if _invalid_atom_chars_regexp.search(atom):
return 0
- if allow_blockers and atom.startswith("!"):
- atom = atom[1:]
+ if allow_blockers and atom[:1] == "!":
+ if atom[1:2] == "!":
+ atom = atom[2:]
+ else:
+ atom = atom[1:]
try:
use = dep_getusedeps(atom)