Merge ~cjwatson/launchpad:pyupgrade-py3-testing into launchpad:master
- Git
- lp:~cjwatson/launchpad
- pyupgrade-py3-testing
- Merge into master
Proposed by
Colin Watson
Status: | Merged |
---|---|
Approved by: | Colin Watson |
Approved revision: | 746f5ebaec2bce4933ad522c5af5c1e96212ccf2 |
Merge reported by: | Otto Co-Pilot |
Merged at revision: | not available |
Proposed branch: | ~cjwatson/launchpad:pyupgrade-py3-testing |
Merge into: | launchpad:master |
Diff against target: |
1397 lines (+165/-177) 32 files modified
.git-blame-ignore-revs (+2/-0) .pre-commit-config.yaml (+3/-0) lib/lp/testing/__init__.py (+15/-17) lib/lp/testing/_login.py (+1/-2) lib/lp/testing/_webservice.py (+3/-3) lib/lp/testing/browser.py (+1/-1) lib/lp/testing/factory.py (+54/-62) lib/lp/testing/fixture.py (+9/-9) lib/lp/testing/html5browser.py (+1/-1) lib/lp/testing/karma.py (+1/-1) lib/lp/testing/keyserver/inprocess.py (+1/-1) lib/lp/testing/layers.py (+3/-4) lib/lp/testing/matchers.py (+9/-10) lib/lp/testing/pages.py (+16/-17) lib/lp/testing/swift/fakeswift.py (+2/-4) lib/lp/testing/swift/fixture.py (+2/-2) lib/lp/testing/swift/tests/test_fixture.py (+1/-1) lib/lp/testing/systemdocs.py (+4/-5) lib/lp/testing/tests/test_factory.py (+7/-7) lib/lp/testing/tests/test_fixture.py (+2/-2) lib/lp/testing/tests/test_html5browser.py (+1/-1) lib/lp/testing/tests/test_layers_functional.py (+4/-4) lib/lp/testing/tests/test_matchers.py (+5/-5) lib/lp/testing/tests/test_run_isolated_test.py (+3/-3) lib/lp/testing/tests/test_sampledata.py (+2/-2) lib/lp/testing/tests/test_testcase.py (+1/-1) lib/lp/testing/tests/test_testing.py (+3/-3) lib/lp/testing/xmlrpc.py (+1/-1) lib/lp/testing/yuixhr.py (+3/-3) lib/lp/testopenid/browser/server.py (+2/-2) lib/lp/testopenid/interfaces/server.py (+1/-1) lib/lp/testopenid/testing/helpers.py (+2/-2) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Guruprasad | Approve | ||
Review via email: mp+413954@code.launchpad.net |
Commit message
lp.{testing,
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs |
2 | index 7b39f1f..83958cd 100644 |
3 | --- a/.git-blame-ignore-revs |
4 | +++ b/.git-blame-ignore-revs |
5 | @@ -44,3 +44,5 @@ f3f15787ebabe305fbf3e3ae6c0fd8ca7dfb4465 |
6 | 2cda038936743a2f9271953c23b9fcc98968db63 |
7 | # apply pyupgrade --py3-plus to lp.soyuz |
8 | 21fb5364d9371c0ad2edf41fa6920c4e16ead2b0 |
9 | +# apply pyupgrade --py3-plus to lp.{testing,testopenid,tests} |
10 | +9621eff0fd58287b254fb228c11948fca85d547c |
11 | diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml |
12 | index d969ed2..cc22ee7 100644 |
13 | --- a/.pre-commit-config.yaml |
14 | +++ b/.pre-commit-config.yaml |
15 | @@ -57,6 +57,9 @@ repos: |
16 | |services |
17 | |snappy |
18 | |soyuz |
19 | + |testing |
20 | + |testopenid |
21 | + |tests |
22 | )/ |
23 | - repo: https://github.com/PyCQA/isort |
24 | rev: 5.9.2 |
25 | diff --git a/lib/lp/testing/__init__.py b/lib/lp/testing/__init__.py |
26 | index 24c4eea..de3cfcf 100644 |
27 | --- a/lib/lp/testing/__init__.py |
28 | +++ b/lib/lp/testing/__init__.py |
29 | @@ -681,7 +681,7 @@ class TestCase(testtools.TestCase, fixtures.TestWithFixtures): |
30 | The config values will be restored during test tearDown. |
31 | """ |
32 | name = self.factory.getUniqueString() |
33 | - body = '\n'.join("%s: %s" % (k, v) for k, v in six.iteritems(kwargs)) |
34 | + body = '\n'.join("%s: %s" % (k, v) for k, v in kwargs.items()) |
35 | config.push(name, "\n[%s]\n%s\n" % (section, body)) |
36 | self.addCleanup(config.pop, name) |
37 | |
38 | @@ -703,7 +703,7 @@ class TestCase(testtools.TestCase, fixtures.TestWithFixtures): |
39 | self.addDetail('librarian-log', content) |
40 | |
41 | def setUp(self): |
42 | - super(TestCase, self).setUp() |
43 | + super().setUp() |
44 | # Circular imports. |
45 | from lp.testing.factory import ObjectFactory |
46 | from lp.testing.layers import LibrarianLayer |
47 | @@ -822,7 +822,7 @@ class TestCase(testtools.TestCase, fixtures.TestWithFixtures): |
48 | class TestCaseWithFactory(TestCase): |
49 | |
50 | def setUp(self, user=ANONYMOUS): |
51 | - super(TestCaseWithFactory, self).setUp() |
52 | + super().setUp() |
53 | login(user) |
54 | self.addCleanup(logout) |
55 | from lp.testing.factory import LaunchpadObjectFactory |
56 | @@ -870,7 +870,7 @@ class TestCaseWithFactory(TestCase): |
57 | :param branch_url: The URL to create the branch at. |
58 | :param format: The format of branch to create. |
59 | """ |
60 | - if format is not None and isinstance(format, six.string_types): |
61 | + if format is not None and isinstance(format, str): |
62 | format = format_registry.get(format)() |
63 | return ControlDir.create_branch_convenience(branch_url, format=format) |
64 | |
65 | @@ -958,7 +958,7 @@ class BrowserTestCase(TestCaseWithFactory): |
66 | |
67 | def setUp(self): |
68 | """Provide useful defaults.""" |
69 | - super(BrowserTestCase, self).setUp() |
70 | + super().setUp() |
71 | self.user = self.factory.makePerson() |
72 | |
73 | def getViewBrowser(self, context, view_name=None, no_login=False, |
74 | @@ -1010,7 +1010,7 @@ class WebServiceTestCase(TestCaseWithFactory): |
75 | return AppServerLayer |
76 | |
77 | def setUp(self): |
78 | - super(WebServiceTestCase, self).setUp() |
79 | + super().setUp() |
80 | self.ws_version = 'devel' |
81 | self.service = self.factory.makeLaunchpadService( |
82 | version=self.ws_version) |
83 | @@ -1057,14 +1057,14 @@ class AbstractYUITestCase(TestCase): |
84 | methodName = self._testMethodName |
85 | else: |
86 | assert methodName == self._testMethodName |
87 | - super(AbstractYUITestCase, self).__init__(methodName) |
88 | + super().__init__(methodName) |
89 | |
90 | def id(self): |
91 | """Return an ID for this test based on the file path.""" |
92 | return os.path.relpath(self.test_path, config.root) |
93 | |
94 | def setUp(self): |
95 | - super(AbstractYUITestCase, self).setUp() |
96 | + super().setUp() |
97 | # html5browser imports from the gir/pygtk stack which causes |
98 | # twisted tests to break because of gtk's initialize. |
99 | from lp.testing import html5browser |
100 | @@ -1227,8 +1227,7 @@ class RunIsolatedTest(testtools.RunTest): |
101 | fdwrite = os.fdopen(pwrite, 'wb', 1) |
102 | # Send results to the subunit stream client so that the parent |
103 | # process can obtain the result. |
104 | - super(RunIsolatedTest, self).run( |
105 | - subunit.TestProtocolClient(fdwrite)) |
106 | + super().run(subunit.TestProtocolClient(fdwrite)) |
107 | fdwrite.flush() |
108 | # See note above about flushing. |
109 | sys.__stdout__.flush() |
110 | @@ -1373,7 +1372,7 @@ def normalize_whitespace(string): |
111 | # whitespace is roughly 6 times faster than using an uncompiled |
112 | # regex (for the expression \s+), and 4 times faster than a |
113 | # compiled regex. |
114 | - joiner = b" " if isinstance(string, bytes) else u" " |
115 | + joiner = b" " if isinstance(string, bytes) else " " |
116 | return joiner.join(string.split()) |
117 | |
118 | |
119 | @@ -1403,7 +1402,7 @@ def map_branch_contents(branch): |
120 | return contents |
121 | |
122 | |
123 | -def set_feature_flag(name, value, scope=u'default', priority=1): |
124 | +def set_feature_flag(name, value, scope='default', priority=1): |
125 | """Set a feature flag to the specified value. |
126 | |
127 | In order to access the flag, use the feature_flags context manager or |
128 | @@ -1442,13 +1441,13 @@ def monkey_patch(context, **kwargs): |
129 | """ |
130 | old_values = {} |
131 | not_set = object() |
132 | - for name, value in six.iteritems(kwargs): |
133 | + for name, value in kwargs.items(): |
134 | old_values[name] = getattr(context, name, not_set) |
135 | setattr(context, name, value) |
136 | try: |
137 | yield |
138 | finally: |
139 | - for name, value in six.iteritems(old_values): |
140 | + for name, value in old_values.items(): |
141 | if value is not_set: |
142 | delattr(context, name) |
143 | else: |
144 | @@ -1472,13 +1471,12 @@ class ExpectedException(TTExpectedException): |
145 | """An ExpectedException that provides access to the caught exception.""" |
146 | |
147 | def __init__(self, exc_type, value_re): |
148 | - super(ExpectedException, self).__init__(exc_type, value_re) |
149 | + super().__init__(exc_type, value_re) |
150 | self.caught_exc = None |
151 | |
152 | def __exit__(self, exc_type, exc_value, traceback): |
153 | self.caught_exc = exc_value |
154 | - return super(ExpectedException, self).__exit__( |
155 | - exc_type, exc_value, traceback) |
156 | + return super().__exit__(exc_type, exc_value, traceback) |
157 | |
158 | |
159 | def extract_lp_cache(text): |
160 | diff --git a/lib/lp/testing/_login.py b/lib/lp/testing/_login.py |
161 | index 439b8b0..a90b3ec 100644 |
162 | --- a/lib/lp/testing/_login.py |
163 | +++ b/lib/lp/testing/_login.py |
164 | @@ -21,7 +21,6 @@ __all__ = [ |
165 | |
166 | from contextlib import contextmanager |
167 | |
168 | -import six |
169 | from zope.component import getUtility |
170 | from zope.security.management import ( |
171 | endInteraction, |
172 | @@ -69,7 +68,7 @@ def login(email, participation=None): |
173 | setPrincipal(), otherwise it must allow setting its principal attribute. |
174 | """ |
175 | |
176 | - if not isinstance(email, six.string_types): |
177 | + if not isinstance(email, str): |
178 | raise ValueError("Expected email parameter to be a string.") |
179 | participation = _test_login_impl(participation) |
180 | setupInteractionByEmail(email, participation) |
181 | diff --git a/lib/lp/testing/_webservice.py b/lib/lp/testing/_webservice.py |
182 | index 4c9d1b6..c705f68 100644 |
183 | --- a/lib/lp/testing/_webservice.py |
184 | +++ b/lib/lp/testing/_webservice.py |
185 | @@ -58,15 +58,15 @@ def oauth_access_token_for(consumer_name, person, permission, context=None): |
186 | |
187 | :return: A tuple of an OAuthAccessToken object and its secret. |
188 | """ |
189 | - if isinstance(person, six.string_types): |
190 | + if isinstance(person, str): |
191 | # Look up a person by name. |
192 | person = getUtility(IPersonSet).getByName(person) |
193 | - if isinstance(context, six.string_types): |
194 | + if isinstance(context, str): |
195 | # Turn an OAuth context string into the corresponding object. |
196 | # Avoid an import loop by importing from launchpad.browser here. |
197 | from lp.services.oauth.browser import lookup_oauth_context |
198 | context = lookup_oauth_context(context) |
199 | - if isinstance(permission, six.string_types): |
200 | + if isinstance(permission, str): |
201 | # Look up a permission by its token string. |
202 | permission = OAuthPermission.items[permission] |
203 | |
204 | diff --git a/lib/lp/testing/browser.py b/lib/lp/testing/browser.py |
205 | index a315362..ed2f222 100644 |
206 | --- a/lib/lp/testing/browser.py |
207 | +++ b/lib/lp/testing/browser.py |
208 | @@ -49,7 +49,7 @@ class Browser(_Browser): |
209 | wsgi_app = AuthorizationMiddleware( |
210 | TransactionMiddleware( |
211 | TransparentProxy(client=client))) |
212 | - super(Browser, self).__init__(url=url, wsgi_app=wsgi_app) |
213 | + super().__init__(url=url, wsgi_app=wsgi_app) |
214 | |
215 | @property |
216 | def vhost(self): |
217 | diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py |
218 | index 05b92c4..7ba28f6 100644 |
219 | --- a/lib/lp/testing/factory.py |
220 | +++ b/lib/lp/testing/factory.py |
221 | @@ -454,7 +454,7 @@ class ObjectFactory(metaclass=AutoDecorate(default_master_store)): |
222 | don't care. |
223 | :return: A hexadecimal string, with 'a'-'f' in lower case. |
224 | """ |
225 | - hex_number = u'%x' % self.getUniqueInteger() |
226 | + hex_number = '%x' % self.getUniqueInteger() |
227 | if digits is not None: |
228 | hex_number = hex_number.zfill(digits) |
229 | return hex_number |
230 | @@ -634,7 +634,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
231 | if account_status == AccountStatus.PLACEHOLDER: |
232 | # Placeholder people are pretty special, so just create and |
233 | # bail out. |
234 | - openid = self.getUniqueUnicode(u'%s-openid' % name) |
235 | + openid = self.getUniqueUnicode('%s-openid' % name) |
236 | person = getUtility(IPersonSet).createPlaceholderPerson( |
237 | openid, name) |
238 | return person |
239 | @@ -800,7 +800,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
240 | """ |
241 | if owner is None: |
242 | owner = self.makePerson() |
243 | - elif isinstance(owner, six.string_types): |
244 | + elif isinstance(owner, str): |
245 | owner = getUtility(IPersonSet).getByName(owner) |
246 | else: |
247 | pass |
248 | @@ -1097,7 +1097,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
249 | if time_starts is None: |
250 | time_starts = datetime(2009, 1, 1, tzinfo=pytz.UTC) |
251 | time_ends = time_starts + timedelta(days=1) |
252 | - time_zone = u'UTC' |
253 | + time_zone = 'UTC' |
254 | summary = self.getUniqueUnicode('summary') |
255 | return getUtility(ISprintSet).new( |
256 | owner=owner, name=name, title=title, time_zone=time_zone, |
257 | @@ -1195,7 +1195,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
258 | else: |
259 | make_sourcepackagename = ( |
260 | sourcepackagename is None or |
261 | - isinstance(sourcepackagename, six.text_type)) |
262 | + isinstance(sourcepackagename, str)) |
263 | if make_sourcepackagename: |
264 | sourcepackagename = self.makeSourcePackageName( |
265 | sourcepackagename) |
266 | @@ -1613,7 +1613,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
267 | return ProxyFactory( |
268 | Diff.fromFile(BytesIO(diff_text), len(diff_text))) |
269 | |
270 | - def makePreviewDiff(self, conflicts=u'', merge_proposal=None, |
271 | + def makePreviewDiff(self, conflicts='', merge_proposal=None, |
272 | date_created=None, size='small', git=False): |
273 | diff = self.makeDiff(size) |
274 | if merge_proposal is None: |
275 | @@ -1804,9 +1804,9 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
276 | paths = [self.getUniqueUnicode('refs/heads/path')] |
277 | refs_info = { |
278 | path: { |
279 | - u"sha1": six.ensure_text( |
280 | + "sha1": six.ensure_text( |
281 | hashlib.sha1(path.encode('utf-8')).hexdigest()), |
282 | - u"type": GitObjectType.COMMIT, |
283 | + "type": GitObjectType.COMMIT, |
284 | } |
285 | for path in paths} |
286 | refs_by_path = { |
287 | @@ -1823,7 +1823,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
288 | path = self.getUniqueUnicode('refs/heads/path') |
289 | return getUtility(IGitRefRemoteSet).new(repository_url, path) |
290 | |
291 | - def makeGitRule(self, repository=None, ref_pattern=u"refs/heads/*", |
292 | + def makeGitRule(self, repository=None, ref_pattern="refs/heads/*", |
293 | creator=None, position=None, **repository_kwargs): |
294 | """Create a Git repository access rule.""" |
295 | if repository is None: |
296 | @@ -2128,7 +2128,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
297 | """ |
298 | if bug is None: |
299 | bug = self.makeBug() |
300 | - elif isinstance(bug, (six.integer_types, six.string_types)): |
301 | + elif isinstance(bug, (int, str)): |
302 | bug = getUtility(IBugSet).getByNameOrID(str(bug)) |
303 | if owner is None: |
304 | owner = self.makePerson() |
305 | @@ -2163,7 +2163,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
306 | """ |
307 | if bug is None: |
308 | bug = self.makeBug() |
309 | - elif isinstance(bug, (six.integer_types, six.string_types)): |
310 | + elif isinstance(bug, (int, str)): |
311 | bug = getUtility(IBugSet).getByNameOrID(str(bug)) |
312 | if owner is None: |
313 | owner = self.makePerson() |
314 | @@ -2362,7 +2362,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
315 | status=SpecificationWorkItemStatus.TODO, |
316 | sequence=None): |
317 | if title is None: |
318 | - title = self.getUniqueString(u'title') |
319 | + title = self.getUniqueString('title') |
320 | if specification is None: |
321 | product = None |
322 | distribution = None |
323 | @@ -2510,7 +2510,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
324 | spn = self.getUniqueString() |
325 | changelog = '' |
326 | for version in versions: |
327 | - entry = dedent(u'''\ |
328 | + entry = dedent('''\ |
329 | %s (%s) unstable; urgency=low |
330 | |
331 | * %s. |
332 | @@ -2936,7 +2936,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
333 | """ |
334 | if purpose is None: |
335 | purpose = ArchivePurpose.PPA |
336 | - elif isinstance(purpose, six.string_types): |
337 | + elif isinstance(purpose, str): |
338 | purpose = ArchivePurpose.items[purpose.upper()] |
339 | |
340 | if distribution is None: |
341 | @@ -3616,8 +3616,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
342 | SourcePackagePublishingHistory. |
343 | """ |
344 | # Make sure we have a real sourcepackagename object. |
345 | - if (sourcepackagename is None or |
346 | - isinstance(sourcepackagename, six.string_types)): |
347 | + if sourcepackagename is None or isinstance(sourcepackagename, str): |
348 | sourcepackagename = self.getOrMakeSourcePackageName( |
349 | sourcepackagename) |
350 | if distroseries is None: |
351 | @@ -3776,17 +3775,16 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
352 | if archive is None: |
353 | archive = distroseries.main_archive |
354 | |
355 | - if (sourcepackagename is None or |
356 | - isinstance(sourcepackagename, six.string_types)): |
357 | + if sourcepackagename is None or isinstance(sourcepackagename, str): |
358 | sourcepackagename = self.getOrMakeSourcePackageName( |
359 | sourcepackagename) |
360 | |
361 | - if (component is None or isinstance(component, six.string_types)): |
362 | + if (component is None or isinstance(component, str)): |
363 | component = self.makeComponent(component) |
364 | |
365 | if urgency is None: |
366 | urgency = self.getAnySourcePackageUrgency() |
367 | - elif isinstance(urgency, six.string_types): |
368 | + elif isinstance(urgency, str): |
369 | urgency = SourcePackageUrgency.items[urgency.upper()] |
370 | |
371 | section = self.makeSection(name=section_name) |
372 | @@ -3803,7 +3801,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
373 | creator = self.makePerson() |
374 | |
375 | if version is None: |
376 | - version = six.text_type(self.getUniqueInteger()) + 'version' |
377 | + version = str(self.getUniqueInteger()) + 'version' |
378 | |
379 | if copyright is None: |
380 | copyright = self.getUniqueString() |
381 | @@ -3893,7 +3891,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
382 | archive = source_package_release.upload_archive |
383 | if pocket is None: |
384 | pocket = PackagePublishingPocket.RELEASE |
385 | - elif isinstance(pocket, six.string_types): |
386 | + elif isinstance(pocket, str): |
387 | pocket = PackagePublishingPocket.items[pocket.upper()] |
388 | |
389 | if source_package_release is None: |
390 | @@ -3973,12 +3971,12 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
391 | |
392 | if pocket is None: |
393 | pocket = self.getAnyPocket() |
394 | - elif isinstance(pocket, six.string_types): |
395 | + elif isinstance(pocket, str): |
396 | pocket = PackagePublishingPocket.items[pocket.upper()] |
397 | |
398 | if status is None: |
399 | status = PackagePublishingStatus.PENDING |
400 | - elif isinstance(status, six.string_types): |
401 | + elif isinstance(status, str): |
402 | status = PackagePublishingStatus.items[status.upper()] |
403 | |
404 | if sourcepackagerelease is None: |
405 | @@ -4177,8 +4175,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
406 | """Make a `BinaryPackageRelease`.""" |
407 | if build is None: |
408 | build = self.makeBinaryPackageBuild() |
409 | - if (binarypackagename is None or |
410 | - isinstance(binarypackagename, six.string_types)): |
411 | + if binarypackagename is None or isinstance(binarypackagename, str): |
412 | binarypackagename = self.getOrMakeBinaryPackageName( |
413 | binarypackagename) |
414 | if version is None: |
415 | @@ -4187,9 +4184,9 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
416 | binpackageformat = BinaryPackageFormat.DEB |
417 | if component is None: |
418 | component = build.source_package_release.component |
419 | - elif isinstance(component, six.text_type): |
420 | + elif isinstance(component, str): |
421 | component = getUtility(IComponentSet)[component] |
422 | - if isinstance(section_name, six.string_types): |
423 | + if isinstance(section_name, str): |
424 | section_name = self.makeSection(section_name) |
425 | section = section_name or build.source_package_release.section |
426 | if priority is None: |
427 | @@ -4252,11 +4249,11 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
428 | packages=(), distroseries=None, related_set=None): |
429 | """Make an `IPackageset`.""" |
430 | if name is None: |
431 | - name = self.getUniqueString(u'package-set-name') |
432 | + name = self.getUniqueString('package-set-name') |
433 | if description is None: |
434 | - description = self.getUniqueString(u'package-set-description') |
435 | + description = self.getUniqueString('package-set-description') |
436 | if owner is None: |
437 | - person = self.getUniqueString(u'package-set-owner') |
438 | + person = self.getUniqueString('package-set-owner') |
439 | owner = self.makePerson(name=person) |
440 | if distroseries is None: |
441 | distroseries = getUtility(IDistributionSet)[ |
442 | @@ -4301,8 +4298,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
443 | if pocket is None: |
444 | pocket = self.getAnyPocket() |
445 | # Make sure we have a real sourcepackagename object. |
446 | - if (sourcepackagename is None or |
447 | - isinstance(sourcepackagename, six.string_types)): |
448 | + if sourcepackagename is None or isinstance(sourcepackagename, str): |
449 | sourcepackagename = self.getOrMakeSourcePackageName( |
450 | sourcepackagename) |
451 | return ProxyFactory( |
452 | @@ -4311,8 +4307,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
453 | def makeDistributionSourcePackage(self, sourcepackagename=None, |
454 | distribution=None, with_db=False): |
455 | # Make sure we have a real sourcepackagename object. |
456 | - if (sourcepackagename is None or |
457 | - isinstance(sourcepackagename, six.string_types)): |
458 | + if sourcepackagename is None or isinstance(sourcepackagename, str): |
459 | sourcepackagename = self.getOrMakeSourcePackageName( |
460 | sourcepackagename) |
461 | if distribution is None: |
462 | @@ -4462,8 +4457,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
463 | It doesn't actually run the job. It fakes it, and uses a fake |
464 | librarian file so as to work without the librarian. |
465 | """ |
466 | - blob = TemporaryBlobStorage( |
467 | - uuid=six.text_type(uuid.uuid1()), file_alias=1) |
468 | + blob = TemporaryBlobStorage(uuid=str(uuid.uuid1()), file_alias=1) |
469 | job = getUtility(IProcessApportBlobJobSource).create(blob) |
470 | job.job.start() |
471 | removeSecurityProxy(job).metadata = { |
472 | @@ -4476,7 +4470,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
473 | person = self.makePerson() |
474 | from lp.testing.layers import BaseLayer |
475 | launchpad = launchpadlib_for( |
476 | - u"test", person, service_root=BaseLayer.appserver_root_url("api"), |
477 | + "test", person, service_root=BaseLayer.appserver_root_url("api"), |
478 | version=version) |
479 | login_person(person) |
480 | return launchpad |
481 | @@ -4510,7 +4504,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
482 | if key is None: |
483 | key = self.getUniqueUnicode("oauthconsumerkey") |
484 | if secret is None: |
485 | - secret = u'' |
486 | + secret = '' |
487 | return getUtility(IOAuthConsumerSet).new(key, secret) |
488 | |
489 | def makeOAuthRequestToken(self, consumer=None, date_created=None, |
490 | @@ -4592,8 +4586,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
491 | """Create a new `PlainPackageCopyJob`.""" |
492 | if package_name is None and package_version is None: |
493 | package_name = self.makeSourcePackageName().name |
494 | - package_version = ( |
495 | - six.text_type(self.getUniqueInteger()) + 'version') |
496 | + package_version = str(self.getUniqueInteger()) + 'version' |
497 | if source_archive is None: |
498 | source_archive = self.makeArchive() |
499 | if target_archive is None: |
500 | @@ -4679,7 +4672,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
501 | return fileupload |
502 | |
503 | def makeCommercialSubscription(self, product, expired=False, |
504 | - voucher_id=u'new'): |
505 | + voucher_id='new'): |
506 | """Create a commercial subscription for the given product.""" |
507 | if IStore(CommercialSubscription).find( |
508 | CommercialSubscription, product=product).one() is not None: |
509 | @@ -4696,7 +4689,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
510 | registrant=product.owner, |
511 | purchaser=product.owner, |
512 | sales_system_id=voucher_id, |
513 | - whiteboard=u'') |
514 | + whiteboard='') |
515 | del get_property_cache(product).commercial_subscription |
516 | return commercial_subscription |
517 | |
518 | @@ -4717,7 +4710,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
519 | if distroseries is None: |
520 | distroseries = self.makeDistroSeries() |
521 | if name is None: |
522 | - name = self.getUniqueString(u"livefs-name") |
523 | + name = self.getUniqueString("livefs-name") |
524 | if metadata is None: |
525 | metadata = {} |
526 | livefs = getUtility(ILiveFSSet).new( |
527 | @@ -4825,7 +4818,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
528 | if distroseries is _DEFAULT: |
529 | distroseries = self.makeDistroSeries() |
530 | if name is None: |
531 | - name = self.getUniqueString(u"snap-name") |
532 | + name = self.getUniqueString("snap-name") |
533 | if branch is None and git_ref is None: |
534 | branch = self.makeAnyBranch() |
535 | if auto_build: |
536 | @@ -4941,7 +4934,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
537 | if registrant is None: |
538 | registrant = self.makePerson() |
539 | if name is None: |
540 | - name = self.getUniqueString(u"snappy-series-name") |
541 | + name = self.getUniqueString("snappy-series-name") |
542 | if display_name is None: |
543 | display_name = SPACE.join( |
544 | word.capitalize() for word in name.split('-')) |
545 | @@ -4965,21 +4958,21 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
546 | if registrant is None: |
547 | registrant = self.makePerson() |
548 | if name is None: |
549 | - name = self.getUniqueString(u"snap-base-name") |
550 | + name = self.getUniqueString("snap-base-name") |
551 | if display_name is None: |
552 | display_name = SPACE.join( |
553 | word.capitalize() for word in name.split('-')) |
554 | if distro_series is None: |
555 | distro_series = self.makeDistroSeries() |
556 | if build_channels is None: |
557 | - build_channels = {u"snapcraft": u"stable"} |
558 | + build_channels = {"snapcraft": "stable"} |
559 | return getUtility(ISnapBaseSet).new( |
560 | registrant, name, display_name, distro_series, build_channels, |
561 | processors=processors, date_created=date_created) |
562 | |
563 | def makeOCIProjectName(self, name=None): |
564 | if name is None: |
565 | - name = self.getUniqueString(u"oci-project-name") |
566 | + name = self.getUniqueString("oci-project-name") |
567 | return getUtility(IOCIProjectNameSet).getOrCreateByName(name) |
568 | |
569 | def makeOCIProject(self, registrant=None, pillar=None, |
570 | @@ -4992,7 +4985,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
571 | registrant = self.makePerson() |
572 | if pillar is None: |
573 | pillar = self.makeDistribution() |
574 | - if ociprojectname is None or isinstance(ociprojectname, six.text_type): |
575 | + if ociprojectname is None or isinstance(ociprojectname, str): |
576 | ociprojectname = self.makeOCIProjectName(ociprojectname) |
577 | return getUtility(IOCIProjectSet).new( |
578 | registrant, pillar, ociprojectname, date_created=date_created, |
579 | @@ -5005,9 +4998,9 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
580 | oci_project=None, **kwargs): |
581 | """Make a new OCIProjectSeries attached to an OCIProject.""" |
582 | if name is None: |
583 | - name = self.getUniqueString(u"oci-project-series-name") |
584 | + name = self.getUniqueString("oci-project-series-name") |
585 | if summary is None: |
586 | - summary = self.getUniqueString(u"oci-project-series-summary") |
587 | + summary = self.getUniqueString("oci-project-series-summary") |
588 | if registrant is None: |
589 | registrant = self.makePerson() |
590 | if oci_project is None: |
591 | @@ -5022,23 +5015,23 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
592 | information_type=InformationType.PUBLIC): |
593 | """Make a new OCIRecipe.""" |
594 | if name is None: |
595 | - name = self.getUniqueString(u"oci-recipe-name") |
596 | + name = self.getUniqueString("oci-recipe-name") |
597 | if registrant is None: |
598 | registrant = self.makePerson() |
599 | if description is None: |
600 | - description = self.getUniqueString(u"oci-recipe-description") |
601 | + description = self.getUniqueString("oci-recipe-description") |
602 | if owner is None: |
603 | owner = self.makeTeam(members=[registrant]) |
604 | if oci_project is None: |
605 | oci_project = self.makeOCIProject() |
606 | if git_ref is None: |
607 | component = self.getUniqueUnicode() |
608 | - paths = [u'refs/heads/{}-20.04'.format(component)] |
609 | + paths = ['refs/heads/{}-20.04'.format(component)] |
610 | [git_ref] = self.makeGitRefs(paths=paths) |
611 | if build_file is None: |
612 | - build_file = self.getUniqueUnicode(u"build_file_for") |
613 | + build_file = self.getUniqueUnicode("build_file_for") |
614 | if build_path is None: |
615 | - build_path = self.getUniqueUnicode(u"build_path_for") |
616 | + build_path = self.getUniqueUnicode("build_path_for") |
617 | return getUtility(IOCIRecipeSet).new( |
618 | name=name, |
619 | registrant=registrant, |
620 | @@ -5148,7 +5141,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
621 | if registry_credentials is None: |
622 | registry_credentials = self.makeOCIRegistryCredentials() |
623 | if image_name is None: |
624 | - image_name = self.getUniqueUnicode(u"oci-image-name") |
625 | + image_name = self.getUniqueUnicode("oci-image-name") |
626 | return getUtility(IOCIPushRuleSet).new( |
627 | recipe=recipe, |
628 | registry_credentials=registry_credentials, |
629 | @@ -5182,7 +5175,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): |
630 | information_type=information_type, |
631 | branch_sharing_policy=branch_sharing_policy) |
632 | if name is None: |
633 | - name = self.getUniqueUnicode(u"charm-name") |
634 | + name = self.getUniqueUnicode("charm-name") |
635 | if git_ref is None: |
636 | git_ref = self.makeGitRefs()[0] |
637 | recipe = getUtility(ICharmRecipeSet).new( |
638 | @@ -5277,7 +5270,6 @@ unwrapped_types = frozenset({ |
639 | datetime, |
640 | int, |
641 | str, |
642 | - six.text_type, |
643 | }) |
644 | |
645 | |
646 | @@ -5305,7 +5297,7 @@ class UnproxiedFactoryMethodWarning(UserWarning): |
647 | """Raised when someone calls an unproxied factory method.""" |
648 | |
649 | def __init__(self, method_name): |
650 | - super(UnproxiedFactoryMethodWarning, self).__init__( |
651 | + super().__init__( |
652 | "PLEASE FIX: LaunchpadObjectFactory.%s returns an " |
653 | "unproxied object." % (method_name, )) |
654 | |
655 | @@ -5317,7 +5309,7 @@ class ShouldThisBeUsingRemoveSecurityProxy(UserWarning): |
656 | message = ( |
657 | "removeSecurityProxy(%r) called. Is this correct? " |
658 | "Either call it directly or fix the test." % obj) |
659 | - super(ShouldThisBeUsingRemoveSecurityProxy, self).__init__(message) |
660 | + super().__init__(message) |
661 | |
662 | |
663 | class LaunchpadObjectFactory: |
664 | diff --git a/lib/lp/testing/fixture.py b/lib/lp/testing/fixture.py |
665 | index ce70144..0a26c57 100644 |
666 | --- a/lib/lp/testing/fixture.py |
667 | +++ b/lib/lp/testing/fixture.py |
668 | @@ -68,7 +68,7 @@ class PGBouncerFixture(pgbouncer.fixture.PGBouncerFixture): |
669 | """ |
670 | |
671 | def __init__(self): |
672 | - super(PGBouncerFixture, self).__init__() |
673 | + super().__init__() |
674 | |
675 | # Known databases |
676 | from lp.testing.layers import DatabaseLayer |
677 | @@ -97,7 +97,7 @@ class PGBouncerFixture(pgbouncer.fixture.PGBouncerFixture): |
678 | self.admin_users = ['launchpad', 'pgbouncer', os.environ['USER']] |
679 | |
680 | def setUp(self): |
681 | - super(PGBouncerFixture, self).setUp() |
682 | + super().setUp() |
683 | |
684 | # reconnect_store cleanup added first so it is run last, after |
685 | # the environment variables have been reset. |
686 | @@ -130,11 +130,11 @@ class PGBouncerFixture(pgbouncer.fixture.PGBouncerFixture): |
687 | def start(self, retries=20, sleep=0.5): |
688 | """Start PGBouncer, waiting for it to accept connections if neccesary. |
689 | """ |
690 | - super(PGBouncerFixture, self).start() |
691 | + super().start() |
692 | for i in range(retries): |
693 | try: |
694 | socket.create_connection((self.host, self.port)) |
695 | - except socket.error: |
696 | + except OSError: |
697 | # Try again. |
698 | pass |
699 | else: |
700 | @@ -147,8 +147,8 @@ class PGBouncerFixture(pgbouncer.fixture.PGBouncerFixture): |
701 | class ZopeAdapterFixture(Fixture): |
702 | """A fixture to register and unregister an adapter.""" |
703 | |
704 | - def __init__(self, factory, required=None, provided=None, name=u"", |
705 | - info=u"", event=True): |
706 | + def __init__(self, factory, required=None, provided=None, name="", |
707 | + info="", event=True): |
708 | # We use some private functions from here since we need them to work |
709 | # out how to query for existing adapters. We could copy and paste |
710 | # the code instead, but it doesn't seem worth it. |
711 | @@ -181,7 +181,7 @@ class ZopeEventHandlerFixture(Fixture): |
712 | """A fixture that provides and then unprovides a Zope event handler.""" |
713 | |
714 | def __init__(self, handler, required=None): |
715 | - super(ZopeEventHandlerFixture, self).__init__() |
716 | + super().__init__() |
717 | self._handler = handler |
718 | self._required = required |
719 | |
720 | @@ -201,7 +201,7 @@ class ZopeViewReplacementFixture(Fixture): |
721 | def __init__(self, name, context_interface, |
722 | request_interface=IDefaultBrowserLayer, |
723 | replacement=None): |
724 | - super(ZopeViewReplacementFixture, self).__init__() |
725 | + super().__init__() |
726 | self.name = name |
727 | self.context_interface = context_interface |
728 | self.request_interface = request_interface |
729 | @@ -270,7 +270,7 @@ class CapturedOutput(Fixture): |
730 | """A fixture that captures output to stdout and stderr.""" |
731 | |
732 | def __init__(self): |
733 | - super(CapturedOutput, self).__init__() |
734 | + super().__init__() |
735 | self.stdout = six.StringIO() |
736 | self.stderr = six.StringIO() |
737 | |
738 | diff --git a/lib/lp/testing/html5browser.py b/lib/lp/testing/html5browser.py |
739 | index e54e305..7230ab2 100644 |
740 | --- a/lib/lp/testing/html5browser.py |
741 | +++ b/lib/lp/testing/html5browser.py |
742 | @@ -67,7 +67,7 @@ class Browser(WebKit.WebView): |
743 | INCREMENTAL_TIMEOUT = None |
744 | |
745 | def __init__(self, show_window=False, hide_console_messages=True): |
746 | - super(Browser, self).__init__() |
747 | + super().__init__() |
748 | self.show_window = show_window |
749 | self.hide_console_messages = hide_console_messages |
750 | self.browser_window = None |
751 | diff --git a/lib/lp/testing/karma.py b/lib/lp/testing/karma.py |
752 | index 0c0e75c..0393a4b 100644 |
753 | --- a/lib/lp/testing/karma.py |
754 | +++ b/lib/lp/testing/karma.py |
755 | @@ -111,7 +111,7 @@ class KarmaAssignedEventListener(KarmaRecorder): |
756 | """ |
757 | |
758 | def __init__(self, show_person=False): |
759 | - super(KarmaAssignedEventListener, self).__init__() |
760 | + super().__init__() |
761 | self.added_karma_actions = set() |
762 | self.show_person = show_person |
763 | |
764 | diff --git a/lib/lp/testing/keyserver/inprocess.py b/lib/lp/testing/keyserver/inprocess.py |
765 | index 70d6aae..932ff2e 100644 |
766 | --- a/lib/lp/testing/keyserver/inprocess.py |
767 | +++ b/lib/lp/testing/keyserver/inprocess.py |
768 | @@ -67,7 +67,7 @@ class InProcessKeyServerFixture(Fixture): |
769 | # fixtures.callmany.CallMany doesn't support cleanup functions that |
770 | # return Deferred, so we have to do this manually. |
771 | yield self._port.stopListening() |
772 | - return super(InProcessKeyServerFixture, self).cleanUp(*args, **kwargs) |
773 | + return super().cleanUp(*args, **kwargs) |
774 | |
775 | @property |
776 | def url(self): |
777 | diff --git a/lib/lp/testing/layers.py b/lib/lp/testing/layers.py |
778 | index 3c60e5b..d27ca18 100644 |
779 | --- a/lib/lp/testing/layers.py |
780 | +++ b/lib/lp/testing/layers.py |
781 | @@ -977,8 +977,7 @@ class TransactionMiddleware: |
782 | |
783 | def __call__(self, environ, start_response): |
784 | transaction.commit() |
785 | - for entry in self.app(environ, start_response): |
786 | - yield entry |
787 | + yield from self.app(environ, start_response) |
788 | |
789 | |
790 | class RemoteAddrMiddleware: |
791 | @@ -1026,7 +1025,7 @@ class _FunctionalBrowserLayer(zope.testbrowser.wsgi.Layer, ZCMLFileLayer): |
792 | fake_db = object() |
793 | |
794 | def __init__(self, *args, **kwargs): |
795 | - super(_FunctionalBrowserLayer, self).__init__(*args, **kwargs) |
796 | + super().__init__(*args, **kwargs) |
797 | self.middlewares = [ |
798 | AuthorizationMiddleware, |
799 | RemoteAddrMiddleware, |
800 | @@ -1036,7 +1035,7 @@ class _FunctionalBrowserLayer(zope.testbrowser.wsgi.Layer, ZCMLFileLayer): |
801 | ] |
802 | |
803 | def setUp(self): |
804 | - super(_FunctionalBrowserLayer, self).setUp() |
805 | + super().setUp() |
806 | # We don't use ZODB, but the webapp subscribes to IDatabaseOpened to |
807 | # perform some post-configuration tasks, so emit that event |
808 | # manually. |
809 | diff --git a/lib/lp/testing/matchers.py b/lib/lp/testing/matchers.py |
810 | index 84e26c9..2f5ffad 100644 |
811 | --- a/lib/lp/testing/matchers.py |
812 | +++ b/lib/lp/testing/matchers.py |
813 | @@ -21,7 +21,6 @@ __all__ = [ |
814 | ] |
815 | |
816 | from lazr.lifecycle.snapshot import Snapshot |
817 | -import six |
818 | from testtools import matchers |
819 | from testtools.content import text_content |
820 | from testtools.matchers import ( |
821 | @@ -119,7 +118,7 @@ class DoesNotCorrectlyProvide(DoesNotProvide): |
822 | :param extra: any extra information about the mismatch as a string, |
823 | or None |
824 | """ |
825 | - super(DoesNotCorrectlyProvide, self).__init__(obj, interface) |
826 | + super().__init__(obj, interface) |
827 | self.extra = extra |
828 | |
829 | def describe(self): |
830 | @@ -209,12 +208,12 @@ class _MismatchedQueryCount(Mismatch): |
831 | result = [] |
832 | for query in collector.queries: |
833 | start, stop, dbname, statement, backtrace = query |
834 | - result.append(u'%d-%d@%s %s' % ( |
835 | + result.append('%d-%d@%s %s' % ( |
836 | start, stop, dbname, statement.rstrip())) |
837 | - result.append(u'-' * 70) |
838 | + result.append('-' * 70) |
839 | if backtrace is not None: |
840 | result.append(backtrace.rstrip()) |
841 | - result.append(u'.' * 70) |
842 | + result.append('.' * 70) |
843 | return text_content('\n'.join(result)) |
844 | |
845 | def get_details(self): |
846 | @@ -402,7 +401,7 @@ class SoupMismatch(Mismatch): |
847 | self.soup_content = soup_content |
848 | |
849 | def get_details(self): |
850 | - return {'content': text_content(six.text_type(self.soup_content))} |
851 | + return {'content': text_content(str(self.soup_content))} |
852 | |
853 | |
854 | class MissingElement(SoupMismatch): |
855 | @@ -474,14 +473,14 @@ class EqualsIgnoringWhitespace(Equals): |
856 | """ |
857 | |
858 | def __init__(self, expected): |
859 | - if isinstance(expected, (bytes, six.text_type)): |
860 | + if isinstance(expected, (bytes, str)): |
861 | expected = normalize_whitespace(expected) |
862 | - super(EqualsIgnoringWhitespace, self).__init__(expected) |
863 | + super().__init__(expected) |
864 | |
865 | def match(self, observed): |
866 | - if isinstance(observed, (bytes, six.text_type)): |
867 | + if isinstance(observed, (bytes, str)): |
868 | observed = normalize_whitespace(observed) |
869 | - return super(EqualsIgnoringWhitespace, self).match(observed) |
870 | + return super().match(observed) |
871 | |
872 | |
873 | class FileContainsBytes(FileContains): |
874 | diff --git a/lib/lp/testing/pages.py b/lib/lp/testing/pages.py |
875 | index 5c7a2fa..f28cf7a 100644 |
876 | --- a/lib/lp/testing/pages.py |
877 | +++ b/lib/lp/testing/pages.py |
878 | @@ -87,9 +87,9 @@ from lp.testing.systemdocs import ( |
879 | |
880 | |
881 | SAMPLEDATA_ACCESS_SECRETS = { |
882 | - u'salgado-read-nonprivate': u'secret', |
883 | - u'salgado-change-anything': u'test', |
884 | - u'nopriv-read-nonprivate': u'mystery', |
885 | + 'salgado-read-nonprivate': 'secret', |
886 | + 'salgado-change-anything': 'test', |
887 | + 'nopriv-read-nonprivate': 'mystery', |
888 | } |
889 | |
890 | |
891 | @@ -141,7 +141,7 @@ class LaunchpadWebServiceCaller(WebServiceCaller): |
892 | if oauth_consumer_key is not None and oauth_access_key is not None: |
893 | if oauth_access_secret is None: |
894 | oauth_access_secret = SAMPLEDATA_ACCESS_SECRETS.get( |
895 | - oauth_access_key, u'') |
896 | + oauth_access_key, '') |
897 | self.oauth_client = oauth1.Client( |
898 | oauth_consumer_key, |
899 | resource_owner_key=oauth_access_key, |
900 | @@ -343,11 +343,11 @@ ELEMENTS_INTRODUCING_NEWLINE = [ |
901 | 'address', 'li', 'dt', 'dd', 'th', 'td', 'caption', 'br'] |
902 | |
903 | |
904 | -NEWLINES_RE = re.compile(u'\n+') |
905 | +NEWLINES_RE = re.compile('\n+') |
906 | LEADING_AND_TRAILING_SPACES_RE = re.compile( |
907 | - u'(^[ \t]+)|([ \t]$)', re.MULTILINE) |
908 | -TABS_AND_SPACES_RE = re.compile(u'[ \t]+') |
909 | -NBSP_RE = re.compile(u' | |\xa0') |
910 | + '(^[ \t]+)|([ \t]$)', re.MULTILINE) |
911 | +TABS_AND_SPACES_RE = re.compile('[ \t]+') |
912 | +NBSP_RE = re.compile(' | |\xa0') |
913 | |
914 | |
915 | def extract_link_from_tag(tag, base=None): |
916 | @@ -390,7 +390,7 @@ def extract_text(content, extract_image_text=False, skip_tags=None, |
917 | if type(node) in IGNORED_ELEMENTS: |
918 | continue |
919 | elif isinstance(node, CData): |
920 | - result.append(six.text_type(node)) |
921 | + result.append(str(node)) |
922 | elif isinstance(node, NavigableString): |
923 | result.append(node.format_string(node, formatter=formatter)) |
924 | else: |
925 | @@ -401,7 +401,7 @@ def extract_text(content, extract_image_text=False, skip_tags=None, |
926 | elif getattr(node, 'name', '') in skip_tags: |
927 | continue |
928 | if node.name.lower() in ELEMENTS_INTRODUCING_NEWLINE: |
929 | - result.append(u'\n') |
930 | + result.append('\n') |
931 | |
932 | # If extract_image_text is True and the node is an |
933 | # image, try to find its title or alt attributes. |
934 | @@ -416,7 +416,7 @@ def extract_text(content, extract_image_text=False, skip_tags=None, |
935 | # Process this node's children next. |
936 | nodes[0:0] = list(node) |
937 | |
938 | - text = u''.join(result) |
939 | + text = ''.join(result) |
940 | text = NBSP_RE.sub(' ', text) |
941 | text = TABS_AND_SPACES_RE.sub(' ', text) |
942 | text = LEADING_AND_TRAILING_SPACES_RE.sub('', text) |
943 | @@ -647,8 +647,7 @@ class Browser(_Browser): |
944 | |
945 | def addHeader(self, key, value): |
946 | """Make sure headers are native strings.""" |
947 | - super(Browser, self).addHeader( |
948 | - wsgi_native_string(key), wsgi_native_string(value)) |
949 | + super().addHeader(wsgi_native_string(key), wsgi_native_string(value)) |
950 | |
951 | def _getText(self, element): |
952 | def get_strings(elem): |
953 | @@ -656,10 +655,10 @@ class Browser(_Browser): |
954 | if isinstance(descendant, (NavigableString, CData)): |
955 | yield descendant |
956 | elif isinstance(descendant, Tag) and descendant.name == 'img': |
957 | - yield u'%s[%s]' % ( |
958 | - descendant.get('alt', u''), descendant.name.upper()) |
959 | + yield '%s[%s]' % ( |
960 | + descendant.get('alt', ''), descendant.name.upper()) |
961 | |
962 | - return u''.join(list(get_strings(element))) |
963 | + return ''.join(list(get_strings(element))) |
964 | |
965 | def getLink(self, text=None, url=None, id=None, index=0): |
966 | """Search for both text nodes and image alt attributes.""" |
967 | @@ -738,7 +737,7 @@ def safe_canonical_url(*args, **kwargs): |
968 | return str(canonical_url(*args, **kwargs)) |
969 | |
970 | |
971 | -def webservice_for_person(person, consumer_key=u'launchpad-library', |
972 | +def webservice_for_person(person, consumer_key='launchpad-library', |
973 | permission=OAuthPermission.READ_PUBLIC, |
974 | context=None, default_api_version=None): |
975 | """Return a valid LaunchpadWebServiceCaller for the person. |
976 | diff --git a/lib/lp/testing/swift/fakeswift.py b/lib/lp/testing/swift/fakeswift.py |
977 | index f0134d8..69d9502 100644 |
978 | --- a/lib/lp/testing/swift/fakeswift.py |
979 | +++ b/lib/lp/testing/swift/fakeswift.py |
980 | @@ -19,7 +19,6 @@ import os.path |
981 | import time |
982 | import uuid |
983 | |
984 | -import six |
985 | from twisted.web import ( |
986 | http, |
987 | resource, |
988 | @@ -75,7 +74,7 @@ class FakeKeystone(resource.Resource): |
989 | if token is not None and self._isValidToken(token, tenant_name): |
990 | return token |
991 | else: |
992 | - for id, token in six.iteritems(self.tokens): |
993 | + for id, token in self.tokens.items(): |
994 | if self._isValidToken(token, tenant_name): |
995 | return token |
996 | |
997 | @@ -353,8 +352,7 @@ class SwiftContainer(resource.Resource): |
998 | |
999 | def iter_children(self): |
1000 | """Iterator that returns each child object.""" |
1001 | - for key, val in self.container_children.items(): |
1002 | - yield key, val |
1003 | + yield from self.container_children.items() |
1004 | |
1005 | def getChild(self, name, request): |
1006 | """Get the next object down the chain.""" |
1007 | diff --git a/lib/lp/testing/swift/fixture.py b/lib/lp/testing/swift/fixture.py |
1008 | index facaf47..d0382d5 100644 |
1009 | --- a/lib/lp/testing/swift/fixture.py |
1010 | +++ b/lib/lp/testing/swift/fixture.py |
1011 | @@ -32,7 +32,7 @@ class SwiftFixture(TacTestFixture): |
1012 | daemon_port = None |
1013 | |
1014 | def __init__(self, old_instance=False): |
1015 | - super(SwiftFixture, self).__init__() |
1016 | + super().__init__() |
1017 | self.old_instance = old_instance |
1018 | |
1019 | def _getConfig(self, key): |
1020 | @@ -53,7 +53,7 @@ class SwiftFixture(TacTestFixture): |
1021 | config.root, 'logs', 'fakeswift-%s.pid' % self.daemon_port) |
1022 | assert self.daemon_port is not None |
1023 | |
1024 | - super(SwiftFixture, self).setUp( |
1025 | + super().setUp( |
1026 | spew, umask, |
1027 | os.path.join(config.root, 'bin', 'py'), |
1028 | os.path.join(config.root, 'bin', 'twistd')) |
1029 | diff --git a/lib/lp/testing/swift/tests/test_fixture.py b/lib/lp/testing/swift/tests/test_fixture.py |
1030 | index 431a6dd..091da15 100644 |
1031 | --- a/lib/lp/testing/swift/tests/test_fixture.py |
1032 | +++ b/lib/lp/testing/swift/tests/test_fixture.py |
1033 | @@ -30,7 +30,7 @@ class TestSwiftFixture(TestCase): |
1034 | layer = BaseLayer |
1035 | |
1036 | def setUp(self): |
1037 | - super(TestSwiftFixture, self).setUp() |
1038 | + super().setUp() |
1039 | self.swift_fixture = SwiftFixture() |
1040 | self.useFixture(self.swift_fixture) |
1041 | self.factory = ObjectFactory() |
1042 | diff --git a/lib/lp/testing/systemdocs.py b/lib/lp/testing/systemdocs.py |
1043 | index 4ea6d5f..99dba51 100644 |
1044 | --- a/lib/lp/testing/systemdocs.py |
1045 | +++ b/lib/lp/testing/systemdocs.py |
1046 | @@ -211,7 +211,7 @@ def stop(): |
1047 | sys.stdout = old_stdout |
1048 | |
1049 | |
1050 | -class PrettyPrinter(pprint.PrettyPrinter, object): |
1051 | +class PrettyPrinter(pprint.PrettyPrinter): |
1052 | """A pretty-printer that formats text in the Python 3 style. |
1053 | |
1054 | This should only be used when the resulting ambiguities between str and |
1055 | @@ -220,20 +220,19 @@ class PrettyPrinter(pprint.PrettyPrinter, object): |
1056 | """ |
1057 | |
1058 | def format(self, obj, contexts, maxlevels, level): |
1059 | - if isinstance(obj, six.text_type): |
1060 | + if isinstance(obj, str): |
1061 | obj = obj.encode('unicode_escape').decode('ASCII') |
1062 | if "'" in obj and '"' not in obj: |
1063 | return '"%s"' % obj, True, False |
1064 | else: |
1065 | return "'%s'" % obj.replace("'", "\\'"), True, False |
1066 | else: |
1067 | - return super(PrettyPrinter, self).format( |
1068 | - obj, contexts, maxlevels, level) |
1069 | + return super().format(obj, contexts, maxlevels, level) |
1070 | |
1071 | # Disable wrapping of long strings on Python >= 3.5, which is unhelpful |
1072 | # in doctests. There seems to be no reasonable public API for this. |
1073 | _dispatch = dict(pprint.PrettyPrinter._dispatch) |
1074 | - del _dispatch[six.text_type.__repr__] |
1075 | + del _dispatch[str.__repr__] |
1076 | del _dispatch[bytes.__repr__] |
1077 | del _dispatch[bytearray.__repr__] |
1078 | |
1079 | diff --git a/lib/lp/testing/tests/test_factory.py b/lib/lp/testing/tests/test_factory.py |
1080 | index 61010aa..4953455 100644 |
1081 | --- a/lib/lp/testing/tests/test_factory.py |
1082 | +++ b/lib/lp/testing/tests/test_factory.py |
1083 | @@ -628,20 +628,20 @@ class TestFactory(TestCaseWithFactory): |
1084 | |
1085 | # makeCVE |
1086 | def test_makeCVE_returns_cve(self): |
1087 | - cve = self.factory.makeCVE(sequence=u'2000-1234') |
1088 | + cve = self.factory.makeCVE(sequence='2000-1234') |
1089 | self.assertThat(cve, ProvidesAndIsProxied(ICve)) |
1090 | |
1091 | def test_makeCVE_uses_sequence(self): |
1092 | - cve = self.factory.makeCVE(sequence=u'2000-1234') |
1093 | - self.assertEqual(u'2000-1234', cve.sequence) |
1094 | + cve = self.factory.makeCVE(sequence='2000-1234') |
1095 | + self.assertEqual('2000-1234', cve.sequence) |
1096 | |
1097 | def test_makeCVE_uses_description(self): |
1098 | - cve = self.factory.makeCVE(sequence=u'2000-1234', description=u'foo') |
1099 | - self.assertEqual(u'foo', cve.description) |
1100 | + cve = self.factory.makeCVE(sequence='2000-1234', description='foo') |
1101 | + self.assertEqual('foo', cve.description) |
1102 | |
1103 | def test_makeCVE_uses_cve_status(self): |
1104 | cve = self.factory.makeCVE( |
1105 | - sequence=u'2000-1234', cvestate=CveStatus.DEPRECATED) |
1106 | + sequence='2000-1234', cvestate=CveStatus.DEPRECATED) |
1107 | self.assertEqual(CveStatus.DEPRECATED, cve.status) |
1108 | |
1109 | # dir() support. |
1110 | @@ -890,7 +890,7 @@ class IsSecurityProxiedOrHarmlessTests(TestCaseWithFactory): |
1111 | def test_is_security_proxied_or_harmless__unicode(self): |
1112 | # is_security_proxied_or_harmless() considers unicode objects |
1113 | # to be harmless. |
1114 | - self.assertTrue(is_security_proxied_or_harmless(u'abc')) |
1115 | + self.assertTrue(is_security_proxied_or_harmless('abc')) |
1116 | |
1117 | def test_is_security_proxied_or_harmless__proxied_object(self): |
1118 | # is_security_proxied_or_harmless() treats security proxied |
1119 | diff --git a/lib/lp/testing/tests/test_fixture.py b/lib/lp/testing/tests/test_fixture.py |
1120 | index f8592c7..db2887a 100644 |
1121 | --- a/lib/lp/testing/tests/test_fixture.py |
1122 | +++ b/lib/lp/testing/tests/test_fixture.py |
1123 | @@ -123,7 +123,7 @@ class TestZopeAdapterFixture(TestCase): |
1124 | |
1125 | |
1126 | @implementer(IMailDelivery) |
1127 | -class DummyMailer(object): |
1128 | +class DummyMailer: |
1129 | |
1130 | pass |
1131 | |
1132 | @@ -332,7 +332,7 @@ class TestDisableTriggerFixture(TestCase): |
1133 | layer = ZopelessDatabaseLayer |
1134 | |
1135 | def setUp(self): |
1136 | - super(TestDisableTriggerFixture, self).setUp() |
1137 | + super().setUp() |
1138 | con_str = dbconfig.rw_main_primary + ' user=launchpad_main' |
1139 | con = psycopg2.connect(con_str) |
1140 | con.set_isolation_level(0) |
1141 | diff --git a/lib/lp/testing/tests/test_html5browser.py b/lib/lp/testing/tests/test_html5browser.py |
1142 | index bd64569..bc30aad 100644 |
1143 | --- a/lib/lp/testing/tests/test_html5browser.py |
1144 | +++ b/lib/lp/testing/tests/test_html5browser.py |
1145 | @@ -78,7 +78,7 @@ class BrowserTestCase(TestCase): |
1146 | """Verify Browser methods.""" |
1147 | |
1148 | def setUp(self): |
1149 | - super(BrowserTestCase, self).setUp() |
1150 | + super().setUp() |
1151 | self.file = NamedTemporaryFile( |
1152 | mode='w+', prefix='html5browser_', suffix='.html') |
1153 | self.addCleanup(self.file.close) |
1154 | diff --git a/lib/lp/testing/tests/test_layers_functional.py b/lib/lp/testing/tests/test_layers_functional.py |
1155 | index 1b8c536..1787087 100644 |
1156 | --- a/lib/lp/testing/tests/test_layers_functional.py |
1157 | +++ b/lib/lp/testing/tests/test_layers_functional.py |
1158 | @@ -66,7 +66,7 @@ class BaseLayerIsolator(Fixture): |
1159 | :param with_persistent: If True LP_PERSISTENT_TEST_SERVICES will |
1160 | be enabled during setUp. |
1161 | """ |
1162 | - super(BaseLayerIsolator, self).__init__() |
1163 | + super().__init__() |
1164 | self.with_persistent = with_persistent |
1165 | |
1166 | def _setUp(self): |
1167 | @@ -92,7 +92,7 @@ class LayerFixture(Fixture): |
1168 | |
1169 | :param layer: The layer to use. |
1170 | """ |
1171 | - super(LayerFixture, self).__init__() |
1172 | + super().__init__() |
1173 | self.layer = layer |
1174 | |
1175 | def _setUp(self): |
1176 | @@ -198,7 +198,7 @@ class BaseTestCase(TestCase): |
1177 | self.want_librarian_running, |
1178 | 'Librarian should not be running.' |
1179 | ) |
1180 | - except IOError: |
1181 | + except OSError: |
1182 | self.assertFalse( |
1183 | self.want_librarian_running, |
1184 | 'Librarian should be running.' |
1185 | @@ -496,7 +496,7 @@ class LayerProcessControllerTestCase(TestCase): |
1186 | layer = DatabaseLayer |
1187 | |
1188 | def tearDown(self): |
1189 | - super(LayerProcessControllerTestCase, self).tearDown() |
1190 | + super().tearDown() |
1191 | # Stop the app server. It's okay if it isn't running. |
1192 | LayerProcessController.stopAppServer() |
1193 | |
1194 | diff --git a/lib/lp/testing/tests/test_matchers.py b/lib/lp/testing/tests/test_matchers.py |
1195 | index 30c0df1..9b04b5d 100644 |
1196 | --- a/lib/lp/testing/tests/test_matchers.py |
1197 | +++ b/lib/lp/testing/tests/test_matchers.py |
1198 | @@ -378,14 +378,14 @@ class EqualsIgnoringWhitespaceTests(TestCase): |
1199 | mismatch.describe()) |
1200 | |
1201 | def test_match_unicode(self): |
1202 | - matcher = EqualsIgnoringWhitespace(u"one \t two \n \u1234 ") |
1203 | - self.assertIs(None, matcher.match(u" one \r two \u1234 ")) |
1204 | + matcher = EqualsIgnoringWhitespace("one \t two \n \u1234 ") |
1205 | + self.assertIs(None, matcher.match(" one \r two \u1234 ")) |
1206 | |
1207 | def test_mismatch_unicode(self): |
1208 | - matcher = EqualsIgnoringWhitespace(u"one \t two \n \u1234 ") |
1209 | - mismatch = matcher.match(u" one \r \u1234 ") |
1210 | + matcher = EqualsIgnoringWhitespace("one \t two \n \u1234 ") |
1211 | + mismatch = matcher.match(" one \r \u1234 ") |
1212 | self.assertEqual( |
1213 | - u"%r != %r" % (u"one \u1234", u"one two \u1234"), |
1214 | + "%r != %r" % ("one \u1234", "one two \u1234"), |
1215 | mismatch.describe()) |
1216 | |
1217 | def test_match_non_string(self): |
1218 | diff --git a/lib/lp/testing/tests/test_run_isolated_test.py b/lib/lp/testing/tests/test_run_isolated_test.py |
1219 | index 363bca2..66a1cfe 100644 |
1220 | --- a/lib/lp/testing/tests/test_run_isolated_test.py |
1221 | +++ b/lib/lp/testing/tests/test_run_isolated_test.py |
1222 | @@ -101,13 +101,13 @@ class TestRunIsolatedTest(TestCase): |
1223 | @record_pid |
1224 | def __init__(self, method_name='runTest'): |
1225 | # Runs in the parent process. |
1226 | - super(TestRunIsolatedTest, self).__init__(method_name) |
1227 | + super().__init__(method_name) |
1228 | self.layer = TestRunIsolatedTestLayer() |
1229 | |
1230 | @record_pid |
1231 | def setUp(self): |
1232 | # Runs in the child process. |
1233 | - super(TestRunIsolatedTest, self).setUp() |
1234 | + super().setUp() |
1235 | self.assertNotEqual( |
1236 | self.layer.pid_in___init__, self.pid_in_setUp, |
1237 | "setUp() called in parent process.") |
1238 | @@ -122,7 +122,7 @@ class TestRunIsolatedTest(TestCase): |
1239 | @record_pid |
1240 | def tearDown(self): |
1241 | # Runs in the child process. |
1242 | - super(TestRunIsolatedTest, self).tearDown() |
1243 | + super().tearDown() |
1244 | self.assertEqual( |
1245 | self.pid_in_setUp, self.pid_in_tearDown, |
1246 | "tearDown() not run in same process as setUp().") |
1247 | diff --git a/lib/lp/testing/tests/test_sampledata.py b/lib/lp/testing/tests/test_sampledata.py |
1248 | index e3699da..ac65bd1 100644 |
1249 | --- a/lib/lp/testing/tests/test_sampledata.py |
1250 | +++ b/lib/lp/testing/tests/test_sampledata.py |
1251 | @@ -21,13 +21,13 @@ class SampleDataTestCase(TestCase): |
1252 | layer = DatabaseLayer |
1253 | |
1254 | def setUp(self): |
1255 | - super(SampleDataTestCase, self).setUp() |
1256 | + super().setUp() |
1257 | self.pg_fixture = PgTestSetup(template='template1') |
1258 | self.pg_fixture.setUp() |
1259 | |
1260 | def tearDown(self): |
1261 | self.pg_fixture.tearDown() |
1262 | - super(SampleDataTestCase, self).tearDown() |
1263 | + super().tearDown() |
1264 | |
1265 | def test_testSampledata(self): |
1266 | """Test the sample data used by the test suite.""" |
1267 | diff --git a/lib/lp/testing/tests/test_testcase.py b/lib/lp/testing/tests/test_testcase.py |
1268 | index 75f5c26..86b61ad 100644 |
1269 | --- a/lib/lp/testing/tests/test_testcase.py |
1270 | +++ b/lib/lp/testing/tests/test_testcase.py |
1271 | @@ -112,7 +112,7 @@ class TestRemoveLoggingHandlers(TestCase): |
1272 | self.logger.addHandler(logging.Handler()) |
1273 | self.logger.addHandler(logging.Handler()) |
1274 | # `TestCase.setUp()` removes the handlers just added. |
1275 | - super(TestRemoveLoggingHandlers, self).setUp() |
1276 | + super().setUp() |
1277 | |
1278 | def test_handlers_list_is_empty(self): |
1279 | # Ensure `TestCase.setUp()` correctly removed all logging handlers. |
1280 | diff --git a/lib/lp/testing/tests/test_testing.py b/lib/lp/testing/tests/test_testing.py |
1281 | index ec6154b..7a7e931 100644 |
1282 | --- a/lib/lp/testing/tests/test_testing.py |
1283 | +++ b/lib/lp/testing/tests/test_testing.py |
1284 | @@ -31,18 +31,18 @@ class TestFeatureFlags(TestCase): |
1285 | # test (other tests will re-add it). This prevents weird |
1286 | # interactions in a parallel test environment. |
1287 | uninstall_feature_controller() |
1288 | - self.assertRaises(AssertionError, set_feature_flag, u'name', u'value') |
1289 | + self.assertRaises(AssertionError, set_feature_flag, 'name', 'value') |
1290 | |
1291 | def test_flags_set_within_feature_flags_context(self): |
1292 | """In the feature_flags context, set/get works.""" |
1293 | self.useContext(feature_flags()) |
1294 | - set_feature_flag(u'name', u'value') |
1295 | + set_feature_flag('name', 'value') |
1296 | self.assertEqual('value', getFeatureFlag('name')) |
1297 | |
1298 | def test_flags_unset_outside_feature_flags_context(self): |
1299 | """get fails when used outside the feature_flags context.""" |
1300 | with feature_flags(): |
1301 | - set_feature_flag(u'name', u'value') |
1302 | + set_feature_flag('name', 'value') |
1303 | self.assertIs(None, getFeatureFlag('name')) |
1304 | |
1305 | |
1306 | diff --git a/lib/lp/testing/xmlrpc.py b/lib/lp/testing/xmlrpc.py |
1307 | index 82ac254..f795693 100644 |
1308 | --- a/lib/lp/testing/xmlrpc.py |
1309 | +++ b/lib/lp/testing/xmlrpc.py |
1310 | @@ -23,7 +23,7 @@ from lp.services.webapp.interaction import ( |
1311 | from lp.testing.pages import http |
1312 | |
1313 | |
1314 | -class _FakeSocket(object): |
1315 | +class _FakeSocket: |
1316 | """Pretend to be a socket that has a makefile method. |
1317 | |
1318 | This is used because it is what http.client.HTTPResponse expects. |
1319 | diff --git a/lib/lp/testing/yuixhr.py b/lib/lp/testing/yuixhr.py |
1320 | index 7bb18a0..e438e15 100644 |
1321 | --- a/lib/lp/testing/yuixhr.py |
1322 | +++ b/lib/lp/testing/yuixhr.py |
1323 | @@ -249,7 +249,7 @@ class YUITestFixtureControllerView(LaunchpadView): |
1324 | """) |
1325 | |
1326 | def __init__(self, context, request): |
1327 | - super(YUITestFixtureControllerView, self).__init__(context, request) |
1328 | + super().__init__(context, request) |
1329 | self.names = [] |
1330 | self.action = None |
1331 | self.fixtures = [] |
1332 | @@ -486,13 +486,13 @@ class YUIAppServerTestCase(AbstractYUITestCase): |
1333 | self.facet = facet |
1334 | # This needs to be done early so the "id" is set correctly. |
1335 | self.test_path = self.module_name.replace('.', '/') |
1336 | - super(YUIAppServerTestCase, self).__init__() |
1337 | + super().__init__() |
1338 | |
1339 | def setUp(self): |
1340 | config = LayerProcessController.appserver_config |
1341 | root_url = config.appserver_root_url(self.facet) |
1342 | self.html_uri = '%s/+yuitest/%s' % (root_url, self.test_path) |
1343 | - super(YUIAppServerTestCase, self).setUp() |
1344 | + super().setUp() |
1345 | |
1346 | runTest = AbstractYUITestCase.checkResults |
1347 | |
1348 | diff --git a/lib/lp/testopenid/browser/server.py b/lib/lp/testopenid/browser/server.py |
1349 | index bdf4774..04d0982 100644 |
1350 | --- a/lib/lp/testopenid/browser/server.py |
1351 | +++ b/lib/lp/testopenid/browser/server.py |
1352 | @@ -134,7 +134,7 @@ class OpenIDMixin: |
1353 | openid_request = None |
1354 | |
1355 | def __init__(self, context, request): |
1356 | - super(OpenIDMixin, self).__init__(context, request) |
1357 | + super().__init__(context, request) |
1358 | self.server_url = get_server_url() |
1359 | self.openid_server = Server(get_openid_store(), self.server_url) |
1360 | |
1361 | @@ -304,7 +304,7 @@ class TestOpenIDLoginView(OpenIDMixin, LaunchpadFormView): |
1362 | |
1363 | def initialize(self): |
1364 | self.restoreRequestFromSession() |
1365 | - super(TestOpenIDLoginView, self).initialize() |
1366 | + super().initialize() |
1367 | |
1368 | def validate(self, data): |
1369 | """Check that the email address is valid for login.""" |
1370 | diff --git a/lib/lp/testopenid/interfaces/server.py b/lib/lp/testopenid/interfaces/server.py |
1371 | index cb8b675..8930f00 100644 |
1372 | --- a/lib/lp/testopenid/interfaces/server.py |
1373 | +++ b/lib/lp/testopenid/interfaces/server.py |
1374 | @@ -23,7 +23,7 @@ class ITestOpenIDApplication(ILaunchpadApplication): |
1375 | |
1376 | |
1377 | class ITestOpenIDLoginForm(Interface): |
1378 | - email = TextLine(title=u'What is your email address?', required=True) |
1379 | + email = TextLine(title='What is your email address?', required=True) |
1380 | |
1381 | |
1382 | class ITestOpenIDPersistentIdentity(IOpenIDPersistentIdentity): |
1383 | diff --git a/lib/lp/testopenid/testing/helpers.py b/lib/lp/testopenid/testing/helpers.py |
1384 | index ded6f31..4d189e4 100644 |
1385 | --- a/lib/lp/testopenid/testing/helpers.py |
1386 | +++ b/lib/lp/testopenid/testing/helpers.py |
1387 | @@ -30,10 +30,10 @@ class EchoView(LaunchpadView): |
1388 | |
1389 | def render(self): |
1390 | out = io.StringIO() |
1391 | - print(u'Request method: %s' % self.request.method, file=out) |
1392 | + print('Request method: %s' % self.request.method, file=out) |
1393 | keys = sorted(self.request.form.keys()) |
1394 | for key in keys: |
1395 | - print(u'%s:%s' % (key, self.request.form[key]), file=out) |
1396 | + print('%s:%s' % (key, self.request.form[key]), file=out) |
1397 | return out.getvalue() |
1398 | |
1399 |
I read through the diff and the changes look okay to me. 👍