From d7dfab59ead97b35c6f6786784225f377783e376 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Sat, 5 May 2012 19:47:03 +0200 Subject: [PATCH] Replaced cStringIO.StringIO by io.BytesIO. Also replaced StringIO.StringIO by BytesIO in some other appropriate places. StringIO is not available in Python 3. --- django/contrib/gis/geos/tests/test_geos.py | 6 ++-- django/contrib/gis/shortcuts.py | 7 ++-- .../contrib/gis/tests/geoapp/test_sitemaps.py | 7 ++-- django/core/files/base.py | 7 ++-- django/core/files/uploadedfile.py | 9 ++--- django/core/files/uploadhandler.py | 9 ++--- django/core/handlers/wsgi.py | 7 ++-- django/core/mail/message.py | 9 ++--- django/core/management/base.py | 7 ++-- django/core/serializers/base.py | 6 ++-- django/core/serializers/json.py | 4 +-- django/core/serializers/pyyaml.py | 4 +-- django/forms/fields.py | 9 ++--- django/http/__init__.py | 11 +++--- django/test/client.py | 11 +++--- django/utils/feedgenerator.py | 4 +-- django/utils/text.py | 8 ++--- django/utils/translation/trans_real.py | 34 ++++++++----------- docs/howto/outputting-pdf.txt | 16 ++++----- tests/modeltests/invalid_models/tests.py | 4 +-- tests/modeltests/model_forms/tests.py | 13 ------- tests/regressiontests/file_storage/tests.py | 11 +++--- .../regressiontests/fixtures_regress/tests.py | 29 +++++++--------- .../i18n/commands/compilation.py | 11 +++--- .../m2m_through_regress/tests.py | 11 +++--- .../serializers_regress/tests.py | 7 ++-- 26 files changed, 94 insertions(+), 167 deletions(-) diff --git a/django/contrib/gis/geos/tests/test_geos.py b/django/contrib/gis/geos/tests/test_geos.py index a81925aec1..4a04d15ad9 100644 --- a/django/contrib/gis/geos/tests/test_geos.py +++ b/django/contrib/gis/geos/tests/test_geos.py @@ -203,12 +203,12 @@ class GEOSTest(unittest.TestCase, TestDataMixin): def test01k_fromfile(self): "Testing the fromfile() factory." - from StringIO import StringIO + from io import BytesIO ref_pnt = GEOSGeometry('POINT(5 23)') - wkt_f = StringIO() + wkt_f = BytesIO() wkt_f.write(ref_pnt.wkt) - wkb_f = StringIO() + wkb_f = BytesIO() wkb_f.write(str(ref_pnt.wkb)) # Other tests use `fromfile()` on string filenames so those diff --git a/django/contrib/gis/shortcuts.py b/django/contrib/gis/shortcuts.py index 1ca6bbb645..16b0fdff9e 100644 --- a/django/contrib/gis/shortcuts.py +++ b/django/contrib/gis/shortcuts.py @@ -1,8 +1,5 @@ -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO import zipfile +from io import BytesIO from django.conf import settings from django.http import HttpResponse @@ -10,7 +7,7 @@ from django.template import loader def compress_kml(kml): "Returns compressed KMZ from the given KML string." - kmz = StringIO() + kmz = BytesIO() zf = zipfile.ZipFile(kmz, 'a', zipfile.ZIP_DEFLATED) zf.writestr('doc.kml', kml.encode(settings.DEFAULT_CHARSET)) zf.close() diff --git a/django/contrib/gis/tests/geoapp/test_sitemaps.py b/django/contrib/gis/tests/geoapp/test_sitemaps.py index 8870d6a89c..a5c8f41ba4 100644 --- a/django/contrib/gis/tests/geoapp/test_sitemaps.py +++ b/django/contrib/gis/tests/geoapp/test_sitemaps.py @@ -1,9 +1,6 @@ from __future__ import absolute_import -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO +from io import BytesIO from xml.dom import minidom import zipfile @@ -66,7 +63,7 @@ class GeoSitemapTest(TestCase): kml_doc = minidom.parseString(self.client.get(kml_url).content) elif kml_type == 'kmz': # Have to decompress KMZ before parsing. - buf = StringIO(self.client.get(kml_url).content) + buf = BytesIO(self.client.get(kml_url).content) zf = zipfile.ZipFile(buf) self.assertEqual(1, len(zf.filelist)) self.assertEqual('doc.kml', zf.filelist[0].filename) diff --git a/django/core/files/base.py b/django/core/files/base.py index 29dbb6fcc1..d9b0fabb33 100644 --- a/django/core/files/base.py +++ b/django/core/files/base.py @@ -1,8 +1,5 @@ import os -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO +from io import BytesIO, StringIO from django.utils.encoding import smart_str, smart_unicode from django.core.files.utils import FileProxyMixin @@ -89,7 +86,7 @@ class File(FileProxyMixin): # Iterate over this file-like object by newlines buffer_ = None for chunk in self.chunks(): - chunk_buffer = StringIO(chunk) + chunk_buffer = BytesIO(chunk) for line in chunk_buffer: if buffer_: diff --git a/django/core/files/uploadedfile.py b/django/core/files/uploadedfile.py index 1dcd9aeeb0..b58349e27b 100644 --- a/django/core/files/uploadedfile.py +++ b/django/core/files/uploadedfile.py @@ -3,10 +3,7 @@ Classes representing uploaded files. """ import os -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO +from io import BytesIO from django.conf import settings from django.core.files.base import File @@ -110,8 +107,8 @@ class SimpleUploadedFile(InMemoryUploadedFile): A simple representation of a file, which just has content, size, and a name. """ def __init__(self, name, content, content_type='text/plain'): - content = content or '' - super(SimpleUploadedFile, self).__init__(StringIO(content), None, name, + content = content or b'' + super(SimpleUploadedFile, self).__init__(BytesIO(content), None, name, content_type, len(content), None) def from_dict(cls, file_dict): diff --git a/django/core/files/uploadhandler.py b/django/core/files/uploadhandler.py index 4316fddf43..88f78904bb 100644 --- a/django/core/files/uploadhandler.py +++ b/django/core/files/uploadhandler.py @@ -2,10 +2,7 @@ Base file upload handler classes, and the built-in concrete subclasses """ -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO +from io import BytesIO from django.conf import settings from django.core.exceptions import ImproperlyConfigured @@ -161,12 +158,12 @@ class MemoryFileUploadHandler(FileUploadHandler): def new_file(self, *args, **kwargs): super(MemoryFileUploadHandler, self).new_file(*args, **kwargs) if self.activated: - self.file = StringIO() + self.file = BytesIO() raise StopFutureHandlers() def receive_data_chunk(self, raw_data, start): """ - Add the data to the StringIO file. + Add the data to the BytesIO file. """ if self.activated: self.file.write(raw_data) diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index 2898703a95..0639ef19da 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -1,9 +1,6 @@ import sys +from io import BytesIO from threading import Lock -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO from django import http from django.core import signals @@ -116,7 +113,7 @@ class LimitedStream(object): if not chunk: break self.buffer += chunk - sio = StringIO(self.buffer) + sio = BytesIO(self.buffer) if size: line = sio.readline(size) else: diff --git a/django/core/mail/message.py b/django/core/mail/message.py index a01832cbd3..2618c7f17d 100644 --- a/django/core/mail/message.py +++ b/django/core/mail/message.py @@ -9,15 +9,12 @@ from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email.header import Header from email.utils import formatdate, getaddresses, formataddr, parseaddr +from io import BytesIO from django.conf import settings from django.core.mail.utils import DNS_NAME from django.utils.encoding import smart_str, force_unicode -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO # Don't BASE64-encode UTF-8 messages so that we avoid unwanted attention from # some spam filters. @@ -132,7 +129,7 @@ class SafeMIMEText(MIMEText): This overrides the default as_string() implementation to not mangle lines that begin with 'From '. See bug #13433 for details. """ - fp = StringIO() + fp = BytesIO() g = Generator(fp, mangle_from_ = False) g.flatten(self, unixfrom=unixfrom) return fp.getvalue() @@ -156,7 +153,7 @@ class SafeMIMEMultipart(MIMEMultipart): This overrides the default as_string() implementation to not mangle lines that begin with 'From '. See bug #13433 for details. """ - fp = StringIO() + fp = BytesIO() g = Generator(fp, mangle_from_ = False) g.flatten(self, unixfrom=unixfrom) return fp.getvalue() diff --git a/django/core/management/base.py b/django/core/management/base.py index a9368776f7..121a5c6ab7 100644 --- a/django/core/management/base.py +++ b/django/core/management/base.py @@ -6,6 +6,7 @@ be executed through ``django-admin.py`` or ``manage.py``). import os import sys +from io import BytesIO from optparse import make_option, OptionParser import traceback @@ -258,11 +259,7 @@ class BaseCommand(object): """ from django.core.management.validation import get_validation_errors - try: - from cStringIO import StringIO - except ImportError: - from StringIO import StringIO - s = StringIO() + s = BytesIO() num_errors = get_validation_errors(s, app) if num_errors: s.seek(0) diff --git a/django/core/serializers/base.py b/django/core/serializers/base.py index dbe7787726..2e6a0656b1 100644 --- a/django/core/serializers/base.py +++ b/django/core/serializers/base.py @@ -2,7 +2,7 @@ Module for abstract serializer/unserializer base classes. """ -from StringIO import StringIO +from io import BytesIO from django.db import models from django.utils.encoding import smart_unicode @@ -34,7 +34,7 @@ class Serializer(object): """ self.options = options - self.stream = options.pop("stream", StringIO()) + self.stream = options.pop("stream", BytesIO()) self.selected_fields = options.pop("fields", None) self.use_natural_keys = options.pop("use_natural_keys", False) @@ -121,7 +121,7 @@ class Deserializer(object): """ self.options = options if isinstance(stream_or_string, basestring): - self.stream = StringIO(stream_or_string) + self.stream = BytesIO(stream_or_string) else: self.stream = stream_or_string # hack to make sure that the models have all been loaded before diff --git a/django/core/serializers/json.py b/django/core/serializers/json.py index eb9fcfbacd..4da8581f68 100644 --- a/django/core/serializers/json.py +++ b/django/core/serializers/json.py @@ -8,7 +8,7 @@ from __future__ import absolute_import import datetime import decimal import json -from StringIO import StringIO +from io import BytesIO from django.core.serializers.base import DeserializationError from django.core.serializers.python import Serializer as PythonSerializer @@ -37,7 +37,7 @@ def Deserializer(stream_or_string, **options): Deserialize a stream or string of JSON data. """ if isinstance(stream_or_string, basestring): - stream = StringIO(stream_or_string) + stream = BytesIO(stream_or_string) else: stream = stream_or_string try: diff --git a/django/core/serializers/pyyaml.py b/django/core/serializers/pyyaml.py index dc884a66c7..5effda5b46 100644 --- a/django/core/serializers/pyyaml.py +++ b/django/core/serializers/pyyaml.py @@ -4,9 +4,9 @@ YAML serializer. Requires PyYaml (http://pyyaml.org/), but that's checked for in __init__. """ -from StringIO import StringIO import decimal import yaml +from io import BytesIO from django.db import models from django.core.serializers.base import DeserializationError @@ -49,7 +49,7 @@ def Deserializer(stream_or_string, **options): Deserialize a stream or string of YAML data. """ if isinstance(stream_or_string, basestring): - stream = StringIO(stream_or_string) + stream = BytesIO(stream_or_string) else: stream = stream_or_string try: diff --git a/django/forms/fields.py b/django/forms/fields.py index 39f8f9c846..61137f55c1 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -10,10 +10,7 @@ import os import re import urlparse from decimal import Decimal, DecimalException -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO +from io import BytesIO from django.core import validators from django.core.exceptions import ValidationError @@ -554,9 +551,9 @@ class ImageField(FileField): file = data.temporary_file_path() else: if hasattr(data, 'read'): - file = StringIO(data.read()) + file = BytesIO(data.read()) else: - file = StringIO(data['content']) + file = BytesIO(data['content']) try: # load() is the only method that can spot a truncated JPEG, diff --git a/django/http/__init__.py b/django/http/__init__.py index efcb3d93c5..2815f5fbd5 100644 --- a/django/http/__init__.py +++ b/django/http/__init__.py @@ -7,13 +7,10 @@ import sys import time import warnings +from io import BytesIO from pprint import pformat from urllib import urlencode, quote from urlparse import urljoin, parse_qsl -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO import Cookie # Some versions of Python 2.7 and later won't need this encoding bug fix: @@ -292,7 +289,7 @@ class HttpRequest(object): self._body = self.read() except IOError as e: raise UnreadablePostError, e, sys.exc_traceback - self._stream = StringIO(self._body) + self._stream = BytesIO(self._body) return self._body @property @@ -317,7 +314,7 @@ class HttpRequest(object): if self.META.get('CONTENT_TYPE', '').startswith('multipart'): if hasattr(self, '_body'): # Use already read data - data = StringIO(self._body) + data = BytesIO(self._body) else: data = self try: @@ -340,7 +337,7 @@ class HttpRequest(object): ## Expects self._stream to be set to an appropriate source of bytes by ## a corresponding request subclass (e.g. WSGIRequest). ## Also when request data has already been read by request.POST or - ## request.body, self._stream points to a StringIO instance + ## request.body, self._stream points to a BytesIO instance ## containing that data. def read(self, *args, **kwargs): diff --git a/django/test/client.py b/django/test/client.py index 807b4cc55e..c1764e2394 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -4,11 +4,8 @@ import os import re import mimetypes from copy import copy +from io import BytesIO from urlparse import urlparse, urlsplit -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO from django.conf import settings from django.contrib.auth import authenticate, login @@ -35,13 +32,13 @@ CONTENT_TYPE_RE = re.compile('.*; charset=([\w\d-]+);?') class FakePayload(object): """ - A wrapper around StringIO that restricts what can be read since data from + A wrapper around BytesIO that restricts what can be read since data from the network can't be seeked and cannot be read outside of its content length. This makes sure that views can't do anything under the test client that wouldn't work in Real Life. """ def __init__(self, content): - self.__content = StringIO(content) + self.__content = BytesIO(content) self.__len = len(content) def read(self, num_bytes=None): @@ -175,7 +172,7 @@ class RequestFactory(object): def __init__(self, **defaults): self.defaults = defaults self.cookies = SimpleCookie() - self.errors = StringIO() + self.errors = BytesIO() def _base_environ(self, **request): """ diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py index 7fa385ebc3..7cd15674d6 100644 --- a/django/utils/feedgenerator.py +++ b/django/utils/feedgenerator.py @@ -174,8 +174,8 @@ class SyndicationFeed(object): """ Returns the feed in the given encoding as a string. """ - from StringIO import StringIO - s = StringIO() + from io import BytesIO + s = BytesIO() self.write(s, encoding) return s.getvalue() diff --git a/django/utils/text.py b/django/utils/text.py index f443b31a67..2ac101fcb8 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -3,11 +3,7 @@ import unicodedata import warnings from gzip import GzipFile from htmlentitydefs import name2codepoint - -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO +from io import BytesIO from django.utils.encoding import force_unicode from django.utils.functional import allow_lazy, SimpleLazyObject @@ -277,7 +273,7 @@ phone2numeric = allow_lazy(phone2numeric) # From http://www.xhaus.com/alan/python/httpcomp.html#gzip # Used with permission. def compress_string(s): - zbuf = StringIO() + zbuf = BytesIO() zfile = GzipFile(mode='wb', compresslevel=6, fileobj=zbuf) zfile.write(s) zfile.close() diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py index 76c9bfc1ea..135a8cf6d5 100644 --- a/django/utils/translation/trans_real.py +++ b/django/utils/translation/trans_real.py @@ -5,13 +5,9 @@ import os import re import sys import gettext as gettext_module +from io import BytesIO from threading import local -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO - from django.utils.importlib import import_module from django.utils.safestring import mark_safe, SafeData @@ -442,7 +438,7 @@ def templatize(src, origin=None): """ from django.template import (Lexer, TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK, TOKEN_COMMENT, TRANSLATOR_COMMENT_MARK) - out = StringIO() + out = BytesIO() message_context = None intrans = False inplural = False @@ -453,16 +449,16 @@ def templatize(src, origin=None): for t in Lexer(src, origin).tokenize(): if incomment: if t.token_type == TOKEN_BLOCK and t.contents == 'endcomment': - content = ''.join(comment) + content = b''.join(comment) translators_comment_start = None for lineno, line in enumerate(content.splitlines(True)): if line.lstrip().startswith(TRANSLATOR_COMMENT_MARK): translators_comment_start = lineno for lineno, line in enumerate(content.splitlines(True)): if translators_comment_start is not None and lineno >= translators_comment_start: - out.write(' # %s' % line) + out.write(b' # %s' % line) else: - out.write(' #\n') + out.write(b' #\n') incomment = False comment = [] else: @@ -474,18 +470,18 @@ def templatize(src, origin=None): if endbmatch: if inplural: if message_context: - out.write(' npgettext(%r, %r, %r,count) ' % (message_context, ''.join(singular), ''.join(plural))) + out.write(b' npgettext(%r, %r, %r,count) ' % (message_context, ''.join(singular), ''.join(plural))) else: - out.write(' ngettext(%r, %r, count) ' % (''.join(singular), ''.join(plural))) + out.write(b' ngettext(%r, %r, count) ' % (''.join(singular), ''.join(plural))) for part in singular: out.write(blankout(part, 'S')) for part in plural: out.write(blankout(part, 'P')) else: if message_context: - out.write(' pgettext(%r, %r) ' % (message_context, ''.join(singular))) + out.write(b' pgettext(%r, %r) ' % (message_context, ''.join(singular))) else: - out.write(' gettext(%r) ' % ''.join(singular)) + out.write(b' gettext(%r) ' % ''.join(singular)) for part in singular: out.write(blankout(part, 'S')) message_context = None @@ -531,10 +527,10 @@ def templatize(src, origin=None): message_context = message_context.strip('"') elif message_context[0] == "'": message_context = message_context.strip("'") - out.write(' pgettext(%r, %r) ' % (message_context, g)) + out.write(b' pgettext(%r, %r) ' % (message_context, g)) message_context = None else: - out.write(' gettext(%r) ' % g) + out.write(b' gettext(%r) ' % g) elif bmatch: for fmatch in constant_re.findall(t.contents): out.write(' _(%s) ' % fmatch) @@ -552,7 +548,7 @@ def templatize(src, origin=None): plural = [] elif cmatches: for cmatch in cmatches: - out.write(' _(%s) ' % cmatch) + out.write(b' _(%s) ' % cmatch) elif t.contents == 'comment': incomment = True else: @@ -561,14 +557,14 @@ def templatize(src, origin=None): parts = t.contents.split('|') cmatch = constant_re.match(parts[0]) if cmatch: - out.write(' _(%s) ' % cmatch.group(1)) + out.write(b' _(%s) ' % cmatch.group(1)) for p in parts[1:]: if p.find(':_(') >= 0: - out.write(' %s ' % p.split(':',1)[1]) + out.write(b' %s ' % p.split(':',1)[1]) else: out.write(blankout(p, 'F')) elif t.token_type == TOKEN_COMMENT: - out.write(' # %s' % t.contents) + out.write(b' # %s' % t.contents) else: out.write(blankout(t.contents, 'X')) return out.getvalue() diff --git a/docs/howto/outputting-pdf.txt b/docs/howto/outputting-pdf.txt index a30b10f7b5..55f80bb4cc 100644 --- a/docs/howto/outputting-pdf.txt +++ b/docs/howto/outputting-pdf.txt @@ -104,15 +104,11 @@ Complex PDFs ============ If you're creating a complex PDF document with ReportLab, consider using the -:mod:`cStringIO` library as a temporary holding place for your PDF file. This +:mod:`io` library as a temporary holding place for your PDF file. This library provides a file-like object interface that is particularly efficient. -Here's the above "Hello World" example rewritten to use :mod:`cStringIO`:: +Here's the above "Hello World" example rewritten to use :mod:`io`:: - # Fall back to StringIO in environments where cStringIO is not available - try: - from cStringIO import StringIO - except ImportError: - from StringIO import StringIO + from io import BytesIO from reportlab.pdfgen import canvas from django.http import HttpResponse @@ -121,9 +117,9 @@ Here's the above "Hello World" example rewritten to use :mod:`cStringIO`:: response = HttpResponse(mimetype='application/pdf') response['Content-Disposition'] = 'attachment; filename=somefilename.pdf' - buffer = StringIO() + buffer = BytesIO() - # Create the PDF object, using the StringIO object as its "file." + # Create the PDF object, using the BytesIO object as its "file." p = canvas.Canvas(buffer) # Draw things on the PDF. Here's where the PDF generation happens. @@ -134,7 +130,7 @@ Here's the above "Hello World" example rewritten to use :mod:`cStringIO`:: p.showPage() p.save() - # Get the value of the StringIO buffer and write it to the response. + # Get the value of the BytesIO buffer and write it to the response. pdf = buffer.getvalue() buffer.close() response.write(pdf) diff --git a/tests/modeltests/invalid_models/tests.py b/tests/modeltests/invalid_models/tests.py index dfc6199624..9d7adb045c 100644 --- a/tests/modeltests/invalid_models/tests.py +++ b/tests/modeltests/invalid_models/tests.py @@ -1,6 +1,6 @@ import copy import sys -from cStringIO import StringIO +from io import BytesIO from django.core.management.validation import get_validation_errors from django.db.models.loading import cache, load_app @@ -16,7 +16,7 @@ class InvalidModelTestCase(unittest.TestCase): # coloring attached (makes matching the results easier). We restore # sys.stderr afterwards. self.old_stdout = sys.stdout - self.stdout = StringIO() + self.stdout = BytesIO() sys.stdout = self.stdout # This test adds dummy applications to the app cache. These diff --git a/tests/modeltests/model_forms/tests.py b/tests/modeltests/model_forms/tests.py index 47902f3a83..fdaae5b852 100644 --- a/tests/modeltests/model_forms/tests.py +++ b/tests/modeltests/model_forms/tests.py @@ -1372,19 +1372,6 @@ class OldFormForXTests(TestCase): self.assertEqual(instance.image.name, 'foo/test4.png') instance.delete() - # Test image field when cStringIO is not available - from django.forms import fields - from StringIO import StringIO - old_StringIO = fields.StringIO - fields.StringIO = StringIO - try: - f = ImageFileForm( - data={'description': u'An image'}, - files={'image': SimpleUploadedFile('test.png', image_data)}) - self.assertEqual(f.is_valid(), True) - finally: - fields.StringIO = old_StringIO - def test_media_on_modelform(self): # Similar to a regular Form class you can define custom media to be used on # the ModelForm. diff --git a/tests/regressiontests/file_storage/tests.py b/tests/regressiontests/file_storage/tests.py index c28b019c84..ce64c5de23 100644 --- a/tests/regressiontests/file_storage/tests.py +++ b/tests/regressiontests/file_storage/tests.py @@ -7,10 +7,7 @@ import shutil import tempfile import time from datetime import datetime, timedelta -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO +from io import BytesIO try: import threading @@ -483,7 +480,7 @@ class DimensionClosingBug(unittest.TestCase): """ Open files passed into get_image_dimensions() should stay opened. """ - empty_io = StringIO() + empty_io = BytesIO() try: get_image_dimensions(empty_io) finally: @@ -557,10 +554,10 @@ class NoNameFileTestCase(unittest.TestCase): urllib.urlopen() """ def test_noname_file_default_name(self): - self.assertEqual(File(StringIO('A file with no name')).name, None) + self.assertEqual(File(BytesIO(b'A file with no name')).name, None) def test_noname_file_get_size(self): - self.assertEqual(File(StringIO('A file with no name')).size, 19) + self.assertEqual(File(BytesIO(b'A file with no name')).size, 19) class FileLikeObjectTestCase(LiveServerBase): """ diff --git a/tests/regressiontests/fixtures_regress/tests.py b/tests/regressiontests/fixtures_regress/tests.py index ed8b404788..5c6f758b66 100644 --- a/tests/regressiontests/fixtures_regress/tests.py +++ b/tests/regressiontests/fixtures_regress/tests.py @@ -4,10 +4,7 @@ from __future__ import absolute_import import os import re -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO +from io import BytesIO from django.core import management from django.core.management.base import CommandError @@ -119,7 +116,7 @@ class TestFixtures(TestCase): Test for ticket #4371 -- Loading data of an unknown format should fail Validate that error conditions are caught correctly """ - stderr = StringIO() + stderr = BytesIO() management.call_command( 'loaddata', 'bad_fixture1.unkn', @@ -138,7 +135,7 @@ class TestFixtures(TestCase): using explicit filename. Validate that error conditions are caught correctly """ - stderr = StringIO() + stderr = BytesIO() management.call_command( 'loaddata', 'bad_fixture2.xml', @@ -157,7 +154,7 @@ class TestFixtures(TestCase): without file extension. Validate that error conditions are caught correctly """ - stderr = StringIO() + stderr = BytesIO() management.call_command( 'loaddata', 'bad_fixture2', @@ -175,7 +172,7 @@ class TestFixtures(TestCase): Test for ticket #4371 -- Loading a fixture file with no data returns an error. Validate that error conditions are caught correctly """ - stderr = StringIO() + stderr = BytesIO() management.call_command( 'loaddata', 'empty', @@ -194,7 +191,7 @@ class TestFixtures(TestCase): loading is aborted. Validate that error conditions are caught correctly """ - stderr = StringIO() + stderr = BytesIO() management.call_command( 'loaddata', 'empty', @@ -211,7 +208,7 @@ class TestFixtures(TestCase): """ (Regression for #9011 - error message is correct) """ - stderr = StringIO() + stderr = BytesIO() management.call_command( 'loaddata', 'bad_fixture2', @@ -317,7 +314,7 @@ class TestFixtures(TestCase): ) animal.save() - stdout = StringIO() + stdout = BytesIO() management.call_command( 'dumpdata', 'fixtures_regress.animal', @@ -346,7 +343,7 @@ class TestFixtures(TestCase): """ Regression for #11428 - Proxy models aren't included when you dumpdata """ - stdout = StringIO() + stdout = BytesIO() # Create an instance of the concrete class widget = Widget.objects.create(name='grommet') management.call_command( @@ -379,7 +376,7 @@ class TestFixtures(TestCase): """ Regression for #3615 - Ensure data with nonexistent child key references raises error """ - stderr = StringIO() + stderr = BytesIO() management.call_command( 'loaddata', 'forward_ref_bad_data.json', @@ -414,7 +411,7 @@ class TestFixtures(TestCase): """ Regression for #7043 - Error is quickly reported when no fixtures is provided in the command line. """ - stderr = StringIO() + stderr = BytesIO() management.call_command( 'loaddata', verbosity=0, @@ -426,7 +423,7 @@ class TestFixtures(TestCase): ) def test_loaddata_not_existant_fixture_file(self): - stdout_output = StringIO() + stdout_output = BytesIO() management.call_command( 'loaddata', 'this_fixture_doesnt_exist', @@ -511,7 +508,7 @@ class NaturalKeyFixtureTests(TestCase): commit=False ) - stdout = StringIO() + stdout = BytesIO() management.call_command( 'dumpdata', 'fixtures_regress.book', diff --git a/tests/regressiontests/i18n/commands/compilation.py b/tests/regressiontests/i18n/commands/compilation.py index 1f38910b61..039e463d0b 100644 --- a/tests/regressiontests/i18n/commands/compilation.py +++ b/tests/regressiontests/i18n/commands/compilation.py @@ -1,8 +1,5 @@ import os -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO +from io import BytesIO from django.core.management import CommandError from django.core.management.commands.compilemessages import compile_messages @@ -31,7 +28,7 @@ class PoFileTests(MessageCompilationTests): # We don't use the django.core.management infrastructure (call_command() # et al) because CommandError's cause exit(1) there. We test the # underlying compile_messages function instead - out = StringIO() + out = BytesIO() self.assertRaises(CommandError, compile_messages, out, locale=self.LOCALE) self.assertFalse(os.path.exists(self.MO_FILE)) @@ -51,7 +48,7 @@ class PoFileContentsTests(MessageCompilationTests): # We don't use the django.core.management infrastructure (call_command() # et al) because CommandError's cause exit(1) there. We test the # underlying compile_messages function instead - out = StringIO() + out = BytesIO() compile_messages(out, locale=self.LOCALE) self.assertTrue(os.path.exists(self.MO_FILE)) @@ -70,7 +67,7 @@ class PercentRenderingTests(MessageCompilationTests): # We don't use the django.core.management infrastructure (call_command() # et al) because CommandError's cause exit(1) there. We test the # underlying compile_messages function instead - out = StringIO() + out = BytesIO() compile_messages(out, locale=self.LOCALE) with translation.override(self.LOCALE): t = Template('{% load i18n %}{% trans "Looks like a str fmt spec %% o but shouldn\'t be interpreted as such" %}') diff --git a/tests/regressiontests/m2m_through_regress/tests.py b/tests/regressiontests/m2m_through_regress/tests.py index 1c188d05c3..73a13654e7 100644 --- a/tests/regressiontests/m2m_through_regress/tests.py +++ b/tests/regressiontests/m2m_through_regress/tests.py @@ -1,9 +1,6 @@ from __future__ import absolute_import -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO +from io import BytesIO from django.core import management from django.contrib.auth.models import User @@ -73,11 +70,11 @@ class M2MThroughTestCase(TestCase): pks = {"p_pk": p.pk, "g_pk": g.pk, "m_pk": m.pk} - out = StringIO() + out = BytesIO() management.call_command("dumpdata", "m2m_through_regress", format="json", stdout=out) self.assertEqual(out.getvalue().strip(), """[{"pk": %(m_pk)s, "model": "m2m_through_regress.membership", "fields": {"person": %(p_pk)s, "price": 100, "group": %(g_pk)s}}, {"pk": %(p_pk)s, "model": "m2m_through_regress.person", "fields": {"name": "Bob"}}, {"pk": %(g_pk)s, "model": "m2m_through_regress.group", "fields": {"name": "Roll"}}]""" % pks) - out = StringIO() + out = BytesIO() management.call_command("dumpdata", "m2m_through_regress", format="xml", indent=2, stdout=out) self.assertEqual(out.getvalue().strip(), """ @@ -145,6 +142,6 @@ class ThroughLoadDataTestCase(TestCase): def test_sequence_creation(self): "Check that sequences on an m2m_through are created for the through model, not a phantom auto-generated m2m table. Refs #11107" - out = StringIO() + out = BytesIO() management.call_command("dumpdata", "m2m_through_regress", format="json", stdout=out) self.assertEqual(out.getvalue().strip(), """[{"pk": 1, "model": "m2m_through_regress.usermembership", "fields": {"price": 100, "group": 1, "user": 1}}, {"pk": 1, "model": "m2m_through_regress.person", "fields": {"name": "Guido"}}, {"pk": 1, "model": "m2m_through_regress.group", "fields": {"name": "Python Core Group"}}]""") diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py index 289db05c71..0c0c59f136 100644 --- a/tests/regressiontests/serializers_regress/tests.py +++ b/tests/regressiontests/serializers_regress/tests.py @@ -10,10 +10,7 @@ from __future__ import absolute_import import datetime import decimal -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO +from io import BytesIO try: import yaml @@ -504,7 +501,7 @@ def streamTest(format, self): obj.save_base(raw=True) # Serialize the test database to a stream - stream = StringIO() + stream = BytesIO() serializers.serialize(format, [obj], indent=2, stream=stream) # Serialize normally for a comparison