← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~abentley/launchpad/specification-cleanup into lp:launchpad

 

Aaron Bentley has proposed merging lp:~abentley/launchpad/specification-cleanup into lp:launchpad with lp:~abentley/launchpad/storm-sprint-queries as a prerequisite.

Commit message:
Reorganize specification access methods.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~abentley/launchpad/specification-cleanup/+merge/126789

= Summary =
Reorginize specification list methods


== Pre-implementation notes ==
None

== LOC Rationale ==
Part of private projects

== Implementation details ==
Supporting privacy in specification listings requires taking a user as input when listing specs.  Ideally, that means supplying the user in the view code.  

This doesn't actually add privacy support, but it prepares the methods so that it can be implemented cleanly.

specification_count becomes a method so that it can start accepting a user as a parameter.

all_specifications and valid_specifications are part of the web service API, so they cannot be removed even though they can't accept a user parameter.  They are renamed as private, with the old name retained in the API.

The implementation of latest_specifications, latest_completed_specifications and specification_count is moved to SpecificationSetView.  The appropriate pages are updated to use SpecificationSetView.

== Tests ==
Everything, really.

== Demo and Q/A ==


= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/blueprints/templates/specifications-portlet-latestregistered.pt
  lib/lp/blueprints/tests/test_hasspecifications.py
  lib/lp/services/database/stormexpr.py
  lib/lp/registry/doc/milestone.txt
  lib/lp/registry/model/projectgroup.py
  lib/lp/registry/doc/distribution.txt
  lib/lp/registry/model/productseries.py
  lib/lp/blueprints/interfaces/specificationtarget.py
  lib/lp/app/browser/root.py
  lib/lp/blueprints/templates/specificationtarget-assignments.pt
  lib/lp/blueprints/browser/specificationtarget.py
  lib/lp/blueprints/model/tests/test_sprint.py
  lib/lp/bugs/model/tests/test_bugtask.py
  lib/lp/blueprints/templates/specifications-portlet-stats.pt
  lib/lp/registry/doc/projectgroup.txt
  lib/lp/blueprints/model/specification.py
  lib/lp/registry/browser/__init__.py
  lib/lp/blueprints/model/sprint.py
  lib/lp/blueprints/templates/specifications-portlet-latestcompleted.pt
  lib/lp/testing/_webservice.py
  lib/lp/registry/model/product.py
  lib/lp/blueprints/browser/configure.zcml
  lib/lp/blueprints/browser/tests/test_sprint.py
  lib/lp/blueprints/doc/specification.txt
  lib/lp/blueprints/browser/specification.py
  lib/lp/registry/model/person.py
  lib/lp/registry/model/distroseries.py
  lib/lp/_schema_circular_imports.py
  lib/lp/registry/model/distribution.py
  lib/lp/blueprints/interfaces/specification.py

./lib/lp/registry/model/product.py
     408: redefinition of function 'date_next_suggest_packaging' from line 400

^^^ This is an acceptable case of re-definition.  It's creating a setter.
-- 
https://code.launchpad.net/~abentley/launchpad/specification-cleanup/+merge/126789
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~abentley/launchpad/specification-cleanup into lp:launchpad.
=== modified file 'lib/lp/_schema_circular_imports.py'
--- lib/lp/_schema_circular_imports.py	2012-08-10 17:08:57 +0000
+++ lib/lp/_schema_circular_imports.py	2012-09-27 20:14:26 +0000
@@ -734,9 +734,9 @@
 
 # IHasSpecifications
 patch_collection_property(
-    IHasSpecifications, 'all_specifications', ISpecification)
+    IHasSpecifications, '_all_specifications', ISpecification)
 patch_collection_property(
-    IHasSpecifications, 'valid_specifications', ISpecification)
+    IHasSpecifications, '_valid_specifications', ISpecification)
 
 
 ###

=== modified file 'lib/lp/app/browser/root.py'
--- lib/lp/app/browser/root.py	2012-08-14 23:27:07 +0000
+++ lib/lp/app/browser/root.py	2012-09-27 20:14:26 +0000
@@ -130,7 +130,7 @@
     @property
     def blueprint_count(self):
         """The total blueprint count in all of Launchpad."""
-        return getUtility(ISpecificationSet).specification_count
+        return getUtility(ISpecificationSet).specificationCount()
 
     @property
     def answer_count(self):

=== modified file 'lib/lp/blueprints/browser/configure.zcml'
--- lib/lp/blueprints/browser/configure.zcml	2012-09-11 20:55:23 +0000
+++ lib/lp/blueprints/browser/configure.zcml	2012-09-27 20:14:26 +0000
@@ -488,15 +488,21 @@
             permission="zope.Public">
 
             <browser:page
+                name="+portlet-sprints"
+                template="../templates/specifications-portlet-sprints.pt"/>
+        </browser:pages>
+        <browser:pages
+            for="lp.blueprints.interfaces.specification.ISpecificationSet"
+            permission="zope.Public"
+            class="lp.blueprints.browser.specification.SpecificationSetView">
+
+            <browser:page
                 name="+portlet-latestcompleted"
                 template="../templates/specifications-portlet-latestcompleted.pt"/>
             <browser:page
                 name="+portlet-latestregistered"
                 template="../templates/specifications-portlet-latestregistered.pt"/>
             <browser:page
-                name="+portlet-sprints"
-                template="../templates/specifications-portlet-sprints.pt"/>
-            <browser:page
                 name="+portlet-stats"
                 template="../templates/specifications-portlet-stats.pt"/>
         </browser:pages>

=== modified file 'lib/lp/blueprints/browser/specification.py'
--- lib/lp/blueprints/browser/specification.py	2012-09-26 13:19:19 +0000
+++ lib/lp/blueprints/browser/specification.py	2012-09-27 20:14:26 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2012 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Specification views."""
@@ -112,7 +112,9 @@
 from lp.blueprints.enums import (
     NewSpecificationDefinitionStatus,
     SpecificationDefinitionStatus,
+    SpecificationFilter,
     SpecificationImplementationStatus,
+    SpecificationSort,
     )
 from lp.blueprints.errors import TargetAlreadyHasSpecification
 from lp.blueprints.interfaces.specification import (
@@ -1527,6 +1529,21 @@
 
     label = 'Blueprints'
 
+    @property
+    def latest_specifications(self):
+        return self.context.specifications(
+            sort=SpecificationSort.DATE, quantity=5)
+
+    @property
+    def latest_completed_specifications(self):
+        return self.context.specifications(
+            sort=SpecificationSort.DATE, quantity=5,
+            filter=[SpecificationFilter.COMPLETE])
+
+    @property
+    def specification_count(self):
+        return self.context.specificationCount()
+
     @safe_action
     @action('Find blueprints', name="search")
     def search_action(self, action, data):

=== modified file 'lib/lp/blueprints/browser/specificationtarget.py'
--- lib/lp/blueprints/browser/specificationtarget.py	2012-07-05 00:47:31 +0000
+++ lib/lp/blueprints/browser/specificationtarget.py	2012-09-27 20:14:26 +0000
@@ -259,7 +259,7 @@
 
     @cachedproperty
     def has_any_specifications(self):
-        return self.context.has_any_specifications
+        return self.context._all_specifications.count() != 0
 
     @cachedproperty
     def all_specifications(self):

=== modified file 'lib/lp/blueprints/doc/specification.txt'
--- lib/lp/blueprints/doc/specification.txt	2011-12-30 06:14:56 +0000
+++ lib/lp/blueprints/doc/specification.txt	2012-09-27 20:14:26 +0000
@@ -99,10 +99,7 @@
 
 SpecificationSet implements the ISpecificationSet interface
 
-    >>> ubuspec in specset.all_specifications
-    True
-
-    >>> specset.has_any_specifications
+    >>> ubuspec in specset._all_specifications
     True
 
     >>> from lp.services.webapp.testing import verifyObject

=== modified file 'lib/lp/blueprints/interfaces/specification.py'
--- lib/lp/blueprints/interfaces/specification.py	2012-09-17 15:19:10 +0000
+++ lib/lp/blueprints/interfaces/specification.py	2012-09-27 20:14:26 +0000
@@ -674,8 +674,8 @@
 
     coming_sprints = Attribute("The next 5 sprints in the system.")
 
-    specification_count = Attribute(
-        "The total number of blueprints in Launchpad")
+    def specificationCount():
+        """The total number of blueprints in Launchpad"""
 
     def getStatusCountsForProductSeries(product_series):
         """Return the status counts for blueprints in a series.

=== modified file 'lib/lp/blueprints/interfaces/specificationtarget.py'
--- lib/lp/blueprints/interfaces/specificationtarget.py	2012-09-13 11:31:12 +0000
+++ lib/lp/blueprints/interfaces/specificationtarget.py	2012-09-27 20:14:26 +0000
@@ -26,10 +26,7 @@
     CollectionField,
     Reference,
     )
-from zope.interface import (
-    Attribute,
-    Interface,
-    )
+from zope.interface import Interface
 from zope.schema import TextLine
 
 from lp import _
@@ -42,7 +39,7 @@
     associated with them, and you can use this interface to query those.
     """
 
-    all_specifications = exported(doNotSnapshot(
+    _all_specifications = exported(doNotSnapshot(
         CollectionField(
             title=_("All specifications"),
             value_type=Reference(schema=Interface),  # ISpecification, really.
@@ -50,13 +47,9 @@
             description=_(
                 'A list of all specifications, regardless of status or '
                 'approval or completion, for this object.'))),
-                                  as_of="devel")
-
-    has_any_specifications = Attribute(
-        'A true or false indicator of whether or not this object has any '
-        'specifications associated with it, regardless of their status.')
-
-    valid_specifications = exported(doNotSnapshot(
+        exported_as="all_specifications", as_of="devel")
+
+    _valid_specifications = exported(doNotSnapshot(
         CollectionField(
             title=_("Valid specifications"),
             value_type=Reference(schema=Interface),  # ISpecification, really.
@@ -65,13 +58,7 @@
                 'All specifications that are not obsolete. When called from '
                 'an ISpecificationGoal it will also exclude the ones that '
                 'have not been accepted for that goal'))),
-                                    as_of="devel")
-
-    latest_specifications = Attribute(
-        "The latest 5 specifications registered for this context.")
-
-    latest_completed_specifications = Attribute(
-        "The 5 specifications most recently completed for this context.")
+        exported_as="valid_specifications", as_of="devel")
 
     def specifications(quantity=None, sort=None, filter=None,
                        prejoin_people=True):

=== modified file 'lib/lp/blueprints/model/specification.py'
--- lib/lp/blueprints/model/specification.py	2012-09-27 20:14:26 +0000
+++ lib/lp/blueprints/model/specification.py	2012-09-27 20:14:26 +0000
@@ -1022,23 +1022,16 @@
         return DecoratedResultSet(results, pre_iter_hook=cache_people)
 
     @property
-    def valid_specifications(self):
+    def _all_specifications(self):
+        """See IHasSpecifications."""
+        return self.specifications(filter=[SpecificationFilter.ALL])
+
+    @property
+    def _valid_specifications(self):
         """See IHasSpecifications."""
         return self.specifications(filter=[SpecificationFilter.VALID])
 
-    @property
-    def latest_specifications(self):
-        """See IHasSpecifications."""
-        return self.specifications(sort=SpecificationSort.DATE, quantity=5)
-
-    @property
-    def latest_completed_specifications(self):
-        """See IHasSpecifications."""
-        return self.specifications(sort=SpecificationSort.DATE, quantity=5,
-            filter=[SpecificationFilter.COMPLETE, ])
-
-    @property
-    def specification_count(self):
+    def specificationCount(self):
         """See IHasSpecifications."""
         return self.specifications(filter=[SpecificationFilter.ALL]).count()
 
@@ -1072,17 +1065,13 @@
         return cur.fetchall()
 
     @property
-    def all_specifications(self):
+    def _all_specifications(self):
         return Specification.select()
 
     def __iter__(self):
         """See ISpecificationSet."""
         return iter(self.all_specifications)
 
-    @property
-    def has_any_specifications(self):
-        return self.all_specifications.count() != 0
-
     def specifications(self, sort=None, quantity=None, filter=None,
                        prejoin_people=True):
         """See IHasSpecifications."""

=== modified file 'lib/lp/blueprints/model/sprint.py'
--- lib/lp/blueprints/model/sprint.py	2012-09-27 20:14:26 +0000
+++ lib/lp/blueprints/model/sprint.py	2012-09-27 20:14:26 +0000
@@ -169,15 +169,6 @@
                 query.append(fti_search(Specification, constraint))
         return query
 
-    @property
-    def has_any_specifications(self):
-        """See IHasSpecifications."""
-        return self.all_specifications.count()
-
-    @property
-    def all_specifications(self):
-        return self.specifications(filter=[SpecificationFilter.ALL])
-
     def specifications(self, sort=None, quantity=None, filter=None,
                        prejoin_people=False):
         """See IHasSpecifications."""

=== modified file 'lib/lp/blueprints/templates/specifications-portlet-latestcompleted.pt'
--- lib/lp/blueprints/templates/specifications-portlet-latestcompleted.pt	2009-07-17 17:59:07 +0000
+++ lib/lp/blueprints/templates/specifications-portlet-latestcompleted.pt	2012-09-27 20:14:26 +0000
@@ -5,7 +5,7 @@
   omit-tag="">
 
 <h2>Recently completed</h2>
-<table tal:define="speclist context/latest_completed_specifications">
+<table tal:define="speclist view/latest_completed_specifications">
   <tr tal:repeat="spec speclist"
       tal:replace="structure spec/@@+listing-compact" />
 </table>

=== modified file 'lib/lp/blueprints/templates/specifications-portlet-latestregistered.pt'
--- lib/lp/blueprints/templates/specifications-portlet-latestregistered.pt	2009-07-17 17:59:07 +0000
+++ lib/lp/blueprints/templates/specifications-portlet-latestregistered.pt	2012-09-27 20:14:26 +0000
@@ -5,7 +5,7 @@
   omit-tag="">
 
 <h2>Recently registered</h2>
-<table tal:define="speclist context/latest_specifications">
+<table tal:define="speclist view/latest_specifications">
   <tbody>
     <tr tal:repeat="spec speclist"
         tal:replace="structure spec/@@+listing-compact" />

=== modified file 'lib/lp/blueprints/templates/specifications-portlet-stats.pt'
--- lib/lp/blueprints/templates/specifications-portlet-stats.pt	2009-07-17 17:59:07 +0000
+++ lib/lp/blueprints/templates/specifications-portlet-stats.pt	2012-09-27 20:14:26 +0000
@@ -5,7 +5,7 @@
   omit-tag="">
 
 <div>
-  <strong tal:content="context/specification_count">5</strong> blueprints
+  <strong tal:content="view/specification_count">5</strong> blueprints
   registered in Launchpad
 </div>
 </tal:root>

=== modified file 'lib/lp/blueprints/tests/test_hasspecifications.py'
--- lib/lp/blueprints/tests/test_hasspecifications.py	2012-01-01 02:58:52 +0000
+++ lib/lp/blueprints/tests/test_hasspecifications.py	2012-09-27 20:14:26 +0000
@@ -25,7 +25,7 @@
         self.factory.makeSpecification(product=product, name="spec1")
         self.factory.makeSpecification(product=product, name="spec2")
         self.assertNamesOfSpecificationsAre(
-            ["spec1", "spec2"], product.all_specifications)
+            ["spec1", "spec2"], product._all_specifications)
 
     def test_product_valid_specifications(self):
         product = self.factory.makeProduct()
@@ -34,7 +34,7 @@
             product=product, name="spec2",
             status=SpecificationDefinitionStatus.OBSOLETE)
         self.assertNamesOfSpecificationsAre(
-            ["spec1"], product.valid_specifications)
+            ["spec1"], product._valid_specifications)
 
     def test_distribution_all_specifications(self):
         distribution = self.factory.makeDistribution()
@@ -43,7 +43,7 @@
         self.factory.makeSpecification(
             distribution=distribution, name="spec2")
         self.assertNamesOfSpecificationsAre(
-            ["spec1", "spec2"], distribution.all_specifications)
+            ["spec1", "spec2"], distribution._all_specifications)
 
     def test_distribution_valid_specifications(self):
         distribution = self.factory.makeDistribution()
@@ -53,7 +53,7 @@
             distribution=distribution, name="spec2",
             status=SpecificationDefinitionStatus.OBSOLETE)
         self.assertNamesOfSpecificationsAre(
-            ["spec1"], distribution.valid_specifications)
+            ["spec1"], distribution._valid_specifications)
 
     def test_distroseries_all_specifications(self):
         distroseries = self.factory.makeDistroSeries(name='maudlin')
@@ -68,10 +68,10 @@
             distribution=distribution, name="spec3")
         self.assertNamesOfSpecificationsAre(
             ["spec1", "spec2"],
-            distroseries.all_specifications)
+            distroseries._all_specifications)
 
     # XXX: salgado, 2010-11-25, bug=681432: Test disabled because
-    # DistroSeries.valid_specifications is broken.
+    # DistroSeries._valid_specifications is broken.
     def disabled_test_distroseries_valid_specifications(self):
         distroseries = self.factory.makeDistroSeries(name='maudlin')
         distribution = distroseries.distribution
@@ -89,7 +89,7 @@
             distribution=distribution, name="spec4")
         self.assertNamesOfSpecificationsAre(
             ["spec1", "spec2"],
-            distroseries.valid_specifications)
+            distroseries._valid_specifications)
 
     def test_productseries_all_specifications(self):
         product = self.factory.makeProduct()
@@ -101,7 +101,7 @@
             product=product, name="spec2", goal=productseries)
         self.factory.makeSpecification(product=product, name="spec3")
         self.assertNamesOfSpecificationsAre(
-            ["spec1", "spec2"], productseries.all_specifications)
+            ["spec1", "spec2"], productseries._all_specifications)
 
     def test_productseries_valid_specifications(self):
         product = self.factory.makeProduct()
@@ -116,7 +116,7 @@
             status=SpecificationDefinitionStatus.OBSOLETE)
         self.factory.makeSpecification(product=product, name="spec4")
         self.assertNamesOfSpecificationsAre(
-            ["spec1", "spec2"], productseries.valid_specifications)
+            ["spec1", "spec2"], productseries._valid_specifications)
 
     def test_projectgroup_all_specifications(self):
         projectgroup = self.factory.makeProject()
@@ -133,7 +133,7 @@
             product=product3, name="spec3")
         self.assertNamesOfSpecificationsAre(
             ["spec1", "spec2"],
-            projectgroup.all_specifications)
+            projectgroup._all_specifications)
 
     def test_projectgroup_valid_specifications(self):
         projectgroup = self.factory.makeProject()
@@ -150,7 +150,7 @@
             product=product3, name="spec3")
         self.assertNamesOfSpecificationsAre(
             ["spec1", "spec2"],
-            projectgroup.valid_specifications)
+            projectgroup._valid_specifications)
 
     def test_person_all_specifications(self):
         person = self.factory.makePerson(name="james-w")
@@ -163,7 +163,7 @@
         self.factory.makeSpecification(
             product=product, name="spec3")
         self.assertNamesOfSpecificationsAre(
-            ["spec1", "spec2"], person.all_specifications)
+            ["spec1", "spec2"], person._all_specifications)
 
     def test_person_valid_specifications(self):
         person = self.factory.makePerson(name="james-w")
@@ -176,7 +176,7 @@
         self.factory.makeSpecification(
             product=product, name="spec3")
         self.assertNamesOfSpecificationsAre(
-            ["spec1"], person.valid_specifications)
+            ["spec1"], person._valid_specifications)
 
 
 class HasSpecificationsSnapshotTestCase(TestCaseWithFactory):

=== modified file 'lib/lp/bugs/model/tests/test_bugtask.py'
--- lib/lp/bugs/model/tests/test_bugtask.py	2012-09-17 16:13:40 +0000
+++ lib/lp/bugs/model/tests/test_bugtask.py	2012-09-27 20:14:26 +0000
@@ -504,7 +504,7 @@
             ' has_specification: False'])
 
         # a specification gets linked...
-        spec = getUtility(ISpecificationSet).all_specifications[0]
+        spec = getUtility(ISpecificationSet)._all_specifications[0]
         spec.linkBug(bug_two)
 
         # or a branch gets linked to the bug...

=== modified file 'lib/lp/registry/browser/__init__.py'
--- lib/lp/registry/browser/__init__.py	2012-09-24 05:17:00 +0000
+++ lib/lp/registry/browser/__init__.py	2012-09-27 20:14:26 +0000
@@ -165,14 +165,15 @@
             params.setProductSeries(target)
         else:
             params = BugTaskSearchParams(
-                milestone=target, user=self.user, ignore_privacy=ignore_privacy)
+                milestone=target, user=self.user,
+                ignore_privacy=ignore_privacy)
         bugtasks = getUtility(IBugTaskSet).search(params)
         return list(bugtasks)
 
     def _getSpecifications(self, target):
         """Return the list `ISpecification`s associated to the target."""
         if IProductSeries.providedBy(target):
-            return list(target.all_specifications)
+            return list(target._all_specifications)
         else:
             return list(target.specifications)
 

=== modified file 'lib/lp/registry/doc/distribution.txt'
--- lib/lp/registry/doc/distribution.txt	2012-09-26 07:55:33 +0000
+++ lib/lp/registry/doc/distribution.txt	2012-09-27 20:14:26 +0000
@@ -562,7 +562,7 @@
     ...         spec.definition_status = (
     ...             SpecificationDefinitionStatus.SUPERSEDED)
     ...     shim = spec.updateLifecycleStatus(owner)
-    >>> for spec in kubuntu.valid_specifications:
+    >>> for spec in kubuntu._valid_specifications:
     ...     print spec.name
     kde-desktopfile-langpacks
 

=== modified file 'lib/lp/registry/doc/milestone.txt'
--- lib/lp/registry/doc/milestone.txt	2012-08-08 07:22:51 +0000
+++ lib/lp/registry/doc/milestone.txt	2012-09-27 20:14:26 +0000
@@ -289,7 +289,7 @@
 the Gnome project has yet any specifications.
 
     >>> for product in gnome.products:
-    ...     print product.name, list(product.all_specifications)
+    ...     print product.name, list(product._all_specifications)
     evolution []
     gnome-terminal []
     applets []
@@ -303,7 +303,7 @@
 milestone, it is "inheritied" by the project milestone.
 
     >>> spec = test_helper.createSpecification('1.1', 'applets')
-    >>> [spec.name for spec in applets.all_specifications]
+    >>> [spec.name for spec in applets._all_specifications]
     [u'applets-specification']
 
     >>> [spec.name for spec in gnome.getMilestone('1.1').specifications]

=== modified file 'lib/lp/registry/doc/projectgroup.txt'
--- lib/lp/registry/doc/projectgroup.txt	2011-12-30 06:14:56 +0000
+++ lib/lp/registry/doc/projectgroup.txt	2012-09-27 20:14:26 +0000
@@ -198,10 +198,10 @@
     >>> firefox.active = True
     >>> flush_database_updates()
 
-We can get all the specifications via the all_specifications property,
-and all valid specifications via the valid_specifications property:
+We can get all the specifications via the _all_specifications property,
+and all valid specifications via the _valid_specifications property:
 
-    >>> for spec in mozilla.all_specifications:
+    >>> for spec in mozilla._all_specifications:
     ...    print spec.name
     svg-support
     canvas
@@ -209,7 +209,7 @@
     mergewin
     e4x
 
-    >>> for spec in mozilla.valid_specifications:
+    >>> for spec in mozilla._valid_specifications:
     ...    print spec.name
     svg-support
     canvas
@@ -236,29 +236,29 @@
     >>> print mozilla.getSeries('nonsense')
     None
 
-IProjectGroupSeries.all_specifications lists all specifications
+IProjectGroupSeries._all_specifications lists all specifications
 assigned to a series. Currently, no specifications are assigned to the
 Mozilla series 1.0.
 
-    >>> specs = mozilla_series_1_0.all_specifications
+    >>> specs = mozilla_series_1_0._all_specifications
     >>> specs.count()
     0
 
 If a specification is assigned to series 1.0, it appears in
-mozilla_1_0_series.all_specifications.
+mozilla_1_0_series._all_specifications.
 
     >>> filter = [SpecificationFilter.INFORMATIONAL]
     >>> extension_manager_upgrades = mozilla.specifications(filter=filter)[0]
     >>> series_1_0 = firefox.getSeries('1.0')
     >>> extension_manager_upgrades.proposeGoal(series_1_0, no_priv)
-    >>> for spec in mozilla_series_1_0.all_specifications:
+    >>> for spec in mozilla_series_1_0._all_specifications:
     ...     print spec.name
     extension-manager-upgrades
 
 This specification is not listed for other series.
 
     >>> mozilla_trunk = mozilla.getSeries('trunk')
-    >>> print mozilla_trunk.all_specifications.count()
+    >>> print mozilla_trunk._all_specifications.count()
     0
 
 Filtered lists of project series related specifications are generated
@@ -270,7 +270,7 @@
 
 If all existing specifications are assigned to the 1.0 series,...
 
-    >>> for spec in mozilla.all_specifications:
+    >>> for spec in mozilla._all_specifications:
     ...     spec.proposeGoal(series_1_0, no_priv)
 
 we have the save five incomplete specs in the series 1.0 as we have for the
@@ -308,10 +308,10 @@
 
     >>> firefox.active = True
 
-We can get all the specifications via the all_specifications property,
-and all valid specifications via the valid_specifications property:
+We can get all the specifications via the _all_specifications property,
+and all valid specifications via the _valid_specifications property:
 
-    >>> for spec in mozilla_series_1_0.all_specifications:
+    >>> for spec in mozilla_series_1_0._all_specifications:
     ...    print spec.name
     svg-support
     canvas
@@ -319,7 +319,7 @@
     mergewin
     e4x
 
-    >>> for spec in mozilla_series_1_0.valid_specifications:
+    >>> for spec in mozilla_series_1_0._valid_specifications:
     ...    print spec.name
     svg-support
     canvas

=== modified file 'lib/lp/registry/model/distribution.py'
--- lib/lp/registry/model/distribution.py	2012-09-26 07:45:31 +0000
+++ lib/lp/registry/model/distribution.py	2012-09-27 20:14:26 +0000
@@ -878,16 +878,6 @@
         return getUtility(IDistributionSet).getCurrentSourceReleases(
             {self: source_package_names})
 
-    @property
-    def has_any_specifications(self):
-        """See `IHasSpecifications`."""
-        return self.all_specifications.count()
-
-    @property
-    def all_specifications(self):
-        """See `IHasSpecifications`."""
-        return self.specifications(filter=[SpecificationFilter.ALL])
-
     def specifications(self, sort=None, quantity=None, filter=None,
                        prejoin_people=True):
         """See `IHasSpecifications`.

=== modified file 'lib/lp/registry/model/distroseries.py'
--- lib/lp/registry/model/distroseries.py	2012-09-26 08:49:53 +0000
+++ lib/lp/registry/model/distroseries.py	2012-09-27 20:14:26 +0000
@@ -777,15 +777,6 @@
         """See `IHasBugs`."""
         return self.distribution.official_bug_tags
 
-    @property
-    def has_any_specifications(self):
-        """See IHasSpecifications."""
-        return self.all_specifications.count()
-
-    @property
-    def all_specifications(self):
-        return self.specifications(filter=[SpecificationFilter.ALL])
-
     def specifications(self, sort=None, quantity=None, filter=None,
                        prejoin_people=True):
         """See IHasSpecifications.

=== modified file 'lib/lp/registry/model/person.py'
--- lib/lp/registry/model/person.py	2012-09-27 02:52:48 +0000
+++ lib/lp/registry/model/person.py	2012-09-27 20:14:26 +0000
@@ -821,19 +821,6 @@
         """See `IPerson`."""
         return "%s (%s)" % (self.displayname, self.name)
 
-    @property
-    def has_any_specifications(self):
-        """See `IHasSpecifications`."""
-        return self.all_specifications.count()
-
-    @property
-    def all_specifications(self):
-        return self.specifications(filter=[SpecificationFilter.ALL])
-
-    @property
-    def valid_specifications(self):
-        return self.specifications(filter=[SpecificationFilter.VALID])
-
     def specifications(self, sort=None, quantity=None, filter=None,
                        prejoin_people=True):
         """See `IHasSpecifications`."""

=== modified file 'lib/lp/registry/model/product.py'
--- lib/lp/registry/model/product.py	2012-09-25 16:52:09 +0000
+++ lib/lp/registry/model/product.py	2012-09-27 20:14:26 +0000
@@ -1303,19 +1303,6 @@
         # automatically shared.
         return True
 
-    @property
-    def has_any_specifications(self):
-        """See `IHasSpecifications`."""
-        return self.all_specifications.count()
-
-    @property
-    def all_specifications(self):
-        return self.specifications(filter=[SpecificationFilter.ALL])
-
-    @property
-    def valid_specifications(self):
-        return self.specifications(filter=[SpecificationFilter.VALID])
-
     def specifications(self, sort=None, quantity=None, filter=None,
                        prejoin_people=True):
         """See `IHasSpecifications`."""

=== modified file 'lib/lp/registry/model/productseries.py'
--- lib/lp/registry/model/productseries.py	2012-09-07 19:40:53 +0000
+++ lib/lp/registry/model/productseries.py	2012-09-27 20:14:26 +0000
@@ -297,19 +297,6 @@
         return ret
 
     @property
-    def has_any_specifications(self):
-        """See IHasSpecifications."""
-        return self.all_specifications.count()
-
-    @property
-    def all_specifications(self):
-        return self.specifications(filter=[SpecificationFilter.ALL])
-
-    @property
-    def valid_specifications(self):
-        return self.specifications(filter=[SpecificationFilter.VALID])
-
-    @property
     def is_development_focus(self):
         """See `IProductSeries`."""
         return self == self.product.development_focus

=== modified file 'lib/lp/registry/model/projectgroup.py'
--- lib/lp/registry/model/projectgroup.py	2012-09-10 17:26:25 +0000
+++ lib/lp/registry/model/projectgroup.py	2012-09-27 20:14:26 +0000
@@ -231,19 +231,6 @@
             """ % sqlvalues(self, SprintSpecificationStatus.ACCEPTED)
         return query, ['Product', 'Specification', 'SprintSpecification']
 
-    @property
-    def has_any_specifications(self):
-        """See `IHasSpecifications`."""
-        return self.all_specifications.count()
-
-    @property
-    def all_specifications(self):
-        return self.specifications(filter=[SpecificationFilter.ALL])
-
-    @property
-    def valid_specifications(self):
-        return self.specifications(filter=[SpecificationFilter.VALID])
-
     def specifications(self, sort=None, quantity=None, filter=None,
                        series=None, prejoin_people=True):
         """See `IHasSpecifications`."""
@@ -650,19 +637,6 @@
             sort, quantity, filter, self.name, prejoin_people=prejoin_people)
 
     @property
-    def has_any_specifications(self):
-        """See `IHasSpecifications`."""
-        return self.all_specifications.count()
-
-    @property
-    def all_specifications(self):
-        return self.specifications(filter=[SpecificationFilter.ALL])
-
-    @property
-    def valid_specifications(self):
-        return self.specifications(filter=[SpecificationFilter.VALID])
-
-    @property
     def title(self):
         return "%s Series %s" % (self.project.title, self.name)
 


Follow ups