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

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 0c99f391d1ba4e2e673e0a2fbe8de860b9fcb234
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:pyupgrade-py3-remaining
Merge into: launchpad:master
Diff against target: 1182 lines (+120/-179)
26 files modified
.pre-commit-config.yaml (+7/-29)
brzplugins/lpserve/__init__.py (+2/-3)
brzplugins/lpserve/test_lpserve.py (+2/-3)
cronscripts/librarian-feed-swift.py (+2/-4)
database/schema/security.py (+10/-12)
database/schema/upgrade.py (+1/-1)
lib/launchpad_loggerhead/app.py (+1/-2)
lib/launchpad_loggerhead/session.py (+2/-2)
lib/launchpad_loggerhead/tests.py (+2/-2)
lib/launchpad_loggerhead/wsgi.py (+2/-2)
lib/lp/security.py (+60/-86)
lib/lp/systemhomes.py (+3/-3)
lib/lp/xmlrpc/application.py (+1/-1)
lib/lp/xmlrpc/tests/test_xmlrpc_selftest.py (+1/-1)
scripts/generate-access-token.py (+1/-1)
scripts/gina.py (+1/-1)
scripts/mlist-import.py (+1/-1)
scripts/update-stacked-on.py (+1/-1)
scripts/upload2librarian.py (+1/-1)
setup.py (+1/-2)
utilities/generate-external-bug-status-docs (+1/-3)
utilities/list-pages (+3/-4)
utilities/make-lp-user (+2/-2)
utilities/massage-bug-import-xml (+9/-9)
utilities/pglogwatch.py (+2/-2)
utilities/soyuz-sampledata-setup.py (+1/-1)
Reviewer Review Type Date Requested Status
Ioana Lasc (community) Approve
Review via email: mp+414243@code.launchpad.net

Commit message

Apply "pyupgrade --py3-plus" to most remaining files

Description of the change

There are a couple of non-production scripts in `utilities/` and their dependencies that still require Python 2, as well as the code in `lib/contrib/` that's copied from elsewhere pending replacement by dependencies from PyPI and that's better to leave alone. Everything else that `pyupgrade` knows how to deal with now uses Python 3 syntax.

To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
2index a64bbd3..80c13da 100644
3--- a/.pre-commit-config.yaml
4+++ b/.pre-commit-config.yaml
5@@ -32,36 +32,14 @@ repos:
6 rev: v2.31.0
7 hooks:
8 - id: pyupgrade
9- args: [--keep-percent-format]
10- exclude: ^lib/contrib/
11- - id: pyupgrade
12- alias: pyupgrade-py3
13- name: pyupgrade (--py3-plus)
14 args: [--keep-percent-format, --py3-plus]
15- files: |
16- (?x)^lib/lp/(
17- answers
18- |app
19- |archivepublisher
20- |archiveuploader
21- |blueprints
22- |bugs
23- |buildmaster
24- |charms
25- |code
26- |codehosting
27- |coop
28- |oci
29- |registry
30- |scripts
31- |services
32- |snappy
33- |soyuz
34- |testing
35- |testopenid
36- |tests
37- |translations
38- )/
39+ exclude: |
40+ (?x)^(
41+ lib/contrib/.*
42+ |lib/devscripts/.*
43+ |utilities/community-contributions\.py
44+ |utilities/update-sourcecode
45+ )$
46 - repo: https://github.com/PyCQA/isort
47 rev: 5.9.2
48 hooks:
49diff --git a/brzplugins/lpserve/__init__.py b/brzplugins/lpserve/__init__.py
50index 52ce8ac..6b47fde 100644
51--- a/brzplugins/lpserve/__init__.py
52+++ b/brzplugins/lpserve/__init__.py
53@@ -29,7 +29,6 @@ from breezy.transport import (
54 get_transport,
55 transport_server_registry,
56 )
57-import six
58
59
60 class cmd_launchpad_server(Command):
61@@ -56,7 +55,7 @@ class cmd_launchpad_server(Command):
62 help=(
63 "upload branches to this directory. Defaults to "
64 "config.codehosting.hosted_branches_root."),
65- type=six.text_type),
66+ type=str),
67 Option(
68 'mirror-directory',
69 help=(
70@@ -67,7 +66,7 @@ class cmd_launchpad_server(Command):
71 help=(
72 "the url of the internal XML-RPC server. Defaults to "
73 "config.codehosting.codehosting_endpoint."),
74- type=six.text_type),
75+ type=str),
76 RegistryOption(
77 'protocol', help="Protocol to serve.",
78 lazy_registry=('breezy.transport', 'transport_server_registry'),
79diff --git a/brzplugins/lpserve/test_lpserve.py b/brzplugins/lpserve/test_lpserve.py
80index a9563ec..1ce8641 100644
81--- a/brzplugins/lpserve/test_lpserve.py
82+++ b/brzplugins/lpserve/test_lpserve.py
83@@ -8,7 +8,6 @@ from breezy import (
84 osutils,
85 tests,
86 )
87-import six
88
89 from lp.codehosting import (
90 get_brz_path,
91@@ -43,11 +42,11 @@ class TestCaseWithSubprocess(tests.TestCaseWithTransport):
92 old_env = {}
93
94 def cleanup_environment():
95- for env_var, value in six.iteritems(env_changes):
96+ for env_var, value in env_changes.items():
97 old_env[env_var] = osutils.set_or_unset_env(env_var, value)
98
99 def restore_environment():
100- for env_var, value in six.iteritems(old_env):
101+ for env_var, value in old_env.items():
102 osutils.set_or_unset_env(env_var, value)
103
104 cwd = None
105diff --git a/cronscripts/librarian-feed-swift.py b/cronscripts/librarian-feed-swift.py
106index 1cb1374..8921ece 100755
107--- a/cronscripts/librarian-feed-swift.py
108+++ b/cronscripts/librarian-feed-swift.py
109@@ -9,8 +9,6 @@ import _pythonpath # noqa: F401
110
111 import os
112
113-import six
114-
115 from lp.services.database.interfaces import IStandbyStore
116 from lp.services.librarian.model import LibraryFileContent
117 from lp.services.librarianserver import swift
118@@ -79,14 +77,14 @@ class LibrarianFeedSwift(LaunchpadCronScript):
119 SELECT MAX(id) FROM LibraryFileContent
120 WHERE datecreated < current_timestamp at time zone 'UTC'
121 - CAST(%s AS INTERVAL)
122- """, (six.text_type(self.options.start_since),)).get_one()[0]
123+ """, (str(self.options.start_since),)).get_one()[0]
124
125 if self.options.end_at:
126 self.options.end = IStandbyStore(LibraryFileContent).execute("""
127 SELECT MAX(id) FROM LibraryFileContent
128 WHERE datecreated < current_timestamp at time zone 'UTC'
129 - CAST(%s AS INTERVAL)
130- """, (six.text_type(self.options.end_at),)).get_one()[0]
131+ """, (str(self.options.end_at),)).get_one()[0]
132
133 if ((self.options.instance_id is None) !=
134 (self.options.num_instances is None)):
135diff --git a/database/schema/security.py b/database/schema/security.py
136index 06bdc23..7281678 100755
137--- a/database/schema/security.py
138+++ b/database/schema/security.py
139@@ -12,8 +12,6 @@ import os
140 import re
141 import sys
142
143-import six
144-
145 from fti import quote_identifier
146 from lp.services.database.sqlbase import connect
147 from lp.services.scripts import (
148@@ -117,7 +115,7 @@ def list_role_members(cur, roles):
149 return members
150
151
152-class DbObject(object):
153+class DbObject:
154
155 def __init__(
156 self, schema, name, type_, owner, acl, arguments=None, language=None):
157@@ -151,7 +149,7 @@ class DbObject(object):
158
159 class DbSchema(dict):
160 def __init__(self, con):
161- super(DbSchema, self).__init__()
162+ super().__init__()
163 cur = con.cursor()
164 log.debug("Getting relation metadata")
165 cur.execute('''
166@@ -223,7 +221,7 @@ class DbSchema(dict):
167 for r in cur.fetchall()}
168
169
170-class CursorWrapper(object):
171+class CursorWrapper:
172
173 def __init__(self, cursor):
174 self.__dict__['_cursor'] = cursor
175@@ -306,8 +304,8 @@ class PermissionGatherer:
176 to grant or revoke for. Each is a string.
177 """
178 result = []
179- for permission, parties in six.iteritems(self.permissions):
180- for principal, entities in six.iteritems(parties):
181+ for permission, parties in self.permissions.items():
182+ for principal, entities in parties.items():
183 result.append(
184 (permission, ", ".join(entities), principal))
185 return result
186@@ -319,8 +317,8 @@ class PermissionGatherer:
187 def countEntities(self):
188 """Count the number of different entities."""
189 entities = set()
190- for entities_and_entities in six.itervalues(self.permissions):
191- for extra_entities in six.itervalues(entities_and_entities):
192+ for entities_and_entities in self.permissions.values():
193+ for extra_entities in entities_and_entities.values():
194 entities.update(extra_entities)
195 return len(entities)
196
197@@ -328,7 +326,7 @@ class PermissionGatherer:
198 """Count the number of different principals."""
199 return len(set(sum((
200 list(principals)
201- for principals in six.itervalues(self.permissions)), [])))
202+ for principals in self.permissions.values()), [])))
203
204 def grant(self, cur):
205 """Grant all gathered permissions.
206@@ -484,7 +482,7 @@ def reset_permissions(con, config, options):
207
208 log.debug('Updating group memberships')
209 existing_memberships = list_role_members(cur, list(memberships))
210- for group, users in six.iteritems(memberships):
211+ for group, users in memberships.items():
212 cur_users = managed_roles.intersection(existing_memberships[group])
213 to_grant = users - cur_users
214 if to_grant:
215@@ -622,7 +620,7 @@ def reset_permissions(con, config, options):
216 new = desired_permissions[obj][role]
217 old_privs = obj.acl.get(role, {})
218 old = set(old_privs)
219- if any(six.itervalues(old_privs)):
220+ if any(old_privs.values()):
221 log.warning("%s has grant option on %s", role, obj.fullname)
222 if new == old:
223 continue
224diff --git a/database/schema/upgrade.py b/database/schema/upgrade.py
225index bab20e3..3b579ff 100755
226--- a/database/schema/upgrade.py
227+++ b/database/schema/upgrade.py
228@@ -180,7 +180,7 @@ def get_patchlist(con):
229 log.fatal('Invalid patch filename %s' % repr(patch_file))
230 raise SystemExit(1)
231
232- major, minor, patch = [int(i) for i in m.groups()]
233+ major, minor, patch = (int(i) for i in m.groups())
234 if (major, minor, patch) in dbpatches:
235 continue # This patch has already been applied
236 log.debug("Found patch %d.%d.%d -- %s" % (
237diff --git a/lib/launchpad_loggerhead/app.py b/lib/launchpad_loggerhead/app.py
238index aa58d54..7ada98a 100644
239--- a/lib/launchpad_loggerhead/app.py
240+++ b/lib/launchpad_loggerhead/app.py
241@@ -120,8 +120,7 @@ class RootApp:
242 """
243 openid_request = self._make_consumer(environ).begin(
244 config.launchpad.openid_provider_root)
245- openid_request.addExtension(
246- SRegRequest(required=[u'nickname']))
247+ openid_request.addExtension(SRegRequest(required=['nickname']))
248 back_to = construct_url(environ)
249 raise HTTPMovedPermanently(openid_request.redirectURL(
250 config.codehosting.secure_codebrowse_root,
251diff --git a/lib/launchpad_loggerhead/session.py b/lib/launchpad_loggerhead/session.py
252index 2adb69c..ce214f7 100644
253--- a/lib/launchpad_loggerhead/session.py
254+++ b/lib/launchpad_loggerhead/session.py
255@@ -21,7 +21,7 @@ class LaunchpadSecureCookie(SecureCookie):
256 hash_method = staticmethod(hashlib.sha256)
257
258 # The OpenID consumer stores non-JSON-encodable objects in the session.
259- class serialization_method(object):
260+ class serialization_method:
261
262 @classmethod
263 def dumps(cls, value):
264@@ -33,7 +33,7 @@ class LaunchpadSecureCookie(SecureCookie):
265 return pickle.loads(value)
266
267
268-class SessionHandler(object):
269+class SessionHandler:
270 """Middleware that provides a cookie-based session.
271
272 The session dict is stored, pickled (and HMACed), in a cookie, so don't
273diff --git a/lib/launchpad_loggerhead/tests.py b/lib/launchpad_loggerhead/tests.py
274index 1c78b51..cad2ec3 100644
275--- a/lib/launchpad_loggerhead/tests.py
276+++ b/lib/launchpad_loggerhead/tests.py
277@@ -128,7 +128,7 @@ class TestWSGI(TestCaseWithFactory):
278 layer = AppServerLayer
279
280 def setUp(self):
281- super(TestWSGI, self).setUp()
282+ super().setUp()
283 self.useBzrBranches()
284 loggerhead_fixture = self.useFixture(LoggerheadFixture())
285
286@@ -136,7 +136,7 @@ class TestWSGI(TestCaseWithFactory):
287 try:
288 with open(loggerhead_fixture.logfile, "rb") as logfile:
289 return [logfile.read()]
290- except IOError:
291+ except OSError:
292 return [b""]
293
294 self.addDetail(
295diff --git a/lib/launchpad_loggerhead/wsgi.py b/lib/launchpad_loggerhead/wsgi.py
296index 633fb7c..eefe119 100644
297--- a/lib/launchpad_loggerhead/wsgi.py
298+++ b/lib/launchpad_loggerhead/wsgi.py
299@@ -92,7 +92,7 @@ def log_request_start_and_stop(app):
300 class LoggerheadLogger(Logger):
301
302 def setup(self, cfg):
303- super(LoggerheadLogger, self).setup(cfg)
304+ super().setup(cfg)
305 formatter = LaunchpadFormatter(datefmt=None)
306 for handler in self.error_log.handlers:
307 handler.setFormatter(formatter)
308@@ -120,7 +120,7 @@ class LoggerheadApplication(Application):
309
310 def __init__(self, **kwargs):
311 self.options = kwargs
312- super(LoggerheadApplication, self).__init__()
313+ super().__init__()
314
315 def init(self, parser, opts, args):
316 top = os.path.abspath(os.path.join(
317diff --git a/lib/lp/security.py b/lib/lp/security.py
318index 044e197..37d52d3 100644
319--- a/lib/lp/security.py
320+++ b/lib/lp/security.py
321@@ -468,7 +468,7 @@ class ViewAccount(EditAccountBySelfOrAdmin):
322 def checkAuthenticated(self, user):
323 """Extend permission to registry experts."""
324 return (
325- super(ViewAccount, self).checkAuthenticated(user)
326+ super().checkAuthenticated(user)
327 or user.in_registry_experts)
328
329
330@@ -544,7 +544,7 @@ class LimitedViewProduct(ViewProduct):
331
332 def checkAuthenticated(self, user):
333 return (
334- super(LimitedViewProduct, self).checkAuthenticated(user) or
335+ super().checkAuthenticated(user) or
336 self.obj.userCanLimitedView(user))
337
338
339@@ -554,7 +554,7 @@ class EditProduct(EditByOwnersOrAdmins):
340 def checkAuthenticated(self, user):
341 # Commercial admins may help setup commercial projects.
342 return (
343- super(EditProduct, self).checkAuthenticated(user)
344+ super().checkAuthenticated(user)
345 or is_commercial_case(self.obj, user)
346 or False)
347
348@@ -580,8 +580,7 @@ class ViewTimelineProductSeries(DelegatedAuthorization):
349 usedfor = ITimelineProductSeries
350
351 def __init__(self, obj):
352- super(ViewTimelineProductSeries, self).__init__(
353- obj, obj.product, 'launchpad.View')
354+ super().__init__(obj, obj.product, 'launchpad.View')
355
356
357 class ViewProductReleaseFile(AnonymousAuthorization):
358@@ -798,7 +797,7 @@ class ModerateSprint(ModerateByRegistryExpertsOrAdmins):
359
360 def checkAuthenticated(self, user):
361 return (
362- super(ModerateSprint, self).checkAuthenticated(user) or
363+ super().checkAuthenticated(user) or
364 user.isOwner(self.obj))
365
366
367@@ -867,8 +866,7 @@ class ViewProjectMilestone(DelegatedAuthorization):
368 usedfor = IProjectGroupMilestone
369
370 def __init__(self, obj):
371- super(ViewProjectMilestone, self).__init__(
372- obj, obj.product, 'launchpad.View')
373+ super().__init__(obj, obj.product, 'launchpad.View')
374
375
376 class EditProjectMilestoneNever(AuthorizationBase):
377@@ -885,8 +883,7 @@ class LimitedViewMilestone(DelegatedAuthorization):
378 usedfor = IMilestone
379
380 def __init__(self, obj):
381- super(LimitedViewMilestone, self).__init__(
382- obj, obj.target, 'launchpad.LimitedView')
383+ super().__init__(obj, obj.target, 'launchpad.LimitedView')
384
385
386 class ViewMilestone(AuthorizationBase):
387@@ -963,7 +960,7 @@ class ModerateTeam(ModerateByRegistryExpertsOrAdmins):
388 registry experts, team admins, or the team owners.
389 """
390 return (
391- super(ModerateTeam, self).checkAuthenticated(user)
392+ super().checkAuthenticated(user)
393 or can_edit_team(self.obj, user))
394
395
396@@ -1003,8 +1000,7 @@ class AdminByCommercialTeamOrAdminsOrPerson(AdminByCommercialTeamOrAdmins):
397
398 def checkAuthenticated(self, user):
399 """Users can manage their commericial data and admins can help."""
400- base = super(AdminByCommercialTeamOrAdminsOrPerson, self)
401- return self.obj.id == user.id or base.checkAuthenticated(user)
402+ return self.obj.id == user.id or super().checkAuthenticated(user)
403
404
405 class EditPersonBySelfOrAdmins(AuthorizationBase):
406@@ -1451,7 +1447,7 @@ class EditDistroSeriesDifference(DelegatedAuthorization):
407 usedfor = IDistroSeriesDifferenceEdit
408
409 def __init__(self, obj):
410- super(EditDistroSeriesDifference, self).__init__(
411+ super().__init__(
412 obj, obj.derived_series.distribution, 'launchpad.View')
413
414 def checkUnauthenticated(self):
415@@ -1479,7 +1475,7 @@ class DriveProduct(SeriesDrivers):
416 def checkAuthenticated(self, user):
417 # Commercial admins may help setup commercial projects.
418 return (
419- super(DriveProduct, self).checkAuthenticated(user)
420+ super().checkAuthenticated(user)
421 or is_commercial_case(self.obj, user)
422 or False)
423
424@@ -1489,8 +1485,7 @@ class LimitedViewProductSeries(DelegatedAuthorization):
425 usedfor = IProductSeriesLimitedView
426
427 def __init__(self, obj):
428- super(LimitedViewProductSeries, self).__init__(
429- obj, obj.product, 'launchpad.LimitedView')
430+ super().__init__(obj, obj.product, 'launchpad.LimitedView')
431
432
433 class ViewProductSeries(AuthorizationBase):
434@@ -1541,8 +1536,7 @@ class ViewDistroArchSeriesFilter(DelegatedAuthorization):
435 usedfor = IDistroArchSeriesFilter
436
437 def __init__(self, obj):
438- super(ViewDistroArchSeriesFilter, self).__init__(
439- obj, obj.distroarchseries, 'launchpad.View')
440+ super().__init__(obj, obj.distroarchseries, 'launchpad.View')
441
442
443 class EditDistroArchSeriesFilter(DelegatedAuthorization):
444@@ -1550,8 +1544,7 @@ class EditDistroArchSeriesFilter(DelegatedAuthorization):
445 usedfor = IDistroArchSeriesFilter
446
447 def __init__(self, obj):
448- super(EditDistroArchSeriesFilter, self).__init__(
449- obj, obj.distroarchseries, 'launchpad.Moderate')
450+ super().__init__(obj, obj.distroarchseries, 'launchpad.Moderate')
451
452
453 class ViewAnnouncement(AuthorizationBase):
454@@ -1888,8 +1881,7 @@ class ViewProductRelease(DelegatedAuthorization):
455 usedfor = IProductRelease
456
457 def __init__(self, obj):
458- super(ViewProductRelease, self).__init__(
459- obj, obj.milestone, 'launchpad.View')
460+ super().__init__(obj, obj.milestone, 'launchpad.View')
461
462
463 class AdminTranslationImportQueueEntry(AuthorizationBase):
464@@ -2002,7 +1994,7 @@ class ViewPackageUploadLog(DelegatedAuthorization):
465 usedfor = IPackageUploadLog
466
467 def __init__(self, obj):
468- super(ViewPackageUploadLog, self).__init__(obj, obj.package_upload)
469+ super().__init__(obj, obj.package_upload)
470
471
472 class EditPackageUpload(AdminByAdminsTeam):
473@@ -2046,7 +2038,7 @@ class ModerateBuilder(EditBuilder):
474
475 def checkAuthenticated(self, user):
476 return (user.in_registry_experts or
477- super(ModerateBuilder, self).checkAuthenticated(user))
478+ super().checkAuthenticated(user))
479
480
481 class AdminBuildRecord(AdminByBuilddAdmin):
482@@ -2154,8 +2146,7 @@ class ModerateBinaryPackageBuild(ViewBinaryPackageBuild):
483 # administer the archive can already achieve the same effect by
484 # setting Archive.external_dependencies.)
485 return (
486- super(ModerateBinaryPackageBuild, self).checkAuthenticated(
487- user) and
488+ super().checkAuthenticated(user) and
489 AdminArchive(self.obj.archive).checkAuthenticated(user))
490
491 def checkUnauthenticated(self, user):
492@@ -2171,7 +2162,7 @@ class ViewTranslationTemplatesBuild(DelegatedAuthorization):
493 usedfor = ITranslationTemplatesBuild
494
495 def __init__(self, obj):
496- super(ViewTranslationTemplatesBuild, self).__init__(obj, obj.branch)
497+ super().__init__(obj, obj.branch)
498
499
500 class AdminQuestion(AuthorizationBase):
501@@ -2389,7 +2380,7 @@ class ModerateBranch(EditBranch):
502 permission = 'launchpad.Moderate'
503
504 def checkAuthenticated(self, user):
505- if super(ModerateBranch, self).checkAuthenticated(user):
506+ if super().checkAuthenticated(user):
507 return True
508 branch = self.obj
509 if branch.product is not None and user.inTeam(branch.product.owner):
510@@ -2464,7 +2455,7 @@ class ModerateGitRepository(EditGitRepository):
511 permission = 'launchpad.Moderate'
512
513 def checkAuthenticated(self, user):
514- if super(ModerateGitRepository, self).checkAuthenticated(user):
515+ if super().checkAuthenticated(user):
516 return True
517 target = self.obj.target
518 if (target is not None and IProduct.providedBy(target) and
519@@ -2484,17 +2475,17 @@ class ViewGitRef(DelegatedAuthorization):
520 usedfor = IGitRef
521
522 def __init__(self, obj):
523- super(ViewGitRef, self).__init__(obj, obj.repository)
524+ super().__init__(obj, obj.repository)
525
526 def checkAuthenticated(self, user):
527 if self.obj.repository is not None:
528- return super(ViewGitRef, self).checkAuthenticated(user)
529+ return super().checkAuthenticated(user)
530 else:
531 return True
532
533 def checkUnauthenticated(self):
534 if self.obj.repository is not None:
535- return super(ViewGitRef, self).checkUnauthenticated()
536+ return super().checkUnauthenticated()
537 else:
538 return True
539
540@@ -2505,7 +2496,7 @@ class EditGitRef(DelegatedAuthorization):
541 usedfor = IGitRef
542
543 def __init__(self, obj):
544- super(EditGitRef, self).__init__(obj, obj.repository)
545+ super().__init__(obj, obj.repository)
546
547
548 class ViewGitRule(DelegatedAuthorization):
549@@ -2514,7 +2505,7 @@ class ViewGitRule(DelegatedAuthorization):
550 usedfor = IGitRule
551
552 def __init__(self, obj):
553- super(ViewGitRule, self).__init__(obj, obj.repository)
554+ super().__init__(obj, obj.repository)
555
556
557 class EditGitRule(DelegatedAuthorization):
558@@ -2523,7 +2514,7 @@ class EditGitRule(DelegatedAuthorization):
559 usedfor = IGitRule
560
561 def __init__(self, obj):
562- super(EditGitRule, self).__init__(obj, obj.repository)
563+ super().__init__(obj, obj.repository)
564
565
566 class ViewGitRuleGrant(DelegatedAuthorization):
567@@ -2532,7 +2523,7 @@ class ViewGitRuleGrant(DelegatedAuthorization):
568 usedfor = IGitRuleGrant
569
570 def __init__(self, obj):
571- super(ViewGitRuleGrant, self).__init__(obj, obj.repository)
572+ super().__init__(obj, obj.repository)
573
574
575 class EditGitRuleGrant(DelegatedAuthorization):
576@@ -2541,7 +2532,7 @@ class EditGitRuleGrant(DelegatedAuthorization):
577 usedfor = IGitRuleGrant
578
579 def __init__(self, obj):
580- super(EditGitRuleGrant, self).__init__(obj, obj.repository)
581+ super().__init__(obj, obj.repository)
582
583
584 class ViewGitActivity(DelegatedAuthorization):
585@@ -2550,7 +2541,7 @@ class ViewGitActivity(DelegatedAuthorization):
586 usedfor = IGitActivity
587
588 def __init__(self, obj):
589- super(ViewGitActivity, self).__init__(obj, obj.repository)
590+ super().__init__(obj, obj.repository)
591
592
593 class AdminDistroSeriesTranslations(AuthorizationBase):
594@@ -2573,8 +2564,7 @@ class AdminDistributionSourcePackageTranslations(DelegatedAuthorization):
595 usedfor = IDistributionSourcePackage
596
597 def __init__(self, obj):
598- super(AdminDistributionSourcePackageTranslations, self).__init__(
599- obj, obj.distribution)
600+ super().__init__(obj, obj.distribution)
601
602
603 class AdminProductSeriesTranslations(AuthorizationBase):
604@@ -2643,7 +2633,7 @@ class PreviewDiffView(DelegatedAuthorization):
605 usedfor = IPreviewDiff
606
607 def __init__(self, obj):
608- super(PreviewDiffView, self).__init__(obj, obj.branch_merge_proposal)
609+ super().__init__(obj, obj.branch_merge_proposal)
610
611
612 class CodeReviewVoteReferenceView(DelegatedAuthorization):
613@@ -2651,8 +2641,7 @@ class CodeReviewVoteReferenceView(DelegatedAuthorization):
614 usedfor = ICodeReviewVoteReference
615
616 def __init__(self, obj):
617- super(CodeReviewVoteReferenceView, self).__init__(
618- obj, obj.branch_merge_proposal)
619+ super().__init__(obj, obj.branch_merge_proposal)
620
621
622 class CodeReviewVoteReferenceEdit(DelegatedAuthorization):
623@@ -2660,8 +2649,7 @@ class CodeReviewVoteReferenceEdit(DelegatedAuthorization):
624 usedfor = ICodeReviewVoteReference
625
626 def __init__(self, obj):
627- super(CodeReviewVoteReferenceEdit, self).__init__(
628- obj, obj.branch_merge_proposal.target_branch)
629+ super().__init__(obj, obj.branch_merge_proposal.target_branch)
630
631 def checkAuthenticated(self, user):
632 """Only the affected teams may change the review request.
633@@ -2675,8 +2663,7 @@ class CodeReviewVoteReferenceEdit(DelegatedAuthorization):
634 """
635 return (user.inTeam(self.obj.reviewer) or
636 user.inTeam(self.obj.registrant) or
637- super(CodeReviewVoteReferenceEdit, self).checkAuthenticated(
638- user))
639+ super().checkAuthenticated(user))
640
641
642 class CodeReviewCommentView(DelegatedAuthorization):
643@@ -2684,8 +2671,7 @@ class CodeReviewCommentView(DelegatedAuthorization):
644 usedfor = ICodeReviewComment
645
646 def __init__(self, obj):
647- super(CodeReviewCommentView, self).__init__(
648- obj, obj.branch_merge_proposal)
649+ super().__init__(obj, obj.branch_merge_proposal)
650
651
652 class CodeReviewCommentOwner(AuthorizationBase):
653@@ -2702,8 +2688,7 @@ class CodeReviewCommentDelete(DelegatedAuthorization):
654 usedfor = ICodeReviewCommentDeletion
655
656 def __init__(self, obj):
657- super(CodeReviewCommentDelete, self).__init__(
658- obj, obj.branch_merge_proposal)
659+ super().__init__(obj, obj.branch_merge_proposal)
660
661
662 class BranchMergeProposalEdit(AuthorizationBase):
663@@ -2804,7 +2789,7 @@ class SubscriberViewArchive(ViewArchive):
664 def checkAuthenticated(self, user):
665 if user.person in self.obj._known_subscribers:
666 return True
667- if super(SubscriberViewArchive, self).checkAuthenticated(user):
668+ if super().checkAuthenticated(user):
669 return True
670 filter = get_enabled_archive_filter(
671 user.person, include_subscribed=True)
672@@ -2854,7 +2839,7 @@ class DeleteArchive(EditArchive):
673
674 def checkAuthenticated(self, user):
675 return (
676- super(DeleteArchive, self).checkAuthenticated(user) or
677+ super().checkAuthenticated(user) or
678 (not self.obj.is_main and user.in_registry_experts))
679
680
681@@ -2943,12 +2928,11 @@ class EditArchiveAuthToken(DelegatedAuthorization):
682 usedfor = IArchiveAuthToken
683
684 def __init__(self, obj):
685- super(EditArchiveAuthToken, self).__init__(
686- obj, obj.archive, 'launchpad.Append')
687+ super().__init__(obj, obj.archive, 'launchpad.Append')
688
689 def checkAuthenticated(self, user):
690 return (user.in_admin or
691- super(EditArchiveAuthToken, self).checkAuthenticated(user))
692+ super().checkAuthenticated(user))
693
694
695 class ViewPersonalArchiveSubscription(DelegatedAuthorization):
696@@ -2961,14 +2945,12 @@ class ViewPersonalArchiveSubscription(DelegatedAuthorization):
697 usedfor = IPersonalArchiveSubscription
698
699 def __init__(self, obj):
700- super(ViewPersonalArchiveSubscription, self).__init__(
701- obj, obj.archive, 'launchpad.Append')
702+ super().__init__(obj, obj.archive, 'launchpad.Append')
703
704 def checkAuthenticated(self, user):
705 if user.person == self.obj.subscriber or user.in_admin:
706 return True
707- return super(
708- ViewPersonalArchiveSubscription, self).checkAuthenticated(user)
709+ return super().checkAuthenticated(user)
710
711
712 class ViewArchiveSubscriber(DelegatedAuthorization):
713@@ -2981,13 +2963,12 @@ class ViewArchiveSubscriber(DelegatedAuthorization):
714 usedfor = IArchiveSubscriber
715
716 def __init__(self, obj):
717- super(ViewArchiveSubscriber, self).__init__(
718- obj, obj, 'launchpad.Edit')
719+ super().__init__(obj, obj, 'launchpad.Edit')
720
721 def checkAuthenticated(self, user):
722 return (user.inTeam(self.obj.subscriber) or
723 user.in_commercial_admin or
724- super(ViewArchiveSubscriber, self).checkAuthenticated(user))
725+ super().checkAuthenticated(user))
726
727
728 class EditArchiveSubscriber(DelegatedAuthorization):
729@@ -2999,13 +2980,12 @@ class EditArchiveSubscriber(DelegatedAuthorization):
730 usedfor = IArchiveSubscriber
731
732 def __init__(self, obj):
733- super(EditArchiveSubscriber, self).__init__(
734- obj, obj.archive, 'launchpad.Append')
735+ super().__init__(obj, obj.archive, 'launchpad.Append')
736
737 def checkAuthenticated(self, user):
738 return (user.in_admin or
739 user.in_commercial_admin or
740- super(EditArchiveSubscriber, self).checkAuthenticated(user))
741+ super().checkAuthenticated(user))
742
743
744 class AdminArchiveSubscriberSet(AdminByCommercialTeamOrAdmins):
745@@ -3062,8 +3042,7 @@ class EditPublishing(DelegatedAuthorization):
746 usedfor = IPublishingEdit
747
748 def __init__(self, obj):
749- super(EditPublishing, self).__init__(
750- obj, obj.archive, 'launchpad.Append')
751+ super().__init__(obj, obj.archive, 'launchpad.Append')
752
753
754 class ViewBinaryPackagePublishingHistory(ViewSourcePackagePublishingHistory):
755@@ -3148,7 +3127,7 @@ class EditEmailAddress(EditByOwnersOrAdmins):
756 # Always allow users to see their own email addresses.
757 if self.obj.person == user:
758 return True
759- return super(EditEmailAddress, self).checkAuthenticated(user)
760+ return super().checkAuthenticated(user)
761
762
763 class ViewGPGKey(AnonymousAuthorization):
764@@ -3258,8 +3237,7 @@ class EditMessageRevision(DelegatedAuthorization):
765 usedfor = IMessageRevision
766
767 def __init__(self, obj):
768- super(EditMessageRevision, self).__init__(
769- obj, obj.message, 'launchpad.Edit')
770+ super().__init__(obj, obj.message, 'launchpad.Edit')
771
772
773 class ViewPublisherConfig(AdminByAdminsTeam):
774@@ -3287,7 +3265,7 @@ class ViewLiveFS(DelegatedAuthorization):
775 usedfor = ILiveFS
776
777 def __init__(self, obj):
778- super(ViewLiveFS, self).__init__(obj, obj.owner, 'launchpad.View')
779+ super().__init__(obj, obj.owner, 'launchpad.View')
780
781
782 class EditLiveFS(AuthorizationBase):
783@@ -3346,7 +3324,7 @@ class EditLiveFSBuild(AdminByBuilddAdmin):
784 auth_livefs = EditLiveFS(self.obj.livefs)
785 if auth_livefs.checkAuthenticated(user):
786 return True
787- return super(EditLiveFSBuild, self).checkAuthenticated(user)
788+ return super().checkAuthenticated(user)
789
790
791 class AdminLiveFSBuild(AdminByBuilddAdmin):
792@@ -3371,8 +3349,7 @@ class ViewWebhookDeliveryJob(DelegatedAuthorization):
793 usedfor = IWebhookDeliveryJob
794
795 def __init__(self, obj):
796- super(ViewWebhookDeliveryJob, self).__init__(
797- obj, obj.webhook, 'launchpad.View')
798+ super().__init__(obj, obj.webhook, 'launchpad.View')
799
800
801 class ViewSnap(AuthorizationBase):
802@@ -3451,8 +3428,7 @@ class ViewSnapBuildRequest(DelegatedAuthorization):
803 usedfor = ISnapBuildRequest
804
805 def __init__(self, obj):
806- super(ViewSnapBuildRequest, self).__init__(
807- obj, obj.snap, 'launchpad.View')
808+ super().__init__(obj, obj.snap, 'launchpad.View')
809
810
811 class ViewSnapBuild(DelegatedAuthorization):
812@@ -3478,7 +3454,7 @@ class EditSnapBuild(AdminByBuilddAdmin):
813 auth_snap = EditSnap(self.obj.snap)
814 if auth_snap.checkAuthenticated(user):
815 return True
816- return super(EditSnapBuild, self).checkAuthenticated(user)
817+ return super().checkAuthenticated(user)
818
819
820 class AdminSnapBuild(AdminByBuilddAdmin):
821@@ -3532,7 +3508,7 @@ class EditOCIProjectSeries(DelegatedAuthorization):
822 usedfor = IOCIProjectSeries
823
824 def __init__(self, obj):
825- super(EditOCIProjectSeries, self).__init__(obj, obj.oci_project)
826+ super().__init__(obj, obj.oci_project)
827
828
829 class ViewOCIRecipeBuildRequest(DelegatedAuthorization):
830@@ -3540,8 +3516,7 @@ class ViewOCIRecipeBuildRequest(DelegatedAuthorization):
831 usedfor = IOCIRecipeBuildRequest
832
833 def __init__(self, obj):
834- super(ViewOCIRecipeBuildRequest, self).__init__(
835- obj, obj.recipe, 'launchpad.View')
836+ super().__init__(obj, obj.recipe, 'launchpad.View')
837
838
839 class ViewOCIRecipe(AnonymousAuthorization):
840@@ -3638,7 +3613,7 @@ class EditOCIRecipeBuild(AdminByBuilddAdmin):
841 auth_recipe = EditOCIRecipe(self.obj.recipe)
842 if auth_recipe.checkAuthenticated(user):
843 return True
844- return super(EditOCIRecipeBuild, self).checkAuthenticated(user)
845+ return super().checkAuthenticated(user)
846
847
848 class AdminOCIRecipeBuild(AdminByBuilddAdmin):
849@@ -3717,8 +3692,7 @@ class ViewCharmRecipeBuildRequest(DelegatedAuthorization):
850 usedfor = ICharmRecipeBuildRequest
851
852 def __init__(self, obj):
853- super(ViewCharmRecipeBuildRequest, self).__init__(
854- obj, obj.recipe, 'launchpad.View')
855+ super().__init__(obj, obj.recipe, 'launchpad.View')
856
857
858 class ViewCharmRecipeBuild(DelegatedAuthorization):
859@@ -3743,7 +3717,7 @@ class EditCharmRecipeBuild(AdminByBuilddAdmin):
860 auth_recipe = EditCharmRecipe(self.obj.recipe)
861 if auth_recipe.checkAuthenticated(user):
862 return True
863- return super(EditCharmRecipeBuild, self).checkAuthenticated(user)
864+ return super().checkAuthenticated(user)
865
866
867 class AdminCharmRecipeBuild(AdminByBuilddAdmin):
868diff --git a/lib/lp/systemhomes.py b/lib/lp/systemhomes.py
869index f9d0fd9..9df2372 100644
870--- a/lib/lp/systemhomes.py
871+++ b/lib/lp/systemhomes.py
872@@ -315,7 +315,7 @@ class WebServiceApplication(ServiceRootResource):
873 if self.__class__.cached_wadl is None:
874 # The cache has been disabled for testing
875 # purposes. Generate the WADL.
876- return super(WebServiceApplication, self).toWADL()
877+ return super().toWADL()
878 if version not in self.__class__.cached_wadl:
879 # It's not cached. Look for it on disk.
880 _wadl_filename = self.cachedWADLPath(
881@@ -327,9 +327,9 @@ class WebServiceApplication(ServiceRootResource):
882 wadl = _wadl_fd.read()
883 finally:
884 _wadl_fd.close()
885- except IOError:
886+ except OSError:
887 # It's not on disk; generate it.
888- wadl = super(WebServiceApplication, self).toWADL()
889+ wadl = super().toWADL()
890 del _wadl_fd
891 self.__class__.cached_wadl[version] = wadl
892 return self.__class__.cached_wadl[version]
893diff --git a/lib/lp/xmlrpc/application.py b/lib/lp/xmlrpc/application.py
894index 1b23765..d7b5edb 100644
895--- a/lib/lp/xmlrpc/application.py
896+++ b/lib/lp/xmlrpc/application.py
897@@ -109,7 +109,7 @@ class SelfTest(LaunchpadXMLRPCView):
898
899 def concatenate(self, string1, string2):
900 """Return the concatenation of the two given strings."""
901- return u'%s %s' % (string1, string2)
902+ return '%s %s' % (string1, string2)
903
904 def hello(self):
905 """Return a greeting to the logged in user."""
906diff --git a/lib/lp/xmlrpc/tests/test_xmlrpc_selftest.py b/lib/lp/xmlrpc/tests/test_xmlrpc_selftest.py
907index 9f0d528..d4fa40f 100644
908--- a/lib/lp/xmlrpc/tests/test_xmlrpc_selftest.py
909+++ b/lib/lp/xmlrpc/tests/test_xmlrpc_selftest.py
910@@ -42,7 +42,7 @@ class TestXMLRPCSelfTest(TestCaseWithFactory):
911 """
912 selftestview = SelfTest('somecontext', 'somerequest')
913 self.assertTrue(verifyObject(ISelfTest, selftestview))
914- self.assertEqual(u'foo bar', selftestview.concatenate('foo', 'bar'))
915+ self.assertEqual('foo bar', selftestview.concatenate('foo', 'bar'))
916 fault = selftestview.make_fault()
917 self.assertEqual("<Fault 666: 'Yoghurt and spanners.'>", str(fault))
918
919diff --git a/scripts/generate-access-token.py b/scripts/generate-access-token.py
920index 961d715..e494888 100755
921--- a/scripts/generate-access-token.py
922+++ b/scripts/generate-access-token.py
923@@ -47,7 +47,7 @@ class AccessTokenGenerator(LaunchpadScript):
924 username = self.args[0]
925
926 key = six.ensure_text(self.options.consumer_name)
927- consumer = getUtility(IOAuthConsumerSet).new(key, u'')
928+ consumer = getUtility(IOAuthConsumerSet).new(key, '')
929 request_token, _ = consumer.newRequestToken()
930
931 # review by username
932diff --git a/scripts/gina.py b/scripts/gina.py
933index b679bf8..e8fb3ed 100755
934--- a/scripts/gina.py
935+++ b/scripts/gina.py
936@@ -26,7 +26,7 @@ from lp.soyuz.scripts.gina.runner import run_gina
937 class Gina(LaunchpadCronScript):
938
939 def __init__(self):
940- super(Gina, self).__init__(name='gina', dbuser=config.gina.dbuser)
941+ super().__init__(name='gina', dbuser=config.gina.dbuser)
942
943 @property
944 def usage(self):
945diff --git a/scripts/mlist-import.py b/scripts/mlist-import.py
946index b7bf8b7..b418b5c 100755
947--- a/scripts/mlist-import.py
948+++ b/scripts/mlist-import.py
949@@ -40,7 +40,7 @@ class MailingListImport(LaunchpadScript):
950
951 def __init__(self, name, dbuser=None):
952 self.usage = textwrap.dedent(self.__doc__)
953- super(MailingListImport, self).__init__(name, dbuser)
954+ super().__init__(name, dbuser)
955
956 def add_my_options(self):
957 """See `LaunchpadScript`."""
958diff --git a/scripts/update-stacked-on.py b/scripts/update-stacked-on.py
959index 7b6bb64..d8351d6 100755
960--- a/scripts/update-stacked-on.py
961+++ b/scripts/update-stacked-on.py
962@@ -56,7 +56,7 @@ class UpdateStackedBranches(LaunchpadScript):
963 """Update stacked branches so their stacked_on_location matches the db."""
964
965 def __init__(self):
966- super(UpdateStackedBranches, self).__init__('update-stacked-on')
967+ super().__init__('update-stacked-on')
968
969 def add_my_options(self):
970 self.parser.add_option(
971diff --git a/scripts/upload2librarian.py b/scripts/upload2librarian.py
972index f211095..4c89bad 100755
973--- a/scripts/upload2librarian.py
974+++ b/scripts/upload2librarian.py
975@@ -53,7 +53,7 @@ class LibrarianUploader(LaunchpadScript):
976 """
977 try:
978 file = open(filepath)
979- except IOError:
980+ except OSError:
981 raise LaunchpadScriptFailure('Could not open: %s' % filepath)
982
983 flen = os.stat(filepath).st_size
984diff --git a/setup.py b/setup.py
985index ee010f0..88f502c 100644
986--- a/setup.py
987+++ b/setup.py
988@@ -51,8 +51,7 @@ class LPScriptWriter(ScriptWriter):
989 "module_name": ep.module_name,
990 })
991 args = cls._get_script_args("console", name, header, script_text)
992- for res in args:
993- yield res
994+ yield from args
995
996
997 class lp_develop(develop):
998diff --git a/utilities/generate-external-bug-status-docs b/utilities/generate-external-bug-status-docs
999index 63a98b6..94ad229 100755
1000--- a/utilities/generate-external-bug-status-docs
1001+++ b/utilities/generate-external-bug-status-docs
1002@@ -26,8 +26,6 @@ from itertools import chain
1003 from optparse import OptionParser
1004 import sys
1005
1006-import six
1007-
1008 from lp.bugs.externalbugtracker import BUG_TRACKER_CLASSES
1009
1010
1011@@ -87,7 +85,7 @@ def generate_table(typ, cls):
1012
1013 def generate_documentable_classes():
1014 """Yield each class that has a mapping table defined."""
1015- for typ, cls in six.iteritems(BUG_TRACKER_CLASSES):
1016+ for typ, cls in BUG_TRACKER_CLASSES.items():
1017 if getattr(cls, '_status_lookup', None) is not None:
1018 yield typ, cls
1019
1020diff --git a/utilities/list-pages b/utilities/list-pages
1021index 2f584ab..3dd9314 100755
1022--- a/utilities/list-pages
1023+++ b/utilities/list-pages
1024@@ -47,7 +47,6 @@ import _pythonpath # noqa: F401
1025 from inspect import getmro
1026 import os
1027
1028-import six
1029 from zope.app.wsgi.testlayer import BrowserLayer
1030 from zope.browserpage.simpleviewclass import simple
1031 from zope.component import (
1032@@ -177,7 +176,7 @@ def format_page_adapter(a):
1033 _BLACKLIST = [
1034 '__conform__',
1035 ]
1036-class Whatever(object):
1037+class Whatever:
1038
1039 def __init__(self, name, interface=None):
1040 self._name = name
1041@@ -196,7 +195,7 @@ class Whatever(object):
1042
1043 def __call__(self, *args, **kwargs):
1044 args = map(repr, args)
1045- args.extend('%s=%r' % (k, v) for k, v in six.iteritems(kwargs))
1046+ args.extend('%s=%r' % (k, v) for k, v in kwargs.items())
1047 # If we're being called with no args, assume this is part of crazy
1048 # TALES stuff:
1049 # webapp/metazcml.py(365)path()
1050@@ -224,7 +223,7 @@ class Whatever(object):
1051
1052 @implementer(ICanonicalUrlData)
1053 @adapter(object)
1054-class DefaultCanonicalUrlData(object):
1055+class DefaultCanonicalUrlData:
1056 def __init__(self, name):
1057 self.path = '[[%s]]' % (name,)
1058 self.rootsite = None
1059diff --git a/utilities/make-lp-user b/utilities/make-lp-user
1060index ee792d1..6278075 100755
1061--- a/utilities/make-lp-user
1062+++ b/utilities/make-lp-user
1063@@ -103,12 +103,12 @@ def add_ssh_public_keys(person):
1064 key_set = getUtility(ISSHKeySet)
1065 for filename in ('id_rsa.pub', 'id_dsa.pub'):
1066 try:
1067- public_key_file = open(os.path.join(ssh_dir, filename), 'r')
1068+ public_key_file = open(os.path.join(ssh_dir, filename))
1069 try:
1070 public_key = public_key_file.read()
1071 finally:
1072 public_key_file.close()
1073- except (OSError, IOError):
1074+ except OSError:
1075 continue
1076 key_set.new(person, public_key)
1077 print('Registered SSH key: %s' % (filename,))
1078diff --git a/utilities/massage-bug-import-xml b/utilities/massage-bug-import-xml
1079index 997e3dd..7e43831 100755
1080--- a/utilities/massage-bug-import-xml
1081+++ b/utilities/massage-bug-import-xml
1082@@ -14,7 +14,7 @@ NS = "https://launchpad.net/xmlns/2006/bugs"
1083 def norm_text(elem):
1084 if elem is not None:
1085 if elem.text is None:
1086- elem.text = u""
1087+ elem.text = ""
1088 else:
1089 elem.text = elem.text.strip()
1090
1091@@ -26,7 +26,7 @@ def truncate(text, message=None):
1092 message = "[Truncated]"
1093 else:
1094 message = "[Truncated; %s]" % message
1095- return u"%s...\n\n%s" % (
1096+ return "%s...\n\n%s" % (
1097 "\n".join(lines[:30]).strip(), message)
1098 else:
1099 return text
1100@@ -97,7 +97,7 @@ def massage(root, project_name, fix_nickname, tag_nickname):
1101
1102 # Change the nickname.
1103 if nickname.text is None or fix_nickname:
1104- nickname.text = u"%s-%s" % (project_name, bug.get('id'))
1105+ nickname.text = "%s-%s" % (project_name, bug.get('id'))
1106
1107 # Resolve duplicateof, if it exists.
1108 if bug.get("id") in duplicates:
1109@@ -117,11 +117,11 @@ def massage(root, project_name, fix_nickname, tag_nickname):
1110 if first_comment_text is None:
1111 problem_detail("No comments!")
1112 problem_resolution("Setting description to '-'.")
1113- description.text = u'-'
1114+ description.text = '-'
1115 elif len(first_comment_text.text) == 0:
1116 problem_detail("First comment has no text!")
1117 problem_resolution("Setting description to '-'.")
1118- description.text = u'-'
1119+ description.text = '-'
1120 else:
1121 problem_detail("First comment has text.")
1122 problem_resolution("Removing description.")
1123@@ -159,7 +159,7 @@ def massage(root, project_name, fix_nickname, tag_nickname):
1124 problem(
1125 "Bug %s's first comment has no text." % bug.get('id'))
1126 problem_resolution("Setting comment text to '-'.")
1127- first_comment_text.text = u'-'
1128+ first_comment_text.text = '-'
1129 problem_resolved()
1130 elif len(first_comment_text.text) > 50000:
1131 problem(
1132@@ -170,12 +170,12 @@ def massage(root, project_name, fix_nickname, tag_nickname):
1133 attachment = etree.SubElement(
1134 first_comment, '{%s}attachment' % NS)
1135 etree.SubElement(attachment, '{%s}filename' % NS).text = (
1136- u"%s-bug-%s-full-description.txt" % (
1137+ "%s-bug-%s-full-description.txt" % (
1138 project_name, bug.get('id')))
1139 etree.SubElement(attachment, '{%s}title' % NS).text = (
1140- u"Full description (text/plain, utf-8)")
1141+ "Full description (text/plain, utf-8)")
1142 etree.SubElement(attachment, '{%s}mimetype' % NS).text = (
1143- u"text/plain")
1144+ "text/plain")
1145 etree.SubElement(attachment, '{%s}contents' % NS).text = (
1146 standard_b64encode(
1147 first_comment_text.text.encode('utf-8')
1148diff --git a/utilities/pglogwatch.py b/utilities/pglogwatch.py
1149index 52eee17..8d61ed1 100755
1150--- a/utilities/pglogwatch.py
1151+++ b/utilities/pglogwatch.py
1152@@ -38,7 +38,7 @@ def generate_loglines(logfile):
1153 raise RuntimeError("tail returned %d" % cmd.returncode)
1154
1155
1156-class Process(object):
1157+class Process:
1158 statement = None
1159 duration = None
1160 connection = None
1161@@ -48,7 +48,7 @@ class Process(object):
1162 self.pid = pid
1163
1164
1165-class Watcher(object):
1166+class Watcher:
1167 _line_re = re.compile(r"""
1168 ^\d{4}-\d\d-\d\d \s \d\d:\d\d:\d\d \s
1169 \[(?P<pid>\d+)\] \s (?P<type>LOG|ERROR|DETAIL): \s+ (?P<rest>.*)$
1170diff --git a/utilities/soyuz-sampledata-setup.py b/utilities/soyuz-sampledata-setup.py
1171index cde53e9..7a6e4f1 100755
1172--- a/utilities/soyuz-sampledata-setup.py
1173+++ b/utilities/soyuz-sampledata-setup.py
1174@@ -322,7 +322,7 @@ def sign_code_of_conduct(person, log):
1175 fake_gpg_key = LaunchpadObjectFactory().makeGPGKey(person)
1176 Store.of(person).add(SignedCodeOfConduct(
1177 owner=person, signing_key_fingerprint=fake_gpg_key.fingerprint,
1178- signedcode=u"Normally a signed CoC would go here.", active=True))
1179+ signedcode="Normally a signed CoC would go here.", active=True))
1180
1181
1182 def create_ppa_user(username, options, approver, log):

Subscribers

People subscribed via source and target branches

to status/vote changes: