← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~danilo/launchpad/no-dummy-psl into lp:launchpad/devel

 

Данило Шеган has proposed merging lp:~danilo/launchpad/no-dummy-psl into lp:launchpad/devel.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)


= Get rid of dummy ProductSeriesLanguage =

When ProductSeriesLanguage was introduced, it was modelled after DistroSeriesLanguage. DistroSeriesLanguage is backed by persistent storage (it's an actual table in the DB), while ProductSeriesLanguage is only an in-memory object.  As such, it is basically always a "dummy".

As part of reworking ISeriesLanguage interface to be more generic and re-usable, this is a refactoring branch that gets rid of the DummyProductSeriesLanguage and related methods.

= Tests =

bin/test -cvvt productserieslanguage

(we just confirm everything works as it used to: existing tests cover all the cases where we were using dummies, and the dummy_ProductSeriesLanguage test is explicit in unit-testing the "dummy" behaviour)

= QA =

https://translations.launchpad.dev/evolution/trunk/+lang/es (no-dummy version)
https://translations.launchpad.dev/evolution/trunk/+lang/sr (dummy version)

Both work in identical way to how they work today, but we've got less code for a net win.

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/translations/configure.zcml
  lib/lp/translations/browser/productseries.py
  lib/lp/translations/browser/tests/test_breadcrumbs.py
  lib/lp/translations/doc/canonical_url_examples.txt
  lib/lp/translations/interfaces/productserieslanguage.py
  lib/lp/translations/model/productserieslanguage.py
  lib/lp/translations/tests/test_productserieslanguage.py

-- 
https://code.launchpad.net/~danilo/launchpad/no-dummy-psl/+merge/30293
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~danilo/launchpad/no-dummy-psl into lp:launchpad/devel.
=== modified file 'lib/lp/translations/browser/productseries.py'
--- lib/lp/translations/browser/productseries.py	2010-06-17 03:29:53 +0000
+++ lib/lp/translations/browser/productseries.py	2010-07-19 15:43:43 +0000
@@ -344,9 +344,7 @@
 
         Produces a list containing a ProductSeriesLanguage object for
         each language this product has been translated into, and for each
-        of the user's preferred languages. Where the series has no
-        ProductSeriesLanguage for that language, we use a
-        DummyProductSeriesLanguage.
+        of the user's preferred languages.
         """
 
         if self.context.potemplate_count == 0:
@@ -369,11 +367,13 @@
                         pofile = pot.getPOFileByLang(lang.code)
                         if pofile is None:
                             pofile = pot.getDummyPOFile(lang.code)
-                        productserieslang = productserieslangset.getDummy(
-                            self.context, lang, pofile=pofile)
+                        productserieslang = (
+                            productserieslangset.getProductSeriesLanguage(
+                                self.context, lang, pofile=pofile))
                     else:
-                        productserieslang = productserieslangset.getDummy(
-                            self.context, lang)
+                        productserieslang = (
+                            productserieslangset.getProductSeriesLanguage(
+                                self.context, lang))
                     productserieslangs.append(
                         productserieslang)
 

=== modified file 'lib/lp/translations/browser/tests/test_breadcrumbs.py'
--- lib/lp/translations/browser/tests/test_breadcrumbs.py	2010-04-28 10:13:00 +0000
+++ lib/lp/translations/browser/tests/test_breadcrumbs.py	2010-07-19 15:43:43 +0000
@@ -23,7 +23,8 @@
             name='crumb-tester', displayname="Crumb Tester")
         self.assertBreadcrumbs(
             [("Crumb Tester", 'http://launchpad.dev/crumb-tester'),
-             ("Translations", 'http://translations.launchpad.dev/crumb-tester')],
+             ("Translations",
+              'http://translations.launchpad.dev/crumb-tester')],
             product, rootsite='translations')
 
     def test_productseries(self):
@@ -33,7 +34,8 @@
         self.assertBreadcrumbs(
             [("Crumb Tester", 'http://launchpad.dev/crumb-tester'),
              ("Series test", 'http://launchpad.dev/crumb-tester/test'),
-             ("Translations", 'http://translations.launchpad.dev/crumb-tester/test')],
+             ("Translations",
+              'http://translations.launchpad.dev/crumb-tester/test')],
             series, rootsite='translations')
 
     def test_distribution(self):
@@ -41,7 +43,8 @@
             name='crumb-tester', displayname="Crumb Tester")
         self.assertBreadcrumbs(
             [("Crumb Tester", 'http://launchpad.dev/crumb-tester'),
-             ("Translations", 'http://translations.launchpad.dev/crumb-tester')],
+             ("Translations",
+              'http://translations.launchpad.dev/crumb-tester')],
             distribution, rootsite='translations')
 
     def test_distroseries(self):
@@ -52,7 +55,8 @@
         self.assertBreadcrumbs(
             [("Crumb Tester", 'http://launchpad.dev/crumb-tester'),
              ("Test (1.0)", 'http://launchpad.dev/crumb-tester/test'),
-             ("Translations", 'http://translations.launchpad.dev/crumb-tester/test')],
+             ("Translations",
+              'http://translations.launchpad.dev/crumb-tester/test')],
             series, rootsite='translations')
 
     def test_project(self):
@@ -60,7 +64,8 @@
             name='crumb-tester', displayname="Crumb Tester")
         self.assertBreadcrumbs(
             [("Crumb Tester", 'http://launchpad.dev/crumb-tester'),
-             ("Translations", 'http://translations.launchpad.dev/crumb-tester')],
+             ("Translations",
+              'http://translations.launchpad.dev/crumb-tester')],
             project, rootsite='translations')
 
     def test_person(self):
@@ -68,7 +73,8 @@
             name='crumb-tester', displayname="Crumb Tester")
         self.assertBreadcrumbs(
             [("Crumb Tester", 'http://launchpad.dev/~crumb-tester'),
-             ("Translations", 'http://translations.launchpad.dev/~crumb-tester')],
+             ("Translations",
+              'http://translations.launchpad.dev/~crumb-tester')],
             person, rootsite='translations')
 
 
@@ -77,14 +83,16 @@
     def test_translationgroupset(self):
         group_set = getUtility(ITranslationGroupSet)
         self.assertBreadcrumbs(
-            [("Translation groups", 'http://translations.launchpad.dev/+groups')],
+            [("Translation groups",
+              'http://translations.launchpad.dev/+groups')],
             group_set, rootsite='translations')
 
     def test_translationgroup(self):
         group = self.factory.makeTranslationGroup(
             name='test-translators', title='Test translators')
         self.assertBreadcrumbs(
-            [("Translation groups", 'http://translations.launchpad.dev/+groups'),
+            [("Translation groups",
+              'http://translations.launchpad.dev/+groups'),
              ("Test translators",
               'http://translations.launchpad.dev/+groups/test-translators')],
             group, rootsite='translations')
@@ -111,7 +119,8 @@
              ("Translations",
               "http://translations.launchpad.dev/crumb-tester/test";),
              ("Serbian (sr)",
-              "http://translations.launchpad.dev/crumb-tester/test/+lang/sr";)],
+              "http://translations.launchpad.dev/";
+              "crumb-tester/test/+lang/sr")],
             serieslanguage)
 
     def test_productserieslanguage(self):
@@ -119,7 +128,8 @@
             name='crumb-tester', displayname="Crumb Tester")
         series = self.factory.makeProductSeries(
             name="test", product=product)
-        serieslanguage = getUtility(IProductSeriesLanguageSet).getDummy(
+        psl_set = getUtility(IProductSeriesLanguageSet)
+        serieslanguage = psl_set.getProductSeriesLanguage(
             series, self.language)
 
         self.assertBreadcrumbs(
@@ -128,11 +138,14 @@
              ("Translations",
               "http://translations.launchpad.dev/crumb-tester/test";),
              ("Serbian (sr)",
-              "http://translations.launchpad.dev/crumb-tester/test/+lang/sr";)],
+              "http://translations.launchpad.dev/";
+              "crumb-tester/test/+lang/sr")],
             serieslanguage)
 
 
 class TestPOTemplateBreadcrumbs(BaseBreadcrumbTestCase):
+    """Test POTemplate breadcrumbs."""
+
     def test_potemplate(self):
         product = self.factory.makeProduct(
             name='crumb-tester', displayname="Crumb Tester",
@@ -147,7 +160,8 @@
              ("Translations",
               "http://translations.launchpad.dev/crumb-tester/test";),
              (smartquote('Template "template"'),
-              "http://translations.launchpad.dev/crumb-tester/test/+pots/template";)],
+              "http://translations.launchpad.dev/";
+              "crumb-tester/test/+pots/template")],
             potemplate)
 
 

=== modified file 'lib/lp/translations/configure.zcml'
--- lib/lp/translations/configure.zcml	2010-05-04 13:42:25 +0000
+++ lib/lp/translations/configure.zcml	2010-07-19 15:43:43 +0000
@@ -372,7 +372,7 @@
             interface="lp.translations.interfaces.translationtemplateitem.ITranslationTemplateItem"/>
     </class>
 
-    <!-- ProductSeriesLanguage and Dummy -->
+    <!-- ProductSeriesLanguage -->
 
     <adapter
         provides="canonical.launchpad.webapp.interfaces.IBreadcrumb"
@@ -385,11 +385,6 @@
         <allow
             interface="lp.translations.interfaces.productserieslanguage.IProductSeriesLanguage"/>
     </class>
-    <class
-        class="lp.translations.model.productserieslanguage.DummyProductSeriesLanguage">
-        <allow
-            interface="lp.translations.interfaces.productserieslanguage.IProductSeriesLanguage"/>
-    </class>
 
     <!-- ProductSeriesLanguageSet -->
 

=== modified file 'lib/lp/translations/doc/canonical_url_examples.txt'
--- lib/lp/translations/doc/canonical_url_examples.txt	2009-09-17 16:22:32 +0000
+++ lib/lp/translations/doc/canonical_url_examples.txt	2010-07-19 15:43:43 +0000
@@ -50,13 +50,13 @@
 
     >>> potemplate = potemplatesubset['evolution-2.2']
     >>> canonical_url(potemplate)
-    u'http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2'
+    u'http://translations.../hoary/+source/evolution/+pots/evolution-2.2'
 
 And we can get a particular PO file for this PO template by its language code.
 
     >>> pofile = potemplate.getPOFileByLang('es')
     >>> canonical_url(pofile)
-    u'http://translations.../ubuntu/hoary/+source/evolution/+pots/evolution-2.2/es'
+    u'http://translations.../hoary/+source/evolution/+pots/evolution-2.2/es'
 
 Also, we can get the url to a translation message.
 
@@ -65,7 +65,7 @@
     ...     pofile.potemplate, pofile.language)
     >>> translationmessage.setPOFile(pofile)
     >>> print canonical_url(translationmessage)
-    http://translations.../ubuntu/hoary/+source/evolution/+pots/evolution-2.2/es/1
+    http://transl.../hoary/+source/evolution/+pots/evolution-2.2/es/1
 
 Even for a dummy one.
 
@@ -73,7 +73,7 @@
     >>> translationmessage = potmsgset.getCurrentDummyTranslationMessage(
     ...     pofile.potemplate, pofile.language)
     >>> print canonical_url(translationmessage)
-    http://translations.../ubuntu/hoary/+source/evolution/+pots/evolution-2.2/es/20
+    http://transl.../hoary/+source/evolution/+pots/evolution-2.2/es/20
 
 Upstream POTemplateSubsets work in much the same way, except they hang off a
 product series.  Let's get a product series.
@@ -173,7 +173,8 @@
     >>> from lp.translations.interfaces.productserieslanguage import (
     ...     IProductSeriesLanguageSet)
 
-    >>> coo_cah_serbian = getUtility(IProductSeriesLanguageSet).getDummy(
+    >>> psl_set = getUtility(IProductSeriesLanguageSet)
+    >>> coo_cah_serbian = psl_set.getProductSeriesLanguage(
     ...     productseries, serbian)
     >>> canonical_url(coo_cah_serbian)
     u'http://translations.launchpad.dev/coo/cah/+lang/sr'

=== modified file 'lib/lp/translations/interfaces/productserieslanguage.py'
--- lib/lp/translations/interfaces/productserieslanguage.py	2009-10-30 19:38:18 +0000
+++ lib/lp/translations/interfaces/productserieslanguage.py	2010-07-19 15:43:43 +0000
@@ -49,7 +49,6 @@
     last_changed_date = Datetime(
         title=_('When this file was last changed.'))
 
-
     def getPOFilesFor(potemplates):
         """Return `POFiles` for each of `potemplates`, in the same order.
 
@@ -67,10 +66,6 @@
 class IProductSeriesLanguageSet(Interface):
     """The set of productserieslanguages."""
 
-    def getDummy(productseries, language, variant=None):
-        """Return a new DummyProductSeriesLanguage for the given
-        productseries and language.
-        """
-
-    def getProductSeriesLanguage(productseries, language, variant=None):
+    def getProductSeriesLanguage(productseries, language, variant=None,
+                                 pofile=None):
         """Return a PSL for a productseries and a language."""

=== modified file 'lib/lp/translations/model/productserieslanguage.py'
--- lib/lp/translations/model/productserieslanguage.py	2009-10-30 19:39:58 +0000
+++ lib/lp/translations/model/productserieslanguage.py	2010-07-19 15:43:43 +0000
@@ -6,14 +6,13 @@
 __metaclass__ = type
 
 __all__ = [
-    'DummyProductSeriesLanguage',
     'ProductSeriesLanguage',
     'ProductSeriesLanguageSet',
     ]
 
 from zope.interface import implements
 
-from storm.expr import Sum
+from storm.expr import Coalesce, Sum
 from storm.store import Store
 
 from lp.translations.utilities.rosettastats import RosettaStats
@@ -41,8 +40,8 @@
         # Reset all cached counts.
         self.setCounts()
 
-    def setCounts(self, total=None, imported=None, changed=None, new=None,
-                  unreviewed=None, last_changed=None):
+    def setCounts(self, total=0, imported=0, changed=0, new=0,
+                  unreviewed=0, last_changed=None):
         """See `IProductSeriesLanguage`."""
         self._messagecount = total
         # "currentcount" in RosettaStats conflicts our recent terminology
@@ -70,20 +69,16 @@
         """See `IProductSeriesLanguage`."""
         store = Store.of(self.language)
         query = store.find(
-            (Sum(POFile.currentcount),
-              Sum(POFile.updatescount),
-              Sum(POFile.rosettacount),
-              Sum(POFile.unreviewed_count)),
+            (Coalesce(Sum(POFile.currentcount), 0),
+             Coalesce(Sum(POFile.updatescount), 0),
+             Coalesce(Sum(POFile.rosettacount), 0),
+             Coalesce(Sum(POFile.unreviewed_count), 0)),
             POFile.language==self.language,
             POFile.variant==None,
             POFile.potemplate==POTemplate.id,
             POTemplate.productseries==self.productseries,
             POTemplate.iscurrent==True)
         imported, changed, new, unreviewed = query[0]
-        if (imported is None or changed is None or
-            new is None or unreviewed is None):
-            # Set all counts to zero.
-            imported = changed = new = unreviewed = 0
         self.setCounts(self._getMessageCount(), imported, changed,
                        new, unreviewed)
 
@@ -138,40 +133,14 @@
         return get_pofiles_for(potemplates, self.language, self.variant)
 
 
-class DummyProductSeriesLanguage(ProductSeriesLanguage):
-    """See `IProductSeriesLanguage`.
-
-    Implementation of IProductSeriesLanguage for a language with no
-    translations.
-    """
-    implements(IProductSeriesLanguage)
-
-    def __init__(self, productseries, language, variant=None, pofile=None):
-        ProductSeriesLanguage.__init__(
-            self, productseries, language, variant, pofile)
-        self.setCounts(self._getMessageCount(), 0, 0, 0, 0)
-
-    def getPOFilesFor(self, potemplates):
-        """See `IProductSeriesLanguage`."""
-        return [
-            DummyPOFile(template, self.language, self.variant)
-            for template in potemplates
-            ]
-
-
 class ProductSeriesLanguageSet:
     """See `IProductSeriesLanguageSet`.
 
-    Provides a means to get a ProductSeriesLanguage or create a dummy.
+    Provides a means to get a ProductSeriesLanguage.
     """
     implements(IProductSeriesLanguageSet)
 
     def getProductSeriesLanguage(self, productseries, language,
-                                 variant=None):
-        """See `IProductSeriesLanguageSet`."""
-        return ProductSeriesLanguage(productseries, language, variant)
-
-    def getDummy(self, productseries, language, variant=None, pofile=None):
-        """See `IProductSeriesLanguageSet`."""
-        return DummyProductSeriesLanguage(
-            productseries, language, variant, pofile)
+                                 variant=None, pofile=None):
+        """See `IProductSeriesLanguageSet`."""
+        return ProductSeriesLanguage(productseries, language, variant, pofile)

=== modified file 'lib/lp/translations/tests/test_productserieslanguage.py'
--- lib/lp/translations/tests/test_productserieslanguage.py	2009-11-04 17:15:56 +0000
+++ lib/lp/translations/tests/test_productserieslanguage.py	2010-07-19 15:43:43 +0000
@@ -143,16 +143,19 @@
              psl.last_changed_date),
              stats)
 
-    def test_DummyProductSeriesLanguage(self):
+    def test_dummy_ProductSeriesLanguage(self):
         # With no templates all counts are zero.
-        psl = self.psl_set.getDummy(self.productseries, self.language)
+        psl = self.psl_set.getProductSeriesLanguage(
+            self.productseries, self.language)
         self.failUnless(verifyObject(IProductSeriesLanguage, psl))
         self.assertPSLStatistics(psl, (0, 0, 0, 0, 0, 0, None))
 
         # Adding a single template with 10 messages makes the total
         # count of messages go up to 10.
         potemplate = self.createPOTemplateWithPOTMsgSets(10)
-        psl = self.psl_set.getDummy(self.productseries, self.language)
+        psl = self.psl_set.getProductSeriesLanguage(
+            self.productseries, self.language)
+        psl.recalculateCounts()
         self.assertPSLStatistics(
             psl, (10, 0, 0, 0, 0, 0, None))