launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #25058
[Merge] ~cjwatson/launchpad:py3-native-string-streams into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:py3-native-string-streams into launchpad:master.
Commit message:
Port native-string streams to six.StringIO
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/387726
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.
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:py3-native-string-streams into launchpad:master.
diff --git a/lib/devscripts/tests/test_sourcecode.py b/lib/devscripts/tests/test_sourcecode.py
index cc8f375..6b538c7 100644
--- a/lib/devscripts/tests/test_sourcecode.py
+++ b/lib/devscripts/tests/test_sourcecode.py
@@ -9,7 +9,6 @@ __metaclass__ = type
import os
import shutil
-from StringIO import StringIO
import tempfile
import unittest
@@ -21,6 +20,7 @@ except ImportError:
from bzrlib.bzrdir import BzrDir
from bzrlib.tests import TestCase
from bzrlib.transport import get_transport
+import six
from devscripts import get_launchpad_root
from devscripts.sourcecode import (
@@ -35,7 +35,7 @@ class TestParseConfigFile(unittest.TestCase):
"""Tests for the config file parser."""
def makeFile(self, contents):
- return StringIO(contents)
+ return six.StringIO(contents)
def test_empty(self):
# Parsing an empty config file returns an empty sequence.
diff --git a/lib/lp/archivepublisher/model/ftparchive.py b/lib/lp/archivepublisher/model/ftparchive.py
index 6fe3c3c..c516068 100644
--- a/lib/lp/archivepublisher/model/ftparchive.py
+++ b/lib/lp/archivepublisher/model/ftparchive.py
@@ -4,7 +4,6 @@
from collections import defaultdict
import os
import re
-from StringIO import StringIO
import time
import scandir
@@ -754,7 +753,7 @@ class FTPArchiveHandler:
explicitly marked as dirty. dirty_pockets must be a nested
dictionary of booleans, keyed by distroseries.name then pocket.
"""
- apt_config = StringIO()
+ apt_config = six.StringIO()
apt_config.write(CONFIG_HEADER % (self._config.archiveroot,
self._config.overrideroot,
self._config.cacheroot,
@@ -875,7 +874,7 @@ class FTPArchiveHandler:
except OSError:
pass
- apt_config = StringIO()
+ apt_config = six.StringIO()
apt_config.write(CONFIG_HEADER % (self._config.archiveroot,
self._config.overrideroot,
self._config.cacheroot,
diff --git a/lib/lp/bugs/scripts/tests/test_bugnotification.py b/lib/lp/bugs/scripts/tests/test_bugnotification.py
index 99b59c6..38d11d9 100644
--- a/lib/lp/bugs/scripts/tests/test_bugnotification.py
+++ b/lib/lp/bugs/scripts/tests/test_bugnotification.py
@@ -13,10 +13,10 @@ from datetime import (
import logging
import re
from smtplib import SMTPException
-import StringIO
import unittest
import pytz
+import six
from testtools.matchers import (
MatchesRegex,
Not,
@@ -402,7 +402,7 @@ class TestGetEmailNotifications(TestCase):
# in place.
# Set up logging so we can later assert that no exceptions are logged.
- log_output = StringIO.StringIO()
+ log_output = six.StringIO()
logger = logging.getLogger()
log_handler = logging.StreamHandler(log_output)
logger.addHandler(logging.StreamHandler(log_output))
diff --git a/lib/lp/registry/scripts/distributionmirror_prober.py b/lib/lp/registry/scripts/distributionmirror_prober.py
index a6350ca..b1d2df0 100644
--- a/lib/lp/registry/scripts/distributionmirror_prober.py
+++ b/lib/lp/registry/scripts/distributionmirror_prober.py
@@ -10,7 +10,6 @@ from datetime import datetime
import itertools
import logging
import os.path
-from StringIO import StringIO
import OpenSSL
from OpenSSL.SSL import (
@@ -18,6 +17,7 @@ from OpenSSL.SSL import (
TLSv1_2_METHOD,
)
import requests
+import six
from six.moves import http_client
from six.moves.urllib.parse import (
unquote,
@@ -1037,7 +1037,7 @@ class DistroMirrorProber:
continue
probed_mirrors.append(mirror)
- logfile = StringIO()
+ logfile = six.StringIO()
logfiles[mirror_id] = logfile
probe_function(mirror, logfile, unchecked_keys, self.logger,
max_parallel, max_parallel_per_host)
diff --git a/lib/lp/registry/tests/test_distributionmirror_prober.py b/lib/lp/registry/tests/test_distributionmirror_prober.py
index c674ac0..38bf7dd 100644
--- a/lib/lp/registry/tests/test_distributionmirror_prober.py
+++ b/lib/lp/registry/tests/test_distributionmirror_prober.py
@@ -9,11 +9,11 @@ __metaclass__ = type
from datetime import datetime
import logging
import os
-from StringIO import StringIO
from fixtures import MockPatchObject
from lazr.uri import URI
import responses
+import six
from six.moves import http_client
from sqlobject import SQLObjectNotFound
from testtools.matchers import (
@@ -859,7 +859,7 @@ class TestMirrorCDImageProberCallbacks(TestCaseWithFactory):
mirror = removeSecurityProxy(
self.factory.makeMirror(distroseries.distribution))
callbacks = MirrorCDImageProberCallbacks(
- mirror, distroseries, 'ubuntu', StringIO())
+ mirror, distroseries, 'ubuntu', six.StringIO())
return callbacks
def getLogger(self):
@@ -961,7 +961,7 @@ class TestArchiveMirrorProberCallbacks(TestCaseWithFactory):
component = self.factory.makeComponent()
callbacks = ArchiveMirrorProberCallbacks(
mirror, distroseries, PackagePublishingPocket.RELEASE,
- component, 'foo', StringIO())
+ component, 'foo', six.StringIO())
return callbacks
def test_failure_propagation(self):
@@ -1050,7 +1050,7 @@ class TestProbeFunctionSemaphores(TestCase):
# Note that calling this function won't actually probe any mirrors; we
# need to call reactor.run() to actually start the probing.
with default_timeout(15.0):
- probe_cdimage_mirror(mirror, StringIO(), [], logging, 100, 2)
+ probe_cdimage_mirror(mirror, six.StringIO(), [], logging, 100, 2)
self.assertEqual(0, len(mirror.cdimage_series))
def test_archive_mirror_probe_function(self):
@@ -1086,7 +1086,7 @@ class TestProbeFunctionSemaphores(TestCase):
mirror2_host = URI(mirror2.base_url).host
mirror3_host = URI(mirror3.base_url).host
- probe_function(mirror1, StringIO(), [], logging, 100, 2)
+ probe_function(mirror1, six.StringIO(), [], logging, 100, 2)
# Since we have a single mirror to probe we need to have a single
# DeferredSemaphore with a limit of max_per_host_requests, to ensure we
# don't issue too many simultaneous connections on that host.
@@ -1097,7 +1097,7 @@ class TestProbeFunctionSemaphores(TestCase):
# overall number of requests.
self.assertEqual(multi_lock.overall_lock.limit, max_requests)
- probe_function(mirror2, StringIO(), [], logging, 100, 2)
+ probe_function(mirror2, six.StringIO(), [], logging, 100, 2)
# Now we have two mirrors to probe, but they have the same hostname,
# so we'll still have a single semaphore in host_semaphores.
self.assertEqual(mirror2_host, mirror1_host)
@@ -1105,7 +1105,7 @@ class TestProbeFunctionSemaphores(TestCase):
multi_lock = request_manager.host_locks[mirror2_host]
self.assertEqual(multi_lock.host_lock.limit, max_per_host_requests)
- probe_function(mirror3, StringIO(), [], logging, 100, 2)
+ probe_function(mirror3, six.StringIO(), [], logging, 100, 2)
# This third mirror is on a separate host, so we'll have a second
# semaphore added to host_semaphores.
self.assertTrue(mirror3_host != mirror1_host)
@@ -1117,7 +1117,7 @@ class TestProbeFunctionSemaphores(TestCase):
# proxy, we'll use the mirror's host as the key to find the semaphore
# that should be used
self.pushConfig('launchpad', http_proxy='http://squid.internal:3128/')
- probe_function(mirror3, StringIO(), [], logging, 100, 2)
+ probe_function(mirror3, six.StringIO(), [], logging, 100, 2)
self.assertEqual(len(request_manager.host_locks), 2)
@@ -1150,7 +1150,7 @@ class TestLoggingMixin(TestCase):
def test_logMessage_output(self):
logger = LoggingMixin()
- logger.log_file = StringIO()
+ logger.log_file = six.StringIO()
logger._getTime = self._fake_gettime
logger.logMessage("Ubuntu Warty Released")
logger.log_file.seek(0)
@@ -1161,7 +1161,7 @@ class TestLoggingMixin(TestCase):
def test_logMessage_integration(self):
logger = LoggingMixin()
- logger.log_file = StringIO()
+ logger.log_file = six.StringIO()
logger.logMessage("Probing...")
logger.log_file.seek(0)
message = logger.log_file.read()
diff --git a/lib/lp/registry/tests/test_prf_finder.py b/lib/lp/registry/tests/test_prf_finder.py
index 32a149a..f37cb1a 100644
--- a/lib/lp/registry/tests/test_prf_finder.py
+++ b/lib/lp/registry/tests/test_prf_finder.py
@@ -4,10 +4,10 @@
import logging
import os
import shutil
-from StringIO import StringIO
import tempfile
import responses
+import six
from testtools import ExpectedException
import transaction
from zope.component import getUtility
@@ -389,7 +389,7 @@ class HandleReleaseTestCase(TestCase):
# Test that handleRelease() handles the case where a version can't be
# parsed from the url given.
ztm = self.layer.txn
- output = StringIO()
+ output = six.StringIO()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.addHandler(logging.StreamHandler(output))
diff --git a/lib/lp/scripts/tests/test_garbo.py b/lib/lp/scripts/tests/test_garbo.py
index ad62894..2662c01 100644
--- a/lib/lp/scripts/tests/test_garbo.py
+++ b/lib/lp/scripts/tests/test_garbo.py
@@ -14,10 +14,10 @@ from datetime import (
)
import hashlib
import logging
-from StringIO import StringIO
import time
from pytz import UTC
+import six
from storm.exceptions import LostObjectError
from storm.expr import (
In,
@@ -431,7 +431,7 @@ class TestGarbo(FakeAdapterMixin, TestCaseWithFactory):
self.runFrequently()
# Capture garbo log output to tests can examine it.
- self.log_buffer = StringIO()
+ self.log_buffer = six.StringIO()
handler = logging.StreamHandler(self.log_buffer)
self.log.addHandler(handler)
self.addDetail(
diff --git a/lib/lp/scripts/utilities/warninghandler.py b/lib/lp/scripts/utilities/warninghandler.py
index cb0c4ff..fb6373b 100644
--- a/lib/lp/scripts/utilities/warninghandler.py
+++ b/lib/lp/scripts/utilities/warninghandler.py
@@ -8,7 +8,6 @@ from __future__ import print_function
__metaclass__ = type
import inspect
-import StringIO
import sys
import warnings
@@ -163,7 +162,7 @@ def launchpad_showwarning(message, category, filename, lineno, file=None,
line=None):
if file is None:
file = sys.stderr
- stream = StringIO.StringIO()
+ stream = six.StringIO()
old_show_warning(message, category, filename, lineno, stream, line=line)
warning_message = stream.getvalue()
important_info = find_important_info()
diff --git a/lib/lp/services/job/tests/test_celeryjob.py b/lib/lp/services/job/tests/test_celeryjob.py
index 85f6252..e96c5b4 100644
--- a/lib/lp/services/job/tests/test_celeryjob.py
+++ b/lib/lp/services/job/tests/test_celeryjob.py
@@ -1,11 +1,11 @@
# Copyright 2012-2020 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
-from cStringIO import StringIO
import sys
from time import sleep
from lazr.jobrunner.bin.clear_queues import clear_queues
+import six
from testtools.content import Content
from testtools.content_type import UTF8_TEXT
@@ -150,8 +150,8 @@ class TestRunMissingJobs(TestCaseWithFactory):
try:
real_stdout = sys.stdout
real_stderr = sys.stderr
- sys.stdout = fake_stdout = StringIO()
- sys.stderr = fake_stderr = StringIO()
+ sys.stdout = fake_stdout = six.StringIO()
+ sys.stderr = fake_stderr = six.StringIO()
clear_queues(
['script_name', '-c', 'lp.services.job.celeryconfig',
result_queue_name])
diff --git a/lib/lp/services/log/logger.py b/lib/lp/services/log/logger.py
index cd83d35..4451a04 100644
--- a/lib/lp/services/log/logger.py
+++ b/lib/lp/services/log/logger.py
@@ -15,10 +15,11 @@ __all__ = [
]
import logging
-from StringIO import StringIO
import sys
import traceback
+import six
+
from lp.services.log import loglevels
@@ -198,7 +199,7 @@ class BufferLogger(FakeLogger):
# service.
def __init__(self):
- super(BufferLogger, self).__init__(StringIO())
+ super(BufferLogger, self).__init__(six.StringIO())
def getLogBuffer(self):
"""Return the existing log messages."""
@@ -206,7 +207,7 @@ class BufferLogger(FakeLogger):
def clearLogBuffer(self):
"""Clear out the existing log messages."""
- self.output_file = StringIO()
+ self.output_file = six.StringIO()
def getLogBufferAndClear(self):
"""Return the existing log messages and clear the buffer."""
diff --git a/lib/lp/services/mail/tests/test_dkim.py b/lib/lp/services/mail/tests/test_dkim.py
index a8b2383..26d3d33 100644
--- a/lib/lp/services/mail/tests/test_dkim.py
+++ b/lib/lp/services/mail/tests/test_dkim.py
@@ -6,10 +6,10 @@
__metaclass__ = type
import logging
-from StringIO import StringIO
import dkim
import dkim.dnsplug
+import six
from lp.services.features.testing import FeatureFixture
from lp.services.identity.interfaces.account import AccountStatus
@@ -69,7 +69,7 @@ class TestDKIM(TestCaseWithFactory):
def setUp(self):
# Login with admin roles as we aren't testing access here.
TestCaseWithFactory.setUp(self, 'admin@xxxxxxxxxxxxx')
- self._log_output = StringIO()
+ self._log_output = six.StringIO()
handler = logging.StreamHandler(self._log_output)
self.logger = logging.getLogger('mail-authenticate-dkim')
self.logger.addHandler(handler)
diff --git a/lib/lp/services/testing/tests/test_parallel.py b/lib/lp/services/testing/tests/test_parallel.py
index 2dec513..f8afd34 100644
--- a/lib/lp/services/testing/tests/test_parallel.py
+++ b/lib/lp/services/testing/tests/test_parallel.py
@@ -5,14 +5,15 @@
__metaclass__ = type
-from StringIO import StringIO
import subprocess
import tempfile
+from textwrap import dedent
from fixtures import (
PopenFixture,
TestWithFixtures,
)
+import six
from testtools import (
TestCase,
TestResult,
@@ -40,7 +41,7 @@ class TestListTestCase(TestCase, TestWithFixtures):
with open(load_list, 'rt') as testlist:
contents = testlist.readlines()
self.assertEqual(['foo\n', 'bar\n'], contents)
- return {'stdout': StringIO(''), 'stdin': StringIO()}
+ return {'stdout': six.StringIO(), 'stdin': six.StringIO()}
popen = self.useFixture(PopenFixture(check_list_file))
case = ListTestCase(['foo', 'bar'], ['bin/test'])
self.assertEqual([], popen.procs)
@@ -102,12 +103,15 @@ class TestUtilities(TestCase, TestWithFixtures):
self.assertEqual(
['bin/test', '-vt', 'filter', '--list-tests', '--subunit'],
args['args'])
- return {'stdin': StringIO(), 'stdout': StringIO("""\
-test: quux
-successful: quux
-test: glom
-successful: glom
-""")}
+ return {
+ 'stdin': six.StringIO(),
+ 'stdout': six.StringIO(six.ensure_str(dedent("""\
+ test: quux
+ successful: quux
+ test: glom
+ successful: glom
+ """))),
+ }
self.useFixture(PopenFixture(inject_testlist))
self.assertEqual(
['quux', 'glom'],
diff --git a/lib/lp/services/tests/test_looptuner.py b/lib/lp/services/tests/test_looptuner.py
index aa99afb..2d4c05c 100644
--- a/lib/lp/services/tests/test_looptuner.py
+++ b/lib/lp/services/tests/test_looptuner.py
@@ -8,8 +8,7 @@ These are the edge test cases that don't belong in the doctest.
__metaclass__ = type
-from cStringIO import StringIO
-
+import six
from zope.interface import implementer
from lp.services.log.logger import FakeLogger
@@ -64,7 +63,7 @@ class TestSomething(TestCase):
Exception from cleanup raised.
"""
- log_file = StringIO()
+ log_file = six.StringIO()
loop = FailingLoop(fail_cleanup=True)
tuner = LoopTuner(loop, 5, log=FakeLogger(log_file))
self.assertRaises(CleanupException, tuner.run)
@@ -76,7 +75,7 @@ class TestSomething(TestCase):
Exception from cleanup is logged.
Original exception from main task is raised.
"""
- log_file = StringIO()
+ log_file = six.StringIO()
loop = FailingLoop(fail_main=True, fail_cleanup=True)
tuner = LoopTuner(loop, 5, log=FakeLogger(log_file))
self.assertRaises(MainException, tuner.run)
diff --git a/lib/lp/services/twistedsupport/__init__.py b/lib/lp/services/twistedsupport/__init__.py
index 778a3eb..16b9953 100644
--- a/lib/lp/services/twistedsupport/__init__.py
+++ b/lib/lp/services/twistedsupport/__init__.py
@@ -20,9 +20,9 @@ from signal import (
SIGCHLD,
signal,
)
-import StringIO
import sys
+import six
from twisted.internet import (
defer,
reactor as default_reactor,
@@ -63,7 +63,7 @@ def suppress_stderr(function):
@functools.wraps(function)
def wrapper(*arguments, **keyword_arguments):
saved_stderr = sys.stderr
- ignored_stream = StringIO.StringIO()
+ ignored_stream = six.StringIO()
sys.stderr = ignored_stream
d = defer.maybeDeferred(function, *arguments, **keyword_arguments)
return d.addBoth(set_stderr, saved_stderr)
diff --git a/lib/lp/services/utils.py b/lib/lp/services/utils.py
index ea661c5..56e5468 100644
--- a/lib/lp/services/utils.py
+++ b/lib/lp/services/utils.py
@@ -41,7 +41,6 @@ from itertools import (
import os
import re
import string
-from StringIO import StringIO
import sys
from textwrap import dedent
from types import FunctionType
@@ -266,8 +265,8 @@ class CapturedOutput(Fixture):
def __init__(self):
super(CapturedOutput, self).__init__()
- self.stdout = StringIO()
- self.stderr = StringIO()
+ self.stdout = six.StringIO()
+ self.stderr = six.StringIO()
def _setUp(self):
self.useFixture(MonkeyPatch('sys.stdout', self.stdout))
diff --git a/lib/lp/services/webapp/opstats.py b/lib/lp/services/webapp/opstats.py
index ce5f8c9..6b626ce 100644
--- a/lib/lp/services/webapp/opstats.py
+++ b/lib/lp/services/webapp/opstats.py
@@ -3,12 +3,15 @@
"""XML-RPC interface for extracting real time stats from the appserver."""
+from __future__ import absolute_import, print_function
+
__metaclass__ = type
__all__ = ["OpStats"]
-from cStringIO import StringIO
from time import time
+import six
+
from lp.services.webapp import LaunchpadXMLRPCView
@@ -65,13 +68,13 @@ class OpStats(LaunchpadXMLRPCView):
def __call__(self):
now = time()
- out = StringIO()
+ out = six.StringIO()
for stat_key in sorted(OpStats.stats.keys()):
- print >> out, '%s:%d@%d' % (
+ print('%s:%d@%d' % (
# Make keys more cricket friendly
stat_key.replace(' ', '_').replace('-', ''),
OpStats.stats[stat_key], now
- )
+ ), file=out)
self.request.response.setHeader(
'Content-Type', 'text/plain; charset=US-ASCII'
)
diff --git a/lib/lp/services/webapp/tests/test_statementtracer.py b/lib/lp/services/webapp/tests/test_statementtracer.py
index 30964a4..bb2c6d0 100644
--- a/lib/lp/services/webapp/tests/test_statementtracer.py
+++ b/lib/lp/services/webapp/tests/test_statementtracer.py
@@ -6,10 +6,10 @@
__metaclass__ = type
from contextlib import contextmanager
-import StringIO
import sys
from lazr.restful.utils import get_current_browser_request
+import six
from lp.services.osutils import override_environ
from lp.services.timeline.requesttimeline import get_request_timeline
@@ -25,7 +25,7 @@ from lp.testing.layers import DatabaseFunctionalLayer
@contextmanager
def stdout():
- file = StringIO.StringIO()
+ file = six.StringIO()
original = sys.stdout
sys.stdout = file
try:
@@ -36,7 +36,7 @@ def stdout():
@contextmanager
def stderr():
- file = StringIO.StringIO()
+ file = six.StringIO()
original = sys.stderr
sys.stderr = file
try:
diff --git a/lib/lp/soyuz/scripts/ppareport.py b/lib/lp/soyuz/scripts/ppareport.py
index 9605c93..94914fe 100644
--- a/lib/lp/soyuz/scripts/ppareport.py
+++ b/lib/lp/soyuz/scripts/ppareport.py
@@ -15,6 +15,7 @@ import operator
import os
import sys
+import six
from storm.locals import Join
from storm.store import Store
from zope.component import getUtility
@@ -174,7 +175,7 @@ class PPAReportScript(LaunchpadScript):
if size <= (threshold * limit):
continue
line = "%s | %d | %d\n" % (canonical_url(ppa), limit, size)
- self.output.write(line.encode('utf-8'))
+ self.output.write(six.ensure_str(line))
self.output.write('\n')
def reportUserEmails(self):
@@ -187,7 +188,7 @@ class PPAReportScript(LaunchpadScript):
for user in sorted_people_to_email:
line = u"%s | %s | %s\n" % (
user.name, user.displayname, user.preferredemail.email)
- self.output.write(line.encode('utf-8'))
+ self.output.write(six.ensure_str(line))
self.output.write('\n')
@cachedproperty
diff --git a/lib/lp/soyuz/scripts/tests/test_ppareport.py b/lib/lp/soyuz/scripts/tests/test_ppareport.py
index b022b32..58e972b 100644
--- a/lib/lp/soyuz/scripts/tests/test_ppareport.py
+++ b/lib/lp/soyuz/scripts/tests/test_ppareport.py
@@ -7,10 +7,11 @@ __metaclass__ = type
import os
import shutil
-from StringIO import StringIO
import tempfile
import unittest
+import six
+
from lp.services.config import config
from lp.services.log.logger import BufferLogger
from lp.services.scripts.base import LaunchpadScriptFailure
@@ -71,7 +72,7 @@ class TestPPAReport(unittest.TestCase):
if output is None:
def set_test_output():
- reporter.output = StringIO()
+ reporter.output = six.StringIO()
reporter.setOutput = set_test_output
reporter.closeOutput = FakeMethod()
diff --git a/lib/lp/testing/__init__.py b/lib/lp/testing/__init__.py
index 81e86f1..d68c1f1 100644
--- a/lib/lp/testing/__init__.py
+++ b/lib/lp/testing/__init__.py
@@ -57,7 +57,6 @@ __all__ = [
]
from contextlib import contextmanager
-from cStringIO import StringIO
from datetime import (
datetime,
timedelta,
@@ -369,7 +368,7 @@ class StormStatementRecorder:
stop_sql_logging()
def __str__(self):
- out = StringIO()
+ out = six.StringIO()
print_queries(self.query_data, file=out)
return out.getvalue()
@@ -682,7 +681,7 @@ class TestCase(testtools.TestCase, fixtures.TestWithFixtures):
@contextmanager
def expectedLog(self, regex):
"""Expect a log to be written that matches the regex."""
- output = StringIO()
+ output = six.StringIO()
handler = logging.StreamHandler(output)
logger = logging.getLogger()
logger.addHandler(handler)
@@ -1580,7 +1579,7 @@ def nonblocking_readline(instream, timeout):
Files must provide a valid fileno() method. This is a test helper
as it is inefficient and unlikely useful for production code.
"""
- result = StringIO()
+ result = six.StringIO()
start = now = time.time()
deadline = start + timeout
while (now < deadline and not result.getvalue().endswith('\n')):
diff --git a/lib/lp/translations/scripts/po_export_queue.py b/lib/lp/translations/scripts/po_export_queue.py
index f8bcf9b..b7281a9 100644
--- a/lib/lp/translations/scripts/po_export_queue.py
+++ b/lib/lp/translations/scripts/po_export_queue.py
@@ -9,10 +9,10 @@ __all__ = [
]
import os
-from StringIO import StringIO
import traceback
import psycopg2
+import six
from zope.component import (
getAdapter,
getUtility,
@@ -346,7 +346,7 @@ class ExportResult:
def addFailure(self):
"""Store an exception that broke the export."""
# Get the trace back that produced this failure.
- exception = StringIO()
+ exception = six.StringIO()
traceback.print_exc(file=exception)
exception.seek(0)
# And store it.