← Back to team overview

launchpad-reviewers team mailing list archive

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

 

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

Commit message:
lp.translations: Apply "pyupgrade --py3-plus"

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/414182
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:pyupgrade-py3-translations-3 into launchpad:master.
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index 06f9be6..6c1e034 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -50,3 +50,5 @@ f3f15787ebabe305fbf3e3ae6c0fd8ca7dfb4465
 d61c2ad002c2997a132a1580ce6ee82bb03de11d
 # apply pyupgrade --py3-plus to lp.translations.{interfaces,model}
 afcfc15adcf3267d3fd07d7679df00231853c908
+# apply pyupgrade --py3-plus to lp.translations
+3f3ea0f7799093f93740d3a1db3a11965d0b25cb
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 14df1e9..a64bbd3 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -60,7 +60,7 @@ repos:
             |testing
             |testopenid
             |tests
-            |translations/(browser|interfaces|model)
+            |translations
           )/
 -   repo: https://github.com/PyCQA/isort
     rev: 5.9.2
diff --git a/lib/lp/translations/publisher.py b/lib/lp/translations/publisher.py
index a12b83e..7cb8311 100644
--- a/lib/lp/translations/publisher.py
+++ b/lib/lp/translations/publisher.py
@@ -42,8 +42,7 @@ class TranslationsBrowserRequest(LaunchpadBrowserRequest):
     """Instances of TranslationsBrowserRequest provide `TranslationsLayer`."""
 
     def __init__(self, body_instream, environ, response=None):
-        super(TranslationsBrowserRequest, self).__init__(
-            body_instream, environ, response)
+        super().__init__(body_instream, environ, response)
         # Many of the responses from Translations vary based on language.
         self.response.setHeader(
             'Vary', 'Cookie, Authorization, Accept-Language')
diff --git a/lib/lp/translations/scripts/gettext_check_messages.py b/lib/lp/translations/scripts/gettext_check_messages.py
index 8b5ed13..444b2db 100644
--- a/lib/lp/translations/scripts/gettext_check_messages.py
+++ b/lib/lp/translations/scripts/gettext_check_messages.py
@@ -8,7 +8,6 @@ from datetime import (
     timedelta,
     )
 
-import six
 from storm.locals import SQL
 from zope.security.proxy import removeSecurityProxy
 
@@ -103,7 +102,7 @@ class GettextCheckMessages(LaunchpadScript):
                 msgstrs, potmsgset.flags)
         except GettextValidationError as error:
             self._error_count += 1
-            return six.text_type(error)
+            return str(error)
 
         return None
 
diff --git a/lib/lp/translations/scripts/language_pack.py b/lib/lp/translations/scripts/language_pack.py
index 719dfe2..b9eefab 100644
--- a/lib/lp/translations/scripts/language_pack.py
+++ b/lib/lp/translations/scripts/language_pack.py
@@ -52,8 +52,7 @@ def iter_sourcepackage_translationdomain_mapping(series):
         ORDER BY SourcePackageName.name, POTemplate.translation_domain
         """ % sqlvalues(series))
 
-    for (sourcepackagename, translationdomain,) in cur.fetchall():
-        yield (sourcepackagename, translationdomain)
+    yield from cur.fetchall()
 
 
 def export(distroseries, component, update, force_utf8, logger):
diff --git a/lib/lp/translations/scripts/po_import.py b/lib/lp/translations/scripts/po_import.py
index 8b7d9b7..f30c8b8 100644
--- a/lib/lp/translations/scripts/po_import.py
+++ b/lib/lp/translations/scripts/po_import.py
@@ -44,7 +44,7 @@ class TranslationsImport(LaunchpadCronScript):
     failures = None
 
     def __init__(self, *args, **kwargs):
-        super(TranslationsImport, self).__init__(*args, **kwargs)
+        super().__init__(*args, **kwargs)
         self.failures = {}
 
     def _describeEntry(self, entry):
@@ -77,7 +77,7 @@ class TranslationsImport(LaunchpadCronScript):
         """Note that a queue entry is unusable in some way."""
         reason_text = (
             six.ensure_text(reason) if reason is bytes
-            else six.text_type(reason))
+            else str(reason))
         entry.setStatus(RosettaImportStatus.FAILED,
                         getUtility(ILaunchpadCelebrities).rosetta_experts)
         entry.setErrorOutput(reason_text)
@@ -209,5 +209,5 @@ class TranslationsImport(LaunchpadCronScript):
 
     def _reportFailures(self):
         """Bulk-report deferred failures as oopses."""
-        for reason, entries in six.iteritems(self.failures):
+        for reason, entries in self.failures.items():
             self._reportOops(reason, entries)
diff --git a/lib/lp/translations/scripts/remove_translations.py b/lib/lp/translations/scripts/remove_translations.py
index b763f01..a0fa0f9 100644
--- a/lib/lp/translations/scripts/remove_translations.py
+++ b/lib/lp/translations/scripts/remove_translations.py
@@ -15,7 +15,6 @@ from optparse import (
     OptionValueError,
     )
 
-import six
 from zope.component import getUtility
 
 from lp.registry.interfaces.person import IPersonSet
@@ -64,7 +63,7 @@ def get_id(identifier, lookup_function=None):
     """
     if identifier is None or identifier == '':
         return None
-    elif isinstance(identifier, six.string_types) and identifier == '':
+    elif isinstance(identifier, str) and identifier == '':
         return None
     elif isinstance(identifier, int):
         return identifier
diff --git a/lib/lp/translations/scripts/scrub_pofiletranslator.py b/lib/lp/translations/scripts/scrub_pofiletranslator.py
index 7094eba..605b822 100644
--- a/lib/lp/translations/scripts/scrub_pofiletranslator.py
+++ b/lib/lp/translations/scripts/scrub_pofiletranslator.py
@@ -258,7 +258,7 @@ class ScrubPOFileTranslator(TunableLoop):
     maximum_chunk_size = 500
 
     def __init__(self, *args, **kwargs):
-        super(ScrubPOFileTranslator, self).__init__(*args, **kwargs)
+        super().__init__(*args, **kwargs)
         self.pofile_ids = tuple(get_pofile_ids())
         self.next_offset = 0
 
diff --git a/lib/lp/translations/scripts/tests/test_cache_suggestive_templates.py b/lib/lp/translations/scripts/tests/test_cache_suggestive_templates.py
index 4c8111f..85ca47f 100644
--- a/lib/lp/translations/scripts/tests/test_cache_suggestive_templates.py
+++ b/lib/lp/translations/scripts/tests/test_cache_suggestive_templates.py
@@ -17,7 +17,7 @@ class TestSuggestivePOTemplatesCache(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestSuggestivePOTemplatesCache, self).setUp()
+        super().setUp()
         self.utility = getUtility(IPOTemplateSet)
 
     def _refreshCache(self):
diff --git a/lib/lp/translations/scripts/tests/test_migrate_current_flag.py b/lib/lp/translations/scripts/tests/test_migrate_current_flag.py
index 0dfa37e..b902800 100644
--- a/lib/lp/translations/scripts/tests/test_migrate_current_flag.py
+++ b/lib/lp/translations/scripts/tests/test_migrate_current_flag.py
@@ -21,7 +21,7 @@ class TestMigrateCurrentFlag(TestCaseWithFactory):
         # TranslationMessages) but it also needs to set up test conditions
         # which requires other privileges.
         switch_dbuser('postgres')
-        super(TestMigrateCurrentFlag, self).setUp(user='mark@xxxxxxxxxxx')
+        super().setUp(user='mark@xxxxxxxxxxx')
         self.migrate_process = MigrateCurrentFlagProcess(self.layer.txn)
 
     def test_getProductsWithTemplates_sampledata(self):
@@ -112,7 +112,7 @@ class TestUpdaterLoop(TestCaseWithFactory):
         # TranslationMessages) but it also needs to set up test conditions
         # which requires other privileges.
         switch_dbuser('postgres')
-        super(TestUpdaterLoop, self).setUp(user='mark@xxxxxxxxxxx')
+        super().setUp(user='mark@xxxxxxxxxxx')
         self.logger = logging.getLogger("migrate-current-flag")
         self.migrate_loop = TranslationMessageImportedFlagUpdater(
             self.layer.txn, self.logger, [])
diff --git a/lib/lp/translations/scripts/tests/test_remove_translations.py b/lib/lp/translations/scripts/tests/test_remove_translations.py
index d542c5c..3a71ca2 100644
--- a/lib/lp/translations/scripts/tests/test_remove_translations.py
+++ b/lib/lp/translations/scripts/tests/test_remove_translations.py
@@ -12,7 +12,6 @@ from optparse import (
     )
 from unittest import TestLoader
 
-import six
 from storm.store import Store
 from testtools.matchers import MatchesStructure
 from zope.component import getUtility
@@ -44,7 +43,7 @@ from lp.translations.scripts.remove_translations import (
 
 def make_script(args=None):
     """Create a `RemoveTranslations` script with given options."""
-    if isinstance(args, six.string_types):
+    if isinstance(args, str):
         args = [args]
     script = RemoveTranslations(
         'remove-translations-test', test_args=args, logger=DevNullLogger())
@@ -56,7 +55,7 @@ class TestRemoveTranslationsConstraints(TestCase):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestRemoveTranslationsConstraints, self).setUp()
+        super().setUp()
         # Acquire privileges to delete TranslationMessages.  We won't
         # actually do that here, but we'll go through all the motions.
         switch_dbuser('postgres')
@@ -156,7 +155,7 @@ class OptionChecker(OptionParser):
 
 def parse_opts(opts):
     """Simulate options being parsed by `LaunchpadScript`."""
-    if isinstance(opts, six.string_types):
+    if isinstance(opts, str):
         opts = [opts]
 
     parser = OptionChecker()
@@ -171,7 +170,7 @@ class TestRemoveTranslationsOptionsHandling(TestCase):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestRemoveTranslationsOptionsHandling, self).setUp()
+        super().setUp()
         self.factory = LaunchpadObjectFactory()
 
     def test_WithNativeArgs(self):
@@ -240,7 +239,7 @@ class TestRemoveTranslations(TestCase):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestRemoveTranslations, self).setUp()
+        super().setUp()
         # Acquire privileges to delete TranslationMessages.  That's not
         # something we normally do.  Actually we should test under
         # rosettaadmin, but that user does not have all the privileges
@@ -586,7 +585,7 @@ class TestRemoveTranslationsUnmasking(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestRemoveTranslationsUnmasking, self).setUp()
+        super().setUp()
         switch_dbuser('postgres')
 
         # Set up a template with a Laotian translation file.  There's
diff --git a/lib/lp/translations/scripts/tests/test_reupload_translations.py b/lib/lp/translations/scripts/tests/test_reupload_translations.py
index d8b43a7..c78a6d6 100644
--- a/lib/lp/translations/scripts/tests/test_reupload_translations.py
+++ b/lib/lp/translations/scripts/tests/test_reupload_translations.py
@@ -9,7 +9,6 @@ import io
 import re
 import tarfile
 
-import six
 import transaction
 from zope.security.proxy import removeSecurityProxy
 
@@ -60,7 +59,7 @@ def upload_tarball(translation_files):
     """
     buf = io.BytesIO()
     tarball = tarfile.open('', 'w:gz', buf)
-    for name, contents in six.iteritems(translation_files):
+    for name, contents in translation_files.items():
         pseudofile = io.BytesIO(contents)
         tarinfo = tarfile.TarInfo()
         tarinfo.name = name
@@ -92,7 +91,7 @@ def filter_paths(files_dict):
         applied to each file's path, and non-Ubuntu files left out.
     """
     filtered_dict = {}
-    for original_path, content in six.iteritems(files_dict):
+    for original_path, content in files_dict.items():
         new_path = _filter_ubuntu_translation_file(original_path)
         if new_path:
             filtered_dict[new_path] = content
@@ -105,7 +104,7 @@ class TestReuploadPackageTranslations(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestReuploadPackageTranslations, self).setUp()
+        super().setUp()
         sourcepackagename = self.factory.makeSourcePackageName()
         distroseries = self.factory.makeDistroSeries()
         self.sourcepackage = SourcePackage(sourcepackagename, distroseries)
@@ -175,7 +174,7 @@ class TestReuploadScript(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestReuploadScript, self).setUp()
+        super().setUp()
         self.distroseries = self.factory.makeDistroSeries()
         self.sourcepackagename1 = self.factory.makeSourcePackageName()
         self.sourcepackagename2 = self.factory.makeSourcePackageName()
diff --git a/lib/lp/translations/scripts/tests/test_translations_approval.py b/lib/lp/translations/scripts/tests/test_translations_approval.py
index fd4bd41..cbf6439 100644
--- a/lib/lp/translations/scripts/tests/test_translations_approval.py
+++ b/lib/lp/translations/scripts/tests/test_translations_approval.py
@@ -19,7 +19,7 @@ class TestTranslationsImportApproval(TestCaseWithFactory):
     layer = LaunchpadScriptLayer
 
     def setUp(self):
-        super(TestTranslationsImportApproval, self).setUp()
+        super().setUp()
         self.queue = TranslationImportQueue()
         self.script = ImportQueueGardener(
             'translations-import-queue-gardener',
diff --git a/lib/lp/translations/scripts/tests/test_translations_import.py b/lib/lp/translations/scripts/tests/test_translations_import.py
index ffc61fd..ce9fed9 100644
--- a/lib/lp/translations/scripts/tests/test_translations_import.py
+++ b/lib/lp/translations/scripts/tests/test_translations_import.py
@@ -33,7 +33,7 @@ class TestTranslationsImport(TestCaseWithFactory):
     layer = LaunchpadScriptLayer
 
     def setUp(self):
-        super(TestTranslationsImport, self).setUp()
+        super().setUp()
         self.queue = TranslationImportQueue()
         self.script = TranslationsImport('poimport', test_args=[])
         self.script.logger.setLevel(logging.FATAL)
diff --git a/lib/lp/translations/scripts/tests/test_translations_to_branch.py b/lib/lp/translations/scripts/tests/test_translations_to_branch.py
index 492b505..ae6c1c2 100644
--- a/lib/lp/translations/scripts/tests/test_translations_to_branch.py
+++ b/lib/lp/translations/scripts/tests/test_translations_to_branch.py
@@ -73,7 +73,7 @@ class TestExportTranslationsToBranch(TestCaseWithFactory):
             path='po/messages.pot')
         template = removeSecurityProxy(template)
         potmsgset = self.factory.makePOTMsgSet(
-            template, singular=u'Hello World', sequence=1)
+            template, singular='Hello World', sequence=1)
         pofile = self.factory.makePOFile(
             'nl', potemplate=template, owner=product.owner)
         self.factory.makeCurrentTranslationMessage(
@@ -126,7 +126,7 @@ class TestExportTranslationsToBranch(TestCaseWithFactory):
         missing_filenames = expected_filenames - branch_filenames
         self.assertEqual(set(), missing_filenames)
 
-        for filename, expected in six.iteritems(expected_contents):
+        for filename, expected in expected_contents.items():
             contents = branch_contents[filename].lstrip(b'\n')
             pattern = dedent(expected.lstrip('\n')).encode('UTF-8')
             if not re.match(pattern, contents, re.MULTILINE):
@@ -182,7 +182,7 @@ class TestExportTranslationsToBranch(TestCaseWithFactory):
         productseries = self.factory.makeProductSeries()
         exporter = ExportTranslationsToBranch(test_args=[])
         exporter.logger = BufferLogger()
-        boom = u'\u2639'
+        boom = '\u2639'
         exporter._exportToBranch = FakeMethod(failure=GruesomeException(boom))
 
         self.becomeDbUser('translationstobranch')
diff --git a/lib/lp/translations/tests/test_autoapproval.py b/lib/lp/translations/tests/test_autoapproval.py
index 925dc86..b778fac 100644
--- a/lib/lp/translations/tests/test_autoapproval.py
+++ b/lib/lp/translations/tests/test_autoapproval.py
@@ -54,7 +54,7 @@ from lp.translations.model.translationimportqueue import (
     )
 
 
-class GardenerDbUserMixin(object):
+class GardenerDbUserMixin:
     """Switch to the translations import queue gardener database role.
 
     Admittedly, this might be a little over-engineered but it looks good. ;)
@@ -78,7 +78,7 @@ class TestCustomLanguageCode(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestCustomLanguageCode, self).setUp()
+        super().setUp()
         self.product_codes = {}
         self.package_codes = {}
 
@@ -173,7 +173,7 @@ class TestGuessPOFileCustomLanguageCode(TestCaseWithFactory,
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestGuessPOFileCustomLanguageCode, self).setUp()
+        super().setUp()
         self.product = self.factory.makeProduct()
         self.series = self.factory.makeProductSeries(product=self.product)
         self.queue = TranslationImportQueue()
@@ -309,7 +309,7 @@ class TestTemplateGuess(TestCaseWithFactory, GardenerDbUserMixin):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestTemplateGuess, self).setUp()
+        super().setUp()
         self.useFixture(FakeLogger())
         self.templateset = POTemplateSet()
 
@@ -760,7 +760,7 @@ class TestKdePOFileGuess(TestCaseWithFactory, GardenerDbUserMixin):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestKdePOFileGuess, self).setUp()
+        super().setUp()
         self.queue = TranslationImportQueue()
 
         self.distroseries = self.factory.makeDistroSeries()
@@ -822,7 +822,7 @@ class TestGetPOFileFromLanguage(TestCaseWithFactory, GardenerDbUserMixin):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestGetPOFileFromLanguage, self).setUp()
+        super().setUp()
         self.queue = TranslationImportQueue()
 
     def test_get_pofile_from_language_feeds_enabled_template(self):
@@ -887,7 +887,7 @@ class TestCleanup(TestCaseWithFactory, GardenerDbUserMixin):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestCleanup, self).setUp()
+        super().setUp()
         self.queue = TranslationImportQueue()
         self.store = IMasterStore(TranslationImportQueueEntry)
 
@@ -1094,7 +1094,7 @@ class TestAutoApprovalNewPOFile(TestCaseWithFactory, GardenerDbUserMixin):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestAutoApprovalNewPOFile, self).setUp()
+        super().setUp()
         self.product = self.factory.makeProduct()
         self.queue = TranslationImportQueue()
         self.language = getUtility(ILanguageSet).getLanguageByCode('nl')
@@ -1151,7 +1151,7 @@ class TestAutoBlocking(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestAutoBlocking, self).setUp()
+        super().setUp()
         self.queue = TranslationImportQueue()
         # Our test queue operates on the master store instead of the
         # slave store so we don't have to synchronize stores.
diff --git a/lib/lp/translations/tests/test_clearcurrenttranslation.py b/lib/lp/translations/tests/test_clearcurrenttranslation.py
index cb345b0..f1b5de4 100644
--- a/lib/lp/translations/tests/test_clearcurrenttranslation.py
+++ b/lib/lp/translations/tests/test_clearcurrenttranslation.py
@@ -267,8 +267,7 @@ class TestClearCurrentTranslationUpstream(TestCaseWithFactory,
     makeOtherPOTemplate = ScenarioMixin.makeUbuntuTemplate
 
     def setUp(self):
-        super(TestClearCurrentTranslationUpstream, self).setUp(
-            'carlos@xxxxxxxxxxxxx')
+        super().setUp('carlos@xxxxxxxxxxxxx')
 
 
 class TestClearCurrentTranslationUbuntu(TestCaseWithFactory,
@@ -278,5 +277,4 @@ class TestClearCurrentTranslationUbuntu(TestCaseWithFactory,
     makeOtherPOTemplate = ScenarioMixin.makeUpstreamTemplate
 
     def setUp(self):
-        super(TestClearCurrentTranslationUbuntu, self).setUp(
-            'carlos@xxxxxxxxxxxxx')
+        super().setUp('carlos@xxxxxxxxxxxxx')
diff --git a/lib/lp/translations/tests/test_exportresult.py b/lib/lp/translations/tests/test_exportresult.py
index ccb7bdf..d8eb9be 100644
--- a/lib/lp/translations/tests/test_exportresult.py
+++ b/lib/lp/translations/tests/test_exportresult.py
@@ -35,7 +35,7 @@ class TestExportResult(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestExportResult, self).setUp()
+        super().setUp()
         # In development mode, the librarian is normally configured to
         # generate HTTP URLs.  Enable HTTPS URLs so that we can test that
         # ExportResult uses them.
diff --git a/lib/lp/translations/tests/test_hastranslationtemplates.py b/lib/lp/translations/tests/test_hastranslationtemplates.py
index c3a0777..4ba7347 100644
--- a/lib/lp/translations/tests/test_hastranslationtemplates.py
+++ b/lib/lp/translations/tests/test_hastranslationtemplates.py
@@ -21,7 +21,7 @@ class HasTranslationTemplatesTestMixin:
     def setUp(self):
         # Create a product with two series and a shared POTemplate
         # in different series ('devel' and 'stable').
-        super(HasTranslationTemplatesTestMixin, self).setUp()
+        super().setUp()
 
     def createTranslationTemplate(self, name=None, priority=0):
         """Attaches a template to appropriate container."""
@@ -296,7 +296,7 @@ class TestProductSeriesHasTranslationTemplates(
             sourcepackage=self.packaging.sourcepackage)
 
     def setUp(self):
-        super(TestProductSeriesHasTranslationTemplates, self).setUp()
+        super().setUp()
         self.container = self.factory.makeProductSeries()
 
 
@@ -328,7 +328,7 @@ class TestSourcePackageHasTranslationTemplates(
             productseries=self.packaging.productseries)
 
     def setUp(self):
-        super(TestSourcePackageHasTranslationTemplates, self).setUp()
+        super().setUp()
         self.container = self.factory.makeSourcePackage()
 
 
@@ -364,7 +364,7 @@ class TestDistroSeriesHasTranslationTemplates(
             productseries=self.packaging.productseries)
 
     def setUp(self):
-        super(TestDistroSeriesHasTranslationTemplates, self).setUp()
+        super().setUp()
         self.container = self.factory.makeDistroSeries()
 
     def test_has_sharing_translation_templates__templates(self):
diff --git a/lib/lp/translations/tests/test_helpers.py b/lib/lp/translations/tests/test_helpers.py
index c436e1b..cd7bdcf 100644
--- a/lib/lp/translations/tests/test_helpers.py
+++ b/lib/lp/translations/tests/test_helpers.py
@@ -18,7 +18,7 @@ class TestTranslationMessageHelpers(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestTranslationMessageHelpers, self).setUp()
+        super().setUp()
         ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
         new_series = self.factory.makeDistroSeries(distribution=ubuntu)
         sourcepackagename = self.factory.makeSourcePackageName()
@@ -33,7 +33,7 @@ class TestTranslationMessageHelpers(TestCaseWithFactory):
             language_code=self.pofile.language.code)
 
     def test_make_translationmessage(self):
-        translations = [u"testing"]
+        translations = ["testing"]
         tm = make_translationmessage(self.factory, pofile=self.pofile,
                                      potmsgset=self.potmsgset,
                                      translations=translations)
diff --git a/lib/lp/translations/tests/test_pofile.py b/lib/lp/translations/tests/test_pofile.py
index 5088d11..1c7ce5c 100644
--- a/lib/lp/translations/tests/test_pofile.py
+++ b/lib/lp/translations/tests/test_pofile.py
@@ -56,7 +56,7 @@ class TestTranslationSharedPOFileSourcePackage(TestCaseWithFactory):
     def setUp(self):
         # Create a product with two series and a shared POTemplate
         # in different series ('devel' and 'stable').
-        super(TestTranslationSharedPOFileSourcePackage, self).setUp()
+        super().setUp()
         self.foo = self.factory.makeDistribution()
         self.foo_devel = self.factory.makeDistroSeries(
             name='devel', distribution=self.foo)
@@ -93,7 +93,7 @@ class TestTranslationSharedPOFileSourcePackage(TestCaseWithFactory):
         date_created = datetime.now(pytz.UTC) - timedelta(5)
         translation = self.factory.makeSuggestion(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Translation"], date_created=date_created)
+            translations=["Translation"], date_created=date_created)
         translation.is_current_ubuntu = True
 
         # When there are no suggestions, nothing is returned.
@@ -105,7 +105,7 @@ class TestTranslationSharedPOFileSourcePackage(TestCaseWithFactory):
         suggestion_date = date_created + timedelta(1)
         suggestion = self.factory.makeSuggestion(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Suggestion"], date_created=suggestion_date)
+            translations=["Suggestion"], date_created=suggestion_date)
         self.assertEqual(suggestion.is_current_ubuntu, False)
 
         found_translations = list(
@@ -130,7 +130,7 @@ class TestTranslationSharedPOFileSourcePackage(TestCaseWithFactory):
         suggestion_date += timedelta(2)
         translation = self.factory.makeSuggestion(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"New suggestion"], date_created=suggestion_date)
+            translations=["New suggestion"], date_created=suggestion_date)
         self.assertEqual(translation.is_current_ubuntu, False)
 
         found_translations = list(
@@ -153,7 +153,7 @@ class TestTranslationSharedPOFileSourcePackage(TestCaseWithFactory):
         date_created = datetime.now(pytz.UTC) - timedelta(5)
         translation = self.factory.makeSuggestion(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Shared translation"], date_created=date_created)
+            translations=["Shared translation"], date_created=date_created)
         translation.is_current_ubuntu = True
 
         # And we also have a diverged translation created a day after a shared
@@ -161,7 +161,7 @@ class TestTranslationSharedPOFileSourcePackage(TestCaseWithFactory):
         diverged_date = date_created + timedelta(1)
         diverged_translation = self.factory.makeSuggestion(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Old translation"], date_created=diverged_date)
+            translations=["Old translation"], date_created=diverged_date)
         diverged_translation.potemplate = self.devel_potemplate
         diverged_translation.is_current_ubuntu = True
 
@@ -170,7 +170,7 @@ class TestTranslationSharedPOFileSourcePackage(TestCaseWithFactory):
         suggestion_date = date_created + timedelta(2)
         suggestion = self.factory.makeSuggestion(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Shared suggestion"], date_created=suggestion_date)
+            translations=["Shared suggestion"], date_created=suggestion_date)
         self.assertEqual(suggestion.is_current_ubuntu, False)
 
         # A suggestion is shown since diverged_date < suggestion_date.
@@ -183,7 +183,7 @@ class TestTranslationSharedPOFileSourcePackage(TestCaseWithFactory):
         diverged_date = suggestion_date + timedelta(1)
         diverged_translation_2 = self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Translation"], date_created=diverged_date,
+            translations=["Translation"], date_created=diverged_date,
             date_reviewed=diverged_date, diverged=True)
         diverged_translation.is_current_ubuntu = False
         diverged_translation_2.potemplate = self.devel_potemplate
@@ -196,7 +196,7 @@ class TestTranslationSharedPOFileSourcePackage(TestCaseWithFactory):
         suggestion_date = diverged_date + timedelta(1)
         suggestion = self.factory.makeSuggestion(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Suggestion"], date_created=suggestion_date)
+            translations=["Suggestion"], date_created=suggestion_date)
         self.assertEqual(suggestion.is_current_ubuntu, False)
 
         found_translations = list(
@@ -220,7 +220,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
     def setUp(self):
         # Create a product with two series and a shared POTemplate
         # in different series ('devel' and 'stable').
-        super(TestTranslationSharedPOFile, self).setUp()
+        super().setUp()
         self.foo = self.factory.makeProduct(
             name='foo',
             translations_usage=ServiceUsage.LAUNCHPAD)
@@ -262,69 +262,69 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
 
         # Searching for English strings.
         potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate,
-                                               u"Some wild text", sequence=2)
+                                               "Some wild text", sequence=2)
 
         found_potmsgsets = list(
-            self.devel_pofile.findPOTMsgSetsContaining(u"wild"))
+            self.devel_pofile.findPOTMsgSetsContaining("wild"))
         self.assertEqual(found_potmsgsets, [potmsgset])
 
         # Just linking an existing POTMsgSet into another POTemplate
         # will make it be returned in searches.
         potmsgset.setSequence(self.stable_potemplate, 2)
         found_potmsgsets = list(
-            self.stable_pofile.findPOTMsgSetsContaining(u"wild"))
+            self.stable_pofile.findPOTMsgSetsContaining("wild"))
         self.assertEqual(found_potmsgsets, [potmsgset])
 
         # Searching for singular in plural messages works as well.
         plural_potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate,
-                                                      u"Some singular text",
-                                                      u"Some plural text",
+                                                      "Some singular text",
+                                                      "Some plural text",
                                                       sequence=3)
 
         found_potmsgsets = list(
-            self.devel_pofile.findPOTMsgSetsContaining(u"singular"))
+            self.devel_pofile.findPOTMsgSetsContaining("singular"))
         self.assertEqual(found_potmsgsets, [plural_potmsgset])
 
         # And searching for plural text returns only the matching plural
         # message.
         found_potmsgsets = list(
-            self.devel_pofile.findPOTMsgSetsContaining(u"plural"))
+            self.devel_pofile.findPOTMsgSetsContaining("plural"))
         self.assertEqual(found_potmsgsets, [plural_potmsgset])
 
         # Search translations as well.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=potmsgset,
-            translations=[u"One translation message"])
+            translations=["One translation message"])
         found_potmsgsets = list(
-            self.devel_pofile.findPOTMsgSetsContaining(u"translation"))
+            self.devel_pofile.findPOTMsgSetsContaining("translation"))
         self.assertEqual(found_potmsgsets, [potmsgset])
 
         # Search matches all plural forms.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=plural_potmsgset,
-            translations=[u"One translation message",
-                          u"Plural translation message",
-                          u"Third translation message"])
+            translations=["One translation message",
+                          "Plural translation message",
+                          "Third translation message"])
         found_potmsgsets = list(
             self.devel_pofile.findPOTMsgSetsContaining(
-                u"Plural translation"))
+                "Plural translation"))
         self.assertEqual(found_potmsgsets, [plural_potmsgset])
 
         # Search works case insensitively for English strings.
         found_potmsgsets = list(
-            self.devel_pofile.findPOTMsgSetsContaining(u"WiLd"))
+            self.devel_pofile.findPOTMsgSetsContaining("WiLd"))
         self.assertEqual(found_potmsgsets, [potmsgset])
         # ...English plural forms.
         found_potmsgsets = list(
-            self.devel_pofile.findPOTMsgSetsContaining(u"PLurAl"))
+            self.devel_pofile.findPOTMsgSetsContaining("PLurAl"))
         self.assertEqual(found_potmsgsets, [plural_potmsgset])
         # ...translations.
         found_potmsgsets = list(
-            self.devel_pofile.findPOTMsgSetsContaining(u"tRANSlaTIon"))
+            self.devel_pofile.findPOTMsgSetsContaining("tRANSlaTIon"))
         self.assertEqual(found_potmsgsets, [potmsgset, plural_potmsgset])
         # ...and translated plurals.
         found_potmsgsets = list(
-            self.devel_pofile.findPOTMsgSetsContaining(u"THIRD"))
+            self.devel_pofile.findPOTMsgSetsContaining("THIRD"))
         self.assertEqual(found_potmsgsets, [plural_potmsgset])
 
     def test_getTranslationsFilteredBy_none(self):
@@ -348,7 +348,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
 
         translation = self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=potmsgset,
-            translations=[u"Translation message"],
+            translations=["Translation message"],
             translator=submitter)
         found_translations = list(
             self.devel_pofile.getTranslationsFilteredBy(submitter))
@@ -364,7 +364,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         someone_else = self.factory.makePerson()
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=potmsgset,
-            translations=[u"Another translation"],
+            translations=["Another translation"],
             translator=someone_else)
         found_translations = list(
             self.devel_pofile.getTranslationsFilteredBy(submitter))
@@ -384,7 +384,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
             'sr@test', potemplate=self.devel_potemplate)
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_sr_test_pofile, potmsgset=potmsgset,
-            translations=[u"Yet another translation"],
+            translations=["Yet another translation"],
             translator=submitter)
         found_translations = list(
             self.devel_pofile.getTranslationsFilteredBy(submitter))
@@ -398,7 +398,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         submitter = self.factory.makePerson()
         translation = self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=potmsgset,
-            translations=[u"Translation message"],
+            translations=["Translation message"],
             translator=submitter)
 
         potmsgset.setSequence(self.stable_potemplate, 1)
@@ -421,7 +421,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # When a diverged translation is added, the potmsgset is returned.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Translation"], diverged=True)
+            translations=["Translation"], diverged=True)
         found_translations = list(
             self.devel_pofile.getPOTMsgSetTranslated())
         self.assertEqual(found_translations, [self.potmsgset])
@@ -429,7 +429,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # If diverged translation is empty, POTMsgSet is not listed.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u""], diverged=True)
+            translations=[""], diverged=True)
         found_translations = list(
             self.devel_pofile.getPOTMsgSetTranslated())
         self.assertEqual(found_translations, [])
@@ -441,7 +441,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # We create a shared translation first.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Shared translation"])
+            translations=["Shared translation"])
 
         # When there is no diverged translation, shared one is returned.
         found_translations = list(
@@ -451,7 +451,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # When an empty diverged translation is added, nothing is listed.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u""], diverged=True)
+            translations=[""], diverged=True)
         found_translations = list(
             self.devel_pofile.getPOTMsgSetTranslated())
         self.assertEqual(found_translations, [])
@@ -459,7 +459,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # If diverged translation is non-empty, POTMsgSet is listed.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Translation"], diverged=True)
+            translations=["Translation"], diverged=True)
         found_translations = list(
             self.devel_pofile.getPOTMsgSetTranslated())
         self.assertEqual(found_translations, [self.potmsgset])
@@ -471,7 +471,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # We create an empty shared translation first.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u""])
+            translations=[""])
 
         # When there is no diverged translation, shared one is returned,
         # but since it's empty, there are no results.
@@ -482,7 +482,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # When an empty diverged translation is added, nothing is listed.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u""], diverged=True)
+            translations=[""], diverged=True)
         found_translations = list(
             self.devel_pofile.getPOTMsgSetTranslated())
         self.assertEqual(found_translations, [])
@@ -490,7 +490,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # If diverged translation is non-empty, POTMsgSet is listed.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Translation"], diverged=True)
+            translations=["Translation"], diverged=True)
         found_translations = list(
             self.devel_pofile.getPOTMsgSetTranslated())
         self.assertEqual(found_translations, [self.potmsgset])
@@ -503,15 +503,15 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # Add a diverged translation on the included POTMsgSet...
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Diverged translation"], diverged=True)
+            translations=["Diverged translation"], diverged=True)
 
         # and a shared translation on newly added POTMsgSet...
         potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate,
-                                               u"Translated text", sequence=2)
+                                               "Translated text", sequence=2)
 
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=potmsgset,
-            translations=[u"Shared translation"])
+            translations=["Shared translation"])
 
         # Both POTMsgSets are listed.
         found_translations = list(
@@ -530,7 +530,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # When a diverged translation is added, the potmsgset is returned.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Translation"], diverged=True)
+            translations=["Translation"], diverged=True)
         found_translations = list(
             self.devel_pofile.getPOTMsgSetUntranslated())
         self.assertEqual(found_translations, [])
@@ -538,7 +538,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # If diverged translation is empty, POTMsgSet is not listed.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u""], diverged=True)
+            translations=[""], diverged=True)
         found_translations = list(
             self.devel_pofile.getPOTMsgSetUntranslated())
         self.assertEqual(found_translations, [self.potmsgset])
@@ -550,7 +550,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # We create a shared translation first.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Shared translation"])
+            translations=["Shared translation"])
 
         # When there is no diverged translation, shared one is returned.
         found_translations = list(
@@ -560,7 +560,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # When an empty diverged translation is added, nothing is listed.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u""], diverged=True)
+            translations=[""], diverged=True)
         found_translations = list(
             self.devel_pofile.getPOTMsgSetUntranslated())
         self.assertEqual(found_translations, [self.potmsgset])
@@ -568,7 +568,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # If diverged translation is non-empty, POTMsgSet is listed.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Translation"], diverged=True)
+            translations=["Translation"], diverged=True)
         found_translations = list(
             self.devel_pofile.getPOTMsgSetUntranslated())
         self.assertEqual(found_translations, [])
@@ -580,7 +580,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # We create an empty shared translation first.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u""])
+            translations=[""])
 
         # When there is no diverged translation, shared one is returned,
         # but since it's empty, there are no results.
@@ -591,7 +591,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # When an empty diverged translation is added, nothing is listed.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u""], diverged=True)
+            translations=[""], diverged=True)
         found_translations = list(
             self.devel_pofile.getPOTMsgSetUntranslated())
         self.assertEqual(found_translations, [self.potmsgset])
@@ -599,7 +599,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # If diverged translation is non-empty, POTMsgSet is listed.
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Translation"], diverged=True)
+            translations=["Translation"], diverged=True)
         found_translations = list(
             self.devel_pofile.getPOTMsgSetUntranslated())
         self.assertEqual(found_translations, [])
@@ -612,11 +612,11 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # Add an empty translation to the included POTMsgSet...
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u""])
+            translations=[""])
 
         # ...and a new untranslated POTMsgSet.
         potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate,
-                                               u"Translated text", sequence=2)
+                                               "Translated text", sequence=2)
 
         # Both POTMsgSets are listed.
         found_translations = list(
@@ -634,7 +634,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # When a suggestion is added, the potmsgset is returned.
         translation = self.factory.makeSuggestion(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Suggestion"])
+            translations=["Suggestion"])
         self.assertEqual(translation.is_current_ubuntu, False)
 
         found_translations = list(
@@ -648,21 +648,21 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # One POTMsgSet has no translations, but only a suggestion.
         self.factory.makeSuggestion(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"New suggestion"])
+            translations=["New suggestion"])
 
         # Another POTMsgSet has both a translation and a suggestion.
         potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate,
-                                               u"Translated text",
+                                               "Translated text",
                                                sequence=2)
         date_created = datetime.now(pytz.UTC) - timedelta(5)
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Translation"],
+            translations=["Translation"],
             date_created=date_created, date_reviewed=date_created)
         suggestion_date = date_created + timedelta(1)
         self.factory.makeSuggestion(
             pofile=self.devel_pofile, potmsgset=potmsgset,
-            translations=[u"New suggestion"], date_created=suggestion_date)
+            translations=["New suggestion"], date_created=suggestion_date)
 
         # Both POTMsgSets are listed.
         found_translations = list(
@@ -730,7 +730,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # Adding a current translation on one side doesn't change anything.
         translation = self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"This side translation"])
+            translations=["This side translation"])
         self.assertEqual(self._getThisSideFlag(translation), True)
         self.assertEqual(self._getOtherSideFlag(translation), False)
         found_translations = list(
@@ -740,7 +740,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # Adding a translation on both sides does not introduce a difference.
         translation = self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Both sides translation"], current_other=True)
+            translations=["Both sides translation"], current_other=True)
         self.assertEqual(self._getThisSideFlag(translation), True)
         self.assertEqual(self._getOtherSideFlag(translation), True)
         found_translations = list(
@@ -751,7 +751,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # between this side and the other side.
         translation = self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Different translation"])
+            translations=["Different translation"])
         self.assertEqual(self._getThisSideFlag(translation), True)
         self.assertEqual(self._getOtherSideFlag(translation), False)
         found_translations = list(
@@ -761,7 +761,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         # A diverged translation is different, too.
         translation = self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=self.potmsgset,
-            translations=[u"Diverged translation"], diverged=True)
+            translations=["Diverged translation"], diverged=True)
         self.assertEqual(self._getThisSideFlag(translation), True)
         self.assertEqual(self._getOtherSideFlag(translation), False)
         found_translations = list(
@@ -808,7 +808,7 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
             self.devel_potemplate, sequence=2)
         self.factory.makeSuggestion(
             pofile=self.devel_pofile, potmsgset=potmsgset,
-            translations=[u"Unreviewed suggestion"])
+            translations=["Unreviewed suggestion"])
 
         # Third POTMsgSet is translated, and with a suggestion.
         potmsgset = self.factory.makePOTMsgSet(
@@ -816,35 +816,35 @@ class TestTranslationSharedPOFile(TestCaseWithFactory):
         update_date = datetime.now(pytz.UTC) - timedelta(1)
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=potmsgset,
-            translations=[u"Translation"], date_created=update_date,
+            translations=["Translation"], date_created=update_date,
             date_reviewed=update_date)
         self.factory.makeSuggestion(
             pofile=self.devel_pofile, potmsgset=potmsgset,
-            translations=[u"Another suggestion"])
+            translations=["Another suggestion"])
 
         # Fourth POTMsgSet is translated in import.
         potmsgset = self.factory.makePOTMsgSet(
             self.devel_potemplate, sequence=4)
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=potmsgset,
-            translations=[u"Imported translation"], current_other=True)
+            translations=["Imported translation"], current_other=True)
 
         # Fifth POTMsgSet is translated in import, but changed in Ubuntu.
         potmsgset = self.factory.makePOTMsgSet(
             self.devel_potemplate, sequence=5)
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=potmsgset,
-            translations=[u"Imported translation"], current_other=True)
+            translations=["Imported translation"], current_other=True)
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=potmsgset,
-            translations=[u"LP translation"], current_other=False)
+            translations=["LP translation"], current_other=False)
 
         # Sixth POTMsgSet is translated in LP only.
         potmsgset = self.factory.makePOTMsgSet(
             self.devel_potemplate, sequence=6)
         self.factory.makeCurrentTranslationMessage(
             pofile=self.devel_pofile, potmsgset=potmsgset,
-            translations=[u"New translation"], current_other=False)
+            translations=["New translation"], current_other=False)
 
         removeSecurityProxy(self.devel_potemplate).messagecount = (
             self.devel_potemplate.getPOTMsgSetsCount())
@@ -908,7 +908,7 @@ class TestSharingPOFileCreation(TestCaseWithFactory):
     def setUp(self):
         # Create a product with two series and a sharing POTemplate
         # in different series ('devel' and 'stable').
-        super(TestSharingPOFileCreation, self).setUp()
+        super().setUp()
         self.foo = self.factory.makeProduct()
         self.foo_devel = self.factory.makeProductSeries(
             name='devel', product=self.foo)
@@ -1041,9 +1041,9 @@ class TestSharingPOFileCreation(TestCaseWithFactory):
         stable_potemplate = self.factory.makePOTemplate(
             productseries=self.foo_stable, name="messages")
         devel_credits = self.factory.makePOTMsgSet(
-            potemplate=devel_potemplate, singular=u'translator-credits')
+            potemplate=devel_potemplate, singular='translator-credits')
         stable_credits = self.factory.makePOTMsgSet(
-            potemplate=stable_potemplate, singular=u'translation-credits')
+            potemplate=stable_potemplate, singular='translation-credits')
 
         # Create one language from the devel end, and the other from
         # stable.
@@ -1072,17 +1072,17 @@ class TestTranslationCredits(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestTranslationCredits, self).setUp()
+        super().setUp()
         self.pofile = self.factory.makePOFile('sr')
         self.potemplate = self.pofile.potemplate
 
         self.potmsgset = self.factory.makePOTMsgSet(
             potemplate=self.potemplate)
         self.credits_potmsgset = self.factory.makePOTMsgSet(
-            potemplate=self.potemplate, singular=u'translator-credits')
+            potemplate=self.potemplate, singular='translator-credits')
 
     def compose_launchpad_credits_text(self, imported_credits_text):
-        return u"%s\n\nLaunchpad Contributions:\n  %s" % (
+        return "%s\n\nLaunchpad Contributions:\n  %s" % (
                 imported_credits_text,
                 "\n  ".join(["%s %s" % (person.displayname,
                                         canonical_url(person))
@@ -1102,13 +1102,13 @@ class TestTranslationCredits(TestCaseWithFactory):
     def test_prepareTranslationCredits_gnome(self):
         # Preparing translation credits for GNOME-like credits message.
         translator = self.factory.makePerson(
-            name=u'the-translator',
-            displayname=u'Launchpad Translator')
+            name='the-translator',
+            displayname='Launchpad Translator')
         self.credits_potmsgset.setCurrentTranslation(
             self.pofile, translator, {0: 'upstream credits'},
             RosettaTranslationOrigin.SCM, share_with_other_side=True)
         self.assertEqual(
-            u'upstream credits\n\n'
+            'upstream credits\n\n'
             'Launchpad Contributions:\n'
             '  Launchpad Translator http://launchpad.test/~the-translator',
             self.pofile.prepareTranslationCredits(self.credits_potmsgset))
@@ -1119,7 +1119,7 @@ class TestTranslationCredits(TestCaseWithFactory):
         # Only the 'translator-credits' message is covered right now.
         person = self.factory.makePerson()
 
-        imported_credits_text = u"Imported Contributor <name@xxxxxxxxxxx>"
+        imported_credits_text = "Imported Contributor <name@xxxxxxxxxxx>"
 
         # Import a translation credits message to 'translator-credits'.
         self.factory.makeCurrentTranslationMessage(
@@ -1158,16 +1158,16 @@ class TestTranslationCredits(TestCaseWithFactory):
         # Preparing translation credits for old (pre-KDE4) KDE-like
         # credits message for contributor names.
         translator = self.factory.makePerson(
-            displayname=u'Launchpad Translator')
+            displayname='Launchpad Translator')
         kde_names_potmsgset = self.factory.makePOTMsgSet(
             potemplate=self.potemplate,
-            singular=u'_: NAME OF TRANSLATORS\nYour names')
+            singular='_: NAME OF TRANSLATORS\nYour names')
         kde_names_potmsgset.setCurrentTranslation(
             self.pofile, translator,
             {0: 'Upstream credits'},
             RosettaTranslationOrigin.SCM, share_with_other_side=True)
         self.assertEqual(
-            u'Upstream credits, ,Launchpad Contributions:,'
+            'Upstream credits, ,Launchpad Contributions:,'
             'Launchpad Translator',
             self.pofile.prepareTranslationCredits(kde_names_potmsgset))
 
@@ -1175,33 +1175,33 @@ class TestTranslationCredits(TestCaseWithFactory):
         # Preparing translation credits for old (pre-KDE4) KDE-like
         # credits message for contributor emails.
         translator = self.factory.makePerson(
-            email=u'translator@launchpad')
+            email='translator@launchpad')
         kde_emails_potmsgset = self.factory.makePOTMsgSet(
             potemplate=self.potemplate,
-            singular=u'_: EMAIL OF TRANSLATORS\nYour emails')
+            singular='_: EMAIL OF TRANSLATORS\nYour emails')
         kde_emails_potmsgset.setCurrentTranslation(
             self.pofile, translator,
             {0: 'translator@upstream'},
             RosettaTranslationOrigin.SCM, share_with_other_side=True)
         self.assertEqual(
-            u'translator@upstream,,,translator@launchpad',
+            'translator@upstream,,,translator@launchpad',
             self.pofile.prepareTranslationCredits(kde_emails_potmsgset))
 
     def test_prepareTranslationCredits_kde_names(self):
         # Preparing translation credits for new (KDE4 and later)
         # KDE-like credits message for contributor names.
         translator = self.factory.makePerson(
-            displayname=u'Launchpad Translator')
+            displayname='Launchpad Translator')
         kde_names_potmsgset = self.factory.makePOTMsgSet(
             potemplate=self.potemplate,
-            context=u'NAME OF TRANSLATORS',
-            singular=u'Your names')
+            context='NAME OF TRANSLATORS',
+            singular='Your names')
         kde_names_potmsgset.setCurrentTranslation(
             self.pofile, translator,
             {0: 'Upstream credits'},
             RosettaTranslationOrigin.SCM, share_with_other_side=True)
         self.assertEqual(
-            u'Upstream credits, ,Launchpad Contributions:,'
+            'Upstream credits, ,Launchpad Contributions:,'
             'Launchpad Translator',
             self.pofile.prepareTranslationCredits(kde_names_potmsgset))
 
@@ -1209,17 +1209,17 @@ class TestTranslationCredits(TestCaseWithFactory):
         # Preparing translation credits for new (KDE4 and later)
         # KDE-like credits message for contributor emails.
         translator = self.factory.makePerson(
-            email=u'translator@launchpad')
+            email='translator@launchpad')
         kde_emails_potmsgset = self.factory.makePOTMsgSet(
             potemplate=self.potemplate,
-            context=u'EMAIL OF TRANSLATORS',
-            singular=u'Your emails')
+            context='EMAIL OF TRANSLATORS',
+            singular='Your emails')
         kde_emails_potmsgset.setCurrentTranslation(
             self.pofile, translator,
             {0: 'translator@upstream'},
             RosettaTranslationOrigin.SCM, share_with_other_side=True)
         self.assertEqual(
-            u'translator@upstream,,,translator@launchpad',
+            'translator@upstream,,,translator@launchpad',
             self.pofile.prepareTranslationCredits(kde_emails_potmsgset))
 
 
@@ -1231,7 +1231,7 @@ class TestTranslationPOFilePOTMsgSetOrdering(TestCaseWithFactory):
     def setUp(self):
         # Create a product with two series and a sharing POTemplate
         # in different series ('devel' and 'stable').
-        super(TestTranslationPOFilePOTMsgSetOrdering, self).setUp()
+        super().setUp()
         self.foo = self.factory.makeProduct(
             translations_usage=ServiceUsage.LAUNCHPAD)
         self.foo_devel = self.factory.makeProductSeries(
@@ -1392,7 +1392,7 @@ class TestPOFileSet(TestCaseWithFactory):
 
     def setUp(self):
         # Create a POFileSet to work with.
-        super(TestPOFileSet, self).setUp()
+        super().setUp()
         self.pofileset = getUtility(IPOFileSet)
 
     def test_POFileSet_getPOFilesTouchedSince_none(self):
@@ -1589,7 +1589,7 @@ class TestPOFileSet(TestCaseWithFactory):
         # returned along with relevant POTMsgSets.
         potemplate1 = self.factory.makePOTemplate()
         self.factory.makePOTMsgSet(
-            potemplate1, singular=u'translator-credits')
+            potemplate1, singular='translator-credits')
 
         sr_pofile = self.factory.makePOFile('sr', potemplate=potemplate1)
         self.assertIn(sr_pofile,
@@ -1609,8 +1609,8 @@ class TestPOFileSet(TestCaseWithFactory):
         # returned as well.
         potemplate2 = self.factory.makePOTemplate()
         self.factory.makePOTMsgSet(
-            potemplate2, singular=u'Your names',
-            context=u'NAME OF TRANSLATORS')
+            potemplate2, singular='Your names',
+            context='NAME OF TRANSLATORS')
         sr_kde_pofile = self.factory.makePOFile('sr', potemplate=potemplate2)
         self.assertIn(sr_kde_pofile,
                       list_of_tuples_into_list(
@@ -1638,7 +1638,7 @@ class TestPOFileSet(TestCaseWithFactory):
 
         potemplate = self.factory.makePOTemplate()
         credits_potmsgset = self.factory.makePOTMsgSet(
-            potemplate, singular=u'translator-credits')
+            potemplate, singular='translator-credits')
         pofile = self.factory.makePOFile(potemplate=potemplate)
 
         credits_translation = credits_potmsgset.getCurrentTranslation(
@@ -1779,7 +1779,7 @@ class TestPOFileStatistics(TestCaseWithFactory):
 
     def setUp(self):
         # Create a POFile to calculate statistics on.
-        super(TestPOFileStatistics, self).setUp()
+        super().setUp()
         self.pofile = self.factory.makePOFile('sr')
         self.potemplate = self.pofile.potemplate
 
@@ -1879,7 +1879,7 @@ class TestPOFileStatistics(TestCaseWithFactory):
         # untranslated if at least one plural translation required
         # for the given language is missing.
         plural_potmsgset = self.factory.makePOTMsgSet(
-            self.potemplate, singular=u'singular-en', plural=u'plural-en')
+            self.potemplate, singular='singular-en', plural='plural-en')
         self.factory.makeCurrentTranslationMessage(
             pofile=self.pofile, potmsgset=plural_potmsgset,
             translations=['sr-singular', 'sr-plural-1'])
@@ -1893,7 +1893,7 @@ class TestPOFileStatistics(TestCaseWithFactory):
         # A translation requiring plural forms is considered to be
         # translated if all variants are translated.
         plural_potmsgset = self.factory.makePOTMsgSet(
-            self.potemplate, singular=u'singular-en', plural=u'plural-en')
+            self.potemplate, singular='singular-en', plural='plural-en')
         self.factory.makeCurrentTranslationMessage(
             pofile=self.pofile, potmsgset=plural_potmsgset,
             translations=['sr-singular', 'sr-plural-1', 'sr-plural-2'])
@@ -1923,7 +1923,7 @@ class TestPOFileStatistics(TestCaseWithFactory):
         # partially translated is considered to be untranslated, regardless
         # of any translations it may have on the other side.
         plural_potmsgset = self.factory.makePOTMsgSet(
-            self.potemplate, singular=u'singular-en', plural=u'plural-en')
+            self.potemplate, singular='singular-en', plural='plural-en')
         self.factory.makeCurrentTranslationMessage(
             pofile=self.pofile, potmsgset=plural_potmsgset,
             translations=['sr-singular', 'sr-plural-1'])
@@ -1964,7 +1964,7 @@ class TestPOFileStatistics(TestCaseWithFactory):
         # Instead, it's counted as translated on this side but not on
         # the other (newCount).
         plural_potmsgset = self.factory.makePOTMsgSet(
-            self.potemplate, singular=u'singular-en', plural=u'plural-en')
+            self.potemplate, singular='singular-en', plural='plural-en')
         self.factory.makeCurrentTranslationMessage(
             pofile=self.pofile, potmsgset=plural_potmsgset,
             translations=['sr-singular', 'sr-plural1', 'sr-plural2'])
@@ -1996,7 +1996,7 @@ class TestPOFileStatistics(TestCaseWithFactory):
         # A partial Translations that's current on both sides
         # counts as untranslated.
         plural_potmsgset = self.factory.makePOTMsgSet(
-            self.potemplate, singular=u'singular-en', plural=u'plural-en')
+            self.potemplate, singular='singular-en', plural='plural-en')
         self.factory.makeCurrentTranslationMessage(
             pofile=self.pofile, potmsgset=plural_potmsgset,
             translations=['sr-singular', 'sr-plural1'], current_other=True)
@@ -2054,16 +2054,16 @@ class TestPOFile(TestCaseWithFactory):
     # The sequence number 0 is put at the beginning of the data to verify that
     # it really gets sorted to the end.
     TEST_MESSAGES = [
-        {'msgid': u'computer', 'string': u'komputilo', 'sequence': 0},
-        {'msgid': u'mouse', 'string': u'muso', 'sequence': 0},
-        {'msgid': u'Good morning', 'string': u'Bonan matenon', 'sequence': 2},
-        {'msgid': u'Thank you', 'string': u'Dankon', 'sequence': 1},
+        {'msgid': 'computer', 'string': 'komputilo', 'sequence': 0},
+        {'msgid': 'mouse', 'string': 'muso', 'sequence': 0},
+        {'msgid': 'Good morning', 'string': 'Bonan matenon', 'sequence': 2},
+        {'msgid': 'Thank you', 'string': 'Dankon', 'sequence': 1},
         ]
     EXPECTED_SEQUENCE = [1, 2, 0, 0]
 
     def setUp(self):
         # Create a POFile to calculate statistics on.
-        super(TestPOFile, self).setUp()
+        super().setUp()
         self.pofile = self.factory.makePOFile('eo')
         self.potemplate = self.pofile.potemplate
 
@@ -2340,7 +2340,7 @@ class TestPOFileUbuntuSharing(TestCaseWithFactory,
     """Test sharing on Ubuntu side."""
 
     def setUp(self):
-        super(TestPOFileUbuntuSharing, self).setUp()
+        super().setUp()
         self.createData()
 
     def makeThisSidePOFile(self, create_sharing=False):
@@ -2358,7 +2358,7 @@ class TestPOFileUpstreamSharing(TestCaseWithFactory,
     """Test sharing on upstream side."""
 
     def setUp(self):
-        super(TestPOFileUpstreamSharing, self).setUp()
+        super().setUp()
         self.createData()
 
     def makeThisSidePOFile(self, create_sharing=False):
@@ -2377,7 +2377,7 @@ class TestPOFileTranslationMessages(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestPOFileTranslationMessages, self).setUp()
+        super().setUp()
         self.pofile = self.factory.makePOFile('eo')
         self.potemplate = self.pofile.potemplate
         self.potmsgset = self.factory.makePOTMsgSet(
@@ -2513,7 +2513,7 @@ class TestPOFileToTranslationFileDataAdapter(TestCaseWithFactory):
     def _makePOFileWithPlural(self, language_code):
         pofile = removeSecurityProxy(self.factory.makePOFile(language_code))
         self.factory.makePOTMsgSet(
-            pofile.potemplate, singular=u"Foo", plural=u"Bar")
+            pofile.potemplate, singular="Foo", plural="Bar")
         return pofile
 
     def test_header_pluralform_equal(self):
@@ -2528,7 +2528,7 @@ class TestPOFileToTranslationFileDataAdapter(TestCaseWithFactory):
         # The expression from the header starts with a "(", the language entry
         # does not.
         self.assertEqual(
-            u"n%10==1 && n%100!=11",
+            "n%10==1 && n%100!=11",
             translation_file_data.header.plural_form_expression[:20])
 
     def test_header_pluralform_larger(self):
@@ -2541,7 +2541,7 @@ class TestPOFileToTranslationFileDataAdapter(TestCaseWithFactory):
             sr_pofile, ITranslationFileData, 'all_messages')
         self.assertEqual(4, translation_file_data.header.number_plural_forms)
         self.assertEqual(
-            u"(n==1 ? 3 : (n%10==1",
+            "(n==1 ? 3 : (n%10==1",
             translation_file_data.header.plural_form_expression[:20])
 
     def test_header_pluralform_larger_but_western(self):
@@ -2565,7 +2565,7 @@ class TestPOFileToTranslationFileDataAdapter(TestCaseWithFactory):
             # The plural form expression for Japanese (or any other language
             # with just one form) is simply '0'.
             self.assertEqual(
-                u"0", translation_file_data.header.plural_form_expression)
+                "0", translation_file_data.header.plural_form_expression)
 
     def test_header_pluralform_2_but_not_western(self):
         # If the plural form expression in the header reports two but is not
@@ -2579,7 +2579,7 @@ class TestPOFileToTranslationFileDataAdapter(TestCaseWithFactory):
             ja_pofile, ITranslationFileData, 'all_messages')
         self.assertEqual(2, translation_file_data.header.number_plural_forms)
         self.assertEqual(
-            u"(n > 0)", translation_file_data.header.plural_form_expression)
+            "(n > 0)", translation_file_data.header.plural_form_expression)
 
     def test_header_pluralform_generic(self):
         # If the plural form expression in the header is a generic one (no
@@ -2591,7 +2591,7 @@ class TestPOFileToTranslationFileDataAdapter(TestCaseWithFactory):
             ja_pofile, ITranslationFileData, 'all_messages')
         self.assertEqual(1, translation_file_data.header.number_plural_forms)
         self.assertEqual(
-            u"0", translation_file_data.header.plural_form_expression)
+            "0", translation_file_data.header.plural_form_expression)
 
 
 class TestPOFilePermissions(TestCaseWithFactory):
@@ -2602,7 +2602,7 @@ class TestPOFilePermissions(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestPOFilePermissions, self).setUp()
+        super().setUp()
         self.pofile = self.factory.makePOFile()
 
     def makeDistroPOFile(self):
diff --git a/lib/lp/translations/tests/test_potemplate.py b/lib/lp/translations/tests/test_potemplate.py
index 93a42fd..7e8f645 100644
--- a/lib/lp/translations/tests/test_potemplate.py
+++ b/lib/lp/translations/tests/test_potemplate.py
@@ -3,7 +3,6 @@
 
 from operator import methodcaller
 
-import six
 from zope.component import getUtility
 from zope.security.proxy import removeSecurityProxy
 
@@ -121,10 +120,10 @@ class TestPOTemplate(TestCaseWithFactory):
         # getTranslationCredits returns only translation credits.
         self.factory.makePOTMsgSet(self.potemplate, sequence=1)
         gnome_credits = self.factory.makePOTMsgSet(
-            self.potemplate, sequence=2, singular=u"translator-credits")
+            self.potemplate, sequence=2, singular="translator-credits")
         kde_credits = self.factory.makePOTMsgSet(
             self.potemplate, sequence=3,
-            singular=u"Your emails", context=u"EMAIL OF TRANSLATORS")
+            singular="Your emails", context="EMAIL OF TRANSLATORS")
         self.factory.makePOTMsgSet(self.potemplate, sequence=4)
 
         self.assertContentEqual([gnome_credits, kde_credits],
@@ -193,7 +192,7 @@ class EquivalenceClassTestMixin:
         A separate test looks at ordering.
         """
         self.assertEqual(set(actual), set(expected))
-        for key, value in six.iteritems(actual):
+        for key, value in actual.items():
             self.assertEqual(set(value), set(expected[key]))
 
 
@@ -203,7 +202,7 @@ class TestProductTemplateEquivalenceClasses(TestCaseWithFactory,
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestProductTemplateEquivalenceClasses, self).setUp()
+        super().setUp()
         self.product = self.factory.makeProduct()
         self.trunk = self.product.getSeries('trunk')
         self.stable = self.factory.makeProductSeries(
@@ -276,7 +275,7 @@ class TestDistroTemplateEquivalenceClasses(TestCaseWithFactory,
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestDistroTemplateEquivalenceClasses, self).setUp()
+        super().setUp()
         self.ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
         self.hoary = self.ubuntu['hoary']
         self.warty = self.ubuntu['warty']
@@ -358,7 +357,7 @@ class TestDistroTemplateEquivalenceClasses(TestCaseWithFactory,
         subset = getUtility(IPOTemplateSet).getSharingSubset(
             distribution=self.ubuntu, sourcepackagename=self.package)
         classes = subset.groupEquivalentPOTemplates(
-            name_pattern=u'krungthepmahanakorn.*-etc')
+            name_pattern='krungthepmahanakorn.*-etc')
 
         expected = {
             (unique_name, self.package.name): [bangkok_template],
@@ -408,7 +407,7 @@ class TestTemplatePrecedence(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestTemplatePrecedence, self).setUp(user='mark@xxxxxxxxxxx')
+        super().setUp(user='mark@xxxxxxxxxxx')
         self.product = self.factory.makeProduct(
             translations_usage=ServiceUsage.LAUNCHPAD)
         self.trunk = self.product.getSeries('trunk')
@@ -589,7 +588,7 @@ class TestGetPOFilesFor(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestGetPOFilesFor, self).setUp()
+        super().setUp()
         self.potemplate = self.factory.makePOTemplate()
         self.greek = getUtility(ILanguageSet).getLanguageByCode('el')
 
@@ -675,7 +674,7 @@ class TestPOTemplateUbuntuSharing(TestCaseWithFactory,
     """Test sharing on Ubuntu side."""
 
     def setUp(self):
-        super(TestPOTemplateUbuntuSharing, self).setUp()
+        super().setUp()
         self.createData()
 
     def makeThisSidePOTemplate(self):
@@ -692,7 +691,7 @@ class TestPOTemplateUpstreamSharing(TestCaseWithFactory,
     """Test sharing on upstream side."""
 
     def setUp(self):
-        super(TestPOTemplateUpstreamSharing, self).setUp()
+        super().setUp()
         self.createData()
 
     def makeThisSidePOTemplate(self):
@@ -715,7 +714,7 @@ class TestPOTemplateSharingSubset(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestPOTemplateSharingSubset, self).setUp()
+        super().setUp()
         self.p1 = self.factory.makeProduct()
         self.p1s1 = self.factory.makeProductSeries(product=self.p1)
         self.p1s2 = self.factory.makeProductSeries(product=self.p1)
diff --git a/lib/lp/translations/tests/test_potmsgset.py b/lib/lp/translations/tests/test_potmsgset.py
index 0a87230..fd19fa4 100644
--- a/lib/lp/translations/tests/test_potmsgset.py
+++ b/lib/lp/translations/tests/test_potmsgset.py
@@ -44,8 +44,7 @@ class TestTranslationSharedPOTMsgSets(TestCaseWithFactory):
         """Set up context to test in."""
         # Create a product with two series and a shared POTemplate
         # in different series ('devel' and 'stable').
-        super(TestTranslationSharedPOTMsgSets, self).setUp(
-            'carlos@xxxxxxxxxxxxx')
+        super().setUp('carlos@xxxxxxxxxxxxx')
         self.foo = self.factory.makeProduct(
             translations_usage=ServiceUsage.LAUNCHPAD)
         self.foo_devel = self.factory.makeProductSeries(
@@ -501,7 +500,7 @@ class TestTranslationSharedPOTMsgSets(TestCaseWithFactory):
         """Test that translation credits are correctly set as translated."""
         sr_pofile = self.factory.makePOFile('sr', self.devel_potemplate)
         credits_potmsgset = self.factory.makePOTMsgSet(
-            self.devel_potemplate, singular=u'translator-credits')
+            self.devel_potemplate, singular='translator-credits')
         credits_potmsgset.setTranslationCreditsToTranslated(sr_pofile)
         current = credits_potmsgset.getCurrentTranslation(
             self.devel_potemplate, sr_pofile.language,
@@ -514,7 +513,7 @@ class TestTranslationSharedPOTMsgSets(TestCaseWithFactory):
         """Test that translation credits don't change."""
         sr_pofile = self.factory.makePOFile('sr', self.devel_potemplate)
         credits_potmsgset = self.factory.makePOTMsgSet(
-            self.devel_potemplate, singular=u'translator-credits')
+            self.devel_potemplate, singular='translator-credits')
         old_credits = credits_potmsgset.setCurrentTranslation(
             sr_pofile, sr_pofile.potemplate.owner, {0: 'credits'},
             RosettaTranslationOrigin.SCM, share_with_other_side=True)
@@ -528,7 +527,7 @@ class TestTranslationSharedPOTMsgSets(TestCaseWithFactory):
         """Test that translation doesn't change on a non-credits message."""
         sr_pofile = self.factory.makePOFile('sr', self.devel_potemplate)
         not_credits_potmsgset = self.factory.makePOTMsgSet(
-            self.devel_potemplate, singular=u'non-credit message')
+            self.devel_potemplate, singular='non-credit message')
         not_credits_potmsgset.setTranslationCreditsToTranslated(sr_pofile)
         current = not_credits_potmsgset.getCurrentTranslation(
             self.devel_potemplate, sr_pofile.language,
@@ -540,7 +539,7 @@ class TestTranslationSharedPOTMsgSets(TestCaseWithFactory):
         # we should provide an automatic shared translation instead.
         sr_pofile = self.factory.makePOFile('sr', self.devel_potemplate)
         credits_potmsgset = self.factory.makePOTMsgSet(
-            self.devel_potemplate, singular=u'translator-credits')
+            self.devel_potemplate, singular='translator-credits')
         diverged_credits = self.factory.makeCurrentTranslationMessage(
             sr_pofile, credits_potmsgset)
         # Since translation credits are special, we can't easily create
@@ -572,7 +571,7 @@ class TestTranslationSharedPOTMsgSets(TestCaseWithFactory):
         sr_pofile.lasttranslator = translator
         sr_pofile.owner = translator
         credits_potmsgset = self.factory.makePOTMsgSet(
-            self.devel_potemplate, singular=u'translator-credits')
+            self.devel_potemplate, singular='translator-credits')
         current = credits_potmsgset.getCurrentTranslation(
             self.devel_potemplate, sr_pofile.language,
             TranslationSide.UPSTREAM)
@@ -604,7 +603,7 @@ class TestPOTMsgSetSuggestions(TestCaseWithFactory):
     def setUp(self):
         # Create a product with all the boilerplate objects to be able to
         # create TranslationMessage objects.
-        super(TestPOTMsgSetSuggestions, self).setUp('carlos@xxxxxxxxxxxxx')
+        super().setUp('carlos@xxxxxxxxxxxxx')
         self.now = partial(next, self.gen_now())
         self.foo = self.factory.makeProduct(
             translations_usage=ServiceUsage.LAUNCHPAD)
@@ -619,13 +618,13 @@ class TestPOTMsgSetSuggestions(TestCaseWithFactory):
         # changed in the tests.
         self.translation = self.factory.makeCurrentTranslationMessage(
             removeSecurityProxy(self.pofile), self.potmsgset,
-            translations=[u'trans1'], reviewer=self.factory.makePerson(),
+            translations=['trans1'], reviewer=self.factory.makePerson(),
             current_other=True, date_created=self.now())
         self.suggestion1 = self.factory.makeSuggestion(
-            self.pofile, self.potmsgset, translations=[u'sugg1'],
+            self.pofile, self.potmsgset, translations=['sugg1'],
             date_created=self.now())
         self.suggestion2 = self.factory.makeSuggestion(
-            self.pofile, self.potmsgset, translations=[u'sugg2'],
+            self.pofile, self.potmsgset, translations=['sugg2'],
             date_created=self.now())
         self._setDateCreated(self.suggestion2)
 
@@ -801,8 +800,7 @@ class TestPOTMsgSetResetTranslation(TestCaseWithFactory):
     def setUp(self):
         # Create a product with all the boilerplate objects to be able to
         # create TranslationMessage objects.
-        super(TestPOTMsgSetResetTranslation, self).setUp(
-            'carlos@xxxxxxxxxxxxx')
+        super().setUp('carlos@xxxxxxxxxxxxx')
         self.now = partial(next, self.gen_now())
         self.foo = self.factory.makeProduct(
             translations_usage=ServiceUsage.LAUNCHPAD)
@@ -968,8 +966,7 @@ class TestPOTMsgSetTranslationCredits(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestPOTMsgSetTranslationCredits, self).setUp(
-            'carlos@xxxxxxxxxxxxx')
+        super().setUp('carlos@xxxxxxxxxxxxx')
         self.potemplate = self.factory.makePOTemplate()
 
     def test_creation_credits(self):
@@ -979,7 +976,7 @@ class TestPOTMsgSetTranslationCredits(TestCaseWithFactory):
         sr_pofile = self.factory.makePOFile('sr', potemplate=self.potemplate)
 
         credits = self.factory.makePOTMsgSet(
-            self.potemplate, u'translator-credits')
+            self.potemplate, 'translator-credits')
 
         eo_translation = credits.getCurrentTranslation(
             self.potemplate, eo_pofile.language,
@@ -1008,10 +1005,10 @@ class TestPOTMsgSetTranslationCredits(TestCaseWithFactory):
         # Dummy translation for translation credits are not created as
         # imported and can therefore be overwritten by later imports.
         eo_pofile = self.factory.makePOFile('eo', potemplate=self.potemplate)
-        imported_credits = u'Imported credits.'
+        imported_credits = 'Imported credits.'
 
         credits = self.factory.makePOTMsgSet(
-            self.potemplate, u'translator-credits')
+            self.potemplate, 'translator-credits')
         self.factory.makeCurrentTranslationMessage(
             eo_pofile, credits, translations=[imported_credits],
             current_other=True)
@@ -1027,7 +1024,7 @@ class TestPOTMsgSetTranslationCredits(TestCaseWithFactory):
         # all translation credits messages.
 
         credits = self.factory.makePOTMsgSet(
-            self.potemplate, u'translator-credits')
+            self.potemplate, 'translator-credits')
         eo_pofile = self.factory.makePOFile('eo', potemplate=self.potemplate)
 
         eo_translation = credits.getCurrentTranslation(
@@ -1040,9 +1037,9 @@ class TestPOTMsgSetTranslationCredits(TestCaseWithFactory):
     def test_translation_credits_gnome(self):
         # Detect all known variations of Gnome translator credits.
         gnome_credits = [
-            u'translator-credits',
-            u'translator_credits',
-            u'translation-credits',
+            'translator-credits',
+            'translator_credits',
+            'translation-credits',
         ]
         for sequence, credits_string in enumerate(gnome_credits):
             credits = self.factory.makePOTMsgSet(
@@ -1054,9 +1051,9 @@ class TestPOTMsgSetTranslationCredits(TestCaseWithFactory):
     def test_translation_credits_kde(self):
         # Detect all known variations of KDE translator credits.
         kde_credits = [
-            (u'Your emails', u'EMAIL OF TRANSLATORS',
+            ('Your emails', 'EMAIL OF TRANSLATORS',
              TranslationCreditsType.KDE_EMAILS),
-            (u'Your names', u'NAME OF TRANSLATORS',
+            ('Your names', 'NAME OF TRANSLATORS',
              TranslationCreditsType.KDE_NAMES),
         ]
         sequence = 0
@@ -1071,7 +1068,7 @@ class TestPOTMsgSetTranslationCredits(TestCaseWithFactory):
             # Old KDE style.
             sequence += 1
             credits = self.factory.makePOTMsgSet(
-                self.potemplate, u'_: %s\n%s' % (context, credits_string),
+                self.potemplate, '_: %s\n%s' % (context, credits_string),
                 sequence=sequence)
             self.assertTrue(credits.is_translation_credit)
             self.assertEqual(credits_type, credits.translation_credits_type)
@@ -1253,7 +1250,7 @@ class TestPOTMsgSet_submitSuggestion(TestCaseWithFactory):
     def test_credits_message(self):
         # Suggestions for translation-credits messages are ignored.
         pofile, potmsgset = self._makePOFileAndPOTMsgSet(
-            msgid=u'translator-credits')
+            msgid='translator-credits')
         self.assertTrue(potmsgset.is_translation_credit)
         owner = pofile.potemplate.owner
         translation = {0: self.factory.getUniqueString()}
@@ -1265,7 +1262,7 @@ class TestPOTMsgSet_submitSuggestion(TestCaseWithFactory):
     def test_credits_karma(self):
         # No karma is assigned for suggestions on translation credits.
         pofile, potmsgset = self._makePOFileAndPOTMsgSet(
-            msgid=u'translator-credits')
+            msgid='translator-credits')
         self.assertTrue(potmsgset.is_translation_credit)
         owner = pofile.potemplate.owner
         translation = {0: self.factory.getUniqueString()}
@@ -1303,7 +1300,7 @@ class TestSetCurrentTranslation(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestSetCurrentTranslation, self).setUp('carlos@xxxxxxxxxxxxx')
+        super().setUp('carlos@xxxxxxxxxxxxx')
 
     def _makePOFileAndPOTMsgSet(self):
         pofile = self.factory.makePOFile('nl')
@@ -1381,7 +1378,7 @@ class TestSetCurrentTranslation(TestCaseWithFactory):
             lock_timestamp=lock_timestamp)
 
 
-class BaseTestGetCurrentTranslation(object):
+class BaseTestGetCurrentTranslation:
     layer = DatabaseFunctionalLayer
 
     def test_no_translation(self):
@@ -1518,8 +1515,7 @@ class TestGetCurrentTranslationForUpstreams(BaseTestGetCurrentTranslation,
     """getCurrentTranslation working on an upstream POFile."""
 
     def setUp(self):
-        super(TestGetCurrentTranslationForUpstreams, self).setUp(
-            'carlos@xxxxxxxxxxxxx')
+        super().setUp('carlos@xxxxxxxxxxxxx')
         self.this_side = TranslationSide.UPSTREAM
         self.other_side = TranslationSide.UBUNTU
 
@@ -1545,8 +1541,7 @@ class TestGetCurrentTranslationForUbuntu(BaseTestGetCurrentTranslation,
     """getCurrentTranslation working on an Ubuntu POFile."""
 
     def setUp(self):
-        super(TestGetCurrentTranslationForUbuntu, self).setUp(
-            'carlos@xxxxxxxxxxxxx')
+        super().setUp('carlos@xxxxxxxxxxxxx')
         self.this_side = TranslationSide.UBUNTU
         self.other_side = TranslationSide.UPSTREAM
 
diff --git a/lib/lp/translations/tests/test_setcurrenttranslation.py b/lib/lp/translations/tests/test_setcurrenttranslation.py
index b3e758c..8e73ee3 100644
--- a/lib/lp/translations/tests/test_setcurrenttranslation.py
+++ b/lib/lp/translations/tests/test_setcurrenttranslation.py
@@ -1120,7 +1120,7 @@ class TestSetCurrentTranslation_Ubuntu(SetCurrentTranslationTestMixin,
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestSetCurrentTranslation_Ubuntu, self).setUp()
+        super().setUp()
         ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
         sourcepackagename = self.factory.makeSourcePackageName()
         potemplate = self.factory.makePOTemplate(
@@ -1158,7 +1158,7 @@ class TestSetCurrentTranslation_Upstream(SetCurrentTranslationTestMixin,
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestSetCurrentTranslation_Upstream, self).setUp()
+        super().setUp()
         series = self.factory.makeProductSeries()
         sharing_series = self.factory.makeProductSeries(
             product=series.product)
diff --git a/lib/lp/translations/tests/test_shared_potemplate.py b/lib/lp/translations/tests/test_shared_potemplate.py
index 6fc740f..1addf52 100644
--- a/lib/lp/translations/tests/test_shared_potemplate.py
+++ b/lib/lp/translations/tests/test_shared_potemplate.py
@@ -21,7 +21,7 @@ class TestTranslationSharingPOTemplate(TestCaseWithFactory):
         """Set up context to test in."""
         # Create a product with two series and sharing POTemplates
         # in different series ('devel' and 'stable').
-        super(TestTranslationSharingPOTemplate, self).setUp()
+        super().setUp()
         self.foo = self.factory.makeProduct(
             translations_usage=ServiceUsage.LAUNCHPAD)
         self.foo_devel = self.factory.makeProductSeries(
@@ -224,7 +224,7 @@ class TestSharingPOTemplatesByRegex(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestSharingPOTemplatesByRegex, self).setUp()
+        super().setUp()
 
     def _makeAndFind(self, names, name_pattern=None):
         product = self.factory.makeProduct()
@@ -240,13 +240,13 @@ class TestSharingPOTemplatesByRegex(TestCaseWithFactory):
         # Baseline test.
         self.assertContentEqual(
             ['foo', 'foo-bar', 'foo-two'],
-            self._makeAndFind(['foo', 'foo-bar', 'foo-two'], u'foo.*'))
+            self._makeAndFind(['foo', 'foo-bar', 'foo-two'], 'foo.*'))
 
     def test_getSharingPOTemplatesByRegex_not_all(self):
         # A template may not match.
         self.assertContentEqual(
             ['foo-bar', 'foo-two'],
-            self._makeAndFind(['foo', 'foo-bar', 'foo-two'], u'foo-.*'))
+            self._makeAndFind(['foo', 'foo-bar', 'foo-two'], 'foo-.*'))
 
     def test_getSharingPOTemplatesByRegex_all(self):
         # Not passing a pattern returns all templates.
@@ -258,19 +258,19 @@ class TestSharingPOTemplatesByRegex(TestCaseWithFactory):
         # A not matching pattern returns no templates.
         self.assertContentEqual(
             [],
-            self._makeAndFind(['foo', 'foo-bar', 'foo-two'], u"doo.+dle"))
+            self._makeAndFind(['foo', 'foo-bar', 'foo-two'], "doo.+dle"))
 
     def test_getSharingPOTemplatesByRegex_robustness_single_quotes(self):
         # Single quotes do not confuse the regex match.
         self.assertContentEqual(
             [],
-            self._makeAndFind(['foo', 'foo-bar', 'foo-two'], u"'"))
+            self._makeAndFind(['foo', 'foo-bar', 'foo-two'], "'"))
 
     def test_getSharingPOTemplatesByRegex_robustness_double_quotes(self):
         # Double quotes do not confuse the regex match.
         self.assertContentEqual(
             [],
-            self._makeAndFind(['foo', 'foo-bar', 'foo-two'], u'"'))
+            self._makeAndFind(['foo', 'foo-bar', 'foo-two'], '"'))
 
     def test_getSharingPOTemplatesByRegex_robustness_backslash(self):
         # A backslash at the end could escape enclosing quotes without
@@ -280,7 +280,7 @@ class TestSharingPOTemplatesByRegex(TestCaseWithFactory):
         product = self.factory.makeProduct()
         subset = getUtility(IPOTemplateSet).getSharingSubset(product=product)
         self.assertRaises(
-            DataError, list, subset.getSharingPOTemplatesByRegex(u"foo.*\\"))
+            DataError, list, subset.getSharingPOTemplatesByRegex("foo.*\\"))
 
 
 class TestMessageSharingProductPackage(TestCaseWithFactory):
@@ -295,7 +295,7 @@ class TestMessageSharingProductPackage(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestMessageSharingProductPackage, self).setUp()
+        super().setUp()
 
         self.ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
         self.hoary = self.ubuntu['hoary']
diff --git a/lib/lp/translations/tests/test_side.py b/lib/lp/translations/tests/test_side.py
index 74030d7..d25e808 100644
--- a/lib/lp/translations/tests/test_side.py
+++ b/lib/lp/translations/tests/test_side.py
@@ -3,7 +3,6 @@
 
 """Test `TranslationSide` and friends."""
 
-import six
 from zope.component import getUtility
 from zope.interface.verify import verifyObject
 
@@ -22,7 +21,7 @@ class TestTranslationSideTraitsSet(TestCaseWithFactory):
     def test_baseline(self):
         utility = getUtility(ITranslationSideTraitsSet)
         self.assertTrue(verifyObject(ITranslationSideTraitsSet, utility))
-        for traits in six.itervalues(utility.getAllTraits()):
+        for traits in utility.getAllTraits().values():
             self.assertTrue(verifyObject(ITranslationSideTraits, traits))
 
     def test_other_sides(self):
@@ -63,7 +62,7 @@ class TestTranslationSideTraitsSet(TestCaseWithFactory):
             [TranslationSide.UPSTREAM, TranslationSide.UBUNTU],
             traits_dict.keys())
 
-        for side, traits in six.iteritems(traits_dict):
+        for side, traits in traits_dict.items():
             self.assertEqual(side, traits.side)
             self.assertEqual(traits, utility.getTraits(side))
 
diff --git a/lib/lp/translations/tests/test_suggestions.py b/lib/lp/translations/tests/test_suggestions.py
index f038e6d..d6bcd16 100644
--- a/lib/lp/translations/tests/test_suggestions.py
+++ b/lib/lp/translations/tests/test_suggestions.py
@@ -26,7 +26,7 @@ class TestTranslationSuggestions(TestCaseWithFactory):
 
     def setUp(self):
         """Set up context to test in."""
-        super(TestTranslationSuggestions, self).setUp()
+        super().setUp()
 
         # Pretend we have two products Foo and Bar being translated.
         # Translations used or suggested in the one may show up as
diff --git a/lib/lp/translations/tests/test_translationbranchapprover.py b/lib/lp/translations/tests/test_translationbranchapprover.py
index 8460ed2..e98d5ea 100644
--- a/lib/lp/translations/tests/test_translationbranchapprover.py
+++ b/lib/lp/translations/tests/test_translationbranchapprover.py
@@ -26,7 +26,7 @@ class TestTranslationBranchApprover(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestTranslationBranchApprover, self).setUp()
+        super().setUp()
         self.useFixture(FakeLibrarian())
         self.queue = getUtility(ITranslationImportQueue)
         self.series = self.factory.makeProductSeries()
@@ -56,7 +56,7 @@ class TestTranslationBranchApprover(TestCaseWithFactory):
 
     def test_new_template_approved(self):
         # The approver puts new entries in the Approved state.
-        template_path = self.factory.getUniqueUnicode() + u'.pot'
+        template_path = self.factory.getUniqueUnicode() + '.pot'
         entry = self._upload_file(template_path)
         self.assertEqual(RosettaImportStatus.NEEDS_REVIEW, entry.status)
         self._createApprover(template_path).approve(entry)
@@ -66,7 +66,7 @@ class TestTranslationBranchApprover(TestCaseWithFactory):
         # When a template upload for a project has a generic path, it
         # can still be approved.  The template will have a name and
         # domain based on the project's name.
-        template_path = u'messages.pot'
+        template_path = 'messages.pot'
         entry = self._upload_file(template_path)
         self._createApprover(template_path).approve(entry)
         self.assertEqual(RosettaImportStatus.APPROVED, entry.status)
@@ -94,7 +94,7 @@ class TestTranslationBranchApprover(TestCaseWithFactory):
 
     def test_new_template_not_a_template(self):
         # Only template files will be approved currently.
-        path = u'eo.po'
+        path = 'eo.po'
         entry = self._upload_file(path)
         self._createApprover(path).approve(entry)
         self.assertEqual(RosettaImportStatus.NEEDS_REVIEW, entry.status)
@@ -103,7 +103,7 @@ class TestTranslationBranchApprover(TestCaseWithFactory):
         # The approver gets the translation domain for the entry from the
         # file path if possible.
         translation_domain = self.factory.getUniqueUnicode()
-        template_path = translation_domain + u'.pot'
+        template_path = translation_domain + '.pot'
         entry = self._upload_file(template_path)
         self._createApprover(template_path).approve(entry)
         self.assertEqual(
@@ -111,18 +111,18 @@ class TestTranslationBranchApprover(TestCaseWithFactory):
 
     def test_template_name(self):
         # The name is derived from the file name and must be a valid name.
-        translation_domain = (u'Invalid-Name_with illegal#Characters')
-        template_path = translation_domain + u'.pot'
+        translation_domain = ('Invalid-Name_with illegal#Characters')
+        template_path = translation_domain + '.pot'
         entry = self._upload_file(template_path)
         self._createApprover(template_path).approve(entry)
         self.assertTrue(valid_name(entry.potemplate.name))
-        self.assertEqual(u'invalid-name-withillegalcharacters',
+        self.assertEqual('invalid-name-withillegalcharacters',
                          entry.potemplate.name)
 
     def test_replace_existing_approved(self):
         # Template files that replace existing entries are approved.
         translation_domain = self.factory.getUniqueUnicode()
-        template_path = translation_domain + u'.pot'
+        template_path = translation_domain + '.pot'
         self._createTemplate(template_path, translation_domain)
         entry = self._upload_file(template_path)
         self._createApprover(template_path).approve(entry)
@@ -132,7 +132,7 @@ class TestTranslationBranchApprover(TestCaseWithFactory):
         # When replacing an existing template, the queue entry is linked
         # to that existing entry.
         translation_domain = self.factory.getUniqueUnicode()
-        template_path = translation_domain + u'.pot'
+        template_path = translation_domain + '.pot'
         potemplate = self._createTemplate(template_path, translation_domain)
         entry = self._upload_file(template_path)
         self._createApprover(template_path).approve(entry)
@@ -142,7 +142,7 @@ class TestTranslationBranchApprover(TestCaseWithFactory):
         # When replacing an existing inactive template, the entry is not
         # approved and no template is created for it.
         translation_domain = self.factory.getUniqueUnicode()
-        template_path = translation_domain + u'.pot'
+        template_path = translation_domain + '.pot'
         potemplate = self._createTemplate(template_path, translation_domain)
         potemplate.setActive(False)
         entry = self._upload_file(template_path)
@@ -154,9 +154,9 @@ class TestTranslationBranchApprover(TestCaseWithFactory):
         # If just one template file is found in the tree and just one
         # POTemplate is in the database, the upload is always approved.
         existing_domain = self.factory.getUniqueUnicode()
-        existing_path = existing_domain + u'.pot'
+        existing_path = existing_domain + '.pot'
         potemplate = self._createTemplate(existing_path, existing_domain)
-        template_path = self.factory.getUniqueUnicode() + u'.pot'
+        template_path = self.factory.getUniqueUnicode() + '.pot'
         entry = self._upload_file(template_path)
         self._createApprover(template_path).approve(entry)
         self.assertEqual(RosettaImportStatus.APPROVED, entry.status)
@@ -167,7 +167,7 @@ class TestTranslationBranchApprover(TestCaseWithFactory):
         # translation domain, it is still approved if an entry with the
         # same file name exists.
         translation_domain = self.factory.getUniqueUnicode()
-        generic_path = u'po/messages.pot'
+        generic_path = 'po/messages.pot'
         self._createTemplate(generic_path, translation_domain)
         entry = self._upload_file(generic_path)
         self._createApprover(generic_path).approve(entry)
@@ -179,7 +179,7 @@ class TestTranslationBranchApprover(TestCaseWithFactory):
         # but matches that of an existing template, even though the
         # entry gets approved for import into that template, the
         # existing template's domain name stays as it was.
-        generic_path = u'po/messages.pot'
+        generic_path = 'po/messages.pot'
 
         package = self.factory.makeSourcePackage()
         package_kwargs = {
@@ -200,10 +200,10 @@ class TestTranslationBranchApprover(TestCaseWithFactory):
         # When adding a template to an existing one it is approved if the
         # approver is told about both template files in the tree.
         existing_domain = self.factory.getUniqueUnicode()
-        existing_path = u"%s/%s.pot" % (existing_domain, existing_domain)
+        existing_path = "%s/%s.pot" % (existing_domain, existing_domain)
         self._createTemplate(existing_path, existing_domain)
         new_domain = self.factory.getUniqueUnicode()
-        new_path = u"%s/%s.pot" % (new_domain, new_domain)
+        new_path = "%s/%s.pot" % (new_domain, new_domain)
         entry = self._upload_file(new_path)
         self._createApprover((existing_path, new_path)).approve(entry)
         self.assertEqual(RosettaImportStatus.APPROVED, entry.status)
diff --git a/lib/lp/translations/tests/test_translationbuildapprover.py b/lib/lp/translations/tests/test_translationbuildapprover.py
index 1b61cb3..f43d0eb 100644
--- a/lib/lp/translations/tests/test_translationbuildapprover.py
+++ b/lib/lp/translations/tests/test_translationbuildapprover.py
@@ -21,7 +21,7 @@ class TestTranslationBuildApprover(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestTranslationBuildApprover, self).setUp()
+        super().setUp()
         self.queue = getUtility(ITranslationImportQueue)
         self.uploader = self.factory.makePerson()
 
diff --git a/lib/lp/translations/tests/test_translationimportqueue.py b/lib/lp/translations/tests/test_translationimportqueue.py
index 23cadd7..671195a 100644
--- a/lib/lp/translations/tests/test_translationimportqueue.py
+++ b/lib/lp/translations/tests/test_translationimportqueue.py
@@ -51,7 +51,7 @@ class TestCanSetStatusBase:
 
     def setUp(self):
         """Set up context to test in."""
-        super(TestCanSetStatusBase, self).setUp()
+        super().setUp()
 
         self.queue = getUtility(ITranslationImportQueue)
         self.rosetta_experts = (
@@ -187,7 +187,7 @@ class TestCanSetStatusPOTemplate(TestCanSetStatusBase, TestCaseWithFactory):
 
     def setUp(self):
         """Create the entry to test on."""
-        super(TestCanSetStatusPOTemplate, self).setUp()
+        super().setUp()
 
         self.potemplate = self.factory.makePOTemplate(
             productseries=self.productseries)
@@ -201,7 +201,7 @@ class TestCanSetStatusPOFile(TestCanSetStatusBase, TestCaseWithFactory):
 
     def setUp(self):
         """Create the entry to test on."""
-        super(TestCanSetStatusPOFile, self).setUp()
+        super().setUp()
 
         self.potemplate = self.factory.makePOTemplate(
             productseries=self.productseries)
@@ -245,7 +245,7 @@ class TestGetGuessedPOFile(TestCaseWithFactory):
 
     def setUp(self):
         """Set up context to test in."""
-        super(TestGetGuessedPOFile, self).setUp()
+        super().setUp()
         self.queue = getUtility(ITranslationImportQueue)
         self.factory = LaunchpadObjectFactory()
         self.distribution = self.factory.makeDistribution('boohoo')
@@ -340,7 +340,7 @@ class TestProductOwnerEntryImporter(TestCaseWithFactory):
     layer = LaunchpadFunctionalLayer
 
     def setUp(self):
-        super(TestProductOwnerEntryImporter, self).setUp()
+        super().setUp()
         self.product = self.factory.makeProduct()
         self.old_owner = self.product.owner
         self.new_owner = self.factory.makePerson()
@@ -352,7 +352,7 @@ class TestProductOwnerEntryImporter(TestCaseWithFactory):
         # Changing the Product owner also updates the importer of the entry.
         with person_logged_in(self.old_owner):
             entry = self.import_queue.addOrUpdateEntry(
-                u'po/sr.po', b'foo', True, self.old_owner,
+                'po/sr.po', b'foo', True, self.old_owner,
                 productseries=self.product.series[0])
             self.product.owner = self.new_owner
         self.assertEqual(self.new_owner, entry.importer)
@@ -363,11 +363,11 @@ class TestProductOwnerEntryImporter(TestCaseWithFactory):
         # cause an non-unique key for the entry.
         with person_logged_in(self.new_owner):
             self.import_queue.addOrUpdateEntry(
-                u'po/sr.po', b'foo', True, self.new_owner,
+                'po/sr.po', b'foo', True, self.new_owner,
                 productseries=self.product.series[0])
         with person_logged_in(self.old_owner):
             old_entry = self.import_queue.addOrUpdateEntry(
-                u'po/sr.po', b'foo', True, self.old_owner,
+                'po/sr.po', b'foo', True, self.old_owner,
                 productseries=self.product.series[0])
             self.product.owner = self.new_owner
         self.assertEqual(self.old_owner, old_entry.importer)
@@ -379,7 +379,7 @@ class TestTranslationImportQueue(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestTranslationImportQueue, self).setUp()
+        super().setUp()
         self.productseries = self.factory.makeProductSeries()
         self.importer = self.factory.makePerson()
         self.import_queue = getUtility(ITranslationImportQueue)
diff --git a/lib/lp/translations/tests/test_translationmerger.py b/lib/lp/translations/tests/test_translationmerger.py
index 1eb095b..b89898a 100644
--- a/lib/lp/translations/tests/test_translationmerger.py
+++ b/lib/lp/translations/tests/test_translationmerger.py
@@ -65,9 +65,9 @@ class TestPOTMsgSetMerging(TestCaseWithFactory, TranslatableProductMixin):
         # This test needs the privileges of rosettaadmin (to delete
         # POTMsgSets) but it also needs to set up test conditions which
         # requires other privileges.
-        super(TestPOTMsgSetMerging, self).setUp(user=ADMIN_EMAIL)
+        super().setUp(user=ADMIN_EMAIL)
         self.becomeDbUser('postgres')
-        super(TestPOTMsgSetMerging, self).setUpProduct()
+        super().setUpProduct()
 
     def test_matchedPOTMsgSetsShare(self):
         # Two identically-keyed POTMsgSets will share.  Where two
@@ -145,7 +145,7 @@ class TranslatedProductMixin(TranslatableProductMixin):
     """
 
     def setUpProduct(self):
-        super(TranslatedProductMixin, self).setUpProduct()
+        super().setUpProduct()
 
         self.trunk_potmsgset = self.factory.makePOTMsgSet(
             self.trunk_template, singular='foo')
@@ -254,10 +254,9 @@ class TestPOTMsgSetMergingAndTranslations(TestCaseWithFactory,
         The matching POTMsgSets will be merged by the mergePOTMsgSets
         call.
         """
-        super(TestPOTMsgSetMergingAndTranslations, self).setUp(
-            user=ADMIN_EMAIL)
+        super().setUp(user=ADMIN_EMAIL)
         self.becomeDbUser('postgres')
-        super(TestPOTMsgSetMergingAndTranslations, self).setUpProduct()
+        super().setUpProduct()
 
     def test_sharingDivergedMessages(self):
         # Diverged TranslationMessages stay with their respective
@@ -375,9 +374,9 @@ class TestTranslationMessageNonMerging(TestCaseWithFactory,
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestTranslationMessageNonMerging, self).setUp(user=ADMIN_EMAIL)
+        super().setUp(user=ADMIN_EMAIL)
         self.becomeDbUser('postgres')
-        super(TestTranslationMessageNonMerging, self).setUpProduct()
+        super().setUpProduct()
 
     def test_MessagesAreNotSharedAcrossPOTMsgSets(self):
         # Merging TranslationMessages does not merge messages that
@@ -402,9 +401,9 @@ class TestTranslationMessageMerging(TestCaseWithFactory,
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestTranslationMessageMerging, self).setUp(user=ADMIN_EMAIL)
+        super().setUp(user=ADMIN_EMAIL)
         self.becomeDbUser('postgres')
-        super(TestTranslationMessageMerging, self).setUpProduct()
+        super().setUpProduct()
 
     def test_messagesCanStayDiverged(self):
         # When POTMsgSets with diverged translations are merged, the
@@ -512,9 +511,9 @@ class TestRemoveDuplicates(TestCaseWithFactory, TranslatedProductMixin):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestRemoveDuplicates, self).setUp(user=ADMIN_EMAIL)
+        super().setUp(user=ADMIN_EMAIL)
         self.becomeDbUser('postgres')
-        super(TestRemoveDuplicates, self).setUpProduct()
+        super().setUpProduct()
 
     def test_duplicatesAreCleanedUp(self):
         # The duplicates removal function cleans up any duplicate
@@ -684,9 +683,9 @@ class TestSharingMigrationPerformance(TestCaseWithFactory,
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestSharingMigrationPerformance, self).setUp()
+        super().setUp()
         self.becomeDbUser('postgres')
-        super(TestSharingMigrationPerformance, self).setUpProduct()
+        super().setUpProduct()
 
     def _flushDbObjects(self):
         """Flush ORM-backed objects from memory as much as possible.
@@ -756,7 +755,7 @@ class TestFindMergablePackagings(TestCaseWithFactory):
 
     def setUp(self):
         """Remove sample data to simplify tests."""
-        super(TestFindMergablePackagings, self).setUp()
+        super().setUp()
         for packaging in set(TranslationMerger.findMergeablePackagings()):
             with person_logged_in(packaging.owner):
                 packaging.destroySelf()
diff --git a/lib/lp/translations/tests/test_translationmessage.py b/lib/lp/translations/tests/test_translationmessage.py
index 8f2e041..d8c382e 100644
--- a/lib/lp/translations/tests/test_translationmessage.py
+++ b/lib/lp/translations/tests/test_translationmessage.py
@@ -431,7 +431,7 @@ class TestAcceptFromUpstreamImportOnPackage(TestCaseWithFactory):
 
     def setUp(self):
         """Every test needs a `POFile` and a `POTMsgSet`."""
-        super(TestAcceptFromUpstreamImportOnPackage, self).setUp()
+        super().setUp()
         self.pofile, self.potmsgset = self.factory.makePOFileAndPOTMsgSet(
             side=TranslationSide.UBUNTU)
 
@@ -829,7 +829,7 @@ class TestTranslationMessageFindIdenticalMessage(TestCaseWithFactory):
         translation message in various ways and then try to find it by
         calling findIdenticalMessage on the first one.
         """
-        super(TestTranslationMessageFindIdenticalMessage, self).setUp()
+        super().setUp()
         self.product = self.factory.makeProduct()
         self.trunk = self.product.getSeries('trunk')
         self.template = self.factory.makePOTemplate(
diff --git a/lib/lp/translations/tests/test_translationpolicy.py b/lib/lp/translations/tests/test_translationpolicy.py
index 8ec8361..89f3ee9 100644
--- a/lib/lp/translations/tests/test_translationpolicy.py
+++ b/lib/lp/translations/tests/test_translationpolicy.py
@@ -35,7 +35,7 @@ class TestTranslationPolicy(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestTranslationPolicy, self).setUp()
+        super().setUp()
         self.policy = TranslationPolicyImplementation()
 
     def _makeParentPolicy(self):
@@ -328,7 +328,7 @@ class TestTranslationsOwners(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestTranslationsOwners, self).setUp()
+        super().setUp()
         self.owner = self.factory.makePerson()
 
     def isTranslationsOwnerOf(self, pillar):
@@ -372,7 +372,7 @@ class TestSharingPolicy(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestSharingPolicy, self).setUp()
+        super().setUp()
         self.user = self.factory.makePerson()
         self.language = self.factory.makeLanguage()
 
diff --git a/lib/lp/translations/tests/test_translations_to_review.py b/lib/lp/translations/tests/test_translations_to_review.py
index 2991854..1008677 100644
--- a/lib/lp/translations/tests/test_translations_to_review.py
+++ b/lib/lp/translations/tests/test_translations_to_review.py
@@ -158,7 +158,7 @@ class TestReviewableProductTranslationFiles(TestCaseWithFactory,
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestReviewableProductTranslationFiles, self).setUp()
+        super().setUp()
         ReviewTestMixin.setUpMixin(self, for_product=True)
 
     def test_getReviewableTranslationFiles_project_deactivated(self):
@@ -176,5 +176,5 @@ class TestReviewableDistroTranslationFiles(TestCaseWithFactory,
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestReviewableDistroTranslationFiles, self).setUp()
+        super().setUp()
         ReviewTestMixin.setUpMixin(self, for_product=False)
diff --git a/lib/lp/translations/tests/test_translationtemplatesbuild.py b/lib/lp/translations/tests/test_translationtemplatesbuild.py
index 5152459..0ff78e8 100644
--- a/lib/lp/translations/tests/test_translationtemplatesbuild.py
+++ b/lib/lp/translations/tests/test_translationtemplatesbuild.py
@@ -60,13 +60,13 @@ class TestTranslationTemplatesBuild(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestTranslationTemplatesBuild, self).setUp()
+        super().setUp()
         self.jobsource = FakeTranslationTemplatesSource
         self.jobsource.fake_pottery_compabitility = None
 
     def tearDown(self):
         self._fakePotteryCompatibleSetup(compatible=None)
-        super(TestTranslationTemplatesBuild, self).tearDown()
+        super().tearDown()
 
     def _makeTranslationBranch(self, fake_pottery_compatible=None):
         """Create a branch that provides translations for a productseries."""
diff --git a/lib/lp/translations/tests/test_translationtemplatesbuildbehaviour.py b/lib/lp/translations/tests/test_translationtemplatesbuildbehaviour.py
index fc1a712..4cca2fa 100644
--- a/lib/lp/translations/tests/test_translationtemplatesbuildbehaviour.py
+++ b/lib/lp/translations/tests/test_translationtemplatesbuildbehaviour.py
@@ -53,7 +53,7 @@ class FakeBuildQueue:
         self.destroySelf = FakeMethod()
 
 
-class MakeBehaviourMixin(object):
+class MakeBehaviourMixin:
     """Provide common test methods."""
 
     def makeBehaviour(self, branch=None, use_fake_chroot=True, **kwargs):
@@ -90,7 +90,7 @@ class TestTranslationTemplatesBuildBehaviour(
     run_tests_with = AsynchronousDeferredRunTest
 
     def setUp(self):
-        super(TestTranslationTemplatesBuildBehaviour, self).setUp()
+        super().setUp()
         self.worker_helper = self.useFixture(WorkerTestHelpers())
 
     def test_getLogFileName(self):
@@ -141,7 +141,7 @@ class TestTranslationTemplatesBuildBehaviour(
         behaviour._slave.valid_files[path] = ''
 
         def got_tarball(filename):
-            tarball = open(filename, 'r')
+            tarball = open(filename)
             try:
                 self.assertEqual(
                     "This is a %s" % path, tarball.read())
@@ -287,7 +287,7 @@ class TestTTBuildBehaviourTranslationsQueue(
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestTTBuildBehaviourTranslationsQueue, self).setUp()
+        super().setUp()
 
         self.queue = getUtility(ITranslationImportQueue)
         self.dummy_tar = os.path.join(
diff --git a/lib/lp/translations/utilities/gettext_po_exporter.py b/lib/lp/translations/utilities/gettext_po_exporter.py
index 2669899..1bc5658 100644
--- a/lib/lp/translations/utilities/gettext_po_exporter.py
+++ b/lib/lp/translations/utilities/gettext_po_exporter.py
@@ -54,22 +54,22 @@ def comments_text_representation(translation_message):
         for line in unparsed_comment.split('\n'):
             if line.startswith('|'):
                 if translation_message.is_obsolete:
-                    comment_prefix = u'#~'
+                    comment_prefix = '#~'
                 else:
-                    comment_prefix = u'#'
+                    comment_prefix = '#'
                 comment_lines_previous_msgids.append(comment_prefix + line)
             else:
-                comment_lines.append(u'#' + line)
+                comment_lines.append('#' + line)
     if not translation_message.is_obsolete:
         # Source comments are only exported if it's not an obsolete entry.
         if translation_message.source_comment:
             unparsed_comment = (
                 strip_last_newline(translation_message.source_comment))
             for line in unparsed_comment.split('\n'):
-                comment_lines.append(u'#. ' + line)
+                comment_lines.append('#. ' + line)
         if translation_message.file_references:
             for line in translation_message.file_references.split('\n'):
-                comment_lines.append(u'#: ' + line)
+                comment_lines.append('#: ' + line)
     if translation_message.flags:
         flags = sorted(translation_message.flags)
         if 'fuzzy' in flags:
@@ -77,9 +77,9 @@ def comments_text_representation(translation_message):
             # tools do.
             flags.remove('fuzzy')
             flags.insert(0, 'fuzzy')
-        comment_lines.append(u'#, %s' % u', '.join(flags))
+        comment_lines.append('#, %s' % ', '.join(flags))
 
-    return u'\n'.join(comment_lines + comment_lines_previous_msgids)
+    return '\n'.join(comment_lines + comment_lines_previous_msgids)
 
 
 def wrap_text(text, prefix, wrap_width):
@@ -105,11 +105,11 @@ def wrap_text(text, prefix, wrap_width):
     """
 
     def local_escape(text):
-        ret = text.replace(u'\\', u'\\\\')
-        ret = ret.replace(u'"', u'\\"')
-        ret = ret.replace(u'\t', u'\\t')
-        ret = ret.replace(u'\r', u'\\r')
-        return ret.replace(u'\n', u'\\n')
+        ret = text.replace('\\', '\\\\')
+        ret = ret.replace('"', '\\"')
+        ret = ret.replace('\t', '\\t')
+        ret = ret.replace('\r', '\\r')
+        return ret.replace('\n', '\\n')
 
     # Quickly get escaped character byte widths using
     #   escaped_length.get(char, 1).
@@ -126,12 +126,12 @@ def wrap_text(text, prefix, wrap_width):
 
     if wrap_width is None:
         raise AssertionError('wrap_width should not be None')
-    wrapped_lines = [u'%s%s' % (prefix, u' ""')]
+    wrapped_lines = ['%s%s' % (prefix, ' ""')]
     if not text:
         return wrapped_lines
     if '\n' not in text[:-1]:
         # Either there are no new-lines, or it's at the end of string.
-        unwrapped_line = u'%s "%s"' % (prefix, local_escape(text))
+        unwrapped_line = '%s "%s"' % (prefix, local_escape(text))
         if len(unwrapped_line) <= wrap_width:
             return [unwrapped_line]
         del unwrapped_line
@@ -147,9 +147,9 @@ def wrap_text(text, prefix, wrap_width):
         if len(local_escape(paragraph)) <= wrap_width:
             wrapped_line = [paragraph]
         else:
-            line = u''
+            line = ''
             escaped_line_len = 0
-            new_block = u''
+            new_block = ''
             escaped_new_block_len = 0
             wrapped_line = []
             for char in paragraph:
@@ -157,10 +157,10 @@ def wrap_text(text, prefix, wrap_width):
                 if (escaped_line_len + escaped_new_block_len
                     + escaped_char_len <= wrap_width):
                     if char in wrap_at:
-                        line += u'%s%s' % (new_block, char)
+                        line += '%s%s' % (new_block, char)
                         escaped_line_len += (escaped_new_block_len
                                              + escaped_char_len)
-                        new_block = u''
+                        new_block = ''
                         escaped_new_block_len = 0
                     else:
                         new_block += char
@@ -181,14 +181,14 @@ def wrap_text(text, prefix, wrap_width):
                         new_block = new_block[line_len:]
                         escaped_new_block_len -= escaped_line_len
                     wrapped_line.append(line)
-                    line = u''
+                    line = ''
                     escaped_line_len = 0
                     new_block += char
                     escaped_new_block_len += escaped_char_len
             if line or new_block:
-                wrapped_line.append(u'%s%s' % (line, new_block))
+                wrapped_line.append('%s%s' % (line, new_block))
         for line in wrapped_line:
-            wrapped_lines.append(u'"%s"' % (local_escape(line)))
+            wrapped_lines.append('"%s"' % (local_escape(line)))
     return wrapped_lines
 
 
@@ -202,19 +202,19 @@ def msgid_text_representation(translation_message, wrap_width):
     text = []
     if translation_message.context is not None:
         text.extend(
-            wrap_text(translation_message.context, u'msgctxt', wrap_width))
+            wrap_text(translation_message.context, 'msgctxt', wrap_width))
     text.extend(
-        wrap_text(translation_message.msgid_singular, u'msgid', wrap_width))
+        wrap_text(translation_message.msgid_singular, 'msgid', wrap_width))
     if translation_message.msgid_plural:
         # This message has a plural form that we must export.
         text.extend(
             wrap_text(
-                translation_message.msgid_plural, u'msgid_plural',
+                translation_message.msgid_plural, 'msgid_plural',
                 wrap_width))
     if translation_message.is_obsolete:
         text = ['#~ ' + line for line in text]
 
-    return u'\n'.join(text)
+    return '\n'.join(text)
 
 
 def translation_text_representation(translation_message, wrap_width):
@@ -228,30 +228,30 @@ def translation_text_representation(translation_message, wrap_width):
     if translation_message.msgid_plural:
         # It's a message with plural forms.
         for i, translation in enumerate(translation_message.translations):
-            text.extend(wrap_text(translation, u'msgstr[%s]' % i, wrap_width))
+            text.extend(wrap_text(translation, 'msgstr[%s]' % i, wrap_width))
 
         if len(text) == 0:
             # We don't have any translation for it.
-            text = [u'msgstr[0] ""', u'msgstr[1] ""']
+            text = ['msgstr[0] ""', 'msgstr[1] ""']
     else:
         # It's a message without plural form.
         if translation_message.translations:
             translation = translation_message.translations[
                 TranslationConstants.SINGULAR_FORM]
-            text = wrap_text(translation, u'msgstr', wrap_width)
+            text = wrap_text(translation, 'msgstr', wrap_width)
         else:
-            text = [u'msgstr ""']
+            text = ['msgstr ""']
 
     if translation_message.is_obsolete:
         text = ['#~ ' + line for line in text]
 
-    return u'\n'.join(text)
+    return '\n'.join(text)
 
 
 def export_translation_message(translation_message, wrap_width=77):
     """Return a text representing translation_message.
     """
-    return u'\n'.join([
+    return '\n'.join([
         comments_text_representation(translation_message),
         msgid_text_representation(translation_message, wrap_width),
         translation_text_representation(translation_message, wrap_width),
@@ -290,7 +290,7 @@ class GettextPOExporterBase:
         """Try to encode the file using the charset given in the header."""
         file_content = (
             self._makeExportedHeader(translation_file) +
-            u'\n\n' +
+            '\n\n' +
             exported_content)
         encoded_file_content = file_content.encode(
             translation_file.header.charset)
@@ -343,7 +343,7 @@ class GettextPOExporterBase:
             chunks.append(self.exportTranslationMessageData(message))
 
         # Gettext .po files are supposed to end with a new line.
-        exported_file_content = u'\n\n'.join(chunks) + u'\n'
+        exported_file_content = '\n\n'.join(chunks) + '\n'
 
         # Try to encode the file
         if force_utf8:
@@ -411,12 +411,12 @@ class GettextPOChangedExporter(GettextPOExporterBase):
     """Support class to export changed Gettext .po files."""
 
     exported_header = (
-        u"# IMPORTANT: This file does NOT contain a complete PO file "
-            u"structure.\n"
-        u"# DO NOT attempt to import this file back into Launchpad.\n\n"
-        u"# This file is a partial export from Launchpad.net.\n"
-        u"# See https://help.launchpad.net/Translations/PartialPOExport\n";
-        u"# for more information.")
+        "# IMPORTANT: This file does NOT contain a complete PO file "
+            "structure.\n"
+        "# DO NOT attempt to import this file back into Launchpad.\n\n"
+        "# This file is a partial export from Launchpad.net.\n"
+        "# See https://help.launchpad.net/Translations/PartialPOExport\n";
+        "# for more information.")
 
     def __init__(self, context=None):
         # 'context' is ignored because it's only required by the way the
diff --git a/lib/lp/translations/utilities/gettext_po_parser.py b/lib/lp/translations/utilities/gettext_po_parser.py
index fcd2305..5447376 100644
--- a/lib/lp/translations/utilities/gettext_po_parser.py
+++ b/lib/lp/translations/utilities/gettext_po_parser.py
@@ -42,7 +42,6 @@ from lp.translations.utilities.translation_common_format import (
     )
 
 
-@six.python_2_unicode_compatible
 class POSyntaxWarning(Warning):
     """Syntax warning in a PO file."""
     def __init__(self, message, line_number=None):
@@ -151,7 +150,7 @@ class POHeader:
 
     def _emitSyntaxWarning(self, message):
         """Issue syntax warning, add to warnings list."""
-        self.syntax_warnings.append(six.text_type(POSyntaxWarning(message)))
+        self.syntax_warnings.append(str(POSyntaxWarning(message)))
 
     def _getHeaderDict(self, raw_header):
         """Return dictionary with all keys in raw_header.
@@ -184,7 +183,7 @@ class POHeader:
         return header_dictionary
 
     def _decode(self, text):
-        if text is None or isinstance(text, six.text_type):
+        if text is None or isinstance(text, str):
             # There is noo need to do anything.
             return text
         charset = self.charset
@@ -231,7 +230,7 @@ class POHeader:
 
     def _parseHeaderFields(self):
         """Return plural form values based on the parsed header."""
-        for key, value in six.iteritems(self._header_dictionary):
+        for key, value in self._header_dictionary.items():
             if key == 'plural-forms':
                 parts = self._parseAssignments(value)
                 nplurals = parts.get('nplurals')
@@ -363,14 +362,14 @@ class POHeader:
                 raise AssertionError('key %s is not being handled!' % value)
 
         # Now, we copy any other header information in the original .po file.
-        for key, value in six.iteritems(self._header_dictionary):
+        for key, value in self._header_dictionary.items():
             if key in self._handled_keys_mapping:
                 # It's already handled, skip it.
                 continue
 
             raw_content_list.append('%s: %s\n' % (key, value.strip()))
 
-        return u''.join(raw_content_list)
+        return ''.join(raw_content_list)
 
     def updateFromTemplateHeader(self, template_header):
         """See `ITranslationHeaderData`."""
@@ -410,8 +409,8 @@ class POHeader:
         assert email is not None, 'Email address cannot be None'
 
         if name is None:
-            name = u''
-        self._last_translator = u'%s <%s>' % (name, email)
+            name = ''
+        self._last_translator = '%s <%s>' % (name, email)
 
     def _renderDate(self, date, default=None):
         """Return string representation of `date`, or `default`."""
@@ -441,7 +440,7 @@ ESCAPE_MAP = {
 STRAIGHT_TEXT_RUN = re.compile('[^"\\\\]*')
 
 
-class POParser(object):
+class POParser:
     """Parser class for Gettext files."""
 
     def __init__(self, plural_formula=None):
@@ -459,8 +458,7 @@ class POParser(object):
     def _emitSyntaxWarning(self, message):
         warning = POSyntaxWarning(message, line_number=self._lineno)
         if self._translation_file:
-            self._translation_file.syntax_warnings.append(
-                six.text_type(warning))
+            self._translation_file.syntax_warnings.append(str(warning))
 
     def _decode(self):
         # is there anything to convert?
@@ -522,14 +520,14 @@ class POParser(object):
         self._translation_file = TranslationFileData()
         self._messageids = set()
         self._pending_chars = content_bytes
-        self._pending_unichars = u''
+        self._pending_unichars = ''
         self._lineno = 0
         # Message specific variables.
         self._message = TranslationMessageData()
         self._message_lineno = self._lineno
         self._section = None
         self._plural_case = None
-        self._parsed_content = u''
+        self._parsed_content = ''
 
         # First thing to do is to get the charset used in the content_bytes.
         charset = parse_charset(content_bytes)
@@ -611,7 +609,7 @@ class POParser(object):
                 # Fill the others with an empty string.
                 for index in range(
                     len(self._message.translations), number_plural_forms):
-                    self._message.addTranslation(index, u'')
+                    self._message.addTranslation(index, '')
 
             self._translation_file.messages.append(self._message)
             self._messageids.add(msgkey)
@@ -886,7 +884,7 @@ class POParser(object):
         else:
             raise AssertionError('Unknown section %s' % self._section)
 
-        self._parsed_content = u''
+        self._parsed_content = ''
 
     def _parseFreshLine(self, line, original_line):
         """Parse a new line (not a continuation after escaped newline).
@@ -933,7 +931,7 @@ class POParser(object):
             self._message_lineno = self._lineno
             self._section = None
             self._plural_case = None
-            self._parsed_content = u''
+            self._parsed_content = ''
 
         if self._message is not None:
             # Record whether the message is obsolete.
diff --git a/lib/lp/translations/utilities/kde_po_exporter.py b/lib/lp/translations/utilities/kde_po_exporter.py
index 825de52..c77e904 100644
--- a/lib/lp/translations/utilities/kde_po_exporter.py
+++ b/lib/lp/translations/utilities/kde_po_exporter.py
@@ -35,7 +35,7 @@ class KdePOExporter(GettextPOExporter):
     format = TranslationFileFormat.KDEPO
 
     def __init__(self, context=None):
-        super(KdePOExporter, self).__init__(context=context)
+        super().__init__(context=context)
         # See GettextPOExporter.__init__ for explanation of `context`.
         self.format = TranslationFileFormat.KDEPO
         # KdePOExporter is also able to export `TranslationFileFormat.PO`,
@@ -48,7 +48,7 @@ class KdePOExporter(GettextPOExporter):
         # Special handling of context and plural forms.
         if translation_message.context is not None:
             # Let's turn context messages into legacy KDE context.
-            translation_message.msgid_singular = u"_: %s\n%s" % (
+            translation_message.msgid_singular = "_: %s\n%s" % (
                 translation_message.context,
                 translation_message.msgid_singular)
             translation_message.context = None
@@ -59,7 +59,7 @@ class KdePOExporter(GettextPOExporter):
                 if translations[pluralform_index] is None:
                     translations[pluralform_index] = ''
             translation_message._translations = ["\n".join(translations)]
-            translation_message.msgid_singular = u"_n: %s\n%s" % (
+            translation_message.msgid_singular = "_n: %s\n%s" % (
                 translation_message.msgid_singular,
                 translation_message.msgid_plural)
             translation_message.msgid_plural = None
diff --git a/lib/lp/translations/utilities/kde_po_importer.py b/lib/lp/translations/utilities/kde_po_importer.py
index 4ef6cd7..15e5c8d 100644
--- a/lib/lp/translations/utilities/kde_po_importer.py
+++ b/lib/lp/translations/utilities/kde_po_importer.py
@@ -62,8 +62,8 @@ class KdePOImporter(GettextPOImporter):
         translation_file = GettextPOImporter.parse(
             self, translation_import_queue_entry)
 
-        plural_prefix = u'_n: '
-        context_prefix = u'_: '
+        plural_prefix = '_n: '
+        context_prefix = '_: '
 
         for message in translation_file.messages:
             msgid = message.msgid_singular
diff --git a/lib/lp/translations/utilities/pluralforms.py b/lib/lp/translations/utilities/pluralforms.py
index d329a5a..b0f7654 100644
--- a/lib/lp/translations/utilities/pluralforms.py
+++ b/lib/lp/translations/utilities/pluralforms.py
@@ -11,8 +11,6 @@ __all__ = [
 import gettext
 import re
 
-import six
-
 from lp.translations.interfaces.translations import TranslationConstants
 
 
@@ -48,7 +46,7 @@ def make_friendly_plural_forms(expression, expected_forms):
 
     return [
         {'form': form, 'examples': examples}
-        for (form, examples) in sorted(six.iteritems(forms))
+        for (form, examples) in sorted(forms.items())
         ]
 
 
diff --git a/lib/lp/translations/utilities/rosettastats.py b/lib/lp/translations/utilities/rosettastats.py
index 642ec25..34ffd86 100644
--- a/lib/lp/translations/utilities/rosettastats.py
+++ b/lib/lp/translations/utilities/rosettastats.py
@@ -10,7 +10,7 @@ from lp.translations.interfaces.rosettastats import IRosettaStats
 # This code should be change to be an adaptor.
 
 @implementer(IRosettaStats)
-class RosettaStats(object):
+class RosettaStats:
 
     def testStatistics(self):
         """See IRosettaStats."""
diff --git a/lib/lp/translations/utilities/sanitize.py b/lib/lp/translations/utilities/sanitize.py
index c620c68..e5cc6db 100644
--- a/lib/lp/translations/utilities/sanitize.py
+++ b/lib/lp/translations/utilities/sanitize.py
@@ -16,16 +16,16 @@ class MixedNewlineMarkersError(ValueError):
     """
 
 
-class Sanitizer(object):
+class Sanitizer:
     """Provide a function to sanitize a translation text."""
 
     # There are three different kinds of newlines:
-    windows_style = u'\r\n'
-    mac_style = u'\r'
-    unix_style = u'\n'
+    windows_style = '\r\n'
+    mac_style = '\r'
+    unix_style = '\n'
     mixed_style = object()
 
-    dot_char = u'\u2022'
+    dot_char = '\u2022'
 
     def __init__(self, english_singular):
         """Extract information from the English singular."""
@@ -54,7 +54,7 @@ class Sanitizer(object):
         # unix with the two-character windows one, remove the windows-style
         # newlines from the text and use that text to search for the other
         # two.
-        stripped_text = text.replace(cls.windows_style, u'')
+        stripped_text = text.replace(cls.windows_style, '')
         if text != stripped_text:
             # Text contains windows style new lines.
             style = cls.windows_style
@@ -109,7 +109,7 @@ class Sanitizer(object):
         if self.has_dots or self.dot_char not in translation_text:
             return translation_text
 
-        return translation_text.replace(u'\u2022', ' ')
+        return translation_text.replace('\u2022', ' ')
 
     def normalizeWhitespace(self, translation_text):
         """Return 'translation_text' with the same trailing and leading
diff --git a/lib/lp/translations/utilities/tests/test_file_importer.py b/lib/lp/translations/utilities/tests/test_file_importer.py
index 0925faa..d68e9c2 100644
--- a/lib/lp/translations/utilities/tests/test_file_importer.py
+++ b/lib/lp/translations/utilities/tests/test_file_importer.py
@@ -180,7 +180,7 @@ class FileImporterTestCase(TestCaseWithFactory):
         return FileImporter(template_entry, GettextPOImporter(), None)
 
     def setUp(self):
-        super(FileImporterTestCase, self).setUp()
+        super().setUp()
         self.fake_librarian = self.useFixture(FakeLibrarian())
         self.translation_import_queue = getUtility(ITranslationImportQueue)
         self.importer_person = self.factory.makePerson()
@@ -242,7 +242,7 @@ class FileImporterTestCase(TestCaseWithFactory):
 
         # Empty message to import.
         message = TranslationMessageData()
-        message.addTranslation(0, u'')
+        message.addTranslation(0, '')
 
         potmsgset = self.factory.makePOTMsgSet(
             potemplate=importer.potemplate, sequence=50)
@@ -425,7 +425,7 @@ class FileImporterTestCase(TestCaseWithFactory):
             "export timestamp (update conflict).")
         self.assertTrue(
             errors[0]['error-message'].find(
-                u"updated by someone else after you") != -1,
+                "updated by someone else after you") != -1,
             "importFile() failed to detect a message update conflict.")
 
     def test_FileImporter_importFile_error(self):
@@ -444,8 +444,8 @@ class FileImporterTestCase(TestCaseWithFactory):
             "No error detected when importing a pofile with mismatched "
             "format specifiers.")
         self.assertTrue(errors[0]['error-message'].find(
-                u"format specifications in 'msgid' and 'msgstr' "
-                u"for argument 1 are not the same") != -1,
+                "format specifications in 'msgid' and 'msgstr' "
+                "for argument 1 are not the same") != -1,
             "importFile() failed to detect mismatched format specifiers "
             "when importing a pofile.")
         # Although the message has an error, it should still be stored
@@ -523,7 +523,7 @@ class CreateFileImporterTestCase(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(CreateFileImporterTestCase, self).setUp()
+        super().setUp()
         self.fake_librarian = self.useFixture(FakeLibrarian())
         self.translation_import_queue = getUtility(ITranslationImportQueue)
         self.importer_person = self.factory.makePerson()
@@ -580,7 +580,7 @@ class FileImporterSharingTest(TestCaseWithFactory):
         """)
 
     def setUp(self):
-        super(FileImporterSharingTest, self).setUp()
+        super().setUp()
         # Create the upstream series and template with a translator.
         self.language = self.factory.makeLanguage()
         self.translator = self.factory.makeTranslator(self.language.code)
diff --git a/lib/lp/translations/utilities/tests/test_gettext_po_exporter.py b/lib/lp/translations/utilities/tests/test_gettext_po_exporter.py
index 99b8f9d..e08918f 100644
--- a/lib/lp/translations/utilities/tests/test_gettext_po_exporter.py
+++ b/lib/lp/translations/utilities/tests/test_gettext_po_exporter.py
@@ -204,7 +204,7 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
         def compare(self, pofile):
             "Compare the original text with the exported one."""
             # This is the word 'Japanese' in Japanese, in Unicode.
-            nihongo_unicode = u'\u65e5\u672c\u8a9e'
+            nihongo_unicode = '\u65e5\u672c\u8a9e'
             translation_file = self.parser.parse(pofile)
             translation_file.is_template = False
             translation_file.language_code = 'ja'
@@ -362,9 +362,9 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
         # first of the two messages is exported.
         template = self.factory.makePOTemplate()
         self.factory.makePOTMsgSet(
-            template, singular=u'%d foo', plural=u'%d foos', sequence=1)
+            template, singular='%d foo', plural='%d foos', sequence=1)
         self.factory.makePOTMsgSet(
-            template, singular=u'%d foo', plural=u'%d foox', sequence=2)
+            template, singular='%d foo', plural='%d foox', sequence=2)
 
         exported_file = template.export()
 
@@ -388,9 +388,9 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
         # non-obsolete one is exported.
         template = self.factory.makePOTemplate()
         obsolete_message = self.factory.makePOTMsgSet(
-            template, singular=u'%d goo', plural=u'%d goos', sequence=0)
+            template, singular='%d goo', plural='%d goos', sequence=0)
         current_message = self.factory.makePOTMsgSet(
-            template, singular=u'%d goo', plural=u'%d gooim', sequence=1)
+            template, singular='%d goo', plural='%d gooim', sequence=1)
 
         pofile = self.factory.makePOFile(
             potemplate=template, language_code='nl')
diff --git a/lib/lp/translations/utilities/tests/test_gettext_po_parser.py b/lib/lp/translations/utilities/tests/test_gettext_po_parser.py
index dc52b7a..252a7f8 100644
--- a/lib/lp/translations/utilities/tests/test_gettext_po_parser.py
+++ b/lib/lp/translations/utilities/tests/test_gettext_po_parser.py
@@ -288,18 +288,18 @@ class POBasicTestCase(unittest.TestCase):
         translation_file.header.plural_form_expression = 'random()'
         lines = translation_file.header.getRawContent().split('\n')
         expected = [
-            u'Project-Id-Version: PACKAGE VERSION',
-            u'Report-Msgid-Bugs-To:  ',
-            u'POT-Creation-Date: ...',
-            u'PO-Revision-Date: ...',
-            u'Last-Translator: FULL NAME <EMAIL@ADDRESS>',
-            u'Language-Team: LANGUAGE <LL@xxxxxx>',
-            u'MIME-Version: 1.0',
-            u'Content-Type: text/plain; charset=UTF-8',
-            u'Content-Transfer-Encoding: 8bit',
-            u'X-Launchpad-Export-Date: ...',
-            u'X-Generator: Launchpad (build ...)',
-            u'foo: bar'
+            'Project-Id-Version: PACKAGE VERSION',
+            'Report-Msgid-Bugs-To:  ',
+            'POT-Creation-Date: ...',
+            'PO-Revision-Date: ...',
+            'Last-Translator: FULL NAME <EMAIL@ADDRESS>',
+            'Language-Team: LANGUAGE <LL@xxxxxx>',
+            'MIME-Version: 1.0',
+            'Content-Type: text/plain; charset=UTF-8',
+            'Content-Transfer-Encoding: 8bit',
+            'X-Launchpad-Export-Date: ...',
+            'X-Generator: Launchpad (build ...)',
+            'foo: bar'
             ]
         for index in range(len(expected)):
             if lines[index].startswith('POT-Creation-Date'):
diff --git a/lib/lp/translations/utilities/tests/test_kde_po_importer.py b/lib/lp/translations/utilities/tests/test_kde_po_importer.py
index 06b321f..5f5abaf 100644
--- a/lib/lp/translations/utilities/tests/test_kde_po_importer.py
+++ b/lib/lp/translations/utilities/tests/test_kde_po_importer.py
@@ -143,7 +143,7 @@ class KdePOImporterTestCase(unittest.TestCase):
         singular = message.msgid_singular
         plural = message.msgid_plural
         self.assertTrue(
-            (singular == u'%1 foo' and plural == u'%1 foos'),
+            (singular == '%1 foo' and plural == '%1 foos'),
             "KdePOImporter didn't import KDE plural forms correctly.")
 
     def testTranslationPlurals(self):
@@ -152,9 +152,9 @@ class KdePOImporterTestCase(unittest.TestCase):
         message = self.translation_file.messages[0]
         translations = message.translations
         self.assertTrue(
-            (translations[0] == u'1st plural form %1' and
-             translations[1] == u'2nd plural form %1' and
-             translations[2] == u'3rd plural form %1'),
+            (translations[0] == '1st plural form %1' and
+             translations[1] == '2nd plural form %1' and
+             translations[2] == '3rd plural form %1'),
             "KdePOImporter didn't import translated KDE plural forms "
             "correctly.")
 
@@ -164,7 +164,7 @@ class KdePOImporterTestCase(unittest.TestCase):
         singular = message.msgid_singular
         context = message.context
         self.assertTrue(
-            (singular == u'Message' and context == u'Context'),
+            (singular == 'Message' and context == 'Context'),
             "KdePOImporter didn't import KDE context correctly.")
 
     def testTranslationContext(self):
@@ -174,6 +174,6 @@ class KdePOImporterTestCase(unittest.TestCase):
         context = message.context
         translations = message.translations
         self.assertTrue(
-            (singular == u'Message' and context == u'Context' and
-             translations[0] == u'Contextual translation'),
+            (singular == 'Message' and context == 'Context' and
+             translations[0] == 'Contextual translation'),
             "KdePOImporter didn't import translated KDE context correctly.")
diff --git a/lib/lp/translations/utilities/tests/test_sanitize.py b/lib/lp/translations/utilities/tests/test_sanitize.py
index b1a58fc..3462f7d 100644
--- a/lib/lp/translations/utilities/tests/test_sanitize.py
+++ b/lib/lp/translations/utilities/tests/test_sanitize.py
@@ -14,9 +14,9 @@ class TestSanitizer(TestCase):
 
     def test_convertDotToSpace(self):
         # Dots are converted back to spaces.
-        sanitizer = Sanitizer(u"English with space.")
-        translation = u"Text\u2022with\u2022dots."
-        expected_sanitized = u"Text with dots."
+        sanitizer = Sanitizer("English with space.")
+        translation = "Text\u2022with\u2022dots."
+        expected_sanitized = "Text with dots."
 
         self.assertEqual(
             expected_sanitized,
@@ -24,9 +24,9 @@ class TestSanitizer(TestCase):
 
     def test_convertDotToSpace_dot_in_english(self):
         # If there are dots in the English string, no conversion happens.
-        sanitizer = Sanitizer(u"English\u2022with\u2022dots.")
-        translation = u"Text\u2022with\u2022dots."
-        expected_sanitized = u"Text\u2022with\u2022dots."
+        sanitizer = Sanitizer("English\u2022with\u2022dots.")
+        translation = "Text\u2022with\u2022dots."
+        expected_sanitized = "Text\u2022with\u2022dots."
 
         self.assertEqual(
             expected_sanitized,
@@ -35,9 +35,9 @@ class TestSanitizer(TestCase):
     def test_normalizeWhitespace_add(self):
         # Leading and trailing white space in the translation are synced to
         # what the English text has.
-        sanitizer = Sanitizer(u"  English with leading white space.  ")
-        translation = u"Text without white space."
-        expected_sanitized = u"  Text without white space.  "
+        sanitizer = Sanitizer("  English with leading white space.  ")
+        translation = "Text without white space."
+        expected_sanitized = "  Text without white space.  "
 
         self.assertEqual(
             expected_sanitized,
@@ -46,9 +46,9 @@ class TestSanitizer(TestCase):
     def test_normalizeWhitespace_remove(self):
         # Leading and trailing white space in the translation are synced to
         # what the English text has.
-        sanitizer = Sanitizer(u"English without leading white space.")
-        translation = u"  Text with white space.  "
-        expected_sanitized = u"Text with white space."
+        sanitizer = Sanitizer("English without leading white space.")
+        translation = "  Text with white space.  "
+        expected_sanitized = "Text with white space."
 
         self.assertEqual(
             expected_sanitized,
@@ -57,9 +57,9 @@ class TestSanitizer(TestCase):
     def test_normalizeWhitespace_add_and_remove(self):
         # Leading and trailing white space in the translation are synced to
         # what the English text has.
-        sanitizer = Sanitizer(u"  English with leading white space.")
-        translation = u"Text with trailing white space.  "
-        expected_sanitized = u"  Text with trailing white space."
+        sanitizer = Sanitizer("  English with leading white space.")
+        translation = "Text with trailing white space.  "
+        expected_sanitized = "  Text with trailing white space."
 
         self.assertEqual(
             expected_sanitized,
@@ -68,28 +68,28 @@ class TestSanitizer(TestCase):
     def test_normalizeWhitespace_only_whitespace(self):
         # If a translation is only whitespace, it will be turned into the
         # empty string.
-        sanitizer = Sanitizer(u"English")
-        only_whitespace = u"    "
+        sanitizer = Sanitizer("English")
+        only_whitespace = "    "
 
-        self.assertEqual(u'', sanitizer.normalizeWhitespace(only_whitespace))
+        self.assertEqual('', sanitizer.normalizeWhitespace(only_whitespace))
 
     def test_normalizeWhitespace_only_whitespace_everywhere(self):
         # Corner case: only whitespace in English and translation will
         # normalize to the English string.
-        english_whitespace = u"  "
+        english_whitespace = "  "
         sanitizer = Sanitizer(english_whitespace)
-        only_whitespace = u"    "
+        only_whitespace = "    "
 
         self.assertEqual(
             english_whitespace,
             sanitizer.normalizeWhitespace(only_whitespace))
 
-    newline_styles = [u'\r\n', u'\r', u'\n']
+    newline_styles = ['\r\n', '\r', '\n']
 
     def test_normalizeNewlines(self):
         # Newlines will be converted to the same style that the English has.
-        english_template = u"Text with%snewline."
-        translation_template = u"Translation with%snewline."
+        english_template = "Text with%snewline."
+        translation_template = "Translation with%snewline."
         for english_newline in self.newline_styles:
             english_text = english_template % english_newline
             sanitizer = Sanitizer(english_text)
@@ -106,8 +106,8 @@ class TestSanitizer(TestCase):
     def test_normalizeNewlines_nothing_to_do_english(self):
         # If no newlines are found in the english text, no normalization
         # takes place.
-        sanitizer = Sanitizer(u"Text without newline.")
-        translation_template = u"Translation with%snewline."
+        sanitizer = Sanitizer("Text without newline.")
+        translation_template = "Translation with%snewline."
         for translation_newline in self.newline_styles:
             translation_text = translation_template % translation_newline
             sanitized = sanitizer.normalizeNewlines(translation_text)
@@ -119,8 +119,8 @@ class TestSanitizer(TestCase):
     def test_normalizeNewlines_nothing_to_do_translation(self):
         # If no newlines are found in the translation text, no normalization
         # takes place.
-        english_template = u"Text with%snewline."
-        translation_text = u"Translation without newline."
+        english_template = "Text with%snewline."
+        translation_text = "Translation without newline."
         for english_newline in self.newline_styles:
             english_text = english_template % english_newline
             sanitizer = Sanitizer(english_text)
@@ -132,7 +132,7 @@ class TestSanitizer(TestCase):
 
     def test_normalizeNewlines_mixed_newlines_english(self):
         # Mixed newlines in the English text will not raise an exception.
-        english_template = u"Text with%smixed%snewlines."
+        english_template = "Text with%smixed%snewlines."
         for english_newline_1 in self.newline_styles:
             other_newlines = self.newline_styles[:]
             other_newlines.remove(english_newline_1)
@@ -143,8 +143,8 @@ class TestSanitizer(TestCase):
 
     def test_normalizeNewlines_mixed_newlines_translation(self):
         # Mixed newlines in the translation text will raise an exception.
-        sanitizer = Sanitizer(u"Text with\nnewline.")
-        translation_template = u"Translation with%smixed%snewlines."
+        sanitizer = Sanitizer("Text with\nnewline.")
+        translation_template = "Translation with%smixed%snewlines."
         for translation_newline_1 in self.newline_styles:
             other_newlines = self.newline_styles[:]
             other_newlines.remove(translation_newline_1)
@@ -157,24 +157,24 @@ class TestSanitizer(TestCase):
 
     def test_sanitize(self):
         # Calling the Sanitizer object will apply all sanitization procedures.
-        sanitizer = Sanitizer(u"Text with\nnewline.")
+        sanitizer = Sanitizer("Text with\nnewline.")
         translation_text = (
-                u"Translation with\r\nnewline dots\u2022and whitespace.  ")
+                "Translation with\r\nnewline dots\u2022and whitespace.  ")
         expected_sanitized = (
-                u"Translation with\nnewline dots and whitespace.")
+                "Translation with\nnewline dots and whitespace.")
         self.assertEqual(
             expected_sanitized, sanitizer.sanitize(translation_text))
 
     def test_sanitize_whitespace_string(self):
         # A whitespace only string will be normalized to None.
-        sanitizer = Sanitizer(u"Text without whitespace.")
-        empty_translation_text = (u"  ")
+        sanitizer = Sanitizer("Text without whitespace.")
+        empty_translation_text = ("  ")
         self.assertTrue(
             sanitizer.sanitize(empty_translation_text) is None)
 
     def test_sanitizer_None(self):
         # None is returned as None.
-        sanitizer = Sanitizer(u"Text without whitespace.")
+        sanitizer = Sanitizer("Text without whitespace.")
         self.assertIs(sanitizer.sanitize(None), None)
 
 
@@ -185,19 +185,19 @@ class TestSanitizeTranslations(TestCase):
     form situations.  The actual sanitization is tested in TestSanitizer.
     """
 
-    english = u"Some English text\nwith unix newline."
+    english = "Some English text\nwith unix newline."
 
     def test_sanitize_translations(self):
         # All plural forms are sanitized.
         translations = {
-            0: u'Plural\r\nform 0  ',
-            1: u'Plural\r\nform 1  ',
-            2: u'Plural\r\nform 2  ',
+            0: 'Plural\r\nform 0  ',
+            1: 'Plural\r\nform 1  ',
+            2: 'Plural\r\nform 2  ',
             }
         expected_sanitized = {
-            0: u'Plural\nform 0',
-            1: u'Plural\nform 1',
-            2: u'Plural\nform 2',
+            0: 'Plural\nform 0',
+            1: 'Plural\nform 1',
+            2: 'Plural\nform 2',
             }
         self.assertEqual(
             expected_sanitized,
@@ -206,14 +206,14 @@ class TestSanitizeTranslations(TestCase):
     def test_sanitize_translations_not_in_dict(self):
         # A list is converted to a dictionary.
         translations = [
-            u'Pluralform 0',
-            u'Pluralform 1',
-            u'Pluralform 2',
+            'Pluralform 0',
+            'Pluralform 1',
+            'Pluralform 2',
             ]
         expected_sanitized = {
-            0: u'Pluralform 0',
-            1: u'Pluralform 1',
-            2: u'Pluralform 2',
+            0: 'Pluralform 0',
+            1: 'Pluralform 1',
+            2: 'Pluralform 2',
             }
         self.assertEqual(
             expected_sanitized,
@@ -222,13 +222,13 @@ class TestSanitizeTranslations(TestCase):
     def test_sanitize_translations_missing_pluralform(self):
         # Missing plural forms are normalized to None.
         translations = {
-            0: u'Plural\r\nform 0  ',
-            2: u'Plural\r\nform 2  ',
+            0: 'Plural\r\nform 0  ',
+            2: 'Plural\r\nform 2  ',
             }
         expected_sanitized = {
-            0: u'Plural\nform 0',
+            0: 'Plural\nform 0',
             1: None,
-            2: u'Plural\nform 2',
+            2: 'Plural\nform 2',
             }
         self.assertEqual(
             expected_sanitized,
@@ -237,16 +237,16 @@ class TestSanitizeTranslations(TestCase):
     def test_sanitize_translations_excess_pluralform(self):
         # Excess plural forms are sanitized, too.
         translations = {
-            0: u'Plural\r\nform 0  ',
-            1: u'Plural\r\nform 1  ',
-            2: u'Plural\r\nform 2  ',
-            4: u'Plural\r\nform 4  ',
+            0: 'Plural\r\nform 0  ',
+            1: 'Plural\r\nform 1  ',
+            2: 'Plural\r\nform 2  ',
+            4: 'Plural\r\nform 4  ',
             }
         expected_sanitized = {
-            0: u'Plural\nform 0',
-            1: u'Plural\nform 1',
-            2: u'Plural\nform 2',
-            4: u'Plural\nform 4',
+            0: 'Plural\nform 0',
+            1: 'Plural\nform 1',
+            2: 'Plural\nform 2',
+            4: 'Plural\nform 4',
             }
         self.assertEqual(
             expected_sanitized,
@@ -255,10 +255,10 @@ class TestSanitizeTranslations(TestCase):
     def test_sanitize_translations_pluralforms_none(self):
         # Some languages don't provide a plural form, so 2 is assumed.
         translations = {
-            0: u'Plural form 0  ',
+            0: 'Plural form 0  ',
             }
         expected_sanitized = {
-            0: u'Plural form 0',
+            0: 'Plural form 0',
             1: None,
             }
         self.assertEqual(
diff --git a/lib/lp/translations/utilities/tests/test_superfastimports.py b/lib/lp/translations/utilities/tests/test_superfastimports.py
index 6d8f467..7315a91 100644
--- a/lib/lp/translations/utilities/tests/test_superfastimports.py
+++ b/lib/lp/translations/utilities/tests/test_superfastimports.py
@@ -19,7 +19,7 @@ class TestSuperFastImports(TestCaseWithFactory):
     def setUp(self):
         # Set up a single POFile in the database to be cached and
         # examined.
-        super(TestSuperFastImports, self).setUp()
+        super().setUp()
 
     def getTranslationMessageData(self, translationmessage):
         # Convert a TranslationMessage to TranslationMessageData object,
diff --git a/lib/lp/translations/utilities/tests/test_syntax_errors.py b/lib/lp/translations/utilities/tests/test_syntax_errors.py
index 9273f5a..897656e 100644
--- a/lib/lp/translations/utilities/tests/test_syntax_errors.py
+++ b/lib/lp/translations/utilities/tests/test_syntax_errors.py
@@ -52,13 +52,13 @@ class TranslationFormatInvalidInputErrorTest(TestCase):
 
         # Here's one with a Thai "r" character in its message.
         exception = TranslationFormatInvalidInputError(
-            filename=u"ror-rua", line_number=2, message=u"r\u0e23")
+            filename="ror-rua", line_number=2, message="r\u0e23")
         representation = str(exception)
         self.assertEqual(representation, "ror-rua, line 2: r\\u0e23")
 
         # And here's one with the Khmer equivalent in its filename.
         exception = TranslationFormatInvalidInputError(
-            filename=u"ro-\u179a", message=u"hok baay heuy?")
+            filename="ro-\u179a", message="hok baay heuy?")
         representation = str(exception)
         self.assertEqual(representation, "ro-\\u179a: hok baay heuy?")
 
@@ -78,8 +78,8 @@ class TranslationFormatSyntaxErrorTest(TestCase):
 
     def testNonAsciiSyntaxError(self):
         # Test against non-ascii characters.
-        exception = TranslationFormatSyntaxError(filename=u"khor-khai-\u0e01",
-            line_number=4, message=u"khor-khai-\u0e02")
+        exception = TranslationFormatSyntaxError(filename="khor-khai-\u0e01",
+            line_number=4, message="khor-khai-\u0e02")
         self.assertEqual(str(exception),
             "khor-khai-\\u0e01, line 4: khor-khai-\\u0e02")
 
diff --git a/lib/lp/translations/utilities/tests/test_translation_importer.py b/lib/lp/translations/utilities/tests/test_translation_importer.py
index b7b42e5..a964138 100644
--- a/lib/lp/translations/utilities/tests/test_translation_importer.py
+++ b/lib/lp/translations/utilities/tests/test_translation_importer.py
@@ -95,7 +95,7 @@ class TranslationImporterTestCase(TestCaseWithFactory):
         exactly the same priority."""
         for file_extension in TranslationImporter().supported_file_extensions:
             priorities = []
-            for format, importer in six.iteritems(importers):
+            for format, importer in importers.items():
                 if file_extension in importer.file_extensions:
                     self.assertNotIn(importer.priority, priorities)
                     priorities.append(importer.priority)
diff --git a/lib/lp/translations/utilities/tests/test_xpi_header.py b/lib/lp/translations/utilities/tests/test_xpi_header.py
index 0f972d9..ca7de38 100644
--- a/lib/lp/translations/utilities/tests/test_xpi_header.py
+++ b/lib/lp/translations/utilities/tests/test_xpi_header.py
@@ -122,6 +122,6 @@ class XpiHeaderTestCase(unittest.TestCase):
     def test_NonAsciiContributor(self):
         # Contributor names don't have to be in ASCII.
         header = self._produceHeader([
-            u"\u0e40\u0e2d\u0e4b <eai@xxxxxxxxxxx>"])
+            "\u0e40\u0e2d\u0e4b <eai@xxxxxxxxxxx>"])
         self.assertEqual(header.getLastTranslator(),
-            (u"\u0e40\u0e2d\u0e4b", 'eai@xxxxxxxxxxx'))
+            ("\u0e40\u0e2d\u0e4b", 'eai@xxxxxxxxxxx'))
diff --git a/lib/lp/translations/utilities/tests/test_xpi_po_exporter.py b/lib/lp/translations/utilities/tests/test_xpi_po_exporter.py
index 4158c8e..f2aab6f 100644
--- a/lib/lp/translations/utilities/tests/test_xpi_po_exporter.py
+++ b/lib/lp/translations/utilities/tests/test_xpi_po_exporter.py
@@ -50,7 +50,7 @@ from lp.translations.utilities.xpi_po_exporter import XPIPOExporter
 # Hardcoded representations of what used to be found in
 # lib/lp/translations/utilities/tests/firefox-data/.  We no longer have real
 # XPI import code, so we pre-parse the messages.
-test_xpi_header = dedent(u'''\
+test_xpi_header = dedent('''\
     <?xml version="1.0"?>
     <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
          xmlns:em="http://www.mozilla.org/2004/em-rdf#";>
@@ -74,12 +74,12 @@ test_xpi_header = dedent(u'''\
     </RDF>
 ''')  # noqa: E501
 test_xpi_messages = [
-    (u'foozilla.menu.title', u'main/subdir/test2.dtd',
-     u'jar:chrome/en-US.jar!/subdir/test2.dtd', u'MENU',
-     u' This is a DTD file inside a subdirectory\n'),
-    (u'foozilla.menu.accesskey', u'main/subdir/test2.dtd',
-     u'jar:chrome/en-US.jar!/subdir/test2.dtd', u'M',
-     dedent(u'''\
+    ('foozilla.menu.title', 'main/subdir/test2.dtd',
+     'jar:chrome/en-US.jar!/subdir/test2.dtd', 'MENU',
+     ' This is a DTD file inside a subdirectory\n'),
+    ('foozilla.menu.accesskey', 'main/subdir/test2.dtd',
+     'jar:chrome/en-US.jar!/subdir/test2.dtd', 'M',
+     dedent('''\
         Select the access key that you want to use. These have
         to be translated in a way that the selected character is
         present in the translated string of the label being
@@ -89,9 +89,9 @@ test_xpi_messages = [
         context of the key from the end of the 'Located in' text
         below.
         ''')),
-    (u'foozilla.menu.commandkey', u'main/subdir/test2.dtd',
-     u'jar:chrome/en-US.jar!/subdir/test2.dtd', u'm',
-     dedent(u'''\
+    ('foozilla.menu.commandkey', 'main/subdir/test2.dtd',
+     'jar:chrome/en-US.jar!/subdir/test2.dtd', 'm',
+     dedent('''\
         Select the shortcut key that you want to use. It
         should be translated, but often shortcut keys (for
         example Ctrl + KEY) are not changed from the original. If
@@ -99,33 +99,33 @@ test_xpi_messages = [
         you are not sure about it. Please find the context of
         the key from the end of the 'Located in' text below.
         ''')),
-    (u'foozilla_something', u'main/subdir/test2.properties',
-     u'jar:chrome/en-US.jar!/subdir/test2.properties:6', u'SomeZilla',
-     dedent(u'''\
+    ('foozilla_something', 'main/subdir/test2.properties',
+     'jar:chrome/en-US.jar!/subdir/test2.properties:6', 'SomeZilla',
+     dedent('''\
         Translators, what you are seeing now is a lovely,
         awesome, multiline comment aimed at you directly
         from the streets of a .properties file
         ''')),
-    (u'foozilla.name', u'main/test1.dtd',
-     u'jar:chrome/en-US.jar!/test1.dtd', u'FooZilla!', None),
-    (u'foozilla.play.fire', u'main/test1.dtd',
-     u'jar:chrome/en-US.jar!/test1.dtd', u'Do you want to play with fire?',
-     u" Translators, don't play with fire!\n"),
-    (u'foozilla.play.ice', u'main/test1.dtd',
-     u'jar:chrome/en-US.jar!/test1.dtd', u'Play with ice?',
-     u' This is just a comment, not a comment for translators\n'),
-    (u'foozilla.title', u'main/test1.properties',
-     u'jar:chrome/en-US.jar!/test1.properties:1', u'FooZilla Zilla Thingy',
+    ('foozilla.name', 'main/test1.dtd',
+     'jar:chrome/en-US.jar!/test1.dtd', 'FooZilla!', None),
+    ('foozilla.play.fire', 'main/test1.dtd',
+     'jar:chrome/en-US.jar!/test1.dtd', 'Do you want to play with fire?',
+     " Translators, don't play with fire!\n"),
+    ('foozilla.play.ice', 'main/test1.dtd',
+     'jar:chrome/en-US.jar!/test1.dtd', 'Play with ice?',
+     ' This is just a comment, not a comment for translators\n'),
+    ('foozilla.title', 'main/test1.properties',
+     'jar:chrome/en-US.jar!/test1.properties:1', 'FooZilla Zilla Thingy',
      None),
-    (u'foozilla.happytitle', u'main/test1.properties',
-     u'jar:chrome/en-US.jar!/test1.properties:3',
-     u'http://foozillingy.happy.net/',
-     u"Translators, if you're older than six, don't translate this\n"),
-    (u'foozilla.nocomment', u'main/test1.properties',
-     u'jar:chrome/en-US.jar!/test1.properties:4', u'No Comment',
-     u'(Except this one)\n'),
-    (u'foozilla.utf8', u'main/test1.properties',
-     u'jar:chrome/en-US.jar!/test1.properties:5', u'\u0414\u0430\u043d=Day',
+    ('foozilla.happytitle', 'main/test1.properties',
+     'jar:chrome/en-US.jar!/test1.properties:3',
+     'http://foozillingy.happy.net/',
+     "Translators, if you're older than six, don't translate this\n"),
+    ('foozilla.nocomment', 'main/test1.properties',
+     'jar:chrome/en-US.jar!/test1.properties:4', 'No Comment',
+     '(Except this one)\n'),
+    ('foozilla.utf8', 'main/test1.properties',
+     'jar:chrome/en-US.jar!/test1.properties:5', '\u0414\u0430\u043d=Day',
      None),
     ]
 
@@ -134,7 +134,7 @@ class FakeXPIMessage(TranslationMessageData):
     """Simulate an XPI translation message."""
 
     def __init__(self, key, chrome_path, file_and_line, value, last_comment):
-        super(FakeXPIMessage, self).__init__()
+        super().__init__()
         self.msgid_singular = key
         self.context = chrome_path
         self.file_references = '%s(%s)' % (file_and_line, key)
@@ -184,7 +184,7 @@ class XPIPOExporterTestCase(TestCase):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(XPIPOExporterTestCase, self).setUp()
+        super().setUp()
 
         self.translation_exporter = XPIPOExporter()
 
@@ -273,7 +273,7 @@ class XPIPOExporterTestCase(TestCase):
         self.translation_exporter.exportTranslationFile(
             translation_file_data, storage)
 
-        expected_template = dedent(u'''
+        expected_template = dedent('''
             #, fuzzy
             msgid ""
             msgstr ""
diff --git a/lib/lp/translations/utilities/translation_common_format.py b/lib/lp/translations/utilities/translation_common_format.py
index 76a9d9b..83830ec 100644
--- a/lib/lp/translations/utilities/translation_common_format.py
+++ b/lib/lp/translations/utilities/translation_common_format.py
@@ -44,9 +44,9 @@ class TranslationMessageData:
         self.plural_text = None
         self.context = None
         self._translations = []
-        self.comment = u''
-        self.source_comment = u''
-        self.file_references = u''
+        self.comment = ''
+        self.source_comment = ''
+        self.file_references = ''
         self.flags = set()
         self.is_obsolete = False
 
diff --git a/lib/lp/translations/utilities/translation_import.py b/lib/lp/translations/utilities/translation_import.py
index ed5e79f..a5afe1e 100644
--- a/lib/lp/translations/utilities/translation_import.py
+++ b/lib/lp/translations/utilities/translation_import.py
@@ -273,7 +273,7 @@ class TranslationImporter:
         """See `ITranslationImporter`."""
         file_extensions = []
 
-        for importer in six.itervalues(importers):
+        for importer in importers.values():
             file_extensions.extend(importer.file_extensions)
 
         return sorted(set(file_extensions))
@@ -289,7 +289,7 @@ class TranslationImporter:
 
     def isTemplateName(self, path):
         """See `ITranslationImporter`."""
-        for importer in six.itervalues(importers):
+        for importer in importers.values():
             if path.endswith(importer.template_suffix):
                 return True
         return False
@@ -354,7 +354,7 @@ class TranslationImporter:
         return file_importer.importFile()
 
 
-class FileImporter(object):
+class FileImporter:
     """Base class for importing translations or translation templates.
 
     This class is meant to be subclassed for the specialised tasks of
@@ -464,7 +464,7 @@ class FileImporter(object):
                 potmsgset.singular_text, potmsgset.plural_text,
                 translations, potmsgset.flags)
         except GettextValidationError as e:
-            self._addUpdateError(message_data, potmsgset, six.text_type(e))
+            self._addUpdateError(message_data, potmsgset, str(e))
             message.validation_status = (
                 TranslationValidationStatus.UNKNOWNERROR)
             return False
@@ -631,8 +631,7 @@ class POTFileImporter(FileImporter):
             "Pofile must be None when importing a template.")
 
         # Call base constructor
-        super(POTFileImporter, self).__init__(
-             translation_import_queue_entry, importer, logger)
+        super().__init__(translation_import_queue_entry, importer, logger)
 
         self.pofile = None
         self.potemplate = translation_import_queue_entry.potemplate
@@ -675,9 +674,9 @@ class POTFileImporter(FileImporter):
             message._translations = None
 
         if len(message.flags) > 0:
-            flags_comment = u", " + u", ".join(message.flags)
+            flags_comment = ", " + ", ".join(message.flags)
         else:
-            flags_comment = u""
+            flags_comment = ""
 
         potmsgset = self.getOrCreatePOTMsgSet(message)
         potmsgset.setSequence(self.potemplate, self.count)
@@ -707,8 +706,7 @@ class POFileImporter(FileImporter):
             "Pofile must not be None when importing a translation.")
 
         # Call base constructor
-        super(POFileImporter, self).__init__(
-             translation_import_queue_entry, importer, logger)
+        super().__init__(translation_import_queue_entry, importer, logger)
 
         self.pofile = translation_import_queue_entry.pofile
         self.potemplate = self.pofile.potemplate
diff --git a/lib/lp/translations/utilities/translationmerger.py b/lib/lp/translations/utilities/translationmerger.py
index 524790f..dd2d2f2 100644
--- a/lib/lp/translations/utilities/translationmerger.py
+++ b/lib/lp/translations/utilities/translationmerger.py
@@ -437,7 +437,7 @@ class TranslationMerger:
 
         self.tm.endTransaction(intermediate=True)
 
-        for representative_id in six.itervalues(representatives):
+        for representative_id in representatives.values():
             representative = POTMsgSet.get(representative_id)
             self._scrubPOTMsgSetTranslations(representative)
             self.tm.endTransaction(intermediate=True)
@@ -492,7 +492,7 @@ class TranslationMerger:
         num_representatives = len(subordinates)
         representative_num = 0
 
-        for representative, potmsgsets in six.iteritems(subordinates):
+        for representative, potmsgsets in subordinates.items():
             representative_num += 1
             log.debug("Message %d/%d: %d subordinate(s)." % (
                 representative_num, num_representatives, len(potmsgsets)))
diff --git a/lib/lp/translations/utilities/validate.py b/lib/lp/translations/utilities/validate.py
index 78075ea..27cbea4 100644
--- a/lib/lp/translations/utilities/validate.py
+++ b/lib/lp/translations/utilities/validate.py
@@ -7,7 +7,6 @@ __all__ = [
     ]
 
 import gettextpo
-import six
 
 
 class GettextValidationError(ValueError):
@@ -36,7 +35,7 @@ def validate_translation(original_singular, original_plural,
     else:
         # Message with plural forms.
         msg.set_msgid_plural(original_plural)
-        for form, translation in six.iteritems(translations):
+        for form, translation in translations.items():
             msg.set_msgstr_plural(form, translation)
 
     for flag in flags:
@@ -47,4 +46,4 @@ def validate_translation(original_singular, original_plural,
         msg.check_format()
     except gettextpo.error as e:
         # Wrap gettextpo.error in GettextValidationError.
-        raise GettextValidationError(six.text_type(e))
+        raise GettextValidationError(str(e))
diff --git a/lib/lp/translations/utilities/xpi_header.py b/lib/lp/translations/utilities/xpi_header.py
index 367c059..acd7db1 100644
--- a/lib/lp/translations/utilities/xpi_header.py
+++ b/lib/lp/translations/utilities/xpi_header.py
@@ -44,7 +44,7 @@ class XpiHeader:
                 raise TranslationFormatInvalidInputError(
                     "XPI header is not encoded in %s." % self.charset)
         else:
-            assert isinstance(header_content, six.text_type), (
+            assert isinstance(header_content, str), (
                 "XPI header text is neither bytes nor unicode.")
             self._text = header_content
 
diff --git a/lib/lp/translations/utilities/xpi_po_exporter.py b/lib/lp/translations/utilities/xpi_po_exporter.py
index 7806434..7f3eea0 100644
--- a/lib/lp/translations/utilities/xpi_po_exporter.py
+++ b/lib/lp/translations/utilities/xpi_po_exporter.py
@@ -25,7 +25,7 @@ class XPIPOExporter(GettextPOExporter):
     format = TranslationFileFormat.XPIPO
 
     def __init__(self, context=None):
-        super(XPIPOExporter, self).__init__(context=context)
+        super().__init__(context=context)
         # 'context' is ignored because it's only required by the way the
         # exporters are instantiated but it isn't used by this class.
 
diff --git a/lib/lp/translations/vocabularies.py b/lib/lp/translations/vocabularies.py
index b3b5617..ab7d3f5 100644
--- a/lib/lp/translations/vocabularies.py
+++ b/lib/lp/translations/vocabularies.py
@@ -54,8 +54,7 @@ class TranslatableLanguageVocabulary(LanguageVocabulary):
             "left operand, got %s instead." % type(language))
         if language.code == 'en':
             return False
-        return language.visible == True and super(
-            TranslatableLanguageVocabulary, self).__contains__(language)
+        return language.visible == True and super().__contains__(language)
 
     def __iter__(self):
         """See `IVocabulary`.
@@ -72,8 +71,7 @@ class TranslatableLanguageVocabulary(LanguageVocabulary):
         """See `IVocabulary`."""
         if token == 'en':
             raise LookupError(token)
-        term = super(TranslatableLanguageVocabulary, self).getTermByToken(
-            token)
+        term = super().getTermByToken(token)
         if not term.value.visible:
             raise LookupError(token)
         return term
@@ -116,7 +114,7 @@ class TranslationTemplateVocabulary(SQLObjectVocabularyBase):
                 POTemplate.iscurrent == True,
                 POTemplate.distroseries == context.distroseries,
                 POTemplate.sourcepackagename == context.sourcepackagename)
-        super(TranslationTemplateVocabulary, self).__init__(context)
+        super().__init__(context)
 
     def toTerm(self, obj):
         return SimpleTerm(obj, obj.id, obj.name)
@@ -132,7 +130,7 @@ class FilteredLanguagePackVocabularyBase(StormVocabularyBase):
             raise AssertionError(
                 "%s is only useful from a DistroSeries context." %
                 self.__class__.__name__)
-        super(FilteredLanguagePackVocabularyBase, self).__init__(context)
+        super().__init__(context)
 
     def toTerm(self, obj):
         return SimpleTerm(
@@ -149,9 +147,7 @@ class FilteredFullLanguagePackVocabulary(FilteredLanguagePackVocabularyBase):
 
     @property
     def _clauses(self):
-        return (
-            super(FilteredFullLanguagePackVocabulary, self)._clauses +
-            [LanguagePack.type == LanguagePackType.FULL])
+        return super()._clauses + [LanguagePack.type == LanguagePackType.FULL]
 
 
 class FilteredDeltaLanguagePackVocabulary(FilteredLanguagePackVocabularyBase):
@@ -161,7 +157,7 @@ class FilteredDeltaLanguagePackVocabulary(FilteredLanguagePackVocabularyBase):
     @property
     def _clauses(self):
         return (
-            super(FilteredDeltaLanguagePackVocabulary, self)._clauses +
+            super()._clauses +
             [LanguagePack.type == LanguagePackType.DELTA,
              LanguagePack.updates == self.context.language_pack_base])
 
@@ -190,4 +186,4 @@ class FilteredLanguagePackVocabulary(FilteredLanguagePackVocabularyBase):
         clauses.append(Or(
             LanguagePack.updates == None,
             LanguagePack.updates == self.context.language_pack_base))
-        return super(FilteredLanguagePackVocabulary, self)._clauses + clauses
+        return super()._clauses + clauses