Merge lp:~wgrant/launchpad/delete-nullbugtask into lp:launchpad
- delete-nullbugtask
- Merge into devel
Proposed by
William Grant
Status: | Superseded | ||||
---|---|---|---|---|---|
Proposed branch: | lp:~wgrant/launchpad/delete-nullbugtask | ||||
Merge into: | lp:launchpad | ||||
Diff against target: |
815 lines (+48/-399) 13 files modified
lib/lp/bugs/browser/bugnomination.py (+1/-9) lib/lp/bugs/browser/bugtask.py (+6/-130) lib/lp/bugs/browser/configure.zcml (+21/-43) lib/lp/bugs/browser/tests/bug-views.txt (+2/-2) lib/lp/bugs/browser/tests/bugtask-edit-views.txt (+13/-13) lib/lp/bugs/configure.zcml (+0/-13) lib/lp/bugs/doc/bugtask.txt (+1/-77) lib/lp/bugs/doc/displaying-bugs-and-tasks.txt (+0/-17) lib/lp/bugs/interfaces/bug.py (+0/-5) lib/lp/bugs/interfaces/bugtask.py (+0/-11) lib/lp/bugs/model/bug.py (+0/-11) lib/lp/bugs/model/bugtask.py (+4/-67) lib/lp/bugs/templates/bugtask-index.pt (+0/-1) |
||||
To merge this branch: | bzr merge lp:~wgrant/launchpad/delete-nullbugtask | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Launchpad code reviewers | Pending | ||
Review via email: mp+53367@code.launchpad.net |
Commit message
Remove NullBugTask.
Description of the change
This branch removes NullBugTask's final callsite, using determine_target in validate_
With that gone, NullBugTask and its tests have also been deleted.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/bugs/browser/bugnomination.py' |
2 | --- lib/lp/bugs/browser/bugnomination.py 2011-02-02 15:43:31 +0000 |
3 | +++ lib/lp/bugs/browser/bugnomination.py 2011-03-15 04:26:27 +0000 |
4 | @@ -15,10 +15,7 @@ |
5 | |
6 | import pytz |
7 | from zope.component import getUtility |
8 | -from zope.publisher.interfaces import ( |
9 | - implements, |
10 | - NotFound, |
11 | - ) |
12 | +from zope.publisher.interfaces import implements |
13 | |
14 | from canonical.launchpad import _ |
15 | from canonical.launchpad.webapp import ( |
16 | @@ -41,7 +38,6 @@ |
17 | IBugNomination, |
18 | IBugNominationForm, |
19 | ) |
20 | -from lp.bugs.interfaces.bugtask import INullBugTask |
21 | from lp.bugs.interfaces.cve import ICveSet |
22 | |
23 | |
24 | @@ -65,10 +61,6 @@ |
25 | LaunchpadFormView.__init__(self, context, request) |
26 | |
27 | def initialize(self): |
28 | - if INullBugTask.providedBy(self.current_bugtask): |
29 | - # It shouldn't be possible to nominate a bug that hasn't |
30 | - # been reported yet. |
31 | - raise NotFound(self.current_bugtask, '+nominate', self.request) |
32 | LaunchpadFormView.initialize(self) |
33 | # Update the submit label based on the user's permission. |
34 | submit_action = self.__class__.actions.byname['actions.submit'] |
35 | |
36 | === modified file 'lib/lp/bugs/browser/bugtask.py' |
37 | --- lib/lp/bugs/browser/bugtask.py 2011-03-10 16:15:57 +0000 |
38 | +++ lib/lp/bugs/browser/bugtask.py 2011-03-15 04:26:27 +0000 |
39 | @@ -236,7 +236,6 @@ |
40 | IDistroSeriesBugTask, |
41 | IFrontPageBugTaskSearch, |
42 | INominationsReviewTableBatchNavigator, |
43 | - INullBugTask, |
44 | IPersonBugTaskSearch, |
45 | IProductSeriesBugTask, |
46 | IRemoveQuestionFromBugTaskForm, |
47 | @@ -490,7 +489,7 @@ |
48 | """Return the IBugTask for this name in this context. |
49 | |
50 | If the bug has been reported, but not in this specific context, a |
51 | - NullBugTask will be returned. |
52 | + redirect to the default context will be returned. |
53 | |
54 | Raises NotFoundError if no bug with the given name is found. |
55 | |
56 | @@ -514,59 +513,15 @@ |
57 | # Security proxy this object on the way out. |
58 | return getUtility(IBugTaskSet).get(bugtask.id) |
59 | |
60 | - # If we've come this far, it means that no actual task exists in this |
61 | - # context, so we'll return a null bug task. This makes it possible to, |
62 | - # for example, return a bug page for a context in which the bug hasn't |
63 | - # yet been reported. |
64 | - if IProduct.providedBy(context): |
65 | - null_bugtask = bug.getNullBugTask(product=context) |
66 | - elif IProductSeries.providedBy(context): |
67 | - null_bugtask = bug.getNullBugTask(productseries=context) |
68 | - elif IDistribution.providedBy(context): |
69 | - null_bugtask = bug.getNullBugTask(distribution=context) |
70 | - elif IDistributionSourcePackage.providedBy(context): |
71 | - null_bugtask = bug.getNullBugTask( |
72 | - distribution=context.distribution, |
73 | - sourcepackagename=context.sourcepackagename) |
74 | - elif IDistroSeries.providedBy(context): |
75 | - null_bugtask = bug.getNullBugTask(distroseries=context) |
76 | - elif ISourcePackage.providedBy(context): |
77 | - null_bugtask = bug.getNullBugTask( |
78 | - distroseries=context.distroseries, |
79 | - sourcepackagename=context.sourcepackagename) |
80 | - else: |
81 | - raise TypeError( |
82 | - "Unknown context type for bug task: %s" % repr(context)) |
83 | - |
84 | - return null_bugtask |
85 | + # If we've come this far, there's no task for the requested |
86 | + # context. Redirect to one that exists. |
87 | + return self.redirectSubTree(canonical_url(bug.default_bugtask)) |
88 | |
89 | |
90 | class BugTaskNavigation(Navigation): |
91 | """Navigation for the `IBugTask`.""" |
92 | usedfor = IBugTask |
93 | |
94 | - def traverse(self, name): |
95 | - """Traverse the `IBugTask`.""" |
96 | - # Are we traversing to the view or edit status page of the |
97 | - # bugtask? If so, and the task actually exists, return the |
98 | - # appropriate page. If the task doesn't yet exist (i.e. it's a |
99 | - # NullBugTask), then return a 404. In other words, the URL: |
100 | - # |
101 | - # /products/foo/+bug/1/+viewstatus |
102 | - # |
103 | - # will return the +viewstatus page if bug 1 has actually been |
104 | - # reported in "foo". If bug 1 has not yet been reported in "foo", |
105 | - # a 404 will be returned. |
106 | - if name not in ("+viewstatus", "+editstatus"): |
107 | - # You're going in the wrong direction. |
108 | - return None |
109 | - if INullBugTask.providedBy(self.context): |
110 | - # The bug has not been reported in this context. |
111 | - return None |
112 | - # Yes! The bug has been reported in this context. |
113 | - return getMultiAdapter((self.context, self.request), |
114 | - name=(name + "-page")) |
115 | - |
116 | @stepthrough('attachments') |
117 | def traverse_attachments(self, name): |
118 | """traverse to an attachment by id.""" |
119 | @@ -655,13 +610,8 @@ |
120 | |
121 | @property |
122 | def page_title(self): |
123 | - bugtask = self.context |
124 | - if INullBugTask.providedBy(bugtask): |
125 | - heading = 'Bug #%s is not in %s' % ( |
126 | - bugtask.bug.id, bugtask.bugtargetdisplayname) |
127 | - else: |
128 | - heading = 'Bug #%s in %s' % ( |
129 | - bugtask.bug.id, bugtask.bugtargetdisplayname) |
130 | + heading = 'Bug #%s in %s' % ( |
131 | + self.context.bug.id, self.context.bugtargetdisplayname) |
132 | return smartquote('%s: "%s"') % (heading, self.context.bug.title) |
133 | |
134 | @property |
135 | @@ -698,12 +648,6 @@ |
136 | # See render() for how this flag is used. |
137 | self._redirecting_to_bug_list = False |
138 | |
139 | - # If the bug is not reported in this context, redirect |
140 | - # to the default bug task. |
141 | - if not self.isReportedInContext(): |
142 | - self.request.response.redirect( |
143 | - canonical_url(self.context.bug.default_bugtask)) |
144 | - |
145 | self.bug_title_edit_widget = TextLineEditorWidget( |
146 | bug, IBug['title'], "Edit this summary", 'h1', |
147 | edit_url=canonical_url(self.context, view_name='+edit')) |
148 | @@ -741,69 +685,6 @@ |
149 | series.bugtargetdisplayname) |
150 | self.request.response.redirect(canonical_url(self.context)) |
151 | |
152 | - def reportBugInContext(self): |
153 | - """Report the bug affects the current context.""" |
154 | - fake_task = self.context |
155 | - if self.request.form.get("reportbug"): |
156 | - if self.isReportedInContext(): |
157 | - self.notices.append( |
158 | - "The bug is already reported in this context.") |
159 | - return |
160 | - # The user has requested that the bug be reported in this |
161 | - # context. |
162 | - if IUpstreamBugTask.providedBy(fake_task): |
163 | - # Create a real upstream task in this context. |
164 | - real_task = fake_task.bug.addTask( |
165 | - getUtility(ILaunchBag).user, fake_task.product) |
166 | - elif IDistroBugTask.providedBy(fake_task): |
167 | - # Create a real distro bug task in this context. |
168 | - real_task = fake_task.bug.addTask( |
169 | - getUtility(ILaunchBag).user, fake_task.target) |
170 | - elif IDistroSeriesBugTask.providedBy(fake_task): |
171 | - self._nominateBug(fake_task.distroseries) |
172 | - return |
173 | - elif IProductSeriesBugTask.providedBy(fake_task): |
174 | - self._nominateBug(fake_task.productseries) |
175 | - return |
176 | - else: |
177 | - raise TypeError( |
178 | - "Unknown bug task type: %s" % repr(fake_task)) |
179 | - |
180 | - self.context = real_task |
181 | - |
182 | - # Add an appropriate feedback message |
183 | - self.notices.append("Thank you for your bug report.") |
184 | - |
185 | - def isReportedInContext(self): |
186 | - """Is the bug reported in this context? Returns True or False. |
187 | - |
188 | - It considers a nominated bug to be reported. |
189 | - |
190 | - This is particularly useful for views that may render a |
191 | - NullBugTask. |
192 | - """ |
193 | - if self.context.id is not None: |
194 | - # Fast path for real bugtasks: they have a DB id. |
195 | - return True |
196 | - params = BugTaskSearchParams(user=self.user, bug=self.context.bug) |
197 | - matching_bugtasks = self.context.target.searchTasks(params) |
198 | - if self.context.productseries is not None: |
199 | - nomination_target = self.context.productseries |
200 | - elif self.context.distroseries is not None: |
201 | - nomination_target = self.context.distroseries |
202 | - else: |
203 | - nomination_target = None |
204 | - if nomination_target is not None: |
205 | - try: |
206 | - nomination = self.context.bug.getNominationFor( |
207 | - nomination_target) |
208 | - except NotFoundError: |
209 | - nomination = None |
210 | - else: |
211 | - nomination = None |
212 | - |
213 | - return nomination is not None or matching_bugtasks.count() > 0 |
214 | - |
215 | def isSeriesTargetableContext(self): |
216 | """Is the context something that supports Series targeting? |
217 | |
218 | @@ -1744,17 +1625,12 @@ |
219 | The assignee is included. |
220 | """ |
221 | bugtask = self.context |
222 | - |
223 | - if INullBugTask.providedBy(bugtask): |
224 | - return u"Not reported in %s" % bugtask.bugtargetname |
225 | - |
226 | assignee = bugtask.assignee |
227 | status = bugtask.status |
228 | status_title = status.title.capitalize() |
229 | |
230 | if not assignee: |
231 | return status_title + ' (unassigned)' |
232 | - |
233 | assignee_html = PersonFormatterAPI(assignee).link('+assignedbugs') |
234 | |
235 | if status in (BugTaskStatus.INVALID, |
236 | |
237 | === modified file 'lib/lp/bugs/browser/configure.zcml' |
238 | --- lib/lp/bugs/browser/configure.zcml 2011-03-11 21:31:10 +0000 |
239 | +++ lib/lp/bugs/browser/configure.zcml 2011-03-15 04:26:27 +0000 |
240 | @@ -637,35 +637,27 @@ |
241 | class="lp.bugs.browser.bugalsoaffects.BugAlsoAffectsDistroMetaView" |
242 | permission="launchpad.AnyPerson"/> |
243 | <browser:page |
244 | - name="+editstatus-page" |
245 | - for="lp.bugs.interfaces.bugtask.IUpstreamBugTask" |
246 | - class="lp.bugs.browser.bugtask.BugTaskEditView" |
247 | - permission="launchpad.Edit" |
248 | - template="../templates/bugtask-edit.pt"> |
249 | - </browser:page> |
250 | - <browser:page |
251 | - name="+edit-form" |
252 | - for="lp.bugs.interfaces.bugtask.IUpstreamBugTask" |
253 | - class="lp.bugs.browser.bugtask.BugTaskEditView" |
254 | - permission="launchpad.Edit" |
255 | - template="../templates/bugtask-edit-form.pt"> |
256 | - </browser:page> |
257 | - <browser:page |
258 | - name="+editstatus-page" |
259 | - for="lp.bugs.interfaces.bugtask.IProductSeriesBugTask" |
260 | - class="lp.bugs.browser.bugtask.BugTaskEditView" |
261 | - permission="launchpad.Edit" |
262 | - template="../templates/bugtask-edit.pt"> |
263 | - </browser:page> |
264 | - <browser:page |
265 | - name="+edit-form" |
266 | - for="lp.bugs.interfaces.bugtask.IProductSeriesBugTask" |
267 | - class="lp.bugs.browser.bugtask.BugTaskEditView" |
268 | - permission="launchpad.Edit" |
269 | - template="../templates/bugtask-edit-form.pt"> |
270 | - </browser:page> |
271 | - <browser:page |
272 | - name="+viewstatus-page" |
273 | + name="+edit-form" |
274 | + for="lp.bugs.interfaces.bugtask.IUpstreamBugTask" |
275 | + class="lp.bugs.browser.bugtask.BugTaskEditView" |
276 | + permission="launchpad.Edit" |
277 | + template="../templates/bugtask-edit-form.pt"> |
278 | + </browser:page> |
279 | + <browser:page |
280 | + name="+edit-form" |
281 | + for="lp.bugs.interfaces.bugtask.IProductSeriesBugTask" |
282 | + class="lp.bugs.browser.bugtask.BugTaskEditView" |
283 | + permission="launchpad.Edit" |
284 | + template="../templates/bugtask-edit-form.pt"> |
285 | + </browser:page> |
286 | + <browser:page |
287 | + name="+editstatus" |
288 | + for="lp.bugs.interfaces.bugtask.IBugTask" |
289 | + class="lp.bugs.browser.bugtask.BugTaskEditView" |
290 | + permission="launchpad.Edit" |
291 | + template="../templates/bugtask-edit.pt"/> |
292 | + <browser:page |
293 | + name="+viewstatus" |
294 | for="lp.bugs.interfaces.bugtask.IBugTask" |
295 | class="lp.bugs.browser.bugtask.BugTaskStatusView" |
296 | permission="launchpad.View" |
297 | @@ -680,13 +672,6 @@ |
298 | for="lp.bugs.interfaces.bugtask.IDistroBugTask" |
299 | name="+index"/> |
300 | <browser:page |
301 | - name="+editstatus-page" |
302 | - for="lp.bugs.interfaces.bugtask.IDistroBugTask" |
303 | - class="lp.bugs.browser.bugtask.BugTaskEditView" |
304 | - permission="launchpad.Edit" |
305 | - template="../templates/bugtask-edit.pt"> |
306 | - </browser:page> |
307 | - <browser:page |
308 | name="+edit-form" |
309 | for="lp.bugs.interfaces.bugtask.IDistroBugTask" |
310 | class="lp.bugs.browser.bugtask.BugTaskEditView" |
311 | @@ -697,13 +682,6 @@ |
312 | for="lp.bugs.interfaces.bugtask.IDistroSeriesBugTask" |
313 | name="+index"/> |
314 | <browser:page |
315 | - name="+editstatus-page" |
316 | - for="lp.bugs.interfaces.bugtask.IDistroSeriesBugTask" |
317 | - class="lp.bugs.browser.bugtask.BugTaskEditView" |
318 | - permission="launchpad.Edit" |
319 | - template="../templates/bugtask-edit.pt"> |
320 | - </browser:page> |
321 | - <browser:page |
322 | name="+edit-form" |
323 | for="lp.bugs.interfaces.bugtask.IDistroSeriesBugTask" |
324 | class="lp.bugs.browser.bugtask.BugTaskEditView" |
325 | |
326 | === modified file 'lib/lp/bugs/browser/tests/bug-views.txt' |
327 | --- lib/lp/bugs/browser/tests/bug-views.txt 2011-02-15 09:31:20 +0000 |
328 | +++ lib/lp/bugs/browser/tests/bug-views.txt 2011-03-15 04:26:27 +0000 |
329 | @@ -777,7 +777,7 @@ |
330 | ... 'testproduct.actions.save': 'Save Changes', |
331 | ... }) |
332 | >>> view = getMultiAdapter( |
333 | - ... (bug.bugtasks[0], request), name="+editstatus-page") |
334 | + ... (bug.bugtasks[0], request), name="+editstatus") |
335 | >>> view.initialize() |
336 | |
337 | >>> view = getMultiAdapter( |
338 | @@ -833,7 +833,7 @@ |
339 | ... 'testproduct.actions.save': 'Save Changes', |
340 | ... }) |
341 | >>> view = getMultiAdapter( |
342 | - ... (bug.bugtasks[0], request), name="+editstatus-page") |
343 | + ... (bug.bugtasks[0], request), name="+editstatus") |
344 | >>> view.initialize() |
345 | |
346 | >>> view = getMultiAdapter( |
347 | |
348 | === modified file 'lib/lp/bugs/browser/tests/bugtask-edit-views.txt' |
349 | --- lib/lp/bugs/browser/tests/bugtask-edit-views.txt 2010-10-18 22:24:59 +0000 |
350 | +++ lib/lp/bugs/browser/tests/bugtask-edit-views.txt 2011-03-15 04:26:27 +0000 |
351 | @@ -29,7 +29,7 @@ |
352 | ... ubuntu_thunderbird_task.sourcepackagename.name} |
353 | >>> request = LaunchpadTestRequest(method='POST', form=edit_form) |
354 | >>> edit_view = getMultiAdapter( |
355 | - ... (ubuntu_thunderbird_task, request), name='+editstatus-page') |
356 | + ... (ubuntu_thunderbird_task, request), name='+editstatus') |
357 | >>> edit_view.initialize() |
358 | >>> ubuntu_thunderbird_task.status.title |
359 | 'In Progress' |
360 | @@ -50,7 +50,7 @@ |
361 | >>> edit_form['ubuntu_thunderbird.sourcepackagename'] = u'linux-2.6.12' |
362 | >>> request = LaunchpadTestRequest(method='POST', form=edit_form) |
363 | >>> edit_view = getMultiAdapter( |
364 | - ... (ubuntu_thunderbird_task, request), name='+editstatus-page') |
365 | + ... (ubuntu_thunderbird_task, request), name='+editstatus') |
366 | >>> edit_view.initialize() |
367 | >>> ubuntu_thunderbird_task.sourcepackagename.name |
368 | u'linux-source-2.6.15' |
369 | @@ -73,7 +73,7 @@ |
370 | >>> edit_form['ubuntu_thunderbird.sourcepackagename'] = u'no-such-package' |
371 | >>> request = LaunchpadTestRequest(form=edit_form, method='POST') |
372 | >>> edit_view = getMultiAdapter( |
373 | - ... (ubuntu_thunderbird_task, request), name='+editstatus-page') |
374 | + ... (ubuntu_thunderbird_task, request), name='+editstatus') |
375 | >>> edit_view.initialize() |
376 | >>> for error in edit_view.errors: |
377 | ... print error |
378 | @@ -112,7 +112,7 @@ |
379 | ... } |
380 | >>> request = LaunchpadTestRequest(form=edit_form, method='POST') |
381 | >>> edit_view = getMultiAdapter( |
382 | - ... (ubuntu_task, request), name='+editstatus-page') |
383 | + ... (ubuntu_task, request), name='+editstatus') |
384 | >>> edit_view.initialize() |
385 | >>> for error in edit_view.errors: |
386 | ... print error |
387 | @@ -144,7 +144,7 @@ |
388 | ... } |
389 | >>> request = LaunchpadTestRequest(form=edit_form, method='POST') |
390 | >>> edit_view = getMultiAdapter( |
391 | - ... (ubuntu_grumpy_task, request), name='+editstatus-page') |
392 | + ... (ubuntu_grumpy_task, request), name='+editstatus') |
393 | >>> edit_view.initialize() |
394 | >>> for error in edit_view.errors: |
395 | ... print error |
396 | @@ -155,7 +155,7 @@ |
397 | |
398 | == Edit the Product == |
399 | |
400 | -+editstatus-page allows a bug to be retargeted to another product. |
401 | ++editstatus allows a bug to be retargeted to another product. |
402 | |
403 | >>> bug_seven = getUtility(IBugSet).get(7) |
404 | >>> product_task = bug_seven.bugtasks[0] |
405 | @@ -173,7 +173,7 @@ |
406 | ... } |
407 | >>> request = LaunchpadTestRequest(form=edit_form, method='POST') |
408 | >>> edit_view = getMultiAdapter( |
409 | - ... (product_task, request), name='+editstatus-page') |
410 | + ... (product_task, request), name='+editstatus') |
411 | >>> edit_view.initialize() |
412 | >>> [str(error) for error in edit_view.errors] |
413 | [] |
414 | @@ -193,7 +193,7 @@ |
415 | ... } |
416 | >>> request = LaunchpadTestRequest(form=edit_form, method='POST') |
417 | >>> edit_view = getMultiAdapter( |
418 | - ... (product_task, request), name='+editstatus-page') |
419 | + ... (product_task, request), name='+editstatus') |
420 | >>> edit_view.initialize() |
421 | >>> for error in edit_view.errors: |
422 | ... print error |
423 | @@ -235,7 +235,7 @@ |
424 | ... 'thunderbird.importance': 'Critical', |
425 | ... 'thunderbird.bugwatch': '6'}) |
426 | >>> edit_view = getMultiAdapter( |
427 | - ... (thunderbird_task, request), name='+editstatus-page') |
428 | + ... (thunderbird_task, request), name='+editstatus') |
429 | >>> edit_view.initialize() |
430 | >>> thunderbird_task.bugwatch == bugzilla_watch |
431 | True |
432 | @@ -251,7 +251,7 @@ |
433 | ... 'thunderbird.actions.save': 'Save Changes', |
434 | ... 'thunderbird.bugwatch-empty-marker': '1'}) |
435 | >>> edit_view = getMultiAdapter( |
436 | - ... (thunderbird_task, request), name='+editstatus-page') |
437 | + ... (thunderbird_task, request), name='+editstatus') |
438 | >>> edit_view.initialize() |
439 | >>> thunderbird_task.bugwatch is None |
440 | True |
441 | @@ -280,7 +280,7 @@ |
442 | >>> request = LaunchpadTestRequest() |
443 | >>> ubuntu_task = getUtility(IBugTaskSet).get(17) |
444 | >>> bugtask_edit_view = getMultiAdapter( |
445 | - ... (ubuntu_task, request), name="+editstatus-page") |
446 | + ... (ubuntu_task, request), name="+editstatus") |
447 | >>> bugtask_edit_view.initialize() |
448 | |
449 | >>> IInputWidget.providedBy(bugtask_edit_view.widgets['milestone']) |
450 | @@ -293,7 +293,7 @@ |
451 | >>> login("no-priv@canonical.com") |
452 | |
453 | >>> bugtask_edit_view = getMultiAdapter( |
454 | - ... (ubuntu_task, request), name="+editstatus-page") |
455 | + ... (ubuntu_task, request), name="+editstatus") |
456 | >>> bugtask_edit_view.initialize() |
457 | |
458 | >>> isinstance(bugtask_edit_view.widgets['milestone'], ItemDisplayWidget) |
459 | @@ -312,7 +312,7 @@ |
460 | Unlike before, no-priv can now edit the milestone. |
461 | |
462 | >>> bugtask_edit_view = getMultiAdapter( |
463 | - ... (ubuntu_task, request), name="+editstatus-page") |
464 | + ... (ubuntu_task, request), name="+editstatus") |
465 | >>> bugtask_edit_view.initialize() |
466 | |
467 | >>> IInputWidget.providedBy(bugtask_edit_view.widgets['milestone']) |
468 | |
469 | === modified file 'lib/lp/bugs/configure.zcml' |
470 | --- lib/lp/bugs/configure.zcml 2011-03-08 01:56:34 +0000 |
471 | +++ lib/lp/bugs/configure.zcml 2011-03-15 04:26:27 +0000 |
472 | @@ -302,18 +302,6 @@ |
473 | factory="lp.bugs.browser.bugcomment.BugCommentBreadcrumb" |
474 | permission="zope.Public"/> |
475 | |
476 | - <!-- NullBugTask --> |
477 | - |
478 | - <class |
479 | - class="lp.bugs.model.bugtask.NullBugTask"> |
480 | - <require |
481 | - permission="launchpad.View" |
482 | - interface="lp.bugs.interfaces.bugtask.IBugTask"/> |
483 | - <require |
484 | - permission="launchpad.Edit" |
485 | - set_schema="lp.bugs.interfaces.bugtask.IBugTask"/> |
486 | - </class> |
487 | - |
488 | <!-- BugTaskSearchParams --> |
489 | <class |
490 | class="lp.bugs.interfaces.bugtask.BugTaskSearchParams"> |
491 | @@ -691,7 +679,6 @@ |
492 | getDirectSubscribers |
493 | getDirectSubscriptions |
494 | getIndirectSubscribers |
495 | - getNullBugTask |
496 | is_complete |
497 | official_tags |
498 | who_made_private |
499 | |
500 | === modified file 'lib/lp/bugs/doc/bugtask.txt' |
501 | --- lib/lp/bugs/doc/bugtask.txt 2011-02-14 11:04:09 +0000 |
502 | +++ lib/lp/bugs/doc/bugtask.txt 2011-03-15 04:26:27 +0000 |
503 | @@ -732,83 +732,6 @@ |
504 | False |
505 | |
506 | |
507 | -== Null Bug Tasks == |
508 | - |
509 | -Sometimes we need to be able to render a page for a bug in a context, |
510 | -when the bug hasn't actually been filed yet in that context. For cases |
511 | -like these, use the NullBugTask object. |
512 | - |
513 | - |
514 | - >>> from lp.bugs.interfaces.bugtask import INullBugTask |
515 | - >>> netapplet = productset.get(11) |
516 | - >>> null_bugtask = bug_one.getNullBugTask(product=netapplet) |
517 | - >>> verifyObject(INullBugTask, null_bugtask) |
518 | - True |
519 | - >>> IUpstreamBugTask.providedBy(null_bugtask) |
520 | - True |
521 | - |
522 | - >>> null_bugtask.id is None |
523 | - True |
524 | - >>> null_bugtask.title |
525 | - u'Bug #1 is not in NetApplet: "Firefox does not support SVG"' |
526 | - >>> null_bugtask.product is netapplet |
527 | - True |
528 | - >>> null_bugtask.bug == bug_one |
529 | - True |
530 | - >>> null_bugtask.datecreated is None |
531 | - True |
532 | - >>> null_bugtask.date_assigned is None |
533 | - True |
534 | - >>> null_bugtask.age is None |
535 | - True |
536 | - >>> null_bugtask.status is None |
537 | - True |
538 | - >>> null_bugtask.sourcepackagename is None |
539 | - True |
540 | - >>> null_bugtask.distribution is None |
541 | - True |
542 | - >>> null_bugtask.distroseries is None |
543 | - True |
544 | - >>> null_bugtask.milestone is None |
545 | - True |
546 | - >>> null_bugtask.importance is None |
547 | - True |
548 | - >>> null_bugtask.assignee is None |
549 | - True |
550 | - >>> null_bugtask.bugwatch is None |
551 | - True |
552 | - >>> null_bugtask.owner is None |
553 | - True |
554 | - >>> null_bugtask.target == netapplet |
555 | - True |
556 | - >>> null_bugtask.bugtargetname |
557 | - u'netapplet' |
558 | - >>> expected_related_task_ids = [ |
559 | - ... task.id for task in null_bugtask.related_tasks] |
560 | - >>> actual_related_task_ids = [task.id for task in bug_one.bugtasks] |
561 | - >>> expected_related_task_ids.sort() |
562 | - >>> actual_related_task_ids.sort() |
563 | - >>> expected_related_task_ids == actual_related_task_ids |
564 | - True |
565 | - |
566 | - >>> null_bugtask.conjoined_slave is None |
567 | - True |
568 | - >>> null_bugtask.conjoined_master is None |
569 | - True |
570 | - |
571 | -The astute reader will have noticed that NullBugTask automatically |
572 | -"marked" itself as providing the correct IBugTask interface. Let's see |
573 | -two more examples: |
574 | - |
575 | - >>> ubuntu_null_bugtask = bug_one.getNullBugTask(distribution=ubuntu) |
576 | - >>> IDistroBugTask.providedBy(ubuntu_null_bugtask) |
577 | - True |
578 | - |
579 | - >>> warty_null_bugtask = bug_one.getNullBugTask(distroseries=warty) |
580 | - >>> IDistroSeriesBugTask.providedBy(warty_null_bugtask) |
581 | - True |
582 | - |
583 | - |
584 | = Bug Privacy = |
585 | |
586 | A bug is either private or public. Private bugs are only visible (e.g. in search |
587 | @@ -1080,6 +1003,7 @@ |
588 | the latter is not exposed in `IBugTask`, so the `bugtargetdisplayname` |
589 | is used here. |
590 | |
591 | + >>> netapplet = productset.get(11) |
592 | >>> upstream_task = bugtaskset.createTask( |
593 | ... bug=bug_one, product=netapplet, owner=mark, |
594 | ... status=STATUS_NEW, importance=IMPORTANCE_MEDIUM) |
595 | |
596 | === modified file 'lib/lp/bugs/doc/displaying-bugs-and-tasks.txt' |
597 | --- lib/lp/bugs/doc/displaying-bugs-and-tasks.txt 2010-11-01 15:46:48 +0000 |
598 | +++ lib/lp/bugs/doc/displaying-bugs-and-tasks.txt 2011-03-15 04:26:27 +0000 |
599 | @@ -150,17 +150,6 @@ |
600 | >>> render_bugtask_status(test_task) |
601 | u'Fix released, assigned to ...Foo Bar...' |
602 | |
603 | -This code also works for null bug tasks: |
604 | - |
605 | - >>> from lp.bugs.model.bug import Bug |
606 | - >>> from lp.bugs.model.bugtask import NullBugTask |
607 | - >>> from lp.registry.model.product import Product |
608 | - >>> bug_one = Bug.get(1) |
609 | - >>> netapplet = Product.selectOneBy(name="netapplet") |
610 | - >>> null_bugtask = NullBugTask(bug=bug_one, product=netapplet) |
611 | - >>> render_bugtask_status(null_bugtask) |
612 | - u'Not reported in netapplet' |
613 | - |
614 | Lastly, some cleanup: |
615 | |
616 | >>> test_task.transitionToStatus( |
617 | @@ -206,9 +195,3 @@ |
618 | |
619 | >>> related_task.transitionToStatus( |
620 | ... ORIGINAL_STATUS, getUtility(ILaunchBag).user) |
621 | - |
622 | -Null tasks are also supported: |
623 | - |
624 | - >>> render_bugtask_status_elsewhere(null_bugtask) |
625 | - 'filed in 3 other places' |
626 | - |
627 | |
628 | === modified file 'lib/lp/bugs/interfaces/bug.py' |
629 | --- lib/lp/bugs/interfaces/bug.py 2011-03-08 01:56:34 +0000 |
630 | +++ lib/lp/bugs/interfaces/bug.py 2011-03-15 04:26:27 +0000 |
631 | @@ -721,11 +721,6 @@ |
632 | returned rows. The step parameter in each slice is ignored. |
633 | """ |
634 | |
635 | - def getNullBugTask(product=None, productseries=None, |
636 | - sourcepackagename=None, distribution=None, |
637 | - distroseries=None): |
638 | - """Create an INullBugTask and return it for the given parameters.""" |
639 | - |
640 | @operation_parameters( |
641 | target=Reference(schema=Interface, title=_('Target'))) |
642 | @call_with(owner=REQUEST_USER) |
643 | |
644 | === modified file 'lib/lp/bugs/interfaces/bugtask.py' |
645 | --- lib/lp/bugs/interfaces/bugtask.py 2011-03-07 21:05:12 +0000 |
646 | +++ lib/lp/bugs/interfaces/bugtask.py 2011-03-15 04:26:27 +0000 |
647 | @@ -30,7 +30,6 @@ |
648 | 'IDistroSeriesBugTask', |
649 | 'IFrontPageBugTaskSearch', |
650 | 'INominationsReviewTableBatchNavigator', |
651 | - 'INullBugTask', |
652 | 'IPersonBugTaskSearch', |
653 | 'IProductSeriesBugTask', |
654 | 'IRemoveQuestionFromBugTaskForm', |
655 | @@ -839,16 +838,6 @@ |
656 | IBugWatch['bugtasks'].value_type.schema = IBugTask |
657 | |
658 | |
659 | -class INullBugTask(IBugTask): |
660 | - """A marker interface for an IBugTask that doesn't exist in a context. |
661 | - |
662 | - An INullBugTask is useful when wanting to view a bug in a context |
663 | - where that bug hasn't yet been reported. This might happen, for |
664 | - example, when searching to see if a bug you want to report has |
665 | - already been filed and finding matching reports that don't yet |
666 | - have tasks reported in your context. |
667 | - """ |
668 | - |
669 | UPSTREAM_STATUS_VOCABULARY = SimpleVocabulary( |
670 | [SimpleTerm( |
671 | "pending_bugwatch", |
672 | |
673 | === modified file 'lib/lp/bugs/model/bug.py' |
674 | --- lib/lp/bugs/model/bug.py 2011-03-08 01:56:34 +0000 |
675 | +++ lib/lp/bugs/model/bug.py 2011-03-15 04:26:27 +0000 |
676 | @@ -168,7 +168,6 @@ |
677 | BugTask, |
678 | bugtask_sort_key, |
679 | get_bug_privacy_filter, |
680 | - NullBugTask, |
681 | ) |
682 | from lp.bugs.model.bugwatch import BugWatch |
683 | from lp.bugs.model.structuralsubscription import ( |
684 | @@ -1429,16 +1428,6 @@ |
685 | need_validity=True)) |
686 | return DecoratedResultSet(result, pre_iter_hook=eager_load_owners) |
687 | |
688 | - def getNullBugTask(self, product=None, productseries=None, |
689 | - sourcepackagename=None, distribution=None, |
690 | - distroseries=None): |
691 | - """See `IBug`.""" |
692 | - return NullBugTask(bug=self, product=product, |
693 | - productseries=productseries, |
694 | - sourcepackagename=sourcepackagename, |
695 | - distribution=distribution, |
696 | - distroseries=distroseries) |
697 | - |
698 | def addNomination(self, owner, target): |
699 | """See `IBug`.""" |
700 | if not self.canBeNominatedFor(target): |
701 | |
702 | === modified file 'lib/lp/bugs/model/bugtask.py' |
703 | --- lib/lp/bugs/model/bugtask.py 2011-03-11 03:06:43 +0000 |
704 | +++ lib/lp/bugs/model/bugtask.py 2011-03-15 04:26:27 +0000 |
705 | @@ -13,7 +13,6 @@ |
706 | 'BugTaskMixin', |
707 | 'BugTask', |
708 | 'BugTaskSet', |
709 | - 'NullBugTask', |
710 | 'bugtask_sort_key', |
711 | 'determine_target', |
712 | 'get_bug_privacy_filter', |
713 | @@ -119,7 +118,6 @@ |
714 | IDistroSeriesBugTask, |
715 | IllegalRelatedBugTasksParams, |
716 | IllegalTarget, |
717 | - INullBugTask, |
718 | IProductSeriesBugTask, |
719 | IUpstreamBugTask, |
720 | RESOLVED_BUGTASK_STATUSES, |
721 | @@ -374,68 +372,6 @@ |
722 | return sorted(result, key=pillar_sort_key) |
723 | |
724 | |
725 | -class NullBugTask(BugTaskMixin): |
726 | - """A null object for IBugTask. |
727 | - |
728 | - This class is used, for example, to be able to render a URL like: |
729 | - |
730 | - /products/evolution/+bug/5 |
731 | - |
732 | - when bug #5 isn't yet reported in evolution. |
733 | - """ |
734 | - implements(INullBugTask) |
735 | - |
736 | - def __init__(self, bug, product=None, productseries=None, |
737 | - sourcepackagename=None, distribution=None, |
738 | - distroseries=None): |
739 | - """Initialize a NullBugTask.""" |
740 | - self.id = None |
741 | - self.bug = bug |
742 | - self.product = product |
743 | - self.productseries = productseries |
744 | - self.sourcepackagename = sourcepackagename |
745 | - self.distribution = distribution |
746 | - self.distroseries = distroseries |
747 | - |
748 | - # Mark the task with the correct interface, depending on its |
749 | - # context. |
750 | - if self.product: |
751 | - alsoProvides(self, IUpstreamBugTask) |
752 | - elif self.distribution: |
753 | - alsoProvides(self, IDistroBugTask) |
754 | - elif self.distroseries: |
755 | - alsoProvides(self, IDistroSeriesBugTask) |
756 | - elif self.productseries: |
757 | - alsoProvides(self, IProductSeriesBugTask) |
758 | - else: |
759 | - raise AssertionError('Unknown NullBugTask: %r.' % self) |
760 | - |
761 | - # Make us provide the interface by setting all required attributes |
762 | - # to None, and define the methods as raising NotImplementedError. |
763 | - # The attributes are set to None because it doesn't make |
764 | - # sense for these attributes to have a value when there is no |
765 | - # real task there. (In fact, it may make sense for these |
766 | - # values to be non-null, but I haven't yet found a use case |
767 | - # for it, and I don't think there's any point on designing for |
768 | - # that until we've encountered one.) |
769 | - def this_is_a_null_bugtask_method(*args, **kwargs): |
770 | - raise NotImplementedError |
771 | - |
772 | - for name, spec in INullBugTask.namesAndDescriptions(True): |
773 | - if not hasattr(self, name): |
774 | - if IMethod.providedBy(spec): |
775 | - value = this_is_a_null_bugtask_method |
776 | - else: |
777 | - value = None |
778 | - setattr(self, name, value) |
779 | - |
780 | - @property |
781 | - def title(self): |
782 | - """See `IBugTask`.""" |
783 | - return 'Bug #%s is not in %s: "%s"' % ( |
784 | - self.bug.id, self.bugtargetdisplayname, self.bug.title) |
785 | - |
786 | - |
787 | def BugTaskToBugAdapter(bugtask): |
788 | """Adapt an IBugTask to an IBug.""" |
789 | return bugtask.bug |
790 | @@ -467,9 +403,10 @@ |
791 | else: |
792 | target_params[attr[:-2]] = getUtility(utility_iface).get(value) |
793 | |
794 | - # Use a NullBugTask to determine the new target. |
795 | - nulltask = NullBugTask(self.bug, **target_params) |
796 | - self.updateTargetNameCache(nulltask.target) |
797 | + # Update the target name cache with the potential new target. The |
798 | + # attribute changes haven't been made yet, so we need to calculate the |
799 | + # target manually. |
800 | + self.updateTargetNameCache(determine_target(**target_params)) |
801 | |
802 | return value |
803 | |
804 | |
805 | === modified file 'lib/lp/bugs/templates/bugtask-index.pt' |
806 | --- lib/lp/bugs/templates/bugtask-index.pt 2011-02-25 22:09:46 +0000 |
807 | +++ lib/lp/bugs/templates/bugtask-index.pt 2011-03-15 04:26:27 +0000 |
808 | @@ -72,7 +72,6 @@ |
809 | <div id="tags-autocomplete"> |
810 | <div id="tags-autocomplete-content"></div> |
811 | </div> |
812 | - <tal:block condition="view/reportBugInContext" /> |
813 | |
814 | <p class="informational message" |
815 | tal:condition="view/notices" |