Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 290818 | Differences between
and this patch

Collapse All | Expand All

(-)a/pym/_emerge/depgraph.py (+52 lines)
Lines 2516-2521 class depgraph(object): Link Here
2516
		for root, atom in self._dynamic_config._slot_abi_replace_installed:
2516
		for root, atom in self._dynamic_config._slot_abi_replace_installed:
2517
			atom_list.append((root, '__auto_slot_abi_replace_installed__', atom))
2517
			atom_list.append((root, '__auto_slot_abi_replace_installed__', atom))
2518
2518
2519
		# Add slot atoms for packages where updating might solve a
2520
		# conflict, but the package wouldn't be pulled in otherwise.
2521
		# Note that this can't result in strange errors being
2522
		# displayed to the user, because if the backtracker gives
2523
		# up, the resolution is done without _runtime_pkg_mask and
2524
		# the original error gets displayed.
2525
		for pkg in self._dynamic_config._runtime_pkg_mask:
2526
			if "force update" in self._dynamic_config._runtime_pkg_mask[pkg]:
2527
				atom_list.append((pkg.root, '__auto_blocker_force_update__', pkg.slot_atom))
2528
2519
		set_dict = {}
2529
		set_dict = {}
2520
		for root, set_name, atom in atom_list:
2530
		for root, set_name, atom in atom_list:
2521
			set_dict.setdefault((root, set_name), []).append(atom)
2531
			set_dict.setdefault((root, set_name), []).append(atom)
Lines 5077-5082 class depgraph(object): Link Here
5077
				if unresolved_blocks:
5087
				if unresolved_blocks:
5078
					self._dynamic_config._unsolvable_blockers.add(blocker, parent)
5088
					self._dynamic_config._unsolvable_blockers.add(blocker, parent)
5079
5089
5090
					#Check if all parents of the package(s) that is/are blocked by this blocker
5091
					#are installed. If this is true, the blocked package(s) might not be
5092
					#pulled into the tree if we force updates for the parent packages.
5093
					pkgs_forced_to_update = set()
5094
					all_parents_installed = True
5095
					for blocked_pkg in blocked_initial:
5096
						for ppkg, patom in self._dynamic_config._parent_atoms.get(blocked_pkg):
5097
							if not ppkg.installed:
5098
								all_parents_installed = False
5099
							pkgs_forced_to_update.add(ppkg)
5100
5101
					if all_parents_installed:
5102
						if "--debug" in self._frozen_config.myopts:
5103
								msg = []
5104
								msg.append("")
5105
								msg.append("")
5106
								msg.append("backtracking due to conflicting packages:")
5107
								msg.append("  blocker parent: %s" % blocker)
5108
								msg.append("      root: %s" % blocker.root)
5109
								msg.append("      atom: %s" % blocker.atom)
5110
								for blocked_pkg in blocked_initial:
5111
									msg.append("      blocked package: %s" % blocked_pkg)
5112
									for ppkg, patom in self._dynamic_config._parent_atoms.get(blocked_pkg):
5113
										msg.append("        masked parent: %s" % ppkg)
5114
								msg.append("")
5115
								writemsg_level("".join("%s\n" % l for l in msg),
5116
									noiselevel=-1, level=logging.DEBUG)
5117
5118
						for ppkg in pkgs_forced_to_update:
5119
							if ppkg in self._dynamic_config._runtime_pkg_mask:
5120
								if "--debug" in self._frozen_config.myopts:
5121
									writemsg(
5122
										"!!! backtracking loop detected: %s %s\n" % \
5123
										(ppkg,
5124
										self._dynamic_config._runtime_pkg_mask[
5125
										ppkg]), noiselevel=-1)
5126
							self._dynamic_config._runtime_pkg_mask.setdefault(
5127
								ppkg, {})["force update"] = \
5128
									set([(ppkg, ppkg.root, blocker.atom)])
5129
5130
						self._dynamic_config._need_restart = True
5131
5080
		return True
5132
		return True
5081
5133
5082
	def _accept_blocker_conflicts(self):
5134
	def _accept_blocker_conflicts(self):
(-)a/pym/portage/tests/resolver/test_backtracking.py (+44 lines)
Lines 210-212 class BacktrackingTestCase(TestCase): Link Here
210
				self.assertEqual(test_case.test_success, True, test_case.fail_msg)
210
				self.assertEqual(test_case.test_success, True, test_case.fail_msg)
211
		finally:
211
		finally:
212
			playground.cleanup()
212
			playground.cleanup()
213
214
	def testBacktrackBlockerForceUpdate(self):
215
		"""
216
		Force updates of old packages that trigger blockers, for
217
		bug #290818. This test currently fails because the
218
		dev-libs/B-2 update doesn't get pulled in automatically,
219
		and the old version can't simply be uninstalled because
220
		dev-libs/B is a deep dependency of @world via dev-libs/D.
221
		"""
222
223
		ebuilds = {
224
			"dev-libs/A-1": {"RDEPEND": "dev-libs/B"},
225
			"dev-libs/A-2": {"RDEPEND": "dev-libs/C"},
226
			"dev-libs/B-1": {},
227
			"dev-libs/B-2": {},
228
			"dev-libs/C-1": {"RDEPEND": "!<dev-libs/B-2"},
229
			"dev-libs/D-1": {"RDEPEND": "dev-libs/B"},
230
		}
231
232
		installed = {
233
			"dev-libs/A-1": {"RDEPEND": "dev-libs/B"},
234
			"dev-libs/B-1": {},
235
			"dev-libs/D-1": {"RDEPEND": "dev-libs/B"},
236
		}
237
238
		world = ["dev-libs/A", "dev-libs/D"]
239
240
		test_cases = (
241
			ResolverPlaygroundTestCase(
242
				["dev-libs/A"],
243
				options =  {'--oneshot': True, '--update' : True},
244
				mergelist = ['dev-libs/B-2', 'dev-libs/C-1', 'dev-libs/A-2'],
245
				success = True),
246
		)
247
248
		playground = ResolverPlayground(ebuilds=ebuilds,
249
			installed=installed, world=world, debug=True)
250
251
		try:
252
			for test_case in test_cases:
253
				playground.run_TestCase(test_case)
254
				self.assertEqual(test_case.test_success, True, test_case.fail_msg)
255
		finally:
256
			playground.cleanup()

Return to bug 290818