launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #19398
[Merge] lp:~cjwatson/launchpad/import-warnings into lp:launchpad
Colin Watson has proposed merging lp:~cjwatson/launchpad/import-warnings into lp:launchpad.
Commit message:
Fix several import policy violations.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/import-warnings/+merge/271790
Fix several import policy violations.
There are two remaining which I don't quite have the energy to fix now:
You should not import lp.bugs.model.bugtasksearch into:
lp.bugs.browser.buglisting
You should not import lp.code.model.branch into:
lp.code.feed.branch
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/import-warnings into lp:launchpad.
=== modified file 'lib/lp/code/browser/branch.py'
--- lib/lp/code/browser/branch.py 2015-09-18 10:38:27 +0000
+++ lib/lp/code/browser/branch.py 2015-09-21 10:22:52 +0000
@@ -119,14 +119,11 @@
from lp.code.interfaces.branchmergeproposal import IBranchMergeProposal
from lp.code.interfaces.branchtarget import IBranchTarget
from lp.code.interfaces.codereviewvote import ICodeReviewVoteReference
-from lp.code.model.branch import Branch
-from lp.code.model.branchcollection import GenericBranchCollection
from lp.registry.interfaces.person import IPersonSet
from lp.registry.interfaces.productseries import IProductSeries
from lp.registry.vocabularies import UserTeamsParticipationPlusSelfVocabulary
from lp.services import searchbuilder
from lp.services.config import config
-from lp.services.database.bulk import load_related
from lp.services.database.constants import UTC_NOW
from lp.services.feeds.browser import (
BranchFeedLink,
@@ -516,12 +513,7 @@
@cachedproperty
def landing_candidates(self):
"""Return a decorated list of landing candidates."""
- candidates = list(self.context.landing_candidates)
- branches = load_related(
- Branch, candidates, ['source_branchID', 'prerequisite_branchID'])
- GenericBranchCollection.preloadVisibleStackedOnBranches(
- branches, self.user)
- return [proposal for proposal in candidates
+ return [proposal for proposal in self.context.landing_candidates
if check_permission('launchpad.View', proposal)]
@property
=== modified file 'lib/lp/code/browser/gitlisting.py'
--- lib/lp/code/browser/gitlisting.py 2015-07-08 16:05:11 +0000
+++ lib/lp/code/browser/gitlisting.py 2015-09-21 10:22:52 +0000
@@ -10,7 +10,6 @@
'TargetGitListingView',
]
-from storm.expr import Desc
from zope.component import getUtility
from zope.interface import (
implementer,
@@ -26,7 +25,6 @@
IGitNamespacePolicy,
)
from lp.code.interfaces.gitrepository import IGitRepositorySet
-from lp.code.model.gitrepository import GitRepository
from lp.registry.interfaces.persondistributionsourcepackage import (
IPersonDistributionSourcePackage,
)
@@ -50,8 +48,8 @@
def __init__(self, view, repo_collection):
super(GitRepositoryBatchNavigator, self).__init__(
- repo_collection.getRepositories(eager_load=True).order_by(
- Desc(GitRepository.date_last_modified)),
+ repo_collection.getRepositories(
+ eager_load=True, order_by_date=True),
view.request, size=config.launchpad.branchlisting_batch_size)
self.view = view
self.column_count = 2
=== modified file 'lib/lp/code/browser/gitref.py'
--- lib/lp/code/browser/gitref.py 2015-09-18 15:41:08 +0000
+++ lib/lp/code/browser/gitref.py 2015-09-21 10:22:52 +0000
@@ -41,8 +41,6 @@
from lp.code.interfaces.codereviewvote import ICodeReviewVoteReference
from lp.code.interfaces.gitref import IGitRef
from lp.code.interfaces.gitrepository import IGitRepositorySet
-from lp.code.model.gitrepository import GitRepository
-from lp.services.database.bulk import load_related
from lp.services.helpers import english_list
from lp.services.propertycache import cachedproperty
from lp.services.webapp import (
@@ -143,11 +141,7 @@
@cachedproperty
def landing_candidates(self):
"""Return a decorated list of landing candidates."""
- candidates = list(self.context.landing_candidates)
- load_related(
- GitRepository, candidates,
- ["source_git_repositoryID", "prerequisite_git_repositoryID"])
- return [proposal for proposal in candidates
+ return [proposal for proposal in self.context.landing_candidates
if check_permission("launchpad.View", proposal)]
def _getBranchCountText(self, count):
=== modified file 'lib/lp/code/browser/gitrepository.py'
--- lib/lp/code/browser/gitrepository.py 2015-09-18 15:41:08 +0000
+++ lib/lp/code/browser/gitrepository.py 2015-09-21 10:22:52 +0000
@@ -26,7 +26,6 @@
copy_field,
use_template,
)
-from storm.expr import Desc
from zope.event import notify
from zope.formlib import form
from zope.interface import (
@@ -236,17 +235,12 @@
def __init__(self, view, context):
self.context = context
super(GitRefBatchNavigator, self).__init__(
- self._branches, view.request,
+ self.context.branches_by_date, view.request,
size=config.launchpad.branchlisting_batch_size)
self.view = view
self.column_count = 3
@property
- def _branches(self):
- from lp.code.model.gitref import GitRef
- return self.context.branches.order_by(Desc(GitRef.committer_date))
-
- @property
def table_class(self):
# XXX: MichaelHudson 2007-10-18 bug=153894: This means there are two
# ways of sorting a one-page branch listing, which is confusing and
=== modified file 'lib/lp/code/interfaces/gitcollection.py'
--- lib/lp/code/interfaces/gitcollection.py 2015-09-17 11:12:42 +0000
+++ lib/lp/code/interfaces/gitcollection.py 2015-09-21 10:22:52 +0000
@@ -54,7 +54,7 @@
collection.
"""
- def getRepositories(eager_load=False):
+ def getRepositories(eager_load=False, order_by_date=False):
"""Return a result set of all repositories in this collection.
The returned result set will also join across the specified tables
@@ -64,6 +64,8 @@
:param eager_load: If True trigger eager loading of all the related
objects in the collection.
+ :param order_by_date: If True, order results by descending
+ modification date.
"""
def getRepositoryIds():
=== modified file 'lib/lp/code/interfaces/gitrepository.py'
--- lib/lp/code/interfaces/gitrepository.py 2015-09-17 08:52:02 +0000
+++ lib/lp/code/interfaces/gitrepository.py 2015-09-21 10:22:52 +0000
@@ -236,6 +236,10 @@
# Really IGitRef, patched in _schema_circular_imports.py.
value_type=Reference(Interface)))
+ branches_by_date = Attribute(
+ "The branch references present in this repository, ordered by last "
+ "commit date.")
+
subscriptions = exported(CollectionField(
title=_("GitSubscriptions associated with this repository."),
readonly=True,
=== modified file 'lib/lp/code/model/branch.py'
--- lib/lp/code/model/branch.py 2015-09-17 11:21:28 +0000
+++ lib/lp/code/model/branch.py 2015-09-21 10:22:52 +0000
@@ -179,6 +179,7 @@
from lp.services.propertycache import cachedproperty
from lp.services.webapp import urlappend
from lp.services.webapp.authorization import check_permission
+from lp.services.webapp.interfaces import ILaunchBag
@implementer(IBranch, IPrivacy, IInformationType)
@@ -474,10 +475,22 @@
@property
def landing_candidates(self):
"""See `IBranch`."""
- return BranchMergeProposal.select("""
- BranchMergeProposal.target_branch = %s AND
- BranchMergeProposal.queue_status NOT IN %s
- """ % sqlvalues(self, BRANCH_MERGE_PROPOSAL_FINAL_STATES))
+ # Circular import.
+ from lp.code.model.branchcollection import GenericBranchCollection
+
+ result = Store.of(self).find(
+ BranchMergeProposal, BranchMergeProposal.target_branch == self,
+ Not(BranchMergeProposal.queue_status.is_in(
+ BRANCH_MERGE_PROPOSAL_FINAL_STATES)))
+
+ def eager_load(rows):
+ user = getUtility(ILaunchBag).user
+ branches = load_related(
+ Branch, rows, ['source_branchID', 'prerequisite_branchID'])
+ GenericBranchCollection.preloadVisibleStackedOnBranches(
+ branches, user)
+
+ return DecoratedResultSet(result, pre_iter_hook=eager_load)
@property
def dependent_branches(self):
=== modified file 'lib/lp/code/model/gitcollection.py'
--- lib/lp/code/model/gitcollection.py 2015-09-17 11:12:42 +0000
+++ lib/lp/code/model/gitcollection.py 2015-09-21 10:22:52 +0000
@@ -198,13 +198,16 @@
load_related(SourcePackageName, repositories, ['sourcepackagename_id'])
load_related(Product, repositories, ['project_id'])
- def getRepositories(self, find_expr=GitRepository, eager_load=False):
+ def getRepositories(self, find_expr=GitRepository, eager_load=False,
+ order_by_date=False):
"""See `IGitCollection`."""
all_tables = set(
self._tables.values() + self._asymmetric_tables.values())
tables = [GitRepository] + list(all_tables)
expressions = self._getRepositoryExpressions()
resultset = self.store.using(*tables).find(find_expr, *expressions)
+ if order_by_date:
+ resultset.order_by(Desc(GitRepository.date_last_modified))
def do_eager_load(rows):
repository_ids = set(repository.id for repository in rows)
=== modified file 'lib/lp/code/model/gitref.py'
--- lib/lp/code/model/gitref.py 2015-09-17 08:52:02 +0000
+++ lib/lp/code/model/gitref.py 2015-09-21 10:22:52 +0000
@@ -45,7 +45,9 @@
BranchMergeProposal,
BranchMergeProposalGetter,
)
+from lp.services.database.bulk import load_related
from lp.services.database.constants import UTC_NOW
+from lp.services.database.decoratedresultset import DecoratedResultSet
from lp.services.database.enumcol import EnumCol
from lp.services.database.interfaces import IStore
from lp.services.database.stormbase import StormBase
@@ -175,13 +177,23 @@
@property
def landing_candidates(self):
"""See `IGitRef`."""
- return Store.of(self).find(
+ # Circular import.
+ from lp.code.model.gitrepository import GitRepository
+
+ result = Store.of(self).find(
BranchMergeProposal,
BranchMergeProposal.target_git_repository == self.repository,
BranchMergeProposal.target_git_path == self.path,
Not(BranchMergeProposal.queue_status.is_in(
BRANCH_MERGE_PROPOSAL_FINAL_STATES)))
+ def eager_load(rows):
+ load_related(
+ GitRepository, rows,
+ ["source_git_repositoryID", "prerequisite_git_repositoryID"])
+
+ return DecoratedResultSet(result, pre_iter_hook=eager_load)
+
@property
def dependent_landings(self):
"""See `IGitRef`."""
=== modified file 'lib/lp/code/model/gitrepository.py'
--- lib/lp/code/model/gitrepository.py 2015-09-17 11:21:28 +0000
+++ lib/lp/code/model/gitrepository.py 2015-09-21 10:22:52 +0000
@@ -24,6 +24,7 @@
from storm.expr import (
And,
Coalesce,
+ Desc,
Insert,
Join,
Not,
@@ -417,6 +418,11 @@
GitRef.path.startswith(u"refs/heads/")).order_by(GitRef.path)
@property
+ def branches_by_date(self):
+ """See `IGitRepository`."""
+ return self.branches.order_by(Desc(GitRef.committer_date))
+
+ @property
def default_branch(self):
"""See `IGitRepository`."""
return self._default_branch
=== modified file 'lib/lp/soyuz/browser/archivesubscription.py'
--- lib/lp/soyuz/browser/archivesubscription.py 2015-07-08 16:05:11 +0000
+++ lib/lp/soyuz/browser/archivesubscription.py 2015-09-21 10:22:52 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2013 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2015 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Browser views related to archive subscriptions."""
@@ -14,10 +14,7 @@
]
import datetime
-from operator import (
- attrgetter,
- itemgetter,
- )
+from operator import attrgetter
import pytz
from zope.component import getUtility
@@ -43,13 +40,8 @@
from lp.app.widgets.date import DateWidget
from lp.app.widgets.popup import PersonPickerWidget
from lp.registry.interfaces.person import IPersonSet
-from lp.services.database.bulk import load_related
from lp.services.fields import PersonChoice
-from lp.services.propertycache import (
- cachedproperty,
- get_property_cache,
- )
-from lp.services.webapp.authorization import precache_permission_for_objects
+from lp.services.propertycache import cachedproperty
from lp.services.webapp.batching import (
BatchNavigator,
StormRangeFactory,
@@ -64,7 +56,6 @@
IArchiveSubscriberSet,
IPersonalArchiveSubscription,
)
-from lp.soyuz.model.archive import Archive
def archive_subscription_ui_adapter(archive_subscription):
@@ -329,14 +320,6 @@
subs_with_tokens = subscriber_set.getBySubscriberWithActiveToken(
self.context)
- subscriptions = map(itemgetter(0), subs_with_tokens)
- precache_permission_for_objects(None, 'launchpad.View', subscriptions)
- archives = load_related(Archive, subscriptions, ['archive_id'])
- list(getUtility(IPersonSet).getPrecachedPersonsFromIDs(
- [archive.ownerID for archive in archives], need_validity=True))
- for archive in archives:
- get_property_cache(archive)._known_subscribers = [self.user]
-
# Turn the result set into a list of dicts so it can be easily
# accessed in TAL. Note that we need to ensure that only one
# PersonalArchiveSubscription is included for each archive,
=== modified file 'lib/lp/soyuz/interfaces/archive.py'
--- lib/lp/soyuz/interfaces/archive.py 2015-09-16 06:53:39 +0000
+++ lib/lp/soyuz/interfaces/archive.py 2015-09-21 10:22:52 +0000
@@ -8,6 +8,7 @@
__all__ = [
'ALLOW_RELEASE_BUILDS',
'AlreadySubscribed',
+ 'ArchiveAlreadyDeleted',
'ArchiveDependencyError',
'ArchiveDisabled',
'ArchiveNotPrivate',
=== modified file 'lib/lp/soyuz/model/archivesubscriber.py'
--- lib/lp/soyuz/model/archivesubscriber.py 2015-07-08 16:05:11 +0000
+++ lib/lp/soyuz/model/archivesubscriber.py 2015-09-21 10:22:52 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2015 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Database class for table ArchiveSubscriber."""
@@ -30,17 +30,25 @@
from zope.component import getUtility
from zope.interface import implementer
-from lp.registry.interfaces.person import validate_person
+from lp.registry.interfaces.person import (
+ IPersonSet,
+ validate_person,
+ )
from lp.registry.model.person import Person
from lp.registry.model.teammembership import TeamParticipation
+from lp.services.database.bulk import load_related
from lp.services.database.constants import UTC_NOW
from lp.services.database.decoratedresultset import DecoratedResultSet
from lp.services.database.enumcol import DBEnum
from lp.services.identity.interfaces.emailaddress import EmailAddressStatus
from lp.services.identity.model.emailaddress import EmailAddress
+from lp.services.propertycache import get_property_cache
+from lp.services.webapp.authorization import precache_permission_for_objects
+from lp.services.webapp.interfaces import ILaunchBag
from lp.soyuz.enums import ArchiveSubscriberStatus
from lp.soyuz.interfaces.archiveauthtoken import IArchiveAuthTokenSet
from lp.soyuz.interfaces.archivesubscriber import IArchiveSubscriber
+from lp.soyuz.model.archive import Archive
from lp.soyuz.model.archiveauthtoken import ArchiveAuthToken
@@ -204,7 +212,20 @@
def getBySubscriberWithActiveToken(self, subscriber, archive=None):
"""See `IArchiveSubscriberSet`."""
- return self._getBySubscriber(subscriber, archive, True, True)
+ result = self._getBySubscriber(subscriber, archive, True, True)
+
+ def eager_load(rows):
+ user = getUtility(ILaunchBag).user
+ subscriptions = map(itemgetter(0), rows)
+ precache_permission_for_objects(
+ None, 'launchpad.View', subscriptions)
+ archives = load_related(Archive, subscriptions, ['archive_id'])
+ list(getUtility(IPersonSet).getPrecachedPersonsFromIDs(
+ [archive.ownerID for archive in archives], need_validity=True))
+ for archive in archives:
+ get_property_cache(archive)._known_subscribers = [user]
+
+ return DecoratedResultSet(result, pre_iter_hook=eager_load)
def getByArchive(self, archive, current_only=True):
"""See `IArchiveSubscriberSet`."""
Follow ups