Merge ~cjwatson/launchpad:pyupgrade-py3-code into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 303156e5913eecfffd1c7307ba219ec3f6442b90
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:pyupgrade-py3-code
Merge into: launchpad:master
Diff against target: 3920 lines (+422/-478)
87 files modified
.git-blame-ignore-revs (+2/-0)
.pre-commit-config.yaml (+1/-1)
lib/lp/code/adapters/tests/test_gitrepository.py (+7/-7)
lib/lp/code/errors.py (+10/-14)
lib/lp/code/event/git.py (+1/-1)
lib/lp/code/feed/branch.py (+3/-3)
lib/lp/code/interfaces/branch.py (+5/-5)
lib/lp/code/interfaces/branchjob.py (+4/-4)
lib/lp/code/interfaces/codeimport.py (+1/-1)
lib/lp/code/interfaces/gitrepository.py (+1/-1)
lib/lp/code/interfaces/sourcepackagerecipe.py (+2/-2)
lib/lp/code/mail/branch.py (+3/-4)
lib/lp/code/mail/sourcepackagerecipebuild.py (+2/-5)
lib/lp/code/mail/tests/test_branch.py (+1/-1)
lib/lp/code/mail/tests/test_branchmergeproposal.py (+1/-1)
lib/lp/code/mail/tests/test_codehandler.py (+7/-9)
lib/lp/code/mail/tests/test_codeimport.py (+1/-1)
lib/lp/code/mail/tests/test_sourcepackagerecipebuild.py (+9/-9)
lib/lp/code/model/branch.py (+2/-2)
lib/lp/code/model/branchcollection.py (+2/-2)
lib/lp/code/model/branchhosting.py (+1/-4)
lib/lp/code/model/branchjob.py (+5/-5)
lib/lp/code/model/branchmergeproposal.py (+6/-11)
lib/lp/code/model/branchmergeproposaljob.py (+1/-1)
lib/lp/code/model/branchsubscription.py (+1/-1)
lib/lp/code/model/branchtarget.py (+1/-1)
lib/lp/code/model/codeimport.py (+1/-1)
lib/lp/code/model/codeimportevent.py (+10/-12)
lib/lp/code/model/codeimportjob.py (+2/-2)
lib/lp/code/model/codeimportmachine.py (+2/-2)
lib/lp/code/model/codeimportresult.py (+2/-2)
lib/lp/code/model/codereviewinlinecomment.py (+1/-2)
lib/lp/code/model/diff.py (+8/-8)
lib/lp/code/model/gitactivity.py (+1/-1)
lib/lp/code/model/gitcollection.py (+1/-1)
lib/lp/code/model/githosting.py (+16/-31)
lib/lp/code/model/gitjob.py (+2/-2)
lib/lp/code/model/gitlookup.py (+3/-5)
lib/lp/code/model/gitref.py (+5/-5)
lib/lp/code/model/gitrepository.py (+9/-11)
lib/lp/code/model/gitrule.py (+1/-1)
lib/lp/code/model/gitsubscription.py (+1/-1)
lib/lp/code/model/recipebuilder.py (+1/-2)
lib/lp/code/model/revision.py (+2/-2)
lib/lp/code/model/sourcepackagerecipebuild.py (+1/-1)
lib/lp/code/model/sourcepackagerecipedata.py (+3/-3)
lib/lp/code/model/tests/test_branch.py (+6/-6)
lib/lp/code/model/tests/test_branchcollection.py (+1/-1)
lib/lp/code/model/tests/test_branchhosting.py (+6/-7)
lib/lp/code/model/tests/test_branchjob.py (+1/-1)
lib/lp/code/model/tests/test_branchlistingqueryoptimiser.py (+2/-4)
lib/lp/code/model/tests/test_branchmergeproposal.py (+7/-8)
lib/lp/code/model/tests/test_branchmergeproposaljobs.py (+1/-2)
lib/lp/code/model/tests/test_branchnamespace.py (+2/-3)
lib/lp/code/model/tests/test_codeimport.py (+7/-8)
lib/lp/code/model/tests/test_codeimportjob.py (+13/-13)
lib/lp/code/model/tests/test_codeimportmachine.py (+1/-2)
lib/lp/code/model/tests/test_codereviewkarma.py (+1/-1)
lib/lp/code/model/tests/test_gitcollection.py (+1/-1)
lib/lp/code/model/tests/test_githosting.py (+7/-8)
lib/lp/code/model/tests/test_gitlookup.py (+5/-5)
lib/lp/code/model/tests/test_gitnamespace.py (+3/-5)
lib/lp/code/model/tests/test_gitref.py (+2/-2)
lib/lp/code/model/tests/test_gitrepository.py (+13/-14)
lib/lp/code/model/tests/test_revision.py (+1/-1)
lib/lp/code/model/tests/test_revisionauthor.py (+9/-9)
lib/lp/code/model/tests/test_sourcepackagerecipe.py (+1/-1)
lib/lp/code/scripts/repackgitrepository.py (+2/-3)
lib/lp/code/scripts/tests/test_repack_git_repositories.py (+2/-2)
lib/lp/code/scripts/tests/test_request_daily_builds.py (+3/-3)
lib/lp/code/tests/helpers.py (+1/-2)
lib/lp/code/tests/test_branch.py (+1/-1)
lib/lp/code/tests/test_branch_webservice.py (+1/-1)
lib/lp/code/tests/test_bzr.py (+4/-5)
lib/lp/code/tests/test_directbranchcommit.py (+2/-2)
lib/lp/code/tests/test_project.py (+1/-1)
lib/lp/code/vocabularies/branch.py (+2/-2)
lib/lp/code/vocabularies/gitref.py (+2/-2)
lib/lp/code/vocabularies/gitrepository.py (+1/-2)
lib/lp/code/vocabularies/gitrule.py (+1/-1)
lib/lp/code/vocabularies/tests/test_branch_vocabularies.py (+4/-5)
lib/lp/code/vocabularies/tests/test_gitrepository_vocabularies.py (+11/-11)
lib/lp/code/xmlrpc/codehosting.py (+1/-1)
lib/lp/code/xmlrpc/git.py (+5/-5)
lib/lp/code/xmlrpc/tests/test_branch.py (+3/-3)
lib/lp/code/xmlrpc/tests/test_codehosting.py (+44/-44)
lib/lp/code/xmlrpc/tests/test_git.py (+89/-89)
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+413331@code.launchpad.net

Commit message

lp.code: Apply "pyupgrade --py3-plus"

To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) wrote :

Self-approving (mechanical).

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
2index 91cb020..4691daf 100644
3--- a/.git-blame-ignore-revs
4+++ b/.git-blame-ignore-revs
5@@ -22,3 +22,5 @@ b6725842a2470e3927bb73bf400c4476a06ee3ba
6 474f07ab7c3f28d8b6b8e4f1bd4c56832cec3fab
7 # apply pyupgrade --py3-plus to lp.code.browser
8 47ee1259461aa54ad7ee967e85f6131be2b74125
9+# apply pyupgrade --py3-plus to lp.code
10+cee9b128d3e49ca814464eeeeec50e6bcabcc4ba
11diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
12index 47ab095..d82d7fe 100644
13--- a/.pre-commit-config.yaml
14+++ b/.pre-commit-config.yaml
15@@ -48,7 +48,7 @@ repos:
16 |bugs
17 |buildmaster
18 |charms
19- |code/browser
20+ |code
21 )/
22 - repo: https://github.com/PyCQA/isort
23 rev: 5.9.2
24diff --git a/lib/lp/code/adapters/tests/test_gitrepository.py b/lib/lp/code/adapters/tests/test_gitrepository.py
25index 5363a15..9983274 100644
26--- a/lib/lp/code/adapters/tests/test_gitrepository.py
27+++ b/lib/lp/code/adapters/tests/test_gitrepository.py
28@@ -19,7 +19,7 @@ class TestGitRepositoryDelta(TestCaseWithFactory):
29
30 def test_no_modification(self):
31 # If there are no modifications, no delta is returned.
32- repository = self.factory.makeGitRepository(name=u"foo")
33+ repository = self.factory.makeGitRepository(name="foo")
34 old_repository = Snapshot(repository, providing=providedBy(repository))
35 delta = GitRepositoryDelta.construct(
36 old_repository, repository, repository.owner)
37@@ -30,18 +30,18 @@ class TestGitRepositoryDelta(TestCaseWithFactory):
38 owner = self.factory.makePerson(name="person")
39 project = self.factory.makeProduct(name="project")
40 repository = self.factory.makeGitRepository(
41- owner=owner, target=project, name=u"foo")
42+ owner=owner, target=project, name="foo")
43 old_repository = Snapshot(repository, providing=providedBy(repository))
44 with person_logged_in(repository.owner):
45- repository.setName(u"bar", repository.owner)
46+ repository.setName("bar", repository.owner)
47 delta = GitRepositoryDelta.construct(old_repository, repository, owner)
48 self.assertIsNotNone(delta)
49 self.assertThat(delta, MatchesStructure.byEquality(
50 name={
51- "old": u"foo",
52- "new": u"bar",
53+ "old": "foo",
54+ "new": "bar",
55 },
56 git_identity={
57- "old": u"lp:~person/project/+git/foo",
58- "new": u"lp:~person/project/+git/bar",
59+ "old": "lp:~person/project/+git/foo",
60+ "new": "lp:~person/project/+git/bar",
61 }))
62diff --git a/lib/lp/code/errors.py b/lib/lp/code/errors.py
63index 885662e..a4dc375 100644
64--- a/lib/lp/code/errors.py
65+++ b/lib/lp/code/errors.py
66@@ -70,7 +70,6 @@ import http.client
67
68 from breezy.plugins.builder.recipe import RecipeParseError
69 from lazr.restful.declarations import error_status
70-import six
71
72 from lp.app.errors import (
73 NameLookupFailed,
74@@ -203,8 +202,7 @@ class CannotUpgradeBranch(Exception):
75 """"Made for subclassing."""
76
77 def __init__(self, branch):
78- super(CannotUpgradeBranch, self).__init__(
79- self._msg_template % branch.bzr_identity)
80+ super().__init__(self._msg_template % branch.bzr_identity)
81 self.branch = branch
82
83
84@@ -254,7 +252,7 @@ class BranchMergeProposalExists(InvalidBranchMergeProposal):
85 display_name = "displayname"
86 else:
87 display_name = "display_name"
88- super(BranchMergeProposalExists, self).__init__(
89+ super().__init__(
90 'There is already a branch merge proposal registered for '
91 'branch %s to land on %s that is still active.' %
92 (getattr(existing_proposal.merge_source, display_name),
93@@ -363,7 +361,7 @@ class BranchFileNotFound(BranchHostingFault):
94 """Raised when a file does not exist in a branch."""
95
96 def __init__(self, branch_id, filename=None, file_id=None, rev=None):
97- super(BranchFileNotFound, self).__init__()
98+ super().__init__()
99 if (filename is None) == (file_id is None):
100 raise AssertionError(
101 "Exactly one of filename and file_id must be given.")
102@@ -416,7 +414,6 @@ class GitRepositoryCreationForbidden(GitRepositoryCreationException):
103 """
104
105
106-@six.python_2_unicode_compatible
107 @error_status(http.client.BAD_REQUEST)
108 class GitRepositoryCreatorNotMemberOfOwnerTeam(GitRepositoryCreationException):
109 """Git repository creator is not a member of the owner team.
110@@ -435,7 +432,6 @@ class GitRepositoryCreatorNotMemberOfOwnerTeam(GitRepositoryCreationException):
111 return message
112
113
114-@six.python_2_unicode_compatible
115 @error_status(http.client.BAD_REQUEST)
116 class GitRepositoryCreatorNotOwner(GitRepositoryCreationException):
117 """A user cannot create a Git repository belonging to another user.
118@@ -458,7 +454,7 @@ class GitRepositoryCreationFault(Exception):
119 """Raised when there is a hosting fault creating a Git repository."""
120
121 def __init__(self, message, path):
122- super(GitRepositoryCreationFault, self).__init__(message)
123+ super().__init__(message)
124 self.path = path
125
126
127@@ -470,7 +466,7 @@ class GitRepositoryBlobNotFound(GitRepositoryScanFault):
128 """Raised when a blob does not exist in a repository."""
129
130 def __init__(self, path, filename, rev=None):
131- super(GitRepositoryBlobNotFound, self).__init__()
132+ super().__init__()
133 self.path = path
134 self.filename = filename
135 self.rev = rev
136@@ -486,7 +482,7 @@ class GitRepositoryBlobUnsupportedRemote(Exception):
137 """Raised when trying to fetch a blob from an unsupported remote host."""
138
139 def __init__(self, repository_url):
140- super(GitRepositoryBlobUnsupportedRemote, self).__init__()
141+ super().__init__()
142 self.repository_url = repository_url
143
144 def __str__(self):
145@@ -565,7 +561,7 @@ class CannotModifyNonHostedGitRepository(Exception):
146 """Raised when trying to modify a non-hosted Git repository."""
147
148 def __init__(self, repository):
149- super(CannotModifyNonHostedGitRepository, self).__init__(
150+ super().__init__(
151 "Cannot modify non-hosted Git repository %s." %
152 repository.display_name)
153
154@@ -579,7 +575,7 @@ class CodeImportAlreadyRequested(Exception):
155 """Raised when the user requests an import that is already requested."""
156
157 def __init__(self, msg, requesting_user):
158- super(CodeImportAlreadyRequested, self).__init__(msg)
159+ super().__init__(msg)
160 self.requesting_user = requesting_user
161
162
163@@ -593,7 +589,7 @@ class CodeImportInvalidTargetType(Exception):
164 """Raised for code imports with an invalid target for their type."""
165
166 def __init__(self, target, target_rcs_type):
167- super(CodeImportInvalidTargetType, self).__init__(
168+ super().__init__(
169 "Objects of type %s do not support code imports targeting %s." %
170 (target.__class__.__name__, target_rcs_type))
171
172@@ -603,7 +599,7 @@ class TooNewRecipeFormat(Exception):
173 """The format of the recipe supplied was too new."""
174
175 def __init__(self, supplied_format, newest_supported):
176- super(TooNewRecipeFormat, self).__init__()
177+ super().__init__()
178 self.supplied_format = supplied_format
179 self.newest_supported = newest_supported
180
181diff --git a/lib/lp/code/event/git.py b/lib/lp/code/event/git.py
182index bc89694..317c687 100644
183--- a/lib/lp/code/event/git.py
184+++ b/lib/lp/code/event/git.py
185@@ -18,6 +18,6 @@ class GitRefsUpdatedEvent(ObjectEvent):
186 """See `IGitRefsUpdatedEvent`."""
187
188 def __init__(self, repository, paths, logger):
189- super(GitRefsUpdatedEvent, self).__init__(repository)
190+ super().__init__(repository)
191 self.paths = paths
192 self.logger = logger
193diff --git a/lib/lp/code/feed/branch.py b/lib/lp/code/feed/branch.py
194index 3339134..27d2047 100644
195--- a/lib/lp/code/feed/branch.py
196+++ b/lib/lp/code/feed/branch.py
197@@ -67,7 +67,7 @@ class BranchFeedContentView(BranchView):
198
199 def __init__(self, context, request, feed,
200 template='templates/branch.pt'):
201- super(BranchFeedContentView, self).__init__(context, request)
202+ super().__init__(context, request)
203 self.feed = feed
204 self.template_ = template
205
206@@ -196,7 +196,7 @@ class RevisionFeedContentView(LaunchpadView):
207 """View for a revision feed contents."""
208
209 def __init__(self, context, request, feed):
210- super(RevisionFeedContentView, self).__init__(context, request)
211+ super().__init__(context, request)
212 self.feed = feed
213
214 @cachedproperty
215@@ -391,7 +391,7 @@ class BranchFeed(BranchFeedBase):
216 def initialize(self):
217 """See `IFeed`."""
218 # For a `BranchFeed` we must ensure that the branch is not private.
219- super(BranchFeed, self).initialize()
220+ super().initialize()
221 try:
222 feed_allowed = not self.context.private
223 if not feed_allowed:
224diff --git a/lib/lp/code/interfaces/branch.py b/lib/lp/code/interfaces/branch.py
225index e6d4e14..57d63e4 100644
226--- a/lib/lp/code/interfaces/branch.py
227+++ b/lib/lp/code/interfaces/branch.py
228@@ -281,7 +281,7 @@ class IBranchView(IHasOwner, IHasBranchTarget, IHasMergeProposals,
229 id = Int(title=_('ID'), readonly=True, required=True)
230
231 @operation_parameters(
232- scheme=TextLine(title=_("URL scheme"), default=u'http'))
233+ scheme=TextLine(title=_("URL scheme"), default='http'))
234 @export_read_operation()
235 @operation_for_version('beta')
236 def composePublicURL(scheme='http'):
237@@ -1376,11 +1376,11 @@ class IBranchSet(Interface):
238
239 @operation_parameters(
240 urls=List(
241- title=u'A list of URLs of branches',
242+ title='A list of URLs of branches',
243 description=(
244- u'These can be URLs external to '
245- u'Launchpad, lp: URLs, or http://bazaar.launchpad.net/ URLs, '
246- u'or any mix of all these different kinds.'),
247+ 'These can be URLs external to '
248+ 'Launchpad, lp: URLs, or http://bazaar.launchpad.net/ URLs, '
249+ 'or any mix of all these different kinds.'),
250 value_type=TextLine(),
251 required=True))
252 @export_read_operation()
253diff --git a/lib/lp/code/interfaces/branchjob.py b/lib/lp/code/interfaces/branchjob.py
254index 6ab861e..4f14416 100644
255--- a/lib/lp/code/interfaces/branchjob.py
256+++ b/lib/lp/code/interfaces/branchjob.py
257@@ -91,13 +91,13 @@ class IBranchUpgradeJobSource(IJobSource):
258 class IRevisionMailJob(IRunnableJob):
259 """A Job to send email a revision change in a branch."""
260
261- revno = Int(title=u'The revno to send mail about.')
262+ revno = Int(title='The revno to send mail about.')
263
264- from_address = Bytes(title=u'The address to send mail from.')
265+ from_address = Bytes(title='The address to send mail from.')
266
267- body = Text(title=u'The main text of the email to send.')
268+ body = Text(title='The main text of the email to send.')
269
270- subject = Text(title=u'The subject of the email to send.')
271+ subject = Text(title='The subject of the email to send.')
272
273
274 class IRevisionMailJobSource(IJobSource):
275diff --git a/lib/lp/code/interfaces/codeimport.py b/lib/lp/code/interfaces/codeimport.py
276index 7799e90..1a3e5a1 100644
277--- a/lib/lp/code/interfaces/codeimport.py
278+++ b/lib/lp/code/interfaces/codeimport.py
279@@ -55,7 +55,7 @@ class CVSRootError(Exception):
280 """Raised when trying to use a CVSROOT with invalid syntax."""
281
282 def __init__(self, root):
283- super(CVSRootError, self).__init__(self, 'bad CVSROOT: %r' % root)
284+ super().__init__(self, 'bad CVSROOT: %r' % root)
285
286
287 _cvs_root_parser = re.compile(r"""
288diff --git a/lib/lp/code/interfaces/gitrepository.py b/lib/lp/code/interfaces/gitrepository.py
289index aae1b90..d2d6a90 100644
290--- a/lib/lp/code/interfaces/gitrepository.py
291+++ b/lib/lp/code/interfaces/gitrepository.py
292@@ -832,7 +832,7 @@ class RevisionStatusReportsFeatureDisabled(Unauthorized):
293 """Only certain users can access APIs for revision status reports."""
294
295 def __init__(self):
296- super(RevisionStatusReportsFeatureDisabled, self).__init__(
297+ super().__init__(
298 "You do not have permission to create revision status reports")
299
300
301diff --git a/lib/lp/code/interfaces/sourcepackagerecipe.py b/lib/lp/code/interfaces/sourcepackagerecipe.py
302index f954618..af05f7b 100644
303--- a/lib/lp/code/interfaces/sourcepackagerecipe.py
304+++ b/lib/lp/code/interfaces/sourcepackagerecipe.py
305@@ -69,13 +69,13 @@ from lp.services.fields import (
306 from lp.soyuz.interfaces.archive import IArchive
307
308
309-MINIMAL_RECIPE_TEXT_BZR = dedent(u'''\
310+MINIMAL_RECIPE_TEXT_BZR = dedent('''\
311 # bzr-builder format 0.3 deb-version {debupstream}-0~{revno}
312 %s
313 ''')
314
315
316-MINIMAL_RECIPE_TEXT_GIT = dedent(u'''\
317+MINIMAL_RECIPE_TEXT_GIT = dedent('''\
318 # git-build-recipe format 0.4 deb-version {debupstream}-0~{revtime}
319 %s %s
320 ''')
321diff --git a/lib/lp/code/mail/branch.py b/lib/lp/code/mail/branch.py
322index c36a8b7..5de23f2 100644
323--- a/lib/lp/code/mail/branch.py
324+++ b/lib/lp/code/mail/branch.py
325@@ -58,8 +58,7 @@ class RecipientReason(basemailer.RecipientReason):
326 max_diff_lines=BranchSubscriptionDiffSize.WHOLEDIFF,
327 branch_identity_cache=None,
328 review_level=CodeReviewNotificationLevel.FULL):
329- super(RecipientReason, self).__init__(subscriber, recipient,
330- mail_header, reason_template)
331+ super().__init__(subscriber, recipient, mail_header, reason_template)
332 self.branch = branch
333 self.merge_proposal = merge_proposal
334 self.max_diff_lines = max_diff_lines
335@@ -150,7 +149,7 @@ class RecipientReason(basemailer.RecipientReason):
336 branch_identity_cache=branch_identity_cache)
337
338 def _getTemplateValues(self):
339- template_values = super(RecipientReason, self)._getTemplateValues()
340+ template_values = super()._getTemplateValues()
341 template_values['branch_name'] = self._getBranchIdentity(self.branch)
342 if self.merge_proposal is not None:
343 source = self._getBranchIdentity(self.merge_proposal.merge_source)
344@@ -169,7 +168,7 @@ class BranchMailer(BaseMailer):
345 delta=None, delta_for_editors=None, contents=None, diff=None,
346 message_id=None, revno=None, revision_id=None,
347 notification_type=None, **kwargs):
348- super(BranchMailer, self).__init__(
349+ super().__init__(
350 subject, template_name, recipients, from_address,
351 message_id=message_id, notification_type=notification_type)
352 self.delta_text = delta
353diff --git a/lib/lp/code/mail/sourcepackagerecipebuild.py b/lib/lp/code/mail/sourcepackagerecipebuild.py
354index 5b81714..a12452e 100644
355--- a/lib/lp/code/mail/sourcepackagerecipebuild.py
356+++ b/lib/lp/code/mail/sourcepackagerecipebuild.py
357@@ -42,8 +42,7 @@ class SourcePackageRecipeBuildMailer(BaseMailer):
358
359 def _getHeaders(self, email, recipient):
360 """See `BaseMailer`"""
361- headers = super(
362- SourcePackageRecipeBuildMailer, self)._getHeaders(email, recipient)
363+ headers = super()._getHeaders(email, recipient)
364 headers.update({
365 'X-Launchpad-Archive': self.build.archive.reference,
366 'X-Launchpad-Build-State': self.build.status.name,
367@@ -52,9 +51,7 @@ class SourcePackageRecipeBuildMailer(BaseMailer):
368
369 def _getTemplateParams(self, email, recipient):
370 """See `BaseMailer`"""
371- params = super(
372- SourcePackageRecipeBuildMailer, self)._getTemplateParams(
373- email, recipient)
374+ params = super()._getTemplateParams(email, recipient)
375 params.update({
376 'status': self.build.status.title,
377 'build_id': self.build.id,
378diff --git a/lib/lp/code/mail/tests/test_branch.py b/lib/lp/code/mail/tests/test_branch.py
379index 69ed7dd..ee56593 100644
380--- a/lib/lp/code/mail/tests/test_branch.py
381+++ b/lib/lp/code/mail/tests/test_branch.py
382@@ -306,7 +306,7 @@ class TestBranchMailerDiffMixin:
383
384 def test_generateEmail_with_diff(self):
385 """When there is a diff, it should be an attachment, not inline."""
386- ctrl = self.makeBobMailController(diff=u'hello \u03A3')
387+ ctrl = self.makeBobMailController(diff='hello \u03A3')
388 self.assertEqual(1, len(ctrl.attachments))
389 diff = ctrl.attachments[0]
390 self.assertEqual(b'hello \xce\xa3', diff.get_payload(decode=True))
391diff --git a/lib/lp/code/mail/tests/test_branchmergeproposal.py b/lib/lp/code/mail/tests/test_branchmergeproposal.py
392index 537918f..8e1e6f7 100644
393--- a/lib/lp/code/mail/tests/test_branchmergeproposal.py
394+++ b/lib/lp/code/mail/tests/test_branchmergeproposal.py
395@@ -57,7 +57,7 @@ class TestMergeProposalMailing(TestCaseWithFactory):
396 layer = LaunchpadZopelessLayer
397
398 def setUp(self):
399- super(TestMergeProposalMailing, self).setUp('admin@canonical.com')
400+ super().setUp('admin@canonical.com')
401
402 def makeProposalWithSubscriber(self, diff_text=None, initial_comment=None,
403 prerequisite=False, needs_review=True,
404diff --git a/lib/lp/code/mail/tests/test_codehandler.py b/lib/lp/code/mail/tests/test_codehandler.py
405index 21f8256..4788904 100644
406--- a/lib/lp/code/mail/tests/test_codehandler.py
407+++ b/lib/lp/code/mail/tests/test_codehandler.py
408@@ -129,13 +129,13 @@ class TestCodeHandler(TestCaseWithFactory):
409 layer = ZopelessAppServerLayer
410
411 def setUp(self):
412- super(TestCodeHandler, self).setUp(user='test@canonical.com')
413+ super().setUp(user='test@canonical.com')
414 self.code_handler = CodeHandler()
415 self._old_policy = setSecurityPolicy(LaunchpadSecurityPolicy)
416
417 def tearDown(self):
418 setSecurityPolicy(self._old_policy)
419- super(TestCodeHandler, self).tearDown()
420+ super().tearDown()
421
422 def test_get(self):
423 handler = mail_handlers.get(config.launchpad.code_domain)
424@@ -453,7 +453,7 @@ class TestVoteEmailCommand(TestCase):
425 # We don't need no stinking layer.
426
427 def setUp(self):
428- super(TestVoteEmailCommand, self).setUp()
429+ super().setUp()
430
431 class FakeExecutionContext:
432 vote = None
433@@ -555,8 +555,7 @@ class TestUpdateStatusEmailCommand(TestCaseWithFactory):
434 layer = LaunchpadZopelessLayer
435
436 def setUp(self):
437- super(TestUpdateStatusEmailCommand, self).setUp(
438- user='test@canonical.com')
439+ super().setUp(user='test@canonical.com')
440 self._old_policy = setSecurityPolicy(LaunchpadSecurityPolicy)
441 self.merge_proposal = self.factory.makeBranchMergeProposal()
442 # Default the user to be the target branch owner, so they are
443@@ -568,7 +567,7 @@ class TestUpdateStatusEmailCommand(TestCaseWithFactory):
444
445 def tearDown(self):
446 setSecurityPolicy(self._old_policy)
447- super(TestUpdateStatusEmailCommand, self).tearDown()
448+ super().tearDown()
449
450 def test_numberOfArguments(self):
451 # The command needs one and only one arg.
452@@ -678,8 +677,7 @@ class TestAddReviewerEmailCommand(TestCaseWithFactory):
453 layer = LaunchpadZopelessLayer
454
455 def setUp(self):
456- super(TestAddReviewerEmailCommand, self).setUp(
457- user='test@canonical.com')
458+ super().setUp(user='test@canonical.com')
459 self._old_policy = setSecurityPolicy(LaunchpadSecurityPolicy)
460 self.merge_proposal = (
461 make_merge_proposal_without_reviewers(self.factory))
462@@ -692,7 +690,7 @@ class TestAddReviewerEmailCommand(TestCaseWithFactory):
463
464 def tearDown(self):
465 setSecurityPolicy(self._old_policy)
466- super(TestAddReviewerEmailCommand, self).tearDown()
467+ super().tearDown()
468
469 def test_numberOfArguments(self):
470 # The command needs at least one arg.
471diff --git a/lib/lp/code/mail/tests/test_codeimport.py b/lib/lp/code/mail/tests/test_codeimport.py
472index ee62761..77eefa5 100644
473--- a/lib/lp/code/mail/tests/test_codeimport.py
474+++ b/lib/lp/code/mail/tests/test_codeimport.py
475@@ -110,7 +110,7 @@ class TestNewCodeImports(TestCaseWithFactory):
476 login_person(eric)
477 self.factory.makeProductCodeImport(
478 git_repo_url='git://git.example.com/fooix.git',
479- branch_name=u'master', product=fooix, registrant=eric,
480+ branch_name='master', product=fooix, registrant=eric,
481 target_rcs_type=TargetRevisionControlSystems.GIT)
482 transaction.commit()
483 msg = email.message_from_bytes(stub.test_emails[0][2])
484diff --git a/lib/lp/code/mail/tests/test_sourcepackagerecipebuild.py b/lib/lp/code/mail/tests/test_sourcepackagerecipebuild.py
485index b0f8f25..ed194e3 100644
486--- a/lib/lp/code/mail/tests/test_sourcepackagerecipebuild.py
487+++ b/lib/lp/code/mail/tests/test_sourcepackagerecipebuild.py
488@@ -16,7 +16,7 @@ from lp.testing.dbuser import switch_dbuser
489 from lp.testing.layers import LaunchpadZopelessLayer
490
491
492-expected_body = u"""\
493+expected_body = """\
494 * State: Successfully built
495 * Recipe: person/recipe
496 * Archive: ~archiveowner/ubuntu/ppa
497@@ -27,7 +27,7 @@ expected_body = u"""\
498 * Builder: http://launchpad.test/builders/bob
499 """ # noqa: W291
500
501-superseded_body = u"""\
502+superseded_body = """\
503 * State: Build for superseded Source
504 * Recipe: person/recipe
505 * Archive: ~archiveowner/ubuntu/ppa
506@@ -53,10 +53,10 @@ class TestSourcePackageRecipeBuildMailer(TestCaseWithFactory):
507 """GenerateEmail produces the right headers and body."""
508 person = self.factory.makePerson(name='person')
509 cake = self.factory.makeSourcePackageRecipe(
510- name=u'recipe', owner=person)
511+ name='recipe', owner=person)
512 pantry_owner = self.factory.makePerson(name='archiveowner')
513 pantry = self.factory.makeArchive(name='ppa', owner=pantry_owner)
514- secret = self.factory.makeDistroSeries(name=u'distroseries')
515+ secret = self.factory.makeDistroSeries(name='distroseries')
516 secret.nominatedarchindep = (
517 self.factory.makeDistroArchSeries(distroseries=secret))
518 build = self.factory.makeSourcePackageRecipeBuild(
519@@ -64,11 +64,11 @@ class TestSourcePackageRecipeBuildMailer(TestCaseWithFactory):
520 status=BuildStatus.FULLYBUILT, duration=timedelta(minutes=5))
521 build.updateStatus(
522 BuildStatus.FULLYBUILT,
523- builder=self.factory.makeBuilder(name=u'bob'))
524+ builder=self.factory.makeBuilder(name='bob'))
525 build.setLog(self.factory.makeLibraryFileAlias())
526 ctrl = self.makeStatusEmail(build)
527 self.assertEqual(
528- u'[recipe build #%d] of ~person recipe in distroseries: '
529+ '[recipe build #%d] of ~person recipe in distroseries: '
530 'Successfully built' % (build.id), ctrl.subject)
531 body, footer = ctrl.body.split('\n-- \n')
532 self.assertEqual(expected_body % build.log_url, body)
533@@ -93,10 +93,10 @@ class TestSourcePackageRecipeBuildMailer(TestCaseWithFactory):
534 """GenerateEmail works when many fields are NULL."""
535 person = self.factory.makePerson(name='person')
536 cake = self.factory.makeSourcePackageRecipe(
537- name=u'recipe', owner=person)
538+ name='recipe', owner=person)
539 pantry_owner = self.factory.makePerson(name='archiveowner')
540 pantry = self.factory.makeArchive(name='ppa', owner=pantry_owner)
541- secret = self.factory.makeDistroSeries(name=u'distroseries')
542+ secret = self.factory.makeDistroSeries(name='distroseries')
543 secret.nominatedarchindep = (
544 self.factory.makeDistroArchSeries(distroseries=secret))
545 build = self.factory.makeSourcePackageRecipeBuild(
546@@ -105,7 +105,7 @@ class TestSourcePackageRecipeBuildMailer(TestCaseWithFactory):
547 Store.of(build).flush()
548 ctrl = self.makeStatusEmail(build)
549 self.assertEqual(
550- u'[recipe build #%d] of ~person recipe in distroseries: '
551+ '[recipe build #%d] of ~person recipe in distroseries: '
552 'Build for superseded Source' % (build.id), ctrl.subject)
553 body, footer = ctrl.body.split('\n-- \n')
554 self.assertEqual(superseded_body, body)
555diff --git a/lib/lp/code/model/branch.py b/lib/lp/code/model/branch.py
556index 1a9bcc4..98952be 100644
557--- a/lib/lp/code/model/branch.py
558+++ b/lib/lp/code/model/branch.py
559@@ -811,7 +811,7 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
560 hosting_client = getUtility(IBranchHostingClient)
561 if enable_memcache is None:
562 enable_memcache = not getFeatureFlag(
563- u'code.bzr.blob.disable_memcache')
564+ 'code.bzr.blob.disable_memcache')
565 if revision_id is None:
566 revision_id = self.last_scanned_id
567 if revision_id is None:
568@@ -1138,7 +1138,7 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
569
570 def removeBranchRevisions(self, revision_ids):
571 """See `IBranch`."""
572- if isinstance(revision_ids, six.string_types):
573+ if isinstance(revision_ids, str):
574 revision_ids = [revision_ids]
575 IMasterStore(BranchRevision).find(
576 BranchRevision,
577diff --git a/lib/lp/code/model/branchcollection.py b/lib/lp/code/model/branchcollection.py
578index 6ba75ec..fe27bc6 100644
579--- a/lib/lp/code/model/branchcollection.py
580+++ b/lib/lp/code/model/branchcollection.py
581@@ -562,7 +562,7 @@ class GenericBranchCollection:
582 bugtasks_for_branch[bugbranch.branch].append(bugtask)
583
584 # Now filter those down to one bugtask per branch
585- for branch, tasks in six.iteritems(bugtasks_for_branch):
586+ for branch, tasks in bugtasks_for_branch.items():
587 linked_bugtasks[branch.id].extend(
588 filter_bugtasks_by_context(branch.target.context, tasks))
589
590@@ -786,7 +786,7 @@ class VisibleBranchCollection(GenericBranchCollection):
591 def __init__(self, user, store=None, branch_filter_expressions=None,
592 tables=None,
593 asymmetric_filter_expressions=None, asymmetric_tables=None):
594- super(VisibleBranchCollection, self).__init__(
595+ super().__init__(
596 store=store, branch_filter_expressions=branch_filter_expressions,
597 tables=tables,
598 asymmetric_filter_expressions=asymmetric_filter_expressions,
599diff --git a/lib/lp/code/model/branchhosting.py b/lib/lp/code/model/branchhosting.py
600index 58594e3..3911c16 100644
601--- a/lib/lp/code/model/branchhosting.py
602+++ b/lib/lp/code/model/branchhosting.py
603@@ -12,7 +12,6 @@ import sys
604
605 from lazr.restful.utils import get_current_browser_request
606 import requests
607-from six import reraise
608 from six.moves.urllib_parse import (
609 quote,
610 urljoin,
611@@ -72,9 +71,7 @@ class BranchHostingClient:
612 except Exception:
613 _, val, tb = sys.exc_info()
614 try:
615- reraise(
616- RequestExceptionWrapper,
617- RequestExceptionWrapper(*val.args), tb)
618+ raise RequestExceptionWrapper(*val.args).with_traceback(tb)
619 finally:
620 # Avoid traceback reference cycles.
621 del val, tb
622diff --git a/lib/lp/code/model/branchjob.py b/lib/lp/code/model/branchjob.py
623index 5d7c0d8..aa06aeb 100644
624--- a/lib/lp/code/model/branchjob.py
625+++ b/lib/lp/code/model/branchjob.py
626@@ -227,7 +227,7 @@ class BranchJob(StormBase):
627 :param metadata: The type-specific variables, as a JSON-compatible
628 dict.
629 """
630- super(BranchJob, self).__init__()
631+ super().__init__()
632 self.job = Job(**job_args)
633 self.branch = branch
634 self.job_type = job_type
635@@ -329,7 +329,7 @@ class BranchScanJob(BranchJobDerived):
636 return cls(branch_job)
637
638 def __init__(self, branch_job):
639- super(BranchScanJob, self).__init__(branch_job)
640+ super().__init__(branch_job)
641 self._cached_branch_name = self.metadata['branch_name']
642
643 @staticmethod
644@@ -507,7 +507,7 @@ class RevisionsAddedJob(BranchJobDerived):
645 return RevisionsAddedJob(branch_job)
646
647 def __init__(self, context):
648- super(RevisionsAddedJob, self).__init__(context)
649+ super().__init__(context)
650 self._bzr_branch = None
651 self._tree_cache = {}
652
653@@ -690,7 +690,7 @@ class RevisionsAddedJob(BranchJobDerived):
654 proposals[source_id] = (proposal, date_created)
655
656 return sorted(
657- (proposal for proposal, date_created in six.itervalues(proposals)),
658+ (proposal for proposal, date_created in proposals.values()),
659 key=operator.attrgetter('date_created'), reverse=True)
660
661 def getRevisionMessage(self, revision_id, revno):
662@@ -763,7 +763,7 @@ class RosettaUploadJob(BranchJobDerived):
663 config = config.IRosettaUploadJobSource
664
665 def __init__(self, branch_job):
666- super(RosettaUploadJob, self).__init__(branch_job)
667+ super().__init__(branch_job)
668
669 self.template_file_names = []
670 self.template_files_changed = []
671diff --git a/lib/lp/code/model/branchmergeproposal.py b/lib/lp/code/model/branchmergeproposal.py
672index a0ff7d1..f0f23d7 100644
673--- a/lib/lp/code/model/branchmergeproposal.py
674+++ b/lib/lp/code/model/branchmergeproposal.py
675@@ -18,7 +18,6 @@ from lazr.lifecycle.event import (
676 ObjectCreatedEvent,
677 ObjectDeletedEvent,
678 )
679-import six
680 from storm.expr import (
681 And,
682 Desc,
683@@ -392,8 +391,7 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
684 else:
685 bug_ids = [
686 int(id) for _, id in getUtility(IXRefSet).findFrom(
687- (u'merge_proposal', six.text_type(self.id)),
688- types=[u'bug'])]
689+ ('merge_proposal', str(self.id)), types=['bug'])]
690 bugs = load(Bug, bug_ids)
691 return list(sorted(bugs, key=attrgetter('id')))
692
693@@ -420,14 +418,12 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
694 props = {}
695 # XXX cjwatson 2016-06-11: Should set creator.
696 getUtility(IXRefSet).create(
697- {(u'merge_proposal', six.text_type(self.id)):
698- {(u'bug', six.text_type(bug.id)): props}})
699+ {('merge_proposal', str(self.id)): {('bug', str(bug.id)): props}})
700
701 def deleteBugLink(self, bug):
702 """See `BugLinkTargetMixin`."""
703 getUtility(IXRefSet).delete(
704- {(u'merge_proposal', six.text_type(self.id)):
705- [(u'bug', six.text_type(bug.id))]})
706+ {('merge_proposal', str(self.id)): [('bug', str(bug.id))]})
707
708 def linkBug(self, bug, user=None, check_permissions=True, props=None):
709 """See `BugLinkTargetMixin`."""
710@@ -436,7 +432,7 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
711 return self.source_branch.linkBug(bug, user)
712 else:
713 # Otherwise, link the bug to the merge proposal directly.
714- return super(BranchMergeProposal, self).linkBug(
715+ return super().linkBug(
716 bug, user=user, check_permissions=check_permissions,
717 props=props)
718
719@@ -451,7 +447,7 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
720 return self.source_branch.unlinkBug(bug, user)
721 else:
722 # Otherwise, unlink the bug from the merge proposal directly.
723- return super(BranchMergeProposal, self).unlinkBug(
724+ return super().unlinkBug(
725 bug, user=user, check_permissions=check_permissions)
726
727 def _reportTooManyRelatedBugs(self):
728@@ -505,8 +501,7 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
729 current_bug_ids_from_source = {
730 int(id): (props['metadata'] or {}).get('from_source', False)
731 for (_, id), props in getUtility(IXRefSet).findFrom(
732- (u'merge_proposal', six.text_type(self.id)),
733- types=[u'bug']).items()}
734+ ('merge_proposal', str(self.id)), types=['bug']).items()}
735 current_bug_ids = set(current_bug_ids_from_source)
736 new_bug_ids = self._fetchRelatedBugIDsFromSource()
737 # Only remove links marked as originating in the source branch.
738diff --git a/lib/lp/code/model/branchmergeproposaljob.py b/lib/lp/code/model/branchmergeproposaljob.py
739index 3a58ae9..8c1fd83 100644
740--- a/lib/lp/code/model/branchmergeproposaljob.py
741+++ b/lib/lp/code/model/branchmergeproposaljob.py
742@@ -175,7 +175,7 @@ class BranchMergeProposalJob(StormBase):
743 :param metadata: The type-specific variables, as a JSON-compatible
744 dict.
745 """
746- super(BranchMergeProposalJob, self).__init__()
747+ super().__init__()
748 json_data = simplejson.dumps(metadata)
749 self.job = Job()
750 self.branch_merge_proposal = branch_merge_proposal
751diff --git a/lib/lp/code/model/branchsubscription.py b/lib/lp/code/model/branchsubscription.py
752index c9b10a8..36ec00a 100644
753--- a/lib/lp/code/model/branchsubscription.py
754+++ b/lib/lp/code/model/branchsubscription.py
755@@ -48,7 +48,7 @@ class BranchSubscription(StormBase):
756
757 def __init__(self, person, branch, notification_level, max_diff_lines,
758 review_level, subscribed_by):
759- super(BranchSubscription, self).__init__()
760+ super().__init__()
761 self.person = person
762 self.branch = branch
763 self.notification_level = notification_level
764diff --git a/lib/lp/code/model/branchtarget.py b/lib/lp/code/model/branchtarget.py
765index 9100558..f341171 100644
766--- a/lib/lp/code/model/branchtarget.py
767+++ b/lib/lp/code/model/branchtarget.py
768@@ -187,7 +187,7 @@ class PackageBranchTarget(_BaseBranchTarget):
769 @implementer(IBranchTarget)
770 class PersonBranchTarget(_BaseBranchTarget):
771
772- name = u'+junk'
773+ name = '+junk'
774 default_stacked_on_branch = None
775 default_merge_target = None
776
777diff --git a/lib/lp/code/model/codeimport.py b/lib/lp/code/model/codeimport.py
778index c2b028e..13f6559 100644
779--- a/lib/lp/code/model/codeimport.py
780+++ b/lib/lp/code/model/codeimport.py
781@@ -83,7 +83,7 @@ class CodeImport(StormBase):
782
783 def __init__(self, registrant, owner, target, review_status, rcs_type=None,
784 url=None, cvs_root=None, cvs_module=None):
785- super(CodeImport, self).__init__()
786+ super().__init__()
787 self.registrant = registrant
788 self.owner = owner
789 if IBranch.providedBy(target):
790diff --git a/lib/lp/code/model/codeimportevent.py b/lib/lp/code/model/codeimportevent.py
791index eb399d1..2b41ce4 100644
792--- a/lib/lp/code/model/codeimportevent.py
793+++ b/lib/lp/code/model/codeimportevent.py
794@@ -12,7 +12,6 @@ __all__ = [
795
796 from lazr.enum import DBItem
797 import pytz
798-import six
799 from storm.locals import (
800 DateTime,
801 Int,
802@@ -65,7 +64,7 @@ class CodeImportEvent(StormBase):
803
804 def __init__(self, event_type, code_import=None, person=None,
805 machine=None, date_created=DEFAULT):
806- super(CodeImportEvent, self).__init__()
807+ super().__init__()
808 self.event_type = event_type
809 self.code_import = code_import
810 self.person = person
811@@ -97,7 +96,7 @@ class _CodeImportEventData(StormBase):
812 data_value = Unicode(allow_none=True)
813
814 def __init__(self, event, data_type, data_value):
815- super(_CodeImportEventData, self).__init__()
816+ super().__init__()
817 self.event = event
818 self.data_type = data_type
819 self.data_value = data_value
820@@ -200,7 +199,7 @@ class CodeImportEventSet:
821 IStore(CodeImportEvent).add(event)
822 IStore(_CodeImportEventData).add(_CodeImportEventData(
823 event=event, data_type=CodeImportEventDataType.OFFLINE_REASON,
824- data_value=six.text_type(reason.name)))
825+ data_value=str(reason.name)))
826 self._recordMessage(event, message)
827 return event
828
829@@ -257,7 +256,7 @@ class CodeImportEventSet:
830 IStore(CodeImportEvent).add(event)
831 IStore(_CodeImportEventData).add(_CodeImportEventData(
832 event=event, data_type=CodeImportEventDataType.RECLAIMED_JOB_ID,
833- data_value=six.text_type(job_id)))
834+ data_value=str(job_id)))
835 return event
836
837 def _recordSnapshot(self, event, code_import):
838@@ -278,18 +277,17 @@ class CodeImportEventSet:
839 def _iterItemsForSnapshot(self, code_import):
840 """Yield key-value tuples to save a snapshot of the code import."""
841 yield self._getCodeImportItem(code_import)
842- yield 'REVIEW_STATUS', six.text_type(code_import.review_status.name)
843- yield 'OWNER', six.text_type(code_import.owner.id)
844+ yield 'REVIEW_STATUS', str(code_import.review_status.name)
845+ yield 'OWNER', str(code_import.owner.id)
846 yield 'UPDATE_INTERVAL', self._getNullableValue(
847 code_import.update_interval)
848 yield 'ASSIGNEE', self._getNullableValue(
849 code_import.assignee, use_id=True)
850- for detail in self._iterSourceDetails(code_import):
851- yield detail
852+ yield from self._iterSourceDetails(code_import)
853
854 def _getCodeImportItem(self, code_import):
855 """Return the key-value tuple for the code import id."""
856- return 'CODE_IMPORT', six.text_type(code_import.id)
857+ return 'CODE_IMPORT', str(code_import.id)
858
859 def _getNullableValue(self, value, use_id=False):
860 """Return the string value for a nullable value.
861@@ -301,9 +299,9 @@ class CodeImportEventSet:
862 if value is None:
863 return None
864 elif use_id:
865- return six.text_type(value.id)
866+ return str(value.id)
867 else:
868- return six.text_type(value)
869+ return str(value)
870
871 def _iterSourceDetails(self, code_import):
872 """Yield key-value tuples describing the source of the import."""
873diff --git a/lib/lp/code/model/codeimportjob.py b/lib/lp/code/model/codeimportjob.py
874index a7839a3..0d010c5 100644
875--- a/lib/lp/code/model/codeimportjob.py
876+++ b/lib/lp/code/model/codeimportjob.py
877@@ -104,7 +104,7 @@ class CodeImportJob(StormBase):
878 date_started = DateTime(tzinfo=pytz.UTC, allow_none=True, default=None)
879
880 def __init__(self, code_import, date_due):
881- super(CodeImportJob, self).__init__()
882+ super().__init__()
883 self.code_import = code_import
884 self.date_due = date_due
885
886@@ -179,7 +179,7 @@ class CodeImportJob(StormBase):
887
888
889 @implementer(ICodeImportJobSet, ICodeImportJobSetPublic)
890-class CodeImportJobSet(object):
891+class CodeImportJobSet:
892 """See `ICodeImportJobSet`."""
893
894 # CodeImportJob database objects are created using
895diff --git a/lib/lp/code/model/codeimportmachine.py b/lib/lp/code/model/codeimportmachine.py
896index 084f8ca..0ce2fc5 100644
897--- a/lib/lp/code/model/codeimportmachine.py
898+++ b/lib/lp/code/model/codeimportmachine.py
899@@ -65,7 +65,7 @@ class CodeImportMachine(StormBase):
900 Desc('CodeImportEvent.id')))
901
902 def __init__(self, hostname, heartbeat=None):
903- super(CodeImportMachine, self).__init__()
904+ super().__init__()
905 self.hostname = hostname
906 self.heartbeat = heartbeat
907 self.state = CodeImportMachineState.OFFLINE
908@@ -120,7 +120,7 @@ class CodeImportMachine(StormBase):
909
910
911 @implementer(ICodeImportMachineSet)
912-class CodeImportMachineSet(object):
913+class CodeImportMachineSet:
914 """See `ICodeImportMachineSet`."""
915
916 def getAll(self):
917diff --git a/lib/lp/code/model/codeimportresult.py b/lib/lp/code/model/codeimportresult.py
918index 84fb963..222e3d6 100644
919--- a/lib/lp/code/model/codeimportresult.py
920+++ b/lib/lp/code/model/codeimportresult.py
921@@ -59,7 +59,7 @@ class CodeImportResult(StormBase):
922 def __init__(self, code_import, machine, status, date_job_started,
923 requesting_user=None, log_excerpt=None, log_file=None,
924 date_created=UTC_NOW):
925- super(CodeImportResult, self).__init__()
926+ super().__init__()
927 self.code_import = code_import
928 self.machine = machine
929 self.status = status
930@@ -80,7 +80,7 @@ class CodeImportResult(StormBase):
931
932
933 @implementer(ICodeImportResultSet)
934-class CodeImportResultSet(object):
935+class CodeImportResultSet:
936 """See `ICodeImportResultSet`."""
937
938 def new(self, code_import, machine, requesting_user, log_excerpt,
939diff --git a/lib/lp/code/model/codereviewinlinecomment.py b/lib/lp/code/model/codereviewinlinecomment.py
940index a6dc6da..a86d682 100644
941--- a/lib/lp/code/model/codereviewinlinecomment.py
942+++ b/lib/lp/code/model/codereviewinlinecomment.py
943@@ -9,7 +9,6 @@ __all__ = [
944 'CodeReviewInlineCommentSet',
945 ]
946
947-import six
948 from storm.expr import LeftJoin
949 from storm.locals import (
950 Int,
951@@ -113,7 +112,7 @@ class CodeReviewInlineCommentSet:
952 list(crics), key=lambda c: c.comment.date_created)
953 inline_comments = []
954 for cric in sorted_crics:
955- for line_number, text in six.iteritems(cric.comments):
956+ for line_number, text in cric.comments.items():
957 comment = {
958 'line_number': line_number,
959 'person': cric.person,
960diff --git a/lib/lp/code/model/diff.py b/lib/lp/code/model/diff.py
961index 13f633c..93626b2 100644
962--- a/lib/lp/code/model/diff.py
963+++ b/lib/lp/code/model/diff.py
964@@ -98,7 +98,7 @@ class Diff(SQLBase):
965 @property
966 def text(self):
967 if self.diff_text is None:
968- return u''
969+ return ''
970 else:
971 with reduced_timeout(
972 0.01, webapp_max=2.0,
973@@ -385,13 +385,13 @@ class PreviewDiff(Storm):
974 source_revision = bmp.source_branch.getBranchRevision(
975 revision_id=self.source_revision_id)
976 if source_revision and source_revision.sequence:
977- source_rev = u'r{}'.format(source_revision.sequence)
978+ source_rev = 'r{}'.format(source_revision.sequence)
979 else:
980 source_rev = self.source_revision_id
981 target_revision = bmp.target_branch.getBranchRevision(
982 revision_id=self.target_revision_id)
983 if target_revision and target_revision.sequence:
984- target_rev = u'r{}'.format(target_revision.sequence)
985+ target_rev = 'r{}'.format(target_revision.sequence)
986 else:
987 target_rev = self.target_revision_id
988 else:
989@@ -402,7 +402,7 @@ class PreviewDiff(Storm):
990 source_rev = self.source_revision_id[:7]
991 target_rev = self.target_revision_id[:7]
992
993- return u'{} into {}'.format(source_rev, target_rev)
994+ return '{} into {}'.format(source_rev, target_rev)
995
996 @property
997 def has_conflicts(self):
998@@ -433,8 +433,8 @@ class PreviewDiff(Storm):
999 preview.target_revision_id = target_revision.decode('utf-8')
1000 preview.branch_merge_proposal = bmp
1001 preview.diff = diff
1002- preview.conflicts = u''.join(
1003- six.text_type(conflict) + '\n' for conflict in conflicts)
1004+ preview.conflicts = ''.join(
1005+ str(conflict) + '\n' for conflict in conflicts)
1006 else:
1007 source_repository = bmp.source_git_repository
1008 target_repository = bmp.target_git_repository
1009@@ -449,8 +449,8 @@ class PreviewDiff(Storm):
1010 response = getUtility(IGitHostingClient).getMergeDiff(
1011 path, bmp.target_git_commit_sha1, bmp.source_git_commit_sha1,
1012 prerequisite=bmp.prerequisite_git_commit_sha1)
1013- conflicts = u"".join(
1014- u"Conflict in %s\n" % path for path in response['conflicts'])
1015+ conflicts = "".join(
1016+ "Conflict in %s\n" % path for path in response['conflicts'])
1017 preview = cls.create(
1018 bmp, response['patch'].encode('utf-8'),
1019 bmp.source_git_commit_sha1, bmp.target_git_commit_sha1,
1020diff --git a/lib/lp/code/model/gitactivity.py b/lib/lp/code/model/gitactivity.py
1021index a7b2036..42091f1 100644
1022--- a/lib/lp/code/model/gitactivity.py
1023+++ b/lib/lp/code/model/gitactivity.py
1024@@ -60,7 +60,7 @@ class GitActivity(StormBase):
1025
1026 def __init__(self, repository, changer, what_changed, changee=None,
1027 old_value=None, new_value=None, date_changed=DEFAULT):
1028- super(GitActivity, self).__init__()
1029+ super().__init__()
1030 self.repository = repository
1031 self.date_changed = date_changed
1032 self.changer = changer
1033diff --git a/lib/lp/code/model/gitcollection.py b/lib/lp/code/model/gitcollection.py
1034index 966ea02..8c2d4f1 100644
1035--- a/lib/lp/code/model/gitcollection.py
1036+++ b/lib/lp/code/model/gitcollection.py
1037@@ -622,7 +622,7 @@ class VisibleGitCollection(GenericGitCollection):
1038
1039 def __init__(self, user, store=None, filter_expressions=None, tables=None,
1040 asymmetric_filter_expressions=None, asymmetric_tables=None):
1041- super(VisibleGitCollection, self).__init__(
1042+ super().__init__(
1043 store=store, filter_expressions=filter_expressions, tables=tables,
1044 asymmetric_filter_expressions=asymmetric_filter_expressions,
1045 asymmetric_tables=asymmetric_tables)
1046diff --git a/lib/lp/code/model/githosting.py b/lib/lp/code/model/githosting.py
1047index 6494390..e498138 100644
1048--- a/lib/lp/code/model/githosting.py
1049+++ b/lib/lp/code/model/githosting.py
1050@@ -14,11 +14,7 @@ import sys
1051
1052 from lazr.restful.utils import get_current_browser_request
1053 import requests
1054-import six
1055-from six import (
1056- ensure_text,
1057- reraise,
1058- )
1059+from six import ensure_text
1060 from six.moves.urllib.parse import (
1061 quote,
1062 urljoin,
1063@@ -89,9 +85,7 @@ class GitHostingClient:
1064 except Exception:
1065 _, val, tb = sys.exc_info()
1066 try:
1067- reraise(
1068- RequestExceptionWrapper,
1069- RequestExceptionWrapper(*val.args), tb)
1070+ raise RequestExceptionWrapper(*val.args).with_traceback(tb)
1071 finally:
1072 # Avoid traceback reference cycles.
1073 del val, tb
1074@@ -131,7 +125,7 @@ class GitHostingClient:
1075 self._post("/repo", json=request)
1076 except requests.RequestException as e:
1077 raise GitRepositoryCreationFault(
1078- "Failed to create Git repository: %s" % six.text_type(e), path)
1079+ "Failed to create Git repository: %s" % str(e), path)
1080
1081 def getProperties(self, path):
1082 """See `IGitHostingClient`."""
1083@@ -139,8 +133,7 @@ class GitHostingClient:
1084 return self._get("/repo/%s" % path)
1085 except requests.RequestException as e:
1086 raise GitRepositoryScanFault(
1087- "Failed to get properties of Git repository: %s" %
1088- six.text_type(e))
1089+ "Failed to get properties of Git repository: %s" % str(e))
1090
1091 def setProperties(self, path, **props):
1092 """See `IGitHostingClient`."""
1093@@ -148,8 +141,7 @@ class GitHostingClient:
1094 self._patch("/repo/%s" % path, json=props)
1095 except requests.RequestException as e:
1096 raise GitRepositoryScanFault(
1097- "Failed to set properties of Git repository: %s" %
1098- six.text_type(e))
1099+ "Failed to set properties of Git repository: %s" % str(e))
1100
1101 def getRefs(self, path, exclude_prefixes=None):
1102 """See `IGitHostingClient`."""
1103@@ -159,8 +151,7 @@ class GitHostingClient:
1104 params={"exclude_prefix": exclude_prefixes})
1105 except requests.RequestException as e:
1106 raise GitRepositoryScanFault(
1107- "Failed to get refs from Git repository: %s" %
1108- six.text_type(e))
1109+ "Failed to get refs from Git repository: %s" % str(e))
1110
1111 def getCommits(self, path, commit_oids, logger=None):
1112 """See `IGitHostingClient`."""
1113@@ -173,7 +164,7 @@ class GitHostingClient:
1114 except requests.RequestException as e:
1115 raise GitRepositoryScanFault(
1116 "Failed to get commit details from Git repository: %s" %
1117- six.text_type(e))
1118+ str(e))
1119
1120 def getLog(self, path, start, limit=None, stop=None, logger=None):
1121 """See `IGitHostingClient`."""
1122@@ -188,8 +179,7 @@ class GitHostingClient:
1123 params={"limit": limit, "stop": stop})
1124 except requests.RequestException as e:
1125 raise GitRepositoryScanFault(
1126- "Failed to get commit log from Git repository: %s" %
1127- six.text_type(e))
1128+ "Failed to get commit log from Git repository: %s" % str(e))
1129
1130 def getDiff(self, path, old, new, common_ancestor=False,
1131 context_lines=None, logger=None):
1132@@ -204,8 +194,7 @@ class GitHostingClient:
1133 return self._get(url, params={"context_lines": context_lines})
1134 except requests.RequestException as e:
1135 raise GitRepositoryScanFault(
1136- "Failed to get diff from Git repository: %s" %
1137- six.text_type(e))
1138+ "Failed to get diff from Git repository: %s" % str(e))
1139
1140 def getMergeDiff(self, path, base, head, prerequisite=None, logger=None):
1141 """See `IGitHostingClient`."""
1142@@ -219,8 +208,7 @@ class GitHostingClient:
1143 return self._get(url, params={"sha1_prerequisite": prerequisite})
1144 except requests.RequestException as e:
1145 raise GitRepositoryScanFault(
1146- "Failed to get merge diff from Git repository: %s" %
1147- six.text_type(e))
1148+ "Failed to get merge diff from Git repository: %s" % str(e))
1149
1150 def detectMerges(self, path, target, sources, logger=None):
1151 """See `IGitHostingClient`."""
1152@@ -235,8 +223,7 @@ class GitHostingClient:
1153 json={"sources": sources})
1154 except requests.RequestException as e:
1155 raise GitRepositoryScanFault(
1156- "Failed to detect merges in Git repository: %s" %
1157- six.text_type(e))
1158+ "Failed to detect merges in Git repository: %s" % str(e))
1159
1160 def delete(self, path, logger=None):
1161 """See `IGitHostingClient`."""
1162@@ -246,7 +233,7 @@ class GitHostingClient:
1163 self._delete("/repo/%s" % path)
1164 except requests.RequestException as e:
1165 raise GitRepositoryDeletionFault(
1166- "Failed to delete Git repository: %s" % six.text_type(e))
1167+ "Failed to delete Git repository: %s" % str(e))
1168
1169 def getBlob(self, path, filename, rev=None, logger=None):
1170 """See `IGitHostingClient`."""
1171@@ -262,8 +249,7 @@ class GitHostingClient:
1172 raise GitRepositoryBlobNotFound(path, filename, rev=rev)
1173 else:
1174 raise GitRepositoryScanFault(
1175- "Failed to get file from Git repository: %s" %
1176- six.text_type(e))
1177+ "Failed to get file from Git repository: %s" % str(e))
1178 try:
1179 blob = base64.b64decode(response["data"].encode("UTF-8"))
1180 if len(blob) != response["size"]:
1181@@ -273,8 +259,7 @@ class GitHostingClient:
1182 return blob
1183 except Exception as e:
1184 raise GitRepositoryScanFault(
1185- "Failed to get file from Git repository: %s" %
1186- six.text_type(e))
1187+ "Failed to get file from Git repository: %s" % str(e))
1188
1189 def copyRefs(self, path, operations, logger=None):
1190 """See `IGitHostingClient`."""
1191@@ -334,7 +319,7 @@ class GitHostingClient:
1192 else:
1193 raise CannotRepackRepository(
1194 "Failed to repack Git repository %s: %s" %
1195- (path, six.text_type(e)))
1196+ (path, str(e)))
1197
1198 def collectGarbage(self, path, logger=None):
1199 """See `IGitHostingClient`."""
1200@@ -349,4 +334,4 @@ class GitHostingClient:
1201 except requests.RequestException as e:
1202 raise CannotRunGitGC(
1203 "Failed to run Git GC for repository %s: %s" %
1204- (path, six.text_type(e)))
1205+ (path, str(e)))
1206diff --git a/lib/lp/code/model/gitjob.py b/lib/lp/code/model/gitjob.py
1207index 2e78d06..8b0ede0 100644
1208--- a/lib/lp/code/model/gitjob.py
1209+++ b/lib/lp/code/model/gitjob.py
1210@@ -125,7 +125,7 @@ class GitJob(StormBase):
1211 :param metadata: The type-specific variables, as a JSON-compatible
1212 dict.
1213 """
1214- super(GitJob, self).__init__()
1215+ super().__init__()
1216 self.job = Job(**job_args)
1217 self.repository = repository
1218 self.job_type = job_type
1219@@ -177,7 +177,7 @@ class GitJobDerived(BaseRunnableJob, metaclass=EnumeratedSubclass):
1220
1221 def getOopsVars(self):
1222 """See `IRunnableJob`."""
1223- oops_vars = super(GitJobDerived, self).getOopsVars()
1224+ oops_vars = super().getOopsVars()
1225 oops_vars.extend([
1226 ('git_job_id', self.context.job.id),
1227 ('git_job_type', self.context.job_type.title),
1228diff --git a/lib/lp/code/model/gitlookup.py b/lib/lp/code/model/gitlookup.py
1229index 03b5a43..6c5746f 100644
1230--- a/lib/lp/code/model/gitlookup.py
1231+++ b/lib/lp/code/model/gitlookup.py
1232@@ -151,8 +151,7 @@ class ProjectGitTraversable(_BaseGitTraversable):
1233 if oci_project is None:
1234 raise NoSuchOCIProjectName(ociproject_name)
1235 return owner, oci_project, None
1236- return super(ProjectGitTraversable, self).traverse(
1237- owner, name, segments)
1238+ return super().traverse(owner, name, segments)
1239
1240 def getNamespace(self, owner):
1241 return getUtility(IGitNamespaceSet).get(owner, project=self.context)
1242@@ -240,8 +239,7 @@ class PersonGitTraversable(_BaseGitTraversable):
1243 `IGitRepository`).
1244 """
1245 if name == "+git":
1246- return super(PersonGitTraversable, self).traverse(
1247- owner, name, segments)
1248+ return super().traverse(owner, name, segments)
1249 else:
1250 if not valid_name(name):
1251 raise InvalidProductName(name)
1252@@ -266,7 +264,7 @@ class DistributionOCIProjectGitTraversable(_BaseGitTraversable):
1253 owner, oci_project=self.context)
1254
1255
1256-class SegmentIterator(six.Iterator):
1257+class SegmentIterator:
1258 """An iterator that remembers the elements it has traversed."""
1259
1260 def __init__(self, iterator):
1261diff --git a/lib/lp/code/model/gitref.py b/lib/lp/code/model/gitref.py
1262index 61a7526..11a3959 100644
1263--- a/lib/lp/code/model/gitref.py
1264+++ b/lib/lp/code/model/gitref.py
1265@@ -333,10 +333,10 @@ class GitRefMixin:
1266 enable_hosting=None, enable_memcache=None, logger=None):
1267 if enable_hosting is None:
1268 enable_hosting = not getFeatureFlag(
1269- u"code.git.log.disable_hosting")
1270+ "code.git.log.disable_hosting")
1271 if enable_memcache is None:
1272 enable_memcache = not getFeatureFlag(
1273- u"code.git.log.disable_memcache")
1274+ "code.git.log.disable_memcache")
1275 path = self.repository.getInternalPath()
1276 if (union_repository is not None and
1277 union_repository != self.repository):
1278@@ -636,9 +636,9 @@ class GitRef(GitRefMixin, StormBase):
1279 def findByReposAndPaths(cls, repos_and_paths):
1280 """See `IGitRefSet`"""
1281 def full_path(path):
1282- if path.startswith(u"refs/heads/"):
1283+ if path.startswith("refs/heads/"):
1284 return path
1285- return u"refs/heads/%s" % path
1286+ return "refs/heads/%s" % path
1287
1288 condition = None
1289 for repo, path in repos_and_paths:
1290@@ -702,7 +702,7 @@ class GitRefDefault(GitRefDatabaseBackedMixin):
1291 def __init__(self, repository):
1292 self.repository_id = repository.id
1293 self.repository = repository
1294- self.path = u"HEAD"
1295+ self.path = "HEAD"
1296
1297 _non_database_attributes = ("repository_id", "repository", "path")
1298
1299diff --git a/lib/lp/code/model/gitrepository.py b/lib/lp/code/model/gitrepository.py
1300index 43a005a..c6b8ada 100644
1301--- a/lib/lp/code/model/gitrepository.py
1302+++ b/lib/lp/code/model/gitrepository.py
1303@@ -500,7 +500,7 @@ class GitRepository(StormBase, WebhookTargetMixin, AccessTokenTargetMixin,
1304 description=None, status=None, loose_object_count=None,
1305 pack_count=None, date_last_scanned=None,
1306 date_last_repacked=None):
1307- super(GitRepository, self).__init__()
1308+ super().__init__()
1309 self.repository_type = repository_type
1310 self.registrant = registrant
1311 self.owner = owner
1312@@ -798,7 +798,7 @@ class GitRepository(StormBase, WebhookTargetMixin, AccessTokenTargetMixin,
1313 return Store.of(self).find(
1314 GitRef,
1315 GitRef.repository_id == self.id,
1316- GitRef.path.startswith(u"refs/heads/")).order_by(GitRef.path)
1317+ GitRef.path.startswith("refs/heads/")).order_by(GitRef.path)
1318
1319 @property
1320 def branches_by_date(self):
1321@@ -831,11 +831,11 @@ class GitRepository(StormBase, WebhookTargetMixin, AccessTokenTargetMixin,
1322 self.getInternalPath(), default_branch=ref.path)
1323
1324 def getRefByPath(self, path):
1325- if path == u"HEAD":
1326+ if path == "HEAD":
1327 return GitRefDefault(self)
1328 paths = [path]
1329- if not path.startswith(u"refs/heads/"):
1330- paths.append(u"refs/heads/%s" % path)
1331+ if not path.startswith("refs/heads/"):
1332+ paths.append("refs/heads/%s" % path)
1333 refs = Store.of(self).find(
1334 GitRef,
1335 GitRef.repository_id == self.id,
1336@@ -864,8 +864,7 @@ class GitRepository(StormBase, WebhookTargetMixin, AccessTokenTargetMixin,
1337 raise ValueError('ref info object does not contain "sha1" key')
1338 if "type" not in obj:
1339 raise ValueError('ref info object does not contain "type" key')
1340- if (not isinstance(obj["sha1"], six.string_types) or
1341- len(obj["sha1"]) != 40):
1342+ if not isinstance(obj["sha1"], str) or len(obj["sha1"]) != 40:
1343 raise ValueError('ref info sha1 is not a 40-character string')
1344 if obj["type"] not in object_type_map:
1345 raise ValueError('ref info type is not a recognised object type')
1346@@ -1971,7 +1970,7 @@ class DeletionCallable(DeletionOperation):
1347 """Deletion operation that invokes a callable."""
1348
1349 def __init__(self, affected_object, rationale, func, *args, **kwargs):
1350- super(DeletionCallable, self).__init__(affected_object, rationale)
1351+ super().__init__(affected_object, rationale)
1352 self.func = func
1353 self.args = args
1354 self.kwargs = kwargs
1355@@ -2231,7 +2230,7 @@ class GitRepositoryMacaroonIssuer(MacaroonIssuerBase):
1356 _timestamp_format = "%Y-%m-%dT%H:%M:%S.%f"
1357
1358 def __init__(self):
1359- super(GitRepositoryMacaroonIssuer, self).__init__()
1360+ super().__init__()
1361 self.checkers = {
1362 "lp.principal.openid-identifier": self.verifyOpenIDIdentifier,
1363 "lp.expires": self.verifyExpires,
1364@@ -2260,8 +2259,7 @@ class GitRepositoryMacaroonIssuer(MacaroonIssuerBase):
1365
1366 def issueMacaroon(self, context, user=None, **kwargs):
1367 """See `IMacaroonIssuer`."""
1368- macaroon = super(GitRepositoryMacaroonIssuer, self).issueMacaroon(
1369- context, user=user, **kwargs)
1370+ macaroon = super().issueMacaroon(context, user=user, **kwargs)
1371 naked_account = removeSecurityProxy(user).account
1372 macaroon.add_first_party_caveat(
1373 "lp.principal.openid-identifier " +
1374diff --git a/lib/lp/code/model/gitrule.py b/lib/lp/code/model/gitrule.py
1375index 5d416b7..b16d327 100644
1376--- a/lib/lp/code/model/gitrule.py
1377+++ b/lib/lp/code/model/gitrule.py
1378@@ -111,7 +111,7 @@ class GitRule(StormBase):
1379
1380 def __init__(self, repository, position, ref_pattern, creator,
1381 date_created):
1382- super(GitRule, self).__init__()
1383+ super().__init__()
1384 self.repository = repository
1385 self.position = position
1386 self.ref_pattern = ref_pattern
1387diff --git a/lib/lp/code/model/gitsubscription.py b/lib/lp/code/model/gitsubscription.py
1388index 8ad435a..2c61db4 100644
1389--- a/lib/lp/code/model/gitsubscription.py
1390+++ b/lib/lp/code/model/gitsubscription.py
1391@@ -53,7 +53,7 @@ class GitSubscription(StormBase):
1392
1393 def __init__(self, person, repository, notification_level, max_diff_lines,
1394 review_level, subscribed_by):
1395- super(GitSubscription, self).__init__()
1396+ super().__init__()
1397 self.person = person
1398 self.repository = repository
1399 self.notification_level = notification_level
1400diff --git a/lib/lp/code/model/recipebuilder.py b/lib/lp/code/model/recipebuilder.py
1401index 46ef5b8..abd82e8 100644
1402--- a/lib/lp/code/model/recipebuilder.py
1403+++ b/lib/lp/code/model/recipebuilder.py
1404@@ -63,8 +63,7 @@ class RecipeBuildBehaviour(BuildFarmJobBehaviourBase):
1405 self.build.distroseries.displayname))
1406
1407 # Build extra arguments.
1408- args = yield super(RecipeBuildBehaviour, self).extraBuildArgs(
1409- logger=logger)
1410+ args = yield super().extraBuildArgs(logger=logger)
1411 args['suite'] = self.build.distroseries.getSuite(self.build.pocket)
1412 requester = self.build.requester
1413 if requester.preferredemail is None:
1414diff --git a/lib/lp/code/model/revision.py b/lib/lp/code/model/revision.py
1415index 680f3a2..2f04cd3 100644
1416--- a/lib/lp/code/model/revision.py
1417+++ b/lib/lp/code/model/revision.py
1418@@ -286,7 +286,7 @@ class RevisionSet:
1419 parent_id=parent_id)
1420
1421 # Create revision properties.
1422- for name, value in six.iteritems(properties):
1423+ for name, value in properties.items():
1424 RevisionProperty(revision=revision, name=name, value=value)
1425
1426 return revision
1427@@ -377,7 +377,7 @@ class RevisionSet:
1428 for bzr_revision in revisions:
1429 db_id = revision_db_id[six.ensure_text(bzr_revision.revision_id)]
1430 # Property data: revision DB id, name, value.
1431- for name, value in six.iteritems(bzr_revision.properties):
1432+ for name, value in bzr_revision.properties.items():
1433 # pristine-tar properties can be huge, and storing them
1434 # in the database provides no value. Exclude them.
1435 if name.startswith('deb-pristine-delta'):
1436diff --git a/lib/lp/code/model/sourcepackagerecipebuild.py b/lib/lp/code/model/sourcepackagerecipebuild.py
1437index f10ed3c..7be41ee 100644
1438--- a/lib/lp/code/model/sourcepackagerecipebuild.py
1439+++ b/lib/lp/code/model/sourcepackagerecipebuild.py
1440@@ -191,7 +191,7 @@ class SourcePackageRecipeBuild(SpecificBuildFarmJobSourceMixin,
1441 archive, pocket, date_created):
1442 """Construct a SourcePackageRecipeBuild."""
1443 processor = distroseries.nominatedarchindep.processor
1444- super(SourcePackageRecipeBuild, self).__init__()
1445+ super().__init__()
1446 self.build_farm_job = build_farm_job
1447 self.distroseries = distroseries
1448 self.recipe = recipe
1449diff --git a/lib/lp/code/model/sourcepackagerecipedata.py b/lib/lp/code/model/sourcepackagerecipedata.py
1450index f5d849b..0185f42 100644
1451--- a/lib/lp/code/model/sourcepackagerecipedata.py
1452+++ b/lib/lp/code/model/sourcepackagerecipedata.py
1453@@ -105,7 +105,7 @@ class _SourcePackageRecipeDataInstruction(Storm):
1454 def __init__(self, name, type, comment, line_number, branch_or_repository,
1455 revspec, directory, recipe_data, parent_instruction,
1456 source_directory):
1457- super(_SourcePackageRecipeDataInstruction, self).__init__()
1458+ super().__init__()
1459 self.name = six.ensure_text(name)
1460 self.type = type
1461 self.comment = comment
1462@@ -431,13 +431,13 @@ class SourcePackageRecipeData(Storm):
1463 else:
1464 self.deb_version_template = six.ensure_text(
1465 builder_recipe.deb_version)
1466- self.recipe_format = six.text_type(builder_recipe.format)
1467+ self.recipe_format = str(builder_recipe.format)
1468
1469 def __init__(self, recipe, recipe_branch_type, sourcepackage_recipe=None,
1470 sourcepackage_recipe_build=None):
1471 """Initialize from the bzr-builder recipe and link it to a db recipe.
1472 """
1473- super(SourcePackageRecipeData, self).__init__()
1474+ super().__init__()
1475 self.setRecipe(recipe, recipe_branch_type)
1476 self.sourcepackage_recipe = sourcepackage_recipe
1477 self.sourcepackage_recipe_build = sourcepackage_recipe_build
1478diff --git a/lib/lp/code/model/tests/test_branch.py b/lib/lp/code/model/tests/test_branch.py
1479index 16858d2..4419b12 100644
1480--- a/lib/lp/code/model/tests/test_branch.py
1481+++ b/lib/lp/code/model/tests/test_branch.py
1482@@ -188,7 +188,7 @@ class TestCodeImport(TestCase):
1483 layer = LaunchpadZopelessLayer
1484
1485 def setUp(self):
1486- super(TestCodeImport, self).setUp()
1487+ super().setUp()
1488 login('test@canonical.com')
1489 self.factory = LaunchpadObjectFactory()
1490
1491@@ -1468,7 +1468,7 @@ class TestBranchDeletionConsequences(TestCase):
1492 layer = LaunchpadZopelessLayer
1493
1494 def setUp(self):
1495- super(TestBranchDeletionConsequences, self).setUp()
1496+ super().setUp()
1497 login('test@canonical.com')
1498 self.factory = LaunchpadObjectFactory()
1499 # Has to be a product branch because of merge proposals.
1500@@ -1823,7 +1823,7 @@ class BranchAddLandingTarget(TestCaseWithFactory):
1501 layer = DatabaseFunctionalLayer
1502
1503 def setUp(self):
1504- super(BranchAddLandingTarget, self).setUp('admin@canonical.com')
1505+ super().setUp('admin@canonical.com')
1506 self.product = self.factory.makeProduct()
1507
1508 self.user = self.factory.makePerson()
1509@@ -1837,7 +1837,7 @@ class BranchAddLandingTarget(TestCaseWithFactory):
1510
1511 def tearDown(self):
1512 logout()
1513- super(BranchAddLandingTarget, self).tearDown()
1514+ super().tearDown()
1515
1516 def assertOnePendingReview(self, proposal, reviewer, review_type=None):
1517 # There should be one pending vote for the reviewer with the specified
1518@@ -3099,7 +3099,7 @@ class TestGetMergeProposals(TestCaseWithFactory):
1519 layer = DatabaseFunctionalLayer
1520
1521 def setUp(self):
1522- super(TestGetMergeProposals, self).setUp()
1523+ super().setUp()
1524 self.branch_set = BranchSet()
1525
1526 def test_getMergeProposals_with_no_merged_revno(self):
1527@@ -3549,7 +3549,7 @@ class TestWebservice(TestCaseWithFactory):
1528 layer = DatabaseFunctionalLayer
1529
1530 def setUp(self):
1531- super(TestWebservice, self).setUp()
1532+ super().setUp()
1533 self.branch_db = self.factory.makeBranch()
1534 self.branch_url = api_url(self.branch_db)
1535 self.webservice = webservice_for_person(
1536diff --git a/lib/lp/code/model/tests/test_branchcollection.py b/lib/lp/code/model/tests/test_branchcollection.py
1537index e66b16b..062a5ab 100644
1538--- a/lib/lp/code/model/tests/test_branchcollection.py
1539+++ b/lib/lp/code/model/tests/test_branchcollection.py
1540@@ -106,7 +106,7 @@ class TestGenericBranchCollection(TestCaseWithFactory):
1541 layer = DatabaseFunctionalLayer
1542
1543 def setUp(self):
1544- super(TestGenericBranchCollection, self).setUp()
1545+ super().setUp()
1546 remove_all_sample_data_branches()
1547 self.store = IStore(Branch)
1548
1549diff --git a/lib/lp/code/model/tests/test_branchhosting.py b/lib/lp/code/model/tests/test_branchhosting.py
1550index 1e1f874..0190806 100644
1551--- a/lib/lp/code/model/tests/test_branchhosting.py
1552+++ b/lib/lp/code/model/tests/test_branchhosting.py
1553@@ -12,7 +12,6 @@ import re
1554
1555 from lazr.restful.utils import get_current_browser_request
1556 import responses
1557-import six
1558 from testtools.matchers import MatchesStructure
1559 from zope.component import getUtility
1560 from zope.interface import implementer
1561@@ -47,7 +46,7 @@ class TestBranchHostingClient(TestCase):
1562 layer = ZopelessDatabaseLayer
1563
1564 def setUp(self):
1565- super(TestBranchHostingClient, self).setUp()
1566+ super().setUp()
1567 self.client = getUtility(IBranchHostingClient)
1568 self.endpoint = removeSecurityProxy(self.client).endpoint
1569 self.requests = []
1570@@ -155,14 +154,14 @@ class TestBranchHostingClient(TestCase):
1571 "+branch-id/123/+json/files/%2Brev%20id%3F/%2Bfile/%20name%3F")
1572
1573 def test_getBlob(self):
1574- blob = b"".join(six.int2byte(i) for i in range(256))
1575+ blob = b"".join(bytes((i,)) for i in range(256))
1576 with self.mockRequests("GET", body=blob):
1577 response = self.client.getBlob(123, "file-id")
1578 self.assertEqual(blob, response)
1579 self.assertRequest("+branch-id/123/download/head%3A/file-id")
1580
1581 def test_getBlob_revision(self):
1582- blob = b"".join(six.int2byte(i) for i in range(256))
1583+ blob = b"".join(bytes((i,)) for i in range(256))
1584 with self.mockRequests("GET", body=blob):
1585 response = self.client.getBlob(123, "file-id", rev="a")
1586 self.assertEqual(blob, response)
1587@@ -195,7 +194,7 @@ class TestBranchHostingClient(TestCase):
1588 self.client.getBlob, 123, "file-id")
1589
1590 def test_getBlob_url_quoting(self):
1591- blob = b"".join(six.int2byte(i) for i in range(256))
1592+ blob = b"".join(bytes((i,)) for i in range(256))
1593 with self.mockRequests("GET", body=blob):
1594 self.client.getBlob(123, "+file/ id?", rev="+rev id?")
1595 self.assertRequest(
1596@@ -203,12 +202,12 @@ class TestBranchHostingClient(TestCase):
1597
1598 def test_works_in_job(self):
1599 # `BranchHostingClient` is usable from a running job.
1600- blob = b"".join(six.int2byte(i) for i in range(256))
1601+ blob = b"".join(bytes((i,)) for i in range(256))
1602
1603 @implementer(IRunnableJob)
1604 class GetBlobJob(BaseRunnableJob):
1605 def __init__(self, testcase):
1606- super(GetBlobJob, self).__init__()
1607+ super().__init__()
1608 self.job = Job()
1609 self.testcase = testcase
1610
1611diff --git a/lib/lp/code/model/tests/test_branchjob.py b/lib/lp/code/model/tests/test_branchjob.py
1612index d3b7592..718df70 100644
1613--- a/lib/lp/code/model/tests/test_branchjob.py
1614+++ b/lib/lp/code/model/tests/test_branchjob.py
1615@@ -917,7 +917,7 @@ class TestRosettaUploadJob(TestCaseWithFactory):
1616 layer = LaunchpadZopelessLayer
1617
1618 def setUp(self):
1619- super(TestRosettaUploadJob, self).setUp()
1620+ super().setUp()
1621 self.series = None
1622
1623 def _makeBranchWithTreeAndFile(self, file_name, file_content=None):
1624diff --git a/lib/lp/code/model/tests/test_branchlistingqueryoptimiser.py b/lib/lp/code/model/tests/test_branchlistingqueryoptimiser.py
1625index 386bb4b..319476f 100644
1626--- a/lib/lp/code/model/tests/test_branchlistingqueryoptimiser.py
1627+++ b/lib/lp/code/model/tests/test_branchlistingqueryoptimiser.py
1628@@ -37,8 +37,7 @@ class TestGetProductSeriesForBranches(TestCaseWithFactory):
1629 def setUp(self):
1630 # Log in as an admin as we are setting series branches, which is a
1631 # protected activity.
1632- super(TestGetProductSeriesForBranches, self).setUp(
1633- 'admin@canonical.com')
1634+ super().setUp('admin@canonical.com')
1635 self.product = self.factory.makeProduct()
1636 self.branches = [
1637 self.factory.makeProductBranch(product=self.product)
1638@@ -114,8 +113,7 @@ class TestGetOfficialSourcePackageLinksForBranches(TestCaseWithFactory):
1639 def setUp(self):
1640 # Log in an admin as we are setting official branches, which is a
1641 # protected activity.
1642- super(TestGetOfficialSourcePackageLinksForBranches, self).setUp(
1643- 'admin@canonical.com')
1644+ super().setUp('admin@canonical.com')
1645
1646 def test_with_branches(self):
1647 # Test the selection of the links.
1648diff --git a/lib/lp/code/model/tests/test_branchmergeproposal.py b/lib/lp/code/model/tests/test_branchmergeproposal.py
1649index ed4fdd4..fd51edf 100644
1650--- a/lib/lp/code/model/tests/test_branchmergeproposal.py
1651+++ b/lib/lp/code/model/tests/test_branchmergeproposal.py
1652@@ -1027,7 +1027,7 @@ class TestMergeProposalWebhooks(WithVCSScenarios, TestCaseWithFactory):
1653 layer = DatabaseFunctionalLayer
1654
1655 def setUp(self):
1656- super(TestMergeProposalWebhooks, self).setUp()
1657+ super().setUp()
1658 self.useFixture(FeatureFixture(
1659 {BRANCH_MERGE_PROPOSAL_WEBHOOKS_FEATURE_FLAG: "on"}))
1660
1661@@ -1509,7 +1509,7 @@ class TestBranchMergeProposalBugs(WithVCSScenarios, TestCaseWithFactory):
1662 layer = DatabaseFunctionalLayer
1663
1664 def setUp(self):
1665- super(TestBranchMergeProposalBugs, self).setUp()
1666+ super().setUp()
1667 self.user = self.factory.makePerson()
1668 login_person(self.user)
1669 if self.git:
1670@@ -1690,16 +1690,15 @@ class TestBranchMergeProposalBugs(WithVCSScenarios, TestCaseWithFactory):
1671 bmp.updateRelatedBugsFromSource()
1672 self.assertEqual([bug], bmp.bugs)
1673 matches_expected_xref = MatchesDict(
1674- {("bug", six.text_type(bug.id)):
1675- ContainsDict({"metadata": Is(None)})})
1676+ {("bug", str(bug.id)): ContainsDict({"metadata": Is(None)})})
1677 self.assertThat(
1678 getUtility(IXRefSet).findFrom(
1679- ("merge_proposal", six.text_type(bmp.id)), types=["bug"]),
1680+ ("merge_proposal", str(bmp.id)), types=["bug"]),
1681 matches_expected_xref)
1682 self._setUpLog([bug])
1683 self.assertThat(
1684 getUtility(IXRefSet).findFrom(
1685- ("merge_proposal", six.text_type(bmp.id)), types=["bug"]),
1686+ ("merge_proposal", str(bmp.id)), types=["bug"]),
1687 matches_expected_xref)
1688
1689 def test_updateRelatedBugsFromSource_honours_limit(self):
1690@@ -2252,7 +2251,7 @@ class TestScheduleDiffUpdates(TestCaseWithFactory):
1691 layer = DatabaseFunctionalLayer
1692
1693 def setUp(self):
1694- super(TestScheduleDiffUpdates, self).setUp()
1695+ super().setUp()
1696 self.job_source = removeSecurityProxy(
1697 getUtility(IBranchMergeProposalJobSource))
1698
1699@@ -2511,7 +2510,7 @@ class TestBranchMergeProposalInlineComments(TestCaseWithFactory):
1700 layer = LaunchpadFunctionalLayer
1701
1702 def setUp(self):
1703- super(TestBranchMergeProposalInlineComments, self).setUp()
1704+ super().setUp()
1705 # Create a testing IPerson, IPreviewDiff and IBranchMergeProposal
1706 # for tests. Log in as the testing IPerson.
1707 self.person = self.factory.makePerson()
1708diff --git a/lib/lp/code/model/tests/test_branchmergeproposaljobs.py b/lib/lp/code/model/tests/test_branchmergeproposaljobs.py
1709index 53f293c..44f04fc 100644
1710--- a/lib/lp/code/model/tests/test_branchmergeproposaljobs.py
1711+++ b/lib/lp/code/model/tests/test_branchmergeproposaljobs.py
1712@@ -197,8 +197,7 @@ class TestMergeProposalNeedsReviewEmailJobBzr(
1713
1714 def test_run_sends_email(self):
1715 self.useBzrBranches(direct_database=True)
1716- parent = super(TestMergeProposalNeedsReviewEmailJobBzr, self)
1717- parent.test_run_sends_email()
1718+ super().test_run_sends_email()
1719
1720 def test_MergeProposalCreateJob_with_sourcepackage_branch(self):
1721 """Jobs for merge proposals with sourcepackage branches work."""
1722diff --git a/lib/lp/code/model/tests/test_branchnamespace.py b/lib/lp/code/model/tests/test_branchnamespace.py
1723index 1c10d07..d0dad62 100644
1724--- a/lib/lp/code/model/tests/test_branchnamespace.py
1725+++ b/lib/lp/code/model/tests/test_branchnamespace.py
1726@@ -3,7 +3,6 @@
1727
1728 """Tests for `IBranchNamespace` implementations."""
1729
1730-import six
1731 from zope.component import getUtility
1732 from zope.security.proxy import removeSecurityProxy
1733
1734@@ -1106,7 +1105,7 @@ class BaseValidateNewBranchMixin:
1735 def test_permitted_first_character(self):
1736 # The first character of a branch name must be a letter or a number.
1737 namespace = self._getNamespace(self.factory.makePerson())
1738- for c in [six.unichr(i) for i in range(128)]:
1739+ for c in [chr(i) for i in range(128)]:
1740 if c.isalnum():
1741 namespace.validateBranchName(c)
1742 else:
1743@@ -1118,7 +1117,7 @@ class BaseValidateNewBranchMixin:
1744 # After the first character, letters, numbers and certain punctuation
1745 # is permitted.
1746 namespace = self._getNamespace(self.factory.makePerson())
1747- for c in [six.unichr(i) for i in range(128)]:
1748+ for c in [chr(i) for i in range(128)]:
1749 if c.isalnum() or c in '+-_@.':
1750 namespace.validateBranchName('a' + c)
1751 else:
1752diff --git a/lib/lp/code/model/tests/test_codeimport.py b/lib/lp/code/model/tests/test_codeimport.py
1753index 3af5208..4f9a355 100644
1754--- a/lib/lp/code/model/tests/test_codeimport.py
1755+++ b/lib/lp/code/model/tests/test_codeimport.py
1756@@ -85,7 +85,7 @@ class TestCodeImportBase(WithScenarios, TestCaseWithFactory):
1757 ]
1758
1759 def setUp(self, *args, **kwargs):
1760- super(TestCodeImportBase, self).setUp(*args, **kwargs)
1761+ super().setUp(*args, **kwargs)
1762 if self.needs_git_hosting_fixture:
1763 self.hosting_fixture = self.useFixture(GitHostingFixture())
1764
1765@@ -372,8 +372,7 @@ class TestCodeImportStatusUpdate(TestCodeImportBase):
1766
1767 def setUp(self):
1768 # Log in a VCS Imports member.
1769- super(TestCodeImportStatusUpdate, self).setUp(
1770- 'david.allouche@canonical.com')
1771+ super().setUp('david.allouche@canonical.com')
1772 self.import_operator = getUtility(IPersonSet).getByEmail(
1773 'david.allouche@canonical.com')
1774 # Remove existing jobs.
1775@@ -505,12 +504,12 @@ class TestCodeImportResultsAttribute(TestCodeImportBase):
1776 layer = LaunchpadFunctionalLayer
1777
1778 def setUp(self):
1779- super(TestCodeImportResultsAttribute, self).setUp()
1780+ super().setUp()
1781 self.code_import = self.factory.makeCodeImport(
1782 target_rcs_type=self.target_rcs_type)
1783
1784 def tearDown(self):
1785- super(TestCodeImportResultsAttribute, self).tearDown()
1786+ super().tearDown()
1787 logout()
1788
1789 def test_no_results(self):
1790@@ -571,7 +570,7 @@ class TestConsecutiveFailureCount(TestCodeImportBase):
1791 layer = LaunchpadZopelessLayer
1792
1793 def setUp(self):
1794- super(TestConsecutiveFailureCount, self).setUp()
1795+ super().setUp()
1796 login('no-priv@canonical.com')
1797 self.machine = self.factory.makeCodeImportMachine()
1798 self.machine.setOnline()
1799@@ -713,7 +712,7 @@ class TestTryFailingImportAgain(TestCodeImportBase):
1800
1801 def setUp(self):
1802 # Log in a VCS Imports member.
1803- super(TestTryFailingImportAgain, self).setUp()
1804+ super().setUp()
1805 login_person(getUtility(ILaunchpadCelebrities).vcs_imports.teamowner)
1806
1807 def test_mustBeFailing(self):
1808@@ -772,7 +771,7 @@ class TestRequestImport(TestCodeImportBase):
1809
1810 def setUp(self):
1811 # We have to be logged in to request imports
1812- super(TestRequestImport, self).setUp(user='no-priv@canonical.com')
1813+ super().setUp(user='no-priv@canonical.com')
1814
1815 def test_requestsJob(self):
1816 code_import = self.factory.makeCodeImport(
1817diff --git a/lib/lp/code/model/tests/test_codeimportjob.py b/lib/lp/code/model/tests/test_codeimportjob.py
1818index d2785a6..72076a2 100644
1819--- a/lib/lp/code/model/tests/test_codeimportjob.py
1820+++ b/lib/lp/code/model/tests/test_codeimportjob.py
1821@@ -97,7 +97,7 @@ class TestCodeImportJob(TestCaseWithFactory):
1822 layer = DatabaseFunctionalLayer
1823
1824 def setUp(self):
1825- super(TestCodeImportJob, self).setUp()
1826+ super().setUp()
1827 login_for_code_imports()
1828
1829 def assertArgumentsMatch(self, code_import, matcher, start_job=False):
1830@@ -211,7 +211,7 @@ class TestCodeImportJobSet(TestCaseWithFactory):
1831 layer = DatabaseFunctionalLayer
1832
1833 def setUp(self):
1834- super(TestCodeImportJobSet, self).setUp()
1835+ super().setUp()
1836 login_for_code_imports()
1837
1838 def test_getByIdExisting(self):
1839@@ -256,7 +256,7 @@ class TestCodeImportJobSetGetJobForMachine(TestCaseWithFactory):
1840 def setUp(self):
1841 # Login so we can access the code import system, delete all jobs in
1842 # the sample data and set up some objects.
1843- super(TestCodeImportJobSetGetJobForMachine, self).setUp()
1844+ super().setUp()
1845 login_for_code_imports()
1846 for job in IStore(CodeImportJob).find(CodeImportJob):
1847 job.destroySelf()
1848@@ -370,7 +370,7 @@ class ReclaimableJobTests(TestCaseWithFactory):
1849 LIMIT = config.codeimportworker.maximum_heartbeat_interval
1850
1851 def setUp(self):
1852- super(ReclaimableJobTests, self).setUp()
1853+ super().setUp()
1854 login_for_code_imports()
1855 for job in IStore(CodeImportJob).find(CodeImportJob):
1856 job.destroySelf()
1857@@ -461,7 +461,7 @@ class AssertFailureMixin:
1858 self.fail("AssertionError was not raised")
1859
1860
1861-class NewEvents(object):
1862+class NewEvents:
1863 """Help in testing the creation of CodeImportEvent objects.
1864
1865 To test that an operation creates CodeImportEvent objects, create an
1866@@ -527,7 +527,7 @@ class TestCodeImportJobWorkflowNewJob(TestCaseWithFactory,
1867 layer = DatabaseFunctionalLayer
1868
1869 def setUp(self):
1870- super(TestCodeImportJobWorkflowNewJob, self).setUp()
1871+ super().setUp()
1872 login_for_code_imports()
1873
1874 def test_wrongReviewStatus(self):
1875@@ -631,7 +631,7 @@ class TestCodeImportJobWorkflowDeletePendingJob(TestCaseWithFactory,
1876 layer = DatabaseFunctionalLayer
1877
1878 def setUp(self):
1879- super(TestCodeImportJobWorkflowDeletePendingJob, self).setUp()
1880+ super().setUp()
1881 self.import_admin = login_for_code_imports()
1882
1883 def test_wrongReviewStatus(self):
1884@@ -687,7 +687,7 @@ class TestCodeImportJobWorkflowRequestJob(TestCaseWithFactory,
1885 layer = DatabaseFunctionalLayer
1886
1887 def setUp(self):
1888- super(TestCodeImportJobWorkflowRequestJob, self).setUp()
1889+ super().setUp()
1890 login_for_code_imports()
1891
1892 def test_wrongJobState(self):
1893@@ -779,7 +779,7 @@ class TestCodeImportJobWorkflowStartJob(TestCaseWithFactory,
1894 layer = DatabaseFunctionalLayer
1895
1896 def setUp(self):
1897- super(TestCodeImportJobWorkflowStartJob, self).setUp()
1898+ super().setUp()
1899 login_for_code_imports()
1900
1901 def test_wrongJobState(self):
1902@@ -832,7 +832,7 @@ class TestCodeImportJobWorkflowUpdateHeartbeat(TestCaseWithFactory,
1903 layer = DatabaseFunctionalLayer
1904
1905 def setUp(self):
1906- super(TestCodeImportJobWorkflowUpdateHeartbeat, self).setUp()
1907+ super().setUp()
1908 login_for_code_imports()
1909
1910 def test_wrongJobState(self):
1911@@ -867,7 +867,7 @@ class TestCodeImportJobWorkflowFinishJob(TestCaseWithFactory,
1912 layer = LaunchpadFunctionalLayer
1913
1914 def setUp(self):
1915- super(TestCodeImportJobWorkflowFinishJob, self).setUp()
1916+ super().setUp()
1917 self.vcs_imports = login_for_code_imports()
1918 self.machine = self.factory.makeCodeImportMachine(set_online=True)
1919
1920@@ -1165,7 +1165,7 @@ class TestCodeImportJobWorkflowReclaimJob(TestCaseWithFactory,
1921 layer = DatabaseFunctionalLayer
1922
1923 def setUp(self):
1924- super(TestCodeImportJobWorkflowReclaimJob, self).setUp()
1925+ super().setUp()
1926 login_for_code_imports()
1927 self.machine = self.factory.makeCodeImportMachine(set_online=True)
1928
1929@@ -1300,7 +1300,7 @@ class TestCodeImportJobMacaroonIssuer(MacaroonTestMixin, TestCaseWithFactory):
1930 layer = DatabaseFunctionalLayer
1931
1932 def setUp(self):
1933- super(TestCodeImportJobMacaroonIssuer, self).setUp()
1934+ super().setUp()
1935 login_for_code_imports()
1936 self.pushConfig(
1937 "launchpad", internal_macaroon_secret_key="some-secret")
1938diff --git a/lib/lp/code/model/tests/test_codeimportmachine.py b/lib/lp/code/model/tests/test_codeimportmachine.py
1939index 1070610..70fcea3 100644
1940--- a/lib/lp/code/model/tests/test_codeimportmachine.py
1941+++ b/lib/lp/code/model/tests/test_codeimportmachine.py
1942@@ -23,8 +23,7 @@ class TestCodeImportMachineShouldLookForJob(TestCaseWithFactory):
1943 layer = DatabaseFunctionalLayer
1944
1945 def setUp(self):
1946- super(TestCodeImportMachineShouldLookForJob, self).setUp(
1947- 'admin@canonical.com')
1948+ super().setUp('admin@canonical.com')
1949 self.machine = self.factory.makeCodeImportMachine(set_online=True)
1950
1951 def createJobRunningOnMachine(self, machine):
1952diff --git a/lib/lp/code/model/tests/test_codereviewkarma.py b/lib/lp/code/model/tests/test_codereviewkarma.py
1953index 5b3027b..846d05d 100644
1954--- a/lib/lp/code/model/tests/test_codereviewkarma.py
1955+++ b/lib/lp/code/model/tests/test_codereviewkarma.py
1956@@ -27,7 +27,7 @@ class TestCodeReviewKarma(TestCaseWithFactory):
1957 def setUp(self):
1958 # Use an admin to get launchpad.Edit on all the branches to easily
1959 # approve and reject the proposals.
1960- super(TestCodeReviewKarma, self).setUp('admin@canonical.com')
1961+ super().setUp('admin@canonical.com')
1962 self.useFixture(ZopeEventHandlerFixture(
1963 self._on_karma_assigned, (IPerson, IKarmaAssignedEvent)))
1964 self.karma_events = []
1965diff --git a/lib/lp/code/model/tests/test_gitcollection.py b/lib/lp/code/model/tests/test_gitcollection.py
1966index b3250f7..f9fdbe8 100644
1967--- a/lib/lp/code/model/tests/test_gitcollection.py
1968+++ b/lib/lp/code/model/tests/test_gitcollection.py
1969@@ -120,7 +120,7 @@ class TestGenericGitCollection(TestCaseWithFactory):
1970 layer = DatabaseFunctionalLayer
1971
1972 def setUp(self):
1973- super(TestGenericGitCollection, self).setUp()
1974+ super().setUp()
1975 self.store = IStore(GitRepository)
1976
1977 def test_provides_gitcollection(self):
1978diff --git a/lib/lp/code/model/tests/test_githosting.py b/lib/lp/code/model/tests/test_githosting.py
1979index 3ca4fdc..aa3c671 100644
1980--- a/lib/lp/code/model/tests/test_githosting.py
1981+++ b/lib/lp/code/model/tests/test_githosting.py
1982@@ -14,7 +14,6 @@ import re
1983
1984 from lazr.restful.utils import get_current_browser_request
1985 import responses
1986-import six
1987 from six.moves.urllib.parse import (
1988 parse_qsl,
1989 urlsplit,
1990@@ -69,7 +68,7 @@ class MatchesURL(AfterPreprocessing):
1991 lambda qs: sorted(parse_qsl(qs)),
1992 MatchesListwise(
1993 [Equals(pair) for pair in sorted(parse_qsl(split_url.query))]))
1994- super(MatchesURL, self).__init__(
1995+ super().__init__(
1996 urlsplit, MatchesStructure(
1997 scheme=Equals(split_url.scheme),
1998 netloc=Equals(split_url.netloc),
1999@@ -83,7 +82,7 @@ class TestGitHostingClient(TestCase):
2000 layer = ZopelessDatabaseLayer
2001
2002 def setUp(self):
2003- super(TestGitHostingClient, self).setUp()
2004+ super().setUp()
2005 self.client = getUtility(IGitHostingClient)
2006 self.endpoint = removeSecurityProxy(self.client).endpoint
2007 self.requests = []
2008@@ -331,7 +330,7 @@ class TestGitHostingClient(TestCase):
2009 self.client.delete, "123")
2010
2011 def test_getBlob(self):
2012- blob = b''.join(six.int2byte(i) for i in range(256))
2013+ blob = b''.join(bytes((i,)) for i in range(256))
2014 payload = {
2015 "data": base64.b64encode(blob).decode("UTF-8"),
2016 "size": len(blob),
2017@@ -343,7 +342,7 @@ class TestGitHostingClient(TestCase):
2018 "repo/123/blob/dir/path/file/name", method="GET")
2019
2020 def test_getBlob_revision(self):
2021- blob = b''.join(six.int2byte(i) for i in range(256))
2022+ blob = b''.join(bytes((i,)) for i in range(256))
2023 payload = {
2024 "data": base64.b64encode(blob).decode("UTF-8"),
2025 "size": len(blob),
2026@@ -378,7 +377,7 @@ class TestGitHostingClient(TestCase):
2027 self.client.getBlob, "123", "dir/path/file/name")
2028
2029 def test_getBlob_url_quoting(self):
2030- blob = b''.join(six.int2byte(i) for i in range(256))
2031+ blob = b''.join(bytes((i,)) for i in range(256))
2032 payload = {
2033 "data": base64.b64encode(blob).decode("UTF-8"),
2034 "size": len(blob),
2035@@ -411,7 +410,7 @@ class TestGitHostingClient(TestCase):
2036 self.client.getBlob, "123", "dir/path/file/name")
2037
2038 def test_getBlob_wrong_size(self):
2039- blob = b''.join(six.int2byte(i) for i in range(256))
2040+ blob = b''.join(bytes((i,)) for i in range(256))
2041 payload = {"data": base64.b64encode(blob).decode("UTF-8"), "size": 0}
2042 with self.mockRequests("GET", json=payload):
2043 self.assertRaisesWithContent(
2044@@ -465,7 +464,7 @@ class TestGitHostingClient(TestCase):
2045 @implementer(IRunnableJob)
2046 class GetRefsJob(BaseRunnableJob):
2047 def __init__(self, testcase):
2048- super(GetRefsJob, self).__init__()
2049+ super().__init__()
2050 self.job = Job()
2051 self.testcase = testcase
2052
2053diff --git a/lib/lp/code/model/tests/test_gitlookup.py b/lib/lp/code/model/tests/test_gitlookup.py
2054index 0f8b8fe..8914d4c 100644
2055--- a/lib/lp/code/model/tests/test_gitlookup.py
2056+++ b/lib/lp/code/model/tests/test_gitlookup.py
2057@@ -38,7 +38,7 @@ class TestGetByHostingPath(TestCaseWithFactory):
2058 layer = DatabaseFunctionalLayer
2059
2060 def setUp(self):
2061- super(TestGetByHostingPath, self).setUp()
2062+ super().setUp()
2063 self.lookup = getUtility(IGitLookup)
2064
2065 def test_exists(self):
2066@@ -57,7 +57,7 @@ class TestGetByUniqueName(TestCaseWithFactory):
2067 layer = DatabaseFunctionalLayer
2068
2069 def setUp(self):
2070- super(TestGetByUniqueName, self).setUp()
2071+ super().setUp()
2072 self.lookup = getUtility(IGitLookup)
2073
2074 def test_not_found(self):
2075@@ -121,7 +121,7 @@ class TestGetByPath(TestCaseWithFactory):
2076 layer = DatabaseFunctionalLayer
2077
2078 def setUp(self):
2079- super(TestGetByPath, self).setUp()
2080+ super().setUp()
2081 self.lookup = getUtility(IGitLookup)
2082
2083 def test_project(self):
2084@@ -213,7 +213,7 @@ class TestGetByUrl(TestCaseWithFactory):
2085 layer = DatabaseFunctionalLayer
2086
2087 def setUp(self):
2088- super(TestGetByUrl, self).setUp()
2089+ super().setUp()
2090 self.lookup = getUtility(IGitLookup)
2091
2092 def makeProjectRepository(self):
2093@@ -309,7 +309,7 @@ class TestGitTraverser(TestCaseWithFactory):
2094 layer = DatabaseFunctionalLayer
2095
2096 def setUp(self):
2097- super(TestGitTraverser, self).setUp()
2098+ super().setUp()
2099 self.traverser = getUtility(IGitTraverser)
2100
2101 def assertTraverses(self, path, owner, target, repository=None):
2102diff --git a/lib/lp/code/model/tests/test_gitnamespace.py b/lib/lp/code/model/tests/test_gitnamespace.py
2103index 3c4ac13..eb11aa9 100644
2104--- a/lib/lp/code/model/tests/test_gitnamespace.py
2105+++ b/lib/lp/code/model/tests/test_gitnamespace.py
2106@@ -5,7 +5,6 @@
2107
2108 from unittest import mock
2109
2110-import six
2111 from zope.component import getUtility
2112 from zope.security.proxy import removeSecurityProxy
2113
2114@@ -954,8 +953,7 @@ class TestProjectGitNamespaceCanCreateBranches(
2115
2116 def setUp(self):
2117 # Setting visibility policies is an admin-only task.
2118- super(TestProjectGitNamespaceCanCreateBranches, self).setUp(
2119- "admin@canonical.com")
2120+ super().setUp("admin@canonical.com")
2121
2122 def test_any_person(self):
2123 # If there is no privacy set up, any person can create a personal
2124@@ -1117,7 +1115,7 @@ class BaseValidateNewRepositoryMixin:
2125 # The first character of a repository name must be a letter or a
2126 # number.
2127 namespace = self._getNamespace(self.factory.makePerson())
2128- for c in [six.unichr(i) for i in range(128)]:
2129+ for c in [chr(i) for i in range(128)]:
2130 if c.isalnum():
2131 namespace.validateRepositoryName(c)
2132 else:
2133@@ -1129,7 +1127,7 @@ class BaseValidateNewRepositoryMixin:
2134 # After the first character, letters, numbers and certain
2135 # punctuation is permitted.
2136 namespace = self._getNamespace(self.factory.makePerson())
2137- for c in [six.unichr(i) for i in range(128)]:
2138+ for c in [chr(i) for i in range(128)]:
2139 if c.isalnum() or c in "+-_@.":
2140 namespace.validateRepositoryName("a" + c)
2141 else:
2142diff --git a/lib/lp/code/model/tests/test_gitref.py b/lib/lp/code/model/tests/test_gitref.py
2143index b97e345..f18287a 100644
2144--- a/lib/lp/code/model/tests/test_gitref.py
2145+++ b/lib/lp/code/model/tests/test_gitref.py
2146@@ -159,7 +159,7 @@ class TestGitRefGetCommits(TestCaseWithFactory):
2147 layer = LaunchpadFunctionalLayer
2148
2149 def setUp(self):
2150- super(TestGitRefGetCommits, self).setUp()
2151+ super().setUp()
2152 [self.ref] = self.factory.makeGitRefs()
2153 self.authors = [self.factory.makePerson() for _ in range(2)]
2154 with admin_logged_in():
2155@@ -492,7 +492,7 @@ class TestGitRefCreateMergeProposal(TestCaseWithFactory):
2156 layer = DatabaseFunctionalLayer
2157
2158 def setUp(self):
2159- super(TestGitRefCreateMergeProposal, self).setUp()
2160+ super().setUp()
2161 with admin_logged_in():
2162 self.project = self.factory.makeProduct()
2163 self.user = self.factory.makePerson()
2164diff --git a/lib/lp/code/model/tests/test_gitrepository.py b/lib/lp/code/model/tests/test_gitrepository.py
2165index 6a759be..6155836 100644
2166--- a/lib/lp/code/model/tests/test_gitrepository.py
2167+++ b/lib/lp/code/model/tests/test_gitrepository.py
2168@@ -601,7 +601,7 @@ class TestGitIdentityMixin(TestCaseWithFactory):
2169 layer = DatabaseFunctionalLayer
2170
2171 def setUp(self):
2172- super(TestGitIdentityMixin, self).setUp()
2173+ super().setUp()
2174 self.repository_set = getUtility(IGitRepositorySet)
2175
2176 def assertGitIdentity(self, repository, identity_path):
2177@@ -792,7 +792,7 @@ class TestGitRepositoryDeletion(TestCaseWithFactory):
2178 layer = LaunchpadFunctionalLayer
2179
2180 def setUp(self):
2181- super(TestGitRepositoryDeletion, self).setUp()
2182+ super().setUp()
2183 self.user = self.factory.makePerson()
2184 self.project = self.factory.makeProduct(owner=self.user)
2185 self.repository = self.factory.makeGitRepository(
2186@@ -1001,8 +1001,7 @@ class TestGitRepositoryDeletionConsequences(TestCaseWithFactory):
2187 layer = ZopelessDatabaseLayer
2188
2189 def setUp(self):
2190- super(TestGitRepositoryDeletionConsequences, self).setUp(
2191- user="test@canonical.com")
2192+ super().setUp(user="test@canonical.com")
2193 self.repository = self.factory.makeGitRepository()
2194 [self.ref] = self.factory.makeGitRefs(repository=self.repository)
2195 # The owner of the repository is subscribed to the repository when
2196@@ -1537,7 +1536,7 @@ class TestGitRepositoryPrivacy(TestCaseWithFactory):
2197
2198 def setUp(self):
2199 # Use an admin user as we aren't checking edit permissions here.
2200- super(TestGitRepositoryPrivacy, self).setUp("admin@canonical.com")
2201+ super().setUp("admin@canonical.com")
2202
2203 def test_personal_repositories_for_private_teams_are_private(self):
2204 team = self.factory.makeTeam(
2205@@ -2865,7 +2864,7 @@ class TestGitRepositoryFork(TestCaseWithFactory):
2206 layer = DatabaseFunctionalLayer
2207
2208 def setUp(self):
2209- super(TestGitRepositoryFork, self).setUp()
2210+ super().setUp()
2211 self.hosting_fixture = self.useFixture(GitHostingFixture())
2212
2213 def test_fork(self):
2214@@ -3474,7 +3473,7 @@ class TestGitRepositorySet(TestCaseWithFactory):
2215 layer = DatabaseFunctionalLayer
2216
2217 def setUp(self):
2218- super(TestGitRepositorySet, self).setUp()
2219+ super().setUp()
2220 self.repository_set = getUtility(IGitRepositorySet)
2221
2222 def test_new(self):
2223@@ -3775,7 +3774,7 @@ class TestGitRepositorySetDefaultsMixin:
2224 layer = DatabaseFunctionalLayer
2225
2226 def setUp(self):
2227- super(TestGitRepositorySetDefaultsMixin, self).setUp()
2228+ super().setUp()
2229 self.repository_set = getUtility(IGitRepositorySet)
2230 self.get_method = self.repository_set.getDefaultRepository
2231 self.set_method = (lambda target, repository, user:
2232@@ -3857,7 +3856,7 @@ class TestGitRepositorySetDefaultsOwnerMixin(
2233 TestGitRepositorySetDefaultsMixin):
2234
2235 def setUp(self):
2236- super(TestGitRepositorySetDefaultsOwnerMixin, self).setUp()
2237+ super().setUp()
2238 self.person = self.factory.makePerson()
2239 self.get_method = partial(
2240 self.repository_set.getDefaultRepositoryForOwner, self.person)
2241@@ -4098,7 +4097,7 @@ class TestGitRepositoryWebservice(TestCaseWithFactory):
2242 self.assertNewWorks(self.factory.makePerson())
2243
2244 def test_new_repo_not_owner(self):
2245- non_ascii_name = u'AndrƩ Luƭs Lopes'
2246+ non_ascii_name = 'AndrƩ Luƭs Lopes'
2247 other_user = self.factory.makePerson(displayname=non_ascii_name)
2248 owner_url = api_url(other_user)
2249 webservice_user = self.factory.makePerson()
2250@@ -4109,8 +4108,8 @@ class TestGitRepositoryWebservice(TestCaseWithFactory):
2251 response = webservice.named_post(
2252 "/+git", "new", owner=owner_url, target=owner_url, name=name)
2253 self.assertEqual(400, response.status)
2254- self.assertIn(u'cannot create Git repositories owned by'
2255- u' AndrƩ Luƭs Lopes', response.body.decode('utf-8'))
2256+ self.assertIn('cannot create Git repositories owned by'
2257+ ' AndrƩ Luƭs Lopes', response.body.decode('utf-8'))
2258
2259 def assertGetRepositoriesWorks(self, target_db):
2260 if IPerson.providedBy(target_db):
2261@@ -4978,7 +4977,7 @@ class TestRevisionStatusReportWebservice(TestCaseWithFactory):
2262 layer = LaunchpadFunctionalLayer
2263
2264 def setUp(self):
2265- super(TestRevisionStatusReportWebservice, self).setUp()
2266+ super().setUp()
2267 self.repository = self.factory.makeGitRepository()
2268 self.requester = self.repository.owner
2269 title = self.factory.getUniqueUnicode('report-title')
2270@@ -5034,7 +5033,7 @@ class TestGitRepositoryMacaroonIssuer(MacaroonTestMixin, TestCaseWithFactory):
2271 layer = DatabaseFunctionalLayer
2272
2273 def setUp(self):
2274- super(TestGitRepositoryMacaroonIssuer, self).setUp()
2275+ super().setUp()
2276 self.pushConfig("codehosting", git_macaroon_secret_key="some-secret")
2277
2278 def test_issueMacaroon_refuses_branch(self):
2279diff --git a/lib/lp/code/model/tests/test_revision.py b/lib/lp/code/model/tests/test_revision.py
2280index 957f2ca..bdd0f7a 100644
2281--- a/lib/lp/code/model/tests/test_revision.py
2282+++ b/lib/lp/code/model/tests/test_revision.py
2283@@ -204,7 +204,7 @@ class TestRevisionSet(TestCaseWithFactory):
2284 layer = DatabaseFunctionalLayer
2285
2286 def setUp(self):
2287- super(TestRevisionSet, self).setUp()
2288+ super().setUp()
2289 self.revision_set = getUtility(IRevisionSet)
2290
2291 def test_getRevisionById_existing(self):
2292diff --git a/lib/lp/code/model/tests/test_revisionauthor.py b/lib/lp/code/model/tests/test_revisionauthor.py
2293index 4953571..9941c7f 100644
2294--- a/lib/lp/code/model/tests/test_revisionauthor.py
2295+++ b/lib/lp/code/model/tests/test_revisionauthor.py
2296@@ -35,7 +35,7 @@ class TestRevisionEmailExtraction(TestCase):
2297 layer = LaunchpadZopelessLayer
2298
2299 def setUp(self):
2300- super(TestRevisionEmailExtraction, self).setUp()
2301+ super().setUp()
2302 switch_dbuser("branchscanner")
2303
2304 def test_email_extracted_from_name(self):
2305@@ -134,7 +134,7 @@ class TestNewlyValidatedEmailsLinkRevisionAuthors(MakeHarryTestCase):
2306
2307 def setUp(self):
2308 # Create a revision author that doesn't have a user yet.
2309- super(TestNewlyValidatedEmailsLinkRevisionAuthors, self).setUp()
2310+ super().setUp()
2311 with dbuser("branchscanner"):
2312 self.author = RevisionSet()._createRevisionAuthor(
2313 '"Harry Potter" <harry@canonical.com>')
2314@@ -171,35 +171,35 @@ class TestRevisionAuthor(TestCase):
2315 layer = LaunchpadZopelessLayer
2316
2317 def setUp(self):
2318- super(TestRevisionAuthor, self).setUp()
2319+ super().setUp()
2320 switch_dbuser("branchscanner")
2321
2322 def testGetNameWithoutEmailReturnsNamePart(self):
2323 # name_without_email is equal to the 'name' part of the revision
2324 # author information.
2325- author = RevisionAuthor(name=u'Jonathan Lange <jml@canonical.com>')
2326- self.assertEqual(u'Jonathan Lange', author.name_without_email)
2327+ author = RevisionAuthor(name='Jonathan Lange <jml@canonical.com>')
2328+ self.assertEqual('Jonathan Lange', author.name_without_email)
2329
2330 def testGetNameWithoutEmailWithNoName(self):
2331 # If there is no name in the revision author information,
2332 # name_without_email is an empty string.
2333- author = RevisionAuthor(name=u'jml@mumak.net')
2334+ author = RevisionAuthor(name='jml@mumak.net')
2335 self.assertEqual('', author.name_without_email)
2336
2337 def testGetNameWithoutEmailWithNoEmail(self):
2338 # If there is no email in the revision author information,
2339 # name_without_email is the name.
2340- author = RevisionAuthor(name=u'Jonathan Lange')
2341+ author = RevisionAuthor(name='Jonathan Lange')
2342 self.assertEqual('Jonathan Lange', author.name_without_email)
2343
2344 def testGetNameWithoutEmailWithOneWord(self):
2345 # If there is no email in the revision author information,
2346 # name_without_email is the name.
2347- author = RevisionAuthor(name=u'Jonathan.Lange')
2348+ author = RevisionAuthor(name='Jonathan.Lange')
2349 self.assertEqual('Jonathan.Lange', author.name_without_email)
2350
2351 def testGetNameWithoutEmailWithBadEmail(self):
2352 # If there is an invalid email in the revision author information,
2353 # name_without_email is an empty string.
2354- author = RevisionAuthor(name=u'jml@localhost')
2355+ author = RevisionAuthor(name='jml@localhost')
2356 self.assertEqual('', author.name_without_email)
2357diff --git a/lib/lp/code/model/tests/test_sourcepackagerecipe.py b/lib/lp/code/model/tests/test_sourcepackagerecipe.py
2358index 719ab3b..4837166 100644
2359--- a/lib/lp/code/model/tests/test_sourcepackagerecipe.py
2360+++ b/lib/lp/code/model/tests/test_sourcepackagerecipe.py
2361@@ -859,7 +859,7 @@ class TestRecipeBranchRoundTrippingMixin:
2362 layer = DatabaseFunctionalLayer
2363
2364 def setUp(self):
2365- super(TestRecipeBranchRoundTrippingMixin, self).setUp()
2366+ super().setUp()
2367 self.base_branch = self.makeBranch()
2368 self.nested_branch = self.makeBranch()
2369 self.merged_branch = self.makeBranch()
2370diff --git a/lib/lp/code/scripts/repackgitrepository.py b/lib/lp/code/scripts/repackgitrepository.py
2371index 9a202a4..6c880da 100644
2372--- a/lib/lp/code/scripts/repackgitrepository.py
2373+++ b/lib/lp/code/scripts/repackgitrepository.py
2374@@ -6,7 +6,6 @@
2375 from datetime import timedelta
2376
2377 from psycopg2.extensions import TransactionRollbackError
2378-import six
2379 from storm.expr import (
2380 Cast,
2381 Or,
2382@@ -33,7 +32,7 @@ class RepackTunableLoop(TunableLoop):
2383 targets = 1000
2384
2385 def __init__(self, log, dry_run, abort_time=None):
2386- super(RepackTunableLoop, self).__init__(log, abort_time)
2387+ super().__init__(log, abort_time)
2388 self.dry_run = dry_run
2389 self.start_at = 0
2390 self.logger = log
2391@@ -103,7 +102,7 @@ class RepackTunableLoop(TunableLoop):
2392 except TransactionRollbackError as error:
2393 self.logger.error(
2394 'An error occurred while requesting repository repack %s'
2395- % six.text_type(error))
2396+ % str(error))
2397 if transaction is not None:
2398 transaction.abort()
2399 continue
2400diff --git a/lib/lp/code/scripts/tests/test_repack_git_repositories.py b/lib/lp/code/scripts/tests/test_repack_git_repositories.py
2401index 9314997..77d1fad 100644
2402--- a/lib/lp/code/scripts/tests/test_repack_git_repositories.py
2403+++ b/lib/lp/code/scripts/tests/test_repack_git_repositories.py
2404@@ -52,7 +52,7 @@ class FakeTurnipServer(threading.Thread):
2405 """Thread that runs a fake turnip server."""
2406
2407 def __init__(self):
2408- super(FakeTurnipServer, self).__init__()
2409+ super().__init__()
2410 self.name = 'FakeTurnipServer'
2411 self.app = FakeTurnipApplication()
2412 self.server = make_server(
2413@@ -74,7 +74,7 @@ class TestRequestGitRepack(TestCaseWithFactory):
2414 layer = ZopelessAppServerLayer
2415
2416 def setUp(self):
2417- super(TestRequestGitRepack, self).setUp()
2418+ super().setUp()
2419 self.log = logging.getLogger('repack')
2420
2421 def runScript_no_Turnip(self):
2422diff --git a/lib/lp/code/scripts/tests/test_request_daily_builds.py b/lib/lp/code/scripts/tests/test_request_daily_builds.py
2423index d1ac03a..0d9b970 100644
2424--- a/lib/lp/code/scripts/tests/test_request_daily_builds.py
2425+++ b/lib/lp/code/scripts/tests/test_request_daily_builds.py
2426@@ -102,7 +102,7 @@ class FakeLoggerheadServer(threading.Thread):
2427 """Thread that runs a fake loggerhead server."""
2428
2429 def __init__(self):
2430- super(FakeLoggerheadServer, self).__init__()
2431+ super().__init__()
2432 self.app = FakeLoggerheadApplication()
2433 self.server = make_server(
2434 'localhost', 0, self.app, handler_class=SilentWSGIRequestHandler)
2435@@ -162,7 +162,7 @@ class FakeTurnipServer(threading.Thread):
2436 """Thread that runs a fake turnip server."""
2437
2438 def __init__(self):
2439- super(FakeTurnipServer, self).__init__()
2440+ super().__init__()
2441 self.app = FakeTurnipApplication()
2442 self.server = make_server(
2443 'localhost', 0, self.app, handler_class=SilentWSGIRequestHandler)
2444@@ -186,7 +186,7 @@ class TestRequestDailyBuilds(TestCaseWithFactory):
2445 layer = ZopelessAppServerLayer
2446
2447 def setUp(self):
2448- super(TestRequestDailyBuilds, self).setUp()
2449+ super().setUp()
2450 features = dict(SNAP_TESTING_FLAGS)
2451 features[CHARM_RECIPE_ALLOW_CREATE] = "on"
2452 self.useFixture(FeatureFixture(features))
2453diff --git a/lib/lp/code/tests/helpers.py b/lib/lp/code/tests/helpers.py
2454index a240ab4..f566b60 100644
2455--- a/lib/lp/code/tests/helpers.py
2456+++ b/lib/lp/code/tests/helpers.py
2457@@ -150,8 +150,7 @@ def consistent_branch_names():
2458
2459 This generator does not finish!
2460 """
2461- for name in ['trunk', 'testing', 'feature-x', 'feature-y', 'feature-z']:
2462- yield name
2463+ yield from ['trunk', 'testing', 'feature-x', 'feature-y', 'feature-z']
2464 index = count(1)
2465 while True:
2466 yield "branch-%s" % next(index)
2467diff --git a/lib/lp/code/tests/test_branch.py b/lib/lp/code/tests/test_branch.py
2468index a9e704d..5b316f3 100644
2469--- a/lib/lp/code/tests/test_branch.py
2470+++ b/lib/lp/code/tests/test_branch.py
2471@@ -331,7 +331,7 @@ class TestComposePublicURL(TestCaseWithFactory):
2472 layer = DatabaseFunctionalLayer
2473
2474 def setUp(self):
2475- super(TestComposePublicURL, self).setUp('admin@canonical.com')
2476+ super().setUp('admin@canonical.com')
2477
2478 def test_composePublicURL_accepts_supported_schemes(self):
2479 # composePublicURL accepts all schemes that PublicCodehostingAPI
2480diff --git a/lib/lp/code/tests/test_branch_webservice.py b/lib/lp/code/tests/test_branch_webservice.py
2481index 653ea5c..0a7e495 100644
2482--- a/lib/lp/code/tests/test_branch_webservice.py
2483+++ b/lib/lp/code/tests/test_branch_webservice.py
2484@@ -175,7 +175,7 @@ class TestBranchDeletes(TestCaseWithFactory):
2485 layer = DatabaseFunctionalLayer
2486
2487 def setUp(self):
2488- super(TestBranchDeletes, self).setUp()
2489+ super().setUp()
2490 self.branch_owner = self.factory.makePerson(name='jimhenson')
2491 self.branch = self.factory.makeBranch(
2492 owner=self.branch_owner,
2493diff --git a/lib/lp/code/tests/test_bzr.py b/lib/lp/code/tests/test_bzr.py
2494index 7f6939c..d430ad0 100644
2495--- a/lib/lp/code/tests/test_bzr.py
2496+++ b/lib/lp/code/tests/test_bzr.py
2497@@ -9,7 +9,6 @@ from breezy.tests import (
2498 TestCaseInTempDir,
2499 TestCaseWithTransport,
2500 )
2501-import six
2502
2503 from lp.code.bzr import (
2504 branch_revision_history,
2505@@ -46,7 +45,7 @@ class TestGetBranchFormats(TestCaseInTempDir):
2506
2507 def test_get_branch_format_2a(self):
2508 # Test the 2a branch format.
2509- branch = self.make_branch('test', six.ensure_str('2a'))
2510+ branch = self.make_branch('test', '2a')
2511 formats = get_branch_formats(branch)
2512 self.assertEqual(ControlFormat.BZR_METADIR_1, formats[0])
2513 self.assertEqual(BranchFormat.BZR_BRANCH_7, formats[1])
2514@@ -54,7 +53,7 @@ class TestGetBranchFormats(TestCaseInTempDir):
2515
2516 def test_get_branch_format_1_9(self):
2517 # Test the 1.9 branch format.
2518- branch = self.make_branch('test', six.ensure_str('1.9'))
2519+ branch = self.make_branch('test', '1.9')
2520 formats = get_branch_formats(branch)
2521 self.assertEqual(ControlFormat.BZR_METADIR_1, formats[0])
2522 self.assertEqual(BranchFormat.BZR_BRANCH_7, formats[1])
2523@@ -62,7 +61,7 @@ class TestGetBranchFormats(TestCaseInTempDir):
2524
2525 def test_get_branch_format_packs(self):
2526 # Test the packs branch format.
2527- branch = self.make_branch('test', six.ensure_str('pack-0.92'))
2528+ branch = self.make_branch('test', 'pack-0.92')
2529 formats = get_branch_formats(branch)
2530 self.assertEqual(ControlFormat.BZR_METADIR_1, formats[0])
2531 self.assertEqual(BranchFormat.BZR_BRANCH_6, formats[1])
2532@@ -70,7 +69,7 @@ class TestGetBranchFormats(TestCaseInTempDir):
2533
2534 def test_get_branch_format_knits(self):
2535 # Test the knits branch format.
2536- branch = self.make_branch('test', six.ensure_str('knit'))
2537+ branch = self.make_branch('test', 'knit')
2538 formats = get_branch_formats(branch)
2539 self.assertEqual(ControlFormat.BZR_METADIR_1, formats[0])
2540 self.assertEqual(BranchFormat.BZR_BRANCH_5, formats[1])
2541diff --git a/lib/lp/code/tests/test_directbranchcommit.py b/lib/lp/code/tests/test_directbranchcommit.py
2542index 977d855..db4d71c 100644
2543--- a/lib/lp/code/tests/test_directbranchcommit.py
2544+++ b/lib/lp/code/tests/test_directbranchcommit.py
2545@@ -30,7 +30,7 @@ class DirectBranchCommitTestCase:
2546 committer = None
2547
2548 def setUp(self):
2549- super(DirectBranchCommitTestCase, self).setUp()
2550+ super().setUp()
2551 self.useBzrBranches(direct_database=True)
2552
2553 self.series = self.factory.makeProductSeries()
2554@@ -292,7 +292,7 @@ class TestGetBzrCommitterID(TestCaseWithFactory):
2555 layer = DatabaseFunctionalLayer
2556
2557 def setUp(self):
2558- super(TestGetBzrCommitterID, self).setUp()
2559+ super().setUp()
2560 self.useBzrBranches(direct_database=True)
2561
2562 def _makeBranch(self, **kwargs):
2563diff --git a/lib/lp/code/tests/test_project.py b/lib/lp/code/tests/test_project.py
2564index d765060..7230a94 100644
2565--- a/lib/lp/code/tests/test_project.py
2566+++ b/lib/lp/code/tests/test_project.py
2567@@ -12,7 +12,7 @@ class TestProjectBranches(TestCaseWithFactory):
2568 layer = DatabaseFunctionalLayer
2569
2570 def setUp(self):
2571- super(TestProjectBranches, self).setUp()
2572+ super().setUp()
2573 self.projectgroup = self.factory.makeProject()
2574 self.product = self.factory.makeProduct(projectgroup=self.projectgroup)
2575
2576diff --git a/lib/lp/code/vocabularies/branch.py b/lib/lp/code/vocabularies/branch.py
2577index b165edc..d1b5eb9 100644
2578--- a/lib/lp/code/vocabularies/branch.py
2579+++ b/lib/lp/code/vocabularies/branch.py
2580@@ -70,7 +70,7 @@ class BranchRestrictedOnProductVocabulary(BranchVocabulary):
2581 """A vocabulary for searching branches restricted on product."""
2582
2583 def __init__(self, context=None):
2584- super(BranchRestrictedOnProductVocabulary, self).__init__(context)
2585+ super().__init__(context)
2586 if IProduct.providedBy(self.context):
2587 self.product = self.context
2588 elif IProductSeries.providedBy(self.context):
2589@@ -94,7 +94,7 @@ class HostedBranchRestrictedOnOwnerVocabulary(BranchVocabulary):
2590
2591 def __init__(self, context=None):
2592 """Pass a Person as context, or anything else for the current user."""
2593- super(HostedBranchRestrictedOnOwnerVocabulary, self).__init__(context)
2594+ super().__init__(context)
2595 if IPerson.providedBy(self.context):
2596 self.user = self.context
2597 else:
2598diff --git a/lib/lp/code/vocabularies/gitref.py b/lib/lp/code/vocabularies/gitref.py
2599index de842d1..2a2bad3 100644
2600--- a/lib/lp/code/vocabularies/gitref.py
2601+++ b/lib/lp/code/vocabularies/gitref.py
2602@@ -59,7 +59,7 @@ class GitRefVocabulary(StormVocabularyBase):
2603 step_title = "Search"
2604
2605 def __init__(self, context):
2606- super(GitRefVocabulary, self).__init__(context=context)
2607+ super().__init__(context=context)
2608 if IReference.providedBy(context):
2609 context = context.context
2610 try:
2611@@ -135,7 +135,7 @@ class GitRefVocabulary(StormVocabularyBase):
2612 # remote refs aren't database backed
2613 if zope_isinstance(value, GitRefRemote):
2614 return self.toTerm(value)
2615- return super(GitRefVocabulary, self).getTerm(value)
2616+ return super().getTerm(value)
2617
2618 def __len__(self):
2619 """See `IVocabulary`."""
2620diff --git a/lib/lp/code/vocabularies/gitrepository.py b/lib/lp/code/vocabularies/gitrepository.py
2621index 4f6f9df..92f8c3c 100644
2622--- a/lib/lp/code/vocabularies/gitrepository.py
2623+++ b/lib/lp/code/vocabularies/gitrepository.py
2624@@ -67,8 +67,7 @@ class GitRepositoryRestrictedOnProductVocabulary(GitRepositoryVocabulary):
2625 """A vocabulary for searching git repositories restricted on product."""
2626
2627 def __init__(self, context):
2628- super(GitRepositoryRestrictedOnProductVocabulary, self).__init__(
2629- context)
2630+ super().__init__(context)
2631 if IProduct.providedBy(self.context):
2632 self.product = self.context
2633 else:
2634diff --git a/lib/lp/code/vocabularies/gitrule.py b/lib/lp/code/vocabularies/gitrule.py
2635index 4b6284b..f6be79b 100644
2636--- a/lib/lp/code/vocabularies/gitrule.py
2637+++ b/lib/lp/code/vocabularies/gitrule.py
2638@@ -102,4 +102,4 @@ class GitPermissionsVocabulary(SimpleVocabulary):
2639 terms.append(SimpleTerm(
2640 grant_permissions,
2641 "custom", "Custom permissions: %s" % ", ".join(names)))
2642- super(GitPermissionsVocabulary, self).__init__(terms)
2643+ super().__init__(terms)
2644diff --git a/lib/lp/code/vocabularies/tests/test_branch_vocabularies.py b/lib/lp/code/vocabularies/tests/test_branch_vocabularies.py
2645index 7773c17..23d018f 100644
2646--- a/lib/lp/code/vocabularies/tests/test_branch_vocabularies.py
2647+++ b/lib/lp/code/vocabularies/tests/test_branch_vocabularies.py
2648@@ -22,7 +22,7 @@ class TestBranchVocabulary(TestCaseWithFactory):
2649 layer = DatabaseFunctionalLayer
2650
2651 def setUp(self):
2652- super(TestBranchVocabulary, self).setUp()
2653+ super().setUp()
2654 self._createBranches()
2655 self.vocab = BranchVocabulary(context=None)
2656
2657@@ -40,8 +40,7 @@ class TestBranchVocabulary(TestCaseWithFactory):
2658 def test_fizzbuzzBranches(self):
2659 """Return branches that match the string 'fizzbuzz'."""
2660 results = self.vocab.searchForTerms('fizzbuzz')
2661- expected = [
2662- u'~scotty/sprocket/fizzbuzz', u'~scotty/widget/fizzbuzz']
2663+ expected = ['~scotty/sprocket/fizzbuzz', '~scotty/widget/fizzbuzz']
2664 branch_names = sorted(branch.token for branch in results)
2665 self.assertEqual(expected, branch_names)
2666
2667@@ -68,7 +67,7 @@ class TestRestrictedBranchVocabularyOnProduct(TestCaseWithFactory):
2668 layer = DatabaseFunctionalLayer
2669
2670 def setUp(self):
2671- super(TestRestrictedBranchVocabularyOnProduct, self).setUp()
2672+ super().setUp()
2673 self._createBranches()
2674 self.vocab = BranchRestrictedOnProductVocabulary(
2675 context=self._getVocabRestriction())
2676@@ -98,7 +97,7 @@ class TestRestrictedBranchVocabularyOnProduct(TestCaseWithFactory):
2677 The result set should not show ~scotty/sprocket/main.
2678 """
2679 results = self.vocab.searchForTerms('main')
2680- expected = [u'~scotty/widget/main']
2681+ expected = ['~scotty/widget/main']
2682 branch_names = sorted(branch.token for branch in results)
2683 self.assertEqual(expected, branch_names)
2684
2685diff --git a/lib/lp/code/vocabularies/tests/test_gitrepository_vocabularies.py b/lib/lp/code/vocabularies/tests/test_gitrepository_vocabularies.py
2686index 774b0a1..d64d8c0 100644
2687--- a/lib/lp/code/vocabularies/tests/test_gitrepository_vocabularies.py
2688+++ b/lib/lp/code/vocabularies/tests/test_gitrepository_vocabularies.py
2689@@ -20,7 +20,7 @@ class TestGitRepositoryVocabulary(TestCaseWithFactory):
2690 layer = DatabaseFunctionalLayer
2691
2692 def setUp(self):
2693- super(TestGitRepositoryVocabulary, self).setUp()
2694+ super().setUp()
2695 self._createRepositories()
2696 self.vocab = GitRepositoryVocabulary(context=None)
2697
2698@@ -29,17 +29,17 @@ class TestGitRepositoryVocabulary(TestCaseWithFactory):
2699 sprocket = self.factory.makeProduct(name="sprocket")
2700 scotty = self.factory.makePerson(name="scotty")
2701 self.factory.makeGitRepository(
2702- owner=scotty, target=widget, name=u"fizzbuzz")
2703+ owner=scotty, target=widget, name="fizzbuzz")
2704 self.factory.makeGitRepository(
2705- owner=scotty, target=widget, name=u"mountain")
2706+ owner=scotty, target=widget, name="mountain")
2707 self.factory.makeGitRepository(
2708- owner=scotty, target=sprocket, name=u"fizzbuzz")
2709+ owner=scotty, target=sprocket, name="fizzbuzz")
2710
2711 def test_fizzbuzzRepositories(self):
2712 """Return repositories that match the string 'fizzbuzz'."""
2713 results = self.vocab.searchForTerms("fizzbuzz")
2714 expected = [
2715- u"~scotty/sprocket/+git/fizzbuzz", u"~scotty/widget/+git/fizzbuzz"]
2716+ "~scotty/sprocket/+git/fizzbuzz", "~scotty/widget/+git/fizzbuzz"]
2717 repository_names = sorted(repository.token for repository in results)
2718 self.assertEqual(expected, repository_names)
2719
2720@@ -67,7 +67,7 @@ class TestRestrictedGitRepositoryVocabularyOnProduct(TestCaseWithFactory):
2721 layer = DatabaseFunctionalLayer
2722
2723 def setUp(self):
2724- super(TestRestrictedGitRepositoryVocabularyOnProduct, self).setUp()
2725+ super().setUp()
2726 self._createRepositories()
2727 self.vocab = GitRepositoryRestrictedOnProductVocabulary(
2728 context=self._getVocabRestriction())
2729@@ -79,11 +79,11 @@ class TestRestrictedGitRepositoryVocabularyOnProduct(TestCaseWithFactory):
2730 def _createRepositories(self):
2731 test_product = self.factory.makeProduct(name='widget')
2732 other_product = self.factory.makeProduct(name='sprocket')
2733- person = self.factory.makePerson(name=u'scotty')
2734+ person = self.factory.makePerson(name='scotty')
2735 self.factory.makeGitRepository(
2736- owner=person, target=test_product, name=u'mountain')
2737+ owner=person, target=test_product, name='mountain')
2738 self.factory.makeGitRepository(
2739- owner=person, target=other_product, name=u'mountain')
2740+ owner=person, target=other_product, name='mountain')
2741 self.product = test_product
2742 self.other_product = test_product
2743
2744@@ -93,7 +93,7 @@ class TestRestrictedGitRepositoryVocabularyOnProduct(TestCaseWithFactory):
2745 The result set should not show ~scotty/sprocket/mountain.
2746 """
2747 results = self.vocab.searchForTerms('mountain')
2748- expected = [u'~scotty/widget/+git/mountain']
2749+ expected = ['~scotty/widget/+git/mountain']
2750 repo_names = sorted(repo.token for repo in results)
2751 self.assertEqual(expected, repo_names)
2752
2753@@ -102,7 +102,7 @@ class TestRestrictedGitRepositoryVocabularyOnProduct(TestCaseWithFactory):
2754 # as the result.
2755 term = self.vocab.getTermByToken('mountain')
2756 self.assertEqual(
2757- u'~scotty/widget/+git/mountain', term.value.unique_name)
2758+ '~scotty/widget/+git/mountain', term.value.unique_name)
2759
2760 def test_multipleQueryResult(self):
2761 # If there are more than one search result, a LookupError is still
2762diff --git a/lib/lp/code/xmlrpc/codehosting.py b/lib/lp/code/xmlrpc/codehosting.py
2763index c32d69f..07416b0 100644
2764--- a/lib/lp/code/xmlrpc/codehosting.py
2765+++ b/lib/lp/code/xmlrpc/codehosting.py
2766@@ -109,7 +109,7 @@ def run_with_login(login_id, function, *args, **kwargs):
2767 # Don't pass in an actual user. Instead pass in LAUNCHPAD_SERVICES
2768 # and expect `function` to use `removeSecurityProxy` or similar.
2769 return function(login_id, *args, **kwargs)
2770- if isinstance(login_id, (six.binary_type, six.text_type)):
2771+ if isinstance(login_id, (bytes, str)):
2772 login_id = six.ensure_text(login_id)
2773 # OpenID identifiers must contain a slash, while names must not.
2774 if "/" in login_id:
2775diff --git a/lib/lp/code/xmlrpc/git.py b/lib/lp/code/xmlrpc/git.py
2776index 9278b1a..83383cd 100644
2777--- a/lib/lp/code/xmlrpc/git.py
2778+++ b/lib/lp/code/xmlrpc/git.py
2779@@ -131,7 +131,7 @@ class GitAPI(LaunchpadXMLRPCView):
2780 """See `IGitAPI`."""
2781
2782 def __init__(self, *args, **kwargs):
2783- super(GitAPI, self).__init__(*args, **kwargs)
2784+ super().__init__(*args, **kwargs)
2785 self.repository_set = getUtility(IGitRepositorySet)
2786
2787 def _verifyMacaroon(self, macaroon_raw, repository=None, user=None):
2788@@ -326,7 +326,7 @@ class GitAPI(LaunchpadXMLRPCView):
2789 def _reportError(self, path, exception, hosting_path=None):
2790 properties = [
2791 ("path", path),
2792- ("error-explanation", six.text_type(exception)),
2793+ ("error-explanation", str(exception)),
2794 ]
2795 if hosting_path is not None:
2796 properties.append(("hosting_path", hosting_path))
2797@@ -360,9 +360,9 @@ class GitAPI(LaunchpadXMLRPCView):
2798 raise faults.InvalidSourcePackageName(e.name)
2799 return self._createRepository(requester, path)
2800 except NameLookupFailed as e:
2801- raise faults.NotFound(six.text_type(e))
2802+ raise faults.NotFound(str(e))
2803 except GitRepositoryCreationForbidden as e:
2804- raise faults.PermissionDenied(six.text_type(e))
2805+ raise faults.PermissionDenied(str(e))
2806
2807 try:
2808 try:
2809@@ -391,7 +391,7 @@ class GitAPI(LaunchpadXMLRPCView):
2810 # private repository). Log an OOPS for investigation.
2811 self._reportError(path, e)
2812 except (GitRepositoryCreationException, Unauthorized) as e:
2813- raise faults.PermissionDenied(six.text_type(e))
2814+ raise faults.PermissionDenied(str(e))
2815 except GitRepositoryCreationFault as e:
2816 # The hosting service failed. Log an OOPS for investigation.
2817 self._reportError(path, e, hosting_path=e.path)
2818diff --git a/lib/lp/code/xmlrpc/tests/test_branch.py b/lib/lp/code/xmlrpc/tests/test_branch.py
2819index 41d55d7..58d2192 100644
2820--- a/lib/lp/code/xmlrpc/tests/test_branch.py
2821+++ b/lib/lp/code/xmlrpc/tests/test_branch.py
2822@@ -24,7 +24,7 @@ from lp.testing.layers import DatabaseFunctionalLayer
2823 from lp.xmlrpc import faults
2824
2825
2826-NON_ASCII_NAME = u'nam\N{LATIN SMALL LETTER E WITH ACUTE}'
2827+NON_ASCII_NAME = 'nam\N{LATIN SMALL LETTER E WITH ACUTE}'
2828
2829
2830 class TestExpandURL(TestCaseWithFactory):
2831@@ -193,7 +193,7 @@ class TestExpandURL(TestCaseWithFactory):
2832 # find a branch, but it still resolves rather than erroring.
2833 owner = self.factory.makePerson()
2834 product = self.factory.makeProduct()
2835- nonexistent_branch = u'~%s/%s/%s' % (
2836+ nonexistent_branch = '~%s/%s/%s' % (
2837 owner.name, product.name, NON_ASCII_NAME)
2838 self.assertResolves(
2839 nonexistent_branch, urlutils.escape(nonexistent_branch))
2840@@ -236,7 +236,7 @@ class TestExpandURL(TestCaseWithFactory):
2841 def test_resolve_branch_with_no_such_owner_non_ascii(self):
2842 # lp:~<non-ascii-string>/product/name returns NoSuchPersonWithName
2843 # with the name escaped.
2844- nonexistent_owner_branch = u"~%s/%s/%s" % (
2845+ nonexistent_owner_branch = "~%s/%s/%s" % (
2846 NON_ASCII_NAME, self.factory.getUniqueString(),
2847 self.factory.getUniqueString())
2848 self.assertFault(
2849diff --git a/lib/lp/code/xmlrpc/tests/test_codehosting.py b/lib/lp/code/xmlrpc/tests/test_codehosting.py
2850index e72e46b..4921642 100644
2851--- a/lib/lp/code/xmlrpc/tests/test_codehosting.py
2852+++ b/lib/lp/code/xmlrpc/tests/test_codehosting.py
2853@@ -85,7 +85,7 @@ class TestRunWithLogin(TestCaseWithFactory):
2854 layer = DatabaseFunctionalLayer
2855
2856 def setUp(self):
2857- super(TestRunWithLogin, self).setUp()
2858+ super().setUp()
2859 self.person = self.factory.makePerson()
2860
2861 def test_loginAsRequester(self):
2862@@ -114,7 +114,7 @@ class TestRunWithLogin(TestCaseWithFactory):
2863 self.person.account.openid_identifiers.one().identifier)
2864 username = run_with_login(
2865 # Deliberately not Unicode, since XML-RPC gives us a byte string.
2866- (u'http://testopenid.test/+id/%s' % identifier).encode("UTF-8"),
2867+ ('http://testopenid.test/+id/%s' % identifier).encode("UTF-8"),
2868 get_logged_in_username)
2869 login(ANONYMOUS)
2870 self.assertEqual(self.person.name, username)
2871@@ -306,7 +306,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
2872
2873 def test_createBranch_no_preceding_slash(self):
2874 requester = self.factory.makePerson()
2875- path = escape(u'invalid')
2876+ path = escape('invalid')
2877 fault = self.codehosting_api.createBranch(requester.id, path)
2878 login(ANONYMOUS)
2879 self.assertEqual(faults.InvalidPath(path), fault)
2880@@ -390,7 +390,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
2881 # Creating a branch with an invalid name fails.
2882 owner = self.factory.makePerson()
2883 product = self.factory.makeProduct()
2884- invalid_name = u'invalid\N{LATIN SMALL LETTER E WITH ACUTE}'
2885+ invalid_name = 'invalid\N{LATIN SMALL LETTER E WITH ACUTE}'
2886 # LaunchpadValidationError unfortunately assumes its output is
2887 # always HTML, so it ends up double-escaped in XML-RPC faults.
2888 message = html_escape(
2889@@ -526,8 +526,8 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
2890 owner = self.factory.makePerson()
2891 product = self.factory.makeProduct()
2892 branch_name = self.factory.getUniqueString('branch-name')
2893- unique_name = u'~%s/%s/%s' % (owner.name, product.name, branch_name)
2894- path = u'/%s/%s' % (BRANCH_ALIAS_PREFIX, unique_name)
2895+ unique_name = '~%s/%s/%s' % (owner.name, product.name, branch_name)
2896+ path = '/%s/%s' % (BRANCH_ALIAS_PREFIX, unique_name)
2897 branch_id = self.codehosting_api.createBranch(owner.id, escape(path))
2898 login(ANONYMOUS)
2899 branch = self.branch_lookup.get(branch_id)
2900@@ -539,8 +539,8 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
2901 owner = self.factory.makePerson()
2902 product = self.factory.makeProduct()
2903 branch_name = self.factory.getUniqueString('branch-name')
2904- unique_name = u'~%s/%s/%s' % (owner.name, product.name, branch_name)
2905- path = escape(u'/%s/%s' % (BRANCH_ALIAS_PREFIX, unique_name))
2906+ unique_name = '~%s/%s/%s' % (owner.name, product.name, branch_name)
2907+ path = escape('/%s/%s' % (BRANCH_ALIAS_PREFIX, unique_name))
2908 branch_id = self.codehosting_api.createBranch(owner.id, path)
2909 login(ANONYMOUS)
2910 translation = self.codehosting_api.translatePath(owner.id, path)
2911@@ -555,7 +555,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
2912 # it.
2913 owner = self.factory.makePerson()
2914 product = self.factory.makeProduct(owner=owner)
2915- path = u'/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name)
2916+ path = '/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name)
2917 branch_id = self.codehosting_api.createBranch(owner.id, escape(path))
2918 login(ANONYMOUS)
2919 branch = self.branch_lookup.get(branch_id)
2920@@ -569,7 +569,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
2921 # immediately traversable using translatePath.
2922 product = self.factory.makeProduct()
2923 owner = product.owner
2924- path = escape(u'/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name))
2925+ path = escape('/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name))
2926 branch_id = self.codehosting_api.createBranch(owner.id, path)
2927 login(ANONYMOUS)
2928 translation = self.codehosting_api.translatePath(owner.id, path)
2929@@ -583,7 +583,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
2930 # the new branch to the alias, then can't create the branch.
2931 owner = self.factory.makePerson(name='eric')
2932 product = self.factory.makeProduct('wibble')
2933- path = u'/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name)
2934+ path = '/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name)
2935 fault = self.codehosting_api.createBranch(owner.id, escape(path))
2936 message = "Cannot create linked branch at 'wibble'."
2937 self.assertEqual(faults.PermissionDenied(message), fault)
2938@@ -595,7 +595,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
2939 def test_createBranch_using_branch_alias_product_not_exist(self):
2940 # If the product doesn't exist, we don't (yet) create one.
2941 owner = self.factory.makePerson()
2942- path = u'/%s/foible' % (BRANCH_ALIAS_PREFIX,)
2943+ path = '/%s/foible' % (BRANCH_ALIAS_PREFIX,)
2944 fault = self.codehosting_api.createBranch(owner.id, escape(path))
2945 message = "Project 'foible' does not exist."
2946 self.assertEqual(faults.NotFound(message), fault)
2947@@ -607,7 +607,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
2948 owner = self.factory.makePerson()
2949 product = self.factory.makeProduct(owner=owner)
2950 series = self.factory.makeProductSeries(product=product)
2951- path = u'/%s/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name, series.name)
2952+ path = '/%s/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name, series.name)
2953 branch_id = self.codehosting_api.createBranch(owner.id, escape(path))
2954 login(ANONYMOUS)
2955 branch = self.branch_lookup.get(branch_id)
2956@@ -622,7 +622,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
2957 owner = self.factory.makePerson()
2958 product = self.factory.makeProduct(name='wibble')
2959 self.factory.makeProductSeries(product=product, name='nip')
2960- path = u'/%s/wibble/nip' % (BRANCH_ALIAS_PREFIX,)
2961+ path = '/%s/wibble/nip' % (BRANCH_ALIAS_PREFIX,)
2962 fault = self.codehosting_api.createBranch(owner.id, escape(path))
2963 message = "Cannot create linked branch at 'wibble/nip'."
2964 self.assertEqual(faults.PermissionDenied(message), fault)
2965@@ -631,7 +631,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
2966 # If the product series doesn't exist, we don't (yet) create it.
2967 owner = self.factory.makePerson()
2968 self.factory.makeProduct(name='wibble')
2969- path = u'/%s/wibble/nip' % (BRANCH_ALIAS_PREFIX,)
2970+ path = '/%s/wibble/nip' % (BRANCH_ALIAS_PREFIX,)
2971 fault = self.codehosting_api.createBranch(owner.id, escape(path))
2972 message = "No such product series: 'nip'."
2973 self.assertEqual(faults.NotFound(message), fault)
2974@@ -777,19 +777,19 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
2975 # this happens, it returns a Fault saying so, including the path it
2976 # couldn't translate.
2977 requester = self.factory.makePerson()
2978- path = escape(u'/untranslatable')
2979+ path = escape('/untranslatable')
2980 self.assertNotFound(requester, path)
2981
2982 def test_translatePath_no_preceding_slash(self):
2983 requester = self.factory.makePerson()
2984- path = escape(u'invalid')
2985+ path = escape('invalid')
2986 fault = self.codehosting_api.translatePath(requester.id, path)
2987 self.assertEqual(faults.InvalidPath(path), fault)
2988
2989 def test_translatePath_branch(self):
2990 requester = self.factory.makePerson()
2991 branch = self.factory.makeAnyBranch()
2992- path = escape(u'/%s' % branch.unique_name)
2993+ path = escape('/%s' % branch.unique_name)
2994 translation = self.codehosting_api.translatePath(requester.id, path)
2995 login(ANONYMOUS)
2996 self.assertEqual(
2997@@ -800,7 +800,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
2998 def test_translatePath_branch_with_trailing_slash(self):
2999 requester = self.factory.makePerson()
3000 branch = self.factory.makeAnyBranch()
3001- path = escape(u'/%s/' % branch.unique_name)
3002+ path = escape('/%s/' % branch.unique_name)
3003 translation = self.codehosting_api.translatePath(requester.id, path)
3004 login(ANONYMOUS)
3005 self.assertEqual(
3006@@ -811,7 +811,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3007 def test_translatePath_path_in_branch(self):
3008 requester = self.factory.makePerson()
3009 branch = self.factory.makeAnyBranch()
3010- path = escape(u'/%s/child' % branch.unique_name)
3011+ path = escape('/%s/child' % branch.unique_name)
3012 translation = self.codehosting_api.translatePath(requester.id, path)
3013 login(ANONYMOUS)
3014 self.assertEqual(
3015@@ -822,7 +822,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3016 def test_translatePath_nested_path_in_branch(self):
3017 requester = self.factory.makePerson()
3018 branch = self.factory.makeAnyBranch()
3019- path = escape(u'/%s/a/b' % branch.unique_name)
3020+ path = escape('/%s/a/b' % branch.unique_name)
3021 translation = self.codehosting_api.translatePath(requester.id, path)
3022 login(ANONYMOUS)
3023 self.assertEqual(
3024@@ -833,11 +833,11 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3025 def test_translatePath_preserves_escaping(self):
3026 requester = self.factory.makePerson()
3027 branch = self.factory.makeAnyBranch()
3028- child_path = u'a@b'
3029+ child_path = 'a@b'
3030 # This test is only meaningful if the path isn't the same when
3031 # escaped.
3032 self.assertNotEqual(escape(child_path), child_path.encode('utf-8'))
3033- path = escape(u'/%s/%s' % (branch.unique_name, child_path))
3034+ path = escape('/%s/%s' % (branch.unique_name, child_path))
3035 translation = self.codehosting_api.translatePath(requester.id, path)
3036 login(ANONYMOUS)
3037 self.assertEqual(
3038@@ -886,7 +886,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3039 def test_translatePath_no_such_branch_non_ascii(self):
3040 requester = self.factory.makePerson()
3041 product = self.factory.makeProduct()
3042- path = u'/~%s/%s/non-asci\N{LATIN SMALL LETTER I WITH DIAERESIS}' % (
3043+ path = '/~%s/%s/non-asci\N{LATIN SMALL LETTER I WITH DIAERESIS}' % (
3044 requester.name, product.name)
3045 self.assertNotFound(requester, escape(path))
3046
3047@@ -896,7 +896,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3048 self.factory.makeAnyBranch(
3049 branch_type=BranchType.HOSTED, owner=requester,
3050 information_type=InformationType.USERDATA))
3051- path = escape(u'/%s' % branch.unique_name)
3052+ path = escape('/%s' % branch.unique_name)
3053 translation = self.codehosting_api.translatePath(requester.id, path)
3054 login(ANONYMOUS)
3055 self.assertEqual(
3056@@ -908,19 +908,19 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3057 requester = self.factory.makePerson()
3058 branch = removeSecurityProxy(self.factory.makeAnyBranch(
3059 information_type=InformationType.USERDATA))
3060- path = escape(u'/%s' % branch.unique_name)
3061+ path = escape('/%s' % branch.unique_name)
3062 self.assertPermissionDenied(requester, path)
3063
3064 def test_translatePath_remote_branch(self):
3065 requester = self.factory.makePerson()
3066 branch = self.factory.makeAnyBranch(branch_type=BranchType.REMOTE)
3067- path = escape(u'/%s' % branch.unique_name)
3068+ path = escape('/%s' % branch.unique_name)
3069 self.assertNotFound(requester, path)
3070
3071 def test_translatePath_launchpad_services_private(self):
3072 branch = removeSecurityProxy(self.factory.makeAnyBranch(
3073 information_type=InformationType.USERDATA))
3074- path = escape(u'/%s' % branch.unique_name)
3075+ path = escape('/%s' % branch.unique_name)
3076 translation = self.codehosting_api.translatePath(
3077 LAUNCHPAD_SERVICES, path)
3078 login(ANONYMOUS)
3079@@ -932,12 +932,12 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3080 def test_translatePath_anonymous_cant_see_private_branch(self):
3081 branch = removeSecurityProxy(self.factory.makeAnyBranch(
3082 information_type=InformationType.USERDATA))
3083- path = escape(u'/%s' % branch.unique_name)
3084+ path = escape('/%s' % branch.unique_name)
3085 self.assertPermissionDenied(LAUNCHPAD_ANONYMOUS, path)
3086
3087 def test_translatePath_anonymous_public_branch(self):
3088 branch = self.factory.makeAnyBranch()
3089- path = escape(u'/%s' % branch.unique_name)
3090+ path = escape('/%s' % branch.unique_name)
3091 translation = self.codehosting_api.translatePath(
3092 LAUNCHPAD_ANONYMOUS, path)
3093 self.assertEqual(
3094@@ -949,7 +949,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3095 requester = self.factory.makePerson()
3096 branch = self.factory.makeAnyBranch(
3097 branch_type=BranchType.HOSTED, owner=requester)
3098- path = escape(u'/%s' % branch.unique_name)
3099+ path = escape('/%s' % branch.unique_name)
3100 translation = self.codehosting_api.translatePath(requester.id, path)
3101 login(ANONYMOUS)
3102 self.assertEqual(
3103@@ -962,7 +962,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3104 team = self.factory.makeTeam(requester)
3105 branch = self.factory.makeAnyBranch(
3106 branch_type=BranchType.HOSTED, owner=team)
3107- path = escape(u'/%s' % branch.unique_name)
3108+ path = escape('/%s' % branch.unique_name)
3109 translation = self.codehosting_api.translatePath(requester.id, path)
3110 login(ANONYMOUS)
3111 self.assertEqual(
3112@@ -975,7 +975,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3113 team = self.factory.makeTeam(self.factory.makePerson())
3114 branch = self.factory.makeAnyBranch(
3115 branch_type=BranchType.HOSTED, owner=team)
3116- path = escape(u'/%s' % branch.unique_name)
3117+ path = escape('/%s' % branch.unique_name)
3118 translation = self.codehosting_api.translatePath(requester.id, path)
3119 login(ANONYMOUS)
3120 self.assertEqual(
3121@@ -987,7 +987,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3122 requester = self.factory.makePerson()
3123 branch = self.factory.makeAnyBranch(
3124 branch_type=BranchType.MIRRORED, owner=requester)
3125- path = escape(u'/%s' % branch.unique_name)
3126+ path = escape('/%s' % branch.unique_name)
3127 translation = self.codehosting_api.translatePath(requester.id, path)
3128 login(ANONYMOUS)
3129 self.assertEqual(
3130@@ -999,7 +999,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3131 requester = self.factory.makePerson()
3132 branch = self.factory.makeAnyBranch(
3133 branch_type=BranchType.IMPORTED, owner=requester)
3134- path = escape(u'/%s' % branch.unique_name)
3135+ path = escape('/%s' % branch.unique_name)
3136 translation = self.codehosting_api.translatePath(requester.id, path)
3137 login(ANONYMOUS)
3138 self.assertEqual(
3139@@ -1015,7 +1015,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3140 removeSecurityProxy(branch.product.development_focus).branch = branch
3141 short_name = ICanHasLinkedBranch(branch.product).bzr_path
3142 path_in_branch = '.bzr/branch-format'
3143- path = escape(u'/%s' % os.path.join(
3144+ path = escape('/%s' % os.path.join(
3145 BRANCH_ALIAS_PREFIX, short_name, path_in_branch))
3146 translation = self.codehosting_api.translatePath(requester.id, path)
3147 login(ANONYMOUS)
3148@@ -1030,7 +1030,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3149 requester = self.factory.makePerson()
3150 branch = self.factory.makeBranch()
3151 path_in_branch = '.bzr/branch-format'
3152- path = escape(u'/%s' % os.path.join(
3153+ path = escape('/%s' % os.path.join(
3154 BRANCH_ALIAS_PREFIX, branch.unique_name, path_in_branch))
3155 translation = self.codehosting_api.translatePath(requester.id, path)
3156 login(ANONYMOUS)
3157@@ -1147,7 +1147,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3158 # Make sure the trailing path is returned.
3159 requester = self.factory.makePerson()
3160 branch = removeSecurityProxy(self.factory.makeAnyBranch())
3161- path = escape(u'%s/foo/bar' % branch_id_alias(branch))
3162+ path = escape('%s/foo/bar' % branch_id_alias(branch))
3163 translation = self.codehosting_api.translatePath(requester.id, path)
3164 expected = (
3165 BRANCH_TRANSPORT,
3166@@ -1206,7 +1206,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3167 def test_translatePath_control_directory(self):
3168 requester = self.factory.makePerson()
3169 product, branch = self._makeProductWithDevFocus()
3170- path = escape(u'/~%s/%s/.bzr' % (requester.name, product.name))
3171+ path = escape('/~%s/%s/.bzr' % (requester.name, product.name))
3172 translation = self.codehosting_api.translatePath(requester.id, path)
3173 login(ANONYMOUS)
3174 self.assertTranslationIsControlDirectory(
3175@@ -1219,20 +1219,20 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3176 # don't even bother translating control directory paths.
3177 requester = self.factory.makePerson()
3178 product = self.factory.makeProduct()
3179- path = escape(u'/~%s/%s/.bzr/' % (requester.name, product.name))
3180+ path = escape('/~%s/%s/.bzr/' % (requester.name, product.name))
3181 self.assertNotFound(requester, path)
3182
3183 def test_translatePath_control_directory_invisble_branch(self):
3184 requester = self.factory.makePerson()
3185 product, branch = self._makeProductWithDevFocus(private=True)
3186- path = escape(u'/~%s/%s/.bzr/' % (requester.name, product.name))
3187+ path = escape('/~%s/%s/.bzr/' % (requester.name, product.name))
3188 self.assertNotFound(requester, path)
3189
3190 def test_translatePath_control_directory_private_branch(self):
3191 product, branch = self._makeProductWithDevFocus(private=True)
3192 branch = removeSecurityProxy(branch)
3193 requester = branch.owner
3194- path = escape(u'/~%s/%s/.bzr/' % (requester.name, product.name))
3195+ path = escape('/~%s/%s/.bzr/' % (requester.name, product.name))
3196 translation = self.codehosting_api.translatePath(requester.id, path)
3197 login(ANONYMOUS)
3198 self.assertTranslationIsControlDirectory(
3199@@ -1244,7 +1244,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
3200 requester = self.factory.makePerson()
3201 product, branch = self._makeProductWithDevFocus()
3202 owner = self.factory.makePerson()
3203- path = escape(u'/~%s/%s/.bzr' % (owner.name, product.name))
3204+ path = escape('/~%s/%s/.bzr' % (owner.name, product.name))
3205 translation = self.codehosting_api.translatePath(requester.id, path)
3206 login(ANONYMOUS)
3207 self.assertTranslationIsControlDirectory(
3208@@ -1291,7 +1291,7 @@ class AcquireBranchToPullTestsViaEndpoint(WithScenarios, TestCaseWithFactory,
3209 ]
3210
3211 def setUp(self):
3212- super(AcquireBranchToPullTestsViaEndpoint, self).setUp()
3213+ super().setUp()
3214 frontend = self.frontend()
3215 self.codehosting_api = frontend.getCodehostingEndpoint()
3216 self.factory = frontend.getLaunchpadObjectFactory()
3217diff --git a/lib/lp/code/xmlrpc/tests/test_git.py b/lib/lp/code/xmlrpc/tests/test_git.py
3218index 27c78c4..9dd57c1 100644
3219--- a/lib/lp/code/xmlrpc/tests/test_git.py
3220+++ b/lib/lp/code/xmlrpc/tests/test_git.py
3221@@ -138,7 +138,7 @@ class MatchesFault(MatchesStructure):
3222
3223 def __init__(self, expected_fault):
3224 fault_matchers = {}
3225- if (isinstance(expected_fault, six.class_types) and
3226+ if (isinstance(expected_fault, type) and
3227 issubclass(expected_fault, faults.LaunchpadFault)):
3228 fault_matchers["faultCode"] = Equals(expected_fault.error_code)
3229 else:
3230@@ -146,17 +146,17 @@ class MatchesFault(MatchesStructure):
3231 fault_string = expected_fault.faultString
3232 # XXX cjwatson 2019-09-27: InvalidBranchName.faultString is
3233 # bytes, so we need this to handle that case. Should it be?
3234- if not isinstance(fault_string, six.text_type):
3235+ if not isinstance(fault_string, str):
3236 fault_string = fault_string.decode("UTF-8")
3237 fault_matchers["faultString"] = Equals(fault_string)
3238- super(MatchesFault, self).__init__(**fault_matchers)
3239+ super().__init__(**fault_matchers)
3240
3241
3242 class TestGitAPIMixin:
3243 """Helper methods for `IGitAPI` tests, and security-relevant tests."""
3244
3245 def setUp(self):
3246- super(TestGitAPIMixin, self).setUp()
3247+ super().setUp()
3248 self.git_api = xmlrpc.client.ServerProxy(
3249 "http://xmlrpc-private.launchpad.test:8087/git",
3250 transport=XMLRPCTestTransport())
3251@@ -495,7 +495,7 @@ class TestGitAPIMixin:
3252 repository = removeSecurityProxy(
3253 self.factory.makeGitRepository(
3254 owner=requester, information_type=InformationType.USERDATA))
3255- path = u"/%s" % repository.unique_name
3256+ path = "/%s" % repository.unique_name
3257 self.assertTranslates(requester, path, repository, True, private=True)
3258
3259 def test_translatePath_cannot_see_private_repository(self):
3260@@ -503,14 +503,14 @@ class TestGitAPIMixin:
3261 repository = removeSecurityProxy(
3262 self.factory.makeGitRepository(
3263 information_type=InformationType.USERDATA))
3264- path = u"/%s" % repository.unique_name
3265+ path = "/%s" % repository.unique_name
3266 self.assertGitRepositoryNotFound(requester, path)
3267
3268 def test_translatePath_anonymous_cannot_see_private_repository(self):
3269 repository = removeSecurityProxy(
3270 self.factory.makeGitRepository(
3271 information_type=InformationType.USERDATA))
3272- path = u"/%s" % repository.unique_name
3273+ path = "/%s" % repository.unique_name
3274 self.assertGitRepositoryNotFound(None, path, can_authenticate=False)
3275 self.assertUnauthorized(None, path, can_authenticate=True)
3276
3277@@ -518,7 +518,7 @@ class TestGitAPIMixin:
3278 requester = self.factory.makePerson()
3279 team = self.factory.makeTeam(self.factory.makePerson())
3280 repository = self.factory.makeGitRepository(owner=team)
3281- path = u"/%s" % repository.unique_name
3282+ path = "/%s" % repository.unique_name
3283 self.assertTranslates(requester, path, repository, False)
3284 self.assertPermissionDenied(requester, path, permission="write")
3285
3286@@ -526,7 +526,7 @@ class TestGitAPIMixin:
3287 requester = self.factory.makePerson()
3288 repository = self.factory.makeGitRepository(
3289 owner=requester, repository_type=GitRepositoryType.IMPORTED)
3290- path = u"/%s" % repository.unique_name
3291+ path = "/%s" % repository.unique_name
3292 self.assertTranslates(requester, path, repository, False)
3293 self.assertPermissionDenied(requester, path, permission="write")
3294
3295@@ -538,7 +538,7 @@ class TestGitAPIMixin:
3296 message = "%s is not a member of %s" % (
3297 requester.displayname, team.displayname)
3298 self.assertPermissionDenied(
3299- requester, u"/~%s/+git/random" % team.name, message=message,
3300+ requester, "/~%s/+git/random" % team.name, message=message,
3301 permission="write")
3302
3303 def test_translatePath_create_other_user(self):
3304@@ -547,7 +547,7 @@ class TestGitAPIMixin:
3305 other_person = self.factory.makePerson()
3306 project = self.factory.makeProduct()
3307 name = self.factory.getUniqueString()
3308- path = u"/~%s/%s/+git/%s" % (other_person.name, project.name, name)
3309+ path = "/~%s/%s/+git/%s" % (other_person.name, project.name, name)
3310 message = "%s cannot create Git repositories owned by %s" % (
3311 requester.displayname, other_person.displayname)
3312 self.assertPermissionDenied(
3313@@ -558,7 +558,7 @@ class TestGitAPIMixin:
3314 # repository and immediately set it as the default for that project.
3315 requester = self.factory.makePerson()
3316 project = self.factory.makeProduct()
3317- path = u"/%s" % project.name
3318+ path = "/%s" % project.name
3319 message = "%s cannot create Git repositories owned by %s" % (
3320 requester.displayname, project.owner.displayname)
3321 initial_count = getUtility(IAllGitRepositories).count()
3322@@ -577,7 +577,7 @@ class TestGitAPIMixin:
3323 distribution = self.factory.makeDistribution(
3324 oci_project_admin=self.factory.makeTeam())
3325 oci_project = self.factory.makeOCIProject(pillar=distribution)
3326- path = u"/%s/+oci/%s" % (oci_project.pillar.name, oci_project.name)
3327+ path = "/%s/+oci/%s" % (oci_project.pillar.name, oci_project.name)
3328 message = "%s is not a member of %s" % (
3329 requester.displayname,
3330 oci_project.pillar.oci_project_admin.displayname)
3331@@ -594,11 +594,11 @@ class TestGitAPIMixin:
3332 other_person = self.factory.makePerson()
3333 repository = self.factory.makeGitRepository(owner=requester)
3334 rule = self.factory.makeGitRule(
3335- repository, ref_pattern=u'refs/heads/stable/next')
3336+ repository, ref_pattern='refs/heads/stable/next')
3337 self.factory.makeGitRuleGrant(
3338 rule=rule, grantee=other_person,
3339 can_force_push=True)
3340- path = u"/%s" % repository.unique_name
3341+ path = "/%s" % repository.unique_name
3342 self.assertTranslates(
3343 other_person, path, repository, True, private=False)
3344
3345@@ -608,11 +608,11 @@ class TestGitAPIMixin:
3346 other_person = self.factory.makePerson()
3347 repository = self.factory.makeGitRepository(owner=requester)
3348 rule = self.factory.makeGitRule(
3349- repository, ref_pattern=u'refs/heads/stable/next')
3350+ repository, ref_pattern='refs/heads/stable/next')
3351 self.factory.makeGitRuleGrant(
3352 rule=rule, grantee=grant_person,
3353 can_force_push=True)
3354- path = u"/%s" % repository.unique_name
3355+ path = "/%s" % repository.unique_name
3356 self.assertTranslates(
3357 other_person, path, repository, False, private=False)
3358
3359@@ -623,11 +623,11 @@ class TestGitAPIMixin:
3360 self.factory.makeGitRepository(
3361 owner=requester, information_type=InformationType.USERDATA))
3362 rule = self.factory.makeGitRule(
3363- repository, ref_pattern=u'refs/heads/stable/next')
3364+ repository, ref_pattern='refs/heads/stable/next')
3365 self.factory.makeGitRuleGrant(
3366 rule=rule, grantee=other_person,
3367 can_force_push=True)
3368- path = u"/%s" % repository.unique_name
3369+ path = "/%s" % repository.unique_name
3370 self.assertGitRepositoryNotFound(
3371 other_person, path, can_authenticate=True)
3372
3373@@ -642,34 +642,34 @@ class TestGitAPIMixin:
3374 self.factory.makeGitRepository(owner=user_a))
3375
3376 rule = self.factory.makeGitRule(
3377- repository, ref_pattern=u'refs/heads/stable/next')
3378+ repository, ref_pattern='refs/heads/stable/next')
3379 self.factory.makeGitRuleGrant(
3380 rule=rule, grantee=GitGranteeType.REPOSITORY_OWNER,
3381 can_force_push=True)
3382
3383 rule = self.factory.makeGitRule(
3384- repository, ref_pattern=u'refs/heads/stable/protected')
3385+ repository, ref_pattern='refs/heads/stable/protected')
3386 self.factory.makeGitRuleGrant(rule=rule, grantee=stable_team)
3387
3388 rule = self.factory.makeGitRule(
3389- repository, ref_pattern=u'refs/heads/archived/*')
3390+ repository, ref_pattern='refs/heads/archived/*')
3391 self.factory.makeGitRuleGrant(
3392 rule=rule, grantee=GitGranteeType.REPOSITORY_OWNER)
3393 self.factory.makeGitRuleGrant(
3394 rule=rule, grantee=user_b, can_create=True)
3395
3396 rule = self.factory.makeGitRule(
3397- repository, ref_pattern=u'refs/heads/stable/*')
3398+ repository, ref_pattern='refs/heads/stable/*')
3399 self.factory.makeGitRuleGrant(
3400 rule=rule, grantee=stable_team, can_push=True)
3401
3402 rule = self.factory.makeGitRule(
3403- repository, ref_pattern=u'refs/heads/*/next')
3404+ repository, ref_pattern='refs/heads/*/next')
3405 self.factory.makeGitRuleGrant(
3406 rule=rule, grantee=next_team, can_force_push=True)
3407
3408 rule = self.factory.makeGitRule(
3409- repository, ref_pattern=u'refs/tags/*')
3410+ repository, ref_pattern='refs/tags/*')
3411 self.factory.makeGitRuleGrant(
3412 rule=rule, grantee=GitGranteeType.REPOSITORY_OWNER,
3413 can_create=True)
3414@@ -743,18 +743,18 @@ class TestGitAPIMixin:
3415 self.factory.makeGitRepository(owner=user_a))
3416
3417 rule = self.factory.makeGitRule(
3418- repository, ref_pattern=u'refs/heads/master')
3419+ repository, ref_pattern='refs/heads/master')
3420 self.factory.makeGitRuleGrant(
3421 rule=rule, grantee=user_b, can_push=True)
3422
3423 rule = self.factory.makeGitRule(
3424- repository, ref_pattern=u'refs/heads/*')
3425+ repository, ref_pattern='refs/heads/*')
3426 self.factory.makeGitRuleGrant(
3427 rule=rule, grantee=GitGranteeType.REPOSITORY_OWNER,
3428 can_create=True, can_push=True, can_force_push=True)
3429
3430 rule = self.factory.makeGitRule(
3431- repository, ref_pattern=u'refs/tags/*')
3432+ repository, ref_pattern='refs/tags/*')
3433 self.factory.makeGitRuleGrant(
3434 rule=rule, grantee=user_b, can_push=True)
3435
3436@@ -797,11 +797,11 @@ class TestGitAPIMixin:
3437 repository = removeSecurityProxy(
3438 self.factory.makeGitRepository(owner=owner))
3439 self.factory.makeGitRuleGrant(
3440- repository=repository, ref_pattern=u"refs/heads/next/*",
3441+ repository=repository, ref_pattern="refs/heads/next/*",
3442 grantee=grantee, can_push=True)
3443 paths = [
3444 # Properly-encoded UTF-8.
3445- u"refs/heads/next/\N{BLACK HEART SUIT}".encode("UTF-8"),
3446+ "refs/heads/next/\N{BLACK HEART SUIT}".encode(),
3447 # Non-UTF-8. (git does not require any particular encoding for
3448 # ref paths; non-UTF-8 ones won't work well everywhere, but it's
3449 # at least possible to round-trip them through Launchpad.)
3450@@ -1211,12 +1211,12 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3451 # When this happens, it returns a Fault saying so, including the
3452 # path it couldn't translate.
3453 requester = self.factory.makePerson()
3454- self.assertGitRepositoryNotFound(requester, u"/untranslatable")
3455+ self.assertGitRepositoryNotFound(requester, "/untranslatable")
3456
3457 def test_translatePath_repository(self):
3458 requester = self.factory.makePerson()
3459 repository = self.factory.makeGitRepository()
3460- path = u"/%s" % repository.unique_name
3461+ path = "/%s" % repository.unique_name
3462 self.assertTranslates(requester, path, repository, False)
3463
3464 def test_translatePath_repository_with_no_leading_slash(self):
3465@@ -1228,30 +1228,30 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3466 def test_translatePath_repository_with_trailing_slash(self):
3467 requester = self.factory.makePerson()
3468 repository = self.factory.makeGitRepository()
3469- path = u"/%s/" % repository.unique_name
3470+ path = "/%s/" % repository.unique_name
3471 self.assertTranslates(requester, path, repository, False)
3472
3473 def test_translatePath_repository_with_trailing_segments(self):
3474 requester = self.factory.makePerson()
3475 repository = self.factory.makeGitRepository()
3476- path = u"/%s/foo/bar" % repository.unique_name
3477+ path = "/%s/foo/bar" % repository.unique_name
3478 self.assertTranslates(
3479 requester, path, repository, False, trailing="foo/bar")
3480
3481 def test_translatePath_no_such_repository(self):
3482 requester = self.factory.makePerson()
3483- path = u"/%s/+git/no-such-repository" % requester.name
3484+ path = "/%s/+git/no-such-repository" % requester.name
3485 self.assertGitRepositoryNotFound(requester, path)
3486
3487 def test_translatePath_no_such_repository_non_ascii(self):
3488 requester = self.factory.makePerson()
3489- path = u"/%s/+git/\N{LATIN SMALL LETTER I WITH DIAERESIS}" % (
3490+ path = "/%s/+git/\N{LATIN SMALL LETTER I WITH DIAERESIS}" % (
3491 requester.name)
3492 self.assertGitRepositoryNotFound(requester, path)
3493
3494 def test_translatePath_anonymous_public_repository(self):
3495 repository = self.factory.makeGitRepository()
3496- path = u"/%s" % repository.unique_name
3497+ path = "/%s" % repository.unique_name
3498 self.assertTranslates(
3499 None, path, repository, False, can_authenticate=False)
3500 self.assertTranslates(
3501@@ -1260,7 +1260,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3502 def test_translatePath_owned(self):
3503 requester = self.factory.makePerson()
3504 repository = self.factory.makeGitRepository(owner=requester)
3505- path = u"/%s" % repository.unique_name
3506+ path = "/%s" % repository.unique_name
3507 self.assertTranslates(
3508 requester, path, repository, True, permission="write")
3509
3510@@ -1268,7 +1268,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3511 requester = self.factory.makePerson()
3512 team = self.factory.makeTeam(requester)
3513 repository = self.factory.makeGitRepository(owner=team)
3514- path = u"/%s" % repository.unique_name
3515+ path = "/%s" % repository.unique_name
3516 self.assertTranslates(
3517 requester, path, repository, True, permission="write")
3518
3519@@ -1279,7 +1279,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3520 with person_logged_in(repository.target.owner):
3521 getUtility(IGitRepositorySet).setDefaultRepository(
3522 repository.target, repository)
3523- path = u"/%s" % repository.target.name
3524+ path = "/%s" % repository.target.name
3525 self.assertTranslates(requester, path, repository, False)
3526
3527 def test_translatePath_create_project_async(self):
3528@@ -1288,14 +1288,14 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3529 requester = self.factory.makePerson()
3530 project = self.factory.makeProduct()
3531 self.assertCreates(
3532- requester, u"/~%s/%s/+git/random" % (requester.name, project.name))
3533+ requester, "/~%s/%s/+git/random" % (requester.name, project.name))
3534
3535 def test_translatePath_create_project_sync(self):
3536 self.useFixture(FeatureFixture({GIT_ASYNC_CREATE_REPO: ''}))
3537 requester = self.factory.makePerson()
3538 project = self.factory.makeProduct()
3539 self.assertCreates(
3540- requester, u"/~%s/%s/+git/random" % (requester.name, project.name),
3541+ requester, "/~%s/%s/+git/random" % (requester.name, project.name),
3542 async_create=False)
3543
3544 def test_translatePath_create_project_blocks_duplicate_calls(self):
3545@@ -1303,7 +1303,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3546 # but blocks any further request to create the same repository.
3547 requester = self.factory.makePerson()
3548 project = self.factory.makeProduct()
3549- path = u"/~%s/%s/+git/random" % (requester.name, project.name)
3550+ path = "/~%s/%s/+git/random" % (requester.name, project.name)
3551 self.assertCreates(requester, path)
3552
3553 auth_params = _make_auth_params(
3554@@ -1323,7 +1323,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3555 self.repository_set.setDefaultRepository(target, repository)
3556 self.assertCreatesFromClone(
3557 target.owner,
3558- u"/~%s/%s/+git/random" % (target.owner.name, target.name),
3559+ "/~%s/%s/+git/random" % (target.owner.name, target.name),
3560 repository)
3561
3562 def test_translatePath_create_project_clone_from_owner_default(self):
3563@@ -1337,7 +1337,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3564 target.owner, target, repository, user)
3565 self.assertCreatesFromClone(
3566 target.owner,
3567- u"/~%s/%s/+git/random" % (target.owner.name, target.name),
3568+ "/~%s/%s/+git/random" % (target.owner.name, target.name),
3569 repository)
3570
3571 def test_translatePath_create_package(self):
3572@@ -1347,7 +1347,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3573 dsp = self.factory.makeDistributionSourcePackage()
3574 self.assertCreates(
3575 requester,
3576- u"/~%s/%s/+source/%s/+git/random" % (
3577+ "/~%s/%s/+source/%s/+git/random" % (
3578 requester.name,
3579 dsp.distribution.name, dsp.sourcepackagename.name))
3580
3581@@ -1358,45 +1358,45 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3582 oci_project = self.factory.makeOCIProject()
3583 self.assertCreates(
3584 requester,
3585- u"/~%s/%s/+oci/%s/+git/random" % (
3586+ "/~%s/%s/+oci/%s/+git/random" % (
3587 requester.name, oci_project.pillar.name, oci_project.name))
3588
3589 def test_translatePath_create_personal(self):
3590 # translatePath creates a personal repository that doesn't exist, if
3591 # it can.
3592 requester = self.factory.makePerson()
3593- self.assertCreates(requester, u"/~%s/+git/random" % requester.name)
3594+ self.assertCreates(requester, "/~%s/+git/random" % requester.name)
3595
3596 def test_translatePath_create_personal_team(self):
3597 # translatePath creates a personal repository for a team of which
3598 # the requester is a member.
3599 requester = self.factory.makePerson()
3600 team = self.factory.makeTeam(members=[requester])
3601- self.assertCreates(requester, u"/~%s/+git/random" % team.name)
3602+ self.assertCreates(requester, "/~%s/+git/random" % team.name)
3603
3604 def test_translatePath_create_native_string(self):
3605 # On Python 2, ASCII strings come in as native strings, not Unicode
3606 # strings. They work fine too.
3607 requester = self.factory.makePerson()
3608 project = self.factory.makeProduct()
3609- path = u"/~%s/%s/+git/random" % (requester.name, project.name)
3610+ path = "/~%s/%s/+git/random" % (requester.name, project.name)
3611 self.assertCreates(requester, six.ensure_str(path))
3612
3613 def test_translatePath_anonymous_cannot_create(self):
3614 # Anonymous users cannot create repositories.
3615 project = self.factory.makeProject()
3616 self.assertGitRepositoryNotFound(
3617- None, u"/%s" % project.name, permission="write",
3618+ None, "/%s" % project.name, permission="write",
3619 can_authenticate=False)
3620 self.assertUnauthorized(
3621- None, u"/%s" % project.name, permission="write",
3622+ None, "/%s" % project.name, permission="write",
3623 can_authenticate=True)
3624
3625 def test_translatePath_create_invalid_namespace(self):
3626 # Trying to create a repository at a path that isn't valid for Git
3627 # repositories returns a PermissionDenied fault.
3628 requester = self.factory.makePerson()
3629- path = u"/~%s" % requester.name
3630+ path = "/~%s" % requester.name
3631 message = "'%s' is not a valid Git repository path." % path.strip("/")
3632 self.assertPermissionDenied(
3633 requester, path, message=message, permission="write")
3634@@ -1405,14 +1405,14 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3635 # Creating a repository for a non-existent person fails.
3636 requester = self.factory.makePerson()
3637 self.assertNotFound(
3638- requester, u"/~nonexistent/+git/random",
3639+ requester, "/~nonexistent/+git/random",
3640 "User/team 'nonexistent' does not exist.", permission="write")
3641
3642 def test_translatePath_create_no_such_project(self):
3643 # Creating a repository for a non-existent project fails.
3644 requester = self.factory.makePerson()
3645 self.assertNotFound(
3646- requester, u"/~%s/nonexistent/+git/random" % requester.name,
3647+ requester, "/~%s/nonexistent/+git/random" % requester.name,
3648 "Project 'nonexistent' does not exist.", permission="write")
3649
3650 def test_translatePath_create_no_such_person_or_project(self):
3651@@ -1420,14 +1420,14 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3652 # person is reported in preference.
3653 requester = self.factory.makePerson()
3654 self.assertNotFound(
3655- requester, u"/~nonexistent/nonexistent/+git/random",
3656+ requester, "/~nonexistent/nonexistent/+git/random",
3657 "User/team 'nonexistent' does not exist.", permission="write")
3658
3659 def test_translatePath_create_invalid_project(self):
3660 # Creating a repository with an invalid project name fails.
3661 requester = self.factory.makePerson()
3662 self.assertNotFound(
3663- requester, u"/_bad_project/+git/random",
3664+ requester, "/_bad_project/+git/random",
3665 "Project '_bad_project' does not exist.", permission="write")
3666
3667 def test_translatePath_create_missing_sourcepackagename(self):
3668@@ -1436,7 +1436,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3669 requester = self.factory.makePerson()
3670 distro = self.factory.makeDistribution()
3671 repository_name = self.factory.getUniqueString()
3672- path = u"/~%s/%s/+source/new-package/+git/%s" % (
3673+ path = "/~%s/%s/+source/new-package/+git/%s" % (
3674 requester.name, distro.name, repository_name)
3675 repository = self.assertCreates(requester, path)
3676 self.assertEqual(
3677@@ -1447,7 +1447,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3678 requester = self.factory.makePerson()
3679 distro = self.factory.makeDistribution()
3680 repository_name = self.factory.getUniqueString()
3681- path = u"/~%s/%s/+source/new package/+git/%s" % (
3682+ path = "/~%s/%s/+source/new package/+git/%s" % (
3683 requester.name, distro.name, repository_name)
3684 self.assertInvalidSourcePackageName(
3685 requester, path, "new package", permission="write")
3686@@ -1457,7 +1457,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3687 requester = self.factory.makePerson()
3688 project = self.factory.makeProduct()
3689 invalid_name = "invalid name!"
3690- path = u"/~%s/%s/+git/%s" % (
3691+ path = "/~%s/%s/+git/%s" % (
3692 requester.name, project.name, invalid_name)
3693 # LaunchpadValidationError unfortunately assumes its output is
3694 # always HTML, so it ends up double-escaped in XML-RPC faults.
3695@@ -1471,8 +1471,8 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3696 # Creating a repository with a non-ASCII invalid name fails.
3697 requester = self.factory.makePerson()
3698 project = self.factory.makeProduct()
3699- invalid_name = u"invalid\N{LATIN SMALL LETTER E WITH ACUTE}"
3700- path = u"/~%s/%s/+git/%s" % (
3701+ invalid_name = "invalid\N{LATIN SMALL LETTER E WITH ACUTE}"
3702+ path = "/~%s/%s/+git/%s" % (
3703 requester.name, project.name, invalid_name)
3704 # LaunchpadValidationError unfortunately assumes its output is
3705 # always HTML, so it ends up double-escaped in XML-RPC faults.
3706@@ -1490,7 +1490,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3707 membership_policy=TeamMembershipPolicy.RESTRICTED,
3708 members=[requester])
3709 project = self.factory.makeProduct(owner=owner)
3710- repository = self.assertCreates(requester, u"/%s" % project.name)
3711+ repository = self.assertCreates(requester, "/%s" % project.name)
3712 self.assertTrue(repository.target_default)
3713 self.assertTrue(repository.owner_default)
3714 self.assertEqual(owner, repository.owner)
3715@@ -1500,7 +1500,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3716 # default for a package.
3717 requester = self.factory.makePerson()
3718 dsp = self.factory.makeDistributionSourcePackage()
3719- path = u"/%s/+source/%s" % (
3720+ path = "/%s/+source/%s" % (
3721 dsp.distribution.name, dsp.sourcepackagename.name)
3722 message = (
3723 "Cannot automatically set the default repository for this target; "
3724@@ -1518,7 +1518,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3725 oci_project = self.factory.makeOCIProject(pillar=distribution)
3726 repository = self.assertCreates(
3727 requester,
3728- u"/%s/+oci/%s" % (oci_project.pillar.name, oci_project.name))
3729+ "/%s/+oci/%s" % (oci_project.pillar.name, oci_project.name))
3730 self.assertTrue(repository.target_default)
3731 self.assertTrue(repository.owner_default)
3732 self.assertEqual(oci_project_admin, repository.owner)
3733@@ -1529,7 +1529,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3734 # default for that OCI project.
3735 requester = self.factory.makePerson()
3736 oci_project = self.factory.makeOCIProject()
3737- path = u"/%s/+oci/%s" % (oci_project.pillar.name, oci_project.name)
3738+ path = "/%s/+oci/%s" % (oci_project.pillar.name, oci_project.name)
3739 message = (
3740 "Cannot automatically set the default repository for this target; "
3741 "push to a named repository instead.")
3742@@ -1547,7 +1547,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3743 requester = self.factory.makePerson()
3744 project = self.factory.makeProduct()
3745 repository = self.assertCreates(
3746- requester, u"/~%s/%s" % (requester.name, project.name))
3747+ requester, "/~%s/%s" % (requester.name, project.name))
3748 self.assertFalse(repository.target_default)
3749 self.assertTrue(repository.owner_default)
3750 self.assertEqual(requester, repository.owner)
3751@@ -1559,7 +1559,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3752 team = self.factory.makeTeam(owner=requester)
3753 project = self.factory.makeProduct()
3754 repository = self.assertCreates(
3755- requester, u"/~%s/%s" % (team.name, project.name))
3756+ requester, "/~%s/%s" % (team.name, project.name))
3757 self.assertFalse(repository.target_default)
3758 self.assertTrue(repository.owner_default)
3759 self.assertEqual(team, repository.owner)
3760@@ -1571,7 +1571,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3761 team = self.factory.makeTeam(members=[requester])
3762 project = self.factory.makeProduct()
3763 repository = self.assertCreates(
3764- requester, u"/~%s/%s" % (team.name, project.name))
3765+ requester, "/~%s/%s" % (team.name, project.name))
3766 self.assertFalse(repository.target_default)
3767 self.assertTrue(repository.owner_default)
3768 self.assertEqual(team, repository.owner)
3769@@ -1581,7 +1581,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3770 # default for a package.
3771 requester = self.factory.makePerson()
3772 dsp = self.factory.makeDistributionSourcePackage()
3773- path = u"/~%s/%s/+source/%s" % (
3774+ path = "/~%s/%s/+source/%s" % (
3775 requester.name, dsp.distribution.name, dsp.sourcepackagename.name)
3776 repository = self.assertCreates(requester, path)
3777 self.assertFalse(repository.target_default)
3778@@ -1594,7 +1594,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3779 requester = self.factory.makePerson()
3780 team = self.factory.makeTeam(owner=requester)
3781 dsp = self.factory.makeDistributionSourcePackage()
3782- path = u"/~%s/%s/+source/%s" % (
3783+ path = "/~%s/%s/+source/%s" % (
3784 team.name, dsp.distribution.name, dsp.sourcepackagename.name)
3785 repository = self.assertCreates(requester, path)
3786 self.assertFalse(repository.target_default)
3787@@ -1607,7 +1607,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3788 requester = self.factory.makePerson()
3789 team = self.factory.makeTeam(members=[requester])
3790 dsp = self.factory.makeDistributionSourcePackage()
3791- path = u"/~%s/%s/+source/%s" % (
3792+ path = "/~%s/%s/+source/%s" % (
3793 team.name, dsp.distribution.name, dsp.sourcepackagename.name)
3794 repository = self.assertCreates(requester, path)
3795 self.assertFalse(repository.target_default)
3796@@ -1619,7 +1619,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3797 # default for an OCI project.
3798 requester = self.factory.makePerson()
3799 oci_project = self.factory.makeOCIProject()
3800- path = u"/~%s/%s/+oci/%s" % (
3801+ path = "/~%s/%s/+oci/%s" % (
3802 requester.name, oci_project.pillar.name, oci_project.name)
3803 repository = self.assertCreates(requester, path)
3804 self.assertFalse(repository.target_default)
3805@@ -1632,7 +1632,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3806 requester = self.factory.makePerson()
3807 team = self.factory.makeTeam(owner=requester)
3808 oci_project = self.factory.makeOCIProject()
3809- path = u"/~%s/%s/+oci/%s" % (
3810+ path = "/~%s/%s/+oci/%s" % (
3811 team.name, oci_project.pillar.name, oci_project.name)
3812 repository = self.assertCreates(requester, path)
3813 self.assertFalse(repository.target_default)
3814@@ -1645,7 +1645,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3815 requester = self.factory.makePerson()
3816 team = self.factory.makeTeam(members=[requester])
3817 oci_project = self.factory.makeOCIProject()
3818- path = u"/~%s/%s/+oci/%s" % (
3819+ path = "/~%s/%s/+oci/%s" % (
3820 team.name, oci_project.pillar.name, oci_project.name)
3821 repository = self.assertCreates(requester, path)
3822 self.assertFalse(repository.target_default)
3823@@ -1661,7 +1661,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3824 requester = self.factory.makePerson()
3825 initial_count = getUtility(IAllGitRepositories).count()
3826 oops_id = self.assertOopsOccurred(
3827- requester, u"/~%s/+git/random" % requester.name,
3828+ requester, "/~%s/+git/random" % requester.name,
3829 permission="write")
3830 login(ANONYMOUS)
3831 self.assertEqual(
3832@@ -1691,7 +1691,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3833 issuer = getUtility(IMacaroonIssuer, "code-import-job")
3834 macaroons = [
3835 removeSecurityProxy(issuer).issueMacaroon(job) for job in jobs]
3836- path = u"/%s" % code_imports[0].git_repository.unique_name
3837+ path = "/%s" % code_imports[0].git_repository.unique_name
3838 self.assertUnauthorized(
3839 LAUNCHPAD_SERVICES, path, permission="write",
3840 macaroon_raw=macaroons[0].serialize())
3841@@ -1735,7 +1735,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3842 issuer = getUtility(IMacaroonIssuer, "code-import-job")
3843 macaroons = [
3844 removeSecurityProxy(issuer).issueMacaroon(job) for job in jobs]
3845- path = u"/%s" % code_imports[0].git_repository.unique_name
3846+ path = "/%s" % code_imports[0].git_repository.unique_name
3847 self.assertUnauthorized(
3848 LAUNCHPAD_SERVICES, path, permission="write",
3849 macaroon_raw=macaroons[0].serialize())
3850@@ -1780,7 +1780,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3851 removeSecurityProxy(issuer).issueMacaroon(build)
3852 for build in builds]
3853 repository = refs[0].repository
3854- path = u"/%s" % repository.unique_name
3855+ path = "/%s" % repository.unique_name
3856 self.assertUnauthorized(
3857 LAUNCHPAD_SERVICES, path, permission="write",
3858 macaroon_raw=macaroons[0].serialize())
3859@@ -1819,7 +1819,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3860 repository, user=requester)
3861 for repository in repositories]
3862 paths = [
3863- u"/%s" % repository.unique_name for repository in repositories]
3864+ "/%s" % repository.unique_name for repository in repositories]
3865 for i, repository in enumerate(repositories):
3866 for j, macaroon in enumerate(macaroons):
3867 login(ANONYMOUS)
3868@@ -1853,7 +1853,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3869 self.useFixture(ZopeUtilityFixture(
3870 issuer, IMacaroonIssuer, name="test"))
3871 repository = self.factory.makeGitRepository()
3872- path = u"/%s" % repository.unique_name
3873+ path = "/%s" % repository.unique_name
3874 macaroon = issuer.issueMacaroon(repository)
3875 requesters = [self.factory.makePerson() for _ in range(2)]
3876 for verified_user, authorized, unauthorized in (
3877@@ -1881,8 +1881,8 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3878 requester_owner = self.factory.makePerson()
3879 repository = self.factory.makeGitRepository(owner=requester_owner)
3880 self.factory.makeGitRefs(
3881- repository=repository, paths=[u'refs/heads/master'])
3882- removeSecurityProxy(repository).default_branch = u'refs/heads/master'
3883+ repository=repository, paths=['refs/heads/master'])
3884+ removeSecurityProxy(repository).default_branch = 'refs/heads/master'
3885 pushed_branch = 'branch1'
3886 self.assertHasMergeProposalURL(repository, pushed_branch,
3887 {"uid": requester_owner.id})
3888@@ -1892,9 +1892,9 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3889 # Consequently LP will process any incoming branch from Turnip
3890 # as being non default and produce a merge proposal URL for it.
3891 self.factory.makeGitRefs(
3892- repository=repository, paths=[u'refs/heads/%s' % pushed_branch])
3893+ repository=repository, paths=['refs/heads/%s' % pushed_branch])
3894 removeSecurityProxy(repository).default_branch = (
3895- u'refs/heads/%s' % pushed_branch)
3896+ 'refs/heads/%s' % pushed_branch)
3897 self.assertHasMergeProposalURL(repository, pushed_branch,
3898 {"uid": requester_owner.id})
3899
3900@@ -1912,8 +1912,8 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3901 repository = self.factory.makeGitRepository(owner=requester)
3902 issuer = getUtility(IMacaroonIssuer, "git-repository")
3903 self.factory.makeGitRefs(
3904- repository=repository, paths=[u'refs/heads/master'])
3905- removeSecurityProxy(repository).default_branch = u'refs/heads/master'
3906+ repository=repository, paths=['refs/heads/master'])
3907+ removeSecurityProxy(repository).default_branch = 'refs/heads/master'
3908
3909 pushed_branch = 'branch1'
3910 with person_logged_in(requester):
3911@@ -1940,8 +1940,8 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
3912 owner = self.factory.makeTeam(members=requesters)
3913 repository = self.factory.makeGitRepository(owner=owner)
3914 self.factory.makeGitRefs(
3915- repository=repository, paths=[u'refs/heads/master'])
3916- removeSecurityProxy(repository).default_branch = u'refs/heads/master'
3917+ repository=repository, paths=['refs/heads/master'])
3918+ removeSecurityProxy(repository).default_branch = 'refs/heads/master'
3919 pushed_branch = 'branch1'
3920 macaroon = issuer.issueMacaroon(repository)
3921

Subscribers

People subscribed via source and target branches

to status/vote changes: