瀏覽代碼

Marked bytestrings with b prefix. Refs #18269

This is a preparation for unicode literals general usage in
Django (Python 3 compatibility).
Claude Paroz 13 年之前
父節點
當前提交
38408f8007
共有 44 個文件被更改,包括 297 次插入296 次删除
  1. 1 1
      django/contrib/humanize/tests.py
  2. 1 1
      django/core/context_processors.py
  3. 1 1
      django/core/files/base.py
  4. 2 2
      django/core/files/uploadedfile.py
  5. 5 5
      django/core/handlers/wsgi.py
  6. 9 9
      django/db/backends/sqlite3/base.py
  7. 2 2
      django/db/models/base.py
  8. 2 2
      django/forms/models.py
  9. 3 3
      django/http/__init__.py
  10. 19 19
      django/http/multipartparser.py
  11. 4 4
      django/utils/crypto.py
  12. 2 2
      django/utils/encoding.py
  13. 1 1
      django/utils/html.py
  14. 1 1
      django/views/debug.py
  15. 1 1
      docs/ref/files/file.txt
  16. 2 2
      docs/ref/unicode.txt
  17. 7 7
      tests/modeltests/model_forms/tests.py
  18. 9 9
      tests/modeltests/serializers/tests.py
  19. 4 4
      tests/modeltests/str/tests.py
  20. 1 1
      tests/regressiontests/admin_util/tests.py
  21. 1 1
      tests/regressiontests/admin_widgets/tests.py
  22. 1 1
      tests/regressiontests/cache/tests.py
  23. 1 1
      tests/regressiontests/csrf_tests/tests.py
  24. 27 27
      tests/regressiontests/file_storage/tests.py
  25. 16 16
      tests/regressiontests/file_uploads/tests.py
  26. 9 9
      tests/regressiontests/forms/tests/fields.py
  27. 3 3
      tests/regressiontests/forms/tests/forms.py
  28. 3 3
      tests/regressiontests/forms/tests/models.py
  29. 3 2
      tests/regressiontests/forms/tests/regressions.py
  30. 1 1
      tests/regressiontests/forms/tests/widgets.py
  31. 1 1
      tests/regressiontests/handlers/tests.py
  32. 5 5
      tests/regressiontests/httpwrappers/tests.py
  33. 1 1
      tests/regressiontests/i18n/tests.py
  34. 1 1
      tests/regressiontests/localflavor/mk/tests.py
  35. 18 18
      tests/regressiontests/mail/tests.py
  36. 3 3
      tests/regressiontests/model_forms_regress/tests.py
  37. 44 44
      tests/regressiontests/requests/tests.py
  38. 3 3
      tests/regressiontests/signing/tests.py
  39. 26 26
      tests/regressiontests/staticfiles_tests/tests.py
  40. 1 1
      tests/regressiontests/string_lookup/tests.py
  41. 7 7
      tests/regressiontests/templates/tests.py
  42. 6 6
      tests/regressiontests/templates/unicode.py
  43. 36 36
      tests/regressiontests/test_client_regress/models.py
  44. 3 3
      tests/regressiontests/views/__init__.py

+ 1 - 1
django/contrib/humanize/tests.py

@@ -190,7 +190,7 @@ class HumanizeTests(TestCase):
         orig_humanize_datetime = humanize.datetime
         orig_timesince_datetime = timesince.datetime
         humanize.datetime = MockDateTime
-        timesince.datetime = new.module("mock_datetime")
+        timesince.datetime = new.module(b"mock_datetime")
         timesince.datetime.datetime = MockDateTime
 
         try:

+ 1 - 1
django/core/context_processors.py

@@ -22,7 +22,7 @@ def csrf(request):
             # In order to be able to provide debugging info in the
             # case of misconfiguration, we use a sentinel value
             # instead of returning an empty dict.
-            return 'NOTPROVIDED'
+            return b'NOTPROVIDED'
         else:
             return token
     _get_val = lazy(_get_val, str)

+ 1 - 1
django/core/files/base.py

@@ -125,7 +125,7 @@ class ContentFile(File):
     A File-like object that takes just raw content, rather than an actual file.
     """
     def __init__(self, content, name=None):
-        content = content or ''
+        content = content or b''
         super(ContentFile, self).__init__(BytesIO(content), name=name)
         self.size = len(content)
 

+ 2 - 2
django/core/files/uploadedfile.py

@@ -30,8 +30,8 @@ class UploadedFile(File):
         self.charset = charset
 
     def __repr__(self):
-        return "<%s: %s (%s)>" % (
-            self.__class__.__name__, smart_str(self.name), self.content_type)
+        return smart_str("<%s: %s (%s)>" % (
+            self.__class__.__name__, self.name, self.content_type))
 
     def _get_name(self):
         return self._name

+ 5 - 5
django/core/handlers/wsgi.py

@@ -78,14 +78,14 @@ class LimitedStream(object):
     def __init__(self, stream, limit, buf_size=64 * 1024 * 1024):
         self.stream = stream
         self.remaining = limit
-        self.buffer = ''
+        self.buffer = b''
         self.buf_size = buf_size
 
     def _read_limited(self, size=None):
         if size is None or size > self.remaining:
             size = self.remaining
         if size == 0:
-            return ''
+            return b''
         result = self.stream.read(size)
         self.remaining -= len(result)
         return result
@@ -93,17 +93,17 @@ class LimitedStream(object):
     def read(self, size=None):
         if size is None:
             result = self.buffer + self._read_limited()
-            self.buffer = ''
+            self.buffer = b''
         elif size < len(self.buffer):
             result = self.buffer[:size]
             self.buffer = self.buffer[size:]
         else: # size >= len(self.buffer)
             result = self.buffer + self._read_limited(size - len(self.buffer))
-            self.buffer = ''
+            self.buffer = b''
         return result
 
     def readline(self, size=None):
-        while '\n' not in self.buffer and \
+        while b'\n' not in self.buffer and \
               (size is None or len(self.buffer) < size):
             if size:
                 # since size is not None here, len(self.buffer) < size

+ 9 - 9
django/db/backends/sqlite3/base.py

@@ -51,15 +51,15 @@ def adapt_datetime_with_timezone_support(value):
             default_timezone = timezone.get_default_timezone()
             value = timezone.make_aware(value, default_timezone)
         value = value.astimezone(timezone.utc).replace(tzinfo=None)
-    return value.isoformat(" ")
-
-Database.register_converter("bool", lambda s: str(s) == '1')
-Database.register_converter("time", parse_time)
-Database.register_converter("date", parse_date)
-Database.register_converter("datetime", parse_datetime_with_timezone_support)
-Database.register_converter("timestamp", parse_datetime_with_timezone_support)
-Database.register_converter("TIMESTAMP", parse_datetime_with_timezone_support)
-Database.register_converter("decimal", util.typecast_decimal)
+    return value.isoformat(b" ")
+
+Database.register_converter(b"bool", lambda s: str(s) == '1')
+Database.register_converter(b"time", parse_time)
+Database.register_converter(b"date", parse_date)
+Database.register_converter(b"datetime", parse_datetime_with_timezone_support)
+Database.register_converter(b"timestamp", parse_datetime_with_timezone_support)
+Database.register_converter(b"TIMESTAMP", parse_datetime_with_timezone_support)
+Database.register_converter(b"decimal", util.typecast_decimal)
 Database.register_adapter(datetime.datetime, adapt_datetime_with_timezone_support)
 Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal)
 if Database.version_info >= (2, 4, 1):

+ 2 - 2
django/db/models/base.py

@@ -57,11 +57,11 @@ class ModelBase(type):
 
         new_class.add_to_class('_meta', Options(meta, **kwargs))
         if not abstract:
-            new_class.add_to_class('DoesNotExist', subclass_exception('DoesNotExist',
+            new_class.add_to_class('DoesNotExist', subclass_exception(b'DoesNotExist',
                     tuple(x.DoesNotExist
                             for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
                                     or (ObjectDoesNotExist,), module))
-            new_class.add_to_class('MultipleObjectsReturned', subclass_exception('MultipleObjectsReturned',
+            new_class.add_to_class('MultipleObjectsReturned', subclass_exception(b'MultipleObjectsReturned',
                     tuple(x.MultipleObjectsReturned
                             for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
                                     or (MultipleObjectsReturned,), module))

+ 2 - 2
django/forms/models.py

@@ -388,10 +388,10 @@ def modelform_factory(model, form=ModelForm, fields=None, exclude=None,
     parent = (object,)
     if hasattr(form, 'Meta'):
         parent = (form.Meta, object)
-    Meta = type('Meta', parent, attrs)
+    Meta = type(b'Meta', parent, attrs)
 
     # Give this new form class a reasonable name.
-    class_name = model.__name__ + 'Form'
+    class_name = model.__name__ + b'Form'
 
     # Class attributes for the new form class.
     form_class_attrs = {

+ 3 - 3
django/http/__init__.py

@@ -18,7 +18,7 @@ _cookie_encodes_correctly = Cookie.SimpleCookie().value_encode(';') == (';', '"\
 # See ticket #13007, http://bugs.python.org/issue2193 and http://trac.edgewall.org/ticket/2256
 _tc = Cookie.SimpleCookie()
 try:
-    _tc.load('foo:bar=1')
+    _tc.load(b'foo:bar=1')
     _cookie_allows_colon_in_names = True
 except Cookie.CookieError:
     _cookie_allows_colon_in_names = False
@@ -650,8 +650,8 @@ class HttpResponse(object):
 
     def _get_content(self):
         if self.has_header('Content-Encoding'):
-            return ''.join([str(e) for e in self._container])
-        return ''.join([smart_str(e, self._charset) for e in self._container])
+            return b''.join([str(e) for e in self._container])
+        return b''.join([smart_str(e, self._charset) for e in self._container])
 
     def _set_content(self, value):
         if hasattr(value, '__iter__'):

+ 19 - 19
django/http/multipartparser.py

@@ -268,7 +268,7 @@ class LazyStream(object):
         """
         self._producer = producer
         self._empty = False
-        self._leftover = ''
+        self._leftover = b''
         self.length = length
         self.position = 0
         self._remaining = length
@@ -282,7 +282,7 @@ class LazyStream(object):
             remaining = (size is not None and [size] or [self._remaining])[0]
             # do the whole thing in one shot if no limit was provided.
             if remaining is None:
-                yield ''.join(self)
+                yield b''.join(self)
                 return
 
             # otherwise do some bookkeeping to return exactly enough
@@ -298,7 +298,7 @@ class LazyStream(object):
                 remaining -= len(emitting)
                 yield emitting
 
-        out = ''.join(parts())
+        out = b''.join(parts())
         return out
 
     def next(self):
@@ -311,7 +311,7 @@ class LazyStream(object):
         """
         if self._leftover:
             output = self._leftover
-            self._leftover = ''
+            self._leftover = b''
         else:
             output = next(self._producer)
             self._unget_history = []
@@ -341,7 +341,7 @@ class LazyStream(object):
             return
         self._update_unget_history(len(bytes))
         self.position -= len(bytes)
-        self._leftover = ''.join([bytes, self._leftover])
+        self._leftover = b''.join([bytes, self._leftover])
 
     def _update_unget_history(self, num_bytes):
         """
@@ -459,7 +459,7 @@ class BoundaryIter(object):
         if not chunks:
             raise StopIteration()
 
-        chunk = ''.join(chunks)
+        chunk = b''.join(chunks)
         boundary = self._find_boundary(chunk, len(chunk) < self._rollback)
 
         if boundary:
@@ -495,9 +495,9 @@ class BoundaryIter(object):
             end = index
             next = index + len(self._boundary)
             # backup over CRLF
-            if data[max(0,end-1)] == '\n':
+            if data[max(0,end-1)] == b'\n':
                 end -= 1
-            if data[max(0,end-1)] == '\r':
+            if data[max(0,end-1)] == b'\r':
                 end -= 1
             return end, next
 
@@ -531,7 +531,7 @@ def parse_boundary_stream(stream, max_header_size):
     # 'find' returns the top of these four bytes, so we'll
     # need to munch them later to prevent them from polluting
     # the payload.
-    header_end = chunk.find('\r\n\r\n')
+    header_end = chunk.find(b'\r\n\r\n')
 
     def _parse_header(line):
         main_value_pair, params = parse_header(line)
@@ -557,7 +557,7 @@ def parse_boundary_stream(stream, max_header_size):
     outdict = {}
 
     # Eliminate blank lines
-    for line in header.split('\r\n'):
+    for line in header.split(b'\r\n'):
         # This terminology ("main value" and "dictionary of
         # parameters") is from the Python docs.
         try:
@@ -580,7 +580,7 @@ def parse_boundary_stream(stream, max_header_size):
 class Parser(object):
     def __init__(self, stream, boundary):
         self._stream = stream
-        self._separator = '--' + boundary
+        self._separator = b'--' + boundary
 
     def __iter__(self):
         boundarystream = InterBoundaryIter(self._stream, self._separator)
@@ -590,27 +590,27 @@ class Parser(object):
 
 def parse_header(line):
     """ Parse the header into a key-value. """
-    plist = _parse_header_params(';' + line)
+    plist = _parse_header_params(b';' + line)
     key = plist.pop(0).lower()
     pdict = {}
     for p in plist:
-        i = p.find('=')
+        i = p.find(b'=')
         if i >= 0:
             name = p[:i].strip().lower()
             value = p[i+1:].strip()
-            if len(value) >= 2 and value[0] == value[-1] == '"':
+            if len(value) >= 2 and value[0] == value[-1] == b'"':
                 value = value[1:-1]
-                value = value.replace('\\\\', '\\').replace('\\"', '"')
+                value = value.replace(b'\\\\', b'\\').replace(b'\\"', b'"')
             pdict[name] = value
     return key, pdict
 
 def _parse_header_params(s):
     plist = []
-    while s[:1] == ';':
+    while s[:1] == b';':
         s = s[1:]
-        end = s.find(';')
-        while end > 0 and s.count('"', 0, end) % 2:
-            end = s.find(';', end + 1)
+        end = s.find(b';')
+        while end > 0 and s.count(b'"', 0, end) % 2:
+            end = s.find(b';', end + 1)
         if end < 0:
             end = len(s)
         f = s[:end]

+ 4 - 4
django/utils/crypto.py

@@ -23,8 +23,8 @@ except NotImplementedError:
 from django.conf import settings
 
 
-_trans_5c = "".join([chr(x ^ 0x5C) for x in xrange(256)])
-_trans_36 = "".join([chr(x ^ 0x36) for x in xrange(256)])
+_trans_5c = b"".join([chr(x ^ 0x5C) for x in xrange(256)])
+_trans_36 = b"".join([chr(x ^ 0x36) for x in xrange(256)])
 
 
 def salted_hmac(key_salt, value, secret=None):
@@ -148,11 +148,11 @@ def pbkdf2(password, salt, iterations, dklen=0, digest=None):
 
     def F(i):
         def U():
-            u = salt + struct.pack('>I', i)
+            u = salt + struct.pack(b'>I', i)
             for j in xrange(int(iterations)):
                 u = _fast_hmac(password, u, digest).digest()
                 yield _bin_to_long(u)
         return _long_to_bin(reduce(operator.xor, U()), hex_format_string)
 
     T = [F(x) for x in range(1, l + 1)]
-    return ''.join(T[:-1]) + T[-1][:r]
+    return b''.join(T[:-1]) + T[-1][:r]

+ 2 - 2
django/utils/encoding.py

@@ -154,7 +154,7 @@ def iri_to_uri(iri):
     # converted.
     if iri is None:
         return iri
-    return urllib.quote(smart_str(iri), safe="/#%[]=:;$&()+,!?*@'~")
+    return urllib.quote(smart_str(iri), safe=b"/#%[]=:;$&()+,!?*@'~")
 
 def filepath_to_uri(path):
     """Convert an file system path to a URI portion that is suitable for
@@ -173,7 +173,7 @@ def filepath_to_uri(path):
         return path
     # I know about `os.sep` and `os.altsep` but I want to leave
     # some flexibility for hardcoding separators.
-    return urllib.quote(smart_str(path).replace("\\", "/"), safe="/~!*()'")
+    return urllib.quote(smart_str(path).replace("\\", "/"), safe=b"/~!*()'")
 
 # The encoding of the default system locale but falls back to the
 # given fallback encoding if the encoding is unsupported by python or could

+ 1 - 1
django/utils/html.py

@@ -116,7 +116,7 @@ def smart_urlquote(url):
     # contains a % not followed by two hexadecimal digits. See #9655.
     if '%' not in url or unquoted_percents_re.search(url):
         # See http://bugs.python.org/issue2637
-        url = urllib.quote(smart_str(url), safe='!*\'();:@&=+$,/?#[]~')
+        url = urllib.quote(smart_str(url), safe=b'!*\'();:@&=+$,/?#[]~')
 
     return force_unicode(url)
 

+ 1 - 1
django/views/debug.py

@@ -333,7 +333,7 @@ class ExceptionReporter(object):
                 source = source.splitlines()
         if source is None:
             try:
-                with open(filename) as fp:
+                with open(filename, 'rb') as fp:
                     source = fp.readlines()
             except (OSError, IOError):
                 pass

+ 1 - 1
docs/ref/files/file.txt

@@ -96,7 +96,7 @@ The ``ContentFile`` Class
 
         from django.core.files.base import ContentFile
 
-        f1 = ContentFile("my string content")
+        f1 = ContentFile(b"my string content")
         f2 = ContentFile(u"my unicode content encoded as UTF-8".encode('UTF-8'))
 
 .. currentmodule:: django.core.files.images

+ 2 - 2
docs/ref/unicode.txt

@@ -269,7 +269,7 @@ You can pass either Unicode strings or UTF-8 bytestrings as arguments to
 querysets are identical::
 
     qs = People.objects.filter(name__contains=u'Å')
-    qs = People.objects.filter(name__contains='\xc3\x85') # UTF-8 encoding of Å
+    qs = People.objects.filter(name__contains=b'\xc3\x85') # UTF-8 encoding of Å
 
 Templates
 =========
@@ -277,7 +277,7 @@ Templates
 You can use either Unicode or bytestrings when creating templates manually::
 
 	from django.template import Template
-	t1 = Template('This is a bytestring template.')
+	t1 = Template(b'This is a bytestring template.')
 	t2 = Template(u'This is a Unicode template.')
 
 But the common case is to read templates from the filesystem, and this creates

+ 7 - 7
tests/modeltests/model_forms/tests.py

@@ -1126,7 +1126,7 @@ class OldFormForXTests(TestCase):
 
         f = TextFileForm(
                 data={'description': u'Assistance'},
-                files={'file': SimpleUploadedFile('test1.txt', 'hello world')})
+                files={'file': SimpleUploadedFile('test1.txt', b'hello world')})
         self.assertEqual(f.is_valid(), True)
         self.assertEqual(type(f.cleaned_data['file']), SimpleUploadedFile)
         instance = f.save()
@@ -1135,7 +1135,7 @@ class OldFormForXTests(TestCase):
         instance.file.delete()
         f = TextFileForm(
                 data={'description': u'Assistance'},
-                files={'file': SimpleUploadedFile('test1.txt', 'hello world')})
+                files={'file': SimpleUploadedFile('test1.txt', b'hello world')})
         self.assertEqual(f.is_valid(), True)
         self.assertEqual(type(f.cleaned_data['file']), SimpleUploadedFile)
         instance = f.save()
@@ -1144,7 +1144,7 @@ class OldFormForXTests(TestCase):
         # Check if the max_length attribute has been inherited from the model.
         f = TextFileForm(
                 data={'description': u'Assistance'},
-                files={'file': SimpleUploadedFile('test-maxlength.txt', 'hello world')})
+                files={'file': SimpleUploadedFile('test-maxlength.txt', b'hello world')})
         self.assertEqual(f.is_valid(), False)
 
         # Edit an instance that already has the file defined in the model. This will not
@@ -1165,7 +1165,7 @@ class OldFormForXTests(TestCase):
 
         f = TextFileForm(
                 data={'description': u'Assistance'},
-                files={'file': SimpleUploadedFile('test2.txt', 'hello world')}, instance=instance)
+                files={'file': SimpleUploadedFile('test2.txt', b'hello world')}, instance=instance)
         self.assertEqual(f.is_valid(), True)
         instance = f.save()
         self.assertEqual(instance.file.name, 'tests/test2.txt')
@@ -1174,7 +1174,7 @@ class OldFormForXTests(TestCase):
         instance.file.delete()
         f = TextFileForm(
                 data={'description': u'Assistance'},
-                files={'file': SimpleUploadedFile('test2.txt', 'hello world')})
+                files={'file': SimpleUploadedFile('test2.txt', b'hello world')})
         self.assertEqual(f.is_valid(), True)
         instance = f.save()
         self.assertEqual(instance.file.name, 'tests/test2.txt')
@@ -1193,7 +1193,7 @@ class OldFormForXTests(TestCase):
 
         f = TextFileForm(
                 data={'description': u'Assistance'},
-                files={'file': SimpleUploadedFile('test3.txt', 'hello world')}, instance=instance)
+                files={'file': SimpleUploadedFile('test3.txt', b'hello world')}, instance=instance)
         self.assertEqual(f.is_valid(), True)
         instance = f.save()
         self.assertEqual(instance.file.name, 'tests/test3.txt')
@@ -1215,7 +1215,7 @@ class OldFormForXTests(TestCase):
 
         f = TextFileForm(
                 data={'description': u'Assistance'},
-                files={'file': SimpleUploadedFile('test3.txt', 'hello world')})
+                files={'file': SimpleUploadedFile('test3.txt', b'hello world')})
         self.assertEqual(f.is_valid(), True)
         instance = f.save()
         self.assertEqual(instance.file.name, 'tests/test3.txt')

+ 9 - 9
tests/modeltests/serializers/tests.py

@@ -113,8 +113,8 @@ class SerializersTestBase(object):
         Tests the ability to create new objects by
         modifying serialized content.
         """
-        old_headline = "Poker has no place on ESPN"
-        new_headline = "Poker has no place on television"
+        old_headline = b"Poker has no place on ESPN"
+        new_headline = b"Poker has no place on television"
         serial_str = serializers.serialize(self.serializer_name,
                                            Article.objects.all())
         serial_str = serial_str.replace(old_headline, new_headline)
@@ -284,7 +284,7 @@ class SerializersTransactionTestBase(object):
 
 class XmlSerializerTestCase(SerializersTestBase, TestCase):
     serializer_name = "xml"
-    pkless_str = """<?xml version="1.0" encoding="utf-8"?>
+    pkless_str = b"""<?xml version="1.0" encoding="utf-8"?>
 <django-objects version="1.0">
     <object model="serializers.category">
         <field type="CharField" name="name">Reference</field>
@@ -330,7 +330,7 @@ class XmlSerializerTestCase(SerializersTestBase, TestCase):
 
 class XmlSerializerTransactionTestCase(SerializersTransactionTestBase, TransactionTestCase):
     serializer_name = "xml"
-    fwd_ref_str = """<?xml version="1.0" encoding="utf-8"?>
+    fwd_ref_str = b"""<?xml version="1.0" encoding="utf-8"?>
 <django-objects version="1.0">
     <object pk="1" model="serializers.article">
         <field to="serializers.author" name="author" rel="ManyToOneRel">1</field>
@@ -350,7 +350,7 @@ class XmlSerializerTransactionTestCase(SerializersTransactionTestBase, Transacti
 
 class JsonSerializerTestCase(SerializersTestBase, TestCase):
     serializer_name = "json"
-    pkless_str = """[{"pk": null, "model": "serializers.category", "fields": {"name": "Reference"}}]"""
+    pkless_str = b"""[{"pk": null, "model": "serializers.category", "fields": {"name": "Reference"}}]"""
 
     @staticmethod
     def _validate_output(serial_str):
@@ -380,7 +380,7 @@ class JsonSerializerTestCase(SerializersTestBase, TestCase):
 
 class JsonSerializerTransactionTestCase(SerializersTransactionTestBase, TransactionTestCase):
     serializer_name = "json"
-    fwd_ref_str = """[
+    fwd_ref_str = b"""[
     {
         "pk": 1,
         "model": "serializers.article",
@@ -413,7 +413,7 @@ except ImportError:
 else:
     class YamlSerializerTestCase(SerializersTestBase, TestCase):
         serializer_name = "yaml"
-        fwd_ref_str = """- fields:
+        fwd_ref_str = b"""- fields:
     headline: Forward references pose no problem
     pub_date: 2006-06-16 15:00:00
     categories: [1]
@@ -429,7 +429,7 @@ else:
   pk: 1
   model: serializers.author"""
 
-        pkless_str = """- fields:
+        pkless_str = b"""- fields:
     name: Reference
   pk: null
   model: serializers.category"""
@@ -469,7 +469,7 @@ else:
 
     class YamlSerializerTransactionTestCase(SerializersTransactionTestBase, TransactionTestCase):
         serializer_name = "yaml"
-        fwd_ref_str = """- fields:
+        fwd_ref_str = b"""- fields:
     headline: Forward references pose no problem
     pub_date: 2006-06-16 15:00:00
     categories: [1]

+ 4 - 4
tests/modeltests/str/tests.py

@@ -11,11 +11,11 @@ from .models import Article, InternationalArticle
 class SimpleTests(TestCase):
     def test_basic(self):
         a = Article.objects.create(
-            headline='Area man programs in Python',
+            headline=b'Area man programs in Python',
             pub_date=datetime.datetime(2005, 7, 28)
         )
-        self.assertEqual(str(a), 'Area man programs in Python')
-        self.assertEqual(repr(a), '<Article: Area man programs in Python>')
+        self.assertEqual(str(a), b'Area man programs in Python')
+        self.assertEqual(repr(a), b'<Article: Area man programs in Python>')
 
     def test_international(self):
         a = InternationalArticle.objects.create(
@@ -23,4 +23,4 @@ class SimpleTests(TestCase):
             pub_date=datetime.datetime(2005, 7, 28)
         )
         # The default str() output will be the UTF-8 encoded output of __unicode__().
-        self.assertEqual(str(a), 'Girl wins \xe2\x82\xac12.500 in lottery')
+        self.assertEqual(str(a), b'Girl wins \xe2\x82\xac12.500 in lottery')

+ 1 - 1
tests/regressiontests/admin_util/tests.py

@@ -170,7 +170,7 @@ class UtilTests(unittest.TestCase):
         )
         self.assertEqual(
             label_for_field("__str__", Article),
-            "article"
+            b"article"
         )
 
         self.assertRaises(

+ 1 - 1
tests/regressiontests/admin_widgets/tests.py

@@ -280,7 +280,7 @@ class AdminFileWidgetTest(DjangoTestCase):
         )
 
         self.assertHTMLEqual(
-            conditional_escape(w.render('test', SimpleUploadedFile('test', 'content'))),
+            conditional_escape(w.render('test', SimpleUploadedFile('test', b'content'))),
             '<input type="file" name="test" />',
         )
 

+ 1 - 1
tests/regressiontests/cache/tests.py

@@ -822,7 +822,7 @@ class DBCacheTests(BaseCacheTests, TransactionTestCase):
     def test_second_call_doesnt_crash(self):
         err = StringIO.StringIO()
         management.call_command('createcachetable', self._table_name, verbosity=0, interactive=False, stderr=err)
-        self.assertTrue("Cache table 'test cache table' could not be created" in err.getvalue())
+        self.assertTrue(b"Cache table 'test cache table' could not be created" in err.getvalue())
 
 
 @override_settings(USE_TZ=True)

+ 1 - 1
tests/regressiontests/csrf_tests/tests.py

@@ -47,7 +47,7 @@ class TestingHttpRequest(HttpRequest):
 class CsrfViewMiddlewareTest(TestCase):
     # The csrf token is potentially from an untrusted source, so could have
     # characters that need dealing with.
-    _csrf_id_cookie = "<1>\xc2\xa1"
+    _csrf_id_cookie = b"<1>\xc2\xa1"
     _csrf_id = "1"
 
     def _get_GET_no_csrf_cookie_request(self):

+ 27 - 27
tests/regressiontests/file_storage/tests.py

@@ -127,7 +127,7 @@ class FileStorageTests(unittest.TestCase):
         """
         self.assertFalse(self.storage.exists('test.file'))
 
-        f = ContentFile('custom contents')
+        f = ContentFile(b'custom contents')
         f_name = self.storage.save('test.file', f)
         atime = self.storage.accessed_time(f_name)
 
@@ -143,7 +143,7 @@ class FileStorageTests(unittest.TestCase):
         """
         self.assertFalse(self.storage.exists('test.file'))
 
-        f = ContentFile('custom contents')
+        f = ContentFile(b'custom contents')
         f_name = self.storage.save('test.file', f)
         ctime = self.storage.created_time(f_name)
 
@@ -160,7 +160,7 @@ class FileStorageTests(unittest.TestCase):
         """
         self.assertFalse(self.storage.exists('test.file'))
 
-        f = ContentFile('custom contents')
+        f = ContentFile(b'custom contents')
         f_name = self.storage.save('test.file', f)
         mtime = self.storage.modified_time(f_name)
 
@@ -177,7 +177,7 @@ class FileStorageTests(unittest.TestCase):
         """
         self.assertFalse(self.storage.exists('test.file'))
 
-        f = ContentFile('custom contents')
+        f = ContentFile(b'custom contents')
         f.name = 'test.file'
 
         storage_f_name = self.storage.save(None, f)
@@ -194,11 +194,11 @@ class FileStorageTests(unittest.TestCase):
         """
         self.assertFalse(self.storage.exists('path/to'))
         self.storage.save('path/to/test.file',
-            ContentFile('file saved with path'))
+            ContentFile(b'file saved with path'))
 
         self.assertTrue(self.storage.exists('path/to'))
         self.assertEqual(self.storage.open('path/to/test.file').read(),
-            'file saved with path')
+            b'file saved with path')
 
         self.assertTrue(os.path.exists(
             os.path.join(self.temp_dir, 'path', 'to', 'test.file')))
@@ -211,7 +211,7 @@ class FileStorageTests(unittest.TestCase):
         """
         self.assertFalse(self.storage.exists('test.file'))
 
-        f = ContentFile('custom contents')
+        f = ContentFile(b'custom contents')
         f_name = self.storage.save('test.file', f)
 
         self.assertEqual(self.storage.path(f_name),
@@ -246,8 +246,8 @@ class FileStorageTests(unittest.TestCase):
         self.assertFalse(self.storage.exists('storage_test_2'))
         self.assertFalse(self.storage.exists('storage_dir_1'))
 
-        f = self.storage.save('storage_test_1', ContentFile('custom content'))
-        f = self.storage.save('storage_test_2', ContentFile('custom content'))
+        f = self.storage.save('storage_test_1', ContentFile(b'custom content'))
+        f = self.storage.save('storage_test_2', ContentFile(b'custom content'))
         os.mkdir(os.path.join(self.temp_dir, 'storage_dir_1'))
 
         dirs, files = self.storage.listdir('')
@@ -304,18 +304,18 @@ class FileStorageTests(unittest.TestCase):
             os.makedirs = fake_makedirs
 
             self.storage.save('normal/test.file',
-                ContentFile('saved normally'))
+                ContentFile(b'saved normally'))
             self.assertEqual(self.storage.open('normal/test.file').read(),
-                'saved normally')
+                b'saved normally')
 
             self.storage.save('raced/test.file',
-                ContentFile('saved with race'))
+                ContentFile(b'saved with race'))
             self.assertEqual(self.storage.open('raced/test.file').read(),
-                'saved with race')
+                b'saved with race')
 
             # Check that OSErrors aside from EEXIST are still raised.
             self.assertRaises(OSError,
-                self.storage.save, 'error/test.file', ContentFile('not saved'))
+                self.storage.save, 'error/test.file', ContentFile(b'not saved'))
         finally:
             os.makedirs = real_makedirs
 
@@ -341,16 +341,16 @@ class FileStorageTests(unittest.TestCase):
         try:
             os.remove = fake_remove
 
-            self.storage.save('normal.file', ContentFile('delete normally'))
+            self.storage.save('normal.file', ContentFile(b'delete normally'))
             self.storage.delete('normal.file')
             self.assertFalse(self.storage.exists('normal.file'))
 
-            self.storage.save('raced.file', ContentFile('delete with race'))
+            self.storage.save('raced.file', ContentFile(b'delete with race'))
             self.storage.delete('raced.file')
             self.assertFalse(self.storage.exists('normal.file'))
 
             # Check that OSErrors aside from ENOENT are still raised.
-            self.storage.save('error.file', ContentFile('delete with error'))
+            self.storage.save('error.file', ContentFile(b'delete with error'))
             self.assertRaises(OSError, self.storage.delete, 'error.file')
         finally:
             os.remove = real_remove
@@ -374,9 +374,9 @@ class CustomStorageTests(FileStorageTests):
     storage_class = CustomStorage
 
     def test_custom_get_available_name(self):
-        first = self.storage.save('custom_storage', ContentFile('custom contents'))
+        first = self.storage.save('custom_storage', ContentFile(b'custom contents'))
         self.assertEqual(first, 'custom_storage')
-        second = self.storage.save('custom_storage', ContentFile('more contents'))
+        second = self.storage.save('custom_storage', ContentFile(b'more contents'))
         self.assertEqual(second, 'custom_storage.2')
         self.storage.delete(first)
         self.storage.delete(second)
@@ -410,7 +410,7 @@ class FileSaveRaceConditionTest(unittest.TestCase):
         shutil.rmtree(self.storage_dir)
 
     def save_file(self, name):
-        name = self.storage.save(name, SlowFile("Data"))
+        name = self.storage.save(name, SlowFile(b"Data"))
 
     def test_race_condition(self):
         self.thread.start()
@@ -433,7 +433,7 @@ class FileStoragePermissions(unittest.TestCase):
         shutil.rmtree(self.storage_dir)
 
     def test_file_upload_permissions(self):
-        name = self.storage.save("the_file", ContentFile("data"))
+        name = self.storage.save("the_file", ContentFile(b"data"))
         actual_mode = os.stat(self.storage.path(name))[0] & 0777
         self.assertEqual(actual_mode, 0666)
 
@@ -453,8 +453,8 @@ class FileStoragePathParsing(unittest.TestCase):
         sure we still mangle the file name instead of the directory name.
         """
 
-        self.storage.save('dotted.path/test', ContentFile("1"))
-        self.storage.save('dotted.path/test', ContentFile("2"))
+        self.storage.save('dotted.path/test', ContentFile(b"1"))
+        self.storage.save('dotted.path/test', ContentFile(b"2"))
 
         self.assertFalse(os.path.exists(os.path.join(self.storage_dir, 'dotted_.path')))
         self.assertTrue(os.path.exists(os.path.join(self.storage_dir, 'dotted.path/test')))
@@ -465,8 +465,8 @@ class FileStoragePathParsing(unittest.TestCase):
         File names with a dot as their first character don't have an extension,
         and the underscore should get added to the end.
         """
-        self.storage.save('dotted.path/.test', ContentFile("1"))
-        self.storage.save('dotted.path/.test', ContentFile("2"))
+        self.storage.save('dotted.path/.test', ContentFile(b"1"))
+        self.storage.save('dotted.path/.test', ContentFile(b"2"))
 
         self.assertTrue(os.path.exists(os.path.join(self.storage_dir, 'dotted.path/.test')))
         self.assertTrue(os.path.exists(os.path.join(self.storage_dir, 'dotted.path/.test_1')))
@@ -542,11 +542,11 @@ class ContentFileTestCase(unittest.TestCase):
     Test that the constructor of ContentFile accepts 'name' (#16590).
     """
     def test_content_file_default_name(self):
-        self.assertEqual(ContentFile("content").name, None)
+        self.assertEqual(ContentFile(b"content").name, None)
 
     def test_content_file_custom_name(self):
         name = "I can have a name too!"
-        self.assertEqual(ContentFile("content", name=name).name, name)
+        self.assertEqual(ContentFile(b"content", name=name).name, name)
 
 class NoNameFileTestCase(unittest.TestCase):
     """

+ 16 - 16
tests/regressiontests/file_uploads/tests.py

@@ -24,7 +24,7 @@ UNICODE_FILENAME = u'test-0123456789_中文_Orléans.jpg'
 
 class FileUploadTests(TestCase):
     def test_simple_upload(self):
-        with open(__file__) as fp:
+        with open(__file__, 'rb') as fp:
             post_data = {
                 'name': 'Ringo',
                 'file_field': fp,
@@ -36,11 +36,11 @@ class FileUploadTests(TestCase):
         tdir = tempfile.gettempdir()
 
         file1 = tempfile.NamedTemporaryFile(suffix=".file1", dir=tdir)
-        file1.write('a' * (2 ** 21))
+        file1.write(b'a' * (2 ** 21))
         file1.seek(0)
 
         file2 = tempfile.NamedTemporaryFile(suffix=".file2", dir=tdir)
-        file2.write('a' * (10 * 2 ** 20))
+        file2.write(b'a' * (10 * 2 ** 20))
         file2.seek(0)
 
         post_data = {
@@ -89,7 +89,7 @@ class FileUploadTests(TestCase):
 
         # This file contains chinese symbols and an accented char in the name.
         with open(os.path.join(tdir, UNICODE_FILENAME.encode('utf-8')), 'w+b') as file1:
-            file1.write('b' * (2 ** 10))
+            file1.write(b'b' * (2 ** 10))
             file1.seek(0)
 
             post_data = {
@@ -214,7 +214,7 @@ class FileUploadTests(TestCase):
             'CONTENT_TYPE': client.MULTIPART_CONTENT,
             'PATH_INFO': '/file_uploads/echo/',
             'REQUEST_METHOD': 'POST',
-            'wsgi.input': client.FakePayload(''),
+            'wsgi.input': client.FakePayload(b''),
         }
         got = json.loads(self.client.request(**r).content)
         self.assertEqual(got, {})
@@ -222,12 +222,12 @@ class FileUploadTests(TestCase):
     def test_custom_upload_handler(self):
         # A small file (under the 5M quota)
         smallfile = tempfile.NamedTemporaryFile()
-        smallfile.write('a' * (2 ** 21))
+        smallfile.write(b'a' * (2 ** 21))
         smallfile.seek(0)
 
         # A big file (over the quota)
         bigfile = tempfile.NamedTemporaryFile()
-        bigfile.write('a' * (10 * 2 ** 20))
+        bigfile.write(b'a' * (10 * 2 ** 20))
         bigfile.seek(0)
 
         # Small file posting should work.
@@ -242,7 +242,7 @@ class FileUploadTests(TestCase):
 
     def test_broken_custom_upload_handler(self):
         f = tempfile.NamedTemporaryFile()
-        f.write('a' * (2 ** 21))
+        f.write(b'a' * (2 ** 21))
         f.seek(0)
 
         # AttributeError: You cannot alter upload handlers after the upload has been processed.
@@ -255,15 +255,15 @@ class FileUploadTests(TestCase):
 
     def test_fileupload_getlist(self):
         file1 = tempfile.NamedTemporaryFile()
-        file1.write('a' * (2 ** 23))
+        file1.write(b'a' * (2 ** 23))
         file1.seek(0)
 
         file2 = tempfile.NamedTemporaryFile()
-        file2.write('a' * (2 * 2 ** 18))
+        file2.write(b'a' * (2 * 2 ** 18))
         file2.seek(0)
 
         file2a = tempfile.NamedTemporaryFile()
-        file2a.write('a' * (5 * 2 ** 20))
+        file2a.write(b'a' * (5 * 2 ** 20))
         file2a.seek(0)
 
         response = self.client.post('/file_uploads/getlist_count/', {
@@ -299,14 +299,14 @@ class FileUploadTests(TestCase):
         # this test would fail.  So we need to know exactly what kind of error
         # it raises when there is an attempt to read more than the available bytes:
         try:
-            client.FakePayload('a').read(2)
+            client.FakePayload(b'a').read(2)
         except Exception as reference_error:
             pass
 
         # install the custom handler that tries to access request.POST
         self.client.handler = POSTAccessingHandler()
 
-        with open(__file__) as fp:
+        with open(__file__, 'rb') as fp:
             post_data = {
                 'name': 'Ringo',
                 'file_field': fp,
@@ -374,7 +374,7 @@ class DirectoryCreationTests(unittest.TestCase):
         """Permission errors are not swallowed"""
         os.chmod(temp_storage.location, 0500)
         try:
-            self.obj.testfile.save('foo.txt', SimpleUploadedFile('foo.txt', 'x'))
+            self.obj.testfile.save('foo.txt', SimpleUploadedFile('foo.txt', b'x'))
         except OSError as err:
             self.assertEqual(err.errno, errno.EACCES)
         except Exception:
@@ -383,9 +383,9 @@ class DirectoryCreationTests(unittest.TestCase):
     def test_not_a_directory(self):
         """The correct IOError is raised when the upload directory name exists but isn't a directory"""
         # Create a file with the upload directory name
-        open(UPLOAD_TO, 'w').close()
+        open(UPLOAD_TO, 'wb').close()
         try:
-            self.obj.testfile.save('foo.txt', SimpleUploadedFile('foo.txt', 'x'))
+            self.obj.testfile.save('foo.txt', SimpleUploadedFile('foo.txt', b'x'))
         except IOError as err:
             # The test needs to be done on a specific string as IOError
             # is raised even without the patch (just not early enough)

+ 9 - 9
tests/regressiontests/forms/tests/fields.py

@@ -540,27 +540,27 @@ class FieldsTests(SimpleTestCase):
         self.assertRaisesMessage(ValidationError, "[u'This field is required.']", f.clean, None)
         self.assertRaisesMessage(ValidationError, "[u'This field is required.']", f.clean, None, '')
         self.assertEqual('files/test2.pdf', f.clean(None, 'files/test2.pdf'))
-        self.assertRaisesMessage(ValidationError, "[u'No file was submitted. Check the encoding type on the form.']", f.clean, SimpleUploadedFile('', ''))
-        self.assertRaisesMessage(ValidationError, "[u'No file was submitted. Check the encoding type on the form.']", f.clean, SimpleUploadedFile('', ''), '')
+        self.assertRaisesMessage(ValidationError, "[u'No file was submitted. Check the encoding type on the form.']", f.clean, SimpleUploadedFile('', b''))
+        self.assertRaisesMessage(ValidationError, "[u'No file was submitted. Check the encoding type on the form.']", f.clean, SimpleUploadedFile('', b''), '')
         self.assertEqual('files/test3.pdf', f.clean(None, 'files/test3.pdf'))
         self.assertRaisesMessage(ValidationError, "[u'No file was submitted. Check the encoding type on the form.']", f.clean, 'some content that is not a file')
         self.assertRaisesMessage(ValidationError, "[u'The submitted file is empty.']", f.clean, SimpleUploadedFile('name', None))
-        self.assertRaisesMessage(ValidationError, "[u'The submitted file is empty.']", f.clean, SimpleUploadedFile('name', ''))
-        self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', 'Some File Content'))))
-        self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', 'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह'))))
-        self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', 'Some File Content'), 'files/test4.pdf')))
+        self.assertRaisesMessage(ValidationError, "[u'The submitted file is empty.']", f.clean, SimpleUploadedFile('name', b''))
+        self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', b'Some File Content'))))
+        self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', u'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह'.encode('utf-8')))))
+        self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', b'Some File Content'), 'files/test4.pdf')))
 
     def test_filefield_2(self):
         f = FileField(max_length = 5)
-        self.assertRaisesMessage(ValidationError, "[u'Ensure this filename has at most 5 characters (it has 18).']", f.clean, SimpleUploadedFile('test_maxlength.txt', 'hello world'))
+        self.assertRaisesMessage(ValidationError, "[u'Ensure this filename has at most 5 characters (it has 18).']", f.clean, SimpleUploadedFile('test_maxlength.txt', b'hello world'))
         self.assertEqual('files/test1.pdf', f.clean('', 'files/test1.pdf'))
         self.assertEqual('files/test2.pdf', f.clean(None, 'files/test2.pdf'))
-        self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', 'Some File Content'))))
+        self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', b'Some File Content'))))
 
     def test_filefield_3(self):
         f = FileField(allow_empty_file=True)
         self.assertEqual(SimpleUploadedFile,
-                         type(f.clean(SimpleUploadedFile('name', ''))))
+                         type(f.clean(SimpleUploadedFile('name', b''))))
 
     # URLField ##################################################################
 

+ 3 - 3
tests/regressiontests/forms/tests/forms.py

@@ -1463,17 +1463,17 @@ class FormsTestCase(TestCase):
         f = FileForm(data={}, files={}, auto_id=False)
         self.assertHTMLEqual(f.as_table(), '<tr><th>File1:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="file" name="file1" /></td></tr>')
 
-        f = FileForm(data={}, files={'file1': SimpleUploadedFile('name', '')}, auto_id=False)
+        f = FileForm(data={}, files={'file1': SimpleUploadedFile('name', b'')}, auto_id=False)
         self.assertHTMLEqual(f.as_table(), '<tr><th>File1:</th><td><ul class="errorlist"><li>The submitted file is empty.</li></ul><input type="file" name="file1" /></td></tr>')
 
         f = FileForm(data={}, files={'file1': 'something that is not a file'}, auto_id=False)
         self.assertHTMLEqual(f.as_table(), '<tr><th>File1:</th><td><ul class="errorlist"><li>No file was submitted. Check the encoding type on the form.</li></ul><input type="file" name="file1" /></td></tr>')
 
-        f = FileForm(data={}, files={'file1': SimpleUploadedFile('name', 'some content')}, auto_id=False)
+        f = FileForm(data={}, files={'file1': SimpleUploadedFile('name', b'some content')}, auto_id=False)
         self.assertHTMLEqual(f.as_table(), '<tr><th>File1:</th><td><input type="file" name="file1" /></td></tr>')
         self.assertTrue(f.is_valid())
 
-        f = FileForm(data={}, files={'file1': SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', 'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह')}, auto_id=False)
+        f = FileForm(data={}, files={'file1': SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', u'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह'.encode('utf-8'))}, auto_id=False)
         self.assertHTMLEqual(f.as_table(), '<tr><th>File1:</th><td><input type="file" name="file1" /></td></tr>')
 
     def test_basic_processing_in_view(self):

+ 3 - 3
tests/regressiontests/forms/tests/models.py

@@ -106,7 +106,7 @@ class ModelFormCallableModelDefault(TestCase):
 class FormsModelTestCase(TestCase):
     def test_unicode_filename(self):
         # FileModel with unicode filename and data #########################
-        f = FileForm(data={}, files={'file1': SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', 'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह')}, auto_id=False)
+        f = FileForm(data={}, files={'file1': SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', u'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह'.encode('utf-8'))}, auto_id=False)
         self.assertTrue(f.is_valid())
         self.assertTrue('file1' in f.cleaned_data)
         m = FileModel.objects.create(file=f.cleaned_data['file1'])
@@ -177,7 +177,7 @@ class RelatedModelFormTests(TestCase):
         class Meta:
             model=A
 
-        self.assertRaises(ValueError, ModelFormMetaclass, 'Form', (ModelForm,), {'Meta': Meta})
+        self.assertRaises(ValueError, ModelFormMetaclass, b'Form', (ModelForm,), {'Meta': Meta})
 
         class B(models.Model):
             pass
@@ -195,4 +195,4 @@ class RelatedModelFormTests(TestCase):
         class Meta:
             model=A
 
-        self.assertTrue(issubclass(ModelFormMetaclass('Form', (ModelForm,), {'Meta': Meta}), ModelForm))
+        self.assertTrue(issubclass(ModelFormMetaclass(b'Form', (ModelForm,), {'Meta': Meta}), ModelForm))

+ 3 - 2
tests/regressiontests/forms/tests/regressions.py

@@ -54,10 +54,11 @@ class FormsRegressionsTestCase(TestCase):
 
         # Testing choice validation with UTF-8 bytestrings as input (these are the
         # Russian abbreviations "мес." and "шт.".
-        UNITS = (('\xd0\xbc\xd0\xb5\xd1\x81.', '\xd0\xbc\xd0\xb5\xd1\x81.'), ('\xd1\x88\xd1\x82.', '\xd1\x88\xd1\x82.'))
+        UNITS = ((b'\xd0\xbc\xd0\xb5\xd1\x81.', b'\xd0\xbc\xd0\xb5\xd1\x81.'),
+                 (b'\xd1\x88\xd1\x82.', b'\xd1\x88\xd1\x82.'))
         f = ChoiceField(choices=UNITS)
         self.assertEqual(f.clean(u'\u0448\u0442.'), u'\u0448\u0442.')
-        self.assertEqual(f.clean('\xd1\x88\xd1\x82.'), u'\u0448\u0442.')
+        self.assertEqual(f.clean(b'\xd1\x88\xd1\x82.'), u'\u0448\u0442.')
 
         # Translated error messages used to be buggy.
         with override('ru'):

+ 1 - 1
tests/regressiontests/forms/tests/widgets.py

@@ -1182,7 +1182,7 @@ class ClearableFileInputTests(TestCase):
         """
         widget = ClearableFileInput()
         widget.is_required = True
-        f = SimpleUploadedFile('something.txt', 'content')
+        f = SimpleUploadedFile('something.txt', b'content')
         self.assertEqual(widget.value_from_datadict(
                 data={'myfile-clear': True},
                 files={'myfile': f},

+ 1 - 1
tests/regressiontests/handlers/tests.py

@@ -28,7 +28,7 @@ class HandlerTests(unittest.TestCase):
     def test_bad_path_info(self):
         """Tests for bug #15672 ('request' referenced before assignment)"""
         environ = RequestFactory().get('/').environ
-        environ['PATH_INFO'] = '\xed'
+        environ['PATH_INFO'] = b'\xed'
         handler = WSGIHandler()
         response = handler(environ, lambda *a, **k: None)
         self.assertEqual(response.status_code, 400)

+ 5 - 5
tests/regressiontests/httpwrappers/tests.py

@@ -174,7 +174,7 @@ class QueryDictTests(unittest.TestCase):
         QueryDicts must be able to handle invalid input encoding (in this
         case, bad UTF-8 encoding).
         """
-        q = QueryDict('foo=bar&foo=\xff')
+        q = QueryDict(b'foo=bar&foo=\xff')
         self.assertEqual(q['foo'], u'\ufffd')
         self.assertEqual(q.getlist('foo'), [u'bar', u'\ufffd'])
 
@@ -198,7 +198,7 @@ class QueryDictTests(unittest.TestCase):
 
     def test_non_default_encoding(self):
         """#13572 - QueryDict with a non-default encoding"""
-        q = QueryDict('sbb=one', encoding='rot_13')
+        q = QueryDict(b'sbb=one', encoding='rot_13')
         self.assertEqual(q.encoding , 'rot_13' )
         self.assertEqual(q.items() , [(u'foo', u'bar')] )
         self.assertEqual(q.urlencode() , 'sbb=one' )
@@ -285,8 +285,8 @@ class HttpResponseTests(unittest.TestCase):
             except StopIteration:
                 break
         #'\xde\x9e' == unichr(1950).encode('utf-8')
-        self.assertEqual(result, ['1', '2', '3', '\xde\x9e'])
-        self.assertEqual(r.content, '123\xde\x9e')
+        self.assertEqual(result, ['1', '2', '3', b'\xde\x9e'])
+        self.assertEqual(r.content, b'123\xde\x9e')
 
         #with Content-Encoding header
         r = HttpResponse([1,1,2,4,8])
@@ -321,7 +321,7 @@ class CookieTests(unittest.TestCase):
         Test that we haven't broken normal encoding
         """
         c = SimpleCookie()
-        c['test'] = "\xf0"
+        c['test'] = b"\xf0"
         c2 = SimpleCookie()
         c2.load(c.output())
         self.assertEqual(c['test'].value, c2['test'].value)

+ 1 - 1
tests/regressiontests/i18n/tests.py

@@ -230,7 +230,7 @@ class TranslationTests(TestCase):
         """
         Translating a string requiring no auto-escaping shouldn't change the "safe" status.
         """
-        s = mark_safe('Password')
+        s = mark_safe(b'Password')
         self.assertEqual(SafeString, type(s))
         with translation.override('de', deactivate=True):
             self.assertEqual(SafeUnicode, type(ugettext(s)))

+ 1 - 1
tests/regressiontests/localflavor/mk/tests.py

@@ -92,7 +92,7 @@ class MKLocalFlavorTests(SimpleTestCase):
         """
         Test that the empty option is there.
         """
-        municipality_select_html = """\
+        municipality_select_html = b"""\
 <select name="municipality" id="id_municipality">
 <option value="">---------</option>
 <option value="AD">Aerodrom</option>

+ 18 - 18
tests/regressiontests/mail/tests.py

@@ -86,7 +86,7 @@ class MailTests(TestCase):
         """
         headers = {"date": "Fri, 09 Nov 2001 01:08:47 -0000", "Message-ID": "foo"}
         email = EmailMessage('subject', 'content', 'from@example.com', ['to@example.com'], headers=headers)
-        self.assertEqual(email.message().as_string(), 'Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nSubject: subject\nFrom: from@example.com\nTo: to@example.com\ndate: Fri, 09 Nov 2001 01:08:47 -0000\nMessage-ID: foo\n\ncontent')
+        self.assertEqual(email.message().as_string(), b'Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nSubject: subject\nFrom: from@example.com\nTo: to@example.com\ndate: Fri, 09 Nov 2001 01:08:47 -0000\nMessage-ID: foo\n\ncontent')
 
     def test_from_header(self):
         """
@@ -168,7 +168,7 @@ class MailTests(TestCase):
         email = EmailMessage('Subject', 'Firstname Sürname is a great guy.', 'from@example.com', ['other@example.com'])
         email.encoding = 'iso-8859-1'
         message = email.message()
-        self.assertTrue(message.as_string().startswith('Content-Type: text/plain; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\nSubject: Subject\nFrom: from@example.com\nTo: other@example.com'))
+        self.assertTrue(message.as_string().startswith(b'Content-Type: text/plain; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\nSubject: Subject\nFrom: from@example.com\nTo: other@example.com'))
         self.assertEqual(message.get_payload(), 'Firstname S=FCrname is a great guy.')
 
         # Make sure MIME attachments also works correctly with other encodings than utf-8
@@ -177,8 +177,8 @@ class MailTests(TestCase):
         msg = EmailMultiAlternatives('Subject', text_content, 'from@example.com', ['to@example.com'])
         msg.encoding = 'iso-8859-1'
         msg.attach_alternative(html_content, "text/html")
-        self.assertEqual(msg.message().get_payload(0).as_string(), 'Content-Type: text/plain; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\nFirstname S=FCrname is a great guy.')
-        self.assertEqual(msg.message().get_payload(1).as_string(), 'Content-Type: text/html; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\n<p>Firstname S=FCrname is a <strong>great</strong> guy.</p>')
+        self.assertEqual(msg.message().get_payload(0).as_string(), b'Content-Type: text/plain; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\nFirstname S=FCrname is a great guy.')
+        self.assertEqual(msg.message().get_payload(1).as_string(), b'Content-Type: text/html; charset="iso-8859-1"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\n<p>Firstname S=FCrname is a <strong>great</strong> guy.</p>')
 
     def test_attachments(self):
         """Regression test for #9367"""
@@ -188,7 +188,7 @@ class MailTests(TestCase):
         html_content = '<p>This is an <strong>important</strong> message.</p>'
         msg = EmailMultiAlternatives(subject, text_content, from_email, [to], headers=headers)
         msg.attach_alternative(html_content, "text/html")
-        msg.attach("an attachment.pdf", "%PDF-1.4.%...", mimetype="application/pdf")
+        msg.attach("an attachment.pdf", b"%PDF-1.4.%...", mimetype="application/pdf")
         msg_str = msg.message().as_string()
         message = email.message_from_string(msg_str)
         self.assertTrue(message.is_multipart())
@@ -205,7 +205,7 @@ class MailTests(TestCase):
         content = 'This is the message.'
         msg = EmailMessage(subject, content, from_email, [to], headers=headers)
         # Unicode in file name
-        msg.attach(u"une pièce jointe.pdf", "%PDF-1.4.%...", mimetype="application/pdf")
+        msg.attach(u"une pièce jointe.pdf", b"%PDF-1.4.%...", mimetype="application/pdf")
         msg_str = msg.message().as_string()
         message = email.message_from_string(msg_str)
         payload = message.get_payload()
@@ -289,31 +289,31 @@ class MailTests(TestCase):
         # Regression for #13433 - Make sure that EmailMessage doesn't mangle
         # 'From ' in message body.
         email = EmailMessage('Subject', 'From the future', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'})
-        self.assertFalse('>From the future' in email.message().as_string())
+        self.assertFalse(b'>From the future' in email.message().as_string())
 
     def test_dont_base64_encode(self):
         # Ticket #3472
         # Shouldn't use Base64 encoding at all
         msg = EmailMessage('Subject', 'UTF-8 encoded body', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'})
-        self.assertFalse('Content-Transfer-Encoding: base64' in msg.message().as_string())
+        self.assertFalse(b'Content-Transfer-Encoding: base64' in msg.message().as_string())
 
         # Ticket #11212
         # Shouldn't use quoted printable, should detect it can represent content with 7 bit data
         msg = EmailMessage('Subject', 'Body with only ASCII characters.', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'})
         s = msg.message().as_string()
-        self.assertFalse('Content-Transfer-Encoding: quoted-printable' in s)
-        self.assertTrue('Content-Transfer-Encoding: 7bit' in s)
+        self.assertFalse(b'Content-Transfer-Encoding: quoted-printable' in s)
+        self.assertTrue(b'Content-Transfer-Encoding: 7bit' in s)
 
         # Shouldn't use quoted printable, should detect it can represent content with 8 bit data
         msg = EmailMessage('Subject', 'Body with latin characters: àáä.', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'})
         s = msg.message().as_string()
-        self.assertFalse('Content-Transfer-Encoding: quoted-printable' in s)
-        self.assertTrue('Content-Transfer-Encoding: 8bit' in s)
+        self.assertFalse(b'Content-Transfer-Encoding: quoted-printable' in s)
+        self.assertTrue(b'Content-Transfer-Encoding: 8bit' in s)
 
         msg = EmailMessage('Subject', u'Body with non latin characters: А Б В Г Д Е Ж Ѕ З И І К Л М Н О П.', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'})
         s = msg.message().as_string()
-        self.assertFalse('Content-Transfer-Encoding: quoted-printable' in s)
-        self.assertTrue('Content-Transfer-Encoding: 8bit' in s)
+        self.assertFalse(b'Content-Transfer-Encoding: quoted-printable' in s)
+        self.assertTrue(b'Content-Transfer-Encoding: 8bit' in s)
 
 
 class BaseEmailBackendTests(object):
@@ -438,7 +438,7 @@ class BaseEmailBackendTests(object):
         email = EmailMessage('Subject', 'Content', 'from@example.com', ['to@example.com'], cc=['cc@example.com'])
         mail.get_connection().send_messages([email])
         message = self.get_the_message()
-        self.assertStartsWith(message.as_string(), 'Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nSubject: Subject\nFrom: from@example.com\nTo: to@example.com\nCc: cc@example.com\nDate: ')
+        self.assertStartsWith(message.as_string(), b'Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nSubject: Subject\nFrom: from@example.com\nTo: to@example.com\nCc: cc@example.com\nDate: ')
 
     def test_idn_send(self):
         """
@@ -517,8 +517,8 @@ class FileBackendTests(BaseEmailBackendTests, TestCase):
     def get_mailbox_content(self):
         messages = []
         for filename in os.listdir(self.tmp_dir):
-            with open(os.path.join(self.tmp_dir, filename)) as fp:
-                session = fp.read().split('\n' + ('-' * 79) + '\n')
+            with open(os.path.join(self.tmp_dir, filename), 'rb') as fp:
+                session = fp.read().split(b'\n' + (b'-' * 79) + b'\n')
             messages.extend(email.message_from_string(m) for m in session if m)
         return messages
 
@@ -569,7 +569,7 @@ class ConsoleBackendTests(BaseEmailBackendTests, TestCase):
         self.stream = sys.stdout = StringIO()
 
     def get_mailbox_content(self):
-        messages = self.stream.getvalue().split('\n' + ('-' * 79) + '\n')
+        messages = self.stream.getvalue().split(b'\n' + (b'-' * 79) + b'\n')
         return [email.message_from_string(m) for m in messages if m]
 
     def test_console_stream_kwarg(self):

+ 3 - 3
tests/regressiontests/model_forms_regress/tests.py

@@ -394,7 +394,7 @@ class FileFieldTests(unittest.TestCase):
         form = DocumentForm()
         self.assertTrue('name="myfile"' in unicode(form))
         self.assertTrue('myfile-clear' not in unicode(form))
-        form = DocumentForm(files={'myfile': SimpleUploadedFile('something.txt', 'content')})
+        form = DocumentForm(files={'myfile': SimpleUploadedFile('something.txt', b'content')})
         self.assertTrue(form.is_valid())
         doc = form.save(commit=False)
         self.assertEqual(doc.myfile.name, 'something.txt')
@@ -411,11 +411,11 @@ class FileFieldTests(unittest.TestCase):
         includes the current file and the clear checkbox.
 
         """
-        form = DocumentForm(files={'myfile': SimpleUploadedFile('something.txt', 'content')})
+        form = DocumentForm(files={'myfile': SimpleUploadedFile('something.txt', b'content')})
         self.assertTrue(form.is_valid())
         doc = form.save(commit=False)
         form = DocumentForm(instance=doc,
-                            files={'myfile': SimpleUploadedFile('something.txt', 'content')},
+                            files={'myfile': SimpleUploadedFile('something.txt', b'content')},
                             data={'myfile-clear': 'true'})
         self.assertTrue(not form.is_valid())
         self.assertEqual(form.errors['myfile'],

+ 44 - 44
tests/regressiontests/requests/tests.py

@@ -204,91 +204,91 @@ class RequestsTests(unittest.TestCase):
 
     def test_limited_stream(self):
         # Read all of a limited stream
-        stream = LimitedStream(StringIO('test'), 2)
-        self.assertEqual(stream.read(), 'te')
+        stream = LimitedStream(StringIO(b'test'), 2)
+        self.assertEqual(stream.read(), b'te')
         # Reading again returns nothing.
-        self.assertEqual(stream.read(), '')
+        self.assertEqual(stream.read(), b'')
 
         # Read a number of characters greater than the stream has to offer
-        stream = LimitedStream(StringIO('test'), 2)
-        self.assertEqual(stream.read(5), 'te')
+        stream = LimitedStream(StringIO(b'test'), 2)
+        self.assertEqual(stream.read(5), b'te')
         # Reading again returns nothing.
-        self.assertEqual(stream.readline(5), '')
+        self.assertEqual(stream.readline(5), b'')
 
         # Read sequentially from a stream
-        stream = LimitedStream(StringIO('12345678'), 8)
-        self.assertEqual(stream.read(5), '12345')
-        self.assertEqual(stream.read(5), '678')
+        stream = LimitedStream(StringIO(b'12345678'), 8)
+        self.assertEqual(stream.read(5), b'12345')
+        self.assertEqual(stream.read(5), b'678')
         # Reading again returns nothing.
-        self.assertEqual(stream.readline(5), '')
+        self.assertEqual(stream.readline(5), b'')
 
         # Read lines from a stream
-        stream = LimitedStream(StringIO('1234\n5678\nabcd\nefgh\nijkl'), 24)
+        stream = LimitedStream(StringIO(b'1234\n5678\nabcd\nefgh\nijkl'), 24)
         # Read a full line, unconditionally
-        self.assertEqual(stream.readline(), '1234\n')
+        self.assertEqual(stream.readline(), b'1234\n')
         # Read a number of characters less than a line
-        self.assertEqual(stream.readline(2), '56')
+        self.assertEqual(stream.readline(2), b'56')
         # Read the rest of the partial line
-        self.assertEqual(stream.readline(), '78\n')
+        self.assertEqual(stream.readline(), b'78\n')
         # Read a full line, with a character limit greater than the line length
-        self.assertEqual(stream.readline(6), 'abcd\n')
+        self.assertEqual(stream.readline(6), b'abcd\n')
         # Read the next line, deliberately terminated at the line end
-        self.assertEqual(stream.readline(4), 'efgh')
+        self.assertEqual(stream.readline(4), b'efgh')
         # Read the next line... just the line end
-        self.assertEqual(stream.readline(), '\n')
+        self.assertEqual(stream.readline(), b'\n')
         # Read everything else.
-        self.assertEqual(stream.readline(), 'ijkl')
+        self.assertEqual(stream.readline(), b'ijkl')
 
         # Regression for #15018
         # If a stream contains a newline, but the provided length
         # is less than the number of provided characters, the newline
         # doesn't reset the available character count
-        stream = LimitedStream(StringIO('1234\nabcdef'), 9)
-        self.assertEqual(stream.readline(10), '1234\n')
-        self.assertEqual(stream.readline(3), 'abc')
+        stream = LimitedStream(StringIO(b'1234\nabcdef'), 9)
+        self.assertEqual(stream.readline(10), b'1234\n')
+        self.assertEqual(stream.readline(3), b'abc')
         # Now expire the available characters
-        self.assertEqual(stream.readline(3), 'd')
+        self.assertEqual(stream.readline(3), b'd')
         # Reading again returns nothing.
-        self.assertEqual(stream.readline(2), '')
+        self.assertEqual(stream.readline(2), b'')
 
         # Same test, but with read, not readline.
-        stream = LimitedStream(StringIO('1234\nabcdef'), 9)
-        self.assertEqual(stream.read(6), '1234\na')
-        self.assertEqual(stream.read(2), 'bc')
-        self.assertEqual(stream.read(2), 'd')
-        self.assertEqual(stream.read(2), '')
-        self.assertEqual(stream.read(), '')
+        stream = LimitedStream(StringIO(b'1234\nabcdef'), 9)
+        self.assertEqual(stream.read(6), b'1234\na')
+        self.assertEqual(stream.read(2), b'bc')
+        self.assertEqual(stream.read(2), b'd')
+        self.assertEqual(stream.read(2), b'')
+        self.assertEqual(stream.read(), b'')
 
     def test_stream(self):
-        payload = 'name=value'
+        payload = b'name=value'
         request = WSGIRequest({'REQUEST_METHOD': 'POST',
                                'CONTENT_LENGTH': len(payload),
                                'wsgi.input': StringIO(payload)})
-        self.assertEqual(request.read(), 'name=value')
+        self.assertEqual(request.read(), b'name=value')
 
     def test_read_after_value(self):
         """
         Reading from request is allowed after accessing request contents as
         POST or body.
         """
-        payload = 'name=value'
+        payload = b'name=value'
         request = WSGIRequest({'REQUEST_METHOD': 'POST',
                                'CONTENT_LENGTH': len(payload),
                                'wsgi.input': StringIO(payload)})
         self.assertEqual(request.POST, {u'name': [u'value']})
-        self.assertEqual(request.body, 'name=value')
-        self.assertEqual(request.read(), 'name=value')
+        self.assertEqual(request.body, b'name=value')
+        self.assertEqual(request.read(), b'name=value')
 
     def test_value_after_read(self):
         """
         Construction of POST or body is not allowed after reading
         from request.
         """
-        payload = 'name=value'
+        payload = b'name=value'
         request = WSGIRequest({'REQUEST_METHOD': 'POST',
                                'CONTENT_LENGTH': len(payload),
                                'wsgi.input': StringIO(payload)})
-        self.assertEqual(request.read(2), 'na')
+        self.assertEqual(request.read(2), b'na')
         self.assertRaises(Exception, lambda: request.body)
         self.assertEqual(request.POST, {})
 
@@ -335,17 +335,17 @@ class RequestsTests(unittest.TestCase):
         self.assertEqual(request.POST, {})
 
     def test_read_by_lines(self):
-        payload = 'name=value'
+        payload = b'name=value'
         request = WSGIRequest({'REQUEST_METHOD': 'POST',
                                'CONTENT_LENGTH': len(payload),
                                'wsgi.input': StringIO(payload)})
-        self.assertEqual(list(request), ['name=value'])
+        self.assertEqual(list(request), [b'name=value'])
 
     def test_POST_after_body_read(self):
         """
         POST should be populated even if body is read first
         """
-        payload = 'name=value'
+        payload = b'name=value'
         request = WSGIRequest({'REQUEST_METHOD': 'POST',
                                'CONTENT_LENGTH': len(payload),
                                'wsgi.input': StringIO(payload)})
@@ -357,12 +357,12 @@ class RequestsTests(unittest.TestCase):
         POST should be populated even if body is read first, and then
         the stream is read second.
         """
-        payload = 'name=value'
+        payload = b'name=value'
         request = WSGIRequest({'REQUEST_METHOD': 'POST',
                                'CONTENT_LENGTH': len(payload),
                                'wsgi.input': StringIO(payload)})
         raw_data = request.body
-        self.assertEqual(request.read(1), u'n')
+        self.assertEqual(request.read(1), b'n')
         self.assertEqual(request.POST, {u'name': [u'value']})
 
     def test_POST_after_body_read_and_stream_read_multipart(self):
@@ -383,14 +383,14 @@ class RequestsTests(unittest.TestCase):
                                'wsgi.input': StringIO(payload)})
         raw_data = request.body
         # Consume enough data to mess up the parsing:
-        self.assertEqual(request.read(13), u'--boundary\r\nC')
+        self.assertEqual(request.read(13), b'--boundary\r\nC')
         self.assertEqual(request.POST, {u'name': [u'value']})
 
     def test_raw_post_data_returns_body(self):
         """
         HttpRequest.raw_post_body should be the same as HttpRequest.body
         """
-        payload = 'Hello There!'
+        payload = b'Hello There!'
         request = WSGIRequest({
             'REQUEST_METHOD': 'POST',
             'CONTENT_LENGTH': len(payload),
@@ -409,7 +409,7 @@ class RequestsTests(unittest.TestCase):
             def read(self, len=0):
                 raise IOError("kaboom!")
 
-        payload = 'name=value'
+        payload = b'name=value'
         request = WSGIRequest({'REQUEST_METHOD': 'POST',
                                'CONTENT_LENGTH': len(payload),
                                'wsgi.input': ExplodingStringIO(payload)})

+ 3 - 3
tests/regressiontests/signing/tests.py

@@ -12,8 +12,8 @@ class TestSigner(TestCase):
         signer = signing.Signer('predictable-secret')
         signer2 = signing.Signer('predictable-secret2')
         for s in (
-            'hello',
-            '3098247:529:087:',
+            b'hello',
+            b'3098247:529:087:',
             u'\u2019'.encode('utf-8'),
         ):
             self.assertEqual(
@@ -69,7 +69,7 @@ class TestSigner(TestCase):
         "dumps and loads be reversible for any JSON serializable object"
         objects = (
             ['a', 'list'],
-            'a string',
+            b'a string',
             u'a unicode string \u2019',
             {'a': 'dictionary'},
         )

+ 26 - 26
tests/regressiontests/staticfiles_tests/tests.py

@@ -387,8 +387,8 @@ class TestCollectionCachedStorage(BaseCollectionTestCase,
         self.assertEqual(relpath, "cached/styles.93b1147e8552.css")
         with storage.staticfiles_storage.open(relpath) as relfile:
             content = relfile.read()
-            self.assertNotIn("cached/other.css", content)
-            self.assertIn("other.d41d8cd98f00.css", content)
+            self.assertNotIn(b"cached/other.css", content)
+            self.assertIn(b"other.d41d8cd98f00.css", content)
 
     def test_path_with_querystring(self):
         relpath = self.cached_file_path("cached/styles.css?spam=eggs")
@@ -397,8 +397,8 @@ class TestCollectionCachedStorage(BaseCollectionTestCase,
         with storage.staticfiles_storage.open(
                 "cached/styles.93b1147e8552.css") as relfile:
             content = relfile.read()
-            self.assertNotIn("cached/other.css", content)
-            self.assertIn("other.d41d8cd98f00.css", content)
+            self.assertNotIn(b"cached/other.css", content)
+            self.assertIn(b"other.d41d8cd98f00.css", content)
 
     def test_path_with_fragment(self):
         relpath = self.cached_file_path("cached/styles.css#eggs")
@@ -406,62 +406,62 @@ class TestCollectionCachedStorage(BaseCollectionTestCase,
         with storage.staticfiles_storage.open(
                 "cached/styles.93b1147e8552.css") as relfile:
             content = relfile.read()
-            self.assertNotIn("cached/other.css", content)
-            self.assertIn("other.d41d8cd98f00.css", content)
+            self.assertNotIn(b"cached/other.css", content)
+            self.assertIn(b"other.d41d8cd98f00.css", content)
 
     def test_path_with_querystring_and_fragment(self):
         relpath = self.cached_file_path("cached/css/fragments.css")
         self.assertEqual(relpath, "cached/css/fragments.75433540b096.css")
         with storage.staticfiles_storage.open(relpath) as relfile:
             content = relfile.read()
-            self.assertIn('fonts/font.a4b0478549d0.eot?#iefix', content)
-            self.assertIn('fonts/font.b8d603e42714.svg#webfontIyfZbseF', content)
-            self.assertIn('data:font/woff;charset=utf-8;base64,d09GRgABAAAAADJoAA0AAAAAR2QAAQAAAAAAAAAAAAA', content)
-            self.assertIn('#default#VML', content)
+            self.assertIn(b'fonts/font.a4b0478549d0.eot?#iefix', content)
+            self.assertIn(b'fonts/font.b8d603e42714.svg#webfontIyfZbseF', content)
+            self.assertIn(b'data:font/woff;charset=utf-8;base64,d09GRgABAAAAADJoAA0AAAAAR2QAAQAAAAAAAAAAAAA', content)
+            self.assertIn(b'#default#VML', content)
 
     def test_template_tag_absolute(self):
         relpath = self.cached_file_path("cached/absolute.css")
         self.assertEqual(relpath, "cached/absolute.23f087ad823a.css")
         with storage.staticfiles_storage.open(relpath) as relfile:
             content = relfile.read()
-            self.assertNotIn("/static/cached/styles.css", content)
-            self.assertIn("/static/cached/styles.93b1147e8552.css", content)
-            self.assertIn('/static/cached/img/relative.acae32e4532b.png', content)
+            self.assertNotIn(b"/static/cached/styles.css", content)
+            self.assertIn(b"/static/cached/styles.93b1147e8552.css", content)
+            self.assertIn(b'/static/cached/img/relative.acae32e4532b.png', content)
 
     def test_template_tag_denorm(self):
         relpath = self.cached_file_path("cached/denorm.css")
         self.assertEqual(relpath, "cached/denorm.c5bd139ad821.css")
         with storage.staticfiles_storage.open(relpath) as relfile:
             content = relfile.read()
-            self.assertNotIn("..//cached///styles.css", content)
-            self.assertIn("../cached/styles.93b1147e8552.css", content)
-            self.assertNotIn("url(img/relative.png )", content)
-            self.assertIn('url("img/relative.acae32e4532b.png', content)
+            self.assertNotIn(b"..//cached///styles.css", content)
+            self.assertIn(b"../cached/styles.93b1147e8552.css", content)
+            self.assertNotIn(b"url(img/relative.png )", content)
+            self.assertIn(b'url("img/relative.acae32e4532b.png', content)
 
     def test_template_tag_relative(self):
         relpath = self.cached_file_path("cached/relative.css")
         self.assertEqual(relpath, "cached/relative.2217ea7273c2.css")
         with storage.staticfiles_storage.open(relpath) as relfile:
             content = relfile.read()
-            self.assertNotIn("../cached/styles.css", content)
-            self.assertNotIn('@import "styles.css"', content)
-            self.assertNotIn('url(img/relative.png)', content)
-            self.assertIn('url("img/relative.acae32e4532b.png")', content)
-            self.assertIn("../cached/styles.93b1147e8552.css", content)
+            self.assertNotIn(b"../cached/styles.css", content)
+            self.assertNotIn(b'@import "styles.css"', content)
+            self.assertNotIn(b'url(img/relative.png)', content)
+            self.assertIn(b'url("img/relative.acae32e4532b.png")', content)
+            self.assertIn(b"../cached/styles.93b1147e8552.css", content)
 
     def test_template_tag_deep_relative(self):
         relpath = self.cached_file_path("cached/css/window.css")
         self.assertEqual(relpath, "cached/css/window.9db38d5169f3.css")
         with storage.staticfiles_storage.open(relpath) as relfile:
             content = relfile.read()
-            self.assertNotIn('url(img/window.png)', content)
-            self.assertIn('url("img/window.acae32e4532b.png")', content)
+            self.assertNotIn(b'url(img/window.png)', content)
+            self.assertIn(b'url("img/window.acae32e4532b.png")', content)
 
     def test_template_tag_url(self):
         relpath = self.cached_file_path("cached/url.css")
         self.assertEqual(relpath, "cached/url.615e21601e4b.css")
         with storage.staticfiles_storage.open(relpath) as relfile:
-            self.assertIn("https://", relfile.read())
+            self.assertIn(b"https://", relfile.read())
 
     def test_cache_invalidation(self):
         name = "cached/styles.css"
@@ -508,7 +508,7 @@ class TestCollectionCachedStorage(BaseCollectionTestCase,
         """
         Handle cache key creation correctly, see #17861.
         """
-        name = "/some crazy/long filename/ with spaces Here and ?#%#$/other/stuff/some crazy/long filename/ with spaces Here and ?#%#$/other/stuff/some crazy/long filename/ with spaces Here and ?#%#$/other/stuff/some crazy/long filename/ with spaces Here and ?#%#$/other/stuff/some crazy/long filename/ with spaces Here and ?#%#$/other/stuff/some crazy/" + chr(22) + chr(180)
+        name = b"/some crazy/long filename/ with spaces Here and ?#%#$/other/stuff/some crazy/long filename/ with spaces Here and ?#%#$/other/stuff/some crazy/long filename/ with spaces Here and ?#%#$/other/stuff/some crazy/long filename/ with spaces Here and ?#%#$/other/stuff/some crazy/long filename/ with spaces Here and ?#%#$/other/stuff/some crazy/" + chr(22) + chr(180)
         cache_key = storage.staticfiles_storage.cache_key(name)
         cache_validator = BaseCache({})
         cache_validator.validate_key(cache_key)

+ 1 - 1
tests/regressiontests/string_lookup/tests.py

@@ -54,7 +54,7 @@ class StringLookupTests(TestCase):
         self.assertEqual(Foo.objects.get(friend__contains=u'\xe7'), fx)
 
         # We can also do the above query using UTF-8 strings.
-        self.assertEqual(Foo.objects.get(friend__contains='\xc3\xa7'), fx)
+        self.assertEqual(Foo.objects.get(friend__contains=b'\xc3\xa7'), fx)
 
     def test_queries_on_textfields(self):
         """

+ 7 - 7
tests/regressiontests/templates/tests.py

@@ -192,17 +192,17 @@ class Templates(unittest.TestCase):
         test_template_sources('../dir1blah', template_dirs, [])
 
         # UTF-8 bytestrings are permitted.
-        test_template_sources('\xc3\x85ngstr\xc3\xb6m', template_dirs,
+        test_template_sources(b'\xc3\x85ngstr\xc3\xb6m', template_dirs,
                               [u'/dir1/Ångström', u'/dir2/Ångström'])
         # Unicode strings are permitted.
         test_template_sources(u'Ångström', template_dirs,
                               [u'/dir1/Ångström', u'/dir2/Ångström'])
-        test_template_sources(u'Ångström', ['/Straße'], [u'/Straße/Ångström'])
-        test_template_sources('\xc3\x85ngstr\xc3\xb6m', ['/Straße'],
+        test_template_sources(u'Ångström', [b'/Stra\xc3\x9fe'], [u'/Straße/Ångström'])
+        test_template_sources(b'\xc3\x85ngstr\xc3\xb6m', [b'/Stra\xc3\x9fe'],
                               [u'/Straße/Ångström'])
         # Invalid UTF-8 encoding in bytestrings is not. Should raise a
         # semi-useful error message.
-        test_template_sources('\xc3\xc3', template_dirs, UnicodeDecodeError)
+        test_template_sources(b'\xc3\xc3', template_dirs, UnicodeDecodeError)
 
         # Case insensitive tests (for win32). Not run unless we're on
         # a case insensitive operating system.
@@ -1239,11 +1239,11 @@ class Templates(unittest.TestCase):
             'i18n02': ('{% load i18n %}{% trans "xxxyyyxxx" %}', {}, "xxxyyyxxx"),
 
             # simple translation of a variable
-            'i18n03': ('{% load i18n %}{% blocktrans %}{{ anton }}{% endblocktrans %}', {'anton': '\xc3\x85'}, u"Å"),
+            'i18n03': ('{% load i18n %}{% blocktrans %}{{ anton }}{% endblocktrans %}', {'anton': b'\xc3\x85'}, u"Å"),
 
             # simple translation of a variable and filter
-            'i18n04': ('{% load i18n %}{% blocktrans with berta=anton|lower %}{{ berta }}{% endblocktrans %}', {'anton': '\xc3\x85'}, u'å'),
-            'legacyi18n04': ('{% load i18n %}{% blocktrans with anton|lower as berta %}{{ berta }}{% endblocktrans %}', {'anton': '\xc3\x85'}, u'å'),
+            'i18n04': ('{% load i18n %}{% blocktrans with berta=anton|lower %}{{ berta }}{% endblocktrans %}', {'anton': b'\xc3\x85'}, u'å'),
+            'legacyi18n04': ('{% load i18n %}{% blocktrans with anton|lower as berta %}{{ berta }}{% endblocktrans %}', {'anton': b'\xc3\x85'}, u'å'),
 
             # simple translation of a string with interpolation
             'i18n05': ('{% load i18n %}{% blocktrans %}xxx{{ anton }}xxx{% endblocktrans %}', {'anton': 'yyy'}, "xxxyyyxxx"),

+ 6 - 6
tests/regressiontests/templates/unicode.py

@@ -10,16 +10,16 @@ class UnicodeTests(TestCase):
         t1 = Template(u'ŠĐĆŽćžšđ {{ var }}')
         # Templates can also be created from bytestrings. These are assumed to
         # be encoded using UTF-8.
-        s = '\xc5\xa0\xc4\x90\xc4\x86\xc5\xbd\xc4\x87\xc5\xbe\xc5\xa1\xc4\x91 {{ var }}'
+        s = b'\xc5\xa0\xc4\x90\xc4\x86\xc5\xbd\xc4\x87\xc5\xbe\xc5\xa1\xc4\x91 {{ var }}'
         t2 = Template(s)
-        s = '\x80\xc5\xc0'
+        s = b'\x80\xc5\xc0'
         self.assertRaises(TemplateEncodingError, Template, s)
 
         # Contexts can be constructed from unicode or UTF-8 bytestrings.
-        c1 = Context({"var": "foo"})
-        c2 = Context({u"var": "foo"})
-        c3 = Context({"var": u"Đđ"})
-        c4 = Context({u"var": "\xc4\x90\xc4\x91"})
+        c1 = Context({b"var": b"foo"})
+        c2 = Context({u"var": b"foo"})
+        c3 = Context({b"var": u"Đđ"})
+        c4 = Context({u"var": b"\xc4\x90\xc4\x91"})
 
         # Since both templates and all four contexts represent the same thing,
         # they all render the same (and are returned as unicode objects and

+ 36 - 36
tests/regressiontests/test_client_regress/models.py

@@ -122,14 +122,14 @@ class AssertContainsTests(TestCase):
         #Regression test for #10183
         r = self.client.get('/test_client_regress/check_unicode/')
         self.assertContains(r, u'さかき')
-        self.assertContains(r, '\xe5\xb3\xa0'.decode('utf-8'))
+        self.assertContains(r, b'\xe5\xb3\xa0'.decode('utf-8'))
 
     def test_unicode_not_contains(self):
         "Unicode characters can be searched for, and not found in template context"
         #Regression test for #10183
         r = self.client.get('/test_client_regress/check_unicode/')
         self.assertNotContains(r, u'はたけ')
-        self.assertNotContains(r, '\xe3\x81\xaf\xe3\x81\x9f\xe3\x81\x91'.decode('utf-8'))
+        self.assertNotContains(r, b'\xe3\x81\xaf\xe3\x81\x9f\xe3\x81\x91'.decode('utf-8'))
 
     def test_assert_contains_renders_template_response(self):
         """ Test that we can pass in an unrendered SimpleTemplateReponse
@@ -571,25 +571,25 @@ class URLEscapingTests(TestCase):
         "Get a view that has a simple string argument"
         response = self.client.get(reverse('arg_view', args=['Slartibartfast']))
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'Howdy, Slartibartfast')
+        self.assertEqual(response.content, b'Howdy, Slartibartfast')
 
     def test_argument_with_space_get(self):
         "Get a view that has a string argument that requires escaping"
         response = self.client.get(reverse('arg_view', args=['Arthur Dent']))
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'Hi, Arthur')
+        self.assertEqual(response.content, b'Hi, Arthur')
 
     def test_simple_argument_post(self):
         "Post for a view that has a simple string argument"
         response = self.client.post(reverse('arg_view', args=['Slartibartfast']))
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'Howdy, Slartibartfast')
+        self.assertEqual(response.content, b'Howdy, Slartibartfast')
 
     def test_argument_with_space_post(self):
         "Post for a view that has a string argument that requires escaping"
         response = self.client.post(reverse('arg_view', args=['Arthur Dent']))
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'Hi, Arthur')
+        self.assertEqual(response.content, b'Hi, Arthur')
 
 @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
 class ExceptionTests(TestCase):
@@ -721,17 +721,17 @@ class SessionTests(TestCase):
         # The session doesn't exist to start.
         response = self.client.get('/test_client_regress/check_session/')
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'NO')
+        self.assertEqual(response.content, b'NO')
 
         # This request sets a session variable.
         response = self.client.get('/test_client_regress/set_session/')
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'set_session')
+        self.assertEqual(response.content, b'set_session')
 
         # Check that the session has been modified
         response = self.client.get('/test_client_regress/check_session/')
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'YES')
+        self.assertEqual(response.content, b'YES')
 
         # Log in
         login = self.client.login(username='testclient',password='password')
@@ -740,7 +740,7 @@ class SessionTests(TestCase):
         # Session should still contain the modified value
         response = self.client.get('/test_client_regress/check_session/')
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'YES')
+        self.assertEqual(response.content, b'YES')
 
     def test_logout(self):
         """Logout should work whether the user is logged in or not (#9978)."""
@@ -755,39 +755,39 @@ class RequestMethodTests(TestCase):
         "Request a view via request method GET"
         response = self.client.get('/test_client_regress/request_methods/')
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'request method: GET')
+        self.assertEqual(response.content, b'request method: GET')
 
     def test_post(self):
         "Request a view via request method POST"
         response = self.client.post('/test_client_regress/request_methods/')
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'request method: POST')
+        self.assertEqual(response.content, b'request method: POST')
 
     def test_head(self):
         "Request a view via request method HEAD"
         response = self.client.head('/test_client_regress/request_methods/')
         self.assertEqual(response.status_code, 200)
         # A HEAD request doesn't return any content.
-        self.assertNotEqual(response.content, 'request method: HEAD')
-        self.assertEqual(response.content, '')
+        self.assertNotEqual(response.content, b'request method: HEAD')
+        self.assertEqual(response.content, b'')
 
     def test_options(self):
         "Request a view via request method OPTIONS"
         response = self.client.options('/test_client_regress/request_methods/')
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'request method: OPTIONS')
+        self.assertEqual(response.content, b'request method: OPTIONS')
 
     def test_put(self):
         "Request a view via request method PUT"
         response = self.client.put('/test_client_regress/request_methods/')
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'request method: PUT')
+        self.assertEqual(response.content, b'request method: PUT')
 
     def test_delete(self):
         "Request a view via request method DELETE"
         response = self.client.delete('/test_client_regress/request_methods/')
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'request method: DELETE')
+        self.assertEqual(response.content, b'request method: DELETE')
 
 class RequestMethodStringDataTests(TestCase):
     def test_post(self):
@@ -796,7 +796,7 @@ class RequestMethodStringDataTests(TestCase):
         data = u'{"test": "json"}'
         response = self.client.post('/test_client_regress/request_methods/', data=data, content_type='application/json')
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'request method: POST')
+        self.assertEqual(response.content, b'request method: POST')
 
     def test_put(self):
         "Request a view with string data via request method PUT"
@@ -804,7 +804,7 @@ class RequestMethodStringDataTests(TestCase):
         data = u'{"test": "json"}'
         response = self.client.put('/test_client_regress/request_methods/', data=data, content_type='application/json')
         self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.content, 'request method: PUT')
+        self.assertEqual(response.content, b'request method: PUT')
 
 class QueryStringTests(TestCase):
     def test_get_like_requests(self):
@@ -913,34 +913,34 @@ class DummyFile(object):
 class UploadedFileEncodingTest(TestCase):
     def test_file_encoding(self):
         encoded_file = encode_file('TEST_BOUNDARY', 'TEST_KEY', DummyFile('test_name.bin'))
-        self.assertEqual('--TEST_BOUNDARY', encoded_file[0])
-        self.assertEqual('Content-Disposition: form-data; name="TEST_KEY"; filename="test_name.bin"', encoded_file[1])
-        self.assertEqual('TEST_FILE_CONTENT', encoded_file[-1])
+        self.assertEqual(b'--TEST_BOUNDARY', encoded_file[0])
+        self.assertEqual(b'Content-Disposition: form-data; name="TEST_KEY"; filename="test_name.bin"', encoded_file[1])
+        self.assertEqual(b'TEST_FILE_CONTENT', encoded_file[-1])
 
     def test_guesses_content_type_on_file_encoding(self):
-        self.assertEqual('Content-Type: application/octet-stream',
+        self.assertEqual(b'Content-Type: application/octet-stream',
                          encode_file('IGNORE', 'IGNORE', DummyFile("file.bin"))[2])
-        self.assertEqual('Content-Type: text/plain',
+        self.assertEqual(b'Content-Type: text/plain',
                          encode_file('IGNORE', 'IGNORE', DummyFile("file.txt"))[2])
         self.assertIn(encode_file('IGNORE', 'IGNORE', DummyFile("file.zip"))[2], (
-                        'Content-Type: application/x-compress',
-                        'Content-Type: application/x-zip',
-                        'Content-Type: application/x-zip-compressed',
-                        'Content-Type: application/zip',))
-        self.assertEqual('Content-Type: application/octet-stream',
+                        b'Content-Type: application/x-compress',
+                        b'Content-Type: application/x-zip',
+                        b'Content-Type: application/x-zip-compressed',
+                        b'Content-Type: application/zip',))
+        self.assertEqual(b'Content-Type: application/octet-stream',
                          encode_file('IGNORE', 'IGNORE', DummyFile("file.unknown"))[2])
 
 class RequestHeadersTest(TestCase):
     def test_client_headers(self):
         "A test client can receive custom headers"
         response = self.client.get("/test_client_regress/check_headers/", HTTP_X_ARG_CHECK='Testing 123')
-        self.assertEqual(response.content, "HTTP_X_ARG_CHECK: Testing 123")
+        self.assertEqual(response.content, b"HTTP_X_ARG_CHECK: Testing 123")
         self.assertEqual(response.status_code, 200)
 
     def test_client_headers_redirect(self):
         "Test client headers are preserved through redirects"
         response = self.client.get("/test_client_regress/check_headers_redirect/", follow=True, HTTP_X_ARG_CHECK='Testing 123')
-        self.assertEqual(response.content, "HTTP_X_ARG_CHECK: Testing 123")
+        self.assertEqual(response.content, b"HTTP_X_ARG_CHECK: Testing 123")
         self.assertRedirects(response, '/test_client_regress/check_headers/',
             status_code=301, target_status_code=200)
 
@@ -956,22 +956,22 @@ class ReadLimitedStreamTest(TestCase):
     def test_body_from_empty_request(self):
         """HttpRequest.body on a test client GET request should return
         the empty string."""
-        self.assertEqual(self.client.get("/test_client_regress/body/").content, '')
+        self.assertEqual(self.client.get("/test_client_regress/body/").content, b'')
 
     def test_read_from_empty_request(self):
         """HttpRequest.read() on a test client GET request should return the
         empty string."""
-        self.assertEqual(self.client.get("/test_client_regress/read_all/").content, '')
+        self.assertEqual(self.client.get("/test_client_regress/read_all/").content, b'')
 
     def test_read_numbytes_from_empty_request(self):
         """HttpRequest.read(LARGE_BUFFER) on a test client GET request should
         return the empty string."""
-        self.assertEqual(self.client.get("/test_client_regress/read_buffer/").content, '')
+        self.assertEqual(self.client.get("/test_client_regress/read_buffer/").content, b'')
 
     def test_read_from_nonempty_request(self):
         """HttpRequest.read() on a test client PUT request with some payload
         should return that payload."""
-        payload = 'foobar'
+        payload = b'foobar'
         self.assertEqual(self.client.put("/test_client_regress/read_all/",
                                           data=payload,
                                           content_type='text/plain').content, payload)
@@ -979,7 +979,7 @@ class ReadLimitedStreamTest(TestCase):
     def test_read_numbytes_from_nonempty_request(self):
         """HttpRequest.read(LARGE_BUFFER) on a test client PUT request with
         some payload should return that payload."""
-        payload = 'foobar'
+        payload = b'foobar'
         self.assertEqual(self.client.put("/test_client_regress/read_buffer/",
                                           data=payload,
                                           content_type='text/plain').content, payload)

+ 3 - 3
tests/regressiontests/views/__init__.py

@@ -3,8 +3,8 @@
 class BrokenException(Exception):
     pass
 
-except_args = ('Broken!',           # plain exception with ASCII text
+except_args = (b'Broken!',           # plain exception with ASCII text
                u'¡Broken!',         # non-ASCII unicode data
-               '¡Broken!',          # non-ASCII, utf-8 encoded bytestring
-               '\xa1Broken!', )     # non-ASCII, latin1 bytestring
+               u'¡Broken!'.encode('utf-8'), # non-ASCII, utf-8 encoded bytestring
+               b'\xa1Broken!', )     # non-ASCII, latin1 bytestring