← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~cjwatson/launchpad/lazr-delegates-class-decorators into lp:launchpad

 

Colin Watson has proposed merging lp:~cjwatson/launchpad/lazr-delegates-class-decorators into lp:launchpad.

Commit message:
Switch lazr.delegates users from class advice to class decorators.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/lazr-delegates-class-decorators/+merge/264343

Switch lazr.delegates users from class advice to class decorators.

This is, I hope, the last for now in the series starting with https://code.launchpad.net/~cjwatson/launchpad/zope-interface-class-decorators/+merge/264175 and https://code.launchpad.net/~cjwatson/launchpad/zope-component-class-decorators/+merge/264276.  It requires upgrading to lazr.delegates 2.0.3, and a few adjustments for the slightly different argument structure.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/lazr-delegates-class-decorators into lp:launchpad.
=== modified file 'lib/lp/answers/browser/questionsubscription.py'
--- lib/lp/answers/browser/questionsubscription.py	2012-01-01 02:58:52 +0000
+++ lib/lp/answers/browser/questionsubscription.py	2015-07-09 20:17:15 +0000
@@ -8,7 +8,7 @@
     'QuestionPortletSubscribersWithDetails',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.restful.interfaces import IWebServiceClientRequest
 from simplejson import dumps
 from zope.traversing.browser import absoluteURL
@@ -90,9 +90,9 @@
         return self.subscriber_data_js
 
 
+@delegate_to(IQuestionSubscription, context='subscription')
 class SubscriptionAttrDecorator:
     """A QuestionSubscription with added attributes for HTML/JS."""
-    delegates(IQuestionSubscription, 'subscription')
 
     def __init__(self, subscription):
         self.subscription = subscription

=== modified file 'lib/lp/answers/model/questionjob.py'
--- lib/lp/answers/model/questionjob.py	2015-07-08 16:05:11 +0000
+++ lib/lp/answers/model/questionjob.py	2015-07-09 20:17:15 +0000
@@ -8,7 +8,7 @@
     'QuestionJob',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 import simplejson
 from storm.expr import And
 from storm.locals import (
@@ -99,12 +99,12 @@
         return QuestionEmailJob(self)
 
 
+@delegate_to(IQuestionJob)
 @implementer(IQuestionEmailJob)
 @provider(IQuestionEmailJobSource)
 class QuestionEmailJob(BaseRunnableJob):
     """Intermediate class for deriving from QuestionJob."""
 
-    delegates(IQuestionJob)
     config = config.IQuestionEmailJobSource
 
     def __init__(self, job):

=== modified file 'lib/lp/answers/model/questionmessage.py'
--- lib/lp/answers/model/questionmessage.py	2015-07-08 16:05:11 +0000
+++ lib/lp/answers/model/questionmessage.py	2015-07-09 20:17:15 +0000
@@ -9,7 +9,7 @@
     'QuestionMessage',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from sqlobject import ForeignKey
 from zope.interface import implementer
 
@@ -26,11 +26,10 @@
 
 
 @implementer(IQuestionMessage)
+@delegate_to(IMessage, context='message')
 class QuestionMessage(SQLBase):
     """A table linking questions and messages."""
 
-    delegates(IMessage, context='message')
-
     _table = 'QuestionMessage'
 
     question = ForeignKey(

=== modified file 'lib/lp/app/doc/badges.txt'
--- lib/lp/app/doc/badges.txt	2015-07-08 16:05:11 +0000
+++ lib/lp/app/doc/badges.txt	2015-07-09 20:17:15 +0000
@@ -226,7 +226,7 @@
     title="Linked to a bug"/>
 
 When showing listings of Foos, you often want to use
-`lazr.delegates.delegates`. By having the DelegatingFoo inherit from the
+`lazr.delegates.delegate_to`. By having the DelegatingFoo inherit from the
 FooBadges class, we provide two things: a default implementation for each of
 the badge methods; and direct implementation of IHasBadges. This allows the
 wrapping, delegating class to provide an alternative method to decide on badge
@@ -236,9 +236,9 @@
 handler for branches executes a single query for the BugBranch links for the
 branches in the batch and that is used to construct the DecoratedBranch.
 
-    >>> from lazr.delegates import delegates
-    >>> class DelegatingFoo(FooBadges):
-    ...     delegates(IFoo, 'foo')
+    >>> from lazr.delegates import delegate_to
+    >>> @delegate_to(IFoo, context='foo')
+    ... class DelegatingFoo(FooBadges):
     ...     def __init__(self, foo):
     ...         FooBadges.__init__(self, foo)
     ...         self.foo = foo

=== modified file 'lib/lp/blueprints/browser/specificationsubscription.py'
--- lib/lp/blueprints/browser/specificationsubscription.py	2012-01-01 02:58:52 +0000
+++ lib/lp/blueprints/browser/specificationsubscription.py	2015-07-09 20:17:15 +0000
@@ -10,7 +10,7 @@
     'SpecificationSubscriptionEditView',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from simplejson import dumps
 from zope.component import getUtility
 
@@ -203,9 +203,9 @@
         return self.subscriber_ids_js
 
 
+@delegate_to(ISpecificationSubscription, context='subscription')
 class SubscriptionAttrDecorator:
     """A SpecificationSubscription with added attributes for HTML/JS."""
-    delegates(ISpecificationSubscription, 'subscription')
 
     def __init__(self, subscription):
         self.subscription = subscription

=== modified file 'lib/lp/bugs/browser/bugcomment.py'
--- lib/lp/bugs/browser/bugcomment.py	2015-07-09 12:18:51 +0000
+++ lib/lp/bugs/browser/bugcomment.py	2015-07-09 20:17:15 +0000
@@ -22,7 +22,7 @@
     )
 from operator import itemgetter
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.restful.interfaces import IWebServiceClientRequest
 from zope.component import (
     adapter,
@@ -174,6 +174,7 @@
 
 
 @implementer(IBugComment)
+@delegate_to(IMessage, context='_message')
 class BugComment(MessageComment):
     """Data structure that holds all data pertaining to a bug comment.
 
@@ -186,8 +187,6 @@
     (task-specific) location.
     """
 
-    delegates(IMessage, '_message')
-
     def __init__(
             self, index, message, bugtask, activity=None,
             show_spam_controls=False, user=None, display='full'):

=== modified file 'lib/lp/bugs/browser/buglisting.py'
--- lib/lp/bugs/browser/buglisting.py	2015-07-08 16:05:11 +0000
+++ lib/lp/bugs/browser/buglisting.py	2015-07-09 20:17:15 +0000
@@ -26,7 +26,7 @@
 import urllib
 import urlparse
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.restful.interfaces import IJSONRequestCache
 from lazr.uri import URI
 import pystache
@@ -601,6 +601,7 @@
     return search_filter_url
 
 
+@delegate_to(IBugTask, context='bugtask')
 class BugTaskListingItem:
     """A decorated bug task.
 
@@ -608,7 +609,6 @@
     to get on the fly for each bug task in the listing.  These items are
     prefetched by the view and decorate the bug task.
     """
-    delegates(IBugTask, 'bugtask')
 
     def __init__(self, bugtask, has_bug_branch,
                  has_specification, has_patch, tags,

=== modified file 'lib/lp/bugs/browser/bugsubscription.py'
--- lib/lp/bugs/browser/bugsubscription.py	2015-04-30 10:21:14 +0000
+++ lib/lp/bugs/browser/bugsubscription.py	2015-07-09 20:17:15 +0000
@@ -12,7 +12,7 @@
     'BugSubscriptionListView',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.restful.interfaces import (
     IJSONRequestCache,
     IWebServiceClientRequest,
@@ -623,9 +623,9 @@
         return self.subscriber_data_js
 
 
+@delegate_to(IBugSubscription, context='subscription')
 class SubscriptionAttrDecorator:
     """A BugSubscription with added attributes for HTML/JS."""
-    delegates(IBugSubscription, 'subscription')
 
     def __init__(self, subscription):
         self.subscription = subscription

=== modified file 'lib/lp/bugs/browser/bugtask.py'
--- lib/lp/bugs/browser/bugtask.py	2015-07-08 16:05:11 +0000
+++ lib/lp/bugs/browser/bugtask.py	2015-07-09 20:17:15 +0000
@@ -37,7 +37,7 @@
 import re
 import urllib
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.lifecycle.event import ObjectModifiedEvent
 from lazr.lifecycle.snapshot import Snapshot
 from lazr.restful.interface import copy_field
@@ -2391,9 +2391,9 @@
     page_title = label
 
 
+@delegate_to(IBugActivity, context='activity')
 class BugActivityItem:
     """A decorated BugActivity."""
-    delegates(IBugActivity, 'activity')
 
     def __init__(self, activity):
         self.activity = activity

=== modified file 'lib/lp/bugs/model/apportjob.py'
--- lib/lp/bugs/model/apportjob.py	2015-07-08 16:05:11 +0000
+++ lib/lp/bugs/model/apportjob.py	2015-07-09 20:17:15 +0000
@@ -11,7 +11,7 @@
 
 from cStringIO import StringIO
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 import simplejson
 from sqlobject import SQLObjectNotFound
 from storm.expr import And
@@ -70,7 +70,7 @@
 
     # The metadata property because it needs to be modifiable by
     # subclasses of ApportJobDerived. However, since ApportJobDerived
-    # only delegates() to ApportJob we can't simply directly access the
+    # only delegates to ApportJob we can't simply directly access the
     # _json_data property, so we use a getter and setter here instead.
     def _set_metadata(self, metadata):
         self._json_data = unicode(
@@ -111,11 +111,11 @@
         return ApportJobDerived.makeSubclass(self)
 
 
+@delegate_to(IApportJob)
 @provider(IApportJobSource)
 class ApportJobDerived(BaseRunnableJob):
     """Intermediate class for deriving from ApportJob."""
     __metaclass__ = EnumeratedSubclass
-    delegates(IApportJob)
 
     def __init__(self, job):
         self.context = job

=== modified file 'lib/lp/code/browser/branchlisting.py'
--- lib/lp/code/browser/branchlisting.py	2015-07-08 16:05:11 +0000
+++ lib/lp/code/browser/branchlisting.py	2015-07-09 20:17:15 +0000
@@ -29,7 +29,7 @@
 from operator import attrgetter
 import urlparse
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.enum import (
     EnumeratedType,
     Item,
@@ -147,6 +147,7 @@
             return super(BranchBadges, self).getBadge(badge_name)
 
 
+@delegate_to(IBranch, context='context')
 class BranchListingItem(BzrIdentityMixin, BranchBadges):
     """A decorated branch.
 
@@ -154,7 +155,6 @@
     to get on the fly for each branch in the listing.  These items are
     prefetched by the view and decorate the branch.
     """
-    delegates(IBranch, 'context')
 
     def __init__(self, branch, last_commit, show_bug_badge,
                  show_blueprint_badge, show_mp_badge,

=== modified file 'lib/lp/code/browser/branchmergeproposal.py'
--- lib/lp/code/browser/branchmergeproposal.py	2015-07-09 12:18:51 +0000
+++ lib/lp/code/browser/branchmergeproposal.py	2015-07-09 20:17:15 +0000
@@ -28,7 +28,7 @@
 from functools import wraps
 import operator
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.restful.interface import copy_field
 from lazr.restful.interfaces import (
     IJSONRequestCache,
@@ -780,11 +780,10 @@
             })
 
 
+@delegate_to(ICodeReviewVoteReference)
 class DecoratedCodeReviewVoteReference:
     """Provide a code review vote that knows if it is important or not."""
 
-    delegates(ICodeReviewVoteReference)
-
     status_text_map = {
         CodeReviewVote.DISAPPROVE: CodeReviewVote.DISAPPROVE.title,
         CodeReviewVote.APPROVE: CodeReviewVote.APPROVE.title,

=== modified file 'lib/lp/code/browser/branchmergeproposallisting.py'
--- lib/lp/code/browser/branchmergeproposallisting.py	2015-07-08 16:05:11 +0000
+++ lib/lp/code/browser/branchmergeproposallisting.py	2015-07-09 20:17:15 +0000
@@ -16,7 +16,7 @@
 
 from operator import attrgetter
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.enum import (
     EnumeratedType,
     Item,
@@ -56,11 +56,10 @@
 from lp.services.webapp.batching import TableBatchNavigator
 
 
+@delegate_to(IBranchMergeProposal, context='context')
 class BranchMergeProposalListingItem:
     """A branch merge proposal that knows summary values for comments."""
 
-    delegates(IBranchMergeProposal, 'context')
-
     def __init__(self, branch_merge_proposal, summary, proposal_reviewer,
                  vote_references=None):
         self.context = branch_merge_proposal

=== modified file 'lib/lp/code/browser/codeimportmachine.py'
--- lib/lp/code/browser/codeimportmachine.py	2012-01-01 02:58:52 +0000
+++ lib/lp/code/browser/codeimportmachine.py	2015-07-09 20:17:15 +0000
@@ -14,7 +14,7 @@
     ]
 
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from zope.component import getUtility
 from zope.interface import Interface
 from zope.schema import TextLine
@@ -81,11 +81,10 @@
             "Why the machine state is changing."))
 
 
+@delegate_to(ICodeImportEvent, context='event')
 class DecoratedEvent:
     """A CodeImportEvent with cached items."""
 
-    delegates(ICodeImportEvent, 'event')
-
     def __init__(self, event):
         self.event = event
 

=== modified file 'lib/lp/code/browser/codereviewcomment.py'
--- lib/lp/code/browser/codereviewcomment.py	2015-07-08 16:05:11 +0000
+++ lib/lp/code/browser/codereviewcomment.py	2015-07-09 20:17:15 +0000
@@ -10,7 +10,7 @@
     'CodeReviewDisplayComment',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.restful.interface import copy_field
 from zope.component import getUtility
 from zope.formlib.widgets import (
@@ -57,6 +57,7 @@
 
 
 @implementer(ICodeReviewDisplayComment)
+@delegate_to(ICodeReviewComment, context='comment')
 class CodeReviewDisplayComment(MessageComment):
     """A code review comment or activity or both.
 
@@ -65,8 +66,6 @@
     only code in the model itself.
     """
 
-    delegates(ICodeReviewComment, 'comment')
-
     def __init__(self, comment, from_superseded=False, limit_length=True):
         if limit_length:
             comment_limit = config.malone.max_comment_size
@@ -140,11 +139,10 @@
 
 
 @implementer(ILibraryFileAlias)
+@delegate_to(ILibraryFileAlias, context='alias')
 class DiffAttachment:
     """An attachment that we are going to display."""
 
-    delegates(ILibraryFileAlias, 'alias')
-
     def __init__(self, alias):
         self.alias = alias
 

=== modified file 'lib/lp/code/browser/decorations.py'
--- lib/lp/code/browser/decorations.py	2015-07-08 16:05:11 +0000
+++ lib/lp/code/browser/decorations.py	2015-07-09 20:17:15 +0000
@@ -8,7 +8,7 @@
     'DecoratedBranch',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from zope.interface import implementer
 
 from lp.app.interfaces.informationtype import IInformationType
@@ -21,12 +21,12 @@
 
 
 @implementer(IPrivacy)
+@delegate_to(IBranch, IInformationType, context='branch')
 class DecoratedBranch(BzrIdentityMixin):
     """Wrap a number of the branch accessors to cache results.
 
     This avoids repeated db queries.
     """
-    delegates([IBranch, IInformationType], 'branch')
 
     def __init__(self, branch):
         self.branch = branch

=== modified file 'lib/lp/code/model/branchjob.py'
--- lib/lp/code/model/branchjob.py	2015-07-08 16:05:11 +0000
+++ lib/lp/code/model/branchjob.py	2015-07-09 20:17:15 +0000
@@ -32,7 +32,7 @@
 from bzrlib.revisionspec import RevisionInfo
 from bzrlib.transport import get_transport
 from bzrlib.upgrade import upgrade
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.enum import (
     DBEnumeratedType,
     DBItem,
@@ -228,12 +228,11 @@
         return BranchJobDerived.makeSubclass(self)
 
 
+@delegate_to(IBranchJob)
 class BranchJobDerived(BaseRunnableJob):
 
     __metaclass__ = EnumeratedSubclass
 
-    delegates(IBranchJob)
-
     def __init__(self, branch_job):
         self.context = branch_job
 
@@ -246,7 +245,7 @@
             }
 
     # XXX: henninge 2009-02-20 bug=331919: These two standard operators
-    # should be implemented by delegates().
+    # should be implemented by delegate_to().
     def __eq__(self, other):
         # removeSecurityProxy, since 'other' might well be a delegated object
         # and the context attribute is not exposed by design.

=== modified file 'lib/lp/code/model/branchmergeproposaljob.py'
--- lib/lp/code/model/branchmergeproposaljob.py	2015-07-08 16:05:11 +0000
+++ lib/lp/code/model/branchmergeproposaljob.py	2015-07-09 20:17:15 +0000
@@ -27,7 +27,7 @@
     timedelta,
     )
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.enum import (
     DBEnumeratedType,
     DBItem,
@@ -220,13 +220,12 @@
         return BranchMergeProposalJobDerived.makeSubclass(self)
 
 
+@delegate_to(IBranchMergeProposalJob)
 class BranchMergeProposalJobDerived(BaseRunnableJob):
     """Intermediate class for deriving from BranchMergeProposalJob."""
 
     __metaclass__ = EnumeratedSubclass
 
-    delegates(IBranchMergeProposalJob)
-
     def __init__(self, job):
         self.context = job
 

=== modified file 'lib/lp/code/model/diff.py'
--- lib/lp/code/model/diff.py	2015-07-08 16:05:11 +0000
+++ lib/lp/code/model/diff.py	2015-07-09 20:17:15 +0000
@@ -24,7 +24,7 @@
     Patch,
     )
 from bzrlib.plugins.difftacular.generate_diff import diff_ignore_branches
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 import simplejson
 from sqlobject import (
     ForeignKey,
@@ -323,11 +323,10 @@
 
 
 @implementer(IIncrementalDiff)
+@delegate_to(IDiff, context='diff')
 class IncrementalDiff(Storm):
     """See `IIncrementalDiff."""
 
-    delegates(IDiff, context='diff')
-
     __storm_table__ = 'IncrementalDiff'
 
     id = Int(primary=True, allow_none=False)
@@ -352,9 +351,9 @@
 
 
 @implementer(IPreviewDiff)
+@delegate_to(IDiff, context='diff')
 class PreviewDiff(Storm):
     """See `IPreviewDiff`."""
-    delegates(IDiff, context='diff')
     __storm_table__ = 'PreviewDiff'
 
     id = Int(primary=True)

=== modified file 'lib/lp/code/model/gitjob.py'
--- lib/lp/code/model/gitjob.py	2015-07-08 16:05:11 +0000
+++ lib/lp/code/model/gitjob.py	2015-07-09 20:17:15 +0000
@@ -10,7 +10,7 @@
     'ReclaimGitRepositorySpaceJob',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.enum import (
     DBEnumeratedType,
     DBItem,
@@ -116,12 +116,11 @@
         return GitJobDerived.makeSubclass(self)
 
 
+@delegate_to(IGitJob)
 class GitJobDerived(BaseRunnableJob):
 
     __metaclass__ = EnumeratedSubclass
 
-    delegates(IGitJob)
-
     def __init__(self, git_job):
         self.context = git_job
         self._cached_repository_name = self.metadata["repository_name"]

=== modified file 'lib/lp/code/model/sourcepackagerecipe.py'
--- lib/lp/code/model/sourcepackagerecipe.py	2015-07-08 16:05:11 +0000
+++ lib/lp/code/model/sourcepackagerecipe.py	2015-07-09 20:17:15 +0000
@@ -14,7 +14,7 @@
     )
 from operator import attrgetter
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from pytz import utc
 from storm.expr import (
     And,
@@ -101,6 +101,7 @@
 
 @implementer(ISourcePackageRecipe)
 @provider(ISourcePackageRecipeSource)
+@delegate_to(ISourcePackageRecipeData, context='_recipe_data')
 class SourcePackageRecipe(Storm):
     """See `ISourcePackageRecipe` and `ISourcePackageRecipeSource`."""
 
@@ -109,9 +110,6 @@
     def __str__(self):
         return '%s/%s' % (self.owner.name, self.name)
 
-    
-    delegates(ISourcePackageRecipeData, context='_recipe_data')
-
     id = Int(primary=True)
 
     daily_build_archive_id = Int(name='daily_build_archive', allow_none=True)

=== modified file 'lib/lp/registry/browser/distributionsourcepackage.py'
--- lib/lp/registry/browser/distributionsourcepackage.py	2015-07-08 16:05:11 +0000
+++ lib/lp/registry/browser/distributionsourcepackage.py	2015-07-09 20:17:15 +0000
@@ -20,7 +20,7 @@
 import itertools
 import operator
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from zope.component import getUtility
 from zope.interface import (
     implementer,
@@ -190,13 +190,13 @@
         return self.context.getVersion(name)
 
 
+@delegate_to(IDistributionSourcePackageRelease, context='context')
 class DecoratedDistributionSourcePackageRelease:
     """A decorated DistributionSourcePackageRelease.
 
     The publishing history and package diffs for the release are
     pre-cached.
     """
-    delegates(IDistributionSourcePackageRelease, 'context')
 
     def __init__(
         self, distributionsourcepackagerelease, publishing_history,

=== modified file 'lib/lp/registry/browser/person.py'
--- lib/lp/registry/browser/person.py	2015-07-09 12:18:51 +0000
+++ lib/lp/registry/browser/person.py	2015-07-09 20:17:15 +0000
@@ -68,7 +68,7 @@
 import urllib
 
 from lazr.config import as_timedelta
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.restful.interface import copy_field
 from lazr.restful.interfaces import IWebServiceClientRequest
 from lazr.restful.utils import smartquote
@@ -1139,6 +1139,7 @@
             '%s/+editlanguages' % canonical_url(self.user))
 
 
+@delegate_to(IPerson, context='person')
 class PersonWithKeysAndPreferredEmail:
     """A decorated person that includes GPG keys and preferred emails."""
 
@@ -1148,7 +1149,6 @@
     gpgkeys = None
     sshkeys = None
     preferredemail = None
-    delegates(IPerson, 'person')
 
     def __init__(self, person):
         self.person = person
@@ -3560,15 +3560,16 @@
 
 
 @implementer(ISourcePackageRelease)
+@delegate_to(ISourcePackageRelease)
 class SourcePackageReleaseWithStats(BaseWithStats):
     """An ISourcePackageRelease, with extra stats added."""
-    delegates(ISourcePackageRelease)
+    pass
 
 
 @implementer(ISourcePackagePublishingHistory)
+@delegate_to(ISourcePackagePublishingHistory)
 class SourcePackagePublishingHistoryWithStats(BaseWithStats):
     """An ISourcePackagePublishingHistory, with extra stats added."""
-    delegates(ISourcePackagePublishingHistory)
 
 
 @implementer(IPersonRelatedSoftwareMenu)

=== modified file 'lib/lp/registry/browser/product.py'
--- lib/lp/registry/browser/product.py	2015-07-08 16:05:11 +0000
+++ lib/lp/registry/browser/product.py	2015-07-09 20:17:15 +0000
@@ -46,7 +46,7 @@
 from operator import attrgetter
 
 from bzrlib.revision import NULL_REVISION
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.restful.interface import (
     copy_field,
     use_template,
@@ -688,6 +688,7 @@
         return self._sorted_filtered_list(check_active)
 
 
+@delegate_to(IProduct, context='product')
 class ProductWithSeries:
     """A decorated product that includes series data.
 
@@ -701,7 +702,6 @@
     # variables to self.product, which would bypass the caching.
     series = None
     development_focus = None
-    delegates(IProduct, 'product')
 
     def __init__(self, product):
         self.product = product
@@ -726,9 +726,9 @@
             self.release_by_id[release.id] = release_delegate
 
 
+@delegate_to(IProductSeries, context='series')
 class DecoratedSeries:
     """A decorated series that includes helper attributes for templates."""
-    delegates(IProductSeries, 'series')
 
     def __init__(self, series):
         self.series = series
@@ -781,6 +781,7 @@
         return False
 
 
+@delegate_to(IProductRelease, context='release')
 class ReleaseWithFiles:
     """A decorated release that includes product release files.
 
@@ -793,7 +794,6 @@
     # this class will not delegate the actual instance variables to
     # self.release, which would raise an AttributeError.
     parent = None
-    delegates(IProductRelease, 'release')
 
     def __init__(self, release, parent):
         self.release = release

=== modified file 'lib/lp/registry/model/distroseries.py'
--- lib/lp/registry/model/distroseries.py	2015-07-08 16:05:11 +0000
+++ lib/lp/registry/model/distroseries.py	2015-07-09 20:17:15 +0000
@@ -17,7 +17,7 @@
 from operator import attrgetter
 
 import apt_pkg
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from sqlobject import (
     BoolCol,
     ForeignKey,
@@ -204,14 +204,13 @@
 @implementer(
     IBugSummaryDimension, IDistroSeries, IHasBuildRecords, IHasQueueItems,
     IServiceUsage, ISeriesBugTarget)
+@delegate_to(ISpecificationTarget, context='distribution')
 class DistroSeries(SQLBase, BugTargetBase, HasSpecificationsMixin,
                    HasTranslationImportsMixin, HasTranslationTemplatesMixin,
                    HasMilestonesMixin, SeriesMixin,
                    StructuralSubscriptionTargetMixin):
     """A particular series of a distribution."""
 
-    delegates(ISpecificationTarget, 'distribution')
-
     _table = 'DistroSeries'
     _defaultOrder = ['distribution', 'version']
 

=== modified file 'lib/lp/registry/model/person.py'
--- lib/lp/registry/model/person.py	2015-07-08 16:05:11 +0000
+++ lib/lp/registry/model/person.py	2015-07-09 20:17:15 +0000
@@ -38,7 +38,7 @@
 import subprocess
 import weakref
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.restful.utils import (
     get_current_browser_request,
     smartquote,
@@ -472,6 +472,7 @@
 
 
 @implementer(IPerson, IHasIcon, IHasLogo, IHasMugshot)
+@delegate_to(IPersonSettings, context='_person_settings')
 class Person(
     SQLBase, HasBugsBase, HasSpecificationsMixin, HasTranslationImportsMixin,
     HasBranchesMixin, HasMergeProposalsMixin, HasRequestedReviewsMixin,
@@ -501,8 +502,6 @@
                 PersonSettings,
                 PersonSettings.person == self).one()
 
-    delegates(IPersonSettings, context='_person_settings')
-
     sortingColumns = SQL("person_sort_key(Person.displayname, Person.name)")
     # Redefine the default ordering into Storm syntax.
     _storm_sortingColumns = ('Person.displayname', 'Person.name')

=== modified file 'lib/lp/registry/model/persontransferjob.py'
--- lib/lp/registry/model/persontransferjob.py	2015-07-08 16:05:11 +0000
+++ lib/lp/registry/model/persontransferjob.py	2015-07-09 20:17:15 +0000
@@ -9,7 +9,7 @@
     'PersonTransferJob',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 import simplejson
 from storm.expr import (
     And,
@@ -127,6 +127,7 @@
         return PersonTransferJobDerived.makeSubclass(self)
 
 
+@delegate_to(IPersonTransferJob)
 @provider(IPersonTransferJobSource)
 class PersonTransferJobDerived(BaseRunnableJob):
     """Intermediate class for deriving from PersonTransferJob.
@@ -139,7 +140,6 @@
     """
 
     __metaclass__ = EnumeratedSubclass
-    delegates(IPersonTransferJob)
 
     def __init__(self, job):
         self.context = job

=== modified file 'lib/lp/registry/model/product.py'
--- lib/lp/registry/model/product.py	2015-07-08 16:05:11 +0000
+++ lib/lp/registry/model/product.py	2015-07-09 20:17:15 +0000
@@ -18,7 +18,7 @@
 import itertools
 import operator
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.lifecycle.event import ObjectModifiedEvent
 from lazr.lifecycle.snapshot import Snapshot
 from lazr.restful.declarations import error_status
@@ -267,11 +267,10 @@
     name = 'array'
 
 
+@delegate_to(IProduct, context='product')
 class ProductWithLicenses:
     """Caches `Product.licenses`."""
 
-    delegates(IProduct, 'product')
-
     def __init__(self, product, license_ids):
         """Initialize a `ProductWithLicenses`.
 

=== modified file 'lib/lp/registry/model/productjob.py'
--- lib/lp/registry/model/productjob.py	2015-07-08 16:05:11 +0000
+++ lib/lp/registry/model/productjob.py	2015-07-09 20:17:15 +0000
@@ -17,7 +17,7 @@
     timedelta,
     )
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from pytz import utc
 import simplejson
 from storm.expr import (
@@ -159,6 +159,7 @@
         self._json_data = json_data.decode('utf-8')
 
 
+@delegate_to(IProductJob)
 @provider(IProductJobSource)
 class ProductJobDerived(BaseRunnableJob):
     """Intermediate class for deriving from ProductJob.
@@ -170,8 +171,6 @@
     the run() method.
     """
 
-    delegates(IProductJob)
-
     def __init__(self, job):
         self.context = job
 

=== modified file 'lib/lp/registry/model/productseries.py'
--- lib/lp/registry/model/productseries.py	2015-07-08 16:05:11 +0000
+++ lib/lp/registry/model/productseries.py	2015-07-09 20:17:15 +0000
@@ -13,7 +13,7 @@
 
 import datetime
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from sqlobject import (
     ForeignKey,
     SQLMultipleJoin,
@@ -112,14 +112,13 @@
 
 @implementer(
     IBugSummaryDimension, IProductSeries, IServiceUsage, ISeriesBugTarget)
+@delegate_to(ISpecificationTarget, context='product')
 class ProductSeries(SQLBase, BugTargetBase, HasMilestonesMixin,
                     HasSpecificationsMixin, HasTranslationImportsMixin,
                     HasTranslationTemplatesMixin,
                     StructuralSubscriptionTargetMixin, SeriesMixin):
     """A series of product releases."""
 
-    delegates(ISpecificationTarget, 'product')
-
     _table = 'ProductSeries'
 
     product = ForeignKey(dbName='product', foreignKey='Product', notNull=True)

=== modified file 'lib/lp/registry/model/sharingjob.py'
--- lib/lp/registry/model/sharingjob.py	2015-07-08 16:05:11 +0000
+++ lib/lp/registry/model/sharingjob.py	2015-07-09 20:17:15 +0000
@@ -12,7 +12,7 @@
 
 import logging
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.enum import (
     DBEnumeratedType,
     DBItem,
@@ -169,14 +169,13 @@
         return SharingJobDerived.makeSubclass(self)
 
 
+@delegate_to(ISharingJob)
 @provider(ISharingJobSource)
 class SharingJobDerived(BaseRunnableJob):
     """Intermediate class for deriving from SharingJob."""
 
     __metaclass__ = EnumeratedSubclass
 
-    delegates(ISharingJob)
-
     def __init__(self, job):
         self.context = job
 

=== modified file 'lib/lp/services/database/decoratedresultset.py'
--- lib/lp/services/database/decoratedresultset.py	2014-01-14 00:31:23 +0000
+++ lib/lp/services/database/decoratedresultset.py	2015-07-09 20:17:15 +0000
@@ -6,7 +6,7 @@
     'DecoratedResultSet',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from storm import Undef
 from storm.zope.interfaces import IResultSet
 from zope.security.proxy import (
@@ -16,6 +16,7 @@
     )
 
 
+@delegate_to(IResultSet, context='result_set')
 class DecoratedResultSet(object):
     """A decorated Storm ResultSet for 'Magic' (presenter) classes.
 
@@ -34,7 +35,6 @@
     This behaviour is required for other classes as well (Distribution,
     DistroArchSeries), hence a generalised solution.
     """
-    delegates(IResultSet, context='result_set')
 
     def __init__(self, result_set, result_decorator=None, pre_iter_hook=None,
                  bulk_decorator=None, slice_info=False, return_both=False):

=== modified file 'lib/lp/services/job/runner.py'
--- lib/lp/services/job/runner.py	2013-07-23 10:40:22 +0000
+++ lib/lp/services/job/runner.py	2015-07-09 20:17:15 +0000
@@ -41,7 +41,7 @@
     main,
     pool,
     )
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.jobrunner.jobrunner import (
     JobRunner as LazrJobRunner,
     LeaseHeld,
@@ -89,6 +89,7 @@
         yield
 
 
+@delegate_to(IJob, context='job')
 class BaseRunnableJob(BaseRunnableJobSource):
     """Base class for jobs to be run via JobRunner.
 
@@ -98,7 +99,6 @@
     Subclasses may provide getOopsRecipients, to send mail about oopses.
     If so, they should also provide getOperationDescription.
     """
-    delegates(IJob, 'job')
 
     user_error_types = ()
 

=== modified file 'lib/lp/services/job/tests/test_retry_jobs_with_celery.py'
--- lib/lp/services/job/tests/test_retry_jobs_with_celery.py	2015-07-08 16:05:11 +0000
+++ lib/lp/services/job/tests/test_retry_jobs_with_celery.py	2015-07-09 20:17:15 +0000
@@ -7,7 +7,7 @@
 from datetime import timedelta
 from time import sleep
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 import transaction
 from zope.interface import implementer
 
@@ -27,9 +27,9 @@
 
 
 @implementer(IRunnableJob)
+@delegate_to(IJob, context='job')
 class TestJob(BaseRunnableJob):
     """A dummy job."""
-    delegates(IJob, 'job')
 
     config = config.launchpad
 

=== modified file 'lib/lp/services/librarian/browser.py'
--- lib/lp/services/librarian/browser.py	2014-01-30 15:04:06 +0000
+++ lib/lp/services/librarian/browser.py	2015-07-09 20:17:15 +0000
@@ -13,7 +13,7 @@
     'ProxiedLibraryFileAlias',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.restful.interfaces import IWebBrowserOriginatingRequest
 from lazr.restful.utils import get_current_browser_request
 from zope.publisher.interfaces import NotFound
@@ -100,6 +100,7 @@
             self.request)
 
 
+@delegate_to(ILibraryFileAlias)
 class ProxiedLibraryFileAlias:
     """A `LibraryFileAlias` decorator for use in URL generation.
 
@@ -118,7 +119,6 @@
     Overrides `ILibraryFileAlias.http_url` to always point to the webapp URL,
     even when called from the webservice domain.
     """
-    delegates(ILibraryFileAlias)
 
     def __init__(self, context, parent):
         self.context = context

=== modified file 'lib/lp/services/librarian/model.py'
--- lib/lp/services/librarian/model.py	2015-07-09 12:18:51 +0000
+++ lib/lp/services/librarian/model.py	2015-07-09 20:17:15 +0000
@@ -15,7 +15,7 @@
 import hashlib
 from urlparse import urlparse
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 import pytz
 from sqlobject import (
     BoolCol,
@@ -227,11 +227,10 @@
 
 @adapter(ILibraryFileAlias, Interface)
 @implementer(ILibraryFileAliasWithParent)
+@delegate_to(ILibraryFileAlias)
 class LibraryFileAliasWithParent:
     """A LibraryFileAlias variant that has a parent."""
 
-    delegates(ILibraryFileAlias)
-
     def __init__(self, libraryfile, parent):
         self.context = libraryfile
         self.__parent__ = parent

=== modified file 'lib/lp/services/messages/interfaces/message.py'
--- lib/lp/services/messages/interfaces/message.py	2015-07-08 16:05:11 +0000
+++ lib/lp/services/messages/interfaces/message.py	2015-07-09 20:17:15 +0000
@@ -19,7 +19,7 @@
     ]
 
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.restful.declarations import (
     accessor_for,
     export_as_webservice_entry,
@@ -198,10 +198,10 @@
                               "of messages in its context."))
 
 
+@delegate_to(IMessage)
 @implementer(IIndexedMessage)
 class IndexedMessage:
     """Adds the `inside` and `index` attributes to an IMessage."""
-    delegates(IMessage)
 
     def __init__(self, context, inside, index, parent=None):
         self.context = context

=== modified file 'lib/lp/services/webapp/menu.py'
--- lib/lp/services/webapp/menu.py	2015-07-08 16:05:11 +0000
+++ lib/lp/services/webapp/menu.py	2015-07-09 20:17:15 +0000
@@ -21,7 +21,7 @@
 
 import types
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.restful.utils import get_current_browser_request
 from lazr.uri import (
     InvalidURIError,
@@ -123,9 +123,9 @@
 
 
 @implementer(ILink)
+@delegate_to(ILinkData, context='_linkdata')
 class MenuLink:
     """Adapter from ILinkData to ILink."""
-    delegates(ILinkData, context='_linkdata')
 
     # These attributes are set by the menus infrastructure.
     name = None

=== modified file 'lib/lp/soyuz/adapters/archivesourcepublication.py'
--- lib/lp/soyuz/adapters/archivesourcepublication.py	2013-06-20 05:50:00 +0000
+++ lib/lp/soyuz/adapters/archivesourcepublication.py	2015-07-09 20:17:15 +0000
@@ -16,7 +16,7 @@
 
 from collections import defaultdict
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from zope.component import getUtility
 
 from lp.registry.model.distroseries import DistroSeries
@@ -30,13 +30,13 @@
 from lp.soyuz.interfaces.sourcepackagerelease import ISourcePackageRelease
 
 
+@delegate_to(ISourcePackageRelease)
 class ArchiveSourcePackageRelease:
     """Decorated `SourcePackageRelease` with cached 'upload_changesfile'.
 
     It receives the related upload changesfile, so it doesn't need
     to be recalculated.
     """
-    delegates(ISourcePackageRelease)
 
     def __init__(self, context, changesfile):
         self.context = context
@@ -48,13 +48,13 @@
         return self._changesfile
 
 
+@delegate_to(ISourcePackagePublishingHistory)
 class ArchiveSourcePublication:
     """Delegates to `ISourcePackagePublishingHistory`.
 
     It receives the expensive external references when it is created
     and provide them as through the decorated interface transparently.
     """
-    delegates(ISourcePackagePublishingHistory)
 
     def __init__(self, context, changesfile, status_summary):
         self.context = context

=== modified file 'lib/lp/soyuz/browser/publishing.py'
--- lib/lp/soyuz/browser/publishing.py	2015-07-08 16:05:11 +0000
+++ lib/lp/soyuz/browser/publishing.py	2015-07-09 20:17:15 +0000
@@ -14,7 +14,7 @@
 
 from operator import attrgetter
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from zope.interface import implementer
 
 from lp.services.librarian.browser import (
@@ -71,13 +71,13 @@
     usedfor = ISourcePackagePublishingHistory
 
 
+@delegate_to(IPackageDiff)
 class ProxiedPackageDiff:
     """A `PackageDiff` extension.
 
     Instead of `LibraryFileAlias` returns `ProxiedLibraryFileAlias`, so
     their 'http_url' attribute can be used in the template.
     """
-    delegates(IPackageDiff)
 
     def __init__(self, context, parent):
         self.context = context

=== modified file 'lib/lp/soyuz/browser/queue.py'
--- lib/lp/soyuz/browser/queue.py	2013-05-28 06:34:11 +0000
+++ lib/lp/soyuz/browser/queue.py	2015-07-09 20:17:15 +0000
@@ -12,7 +12,7 @@
 
 from operator import attrgetter
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from zope.component import getUtility
 from zope.security.proxy import removeSecurityProxy
 
@@ -475,6 +475,7 @@
     usedfor = IPackageUpload
 
 
+@delegate_to(IPackageUpload)
 class CompletePackageUpload:
     """A decorated `PackageUpload` including sources, builds and packages.
 
@@ -494,8 +495,6 @@
     contains_build = None
     sourcepackagerelease = None
 
-    delegates(IPackageUpload)
-
     def __init__(self, packageupload, build_upload_files,
                  source_upload_files, package_sets):
         self.pocket = packageupload.pocket

=== modified file 'lib/lp/soyuz/model/distributionjob.py'
--- lib/lp/soyuz/model/distributionjob.py	2015-07-08 16:05:11 +0000
+++ lib/lp/soyuz/model/distributionjob.py	2015-07-09 20:17:15 +0000
@@ -8,7 +8,7 @@
     "DistributionJobDerived",
 ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from storm.locals import (
     And,
     Int,
@@ -67,13 +67,12 @@
         return DistributionJobDerived.makeSubclass(self)
 
 
+@delegate_to(IDistributionJob)
 class DistributionJobDerived(BaseRunnableJob):
     """Abstract class for deriving from DistributionJob."""
 
     __metaclass__ = EnumeratedSubclass
 
-    delegates(IDistributionJob)
-
     def __init__(self, job):
         self.context = job
 

=== modified file 'lib/lp/soyuz/model/distributionsourcepackagerelease.py'
--- lib/lp/soyuz/model/distributionsourcepackagerelease.py	2015-07-08 16:05:11 +0000
+++ lib/lp/soyuz/model/distributionsourcepackagerelease.py	2015-07-09 20:17:15 +0000
@@ -11,7 +11,7 @@
 
 from operator import itemgetter
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from storm.expr import (
     And,
     Desc,
@@ -39,6 +39,7 @@
 
 
 @implementer(IDistributionSourcePackageRelease)
+@delegate_to(ISourcePackageRelease, context='sourcepackagerelease')
 class DistributionSourcePackageRelease:
     """This is a "Magic Distribution Source Package Release". It is not an
     SQLObject, but it represents the concept of a specific source package
@@ -46,8 +47,6 @@
     information.
     """
 
-    delegates(ISourcePackageRelease, context='sourcepackagerelease')
-
     def __init__(self, distribution, sourcepackagerelease):
         self.distribution = distribution
         self.sourcepackagerelease = sourcepackagerelease

=== modified file 'lib/lp/soyuz/model/packagecopyjob.py'
--- lib/lp/soyuz/model/packagecopyjob.py	2015-07-08 16:05:11 +0000
+++ lib/lp/soyuz/model/packagecopyjob.py	2015-07-09 20:17:15 +0000
@@ -10,7 +10,7 @@
 
 import logging
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.jobrunner.jobrunner import SuspendJobException
 from psycopg2.extensions import TransactionRollbackError
 from storm.locals import (
@@ -174,13 +174,12 @@
         return PackageCopyJobDerived.makeSubclass(self)
 
 
+@delegate_to(IPackageCopyJob)
 class PackageCopyJobDerived(BaseRunnableJob):
     """Abstract class for deriving from PackageCopyJob."""
 
     __metaclass__ = EnumeratedSubclass
 
-    delegates(IPackageCopyJob)
-
     def __init__(self, job):
         self.context = job
         self.logger = logging.getLogger()

=== modified file 'lib/lp/soyuz/model/packagediffjob.py'
--- lib/lp/soyuz/model/packagediffjob.py	2015-07-08 16:05:11 +0000
+++ lib/lp/soyuz/model/packagediffjob.py	2015-07-09 20:17:15 +0000
@@ -7,7 +7,7 @@
     'PackageDiffJob',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 import simplejson
 from zope.component import getUtility
 from zope.interface import (
@@ -30,12 +30,12 @@
     )
 
 
+@delegate_to(IPackageDiffJob)
 @provider(IPackageDiffJobSource)
 class PackageDiffJobDerived(BaseRunnableJob):
 
     __metaclass__ = EnumeratedSubclass
 
-    delegates(IPackageDiffJob)
     config = config.IPackageDiffJobSource
 
     def __init__(self, job):

=== modified file 'lib/lp/soyuz/model/packagetranslationsuploadjob.py'
--- lib/lp/soyuz/model/packagetranslationsuploadjob.py	2015-07-08 16:05:11 +0000
+++ lib/lp/soyuz/model/packagetranslationsuploadjob.py	2015-07-09 20:17:15 +0000
@@ -8,7 +8,7 @@
     'PackageTranslationsUploadJob',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 import simplejson
 from zope.component import getUtility
 from zope.interface import (
@@ -69,12 +69,12 @@
     return filename
 
 
+@delegate_to(IPackageTranslationsUploadJob)
 @provider(IPackageTranslationsUploadJobSource)
 class PackageTranslationsUploadJobDerived(BaseRunnableJob):
 
     __metaclass__ = EnumeratedSubclass
 
-    delegates(IPackageTranslationsUploadJob)
     config = config.IPackageTranslationsUploadJobSource
 
     def __init__(self, job):

=== modified file 'lib/lp/soyuz/model/reporting.py'
--- lib/lp/soyuz/model/reporting.py	2015-07-08 16:05:11 +0000
+++ lib/lp/soyuz/model/reporting.py	2015-07-09 20:17:15 +0000
@@ -6,7 +6,7 @@
     'LatestPersonSourcePackageReleaseCache',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from storm.base import Storm
 from storm.locals import (
     Int,
@@ -24,9 +24,9 @@
 
 
 @implementer(ILatestPersonSourcePackageReleaseCache)
+@delegate_to(ISourcePackageRelease, context='sourcepackagerelease')
 class LatestPersonSourcePackageReleaseCache(Storm):
     """See `LatestPersonSourcePackageReleaseCache`."""
-    delegates(ISourcePackageRelease, context='sourcepackagerelease')
 
     __storm_table__ = 'LatestPersonSourcePackageReleaseCache'
 

=== modified file 'lib/lp/soyuz/scripts/packagecopier.py'
--- lib/lp/soyuz/scripts/packagecopier.py	2015-05-06 10:55:59 +0000
+++ lib/lp/soyuz/scripts/packagecopier.py	2015-07-09 20:17:15 +0000
@@ -14,7 +14,7 @@
     ]
 
 import apt_pkg
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from zope.component import getUtility
 from zope.security.proxy import removeSecurityProxy
 
@@ -120,6 +120,7 @@
     return False
 
 
+@delegate_to(ISourcePackagePublishingHistory)
 class CheckedCopy:
     """Representation of a copy that was checked and approved.
 
@@ -127,7 +128,6 @@
     `getStatusSummaryForBuilds` to return `BuildSetStatus.NEEDSBUILD`
     for source-only copies.
     """
-    delegates(ISourcePackagePublishingHistory)
 
     def __init__(self, context, include_binaries):
         self.context = context

=== modified file 'lib/lp/translations/model/translationsharingjob.py'
--- lib/lp/translations/model/translationsharingjob.py	2013-06-20 05:50:00 +0000
+++ lib/lp/translations/model/translationsharingjob.py	2015-07-09 20:17:15 +0000
@@ -11,7 +11,7 @@
     'TranslationSharingJobDerived',
     ]
 
-from lazr.delegates import delegates
+from lazr.delegates import delegate_to
 from lazr.enum import (
     DBEnumeratedType,
     DBItem,
@@ -63,6 +63,7 @@
         """)
 
 
+@delegate_to(IJob, context='job')
 class TranslationSharingJob(StormBase):
     """Base class for jobs related to a packaging."""
 
@@ -74,8 +75,6 @@
 
     job = Reference(job_id, Job.id)
 
-    delegates(IJob, 'job')
-
     job_type = EnumCol(enum=TranslationSharingJobType, notNull=True)
 
     productseries_id = Int('productseries')
@@ -114,13 +113,12 @@
         return TranslationSharingJobDerived.makeSubclass(self)
 
 
+@delegate_to(ITranslationSharingJob, context='job')
 class TranslationSharingJobDerived:
     """Base class for specialized TranslationTemplate Job types."""
 
     __metaclass__ = EnumeratedSubclass
 
-    delegates(ITranslationSharingJob, 'job')
-
     def getDBClass(self):
         return TranslationSharingJob
 

=== modified file 'versions.cfg'
--- versions.cfg	2015-07-02 11:58:33 +0000
+++ versions.cfg	2015-07-09 20:17:15 +0000
@@ -47,7 +47,7 @@
 lazr.authentication = 0.1.1
 lazr.batchnavigator = 1.2.11
 lazr.config = 1.1.3
-lazr.delegates = 1.2.0
+lazr.delegates = 2.0.3
 lazr.enum = 1.1.3
 lazr.jobrunner = 0.12
 lazr.lifecycle = 1.1


Follow ups