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