← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:pyupgrade-py3-translations-2 into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:pyupgrade-py3-translations-2 into launchpad:master.

Commit message:
lp.translations.{interfaces,model}: Apply "pyupgrade --py3-plus"

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/414171
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:pyupgrade-py3-translations-2 into launchpad:master.
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index e01ae37..06f9be6 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -46,5 +46,7 @@ f3f15787ebabe305fbf3e3ae6c0fd8ca7dfb4465
 21fb5364d9371c0ad2edf41fa6920c4e16ead2b0
 # apply pyupgrade --py3-plus to lp.{testing,testopenid,tests}
 9621eff0fd58287b254fb228c11948fca85d547c
-# apply pyupgrade --py3-plus to lp.translations
+# apply pyupgrade --py3-plus to lp.translations.browser
 d61c2ad002c2997a132a1580ce6ee82bb03de11d
+# apply pyupgrade --py3-plus to lp.translations.{interfaces,model}
+afcfc15adcf3267d3fd07d7679df00231853c908
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index ba49e44..14df1e9 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -60,7 +60,7 @@ repos:
             |testing
             |testopenid
             |tests
-            |translations/browser
+            |translations/(browser|interfaces|model)
           )/
 -   repo: https://github.com/PyCQA/isort
     rev: 5.9.2
diff --git a/lib/lp/translations/interfaces/poexportrequest.py b/lib/lp/translations/interfaces/poexportrequest.py
index b80caf5..de4ad9b 100644
--- a/lib/lp/translations/interfaces/poexportrequest.py
+++ b/lib/lp/translations/interfaces/poexportrequest.py
@@ -23,7 +23,7 @@ from lp.translations.interfaces.translationfileformat import (
 
 class IPOExportRequestSet(Interface):
     entry_count = Int(
-        title=u'Number of entries waiting in the queue.',
+        title='Number of entries waiting in the queue.',
         required=True, readonly=True)
 
     def estimateBacklog():
@@ -62,16 +62,16 @@ class IPOExportRequestSet(Interface):
 
 class IPOExportRequest(Interface):
     person = Object(
-        title=u'The person who made the request.',
+        title='The person who made the request.',
         required=True, readonly=True, schema=IPerson)
 
     date_created = Datetime(
-        title=u"Request's creation timestamp.", required=True, readonly=True)
+        title="Request's creation timestamp.", required=True, readonly=True)
 
     potemplate = Object(
-        title=u'The translation template to which the requested file belong.',
+        title='The translation template to which the requested file belong.',
         required=True, readonly=True, schema=IPOTemplate)
 
     pofile = Object(
-        title=u'The translation file requested, if any.',
+        title='The translation file requested, if any.',
         required=True, readonly=True, schema=IPOFile)
diff --git a/lib/lp/translations/interfaces/pofile.py b/lib/lp/translations/interfaces/pofile.py
index 1c1d41c..6424c56 100644
--- a/lib/lp/translations/interfaces/pofile.py
+++ b/lib/lp/translations/interfaces/pofile.py
@@ -345,9 +345,9 @@ class IPOFileAlternativeLanguage(Interface):
     """A PO File's alternative language."""
 
     alternative_language = Choice(
-        title=u'Alternative language',
-        description=(u'Language from where we could get alternative'
-                     u' translations for this PO file.'),
+        title='Alternative language',
+        description=('Language from where we could get alternative'
+                     ' translations for this PO file.'),
         source=AlternativeLanguageVocabularyFactory(),
         required=False)
 
diff --git a/lib/lp/translations/interfaces/pofiletranslator.py b/lib/lp/translations/interfaces/pofiletranslator.py
index df069f9..6d68b02 100644
--- a/lib/lp/translations/interfaces/pofiletranslator.py
+++ b/lib/lp/translations/interfaces/pofiletranslator.py
@@ -25,15 +25,15 @@ class IPOFileTranslator(Interface):
     id = Int(title=_("ID"), readonly=True, required=True)
 
     person = Object(
-        title=_(u"The `Person` whose contribution this record represents."),
+        title=_("The `Person` whose contribution this record represents."),
         required=True, readonly=True, schema=IPerson)
 
     pofile = Object(
-        title=_(u"The `POFile` modified by the translator."), required=True,
+        title=_("The `POFile` modified by the translator."), required=True,
         readonly=True, schema=IPOFile)
 
     date_last_touched = Datetime(
-        title=_(u"When the latest translation message was added."),
+        title=_("When the latest translation message was added."),
         required=True, readonly=True)
 
 
diff --git a/lib/lp/translations/interfaces/pomsgid.py b/lib/lp/translations/interfaces/pomsgid.py
index 0b0b45c..f113879 100644
--- a/lib/lp/translations/interfaces/pomsgid.py
+++ b/lib/lp/translations/interfaces/pomsgid.py
@@ -21,4 +21,4 @@ class IPOMsgID(Interface):
         readonly=True, required=True)
 
     msgid = Text(
-        title=_(u"A msgid string."))
+        title=_("A msgid string."))
diff --git a/lib/lp/translations/interfaces/potemplate.py b/lib/lp/translations/interfaces/potemplate.py
index 8a1850d..ebfea42 100644
--- a/lib/lp/translations/interfaces/potemplate.py
+++ b/lib/lp/translations/interfaces/potemplate.py
@@ -57,7 +57,7 @@ class IPOTemplate(IRosettaStats):
     """A translation template."""
 
     id = exported(Int(
-        title=u"The translation template id.",
+        title="The translation template id.",
         required=True, readonly=True))
 
     name = exported(TextLine(
@@ -132,7 +132,7 @@ class IPOTemplate(IRosettaStats):
         readonly=True)
 
     sourcepackage = Reference(
-        ISourcePackage, title=u"Source package this template is for, if any.",
+        ISourcePackage, title="Source package this template is for, if any.",
         required=False, readonly=True)
 
     from_sourcepackagename = Choice(
diff --git a/lib/lp/translations/interfaces/potmsgset.py b/lib/lp/translations/interfaces/potmsgset.py
index 18c5c3d..4af6b3d 100644
--- a/lib/lp/translations/interfaces/potmsgset.py
+++ b/lib/lp/translations/interfaces/potmsgset.py
@@ -73,7 +73,7 @@ class IPOTMsgSet(Interface):
         readonly=True, required=True)
 
     context = Text(
-        title=u"String used to disambiguate messages with identical msgids.")
+        title="String used to disambiguate messages with identical msgids.")
 
     msgid_singular = Object(
         title=_("The singular msgid for this message."),
@@ -83,10 +83,10 @@ class IPOTMsgSet(Interface):
             """), readonly=True, required=True, schema=IPOMsgID)
 
     msgid_plural = Object(
-        title=u"The plural msgid for this message.",
-        description=(u"Provides a plural msgid for the message. "
-                     u"If it's not a plural form message, this value"
-                     u"should be None."),
+        title="The plural msgid for this message.",
+        description=("Provides a plural msgid for the message. "
+                     "If it's not a plural form message, this value"
+                     "should be None."),
         required=True,
         readonly=True,
         schema=IPOMsgID)
@@ -334,7 +334,7 @@ class IPOTMsgSet(Interface):
         """Whether this is a message set for crediting translators.""")
 
     translation_credits_type = Choice(
-        title=u"The type of translation credit of this message.",
+        title="The type of translation credit of this message.",
         required=True,
         vocabulary=TranslationCreditsType)
 
diff --git a/lib/lp/translations/interfaces/side.py b/lib/lp/translations/interfaces/side.py
index 1888802..47ca948 100644
--- a/lib/lp/translations/interfaces/side.py
+++ b/lib/lp/translations/interfaces/side.py
@@ -39,13 +39,13 @@ class ITranslationSideTraits(Interface):
     """
     side = Attribute("This TranslationSide")
     other_side_traits = Reference(
-        Interface, title=u"Traits for other side.", required=True,
+        Interface, title="Traits for other side.", required=True,
         readonly=True)
     flag_name = TextLine(
-        title=u"The TranslationMessage flag for this side",
+        title="The TranslationMessage flag for this side",
         required=True, readonly=True)
     displayname = TextLine(
-        title=u"Display name for this side", required=True, readonly=True)
+        title="Display name for this side", required=True, readonly=True)
 
     def getCurrentMessage(potemplate, potmsgset, language):
         """Find the current message on this side, if any."""
diff --git a/lib/lp/translations/interfaces/translationcommonformat.py b/lib/lp/translations/interfaces/translationcommonformat.py
index 3bd70c0..1234078 100644
--- a/lib/lp/translations/interfaces/translationcommonformat.py
+++ b/lib/lp/translations/interfaces/translationcommonformat.py
@@ -38,42 +38,42 @@ class ITranslationHeaderData(Interface):
     """Translation header interface."""
 
     is_fuzzy = Bool(
-        title=u'A flag indicating whether the header needs to be edited',
+        title='A flag indicating whether the header needs to be edited',
         required=True, readonly=True)
 
     template_creation_date = Datetime(
-        title=u'When was created the template used in this file.',
+        title='When was created the template used in this file.',
         required=True, readonly=True)
 
     translation_revision_date = Datetime(
-        title=u'When the translation resource was last revised or None.',
+        title='When the translation resource was last revised or None.',
         required=True)
 
     language_team = TextLine(
-        title=u'The language team in charge of this translation.',
+        title='The language team in charge of this translation.',
         required=True, readonly=True)
 
     has_plural_forms = Bool(
-        title=u'Whether this file contains plural forms.', required=True)
+        title='Whether this file contains plural forms.', required=True)
 
     number_plural_forms = Int(
-        title=u'Number of plural forms.', required=True)
+        title='Number of plural forms.', required=True)
 
     plural_form_expression = TextLine(
-        title=u'The plural form expression defined in this file or None.',
+        title='The plural form expression defined in this file or None.',
         required=True)
 
     charset = TextLine(
-        title=u'Charset used to encode the content in its native form.',
+        title='Charset used to encode the content in its native form.',
         required=True)
 
     launchpad_export_date = Datetime(
-        title=u'When this file was last exported from Launchpad or None.',
+        title='When this file was last exported from Launchpad or None.',
         required=True)
 
     comment = Text(
-        title=u'Header comment',
-        description=u'''
+        title='Header comment',
+        description='''
             It usually has copyright information and list of contributors.
             ''',
         required=True)
@@ -108,88 +108,88 @@ class ITranslationMessageData(Interface):
     """Translation message interface."""
 
     context = Text(
-        title=u'The context of the message.',
+        title='The context of the message.',
         required=True, readonly=True)
 
     msgid_singular = Text(
-        title=u'The singular msgid of the message.', required=True,
+        title='The singular msgid of the message.', required=True,
         readonly=True)
 
     singular_text = Text(
         title=(
-            u'The message singular text. Usually matches msgid_singular.'),
+            'The message singular text. Usually matches msgid_singular.'),
             required=False, readonly=True)
 
     msgid_plural = Text(
-        title=u'The plural msgid of the message or None.',
+        title='The plural msgid of the message or None.',
         required=True, readonly=True)
 
     plural_text = Text(
         title=(
-            u'The message plural text. Usually matches msgid_plural.'),
+            'The message plural text. Usually matches msgid_plural.'),
             required=False, readonly=True)
 
     translations = List(
-        title=u'The translations of the message.', required=True,
+        title='The translations of the message.', required=True,
         readonly=True)
 
     comment = Text(
-        title=u'Comments added by a translator.', required=True,
+        title='Comments added by a translator.', required=True,
         readonly=True)
 
     source_comment = Text(
-        title=u'Comments added by the developer to help translators.',
+        title='Comments added by the developer to help translators.',
         required=True, readonly=True)
 
     file_references = Text(
-        title=u'File references from where this message was extracted."',
+        title='File references from where this message was extracted."',
         required=True, readonly=True)
 
     flags = Set(
-        title=u'Message flags needed to validate its translation.',
+        title='Message flags needed to validate its translation.',
         required=True, readonly=True)
 
     is_obsolete = Bool(
-        title=u"Is this message obsolete?", required=True, readonly=True)
+        title="Is this message obsolete?", required=True, readonly=True)
 
 
 class ITranslationFileData(Interface):
     """Parsed translation template file interface."""
     format = Choice(
-        title=u"This file's translation file format.", required=True,
+        title="This file's translation file format.", required=True,
         vocabulary=TranslationFileFormat)
 
     header = Object(
-        title=u'An `ITranslationHeaderData` for the parsed file.',
+        title='An `ITranslationHeaderData` for the parsed file.',
         required=True, schema=ITranslationHeaderData)
 
     messages = List(
-        title=u'ITranslationMessageData objects included in the parsed file.',
+        title='ITranslationMessageData objects included in the parsed file.',
         required=True, readonly=True)
 
     path = TextLine(
-        title=u'The path directory where this file is stored.',
+        title='The path directory where this file is stored.',
         required=True, readonly=True)
 
     translation_domain = TextLine(
-        title=u'Translation domain used for this translation file',
-        description=u'''
+        title='Translation domain used for this translation file',
+        description='''
             It would be used to find its content on the file system, when
             its associated application is executed.
             ''',
         required=True, readonly=True)
 
     is_template = Bool(
-        title=u"Is this entry a translation template?", required=True,
+        title="Is this entry a translation template?", required=True,
         readonly=True)
 
     language_code = TextLine(
-        title=u'Language iso code for this translation file',
-        description=u'''
+        title='Language iso code for this translation file',
+        description='''
             Language iso code for this translation file or None either if it's
             unknown or is_template flag is set.
             ''',
         required=True, readonly=True)
 
     syntax_warnings = Set(
-        title=u"Syntax warnings", required=False, readonly=True)
+        title="Syntax warnings", required=False, readonly=True)
diff --git a/lib/lp/translations/interfaces/translationimporter.py b/lib/lp/translations/interfaces/translationimporter.py
index b24a0c7..c0c5935 100644
--- a/lib/lp/translations/interfaces/translationimporter.py
+++ b/lib/lp/translations/interfaces/translationimporter.py
@@ -13,7 +13,6 @@ __all__ = [
     'TranslationFormatInvalidInputError',
     ]
 
-import six
 from zope.interface import Interface
 from zope.schema import (
     Bool,
@@ -82,10 +81,9 @@ class TranslationFormatBaseError(TranslationImportExportBaseException):
         else:
             text = default_message
 
-        return u"%s%s" % (location_prefix, text)
+        return "%s%s" % (location_prefix, text)
 
 
-@six.python_2_unicode_compatible
 class TranslationFormatSyntaxError(TranslationFormatBaseError):
     """A syntax error occurred while parsing a translation file."""
 
@@ -93,7 +91,6 @@ class TranslationFormatSyntaxError(TranslationFormatBaseError):
         return self.represent("Unknown syntax error")
 
 
-@six.python_2_unicode_compatible
 class TranslationFormatInvalidInputError(TranslationFormatBaseError):
     """Some fields in the parsed file contain bad content."""
 
@@ -105,14 +102,14 @@ class ITranslationImporter(Interface):
     """Importer of translation files."""
 
     supported_file_extensions = List(
-        title=u'List of file extensions we have imports for.',
+        title='List of file extensions we have imports for.',
         required=True, readonly=True)
 
     # Filename suffixes that identify templates.  These do not have to be
     # CP/M-style "filename extensions" separated from the base file name by a
     # dot; any suffix will do.
     template_suffixes = TextLine(
-        title=u'Filename endings that identify templates.', required=True,
+        title='Filename endings that identify templates.', required=True,
         readonly=True)
 
     def isTemplateName(path):
@@ -193,8 +190,8 @@ class ITranslationFormatImporter(Interface):
         """
 
     priority = Int(
-        title=u'Priority among importers for the same file extension.',
-        description=u'''
+        title='Priority among importers for the same file extension.',
+        description='''
             Priority an `ITranslationFormatImporter` has if there are
             multiple importers for the same file extension.
 
@@ -206,16 +203,16 @@ class ITranslationFormatImporter(Interface):
         )
 
     content_type = TextLine(
-        title=u'Content type string for this file format.',
+        title='Content type string for this file format.',
         required=True, readonly=True)
 
     file_extensions = List(
-        title=u'File extensions handable by this importer.',
+        title='File extensions handable by this importer.',
         required=True, readonly=True)
 
     uses_source_string_msgids = Bool(
-        title=u'A flag indicating whether uses source string as the id',
-        description=u'''
+        title='A flag indicating whether uses source string as the id',
+        description='''
             A flag indicating whether this file format importer uses source
             string msgids as the English strings.
             ''',
diff --git a/lib/lp/translations/interfaces/translationmessage.py b/lib/lp/translations/interfaces/translationmessage.py
index b4a179e..6a10ea6 100644
--- a/lib/lp/translations/interfaces/translationmessage.py
+++ b/lib/lp/translations/interfaces/translationmessage.py
@@ -322,7 +322,7 @@ class ITranslationMessageSuggestions(Interface):
                       "indicating where it came from.")
     submissions = Attribute("An iterable of submissions.")
     user_is_official_translator = Bool(
-        title=(u'Whether the user is an official translator.'),
+        title=('Whether the user is an official translator.'),
         required=True)
 
 
diff --git a/lib/lp/translations/interfaces/vpoexport.py b/lib/lp/translations/interfaces/vpoexport.py
index ae7e008..35ef9d9 100644
--- a/lib/lp/translations/interfaces/vpoexport.py
+++ b/lib/lp/translations/interfaces/vpoexport.py
@@ -50,65 +50,65 @@ class IVPOExport(Interface):
     """Shorthand of translation messages for efficient exports."""
 
     pofile = Object(
-        title=u"Translation file",
+        title="Translation file",
         required=True, readonly=True, schema=IPOFile)
 
     diverged = Text(
-        title=u"Message divergence.",
-        description=u"A POTemplate this is a divergence for, or None.",
+        title="Message divergence.",
+        description="A POTemplate this is a divergence for, or None.",
         required=False, readonly=True)
 
     potmsgset = Object(
-        title=u"See `IPOTMsgSet`.",
+        title="See `IPOTMsgSet`.",
         required=True, readonly=True, schema=IPOTMsgSet)
 
     sequence = Int(
-        title=u"Message sequence number",
-        description=u"As in IPOTMsgSet.",
+        title="Message sequence number",
+        description="As in IPOTMsgSet.",
         required=True, readonly=True)
 
     comment = Text(
-        title=u"Comment for translated message",
-        description=u"Same as IPOTMsgSet.commenttext.",
+        title="Comment for translated message",
+        description="Same as IPOTMsgSet.commenttext.",
         required=False, readonly=True)
 
     source_comment = Text(
-        title=u"Comment for original message",
-        description=u"Same as IPOTMsgSet.sourcecomment.",
+        title="Comment for original message",
+        description="Same as IPOTMsgSet.sourcecomment.",
         required=False, readonly=True)
 
     file_references = Text(
-        title=u"Message's source location",
-        description=u"Same as IPOTMsgSet.filereferences.",
+        title="Message's source location",
+        description="Same as IPOTMsgSet.filereferences.",
         required=False, readonly=True)
 
     flags_comment = Text(
-        title=u"Message flags",
-        description=u"Same as IPOTMsgSet.flagscomment.",
+        title="Message flags",
+        description="Same as IPOTMsgSet.flagscomment.",
         required=False, readonly=True)
 
     context = Text(
-        title=u"Message context",
-        description=u"As in IPOTMsgSet.", readonly=True, required=False)
+        title="Message context",
+        description="As in IPOTMsgSet.", readonly=True, required=False)
 
     msgid_singular = Text(
-        title=u"Message identifier (singular)",
-        description=u"See IPOMsgID.pomsgid.",
+        title="Message identifier (singular)",
+        description="See IPOMsgID.pomsgid.",
         required=True, readonly=True)
 
     msgid_plural = Text(
-        title=u"Message identifier (plural)",
-        description=u"See IPOMsgID.pomsgid.",
+        title="Message identifier (plural)",
+        description="See IPOMsgID.pomsgid.",
         required=False, readonly=True)
 
     is_current_ubuntu = Bool(
         title=_("Whether this message is currently used in Launchpad"),
-        description=u"As in ITranslationMessage.",
+        description="As in ITranslationMessage.",
         readonly=True, required=True)
 
     is_current_upstream = Bool(
         title=_("Whether this message was imported"),
-        description=u"As in ITranslationMessage.",
+        description="As in ITranslationMessage.",
         readonly=True, required=True)
 
     assert TranslationConstants.MAX_PLURAL_FORMS == 6, (
@@ -116,31 +116,31 @@ class IVPOExport(Interface):
         % TranslationConstants.MAX_PLURAL_FORMS)
 
     translation0 = Text(
-        title=u"Translation in plural form 0",
-        description=u"As in ITranslationMessage.",
+        title="Translation in plural form 0",
+        description="As in ITranslationMessage.",
         readonly=True, required=False)
 
     translation1 = Text(
-        title=u"Translation in plural form 1",
-        description=u"As in ITranslationMessage.",
+        title="Translation in plural form 1",
+        description="As in ITranslationMessage.",
         readonly=True, required=False)
 
     translation2 = Text(
-        title=u"Translation in plural form 2",
-        description=u"As in ITranslationMessage.",
+        title="Translation in plural form 2",
+        description="As in ITranslationMessage.",
         readonly=True, required=False)
 
     translation3 = Text(
-        title=u"Translation in plural form 3",
-        description=u"As in ITranslationMessage.",
+        title="Translation in plural form 3",
+        description="As in ITranslationMessage.",
         readonly=True, required=False)
 
     translation4 = Text(
-        title=u"Translation in plural form 4",
-        description=u"As in ITranslationMessage.",
+        title="Translation in plural form 4",
+        description="As in ITranslationMessage.",
         readonly=True, required=False)
 
     translation5 = Text(
-        title=u"Translation in plural form 5",
-        description=u"As in ITranslationMessage.",
+        title="Translation in plural form 5",
+        description="As in ITranslationMessage.",
         readonly=True, required=False)
diff --git a/lib/lp/translations/interfaces/vpotexport.py b/lib/lp/translations/interfaces/vpotexport.py
index c657dc8..6d41520 100644
--- a/lib/lp/translations/interfaces/vpotexport.py
+++ b/lib/lp/translations/interfaces/vpotexport.py
@@ -20,45 +20,45 @@ class IVPOTExport(Interface):
     """Database view for efficient POT exports."""
 
     potemplate = Object(
-        title=u"See IPOTemplate",
+        title="See IPOTemplate",
         required=True, readonly=True, schema=IPOTemplate)
 
     template_header = Text(
-        title=u"See IPOTemplate.header",
+        title="See IPOTemplate.header",
         required=True, readonly=True)
 
     potmsgset = Object(
-        title=u"See `IPOTMsgSet`.",
+        title="See `IPOTMsgSet`.",
         required=True, readonly=True, schema=IPOTMsgSet)
 
     sequence = Int(
-        title=u"See `IPOTMsgSet`.sequence",
+        title="See `IPOTMsgSet`.sequence",
         required=False, readonly=True)
 
     comment = Text(
-        title=u"See `IPOTMsgSet`.commenttext",
+        title="See `IPOTMsgSet`.commenttext",
         required=False, readonly=True)
 
     source_comment = Text(
-        title=u"See `IPOTMsgSet`.sourcecomment",
+        title="See `IPOTMsgSet`.sourcecomment",
         required=False, readonly=True)
 
     file_references = Text(
-        title=u"See `IPOTMsgSet.filereferences`",
+        title="See `IPOTMsgSet.filereferences`",
         required=False, readonly=True)
 
     flags_comment = Text(
-        title=u"See `IPOTMsgSet`.flagscomment",
+        title="See `IPOTMsgSet`.flagscomment",
         required=False, readonly=True)
 
     context = Text(
-        title=u"See `IPOTMsgSet`.context",
+        title="See `IPOTMsgSet`.context",
         required=False, readonly=True)
 
     msgid_singular = Text(
-        title=u"See `IPOMsgID`.pomsgid",
+        title="See `IPOMsgID`.pomsgid",
         required=True, readonly=True)
 
     msgid_plural = Text(
-        title=u"See `IPOMsgID`.pomsgid",
+        title="See `IPOMsgID`.pomsgid",
         required=False, readonly=True)
diff --git a/lib/lp/translations/model/approver.py b/lib/lp/translations/model/approver.py
index 158db49..edbe1f1 100644
--- a/lib/lp/translations/model/approver.py
+++ b/lib/lp/translations/model/approver.py
@@ -32,7 +32,7 @@ def get_product_name(productseries):
         return productseries.product.name
 
 
-class TranslationNullApprover(object):
+class TranslationNullApprover:
     """Does not approve any files."""
 
     def __init__(self, *args, **kwargs):
@@ -43,7 +43,7 @@ class TranslationNullApprover(object):
         return entry
 
 
-class TranslationBranchApprover(object):
+class TranslationBranchApprover:
     """Automatic approval of template files uploaded from bzr branches."""
 
     def __init__(self, files, productseries=None,
@@ -161,7 +161,7 @@ class TranslationBranchApprover(object):
         return entry
 
 
-class TranslationBuildApprover(object):
+class TranslationBuildApprover:
     """Automatic approval of automatically build translation templates."""
 
     def __init__(
diff --git a/lib/lp/translations/model/customlanguagecode.py b/lib/lp/translations/model/customlanguagecode.py
index 8dcdbc4..ab69f4c 100644
--- a/lib/lp/translations/model/customlanguagecode.py
+++ b/lib/lp/translations/model/customlanguagecode.py
@@ -49,7 +49,7 @@ class CustomLanguageCode(StormBase):
     language = Reference(language_id, 'Language.id')
 
     def __init__(self, translation_target, language_code, language=None):
-        super(CustomLanguageCode, self).__init__()
+        super().__init__()
         self.product = None
         self.distribution = None
         self.sourcepackagename = None
diff --git a/lib/lp/translations/model/distroserieslanguage.py b/lib/lp/translations/model/distroserieslanguage.py
index 2fc7de1..c25bce0 100644
--- a/lib/lp/translations/model/distroserieslanguage.py
+++ b/lib/lp/translations/model/distroserieslanguage.py
@@ -72,7 +72,7 @@ class DistroSeriesLanguage(StormBase, RosettaStats):
         name='dateupdated', tzinfo=pytz.UTC, default=DEFAULT)
 
     def __init__(self, distroseries, language):
-        super(DistroSeriesLanguage, self).__init__()
+        super().__init__()
         self.distroseries = distroseries
         self.language = language
 
@@ -171,7 +171,7 @@ class DummyDistroSeriesLanguage(RosettaStats):
         assert 'en' != language.code, (
             'English is not a translatable language.')
 
-        super(DummyDistroSeriesLanguage, self).__init__()
+        super().__init__()
 
         self.id = None
         self.language = language
diff --git a/lib/lp/translations/model/languagepack.py b/lib/lp/translations/model/languagepack.py
index 68f0709..f06a112 100644
--- a/lib/lp/translations/model/languagepack.py
+++ b/lib/lp/translations/model/languagepack.py
@@ -49,7 +49,7 @@ class LanguagePack(StormBase):
     updates = Reference(updates_id, 'LanguagePack.id')
 
     def __init__(self, file, date_exported, distroseries, type, updates=None):
-        super(LanguagePack, self).__init__()
+        super().__init__()
         self.file = file
         self.date_exported = date_exported
         self.distroseries = distroseries
diff --git a/lib/lp/translations/model/pofile.py b/lib/lp/translations/model/pofile.py
index 47d9d0e..a5e8162 100644
--- a/lib/lp/translations/model/pofile.py
+++ b/lib/lp/translations/model/pofile.py
@@ -14,7 +14,6 @@ __all__ = [
 import datetime
 
 import pytz
-import six
 from storm.expr import (
     And,
     Cast,
@@ -198,8 +197,8 @@ class POFileMixIn(RosettaStats):
                             distinct=True)),
                         Like(
                             POTranslation.translation,
-                            u"%" + text.translate(like_escape) + u"%",
-                            u"!", case_sensitive=False))))))
+                            "%" + text.translate(like_escape) + "%",
+                            "!", case_sensitive=False))))))
 
     def _getTemplateSearchQuery(self, text):
         """Query for finding `text` in msgids of this POFile.
@@ -239,8 +238,8 @@ class POFileMixIn(RosettaStats):
                                     TranslationTemplateItem.sequence > 0))),
                             Like(
                                 POMsgID.msgid,
-                                u"%" + text.translate(like_escape) + u"%",
-                                u"!", case_sensitive=False))))))
+                                "%" + text.translate(like_escape) + "%",
+                                "!", case_sensitive=False))))))
 
         return Union(
             select_potmsgsets("msgid_singular"),
@@ -435,8 +434,8 @@ class POFile(SQLBase, POFileMixIn):
 
     def prepareTranslationCredits(self, potmsgset):
         """See `IPOFile`."""
-        LP_CREDIT_HEADER = u'Launchpad Contributions:'
-        SPACE = u' '
+        LP_CREDIT_HEADER = 'Launchpad Contributions:'
+        SPACE = ' '
         credits_type = potmsgset.translation_credits_type
         assert credits_type != TranslationCreditsType.NOT_CREDITS, (
             "Calling prepareTranslationCredits on a message with "
@@ -457,7 +456,7 @@ class POFile(SQLBase, POFileMixIn):
 
             # Add two empty email fields to make formatting nicer.
             # See bug #133817 for details.
-            emails.extend([u'', u''])
+            emails.extend(['', ''])
 
             for contributor in self.contributors:
                 preferred_email = contributor.preferredemail
@@ -466,12 +465,12 @@ class POFile(SQLBase, POFileMixIn):
                     emails.append('')
                 else:
                     emails.append(preferred_email.email)
-            return u','.join(emails)
+            return ','.join(emails)
         elif credits_type == TranslationCreditsType.KDE_NAMES:
             names = []
 
             if text is not None:
-                if text == u'':
+                if text == '':
                     text = SPACE
                 names.append(text)
             # Add an empty name as a separator, and 'Launchpad
@@ -480,18 +479,18 @@ class POFile(SQLBase, POFileMixIn):
             names.extend([
                 contributor.displayname
                 for contributor in self.contributors])
-            return u','.join(names)
+            return ','.join(names)
         elif credits_type == TranslationCreditsType.GNOME:
             if len(list(self.contributors)):
                 if text is None:
-                    text = u''
+                    text = ''
                 else:
                     # Strip existing Launchpad contribution lists.
                     header_index = text.find(LP_CREDIT_HEADER)
                     if header_index != -1:
                         text = text[:header_index]
                     else:
-                        text += u'\n\n'
+                        text += '\n\n'
 
                 text += LP_CREDIT_HEADER
                 for contributor in self.contributors:
@@ -640,7 +639,7 @@ class POFile(SQLBase, POFileMixIn):
                 getattr(Shared, flag_name),
                 Shared.potemplateID == None))
 
-        beginning_of_time = Cast(u'1970-01-01 00:00:00', 'timestamp')
+        beginning_of_time = Cast('1970-01-01 00:00:00', 'timestamp')
         clauses.append(
             TranslationMessage.date_created >
                 Coalesce(
@@ -971,7 +970,7 @@ class POFile(SQLBase, POFileMixIn):
             template_mail = 'poimport-not-exported-from-rosetta.txt'
             import_rejected = True
             entry_to_import.setErrorOutput(
-                u"File was not exported from Launchpad.")
+                "File was not exported from Launchpad.")
         except (MixedNewlineMarkersError, TranslationFormatSyntaxError,
                 TranslationFormatInvalidInputError,
                 UnicodeDecodeError) as exception:
@@ -985,7 +984,7 @@ class POFile(SQLBase, POFileMixIn):
             else:
                 template_mail = 'poimport-syntax-error.txt'
             import_rejected = True
-            error_text = six.text_type(exception)
+            error_text = str(exception)
             entry_to_import.setErrorOutput(error_text)
             needs_notification_for_imported = True
         except OutdatedTranslationError as exception:
@@ -995,15 +994,15 @@ class POFile(SQLBase, POFileMixIn):
                 logger.info('Got an old version for %s' % self.title)
             template_mail = 'poimport-got-old-version.txt'
             import_rejected = True
-            error_text = six.text_type(exception)
+            error_text = str(exception)
             entry_to_import.setErrorOutput(
-                u"Outdated translation.  " + error_text)
+                "Outdated translation.  " + error_text)
         except TooManyPluralFormsError:
             if logger:
                 logger.warning("Too many plural forms.")
             template_mail = 'poimport-too-many-plural-forms.txt'
             import_rejected = True
-            entry_to_import.setErrorOutput(u"Too many plural forms.")
+            entry_to_import.setErrorOutput("Too many plural forms.")
         else:
             # The import succeeded.  There may still be non-fatal errors
             # or warnings for individual messages (kept as a list in
@@ -1037,7 +1036,7 @@ class POFile(SQLBase, POFileMixIn):
             data = self._prepare_pomessage_error_message(errors, replacements)
             subject, template_mail, errorsdetails = data
             entry_to_import.setErrorOutput(
-                u"Imported, but with errors:\n" + errorsdetails)
+                "Imported, but with errors:\n" + errorsdetails)
         else:
             # The import was successful.
             template_mail = 'poimport-confirmation.txt'
@@ -1252,7 +1251,7 @@ class DummyPOFile(POFileMixIn):
         # privileges.
         self.owner = owner
 
-        self.path = u'unknown'
+        self.path = 'unknown'
         self.datecreated = datetime.datetime.now(UTC)
         self.last_touched_pomsgset = None
         self.contributors = []
diff --git a/lib/lp/translations/model/pofilestatsjob.py b/lib/lp/translations/model/pofilestatsjob.py
index 844061f..935a335 100644
--- a/lib/lp/translations/model/pofilestatsjob.py
+++ b/lib/lp/translations/model/pofilestatsjob.py
@@ -57,7 +57,7 @@ class POFileStatsJob(StormBase, BaseRunnableJob):
     def __init__(self, pofile):
         self.job = Job()
         self.pofile = pofile
-        super(POFileStatsJob, self).__init__()
+        super().__init__()
 
     def getOperationDescription(self):
         """See `IRunnableJob`."""
diff --git a/lib/lp/translations/model/pomsgid.py b/lib/lp/translations/model/pomsgid.py
index 1d99df0..85bcd87 100644
--- a/lib/lp/translations/model/pomsgid.py
+++ b/lib/lp/translations/model/pomsgid.py
@@ -26,7 +26,7 @@ class POMsgID(StormBase):
     msgid = Unicode(name='msgid', allow_none=False)
 
     def __init__(self, msgid):
-        super(POMsgID, self).__init__()
+        super().__init__()
         self.msgid = msgid
 
     @classmethod
diff --git a/lib/lp/translations/model/potemplate.py b/lib/lp/translations/model/potemplate.py
index 8b82150..ccd6457 100644
--- a/lib/lp/translations/model/potemplate.py
+++ b/lib/lp/translations/model/potemplate.py
@@ -18,7 +18,6 @@ import operator
 import os
 
 from psycopg2.extensions import TransactionRollbackError
-import six
 from storm.expr import (
     And,
     Desc,
@@ -261,7 +260,7 @@ class POTemplate(SQLBase, RosettaStats):
             return result
 
     def __storm_invalidated__(self):
-        super(POTemplate, self).__storm_invalidated__()
+        super().__storm_invalidated__()
         self.clearPOFileCache()
         self._uses_english_msgids = None
 
@@ -294,8 +293,7 @@ class POTemplate(SQLBase, RosettaStats):
 
     def __iter__(self):
         """See `IPOTemplate`."""
-        for potmsgset in self.getPOTMsgSets():
-            yield potmsgset
+        yield from self.getPOTMsgSets()
 
     def __getitem__(self, key):
         """See `IPOTemplate`."""
@@ -537,7 +535,7 @@ class POTemplate(SQLBase, RosettaStats):
         return Store.of(self).find(
             Language,
             POFile.languageID == Language.id,
-            Language.code != u'en',
+            Language.code != 'en',
             POFile.potemplateID == self.id).config(distinct=True)
 
     def getPOFileByPath(self, path):
@@ -944,7 +942,7 @@ class POTemplate(SQLBase, RosettaStats):
                 template_mail = 'poimport-syntax-error.txt'
             entry_to_import.setStatus(RosettaImportStatus.FAILED,
                                       rosetta_experts)
-            error_text = six.text_type(exception)
+            error_text = str(exception)
             entry_to_import.setErrorOutput(error_text)
         else:
             error_text = None
@@ -1003,7 +1001,7 @@ class POTemplate(SQLBase, RosettaStats):
                     if logger:
                         logger.warning(
                             "Statistics update failed: %s" %
-                            six.text_type(error))
+                            str(error))
 
         if template_mail is not None:
             template = get_email_template(
@@ -1131,8 +1129,7 @@ class POTemplateSubset:
 
     def __iter__(self):
         """See `IPOTemplateSubset`."""
-        for potemplate in self._build_query():
-            yield potemplate
+        yield from self._build_query()
 
     def __len__(self):
         """See `IPOTemplateSubset`."""
@@ -1265,7 +1262,7 @@ class POTemplateSubset:
         result = self._build_query(
             Or(
                 POTemplate.path == filename,
-                POTemplate.path.endswith(u'/%s' % filename)),
+                POTemplate.path.endswith('/%s' % filename)),
             ordered=False)
         candidates = list(result.config(limit=2))
 
@@ -1281,8 +1278,7 @@ class POTemplateSet:
 
     def __iter__(self):
         """See `IPOTemplateSet`."""
-        for potemplate in IStore(POTemplate).find(POTemplate):
-            yield potemplate
+        yield from IStore(POTemplate).find(POTemplate)
 
     def getAllByName(self, name):
         """See `IPOTemplateSet`."""
@@ -1413,7 +1409,7 @@ class POTemplateSet:
 
 
 @implementer(IPOTemplateSharingSubset)
-class POTemplateSharingSubset(object):
+class POTemplateSharingSubset:
 
     distribution = None
     sourcepackagename = None
@@ -1551,7 +1547,7 @@ class POTemplateSharingSubset(object):
                 equivalents[key] = []
             equivalents[key].append(template)
 
-        for equivalence_list in six.itervalues(equivalents):
+        for equivalence_list in equivalents.values():
             # Sort potemplates from "most representative" to "least
             # representative."
             equivalence_list.sort(key=POTemplate.sharingKey, reverse=True)
diff --git a/lib/lp/translations/model/potmsgset.py b/lib/lp/translations/model/potmsgset.py
index 6e26c90..9435564 100644
--- a/lib/lp/translations/model/potmsgset.py
+++ b/lib/lp/translations/model/potmsgset.py
@@ -13,7 +13,6 @@ from collections import (
 import logging
 import re
 
-import six
 from storm.expr import (
     And,
     Coalesce,
@@ -91,26 +90,26 @@ from lp.translations.utilities.validate import validate_translation
 # contexts and type.
 credits_message_info = {
     # Regular gettext credits messages.
-    u'translation-credits': (None, TranslationCreditsType.GNOME),
-    u'translator-credits': (None, TranslationCreditsType.GNOME),
-    u'translator_credits': (None, TranslationCreditsType.GNOME),
+    'translation-credits': (None, TranslationCreditsType.GNOME),
+    'translator-credits': (None, TranslationCreditsType.GNOME),
+    'translator_credits': (None, TranslationCreditsType.GNOME),
 
     # KDE credits messages.
-    u'Your emails':
-        (u'EMAIL OF TRANSLATORS', TranslationCreditsType.KDE_EMAILS),
-    u'Your names':
-        (u'NAME OF TRANSLATORS', TranslationCreditsType.KDE_NAMES),
+    'Your emails':
+        ('EMAIL OF TRANSLATORS', TranslationCreditsType.KDE_EMAILS),
+    'Your names':
+        ('NAME OF TRANSLATORS', TranslationCreditsType.KDE_NAMES),
 
     # Old KDE credits messages.
-    u'_: EMAIL OF TRANSLATORS\nYour emails':
+    '_: EMAIL OF TRANSLATORS\nYour emails':
         (None, TranslationCreditsType.KDE_EMAILS),
-    u'_: NAME OF TRANSLATORS\nYour names':
+    '_: NAME OF TRANSLATORS\nYour names':
         (None, TranslationCreditsType.KDE_NAMES),
     }
 
 # String to be used as msgstr for translation credits messages.
-credits_message_str = (u'This is a dummy translation so that the '
-                       u'credits are counted as translated.')
+credits_message_str = ('This is a dummy translation so that the '
+                       'credits are counted as translated.')
 
 
 # Marker for "no incumbent message found yet."
@@ -131,7 +130,7 @@ def dictify_translations(translations):
     # Filter out None values.
     return {
         form: translation
-        for form, translation in six.iteritems(translations)
+        for form, translation in translations.items()
         if translation is not None}
 
 
@@ -627,7 +626,7 @@ class POTMsgSet(SQLBase):
 
         forms = {
             'msgstr%d' % form: potranslation
-            for form, potranslation in six.iteritems(potranslations)}
+            for form, potranslation in potranslations.items()}
 
         if from_import:
             origin = RosettaTranslationOrigin.SCM
@@ -764,7 +763,7 @@ class POTMsgSet(SQLBase):
 
         translation_args = {
             'msgstr%d' % form: translation
-            for form, translation in six.iteritems(translations)}
+            for form, translation in translations.items()}
 
         return TranslationMessage(
             potmsgset=self,
diff --git a/lib/lp/translations/model/potranslation.py b/lib/lp/translations/model/potranslation.py
index 7ac0222..b342098 100644
--- a/lib/lp/translations/model/potranslation.py
+++ b/lib/lp/translations/model/potranslation.py
@@ -26,7 +26,7 @@ class POTranslation(StormBase):
     translation = Unicode(name='translation', allow_none=False)
 
     def __init__(self, translation):
-        super(POTranslation, self).__init__()
+        super().__init__()
         self.translation = translation
 
     @classmethod
diff --git a/lib/lp/translations/model/translatedlanguage.py b/lib/lp/translations/model/translatedlanguage.py
index 7c7606c..f86d944 100644
--- a/lib/lp/translations/model/translatedlanguage.py
+++ b/lib/lp/translations/model/translatedlanguage.py
@@ -24,7 +24,7 @@ from lp.translations.model.potemplate import POTemplate
 
 
 @implementer(IPOFilesByPOTemplates)
-class POFilesByPOTemplates(object):
+class POFilesByPOTemplates:
     """See `IPOFilesByPOTemplates`."""
 
     def __init__(self, templates_collection, language):
@@ -65,8 +65,7 @@ class POFilesByPOTemplates(object):
 
     def __iter__(self):
         resultset = self._getPOTemplatesAndPOFilesResultSet()
-        for pofile in self._getPOFilesForResultSet(resultset):
-            yield pofile
+        yield from self._getPOFilesForResultSet(resultset)
 
     def __len__(self):
         return self.templates_collection.select(POTemplate).count()
@@ -76,7 +75,7 @@ class POFilesByPOTemplates(object):
 
 
 @implementer(ITranslatedLanguage)
-class TranslatedLanguageMixin(object):
+class TranslatedLanguageMixin:
     """See `ITranslatedLanguage`."""
 
     language = None
diff --git a/lib/lp/translations/model/translationgroup.py b/lib/lp/translations/model/translationgroup.py
index a3e0f48..ab39ddf 100644
--- a/lib/lp/translations/model/translationgroup.py
+++ b/lib/lp/translations/model/translationgroup.py
@@ -262,11 +262,10 @@ class TranslationGroupSet:
         # group names from their respective celebrities.  For now,
         # just hard-code them so they show up at the top of the
         # listing of all translation groups.
-        for group in IStore(TranslationGroup).find(TranslationGroup).order_by(
-                Desc(TranslationGroup.name.is_in((
-                    'launchpad-translators', 'ubuntu-translators'))),
-                TranslationGroup.title):
-            yield group
+        yield from IStore(TranslationGroup).find(TranslationGroup).order_by(
+            Desc(TranslationGroup.name.is_in((
+                'launchpad-translators', 'ubuntu-translators'))),
+            TranslationGroup.title)
 
     def __getitem__(self, name):
         """See ITranslationGroupSet."""
diff --git a/lib/lp/translations/model/translationimportqueue.py b/lib/lp/translations/model/translationimportqueue.py
index fac6387..39df58b 100644
--- a/lib/lp/translations/model/translationimportqueue.py
+++ b/lib/lp/translations/model/translationimportqueue.py
@@ -18,7 +18,6 @@ import tarfile
 from textwrap import dedent
 
 import pytz
-import six
 from storm.expr import (
     Alias,
     And,
@@ -1485,8 +1484,7 @@ class TranslationImportQueue:
         """
         now = datetime.datetime.now(pytz.UTC)
         deletion_clauses = []
-        for status, max_age in six.iteritems(
-                translation_import_queue_entry_age):
+        for status, max_age in translation_import_queue_entry_age.items():
             cutoff = now - max_age
             deletion_clauses.append(And(
                 TranslationImportQueueEntry.status == status,
@@ -1499,7 +1497,7 @@ class TranslationImportQueue:
         deletion_clauses.append(And(
             TranslationImportQueueEntry.distroseries_id != None,
             TranslationImportQueueEntry.date_status_changed < blocked_cutoff,
-            TranslationImportQueueEntry.path.like(u'%.po')))
+            TranslationImportQueueEntry.path.like('%.po')))
 
         entries = store.find(
             TranslationImportQueueEntry, Or(*deletion_clauses))
diff --git a/lib/lp/translations/model/translationpackagingjob.py b/lib/lp/translations/model/translationpackagingjob.py
index 2a1e530..fb783f6 100644
--- a/lib/lp/translations/model/translationpackagingjob.py
+++ b/lib/lp/translations/model/translationpackagingjob.py
@@ -73,7 +73,7 @@ class TranslationPackagingJob(TranslationSharingJobDerived, BaseRunnableJob):
         """See `IJobSource`."""
         clause = TranslationSharingJob.job_type.is_in(
             cls._translation_packaging_job_types)
-        return super(TranslationPackagingJob, cls).iterReady([clause])
+        return super().iterReady([clause])
 
 
 @implementer(IRunnableJob)
diff --git a/lib/lp/translations/model/translationsharingjob.py b/lib/lp/translations/model/translationsharingjob.py
index bd3b402..6124d16 100644
--- a/lib/lp/translations/model/translationsharingjob.py
+++ b/lib/lp/translations/model/translationsharingjob.py
@@ -14,7 +14,6 @@ from lazr.enum import (
     DBEnumeratedType,
     DBItem,
     )
-import six
 from storm.locals import (
     Int,
     Reference,
@@ -167,7 +166,7 @@ class TranslationSharingJobDerived(metaclass=EnumeratedSubclass):
             for.
         :param event: The event itself.
         """
-        for event_type, job_classes in six.iteritems(cls._event_types):
+        for event_type, job_classes in cls._event_types.items():
             if not event_type.providedBy(event):
                 continue
             for job_class in job_classes:
@@ -188,7 +187,7 @@ class TranslationSharingJobDerived(metaclass=EnumeratedSubclass):
             # Ignore changes to POTemplates that are neither renames,
             # nor moves to a different package/project.
             return
-        for event_type, job_classes in six.iteritems(cls._event_types):
+        for event_type, job_classes in cls._event_types.items():
             if not event_type.providedBy(event):
                 continue
             for job_class in job_classes:
diff --git a/lib/lp/translations/model/translationtemplatesbuild.py b/lib/lp/translations/model/translationtemplatesbuild.py
index a1448d5..8a23849 100644
--- a/lib/lp/translations/model/translationtemplatesbuild.py
+++ b/lib/lp/translations/model/translationtemplatesbuild.py
@@ -93,11 +93,11 @@ class TranslationTemplatesBuild(SpecificBuildFarmJobSourceMixin,
 
     @property
     def title(self):
-        return u'Translation template build for %s' % (
+        return 'Translation template build for %s' % (
             self.branch.displayname)
 
     def __init__(self, build_farm_job, branch, processor):
-        super(TranslationTemplatesBuild, self).__init__()
+        super().__init__()
         self.build_farm_job = build_farm_job
         self.branch = branch
         self.status = BuildStatus.NEEDSBUILD
diff --git a/lib/lp/translations/model/translationtemplatesbuildbehaviour.py b/lib/lp/translations/model/translationtemplatesbuildbehaviour.py
index f141c87..7ae20d0 100644
--- a/lib/lp/translations/model/translationtemplatesbuildbehaviour.py
+++ b/lib/lp/translations/model/translationtemplatesbuildbehaviour.py
@@ -68,8 +68,7 @@ class TranslationTemplatesBuildBehaviour(BuildFarmJobBehaviourBase):
         return PackagePublishingPocket.RELEASE
 
     def extraBuildArgs(self, logger=None):
-        args = super(TranslationTemplatesBuildBehaviour, self).extraBuildArgs(
-            logger=logger)
+        args = super().extraBuildArgs(logger=logger)
         args["branch_url"] = self.build.branch.composePublicURL()
         return args