Gentoo Archives: gentoo-portage-dev

From: Sebastian Luther <SebastianLuther@×××.de>
To: gentoo-portage-dev@l.g.o
Subject: Re: [gentoo-portage-dev] [PATCH] Another slot operator bug (bug 486580, try 2)
Date: Thu, 28 Nov 2013 19:36:16
Message-Id: 52979B2A.1080508@gmx.de
In Reply to: Re: [gentoo-portage-dev] [PATCH] Another slot operator bug (bug 486580, try 2) by Brian Dolbec
1 Am 28.11.2013 15:47, schrieb Brian Dolbec:
2 > I like this one much better, thank you.
3 >
4 > Could you rebase the 2 patches together, tis one shows removing
5 > lines from the first. Also see inline comments below :)
6
7 The removed lines are another large if-block that already existed.
8 This has been moved into _ignore_dependency() too.
9
10 >
11 > On Thu, 2013-11-28 at 11:34 +0100, SebastianLuther@×××.de wrote:
12 >> From: Sebastian Luther <SebastianLuther@×××.de>
13 >>
14 >> This time rebuilds are scheduled properly, but we might still
15 >> forget to install the package that caused the rebuild.
16 >>
17 >> URL: https://bugs.gentoo.org/486580 --- pym/_emerge/depgraph.py
18 >> | 48 +++++++++++------
19 >> .../tests/resolver/test_slot_conflict_rebuild.py | 63
20 >> ++++++++++++++++++++++ 2 files changed, 95 insertions(+), 16
21 >> deletions(-)
22 >>
23 >> diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
24 >> index da2e604..0a998b5 100644 --- a/pym/_emerge/depgraph.py +++
25 >> b/pym/_emerge/depgraph.py @@ -2268,6 +2268,36 @@ class
26 >> depgraph(object): finally: self._dynamic_config._autounmask =
27 >> _autounmask_backup
28 >>
29 >> + def _ignore_dependency(self, atom, pkg, child, dep, mypriority,
30 >> recurse_satisfied): + """ + In some cases, dep_check will
31 >> return deps that shouldn't + be proccessed any further, so they
32 >> are identified and + discarded here. Try to discard as few as
33 >> possible since + discarded dependencies reduce the amount of
34 >> information + available for optimization of merge order. +
35 >> Don't ignore dependencies if pkg has a slot operator dependency
36 >> on the child + and the child has changed slot/sub_slot. + """ +
37 >> slot_operator_rebuild = False + if atom.slot_operator == '=' and
38 >> \ + (pkg.root, pkg.slot_atom) in
39 >> self._dynamic_config._slot_operator_replace_installed and \ +
40 >> mypriority.satisfied and \ + mypriority.satisfied is not child
41 >> and \ + mypriority.satisfied.installed and \ + not
42 >> child.installed and \ + (child.slot !=
43 >> mypriority.satisfied.slot or child.sub_slot !=
44 >> mypriority.satisfied.sub_slot): + slot_operator_rebuild = True
45 >> + + return not atom.blocker and \ + not recurse_satisfied and
46 >> \ + mypriority.satisfied and \ + mypriority.satisfied.visible
47 >> and \ + dep.child is not None and \ + not dep.child.installed
48 >> and \ +
49 >> self._dynamic_config._slot_pkg_map[dep.child.root].get( +
50 >> dep.child.slot_atom) is None and \ + not slot_operator_rebuild
51 >> +
52 >
53 > Since slot_operator_rebuild is already set either true or false,
54 > would it be better if "not slot_operator_rebuild" is first in the
55 > return statement. If it resolves False, it will be an early out
56 > for the remaining checks. Personally I don't know which is the
57 > more common case. But if it resolve False more often, it will be a
58 > slight speed improvement. That goes for the rest of them too, they
59 > should be ordered in the most often to resolve False order. Same
60 > for the if as well.
61
62 This should be more often False than True. recurse_satisfied in the
63 second block should be more often True than False.
64
65 In fact there's some duplication between the two blocks. Feel free to
66 clean this up after it has been pushed.
67
68
69 >
70 > /end tiny nitpick
71 >
72 >> def _wrapped_add_pkg_dep_string(self, pkg, dep_root,
73 >> dep_priority, dep_string, allow_unsatisfied): depth = pkg.depth +
74 >> 1 @@ -2357,14 +2387,7 @@ class depgraph(object): # discarded
75 >> dependencies reduce the amount of information # available for
76 >> optimization of merge order. ignored = False - if not
77 >> atom.blocker and \ - not recurse_satisfied and \ -
78 >> mypriority.satisfied and \ - mypriority.satisfied.visible and
79 >> \ - dep.child is not None and \ - not dep.child.installed
80 >> and \ -
81 >> self._dynamic_config._slot_pkg_map[dep.child.root].get( -
82 >> dep.child.slot_atom) is None: + if
83 >> self._ignore_dependency(atom, pkg, child, dep, mypriority,
84 >> recurse_satisfied): myarg = None try: myarg =
85 >> next(self._iter_atoms_for_pkg(dep.child), None) @@ -2467,14
86 >> +2490,7 @@ class depgraph(object): collapsed_parent=pkg,
87 >> collapsed_priority=dep_priority)
88 >>
89 >> ignored = False - if not atom.blocker and \ - not
90 >> recurse_satisfied and \ - mypriority.satisfied and \ -
91 >> mypriority.satisfied.visible and \ - dep.child is not None
92 >> and \ - not dep.child.installed and \ -
93 >> self._dynamic_config._slot_pkg_map[dep.child.root].get( -
94 >> dep.child.slot_atom) is None: + if
95 >> self._ignore_dependency(atom, pkg, child, dep, mypriority,
96 >> recurse_satisfied): myarg = None try: myarg =
97 >> next(self._iter_atoms_for_pkg(dep.child), None) diff --git
98 >> a/pym/portage/tests/resolver/test_slot_conflict_rebuild.py
99 >> b/pym/portage/tests/resolver/test_slot_conflict_rebuild.py index
100 >> 74f5cc1..e3c517d 100644 ---
101 >> a/pym/portage/tests/resolver/test_slot_conflict_rebuild.py +++
102 >> b/pym/portage/tests/resolver/test_slot_conflict_rebuild.py @@
103 >> -181,6 +181,69 @@ class SlotConflictRebuildTestCase(TestCase):
104 >> finally: playground.cleanup()
105 >>
106 >> + def testSlotConflictForgottenChild(self): + """ + Similar to
107 >> testSlotConflictMassRebuild above, but this time the rebuilds are
108 >> scheduled, + but the package causing the rebuild (the child) is
109 >> not installed. + """ + ebuilds = { + + "app-misc/A-2" : { +
110 >> "EAPI": "5", + "DEPEND": "app-misc/B:= app-misc/C", +
111 >> "RDEPEND": "app-misc/B:= app-misc/C", + }, + + "app-misc/B-2"
112 >> : { + "EAPI": "5", + "SLOT": "2" + }, + +
113 >> "app-misc/C-1": { + "EAPI": "5", + "DEPEND":
114 >> "app-misc/B:=", + "RDEPEND": "app-misc/B:=" + }, + } + +
115 >> installed = { + "app-misc/A-1" : { + "EAPI": "5", +
116 >> "DEPEND": "app-misc/B:1/1= app-misc/C", + "RDEPEND":
117 >> "app-misc/B:1/1= app-misc/C", + }, + + "app-misc/B-1" : { +
118 >> "EAPI": "5", + "SLOT": "1" + }, + + "app-misc/C-1": { +
119 >> "EAPI": "5", + "DEPEND": "app-misc/B:1/1=", + "RDEPEND":
120 >> "app-misc/B:1/1=" + }, + } + + test_cases = ( +
121 >> ResolverPlaygroundTestCase( + ["app-misc/A"], + success =
122 >> True, + mergelist = ['app-misc/B-2', 'app-misc/C-1',
123 >> 'app-misc/A-2']), + ) + + world = [] + + playground =
124 >> ResolverPlayground(ebuilds=ebuilds, + installed=installed,
125 >> world=world, debug=False) + try: + for test_case in
126 >> test_cases: + playground.run_TestCase(test_case) +
127 >> self.assertEqual(test_case.test_success, True,
128 >> test_case.fail_msg) + finally: + playground.cleanup() + + def
129 >> testSlotConflictDepChange(self): """ Bug 490362
130 >

Replies