Merge ~cjwatson/launchpad:py3-native-string-streams into launchpad:master
- Git
- lp:~cjwatson/launchpad
- py3-native-string-streams
- Merge into master
Proposed by
Colin Watson
Status: | Merged |
---|---|
Approved by: | Colin Watson |
Approved revision: | dc8ab9fa51c44661e2a8e49331bbcb837b70637b |
Merge reported by: | Otto Co-Pilot |
Merged at revision: | not available |
Proposed branch: | ~cjwatson/launchpad:py3-native-string-streams |
Merge into: | launchpad:master |
Diff against target: |
693 lines (+72/-67) 21 files modified
lib/devscripts/tests/test_sourcecode.py (+2/-2) lib/lp/archivepublisher/model/ftparchive.py (+2/-3) lib/lp/bugs/scripts/tests/test_bugnotification.py (+2/-2) lib/lp/registry/scripts/distributionmirror_prober.py (+2/-2) lib/lp/registry/tests/test_distributionmirror_prober.py (+10/-10) lib/lp/registry/tests/test_prf_finder.py (+2/-2) lib/lp/scripts/tests/test_garbo.py (+2/-2) lib/lp/scripts/utilities/warninghandler.py (+1/-2) lib/lp/services/job/tests/test_celeryjob.py (+3/-3) lib/lp/services/log/logger.py (+4/-3) lib/lp/services/mail/tests/test_dkim.py (+2/-2) lib/lp/services/testing/tests/test_parallel.py (+12/-8) lib/lp/services/tests/test_looptuner.py (+3/-4) lib/lp/services/twistedsupport/__init__.py (+2/-2) lib/lp/services/utils.py (+2/-3) lib/lp/services/webapp/opstats.py (+7/-4) lib/lp/services/webapp/tests/test_statementtracer.py (+3/-3) lib/lp/soyuz/scripts/ppareport.py (+3/-2) lib/lp/soyuz/scripts/tests/test_ppareport.py (+3/-2) lib/lp/testing/__init__.py (+3/-4) lib/lp/translations/scripts/po_export_queue.py (+2/-2) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ioana Lasc (community) | Approve | ||
Review via email: mp+387726@code.launchpad.net |
Commit message
Port native-string streams to six.StringIO
Description of the change
Of the streams that were created using StringIO.StringIO or cStringIO.StringIO, a number of them (mainly things like log files) accept native strings on both Python 2 and 3. Port these to six.StringIO for compatibility with Python 3.
To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/lib/devscripts/tests/test_sourcecode.py b/lib/devscripts/tests/test_sourcecode.py |
2 | index cc8f375..6b538c7 100644 |
3 | --- a/lib/devscripts/tests/test_sourcecode.py |
4 | +++ b/lib/devscripts/tests/test_sourcecode.py |
5 | @@ -9,7 +9,6 @@ __metaclass__ = type |
6 | |
7 | import os |
8 | import shutil |
9 | -from StringIO import StringIO |
10 | import tempfile |
11 | import unittest |
12 | |
13 | @@ -21,6 +20,7 @@ except ImportError: |
14 | from bzrlib.bzrdir import BzrDir |
15 | from bzrlib.tests import TestCase |
16 | from bzrlib.transport import get_transport |
17 | +import six |
18 | |
19 | from devscripts import get_launchpad_root |
20 | from devscripts.sourcecode import ( |
21 | @@ -35,7 +35,7 @@ class TestParseConfigFile(unittest.TestCase): |
22 | """Tests for the config file parser.""" |
23 | |
24 | def makeFile(self, contents): |
25 | - return StringIO(contents) |
26 | + return six.StringIO(contents) |
27 | |
28 | def test_empty(self): |
29 | # Parsing an empty config file returns an empty sequence. |
30 | diff --git a/lib/lp/archivepublisher/model/ftparchive.py b/lib/lp/archivepublisher/model/ftparchive.py |
31 | index 6fe3c3c..c516068 100644 |
32 | --- a/lib/lp/archivepublisher/model/ftparchive.py |
33 | +++ b/lib/lp/archivepublisher/model/ftparchive.py |
34 | @@ -4,7 +4,6 @@ |
35 | from collections import defaultdict |
36 | import os |
37 | import re |
38 | -from StringIO import StringIO |
39 | import time |
40 | |
41 | import scandir |
42 | @@ -754,7 +753,7 @@ class FTPArchiveHandler: |
43 | explicitly marked as dirty. dirty_pockets must be a nested |
44 | dictionary of booleans, keyed by distroseries.name then pocket. |
45 | """ |
46 | - apt_config = StringIO() |
47 | + apt_config = six.StringIO() |
48 | apt_config.write(CONFIG_HEADER % (self._config.archiveroot, |
49 | self._config.overrideroot, |
50 | self._config.cacheroot, |
51 | @@ -875,7 +874,7 @@ class FTPArchiveHandler: |
52 | except OSError: |
53 | pass |
54 | |
55 | - apt_config = StringIO() |
56 | + apt_config = six.StringIO() |
57 | apt_config.write(CONFIG_HEADER % (self._config.archiveroot, |
58 | self._config.overrideroot, |
59 | self._config.cacheroot, |
60 | diff --git a/lib/lp/bugs/scripts/tests/test_bugnotification.py b/lib/lp/bugs/scripts/tests/test_bugnotification.py |
61 | index 99b59c6..38d11d9 100644 |
62 | --- a/lib/lp/bugs/scripts/tests/test_bugnotification.py |
63 | +++ b/lib/lp/bugs/scripts/tests/test_bugnotification.py |
64 | @@ -13,10 +13,10 @@ from datetime import ( |
65 | import logging |
66 | import re |
67 | from smtplib import SMTPException |
68 | -import StringIO |
69 | import unittest |
70 | |
71 | import pytz |
72 | +import six |
73 | from testtools.matchers import ( |
74 | MatchesRegex, |
75 | Not, |
76 | @@ -402,7 +402,7 @@ class TestGetEmailNotifications(TestCase): |
77 | # in place. |
78 | |
79 | # Set up logging so we can later assert that no exceptions are logged. |
80 | - log_output = StringIO.StringIO() |
81 | + log_output = six.StringIO() |
82 | logger = logging.getLogger() |
83 | log_handler = logging.StreamHandler(log_output) |
84 | logger.addHandler(logging.StreamHandler(log_output)) |
85 | diff --git a/lib/lp/registry/scripts/distributionmirror_prober.py b/lib/lp/registry/scripts/distributionmirror_prober.py |
86 | index a6350ca..b1d2df0 100644 |
87 | --- a/lib/lp/registry/scripts/distributionmirror_prober.py |
88 | +++ b/lib/lp/registry/scripts/distributionmirror_prober.py |
89 | @@ -10,7 +10,6 @@ from datetime import datetime |
90 | import itertools |
91 | import logging |
92 | import os.path |
93 | -from StringIO import StringIO |
94 | |
95 | import OpenSSL |
96 | from OpenSSL.SSL import ( |
97 | @@ -18,6 +17,7 @@ from OpenSSL.SSL import ( |
98 | TLSv1_2_METHOD, |
99 | ) |
100 | import requests |
101 | +import six |
102 | from six.moves import http_client |
103 | from six.moves.urllib.parse import ( |
104 | unquote, |
105 | @@ -1037,7 +1037,7 @@ class DistroMirrorProber: |
106 | continue |
107 | |
108 | probed_mirrors.append(mirror) |
109 | - logfile = StringIO() |
110 | + logfile = six.StringIO() |
111 | logfiles[mirror_id] = logfile |
112 | probe_function(mirror, logfile, unchecked_keys, self.logger, |
113 | max_parallel, max_parallel_per_host) |
114 | diff --git a/lib/lp/registry/tests/test_distributionmirror_prober.py b/lib/lp/registry/tests/test_distributionmirror_prober.py |
115 | index c674ac0..38bf7dd 100644 |
116 | --- a/lib/lp/registry/tests/test_distributionmirror_prober.py |
117 | +++ b/lib/lp/registry/tests/test_distributionmirror_prober.py |
118 | @@ -9,11 +9,11 @@ __metaclass__ = type |
119 | from datetime import datetime |
120 | import logging |
121 | import os |
122 | -from StringIO import StringIO |
123 | |
124 | from fixtures import MockPatchObject |
125 | from lazr.uri import URI |
126 | import responses |
127 | +import six |
128 | from six.moves import http_client |
129 | from sqlobject import SQLObjectNotFound |
130 | from testtools.matchers import ( |
131 | @@ -859,7 +859,7 @@ class TestMirrorCDImageProberCallbacks(TestCaseWithFactory): |
132 | mirror = removeSecurityProxy( |
133 | self.factory.makeMirror(distroseries.distribution)) |
134 | callbacks = MirrorCDImageProberCallbacks( |
135 | - mirror, distroseries, 'ubuntu', StringIO()) |
136 | + mirror, distroseries, 'ubuntu', six.StringIO()) |
137 | return callbacks |
138 | |
139 | def getLogger(self): |
140 | @@ -961,7 +961,7 @@ class TestArchiveMirrorProberCallbacks(TestCaseWithFactory): |
141 | component = self.factory.makeComponent() |
142 | callbacks = ArchiveMirrorProberCallbacks( |
143 | mirror, distroseries, PackagePublishingPocket.RELEASE, |
144 | - component, 'foo', StringIO()) |
145 | + component, 'foo', six.StringIO()) |
146 | return callbacks |
147 | |
148 | def test_failure_propagation(self): |
149 | @@ -1050,7 +1050,7 @@ class TestProbeFunctionSemaphores(TestCase): |
150 | # Note that calling this function won't actually probe any mirrors; we |
151 | # need to call reactor.run() to actually start the probing. |
152 | with default_timeout(15.0): |
153 | - probe_cdimage_mirror(mirror, StringIO(), [], logging, 100, 2) |
154 | + probe_cdimage_mirror(mirror, six.StringIO(), [], logging, 100, 2) |
155 | self.assertEqual(0, len(mirror.cdimage_series)) |
156 | |
157 | def test_archive_mirror_probe_function(self): |
158 | @@ -1086,7 +1086,7 @@ class TestProbeFunctionSemaphores(TestCase): |
159 | mirror2_host = URI(mirror2.base_url).host |
160 | mirror3_host = URI(mirror3.base_url).host |
161 | |
162 | - probe_function(mirror1, StringIO(), [], logging, 100, 2) |
163 | + probe_function(mirror1, six.StringIO(), [], logging, 100, 2) |
164 | # Since we have a single mirror to probe we need to have a single |
165 | # DeferredSemaphore with a limit of max_per_host_requests, to ensure we |
166 | # don't issue too many simultaneous connections on that host. |
167 | @@ -1097,7 +1097,7 @@ class TestProbeFunctionSemaphores(TestCase): |
168 | # overall number of requests. |
169 | self.assertEqual(multi_lock.overall_lock.limit, max_requests) |
170 | |
171 | - probe_function(mirror2, StringIO(), [], logging, 100, 2) |
172 | + probe_function(mirror2, six.StringIO(), [], logging, 100, 2) |
173 | # Now we have two mirrors to probe, but they have the same hostname, |
174 | # so we'll still have a single semaphore in host_semaphores. |
175 | self.assertEqual(mirror2_host, mirror1_host) |
176 | @@ -1105,7 +1105,7 @@ class TestProbeFunctionSemaphores(TestCase): |
177 | multi_lock = request_manager.host_locks[mirror2_host] |
178 | self.assertEqual(multi_lock.host_lock.limit, max_per_host_requests) |
179 | |
180 | - probe_function(mirror3, StringIO(), [], logging, 100, 2) |
181 | + probe_function(mirror3, six.StringIO(), [], logging, 100, 2) |
182 | # This third mirror is on a separate host, so we'll have a second |
183 | # semaphore added to host_semaphores. |
184 | self.assertTrue(mirror3_host != mirror1_host) |
185 | @@ -1117,7 +1117,7 @@ class TestProbeFunctionSemaphores(TestCase): |
186 | # proxy, we'll use the mirror's host as the key to find the semaphore |
187 | # that should be used |
188 | self.pushConfig('launchpad', http_proxy='http://squid.internal:3128/') |
189 | - probe_function(mirror3, StringIO(), [], logging, 100, 2) |
190 | + probe_function(mirror3, six.StringIO(), [], logging, 100, 2) |
191 | self.assertEqual(len(request_manager.host_locks), 2) |
192 | |
193 | |
194 | @@ -1150,7 +1150,7 @@ class TestLoggingMixin(TestCase): |
195 | |
196 | def test_logMessage_output(self): |
197 | logger = LoggingMixin() |
198 | - logger.log_file = StringIO() |
199 | + logger.log_file = six.StringIO() |
200 | logger._getTime = self._fake_gettime |
201 | logger.logMessage("Ubuntu Warty Released") |
202 | logger.log_file.seek(0) |
203 | @@ -1161,7 +1161,7 @@ class TestLoggingMixin(TestCase): |
204 | |
205 | def test_logMessage_integration(self): |
206 | logger = LoggingMixin() |
207 | - logger.log_file = StringIO() |
208 | + logger.log_file = six.StringIO() |
209 | logger.logMessage("Probing...") |
210 | logger.log_file.seek(0) |
211 | message = logger.log_file.read() |
212 | diff --git a/lib/lp/registry/tests/test_prf_finder.py b/lib/lp/registry/tests/test_prf_finder.py |
213 | index 32a149a..f37cb1a 100644 |
214 | --- a/lib/lp/registry/tests/test_prf_finder.py |
215 | +++ b/lib/lp/registry/tests/test_prf_finder.py |
216 | @@ -4,10 +4,10 @@ |
217 | import logging |
218 | import os |
219 | import shutil |
220 | -from StringIO import StringIO |
221 | import tempfile |
222 | |
223 | import responses |
224 | +import six |
225 | from testtools import ExpectedException |
226 | import transaction |
227 | from zope.component import getUtility |
228 | @@ -389,7 +389,7 @@ class HandleReleaseTestCase(TestCase): |
229 | # Test that handleRelease() handles the case where a version can't be |
230 | # parsed from the url given. |
231 | ztm = self.layer.txn |
232 | - output = StringIO() |
233 | + output = six.StringIO() |
234 | logger = logging.getLogger() |
235 | logger.setLevel(logging.INFO) |
236 | logger.addHandler(logging.StreamHandler(output)) |
237 | diff --git a/lib/lp/scripts/tests/test_garbo.py b/lib/lp/scripts/tests/test_garbo.py |
238 | index ad62894..2662c01 100644 |
239 | --- a/lib/lp/scripts/tests/test_garbo.py |
240 | +++ b/lib/lp/scripts/tests/test_garbo.py |
241 | @@ -14,10 +14,10 @@ from datetime import ( |
242 | ) |
243 | import hashlib |
244 | import logging |
245 | -from StringIO import StringIO |
246 | import time |
247 | |
248 | from pytz import UTC |
249 | +import six |
250 | from storm.exceptions import LostObjectError |
251 | from storm.expr import ( |
252 | In, |
253 | @@ -431,7 +431,7 @@ class TestGarbo(FakeAdapterMixin, TestCaseWithFactory): |
254 | self.runFrequently() |
255 | |
256 | # Capture garbo log output to tests can examine it. |
257 | - self.log_buffer = StringIO() |
258 | + self.log_buffer = six.StringIO() |
259 | handler = logging.StreamHandler(self.log_buffer) |
260 | self.log.addHandler(handler) |
261 | self.addDetail( |
262 | diff --git a/lib/lp/scripts/utilities/warninghandler.py b/lib/lp/scripts/utilities/warninghandler.py |
263 | index cb0c4ff..fb6373b 100644 |
264 | --- a/lib/lp/scripts/utilities/warninghandler.py |
265 | +++ b/lib/lp/scripts/utilities/warninghandler.py |
266 | @@ -8,7 +8,6 @@ from __future__ import print_function |
267 | __metaclass__ = type |
268 | |
269 | import inspect |
270 | -import StringIO |
271 | import sys |
272 | import warnings |
273 | |
274 | @@ -163,7 +162,7 @@ def launchpad_showwarning(message, category, filename, lineno, file=None, |
275 | line=None): |
276 | if file is None: |
277 | file = sys.stderr |
278 | - stream = StringIO.StringIO() |
279 | + stream = six.StringIO() |
280 | old_show_warning(message, category, filename, lineno, stream, line=line) |
281 | warning_message = stream.getvalue() |
282 | important_info = find_important_info() |
283 | diff --git a/lib/lp/services/job/tests/test_celeryjob.py b/lib/lp/services/job/tests/test_celeryjob.py |
284 | index 85f6252..e96c5b4 100644 |
285 | --- a/lib/lp/services/job/tests/test_celeryjob.py |
286 | +++ b/lib/lp/services/job/tests/test_celeryjob.py |
287 | @@ -1,11 +1,11 @@ |
288 | # Copyright 2012-2020 Canonical Ltd. This software is licensed under the |
289 | # GNU Affero General Public License version 3 (see the file LICENSE). |
290 | |
291 | -from cStringIO import StringIO |
292 | import sys |
293 | from time import sleep |
294 | |
295 | from lazr.jobrunner.bin.clear_queues import clear_queues |
296 | +import six |
297 | from testtools.content import Content |
298 | from testtools.content_type import UTF8_TEXT |
299 | |
300 | @@ -150,8 +150,8 @@ class TestRunMissingJobs(TestCaseWithFactory): |
301 | try: |
302 | real_stdout = sys.stdout |
303 | real_stderr = sys.stderr |
304 | - sys.stdout = fake_stdout = StringIO() |
305 | - sys.stderr = fake_stderr = StringIO() |
306 | + sys.stdout = fake_stdout = six.StringIO() |
307 | + sys.stderr = fake_stderr = six.StringIO() |
308 | clear_queues( |
309 | ['script_name', '-c', 'lp.services.job.celeryconfig', |
310 | result_queue_name]) |
311 | diff --git a/lib/lp/services/log/logger.py b/lib/lp/services/log/logger.py |
312 | index cd83d35..4451a04 100644 |
313 | --- a/lib/lp/services/log/logger.py |
314 | +++ b/lib/lp/services/log/logger.py |
315 | @@ -15,10 +15,11 @@ __all__ = [ |
316 | ] |
317 | |
318 | import logging |
319 | -from StringIO import StringIO |
320 | import sys |
321 | import traceback |
322 | |
323 | +import six |
324 | + |
325 | from lp.services.log import loglevels |
326 | |
327 | |
328 | @@ -198,7 +199,7 @@ class BufferLogger(FakeLogger): |
329 | # service. |
330 | |
331 | def __init__(self): |
332 | - super(BufferLogger, self).__init__(StringIO()) |
333 | + super(BufferLogger, self).__init__(six.StringIO()) |
334 | |
335 | def getLogBuffer(self): |
336 | """Return the existing log messages.""" |
337 | @@ -206,7 +207,7 @@ class BufferLogger(FakeLogger): |
338 | |
339 | def clearLogBuffer(self): |
340 | """Clear out the existing log messages.""" |
341 | - self.output_file = StringIO() |
342 | + self.output_file = six.StringIO() |
343 | |
344 | def getLogBufferAndClear(self): |
345 | """Return the existing log messages and clear the buffer.""" |
346 | diff --git a/lib/lp/services/mail/tests/test_dkim.py b/lib/lp/services/mail/tests/test_dkim.py |
347 | index a8b2383..26d3d33 100644 |
348 | --- a/lib/lp/services/mail/tests/test_dkim.py |
349 | +++ b/lib/lp/services/mail/tests/test_dkim.py |
350 | @@ -6,10 +6,10 @@ |
351 | __metaclass__ = type |
352 | |
353 | import logging |
354 | -from StringIO import StringIO |
355 | |
356 | import dkim |
357 | import dkim.dnsplug |
358 | +import six |
359 | |
360 | from lp.services.features.testing import FeatureFixture |
361 | from lp.services.identity.interfaces.account import AccountStatus |
362 | @@ -69,7 +69,7 @@ class TestDKIM(TestCaseWithFactory): |
363 | def setUp(self): |
364 | # Login with admin roles as we aren't testing access here. |
365 | TestCaseWithFactory.setUp(self, 'admin@canonical.com') |
366 | - self._log_output = StringIO() |
367 | + self._log_output = six.StringIO() |
368 | handler = logging.StreamHandler(self._log_output) |
369 | self.logger = logging.getLogger('mail-authenticate-dkim') |
370 | self.logger.addHandler(handler) |
371 | diff --git a/lib/lp/services/testing/tests/test_parallel.py b/lib/lp/services/testing/tests/test_parallel.py |
372 | index 2dec513..f8afd34 100644 |
373 | --- a/lib/lp/services/testing/tests/test_parallel.py |
374 | +++ b/lib/lp/services/testing/tests/test_parallel.py |
375 | @@ -5,14 +5,15 @@ |
376 | |
377 | __metaclass__ = type |
378 | |
379 | -from StringIO import StringIO |
380 | import subprocess |
381 | import tempfile |
382 | +from textwrap import dedent |
383 | |
384 | from fixtures import ( |
385 | PopenFixture, |
386 | TestWithFixtures, |
387 | ) |
388 | +import six |
389 | from testtools import ( |
390 | TestCase, |
391 | TestResult, |
392 | @@ -40,7 +41,7 @@ class TestListTestCase(TestCase, TestWithFixtures): |
393 | with open(load_list, 'rt') as testlist: |
394 | contents = testlist.readlines() |
395 | self.assertEqual(['foo\n', 'bar\n'], contents) |
396 | - return {'stdout': StringIO(''), 'stdin': StringIO()} |
397 | + return {'stdout': six.StringIO(), 'stdin': six.StringIO()} |
398 | popen = self.useFixture(PopenFixture(check_list_file)) |
399 | case = ListTestCase(['foo', 'bar'], ['bin/test']) |
400 | self.assertEqual([], popen.procs) |
401 | @@ -102,12 +103,15 @@ class TestUtilities(TestCase, TestWithFixtures): |
402 | self.assertEqual( |
403 | ['bin/test', '-vt', 'filter', '--list-tests', '--subunit'], |
404 | args['args']) |
405 | - return {'stdin': StringIO(), 'stdout': StringIO("""\ |
406 | -test: quux |
407 | -successful: quux |
408 | -test: glom |
409 | -successful: glom |
410 | -""")} |
411 | + return { |
412 | + 'stdin': six.StringIO(), |
413 | + 'stdout': six.StringIO(six.ensure_str(dedent("""\ |
414 | + test: quux |
415 | + successful: quux |
416 | + test: glom |
417 | + successful: glom |
418 | + """))), |
419 | + } |
420 | self.useFixture(PopenFixture(inject_testlist)) |
421 | self.assertEqual( |
422 | ['quux', 'glom'], |
423 | diff --git a/lib/lp/services/tests/test_looptuner.py b/lib/lp/services/tests/test_looptuner.py |
424 | index aa99afb..2d4c05c 100644 |
425 | --- a/lib/lp/services/tests/test_looptuner.py |
426 | +++ b/lib/lp/services/tests/test_looptuner.py |
427 | @@ -8,8 +8,7 @@ These are the edge test cases that don't belong in the doctest. |
428 | |
429 | __metaclass__ = type |
430 | |
431 | -from cStringIO import StringIO |
432 | - |
433 | +import six |
434 | from zope.interface import implementer |
435 | |
436 | from lp.services.log.logger import FakeLogger |
437 | @@ -64,7 +63,7 @@ class TestSomething(TestCase): |
438 | |
439 | Exception from cleanup raised. |
440 | """ |
441 | - log_file = StringIO() |
442 | + log_file = six.StringIO() |
443 | loop = FailingLoop(fail_cleanup=True) |
444 | tuner = LoopTuner(loop, 5, log=FakeLogger(log_file)) |
445 | self.assertRaises(CleanupException, tuner.run) |
446 | @@ -76,7 +75,7 @@ class TestSomething(TestCase): |
447 | Exception from cleanup is logged. |
448 | Original exception from main task is raised. |
449 | """ |
450 | - log_file = StringIO() |
451 | + log_file = six.StringIO() |
452 | loop = FailingLoop(fail_main=True, fail_cleanup=True) |
453 | tuner = LoopTuner(loop, 5, log=FakeLogger(log_file)) |
454 | self.assertRaises(MainException, tuner.run) |
455 | diff --git a/lib/lp/services/twistedsupport/__init__.py b/lib/lp/services/twistedsupport/__init__.py |
456 | index 778a3eb..16b9953 100644 |
457 | --- a/lib/lp/services/twistedsupport/__init__.py |
458 | +++ b/lib/lp/services/twistedsupport/__init__.py |
459 | @@ -20,9 +20,9 @@ from signal import ( |
460 | SIGCHLD, |
461 | signal, |
462 | ) |
463 | -import StringIO |
464 | import sys |
465 | |
466 | +import six |
467 | from twisted.internet import ( |
468 | defer, |
469 | reactor as default_reactor, |
470 | @@ -63,7 +63,7 @@ def suppress_stderr(function): |
471 | @functools.wraps(function) |
472 | def wrapper(*arguments, **keyword_arguments): |
473 | saved_stderr = sys.stderr |
474 | - ignored_stream = StringIO.StringIO() |
475 | + ignored_stream = six.StringIO() |
476 | sys.stderr = ignored_stream |
477 | d = defer.maybeDeferred(function, *arguments, **keyword_arguments) |
478 | return d.addBoth(set_stderr, saved_stderr) |
479 | diff --git a/lib/lp/services/utils.py b/lib/lp/services/utils.py |
480 | index ea661c5..56e5468 100644 |
481 | --- a/lib/lp/services/utils.py |
482 | +++ b/lib/lp/services/utils.py |
483 | @@ -41,7 +41,6 @@ from itertools import ( |
484 | import os |
485 | import re |
486 | import string |
487 | -from StringIO import StringIO |
488 | import sys |
489 | from textwrap import dedent |
490 | from types import FunctionType |
491 | @@ -266,8 +265,8 @@ class CapturedOutput(Fixture): |
492 | |
493 | def __init__(self): |
494 | super(CapturedOutput, self).__init__() |
495 | - self.stdout = StringIO() |
496 | - self.stderr = StringIO() |
497 | + self.stdout = six.StringIO() |
498 | + self.stderr = six.StringIO() |
499 | |
500 | def _setUp(self): |
501 | self.useFixture(MonkeyPatch('sys.stdout', self.stdout)) |
502 | diff --git a/lib/lp/services/webapp/opstats.py b/lib/lp/services/webapp/opstats.py |
503 | index ce5f8c9..6b626ce 100644 |
504 | --- a/lib/lp/services/webapp/opstats.py |
505 | +++ b/lib/lp/services/webapp/opstats.py |
506 | @@ -3,12 +3,15 @@ |
507 | |
508 | """XML-RPC interface for extracting real time stats from the appserver.""" |
509 | |
510 | +from __future__ import absolute_import, print_function |
511 | + |
512 | __metaclass__ = type |
513 | __all__ = ["OpStats"] |
514 | |
515 | -from cStringIO import StringIO |
516 | from time import time |
517 | |
518 | +import six |
519 | + |
520 | from lp.services.webapp import LaunchpadXMLRPCView |
521 | |
522 | |
523 | @@ -65,13 +68,13 @@ class OpStats(LaunchpadXMLRPCView): |
524 | |
525 | def __call__(self): |
526 | now = time() |
527 | - out = StringIO() |
528 | + out = six.StringIO() |
529 | for stat_key in sorted(OpStats.stats.keys()): |
530 | - print >> out, '%s:%d@%d' % ( |
531 | + print('%s:%d@%d' % ( |
532 | # Make keys more cricket friendly |
533 | stat_key.replace(' ', '_').replace('-', ''), |
534 | OpStats.stats[stat_key], now |
535 | - ) |
536 | + ), file=out) |
537 | self.request.response.setHeader( |
538 | 'Content-Type', 'text/plain; charset=US-ASCII' |
539 | ) |
540 | diff --git a/lib/lp/services/webapp/tests/test_statementtracer.py b/lib/lp/services/webapp/tests/test_statementtracer.py |
541 | index 30964a4..bb2c6d0 100644 |
542 | --- a/lib/lp/services/webapp/tests/test_statementtracer.py |
543 | +++ b/lib/lp/services/webapp/tests/test_statementtracer.py |
544 | @@ -6,10 +6,10 @@ |
545 | __metaclass__ = type |
546 | |
547 | from contextlib import contextmanager |
548 | -import StringIO |
549 | import sys |
550 | |
551 | from lazr.restful.utils import get_current_browser_request |
552 | +import six |
553 | |
554 | from lp.services.osutils import override_environ |
555 | from lp.services.timeline.requesttimeline import get_request_timeline |
556 | @@ -25,7 +25,7 @@ from lp.testing.layers import DatabaseFunctionalLayer |
557 | |
558 | @contextmanager |
559 | def stdout(): |
560 | - file = StringIO.StringIO() |
561 | + file = six.StringIO() |
562 | original = sys.stdout |
563 | sys.stdout = file |
564 | try: |
565 | @@ -36,7 +36,7 @@ def stdout(): |
566 | |
567 | @contextmanager |
568 | def stderr(): |
569 | - file = StringIO.StringIO() |
570 | + file = six.StringIO() |
571 | original = sys.stderr |
572 | sys.stderr = file |
573 | try: |
574 | diff --git a/lib/lp/soyuz/scripts/ppareport.py b/lib/lp/soyuz/scripts/ppareport.py |
575 | index 9605c93..94914fe 100644 |
576 | --- a/lib/lp/soyuz/scripts/ppareport.py |
577 | +++ b/lib/lp/soyuz/scripts/ppareport.py |
578 | @@ -15,6 +15,7 @@ import operator |
579 | import os |
580 | import sys |
581 | |
582 | +import six |
583 | from storm.locals import Join |
584 | from storm.store import Store |
585 | from zope.component import getUtility |
586 | @@ -174,7 +175,7 @@ class PPAReportScript(LaunchpadScript): |
587 | if size <= (threshold * limit): |
588 | continue |
589 | line = "%s | %d | %d\n" % (canonical_url(ppa), limit, size) |
590 | - self.output.write(line.encode('utf-8')) |
591 | + self.output.write(six.ensure_str(line)) |
592 | self.output.write('\n') |
593 | |
594 | def reportUserEmails(self): |
595 | @@ -187,7 +188,7 @@ class PPAReportScript(LaunchpadScript): |
596 | for user in sorted_people_to_email: |
597 | line = u"%s | %s | %s\n" % ( |
598 | user.name, user.displayname, user.preferredemail.email) |
599 | - self.output.write(line.encode('utf-8')) |
600 | + self.output.write(six.ensure_str(line)) |
601 | self.output.write('\n') |
602 | |
603 | @cachedproperty |
604 | diff --git a/lib/lp/soyuz/scripts/tests/test_ppareport.py b/lib/lp/soyuz/scripts/tests/test_ppareport.py |
605 | index b022b32..58e972b 100644 |
606 | --- a/lib/lp/soyuz/scripts/tests/test_ppareport.py |
607 | +++ b/lib/lp/soyuz/scripts/tests/test_ppareport.py |
608 | @@ -7,10 +7,11 @@ __metaclass__ = type |
609 | |
610 | import os |
611 | import shutil |
612 | -from StringIO import StringIO |
613 | import tempfile |
614 | import unittest |
615 | |
616 | +import six |
617 | + |
618 | from lp.services.config import config |
619 | from lp.services.log.logger import BufferLogger |
620 | from lp.services.scripts.base import LaunchpadScriptFailure |
621 | @@ -71,7 +72,7 @@ class TestPPAReport(unittest.TestCase): |
622 | if output is None: |
623 | |
624 | def set_test_output(): |
625 | - reporter.output = StringIO() |
626 | + reporter.output = six.StringIO() |
627 | reporter.setOutput = set_test_output |
628 | |
629 | reporter.closeOutput = FakeMethod() |
630 | diff --git a/lib/lp/testing/__init__.py b/lib/lp/testing/__init__.py |
631 | index 81e86f1..d68c1f1 100644 |
632 | --- a/lib/lp/testing/__init__.py |
633 | +++ b/lib/lp/testing/__init__.py |
634 | @@ -57,7 +57,6 @@ __all__ = [ |
635 | ] |
636 | |
637 | from contextlib import contextmanager |
638 | -from cStringIO import StringIO |
639 | from datetime import ( |
640 | datetime, |
641 | timedelta, |
642 | @@ -369,7 +368,7 @@ class StormStatementRecorder: |
643 | stop_sql_logging() |
644 | |
645 | def __str__(self): |
646 | - out = StringIO() |
647 | + out = six.StringIO() |
648 | print_queries(self.query_data, file=out) |
649 | return out.getvalue() |
650 | |
651 | @@ -682,7 +681,7 @@ class TestCase(testtools.TestCase, fixtures.TestWithFixtures): |
652 | @contextmanager |
653 | def expectedLog(self, regex): |
654 | """Expect a log to be written that matches the regex.""" |
655 | - output = StringIO() |
656 | + output = six.StringIO() |
657 | handler = logging.StreamHandler(output) |
658 | logger = logging.getLogger() |
659 | logger.addHandler(handler) |
660 | @@ -1580,7 +1579,7 @@ def nonblocking_readline(instream, timeout): |
661 | Files must provide a valid fileno() method. This is a test helper |
662 | as it is inefficient and unlikely useful for production code. |
663 | """ |
664 | - result = StringIO() |
665 | + result = six.StringIO() |
666 | start = now = time.time() |
667 | deadline = start + timeout |
668 | while (now < deadline and not result.getvalue().endswith('\n')): |
669 | diff --git a/lib/lp/translations/scripts/po_export_queue.py b/lib/lp/translations/scripts/po_export_queue.py |
670 | index f8bcf9b..b7281a9 100644 |
671 | --- a/lib/lp/translations/scripts/po_export_queue.py |
672 | +++ b/lib/lp/translations/scripts/po_export_queue.py |
673 | @@ -9,10 +9,10 @@ __all__ = [ |
674 | ] |
675 | |
676 | import os |
677 | -from StringIO import StringIO |
678 | import traceback |
679 | |
680 | import psycopg2 |
681 | +import six |
682 | from zope.component import ( |
683 | getAdapter, |
684 | getUtility, |
685 | @@ -346,7 +346,7 @@ class ExportResult: |
686 | def addFailure(self): |
687 | """Store an exception that broke the export.""" |
688 | # Get the trace back that produced this failure. |
689 | - exception = StringIO() |
690 | + exception = six.StringIO() |
691 | traceback.print_exc(file=exception) |
692 | exception.seek(0) |
693 | # And store it. |