Merge ~cjwatson/launchpad:pyupgrade-py3-registry-1 into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 00f8fbecbdad86d49383674e68c4fa662cf5fc1e
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:pyupgrade-py3-registry-1
Merge into: launchpad:master
Diff against target: 3377 lines (+405/-423)
54 files modified
.git-blame-ignore-revs (+2/-0)
.pre-commit-config.yaml (+1/-0)
lib/lp/registry/browser/codeofconduct.py (+1/-1)
lib/lp/registry/browser/distribution.py (+10/-10)
lib/lp/registry/browser/distributionsourcepackage.py (+3/-4)
lib/lp/registry/browser/distroseries.py (+14/-14)
lib/lp/registry/browser/distroseriesdifference.py (+1/-1)
lib/lp/registry/browser/distroseriesdifferencecomment.py (+1/-2)
lib/lp/registry/browser/featuredproject.py (+1/-1)
lib/lp/registry/browser/mailinglists.py (+10/-10)
lib/lp/registry/browser/milestone.py (+9/-9)
lib/lp/registry/browser/objectreassignment.py (+1/-1)
lib/lp/registry/browser/ociproject.py (+5/-5)
lib/lp/registry/browser/peoplemerge.py (+7/-9)
lib/lp/registry/browser/person.py (+40/-45)
lib/lp/registry/browser/pillar.py (+3/-3)
lib/lp/registry/browser/poll.py (+2/-2)
lib/lp/registry/browser/product.py (+26/-26)
lib/lp/registry/browser/productrelease.py (+4/-4)
lib/lp/registry/browser/productseries.py (+4/-5)
lib/lp/registry/browser/project.py (+4/-4)
lib/lp/registry/browser/sourcepackage.py (+5/-5)
lib/lp/registry/browser/team.py (+15/-19)
lib/lp/registry/browser/teammembership.py (+1/-1)
lib/lp/registry/browser/tests/test_announcements.py (+4/-4)
lib/lp/registry/browser/tests/test_branding.py (+1/-1)
lib/lp/registry/browser/tests/test_breadcrumbs.py (+7/-7)
lib/lp/registry/browser/tests/test_codeofconduct.py (+2/-2)
lib/lp/registry/browser/tests/test_distribution.py (+4/-4)
lib/lp/registry/browser/tests/test_distribution_views.py (+12/-12)
lib/lp/registry/browser/tests/test_distributionsourcepackage.py (+3/-3)
lib/lp/registry/browser/tests/test_distroseries.py (+57/-62)
lib/lp/registry/browser/tests/test_distroseriesdifference_views.py (+4/-4)
lib/lp/registry/browser/tests/test_distroseriesdifference_webservice.py (+9/-9)
lib/lp/registry/browser/tests/test_edit_permissions.py (+1/-1)
lib/lp/registry/browser/tests/test_mailinglists.py (+1/-1)
lib/lp/registry/browser/tests/test_milestone.py (+15/-15)
lib/lp/registry/browser/tests/test_ociproject.py (+1/-1)
lib/lp/registry/browser/tests/test_packaging.py (+3/-3)
lib/lp/registry/browser/tests/test_peoplemerge.py (+15/-15)
lib/lp/registry/browser/tests/test_person.py (+37/-38)
lib/lp/registry/browser/tests/test_person_contact.py (+1/-1)
lib/lp/registry/browser/tests/test_person_webservice.py (+9/-9)
lib/lp/registry/browser/tests/test_pillar_sharing.py (+5/-5)
lib/lp/registry/browser/tests/test_poll.py (+2/-2)
lib/lp/registry/browser/tests/test_product.py (+5/-5)
lib/lp/registry/browser/tests/test_projectgroup.py (+2/-2)
lib/lp/registry/browser/tests/test_reassign_team_view.py (+1/-1)
lib/lp/registry/browser/tests/test_sourcepackage_views.py (+1/-1)
lib/lp/registry/browser/tests/test_subscription_links.py (+20/-21)
lib/lp/registry/browser/tests/test_team.py (+8/-8)
lib/lp/registry/browser/tests/test_teammembership.py (+1/-1)
lib/lp/registry/browser/widgets/ocicredentialswidget.py (+1/-1)
lib/lp/registry/browser/widgets/tests/test_ocicredentialswidget.py (+3/-3)
Reviewer Review Type Date Requested Status
Colin Watson Approve
Review via email: mp+413506@code.launchpad.net

Commit message

lp.registry.browser: Apply "pyupgrade --py3-plus"

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

Self-approving (mechanical).

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
2index a251b8f..c594c33 100644
3--- a/.git-blame-ignore-revs
4+++ b/.git-blame-ignore-revs
5@@ -28,3 +28,5 @@ cee9b128d3e49ca814464eeeeec50e6bcabcc4ba
6 f36fe66e5e5a5e82ba8c3269e32d76bd573d1175
7 # apply pyupgrade --py3-plus to lp.{coop,oci}
8 fbed83f22424df8fa5647349493f78937a520db5
9+# apply pyupgrade --py3-plus to lp.registry.browser
10+9c1665b1dfed3f6abf69afa192700172ea3089a1
11diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
12index 22c2329..784ae6a 100644
13--- a/.pre-commit-config.yaml
14+++ b/.pre-commit-config.yaml
15@@ -52,6 +52,7 @@ repos:
16 |codehosting
17 |coop
18 |oci
19+ |registry/browser
20 )/
21 - repo: https://github.com/PyCQA/isort
22 rev: 5.9.2
23diff --git a/lib/lp/registry/browser/codeofconduct.py b/lib/lp/registry/browser/codeofconduct.py
24index 65fc254..cda21f9 100644
25--- a/lib/lp/registry/browser/codeofconduct.py
26+++ b/lib/lp/registry/browser/codeofconduct.py
27@@ -175,7 +175,7 @@ class AffirmCodeOfConductView(LaunchpadFormView):
28
29 affirmed = copy_field(
30 ISignedCodeOfConduct["affirmed"],
31- title=_("I agree to this Code of Conduct"), description=u"")
32+ title=_("I agree to this Code of Conduct"), description="")
33
34 field_names = ['affirmed']
35
36diff --git a/lib/lp/registry/browser/distribution.py b/lib/lp/registry/browser/distribution.py
37index 741fab0..025e405 100644
38--- a/lib/lp/registry/browser/distribution.py
39+++ b/lib/lp/registry/browser/distribution.py
40@@ -372,7 +372,7 @@ class DistributionNavigationMenu(NavigationMenu, DistributionLinksMixin):
41
42 def search_oci_project(self):
43 oci_projects = getUtility(IOCIProjectSet).findByPillarAndName(
44- self.context, u'')
45+ self.context, '')
46 text = 'Search for OCI project'
47 link = Link('+search-oci-project', text, icon='info')
48 link.enabled = not oci_projects.is_empty()
49@@ -574,7 +574,7 @@ class DistributionPackageSearchView(PackageSearchViewBase):
50
51 def initialize(self):
52 """Save the search type if provided."""
53- super(DistributionPackageSearchView, self).initialize()
54+ super().initialize()
55
56 # If the distribution contains binary packages, then we'll
57 # default to searches on binary names, but allow the user to
58@@ -704,7 +704,7 @@ class DistributionView(PillarViewMixin, HasAnnouncementsView, FeedsMixin):
59 """Default Distribution view class."""
60
61 def initialize(self):
62- super(DistributionView, self).initialize()
63+ super().initialize()
64 expose_structural_subscription_data_to_js(
65 self.context, self.request, self.user)
66
67@@ -902,9 +902,9 @@ class RequireVirtualizedBuildersMixin:
68 return form.Fields(
69 Bool(
70 __name__='require_virtualized',
71- title=u"Require virtualized builders",
72+ title="Require virtualized builders",
73 description=(
74- u"Only build the distribution's packages on virtual "
75+ "Only build the distribution's packages on virtual "
76 "builders."),
77 required=True))
78
79@@ -956,8 +956,8 @@ class DistributionAddView(LaunchpadFormView, RequireVirtualizedBuildersMixin,
80 self.form_fields += self.createRequireVirtualized()
81 self.form_fields += self.createEnabledProcessors(
82 getUtility(IProcessorSet).getAll(),
83- u"The architectures on which the distribution's main archive can "
84- u"build.")
85+ "The architectures on which the distribution's main archive can "
86+ "build.")
87
88 @action("Save", name='save')
89 def save_action(self, action, data):
90@@ -1028,8 +1028,8 @@ class DistributionEditView(RegistryEditFormView,
91 self.form_fields += self.createRequireVirtualized()
92 self.form_fields += self.createEnabledProcessors(
93 getUtility(IProcessorSet).getAll(),
94- u"The architectures on which the distribution's main archive can "
95- u"build.")
96+ "The architectures on which the distribution's main archive can "
97+ "build.")
98
99 @property
100 def initial_values(self):
101@@ -1195,7 +1195,7 @@ class DistributionCountryArchiveMirrorsView(LaunchpadView):
102 request = self.request
103 if not self.context.supports_mirrors:
104 request.response.setStatus(404)
105- return u''
106+ return ''
107 ip_address = ipaddress_from_request(request)
108 country = request_country(request)
109 mirrors = getUtility(IDistributionMirrorSet).getBestMirrorsForCountry(
110diff --git a/lib/lp/registry/browser/distributionsourcepackage.py b/lib/lp/registry/browser/distributionsourcepackage.py
111index 48def0c..1d09774 100644
112--- a/lib/lp/registry/browser/distributionsourcepackage.py
113+++ b/lib/lp/registry/browser/distributionsourcepackage.py
114@@ -22,7 +22,6 @@ import operator
115
116 import apt_pkg
117 from lazr.delegates import delegate_to
118-import six
119 from zope.component import getUtility
120 from zope.interface import (
121 implementer,
122@@ -119,7 +118,7 @@ class DistributionSourcePackageURL:
123 not self.context.distribution.redirect_default_traversal):
124 return self.context.name
125 else:
126- return u"+source/%s" % self.context.name
127+ return "+source/%s" % self.context.name
128
129
130 class DistributionSourcePackageFormatterAPI(CustomizableFormatter):
131@@ -298,7 +297,7 @@ class DistributionSourcePackageBaseView(LaunchpadView):
132
133 def not_empty(text):
134 return (
135- text is not None and isinstance(text, six.string_types)
136+ text is not None and isinstance(text, str)
137 and len(text.strip()) > 0)
138
139 def decorate(dspr_pubs):
140@@ -341,7 +340,7 @@ class DistributionSourcePackageView(DistributionSourcePackageBaseView,
141 """View class for DistributionSourcePackage."""
142
143 def initialize(self):
144- super(DistributionSourcePackageView, self).initialize()
145+ super().initialize()
146 expose_structural_subscription_data_to_js(
147 self.context, self.request, self.user)
148
149diff --git a/lib/lp/registry/browser/distroseries.py b/lib/lp/registry/browser/distroseries.py
150index 6b162dc..0834c89 100644
151--- a/lib/lp/registry/browser/distroseries.py
152+++ b/lib/lp/registry/browser/distroseries.py
153@@ -159,7 +159,7 @@ class DistroSeriesURL:
154 not self.context.distribution.redirect_default_traversal):
155 return self.context.name
156 else:
157- return u"+series/%s" % self.context.name
158+ return "+series/%s" % self.context.name
159
160
161 class DistroSeriesNavigation(GetitemNavigation, BugTargetTraversalMixin,
162@@ -439,7 +439,7 @@ class DistroSeriesView(LaunchpadView, MilestoneOverlayMixin,
163 DerivedDistroSeriesMixin):
164
165 def initialize(self):
166- super(DistroSeriesView, self).initialize()
167+ super().initialize()
168 self.displayname = '%s %s' % (
169 self.context.distribution.displayname,
170 self.context.version)
171@@ -709,7 +709,7 @@ class DistroSeriesAddView(LaunchpadFormView):
172 ]
173
174 help_links = {
175- "name": u"/+help-registry/distribution-add-series.html#codename",
176+ "name": "/+help-registry/distribution-add-series.html#codename",
177 }
178
179 label = 'Add a series'
180@@ -729,7 +729,7 @@ class DistroSeriesAddView(LaunchpadFormView):
181 display_name=data['display_name'],
182 title=data['display_name'],
183 summary=data['summary'],
184- description=u"",
185+ description="",
186 version=data['version'],
187 previous_series=previous_series,
188 registrant=self.user)
189@@ -765,7 +765,7 @@ class DistroSeriesInitializeView(LaunchpadFormView):
190 page_title = label
191
192 def initialize(self):
193- super(DistroSeriesInitializeView, self).initialize()
194+ super().initialize()
195 cache = IJSONRequestCache(self.request).objects
196 distribution = self.context.distribution
197 is_first_derivation = not distribution.has_published_sources
198@@ -778,7 +778,7 @@ class DistroSeriesInitializeView(LaunchpadFormView):
199 cache['previous_parents'] = [
200 seriesToVocab(series) for series in previous_parents]
201
202- @action(u"Initialize Series", name='initialize')
203+ @action("Initialize Series", name='initialize')
204 def submit(self, action, data):
205 """Stub for the Javascript in the page to use."""
206
207@@ -888,7 +888,7 @@ class IDifferencesFormSchema(Interface):
208 required=True)
209
210 sponsored_person = Choice(
211- title=u"Person being sponsored", vocabulary='ValidPerson',
212+ title="Person being sponsored", vocabulary='ValidPerson',
213 required=False)
214
215
216@@ -954,7 +954,7 @@ class DistroSeriesDifferenceBaseView(LaunchpadFormView,
217 As this field depends on other search/filtering field values
218 for its own vocabulary, we set it up after all the others.
219 """
220- super(DistroSeriesDifferenceBaseView, self).setUpFields()
221+ super().setUpFields()
222 self.form_fields = (
223 self.setupPackageFilterRadio() +
224 self.form_fields)
225@@ -1231,7 +1231,7 @@ class DistroSeriesLocalDifferencesView(DistroSeriesDifferenceBaseView,
226 parent_name,
227 self.context.displayname,
228 ))
229- super(DistroSeriesLocalDifferencesView, self).initialize()
230+ super().initialize()
231
232 @property
233 def explanation(self):
234@@ -1294,9 +1294,9 @@ class DistroSeriesLocalDifferencesView(DistroSeriesDifferenceBaseView,
235 copies, self.user, copy_policy=PackageCopyPolicy.MASS_SYNC)
236
237 self.request.response.addInfoNotification(
238- (u"Upgrades of {context.displayname} packages have been "
239- u"requested. Please give Launchpad some time to complete "
240- u"these.").format(context=self.context))
241+ ("Upgrades of {context.displayname} packages have been "
242+ "requested. Please give Launchpad some time to complete "
243+ "these.").format(context=self.context))
244
245 def canUpgrade(self, action=None):
246 """Should the form offer a packages upgrade?"""
247@@ -1330,7 +1330,7 @@ class DistroSeriesMissingPackagesView(DistroSeriesDifferenceBaseView,
248 "Include Selected packages into %s" % (
249 self.context.displayname,
250 ))
251- super(DistroSeriesMissingPackagesView, self).initialize()
252+ super().initialize()
253
254 @property
255 def explanation(self):
256@@ -1369,7 +1369,7 @@ class DistroSeriesUniquePackagesView(DistroSeriesDifferenceBaseView,
257 show_packagesets = True
258
259 def initialize(self):
260- super(DistroSeriesUniquePackagesView, self).initialize()
261+ super().initialize()
262
263 @property
264 def explanation(self):
265diff --git a/lib/lp/registry/browser/distroseriesdifference.py b/lib/lp/registry/browser/distroseriesdifference.py
266index 717cb88..ddcd915 100644
267--- a/lib/lp/registry/browser/distroseriesdifference.py
268+++ b/lib/lp/registry/browser/distroseriesdifference.py
269@@ -258,7 +258,7 @@ class DistroSeriesDifferenceDisplayComment(MessageComment):
270
271 def __init__(self, comment):
272 """Setup the attributes required by `IComment`."""
273- super(DistroSeriesDifferenceDisplayComment, self).__init__(None)
274+ super().__init__(None)
275 self.comment = comment
276 self._message = comment.message
277
278diff --git a/lib/lp/registry/browser/distroseriesdifferencecomment.py b/lib/lp/registry/browser/distroseriesdifferencecomment.py
279index 6d1a8a1..5bb0c86 100644
280--- a/lib/lp/registry/browser/distroseriesdifferencecomment.py
281+++ b/lib/lp/registry/browser/distroseriesdifferencecomment.py
282@@ -18,7 +18,6 @@ class DistroSeriesDifferenceCommentView(LaunchpadView):
283 """
284
285 def __init__(self, *args, **kwargs):
286- super(DistroSeriesDifferenceCommentView, self).__init__(
287- *args, **kwargs)
288+ super().__init__(*args, **kwargs)
289 error_persona = getUtility(ILaunchpadCelebrities).janitor
290 self.is_error = (self.context.comment_author == error_persona)
291diff --git a/lib/lp/registry/browser/featuredproject.py b/lib/lp/registry/browser/featuredproject.py
292index c77adcb..214eede 100644
293--- a/lib/lp/registry/browser/featuredproject.py
294+++ b/lib/lp/registry/browser/featuredproject.py
295@@ -34,7 +34,7 @@ class FeaturedProjectForm(Interface):
296 required=False, vocabulary='DistributionOrProductOrProjectGroup')
297
298 remove = Set(
299- title=u'Remove projects',
300+ title='Remove projects',
301 description=_(
302 'Select projects that you would like to remove from the list.'),
303 required=False,
304diff --git a/lib/lp/registry/browser/mailinglists.py b/lib/lp/registry/browser/mailinglists.py
305index ea8c6ed..bbc26a2 100644
306--- a/lib/lp/registry/browser/mailinglists.py
307+++ b/lib/lp/registry/browser/mailinglists.py
308@@ -28,7 +28,7 @@ class HeldMessageView(LaunchpadView):
309 """A little helper view for held messages."""
310
311 def __init__(self, context, request):
312- super(HeldMessageView, self).__init__(context, request)
313+ super().__init__(context, request)
314 self.context = context
315 self.request = request
316 # The context object is an IMessageApproval, but we need some extra
317@@ -74,16 +74,16 @@ class HeldMessageView(LaunchpadView):
318 else:
319 current_paragraph.append(line)
320 self._append_paragraph(paragraphs, current_paragraph)
321- self.body_details = u''.join(paragraphs)
322+ self.body_details = ''.join(paragraphs)
323
324 def _append_paragraph(self, paragraphs, current_paragraph):
325 if len(current_paragraph) == 0:
326 # There is nothing to append. The message has multiple
327 # blank lines.
328 return
329- paragraphs.append(u'\n<p>\n')
330- paragraphs.append(u'\n'.join(current_paragraph))
331- paragraphs.append(u'\n</p>\n')
332+ paragraphs.append('\n<p>\n')
333+ paragraphs.append('\n'.join(current_paragraph))
334+ paragraphs.append('\n</p>\n')
335
336 def _remove_leading_blank_lines(self):
337 """Strip off any leading blank lines.
338@@ -113,13 +113,13 @@ class HeldMessageView(LaunchpadView):
339 """
340 # If there are no non-blank lines, then we're done.
341 if len(text_lines) == 0:
342- self.body_summary = u''
343- return u''
344+ self.body_summary = ''
345+ return ''
346 # If the first line is of a completely arbitrarily chosen reasonable
347 # length, then we'll just use that as the summary.
348 elif len(text_lines[0]) < 60:
349 self.body_summary = text_lines[0]
350- return u'\n'.join(text_lines[1:])
351+ return '\n'.join(text_lines[1:])
352 # It could be the case that the text is actually flowed using RFC
353 # 3676 format="flowed" parameters. In that case, just split the line
354 # at the first whitespace after, again, our arbitrarily chosen limit.
355@@ -128,8 +128,8 @@ class HeldMessageView(LaunchpadView):
356 wrapper = TextWrapper(width=60)
357 filled_lines = wrapper.fill(first_line).splitlines()
358 self.body_summary = filled_lines[0]
359- text_lines.insert(0, u''.join(filled_lines[1:]))
360- return u'\n'.join(text_lines)
361+ text_lines.insert(0, ''.join(filled_lines[1:]))
362+ return '\n'.join(text_lines)
363
364
365 class enabled_with_active_mailing_list:
366diff --git a/lib/lp/registry/browser/milestone.py b/lib/lp/registry/browser/milestone.py
367index 3d2724e..375f5e4 100644
368--- a/lib/lp/registry/browser/milestone.py
369+++ b/lib/lp/registry/browser/milestone.py
370@@ -194,7 +194,7 @@ class MilestoneInlineNavigationMenu(NavigationMenu, MilestoneLinkMixin):
371 links = ('edit', )
372
373
374-class MilestoneViewMixin(object):
375+class MilestoneViewMixin:
376 """Common methods shared between MilestoneView and MilestoneTagView."""
377
378 @property
379@@ -366,7 +366,7 @@ class MilestoneView(
380 :param context: `IMilestone` or `IProductRelease`.
381 :param request: `ILaunchpadRequest`.
382 """
383- super(MilestoneView, self).__init__(context, request)
384+ super().__init__(context, request)
385 if IMilestoneData.providedBy(context):
386 self.milestone = context
387 self.release = getattr(context, "product_release", None)
388@@ -431,7 +431,7 @@ class MilestoneTagBase:
389 on the interface.
390 """
391 tag_entry = TextLine(
392- __name__='tags', title=u'Tags', required=False,
393+ __name__='tags', title='Tags', required=False,
394 constraint=lambda value: validate_tags(value.split()))
395 self.form_fields += form.Fields(
396 tag_entry, render_context=self.render_context)
397@@ -512,7 +512,7 @@ class MilestoneEditView(MilestoneTagBase, LaunchpadEditFormView):
398
399 @property
400 def initial_values(self):
401- return {'tags': u' '.join(self.context.getTags())}
402+ return {'tags': ' '.join(self.context.getTags())}
403
404 def setUpFields(self):
405 """See `LaunchpadFormView`.
406@@ -521,7 +521,7 @@ class MilestoneEditView(MilestoneTagBase, LaunchpadEditFormView):
407 create the milestone, but once a series field is set, None is invalid.
408 The choice for the series is redefined to ensure None is not included.
409 """
410- super(MilestoneEditView, self).setUpFields()
411+ super().setUpFields()
412 if self.context.product is None:
413 # This is a distribution milestone.
414 choice = Choice(
415@@ -538,7 +538,7 @@ class MilestoneEditView(MilestoneTagBase, LaunchpadEditFormView):
416 @action(_('Update'), name='update')
417 def update_action(self, action, data):
418 """Update the milestone."""
419- tags = data.pop('tags') or u''
420+ tags = data.pop('tags') or ''
421 self.updateContextFromData(data)
422 self.context.setTags(tags.lower().split(), self.user)
423 self.next_url = canonical_url(self.context)
424@@ -611,17 +611,17 @@ class MilestoneTagView(
425 :param context: `IProjectGroupMilestoneTag`
426 :param request: `ILaunchpadRequest`.
427 """
428- super(MilestoneTagView, self).__init__(context, request)
429+ super().__init__(context, request)
430 self.context = self.milestone = context
431 self.release = None
432
433 @property
434 def initial_values(self):
435 """Set the initial value of the search tags field."""
436- return {'tags': u' '.join(self.context.tags)}
437+ return {'tags': ' '.join(self.context.tags)}
438
439 @safe_action
440- @action(u'Search Milestone Tags', name='search')
441+ @action('Search Milestone Tags', name='search')
442 def search_by_tags(self, action, data):
443 tags = data['tags'].split()
444 milestone_tag = ProjectGroupMilestoneTag(self.context.target, tags)
445diff --git a/lib/lp/registry/browser/objectreassignment.py b/lib/lp/registry/browser/objectreassignment.py
446index 79c0ddf..014f9a2 100644
447--- a/lib/lp/registry/browser/objectreassignment.py
448+++ b/lib/lp/registry/browser/objectreassignment.py
449@@ -72,7 +72,7 @@ class ObjectReassignmentView(LaunchpadFormView):
450 page_title = label
451
452 def setUpFields(self):
453- super(ObjectReassignmentView, self).setUpFields()
454+ super().setUpFields()
455 self.form_fields = FormFields(
456 self.form_fields, self.auto_create_team_field)
457
458diff --git a/lib/lp/registry/browser/ociproject.py b/lib/lp/registry/browser/ociproject.py
459index 55f2d61..85a1c00 100644
460--- a/lib/lp/registry/browser/ociproject.py
461+++ b/lib/lp/registry/browser/ociproject.py
462@@ -93,7 +93,7 @@ class OCIProjectURL:
463 if (policy == DistributionDefaultTraversalPolicy.OCI_PROJECT and
464 not self.context.distribution.redirect_default_traversal):
465 return self.context.name
466- return u"+oci/%s" % self.context.name
467+ return "+oci/%s" % self.context.name
468
469
470 def getPillarFieldName(pillar):
471@@ -114,7 +114,7 @@ class OCIProjectAddView(LaunchpadFormView):
472 if (not getFeatureFlag(OCI_PROJECT_ALLOW_CREATE) and not
473 self.context.canAdministerOCIProjects(self.user)):
474 raise OCIProjectCreateFeatureDisabled
475- super(OCIProjectAddView, self).initialize()
476+ super().initialize()
477
478 @action("Create OCI Project", name="create")
479 def create_action(self, action, data):
480@@ -129,7 +129,7 @@ class OCIProjectAddView(LaunchpadFormView):
481 self.next_url = canonical_url(oci_project)
482
483 def validate(self, data):
484- super(OCIProjectAddView, self).validate(data)
485+ super().validate(data)
486 name = data.get('name', None)
487 oci_project_name = getUtility(
488 IOCIProjectNameSet).getOrCreateByName(name)
489@@ -289,7 +289,7 @@ class OCIProjectEditView(LaunchpadEditFormView):
490 pillar_key = getPillarFieldName(self.context.pillar)
491 self.field_names = [pillar_key] + self.field_names
492
493- super(OCIProjectEditView, self).setUpFields()
494+ super().setUpFields()
495
496 # Set the correct pillar field as mandatory
497 pillar_field = self.form_fields.get(pillar_key).field
498@@ -302,7 +302,7 @@ class OCIProjectEditView(LaunchpadEditFormView):
499 page_title = 'Edit'
500
501 def validate(self, data):
502- super(OCIProjectEditView, self).validate(data)
503+ super().validate(data)
504 pillar_type_field = getPillarFieldName(self.context.pillar)
505 pillar = data.get(pillar_type_field)
506 name = data.get('name')
507diff --git a/lib/lp/registry/browser/peoplemerge.py b/lib/lp/registry/browser/peoplemerge.py
508index eb15d67..f37f6da 100644
509--- a/lib/lp/registry/browser/peoplemerge.py
510+++ b/lib/lp/registry/browser/peoplemerge.py
511@@ -123,7 +123,7 @@ class AdminMergeBaseView(ValidatingMergeView):
512 # only in certain circunstances, so don't include them in the list of
513 # actions to be rendered.
514 self.actions = [self.merge_action]
515- return super(AdminMergeBaseView, self).render()
516+ return super().render()
517
518 def setUpPeople(self, data):
519 """Store the people to be merged in instance variables.
520@@ -224,7 +224,7 @@ class AdminTeamMergeView(AdminMergeBaseView):
521 if len(self.errors) > 0:
522 return
523
524- super(AdminTeamMergeView, self).validate(data)
525+ super().validate(data)
526 dupe_team = data['dupe_person']
527 # We cannot merge the teams if there is a mailing list on the
528 # duplicate person, unless that mailing list is purged.
529@@ -248,14 +248,14 @@ class AdminTeamMergeView(AdminMergeBaseView):
530 # merge.
531 self.should_confirm_member_deactivation = True
532 return
533- super(AdminTeamMergeView, self).doMerge(data)
534+ super().doMerge(data)
535
536 @action('Deactivate Members and Merge',
537 name='deactivate_members_and_merge')
538 def deactivate_members_and_merge_action(self, action, data):
539 """Deactivate all members of the team to be merged and merge them."""
540 self.setUpPeople(data)
541- super(AdminTeamMergeView, self).doMerge(data)
542+ super().doMerge(data)
543
544
545 class DeleteTeamView(AdminTeamMergeView):
546@@ -270,7 +270,7 @@ class DeleteTeamView(AdminTeamMergeView):
547 return 'Delete %s' % self.context.displayname
548
549 def __init__(self, context, request):
550- super(DeleteTeamView, self).__init__(context, request)
551+ super().__init__(context, request)
552 if ('field.dupe_person' in self.request.form):
553 # These fields have fixed values and are managed by this method.
554 # The user has crafted a request to gain ownership of the dupe
555@@ -311,9 +311,8 @@ class DeleteTeamView(AdminTeamMergeView):
556
557 @action('Delete', name='delete', condition=canDelete)
558 def merge_action(self, action, data):
559- base = super(DeleteTeamView, self)
560 self.delete = True
561- base.deactivate_members_and_merge_action.success(data)
562+ super().deactivate_members_and_merge_action.success(data)
563
564
565 class FinishedPeopleMergeRequestView(LaunchpadView):
566@@ -361,8 +360,7 @@ class RequestPeopleMergeMultipleEmailsView(LaunchpadView):
567 page_title = label
568
569 def __init__(self, context, request):
570- super(RequestPeopleMergeMultipleEmailsView, self).__init__(
571- context, request)
572+ super().__init__(context, request)
573 self.form_processed = False
574 self.dupe = None
575 self.notified_addresses = []
576diff --git a/lib/lp/registry/browser/person.py b/lib/lp/registry/browser/person.py
577index 7cf2fcb..ccd09c7 100644
578--- a/lib/lp/registry/browser/person.py
579+++ b/lib/lp/registry/browser/person.py
580@@ -65,7 +65,6 @@ from lazr.restful.interfaces import IWebServiceClientRequest
581 from lazr.restful.utils import smartquote
582 from lazr.uri import URI
583 import pytz
584-import six
585 from six.moves.urllib.parse import (
586 quote,
587 urlencode,
588@@ -470,7 +469,7 @@ class BranchTraversalMixin:
589 branch = getUtility(IBranchNamespaceSet).traverse(
590 self._getSegments(pillar_name))
591 except (NotFoundError, InvalidNamespace):
592- return super(BranchTraversalMixin, self).traverse(pillar_name)
593+ return super().traverse(pillar_name)
594
595 # Normally, populating the launch bag is done by the traversal
596 # mechanism. However, here we short-circuit that mechanism by
597@@ -905,8 +904,8 @@ class PersonOverviewMenu(ApplicationMenu, PersonMenuMixin, HasRecipesMenuMixin,
598 target = '+karma'
599 text = 'Show karma summary'
600 summary = (
601- u'%s\N{right single quotation mark}s activities '
602- u'in Launchpad' % self.context.displayname)
603+ '%s\N{right single quotation mark}s activities '
604+ 'in Launchpad' % self.context.displayname)
605 return Link(target, text, summary, icon='info')
606
607 def memberships(self):
608@@ -1034,7 +1033,7 @@ class PeopleSearchView(LaunchpadView):
609 page_title = 'People and teams in Launchpad'
610
611 def __init__(self, context, request):
612- super(PeopleSearchView, self).__init__(context, request)
613+ super().__init__(context, request)
614 self.results = []
615
616 @property
617@@ -1092,7 +1091,7 @@ class PersonDeactivateAccountView(LaunchpadFormView):
618 getUtility(IPersonDeactivateJobSource).create(self.context)
619 logoutPerson(self.request)
620 self.request.response.addInfoNotification(
621- _(u'Your account has been deactivated.'))
622+ _('Your account has been deactivated.'))
623 self.next_url = self.request.getApplicationURL()
624
625
626@@ -1237,7 +1236,7 @@ class PersonRenameFormMixin(LaunchpadEditFormView):
627 if reason:
628 # This makes the field's widget display (i.e. read) only.
629 self.form_fields['name'].for_display = True
630- super(PersonRenameFormMixin, self).setUpWidgets()
631+ super().setUpWidgets()
632 if reason:
633 self.widgets['name'].hint = reason
634
635@@ -1319,7 +1318,7 @@ class PersonAccountAdministerView(LaunchpadFormView):
636
637 def __init__(self, context, request):
638 """See `LaunchpadEditFormView`."""
639- super(PersonAccountAdministerView, self).__init__(context, request)
640+ super().__init__(context, request)
641 # Only the IPerson can be traversed to, so it provides the IAccount.
642 # It also means that permissions are checked on IAccount, not IPerson.
643 self.person = self.context
644@@ -1376,18 +1375,18 @@ class PersonAccountAdministerView(LaunchpadFormView):
645 # is sent to the user.
646 self.person.setPreferredEmail(None)
647 self.request.response.addInfoNotification(
648- u'The account "%s" has been suspended.'
649+ 'The account "%s" has been suspended.'
650 % self.context.displayname)
651 elif data['status'] == AccountStatus.DEACTIVATED:
652 self.request.response.addInfoNotification(
653- u'The account "%s" is now deactivated. The user can log in '
654- u'to reactivate it.' % self.context.displayname)
655+ 'The account "%s" is now deactivated. The user can log in '
656+ 'to reactivate it.' % self.context.displayname)
657 elif data['status'] == AccountStatus.DECEASED:
658 # Deliberately leave the email address in place so that it can't
659 # easily be claimed by somebody else.
660 self.request.response.addInfoNotification(
661- u'The account "%s" has been marked as having belonged to a '
662- u'deceased user.' % self.context.displayname)
663+ 'The account "%s" has been marked as having belonged to a '
664+ 'deceased user.' % self.context.displayname)
665 self.context.setStatus(data['status'], self.user, data['comment'])
666
667
668@@ -1464,7 +1463,7 @@ class PersonLanguagesView(LaunchpadFormView):
669 new_languages = []
670
671 for key in all_languages.keys():
672- if self.request.get(key, None) == u'on':
673+ if self.request.get(key, None) == 'on':
674 new_languages.append(all_languages[key])
675
676 if self.is_current_user:
677@@ -2128,7 +2127,7 @@ class PersonIndexView(XRDSContentNegotiationMixin, PersonView,
678 "../../services/openid/templates/person-xrds.pt")
679
680 def initialize(self):
681- super(PersonIndexView, self).initialize()
682+ super().initialize()
683 if self.context.isMergePending():
684 if self.context.is_team:
685 merge_action = 'merged or deleted'
686@@ -2225,7 +2224,7 @@ class PersonCodeOfConductEditView(LaunchpadView):
687 for sig_id in sig_ids:
688 sig_id = int(sig_id)
689 # Deactivating signature.
690- comment = u'Deactivated by Owner'
691+ comment = 'Deactivated by Owner'
692 sCoC_util.modifySignature(sig_id, self.user, comment, False)
693
694
695@@ -2285,7 +2284,7 @@ class PersonEditJabberIDsView(LaunchpadFormView):
696 field_names = ['jabberid']
697
698 def setUpFields(self):
699- super(PersonEditJabberIDsView, self).setUpFields()
700+ super().setUpFields()
701 if not self.context.jabberids.is_empty():
702 # Make the jabberid entry optional on the edit page if one or more
703 # ids already exist, which allows the removal of ids without
704@@ -2422,7 +2421,7 @@ class PersonGPGView(LaunchpadView):
705
706 def initialize(self):
707 require_fresh_login(self.request, self.context, '+editpgpkeys')
708- super(PersonGPGView, self).initialize()
709+ super().initialize()
710
711 @property
712 def cancel_url(self):
713@@ -2725,7 +2724,7 @@ class PersonEditEmailsView(LaunchpadFormView):
714 # +editemails is not available on teams.
715 name = self.request['PATH_INFO'].split('/')[-1]
716 raise NotFound(self, name, request=self.request)
717- super(PersonEditEmailsView, self).initialize()
718+ super().initialize()
719
720 def setUpFields(self):
721 """Set up fields for this view.
722@@ -2734,11 +2733,11 @@ class PersonEditEmailsView(LaunchpadFormView):
723 vocabularies for the lists of validated and unvalidated email
724 addresses.
725 """
726- super(PersonEditEmailsView, self).setUpFields()
727+ super().setUpFields()
728 self.form_fields = (self._validated_emails_field() +
729 self._unvalidated_emails_field() +
730 FormFields(TextLine(__name__='newemail',
731- title=u'Add a new address')))
732+ title='Add a new address')))
733
734 @property
735 def initial_values(self):
736@@ -2786,7 +2785,7 @@ class PersonEditEmailsView(LaunchpadFormView):
737 """
738 terms = []
739 for term in self.unvalidated_addresses:
740- if isinstance(term, six.text_type):
741+ if isinstance(term, str):
742 term = SimpleTerm(term)
743 else:
744 term = SimpleTerm(term, term.email)
745@@ -2827,7 +2826,7 @@ class PersonEditEmailsView(LaunchpadFormView):
746 "self.context.id(%s,%d) (%s)"
747 % (person.name, person.id, self.context.name, self.context.id,
748 email.email))
749- elif isinstance(email, six.text_type):
750+ elif isinstance(email, str):
751 tokenset = getUtility(ILoginTokenSet)
752 email = tokenset.searchByEmailRequesterAndType(
753 email, self.context, LoginTokenType.VALIDATEEMAIL)
754@@ -2953,7 +2952,7 @@ class PersonEditEmailsView(LaunchpadFormView):
755 if IEmailAddress.providedBy(emailaddress):
756 emailaddress.destroySelf()
757 email = emailaddress.email
758- elif isinstance(emailaddress, six.text_type):
759+ elif isinstance(emailaddress, str):
760 logintokenset = getUtility(ILoginTokenSet)
761 logintokenset.deleteByEmailRequesterAndType(
762 emailaddress, self.context, LoginTokenType.VALIDATEEMAIL)
763@@ -3049,7 +3048,7 @@ class PersonEditMailingListsView(LaunchpadFormView):
764 # +editmailinglists is not available on teams.
765 name = self.request['PATH_INFO'].split('/')[-1]
766 raise NotFound(self, name, request=self.request)
767- super(PersonEditMailingListsView, self).initialize()
768+ super().initialize()
769
770 def setUpFields(self):
771 """Set up fields for this view.
772@@ -3058,7 +3057,7 @@ class PersonEditMailingListsView(LaunchpadFormView):
773 vocabularies for the lists of validated and unvalidated email
774 addresses.
775 """
776- super(PersonEditMailingListsView, self).setUpFields()
777+ super().setUpFields()
778 self.form_fields = (self._mailing_list_fields()
779 + self._autosubscribe_policy_fields())
780
781@@ -3081,7 +3080,7 @@ class PersonEditMailingListsView(LaunchpadFormView):
782
783 def setUpWidgets(self, context=None):
784 """See `LaunchpadFormView`."""
785- super(PersonEditMailingListsView, self).setUpWidgets(context)
786+ super().setUpWidgets(context)
787 widget = self.widgets['mailing_list_auto_subscribe_policy']
788 widget.display_label = False
789
790@@ -3679,7 +3678,7 @@ class PersonOCIRegistryCredentialsView(LaunchpadView):
791 def initialize(self):
792 if not user_can_edit_credentials_for_owner(self.context, self.user):
793 raise Unauthorized
794- super(PersonOCIRegistryCredentialsView, self).initialize()
795+ super().initialize()
796
797 @property
798 def label(self):
799@@ -3712,7 +3711,7 @@ class PersonEditOCIRegistryCredentialsView(LaunchpadFormView):
800 def initialize(self):
801 if not user_can_edit_credentials_for_owner(self.context, self.user):
802 raise Unauthorized
803- super(PersonEditOCIRegistryCredentialsView, self).initialize()
804+ super().initialize()
805
806 def _getFieldName(self, name, credentials_id):
807 """Get the combined field name for an `OCIRegistryCredentials` ID.
808@@ -3764,25 +3763,25 @@ class PersonEditOCIRegistryCredentialsView(LaunchpadFormView):
809
810 def getAddFieldsRow(self):
811 add_url = TextLine(
812- __name__=u'add_url',
813+ __name__='add_url',
814 required=False, readonly=False)
815 add_region = TextLine(
816- __name__=u'add_region',
817+ __name__='add_region',
818 required=False, readonly=False)
819 add_owner = Choice(
820- __name__=u'add_owner',
821+ __name__='add_owner',
822 vocabulary=(
823 'AllUserTeamsParticipationPlusSelfSimpleDisplay'),
824 default=self.default_owner,
825 required=False, readonly=False)
826 add_username = TextLine(
827- __name__=u'add_username',
828+ __name__='add_username',
829 required=False, readonly=False)
830 add_password = Password(
831- __name__=u'add_password',
832+ __name__='add_password',
833 required=False, readonly=False)
834 add_confirm_password = Password(
835- __name__=u'add_confirm_password',
836+ __name__='add_confirm_password',
837 required=False, readonly=False)
838
839 return (
840@@ -3819,8 +3818,7 @@ class PersonEditOCIRegistryCredentialsView(LaunchpadFormView):
841 self.form_fields += FormFields(*add_fields)
842
843 def setUpWidgets(self, context=None):
844- super(PersonEditOCIRegistryCredentialsView, self).setUpWidgets(
845- context=context)
846+ super().setUpWidgets(context=context)
847 for widget in self.widgets:
848 widget.display_label = False
849 widget.hint = None
850@@ -4249,19 +4247,16 @@ class ContactViaWebNotificationRecipientSet:
851
852 def getEmails(self):
853 """See `INotificationRecipientSet`."""
854- for email in sorted(self._all_recipients.keys()):
855- yield email
856+ yield from sorted(self._all_recipients.keys())
857
858 def getRecipients(self):
859 """See `INotificationRecipientSet`."""
860- for recipient in sorted(
861- self._all_recipients.values(), key=attrgetter('displayname')):
862- yield recipient
863+ yield from sorted(
864+ self._all_recipients.values(), key=attrgetter('displayname'))
865
866 def getRecipientPersons(self):
867 """See `INotificationRecipientSet`."""
868- for email, person in self._all_recipients.items():
869- yield (email, person)
870+ yield from self._all_recipients.items()
871
872 def __iter__(self):
873 """See `INotificationRecipientSet`."""
874@@ -4351,7 +4346,7 @@ class EmailToPersonView(LaunchpadFormView):
875 a vocabulary of the user's preferred (first) and validated
876 (subsequent) email addresses.
877 """
878- super(EmailToPersonView, self).setUpFields()
879+ super().setUpFields()
880 usable_addresses = [self.user.preferredemail]
881 usable_addresses.extend(self.user.validatedemails)
882 terms = [SimpleTerm(email, email.email) for email in usable_addresses]
883diff --git a/lib/lp/registry/browser/pillar.py b/lib/lp/registry/browser/pillar.py
884index 4c09eb2..3f5c29d 100644
885--- a/lib/lp/registry/browser/pillar.py
886+++ b/lib/lp/registry/browser/pillar.py
887@@ -164,7 +164,7 @@ class PillarInvolvementView(LaunchpadView):
888 visible_disabled_link_names = []
889
890 def __init__(self, context, request):
891- super(PillarInvolvementView, self).__init__(context, request)
892+ super().__init__(context, request)
893 self.official_malone = False
894 self.answers_usage = ServiceUsage.UNKNOWN
895 self.blueprints_usage = ServiceUsage.UNKNOWN
896@@ -278,7 +278,7 @@ class PillarViewMixin():
897 def initialize(self):
898 # Insert close team membership policy data into the json cache.
899 # This data is used for the maintainer and driver pickers.
900- super(PillarViewMixin, self).initialize()
901+ super().initialize()
902 cache = IJSONRequestCache(self.request)
903 policy_items = [(item.name, item) for item in EXCLUSIVE_TEAM_POLICY]
904 team_membership_policy_data = vocabulary_to_choice_edit_items(
905@@ -365,7 +365,7 @@ class PillarSharingView(LaunchpadView):
906 return self._getSharingService().getPillarGrantees(self.context)
907
908 def initialize(self):
909- super(PillarSharingView, self).initialize()
910+ super().initialize()
911 cache = IJSONRequestCache(self.request)
912 cache.objects['information_types'] = self.information_types
913 cache.objects['sharing_permissions'] = self.sharing_permissions
914diff --git a/lib/lp/registry/browser/poll.py b/lib/lp/registry/browser/poll.py
915index eaba0c7..66049fe 100644
916--- a/lib/lp/registry/browser/poll.py
917+++ b/lib/lp/registry/browser/poll.py
918@@ -227,7 +227,7 @@ class PollView(BasePollView):
919 """A view class to display the results of a poll."""
920
921 def initialize(self):
922- super(PollView, self).initialize()
923+ super().initialize()
924 request = self.request
925 if (self.userCanVote() and self.context.isOpen() and
926 self.context.getActiveOptions()):
927@@ -281,7 +281,7 @@ class PollVoteView(BasePollView):
928
929 def initialize(self):
930 """Process the form, if it was submitted."""
931- super(PollVoteView, self).initialize()
932+ super().initialize()
933 if not self.isSecret() and self.userVoted():
934 # For non-secret polls, the user's vote is always displayed
935 self.setUpTokenAndVotesForNonSecretPolls()
936diff --git a/lib/lp/registry/browser/product.py b/lib/lp/registry/browser/product.py
937index 3f58926..faea1f8 100644
938--- a/lib/lp/registry/browser/product.py
939+++ b/lib/lp/registry/browser/product.py
940@@ -517,7 +517,7 @@ class ProductEditLinksMixin(StructuralSubscriptionMenuMixin):
941 def search_oci_project(self):
942 product = self.context.context
943 oci_projects = getUtility(IOCIProjectSet).findByPillarAndName(
944- product, u'')
945+ product, '')
946 text = 'Search for OCI project'
947 link = Link('+search-oci-project', text, icon='info')
948 link.enabled = not oci_projects.is_empty()
949@@ -807,7 +807,7 @@ class SeriesWithReleases(DecoratedSeries):
950 releases = None
951
952 def __init__(self, series, parent):
953- super(SeriesWithReleases, self).__init__(series)
954+ super().__init__(series)
955 self.parent = parent
956 self.releases = []
957
958@@ -987,7 +987,7 @@ class ProductView(PillarViewMixin, HasAnnouncementsView, SortSeriesMixin,
959 self.form = request.form_ng
960
961 def initialize(self):
962- super(ProductView, self).initialize()
963+ super().initialize()
964 self.status_message = None
965 product = self.context
966 programming_lang = IProduct['programminglang']
967@@ -1370,7 +1370,7 @@ class ProductConfigureBase(ReturnToReferrerMixin, LaunchpadEditFormView):
968 usage_fieldname = None
969
970 def setUpFields(self):
971- super(ProductConfigureBase, self).setUpFields()
972+ super().setUpFields()
973 if self.usage_fieldname is not None:
974 # The usage fields are shared among pillars. But when referring
975 # to an individual object in Launchpad it is better to call it by
976@@ -1474,7 +1474,7 @@ class ProductEditView(ProductLicenseMixin, LaunchpadEditFormView):
977 # when an action is invoked.
978 cache = IJSONRequestCache(self.request)
979 json_dump_information_types(cache, PILLAR_INFORMATION_TYPES)
980- super(ProductEditView, self).initialize()
981+ super().initialize()
982
983 def validate(self, data):
984 """Validate 'licenses' and 'license_info'.
985@@ -1485,7 +1485,7 @@ class ProductEditView(ProductLicenseMixin, LaunchpadEditFormView):
986 'license_info' must not be empty if "Other/Proprietary"
987 or "Other/Open Source" is checked.
988 """
989- super(ProductEditView, self).validate(data)
990+ super().validate(data)
991 information_type = data.get('information_type')
992 if information_type:
993 errors = [
994@@ -1502,7 +1502,7 @@ class ProductEditView(ProductLicenseMixin, LaunchpadEditFormView):
995 # LicenseWidget instead of the enclosing form.
996 if field_name == 'license_info':
997 return False
998- return super(ProductEditView, self).showOptionalMarker(field_name)
999+ return super().showOptionalMarker(field_name)
1000
1001 @action("Change", name='change')
1002 def change_action(self, action, data):
1003@@ -1550,7 +1550,7 @@ class ProductAdminView(ProductEditView, ProductValidationMixin):
1004 if not admin:
1005 self.field_names.remove('owner')
1006 self.field_names.remove('autoupdate')
1007- super(ProductAdminView, self).setUpFields()
1008+ super().setUpFields()
1009 self.form_fields = self._createAliasesField() + self.form_fields
1010 if admin:
1011 self.form_fields = (
1012@@ -1590,7 +1590,7 @@ class ProductAdminView(ProductEditView, ProductValidationMixin):
1013
1014 def validate(self, data):
1015 """See `LaunchpadFormView`."""
1016- super(ProductAdminView, self).validate(data)
1017+ super().validate(data)
1018 self.validate_deactivation(data)
1019
1020 @property
1021@@ -1618,7 +1618,7 @@ class ProductReviewLicenseView(ReturnToReferrerMixin, ProductEditView,
1022 def validate(self, data):
1023 """See `LaunchpadFormView`."""
1024
1025- super(ProductReviewLicenseView, self).validate(data)
1026+ super().validate(data)
1027 # A project can only be approved if it has OTHER_OPEN_SOURCE as one of
1028 # its licenses and not OTHER_PROPRIETARY.
1029 licenses = self.context.licenses
1030@@ -1848,11 +1848,11 @@ class ProductSetBranchView(ReturnToReferrerMixin, LaunchpadFormView,
1031 """
1032 if self.errors_in_action:
1033 return None
1034- return super(ProductSetBranchView, self).next_url
1035+ return super().next_url
1036
1037 def setUpFields(self):
1038 """See `LaunchpadFormView`."""
1039- super(ProductSetBranchView, self).setUpFields()
1040+ super().setUpFields()
1041 if self.is_series:
1042 self.form_fields = self.form_fields.omit(
1043 'default_vcs', 'git_repository_location',
1044@@ -1861,7 +1861,7 @@ class ProductSetBranchView(ReturnToReferrerMixin, LaunchpadFormView,
1045
1046 def setUpWidgets(self):
1047 """See `LaunchpadFormView`."""
1048- super(ProductSetBranchView, self).setUpWidgets()
1049+ super().setUpWidgets()
1050 widget = self.widgets['rcs_type']
1051 vocab = widget.vocabulary
1052 current_value = widget._getFormValue()
1053@@ -1878,9 +1878,9 @@ class ProductSetBranchView(ReturnToReferrerMixin, LaunchpadFormView,
1054 widget = self.widgets['branch_type']
1055 current_value = widget._getFormValue()
1056 vocab = widget.vocabulary
1057- self.branch_type_link, self.branch_type_import = [
1058+ self.branch_type_link, self.branch_type_import = (
1059 render_radio_widget_part(widget, value, current_value)
1060- for value in (LINK_LP, IMPORT_EXTERNAL)]
1061+ for value in (LINK_LP, IMPORT_EXTERNAL))
1062
1063 if not self.is_series:
1064 widget = self.widgets['default_vcs']
1065@@ -1894,9 +1894,9 @@ class ProductSetBranchView(ReturnToReferrerMixin, LaunchpadFormView,
1066 widget = self.widgets['git_repository_type']
1067 current_value = widget._getFormValue()
1068 vocab = widget.vocabulary
1069- self.git_repository_type_link, self.git_repository_type_import = [
1070+ self.git_repository_type_link, self.git_repository_type_import = (
1071 render_radio_widget_part(widget, value, current_value)
1072- for value in (LINK_LP, IMPORT_EXTERNAL)]
1073+ for value in (LINK_LP, IMPORT_EXTERNAL))
1074
1075 def _validateLinkLpBzr(self, data):
1076 """Validate data for link-lp bzr case."""
1077@@ -2005,7 +2005,7 @@ class ProductSetBranchView(ReturnToReferrerMixin, LaunchpadFormView,
1078 """See `LaunchpadFormView`."""
1079 names = [
1080 'branch_type', 'rcs_type', 'default_vcs', 'git_repository_type']
1081- super(ProductSetBranchView, self).validate_widgets(data, names)
1082+ super().validate_widgets(data, names)
1083
1084 if not self.is_series:
1085 git_repository_type = data.get('git_repository_type')
1086@@ -2040,7 +2040,7 @@ class ProductSetBranchView(ReturnToReferrerMixin, LaunchpadFormView,
1087 raise AssertionError("Unknown branch type %s" % branch_type)
1088
1089 # Perform full validation now.
1090- super(ProductSetBranchView, self).validate_widgets(data)
1091+ super().validate_widgets(data)
1092
1093 def validate(self, data):
1094 """See `LaunchpadFormView`."""
1095@@ -2345,12 +2345,12 @@ class ProjectAddStepOne(StepView):
1096
1097 def setUpFields(self):
1098 """See `LaunchpadFormView`."""
1099- super(ProjectAddStepOne, self).setUpFields()
1100+ super().setUpFields()
1101 self.form_fields = (self.form_fields + create_source_package_fields())
1102
1103 def setUpWidgets(self):
1104 """See `LaunchpadFormView`."""
1105- super(ProjectAddStepOne, self).setUpWidgets()
1106+ super().setUpWidgets()
1107 self.widgets['source_package_name'].visible = False
1108 self.widgets['distroseries'].visible = False
1109
1110@@ -2425,14 +2425,14 @@ class ProjectAddStepTwo(StepView, ProductLicenseMixin, ReturnToReferrerMixin):
1111 # when an action is invoked.
1112 cache = IJSONRequestCache(self.request)
1113 json_dump_information_types(cache, PILLAR_INFORMATION_TYPES)
1114- super(ProjectAddStepTwo, self).initialize()
1115+ super().initialize()
1116
1117 @property
1118 def main_action_label(self):
1119 if self.source_package_name is None:
1120- return u'Complete Registration'
1121+ return 'Complete Registration'
1122 else:
1123- return u'Complete registration and link to %s package' % (
1124+ return 'Complete registration and link to %s package' % (
1125 self.source_package_name.name)
1126
1127 @property
1128@@ -2467,7 +2467,7 @@ class ProjectAddStepTwo(StepView, ProductLicenseMixin, ReturnToReferrerMixin):
1129
1130 def setUpFields(self):
1131 """See `LaunchpadFormView`."""
1132- super(ProjectAddStepTwo, self).setUpFields()
1133+ super().setUpFields()
1134 hidden_names = ['__visited_steps__', 'license_info']
1135 hidden_fields = self.form_fields.select(*hidden_names)
1136
1137@@ -2502,7 +2502,7 @@ class ProjectAddStepTwo(StepView, ProductLicenseMixin, ReturnToReferrerMixin):
1138
1139 def setUpWidgets(self):
1140 """See `LaunchpadFormView`."""
1141- super(ProjectAddStepTwo, self).setUpWidgets()
1142+ super().setUpWidgets()
1143 self.widgets['name'].read_only = True
1144 # The "hint" is really more of an explanation at this point, but the
1145 # phrasing is different.
1146diff --git a/lib/lp/registry/browser/productrelease.py b/lib/lp/registry/browser/productrelease.py
1147index 9bb9242..ac680b8 100644
1148--- a/lib/lp/registry/browser/productrelease.py
1149+++ b/lib/lp/registry/browser/productrelease.py
1150@@ -167,10 +167,10 @@ class ProductReleaseAddView(ProductReleaseAddViewBase):
1151 self.request.response.redirect(
1152 canonical_url(self.context.product_release) + '/+edit')
1153 else:
1154- super(ProductReleaseAddView, self).initialize()
1155+ super().initialize()
1156
1157 def setUpFields(self):
1158- super(ProductReleaseAddView, self).setUpFields()
1159+ super().setUpFields()
1160 if self.context.active is True:
1161 self._prependKeepMilestoneActiveField()
1162
1163@@ -193,7 +193,7 @@ class ProductReleaseFromSeriesAddView(ProductReleaseAddViewBase,
1164 ]
1165
1166 def setUpFields(self):
1167- super(ProductReleaseFromSeriesAddView, self).setUpFields()
1168+ super().setUpFields()
1169 self._prependKeepMilestoneActiveField()
1170 self._prependMilestoneField()
1171
1172@@ -288,7 +288,7 @@ class ProductReleaseAddDownloadFileView(LaunchpadFormView):
1173 if file_name and self.context.hasReleaseFile(file_name):
1174 self.setFieldError(
1175 'filecontent',
1176- u"The file '%s' is already uploaded." % file_name)
1177+ "The file '%s' is already uploaded." % file_name)
1178
1179 @action('Upload', name='add')
1180 def add_action(self, action, data):
1181diff --git a/lib/lp/registry/browser/productseries.py b/lib/lp/registry/browser/productseries.py
1182index 8af4afb..707b077 100644
1183--- a/lib/lp/registry/browser/productseries.py
1184+++ b/lib/lp/registry/browser/productseries.py
1185@@ -197,7 +197,7 @@ class ProductSeriesInvolvementView(PillarInvolvementView):
1186 has_involvement = True
1187
1188 def __init__(self, context, request):
1189- super(ProductSeriesInvolvementView, self).__init__(context, request)
1190+ super().__init__(context, request)
1191 self.answers_usage = ServiceUsage.NOT_APPLICABLE
1192 if self.context.branch is not None:
1193 self.codehosting_usage = ServiceUsage.LAUNCHPAD
1194@@ -370,7 +370,7 @@ class ProductSeriesView(
1195 """A view to show a series with translations."""
1196
1197 def initialize(self):
1198- super(ProductSeriesView, self).initialize()
1199+ super().initialize()
1200 expose_structural_subscription_data_to_js(
1201 self.context, self.request, self.user)
1202
1203@@ -506,8 +506,7 @@ class ProductSeriesUbuntuPackagingView(LaunchpadFormView):
1204
1205 def __init__(self, context, request):
1206 """Set the static packaging information for this series."""
1207- super(ProductSeriesUbuntuPackagingView, self).__init__(
1208- context, request)
1209+ super().__init__(context, request)
1210 self._ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
1211 self._ubuntu_series = self._ubuntu.currentseries
1212 try:
1213@@ -534,7 +533,7 @@ class ProductSeriesUbuntuPackagingView(LaunchpadFormView):
1214 The packaging is restricted to ubuntu series and the default value
1215 is the current development series.
1216 """
1217- super(ProductSeriesUbuntuPackagingView, self).setUpFields()
1218+ super().setUpFields()
1219 series_vocabulary = SimpleVocabulary(
1220 [SimpleTerm(series, series.name, series.named_version)
1221 for series in self._ubuntu.series])
1222diff --git a/lib/lp/registry/browser/project.py b/lib/lp/registry/browser/project.py
1223index 3927fc6..2a7ee6a 100644
1224--- a/lib/lp/registry/browser/project.py
1225+++ b/lib/lp/registry/browser/project.py
1226@@ -136,7 +136,7 @@ class ProjectNavigation(Navigation,
1227
1228 @stepthrough('+tags')
1229 def traverse_tags(self, name):
1230- tags = name.split(u',')
1231+ tags = name.split(',')
1232 if validate_tags(tags):
1233 return ProjectGroupMilestoneTag(self.context, tags)
1234
1235@@ -354,7 +354,7 @@ class ProjectView(PillarViewMixin, HasAnnouncementsView, FeedsMixin):
1236 help_link="/+help-registry/driver.html", show_create_team=True)
1237
1238 def initialize(self):
1239- super(ProjectView, self).initialize()
1240+ super().initialize()
1241 expose_structural_subscription_data_to_js(
1242 self.context, self.request, self.user)
1243
1244@@ -422,7 +422,7 @@ class ProjectReviewView(ProjectEditView):
1245 moderator = check_permission('launchpad.Moderate', self.context)
1246 if not moderator:
1247 self.field_names.remove('name')
1248- super(ProjectReviewView, self).setUpFields()
1249+ super().setUpFields()
1250 self.form_fields = self._createAliasesField() + self.form_fields
1251 if admin:
1252 self.form_fields = (
1253@@ -544,7 +544,7 @@ class ProjectSetView(LaunchpadView):
1254 page_title = "Project groups registered in Launchpad"
1255
1256 def __init__(self, context, request):
1257- super(ProjectSetView, self).__init__(context, request)
1258+ super().__init__(context, request)
1259 self.form = self.request.form_ng
1260 self.search_string = self.form.getOne('text', None)
1261 self.search_requested = False
1262diff --git a/lib/lp/registry/browser/sourcepackage.py b/lib/lp/registry/browser/sourcepackage.py
1263index ea447c2..43e6fb7 100644
1264--- a/lib/lp/registry/browser/sourcepackage.py
1265+++ b/lib/lp/registry/browser/sourcepackage.py
1266@@ -265,7 +265,7 @@ class SourcePackageChangeUpstreamStepOne(ReturnToReferrerMixin, StepView):
1267 product = None
1268
1269 def setUpFields(self):
1270- super(SourcePackageChangeUpstreamStepOne, self).setUpFields()
1271+ super().setUpFields()
1272 series = self.context.productseries
1273 if series is not None:
1274 default = series.product
1275@@ -284,7 +284,7 @@ class SourcePackageChangeUpstreamStepOne(ReturnToReferrerMixin, StepView):
1276 self.request.form['product'] = data['product']
1277
1278 def validateStep(self, data):
1279- super(SourcePackageChangeUpstreamStepOne, self).validateStep(data)
1280+ super().validateStep(data)
1281 product = data.get('product')
1282 if product is None:
1283 return
1284@@ -318,7 +318,7 @@ class SourcePackageChangeUpstreamStepTwo(ReturnToReferrerMixin, StepView):
1285 custom_widget_productseries = LaunchpadRadioWidget
1286
1287 def setUpFields(self):
1288- super(SourcePackageChangeUpstreamStepTwo, self).setUpFields()
1289+ super().setUpFields()
1290
1291 # The vocabulary for the product series is overridden to just
1292 # include active series from the product selected in the
1293@@ -380,7 +380,7 @@ class SourcePackageChangeUpstreamStepTwo(ReturnToReferrerMixin, StepView):
1294 # is called.
1295 next_url = None
1296
1297- main_action_label = u'Change'
1298+ main_action_label = 'Change'
1299
1300 def main_action(self, data):
1301 productseries = data['productseries']
1302@@ -564,7 +564,7 @@ class SourcePackageAssociationPortletView(LaunchpadFormView):
1303
1304 def setUpFields(self):
1305 """See `LaunchpadFormView`."""
1306- super(SourcePackageAssociationPortletView, self).setUpFields()
1307+ super().setUpFields()
1308 self.request.annotations['show_edit_buttons'] = True
1309 # Find registered products that are similarly named to the source
1310 # package.
1311diff --git a/lib/lp/registry/browser/team.py b/lib/lp/registry/browser/team.py
1312index eeefcee..c37bbf0 100644
1313--- a/lib/lp/registry/browser/team.py
1314+++ b/lib/lp/registry/browser/team.py
1315@@ -42,7 +42,6 @@ from lazr.restful.interfaces import IJSONRequestCache
1316 from lazr.restful.utils import smartquote
1317 import pytz
1318 import simplejson
1319-import six
1320 from six.moves.urllib.parse import unquote
1321 from zope.browserpage import ViewPageTemplateFile
1322 from zope.component import getUtility
1323@@ -219,14 +218,12 @@ class HasRenewalPolicyMixin:
1324 def isMultiLineLayout(self, field_name):
1325 if field_name == 'renewal_policy':
1326 return True
1327- return super(HasRenewalPolicyMixin, self).isMultiLineLayout(
1328- field_name)
1329+ return super().isMultiLineLayout(field_name)
1330
1331 def isSingleLineLayout(self, field_name):
1332 if field_name == 'renewal_policy':
1333 return False
1334- return super(HasRenewalPolicyMixin, self).isSingleLineLayout(
1335- field_name)
1336+ return super().isSingleLineLayout(field_name)
1337
1338
1339 class TeamFormMixin:
1340@@ -317,11 +314,11 @@ class TeamEditView(TeamFormMixin, PersonRenameFormMixin,
1341 # class list.
1342 self.field_names = list(self.field_names)
1343 self.field_names.remove('teamowner')
1344- super(TeamEditView, self).setUpFields()
1345+ super().setUpFields()
1346 self.setUpVisibilityField(render_context=True)
1347
1348 def setUpWidgets(self):
1349- super(TeamEditView, self).setUpWidgets()
1350+ super().setUpWidgets()
1351 team = self.context
1352 # Do we need to only show open membership policy choices?
1353 try:
1354@@ -457,7 +454,7 @@ class TeamContactAddressView(MailingListTeamBaseView):
1355 def setUpFields(self):
1356 """See `LaunchpadFormView`.
1357 """
1358- super(TeamContactAddressView, self).setUpFields()
1359+ super().setUpFields()
1360
1361 # Replace the default contact_method field by a custom one.
1362 self.form_fields = (
1363@@ -525,7 +522,7 @@ class TeamContactAddressView(MailingListTeamBaseView):
1364 # responsibility for security on the exception thrower.
1365 msg = error.args[0]
1366 if not IStructuredString.providedBy(msg):
1367- msg = structured(six.text_type(msg))
1368+ msg = structured(str(msg))
1369 self.setFieldError('contact_address', msg)
1370 elif data['contact_method'] == TeamContactMethod.HOSTED_LIST:
1371 mailing_list = getUtility(IMailingListSet).get(self.context.name)
1372@@ -621,8 +618,7 @@ class TeamMailingListConfigurationView(MailingListTeamBaseView):
1373 address. Second, the mailing list may be in a transitional
1374 state: from MODIFIED to UPDATING to ACTIVE can take a while.
1375 """
1376- super(TeamMailingListConfigurationView, self).__init__(
1377- context, request)
1378+ super().__init__(context, request)
1379 list_set = getUtility(IMailingListSet)
1380 self.mailing_list = list_set.get(self.context.name)
1381
1382@@ -903,7 +899,7 @@ class TeamMailingListModerationView(MailingListTeamBaseView):
1383
1384 def __init__(self, context, request):
1385 """Allow for review and moderation of held mailing list posts."""
1386- super(TeamMailingListModerationView, self).__init__(context, request)
1387+ super().__init__(context, request)
1388 list_set = getUtility(IMailingListSet)
1389 self.mailing_list = list_set.get(self.context.name)
1390 if self.mailing_list is None:
1391@@ -988,7 +984,7 @@ class TeamMailingListArchiveView(LaunchpadView):
1392 label = "Mailing list archive"
1393
1394 def __init__(self, context, request):
1395- super(TeamMailingListArchiveView, self).__init__(context, request)
1396+ super().__init__(context, request)
1397 self.messages = self._get_messages()
1398 cache = IJSONRequestCache(request).objects
1399 cache['mail'] = self.messages
1400@@ -1021,7 +1017,7 @@ class TeamAddView(TeamFormMixin, HasRenewalPolicyMixin, LaunchpadFormView):
1401
1402 Only Launchpad Admins get to see the visibility field.
1403 """
1404- super(TeamAddView, self).setUpFields()
1405+ super().setUpFields()
1406 self.setUpVisibilityField()
1407
1408 @action('Create Team', name='create',
1409@@ -1201,7 +1197,7 @@ class TeamMemberAddView(LaunchpadFormView):
1410 if error:
1411 self.setFieldError("newmember", error)
1412
1413- @action(u"Add Member", name="add")
1414+ @action("Add Member", name="add")
1415 def add_action(self, action, data):
1416 """Add the new member to the team."""
1417 newmember = data['newmember']
1418@@ -1778,7 +1774,7 @@ class TeamJoinView(LaunchpadFormView, TeamJoinMixin):
1419 page_title = label
1420
1421 def setUpWidgets(self):
1422- super(TeamJoinView, self).setUpWidgets()
1423+ super().setUpWidgets()
1424 if 'mailinglist_subscribe' in self.field_names:
1425 widget = self.widgets['mailinglist_subscribe']
1426 widget.setRenderedValue(self.user_wants_list_subscriptions)
1427@@ -1914,7 +1910,7 @@ class TeamAddMyTeamsView(LaunchpadFormView):
1428 else:
1429 self.label = 'Add these teams to %s' % context.displayname
1430 self.next_url = canonical_url(context)
1431- super(TeamAddMyTeamsView, self).initialize()
1432+ super().initialize()
1433
1434 def setUpFields(self):
1435 terms = []
1436@@ -1930,7 +1926,7 @@ class TeamAddMyTeamsView(LaunchpadFormView):
1437 render_context=self.render_context)
1438
1439 def setUpWidgets(self, context=None):
1440- super(TeamAddMyTeamsView, self).setUpWidgets(context)
1441+ super().setUpWidgets(context)
1442 self.widgets['teams'].display_label = False
1443
1444 @cachedproperty
1445@@ -2063,7 +2059,7 @@ class TeamReassignmentView(ObjectReassignmentView):
1446 schema = ITeamReassignment
1447
1448 def __init__(self, context, request):
1449- super(TeamReassignmentView, self).__init__(context, request)
1450+ super().__init__(context, request)
1451 self.callback = self._afterOwnerChange
1452 self.teamdisplayname = self.contextName
1453 self._next_url = canonical_url(self.context)
1454diff --git a/lib/lp/registry/browser/teammembership.py b/lib/lp/registry/browser/teammembership.py
1455index ef62f97..3610e3e 100644
1456--- a/lib/lp/registry/browser/teammembership.py
1457+++ b/lib/lp/registry/browser/teammembership.py
1458@@ -38,7 +38,7 @@ class TeamMembershipBreadcrumb(Breadcrumb):
1459 class TeamMembershipEditView(LaunchpadView):
1460
1461 def __init__(self, context, request):
1462- super(TeamMembershipEditView, self).__init__(context, request)
1463+ super().__init__(context, request)
1464 self.errormessage = ""
1465 self.prefix = 'membership'
1466 self.max_year = 2050
1467diff --git a/lib/lp/registry/browser/tests/test_announcements.py b/lib/lp/registry/browser/tests/test_announcements.py
1468index b79d42e..5f005c6 100644
1469--- a/lib/lp/registry/browser/tests/test_announcements.py
1470+++ b/lib/lp/registry/browser/tests/test_announcements.py
1471@@ -30,8 +30,8 @@ class TestAnnouncement(TestCaseWithFactory):
1472 layer = LaunchpadFunctionalLayer
1473
1474 def test_announcement_info(self):
1475- product = self.factory.makeProduct(displayname=u"Foo")
1476- announcer = self.factory.makePerson(displayname=u"Bar Baz")
1477+ product = self.factory.makeProduct(displayname="Foo")
1478+ announcer = self.factory.makePerson(displayname="Bar Baz")
1479 announcement = product.announce(announcer, "Hello World")
1480 view = create_initialized_view(announcement, "+index")
1481 root = html.fromstring(view())
1482@@ -41,8 +41,8 @@ class TestAnnouncement(TestCaseWithFactory):
1483 normalize_whitespace(reg_para.text_content()))
1484
1485 def test_announcement_info_with_publication_date(self):
1486- product = self.factory.makeProduct(displayname=u"Foo")
1487- announcer = self.factory.makePerson(displayname=u"Bar Baz")
1488+ product = self.factory.makeProduct(displayname="Foo")
1489+ announcer = self.factory.makePerson(displayname="Bar Baz")
1490 announced = datetime(2007, 1, 12, tzinfo=utc)
1491 announcement = product.announce(
1492 announcer, "Hello World", publication_date=announced)
1493diff --git a/lib/lp/registry/browser/tests/test_branding.py b/lib/lp/registry/browser/tests/test_branding.py
1494index 1b2d321..7c1ba39 100644
1495--- a/lib/lp/registry/browser/tests/test_branding.py
1496+++ b/lib/lp/registry/browser/tests/test_branding.py
1497@@ -14,7 +14,7 @@ class TestBrandingChangeView(TestCaseWithFactory):
1498 layer = DatabaseFunctionalLayer
1499
1500 def setUp(self):
1501- super(TestBrandingChangeView, self).setUp()
1502+ super().setUp()
1503 self.context = self.factory.makePerson(name='cow')
1504 self.view = BrandingChangeView(self.context, LaunchpadTestRequest())
1505
1506diff --git a/lib/lp/registry/browser/tests/test_breadcrumbs.py b/lib/lp/registry/browser/tests/test_breadcrumbs.py
1507index 459a259..10bd2e9 100644
1508--- a/lib/lp/registry/browser/tests/test_breadcrumbs.py
1509+++ b/lib/lp/registry/browser/tests/test_breadcrumbs.py
1510@@ -17,7 +17,7 @@ class TestPillarSharingBreadcrumb(BaseBreadcrumbTestCase, SharingBaseTestCase):
1511 pillar_type = 'product'
1512
1513 def setUp(self):
1514- super(TestPillarSharingBreadcrumb, self).setUp()
1515+ super().setUp()
1516 login_person(self.driver)
1517
1518 def test_sharing_breadcrumb(self):
1519@@ -44,7 +44,7 @@ class TestDistroseriesBreadcrumb(BaseBreadcrumbTestCase):
1520 """Test breadcrumbs for an `IDistroseries`."""
1521
1522 def setUp(self):
1523- super(TestDistroseriesBreadcrumb, self).setUp()
1524+ super().setUp()
1525 self.distribution = self.factory.makeDistribution(
1526 name='youbuntu', displayname='Youbuntu')
1527 self.distroseries = self.factory.makeDistroSeries(
1528@@ -61,7 +61,7 @@ class TestDistributionMirrorBreadcrumb(BaseBreadcrumbTestCase):
1529 """Test breadcrumbs for an `IDistributionMirror`."""
1530
1531 def setUp(self):
1532- super(TestDistributionMirrorBreadcrumb, self).setUp()
1533+ super().setUp()
1534 self.distribution = getUtility(ILaunchpadCelebrities).ubuntu
1535
1536 def test_distributionmirror_withDisplayName(self):
1537@@ -104,7 +104,7 @@ class TestMilestoneBreadcrumb(BaseBreadcrumbTestCase):
1538 """Test the breadcrumbs for an `IMilestone`."""
1539
1540 def setUp(self):
1541- super(TestMilestoneBreadcrumb, self).setUp()
1542+ super().setUp()
1543 self.project = self.factory.makeProduct()
1544 self.series = self.factory.makeProductSeries(product=self.project)
1545 self.milestone = self.factory.makeMilestone(
1546@@ -136,7 +136,7 @@ class TestPollBreadcrumb(BaseBreadcrumbTestCase):
1547 """Test breadcrumbs for an `IPoll`."""
1548
1549 def setUp(self):
1550- super(TestPollBreadcrumb, self).setUp()
1551+ super().setUp()
1552 self.team = self.factory.makeTeam(displayname="Poll Team")
1553 name = "pollo-poll"
1554 title = "Marco Pollo"
1555@@ -157,7 +157,7 @@ class TestNameblacklistBreadcrumb(BaseBreadcrumbTestCase):
1556 """Test breadcrumbs for +nameblacklist."""
1557
1558 def setUp(self):
1559- super(TestNameblacklistBreadcrumb, self).setUp()
1560+ super().setUp()
1561 self.name_blacklist_set = getUtility(INameBlacklistSet)
1562 self.registry_expert = self.factory.makeRegistryExpert()
1563 login_person(self.registry_expert)
1564@@ -167,7 +167,7 @@ class TestNameblacklistBreadcrumb(BaseBreadcrumbTestCase):
1565 self.assertBreadcrumbs(expected, self.name_blacklist_set)
1566
1567 def test_nameblacklist_edit(self):
1568- blacklist = self.name_blacklist_set.getByRegExp(u'blacklist')
1569+ blacklist = self.name_blacklist_set.getByRegExp('blacklist')
1570 expected = [
1571 ('Name Blacklist',
1572 'http://launchpad.test/+nameblacklist'),
1573diff --git a/lib/lp/registry/browser/tests/test_codeofconduct.py b/lib/lp/registry/browser/tests/test_codeofconduct.py
1574index f52b93b..b270f70 100644
1575--- a/lib/lp/registry/browser/tests/test_codeofconduct.py
1576+++ b/lib/lp/registry/browser/tests/test_codeofconduct.py
1577@@ -25,7 +25,7 @@ class TestSignedCodeOfConductAckView(TestCaseWithFactory):
1578 layer = DatabaseFunctionalLayer
1579
1580 def setUp(self):
1581- super(TestSignedCodeOfConductAckView, self).setUp()
1582+ super().setUp()
1583 self.signed_coc_set = getUtility(ISignedCodeOfConductSet)
1584 self.owner = self.factory.makePerson()
1585 self.admin = login_celebrity('admin')
1586@@ -60,7 +60,7 @@ class SignCodeOfConductTestCase(TestCaseWithFactory):
1587 layer = DatabaseFunctionalLayer
1588
1589 def setUp(self):
1590- super(SignCodeOfConductTestCase, self).setUp()
1591+ super().setUp()
1592 user = self.factory.makePerson()
1593 gpg_key = self.factory.makeGPGKey(user)
1594 self.signed_coc = self.sign_coc(user, gpg_key)
1595diff --git a/lib/lp/registry/browser/tests/test_distribution.py b/lib/lp/registry/browser/tests/test_distribution.py
1596index f75dce0..3f3ac9c 100644
1597--- a/lib/lp/registry/browser/tests/test_distribution.py
1598+++ b/lib/lp/registry/browser/tests/test_distribution.py
1599@@ -336,9 +336,9 @@ class TestDistributionPage(TestCaseWithFactory):
1600 layer = DatabaseFunctionalLayer
1601
1602 def setUp(self):
1603- super(TestDistributionPage, self).setUp()
1604+ super().setUp()
1605 self.distro = self.factory.makeDistribution(
1606- name="distro", displayname=u'distro')
1607+ name="distro", displayname='distro')
1608 self.simple_user = self.factory.makePerson()
1609 # Use a FakeLogger fixture to prevent Memcached warnings to be
1610 # printed to stdout while browsing pages.
1611@@ -510,9 +510,9 @@ class TestDistributionView(TestCaseWithFactory):
1612 layer = DatabaseFunctionalLayer
1613
1614 def setUp(self):
1615- super(TestDistributionView, self).setUp()
1616+ super().setUp()
1617 self.distro = self.factory.makeDistribution(
1618- name="distro", displayname=u'distro')
1619+ name="distro", displayname='distro')
1620
1621 def test_view_data_model(self):
1622 # The view's json request cache contains the expected data.
1623diff --git a/lib/lp/registry/browser/tests/test_distribution_views.py b/lib/lp/registry/browser/tests/test_distribution_views.py
1624index ad7956d..252bf72 100644
1625--- a/lib/lp/registry/browser/tests/test_distribution_views.py
1626+++ b/lib/lp/registry/browser/tests/test_distribution_views.py
1627@@ -38,13 +38,13 @@ class TestDistributionPublisherConfigView(TestCaseWithFactory):
1628
1629 def setUp(self):
1630 # Create a test distribution.
1631- super(TestDistributionPublisherConfigView, self).setUp()
1632+ super().setUp()
1633 self.distro = self.factory.makeDistribution(no_pubconf=True)
1634 login(LAUNCHPAD_ADMIN)
1635
1636- self.ROOT_DIR = u"rootdir/test"
1637- self.BASE_URL = u"http://base.url"
1638- self.COPY_BASE_URL = u"http://copybase.url"
1639+ self.ROOT_DIR = "rootdir/test"
1640+ self.BASE_URL = "http://base.url"
1641+ self.COPY_BASE_URL = "http://copybase.url"
1642
1643 def test_empty_initial_values(self):
1644 # Test that the page will display empty field values with no
1645@@ -53,7 +53,7 @@ class TestDistributionPublisherConfigView(TestCaseWithFactory):
1646 self.distro, LaunchpadTestRequest())
1647
1648 for value in view.initial_values:
1649- self.assertEqual(u"", value)
1650+ self.assertEqual("", value)
1651
1652 def test_previous_initial_values(self):
1653 # Test that the initial values are the same as the ones in the
1654@@ -96,9 +96,9 @@ class TestDistributionPublisherConfigView(TestCaseWithFactory):
1655 # Test POSTing to change existing config.
1656 self.factory.makePublisherConfig(
1657 distribution=self.distro,
1658- root_dir=u"random",
1659- base_url=u"blah",
1660- copy_base_url=u"foo",
1661+ root_dir="random",
1662+ base_url="blah",
1663+ copy_base_url="foo",
1664 )
1665 self._change_and_test_config()
1666
1667@@ -109,7 +109,7 @@ class TestDistroAddView(TestCaseWithFactory):
1668 layer = DatabaseFunctionalLayer
1669
1670 def setUp(self):
1671- super(TestDistroAddView, self).setUp()
1672+ super().setUp()
1673 self.owner = self.factory.makePerson()
1674 self.registrant = self.factory.makePerson()
1675 self.simple_user = self.factory.makePerson()
1676@@ -189,7 +189,7 @@ class TestDistroEditView(OCIConfigHelperMixin, TestCaseWithFactory):
1677 layer = DatabaseFunctionalLayer
1678
1679 def setUp(self):
1680- super(TestDistroEditView, self).setUp()
1681+ super().setUp()
1682 self.admin = login_celebrity('admin')
1683 self.oci_admins = self.factory.makeTeam(
1684 members=[self.admin])
1685@@ -226,7 +226,7 @@ class TestDistroEditView(OCIConfigHelperMixin, TestCaseWithFactory):
1686 'field.title': 'newbuntu',
1687 'field.summary': 'newbuntu',
1688 'field.description': 'newbuntu',
1689- 'field.require_virtualized.used': u'',
1690+ 'field.require_virtualized.used': '',
1691 'field.processors': [proc.name for proc in self.all_processors],
1692 'field.actions.change': 'Change',
1693 }
1694@@ -496,7 +496,7 @@ class TestDistroReassignView(TestCaseWithFactory):
1695 layer = DatabaseFunctionalLayer
1696
1697 def setUp(self):
1698- super(TestDistroReassignView, self).setUp()
1699+ super().setUp()
1700 self.owner = self.factory.makePerson()
1701 self.registrant = self.factory.makePerson()
1702 self.simple_user = self.factory.makePerson()
1703diff --git a/lib/lp/registry/browser/tests/test_distributionsourcepackage.py b/lib/lp/registry/browser/tests/test_distributionsourcepackage.py
1704index 0ae0087..3de69df 100644
1705--- a/lib/lp/registry/browser/tests/test_distributionsourcepackage.py
1706+++ b/lib/lp/registry/browser/tests/test_distributionsourcepackage.py
1707@@ -42,8 +42,8 @@ class TestDistributionSourcePackageFormatterAPI(TestCaseWithFactory):
1708 ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
1709 dsp = ubuntu.getSourcePackage('mouse')
1710 markup = (
1711- u'<a href="/ubuntu/+source/mouse" class="sprite package-source">'
1712- u'mouse in Ubuntu</a>')
1713+ '<a href="/ubuntu/+source/mouse" class="sprite package-source">'
1714+ 'mouse in Ubuntu</a>')
1715 self.assertEqual(markup, test_tales('dsp/fmt:link', dsp=dsp))
1716
1717
1718@@ -157,7 +157,7 @@ class TestDistributionSourceView(TestCaseWithFactory):
1719 layer = DatabaseFunctionalLayer
1720
1721 def setUp(self):
1722- super(TestDistributionSourceView, self).setUp()
1723+ super().setUp()
1724 self.factory.makeSourcePackageName('mouse')
1725 distro = self.factory.makeDistribution()
1726 self.dsp = distro.getSourcePackage('mouse')
1727diff --git a/lib/lp/registry/browser/tests/test_distroseries.py b/lib/lp/registry/browser/tests/test_distroseries.py
1728index e0d714e..326bbfd 100644
1729--- a/lib/lp/registry/browser/tests/test_distroseries.py
1730+++ b/lib/lp/registry/browser/tests/test_distroseries.py
1731@@ -244,7 +244,7 @@ class DistroSeriesIndexFunctionalTestCase(TestCaseWithFactory):
1732 layer = DatabaseFunctionalLayer
1733
1734 def setUp(self):
1735- super(DistroSeriesIndexFunctionalTestCase, self).setUp()
1736+ super().setUp()
1737 # Use a FakeLogger fixture to prevent Memcached warnings to be
1738 # printed to stdout while browsing pages.
1739 self.useFixture(FakeLogger())
1740@@ -501,7 +501,7 @@ class TestDistroSeriesDerivationPortlet(TestCaseWithFactory):
1741 job.start()
1742 job.fail()
1743 with person_logged_in(series.distribution.owner):
1744- series.distribution.owner.display_name = u"Bob Individual"
1745+ series.distribution.owner.display_name = "Bob Individual"
1746 with anonymous_logged_in():
1747 view = create_initialized_view(series, '+portlet-derivation')
1748 html_content = view()
1749@@ -514,7 +514,7 @@ class TestDistroSeriesDerivationPortlet(TestCaseWithFactory):
1750 # owner is an individual.
1751 with person_logged_in(series.distribution.owner):
1752 series.distribution.owner = self.factory.makeTeam(
1753- displayname=u"Team Teamy Team Team",
1754+ displayname="Team Teamy Team Team",
1755 membership_policy=TeamMembershipPolicy.RESTRICTED)
1756 with anonymous_logged_in():
1757 view = create_initialized_view(series, '+portlet-derivation')
1758@@ -614,31 +614,31 @@ class TestDistroSeriesAddView(TestCaseWithFactory):
1759 layer = DatabaseFunctionalLayer
1760
1761 def setUp(self):
1762- super(TestDistroSeriesAddView, self).setUp()
1763+ super().setUp()
1764 self.user = self.factory.makePerson()
1765 self.distribution = self.factory.makeDistribution(owner=self.user)
1766
1767 def createNewDistroseries(self):
1768 form = {
1769- "field.name": u"polished",
1770- "field.version": u"12.04",
1771- "field.display_name": u"Polished Polecat",
1772- "field.summary": u"Even The Register likes it.",
1773- "field.actions.create": u"Add Series",
1774+ "field.name": "polished",
1775+ "field.version": "12.04",
1776+ "field.display_name": "Polished Polecat",
1777+ "field.summary": "Even The Register likes it.",
1778+ "field.actions.create": "Add Series",
1779 }
1780 with person_logged_in(self.user):
1781 create_initialized_view(self.distribution, "+addseries",
1782 form=form)
1783- distroseries = self.distribution.getSeries(u"polished")
1784+ distroseries = self.distribution.getSeries("polished")
1785 return distroseries
1786
1787 def assertCreated(self, distroseries):
1788- self.assertEqual(u"polished", distroseries.name)
1789- self.assertEqual(u"12.04", distroseries.version)
1790- self.assertEqual(u"Polished Polecat", distroseries.display_name)
1791- self.assertEqual(u"Polished Polecat", distroseries.title)
1792- self.assertEqual(u"Even The Register likes it.", distroseries.summary)
1793- self.assertEqual(u"", distroseries.description)
1794+ self.assertEqual("polished", distroseries.name)
1795+ self.assertEqual("12.04", distroseries.version)
1796+ self.assertEqual("Polished Polecat", distroseries.display_name)
1797+ self.assertEqual("Polished Polecat", distroseries.title)
1798+ self.assertEqual("Even The Register likes it.", distroseries.summary)
1799+ self.assertEqual("", distroseries.description)
1800 self.assertEqual(self.user, distroseries.owner)
1801
1802 def test_plain_submit(self):
1803@@ -684,10 +684,10 @@ class TestDistroSeriesInitializeView(TestCaseWithFactory):
1804 # process Javascript.
1805 [message] = root.cssselect("p.error.message")
1806 self.assertIn(
1807- u"Javascript is required to use this page",
1808+ "Javascript is required to use this page",
1809 message.text)
1810 self.assertIn(
1811- u"javascript-disabled",
1812+ "javascript-disabled",
1813 message.get("class").split())
1814
1815 def test_seriesToVocab(self):
1816@@ -755,8 +755,8 @@ class TestDistroSeriesInitializeView(TestCaseWithFactory):
1817 [message] = root.cssselect("p.error.message")
1818 self.assertThat(
1819 message.text, EqualsIgnoringWhitespace(
1820- u"This series already contains source packages "
1821- u"and cannot be initialized again."))
1822+ "This series already contains source packages "
1823+ "and cannot be initialized again."))
1824
1825 def test_form_hidden_when_distroseries_is_being_initialized(self):
1826 # The form is hidden when the series has already been derived.
1827@@ -770,7 +770,7 @@ class TestDistroSeriesInitializeView(TestCaseWithFactory):
1828 [message] = root.cssselect("p.error.message")
1829 self.assertThat(
1830 message.text, EqualsIgnoringWhitespace(
1831- u"This series is already being initialized."))
1832+ "This series is already being initialized."))
1833
1834 def test_form_hidden_when_previous_series_none(self):
1835 # If the distribution has an initialized series and the
1836@@ -789,9 +789,9 @@ class TestDistroSeriesInitializeView(TestCaseWithFactory):
1837 [message] = root.cssselect("p.error.message")
1838 self.assertThat(
1839 message.text, EqualsIgnoringWhitespace(
1840- u'Unable to initialize series: the distribution '
1841- u'already has initialized series and this distroseries '
1842- u'has no previous series.'))
1843+ 'Unable to initialize series: the distribution '
1844+ 'already has initialized series and this distroseries '
1845+ 'has no previous series.'))
1846
1847 def test_form_hidden_when_no_publisher_config_set_up(self):
1848 # If the distribution has no publisher config set up:
1849@@ -807,8 +807,8 @@ class TestDistroSeriesInitializeView(TestCaseWithFactory):
1850 [message] = root.cssselect("p.error.message")
1851 self.assertThat(
1852 message.text, EqualsIgnoringWhitespace(
1853- u"The series' distribution has no publisher configuration. "
1854- u"Please ask an administrator to set this up."))
1855+ "The series' distribution has no publisher configuration. "
1856+ "Please ask an administrator to set this up."))
1857
1858
1859 class TestDistroSeriesInitializeViewAccess(TestCaseWithFactory):
1860@@ -817,8 +817,7 @@ class TestDistroSeriesInitializeViewAccess(TestCaseWithFactory):
1861 layer = LaunchpadFunctionalLayer
1862
1863 def setUp(self):
1864- super(TestDistroSeriesInitializeViewAccess,
1865- self).setUp('foo.bar@canonical.com')
1866+ super().setUp('foo.bar@canonical.com')
1867
1868 def test_initseries_access_anon(self):
1869 # Anonymous users cannot access +initseries.
1870@@ -898,8 +897,7 @@ class TestDistroSeriesLocalDiffPerformance(TestCaseWithFactory,
1871 layer = DatabaseFunctionalLayer
1872
1873 def setUp(self):
1874- super(TestDistroSeriesLocalDiffPerformance,
1875- self).setUp('foo.bar@canonical.com')
1876+ super().setUp('foo.bar@canonical.com')
1877 self.simple_user = self.factory.makePerson()
1878
1879 def _assertQueryCount(self, derived_series):
1880@@ -917,9 +915,9 @@ class TestDistroSeriesLocalDiffPerformance(TestCaseWithFactory,
1881 for index in range(num):
1882 version = self.factory.getUniqueInteger()
1883 versions = {
1884- 'base': u'1.%d' % version,
1885- 'derived': u'1.%dderived1' % version,
1886- 'parent': u'1.%d-1' % version,
1887+ 'base': '1.%d' % version,
1888+ 'derived': '1.%dderived1' % version,
1889+ 'parent': '1.%d-1' % version,
1890 }
1891 dsd = self.factory.makeDistroSeriesDifference(
1892 derived_series=derived_series,
1893@@ -965,8 +963,7 @@ class TestDistroSeriesLocalDiffPerformance(TestCaseWithFactory,
1894
1895 def prepare_statements(rec):
1896 for statement in rec.statements:
1897- for line in wrapper.wrap(statement):
1898- yield line
1899+ yield from wrapper.wrap(statement)
1900 yield "-" * wrapper.width
1901
1902 def statement_diff():
1903@@ -983,19 +980,19 @@ class TestDistroSeriesLocalDiffPerformance(TestCaseWithFactory,
1904 self.assertThat(recorder1, HasQueryCount(LessThan(30)))
1905 self.addDetail(
1906 "statement-count-0-differences",
1907- text_content(u"%d" % recorder1.count))
1908+ text_content("%d" % recorder1.count))
1909 # Add some differences and render.
1910 add_differences(2)
1911 recorder2, batch_size = flush_and_render()
1912 self.addDetail(
1913 "statement-count-2-differences",
1914- text_content(u"%d" % recorder2.count))
1915+ text_content("%d" % recorder2.count))
1916 # Add more differences and render again.
1917 add_differences(2)
1918 recorder3, batch_size = flush_and_render()
1919 self.addDetail(
1920 "statement-count-4-differences",
1921- text_content(u"%d" % recorder3.count))
1922+ text_content("%d" % recorder3.count))
1923 # The last render should not need more queries than the previous.
1924 self.addDetail(
1925 "statement-diff", Content(
1926@@ -1005,7 +1002,7 @@ class TestDistroSeriesLocalDiffPerformance(TestCaseWithFactory,
1927 (recorder3.count - recorder1.count) / float(batch_size))
1928 self.addDetail(
1929 "statement-count-per-row-average",
1930- text_content(u"%.2f" % statement_count_per_row))
1931+ text_content("%.2f" % statement_count_per_row))
1932 # Query count is ~O(1) (i.e. not dependent of the number of
1933 # differences displayed).
1934 self.assertThat(recorder3, HasQueryCount.byEquality(recorder2))
1935@@ -1099,7 +1096,7 @@ class TestDistroSeriesLocalDifferences(TestCaseWithFactory,
1936 def test_parent_packagesets_localpackagediffs_sorts(self):
1937 # Multiple packagesets are sorted in a comma separated list.
1938 ds_diff = self.factory.makeDistroSeriesDifference()
1939- unsorted_names = [u"zzz", u"aaa"]
1940+ unsorted_names = ["zzz", "aaa"]
1941 with celebrity_logged_in('admin'):
1942 for name in unsorted_names:
1943 self.factory.makePackageset(
1944@@ -1203,8 +1200,8 @@ class TestDistroSeriesLocalDifferences(TestCaseWithFactory,
1945 rows = diff_table.tbody.find_all('tr')
1946
1947 self.assertEqual(1, len(rows))
1948- self.assertIn("Latest comment", six.text_type(rows[0]))
1949- self.assertNotIn("Earlier comment", six.text_type(rows[0]))
1950+ self.assertIn("Latest comment", str(rows[0]))
1951+ self.assertNotIn("Earlier comment", str(rows[0]))
1952
1953 def test_diff_row_links_to_extra_details(self):
1954 # The source package name links to the difference details.
1955@@ -1227,9 +1224,9 @@ class TestDistroSeriesLocalDifferences(TestCaseWithFactory,
1956 derived_series, parent_series = self._createChildAndParents(
1957 other_parent_series=other_parent_series)
1958 versions = {
1959- 'base': u'1.0',
1960- 'derived': u'1.0derived1',
1961- 'parent': u'1.0-1',
1962+ 'base': '1.0',
1963+ 'derived': '1.0derived1',
1964+ 'parent': '1.0-1',
1965 }
1966
1967 self.factory.makeDistroSeriesDifference(
1968@@ -1264,11 +1261,11 @@ class TestDistroSeriesLocalDifferences(TestCaseWithFactory,
1969 package_name = 'package-1'
1970 derived_series, parent_series = self._createChildAndParent()
1971 versions = {
1972- 'base': u'1.0',
1973- 'derived': u'1.0derived1',
1974- 'parent': u'1.0-1',
1975+ 'base': '1.0',
1976+ 'derived': '1.0derived1',
1977+ 'parent': '1.0-1',
1978 }
1979- new_version = u'1.2'
1980+ new_version = '1.2'
1981
1982 difference = self.factory.makeDistroSeriesDifference(
1983 versions=versions,
1984@@ -1307,9 +1304,9 @@ class TestDistroSeriesLocalDifferences(TestCaseWithFactory,
1985 package_name = 'package-1'
1986 derived_series, parent_series = self._createChildAndParent()
1987 versions = {
1988- 'base': u'1.0',
1989- 'derived': u'1.0derived1',
1990- 'parent': u'1.0-1',
1991+ 'base': '1.0',
1992+ 'derived': '1.0derived1',
1993+ 'parent': '1.0-1',
1994 }
1995
1996 difference = self.factory.makeDistroSeriesDifference(
1997@@ -1407,7 +1404,7 @@ class TestDistroSeriesLocalDifferences(TestCaseWithFactory,
1998 """Enable the feature flag for derived-series upgrade."""
1999 self.useFixture(
2000 FeatureFixture(
2001- {u'soyuz.derived_series_upgrade.enabled': u'on'}))
2002+ {'soyuz.derived_series_upgrade.enabled': 'on'}))
2003
2004 @with_celebrity_logged_in("admin")
2005 def test_upgrades_offered_only_with_feature_flag(self):
2006@@ -1544,7 +1541,7 @@ class TestDistroSeriesLocalDifferences(TestCaseWithFactory,
2007 '+localpackagediffs')
2008
2009 radio_title = (
2010- u"\xa0Ignored packages with a higher version than in 'Lucid'")
2011+ "\xa0Ignored packages with a higher version than in 'Lucid'")
2012 radio_option_matches = soupmatchers.HTMLContains(
2013 soupmatchers.Tag(
2014 "radio displays parent's name", 'label',
2015@@ -1562,7 +1559,7 @@ class TestDistroSeriesLocalDifferences(TestCaseWithFactory,
2016 '+localpackagediffs')
2017
2018 radio_title = (
2019- u"\xa0Ignored packages with a higher version than in parent")
2020+ "\xa0Ignored packages with a higher version than in parent")
2021 radio_option_matches = soupmatchers.HTMLContains(
2022 soupmatchers.Tag(
2023 "radio displays parent's name", 'label',
2024@@ -2085,7 +2082,7 @@ class TestDistroSeriesLocalDifferences(TestCaseWithFactory,
2025
2026 # The inital state is that 1.0-1 is not in the derived series.
2027 pubs = derived_series.main_archive.getPublishedSources(
2028- name=u'my-src-name', version=versions['parent'],
2029+ name='my-src-name', version=versions['parent'],
2030 distroseries=derived_series).any()
2031 self.assertIs(None, pubs)
2032
2033@@ -2144,7 +2141,7 @@ class TestDistroSeriesLocalDifferences(TestCaseWithFactory,
2034 self._syncAndGetView(
2035 derived_series, person, [diff_id])
2036 parent_series.main_archive.getPublishedSources(
2037- name=u'my-src-name', version=versions['parent'],
2038+ name='my-src-name', version=versions['parent'],
2039 distroseries=parent_series).one()
2040
2041 # We look for a PackageCopyJob with the right metadata.
2042@@ -2274,7 +2271,7 @@ class TestCopyAsynchronouslyMessage(TestCaseWithFactory):
2043 layer = DatabaseFunctionalLayer
2044
2045 def setUp(self):
2046- super(TestCopyAsynchronouslyMessage, self).setUp()
2047+ super().setUp()
2048 self.archive = self.factory.makeArchive()
2049 self.series = self.factory.makeDistroSeries()
2050 self.series_url = canonical_url(self.series)
2051@@ -2388,8 +2385,7 @@ class DistroSeriesMissingPackagesPageTestCase(TestCaseWithFactory,
2052 layer = LaunchpadFunctionalLayer
2053
2054 def setUp(self):
2055- super(DistroSeriesMissingPackagesPageTestCase,
2056- self).setUp('foo.bar@canonical.com')
2057+ super().setUp('foo.bar@canonical.com')
2058 self.simple_user = self.factory.makePerson()
2059
2060 def test_parent_packagesets_missingpackages(self):
2061@@ -2552,8 +2548,7 @@ class DistroSeriesUniquePackagesPageTestCase(TestCaseWithFactory,
2062 layer = DatabaseFunctionalLayer
2063
2064 def setUp(self):
2065- super(DistroSeriesUniquePackagesPageTestCase,
2066- self).setUp('foo.bar@canonical.com')
2067+ super().setUp('foo.bar@canonical.com')
2068 self.simple_user = self.factory.makePerson()
2069
2070 def test_packagesets_uniquepackages(self):
2071diff --git a/lib/lp/registry/browser/tests/test_distroseriesdifference_views.py b/lib/lp/registry/browser/tests/test_distroseriesdifference_views.py
2072index 766caac..ea2e246 100644
2073--- a/lib/lp/registry/browser/tests/test_distroseriesdifference_views.py
2074+++ b/lib/lp/registry/browser/tests/test_distroseriesdifference_views.py
2075@@ -108,8 +108,8 @@ class DistroSeriesDifferenceTestCase(TestCaseWithFactory):
2076
2077 self.assertIsNot(None, view.binary_summaries)
2078 self.assertEqual([
2079- u'flubber-bin: summary for flubber-bin',
2080- u'flubber-lib: summary for flubber-lib',
2081+ 'flubber-bin: summary for flubber-bin',
2082+ 'flubber-lib: summary for flubber-lib',
2083 ], view.binary_summaries)
2084
2085 def test_binary_summaries_for_missing_difference(self):
2086@@ -124,8 +124,8 @@ class DistroSeriesDifferenceTestCase(TestCaseWithFactory):
2087
2088 self.assertIsNot(None, view.binary_summaries)
2089 self.assertEqual([
2090- u'flubber-bin: summary for flubber-bin',
2091- u'flubber-lib: summary for flubber-lib',
2092+ 'flubber-bin: summary for flubber-bin',
2093+ 'flubber-lib: summary for flubber-lib',
2094 ], view.binary_summaries)
2095
2096 def test_binary_summaries_no_pubs(self):
2097diff --git a/lib/lp/registry/browser/tests/test_distroseriesdifference_webservice.py b/lib/lp/registry/browser/tests/test_distroseriesdifference_webservice.py
2098index 79a74d4..58941cc 100644
2099--- a/lib/lp/registry/browser/tests/test_distroseriesdifference_webservice.py
2100+++ b/lib/lp/registry/browser/tests/test_distroseriesdifference_webservice.py
2101@@ -179,40 +179,40 @@ class DistroSeriesDifferenceWebServiceTestCase(TestCaseWithFactory):
2102 ws_diff = ws_object(self.factory.makeLaunchpadService(
2103 self.factory.makePerson()), ds_diff)
2104
2105- self.assertEqual(u'Blocklisted always', ws_diff.status)
2106+ self.assertEqual('Blocklisted always', ws_diff.status)
2107
2108 def test_exported_sourcepackagename(self):
2109 # The difference's sourcepackagename is exposed.
2110 ds_diff = self.factory.makeDistroSeriesDifference(
2111- source_package_name_str=u'package')
2112+ source_package_name_str='package')
2113 ws_diff = ws_object(self.factory.makeLaunchpadService(
2114 self.factory.makePerson()), ds_diff)
2115
2116- self.assertEqual(u'package', ws_diff.sourcepackagename)
2117+ self.assertEqual('package', ws_diff.sourcepackagename)
2118
2119 def test_exported_parent_source_version(self):
2120 # The difference's parent_source_version is exposed.
2121 ds_diff = self.factory.makeDistroSeriesDifference(
2122- versions={'parent': u'1.1'})
2123+ versions={'parent': '1.1'})
2124 ws_diff = ws_object(self.factory.makeLaunchpadService(
2125 self.factory.makePerson()), ds_diff)
2126
2127- self.assertEqual(u'1.1', ws_diff.parent_source_version)
2128+ self.assertEqual('1.1', ws_diff.parent_source_version)
2129
2130 def test_exported_source_version(self):
2131 # The difference's source_version is exposed.
2132 ds_diff = self.factory.makeDistroSeriesDifference(
2133- versions={'derived': u'1.3'})
2134+ versions={'derived': '1.3'})
2135 ws_diff = ws_object(self.factory.makeLaunchpadService(
2136 self.factory.makePerson()), ds_diff)
2137
2138- self.assertEqual(u'1.3', ws_diff.source_version)
2139+ self.assertEqual('1.3', ws_diff.source_version)
2140
2141 def test_exported_base_version(self):
2142 # The difference's base_version is exposed.
2143 ds_diff = self.factory.makeDistroSeriesDifference(
2144- versions={'base': u'0.5'}, set_base_version=True)
2145+ versions={'base': '0.5'}, set_base_version=True)
2146 ws_diff = ws_object(self.factory.makeLaunchpadService(
2147 self.factory.makePerson()), ds_diff)
2148
2149- self.assertEqual(u'0.5', ws_diff.base_version)
2150+ self.assertEqual('0.5', ws_diff.base_version)
2151diff --git a/lib/lp/registry/browser/tests/test_edit_permissions.py b/lib/lp/registry/browser/tests/test_edit_permissions.py
2152index 022daa5..7e41b28 100644
2153--- a/lib/lp/registry/browser/tests/test_edit_permissions.py
2154+++ b/lib/lp/registry/browser/tests/test_edit_permissions.py
2155@@ -28,7 +28,7 @@ class EditViewPermissionBase(TestCaseWithFactory):
2156 layer = DatabaseFunctionalLayer
2157
2158 def setUp(self):
2159- super(EditViewPermissionBase, self).setUp()
2160+ super().setUp()
2161 self.setupTarget()
2162 self.registry_admin = self.factory.makePerson(name='registry-admin')
2163 celebs = getUtility(ILaunchpadCelebrities)
2164diff --git a/lib/lp/registry/browser/tests/test_mailinglists.py b/lib/lp/registry/browser/tests/test_mailinglists.py
2165index b1154ba..004eb71 100644
2166--- a/lib/lp/registry/browser/tests/test_mailinglists.py
2167+++ b/lib/lp/registry/browser/tests/test_mailinglists.py
2168@@ -68,7 +68,7 @@ class MailingListSubscriptionControlsTestCase(TestCaseWithFactory):
2169 layer = DatabaseFunctionalLayer
2170
2171 def setUp(self):
2172- super(MailingListSubscriptionControlsTestCase, self).setUp()
2173+ super().setUp()
2174 self.a_team = self.factory.makeTeam(name='a')
2175 self.b_team = self.factory.makeTeam(name='b', owner=self.a_team)
2176 self.b_team_list = self.factory.makeMailingList(team=self.b_team,
2177diff --git a/lib/lp/registry/browser/tests/test_milestone.py b/lib/lp/registry/browser/tests/test_milestone.py
2178index e56ac8b..f5c22f6 100644
2179--- a/lib/lp/registry/browser/tests/test_milestone.py
2180+++ b/lib/lp/registry/browser/tests/test_milestone.py
2181@@ -156,7 +156,7 @@ class TestAddMilestoneViews(TestCaseWithFactory):
2182 layer = DatabaseFunctionalLayer
2183
2184 def setUp(self):
2185- super(TestAddMilestoneViews, self).setUp()
2186+ super().setUp()
2187 self.product = self.factory.makeProduct()
2188 self.series = self.factory.makeProductSeries(product=self.product)
2189 self.owner = self.product.owner
2190@@ -196,7 +196,7 @@ class TestAddMilestoneViews(TestCaseWithFactory):
2191 self.assertEqual(expected_msg, error_msg)
2192
2193 def test_add_milestone_with_tags(self):
2194- tags = u'zed alpha'
2195+ tags = 'zed alpha'
2196 form = {
2197 'field.name': '1.1',
2198 'field.tags': tags,
2199@@ -222,7 +222,7 @@ class TestMilestoneEditView(TestCaseWithFactory):
2200 layer = DatabaseFunctionalLayer
2201
2202 def setUp(self):
2203- super(TestMilestoneEditView, self).setUp()
2204+ super().setUp()
2205 self.product = self.factory.makeProduct()
2206 self.milestone = self.factory.makeMilestone(
2207 name='orig-name', product=self.product)
2208@@ -230,9 +230,9 @@ class TestMilestoneEditView(TestCaseWithFactory):
2209 login_person(self.owner)
2210
2211 def test_edit_milestone_with_tags(self):
2212- orig_tags = u'ba ac'
2213+ orig_tags = 'ba ac'
2214 self.milestone.setTags(orig_tags.split(), self.owner)
2215- new_tags = u'za ab'
2216+ new_tags = 'za ab'
2217 form = {
2218 'field.name': 'new-name',
2219 'field.tags': new_tags,
2220@@ -245,7 +245,7 @@ class TestMilestoneEditView(TestCaseWithFactory):
2221 self.assertEqual(expected, self.milestone.getTags())
2222
2223 def test_edit_milestone_clear_tags(self):
2224- orig_tags = u'ba ac'
2225+ orig_tags = 'ba ac'
2226 self.milestone.setTags(orig_tags.split(), self.owner)
2227 form = {
2228 'field.name': 'new-name',
2229@@ -365,7 +365,7 @@ class TestProjectMilestoneIndexQueryCount(TestQueryCountBase):
2230 layer = DatabaseFunctionalLayer
2231
2232 def setUp(self):
2233- super(TestProjectMilestoneIndexQueryCount, self).setUp()
2234+ super().setUp()
2235 self.owner = self.factory.makePerson(name='product-owner')
2236 self.product = self.factory.makeProduct(owner=self.owner)
2237 self.product_owner = self.product.owner
2238@@ -481,7 +481,7 @@ class TestProjectGroupMilestoneIndexQueryCount(TestQueryCountBase):
2239 layer = DatabaseFunctionalLayer
2240
2241 def setUp(self):
2242- super(TestProjectGroupMilestoneIndexQueryCount, self).setUp()
2243+ super().setUp()
2244 self.owner = self.factory.makePerson(name='product-owner')
2245 self.project_group = self.factory.makeProject(owner=self.owner)
2246 login_person(self.owner)
2247@@ -539,7 +539,7 @@ class TestDistributionMilestoneIndexQueryCount(TestQueryCountBase):
2248 layer = DatabaseFunctionalLayer
2249
2250 def setUp(self):
2251- super(TestDistributionMilestoneIndexQueryCount, self).setUp()
2252+ super().setUp()
2253 self.ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
2254 self.owner = self.factory.makePerson(name='test-owner')
2255 login_team(self.ubuntu.owner)
2256@@ -597,8 +597,8 @@ class TestMilestoneTagView(TestQueryCountBase):
2257 layer = DatabaseFunctionalLayer
2258
2259 def setUp(self):
2260- super(TestMilestoneTagView, self).setUp()
2261- self.tags = [u'tag1']
2262+ super().setUp()
2263+ self.tags = ['tag1']
2264 self.owner = self.factory.makePerson()
2265 self.project_group = self.factory.makeProject(owner=self.owner)
2266 self.product = self.factory.makeProduct(
2267@@ -620,8 +620,8 @@ class TestMilestoneTagView(TestQueryCountBase):
2268
2269 def _make_form(self, tags):
2270 return {
2271- u'field.actions.search': u'Search',
2272- u'field.tags': u' '.join(tags),
2273+ 'field.actions.search': 'Search',
2274+ 'field.tags': ' '.join(tags),
2275 }
2276
2277 def _url_tail(self, url, separator='/'):
2278@@ -636,7 +636,7 @@ class TestMilestoneTagView(TestQueryCountBase):
2279
2280 def test_view_form_redirect(self):
2281 # Ensure a correct redirection is performed when tags are searched.
2282- tags = [u'tag1', u'tag2']
2283+ tags = ['tag1', 'tag2']
2284 form = self._make_form(tags)
2285 view = create_initialized_view(self.milestonetag, '+index', form=form)
2286 self.assertEqual(302, view.request.response.getStatus())
2287@@ -648,7 +648,7 @@ class TestMilestoneTagView(TestQueryCountBase):
2288
2289 def test_view_form_error(self):
2290 # Ensure the form correctly handles invalid submissions.
2291- tags = [u'tag1', u't'] # One char tag is not valid.
2292+ tags = ['tag1', 't'] # One char tag is not valid.
2293 form = self._make_form(tags)
2294 view = create_initialized_view(self.milestonetag, '+index', form=form)
2295 self.assertEqual(1, len(view.errors))
2296diff --git a/lib/lp/registry/browser/tests/test_ociproject.py b/lib/lp/registry/browser/tests/test_ociproject.py
2297index 4557d1d..05babda 100644
2298--- a/lib/lp/registry/browser/tests/test_ociproject.py
2299+++ b/lib/lp/registry/browser/tests/test_ociproject.py
2300@@ -85,7 +85,7 @@ class TestOCIProjectView(OCIConfigHelperMixin, BrowserTestCase):
2301 layer = DatabaseFunctionalLayer
2302
2303 def setUp(self):
2304- super(TestOCIProjectView, self).setUp()
2305+ super().setUp()
2306 self.setConfig()
2307
2308 def test_facet_top_links(self):
2309diff --git a/lib/lp/registry/browser/tests/test_packaging.py b/lib/lp/registry/browser/tests/test_packaging.py
2310index 35ffc0c..770ff37 100644
2311--- a/lib/lp/registry/browser/tests/test_packaging.py
2312+++ b/lib/lp/registry/browser/tests/test_packaging.py
2313@@ -36,12 +36,12 @@ class TestProductSeriesUbuntuPackagingView(WithScenarios, TestCaseWithFactory):
2314 scenarios = [
2315 ("spn_picker", {"features": {}}),
2316 ("dsp_picker", {
2317- "features": {u"disclosure.dsp_picker.enabled": u"on"},
2318+ "features": {"disclosure.dsp_picker.enabled": "on"},
2319 }),
2320 ]
2321
2322 def setUp(self):
2323- super(TestProductSeriesUbuntuPackagingView, self).setUp()
2324+ super().setUp()
2325 if self.features:
2326 self.useFixture(FeatureFixture(self.features))
2327 self.ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
2328@@ -150,7 +150,7 @@ class TestBrowserDeletePackaging(TestCaseWithFactory):
2329 layer = DatabaseFunctionalLayer
2330
2331 def setUp(self):
2332- super(TestBrowserDeletePackaging, self).setUp()
2333+ super().setUp()
2334 # Only the person which created the packaging, admins
2335 # and other people with certain privileges can delete a
2336 # packaging. Since the sample data record we'll use for
2337diff --git a/lib/lp/registry/browser/tests/test_peoplemerge.py b/lib/lp/registry/browser/tests/test_peoplemerge.py
2338index aa359fd..939e432 100644
2339--- a/lib/lp/registry/browser/tests/test_peoplemerge.py
2340+++ b/lib/lp/registry/browser/tests/test_peoplemerge.py
2341@@ -37,13 +37,13 @@ from lp.testing.views import (
2342 class RequestPeopleMergeMixin(TestCaseWithFactory):
2343
2344 def setUp(self):
2345- super(RequestPeopleMergeMixin, self).setUp()
2346+ super().setUp()
2347 self.person_set = getUtility(IPersonSet)
2348 self.dupe = self.factory.makePerson(
2349 name='foo', email='foo@baz.com')
2350
2351 def tearDown(self):
2352- super(RequestPeopleMergeMixin, self).tearDown()
2353+ super().tearDown()
2354 stub.test_emails = []
2355
2356
2357@@ -53,7 +53,7 @@ class TestRequestPeopleMergeMultipleEmails(RequestPeopleMergeMixin):
2358 layer = DatabaseFunctionalLayer
2359
2360 def setUp(self):
2361- super(TestRequestPeopleMergeMultipleEmails, self).setUp()
2362+ super().setUp()
2363 EmailAddressSet().new(
2364 'bar.foo@canonical.com', person=self.dupe,
2365 status=EmailAddressStatus.VALIDATED)
2366@@ -72,8 +72,8 @@ class TestRequestPeopleMergeMultipleEmails(RequestPeopleMergeMixin):
2367 explanation = find_tag_by_id(browser.contents, 'explanation')
2368 self.assertThat(
2369 extract_text(explanation), DocTestMatches(
2370- u"The account..."
2371- u"has more than one registered email address..."))
2372+ "The account..."
2373+ "has more than one registered email address..."))
2374 email_select_control = browser.getControl(name='selected')
2375 for ctrl in email_select_control.controls:
2376 ctrl.selected = True
2377@@ -213,7 +213,7 @@ class TestRequestPeopleMergeHiddenEmailAddresses(RequestPeopleMergeMixin):
2378 layer = DatabaseFunctionalLayer
2379
2380 def setUp(self):
2381- super(TestRequestPeopleMergeHiddenEmailAddresses, self).setUp()
2382+ super().setUp()
2383 removeSecurityProxy(self.dupe).hide_email_addresses = True
2384 EmailAddressSet().new(
2385 'bar.foo@canonical.com', person=self.dupe,
2386@@ -257,7 +257,7 @@ class TestValidatingMergeView(TestCaseWithFactory):
2387 layer = DatabaseFunctionalLayer
2388
2389 def setUp(self):
2390- super(TestValidatingMergeView, self).setUp()
2391+ super().setUp()
2392 self.person_set = getUtility(IPersonSet)
2393 self.dupe = self.factory.makePerson(name='dupe')
2394 self.target = self.factory.makePerson(name='target')
2395@@ -281,7 +281,7 @@ class TestValidatingMergeView(TestCaseWithFactory):
2396 self.person_set, '+requestmerge', form=self.getForm())
2397 self.assertEqual(
2398 [html_escape(
2399- u"dupe has a PPA that must be deleted before it can be "
2400+ "dupe has a PPA that must be deleted before it can be "
2401 "merged. It may take ten minutes to remove the deleted PPA's "
2402 "files.")],
2403 view.errors)
2404@@ -294,7 +294,7 @@ class TestValidatingMergeView(TestCaseWithFactory):
2405 view = create_initialized_view(
2406 self.person_set, '+requestmerge', form=self.getForm())
2407 self.assertEqual(
2408- [u"dupe owns private branches that must be deleted or "
2409+ ["dupe owns private branches that must be deleted or "
2410 "transferred to another owner first."],
2411 view.errors)
2412
2413@@ -306,7 +306,7 @@ class TestValidatingMergeView(TestCaseWithFactory):
2414 view = create_initialized_view(
2415 self.person_set, '+requestmerge', form=self.getForm())
2416 self.assertEqual(
2417- [u"dupe owns private Git repositories that must be deleted or "
2418+ ["dupe owns private Git repositories that must be deleted or "
2419 "transferred to another owner first."],
2420 view.errors)
2421
2422@@ -352,7 +352,7 @@ class TestRequestPeopleMergeMultipleEmailsView(TestCaseWithFactory):
2423 layer = DatabaseFunctionalLayer
2424
2425 def setUp(self):
2426- super(TestRequestPeopleMergeMultipleEmailsView, self).setUp()
2427+ super().setUp()
2428 self.personset = getUtility(IPersonSet)
2429 self.dupe_user = self.factory.makePerson()
2430 self.email_2 = self.factory.makeEmail(
2431@@ -409,7 +409,7 @@ class TestAdminTeamMergeView(TestCaseWithFactory):
2432 layer = DatabaseFunctionalLayer
2433
2434 def setUp(self):
2435- super(TestAdminTeamMergeView, self).setUp()
2436+ super().setUp()
2437 self.person_set = getUtility(IPersonSet)
2438 self.dupe_team = self.factory.makeTeam(name='dupe-team')
2439 self.target_team = self.factory.makeTeam(name='target-team')
2440@@ -434,7 +434,7 @@ class TestAdminTeamMergeView(TestCaseWithFactory):
2441 view = self.getView()
2442 self.assertEqual(
2443 [html_escape(
2444- u"dupe-team has a PPA that must be deleted before it can be "
2445+ "dupe-team has a PPA that must be deleted before it can be "
2446 "merged. It may take ten minutes to remove the deleted PPA's "
2447 "files.")],
2448 view.errors)
2449@@ -446,7 +446,7 @@ class TestAdminPeopleMergeView(TestCaseWithFactory):
2450 layer = DatabaseFunctionalLayer
2451
2452 def setUp(self):
2453- super(TestAdminPeopleMergeView, self).setUp()
2454+ super().setUp()
2455 self.person_set = getUtility(IPersonSet)
2456 self.dupe_person = self.factory.makePerson(name='dupe-person')
2457 self.target_person = self.factory.makePerson()
2458@@ -470,7 +470,7 @@ class TestAdminPeopleMergeView(TestCaseWithFactory):
2459 view = self.getView()
2460 self.assertEqual(
2461 [html_escape(
2462- u"dupe-person has a PPA that must be deleted before it can "
2463+ "dupe-person has a PPA that must be deleted before it can "
2464 "be merged. It may take ten minutes to remove the deleted "
2465 "PPA's files.")],
2466 view.errors)
2467diff --git a/lib/lp/registry/browser/tests/test_person.py b/lib/lp/registry/browser/tests/test_person.py
2468index bed2125..1a1624f 100644
2469--- a/lib/lp/registry/browser/tests/test_person.py
2470+++ b/lib/lp/registry/browser/tests/test_person.py
2471@@ -593,7 +593,7 @@ class TestPersonViewKarma(TestCaseWithFactory):
2472 layer = LaunchpadZopelessLayer
2473
2474 def setUp(self):
2475- super(TestPersonViewKarma, self).setUp()
2476+ super().setUp()
2477 person = self.factory.makePerson()
2478 product = self.factory.makeProduct()
2479 transaction.commit()
2480@@ -612,7 +612,7 @@ class TestPersonViewKarma(TestCaseWithFactory):
2481 for category in categories:
2482 category_names.append(category.name)
2483
2484- self.assertEqual(category_names, [u'code', u'bugs', u'answers'],
2485+ self.assertEqual(category_names, ['code', 'bugs', 'answers'],
2486 'Categories are not sorted correctly')
2487
2488 def _makeKarmaCache(self, person, product, category, value=10):
2489@@ -781,7 +781,7 @@ class TestPersonEditView(TestPersonRenameFormMixin, TestCaseWithFactory):
2490 layer = LaunchpadFunctionalLayer
2491
2492 def setUp(self):
2493- super(TestPersonEditView, self).setUp()
2494+ super().setUp()
2495 self.valid_email_address = self.factory.getUniqueEmailAddress()
2496 self.person = self.factory.makePerson(email=self.valid_email_address)
2497 login_person(self.person)
2498@@ -846,7 +846,7 @@ class TestPersonEditView(TestPersonRenameFormMixin, TestCaseWithFactory):
2499 """Special assert function for dealing with email-related errors."""
2500 view = self.createAddEmailView(email_str)
2501 error_msg = view.errors[0]
2502- if not isinstance(error_msg, six.text_type):
2503+ if not isinstance(error_msg, str):
2504 error_msg = error_msg.doc()
2505 self.assertEqual(expected_msg, error_msg)
2506
2507@@ -865,7 +865,7 @@ class TestPersonEditView(TestPersonRenameFormMixin, TestCaseWithFactory):
2508 notifications = view.request.response.notifications
2509 self.assertEqual(1, len(notifications))
2510 expected_msg = html_escape(
2511- u"A confirmation message has been sent to '%s'."
2512+ "A confirmation message has been sent to '%s'."
2513 " Follow the instructions in that message to confirm"
2514 " that the address is yours. (If the message doesn't arrive in a"
2515 " few minutes, your mail provider might use 'greylisting', which"
2516@@ -911,7 +911,7 @@ class TestPersonEditView(TestPersonRenameFormMixin, TestCaseWithFactory):
2517 notifications = view.request.response.notifications
2518 self.assertEqual(1, len(notifications))
2519 expected_msg = html_escape(
2520- u"An email message was sent to '%s' "
2521+ "An email message was sent to '%s' "
2522 "with instructions on how to confirm that it belongs to you."
2523 % added_email)
2524 self.assertEqual(expected_msg, notifications[0].message)
2525@@ -941,12 +941,12 @@ class TestPersonEditView(TestPersonRenameFormMixin, TestCaseWithFactory):
2526 token_url = get_token_url_from_email(raw_msg)
2527 browser = setupBrowserForUser(user=self.person)
2528 browser.open(token_url)
2529- expected_msg = u'Confirm email address <code>%s</code>' % added_email
2530+ expected_msg = 'Confirm email address <code>%s</code>' % added_email
2531 self.assertIn(expected_msg, browser.contents)
2532 browser.getControl('Continue').click()
2533 # Login again to access displayname, since browser logged us out.
2534 login_person(self.person)
2535- expected_title = u'%s in Launchpad' % self.person.displayname
2536+ expected_title = '%s in Launchpad' % self.person.displayname
2537 self.assertEqual(expected_title, browser.title)
2538
2539 def test_remove_unvalidated_email_address(self):
2540@@ -961,7 +961,7 @@ class TestPersonEditView(TestPersonRenameFormMixin, TestCaseWithFactory):
2541 notifications = view.request.response.notifications
2542 self.assertEqual(1, len(notifications))
2543 expected_msg = html_escape(
2544- u"The email address '%s' has been removed." % added_email)
2545+ "The email address '%s' has been removed." % added_email)
2546 self.assertEqual(expected_msg, notifications[0].message)
2547
2548 def test_cannot_remove_contact_address(self):
2549@@ -990,7 +990,7 @@ class TestPersonEditView(TestPersonRenameFormMixin, TestCaseWithFactory):
2550 notifications = view.request.response.notifications
2551 self.assertEqual(1, len(notifications))
2552 expected_msg = (
2553- u"Your contact address has been changed to: %s" % added_email)
2554+ "Your contact address has been changed to: %s" % added_email)
2555 self.assertEqual(expected_msg, notifications[0].message)
2556
2557 def test_set_contact_address_already_set(self):
2558@@ -1022,21 +1022,21 @@ class TestPersonEditView(TestPersonRenameFormMixin, TestCaseWithFactory):
2559 def test_email_string_validation_no_email_prodvided(self):
2560 """+editemails should warn if no email is provided."""
2561 no_email = ''
2562- expected_msg = u'Required input is missing.'
2563+ expected_msg = 'Required input is missing.'
2564 self._assertEmailAndError(no_email, expected_msg)
2565
2566 def test_email_string_validation_invalid_email(self):
2567 """+editemails should warn when provided data is not an email."""
2568 not_an_email = 'foo'
2569 expected_msg = html_escape(
2570- u"'foo' doesn't seem to be a valid email address.")
2571+ "'foo' doesn't seem to be a valid email address.")
2572 self._assertEmailAndError(not_an_email, expected_msg)
2573
2574 def test_email_string_validation_is_escaped(self):
2575 """+editemails should escape output to prevent XSS."""
2576 xss_email = "foo@example.com<script>window.alert('XSS')</script>"
2577 expected_msg = (
2578- u"&#x27;foo@example.com&lt;script&gt;"
2579+ "&#x27;foo@example.com&lt;script&gt;"
2580 "window.alert(&#x27;XSS&#x27;)&lt;/script&gt;&#x27;"
2581 " doesn&#x27;t seem to be a valid email address.")
2582 self._assertEmailAndError(xss_email, expected_msg)
2583@@ -1056,7 +1056,7 @@ class TestPersonParticipationView(TestCaseWithFactory):
2584 layer = DatabaseFunctionalLayer
2585
2586 def setUp(self):
2587- super(TestPersonParticipationView, self).setUp()
2588+ super().setUp()
2589 self.user = self.factory.makePerson()
2590 self.view = create_view(self.user, name='+participation')
2591
2592@@ -1234,7 +1234,7 @@ class TestPersonRelatedPackagesView(TestCaseWithFactory):
2593 layer = LaunchpadFunctionalLayer
2594
2595 def setUp(self):
2596- super(TestPersonRelatedPackagesView, self).setUp()
2597+ super().setUp()
2598 self.user = self.factory.makePerson()
2599 self.factory.makeGPGKey(self.user)
2600 self.ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
2601@@ -1328,7 +1328,7 @@ class TestPersonMaintainedPackagesView(TestCaseWithFactory):
2602 layer = DatabaseFunctionalLayer
2603
2604 def setUp(self):
2605- super(TestPersonMaintainedPackagesView, self).setUp()
2606+ super().setUp()
2607 self.user = self.factory.makePerson()
2608 self.view = create_initialized_view(self.user, '+maintained-packages')
2609
2610@@ -1347,7 +1347,7 @@ class TestPersonUploadedPackagesView(TestCaseWithFactory):
2611 layer = DatabaseFunctionalLayer
2612
2613 def setUp(self):
2614- super(TestPersonUploadedPackagesView, self).setUp()
2615+ super().setUp()
2616 self.user = self.factory.makePerson()
2617 archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
2618 spr = self.factory.makeSourcePackageRelease(
2619@@ -1371,7 +1371,7 @@ class TestPersonPPAPackagesView(TestCaseWithFactory):
2620 layer = DatabaseFunctionalLayer
2621
2622 def setUp(self):
2623- super(TestPersonPPAPackagesView, self).setUp()
2624+ super().setUp()
2625 self.user = self.factory.makePerson()
2626 self.view = create_initialized_view(self.user, '+ppa-packages')
2627
2628@@ -1432,7 +1432,7 @@ class TestPersonSynchronisedPackagesView(TestCaseWithFactory):
2629 layer = DatabaseFunctionalLayer
2630
2631 def setUp(self):
2632- super(TestPersonSynchronisedPackagesView, self).setUp()
2633+ super().setUp()
2634 user = self.factory.makePerson()
2635 archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
2636 spr = self.factory.makeSourcePackageRelease(
2637@@ -1463,7 +1463,7 @@ class TestPersonRelatedProjectsView(TestCaseWithFactory):
2638 layer = DatabaseFunctionalLayer
2639
2640 def setUp(self):
2641- super(TestPersonRelatedProjectsView, self).setUp()
2642+ super().setUp()
2643 self.user = self.factory.makePerson()
2644
2645 def test_view_helper_attributes(self):
2646@@ -1498,7 +1498,7 @@ class TestPersonOCIRegistryCredentialsView(
2647 ]
2648
2649 def setUp(self):
2650- super(TestPersonOCIRegistryCredentialsView, self).setUp()
2651+ super().setUp()
2652 self.setConfig()
2653 if self.use_team:
2654 self.owner = self.factory.makeTeam(members=[self.user])
2655@@ -1721,7 +1721,7 @@ class TestPersonLiveFSView(BrowserTestCase):
2656 layer = DatabaseFunctionalLayer
2657
2658 def setUp(self):
2659- super(TestPersonLiveFSView, self).setUp()
2660+ super().setUp()
2661 self.useFixture(FeatureFixture({LIVEFS_FEATURE_FLAG: "on"}))
2662 self.person = self.factory.makePerson(
2663 name="test-person", displayname="Test Person")
2664@@ -1869,7 +1869,7 @@ class TestPersonRelatedPackagesFailedBuild(TestCaseWithFactory):
2665 layer = LaunchpadFunctionalLayer
2666
2667 def setUp(self):
2668- super(TestPersonRelatedPackagesFailedBuild, self).setUp()
2669+ super().setUp()
2670 self.user = self.factory.makePerson()
2671
2672 # First we need to publish some PPA packages with failed builds
2673@@ -1923,7 +1923,7 @@ class TestPersonRelatedPackagesSynchronisedPackages(TestCaseWithFactory):
2674 layer = LaunchpadFunctionalLayer
2675
2676 def setUp(self):
2677- super(TestPersonRelatedPackagesSynchronisedPackages, self).setUp()
2678+ super().setUp()
2679 self.user = self.factory.makePerson()
2680 self.spph = self.factory.makeSourcePackagePublishingHistory()
2681
2682@@ -2023,7 +2023,7 @@ class TestTeamInvitationView(TestCaseWithFactory):
2683 layer = DatabaseFunctionalLayer
2684
2685 def setUp(self):
2686- super(TestTeamInvitationView, self).setUp()
2687+ super().setUp()
2688 self.a_team = self.factory.makeTeam(name="team-a",
2689 displayname="A-Team")
2690 self.b_team = self.factory.makeTeam(name="team-b",
2691@@ -2046,7 +2046,7 @@ class TestTeamInvitationView(TestCaseWithFactory):
2692 notifications = view.request.response.notifications
2693 self.assertEqual(1, len(notifications))
2694 self.assertEqual(
2695- u'B-Team (team-b) has been invited to join this team.',
2696+ 'B-Team (team-b) has been invited to join this team.',
2697 notifications[0].message)
2698
2699 # B invites A.
2700@@ -2058,7 +2058,7 @@ class TestTeamInvitationView(TestCaseWithFactory):
2701 notifications = view.request.response.notifications
2702 self.assertEqual(1, len(notifications))
2703 self.assertEqual(
2704- u'A-Team (team-a) has been invited to join this team.',
2705+ 'A-Team (team-a) has been invited to join this team.',
2706 notifications[0].message)
2707
2708 # Team A accepts the invitation.
2709@@ -2078,7 +2078,7 @@ class TestTeamInvitationView(TestCaseWithFactory):
2710 notifications = view.request.response.notifications
2711 self.assertEqual(1, len(notifications))
2712 self.assertEqual(
2713- u'This team is now a member of B-Team.',
2714+ 'This team is now a member of B-Team.',
2715 notifications[0].message)
2716
2717 # Team B attempts to accept the invitation.
2718@@ -2093,7 +2093,7 @@ class TestTeamInvitationView(TestCaseWithFactory):
2719 notifications = view.request.response.notifications
2720 self.assertEqual(1, len(notifications))
2721 expected = (
2722- u'This team may not be added to A-Team because it is a member '
2723+ 'This team may not be added to A-Team because it is a member '
2724 'of B-Team.')
2725 self.assertEqual(
2726 expected,
2727@@ -2105,8 +2105,7 @@ class TestSubscriptionsView(TestCaseWithFactory):
2728 layer = LaunchpadFunctionalLayer
2729
2730 def setUp(self):
2731- super(TestSubscriptionsView, self).setUp(
2732- user='test@canonical.com')
2733+ super().setUp(user='test@canonical.com')
2734 self.user = getUtility(ILaunchBag).user
2735 self.person = self.factory.makePerson()
2736 self.other_person = self.factory.makePerson()
2737@@ -2135,7 +2134,7 @@ class BugTaskViewsTestBase:
2738 layer = DatabaseFunctionalLayer
2739
2740 def setUp(self):
2741- super(BugTaskViewsTestBase, self).setUp()
2742+ super().setUp()
2743 self.person = self.factory.makePerson()
2744 with person_logged_in(self.person):
2745 self.subscribed_bug = self.factory.makeBug()
2746@@ -2189,7 +2188,7 @@ class TestPersonRelatedBugTaskSearchListingView(
2747 view_name = '+bugs'
2748
2749 def setUp(self):
2750- super(TestPersonRelatedBugTaskSearchListingView, self).setUp()
2751+ super().setUp()
2752 self.expected_for_search_unbatched = [
2753 self.subscribed_bug.default_bugtask,
2754 self.assigned_bug.default_bugtask,
2755@@ -2205,7 +2204,7 @@ class TestPersonAssignedBugTaskSearchListingView(
2756 view_name = '+assignedbugs'
2757
2758 def setUp(self):
2759- super(TestPersonAssignedBugTaskSearchListingView, self).setUp()
2760+ super().setUp()
2761 self.expected_for_search_unbatched = [
2762 self.assigned_bug.default_bugtask,
2763 ]
2764@@ -2218,7 +2217,7 @@ class TestPersonCommentedBugTaskSearchListingView(
2765 view_name = '+commentedbugs'
2766
2767 def setUp(self):
2768- super(TestPersonCommentedBugTaskSearchListingView, self).setUp()
2769+ super().setUp()
2770 self.expected_for_search_unbatched = [
2771 self.commented_bug.default_bugtask,
2772 ]
2773@@ -2231,7 +2230,7 @@ class TestPersonReportedBugTaskSearchListingView(
2774 view_name = '+reportedbugs'
2775
2776 def setUp(self):
2777- super(TestPersonReportedBugTaskSearchListingView, self).setUp()
2778+ super().setUp()
2779 self.expected_for_search_unbatched = [
2780 self.owned_bug.default_bugtask,
2781 ]
2782@@ -2244,7 +2243,7 @@ class TestPersonSubscribedBugTaskSearchListingView(
2783 view_name = '+subscribedbugs'
2784
2785 def setUp(self):
2786- super(TestPersonSubscribedBugTaskSearchListingView, self).setUp()
2787+ super().setUp()
2788 self.expected_for_search_unbatched = [
2789 self.subscribed_bug.default_bugtask,
2790 self.owned_bug.default_bugtask,
2791@@ -2258,7 +2257,7 @@ class TestPersonAffectingBugTaskSearchListingView(
2792 view_name = '+affectingbugs'
2793
2794 def setUp(self):
2795- super(TestPersonAffectingBugTaskSearchListingView, self).setUp()
2796+ super().setUp()
2797 # Bugs filed by this user are marked as affecting them by default, so
2798 # the bug we filed is returned.
2799 self.expected_for_search_unbatched = [
2800diff --git a/lib/lp/registry/browser/tests/test_person_contact.py b/lib/lp/registry/browser/tests/test_person_contact.py
2801index 3696a64..4d26d16 100644
2802--- a/lib/lp/registry/browser/tests/test_person_contact.py
2803+++ b/lib/lp/registry/browser/tests/test_person_contact.py
2804@@ -424,7 +424,7 @@ class EmailToPersonViewTestCase(TestCaseWithFactory):
2805 with person_logged_in(sender):
2806 view = create_initialized_view(user, '+contactuser', form=form)
2807 self.assertEqual(
2808- [u'You must provide a subject and a message.'], view.errors)
2809+ ['You must provide a subject and a message.'], view.errors)
2810
2811 def test_submitted_after_quota(self):
2812 # The view explains when a message was not sent because the quota
2813diff --git a/lib/lp/registry/browser/tests/test_person_webservice.py b/lib/lp/registry/browser/tests/test_person_webservice.py
2814index 2f5bc88..6d2ccdb 100644
2815--- a/lib/lp/registry/browser/tests/test_person_webservice.py
2816+++ b/lib/lp/registry/browser/tests/test_person_webservice.py
2817@@ -50,7 +50,7 @@ class TestPersonEmailSecurity(TestCaseWithFactory):
2818 layer = DatabaseFunctionalLayer
2819
2820 def setUp(self):
2821- super(TestPersonEmailSecurity, self).setUp()
2822+ super().setUp()
2823 self.target = self.factory.makePerson(name='target')
2824 self.email_one = self.factory.makeEmail(
2825 'test1@example.com', self.target)
2826@@ -87,7 +87,7 @@ class TestPersonAccountStatus(TestCaseWithFactory):
2827 person = self.factory.makePerson()
2828 registrar = self.factory.makePerson(
2829 member_of=[getUtility(IPersonSet).getByName('registry')])
2830- removeSecurityProxy(person.account).status_history = u'Test'
2831+ removeSecurityProxy(person.account).status_history = 'Test'
2832 person_url = api_url(person)
2833
2834 # A normal user cannot read account_status_history. Not even
2835@@ -178,7 +178,7 @@ class PersonWebServiceTests(TestCaseWithFactory):
2836 team.addMember(person, owner)
2837 getUtility(ITeamMembershipSet).getByPersonAndTeam(
2838 person, team).setStatus(
2839- TeamMembershipStatus.DEACTIVATED, owner, u"Go away.")
2840+ TeamMembershipStatus.DEACTIVATED, owner, "Go away.")
2841
2842 def get_members():
2843 ws.get('/~%s/deactivated_members' % name).jsonBody()
2844@@ -250,7 +250,7 @@ class PersonSetWebServiceTests(TestCaseWithFactory):
2845 layer = DatabaseFunctionalLayer
2846
2847 def setUp(self):
2848- super(PersonSetWebServiceTests, self).setUp()
2849+ super().setUp()
2850 self.webservice = webservice_for_person(None)
2851
2852 def assertReturnsPeople(self, expected_names, path):
2853@@ -309,7 +309,7 @@ class PersonSetWebServiceTests(TestCaseWithFactory):
2854 def test_find_by_date(self):
2855 # Creation date filtering is supported.
2856 self.assertReturnsPeople(
2857- [u'bac'],
2858+ ['bac'],
2859 '/people?ws.op=findPerson&text='
2860 '&created_after=2008-06-27&created_before=2008-07-01')
2861
2862@@ -401,7 +401,7 @@ class PersonSetWebServiceTests(TestCaseWithFactory):
2863 account_status=AccountStatus.SUSPENDED)
2864 oid = OpenIdIdentifier()
2865 oid.account = existing.account
2866- oid.identifier = u'somebody'
2867+ oid.identifier = 'somebody'
2868 Store.of(existing).add(oid)
2869 sca = getUtility(IPersonSet).getByName('software-center-agent')
2870 response = self.getOrCreateSoftwareCenterCustomer(sca)
2871@@ -415,7 +415,7 @@ class PersonSetWebServiceTests(TestCaseWithFactory):
2872 account_status=AccountStatus.DECEASED)
2873 oid = OpenIdIdentifier()
2874 oid.account = existing.account
2875- oid.identifier = u'somebody'
2876+ oid.identifier = 'somebody'
2877 Store.of(existing).add(oid)
2878 sca = getUtility(IPersonSet).getByName('software-center-agent')
2879 response = self.getOrCreateSoftwareCenterCustomer(sca)
2880@@ -468,7 +468,7 @@ class PersonSetWebServiceTests(TestCaseWithFactory):
2881 with admin_logged_in():
2882 by_name = getUtility(IPersonSet).getByName('bar')
2883 by_openid = getUtility(IPersonSet).getByOpenIDIdentifier(
2884- u'http://testopenid.test/+id/foo')
2885+ 'http://testopenid.test/+id/foo')
2886 self.assertEqual(by_name, by_openid)
2887 self.assertEqual(
2888 AccountStatus.PLACEHOLDER, by_name.account_status)
2889@@ -485,7 +485,7 @@ class PersonSetWebServiceTests(TestCaseWithFactory):
2890 self.assertIs(None, getUtility(IPersonSet).getByName('bar'))
2891 self.assertRaises(
2892 LookupError,
2893- getUtility(IAccountSet).getByOpenIDIdentifier, u'foo')
2894+ getUtility(IAccountSet).getByOpenIDIdentifier, 'foo')
2895
2896 def test_setUsernameFromSSO_is_restricted(self):
2897 # The method may only be invoked by the ~ubuntu-sso celebrity
2898diff --git a/lib/lp/registry/browser/tests/test_pillar_sharing.py b/lib/lp/registry/browser/tests/test_pillar_sharing.py
2899index dbfd6b2..8ef5a25 100644
2900--- a/lib/lp/registry/browser/tests/test_pillar_sharing.py
2901+++ b/lib/lp/registry/browser/tests/test_pillar_sharing.py
2902@@ -63,7 +63,7 @@ class SharingBaseTestCase(TestCaseWithFactory):
2903 pillar_type = None
2904
2905 def setUp(self):
2906- super(SharingBaseTestCase, self).setUp()
2907+ super().setUp()
2908 self.driver = self.factory.makePerson()
2909 self.owner = self.factory.makePerson()
2910 if self.pillar_type == 'distribution':
2911@@ -249,7 +249,7 @@ class TestProductSharingDetailsView(
2912 pillar_type = 'product'
2913
2914 def setUp(self):
2915- super(TestProductSharingDetailsView, self).setUp()
2916+ super().setUp()
2917 login_person(self.owner)
2918
2919
2920@@ -259,7 +259,7 @@ class TestDistributionSharingDetailsView(
2921 pillar_type = 'distribution'
2922
2923 def setUp(self):
2924- super(TestDistributionSharingDetailsView, self).setUp()
2925+ super().setUp()
2926 login_person(self.owner)
2927
2928
2929@@ -471,7 +471,7 @@ class TestProductSharingView(PillarSharingViewTestMixin,
2930 pillar_type = 'product'
2931
2932 def setUp(self):
2933- super(TestProductSharingView, self).setUp()
2934+ super().setUp()
2935 self.setupSharing(self.grantees)
2936 login_person(self.driver)
2937 # Use a FakeLogger fixture to prevent Memcached warnings to be
2938@@ -517,7 +517,7 @@ class TestDistributionSharingView(PillarSharingViewTestMixin,
2939 pillar_type = 'distribution'
2940
2941 def setUp(self):
2942- super(TestDistributionSharingView, self).setUp()
2943+ super().setUp()
2944 self.setupSharing(self.grantees)
2945 login_person(self.driver)
2946
2947diff --git a/lib/lp/registry/browser/tests/test_poll.py b/lib/lp/registry/browser/tests/test_poll.py
2948index 05f0183..b689df6 100644
2949--- a/lib/lp/registry/browser/tests/test_poll.py
2950+++ b/lib/lp/registry/browser/tests/test_poll.py
2951@@ -29,7 +29,7 @@ class TestPollVoteView(TestCaseWithFactory):
2952 layer = DatabaseFunctionalLayer
2953
2954 def setUp(self):
2955- super(TestPollVoteView, self).setUp()
2956+ super().setUp()
2957 self.team = self.factory.makeTeam()
2958
2959 def test_simple_poll_template(self):
2960@@ -55,7 +55,7 @@ class TestPollAddView(BrowserTestCase):
2961 layer = DatabaseFunctionalLayer
2962
2963 def setUp(self):
2964- super(TestPollAddView, self).setUp()
2965+ super().setUp()
2966 self.pushConfig(
2967 "launchpad", min_legitimate_karma=5, min_legitimate_account_age=5)
2968
2969diff --git a/lib/lp/registry/browser/tests/test_product.py b/lib/lp/registry/browser/tests/test_product.py
2970index 1f571fe..c79cbd1 100644
2971--- a/lib/lp/registry/browser/tests/test_product.py
2972+++ b/lib/lp/registry/browser/tests/test_product.py
2973@@ -206,7 +206,7 @@ class TestProductConfiguration(BrowserTestCase):
2974 layer = DatabaseFunctionalLayer
2975
2976 def setUp(self):
2977- super(TestProductConfiguration, self).setUp()
2978+ super().setUp()
2979 self.product = self.factory.makeProduct()
2980
2981 def test_registration_not_done(self):
2982@@ -295,7 +295,7 @@ class TestProductAddView(TestCaseWithFactory):
2983 layer = DatabaseFunctionalLayer
2984
2985 def setUp(self):
2986- super(TestProductAddView, self).setUp()
2987+ super().setUp()
2988 self.product_set = getUtility(IProductSet)
2989
2990 def test_view_data_model(self):
2991@@ -424,7 +424,7 @@ class TestProductView(BrowserTestCase):
2992 layer = DatabaseFunctionalLayer
2993
2994 def setUp(self):
2995- super(TestProductView, self).setUp()
2996+ super().setUp()
2997 self.product = self.factory.makeProduct(name='fnord')
2998 self.tag_meta_noindex = Tag(
2999 'meta_noindex', 'meta', attrs={
3000@@ -741,7 +741,7 @@ class TestProductEditView(BrowserTestCase):
3001 layer = DatabaseFunctionalLayer
3002
3003 def setUp(self):
3004- super(TestProductEditView, self).setUp()
3005+ super().setUp()
3006
3007 def _make_product_edit_form(self, product, proprietary=False):
3008 """Return form data for product edit.
3009@@ -927,7 +927,7 @@ class ProductSetReviewLicensesViewTestCase(TestCaseWithFactory):
3010 layer = LaunchpadFunctionalLayer
3011
3012 def setUp(self):
3013- super(ProductSetReviewLicensesViewTestCase, self).setUp()
3014+ super().setUp()
3015 self.product_set = getUtility(IProductSet)
3016 self.user = login_celebrity('registry_experts')
3017
3018diff --git a/lib/lp/registry/browser/tests/test_projectgroup.py b/lib/lp/registry/browser/tests/test_projectgroup.py
3019index 75c9d9f..a76ae7d 100644
3020--- a/lib/lp/registry/browser/tests/test_projectgroup.py
3021+++ b/lib/lp/registry/browser/tests/test_projectgroup.py
3022@@ -39,7 +39,7 @@ class TestProjectGroupView(BrowserTestCase):
3023 layer = DatabaseFunctionalLayer
3024
3025 def setUp(self):
3026- super(TestProjectGroupView, self).setUp()
3027+ super().setUp()
3028 self.project_group = self.factory.makeProject(name='group')
3029
3030 def test_view_data_model(self):
3031@@ -136,7 +136,7 @@ class TestProjectGroupEditView(TestCaseWithFactory):
3032 layer = DatabaseFunctionalLayer
3033
3034 def setUp(self):
3035- super(TestProjectGroupEditView, self).setUp()
3036+ super().setUp()
3037 self.project_group = self.factory.makeProject(name='group')
3038 # Use a FakeLogger fixture to prevent Memcached warnings to be
3039 # printed to stdout while browsing pages.
3040diff --git a/lib/lp/registry/browser/tests/test_reassign_team_view.py b/lib/lp/registry/browser/tests/test_reassign_team_view.py
3041index c5cba77..cad98ce 100644
3042--- a/lib/lp/registry/browser/tests/test_reassign_team_view.py
3043+++ b/lib/lp/registry/browser/tests/test_reassign_team_view.py
3044@@ -153,7 +153,7 @@ class TestTeamReassignmentViewErrors(TestCaseWithFactory):
3045 a_team, '+reassign', form=form, principal=owner)
3046 self.assertEqual(
3047 [html_escape(
3048- u"There's already a person/team with the name 'a-team' in "
3049+ "There's already a person/team with the name 'a-team' in "
3050 "Launchpad. Please choose a different name or select the "
3051 "option to make that person/team the new owner, if that's "
3052 "what you want.")],
3053diff --git a/lib/lp/registry/browser/tests/test_sourcepackage_views.py b/lib/lp/registry/browser/tests/test_sourcepackage_views.py
3054index eb5ccd3..dcb66d0 100644
3055--- a/lib/lp/registry/browser/tests/test_sourcepackage_views.py
3056+++ b/lib/lp/registry/browser/tests/test_sourcepackage_views.py
3057@@ -221,7 +221,7 @@ class TestSourcePackageUpstreamConnectionsView(TestCaseWithFactory):
3058 layer = DatabaseFunctionalLayer
3059
3060 def setUp(self):
3061- super(TestSourcePackageUpstreamConnectionsView, self).setUp()
3062+ super().setUp()
3063 productseries = self.factory.makeProductSeries(name='1.0')
3064 self.milestone = self.factory.makeMilestone(
3065 product=productseries.product, productseries=productseries)
3066diff --git a/lib/lp/registry/browser/tests/test_subscription_links.py b/lib/lp/registry/browser/tests/test_subscription_links.py
3067index 0c820b8..886e078 100644
3068--- a/lib/lp/registry/browser/tests/test_subscription_links.py
3069+++ b/lib/lp/registry/browser/tests/test_subscription_links.py
3070@@ -85,7 +85,7 @@ class _TestStructSubs(TestCaseWithFactory, _TestResultsMixin):
3071 layer = DatabaseFunctionalLayer
3072
3073 def setUp(self):
3074- super(_TestStructSubs, self).setUp()
3075+ super().setUp()
3076 self.regular_user = self.factory.makePerson()
3077 # Use a FakeLogger fixture to prevent Memcached warnings to be
3078 # printed to stdout while browsing pages.
3079@@ -123,7 +123,7 @@ class ProductView(_TestStructSubs):
3080 view = '+index'
3081
3082 def setUp(self):
3083- super(ProductView, self).setUp()
3084+ super().setUp()
3085 self.target = self.factory.makeProduct(official_malone=True)
3086
3087
3088@@ -141,7 +141,7 @@ class ProjectGroupView(_TestStructSubs):
3089 view = '+index'
3090
3091 def setUp(self):
3092- super(ProjectGroupView, self).setUp()
3093+ super().setUp()
3094 self.target = self.factory.makeProject()
3095 self.factory.makeProduct(
3096 projectgroup=self.target, official_malone=True)
3097@@ -183,7 +183,7 @@ class ProductSeriesView(_TestStructSubs):
3098 view = '+index'
3099
3100 def setUp(self):
3101- super(ProductSeriesView, self).setUp()
3102+ super().setUp()
3103 product = self.factory.makeProduct(official_malone=True)
3104 self.target = self.factory.makeProductSeries(product=product)
3105
3106@@ -195,7 +195,7 @@ class ProductSeriesBugs(ProductSeriesView):
3107 view = '+bugs'
3108
3109 def setUp(self):
3110- super(ProductSeriesBugs, self).setUp()
3111+ super().setUp()
3112 with person_logged_in(self.target.product.owner):
3113 self.target.product.official_malone = True
3114
3115@@ -207,7 +207,7 @@ class DistributionSourcePackageView(_TestStructSubs):
3116 view = '+index'
3117
3118 def setUp(self):
3119- super(DistributionSourcePackageView, self).setUp()
3120+ super().setUp()
3121 distro = self.factory.makeDistribution()
3122 with person_logged_in(distro.owner):
3123 distro.official_malone = True
3124@@ -242,7 +242,7 @@ class DistroView(BrowserTestCase, _TestResultsMixin):
3125 view = '+index'
3126
3127 def setUp(self):
3128- super(DistroView, self).setUp()
3129+ super().setUp()
3130 self.target = self.factory.makeDistribution()
3131 with person_logged_in(self.target.owner):
3132 self.target.official_malone = True
3133@@ -341,7 +341,7 @@ class DistroMilestoneView(DistroView):
3134 """Test structural subscriptions on the distro milestones."""
3135
3136 def setUp(self):
3137- super(DistroMilestoneView, self).setUp()
3138+ super().setUp()
3139 self.distro = self.target
3140 self.target = self.factory.makeMilestone(distribution=self.distro)
3141
3142@@ -380,7 +380,7 @@ class ProductMilestoneView(DistroView):
3143 """Test structural subscriptions on the product milestones."""
3144
3145 def setUp(self):
3146- super(ProductMilestoneView, self).setUp()
3147+ super().setUp()
3148 self.product = self.factory.makeProduct()
3149 with person_logged_in(self.product.owner):
3150 self.product.official_malone = True
3151@@ -411,7 +411,7 @@ class ProductSeriesMilestoneView(ProductMilestoneView):
3152 """Test structural subscriptions on the product series milestones."""
3153
3154 def setUp(self):
3155- super(ProductSeriesMilestoneView, self).setUp()
3156+ super().setUp()
3157 self.productseries = self.factory.makeProductSeries()
3158 with person_logged_in(self.productseries.product.owner):
3159 self.productseries.product.official_malone = True
3160@@ -426,7 +426,7 @@ class _DoesNotUseLP(ProductView):
3161 """Test structural subscriptions on the product view."""
3162
3163 def setUp(self):
3164- super(_DoesNotUseLP, self).setUp()
3165+ super().setUp()
3166 self.target = self.factory.makeProduct(official_malone=False)
3167
3168 def test_subscribe_link_owner(self):
3169@@ -472,7 +472,7 @@ class ProjectGroupDoesNotUseLPView(_DoesNotUseLP):
3170 view = '+index'
3171
3172 def setUp(self):
3173- super(ProjectGroupDoesNotUseLPView, self).setUp()
3174+ super().setUp()
3175 self.target = self.factory.makeProject()
3176 self.factory.makeProduct(
3177 projectgroup=self.target, official_malone=False)
3178@@ -485,7 +485,7 @@ class ProjectGroupDoesNotUseLPBugs(ProductDoesNotUseLPBugs):
3179 view = '+bugs'
3180
3181 def setUp(self):
3182- super(ProjectGroupDoesNotUseLPBugs, self).setUp()
3183+ super().setUp()
3184 self.target = self.factory.makeProject()
3185 self.factory.makeProduct(
3186 projectgroup=self.target, official_malone=False)
3187@@ -496,7 +496,7 @@ class ProjectGroupDoesNotUseLPBugs(ProductDoesNotUseLPBugs):
3188 class ProductSeriesDoesNotUseLPView(_DoesNotUseLP):
3189
3190 def setUp(self):
3191- super(ProductSeriesDoesNotUseLPView, self).setUp()
3192+ super().setUp()
3193 product = self.factory.makeProduct(official_malone=False)
3194 self.target = self.factory.makeProductSeries(product=product)
3195
3196@@ -504,7 +504,7 @@ class ProductSeriesDoesNotUseLPView(_DoesNotUseLP):
3197 class ProductSeriesDoesNotUseLPBugs(_DoesNotUseLP):
3198
3199 def setUp(self):
3200- super(ProductSeriesDoesNotUseLPBugs, self).setUp()
3201+ super().setUp()
3202 product = self.factory.makeProduct(official_malone=False)
3203 self.target = self.factory.makeProductSeries(product=product)
3204
3205@@ -513,7 +513,7 @@ class DistributionSourcePackageDoesNotUseLPView(_DoesNotUseLP):
3206 """Test structural subscriptions on the distro src pkg view."""
3207
3208 def setUp(self):
3209- super(DistributionSourcePackageDoesNotUseLPView, self).setUp()
3210+ super().setUp()
3211 distro = self.factory.makeDistribution()
3212 self.target = self.factory.makeDistributionSourcePackage(
3213 distribution=distro)
3214@@ -535,7 +535,7 @@ class DistributionSourcePackageDoesNotUseLPBugs(ProductDoesNotUseLPBugs):
3215 class DistroDoesNotUseLPView(DistroView):
3216
3217 def setUp(self):
3218- super(DistroDoesNotUseLPView, self).setUp()
3219+ super().setUp()
3220 self.target = self.factory.makeDistribution()
3221 self.regular_user = self.factory.makePerson()
3222
3223@@ -577,7 +577,7 @@ class DistroDoesNotUseLPBugs(DistroDoesNotUseLPView):
3224 class DistroMilestoneDoesNotUseLPView(DistroMilestoneView):
3225
3226 def setUp(self):
3227- super(DistroMilestoneDoesNotUseLPView, self).setUp()
3228+ super().setUp()
3229 with person_logged_in(self.distro.owner):
3230 self.distro.official_malone = False
3231
3232@@ -620,7 +620,7 @@ class DistroMilestoneDoesNotUseLPView(DistroMilestoneView):
3233 class ProductMilestoneDoesNotUseLPView(ProductMilestoneView):
3234
3235 def setUp(self):
3236- super(ProductMilestoneDoesNotUseLPView, self).setUp()
3237+ super().setUp()
3238 self.product = self.factory.makeProduct()
3239 with person_logged_in(self.product.owner):
3240 self.product.official_malone = False
3241@@ -648,8 +648,7 @@ class CustomTestLoader(unittest.TestLoader):
3242 if testCaseClass is _TestStructSubs:
3243 return []
3244 else:
3245- return super(CustomTestLoader, self).getTestCaseNames(
3246- testCaseClass)
3247+ return super().getTestCaseNames(testCaseClass)
3248
3249
3250 def test_suite():
3251diff --git a/lib/lp/registry/browser/tests/test_team.py b/lib/lp/registry/browser/tests/test_team.py
3252index 5a3f781..fb02cb2 100644
3253--- a/lib/lp/registry/browser/tests/test_team.py
3254+++ b/lib/lp/registry/browser/tests/test_team.py
3255@@ -70,7 +70,7 @@ class TestProposedTeamMembersEditView(TestCaseWithFactory):
3256 layer = DatabaseFunctionalLayer
3257
3258 def setUp(self):
3259- super(TestProposedTeamMembersEditView, self).setUp()
3260+ super().setUp()
3261 self.owner = self.factory.makePerson(name="team-owner")
3262 self.a_team = self.makeTeam("team-a", "A-Team")
3263 self.b_team = self.makeTeam("team-b", "B-Team")
3264@@ -97,7 +97,7 @@ class TestProposedTeamMembersEditView(TestCaseWithFactory):
3265 self.assertEqual([], view.errors)
3266 notifications = view.request.response.notifications
3267 self.assertEqual(1, len(notifications))
3268- expected = u"%s has been proposed to this team." % (
3269+ expected = "%s has been proposed to this team." % (
3270 joiner.displayname)
3271 self.assertEqual(
3272 expected,
3273@@ -112,13 +112,13 @@ class TestProposedTeamMembersEditView(TestCaseWithFactory):
3274 failed_names = ', '.join([team.displayname for team in failed])
3275 if len(failed) == 1:
3276 failed_message = html_escape(
3277- u'%s is a member of the following team, '
3278+ '%s is a member of the following team, '
3279 'so it could not be accepted: %s. '
3280 'You need to "Decline" that team.' %
3281 (joinee.displayname, failed_names))
3282 else:
3283 failed_message = html_escape(
3284- u'%s is a member of the following teams, '
3285+ '%s is a member of the following teams, '
3286 'so they could not be accepted: %s. '
3287 'You need to "Decline" those teams.' %
3288 (joinee.displayname, failed_names))
3289@@ -605,7 +605,7 @@ class TestTeamMenu(TestCaseWithFactory):
3290 layer = DatabaseFunctionalLayer
3291
3292 def setUp(self):
3293- super(TestTeamMenu, self).setUp()
3294+ super().setUp()
3295 self.team = self.factory.makeTeam()
3296
3297 def test_TeamIndexMenu(self):
3298@@ -754,7 +754,7 @@ class TestTeamMemberAddView(TestCaseWithFactory):
3299 layer = DatabaseFunctionalLayer
3300
3301 def setUp(self):
3302- super(TestTeamMemberAddView, self).setUp()
3303+ super().setUp()
3304 self.team = self.factory.makeTeam(name='test-team')
3305 login_person(self.team.teamowner)
3306
3307@@ -844,7 +844,7 @@ class TeamMembershipViewTestCase(TestCaseWithFactory):
3308 team = self.factory.makeTeam(name='pting')
3309 view = create_initialized_view(team, name='+members')
3310 self.assertEqual('Members', view.page_title)
3311- self.assertEqual(u'Members of \u201cPting\u201d', view.label)
3312+ self.assertEqual('Members of \u201cPting\u201d', view.label)
3313
3314
3315 class TestTeamIndexView(TestCaseWithFactory):
3316@@ -852,7 +852,7 @@ class TestTeamIndexView(TestCaseWithFactory):
3317 layer = DatabaseFunctionalLayer
3318
3319 def setUp(self):
3320- super(TestTeamIndexView, self).setUp()
3321+ super().setUp()
3322 self.team = self.factory.makeTeam(name='test-team')
3323 login_person(self.team.teamowner)
3324
3325diff --git a/lib/lp/registry/browser/tests/test_teammembership.py b/lib/lp/registry/browser/tests/test_teammembership.py
3326index 21c953f..a87d121 100644
3327--- a/lib/lp/registry/browser/tests/test_teammembership.py
3328+++ b/lib/lp/registry/browser/tests/test_teammembership.py
3329@@ -23,7 +23,7 @@ class TestTeamMenu(TestCaseWithFactory):
3330 layer = DatabaseFunctionalLayer
3331
3332 def setUp(self):
3333- super(TestTeamMenu, self).setUp()
3334+ super().setUp()
3335 login_celebrity('admin')
3336 self.membership_set = getUtility(ITeamMembershipSet)
3337 self.team = self.factory.makeTeam()
3338diff --git a/lib/lp/registry/browser/widgets/ocicredentialswidget.py b/lib/lp/registry/browser/widgets/ocicredentialswidget.py
3339index b47f436..924903d 100644
3340--- a/lib/lp/registry/browser/widgets/ocicredentialswidget.py
3341+++ b/lib/lp/registry/browser/widgets/ocicredentialswidget.py
3342@@ -113,7 +113,7 @@ class OCICredentialsWidget(BrowserWidget, InputWidget):
3343 self.getInputValue()
3344 except InputErrors as error:
3345 self._error = error
3346- return super(OCICredentialsWidget, self).error()
3347+ return super().error()
3348
3349 def setRenderedValue(self, value):
3350 """See `IInputWidget`."""
3351diff --git a/lib/lp/registry/browser/widgets/tests/test_ocicredentialswidget.py b/lib/lp/registry/browser/widgets/tests/test_ocicredentialswidget.py
3352index 5494439..430e6c3 100644
3353--- a/lib/lp/registry/browser/widgets/tests/test_ocicredentialswidget.py
3354+++ b/lib/lp/registry/browser/widgets/tests/test_ocicredentialswidget.py
3355@@ -32,11 +32,11 @@ class TestOCICredentialsWidget(OCIConfigHelperMixin, TestCaseWithFactory):
3356 layer = DatabaseFunctionalLayer
3357
3358 def setUp(self):
3359- super(TestOCICredentialsWidget, self).setUp()
3360+ super().setUp()
3361 self.setConfig()
3362 field = Reference(
3363 __name__="oci_registry_credentials",
3364- schema=Interface, title=u"OCI Registry Credentials")
3365+ schema=Interface, title="OCI Registry Credentials")
3366 self.context = self.factory.makeDistribution()
3367 field = field.bind(self.context)
3368 request = LaunchpadTestRequest()
3369@@ -163,7 +163,7 @@ class TestOCICredentialsWidget(OCIConfigHelperMixin, TestCaseWithFactory):
3370 def test_getInputValue_valid(self):
3371 field = Reference(
3372 __name__="oci_registry_credentials",
3373- schema=Interface, title=u"OCI Registry Credentials")
3374+ schema=Interface, title="OCI Registry Credentials")
3375 self.context = self.factory.makeDistribution(
3376 oci_project_admin=self.owner)
3377 field = field.bind(self.context)

Subscribers

People subscribed via source and target branches

to status/vote changes: