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
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index 91cb020..4691daf 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -22,3 +22,5 @@ b6725842a2470e3927bb73bf400c4476a06ee3ba
22474f07ab7c3f28d8b6b8e4f1bd4c56832cec3fab22474f07ab7c3f28d8b6b8e4f1bd4c56832cec3fab
23# apply pyupgrade --py3-plus to lp.code.browser23# apply pyupgrade --py3-plus to lp.code.browser
2447ee1259461aa54ad7ee967e85f6131be2b741252447ee1259461aa54ad7ee967e85f6131be2b74125
25# apply pyupgrade --py3-plus to lp.code
26cee9b128d3e49ca814464eeeeec50e6bcabcc4ba
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 47ab095..d82d7fe 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -48,7 +48,7 @@ repos:
48 |bugs48 |bugs
49 |buildmaster49 |buildmaster
50 |charms50 |charms
51 |code/browser51 |code
52 )/52 )/
53- repo: https://github.com/PyCQA/isort53- repo: https://github.com/PyCQA/isort
54 rev: 5.9.254 rev: 5.9.2
diff --git a/lib/lp/code/adapters/tests/test_gitrepository.py b/lib/lp/code/adapters/tests/test_gitrepository.py
index 5363a15..9983274 100644
--- a/lib/lp/code/adapters/tests/test_gitrepository.py
+++ b/lib/lp/code/adapters/tests/test_gitrepository.py
@@ -19,7 +19,7 @@ class TestGitRepositoryDelta(TestCaseWithFactory):
1919
20 def test_no_modification(self):20 def test_no_modification(self):
21 # If there are no modifications, no delta is returned.21 # If there are no modifications, no delta is returned.
22 repository = self.factory.makeGitRepository(name=u"foo")22 repository = self.factory.makeGitRepository(name="foo")
23 old_repository = Snapshot(repository, providing=providedBy(repository))23 old_repository = Snapshot(repository, providing=providedBy(repository))
24 delta = GitRepositoryDelta.construct(24 delta = GitRepositoryDelta.construct(
25 old_repository, repository, repository.owner)25 old_repository, repository, repository.owner)
@@ -30,18 +30,18 @@ class TestGitRepositoryDelta(TestCaseWithFactory):
30 owner = self.factory.makePerson(name="person")30 owner = self.factory.makePerson(name="person")
31 project = self.factory.makeProduct(name="project")31 project = self.factory.makeProduct(name="project")
32 repository = self.factory.makeGitRepository(32 repository = self.factory.makeGitRepository(
33 owner=owner, target=project, name=u"foo")33 owner=owner, target=project, name="foo")
34 old_repository = Snapshot(repository, providing=providedBy(repository))34 old_repository = Snapshot(repository, providing=providedBy(repository))
35 with person_logged_in(repository.owner):35 with person_logged_in(repository.owner):
36 repository.setName(u"bar", repository.owner)36 repository.setName("bar", repository.owner)
37 delta = GitRepositoryDelta.construct(old_repository, repository, owner)37 delta = GitRepositoryDelta.construct(old_repository, repository, owner)
38 self.assertIsNotNone(delta)38 self.assertIsNotNone(delta)
39 self.assertThat(delta, MatchesStructure.byEquality(39 self.assertThat(delta, MatchesStructure.byEquality(
40 name={40 name={
41 "old": u"foo",41 "old": "foo",
42 "new": u"bar",42 "new": "bar",
43 },43 },
44 git_identity={44 git_identity={
45 "old": u"lp:~person/project/+git/foo",45 "old": "lp:~person/project/+git/foo",
46 "new": u"lp:~person/project/+git/bar",46 "new": "lp:~person/project/+git/bar",
47 }))47 }))
diff --git a/lib/lp/code/errors.py b/lib/lp/code/errors.py
index 885662e..a4dc375 100644
--- a/lib/lp/code/errors.py
+++ b/lib/lp/code/errors.py
@@ -70,7 +70,6 @@ import http.client
7070
71from breezy.plugins.builder.recipe import RecipeParseError71from breezy.plugins.builder.recipe import RecipeParseError
72from lazr.restful.declarations import error_status72from lazr.restful.declarations import error_status
73import six
7473
75from lp.app.errors import (74from lp.app.errors import (
76 NameLookupFailed,75 NameLookupFailed,
@@ -203,8 +202,7 @@ class CannotUpgradeBranch(Exception):
203 """"Made for subclassing."""202 """"Made for subclassing."""
204203
205 def __init__(self, branch):204 def __init__(self, branch):
206 super(CannotUpgradeBranch, self).__init__(205 super().__init__(self._msg_template % branch.bzr_identity)
207 self._msg_template % branch.bzr_identity)
208 self.branch = branch206 self.branch = branch
209207
210208
@@ -254,7 +252,7 @@ class BranchMergeProposalExists(InvalidBranchMergeProposal):
254 display_name = "displayname"252 display_name = "displayname"
255 else:253 else:
256 display_name = "display_name"254 display_name = "display_name"
257 super(BranchMergeProposalExists, self).__init__(255 super().__init__(
258 'There is already a branch merge proposal registered for '256 'There is already a branch merge proposal registered for '
259 'branch %s to land on %s that is still active.' %257 'branch %s to land on %s that is still active.' %
260 (getattr(existing_proposal.merge_source, display_name),258 (getattr(existing_proposal.merge_source, display_name),
@@ -363,7 +361,7 @@ class BranchFileNotFound(BranchHostingFault):
363 """Raised when a file does not exist in a branch."""361 """Raised when a file does not exist in a branch."""
364362
365 def __init__(self, branch_id, filename=None, file_id=None, rev=None):363 def __init__(self, branch_id, filename=None, file_id=None, rev=None):
366 super(BranchFileNotFound, self).__init__()364 super().__init__()
367 if (filename is None) == (file_id is None):365 if (filename is None) == (file_id is None):
368 raise AssertionError(366 raise AssertionError(
369 "Exactly one of filename and file_id must be given.")367 "Exactly one of filename and file_id must be given.")
@@ -416,7 +414,6 @@ class GitRepositoryCreationForbidden(GitRepositoryCreationException):
416 """414 """
417415
418416
419@six.python_2_unicode_compatible
420@error_status(http.client.BAD_REQUEST)417@error_status(http.client.BAD_REQUEST)
421class GitRepositoryCreatorNotMemberOfOwnerTeam(GitRepositoryCreationException):418class GitRepositoryCreatorNotMemberOfOwnerTeam(GitRepositoryCreationException):
422 """Git repository creator is not a member of the owner team.419 """Git repository creator is not a member of the owner team.
@@ -435,7 +432,6 @@ class GitRepositoryCreatorNotMemberOfOwnerTeam(GitRepositoryCreationException):
435 return message432 return message
436433
437434
438@six.python_2_unicode_compatible
439@error_status(http.client.BAD_REQUEST)435@error_status(http.client.BAD_REQUEST)
440class GitRepositoryCreatorNotOwner(GitRepositoryCreationException):436class GitRepositoryCreatorNotOwner(GitRepositoryCreationException):
441 """A user cannot create a Git repository belonging to another user.437 """A user cannot create a Git repository belonging to another user.
@@ -458,7 +454,7 @@ class GitRepositoryCreationFault(Exception):
458 """Raised when there is a hosting fault creating a Git repository."""454 """Raised when there is a hosting fault creating a Git repository."""
459455
460 def __init__(self, message, path):456 def __init__(self, message, path):
461 super(GitRepositoryCreationFault, self).__init__(message)457 super().__init__(message)
462 self.path = path458 self.path = path
463459
464460
@@ -470,7 +466,7 @@ class GitRepositoryBlobNotFound(GitRepositoryScanFault):
470 """Raised when a blob does not exist in a repository."""466 """Raised when a blob does not exist in a repository."""
471467
472 def __init__(self, path, filename, rev=None):468 def __init__(self, path, filename, rev=None):
473 super(GitRepositoryBlobNotFound, self).__init__()469 super().__init__()
474 self.path = path470 self.path = path
475 self.filename = filename471 self.filename = filename
476 self.rev = rev472 self.rev = rev
@@ -486,7 +482,7 @@ class GitRepositoryBlobUnsupportedRemote(Exception):
486 """Raised when trying to fetch a blob from an unsupported remote host."""482 """Raised when trying to fetch a blob from an unsupported remote host."""
487483
488 def __init__(self, repository_url):484 def __init__(self, repository_url):
489 super(GitRepositoryBlobUnsupportedRemote, self).__init__()485 super().__init__()
490 self.repository_url = repository_url486 self.repository_url = repository_url
491487
492 def __str__(self):488 def __str__(self):
@@ -565,7 +561,7 @@ class CannotModifyNonHostedGitRepository(Exception):
565 """Raised when trying to modify a non-hosted Git repository."""561 """Raised when trying to modify a non-hosted Git repository."""
566562
567 def __init__(self, repository):563 def __init__(self, repository):
568 super(CannotModifyNonHostedGitRepository, self).__init__(564 super().__init__(
569 "Cannot modify non-hosted Git repository %s." %565 "Cannot modify non-hosted Git repository %s." %
570 repository.display_name)566 repository.display_name)
571567
@@ -579,7 +575,7 @@ class CodeImportAlreadyRequested(Exception):
579 """Raised when the user requests an import that is already requested."""575 """Raised when the user requests an import that is already requested."""
580576
581 def __init__(self, msg, requesting_user):577 def __init__(self, msg, requesting_user):
582 super(CodeImportAlreadyRequested, self).__init__(msg)578 super().__init__(msg)
583 self.requesting_user = requesting_user579 self.requesting_user = requesting_user
584580
585581
@@ -593,7 +589,7 @@ class CodeImportInvalidTargetType(Exception):
593 """Raised for code imports with an invalid target for their type."""589 """Raised for code imports with an invalid target for their type."""
594590
595 def __init__(self, target, target_rcs_type):591 def __init__(self, target, target_rcs_type):
596 super(CodeImportInvalidTargetType, self).__init__(592 super().__init__(
597 "Objects of type %s do not support code imports targeting %s." %593 "Objects of type %s do not support code imports targeting %s." %
598 (target.__class__.__name__, target_rcs_type))594 (target.__class__.__name__, target_rcs_type))
599595
@@ -603,7 +599,7 @@ class TooNewRecipeFormat(Exception):
603 """The format of the recipe supplied was too new."""599 """The format of the recipe supplied was too new."""
604600
605 def __init__(self, supplied_format, newest_supported):601 def __init__(self, supplied_format, newest_supported):
606 super(TooNewRecipeFormat, self).__init__()602 super().__init__()
607 self.supplied_format = supplied_format603 self.supplied_format = supplied_format
608 self.newest_supported = newest_supported604 self.newest_supported = newest_supported
609605
diff --git a/lib/lp/code/event/git.py b/lib/lp/code/event/git.py
index bc89694..317c687 100644
--- a/lib/lp/code/event/git.py
+++ b/lib/lp/code/event/git.py
@@ -18,6 +18,6 @@ class GitRefsUpdatedEvent(ObjectEvent):
18 """See `IGitRefsUpdatedEvent`."""18 """See `IGitRefsUpdatedEvent`."""
1919
20 def __init__(self, repository, paths, logger):20 def __init__(self, repository, paths, logger):
21 super(GitRefsUpdatedEvent, self).__init__(repository)21 super().__init__(repository)
22 self.paths = paths22 self.paths = paths
23 self.logger = logger23 self.logger = logger
diff --git a/lib/lp/code/feed/branch.py b/lib/lp/code/feed/branch.py
index 3339134..27d2047 100644
--- a/lib/lp/code/feed/branch.py
+++ b/lib/lp/code/feed/branch.py
@@ -67,7 +67,7 @@ class BranchFeedContentView(BranchView):
6767
68 def __init__(self, context, request, feed,68 def __init__(self, context, request, feed,
69 template='templates/branch.pt'):69 template='templates/branch.pt'):
70 super(BranchFeedContentView, self).__init__(context, request)70 super().__init__(context, request)
71 self.feed = feed71 self.feed = feed
72 self.template_ = template72 self.template_ = template
7373
@@ -196,7 +196,7 @@ class RevisionFeedContentView(LaunchpadView):
196 """View for a revision feed contents."""196 """View for a revision feed contents."""
197197
198 def __init__(self, context, request, feed):198 def __init__(self, context, request, feed):
199 super(RevisionFeedContentView, self).__init__(context, request)199 super().__init__(context, request)
200 self.feed = feed200 self.feed = feed
201201
202 @cachedproperty202 @cachedproperty
@@ -391,7 +391,7 @@ class BranchFeed(BranchFeedBase):
391 def initialize(self):391 def initialize(self):
392 """See `IFeed`."""392 """See `IFeed`."""
393 # For a `BranchFeed` we must ensure that the branch is not private.393 # For a `BranchFeed` we must ensure that the branch is not private.
394 super(BranchFeed, self).initialize()394 super().initialize()
395 try:395 try:
396 feed_allowed = not self.context.private396 feed_allowed = not self.context.private
397 if not feed_allowed:397 if not feed_allowed:
diff --git a/lib/lp/code/interfaces/branch.py b/lib/lp/code/interfaces/branch.py
index e6d4e14..57d63e4 100644
--- a/lib/lp/code/interfaces/branch.py
+++ b/lib/lp/code/interfaces/branch.py
@@ -281,7 +281,7 @@ class IBranchView(IHasOwner, IHasBranchTarget, IHasMergeProposals,
281 id = Int(title=_('ID'), readonly=True, required=True)281 id = Int(title=_('ID'), readonly=True, required=True)
282282
283 @operation_parameters(283 @operation_parameters(
284 scheme=TextLine(title=_("URL scheme"), default=u'http'))284 scheme=TextLine(title=_("URL scheme"), default='http'))
285 @export_read_operation()285 @export_read_operation()
286 @operation_for_version('beta')286 @operation_for_version('beta')
287 def composePublicURL(scheme='http'):287 def composePublicURL(scheme='http'):
@@ -1376,11 +1376,11 @@ class IBranchSet(Interface):
13761376
1377 @operation_parameters(1377 @operation_parameters(
1378 urls=List(1378 urls=List(
1379 title=u'A list of URLs of branches',1379 title='A list of URLs of branches',
1380 description=(1380 description=(
1381 u'These can be URLs external to '1381 'These can be URLs external to '
1382 u'Launchpad, lp: URLs, or http://bazaar.launchpad.net/ URLs, '1382 'Launchpad, lp: URLs, or http://bazaar.launchpad.net/ URLs, '
1383 u'or any mix of all these different kinds.'),1383 'or any mix of all these different kinds.'),
1384 value_type=TextLine(),1384 value_type=TextLine(),
1385 required=True))1385 required=True))
1386 @export_read_operation()1386 @export_read_operation()
diff --git a/lib/lp/code/interfaces/branchjob.py b/lib/lp/code/interfaces/branchjob.py
index 6ab861e..4f14416 100644
--- a/lib/lp/code/interfaces/branchjob.py
+++ b/lib/lp/code/interfaces/branchjob.py
@@ -91,13 +91,13 @@ class IBranchUpgradeJobSource(IJobSource):
91class IRevisionMailJob(IRunnableJob):91class IRevisionMailJob(IRunnableJob):
92 """A Job to send email a revision change in a branch."""92 """A Job to send email a revision change in a branch."""
9393
94 revno = Int(title=u'The revno to send mail about.')94 revno = Int(title='The revno to send mail about.')
9595
96 from_address = Bytes(title=u'The address to send mail from.')96 from_address = Bytes(title='The address to send mail from.')
9797
98 body = Text(title=u'The main text of the email to send.')98 body = Text(title='The main text of the email to send.')
9999
100 subject = Text(title=u'The subject of the email to send.')100 subject = Text(title='The subject of the email to send.')
101101
102102
103class IRevisionMailJobSource(IJobSource):103class IRevisionMailJobSource(IJobSource):
diff --git a/lib/lp/code/interfaces/codeimport.py b/lib/lp/code/interfaces/codeimport.py
index 7799e90..1a3e5a1 100644
--- a/lib/lp/code/interfaces/codeimport.py
+++ b/lib/lp/code/interfaces/codeimport.py
@@ -55,7 +55,7 @@ class CVSRootError(Exception):
55 """Raised when trying to use a CVSROOT with invalid syntax."""55 """Raised when trying to use a CVSROOT with invalid syntax."""
5656
57 def __init__(self, root):57 def __init__(self, root):
58 super(CVSRootError, self).__init__(self, 'bad CVSROOT: %r' % root)58 super().__init__(self, 'bad CVSROOT: %r' % root)
5959
6060
61_cvs_root_parser = re.compile(r"""61_cvs_root_parser = re.compile(r"""
diff --git a/lib/lp/code/interfaces/gitrepository.py b/lib/lp/code/interfaces/gitrepository.py
index aae1b90..d2d6a90 100644
--- a/lib/lp/code/interfaces/gitrepository.py
+++ b/lib/lp/code/interfaces/gitrepository.py
@@ -832,7 +832,7 @@ class RevisionStatusReportsFeatureDisabled(Unauthorized):
832 """Only certain users can access APIs for revision status reports."""832 """Only certain users can access APIs for revision status reports."""
833833
834 def __init__(self):834 def __init__(self):
835 super(RevisionStatusReportsFeatureDisabled, self).__init__(835 super().__init__(
836 "You do not have permission to create revision status reports")836 "You do not have permission to create revision status reports")
837837
838838
diff --git a/lib/lp/code/interfaces/sourcepackagerecipe.py b/lib/lp/code/interfaces/sourcepackagerecipe.py
index f954618..af05f7b 100644
--- a/lib/lp/code/interfaces/sourcepackagerecipe.py
+++ b/lib/lp/code/interfaces/sourcepackagerecipe.py
@@ -69,13 +69,13 @@ from lp.services.fields import (
69from lp.soyuz.interfaces.archive import IArchive69from lp.soyuz.interfaces.archive import IArchive
7070
7171
72MINIMAL_RECIPE_TEXT_BZR = dedent(u'''\72MINIMAL_RECIPE_TEXT_BZR = dedent('''\
73 # bzr-builder format 0.3 deb-version {debupstream}-0~{revno}73 # bzr-builder format 0.3 deb-version {debupstream}-0~{revno}
74 %s74 %s
75 ''')75 ''')
7676
7777
78MINIMAL_RECIPE_TEXT_GIT = dedent(u'''\78MINIMAL_RECIPE_TEXT_GIT = dedent('''\
79 # git-build-recipe format 0.4 deb-version {debupstream}-0~{revtime}79 # git-build-recipe format 0.4 deb-version {debupstream}-0~{revtime}
80 %s %s80 %s %s
81 ''')81 ''')
diff --git a/lib/lp/code/mail/branch.py b/lib/lp/code/mail/branch.py
index c36a8b7..5de23f2 100644
--- a/lib/lp/code/mail/branch.py
+++ b/lib/lp/code/mail/branch.py
@@ -58,8 +58,7 @@ class RecipientReason(basemailer.RecipientReason):
58 max_diff_lines=BranchSubscriptionDiffSize.WHOLEDIFF,58 max_diff_lines=BranchSubscriptionDiffSize.WHOLEDIFF,
59 branch_identity_cache=None,59 branch_identity_cache=None,
60 review_level=CodeReviewNotificationLevel.FULL):60 review_level=CodeReviewNotificationLevel.FULL):
61 super(RecipientReason, self).__init__(subscriber, recipient,61 super().__init__(subscriber, recipient, mail_header, reason_template)
62 mail_header, reason_template)
63 self.branch = branch62 self.branch = branch
64 self.merge_proposal = merge_proposal63 self.merge_proposal = merge_proposal
65 self.max_diff_lines = max_diff_lines64 self.max_diff_lines = max_diff_lines
@@ -150,7 +149,7 @@ class RecipientReason(basemailer.RecipientReason):
150 branch_identity_cache=branch_identity_cache)149 branch_identity_cache=branch_identity_cache)
151150
152 def _getTemplateValues(self):151 def _getTemplateValues(self):
153 template_values = super(RecipientReason, self)._getTemplateValues()152 template_values = super()._getTemplateValues()
154 template_values['branch_name'] = self._getBranchIdentity(self.branch)153 template_values['branch_name'] = self._getBranchIdentity(self.branch)
155 if self.merge_proposal is not None:154 if self.merge_proposal is not None:
156 source = self._getBranchIdentity(self.merge_proposal.merge_source)155 source = self._getBranchIdentity(self.merge_proposal.merge_source)
@@ -169,7 +168,7 @@ class BranchMailer(BaseMailer):
169 delta=None, delta_for_editors=None, contents=None, diff=None,168 delta=None, delta_for_editors=None, contents=None, diff=None,
170 message_id=None, revno=None, revision_id=None,169 message_id=None, revno=None, revision_id=None,
171 notification_type=None, **kwargs):170 notification_type=None, **kwargs):
172 super(BranchMailer, self).__init__(171 super().__init__(
173 subject, template_name, recipients, from_address,172 subject, template_name, recipients, from_address,
174 message_id=message_id, notification_type=notification_type)173 message_id=message_id, notification_type=notification_type)
175 self.delta_text = delta174 self.delta_text = delta
diff --git a/lib/lp/code/mail/sourcepackagerecipebuild.py b/lib/lp/code/mail/sourcepackagerecipebuild.py
index 5b81714..a12452e 100644
--- a/lib/lp/code/mail/sourcepackagerecipebuild.py
+++ b/lib/lp/code/mail/sourcepackagerecipebuild.py
@@ -42,8 +42,7 @@ class SourcePackageRecipeBuildMailer(BaseMailer):
4242
43 def _getHeaders(self, email, recipient):43 def _getHeaders(self, email, recipient):
44 """See `BaseMailer`"""44 """See `BaseMailer`"""
45 headers = super(45 headers = super()._getHeaders(email, recipient)
46 SourcePackageRecipeBuildMailer, self)._getHeaders(email, recipient)
47 headers.update({46 headers.update({
48 'X-Launchpad-Archive': self.build.archive.reference,47 'X-Launchpad-Archive': self.build.archive.reference,
49 'X-Launchpad-Build-State': self.build.status.name,48 'X-Launchpad-Build-State': self.build.status.name,
@@ -52,9 +51,7 @@ class SourcePackageRecipeBuildMailer(BaseMailer):
5251
53 def _getTemplateParams(self, email, recipient):52 def _getTemplateParams(self, email, recipient):
54 """See `BaseMailer`"""53 """See `BaseMailer`"""
55 params = super(54 params = super()._getTemplateParams(email, recipient)
56 SourcePackageRecipeBuildMailer, self)._getTemplateParams(
57 email, recipient)
58 params.update({55 params.update({
59 'status': self.build.status.title,56 'status': self.build.status.title,
60 'build_id': self.build.id,57 'build_id': self.build.id,
diff --git a/lib/lp/code/mail/tests/test_branch.py b/lib/lp/code/mail/tests/test_branch.py
index 69ed7dd..ee56593 100644
--- a/lib/lp/code/mail/tests/test_branch.py
+++ b/lib/lp/code/mail/tests/test_branch.py
@@ -306,7 +306,7 @@ class TestBranchMailerDiffMixin:
306306
307 def test_generateEmail_with_diff(self):307 def test_generateEmail_with_diff(self):
308 """When there is a diff, it should be an attachment, not inline."""308 """When there is a diff, it should be an attachment, not inline."""
309 ctrl = self.makeBobMailController(diff=u'hello \u03A3')309 ctrl = self.makeBobMailController(diff='hello \u03A3')
310 self.assertEqual(1, len(ctrl.attachments))310 self.assertEqual(1, len(ctrl.attachments))
311 diff = ctrl.attachments[0]311 diff = ctrl.attachments[0]
312 self.assertEqual(b'hello \xce\xa3', diff.get_payload(decode=True))312 self.assertEqual(b'hello \xce\xa3', diff.get_payload(decode=True))
diff --git a/lib/lp/code/mail/tests/test_branchmergeproposal.py b/lib/lp/code/mail/tests/test_branchmergeproposal.py
index 537918f..8e1e6f7 100644
--- a/lib/lp/code/mail/tests/test_branchmergeproposal.py
+++ b/lib/lp/code/mail/tests/test_branchmergeproposal.py
@@ -57,7 +57,7 @@ class TestMergeProposalMailing(TestCaseWithFactory):
57 layer = LaunchpadZopelessLayer57 layer = LaunchpadZopelessLayer
5858
59 def setUp(self):59 def setUp(self):
60 super(TestMergeProposalMailing, self).setUp('admin@canonical.com')60 super().setUp('admin@canonical.com')
6161
62 def makeProposalWithSubscriber(self, diff_text=None, initial_comment=None,62 def makeProposalWithSubscriber(self, diff_text=None, initial_comment=None,
63 prerequisite=False, needs_review=True,63 prerequisite=False, needs_review=True,
diff --git a/lib/lp/code/mail/tests/test_codehandler.py b/lib/lp/code/mail/tests/test_codehandler.py
index 21f8256..4788904 100644
--- a/lib/lp/code/mail/tests/test_codehandler.py
+++ b/lib/lp/code/mail/tests/test_codehandler.py
@@ -129,13 +129,13 @@ class TestCodeHandler(TestCaseWithFactory):
129 layer = ZopelessAppServerLayer129 layer = ZopelessAppServerLayer
130130
131 def setUp(self):131 def setUp(self):
132 super(TestCodeHandler, self).setUp(user='test@canonical.com')132 super().setUp(user='test@canonical.com')
133 self.code_handler = CodeHandler()133 self.code_handler = CodeHandler()
134 self._old_policy = setSecurityPolicy(LaunchpadSecurityPolicy)134 self._old_policy = setSecurityPolicy(LaunchpadSecurityPolicy)
135135
136 def tearDown(self):136 def tearDown(self):
137 setSecurityPolicy(self._old_policy)137 setSecurityPolicy(self._old_policy)
138 super(TestCodeHandler, self).tearDown()138 super().tearDown()
139139
140 def test_get(self):140 def test_get(self):
141 handler = mail_handlers.get(config.launchpad.code_domain)141 handler = mail_handlers.get(config.launchpad.code_domain)
@@ -453,7 +453,7 @@ class TestVoteEmailCommand(TestCase):
453 # We don't need no stinking layer.453 # We don't need no stinking layer.
454454
455 def setUp(self):455 def setUp(self):
456 super(TestVoteEmailCommand, self).setUp()456 super().setUp()
457457
458 class FakeExecutionContext:458 class FakeExecutionContext:
459 vote = None459 vote = None
@@ -555,8 +555,7 @@ class TestUpdateStatusEmailCommand(TestCaseWithFactory):
555 layer = LaunchpadZopelessLayer555 layer = LaunchpadZopelessLayer
556556
557 def setUp(self):557 def setUp(self):
558 super(TestUpdateStatusEmailCommand, self).setUp(558 super().setUp(user='test@canonical.com')
559 user='test@canonical.com')
560 self._old_policy = setSecurityPolicy(LaunchpadSecurityPolicy)559 self._old_policy = setSecurityPolicy(LaunchpadSecurityPolicy)
561 self.merge_proposal = self.factory.makeBranchMergeProposal()560 self.merge_proposal = self.factory.makeBranchMergeProposal()
562 # Default the user to be the target branch owner, so they are561 # Default the user to be the target branch owner, so they are
@@ -568,7 +567,7 @@ class TestUpdateStatusEmailCommand(TestCaseWithFactory):
568567
569 def tearDown(self):568 def tearDown(self):
570 setSecurityPolicy(self._old_policy)569 setSecurityPolicy(self._old_policy)
571 super(TestUpdateStatusEmailCommand, self).tearDown()570 super().tearDown()
572571
573 def test_numberOfArguments(self):572 def test_numberOfArguments(self):
574 # The command needs one and only one arg.573 # The command needs one and only one arg.
@@ -678,8 +677,7 @@ class TestAddReviewerEmailCommand(TestCaseWithFactory):
678 layer = LaunchpadZopelessLayer677 layer = LaunchpadZopelessLayer
679678
680 def setUp(self):679 def setUp(self):
681 super(TestAddReviewerEmailCommand, self).setUp(680 super().setUp(user='test@canonical.com')
682 user='test@canonical.com')
683 self._old_policy = setSecurityPolicy(LaunchpadSecurityPolicy)681 self._old_policy = setSecurityPolicy(LaunchpadSecurityPolicy)
684 self.merge_proposal = (682 self.merge_proposal = (
685 make_merge_proposal_without_reviewers(self.factory))683 make_merge_proposal_without_reviewers(self.factory))
@@ -692,7 +690,7 @@ class TestAddReviewerEmailCommand(TestCaseWithFactory):
692690
693 def tearDown(self):691 def tearDown(self):
694 setSecurityPolicy(self._old_policy)692 setSecurityPolicy(self._old_policy)
695 super(TestAddReviewerEmailCommand, self).tearDown()693 super().tearDown()
696694
697 def test_numberOfArguments(self):695 def test_numberOfArguments(self):
698 # The command needs at least one arg.696 # The command needs at least one arg.
diff --git a/lib/lp/code/mail/tests/test_codeimport.py b/lib/lp/code/mail/tests/test_codeimport.py
index ee62761..77eefa5 100644
--- a/lib/lp/code/mail/tests/test_codeimport.py
+++ b/lib/lp/code/mail/tests/test_codeimport.py
@@ -110,7 +110,7 @@ class TestNewCodeImports(TestCaseWithFactory):
110 login_person(eric)110 login_person(eric)
111 self.factory.makeProductCodeImport(111 self.factory.makeProductCodeImport(
112 git_repo_url='git://git.example.com/fooix.git',112 git_repo_url='git://git.example.com/fooix.git',
113 branch_name=u'master', product=fooix, registrant=eric,113 branch_name='master', product=fooix, registrant=eric,
114 target_rcs_type=TargetRevisionControlSystems.GIT)114 target_rcs_type=TargetRevisionControlSystems.GIT)
115 transaction.commit()115 transaction.commit()
116 msg = email.message_from_bytes(stub.test_emails[0][2])116 msg = email.message_from_bytes(stub.test_emails[0][2])
diff --git a/lib/lp/code/mail/tests/test_sourcepackagerecipebuild.py b/lib/lp/code/mail/tests/test_sourcepackagerecipebuild.py
index b0f8f25..ed194e3 100644
--- a/lib/lp/code/mail/tests/test_sourcepackagerecipebuild.py
+++ b/lib/lp/code/mail/tests/test_sourcepackagerecipebuild.py
@@ -16,7 +16,7 @@ from lp.testing.dbuser import switch_dbuser
16from lp.testing.layers import LaunchpadZopelessLayer16from lp.testing.layers import LaunchpadZopelessLayer
1717
1818
19expected_body = u"""\19expected_body = """\
20 * State: Successfully built20 * State: Successfully built
21 * Recipe: person/recipe21 * Recipe: person/recipe
22 * Archive: ~archiveowner/ubuntu/ppa22 * Archive: ~archiveowner/ubuntu/ppa
@@ -27,7 +27,7 @@ expected_body = u"""\
27 * Builder: http://launchpad.test/builders/bob27 * Builder: http://launchpad.test/builders/bob
28""" # noqa: W29128""" # noqa: W291
2929
30superseded_body = u"""\30superseded_body = """\
31 * State: Build for superseded Source31 * State: Build for superseded Source
32 * Recipe: person/recipe32 * Recipe: person/recipe
33 * Archive: ~archiveowner/ubuntu/ppa33 * Archive: ~archiveowner/ubuntu/ppa
@@ -53,10 +53,10 @@ class TestSourcePackageRecipeBuildMailer(TestCaseWithFactory):
53 """GenerateEmail produces the right headers and body."""53 """GenerateEmail produces the right headers and body."""
54 person = self.factory.makePerson(name='person')54 person = self.factory.makePerson(name='person')
55 cake = self.factory.makeSourcePackageRecipe(55 cake = self.factory.makeSourcePackageRecipe(
56 name=u'recipe', owner=person)56 name='recipe', owner=person)
57 pantry_owner = self.factory.makePerson(name='archiveowner')57 pantry_owner = self.factory.makePerson(name='archiveowner')
58 pantry = self.factory.makeArchive(name='ppa', owner=pantry_owner)58 pantry = self.factory.makeArchive(name='ppa', owner=pantry_owner)
59 secret = self.factory.makeDistroSeries(name=u'distroseries')59 secret = self.factory.makeDistroSeries(name='distroseries')
60 secret.nominatedarchindep = (60 secret.nominatedarchindep = (
61 self.factory.makeDistroArchSeries(distroseries=secret))61 self.factory.makeDistroArchSeries(distroseries=secret))
62 build = self.factory.makeSourcePackageRecipeBuild(62 build = self.factory.makeSourcePackageRecipeBuild(
@@ -64,11 +64,11 @@ class TestSourcePackageRecipeBuildMailer(TestCaseWithFactory):
64 status=BuildStatus.FULLYBUILT, duration=timedelta(minutes=5))64 status=BuildStatus.FULLYBUILT, duration=timedelta(minutes=5))
65 build.updateStatus(65 build.updateStatus(
66 BuildStatus.FULLYBUILT,66 BuildStatus.FULLYBUILT,
67 builder=self.factory.makeBuilder(name=u'bob'))67 builder=self.factory.makeBuilder(name='bob'))
68 build.setLog(self.factory.makeLibraryFileAlias())68 build.setLog(self.factory.makeLibraryFileAlias())
69 ctrl = self.makeStatusEmail(build)69 ctrl = self.makeStatusEmail(build)
70 self.assertEqual(70 self.assertEqual(
71 u'[recipe build #%d] of ~person recipe in distroseries: '71 '[recipe build #%d] of ~person recipe in distroseries: '
72 'Successfully built' % (build.id), ctrl.subject)72 'Successfully built' % (build.id), ctrl.subject)
73 body, footer = ctrl.body.split('\n-- \n')73 body, footer = ctrl.body.split('\n-- \n')
74 self.assertEqual(expected_body % build.log_url, body)74 self.assertEqual(expected_body % build.log_url, body)
@@ -93,10 +93,10 @@ class TestSourcePackageRecipeBuildMailer(TestCaseWithFactory):
93 """GenerateEmail works when many fields are NULL."""93 """GenerateEmail works when many fields are NULL."""
94 person = self.factory.makePerson(name='person')94 person = self.factory.makePerson(name='person')
95 cake = self.factory.makeSourcePackageRecipe(95 cake = self.factory.makeSourcePackageRecipe(
96 name=u'recipe', owner=person)96 name='recipe', owner=person)
97 pantry_owner = self.factory.makePerson(name='archiveowner')97 pantry_owner = self.factory.makePerson(name='archiveowner')
98 pantry = self.factory.makeArchive(name='ppa', owner=pantry_owner)98 pantry = self.factory.makeArchive(name='ppa', owner=pantry_owner)
99 secret = self.factory.makeDistroSeries(name=u'distroseries')99 secret = self.factory.makeDistroSeries(name='distroseries')
100 secret.nominatedarchindep = (100 secret.nominatedarchindep = (
101 self.factory.makeDistroArchSeries(distroseries=secret))101 self.factory.makeDistroArchSeries(distroseries=secret))
102 build = self.factory.makeSourcePackageRecipeBuild(102 build = self.factory.makeSourcePackageRecipeBuild(
@@ -105,7 +105,7 @@ class TestSourcePackageRecipeBuildMailer(TestCaseWithFactory):
105 Store.of(build).flush()105 Store.of(build).flush()
106 ctrl = self.makeStatusEmail(build)106 ctrl = self.makeStatusEmail(build)
107 self.assertEqual(107 self.assertEqual(
108 u'[recipe build #%d] of ~person recipe in distroseries: '108 '[recipe build #%d] of ~person recipe in distroseries: '
109 'Build for superseded Source' % (build.id), ctrl.subject)109 'Build for superseded Source' % (build.id), ctrl.subject)
110 body, footer = ctrl.body.split('\n-- \n')110 body, footer = ctrl.body.split('\n-- \n')
111 self.assertEqual(superseded_body, body)111 self.assertEqual(superseded_body, body)
diff --git a/lib/lp/code/model/branch.py b/lib/lp/code/model/branch.py
index 1a9bcc4..98952be 100644
--- a/lib/lp/code/model/branch.py
+++ b/lib/lp/code/model/branch.py
@@ -811,7 +811,7 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
811 hosting_client = getUtility(IBranchHostingClient)811 hosting_client = getUtility(IBranchHostingClient)
812 if enable_memcache is None:812 if enable_memcache is None:
813 enable_memcache = not getFeatureFlag(813 enable_memcache = not getFeatureFlag(
814 u'code.bzr.blob.disable_memcache')814 'code.bzr.blob.disable_memcache')
815 if revision_id is None:815 if revision_id is None:
816 revision_id = self.last_scanned_id816 revision_id = self.last_scanned_id
817 if revision_id is None:817 if revision_id is None:
@@ -1138,7 +1138,7 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
11381138
1139 def removeBranchRevisions(self, revision_ids):1139 def removeBranchRevisions(self, revision_ids):
1140 """See `IBranch`."""1140 """See `IBranch`."""
1141 if isinstance(revision_ids, six.string_types):1141 if isinstance(revision_ids, str):
1142 revision_ids = [revision_ids]1142 revision_ids = [revision_ids]
1143 IMasterStore(BranchRevision).find(1143 IMasterStore(BranchRevision).find(
1144 BranchRevision,1144 BranchRevision,
diff --git a/lib/lp/code/model/branchcollection.py b/lib/lp/code/model/branchcollection.py
index 6ba75ec..fe27bc6 100644
--- a/lib/lp/code/model/branchcollection.py
+++ b/lib/lp/code/model/branchcollection.py
@@ -562,7 +562,7 @@ class GenericBranchCollection:
562 bugtasks_for_branch[bugbranch.branch].append(bugtask)562 bugtasks_for_branch[bugbranch.branch].append(bugtask)
563563
564 # Now filter those down to one bugtask per branch564 # Now filter those down to one bugtask per branch
565 for branch, tasks in six.iteritems(bugtasks_for_branch):565 for branch, tasks in bugtasks_for_branch.items():
566 linked_bugtasks[branch.id].extend(566 linked_bugtasks[branch.id].extend(
567 filter_bugtasks_by_context(branch.target.context, tasks))567 filter_bugtasks_by_context(branch.target.context, tasks))
568568
@@ -786,7 +786,7 @@ class VisibleBranchCollection(GenericBranchCollection):
786 def __init__(self, user, store=None, branch_filter_expressions=None,786 def __init__(self, user, store=None, branch_filter_expressions=None,
787 tables=None,787 tables=None,
788 asymmetric_filter_expressions=None, asymmetric_tables=None):788 asymmetric_filter_expressions=None, asymmetric_tables=None):
789 super(VisibleBranchCollection, self).__init__(789 super().__init__(
790 store=store, branch_filter_expressions=branch_filter_expressions,790 store=store, branch_filter_expressions=branch_filter_expressions,
791 tables=tables,791 tables=tables,
792 asymmetric_filter_expressions=asymmetric_filter_expressions,792 asymmetric_filter_expressions=asymmetric_filter_expressions,
diff --git a/lib/lp/code/model/branchhosting.py b/lib/lp/code/model/branchhosting.py
index 58594e3..3911c16 100644
--- a/lib/lp/code/model/branchhosting.py
+++ b/lib/lp/code/model/branchhosting.py
@@ -12,7 +12,6 @@ import sys
1212
13from lazr.restful.utils import get_current_browser_request13from lazr.restful.utils import get_current_browser_request
14import requests14import requests
15from six import reraise
16from six.moves.urllib_parse import (15from six.moves.urllib_parse import (
17 quote,16 quote,
18 urljoin,17 urljoin,
@@ -72,9 +71,7 @@ class BranchHostingClient:
72 except Exception:71 except Exception:
73 _, val, tb = sys.exc_info()72 _, val, tb = sys.exc_info()
74 try:73 try:
75 reraise(74 raise RequestExceptionWrapper(*val.args).with_traceback(tb)
76 RequestExceptionWrapper,
77 RequestExceptionWrapper(*val.args), tb)
78 finally:75 finally:
79 # Avoid traceback reference cycles.76 # Avoid traceback reference cycles.
80 del val, tb77 del val, tb
diff --git a/lib/lp/code/model/branchjob.py b/lib/lp/code/model/branchjob.py
index 5d7c0d8..aa06aeb 100644
--- a/lib/lp/code/model/branchjob.py
+++ b/lib/lp/code/model/branchjob.py
@@ -227,7 +227,7 @@ class BranchJob(StormBase):
227 :param metadata: The type-specific variables, as a JSON-compatible227 :param metadata: The type-specific variables, as a JSON-compatible
228 dict.228 dict.
229 """229 """
230 super(BranchJob, self).__init__()230 super().__init__()
231 self.job = Job(**job_args)231 self.job = Job(**job_args)
232 self.branch = branch232 self.branch = branch
233 self.job_type = job_type233 self.job_type = job_type
@@ -329,7 +329,7 @@ class BranchScanJob(BranchJobDerived):
329 return cls(branch_job)329 return cls(branch_job)
330330
331 def __init__(self, branch_job):331 def __init__(self, branch_job):
332 super(BranchScanJob, self).__init__(branch_job)332 super().__init__(branch_job)
333 self._cached_branch_name = self.metadata['branch_name']333 self._cached_branch_name = self.metadata['branch_name']
334334
335 @staticmethod335 @staticmethod
@@ -507,7 +507,7 @@ class RevisionsAddedJob(BranchJobDerived):
507 return RevisionsAddedJob(branch_job)507 return RevisionsAddedJob(branch_job)
508508
509 def __init__(self, context):509 def __init__(self, context):
510 super(RevisionsAddedJob, self).__init__(context)510 super().__init__(context)
511 self._bzr_branch = None511 self._bzr_branch = None
512 self._tree_cache = {}512 self._tree_cache = {}
513513
@@ -690,7 +690,7 @@ class RevisionsAddedJob(BranchJobDerived):
690 proposals[source_id] = (proposal, date_created)690 proposals[source_id] = (proposal, date_created)
691691
692 return sorted(692 return sorted(
693 (proposal for proposal, date_created in six.itervalues(proposals)),693 (proposal for proposal, date_created in proposals.values()),
694 key=operator.attrgetter('date_created'), reverse=True)694 key=operator.attrgetter('date_created'), reverse=True)
695695
696 def getRevisionMessage(self, revision_id, revno):696 def getRevisionMessage(self, revision_id, revno):
@@ -763,7 +763,7 @@ class RosettaUploadJob(BranchJobDerived):
763 config = config.IRosettaUploadJobSource763 config = config.IRosettaUploadJobSource
764764
765 def __init__(self, branch_job):765 def __init__(self, branch_job):
766 super(RosettaUploadJob, self).__init__(branch_job)766 super().__init__(branch_job)
767767
768 self.template_file_names = []768 self.template_file_names = []
769 self.template_files_changed = []769 self.template_files_changed = []
diff --git a/lib/lp/code/model/branchmergeproposal.py b/lib/lp/code/model/branchmergeproposal.py
index a0ff7d1..f0f23d7 100644
--- a/lib/lp/code/model/branchmergeproposal.py
+++ b/lib/lp/code/model/branchmergeproposal.py
@@ -18,7 +18,6 @@ from lazr.lifecycle.event import (
18 ObjectCreatedEvent,18 ObjectCreatedEvent,
19 ObjectDeletedEvent,19 ObjectDeletedEvent,
20 )20 )
21import six
22from storm.expr import (21from storm.expr import (
23 And,22 And,
24 Desc,23 Desc,
@@ -392,8 +391,7 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
392 else:391 else:
393 bug_ids = [392 bug_ids = [
394 int(id) for _, id in getUtility(IXRefSet).findFrom(393 int(id) for _, id in getUtility(IXRefSet).findFrom(
395 (u'merge_proposal', six.text_type(self.id)),394 ('merge_proposal', str(self.id)), types=['bug'])]
396 types=[u'bug'])]
397 bugs = load(Bug, bug_ids)395 bugs = load(Bug, bug_ids)
398 return list(sorted(bugs, key=attrgetter('id')))396 return list(sorted(bugs, key=attrgetter('id')))
399397
@@ -420,14 +418,12 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
420 props = {}418 props = {}
421 # XXX cjwatson 2016-06-11: Should set creator.419 # XXX cjwatson 2016-06-11: Should set creator.
422 getUtility(IXRefSet).create(420 getUtility(IXRefSet).create(
423 {(u'merge_proposal', six.text_type(self.id)):421 {('merge_proposal', str(self.id)): {('bug', str(bug.id)): props}})
424 {(u'bug', six.text_type(bug.id)): props}})
425422
426 def deleteBugLink(self, bug):423 def deleteBugLink(self, bug):
427 """See `BugLinkTargetMixin`."""424 """See `BugLinkTargetMixin`."""
428 getUtility(IXRefSet).delete(425 getUtility(IXRefSet).delete(
429 {(u'merge_proposal', six.text_type(self.id)):426 {('merge_proposal', str(self.id)): [('bug', str(bug.id))]})
430 [(u'bug', six.text_type(bug.id))]})
431427
432 def linkBug(self, bug, user=None, check_permissions=True, props=None):428 def linkBug(self, bug, user=None, check_permissions=True, props=None):
433 """See `BugLinkTargetMixin`."""429 """See `BugLinkTargetMixin`."""
@@ -436,7 +432,7 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
436 return self.source_branch.linkBug(bug, user)432 return self.source_branch.linkBug(bug, user)
437 else:433 else:
438 # Otherwise, link the bug to the merge proposal directly.434 # Otherwise, link the bug to the merge proposal directly.
439 return super(BranchMergeProposal, self).linkBug(435 return super().linkBug(
440 bug, user=user, check_permissions=check_permissions,436 bug, user=user, check_permissions=check_permissions,
441 props=props)437 props=props)
442438
@@ -451,7 +447,7 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
451 return self.source_branch.unlinkBug(bug, user)447 return self.source_branch.unlinkBug(bug, user)
452 else:448 else:
453 # Otherwise, unlink the bug from the merge proposal directly.449 # Otherwise, unlink the bug from the merge proposal directly.
454 return super(BranchMergeProposal, self).unlinkBug(450 return super().unlinkBug(
455 bug, user=user, check_permissions=check_permissions)451 bug, user=user, check_permissions=check_permissions)
456452
457 def _reportTooManyRelatedBugs(self):453 def _reportTooManyRelatedBugs(self):
@@ -505,8 +501,7 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
505 current_bug_ids_from_source = {501 current_bug_ids_from_source = {
506 int(id): (props['metadata'] or {}).get('from_source', False)502 int(id): (props['metadata'] or {}).get('from_source', False)
507 for (_, id), props in getUtility(IXRefSet).findFrom(503 for (_, id), props in getUtility(IXRefSet).findFrom(
508 (u'merge_proposal', six.text_type(self.id)),504 ('merge_proposal', str(self.id)), types=['bug']).items()}
509 types=[u'bug']).items()}
510 current_bug_ids = set(current_bug_ids_from_source)505 current_bug_ids = set(current_bug_ids_from_source)
511 new_bug_ids = self._fetchRelatedBugIDsFromSource()506 new_bug_ids = self._fetchRelatedBugIDsFromSource()
512 # Only remove links marked as originating in the source branch.507 # Only remove links marked as originating in the source branch.
diff --git a/lib/lp/code/model/branchmergeproposaljob.py b/lib/lp/code/model/branchmergeproposaljob.py
index 3a58ae9..8c1fd83 100644
--- a/lib/lp/code/model/branchmergeproposaljob.py
+++ b/lib/lp/code/model/branchmergeproposaljob.py
@@ -175,7 +175,7 @@ class BranchMergeProposalJob(StormBase):
175 :param metadata: The type-specific variables, as a JSON-compatible175 :param metadata: The type-specific variables, as a JSON-compatible
176 dict.176 dict.
177 """177 """
178 super(BranchMergeProposalJob, self).__init__()178 super().__init__()
179 json_data = simplejson.dumps(metadata)179 json_data = simplejson.dumps(metadata)
180 self.job = Job()180 self.job = Job()
181 self.branch_merge_proposal = branch_merge_proposal181 self.branch_merge_proposal = branch_merge_proposal
diff --git a/lib/lp/code/model/branchsubscription.py b/lib/lp/code/model/branchsubscription.py
index c9b10a8..36ec00a 100644
--- a/lib/lp/code/model/branchsubscription.py
+++ b/lib/lp/code/model/branchsubscription.py
@@ -48,7 +48,7 @@ class BranchSubscription(StormBase):
4848
49 def __init__(self, person, branch, notification_level, max_diff_lines,49 def __init__(self, person, branch, notification_level, max_diff_lines,
50 review_level, subscribed_by):50 review_level, subscribed_by):
51 super(BranchSubscription, self).__init__()51 super().__init__()
52 self.person = person52 self.person = person
53 self.branch = branch53 self.branch = branch
54 self.notification_level = notification_level54 self.notification_level = notification_level
diff --git a/lib/lp/code/model/branchtarget.py b/lib/lp/code/model/branchtarget.py
index 9100558..f341171 100644
--- a/lib/lp/code/model/branchtarget.py
+++ b/lib/lp/code/model/branchtarget.py
@@ -187,7 +187,7 @@ class PackageBranchTarget(_BaseBranchTarget):
187@implementer(IBranchTarget)187@implementer(IBranchTarget)
188class PersonBranchTarget(_BaseBranchTarget):188class PersonBranchTarget(_BaseBranchTarget):
189189
190 name = u'+junk'190 name = '+junk'
191 default_stacked_on_branch = None191 default_stacked_on_branch = None
192 default_merge_target = None192 default_merge_target = None
193193
diff --git a/lib/lp/code/model/codeimport.py b/lib/lp/code/model/codeimport.py
index c2b028e..13f6559 100644
--- a/lib/lp/code/model/codeimport.py
+++ b/lib/lp/code/model/codeimport.py
@@ -83,7 +83,7 @@ class CodeImport(StormBase):
8383
84 def __init__(self, registrant, owner, target, review_status, rcs_type=None,84 def __init__(self, registrant, owner, target, review_status, rcs_type=None,
85 url=None, cvs_root=None, cvs_module=None):85 url=None, cvs_root=None, cvs_module=None):
86 super(CodeImport, self).__init__()86 super().__init__()
87 self.registrant = registrant87 self.registrant = registrant
88 self.owner = owner88 self.owner = owner
89 if IBranch.providedBy(target):89 if IBranch.providedBy(target):
diff --git a/lib/lp/code/model/codeimportevent.py b/lib/lp/code/model/codeimportevent.py
index eb399d1..2b41ce4 100644
--- a/lib/lp/code/model/codeimportevent.py
+++ b/lib/lp/code/model/codeimportevent.py
@@ -12,7 +12,6 @@ __all__ = [
1212
13from lazr.enum import DBItem13from lazr.enum import DBItem
14import pytz14import pytz
15import six
16from storm.locals import (15from storm.locals import (
17 DateTime,16 DateTime,
18 Int,17 Int,
@@ -65,7 +64,7 @@ class CodeImportEvent(StormBase):
6564
66 def __init__(self, event_type, code_import=None, person=None,65 def __init__(self, event_type, code_import=None, person=None,
67 machine=None, date_created=DEFAULT):66 machine=None, date_created=DEFAULT):
68 super(CodeImportEvent, self).__init__()67 super().__init__()
69 self.event_type = event_type68 self.event_type = event_type
70 self.code_import = code_import69 self.code_import = code_import
71 self.person = person70 self.person = person
@@ -97,7 +96,7 @@ class _CodeImportEventData(StormBase):
97 data_value = Unicode(allow_none=True)96 data_value = Unicode(allow_none=True)
9897
99 def __init__(self, event, data_type, data_value):98 def __init__(self, event, data_type, data_value):
100 super(_CodeImportEventData, self).__init__()99 super().__init__()
101 self.event = event100 self.event = event
102 self.data_type = data_type101 self.data_type = data_type
103 self.data_value = data_value102 self.data_value = data_value
@@ -200,7 +199,7 @@ class CodeImportEventSet:
200 IStore(CodeImportEvent).add(event)199 IStore(CodeImportEvent).add(event)
201 IStore(_CodeImportEventData).add(_CodeImportEventData(200 IStore(_CodeImportEventData).add(_CodeImportEventData(
202 event=event, data_type=CodeImportEventDataType.OFFLINE_REASON,201 event=event, data_type=CodeImportEventDataType.OFFLINE_REASON,
203 data_value=six.text_type(reason.name)))202 data_value=str(reason.name)))
204 self._recordMessage(event, message)203 self._recordMessage(event, message)
205 return event204 return event
206205
@@ -257,7 +256,7 @@ class CodeImportEventSet:
257 IStore(CodeImportEvent).add(event)256 IStore(CodeImportEvent).add(event)
258 IStore(_CodeImportEventData).add(_CodeImportEventData(257 IStore(_CodeImportEventData).add(_CodeImportEventData(
259 event=event, data_type=CodeImportEventDataType.RECLAIMED_JOB_ID,258 event=event, data_type=CodeImportEventDataType.RECLAIMED_JOB_ID,
260 data_value=six.text_type(job_id)))259 data_value=str(job_id)))
261 return event260 return event
262261
263 def _recordSnapshot(self, event, code_import):262 def _recordSnapshot(self, event, code_import):
@@ -278,18 +277,17 @@ class CodeImportEventSet:
278 def _iterItemsForSnapshot(self, code_import):277 def _iterItemsForSnapshot(self, code_import):
279 """Yield key-value tuples to save a snapshot of the code import."""278 """Yield key-value tuples to save a snapshot of the code import."""
280 yield self._getCodeImportItem(code_import)279 yield self._getCodeImportItem(code_import)
281 yield 'REVIEW_STATUS', six.text_type(code_import.review_status.name)280 yield 'REVIEW_STATUS', str(code_import.review_status.name)
282 yield 'OWNER', six.text_type(code_import.owner.id)281 yield 'OWNER', str(code_import.owner.id)
283 yield 'UPDATE_INTERVAL', self._getNullableValue(282 yield 'UPDATE_INTERVAL', self._getNullableValue(
284 code_import.update_interval)283 code_import.update_interval)
285 yield 'ASSIGNEE', self._getNullableValue(284 yield 'ASSIGNEE', self._getNullableValue(
286 code_import.assignee, use_id=True)285 code_import.assignee, use_id=True)
287 for detail in self._iterSourceDetails(code_import):286 yield from self._iterSourceDetails(code_import)
288 yield detail
289287
290 def _getCodeImportItem(self, code_import):288 def _getCodeImportItem(self, code_import):
291 """Return the key-value tuple for the code import id."""289 """Return the key-value tuple for the code import id."""
292 return 'CODE_IMPORT', six.text_type(code_import.id)290 return 'CODE_IMPORT', str(code_import.id)
293291
294 def _getNullableValue(self, value, use_id=False):292 def _getNullableValue(self, value, use_id=False):
295 """Return the string value for a nullable value.293 """Return the string value for a nullable value.
@@ -301,9 +299,9 @@ class CodeImportEventSet:
301 if value is None:299 if value is None:
302 return None300 return None
303 elif use_id:301 elif use_id:
304 return six.text_type(value.id)302 return str(value.id)
305 else:303 else:
306 return six.text_type(value)304 return str(value)
307305
308 def _iterSourceDetails(self, code_import):306 def _iterSourceDetails(self, code_import):
309 """Yield key-value tuples describing the source of the import."""307 """Yield key-value tuples describing the source of the import."""
diff --git a/lib/lp/code/model/codeimportjob.py b/lib/lp/code/model/codeimportjob.py
index a7839a3..0d010c5 100644
--- a/lib/lp/code/model/codeimportjob.py
+++ b/lib/lp/code/model/codeimportjob.py
@@ -104,7 +104,7 @@ class CodeImportJob(StormBase):
104 date_started = DateTime(tzinfo=pytz.UTC, allow_none=True, default=None)104 date_started = DateTime(tzinfo=pytz.UTC, allow_none=True, default=None)
105105
106 def __init__(self, code_import, date_due):106 def __init__(self, code_import, date_due):
107 super(CodeImportJob, self).__init__()107 super().__init__()
108 self.code_import = code_import108 self.code_import = code_import
109 self.date_due = date_due109 self.date_due = date_due
110110
@@ -179,7 +179,7 @@ class CodeImportJob(StormBase):
179179
180180
181@implementer(ICodeImportJobSet, ICodeImportJobSetPublic)181@implementer(ICodeImportJobSet, ICodeImportJobSetPublic)
182class CodeImportJobSet(object):182class CodeImportJobSet:
183 """See `ICodeImportJobSet`."""183 """See `ICodeImportJobSet`."""
184184
185 # CodeImportJob database objects are created using185 # CodeImportJob database objects are created using
diff --git a/lib/lp/code/model/codeimportmachine.py b/lib/lp/code/model/codeimportmachine.py
index 084f8ca..0ce2fc5 100644
--- a/lib/lp/code/model/codeimportmachine.py
+++ b/lib/lp/code/model/codeimportmachine.py
@@ -65,7 +65,7 @@ class CodeImportMachine(StormBase):
65 Desc('CodeImportEvent.id')))65 Desc('CodeImportEvent.id')))
6666
67 def __init__(self, hostname, heartbeat=None):67 def __init__(self, hostname, heartbeat=None):
68 super(CodeImportMachine, self).__init__()68 super().__init__()
69 self.hostname = hostname69 self.hostname = hostname
70 self.heartbeat = heartbeat70 self.heartbeat = heartbeat
71 self.state = CodeImportMachineState.OFFLINE71 self.state = CodeImportMachineState.OFFLINE
@@ -120,7 +120,7 @@ class CodeImportMachine(StormBase):
120120
121121
122@implementer(ICodeImportMachineSet)122@implementer(ICodeImportMachineSet)
123class CodeImportMachineSet(object):123class CodeImportMachineSet:
124 """See `ICodeImportMachineSet`."""124 """See `ICodeImportMachineSet`."""
125125
126 def getAll(self):126 def getAll(self):
diff --git a/lib/lp/code/model/codeimportresult.py b/lib/lp/code/model/codeimportresult.py
index 84fb963..222e3d6 100644
--- a/lib/lp/code/model/codeimportresult.py
+++ b/lib/lp/code/model/codeimportresult.py
@@ -59,7 +59,7 @@ class CodeImportResult(StormBase):
59 def __init__(self, code_import, machine, status, date_job_started,59 def __init__(self, code_import, machine, status, date_job_started,
60 requesting_user=None, log_excerpt=None, log_file=None,60 requesting_user=None, log_excerpt=None, log_file=None,
61 date_created=UTC_NOW):61 date_created=UTC_NOW):
62 super(CodeImportResult, self).__init__()62 super().__init__()
63 self.code_import = code_import63 self.code_import = code_import
64 self.machine = machine64 self.machine = machine
65 self.status = status65 self.status = status
@@ -80,7 +80,7 @@ class CodeImportResult(StormBase):
8080
8181
82@implementer(ICodeImportResultSet)82@implementer(ICodeImportResultSet)
83class CodeImportResultSet(object):83class CodeImportResultSet:
84 """See `ICodeImportResultSet`."""84 """See `ICodeImportResultSet`."""
8585
86 def new(self, code_import, machine, requesting_user, log_excerpt,86 def new(self, code_import, machine, requesting_user, log_excerpt,
diff --git a/lib/lp/code/model/codereviewinlinecomment.py b/lib/lp/code/model/codereviewinlinecomment.py
index a6dc6da..a86d682 100644
--- a/lib/lp/code/model/codereviewinlinecomment.py
+++ b/lib/lp/code/model/codereviewinlinecomment.py
@@ -9,7 +9,6 @@ __all__ = [
9 'CodeReviewInlineCommentSet',9 'CodeReviewInlineCommentSet',
10 ]10 ]
1111
12import six
13from storm.expr import LeftJoin12from storm.expr import LeftJoin
14from storm.locals import (13from storm.locals import (
15 Int,14 Int,
@@ -113,7 +112,7 @@ class CodeReviewInlineCommentSet:
113 list(crics), key=lambda c: c.comment.date_created)112 list(crics), key=lambda c: c.comment.date_created)
114 inline_comments = []113 inline_comments = []
115 for cric in sorted_crics:114 for cric in sorted_crics:
116 for line_number, text in six.iteritems(cric.comments):115 for line_number, text in cric.comments.items():
117 comment = {116 comment = {
118 'line_number': line_number,117 'line_number': line_number,
119 'person': cric.person,118 'person': cric.person,
diff --git a/lib/lp/code/model/diff.py b/lib/lp/code/model/diff.py
index 13f633c..93626b2 100644
--- a/lib/lp/code/model/diff.py
+++ b/lib/lp/code/model/diff.py
@@ -98,7 +98,7 @@ class Diff(SQLBase):
98 @property98 @property
99 def text(self):99 def text(self):
100 if self.diff_text is None:100 if self.diff_text is None:
101 return u''101 return ''
102 else:102 else:
103 with reduced_timeout(103 with reduced_timeout(
104 0.01, webapp_max=2.0,104 0.01, webapp_max=2.0,
@@ -385,13 +385,13 @@ class PreviewDiff(Storm):
385 source_revision = bmp.source_branch.getBranchRevision(385 source_revision = bmp.source_branch.getBranchRevision(
386 revision_id=self.source_revision_id)386 revision_id=self.source_revision_id)
387 if source_revision and source_revision.sequence:387 if source_revision and source_revision.sequence:
388 source_rev = u'r{}'.format(source_revision.sequence)388 source_rev = 'r{}'.format(source_revision.sequence)
389 else:389 else:
390 source_rev = self.source_revision_id390 source_rev = self.source_revision_id
391 target_revision = bmp.target_branch.getBranchRevision(391 target_revision = bmp.target_branch.getBranchRevision(
392 revision_id=self.target_revision_id)392 revision_id=self.target_revision_id)
393 if target_revision and target_revision.sequence:393 if target_revision and target_revision.sequence:
394 target_rev = u'r{}'.format(target_revision.sequence)394 target_rev = 'r{}'.format(target_revision.sequence)
395 else:395 else:
396 target_rev = self.target_revision_id396 target_rev = self.target_revision_id
397 else:397 else:
@@ -402,7 +402,7 @@ class PreviewDiff(Storm):
402 source_rev = self.source_revision_id[:7]402 source_rev = self.source_revision_id[:7]
403 target_rev = self.target_revision_id[:7]403 target_rev = self.target_revision_id[:7]
404404
405 return u'{} into {}'.format(source_rev, target_rev)405 return '{} into {}'.format(source_rev, target_rev)
406406
407 @property407 @property
408 def has_conflicts(self):408 def has_conflicts(self):
@@ -433,8 +433,8 @@ class PreviewDiff(Storm):
433 preview.target_revision_id = target_revision.decode('utf-8')433 preview.target_revision_id = target_revision.decode('utf-8')
434 preview.branch_merge_proposal = bmp434 preview.branch_merge_proposal = bmp
435 preview.diff = diff435 preview.diff = diff
436 preview.conflicts = u''.join(436 preview.conflicts = ''.join(
437 six.text_type(conflict) + '\n' for conflict in conflicts)437 str(conflict) + '\n' for conflict in conflicts)
438 else:438 else:
439 source_repository = bmp.source_git_repository439 source_repository = bmp.source_git_repository
440 target_repository = bmp.target_git_repository440 target_repository = bmp.target_git_repository
@@ -449,8 +449,8 @@ class PreviewDiff(Storm):
449 response = getUtility(IGitHostingClient).getMergeDiff(449 response = getUtility(IGitHostingClient).getMergeDiff(
450 path, bmp.target_git_commit_sha1, bmp.source_git_commit_sha1,450 path, bmp.target_git_commit_sha1, bmp.source_git_commit_sha1,
451 prerequisite=bmp.prerequisite_git_commit_sha1)451 prerequisite=bmp.prerequisite_git_commit_sha1)
452 conflicts = u"".join(452 conflicts = "".join(
453 u"Conflict in %s\n" % path for path in response['conflicts'])453 "Conflict in %s\n" % path for path in response['conflicts'])
454 preview = cls.create(454 preview = cls.create(
455 bmp, response['patch'].encode('utf-8'),455 bmp, response['patch'].encode('utf-8'),
456 bmp.source_git_commit_sha1, bmp.target_git_commit_sha1,456 bmp.source_git_commit_sha1, bmp.target_git_commit_sha1,
diff --git a/lib/lp/code/model/gitactivity.py b/lib/lp/code/model/gitactivity.py
index a7b2036..42091f1 100644
--- a/lib/lp/code/model/gitactivity.py
+++ b/lib/lp/code/model/gitactivity.py
@@ -60,7 +60,7 @@ class GitActivity(StormBase):
6060
61 def __init__(self, repository, changer, what_changed, changee=None,61 def __init__(self, repository, changer, what_changed, changee=None,
62 old_value=None, new_value=None, date_changed=DEFAULT):62 old_value=None, new_value=None, date_changed=DEFAULT):
63 super(GitActivity, self).__init__()63 super().__init__()
64 self.repository = repository64 self.repository = repository
65 self.date_changed = date_changed65 self.date_changed = date_changed
66 self.changer = changer66 self.changer = changer
diff --git a/lib/lp/code/model/gitcollection.py b/lib/lp/code/model/gitcollection.py
index 966ea02..8c2d4f1 100644
--- a/lib/lp/code/model/gitcollection.py
+++ b/lib/lp/code/model/gitcollection.py
@@ -622,7 +622,7 @@ class VisibleGitCollection(GenericGitCollection):
622622
623 def __init__(self, user, store=None, filter_expressions=None, tables=None,623 def __init__(self, user, store=None, filter_expressions=None, tables=None,
624 asymmetric_filter_expressions=None, asymmetric_tables=None):624 asymmetric_filter_expressions=None, asymmetric_tables=None):
625 super(VisibleGitCollection, self).__init__(625 super().__init__(
626 store=store, filter_expressions=filter_expressions, tables=tables,626 store=store, filter_expressions=filter_expressions, tables=tables,
627 asymmetric_filter_expressions=asymmetric_filter_expressions,627 asymmetric_filter_expressions=asymmetric_filter_expressions,
628 asymmetric_tables=asymmetric_tables)628 asymmetric_tables=asymmetric_tables)
diff --git a/lib/lp/code/model/githosting.py b/lib/lp/code/model/githosting.py
index 6494390..e498138 100644
--- a/lib/lp/code/model/githosting.py
+++ b/lib/lp/code/model/githosting.py
@@ -14,11 +14,7 @@ import sys
1414
15from lazr.restful.utils import get_current_browser_request15from lazr.restful.utils import get_current_browser_request
16import requests16import requests
17import six17from six import ensure_text
18from six import (
19 ensure_text,
20 reraise,
21 )
22from six.moves.urllib.parse import (18from six.moves.urllib.parse import (
23 quote,19 quote,
24 urljoin,20 urljoin,
@@ -89,9 +85,7 @@ class GitHostingClient:
89 except Exception:85 except Exception:
90 _, val, tb = sys.exc_info()86 _, val, tb = sys.exc_info()
91 try:87 try:
92 reraise(88 raise RequestExceptionWrapper(*val.args).with_traceback(tb)
93 RequestExceptionWrapper,
94 RequestExceptionWrapper(*val.args), tb)
95 finally:89 finally:
96 # Avoid traceback reference cycles.90 # Avoid traceback reference cycles.
97 del val, tb91 del val, tb
@@ -131,7 +125,7 @@ class GitHostingClient:
131 self._post("/repo", json=request)125 self._post("/repo", json=request)
132 except requests.RequestException as e:126 except requests.RequestException as e:
133 raise GitRepositoryCreationFault(127 raise GitRepositoryCreationFault(
134 "Failed to create Git repository: %s" % six.text_type(e), path)128 "Failed to create Git repository: %s" % str(e), path)
135129
136 def getProperties(self, path):130 def getProperties(self, path):
137 """See `IGitHostingClient`."""131 """See `IGitHostingClient`."""
@@ -139,8 +133,7 @@ class GitHostingClient:
139 return self._get("/repo/%s" % path)133 return self._get("/repo/%s" % path)
140 except requests.RequestException as e:134 except requests.RequestException as e:
141 raise GitRepositoryScanFault(135 raise GitRepositoryScanFault(
142 "Failed to get properties of Git repository: %s" %136 "Failed to get properties of Git repository: %s" % str(e))
143 six.text_type(e))
144137
145 def setProperties(self, path, **props):138 def setProperties(self, path, **props):
146 """See `IGitHostingClient`."""139 """See `IGitHostingClient`."""
@@ -148,8 +141,7 @@ class GitHostingClient:
148 self._patch("/repo/%s" % path, json=props)141 self._patch("/repo/%s" % path, json=props)
149 except requests.RequestException as e:142 except requests.RequestException as e:
150 raise GitRepositoryScanFault(143 raise GitRepositoryScanFault(
151 "Failed to set properties of Git repository: %s" %144 "Failed to set properties of Git repository: %s" % str(e))
152 six.text_type(e))
153145
154 def getRefs(self, path, exclude_prefixes=None):146 def getRefs(self, path, exclude_prefixes=None):
155 """See `IGitHostingClient`."""147 """See `IGitHostingClient`."""
@@ -159,8 +151,7 @@ class GitHostingClient:
159 params={"exclude_prefix": exclude_prefixes})151 params={"exclude_prefix": exclude_prefixes})
160 except requests.RequestException as e:152 except requests.RequestException as e:
161 raise GitRepositoryScanFault(153 raise GitRepositoryScanFault(
162 "Failed to get refs from Git repository: %s" %154 "Failed to get refs from Git repository: %s" % str(e))
163 six.text_type(e))
164155
165 def getCommits(self, path, commit_oids, logger=None):156 def getCommits(self, path, commit_oids, logger=None):
166 """See `IGitHostingClient`."""157 """See `IGitHostingClient`."""
@@ -173,7 +164,7 @@ class GitHostingClient:
173 except requests.RequestException as e:164 except requests.RequestException as e:
174 raise GitRepositoryScanFault(165 raise GitRepositoryScanFault(
175 "Failed to get commit details from Git repository: %s" %166 "Failed to get commit details from Git repository: %s" %
176 six.text_type(e))167 str(e))
177168
178 def getLog(self, path, start, limit=None, stop=None, logger=None):169 def getLog(self, path, start, limit=None, stop=None, logger=None):
179 """See `IGitHostingClient`."""170 """See `IGitHostingClient`."""
@@ -188,8 +179,7 @@ class GitHostingClient:
188 params={"limit": limit, "stop": stop})179 params={"limit": limit, "stop": stop})
189 except requests.RequestException as e:180 except requests.RequestException as e:
190 raise GitRepositoryScanFault(181 raise GitRepositoryScanFault(
191 "Failed to get commit log from Git repository: %s" %182 "Failed to get commit log from Git repository: %s" % str(e))
192 six.text_type(e))
193183
194 def getDiff(self, path, old, new, common_ancestor=False,184 def getDiff(self, path, old, new, common_ancestor=False,
195 context_lines=None, logger=None):185 context_lines=None, logger=None):
@@ -204,8 +194,7 @@ class GitHostingClient:
204 return self._get(url, params={"context_lines": context_lines})194 return self._get(url, params={"context_lines": context_lines})
205 except requests.RequestException as e:195 except requests.RequestException as e:
206 raise GitRepositoryScanFault(196 raise GitRepositoryScanFault(
207 "Failed to get diff from Git repository: %s" %197 "Failed to get diff from Git repository: %s" % str(e))
208 six.text_type(e))
209198
210 def getMergeDiff(self, path, base, head, prerequisite=None, logger=None):199 def getMergeDiff(self, path, base, head, prerequisite=None, logger=None):
211 """See `IGitHostingClient`."""200 """See `IGitHostingClient`."""
@@ -219,8 +208,7 @@ class GitHostingClient:
219 return self._get(url, params={"sha1_prerequisite": prerequisite})208 return self._get(url, params={"sha1_prerequisite": prerequisite})
220 except requests.RequestException as e:209 except requests.RequestException as e:
221 raise GitRepositoryScanFault(210 raise GitRepositoryScanFault(
222 "Failed to get merge diff from Git repository: %s" %211 "Failed to get merge diff from Git repository: %s" % str(e))
223 six.text_type(e))
224212
225 def detectMerges(self, path, target, sources, logger=None):213 def detectMerges(self, path, target, sources, logger=None):
226 """See `IGitHostingClient`."""214 """See `IGitHostingClient`."""
@@ -235,8 +223,7 @@ class GitHostingClient:
235 json={"sources": sources})223 json={"sources": sources})
236 except requests.RequestException as e:224 except requests.RequestException as e:
237 raise GitRepositoryScanFault(225 raise GitRepositoryScanFault(
238 "Failed to detect merges in Git repository: %s" %226 "Failed to detect merges in Git repository: %s" % str(e))
239 six.text_type(e))
240227
241 def delete(self, path, logger=None):228 def delete(self, path, logger=None):
242 """See `IGitHostingClient`."""229 """See `IGitHostingClient`."""
@@ -246,7 +233,7 @@ class GitHostingClient:
246 self._delete("/repo/%s" % path)233 self._delete("/repo/%s" % path)
247 except requests.RequestException as e:234 except requests.RequestException as e:
248 raise GitRepositoryDeletionFault(235 raise GitRepositoryDeletionFault(
249 "Failed to delete Git repository: %s" % six.text_type(e))236 "Failed to delete Git repository: %s" % str(e))
250237
251 def getBlob(self, path, filename, rev=None, logger=None):238 def getBlob(self, path, filename, rev=None, logger=None):
252 """See `IGitHostingClient`."""239 """See `IGitHostingClient`."""
@@ -262,8 +249,7 @@ class GitHostingClient:
262 raise GitRepositoryBlobNotFound(path, filename, rev=rev)249 raise GitRepositoryBlobNotFound(path, filename, rev=rev)
263 else:250 else:
264 raise GitRepositoryScanFault(251 raise GitRepositoryScanFault(
265 "Failed to get file from Git repository: %s" %252 "Failed to get file from Git repository: %s" % str(e))
266 six.text_type(e))
267 try:253 try:
268 blob = base64.b64decode(response["data"].encode("UTF-8"))254 blob = base64.b64decode(response["data"].encode("UTF-8"))
269 if len(blob) != response["size"]:255 if len(blob) != response["size"]:
@@ -273,8 +259,7 @@ class GitHostingClient:
273 return blob259 return blob
274 except Exception as e:260 except Exception as e:
275 raise GitRepositoryScanFault(261 raise GitRepositoryScanFault(
276 "Failed to get file from Git repository: %s" %262 "Failed to get file from Git repository: %s" % str(e))
277 six.text_type(e))
278263
279 def copyRefs(self, path, operations, logger=None):264 def copyRefs(self, path, operations, logger=None):
280 """See `IGitHostingClient`."""265 """See `IGitHostingClient`."""
@@ -334,7 +319,7 @@ class GitHostingClient:
334 else:319 else:
335 raise CannotRepackRepository(320 raise CannotRepackRepository(
336 "Failed to repack Git repository %s: %s" %321 "Failed to repack Git repository %s: %s" %
337 (path, six.text_type(e)))322 (path, str(e)))
338323
339 def collectGarbage(self, path, logger=None):324 def collectGarbage(self, path, logger=None):
340 """See `IGitHostingClient`."""325 """See `IGitHostingClient`."""
@@ -349,4 +334,4 @@ class GitHostingClient:
349 except requests.RequestException as e:334 except requests.RequestException as e:
350 raise CannotRunGitGC(335 raise CannotRunGitGC(
351 "Failed to run Git GC for repository %s: %s" %336 "Failed to run Git GC for repository %s: %s" %
352 (path, six.text_type(e)))337 (path, str(e)))
diff --git a/lib/lp/code/model/gitjob.py b/lib/lp/code/model/gitjob.py
index 2e78d06..8b0ede0 100644
--- a/lib/lp/code/model/gitjob.py
+++ b/lib/lp/code/model/gitjob.py
@@ -125,7 +125,7 @@ class GitJob(StormBase):
125 :param metadata: The type-specific variables, as a JSON-compatible125 :param metadata: The type-specific variables, as a JSON-compatible
126 dict.126 dict.
127 """127 """
128 super(GitJob, self).__init__()128 super().__init__()
129 self.job = Job(**job_args)129 self.job = Job(**job_args)
130 self.repository = repository130 self.repository = repository
131 self.job_type = job_type131 self.job_type = job_type
@@ -177,7 +177,7 @@ class GitJobDerived(BaseRunnableJob, metaclass=EnumeratedSubclass):
177177
178 def getOopsVars(self):178 def getOopsVars(self):
179 """See `IRunnableJob`."""179 """See `IRunnableJob`."""
180 oops_vars = super(GitJobDerived, self).getOopsVars()180 oops_vars = super().getOopsVars()
181 oops_vars.extend([181 oops_vars.extend([
182 ('git_job_id', self.context.job.id),182 ('git_job_id', self.context.job.id),
183 ('git_job_type', self.context.job_type.title),183 ('git_job_type', self.context.job_type.title),
diff --git a/lib/lp/code/model/gitlookup.py b/lib/lp/code/model/gitlookup.py
index 03b5a43..6c5746f 100644
--- a/lib/lp/code/model/gitlookup.py
+++ b/lib/lp/code/model/gitlookup.py
@@ -151,8 +151,7 @@ class ProjectGitTraversable(_BaseGitTraversable):
151 if oci_project is None:151 if oci_project is None:
152 raise NoSuchOCIProjectName(ociproject_name)152 raise NoSuchOCIProjectName(ociproject_name)
153 return owner, oci_project, None153 return owner, oci_project, None
154 return super(ProjectGitTraversable, self).traverse(154 return super().traverse(owner, name, segments)
155 owner, name, segments)
156155
157 def getNamespace(self, owner):156 def getNamespace(self, owner):
158 return getUtility(IGitNamespaceSet).get(owner, project=self.context)157 return getUtility(IGitNamespaceSet).get(owner, project=self.context)
@@ -240,8 +239,7 @@ class PersonGitTraversable(_BaseGitTraversable):
240 `IGitRepository`).239 `IGitRepository`).
241 """240 """
242 if name == "+git":241 if name == "+git":
243 return super(PersonGitTraversable, self).traverse(242 return super().traverse(owner, name, segments)
244 owner, name, segments)
245 else:243 else:
246 if not valid_name(name):244 if not valid_name(name):
247 raise InvalidProductName(name)245 raise InvalidProductName(name)
@@ -266,7 +264,7 @@ class DistributionOCIProjectGitTraversable(_BaseGitTraversable):
266 owner, oci_project=self.context)264 owner, oci_project=self.context)
267265
268266
269class SegmentIterator(six.Iterator):267class SegmentIterator:
270 """An iterator that remembers the elements it has traversed."""268 """An iterator that remembers the elements it has traversed."""
271269
272 def __init__(self, iterator):270 def __init__(self, iterator):
diff --git a/lib/lp/code/model/gitref.py b/lib/lp/code/model/gitref.py
index 61a7526..11a3959 100644
--- a/lib/lp/code/model/gitref.py
+++ b/lib/lp/code/model/gitref.py
@@ -333,10 +333,10 @@ class GitRefMixin:
333 enable_hosting=None, enable_memcache=None, logger=None):333 enable_hosting=None, enable_memcache=None, logger=None):
334 if enable_hosting is None:334 if enable_hosting is None:
335 enable_hosting = not getFeatureFlag(335 enable_hosting = not getFeatureFlag(
336 u"code.git.log.disable_hosting")336 "code.git.log.disable_hosting")
337 if enable_memcache is None:337 if enable_memcache is None:
338 enable_memcache = not getFeatureFlag(338 enable_memcache = not getFeatureFlag(
339 u"code.git.log.disable_memcache")339 "code.git.log.disable_memcache")
340 path = self.repository.getInternalPath()340 path = self.repository.getInternalPath()
341 if (union_repository is not None and341 if (union_repository is not None and
342 union_repository != self.repository):342 union_repository != self.repository):
@@ -636,9 +636,9 @@ class GitRef(GitRefMixin, StormBase):
636 def findByReposAndPaths(cls, repos_and_paths):636 def findByReposAndPaths(cls, repos_and_paths):
637 """See `IGitRefSet`"""637 """See `IGitRefSet`"""
638 def full_path(path):638 def full_path(path):
639 if path.startswith(u"refs/heads/"):639 if path.startswith("refs/heads/"):
640 return path640 return path
641 return u"refs/heads/%s" % path641 return "refs/heads/%s" % path
642642
643 condition = None643 condition = None
644 for repo, path in repos_and_paths:644 for repo, path in repos_and_paths:
@@ -702,7 +702,7 @@ class GitRefDefault(GitRefDatabaseBackedMixin):
702 def __init__(self, repository):702 def __init__(self, repository):
703 self.repository_id = repository.id703 self.repository_id = repository.id
704 self.repository = repository704 self.repository = repository
705 self.path = u"HEAD"705 self.path = "HEAD"
706706
707 _non_database_attributes = ("repository_id", "repository", "path")707 _non_database_attributes = ("repository_id", "repository", "path")
708708
diff --git a/lib/lp/code/model/gitrepository.py b/lib/lp/code/model/gitrepository.py
index 43a005a..c6b8ada 100644
--- a/lib/lp/code/model/gitrepository.py
+++ b/lib/lp/code/model/gitrepository.py
@@ -500,7 +500,7 @@ class GitRepository(StormBase, WebhookTargetMixin, AccessTokenTargetMixin,
500 description=None, status=None, loose_object_count=None,500 description=None, status=None, loose_object_count=None,
501 pack_count=None, date_last_scanned=None,501 pack_count=None, date_last_scanned=None,
502 date_last_repacked=None):502 date_last_repacked=None):
503 super(GitRepository, self).__init__()503 super().__init__()
504 self.repository_type = repository_type504 self.repository_type = repository_type
505 self.registrant = registrant505 self.registrant = registrant
506 self.owner = owner506 self.owner = owner
@@ -798,7 +798,7 @@ class GitRepository(StormBase, WebhookTargetMixin, AccessTokenTargetMixin,
798 return Store.of(self).find(798 return Store.of(self).find(
799 GitRef,799 GitRef,
800 GitRef.repository_id == self.id,800 GitRef.repository_id == self.id,
801 GitRef.path.startswith(u"refs/heads/")).order_by(GitRef.path)801 GitRef.path.startswith("refs/heads/")).order_by(GitRef.path)
802802
803 @property803 @property
804 def branches_by_date(self):804 def branches_by_date(self):
@@ -831,11 +831,11 @@ class GitRepository(StormBase, WebhookTargetMixin, AccessTokenTargetMixin,
831 self.getInternalPath(), default_branch=ref.path)831 self.getInternalPath(), default_branch=ref.path)
832832
833 def getRefByPath(self, path):833 def getRefByPath(self, path):
834 if path == u"HEAD":834 if path == "HEAD":
835 return GitRefDefault(self)835 return GitRefDefault(self)
836 paths = [path]836 paths = [path]
837 if not path.startswith(u"refs/heads/"):837 if not path.startswith("refs/heads/"):
838 paths.append(u"refs/heads/%s" % path)838 paths.append("refs/heads/%s" % path)
839 refs = Store.of(self).find(839 refs = Store.of(self).find(
840 GitRef,840 GitRef,
841 GitRef.repository_id == self.id,841 GitRef.repository_id == self.id,
@@ -864,8 +864,7 @@ class GitRepository(StormBase, WebhookTargetMixin, AccessTokenTargetMixin,
864 raise ValueError('ref info object does not contain "sha1" key')864 raise ValueError('ref info object does not contain "sha1" key')
865 if "type" not in obj:865 if "type" not in obj:
866 raise ValueError('ref info object does not contain "type" key')866 raise ValueError('ref info object does not contain "type" key')
867 if (not isinstance(obj["sha1"], six.string_types) or867 if not isinstance(obj["sha1"], str) or len(obj["sha1"]) != 40:
868 len(obj["sha1"]) != 40):
869 raise ValueError('ref info sha1 is not a 40-character string')868 raise ValueError('ref info sha1 is not a 40-character string')
870 if obj["type"] not in object_type_map:869 if obj["type"] not in object_type_map:
871 raise ValueError('ref info type is not a recognised object type')870 raise ValueError('ref info type is not a recognised object type')
@@ -1971,7 +1970,7 @@ class DeletionCallable(DeletionOperation):
1971 """Deletion operation that invokes a callable."""1970 """Deletion operation that invokes a callable."""
19721971
1973 def __init__(self, affected_object, rationale, func, *args, **kwargs):1972 def __init__(self, affected_object, rationale, func, *args, **kwargs):
1974 super(DeletionCallable, self).__init__(affected_object, rationale)1973 super().__init__(affected_object, rationale)
1975 self.func = func1974 self.func = func
1976 self.args = args1975 self.args = args
1977 self.kwargs = kwargs1976 self.kwargs = kwargs
@@ -2231,7 +2230,7 @@ class GitRepositoryMacaroonIssuer(MacaroonIssuerBase):
2231 _timestamp_format = "%Y-%m-%dT%H:%M:%S.%f"2230 _timestamp_format = "%Y-%m-%dT%H:%M:%S.%f"
22322231
2233 def __init__(self):2232 def __init__(self):
2234 super(GitRepositoryMacaroonIssuer, self).__init__()2233 super().__init__()
2235 self.checkers = {2234 self.checkers = {
2236 "lp.principal.openid-identifier": self.verifyOpenIDIdentifier,2235 "lp.principal.openid-identifier": self.verifyOpenIDIdentifier,
2237 "lp.expires": self.verifyExpires,2236 "lp.expires": self.verifyExpires,
@@ -2260,8 +2259,7 @@ class GitRepositoryMacaroonIssuer(MacaroonIssuerBase):
22602259
2261 def issueMacaroon(self, context, user=None, **kwargs):2260 def issueMacaroon(self, context, user=None, **kwargs):
2262 """See `IMacaroonIssuer`."""2261 """See `IMacaroonIssuer`."""
2263 macaroon = super(GitRepositoryMacaroonIssuer, self).issueMacaroon(2262 macaroon = super().issueMacaroon(context, user=user, **kwargs)
2264 context, user=user, **kwargs)
2265 naked_account = removeSecurityProxy(user).account2263 naked_account = removeSecurityProxy(user).account
2266 macaroon.add_first_party_caveat(2264 macaroon.add_first_party_caveat(
2267 "lp.principal.openid-identifier " +2265 "lp.principal.openid-identifier " +
diff --git a/lib/lp/code/model/gitrule.py b/lib/lp/code/model/gitrule.py
index 5d416b7..b16d327 100644
--- a/lib/lp/code/model/gitrule.py
+++ b/lib/lp/code/model/gitrule.py
@@ -111,7 +111,7 @@ class GitRule(StormBase):
111111
112 def __init__(self, repository, position, ref_pattern, creator,112 def __init__(self, repository, position, ref_pattern, creator,
113 date_created):113 date_created):
114 super(GitRule, self).__init__()114 super().__init__()
115 self.repository = repository115 self.repository = repository
116 self.position = position116 self.position = position
117 self.ref_pattern = ref_pattern117 self.ref_pattern = ref_pattern
diff --git a/lib/lp/code/model/gitsubscription.py b/lib/lp/code/model/gitsubscription.py
index 8ad435a..2c61db4 100644
--- a/lib/lp/code/model/gitsubscription.py
+++ b/lib/lp/code/model/gitsubscription.py
@@ -53,7 +53,7 @@ class GitSubscription(StormBase):
5353
54 def __init__(self, person, repository, notification_level, max_diff_lines,54 def __init__(self, person, repository, notification_level, max_diff_lines,
55 review_level, subscribed_by):55 review_level, subscribed_by):
56 super(GitSubscription, self).__init__()56 super().__init__()
57 self.person = person57 self.person = person
58 self.repository = repository58 self.repository = repository
59 self.notification_level = notification_level59 self.notification_level = notification_level
diff --git a/lib/lp/code/model/recipebuilder.py b/lib/lp/code/model/recipebuilder.py
index 46ef5b8..abd82e8 100644
--- a/lib/lp/code/model/recipebuilder.py
+++ b/lib/lp/code/model/recipebuilder.py
@@ -63,8 +63,7 @@ class RecipeBuildBehaviour(BuildFarmJobBehaviourBase):
63 self.build.distroseries.displayname))63 self.build.distroseries.displayname))
6464
65 # Build extra arguments.65 # Build extra arguments.
66 args = yield super(RecipeBuildBehaviour, self).extraBuildArgs(66 args = yield super().extraBuildArgs(logger=logger)
67 logger=logger)
68 args['suite'] = self.build.distroseries.getSuite(self.build.pocket)67 args['suite'] = self.build.distroseries.getSuite(self.build.pocket)
69 requester = self.build.requester68 requester = self.build.requester
70 if requester.preferredemail is None:69 if requester.preferredemail is None:
diff --git a/lib/lp/code/model/revision.py b/lib/lp/code/model/revision.py
index 680f3a2..2f04cd3 100644
--- a/lib/lp/code/model/revision.py
+++ b/lib/lp/code/model/revision.py
@@ -286,7 +286,7 @@ class RevisionSet:
286 parent_id=parent_id)286 parent_id=parent_id)
287287
288 # Create revision properties.288 # Create revision properties.
289 for name, value in six.iteritems(properties):289 for name, value in properties.items():
290 RevisionProperty(revision=revision, name=name, value=value)290 RevisionProperty(revision=revision, name=name, value=value)
291291
292 return revision292 return revision
@@ -377,7 +377,7 @@ class RevisionSet:
377 for bzr_revision in revisions:377 for bzr_revision in revisions:
378 db_id = revision_db_id[six.ensure_text(bzr_revision.revision_id)]378 db_id = revision_db_id[six.ensure_text(bzr_revision.revision_id)]
379 # Property data: revision DB id, name, value.379 # Property data: revision DB id, name, value.
380 for name, value in six.iteritems(bzr_revision.properties):380 for name, value in bzr_revision.properties.items():
381 # pristine-tar properties can be huge, and storing them381 # pristine-tar properties can be huge, and storing them
382 # in the database provides no value. Exclude them.382 # in the database provides no value. Exclude them.
383 if name.startswith('deb-pristine-delta'):383 if name.startswith('deb-pristine-delta'):
diff --git a/lib/lp/code/model/sourcepackagerecipebuild.py b/lib/lp/code/model/sourcepackagerecipebuild.py
index f10ed3c..7be41ee 100644
--- a/lib/lp/code/model/sourcepackagerecipebuild.py
+++ b/lib/lp/code/model/sourcepackagerecipebuild.py
@@ -191,7 +191,7 @@ class SourcePackageRecipeBuild(SpecificBuildFarmJobSourceMixin,
191 archive, pocket, date_created):191 archive, pocket, date_created):
192 """Construct a SourcePackageRecipeBuild."""192 """Construct a SourcePackageRecipeBuild."""
193 processor = distroseries.nominatedarchindep.processor193 processor = distroseries.nominatedarchindep.processor
194 super(SourcePackageRecipeBuild, self).__init__()194 super().__init__()
195 self.build_farm_job = build_farm_job195 self.build_farm_job = build_farm_job
196 self.distroseries = distroseries196 self.distroseries = distroseries
197 self.recipe = recipe197 self.recipe = recipe
diff --git a/lib/lp/code/model/sourcepackagerecipedata.py b/lib/lp/code/model/sourcepackagerecipedata.py
index f5d849b..0185f42 100644
--- a/lib/lp/code/model/sourcepackagerecipedata.py
+++ b/lib/lp/code/model/sourcepackagerecipedata.py
@@ -105,7 +105,7 @@ class _SourcePackageRecipeDataInstruction(Storm):
105 def __init__(self, name, type, comment, line_number, branch_or_repository,105 def __init__(self, name, type, comment, line_number, branch_or_repository,
106 revspec, directory, recipe_data, parent_instruction,106 revspec, directory, recipe_data, parent_instruction,
107 source_directory):107 source_directory):
108 super(_SourcePackageRecipeDataInstruction, self).__init__()108 super().__init__()
109 self.name = six.ensure_text(name)109 self.name = six.ensure_text(name)
110 self.type = type110 self.type = type
111 self.comment = comment111 self.comment = comment
@@ -431,13 +431,13 @@ class SourcePackageRecipeData(Storm):
431 else:431 else:
432 self.deb_version_template = six.ensure_text(432 self.deb_version_template = six.ensure_text(
433 builder_recipe.deb_version)433 builder_recipe.deb_version)
434 self.recipe_format = six.text_type(builder_recipe.format)434 self.recipe_format = str(builder_recipe.format)
435435
436 def __init__(self, recipe, recipe_branch_type, sourcepackage_recipe=None,436 def __init__(self, recipe, recipe_branch_type, sourcepackage_recipe=None,
437 sourcepackage_recipe_build=None):437 sourcepackage_recipe_build=None):
438 """Initialize from the bzr-builder recipe and link it to a db recipe.438 """Initialize from the bzr-builder recipe and link it to a db recipe.
439 """439 """
440 super(SourcePackageRecipeData, self).__init__()440 super().__init__()
441 self.setRecipe(recipe, recipe_branch_type)441 self.setRecipe(recipe, recipe_branch_type)
442 self.sourcepackage_recipe = sourcepackage_recipe442 self.sourcepackage_recipe = sourcepackage_recipe
443 self.sourcepackage_recipe_build = sourcepackage_recipe_build443 self.sourcepackage_recipe_build = sourcepackage_recipe_build
diff --git a/lib/lp/code/model/tests/test_branch.py b/lib/lp/code/model/tests/test_branch.py
index 16858d2..4419b12 100644
--- a/lib/lp/code/model/tests/test_branch.py
+++ b/lib/lp/code/model/tests/test_branch.py
@@ -188,7 +188,7 @@ class TestCodeImport(TestCase):
188 layer = LaunchpadZopelessLayer188 layer = LaunchpadZopelessLayer
189189
190 def setUp(self):190 def setUp(self):
191 super(TestCodeImport, self).setUp()191 super().setUp()
192 login('test@canonical.com')192 login('test@canonical.com')
193 self.factory = LaunchpadObjectFactory()193 self.factory = LaunchpadObjectFactory()
194194
@@ -1468,7 +1468,7 @@ class TestBranchDeletionConsequences(TestCase):
1468 layer = LaunchpadZopelessLayer1468 layer = LaunchpadZopelessLayer
14691469
1470 def setUp(self):1470 def setUp(self):
1471 super(TestBranchDeletionConsequences, self).setUp()1471 super().setUp()
1472 login('test@canonical.com')1472 login('test@canonical.com')
1473 self.factory = LaunchpadObjectFactory()1473 self.factory = LaunchpadObjectFactory()
1474 # Has to be a product branch because of merge proposals.1474 # Has to be a product branch because of merge proposals.
@@ -1823,7 +1823,7 @@ class BranchAddLandingTarget(TestCaseWithFactory):
1823 layer = DatabaseFunctionalLayer1823 layer = DatabaseFunctionalLayer
18241824
1825 def setUp(self):1825 def setUp(self):
1826 super(BranchAddLandingTarget, self).setUp('admin@canonical.com')1826 super().setUp('admin@canonical.com')
1827 self.product = self.factory.makeProduct()1827 self.product = self.factory.makeProduct()
18281828
1829 self.user = self.factory.makePerson()1829 self.user = self.factory.makePerson()
@@ -1837,7 +1837,7 @@ class BranchAddLandingTarget(TestCaseWithFactory):
18371837
1838 def tearDown(self):1838 def tearDown(self):
1839 logout()1839 logout()
1840 super(BranchAddLandingTarget, self).tearDown()1840 super().tearDown()
18411841
1842 def assertOnePendingReview(self, proposal, reviewer, review_type=None):1842 def assertOnePendingReview(self, proposal, reviewer, review_type=None):
1843 # There should be one pending vote for the reviewer with the specified1843 # There should be one pending vote for the reviewer with the specified
@@ -3099,7 +3099,7 @@ class TestGetMergeProposals(TestCaseWithFactory):
3099 layer = DatabaseFunctionalLayer3099 layer = DatabaseFunctionalLayer
31003100
3101 def setUp(self):3101 def setUp(self):
3102 super(TestGetMergeProposals, self).setUp()3102 super().setUp()
3103 self.branch_set = BranchSet()3103 self.branch_set = BranchSet()
31043104
3105 def test_getMergeProposals_with_no_merged_revno(self):3105 def test_getMergeProposals_with_no_merged_revno(self):
@@ -3549,7 +3549,7 @@ class TestWebservice(TestCaseWithFactory):
3549 layer = DatabaseFunctionalLayer3549 layer = DatabaseFunctionalLayer
35503550
3551 def setUp(self):3551 def setUp(self):
3552 super(TestWebservice, self).setUp()3552 super().setUp()
3553 self.branch_db = self.factory.makeBranch()3553 self.branch_db = self.factory.makeBranch()
3554 self.branch_url = api_url(self.branch_db)3554 self.branch_url = api_url(self.branch_db)
3555 self.webservice = webservice_for_person(3555 self.webservice = webservice_for_person(
diff --git a/lib/lp/code/model/tests/test_branchcollection.py b/lib/lp/code/model/tests/test_branchcollection.py
index e66b16b..062a5ab 100644
--- a/lib/lp/code/model/tests/test_branchcollection.py
+++ b/lib/lp/code/model/tests/test_branchcollection.py
@@ -106,7 +106,7 @@ class TestGenericBranchCollection(TestCaseWithFactory):
106 layer = DatabaseFunctionalLayer106 layer = DatabaseFunctionalLayer
107107
108 def setUp(self):108 def setUp(self):
109 super(TestGenericBranchCollection, self).setUp()109 super().setUp()
110 remove_all_sample_data_branches()110 remove_all_sample_data_branches()
111 self.store = IStore(Branch)111 self.store = IStore(Branch)
112112
diff --git a/lib/lp/code/model/tests/test_branchhosting.py b/lib/lp/code/model/tests/test_branchhosting.py
index 1e1f874..0190806 100644
--- a/lib/lp/code/model/tests/test_branchhosting.py
+++ b/lib/lp/code/model/tests/test_branchhosting.py
@@ -12,7 +12,6 @@ import re
1212
13from lazr.restful.utils import get_current_browser_request13from lazr.restful.utils import get_current_browser_request
14import responses14import responses
15import six
16from testtools.matchers import MatchesStructure15from testtools.matchers import MatchesStructure
17from zope.component import getUtility16from zope.component import getUtility
18from zope.interface import implementer17from zope.interface import implementer
@@ -47,7 +46,7 @@ class TestBranchHostingClient(TestCase):
47 layer = ZopelessDatabaseLayer46 layer = ZopelessDatabaseLayer
4847
49 def setUp(self):48 def setUp(self):
50 super(TestBranchHostingClient, self).setUp()49 super().setUp()
51 self.client = getUtility(IBranchHostingClient)50 self.client = getUtility(IBranchHostingClient)
52 self.endpoint = removeSecurityProxy(self.client).endpoint51 self.endpoint = removeSecurityProxy(self.client).endpoint
53 self.requests = []52 self.requests = []
@@ -155,14 +154,14 @@ class TestBranchHostingClient(TestCase):
155 "+branch-id/123/+json/files/%2Brev%20id%3F/%2Bfile/%20name%3F")154 "+branch-id/123/+json/files/%2Brev%20id%3F/%2Bfile/%20name%3F")
156155
157 def test_getBlob(self):156 def test_getBlob(self):
158 blob = b"".join(six.int2byte(i) for i in range(256))157 blob = b"".join(bytes((i,)) for i in range(256))
159 with self.mockRequests("GET", body=blob):158 with self.mockRequests("GET", body=blob):
160 response = self.client.getBlob(123, "file-id")159 response = self.client.getBlob(123, "file-id")
161 self.assertEqual(blob, response)160 self.assertEqual(blob, response)
162 self.assertRequest("+branch-id/123/download/head%3A/file-id")161 self.assertRequest("+branch-id/123/download/head%3A/file-id")
163162
164 def test_getBlob_revision(self):163 def test_getBlob_revision(self):
165 blob = b"".join(six.int2byte(i) for i in range(256))164 blob = b"".join(bytes((i,)) for i in range(256))
166 with self.mockRequests("GET", body=blob):165 with self.mockRequests("GET", body=blob):
167 response = self.client.getBlob(123, "file-id", rev="a")166 response = self.client.getBlob(123, "file-id", rev="a")
168 self.assertEqual(blob, response)167 self.assertEqual(blob, response)
@@ -195,7 +194,7 @@ class TestBranchHostingClient(TestCase):
195 self.client.getBlob, 123, "file-id")194 self.client.getBlob, 123, "file-id")
196195
197 def test_getBlob_url_quoting(self):196 def test_getBlob_url_quoting(self):
198 blob = b"".join(six.int2byte(i) for i in range(256))197 blob = b"".join(bytes((i,)) for i in range(256))
199 with self.mockRequests("GET", body=blob):198 with self.mockRequests("GET", body=blob):
200 self.client.getBlob(123, "+file/ id?", rev="+rev id?")199 self.client.getBlob(123, "+file/ id?", rev="+rev id?")
201 self.assertRequest(200 self.assertRequest(
@@ -203,12 +202,12 @@ class TestBranchHostingClient(TestCase):
203202
204 def test_works_in_job(self):203 def test_works_in_job(self):
205 # `BranchHostingClient` is usable from a running job.204 # `BranchHostingClient` is usable from a running job.
206 blob = b"".join(six.int2byte(i) for i in range(256))205 blob = b"".join(bytes((i,)) for i in range(256))
207206
208 @implementer(IRunnableJob)207 @implementer(IRunnableJob)
209 class GetBlobJob(BaseRunnableJob):208 class GetBlobJob(BaseRunnableJob):
210 def __init__(self, testcase):209 def __init__(self, testcase):
211 super(GetBlobJob, self).__init__()210 super().__init__()
212 self.job = Job()211 self.job = Job()
213 self.testcase = testcase212 self.testcase = testcase
214213
diff --git a/lib/lp/code/model/tests/test_branchjob.py b/lib/lp/code/model/tests/test_branchjob.py
index d3b7592..718df70 100644
--- a/lib/lp/code/model/tests/test_branchjob.py
+++ b/lib/lp/code/model/tests/test_branchjob.py
@@ -917,7 +917,7 @@ class TestRosettaUploadJob(TestCaseWithFactory):
917 layer = LaunchpadZopelessLayer917 layer = LaunchpadZopelessLayer
918918
919 def setUp(self):919 def setUp(self):
920 super(TestRosettaUploadJob, self).setUp()920 super().setUp()
921 self.series = None921 self.series = None
922922
923 def _makeBranchWithTreeAndFile(self, file_name, file_content=None):923 def _makeBranchWithTreeAndFile(self, file_name, file_content=None):
diff --git a/lib/lp/code/model/tests/test_branchlistingqueryoptimiser.py b/lib/lp/code/model/tests/test_branchlistingqueryoptimiser.py
index 386bb4b..319476f 100644
--- a/lib/lp/code/model/tests/test_branchlistingqueryoptimiser.py
+++ b/lib/lp/code/model/tests/test_branchlistingqueryoptimiser.py
@@ -37,8 +37,7 @@ class TestGetProductSeriesForBranches(TestCaseWithFactory):
37 def setUp(self):37 def setUp(self):
38 # Log in as an admin as we are setting series branches, which is a38 # Log in as an admin as we are setting series branches, which is a
39 # protected activity.39 # protected activity.
40 super(TestGetProductSeriesForBranches, self).setUp(40 super().setUp('admin@canonical.com')
41 'admin@canonical.com')
42 self.product = self.factory.makeProduct()41 self.product = self.factory.makeProduct()
43 self.branches = [42 self.branches = [
44 self.factory.makeProductBranch(product=self.product)43 self.factory.makeProductBranch(product=self.product)
@@ -114,8 +113,7 @@ class TestGetOfficialSourcePackageLinksForBranches(TestCaseWithFactory):
114 def setUp(self):113 def setUp(self):
115 # Log in an admin as we are setting official branches, which is a114 # Log in an admin as we are setting official branches, which is a
116 # protected activity.115 # protected activity.
117 super(TestGetOfficialSourcePackageLinksForBranches, self).setUp(116 super().setUp('admin@canonical.com')
118 'admin@canonical.com')
119117
120 def test_with_branches(self):118 def test_with_branches(self):
121 # Test the selection of the links.119 # Test the selection of the links.
diff --git a/lib/lp/code/model/tests/test_branchmergeproposal.py b/lib/lp/code/model/tests/test_branchmergeproposal.py
index ed4fdd4..fd51edf 100644
--- a/lib/lp/code/model/tests/test_branchmergeproposal.py
+++ b/lib/lp/code/model/tests/test_branchmergeproposal.py
@@ -1027,7 +1027,7 @@ class TestMergeProposalWebhooks(WithVCSScenarios, TestCaseWithFactory):
1027 layer = DatabaseFunctionalLayer1027 layer = DatabaseFunctionalLayer
10281028
1029 def setUp(self):1029 def setUp(self):
1030 super(TestMergeProposalWebhooks, self).setUp()1030 super().setUp()
1031 self.useFixture(FeatureFixture(1031 self.useFixture(FeatureFixture(
1032 {BRANCH_MERGE_PROPOSAL_WEBHOOKS_FEATURE_FLAG: "on"}))1032 {BRANCH_MERGE_PROPOSAL_WEBHOOKS_FEATURE_FLAG: "on"}))
10331033
@@ -1509,7 +1509,7 @@ class TestBranchMergeProposalBugs(WithVCSScenarios, TestCaseWithFactory):
1509 layer = DatabaseFunctionalLayer1509 layer = DatabaseFunctionalLayer
15101510
1511 def setUp(self):1511 def setUp(self):
1512 super(TestBranchMergeProposalBugs, self).setUp()1512 super().setUp()
1513 self.user = self.factory.makePerson()1513 self.user = self.factory.makePerson()
1514 login_person(self.user)1514 login_person(self.user)
1515 if self.git:1515 if self.git:
@@ -1690,16 +1690,15 @@ class TestBranchMergeProposalBugs(WithVCSScenarios, TestCaseWithFactory):
1690 bmp.updateRelatedBugsFromSource()1690 bmp.updateRelatedBugsFromSource()
1691 self.assertEqual([bug], bmp.bugs)1691 self.assertEqual([bug], bmp.bugs)
1692 matches_expected_xref = MatchesDict(1692 matches_expected_xref = MatchesDict(
1693 {("bug", six.text_type(bug.id)):1693 {("bug", str(bug.id)): ContainsDict({"metadata": Is(None)})})
1694 ContainsDict({"metadata": Is(None)})})
1695 self.assertThat(1694 self.assertThat(
1696 getUtility(IXRefSet).findFrom(1695 getUtility(IXRefSet).findFrom(
1697 ("merge_proposal", six.text_type(bmp.id)), types=["bug"]),1696 ("merge_proposal", str(bmp.id)), types=["bug"]),
1698 matches_expected_xref)1697 matches_expected_xref)
1699 self._setUpLog([bug])1698 self._setUpLog([bug])
1700 self.assertThat(1699 self.assertThat(
1701 getUtility(IXRefSet).findFrom(1700 getUtility(IXRefSet).findFrom(
1702 ("merge_proposal", six.text_type(bmp.id)), types=["bug"]),1701 ("merge_proposal", str(bmp.id)), types=["bug"]),
1703 matches_expected_xref)1702 matches_expected_xref)
17041703
1705 def test_updateRelatedBugsFromSource_honours_limit(self):1704 def test_updateRelatedBugsFromSource_honours_limit(self):
@@ -2252,7 +2251,7 @@ class TestScheduleDiffUpdates(TestCaseWithFactory):
2252 layer = DatabaseFunctionalLayer2251 layer = DatabaseFunctionalLayer
22532252
2254 def setUp(self):2253 def setUp(self):
2255 super(TestScheduleDiffUpdates, self).setUp()2254 super().setUp()
2256 self.job_source = removeSecurityProxy(2255 self.job_source = removeSecurityProxy(
2257 getUtility(IBranchMergeProposalJobSource))2256 getUtility(IBranchMergeProposalJobSource))
22582257
@@ -2511,7 +2510,7 @@ class TestBranchMergeProposalInlineComments(TestCaseWithFactory):
2511 layer = LaunchpadFunctionalLayer2510 layer = LaunchpadFunctionalLayer
25122511
2513 def setUp(self):2512 def setUp(self):
2514 super(TestBranchMergeProposalInlineComments, self).setUp()2513 super().setUp()
2515 # Create a testing IPerson, IPreviewDiff and IBranchMergeProposal2514 # Create a testing IPerson, IPreviewDiff and IBranchMergeProposal
2516 # for tests. Log in as the testing IPerson.2515 # for tests. Log in as the testing IPerson.
2517 self.person = self.factory.makePerson()2516 self.person = self.factory.makePerson()
diff --git a/lib/lp/code/model/tests/test_branchmergeproposaljobs.py b/lib/lp/code/model/tests/test_branchmergeproposaljobs.py
index 53f293c..44f04fc 100644
--- a/lib/lp/code/model/tests/test_branchmergeproposaljobs.py
+++ b/lib/lp/code/model/tests/test_branchmergeproposaljobs.py
@@ -197,8 +197,7 @@ class TestMergeProposalNeedsReviewEmailJobBzr(
197197
198 def test_run_sends_email(self):198 def test_run_sends_email(self):
199 self.useBzrBranches(direct_database=True)199 self.useBzrBranches(direct_database=True)
200 parent = super(TestMergeProposalNeedsReviewEmailJobBzr, self)200 super().test_run_sends_email()
201 parent.test_run_sends_email()
202201
203 def test_MergeProposalCreateJob_with_sourcepackage_branch(self):202 def test_MergeProposalCreateJob_with_sourcepackage_branch(self):
204 """Jobs for merge proposals with sourcepackage branches work."""203 """Jobs for merge proposals with sourcepackage branches work."""
diff --git a/lib/lp/code/model/tests/test_branchnamespace.py b/lib/lp/code/model/tests/test_branchnamespace.py
index 1c10d07..d0dad62 100644
--- a/lib/lp/code/model/tests/test_branchnamespace.py
+++ b/lib/lp/code/model/tests/test_branchnamespace.py
@@ -3,7 +3,6 @@
33
4"""Tests for `IBranchNamespace` implementations."""4"""Tests for `IBranchNamespace` implementations."""
55
6import six
7from zope.component import getUtility6from zope.component import getUtility
8from zope.security.proxy import removeSecurityProxy7from zope.security.proxy import removeSecurityProxy
98
@@ -1106,7 +1105,7 @@ class BaseValidateNewBranchMixin:
1106 def test_permitted_first_character(self):1105 def test_permitted_first_character(self):
1107 # The first character of a branch name must be a letter or a number.1106 # The first character of a branch name must be a letter or a number.
1108 namespace = self._getNamespace(self.factory.makePerson())1107 namespace = self._getNamespace(self.factory.makePerson())
1109 for c in [six.unichr(i) for i in range(128)]:1108 for c in [chr(i) for i in range(128)]:
1110 if c.isalnum():1109 if c.isalnum():
1111 namespace.validateBranchName(c)1110 namespace.validateBranchName(c)
1112 else:1111 else:
@@ -1118,7 +1117,7 @@ class BaseValidateNewBranchMixin:
1118 # After the first character, letters, numbers and certain punctuation1117 # After the first character, letters, numbers and certain punctuation
1119 # is permitted.1118 # is permitted.
1120 namespace = self._getNamespace(self.factory.makePerson())1119 namespace = self._getNamespace(self.factory.makePerson())
1121 for c in [six.unichr(i) for i in range(128)]:1120 for c in [chr(i) for i in range(128)]:
1122 if c.isalnum() or c in '+-_@.':1121 if c.isalnum() or c in '+-_@.':
1123 namespace.validateBranchName('a' + c)1122 namespace.validateBranchName('a' + c)
1124 else:1123 else:
diff --git a/lib/lp/code/model/tests/test_codeimport.py b/lib/lp/code/model/tests/test_codeimport.py
index 3af5208..4f9a355 100644
--- a/lib/lp/code/model/tests/test_codeimport.py
+++ b/lib/lp/code/model/tests/test_codeimport.py
@@ -85,7 +85,7 @@ class TestCodeImportBase(WithScenarios, TestCaseWithFactory):
85 ]85 ]
8686
87 def setUp(self, *args, **kwargs):87 def setUp(self, *args, **kwargs):
88 super(TestCodeImportBase, self).setUp(*args, **kwargs)88 super().setUp(*args, **kwargs)
89 if self.needs_git_hosting_fixture:89 if self.needs_git_hosting_fixture:
90 self.hosting_fixture = self.useFixture(GitHostingFixture())90 self.hosting_fixture = self.useFixture(GitHostingFixture())
9191
@@ -372,8 +372,7 @@ class TestCodeImportStatusUpdate(TestCodeImportBase):
372372
373 def setUp(self):373 def setUp(self):
374 # Log in a VCS Imports member.374 # Log in a VCS Imports member.
375 super(TestCodeImportStatusUpdate, self).setUp(375 super().setUp('david.allouche@canonical.com')
376 'david.allouche@canonical.com')
377 self.import_operator = getUtility(IPersonSet).getByEmail(376 self.import_operator = getUtility(IPersonSet).getByEmail(
378 'david.allouche@canonical.com')377 'david.allouche@canonical.com')
379 # Remove existing jobs.378 # Remove existing jobs.
@@ -505,12 +504,12 @@ class TestCodeImportResultsAttribute(TestCodeImportBase):
505 layer = LaunchpadFunctionalLayer504 layer = LaunchpadFunctionalLayer
506505
507 def setUp(self):506 def setUp(self):
508 super(TestCodeImportResultsAttribute, self).setUp()507 super().setUp()
509 self.code_import = self.factory.makeCodeImport(508 self.code_import = self.factory.makeCodeImport(
510 target_rcs_type=self.target_rcs_type)509 target_rcs_type=self.target_rcs_type)
511510
512 def tearDown(self):511 def tearDown(self):
513 super(TestCodeImportResultsAttribute, self).tearDown()512 super().tearDown()
514 logout()513 logout()
515514
516 def test_no_results(self):515 def test_no_results(self):
@@ -571,7 +570,7 @@ class TestConsecutiveFailureCount(TestCodeImportBase):
571 layer = LaunchpadZopelessLayer570 layer = LaunchpadZopelessLayer
572571
573 def setUp(self):572 def setUp(self):
574 super(TestConsecutiveFailureCount, self).setUp()573 super().setUp()
575 login('no-priv@canonical.com')574 login('no-priv@canonical.com')
576 self.machine = self.factory.makeCodeImportMachine()575 self.machine = self.factory.makeCodeImportMachine()
577 self.machine.setOnline()576 self.machine.setOnline()
@@ -713,7 +712,7 @@ class TestTryFailingImportAgain(TestCodeImportBase):
713712
714 def setUp(self):713 def setUp(self):
715 # Log in a VCS Imports member.714 # Log in a VCS Imports member.
716 super(TestTryFailingImportAgain, self).setUp()715 super().setUp()
717 login_person(getUtility(ILaunchpadCelebrities).vcs_imports.teamowner)716 login_person(getUtility(ILaunchpadCelebrities).vcs_imports.teamowner)
718717
719 def test_mustBeFailing(self):718 def test_mustBeFailing(self):
@@ -772,7 +771,7 @@ class TestRequestImport(TestCodeImportBase):
772771
773 def setUp(self):772 def setUp(self):
774 # We have to be logged in to request imports773 # We have to be logged in to request imports
775 super(TestRequestImport, self).setUp(user='no-priv@canonical.com')774 super().setUp(user='no-priv@canonical.com')
776775
777 def test_requestsJob(self):776 def test_requestsJob(self):
778 code_import = self.factory.makeCodeImport(777 code_import = self.factory.makeCodeImport(
diff --git a/lib/lp/code/model/tests/test_codeimportjob.py b/lib/lp/code/model/tests/test_codeimportjob.py
index d2785a6..72076a2 100644
--- a/lib/lp/code/model/tests/test_codeimportjob.py
+++ b/lib/lp/code/model/tests/test_codeimportjob.py
@@ -97,7 +97,7 @@ class TestCodeImportJob(TestCaseWithFactory):
97 layer = DatabaseFunctionalLayer97 layer = DatabaseFunctionalLayer
9898
99 def setUp(self):99 def setUp(self):
100 super(TestCodeImportJob, self).setUp()100 super().setUp()
101 login_for_code_imports()101 login_for_code_imports()
102102
103 def assertArgumentsMatch(self, code_import, matcher, start_job=False):103 def assertArgumentsMatch(self, code_import, matcher, start_job=False):
@@ -211,7 +211,7 @@ class TestCodeImportJobSet(TestCaseWithFactory):
211 layer = DatabaseFunctionalLayer211 layer = DatabaseFunctionalLayer
212212
213 def setUp(self):213 def setUp(self):
214 super(TestCodeImportJobSet, self).setUp()214 super().setUp()
215 login_for_code_imports()215 login_for_code_imports()
216216
217 def test_getByIdExisting(self):217 def test_getByIdExisting(self):
@@ -256,7 +256,7 @@ class TestCodeImportJobSetGetJobForMachine(TestCaseWithFactory):
256 def setUp(self):256 def setUp(self):
257 # Login so we can access the code import system, delete all jobs in257 # Login so we can access the code import system, delete all jobs in
258 # the sample data and set up some objects.258 # the sample data and set up some objects.
259 super(TestCodeImportJobSetGetJobForMachine, self).setUp()259 super().setUp()
260 login_for_code_imports()260 login_for_code_imports()
261 for job in IStore(CodeImportJob).find(CodeImportJob):261 for job in IStore(CodeImportJob).find(CodeImportJob):
262 job.destroySelf()262 job.destroySelf()
@@ -370,7 +370,7 @@ class ReclaimableJobTests(TestCaseWithFactory):
370 LIMIT = config.codeimportworker.maximum_heartbeat_interval370 LIMIT = config.codeimportworker.maximum_heartbeat_interval
371371
372 def setUp(self):372 def setUp(self):
373 super(ReclaimableJobTests, self).setUp()373 super().setUp()
374 login_for_code_imports()374 login_for_code_imports()
375 for job in IStore(CodeImportJob).find(CodeImportJob):375 for job in IStore(CodeImportJob).find(CodeImportJob):
376 job.destroySelf()376 job.destroySelf()
@@ -461,7 +461,7 @@ class AssertFailureMixin:
461 self.fail("AssertionError was not raised")461 self.fail("AssertionError was not raised")
462462
463463
464class NewEvents(object):464class NewEvents:
465 """Help in testing the creation of CodeImportEvent objects.465 """Help in testing the creation of CodeImportEvent objects.
466466
467 To test that an operation creates CodeImportEvent objects, create an467 To test that an operation creates CodeImportEvent objects, create an
@@ -527,7 +527,7 @@ class TestCodeImportJobWorkflowNewJob(TestCaseWithFactory,
527 layer = DatabaseFunctionalLayer527 layer = DatabaseFunctionalLayer
528528
529 def setUp(self):529 def setUp(self):
530 super(TestCodeImportJobWorkflowNewJob, self).setUp()530 super().setUp()
531 login_for_code_imports()531 login_for_code_imports()
532532
533 def test_wrongReviewStatus(self):533 def test_wrongReviewStatus(self):
@@ -631,7 +631,7 @@ class TestCodeImportJobWorkflowDeletePendingJob(TestCaseWithFactory,
631 layer = DatabaseFunctionalLayer631 layer = DatabaseFunctionalLayer
632632
633 def setUp(self):633 def setUp(self):
634 super(TestCodeImportJobWorkflowDeletePendingJob, self).setUp()634 super().setUp()
635 self.import_admin = login_for_code_imports()635 self.import_admin = login_for_code_imports()
636636
637 def test_wrongReviewStatus(self):637 def test_wrongReviewStatus(self):
@@ -687,7 +687,7 @@ class TestCodeImportJobWorkflowRequestJob(TestCaseWithFactory,
687 layer = DatabaseFunctionalLayer687 layer = DatabaseFunctionalLayer
688688
689 def setUp(self):689 def setUp(self):
690 super(TestCodeImportJobWorkflowRequestJob, self).setUp()690 super().setUp()
691 login_for_code_imports()691 login_for_code_imports()
692692
693 def test_wrongJobState(self):693 def test_wrongJobState(self):
@@ -779,7 +779,7 @@ class TestCodeImportJobWorkflowStartJob(TestCaseWithFactory,
779 layer = DatabaseFunctionalLayer779 layer = DatabaseFunctionalLayer
780780
781 def setUp(self):781 def setUp(self):
782 super(TestCodeImportJobWorkflowStartJob, self).setUp()782 super().setUp()
783 login_for_code_imports()783 login_for_code_imports()
784784
785 def test_wrongJobState(self):785 def test_wrongJobState(self):
@@ -832,7 +832,7 @@ class TestCodeImportJobWorkflowUpdateHeartbeat(TestCaseWithFactory,
832 layer = DatabaseFunctionalLayer832 layer = DatabaseFunctionalLayer
833833
834 def setUp(self):834 def setUp(self):
835 super(TestCodeImportJobWorkflowUpdateHeartbeat, self).setUp()835 super().setUp()
836 login_for_code_imports()836 login_for_code_imports()
837837
838 def test_wrongJobState(self):838 def test_wrongJobState(self):
@@ -867,7 +867,7 @@ class TestCodeImportJobWorkflowFinishJob(TestCaseWithFactory,
867 layer = LaunchpadFunctionalLayer867 layer = LaunchpadFunctionalLayer
868868
869 def setUp(self):869 def setUp(self):
870 super(TestCodeImportJobWorkflowFinishJob, self).setUp()870 super().setUp()
871 self.vcs_imports = login_for_code_imports()871 self.vcs_imports = login_for_code_imports()
872 self.machine = self.factory.makeCodeImportMachine(set_online=True)872 self.machine = self.factory.makeCodeImportMachine(set_online=True)
873873
@@ -1165,7 +1165,7 @@ class TestCodeImportJobWorkflowReclaimJob(TestCaseWithFactory,
1165 layer = DatabaseFunctionalLayer1165 layer = DatabaseFunctionalLayer
11661166
1167 def setUp(self):1167 def setUp(self):
1168 super(TestCodeImportJobWorkflowReclaimJob, self).setUp()1168 super().setUp()
1169 login_for_code_imports()1169 login_for_code_imports()
1170 self.machine = self.factory.makeCodeImportMachine(set_online=True)1170 self.machine = self.factory.makeCodeImportMachine(set_online=True)
11711171
@@ -1300,7 +1300,7 @@ class TestCodeImportJobMacaroonIssuer(MacaroonTestMixin, TestCaseWithFactory):
1300 layer = DatabaseFunctionalLayer1300 layer = DatabaseFunctionalLayer
13011301
1302 def setUp(self):1302 def setUp(self):
1303 super(TestCodeImportJobMacaroonIssuer, self).setUp()1303 super().setUp()
1304 login_for_code_imports()1304 login_for_code_imports()
1305 self.pushConfig(1305 self.pushConfig(
1306 "launchpad", internal_macaroon_secret_key="some-secret")1306 "launchpad", internal_macaroon_secret_key="some-secret")
diff --git a/lib/lp/code/model/tests/test_codeimportmachine.py b/lib/lp/code/model/tests/test_codeimportmachine.py
index 1070610..70fcea3 100644
--- a/lib/lp/code/model/tests/test_codeimportmachine.py
+++ b/lib/lp/code/model/tests/test_codeimportmachine.py
@@ -23,8 +23,7 @@ class TestCodeImportMachineShouldLookForJob(TestCaseWithFactory):
23 layer = DatabaseFunctionalLayer23 layer = DatabaseFunctionalLayer
2424
25 def setUp(self):25 def setUp(self):
26 super(TestCodeImportMachineShouldLookForJob, self).setUp(26 super().setUp('admin@canonical.com')
27 'admin@canonical.com')
28 self.machine = self.factory.makeCodeImportMachine(set_online=True)27 self.machine = self.factory.makeCodeImportMachine(set_online=True)
2928
30 def createJobRunningOnMachine(self, machine):29 def createJobRunningOnMachine(self, machine):
diff --git a/lib/lp/code/model/tests/test_codereviewkarma.py b/lib/lp/code/model/tests/test_codereviewkarma.py
index 5b3027b..846d05d 100644
--- a/lib/lp/code/model/tests/test_codereviewkarma.py
+++ b/lib/lp/code/model/tests/test_codereviewkarma.py
@@ -27,7 +27,7 @@ class TestCodeReviewKarma(TestCaseWithFactory):
27 def setUp(self):27 def setUp(self):
28 # Use an admin to get launchpad.Edit on all the branches to easily28 # Use an admin to get launchpad.Edit on all the branches to easily
29 # approve and reject the proposals.29 # approve and reject the proposals.
30 super(TestCodeReviewKarma, self).setUp('admin@canonical.com')30 super().setUp('admin@canonical.com')
31 self.useFixture(ZopeEventHandlerFixture(31 self.useFixture(ZopeEventHandlerFixture(
32 self._on_karma_assigned, (IPerson, IKarmaAssignedEvent)))32 self._on_karma_assigned, (IPerson, IKarmaAssignedEvent)))
33 self.karma_events = []33 self.karma_events = []
diff --git a/lib/lp/code/model/tests/test_gitcollection.py b/lib/lp/code/model/tests/test_gitcollection.py
index b3250f7..f9fdbe8 100644
--- a/lib/lp/code/model/tests/test_gitcollection.py
+++ b/lib/lp/code/model/tests/test_gitcollection.py
@@ -120,7 +120,7 @@ class TestGenericGitCollection(TestCaseWithFactory):
120 layer = DatabaseFunctionalLayer120 layer = DatabaseFunctionalLayer
121121
122 def setUp(self):122 def setUp(self):
123 super(TestGenericGitCollection, self).setUp()123 super().setUp()
124 self.store = IStore(GitRepository)124 self.store = IStore(GitRepository)
125125
126 def test_provides_gitcollection(self):126 def test_provides_gitcollection(self):
diff --git a/lib/lp/code/model/tests/test_githosting.py b/lib/lp/code/model/tests/test_githosting.py
index 3ca4fdc..aa3c671 100644
--- a/lib/lp/code/model/tests/test_githosting.py
+++ b/lib/lp/code/model/tests/test_githosting.py
@@ -14,7 +14,6 @@ import re
1414
15from lazr.restful.utils import get_current_browser_request15from lazr.restful.utils import get_current_browser_request
16import responses16import responses
17import six
18from six.moves.urllib.parse import (17from six.moves.urllib.parse import (
19 parse_qsl,18 parse_qsl,
20 urlsplit,19 urlsplit,
@@ -69,7 +68,7 @@ class MatchesURL(AfterPreprocessing):
69 lambda qs: sorted(parse_qsl(qs)),68 lambda qs: sorted(parse_qsl(qs)),
70 MatchesListwise(69 MatchesListwise(
71 [Equals(pair) for pair in sorted(parse_qsl(split_url.query))]))70 [Equals(pair) for pair in sorted(parse_qsl(split_url.query))]))
72 super(MatchesURL, self).__init__(71 super().__init__(
73 urlsplit, MatchesStructure(72 urlsplit, MatchesStructure(
74 scheme=Equals(split_url.scheme),73 scheme=Equals(split_url.scheme),
75 netloc=Equals(split_url.netloc),74 netloc=Equals(split_url.netloc),
@@ -83,7 +82,7 @@ class TestGitHostingClient(TestCase):
83 layer = ZopelessDatabaseLayer82 layer = ZopelessDatabaseLayer
8483
85 def setUp(self):84 def setUp(self):
86 super(TestGitHostingClient, self).setUp()85 super().setUp()
87 self.client = getUtility(IGitHostingClient)86 self.client = getUtility(IGitHostingClient)
88 self.endpoint = removeSecurityProxy(self.client).endpoint87 self.endpoint = removeSecurityProxy(self.client).endpoint
89 self.requests = []88 self.requests = []
@@ -331,7 +330,7 @@ class TestGitHostingClient(TestCase):
331 self.client.delete, "123")330 self.client.delete, "123")
332331
333 def test_getBlob(self):332 def test_getBlob(self):
334 blob = b''.join(six.int2byte(i) for i in range(256))333 blob = b''.join(bytes((i,)) for i in range(256))
335 payload = {334 payload = {
336 "data": base64.b64encode(blob).decode("UTF-8"),335 "data": base64.b64encode(blob).decode("UTF-8"),
337 "size": len(blob),336 "size": len(blob),
@@ -343,7 +342,7 @@ class TestGitHostingClient(TestCase):
343 "repo/123/blob/dir/path/file/name", method="GET")342 "repo/123/blob/dir/path/file/name", method="GET")
344343
345 def test_getBlob_revision(self):344 def test_getBlob_revision(self):
346 blob = b''.join(six.int2byte(i) for i in range(256))345 blob = b''.join(bytes((i,)) for i in range(256))
347 payload = {346 payload = {
348 "data": base64.b64encode(blob).decode("UTF-8"),347 "data": base64.b64encode(blob).decode("UTF-8"),
349 "size": len(blob),348 "size": len(blob),
@@ -378,7 +377,7 @@ class TestGitHostingClient(TestCase):
378 self.client.getBlob, "123", "dir/path/file/name")377 self.client.getBlob, "123", "dir/path/file/name")
379378
380 def test_getBlob_url_quoting(self):379 def test_getBlob_url_quoting(self):
381 blob = b''.join(six.int2byte(i) for i in range(256))380 blob = b''.join(bytes((i,)) for i in range(256))
382 payload = {381 payload = {
383 "data": base64.b64encode(blob).decode("UTF-8"),382 "data": base64.b64encode(blob).decode("UTF-8"),
384 "size": len(blob),383 "size": len(blob),
@@ -411,7 +410,7 @@ class TestGitHostingClient(TestCase):
411 self.client.getBlob, "123", "dir/path/file/name")410 self.client.getBlob, "123", "dir/path/file/name")
412411
413 def test_getBlob_wrong_size(self):412 def test_getBlob_wrong_size(self):
414 blob = b''.join(six.int2byte(i) for i in range(256))413 blob = b''.join(bytes((i,)) for i in range(256))
415 payload = {"data": base64.b64encode(blob).decode("UTF-8"), "size": 0}414 payload = {"data": base64.b64encode(blob).decode("UTF-8"), "size": 0}
416 with self.mockRequests("GET", json=payload):415 with self.mockRequests("GET", json=payload):
417 self.assertRaisesWithContent(416 self.assertRaisesWithContent(
@@ -465,7 +464,7 @@ class TestGitHostingClient(TestCase):
465 @implementer(IRunnableJob)464 @implementer(IRunnableJob)
466 class GetRefsJob(BaseRunnableJob):465 class GetRefsJob(BaseRunnableJob):
467 def __init__(self, testcase):466 def __init__(self, testcase):
468 super(GetRefsJob, self).__init__()467 super().__init__()
469 self.job = Job()468 self.job = Job()
470 self.testcase = testcase469 self.testcase = testcase
471470
diff --git a/lib/lp/code/model/tests/test_gitlookup.py b/lib/lp/code/model/tests/test_gitlookup.py
index 0f8b8fe..8914d4c 100644
--- a/lib/lp/code/model/tests/test_gitlookup.py
+++ b/lib/lp/code/model/tests/test_gitlookup.py
@@ -38,7 +38,7 @@ class TestGetByHostingPath(TestCaseWithFactory):
38 layer = DatabaseFunctionalLayer38 layer = DatabaseFunctionalLayer
3939
40 def setUp(self):40 def setUp(self):
41 super(TestGetByHostingPath, self).setUp()41 super().setUp()
42 self.lookup = getUtility(IGitLookup)42 self.lookup = getUtility(IGitLookup)
4343
44 def test_exists(self):44 def test_exists(self):
@@ -57,7 +57,7 @@ class TestGetByUniqueName(TestCaseWithFactory):
57 layer = DatabaseFunctionalLayer57 layer = DatabaseFunctionalLayer
5858
59 def setUp(self):59 def setUp(self):
60 super(TestGetByUniqueName, self).setUp()60 super().setUp()
61 self.lookup = getUtility(IGitLookup)61 self.lookup = getUtility(IGitLookup)
6262
63 def test_not_found(self):63 def test_not_found(self):
@@ -121,7 +121,7 @@ class TestGetByPath(TestCaseWithFactory):
121 layer = DatabaseFunctionalLayer121 layer = DatabaseFunctionalLayer
122122
123 def setUp(self):123 def setUp(self):
124 super(TestGetByPath, self).setUp()124 super().setUp()
125 self.lookup = getUtility(IGitLookup)125 self.lookup = getUtility(IGitLookup)
126126
127 def test_project(self):127 def test_project(self):
@@ -213,7 +213,7 @@ class TestGetByUrl(TestCaseWithFactory):
213 layer = DatabaseFunctionalLayer213 layer = DatabaseFunctionalLayer
214214
215 def setUp(self):215 def setUp(self):
216 super(TestGetByUrl, self).setUp()216 super().setUp()
217 self.lookup = getUtility(IGitLookup)217 self.lookup = getUtility(IGitLookup)
218218
219 def makeProjectRepository(self):219 def makeProjectRepository(self):
@@ -309,7 +309,7 @@ class TestGitTraverser(TestCaseWithFactory):
309 layer = DatabaseFunctionalLayer309 layer = DatabaseFunctionalLayer
310310
311 def setUp(self):311 def setUp(self):
312 super(TestGitTraverser, self).setUp()312 super().setUp()
313 self.traverser = getUtility(IGitTraverser)313 self.traverser = getUtility(IGitTraverser)
314314
315 def assertTraverses(self, path, owner, target, repository=None):315 def assertTraverses(self, path, owner, target, repository=None):
diff --git a/lib/lp/code/model/tests/test_gitnamespace.py b/lib/lp/code/model/tests/test_gitnamespace.py
index 3c4ac13..eb11aa9 100644
--- a/lib/lp/code/model/tests/test_gitnamespace.py
+++ b/lib/lp/code/model/tests/test_gitnamespace.py
@@ -5,7 +5,6 @@
55
6from unittest import mock6from unittest import mock
77
8import six
9from zope.component import getUtility8from zope.component import getUtility
10from zope.security.proxy import removeSecurityProxy9from zope.security.proxy import removeSecurityProxy
1110
@@ -954,8 +953,7 @@ class TestProjectGitNamespaceCanCreateBranches(
954953
955 def setUp(self):954 def setUp(self):
956 # Setting visibility policies is an admin-only task.955 # Setting visibility policies is an admin-only task.
957 super(TestProjectGitNamespaceCanCreateBranches, self).setUp(956 super().setUp("admin@canonical.com")
958 "admin@canonical.com")
959957
960 def test_any_person(self):958 def test_any_person(self):
961 # If there is no privacy set up, any person can create a personal959 # If there is no privacy set up, any person can create a personal
@@ -1117,7 +1115,7 @@ class BaseValidateNewRepositoryMixin:
1117 # The first character of a repository name must be a letter or a1115 # The first character of a repository name must be a letter or a
1118 # number.1116 # number.
1119 namespace = self._getNamespace(self.factory.makePerson())1117 namespace = self._getNamespace(self.factory.makePerson())
1120 for c in [six.unichr(i) for i in range(128)]:1118 for c in [chr(i) for i in range(128)]:
1121 if c.isalnum():1119 if c.isalnum():
1122 namespace.validateRepositoryName(c)1120 namespace.validateRepositoryName(c)
1123 else:1121 else:
@@ -1129,7 +1127,7 @@ class BaseValidateNewRepositoryMixin:
1129 # After the first character, letters, numbers and certain1127 # After the first character, letters, numbers and certain
1130 # punctuation is permitted.1128 # punctuation is permitted.
1131 namespace = self._getNamespace(self.factory.makePerson())1129 namespace = self._getNamespace(self.factory.makePerson())
1132 for c in [six.unichr(i) for i in range(128)]:1130 for c in [chr(i) for i in range(128)]:
1133 if c.isalnum() or c in "+-_@.":1131 if c.isalnum() or c in "+-_@.":
1134 namespace.validateRepositoryName("a" + c)1132 namespace.validateRepositoryName("a" + c)
1135 else:1133 else:
diff --git a/lib/lp/code/model/tests/test_gitref.py b/lib/lp/code/model/tests/test_gitref.py
index b97e345..f18287a 100644
--- a/lib/lp/code/model/tests/test_gitref.py
+++ b/lib/lp/code/model/tests/test_gitref.py
@@ -159,7 +159,7 @@ class TestGitRefGetCommits(TestCaseWithFactory):
159 layer = LaunchpadFunctionalLayer159 layer = LaunchpadFunctionalLayer
160160
161 def setUp(self):161 def setUp(self):
162 super(TestGitRefGetCommits, self).setUp()162 super().setUp()
163 [self.ref] = self.factory.makeGitRefs()163 [self.ref] = self.factory.makeGitRefs()
164 self.authors = [self.factory.makePerson() for _ in range(2)]164 self.authors = [self.factory.makePerson() for _ in range(2)]
165 with admin_logged_in():165 with admin_logged_in():
@@ -492,7 +492,7 @@ class TestGitRefCreateMergeProposal(TestCaseWithFactory):
492 layer = DatabaseFunctionalLayer492 layer = DatabaseFunctionalLayer
493493
494 def setUp(self):494 def setUp(self):
495 super(TestGitRefCreateMergeProposal, self).setUp()495 super().setUp()
496 with admin_logged_in():496 with admin_logged_in():
497 self.project = self.factory.makeProduct()497 self.project = self.factory.makeProduct()
498 self.user = self.factory.makePerson()498 self.user = self.factory.makePerson()
diff --git a/lib/lp/code/model/tests/test_gitrepository.py b/lib/lp/code/model/tests/test_gitrepository.py
index 6a759be..6155836 100644
--- a/lib/lp/code/model/tests/test_gitrepository.py
+++ b/lib/lp/code/model/tests/test_gitrepository.py
@@ -601,7 +601,7 @@ class TestGitIdentityMixin(TestCaseWithFactory):
601 layer = DatabaseFunctionalLayer601 layer = DatabaseFunctionalLayer
602602
603 def setUp(self):603 def setUp(self):
604 super(TestGitIdentityMixin, self).setUp()604 super().setUp()
605 self.repository_set = getUtility(IGitRepositorySet)605 self.repository_set = getUtility(IGitRepositorySet)
606606
607 def assertGitIdentity(self, repository, identity_path):607 def assertGitIdentity(self, repository, identity_path):
@@ -792,7 +792,7 @@ class TestGitRepositoryDeletion(TestCaseWithFactory):
792 layer = LaunchpadFunctionalLayer792 layer = LaunchpadFunctionalLayer
793793
794 def setUp(self):794 def setUp(self):
795 super(TestGitRepositoryDeletion, self).setUp()795 super().setUp()
796 self.user = self.factory.makePerson()796 self.user = self.factory.makePerson()
797 self.project = self.factory.makeProduct(owner=self.user)797 self.project = self.factory.makeProduct(owner=self.user)
798 self.repository = self.factory.makeGitRepository(798 self.repository = self.factory.makeGitRepository(
@@ -1001,8 +1001,7 @@ class TestGitRepositoryDeletionConsequences(TestCaseWithFactory):
1001 layer = ZopelessDatabaseLayer1001 layer = ZopelessDatabaseLayer
10021002
1003 def setUp(self):1003 def setUp(self):
1004 super(TestGitRepositoryDeletionConsequences, self).setUp(1004 super().setUp(user="test@canonical.com")
1005 user="test@canonical.com")
1006 self.repository = self.factory.makeGitRepository()1005 self.repository = self.factory.makeGitRepository()
1007 [self.ref] = self.factory.makeGitRefs(repository=self.repository)1006 [self.ref] = self.factory.makeGitRefs(repository=self.repository)
1008 # The owner of the repository is subscribed to the repository when1007 # The owner of the repository is subscribed to the repository when
@@ -1537,7 +1536,7 @@ class TestGitRepositoryPrivacy(TestCaseWithFactory):
15371536
1538 def setUp(self):1537 def setUp(self):
1539 # Use an admin user as we aren't checking edit permissions here.1538 # Use an admin user as we aren't checking edit permissions here.
1540 super(TestGitRepositoryPrivacy, self).setUp("admin@canonical.com")1539 super().setUp("admin@canonical.com")
15411540
1542 def test_personal_repositories_for_private_teams_are_private(self):1541 def test_personal_repositories_for_private_teams_are_private(self):
1543 team = self.factory.makeTeam(1542 team = self.factory.makeTeam(
@@ -2865,7 +2864,7 @@ class TestGitRepositoryFork(TestCaseWithFactory):
2865 layer = DatabaseFunctionalLayer2864 layer = DatabaseFunctionalLayer
28662865
2867 def setUp(self):2866 def setUp(self):
2868 super(TestGitRepositoryFork, self).setUp()2867 super().setUp()
2869 self.hosting_fixture = self.useFixture(GitHostingFixture())2868 self.hosting_fixture = self.useFixture(GitHostingFixture())
28702869
2871 def test_fork(self):2870 def test_fork(self):
@@ -3474,7 +3473,7 @@ class TestGitRepositorySet(TestCaseWithFactory):
3474 layer = DatabaseFunctionalLayer3473 layer = DatabaseFunctionalLayer
34753474
3476 def setUp(self):3475 def setUp(self):
3477 super(TestGitRepositorySet, self).setUp()3476 super().setUp()
3478 self.repository_set = getUtility(IGitRepositorySet)3477 self.repository_set = getUtility(IGitRepositorySet)
34793478
3480 def test_new(self):3479 def test_new(self):
@@ -3775,7 +3774,7 @@ class TestGitRepositorySetDefaultsMixin:
3775 layer = DatabaseFunctionalLayer3774 layer = DatabaseFunctionalLayer
37763775
3777 def setUp(self):3776 def setUp(self):
3778 super(TestGitRepositorySetDefaultsMixin, self).setUp()3777 super().setUp()
3779 self.repository_set = getUtility(IGitRepositorySet)3778 self.repository_set = getUtility(IGitRepositorySet)
3780 self.get_method = self.repository_set.getDefaultRepository3779 self.get_method = self.repository_set.getDefaultRepository
3781 self.set_method = (lambda target, repository, user:3780 self.set_method = (lambda target, repository, user:
@@ -3857,7 +3856,7 @@ class TestGitRepositorySetDefaultsOwnerMixin(
3857 TestGitRepositorySetDefaultsMixin):3856 TestGitRepositorySetDefaultsMixin):
38583857
3859 def setUp(self):3858 def setUp(self):
3860 super(TestGitRepositorySetDefaultsOwnerMixin, self).setUp()3859 super().setUp()
3861 self.person = self.factory.makePerson()3860 self.person = self.factory.makePerson()
3862 self.get_method = partial(3861 self.get_method = partial(
3863 self.repository_set.getDefaultRepositoryForOwner, self.person)3862 self.repository_set.getDefaultRepositoryForOwner, self.person)
@@ -4098,7 +4097,7 @@ class TestGitRepositoryWebservice(TestCaseWithFactory):
4098 self.assertNewWorks(self.factory.makePerson())4097 self.assertNewWorks(self.factory.makePerson())
40994098
4100 def test_new_repo_not_owner(self):4099 def test_new_repo_not_owner(self):
4101 non_ascii_name = u'AndrƩ Luƭs Lopes'4100 non_ascii_name = 'AndrƩ Luƭs Lopes'
4102 other_user = self.factory.makePerson(displayname=non_ascii_name)4101 other_user = self.factory.makePerson(displayname=non_ascii_name)
4103 owner_url = api_url(other_user)4102 owner_url = api_url(other_user)
4104 webservice_user = self.factory.makePerson()4103 webservice_user = self.factory.makePerson()
@@ -4109,8 +4108,8 @@ class TestGitRepositoryWebservice(TestCaseWithFactory):
4109 response = webservice.named_post(4108 response = webservice.named_post(
4110 "/+git", "new", owner=owner_url, target=owner_url, name=name)4109 "/+git", "new", owner=owner_url, target=owner_url, name=name)
4111 self.assertEqual(400, response.status)4110 self.assertEqual(400, response.status)
4112 self.assertIn(u'cannot create Git repositories owned by'4111 self.assertIn('cannot create Git repositories owned by'
4113 u' AndrƩ Luƭs Lopes', response.body.decode('utf-8'))4112 ' AndrƩ Luƭs Lopes', response.body.decode('utf-8'))
41144113
4115 def assertGetRepositoriesWorks(self, target_db):4114 def assertGetRepositoriesWorks(self, target_db):
4116 if IPerson.providedBy(target_db):4115 if IPerson.providedBy(target_db):
@@ -4978,7 +4977,7 @@ class TestRevisionStatusReportWebservice(TestCaseWithFactory):
4978 layer = LaunchpadFunctionalLayer4977 layer = LaunchpadFunctionalLayer
49794978
4980 def setUp(self):4979 def setUp(self):
4981 super(TestRevisionStatusReportWebservice, self).setUp()4980 super().setUp()
4982 self.repository = self.factory.makeGitRepository()4981 self.repository = self.factory.makeGitRepository()
4983 self.requester = self.repository.owner4982 self.requester = self.repository.owner
4984 title = self.factory.getUniqueUnicode('report-title')4983 title = self.factory.getUniqueUnicode('report-title')
@@ -5034,7 +5033,7 @@ class TestGitRepositoryMacaroonIssuer(MacaroonTestMixin, TestCaseWithFactory):
5034 layer = DatabaseFunctionalLayer5033 layer = DatabaseFunctionalLayer
50355034
5036 def setUp(self):5035 def setUp(self):
5037 super(TestGitRepositoryMacaroonIssuer, self).setUp()5036 super().setUp()
5038 self.pushConfig("codehosting", git_macaroon_secret_key="some-secret")5037 self.pushConfig("codehosting", git_macaroon_secret_key="some-secret")
50395038
5040 def test_issueMacaroon_refuses_branch(self):5039 def test_issueMacaroon_refuses_branch(self):
diff --git a/lib/lp/code/model/tests/test_revision.py b/lib/lp/code/model/tests/test_revision.py
index 957f2ca..bdd0f7a 100644
--- a/lib/lp/code/model/tests/test_revision.py
+++ b/lib/lp/code/model/tests/test_revision.py
@@ -204,7 +204,7 @@ class TestRevisionSet(TestCaseWithFactory):
204 layer = DatabaseFunctionalLayer204 layer = DatabaseFunctionalLayer
205205
206 def setUp(self):206 def setUp(self):
207 super(TestRevisionSet, self).setUp()207 super().setUp()
208 self.revision_set = getUtility(IRevisionSet)208 self.revision_set = getUtility(IRevisionSet)
209209
210 def test_getRevisionById_existing(self):210 def test_getRevisionById_existing(self):
diff --git a/lib/lp/code/model/tests/test_revisionauthor.py b/lib/lp/code/model/tests/test_revisionauthor.py
index 4953571..9941c7f 100644
--- a/lib/lp/code/model/tests/test_revisionauthor.py
+++ b/lib/lp/code/model/tests/test_revisionauthor.py
@@ -35,7 +35,7 @@ class TestRevisionEmailExtraction(TestCase):
35 layer = LaunchpadZopelessLayer35 layer = LaunchpadZopelessLayer
3636
37 def setUp(self):37 def setUp(self):
38 super(TestRevisionEmailExtraction, self).setUp()38 super().setUp()
39 switch_dbuser("branchscanner")39 switch_dbuser("branchscanner")
4040
41 def test_email_extracted_from_name(self):41 def test_email_extracted_from_name(self):
@@ -134,7 +134,7 @@ class TestNewlyValidatedEmailsLinkRevisionAuthors(MakeHarryTestCase):
134134
135 def setUp(self):135 def setUp(self):
136 # Create a revision author that doesn't have a user yet.136 # Create a revision author that doesn't have a user yet.
137 super(TestNewlyValidatedEmailsLinkRevisionAuthors, self).setUp()137 super().setUp()
138 with dbuser("branchscanner"):138 with dbuser("branchscanner"):
139 self.author = RevisionSet()._createRevisionAuthor(139 self.author = RevisionSet()._createRevisionAuthor(
140 '"Harry Potter" <harry@canonical.com>')140 '"Harry Potter" <harry@canonical.com>')
@@ -171,35 +171,35 @@ class TestRevisionAuthor(TestCase):
171 layer = LaunchpadZopelessLayer171 layer = LaunchpadZopelessLayer
172172
173 def setUp(self):173 def setUp(self):
174 super(TestRevisionAuthor, self).setUp()174 super().setUp()
175 switch_dbuser("branchscanner")175 switch_dbuser("branchscanner")
176176
177 def testGetNameWithoutEmailReturnsNamePart(self):177 def testGetNameWithoutEmailReturnsNamePart(self):
178 # name_without_email is equal to the 'name' part of the revision178 # name_without_email is equal to the 'name' part of the revision
179 # author information.179 # author information.
180 author = RevisionAuthor(name=u'Jonathan Lange <jml@canonical.com>')180 author = RevisionAuthor(name='Jonathan Lange <jml@canonical.com>')
181 self.assertEqual(u'Jonathan Lange', author.name_without_email)181 self.assertEqual('Jonathan Lange', author.name_without_email)
182182
183 def testGetNameWithoutEmailWithNoName(self):183 def testGetNameWithoutEmailWithNoName(self):
184 # If there is no name in the revision author information,184 # If there is no name in the revision author information,
185 # name_without_email is an empty string.185 # name_without_email is an empty string.
186 author = RevisionAuthor(name=u'jml@mumak.net')186 author = RevisionAuthor(name='jml@mumak.net')
187 self.assertEqual('', author.name_without_email)187 self.assertEqual('', author.name_without_email)
188188
189 def testGetNameWithoutEmailWithNoEmail(self):189 def testGetNameWithoutEmailWithNoEmail(self):
190 # If there is no email in the revision author information,190 # If there is no email in the revision author information,
191 # name_without_email is the name.191 # name_without_email is the name.
192 author = RevisionAuthor(name=u'Jonathan Lange')192 author = RevisionAuthor(name='Jonathan Lange')
193 self.assertEqual('Jonathan Lange', author.name_without_email)193 self.assertEqual('Jonathan Lange', author.name_without_email)
194194
195 def testGetNameWithoutEmailWithOneWord(self):195 def testGetNameWithoutEmailWithOneWord(self):
196 # If there is no email in the revision author information,196 # If there is no email in the revision author information,
197 # name_without_email is the name.197 # name_without_email is the name.
198 author = RevisionAuthor(name=u'Jonathan.Lange')198 author = RevisionAuthor(name='Jonathan.Lange')
199 self.assertEqual('Jonathan.Lange', author.name_without_email)199 self.assertEqual('Jonathan.Lange', author.name_without_email)
200200
201 def testGetNameWithoutEmailWithBadEmail(self):201 def testGetNameWithoutEmailWithBadEmail(self):
202 # If there is an invalid email in the revision author information,202 # If there is an invalid email in the revision author information,
203 # name_without_email is an empty string.203 # name_without_email is an empty string.
204 author = RevisionAuthor(name=u'jml@localhost')204 author = RevisionAuthor(name='jml@localhost')
205 self.assertEqual('', author.name_without_email)205 self.assertEqual('', author.name_without_email)
diff --git a/lib/lp/code/model/tests/test_sourcepackagerecipe.py b/lib/lp/code/model/tests/test_sourcepackagerecipe.py
index 719ab3b..4837166 100644
--- a/lib/lp/code/model/tests/test_sourcepackagerecipe.py
+++ b/lib/lp/code/model/tests/test_sourcepackagerecipe.py
@@ -859,7 +859,7 @@ class TestRecipeBranchRoundTrippingMixin:
859 layer = DatabaseFunctionalLayer859 layer = DatabaseFunctionalLayer
860860
861 def setUp(self):861 def setUp(self):
862 super(TestRecipeBranchRoundTrippingMixin, self).setUp()862 super().setUp()
863 self.base_branch = self.makeBranch()863 self.base_branch = self.makeBranch()
864 self.nested_branch = self.makeBranch()864 self.nested_branch = self.makeBranch()
865 self.merged_branch = self.makeBranch()865 self.merged_branch = self.makeBranch()
diff --git a/lib/lp/code/scripts/repackgitrepository.py b/lib/lp/code/scripts/repackgitrepository.py
index 9a202a4..6c880da 100644
--- a/lib/lp/code/scripts/repackgitrepository.py
+++ b/lib/lp/code/scripts/repackgitrepository.py
@@ -6,7 +6,6 @@
6from datetime import timedelta6from datetime import timedelta
77
8from psycopg2.extensions import TransactionRollbackError8from psycopg2.extensions import TransactionRollbackError
9import six
10from storm.expr import (9from storm.expr import (
11 Cast,10 Cast,
12 Or,11 Or,
@@ -33,7 +32,7 @@ class RepackTunableLoop(TunableLoop):
33 targets = 100032 targets = 1000
3433
35 def __init__(self, log, dry_run, abort_time=None):34 def __init__(self, log, dry_run, abort_time=None):
36 super(RepackTunableLoop, self).__init__(log, abort_time)35 super().__init__(log, abort_time)
37 self.dry_run = dry_run36 self.dry_run = dry_run
38 self.start_at = 037 self.start_at = 0
39 self.logger = log38 self.logger = log
@@ -103,7 +102,7 @@ class RepackTunableLoop(TunableLoop):
103 except TransactionRollbackError as error:102 except TransactionRollbackError as error:
104 self.logger.error(103 self.logger.error(
105 'An error occurred while requesting repository repack %s'104 'An error occurred while requesting repository repack %s'
106 % six.text_type(error))105 % str(error))
107 if transaction is not None:106 if transaction is not None:
108 transaction.abort()107 transaction.abort()
109 continue108 continue
diff --git a/lib/lp/code/scripts/tests/test_repack_git_repositories.py b/lib/lp/code/scripts/tests/test_repack_git_repositories.py
index 9314997..77d1fad 100644
--- a/lib/lp/code/scripts/tests/test_repack_git_repositories.py
+++ b/lib/lp/code/scripts/tests/test_repack_git_repositories.py
@@ -52,7 +52,7 @@ class FakeTurnipServer(threading.Thread):
52 """Thread that runs a fake turnip server."""52 """Thread that runs a fake turnip server."""
5353
54 def __init__(self):54 def __init__(self):
55 super(FakeTurnipServer, self).__init__()55 super().__init__()
56 self.name = 'FakeTurnipServer'56 self.name = 'FakeTurnipServer'
57 self.app = FakeTurnipApplication()57 self.app = FakeTurnipApplication()
58 self.server = make_server(58 self.server = make_server(
@@ -74,7 +74,7 @@ class TestRequestGitRepack(TestCaseWithFactory):
74 layer = ZopelessAppServerLayer74 layer = ZopelessAppServerLayer
7575
76 def setUp(self):76 def setUp(self):
77 super(TestRequestGitRepack, self).setUp()77 super().setUp()
78 self.log = logging.getLogger('repack')78 self.log = logging.getLogger('repack')
7979
80 def runScript_no_Turnip(self):80 def runScript_no_Turnip(self):
diff --git a/lib/lp/code/scripts/tests/test_request_daily_builds.py b/lib/lp/code/scripts/tests/test_request_daily_builds.py
index d1ac03a..0d9b970 100644
--- a/lib/lp/code/scripts/tests/test_request_daily_builds.py
+++ b/lib/lp/code/scripts/tests/test_request_daily_builds.py
@@ -102,7 +102,7 @@ class FakeLoggerheadServer(threading.Thread):
102 """Thread that runs a fake loggerhead server."""102 """Thread that runs a fake loggerhead server."""
103103
104 def __init__(self):104 def __init__(self):
105 super(FakeLoggerheadServer, self).__init__()105 super().__init__()
106 self.app = FakeLoggerheadApplication()106 self.app = FakeLoggerheadApplication()
107 self.server = make_server(107 self.server = make_server(
108 'localhost', 0, self.app, handler_class=SilentWSGIRequestHandler)108 'localhost', 0, self.app, handler_class=SilentWSGIRequestHandler)
@@ -162,7 +162,7 @@ class FakeTurnipServer(threading.Thread):
162 """Thread that runs a fake turnip server."""162 """Thread that runs a fake turnip server."""
163163
164 def __init__(self):164 def __init__(self):
165 super(FakeTurnipServer, self).__init__()165 super().__init__()
166 self.app = FakeTurnipApplication()166 self.app = FakeTurnipApplication()
167 self.server = make_server(167 self.server = make_server(
168 'localhost', 0, self.app, handler_class=SilentWSGIRequestHandler)168 'localhost', 0, self.app, handler_class=SilentWSGIRequestHandler)
@@ -186,7 +186,7 @@ class TestRequestDailyBuilds(TestCaseWithFactory):
186 layer = ZopelessAppServerLayer186 layer = ZopelessAppServerLayer
187187
188 def setUp(self):188 def setUp(self):
189 super(TestRequestDailyBuilds, self).setUp()189 super().setUp()
190 features = dict(SNAP_TESTING_FLAGS)190 features = dict(SNAP_TESTING_FLAGS)
191 features[CHARM_RECIPE_ALLOW_CREATE] = "on"191 features[CHARM_RECIPE_ALLOW_CREATE] = "on"
192 self.useFixture(FeatureFixture(features))192 self.useFixture(FeatureFixture(features))
diff --git a/lib/lp/code/tests/helpers.py b/lib/lp/code/tests/helpers.py
index a240ab4..f566b60 100644
--- a/lib/lp/code/tests/helpers.py
+++ b/lib/lp/code/tests/helpers.py
@@ -150,8 +150,7 @@ def consistent_branch_names():
150150
151 This generator does not finish!151 This generator does not finish!
152 """152 """
153 for name in ['trunk', 'testing', 'feature-x', 'feature-y', 'feature-z']:153 yield from ['trunk', 'testing', 'feature-x', 'feature-y', 'feature-z']
154 yield name
155 index = count(1)154 index = count(1)
156 while True:155 while True:
157 yield "branch-%s" % next(index)156 yield "branch-%s" % next(index)
diff --git a/lib/lp/code/tests/test_branch.py b/lib/lp/code/tests/test_branch.py
index a9e704d..5b316f3 100644
--- a/lib/lp/code/tests/test_branch.py
+++ b/lib/lp/code/tests/test_branch.py
@@ -331,7 +331,7 @@ class TestComposePublicURL(TestCaseWithFactory):
331 layer = DatabaseFunctionalLayer331 layer = DatabaseFunctionalLayer
332332
333 def setUp(self):333 def setUp(self):
334 super(TestComposePublicURL, self).setUp('admin@canonical.com')334 super().setUp('admin@canonical.com')
335335
336 def test_composePublicURL_accepts_supported_schemes(self):336 def test_composePublicURL_accepts_supported_schemes(self):
337 # composePublicURL accepts all schemes that PublicCodehostingAPI337 # composePublicURL accepts all schemes that PublicCodehostingAPI
diff --git a/lib/lp/code/tests/test_branch_webservice.py b/lib/lp/code/tests/test_branch_webservice.py
index 653ea5c..0a7e495 100644
--- a/lib/lp/code/tests/test_branch_webservice.py
+++ b/lib/lp/code/tests/test_branch_webservice.py
@@ -175,7 +175,7 @@ class TestBranchDeletes(TestCaseWithFactory):
175 layer = DatabaseFunctionalLayer175 layer = DatabaseFunctionalLayer
176176
177 def setUp(self):177 def setUp(self):
178 super(TestBranchDeletes, self).setUp()178 super().setUp()
179 self.branch_owner = self.factory.makePerson(name='jimhenson')179 self.branch_owner = self.factory.makePerson(name='jimhenson')
180 self.branch = self.factory.makeBranch(180 self.branch = self.factory.makeBranch(
181 owner=self.branch_owner,181 owner=self.branch_owner,
diff --git a/lib/lp/code/tests/test_bzr.py b/lib/lp/code/tests/test_bzr.py
index 7f6939c..d430ad0 100644
--- a/lib/lp/code/tests/test_bzr.py
+++ b/lib/lp/code/tests/test_bzr.py
@@ -9,7 +9,6 @@ from breezy.tests import (
9 TestCaseInTempDir,9 TestCaseInTempDir,
10 TestCaseWithTransport,10 TestCaseWithTransport,
11 )11 )
12import six
1312
14from lp.code.bzr import (13from lp.code.bzr import (
15 branch_revision_history,14 branch_revision_history,
@@ -46,7 +45,7 @@ class TestGetBranchFormats(TestCaseInTempDir):
4645
47 def test_get_branch_format_2a(self):46 def test_get_branch_format_2a(self):
48 # Test the 2a branch format.47 # Test the 2a branch format.
49 branch = self.make_branch('test', six.ensure_str('2a'))48 branch = self.make_branch('test', '2a')
50 formats = get_branch_formats(branch)49 formats = get_branch_formats(branch)
51 self.assertEqual(ControlFormat.BZR_METADIR_1, formats[0])50 self.assertEqual(ControlFormat.BZR_METADIR_1, formats[0])
52 self.assertEqual(BranchFormat.BZR_BRANCH_7, formats[1])51 self.assertEqual(BranchFormat.BZR_BRANCH_7, formats[1])
@@ -54,7 +53,7 @@ class TestGetBranchFormats(TestCaseInTempDir):
5453
55 def test_get_branch_format_1_9(self):54 def test_get_branch_format_1_9(self):
56 # Test the 1.9 branch format.55 # Test the 1.9 branch format.
57 branch = self.make_branch('test', six.ensure_str('1.9'))56 branch = self.make_branch('test', '1.9')
58 formats = get_branch_formats(branch)57 formats = get_branch_formats(branch)
59 self.assertEqual(ControlFormat.BZR_METADIR_1, formats[0])58 self.assertEqual(ControlFormat.BZR_METADIR_1, formats[0])
60 self.assertEqual(BranchFormat.BZR_BRANCH_7, formats[1])59 self.assertEqual(BranchFormat.BZR_BRANCH_7, formats[1])
@@ -62,7 +61,7 @@ class TestGetBranchFormats(TestCaseInTempDir):
6261
63 def test_get_branch_format_packs(self):62 def test_get_branch_format_packs(self):
64 # Test the packs branch format.63 # Test the packs branch format.
65 branch = self.make_branch('test', six.ensure_str('pack-0.92'))64 branch = self.make_branch('test', 'pack-0.92')
66 formats = get_branch_formats(branch)65 formats = get_branch_formats(branch)
67 self.assertEqual(ControlFormat.BZR_METADIR_1, formats[0])66 self.assertEqual(ControlFormat.BZR_METADIR_1, formats[0])
68 self.assertEqual(BranchFormat.BZR_BRANCH_6, formats[1])67 self.assertEqual(BranchFormat.BZR_BRANCH_6, formats[1])
@@ -70,7 +69,7 @@ class TestGetBranchFormats(TestCaseInTempDir):
7069
71 def test_get_branch_format_knits(self):70 def test_get_branch_format_knits(self):
72 # Test the knits branch format.71 # Test the knits branch format.
73 branch = self.make_branch('test', six.ensure_str('knit'))72 branch = self.make_branch('test', 'knit')
74 formats = get_branch_formats(branch)73 formats = get_branch_formats(branch)
75 self.assertEqual(ControlFormat.BZR_METADIR_1, formats[0])74 self.assertEqual(ControlFormat.BZR_METADIR_1, formats[0])
76 self.assertEqual(BranchFormat.BZR_BRANCH_5, formats[1])75 self.assertEqual(BranchFormat.BZR_BRANCH_5, formats[1])
diff --git a/lib/lp/code/tests/test_directbranchcommit.py b/lib/lp/code/tests/test_directbranchcommit.py
index 977d855..db4d71c 100644
--- a/lib/lp/code/tests/test_directbranchcommit.py
+++ b/lib/lp/code/tests/test_directbranchcommit.py
@@ -30,7 +30,7 @@ class DirectBranchCommitTestCase:
30 committer = None30 committer = None
3131
32 def setUp(self):32 def setUp(self):
33 super(DirectBranchCommitTestCase, self).setUp()33 super().setUp()
34 self.useBzrBranches(direct_database=True)34 self.useBzrBranches(direct_database=True)
3535
36 self.series = self.factory.makeProductSeries()36 self.series = self.factory.makeProductSeries()
@@ -292,7 +292,7 @@ class TestGetBzrCommitterID(TestCaseWithFactory):
292 layer = DatabaseFunctionalLayer292 layer = DatabaseFunctionalLayer
293293
294 def setUp(self):294 def setUp(self):
295 super(TestGetBzrCommitterID, self).setUp()295 super().setUp()
296 self.useBzrBranches(direct_database=True)296 self.useBzrBranches(direct_database=True)
297297
298 def _makeBranch(self, **kwargs):298 def _makeBranch(self, **kwargs):
diff --git a/lib/lp/code/tests/test_project.py b/lib/lp/code/tests/test_project.py
index d765060..7230a94 100644
--- a/lib/lp/code/tests/test_project.py
+++ b/lib/lp/code/tests/test_project.py
@@ -12,7 +12,7 @@ class TestProjectBranches(TestCaseWithFactory):
12 layer = DatabaseFunctionalLayer12 layer = DatabaseFunctionalLayer
1313
14 def setUp(self):14 def setUp(self):
15 super(TestProjectBranches, self).setUp()15 super().setUp()
16 self.projectgroup = self.factory.makeProject()16 self.projectgroup = self.factory.makeProject()
17 self.product = self.factory.makeProduct(projectgroup=self.projectgroup)17 self.product = self.factory.makeProduct(projectgroup=self.projectgroup)
1818
diff --git a/lib/lp/code/vocabularies/branch.py b/lib/lp/code/vocabularies/branch.py
index b165edc..d1b5eb9 100644
--- a/lib/lp/code/vocabularies/branch.py
+++ b/lib/lp/code/vocabularies/branch.py
@@ -70,7 +70,7 @@ class BranchRestrictedOnProductVocabulary(BranchVocabulary):
70 """A vocabulary for searching branches restricted on product."""70 """A vocabulary for searching branches restricted on product."""
7171
72 def __init__(self, context=None):72 def __init__(self, context=None):
73 super(BranchRestrictedOnProductVocabulary, self).__init__(context)73 super().__init__(context)
74 if IProduct.providedBy(self.context):74 if IProduct.providedBy(self.context):
75 self.product = self.context75 self.product = self.context
76 elif IProductSeries.providedBy(self.context):76 elif IProductSeries.providedBy(self.context):
@@ -94,7 +94,7 @@ class HostedBranchRestrictedOnOwnerVocabulary(BranchVocabulary):
9494
95 def __init__(self, context=None):95 def __init__(self, context=None):
96 """Pass a Person as context, or anything else for the current user."""96 """Pass a Person as context, or anything else for the current user."""
97 super(HostedBranchRestrictedOnOwnerVocabulary, self).__init__(context)97 super().__init__(context)
98 if IPerson.providedBy(self.context):98 if IPerson.providedBy(self.context):
99 self.user = self.context99 self.user = self.context
100 else:100 else:
diff --git a/lib/lp/code/vocabularies/gitref.py b/lib/lp/code/vocabularies/gitref.py
index de842d1..2a2bad3 100644
--- a/lib/lp/code/vocabularies/gitref.py
+++ b/lib/lp/code/vocabularies/gitref.py
@@ -59,7 +59,7 @@ class GitRefVocabulary(StormVocabularyBase):
59 step_title = "Search"59 step_title = "Search"
6060
61 def __init__(self, context):61 def __init__(self, context):
62 super(GitRefVocabulary, self).__init__(context=context)62 super().__init__(context=context)
63 if IReference.providedBy(context):63 if IReference.providedBy(context):
64 context = context.context64 context = context.context
65 try:65 try:
@@ -135,7 +135,7 @@ class GitRefVocabulary(StormVocabularyBase):
135 # remote refs aren't database backed135 # remote refs aren't database backed
136 if zope_isinstance(value, GitRefRemote):136 if zope_isinstance(value, GitRefRemote):
137 return self.toTerm(value)137 return self.toTerm(value)
138 return super(GitRefVocabulary, self).getTerm(value)138 return super().getTerm(value)
139139
140 def __len__(self):140 def __len__(self):
141 """See `IVocabulary`."""141 """See `IVocabulary`."""
diff --git a/lib/lp/code/vocabularies/gitrepository.py b/lib/lp/code/vocabularies/gitrepository.py
index 4f6f9df..92f8c3c 100644
--- a/lib/lp/code/vocabularies/gitrepository.py
+++ b/lib/lp/code/vocabularies/gitrepository.py
@@ -67,8 +67,7 @@ class GitRepositoryRestrictedOnProductVocabulary(GitRepositoryVocabulary):
67 """A vocabulary for searching git repositories restricted on product."""67 """A vocabulary for searching git repositories restricted on product."""
6868
69 def __init__(self, context):69 def __init__(self, context):
70 super(GitRepositoryRestrictedOnProductVocabulary, self).__init__(70 super().__init__(context)
71 context)
72 if IProduct.providedBy(self.context):71 if IProduct.providedBy(self.context):
73 self.product = self.context72 self.product = self.context
74 else:73 else:
diff --git a/lib/lp/code/vocabularies/gitrule.py b/lib/lp/code/vocabularies/gitrule.py
index 4b6284b..f6be79b 100644
--- a/lib/lp/code/vocabularies/gitrule.py
+++ b/lib/lp/code/vocabularies/gitrule.py
@@ -102,4 +102,4 @@ class GitPermissionsVocabulary(SimpleVocabulary):
102 terms.append(SimpleTerm(102 terms.append(SimpleTerm(
103 grant_permissions,103 grant_permissions,
104 "custom", "Custom permissions: %s" % ", ".join(names)))104 "custom", "Custom permissions: %s" % ", ".join(names)))
105 super(GitPermissionsVocabulary, self).__init__(terms)105 super().__init__(terms)
diff --git a/lib/lp/code/vocabularies/tests/test_branch_vocabularies.py b/lib/lp/code/vocabularies/tests/test_branch_vocabularies.py
index 7773c17..23d018f 100644
--- a/lib/lp/code/vocabularies/tests/test_branch_vocabularies.py
+++ b/lib/lp/code/vocabularies/tests/test_branch_vocabularies.py
@@ -22,7 +22,7 @@ class TestBranchVocabulary(TestCaseWithFactory):
22 layer = DatabaseFunctionalLayer22 layer = DatabaseFunctionalLayer
2323
24 def setUp(self):24 def setUp(self):
25 super(TestBranchVocabulary, self).setUp()25 super().setUp()
26 self._createBranches()26 self._createBranches()
27 self.vocab = BranchVocabulary(context=None)27 self.vocab = BranchVocabulary(context=None)
2828
@@ -40,8 +40,7 @@ class TestBranchVocabulary(TestCaseWithFactory):
40 def test_fizzbuzzBranches(self):40 def test_fizzbuzzBranches(self):
41 """Return branches that match the string 'fizzbuzz'."""41 """Return branches that match the string 'fizzbuzz'."""
42 results = self.vocab.searchForTerms('fizzbuzz')42 results = self.vocab.searchForTerms('fizzbuzz')
43 expected = [43 expected = ['~scotty/sprocket/fizzbuzz', '~scotty/widget/fizzbuzz']
44 u'~scotty/sprocket/fizzbuzz', u'~scotty/widget/fizzbuzz']
45 branch_names = sorted(branch.token for branch in results)44 branch_names = sorted(branch.token for branch in results)
46 self.assertEqual(expected, branch_names)45 self.assertEqual(expected, branch_names)
4746
@@ -68,7 +67,7 @@ class TestRestrictedBranchVocabularyOnProduct(TestCaseWithFactory):
68 layer = DatabaseFunctionalLayer67 layer = DatabaseFunctionalLayer
6968
70 def setUp(self):69 def setUp(self):
71 super(TestRestrictedBranchVocabularyOnProduct, self).setUp()70 super().setUp()
72 self._createBranches()71 self._createBranches()
73 self.vocab = BranchRestrictedOnProductVocabulary(72 self.vocab = BranchRestrictedOnProductVocabulary(
74 context=self._getVocabRestriction())73 context=self._getVocabRestriction())
@@ -98,7 +97,7 @@ class TestRestrictedBranchVocabularyOnProduct(TestCaseWithFactory):
98 The result set should not show ~scotty/sprocket/main.97 The result set should not show ~scotty/sprocket/main.
99 """98 """
100 results = self.vocab.searchForTerms('main')99 results = self.vocab.searchForTerms('main')
101 expected = [u'~scotty/widget/main']100 expected = ['~scotty/widget/main']
102 branch_names = sorted(branch.token for branch in results)101 branch_names = sorted(branch.token for branch in results)
103 self.assertEqual(expected, branch_names)102 self.assertEqual(expected, branch_names)
104103
diff --git a/lib/lp/code/vocabularies/tests/test_gitrepository_vocabularies.py b/lib/lp/code/vocabularies/tests/test_gitrepository_vocabularies.py
index 774b0a1..d64d8c0 100644
--- a/lib/lp/code/vocabularies/tests/test_gitrepository_vocabularies.py
+++ b/lib/lp/code/vocabularies/tests/test_gitrepository_vocabularies.py
@@ -20,7 +20,7 @@ class TestGitRepositoryVocabulary(TestCaseWithFactory):
20 layer = DatabaseFunctionalLayer20 layer = DatabaseFunctionalLayer
2121
22 def setUp(self):22 def setUp(self):
23 super(TestGitRepositoryVocabulary, self).setUp()23 super().setUp()
24 self._createRepositories()24 self._createRepositories()
25 self.vocab = GitRepositoryVocabulary(context=None)25 self.vocab = GitRepositoryVocabulary(context=None)
2626
@@ -29,17 +29,17 @@ class TestGitRepositoryVocabulary(TestCaseWithFactory):
29 sprocket = self.factory.makeProduct(name="sprocket")29 sprocket = self.factory.makeProduct(name="sprocket")
30 scotty = self.factory.makePerson(name="scotty")30 scotty = self.factory.makePerson(name="scotty")
31 self.factory.makeGitRepository(31 self.factory.makeGitRepository(
32 owner=scotty, target=widget, name=u"fizzbuzz")32 owner=scotty, target=widget, name="fizzbuzz")
33 self.factory.makeGitRepository(33 self.factory.makeGitRepository(
34 owner=scotty, target=widget, name=u"mountain")34 owner=scotty, target=widget, name="mountain")
35 self.factory.makeGitRepository(35 self.factory.makeGitRepository(
36 owner=scotty, target=sprocket, name=u"fizzbuzz")36 owner=scotty, target=sprocket, name="fizzbuzz")
3737
38 def test_fizzbuzzRepositories(self):38 def test_fizzbuzzRepositories(self):
39 """Return repositories that match the string 'fizzbuzz'."""39 """Return repositories that match the string 'fizzbuzz'."""
40 results = self.vocab.searchForTerms("fizzbuzz")40 results = self.vocab.searchForTerms("fizzbuzz")
41 expected = [41 expected = [
42 u"~scotty/sprocket/+git/fizzbuzz", u"~scotty/widget/+git/fizzbuzz"]42 "~scotty/sprocket/+git/fizzbuzz", "~scotty/widget/+git/fizzbuzz"]
43 repository_names = sorted(repository.token for repository in results)43 repository_names = sorted(repository.token for repository in results)
44 self.assertEqual(expected, repository_names)44 self.assertEqual(expected, repository_names)
4545
@@ -67,7 +67,7 @@ class TestRestrictedGitRepositoryVocabularyOnProduct(TestCaseWithFactory):
67 layer = DatabaseFunctionalLayer67 layer = DatabaseFunctionalLayer
6868
69 def setUp(self):69 def setUp(self):
70 super(TestRestrictedGitRepositoryVocabularyOnProduct, self).setUp()70 super().setUp()
71 self._createRepositories()71 self._createRepositories()
72 self.vocab = GitRepositoryRestrictedOnProductVocabulary(72 self.vocab = GitRepositoryRestrictedOnProductVocabulary(
73 context=self._getVocabRestriction())73 context=self._getVocabRestriction())
@@ -79,11 +79,11 @@ class TestRestrictedGitRepositoryVocabularyOnProduct(TestCaseWithFactory):
79 def _createRepositories(self):79 def _createRepositories(self):
80 test_product = self.factory.makeProduct(name='widget')80 test_product = self.factory.makeProduct(name='widget')
81 other_product = self.factory.makeProduct(name='sprocket')81 other_product = self.factory.makeProduct(name='sprocket')
82 person = self.factory.makePerson(name=u'scotty')82 person = self.factory.makePerson(name='scotty')
83 self.factory.makeGitRepository(83 self.factory.makeGitRepository(
84 owner=person, target=test_product, name=u'mountain')84 owner=person, target=test_product, name='mountain')
85 self.factory.makeGitRepository(85 self.factory.makeGitRepository(
86 owner=person, target=other_product, name=u'mountain')86 owner=person, target=other_product, name='mountain')
87 self.product = test_product87 self.product = test_product
88 self.other_product = test_product88 self.other_product = test_product
8989
@@ -93,7 +93,7 @@ class TestRestrictedGitRepositoryVocabularyOnProduct(TestCaseWithFactory):
93 The result set should not show ~scotty/sprocket/mountain.93 The result set should not show ~scotty/sprocket/mountain.
94 """94 """
95 results = self.vocab.searchForTerms('mountain')95 results = self.vocab.searchForTerms('mountain')
96 expected = [u'~scotty/widget/+git/mountain']96 expected = ['~scotty/widget/+git/mountain']
97 repo_names = sorted(repo.token for repo in results)97 repo_names = sorted(repo.token for repo in results)
98 self.assertEqual(expected, repo_names)98 self.assertEqual(expected, repo_names)
9999
@@ -102,7 +102,7 @@ class TestRestrictedGitRepositoryVocabularyOnProduct(TestCaseWithFactory):
102 # as the result.102 # as the result.
103 term = self.vocab.getTermByToken('mountain')103 term = self.vocab.getTermByToken('mountain')
104 self.assertEqual(104 self.assertEqual(
105 u'~scotty/widget/+git/mountain', term.value.unique_name)105 '~scotty/widget/+git/mountain', term.value.unique_name)
106106
107 def test_multipleQueryResult(self):107 def test_multipleQueryResult(self):
108 # If there are more than one search result, a LookupError is still108 # If there are more than one search result, a LookupError is still
diff --git a/lib/lp/code/xmlrpc/codehosting.py b/lib/lp/code/xmlrpc/codehosting.py
index c32d69f..07416b0 100644
--- a/lib/lp/code/xmlrpc/codehosting.py
+++ b/lib/lp/code/xmlrpc/codehosting.py
@@ -109,7 +109,7 @@ def run_with_login(login_id, function, *args, **kwargs):
109 # Don't pass in an actual user. Instead pass in LAUNCHPAD_SERVICES109 # Don't pass in an actual user. Instead pass in LAUNCHPAD_SERVICES
110 # and expect `function` to use `removeSecurityProxy` or similar.110 # and expect `function` to use `removeSecurityProxy` or similar.
111 return function(login_id, *args, **kwargs)111 return function(login_id, *args, **kwargs)
112 if isinstance(login_id, (six.binary_type, six.text_type)):112 if isinstance(login_id, (bytes, str)):
113 login_id = six.ensure_text(login_id)113 login_id = six.ensure_text(login_id)
114 # OpenID identifiers must contain a slash, while names must not.114 # OpenID identifiers must contain a slash, while names must not.
115 if "/" in login_id:115 if "/" in login_id:
diff --git a/lib/lp/code/xmlrpc/git.py b/lib/lp/code/xmlrpc/git.py
index 9278b1a..83383cd 100644
--- a/lib/lp/code/xmlrpc/git.py
+++ b/lib/lp/code/xmlrpc/git.py
@@ -131,7 +131,7 @@ class GitAPI(LaunchpadXMLRPCView):
131 """See `IGitAPI`."""131 """See `IGitAPI`."""
132132
133 def __init__(self, *args, **kwargs):133 def __init__(self, *args, **kwargs):
134 super(GitAPI, self).__init__(*args, **kwargs)134 super().__init__(*args, **kwargs)
135 self.repository_set = getUtility(IGitRepositorySet)135 self.repository_set = getUtility(IGitRepositorySet)
136136
137 def _verifyMacaroon(self, macaroon_raw, repository=None, user=None):137 def _verifyMacaroon(self, macaroon_raw, repository=None, user=None):
@@ -326,7 +326,7 @@ class GitAPI(LaunchpadXMLRPCView):
326 def _reportError(self, path, exception, hosting_path=None):326 def _reportError(self, path, exception, hosting_path=None):
327 properties = [327 properties = [
328 ("path", path),328 ("path", path),
329 ("error-explanation", six.text_type(exception)),329 ("error-explanation", str(exception)),
330 ]330 ]
331 if hosting_path is not None:331 if hosting_path is not None:
332 properties.append(("hosting_path", hosting_path))332 properties.append(("hosting_path", hosting_path))
@@ -360,9 +360,9 @@ class GitAPI(LaunchpadXMLRPCView):
360 raise faults.InvalidSourcePackageName(e.name)360 raise faults.InvalidSourcePackageName(e.name)
361 return self._createRepository(requester, path)361 return self._createRepository(requester, path)
362 except NameLookupFailed as e:362 except NameLookupFailed as e:
363 raise faults.NotFound(six.text_type(e))363 raise faults.NotFound(str(e))
364 except GitRepositoryCreationForbidden as e:364 except GitRepositoryCreationForbidden as e:
365 raise faults.PermissionDenied(six.text_type(e))365 raise faults.PermissionDenied(str(e))
366366
367 try:367 try:
368 try:368 try:
@@ -391,7 +391,7 @@ class GitAPI(LaunchpadXMLRPCView):
391 # private repository). Log an OOPS for investigation.391 # private repository). Log an OOPS for investigation.
392 self._reportError(path, e)392 self._reportError(path, e)
393 except (GitRepositoryCreationException, Unauthorized) as e:393 except (GitRepositoryCreationException, Unauthorized) as e:
394 raise faults.PermissionDenied(six.text_type(e))394 raise faults.PermissionDenied(str(e))
395 except GitRepositoryCreationFault as e:395 except GitRepositoryCreationFault as e:
396 # The hosting service failed. Log an OOPS for investigation.396 # The hosting service failed. Log an OOPS for investigation.
397 self._reportError(path, e, hosting_path=e.path)397 self._reportError(path, e, hosting_path=e.path)
diff --git a/lib/lp/code/xmlrpc/tests/test_branch.py b/lib/lp/code/xmlrpc/tests/test_branch.py
index 41d55d7..58d2192 100644
--- a/lib/lp/code/xmlrpc/tests/test_branch.py
+++ b/lib/lp/code/xmlrpc/tests/test_branch.py
@@ -24,7 +24,7 @@ from lp.testing.layers import DatabaseFunctionalLayer
24from lp.xmlrpc import faults24from lp.xmlrpc import faults
2525
2626
27NON_ASCII_NAME = u'nam\N{LATIN SMALL LETTER E WITH ACUTE}'27NON_ASCII_NAME = 'nam\N{LATIN SMALL LETTER E WITH ACUTE}'
2828
2929
30class TestExpandURL(TestCaseWithFactory):30class TestExpandURL(TestCaseWithFactory):
@@ -193,7 +193,7 @@ class TestExpandURL(TestCaseWithFactory):
193 # find a branch, but it still resolves rather than erroring.193 # find a branch, but it still resolves rather than erroring.
194 owner = self.factory.makePerson()194 owner = self.factory.makePerson()
195 product = self.factory.makeProduct()195 product = self.factory.makeProduct()
196 nonexistent_branch = u'~%s/%s/%s' % (196 nonexistent_branch = '~%s/%s/%s' % (
197 owner.name, product.name, NON_ASCII_NAME)197 owner.name, product.name, NON_ASCII_NAME)
198 self.assertResolves(198 self.assertResolves(
199 nonexistent_branch, urlutils.escape(nonexistent_branch))199 nonexistent_branch, urlutils.escape(nonexistent_branch))
@@ -236,7 +236,7 @@ class TestExpandURL(TestCaseWithFactory):
236 def test_resolve_branch_with_no_such_owner_non_ascii(self):236 def test_resolve_branch_with_no_such_owner_non_ascii(self):
237 # lp:~<non-ascii-string>/product/name returns NoSuchPersonWithName237 # lp:~<non-ascii-string>/product/name returns NoSuchPersonWithName
238 # with the name escaped.238 # with the name escaped.
239 nonexistent_owner_branch = u"~%s/%s/%s" % (239 nonexistent_owner_branch = "~%s/%s/%s" % (
240 NON_ASCII_NAME, self.factory.getUniqueString(),240 NON_ASCII_NAME, self.factory.getUniqueString(),
241 self.factory.getUniqueString())241 self.factory.getUniqueString())
242 self.assertFault(242 self.assertFault(
diff --git a/lib/lp/code/xmlrpc/tests/test_codehosting.py b/lib/lp/code/xmlrpc/tests/test_codehosting.py
index e72e46b..4921642 100644
--- a/lib/lp/code/xmlrpc/tests/test_codehosting.py
+++ b/lib/lp/code/xmlrpc/tests/test_codehosting.py
@@ -85,7 +85,7 @@ class TestRunWithLogin(TestCaseWithFactory):
85 layer = DatabaseFunctionalLayer85 layer = DatabaseFunctionalLayer
8686
87 def setUp(self):87 def setUp(self):
88 super(TestRunWithLogin, self).setUp()88 super().setUp()
89 self.person = self.factory.makePerson()89 self.person = self.factory.makePerson()
9090
91 def test_loginAsRequester(self):91 def test_loginAsRequester(self):
@@ -114,7 +114,7 @@ class TestRunWithLogin(TestCaseWithFactory):
114 self.person.account.openid_identifiers.one().identifier)114 self.person.account.openid_identifiers.one().identifier)
115 username = run_with_login(115 username = run_with_login(
116 # Deliberately not Unicode, since XML-RPC gives us a byte string.116 # Deliberately not Unicode, since XML-RPC gives us a byte string.
117 (u'http://testopenid.test/+id/%s' % identifier).encode("UTF-8"),117 ('http://testopenid.test/+id/%s' % identifier).encode("UTF-8"),
118 get_logged_in_username)118 get_logged_in_username)
119 login(ANONYMOUS)119 login(ANONYMOUS)
120 self.assertEqual(self.person.name, username)120 self.assertEqual(self.person.name, username)
@@ -306,7 +306,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
306306
307 def test_createBranch_no_preceding_slash(self):307 def test_createBranch_no_preceding_slash(self):
308 requester = self.factory.makePerson()308 requester = self.factory.makePerson()
309 path = escape(u'invalid')309 path = escape('invalid')
310 fault = self.codehosting_api.createBranch(requester.id, path)310 fault = self.codehosting_api.createBranch(requester.id, path)
311 login(ANONYMOUS)311 login(ANONYMOUS)
312 self.assertEqual(faults.InvalidPath(path), fault)312 self.assertEqual(faults.InvalidPath(path), fault)
@@ -390,7 +390,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
390 # Creating a branch with an invalid name fails.390 # Creating a branch with an invalid name fails.
391 owner = self.factory.makePerson()391 owner = self.factory.makePerson()
392 product = self.factory.makeProduct()392 product = self.factory.makeProduct()
393 invalid_name = u'invalid\N{LATIN SMALL LETTER E WITH ACUTE}'393 invalid_name = 'invalid\N{LATIN SMALL LETTER E WITH ACUTE}'
394 # LaunchpadValidationError unfortunately assumes its output is394 # LaunchpadValidationError unfortunately assumes its output is
395 # always HTML, so it ends up double-escaped in XML-RPC faults.395 # always HTML, so it ends up double-escaped in XML-RPC faults.
396 message = html_escape(396 message = html_escape(
@@ -526,8 +526,8 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
526 owner = self.factory.makePerson()526 owner = self.factory.makePerson()
527 product = self.factory.makeProduct()527 product = self.factory.makeProduct()
528 branch_name = self.factory.getUniqueString('branch-name')528 branch_name = self.factory.getUniqueString('branch-name')
529 unique_name = u'~%s/%s/%s' % (owner.name, product.name, branch_name)529 unique_name = '~%s/%s/%s' % (owner.name, product.name, branch_name)
530 path = u'/%s/%s' % (BRANCH_ALIAS_PREFIX, unique_name)530 path = '/%s/%s' % (BRANCH_ALIAS_PREFIX, unique_name)
531 branch_id = self.codehosting_api.createBranch(owner.id, escape(path))531 branch_id = self.codehosting_api.createBranch(owner.id, escape(path))
532 login(ANONYMOUS)532 login(ANONYMOUS)
533 branch = self.branch_lookup.get(branch_id)533 branch = self.branch_lookup.get(branch_id)
@@ -539,8 +539,8 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
539 owner = self.factory.makePerson()539 owner = self.factory.makePerson()
540 product = self.factory.makeProduct()540 product = self.factory.makeProduct()
541 branch_name = self.factory.getUniqueString('branch-name')541 branch_name = self.factory.getUniqueString('branch-name')
542 unique_name = u'~%s/%s/%s' % (owner.name, product.name, branch_name)542 unique_name = '~%s/%s/%s' % (owner.name, product.name, branch_name)
543 path = escape(u'/%s/%s' % (BRANCH_ALIAS_PREFIX, unique_name))543 path = escape('/%s/%s' % (BRANCH_ALIAS_PREFIX, unique_name))
544 branch_id = self.codehosting_api.createBranch(owner.id, path)544 branch_id = self.codehosting_api.createBranch(owner.id, path)
545 login(ANONYMOUS)545 login(ANONYMOUS)
546 translation = self.codehosting_api.translatePath(owner.id, path)546 translation = self.codehosting_api.translatePath(owner.id, path)
@@ -555,7 +555,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
555 # it.555 # it.
556 owner = self.factory.makePerson()556 owner = self.factory.makePerson()
557 product = self.factory.makeProduct(owner=owner)557 product = self.factory.makeProduct(owner=owner)
558 path = u'/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name)558 path = '/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name)
559 branch_id = self.codehosting_api.createBranch(owner.id, escape(path))559 branch_id = self.codehosting_api.createBranch(owner.id, escape(path))
560 login(ANONYMOUS)560 login(ANONYMOUS)
561 branch = self.branch_lookup.get(branch_id)561 branch = self.branch_lookup.get(branch_id)
@@ -569,7 +569,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
569 # immediately traversable using translatePath.569 # immediately traversable using translatePath.
570 product = self.factory.makeProduct()570 product = self.factory.makeProduct()
571 owner = product.owner571 owner = product.owner
572 path = escape(u'/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name))572 path = escape('/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name))
573 branch_id = self.codehosting_api.createBranch(owner.id, path)573 branch_id = self.codehosting_api.createBranch(owner.id, path)
574 login(ANONYMOUS)574 login(ANONYMOUS)
575 translation = self.codehosting_api.translatePath(owner.id, path)575 translation = self.codehosting_api.translatePath(owner.id, path)
@@ -583,7 +583,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
583 # the new branch to the alias, then can't create the branch.583 # the new branch to the alias, then can't create the branch.
584 owner = self.factory.makePerson(name='eric')584 owner = self.factory.makePerson(name='eric')
585 product = self.factory.makeProduct('wibble')585 product = self.factory.makeProduct('wibble')
586 path = u'/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name)586 path = '/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name)
587 fault = self.codehosting_api.createBranch(owner.id, escape(path))587 fault = self.codehosting_api.createBranch(owner.id, escape(path))
588 message = "Cannot create linked branch at 'wibble'."588 message = "Cannot create linked branch at 'wibble'."
589 self.assertEqual(faults.PermissionDenied(message), fault)589 self.assertEqual(faults.PermissionDenied(message), fault)
@@ -595,7 +595,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
595 def test_createBranch_using_branch_alias_product_not_exist(self):595 def test_createBranch_using_branch_alias_product_not_exist(self):
596 # If the product doesn't exist, we don't (yet) create one.596 # If the product doesn't exist, we don't (yet) create one.
597 owner = self.factory.makePerson()597 owner = self.factory.makePerson()
598 path = u'/%s/foible' % (BRANCH_ALIAS_PREFIX,)598 path = '/%s/foible' % (BRANCH_ALIAS_PREFIX,)
599 fault = self.codehosting_api.createBranch(owner.id, escape(path))599 fault = self.codehosting_api.createBranch(owner.id, escape(path))
600 message = "Project 'foible' does not exist."600 message = "Project 'foible' does not exist."
601 self.assertEqual(faults.NotFound(message), fault)601 self.assertEqual(faults.NotFound(message), fault)
@@ -607,7 +607,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
607 owner = self.factory.makePerson()607 owner = self.factory.makePerson()
608 product = self.factory.makeProduct(owner=owner)608 product = self.factory.makeProduct(owner=owner)
609 series = self.factory.makeProductSeries(product=product)609 series = self.factory.makeProductSeries(product=product)
610 path = u'/%s/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name, series.name)610 path = '/%s/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name, series.name)
611 branch_id = self.codehosting_api.createBranch(owner.id, escape(path))611 branch_id = self.codehosting_api.createBranch(owner.id, escape(path))
612 login(ANONYMOUS)612 login(ANONYMOUS)
613 branch = self.branch_lookup.get(branch_id)613 branch = self.branch_lookup.get(branch_id)
@@ -622,7 +622,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
622 owner = self.factory.makePerson()622 owner = self.factory.makePerson()
623 product = self.factory.makeProduct(name='wibble')623 product = self.factory.makeProduct(name='wibble')
624 self.factory.makeProductSeries(product=product, name='nip')624 self.factory.makeProductSeries(product=product, name='nip')
625 path = u'/%s/wibble/nip' % (BRANCH_ALIAS_PREFIX,)625 path = '/%s/wibble/nip' % (BRANCH_ALIAS_PREFIX,)
626 fault = self.codehosting_api.createBranch(owner.id, escape(path))626 fault = self.codehosting_api.createBranch(owner.id, escape(path))
627 message = "Cannot create linked branch at 'wibble/nip'."627 message = "Cannot create linked branch at 'wibble/nip'."
628 self.assertEqual(faults.PermissionDenied(message), fault)628 self.assertEqual(faults.PermissionDenied(message), fault)
@@ -631,7 +631,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
631 # If the product series doesn't exist, we don't (yet) create it.631 # If the product series doesn't exist, we don't (yet) create it.
632 owner = self.factory.makePerson()632 owner = self.factory.makePerson()
633 self.factory.makeProduct(name='wibble')633 self.factory.makeProduct(name='wibble')
634 path = u'/%s/wibble/nip' % (BRANCH_ALIAS_PREFIX,)634 path = '/%s/wibble/nip' % (BRANCH_ALIAS_PREFIX,)
635 fault = self.codehosting_api.createBranch(owner.id, escape(path))635 fault = self.codehosting_api.createBranch(owner.id, escape(path))
636 message = "No such product series: 'nip'."636 message = "No such product series: 'nip'."
637 self.assertEqual(faults.NotFound(message), fault)637 self.assertEqual(faults.NotFound(message), fault)
@@ -777,19 +777,19 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
777 # this happens, it returns a Fault saying so, including the path it777 # this happens, it returns a Fault saying so, including the path it
778 # couldn't translate.778 # couldn't translate.
779 requester = self.factory.makePerson()779 requester = self.factory.makePerson()
780 path = escape(u'/untranslatable')780 path = escape('/untranslatable')
781 self.assertNotFound(requester, path)781 self.assertNotFound(requester, path)
782782
783 def test_translatePath_no_preceding_slash(self):783 def test_translatePath_no_preceding_slash(self):
784 requester = self.factory.makePerson()784 requester = self.factory.makePerson()
785 path = escape(u'invalid')785 path = escape('invalid')
786 fault = self.codehosting_api.translatePath(requester.id, path)786 fault = self.codehosting_api.translatePath(requester.id, path)
787 self.assertEqual(faults.InvalidPath(path), fault)787 self.assertEqual(faults.InvalidPath(path), fault)
788788
789 def test_translatePath_branch(self):789 def test_translatePath_branch(self):
790 requester = self.factory.makePerson()790 requester = self.factory.makePerson()
791 branch = self.factory.makeAnyBranch()791 branch = self.factory.makeAnyBranch()
792 path = escape(u'/%s' % branch.unique_name)792 path = escape('/%s' % branch.unique_name)
793 translation = self.codehosting_api.translatePath(requester.id, path)793 translation = self.codehosting_api.translatePath(requester.id, path)
794 login(ANONYMOUS)794 login(ANONYMOUS)
795 self.assertEqual(795 self.assertEqual(
@@ -800,7 +800,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
800 def test_translatePath_branch_with_trailing_slash(self):800 def test_translatePath_branch_with_trailing_slash(self):
801 requester = self.factory.makePerson()801 requester = self.factory.makePerson()
802 branch = self.factory.makeAnyBranch()802 branch = self.factory.makeAnyBranch()
803 path = escape(u'/%s/' % branch.unique_name)803 path = escape('/%s/' % branch.unique_name)
804 translation = self.codehosting_api.translatePath(requester.id, path)804 translation = self.codehosting_api.translatePath(requester.id, path)
805 login(ANONYMOUS)805 login(ANONYMOUS)
806 self.assertEqual(806 self.assertEqual(
@@ -811,7 +811,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
811 def test_translatePath_path_in_branch(self):811 def test_translatePath_path_in_branch(self):
812 requester = self.factory.makePerson()812 requester = self.factory.makePerson()
813 branch = self.factory.makeAnyBranch()813 branch = self.factory.makeAnyBranch()
814 path = escape(u'/%s/child' % branch.unique_name)814 path = escape('/%s/child' % branch.unique_name)
815 translation = self.codehosting_api.translatePath(requester.id, path)815 translation = self.codehosting_api.translatePath(requester.id, path)
816 login(ANONYMOUS)816 login(ANONYMOUS)
817 self.assertEqual(817 self.assertEqual(
@@ -822,7 +822,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
822 def test_translatePath_nested_path_in_branch(self):822 def test_translatePath_nested_path_in_branch(self):
823 requester = self.factory.makePerson()823 requester = self.factory.makePerson()
824 branch = self.factory.makeAnyBranch()824 branch = self.factory.makeAnyBranch()
825 path = escape(u'/%s/a/b' % branch.unique_name)825 path = escape('/%s/a/b' % branch.unique_name)
826 translation = self.codehosting_api.translatePath(requester.id, path)826 translation = self.codehosting_api.translatePath(requester.id, path)
827 login(ANONYMOUS)827 login(ANONYMOUS)
828 self.assertEqual(828 self.assertEqual(
@@ -833,11 +833,11 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
833 def test_translatePath_preserves_escaping(self):833 def test_translatePath_preserves_escaping(self):
834 requester = self.factory.makePerson()834 requester = self.factory.makePerson()
835 branch = self.factory.makeAnyBranch()835 branch = self.factory.makeAnyBranch()
836 child_path = u'a@b'836 child_path = 'a@b'
837 # This test is only meaningful if the path isn't the same when837 # This test is only meaningful if the path isn't the same when
838 # escaped.838 # escaped.
839 self.assertNotEqual(escape(child_path), child_path.encode('utf-8'))839 self.assertNotEqual(escape(child_path), child_path.encode('utf-8'))
840 path = escape(u'/%s/%s' % (branch.unique_name, child_path))840 path = escape('/%s/%s' % (branch.unique_name, child_path))
841 translation = self.codehosting_api.translatePath(requester.id, path)841 translation = self.codehosting_api.translatePath(requester.id, path)
842 login(ANONYMOUS)842 login(ANONYMOUS)
843 self.assertEqual(843 self.assertEqual(
@@ -886,7 +886,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
886 def test_translatePath_no_such_branch_non_ascii(self):886 def test_translatePath_no_such_branch_non_ascii(self):
887 requester = self.factory.makePerson()887 requester = self.factory.makePerson()
888 product = self.factory.makeProduct()888 product = self.factory.makeProduct()
889 path = u'/~%s/%s/non-asci\N{LATIN SMALL LETTER I WITH DIAERESIS}' % (889 path = '/~%s/%s/non-asci\N{LATIN SMALL LETTER I WITH DIAERESIS}' % (
890 requester.name, product.name)890 requester.name, product.name)
891 self.assertNotFound(requester, escape(path))891 self.assertNotFound(requester, escape(path))
892892
@@ -896,7 +896,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
896 self.factory.makeAnyBranch(896 self.factory.makeAnyBranch(
897 branch_type=BranchType.HOSTED, owner=requester,897 branch_type=BranchType.HOSTED, owner=requester,
898 information_type=InformationType.USERDATA))898 information_type=InformationType.USERDATA))
899 path = escape(u'/%s' % branch.unique_name)899 path = escape('/%s' % branch.unique_name)
900 translation = self.codehosting_api.translatePath(requester.id, path)900 translation = self.codehosting_api.translatePath(requester.id, path)
901 login(ANONYMOUS)901 login(ANONYMOUS)
902 self.assertEqual(902 self.assertEqual(
@@ -908,19 +908,19 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
908 requester = self.factory.makePerson()908 requester = self.factory.makePerson()
909 branch = removeSecurityProxy(self.factory.makeAnyBranch(909 branch = removeSecurityProxy(self.factory.makeAnyBranch(
910 information_type=InformationType.USERDATA))910 information_type=InformationType.USERDATA))
911 path = escape(u'/%s' % branch.unique_name)911 path = escape('/%s' % branch.unique_name)
912 self.assertPermissionDenied(requester, path)912 self.assertPermissionDenied(requester, path)
913913
914 def test_translatePath_remote_branch(self):914 def test_translatePath_remote_branch(self):
915 requester = self.factory.makePerson()915 requester = self.factory.makePerson()
916 branch = self.factory.makeAnyBranch(branch_type=BranchType.REMOTE)916 branch = self.factory.makeAnyBranch(branch_type=BranchType.REMOTE)
917 path = escape(u'/%s' % branch.unique_name)917 path = escape('/%s' % branch.unique_name)
918 self.assertNotFound(requester, path)918 self.assertNotFound(requester, path)
919919
920 def test_translatePath_launchpad_services_private(self):920 def test_translatePath_launchpad_services_private(self):
921 branch = removeSecurityProxy(self.factory.makeAnyBranch(921 branch = removeSecurityProxy(self.factory.makeAnyBranch(
922 information_type=InformationType.USERDATA))922 information_type=InformationType.USERDATA))
923 path = escape(u'/%s' % branch.unique_name)923 path = escape('/%s' % branch.unique_name)
924 translation = self.codehosting_api.translatePath(924 translation = self.codehosting_api.translatePath(
925 LAUNCHPAD_SERVICES, path)925 LAUNCHPAD_SERVICES, path)
926 login(ANONYMOUS)926 login(ANONYMOUS)
@@ -932,12 +932,12 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
932 def test_translatePath_anonymous_cant_see_private_branch(self):932 def test_translatePath_anonymous_cant_see_private_branch(self):
933 branch = removeSecurityProxy(self.factory.makeAnyBranch(933 branch = removeSecurityProxy(self.factory.makeAnyBranch(
934 information_type=InformationType.USERDATA))934 information_type=InformationType.USERDATA))
935 path = escape(u'/%s' % branch.unique_name)935 path = escape('/%s' % branch.unique_name)
936 self.assertPermissionDenied(LAUNCHPAD_ANONYMOUS, path)936 self.assertPermissionDenied(LAUNCHPAD_ANONYMOUS, path)
937937
938 def test_translatePath_anonymous_public_branch(self):938 def test_translatePath_anonymous_public_branch(self):
939 branch = self.factory.makeAnyBranch()939 branch = self.factory.makeAnyBranch()
940 path = escape(u'/%s' % branch.unique_name)940 path = escape('/%s' % branch.unique_name)
941 translation = self.codehosting_api.translatePath(941 translation = self.codehosting_api.translatePath(
942 LAUNCHPAD_ANONYMOUS, path)942 LAUNCHPAD_ANONYMOUS, path)
943 self.assertEqual(943 self.assertEqual(
@@ -949,7 +949,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
949 requester = self.factory.makePerson()949 requester = self.factory.makePerson()
950 branch = self.factory.makeAnyBranch(950 branch = self.factory.makeAnyBranch(
951 branch_type=BranchType.HOSTED, owner=requester)951 branch_type=BranchType.HOSTED, owner=requester)
952 path = escape(u'/%s' % branch.unique_name)952 path = escape('/%s' % branch.unique_name)
953 translation = self.codehosting_api.translatePath(requester.id, path)953 translation = self.codehosting_api.translatePath(requester.id, path)
954 login(ANONYMOUS)954 login(ANONYMOUS)
955 self.assertEqual(955 self.assertEqual(
@@ -962,7 +962,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
962 team = self.factory.makeTeam(requester)962 team = self.factory.makeTeam(requester)
963 branch = self.factory.makeAnyBranch(963 branch = self.factory.makeAnyBranch(
964 branch_type=BranchType.HOSTED, owner=team)964 branch_type=BranchType.HOSTED, owner=team)
965 path = escape(u'/%s' % branch.unique_name)965 path = escape('/%s' % branch.unique_name)
966 translation = self.codehosting_api.translatePath(requester.id, path)966 translation = self.codehosting_api.translatePath(requester.id, path)
967 login(ANONYMOUS)967 login(ANONYMOUS)
968 self.assertEqual(968 self.assertEqual(
@@ -975,7 +975,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
975 team = self.factory.makeTeam(self.factory.makePerson())975 team = self.factory.makeTeam(self.factory.makePerson())
976 branch = self.factory.makeAnyBranch(976 branch = self.factory.makeAnyBranch(
977 branch_type=BranchType.HOSTED, owner=team)977 branch_type=BranchType.HOSTED, owner=team)
978 path = escape(u'/%s' % branch.unique_name)978 path = escape('/%s' % branch.unique_name)
979 translation = self.codehosting_api.translatePath(requester.id, path)979 translation = self.codehosting_api.translatePath(requester.id, path)
980 login(ANONYMOUS)980 login(ANONYMOUS)
981 self.assertEqual(981 self.assertEqual(
@@ -987,7 +987,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
987 requester = self.factory.makePerson()987 requester = self.factory.makePerson()
988 branch = self.factory.makeAnyBranch(988 branch = self.factory.makeAnyBranch(
989 branch_type=BranchType.MIRRORED, owner=requester)989 branch_type=BranchType.MIRRORED, owner=requester)
990 path = escape(u'/%s' % branch.unique_name)990 path = escape('/%s' % branch.unique_name)
991 translation = self.codehosting_api.translatePath(requester.id, path)991 translation = self.codehosting_api.translatePath(requester.id, path)
992 login(ANONYMOUS)992 login(ANONYMOUS)
993 self.assertEqual(993 self.assertEqual(
@@ -999,7 +999,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
999 requester = self.factory.makePerson()999 requester = self.factory.makePerson()
1000 branch = self.factory.makeAnyBranch(1000 branch = self.factory.makeAnyBranch(
1001 branch_type=BranchType.IMPORTED, owner=requester)1001 branch_type=BranchType.IMPORTED, owner=requester)
1002 path = escape(u'/%s' % branch.unique_name)1002 path = escape('/%s' % branch.unique_name)
1003 translation = self.codehosting_api.translatePath(requester.id, path)1003 translation = self.codehosting_api.translatePath(requester.id, path)
1004 login(ANONYMOUS)1004 login(ANONYMOUS)
1005 self.assertEqual(1005 self.assertEqual(
@@ -1015,7 +1015,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
1015 removeSecurityProxy(branch.product.development_focus).branch = branch1015 removeSecurityProxy(branch.product.development_focus).branch = branch
1016 short_name = ICanHasLinkedBranch(branch.product).bzr_path1016 short_name = ICanHasLinkedBranch(branch.product).bzr_path
1017 path_in_branch = '.bzr/branch-format'1017 path_in_branch = '.bzr/branch-format'
1018 path = escape(u'/%s' % os.path.join(1018 path = escape('/%s' % os.path.join(
1019 BRANCH_ALIAS_PREFIX, short_name, path_in_branch))1019 BRANCH_ALIAS_PREFIX, short_name, path_in_branch))
1020 translation = self.codehosting_api.translatePath(requester.id, path)1020 translation = self.codehosting_api.translatePath(requester.id, path)
1021 login(ANONYMOUS)1021 login(ANONYMOUS)
@@ -1030,7 +1030,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
1030 requester = self.factory.makePerson()1030 requester = self.factory.makePerson()
1031 branch = self.factory.makeBranch()1031 branch = self.factory.makeBranch()
1032 path_in_branch = '.bzr/branch-format'1032 path_in_branch = '.bzr/branch-format'
1033 path = escape(u'/%s' % os.path.join(1033 path = escape('/%s' % os.path.join(
1034 BRANCH_ALIAS_PREFIX, branch.unique_name, path_in_branch))1034 BRANCH_ALIAS_PREFIX, branch.unique_name, path_in_branch))
1035 translation = self.codehosting_api.translatePath(requester.id, path)1035 translation = self.codehosting_api.translatePath(requester.id, path)
1036 login(ANONYMOUS)1036 login(ANONYMOUS)
@@ -1147,7 +1147,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
1147 # Make sure the trailing path is returned.1147 # Make sure the trailing path is returned.
1148 requester = self.factory.makePerson()1148 requester = self.factory.makePerson()
1149 branch = removeSecurityProxy(self.factory.makeAnyBranch())1149 branch = removeSecurityProxy(self.factory.makeAnyBranch())
1150 path = escape(u'%s/foo/bar' % branch_id_alias(branch))1150 path = escape('%s/foo/bar' % branch_id_alias(branch))
1151 translation = self.codehosting_api.translatePath(requester.id, path)1151 translation = self.codehosting_api.translatePath(requester.id, path)
1152 expected = (1152 expected = (
1153 BRANCH_TRANSPORT,1153 BRANCH_TRANSPORT,
@@ -1206,7 +1206,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
1206 def test_translatePath_control_directory(self):1206 def test_translatePath_control_directory(self):
1207 requester = self.factory.makePerson()1207 requester = self.factory.makePerson()
1208 product, branch = self._makeProductWithDevFocus()1208 product, branch = self._makeProductWithDevFocus()
1209 path = escape(u'/~%s/%s/.bzr' % (requester.name, product.name))1209 path = escape('/~%s/%s/.bzr' % (requester.name, product.name))
1210 translation = self.codehosting_api.translatePath(requester.id, path)1210 translation = self.codehosting_api.translatePath(requester.id, path)
1211 login(ANONYMOUS)1211 login(ANONYMOUS)
1212 self.assertTranslationIsControlDirectory(1212 self.assertTranslationIsControlDirectory(
@@ -1219,20 +1219,20 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
1219 # don't even bother translating control directory paths.1219 # don't even bother translating control directory paths.
1220 requester = self.factory.makePerson()1220 requester = self.factory.makePerson()
1221 product = self.factory.makeProduct()1221 product = self.factory.makeProduct()
1222 path = escape(u'/~%s/%s/.bzr/' % (requester.name, product.name))1222 path = escape('/~%s/%s/.bzr/' % (requester.name, product.name))
1223 self.assertNotFound(requester, path)1223 self.assertNotFound(requester, path)
12241224
1225 def test_translatePath_control_directory_invisble_branch(self):1225 def test_translatePath_control_directory_invisble_branch(self):
1226 requester = self.factory.makePerson()1226 requester = self.factory.makePerson()
1227 product, branch = self._makeProductWithDevFocus(private=True)1227 product, branch = self._makeProductWithDevFocus(private=True)
1228 path = escape(u'/~%s/%s/.bzr/' % (requester.name, product.name))1228 path = escape('/~%s/%s/.bzr/' % (requester.name, product.name))
1229 self.assertNotFound(requester, path)1229 self.assertNotFound(requester, path)
12301230
1231 def test_translatePath_control_directory_private_branch(self):1231 def test_translatePath_control_directory_private_branch(self):
1232 product, branch = self._makeProductWithDevFocus(private=True)1232 product, branch = self._makeProductWithDevFocus(private=True)
1233 branch = removeSecurityProxy(branch)1233 branch = removeSecurityProxy(branch)
1234 requester = branch.owner1234 requester = branch.owner
1235 path = escape(u'/~%s/%s/.bzr/' % (requester.name, product.name))1235 path = escape('/~%s/%s/.bzr/' % (requester.name, product.name))
1236 translation = self.codehosting_api.translatePath(requester.id, path)1236 translation = self.codehosting_api.translatePath(requester.id, path)
1237 login(ANONYMOUS)1237 login(ANONYMOUS)
1238 self.assertTranslationIsControlDirectory(1238 self.assertTranslationIsControlDirectory(
@@ -1244,7 +1244,7 @@ class CodehostingTest(WithScenarios, TestCaseWithFactory):
1244 requester = self.factory.makePerson()1244 requester = self.factory.makePerson()
1245 product, branch = self._makeProductWithDevFocus()1245 product, branch = self._makeProductWithDevFocus()
1246 owner = self.factory.makePerson()1246 owner = self.factory.makePerson()
1247 path = escape(u'/~%s/%s/.bzr' % (owner.name, product.name))1247 path = escape('/~%s/%s/.bzr' % (owner.name, product.name))
1248 translation = self.codehosting_api.translatePath(requester.id, path)1248 translation = self.codehosting_api.translatePath(requester.id, path)
1249 login(ANONYMOUS)1249 login(ANONYMOUS)
1250 self.assertTranslationIsControlDirectory(1250 self.assertTranslationIsControlDirectory(
@@ -1291,7 +1291,7 @@ class AcquireBranchToPullTestsViaEndpoint(WithScenarios, TestCaseWithFactory,
1291 ]1291 ]
12921292
1293 def setUp(self):1293 def setUp(self):
1294 super(AcquireBranchToPullTestsViaEndpoint, self).setUp()1294 super().setUp()
1295 frontend = self.frontend()1295 frontend = self.frontend()
1296 self.codehosting_api = frontend.getCodehostingEndpoint()1296 self.codehosting_api = frontend.getCodehostingEndpoint()
1297 self.factory = frontend.getLaunchpadObjectFactory()1297 self.factory = frontend.getLaunchpadObjectFactory()
diff --git a/lib/lp/code/xmlrpc/tests/test_git.py b/lib/lp/code/xmlrpc/tests/test_git.py
index 27c78c4..9dd57c1 100644
--- a/lib/lp/code/xmlrpc/tests/test_git.py
+++ b/lib/lp/code/xmlrpc/tests/test_git.py
@@ -138,7 +138,7 @@ class MatchesFault(MatchesStructure):
138138
139 def __init__(self, expected_fault):139 def __init__(self, expected_fault):
140 fault_matchers = {}140 fault_matchers = {}
141 if (isinstance(expected_fault, six.class_types) and141 if (isinstance(expected_fault, type) and
142 issubclass(expected_fault, faults.LaunchpadFault)):142 issubclass(expected_fault, faults.LaunchpadFault)):
143 fault_matchers["faultCode"] = Equals(expected_fault.error_code)143 fault_matchers["faultCode"] = Equals(expected_fault.error_code)
144 else:144 else:
@@ -146,17 +146,17 @@ class MatchesFault(MatchesStructure):
146 fault_string = expected_fault.faultString146 fault_string = expected_fault.faultString
147 # XXX cjwatson 2019-09-27: InvalidBranchName.faultString is147 # XXX cjwatson 2019-09-27: InvalidBranchName.faultString is
148 # bytes, so we need this to handle that case. Should it be?148 # bytes, so we need this to handle that case. Should it be?
149 if not isinstance(fault_string, six.text_type):149 if not isinstance(fault_string, str):
150 fault_string = fault_string.decode("UTF-8")150 fault_string = fault_string.decode("UTF-8")
151 fault_matchers["faultString"] = Equals(fault_string)151 fault_matchers["faultString"] = Equals(fault_string)
152 super(MatchesFault, self).__init__(**fault_matchers)152 super().__init__(**fault_matchers)
153153
154154
155class TestGitAPIMixin:155class TestGitAPIMixin:
156 """Helper methods for `IGitAPI` tests, and security-relevant tests."""156 """Helper methods for `IGitAPI` tests, and security-relevant tests."""
157157
158 def setUp(self):158 def setUp(self):
159 super(TestGitAPIMixin, self).setUp()159 super().setUp()
160 self.git_api = xmlrpc.client.ServerProxy(160 self.git_api = xmlrpc.client.ServerProxy(
161 "http://xmlrpc-private.launchpad.test:8087/git",161 "http://xmlrpc-private.launchpad.test:8087/git",
162 transport=XMLRPCTestTransport())162 transport=XMLRPCTestTransport())
@@ -495,7 +495,7 @@ class TestGitAPIMixin:
495 repository = removeSecurityProxy(495 repository = removeSecurityProxy(
496 self.factory.makeGitRepository(496 self.factory.makeGitRepository(
497 owner=requester, information_type=InformationType.USERDATA))497 owner=requester, information_type=InformationType.USERDATA))
498 path = u"/%s" % repository.unique_name498 path = "/%s" % repository.unique_name
499 self.assertTranslates(requester, path, repository, True, private=True)499 self.assertTranslates(requester, path, repository, True, private=True)
500500
501 def test_translatePath_cannot_see_private_repository(self):501 def test_translatePath_cannot_see_private_repository(self):
@@ -503,14 +503,14 @@ class TestGitAPIMixin:
503 repository = removeSecurityProxy(503 repository = removeSecurityProxy(
504 self.factory.makeGitRepository(504 self.factory.makeGitRepository(
505 information_type=InformationType.USERDATA))505 information_type=InformationType.USERDATA))
506 path = u"/%s" % repository.unique_name506 path = "/%s" % repository.unique_name
507 self.assertGitRepositoryNotFound(requester, path)507 self.assertGitRepositoryNotFound(requester, path)
508508
509 def test_translatePath_anonymous_cannot_see_private_repository(self):509 def test_translatePath_anonymous_cannot_see_private_repository(self):
510 repository = removeSecurityProxy(510 repository = removeSecurityProxy(
511 self.factory.makeGitRepository(511 self.factory.makeGitRepository(
512 information_type=InformationType.USERDATA))512 information_type=InformationType.USERDATA))
513 path = u"/%s" % repository.unique_name513 path = "/%s" % repository.unique_name
514 self.assertGitRepositoryNotFound(None, path, can_authenticate=False)514 self.assertGitRepositoryNotFound(None, path, can_authenticate=False)
515 self.assertUnauthorized(None, path, can_authenticate=True)515 self.assertUnauthorized(None, path, can_authenticate=True)
516516
@@ -518,7 +518,7 @@ class TestGitAPIMixin:
518 requester = self.factory.makePerson()518 requester = self.factory.makePerson()
519 team = self.factory.makeTeam(self.factory.makePerson())519 team = self.factory.makeTeam(self.factory.makePerson())
520 repository = self.factory.makeGitRepository(owner=team)520 repository = self.factory.makeGitRepository(owner=team)
521 path = u"/%s" % repository.unique_name521 path = "/%s" % repository.unique_name
522 self.assertTranslates(requester, path, repository, False)522 self.assertTranslates(requester, path, repository, False)
523 self.assertPermissionDenied(requester, path, permission="write")523 self.assertPermissionDenied(requester, path, permission="write")
524524
@@ -526,7 +526,7 @@ class TestGitAPIMixin:
526 requester = self.factory.makePerson()526 requester = self.factory.makePerson()
527 repository = self.factory.makeGitRepository(527 repository = self.factory.makeGitRepository(
528 owner=requester, repository_type=GitRepositoryType.IMPORTED)528 owner=requester, repository_type=GitRepositoryType.IMPORTED)
529 path = u"/%s" % repository.unique_name529 path = "/%s" % repository.unique_name
530 self.assertTranslates(requester, path, repository, False)530 self.assertTranslates(requester, path, repository, False)
531 self.assertPermissionDenied(requester, path, permission="write")531 self.assertPermissionDenied(requester, path, permission="write")
532532
@@ -538,7 +538,7 @@ class TestGitAPIMixin:
538 message = "%s is not a member of %s" % (538 message = "%s is not a member of %s" % (
539 requester.displayname, team.displayname)539 requester.displayname, team.displayname)
540 self.assertPermissionDenied(540 self.assertPermissionDenied(
541 requester, u"/~%s/+git/random" % team.name, message=message,541 requester, "/~%s/+git/random" % team.name, message=message,
542 permission="write")542 permission="write")
543543
544 def test_translatePath_create_other_user(self):544 def test_translatePath_create_other_user(self):
@@ -547,7 +547,7 @@ class TestGitAPIMixin:
547 other_person = self.factory.makePerson()547 other_person = self.factory.makePerson()
548 project = self.factory.makeProduct()548 project = self.factory.makeProduct()
549 name = self.factory.getUniqueString()549 name = self.factory.getUniqueString()
550 path = u"/~%s/%s/+git/%s" % (other_person.name, project.name, name)550 path = "/~%s/%s/+git/%s" % (other_person.name, project.name, name)
551 message = "%s cannot create Git repositories owned by %s" % (551 message = "%s cannot create Git repositories owned by %s" % (
552 requester.displayname, other_person.displayname)552 requester.displayname, other_person.displayname)
553 self.assertPermissionDenied(553 self.assertPermissionDenied(
@@ -558,7 +558,7 @@ class TestGitAPIMixin:
558 # repository and immediately set it as the default for that project.558 # repository and immediately set it as the default for that project.
559 requester = self.factory.makePerson()559 requester = self.factory.makePerson()
560 project = self.factory.makeProduct()560 project = self.factory.makeProduct()
561 path = u"/%s" % project.name561 path = "/%s" % project.name
562 message = "%s cannot create Git repositories owned by %s" % (562 message = "%s cannot create Git repositories owned by %s" % (
563 requester.displayname, project.owner.displayname)563 requester.displayname, project.owner.displayname)
564 initial_count = getUtility(IAllGitRepositories).count()564 initial_count = getUtility(IAllGitRepositories).count()
@@ -577,7 +577,7 @@ class TestGitAPIMixin:
577 distribution = self.factory.makeDistribution(577 distribution = self.factory.makeDistribution(
578 oci_project_admin=self.factory.makeTeam())578 oci_project_admin=self.factory.makeTeam())
579 oci_project = self.factory.makeOCIProject(pillar=distribution)579 oci_project = self.factory.makeOCIProject(pillar=distribution)
580 path = u"/%s/+oci/%s" % (oci_project.pillar.name, oci_project.name)580 path = "/%s/+oci/%s" % (oci_project.pillar.name, oci_project.name)
581 message = "%s is not a member of %s" % (581 message = "%s is not a member of %s" % (
582 requester.displayname,582 requester.displayname,
583 oci_project.pillar.oci_project_admin.displayname)583 oci_project.pillar.oci_project_admin.displayname)
@@ -594,11 +594,11 @@ class TestGitAPIMixin:
594 other_person = self.factory.makePerson()594 other_person = self.factory.makePerson()
595 repository = self.factory.makeGitRepository(owner=requester)595 repository = self.factory.makeGitRepository(owner=requester)
596 rule = self.factory.makeGitRule(596 rule = self.factory.makeGitRule(
597 repository, ref_pattern=u'refs/heads/stable/next')597 repository, ref_pattern='refs/heads/stable/next')
598 self.factory.makeGitRuleGrant(598 self.factory.makeGitRuleGrant(
599 rule=rule, grantee=other_person,599 rule=rule, grantee=other_person,
600 can_force_push=True)600 can_force_push=True)
601 path = u"/%s" % repository.unique_name601 path = "/%s" % repository.unique_name
602 self.assertTranslates(602 self.assertTranslates(
603 other_person, path, repository, True, private=False)603 other_person, path, repository, True, private=False)
604604
@@ -608,11 +608,11 @@ class TestGitAPIMixin:
608 other_person = self.factory.makePerson()608 other_person = self.factory.makePerson()
609 repository = self.factory.makeGitRepository(owner=requester)609 repository = self.factory.makeGitRepository(owner=requester)
610 rule = self.factory.makeGitRule(610 rule = self.factory.makeGitRule(
611 repository, ref_pattern=u'refs/heads/stable/next')611 repository, ref_pattern='refs/heads/stable/next')
612 self.factory.makeGitRuleGrant(612 self.factory.makeGitRuleGrant(
613 rule=rule, grantee=grant_person,613 rule=rule, grantee=grant_person,
614 can_force_push=True)614 can_force_push=True)
615 path = u"/%s" % repository.unique_name615 path = "/%s" % repository.unique_name
616 self.assertTranslates(616 self.assertTranslates(
617 other_person, path, repository, False, private=False)617 other_person, path, repository, False, private=False)
618618
@@ -623,11 +623,11 @@ class TestGitAPIMixin:
623 self.factory.makeGitRepository(623 self.factory.makeGitRepository(
624 owner=requester, information_type=InformationType.USERDATA))624 owner=requester, information_type=InformationType.USERDATA))
625 rule = self.factory.makeGitRule(625 rule = self.factory.makeGitRule(
626 repository, ref_pattern=u'refs/heads/stable/next')626 repository, ref_pattern='refs/heads/stable/next')
627 self.factory.makeGitRuleGrant(627 self.factory.makeGitRuleGrant(
628 rule=rule, grantee=other_person,628 rule=rule, grantee=other_person,
629 can_force_push=True)629 can_force_push=True)
630 path = u"/%s" % repository.unique_name630 path = "/%s" % repository.unique_name
631 self.assertGitRepositoryNotFound(631 self.assertGitRepositoryNotFound(
632 other_person, path, can_authenticate=True)632 other_person, path, can_authenticate=True)
633633
@@ -642,34 +642,34 @@ class TestGitAPIMixin:
642 self.factory.makeGitRepository(owner=user_a))642 self.factory.makeGitRepository(owner=user_a))
643643
644 rule = self.factory.makeGitRule(644 rule = self.factory.makeGitRule(
645 repository, ref_pattern=u'refs/heads/stable/next')645 repository, ref_pattern='refs/heads/stable/next')
646 self.factory.makeGitRuleGrant(646 self.factory.makeGitRuleGrant(
647 rule=rule, grantee=GitGranteeType.REPOSITORY_OWNER,647 rule=rule, grantee=GitGranteeType.REPOSITORY_OWNER,
648 can_force_push=True)648 can_force_push=True)
649649
650 rule = self.factory.makeGitRule(650 rule = self.factory.makeGitRule(
651 repository, ref_pattern=u'refs/heads/stable/protected')651 repository, ref_pattern='refs/heads/stable/protected')
652 self.factory.makeGitRuleGrant(rule=rule, grantee=stable_team)652 self.factory.makeGitRuleGrant(rule=rule, grantee=stable_team)
653653
654 rule = self.factory.makeGitRule(654 rule = self.factory.makeGitRule(
655 repository, ref_pattern=u'refs/heads/archived/*')655 repository, ref_pattern='refs/heads/archived/*')
656 self.factory.makeGitRuleGrant(656 self.factory.makeGitRuleGrant(
657 rule=rule, grantee=GitGranteeType.REPOSITORY_OWNER)657 rule=rule, grantee=GitGranteeType.REPOSITORY_OWNER)
658 self.factory.makeGitRuleGrant(658 self.factory.makeGitRuleGrant(
659 rule=rule, grantee=user_b, can_create=True)659 rule=rule, grantee=user_b, can_create=True)
660660
661 rule = self.factory.makeGitRule(661 rule = self.factory.makeGitRule(
662 repository, ref_pattern=u'refs/heads/stable/*')662 repository, ref_pattern='refs/heads/stable/*')
663 self.factory.makeGitRuleGrant(663 self.factory.makeGitRuleGrant(
664 rule=rule, grantee=stable_team, can_push=True)664 rule=rule, grantee=stable_team, can_push=True)
665665
666 rule = self.factory.makeGitRule(666 rule = self.factory.makeGitRule(
667 repository, ref_pattern=u'refs/heads/*/next')667 repository, ref_pattern='refs/heads/*/next')
668 self.factory.makeGitRuleGrant(668 self.factory.makeGitRuleGrant(
669 rule=rule, grantee=next_team, can_force_push=True)669 rule=rule, grantee=next_team, can_force_push=True)
670670
671 rule = self.factory.makeGitRule(671 rule = self.factory.makeGitRule(
672 repository, ref_pattern=u'refs/tags/*')672 repository, ref_pattern='refs/tags/*')
673 self.factory.makeGitRuleGrant(673 self.factory.makeGitRuleGrant(
674 rule=rule, grantee=GitGranteeType.REPOSITORY_OWNER,674 rule=rule, grantee=GitGranteeType.REPOSITORY_OWNER,
675 can_create=True)675 can_create=True)
@@ -743,18 +743,18 @@ class TestGitAPIMixin:
743 self.factory.makeGitRepository(owner=user_a))743 self.factory.makeGitRepository(owner=user_a))
744744
745 rule = self.factory.makeGitRule(745 rule = self.factory.makeGitRule(
746 repository, ref_pattern=u'refs/heads/master')746 repository, ref_pattern='refs/heads/master')
747 self.factory.makeGitRuleGrant(747 self.factory.makeGitRuleGrant(
748 rule=rule, grantee=user_b, can_push=True)748 rule=rule, grantee=user_b, can_push=True)
749749
750 rule = self.factory.makeGitRule(750 rule = self.factory.makeGitRule(
751 repository, ref_pattern=u'refs/heads/*')751 repository, ref_pattern='refs/heads/*')
752 self.factory.makeGitRuleGrant(752 self.factory.makeGitRuleGrant(
753 rule=rule, grantee=GitGranteeType.REPOSITORY_OWNER,753 rule=rule, grantee=GitGranteeType.REPOSITORY_OWNER,
754 can_create=True, can_push=True, can_force_push=True)754 can_create=True, can_push=True, can_force_push=True)
755755
756 rule = self.factory.makeGitRule(756 rule = self.factory.makeGitRule(
757 repository, ref_pattern=u'refs/tags/*')757 repository, ref_pattern='refs/tags/*')
758 self.factory.makeGitRuleGrant(758 self.factory.makeGitRuleGrant(
759 rule=rule, grantee=user_b, can_push=True)759 rule=rule, grantee=user_b, can_push=True)
760760
@@ -797,11 +797,11 @@ class TestGitAPIMixin:
797 repository = removeSecurityProxy(797 repository = removeSecurityProxy(
798 self.factory.makeGitRepository(owner=owner))798 self.factory.makeGitRepository(owner=owner))
799 self.factory.makeGitRuleGrant(799 self.factory.makeGitRuleGrant(
800 repository=repository, ref_pattern=u"refs/heads/next/*",800 repository=repository, ref_pattern="refs/heads/next/*",
801 grantee=grantee, can_push=True)801 grantee=grantee, can_push=True)
802 paths = [802 paths = [
803 # Properly-encoded UTF-8.803 # Properly-encoded UTF-8.
804 u"refs/heads/next/\N{BLACK HEART SUIT}".encode("UTF-8"),804 "refs/heads/next/\N{BLACK HEART SUIT}".encode(),
805 # Non-UTF-8. (git does not require any particular encoding for805 # Non-UTF-8. (git does not require any particular encoding for
806 # ref paths; non-UTF-8 ones won't work well everywhere, but it's806 # ref paths; non-UTF-8 ones won't work well everywhere, but it's
807 # at least possible to round-trip them through Launchpad.)807 # at least possible to round-trip them through Launchpad.)
@@ -1211,12 +1211,12 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1211 # When this happens, it returns a Fault saying so, including the1211 # When this happens, it returns a Fault saying so, including the
1212 # path it couldn't translate.1212 # path it couldn't translate.
1213 requester = self.factory.makePerson()1213 requester = self.factory.makePerson()
1214 self.assertGitRepositoryNotFound(requester, u"/untranslatable")1214 self.assertGitRepositoryNotFound(requester, "/untranslatable")
12151215
1216 def test_translatePath_repository(self):1216 def test_translatePath_repository(self):
1217 requester = self.factory.makePerson()1217 requester = self.factory.makePerson()
1218 repository = self.factory.makeGitRepository()1218 repository = self.factory.makeGitRepository()
1219 path = u"/%s" % repository.unique_name1219 path = "/%s" % repository.unique_name
1220 self.assertTranslates(requester, path, repository, False)1220 self.assertTranslates(requester, path, repository, False)
12211221
1222 def test_translatePath_repository_with_no_leading_slash(self):1222 def test_translatePath_repository_with_no_leading_slash(self):
@@ -1228,30 +1228,30 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1228 def test_translatePath_repository_with_trailing_slash(self):1228 def test_translatePath_repository_with_trailing_slash(self):
1229 requester = self.factory.makePerson()1229 requester = self.factory.makePerson()
1230 repository = self.factory.makeGitRepository()1230 repository = self.factory.makeGitRepository()
1231 path = u"/%s/" % repository.unique_name1231 path = "/%s/" % repository.unique_name
1232 self.assertTranslates(requester, path, repository, False)1232 self.assertTranslates(requester, path, repository, False)
12331233
1234 def test_translatePath_repository_with_trailing_segments(self):1234 def test_translatePath_repository_with_trailing_segments(self):
1235 requester = self.factory.makePerson()1235 requester = self.factory.makePerson()
1236 repository = self.factory.makeGitRepository()1236 repository = self.factory.makeGitRepository()
1237 path = u"/%s/foo/bar" % repository.unique_name1237 path = "/%s/foo/bar" % repository.unique_name
1238 self.assertTranslates(1238 self.assertTranslates(
1239 requester, path, repository, False, trailing="foo/bar")1239 requester, path, repository, False, trailing="foo/bar")
12401240
1241 def test_translatePath_no_such_repository(self):1241 def test_translatePath_no_such_repository(self):
1242 requester = self.factory.makePerson()1242 requester = self.factory.makePerson()
1243 path = u"/%s/+git/no-such-repository" % requester.name1243 path = "/%s/+git/no-such-repository" % requester.name
1244 self.assertGitRepositoryNotFound(requester, path)1244 self.assertGitRepositoryNotFound(requester, path)
12451245
1246 def test_translatePath_no_such_repository_non_ascii(self):1246 def test_translatePath_no_such_repository_non_ascii(self):
1247 requester = self.factory.makePerson()1247 requester = self.factory.makePerson()
1248 path = u"/%s/+git/\N{LATIN SMALL LETTER I WITH DIAERESIS}" % (1248 path = "/%s/+git/\N{LATIN SMALL LETTER I WITH DIAERESIS}" % (
1249 requester.name)1249 requester.name)
1250 self.assertGitRepositoryNotFound(requester, path)1250 self.assertGitRepositoryNotFound(requester, path)
12511251
1252 def test_translatePath_anonymous_public_repository(self):1252 def test_translatePath_anonymous_public_repository(self):
1253 repository = self.factory.makeGitRepository()1253 repository = self.factory.makeGitRepository()
1254 path = u"/%s" % repository.unique_name1254 path = "/%s" % repository.unique_name
1255 self.assertTranslates(1255 self.assertTranslates(
1256 None, path, repository, False, can_authenticate=False)1256 None, path, repository, False, can_authenticate=False)
1257 self.assertTranslates(1257 self.assertTranslates(
@@ -1260,7 +1260,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1260 def test_translatePath_owned(self):1260 def test_translatePath_owned(self):
1261 requester = self.factory.makePerson()1261 requester = self.factory.makePerson()
1262 repository = self.factory.makeGitRepository(owner=requester)1262 repository = self.factory.makeGitRepository(owner=requester)
1263 path = u"/%s" % repository.unique_name1263 path = "/%s" % repository.unique_name
1264 self.assertTranslates(1264 self.assertTranslates(
1265 requester, path, repository, True, permission="write")1265 requester, path, repository, True, permission="write")
12661266
@@ -1268,7 +1268,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1268 requester = self.factory.makePerson()1268 requester = self.factory.makePerson()
1269 team = self.factory.makeTeam(requester)1269 team = self.factory.makeTeam(requester)
1270 repository = self.factory.makeGitRepository(owner=team)1270 repository = self.factory.makeGitRepository(owner=team)
1271 path = u"/%s" % repository.unique_name1271 path = "/%s" % repository.unique_name
1272 self.assertTranslates(1272 self.assertTranslates(
1273 requester, path, repository, True, permission="write")1273 requester, path, repository, True, permission="write")
12741274
@@ -1279,7 +1279,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1279 with person_logged_in(repository.target.owner):1279 with person_logged_in(repository.target.owner):
1280 getUtility(IGitRepositorySet).setDefaultRepository(1280 getUtility(IGitRepositorySet).setDefaultRepository(
1281 repository.target, repository)1281 repository.target, repository)
1282 path = u"/%s" % repository.target.name1282 path = "/%s" % repository.target.name
1283 self.assertTranslates(requester, path, repository, False)1283 self.assertTranslates(requester, path, repository, False)
12841284
1285 def test_translatePath_create_project_async(self):1285 def test_translatePath_create_project_async(self):
@@ -1288,14 +1288,14 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1288 requester = self.factory.makePerson()1288 requester = self.factory.makePerson()
1289 project = self.factory.makeProduct()1289 project = self.factory.makeProduct()
1290 self.assertCreates(1290 self.assertCreates(
1291 requester, u"/~%s/%s/+git/random" % (requester.name, project.name))1291 requester, "/~%s/%s/+git/random" % (requester.name, project.name))
12921292
1293 def test_translatePath_create_project_sync(self):1293 def test_translatePath_create_project_sync(self):
1294 self.useFixture(FeatureFixture({GIT_ASYNC_CREATE_REPO: ''}))1294 self.useFixture(FeatureFixture({GIT_ASYNC_CREATE_REPO: ''}))
1295 requester = self.factory.makePerson()1295 requester = self.factory.makePerson()
1296 project = self.factory.makeProduct()1296 project = self.factory.makeProduct()
1297 self.assertCreates(1297 self.assertCreates(
1298 requester, u"/~%s/%s/+git/random" % (requester.name, project.name),1298 requester, "/~%s/%s/+git/random" % (requester.name, project.name),
1299 async_create=False)1299 async_create=False)
13001300
1301 def test_translatePath_create_project_blocks_duplicate_calls(self):1301 def test_translatePath_create_project_blocks_duplicate_calls(self):
@@ -1303,7 +1303,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1303 # but blocks any further request to create the same repository.1303 # but blocks any further request to create the same repository.
1304 requester = self.factory.makePerson()1304 requester = self.factory.makePerson()
1305 project = self.factory.makeProduct()1305 project = self.factory.makeProduct()
1306 path = u"/~%s/%s/+git/random" % (requester.name, project.name)1306 path = "/~%s/%s/+git/random" % (requester.name, project.name)
1307 self.assertCreates(requester, path)1307 self.assertCreates(requester, path)
13081308
1309 auth_params = _make_auth_params(1309 auth_params = _make_auth_params(
@@ -1323,7 +1323,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1323 self.repository_set.setDefaultRepository(target, repository)1323 self.repository_set.setDefaultRepository(target, repository)
1324 self.assertCreatesFromClone(1324 self.assertCreatesFromClone(
1325 target.owner,1325 target.owner,
1326 u"/~%s/%s/+git/random" % (target.owner.name, target.name),1326 "/~%s/%s/+git/random" % (target.owner.name, target.name),
1327 repository)1327 repository)
13281328
1329 def test_translatePath_create_project_clone_from_owner_default(self):1329 def test_translatePath_create_project_clone_from_owner_default(self):
@@ -1337,7 +1337,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1337 target.owner, target, repository, user)1337 target.owner, target, repository, user)
1338 self.assertCreatesFromClone(1338 self.assertCreatesFromClone(
1339 target.owner,1339 target.owner,
1340 u"/~%s/%s/+git/random" % (target.owner.name, target.name),1340 "/~%s/%s/+git/random" % (target.owner.name, target.name),
1341 repository)1341 repository)
13421342
1343 def test_translatePath_create_package(self):1343 def test_translatePath_create_package(self):
@@ -1347,7 +1347,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1347 dsp = self.factory.makeDistributionSourcePackage()1347 dsp = self.factory.makeDistributionSourcePackage()
1348 self.assertCreates(1348 self.assertCreates(
1349 requester,1349 requester,
1350 u"/~%s/%s/+source/%s/+git/random" % (1350 "/~%s/%s/+source/%s/+git/random" % (
1351 requester.name,1351 requester.name,
1352 dsp.distribution.name, dsp.sourcepackagename.name))1352 dsp.distribution.name, dsp.sourcepackagename.name))
13531353
@@ -1358,45 +1358,45 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1358 oci_project = self.factory.makeOCIProject()1358 oci_project = self.factory.makeOCIProject()
1359 self.assertCreates(1359 self.assertCreates(
1360 requester,1360 requester,
1361 u"/~%s/%s/+oci/%s/+git/random" % (1361 "/~%s/%s/+oci/%s/+git/random" % (
1362 requester.name, oci_project.pillar.name, oci_project.name))1362 requester.name, oci_project.pillar.name, oci_project.name))
13631363
1364 def test_translatePath_create_personal(self):1364 def test_translatePath_create_personal(self):
1365 # translatePath creates a personal repository that doesn't exist, if1365 # translatePath creates a personal repository that doesn't exist, if
1366 # it can.1366 # it can.
1367 requester = self.factory.makePerson()1367 requester = self.factory.makePerson()
1368 self.assertCreates(requester, u"/~%s/+git/random" % requester.name)1368 self.assertCreates(requester, "/~%s/+git/random" % requester.name)
13691369
1370 def test_translatePath_create_personal_team(self):1370 def test_translatePath_create_personal_team(self):
1371 # translatePath creates a personal repository for a team of which1371 # translatePath creates a personal repository for a team of which
1372 # the requester is a member.1372 # the requester is a member.
1373 requester = self.factory.makePerson()1373 requester = self.factory.makePerson()
1374 team = self.factory.makeTeam(members=[requester])1374 team = self.factory.makeTeam(members=[requester])
1375 self.assertCreates(requester, u"/~%s/+git/random" % team.name)1375 self.assertCreates(requester, "/~%s/+git/random" % team.name)
13761376
1377 def test_translatePath_create_native_string(self):1377 def test_translatePath_create_native_string(self):
1378 # On Python 2, ASCII strings come in as native strings, not Unicode1378 # On Python 2, ASCII strings come in as native strings, not Unicode
1379 # strings. They work fine too.1379 # strings. They work fine too.
1380 requester = self.factory.makePerson()1380 requester = self.factory.makePerson()
1381 project = self.factory.makeProduct()1381 project = self.factory.makeProduct()
1382 path = u"/~%s/%s/+git/random" % (requester.name, project.name)1382 path = "/~%s/%s/+git/random" % (requester.name, project.name)
1383 self.assertCreates(requester, six.ensure_str(path))1383 self.assertCreates(requester, six.ensure_str(path))
13841384
1385 def test_translatePath_anonymous_cannot_create(self):1385 def test_translatePath_anonymous_cannot_create(self):
1386 # Anonymous users cannot create repositories.1386 # Anonymous users cannot create repositories.
1387 project = self.factory.makeProject()1387 project = self.factory.makeProject()
1388 self.assertGitRepositoryNotFound(1388 self.assertGitRepositoryNotFound(
1389 None, u"/%s" % project.name, permission="write",1389 None, "/%s" % project.name, permission="write",
1390 can_authenticate=False)1390 can_authenticate=False)
1391 self.assertUnauthorized(1391 self.assertUnauthorized(
1392 None, u"/%s" % project.name, permission="write",1392 None, "/%s" % project.name, permission="write",
1393 can_authenticate=True)1393 can_authenticate=True)
13941394
1395 def test_translatePath_create_invalid_namespace(self):1395 def test_translatePath_create_invalid_namespace(self):
1396 # Trying to create a repository at a path that isn't valid for Git1396 # Trying to create a repository at a path that isn't valid for Git
1397 # repositories returns a PermissionDenied fault.1397 # repositories returns a PermissionDenied fault.
1398 requester = self.factory.makePerson()1398 requester = self.factory.makePerson()
1399 path = u"/~%s" % requester.name1399 path = "/~%s" % requester.name
1400 message = "'%s' is not a valid Git repository path." % path.strip("/")1400 message = "'%s' is not a valid Git repository path." % path.strip("/")
1401 self.assertPermissionDenied(1401 self.assertPermissionDenied(
1402 requester, path, message=message, permission="write")1402 requester, path, message=message, permission="write")
@@ -1405,14 +1405,14 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1405 # Creating a repository for a non-existent person fails.1405 # Creating a repository for a non-existent person fails.
1406 requester = self.factory.makePerson()1406 requester = self.factory.makePerson()
1407 self.assertNotFound(1407 self.assertNotFound(
1408 requester, u"/~nonexistent/+git/random",1408 requester, "/~nonexistent/+git/random",
1409 "User/team 'nonexistent' does not exist.", permission="write")1409 "User/team 'nonexistent' does not exist.", permission="write")
14101410
1411 def test_translatePath_create_no_such_project(self):1411 def test_translatePath_create_no_such_project(self):
1412 # Creating a repository for a non-existent project fails.1412 # Creating a repository for a non-existent project fails.
1413 requester = self.factory.makePerson()1413 requester = self.factory.makePerson()
1414 self.assertNotFound(1414 self.assertNotFound(
1415 requester, u"/~%s/nonexistent/+git/random" % requester.name,1415 requester, "/~%s/nonexistent/+git/random" % requester.name,
1416 "Project 'nonexistent' does not exist.", permission="write")1416 "Project 'nonexistent' does not exist.", permission="write")
14171417
1418 def test_translatePath_create_no_such_person_or_project(self):1418 def test_translatePath_create_no_such_person_or_project(self):
@@ -1420,14 +1420,14 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1420 # person is reported in preference.1420 # person is reported in preference.
1421 requester = self.factory.makePerson()1421 requester = self.factory.makePerson()
1422 self.assertNotFound(1422 self.assertNotFound(
1423 requester, u"/~nonexistent/nonexistent/+git/random",1423 requester, "/~nonexistent/nonexistent/+git/random",
1424 "User/team 'nonexistent' does not exist.", permission="write")1424 "User/team 'nonexistent' does not exist.", permission="write")
14251425
1426 def test_translatePath_create_invalid_project(self):1426 def test_translatePath_create_invalid_project(self):
1427 # Creating a repository with an invalid project name fails.1427 # Creating a repository with an invalid project name fails.
1428 requester = self.factory.makePerson()1428 requester = self.factory.makePerson()
1429 self.assertNotFound(1429 self.assertNotFound(
1430 requester, u"/_bad_project/+git/random",1430 requester, "/_bad_project/+git/random",
1431 "Project '_bad_project' does not exist.", permission="write")1431 "Project '_bad_project' does not exist.", permission="write")
14321432
1433 def test_translatePath_create_missing_sourcepackagename(self):1433 def test_translatePath_create_missing_sourcepackagename(self):
@@ -1436,7 +1436,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1436 requester = self.factory.makePerson()1436 requester = self.factory.makePerson()
1437 distro = self.factory.makeDistribution()1437 distro = self.factory.makeDistribution()
1438 repository_name = self.factory.getUniqueString()1438 repository_name = self.factory.getUniqueString()
1439 path = u"/~%s/%s/+source/new-package/+git/%s" % (1439 path = "/~%s/%s/+source/new-package/+git/%s" % (
1440 requester.name, distro.name, repository_name)1440 requester.name, distro.name, repository_name)
1441 repository = self.assertCreates(requester, path)1441 repository = self.assertCreates(requester, path)
1442 self.assertEqual(1442 self.assertEqual(
@@ -1447,7 +1447,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1447 requester = self.factory.makePerson()1447 requester = self.factory.makePerson()
1448 distro = self.factory.makeDistribution()1448 distro = self.factory.makeDistribution()
1449 repository_name = self.factory.getUniqueString()1449 repository_name = self.factory.getUniqueString()
1450 path = u"/~%s/%s/+source/new package/+git/%s" % (1450 path = "/~%s/%s/+source/new package/+git/%s" % (
1451 requester.name, distro.name, repository_name)1451 requester.name, distro.name, repository_name)
1452 self.assertInvalidSourcePackageName(1452 self.assertInvalidSourcePackageName(
1453 requester, path, "new package", permission="write")1453 requester, path, "new package", permission="write")
@@ -1457,7 +1457,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1457 requester = self.factory.makePerson()1457 requester = self.factory.makePerson()
1458 project = self.factory.makeProduct()1458 project = self.factory.makeProduct()
1459 invalid_name = "invalid name!"1459 invalid_name = "invalid name!"
1460 path = u"/~%s/%s/+git/%s" % (1460 path = "/~%s/%s/+git/%s" % (
1461 requester.name, project.name, invalid_name)1461 requester.name, project.name, invalid_name)
1462 # LaunchpadValidationError unfortunately assumes its output is1462 # LaunchpadValidationError unfortunately assumes its output is
1463 # always HTML, so it ends up double-escaped in XML-RPC faults.1463 # always HTML, so it ends up double-escaped in XML-RPC faults.
@@ -1471,8 +1471,8 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1471 # Creating a repository with a non-ASCII invalid name fails.1471 # Creating a repository with a non-ASCII invalid name fails.
1472 requester = self.factory.makePerson()1472 requester = self.factory.makePerson()
1473 project = self.factory.makeProduct()1473 project = self.factory.makeProduct()
1474 invalid_name = u"invalid\N{LATIN SMALL LETTER E WITH ACUTE}"1474 invalid_name = "invalid\N{LATIN SMALL LETTER E WITH ACUTE}"
1475 path = u"/~%s/%s/+git/%s" % (1475 path = "/~%s/%s/+git/%s" % (
1476 requester.name, project.name, invalid_name)1476 requester.name, project.name, invalid_name)
1477 # LaunchpadValidationError unfortunately assumes its output is1477 # LaunchpadValidationError unfortunately assumes its output is
1478 # always HTML, so it ends up double-escaped in XML-RPC faults.1478 # always HTML, so it ends up double-escaped in XML-RPC faults.
@@ -1490,7 +1490,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1490 membership_policy=TeamMembershipPolicy.RESTRICTED,1490 membership_policy=TeamMembershipPolicy.RESTRICTED,
1491 members=[requester])1491 members=[requester])
1492 project = self.factory.makeProduct(owner=owner)1492 project = self.factory.makeProduct(owner=owner)
1493 repository = self.assertCreates(requester, u"/%s" % project.name)1493 repository = self.assertCreates(requester, "/%s" % project.name)
1494 self.assertTrue(repository.target_default)1494 self.assertTrue(repository.target_default)
1495 self.assertTrue(repository.owner_default)1495 self.assertTrue(repository.owner_default)
1496 self.assertEqual(owner, repository.owner)1496 self.assertEqual(owner, repository.owner)
@@ -1500,7 +1500,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1500 # default for a package.1500 # default for a package.
1501 requester = self.factory.makePerson()1501 requester = self.factory.makePerson()
1502 dsp = self.factory.makeDistributionSourcePackage()1502 dsp = self.factory.makeDistributionSourcePackage()
1503 path = u"/%s/+source/%s" % (1503 path = "/%s/+source/%s" % (
1504 dsp.distribution.name, dsp.sourcepackagename.name)1504 dsp.distribution.name, dsp.sourcepackagename.name)
1505 message = (1505 message = (
1506 "Cannot automatically set the default repository for this target; "1506 "Cannot automatically set the default repository for this target; "
@@ -1518,7 +1518,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1518 oci_project = self.factory.makeOCIProject(pillar=distribution)1518 oci_project = self.factory.makeOCIProject(pillar=distribution)
1519 repository = self.assertCreates(1519 repository = self.assertCreates(
1520 requester,1520 requester,
1521 u"/%s/+oci/%s" % (oci_project.pillar.name, oci_project.name))1521 "/%s/+oci/%s" % (oci_project.pillar.name, oci_project.name))
1522 self.assertTrue(repository.target_default)1522 self.assertTrue(repository.target_default)
1523 self.assertTrue(repository.owner_default)1523 self.assertTrue(repository.owner_default)
1524 self.assertEqual(oci_project_admin, repository.owner)1524 self.assertEqual(oci_project_admin, repository.owner)
@@ -1529,7 +1529,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1529 # default for that OCI project.1529 # default for that OCI project.
1530 requester = self.factory.makePerson()1530 requester = self.factory.makePerson()
1531 oci_project = self.factory.makeOCIProject()1531 oci_project = self.factory.makeOCIProject()
1532 path = u"/%s/+oci/%s" % (oci_project.pillar.name, oci_project.name)1532 path = "/%s/+oci/%s" % (oci_project.pillar.name, oci_project.name)
1533 message = (1533 message = (
1534 "Cannot automatically set the default repository for this target; "1534 "Cannot automatically set the default repository for this target; "
1535 "push to a named repository instead.")1535 "push to a named repository instead.")
@@ -1547,7 +1547,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1547 requester = self.factory.makePerson()1547 requester = self.factory.makePerson()
1548 project = self.factory.makeProduct()1548 project = self.factory.makeProduct()
1549 repository = self.assertCreates(1549 repository = self.assertCreates(
1550 requester, u"/~%s/%s" % (requester.name, project.name))1550 requester, "/~%s/%s" % (requester.name, project.name))
1551 self.assertFalse(repository.target_default)1551 self.assertFalse(repository.target_default)
1552 self.assertTrue(repository.owner_default)1552 self.assertTrue(repository.owner_default)
1553 self.assertEqual(requester, repository.owner)1553 self.assertEqual(requester, repository.owner)
@@ -1559,7 +1559,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1559 team = self.factory.makeTeam(owner=requester)1559 team = self.factory.makeTeam(owner=requester)
1560 project = self.factory.makeProduct()1560 project = self.factory.makeProduct()
1561 repository = self.assertCreates(1561 repository = self.assertCreates(
1562 requester, u"/~%s/%s" % (team.name, project.name))1562 requester, "/~%s/%s" % (team.name, project.name))
1563 self.assertFalse(repository.target_default)1563 self.assertFalse(repository.target_default)
1564 self.assertTrue(repository.owner_default)1564 self.assertTrue(repository.owner_default)
1565 self.assertEqual(team, repository.owner)1565 self.assertEqual(team, repository.owner)
@@ -1571,7 +1571,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1571 team = self.factory.makeTeam(members=[requester])1571 team = self.factory.makeTeam(members=[requester])
1572 project = self.factory.makeProduct()1572 project = self.factory.makeProduct()
1573 repository = self.assertCreates(1573 repository = self.assertCreates(
1574 requester, u"/~%s/%s" % (team.name, project.name))1574 requester, "/~%s/%s" % (team.name, project.name))
1575 self.assertFalse(repository.target_default)1575 self.assertFalse(repository.target_default)
1576 self.assertTrue(repository.owner_default)1576 self.assertTrue(repository.owner_default)
1577 self.assertEqual(team, repository.owner)1577 self.assertEqual(team, repository.owner)
@@ -1581,7 +1581,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1581 # default for a package.1581 # default for a package.
1582 requester = self.factory.makePerson()1582 requester = self.factory.makePerson()
1583 dsp = self.factory.makeDistributionSourcePackage()1583 dsp = self.factory.makeDistributionSourcePackage()
1584 path = u"/~%s/%s/+source/%s" % (1584 path = "/~%s/%s/+source/%s" % (
1585 requester.name, dsp.distribution.name, dsp.sourcepackagename.name)1585 requester.name, dsp.distribution.name, dsp.sourcepackagename.name)
1586 repository = self.assertCreates(requester, path)1586 repository = self.assertCreates(requester, path)
1587 self.assertFalse(repository.target_default)1587 self.assertFalse(repository.target_default)
@@ -1594,7 +1594,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1594 requester = self.factory.makePerson()1594 requester = self.factory.makePerson()
1595 team = self.factory.makeTeam(owner=requester)1595 team = self.factory.makeTeam(owner=requester)
1596 dsp = self.factory.makeDistributionSourcePackage()1596 dsp = self.factory.makeDistributionSourcePackage()
1597 path = u"/~%s/%s/+source/%s" % (1597 path = "/~%s/%s/+source/%s" % (
1598 team.name, dsp.distribution.name, dsp.sourcepackagename.name)1598 team.name, dsp.distribution.name, dsp.sourcepackagename.name)
1599 repository = self.assertCreates(requester, path)1599 repository = self.assertCreates(requester, path)
1600 self.assertFalse(repository.target_default)1600 self.assertFalse(repository.target_default)
@@ -1607,7 +1607,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1607 requester = self.factory.makePerson()1607 requester = self.factory.makePerson()
1608 team = self.factory.makeTeam(members=[requester])1608 team = self.factory.makeTeam(members=[requester])
1609 dsp = self.factory.makeDistributionSourcePackage()1609 dsp = self.factory.makeDistributionSourcePackage()
1610 path = u"/~%s/%s/+source/%s" % (1610 path = "/~%s/%s/+source/%s" % (
1611 team.name, dsp.distribution.name, dsp.sourcepackagename.name)1611 team.name, dsp.distribution.name, dsp.sourcepackagename.name)
1612 repository = self.assertCreates(requester, path)1612 repository = self.assertCreates(requester, path)
1613 self.assertFalse(repository.target_default)1613 self.assertFalse(repository.target_default)
@@ -1619,7 +1619,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1619 # default for an OCI project.1619 # default for an OCI project.
1620 requester = self.factory.makePerson()1620 requester = self.factory.makePerson()
1621 oci_project = self.factory.makeOCIProject()1621 oci_project = self.factory.makeOCIProject()
1622 path = u"/~%s/%s/+oci/%s" % (1622 path = "/~%s/%s/+oci/%s" % (
1623 requester.name, oci_project.pillar.name, oci_project.name)1623 requester.name, oci_project.pillar.name, oci_project.name)
1624 repository = self.assertCreates(requester, path)1624 repository = self.assertCreates(requester, path)
1625 self.assertFalse(repository.target_default)1625 self.assertFalse(repository.target_default)
@@ -1632,7 +1632,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1632 requester = self.factory.makePerson()1632 requester = self.factory.makePerson()
1633 team = self.factory.makeTeam(owner=requester)1633 team = self.factory.makeTeam(owner=requester)
1634 oci_project = self.factory.makeOCIProject()1634 oci_project = self.factory.makeOCIProject()
1635 path = u"/~%s/%s/+oci/%s" % (1635 path = "/~%s/%s/+oci/%s" % (
1636 team.name, oci_project.pillar.name, oci_project.name)1636 team.name, oci_project.pillar.name, oci_project.name)
1637 repository = self.assertCreates(requester, path)1637 repository = self.assertCreates(requester, path)
1638 self.assertFalse(repository.target_default)1638 self.assertFalse(repository.target_default)
@@ -1645,7 +1645,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1645 requester = self.factory.makePerson()1645 requester = self.factory.makePerson()
1646 team = self.factory.makeTeam(members=[requester])1646 team = self.factory.makeTeam(members=[requester])
1647 oci_project = self.factory.makeOCIProject()1647 oci_project = self.factory.makeOCIProject()
1648 path = u"/~%s/%s/+oci/%s" % (1648 path = "/~%s/%s/+oci/%s" % (
1649 team.name, oci_project.pillar.name, oci_project.name)1649 team.name, oci_project.pillar.name, oci_project.name)
1650 repository = self.assertCreates(requester, path)1650 repository = self.assertCreates(requester, path)
1651 self.assertFalse(repository.target_default)1651 self.assertFalse(repository.target_default)
@@ -1661,7 +1661,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1661 requester = self.factory.makePerson()1661 requester = self.factory.makePerson()
1662 initial_count = getUtility(IAllGitRepositories).count()1662 initial_count = getUtility(IAllGitRepositories).count()
1663 oops_id = self.assertOopsOccurred(1663 oops_id = self.assertOopsOccurred(
1664 requester, u"/~%s/+git/random" % requester.name,1664 requester, "/~%s/+git/random" % requester.name,
1665 permission="write")1665 permission="write")
1666 login(ANONYMOUS)1666 login(ANONYMOUS)
1667 self.assertEqual(1667 self.assertEqual(
@@ -1691,7 +1691,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1691 issuer = getUtility(IMacaroonIssuer, "code-import-job")1691 issuer = getUtility(IMacaroonIssuer, "code-import-job")
1692 macaroons = [1692 macaroons = [
1693 removeSecurityProxy(issuer).issueMacaroon(job) for job in jobs]1693 removeSecurityProxy(issuer).issueMacaroon(job) for job in jobs]
1694 path = u"/%s" % code_imports[0].git_repository.unique_name1694 path = "/%s" % code_imports[0].git_repository.unique_name
1695 self.assertUnauthorized(1695 self.assertUnauthorized(
1696 LAUNCHPAD_SERVICES, path, permission="write",1696 LAUNCHPAD_SERVICES, path, permission="write",
1697 macaroon_raw=macaroons[0].serialize())1697 macaroon_raw=macaroons[0].serialize())
@@ -1735,7 +1735,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1735 issuer = getUtility(IMacaroonIssuer, "code-import-job")1735 issuer = getUtility(IMacaroonIssuer, "code-import-job")
1736 macaroons = [1736 macaroons = [
1737 removeSecurityProxy(issuer).issueMacaroon(job) for job in jobs]1737 removeSecurityProxy(issuer).issueMacaroon(job) for job in jobs]
1738 path = u"/%s" % code_imports[0].git_repository.unique_name1738 path = "/%s" % code_imports[0].git_repository.unique_name
1739 self.assertUnauthorized(1739 self.assertUnauthorized(
1740 LAUNCHPAD_SERVICES, path, permission="write",1740 LAUNCHPAD_SERVICES, path, permission="write",
1741 macaroon_raw=macaroons[0].serialize())1741 macaroon_raw=macaroons[0].serialize())
@@ -1780,7 +1780,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1780 removeSecurityProxy(issuer).issueMacaroon(build)1780 removeSecurityProxy(issuer).issueMacaroon(build)
1781 for build in builds]1781 for build in builds]
1782 repository = refs[0].repository1782 repository = refs[0].repository
1783 path = u"/%s" % repository.unique_name1783 path = "/%s" % repository.unique_name
1784 self.assertUnauthorized(1784 self.assertUnauthorized(
1785 LAUNCHPAD_SERVICES, path, permission="write",1785 LAUNCHPAD_SERVICES, path, permission="write",
1786 macaroon_raw=macaroons[0].serialize())1786 macaroon_raw=macaroons[0].serialize())
@@ -1819,7 +1819,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1819 repository, user=requester)1819 repository, user=requester)
1820 for repository in repositories]1820 for repository in repositories]
1821 paths = [1821 paths = [
1822 u"/%s" % repository.unique_name for repository in repositories]1822 "/%s" % repository.unique_name for repository in repositories]
1823 for i, repository in enumerate(repositories):1823 for i, repository in enumerate(repositories):
1824 for j, macaroon in enumerate(macaroons):1824 for j, macaroon in enumerate(macaroons):
1825 login(ANONYMOUS)1825 login(ANONYMOUS)
@@ -1853,7 +1853,7 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1853 self.useFixture(ZopeUtilityFixture(1853 self.useFixture(ZopeUtilityFixture(
1854 issuer, IMacaroonIssuer, name="test"))1854 issuer, IMacaroonIssuer, name="test"))
1855 repository = self.factory.makeGitRepository()1855 repository = self.factory.makeGitRepository()
1856 path = u"/%s" % repository.unique_name1856 path = "/%s" % repository.unique_name
1857 macaroon = issuer.issueMacaroon(repository)1857 macaroon = issuer.issueMacaroon(repository)
1858 requesters = [self.factory.makePerson() for _ in range(2)]1858 requesters = [self.factory.makePerson() for _ in range(2)]
1859 for verified_user, authorized, unauthorized in (1859 for verified_user, authorized, unauthorized in (
@@ -1881,8 +1881,8 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1881 requester_owner = self.factory.makePerson()1881 requester_owner = self.factory.makePerson()
1882 repository = self.factory.makeGitRepository(owner=requester_owner)1882 repository = self.factory.makeGitRepository(owner=requester_owner)
1883 self.factory.makeGitRefs(1883 self.factory.makeGitRefs(
1884 repository=repository, paths=[u'refs/heads/master'])1884 repository=repository, paths=['refs/heads/master'])
1885 removeSecurityProxy(repository).default_branch = u'refs/heads/master'1885 removeSecurityProxy(repository).default_branch = 'refs/heads/master'
1886 pushed_branch = 'branch1'1886 pushed_branch = 'branch1'
1887 self.assertHasMergeProposalURL(repository, pushed_branch,1887 self.assertHasMergeProposalURL(repository, pushed_branch,
1888 {"uid": requester_owner.id})1888 {"uid": requester_owner.id})
@@ -1892,9 +1892,9 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1892 # Consequently LP will process any incoming branch from Turnip1892 # Consequently LP will process any incoming branch from Turnip
1893 # as being non default and produce a merge proposal URL for it.1893 # as being non default and produce a merge proposal URL for it.
1894 self.factory.makeGitRefs(1894 self.factory.makeGitRefs(
1895 repository=repository, paths=[u'refs/heads/%s' % pushed_branch])1895 repository=repository, paths=['refs/heads/%s' % pushed_branch])
1896 removeSecurityProxy(repository).default_branch = (1896 removeSecurityProxy(repository).default_branch = (
1897 u'refs/heads/%s' % pushed_branch)1897 'refs/heads/%s' % pushed_branch)
1898 self.assertHasMergeProposalURL(repository, pushed_branch,1898 self.assertHasMergeProposalURL(repository, pushed_branch,
1899 {"uid": requester_owner.id})1899 {"uid": requester_owner.id})
19001900
@@ -1912,8 +1912,8 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1912 repository = self.factory.makeGitRepository(owner=requester)1912 repository = self.factory.makeGitRepository(owner=requester)
1913 issuer = getUtility(IMacaroonIssuer, "git-repository")1913 issuer = getUtility(IMacaroonIssuer, "git-repository")
1914 self.factory.makeGitRefs(1914 self.factory.makeGitRefs(
1915 repository=repository, paths=[u'refs/heads/master'])1915 repository=repository, paths=['refs/heads/master'])
1916 removeSecurityProxy(repository).default_branch = u'refs/heads/master'1916 removeSecurityProxy(repository).default_branch = 'refs/heads/master'
19171917
1918 pushed_branch = 'branch1'1918 pushed_branch = 'branch1'
1919 with person_logged_in(requester):1919 with person_logged_in(requester):
@@ -1940,8 +1940,8 @@ class TestGitAPI(TestGitAPIMixin, TestCaseWithFactory):
1940 owner = self.factory.makeTeam(members=requesters)1940 owner = self.factory.makeTeam(members=requesters)
1941 repository = self.factory.makeGitRepository(owner=owner)1941 repository = self.factory.makeGitRepository(owner=owner)
1942 self.factory.makeGitRefs(1942 self.factory.makeGitRefs(
1943 repository=repository, paths=[u'refs/heads/master'])1943 repository=repository, paths=['refs/heads/master'])
1944 removeSecurityProxy(repository).default_branch = u'refs/heads/master'1944 removeSecurityProxy(repository).default_branch = 'refs/heads/master'
1945 pushed_branch = 'branch1'1945 pushed_branch = 'branch1'
1946 macaroon = issuer.issueMacaroon(repository)1946 macaroon = issuer.issueMacaroon(repository)
19471947

Subscribers

People subscribed via source and target branches

to status/vote changes: