launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #02954
[Merge] lp:~wgrant/launchpad/delete-nullbugtask into lp:launchpad
William Grant has proposed merging lp:~wgrant/launchpad/delete-nullbugtask into lp:launchpad with lp:~wgrant/launchpad/unuse-nullbugtask as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #365489 in Launchpad itself: "Remove NullBugTask"
https://bugs.launchpad.net/launchpad/+bug/365489
For more details, see:
https://code.launchpad.net/~wgrant/launchpad/delete-nullbugtask/+merge/53369
This branch removes NullBugTask's final callsite, using determine_target in validate_target_attribute instead.
With that gone, NullBugTask and its tests have also been deleted.
--
https://code.launchpad.net/~wgrant/launchpad/delete-nullbugtask/+merge/53369
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/launchpad/delete-nullbugtask into lp:launchpad.
=== modified file 'lib/lp/bugs/configure.zcml'
--- lib/lp/bugs/configure.zcml 2011-03-08 01:56:34 +0000
+++ lib/lp/bugs/configure.zcml 2011-03-15 04:38:22 +0000
@@ -302,18 +302,6 @@
factory="lp.bugs.browser.bugcomment.BugCommentBreadcrumb"
permission="zope.Public"/>
- <!-- NullBugTask -->
-
- <class
- class="lp.bugs.model.bugtask.NullBugTask">
- <require
- permission="launchpad.View"
- interface="lp.bugs.interfaces.bugtask.IBugTask"/>
- <require
- permission="launchpad.Edit"
- set_schema="lp.bugs.interfaces.bugtask.IBugTask"/>
- </class>
-
<!-- BugTaskSearchParams -->
<class
class="lp.bugs.interfaces.bugtask.BugTaskSearchParams">
@@ -691,7 +679,6 @@
getDirectSubscribers
getDirectSubscriptions
getIndirectSubscribers
- getNullBugTask
is_complete
official_tags
who_made_private
=== modified file 'lib/lp/bugs/doc/bugtask.txt'
--- lib/lp/bugs/doc/bugtask.txt 2011-02-14 11:04:09 +0000
+++ lib/lp/bugs/doc/bugtask.txt 2011-03-15 04:38:22 +0000
@@ -732,83 +732,6 @@
False
-== Null Bug Tasks ==
-
-Sometimes we need to be able to render a page for a bug in a context,
-when the bug hasn't actually been filed yet in that context. For cases
-like these, use the NullBugTask object.
-
-
- >>> from lp.bugs.interfaces.bugtask import INullBugTask
- >>> netapplet = productset.get(11)
- >>> null_bugtask = bug_one.getNullBugTask(product=netapplet)
- >>> verifyObject(INullBugTask, null_bugtask)
- True
- >>> IUpstreamBugTask.providedBy(null_bugtask)
- True
-
- >>> null_bugtask.id is None
- True
- >>> null_bugtask.title
- u'Bug #1 is not in NetApplet: "Firefox does not support SVG"'
- >>> null_bugtask.product is netapplet
- True
- >>> null_bugtask.bug == bug_one
- True
- >>> null_bugtask.datecreated is None
- True
- >>> null_bugtask.date_assigned is None
- True
- >>> null_bugtask.age is None
- True
- >>> null_bugtask.status is None
- True
- >>> null_bugtask.sourcepackagename is None
- True
- >>> null_bugtask.distribution is None
- True
- >>> null_bugtask.distroseries is None
- True
- >>> null_bugtask.milestone is None
- True
- >>> null_bugtask.importance is None
- True
- >>> null_bugtask.assignee is None
- True
- >>> null_bugtask.bugwatch is None
- True
- >>> null_bugtask.owner is None
- True
- >>> null_bugtask.target == netapplet
- True
- >>> null_bugtask.bugtargetname
- u'netapplet'
- >>> expected_related_task_ids = [
- ... task.id for task in null_bugtask.related_tasks]
- >>> actual_related_task_ids = [task.id for task in bug_one.bugtasks]
- >>> expected_related_task_ids.sort()
- >>> actual_related_task_ids.sort()
- >>> expected_related_task_ids == actual_related_task_ids
- True
-
- >>> null_bugtask.conjoined_slave is None
- True
- >>> null_bugtask.conjoined_master is None
- True
-
-The astute reader will have noticed that NullBugTask automatically
-"marked" itself as providing the correct IBugTask interface. Let's see
-two more examples:
-
- >>> ubuntu_null_bugtask = bug_one.getNullBugTask(distribution=ubuntu)
- >>> IDistroBugTask.providedBy(ubuntu_null_bugtask)
- True
-
- >>> warty_null_bugtask = bug_one.getNullBugTask(distroseries=warty)
- >>> IDistroSeriesBugTask.providedBy(warty_null_bugtask)
- True
-
-
= Bug Privacy =
A bug is either private or public. Private bugs are only visible (e.g. in search
@@ -1080,6 +1003,7 @@
the latter is not exposed in `IBugTask`, so the `bugtargetdisplayname`
is used here.
+ >>> netapplet = productset.get(11)
>>> upstream_task = bugtaskset.createTask(
... bug=bug_one, product=netapplet, owner=mark,
... status=STATUS_NEW, importance=IMPORTANCE_MEDIUM)
=== modified file 'lib/lp/bugs/doc/displaying-bugs-and-tasks.txt'
--- lib/lp/bugs/doc/displaying-bugs-and-tasks.txt 2010-11-01 15:46:48 +0000
+++ lib/lp/bugs/doc/displaying-bugs-and-tasks.txt 2011-03-15 04:38:22 +0000
@@ -150,17 +150,6 @@
>>> render_bugtask_status(test_task)
u'Fix released, assigned to ...Foo Bar...'
-This code also works for null bug tasks:
-
- >>> from lp.bugs.model.bug import Bug
- >>> from lp.bugs.model.bugtask import NullBugTask
- >>> from lp.registry.model.product import Product
- >>> bug_one = Bug.get(1)
- >>> netapplet = Product.selectOneBy(name="netapplet")
- >>> null_bugtask = NullBugTask(bug=bug_one, product=netapplet)
- >>> render_bugtask_status(null_bugtask)
- u'Not reported in netapplet'
-
Lastly, some cleanup:
>>> test_task.transitionToStatus(
@@ -206,9 +195,3 @@
>>> related_task.transitionToStatus(
... ORIGINAL_STATUS, getUtility(ILaunchBag).user)
-
-Null tasks are also supported:
-
- >>> render_bugtask_status_elsewhere(null_bugtask)
- 'filed in 3 other places'
-
=== modified file 'lib/lp/bugs/interfaces/bug.py'
--- lib/lp/bugs/interfaces/bug.py 2011-03-08 01:56:34 +0000
+++ lib/lp/bugs/interfaces/bug.py 2011-03-15 04:38:22 +0000
@@ -721,11 +721,6 @@
returned rows. The step parameter in each slice is ignored.
"""
- def getNullBugTask(product=None, productseries=None,
- sourcepackagename=None, distribution=None,
- distroseries=None):
- """Create an INullBugTask and return it for the given parameters."""
-
@operation_parameters(
target=Reference(schema=Interface, title=_('Target')))
@call_with(owner=REQUEST_USER)
=== modified file 'lib/lp/bugs/interfaces/bugtask.py'
--- lib/lp/bugs/interfaces/bugtask.py 2011-03-07 21:05:12 +0000
+++ lib/lp/bugs/interfaces/bugtask.py 2011-03-15 04:38:22 +0000
@@ -30,7 +30,6 @@
'IDistroSeriesBugTask',
'IFrontPageBugTaskSearch',
'INominationsReviewTableBatchNavigator',
- 'INullBugTask',
'IPersonBugTaskSearch',
'IProductSeriesBugTask',
'IRemoveQuestionFromBugTaskForm',
@@ -839,16 +838,6 @@
IBugWatch['bugtasks'].value_type.schema = IBugTask
-class INullBugTask(IBugTask):
- """A marker interface for an IBugTask that doesn't exist in a context.
-
- An INullBugTask is useful when wanting to view a bug in a context
- where that bug hasn't yet been reported. This might happen, for
- example, when searching to see if a bug you want to report has
- already been filed and finding matching reports that don't yet
- have tasks reported in your context.
- """
-
UPSTREAM_STATUS_VOCABULARY = SimpleVocabulary(
[SimpleTerm(
"pending_bugwatch",
=== modified file 'lib/lp/bugs/model/bug.py'
--- lib/lp/bugs/model/bug.py 2011-03-08 01:56:34 +0000
+++ lib/lp/bugs/model/bug.py 2011-03-15 04:38:22 +0000
@@ -168,7 +168,6 @@
BugTask,
bugtask_sort_key,
get_bug_privacy_filter,
- NullBugTask,
)
from lp.bugs.model.bugwatch import BugWatch
from lp.bugs.model.structuralsubscription import (
@@ -1429,16 +1428,6 @@
need_validity=True))
return DecoratedResultSet(result, pre_iter_hook=eager_load_owners)
- def getNullBugTask(self, product=None, productseries=None,
- sourcepackagename=None, distribution=None,
- distroseries=None):
- """See `IBug`."""
- return NullBugTask(bug=self, product=product,
- productseries=productseries,
- sourcepackagename=sourcepackagename,
- distribution=distribution,
- distroseries=distroseries)
-
def addNomination(self, owner, target):
"""See `IBug`."""
if not self.canBeNominatedFor(target):
=== modified file 'lib/lp/bugs/model/bugtask.py'
--- lib/lp/bugs/model/bugtask.py 2011-03-11 03:06:43 +0000
+++ lib/lp/bugs/model/bugtask.py 2011-03-15 04:38:22 +0000
@@ -13,7 +13,6 @@
'BugTaskMixin',
'BugTask',
'BugTaskSet',
- 'NullBugTask',
'bugtask_sort_key',
'determine_target',
'get_bug_privacy_filter',
@@ -119,7 +118,6 @@
IDistroSeriesBugTask,
IllegalRelatedBugTasksParams,
IllegalTarget,
- INullBugTask,
IProductSeriesBugTask,
IUpstreamBugTask,
RESOLVED_BUGTASK_STATUSES,
@@ -374,68 +372,6 @@
return sorted(result, key=pillar_sort_key)
-class NullBugTask(BugTaskMixin):
- """A null object for IBugTask.
-
- This class is used, for example, to be able to render a URL like:
-
- /products/evolution/+bug/5
-
- when bug #5 isn't yet reported in evolution.
- """
- implements(INullBugTask)
-
- def __init__(self, bug, product=None, productseries=None,
- sourcepackagename=None, distribution=None,
- distroseries=None):
- """Initialize a NullBugTask."""
- self.id = None
- self.bug = bug
- self.product = product
- self.productseries = productseries
- self.sourcepackagename = sourcepackagename
- self.distribution = distribution
- self.distroseries = distroseries
-
- # Mark the task with the correct interface, depending on its
- # context.
- if self.product:
- alsoProvides(self, IUpstreamBugTask)
- elif self.distribution:
- alsoProvides(self, IDistroBugTask)
- elif self.distroseries:
- alsoProvides(self, IDistroSeriesBugTask)
- elif self.productseries:
- alsoProvides(self, IProductSeriesBugTask)
- else:
- raise AssertionError('Unknown NullBugTask: %r.' % self)
-
- # Make us provide the interface by setting all required attributes
- # to None, and define the methods as raising NotImplementedError.
- # The attributes are set to None because it doesn't make
- # sense for these attributes to have a value when there is no
- # real task there. (In fact, it may make sense for these
- # values to be non-null, but I haven't yet found a use case
- # for it, and I don't think there's any point on designing for
- # that until we've encountered one.)
- def this_is_a_null_bugtask_method(*args, **kwargs):
- raise NotImplementedError
-
- for name, spec in INullBugTask.namesAndDescriptions(True):
- if not hasattr(self, name):
- if IMethod.providedBy(spec):
- value = this_is_a_null_bugtask_method
- else:
- value = None
- setattr(self, name, value)
-
- @property
- def title(self):
- """See `IBugTask`."""
- return 'Bug #%s is not in %s: "%s"' % (
- self.bug.id, self.bugtargetdisplayname, self.bug.title)
-
-
def BugTaskToBugAdapter(bugtask):
"""Adapt an IBugTask to an IBug."""
return bugtask.bug
@@ -467,9 +403,10 @@
else:
target_params[attr[:-2]] = getUtility(utility_iface).get(value)
- # Use a NullBugTask to determine the new target.
- nulltask = NullBugTask(self.bug, **target_params)
- self.updateTargetNameCache(nulltask.target)
+ # Update the target name cache with the potential new target. The
+ # attribute changes haven't been made yet, so we need to calculate the
+ # target manually.
+ self.updateTargetNameCache(determine_target(**target_params))
return value