← Back to team overview

launchpad-reviewers team mailing list archive

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

 

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

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

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/414052
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:pyupgrade-py3-translations-1 into launchpad:master.
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index 83958cd..e01ae37 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -46,3 +46,5 @@ f3f15787ebabe305fbf3e3ae6c0fd8ca7dfb4465
 21fb5364d9371c0ad2edf41fa6920c4e16ead2b0
 # apply pyupgrade --py3-plus to lp.{testing,testopenid,tests}
 9621eff0fd58287b254fb228c11948fca85d547c
+# apply pyupgrade --py3-plus to lp.translations
+d61c2ad002c2997a132a1580ce6ee82bb03de11d
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index cc22ee7..ba49e44 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -60,6 +60,7 @@ repos:
             |testing
             |testopenid
             |tests
+            |translations/browser
           )/
 -   repo: https://github.com/PyCQA/isort
     rev: 5.9.2
diff --git a/lib/lp/translations/browser/browser_helpers.py b/lib/lp/translations/browser/browser_helpers.py
index 48a57b1..a4894a6 100644
--- a/lib/lp/translations/browser/browser_helpers.py
+++ b/lib/lp/translations/browser/browser_helpers.py
@@ -15,8 +15,6 @@ __all__ = [
 from math import ceil
 import re
 
-import six
-
 from lp.services import helpers
 from lp.services.webapp.escaping import html_escape
 from lp.translations.interfaces.translations import TranslationConstants
@@ -30,20 +28,20 @@ def contract_rosetta_escapes(text):
     """Replace Rosetta escape sequences with the real characters."""
     return helpers.text_replaced(text, {'[tab]': '\t',
                                         r'\[tab]': '[tab]',
-                                        '[nbsp]': u'\u00a0',
+                                        '[nbsp]': '\u00a0',
                                         r'\[nbsp]': '[nbsp]',
-                                        '[nnbsp]': u'\u202f',
+                                        '[nnbsp]': '\u202f',
                                         r'\[nnbsp]': '[nnbsp]'})
 
 
 def expand_rosetta_escapes(unicode_text):
     """Replace characters needing a Rosetta escape sequences."""
-    escapes = {u'\t': TranslationConstants.TAB_CHAR,
-               u'[tab]': TranslationConstants.TAB_CHAR_ESCAPED,
-               u'\u00a0': TranslationConstants.NO_BREAK_SPACE_CHAR,
-               u'[nbsp]': TranslationConstants.NO_BREAK_SPACE_CHAR_ESCAPED,
-               u'\u202f': TranslationConstants.NARROW_NO_BREAK_SPACE_CHAR,
-               u'[nnbsp]':
+    escapes = {'\t': TranslationConstants.TAB_CHAR,
+               '[tab]': TranslationConstants.TAB_CHAR_ESCAPED,
+               '\u00a0': TranslationConstants.NO_BREAK_SPACE_CHAR,
+               '[nbsp]': TranslationConstants.NO_BREAK_SPACE_CHAR_ESCAPED,
+               '\u202f': TranslationConstants.NARROW_NO_BREAK_SPACE_CHAR,
+               '[nnbsp]':
     TranslationConstants.NARROW_NO_BREAK_SPACE_CHAR_ESCAPED}
     return helpers.text_replaced(unicode_text, escapes)
 
@@ -56,12 +54,12 @@ def text_to_html(text, flags, space=TranslationConstants.SPACE_CHAR,
 
     markup_lines = []
     # Replace leading and trailing spaces on each line with special markup.
-    if u'\r\n' in text:
-        newline_chars = u'\r\n'
-    elif u'\r' in text:
-        newline_chars = u'\r'
+    if '\r\n' in text:
+        newline_chars = '\r\n'
+    elif '\r' in text:
+        newline_chars = '\r'
     else:
-        newline_chars = u'\n'
+        newline_chars = '\n'
     for line in text.split(newline_chars):
         # Pattern:
         # - group 1: zero or more spaces: leading whitespace
@@ -69,7 +67,7 @@ def text_to_html(text, flags, space=TranslationConstants.SPACE_CHAR,
         #   more spaces followed by one or more non-spaces): maximal string
         #   which doesn't begin or end with whitespace
         # - group 3: zero or more spaces: trailing whitespace
-        match = re.match(u'^( *)((?: *[^ ]+)*)( *)$', line)
+        match = re.match('^( *)((?: *[^ ]+)*)( *)$', line)
 
         if match:
             format_segments = None
@@ -84,7 +82,7 @@ def text_to_html(text, flags, space=TranslationConstants.SPACE_CHAR,
                     type, content = segment
 
                     if type == 'interpolation':
-                        markup += (u'<code>%s</code>' % html_escape(content))
+                        markup += ('<code>%s</code>' % html_escape(content))
                     elif type == 'string':
                         markup += html_escape(content)
             else:
@@ -109,18 +107,18 @@ def convert_newlines_to_web_form(unicode_text):
     if unicode_text is None:
         return None
 
-    assert isinstance(unicode_text, six.text_type), (
+    assert isinstance(unicode_text, str), (
         "The given text must be unicode instead of %s" % type(unicode_text))
 
     if unicode_text is None:
         return None
-    elif u'\r\n' in unicode_text:
+    elif '\r\n' in unicode_text:
         # The text is already using the windows newline chars
         return unicode_text
-    elif u'\n' in unicode_text:
-        return helpers.text_replaced(unicode_text, {u'\n': u'\r\n'})
+    elif '\n' in unicode_text:
+        return helpers.text_replaced(unicode_text, {'\n': '\r\n'})
     else:
-        return helpers.text_replaced(unicode_text, {u'\r': u'\r\n'})
+        return helpers.text_replaced(unicode_text, {'\r': '\r\n'})
 
 
 def count_lines(text):
@@ -135,7 +133,7 @@ def count_lines(text):
     CHARACTERS_PER_LINE = 60
     count = 0
 
-    for line in text.split(u'\n'):
+    for line in text.split('\n'):
         if len(line) == 0:
             count += 1
         else:
diff --git a/lib/lp/translations/browser/distroseries.py b/lib/lp/translations/browser/distroseries.py
index 02a4292..8191792 100644
--- a/lib/lp/translations/browser/distroseries.py
+++ b/lib/lp/translations/browser/distroseries.py
@@ -102,7 +102,7 @@ class DistroSeriesLanguagePackView(LaunchpadEditFormView):
             self.field_names = ['language_pack_full_export_requested']
         else:
             self.field_names = []
-        super(DistroSeriesLanguagePackView, self).initialize()
+        super().initialize()
         self.displayname = '%s %s' % (
             self.context.distribution.displayname,
             self.context.version)
@@ -194,8 +194,7 @@ class DistroSeriesTemplatesView(BaseSeriesTemplatesView):
     """Show a list of all templates for the DistroSeries."""
 
     def initialize(self):
-        super(DistroSeriesTemplatesView, self).initialize(
-            series=self.context, is_distroseries=True)
+        super().initialize(series=self.context, is_distroseries=True)
 
     def constructTemplateURL(self, template):
         """See `BaseSeriesTemplatesView`."""
diff --git a/lib/lp/translations/browser/language.py b/lib/lp/translations/browser/language.py
index adc5612..918b7ed 100644
--- a/lib/lp/translations/browser/language.py
+++ b/lib/lp/translations/browser/language.py
@@ -75,7 +75,7 @@ class LanguageSetNavigation(GetitemNavigation):
 
 class LanguageSetBreadcrumb(Breadcrumb):
     """`Breadcrumb` for `ILanguageSet`."""
-    text = u"Languages"
+    text = "Languages"
 
 
 class LanguageSetContextMenu(ContextMenu):
@@ -108,7 +108,7 @@ class ILanguageSetSearch(Interface):
     """The collection of languages."""
 
     search_lang = TextLine(
-        title=u'Name of the language to search for.',
+        title='Name of the language to search for.',
         required=True)
 
 
diff --git a/lib/lp/translations/browser/person.py b/lib/lp/translations/browser/person.py
index 3b416da..2dd8d81 100644
--- a/lib/lp/translations/browser/person.py
+++ b/lib/lp/translations/browser/person.py
@@ -204,7 +204,7 @@ class PersonTranslationView(LaunchpadView):
     reviews_to_show = 10
 
     def __init__(self, *args, **kwargs):
-        super(PersonTranslationView, self).__init__(*args, **kwargs)
+        super().__init__(*args, **kwargs)
         now = datetime.now(pytz.timezone('UTC'))
         # Down-to-the-second detail isn't important so the hope is that this
         # will result in faster queries (cache effects).
diff --git a/lib/lp/translations/browser/pofile.py b/lib/lp/translations/browser/pofile.py
index c01f046..1e85b3e 100644
--- a/lib/lp/translations/browser/pofile.py
+++ b/lib/lp/translations/browser/pofile.py
@@ -582,7 +582,7 @@ class POFileTranslateView(BaseTranslationView, POFileMetadataViewMixin):
         self.start_offset = 0
 
         self._initializeShowOption()
-        super(POFileTranslateView, self).initialize()
+        super().initialize()
 
     #
     # BaseTranslationView API
diff --git a/lib/lp/translations/browser/potemplate.py b/lib/lp/translations/browser/potemplate.py
index 12cb580..aa3d5f2 100644
--- a/lib/lp/translations/browser/potemplate.py
+++ b/lib/lp/translations/browser/potemplate.py
@@ -183,8 +183,7 @@ class POTemplateMenu(NavigationMenu):
 class POTemplateSubsetView(RedirectionView):
 
     def __init__(self, context, request):
-        super(POTemplateSubsetView, self).__init__(
-            '../+translations', request)
+        super().__init__('../+translations', request)
 
 
 class POTemplateView(LaunchpadView,
diff --git a/lib/lp/translations/browser/productseries.py b/lib/lp/translations/browser/productseries.py
index 0b9b00a..e17dafc 100644
--- a/lib/lp/translations/browser/productseries.py
+++ b/lib/lp/translations/browser/productseries.py
@@ -467,7 +467,7 @@ class SettingsRadioWidget(LaunchpadRadioWidgetWithDescription):
     """Remove the confusing hint under the widget."""
 
     def __init__(self, field, vocabulary, request):
-        super(SettingsRadioWidget, self).__init__(field, vocabulary, request)
+        super().__init__(field, vocabulary, request)
         self.hint = None
 
 
@@ -485,7 +485,7 @@ class ProductSeriesTranslationsSettingsView(ReturnToReferrerMixin,
     field_names = ['translations_autoimport_mode']
     custom_widget_translations_autoimport_mode = SettingsRadioWidget
 
-    @action(u"Save settings", name="save_settings")
+    @action("Save settings", name="save_settings")
     def change_settings_action(self, action, data):
         """Change the translation settings."""
         if (self.context.translations_autoimport_mode !=
@@ -522,7 +522,7 @@ class ProductSeriesTranslationsBzrImportView(LaunchpadFormView,
             self.addError(
                 "Please set the official Bazaar branch first.")
 
-    @action(u"Request one-time import", name="request_import")
+    @action("Request one-time import", name="request_import")
     def request_import_action(self, action, data):
         """ Request an upload of translation files. """
         job = getUtility(IRosettaUploadJobSource).create(
@@ -539,8 +539,7 @@ class ProductSeriesTemplatesView(BaseSeriesTemplatesView):
     """Show a list of all templates for the ProductSeries."""
 
     def initialize(self):
-        super(ProductSeriesTemplatesView, self).initialize(
-            series=self.context, is_distroseries=False)
+        super().initialize(series=self.context, is_distroseries=False)
 
     def constructTemplateURL(self, template):
         """See `BaseSeriesTemplatesView`."""
diff --git a/lib/lp/translations/browser/serieslanguage.py b/lib/lp/translations/browser/serieslanguage.py
index d0eeca3..6004a18 100644
--- a/lib/lp/translations/browser/serieslanguage.py
+++ b/lib/lp/translations/browser/serieslanguage.py
@@ -144,7 +144,7 @@ class DistroSeriesLanguageView(BaseSeriesLanguageView):
 
     def initialize(self):
         series = self.context.distroseries
-        super(DistroSeriesLanguageView, self).initialize(
+        super().initialize(
             series=series,
             translationgroup=series.distribution.translationgroup)
         self.parent = self.series.distribution
@@ -155,7 +155,7 @@ class ProductSeriesLanguageView(BaseSeriesLanguageView):
 
     def initialize(self):
         series = self.context.productseries
-        super(ProductSeriesLanguageView, self).initialize(
+        super().initialize(
             series=series,
             translationgroup=series.product.translationgroup)
         self.context.recalculateCounts()
diff --git a/lib/lp/translations/browser/sourcepackage.py b/lib/lp/translations/browser/sourcepackage.py
index 37c5c25..1cf947a 100644
--- a/lib/lp/translations/browser/sourcepackage.py
+++ b/lib/lp/translations/browser/sourcepackage.py
@@ -116,7 +116,7 @@ class SourcePackageTranslationSharingDetailsView(LaunchpadView):
         return check_permission('launchpad.Edit', self.context.productseries)
 
     def initialize(self):
-        super(SourcePackageTranslationSharingDetailsView, self).initialize()
+        super().initialize()
         if self.is_configuration_complete and not self.is_sharing():
             self.request.response.addInfoNotification(
                 structured(
diff --git a/lib/lp/translations/browser/tests/test_baseexportview.py b/lib/lp/translations/browser/tests/test_baseexportview.py
index 7e62dd0..d4f3488 100644
--- a/lib/lp/translations/browser/tests/test_baseexportview.py
+++ b/lib/lp/translations/browser/tests/test_baseexportview.py
@@ -35,7 +35,7 @@ class BaseExportViewMixin(TestCaseWithFactory):
     def setUp(self):
         # Create a product with two series and a shared POTemplate
         # in different series ('devel' and 'stable').
-        super(BaseExportViewMixin, self).setUp()
+        super().setUp()
 
     def createTranslationTemplate(self, name, priority=0):
         """Attaches a template to appropriate container."""
@@ -142,7 +142,7 @@ class TestProductSeries(BaseExportViewMixin):
         return potemplate
 
     def setUp(self):
-        super(TestProductSeries, self).setUp()
+        super().setUp()
         self.container = self.factory.makeProductSeries()
         self.view = ProductSeriesTranslationsExportView(
             self.container, LaunchpadTestRequest())
@@ -159,7 +159,7 @@ class TestSourcePackage(BaseExportViewMixin):
         return potemplate
 
     def setUp(self):
-        super(TestSourcePackage, self).setUp()
+        super().setUp()
         self.container = self.factory.makeSourcePackage()
         self.view = SourcePackageTranslationsExportView(
             self.container, LaunchpadTestRequest())
@@ -170,7 +170,7 @@ class TestPOExportQueueStatusDescriptions(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestPOExportQueueStatusDescriptions, self).setUp()
+        super().setUp()
         self.container = self.factory.makeProductSeries()
         self.view = ProductSeriesTranslationsExportView(
             self.container, LaunchpadTestRequest())
diff --git a/lib/lp/translations/browser/tests/test_breadcrumbs.py b/lib/lp/translations/browser/tests/test_breadcrumbs.py
index 2033298..75be521 100644
--- a/lib/lp/translations/browser/tests/test_breadcrumbs.py
+++ b/lib/lp/translations/browser/tests/test_breadcrumbs.py
@@ -104,7 +104,7 @@ class TestTranslationGroupsBreadcrumbs(BaseBreadcrumbTestCase):
 class TestSeriesLanguageBreadcrumbs(BaseBreadcrumbTestCase):
 
     def setUp(self):
-        super(TestSeriesLanguageBreadcrumbs, self).setUp()
+        super().setUp()
         self.language = getUtility(ILanguageSet)['sr']
 
     def test_distroserieslanguage(self):
@@ -175,7 +175,7 @@ class TestPOTemplateBreadcrumbs(BaseBreadcrumbTestCase):
 class TestPOFileBreadcrumbs(BaseBreadcrumbTestCase):
 
     def setUp(self):
-        super(TestPOFileBreadcrumbs, self).setUp()
+        super().setUp()
 
     def test_pofiletranslate(self):
         product = self.factory.makeProduct(
diff --git a/lib/lp/translations/browser/tests/test_noindex.py b/lib/lp/translations/browser/tests/test_noindex.py
index a1bc130..5383319 100644
--- a/lib/lp/translations/browser/tests/test_noindex.py
+++ b/lib/lp/translations/browser/tests/test_noindex.py
@@ -86,7 +86,7 @@ class TestRobotsProduct(BrowserTestCase, TestRobotsMixin):
     """Test noindex,nofollow for products."""
 
     def setUp(self):
-        super(TestRobotsProduct, self).setUp()
+        super().setUp()
         self.target = self.factory.makeProduct()
         self.factory.makePOTemplate(
             productseries=self.target.development_focus)
@@ -97,7 +97,7 @@ class TestRobotsProjectGroup(BrowserTestCase, TestRobotsMixin):
     """Test noindex,nofollow for project groups."""
 
     def setUp(self):
-        super(TestRobotsProjectGroup, self).setUp()
+        super().setUp()
         self.target = self.factory.makeProject()
         self.product = self.factory.makeProduct()
         self.factory.makePOTemplate(
@@ -110,7 +110,7 @@ class TestRobotsProductSeries(BrowserTestCase, TestRobotsMixin):
     """Test noindex,nofollow for product series."""
 
     def setUp(self):
-        super(TestRobotsProductSeries, self).setUp()
+        super().setUp()
         self.product = self.factory.makeProduct()
         self.target = self.product.development_focus
         self.factory.makePOTemplate(
@@ -122,7 +122,7 @@ class TestRobotsDistroSeries(BrowserTestCase, TestRobotsMixin):
     """Test noindex,nofollow for distro series."""
 
     def setUp(self):
-        super(TestRobotsDistroSeries, self).setUp()
+        super().setUp()
         login_person(self.user)
         self.distro = self.factory.makeDistribution(
             name="whobuntu", owner=self.user)
@@ -140,7 +140,7 @@ class TestRobotsDistro(BrowserTestCase, TestRobotsMixin):
     """Test noindex,nofollow for distro."""
 
     def setUp(self):
-        super(TestRobotsDistro, self).setUp()
+        super().setUp()
         login_person(self.user)
         self.target = self.factory.makeDistribution(
             name="whobuntu", owner=self.user)
diff --git a/lib/lp/translations/browser/tests/test_persontranslationview.py b/lib/lp/translations/browser/tests/test_persontranslationview.py
index 98ff0ba..e3c1251 100644
--- a/lib/lp/translations/browser/tests/test_persontranslationview.py
+++ b/lib/lp/translations/browser/tests/test_persontranslationview.py
@@ -26,7 +26,7 @@ class TestPersonTranslationView(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestPersonTranslationView, self).setUp()
+        super().setUp()
         person = removeSecurityProxy(self.factory.makePerson())
         self.view = PersonTranslationView(person, LaunchpadTestRequest())
         self.translationgroup = None
@@ -388,7 +388,7 @@ class TestPersonTranslationViewPermissions(BrowserTestCase):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestPersonTranslationViewPermissions, self).setUp()
+        super().setUp()
         self.context = self.factory.makePerson()
         self.language = self.factory.makeLanguage()
         with person_logged_in(self.context):
diff --git a/lib/lp/translations/browser/tests/test_poexportrequest_views.py b/lib/lp/translations/browser/tests/test_poexportrequest_views.py
index fdcd704..cda3a05 100644
--- a/lib/lp/translations/browser/tests/test_poexportrequest_views.py
+++ b/lib/lp/translations/browser/tests/test_poexportrequest_views.py
@@ -42,7 +42,7 @@ class TestPOTEmplateExportView(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestPOTEmplateExportView, self).setUp()
+        super().setUp()
         self.potemplate = self.factory.makePOTemplate()
         # All exports can be requested by an unprivileged user.
         self.translator = self.factory.makePerson()
diff --git a/lib/lp/translations/browser/tests/test_pofile_view.py b/lib/lp/translations/browser/tests/test_pofile_view.py
index 2a45878..3c50614 100644
--- a/lib/lp/translations/browser/tests/test_pofile_view.py
+++ b/lib/lp/translations/browser/tests/test_pofile_view.py
@@ -92,7 +92,7 @@ class TestPOFileTranslateViewInvalidFiltering(TestCaseWithFactory):
     view_class = POFileTranslateView
 
     def setUp(self):
-        super(TestPOFileTranslateViewInvalidFiltering, self).setUp()
+        super().setUp()
         self.pofile = self.factory.makePOFile('eo')
 
     def _test_parameter_list(self, parameter_name):
@@ -366,7 +366,7 @@ class TestBrowser(BrowserTestCase):
             product.translationpermission = TranslationPermission.CLOSED
         # Add credits so that they show in the UI
         self.factory.makePOTMsgSet(
-            potemplate=pofile.potemplate, singular=u'translator-credits')
+            potemplate=pofile.potemplate, singular='translator-credits')
         browser = self.getViewBrowser(pofile)
         self.assertNotIn('This is a dummy translation', browser.contents)
         self.assertIn('(no translation yet)', browser.contents)
@@ -376,7 +376,7 @@ class TestBrowser(BrowserTestCase):
         pofile = self.factory.makePOFile()
         # Add credits so that they show in the UI
         self.factory.makePOTMsgSet(
-            potemplate=pofile.potemplate, singular=u'translator-credits')
+            potemplate=pofile.potemplate, singular='translator-credits')
         browser = self.getViewBrowser(pofile, no_login=True)
         self.assertTextMatchesExpressionIgnoreWhitespace(
             'To prevent privacy issues, this translation is not available to'
diff --git a/lib/lp/translations/browser/tests/test_potemplate_views.py b/lib/lp/translations/browser/tests/test_potemplate_views.py
index 78dc73b..4a85ac4 100644
--- a/lib/lp/translations/browser/tests/test_potemplate_views.py
+++ b/lib/lp/translations/browser/tests/test_potemplate_views.py
@@ -29,13 +29,11 @@ class TestPOTemplateEditViewValidation(WithScenarios, TestCaseWithFactory):
 
     scenarios = [
         ("spn_picker", {"features": {}}),
-        ("dsp_picker", {
-            "features": {u"disclosure.dsp_picker.enabled": u"on"},
-            }),
+        ("dsp_picker", {"features": {"disclosure.dsp_picker.enabled": "on"}}),
         ]
 
     def setUp(self):
-        super(TestPOTemplateEditViewValidation, self).setUp()
+        super().setUp()
         if self.features:
             self.useFixture(FeatureFixture(self.features))
 
@@ -84,9 +82,9 @@ class TestPOTemplateEditViewValidation(WithScenarios, TestCaseWithFactory):
         view.validate(data)
         self.assertEqual(
             [html_escape(
-                u'Template name can only start with lowercase letters a-z '
-                u'or digits 0-9, and other than those characters, can only '
-                u'contain "-", "+" and "." characters.')],
+                'Template name can only start with lowercase letters a-z '
+                'or digits 0-9, and other than those characters, can only '
+                'contain "-", "+" and "." characters.')],
             view.errors)
 
     def test_detects_name_clash_on_name_change(self):
@@ -99,7 +97,7 @@ class TestPOTemplateEditViewValidation(WithScenarios, TestCaseWithFactory):
         view = POTemplateEditView(potemplate, LaunchpadTestRequest())
         data = self._makeData(potemplate, name=existing_name)
         view.validate(data)
-        self.assertEqual([u'Name is already in use.'], view.errors)
+        self.assertEqual(['Name is already in use.'], view.errors)
 
     def test_detects_domain_clash_on_domain_change(self):
         # A translation domain may not already be used.
@@ -112,7 +110,7 @@ class TestPOTemplateEditViewValidation(WithScenarios, TestCaseWithFactory):
         view = POTemplateEditView(potemplate, LaunchpadTestRequest())
         data = self._makeData(potemplate, translation_domain=existing_domain)
         view.validate(data)
-        self.assertEqual([u'Domain is already in use.'], view.errors)
+        self.assertEqual(['Domain is already in use.'], view.errors)
 
     def test_detects_name_clash_on_sourcepackage_change(self):
         # Detect changing to a source package that already has a template of
@@ -129,7 +127,7 @@ class TestPOTemplateEditViewValidation(WithScenarios, TestCaseWithFactory):
             potemplate, sourcepackagename=sourcepackage.sourcepackagename)
         view.validate(data)
         self.assertEqual(
-            [u'Source package already has a template with that same name.'],
+            ['Source package already has a template with that same name.'],
             view.errors)
 
     def test_detects_domain_clash_on_sourcepackage_change(self):
@@ -147,7 +145,7 @@ class TestPOTemplateEditViewValidation(WithScenarios, TestCaseWithFactory):
             potemplate, sourcepackagename=sourcepackage.sourcepackagename)
         view.validate(data)
         self.assertEqual(
-            [u'Source package already has a template with that same domain.'],
+            ['Source package already has a template with that same domain.'],
             view.errors)
 
     def test_change_sourcepackage(self):
@@ -182,7 +180,7 @@ class TestPOTemplateAdminViewValidation(TestPOTemplateEditViewValidation):
         data = self._makeData(potemplate, productseries=new_series)
         view.validate(data)
         self.assertEqual(
-            [u'Series already has a template with that same name.'],
+            ['Series already has a template with that same name.'],
             view.errors)
 
     def test_detects_domain_clash_on_productseries_change(self):
@@ -199,7 +197,7 @@ class TestPOTemplateAdminViewValidation(TestPOTemplateEditViewValidation):
         data = self._makeData(potemplate, productseries=new_series)
         view.validate(data)
         self.assertEqual(
-            [u'Series already has a template with that same domain.'],
+            ['Series already has a template with that same domain.'],
             view.errors)
 
     def test_detects_no_sourcepackage_or_productseries(self):
@@ -212,8 +210,8 @@ class TestPOTemplateAdminViewValidation(TestPOTemplateEditViewValidation):
             distroseries=None, sourcepackagename=None, productseries=None)
         view.validate(data)
         self.assertEqual(
-            [u'Choose either a distribution release series or a project '
-             u'release series.'], view.errors)
+            ['Choose either a distribution release series or a project '
+             'release series.'], view.errors)
 
     def test_detects_sourcepackage_and_productseries(self):
         # Detect if no source package or productseries was selected.
@@ -228,8 +226,8 @@ class TestPOTemplateAdminViewValidation(TestPOTemplateEditViewValidation):
             productseries=potemplate.productseries)
         view.validate(data)
         self.assertEqual(
-            [u'Choose a distribution release series or a project '
-             u'release series, but not both.'], view.errors)
+            ['Choose a distribution release series or a project '
+             'release series, but not both.'], view.errors)
 
     def test_change_from_sourcepackage(self):
         # Changing the source package the template comes from is honoured.
diff --git a/lib/lp/translations/browser/tests/test_product_view.py b/lib/lp/translations/browser/tests/test_product_view.py
index 1b380c5..83b69cc 100644
--- a/lib/lp/translations/browser/tests/test_product_view.py
+++ b/lib/lp/translations/browser/tests/test_product_view.py
@@ -96,13 +96,13 @@ class TestProduct(TestCaseWithFactory):
         # include obsolete series.
         series_names = [series.name for series in view.untranslatable_series]
         self.assertEqual([
-            u'evo-current',
-            u'evo-development',
-            u'evo-experimental',
-            u'evo-frozen',
-            u'evo-future',
-            u'evo-supported',
-            u'trunk'], series_names)
+            'evo-current',
+            'evo-development',
+            'evo-experimental',
+            'evo-frozen',
+            'evo-future',
+            'evo-supported',
+            'trunk'], series_names)
 
 
 class TestCanConfigureTranslations(TestCaseWithFactory):
diff --git a/lib/lp/translations/browser/tests/test_productserieslanguage_views.py b/lib/lp/translations/browser/tests/test_productserieslanguage_views.py
index d62bfbf..319f05c 100644
--- a/lib/lp/translations/browser/tests/test_productserieslanguage_views.py
+++ b/lib/lp/translations/browser/tests/test_productserieslanguage_views.py
@@ -28,7 +28,7 @@ class TestProductSeriesView(TestCaseWithFactory):
 
     def setUp(self):
         # Create a productseries that uses translations.
-        super(TestProductSeriesView, self).setUp()
+        super().setUp()
         self.productseries = self.factory.makeProductSeries()
         self.product = self.productseries.product
 
@@ -67,7 +67,7 @@ class TestProductSeriesView(TestCaseWithFactory):
         # After adding a translation group with a documentation URL lets
         # `has_translation_documentation` be True.
         self.product.translationgroup = self.factory.makeTranslationGroup(
-            self.productseries.product.owner, url=u'http://something')
+            self.productseries.product.owner, url='http://something')
         view = self._createView()
         self.assertTrue(view.has_translation_documentation)
 
@@ -162,7 +162,7 @@ class TestProductSeriesViewBzrUsage(TestCaseWithFactory):
     def setUp(self):
         # Create a productseries that uses translations.
         # Strip off the security proxy to allow customization.
-        super(TestProductSeriesViewBzrUsage, self).setUp()
+        super().setUp()
         self.secured_productseries = self.factory.makeProductSeries()
         self.productseries = removeSecurityProxy(self.secured_productseries)
 
@@ -251,7 +251,7 @@ class TestProductSeriesLanguageView(TestCaseWithFactory):
 
     def setUp(self):
         # Create a productseries that uses translations.
-        super(TestProductSeriesLanguageView, self).setUp()
+        super().setUp()
         self.productseries = self.factory.makeProductSeries()
         self.language = self.factory.makeLanguage()
         potemplate = self.factory.makePOTemplate(
diff --git a/lib/lp/translations/browser/tests/test_sharing_details.py b/lib/lp/translations/browser/tests/test_sharing_details.py
index ee6f04d..b2c068c 100644
--- a/lib/lp/translations/browser/tests/test_sharing_details.py
+++ b/lib/lp/translations/browser/tests/test_sharing_details.py
@@ -90,7 +90,7 @@ class TestSourcePackageTranslationSharingDetailsView(TestCaseWithFactory,
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestSourcePackageTranslationSharingDetailsView, self).setUp()
+        super().setUp()
         distroseries = self.factory.makeUbuntuDistroSeries()
         self.sourcepackage = self.factory.makeSourcePackage(
             distroseries=distroseries)
diff --git a/lib/lp/translations/browser/tests/test_translationgroup.py b/lib/lp/translations/browser/tests/test_translationgroup.py
index 0f3fc46..2b642d6 100644
--- a/lib/lp/translations/browser/tests/test_translationgroup.py
+++ b/lib/lp/translations/browser/tests/test_translationgroup.py
@@ -23,7 +23,7 @@ class TestTranslationGroupView(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestTranslationGroupView, self).setUp()
+        super().setUp()
 
     def _makeView(self, group, name=None):
         """Create a view for self.group."""
diff --git a/lib/lp/translations/browser/tests/test_translationimportqueueentry.py b/lib/lp/translations/browser/tests/test_translationimportqueueentry.py
index 8f5347d..ac7c9ab 100644
--- a/lib/lp/translations/browser/tests/test_translationimportqueueentry.py
+++ b/lib/lp/translations/browser/tests/test_translationimportqueueentry.py
@@ -36,14 +36,11 @@ class TestTranslationImportQueueEntryView(WithScenarios, TestCaseWithFactory):
 
     scenarios = [
         ("spn_picker", {"features": {}}),
-        ("dsp_picker", {
-            "features": {u"disclosure.dsp_picker.enabled": u"on"},
-            }),
+        ("dsp_picker", {"features": {"disclosure.dsp_picker.enabled": "on"}}),
         ]
 
     def setUp(self):
-        super(TestTranslationImportQueueEntryView, self).setUp(
-            'foo.bar@xxxxxxxxxxxxx')
+        super().setUp('foo.bar@xxxxxxxxxxxxx')
         if self.features:
             self.useFixture(FeatureFixture(self.features))
         self.queue = getUtility(ITranslationImportQueue)
diff --git a/lib/lp/translations/browser/tests/test_translationlinksaggregator.py b/lib/lp/translations/browser/tests/test_translationlinksaggregator.py
index 2bab92a..1106ff1 100644
--- a/lib/lp/translations/browser/tests/test_translationlinksaggregator.py
+++ b/lib/lp/translations/browser/tests/test_translationlinksaggregator.py
@@ -48,7 +48,7 @@ class TestTranslationLinksAggregator(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestTranslationLinksAggregator, self).setUp()
+        super().setUp()
         self.aggregator = DumbAggregator()
 
     def test_circumscribe_single_pofile(self):
diff --git a/lib/lp/translations/browser/tests/test_translationmessage_view.py b/lib/lp/translations/browser/tests/test_translationmessage_view.py
index 3b7ecc0..0c84403 100644
--- a/lib/lp/translations/browser/tests/test_translationmessage_view.py
+++ b/lib/lp/translations/browser/tests/test_translationmessage_view.py
@@ -49,7 +49,7 @@ class TestCurrentTranslationMessage_can_dismiss(TestCaseWithFactory):
             now += timedelta(milliseconds=1)
 
     def setUp(self):
-        super(TestCurrentTranslationMessage_can_dismiss, self).setUp()
+        super().setUp()
         self.owner = self.factory.makePerson()
         self.potemplate = self.factory.makePOTemplate(owner=self.owner)
         self.pofile = self.factory.makePOFile(potemplate=self.potemplate)
@@ -155,7 +155,7 @@ class TestCurrentTranslationMessage_can_dismiss(TestCaseWithFactory):
         # in yet a different place.
         self.potmsgset = self.factory.makePOTMsgSet(
             self.potemplate,
-            singular=u"msgid_singular", plural=u"msgid_plural")
+            singular="msgid_singular", plural="msgid_plural")
         message = self._makeTranslation(["singular_trans", "plural_trans"])
         self._makeTranslation(
             ["singular_sugg", "plural_sugg"], suggestion=True)
@@ -182,7 +182,7 @@ class TestCurrentTranslationMessage_can_dismiss(TestCaseWithFactory):
         # in yet a different place.
         self.potmsgset = self.factory.makePOTMsgSet(
             self.potemplate,
-            singular=u"msgid_singular", plural=u"msgid_plural")
+            singular="msgid_singular", plural="msgid_plural")
         message = self._makeTranslation(["singular_trans", "plural_trans"])
         self._makeTranslation(["singular_new", "plural_new"], is_other=True)
         self._createView(message)
@@ -218,7 +218,7 @@ class TestResetTranslations(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestResetTranslations, self).setUp()
+        super().setUp()
         package = self.factory.makeSourcePackage()
         template = self.factory.makePOTemplate(
             distroseries=package.distroseries,
@@ -246,7 +246,7 @@ class TestResetTranslations(TestCaseWithFactory):
 
     def submitForcedEmptySuggestion(self):
         """Submit an empty suggestion for `self.current_translation`."""
-        empty_translation = u''
+        empty_translation = ''
 
         msgset_id = 'msgset_' + str(self.current_translation.potmsgset.id)
         msgset_id_lang = msgset_id + '_' + self.pofile.language.code
@@ -310,13 +310,13 @@ class TestCurrentTranslationMessagePageView(TestCaseWithFactory):
         form = {}
         if with_form:
             msgset_id_field = 'msgset_%d' % potmsgset.id
-            form[msgset_id_field] = u'poit'
+            form[msgset_id_field] = 'poit'
             base_field_name = 'msgset_%d_%s_translation_' % (
                 message.potmsgset.id, pofile.language.code)
             # Add the expected plural forms fields.
             for plural_form in range(TranslationConstants.MAX_PLURAL_FORMS):
                 field_name = '%s%d_new' % (base_field_name, plural_form)
-                form[field_name] = u'snarf'
+                form[field_name] = 'snarf'
         url = '/%s/%s/%s/+translate' % (
             canonical_url(potemplate), pofile.language.code, 1)
         request = LaunchpadTestRequest(SERVER_URL=url, form=form)
@@ -326,7 +326,7 @@ class TestCurrentTranslationMessagePageView(TestCaseWithFactory):
 
     def test_extractLockTimestamp(self):
         view = self._makeView()
-        view.request.form['lock_timestamp'] = u'2010-01-01 00:00:00 UTC'
+        view.request.form['lock_timestamp'] = '2010-01-01 00:00:00 UTC'
         self.assertEqual(
             datetime(2010, 1, 1, tzinfo=pytz.utc),
             view._extractLockTimestamp())
@@ -337,7 +337,7 @@ class TestCurrentTranslationMessagePageView(TestCaseWithFactory):
 
     def test_extractLockTimestamp_returns_None_for_bogus_timestamp(self):
         view = self._makeView()
-        view.request.form['lock_timestamp'] = u'Hi mom!'
+        view.request.form['lock_timestamp'] = 'Hi mom!'
         self.assertIs(None, view._extractLockTimestamp())
 
     def test_checkSubmitConditions_passes(self):
@@ -383,7 +383,7 @@ class TestCurrentTranslationMessagePageView(TestCaseWithFactory):
         field_name = 'msgset_%d_%s_translation_%d_new' % (
             view.context.potmsgset.id, view.pofile.language.code,
             TranslationConstants.MAX_PLURAL_FORMS)
-        view.request.form[field_name] = u'snarf'
+        view.request.form[field_name] = 'snarf'
         self.assertRaises(AssertionError,
             view._extractFormPostedTranslations, view.context.potmsgset)
 
@@ -401,7 +401,7 @@ class TestHelpers(TestCaseWithFactory):
                 contains_translations({plural_form: self.getUniqueString()}))
 
     def test_contains_translations_ignores_empty_strings(self):
-        self.assertFalse(contains_translations({0: u''}))
+        self.assertFalse(contains_translations({0: ''}))
 
     def test_contains_translations_ignores_nones(self):
         self.assertFalse(contains_translations({0: None}))
@@ -436,7 +436,7 @@ class TestHelpers(TestCaseWithFactory):
             translations, None, [0])
         self.assertEqual(translations[0], resulting_translations[0])
         self.assertNotEqual(translations[1], resulting_translations[1])
-        self.assertEqual(u'', resulting_translations[1])
+        self.assertEqual('', resulting_translations[1])
 
     def test_revert_unselected_translations_ignores_untranslated_form(self):
         translations = {0: self.getUniqueString()}
@@ -461,7 +461,7 @@ class TestHelpers(TestCaseWithFactory):
         # plural_indices_to_store is set to the empty string.
         translations = {0: self.getUniqueString()}
         self.assertEqual(
-            {0: u''}, revert_unselected_translations(translations, None, []))
+            {0: ''}, revert_unselected_translations(translations, None, []))
 
     def test_revert_unselected_translations_handles_missing_plurals(self):
         # When reverting based on a current message that does not
@@ -472,7 +472,7 @@ class TestHelpers(TestCaseWithFactory):
         current_message = self.factory.makeCurrentTranslationMessage(
             translations=original_translations)
         self.assertEqual(
-            {1: u''},
+            {1: ''},
             revert_unselected_translations(
                 new_translations, current_message, []))
 
diff --git a/lib/lp/translations/browser/translationgroup.py b/lib/lp/translations/browser/translationgroup.py
index c93538c..eb64a92 100644
--- a/lib/lp/translations/browser/translationgroup.py
+++ b/lib/lp/translations/browser/translationgroup.py
@@ -53,7 +53,7 @@ class TranslationGroupSetNavigation(GetitemNavigation):
 
 class TranslationGroupSetBreadcrumb(Breadcrumb):
     """Builds a breadcrumb for an `ITranslationGroupSet`."""
-    text = u"Translation groups"
+    text = "Translation groups"
 
 
 class TranslationGroupSetView(LaunchpadView):
@@ -65,7 +65,7 @@ class TranslationGroupSetView(LaunchpadView):
 class TranslationGroupView(LaunchpadView):
 
     def __init__(self, context, request):
-        super(TranslationGroupView, self).__init__(context, request)
+        super().__init__(context, request)
         self.context = context
         self.request = request
         self.translation_groups = getUtility(ITranslationGroupSet)
diff --git a/lib/lp/translations/browser/translationimportqueue.py b/lib/lp/translations/browser/translationimportqueue.py
index 556b3a5..a3790c3 100644
--- a/lib/lp/translations/browser/translationimportqueue.py
+++ b/lib/lp/translations/browser/translationimportqueue.py
@@ -167,7 +167,7 @@ class TranslationImportQueueEntryView(LaunchpadFormView):
                 # as its filename. We try to get it to use as a suggestion.
                 language_set = getUtility(ILanguageSet)
                 filename = os.path.basename(self.context.path)
-                guessed_language, file_ext = filename.split(u'.', 1)
+                guessed_language, file_ext = filename.split('.', 1)
                 language = language_set.getLanguageByCode(guessed_language)
                 if language is not None:
                     field_values['language'] = language
@@ -596,7 +596,7 @@ class TranslationImportQueueView(HasTranslationImportsView):
 
     def initialize(self):
         """Useful initialization for this view class."""
-        super(TranslationImportQueueView, self).initialize()
+        super().initialize()
         target_filter = self.widgets['filter_target']
         if target_filter.hasInput() and not target_filter.hasValidInput():
             raise UnexpectedFormData("Unknown target.")
diff --git a/lib/lp/translations/browser/translationlinksaggregator.py b/lib/lp/translations/browser/translationlinksaggregator.py
index d22ed82..7d250b2 100644
--- a/lib/lp/translations/browser/translationlinksaggregator.py
+++ b/lib/lp/translations/browser/translationlinksaggregator.py
@@ -5,8 +5,6 @@ __all__ = [
     'TranslationLinksAggregator',
     ]
 
-import six
-
 from lp.services.webapp import canonical_url
 from lp.translations.interfaces.pofile import IPOFile
 from lp.translations.model.productserieslanguage import ProductSeriesLanguage
@@ -177,10 +175,10 @@ class TranslationLinksAggregator:
             returns for the sensible chunks.
         """
         links = []
-        for target, sheets in six.iteritems(self._bundle(sheets)):
+        for target, sheets in self._bundle(sheets).items():
             assert sheets, "Translation target has no POFiles or templates."
             links_and_sheets = self._circumscribe(sheets)
-            for link, covered_sheets in six.iteritems(links_and_sheets):
+            for link, covered_sheets in links_and_sheets.items():
                 links.append(self.describe(target, link, covered_sheets))
 
         return links
diff --git a/lib/lp/translations/browser/translationmessage.py b/lib/lp/translations/browser/translationmessage.py
index 5087c92..4f904d9 100644
--- a/lib/lp/translations/browser/translationmessage.py
+++ b/lib/lp/translations/browser/translationmessage.py
@@ -21,7 +21,6 @@ import operator
 import re
 
 import pytz
-import six
 from six.moves.urllib.parse import (
     parse_qsl,
     urlencode,
@@ -95,11 +94,11 @@ def revert_unselected_translations(translations, current_message,
         original_translations = dict(enumerate(current_message.translations))
 
     output = {}
-    for plural_form, translation in six.iteritems(translations):
+    for plural_form, translation in translations.items():
         if plural_form in plural_indices_to_store:
             output[plural_form] = translation
         elif original_translations.get(plural_form) is None:
-            output[plural_form] = u''
+            output[plural_form] = ''
         else:
             output[plural_form] = original_translations[plural_form]
 
@@ -112,7 +111,7 @@ def contains_translations(translations):
     :param translations: a dict mapping plural forms to their respective
         translation strings.
     """
-    for text in six.itervalues(translations):
+    for text in translations.values():
         if text is not None and len(text) != 0:
             return True
     return False
@@ -219,8 +218,7 @@ class CurrentTranslationMessageIndexView(RedirectionView):
 
     def __init__(self, context, request):
         target = canonical_url(context, view_name='+translate')
-        super(CurrentTranslationMessageIndexView, self).__init__(
-            target, request)
+        super().__init__(target, request)
 
 
 def _getSuggestionFromFormId(form_id):
@@ -358,7 +356,7 @@ class BaseTranslationView(LaunchpadView):
         """
         try:
             return zope_datetime.parseDatetimetz(
-                self.request.form.get('lock_timestamp', u''))
+                self.request.form.get('lock_timestamp', ''))
         except zope_datetime.DateTimeError:
             # invalid format. Either we don't have the timestamp in the
             # submitted form or it has the wrong format.
@@ -439,7 +437,7 @@ class BaseTranslationView(LaunchpadView):
         try:
             self._storeTranslations(potmsgset)
         except GettextValidationError as e:
-            return six.text_type(e)
+            return str(e)
         except TranslationConflict:
             # The translations are demoted to suggestions, but they may
             # still affect the "messages with new suggestions" filter.
@@ -644,7 +642,7 @@ class BaseTranslationView(LaunchpadView):
                     editlanguages_url = canonical_url(
                         self.user, view_name="+editlanguages")
                     self.request.response.addInfoNotification(structured(
-                        u"Not showing suggestions from selected alternative "
+                        "Not showing suggestions from selected alternative "
                         "language %(alternative)s.  If you wish to see "
                         "suggestions from this language, "
                         '<a href="%(editlanguages_url)s">'
@@ -791,7 +789,7 @@ class BaseTranslationView(LaunchpadView):
                     else:
                         # Current translation is None, this code expects u''
                         # when there is no translation.
-                        value = u''
+                        value = ''
                 # Current user is an official translator and the radio button
                 # for 'New translation' is selected, so we are sure we want to
                 # store this submission.
@@ -1167,7 +1165,7 @@ class CurrentTranslationMessageView(LaunchpadView):
             if self.message_must_be_hidden:
                 # We must hide the translation because it may have private
                 # info that we don't want to show to anonymous users.
-                translation_entry['current_translation'] = u'''
+                translation_entry['current_translation'] = '''
                     To prevent privacy issues, this translation is not
                     available to anonymous users,<br />
                     if you want to see it, please, <a href="+login">log in</a>
@@ -1668,7 +1666,7 @@ def convert_translationmessage_to_submission(
     submission.legal_warning = legal_warning_needed and (
         message.origin == RosettaTranslationOrigin.SCM)
     submission.suggestion_html_id = (
-        current_message.potmsgset.makeHTMLID(u'%s_suggestion_%s_%s' % (
+        current_message.potmsgset.makeHTMLID('%s_suggestion_%s_%s' % (
             message.language.code, message.id,
             plural_form)))
     if other_side:
@@ -1679,14 +1677,13 @@ def convert_translationmessage_to_submission(
         submission.row_html_id = ''
         submission.origin_html_id = submission.suggestion_html_id + '_origin'
     submission.translation_html_id = (
-        current_message.makeHTMLID(
-            u'translation_%s' % (plural_form)))
+        current_message.makeHTMLID('translation_%s' % (plural_form)))
 
     suggestion_dismissable_class = message.potmsgset.makeHTMLID(
-        u'dismissable_button')
+        'dismissable_button')
     if submission.is_local_to_pofile:
-        suggestion_dismissable_class += u' ' + message.potmsgset.makeHTMLID(
-            u'dismissable')
+        suggestion_dismissable_class += ' ' + message.potmsgset.makeHTMLID(
+            'dismissable')
     submission.suggestion_dismissable_class = suggestion_dismissable_class
 
     return submission
diff --git a/lib/lp/translations/browser/translations.py b/lib/lp/translations/browser/translations.py
index be77832..61b99b1 100644
--- a/lib/lp/translations/browser/translations.py
+++ b/lib/lp/translations/browser/translations.py
@@ -153,8 +153,7 @@ class TranslationsRedirectView(RedirectionView):
     def __init__(self, context, request):
         target = canonical_url(
             context, rootsite='translations', view_name='+translations')
-        super(TranslationsRedirectView, self).__init__(
-            target, request, status=301)
+        super().__init__(target, request, status=301)
 
 
 class TranslationsLanguageBreadcrumb(Breadcrumb):
diff --git a/lib/lp/translations/browser/widgets/tests/test_potemplate.py b/lib/lp/translations/browser/widgets/tests/test_potemplate.py
index 8763ebe..e52ece0 100644
--- a/lib/lp/translations/browser/widgets/tests/test_potemplate.py
+++ b/lib/lp/translations/browser/widgets/tests/test_potemplate.py
@@ -32,13 +32,13 @@ class TestPOTemplateEditSourcePackageNameWidget(
             "interface": IPOTemplate,
             }),
         ("dsp_picker", {
-            "features": {u"disclosure.dsp_picker.enabled": u"on"},
+            "features": {"disclosure.dsp_picker.enabled": "on"},
             "interface": IPOTemplateEditForm,
             }),
         ]
 
     def setUp(self):
-        super(TestPOTemplateEditSourcePackageNameWidget, self).setUp()
+        super().setUp()
         if self.features:
             self.useFixture(FeatureFixture(self.features))
 
@@ -75,13 +75,13 @@ class TestPOTemplateAdminSourcePackageNameWidget(
             "interface": IPOTemplate,
             }),
         ("dsp_picker", {
-            "features": {u"disclosure.dsp_picker.enabled": u"on"},
+            "features": {"disclosure.dsp_picker.enabled": "on"},
             "interface": IPOTemplateEditForm,
             }),
         ]
 
     def setUp(self):
-        super(TestPOTemplateAdminSourcePackageNameWidget, self).setUp()
+        super().setUp()
         if self.features:
             self.useFixture(FeatureFixture(self.features))
 
diff --git a/lib/lp/translations/browser/widgets/tests/test_translationimportqueue.py b/lib/lp/translations/browser/widgets/tests/test_translationimportqueue.py
index e7dcf3c..8729a03 100644
--- a/lib/lp/translations/browser/widgets/tests/test_translationimportqueue.py
+++ b/lib/lp/translations/browser/widgets/tests/test_translationimportqueue.py
@@ -34,15 +34,13 @@ class TestTranslationImportQueueEntrySourcePackageNameWidget(
             "interface": IEditTranslationImportQueueEntry,
             }),
         ("dsp_picker", {
-            "features": {u"disclosure.dsp_picker.enabled": u"on"},
+            "features": {"disclosure.dsp_picker.enabled": "on"},
             "interface": IEditTranslationImportQueueEntryDSP,
             }),
         ]
 
     def setUp(self):
-        super(
-            TestTranslationImportQueueEntrySourcePackageNameWidget,
-            self).setUp()
+        super().setUp()
         if self.features:
             self.useFixture(FeatureFixture(self.features))