Merge ~cjwatson/launchpad:py3-native-string-streams into launchpad: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)
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
1diff --git a/lib/devscripts/tests/test_sourcecode.py b/lib/devscripts/tests/test_sourcecode.py
2index 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.
30diff --git a/lib/lp/archivepublisher/model/ftparchive.py b/lib/lp/archivepublisher/model/ftparchive.py
31index 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,
60diff --git a/lib/lp/bugs/scripts/tests/test_bugnotification.py b/lib/lp/bugs/scripts/tests/test_bugnotification.py
61index 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))
85diff --git a/lib/lp/registry/scripts/distributionmirror_prober.py b/lib/lp/registry/scripts/distributionmirror_prober.py
86index 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)
114diff --git a/lib/lp/registry/tests/test_distributionmirror_prober.py b/lib/lp/registry/tests/test_distributionmirror_prober.py
115index 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()
212diff --git a/lib/lp/registry/tests/test_prf_finder.py b/lib/lp/registry/tests/test_prf_finder.py
213index 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))
237diff --git a/lib/lp/scripts/tests/test_garbo.py b/lib/lp/scripts/tests/test_garbo.py
238index 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(
262diff --git a/lib/lp/scripts/utilities/warninghandler.py b/lib/lp/scripts/utilities/warninghandler.py
263index 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()
283diff --git a/lib/lp/services/job/tests/test_celeryjob.py b/lib/lp/services/job/tests/test_celeryjob.py
284index 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])
311diff --git a/lib/lp/services/log/logger.py b/lib/lp/services/log/logger.py
312index 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."""
346diff --git a/lib/lp/services/mail/tests/test_dkim.py b/lib/lp/services/mail/tests/test_dkim.py
347index 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)
371diff --git a/lib/lp/services/testing/tests/test_parallel.py b/lib/lp/services/testing/tests/test_parallel.py
372index 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'],
423diff --git a/lib/lp/services/tests/test_looptuner.py b/lib/lp/services/tests/test_looptuner.py
424index 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)
455diff --git a/lib/lp/services/twistedsupport/__init__.py b/lib/lp/services/twistedsupport/__init__.py
456index 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)
479diff --git a/lib/lp/services/utils.py b/lib/lp/services/utils.py
480index 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))
502diff --git a/lib/lp/services/webapp/opstats.py b/lib/lp/services/webapp/opstats.py
503index 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 )
540diff --git a/lib/lp/services/webapp/tests/test_statementtracer.py b/lib/lp/services/webapp/tests/test_statementtracer.py
541index 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:
574diff --git a/lib/lp/soyuz/scripts/ppareport.py b/lib/lp/soyuz/scripts/ppareport.py
575index 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
604diff --git a/lib/lp/soyuz/scripts/tests/test_ppareport.py b/lib/lp/soyuz/scripts/tests/test_ppareport.py
605index 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()
630diff --git a/lib/lp/testing/__init__.py b/lib/lp/testing/__init__.py
631index 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')):
669diff --git a/lib/lp/translations/scripts/po_export_queue.py b/lib/lp/translations/scripts/po_export_queue.py
670index 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.

Subscribers

People subscribed via source and target branches

to status/vote changes: