← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~jtv/launchpad/independence-for-ihastranslationtemplates into lp:launchpad/devel

 

Jeroen T. Vermeulen has proposed merging lp:~jtv/launchpad/independence-for-ihastranslationtemplates into lp:launchpad/devel.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers): code


= Independence for IHasTranslationTemplates! =

This branch does absolutely nothing but move IHasTranslationTemplates and its supporting mixin implementation into modules of their own.  Helps avoid some circular imports I'm facing.

So instead of boring you with the formalities of a cover letter, instead let me tell you a story this reminds me of.  I heard of someone who set up a food stall at some demonstration (either for or against global warming, I believe).  To express his support for the cause, he gave the food he made away for free.  The sign on his stall said: free falafel.

The first group to approach his stall asked: "who's Falafel?"


Jeroen
-- 
https://code.launchpad.net/~jtv/launchpad/independence-for-ihastranslationtemplates/+merge/40321
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jtv/launchpad/independence-for-ihastranslationtemplates into lp:launchpad/devel.
=== modified file 'lib/canonical/launchpad/interfaces/_schema_circular_imports.py'
--- lib/canonical/launchpad/interfaces/_schema_circular_imports.py	2010-11-04 07:14:21 +0000
+++ lib/canonical/launchpad/interfaces/_schema_circular_imports.py	2010-11-08 12:49:43 +0000
@@ -117,6 +117,9 @@
 from lp.translations.interfaces.hastranslationimports import (
     IHasTranslationImports,
     )
+from lp.translations.interfaces.hastranslationtemplates import (
+    IHasTranslationTemplates,
+    )
 from lp.translations.interfaces.pofile import IPOFile
 from lp.translations.interfaces.potemplate import (
     IPOTemplate,
@@ -475,6 +478,10 @@
 # IBugTracker
 patch_reference_property(IBugTracker, 'owner', IPerson)
 
+# IHasTranslationTemplates
+patch_collection_return_type(
+    IHasTranslationTemplates, 'getTranslationTemplates', IPOTemplate)
+
 # IPOTemplate
 patch_collection_property(IPOTemplate, 'pofiles', IPOFile)
 patch_reference_property(IPOTemplate, 'product', IProduct)

=== modified file 'lib/lp/registry/interfaces/distroseries.py'
--- lib/lp/registry/interfaces/distroseries.py	2010-11-08 03:45:09 +0000
+++ lib/lp/registry/interfaces/distroseries.py	2010-11-08 12:49:43 +0000
@@ -89,8 +89,10 @@
 from lp.translations.interfaces.hastranslationimports import (
     IHasTranslationImports,
     )
+from lp.translations.interfaces.hastranslationtemplates import (
+    IHasTranslationTemplates,
+    )
 from lp.translations.interfaces.languagepack import ILanguagePack
-from lp.translations.interfaces.potemplate import IHasTranslationTemplates
 
 
 class DistroSeriesNameField(ContentNameField):

=== modified file 'lib/lp/registry/interfaces/productseries.py'
--- lib/lp/registry/interfaces/productseries.py	2010-10-29 10:01:34 +0000
+++ lib/lp/registry/interfaces/productseries.py	2010-11-08 12:49:43 +0000
@@ -76,7 +76,9 @@
 from lp.translations.interfaces.hastranslationimports import (
     IHasTranslationImports,
     )
-from lp.translations.interfaces.potemplate import IHasTranslationTemplates
+from lp.translations.interfaces.hastranslationtemplates import (
+    IHasTranslationTemplates,
+    )
 from lp.translations.interfaces.translations import (
     TranslationsBranchImportMode,
     )

=== modified file 'lib/lp/registry/interfaces/sourcepackage.py'
--- lib/lp/registry/interfaces/sourcepackage.py	2010-10-29 10:01:34 +0000
+++ lib/lp/registry/interfaces/sourcepackage.py	2010-11-08 12:49:43 +0000
@@ -55,10 +55,12 @@
     IHasMergeProposals,
     )
 from lp.soyuz.interfaces.component import IComponent
+from lp.translations.interfaces.hastranslationtemplates import (
+    IHasTranslationTemplates,
+    )
 from lp.translations.interfaces.hastranslationimports import (
     IHasTranslationImports,
     )
-from lp.translations.interfaces.potemplate import IHasTranslationTemplates
 
 
 class ISourcePackage(IBugTarget, IHasBranches, IHasMergeProposals,

=== modified file 'lib/lp/registry/model/distroseries.py'
--- lib/lp/registry/model/distroseries.py	2010-11-08 03:45:09 +0000
+++ lib/lp/registry/model/distroseries.py	2010-11-08 12:49:43 +0000
@@ -187,11 +187,13 @@
 from lp.translations.model.hastranslationimports import (
     HasTranslationImportsMixin,
     )
+from lp.translations.model.hastranslationtemplates import (
+    HasTranslationTemplatesMixin,
+    )
 from lp.translations.model.languagepack import LanguagePack
 from lp.translations.model.pofile import POFile
 from lp.translations.model.pofiletranslator import POFileTranslator
 from lp.translations.model.potemplate import (
-    HasTranslationTemplatesMixin,
     POTemplate,
     TranslationTemplatesCollection,
     )

=== modified file 'lib/lp/registry/model/productseries.py'
--- lib/lp/registry/model/productseries.py	2010-11-02 06:21:58 +0000
+++ lib/lp/registry/model/productseries.py	2010-11-08 12:49:43 +0000
@@ -92,9 +92,11 @@
 from lp.translations.model.hastranslationimports import (
     HasTranslationImportsMixin,
     )
+from lp.translations.model.hastranslationtemplates import (
+    HasTranslationTemplatesMixin,
+    )
 from lp.translations.model.pofile import POFile
 from lp.translations.model.potemplate import (
-    HasTranslationTemplatesMixin,
     POTemplate,
     TranslationTemplatesCollection,
     )

=== modified file 'lib/lp/registry/model/sourcepackage.py'
--- lib/lp/registry/model/sourcepackage.py	2010-10-29 10:09:04 +0000
+++ lib/lp/registry/model/sourcepackage.py	2010-11-08 12:49:43 +0000
@@ -94,10 +94,10 @@
 from lp.translations.model.hastranslationimports import (
     HasTranslationImportsMixin,
     )
-from lp.translations.model.potemplate import (
+from lp.translations.model.hastranslationtemplates import (
     HasTranslationTemplatesMixin,
-    TranslationTemplatesCollection,
     )
+from lp.translations.model.potemplate import TranslationTemplatesCollection
 
 
 class SourcePackageQuestionTargetMixin(QuestionTargetMixin):

=== modified file 'lib/lp/translations/browser/poexportrequest.py'
--- lib/lp/translations/browser/poexportrequest.py	2010-09-27 20:47:58 +0000
+++ lib/lp/translations/browser/poexportrequest.py	2010-11-08 12:49:43 +0000
@@ -19,7 +19,9 @@
 from lp.app.browser.tales import DurationFormatterAPI
 from lp.services.propertycache import cachedproperty
 from lp.translations.interfaces.poexportrequest import IPOExportRequestSet
-from lp.translations.interfaces.potemplate import IHasTranslationTemplates
+from lp.translations.interfaces.hastranslationtemplates import (
+    IHasTranslationTemplates,
+    )
 from lp.translations.interfaces.translationexporter import (
     ITranslationExporter,
     )

=== added file 'lib/lp/translations/interfaces/hastranslationtemplates.py'
--- lib/lp/translations/interfaces/hastranslationtemplates.py	1970-01-01 00:00:00 +0000
+++ lib/lp/translations/interfaces/hastranslationtemplates.py	2010-11-08 12:49:43 +0000
@@ -0,0 +1,104 @@
+# Copyright 2010 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Interface for objects that translation templates can belong to."""
+
+__metaclass__ = type
+__all__ = [
+    'IHasTranslationTemplates',
+    ]
+
+from lazr.restful.declarations import (
+    export_read_operation,
+    operation_returns_collection_of,
+    )
+from zope.interface import Interface
+from zope.schema import Bool
+
+from canonical.launchpad import _
+
+
+class IHasTranslationTemplates(Interface):
+    """An entity that has translation templates attached.
+
+    Examples include `ISourcePackage`, `IDistroSeries`, and `IProductSeries`.
+    """
+
+    has_translation_templates = Bool(
+        title=_("Does this object have any translation templates?"),
+        readonly=True)
+
+    has_current_translation_templates = Bool(
+        title=_("Does this object have current translation templates?"),
+        readonly=True)
+
+    has_translation_files = Bool(
+        title=_("Does this object have translation files?"),
+        readonly=True)
+
+    def getTemplatesCollection():
+        """Return templates as a `TranslationTemplatesCollection`.
+
+        The collection selects all `POTemplate`s attached to the
+        translation target that implements this interface.
+        """
+
+    def getCurrentTemplatesCollection():
+        """Return `TranslationTemplatesCollection` of current templates.
+
+        A translation template is considered active when both
+        `IPOTemplate`.iscurrent and the `official_rosetta` flag for its
+        containing `Product` or `Distribution` are set to True.
+        """
+        # XXX JeroenVermeulen 2010-07-16 bug=605924: Move the
+        # official_rosetta distinction into browser code.
+
+    def getCurrentTranslationTemplates(just_ids=False):
+        """Return an iterator over all active translation templates.
+
+        :param just_ids: If True, return only the `POTemplate.id` rather
+            than the full `POTemplate`.  Used to save time on retrieving
+            and deserializing the objects from the database.
+
+        A translation template is considered active when both
+        `IPOTemplate`.iscurrent and the `official_rosetta` flag for its
+        containing `Product` or `Distribution` are set to True.
+        """
+        # XXX JeroenVermeulen 2010-07-16 bug=605924: Move the
+        # official_rosetta distinction into browser code.
+
+    def getCurrentTranslationFiles(just_ids=False):
+        """Return an iterator over all active translation files.
+
+        A translation file is active if it's attached to an
+        active translation template.
+        """
+
+    def getObsoleteTranslationTemplates():
+        """Return an iterator over its not active translation templates.
+
+        A translation template is considered not active when any of
+        `IPOTemplate`.iscurrent or `IDistribution`.official_rosetta flags
+        are set to False.
+        """
+
+    @export_read_operation()
+    @operation_returns_collection_of(Interface)
+    def getTranslationTemplates():
+        """Return an iterator over all its translation templates.
+
+        The returned templates are either obsolete or current.
+
+        :return: A sequence of `IPOTemplate`.
+        """
+
+    def getTranslationTemplateFormats():
+        """A list of native formats for all current translation templates.
+        """
+
+    def getTemplatesAndLanguageCounts():
+        """List tuples of `POTemplate` and its language count.
+
+        A template's language count is the number of `POFile`s that
+        exist for it.
+        """

=== modified file 'lib/lp/translations/interfaces/potemplate.py'
--- lib/lp/translations/interfaces/potemplate.py	2010-10-03 15:30:06 +0000
+++ lib/lp/translations/interfaces/potemplate.py	2010-11-08 12:49:43 +0000
@@ -9,9 +9,7 @@
     )
 from lazr.restful.declarations import (
     export_as_webservice_entry,
-    export_read_operation,
     exported,
-    operation_returns_collection_of,
     )
 from lazr.restful.fields import (
     CollectionField,
@@ -47,7 +45,6 @@
 __metaclass__ = type
 
 __all__ = [
-    'IHasTranslationTemplates',
     'IPOTemplate',
     'IPOTemplateSet',
     'IPOTemplateSharingSubset',
@@ -725,90 +722,6 @@
         required=True)
 
 
-class IHasTranslationTemplates(Interface):
-    """An entity that has translation templates attached.
-
-    Examples include `ISourcePackage`, `IDistroSeries`, and `IProductSeries`.
-    """
-
-    has_translation_templates = Bool(
-        title=_("Does this object have any translation templates?"),
-        readonly=True)
-
-    has_current_translation_templates = Bool(
-        title=_("Does this object have current translation templates?"),
-        readonly=True)
-
-    has_translation_files = Bool(
-        title=_("Does this object have translation files?"),
-        readonly=True)
-
-    def getTemplatesCollection():
-        """Return templates as a `TranslationTemplatesCollection`.
-
-        The collection selects all `POTemplate`s attached to the
-        translation target that implements this interface.
-        """
-
-    def getCurrentTemplatesCollection():
-        """Return `TranslationTemplatesCollection` of current templates.
-
-        A translation template is considered active when both
-        `IPOTemplate`.iscurrent and the `official_rosetta` flag for its
-        containing `Product` or `Distribution` are set to True.
-        """
-        # XXX JeroenVermeulen 2010-07-16 bug=605924: Move the
-        # official_rosetta distinction into browser code.
-
-    def getCurrentTranslationTemplates(just_ids=False):
-        """Return an iterator over all active translation templates.
-
-        :param just_ids: If True, return only the `POTemplate.id` rather
-            than the full `POTemplate`.  Used to save time on retrieving
-            and deserializing the objects from the database.
-
-        A translation template is considered active when both
-        `IPOTemplate`.iscurrent and the `official_rosetta` flag for its
-        containing `Product` or `Distribution` are set to True.
-        """
-        # XXX JeroenVermeulen 2010-07-16 bug=605924: Move the
-        # official_rosetta distinction into browser code.
-
-    def getCurrentTranslationFiles(just_ids=False):
-        """Return an iterator over all active translation files.
-
-        A translation file is active if it's attached to an
-        active translation template.
-        """
-
-    def getObsoleteTranslationTemplates():
-        """Return an iterator over its not active translation templates.
-
-        A translation template is considered not active when any of
-        `IPOTemplate`.iscurrent or `IDistribution`.official_rosetta flags
-        are set to False.
-        """
-
-    @export_read_operation()
-    @operation_returns_collection_of(IPOTemplate)
-    def getTranslationTemplates():
-        """Return an iterator over all its translation templates.
-
-        The returned templates are either obsolete or current.
-        """
-
-    def getTranslationTemplateFormats():
-        """A list of native formats for all current translation templates.
-        """
-
-    def getTemplatesAndLanguageCounts():
-        """List tuples of `POTemplate` and its language count.
-
-        A template's language count is the number of `POFile`s that
-        exist for it.
-        """
-
-
 class ITranslationTemplatesCollection(Interface):
     """A `Collection` of `POTemplate`s."""
 

=== modified file 'lib/lp/translations/interfaces/translatedlanguage.py'
--- lib/lp/translations/interfaces/translatedlanguage.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/interfaces/translatedlanguage.py	2010-11-08 12:49:43 +0000
@@ -16,7 +16,9 @@
 from canonical.launchpad import _
 from lp.registry.interfaces.person import IPerson
 from lp.services.worlddata.interfaces.language import ILanguage
-from lp.translations.interfaces.potemplate import IHasTranslationTemplates
+from lp.translations.interfaces.hastranslationtemplates import (
+    IHasTranslationTemplates,
+    )
 
 
 __metaclass__ = type

=== added file 'lib/lp/translations/model/hastranslationtemplates.py'
--- lib/lp/translations/model/hastranslationtemplates.py	1970-01-01 00:00:00 +0000
+++ lib/lp/translations/model/hastranslationtemplates.py	2010-11-08 12:49:43 +0000
@@ -0,0 +1,117 @@
+# Copyright 2010 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Implementation class for objects that `POTemplate`s can belong to."""
+
+__metaclass__ = type
+__all__ = [
+    'HasTranslationTemplatesMixin',
+    ]
+
+from storm.expr import (
+    Count,
+    Desc,
+    )
+from zope.interface import implements
+
+from canonical.launchpad import helpers
+from lp.app.enums import service_uses_launchpad
+from lp.translations.interfaces.hastranslationtemplates import (
+    IHasTranslationTemplates,
+    )
+from lp.translations.model.potemplate import POTemplate
+from lp.translations.model.pofile import POFile
+
+
+class HasTranslationTemplatesMixin:
+    """Helper class for implementing `IHasTranslationTemplates`."""
+    implements(IHasTranslationTemplates)
+
+    def getTemplatesCollection(self):
+        """See `IHasTranslationTemplates`.
+
+        To be provided by derived classes.
+        """
+        raise NotImplementedError(
+            "Child class must provide getTemplatesCollection.")
+
+    def _orderTemplates(self, result):
+        """Apply the conventional ordering to a result set of templates."""
+        return result.order_by(Desc(POTemplate.priority), POTemplate.name)
+
+    def getCurrentTemplatesCollection(self, current_value=True):
+        """See `IHasTranslationTemplates`."""
+        collection = self.getTemplatesCollection()
+
+        # XXX JeroenVermeulen 2010-07-15 bug=605924: Move the
+        # translations_usage distinction into browser code.
+        pillar = collection.target_pillar
+        if service_uses_launchpad(pillar.translations_usage):
+            return collection.restrictCurrent(current_value)
+        else:
+            # Product/Distribution does not have translation enabled.
+            # Treat all templates as obsolete.
+            return collection.refine(not current_value)
+
+    def getCurrentTranslationTemplates(self,
+                                       just_ids=False,
+                                       current_value=True):
+        """See `IHasTranslationTemplates`."""
+        if just_ids:
+            selection = POTemplate.id
+        else:
+            selection = POTemplate
+
+        collection = self.getCurrentTemplatesCollection(current_value)
+        return self._orderTemplates(collection.select(selection))
+
+    @property
+    def has_translation_templates(self):
+        """See `IHasTranslationTemplates`."""
+        return bool(self.getTranslationTemplates().any())
+
+    @property
+    def has_current_translation_templates(self):
+        """See `IHasTranslationTemplates`."""
+        return bool(
+            self.getCurrentTranslationTemplates(just_ids=True).any())
+
+    def getCurrentTranslationFiles(self, just_ids=False):
+        """See `IHasTranslationTemplates`."""
+        if just_ids:
+            selection = POFile.id
+        else:
+            selection = POFile
+
+        collection = self.getCurrentTemplatesCollection()
+        return collection.joinPOFile().select(selection)
+
+    @property
+    def has_translation_files(self):
+        """See `IHasTranslationTemplates`."""
+        return bool(
+            self.getCurrentTranslationFiles(just_ids=True).any())
+
+    def getObsoleteTranslationTemplates(self):
+        """See `IHasTranslationTemplates`."""
+        # XXX JeroenVermeulen 2010-07-15 bug=605924: This returns a list
+        # whereas the analogous method for current template returns a
+        # result set.  Clean up this mess.
+        return list(self.getCurrentTranslationTemplates(current_value=False))
+
+    def getTranslationTemplates(self):
+        """See `IHasTranslationTemplates`."""
+        return self._orderTemplates(self.getTemplatesCollection().select())
+
+    def getTranslationTemplateFormats(self):
+        """See `IHasTranslationTemplates`."""
+        formats_query = self.getCurrentTranslationTemplates().order_by(
+            'source_file_format').config(distinct=True)
+        return helpers.shortlist(
+            formats_query.values(POTemplate.source_file_format), 10)
+
+    def getTemplatesAndLanguageCounts(self):
+        """See `IHasTranslationTemplates`."""
+        join = self.getTemplatesCollection().joinOuterPOFile()
+        result = join.select(POTemplate, Count(POFile.id))
+        return result.group_by(POTemplate)

=== modified file 'lib/lp/translations/model/potemplate.py'
--- lib/lp/translations/model/potemplate.py	2010-10-29 05:58:51 +0000
+++ lib/lp/translations/model/potemplate.py	2010-11-08 12:49:43 +0000
@@ -8,7 +8,6 @@
 __metaclass__ = type
 __all__ = [
     'get_pofiles_for',
-    'HasTranslationTemplatesMixin',
     'POTemplate',
     'POTemplateSet',
     'POTemplateSubset',
@@ -32,7 +31,6 @@
     )
 from storm.expr import (
     And,
-    Count,
     Desc,
     In,
     Join,
@@ -64,7 +62,6 @@
     IMasterStore,
     IStore,
     )
-from lp.app.enums import service_uses_launchpad
 from lp.app.errors import NotFoundError
 from lp.registry.interfaces.person import validate_public_person
 from lp.registry.model.sourcepackagename import SourcePackageName
@@ -75,7 +72,6 @@
 from lp.translations.enums import RosettaImportStatus
 from lp.translations.interfaces.pofile import IPOFileSet
 from lp.translations.interfaces.potemplate import (
-    IHasTranslationTemplates,
     IPOTemplate,
     IPOTemplateSet,
     IPOTemplateSharingSubset,
@@ -1555,100 +1551,6 @@
         return messages
 
 
-class HasTranslationTemplatesMixin:
-    """Helper class for implementing `IHasTranslationTemplates`."""
-    implements(IHasTranslationTemplates)
-
-    def getTemplatesCollection(self):
-        """See `IHasTranslationTemplates`.
-
-        To be provided by derived classes.
-        """
-        raise NotImplementedError(
-            "Child class must provide getTemplatesCollection.")
-
-    def _orderTemplates(self, result):
-        """Apply the conventional ordering to a result set of templates."""
-        return result.order_by(Desc(POTemplate.priority), POTemplate.name)
-
-    def getCurrentTemplatesCollection(self, current_value=True):
-        """See `IHasTranslationTemplates`."""
-        collection = self.getTemplatesCollection()
-
-        # XXX JeroenVermeulen 2010-07-15 bug=605924: Move the
-        # translations_usage distinction into browser code.
-        pillar = collection.target_pillar
-        if service_uses_launchpad(pillar.translations_usage):
-            return collection.restrictCurrent(current_value)
-        else:
-            # Product/Distribution does not have translation enabled.
-            # Treat all templates as obsolete.
-            return collection.refine(not current_value)
-
-    def getCurrentTranslationTemplates(self,
-                                       just_ids=False,
-                                       current_value=True):
-        """See `IHasTranslationTemplates`."""
-        if just_ids:
-            selection = POTemplate.id
-        else:
-            selection = POTemplate
-
-        collection = self.getCurrentTemplatesCollection(current_value)
-        return self._orderTemplates(collection.select(selection))
-
-    @property
-    def has_translation_templates(self):
-        """See `IHasTranslationTemplates`."""
-        return bool(self.getTranslationTemplates().any())
-
-    @property
-    def has_current_translation_templates(self):
-        """See `IHasTranslationTemplates`."""
-        return bool(
-            self.getCurrentTranslationTemplates(just_ids=True).any())
-
-    def getCurrentTranslationFiles(self, just_ids=False):
-        """See `IHasTranslationTemplates`."""
-        if just_ids:
-            selection = POFile.id
-        else:
-            selection = POFile
-
-        collection = self.getCurrentTemplatesCollection()
-        return collection.joinPOFile().select(selection)
-
-    @property
-    def has_translation_files(self):
-        """See `IHasTranslationTemplates`."""
-        return bool(
-            self.getCurrentTranslationFiles(just_ids=True).any())
-
-    def getObsoleteTranslationTemplates(self):
-        """See `IHasTranslationTemplates`."""
-        # XXX JeroenVermeulen 2010-07-15 bug=605924: This returns a list
-        # whereas the analogous method for current template returns a
-        # result set.  Clean up this mess.
-        return list(self.getCurrentTranslationTemplates(current_value=False))
-
-    def getTranslationTemplates(self):
-        """See `IHasTranslationTemplates`."""
-        return self._orderTemplates(self.getTemplatesCollection().select())
-
-    def getTranslationTemplateFormats(self):
-        """See `IHasTranslationTemplates`."""
-        formats_query = self.getCurrentTranslationTemplates().order_by(
-            'source_file_format').config(distinct=True)
-        return helpers.shortlist(
-            formats_query.values(POTemplate.source_file_format), 10)
-
-    def getTemplatesAndLanguageCounts(self):
-        """See `IHasTranslationTemplates`."""
-        join = self.getTemplatesCollection().joinOuterPOFile()
-        result = join.select(POTemplate, Count(POFile.id))
-        return result.group_by(POTemplate)
-
-
 class TranslationTemplatesCollection(Collection):
     """A `Collection` of `POTemplate`."""
     starting_table = POTemplate

=== modified file 'lib/lp/translations/model/translatedlanguage.py'
--- lib/lp/translations/model/translatedlanguage.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/model/translatedlanguage.py	2010-11-08 12:49:43 +0000
@@ -12,7 +12,9 @@
     )
 from zope.interface import implements
 
-from lp.translations.interfaces.potemplate import IHasTranslationTemplates
+from lp.translations.interfaces.hastranslationtemplates import (
+    IHasTranslationTemplates,
+    )
 from lp.translations.interfaces.translatedlanguage import (
     IPOFilesByPOTemplates,
     ITranslatedLanguage,

=== modified file 'lib/lp/translations/tests/test_hastranslationtemplates.py'
--- lib/lp/translations/tests/test_hastranslationtemplates.py	2010-10-04 19:50:45 +0000
+++ lib/lp/translations/tests/test_hastranslationtemplates.py	2010-11-08 12:49:43 +0000
@@ -8,7 +8,9 @@
 from canonical.testing.layers import ZopelessDatabaseLayer
 from lp.app.enums import ServiceUsage
 from lp.testing import TestCaseWithFactory
-from lp.translations.interfaces.potemplate import IHasTranslationTemplates
+from lp.translations.interfaces.hastranslationtemplates import (
+    IHasTranslationTemplates,
+    )
 from lp.translations.interfaces.translationfileformat import (
     TranslationFileFormat,
     )