← Back to team overview

launchpad-reviewers team mailing list archive

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

 

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

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

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/413140
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:pyupgrade-py3-bugs-3 into launchpad:master.
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 0d4f803..76048b1 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -45,7 +45,7 @@ repos:
             |archivepublisher
             |archiveuploader
             |blueprints
-            |bugs/(browser|externalbugtracker|interfaces|model)
+            |bugs
           )/
 -   repo: https://github.com/PyCQA/isort
     rev: 5.9.2
diff --git a/lib/lp/bugs/adapters/bugchange.py b/lib/lp/bugs/adapters/bugchange.py
index c7d8dbf..ba0e99a 100644
--- a/lib/lp/bugs/adapters/bugchange.py
+++ b/lib/lp/bugs/adapters/bugchange.py
@@ -168,7 +168,7 @@ class AttributeChange(BugChangeBase):
     """A mixin class that provides basic functionality for `IBugChange`s."""
 
     def __init__(self, when, person, what_changed, old_value, new_value):
-        super(AttributeChange, self).__init__(when, person)
+        super().__init__(when, person)
         self.new_value = new_value
         self.old_value = old_value
         self.what_changed = what_changed
@@ -186,7 +186,7 @@ class UnsubscribedFromBug(BugChangeBase):
     """A user got unsubscribed from a bug."""
 
     def __init__(self, when, person, unsubscribed_user, **kwargs):
-        super(UnsubscribedFromBug, self).__init__(when, person)
+        super().__init__(when, person)
         self.unsubscribed_user = unsubscribed_user
         self.send_notification = kwargs.get('send_notification', False)
         self.notification_text = kwargs.get('notification_text')
@@ -210,7 +210,7 @@ class BugConvertedToQuestion(BugChangeBase):
     """A bug got converted into a question."""
 
     def __init__(self, when, person, question):
-        super(BugConvertedToQuestion, self).__init__(when, person)
+        super().__init__(when, person)
         self.question = question
 
     def getBugActivity(self):
@@ -234,7 +234,7 @@ class BugTaskAdded(BugChangeBase):
     change_level = BugNotificationLevel.LIFECYCLE
 
     def __init__(self, when, person, bug_task):
-        super(BugTaskAdded, self).__init__(when, person)
+        super().__init__(when, person)
         self.bug_task = bug_task
 
     def getBugActivity(self):
@@ -247,20 +247,20 @@ class BugTaskAdded(BugChangeBase):
         """See `IBugChange`."""
         lines = []
         if self.bug_task.bugwatch:
-            lines.append(u"** Also affects: %s via" % (
+            lines.append("** Also affects: %s via" % (
                 self.bug_task.bugtargetname))
-            lines.append(u"   %s" % self.bug_task.bugwatch.url)
+            lines.append("   %s" % self.bug_task.bugwatch.url)
         else:
-            lines.append(u"** Also affects: %s" % (
+            lines.append("** Also affects: %s" % (
                 self.bug_task.bugtargetname))
-        lines.append(u"%13s: %s" % (
-            u"Importance", self.bug_task.importance.title))
+        lines.append("%13s: %s" % (
+            "Importance", self.bug_task.importance.title))
         if self.bug_task.assignee:
             assignee = self.bug_task.assignee
-            lines.append(u"%13s: %s" % (
-                u"Assignee", assignee.unique_displayname))
-        lines.append(u"%13s: %s" % (
-            u"Status", self.bug_task.status.title))
+            lines.append("%13s: %s" % (
+                "Assignee", assignee.unique_displayname))
+        lines.append("%13s: %s" % (
+            "Status", self.bug_task.status.title))
         return {
             'text': '\n'.join(lines),
             }
@@ -272,7 +272,7 @@ class BugTaskDeleted(BugChangeBase):
     change_level = BugNotificationLevel.LIFECYCLE
 
     def __init__(self, when, person, bugtask):
-        super(BugTaskDeleted, self).__init__(when, person)
+        super().__init__(when, person)
         self.targetname = bugtask.bugtargetname
 
     def getBugActivity(self):
@@ -293,7 +293,7 @@ class SeriesNominated(BugChangeBase):
     """A user nominated the bug to be fixed in a series."""
 
     def __init__(self, when, person, series):
-        super(SeriesNominated, self).__init__(when, person)
+        super().__init__(when, person)
         self.series = series
 
     def getBugActivity(self):
@@ -311,7 +311,7 @@ class BugWatchAdded(BugChangeBase):
     """A bug watch was added to the bug."""
 
     def __init__(self, when, person, bug_watch):
-        super(BugWatchAdded, self).__init__(when, person)
+        super().__init__(when, person)
         self.bug_watch = bug_watch
 
     def getBugActivity(self):
@@ -335,7 +335,7 @@ class BugWatchRemoved(BugChangeBase):
     """A bug watch was removed from the bug."""
 
     def __init__(self, when, person, bug_watch):
-        super(BugWatchRemoved, self).__init__(when, person)
+        super().__init__(when, person)
         self.bug_watch = bug_watch
 
     def getBugActivity(self):
@@ -359,7 +359,7 @@ class BranchLinkedToBug(BugChangeBase):
     """A branch got linked to the bug."""
 
     def __init__(self, when, person, branch, bug):
-        super(BranchLinkedToBug, self).__init__(when, person)
+        super().__init__(when, person)
         self.branch = branch
         self.bug = bug
 
@@ -382,7 +382,7 @@ class BranchUnlinkedFromBug(BugChangeBase):
     """A branch got unlinked from the bug."""
 
     def __init__(self, when, person, branch, bug):
-        super(BranchUnlinkedFromBug, self).__init__(when, person)
+        super().__init__(when, person)
         self.branch = branch
         self.bug = bug
 
@@ -405,7 +405,7 @@ class MergeProposalLinkedToBug(BugChangeBase):
     """A merge proposal got linked to the bug."""
 
     def __init__(self, when, person, merge_proposal, bug):
-        super(MergeProposalLinkedToBug, self).__init__(when, person)
+        super().__init__(when, person)
         self.merge_proposal = merge_proposal
         self.bug = bug
 
@@ -432,7 +432,7 @@ class MergeProposalUnlinkedFromBug(BugChangeBase):
     """A merge proposal got unlinked from the bug."""
 
     def __init__(self, when, person, merge_proposal, bug):
-        super(MergeProposalUnlinkedFromBug, self).__init__(when, person)
+        super().__init__(when, person)
         self.merge_proposal = merge_proposal
         self.bug = bug
 
@@ -463,7 +463,7 @@ class BugDescriptionChange(AttributeChange):
         description_diff = get_unified_diff(
             self.old_value, self.new_value, 72)
         notification_text = (
-            u"** Description changed:\n\n%s" % description_diff)
+            "** Description changed:\n\n%s" % description_diff)
         return {'text': notification_text}
 
 
@@ -584,7 +584,7 @@ class BugTitleChange(AttributeChange):
     """Describes a change to a bug's title, aka summary."""
 
     def getBugActivity(self):
-        activity = super(BugTitleChange, self).getBugActivity()
+        activity = super().getBugActivity()
 
         # We return 'summary' instead of 'title' for title changes
         # because the bug's title is referred to as its summary in the
@@ -703,7 +703,7 @@ class CveLinkedToBug(BugChangeBase):
     """Used to represent the linking of a CVE to a bug."""
 
     def __init__(self, when, person, cve):
-        super(CveLinkedToBug, self).__init__(when, person)
+        super().__init__(when, person)
         self.cve = cve
 
     def getBugActivity(self):
@@ -721,7 +721,7 @@ class CveUnlinkedFromBug(BugChangeBase):
     """Used to represent the unlinking of a CVE from a bug."""
 
     def __init__(self, when, person, cve):
-        super(CveUnlinkedFromBug, self).__init__(when, person)
+        super().__init__(when, person)
         self.cve = cve
 
     def getBugActivity(self):
@@ -749,8 +749,7 @@ class BugTaskAttributeChange(AttributeChange):
 
     def __init__(self, bug_task, when, person, what_changed, old_value,
                  new_value):
-        super(BugTaskAttributeChange, self).__init__(
-            when, person, what_changed, old_value, new_value)
+        super().__init__(when, person, what_changed, old_value, new_value)
         self.bug_task = bug_task
 
         if self.old_value is None:
@@ -802,7 +801,7 @@ class BugTaskAttributeChange(AttributeChange):
         make it clear in which task the change was made.
         """
         text = (
-            u"** Changed in: %(bug_target_name)s\n"
+            "** Changed in: %(bug_target_name)s\n"
             "%(label)13s: %(oldval)s => %(newval)s\n" % {
                 'bug_target_name': self.bug_task.bugtargetname,
                 'label': self.display_notification_label,
@@ -862,8 +861,7 @@ class BugTaskAssigneeChange(AttributeChange):
 
     def __init__(self, bug_task, when, person,
                  what_changed, old_value, new_value):
-        super(BugTaskAssigneeChange, self).__init__(
-            when, person, what_changed, old_value, new_value)
+        super().__init__(when, person, what_changed, old_value, new_value)
         self.bug_task = bug_task
 
     def getBugActivity(self):
@@ -892,8 +890,8 @@ class BugTaskAssigneeChange(AttributeChange):
 
         return {
             'text': (
-                u"** Changed in: %s\n"
-                u"     Assignee: %s => %s" % (
+                "** Changed in: %s\n"
+                "     Assignee: %s => %s" % (
                     self.bug_task.bugtargetname,
                     assignee_for_display(self.old_value),
                     assignee_for_display(self.new_value))),
@@ -907,8 +905,7 @@ class BugTaskTargetChange(AttributeChange):
 
     def __init__(self, bug_task, when, person,
                  what_changed, old_value, new_value):
-        super(BugTaskTargetChange, self).__init__(
-            when, person, what_changed, old_value, new_value)
+        super().__init__(when, person, what_changed, old_value, new_value)
         self.bug_task = bug_task
 
     def getBugActivity(self):
@@ -922,9 +919,9 @@ class BugTaskTargetChange(AttributeChange):
     def getBugNotification(self):
         """See `IBugChange`."""
         if IProduct.providedBy(self.old_value):
-            template = u"** Project changed: %s => %s"
+            template = "** Project changed: %s => %s"
         else:
-            template = u"** Package changed: %s => %s"
+            template = "** Package changed: %s => %s"
         text = template % (
             self.old_value.bugtargetname,
             self.new_value.bugtargetname)
diff --git a/lib/lp/bugs/adapters/tests/test_bugchange.py b/lib/lp/bugs/adapters/tests/test_bugchange.py
index 1e473fd..e2af8df 100644
--- a/lib/lp/bugs/adapters/tests/test_bugchange.py
+++ b/lib/lp/bugs/adapters/tests/test_bugchange.py
@@ -23,7 +23,7 @@ class BugChangeTestCase(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(BugChangeTestCase, self).setUp()
+        super().setUp()
 
     def test_get_bug_change_class(self):
         # get_bug_change_class() should return whatever is contained
@@ -44,7 +44,7 @@ class BugChangeLevelTestCase(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(BugChangeLevelTestCase, self).setUp()
+        super().setUp()
         self.bug = self.factory.makeBug()
         self.bugtask = self.bug.default_bugtask
         self.user = self.factory.makePerson()
diff --git a/lib/lp/bugs/adapters/treelookup.py b/lib/lp/bugs/adapters/treelookup.py
index 218c07b..eebb7e2 100644
--- a/lib/lp/bugs/adapters/treelookup.py
+++ b/lib/lp/bugs/adapters/treelookup.py
@@ -51,7 +51,7 @@ class LookupBranch:
 
         As an extra step, the branch is verified by calling `_verify`.
         """
-        super(LookupBranch, self).__init__()
+        super().__init__()
         self.keys = args[:-1]
         self.result = args[-1]
         self._verify()
diff --git a/lib/lp/bugs/feed/bug.py b/lib/lp/bugs/feed/bug.py
index 207aec4..1388d6b 100644
--- a/lib/lp/bugs/feed/bug.py
+++ b/lib/lp/bugs/feed/bug.py
@@ -47,7 +47,7 @@ class BugFeedContentView(LaunchpadView):
     """View for a bug feed contents."""
 
     def __init__(self, context, request, feed):
-        super(BugFeedContentView, self).__init__(context, request)
+        super().__init__(context, request)
         self.feed = feed
 
     def render(self):
@@ -65,7 +65,7 @@ class BugsFeedBase(FeedBase):
 
     def initialize(self):
         """See `LaunchpadView`."""
-        super(BugsFeedBase, self).initialize()
+        super().initialize()
         self.setupColumns()
 
     def setupColumns(self):
@@ -168,7 +168,7 @@ class BugFeed(BugsFeedBase):
     def initialize(self):
         """See `IFeed`."""
         # For a `BugFeed` we must ensure that the bug is not private.
-        super(BugFeed, self).initialize()
+        super().initialize()
         if self.context.private:
             if check_permission("launchpad.View", self.context):
                 message_prefix = "This bug is private."
@@ -215,7 +215,7 @@ class BugTargetBugsFeed(BugsFeedBase):
         Since this feed is for a specific IHasBugs it is redundant to
         include the name in the output.
         """
-        super(BugTargetBugsFeed, self).setupColumns()
+        super().setupColumns()
         if 'bugtargetdisplayname' in self.show_column:
             del self.show_column['bugtargetdisplayname']
 
diff --git a/lib/lp/bugs/mail/bugnotificationbuilder.py b/lib/lp/bugs/mail/bugnotificationbuilder.py
index 7b381a1..251fe46 100644
--- a/lib/lp/bugs/mail/bugnotificationbuilder.py
+++ b/lib/lp/bugs/mail/bugnotificationbuilder.py
@@ -57,7 +57,7 @@ def get_bugmail_replyto_address(bug):
 
         From: Foo Bar via Malone <123@bugs...>
     """
-    return u"Bug %d <%s@%s>" % (bug.id, bug.id, config.launchpad.bugs_domain)
+    return "Bug %d <%s@%s>" % (bug.id, bug.id, config.launchpad.bugs_domain)
 
 
 def get_bugmail_error_address():
diff --git a/lib/lp/bugs/mail/bugnotificationrecipients.py b/lib/lp/bugs/mail/bugnotificationrecipients.py
index 40b88bd..be06190 100644
--- a/lib/lp/bugs/mail/bugnotificationrecipients.py
+++ b/lib/lp/bugs/mail/bugnotificationrecipients.py
@@ -55,7 +55,7 @@ class BugNotificationRecipients(NotificationRecipientSet):
         duplicateof parameter above and the addDupeSubscriber method.
         Don't confuse them!
         """
-        super(BugNotificationRecipients, self).__init__()
+        super().__init__()
         self.duplicateof = duplicateof
         self.subscription_filters = set()
 
@@ -119,7 +119,7 @@ class BugNotificationRecipients(NotificationRecipientSet):
 
     def update(self, recipient_set):
         """See `INotificationRecipientSet`."""
-        super(BugNotificationRecipients, self).update(recipient_set)
+        super().update(recipient_set)
         self.subscription_filters.update(
             recipient_set.subscription_filters)
 
diff --git a/lib/lp/bugs/mail/commands.py b/lib/lp/bugs/mail/commands.py
index d4b2868..c4bb5eb 100644
--- a/lib/lp/bugs/mail/commands.py
+++ b/lib/lp/bugs/mail/commands.py
@@ -588,8 +588,7 @@ class AffectsEmailCommand(EmailCommand):
         try:
             bug_target = self.getBugTarget(path)
         except BugTargetNotFound as error:
-            raise EmailProcessingError(
-                six.text_type(error), stop_processing=True)
+            raise EmailProcessingError(str(error), stop_processing=True)
         event = None
 
         if isinstance(bug, CreateBugParams):
@@ -777,8 +776,7 @@ class InformationTypeEmailCommand(DBSchemaEditEmailCommand):
     RANK = 3
 
     def convertArguments(self, context):
-        args = super(InformationTypeEmailCommand, self).convertArguments(
-            context)
+        args = super().convertArguments(context)
         return {'information_type': args['informationtype']}
 
     def setAttributeValue(self, context, attr_name, attr_value):
diff --git a/lib/lp/bugs/mail/handler.py b/lib/lp/bugs/mail/handler.py
index fadb5bc..69ba504 100644
--- a/lib/lp/bugs/mail/handler.py
+++ b/lib/lp/bugs/mail/handler.py
@@ -84,17 +84,17 @@ class BugTaskCommandGroup:
 class BugCommandGroup(BugTaskCommandGroup):
 
     def __init__(self, command=None):
-        super(BugCommandGroup, self).__init__(command=command)
+        super().__init__(command=command)
         self._groups = []
 
     def __bool__(self):
         if len(self._groups) > 0:
             return True
         else:
-            return super(BugCommandGroup, self).__bool__()
+            return super().__bool__()
 
     def __str__(self):
-        text_commands = [super(BugCommandGroup, self).__str__()]
+        text_commands = [super().__str__()]
         for group in self.groups:
             text_commands += [str(group)]
         return '\n'.join(text_commands).strip()
@@ -126,13 +126,13 @@ class BugCommandGroup(BugTaskCommandGroup):
             if command_or_group:
                 self._groups.append(command_or_group)
         else:
-            super(BugCommandGroup, self).add(command_or_group)
+            super().add(command_or_group)
 
 
 class BugCommandGroups(BugCommandGroup):
 
     def __init__(self, commands):
-        super(BugCommandGroups, self).__init__(command=None)
+        super().__init__(command=None)
         self._groups = []
         this_bug = BugCommandGroup()
         this_bugtask = BugTaskCommandGroup()
@@ -157,11 +157,9 @@ class BugCommandGroups(BugCommandGroup):
 
     def __iter__(self):
         for bug_group in self.groups:
-            for command in bug_group.commands:
-                yield command
+            yield from bug_group.commands
             for bugtask_group in bug_group.groups:
-                for command in bugtask_group.commands:
-                    yield command
+                yield from bugtask_group.commands
 
     def add(self, command_or_group):
         """Add a `BugCommandGroup` to the groups of commands.
diff --git a/lib/lp/bugs/mail/newbug.py b/lib/lp/bugs/mail/newbug.py
index 9c48c9e..8bd72f9 100644
--- a/lib/lp/bugs/mail/newbug.py
+++ b/lib/lp/bugs/mail/newbug.py
@@ -20,15 +20,15 @@ def generate_bug_add_email(bug, new_recipients=False, reason=None,
     that the new recipients have been subscribed to the bug. Otherwise
     it's just a notification of a new bug report.
     """
-    subject = u"[Bug %d] [NEW] %s" % (bug.id, bug.title)
+    subject = "[Bug %d] [NEW] %s" % (bug.id, bug.title)
     contents = ''
 
     if bug.private:
         # This is a confidential bug.
-        visibility = u"Private"
+        visibility = "Private"
     else:
         # This is a public bug.
-        visibility = u"Public"
+        visibility = "Public"
 
     if bug.security_related:
         visibility += ' security'
@@ -37,15 +37,15 @@ def generate_bug_add_email(bug, new_recipients=False, reason=None,
     bug_info = []
     # Add information about the affected upstreams and packages.
     for bugtask in bug.bugtasks:
-        bug_info.append(u"** Affects: %s" % bugtask.bugtargetname)
-        bug_info.append(u"     Importance: %s" % bugtask.importance.title)
+        bug_info.append("** Affects: %s" % bugtask.bugtargetname)
+        bug_info.append("     Importance: %s" % bugtask.importance.title)
 
         if bugtask.assignee:
             # There's a person assigned to fix this task, so show that
             # information too.
             bug_info.append(
-                u"     Assignee: %s" % bugtask.assignee.unique_displayname)
-        bug_info.append(u"         Status: %s\n" % bugtask.status.title)
+                "     Assignee: %s" % bugtask.assignee.unique_displayname)
+        bug_info.append("         Status: %s\n" % bugtask.status.title)
 
     if bug.tags:
         bug_info.append('\n** Tags: %s' % ' '.join(bug.tags))
diff --git a/lib/lp/bugs/mail/tests/test_bug_duplicate_notifications.py b/lib/lp/bugs/mail/tests/test_bug_duplicate_notifications.py
index 431ad45..7794a93 100644
--- a/lib/lp/bugs/mail/tests/test_bug_duplicate_notifications.py
+++ b/lib/lp/bugs/mail/tests/test_bug_duplicate_notifications.py
@@ -23,8 +23,7 @@ class TestAssignmentNotification(TestCaseWithFactory):
 
     def setUp(self):
         # Run the tests as a logged-in user.
-        super(TestAssignmentNotification, self).setUp(
-            user='test@xxxxxxxxxxxxx')
+        super().setUp(user='test@xxxxxxxxxxxxx')
         self.user = getUtility(ILaunchBag).user
         self.product = self.factory.makeProduct(owner=self.user,
                                                 name='project')
diff --git a/lib/lp/bugs/mail/tests/test_bug_subscribe.py b/lib/lp/bugs/mail/tests/test_bug_subscribe.py
index 09dfb94..286fc4d 100644
--- a/lib/lp/bugs/mail/tests/test_bug_subscribe.py
+++ b/lib/lp/bugs/mail/tests/test_bug_subscribe.py
@@ -17,8 +17,7 @@ class TestSubscribedBySomeoneElseNotification(TestCaseWithFactory):
 
     def setUp(self):
         # Run the tests as a logged-in user.
-        super(TestSubscribedBySomeoneElseNotification, self).setUp(
-            user='test@xxxxxxxxxxxxx')
+        super().setUp(user='test@xxxxxxxxxxxxx')
 
     def test_suppress_notify_false_does_notify(self):
         """Test notifications are sent when suppress_notify is False."""
diff --git a/lib/lp/bugs/mail/tests/test_bug_task_assignment.py b/lib/lp/bugs/mail/tests/test_bug_task_assignment.py
index cec7c15..4a0ac50 100644
--- a/lib/lp/bugs/mail/tests/test_bug_task_assignment.py
+++ b/lib/lp/bugs/mail/tests/test_bug_task_assignment.py
@@ -23,8 +23,7 @@ class TestAssignmentNotification(TestCaseWithFactory):
 
     def setUp(self):
         # Run the tests as a logged-in user.
-        super(TestAssignmentNotification, self).setUp(
-            user='test@xxxxxxxxxxxxx')
+        super().setUp(user='test@xxxxxxxxxxxxx')
         self.user = getUtility(ILaunchBag).user
         self.product = self.factory.makeProduct(owner=self.user,
                                                 name='rebirth')
diff --git a/lib/lp/bugs/mail/tests/test_bug_task_deletion.py b/lib/lp/bugs/mail/tests/test_bug_task_deletion.py
index 0cbb63f..ae46cb7 100644
--- a/lib/lp/bugs/mail/tests/test_bug_task_deletion.py
+++ b/lib/lp/bugs/mail/tests/test_bug_task_deletion.py
@@ -21,8 +21,7 @@ class TestDeletionNotification(TestCaseWithFactory):
 
     def setUp(self):
         # Run the tests as a logged-in user.
-        super(TestDeletionNotification, self).setUp(
-            user='test@xxxxxxxxxxxxx')
+        super().setUp(user='test@xxxxxxxxxxxxx')
         self.user = getUtility(ILaunchBag).user
         product = self.factory.makeProduct(owner=self.user)
         self.bug_task = self.factory.makeBugTask(target=product)
diff --git a/lib/lp/bugs/mail/tests/test_bug_task_modification.py b/lib/lp/bugs/mail/tests/test_bug_task_modification.py
index c181a1b..93bf2d9 100644
--- a/lib/lp/bugs/mail/tests/test_bug_task_modification.py
+++ b/lib/lp/bugs/mail/tests/test_bug_task_modification.py
@@ -23,8 +23,7 @@ class TestModificationNotification(TestCaseWithFactory):
 
     def setUp(self):
         # Run the tests as a logged-in user.
-        super(TestModificationNotification, self).setUp(
-            user='test@xxxxxxxxxxxxx')
+        super().setUp(user='test@xxxxxxxxxxxxx')
         self.user = getUtility(ILaunchBag).user
         self.product = self.factory.makeProduct(owner=self.user)
         self.bug = self.factory.makeBug(target=self.product)
diff --git a/lib/lp/bugs/mail/tests/test_bugnotificationbuilder.py b/lib/lp/bugs/mail/tests/test_bugnotificationbuilder.py
index c3063f4..5ffbdaa 100644
--- a/lib/lp/bugs/mail/tests/test_bugnotificationbuilder.py
+++ b/lib/lp/bugs/mail/tests/test_bugnotificationbuilder.py
@@ -24,8 +24,7 @@ class TestBugNotificationBuilder(TestCaseWithFactory):
 
     def setUp(self):
         # Run the tests as a logged-in user.
-        super(TestBugNotificationBuilder, self).setUp(
-            user='test@xxxxxxxxxxxxx')
+        super().setUp(user='test@xxxxxxxxxxxxx')
         self.bug = self.factory.makeBug()
         self.builder = BugNotificationBuilder(self.bug)
 
@@ -41,9 +40,9 @@ class TestBugNotificationBuilder(TestCaseWithFactory):
         """Filters are added."""
         utc_now = datetime.now(pytz.UTC)
         message = self.builder.build('from', self.bug.owner, 'body', 'subject',
-                                     utc_now, filters=[u"Testing filter"])
+                                     utc_now, filters=["Testing filter"])
         self.assertContentEqual(
-            [u"Testing filter"],
+            ["Testing filter"],
             message.get_all("X-Launchpad-Subscription"))
 
     def test_build_filters_multiple(self):
@@ -51,9 +50,9 @@ class TestBugNotificationBuilder(TestCaseWithFactory):
         utc_now = datetime.now(pytz.UTC)
         message = self.builder.build(
             'from', self.bug.owner, 'body', 'subject', utc_now,
-            filters=[u"Testing filter", u"Second testing filter"])
+            filters=["Testing filter", "Second testing filter"])
         self.assertContentEqual(
-            [u"Testing filter", u"Second testing filter"],
+            ["Testing filter", "Second testing filter"],
             message.get_all("X-Launchpad-Subscription"))
 
     def test_mails_contain_notification_type_header(self):
diff --git a/lib/lp/bugs/mail/tests/test_handler.py b/lib/lp/bugs/mail/tests/test_handler.py
index ff4da2b..20dadf6 100644
--- a/lib/lp/bugs/mail/tests/test_handler.py
+++ b/lib/lp/bugs/mail/tests/test_handler.py
@@ -61,12 +61,12 @@ class TestMaloneHandler(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestMaloneHandler, self).setUp()
+        super().setUp()
         self._old_policy = getSecurityPolicy()
         setSecurityPolicy(LaunchpadSecurityPolicy)
 
     def tearDown(self):
-        super(TestMaloneHandler, self).tearDown()
+        super().tearDown()
         setSecurityPolicy(self._old_policy)
 
     def test_getCommandsEmpty(self):
diff --git a/lib/lp/bugs/scripts/bugexport.py b/lib/lp/bugs/scripts/bugexport.py
index b607f40..3a697b5 100644
--- a/lib/lp/bugs/scripts/bugexport.py
+++ b/lib/lp/bugs/scripts/bugexport.py
@@ -8,12 +8,7 @@ __all__ = [
     ]
 
 import base64
-
-
-try:
-    import xml.etree.cElementTree as ET
-except ImportError:
-    import cElementTree as ET
+import xml.etree.ElementTree as ET
 
 from zope.component import getUtility
 
diff --git a/lib/lp/bugs/scripts/bugimport.py b/lib/lp/bugs/scripts/bugimport.py
index facc2ba..c403883 100644
--- a/lib/lp/bugs/scripts/bugimport.py
+++ b/lib/lp/bugs/scripts/bugimport.py
@@ -86,7 +86,7 @@ def get_text(node):
         raise BugXMLSyntaxError('No child nodes are expected for <%s>'
                                 % node.tag)
     if node.text is None:
-        return u''
+        return ''
     return six.ensure_text(node.text.strip())
 
 
diff --git a/lib/lp/bugs/scripts/bugnotification.py b/lib/lp/bugs/scripts/bugnotification.py
index f5b6183..faffa9f 100644
--- a/lib/lp/bugs/scripts/bugnotification.py
+++ b/lib/lp/bugs/scripts/bugnotification.py
@@ -200,10 +200,10 @@ def construct_email_notifications(bug_notifications):
         if data['filter descriptions']:
             # There are some filter descriptions as well. Add them to
             # the email body.
-            filters_text = u"\nMatching subscriptions: %s" % ", ".join(
+            filters_text = "\nMatching subscriptions: %s" % ", ".join(
                 data['filter descriptions'])
         else:
-            filters_text = u""
+            filters_text = ""
 
         # In the rare case of a bug with no bugtasks, we can't generate the
         # subscription management URL so just leave off the subscription
diff --git a/lib/lp/bugs/scripts/bugsummaryrebuild.py b/lib/lp/bugs/scripts/bugsummaryrebuild.py
index 58daf6b..98a1fc6 100644
--- a/lib/lp/bugs/scripts/bugsummaryrebuild.py
+++ b/lib/lp/bugs/scripts/bugsummaryrebuild.py
@@ -1,7 +1,6 @@
 # Copyright 2012-2021 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-import six
 from storm.expr import (
     Alias,
     And,
@@ -120,7 +119,7 @@ def get_bugsummary_constraint(target, cls=RawBugSummary):
     # Map to ID columns to work around Storm bug #682989.
     return [
         getattr(cls, k) == v
-        for (k, v) in six.iteritems(_get_bugsummary_constraint_bits(target))]
+        for (k, v) in _get_bugsummary_constraint_bits(target).items()]
 
 
 def get_bugtaskflat_constraint(target):
@@ -169,8 +168,8 @@ def calculate_bugsummary_changes(old, new):
     from the old one.
     """
     keys = set()
-    keys.update(six.iterkeys(old))
-    keys.update(six.iterkeys(new))
+    keys.update(old.keys())
+    keys.update(new.keys())
     added = {}
     updated = {}
     removed = []
@@ -206,7 +205,7 @@ def apply_bugsummary_changes(target, added, updated, removed):
         RawBugSummary.access_policy_id)
 
     # Postgres doesn't do bulk updates, so do a delete+add.
-    for key, count in six.iteritems(updated):
+    for key, count in updated.items():
         removed.append(key)
         added[key] = count
 
@@ -228,7 +227,7 @@ def apply_bugsummary_changes(target, added, updated, removed):
         create(
             target_cols + key_cols + (RawBugSummary.count,),
             [target_key + key + (count,)
-             for key, count in six.iteritems(added)])
+             for key, count in added.items()])
 
 
 def rebuild_bugsummary_for_target(target, log):
@@ -349,7 +348,7 @@ class BugSummaryRebuildTunableLoop(TunableLoop):
     maximum_chunk_size = 100
 
     def __init__(self, log, dry_run, abort_time=None):
-        super(BugSummaryRebuildTunableLoop, self).__init__(log, abort_time)
+        super().__init__(log, abort_time)
         self.dry_run = dry_run
         self.targets = list(
             get_bugsummary_targets().union(get_bugtask_targets()))
diff --git a/lib/lp/bugs/scripts/bugtasktargetnamecaches.py b/lib/lp/bugs/scripts/bugtasktargetnamecaches.py
index 1b32b29..d6cc18d 100644
--- a/lib/lp/bugs/scripts/bugtasktargetnamecaches.py
+++ b/lib/lp/bugs/scripts/bugtasktargetnamecaches.py
@@ -7,7 +7,6 @@ __all__ = ['BugTaskTargetNameCacheUpdater']
 
 from collections import defaultdict
 
-import six
 from zope.interface import implementer
 
 from lp.bugs.model.bugtask import (
@@ -42,7 +41,7 @@ target_classes = (
 
 
 @implementer(ITunableLoop)
-class BugTaskTargetNameCachesTunableLoop(object):
+class BugTaskTargetNameCachesTunableLoop:
     """An `ITunableLoop` for updating BugTask targetname caches."""
 
     def __init__(self, transaction, logger, offset=0):
@@ -68,7 +67,7 @@ class BugTaskTargetNameCachesTunableLoop(object):
         candidates = defaultdict(set)
         for candidate in candidate_set:
             candidates[candidate[:-1]].add(candidate[-1])
-        return list(six.iteritems(candidates))
+        return list(candidates.items())
 
     def isDone(self):
         """See `ITunableLoop`."""
diff --git a/lib/lp/bugs/scripts/bzremotecomponentfinder.py b/lib/lp/bugs/scripts/bzremotecomponentfinder.py
index 1c4f3da..571be8d 100644
--- a/lib/lp/bugs/scripts/bzremotecomponentfinder.py
+++ b/lib/lp/bugs/scripts/bzremotecomponentfinder.py
@@ -11,7 +11,6 @@ __all__ = [
 import re
 
 import requests
-import six
 import transaction
 from zope.component import getUtility
 
@@ -106,8 +105,8 @@ class BugzillaRemoteComponentFinder:
 
     # Names of bug trackers we should not pull data from
     _BLACKLIST = [
-        u"ubuntu-bugzilla",
-        u"mozilla.org",
+        "ubuntu-bugzilla",
+        "mozilla.org",
         ]
 
     def __init__(self, logger=None):
@@ -164,7 +163,7 @@ class BugzillaRemoteComponentFinder:
     def storeRemoteProductsAndComponents(self, bz_bugtracker, lp_bugtracker):
         """Stores parsed product/component data from bz_bugtracker"""
         components_to_add = []
-        for product in six.itervalues(bz_bugtracker.products):
+        for product in bz_bugtracker.products.values():
             # Look up the component group id from Launchpad for the product
             # if it already exists.  Otherwise, add it.
             lp_component_group = lp_bugtracker.getRemoteComponentGroup(
diff --git a/lib/lp/bugs/scripts/checkwatches/core.py b/lib/lp/bugs/scripts/checkwatches/core.py
index db59005..069fb19 100644
--- a/lib/lp/bugs/scripts/checkwatches/core.py
+++ b/lib/lp/bugs/scripts/checkwatches/core.py
@@ -30,7 +30,6 @@ import time
 from xmlrpc.client import ProtocolError
 
 import pytz
-import six
 from twisted.internet import reactor
 from twisted.internet.defer import DeferredList
 from twisted.internet.threads import deferToThreadPool
@@ -257,7 +256,7 @@ class CheckwatchesMaster(WorkingBase):
         """
         with self.transaction:
             # Get the bug tracker.
-            if isinstance(bug_tracker, six.integer_types):
+            if isinstance(bug_tracker, int):
                 bug_tracker = getUtility(IBugTrackerSet).get(bug_tracker)
             # Save the name and url for later, since we might need it
             # to report an error after a transaction has been aborted.
diff --git a/lib/lp/bugs/scripts/checkwatches/scheduler.py b/lib/lp/bugs/scripts/checkwatches/scheduler.py
index d71a906..1147096 100644
--- a/lib/lp/bugs/scripts/checkwatches/scheduler.py
+++ b/lib/lp/bugs/scripts/checkwatches/scheduler.py
@@ -34,7 +34,7 @@ class BugWatchScheduler(TunableLoop):
 
     def __init__(self, log, abort_time=None, max_delay_days=None,
                  max_sample_size=None):
-        super(BugWatchScheduler, self).__init__(log, abort_time)
+        super().__init__(log, abort_time)
         self.transaction = transaction
         self.store = IMasterStore(BugWatch)
 
diff --git a/lib/lp/bugs/scripts/checkwatches/tests/test_base.py b/lib/lp/bugs/scripts/checkwatches/tests/test_base.py
index be29938..559e8a6 100644
--- a/lib/lp/bugs/scripts/checkwatches/tests/test_base.py
+++ b/lib/lp/bugs/scripts/checkwatches/tests/test_base.py
@@ -38,7 +38,7 @@ class TestWorkingBase(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestWorkingBase, self).setUp()
+        super().setUp()
         self.person = self.factory.makePerson()
         self.email = self.person.preferredemail.email
         self.logger = BufferLogger()
diff --git a/lib/lp/bugs/scripts/checkwatches/tests/test_bugwatchupdater.py b/lib/lp/bugs/scripts/checkwatches/tests/test_bugwatchupdater.py
index 541a9a1..46c21c2 100644
--- a/lib/lp/bugs/scripts/checkwatches/tests/test_bugwatchupdater.py
+++ b/lib/lp/bugs/scripts/checkwatches/tests/test_bugwatchupdater.py
@@ -100,7 +100,7 @@ class BugWatchUpdaterTestCase(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(BugWatchUpdaterTestCase, self).setUp()
+        super().setUp()
         self.checkwatches_master = CheckwatchesMaster(transaction)
         self.bug_task = self.factory.makeBugTask()
         self.bug_watch = self.factory.makeBugWatch(bug_task=self.bug_task)
diff --git a/lib/lp/bugs/scripts/checkwatches/tests/test_core.py b/lib/lp/bugs/scripts/checkwatches/tests/test_core.py
index f127aff..509b488 100644
--- a/lib/lp/bugs/scripts/checkwatches/tests/test_core.py
+++ b/lib/lp/bugs/scripts/checkwatches/tests/test_core.py
@@ -92,7 +92,7 @@ class TestCheckwatchesWithSyncableGnomeProducts(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestCheckwatchesWithSyncableGnomeProducts, self).setUp()
+        super().setUp()
         transaction.commit()
 
         # We monkey-patch externalbugtracker.get_external_bugtracker()
@@ -110,7 +110,7 @@ class TestCheckwatchesWithSyncableGnomeProducts(TestCaseWithFactory):
     def tearDown(self):
         checkwatches.externalbugtracker.get_external_bugtracker = (
             self.original_get_external_bug_tracker)
-        super(TestCheckwatchesWithSyncableGnomeProducts, self).tearDown()
+        super().tearDown()
 
     def test_bug_496988(self):
         # Regression test for bug 496988. KeyErrors when looking for the
@@ -176,7 +176,7 @@ class TestCheckwatchesMaster(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestCheckwatchesMaster, self).setUp()
+        super().setUp()
         transaction.abort()
 
     def test_bug_497141(self):
@@ -279,7 +279,7 @@ class TestUpdateBugsWithLinkedQuestions(unittest.TestCase):
 
     def setUp(self):
         """Set up bugs, watches and questions to test with."""
-        super(TestUpdateBugsWithLinkedQuestions, self).setUp()
+        super().setUp()
 
         # For test_can_update_bug_with_questions we need a bug that has
         # a question linked to it.
@@ -398,7 +398,7 @@ class TestTwistedThreadScheduler(TestSchedulerBase, TestCase):
     run_tests_with = RunIsolatedTest
 
     def setUp(self):
-        super(TestTwistedThreadScheduler, self).setUp()
+        super().setUp()
         self.scheduler = checkwatches.TwistedThreadScheduler(
             num_threads=5, install_signal_handlers=False)
 
@@ -423,7 +423,7 @@ class ExternalBugTrackerForThreads(TestExternalBugTracker):
     """Fake which records interesting activity to a file."""
 
     def __init__(self, output_file):
-        super(ExternalBugTrackerForThreads, self).__init__()
+        super().__init__()
         self.output_file = output_file
 
     def getRemoteStatus(self, bug_id):
@@ -444,8 +444,7 @@ class CheckwatchesMasterForThreads(CheckwatchesMaster):
 
     def __init__(self, output_file):
         logger = BufferLogger()
-        super(CheckwatchesMasterForThreads, self).__init__(
-            transaction.manager, logger)
+        super().__init__(transaction.manager, logger)
         self.output_file = output_file
 
     def _getExternalBugTrackersAndWatches(self, bug_trackers, bug_watches):
diff --git a/lib/lp/bugs/scripts/checkwatches/tests/test_scheduler.py b/lib/lp/bugs/scripts/checkwatches/tests/test_scheduler.py
index 7cf69c3..a0dc48e 100644
--- a/lib/lp/bugs/scripts/checkwatches/tests/test_scheduler.py
+++ b/lib/lp/bugs/scripts/checkwatches/tests/test_scheduler.py
@@ -29,7 +29,7 @@ class TestBugWatchScheduler(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugWatchScheduler, self).setUp('foo.bar@xxxxxxxxxxxxx')
+        super().setUp('foo.bar@xxxxxxxxxxxxx')
         # We'll make sure that all the other bug watches look like
         # they've been scheduled so that only our watch gets scheduled.
         for watch in getUtility(IBugWatchSet).search():
diff --git a/lib/lp/bugs/scripts/cveimport.py b/lib/lp/bugs/scripts/cveimport.py
index f9f75ba..0270fc5 100644
--- a/lib/lp/bugs/scripts/cveimport.py
+++ b/lib/lp/bugs/scripts/cveimport.py
@@ -147,7 +147,7 @@ def update_one_cve(cve_node, log):
 
 
 @implementer(ITunableLoop)
-class CveUpdaterTunableLoop(object):
+class CveUpdaterTunableLoop:
     """An `ITunableLoop` for updating CVEs."""
 
     total_updated = 0
@@ -207,7 +207,7 @@ class CVEUpdater(LaunchpadCronScript):
             try:
                 with open(self.options.cvefile) as f:
                     cve_db = f.read()
-            except IOError:
+            except OSError:
                 raise LaunchpadScriptFailure(
                     'Unable to open CVE database in %s'
                     % self.options.cvefile)
diff --git a/lib/lp/bugs/scripts/debbugs.py b/lib/lp/bugs/scripts/debbugs.py
index d693df1..260b319 100644
--- a/lib/lp/bugs/scripts/debbugs.py
+++ b/lib/lp/bugs/scripts/debbugs.py
@@ -9,8 +9,6 @@ import re
 import subprocess
 import sys
 
-import six
-
 
 class Bug:
     def __init__(self, db, id, package=None, date=None, status=None,
@@ -100,7 +98,7 @@ class Database:
         self.debbugs_pl = debbugs_pl
         self.subdir = subdir
 
-    class bug_iterator(six.Iterator):
+    class bug_iterator:
         index_record = re.compile(
             r'^(?P<package>\S+) (?P<bugid>\d+) (?P<date>\d+) (?P<status>\w+) '
             r'\[(?P<originator>.*)\] (?P<severity>\w+)(?: (?P<tags>.*))?$')
@@ -154,7 +152,7 @@ class Database:
 
         try:
             fd = open(summary)
-        except IOError as e:
+        except OSError as e:
             if e.errno == 2:
                 raise SummaryMissing(summary)
             raise
@@ -197,7 +195,7 @@ class Database:
 
         try:
             fd = open(report, 'rb')
-        except IOError as e:
+        except OSError as e:
             if e.errno == 2:
                 raise ReportMissing(report)
             raise
@@ -247,7 +245,7 @@ class Database:
             if process.returncode != 0:
                 raise LogParseFailed(errors)
 
-        except IOError as e:
+        except OSError as e:
             if e.errno == 2:
                 raise LogMissing(log)
             raise
diff --git a/lib/lp/bugs/scripts/sfremoteproductfinder.py b/lib/lp/bugs/scripts/sfremoteproductfinder.py
index c4748ab..104a5d9 100644
--- a/lib/lp/bugs/scripts/sfremoteproductfinder.py
+++ b/lib/lp/bugs/scripts/sfremoteproductfinder.py
@@ -111,7 +111,7 @@ class SourceForgeRemoteProductFinder:
             # None.
             return None
 
-        return u'%s&%s' % (group_id, atid)
+        return '%s&%s' % (group_id, atid)
 
     def setRemoteProductsFromSourceForge(self):
         """Find and set the remote product for SF-linked Products."""
diff --git a/lib/lp/bugs/scripts/tests/test_bugimport.py b/lib/lp/bugs/scripts/tests/test_bugimport.py
index a0088a6..f4f5f7e 100644
--- a/lib/lp/bugs/scripts/tests/test_bugimport.py
+++ b/lib/lp/bugs/scripts/tests/test_bugimport.py
@@ -444,11 +444,11 @@ class ImportBugTestCase(TestCase):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(ImportBugTestCase, self).setUp()
+        super().setUp()
         login('bug-importer@xxxxxxxxxxxxx')
 
     def tearDown(self):
-        super(ImportBugTestCase, self).tearDown()
+        super().tearDown()
         logout()
 
     def assertNoPendingNotifications(self, bug):
@@ -649,7 +649,7 @@ class BugImportCacheTestCase(TestCase):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(BugImportCacheTestCase, self).setUp()
+        super().setUp()
         self.tmpdir = self.makeTemporaryDirectory()
 
     def test_load_no_cache(self):
@@ -733,7 +733,7 @@ class BugImportScriptTestCase(TestCase):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(BugImportScriptTestCase, self).setUp()
+        super().setUp()
         self.tmpdir = self.makeTemporaryDirectory()
         # We'll be running subprocesses that may change the database, so force
         # the test system to treat it as dirty.
@@ -942,7 +942,7 @@ class TestRemoteBugUpdater(RemoteBugUpdater):
     def __init__(self, parent, external_bugtracker, remote_bug,
                  bug_watch_ids, unmodified_remote_ids, server_time,
                  bugtracker):
-        super(TestRemoteBugUpdater, self). __init__(
+        super(). __init__(
             parent, external_bugtracker, remote_bug, bug_watch_ids,
             unmodified_remote_ids, server_time)
         self.bugtracker = bugtracker
@@ -970,7 +970,7 @@ class TestCheckwatchesMaster(CheckwatchesMaster):
         reload = core.reload
         try:
             core.reload = lambda objects: objects
-            super(TestCheckwatchesMaster, self)._updateBugTracker(bug_tracker)
+            super()._updateBugTracker(bug_tracker)
         finally:
             core.reload = reload
 
diff --git a/lib/lp/bugs/scripts/tests/test_bugnotification.py b/lib/lp/bugs/scripts/tests/test_bugnotification.py
index d5ec852..2ea216f 100644
--- a/lib/lp/bugs/scripts/tests/test_bugnotification.py
+++ b/lib/lp/bugs/scripts/tests/test_bugnotification.py
@@ -175,7 +175,7 @@ class FakeNotification:
     Used by TestGetActivityKey, TestNotificationCommentBatches and
     TestNotificationBatches."""
 
-    class Message(object):
+    class Message:
         pass
 
     def __init__(self, is_comment=False, bug=None, owner=None):
@@ -247,7 +247,7 @@ class TestGetEmailNotifications(TestCase):
 
     def setUp(self):
         """Set up some mock bug notifications to use."""
-        super(TestGetEmailNotifications, self).setUp()
+        super().setUp()
         switch_dbuser(config.malone.bugnotification_dbuser)
         sample_person = getUtility(IPersonSet).getByEmail(
             'test@xxxxxxxxxxxxx')
@@ -294,7 +294,7 @@ class TestGetEmailNotifications(TestCase):
         self.logger = self.useFixture(FakeLogger())
 
     def tearDown(self):
-        super(TestGetEmailNotifications, self).tearDown()
+        super().tearDown()
         sm = getSiteManager()
         sm.unregisterUtility(self._fake_utility)
         sm.registerUtility(self._original_utility)
@@ -641,7 +641,7 @@ class EmailNotificationTestBase(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(EmailNotificationTestBase, self).setUp()
+        super().setUp()
         login('foo.bar@xxxxxxxxxxxxx')
         self.product_owner = self.factory.makePerson(name="product-owner")
         self.person = self.factory.makePerson(name="sample-person")
@@ -672,7 +672,7 @@ class EmailNotificationTestBase(TestCaseWithFactory):
         for notification in self.notification_set.getNotificationsToSend():
             notification.date_emailed = self.now
         flush_database_updates()
-        super(EmailNotificationTestBase, self).tearDown()
+        super().tearDown()
 
     def get_messages(self):
         notifications = self.notification_set.getNotificationsToSend()
@@ -994,7 +994,7 @@ class TestEmailNotificationsWithFilters(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestEmailNotificationsWithFilters, self).setUp()
+        super().setUp()
         self.bug = self.factory.makeBug()
         subscriber = self.factory.makePerson()
         self.subscription = self.bug.default_bugtask.target.addSubscription(
@@ -1087,18 +1087,18 @@ class TestEmailNotificationsWithFilters(TestCaseWithFactory):
     def test_header_single(self):
         # A single filter with a description makes all emails
         # include that particular filter description in a header.
-        self.addFilter(u"Test filter")
+        self.addFilter("Test filter")
 
-        self.assertContentEqual([u"Test filter"],
+        self.assertContentEqual(["Test filter"],
                                 self.getSubscriptionEmailHeaders())
 
     def test_header_multiple(self):
         # Multiple filters with a description make all emails
         # include all filter descriptions in the header.
-        self.addFilter(u"First filter")
-        self.addFilter(u"Second filter")
+        self.addFilter("First filter")
+        self.addFilter("Second filter")
 
-        self.assertContentEqual([u"First filter", u"Second filter"],
+        self.assertContentEqual(["First filter", "Second filter"],
                                 self.getSubscriptionEmailHeaders())
 
     def test_header_other_subscriber_by_person(self):
@@ -1108,15 +1108,15 @@ class TestEmailNotificationsWithFilters(TestCaseWithFactory):
         other_person = self.factory.makePerson()
         other_subscription = self.bug.default_bugtask.target.addSubscription(
             other_person, other_person)
-        self.addFilter(u"Someone's filter", other_subscription)
+        self.addFilter("Someone's filter", other_subscription)
         self.addNotificationRecipient(self.notification, other_person)
 
-        self.addFilter(u"Test filter")
+        self.addFilter("Test filter")
 
         the_subscriber = self.subscription.subscriber
         self.assertEqual(
-            {other_person.preferredemail.email: [u"Someone's filter"],
-             the_subscriber.preferredemail.email: [u"Test filter"]},
+            {other_person.preferredemail.email: ["Someone's filter"],
+             the_subscriber.preferredemail.email: ["Test filter"]},
             self.getSubscriptionEmailHeaders(by_person=True))
 
     def test_body_empty(self):
@@ -1128,23 +1128,23 @@ class TestEmailNotificationsWithFilters(TestCaseWithFactory):
     def test_body_single(self):
         # A single filter with a description makes all emails
         # include that particular filter description in the body.
-        self.addFilter(u"Test filter")
+        self.addFilter("Test filter")
 
-        self.assertContentEqual([u"Matching subscriptions: Test filter"],
+        self.assertContentEqual(["Matching subscriptions: Test filter"],
                                 self.getSubscriptionEmailBody())
 
     def test_body_multiple(self):
         # Multiple filters with description make all emails
         # include them in the email body.
-        self.addFilter(u"First filter")
-        self.addFilter(u"Second filter")
+        self.addFilter("First filter")
+        self.addFilter("Second filter")
 
         self.assertContentEqual(
-            [u"Matching subscriptions: First filter, Second filter"],
+            ["Matching subscriptions: First filter, Second filter"],
             self.getSubscriptionEmailBody())
 
     def test_muted(self):
-        self.addFilter(u"Test filter")
+        self.addFilter("Test filter")
         BugSubscriptionFilterMute(
             person=self.subscription.subscriber,
             filter=self.notification.bug_filters.one())
@@ -1155,13 +1155,13 @@ class TestEmailNotificationsWithFilters(TestCaseWithFactory):
     def test_header_multiple_one_muted(self):
         # Multiple filters with a description make all emails
         # include all filter descriptions in the header.
-        self.addFilter(u"First filter")
-        self.addFilter(u"Second filter")
+        self.addFilter("First filter")
+        self.addFilter("Second filter")
         BugSubscriptionFilterMute(
             person=self.subscription.subscriber,
             filter=self.notification.bug_filters[0])
 
-        self.assertContentEqual([u"Second filter"],
+        self.assertContentEqual(["Second filter"],
                                 self.getSubscriptionEmailHeaders())
 
 
@@ -1179,7 +1179,7 @@ class TestEmailNotificationsWithFiltersWhenBugCreated(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestEmailNotificationsWithFiltersWhenBugCreated, self).setUp()
+        super().setUp()
         self.subscriber = self.factory.makePerson()
         self.submitter = self.factory.makePerson()
         self.product = self.factory.makeProduct(
@@ -1187,13 +1187,13 @@ class TestEmailNotificationsWithFiltersWhenBugCreated(TestCaseWithFactory):
         self.subscription = self.product.addSubscription(
             self.subscriber, self.subscriber)
         self.filter = self.subscription.bug_filters[0]
-        self.filter.description = u'Needs triage'
+        self.filter.description = 'Needs triage'
         self.filter.statuses = [BugTaskStatus.NEW, BugTaskStatus.INCOMPLETE]
 
     def test_filters_match_when_bug_is_created(self):
-        message = u"this is an unfiltered comment"
+        message = "this is an unfiltered comment"
         params = CreateBugParams(
-            title=u"crashes all the time",
+            title="crashes all the time",
             comment=message, owner=self.submitter,
             status=BugTaskStatus.NEW)
         bug = self.product.createBug(params)
@@ -1201,9 +1201,9 @@ class TestEmailNotificationsWithFiltersWhenBugCreated(TestCaseWithFactory):
         self.assertEqual(notification.message.text_contents, message)
 
     def test_filters_do_not_match_when_bug_is_created(self):
-        message = u"this is a filtered comment"
+        message = "this is a filtered comment"
         params = CreateBugParams(
-            title=u"crashes all the time",
+            title="crashes all the time",
             comment=message, owner=self.submitter,
             status=BugTaskStatus.TRIAGED,
             importance=BugTaskImportance.HIGH)
@@ -1277,7 +1277,7 @@ class TestDeferredNotifications(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestDeferredNotifications, self).setUp()
+        super().setUp()
         self.notification_set = getUtility(IBugNotificationSet)
         # Ensure there are no outstanding notifications.
         for notification in self.notification_set.getNotificationsToSend():
@@ -1319,7 +1319,7 @@ class BrokenMailer(TestMailer):
     def send(self, from_addr, to_addrs, message):
         if any(to_addr in self.broken for to_addr in to_addrs):
             raise SMTPException("test requested delivery failure")
-        return super(BrokenMailer, self).send(from_addr, to_addrs, message)
+        return super().send(from_addr, to_addrs, message)
 
 
 class TestSendBugNotifications(TestCaseWithFactory):
@@ -1327,7 +1327,7 @@ class TestSendBugNotifications(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestSendBugNotifications, self).setUp()
+        super().setUp()
         self.notification_set = getUtility(IBugNotificationSet)
         # Ensure there are no outstanding notifications.
         for notification in self.notification_set.getNotificationsToSend():
diff --git a/lib/lp/bugs/scripts/tests/test_bugsummaryrebuild.py b/lib/lp/bugs/scripts/tests/test_bugsummaryrebuild.py
index 864d1c4..b36999e 100644
--- a/lib/lp/bugs/scripts/tests/test_bugsummaryrebuild.py
+++ b/lib/lp/bugs/scripts/tests/test_bugsummaryrebuild.py
@@ -212,11 +212,11 @@ class TestCalculateBugSummaryRows(TestCaseWithFactory):
         # untagged row.
         product = self.factory.makeProduct()
         bug = self.factory.makeBug(
-            target=product, tags=[u'foo', u'bar']).default_bugtask
+            target=product, tags=['foo', 'bar']).default_bugtask
         self.assertContentEqual(
             [(bug.status, None, bug.importance, False, None, None, None, 1),
-             (bug.status, None, bug.importance, False, u'foo', None, None, 1),
-             (bug.status, None, bug.importance, False, u'bar', None, None, 1),
+             (bug.status, None, bug.importance, False, 'foo', None, None, 1),
+             (bug.status, None, bug.importance, False, 'bar', None, None, 1),
             ], calculate_bugsummary_rows(product))
 
     def test_private_untagged(self):
@@ -242,17 +242,17 @@ class TestCalculateBugSummaryRows(TestCaseWithFactory):
         product = self.factory.makeProduct()
         o = self.factory.makePerson()
         bug = self.factory.makeBug(
-            target=product, owner=o, tags=[u'foo', u'bar'],
+            target=product, owner=o, tags=['foo', 'bar'],
             information_type=InformationType.USERDATA).default_bugtask
         [ap] = getUtility(IAccessPolicySource).find(
             [(product, InformationType.USERDATA)])
         self.assertContentEqual(
             [(bug.status, None, bug.importance, False, None, o.id, None, 1),
-             (bug.status, None, bug.importance, False, u'foo', o.id, None, 1),
-             (bug.status, None, bug.importance, False, u'bar', o.id, None, 1),
+             (bug.status, None, bug.importance, False, 'foo', o.id, None, 1),
+             (bug.status, None, bug.importance, False, 'bar', o.id, None, 1),
              (bug.status, None, bug.importance, False, None, None, ap.id, 1),
-             (bug.status, None, bug.importance, False, u'foo', None, ap.id, 1),
-             (bug.status, None, bug.importance, False, u'bar', None, ap.id, 1),
+             (bug.status, None, bug.importance, False, 'foo', None, ap.id, 1),
+             (bug.status, None, bug.importance, False, 'bar', None, ap.id, 1),
             ],
             calculate_bugsummary_rows(product))
 
diff --git a/lib/lp/bugs/security.py b/lib/lp/bugs/security.py
index 142bd5d..ace8336 100644
--- a/lib/lp/bugs/security.py
+++ b/lib/lp/bugs/security.py
@@ -206,8 +206,7 @@ class ViewBugAttachment(DelegatedAuthorization):
     usedfor = IBugAttachment
 
     def __init__(self, bugattachment):
-        super(ViewBugAttachment, self).__init__(
-            bugattachment, bugattachment.bug)
+        super().__init__(bugattachment, bugattachment.bug)
 
 
 class EditBugAttachment(AuthorizationBase):
@@ -239,7 +238,7 @@ class ViewBugActivity(DelegatedAuthorization):
     usedfor = IBugActivity
 
     def __init__(self, bugactivity):
-        super(ViewBugActivity, self).__init__(bugactivity, bugactivity.bug)
+        super().__init__(bugactivity, bugactivity.bug)
 
 
 class ViewBugSubscription(AnonymousAuthorization):
diff --git a/lib/lp/bugs/subscribers/bugactivity.py b/lib/lp/bugs/subscribers/bugactivity.py
index 7468e1a..942d168 100644
--- a/lib/lp/bugs/subscribers/bugactivity.py
+++ b/lib/lp/bugs/subscribers/bugactivity.py
@@ -2,7 +2,6 @@
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 from lazr.enum import BaseItem
-import six
 from zope.component import getUtility
 from zope.proxy import isProxy
 from zope.schema.interfaces import IField
@@ -55,7 +54,7 @@ def get_string_representation(obj):
         return obj.name
     elif isinstance(obj, BaseItem):
         return obj.title
-    elif isinstance(obj, six.string_types):
+    elif isinstance(obj, str):
         return obj
     elif isinstance(obj, bool):
         return str(obj)
diff --git a/lib/lp/bugs/subscribers/tests/test_bug.py b/lib/lp/bugs/subscribers/tests/test_bug.py
index deb459d..1530544 100644
--- a/lib/lp/bugs/subscribers/tests/test_bug.py
+++ b/lib/lp/bugs/subscribers/tests/test_bug.py
@@ -30,7 +30,7 @@ class BugSubscriberTestCase(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(BugSubscriberTestCase, self).setUp()
+        super().setUp()
         self.bug = self.factory.makeBug()
         self.bugtask = self.bug.default_bugtask
         self.user = self.factory.makePerson()
diff --git a/lib/lp/bugs/tests/bug.py b/lib/lp/bugs/tests/bug.py
index 4ac066d..2dea2e4 100644
--- a/lib/lp/bugs/tests/bug.py
+++ b/lib/lp/bugs/tests/bug.py
@@ -87,7 +87,7 @@ def print_bug_affects_table(content, highlighted_only=False):
             # Don't print the bugtask edit form.
             continue
         # Strip zero-width white-spaces.
-        print(extract_text(tr).replace(u'\u200B', u''))
+        print(extract_text(tr).replace('\u200B', ''))
 
 
 def print_remote_bugtasks(content):
@@ -115,7 +115,7 @@ def print_bugs_list(content, list_id):
         None, {'class': 'similar-bug'})
     for node in bugs_list:
         # Also strip zero-width spaces out.
-        print(extract_text(node).replace(u'\u200B', u''))
+        print(extract_text(node).replace('\u200B', ''))
 
 
 def print_bugtasks(text, show_heat=None):
diff --git a/lib/lp/bugs/tests/externalbugtracker.py b/lib/lp/bugs/tests/externalbugtracker.py
index 5caceae..a7706d7 100644
--- a/lib/lp/bugs/tests/externalbugtracker.py
+++ b/lib/lp/bugs/tests/externalbugtracker.py
@@ -17,7 +17,6 @@ import time
 import xmlrpc.client
 
 import responses
-import six
 from six.moves.urllib_parse import (
     parse_qs,
     urljoin,
@@ -192,7 +191,7 @@ class TestExternalBugTracker(ExternalBugTracker):
     batch_size = BATCH_SIZE_UNLIMITED
 
     def __init__(self, baseurl='http://example.com/'):
-        super(TestExternalBugTracker, self).__init__(baseurl)
+        super().__init__(baseurl)
 
     def getRemoteBug(self, remote_bug):
         """Return the tuple (None, None) as a representation of a remote bug.
@@ -720,7 +719,7 @@ class TestBugzillaXMLRPCTransport(RequestsTransport):
     def _copy_comment(self, comment, fields_to_return=None):
         # Copy wanted fields.
         return {
-            key: value for (key, value) in six.iteritems(comment)
+            key: value for (key, value) in comment.items()
             if fields_to_return is None or key in fields_to_return}
 
     def comments(self, arguments):
@@ -1682,7 +1681,7 @@ class TestDebBugs(DebBugs):
     sync_comments = False
 
     def __init__(self, baseurl, bugs):
-        super(TestDebBugs, self).__init__(baseurl)
+        super().__init__(baseurl)
         self.bugs = bugs
         self.debbugs_db = TestDebBugsDB()
 
diff --git a/lib/lp/bugs/tests/test_apportjob.py b/lib/lp/bugs/tests/test_apportjob.py
index 1abc69f..8722f5f 100644
--- a/lib/lp/bugs/tests/test_apportjob.py
+++ b/lib/lp/bugs/tests/test_apportjob.py
@@ -66,7 +66,7 @@ class ApportJobTestCase(TestCaseWithFactory):
         # unserialized from JSON, so the representation returned by
         # apport_job.metadata will be different from what we originally
         # passed in.
-        metadata_expected = [u'some', u'arbitrary', u'metadata']
+        metadata_expected = ['some', 'arbitrary', 'metadata']
         self.assertEqual(metadata_expected, apport_job.metadata)
         self.assertProvides(apport_job, IApportJob)
 
@@ -90,7 +90,7 @@ class ProcessApportBlobJobTestCase(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(ProcessApportBlobJobTestCase, self).setUp()
+        super().setUp()
 
         # Create a BLOB using existing testing data.
 
@@ -218,7 +218,7 @@ class ProcessApportBlobJobTestCase(TestCaseWithFactory):
         # NotFoundError.
         self.assertRaises(
             NotFoundError,
-            getUtility(IProcessApportBlobJobSource).getByBlobUUID, u'foobar')
+            getUtility(IProcessApportBlobJobSource).getByBlobUUID, 'foobar')
 
     def test_create_job_creates_only_one(self):
         # IProcessApportBlobJobSource.create() will create only one
@@ -331,7 +331,7 @@ class TestTemporaryBlobStorageAddView(TestCaseWithFactory):
     layer = LaunchpadFunctionalLayer
 
     def setUp(self):
-        super(TestTemporaryBlobStorageAddView, self).setUp()
+        super().setUp()
 
         # Create a BLOB using existing testing data.
         testfiles = os.path.join(config.root, 'lib/lp/bugs/tests/testfiles')
diff --git a/lib/lp/bugs/tests/test_bug.py b/lib/lp/bugs/tests/test_bug.py
index 9598fb1..0c1e24b 100644
--- a/lib/lp/bugs/tests/test_bug.py
+++ b/lib/lp/bugs/tests/test_bug.py
@@ -63,7 +63,7 @@ class TestBugSubscriptionMethods(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugSubscriptionMethods, self).setUp()
+        super().setUp()
         self.bug = self.factory.makeBug()
         self.person = self.factory.makePerson()
 
@@ -172,7 +172,7 @@ class TestBugSnapshotting(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugSnapshotting, self).setUp()
+        super().setUp()
         self.bug = self.factory.makeBug()
         self.person = self.factory.makePerson()
 
@@ -338,7 +338,7 @@ class TestBugPermissions(TestCaseWithFactory, KarmaTestMixin):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugPermissions, self).setUp()
+        super().setUp()
         self.pushConfig(
             'launchpad', min_legitimate_karma=5, min_legitimate_account_age=5)
         self.bug = self.factory.makeBug()
diff --git a/lib/lp/bugs/tests/test_bug_messages.py b/lib/lp/bugs/tests/test_bug_messages.py
index 40c4235..2161049 100644
--- a/lib/lp/bugs/tests/test_bug_messages.py
+++ b/lib/lp/bugs/tests/test_bug_messages.py
@@ -26,7 +26,7 @@ class TestBugIndexedMessages(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugIndexedMessages, self).setUp()
+        super().setUp()
         login('foo.bar@xxxxxxxxxxxxx')
 
         bug_1 = self.factory.makeBug()
diff --git a/lib/lp/bugs/tests/test_bug_messages_webservice.py b/lib/lp/bugs/tests/test_bug_messages_webservice.py
index 96c7f2e..284760b 100644
--- a/lib/lp/bugs/tests/test_bug_messages_webservice.py
+++ b/lib/lp/bugs/tests/test_bug_messages_webservice.py
@@ -122,7 +122,7 @@ class TestSetCommentVisibility(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestSetCommentVisibility, self).setUp()
+        super().setUp()
         self.person_set = getUtility(IPersonSet)
         admins = self.person_set.getByName('admins')
         self.admin = admins.teamowner
diff --git a/lib/lp/bugs/tests/test_bugbranch.py b/lib/lp/bugs/tests/test_bugbranch.py
index 43c16e4..080bf69 100644
--- a/lib/lp/bugs/tests/test_bugbranch.py
+++ b/lib/lp/bugs/tests/test_bugbranch.py
@@ -147,7 +147,7 @@ class TestBugBranch(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugBranch, self).setUp()
+        super().setUp()
         # Bug branch linking is generally available to any logged in user.
         self.factory.loginAsAnyone()
 
diff --git a/lib/lp/bugs/tests/test_bugchanges.py b/lib/lp/bugs/tests/test_bugchanges.py
index 71daeab..b106ada 100644
--- a/lib/lp/bugs/tests/test_bugchanges.py
+++ b/lib/lp/bugs/tests/test_bugchanges.py
@@ -42,7 +42,7 @@ class TestBugChanges(TestCaseWithFactory):
     layer = LaunchpadFunctionalLayer
 
     def setUp(self):
-        super(TestBugChanges, self).setUp('foo.bar@xxxxxxxxxxxxx')
+        super().setUp('foo.bar@xxxxxxxxxxxxx')
         self.user = self.factory.makePerson(
             displayname='Arthur Dent', selfgenerated_bugnotifications=True)
         self.product = self.factory.makeProduct(
@@ -234,7 +234,7 @@ class TestBugChanges(TestCaseWithFactory):
         self.saveOldChanges(bug=bug)
         bug.unsubscribe(subscriber, subscriber)
         unsubscribe_activity = dict(
-            whatchanged=u'removed subscriber Mom', person=subscriber)
+            whatchanged='removed subscriber Mom', person=subscriber)
         self.assertRecordedChange(
             expected_activity=unsubscribe_activity, bug=bug)
 
@@ -1005,7 +1005,7 @@ class TestBugChanges(TestCaseWithFactory):
         # This checks the activity's attribute and target attributes.
         activity = self.bug.activity[-1]
         self.assertEqual(activity.attribute, 'importance')
-        self.assertThat(activity.target, StartsWith(u'product-name'))
+        self.assertThat(activity.target, StartsWith('product-name'))
 
         expected_activity = {
             'person': self.user,
@@ -1017,7 +1017,7 @@ class TestBugChanges(TestCaseWithFactory):
 
         expected_notification = {
             'text': (
-                u'** Changed in: %s\n   Importance: Undecided => High' %
+                '** Changed in: %s\n   Importance: Undecided => High' %
                 self.bug_task.bugtargetname),
             'person': self.user,
             }
@@ -1043,7 +1043,7 @@ class TestBugChanges(TestCaseWithFactory):
 
         expected_notification = {
             'text': (
-                u'** Changed in: %s\n       Status: New => Fix Committed' %
+                '** Changed in: %s\n       Status: New => Fix Committed' %
                 self.bug_task.bugtargetname),
             'person': self.user,
             }
@@ -1071,7 +1071,7 @@ class TestBugChanges(TestCaseWithFactory):
             }
 
         expected_notification = {
-            'text': u"** Project changed: %s => %s" % (
+            'text': "** Project changed: %s => %s" % (
                 bug_task_before_modification.bugtargetname,
                 self.bug_task.bugtargetname),
             'person': self.user,
@@ -1123,7 +1123,7 @@ class TestBugChanges(TestCaseWithFactory):
             for bug_task in source_package_bug.bugtasks
             if bug_task.pillar.official_malone)
         expected_notification = {
-            'text': u"** Package changed: %s => %s" % (
+            'text': "** Package changed: %s => %s" % (
                 bug_task_before_modification.bugtargetname,
                 source_package_bug_task.bugtargetname),
             'person': self.user,
@@ -1167,7 +1167,7 @@ class TestBugChanges(TestCaseWithFactory):
 
         expected_notification = {
             'text': (
-                u'** Changed in: %s\n Remote watch: None => %s' % (
+                '** Changed in: %s\n Remote watch: None => %s' % (
                 self.bug_task.bugtargetname, bug_watch.title)),
             'person': self.user,
             }
@@ -1194,7 +1194,7 @@ class TestBugChanges(TestCaseWithFactory):
 
         expected_notification = {
             'text': (
-                u'** Changed in: %s\n Remote watch: %s => None' % (
+                '** Changed in: %s\n Remote watch: %s => None' % (
                 self.bug_task.bugtargetname, bug_watch.title)),
             'person': self.user,
             }
@@ -1219,8 +1219,8 @@ class TestBugChanges(TestCaseWithFactory):
 
         expected_notification = {
             'text': (
-                u'** Changed in: %s\n'
-                u'     Assignee: (unassigned) => %s' % (
+                '** Changed in: %s\n'
+                '     Assignee: (unassigned) => %s' % (
                     self.bug_task.bugtargetname,
                     self.user.unique_displayname)),
             'person': self.user,
@@ -1250,8 +1250,8 @@ class TestBugChanges(TestCaseWithFactory):
 
         expected_notification = {
             'text': (
-                u'** Changed in: %s\n'
-                u'     Assignee: %s => (unassigned)' % (
+                '** Changed in: %s\n'
+                '     Assignee: %s => (unassigned)' % (
                     bug_task.bugtargetname,
                     old_assignee.unique_displayname)),
             'person': self.user,
@@ -1291,7 +1291,7 @@ class TestBugChanges(TestCaseWithFactory):
 
         expected_notification = {
             'text': (
-                u'** Changed in: %s\n    Milestone: None => %s' % (
+                '** Changed in: %s\n    Milestone: None => %s' % (
                 self.bug_task.bugtargetname, milestone.name)),
             'person': self.user,
             }
@@ -1322,7 +1322,7 @@ class TestBugChanges(TestCaseWithFactory):
 
         expected_notification = {
             'text': (
-                u'** Changed in: %s\n    Milestone: %s => None' % (
+                '** Changed in: %s\n    Milestone: %s => None' % (
                 self.bug_task.bugtargetname, milestone.name)),
             'person': self.user,
             'recipients': [
@@ -1360,8 +1360,8 @@ class TestBugChanges(TestCaseWithFactory):
 
         expected_notification = {
             'text': (
-                u'** Changed in: %s\n'
-                u'    Milestone: %s => %s' % (
+                '** Changed in: %s\n'
+                '    Milestone: %s => %s' % (
                     self.bug_task.bugtargetname,
                     old_milestone.name, new_milestone.name)),
             'person': self.user,
@@ -1772,12 +1772,12 @@ class TestBugChanges(TestCaseWithFactory):
         expected_activity = {
             'person': self.user,
             'whatchanged': 'bug',
-            'message': u"added bug",
+            'message': "added bug",
             }
 
         expected_notification = {
             'person': self.user,
-            'text': u"ENOTOWEL",
+            'text': "ENOTOWEL",
             'is_comment': True,
             'recipients': new_bug.getBugNotificationRecipients(
                 level=BugNotificationLevel.LIFECYCLE),
diff --git a/lib/lp/bugs/tests/test_bugnomination.py b/lib/lp/bugs/tests/test_bugnomination.py
index 94d5578..d24c992 100644
--- a/lib/lp/bugs/tests/test_bugnomination.py
+++ b/lib/lp/bugs/tests/test_bugnomination.py
@@ -204,14 +204,14 @@ class CanBeNominatedForTestMixin:
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(CanBeNominatedForTestMixin, self).setUp()
+        super().setUp()
         login('foo.bar@xxxxxxxxxxxxx')
         self.eric = self.factory.makePerson(name='eric')
         self.setUpTarget()
 
     def tearDown(self):
         logout()
-        super(CanBeNominatedForTestMixin, self).tearDown()
+        super().tearDown()
 
     def test_canBeNominatedFor_series(self):
         # A bug may be nominated for a series of a product with an existing
diff --git a/lib/lp/bugs/tests/test_bugnotification.py b/lib/lp/bugs/tests/test_bugnotification.py
index e58328d..6fb03c3 100644
--- a/lib/lp/bugs/tests/test_bugnotification.py
+++ b/lib/lp/bugs/tests/test_bugnotification.py
@@ -42,8 +42,7 @@ class TestNotificationsSentForBugExpiration(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestNotificationsSentForBugExpiration, self).setUp(
-            user='test@xxxxxxxxxxxxx')
+        super().setUp(user='test@xxxxxxxxxxxxx')
         # We need a product, a bug for this product, a question linked
         # to the bug and a subscriber.
         self.product = self.factory.makeProduct()
@@ -75,7 +74,7 @@ class TestNotificationsLinkToFilters(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestNotificationsLinkToFilters, self).setUp()
+        super().setUp()
         self.bug = self.factory.makeBug()
         self.subscriber = self.factory.makePerson()
         self.subscription = self.bug.default_bugtask.target.addSubscription(
@@ -87,7 +86,7 @@ class TestNotificationsLinkToFilters(TestCaseWithFactory):
         # construct_email_notifications to work.
         BugNotificationRecipient(
             bug_notification=notification, person=person,
-            reason_header=u'reason header', reason_body=u'reason body')
+            reason_header='reason header', reason_body='reason body')
 
     def addNotification(self, person, bug=None):
         # Add a notification along with recipient data.
@@ -121,10 +120,10 @@ class TestNotificationsLinkToFilters(TestCaseWithFactory):
 
     def prepareTwoNotificationsWithFilters(self):
         # Set up first notification and filter.
-        self.includeFilterInNotification(description=u'Special Filter!')
+        self.includeFilterInNotification(description='Special Filter!')
         # Set up second notification and filter.
         self.notification2 = self.addNotification(self.subscriber)
-        self.includeFilterInNotification(description=u'Another Filter!',
+        self.includeFilterInNotification(description='Another Filter!',
                                          create_new_filter=True,
                                          notification=self.notification2)
 
@@ -173,7 +172,7 @@ class TestNotificationsLinkToFilters(TestCaseWithFactory):
             subscriber2, subscriber2)
         notification2 = self.addNotification(subscriber2)
         self.includeFilterInNotification(subscription=subscription2,
-                                         description=u'Special Filter!',
+                                         description='Special Filter!',
                                          notification=notification2)
         sources = list(self.notification.recipients)
         sources2 = list(notification2.recipients)
@@ -181,7 +180,7 @@ class TestNotificationsLinkToFilters(TestCaseWithFactory):
             {self.subscriber: {'sources': sources,
                                'filter descriptions': []},
              subscriber2: {'sources': sources2,
-                           'filter descriptions': [u'Special Filter!']}},
+                           'filter descriptions': ['Special Filter!']}},
             BugNotificationSet().getRecipientFilterData(
                 self.bug, {self.subscriber: sources, subscriber2: sources2},
                 [self.notification, notification2]))
@@ -189,7 +188,7 @@ class TestNotificationsLinkToFilters(TestCaseWithFactory):
     def test_getRecipientFilterData_match(self):
         # When there are bug filters for the recipient,
         # only those filters are returned.
-        self.includeFilterInNotification(description=u'Special Filter!')
+        self.includeFilterInNotification(description='Special Filter!')
         sources = list(self.notification.recipients)
         self.assertEqual(
             {self.subscriber: {'sources': sources,
@@ -215,7 +214,7 @@ class TestNotificationsLinkToFilters(TestCaseWithFactory):
     def test_getRecipientFilterData_mute(self):
         # When there are bug filters for the recipient,
         # only those filters are returned.
-        self.includeFilterInNotification(description=u'Special Filter!')
+        self.includeFilterInNotification(description='Special Filter!')
         # Mute the first filter.
         BugSubscriptionFilterMute(
             person=self.subscriber,
@@ -237,13 +236,13 @@ class TestNotificationsLinkToFilters(TestCaseWithFactory):
             subscriber2, subscriber2)
         notification2 = self.addNotification(subscriber2)
         self.includeFilterInNotification(subscription=subscription2,
-                                         description=u'Special Filter!',
+                                         description='Special Filter!',
                                          notification=notification2)
         sources = list(self.notification.recipients)
         sources2 = list(notification2.recipients)
         self.assertEqual(
             {subscriber2: {'sources': sources2,
-                           'filter descriptions': [u'Special Filter!']}},
+                           'filter descriptions': ['Special Filter!']}},
             BugNotificationSet().getRecipientFilterData(
                 self.bug, {self.subscriber: sources, subscriber2: sources2},
                 [self.notification, notification2]))
@@ -318,7 +317,7 @@ class TestNotificationsLinkToFilters(TestCaseWithFactory):
     def test_getRecipientFilterData_mute_bug_mutes_filter(self):
         # Mute the bug for the subscriber.
         self.bug.mute(self.subscriber, self.subscriber)
-        self.includeFilterInNotification(description=u'Special Filter!')
+        self.includeFilterInNotification(description='Special Filter!')
         sources = list(self.notification.recipients)
         self.assertEqual(
             {},
@@ -357,8 +356,7 @@ class TestNotificationsForDuplicates(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestNotificationsForDuplicates, self).setUp(
-            user='test@xxxxxxxxxxxxx')
+        super().setUp(user='test@xxxxxxxxxxxxx')
         self.bug = self.factory.makeBug()
         self.dupe_bug = self.factory.makeBug()
         self.dupe_bug.markAsDuplicate(self.bug)
@@ -467,7 +465,7 @@ class TestGetDeferredNotifications(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestGetDeferredNotifications, self).setUp()
+        super().setUp()
         self.bns = BugNotificationSet()
 
     def test_no_deferred_notifications(self):
diff --git a/lib/lp/bugs/tests/test_bugs_webservice.py b/lib/lp/bugs/tests/test_bugs_webservice.py
index 6dd7137..8248f22 100644
--- a/lib/lp/bugs/tests/test_bugs_webservice.py
+++ b/lib/lp/bugs/tests/test_bugs_webservice.py
@@ -62,7 +62,7 @@ class TestBugConstraints(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugConstraints, self).setUp()
+        super().setUp()
         product = self.factory.makeProduct(name='foo')
         self.bug = self.factory.makeBug(target=product)
         self.bug_url = api_url(self.bug)
@@ -117,7 +117,7 @@ class TestBugDescriptionRepresentation(TestCaseWithFactory):
 
         self.assertEqual(
             self.findBugDescription(response),
-            u'<p>Useless bugs are useless. '
+            '<p>Useless bugs are useless. '
             'See <a class="bug-link" href="/bugs/%d">Bug %d</a>.</p>' % (
             self.bug_one.id, self.bug_one.id))
 
@@ -137,7 +137,7 @@ class TestBugDescriptionRepresentation(TestCaseWithFactory):
 
         self.assertEqual(
             self.findBugDescription(response),
-            u'<p>See <a class="bug-link" href="/bugs/%d">bug %d</a></p>' % (
+            '<p>See <a class="bug-link" href="/bugs/%d">bug %d</a></p>' % (
             self.bug_one.id, self.bug_one.id))
 
 
@@ -271,7 +271,7 @@ class TestBugMessages(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugMessages, self).setUp(USER_EMAIL)
+        super().setUp(USER_EMAIL)
         self.bug = self.factory.makeBug()
         self.bug_url = api_url(self.bug)
         self.message1 = self.factory.makeMessage()
diff --git a/lib/lp/bugs/tests/test_bugsearch_conjoined.py b/lib/lp/bugs/tests/test_bugsearch_conjoined.py
index 5b572df..6e28a4a 100644
--- a/lib/lp/bugs/tests/test_bugsearch_conjoined.py
+++ b/lib/lp/bugs/tests/test_bugsearch_conjoined.py
@@ -42,7 +42,7 @@ class TestProjectExcludeConjoinedMasterSearch(TestSearchBase):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestProjectExcludeConjoinedMasterSearch, self).setUp()
+        super().setUp()
         self.bugtask_set = getUtility(IBugTaskSet)
         self.product = self.factory.makeProduct()
         self.milestone = self.factory.makeMilestone(
@@ -135,7 +135,7 @@ class TestProjectGroupExcludeConjoinedMasterSearch(TestSearchBase):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestProjectGroupExcludeConjoinedMasterSearch, self).setUp()
+        super().setUp()
         self.bugtask_set = getUtility(IBugTaskSet)
         self.projectgroup = self.factory.makeProject()
         self.bug_count = 2
@@ -249,7 +249,7 @@ class TestDistributionExcludeConjoinedMasterSearch(TestSearchBase):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestDistributionExcludeConjoinedMasterSearch, self).setUp()
+        super().setUp()
         self.bugtask_set = getUtility(IBugTaskSet)
         self.distro = getUtility(ILaunchpadCelebrities).ubuntu
         self.milestone = self.factory.makeMilestone(
diff --git a/lib/lp/bugs/tests/test_bugsubscription.py b/lib/lp/bugs/tests/test_bugsubscription.py
index 768f3b0..351054c 100644
--- a/lib/lp/bugs/tests/test_bugsubscription.py
+++ b/lib/lp/bugs/tests/test_bugsubscription.py
@@ -28,7 +28,7 @@ class TestBugSubscription(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugSubscription, self).setUp()
+        super().setUp()
         self.bug = self.factory.makeBug()
         self.subscriber = self.factory.makePerson()
 
diff --git a/lib/lp/bugs/tests/test_bugsupervisor_bugnomination.py b/lib/lp/bugs/tests/test_bugsupervisor_bugnomination.py
index e042e61..0233e02 100644
--- a/lib/lp/bugs/tests/test_bugsupervisor_bugnomination.py
+++ b/lib/lp/bugs/tests/test_bugsupervisor_bugnomination.py
@@ -24,7 +24,7 @@ class AddNominationTestMixin:
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(AddNominationTestMixin, self).setUp()
+        super().setUp()
         login('foo.bar@xxxxxxxxxxxxx')
         self.user = self.factory.makePerson(name='ordinary-user')
         self.bug_supervisor = self.factory.makePerson(name='no-ordinary-user')
@@ -34,7 +34,7 @@ class AddNominationTestMixin:
 
     def tearDown(self):
         logout()
-        super(AddNominationTestMixin, self).tearDown()
+        super().tearDown()
 
     def test_user_addNominationFor_series(self):
         # A bug may not be nominated for a series of a product with an
diff --git a/lib/lp/bugs/tests/test_bugtarget2.py b/lib/lp/bugs/tests/test_bugtarget2.py
index 9f50d1e..358ae94 100644
--- a/lib/lp/bugs/tests/test_bugtarget2.py
+++ b/lib/lp/bugs/tests/test_bugtarget2.py
@@ -36,7 +36,7 @@ class TestDistribution(BugTargetBugFilingDuplicateSearchAlwaysOn,
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestDistribution, self).setUp()
+        super().setUp()
         self.bugtarget = self.factory.makeDistribution()
 
     def test_pillar(self):
@@ -50,7 +50,7 @@ class TestDistroSeries(BugTargetBugFilingDuplicateSearchAlwaysOn,
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestDistroSeries, self).setUp()
+        super().setUp()
         self.bugtarget = self.factory.makeDistroSeries()
 
     def test_bugtarget_parent(self):
@@ -72,7 +72,7 @@ class TestProjectGroup(BugTargetBugFilingDuplicateSearchAlwaysOn,
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestProjectGroup, self).setUp()
+        super().setUp()
         self.bugtarget = self.factory.makeProject()
 
 
@@ -98,7 +98,7 @@ class TestProduct(BugTargetBugFilingDuplicateSearchSettable,
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestProduct, self).setUp()
+        super().setUp()
         self.bug_supervisor = self.factory.makePerson()
         self.bugtarget = self.factory.makeProduct(
             bug_supervisor=self.bug_supervisor)
@@ -114,7 +114,7 @@ class TestDistributionSourcePackage(BugTargetBugFilingDuplicateSearchSettable,
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestDistributionSourcePackage, self).setUp()
+        super().setUp()
         self.bug_supervisor = self.factory.makePerson()
         distribution = self.factory.makeDistribution(
             bug_supervisor=self.bug_supervisor)
@@ -150,7 +150,7 @@ class TestProductSeries(BugTargetBugFilingDuplicateSearchInherited,
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestProductSeries, self).setUp()
+        super().setUp()
         self.bug_supervisor = self.factory.makePerson()
         self.bugtarget = self.factory.makeProductSeries(
             product=self.factory.makeProduct(
@@ -175,7 +175,7 @@ class TestSourcePackage(BugTargetBugFilingDuplicateSearchInherited,
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestSourcePackage, self).setUp()
+        super().setUp()
         self.bug_supervisor = self.factory.makePerson()
         distribution = self.factory.makeDistribution(
             bug_supervisor=self.bug_supervisor)
diff --git a/lib/lp/bugs/tests/test_bugtaskset.py b/lib/lp/bugs/tests/test_bugtaskset.py
index f6bd8f4..11eb0bc 100644
--- a/lib/lp/bugs/tests/test_bugtaskset.py
+++ b/lib/lp/bugs/tests/test_bugtaskset.py
@@ -88,7 +88,7 @@ class TestSortingBugTasks(TestCase):
         tasks = bug_one.bugtasks
         task_names = [task.bugtargetdisplayname for task in tasks]
         self.assertEqual(task_names, [
-            u'Mozilla Firefox',
+            'Mozilla Firefox',
             'mozilla-firefox (Ubuntu)',
             'mozilla-firefox (Debian)',
         ])
diff --git a/lib/lp/bugs/tests/test_bugtracker.py b/lib/lp/bugs/tests/test_bugtracker.py
index 1de0a76..59f4e7d 100644
--- a/lib/lp/bugs/tests/test_bugtracker.py
+++ b/lib/lp/bugs/tests/test_bugtracker.py
@@ -107,7 +107,7 @@ class BugTrackerTestCase(TestCaseWithFactory):
     layer = LaunchpadFunctionalLayer
 
     def setUp(self):
-        super(BugTrackerTestCase, self).setUp()
+        super().setUp()
         self.bug_tracker = self.factory.makeBugTracker()
         for i in range(5):
             self.factory.makeBugWatch(bugtracker=self.bug_tracker)
@@ -274,7 +274,7 @@ class TestMantis(TestCaseWithFactory):
     layer = LaunchpadFunctionalLayer
 
     def setUp(self):
-        super(TestMantis, self).setUp()
+        super().setUp()
         # We need to commit to avoid there being errors from the
         # checkwatches isolation protection code.
         transaction.commit()
diff --git a/lib/lp/bugs/tests/test_bugtracker_components.py b/lib/lp/bugs/tests/test_bugtracker_components.py
index a30a522..f457d7c 100644
--- a/lib/lp/bugs/tests/test_bugtracker_components.py
+++ b/lib/lp/bugs/tests/test_bugtracker_components.py
@@ -23,7 +23,7 @@ class BugTrackerComponentTestCase(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(BugTrackerComponentTestCase, self).setUp()
+        super().setUp()
 
         regular_user = self.factory.makePerson()
         login_person(regular_user)
@@ -31,15 +31,15 @@ class BugTrackerComponentTestCase(TestCaseWithFactory):
         self.bug_tracker = self.factory.makeBugTracker()
 
         self.comp_group = self.factory.makeBugTrackerComponentGroup(
-            u'alpha',
+            'alpha',
             self.bug_tracker)
 
     def test_component_creation(self):
         """Verify a component can be created"""
         component = self.factory.makeBugTrackerComponent(
-            u'example', self.comp_group)
+            'example', self.comp_group)
         self.assertIsNot(None, component)
-        self.assertEqual(component.name, u'example')
+        self.assertEqual(component.name, 'example')
 
     def test_set_visibility(self):
         """Users can delete components
@@ -50,7 +50,7 @@ class BugTrackerComponentTestCase(TestCaseWithFactory):
         show up again when we re-sync from the remote bug tracker.
         """
         component = self.factory.makeBugTrackerComponent(
-            u'example', self.comp_group)
+            'example', self.comp_group)
         self.assertEqual(component.is_visible, True)
 
         component.is_visible = False
@@ -66,18 +66,18 @@ class BugTrackerComponentTestCase(TestCaseWithFactory):
         from the remote bug tracker.  This gives users a way to correct
         the omissions."""
         custom_component = self.factory.makeBugTrackerComponent(
-            u'example', self.comp_group, custom=True)
+            'example', self.comp_group, custom=True)
         self.assertIsNot(None, custom_component)
         self.assertEqual(custom_component.is_custom, True)
 
     def test_multiple_component_creation(self):
         """Verify several components can be created at once"""
         comp_a = self.factory.makeBugTrackerComponent(
-            u'example-a', self.comp_group)
+            'example-a', self.comp_group)
         comp_b = self.factory.makeBugTrackerComponent(
-            u'example-b', self.comp_group)
+            'example-b', self.comp_group)
         comp_c = self.factory.makeBugTrackerComponent(
-            u'example-c', self.comp_group, True)
+            'example-c', self.comp_group, True)
 
         self.assertIsNot(None, comp_a)
         self.assertIsNot(None, comp_b)
@@ -86,8 +86,8 @@ class BugTrackerComponentTestCase(TestCaseWithFactory):
     def test_link_distro_source_package(self):
         """Check that a link can be set to a distro source package"""
         example_component = self.factory.makeBugTrackerComponent(
-            u'example', self.comp_group)
-        dsp = self.factory.makeDistributionSourcePackage(u'example')
+            'example', self.comp_group)
+        dsp = self.factory.makeDistributionSourcePackage('example')
 
         example_component.distro_source_package = dsp
         self.assertEqual(dsp, example_component.distro_source_package)
@@ -101,7 +101,7 @@ class TestBugTrackerWithComponents(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugTrackerWithComponents, self).setUp()
+        super().setUp()
 
         regular_user = self.factory.makePerson()
         login_person(regular_user)
@@ -113,7 +113,7 @@ class TestBugTrackerWithComponents(TestCaseWithFactory):
         self.assertTrue(self.bug_tracker is not None)
 
         # Empty bugtrackers shouldn't return component groups
-        comp_group = self.bug_tracker.getRemoteComponentGroup(u'non-existant')
+        comp_group = self.bug_tracker.getRemoteComponentGroup('non-existant')
         self.assertEqual(comp_group, None)
 
         # Verify it contains no component groups
@@ -125,19 +125,19 @@ class TestBugTrackerWithComponents(TestCaseWithFactory):
         """
         # Add a component group and fill it with some components
         default_comp_group = self.bug_tracker.addRemoteComponentGroup(
-            u'alpha')
-        default_comp_group.addComponent(u'example-a')
-        default_comp_group.addComponent(u'example-b')
-        default_comp_group.addComponent(u'example-c')
+            'alpha')
+        default_comp_group.addComponent('example-a')
+        default_comp_group.addComponent('example-b')
+        default_comp_group.addComponent('example-c')
 
         # Verify that retrieving an invalid component group returns nothing
-        comp_group = self.bug_tracker.getRemoteComponentGroup(u'non-existant')
+        comp_group = self.bug_tracker.getRemoteComponentGroup('non-existant')
         self.assertEqual(comp_group, None)
 
         # Now retrieve the component group we added
-        comp_group = self.bug_tracker.getRemoteComponentGroup(u'alpha')
+        comp_group = self.bug_tracker.getRemoteComponentGroup('alpha')
         self.assertEqual(comp_group, default_comp_group)
-        self.assertEqual(comp_group.name, u'alpha')
+        self.assertEqual(comp_group.name, 'alpha')
 
         # Verify there is only the one component group in the tracker
         comp_groups = self.bug_tracker.getAllRemoteComponentGroups()
@@ -146,22 +146,22 @@ class TestBugTrackerWithComponents(TestCaseWithFactory):
     def test_multiple_product_bugtracker(self):
         """Bug tracker with multiple products and components"""
         # Create several component groups with varying numbers of components
-        self.bug_tracker.addRemoteComponentGroup(u'alpha')
+        self.bug_tracker.addRemoteComponentGroup('alpha')
 
-        comp_group_ii = self.bug_tracker.addRemoteComponentGroup(u'beta')
-        comp_group_ii.addComponent(u'example-beta-1')
+        comp_group_ii = self.bug_tracker.addRemoteComponentGroup('beta')
+        comp_group_ii.addComponent('example-beta-1')
 
-        comp_group_iii = self.bug_tracker.addRemoteComponentGroup(u'gamma')
-        comp_group_iii.addComponent(u'example-gamma-1')
-        comp_group_iii.addComponent(u'example-gamma-2')
-        comp_group_iii.addComponent(u'example-gamma-3')
+        comp_group_iii = self.bug_tracker.addRemoteComponentGroup('gamma')
+        comp_group_iii.addComponent('example-gamma-1')
+        comp_group_iii.addComponent('example-gamma-2')
+        comp_group_iii.addComponent('example-gamma-3')
 
         # Retrieving a non-existant component group returns nothing
-        comp_group = self.bug_tracker.getRemoteComponentGroup(u'non-existant')
+        comp_group = self.bug_tracker.getRemoteComponentGroup('non-existant')
         self.assertEqual(comp_group, None)
 
         # Now retrieve one of the real component groups
-        comp_group = self.bug_tracker.getRemoteComponentGroup(u'beta')
+        comp_group = self.bug_tracker.getRemoteComponentGroup('beta')
         self.assertEqual(comp_group, comp_group_ii)
 
         # Check the correct number of component groups are in the bug tracker
@@ -172,18 +172,18 @@ class TestBugTrackerWithComponents(TestCaseWithFactory):
         """Retrieve a set of components from a given product"""
         # Create a component group with some components
         default_comp_group = self.bug_tracker.addRemoteComponentGroup(
-            u'alpha')
-        default_comp_group.addComponent(u'example-a')
-        default_comp_group.addComponent(u'example-b')
-        default_comp_group.addComponent(u'example-c')
+            'alpha')
+        default_comp_group.addComponent('example-a')
+        default_comp_group.addComponent('example-b')
+        default_comp_group.addComponent('example-c')
 
         # Verify group has the correct number of components
-        comp_group = self.bug_tracker.getRemoteComponentGroup(u'alpha')
+        comp_group = self.bug_tracker.getRemoteComponentGroup('alpha')
         self.assertEqual(len(list(comp_group.components)), 3)
 
         # Check one of the components, that it is what we expect
-        comp = comp_group.getComponent(u'example-b')
-        self.assertEqual(comp.name, u'example-b')
+        comp = comp_group.getComponent('example-b')
+        self.assertEqual(comp.name, 'example-b')
 
 
 class TestWebservice(TestCaseWithFactory):
@@ -191,7 +191,7 @@ class TestWebservice(TestCaseWithFactory):
     layer = AppServerLayer
 
     def setUp(self):
-        super(TestWebservice, self).setUp()
+        super().setUp()
 
         regular_user = self.factory.makePerson()
         login_person(regular_user)
@@ -212,17 +212,17 @@ class TestWebservice(TestCaseWithFactory):
 
     def test_retrieve_component_group_from_bug_tracker(self):
         """Looks up specific component group in bug tracker"""
-        self.bug_tracker.addRemoteComponentGroup(u'alpha')
+        self.bug_tracker.addRemoteComponentGroup('alpha')
 
         bug_tracker = ws_object(self.launchpad, self.bug_tracker)
         comp_group = bug_tracker.getRemoteComponentGroup(
-            component_group_name=u'alpha')
+            component_group_name='alpha')
         self.assertIsNot(None, comp_group)
 
     def test_list_component_groups_for_bug_tracker(self):
         """Retrieve the component groups for a bug tracker"""
-        self.bug_tracker.addRemoteComponentGroup(u'alpha')
-        self.bug_tracker.addRemoteComponentGroup(u'beta')
+        self.bug_tracker.addRemoteComponentGroup('alpha')
+        self.bug_tracker.addRemoteComponentGroup('beta')
 
         bug_tracker = ws_object(self.launchpad, self.bug_tracker)
         comp_groups = bug_tracker.getAllRemoteComponentGroups()
@@ -230,10 +230,9 @@ class TestWebservice(TestCaseWithFactory):
 
     def test_list_components_for_component_group(self):
         """Retrieve the components for a given group"""
-        db_comp_group_alpha = self.bug_tracker.addRemoteComponentGroup(
-            u'alpha')
-        db_comp_group_alpha.addComponent(u'1')
-        db_comp_group_alpha.addComponent(u'2')
+        db_comp_group_alpha = self.bug_tracker.addRemoteComponentGroup('alpha')
+        db_comp_group_alpha.addComponent('1')
+        db_comp_group_alpha.addComponent('2')
         transaction.commit()
 
         comp_group = ws_object(self.launchpad, db_comp_group_alpha)
@@ -241,10 +240,9 @@ class TestWebservice(TestCaseWithFactory):
 
     def test_add_component(self):
         """Add a custom (local) component to the component group"""
-        db_comp_group = self.bug_tracker.addRemoteComponentGroup(
-            u'alpha')
+        db_comp_group = self.bug_tracker.addRemoteComponentGroup('alpha')
         comp_group = ws_object(self.launchpad, db_comp_group)
-        comp_group.addComponent(component_name=u'c')
+        comp_group.addComponent(component_name='c')
         self.assertEqual(1, len(comp_group.components))
 
     def test_remove_component(self):
diff --git a/lib/lp/bugs/tests/test_bugtracker_vocabulary.py b/lib/lp/bugs/tests/test_bugtracker_vocabulary.py
index d01c9da..0a52519 100644
--- a/lib/lp/bugs/tests/test_bugtracker_vocabulary.py
+++ b/lib/lp/bugs/tests/test_bugtracker_vocabulary.py
@@ -19,7 +19,7 @@ class TestBugTrackerVocabulary(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugTrackerVocabulary, self).setUp()
+        super().setUp()
         vocabulary_registry = getVocabularyRegistry()
         self.vocab = vocabulary_registry.get(None, 'BugTracker')
 
@@ -100,7 +100,7 @@ class TestWebBugTrackerVocabulary(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestWebBugTrackerVocabulary, self).setUp()
+        super().setUp()
         vocabulary_registry = getVocabularyRegistry()
         self.vocab = vocabulary_registry.get(None, 'WebBugTracker')
 
diff --git a/lib/lp/bugs/tests/test_bugvisibility.py b/lib/lp/bugs/tests/test_bugvisibility.py
index 2ee32e8..b5c4cc9 100644
--- a/lib/lp/bugs/tests/test_bugvisibility.py
+++ b/lib/lp/bugs/tests/test_bugvisibility.py
@@ -20,7 +20,7 @@ class TestPublicBugVisibility(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestPublicBugVisibility, self).setUp()
+        super().setUp()
         owner = self.factory.makePerson(name="bugowner")
         self.bug = self.factory.makeBug(owner=owner)
 
@@ -40,7 +40,7 @@ class TestPrivateBugVisibility(TestCaseWithFactory):
     layer = ZopelessDatabaseLayer
 
     def setUp(self):
-        super(TestPrivateBugVisibility, self).setUp()
+        super().setUp()
         self.owner = self.factory.makePerson(name="bugowner")
         self.product_owner = self.factory.makePerson(name="productowner")
         self.product = self.factory.makeProduct(
diff --git a/lib/lp/bugs/tests/test_bugwatch.py b/lib/lp/bugs/tests/test_bugwatch.py
index 6dca2df..d595d08 100644
--- a/lib/lp/bugs/tests/test_bugwatch.py
+++ b/lib/lp/bugs/tests/test_bugwatch.py
@@ -201,7 +201,7 @@ class ExtractBugTrackerAndBugTest(WithScenarios, TestCase):
     already_registered = False
 
     def setUp(self):
-        super(ExtractBugTrackerAndBugTest, self).setUp()
+        super().setUp()
         login(ANONYMOUS)
         self.bugwatch_set = getUtility(IBugWatchSet)
         self.bugtracker_set = getUtility(IBugTrackerSet)
@@ -509,7 +509,7 @@ class TestBugWatchSetBulkOperations(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestBugWatchSetBulkOperations, self).setUp()
+        super().setUp()
         self.bug_watches = [
             self.factory.makeBugWatch(remote_bug='alice'),
             self.factory.makeBugWatch(remote_bug='bob'),
@@ -594,7 +594,7 @@ class TestBugWatchBugTasks(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugWatchBugTasks, self).setUp('test@xxxxxxxxxxxxx')
+        super().setUp('test@xxxxxxxxxxxxx')
         self.bug_watch = self.factory.makeBugWatch()
 
     def test_bugtasks(self):
@@ -609,8 +609,7 @@ class TestBugWatchActivityPruner(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestBugWatchActivityPruner, self).setUp(
-            'foo.bar@xxxxxxxxxxxxx')
+        super().setUp('foo.bar@xxxxxxxxxxxxx')
         self.bug_watch = self.factory.makeBugWatch()
         for i in range(MAX_SAMPLE_SIZE + 1):
             self.bug_watch.addActivity()
@@ -650,7 +649,7 @@ class TestBugWatchResetting(TestCaseWithFactory):
     layer = LaunchpadFunctionalLayer
 
     def setUp(self):
-        super(TestBugWatchResetting, self).setUp(user=ADMIN_EMAIL)
+        super().setUp(user=ADMIN_EMAIL)
         self.bug_watch = self.factory.makeBugWatch()
         naked = removeSecurityProxy(self.bug_watch)
         naked.last_error_type = BugWatchActivityStatus.BUG_NOT_FOUND
diff --git a/lib/lp/bugs/tests/test_bzremotecomponentfinder.py b/lib/lp/bugs/tests/test_bzremotecomponentfinder.py
index 0bdf42b..71c6801 100644
--- a/lib/lp/bugs/tests/test_bzremotecomponentfinder.py
+++ b/lib/lp/bugs/tests/test_bzremotecomponentfinder.py
@@ -31,7 +31,7 @@ def read_test_file(name):
     Test files are located in lib/canonical/launchpad/ftests/testfiles
     """
     file_path = os.path.join(os.path.dirname(__file__), 'testfiles', name)
-    with open(file_path, 'r') as test_file:
+    with open(file_path) as test_file:
         return test_file.read()
 
 
@@ -40,7 +40,7 @@ class TestBugzillaRemoteComponentScraper(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugzillaRemoteComponentScraper, self).setUp()
+        super().setUp()
 
     def test_url_correction(self):
         scraper = BugzillaRemoteComponentScraper(
@@ -66,7 +66,6 @@ class TestBugzillaRemoteComponentScraper(TestCaseWithFactory):
             ("'b\\!ah'",     {'b!ah':    {'name': 'b!ah'}}),
             ("42",           {'42':      {'name': '42'}}),
             ("''",           {'':        {'name': ''}}),
-            (u"uni",         {'uni':     {'name': 'uni'}}),
             ("'a', 'b','c'", {'a':       {'name': 'a'},
                               'b':       {'name': 'b'},
                               'c':       {'name': 'c'},
@@ -83,9 +82,9 @@ class TestBugzillaRemoteComponentScraper(TestCaseWithFactory):
             base_url="http://bugs.wine.org";)
         page_text = read_test_file("bugzilla-wine-advanced-query.html")
         self.scraper.parsePage(page_text)
-        self.assertTrue(u'Wine' in self.scraper.products)
+        self.assertTrue('Wine' in self.scraper.products)
         xorg = self.scraper.products['Wine']
-        self.assertTrue(u'ole' in xorg['components'])
+        self.assertTrue('ole' in xorg['components'])
 
 
 class TestBugzillaRemoteComponentFinder(TestCaseWithFactory):
@@ -93,7 +92,7 @@ class TestBugzillaRemoteComponentFinder(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugzillaRemoteComponentFinder, self).setUp()
+        super().setUp()
         login(ADMIN_EMAIL)
 
     def assertGetRemoteProductsAndComponentsDoesNotAssert(self, finder):
@@ -118,19 +117,19 @@ class TestBugzillaRemoteComponentFinder(TestCaseWithFactory):
         bz_bugtracker = BugzillaRemoteComponentScraper(
             base_url="http://bugzilla.example.org";)
         bz_bugtracker.products = {
-            u'alpha': {
-                'name': u'alpha',
+            'alpha': {
+                'name': 'alpha',
                 'components': {
-                    u'1': {'name': u'one', },
-                    u'2': {'name': u'two', },
-                    u'3': {'name': u'three', },
+                    '1': {'name': 'one', },
+                    '2': {'name': 'two', },
+                    '3': {'name': 'three', },
                     },
                 'versions': None,
                 },
-            u'beta': {
-                'name': u'beta',
+            'beta': {
+                'name': 'beta',
                 'components': {
-                    u'4': {'name': u'four', },
+                    '4': {'name': 'four', },
                     },
                 'versions': None,
                 }
@@ -143,14 +142,14 @@ class TestBugzillaRemoteComponentFinder(TestCaseWithFactory):
         # Verify the data got stored properly
         comp_groups = lp_bugtracker.getAllRemoteComponentGroups()
         self.assertEqual(2, len(list(comp_groups)))
-        comp_group = lp_bugtracker.getRemoteComponentGroup(u'alpha')
+        comp_group = lp_bugtracker.getRemoteComponentGroup('alpha')
         self.assertEqual(3, len(list(comp_group.components)))
-        comp_group = lp_bugtracker.getRemoteComponentGroup(u'beta')
+        comp_group = lp_bugtracker.getRemoteComponentGroup('beta')
         self.assertEqual(1, len(list(comp_group.components)))
-        comp = comp_group.getComponent(u'non-existant')
+        comp = comp_group.getComponent('non-existant')
         self.assertIs(None, comp)
-        comp = comp_group.getComponent(u'four')
-        self.assertEqual(u'four', comp.name)
+        comp = comp_group.getComponent('four')
+        self.assertEqual('four', comp.name)
 
     @responses.activate
     def test_get_remote_products_and_components(self):
@@ -169,12 +168,12 @@ class TestBugzillaRemoteComponentFinder(TestCaseWithFactory):
 
         self.assertEqual(
             109, len(list(lp_bugtracker.getAllRemoteComponentGroups())))
-        comp_group = lp_bugtracker.getRemoteComponentGroup(u'xorg')
+        comp_group = lp_bugtracker.getRemoteComponentGroup('xorg')
         self.assertIsNot(None, comp_group)
         self.assertEqual(146, len(list(comp_group.components)))
-        comp = comp_group.getComponent(u'Driver/Radeon')
+        comp = comp_group.getComponent('Driver/Radeon')
         self.assertIsNot(None, comp)
-        self.assertEqual(u'Driver/Radeon', comp.name)
+        self.assertEqual('Driver/Radeon', comp.name)
 
     @responses.activate
     def test_get_remote_products_and_components_encounters_301(self):
@@ -198,12 +197,12 @@ class TestBugzillaRemoteComponentFinder(TestCaseWithFactory):
 
         self.assertEqual(
             109, len(list(lp_bugtracker.getAllRemoteComponentGroups())))
-        comp_group = lp_bugtracker.getRemoteComponentGroup(u'xorg')
+        comp_group = lp_bugtracker.getRemoteComponentGroup('xorg')
         self.assertIsNot(None, comp_group)
         self.assertEqual(146, len(list(comp_group.components)))
-        comp = comp_group.getComponent(u'Driver/Radeon')
+        comp = comp_group.getComponent('Driver/Radeon')
         self.assertIsNot(None, comp)
-        self.assertEqual(u'Driver/Radeon', comp.name)
+        self.assertEqual('Driver/Radeon', comp.name)
 
     @responses.activate
     def test_get_remote_products_and_components_encounters_400(self):
diff --git a/lib/lp/bugs/tests/test_cve.py b/lib/lp/bugs/tests/test_cve.py
index e131bb5..90bffc7 100644
--- a/lib/lp/bugs/tests/test_cve.py
+++ b/lib/lp/bugs/tests/test_cve.py
@@ -23,7 +23,7 @@ class TestCveSet(TestCaseWithFactory):
 
     def setUp(self):
         """Create a few bugtasks and CVEs."""
-        super(TestCveSet, self).setUp()
+        super().setUp()
         self.distroseries = self.factory.makeDistroSeries()
         self.bugs = []
         self.cves = []
@@ -73,8 +73,8 @@ class TestCveSet(TestCaseWithFactory):
         cve_data = [cve for bug, cve in bug_cves]
         self.assertEqual(self.bugs, found_bugs)
         expected = [
-            u'CVE-2000-0001', u'CVE-2000-0002', u'CVE-2000-0003',
-            u'CVE-2000-0004']
+            'CVE-2000-0001', 'CVE-2000-0002', 'CVE-2000-0003',
+            'CVE-2000-0004']
         self.assertEqual(expected, cve_data)
 
     def test_getBugCveCount(self):
diff --git a/lib/lp/bugs/tests/test_doc.py b/lib/lp/bugs/tests/test_doc.py
index 78f8cbf..5e19017 100644
--- a/lib/lp/bugs/tests/test_doc.py
+++ b/lib/lp/bugs/tests/test_doc.py
@@ -132,7 +132,7 @@ def bugmessageSetUp(test):
 
 def enableDSPPickerSetUp(test):
     setUp(test)
-    ff = FeatureFixture({u'disclosure.dsp_picker.enabled': u'on'})
+    ff = FeatureFixture({'disclosure.dsp_picker.enabled': 'on'})
     ff.setUp()
     test.globs['dsp_picker_feature_fixture'] = ff
 
diff --git a/lib/lp/bugs/tests/test_duplicate_handling.py b/lib/lp/bugs/tests/test_duplicate_handling.py
index e989a0f..b70b624 100644
--- a/lib/lp/bugs/tests/test_duplicate_handling.py
+++ b/lib/lp/bugs/tests/test_duplicate_handling.py
@@ -19,7 +19,7 @@ class TestDuplicateAttributes(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestDuplicateAttributes, self).setUp(user='test@xxxxxxxxxxxxx')
+        super().setUp(user='test@xxxxxxxxxxxxx')
 
     def setDuplicateofDirectly(self, bug, duplicateof):
         """Helper method to set duplicateof directly."""
@@ -39,8 +39,7 @@ class TestMarkDuplicateValidation(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestMarkDuplicateValidation, self).setUp(
-            user='test@xxxxxxxxxxxxx')
+        super().setUp(user='test@xxxxxxxxxxxxx')
         self.bug = self.factory.makeBug()
         self.dupe_bug = self.factory.makeBug()
         self.dupe_bug.markAsDuplicate(self.bug)
@@ -55,7 +54,7 @@ class TestMarkDuplicateValidation(TestCaseWithFactory):
     def test_error_on_duplicate_to_duplicate(self):
         # Test that a bug cannot be marked a duplicate of
         # a bug that is already itself a duplicate.
-        msg = dedent(u"""
+        msg = dedent("""
             Bug %s is already a duplicate of bug %s. You
             can only mark a bug report as duplicate of one that
             isn't a duplicate itself.
@@ -66,7 +65,7 @@ class TestMarkDuplicateValidation(TestCaseWithFactory):
 
     def test_error_duplicate_to_itself(self):
         # Test that a bug cannot be marked its own duplicate
-        msg = html_escape(dedent(u"""
+        msg = html_escape(dedent("""
             You can't mark a bug as a duplicate of itself."""))
         self.assertDuplicateError(self.bug, self.bug, msg)
 
@@ -77,7 +76,7 @@ class TestMoveDuplicates(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestMoveDuplicates, self).setUp(user='test@xxxxxxxxxxxxx')
+        super().setUp(user='test@xxxxxxxxxxxxx')
 
     def test_duplicates_are_moved(self):
         # Confirm that a bug with two duplicates can be marked
diff --git a/lib/lp/bugs/tests/test_searchtasks_webservice.py b/lib/lp/bugs/tests/test_searchtasks_webservice.py
index 62133ca..c716271 100644
--- a/lib/lp/bugs/tests/test_searchtasks_webservice.py
+++ b/lib/lp/bugs/tests/test_searchtasks_webservice.py
@@ -19,7 +19,7 @@ class TestOmitTargetedParameter(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestOmitTargetedParameter, self).setUp()
+        super().setUp()
         self.owner = self.factory.makePerson()
         with person_logged_in(self.owner):
             self.distro = self.factory.makeDistribution(name='mebuntu')
@@ -47,7 +47,7 @@ class TestProductSearchTasks(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestProductSearchTasks, self).setUp()
+        super().setUp()
         self.owner = self.factory.makePerson()
         with person_logged_in(self.owner):
             self.product = self.factory.makeProduct()
@@ -104,7 +104,7 @@ class TestProductSearchTasks(TestCaseWithFactory):
             api_version='devel', order_by='date_created')
         self.assertEqual(400, response.status)
         self.assertRaisesWithContent(
-            ValueError, "Unrecognized order_by: %r" % u'date_created',
+            ValueError, "Unrecognized order_by: %r" % 'date_created',
             response.jsonBody)
 
     def test_search_incomplete_status_results(self):
@@ -129,17 +129,17 @@ class TestMaloneApplicationSearchTasks(TestCaseWithFactory):
     def test_global_search_by_tag(self):
         project1 = self.factory.makeProduct()
         project2 = self.factory.makeProduct()
-        bug1 = self.factory.makeBug(target=project1, tags=[u'foo'])
-        self.factory.makeBug(target=project1, tags=[u'bar'])
-        bug3 = self.factory.makeBug(target=project2, tags=[u'foo'])
-        self.factory.makeBug(target=project2, tags=[u'baz'])
+        bug1 = self.factory.makeBug(target=project1, tags=['foo'])
+        self.factory.makeBug(target=project1, tags=['bar'])
+        bug3 = self.factory.makeBug(target=project2, tags=['foo'])
+        self.factory.makeBug(target=project2, tags=['baz'])
         webservice = LaunchpadWebServiceCaller(
             "launchpad-library", "salgado-change-anything")
         response = webservice.named_get(
             "/bugs",
             "searchTasks",
             api_version="devel",
-            tags=u'foo').jsonBody()
+            tags='foo').jsonBody()
         self.assertEqual(2, response["total_size"])
         self.assertContentEqual(
             [bug1.id, bug3.id],
@@ -153,7 +153,7 @@ class TestGetBugData(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestGetBugData, self).setUp()
+        super().setUp()
         self.owner = self.factory.makePerson()
         with person_logged_in(self.owner):
             self.product = self.factory.makeProduct()
diff --git a/lib/lp/bugs/tests/test_structuralsubscription.py b/lib/lp/bugs/tests/test_structuralsubscription.py
index d67bba2..05464c9 100644
--- a/lib/lp/bugs/tests/test_structuralsubscription.py
+++ b/lib/lp/bugs/tests/test_structuralsubscription.py
@@ -51,7 +51,7 @@ class TestStructuralSubscription(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestStructuralSubscription, self).setUp()
+        super().setUp()
         self.product = self.factory.makeProduct()
         with person_logged_in(self.product.owner):
             self.subscription = self.product.addSubscription(
@@ -146,7 +146,7 @@ class FilteredStructuralSubscriptionTestBase:
         return self.factory.makeBugTask(target=self.target)
 
     def setUp(self):
-        super(FilteredStructuralSubscriptionTestBase, self).setUp()
+        super().setUp()
         self.ordinary_subscriber = self.factory.makePerson()
         login_person(self.ordinary_subscriber)
         self.target = self.makeTarget()
@@ -239,7 +239,7 @@ class FilteredStructuralSubscriptionTestBase:
         self.assertSubscribers([])
 
         # With any tag the subscription is found.
-        self.bug.tags = [u'foo']
+        self.bug.tags = ['foo']
         self.assertSubscribers([self.ordinary_subscriber])
 
     def test_getStructuralSubscribers_with_filter_exclude_any_tags(self):
@@ -252,7 +252,7 @@ class FilteredStructuralSubscriptionTestBase:
         self.assertSubscribers([self.ordinary_subscriber])
 
         # With any tag the subscription is not found.
-        self.bug.tags = [u'foo']
+        self.bug.tags = ['foo']
         self.assertSubscribers([])
 
     def test_getStructuralSubscribers_with_filter_for_any_tag(self):
@@ -260,14 +260,14 @@ class FilteredStructuralSubscriptionTestBase:
         # tags must be present, bugs with any of those tags are matched.
 
         # Looking for either the "foo" or the "bar" tag.
-        self.initial_filter.tags = [u'foo', u'bar']
+        self.initial_filter.tags = ['foo', 'bar']
         self.initial_filter.find_all_tags = False
 
         # Without either tag the subscription is not found.
         self.assertSubscribers([])
 
         # With either tag the subscription is found.
-        self.bug.tags = [u'bar', u'baz']
+        self.bug.tags = ['bar', 'baz']
         self.assertSubscribers([self.ordinary_subscriber])
 
     def test_getStructuralSubscribers_with_filter_for_all_tags(self):
@@ -275,18 +275,18 @@ class FilteredStructuralSubscriptionTestBase:
         # tags must be present, bugs with all of those tags are matched.
 
         # Looking for both the "foo" and the "bar" tag.
-        self.initial_filter.tags = [u'foo', u'bar']
+        self.initial_filter.tags = ['foo', 'bar']
         self.initial_filter.find_all_tags = True
 
         # Without either tag the subscription is not found.
         self.assertSubscribers([])
 
         # Without only one of the required tags the subscription is not found.
-        self.bug.tags = [u'foo']
+        self.bug.tags = ['foo']
         self.assertSubscribers([])
 
         # With both required tags the subscription is found.
-        self.bug.tags = [u'foo', u'bar']
+        self.bug.tags = ['foo', 'bar']
         self.assertSubscribers([self.ordinary_subscriber])
 
     def test_getStructuralSubscribers_with_filter_for_not_any_tag(self):
@@ -295,18 +295,18 @@ class FilteredStructuralSubscriptionTestBase:
         # matched.
 
         # Looking to exclude the "foo" or "bar" tags.
-        self.initial_filter.tags = [u"-foo", u"-bar"]
+        self.initial_filter.tags = ["-foo", "-bar"]
         self.initial_filter.find_all_tags = False
 
         # Without either tag the subscription is found.
         self.assertSubscribers([self.ordinary_subscriber])
 
         # With both tags, the subscription is omitted.
-        self.bug.tags = [u'foo', u'bar']
+        self.bug.tags = ['foo', 'bar']
         self.assertSubscribers([])
 
         # With only one tag, the subscription is found again.
-        self.bug.tags = [u'foo']
+        self.bug.tags = ['foo']
         self.assertSubscribers([self.ordinary_subscriber])
 
         # However, if find_all_tags is True, even a single excluded tag
@@ -315,7 +315,7 @@ class FilteredStructuralSubscriptionTestBase:
         self.assertSubscribers([])
 
         # This is also true, of course, if the bug has both tags.
-        self.bug.tags = [u'foo', u'bar']
+        self.bug.tags = ['foo', 'bar']
         self.assertSubscribers([])
 
     def test_getStructuralSubscribers_with_filter_for_not_all_tags(self):
@@ -324,7 +324,7 @@ class FilteredStructuralSubscriptionTestBase:
         # matched.
 
         # Looking to exclude the "foo" and "bar" tags.
-        self.initial_filter.tags = [u'-foo', u'-bar']
+        self.initial_filter.tags = ['-foo', '-bar']
         self.initial_filter.find_all_tags = True
 
         # Without either tag the subscription is found.
@@ -333,11 +333,11 @@ class FilteredStructuralSubscriptionTestBase:
         # With only one of the excluded tags the subscription is not
         # found--we are saying that we want to find both an absence of foo
         # and an absence of bar, and yet foo exists.
-        self.bug.tags = [u'foo']
+        self.bug.tags = ['foo']
         self.assertSubscribers([])
 
         # With both tags the subscription is also not found.
-        self.bug.tags = [u'foo', u'bar']
+        self.bug.tags = ['foo', 'bar']
         self.assertSubscribers([])
 
     def test_getStructuralSubscribers_with_multiple_filters(self):
@@ -345,7 +345,7 @@ class FilteredStructuralSubscriptionTestBase:
         # match.
 
         # Add the "foo" tag to the bug.
-        self.bug.tags = [u'foo']
+        self.bug.tags = ['foo']
         self.assertSubscribers([self.ordinary_subscriber])
 
         # Filter the subscription to bugs in the CRITICAL state.
@@ -367,13 +367,13 @@ class FilteredStructuralSubscriptionTestBase:
 
         # If the filter is given some tag criteria, the subscription is not
         # found.
-        self.initial_filter.tags = [u'-foo', u'bar', u'baz']
+        self.initial_filter.tags = ['-foo', 'bar', 'baz']
         self.initial_filter.find_all_tags = False
         self.assertSubscribers([])
 
         # After removing the "foo" tag and adding the "bar" tag, the
         # subscription is found.
-        self.bug.tags = [u'bar']
+        self.bug.tags = ['bar']
         self.assertSubscribers([self.ordinary_subscriber])
 
         # Requiring that all tag criteria are fulfilled causes the
@@ -382,7 +382,7 @@ class FilteredStructuralSubscriptionTestBase:
         self.assertSubscribers([])
 
         # After adding the "baz" tag, the subscription is found again.
-        self.bug.tags = [u'bar', u'baz']
+        self.bug.tags = ['bar', 'baz']
         self.assertSubscribers([self.ordinary_subscriber])
 
     def test_getStructuralSubscribers_any_filter_is_a_match(self):
@@ -392,7 +392,7 @@ class FilteredStructuralSubscriptionTestBase:
         subscription_filter1 = self.initial_filter
         subscription_filter1.statuses = [BugTaskStatus.CONFIRMED]
         subscription_filter2 = self.subscription.newBugFilter()
-        subscription_filter2.tags = [u'foo']
+        subscription_filter2.tags = ['foo']
 
         # With the filter the subscription is not found.
         self.assertSubscribers([])
@@ -405,7 +405,7 @@ class FilteredStructuralSubscriptionTestBase:
 
         # If the filter is adjusted to also match the criteria of the second
         # filter, the subscription is still found.
-        self.bugtask.bug.tags = [u'foo']
+        self.bugtask.bug.tags = ['foo']
         self.assertSubscribers([self.ordinary_subscriber])
 
         # If the bugtask is adjusted to no longer match the criteria of the
@@ -550,7 +550,7 @@ class TestGetStructuralSubscriptionsForBug(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestGetStructuralSubscriptionsForBug, self).setUp()
+        super().setUp()
         self.subscriber = self.factory.makePerson()
         self.team = self.factory.makeTeam(members=[self.subscriber])
         login_person(self.subscriber)
@@ -800,9 +800,9 @@ class TestGetStructuralSubscribers(TestCaseWithFactory):
         reason, header = recipients.getReason(subscriber)
         self.assertThat(
             reason, StartsWith(
-                u"You received this bug notification because "
-                u"you are subscribed to "))
-        self.assertThat(header, StartsWith(u"Subscriber "))
+                "You received this bug notification because "
+                "you are subscribed to "))
+        self.assertThat(header, StartsWith("Subscriber "))
 
     def test_getStructuralSubscribers_level(self):
         # get_structural_subscribers() respects the given level.
@@ -829,7 +829,7 @@ class TestBugSubscriptionFilterMute(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestBugSubscriptionFilterMute, self).setUp()
+        super().setUp()
         self.target = self.factory.makeProduct()
         self.team = self.factory.makeTeam()
         self.team_member = self.factory.makePerson()
diff --git a/lib/lp/bugs/tests/test_structuralsubscriptiontarget.py b/lib/lp/bugs/tests/test_structuralsubscriptiontarget.py
index 696d7c5..0a6f5fb 100644
--- a/lib/lp/bugs/tests/test_structuralsubscriptiontarget.py
+++ b/lib/lp/bugs/tests/test_structuralsubscriptiontarget.py
@@ -59,7 +59,7 @@ class RestrictedStructuralSubscriptionTestBase:
     """Tests suitable for a target that restricts structural subscriptions."""
 
     def setUp(self):
-        super(RestrictedStructuralSubscriptionTestBase, self).setUp()
+        super().setUp()
         self.ordinary_subscriber = self.factory.makePerson()
         self.bug_supervisor_subscriber = self.factory.makePerson()
         self.team_owner = self.factory.makePerson()
@@ -177,7 +177,7 @@ class TestStructuralSubscriptionForDistro(
     layer = LaunchpadFunctionalLayer
 
     def setUp(self):
-        super(TestStructuralSubscriptionForDistro, self).setUp()
+        super().setUp()
         self.target = self.factory.makeDistribution()
         naked_distro = removeSecurityProxy(self.target)
         naked_distro.bug_supervisor = self.bug_supervisor_subscriber
@@ -241,7 +241,7 @@ class TestStructuralSubscriptionForProduct(
     layer = LaunchpadFunctionalLayer
 
     def setUp(self):
-        super(TestStructuralSubscriptionForProduct, self).setUp()
+        super().setUp()
         self.target = self.factory.makeProduct()
 
 
@@ -251,7 +251,7 @@ class TestStructuralSubscriptionForDistroSourcePackage(
     layer = LaunchpadFunctionalLayer
 
     def setUp(self):
-        super(TestStructuralSubscriptionForDistroSourcePackage, self).setUp()
+        super().setUp()
         self.target = self.factory.makeDistributionSourcePackage()
         self.target = ProxyFactory(self.target)
 
@@ -262,7 +262,7 @@ class TestStructuralSubscriptionForMilestone(
     layer = LaunchpadFunctionalLayer
 
     def setUp(self):
-        super(TestStructuralSubscriptionForMilestone, self).setUp()
+        super().setUp()
         self.target = self.factory.makeMilestone()
         self.target = ProxyFactory(self.target)
 
@@ -273,7 +273,7 @@ class TestStructuralSubscriptionForDistroSeries(
     layer = LaunchpadFunctionalLayer
 
     def setUp(self):
-        super(TestStructuralSubscriptionForDistroSeries, self).setUp()
+        super().setUp()
         self.target = self.factory.makeDistroSeries()
         self.target = ProxyFactory(self.target)
 
@@ -284,7 +284,7 @@ class TestStructuralSubscriptionForProjectGroup(
     layer = LaunchpadFunctionalLayer
 
     def setUp(self):
-        super(TestStructuralSubscriptionForProjectGroup, self).setUp()
+        super().setUp()
         self.target = self.factory.makeProject()
         self.target = ProxyFactory(self.target)
 
@@ -295,7 +295,7 @@ class TestStructuralSubscriptionForProductSeries(
     layer = LaunchpadFunctionalLayer
 
     def setUp(self):
-        super(TestStructuralSubscriptionForProductSeries, self).setUp()
+        super().setUp()
         self.target = self.factory.makeProductSeries()
         self.target = ProxyFactory(self.target)
 
@@ -306,7 +306,7 @@ class TestStructuralSubscriptionTargetHelper(TestCaseWithFactory):
     layer = LaunchpadZopelessLayer
 
     def setUp(self):
-        super(TestStructuralSubscriptionTargetHelper, self).setUp()
+        super().setUp()
         self.person = self.factory.makePerson()
         login_person(self.person)
 
@@ -320,7 +320,7 @@ class TestStructuralSubscriptionTargetHelper(TestCaseWithFactory):
         self.assertEqual({"distroseries": target}, helper.target_arguments)
         self.assertEqual(target.distribution, helper.pillar)
         self.assertEqual(
-            u"StructuralSubscription.distroseries = ?",
+            "StructuralSubscription.distroseries = ?",
             compile_storm(helper.join))
 
     def test_project_group(self):
@@ -333,7 +333,7 @@ class TestStructuralSubscriptionTargetHelper(TestCaseWithFactory):
         self.assertEqual(target, helper.pillar)
         self.assertEqual({"projectgroup": target}, helper.target_arguments)
         self.assertEqual(
-            u"StructuralSubscription.project = ?",
+            "StructuralSubscription.project = ?",
             compile_storm(helper.join))
 
     def test_distribution_source_package(self):
@@ -351,8 +351,8 @@ class TestStructuralSubscriptionTargetHelper(TestCaseWithFactory):
              "sourcepackagename": target.sourcepackagename},
             helper.target_arguments)
         self.assertEqual(
-            u"StructuralSubscription.distribution = ? AND "
-            u"StructuralSubscription.sourcepackagename = ?",
+            "StructuralSubscription.distribution = ? AND "
+            "StructuralSubscription.sourcepackagename = ?",
             compile_storm(helper.join))
 
     def test_milestone(self):
@@ -367,7 +367,7 @@ class TestStructuralSubscriptionTargetHelper(TestCaseWithFactory):
         self.assertEqual(target.target, helper.pillar)
         self.assertEqual({"milestone": target}, helper.target_arguments)
         self.assertEqual(
-            u"StructuralSubscription.milestone = ?",
+            "StructuralSubscription.milestone = ?",
             compile_storm(helper.join))
 
     def test_product(self):
@@ -380,7 +380,7 @@ class TestStructuralSubscriptionTargetHelper(TestCaseWithFactory):
         self.assertEqual(target, helper.pillar)
         self.assertEqual({"product": target}, helper.target_arguments)
         self.assertEqual(
-            u"StructuralSubscription.product = ?",
+            "StructuralSubscription.product = ?",
             compile_storm(helper.join))
 
     def test_product_in_group(self):
@@ -394,7 +394,7 @@ class TestStructuralSubscriptionTargetHelper(TestCaseWithFactory):
         self.assertEqual(target, helper.pillar)
         self.assertEqual({"product": target}, helper.target_arguments)
         self.assertEqual(
-            u"StructuralSubscription.product = ? OR "
+            "StructuralSubscription.product = ? OR "
             "StructuralSubscription.project = ?",
             compile_storm(helper.join))
 
@@ -410,7 +410,7 @@ class TestStructuralSubscriptionTargetHelper(TestCaseWithFactory):
         self.assertEqual(target.product, helper.pillar)
         self.assertEqual({"productseries": target}, helper.target_arguments)
         self.assertEqual(
-            u"StructuralSubscription.productseries = ?",
+            "StructuralSubscription.productseries = ?",
             compile_storm(helper.join))
 
     def test_distribution(self):
@@ -426,8 +426,8 @@ class TestStructuralSubscriptionTargetHelper(TestCaseWithFactory):
              "sourcepackagename": None},
             helper.target_arguments)
         self.assertEqual(
-            u"StructuralSubscription.distribution = ? AND "
-            u"StructuralSubscription.sourcepackagename IS NULL",
+            "StructuralSubscription.distribution = ? AND "
+            "StructuralSubscription.sourcepackagename IS NULL",
             compile_storm(helper.join))
 
 
@@ -436,7 +436,7 @@ class TestGetAllStructuralSubscriptionsForTarget(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
-        super(TestGetAllStructuralSubscriptionsForTarget, self).setUp()
+        super().setUp()
         self.subscriber = self.factory.makePerson()
         self.team = self.factory.makeTeam(members=[self.subscriber])
         login_person(self.subscriber)
diff --git a/lib/lp/bugs/vocabularies.py b/lib/lp/bugs/vocabularies.py
index b4e5f2d..7faa6fc 100644
--- a/lib/lp/bugs/vocabularies.py
+++ b/lib/lp/bugs/vocabularies.py
@@ -88,7 +88,7 @@ class UsesBugsDistributionVocabulary(DistributionVocabulary):
     """
 
     def __init__(self, context=None):
-        super(UsesBugsDistributionVocabulary, self).__init__(context=context)
+        super().__init__(context=context)
         self.distribution = IDistribution(self.context, None)
 
     @property