← Back to team overview

launchpad-reviewers team mailing list archive

Re: [Merge] lp:~cjwatson/launchpad/optimise-publish-a into lp:launchpad

 

Review: Approve code

I'd like to see a couple of minor cleanups, but otherwise looks good.

Diff comments:

> === modified file 'database/sampledata/current-dev.sql'
> --- database/sampledata/current-dev.sql	2014-05-19 11:33:05 +0000
> +++ database/sampledata/current-dev.sql	2014-07-14 17:04:11 +0000
> @@ -2768,7 +2768,6 @@
>  INSERT INTO binarypackagepublishinghistory (id, binarypackagerelease, distroarchseries, status, component, section, priority, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, binarypackagename, phased_update_percentage) VALUES (22, 20, 8, 4, 1, 1, 40, '2006-09-13 00:00:00', '2006-09-13 00:00:01', '2006-09-13 00:00:01', NULL, NULL, '2006-09-13 00:00:02', '2006-09-13 00:00:03', 0, 1, 1, 'nah ...', 13, NULL);
>  INSERT INTO binarypackagepublishinghistory (id, binarypackagerelease, distroarchseries, status, component, section, priority, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, binarypackagename, phased_update_percentage) VALUES (23, 6, 1, 4, 1, 1, 40, '2006-12-01 00:00:00', '2006-12-01 00:00:01', '2006-12-01 00:00:01', NULL, NULL, '2006-12-01 00:00:02', '2006-12-01 00:00:03', 0, 1, 28, 'I do not like it either', 6, NULL);
>  INSERT INTO binarypackagepublishinghistory (id, binarypackagerelease, distroarchseries, status, component, section, priority, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, binarypackagename, phased_update_percentage) VALUES (24, 21, 1, 2, 1, 1, 40, '2006-12-01 00:00:00', '2006-12-01 00:00:01', NULL, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 16, NULL);
> -INSERT INTO binarypackagepublishinghistory (id, binarypackagerelease, distroarchseries, status, component, section, priority, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, binarypackagename, phased_update_percentage) VALUES (25, 12, 1, 2, 1, 1, 10, '2007-01-19 00:00:00', '2007-02-19 00:00:00', NULL, NULL, NULL, NULL, NULL, 0, 8, NULL, NULL, 8, NULL);
>  INSERT INTO binarypackagepublishinghistory (id, binarypackagerelease, distroarchseries, status, component, section, priority, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, binarypackagename, phased_update_percentage) VALUES (26, 22, 1, 2, 1, 1, 40, '2006-04-11 13:00:00', '2006-04-11 13:00:01', NULL, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 8, NULL);
>  INSERT INTO binarypackagepublishinghistory (id, binarypackagerelease, distroarchseries, status, component, section, priority, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, binarypackagename, phased_update_percentage) VALUES (27, 22, 1, 2, 1, 1, 40, '2007-07-10 13:00:00', '2007-07-10 13:00:01', NULL, NULL, NULL, NULL, NULL, 0, 9, NULL, NULL, 8, NULL);
>  INSERT INTO binarypackagepublishinghistory (id, binarypackagerelease, distroarchseries, status, component, section, priority, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, binarypackagename, phased_update_percentage) VALUES (28, 23, 1, 2, 1, 1, 40, '2007-07-10 13:00:00', '2007-07-10 13:00:01', NULL, NULL, NULL, NULL, NULL, 0, 9, NULL, NULL, 13, NULL);
> @@ -4826,7 +4825,6 @@
>  INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (21, 24, 11, 4, 1, 3, '2006-09-14 11:44:00.10654', '2006-09-14 11:44:00', '2006-09-14 11:44:01', 25, '2006-09-14 11:45:00', '2006-09-14 11:45:00', '2006-09-15 11:45:00', 0, 8, 1, 'does anyone like ? I did not think so.', NULL, 19, NULL, NULL, NULL);
>  INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (22, 32, 1, 4, 1, 3, '2006-12-01 13:44:00.10654', '2006-12-01 11:44:00', NULL, NULL, NULL, NULL, '2006-12-02 11:44:00', 0, 1, 28, 'I do not like it.', NULL, 23, NULL, NULL, NULL);
>  INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (23, 33, 1, 2, 1, 3, '2006-12-01 13:44:00.10654', '2006-12-01 11:44:00', NULL, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, NULL, 24, NULL, NULL, NULL);
> -INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (24, 14, 1, 2, 1, 2, '2006-02-19 11:57:13', '2007-02-19 11:57:13', NULL, NULL, NULL, NULL, NULL, 0, 8, NULL, NULL, NULL, 1, NULL, NULL, NULL);
>  INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (25, 33, 10, 2, 1, 3, '2007-04-25 13:44:00.10654', '2007-04-25 14:14:00', NULL, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, NULL, 24, NULL, NULL, NULL);
>  INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (26, 35, 1, 2, 1, 3, '2006-04-11 12:00:00', '2006-04-11 12:00:01', NULL, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, NULL, 26, NULL, NULL, NULL);
>  INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (27, 33, 10, 2, 1, 3, '2007-07-09 13:44:00.10654', '2007-07-09 14:14:00', NULL, NULL, NULL, NULL, NULL, 0, 9, NULL, NULL, NULL, 24, NULL, NULL, NULL);
> 
> === modified file 'database/sampledata/current.sql'
> --- database/sampledata/current.sql	2014-05-19 11:33:05 +0000
> +++ database/sampledata/current.sql	2014-07-14 17:04:11 +0000
> @@ -2705,7 +2705,6 @@
>  INSERT INTO binarypackagepublishinghistory (id, binarypackagerelease, distroarchseries, status, component, section, priority, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, binarypackagename, phased_update_percentage) VALUES (22, 20, 8, 4, 1, 1, 40, '2006-09-13 00:00:00', '2006-09-13 00:00:01', '2006-09-13 00:00:01', NULL, NULL, '2006-09-13 00:00:02', '2006-09-13 00:00:03', 0, 1, 1, 'nah ...', 13, NULL);
>  INSERT INTO binarypackagepublishinghistory (id, binarypackagerelease, distroarchseries, status, component, section, priority, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, binarypackagename, phased_update_percentage) VALUES (23, 6, 1, 4, 1, 1, 40, '2006-12-01 00:00:00', '2006-12-01 00:00:01', '2006-12-01 00:00:01', NULL, NULL, '2006-12-01 00:00:02', '2006-12-01 00:00:03', 0, 1, 28, 'I do not like it either', 6, NULL);
>  INSERT INTO binarypackagepublishinghistory (id, binarypackagerelease, distroarchseries, status, component, section, priority, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, binarypackagename, phased_update_percentage) VALUES (24, 21, 1, 2, 1, 1, 40, '2006-12-01 00:00:00', '2006-12-01 00:00:01', NULL, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 16, NULL);
> -INSERT INTO binarypackagepublishinghistory (id, binarypackagerelease, distroarchseries, status, component, section, priority, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, binarypackagename, phased_update_percentage) VALUES (25, 12, 1, 2, 1, 1, 10, '2007-01-19 00:00:00', '2007-02-19 00:00:00', NULL, NULL, NULL, NULL, NULL, 0, 8, NULL, NULL, 8, NULL);
>  INSERT INTO binarypackagepublishinghistory (id, binarypackagerelease, distroarchseries, status, component, section, priority, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, binarypackagename, phased_update_percentage) VALUES (26, 22, 1, 2, 1, 1, 40, '2006-04-11 13:00:00', '2006-04-11 13:00:01', NULL, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 8, NULL);
>  INSERT INTO binarypackagepublishinghistory (id, binarypackagerelease, distroarchseries, status, component, section, priority, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, binarypackagename, phased_update_percentage) VALUES (27, 22, 1, 2, 1, 1, 40, '2007-07-10 13:00:00', '2007-07-10 13:00:01', NULL, NULL, NULL, NULL, NULL, 0, 9, NULL, NULL, 8, NULL);
>  INSERT INTO binarypackagepublishinghistory (id, binarypackagerelease, distroarchseries, status, component, section, priority, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, binarypackagename, phased_update_percentage) VALUES (28, 23, 1, 2, 1, 1, 40, '2007-07-10 13:00:00', '2007-07-10 13:00:01', NULL, NULL, NULL, NULL, NULL, 0, 9, NULL, NULL, 13, NULL);
> @@ -4753,7 +4752,6 @@
>  INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (21, 24, 11, 4, 1, 3, '2006-09-14 11:44:00.10654', '2006-09-14 11:44:00', '2006-09-14 11:44:01', 25, '2006-09-14 11:45:00', '2006-09-14 11:45:00', '2006-09-15 11:45:00', 0, 8, 1, 'does anyone like ? I did not think so.', NULL, 19, NULL, NULL, NULL);
>  INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (22, 32, 1, 4, 1, 3, '2006-12-01 13:44:00.10654', '2006-12-01 11:44:00', NULL, NULL, NULL, NULL, '2006-12-02 11:44:00', 0, 1, 28, 'I do not like it.', NULL, 23, NULL, NULL, NULL);
>  INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (23, 33, 1, 2, 1, 3, '2006-12-01 13:44:00.10654', '2006-12-01 11:44:00', NULL, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, NULL, 24, NULL, NULL, NULL);
> -INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (24, 14, 1, 2, 1, 2, '2006-02-19 11:57:13', '2007-02-19 11:57:13', NULL, NULL, NULL, NULL, NULL, 0, 8, NULL, NULL, NULL, 1, NULL, NULL, NULL);
>  INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (25, 33, 10, 2, 1, 3, '2007-04-25 13:44:00.10654', '2007-04-25 14:14:00', NULL, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, NULL, 24, NULL, NULL, NULL);
>  INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (26, 35, 1, 2, 1, 3, '2006-04-11 12:00:00', '2006-04-11 12:00:01', NULL, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, NULL, 26, NULL, NULL, NULL);
>  INSERT INTO sourcepackagepublishinghistory (id, sourcepackagerelease, distroseries, status, component, section, datecreated, datepublished, datesuperseded, supersededby, datemadepending, scheduleddeletiondate, dateremoved, pocket, archive, removed_by, removal_comment, ancestor, sourcepackagename, creator, sponsor, packageupload) VALUES (27, 33, 10, 2, 1, 3, '2007-07-09 13:44:00.10654', '2007-07-09 14:14:00', NULL, NULL, NULL, NULL, NULL, 0, 9, NULL, NULL, NULL, 24, NULL, NULL, NULL);
> 
> === modified file 'lib/lp/archivepublisher/publishing.py'
> --- lib/lp/archivepublisher/publishing.py	2014-07-09 12:19:54 +0000
> +++ lib/lp/archivepublisher/publishing.py	2014-07-14 17:04:11 +0000
> @@ -13,7 +13,9 @@
>  from datetime import datetime
>  import errno
>  import hashlib
> +from itertools import groupby
>  import logging
> +from operator import attrgetter
>  import os
>  import shutil
>  
> @@ -22,7 +24,6 @@
>      Release,
>      )
>  from storm.expr import Desc
> -from storm.store import EmptyResultSet
>  from zope.component import getUtility
>  
>  from lp.app.interfaces.launchpad import ILaunchpadCelebrities
> @@ -48,6 +49,7 @@
>      pocketsuffix,
>      )
>  from lp.registry.interfaces.series import SeriesStatus
> +from lp.registry.model.distroseries import DistroSeries
>  from lp.services.database.constants import UTC_NOW
>  from lp.services.database.interfaces import IStore
>  from lp.services.librarian.client import LibrarianClient
> @@ -295,44 +297,18 @@
>              # provide custom builds for users who haven't upgraded yet.
>              return self.distro.series
>  
> -    def checkLegalPocket(self, distroseries, publication, is_careful):
> +    def checkLegalPocket(self, distroseries, pocket, is_careful):
>          """Check if the publication can happen in the archive."""
> +        if distroseries not in self.consider_series:
> +            return False
>          # 'careful' mode re-publishes everything:
>          if is_careful:
>              return True
> -
> -        if not publication.archive.canModifySuite(
> -                distroseries, publication.pocket):
> -            self.log.error(
> -                "Tried to publish %s (%s) into the %s pocket on series %s "
> -                "(%s), skipping" % (
> -                    publication.displayname, publication.id,
> -                    publication.pocket, distroseries.displayname,
> -                    distroseries.status.name))
> -            return False
> -
> -        return True
> -
> -    def getPendingSourcePublications(self, distroseries, pocket, is_careful):
> -        """Return the specific group of source records to be published.
> -
> -        If the distroseries is already released, it automatically refuses
> -        to publish records to the RELEASE pocket.
> -        """
> -        # Exclude RELEASE pocket if the distroseries was already released,
> -        # since it should not change for main archive.
> -        # We allow RELEASE publishing for PPAs.
> -        # We also allow RELEASE publishing for partner.
> -        if (pocket == PackagePublishingPocket.RELEASE and
> -            not distroseries.isUnstable() and
> -            not self.archive.allowUpdatesToReleasePocket()):
> -            return EmptyResultSet()
> -
> -        conditions = [
> -            SourcePackagePublishingHistory.distroseries == distroseries,
> -            SourcePackagePublishingHistory.pocket == pocket,
> -            SourcePackagePublishingHistory.archive == self.archive,
> -            ]
> +        return self.archive.canModifySuite(distroseries, pocket)
> +
> +    def getPendingSourcePublications(self, is_careful):
> +        """Return the specific group of source records to be published."""
> +        conditions = [SourcePackagePublishingHistory.archive == self.archive]
>  
>          # Careful publishing should include all PUBLISHED rows, normal run
>          # only includes PENDING ones.
> @@ -344,47 +320,53 @@
>  
>          publications = IStore(SourcePackagePublishingHistory).find(
>              SourcePackagePublishingHistory, *conditions)

Consider inlining the two conditions; all that varies now is the particular set of statuses.

> -        return publications.order_by(Desc(SourcePackagePublishingHistory.id))
> -
> -    def publishSources(self, distroseries, pocket, is_careful=False):
> -        """Publish sources for a given distroseries and pocket.
> +        return publications.order_by(
> +            SourcePackagePublishingHistory.distroseriesID,
> +            SourcePackagePublishingHistory.pocket,
> +            Desc(SourcePackagePublishingHistory.id))
> +
> +    def publishSources(self, distroseries, pocket, spphs):
> +        """Publish sources for a given distroseries and pocket."""
> +        self.log.debug(
> +            "Publishing pending sources for %s" %
> +            distroseries.getSuite(pocket))
> +        for spph in spphs:
> +            spph.publish(self._diskpool, self.log)

I'd inline publishSources and publishBinaries. Two of the three parameters are only used for logging, and the message is inconsistent with the other two messages in findAndPublish*. You can probably unify the logging somewhat once the loop is inlined.

> +
> +    def findAndPublishSources(self, is_careful=False):
> +        """Search for and publish all pending sources.
>  
>          :param is_careful: If True, republish all published records (system
>              will DTRT checking the hash of all published files).
>  
>          Consider records returned by getPendingSourcePublications.
>          """
> -        self.log.debug("Publishing %s-%s" % (distroseries.title, pocket.name))
> -        self.log.debug("Attempting to publish pending sources.")
> -
>          dirty_pockets = set()
> -        for spph in self.getPendingSourcePublications(
> -                distroseries, pocket, is_careful):
> -            if not self.checkLegalPocket(distroseries, spph, is_careful):
> -                continue
> -            spph.publish(self._diskpool, self.log)
> -            dirty_pockets.add((distroseries.name, spph.pocket))
> +        all_spphs = self.getPendingSourcePublications(is_careful)
> +        for (distroseries, pocket), spphs in groupby(
> +                all_spphs, attrgetter("distroseries", "pocket")):
> +            if not self.isAllowed(distroseries, pocket):
> +                self.log.debug("* Skipping %s", distroseries.getSuite(pocket))
> +            elif not self.checkLegalPocket(distroseries, pocket, is_careful):
> +                for spph in spphs:
> +                    self.log.error(
> +                        "Tried to publish %s (%s) into the %s pocket on "
> +                        "series %s (%s), skipping" % (
> +                            spph.displayname, spph.id, pocket,
> +                            distroseries.displayname,
> +                            distroseries.status.name))
> +            else:
> +                self.publishSources(distroseries, pocket, spphs)
> +                dirty_pockets.add((distroseries.name, pocket))
>          return dirty_pockets
>  
> -    def getPendingBinaryPublications(self, distroarchseries, pocket,
> -                                     is_careful):
> -        """Return the specific group of binary records to be published.
> -
> -        If the distroseries is already released, it automatically refuses
> -        to publish records to the RELEASE pocket.
> -        """
> -        # Exclude RELEASE pocket if the distroseries was already released,
> -        # since it should not change, unless the archive allows it.
> -        if (pocket == PackagePublishingPocket.RELEASE and
> -            not distroarchseries.distroseries.isUnstable() and
> -            not self.archive.allowUpdatesToReleasePocket()):
> -            return EmptyResultSet()
> -
> +    def getPendingBinaryPublications(self, is_careful):
> +        """Return the specific group of binary records to be published."""
>          conditions = [
> -            BinaryPackagePublishingHistory.distroarchseries ==
> -                distroarchseries,
> -            BinaryPackagePublishingHistory.pocket == pocket,
>              BinaryPackagePublishingHistory.archive == self.archive,
> +            BinaryPackagePublishingHistory.distroarchseriesID ==
> +                DistroArchSeries.id,
> +            DistroArchSeries.distroseriesID == DistroSeries.id,
>              ]
>  
>          statuses = [PackagePublishingStatus.PENDING]
> @@ -395,27 +377,47 @@
>  
>          publications = IStore(BinaryPackagePublishingHistory).find(
>              BinaryPackagePublishingHistory, *conditions)
> -        return publications.order_by(Desc(BinaryPackagePublishingHistory.id))
> -
> -    def publishBinaries(self, distroarchseries, pocket, is_careful=False):
> -        """Publish binaries for a given distroseries and pocket.
> +        return publications.order_by(
> +            DistroSeries.id,
> +            BinaryPackagePublishingHistory.pocket,
> +            DistroArchSeries.architecturetag,
> +            Desc(BinaryPackagePublishingHistory.id))
> +
> +    def publishBinaries(self, distroarchseries, pocket, bpphs):
> +        """Publish binaries for a given distroarchseries and pocket."""
> +        self.log.debug(
> +            "Publishing pending binaries for %s/%s" % (
> +                distroarchseries.distroseries.getSuite(pocket),
> +                distroarchseries.architecturetag))
> +        for bpph in bpphs:
> +            bpph.publish(self._diskpool, self.log)
> +
> +    def findAndPublishBinaries(self, is_careful=False):
> +        """Search for and publish all pending binaries.
>  
>          :param is_careful: If True, republish all published records (system
>              will DTRT checking the hash of all published files).
>  
>          Consider records returned by getPendingBinaryPublications.
>          """
> -        self.log.debug("Attempting to publish pending binaries for %s"
> -              % distroarchseries.architecturetag)
> -
> -        distroseries = distroarchseries.distroseries
>          dirty_pockets = set()
> -        for bpph in self.getPendingBinaryPublications(
> -                distroarchseries, pocket, is_careful):
> -            if not self.checkLegalPocket(distroseries, bpph, is_careful):
> -                continue
> -            bpph.publish(self._diskpool, self.log)
> -            dirty_pockets.add((distroseries.name, bpph.pocket))
> +        all_bpphs = self.getPendingBinaryPublications(is_careful)
> +        for (distroarchseries, pocket), bpphs in groupby(
> +                all_bpphs, attrgetter("distroarchseries", "pocket")):
> +            distroseries = distroarchseries.distroseries
> +            if not self.isAllowed(distroseries, pocket):
> +                pass  # Already logged by publishSources.
> +            elif not self.checkLegalPocket(distroseries, pocket, is_careful):
> +                for bpph in bpphs:
> +                    self.log.error(
> +                        "Tried to publish %s (%s) into the %s pocket on "
> +                        "series %s (%s), skipping" % (
> +                            bpph.displayname, bpph.id, pocket,
> +                            distroseries.displayname,
> +                            distroseries.status.name))
> +            else:
> +                self.publishBinaries(distroarchseries, pocket, bpphs)
> +                dirty_pockets.add((distroseries.name, pocket))
>          return dirty_pockets
>  
>      def A_publish(self, force_publishing):
> @@ -428,18 +430,10 @@
>          """
>          self.log.debug("* Step A: Publishing packages")
>  
> -        for distroseries in self.consider_series:
> -            for pocket in self.archive.getPockets():
> -                if self.isAllowed(distroseries, pocket):
> -                    self.dirty_pockets.update(self.publishSources(
> -                        distroseries, pocket, is_careful=force_publishing))
> -                    for distroarchseries in distroseries.architectures:
> -                        self.dirty_pockets.update(self.publishBinaries(
> -                            distroarchseries, pocket,
> -                            is_careful=force_publishing))
> -                else:
> -                    self.log.debug(
> -                        "* Skipping %s/%s", distroseries.name, pocket.name)
> +        self.dirty_pockets.update(
> +            self.findAndPublishSources(is_careful=force_publishing))
> +        self.dirty_pockets.update(
> +            self.findAndPublishBinaries(is_careful=force_publishing))
>  
>      def A2_markPocketsWithDeletionsDirty(self):
>          """An intermediate step in publishing to detect deleted packages.
> 
> === modified file 'lib/lp/archivepublisher/tests/test_publisher.py'
> --- lib/lp/archivepublisher/tests/test_publisher.py	2014-07-09 01:18:27 +0000
> +++ lib/lp/archivepublisher/tests/test_publisher.py	2014-07-14 17:04:11 +0000
> @@ -171,12 +171,10 @@
>      def checkLegalPocket(self, status, pocket):
>          distroseries = self.factory.makeDistroSeries(
>              distribution=self.ubuntutest, status=status)
> -        spph = self.factory.makeSourcePackagePublishingHistory(
> -            distroseries=distroseries, pocket=pocket)
>          publisher = Publisher(
>              self.logger, self.config, self.disk_pool,
>              distroseries.main_archive)
> -        return publisher.checkLegalPocket(distroseries, spph, False)
> +        return publisher.checkLegalPocket(distroseries, pocket, False)
>  
>      def test_checkLegalPocket_allows_unstable_release(self):
>          """Publishing to RELEASE in a DEVELOPMENT series is allowed."""
> @@ -194,17 +192,17 @@
>              SeriesStatus.DEVELOPMENT, PackagePublishingPocket.UPDATES))
>  
>      def test_checkLegalPocket_forbids_stable_release(self):
> -        """Publishing to RELEASE in a DEVELOPMENT series is forbidden."""
> +        """Publishing to RELEASE in a CURRENT series is forbidden."""
>          self.assertFalse(self.checkLegalPocket(
>              SeriesStatus.CURRENT, PackagePublishingPocket.RELEASE))
>  
>      def test_checkLegalPocket_allows_stable_proposed(self):
> -        """Publishing to PROPOSED in a DEVELOPMENT series is allowed."""
> +        """Publishing to PROPOSED in a CURRENT series is allowed."""
>          self.assertTrue(self.checkLegalPocket(
>              SeriesStatus.CURRENT, PackagePublishingPocket.PROPOSED))
>  
>      def test_checkLegalPocket_allows_stable_updates(self):
> -        """Publishing to UPDATES in a DEVELOPMENT series is allowed."""
> +        """Publishing to UPDATES in a CURRENT series is allowed."""
>          self.assertTrue(self.checkLegalPocket(
>              SeriesStatus.CURRENT, PackagePublishingPocket.UPDATES))
>  
> @@ -218,11 +216,8 @@
>      def _publish(self, pocket, is_careful=False):
>          """Publish the test IDistroSeries and its IDistroArchSeries."""
>          self._ensurePublisher()
> -        self.publisher.publishSources(
> -            self.breezy_autotest, pocket, is_careful=is_careful)
> -        for distroarchseries in self.breezy_autotest.architectures:
> -            self.publisher.publishBinaries(
> -                distroarchseries, pocket, is_careful=is_careful)
> +        self.publisher.findAndPublishSources(is_careful=is_careful)
> +        self.publisher.findAndPublishBinaries(is_careful=is_careful)
>          self.layer.txn.commit()
>  
>      def checkPublicationsAreConsidered(self, pocket):
> @@ -261,26 +256,30 @@
>          self.assertEqual(pub_source.status, PackagePublishingStatus.PENDING)
>          self.assertEqual(pub_bin.status, PackagePublishingStatus.PENDING)
>  
> -    def checkSourceLookupForPocket(self, pocket, expected_result,
> -                                   is_careful=False):
> +    def checkSourceLookup(self, expected_result, is_careful=False):
>          """Check the results of an IDistroSeries publishing lookup."""
>          self._ensurePublisher()
>          pub_records = self.publisher.getPendingSourcePublications(
> -            self.breezy_autotest, pocket, is_careful=is_careful)
> +            is_careful=is_careful)
> +        pub_records = [
> +            pub for pub in pub_records
> +                if pub.distroseries == self.breezy_autotest]
>  
> -        self.assertEqual(pub_records.count(), len(expected_result))
> +        self.assertEqual(len(expected_result), len(pub_records))
>          self.assertEqual(
>              [item.id for item in expected_result],
>              [pub.id for pub in pub_records])
>  
> -    def checkBinaryLookupForPocket(self, pocket, expected_result,
> -                                   is_careful=False):
> +    def checkBinaryLookup(self, expected_result, is_careful=False):
>          """Check the results of an IDistroArchSeries publishing lookup."""
>          self._ensurePublisher()
>          pub_records = self.publisher.getPendingBinaryPublications(
> -            self.breezy_autotest_i386, pocket, is_careful=is_careful)
> +            is_careful=is_careful)
> +        pub_records = [
> +            pub for pub in pub_records
> +                if pub.distroarchseries == self.breezy_autotest_i386]
>  
> -        self.assertEqual(pub_records.count(), len(expected_result))
> +        self.assertEqual(len(expected_result), len(pub_records))
>          self.assertEqual(
>              [item.id for item in expected_result],
>              [pub.id for pub in pub_records])
> @@ -329,223 +328,52 @@
>          self.checkPublicationsAreConsidered(PackagePublishingPocket.UPDATES)
>          self.checkPublicationsAreConsidered(PackagePublishingPocket.RELEASE)
>  
> -    def testPublicationLookUpForUnstableDistroSeries(self):
> -        """Source publishing record lookup for a unstable DistroSeries.
> -
> -        Check if Publisher.getPendingSourcePublications() works properly for
> -        a DistroSeries when it is still in development, 'unreleased'.
> -        """
> -        pub_pending_release, pub_published_release, pub_pending_updates = (
> -            self._createDefaultSourcePublications())
> -
> -        # Usual publication procedure for a distroseries in development
> -        # state only 'pending' publishing records for pocket RELEASE
> -        # are published.
> -        self.checkSourceLookupForPocket(
> -            PackagePublishingPocket.RELEASE,
> -            expected_result=[pub_pending_release])
> -
> -        # This step is unusual but checks if the pocket restriction also
> -        # work for other pockets than the RELEASE.
> -        self.checkSourceLookupForPocket(
> -            PackagePublishingPocket.UPDATES,
> -            expected_result=[pub_pending_updates])
> -
> -        # Restricting to a pocket with no publication returns an
> -        # empty SQLResult.
> -        self.checkSourceLookupForPocket(
> -            PackagePublishingPocket.BACKPORTS, expected_result=[])
> -
> -        # Using the 'careful' mode results in the consideration
> -        # of every 'pending' and 'published' records present in
> -        # the given pocket. The order is also important, NEWER first.
> -        self.checkSourceLookupForPocket(
> -            PackagePublishingPocket.RELEASE, is_careful=True,
> -            expected_result=[pub_published_release, pub_pending_release])
> -
> -    def testPublicationLookUpForStableDistroSeries(self):
> -        """Source publishing record lookup for a stable/released DistroSeries.
> -
> -        Check if Publisher.getPendingSourcePublications() works properly for
> -        a DistroSeries when it is not in development anymore, i.e.,
> -        'released'.
> -        """
> -        pub_pending_release, pub_published_release, pub_pending_updates = (
> -            self._createDefaultSourcePublications())
> -
> -        # Release 'breezy-autotest'.
> -        self.breezy_autotest.status = SeriesStatus.CURRENT
> -        self.layer.commit()
> -
> -        # Since the distroseries is stable, nothing is returned because
> -        # RELEASE pocket is ignored, in both modes, careful or not.
> -        self.checkSourceLookupForPocket(
> -            PackagePublishingPocket.RELEASE, expected_result=[])
> -
> -        # XXX cprov 2007-01-05: it means that "careful" mode is useless for
> -        # rebuilding released archives.
> -        # This is quite right, IMHO, since republication of a released
> -        # archive will, obviously contain new timestamps, which would freak
> -        # mirrors/clients out.
> -        # At the end, "careful" mode is such a gross hack.
> -        self.checkSourceLookupForPocket(
> -            PackagePublishingPocket.RELEASE, is_careful=True,
> -            expected_result=[])
> -
> -        # Publications targeted to other pockets than RELEASE are
> -        # still reachable.
> -        self.checkSourceLookupForPocket(
> -            PackagePublishingPocket.UPDATES,
> -            expected_result=[pub_pending_updates])
> -
> -    def testPublicationLookUpForFrozenDistroSeries(self):
> -        """Source publishing record lookup for a frozen DistroSeries.
> -
> -        Check if Publisher.getPendingSourcePublications() works properly for
> -        a DistroSeries when it is in FROZEN state.
> -        """
> -        pub_pending_release, pub_published_release, pub_pending_updates = (
> -            self._createDefaultSourcePublications())
> -        # Freeze 'breezy-autotest'.
> -        self.breezy_autotest.status = SeriesStatus.FROZEN
> -        self.layer.commit()
> -
> -        # Usual publication procedure for a distroseries in development
> -        # state only 'pending' publishing records for pocket RELEASE
> -        # are published.
> -        self.checkSourceLookupForPocket(
> -            PackagePublishingPocket.RELEASE,
> -            expected_result=[pub_pending_release])
> -
> -        # This step is unusual but checks if the pocket restriction also
> -        # work for other pockets than the RELEASE.
> -        self.checkSourceLookupForPocket(
> -            PackagePublishingPocket.UPDATES,
> -            expected_result=[pub_pending_updates])
> -
> -        # Restricting to a pocket with no publication returns an
> -        # empty SQLResult.
> -        self.checkSourceLookupForPocket(
> -            PackagePublishingPocket.BACKPORTS, expected_result=[])
> -
> -        # Using the 'careful' mode results in the consideration
> -        # of every 'pending' and 'published' records present in
> -        # the given pocket.
> -        self.checkSourceLookupForPocket(
> -            PackagePublishingPocket.RELEASE, is_careful=True,
> -            expected_result=[pub_published_release, pub_pending_release])
> -
> -    def testPublicationLookUpForUnstableDistroArchSeries(self):
> -        """Binary publishing record lookup for a unstable DistroArchSeries.
> -
> -        Check if Publisher.getPendingBinaryPublications() works properly for
> -        a DistroArchSeries when it is still in DEVELOPMENT, i.e.,
> -        'unstable'.
> -        """
> -        pub_pending_release, pub_published_release, pub_pending_updates = (
> -            self._createDefaultBinaryPublications())
> -        self.layer.commit()
> -
> -        # Usual publication procedure for a distroseries in development
> -        # state only 'pending' publishing records for pocket RELEASE
> -        # are published.
> -        self.checkBinaryLookupForPocket(
> -            PackagePublishingPocket.RELEASE,
> -            expected_result=[pub_pending_release])
> -
> -        # This step is unusual but checks if the pocket restriction also
> -        # work for other pockets than the RELEASE.
> -        self.checkBinaryLookupForPocket(
> -            PackagePublishingPocket.UPDATES,
> -            expected_result=[pub_pending_updates])
> -
> -        # Restricting to a pocket with no publication returns an
> -        # empty SQLResult.
> -        self.checkBinaryLookupForPocket(
> -            PackagePublishingPocket.BACKPORTS, expected_result=[])
> -
> -        # Using the 'careful' mode results in the consideration
> -        # of every 'pending' and 'published' records present in
> -        # the given pocket.
> -        self.checkBinaryLookupForPocket(
> -            PackagePublishingPocket.RELEASE, is_careful=True,
> -            expected_result=[pub_published_release, pub_pending_release])
> -
> -    def testPublicationLookUpForStableDistroArchSeries(self):
> -        """Binary publishing record lookup for released DistroArchSeries.
> -
> -        Check if Publisher.getPendingBinaryPublications() works properly for
> -        a DistroArchSeries when it is not in development anymore, i.e.,
> -        'released'.
> -
> -        Released DistroArchSeries can't be modified, so we expect empty
> -        results in the lookups, even if there are pending publishing
> -        records available.
> -        """
> -        pub_pending_release, pub_published_release, pub_pending_updates = (
> -            self._createDefaultBinaryPublications())
> -
> -        # Release 'breezy-autotest'
> -        self.breezy_autotest.status = SeriesStatus.CURRENT
> -        self.layer.commit()
> -
> -        # Since the distroseries is stable, nothing is returned because
> -        # RELEASE pocket is ignored, in both modes, careful or not.
> -        self.checkBinaryLookupForPocket(
> -            PackagePublishingPocket.RELEASE, expected_result=[])
> -
> -        # XXX cprov 2007-01-05: it means that "careful" mode is useless for
> -        # rebuilding released archives.
> -        # This is quite right, IMHO, since republication of a released
> -        # archive will, obviously contain new timestamps, which would freak
> -        # mirrors/clients out.
> -        # At the end, "careful" mode is such a gross hack.
> -        self.checkBinaryLookupForPocket(
> -            PackagePublishingPocket.RELEASE, is_careful=True,
> -            expected_result=[])
> -
> -        # Publications targeted to other pockets than RELEASE are
> -        # still reachable.
> -        self.checkBinaryLookupForPocket(
> -            PackagePublishingPocket.UPDATES,
> -            expected_result=[pub_pending_updates])
> -
> -    def testPublicationLookUpForFrozenDistroArchSeries(self):
> -        """Binary publishing record lookup for a frozen DistroArchSeries.
> -
> -        Check if Publisher.getPendingBinaryPublications() works properly for
> -        a DistroArchSeries when it is frozen state.
> -        """
> -        pub_pending_release, pub_published_release, pub_pending_updates = (
> -            self._createDefaultBinaryPublications())
> -        # Freeze 'breezy-autotest'
> -        self.breezy_autotest.status = SeriesStatus.FROZEN
> -        self.layer.commit()
> -
> -        # Usual publication procedure for a distroseries in development
> -        # state only 'pending' publishing records for pocket RELEASE
> -        # are published.
> -        self.checkBinaryLookupForPocket(
> -            PackagePublishingPocket.RELEASE,
> -            expected_result=[pub_pending_release])
> -
> -        # This step is unusual but checks if the pocket restriction also
> -        # work for other pockets than the RELEASE.
> -        self.checkBinaryLookupForPocket(
> -            PackagePublishingPocket.UPDATES,
> -            expected_result=[pub_pending_updates])
> -
> -        # Restricting to a pocket with no publication returns an
> -        # empty SQLResult.
> -        self.checkBinaryLookupForPocket(
> -            PackagePublishingPocket.BACKPORTS, expected_result=[])
> -
> -        # Using the 'careful' mode results in the consideration
> -        # of every 'pending' and 'published' records present in
> -        # the given pocket.
> -        self.checkBinaryLookupForPocket(
> -            PackagePublishingPocket.RELEASE, is_careful=True,
> -            expected_result=[pub_published_release, pub_pending_release])
> +    def testSourcePublicationLookUp(self):
> +        """Source publishing record lookup.
> +
> +        Check if Publisher.getPendingSourcePublications() returns only
> +        pending publications.
> +        """
> +        pub_pending_release, pub_published_release, pub_pending_updates = (
> +            self._createDefaultSourcePublications())
> +
> +        # Normally, only pending records are considered.
> +        self.checkSourceLookup(
> +            expected_result=[pub_pending_release, pub_pending_updates])
> +
> +        # In careful mode, both pending and published records are
> +        # considered, ordered by distroseries, pocket, ID.
> +        self.checkSourceLookup(
> +            expected_result=[
> +                pub_published_release,
> +                pub_pending_release,
> +                pub_pending_updates,
> +                ],
> +            is_careful=True)
> +
> +    def testBinaryPublicationLookUp(self):
> +        """Binary publishing record lookup.
> +
> +        Check if Publisher.getPendingBinaryPublications() returns only
> +        pending publications.
> +        """
> +        pub_pending_release, pub_published_release, pub_pending_updates = (
> +            self._createDefaultBinaryPublications())
> +        self.layer.commit()
> +
> +        # Normally, only pending records are considered.
> +        self.checkBinaryLookup(
> +            expected_result=[pub_pending_release, pub_pending_updates])
> +
> +        # In careful mode, both pending and published records are
> +        # considered, ordered by distroseries, pocket, architecture tag, ID.
> +        self.checkBinaryLookup(
> +            expected_result=[
> +                pub_published_release,
> +                pub_pending_release,
> +                pub_pending_updates,
> +                ],
> +            is_careful=True)
>  
>      def test_publishing_disabled_distroarchseries(self):
>          # Disabled DASes will not receive new publications at all.
> @@ -946,6 +774,12 @@
>              filecontent='Hello world',
>              status=PackagePublishingStatus.PUBLISHED)
>  
> +        # Make everything other than breezy-autotest OBSOLETE so that they
> +        # aren't republished.
> +        for series in self.ubuntutest.series:
> +            if series.name != "breezy-autotest":
> +                series.status = SeriesStatus.OBSOLETE
> +
>          # A careful publisher run will re-publish the PUBLISHED records,
>          # then we will have a corresponding dirty_pocket entry.
>          publisher.A_publish(True)
> @@ -1031,7 +865,9 @@
>          # Remove security proxy so that the publisher can call our fake
>          # method.
>          publisher.distro = removeSecurityProxy(publisher.distro)
> -        publisher.distro['hoary-test'].status = SeriesStatus.OBSOLETE
> +        pub_source = self.getPubSource(distroseries=self.breezy_autotest)
> +        self.getPubBinaries(
> +            distroseries=self.breezy_autotest, pub_source=pub_source)
>  
>          for status in (SeriesStatus.OBSOLETE, SeriesStatus.FUTURE):
>              naked_breezy_autotest = publisher.distro['breezy-autotest']
> @@ -1055,6 +891,11 @@
>          # Remove security proxy so that the publisher can call our fake
>          # method.
>          publisher.distro = removeSecurityProxy(publisher.distro)
> +        pub_source = self.getPubSource(
> +            distroseries=self.breezy_autotest, archive=test_archive)
> +        self.getPubBinaries(
> +            distroseries=self.breezy_autotest, archive=test_archive,
> +            pub_source=pub_source)
>  
>          for status in (SeriesStatus.OBSOLETE, SeriesStatus.FUTURE):
>              naked_breezy_autotest = publisher.distro['breezy-autotest']
> @@ -1064,12 +905,13 @@
>  
>              publisher.A_publish(False)
>  
> -            self.assertIn(
> -                (naked_breezy_autotest, RELEASE),
> -                publisher.publishSources.extract_args())
> -            self.assertIn(
> -                (naked_breezy_autotest.architectures[0], RELEASE),
> -                publisher.publishBinaries.extract_args())
> +            source_args = [
> +                args[:2] for args in publisher.publishSources.extract_args()]
> +            self.assertIn((naked_breezy_autotest, RELEASE), source_args)
> +            binary_args = [
> +                args[:2] for args in publisher.publishBinaries.extract_args()]
> +            self.assertIn(
> +                (naked_breezy_autotest.architectures[0], RELEASE), binary_args)
>  
>      def testPublisherBuilderFunctions(self):
>          """Publisher can be initialized via provided helper function.
> @@ -1674,6 +1516,12 @@
>          self.getPubSource(filecontent='Hello world', pocket=RELEASE)
>          self.getPubSource(filecontent='Hello world', pocket=BACKPORTS)
>  
> +        # Make everything other than breezy-autotest OBSOLETE so that they
> +        # aren't republished.
> +        for series in self.ubuntutest.series:
> +            if series.name != "breezy-autotest":
> +                series.status = SeriesStatus.OBSOLETE
> +
>          publisher.A_publish(True)
>          publisher.C_writeIndexes(False)
>  
> 
> === modified file 'lib/lp/registry/model/distroseries.py'
> --- lib/lp/registry/model/distroseries.py	2014-07-08 22:31:49 +0000
> +++ lib/lp/registry/model/distroseries.py	2014-07-14 17:04:11 +0000
> @@ -6,6 +6,8 @@
>  __metaclass__ = type
>  
>  __all__ = [
> +    'ACTIVE_RELEASED_STATUSES',
> +    'ACTIVE_UNRELEASED_STATUSES',
>      'DistroSeries',
>      'DistroSeriesSet',
>      ]
> @@ -191,6 +193,19 @@
>      )
>  
>  
> +ACTIVE_RELEASED_STATUSES = [
> +    SeriesStatus.CURRENT,
> +    SeriesStatus.SUPPORTED,
> +    ]
> +
> +
> +ACTIVE_UNRELEASED_STATUSES = [
> +    SeriesStatus.EXPERIMENTAL,
> +    SeriesStatus.DEVELOPMENT,
> +    SeriesStatus.FROZEN,
> +    ]
> +
> +
>  class DistroSeries(SQLBase, BugTargetBase, HasSpecificationsMixin,
>                     HasTranslationImportsMixin, HasTranslationTemplatesMixin,
>                     HasMilestonesMixin, SeriesMixin,
> @@ -945,11 +960,7 @@
>  
>      def isUnstable(self):
>          """See `IDistroSeries`."""
> -        return self.status in [
> -            SeriesStatus.FROZEN,
> -            SeriesStatus.DEVELOPMENT,
> -            SeriesStatus.EXPERIMENTAL,
> -        ]
> +        return self.status in ACTIVE_UNRELEASED_STATUSES
>  
>      def _getAllSources(self):
>          """Get all sources ever published in this series' main archives."""
> @@ -1535,14 +1546,11 @@
>              if isreleased:
>                  # The query is filtered on released releases.
>                  where_clause += "releasestatus in (%s, %s)" % sqlvalues(
> -                    SeriesStatus.CURRENT,
> -                    SeriesStatus.SUPPORTED)
> +                    *ACTIVE_RELEASED_STATUSES)
>              else:
>                  # The query is filtered on unreleased releases.
>                  where_clause += "releasestatus in (%s, %s, %s)" % sqlvalues(
> -                    SeriesStatus.EXPERIMENTAL,
> -                    SeriesStatus.DEVELOPMENT,
> -                    SeriesStatus.FROZEN)
> +                    *ACTIVE_UNRELEASED_STATUSES)
>          if orderBy is not None:
>              return DistroSeries.select(where_clause, orderBy=orderBy)
>          else:
> 
> === modified file 'lib/lp/soyuz/doc/packageupload-lookups.txt'
> --- lib/lp/soyuz/doc/packageupload-lookups.txt	2013-07-25 11:58:55 +0000
> +++ lib/lp/soyuz/doc/packageupload-lookups.txt	2014-07-14 17:04:11 +0000
> @@ -82,7 +82,7 @@
>      >>> for archive in ubuntutest.all_distro_archives:
>      ...     check_upload_lookups(archive)
>      * Primary Archive for Ubuntu Test
> -    1 of 2 sources and 0 of 0 builds missing uploads
> +    1 of 1 sources and 0 of 0 builds missing uploads
>      * Partner Archive for Ubuntu Test
>      0 of 0 sources and 0 of 0 builds missing uploads
>  
> 
> === modified file 'lib/lp/soyuz/doc/sourcepackagerelease.txt'
> --- lib/lp/soyuz/doc/sourcepackagerelease.txt	2014-04-24 06:45:51 +0000
> +++ lib/lp/soyuz/doc/sourcepackagerelease.txt	2014-07-14 17:04:11 +0000
> @@ -15,13 +15,13 @@
>  Let's get one from the database:
>  
>     >>> from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
> -   >>> spr = SourcePackageRelease.get(14)
> +   >>> spr = SourcePackageRelease.get(20)
>     >>> spr.name
> -   u'mozilla-firefox'
> +   u'pmount'
>     >>> spr.version
> -   u'0.9'
> +   u'0.1-1'
>     >>> spr.dateuploaded
> -   datetime.datetime(2004, 9, 27, 11, 57, 13, tzinfo=<UTC>)
> +   datetime.datetime(2005, 3, 24, 20, 59, 31, 439579, tzinfo=<UTC>)
>  
>  published_archives returns a set of all the archives that this
>  SourcePackageRelease is published in.
> @@ -29,7 +29,7 @@
>      >>> for archive in spr.published_archives:
>      ...     print archive.displayname
>      Primary Archive for Ubuntu Linux
> -    Primary Archive for Ubuntu Test
> +    PPA for Celso Providelo
>  
>  'age' is a special property that performs on-the-fly:
>  {{{
> @@ -57,7 +57,7 @@
>     >>> spr.age.days == 10
>     True
>  
> -Mozilla-firefox 0.9 has got some builds. including a PPA build.  The 'builds'
> +pmount 0.1-1 has got some builds. including a PPA build.  The 'builds'
>  property only returns the non-PPA builds.
>  
>     >>> from lp.registry.interfaces.person import IPersonSet
> @@ -89,7 +89,7 @@
>  Check ISourcePackageRelease.override() behaviour:
>  
>     >>> spr.component.name, spr.section.name
> -   (u'main', u'base')
> +   (u'main', u'web')
>  
>     >>> from lp.soyuz.interfaces.component import IComponentSet
>     >>> from lp.soyuz.interfaces.section import ISectionSet
> 


-- 
https://code.launchpad.net/~cjwatson/launchpad/optimise-publish-a/+merge/226312
Your team Launchpad code reviewers is subscribed to branch lp:launchpad.


Follow ups

References