Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 384318 Details for
Bug 520950
dev-java/icedtea-web-1.3.2-r7 ebuild incorrectly treated as masked and with no reason of masking
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
depgraph._add_dep: fix bug #520950
depgraph._add_dep-fix-bug-520950.patch (text/plain), 12.73 KB, created by
Zac Medico
on 2014-09-06 23:51:47 UTC
(
hide
)
Description:
depgraph._add_dep: fix bug #520950
Filename:
MIME Type:
Creator:
Zac Medico
Created:
2014-09-06 23:51:47 UTC
Size:
12.73 KB
patch
obsolete
>From 17a8ec31dc56d58e8d6f4e05bf7214a3daaa9759 Mon Sep 17 00:00:00 2001 >From: Zac Medico <zmedico@gentoo.org> >Date: Sat, 6 Sep 2014 16:25:24 -0700 >Subject: [PATCH] depgraph._add_dep: fix bug #520950 > >This handles a case which occurs when >_solve_non_slot_operator_slot_conflicts calls _create_graph. In this >case, ignore unsatisfied deps for installed packages only if their depth >is beyond the depth requested by the user and the dep was initially >unsatisfied (not broken by a slot conflict in the current graph). > >Since depth is meaningless for packages that are not reachable as deep >dependencies of arguments, the _UNREACHABLE_DEPTH constant is used as >the depth value for any packages added via _complete_graph. Also, any >sets added via _complete_graph have their reset_depth attribute set to >False. >--- > pym/_emerge/depgraph.py | 97 +++++++++++++++++++--- > pym/portage/tests/resolver/ResolverPlayground.py | 11 ++- > .../test_slot_conflict_unsatisfied_deep_deps.py | 55 ++++++++++++ > 3 files changed, 148 insertions(+), 15 deletions(-) > create mode 100644 pym/portage/tests/resolver/test_slot_conflict_unsatisfied_deep_deps.py > >diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py >index d6cd24d..386c9a2 100644 >--- a/pym/_emerge/depgraph.py >+++ b/pym/_emerge/depgraph.py >@@ -107,7 +107,7 @@ def _wildcard_set(atoms): > > class _frozen_depgraph_config(object): > >- def __init__(self, settings, trees, myopts, spinner): >+ def __init__(self, settings, trees, myopts, params, spinner): > self.settings = settings > self.target_root = settings["EROOT"] > self.myopts = myopts >@@ -115,6 +115,7 @@ class _frozen_depgraph_config(object): > if settings.get("PORTAGE_DEBUG", "") == "1": > self.edebug = 1 > self.spinner = spinner >+ self.requested_depth = params.get("deep", 0) > self._running_root = trees[trees._running_eroot]["root_config"] > self.pkgsettings = {} > self.trees = {} >@@ -502,13 +503,18 @@ class _dynamic_depgraph_config(object): > > class depgraph(object): > >+ # Represents the depth of a node that is unreachable from explicit >+ # user arguments (or their deep dependencies). Such nodes are pulled >+ # in by the _complete_graph method. >+ _UNREACHABLE_DEPTH = object() >+ > pkg_tree_map = RootConfig.pkg_tree_map > > def __init__(self, settings, trees, myopts, myparams, spinner, > frozen_config=None, backtrack_parameters=BacktrackParameter(), allow_backtracking=False): > if frozen_config is None: > frozen_config = _frozen_depgraph_config(settings, trees, >- myopts, spinner) >+ myopts, myparams, spinner) > self._frozen_config = frozen_config > self._dynamic_config = _dynamic_depgraph_config(self, myparams, > allow_backtracking, backtrack_parameters) >@@ -2095,6 +2101,13 @@ class depgraph(object): > arg = arg_stack.pop() > if arg in traversed_set_args: > continue >+ >+ # If a node with the same hash already exists in >+ # the digraph, preserve the existing instance which >+ # may have a different reset_depth attribute >+ # (distiguishes user arguments from sets added for >+ # another reason such as complete mode). >+ arg = self._dynamic_config.digraph.get(arg, arg) > traversed_set_args.add(arg) > > if add_to_digraph: >@@ -2114,8 +2127,16 @@ class depgraph(object): > if nested_set is None: > nested_set = root_config.sets.get(s) > if nested_set is not None: >+ # Propagate the reset_depth attribute from >+ # parent set to nested set. > nested_arg = SetArg(arg=token, pset=nested_set, >+ reset_depth=arg.reset_depth, > root_config=root_config) >+ >+ # Preserve instances already in the graph (same >+ # reason as for the "arg" variable above). >+ nested_arg = self._dynamic_config.digraph.get( >+ nested_arg, nested_arg) > arg_stack.append(nested_arg) > if add_to_digraph: > self._dynamic_config.digraph.add(nested_arg, arg, >@@ -2164,9 +2185,42 @@ class depgraph(object): > dep.collapsed_priority.ignored): > # This is an unnecessary build-time dep. > return 1 >+ >+ # NOTE: For removal actions, allow_unsatisfied is always >+ # True since all existing removal actions traverse all >+ # installed deps deeply via the _complete_graph method, >+ # which calls _create_graph with allow_unsatisfied = True. > if allow_unsatisfied: > self._dynamic_config._unsatisfied_deps.append(dep) > return 1 >+ >+ # The following case occurs when >+ # _solve_non_slot_operator_slot_conflicts calls >+ # _create_graph. In this case, ignore unsatisfied deps for >+ # installed packages only if their depth is beyond the depth >+ # requested by the user and the dep was initially >+ # unsatisfied (not broken by a slot conflict in the current >+ # graph). See bug #520950. >+ # NOTE: The value of dep.parent.depth is guaranteed to be >+ # either an integer or _UNREACHABLE_DEPTH, where >+ # _UNREACHABLE_DEPTH indicates that the parent has been >+ # pulled in by the _complete_graph method (rather than by >+ # explicit arguments or their deep dependencies). These >+ # cases must be distinguished because depth is meaningless >+ # for packages that are not reachable as deep dependencies >+ # of arguments. >+ if (self._dynamic_config._complete_mode and >+ isinstance(dep.parent, Package) and >+ dep.parent.installed and >+ (dep.parent.depth is self._UNREACHABLE_DEPTH or >+ (self._frozen_config.requested_depth is not True and >+ dep.parent.depth >= self._frozen_config.requested_depth))): >+ inst_pkg, in_graph = \ >+ self._select_pkg_from_installed(dep.root, dep.atom) >+ if inst_pkg is None: >+ self._dynamic_config._initially_unsatisfied_deps.append(dep) >+ return 1 >+ > self._dynamic_config._unsatisfied_deps_for_display.append( > ((dep.root, dep.atom), {"myparent":dep.parent})) > >@@ -2411,14 +2465,23 @@ class depgraph(object): > # Installing package A, we need to make sure package A's deps are met. > # emerge --deep <pkgspec>; we need to recursively check dependencies of pkgspec > # If we are in --nodeps (no recursion) mode, we obviously only check 1 level of dependencies. >- if arg_atoms and depth > 0: >+ if arg_atoms and depth != 0: > for parent, atom in arg_atoms: > if parent.reset_depth: > depth = 0 > break > >- if previously_added and pkg.depth is not None: >- depth = min(pkg.depth, depth) >+ if previously_added and depth != 0 and \ >+ isinstance(pkg.depth, int): >+ # Use pkg.depth if it is less than depth. >+ if isinstance(depth, int): >+ depth = min(pkg.depth, depth) >+ else: >+ # depth is _UNREACHABLE_DEPTH and pkg.depth is >+ # an int, so use the int because it's considered >+ # to be less than _UNREACHABLE_DEPTH. >+ depth = pkg.depth >+ > pkg.depth = depth > deep = self._dynamic_config.myparams.get("deep", 0) > update = "--update" in self._frozen_config.myopts >@@ -2716,7 +2779,11 @@ class depgraph(object): > > def _wrapped_add_pkg_dep_string(self, pkg, dep_root, dep_priority, > dep_string, allow_unsatisfied): >- depth = pkg.depth + 1 >+ if isinstance(pkg.depth, int): >+ depth = pkg.depth + 1 >+ else: >+ depth = pkg.depth >+ > deep = self._dynamic_config.myparams.get("deep", 0) > recurse_satisfied = deep is True or depth <= deep > debug = "--debug" in self._frozen_config.myopts >@@ -3947,10 +4014,14 @@ class depgraph(object): > # Recursively traversed virtual dependencies, and their > # direct dependencies, are considered to have the same > # depth as direct dependencies. >- if parent.depth is None: >- virt_depth = None >- else: >+ if isinstance(parent.depth, int): > virt_depth = parent.depth + 1 >+ else: >+ # The depth may be None when called via >+ # _select_atoms_probe, or it may be >+ # _UNREACHABLE_DEPTH for complete mode. >+ virt_depth = parent.depth >+ > chosen_atom_ids = frozenset(id(atom) for atom in mycheck[1]) > selected_atoms = OrderedDict() > node_stack = [(parent, None, None)] >@@ -5833,14 +5904,14 @@ class depgraph(object): > pset = root_config.sets[s] > atom = SETPREFIX + s > args.append(SetArg(arg=atom, pset=pset, >- root_config=root_config)) >+ reset_depth=False, root_config=root_config)) > > self._set_args(args) > for arg in self._expand_set_args(args, add_to_digraph=True): > for atom in arg.pset.getAtoms(): > self._dynamic_config._dep_stack.append( > Dependency(atom=atom, root=arg.root_config.root, >- parent=arg)) >+ parent=arg, depth=self._UNREACHABLE_DEPTH)) > > if True: > if self._dynamic_config._ignored_deps: >@@ -8487,7 +8558,7 @@ def _backtrack_depgraph(settings, trees, myopts, myparams, myaction, myfiles, sp > backtracked = 0 > > frozen_config = _frozen_depgraph_config(settings, trees, >- myopts, spinner) >+ myopts, myparams, spinner) > > while backtracker: > >@@ -8569,7 +8640,7 @@ def _resume_depgraph(settings, trees, mtimedb, myopts, myparams, spinner): > mergelist = mtimedb["resume"]["mergelist"] > dropped_tasks = {} > frozen_config = _frozen_depgraph_config(settings, trees, >- myopts, spinner) >+ myopts, myparams, spinner) > while True: > mydepgraph = depgraph(settings, trees, > myopts, myparams, spinner, frozen_config=frozen_config) >diff --git a/pym/portage/tests/resolver/ResolverPlayground.py b/pym/portage/tests/resolver/ResolverPlayground.py >index 077e271..e4a3f24 100644 >--- a/pym/portage/tests/resolver/ResolverPlayground.py >+++ b/pym/portage/tests/resolver/ResolverPlayground.py >@@ -659,7 +659,8 @@ class ResolverPlaygroundTestCase(object): > str((node1, node2))) + \ > ", got: " + str(got)) > >- elif key in ("unstable_keywords", "needed_p_mask_changes") and expected is not None: >+ elif key in ("unstable_keywords", "needed_p_mask_changes", >+ "unsatisfied_deps") and expected is not None: > expected = set(expected) > > if got != expected: >@@ -675,9 +676,10 @@ class ResolverPlaygroundResult(object): > > checks = ( > "success", "mergelist", "use_changes", "license_changes", "unstable_keywords", "slot_collision_solutions", >- "circular_dependency_solutions", "needed_p_mask_changes", >+ "circular_dependency_solutions", "needed_p_mask_changes", "unsatisfied_deps", > ) > optional_checks = ( >+ "unsatisfied_deps" > ) > > def __init__(self, atoms, success, mydepgraph, favorites): >@@ -692,6 +694,7 @@ class ResolverPlaygroundResult(object): > self.needed_p_mask_changes = None > self.slot_collision_solutions = None > self.circular_dependency_solutions = None >+ self.unsatisfied_deps = frozenset() > > if self.depgraph._dynamic_config._serialized_tasks_cache is not None: > self.mergelist = [] >@@ -751,6 +754,10 @@ class ResolverPlaygroundResult(object): > sol = handler.solutions > self.circular_dependency_solutions = dict(zip([x.cpv for x in sol.keys()], sol.values())) > >+ if self.depgraph._dynamic_config._unsatisfied_deps_for_display: >+ self.unsatisfied_deps = set(dep_info[0][1] >+ for dep_info in self.depgraph._dynamic_config._unsatisfied_deps_for_display) >+ > class ResolverPlaygroundDepcleanResult(object): > > checks = ( >diff --git a/pym/portage/tests/resolver/test_slot_conflict_unsatisfied_deep_deps.py b/pym/portage/tests/resolver/test_slot_conflict_unsatisfied_deep_deps.py >new file mode 100644 >index 0000000..3ecbf53 >--- /dev/null >+++ b/pym/portage/tests/resolver/test_slot_conflict_unsatisfied_deep_deps.py >@@ -0,0 +1,55 @@ >+# Copyright 2014 Gentoo Foundation >+# Distributed under the terms of the GNU General Public License v2 >+ >+from portage.tests import TestCase >+from portage.tests.resolver.ResolverPlayground import ResolverPlayground, ResolverPlaygroundTestCase >+ >+class SlotConflictUnsatisfiedDeepDepsTestCase(TestCase): >+ >+ def testSlotConflictUnsatisfiedDeepDeps(self): >+ >+ ebuilds = { >+ "dev-libs/A-1": { }, >+ "dev-libs/A-2": { "KEYWORDS": "~x86" }, >+ "dev-libs/B-1": { "DEPEND": "dev-libs/A" }, >+ "dev-libs/C-1": { "DEPEND": ">=dev-libs/A-2" }, >+ "dev-libs/D-1": { "DEPEND": "dev-libs/A" }, >+ } >+ >+ installed = { >+ "dev-libs/broken-1": { >+ "RDEPEND": "dev-libs/A dev-libs/initially-unsatisfied" >+ }, >+ } >+ >+ world = ( >+ "dev-libs/A", >+ "dev-libs/B", >+ "dev-libs/C", >+ "dev-libs/D", >+ "dev-libs/broken" >+ ) >+ >+ test_cases = ( >+ # Test bug #520950, where unsatisfied deps of installed >+ # packages are supposed to be ignored when they are beyond >+ # the depth requested by the user. >+ ResolverPlaygroundTestCase( >+ ["dev-libs/B", "dev-libs/C", "dev-libs/D"], >+ all_permutations=True, >+ options={"--autounmask": "y", "--complete-graph": True}, >+ mergelist=["dev-libs/A-2", "dev-libs/B-1", "dev-libs/C-1", "dev-libs/D-1"], >+ ignore_mergelist_order=True, >+ unstable_keywords=["dev-libs/A-2"], >+ unsatisfied_deps=[], >+ success=False), >+ ) >+ >+ playground = ResolverPlayground(ebuilds=ebuilds, installed=installed, >+ world=world, debug=False) >+ try: >+ for test_case in test_cases: >+ playground.run_TestCase(test_case) >+ self.assertEqual(test_case.test_success, True, test_case.fail_msg) >+ finally: >+ playground.cleanup() >-- >1.8.5.5 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 520950
:
384126
|
384138
|
384140
|
384162
|
384164
|
384180
|
384202
|
384316
| 384318