From 3c0877938f5eafc822d32b6c4f85e5a46b873390 Mon Sep 17 00:00:00 2001
From: Julian Bez <web-spy@gmx.de>
Date: Thu, 14 Jun 2012 17:42:55 +0300
Subject: [PATCH 01/88] Fixed #18110 -- Improve template cache tag
 documentation

---
 docs/topics/cache.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/docs/topics/cache.txt b/docs/topics/cache.txt
index 03afa866476..d0bd9f69929 100644
--- a/docs/topics/cache.txt
+++ b/docs/topics/cache.txt
@@ -595,7 +595,8 @@ the ``cache`` template tag. To give your template access to this tag, put
 
 The ``{% cache %}`` template tag caches the contents of the block for a given
 amount of time. It takes at least two arguments: the cache timeout, in seconds,
-and the name to give the cache fragment. For example:
+and the name to give the cache fragment. The name will be taken as is, do not
+use a variable. For example:
 
 .. code-block:: html+django
 

From dea554bd9df193ee11b7d924ffa0631fabdfdaee Mon Sep 17 00:00:00 2001
From: Daniel Greenfeld <pydanny@gmail.com>
Date: Sun, 15 Jul 2012 17:30:39 -0700
Subject: [PATCH 02/88] Added mention in MRO section about method/attribute
 inheritence. Added simple examples to Generic editing views, added index to
 Generic editing views and Editing mixins, added missing template_name_suffix
 attribute to Generic editing views.

---
 .../ref/class-based-views/generic-editing.txt | 106 +++++++++++++++++-
 docs/ref/class-based-views/mixins-editing.txt |  10 ++
 2 files changed, 112 insertions(+), 4 deletions(-)

diff --git a/docs/ref/class-based-views/generic-editing.txt b/docs/ref/class-based-views/generic-editing.txt
index d5df369fb30..eb286ec3a77 100644
--- a/docs/ref/class-based-views/generic-editing.txt
+++ b/docs/ref/class-based-views/generic-editing.txt
@@ -2,7 +2,26 @@
 Generic editing views
 =====================
 
-The views described here provide a foundation for editing content.
+The following views are described on this page and provide a foundation for 
+editing content:
+
+* :class:`django.views.generic.edit.FormView`
+* :class:`django.views.generic.edit.CreateView`
+* :class:`django.views.generic.edit.UpdateView`
+* :class:`django.views.generic.edit.DeleteView`
+
+.. note:: Some of the examples on this page assume that a model titled 'authors'
+    has been defined. For these cases we assume the following has been defined 
+    in `myapps.models.py`::
+
+        from django import models
+        from django.core.urlresolvers import reverse
+
+        class Author(models.Model):
+            name = models.CharField(max_length=200)
+
+            def get_absolute_url(self):
+                return reverse('author-detail', kwargs={'pk': self.pk})
 
 .. class:: django.views.generic.edit.FormView
 
@@ -11,6 +30,8 @@ The views described here provide a foundation for editing content.
 
     **Ancestors (MRO)**
 
+    This view inherits methods and attributes from the following views:
+
     * :class:`django.views.generic.edit.FormView`
     * :class:`django.views.generic.base.TemplateResponseMixin`
     * :class:`django.views.generic.edit.BaseFormView`
@@ -18,6 +39,35 @@ The views described here provide a foundation for editing content.
     * :class:`django.views.generic.edit.ProcessFormView`
     * :class:`django.views.generic.base.View`
 
+    **Example forms.py**::
+
+        from django import forms
+
+        class ContactForm(forms.Form):
+            name = forms.CharField()
+            message = forms.CharField(widget=forms.Textarea)
+
+            def send_email(self):
+                # send email using the self.cleaned_data dictionary
+                pass
+
+    **Example views.py**::
+
+        from myapp.forms import ContactForm
+        from django.views.generic.edit import FormView
+
+        class ContactView(FormView):
+            template_name = 'contact.html'
+            form_class = ContactForm
+            success_url = '/thanks/'
+
+            def form_valid(self, form):
+                # This method is called when valid form data has been POSTed.
+                # It should return an HttpResponse.
+                form.send_email()
+                return super(ContactView, self).form_valid(form)
+
+
 .. class:: django.views.generic.edit.CreateView
 
     A view that displays a form for creating an object, redisplaying the form
@@ -25,6 +75,8 @@ The views described here provide a foundation for editing content.
 
     **Ancestors (MRO)**
 
+    This view inherits methods and attributes from the following views:
+
     * :class:`django.views.generic.edit.CreateView`
     * :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin`
     * :class:`django.views.generic.base.TemplateResponseMixin`
@@ -35,6 +87,21 @@ The views described here provide a foundation for editing content.
     * :class:`django.views.generic.edit.ProcessFormView`
     * :class:`django.views.generic.base.View`
 
+    **Attributes**
+
+    .. attribute:: template_name_suffix
+
+        The CreateView page displayed to a GET request uses a
+        ``template_name_suffix`` of ``'_form'``.
+
+    **Example views.py**::
+
+        from django.views.generic.edit import CreateView
+        from myapp.models import Author
+
+        class AuthorCreate(CreateView):
+            model = Author
+
 .. class:: django.views.generic.edit.UpdateView
 
     A view that displays a form for editing an existing object, redisplaying
@@ -44,6 +111,8 @@ The views described here provide a foundation for editing content.
 
     **Ancestors (MRO)**
 
+    This view inherits methods and attributes from the following views:
+
     * :class:`django.views.generic.edit.UpdateView`
     * :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin`
     * :class:`django.views.generic.base.TemplateResponseMixin`
@@ -54,6 +123,21 @@ The views described here provide a foundation for editing content.
     * :class:`django.views.generic.edit.ProcessFormView`
     * :class:`django.views.generic.base.View`
 
+    **Attributes**
+
+    .. attribute:: template_name_suffix
+
+        The CreateView page displayed to a GET request uses a
+        ``template_name_suffix`` of ``'_form'``.
+
+    **Example views.py**::
+
+        from django.views.generic.edit import UpdateView
+        from myapp.models import Author
+
+        class AuthorUpdate(UpdateView):
+            model = Author
+
 .. class:: django.views.generic.edit.DeleteView
 
     A view that displays a confirmation page and deletes an existing object.
@@ -63,6 +147,8 @@ The views described here provide a foundation for editing content.
 
     **Ancestors (MRO)**
 
+    This view inherits methods and attributes from the following views:
+
     * :class:`django.views.generic.edit.DeleteView`
     * :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin`
     * :class:`django.views.generic.base.TemplateResponseMixin`
@@ -72,7 +158,19 @@ The views described here provide a foundation for editing content.
     * :class:`django.views.generic.detail.SingleObjectMixin`
     * :class:`django.views.generic.base.View`
 
-    **Notes**
+    **Attributes**
 
-    * The delete confirmation page displayed to a GET request uses a
-      ``template_name_suffix`` of ``'_confirm_delete'``.
+    .. attribute:: template_name_suffix
+
+        The CreateView page displayed to a GET request uses a
+        ``template_name_suffix`` of ``'_confirm_delete'``.
+
+    **Example views.py**::
+
+        from django.views.generic.edit import DeleteView
+        from django.core.urlresolvers import reverse_lazy
+        from myapp.models import Author
+
+        class AuthorDelete(DeleteView):
+            model = Author
+            success_url = reverse_lazy('author-list')        
diff --git a/docs/ref/class-based-views/mixins-editing.txt b/docs/ref/class-based-views/mixins-editing.txt
index 7258893d63a..f68c279ff3a 100644
--- a/docs/ref/class-based-views/mixins-editing.txt
+++ b/docs/ref/class-based-views/mixins-editing.txt
@@ -2,6 +2,16 @@
 Editing mixins
 ==============
 
+The following mixins are used to construct Django's editing views:
+
+* :class:`django.views.generic.edit.FormMixin`
+* :class:`django.views.generic.edit.ModelFormMixin`
+* :class:`django.views.generic.edit.ProcessFormView`
+* :class:`django.views.generic.edit.DeletionMixin`
+
+.. note:: Examples of how these are combined into editing views can be found at
+    the documentation on ``Generic editing views``.
+
 .. class:: django.views.generic.edit.FormMixin
 
     A mixin class that provides facilities for creating and displaying forms.

From b90caf014c8cb447d34217e81bbc3fb57b2df89b Mon Sep 17 00:00:00 2001
From: Daniel Greenfeld <pydanny@gmail.com>
Date: Sun, 15 Jul 2012 19:29:19 -0700
Subject: [PATCH 03/88] Changed myapps.models.py to myapps/models.py

---
 docs/ref/class-based-views/generic-editing.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/ref/class-based-views/generic-editing.txt b/docs/ref/class-based-views/generic-editing.txt
index eb286ec3a77..78f46851f79 100644
--- a/docs/ref/class-based-views/generic-editing.txt
+++ b/docs/ref/class-based-views/generic-editing.txt
@@ -12,7 +12,7 @@ editing content:
 
 .. note:: Some of the examples on this page assume that a model titled 'authors'
     has been defined. For these cases we assume the following has been defined 
-    in `myapps.models.py`::
+    in `myapp/models.py`::
 
         from django import models
         from django.core.urlresolvers import reverse

From 226a3e7e00357a5c055faa5138d8338243c4c2c9 Mon Sep 17 00:00:00 2001
From: Jeroen Dekkers <jeroen@dekkers.ch>
Date: Tue, 24 Jul 2012 00:28:29 +0200
Subject: [PATCH 04/88] Remove double isinstance check in force_unicode

---
 django/utils/encoding.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/django/utils/encoding.py b/django/utils/encoding.py
index f2295444bf5..b5f4b76507e 100644
--- a/django/utils/encoding.py
+++ b/django/utils/encoding.py
@@ -94,7 +94,7 @@ def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
                     # output should be.
                     s = ' '.join([force_unicode(arg, encoding, strings_only,
                             errors) for arg in s])
-        elif not isinstance(s, six.text_type):
+        else:
             # Note: We use .decode() here, instead of six.text_type(s, encoding,
             # errors), so that if s is a SafeString, it ends up being a
             # SafeUnicode at the end.

From 04e8ef5a8361042577c2ebdb0512561e8249e0c5 Mon Sep 17 00:00:00 2001
From: Rafik Draoui <rafik@rafik.ca>
Date: Wed, 25 Jul 2012 21:33:38 +0100
Subject: [PATCH 05/88] Updated example of customized ModelAdmin in
 documentation for 1.4

The change_view method of django.contrib.admin.ModelAdmin takes an
extra `form_url` argument in Django 1.4.
---
 docs/ref/contrib/admin/index.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
index f28aa4687bd..4d39981a4d4 100644
--- a/docs/ref/contrib/admin/index.txt
+++ b/docs/ref/contrib/admin/index.txt
@@ -1266,11 +1266,11 @@ provided some extra mapping data that would not otherwise be available::
             # ...
             pass
 
-        def change_view(self, request, object_id, extra_context=None):
+        def change_view(self, request, object_id, form_url='', extra_context=None):
             extra_context = extra_context or {}
             extra_context['osm_data'] = self.get_osm_info()
             return super(MyModelAdmin, self).change_view(request, object_id,
-                extra_context=extra_context)
+                form_url, extra_context=extra_context)
 
 .. versionadded:: 1.4
 

From 00d5e632fabc03a0633b9910605b23bcec439cdc Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Sat, 28 Jul 2012 13:17:33 -0400
Subject: [PATCH 06/88] Fixed #18630 -- Updated version in
 docs/intro/install.txt; thanks Kevin London.

---
 docs/intro/install.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/docs/intro/install.txt b/docs/intro/install.txt
index 7e8c7db7b36..70c8034c5d7 100644
--- a/docs/intro/install.txt
+++ b/docs/intro/install.txt
@@ -84,8 +84,9 @@ Then at the Python prompt, try to import Django::
 
     >>> import django
     >>> print(django.get_version())
-    1.4
+    1.5
 
+You may have another version of Django installed.
 
 That's it!
 ----------

From 07d70e9b267797f5f375a1dfcc0513a68d0feb5f Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Sat, 28 Jul 2012 13:31:41 -0400
Subject: [PATCH 07/88] Fixed #18656 -- Fixed LocaleMiddleware link; thanks
 mitar for the report.

---
 docs/ref/middleware.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/ref/middleware.txt b/docs/ref/middleware.txt
index c280202ebf1..a6ea9a6c415 100644
--- a/docs/ref/middleware.txt
+++ b/docs/ref/middleware.txt
@@ -146,7 +146,7 @@ Locale middleware
 
 Enables language selection based on data from the request. It customizes
 content for each user. See the :doc:`internationalization documentation
-</topics/i18n/index>`.
+</topics/i18n/translation>`.
 
 Message middleware
 ------------------

From 690ed5794672495e4cffca9a4a701008d254a4e7 Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Sun, 29 Jul 2012 18:14:26 -0400
Subject: [PATCH 08/88] Fixed #18476 - Added use of {% url %} tag to tutorial.

Thanks Claude Paroz for the patch.
---
 docs/intro/tutorial03.txt | 17 +++++++++++++++++
 docs/intro/tutorial04.txt | 23 ++++++++++++++++-------
 2 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/docs/intro/tutorial03.txt b/docs/intro/tutorial03.txt
index fd3a04ba93a..d15b2f43ae0 100644
--- a/docs/intro/tutorial03.txt
+++ b/docs/intro/tutorial03.txt
@@ -533,5 +533,22 @@ under "/content/polls/", or any other path root, and the app will still work.
 
 All the poll app cares about is its relative path, not its absolute path.
 
+Removing hardcoded URLs in templates
+------------------------------------
+
+Remember, when we wrote the link to a poll in our template, the link was
+partially hardcoded like this:
+
+.. code-block:: html+django
+
+    <li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>
+
+To use the decoupled URLs we've just introduced, replace the hardcoded link
+with the :ttag:`url` template tag:
+
+.. code-block:: html+django
+
+    <li><a href="{% url 'polls.views.detail' poll.id %}">{{ poll.question }}</a></li>
+
 When you're comfortable with writing views, read :doc:`part 4 of this tutorial
 </intro/tutorial04>` to learn about simple form processing and generic views.
diff --git a/docs/intro/tutorial04.txt b/docs/intro/tutorial04.txt
index 44b9c16c2a0..31680ea5e57 100644
--- a/docs/intro/tutorial04.txt
+++ b/docs/intro/tutorial04.txt
@@ -18,7 +18,7 @@ tutorial, so that the template contains an HTML ``<form>`` element:
 
     {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
 
-    <form action="/polls/{{ poll.id }}/vote/" method="post">
+    <form action="{% url 'polls.views.vote' poll.id %}" method="post">
     {% csrf_token %}
     {% for choice in poll.choice_set.all %}
         <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
@@ -35,7 +35,7 @@ A quick rundown:
   selects one of the radio buttons and submits the form, it'll send the
   POST data ``choice=3``. This is HTML Forms 101.
 
-* We set the form's ``action`` to ``/polls/{{ poll.id }}/vote/``, and we
+* We set the form's ``action`` to ``{% url 'polls.views.vote' poll.id %}``, and we
   set ``method="post"``. Using ``method="post"`` (as opposed to
   ``method="get"``) is very important, because the act of submitting this
   form will alter data server-side. Whenever you create a form that alters
@@ -172,7 +172,7 @@ Now, create a ``results.html`` template:
     {% endfor %}
     </ul>
 
-    <a href="/polls/{{ poll.id }}/">Vote again?</a>
+    <a href="{% url 'polls.views.detail' poll.id %}">Vote again?</a>
 
 Now, go to ``/polls/1/`` in your browser and vote in the poll. You should see a
 results page that gets updated each time you vote. If you submit the form
@@ -238,11 +238,13 @@ Change it like so::
             ListView.as_view(
                 queryset=Poll.objects.order_by('-pub_date')[:5],
                 context_object_name='latest_poll_list',
-                template_name='polls/index.html')),
+                template_name='polls/index.html'),
+            name='poll_index'),
         url(r'^(?P<pk>\d+)/$',
             DetailView.as_view(
                 model=Poll,
-                template_name='polls/detail.html')),
+                template_name='polls/detail.html'),
+            name='poll_detail'),
         url(r'^(?P<pk>\d+)/results/$',
             DetailView.as_view(
                 model=Poll,
@@ -265,8 +267,8 @@ two views abstract the concepts of "display a list of objects" and
   ``"pk"``, so we've changed ``poll_id`` to ``pk`` for the generic
   views.
 
-* We've added a name, ``poll_results``, to the results view so
-  that we have a way to refer to its URL later on (see the
+* We've added the ``name`` argument to the views (e.g. ``name='poll_results'``)
+  so that we have a way to refer to their URL later on (see the
   documentation about :ref:`naming URL patterns
   <naming-url-patterns>` for information). We're also using the
   :func:`~django.conf.urls.url` function from
@@ -317,6 +319,13 @@ function anymore -- generic views can be (and are) used multiple times
 
     return HttpResponseRedirect(reverse('poll_results', args=(p.id,)))
 
+The same rule apply for the :ttag:`url` template tag. For example in the
+``results.html`` template:
+
+.. code-block:: html+django
+
+    <a href="{% url 'poll_detail' poll.id %}">Vote again?</a>
+
 Run the server, and use your new polling app based on generic views.
 
 For full details on generic views, see the :doc:`generic views documentation

From c0748a621ceaae0f90133bb7980c857bf13811a1 Mon Sep 17 00:00:00 2001
From: Justin Bronn <jbronn@geodjango.org>
Date: Sun, 29 Jul 2012 16:53:56 -0700
Subject: [PATCH 09/88] Updated my bio.

---
 docs/internals/committers.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/internals/committers.txt b/docs/internals/committers.txt
index fb601a24c02..9e9847d88d8 100644
--- a/docs/internals/committers.txt
+++ b/docs/internals/committers.txt
@@ -174,7 +174,7 @@ Justin Bronn
     implementing GeoDjango, Justin obtained a deep knowledge of Django's
     internals including the ORM, the admin, and Oracle support.
 
-    Justin lives in Houston, Texas.
+    Justin lives in San Francisco, CA.
 
 .. _GeoDjango: http://geodjango.org/
 

From dd16b17099b7d86f27773df048c5014cf439b282 Mon Sep 17 00:00:00 2001
From: Florian Apolloner <florian@apolloner.eu>
Date: Mon, 30 Jul 2012 21:54:29 +0200
Subject: [PATCH 10/88] Fixed a security issue in image uploading. Disclosure
 and release forthcoming.

---
 django/core/files/images.py | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/django/core/files/images.py b/django/core/files/images.py
index 228a7118c51..7d7eac65db9 100644
--- a/django/core/files/images.py
+++ b/django/core/files/images.py
@@ -47,13 +47,18 @@ def get_image_dimensions(file_or_path, close=False):
         file = open(file_or_path, 'rb')
         close = True
     try:
+        # Most of the time PIL only needs a small chunk to parse the image and
+        # get the dimensions, but with some TIFF files PIL needs to parse the
+        # whole file.
+        chunk_size = 1024
         while 1:
-            data = file.read(1024)
+            data = file.read(chunk_size)
             if not data:
                 break
             p.feed(data)
             if p.image:
                 return p.image.size
+            chunk_size = chunk_size*2
         return None
     finally:
         if close:

From b1d463468694f2e91fde67221b7996e9c52a9720 Mon Sep 17 00:00:00 2001
From: Florian Apolloner <florian@apolloner.eu>
Date: Mon, 30 Jul 2012 21:57:22 +0200
Subject: [PATCH 11/88] Fixed second security issue in image uploading.
 Disclosure and release forthcoming.

---
 django/forms/fields.py | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/django/forms/fields.py b/django/forms/fields.py
index c4a675da747..cdb1d7be676 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -560,20 +560,10 @@ class ImageField(FileField):
                 file = BytesIO(data['content'])
 
         try:
-            # load() is the only method that can spot a truncated JPEG,
-            #  but it cannot be called sanely after verify()
-            trial_image = Image.open(file)
-            trial_image.load()
-
-            # Since we're about to use the file again we have to reset the
-            # file object if possible.
-            if hasattr(file, 'seek') and callable(file.seek):
-                file.seek(0)
-
-            # verify() is the only method that can spot a corrupt PNG,
-            #  but it must be called immediately after the constructor
-            trial_image = Image.open(file)
-            trial_image.verify()
+            # load() could spot a truncated JPEG, but it loads the entire
+            # image in memory, which is a DoS vector. See #3848 and #18520.
+            # verify() must be called immediately after the constructor.
+            Image.open(file).verify()
         except ImportError:
             # Under PyPy, it is possible to import PIL. However, the underlying
             # _imaging C module isn't available, so an ImportError will be

From 4129201c3e0fa057c198bdefcb34686a23b4a93c Mon Sep 17 00:00:00 2001
From: Florian Apolloner <florian@apolloner.eu>
Date: Mon, 30 Jul 2012 22:01:50 +0200
Subject: [PATCH 12/88] Fixed a security issue in http redirects. Disclosure
 and new release forthcoming.

---
 django/http/__init__.py                     | 28 +++++++++++----------
 tests/regressiontests/httpwrappers/tests.py | 19 ++++++++++++--
 2 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/django/http/__init__.py b/django/http/__init__.py
index 6f9d70eebd9..19b581f5cb2 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -11,10 +11,10 @@ import warnings
 from io import BytesIO
 from pprint import pformat
 try:
-    from urllib.parse import quote, parse_qsl, urlencode, urljoin
+    from urllib.parse import quote, parse_qsl, urlencode, urljoin, urlparse
 except ImportError:     # Python 2
     from urllib import quote, urlencode
-    from urlparse import parse_qsl, urljoin
+    from urlparse import parse_qsl, urljoin, urlparse
 
 from django.utils.six.moves import http_cookies
 # Some versions of Python 2.7 and later won't need this encoding bug fix:
@@ -80,7 +80,7 @@ else:
 
 from django.conf import settings
 from django.core import signing
-from django.core.exceptions import ImproperlyConfigured
+from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
 from django.core.files import uploadhandler
 from django.http.multipartparser import MultiPartParser
 from django.http.utils import *
@@ -689,20 +689,22 @@ class HttpResponse(object):
             raise Exception("This %s instance cannot tell its position" % self.__class__)
         return sum([len(chunk) for chunk in self])
 
-class HttpResponseRedirect(HttpResponse):
+class HttpResponseRedirectBase(HttpResponse):
+    allowed_schemes = ['http', 'https', 'ftp']
+
+    def __init__(self, redirect_to):
+        parsed = urlparse(redirect_to)
+        if parsed.scheme and parsed.scheme not in self.allowed_schemes:
+            raise SuspiciousOperation("Unsafe redirect to URL with protocol '%s'" % parsed.scheme)
+        super(HttpResponseRedirectBase, self).__init__()
+        self['Location'] = iri_to_uri(redirect_to)
+    
+class HttpResponseRedirect(HttpResponseRedirectBase):
     status_code = 302
 
-    def __init__(self, redirect_to):
-        super(HttpResponseRedirect, self).__init__()
-        self['Location'] = iri_to_uri(redirect_to)
-
-class HttpResponsePermanentRedirect(HttpResponse):
+class HttpResponsePermanentRedirect(HttpResponseRedirectBase):
     status_code = 301
 
-    def __init__(self, redirect_to):
-        super(HttpResponsePermanentRedirect, self).__init__()
-        self['Location'] = iri_to_uri(redirect_to)
-
 class HttpResponseNotModified(HttpResponse):
     status_code = 304
 
diff --git a/tests/regressiontests/httpwrappers/tests.py b/tests/regressiontests/httpwrappers/tests.py
index 9b599db6d0e..0f61c2d8402 100644
--- a/tests/regressiontests/httpwrappers/tests.py
+++ b/tests/regressiontests/httpwrappers/tests.py
@@ -4,8 +4,11 @@ from __future__ import unicode_literals
 import copy
 import pickle
 
-from django.http import (QueryDict, HttpResponse, SimpleCookie, BadHeaderError,
-        parse_cookie)
+from django.core.exceptions import SuspiciousOperation
+from django.http import (QueryDict, HttpResponse, HttpResponseRedirect,
+                         HttpResponsePermanentRedirect,
+                         SimpleCookie, BadHeaderError,
+                         parse_cookie)
 from django.utils import unittest
 
 
@@ -309,6 +312,18 @@ class HttpResponseTests(unittest.TestCase):
         r = HttpResponse(['abc'])
         self.assertRaises(Exception, r.write, 'def')
 
+    def test_unsafe_redirect(self):
+        bad_urls = [
+            'data:text/html,<script>window.alert("xss")</script>',
+            'mailto:test@example.com',
+            'file:///etc/passwd',
+        ]
+        for url in bad_urls:
+            self.assertRaises(SuspiciousOperation,
+                              HttpResponseRedirect, url)
+            self.assertRaises(SuspiciousOperation,
+                              HttpResponsePermanentRedirect, url)
+
 
 class CookieTests(unittest.TestCase):
     def test_encode(self):

From 8d3e501502c308cbdd3cc95b62ace0fe11d373ab Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Mon, 30 Jul 2012 16:16:11 -0400
Subject: [PATCH 13/88] Fixed #17131 - Added per object permission notes to
 docs.

Thanks dchandek for the suggestion and mateusgondim for the patch.
---
 docs/topics/auth.txt | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt
index c0e56dbba06..942d46073a8 100644
--- a/docs/topics/auth.txt
+++ b/docs/topics/auth.txt
@@ -1450,7 +1450,7 @@ The permission_required decorator
 Limiting access to generic views
 --------------------------------
 
-To limit access to a :doc:`class-based generic view 
+To limit access to a :doc:`class-based generic view
 </ref/class-based-views/index>`, decorate the :meth:`View.dispatch
 <django.views.generic.base.View.dispatch>` method on the class. See
 :ref:`decorating-class-based-views` for details.
@@ -1476,12 +1476,13 @@ The Django admin site uses permissions as follows:
 * Access to delete an object is limited to users with the "delete"
   permission for that type of object.
 
-Permissions are set globally per type of object, not per specific object
-instance. For example, it's possible to say "Mary may change news stories," but
-it's not currently possible to say "Mary may change news stories, but only the
-ones she created herself" or "Mary may only change news stories that have a
-certain status, publication date or ID." The latter functionality is something
-Django developers are currently discussing.
+Permissions can be set not only per type of object, but also per specific
+object instance. By using the
+:meth:`~django.contrib.admin.ModelAdmin.has_add_permission`,
+:meth:`~django.contrib.admin.ModelAdmin.has_change_permission` and
+:meth:`~django.contrib.admin.ModelAdmin.has_delete_permission` methods provided
+by the :class:`~django.contrib.admin.ModelAdmin` class, it is possible to
+customize permissions for different object instances of the same type.
 
 Default permissions
 -------------------

From 964979e8ecec3ceccb2119ccb7270111b953611e Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Tue, 31 Jul 2012 16:13:52 -0400
Subject: [PATCH 14/88] Fixed #18122 - Clarified section title regarding
 applying permissions to generic views.

---
 docs/topics/auth.txt | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt
index 942d46073a8..7e1353210af 100644
--- a/docs/topics/auth.txt
+++ b/docs/topics/auth.txt
@@ -1447,10 +1447,10 @@ The permission_required decorator
 
 .. currentmodule:: django.contrib.auth
 
-Limiting access to generic views
---------------------------------
+Applying permissions to generic views
+-------------------------------------
 
-To limit access to a :doc:`class-based generic view
+To apply a permission to a :doc:`class-based generic view
 </ref/class-based-views/index>`, decorate the :meth:`View.dispatch
 <django.views.generic.base.View.dispatch>` method on the class. See
 :ref:`decorating-class-based-views` for details.

From ebbc414d1729f24e395ee050a62276229c59d75d Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Tue, 31 Jul 2012 16:20:41 -0400
Subject: [PATCH 15/88] Fixed #16168 - Added note regarding type requirements
 when overridng ModelForm fields.

Thanks Pieter Swinkels for the patch.
---
 docs/topics/forms/modelforms.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt
index 4cfde400a70..0ca37745c7c 100644
--- a/docs/topics/forms/modelforms.txt
+++ b/docs/topics/forms/modelforms.txt
@@ -437,6 +437,10 @@ parameter when declaring the form field::
             class Meta:
                 model = Article
 
+    You must ensure that the type of the form field can be used to set the
+    contents of the corresponding model field. When they are not compatible,
+    you will get a ``ValueError`` as no implicit conversion takes place.
+
     See the :doc:`form field documentation </ref/forms/fields>` for more information
     on fields and their arguments.
 

From c59fff707ac5cfa1f6d12e889a157b569cf2429e Mon Sep 17 00:00:00 2001
From: Simon Meers <simon@simonmeers.com>
Date: Thu, 2 Aug 2012 20:27:53 +1000
Subject: [PATCH 16/88] Reinstated Pinax link that was still in use by others.

---
 docs/internals/committers.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/docs/internals/committers.txt b/docs/internals/committers.txt
index 9e9847d88d8..5567c26fa1c 100644
--- a/docs/internals/committers.txt
+++ b/docs/internals/committers.txt
@@ -149,6 +149,7 @@ Joseph Kocherhans
 .. _brian rosner: http://brosner.com/
 .. _eldarion: http://eldarion.com/
 .. _django dose: http://djangodose.com/
+.. _pinax: http://pinaxproject.com/
 
 `Gary Wilson`_
     Gary starting contributing patches to Django in 2006 while developing Web

From d7816c563b58ed53d49956321d549a16e2b2ebc0 Mon Sep 17 00:00:00 2001
From: Simon Meers <simon@simonmeers.com>
Date: Thu, 2 Aug 2012 20:45:55 +1000
Subject: [PATCH 17/88] Fixed #18472 - Added warning regarding set_language /
 i18n_patterns.

---
 docs/topics/i18n/translation.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt
index c912bf95755..988948e259b 100644
--- a/docs/topics/i18n/translation.txt
+++ b/docs/topics/i18n/translation.txt
@@ -1247,6 +1247,12 @@ Activate this view by adding the following line to your URLconf::
 
 (Note that this example makes the view available at ``/i18n/setlang/``.)
 
+.. warning::
+
+    Make sure that you don't include the above URL within
+    :func:`~django.conf.urls.i18n.i18n_patterns` - it needs to be
+    language-independent itself to work correctly.
+
 The view expects to be called via the ``POST`` method, with a ``language``
 parameter set in request. If session support is enabled, the view
 saves the language choice in the user's session. Otherwise, it saves the

From 6f229d2d7a4621fd73e0a5d22b8b7d42dec9493e Mon Sep 17 00:00:00 2001
From: Martin Brochhaus <mbrochh@gmail.com>
Date: Thu, 2 Aug 2012 19:29:19 +0800
Subject: [PATCH 18/88] Update docs/topics/class-based-views/index.txt

Fixed a small typo:

"We can use create" should be "We can create"
---
 docs/topics/class-based-views/index.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/topics/class-based-views/index.txt b/docs/topics/class-based-views/index.txt
index 6c2848944c8..1ac70e6938c 100644
--- a/docs/topics/class-based-views/index.txt
+++ b/docs/topics/class-based-views/index.txt
@@ -87,7 +87,7 @@ Where class based views shine is when you want to do the same thing many times.
 Suppose you're writing an API, and every view should return JSON instead of
 rendered HTML.
 
-We can use create a mixin class to use in all of our views, handling the
+We can create a mixin class to use in all of our views, handling the
 conversion to JSON once.
 
 For example, a simple JSON mixin might look something like this::

From 39541be3bc76f937cd8a2182aee4c92c9212c6b7 Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Thu, 2 Aug 2012 06:47:59 -0400
Subject: [PATCH 19/88] Fixed #18581 - Updated admin actions screenshots.
 Thanks Kevin London.

---
 .../contrib/admin/_images/article_actions.png | Bin 38545 -> 52563 bytes
 .../admin/_images/article_actions_message.png | Bin 22098 -> 31936 bytes
 .../contrib/admin/_images/user_actions.png    | Bin 27047 -> 35765 bytes
 3 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/docs/ref/contrib/admin/_images/article_actions.png b/docs/ref/contrib/admin/_images/article_actions.png
index 78a78ae494b636a391f9c16869bd726a9aa8584d..1d35e60e5d620d2fe115073f9f624c418fd75c93 100644
GIT binary patch
literal 52563
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

literal 38545
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

diff --git a/docs/ref/contrib/admin/_images/article_actions_message.png b/docs/ref/contrib/admin/_images/article_actions_message.png
index 6ea9439b8e7affe93121c8989892b5f68e2cbeaf..16a2d0e197a97bd3c3820533868e8028e6992b5f 100644
GIT binary patch
literal 31936
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
Kv_{x4=zjnzp@4M&

literal 22098
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

diff --git a/docs/ref/contrib/admin/_images/user_actions.png b/docs/ref/contrib/admin/_images/user_actions.png
index fdbe2ad897950b0a6cee133a76155b6c299aaf5e..22d40e0181e5ec0acfacb709b878aa982fc72f3e 100644
GIT binary patch
literal 35765
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

literal 27047
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
BFlqn*


From 07e10fbe9f1a77fe03cfceeb008e1e56caba3a40 Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Thu, 2 Aug 2012 06:54:19 -0400
Subject: [PATCH 20/88] Fixed #16941 - Clarified naturaltime output when the
 time is more than a day old.

Thanks antoviaque for the patch.
---
 docs/ref/contrib/humanize.txt | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/docs/ref/contrib/humanize.txt b/docs/ref/contrib/humanize.txt
index cdc3009a51f..57978288b1d 100644
--- a/docs/ref/contrib/humanize.txt
+++ b/docs/ref/contrib/humanize.txt
@@ -103,9 +103,9 @@ naturaltime
 .. versionadded:: 1.4
 
 For datetime values, returns a string representing how many seconds,
-minutes or hours ago it was -- falling back to a longer date format if the
-value is more than a day old. In case the datetime value is in the future
-the return value will automatically use an appropriate phrase.
+minutes or hours ago it was -- falling back to the :tfilter:`timesince` 
+format if the value is more than a day old. In case the datetime value is in
+the future the return value will automatically use an appropriate phrase.
 
 Examples (when 'now' is 17 Feb 2007 16:30:00):
 
@@ -115,13 +115,14 @@ Examples (when 'now' is 17 Feb 2007 16:30:00):
 * ``17 Feb 2007 16:25:35`` becomes ``4 minutes ago``.
 * ``17 Feb 2007 15:30:29`` becomes ``an hour ago``.
 * ``17 Feb 2007 13:31:29`` becomes ``2 hours ago``.
-* ``16 Feb 2007 13:31:29`` becomes ``1 day ago``.
+* ``16 Feb 2007 13:31:29`` becomes ``1 day, 3 hours ago``.
 * ``17 Feb 2007 16:30:30`` becomes ``29 seconds from now``.
 * ``17 Feb 2007 16:31:00`` becomes ``a minute from now``.
 * ``17 Feb 2007 16:34:35`` becomes ``4 minutes from now``.
 * ``17 Feb 2007 16:30:29`` becomes ``an hour from now``.
 * ``17 Feb 2007 18:31:29`` becomes ``2 hours from now``.
 * ``18 Feb 2007 16:31:29`` becomes ``1 day from now``.
+* ``26 Feb 2007 18:31:29`` becomes ``1 week, 2 days from now``.
 
 .. templatefilter:: ordinal
 

From 2a16eb07927c866b4d8e1d318f71bd1038b34cae Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Thu, 2 Aug 2012 19:21:48 -0400
Subject: [PATCH 21/88] Fixed #17704 - Updated the StackedInline section in
 Tutorial 2; thanks xbito for the draft patch.

---
 docs/intro/_images/admin15t.png | Bin 0 -> 22805 bytes
 docs/intro/tutorial02.txt       |   8 ++++++++
 2 files changed, 8 insertions(+)
 create mode 100644 docs/intro/_images/admin15t.png

diff --git a/docs/intro/_images/admin15t.png b/docs/intro/_images/admin15t.png
new file mode 100644
index 0000000000000000000000000000000000000000..999d0519fb59c8cb64cc41d9912a9b5886feec86
GIT binary patch
literal 22805
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

literal 0
HcmV?d00001

diff --git a/docs/intro/tutorial02.txt b/docs/intro/tutorial02.txt
index 84da36be86f..fd13230c8b9 100644
--- a/docs/intro/tutorial02.txt
+++ b/docs/intro/tutorial02.txt
@@ -311,6 +311,14 @@ It works like this: There are three slots for related Choices -- as specified
 by ``extra`` -- and each time you come back to the "Change" page for an
 already-created object, you get another three extra slots.
 
+At the end of the three current slots you will find an "Add another Choice"
+link.  If you click on it, a new slot will be added. If you want to remove the
+added slot, you can click on the X to the top right of the added slot. Note
+that you can't remove the original three slots. This image shows an added slot:
+
+.. image:: _images/admin15t.png
+   :alt: Additional slot added dynamically
+
 One small problem, though. It takes a lot of screen space to display all the
 fields for entering related ``Choice`` objects. For that reason, Django offers a
 tabular way of displaying inline related objects; you just need to change

From 8fbfd217196e6bc49677d348338ded64d3373e9a Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Fri, 3 Aug 2012 09:26:11 +0200
Subject: [PATCH 22/88] Fixed #18684 -- Added Finnish DATETIME_FORMAT
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Thanks Guttorm Flatabø for the report and the initial patch.
---
 django/conf/locale/fi/formats.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/django/conf/locale/fi/formats.py b/django/conf/locale/fi/formats.py
index 9a658eed402..e76144a9e42 100644
--- a/django/conf/locale/fi/formats.py
+++ b/django/conf/locale/fi/formats.py
@@ -7,7 +7,7 @@ from __future__ import unicode_literals
 # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
 DATE_FORMAT = 'j. E Y'
 TIME_FORMAT = 'G.i.s'
-# DATETIME_FORMAT = 
+DATETIME_FORMAT = r'j. E Y \k\e\l\l\o G.i.s'
 YEAR_MONTH_FORMAT = 'F Y'
 MONTH_DAY_FORMAT = 'j. F'
 SHORT_DATE_FORMAT = 'j.n.Y'

From a55cde8ab1dc33723b4bac472b6fac6bb45d725a Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Fri, 3 Aug 2012 09:35:39 +0200
Subject: [PATCH 23/88] Fixed #18363 -- Improved Galician date and time format
 strings
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Thanks Guttorm Flatabø for the report and the initial patch, and
Fran Dieguez for the review.
---
 django/conf/locale/gl/formats.py | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/django/conf/locale/gl/formats.py b/django/conf/locale/gl/formats.py
index 1ff9f345217..ba7f6c52a01 100644
--- a/django/conf/locale/gl/formats.py
+++ b/django/conf/locale/gl/formats.py
@@ -1,17 +1,18 @@
 # -*- encoding: utf-8 -*-
 # This file is distributed under the same license as the Django package.
 #
+from __future__ import unicode_literals
 
 # The *_FORMAT strings use the Django date format syntax,
 # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
-DATE_FORMAT = 'd F Y'
+DATE_FORMAT = r'j \d\e F \d\e Y'
 TIME_FORMAT = 'H:i:s'
-# DATETIME_FORMAT = 
-YEAR_MONTH_FORMAT = 'F Y'
-MONTH_DAY_FORMAT = 'j F'
-SHORT_DATE_FORMAT = 'j M, Y'
-# SHORT_DATETIME_FORMAT = 
-# FIRST_DAY_OF_WEEK = 
+DATETIME_FORMAT = r'j \d\e F \d\e Y \á\s H:i'
+YEAR_MONTH_FORMAT = r'F \d\e Y'
+MONTH_DAY_FORMAT = r'j \d\e F'
+SHORT_DATE_FORMAT = 'd-m-Y'
+SHORT_DATETIME_FORMAT = 'd-m-Y, H:i'
+FIRST_DAY_OF_WEEK = 1 # Monday
 
 # The *_INPUT_FORMATS strings use the Python strftime format syntax,
 # see http://docs.python.org/library/datetime.html#strftime-strptime-behavior

From c5d6f6d6829e730bdddf63c1252304f0c49a9053 Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Fri, 3 Aug 2012 10:47:27 +0200
Subject: [PATCH 24/88] Reorganized geoapp gis tests

Removed the numbering of tests and moved lookup/geoqueryset tests
in their own test class.
---
 .../contrib/gis/tests/geoapp/test_regress.py  |  14 +-
 django/contrib/gis/tests/geoapp/tests.py      | 817 +++++++++---------
 2 files changed, 419 insertions(+), 412 deletions(-)

diff --git a/django/contrib/gis/tests/geoapp/test_regress.py b/django/contrib/gis/tests/geoapp/test_regress.py
index a9d802d8f18..fffd7d3cab3 100644
--- a/django/contrib/gis/tests/geoapp/test_regress.py
+++ b/django/contrib/gis/tests/geoapp/test_regress.py
@@ -12,7 +12,7 @@ from .models import City, PennsylvaniaCity, State, Truth
 
 class GeoRegressionTests(TestCase):
 
-    def test01_update(self):
+    def test_update(self):
         "Testing GeoQuerySet.update(). See #10411."
         pnt = City.objects.get(name='Pueblo').point
         bak = pnt.clone()
@@ -24,7 +24,7 @@ class GeoRegressionTests(TestCase):
         City.objects.filter(name='Pueblo').update(point=bak)
         self.assertEqual(bak, City.objects.get(name='Pueblo').point)
 
-    def test02_kmz(self):
+    def test_kmz(self):
         "Testing `render_to_kmz` with non-ASCII data. See #11624."
         name = '\xc3\x85land Islands'.decode('iso-8859-1')
         places = [{'name' : name,
@@ -35,7 +35,7 @@ class GeoRegressionTests(TestCase):
 
     @no_spatialite
     @no_mysql
-    def test03_extent(self):
+    def test_extent(self):
         "Testing `extent` on a table with a single point. See #11827."
         pnt = City.objects.get(name='Pueblo').point
         ref_ext = (pnt.x, pnt.y, pnt.x, pnt.y)
@@ -43,14 +43,14 @@ class GeoRegressionTests(TestCase):
         for ref_val, val in zip(ref_ext, extent):
             self.assertAlmostEqual(ref_val, val, 4)
 
-    def test04_unicode_date(self):
+    def test_unicode_date(self):
         "Testing dates are converted properly, even on SpatiaLite. See #16408."
         founded = datetime(1857, 5, 23)
         mansfield = PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)',
                                                     founded=founded)
         self.assertEqual(founded, PennsylvaniaCity.objects.dates('founded', 'day')[0])
 
-    def test05_empty_count(self):
+    def test_empty_count(self):
          "Testing that PostGISAdapter.__eq__ does check empty strings. See #13670."
          # contrived example, but need a geo lookup paired with an id__in lookup
          pueblo = City.objects.get(name='Pueblo')
@@ -60,12 +60,12 @@ class GeoRegressionTests(TestCase):
          # .count() should not throw TypeError in __eq__
          self.assertEqual(cities_within_state.count(), 1)
 
-    def test06_defer_or_only_with_annotate(self):
+    def test_defer_or_only_with_annotate(self):
         "Regression for #16409. Make sure defer() and only() work with annotate()"
         self.assertIsInstance(list(City.objects.annotate(Count('point')).defer('name')), list)
         self.assertIsInstance(list(City.objects.annotate(Count('point')).only('name')), list)
 
-    def test07_boolean_conversion(self):
+    def test_boolean_conversion(self):
         "Testing Boolean value conversion with the spatial backend, see #15169."
         t1 = Truth.objects.create(val=True)
         t2 = Truth.objects.create(val=False)
diff --git a/django/contrib/gis/tests/geoapp/tests.py b/django/contrib/gis/tests/geoapp/tests.py
index bcdbe734fff..b06d6b5e1bb 100644
--- a/django/contrib/gis/tests/geoapp/tests.py
+++ b/django/contrib/gis/tests/geoapp/tests.py
@@ -15,19 +15,24 @@ from django.utils import six
 
 from .models import Country, City, PennsylvaniaCity, State, Track
 
+from .test_feeds import GeoFeedTest
+from .test_regress import GeoRegressionTests
+from .test_sitemaps import GeoSitemapTest
+
+
 if not spatialite:
     from .models import Feature, MinusOneSRID
 
 class GeoModelTest(TestCase):
 
-    def test01_fixtures(self):
+    def test_fixtures(self):
         "Testing geographic model initialization from fixtures."
         # Ensuring that data was loaded from initial data fixtures.
         self.assertEqual(2, Country.objects.count())
         self.assertEqual(8, City.objects.count())
         self.assertEqual(2, State.objects.count())
 
-    def test02_proxy(self):
+    def test_proxy(self):
         "Testing Lazy-Geometry support (using the GeometryProxy)."
         ## Testing on a Point
         pnt = Point(0, 0)
@@ -95,165 +100,97 @@ class GeoModelTest(TestCase):
         self.assertEqual(ply, State.objects.get(name='NullState').poly)
         ns.delete()
 
-    def test03a_kml(self):
-        "Testing KML output from the database using GeoQuerySet.kml()."
-        # Only PostGIS and Spatialite (>=2.4.0-RC4) support KML serialization
-        if not (postgis or (spatialite and connection.ops.kml)):
-            self.assertRaises(NotImplementedError, State.objects.all().kml, field_name='poly')
-            return
-
-        # Should throw a TypeError when trying to obtain KML from a
-        #  non-geometry field.
-        qs = City.objects.all()
-        self.assertRaises(TypeError, qs.kml, 'name')
-
-        # The reference KML depends on the version of PostGIS used
-        # (the output stopped including altitude in 1.3.3).
-        if connection.ops.spatial_version >= (1, 3, 3):
-            ref_kml =  '<Point><coordinates>-104.609252,38.255001</coordinates></Point>'
-        else:
-            ref_kml = '<Point><coordinates>-104.609252,38.255001,0</coordinates></Point>'
-
-        # Ensuring the KML is as expected.
-        ptown1 = City.objects.kml(field_name='point', precision=9).get(name='Pueblo')
-        ptown2 = City.objects.kml(precision=9).get(name='Pueblo')
-        for ptown in [ptown1, ptown2]:
-            self.assertEqual(ref_kml, ptown.kml)
-
-    def test03b_gml(self):
-        "Testing GML output from the database using GeoQuerySet.gml()."
-        if mysql or (spatialite and not connection.ops.gml) :
-            self.assertRaises(NotImplementedError, Country.objects.all().gml, field_name='mpoly')
-            return
-
-        # Should throw a TypeError when tyring to obtain GML from a
-        # non-geometry field.
-        qs = City.objects.all()
-        self.assertRaises(TypeError, qs.gml, field_name='name')
-        ptown1 = City.objects.gml(field_name='point', precision=9).get(name='Pueblo')
-        ptown2 = City.objects.gml(precision=9).get(name='Pueblo')
+    @no_mysql
+    def test_lookup_insert_transform(self):
+        "Testing automatic transform for lookups and inserts."
+        # San Antonio in 'WGS84' (SRID 4326)
+        sa_4326 = 'POINT (-98.493183 29.424170)'
+        wgs_pnt = fromstr(sa_4326, srid=4326) # Our reference point in WGS84
 
+        # Oracle doesn't have SRID 3084, using 41157.
         if oracle:
-            # No precision parameter for Oracle :-/
-            gml_regex = re.compile(r'^<gml:Point srsName="SDO:4326" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates decimal="\." cs="," ts=" ">-104.60925\d+,38.25500\d+ </gml:coordinates></gml:Point>')
-        elif spatialite:
-            # Spatialite has extra colon in SrsName
-            gml_regex = re.compile(r'^<gml:Point SrsName="EPSG::4326"><gml:coordinates decimal="\." cs="," ts=" ">-104.609251\d+,38.255001</gml:coordinates></gml:Point>')
+            # San Antonio in 'Texas 4205, Southern Zone (1983, meters)' (SRID 41157)
+            # Used the following Oracle SQL to get this value:
+            #  SELECT SDO_UTIL.TO_WKTGEOMETRY(SDO_CS.TRANSFORM(SDO_GEOMETRY('POINT (-98.493183 29.424170)', 4326), 41157)) FROM DUAL;
+            nad_wkt  = 'POINT (300662.034646583 5416427.45974934)'
+            nad_srid = 41157
         else:
-            gml_regex = re.compile(r'^<gml:Point srsName="EPSG:4326"><gml:coordinates>-104\.60925\d+,38\.255001</gml:coordinates></gml:Point>')
+            # San Antonio in 'NAD83(HARN) / Texas Centric Lambert Conformal' (SRID 3084)
+            nad_wkt = 'POINT (1645978.362408288754523 6276356.025927528738976)' # Used ogr.py in gdal 1.4.1 for this transform
+            nad_srid = 3084
 
-        for ptown in [ptown1, ptown2]:
-            self.assertTrue(gml_regex.match(ptown.gml))
-
-
-    def test03c_geojson(self):
-        "Testing GeoJSON output from the database using GeoQuerySet.geojson()."
-        # Only PostGIS 1.3.4+ supports GeoJSON.
-        if not connection.ops.geojson:
-            self.assertRaises(NotImplementedError, Country.objects.all().geojson, field_name='mpoly')
-            return
-
-        if connection.ops.spatial_version >= (1, 4, 0):
-            pueblo_json = '{"type":"Point","coordinates":[-104.609252,38.255001]}'
-            houston_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"coordinates":[-95.363151,29.763374]}'
-            victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.305196,48.462611]}'
-            chicago_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}'
+        # Constructing & querying with a point from a different SRID. Oracle
+        # `SDO_OVERLAPBDYINTERSECT` operates differently from
+        # `ST_Intersects`, so contains is used instead.
+        nad_pnt = fromstr(nad_wkt, srid=nad_srid)
+        if oracle:
+            tx = Country.objects.get(mpoly__contains=nad_pnt)
         else:
-            pueblo_json = '{"type":"Point","coordinates":[-104.60925200,38.25500100]}'
-            houston_json = '{"type":"Point","crs":{"type":"EPSG","properties":{"EPSG":4326}},"coordinates":[-95.36315100,29.76337400]}'
-            victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.30519600,48.46261100]}'
-            chicago_json = '{"type":"Point","crs":{"type":"EPSG","properties":{"EPSG":4326}},"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}'
+            tx = Country.objects.get(mpoly__intersects=nad_pnt)
+        self.assertEqual('Texas', tx.name)
 
-        # Precision argument should only be an integer
-        self.assertRaises(TypeError, City.objects.geojson, precision='foo')
+        # Creating San Antonio.  Remember the Alamo.
+        sa = City.objects.create(name='San Antonio', point=nad_pnt)
 
-        # Reference queries and values.
-        # SELECT ST_AsGeoJson("geoapp_city"."point", 8, 0) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Pueblo';
-        self.assertEqual(pueblo_json, City.objects.geojson().get(name='Pueblo').geojson)
+        # Now verifying that San Antonio was transformed correctly
+        sa = City.objects.get(name='San Antonio')
+        self.assertAlmostEqual(wgs_pnt.x, sa.point.x, 6)
+        self.assertAlmostEqual(wgs_pnt.y, sa.point.y, 6)
 
-        # 1.3.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 1) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston';
-        # 1.4.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 2) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston';
-        # This time we want to include the CRS by using the `crs` keyword.
-        self.assertEqual(houston_json, City.objects.geojson(crs=True, model_att='json').get(name='Houston').json)
+        # If the GeometryField SRID is -1, then we shouldn't perform any
+        # transformation if the SRID of the input geometry is different.
+        # SpatiaLite does not support missing SRID values.
+        if not spatialite:
+            m1 = MinusOneSRID(geom=Point(17, 23, srid=4326))
+            m1.save()
+            self.assertEqual(-1, m1.geom.srid)
 
-        # 1.3.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 2) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Victoria';
-        # 1.4.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 1) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston';
-        # This time we include the bounding box by using the `bbox` keyword.
-        self.assertEqual(victoria_json, City.objects.geojson(bbox=True).get(name='Victoria').geojson)
+    def test_createnull(self):
+        "Testing creating a model instance and the geometry being None"
+        c = City()
+        self.assertEqual(c.point, None)
 
-        # 1.(3|4).x: SELECT ST_AsGeoJson("geoapp_city"."point", 5, 3) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Chicago';
-        # Finally, we set every available keyword.
-        self.assertEqual(chicago_json, City.objects.geojson(bbox=True, crs=True, precision=5).get(name='Chicago').geojson)
+    @no_spatialite # SpatiaLite does not support abstract geometry columns
+    def test_geometryfield(self):
+        "Testing the general GeometryField."
+        Feature(name='Point', geom=Point(1, 1)).save()
+        Feature(name='LineString', geom=LineString((0, 0), (1, 1), (5, 5))).save()
+        Feature(name='Polygon', geom=Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0)))).save()
+        Feature(name='GeometryCollection',
+                geom=GeometryCollection(Point(2, 2), LineString((0, 0), (2, 2)),
+                                        Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0))))).save()
 
-    def test03d_svg(self):
-        "Testing SVG output using GeoQuerySet.svg()."
-        if mysql or oracle:
-            self.assertRaises(NotImplementedError, City.objects.svg)
-            return
+        f_1 = Feature.objects.get(name='Point')
+        self.assertEqual(True, isinstance(f_1.geom, Point))
+        self.assertEqual((1.0, 1.0), f_1.geom.tuple)
+        f_2 = Feature.objects.get(name='LineString')
+        self.assertEqual(True, isinstance(f_2.geom, LineString))
+        self.assertEqual(((0.0, 0.0), (1.0, 1.0), (5.0, 5.0)), f_2.geom.tuple)
 
-        self.assertRaises(TypeError, City.objects.svg, precision='foo')
-        # SELECT AsSVG(geoapp_city.point, 0, 8) FROM geoapp_city WHERE name = 'Pueblo';
-        svg1 = 'cx="-104.609252" cy="-38.255001"'
-        # Even though relative, only one point so it's practically the same except for
-        # the 'c' letter prefix on the x,y values.
-        svg2 = svg1.replace('c', '')
-        self.assertEqual(svg1, City.objects.svg().get(name='Pueblo').svg)
-        self.assertEqual(svg2, City.objects.svg(relative=5).get(name='Pueblo').svg)
+        f_3 = Feature.objects.get(name='Polygon')
+        self.assertEqual(True, isinstance(f_3.geom, Polygon))
+        f_4 = Feature.objects.get(name='GeometryCollection')
+        self.assertEqual(True, isinstance(f_4.geom, GeometryCollection))
+        self.assertEqual(f_3.geom, f_4.geom[2])
 
     @no_mysql
-    def test04_transform(self):
-        "Testing the transform() GeoManager method."
-        # Pre-transformed points for Houston and Pueblo.
-        htown = fromstr('POINT(1947516.83115183 6322297.06040572)', srid=3084)
-        ptown = fromstr('POINT(992363.390841912 481455.395105533)', srid=2774)
-        prec = 3 # Precision is low due to version variations in PROJ and GDAL.
+    def test_inherited_geofields(self):
+        "Test GeoQuerySet methods on inherited Geometry fields."
+        # Creating a Pennsylvanian city.
+        mansfield = PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)')
 
-        # Asserting the result of the transform operation with the values in
-        #  the pre-transformed points.  Oracle does not have the 3084 SRID.
-        if not oracle:
-            h = City.objects.transform(htown.srid).get(name='Houston')
-            self.assertEqual(3084, h.point.srid)
-            self.assertAlmostEqual(htown.x, h.point.x, prec)
-            self.assertAlmostEqual(htown.y, h.point.y, prec)
+        # All transformation SQL will need to be performed on the
+        # _parent_ table.
+        qs = PennsylvaniaCity.objects.transform(32128)
 
-        p1 = City.objects.transform(ptown.srid, field_name='point').get(name='Pueblo')
-        p2 = City.objects.transform(srid=ptown.srid).get(name='Pueblo')
-        for p in [p1, p2]:
-            self.assertEqual(2774, p.point.srid)
-            self.assertAlmostEqual(ptown.x, p.point.x, prec)
-            self.assertAlmostEqual(ptown.y, p.point.y, prec)
+        self.assertEqual(1, qs.count())
+        for pc in qs: self.assertEqual(32128, pc.point.srid)
+
+
+class GeoLookupTest(TestCase):
 
     @no_mysql
-    @no_spatialite # SpatiaLite does not have an Extent function
-    def test05_extent(self):
-        "Testing the `extent` GeoQuerySet method."
-        # Reference query:
-        # `SELECT ST_extent(point) FROM geoapp_city WHERE (name='Houston' or name='Dallas');`
-        #   =>  BOX(-96.8016128540039 29.7633724212646,-95.3631439208984 32.7820587158203)
-        expected = (-96.8016128540039, 29.7633724212646, -95.3631439208984, 32.782058715820)
-
-        qs = City.objects.filter(name__in=('Houston', 'Dallas'))
-        extent = qs.extent()
-
-        for val, exp in zip(extent, expected):
-            self.assertAlmostEqual(exp, val, 4)
-
-    # Only PostGIS has support for the MakeLine aggregate.
-    @no_mysql
-    @no_oracle
-    @no_spatialite
-    def test06_make_line(self):
-        "Testing the `make_line` GeoQuerySet method."
-        # Ensuring that a `TypeError` is raised on models without PointFields.
-        self.assertRaises(TypeError, State.objects.make_line)
-        self.assertRaises(TypeError, Country.objects.make_line)
-        # Reference query:
-        # SELECT AsText(ST_MakeLine(geoapp_city.point)) FROM geoapp_city;
-        ref_line = GEOSGeometry('LINESTRING(-95.363151 29.763374,-96.801611 32.782057,-97.521157 34.464642,174.783117 -41.315268,-104.609252 38.255001,-95.23506 38.971823,-87.650175 41.850385,-123.305196 48.462611)', srid=4326)
-        self.assertEqual(ref_line, City.objects.make_line())
-
-    @no_mysql
-    def test09_disjoint(self):
+    def test_disjoint_lookup(self):
         "Testing the `disjoint` lookup type."
         ptown = City.objects.get(name='Pueblo')
         qs1 = City.objects.filter(point__disjoint=ptown.point)
@@ -263,7 +200,7 @@ class GeoModelTest(TestCase):
         self.assertEqual(1, qs2.count())
         self.assertEqual('Kansas', qs2[0].name)
 
-    def test10_contains_contained(self):
+    def test_contains_contained_lookups(self):
         "Testing the 'contained', 'contains', and 'bbcontains' lookup types."
         # Getting Texas, yes we were a country -- once ;)
         texas = Country.objects.get(name='Texas')
@@ -308,86 +245,11 @@ class GeoModelTest(TestCase):
             self.assertEqual(1, len(qs))
             self.assertEqual('Texas', qs[0].name)
 
-    @no_mysql
-    def test11_lookup_insert_transform(self):
-        "Testing automatic transform for lookups and inserts."
-        # San Antonio in 'WGS84' (SRID 4326)
-        sa_4326 = 'POINT (-98.493183 29.424170)'
-        wgs_pnt = fromstr(sa_4326, srid=4326) # Our reference point in WGS84
-
-        # Oracle doesn't have SRID 3084, using 41157.
-        if oracle:
-            # San Antonio in 'Texas 4205, Southern Zone (1983, meters)' (SRID 41157)
-            # Used the following Oracle SQL to get this value:
-            #  SELECT SDO_UTIL.TO_WKTGEOMETRY(SDO_CS.TRANSFORM(SDO_GEOMETRY('POINT (-98.493183 29.424170)', 4326), 41157)) FROM DUAL;
-            nad_wkt  = 'POINT (300662.034646583 5416427.45974934)'
-            nad_srid = 41157
-        else:
-            # San Antonio in 'NAD83(HARN) / Texas Centric Lambert Conformal' (SRID 3084)
-            nad_wkt = 'POINT (1645978.362408288754523 6276356.025927528738976)' # Used ogr.py in gdal 1.4.1 for this transform
-            nad_srid = 3084
-
-        # Constructing & querying with a point from a different SRID. Oracle
-        # `SDO_OVERLAPBDYINTERSECT` operates differently from
-        # `ST_Intersects`, so contains is used instead.
-        nad_pnt = fromstr(nad_wkt, srid=nad_srid)
-        if oracle:
-            tx = Country.objects.get(mpoly__contains=nad_pnt)
-        else:
-            tx = Country.objects.get(mpoly__intersects=nad_pnt)
-        self.assertEqual('Texas', tx.name)
-
-        # Creating San Antonio.  Remember the Alamo.
-        sa = City.objects.create(name='San Antonio', point=nad_pnt)
-
-        # Now verifying that San Antonio was transformed correctly
-        sa = City.objects.get(name='San Antonio')
-        self.assertAlmostEqual(wgs_pnt.x, sa.point.x, 6)
-        self.assertAlmostEqual(wgs_pnt.y, sa.point.y, 6)
-
-        # If the GeometryField SRID is -1, then we shouldn't perform any
-        # transformation if the SRID of the input geometry is different.
-        # SpatiaLite does not support missing SRID values.
-        if not spatialite:
-            m1 = MinusOneSRID(geom=Point(17, 23, srid=4326))
-            m1.save()
-            self.assertEqual(-1, m1.geom.srid)
-
-    @no_mysql
-    def test12_null_geometries(self):
-        "Testing NULL geometry support, and the `isnull` lookup type."
-        # Creating a state with a NULL boundary.
-        State.objects.create(name='Puerto Rico')
-
-        # Querying for both NULL and Non-NULL values.
-        nullqs = State.objects.filter(poly__isnull=True)
-        validqs = State.objects.filter(poly__isnull=False)
-
-        # Puerto Rico should be NULL (it's a commonwealth unincorporated territory)
-        self.assertEqual(1, len(nullqs))
-        self.assertEqual('Puerto Rico', nullqs[0].name)
-
-        # The valid states should be Colorado & Kansas
-        self.assertEqual(2, len(validqs))
-        state_names = [s.name for s in validqs]
-        self.assertEqual(True, 'Colorado' in state_names)
-        self.assertEqual(True, 'Kansas' in state_names)
-
-        # Saving another commonwealth w/a NULL geometry.
-        nmi = State.objects.create(name='Northern Mariana Islands', poly=None)
-        self.assertEqual(nmi.poly, None)
-
-        # Assigning a geomery and saving -- then UPDATE back to NULL.
-        nmi.poly = 'POLYGON((0 0,1 0,1 1,1 0,0 0))'
-        nmi.save()
-        State.objects.filter(name='Northern Mariana Islands').update(poly=None)
-        self.assertEqual(None, State.objects.get(name='Northern Mariana Islands').poly)
-
     # Only PostGIS has `left` and `right` lookup types.
     @no_mysql
     @no_oracle
     @no_spatialite
-    def test13_left_right(self):
+    def test_left_right_lookups(self):
         "Testing the 'left' and 'right' lookup types."
         # Left: A << B => true if xmax(A) < xmin(B)
         # Right: A >> B => true if xmin(A) > xmax(B)
@@ -423,7 +285,7 @@ class GeoModelTest(TestCase):
         self.assertEqual(2, len(qs))
         for c in qs: self.assertEqual(True, c.name in cities)
 
-    def test14_equals(self):
+    def test_equals_lookups(self):
         "Testing the 'same_as' and 'equals' lookup types."
         pnt = fromstr('POINT (-95.363151 29.763374)', srid=4326)
         c1 = City.objects.get(point=pnt)
@@ -432,7 +294,37 @@ class GeoModelTest(TestCase):
         for c in [c1, c2, c3]: self.assertEqual('Houston', c.name)
 
     @no_mysql
-    def test15_relate(self):
+    def test_null_geometries(self):
+        "Testing NULL geometry support, and the `isnull` lookup type."
+        # Creating a state with a NULL boundary.
+        State.objects.create(name='Puerto Rico')
+
+        # Querying for both NULL and Non-NULL values.
+        nullqs = State.objects.filter(poly__isnull=True)
+        validqs = State.objects.filter(poly__isnull=False)
+
+        # Puerto Rico should be NULL (it's a commonwealth unincorporated territory)
+        self.assertEqual(1, len(nullqs))
+        self.assertEqual('Puerto Rico', nullqs[0].name)
+
+        # The valid states should be Colorado & Kansas
+        self.assertEqual(2, len(validqs))
+        state_names = [s.name for s in validqs]
+        self.assertEqual(True, 'Colorado' in state_names)
+        self.assertEqual(True, 'Kansas' in state_names)
+
+        # Saving another commonwealth w/a NULL geometry.
+        nmi = State.objects.create(name='Northern Mariana Islands', poly=None)
+        self.assertEqual(nmi.poly, None)
+
+        # Assigning a geomery and saving -- then UPDATE back to NULL.
+        nmi.poly = 'POLYGON((0 0,1 0,1 1,1 0,0 0))'
+        nmi.save()
+        State.objects.filter(name='Northern Mariana Islands').update(poly=None)
+        self.assertEqual(None, State.objects.get(name='Northern Mariana Islands').poly)
+
+    @no_mysql
+    def test_relate_lookup(self):
         "Testing the 'relate' lookup type."
         # To make things more interesting, we will have our Texas reference point in
         # different SRIDs.
@@ -474,60 +366,12 @@ class GeoModelTest(TestCase):
             self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt2, intersects_mask)).name)
             self.assertEqual('Lawrence', City.objects.get(point__relate=(ks.poly, intersects_mask)).name)
 
-    def test16_createnull(self):
-        "Testing creating a model instance and the geometry being None"
-        c = City()
-        self.assertEqual(c.point, None)
+
+class GeoQuerySetTest(TestCase):
+    # Please keep the tests in GeoQuerySet method's alphabetic order
 
     @no_mysql
-    def test17_unionagg(self):
-        "Testing the `unionagg` (aggregate union) GeoManager method."
-        tx = Country.objects.get(name='Texas').mpoly
-        # Houston, Dallas -- Oracle has different order.
-        union1 = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)')
-        union2 = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)')
-        qs = City.objects.filter(point__within=tx)
-        self.assertRaises(TypeError, qs.unionagg, 'name')
-        # Using `field_name` keyword argument in one query and specifying an
-        # order in the other (which should not be used because this is
-        # an aggregate method on a spatial column)
-        u1 = qs.unionagg(field_name='point')
-        u2 = qs.order_by('name').unionagg()
-        tol = 0.00001
-        if oracle:
-            union = union2
-        else:
-            union = union1
-        self.assertEqual(True, union.equals_exact(u1, tol))
-        self.assertEqual(True, union.equals_exact(u2, tol))
-        qs = City.objects.filter(name='NotACity')
-        self.assertEqual(None, qs.unionagg(field_name='point'))
-
-    @no_spatialite # SpatiaLite does not support abstract geometry columns
-    def test18_geometryfield(self):
-        "Testing the general GeometryField."
-        Feature(name='Point', geom=Point(1, 1)).save()
-        Feature(name='LineString', geom=LineString((0, 0), (1, 1), (5, 5))).save()
-        Feature(name='Polygon', geom=Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0)))).save()
-        Feature(name='GeometryCollection',
-                geom=GeometryCollection(Point(2, 2), LineString((0, 0), (2, 2)),
-                                        Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0))))).save()
-
-        f_1 = Feature.objects.get(name='Point')
-        self.assertEqual(True, isinstance(f_1.geom, Point))
-        self.assertEqual((1.0, 1.0), f_1.geom.tuple)
-        f_2 = Feature.objects.get(name='LineString')
-        self.assertEqual(True, isinstance(f_2.geom, LineString))
-        self.assertEqual(((0.0, 0.0), (1.0, 1.0), (5.0, 5.0)), f_2.geom.tuple)
-
-        f_3 = Feature.objects.get(name='Polygon')
-        self.assertEqual(True, isinstance(f_3.geom, Polygon))
-        f_4 = Feature.objects.get(name='GeometryCollection')
-        self.assertEqual(True, isinstance(f_4.geom, GeometryCollection))
-        self.assertEqual(f_3.geom, f_4.geom[2])
-
-    @no_mysql
-    def test19_centroid(self):
+    def test_centroid(self):
         "Testing the `centroid` GeoQuerySet method."
         qs = State.objects.exclude(poly__isnull=True).centroid()
         if oracle:
@@ -540,84 +384,7 @@ class GeoModelTest(TestCase):
             self.assertEqual(True, s.poly.centroid.equals_exact(s.centroid, tol))
 
     @no_mysql
-    def test20_pointonsurface(self):
-        "Testing the `point_on_surface` GeoQuerySet method."
-        # Reference values.
-        if oracle:
-            # SELECT SDO_UTIL.TO_WKTGEOMETRY(SDO_GEOM.SDO_POINTONSURFACE(GEOAPP_COUNTRY.MPOLY, 0.05)) FROM GEOAPP_COUNTRY;
-            ref = {'New Zealand' : fromstr('POINT (174.616364 -36.100861)', srid=4326),
-                   'Texas' : fromstr('POINT (-103.002434 36.500397)', srid=4326),
-                   }
-
-        elif postgis or spatialite:
-            # Using GEOSGeometry to compute the reference point on surface values
-            # -- since PostGIS also uses GEOS these should be the same.
-            ref = {'New Zealand' : Country.objects.get(name='New Zealand').mpoly.point_on_surface,
-                   'Texas' : Country.objects.get(name='Texas').mpoly.point_on_surface
-                   }
-
-        for c in Country.objects.point_on_surface():
-            if spatialite:
-                # XXX This seems to be a WKT-translation-related precision issue?
-                tol = 0.00001
-            else:
-                tol = 0.000000001
-            self.assertEqual(True, ref[c.name].equals_exact(c.point_on_surface, tol))
-
-    @no_mysql
-    @no_oracle
-    def test21_scale(self):
-        "Testing the `scale` GeoQuerySet method."
-        xfac, yfac = 2, 3
-        tol = 5 # XXX The low precision tolerance is for SpatiaLite
-        qs = Country.objects.scale(xfac, yfac, model_att='scaled')
-        for c in qs:
-            for p1, p2 in zip(c.mpoly, c.scaled):
-                for r1, r2 in zip(p1, p2):
-                    for c1, c2 in zip(r1.coords, r2.coords):
-                        self.assertAlmostEqual(c1[0] * xfac, c2[0], tol)
-                        self.assertAlmostEqual(c1[1] * yfac, c2[1], tol)
-
-    @no_mysql
-    @no_oracle
-    def test22_translate(self):
-        "Testing the `translate` GeoQuerySet method."
-        xfac, yfac = 5, -23
-        qs = Country.objects.translate(xfac, yfac, model_att='translated')
-        for c in qs:
-            for p1, p2 in zip(c.mpoly, c.translated):
-                for r1, r2 in zip(p1, p2):
-                    for c1, c2 in zip(r1.coords, r2.coords):
-                        # XXX The low precision is for SpatiaLite
-                        self.assertAlmostEqual(c1[0] + xfac, c2[0], 5)
-                        self.assertAlmostEqual(c1[1] + yfac, c2[1], 5)
-
-    @no_mysql
-    def test23_numgeom(self):
-        "Testing the `num_geom` GeoQuerySet method."
-        # Both 'countries' only have two geometries.
-        for c in Country.objects.num_geom(): self.assertEqual(2, c.num_geom)
-        for c in City.objects.filter(point__isnull=False).num_geom():
-            # Oracle will return 1 for the number of geometries on non-collections,
-            # whereas PostGIS will return None.
-            if postgis:
-                self.assertEqual(None, c.num_geom)
-            else:
-                self.assertEqual(1, c.num_geom)
-
-    @no_mysql
-    @no_spatialite # SpatiaLite can only count vertices in LineStrings
-    def test24_numpoints(self):
-        "Testing the `num_points` GeoQuerySet method."
-        for c in Country.objects.num_points():
-            self.assertEqual(c.mpoly.num_points, c.num_points)
-
-        if not oracle:
-            # Oracle cannot count vertices in Point geometries.
-            for c in City.objects.num_points(): self.assertEqual(1, c.num_points)
-
-    @no_mysql
-    def test25_geoset(self):
+    def test_diff_intersection_union(self):
         "Testing the `difference`, `intersection`, `sym_difference`, and `union` GeoQuerySet methods."
         geom = Point(5, 23)
         tol = 1
@@ -644,22 +411,232 @@ class GeoModelTest(TestCase):
                 self.assertEqual(c.mpoly.union(geom), c.union)
 
     @no_mysql
-    def test26_inherited_geofields(self):
-        "Test GeoQuerySet methods on inherited Geometry fields."
-        # Creating a Pennsylvanian city.
-        mansfield = PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)')
+    @no_spatialite # SpatiaLite does not have an Extent function
+    def test_extent(self):
+        "Testing the `extent` GeoQuerySet method."
+        # Reference query:
+        # `SELECT ST_extent(point) FROM geoapp_city WHERE (name='Houston' or name='Dallas');`
+        #   =>  BOX(-96.8016128540039 29.7633724212646,-95.3631439208984 32.7820587158203)
+        expected = (-96.8016128540039, 29.7633724212646, -95.3631439208984, 32.782058715820)
 
-        # All transformation SQL will need to be performed on the
-        # _parent_ table.
-        qs = PennsylvaniaCity.objects.transform(32128)
+        qs = City.objects.filter(name__in=('Houston', 'Dallas'))
+        extent = qs.extent()
 
-        self.assertEqual(1, qs.count())
-        for pc in qs: self.assertEqual(32128, pc.point.srid)
+        for val, exp in zip(extent, expected):
+            self.assertAlmostEqual(exp, val, 4)
 
     @no_mysql
     @no_oracle
     @no_spatialite
-    def test27_snap_to_grid(self):
+    def test_force_rhr(self):
+        "Testing GeoQuerySet.force_rhr()."
+        rings = ( ( (0, 0), (5, 0), (0, 5), (0, 0) ),
+                  ( (1, 1), (1, 3), (3, 1), (1, 1) ),
+                  )
+        rhr_rings = ( ( (0, 0), (0, 5), (5, 0), (0, 0) ),
+                      ( (1, 1), (3, 1), (1, 3), (1, 1) ),
+                      )
+        State.objects.create(name='Foo', poly=Polygon(*rings))
+        s = State.objects.force_rhr().get(name='Foo')
+        self.assertEqual(rhr_rings, s.force_rhr.coords)
+
+    @no_mysql
+    @no_oracle
+    @no_spatialite
+    def test_geohash(self):
+        "Testing GeoQuerySet.geohash()."
+        if not connection.ops.geohash: return
+        # Reference query:
+        # SELECT ST_GeoHash(point) FROM geoapp_city WHERE name='Houston';
+        # SELECT ST_GeoHash(point, 5) FROM geoapp_city WHERE name='Houston';
+        ref_hash = '9vk1mfq8jx0c8e0386z6'
+        h1 = City.objects.geohash().get(name='Houston')
+        h2 = City.objects.geohash(precision=5).get(name='Houston')
+        self.assertEqual(ref_hash, h1.geohash)
+        self.assertEqual(ref_hash[:5], h2.geohash)
+
+    def test_geojson(self):
+        "Testing GeoJSON output from the database using GeoQuerySet.geojson()."
+        # Only PostGIS 1.3.4+ supports GeoJSON.
+        if not connection.ops.geojson:
+            self.assertRaises(NotImplementedError, Country.objects.all().geojson, field_name='mpoly')
+            return
+
+        if connection.ops.spatial_version >= (1, 4, 0):
+            pueblo_json = '{"type":"Point","coordinates":[-104.609252,38.255001]}'
+            houston_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"coordinates":[-95.363151,29.763374]}'
+            victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.305196,48.462611]}'
+            chicago_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}'
+        else:
+            pueblo_json = '{"type":"Point","coordinates":[-104.60925200,38.25500100]}'
+            houston_json = '{"type":"Point","crs":{"type":"EPSG","properties":{"EPSG":4326}},"coordinates":[-95.36315100,29.76337400]}'
+            victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.30519600,48.46261100]}'
+            chicago_json = '{"type":"Point","crs":{"type":"EPSG","properties":{"EPSG":4326}},"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}'
+
+        # Precision argument should only be an integer
+        self.assertRaises(TypeError, City.objects.geojson, precision='foo')
+
+        # Reference queries and values.
+        # SELECT ST_AsGeoJson("geoapp_city"."point", 8, 0) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Pueblo';
+        self.assertEqual(pueblo_json, City.objects.geojson().get(name='Pueblo').geojson)
+
+        # 1.3.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 1) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston';
+        # 1.4.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 2) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston';
+        # This time we want to include the CRS by using the `crs` keyword.
+        self.assertEqual(houston_json, City.objects.geojson(crs=True, model_att='json').get(name='Houston').json)
+
+        # 1.3.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 2) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Victoria';
+        # 1.4.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 1) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston';
+        # This time we include the bounding box by using the `bbox` keyword.
+        self.assertEqual(victoria_json, City.objects.geojson(bbox=True).get(name='Victoria').geojson)
+
+        # 1.(3|4).x: SELECT ST_AsGeoJson("geoapp_city"."point", 5, 3) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Chicago';
+        # Finally, we set every available keyword.
+        self.assertEqual(chicago_json, City.objects.geojson(bbox=True, crs=True, precision=5).get(name='Chicago').geojson)
+
+    def test_gml(self):
+        "Testing GML output from the database using GeoQuerySet.gml()."
+        if mysql or (spatialite and not connection.ops.gml) :
+            self.assertRaises(NotImplementedError, Country.objects.all().gml, field_name='mpoly')
+            return
+
+        # Should throw a TypeError when tyring to obtain GML from a
+        # non-geometry field.
+        qs = City.objects.all()
+        self.assertRaises(TypeError, qs.gml, field_name='name')
+        ptown1 = City.objects.gml(field_name='point', precision=9).get(name='Pueblo')
+        ptown2 = City.objects.gml(precision=9).get(name='Pueblo')
+
+        if oracle:
+            # No precision parameter for Oracle :-/
+            gml_regex = re.compile(r'^<gml:Point srsName="SDO:4326" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates decimal="\." cs="," ts=" ">-104.60925\d+,38.25500\d+ </gml:coordinates></gml:Point>')
+        elif spatialite:
+            # Spatialite has extra colon in SrsName
+            gml_regex = re.compile(r'^<gml:Point SrsName="EPSG::4326"><gml:coordinates decimal="\." cs="," ts=" ">-104.609251\d+,38.255001</gml:coordinates></gml:Point>')
+        else:
+            gml_regex = re.compile(r'^<gml:Point srsName="EPSG:4326"><gml:coordinates>-104\.60925\d+,38\.255001</gml:coordinates></gml:Point>')
+
+        for ptown in [ptown1, ptown2]:
+            self.assertTrue(gml_regex.match(ptown.gml))
+
+    def test_kml(self):
+        "Testing KML output from the database using GeoQuerySet.kml()."
+        # Only PostGIS and Spatialite (>=2.4.0-RC4) support KML serialization
+        if not (postgis or (spatialite and connection.ops.kml)):
+            self.assertRaises(NotImplementedError, State.objects.all().kml, field_name='poly')
+            return
+
+        # Should throw a TypeError when trying to obtain KML from a
+        #  non-geometry field.
+        qs = City.objects.all()
+        self.assertRaises(TypeError, qs.kml, 'name')
+
+        # The reference KML depends on the version of PostGIS used
+        # (the output stopped including altitude in 1.3.3).
+        if connection.ops.spatial_version >= (1, 3, 3):
+            ref_kml =  '<Point><coordinates>-104.609252,38.255001</coordinates></Point>'
+        else:
+            ref_kml = '<Point><coordinates>-104.609252,38.255001,0</coordinates></Point>'
+
+        # Ensuring the KML is as expected.
+        ptown1 = City.objects.kml(field_name='point', precision=9).get(name='Pueblo')
+        ptown2 = City.objects.kml(precision=9).get(name='Pueblo')
+        for ptown in [ptown1, ptown2]:
+            self.assertEqual(ref_kml, ptown.kml)
+
+    # Only PostGIS has support for the MakeLine aggregate.
+    @no_mysql
+    @no_oracle
+    @no_spatialite
+    def test_make_line(self):
+        "Testing the `make_line` GeoQuerySet method."
+        # Ensuring that a `TypeError` is raised on models without PointFields.
+        self.assertRaises(TypeError, State.objects.make_line)
+        self.assertRaises(TypeError, Country.objects.make_line)
+        # Reference query:
+        # SELECT AsText(ST_MakeLine(geoapp_city.point)) FROM geoapp_city;
+        ref_line = GEOSGeometry('LINESTRING(-95.363151 29.763374,-96.801611 32.782057,-97.521157 34.464642,174.783117 -41.315268,-104.609252 38.255001,-95.23506 38.971823,-87.650175 41.850385,-123.305196 48.462611)', srid=4326)
+        self.assertEqual(ref_line, City.objects.make_line())
+
+    @no_mysql
+    def test_num_geom(self):
+        "Testing the `num_geom` GeoQuerySet method."
+        # Both 'countries' only have two geometries.
+        for c in Country.objects.num_geom(): self.assertEqual(2, c.num_geom)
+        for c in City.objects.filter(point__isnull=False).num_geom():
+            # Oracle will return 1 for the number of geometries on non-collections,
+            # whereas PostGIS will return None.
+            if postgis:
+                self.assertEqual(None, c.num_geom)
+            else:
+                self.assertEqual(1, c.num_geom)
+
+    @no_mysql
+    @no_spatialite # SpatiaLite can only count vertices in LineStrings
+    def test_num_points(self):
+        "Testing the `num_points` GeoQuerySet method."
+        for c in Country.objects.num_points():
+            self.assertEqual(c.mpoly.num_points, c.num_points)
+
+        if not oracle:
+            # Oracle cannot count vertices in Point geometries.
+            for c in City.objects.num_points(): self.assertEqual(1, c.num_points)
+
+    @no_mysql
+    def test_point_on_surface(self):
+        "Testing the `point_on_surface` GeoQuerySet method."
+        # Reference values.
+        if oracle:
+            # SELECT SDO_UTIL.TO_WKTGEOMETRY(SDO_GEOM.SDO_POINTONSURFACE(GEOAPP_COUNTRY.MPOLY, 0.05)) FROM GEOAPP_COUNTRY;
+            ref = {'New Zealand' : fromstr('POINT (174.616364 -36.100861)', srid=4326),
+                   'Texas' : fromstr('POINT (-103.002434 36.500397)', srid=4326),
+                   }
+
+        elif postgis or spatialite:
+            # Using GEOSGeometry to compute the reference point on surface values
+            # -- since PostGIS also uses GEOS these should be the same.
+            ref = {'New Zealand' : Country.objects.get(name='New Zealand').mpoly.point_on_surface,
+                   'Texas' : Country.objects.get(name='Texas').mpoly.point_on_surface
+                   }
+
+        for c in Country.objects.point_on_surface():
+            if spatialite:
+                # XXX This seems to be a WKT-translation-related precision issue?
+                tol = 0.00001
+            else:
+                tol = 0.000000001
+            self.assertEqual(True, ref[c.name].equals_exact(c.point_on_surface, tol))
+
+    @no_mysql
+    @no_spatialite
+    def test_reverse_geom(self):
+        "Testing GeoQuerySet.reverse_geom()."
+        coords = [ (-95.363151, 29.763374), (-95.448601, 29.713803) ]
+        Track.objects.create(name='Foo', line=LineString(coords))
+        t = Track.objects.reverse_geom().get(name='Foo')
+        coords.reverse()
+        self.assertEqual(tuple(coords), t.reverse_geom.coords)
+        if oracle:
+            self.assertRaises(TypeError, State.objects.reverse_geom)
+
+    @no_mysql
+    @no_oracle
+    def test_scale(self):
+        "Testing the `scale` GeoQuerySet method."
+        xfac, yfac = 2, 3
+        tol = 5 # XXX The low precision tolerance is for SpatiaLite
+        qs = Country.objects.scale(xfac, yfac, model_att='scaled')
+        for c in qs:
+            for p1, p2 in zip(c.mpoly, c.scaled):
+                for r1, r2 in zip(p1, p2):
+                    for c1, c2 in zip(r1.coords, r2.coords):
+                        self.assertAlmostEqual(c1[0] * xfac, c2[0], tol)
+                        self.assertAlmostEqual(c1[1] * yfac, c2[1], tol)
+
+    @no_mysql
+    @no_oracle
+    @no_spatialite
+    def test_snap_to_grid(self):
         "Testing GeoQuerySet.snap_to_grid()."
         # Let's try and break snap_to_grid() with bad combinations of arguments.
         for bad_args in ((), range(3), range(5)):
@@ -695,48 +672,78 @@ class GeoModelTest(TestCase):
         ref = fromstr('MULTIPOLYGON(((12.4 43.87,12.45 43.87,12.45 44.1,12.5 44.1,12.5 43.87,12.45 43.87,12.4 43.87)))')
         self.assertTrue(ref.equals_exact(Country.objects.snap_to_grid(0.05, 0.23, 0.5, 0.17).get(name='San Marino').snap_to_grid, tol))
 
+    def test_svg(self):
+        "Testing SVG output using GeoQuerySet.svg()."
+        if mysql or oracle:
+            self.assertRaises(NotImplementedError, City.objects.svg)
+            return
+
+        self.assertRaises(TypeError, City.objects.svg, precision='foo')
+        # SELECT AsSVG(geoapp_city.point, 0, 8) FROM geoapp_city WHERE name = 'Pueblo';
+        svg1 = 'cx="-104.609252" cy="-38.255001"'
+        # Even though relative, only one point so it's practically the same except for
+        # the 'c' letter prefix on the x,y values.
+        svg2 = svg1.replace('c', '')
+        self.assertEqual(svg1, City.objects.svg().get(name='Pueblo').svg)
+        self.assertEqual(svg2, City.objects.svg(relative=5).get(name='Pueblo').svg)
+
     @no_mysql
-    @no_spatialite
-    def test28_reverse(self):
-        "Testing GeoQuerySet.reverse_geom()."
-        coords = [ (-95.363151, 29.763374), (-95.448601, 29.713803) ]
-        Track.objects.create(name='Foo', line=LineString(coords))
-        t = Track.objects.reverse_geom().get(name='Foo')
-        coords.reverse()
-        self.assertEqual(tuple(coords), t.reverse_geom.coords)
+    def test_transform(self):
+        "Testing the transform() GeoQuerySet method."
+        # Pre-transformed points for Houston and Pueblo.
+        htown = fromstr('POINT(1947516.83115183 6322297.06040572)', srid=3084)
+        ptown = fromstr('POINT(992363.390841912 481455.395105533)', srid=2774)
+        prec = 3 # Precision is low due to version variations in PROJ and GDAL.
+
+        # Asserting the result of the transform operation with the values in
+        #  the pre-transformed points.  Oracle does not have the 3084 SRID.
+        if not oracle:
+            h = City.objects.transform(htown.srid).get(name='Houston')
+            self.assertEqual(3084, h.point.srid)
+            self.assertAlmostEqual(htown.x, h.point.x, prec)
+            self.assertAlmostEqual(htown.y, h.point.y, prec)
+
+        p1 = City.objects.transform(ptown.srid, field_name='point').get(name='Pueblo')
+        p2 = City.objects.transform(srid=ptown.srid).get(name='Pueblo')
+        for p in [p1, p2]:
+            self.assertEqual(2774, p.point.srid)
+            self.assertAlmostEqual(ptown.x, p.point.x, prec)
+            self.assertAlmostEqual(ptown.y, p.point.y, prec)
+
+    @no_mysql
+    @no_oracle
+    def test_translate(self):
+        "Testing the `translate` GeoQuerySet method."
+        xfac, yfac = 5, -23
+        qs = Country.objects.translate(xfac, yfac, model_att='translated')
+        for c in qs:
+            for p1, p2 in zip(c.mpoly, c.translated):
+                for r1, r2 in zip(p1, p2):
+                    for c1, c2 in zip(r1.coords, r2.coords):
+                        # XXX The low precision is for SpatiaLite
+                        self.assertAlmostEqual(c1[0] + xfac, c2[0], 5)
+                        self.assertAlmostEqual(c1[1] + yfac, c2[1], 5)
+
+    @no_mysql
+    def test_unionagg(self):
+        "Testing the `unionagg` (aggregate union) GeoQuerySet method."
+        tx = Country.objects.get(name='Texas').mpoly
+        # Houston, Dallas -- Oracle has different order.
+        union1 = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)')
+        union2 = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)')
+        qs = City.objects.filter(point__within=tx)
+        self.assertRaises(TypeError, qs.unionagg, 'name')
+        # Using `field_name` keyword argument in one query and specifying an
+        # order in the other (which should not be used because this is
+        # an aggregate method on a spatial column)
+        u1 = qs.unionagg(field_name='point')
+        u2 = qs.order_by('name').unionagg()
+        tol = 0.00001
         if oracle:
-            self.assertRaises(TypeError, State.objects.reverse_geom)
-
-    @no_mysql
-    @no_oracle
-    @no_spatialite
-    def test29_force_rhr(self):
-        "Testing GeoQuerySet.force_rhr()."
-        rings = ( ( (0, 0), (5, 0), (0, 5), (0, 0) ),
-                  ( (1, 1), (1, 3), (3, 1), (1, 1) ),
-                  )
-        rhr_rings = ( ( (0, 0), (0, 5), (5, 0), (0, 0) ),
-                      ( (1, 1), (3, 1), (1, 3), (1, 1) ),
-                      )
-        State.objects.create(name='Foo', poly=Polygon(*rings))
-        s = State.objects.force_rhr().get(name='Foo')
-        self.assertEqual(rhr_rings, s.force_rhr.coords)
-
-    @no_mysql
-    @no_oracle
-    @no_spatialite
-    def test30_geohash(self):
-        "Testing GeoQuerySet.geohash()."
-        if not connection.ops.geohash: return
-        # Reference query:
-        # SELECT ST_GeoHash(point) FROM geoapp_city WHERE name='Houston';
-        # SELECT ST_GeoHash(point, 5) FROM geoapp_city WHERE name='Houston';
-        ref_hash = '9vk1mfq8jx0c8e0386z6'
-        h1 = City.objects.geohash().get(name='Houston')
-        h2 = City.objects.geohash(precision=5).get(name='Houston')
-        self.assertEqual(ref_hash, h1.geohash)
-        self.assertEqual(ref_hash[:5], h2.geohash)
-
-from .test_feeds import GeoFeedTest
-from .test_regress import GeoRegressionTests
-from .test_sitemaps import GeoSitemapTest
+            union = union2
+        else:
+            union = union1
+        self.assertEqual(True, union.equals_exact(u1, tol))
+        self.assertEqual(True, union.equals_exact(u2, tol))
+        qs = City.objects.filter(name='NotACity')
+        self.assertEqual(None, qs.unionagg(field_name='point'))

From 083a3a4e39bc3ead6090e862935d223d8719c4ce Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Fri, 3 Aug 2012 05:17:52 -0400
Subject: [PATCH 25/88] Fixed #13904 - Documented how to avoid garbage
 collection messages in GIS.

Thanks Claude Peroz for the patch.
---
 docs/ref/contrib/gis/geos.txt    | 11 +++++++++++
 docs/ref/contrib/gis/install.txt |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/docs/ref/contrib/gis/geos.txt b/docs/ref/contrib/gis/geos.txt
index eda96173812..f4e706d2757 100644
--- a/docs/ref/contrib/gis/geos.txt
+++ b/docs/ref/contrib/gis/geos.txt
@@ -75,6 +75,17 @@ return a :class:`GEOSGeometry` object from an input string or a file::
     >>> pnt = fromfile('/path/to/pnt.wkt')
     >>> pnt = fromfile(open('/path/to/pnt.wkt'))
 
+.. _geos-exceptions-in-logfile:
+
+.. admonition:: My logs are filled with GEOS-related errors
+
+    You find many ``TypeError`` or ``AttributeError`` exceptions filling your
+    Web server's log files. This generally means that you are creating GEOS
+    objects at the top level of some of your Python modules. Then, due to a race
+    condition in the garbage collector, your module is garbage collected before
+    the GEOS object. To prevent this, create :class:`GEOSGeometry` objects
+    inside the local scope of your functions/methods.
+
 Geometries are Pythonic
 -----------------------
 :class:`GEOSGeometry` objects are 'Pythonic', in other words components may
diff --git a/docs/ref/contrib/gis/install.txt b/docs/ref/contrib/gis/install.txt
index 5ee6d5153d8..72bd72a6f81 100644
--- a/docs/ref/contrib/gis/install.txt
+++ b/docs/ref/contrib/gis/install.txt
@@ -191,6 +191,8 @@ GEOS C library.  For example:
     The setting must be the *full* path to the **C** shared library; in
     other words you want to use ``libgeos_c.so``, not ``libgeos.so``.
 
+See also :ref:`My logs are filled with GEOS-related errors <geos-exceptions-in-logfile>`.
+
 .. _proj4:
 
 PROJ.4

From 2407c45c180703f935a2280cb3325beadc2ac8cc Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Fri, 3 Aug 2012 11:26:47 +0200
Subject: [PATCH 26/88] Removed some pre-1.3.0 postgis compatibility code

---
 .../gis/db/backends/postgis/operations.py     | 37 +++++--------------
 1 file changed, 9 insertions(+), 28 deletions(-)

diff --git a/django/contrib/gis/db/backends/postgis/operations.py b/django/contrib/gis/db/backends/postgis/operations.py
index a6340ce22b2..bd249df179d 100644
--- a/django/contrib/gis/db/backends/postgis/operations.py
+++ b/django/contrib/gis/db/backends/postgis/operations.py
@@ -163,7 +163,9 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
             'contains' : PostGISFunction(prefix, 'Contains'),
             'intersects' : PostGISFunction(prefix, 'Intersects'),
             'relate' : (PostGISRelate, six.string_types),
-            }
+            'coveredby' : PostGISFunction(prefix, 'CoveredBy'),
+            'covers' : PostGISFunction(prefix, 'Covers'),
+        }
 
         # Valid distance types and substitutions
         dtypes = (Decimal, Distance, float) + six.integer_types
@@ -178,33 +180,12 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
             'distance_gte' : (get_dist_ops('>='), dtypes),
             'distance_lt' : (get_dist_ops('<'), dtypes),
             'distance_lte' : (get_dist_ops('<='), dtypes),
-            }
-
-        # Versions 1.2.2+ have KML serialization support.
-        if version < (1, 2, 2):
-            ASKML = False
-        else:
-            ASKML = 'ST_AsKML'
-            self.geometry_functions.update(
-                {'coveredby' : PostGISFunction(prefix, 'CoveredBy'),
-                 'covers' : PostGISFunction(prefix, 'Covers'),
-                 })
-            self.distance_functions['dwithin'] = (PostGISFunctionParam(prefix, 'DWithin'), dtypes)
+            'dwithin' : (PostGISFunctionParam(prefix, 'DWithin'), dtypes)
+        }
 
         # Adding the distance functions to the geometries lookup.
         self.geometry_functions.update(self.distance_functions)
 
-        # The union aggregate and topology operation use the same signature
-        # in versions 1.3+.
-        if version < (1, 3, 0):
-            UNIONAGG = 'GeomUnion'
-            UNION = 'Union'
-            MAKELINE = False
-        else:
-            UNIONAGG = 'ST_Union'
-            UNION = 'ST_Union'
-            MAKELINE = 'ST_MakeLine'
-
         # Only PostGIS versions 1.3.4+ have GeoJSON serialization support.
         if version < (1, 3, 4):
             GEOJSON = False
@@ -256,11 +237,11 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
         self.geojson = GEOJSON
         self.gml = prefix + 'AsGML'
         self.intersection = prefix + 'Intersection'
-        self.kml = ASKML
+        self.kml = prefix + 'AsKML'
         self.length = prefix + 'Length'
         self.length3d = prefix + 'Length3D'
         self.length_spheroid = prefix + 'length_spheroid'
-        self.makeline = MAKELINE
+        self.makeline = prefix + 'MakeLine'
         self.mem_size = prefix + 'mem_size'
         self.num_geom = prefix + 'NumGeometries'
         self.num_points =prefix + 'npoints'
@@ -275,8 +256,8 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
         self.sym_difference = prefix + 'SymDifference'
         self.transform = prefix + 'Transform'
         self.translate = prefix + 'Translate'
-        self.union = UNION
-        self.unionagg = UNIONAGG
+        self.union = prefix + 'Union'
+        self.unionagg = prefix + 'Union'
 
     def check_aggregate_support(self, aggregate):
         """

From 9908201d7fc3340b83db21298033c5b347f38d65 Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Fri, 3 Aug 2012 15:18:13 +0200
Subject: [PATCH 27/88] Replaced some byte strings by str() calls

This is a useful trick when Python 2 awaits byte strings and
Python 3 Unicode (regular) strings.
---
 django/core/handlers/wsgi.py       |  2 +-
 django/db/backends/sqlite3/base.py | 16 ++++++++--------
 django/db/models/base.py           |  4 ++--
 django/forms/formsets.py           |  2 +-
 django/forms/models.py             |  4 ++--
 django/http/__init__.py            |  2 +-
 6 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py
index 617068a21ca..51ad2be002a 100644
--- a/django/core/handlers/wsgi.py
+++ b/django/core/handlers/wsgi.py
@@ -245,6 +245,6 @@ class WSGIHandler(base.BaseHandler):
         status = '%s %s' % (response.status_code, status_text)
         response_headers = [(str(k), str(v)) for k, v in response.items()]
         for c in response.cookies.values():
-            response_headers.append((b'Set-Cookie', str(c.output(header=''))))
+            response_headers.append((str('Set-Cookie'), str(c.output(header=''))))
         start_response(smart_str(status), response_headers)
         return response
diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index 0a974497892..08800791898 100644
--- a/django/db/backends/sqlite3/base.py
+++ b/django/db/backends/sqlite3/base.py
@@ -54,15 +54,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(b" ")
+    return value.isoformat(str(" "))
 
-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_converter(str("bool"), lambda s: str(s) == '1')
+Database.register_converter(str("time"), parse_time)
+Database.register_converter(str("date"), parse_date)
+Database.register_converter(str("datetime"), parse_datetime_with_timezone_support)
+Database.register_converter(str("timestamp"), parse_datetime_with_timezone_support)
+Database.register_converter(str("TIMESTAMP"), parse_datetime_with_timezone_support)
+Database.register_converter(str("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):
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 002e2aff659..8dd5bf864f2 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -63,12 +63,12 @@ class ModelBase(type):
 
         new_class.add_to_class('_meta', Options(meta, **kwargs))
         if not abstract:
-            new_class.add_to_class('DoesNotExist', subclass_exception(b'DoesNotExist',
+            new_class.add_to_class('DoesNotExist', subclass_exception(str('DoesNotExist'),
                     tuple(x.DoesNotExist
                           for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
                     or (ObjectDoesNotExist,),
                     module, attached_to=new_class))
-            new_class.add_to_class('MultipleObjectsReturned', subclass_exception(b'MultipleObjectsReturned',
+            new_class.add_to_class('MultipleObjectsReturned', subclass_exception(str('MultipleObjectsReturned'),
                     tuple(x.MultipleObjectsReturned
                           for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
                     or (MultipleObjectsReturned,),
diff --git a/django/forms/formsets.py b/django/forms/formsets.py
index 240cf71f436..1ec83404620 100644
--- a/django/forms/formsets.py
+++ b/django/forms/formsets.py
@@ -365,7 +365,7 @@ def formset_factory(form, formset=BaseFormSet, extra=1, can_order=False,
     attrs = {'form': form, 'extra': extra,
              'can_order': can_order, 'can_delete': can_delete,
              'max_num': max_num}
-    return type(form.__name__ + b'FormSet', (formset,), attrs)
+    return type(form.__name__ + str('FormSet'), (formset,), attrs)
 
 def all_valid(formsets):
     """Returns true if every formset in formsets is valid."""
diff --git a/django/forms/models.py b/django/forms/models.py
index 4d56f1d38ab..b5939b6be31 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -389,10 +389,10 @@ def modelform_factory(model, form=ModelForm, fields=None, exclude=None,
     parent = (object,)
     if hasattr(form, 'Meta'):
         parent = (form.Meta, object)
-    Meta = type(b'Meta', parent, attrs)
+    Meta = type(str('Meta'), parent, attrs)
 
     # Give this new form class a reasonable name.
-    class_name = model.__name__ + b'Form'
+    class_name = model.__name__ + str('Form')
 
     # Class attributes for the new form class.
     form_class_attrs = {
diff --git a/django/http/__init__.py b/django/http/__init__.py
index 19b581f5cb2..4c2db74890c 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -22,7 +22,7 @@ _cookie_encodes_correctly = http_cookies.SimpleCookie().value_encode(';') == (';
 # See ticket #13007, http://bugs.python.org/issue2193 and http://trac.edgewall.org/ticket/2256
 _tc = http_cookies.SimpleCookie()
 try:
-    _tc.load(b'foo:bar=1')
+    _tc.load(str('foo:bar=1'))
     _cookie_allows_colon_in_names = True
 except http_cookies.CookieError:
     _cookie_allows_colon_in_names = False

From 5aec69ed290552e7ea20bdef416c5bc23f6231f8 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Fri, 3 Aug 2012 15:40:29 +0200
Subject: [PATCH 28/88] Documented the trick used in 9908201d7f.

---
 docs/topics/python3.txt | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/docs/topics/python3.txt b/docs/topics/python3.txt
index 3f799edac77..b09c1d23478 100644
--- a/docs/topics/python3.txt
+++ b/docs/topics/python3.txt
@@ -36,6 +36,11 @@ In order to enable the same behavior in Python 2, every module must import
     my_string = "This is an unicode literal"
     my_bytestring = b"This is a bytestring"
 
+If you need a byte string under Python 2 and a unicode string under Python 3,
+use the :func:`str` builtin::
+
+    str('my string')
+
 Be cautious if you have to `slice bytestrings`_.
 
 .. _slice bytestrings: http://docs.python.org/py3k/howto/pyporting.html#bytes-literals

From 129f1ac8484d63c2e61a44fb2a18dd17246c1c4d Mon Sep 17 00:00:00 2001
From: Alex Gaynor <alex.gaynor@gmail.com>
Date: Fri, 3 Aug 2012 07:10:04 -0700
Subject: [PATCH 29/88] Remove a temporary variable deletion, it's not a big
 deal and it doesn't exist on python3.

---
 django/utils/html.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/django/utils/html.py b/django/utils/html.py
index ca3340ccb17..e1263fbd66b 100644
--- a/django/utils/html.py
+++ b/django/utils/html.py
@@ -33,7 +33,7 @@ link_target_attribute_re = re.compile(r'(<a [^>]*?)target=[^\s>]+')
 html_gunk_re = re.compile(r'(?:<br clear="all">|<i><\/i>|<b><\/b>|<em><\/em>|<strong><\/strong>|<\/?smallcaps>|<\/?uppercase>)', re.IGNORECASE)
 hard_coded_bullets_re = re.compile(r'((?:<p>(?:%s).*?[a-zA-Z].*?</p>\s*)+)' % '|'.join([re.escape(x) for x in DOTS]), re.DOTALL)
 trailing_empty_content_re = re.compile(r'(?:<p>(?:&nbsp;|\s|<br \/>)*?</p>\s*)+\Z')
-del x # Temporary variable
+
 
 def escape(text):
     """

From d01eaf7104e96b2fcf373ddfbc80ef4568bd0387 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Fri, 3 Aug 2012 18:46:30 +0200
Subject: [PATCH 30/88] [py3] Removed uses of sys.maxint under Python 3.

Also fixed #18706: improved exceptions raised by int_to_base36.
---
 django/utils/http.py                | 14 ++++++++++----
 docs/ref/utils.txt                  |  6 ++++--
 docs/releases/1.5.txt               |  3 +++
 tests/regressiontests/utils/http.py | 26 ++++++++++++++------------
 4 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/django/utils/http.py b/django/utils/http.py
index f3a3dce58ca..272e73f1902 100644
--- a/django/utils/http.py
+++ b/django/utils/http.py
@@ -167,8 +167,9 @@ def base36_to_int(s):
     if len(s) > 13:
         raise ValueError("Base36 input too large")
     value = int(s, 36)
-    # ... then do a final check that the value will fit into an int.
-    if value > sys.maxint:
+    # ... then do a final check that the value will fit into an int to avoid
+    # returning a long (#15067). The long type was removed in Python 3.
+    if not six.PY3 and value > sys.maxint:
         raise ValueError("Base36 input too large")
     return value
 
@@ -178,8 +179,13 @@ def int_to_base36(i):
     """
     digits = "0123456789abcdefghijklmnopqrstuvwxyz"
     factor = 0
-    if not 0 <= i <= sys.maxint:
-        raise ValueError("Base36 conversion input too large or incorrect type.")
+    if i < 0:
+        raise ValueError("Negative base36 conversion input.")
+    if not six.PY3:
+        if not isinstance(i, six.integer_types):
+            raise TypeError("Non-integer base36 conversion input.")
+        if i > sys.maxint:
+            raise ValueError("Base36 conversion input too large.")
     # Find starting factor
     while True:
         factor += 1
diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt
index c2f2025bc3d..5157c399da7 100644
--- a/docs/ref/utils.txt
+++ b/docs/ref/utils.txt
@@ -504,11 +504,13 @@ escaping HTML.
 
 .. function:: base36_to_int(s)
 
-    Converts a base 36 string to an integer.
+    Converts a base 36 string to an integer. On Python 2 the output is
+    guaranteed to be an :class:`int` and not a :class:`long`.
 
 .. function:: int_to_base36(i)
 
-    Converts a positive integer less than sys.maxint to a base 36 string.
+    Converts a positive integer to a base 36 string. On Python 2 ``i`` must be
+    smaller than :attr:`sys.maxint`.
 
 ``django.utils.safestring``
 ===========================
diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt
index aae8b25e074..968d63e1f36 100644
--- a/docs/releases/1.5.txt
+++ b/docs/releases/1.5.txt
@@ -244,6 +244,9 @@ Miscellaneous
 
 * GeoDjango dropped support for GDAL < 1.5
 
+* :func:`~django.utils.http.int_to_base36` properly raises a :exc:`TypeError`
+  instead of :exc:`ValueError` for non-integer inputs.
+
 Features deprecated in 1.5
 ==========================
 
diff --git a/tests/regressiontests/utils/http.py b/tests/regressiontests/utils/http.py
index 67dcd7af89e..f22e05496da 100644
--- a/tests/regressiontests/utils/http.py
+++ b/tests/regressiontests/utils/http.py
@@ -1,10 +1,11 @@
 import sys
 
-from django.utils import http
-from django.utils import unittest
-from django.utils.datastructures import MultiValueDict
 from django.http import HttpResponse, utils
 from django.test import RequestFactory
+from django.utils.datastructures import MultiValueDict
+from django.utils import http
+from django.utils import six
+from django.utils import unittest
 
 class TestUtilsHttp(unittest.TestCase):
 
@@ -110,22 +111,23 @@ class TestUtilsHttp(unittest.TestCase):
 
     def test_base36(self):
         # reciprocity works
-        for n in [0, 1, 1000, 1000000, sys.maxint]:
+        for n in [0, 1, 1000, 1000000]:
             self.assertEqual(n, http.base36_to_int(http.int_to_base36(n)))
+        if not six.PY3:
+            self.assertEqual(sys.maxint, http.base36_to_int(http.int_to_base36(sys.maxint)))
 
         # bad input
-        for n in [-1, sys.maxint+1, '1', 'foo', {1:2}, (1,2,3)]:
-            self.assertRaises(ValueError, http.int_to_base36, n)
-        
+        self.assertRaises(ValueError, http.int_to_base36, -1)
+        if not six.PY3:
+            self.assertRaises(ValueError, http.int_to_base36, sys.maxint + 1)
+        for n in ['1', 'foo', {1: 2}, (1, 2, 3), 3.141]:
+            self.assertRaises(TypeError, http.int_to_base36, n)
+
         for n in ['#', ' ']:
             self.assertRaises(ValueError, http.base36_to_int, n)
-
-        for n in [123, {1:2}, (1,2,3)]:
+        for n in [123, {1: 2}, (1, 2, 3), 3.141]:
             self.assertRaises(TypeError, http.base36_to_int, n)
 
-        # non-integer input
-        self.assertRaises(TypeError, http.int_to_base36, 3.141)
-        
         # more explicit output testing
         for n, b36 in [(0, '0'), (1, '1'), (42, '16'), (818469960, 'django')]:
             self.assertEqual(http.int_to_base36(n), b36)

From b496be331c19f41bee3a8f6c79de0722f91d6662 Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Fri, 3 Aug 2012 16:06:41 -0400
Subject: [PATCH 31/88] Fixed #15932 - Documented how to supress multiple
 reverse relations to the same model.

Thanks Claude Paroz for the patch.
---
 docs/ref/models/fields.txt | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt
index 5039ba4373d..67bb0f141f1 100644
--- a/docs/ref/models/fields.txt
+++ b/docs/ref/models/fields.txt
@@ -1002,9 +1002,10 @@ define the details of how the relation works.
     <abstract-base-classes>`; and when you do so
     :ref:`some special syntax <abstract-related-name>` is available.
 
-    If you'd prefer Django didn't create a backwards relation, set ``related_name``
-    to ``'+'``. For example, this will ensure that the ``User`` model won't get a
-    backwards relation to this model::
+    If you'd prefer Django not to create a backwards relation, set
+    ``related_name`` to ``'+'`` or end it with ``'+'``. For example, this will
+    ensure that the ``User`` model won't have a backwards relation to this
+    model::
 
         user = models.ForeignKey(User, related_name='+')
 
@@ -1095,6 +1096,13 @@ that control how the relationship functions.
 
     Same as :attr:`ForeignKey.related_name`.
 
+    If you have more than one ``ManyToManyField`` pointing to the same model
+    and want to suppress the backwards relations, set each ``related_name``
+    to a unique value ending with ``'+'``::
+
+        users = models.ManyToManyField(User, related_name='u+')
+        referents = models.ManyToManyField(User, related_name='ref+')
+
 .. attribute:: ManyToManyField.limit_choices_to
 
     Same as :attr:`ForeignKey.limit_choices_to`.

From 10f979fd92000de1ac9713351f5cb749e2cbca03 Mon Sep 17 00:00:00 2001
From: Simon Meers <simon@simonmeers.com>
Date: Fri, 3 Aug 2012 10:03:52 +1000
Subject: [PATCH 32/88] Fixed #18700 -- Added URL reversal for i18n
 set_language view.

---
 django/conf/urls/i18n.py                  | 4 ++--
 docs/topics/i18n/translation.txt          | 2 +-
 tests/regressiontests/views/tests/i18n.py | 4 ++++
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/django/conf/urls/i18n.py b/django/conf/urls/i18n.py
index 6e56af82710..426c2b2d30e 100644
--- a/django/conf/urls/i18n.py
+++ b/django/conf/urls/i18n.py
@@ -1,5 +1,5 @@
 from django.conf import settings
-from django.conf.urls import patterns
+from django.conf.urls import patterns, url
 from django.core.urlresolvers import LocaleRegexURLResolver
 
 def i18n_patterns(prefix, *args):
@@ -16,5 +16,5 @@ def i18n_patterns(prefix, *args):
 
 
 urlpatterns = patterns('',
-    (r'^setlang/$', 'django.views.i18n.set_language'),
+    url(r'^setlang/$', 'django.views.i18n.set_language', name='set_language'),
 )
diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt
index 988948e259b..bdbb04823d5 100644
--- a/docs/topics/i18n/translation.txt
+++ b/docs/topics/i18n/translation.txt
@@ -1272,7 +1272,7 @@ Here's example HTML template code:
 
 .. code-block:: html+django
 
-    <form action="/i18n/setlang/" method="post">
+    <form action="{% url 'set_language' %}" method="post">
     {% csrf_token %}
     <input name="next" type="hidden" value="{{ redirect_to }}" />
     <select name="language">
diff --git a/tests/regressiontests/views/tests/i18n.py b/tests/regressiontests/views/tests/i18n.py
index 9993ae959c8..cb580267d2c 100644
--- a/tests/regressiontests/views/tests/i18n.py
+++ b/tests/regressiontests/views/tests/i18n.py
@@ -5,6 +5,7 @@ import gettext
 from os import path
 
 from django.conf import settings
+from django.core.urlresolvers import reverse
 from django.test import TestCase
 from django.utils.translation import override, activate, get_language
 from django.utils.text import javascript_quote
@@ -23,6 +24,9 @@ class I18NTests(TestCase):
             self.assertRedirects(response, 'http://testserver/views/')
             self.assertEqual(self.client.session['django_language'], lang_code)
 
+    def test_setlang_reversal(self):
+        self.assertEqual(reverse('set_language'), '/views/i18n/setlang/')
+
     def test_jsi18n(self):
         """The javascript_catalog can be deployed with language settings"""
         saved_lang = get_language()

From 121fd109de09ece4e263e508f9034df9b583da46 Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Sat, 4 Aug 2012 14:17:02 +0200
Subject: [PATCH 33/88] Fixed #5524 -- Do not remove cleaned_data when a form
 fails validation

cleaned_data is no longer deleted when form validation fails but only
contains the data that did validate.
Thanks to the various contributors to this patch (see ticket).
---
 django/contrib/formtools/tests/__init__.py |  2 +-
 django/forms/forms.py                      |  2 --
 django/forms/models.py                     | 25 +++++++++++-----------
 docs/ref/forms/api.txt                     | 21 ++++++++++--------
 docs/ref/forms/validation.txt              | 10 +++++----
 docs/releases/1.5.txt                      | 10 +++++++++
 tests/modeltests/model_forms/tests.py      |  3 +--
 tests/regressiontests/forms/tests/forms.py | 24 ++++-----------------
 8 files changed, 46 insertions(+), 51 deletions(-)

diff --git a/django/contrib/formtools/tests/__init__.py b/django/contrib/formtools/tests/__init__.py
index 3bccb550340..ee93479cbd7 100644
--- a/django/contrib/formtools/tests/__init__.py
+++ b/django/contrib/formtools/tests/__init__.py
@@ -317,7 +317,7 @@ class WizardTests(TestCase):
 
         class WizardWithProcessStep(TestWizardClass):
             def process_step(self, request, form, step):
-                that.assertTrue(hasattr(form, 'cleaned_data'))
+                that.assertTrue(form.is_valid())
                 reached[0] = True
 
         wizard = WizardWithProcessStep([WizardPageOneForm,
diff --git a/django/forms/forms.py b/django/forms/forms.py
index 4bc3ee9d264..4d4cdbe3db5 100644
--- a/django/forms/forms.py
+++ b/django/forms/forms.py
@@ -271,8 +271,6 @@ class BaseForm(StrAndUnicode):
         self._clean_fields()
         self._clean_form()
         self._post_clean()
-        if self._errors:
-            del self.cleaned_data
 
     def _clean_fields(self):
         for name, field in self.fields.items():
diff --git a/django/forms/models.py b/django/forms/models.py
index b5939b6be31..e6ae357d192 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -506,7 +506,7 @@ class BaseModelFormSet(BaseFormSet):
         all_unique_checks = set()
         all_date_checks = set()
         for form in self.forms:
-            if not hasattr(form, 'cleaned_data'):
+            if not form.is_valid():
                 continue
             exclude = form._get_validation_exclusions()
             unique_checks, date_checks = form.instance._get_unique_checks(exclude=exclude)
@@ -518,21 +518,21 @@ class BaseModelFormSet(BaseFormSet):
         for uclass, unique_check in all_unique_checks:
             seen_data = set()
             for form in self.forms:
-                # if the form doesn't have cleaned_data then we ignore it,
-                # it's already invalid
-                if not hasattr(form, "cleaned_data"):
+                if not form.is_valid():
                     continue
                 # get data for each field of each of unique_check
                 row_data = tuple([form.cleaned_data[field] for field in unique_check if field in form.cleaned_data])
                 if row_data and not None in row_data:
-                    # if we've aready seen it then we have a uniqueness failure
+                    # if we've already seen it then we have a uniqueness failure
                     if row_data in seen_data:
                         # poke error messages into the right places and mark
                         # the form as invalid
                         errors.append(self.get_unique_error_message(unique_check))
                         form._errors[NON_FIELD_ERRORS] = self.error_class([self.get_form_error()])
-                        del form.cleaned_data
-                        break
+                        # remove the data from the cleaned_data dict since it was invalid
+                        for field in unique_check:
+                            if field in form.cleaned_data:
+                                del form.cleaned_data[field]
                     # mark the data as seen
                     seen_data.add(row_data)
         # iterate over each of the date checks now
@@ -540,9 +540,7 @@ class BaseModelFormSet(BaseFormSet):
             seen_data = set()
             uclass, lookup, field, unique_for = date_check
             for form in self.forms:
-                # if the form doesn't have cleaned_data then we ignore it,
-                # it's already invalid
-                if not hasattr(self, 'cleaned_data'):
+                if not form.is_valid():
                     continue
                 # see if we have data for both fields
                 if (form.cleaned_data and form.cleaned_data[field] is not None
@@ -556,14 +554,15 @@ class BaseModelFormSet(BaseFormSet):
                     else:
                         date_data = (getattr(form.cleaned_data[unique_for], lookup),)
                     data = (form.cleaned_data[field],) + date_data
-                    # if we've aready seen it then we have a uniqueness failure
+                    # if we've already seen it then we have a uniqueness failure
                     if data in seen_data:
                         # poke error messages into the right places and mark
                         # the form as invalid
                         errors.append(self.get_date_error_message(date_check))
                         form._errors[NON_FIELD_ERRORS] = self.error_class([self.get_form_error()])
-                        del form.cleaned_data
-                        break
+                        # remove the data from the cleaned_data dict since it was invalid
+                        del form.cleaned_data[field]
+                    # mark the data as seen
                     seen_data.add(data)
         if errors:
             raise ValidationError(errors)
diff --git a/docs/ref/forms/api.txt b/docs/ref/forms/api.txt
index 50488b026ae..777d73e0150 100644
--- a/docs/ref/forms/api.txt
+++ b/docs/ref/forms/api.txt
@@ -199,8 +199,8 @@ Note that any text-based field -- such as ``CharField`` or ``EmailField`` --
 always cleans the input into a Unicode string. We'll cover the encoding
 implications later in this document.
 
-If your data does *not* validate, your ``Form`` instance will not have a
-``cleaned_data`` attribute::
+If your data does *not* validate, the ``cleaned_data`` dictionary contains
+only the valid fields::
 
     >>> data = {'subject': '',
     ...         'message': 'Hi there',
@@ -210,9 +210,12 @@ If your data does *not* validate, your ``Form`` instance will not have a
     >>> f.is_valid()
     False
     >>> f.cleaned_data
-    Traceback (most recent call last):
-    ...
-    AttributeError: 'ContactForm' object has no attribute 'cleaned_data'
+    {'cc_myself': True, 'message': u'Hi there'}
+
+.. versionchanged:: 1.5
+
+Until Django 1.5, the ``cleaned_data`` attribute wasn't defined at all when
+the ``Form`` didn't validate.
 
 ``cleaned_data`` will always *only* contain a key for fields defined in the
 ``Form``, even if you pass extra data when you define the ``Form``. In this
@@ -232,9 +235,9 @@ but ``cleaned_data`` contains only the form's fields::
     >>> f.cleaned_data # Doesn't contain extra_field_1, etc.
     {'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
 
-``cleaned_data`` will include a key and value for *all* fields defined in the
-``Form``, even if the data didn't include a value for fields that are not
-required. In this example, the data dictionary doesn't include a value for the
+When the ``Form`` is valid, ``cleaned_data`` will include a key and value for
+*all* its fields, even if the data didn't include a value for some optional
+fields. In this example, the data dictionary doesn't include a value for the
 ``nick_name`` field, but ``cleaned_data`` includes it, with an empty value::
 
     >>> class OptionalPersonForm(Form):
@@ -583,7 +586,7 @@ lazy developers -- they're not the only way a form object can be displayed.
 
    Used to display HTML or access attributes for a single field of a
    :class:`Form` instance.
-   
+
    The :meth:`__unicode__` and :meth:`__str__` methods of this object displays
    the HTML for this field.
 
diff --git a/docs/ref/forms/validation.txt b/docs/ref/forms/validation.txt
index 97883d78800..95424d0cd0d 100644
--- a/docs/ref/forms/validation.txt
+++ b/docs/ref/forms/validation.txt
@@ -362,7 +362,9 @@ Secondly, once we have decided that the combined data in the two fields we are
 considering aren't valid, we must remember to remove them from the
 ``cleaned_data``.
 
-In fact, Django will currently completely wipe out the ``cleaned_data``
-dictionary if there are any errors in the form. However, this behavior may
-change in the future, so it's not a bad idea to clean up after yourself in the
-first place.
+.. versionchanged:: 1.5
+
+Django used to remove the ``cleaned_data`` attribute entirely if there were
+any errors in the form. Since version 1.5, ``cleaned_data`` is present even if
+the form doesn't validate, but it contains only field values that did
+validate.
diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt
index 968d63e1f36..3a9b2d859ae 100644
--- a/docs/releases/1.5.txt
+++ b/docs/releases/1.5.txt
@@ -239,6 +239,16 @@ database state behind or unit tests that rely on some form of state being
 preserved after the execution of other tests. Such tests are already very
 fragile, and must now be changed to be able to run independently.
 
+`cleaned_data` dictionary kept for invalid forms
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :attr:`~django.forms.Form.cleaned_data` dictionary is now always present
+after form validation. When the form doesn't validate, it contains only the
+fields that passed validation. You should test the success of the validation
+with the :meth:`~django.forms.Form.is_valid()` method and not with the
+presence or absence of the :attr:`~django.forms.Form.cleaned_data` attribute
+on the form.
+
 Miscellaneous
 ~~~~~~~~~~~~~
 
diff --git a/tests/modeltests/model_forms/tests.py b/tests/modeltests/model_forms/tests.py
index fc37a258727..1da7f583be4 100644
--- a/tests/modeltests/model_forms/tests.py
+++ b/tests/modeltests/model_forms/tests.py
@@ -638,8 +638,7 @@ class OldFormForXTests(TestCase):
         f = BaseCategoryForm({'name': '', 'slug': 'not a slug!', 'url': 'foo'})
         self.assertEqual(f.errors['name'], ['This field is required.'])
         self.assertEqual(f.errors['slug'], ["Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."])
-        with self.assertRaises(AttributeError):
-            f.cleaned_data
+        self.assertEqual(f.cleaned_data, {'url': 'foo'})
         with self.assertRaises(ValueError):
             f.save()
         f = BaseCategoryForm({'name': '', 'slug': '', 'url': 'foo'})
diff --git a/tests/regressiontests/forms/tests/forms.py b/tests/regressiontests/forms/tests/forms.py
index 7e1c8384a05..a8a28ba8060 100644
--- a/tests/regressiontests/forms/tests/forms.py
+++ b/tests/regressiontests/forms/tests/forms.py
@@ -82,11 +82,7 @@ class FormsTestCase(TestCase):
         self.assertEqual(p.errors['last_name'], ['This field is required.'])
         self.assertEqual(p.errors['birthday'], ['This field is required.'])
         self.assertFalse(p.is_valid())
-        try:
-            p.cleaned_data
-            self.fail('Attempts to access cleaned_data when validation fails should fail.')
-        except AttributeError:
-            pass
+        self.assertEqual(p.cleaned_data, {})
         self.assertHTMLEqual(str(p), """<tr><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr>
 <tr><th><label for="id_last_name">Last name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="last_name" id="id_last_name" /></td></tr>
 <tr><th><label for="id_birthday">Birthday:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="birthday" id="id_birthday" /></td></tr>""")
@@ -145,11 +141,7 @@ class FormsTestCase(TestCase):
   * This field is required.
 * birthday
   * This field is required.""")
-        try:
-            p.cleaned_data
-            self.fail('Attempts to access cleaned_data when validation fails should fail.')
-        except AttributeError:
-            pass
+        self.assertEqual(p.cleaned_data, {'last_name': 'Lennon'})
         self.assertEqual(p['first_name'].errors, ['This field is required.'])
         self.assertHTMLEqual(p['first_name'].errors.as_ul(), '<ul class="errorlist"><li>This field is required.</li></ul>')
         self.assertEqual(p['first_name'].errors.as_text(), '* This field is required.')
@@ -1678,11 +1670,7 @@ class FormsTestCase(TestCase):
         form = SongForm(data, empty_permitted=False)
         self.assertFalse(form.is_valid())
         self.assertEqual(form.errors, {'name': ['This field is required.'], 'artist': ['This field is required.']})
-        try:
-            form.cleaned_data
-            self.fail('Attempts to access cleaned_data when validation fails should fail.')
-        except AttributeError:
-            pass
+        self.assertEqual(form.cleaned_data, {})
 
         # Now let's show what happens when empty_permitted=True and the form is empty.
         form = SongForm(data, empty_permitted=True)
@@ -1696,11 +1684,7 @@ class FormsTestCase(TestCase):
         form = SongForm(data, empty_permitted=False)
         self.assertFalse(form.is_valid())
         self.assertEqual(form.errors, {'name': ['This field is required.']})
-        try:
-            form.cleaned_data
-            self.fail('Attempts to access cleaned_data when validation fails should fail.')
-        except AttributeError:
-            pass
+        self.assertEqual(form.cleaned_data, {'artist': 'The Doors'})
 
         # If a field is not given in the data then None is returned for its data. Lets
         # make sure that when checking for empty_permitted that None is treated

From 09a719a4e6820d462fc796606cb242583ad4e79d Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Sat, 4 Aug 2012 14:55:13 +0200
Subject: [PATCH 34/88] Fixed #7833 -- Improved UserCreationForm password
 validation

Make UserCreationForm password validation similar to
SetPasswordForm and AdminPasswordChangeForm, so as the match
check is only done when both passwords are supplied.
Thanks Mitar for the suggestion.
---
 django/contrib/auth/forms.py       | 6 +++---
 django/contrib/auth/tests/forms.py | 1 +
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py
index d17c41132ed..dfd039f0180 100644
--- a/django/contrib/auth/forms.py
+++ b/django/contrib/auth/forms.py
@@ -89,9 +89,9 @@ class UserCreationForm(forms.ModelForm):
         raise forms.ValidationError(self.error_messages['duplicate_username'])
 
     def clean_password2(self):
-        password1 = self.cleaned_data.get("password1", "")
-        password2 = self.cleaned_data["password2"]
-        if password1 != password2:
+        password1 = self.cleaned_data.get("password1")
+        password2 = self.cleaned_data.get("password2")
+        if password1 and password2 and password1 != password2:
             raise forms.ValidationError(
                 self.error_messages['password_mismatch'])
         return password2
diff --git a/django/contrib/auth/tests/forms.py b/django/contrib/auth/tests/forms.py
index 2ab895804f6..13b8dd1216b 100644
--- a/django/contrib/auth/tests/forms.py
+++ b/django/contrib/auth/tests/forms.py
@@ -65,6 +65,7 @@ class UserCreationFormTest(TestCase):
         form = UserCreationForm(data)
         self.assertFalse(form.is_valid())
         self.assertEqual(form['password1'].errors, required_error)
+        self.assertEqual(form['password2'].errors, [])
 
     def test_success(self):
         # The success case.

From 542c20b38263afb8161d354e6a2cc4ef6bb21de5 Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Sat, 4 Aug 2012 17:38:18 +0200
Subject: [PATCH 35/88] Fixed #18713 -- Fixed custom comment app name in
 comments docs

Thanks Pratyush for the report.
---
 docs/ref/contrib/comments/custom.txt | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/docs/ref/contrib/comments/custom.txt b/docs/ref/contrib/comments/custom.txt
index 5007ddff692..0ef37a9a0bb 100644
--- a/docs/ref/contrib/comments/custom.txt
+++ b/docs/ref/contrib/comments/custom.txt
@@ -51,9 +51,9 @@ To make this kind of customization, we'll need to do three things:
    custom :setting:`COMMENTS_APP`.
 
 So, carrying on the example above, we're dealing with a typical app structure in
-the ``my_custom_app`` directory::
+the ``my_comment_app`` directory::
 
-    my_custom_app/
+    my_comment_app/
         __init__.py
         models.py
         forms.py
@@ -98,11 +98,11 @@ Django provides a couple of "helper" classes to make writing certain types of
 custom comment forms easier; see :mod:`django.contrib.comments.forms` for
 more.
 
-Finally, we'll define a couple of methods in ``my_custom_app/__init__.py`` to
+Finally, we'll define a couple of methods in ``my_comment_app/__init__.py`` to
 point Django at these classes we've created::
 
-    from my_comments_app.models import CommentWithTitle
-    from my_comments_app.forms import CommentFormWithTitle
+    from my_comment_app.models import CommentWithTitle
+    from my_comment_app.forms import CommentFormWithTitle
 
     def get_model():
         return CommentWithTitle

From 865ff32b84316a416661abc3e3e15c753395486c Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Sat, 4 Aug 2012 15:24:40 -0400
Subject: [PATCH 36/88] Fixed #16980 - Misc updates to the auth docs. Thanks
 Preston Holmes for the patch.

---
 docs/topics/auth.txt | 65 +++++++++++++++++++++++++++-----------------
 1 file changed, 40 insertions(+), 25 deletions(-)

diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt
index 7e1353210af..307691bd4ae 100644
--- a/docs/topics/auth.txt
+++ b/docs/topics/auth.txt
@@ -98,12 +98,13 @@ Fields
 
         This doesn't necessarily control whether or not the user can log in.
         Authentication backends aren't required to check for the ``is_active``
-        flag, so if you want to reject a login based on ``is_active`` being
-        ``False``, it's up to you to check that in your own login view.
-        However, the :class:`~django.contrib.auth.forms.AuthenticationForm`
-        used by the :func:`~django.contrib.auth.views.login` view *does*
-        perform this check, as do the permission-checking methods such as
-        :meth:`~models.User.has_perm` and the authentication in the Django
+        flag, and the default backends do not. If you want to reject a login
+        based on ``is_active`` being ``False``, it's up to you to check that in
+        your own login view or a custom authentication backend. However, the
+        :class:`~django.contrib.auth.forms.AuthenticationForm` used by the
+        :func:`~django.contrib.auth.views.login` view (which is the default)
+        *does* perform this check, as do the permission-checking methods such
+        as :meth:`~models.User.has_perm` and the authentication in the Django
         admin. All of those functions/methods will return ``False`` for
         inactive users.
 
@@ -1748,7 +1749,11 @@ By default, :setting:`AUTHENTICATION_BACKENDS` is set to::
 
     ('django.contrib.auth.backends.ModelBackend',)
 
-That's the basic authentication scheme that checks the Django users database.
+That's the basic authentication backend that checks the Django users database
+and queries the builtin permissions. It does not provide protection against
+brute force attacks via any rate limiting mechanism. You may either implement
+your own rate limiting mechanism in a custom auth backend, or use the
+mechanisms provided by most Web servers.
 
 The order of :setting:`AUTHENTICATION_BACKENDS` matters, so if the same
 username and password is valid in multiple backends, Django will stop
@@ -1768,8 +1773,9 @@ processing at the first positive match.
 Writing an authentication backend
 ---------------------------------
 
-An authentication backend is a class that implements two methods:
-``get_user(user_id)`` and ``authenticate(**credentials)``.
+An authentication backend is a class that implements two required methods:
+``get_user(user_id)`` and ``authenticate(**credentials)``, as well as a set of
+optional permission related :ref:`authorization methods <authorization_methods>`.
 
 The ``get_user`` method takes a ``user_id`` -- which could be a username,
 database ID or whatever -- and returns a ``User`` object.
@@ -1838,6 +1844,8 @@ object the first time a user authenticates::
             except User.DoesNotExist:
                 return None
 
+.. _authorization_methods:
+
 Handling authorization in custom backends
 -----------------------------------------
 
@@ -1868,13 +1876,16 @@ fairly simply::
                 return False
 
 This gives full permissions to the user granted access in the above example.
-Notice that the backend auth functions all take the user object as an argument,
-and they also accept the same arguments given to the associated
-:class:`django.contrib.auth.models.User` functions.
+Notice that in addition to the same arguments given to the associated
+:class:`django.contrib.auth.models.User` functions, the backend auth functions
+all take the user object, which may be an anonymous user, as an argument.
 
-A full authorization implementation can be found in
-`django/contrib/auth/backends.py`_, which is the default backend and queries
-the ``auth_permission`` table most of the time.
+A full authorization implementation can be found in the ``ModelBackend`` class
+in `django/contrib/auth/backends.py`_, which is the default backend and queries
+the ``auth_permission`` table most of the time. If you wish to provide
+custom behavior for only part of the backend API, you can take advantage of
+Python inheritence and subclass ``ModelBackend`` instead of implementing the
+complete API in a custom backend.
 
 .. _django/contrib/auth/backends.py: https://github.com/django/django/blob/master/django/contrib/auth/backends.py
 
@@ -1890,25 +1901,27 @@ authorize anonymous users to browse most of the site, and many allow anonymous
 posting of comments etc.
 
 Django's permission framework does not have a place to store permissions for
-anonymous users. However, it has a foundation that allows custom authentication
-backends to specify authorization for anonymous users. This is especially useful
-for the authors of re-usable apps, who can delegate all questions of authorization
-to the auth backend, rather than needing settings, for example, to control
-anonymous access.
+anonymous users. However, the user object passed to an authentication backend
+may be an :class:`django.contrib.auth.models.AnonymousUser` object, allowing
+the backend to specify custom authorization behavior for anonymous users. This
+is especially useful for the authors of re-usable apps, who can delegate all
+questions of authorization to the auth backend, rather than needing settings,
+for example, to control anonymous access.
 
+.. _inactive_auth:
 
 Authorization for inactive users
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. versionadded:: 1.3
+.. versionchanged:: 1.3
 
 An inactive user is a one that is authenticated but has its attribute
 ``is_active`` set to ``False``. However this does not mean they are not
 authorized to do anything. For example they are allowed to activate their
 account.
 
-The support for anonymous users in the permission system allows for
-anonymous users to have permissions to do something while inactive
+The support for anonymous users in the permission system allows for a scenario
+where anonymous users have permissions to do something while inactive
 authenticated users do not.
 
 Do not forget to test for the ``is_active`` attribute of the user in your own
@@ -1916,9 +1929,11 @@ backend permission methods.
 
 
 Handling object permissions
----------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Django's permission framework has a foundation for object permissions, though
 there is no implementation for it in the core. That means that checking for
 object permissions will always return ``False`` or an empty list (depending on
-the check performed).
+the check performed). An authentication backend will receive the keyword
+parameters ``obj`` and ``user_obj`` for each object related authorization
+method and can return the object level permission as appropriate.

From 1fefd91e1e9facc786d27e3234cb69c4212f6d1d Mon Sep 17 00:00:00 2001
From: Daniel Greenfeld <pydanny@gmail.com>
Date: Sat, 4 Aug 2012 13:01:40 -0700
Subject: [PATCH 37/88] For #210, cleaned up text and formatting.

---
 .../ref/class-based-views/generic-editing.txt | 24 ++++++++++++++-----
 docs/ref/class-based-views/mixins-editing.txt |  4 +++-
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/docs/ref/class-based-views/generic-editing.txt b/docs/ref/class-based-views/generic-editing.txt
index 78f46851f79..a65a59bc8be 100644
--- a/docs/ref/class-based-views/generic-editing.txt
+++ b/docs/ref/class-based-views/generic-editing.txt
@@ -10,7 +10,9 @@ editing content:
 * :class:`django.views.generic.edit.UpdateView`
 * :class:`django.views.generic.edit.DeleteView`
 
-.. note:: Some of the examples on this page assume that a model titled 'authors'
+.. note::
+
+    Some of the examples on this page assume that a model titled 'Author'
     has been defined. For these cases we assume the following has been defined 
     in `myapp/models.py`::
 
@@ -92,7 +94,10 @@ editing content:
     .. attribute:: template_name_suffix
 
         The CreateView page displayed to a GET request uses a
-        ``template_name_suffix`` of ``'_form'``.
+        ``template_name_suffix`` of ``'_form.html'``. For 
+        example, changing this attribute to ``'_create_form.html'`` for a view
+        creating objects for the the example `Author` model would cause the the
+        default `template_name` to be ``'myapp/author_create_form.html'``.
 
     **Example views.py**::
 
@@ -127,8 +132,11 @@ editing content:
 
     .. attribute:: template_name_suffix
 
-        The CreateView page displayed to a GET request uses a
-        ``template_name_suffix`` of ``'_form'``.
+        The UpdateView page displayed to a GET request uses a
+        ``template_name_suffix`` of ``'_form.html'``. For 
+        example, changing this attribute to ``'_update_form.html'`` for a view
+        updating objects for the the example `Author` model would cause the the
+        default `template_name` to be ``'myapp/author_update_form.html'``.        
 
     **Example views.py**::
 
@@ -162,8 +170,12 @@ editing content:
 
     .. attribute:: template_name_suffix
 
-        The CreateView page displayed to a GET request uses a
-        ``template_name_suffix`` of ``'_confirm_delete'``.
+        The DeleteView page displayed to a GET request uses a
+        ``template_name_suffix`` of ``'_confirm_delete.html'``. For 
+        example, changing this attribute to ``'_check_delete.html'`` for a view
+        deleting objects for the the example `Author` model would cause the the
+        default `template_name` to be ``'myapp/author_check_delete.html'``.        
+
 
     **Example views.py**::
 
diff --git a/docs/ref/class-based-views/mixins-editing.txt b/docs/ref/class-based-views/mixins-editing.txt
index f68c279ff3a..89610889dbe 100644
--- a/docs/ref/class-based-views/mixins-editing.txt
+++ b/docs/ref/class-based-views/mixins-editing.txt
@@ -9,7 +9,9 @@ The following mixins are used to construct Django's editing views:
 * :class:`django.views.generic.edit.ProcessFormView`
 * :class:`django.views.generic.edit.DeletionMixin`
 
-.. note:: Examples of how these are combined into editing views can be found at
+.. note::
+
+    Examples of how these are combined into editing views can be found at
     the documentation on ``Generic editing views``.
 
 .. class:: django.views.generic.edit.FormMixin

From 62ae711cecc823f0499cbddac3465c256dee106a Mon Sep 17 00:00:00 2001
From: Florian Apolloner <florian@apolloner.eu>
Date: Sat, 4 Aug 2012 23:58:31 +0200
Subject: [PATCH 38/88] Added a missing space to the description of the `cut`
 filter.

---
 docs/ref/templates/builtins.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
index 500a47c6f1d..072eebf69fb 100644
--- a/docs/ref/templates/builtins.txt
+++ b/docs/ref/templates/builtins.txt
@@ -1184,7 +1184,7 @@ Removes all values of arg from the given string.
 
 For example::
 
-    {{ value|cut:" "}}
+    {{ value|cut:" " }}
 
 If ``value`` is ``"String with spaces"``, the output will be
 ``"Stringwithspaces"``.

From 9ea4dc90b9d72648f0f26cc60b19727b35267da0 Mon Sep 17 00:00:00 2001
From: Julien Phalip <jphalip@gmail.com>
Date: Sat, 4 Aug 2012 15:46:15 -0700
Subject: [PATCH 39/88] Small improvement to the `contrib.messages` doc
 introduction.

---
 docs/ref/contrib/messages.txt | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/docs/ref/contrib/messages.txt b/docs/ref/contrib/messages.txt
index 6929a3b0d0a..4cf90ee3810 100644
--- a/docs/ref/contrib/messages.txt
+++ b/docs/ref/contrib/messages.txt
@@ -5,12 +5,14 @@ The messages framework
 .. module:: django.contrib.messages
    :synopsis: Provides cookie- and session-based temporary message storage.
 
-Django provides full support for cookie- and session-based messaging, for
-both anonymous and authenticated clients. The messages framework allows you
-to temporarily store messages in one request and retrieve them for display
-in a subsequent request (usually the next one). Every message is tagged
-with a specific ``level`` that determines its priority (e.g., ``info``,
-``warning``, or ``error``).
+Quite commonly in web applications, you may need to display a one-time
+notification message (also know as "flash message") to the user after
+processing a form or some other types of user input. For this, Django provides
+full support for cookie- and session-based messaging, for both anonymous and
+authenticated users. The messages framework allows you to temporarily store
+messages in one request and retrieve them for display in a subsequent request
+(usually the next one). Every message is tagged with a specific ``level`` that
+determines its priority (e.g., ``info``, ``warning``, or ``error``).
 
 Enabling messages
 =================

From 86c5c0154f69728eba4aad6204621f07cdd3459d Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Sat, 4 Aug 2012 18:56:43 -0400
Subject: [PATCH 40/88] Fixed a mistake in function documentation
 'django.utils.functional.partition'

Thanks Raman Barkholenka for the patch.
---
 django/utils/functional.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/django/utils/functional.py b/django/utils/functional.py
index 2dca182b992..69aae098876 100644
--- a/django/utils/functional.py
+++ b/django/utils/functional.py
@@ -312,8 +312,8 @@ def partition(predicate, values):
     Splits the values into two sets, based on the return value of the function
     (True/False). e.g.:
 
-        >>> partition(lambda: x > 3, range(5))
-        [1, 2, 3], [4]
+        >>> partition(lambda x: x > 3, range(5))
+        [0, 1, 2, 3], [4]
     """
     results = ([], [])
     for item in values:

From 197863523a7631ae1d11d4fdf49b747a96e011a3 Mon Sep 17 00:00:00 2001
From: Julien Phalip <jphalip@gmail.com>
Date: Sat, 4 Aug 2012 16:05:12 -0700
Subject: [PATCH 41/88] Restructured the documentation's index page and added
 some introductory sentences to each section.

---
 docs/index.txt | 140 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 104 insertions(+), 36 deletions(-)

diff --git a/docs/index.txt b/docs/index.txt
index 50e8471b147..b01116124f7 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -34,6 +34,8 @@ Having trouble? We'd like to help!
 First steps
 ===========
 
+Are you new to Django or to programming? This is the place to start!
+
 * **From scratch:**
   :doc:`Overview <intro/overview>` |
   :doc:`Installation <intro/install>`
@@ -47,6 +49,9 @@ First steps
 The model layer
 ===============
 
+Django provides an abstration layer (the "models") for structuring and
+manipulating the data of your Web application. Learn more about it below:
+
 * **Models:**
   :doc:`Model syntax <topics/db/models>` |
   :doc:`Field types <ref/models/fields>` |
@@ -74,20 +79,13 @@ The model layer
   :doc:`Providing initial data <howto/initial-data>` |
   :doc:`Optimize database access <topics/db/optimization>`
 
-The template layer
-==================
-
-* **For designers:**
-  :doc:`Syntax overview <topics/templates>` |
-  :doc:`Built-in tags and filters <ref/templates/builtins>`
-
-* **For programmers:**
-  :doc:`Template API <ref/templates/api>` |
-  :doc:`Custom tags and filters <howto/custom-template-tags>`
-
 The view layer
 ==============
 
+Django offers the concept of "views" to encapsulate the logic reponsible for
+processing a user's request and for returning the response. Find all you need
+to know about views via the links below:
+
 * **The basics:**
   :doc:`URLconfs <topics/http/urls>` |
   :doc:`View functions <topics/http/views>` |
@@ -118,9 +116,29 @@ The view layer
   :doc:`Overview <topics/http/middleware>` |
   :doc:`Built-in middleware classes <ref/middleware>`
 
+The template layer
+==================
+
+The template layer provides a designer-friendly syntax for rendering the
+information to be presented to the user. Learn how this syntax can be used by
+designers and how it can be extended by programmers:
+
+* **For designers:**
+  :doc:`Syntax overview <topics/templates>` |
+  :doc:`Built-in tags and filters <ref/templates/builtins>` |
+  :doc:`Web design helpers <ref/contrib/webdesign>` |
+  :doc:`Humanization <ref/contrib/humanize>`
+
+* **For programmers:**
+  :doc:`Template API <ref/templates/api>` |
+  :doc:`Custom tags and filters <howto/custom-template-tags>`
+
 Forms
 =====
 
+Django provides a rich framework to facilitate the creation of forms and the
+manipulation of form data.
+
 * **The basics:**
   :doc:`Overview <topics/forms/index>` |
   :doc:`Form API <ref/forms/api>` |
@@ -140,6 +158,9 @@ Forms
 The development process
 =======================
 
+Learn about the various components and tools to help you in the development and
+testing of Django applications:
+
 * **Settings:**
   :doc:`Overview <topics/settings>` |
   :doc:`Full list of settings <ref/settings>`
@@ -161,46 +182,93 @@ The development process
   :doc:`Handling static files <howto/static-files>` |
   :doc:`Tracking code errors by email <howto/error-reporting>`
 
-Other batteries included
-========================
+The admin
+=========
 
-* :doc:`Admin site <ref/contrib/admin/index>` | :doc:`Admin actions <ref/contrib/admin/actions>` | :doc:`Admin documentation generator<ref/contrib/admin/admindocs>`
-* :doc:`Authentication <topics/auth>`
-* :doc:`Cache system <topics/cache>`
+Find all you need to know about the automated admin interface, one of Django's
+most popular features:
+
+* :doc:`Admin site <ref/contrib/admin/index>`
+* :doc:`Admin actions <ref/contrib/admin/actions>`
+* :doc:`Admin documentation generator<ref/contrib/admin/admindocs>`
+
+Security
+========
+
+Security is a topic of paramount importance in the development of Web
+applications and Django provides multiple protection tools and mechanisms:
+
+* :doc:`Security overview <topics/security>`
 * :doc:`Clickjacking protection <ref/clickjacking>`
-* :doc:`Comments <ref/contrib/comments/index>` | :doc:`Moderation <ref/contrib/comments/moderation>` | :doc:`Custom comments <ref/contrib/comments/custom>`
-* :doc:`Conditional content processing <topics/conditional-view-processing>`
-* :doc:`Content types and generic relations <ref/contrib/contenttypes>`
 * :doc:`Cross Site Request Forgery protection <ref/contrib/csrf>`
 * :doc:`Cryptographic signing <topics/signing>`
-* :doc:`Databrowse <ref/contrib/databrowse>`
-* :doc:`E-mail (sending) <topics/email>`
-* :doc:`Flatpages <ref/contrib/flatpages>`
-* :doc:`GeoDjango <ref/contrib/gis/index>`
-* :doc:`Humanize <ref/contrib/humanize>`
+
+Internationalization and localization
+=====================================
+
+Django offers a robust internationalization and localization framework to
+assist you in the development of applications for multiple languages and world
+regions:
+
 * :doc:`Internationalization <topics/i18n/index>`
-* :doc:`Jython support <howto/jython>`
 * :doc:`"Local flavor" <ref/contrib/localflavor>`
-* :doc:`Logging <topics/logging>`
-* :doc:`Messages <ref/contrib/messages>`
-* :doc:`Pagination <topics/pagination>`
+
+Python compatibility
+====================
+
+Django aims to be compatible with multiple different flavors and versions of
+Python:
+
+* :doc:`Jython support <howto/jython>`
 * :doc:`Python 3 compatibility <topics/python3>`
-* :doc:`Redirects <ref/contrib/redirects>`
-* :doc:`Security <topics/security>`
+
+Geographic framework
+====================
+
+:doc:`GeoDjango <ref/contrib/gis/index>` intends to be a world-class geographic
+Web framework. Its goal is to make it as easy as possible to build GIS Web
+applications and harness the power of spatially enabled data.
+
+Common Web application tools
+============================
+
+Django offers multiple tools commonly needed in the development of Web
+applications:
+
+* :doc:`Authentication <topics/auth>`
+* :doc:`Caching <topics/cache>`
+* :doc:`Logging <topics/logging>`
+* :doc:`Sending e-mails <topics/email>`
+* :doc:`Syndication feeds (RSS/Atom) <ref/contrib/syndication>`
+* :doc:`Comments <ref/contrib/comments/index>`, :doc:`comment moderation <ref/contrib/comments/moderation>` and :doc:`custom comments <ref/contrib/comments/custom>`
+* :doc:`Pagination <topics/pagination>`
+* :doc:`Messages framework <ref/contrib/messages>`
 * :doc:`Serialization <topics/serialization>`
 * :doc:`Sessions <topics/http/sessions>`
-* :doc:`Signals <topics/signals>`
 * :doc:`Sitemaps <ref/contrib/sitemaps>`
-* :doc:`Sites <ref/contrib/sites>`
-* :doc:`Static Files <ref/contrib/staticfiles>`
-* :doc:`Syndication feeds (RSS/Atom) <ref/contrib/syndication>`
+* :doc:`Static files management <ref/contrib/staticfiles>`
+* :doc:`Data validation <ref/validators>`
+
+Other core functionalities
+==========================
+
+Learn about some other core functionalities of the Django framework:
+
+* :doc:`Conditional content processing <topics/conditional-view-processing>`
+* :doc:`Content types and generic relations <ref/contrib/contenttypes>`
+* :doc:`Databrowse <ref/contrib/databrowse>`
+* :doc:`Flatpages <ref/contrib/flatpages>`
+* :doc:`Redirects <ref/contrib/redirects>`
+* :doc:`Signals <topics/signals>`
+* :doc:`The sites framework <ref/contrib/sites>`
 * :doc:`Unicode in Django <ref/unicode>`
-* :doc:`Web design helpers <ref/contrib/webdesign>`
-* :doc:`Validators <ref/validators>`
 
 The Django open-source project
 ==============================
 
+Learn about the development process for the Django project itself and about how
+you can contribute:
+
 * **Community:**
   :doc:`How to get involved <internals/contributing/index>` |
   :doc:`The release process <internals/release-process>` |

From 5d4f993bb1f01c3a79194031827380dc763ce628 Mon Sep 17 00:00:00 2001
From: Angeline Tan <angeline.agilemeister@gmail.com>
Date: Sat, 4 Aug 2012 15:05:57 -0700
Subject: [PATCH 42/88] Moved a note about django-admin.py errors from Tutorial
 Part 1 to a new FAQ Troubleshooting page. This is to avoid confusion for
 beginners.

---
 docs/faq/index.txt           |  3 ++-
 docs/faq/troubleshooting.txt | 16 ++++++++++++++++
 docs/intro/tutorial01.txt    | 10 ++--------
 3 files changed, 20 insertions(+), 9 deletions(-)
 create mode 100644 docs/faq/troubleshooting.txt

diff --git a/docs/faq/index.txt b/docs/faq/index.txt
index 347cabaabce..b7281946ee7 100644
--- a/docs/faq/index.txt
+++ b/docs/faq/index.txt
@@ -11,4 +11,5 @@ Django FAQ
    help
    models
    admin
-   contributing
\ No newline at end of file
+   contributing
+   troubleshooting
\ No newline at end of file
diff --git a/docs/faq/troubleshooting.txt b/docs/faq/troubleshooting.txt
new file mode 100644
index 00000000000..f984be4bf5f
--- /dev/null
+++ b/docs/faq/troubleshooting.txt
@@ -0,0 +1,16 @@
+===============
+Troubleshooting
+===============
+
+This page contains some advice about errors and problems commonly encountered
+during the development of Django applications.
+
+"command not found: django-admin.py"
+------------------------------------
+
+:doc:`django-admin.py </ref/django-admin>` should be on your system path if you
+installed Django via ``python setup.py``. If it's not on your path, you can
+find it in ``site-packages/django/bin``, where ``site-packages`` is a directory
+within your Python installation. Consider symlinking to :doc:`django-admin.py
+</ref/django-admin>` from some place on your path, such as
+:file:`/usr/local/bin`.
\ No newline at end of file
diff --git a/docs/intro/tutorial01.txt b/docs/intro/tutorial01.txt
index 250c0f1f412..1e2231d1e05 100644
--- a/docs/intro/tutorial01.txt
+++ b/docs/intro/tutorial01.txt
@@ -52,7 +52,8 @@ code, then run the following command:
 
    django-admin.py startproject mysite
 
-This will create a ``mysite`` directory in your current directory.
+This will create a ``mysite`` directory in your current directory.  If it didn't 
+work, see :doc:`Troubleshooting </faq/troubleshooting>`.
 
 .. admonition:: Script name may differ in distribution packages
 
@@ -78,13 +79,6 @@ This will create a ``mysite`` directory in your current directory.
     ``django`` (which will conflict with Django itself) or ``test`` (which
     conflicts with a built-in Python package).
 
-:doc:`django-admin.py </ref/django-admin>` should be on your system path if you
-installed Django via ``python setup.py``. If it's not on your path, you can find
-it in ``site-packages/django/bin``, where ``site-packages`` is a directory
-within your Python installation. Consider symlinking to :doc:`django-admin.py
-</ref/django-admin>` from some place on your path, such as
-:file:`/usr/local/bin`.
-
 .. admonition:: Where should this code live?
 
     If your background is in PHP, you're probably used to putting code under the

From 1c3464e809bf84a18cf909959e910b8c6e5df0db Mon Sep 17 00:00:00 2001
From: Justin Bronn <jbronn@geodjango.org>
Date: Sat, 4 Aug 2012 18:10:34 -0700
Subject: [PATCH 43/88] Fixed testing on SpatiaLite 2.4, which has support for
 `InitSpatialMetaData`.

---
 django/contrib/gis/db/backends/spatialite/creation.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/django/contrib/gis/db/backends/spatialite/creation.py b/django/contrib/gis/db/backends/spatialite/creation.py
index 31f2fca1bd6..d0a5f820332 100644
--- a/django/contrib/gis/db/backends/spatialite/creation.py
+++ b/django/contrib/gis/db/backends/spatialite/creation.py
@@ -99,14 +99,14 @@ class SpatiaLiteCreation(DatabaseCreation):
         """
         This routine loads up the SpatiaLite SQL file.
         """
-        if self.connection.ops.spatial_version[:2] >= (3, 0):
-            # Spatialite >= 3.0.x -- No need to load any SQL file, calling
+        if self.connection.ops.spatial_version[:2] >= (2, 4):
+            # Spatialite >= 2.4 -- No need to load any SQL file, calling
             # InitSpatialMetaData() transparently creates the spatial metadata
             # tables
             cur = self.connection._cursor()
             cur.execute("SELECT InitSpatialMetaData()")
         else:
-            # Spatialite < 3.0.x -- Load the initial SQL
+            # Spatialite < 2.4 -- Load the initial SQL
 
             # Getting the location of the SpatiaLite SQL file, and confirming
             # it exists.

From 19642a7a09a0f9c7fbeeaec687316f7f9f8027bb Mon Sep 17 00:00:00 2001
From: Julien Phalip <jphalip@gmail.com>
Date: Sat, 4 Aug 2012 18:19:25 -0700
Subject: [PATCH 44/88] Fixed some typos on the documentation's index page.

---
 docs/index.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docs/index.txt b/docs/index.txt
index b01116124f7..d5723186e6c 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -49,7 +49,7 @@ Are you new to Django or to programming? This is the place to start!
 The model layer
 ===============
 
-Django provides an abstration layer (the "models") for structuring and
+Django provides an abstraction layer (the "models") for structuring and
 manipulating the data of your Web application. Learn more about it below:
 
 * **Models:**
@@ -82,7 +82,7 @@ manipulating the data of your Web application. Learn more about it below:
 The view layer
 ==============
 
-Django offers the concept of "views" to encapsulate the logic reponsible for
+Django has the concept of "views" to encapsulate the logic responsible for
 processing a user's request and for returning the response. Find all you need
 to know about views via the links below:
 

From 9a3026a920286e9932401300d14f72a85ba03a43 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Sun, 5 Aug 2012 22:47:29 +0200
Subject: [PATCH 45/88] Fixed a rst error introduced in f2abfe1e.

---
 docs/ref/django-admin.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt
index c4295c68d59..5ff7ecba2c7 100644
--- a/docs/ref/django-admin.txt
+++ b/docs/ref/django-admin.txt
@@ -747,7 +747,7 @@ use the ``--plain`` option, like so::
 
 If you would like to specify either IPython or bpython as your interpreter if
 you have both installed you can specify an alternative interpreter interface
-with the ``-i`` or ``--interface`` options like so::
+with the ``-i`` or ``--interface`` options like so:
 
 IPython::
 

From ad237fb72f769bbd99b5ed6e3292bead614e1c94 Mon Sep 17 00:00:00 2001
From: Brendan MacDonell <brendan@macdonell.net>
Date: Mon, 6 Aug 2012 10:42:21 +0200
Subject: [PATCH 46/88] Fixed #18724 -- Fixed IntegerField validation with
 value 0

---
 django/db/models/fields/__init__.py         | 3 ++-
 tests/regressiontests/model_fields/tests.py | 4 ++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 9606b1b8436..de24a24ed13 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -179,7 +179,8 @@ class Field(object):
         if not self.editable:
             # Skip validation for non-editable fields.
             return
-        if self._choices and value:
+
+        if self._choices and value not in validators.EMPTY_VALUES:
             for option_key, option_value in self.choices:
                 if isinstance(option_value, (list, tuple)):
                     # This is an optgroup, so look inside the group for
diff --git a/tests/regressiontests/model_fields/tests.py b/tests/regressiontests/model_fields/tests.py
index e86159463dd..7d6071accc3 100644
--- a/tests/regressiontests/model_fields/tests.py
+++ b/tests/regressiontests/model_fields/tests.py
@@ -274,6 +274,10 @@ class ValidationTest(test.TestCase):
         self.assertRaises(ValidationError, f.clean, None, None)
         self.assertRaises(ValidationError, f.clean, '', None)
 
+    def test_integerfield_validates_zero_against_choices(self):
+        f = models.IntegerField(choices=((1, 1),))
+        self.assertRaises(ValidationError, f.clean, '0', None)
+
     def test_charfield_raises_error_on_empty_input(self):
         f = models.CharField(null=False)
         self.assertRaises(ValidationError, f.clean, None, None)

From ede49c7ee03dd1519d0c375d953cb73e106837b6 Mon Sep 17 00:00:00 2001
From: Alex Gaynor <alex.gaynor@gmail.com>
Date: Mon, 6 Aug 2012 07:58:54 -0700
Subject: [PATCH 47/88] Fixed #15754 -- avoid recursively computing the tree of
 media widgets more times than is necessary for a wiget

---
 django/forms/widgets.py | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index 6b1be37ec27..3c4da2444df 100644
--- a/django/forms/widgets.py
+++ b/django/forms/widgets.py
@@ -110,9 +110,10 @@ class Media(StrAndUnicode):
 def media_property(cls):
     def _media(self):
         # Get the media property of the superclass, if it exists
-        if hasattr(super(cls, self), 'media'):
-            base = super(cls, self).media
-        else:
+        sup_cls = super(cls, self)
+        try:
+            base = sup_cls.media
+        except AttributeError:
             base = Media()
 
         # Get the media definition for this class

From 4f3a6b853a6160a9f96d0b73199524a9bb062f90 Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Mon, 6 Aug 2012 16:15:09 -0400
Subject: [PATCH 48/88] Fixed #17053 - Added a note about
 USE_THOUSAND_SEPARATOR setting to localizations docs.

Thanks shelldweller for the draft patch.
---
 docs/topics/i18n/formatting.txt | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/docs/topics/i18n/formatting.txt b/docs/topics/i18n/formatting.txt
index d18781c0a9d..b09164769e4 100644
--- a/docs/topics/i18n/formatting.txt
+++ b/docs/topics/i18n/formatting.txt
@@ -21,7 +21,10 @@ necessary to set :setting:`USE_L10N = True <USE_L10N>` in your settings file.
 
     The default :file:`settings.py` file created by :djadmin:`django-admin.py
     startproject <startproject>` includes :setting:`USE_L10N = True <USE_L10N>`
-    for convenience.
+    for convenience.  Note, however, that to enable number formatting with
+    thousand separators it is necessary to set :setting:`USE_THOUSAND_SEPARATOR
+    = True <USE_THOUSAND_SEPARATOR>` in your settings file. Alternatively, you
+    could use :tfilter:`intcomma` to format numbers in your template.
 
 .. note::
 

From c8780d9f4d32a1ff7b78f0b6bbb052e1e30d90f7 Mon Sep 17 00:00:00 2001
From: Michael Blume <mike@loggly.com>
Date: Mon, 6 Aug 2012 14:28:58 -0700
Subject: [PATCH 49/88] change "has now" -> "now has" in 1.5 release notes

I believe this is standard.
---
 docs/releases/1.5.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt
index 3a9b2d859ae..d58d3cadf4f 100644
--- a/docs/releases/1.5.txt
+++ b/docs/releases/1.5.txt
@@ -107,7 +107,7 @@ Django 1.5 also includes several smaller improvements worth noting:
   connect to more than one signal by supplying a list of signals.
 
 * :meth:`QuerySet.bulk_create()
-  <django.db.models.query.QuerySet.bulk_create>` has now a batch_size
+  <django.db.models.query.QuerySet.bulk_create>` now has a batch_size
   argument. By default the batch_size is unlimited except for SQLite where
   single batch is limited so that 999 parameters per query isn't exceeded.
 

From ee191715eae73362768184aa95206cf61bac5d38 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Fri, 20 Jul 2012 21:14:27 +0200
Subject: [PATCH 50/88] [py3] Fixed access to dict keys/values/items.

---
 django/conf/__init__.py                       |  2 +-
 django/contrib/admin/helpers.py               |  4 +--
 django/contrib/admin/options.py               |  6 ++---
 django/contrib/admin/sites.py                 |  7 +++---
 .../contrib/admin/templatetags/admin_list.py  |  3 ++-
 django/contrib/admindocs/views.py             |  5 ++--
 django/contrib/auth/admin.py                  |  3 ++-
 django/contrib/auth/tests/forms.py            |  3 ++-
 django/contrib/contenttypes/management.py     |  5 ++--
 django/contrib/databrowse/datastructures.py   |  8 +++---
 .../contrib/databrowse/plugins/calendars.py   |  2 +-
 .../databrowse/plugins/fieldchoices.py        |  2 +-
 .../contrib/formtools/wizard/storage/base.py  |  7 +++---
 django/contrib/formtools/wizard/views.py      |  8 +++---
 .../gis/db/backends/mysql/operations.py       |  4 ++-
 .../gis/db/backends/oracle/operations.py      |  2 +-
 .../gis/db/backends/postgis/operations.py     |  4 +--
 .../gis/db/backends/spatialite/operations.py  |  2 +-
 django/contrib/gis/db/models/query.py         |  5 ++--
 django/contrib/gis/db/models/sql/compiler.py  |  5 ++--
 django/contrib/gis/geometry/test_data.py      |  3 ++-
 django/contrib/gis/measure.py                 |  2 +-
 django/contrib/gis/sitemaps/views.py          |  3 ++-
 django/contrib/messages/storage/cookie.py     |  3 ++-
 django/contrib/sessions/tests.py              | 19 +++++++-------
 django/contrib/sitemaps/views.py              |  3 ++-
 django/contrib/staticfiles/finders.py         |  3 ++-
 django/core/management/__init__.py            |  5 ++--
 .../core/management/commands/diffsettings.py  |  4 +--
 django/core/serializers/__init__.py           |  5 ++--
 django/core/serializers/python.py             |  3 ++-
 django/core/urlresolvers.py                   |  2 +-
 django/core/validators.py                     |  2 +-
 django/db/backends/mysql/introspection.py     |  3 ++-
 django/db/models/base.py                      |  4 +--
 django/db/models/deletion.py                  | 25 ++++++++++---------
 django/db/models/fields/related.py            |  8 +++---
 django/db/models/loading.py                   |  5 ++--
 django/db/models/options.py                   | 17 ++++++-------
 django/db/models/query.py                     | 20 +++++++--------
 django/db/models/query_utils.py               |  5 ++--
 django/db/models/sql/compiler.py              |  7 +++---
 django/db/models/sql/query.py                 | 25 ++++++++++---------
 django/db/models/sql/subqueries.py            |  5 ++--
 django/forms/extras/widgets.py                |  2 +-
 django/forms/forms.py                         |  6 ++---
 django/forms/models.py                        |  3 ++-
 django/forms/widgets.py                       |  3 +--
 django/template/base.py                       |  2 +-
 django/template/defaulttags.py                |  5 ++--
 django/template/loader_tags.py                |  5 ++--
 django/templatetags/i18n.py                   |  2 +-
 django/utils/dateparse.py                     |  7 +++---
 django/utils/dictconfig.py                    |  2 +-
 django/utils/functional.py                    |  2 +-
 django/utils/html.py                          |  2 +-
 django/utils/termcolors.py                    |  4 ++-
 django/views/debug.py                         |  2 +-
 django/views/generic/base.py                  |  3 ++-
 tests/modeltests/timezones/tests.py           |  9 ++++---
 .../aggregation_regress/tests.py              |  3 ++-
 tests/regressiontests/db_typecasts/tests.py   |  3 ++-
 .../templates/templatetags/custom.py          |  6 ++---
 tests/regressiontests/templates/tests.py      |  3 ++-
 64 files changed, 187 insertions(+), 155 deletions(-)

diff --git a/django/conf/__init__.py b/django/conf/__init__.py
index 77454b3fb91..6325ccb1a91 100644
--- a/django/conf/__init__.py
+++ b/django/conf/__init__.py
@@ -158,7 +158,7 @@ class UserSettingsHolder(BaseSettings):
         return getattr(self.default_settings, name)
 
     def __dir__(self):
-        return self.__dict__.keys() + dir(self.default_settings)
+        return list(six.iterkeys(self.__dict__)) + dir(self.default_settings)
 
     # For Python < 2.6:
     __members__ = property(lambda self: self.__dir__())
diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py
index 1bc843cdf9b..4fc78784f44 100644
--- a/django/contrib/admin/helpers.py
+++ b/django/contrib/admin/helpers.py
@@ -325,11 +325,11 @@ class AdminErrorList(forms.util.ErrorList):
     """
     def __init__(self, form, inline_formsets):
         if form.is_bound:
-            self.extend(form.errors.values())
+            self.extend(list(six.itervalues(form.errors)))
             for inline_formset in inline_formsets:
                 self.extend(inline_formset.non_form_errors())
                 for errors_in_inline_form in inline_formset.errors:
-                    self.extend(errors_in_inline_form.values())
+                    self.extend(list(six.itervalues(errors_in_inline_form)))
 
 def normalize_fieldsets(fieldsets):
     """
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index c13a6bc5cc8..ea28125a5ff 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -425,7 +425,7 @@ class ModelAdmin(BaseModelAdmin):
         if self.declared_fieldsets:
             return self.declared_fieldsets
         form = self.get_form(request, obj)
-        fields = form.base_fields.keys() + list(self.get_readonly_fields(request, obj))
+        fields = list(six.iterkeys(form.base_fields)) + list(self.get_readonly_fields(request, obj))
         return [(None, {'fields': fields})]
 
     def get_form(self, request, obj=None, **kwargs):
@@ -608,7 +608,7 @@ class ModelAdmin(BaseModelAdmin):
         tuple (name, description).
         """
         choices = [] + default_choices
-        for func, name, description in self.get_actions(request).itervalues():
+        for func, name, description in six.itervalues(self.get_actions(request)):
             choice = (name, description % model_format_dict(self.opts))
             choices.append(choice)
         return choices
@@ -1415,7 +1415,7 @@ class InlineModelAdmin(BaseModelAdmin):
         if self.declared_fieldsets:
             return self.declared_fieldsets
         form = self.get_formset(request, obj).form
-        fields = form.base_fields.keys() + list(self.get_readonly_fields(request, obj))
+        fields = list(six.iterkeys(form.base_fields)) + list(self.get_readonly_fields(request, obj))
         return [(None, {'fields': fields})]
 
     def queryset(self, request):
diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
index 515cc33eca6..05773ceac05 100644
--- a/django/contrib/admin/sites.py
+++ b/django/contrib/admin/sites.py
@@ -10,6 +10,7 @@ from django.core.exceptions import ImproperlyConfigured
 from django.core.urlresolvers import reverse, NoReverseMatch
 from django.template.response import TemplateResponse
 from django.utils.safestring import mark_safe
+from django.utils import six
 from django.utils.text import capfirst
 from django.utils.translation import ugettext as _
 from django.views.decorators.cache import never_cache
@@ -133,7 +134,7 @@ class AdminSite(object):
         """
         Get all the enabled actions as an iterable of (name, func).
         """
-        return self._actions.iteritems()
+        return six.iteritems(self._actions)
 
     def has_permission(self, request):
         """
@@ -239,7 +240,7 @@ class AdminSite(object):
         )
 
         # Add in each model's views.
-        for model, model_admin in self._registry.iteritems():
+        for model, model_admin in six.iteritems(self._registry):
             urlpatterns += patterns('',
                 url(r'^%s/%s/' % (model._meta.app_label, model._meta.module_name),
                     include(model_admin.urls))
@@ -370,7 +371,7 @@ class AdminSite(object):
                         }
 
         # Sort the apps alphabetically.
-        app_list = app_dict.values()
+        app_list = list(six.itervalues(app_dict))
         app_list.sort(key=lambda x: x['name'])
 
         # Sort the models alphabetically within each app.
diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py
index 0f15781fa94..a16226a70e2 100644
--- a/django/contrib/admin/templatetags/admin_list.py
+++ b/django/contrib/admin/templatetags/admin_list.py
@@ -12,6 +12,7 @@ from django.db import models
 from django.utils import formats
 from django.utils.html import format_html
 from django.utils.safestring import mark_safe
+from django.utils import six
 from django.utils.text import capfirst
 from django.utils.translation import ugettext as _
 from django.utils.encoding import smart_unicode, force_unicode
@@ -125,7 +126,7 @@ def result_headers(cl):
         if i in ordering_field_columns:
             sorted = True
             order_type = ordering_field_columns.get(i).lower()
-            sort_priority = ordering_field_columns.keys().index(i) + 1
+            sort_priority = list(six.iterkeys(ordering_field_columns)).index(i) + 1
             th_classes.append('sorted %sending' % order_type)
             new_order_type = {'asc': 'desc', 'desc': 'asc'}[order_type]
 
diff --git a/django/contrib/admindocs/views.py b/django/contrib/admindocs/views.py
index 5649398cc8f..94963b4d39b 100644
--- a/django/contrib/admindocs/views.py
+++ b/django/contrib/admindocs/views.py
@@ -14,6 +14,7 @@ from django.core import urlresolvers
 from django.contrib.admindocs import utils
 from django.contrib.sites.models import Site
 from django.utils.importlib import import_module
+from django.utils import six
 from django.utils.translation import ugettext as _
 from django.utils.safestring import mark_safe
 
@@ -48,7 +49,7 @@ def template_tag_index(request):
     load_all_installed_template_libraries()
 
     tags = []
-    app_libs = template.libraries.items()
+    app_libs = list(six.iteritems(template.libraries))
     builtin_libs = [(None, lib) for lib in template.builtins]
     for module_name, library in builtin_libs + app_libs:
         for tag_name, tag_func in library.tags.items():
@@ -83,7 +84,7 @@ def template_filter_index(request):
     load_all_installed_template_libraries()
 
     filters = []
-    app_libs = template.libraries.items()
+    app_libs = list(six.iteritems(template.libraries))
     builtin_libs = [(None, lib) for lib in template.builtins]
     for module_name, library in builtin_libs + app_libs:
         for filter_name, filter_func in library.filters.items():
diff --git a/django/contrib/auth/admin.py b/django/contrib/auth/admin.py
index ad61904041f..cb09822f52b 100644
--- a/django/contrib/auth/admin.py
+++ b/django/contrib/auth/admin.py
@@ -12,6 +12,7 @@ from django.template.response import TemplateResponse
 from django.utils.html import escape
 from django.utils.decorators import method_decorator
 from django.utils.safestring import mark_safe
+from django.utils import six
 from django.utils.translation import ugettext, ugettext_lazy as _
 from django.views.decorators.csrf import csrf_protect
 from django.views.decorators.debug import sensitive_post_parameters
@@ -128,7 +129,7 @@ class UserAdmin(admin.ModelAdmin):
         else:
             form = self.change_password_form(user)
 
-        fieldsets = [(None, {'fields': form.base_fields.keys()})]
+        fieldsets = [(None, {'fields': list(six.iterkeys(form.base_fields))})]
         adminForm = admin.helpers.AdminForm(form, fieldsets, {})
 
         context = {
diff --git a/django/contrib/auth/tests/forms.py b/django/contrib/auth/tests/forms.py
index 13b8dd1216b..2bfe35ac884 100644
--- a/django/contrib/auth/tests/forms.py
+++ b/django/contrib/auth/tests/forms.py
@@ -9,6 +9,7 @@ from django.forms.fields import Field, EmailField
 from django.test import TestCase
 from django.test.utils import override_settings
 from django.utils.encoding import force_unicode
+from django.utils import six
 from django.utils import translation
 from django.utils.translation import ugettext as _
 
@@ -203,7 +204,7 @@ class PasswordChangeFormTest(TestCase):
     def test_field_order(self):
         # Regression test - check the order of fields:
         user = User.objects.get(username='testclient')
-        self.assertEqual(PasswordChangeForm(user, {}).fields.keys(),
+        self.assertEqual(list(six.iterkeys(PasswordChangeForm(user, {}).fields)),
                          ['old_password', 'new_password1', 'new_password2'])
 
 
diff --git a/django/contrib/contenttypes/management.py b/django/contrib/contenttypes/management.py
index 6a23ef52878..1b1c9c85628 100644
--- a/django/contrib/contenttypes/management.py
+++ b/django/contrib/contenttypes/management.py
@@ -1,6 +1,7 @@
 from django.contrib.contenttypes.models import ContentType
 from django.db.models import get_apps, get_models, signals
 from django.utils.encoding import smart_unicode
+from django.utils import six
 
 def update_contenttypes(app, created_models, verbosity=2, **kwargs):
     """
@@ -24,7 +25,7 @@ def update_contenttypes(app, created_models, verbosity=2, **kwargs):
     )
     to_remove = [
         ct
-        for (model_name, ct) in content_types.iteritems()
+        for (model_name, ct) in six.iteritems(content_types)
         if model_name not in app_models
     ]
 
@@ -34,7 +35,7 @@ def update_contenttypes(app, created_models, verbosity=2, **kwargs):
             app_label=app_label,
             model=model_name,
         )
-        for (model_name, model) in app_models.iteritems()
+        for (model_name, model) in six.iteritems(app_models)
         if model_name not in content_types
     ])
     if verbosity >= 2:
diff --git a/django/contrib/databrowse/datastructures.py b/django/contrib/databrowse/datastructures.py
index 687aa87f030..95d347cac07 100644
--- a/django/contrib/databrowse/datastructures.py
+++ b/django/contrib/databrowse/datastructures.py
@@ -17,7 +17,7 @@ class EasyModel(object):
     def __init__(self, site, model):
         self.site = site
         self.model = model
-        self.model_list = site.registry.keys()
+        self.model_list = list(site.registry.keys())
         self.verbose_name = model._meta.verbose_name
         self.verbose_name_plural = model._meta.verbose_name_plural
 
@@ -176,8 +176,6 @@ class EasyInstanceField(object):
         for plugin_name, plugin in self.model.model_databrowse().plugins.items():
             urls = plugin.urls(plugin_name, self)
             if urls is not None:
-                #plugin_urls.append(urls)
-                values = self.values()
                 return zip(self.values(), urls)
         if self.field.rel:
             m = EasyModel(self.model.site, self.field.rel.to)
@@ -196,10 +194,10 @@ class EasyInstanceField(object):
                 url = '%s%s/%s/fields/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name, iri_to_uri(self.raw_value))
                 lst.append((value, url))
         elif isinstance(self.field, models.URLField):
-            val = self.values()[0]
+            val = list(self.values())[0]
             lst = [(val, iri_to_uri(val))]
         else:
-            lst = [(self.values()[0], None)]
+            lst = [(list(self.values())[0], None)]
         return lst
 
 class EasyQuerySet(QuerySet):
diff --git a/django/contrib/databrowse/plugins/calendars.py b/django/contrib/databrowse/plugins/calendars.py
index 7bdd1e00323..923adb90f66 100644
--- a/django/contrib/databrowse/plugins/calendars.py
+++ b/django/contrib/databrowse/plugins/calendars.py
@@ -96,7 +96,7 @@ class CalendarPlugin(DatabrowsePlugin):
 
     def homepage_view(self, request):
         easy_model = EasyModel(self.site, self.model)
-        field_list = self.fields.values()
+        field_list = list(self.fields.values())
         field_list.sort(key=lambda k:k.verbose_name)
         return render_to_response('databrowse/calendar_homepage.html', {
                 'root_url': self.site.root_url,
diff --git a/django/contrib/databrowse/plugins/fieldchoices.py b/django/contrib/databrowse/plugins/fieldchoices.py
index c016385ffbb..73298b8d562 100644
--- a/django/contrib/databrowse/plugins/fieldchoices.py
+++ b/django/contrib/databrowse/plugins/fieldchoices.py
@@ -63,7 +63,7 @@ class FieldChoicePlugin(DatabrowsePlugin):
 
     def homepage_view(self, request):
         easy_model = EasyModel(self.site, self.model)
-        field_list = self.fields.values()
+        field_list = list(self.fields.values())
         field_list.sort(key=lambda k: k.verbose_name)
         return render_to_response('databrowse/fieldchoice_homepage.html', {'root_url': self.site.root_url, 'model': easy_model, 'field_list': field_list})
 
diff --git a/django/contrib/formtools/wizard/storage/base.py b/django/contrib/formtools/wizard/storage/base.py
index 274e07ffbea..7c802712c17 100644
--- a/django/contrib/formtools/wizard/storage/base.py
+++ b/django/contrib/formtools/wizard/storage/base.py
@@ -2,6 +2,7 @@ from django.core.files.uploadedfile import UploadedFile
 from django.utils.datastructures import MultiValueDict
 from django.utils.encoding import smart_str
 from django.utils.functional import lazy_property
+from django.utils import six
 
 from django.contrib.formtools.wizard.storage.exceptions import NoFileStorageConfigured
 
@@ -72,9 +73,9 @@ class BaseStorage(object):
             raise NoFileStorageConfigured
 
         files = {}
-        for field, field_dict in wizard_files.iteritems():
+        for field, field_dict in six.iteritems(wizard_files):
             field_dict = dict((smart_str(k), v)
-                              for k, v in field_dict.iteritems())
+                              for k, v in six.iteritems(field_dict))
             tmp_name = field_dict.pop('tmp_name')
             files[field] = UploadedFile(
                 file=self.file_storage.open(tmp_name), **field_dict)
@@ -87,7 +88,7 @@ class BaseStorage(object):
         if step not in self.data[self.step_files_key]:
             self.data[self.step_files_key][step] = {}
 
-        for field, field_file in (files or {}).iteritems():
+        for field, field_file in six.iteritems(files or {}):
             tmp_filename = self.file_storage.save(field_file.name, field_file)
             file_dict = {
                 'tmp_name': tmp_filename,
diff --git a/django/contrib/formtools/wizard/views.py b/django/contrib/formtools/wizard/views.py
index 466af1cac94..741b7e52b6b 100644
--- a/django/contrib/formtools/wizard/views.py
+++ b/django/contrib/formtools/wizard/views.py
@@ -44,7 +44,7 @@ class StepsHelper(object):
     @property
     def all(self):
         "Returns the names of all steps/forms."
-        return self._wizard.get_form_list().keys()
+        return list(six.iterkeys(self._wizard.get_form_list()))
 
     @property
     def count(self):
@@ -164,14 +164,14 @@ class WizardView(TemplateView):
                 init_form_list[six.text_type(i)] = form
 
         # walk through the new created list of forms
-        for form in init_form_list.itervalues():
+        for form in six.itervalues(init_form_list):
             if issubclass(form, formsets.BaseFormSet):
                 # if the element is based on BaseFormSet (FormSet/ModelFormSet)
                 # we need to override the form variable.
                 form = form.form
             # check if any form contains a FileField, if yes, we need a
             # file_storage added to the wizardview (by subclassing).
-            for field in form.base_fields.itervalues():
+            for field in six.itervalues(form.base_fields):
                 if (isinstance(field, forms.FileField) and
                         not hasattr(cls, 'file_storage')):
                     raise NoFileStorageConfigured
@@ -196,7 +196,7 @@ class WizardView(TemplateView):
         could use data from other (maybe previous forms).
         """
         form_list = SortedDict()
-        for form_key, form_class in self.form_list.iteritems():
+        for form_key, form_class in six.iteritems(self.form_list):
             # try to fetch the value from condition list, by default, the form
             # gets passed to the new list.
             condition = self.condition_dict.get(form_key, True)
diff --git a/django/contrib/gis/db/backends/mysql/operations.py b/django/contrib/gis/db/backends/mysql/operations.py
index c0e5aa6691b..277b7648102 100644
--- a/django/contrib/gis/db/backends/mysql/operations.py
+++ b/django/contrib/gis/db/backends/mysql/operations.py
@@ -3,6 +3,8 @@ from django.db.backends.mysql.base import DatabaseOperations
 from django.contrib.gis.db.backends.adapter import WKTAdapter
 from django.contrib.gis.db.backends.base import BaseSpatialOperations
 
+from django.utils import six
+
 class MySQLOperations(DatabaseOperations, BaseSpatialOperations):
 
     compiler_module = 'django.contrib.gis.db.backends.mysql.compiler'
@@ -30,7 +32,7 @@ class MySQLOperations(DatabaseOperations, BaseSpatialOperations):
         'within' : 'MBRWithin',
         }
 
-    gis_terms = dict([(term, None) for term in geometry_functions.keys() + ['isnull']])
+    gis_terms = dict([(term, None) for term in list(six.iterkeys(geometry_functions)) + ['isnull']])
 
     def geo_db_type(self, f):
         return f.geom_type
diff --git a/django/contrib/gis/db/backends/oracle/operations.py b/django/contrib/gis/db/backends/oracle/operations.py
index 4e33942f7ab..5db30e6fc69 100644
--- a/django/contrib/gis/db/backends/oracle/operations.py
+++ b/django/contrib/gis/db/backends/oracle/operations.py
@@ -128,7 +128,7 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
     geometry_functions.update(distance_functions)
 
     gis_terms = ['isnull']
-    gis_terms += geometry_functions.keys()
+    gis_terms += list(six.iterkeys(geometry_functions))
     gis_terms = dict([(term, None) for term in gis_terms])
 
     truncate_params = {'relate' : None}
diff --git a/django/contrib/gis/db/backends/postgis/operations.py b/django/contrib/gis/db/backends/postgis/operations.py
index bd249df179d..92f8925a7d8 100644
--- a/django/contrib/gis/db/backends/postgis/operations.py
+++ b/django/contrib/gis/db/backends/postgis/operations.py
@@ -217,8 +217,8 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
 
         # Creating a dictionary lookup of all GIS terms for PostGIS.
         gis_terms = ['isnull']
-        gis_terms += self.geometry_operators.keys()
-        gis_terms += self.geometry_functions.keys()
+        gis_terms += list(six.iterkeys(self.geometry_operators))
+        gis_terms += list(six.iterkeys(self.geometry_functions))
         self.gis_terms = dict([(term, None) for term in gis_terms])
 
         self.area = prefix + 'Area'
diff --git a/django/contrib/gis/db/backends/spatialite/operations.py b/django/contrib/gis/db/backends/spatialite/operations.py
index 1d7c4fab52e..31c98212e99 100644
--- a/django/contrib/gis/db/backends/spatialite/operations.py
+++ b/django/contrib/gis/db/backends/spatialite/operations.py
@@ -131,7 +131,7 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
 
         # Creating the GIS terms dictionary.
         gis_terms = ['isnull']
-        gis_terms += self.geometry_functions.keys()
+        gis_terms += list(six.iterkeys(self.geometry_functions))
         self.gis_terms = dict([(term, None) for term in gis_terms])
 
         if version >= (2, 4, 0):
diff --git a/django/contrib/gis/db/models/query.py b/django/contrib/gis/db/models/query.py
index dd2983aecce..6dc36d6ab89 100644
--- a/django/contrib/gis/db/models/query.py
+++ b/django/contrib/gis/db/models/query.py
@@ -1,5 +1,6 @@
 from django.db import connections
 from django.db.models.query import QuerySet, ValuesQuerySet, ValuesListQuerySet
+from django.utils import six
 
 from django.contrib.gis.db.models import aggregates
 from django.contrib.gis.db.models.fields import get_srid_info, PointField, LineStringField
@@ -25,7 +26,7 @@ class GeoQuerySet(QuerySet):
         flat = kwargs.pop('flat', False)
         if kwargs:
             raise TypeError('Unexpected keyword arguments to values_list: %s'
-                    % (kwargs.keys(),))
+                    % (list(six.iterkeys(kwargs)),))
         if flat and len(fields) > 1:
             raise TypeError("'flat' is not valid when values_list is called with more than one field.")
         return self._clone(klass=GeoValuesListQuerySet, setup=True, flat=flat,
@@ -531,7 +532,7 @@ class GeoQuerySet(QuerySet):
         if settings.get('setup', True):
             default_args, geo_field = self._spatial_setup(att, desc=settings['desc'], field_name=field_name,
                                                           geo_field_type=settings.get('geo_field_type', None))
-            for k, v in default_args.iteritems(): settings['procedure_args'].setdefault(k, v)
+            for k, v in six.iteritems(default_args): settings['procedure_args'].setdefault(k, v)
         else:
             geo_field = settings['geo_field']
 
diff --git a/django/contrib/gis/db/models/sql/compiler.py b/django/contrib/gis/db/models/sql/compiler.py
index d016357f1b6..64d1a4d869d 100644
--- a/django/contrib/gis/db/models/sql/compiler.py
+++ b/django/contrib/gis/db/models/sql/compiler.py
@@ -3,6 +3,7 @@ from django.utils.six.moves import zip
 from django.db.backends.util import truncate_name, typecast_timestamp
 from django.db.models.sql import compiler
 from django.db.models.sql.constants import MULTI
+from django.utils import six
 
 SQLCompiler = compiler.SQLCompiler
 
@@ -24,7 +25,7 @@ class GeoSQLCompiler(compiler.SQLCompiler):
         qn = self.quote_name_unless_alias
         qn2 = self.connection.ops.quote_name
         result = ['(%s) AS %s' % (self.get_extra_select_format(alias) % col[0], qn2(alias))
-                  for alias, col in self.query.extra_select.iteritems()]
+                  for alias, col in six.iteritems(self.query.extra_select)]
         aliases = set(self.query.extra_select.keys())
         if with_aliases:
             col_aliases = aliases.copy()
@@ -170,7 +171,7 @@ class GeoSQLCompiler(compiler.SQLCompiler):
         objects.
         """
         values = []
-        aliases = self.query.extra_select.keys()
+        aliases = list(six.iterkeys(self.query.extra_select))
 
         # Have to set a starting row number offset that is used for
         # determining the correct starting row index -- needed for
diff --git a/django/contrib/gis/geometry/test_data.py b/django/contrib/gis/geometry/test_data.py
index f92740248e5..505f0e4f4b4 100644
--- a/django/contrib/gis/geometry/test_data.py
+++ b/django/contrib/gis/geometry/test_data.py
@@ -7,6 +7,7 @@ import json
 import os
 
 from django.contrib import gis
+from django.utils import six
 
 
 # This global used to store reference geometry data.
@@ -25,7 +26,7 @@ def tuplize(seq):
 
 def strconvert(d):
     "Converts all keys in dictionary to str type."
-    return dict([(str(k), v) for k, v in d.iteritems()])
+    return dict([(str(k), v) for k, v in six.iteritems(d)])
 
 
 def get_ds_file(name, ext):
diff --git a/django/contrib/gis/measure.py b/django/contrib/gis/measure.py
index ba7817e51c7..fa8bab13407 100644
--- a/django/contrib/gis/measure.py
+++ b/django/contrib/gis/measure.py
@@ -169,7 +169,7 @@ class MeasureBase(object):
         """
         val = 0.0
         default_unit = self.STANDARD_UNIT
-        for unit, value in kwargs.iteritems():
+        for unit, value in six.iteritems(kwargs):
             if not isinstance(value, float): value = float(value)
             if unit in self.UNITS:
                 val += self.UNITS[unit] * value
diff --git a/django/contrib/gis/sitemaps/views.py b/django/contrib/gis/sitemaps/views.py
index eb42d0cae88..6753b9e34a3 100644
--- a/django/contrib/gis/sitemaps/views.py
+++ b/django/contrib/gis/sitemaps/views.py
@@ -9,6 +9,7 @@ from django.contrib.gis.db.models.fields import GeometryField
 from django.db import connections, DEFAULT_DB_ALIAS
 from django.db.models import get_model
 from django.utils.encoding import smart_str
+from django.utils import six
 from django.utils.translation import ugettext as _
 
 from django.contrib.gis.shortcuts import render_to_kml, render_to_kmz
@@ -46,7 +47,7 @@ def sitemap(request, sitemaps, section=None):
             raise Http404(_("No sitemap available for section: %r") % section)
         maps.append(sitemaps[section])
     else:
-        maps = sitemaps.values()
+        maps = list(six.itervalues(sitemaps))
 
     page = request.GET.get("p", 1)
     current_site = get_current_site(request)
diff --git a/django/contrib/messages/storage/cookie.py b/django/contrib/messages/storage/cookie.py
index 07620050c7b..5f64ccd0c5d 100644
--- a/django/contrib/messages/storage/cookie.py
+++ b/django/contrib/messages/storage/cookie.py
@@ -4,6 +4,7 @@ from django.conf import settings
 from django.contrib.messages.storage.base import BaseStorage, Message
 from django.http import SimpleCookie
 from django.utils.crypto import salted_hmac, constant_time_compare
+from django.utils import six
 
 
 class MessageEncoder(json.JSONEncoder):
@@ -33,7 +34,7 @@ class MessageDecoder(json.JSONDecoder):
             return [self.process_messages(item) for item in obj]
         if isinstance(obj, dict):
             return dict([(key, self.process_messages(value))
-                         for key, value in obj.iteritems()])
+                         for key, value in six.iteritems(obj)])
         return obj
 
     def decode(self, s, **kwargs):
diff --git a/django/contrib/sessions/tests.py b/django/contrib/sessions/tests.py
index 328b085f1e8..7de2941122f 100644
--- a/django/contrib/sessions/tests.py
+++ b/django/contrib/sessions/tests.py
@@ -16,6 +16,7 @@ from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
 from django.http import HttpResponse
 from django.test import TestCase, RequestFactory
 from django.test.utils import override_settings
+from django.utils import six
 from django.utils import timezone
 from django.utils import unittest
 
@@ -86,16 +87,16 @@ class SessionTestsMixin(object):
         self.assertFalse(self.session.modified)
 
     def test_values(self):
-        self.assertEqual(self.session.values(), [])
+        self.assertEqual(list(self.session.values()), [])
         self.assertTrue(self.session.accessed)
         self.session['some key'] = 1
-        self.assertEqual(self.session.values(), [1])
+        self.assertEqual(list(self.session.values()), [1])
 
     def test_iterkeys(self):
         self.session['x'] = 1
         self.session.modified = False
         self.session.accessed = False
-        i = self.session.iterkeys()
+        i = six.iterkeys(self.session)
         self.assertTrue(hasattr(i, '__iter__'))
         self.assertTrue(self.session.accessed)
         self.assertFalse(self.session.modified)
@@ -105,7 +106,7 @@ class SessionTestsMixin(object):
         self.session['x'] = 1
         self.session.modified = False
         self.session.accessed = False
-        i = self.session.itervalues()
+        i = six.itervalues(self.session)
         self.assertTrue(hasattr(i, '__iter__'))
         self.assertTrue(self.session.accessed)
         self.assertFalse(self.session.modified)
@@ -115,7 +116,7 @@ class SessionTestsMixin(object):
         self.session['x'] = 1
         self.session.modified = False
         self.session.accessed = False
-        i = self.session.iteritems()
+        i = six.iteritems(self.session)
         self.assertTrue(hasattr(i, '__iter__'))
         self.assertTrue(self.session.accessed)
         self.assertFalse(self.session.modified)
@@ -125,9 +126,9 @@ class SessionTestsMixin(object):
         self.session['x'] = 1
         self.session.modified = False
         self.session.accessed = False
-        self.assertEqual(self.session.items(), [('x', 1)])
+        self.assertEqual(list(self.session.items()), [('x', 1)])
         self.session.clear()
-        self.assertEqual(self.session.items(), [])
+        self.assertEqual(list(self.session.items()), [])
         self.assertTrue(self.session.accessed)
         self.assertTrue(self.session.modified)
 
@@ -154,10 +155,10 @@ class SessionTestsMixin(object):
         self.session['a'], self.session['b'] = 'c', 'd'
         self.session.save()
         prev_key = self.session.session_key
-        prev_data = self.session.items()
+        prev_data = list(self.session.items())
         self.session.cycle_key()
         self.assertNotEqual(self.session.session_key, prev_key)
-        self.assertEqual(self.session.items(), prev_data)
+        self.assertEqual(list(self.session.items()), prev_data)
 
     def test_invalid_key(self):
         # Submitting an invalid session key (either by guessing, or if the db has
diff --git a/django/contrib/sitemaps/views.py b/django/contrib/sitemaps/views.py
index b90a39e9544..cfe3aa66a92 100644
--- a/django/contrib/sitemaps/views.py
+++ b/django/contrib/sitemaps/views.py
@@ -3,6 +3,7 @@ from django.core import urlresolvers
 from django.core.paginator import EmptyPage, PageNotAnInteger
 from django.http import Http404
 from django.template.response import TemplateResponse
+from django.utils import six
 
 def index(request, sitemaps,
           template_name='sitemap_index.xml', mimetype='application/xml',
@@ -35,7 +36,7 @@ def sitemap(request, sitemaps, section=None,
             raise Http404("No sitemap available for section: %r" % section)
         maps = [sitemaps[section]]
     else:
-        maps = sitemaps.values()
+        maps = list(six.itervalues(sitemaps))
     page = request.GET.get("p", 1)
 
     urls = []
diff --git a/django/contrib/staticfiles/finders.py b/django/contrib/staticfiles/finders.py
index 766687cf7dd..9b06c2cf60c 100644
--- a/django/contrib/staticfiles/finders.py
+++ b/django/contrib/staticfiles/finders.py
@@ -6,6 +6,7 @@ from django.utils.datastructures import SortedDict
 from django.utils.functional import empty, memoize, LazyObject
 from django.utils.importlib import import_module
 from django.utils._os import safe_join
+from django.utils import six
 
 from django.contrib.staticfiles import utils
 from django.contrib.staticfiles.storage import AppStaticStorage
@@ -132,7 +133,7 @@ class AppDirectoriesFinder(BaseFinder):
         """
         List all files in all app storages.
         """
-        for storage in self.storages.itervalues():
+        for storage in six.itervalues(self.storages):
             if storage.exists(''):  # check if storage location exists
                 for path in utils.get_files(storage, ignore_patterns):
                     yield path, storage
diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
index 68048e5672e..e2f9798dcd2 100644
--- a/django/core/management/__init__.py
+++ b/django/core/management/__init__.py
@@ -8,6 +8,7 @@ import warnings
 from django.core.management.base import BaseCommand, CommandError, handle_default_options
 from django.core.management.color import color_style
 from django.utils.importlib import import_module
+from django.utils import six
 
 # For backwards compatibility: get_version() used to be in this module.
 from django import get_version
@@ -228,7 +229,7 @@ class ManagementUtility(object):
                 "Available subcommands:",
             ]
             commands_dict = collections.defaultdict(lambda: [])
-            for name, app in get_commands().iteritems():
+            for name, app in six.iteritems(get_commands()):
                 if app == 'django.core':
                     app = 'django'
                 else:
@@ -294,7 +295,7 @@ class ManagementUtility(object):
         except IndexError:
             curr = ''
 
-        subcommands = get_commands().keys() + ['help']
+        subcommands = list(six.iterkeys(get_commands())) + ['help']
         options = [('--help', None)]
 
         # subcommand
diff --git a/django/core/management/commands/diffsettings.py b/django/core/management/commands/diffsettings.py
index 98b53b405d2..aa7395e5eea 100644
--- a/django/core/management/commands/diffsettings.py
+++ b/django/core/management/commands/diffsettings.py
@@ -22,9 +22,7 @@ class Command(NoArgsCommand):
         default_settings = module_to_dict(global_settings)
 
         output = []
-        keys = user_settings.keys()
-        keys.sort()
-        for key in keys:
+        for key in sorted(user_settings.keys()):
             if key not in default_settings:
                 output.append("%s = %s  ###" % (key, user_settings[key]))
             elif user_settings[key] != default_settings[key]:
diff --git a/django/core/serializers/__init__.py b/django/core/serializers/__init__.py
index 09bcb651d5a..2d5e7624a45 100644
--- a/django/core/serializers/__init__.py
+++ b/django/core/serializers/__init__.py
@@ -18,6 +18,7 @@ To add your own serializers, use the SERIALIZATION_MODULES setting::
 
 from django.conf import settings
 from django.utils import importlib
+from django.utils import six
 from django.core.serializers.base import SerializerDoesNotExist
 
 # Built-in serializers
@@ -75,12 +76,12 @@ def get_serializer(format):
 def get_serializer_formats():
     if not _serializers:
         _load_serializers()
-    return _serializers.keys()
+    return list(six.iterkeys(_serializers))
 
 def get_public_serializer_formats():
     if not _serializers:
         _load_serializers()
-    return [k for k, v in _serializers.iteritems() if not v.Serializer.internal_use_only]
+    return [k for k, v in six.iteritems(_serializers) if not v.Serializer.internal_use_only]
 
 def get_deserializer(format):
     if not _serializers:
diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py
index 333161c9295..83c6eb67392 100644
--- a/django/core/serializers/python.py
+++ b/django/core/serializers/python.py
@@ -9,6 +9,7 @@ from django.conf import settings
 from django.core.serializers import base
 from django.db import models, DEFAULT_DB_ALIAS
 from django.utils.encoding import smart_unicode, is_protected_type
+from django.utils import six
 
 class Serializer(base.Serializer):
     """
@@ -87,7 +88,7 @@ def Deserializer(object_list, **options):
         m2m_data = {}
 
         # Handle each field
-        for (field_name, field_value) in d["fields"].iteritems():
+        for (field_name, field_value) in six.iteritems(d["fields"]):
             if isinstance(field_value, str):
                 field_value = smart_unicode(field_value, options.get("encoding", settings.DEFAULT_CHARSET), strings_only=True)
 
diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py
index 7397cf3b3dc..c17168f8cb4 100644
--- a/django/core/urlresolvers.py
+++ b/django/core/urlresolvers.py
@@ -376,7 +376,7 @@ class RegexURLResolver(LocaleRegexProvider):
                     unicode_args = [force_unicode(val) for val in args]
                     candidate =  (prefix_norm + result) % dict(zip(prefix_args + params, unicode_args))
                 else:
-                    if set(kwargs.keys() + defaults.keys()) != set(params + defaults.keys() + prefix_args):
+                    if set(kwargs.keys()) | set(defaults.keys()) != set(params) | set(defaults.keys()) | set(prefix_args):
                         continue
                     matches = True
                     for k, v in defaults.items():
diff --git a/django/core/validators.py b/django/core/validators.py
index 03ff8be3bca..91d6f62dcfb 100644
--- a/django/core/validators.py
+++ b/django/core/validators.py
@@ -138,7 +138,7 @@ def ip_address_validators(protocol, unpack_ipv4):
         return ip_address_validator_map[protocol.lower()]
     except KeyError:
         raise ValueError("The protocol '%s' is unknown. Supported: %s"
-                         % (protocol, ip_address_validator_map.keys()))
+                         % (protocol, list(six.iterkeys(ip_address_validator_map))))
 
 comma_separated_int_list_re = re.compile('^[\d,]+$')
 validate_comma_separated_integer_list = RegexValidator(comma_separated_int_list_re, _('Enter only digits separated by commas.'), 'invalid')
diff --git a/django/db/backends/mysql/introspection.py b/django/db/backends/mysql/introspection.py
index e6f18b819f6..6aab0b99ab0 100644
--- a/django/db/backends/mysql/introspection.py
+++ b/django/db/backends/mysql/introspection.py
@@ -1,4 +1,5 @@
 from django.db.backends import BaseDatabaseIntrospection
+from django.utils import six
 from MySQLdb import ProgrammingError, OperationalError
 from MySQLdb.constants import FIELD_TYPE
 import re
@@ -79,7 +80,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
         """
         Returns the name of the primary key column for the given table
         """
-        for column in self.get_indexes(cursor, table_name).iteritems():
+        for column in six.iteritems(self.get_indexes(cursor, table_name)):
             if column[1]['primary_key']:
                 return column[0]
         return None
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 8dd5bf864f2..a25c1062900 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -364,14 +364,14 @@ class Model(six.with_metaclass(ModelBase, object)):
                 setattr(self, field.attname, val)
 
         if kwargs:
-            for prop in kwargs.keys():
+            for prop in list(six.iterkeys(kwargs)):
                 try:
                     if isinstance(getattr(self.__class__, prop), property):
                         setattr(self, prop, kwargs.pop(prop))
                 except AttributeError:
                     pass
             if kwargs:
-                raise TypeError("'%s' is an invalid keyword argument for this function" % kwargs.keys()[0])
+                raise TypeError("'%s' is an invalid keyword argument for this function" % list(six.iterkeys(kwargs))[0])
         super(Model, self).__init__()
         signals.post_init.send(sender=self.__class__, instance=self)
 
diff --git a/django/db/models/deletion.py b/django/db/models/deletion.py
index d8bb8f2e66f..2e5ed53e636 100644
--- a/django/db/models/deletion.py
+++ b/django/db/models/deletion.py
@@ -4,6 +4,7 @@ from operator import attrgetter
 from django.db import connections, transaction, IntegrityError
 from django.db.models import signals, sql
 from django.utils.datastructures import SortedDict
+from django.utils import six
 
 
 class ProtectedError(IntegrityError):
@@ -157,7 +158,7 @@ class Collector(object):
         # Recursively collect concrete model's parent models, but not their
         # related objects. These will be found by meta.get_all_related_objects()
         concrete_model = model._meta.concrete_model
-        for ptr in concrete_model._meta.parents.itervalues():
+        for ptr in six.itervalues(concrete_model._meta.parents):
             if ptr:
                 parent_objs = [getattr(obj, ptr.name) for obj in new_objs]
                 self.collect(parent_objs, source=model,
@@ -199,14 +200,14 @@ class Collector(object):
         )
 
     def instances_with_model(self):
-        for model, instances in self.data.iteritems():
+        for model, instances in six.iteritems(self.data):
             for obj in instances:
                 yield model, obj
 
     def sort(self):
         sorted_models = []
         concrete_models = set()
-        models = self.data.keys()
+        models = list(six.iterkeys(self.data))
         while len(sorted_models) < len(models):
             found = False
             for model in models:
@@ -241,24 +242,24 @@ class Collector(object):
                 )
 
         # update fields
-        for model, instances_for_fieldvalues in self.field_updates.iteritems():
+        for model, instances_for_fieldvalues in six.iteritems(self.field_updates):
             query = sql.UpdateQuery(model)
-            for (field, value), instances in instances_for_fieldvalues.iteritems():
+            for (field, value), instances in six.iteritems(instances_for_fieldvalues):
                 query.update_batch([obj.pk for obj in instances],
                                    {field.name: value}, self.using)
 
         # reverse instance collections
-        for instances in self.data.itervalues():
+        for instances in six.itervalues(self.data):
             instances.reverse()
 
         # delete batches
-        for model, batches in self.batches.iteritems():
+        for model, batches in six.iteritems(self.batches):
             query = sql.DeleteQuery(model)
-            for field, instances in batches.iteritems():
+            for field, instances in six.iteritems(batches):
                 query.delete_batch([obj.pk for obj in instances], self.using, field)
 
         # delete instances
-        for model, instances in self.data.iteritems():
+        for model, instances in six.iteritems(self.data):
             query = sql.DeleteQuery(model)
             pk_list = [obj.pk for obj in instances]
             query.delete_batch(pk_list, self.using)
@@ -271,10 +272,10 @@ class Collector(object):
                 )
 
         # update collected instances
-        for model, instances_for_fieldvalues in self.field_updates.iteritems():
-            for (field, value), instances in instances_for_fieldvalues.iteritems():
+        for model, instances_for_fieldvalues in six.iteritems(self.field_updates):
+            for (field, value), instances in six.iteritems(instances_for_fieldvalues):
                 for obj in instances:
                     setattr(obj, field.attname, value)
-        for model, instances in self.data.iteritems():
+        for model, instances in six.iteritems(self.data):
             for instance in instances:
                 setattr(instance, model._meta.pk.attname, None)
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index 2a2502b54ff..bfa8feee9fa 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -241,7 +241,7 @@ class SingleRelatedObjectDescriptor(object):
         rel_obj_attr = attrgetter(self.related.field.attname)
         instance_attr = lambda obj: obj._get_pk_val()
         instances_dict = dict((instance_attr(inst), inst) for inst in instances)
-        params = {'%s__pk__in' % self.related.field.name: instances_dict.keys()}
+        params = {'%s__pk__in' % self.related.field.name: list(six.iterkeys(instances_dict))}
         qs = self.get_query_set(instance=instances[0]).filter(**params)
         # Since we're going to assign directly in the cache,
         # we must manage the reverse relation cache manually.
@@ -335,9 +335,9 @@ class ReverseSingleRelatedObjectDescriptor(object):
         instance_attr = attrgetter(self.field.attname)
         instances_dict = dict((instance_attr(inst), inst) for inst in instances)
         if other_field.rel:
-            params = {'%s__pk__in' % self.field.rel.field_name: instances_dict.keys()}
+            params = {'%s__pk__in' % self.field.rel.field_name: list(six.iterkeys(instances_dict))}
         else:
-            params = {'%s__in' % self.field.rel.field_name: instances_dict.keys()}
+            params = {'%s__in' % self.field.rel.field_name: list(six.iterkeys(instances_dict))}
         qs = self.get_query_set(instance=instances[0]).filter(**params)
         # Since we're going to assign directly in the cache,
         # we must manage the reverse relation cache manually.
@@ -488,7 +488,7 @@ class ForeignRelatedObjectsDescriptor(object):
                 instance_attr = attrgetter(attname)
                 instances_dict = dict((instance_attr(inst), inst) for inst in instances)
                 db = self._db or router.db_for_read(self.model, instance=instances[0])
-                query = {'%s__%s__in' % (rel_field.name, attname): instances_dict.keys()}
+                query = {'%s__%s__in' % (rel_field.name, attname): list(six.iterkeys(instances_dict))}
                 qs = super(RelatedManager, self).get_query_set().using(db).filter(**query)
                 # Since we just bypassed this class' get_query_set(), we must manage
                 # the reverse relation manually.
diff --git a/django/db/models/loading.py b/django/db/models/loading.py
index d651584e7af..7a9cb2cb415 100644
--- a/django/db/models/loading.py
+++ b/django/db/models/loading.py
@@ -5,6 +5,7 @@ from django.core.exceptions import ImproperlyConfigured
 from django.utils.datastructures import SortedDict
 from django.utils.importlib import import_module
 from django.utils.module_loading import module_has_submodule
+from django.utils import six
 
 import imp
 import sys
@@ -193,9 +194,9 @@ class AppCache(object):
         else:
             if only_installed:
                 app_list = [self.app_models.get(app_label, SortedDict())
-                            for app_label in self.app_labels.iterkeys()]
+                            for app_label in six.iterkeys(self.app_labels)]
             else:
-                app_list = self.app_models.itervalues()
+                app_list = six.itervalues(self.app_models)
         model_list = []
         for app in app_list:
             model_list.extend(
diff --git a/django/db/models/options.py b/django/db/models/options.py
index 7308a15c6bd..9e8d4120e9f 100644
--- a/django/db/models/options.py
+++ b/django/db/models/options.py
@@ -127,7 +127,7 @@ class Options(object):
             if self.parents:
                 # Promote the first parent link in lieu of adding yet another
                 # field.
-                field = next(self.parents.itervalues())
+                field = next(six.itervalues(self.parents))
                 # Look for a local field with the same name as the
                 # first parent link. If a local field has already been
                 # created, use it instead of promoting the parent
@@ -147,13 +147,13 @@ class Options(object):
         # self.duplicate_targets will map each duplicate field column to the
         # columns it duplicates.
         collections = {}
-        for column, target in self.duplicate_targets.iteritems():
+        for column, target in six.iteritems(self.duplicate_targets):
             try:
                 collections[target].add(column)
             except KeyError:
                 collections[target] = set([column])
         self.duplicate_targets = {}
-        for elt in collections.itervalues():
+        for elt in six.itervalues(collections):
             if len(elt) == 1:
                 continue
             for column in elt:
@@ -258,7 +258,7 @@ class Options(object):
             self._m2m_cache
         except AttributeError:
             self._fill_m2m_cache()
-        return self._m2m_cache.keys()
+        return list(six.iterkeys(self._m2m_cache))
     many_to_many = property(_many_to_many)
 
     def get_m2m_with_model(self):
@@ -269,7 +269,7 @@ class Options(object):
             self._m2m_cache
         except AttributeError:
             self._fill_m2m_cache()
-        return self._m2m_cache.items()
+        return list(six.iteritems(self._m2m_cache))
 
     def _fill_m2m_cache(self):
         cache = SortedDict()
@@ -326,8 +326,7 @@ class Options(object):
             cache = self._name_map
         except AttributeError:
             cache = self.init_name_map()
-        names = cache.keys()
-        names.sort()
+        names = sorted(cache.keys())
         # Internal-only names end with "+" (symmetrical m2m related names being
         # the main example). Trim them.
         return [val for val in names if not val.endswith('+')]
@@ -417,7 +416,7 @@ class Options(object):
             cache = self._fill_related_many_to_many_cache()
         if local_only:
             return [k for k, v in cache.items() if not v]
-        return cache.keys()
+        return list(six.iterkeys(cache))
 
     def get_all_related_m2m_objects_with_model(self):
         """
@@ -428,7 +427,7 @@ class Options(object):
             cache = self._related_many_to_many_cache
         except AttributeError:
             cache = self._fill_related_many_to_many_cache()
-        return cache.items()
+        return list(six.iteritems(cache))
 
     def _fill_related_many_to_many_cache(self):
         cache = SortedDict()
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 8b6b42b7b1b..6013233a0f3 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -245,8 +245,8 @@ class QuerySet(object):
             requested = None
         max_depth = self.query.max_depth
 
-        extra_select = self.query.extra_select.keys()
-        aggregate_select = self.query.aggregate_select.keys()
+        extra_select = list(six.iterkeys(self.query.extra_select))
+        aggregate_select = list(six.iterkeys(self.query.aggregate_select))
 
         only_load = self.query.get_loaded_field_names()
         if not fill_cache:
@@ -593,7 +593,7 @@ class QuerySet(object):
         flat = kwargs.pop('flat', False)
         if kwargs:
             raise TypeError('Unexpected keyword arguments to values_list: %s'
-                    % (kwargs.keys(),))
+                    % (list(six.iterkeys(kwargs)),))
         if flat and len(fields) > 1:
             raise TypeError("'flat' is not valid when values_list is called with more than one field.")
         return self._clone(klass=ValuesListQuerySet, setup=True, flat=flat,
@@ -693,7 +693,7 @@ class QuerySet(object):
         depth = kwargs.pop('depth', 0)
         if kwargs:
             raise TypeError('Unexpected keyword arguments to select_related: %s'
-                    % (kwargs.keys(),))
+                    % (list(six.iterkeys(kwargs)),))
         obj = self._clone()
         if fields:
             if depth:
@@ -751,7 +751,7 @@ class QuerySet(object):
 
         obj = self._clone()
 
-        obj._setup_aggregate_query(kwargs.keys())
+        obj._setup_aggregate_query(list(six.iterkeys(kwargs)))
 
         # Add the aggregates to the query
         for (alias, aggregate_expr) in kwargs.items():
@@ -966,9 +966,9 @@ class ValuesQuerySet(QuerySet):
 
     def iterator(self):
         # Purge any extra columns that haven't been explicitly asked for
-        extra_names = self.query.extra_select.keys()
+        extra_names = list(six.iterkeys(self.query.extra_select))
         field_names = self.field_names
-        aggregate_names = self.query.aggregate_select.keys()
+        aggregate_names = list(six.iterkeys(self.query.aggregate_select))
 
         names = extra_names + field_names + aggregate_names
 
@@ -1097,9 +1097,9 @@ class ValuesListQuerySet(ValuesQuerySet):
             # When extra(select=...) or an annotation is involved, the extra
             # cols are always at the start of the row, and we need to reorder
             # the fields to match the order in self._fields.
-            extra_names = self.query.extra_select.keys()
+            extra_names = list(six.iterkeys(self.query.extra_select))
             field_names = self.field_names
-            aggregate_names = self.query.aggregate_select.keys()
+            aggregate_names = list(six.iterkeys(self.query.aggregate_select))
 
             names = extra_names + field_names + aggregate_names
 
@@ -1527,7 +1527,7 @@ class RawQuerySet(object):
             # Associate fields to values
             if skip:
                 model_init_kwargs = {}
-                for attname, pos in model_init_field_names.iteritems():
+                for attname, pos in six.iteritems(model_init_field_names):
                     model_init_kwargs[attname] = values[pos]
                 instance = model_cls(**model_init_kwargs)
             else:
diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py
index 60bdb2bcb4d..c1a690a524e 100644
--- a/django/db/models/query_utils.py
+++ b/django/db/models/query_utils.py
@@ -8,6 +8,7 @@ circular import difficulties.
 from __future__ import unicode_literals
 
 from django.db.backends import util
+from django.utils import six
 from django.utils import tree
 
 
@@ -40,7 +41,7 @@ class Q(tree.Node):
     default = AND
 
     def __init__(self, *args, **kwargs):
-        super(Q, self).__init__(children=list(args) + kwargs.items())
+        super(Q, self).__init__(children=list(args) + list(six.iteritems(kwargs)))
 
     def _combine(self, other, conn):
         if not isinstance(other, Q):
@@ -114,7 +115,7 @@ class DeferredAttribute(object):
 
     def _check_parent_chain(self, instance, name):
         """
-        Check if the field value can be fetched from a parent field already 
+        Check if the field value can be fetched from a parent field already
         loaded in the instance. This can be done if the to-be fetched
         field is a primary key field.
         """
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
index 7a0afa349d8..1311ea546cc 100644
--- a/django/db/models/sql/compiler.py
+++ b/django/db/models/sql/compiler.py
@@ -9,6 +9,7 @@ from django.db.models.sql.datastructures import EmptyResultSet
 from django.db.models.sql.expressions import SQLEvaluator
 from django.db.models.sql.query import get_order_dir, Query
 from django.db.utils import DatabaseError
+from django.utils import six
 
 
 class SQLCompiler(object):
@@ -82,7 +83,7 @@ class SQLCompiler(object):
         where, w_params = self.query.where.as_sql(qn=qn, connection=self.connection)
         having, h_params = self.query.having.as_sql(qn=qn, connection=self.connection)
         params = []
-        for val in self.query.extra_select.itervalues():
+        for val in six.itervalues(self.query.extra_select):
             params.extend(val[1])
 
         result = ['SELECT']
@@ -177,7 +178,7 @@ class SQLCompiler(object):
         """
         qn = self.quote_name_unless_alias
         qn2 = self.connection.ops.quote_name
-        result = ['(%s) AS %s' % (col[0], qn2(alias)) for alias, col in self.query.extra_select.iteritems()]
+        result = ['(%s) AS %s' % (col[0], qn2(alias)) for alias, col in six.iteritems(self.query.extra_select)]
         aliases = set(self.query.extra_select.keys())
         if with_aliases:
             col_aliases = aliases.copy()
@@ -553,7 +554,7 @@ class SQLCompiler(object):
             group_by = self.query.group_by or []
 
             extra_selects = []
-            for extra_select, extra_params in self.query.extra_select.itervalues():
+            for extra_select, extra_params in six.itervalues(self.query.extra_select):
                 extra_selects.append(extra_select)
                 params.extend(extra_params)
             cols = (group_by + self.query.select +
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 53dad608bf7..9cf732f2632 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -12,6 +12,7 @@ import copy
 from django.utils.datastructures import SortedDict
 from django.utils.encoding import force_unicode
 from django.utils.tree import Node
+from django.utils import six
 from django.db import connections, DEFAULT_DB_ALIAS
 from django.db.models import signals
 from django.db.models.expressions import ExpressionNode
@@ -602,22 +603,22 @@ class Query(object):
             # slight complexity here is handling fields that exist on parent
             # models.
             workset = {}
-            for model, values in seen.iteritems():
+            for model, values in six.iteritems(seen):
                 for field, m in model._meta.get_fields_with_model():
                     if field in values:
                         continue
                     add_to_dict(workset, m or model, field)
-            for model, values in must_include.iteritems():
+            for model, values in six.iteritems(must_include):
                 # If we haven't included a model in workset, we don't add the
                 # corresponding must_include fields for that model, since an
                 # empty set means "include all fields". That's why there's no
                 # "else" branch here.
                 if model in workset:
                     workset[model].update(values)
-            for model, values in workset.iteritems():
+            for model, values in six.iteritems(workset):
                 callback(target, model, values)
         else:
-            for model, values in must_include.iteritems():
+            for model, values in six.iteritems(must_include):
                 if model in seen:
                     seen[model].update(values)
                 else:
@@ -631,7 +632,7 @@ class Query(object):
             for model in orig_opts.get_parent_list():
                 if model not in seen:
                     seen[model] = set()
-            for model, values in seen.iteritems():
+            for model, values in six.iteritems(seen):
                 callback(target, model, values)
 
 
@@ -770,7 +771,7 @@ class Query(object):
         for k, aliases in self.join_map.items():
             aliases = tuple([change_map.get(a, a) for a in aliases])
             self.join_map[k] = aliases
-        for old_alias, new_alias in change_map.iteritems():
+        for old_alias, new_alias in six.iteritems(change_map):
             alias_data = self.alias_map[old_alias]
             alias_data = alias_data._replace(rhs_alias=new_alias)
             self.alias_refcount[new_alias] = self.alias_refcount[old_alias]
@@ -792,7 +793,7 @@ class Query(object):
                 self.included_inherited_models[key] = change_map[alias]
 
         # 3. Update any joins that refer to the old alias.
-        for alias, data in self.alias_map.iteritems():
+        for alias, data in six.iteritems(self.alias_map):
             lhs = data.lhs_alias
             if lhs in change_map:
                 data = data._replace(lhs_alias=change_map[lhs])
@@ -842,7 +843,7 @@ class Query(object):
         count. Note that after execution, the reference counts are zeroed, so
         tables added in compiler will not be seen by this method.
         """
-        return len([1 for count in self.alias_refcount.itervalues() if count])
+        return len([1 for count in six.itervalues(self.alias_refcount) if count])
 
     def join(self, connection, always_create=False, exclusions=(),
             promote=False, outer_if_first=False, nullable=False, reuse=None):
@@ -1302,7 +1303,7 @@ class Query(object):
                         field, model, direct, m2m = opts.get_field_by_name(f.name)
                         break
                 else:
-                    names = opts.get_all_field_names() + self.aggregate_select.keys()
+                    names = opts.get_all_field_names() + list(six.iterkeys(self.aggregate_select))
                     raise FieldError("Cannot resolve keyword %r into field. "
                             "Choices are: %s" % (name, ", ".join(names)))
 
@@ -1571,7 +1572,7 @@ class Query(object):
         # Tag.objects.exclude(parent__parent__name='t1'), a tag with no parent
         # would otherwise be overlooked).
         active_positions = [pos for (pos, count) in
-                enumerate(query.alias_refcount.itervalues()) if count]
+                enumerate(six.itervalues(query.alias_refcount)) if count]
         if active_positions[-1] > 1:
             self.add_filter(('%s__isnull' % prefix, False), negate=True,
                     trim=True, can_reuse=can_reuse)
@@ -1660,8 +1661,8 @@ class Query(object):
                 # from the model on which the lookup failed.
                 raise
             else:
-                names = sorted(opts.get_all_field_names() + self.extra.keys()
-                               + self.aggregate_select.keys())
+                names = sorted(opts.get_all_field_names() + list(six.iterkeys(self.extra))
+                               + list(six.iterkeys(self.aggregate_select)))
                 raise FieldError("Cannot resolve keyword %r into field. "
                                  "Choices are: %s" % (name, ", ".join(names)))
         self.remove_inherited_models()
diff --git a/django/db/models/sql/subqueries.py b/django/db/models/sql/subqueries.py
index 7b92394e906..cc7da0eeaf4 100644
--- a/django/db/models/sql/subqueries.py
+++ b/django/db/models/sql/subqueries.py
@@ -11,6 +11,7 @@ from django.db.models.sql.where import AND, Constraint
 from django.utils.datastructures import SortedDict
 from django.utils.functional import Promise
 from django.utils.encoding import force_unicode
+from django.utils import six
 
 
 __all__ = ['DeleteQuery', 'UpdateQuery', 'InsertQuery', 'DateQuery',
@@ -87,7 +88,7 @@ class UpdateQuery(Query):
         querysets.
         """
         values_seq = []
-        for name, val in values.iteritems():
+        for name, val in six.iteritems(values):
             field, model, direct, m2m = self.model._meta.get_field_by_name(name)
             if not direct or m2m:
                 raise FieldError('Cannot update model field %r (only non-relations and foreign keys permitted).' % field)
@@ -129,7 +130,7 @@ class UpdateQuery(Query):
         if not self.related_updates:
             return []
         result = []
-        for model, values in self.related_updates.iteritems():
+        for model, values in six.iteritems(self.related_updates):
             query = UpdateQuery(model)
             query.values = values
             if self.related_ids is not None:
diff --git a/django/forms/extras/widgets.py b/django/forms/extras/widgets.py
index 4e11a4ee062..c5ca1424c80 100644
--- a/django/forms/extras/widgets.py
+++ b/django/forms/extras/widgets.py
@@ -79,7 +79,7 @@ class SelectDateWidget(Widget):
                         year_val, month_val, day_val = [int(v) for v in match.groups()]
         choices = [(i, i) for i in self.years]
         year_html = self.create_select(name, self.year_field, value, year_val, choices)
-        choices = MONTHS.items()
+        choices = list(six.iteritems(MONTHS))
         month_html = self.create_select(name, self.month_field, value, month_val, choices)
         choices = [(i, i) for i in range(1, 32)]
         day_html = self.create_select(name, self.day_field, value, day_val,  choices)
diff --git a/django/forms/forms.py b/django/forms/forms.py
index 4d4cdbe3db5..0f3fdb2e407 100644
--- a/django/forms/forms.py
+++ b/django/forms/forms.py
@@ -38,7 +38,7 @@ def get_declared_fields(bases, attrs, with_base_fields=True):
     used. The distinction is useful in ModelForm subclassing.
     Also integrates any additional media definitions
     """
-    fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)]
+    fields = [(field_name, attrs.pop(field_name)) for field_name, obj in list(six.iteritems(attrs)) if isinstance(obj, Field)]
     fields.sort(key=lambda x: x[1].creation_counter)
 
     # If this class is subclassing another Form, add that Form's fields.
@@ -47,11 +47,11 @@ def get_declared_fields(bases, attrs, with_base_fields=True):
     if with_base_fields:
         for base in bases[::-1]:
             if hasattr(base, 'base_fields'):
-                fields = base.base_fields.items() + fields
+                fields = list(six.iteritems(base.base_fields)) + fields
     else:
         for base in bases[::-1]:
             if hasattr(base, 'declared_fields'):
-                fields = base.declared_fields.items() + fields
+                fields = list(six.iteritems(base.declared_fields)) + fields
 
     return SortedDict(fields)
 
diff --git a/django/forms/models.py b/django/forms/models.py
index e6ae357d192..a2b5448b14e 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -18,6 +18,7 @@ from django.utils.datastructures import SortedDict
 from django.utils import six
 from django.utils.text import get_text_list, capfirst
 from django.utils.translation import ugettext_lazy as _, ugettext
+from django.utils import six
 
 
 __all__ = (
@@ -206,7 +207,7 @@ class ModelFormMetaclass(type):
             fields = fields_for_model(opts.model, opts.fields,
                                       opts.exclude, opts.widgets, formfield_callback)
             # make sure opts.fields doesn't specify an invalid field
-            none_model_fields = [k for k, v in fields.iteritems() if not v]
+            none_model_fields = [k for k, v in six.iteritems(fields) if not v]
             missing_fields = set(none_model_fields) - \
                              set(declared_fields.keys())
             if missing_fields:
diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index 3c4da2444df..13b7d8e7f6a 100644
--- a/django/forms/widgets.py
+++ b/django/forms/widgets.py
@@ -63,8 +63,7 @@ class Media(StrAndUnicode):
     def render_css(self):
         # To keep rendering order consistent, we can't just iterate over items().
         # We need to sort the keys, and iterate over the sorted list.
-        media = self._css.keys()
-        media.sort()
+        media = sorted(self._css.keys())
         return chain(*[
                 [format_html('<link href="{0}" type="text/css" media="{1}" rel="stylesheet" />', self.absolute_path(path), medium)
                     for path in self._css[medium]]
diff --git a/django/template/base.py b/django/template/base.py
index 489b1681e0f..d5c24385000 100644
--- a/django/template/base.py
+++ b/django/template/base.py
@@ -961,7 +961,7 @@ def parse_bits(parser, bits, params, varargs, varkw, defaults,
         kwarg = token_kwargs([bit], parser)
         if kwarg:
             # The kwarg was successfully extracted
-            param, value = kwarg.items()[0]
+            param, value = list(six.iteritems(kwarg))[0]
             if param not in params and varkw is None:
                 # An unexpected keyword argument was supplied
                 raise TemplateSyntaxError(
diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
index fb45fe722eb..7a00d60361c 100644
--- a/django/template/defaulttags.py
+++ b/django/template/defaulttags.py
@@ -17,6 +17,7 @@ from django.template.defaultfilters import date
 from django.utils.encoding import smart_unicode
 from django.utils.safestring import mark_safe
 from django.utils.html import format_html
+from django.utils import six
 from django.utils import timezone
 
 register = Library()
@@ -473,7 +474,7 @@ class WithNode(Node):
 
     def render(self, context):
         values = dict([(key, val.resolve(context)) for key, val in
-                       self.extra_context.iteritems()])
+                       six.iteritems(self.extra_context)])
         context.update(values)
         output = self.nodelist.render(context)
         context.pop()
@@ -1188,7 +1189,7 @@ def templatetag(parser, token):
     if tag not in TemplateTagNode.mapping:
         raise TemplateSyntaxError("Invalid templatetag argument: '%s'."
                                   " Must be one of: %s" %
-                                  (tag, TemplateTagNode.mapping.keys()))
+                                  (tag, list(six.iterkeys(TemplateTagNode.mapping))))
     return TemplateTagNode(tag)
 
 @register.tag
diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py
index b63938abb07..d295d058d07 100644
--- a/django/template/loader_tags.py
+++ b/django/template/loader_tags.py
@@ -3,6 +3,7 @@ from django.template.base import TemplateSyntaxError, Library, Node, TextNode,\
     token_kwargs, Variable
 from django.template.loader import get_template
 from django.utils.safestring import mark_safe
+from django.utils import six
 
 register = Library()
 
@@ -17,7 +18,7 @@ class BlockContext(object):
         self.blocks = {}
 
     def add_blocks(self, blocks):
-        for name, block in blocks.iteritems():
+        for name, block in six.iteritems(blocks):
             if name in self.blocks:
                 self.blocks[name].insert(0, block)
             else:
@@ -130,7 +131,7 @@ class BaseIncludeNode(Node):
 
     def render_template(self, template, context):
         values = dict([(name, var.resolve(context)) for name, var
-                       in self.extra_context.iteritems()])
+                       in six.iteritems(self.extra_context)])
         if self.isolated_context:
             return template.render(context.new(values))
         context.update(values)
diff --git a/django/templatetags/i18n.py b/django/templatetags/i18n.py
index 509ab6707de..30eb6b5f761 100644
--- a/django/templatetags/i18n.py
+++ b/django/templatetags/i18n.py
@@ -425,7 +425,7 @@ def do_block_translate(parser, token):
         options[option] = value
 
     if 'count' in options:
-        countervar, counter = options['count'].items()[0]
+        countervar, counter = list(six.iteritems(options['count']))[0]
     else:
         countervar, counter = None, None
     if 'context' in options:
diff --git a/django/utils/dateparse.py b/django/utils/dateparse.py
index 532bb259c31..032eb493b62 100644
--- a/django/utils/dateparse.py
+++ b/django/utils/dateparse.py
@@ -7,6 +7,7 @@
 
 import datetime
 import re
+from django.utils import six
 from django.utils.timezone import utc
 from django.utils.tzinfo import FixedOffset
 
@@ -34,7 +35,7 @@ def parse_date(value):
     """
     match = date_re.match(value)
     if match:
-        kw = dict((k, int(v)) for k, v in match.groupdict().iteritems())
+        kw = dict((k, int(v)) for k, v in six.iteritems(match.groupdict()))
         return datetime.date(**kw)
 
 def parse_time(value):
@@ -53,7 +54,7 @@ def parse_time(value):
         kw = match.groupdict()
         if kw['microsecond']:
             kw['microsecond'] = kw['microsecond'].ljust(6, '0')
-        kw = dict((k, int(v)) for k, v in kw.iteritems() if v is not None)
+        kw = dict((k, int(v)) for k, v in six.iteritems(kw) if v is not None)
         return datetime.time(**kw)
 
 def parse_datetime(value):
@@ -80,6 +81,6 @@ def parse_datetime(value):
             if tzinfo[0] == '-':
                 offset = -offset
             tzinfo = FixedOffset(offset)
-        kw = dict((k, int(v)) for k, v in kw.iteritems() if v is not None)
+        kw = dict((k, int(v)) for k, v in six.iteritems(kw) if v is not None)
         kw['tzinfo'] = tzinfo
         return datetime.datetime(**kw)
diff --git a/django/utils/dictconfig.py b/django/utils/dictconfig.py
index b4d6d66b3c4..f8d6eebf89b 100644
--- a/django/utils/dictconfig.py
+++ b/django/utils/dictconfig.py
@@ -363,7 +363,7 @@ class DictConfigurator(BaseConfigurator):
                 #which were in the previous configuration but
                 #which are not in the new configuration.
                 root = logging.root
-                existing = root.manager.loggerDict.keys()
+                existing = list(six.iterkeys(root.manager.loggerDict))
                 #The list needs to be sorted so that we can
                 #avoid disabling child loggers of explicitly
                 #named loggers. With a sorted list it is easier
diff --git a/django/utils/functional.py b/django/utils/functional.py
index 69aae098876..177325dfb6e 100644
--- a/django/utils/functional.py
+++ b/django/utils/functional.py
@@ -178,7 +178,7 @@ def allow_lazy(func, *resultclasses):
     """
     @wraps(func)
     def wrapper(*args, **kwargs):
-        for arg in list(args) + kwargs.values():
+        for arg in list(args) + list(six.itervalues(kwargs)):
             if isinstance(arg, Promise):
                 break
         else:
diff --git a/django/utils/html.py b/django/utils/html.py
index e1263fbd66b..4e888fc59bf 100644
--- a/django/utils/html.py
+++ b/django/utils/html.py
@@ -84,7 +84,7 @@ def format_html(format_string, *args, **kwargs):
     """
     args_safe = map(conditional_escape, args)
     kwargs_safe = dict([(k, conditional_escape(v)) for (k, v) in
-                        kwargs.iteritems()])
+                        six.iteritems(kwargs)])
     return mark_safe(format_string.format(*args_safe, **kwargs_safe))
 
 def format_html_join(sep, format_string, args_generator):
diff --git a/django/utils/termcolors.py b/django/utils/termcolors.py
index 1eebaa2316b..4f74b564a5a 100644
--- a/django/utils/termcolors.py
+++ b/django/utils/termcolors.py
@@ -2,6 +2,8 @@
 termcolors.py
 """
 
+from django.utils import six
+
 color_names = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white')
 foreground = dict([(color_names[x], '3%s' % x) for x in range(8)])
 background = dict([(color_names[x], '4%s' % x) for x in range(8)])
@@ -41,7 +43,7 @@ def colorize(text='', opts=(), **kwargs):
     code_list = []
     if text == '' and len(opts) == 1 and opts[0] == 'reset':
         return '\x1b[%sm' % RESET
-    for k, v in kwargs.iteritems():
+    for k, v in six.iteritems(kwargs):
         if k == 'fg':
             code_list.append(foreground[v])
         elif k == 'bg':
diff --git a/django/views/debug.py b/django/views/debug.py
index 8e81b8239bd..08341fe145c 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -111,7 +111,7 @@ class ExceptionReporterFilter(object):
             return request.POST
 
     def get_traceback_frame_variables(self, request, tb_frame):
-        return tb_frame.f_locals.items()
+        return list(six.iteritems(tb_frame.f_locals))
 
 class SafeExceptionReporterFilter(ExceptionReporterFilter):
     """
diff --git a/django/views/generic/base.py b/django/views/generic/base.py
index 69751727bbf..6554e898caf 100644
--- a/django/views/generic/base.py
+++ b/django/views/generic/base.py
@@ -6,6 +6,7 @@ from django.core.exceptions import ImproperlyConfigured
 from django.template.response import TemplateResponse
 from django.utils.log import getLogger
 from django.utils.decorators import classonlymethod
+from django.utils import six
 
 logger = getLogger('django.request')
 
@@ -35,7 +36,7 @@ class View(object):
         """
         # Go through keyword arguments, and either save their values to our
         # instance, or raise an error.
-        for key, value in kwargs.iteritems():
+        for key, value in six.iteritems(kwargs):
             setattr(self, key, value)
 
     @classonlymethod
diff --git a/tests/modeltests/timezones/tests.py b/tests/modeltests/timezones/tests.py
index aadb8ba842f..a38e4b3f753 100644
--- a/tests/modeltests/timezones/tests.py
+++ b/tests/modeltests/timezones/tests.py
@@ -20,6 +20,7 @@ from django.http import HttpRequest
 from django.template import Context, RequestContext, Template, TemplateSyntaxError
 from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
 from django.test.utils import override_settings
+from django.utils import six
 from django.utils import timezone
 from django.utils.tzinfo import FixedOffset
 from django.utils.unittest import skipIf, skipUnless
@@ -690,8 +691,8 @@ class TemplateTests(TestCase):
             }
         }
 
-        for k1, dt in datetimes.iteritems():
-            for k2, tpl in templates.iteritems():
+        for k1, dt in six.iteritems(datetimes):
+            for k2, tpl in six.iteritems(templates):
                 ctx = Context({'dt': dt, 'ICT': ICT})
                 actual = tpl.render(ctx)
                 expected = results[k1][k2]
@@ -703,8 +704,8 @@ class TemplateTests(TestCase):
         results['ict']['notag'] = t('ict', 'eat', 'utc', 'ict')
 
         with self.settings(USE_TZ=False):
-            for k1, dt in datetimes.iteritems():
-                for k2, tpl in templates.iteritems():
+            for k1, dt in six.iteritems(datetimes):
+                for k2, tpl in six.iteritems(templates):
                     ctx = Context({'dt': dt, 'ICT': ICT})
                     actual = tpl.render(ctx)
                     expected = results[k1][k2]
diff --git a/tests/regressiontests/aggregation_regress/tests.py b/tests/regressiontests/aggregation_regress/tests.py
index e5f12e5781c..e24eb43b87c 100644
--- a/tests/regressiontests/aggregation_regress/tests.py
+++ b/tests/regressiontests/aggregation_regress/tests.py
@@ -8,6 +8,7 @@ from operator import attrgetter
 from django.core.exceptions import FieldError
 from django.db.models import Count, Max, Avg, Sum, StdDev, Variance, F, Q
 from django.test import TestCase, Approximate, skipUnlessDBFeature
+from django.utils import six
 
 from .models import Author, Book, Publisher, Clues, Entries, HardbackBook
 
@@ -16,7 +17,7 @@ class AggregationTests(TestCase):
     fixtures = ["aggregation_regress.json"]
 
     def assertObjectAttrs(self, obj, **kwargs):
-        for attr, value in kwargs.iteritems():
+        for attr, value in six.iteritems(kwargs):
             self.assertEqual(getattr(obj, attr), value)
 
     def test_aggregates_in_where_clause(self):
diff --git a/tests/regressiontests/db_typecasts/tests.py b/tests/regressiontests/db_typecasts/tests.py
index 83bd1e68512..2cf835d94e9 100644
--- a/tests/regressiontests/db_typecasts/tests.py
+++ b/tests/regressiontests/db_typecasts/tests.py
@@ -3,6 +3,7 @@
 import datetime
 
 from django.db.backends import util as typecasts
+from django.utils import six
 from django.utils import unittest
 
 
@@ -49,7 +50,7 @@ TEST_CASES = {
 
 class DBTypeCasts(unittest.TestCase):
     def test_typeCasts(self):
-        for k, v in TEST_CASES.iteritems():
+        for k, v in six.iteritems(TEST_CASES):
             for inpt, expected in v:
                 got = getattr(typecasts, k)(inpt)
                 self.assertEqual(got, expected, "In %s: %r doesn't match %r. Got %r instead." % (k, inpt, expected, got))
diff --git a/tests/regressiontests/templates/templatetags/custom.py b/tests/regressiontests/templates/templatetags/custom.py
index 95fcd551de3..3f513538801 100644
--- a/tests/regressiontests/templates/templatetags/custom.py
+++ b/tests/regressiontests/templates/templatetags/custom.py
@@ -70,7 +70,7 @@ simple_only_unlimited_args.anything = "Expected simple_only_unlimited_args __dic
 def simple_unlimited_args_kwargs(one, two='hi', *args, **kwargs):
     """Expected simple_unlimited_args_kwargs __doc__"""
     # Sort the dictionary by key to guarantee the order for testing.
-    sorted_kwarg = sorted(kwargs.iteritems(), key=operator.itemgetter(0))
+    sorted_kwarg = sorted(six.iteritems(kwargs), key=operator.itemgetter(0))
     return "simple_unlimited_args_kwargs - Expected result: %s / %s" % (
         ', '.join([six.text_type(arg) for arg in [one, two] + list(args)]),
         ', '.join(['%s=%s' % (k, v) for (k, v) in sorted_kwarg])
@@ -221,7 +221,7 @@ inclusion_tag_use_l10n.anything = "Expected inclusion_tag_use_l10n __dict__"
 def inclusion_unlimited_args_kwargs(one, two='hi', *args, **kwargs):
     """Expected inclusion_unlimited_args_kwargs __doc__"""
     # Sort the dictionary by key to guarantee the order for testing.
-    sorted_kwarg = sorted(kwargs.iteritems(), key=operator.itemgetter(0))
+    sorted_kwarg = sorted(six.iteritems(kwargs), key=operator.itemgetter(0))
     return {"result": "inclusion_unlimited_args_kwargs - Expected result: %s / %s" % (
         ', '.join([six.text_type(arg) for arg in [one, two] + list(args)]),
         ', '.join(['%s=%s' % (k, v) for (k, v) in sorted_kwarg])
@@ -292,7 +292,7 @@ assignment_only_unlimited_args.anything = "Expected assignment_only_unlimited_ar
 def assignment_unlimited_args_kwargs(one, two='hi', *args, **kwargs):
     """Expected assignment_unlimited_args_kwargs __doc__"""
     # Sort the dictionary by key to guarantee the order for testing.
-    sorted_kwarg = sorted(kwargs.iteritems(), key=operator.itemgetter(0))
+    sorted_kwarg = sorted(six.iteritems(kwargs), key=operator.itemgetter(0))
     return "assignment_unlimited_args_kwargs - Expected result: %s / %s" % (
         ', '.join([six.text_type(arg) for arg in [one, two] + list(args)]),
         ', '.join(['%s=%s' % (k, v) for (k, v) in sorted_kwarg])
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
index 402cbb19d21..edbb21b6bd8 100644
--- a/tests/regressiontests/templates/tests.py
+++ b/tests/regressiontests/templates/tests.py
@@ -30,6 +30,7 @@ from django.utils import unittest
 from django.utils.formats import date_format
 from django.utils.translation import activate, deactivate, ugettext as _
 from django.utils.safestring import mark_safe
+from django.utils import six
 from django.utils.tzinfo import LocalTimezone
 
 from .callables import CallableVariablesTests
@@ -402,7 +403,7 @@ class Templates(unittest.TestCase):
         template_tests.update(filter_tests)
 
         cache_loader = setup_test_template_loader(
-            dict([(name, t[0]) for name, t in template_tests.iteritems()]),
+            dict([(name, t[0]) for name, t in six.iteritems(template_tests)]),
             use_cached_loader=True,
         )
 

From c5ef65bcf324f4c90b53be90f4aec069a68e8c59 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Sat, 21 Jul 2012 10:00:10 +0200
Subject: [PATCH 51/88] [py3] Ported django.utils.encoding.

* Renamed smart_unicode to smart_text (but kept the old name under
  Python 2 for backwards compatibility).
* Renamed smart_str to smart_bytes.
* Re-introduced smart_str as an alias for smart_text under Python 3
  and smart_bytes under Python 2 (which is backwards compatible).
  Thus smart_str always returns a str objects.
* Used the new smart_str in a few places where both Python 2 and 3
  want a str.
---
 django/contrib/admin/actions.py               |  8 +--
 django/contrib/admin/filters.py               |  8 +--
 django/contrib/admin/helpers.py               |  8 +--
 django/contrib/admin/models.py                |  6 +-
 django/contrib/admin/options.py               | 58 ++++++++--------
 .../contrib/admin/templatetags/admin_list.py  | 12 ++--
 django/contrib/admin/util.py                  | 18 ++---
 django/contrib/admin/views/main.py            |  6 +-
 django/contrib/admin/widgets.py               |  8 +--
 django/contrib/admindocs/utils.py             |  4 +-
 django/contrib/auth/hashers.py                |  8 +--
 django/contrib/auth/tests/forms.py            | 28 ++++----
 django/contrib/auth/tests/views.py            |  4 +-
 django/contrib/comments/forms.py              |  4 +-
 django/contrib/comments/managers.py           |  4 +-
 .../contrib/comments/templatetags/comments.py |  4 +-
 django/contrib/contenttypes/generic.py        |  4 +-
 django/contrib/contenttypes/management.py     |  4 +-
 django/contrib/contenttypes/models.py         | 10 +--
 django/contrib/databrowse/datastructures.py   | 16 ++---
 .../contrib/databrowse/plugins/calendars.py   |  4 +-
 .../databrowse/plugins/fieldchoices.py        |  4 +-
 .../contrib/formtools/wizard/storage/base.py  |  4 +-
 django/contrib/gis/sitemaps/views.py          |  4 +-
 .../contrib/humanize/templatetags/humanize.py |  4 +-
 django/contrib/localflavor/au/forms.py        |  4 +-
 django/contrib/localflavor/br/forms.py        |  8 +--
 django/contrib/localflavor/ca/forms.py        |  4 +-
 django/contrib/localflavor/ch/forms.py        |  4 +-
 django/contrib/localflavor/cl/forms.py        |  4 +-
 django/contrib/localflavor/fr/forms.py        |  4 +-
 django/contrib/localflavor/hk/forms.py        |  4 +-
 django/contrib/localflavor/hr/forms.py        |  6 +-
 django/contrib/localflavor/id/forms.py        | 10 +--
 django/contrib/localflavor/in_/forms.py       |  6 +-
 django/contrib/localflavor/is_/forms.py       |  4 +-
 django/contrib/localflavor/it/forms.py        |  4 +-
 django/contrib/localflavor/it/util.py         |  6 +-
 django/contrib/localflavor/nl/forms.py        |  4 +-
 django/contrib/localflavor/pt/forms.py        |  6 +-
 django/contrib/localflavor/tr/forms.py        |  4 +-
 django/contrib/localflavor/us/forms.py        |  4 +-
 django/contrib/markup/templatetags/markup.py  | 20 +++---
 django/contrib/messages/storage/base.py       | 14 ++--
 django/contrib/sessions/backends/db.py        |  4 +-
 .../management/commands/collectstatic.py      |  6 +-
 .../management/commands/findstatic.py         |  6 +-
 django/contrib/staticfiles/storage.py         | 10 +--
 django/contrib/syndication/views.py           | 12 ++--
 django/core/cache/backends/base.py            |  6 +-
 django/core/context_processors.py             |  4 +-
 django/core/exceptions.py                     |  6 +-
 django/core/files/base.py                     |  6 +-
 django/core/files/storage.py                  |  4 +-
 django/core/files/uploadedfile.py             |  4 +-
 django/core/handlers/base.py                  |  8 +--
 django/core/handlers/wsgi.py                  |  6 +-
 django/core/mail/message.py                   | 12 ++--
 .../management/commands/createcachetable.py   |  4 +-
 django/core/management/commands/loaddata.py   |  4 +-
 django/core/serializers/base.py               |  2 +-
 django/core/serializers/json.py               |  2 +-
 django/core/serializers/python.py             | 14 ++--
 django/core/serializers/pyyaml.py             |  2 +-
 django/core/serializers/xml_serializer.py     | 18 ++---
 django/core/signing.py                        | 12 ++--
 django/core/urlresolvers.py                   | 12 ++--
 django/core/validators.py                     |  6 +-
 django/db/backends/__init__.py                | 10 +--
 django/db/backends/oracle/base.py             | 18 ++---
 django/db/models/base.py                      | 10 +--
 django/db/models/fields/__init__.py           | 14 ++--
 django/db/models/fields/files.py              |  4 +-
 django/db/models/fields/related.py            |  6 +-
 django/db/models/options.py                   |  6 +-
 django/db/models/related.py                   |  6 +-
 django/db/models/sql/query.py                 |  4 +-
 django/db/models/sql/subqueries.py            |  6 +-
 django/forms/fields.py                        | 20 +++---
 django/forms/forms.py                         | 20 +++---
 django/forms/models.py                        | 10 +--
 django/forms/util.py                          | 12 ++--
 django/forms/widgets.py                       | 42 ++++++------
 django/http/__init__.py                       | 24 +++----
 django/http/multipartparser.py                | 10 +--
 django/template/base.py                       | 12 ++--
 django/template/debug.py                      |  4 +-
 django/template/defaultfilters.py             | 18 ++---
 django/template/defaulttags.py                |  6 +-
 django/templatetags/l10n.py                   |  6 +-
 django/test/client.py                         | 10 +--
 django/test/html.py                           |  4 +-
 django/test/testcases.py                      |  8 +--
 django/utils/_os.py                           |  6 +-
 django/utils/cache.py                         |  4 +-
 django/utils/crypto.py                        |  8 +--
 django/utils/dateformat.py                    |  6 +-
 django/utils/encoding.py                      | 66 ++++++++++++-------
 django/utils/feedgenerator.py                 | 12 ++--
 django/utils/html.py                          | 22 +++----
 django/utils/http.py                          | 10 +--
 django/utils/text.py                          | 24 +++----
 django/utils/translation/__init__.py          |  4 +-
 django/utils/translation/trans_null.py        |  6 +-
 django/utils/tzinfo.py                        |  6 +-
 django/views/debug.py                         |  8 +--
 django/views/generic/dates.py                 |  6 +-
 django/views/i18n.py                          |  6 +-
 docs/howto/custom-model-fields.txt            |  2 +-
 docs/ref/databases.txt                        |  2 +-
 docs/ref/models/instances.txt                 |  4 +-
 docs/ref/settings.txt                         |  2 +-
 docs/ref/unicode.txt                          | 24 +++----
 docs/ref/utils.txt                            | 50 ++++++++++----
 docs/releases/1.5.txt                         |  2 +-
 docs/topics/cache.txt                         |  2 +-
 docs/topics/serialization.txt                 |  4 +-
 tests/modeltests/field_subclassing/fields.py  |  8 +--
 tests/modeltests/field_subclassing/models.py  |  4 +-
 tests/regressiontests/admin_filters/tests.py  | 60 ++++++++---------
 tests/regressiontests/admin_views/admin.py    |  2 +-
 tests/regressiontests/cache/tests.py          |  6 +-
 tests/regressiontests/forms/tests/extra.py    | 14 ++--
 tests/regressiontests/signing/tests.py        |  4 +-
 .../staticfiles_tests/tests.py                |  6 +-
 125 files changed, 629 insertions(+), 583 deletions(-)

diff --git a/django/contrib/admin/actions.py b/django/contrib/admin/actions.py
index 5b56402428a..201101736e9 100644
--- a/django/contrib/admin/actions.py
+++ b/django/contrib/admin/actions.py
@@ -7,7 +7,7 @@ from django.contrib.admin import helpers
 from django.contrib.admin.util import get_deleted_objects, model_ngettext
 from django.db import router
 from django.template.response import TemplateResponse
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils.translation import ugettext_lazy, ugettext as _
 
 def delete_selected(modeladmin, request, queryset):
@@ -42,7 +42,7 @@ def delete_selected(modeladmin, request, queryset):
         n = queryset.count()
         if n:
             for obj in queryset:
-                obj_display = force_unicode(obj)
+                obj_display = force_text(obj)
                 modeladmin.log_deletion(request, obj, obj_display)
             queryset.delete()
             modeladmin.message_user(request, _("Successfully deleted %(count)d %(items)s.") % {
@@ -52,9 +52,9 @@ def delete_selected(modeladmin, request, queryset):
         return None
 
     if len(queryset) == 1:
-        objects_name = force_unicode(opts.verbose_name)
+        objects_name = force_text(opts.verbose_name)
     else:
-        objects_name = force_unicode(opts.verbose_name_plural)
+        objects_name = force_text(opts.verbose_name_plural)
 
     if perms_needed or protected:
         title = _("Cannot delete %(name)s") % {"name": objects_name}
diff --git a/django/contrib/admin/filters.py b/django/contrib/admin/filters.py
index 538bf54df96..cecae216c08 100644
--- a/django/contrib/admin/filters.py
+++ b/django/contrib/admin/filters.py
@@ -9,7 +9,7 @@ import datetime
 
 from django.db import models
 from django.core.exceptions import ImproperlyConfigured
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 from django.utils import timezone
 
@@ -195,7 +195,7 @@ class RelatedFieldListFilter(FieldListFilter):
         }
         for pk_val, val in self.lookup_choices:
             yield {
-                'selected': self.lookup_val == smart_unicode(pk_val),
+                'selected': self.lookup_val == smart_text(pk_val),
                 'query_string': cl.get_query_string({
                     self.lookup_kwarg: pk_val,
                 }, [self.lookup_kwarg_isnull]),
@@ -272,7 +272,7 @@ class ChoicesFieldListFilter(FieldListFilter):
         }
         for lookup, title in self.field.flatchoices:
             yield {
-                'selected': smart_unicode(lookup) == self.lookup_val,
+                'selected': smart_text(lookup) == self.lookup_val,
                 'query_string': cl.get_query_string({
                                     self.lookup_kwarg: lookup}),
                 'display': title,
@@ -381,7 +381,7 @@ class AllValuesFieldListFilter(FieldListFilter):
             if val is None:
                 include_none = True
                 continue
-            val = smart_unicode(val)
+            val = smart_text(val)
             yield {
                 'selected': self.lookup_val == val,
                 'query_string': cl.get_query_string({
diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py
index 4fc78784f44..aeacd234a34 100644
--- a/django/contrib/admin/helpers.py
+++ b/django/contrib/admin/helpers.py
@@ -9,7 +9,7 @@ from django.core.exceptions import ObjectDoesNotExist
 from django.db.models.fields.related import ManyToManyRel
 from django.forms.util import flatatt
 from django.template.defaultfilters import capfirst
-from django.utils.encoding import force_unicode, smart_unicode
+from django.utils.encoding import force_text, smart_text
 from django.utils.html import conditional_escape, format_html
 from django.utils.safestring import mark_safe
 from django.utils import six
@@ -122,7 +122,7 @@ class AdminField(object):
 
     def label_tag(self):
         classes = []
-        contents = conditional_escape(force_unicode(self.field.label))
+        contents = conditional_escape(force_text(self.field.label))
         if self.is_checkbox:
             classes.append('vCheckboxLabel')
         else:
@@ -166,7 +166,7 @@ class AdminReadonlyField(object):
         label = self.field['label']
         return format_html('<label{0}>{1}:</label>',
                            flatatt(attrs),
-                           capfirst(force_unicode(label)))
+                           capfirst(force_text(label)))
 
     def contents(self):
         from django.contrib.admin.templatetags.admin_list import _boolean_icon
@@ -182,7 +182,7 @@ class AdminReadonlyField(object):
                 if boolean:
                     result_repr = _boolean_icon(value)
                 else:
-                    result_repr = smart_unicode(value)
+                    result_repr = smart_text(value)
                     if getattr(attr, "allow_tags", False):
                         result_repr = mark_safe(result_repr)
             else:
diff --git a/django/contrib/admin/models.py b/django/contrib/admin/models.py
index 58bbbabfdf4..e31c6d84eda 100644
--- a/django/contrib/admin/models.py
+++ b/django/contrib/admin/models.py
@@ -5,7 +5,7 @@ from django.contrib.contenttypes.models import ContentType
 from django.contrib.auth.models import User
 from django.contrib.admin.util import quote
 from django.utils.translation import ugettext_lazy as _
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 
 ADDITION = 1
 CHANGE = 2
@@ -13,7 +13,7 @@ DELETION = 3
 
 class LogEntryManager(models.Manager):
     def log_action(self, user_id, content_type_id, object_id, object_repr, action_flag, change_message=''):
-        e = self.model(None, None, user_id, content_type_id, smart_unicode(object_id), object_repr[:200], action_flag, change_message)
+        e = self.model(None, None, user_id, content_type_id, smart_text(object_id), object_repr[:200], action_flag, change_message)
         e.save()
 
 class LogEntry(models.Model):
@@ -34,7 +34,7 @@ class LogEntry(models.Model):
         ordering = ('-action_time',)
 
     def __repr__(self):
-        return smart_unicode(self.action_time)
+        return smart_text(self.action_time)
 
     def __unicode__(self):
         if self.action_flag == ADDITION:
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index ea28125a5ff..7708050e6f8 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -28,7 +28,7 @@ from django.utils import six
 from django.utils.text import capfirst, get_text_list
 from django.utils.translation import ugettext as _
 from django.utils.translation import ungettext
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 
 HORIZONTAL, VERTICAL = 1, 2
 # returns the <ul> class for a given radio_admin field
@@ -520,7 +520,7 @@ class ModelAdmin(BaseModelAdmin):
             user_id         = request.user.pk,
             content_type_id = ContentType.objects.get_for_model(object).pk,
             object_id       = object.pk,
-            object_repr     = force_unicode(object),
+            object_repr     = force_text(object),
             action_flag     = ADDITION
         )
 
@@ -535,7 +535,7 @@ class ModelAdmin(BaseModelAdmin):
             user_id         = request.user.pk,
             content_type_id = ContentType.objects.get_for_model(object).pk,
             object_id       = object.pk,
-            object_repr     = force_unicode(object),
+            object_repr     = force_text(object),
             action_flag     = CHANGE,
             change_message  = message
         )
@@ -560,7 +560,7 @@ class ModelAdmin(BaseModelAdmin):
         """
         A list_display column containing a checkbox widget.
         """
-        return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_unicode(obj.pk))
+        return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))
     action_checkbox.short_description = mark_safe('<input type="checkbox" id="action-toggle" />')
     action_checkbox.allow_tags = True
 
@@ -674,17 +674,17 @@ class ModelAdmin(BaseModelAdmin):
             for formset in formsets:
                 for added_object in formset.new_objects:
                     change_message.append(_('Added %(name)s "%(object)s".')
-                                          % {'name': force_unicode(added_object._meta.verbose_name),
-                                             'object': force_unicode(added_object)})
+                                          % {'name': force_text(added_object._meta.verbose_name),
+                                             'object': force_text(added_object)})
                 for changed_object, changed_fields in formset.changed_objects:
                     change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                           % {'list': get_text_list(changed_fields, _('and')),
-                                             'name': force_unicode(changed_object._meta.verbose_name),
-                                             'object': force_unicode(changed_object)})
+                                             'name': force_text(changed_object._meta.verbose_name),
+                                             'object': force_text(changed_object)})
                 for deleted_object in formset.deleted_objects:
                     change_message.append(_('Deleted %(name)s "%(object)s".')
-                                          % {'name': force_unicode(deleted_object._meta.verbose_name),
-                                             'object': force_unicode(deleted_object)})
+                                          % {'name': force_text(deleted_object._meta.verbose_name),
+                                             'object': force_text(deleted_object)})
         change_message = ' '.join(change_message)
         return change_message or _('No fields changed.')
 
@@ -769,7 +769,7 @@ class ModelAdmin(BaseModelAdmin):
         opts = obj._meta
         pk_value = obj._get_pk_val()
 
-        msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj)}
+        msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
         # Here, we distinguish between different save types by checking for
         # the presence of keys in request.POST.
         if "_continue" in request.POST:
@@ -782,10 +782,10 @@ class ModelAdmin(BaseModelAdmin):
             return HttpResponse(
                 '<!DOCTYPE html><html><head><title></title></head><body>'
                 '<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script></body></html>' % \
-                # escape() calls force_unicode.
+                # escape() calls force_text.
                 (escape(pk_value), escapejs(obj)))
         elif "_addanother" in request.POST:
-            self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
+            self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_text(opts.verbose_name)))
             return HttpResponseRedirect(request.path)
         else:
             self.message_user(request, msg)
@@ -819,7 +819,7 @@ class ModelAdmin(BaseModelAdmin):
 
         pk_value = obj._get_pk_val()
 
-        msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_unicode(verbose_name), 'obj': force_unicode(obj)}
+        msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_text(verbose_name), 'obj': force_text(obj)}
         if "_continue" in request.POST:
             self.message_user(request, msg + ' ' + _("You may edit it again below."))
             if "_popup" in request.REQUEST:
@@ -827,14 +827,14 @@ class ModelAdmin(BaseModelAdmin):
             else:
                 return HttpResponseRedirect(request.path)
         elif "_saveasnew" in request.POST:
-            msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(verbose_name), 'obj': obj}
+            msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_text(verbose_name), 'obj': obj}
             self.message_user(request, msg)
             return HttpResponseRedirect(reverse('admin:%s_%s_change' %
                                         (opts.app_label, module_name),
                                         args=(pk_value,),
                                         current_app=self.admin_site.name))
         elif "_addanother" in request.POST:
-            self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(verbose_name)))
+            self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_text(verbose_name)))
             return HttpResponseRedirect(reverse('admin:%s_%s_add' %
                                         (opts.app_label, module_name),
                                         current_app=self.admin_site.name))
@@ -995,7 +995,7 @@ class ModelAdmin(BaseModelAdmin):
             media = media + inline_admin_formset.media
 
         context = {
-            'title': _('Add %s') % force_unicode(opts.verbose_name),
+            'title': _('Add %s') % force_text(opts.verbose_name),
             'adminform': adminForm,
             'is_popup': "_popup" in request.REQUEST,
             'media': media,
@@ -1019,7 +1019,7 @@ class ModelAdmin(BaseModelAdmin):
             raise PermissionDenied
 
         if obj is None:
-            raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_unicode(opts.verbose_name), 'key': escape(object_id)})
+            raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)})
 
         if request.method == 'POST' and "_saveasnew" in request.POST:
             return self.add_view(request, form_url=reverse('admin:%s_%s_add' %
@@ -1085,7 +1085,7 @@ class ModelAdmin(BaseModelAdmin):
             media = media + inline_admin_formset.media
 
         context = {
-            'title': _('Change %s') % force_unicode(opts.verbose_name),
+            'title': _('Change %s') % force_text(opts.verbose_name),
             'adminform': adminForm,
             'object_id': object_id,
             'original': obj,
@@ -1194,14 +1194,14 @@ class ModelAdmin(BaseModelAdmin):
 
                 if changecount:
                     if changecount == 1:
-                        name = force_unicode(opts.verbose_name)
+                        name = force_text(opts.verbose_name)
                     else:
-                        name = force_unicode(opts.verbose_name_plural)
+                        name = force_text(opts.verbose_name_plural)
                     msg = ungettext("%(count)s %(name)s was changed successfully.",
                                     "%(count)s %(name)s were changed successfully.",
                                     changecount) % {'count': changecount,
                                                     'name': name,
-                                                    'obj': force_unicode(obj)}
+                                                    'obj': force_text(obj)}
                     self.message_user(request, msg)
 
                 return HttpResponseRedirect(request.get_full_path())
@@ -1228,7 +1228,7 @@ class ModelAdmin(BaseModelAdmin):
             'All %(total_count)s selected', cl.result_count)
 
         context = {
-            'module_name': force_unicode(opts.verbose_name_plural),
+            'module_name': force_text(opts.verbose_name_plural),
             'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)},
             'selection_note_all': selection_note_all % {'total_count': cl.result_count},
             'title': cl.title,
@@ -1263,7 +1263,7 @@ class ModelAdmin(BaseModelAdmin):
             raise PermissionDenied
 
         if obj is None:
-            raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_unicode(opts.verbose_name), 'key': escape(object_id)})
+            raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)})
 
         using = router.db_for_write(self.model)
 
@@ -1275,11 +1275,11 @@ class ModelAdmin(BaseModelAdmin):
         if request.POST: # The user has already confirmed the deletion.
             if perms_needed:
                 raise PermissionDenied
-            obj_display = force_unicode(obj)
+            obj_display = force_text(obj)
             self.log_deletion(request, obj, obj_display)
             self.delete_model(request, obj)
 
-            self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)})
+            self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_text(opts.verbose_name), 'obj': force_text(obj_display)})
 
             if not self.has_change_permission(request, None):
                 return HttpResponseRedirect(reverse('admin:index',
@@ -1288,7 +1288,7 @@ class ModelAdmin(BaseModelAdmin):
                                         (opts.app_label, opts.module_name),
                                         current_app=self.admin_site.name))
 
-        object_name = force_unicode(opts.verbose_name)
+        object_name = force_text(opts.verbose_name)
 
         if perms_needed or protected:
             title = _("Cannot delete %(name)s") % {"name": object_name}
@@ -1326,9 +1326,9 @@ class ModelAdmin(BaseModelAdmin):
         # If no history was found, see whether this object even exists.
         obj = get_object_or_404(model, pk=unquote(object_id))
         context = {
-            'title': _('Change history: %s') % force_unicode(obj),
+            'title': _('Change history: %s') % force_text(obj),
             'action_list': action_list,
-            'module_name': capfirst(force_unicode(opts.verbose_name_plural)),
+            'module_name': capfirst(force_text(opts.verbose_name_plural)),
             'object': obj,
             'app_label': app_label,
             'opts': opts,
diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py
index a16226a70e2..b8b64d032f3 100644
--- a/django/contrib/admin/templatetags/admin_list.py
+++ b/django/contrib/admin/templatetags/admin_list.py
@@ -15,7 +15,7 @@ from django.utils.safestring import mark_safe
 from django.utils import six
 from django.utils.text import capfirst
 from django.utils.translation import ugettext as _
-from django.utils.encoding import smart_unicode, force_unicode
+from django.utils.encoding import smart_text, force_text
 from django.template import Library
 from django.template.loader import get_template
 from django.template.context import Context
@@ -210,7 +210,7 @@ def items_for_result(cl, result, form):
                     result_repr = display_for_field(value, f)
                 if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)):
                     row_class = mark_safe(' class="nowrap"')
-        if force_unicode(result_repr) == '':
+        if force_text(result_repr) == '':
             result_repr = mark_safe('&nbsp;')
         # If list_display_links not defined, add the link tag to the first field
         if (first and not cl.list_display_links) or field_name in cl.list_display_links:
@@ -224,7 +224,7 @@ def items_for_result(cl, result, form):
             else:
                 attr = pk
             value = result.serializable_value(attr)
-            result_id = repr(force_unicode(value))[1:]
+            result_id = repr(force_text(value))[1:]
             yield format_html('<{0}{1}><a href="{2}"{3}>{4}</a></{5}>',
                               table_tag,
                               row_class,
@@ -241,10 +241,10 @@ def items_for_result(cl, result, form):
                     field_name == cl.model._meta.pk.name and
                         form[cl.model._meta.pk.name].is_hidden)):
                 bf = form[field_name]
-                result_repr = mark_safe(force_unicode(bf.errors) + force_unicode(bf))
+                result_repr = mark_safe(force_text(bf.errors) + force_text(bf))
             yield format_html('<td{0}>{1}</td>', row_class, result_repr)
     if form and not form[cl.model._meta.pk.name].is_hidden:
-        yield format_html('<td>{0}</td>', force_unicode(form[cl.model._meta.pk.name]))
+        yield format_html('<td>{0}</td>', force_text(form[cl.model._meta.pk.name]))
 
 class ResultList(list):
     # Wrapper class used to return items in a list_editable
@@ -267,7 +267,7 @@ def result_hidden_fields(cl):
     if cl.formset:
         for res, form in zip(cl.result_list, cl.formset.forms):
             if form[cl.model._meta.pk.name].is_hidden:
-                yield mark_safe(force_unicode(form[cl.model._meta.pk.name]))
+                yield mark_safe(force_text(form[cl.model._meta.pk.name]))
 
 @register.inclusion_tag("admin/change_list_results.html")
 def result_list(cl):
diff --git a/django/contrib/admin/util.py b/django/contrib/admin/util.py
index 16bdfe05661..ff90e1d0079 100644
--- a/django/contrib/admin/util.py
+++ b/django/contrib/admin/util.py
@@ -12,7 +12,7 @@ from django.utils import formats
 from django.utils.html import format_html
 from django.utils.text import capfirst
 from django.utils import timezone
-from django.utils.encoding import force_unicode, smart_unicode, smart_str
+from django.utils.encoding import force_text, smart_text, smart_bytes
 from django.utils import six
 from django.utils.translation import ungettext
 from django.core.urlresolvers import reverse
@@ -132,7 +132,7 @@ def get_deleted_objects(objs, opts, user, admin_site, using):
             # Don't display link to edit, because it either has no
             # admin or is edited inline.
             return '%s: %s' % (capfirst(opts.verbose_name),
-                                force_unicode(obj))
+                                force_text(obj))
 
     to_delete = collector.nested(format_callback)
 
@@ -207,8 +207,8 @@ def model_format_dict(obj):
     else:
         opts = obj
     return {
-        'verbose_name': force_unicode(opts.verbose_name),
-        'verbose_name_plural': force_unicode(opts.verbose_name_plural)
+        'verbose_name': force_text(opts.verbose_name),
+        'verbose_name_plural': force_text(opts.verbose_name_plural)
     }
 
 
@@ -274,10 +274,10 @@ def label_for_field(name, model, model_admin=None, return_attr=False):
             label = field.verbose_name
     except models.FieldDoesNotExist:
         if name == "__unicode__":
-            label = force_unicode(model._meta.verbose_name)
+            label = force_text(model._meta.verbose_name)
             attr = six.text_type
         elif name == "__str__":
-            label = smart_str(model._meta.verbose_name)
+            label = smart_bytes(model._meta.verbose_name)
             attr = bytes
         else:
             if callable(name):
@@ -311,7 +311,7 @@ def help_text_for_field(name, model):
         help_text = model._meta.get_field_by_name(name)[0].help_text
     except models.FieldDoesNotExist:
         help_text = ""
-    return smart_unicode(help_text)
+    return smart_text(help_text)
 
 
 def display_for_field(value, field):
@@ -335,7 +335,7 @@ def display_for_field(value, field):
     elif isinstance(field, models.FloatField):
         return formats.number_format(value)
     else:
-        return smart_unicode(value)
+        return smart_text(value)
 
 
 def display_for_value(value, boolean=False):
@@ -353,7 +353,7 @@ def display_for_value(value, boolean=False):
     elif isinstance(value, six.integer_types + (decimal.Decimal, float)):
         return formats.number_format(value)
     else:
-        return smart_unicode(value)
+        return smart_text(value)
 
 
 class NotRelationField(Exception):
diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py
index 85e03f3b75c..3eabf3dbebc 100644
--- a/django/contrib/admin/views/main.py
+++ b/django/contrib/admin/views/main.py
@@ -6,7 +6,7 @@ from django.core.paginator import InvalidPage
 from django.db import models
 from django.db.models.fields import FieldDoesNotExist
 from django.utils.datastructures import SortedDict
-from django.utils.encoding import force_unicode, smart_str
+from django.utils.encoding import force_text, smart_bytes
 from django.utils.translation import ugettext, ugettext_lazy
 from django.utils.http import urlencode
 
@@ -75,7 +75,7 @@ class ChangeList(object):
             title = ugettext('Select %s')
         else:
             title = ugettext('Select %s to change')
-        self.title = title % force_unicode(self.opts.verbose_name)
+        self.title = title % force_text(self.opts.verbose_name)
         self.pk_attname = self.lookup_opts.pk.attname
 
     def get_filters(self, request):
@@ -94,7 +94,7 @@ class ChangeList(object):
                 # 'key' will be used as a keyword argument later, so Python
                 # requires it to be a string.
                 del lookup_params[key]
-                lookup_params[smart_str(key)] = value
+                lookup_params[smart_bytes(key)] = value
 
             if not self.model_admin.lookup_allowed(key, value):
                 raise SuspiciousOperation("Filtering by %s not allowed" % key)
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
index 550ed0f7e2e..1e0bc2d3660 100644
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -14,7 +14,7 @@ from django.utils.html import escape, format_html, format_html_join
 from django.utils.text import Truncator
 from django.utils.translation import ugettext as _
 from django.utils.safestring import mark_safe
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils import six
 
 
@@ -96,7 +96,7 @@ class AdminRadioFieldRenderer(RadioFieldRenderer):
         return format_html('<ul{0}>\n{1}\n</ul>',
                            flatatt(self.attrs),
                            format_html_join('\n', '<li>{0}</li>',
-                                            ((force_unicode(w),) for w in self)))
+                                            ((force_text(w),) for w in self)))
 
 class AdminRadioSelect(forms.RadioSelect):
     renderer = AdminRadioFieldRenderer
@@ -197,7 +197,7 @@ class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
             # The related object is registered with the same AdminSite
             attrs['class'] = 'vManyToManyRawIdAdminField'
         if value:
-            value = ','.join([force_unicode(v) for v in value])
+            value = ','.join([force_text(v) for v in value])
         else:
             value = ''
         return super(ManyToManyRawIdWidget, self).render(name, value, attrs)
@@ -221,7 +221,7 @@ class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
         if len(initial) != len(data):
             return True
         for pk1, pk2 in zip(initial, data):
-            if force_unicode(pk1) != force_unicode(pk2):
+            if force_text(pk1) != force_text(pk2):
                 return True
         return False
 
diff --git a/django/contrib/admindocs/utils.py b/django/contrib/admindocs/utils.py
index 4bf1250ac64..0e10eb4fa3a 100644
--- a/django/contrib/admindocs/utils.py
+++ b/django/contrib/admindocs/utils.py
@@ -6,7 +6,7 @@ from email.errors import HeaderParseError
 
 from django.utils.safestring import mark_safe
 from django.core.urlresolvers import reverse
-from django.utils.encoding import smart_str
+from django.utils.encoding import smart_bytes
 try:
     import docutils.core
     import docutils.nodes
@@ -66,7 +66,7 @@ def parse_rst(text, default_reference_context, thing_being_parsed=None):
         "link_base" : reverse('django-admindocs-docroot').rstrip('/')
     }
     if thing_being_parsed:
-        thing_being_parsed = smart_str("<%s>" % thing_being_parsed)
+        thing_being_parsed = smart_bytes("<%s>" % thing_being_parsed)
     parts = docutils.core.publish_parts(text, source_path=thing_being_parsed,
                 destination_path=None, writer_name='html',
                 settings_overrides=overrides)
diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py
index 96ec40ba60f..c676cf84db1 100644
--- a/django/contrib/auth/hashers.py
+++ b/django/contrib/auth/hashers.py
@@ -7,7 +7,7 @@ from django.conf import settings
 from django.test.signals import setting_changed
 from django.utils import importlib
 from django.utils.datastructures import SortedDict
-from django.utils.encoding import smart_str
+from django.utils.encoding import smart_bytes
 from django.core.exceptions import ImproperlyConfigured
 from django.utils.crypto import (
     pbkdf2, constant_time_compare, get_random_string)
@@ -298,7 +298,7 @@ class SHA1PasswordHasher(BasePasswordHasher):
     def encode(self, password, salt):
         assert password
         assert salt and '$' not in salt
-        hash = hashlib.sha1(smart_str(salt + password)).hexdigest()
+        hash = hashlib.sha1(smart_bytes(salt + password)).hexdigest()
         return "%s$%s$%s" % (self.algorithm, salt, hash)
 
     def verify(self, password, encoded):
@@ -326,7 +326,7 @@ class MD5PasswordHasher(BasePasswordHasher):
     def encode(self, password, salt):
         assert password
         assert salt and '$' not in salt
-        hash = hashlib.md5(smart_str(salt + password)).hexdigest()
+        hash = hashlib.md5(smart_bytes(salt + password)).hexdigest()
         return "%s$%s$%s" % (self.algorithm, salt, hash)
 
     def verify(self, password, encoded):
@@ -360,7 +360,7 @@ class UnsaltedMD5PasswordHasher(BasePasswordHasher):
         return ''
 
     def encode(self, password, salt):
-        return hashlib.md5(smart_str(password)).hexdigest()
+        return hashlib.md5(smart_bytes(password)).hexdigest()
 
     def verify(self, password, encoded):
         encoded_2 = self.encode(password, '')
diff --git a/django/contrib/auth/tests/forms.py b/django/contrib/auth/tests/forms.py
index 2bfe35ac884..f917ea26016 100644
--- a/django/contrib/auth/tests/forms.py
+++ b/django/contrib/auth/tests/forms.py
@@ -8,7 +8,7 @@ from django.core import mail
 from django.forms.fields import Field, EmailField
 from django.test import TestCase
 from django.test.utils import override_settings
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils import six
 from django.utils import translation
 from django.utils.translation import ugettext as _
@@ -28,7 +28,7 @@ class UserCreationFormTest(TestCase):
         form = UserCreationForm(data)
         self.assertFalse(form.is_valid())
         self.assertEqual(form["username"].errors,
-                         [force_unicode(form.error_messages['duplicate_username'])])
+                         [force_text(form.error_messages['duplicate_username'])])
 
     def test_invalid_data(self):
         data = {
@@ -39,7 +39,7 @@ class UserCreationFormTest(TestCase):
         form = UserCreationForm(data)
         self.assertFalse(form.is_valid())
         self.assertEqual(form["username"].errors,
-                         [force_unicode(form.fields['username'].error_messages['invalid'])])
+                         [force_text(form.fields['username'].error_messages['invalid'])])
 
     def test_password_verification(self):
         # The verification password is incorrect.
@@ -51,13 +51,13 @@ class UserCreationFormTest(TestCase):
         form = UserCreationForm(data)
         self.assertFalse(form.is_valid())
         self.assertEqual(form["password2"].errors,
-                         [force_unicode(form.error_messages['password_mismatch'])])
+                         [force_text(form.error_messages['password_mismatch'])])
 
     def test_both_passwords(self):
         # One (or both) passwords weren't given
         data = {'username': 'jsmith'}
         form = UserCreationForm(data)
-        required_error = [force_unicode(Field.default_error_messages['required'])]
+        required_error = [force_text(Field.default_error_messages['required'])]
         self.assertFalse(form.is_valid())
         self.assertEqual(form['password1'].errors, required_error)
         self.assertEqual(form['password2'].errors, required_error)
@@ -96,7 +96,7 @@ class AuthenticationFormTest(TestCase):
         form = AuthenticationForm(None, data)
         self.assertFalse(form.is_valid())
         self.assertEqual(form.non_field_errors(),
-                         [force_unicode(form.error_messages['invalid_login'])])
+                         [force_text(form.error_messages['invalid_login'])])
 
     def test_inactive_user(self):
         # The user is inactive.
@@ -107,7 +107,7 @@ class AuthenticationFormTest(TestCase):
         form = AuthenticationForm(None, data)
         self.assertFalse(form.is_valid())
         self.assertEqual(form.non_field_errors(),
-                         [force_unicode(form.error_messages['inactive'])])
+                         [force_text(form.error_messages['inactive'])])
 
     def test_inactive_user_i18n(self):
         with self.settings(USE_I18N=True):
@@ -120,7 +120,7 @@ class AuthenticationFormTest(TestCase):
                 form = AuthenticationForm(None, data)
                 self.assertFalse(form.is_valid())
                 self.assertEqual(form.non_field_errors(),
-                                 [force_unicode(form.error_messages['inactive'])])
+                                 [force_text(form.error_messages['inactive'])])
 
     def test_success(self):
         # The success case
@@ -148,7 +148,7 @@ class SetPasswordFormTest(TestCase):
         form = SetPasswordForm(user, data)
         self.assertFalse(form.is_valid())
         self.assertEqual(form["new_password2"].errors,
-                         [force_unicode(form.error_messages['password_mismatch'])])
+                         [force_text(form.error_messages['password_mismatch'])])
 
     def test_success(self):
         user = User.objects.get(username='testclient')
@@ -175,7 +175,7 @@ class PasswordChangeFormTest(TestCase):
         form = PasswordChangeForm(user, data)
         self.assertFalse(form.is_valid())
         self.assertEqual(form["old_password"].errors,
-                         [force_unicode(form.error_messages['password_incorrect'])])
+                         [force_text(form.error_messages['password_incorrect'])])
 
     def test_password_verification(self):
         # The two new passwords do not match.
@@ -188,7 +188,7 @@ class PasswordChangeFormTest(TestCase):
         form = PasswordChangeForm(user, data)
         self.assertFalse(form.is_valid())
         self.assertEqual(form["new_password2"].errors,
-                         [force_unicode(form.error_messages['password_mismatch'])])
+                         [force_text(form.error_messages['password_mismatch'])])
 
     def test_success(self):
         # The success case.
@@ -219,7 +219,7 @@ class UserChangeFormTest(TestCase):
         form = UserChangeForm(data, instance=user)
         self.assertFalse(form.is_valid())
         self.assertEqual(form['username'].errors,
-                         [force_unicode(form.fields['username'].error_messages['invalid'])])
+                         [force_text(form.fields['username'].error_messages['invalid'])])
 
     def test_bug_14242(self):
         # A regression test, introduce by adding an optimization for the
@@ -274,7 +274,7 @@ class PasswordResetFormTest(TestCase):
         form = PasswordResetForm(data)
         self.assertFalse(form.is_valid())
         self.assertEqual(form['email'].errors,
-                         [force_unicode(EmailField.default_error_messages['invalid'])])
+                         [force_text(EmailField.default_error_messages['invalid'])])
 
     def test_nonexistant_email(self):
         # Test nonexistant email address
@@ -282,7 +282,7 @@ class PasswordResetFormTest(TestCase):
         form = PasswordResetForm(data)
         self.assertFalse(form.is_valid())
         self.assertEqual(form.errors,
-                         {'email': [force_unicode(form.error_messages['unknown'])]})
+                         {'email': [force_text(form.error_messages['unknown'])]})
 
     def test_cleaned_data(self):
         # Regression test
diff --git a/django/contrib/auth/tests/views.py b/django/contrib/auth/tests/views.py
index e76e7dd10f7..3c847f456a9 100644
--- a/django/contrib/auth/tests/views.py
+++ b/django/contrib/auth/tests/views.py
@@ -7,7 +7,7 @@ from django.contrib.auth.models import User
 from django.core import mail
 from django.core.urlresolvers import reverse, NoReverseMatch
 from django.http import QueryDict
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils.html import escape
 from django.utils.http import urlquote
 from django.test import TestCase
@@ -46,7 +46,7 @@ class AuthViewsTestCase(TestCase):
         self.assertTrue(SESSION_KEY in self.client.session)
 
     def assertContainsEscaped(self, response, text, **kwargs):
-        return self.assertContains(response, escape(force_unicode(text)), **kwargs)
+        return self.assertContains(response, escape(force_text(text)), **kwargs)
 
 
 class AuthViewNamedURLTests(AuthViewsTestCase):
diff --git a/django/contrib/comments/forms.py b/django/contrib/comments/forms.py
index 830e24bca93..bd254d27337 100644
--- a/django/contrib/comments/forms.py
+++ b/django/contrib/comments/forms.py
@@ -5,7 +5,7 @@ from django.conf import settings
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.comments.models import Comment
 from django.utils.crypto import salted_hmac, constant_time_compare
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils.text import get_text_list
 from django.utils import timezone
 from django.utils.translation import ungettext, ugettext, ugettext_lazy as _
@@ -133,7 +133,7 @@ class CommentDetailsForm(CommentSecurityForm):
         """
         return dict(
             content_type = ContentType.objects.get_for_model(self.target_object),
-            object_pk    = force_unicode(self.target_object._get_pk_val()),
+            object_pk    = force_text(self.target_object._get_pk_val()),
             user_name    = self.cleaned_data["name"],
             user_email   = self.cleaned_data["email"],
             user_url     = self.cleaned_data["url"],
diff --git a/django/contrib/comments/managers.py b/django/contrib/comments/managers.py
index 499feee6c3e..bc0fc5f332a 100644
--- a/django/contrib/comments/managers.py
+++ b/django/contrib/comments/managers.py
@@ -1,6 +1,6 @@
 from django.db import models
 from django.contrib.contenttypes.models import ContentType
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 
 class CommentManager(models.Manager):
 
@@ -18,5 +18,5 @@ class CommentManager(models.Manager):
         ct = ContentType.objects.get_for_model(model)
         qs = self.get_query_set().filter(content_type=ct)
         if isinstance(model, models.Model):
-            qs = qs.filter(object_pk=force_unicode(model._get_pk_val()))
+            qs = qs.filter(object_pk=force_text(model._get_pk_val()))
         return qs
diff --git a/django/contrib/comments/templatetags/comments.py b/django/contrib/comments/templatetags/comments.py
index ce1825e5293..4d4eb2322f7 100644
--- a/django/contrib/comments/templatetags/comments.py
+++ b/django/contrib/comments/templatetags/comments.py
@@ -3,7 +3,7 @@ from django.template.loader import render_to_string
 from django.conf import settings
 from django.contrib.contenttypes.models import ContentType
 from django.contrib import comments
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 
 register = template.Library()
 
@@ -75,7 +75,7 @@ class BaseCommentNode(template.Node):
 
         qs = self.comment_model.objects.filter(
             content_type = ctype,
-            object_pk    = smart_unicode(object_pk),
+            object_pk    = smart_text(object_pk),
             site__pk     = settings.SITE_ID,
         )
 
diff --git a/django/contrib/contenttypes/generic.py b/django/contrib/contenttypes/generic.py
index d5062cabf3a..29e93eefe7a 100644
--- a/django/contrib/contenttypes/generic.py
+++ b/django/contrib/contenttypes/generic.py
@@ -17,7 +17,7 @@ from django.forms import ModelForm
 from django.forms.models import BaseModelFormSet, modelformset_factory, save_instance
 from django.contrib.admin.options import InlineModelAdmin, flatten_fieldsets
 from django.contrib.contenttypes.models import ContentType
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 
 class GenericForeignKey(object):
     """
@@ -169,7 +169,7 @@ class GenericRelation(RelatedField, Field):
 
     def value_to_string(self, obj):
         qs = getattr(obj, self.name).all()
-        return smart_unicode([instance._get_pk_val() for instance in qs])
+        return smart_text([instance._get_pk_val() for instance in qs])
 
     def m2m_db_table(self):
         return self.rel.to._meta.db_table
diff --git a/django/contrib/contenttypes/management.py b/django/contrib/contenttypes/management.py
index 1b1c9c85628..11ca7e47634 100644
--- a/django/contrib/contenttypes/management.py
+++ b/django/contrib/contenttypes/management.py
@@ -1,6 +1,6 @@
 from django.contrib.contenttypes.models import ContentType
 from django.db.models import get_apps, get_models, signals
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils import six
 
 def update_contenttypes(app, created_models, verbosity=2, **kwargs):
@@ -31,7 +31,7 @@ def update_contenttypes(app, created_models, verbosity=2, **kwargs):
 
     cts = ContentType.objects.bulk_create([
         ContentType(
-            name=smart_unicode(model._meta.verbose_name_raw),
+            name=smart_text(model._meta.verbose_name_raw),
             app_label=app_label,
             model=model_name,
         )
diff --git a/django/contrib/contenttypes/models.py b/django/contrib/contenttypes/models.py
index 867351f6c8d..e6d547a4910 100644
--- a/django/contrib/contenttypes/models.py
+++ b/django/contrib/contenttypes/models.py
@@ -1,6 +1,6 @@
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
-from django.utils.encoding import smart_unicode, force_unicode
+from django.utils.encoding import smart_text, force_text
 
 class ContentTypeManager(models.Manager):
 
@@ -37,13 +37,13 @@ class ContentTypeManager(models.Manager):
         try:
             ct = self._get_from_cache(opts)
         except KeyError:
-            # Load or create the ContentType entry. The smart_unicode() is
+            # Load or create the ContentType entry. The smart_text() is
             # needed around opts.verbose_name_raw because name_raw might be a
             # django.utils.functional.__proxy__ object.
             ct, created = self.get_or_create(
                 app_label = opts.app_label,
                 model = opts.object_name.lower(),
-                defaults = {'name': smart_unicode(opts.verbose_name_raw)},
+                defaults = {'name': smart_text(opts.verbose_name_raw)},
             )
             self._add_to_cache(self.db, ct)
 
@@ -86,7 +86,7 @@ class ContentTypeManager(models.Manager):
             ct = self.create(
                 app_label=opts.app_label,
                 model=opts.object_name.lower(),
-                name=smart_unicode(opts.verbose_name_raw),
+                name=smart_text(opts.verbose_name_raw),
             )
             self._add_to_cache(self.db, ct)
             results[ct.model_class()] = ct
@@ -147,7 +147,7 @@ class ContentType(models.Model):
         if not model or self.name != model._meta.verbose_name_raw:
             return self.name
         else:
-            return force_unicode(model._meta.verbose_name)
+            return force_text(model._meta.verbose_name)
 
     def model_class(self):
         "Returns the Python model class for this type of content."
diff --git a/django/contrib/databrowse/datastructures.py b/django/contrib/databrowse/datastructures.py
index 95d347cac07..810e0398946 100644
--- a/django/contrib/databrowse/datastructures.py
+++ b/django/contrib/databrowse/datastructures.py
@@ -7,7 +7,7 @@ from __future__ import unicode_literals
 from django.db import models
 from django.utils import formats
 from django.utils.text import capfirst
-from django.utils.encoding import smart_unicode, smart_str, iri_to_uri
+from django.utils.encoding import smart_text, smart_bytes, iri_to_uri
 from django.db.models.query import QuerySet
 
 EMPTY_VALUE = '(None)'
@@ -22,7 +22,7 @@ class EasyModel(object):
         self.verbose_name_plural = model._meta.verbose_name_plural
 
     def __repr__(self):
-        return '<EasyModel for %s>' % smart_str(self.model._meta.object_name)
+        return '<EasyModel for %s>' % smart_bytes(self.model._meta.object_name)
 
     def model_databrowse(self):
         "Returns the ModelDatabrowse class for this model."
@@ -61,7 +61,7 @@ class EasyField(object):
         self.model, self.field = easy_model, field
 
     def __repr__(self):
-        return smart_str('<EasyField for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
+        return smart_bytes('<EasyField for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
 
     def choices(self):
         for value, label in self.field.choices:
@@ -79,7 +79,7 @@ class EasyChoice(object):
         self.value, self.label = value, label
 
     def __repr__(self):
-        return smart_str('<EasyChoice for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
+        return smart_bytes('<EasyChoice for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
 
     def url(self):
         return '%s%s/%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.field.name, iri_to_uri(self.value))
@@ -89,10 +89,10 @@ class EasyInstance(object):
         self.model, self.instance = easy_model, instance
 
     def __repr__(self):
-        return smart_str('<EasyInstance for %s (%s)>' % (self.model.model._meta.object_name, self.instance._get_pk_val()))
+        return smart_bytes('<EasyInstance for %s (%s)>' % (self.model.model._meta.object_name, self.instance._get_pk_val()))
 
     def __unicode__(self):
-        val = smart_unicode(self.instance)
+        val = smart_text(self.instance)
         if len(val) > DISPLAY_SIZE:
             return val[:DISPLAY_SIZE] + '...'
         return val
@@ -136,7 +136,7 @@ class EasyInstanceField(object):
         self.raw_value = getattr(instance.instance, field.name)
 
     def __repr__(self):
-        return smart_str('<EasyInstanceField for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
+        return smart_bytes('<EasyInstanceField for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
 
     def values(self):
         """
@@ -185,7 +185,7 @@ class EasyInstanceField(object):
                     if value is None:
                         continue
                     url = '%s%s/%s/objects/%s/' % (self.model.site.root_url, m.model._meta.app_label, m.model._meta.module_name, iri_to_uri(value._get_pk_val()))
-                    lst.append((smart_unicode(value), url))
+                    lst.append((smart_text(value), url))
             else:
                 lst = [(value, None) for value in self.values()]
         elif self.field.choices:
diff --git a/django/contrib/databrowse/plugins/calendars.py b/django/contrib/databrowse/plugins/calendars.py
index 923adb90f66..a548c33c8fb 100644
--- a/django/contrib/databrowse/plugins/calendars.py
+++ b/django/contrib/databrowse/plugins/calendars.py
@@ -7,7 +7,7 @@ from django.contrib.databrowse.sites import DatabrowsePlugin
 from django.shortcuts import render_to_response
 from django.utils.html import format_html, format_html_join
 from django.utils.text import capfirst
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.views.generic import dates
 from django.utils import datetime_safe
 
@@ -66,7 +66,7 @@ class CalendarPlugin(DatabrowsePlugin):
             return ''
         return format_html('<p class="filter"><strong>View calendar by:</strong> {0}</p>',
                            format_html_join(', ', '<a href="calendars/{0}/">{1}</a>',
-                                            ((f.name, force_unicode(capfirst(f.verbose_name))) for f in fields.values())))
+                                            ((f.name, force_text(capfirst(f.verbose_name))) for f in fields.values())))
 
     def urls(self, plugin_name, easy_instance_field):
         if isinstance(easy_instance_field.field, models.DateField):
diff --git a/django/contrib/databrowse/plugins/fieldchoices.py b/django/contrib/databrowse/plugins/fieldchoices.py
index 73298b8d562..dc5e9aef14b 100644
--- a/django/contrib/databrowse/plugins/fieldchoices.py
+++ b/django/contrib/databrowse/plugins/fieldchoices.py
@@ -8,7 +8,7 @@ from django.shortcuts import render_to_response
 from django.utils.html import format_html, format_html_join
 from django.utils.http import urlquote
 from django.utils.text import capfirst
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 
 
 class FieldChoicePlugin(DatabrowsePlugin):
@@ -35,7 +35,7 @@ class FieldChoicePlugin(DatabrowsePlugin):
             return ''
         return format_html('<p class="filter"><strong>View by:</strong> {0}</p>',
                            format_html_join(', ', '<a href="fields/{0}/">{1}</a>',
-                                            ((f.name, force_unicode(capfirst(f.verbose_name))) for f in fields.values())))
+                                            ((f.name, force_text(capfirst(f.verbose_name))) for f in fields.values())))
 
     def urls(self, plugin_name, easy_instance_field):
         if easy_instance_field.field in self.field_dict(easy_instance_field.model.model).values():
diff --git a/django/contrib/formtools/wizard/storage/base.py b/django/contrib/formtools/wizard/storage/base.py
index 7c802712c17..05c9f6f121b 100644
--- a/django/contrib/formtools/wizard/storage/base.py
+++ b/django/contrib/formtools/wizard/storage/base.py
@@ -1,6 +1,6 @@
 from django.core.files.uploadedfile import UploadedFile
 from django.utils.datastructures import MultiValueDict
-from django.utils.encoding import smart_str
+from django.utils.encoding import smart_bytes
 from django.utils.functional import lazy_property
 from django.utils import six
 
@@ -74,7 +74,7 @@ class BaseStorage(object):
 
         files = {}
         for field, field_dict in six.iteritems(wizard_files):
-            field_dict = dict((smart_str(k), v)
+            field_dict = dict((smart_bytes(k), v)
                               for k, v in six.iteritems(field_dict))
             tmp_name = field_dict.pop('tmp_name')
             files[field] = UploadedFile(
diff --git a/django/contrib/gis/sitemaps/views.py b/django/contrib/gis/sitemaps/views.py
index 6753b9e34a3..8bcdba1b44d 100644
--- a/django/contrib/gis/sitemaps/views.py
+++ b/django/contrib/gis/sitemaps/views.py
@@ -8,7 +8,7 @@ from django.core.paginator import EmptyPage, PageNotAnInteger
 from django.contrib.gis.db.models.fields import GeometryField
 from django.db import connections, DEFAULT_DB_ALIAS
 from django.db.models import get_model
-from django.utils.encoding import smart_str
+from django.utils.encoding import smart_bytes
 from django.utils import six
 from django.utils.translation import ugettext as _
 
@@ -61,7 +61,7 @@ def sitemap(request, sitemaps, section=None):
             raise Http404(_("Page %s empty") % page)
         except PageNotAnInteger:
             raise Http404(_("No page '%s'") % page)
-    xml = smart_str(loader.render_to_string('gis/sitemaps/geo_sitemap.xml', {'urlset': urls}))
+    xml = smart_bytes(loader.render_to_string('gis/sitemaps/geo_sitemap.xml', {'urlset': urls}))
     return HttpResponse(xml, content_type='application/xml')
 
 def kml(request, label, model, field_name=None, compress=False, using=DEFAULT_DB_ALIAS):
diff --git a/django/contrib/humanize/templatetags/humanize.py b/django/contrib/humanize/templatetags/humanize.py
index 8f6c2602c93..7e8f1631741 100644
--- a/django/contrib/humanize/templatetags/humanize.py
+++ b/django/contrib/humanize/templatetags/humanize.py
@@ -5,7 +5,7 @@ from datetime import date, datetime
 from django import template
 from django.conf import settings
 from django.template import defaultfilters
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils.formats import number_format
 from django.utils.translation import pgettext, ungettext, ugettext as _
 from django.utils.timezone import is_aware, utc
@@ -41,7 +41,7 @@ def intcomma(value, use_l10n=True):
             return intcomma(value, False)
         else:
             return number_format(value, force_grouping=True)
-    orig = force_unicode(value)
+    orig = force_text(value)
     new = re.sub("^(-?\d+)(\d{3})", '\g<1>,\g<2>', orig)
     if orig == new:
         return new
diff --git a/django/contrib/localflavor/au/forms.py b/django/contrib/localflavor/au/forms.py
index 34170fabc88..d3a00e200cd 100644
--- a/django/contrib/localflavor/au/forms.py
+++ b/django/contrib/localflavor/au/forms.py
@@ -10,7 +10,7 @@ from django.contrib.localflavor.au.au_states import STATE_CHOICES
 from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import Field, RegexField, Select
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 
 
@@ -44,7 +44,7 @@ class AUPhoneNumberField(Field):
         super(AUPhoneNumberField, self).clean(value)
         if value in EMPTY_VALUES:
             return ''
-        value = re.sub('(\(|\)|\s+|-)', '', smart_unicode(value))
+        value = re.sub('(\(|\)|\s+|-)', '', smart_text(value))
         phone_match = PHONE_DIGITS_RE.search(value)
         if phone_match:
             return '%s' % phone_match.group(1)
diff --git a/django/contrib/localflavor/br/forms.py b/django/contrib/localflavor/br/forms.py
index f287d46a9ae..4d0d6815ba9 100644
--- a/django/contrib/localflavor/br/forms.py
+++ b/django/contrib/localflavor/br/forms.py
@@ -11,7 +11,7 @@ from django.contrib.localflavor.br.br_states import STATE_CHOICES
 from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import Field, RegexField, CharField, Select
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 
 
@@ -35,7 +35,7 @@ class BRPhoneNumberField(Field):
         super(BRPhoneNumberField, self).clean(value)
         if value in EMPTY_VALUES:
             return ''
-        value = re.sub('(\(|\)|\s+)', '', smart_unicode(value))
+        value = re.sub('(\(|\)|\s+)', '', smart_text(value))
         m = phone_digits_re.search(value)
         if m:
             return '%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
@@ -68,10 +68,10 @@ class BRStateChoiceField(Field):
         value = super(BRStateChoiceField, self).clean(value)
         if value in EMPTY_VALUES:
             value = ''
-        value = smart_unicode(value)
+        value = smart_text(value)
         if value == '':
             return value
-        valid_values = set([smart_unicode(k) for k, v in self.widget.choices])
+        valid_values = set([smart_text(k) for k, v in self.widget.choices])
         if value not in valid_values:
             raise ValidationError(self.error_messages['invalid'])
         return value
diff --git a/django/contrib/localflavor/ca/forms.py b/django/contrib/localflavor/ca/forms.py
index daa40044f9c..4ebfb06c2bb 100644
--- a/django/contrib/localflavor/ca/forms.py
+++ b/django/contrib/localflavor/ca/forms.py
@@ -9,7 +9,7 @@ import re
 from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import Field, CharField, Select
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 
 
@@ -53,7 +53,7 @@ class CAPhoneNumberField(Field):
         super(CAPhoneNumberField, self).clean(value)
         if value in EMPTY_VALUES:
             return ''
-        value = re.sub('(\(|\)|\s+)', '', smart_unicode(value))
+        value = re.sub('(\(|\)|\s+)', '', smart_text(value))
         m = phone_digits_re.search(value)
         if m:
             return '%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
diff --git a/django/contrib/localflavor/ch/forms.py b/django/contrib/localflavor/ch/forms.py
index e844a3c57cf..bf71eeea322 100644
--- a/django/contrib/localflavor/ch/forms.py
+++ b/django/contrib/localflavor/ch/forms.py
@@ -10,7 +10,7 @@ from django.contrib.localflavor.ch.ch_states import STATE_CHOICES
 from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import Field, RegexField, Select
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 
 
@@ -41,7 +41,7 @@ class CHPhoneNumberField(Field):
         super(CHPhoneNumberField, self).clean(value)
         if value in EMPTY_VALUES:
             return ''
-        value = re.sub('(\.|\s|/|-)', '', smart_unicode(value))
+        value = re.sub('(\.|\s|/|-)', '', smart_text(value))
         m = phone_digits_re.search(value)
         if m:
             return '%s %s %s %s' % (value[0:3], value[3:6], value[6:8], value[8:10])
diff --git a/django/contrib/localflavor/cl/forms.py b/django/contrib/localflavor/cl/forms.py
index 59911763828..a5340141ce4 100644
--- a/django/contrib/localflavor/cl/forms.py
+++ b/django/contrib/localflavor/cl/forms.py
@@ -8,7 +8,7 @@ from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import RegexField, Select
 from django.utils.translation import ugettext_lazy as _
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 
 from .cl_regions import REGION_CHOICES
 
@@ -75,7 +75,7 @@ class CLRutField(RegexField):
         Turns the RUT into one normalized format. Returns a (rut, verifier)
         tuple.
         """
-        rut = smart_unicode(rut).replace(' ', '').replace('.', '').replace('-', '')
+        rut = smart_text(rut).replace(' ', '').replace('.', '').replace('-', '')
         return rut[:-1], rut[-1].upper()
 
     def _format(self, code, verifier=None):
diff --git a/django/contrib/localflavor/fr/forms.py b/django/contrib/localflavor/fr/forms.py
index d836dd6397b..8b841fff5fe 100644
--- a/django/contrib/localflavor/fr/forms.py
+++ b/django/contrib/localflavor/fr/forms.py
@@ -9,7 +9,7 @@ from django.contrib.localflavor.fr.fr_department import DEPARTMENT_CHOICES
 from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import CharField, RegexField, Select
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 
 
@@ -43,7 +43,7 @@ class FRPhoneNumberField(CharField):
         super(FRPhoneNumberField, self).clean(value)
         if value in EMPTY_VALUES:
             return ''
-        value = re.sub('(\.|\s)', '', smart_unicode(value))
+        value = re.sub('(\.|\s)', '', smart_text(value))
         m = phone_digits_re.search(value)
         if m:
             return '%s %s %s %s %s' % (value[0:2], value[2:4], value[4:6], value[6:8], value[8:10])
diff --git a/django/contrib/localflavor/hk/forms.py b/django/contrib/localflavor/hk/forms.py
index 8cf9360e198..ab4f70f1939 100644
--- a/django/contrib/localflavor/hk/forms.py
+++ b/django/contrib/localflavor/hk/forms.py
@@ -8,7 +8,7 @@ import re
 from django.core.validators import EMPTY_VALUES
 from django.forms import CharField
 from django.forms import ValidationError
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 
 
@@ -53,7 +53,7 @@ class HKPhoneNumberField(CharField):
         if value in EMPTY_VALUES:
             return ''
 
-        value = re.sub('(\(|\)|\s+|\+)', '', smart_unicode(value))
+        value = re.sub('(\(|\)|\s+|\+)', '', smart_text(value))
         m = hk_phone_digits_re.search(value)
         if not m:
             raise ValidationError(self.error_messages['invalid'])
diff --git a/django/contrib/localflavor/hr/forms.py b/django/contrib/localflavor/hr/forms.py
index eb4436a78c5..b935fd8a3a9 100644
--- a/django/contrib/localflavor/hr/forms.py
+++ b/django/contrib/localflavor/hr/forms.py
@@ -12,7 +12,7 @@ from django.contrib.localflavor.hr.hr_choices import (
 from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import Field, Select, RegexField
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 
 
@@ -159,7 +159,7 @@ class HRLicensePlateField(Field):
         if value in EMPTY_VALUES:
             return ''
 
-        value = re.sub(r'[\s\-]+', '', smart_unicode(value.strip())).upper()
+        value = re.sub(r'[\s\-]+', '', smart_text(value.strip())).upper()
 
         matches = plate_re.search(value)
         if matches is None:
@@ -225,7 +225,7 @@ class HRPhoneNumberField(Field):
         if value in EMPTY_VALUES:
             return ''
 
-        value = re.sub(r'[\-\s\(\)]', '', smart_unicode(value))
+        value = re.sub(r'[\-\s\(\)]', '', smart_text(value))
 
         matches = phone_re.search(value)
         if matches is None:
diff --git a/django/contrib/localflavor/id/forms.py b/django/contrib/localflavor/id/forms.py
index f22b06134e8..2005dbc75c4 100644
--- a/django/contrib/localflavor/id/forms.py
+++ b/django/contrib/localflavor/id/forms.py
@@ -11,7 +11,7 @@ from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import Field, Select
 from django.utils.translation import ugettext_lazy as _
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 
 
 postcode_re = re.compile(r'^[1-9]\d{4}$')
@@ -77,10 +77,10 @@ class IDPhoneNumberField(Field):
         if value in EMPTY_VALUES:
             return ''
 
-        phone_number = re.sub(r'[\-\s\(\)]', '', smart_unicode(value))
+        phone_number = re.sub(r'[\-\s\(\)]', '', smart_text(value))
 
         if phone_re.search(phone_number):
-            return smart_unicode(value)
+            return smart_text(value)
 
         raise ValidationError(self.error_messages['invalid'])
 
@@ -120,7 +120,7 @@ class IDLicensePlateField(Field):
             return ''
 
         plate_number = re.sub(r'\s+', ' ',
-            smart_unicode(value.strip())).upper()
+            smart_text(value.strip())).upper()
 
         matches = plate_re.search(plate_number)
         if matches is None:
@@ -181,7 +181,7 @@ class IDNationalIdentityNumberField(Field):
         if value in EMPTY_VALUES:
             return ''
 
-        value = re.sub(r'[\s.]', '', smart_unicode(value))
+        value = re.sub(r'[\s.]', '', smart_text(value))
 
         if not nik_re.search(value):
             raise ValidationError(self.error_messages['invalid'])
diff --git a/django/contrib/localflavor/in_/forms.py b/django/contrib/localflavor/in_/forms.py
index b62ec7bdb24..5c1d009ef4d 100644
--- a/django/contrib/localflavor/in_/forms.py
+++ b/django/contrib/localflavor/in_/forms.py
@@ -10,7 +10,7 @@ from django.contrib.localflavor.in_.in_states import STATES_NORMALIZED, STATE_CH
 from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import Field, RegexField, CharField, Select
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 
 
@@ -74,7 +74,7 @@ class INStateField(Field):
             pass
         else:
             try:
-                return smart_unicode(STATES_NORMALIZED[value.strip().lower()])
+                return smart_text(STATES_NORMALIZED[value.strip().lower()])
             except KeyError:
                 pass
         raise ValidationError(self.error_messages['invalid'])
@@ -107,7 +107,7 @@ class INPhoneNumberField(CharField):
         super(INPhoneNumberField, self).clean(value)
         if value in EMPTY_VALUES:
             return ''
-        value = smart_unicode(value)
+        value = smart_text(value)
         m = phone_digits_re.match(value)
         if m:
             return '%s' % (value)
diff --git a/django/contrib/localflavor/is_/forms.py b/django/contrib/localflavor/is_/forms.py
index 7af9f51cfbd..1ae3e012a10 100644
--- a/django/contrib/localflavor/is_/forms.py
+++ b/django/contrib/localflavor/is_/forms.py
@@ -9,7 +9,7 @@ from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import RegexField
 from django.forms.widgets import Select
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 
 
@@ -58,7 +58,7 @@ class ISIdNumberField(RegexField):
         Takes in the value in canonical form and returns it in the common
         display format.
         """
-        return smart_unicode(value[:6]+'-'+value[6:])
+        return smart_text(value[:6]+'-'+value[6:])
 
 class ISPhoneNumberField(RegexField):
     """
diff --git a/django/contrib/localflavor/it/forms.py b/django/contrib/localflavor/it/forms.py
index 60b1eff951e..916ce9bb3df 100644
--- a/django/contrib/localflavor/it/forms.py
+++ b/django/contrib/localflavor/it/forms.py
@@ -13,7 +13,7 @@ from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import Field, RegexField, Select
 from django.utils.translation import ugettext_lazy as _
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 
 
 class ITZipCodeField(RegexField):
@@ -85,4 +85,4 @@ class ITVatNumberField(Field):
         check_digit = vat_number_check_digit(vat_number[0:10])
         if not vat_number[10] == check_digit:
             raise ValidationError(self.error_messages['invalid'])
-        return smart_unicode(vat_number)
+        return smart_text(vat_number)
diff --git a/django/contrib/localflavor/it/util.py b/django/contrib/localflavor/it/util.py
index ec1b7e3f83a..e1aa9c04199 100644
--- a/django/contrib/localflavor/it/util.py
+++ b/django/contrib/localflavor/it/util.py
@@ -1,4 +1,4 @@
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 
 def ssn_check_digit(value):
     "Calculate Italian social security number check digit."
@@ -34,11 +34,11 @@ def ssn_check_digit(value):
 
 def vat_number_check_digit(vat_number):
     "Calculate Italian VAT number check digit."
-    normalized_vat_number = smart_unicode(vat_number).zfill(10)
+    normalized_vat_number = smart_text(vat_number).zfill(10)
     total = 0
     for i in range(0, 10, 2):
         total += int(normalized_vat_number[i])
     for i in range(1, 11, 2):
         quotient , remainder = divmod(int(normalized_vat_number[i]) * 2, 10)
         total += quotient + remainder
-    return smart_unicode((10 - total % 10) % 10)
+    return smart_text((10 - total % 10) % 10)
diff --git a/django/contrib/localflavor/nl/forms.py b/django/contrib/localflavor/nl/forms.py
index bdd769bd391..a05dd38f7f1 100644
--- a/django/contrib/localflavor/nl/forms.py
+++ b/django/contrib/localflavor/nl/forms.py
@@ -10,7 +10,7 @@ from django.contrib.localflavor.nl.nl_provinces import PROVINCE_CHOICES
 from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import Field, Select
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 
 
@@ -61,7 +61,7 @@ class NLPhoneNumberField(Field):
         if value in EMPTY_VALUES:
             return ''
 
-        phone_nr = re.sub('[\-\s\(\)]', '', smart_unicode(value))
+        phone_nr = re.sub('[\-\s\(\)]', '', smart_text(value))
 
         if len(phone_nr) == 10 and numeric_re.search(phone_nr):
             return value
diff --git a/django/contrib/localflavor/pt/forms.py b/django/contrib/localflavor/pt/forms.py
index b27fb577bd7..01cdd101b27 100644
--- a/django/contrib/localflavor/pt/forms.py
+++ b/django/contrib/localflavor/pt/forms.py
@@ -8,7 +8,7 @@ import re
 from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import Field, RegexField
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 
 phone_digits_re = re.compile(r'^(\d{9}|(00|\+)\d*)$')
@@ -29,7 +29,7 @@ class PTZipCodeField(RegexField):
            return '%s-%s' % (cleaned[:4],cleaned[4:])
         else:
            return cleaned
-        
+
 class PTPhoneNumberField(Field):
     """
     Validate local Portuguese phone number (including international ones)
@@ -43,7 +43,7 @@ class PTPhoneNumberField(Field):
         super(PTPhoneNumberField, self).clean(value)
         if value in EMPTY_VALUES:
             return ''
-        value = re.sub('(\.|\s)', '', smart_unicode(value))
+        value = re.sub('(\.|\s)', '', smart_text(value))
         m = phone_digits_re.search(value)
         if m:
             return '%s' % value
diff --git a/django/contrib/localflavor/tr/forms.py b/django/contrib/localflavor/tr/forms.py
index 15bc1f99bb0..c4f928e670b 100644
--- a/django/contrib/localflavor/tr/forms.py
+++ b/django/contrib/localflavor/tr/forms.py
@@ -10,7 +10,7 @@ from django.contrib.localflavor.tr.tr_provinces import PROVINCE_CHOICES
 from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import Field, RegexField, Select, CharField
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 
 
@@ -46,7 +46,7 @@ class TRPhoneNumberField(CharField):
         super(TRPhoneNumberField, self).clean(value)
         if value in EMPTY_VALUES:
             return ''
-        value = re.sub('(\(|\)|\s+)', '', smart_unicode(value))
+        value = re.sub('(\(|\)|\s+)', '', smart_text(value))
         m = phone_digits_re.search(value)
         if m:
             return '%s%s' % (m.group(2), m.group(4))
diff --git a/django/contrib/localflavor/us/forms.py b/django/contrib/localflavor/us/forms.py
index ef565163cd9..437bb7c466f 100644
--- a/django/contrib/localflavor/us/forms.py
+++ b/django/contrib/localflavor/us/forms.py
@@ -9,7 +9,7 @@ import re
 from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
 from django.forms.fields import Field, RegexField, Select, CharField
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 
 
@@ -34,7 +34,7 @@ class USPhoneNumberField(CharField):
         super(USPhoneNumberField, self).clean(value)
         if value in EMPTY_VALUES:
             return ''
-        value = re.sub('(\(|\)|\s+)', '', smart_unicode(value))
+        value = re.sub('(\(|\)|\s+)', '', smart_text(value))
         m = phone_digits_re.search(value)
         if m:
             return '%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
diff --git a/django/contrib/markup/templatetags/markup.py b/django/contrib/markup/templatetags/markup.py
index 84251cf30af..af9c842f423 100644
--- a/django/contrib/markup/templatetags/markup.py
+++ b/django/contrib/markup/templatetags/markup.py
@@ -13,7 +13,7 @@ markup syntaxes to HTML; currently there is support for:
 
 from django import template
 from django.conf import settings
-from django.utils.encoding import smart_str, force_unicode
+from django.utils.encoding import smart_bytes, force_text
 from django.utils.safestring import mark_safe
 
 register = template.Library()
@@ -25,9 +25,9 @@ def textile(value):
     except ImportError:
         if settings.DEBUG:
             raise template.TemplateSyntaxError("Error in 'textile' filter: The Python textile library isn't installed.")
-        return force_unicode(value)
+        return force_text(value)
     else:
-        return mark_safe(force_unicode(textile.textile(smart_str(value), encoding='utf-8', output='utf-8')))
+        return mark_safe(force_text(textile.textile(smart_bytes(value), encoding='utf-8', output='utf-8')))
 
 @register.filter(is_safe=True)
 def markdown(value, arg=''):
@@ -52,23 +52,23 @@ def markdown(value, arg=''):
     except ImportError:
         if settings.DEBUG:
             raise template.TemplateSyntaxError("Error in 'markdown' filter: The Python markdown library isn't installed.")
-        return force_unicode(value)
+        return force_text(value)
     else:
         markdown_vers = getattr(markdown, "version_info", 0)
         if markdown_vers < (2, 1):
             if settings.DEBUG:
                 raise template.TemplateSyntaxError(
                     "Error in 'markdown' filter: Django does not support versions of the Python markdown library < 2.1.")
-            return force_unicode(value)
+            return force_text(value)
         else:
             extensions = [e for e in arg.split(",") if e]
             if extensions and extensions[0] == "safe":
                 extensions = extensions[1:]
                 return mark_safe(markdown.markdown(
-                    force_unicode(value), extensions, safe_mode=True, enable_attributes=False))
+                    force_text(value), extensions, safe_mode=True, enable_attributes=False))
             else:
                 return mark_safe(markdown.markdown(
-                    force_unicode(value), extensions, safe_mode=False))
+                    force_text(value), extensions, safe_mode=False))
 
 @register.filter(is_safe=True)
 def restructuredtext(value):
@@ -77,8 +77,8 @@ def restructuredtext(value):
     except ImportError:
         if settings.DEBUG:
             raise template.TemplateSyntaxError("Error in 'restructuredtext' filter: The Python docutils library isn't installed.")
-        return force_unicode(value)
+        return force_text(value)
     else:
         docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {})
-        parts = publish_parts(source=smart_str(value), writer_name="html4css1", settings_overrides=docutils_settings)
-        return mark_safe(force_unicode(parts["fragment"]))
+        parts = publish_parts(source=smart_bytes(value), writer_name="html4css1", settings_overrides=docutils_settings)
+        return mark_safe(force_text(parts["fragment"]))
diff --git a/django/contrib/messages/storage/base.py b/django/contrib/messages/storage/base.py
index e80818e84e7..5433bbff28e 100644
--- a/django/contrib/messages/storage/base.py
+++ b/django/contrib/messages/storage/base.py
@@ -1,7 +1,7 @@
 from __future__ import unicode_literals
 
 from django.conf import settings
-from django.utils.encoding import force_unicode, StrAndUnicode
+from django.utils.encoding import force_text, StrAndUnicode
 from django.contrib.messages import constants, utils
 
 
@@ -26,22 +26,22 @@ class Message(StrAndUnicode):
         and ``extra_tags`` to unicode in case they are lazy translations.
 
         Known "safe" types (None, int, etc.) are not converted (see Django's
-        ``force_unicode`` implementation for details).
+        ``force_text`` implementation for details).
         """
-        self.message = force_unicode(self.message, strings_only=True)
-        self.extra_tags = force_unicode(self.extra_tags, strings_only=True)
+        self.message = force_text(self.message, strings_only=True)
+        self.extra_tags = force_text(self.extra_tags, strings_only=True)
 
     def __eq__(self, other):
         return isinstance(other, Message) and self.level == other.level and \
                                               self.message == other.message
 
     def __unicode__(self):
-        return force_unicode(self.message)
+        return force_text(self.message)
 
     def _get_tags(self):
-        label_tag = force_unicode(LEVEL_TAGS.get(self.level, ''),
+        label_tag = force_text(LEVEL_TAGS.get(self.level, ''),
                                   strings_only=True)
-        extra_tags = force_unicode(self.extra_tags, strings_only=True)
+        extra_tags = force_text(self.extra_tags, strings_only=True)
         if extra_tags and label_tag:
             return ' '.join([extra_tags, label_tag])
         elif extra_tags:
diff --git a/django/contrib/sessions/backends/db.py b/django/contrib/sessions/backends/db.py
index 3dd0d9516c7..0cc17b44c31 100644
--- a/django/contrib/sessions/backends/db.py
+++ b/django/contrib/sessions/backends/db.py
@@ -1,7 +1,7 @@
 from django.contrib.sessions.backends.base import SessionBase, CreateError
 from django.core.exceptions import SuspiciousOperation
 from django.db import IntegrityError, transaction, router
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils import timezone
 
 
@@ -18,7 +18,7 @@ class SessionStore(SessionBase):
                 session_key = self.session_key,
                 expire_date__gt=timezone.now()
             )
-            return self.decode(force_unicode(s.session_data))
+            return self.decode(force_text(s.session_data))
         except (Session.DoesNotExist, SuspiciousOperation):
             self.create()
             return {}
diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py
index d3977213a9b..45c5ecfe1fd 100644
--- a/django/contrib/staticfiles/management/commands/collectstatic.py
+++ b/django/contrib/staticfiles/management/commands/collectstatic.py
@@ -6,7 +6,7 @@ from optparse import make_option
 
 from django.core.files.storage import FileSystemStorage
 from django.core.management.base import CommandError, NoArgsCommand
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.datastructures import SortedDict
 
 from django.contrib.staticfiles import finders, storage
@@ -198,9 +198,9 @@ Type 'yes' to continue, or 'no' to cancel: """
             fpath = os.path.join(path, f)
             if self.dry_run:
                 self.log("Pretending to delete '%s'" %
-                         smart_unicode(fpath), level=1)
+                         smart_text(fpath), level=1)
             else:
-                self.log("Deleting '%s'" % smart_unicode(fpath), level=1)
+                self.log("Deleting '%s'" % smart_text(fpath), level=1)
                 self.storage.delete(fpath)
         for d in dirs:
             self.clear_dir(os.path.join(path, d))
diff --git a/django/contrib/staticfiles/management/commands/findstatic.py b/django/contrib/staticfiles/management/commands/findstatic.py
index 772220b3427..dc1e88d7780 100644
--- a/django/contrib/staticfiles/management/commands/findstatic.py
+++ b/django/contrib/staticfiles/management/commands/findstatic.py
@@ -3,7 +3,7 @@ from __future__ import unicode_literals
 import os
 from optparse import make_option
 from django.core.management.base import LabelCommand
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 
 from django.contrib.staticfiles import finders
 
@@ -19,12 +19,12 @@ class Command(LabelCommand):
     def handle_label(self, path, **options):
         verbosity = int(options.get('verbosity', 1))
         result = finders.find(path, all=options['all'])
-        path = smart_unicode(path)
+        path = smart_text(path)
         if result:
             if not isinstance(result, (list, tuple)):
                 result = [result]
             output = '\n  '.join(
-                (smart_unicode(os.path.realpath(path)) for path in result))
+                (smart_text(os.path.realpath(path)) for path in result))
             self.stdout.write("Found '%s' here:\n  %s" % (path, output))
         else:
             if verbosity >= 1:
diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py
index a0133e1c6a8..2ca54dde71f 100644
--- a/django/contrib/staticfiles/storage.py
+++ b/django/contrib/staticfiles/storage.py
@@ -16,7 +16,7 @@ from django.core.exceptions import ImproperlyConfigured
 from django.core.files.base import ContentFile
 from django.core.files.storage import FileSystemStorage, get_storage_class
 from django.utils.datastructures import SortedDict
-from django.utils.encoding import force_unicode, smart_str
+from django.utils.encoding import force_text, smart_bytes
 from django.utils.functional import LazyObject
 from django.utils.importlib import import_module
 
@@ -112,7 +112,7 @@ class CachedFilesMixin(object):
         return urlunsplit(unparsed_name)
 
     def cache_key(self, name):
-        return 'staticfiles:%s' % hashlib.md5(smart_str(name)).hexdigest()
+        return 'staticfiles:%s' % hashlib.md5(smart_bytes(name)).hexdigest()
 
     def url(self, name, force=False):
         """
@@ -248,9 +248,9 @@ class CachedFilesMixin(object):
                     if hashed_file_exists:
                         self.delete(hashed_name)
                     # then save the processed result
-                    content_file = ContentFile(smart_str(content))
+                    content_file = ContentFile(smart_bytes(content))
                     saved_name = self._save(hashed_name, content_file)
-                    hashed_name = force_unicode(saved_name.replace('\\', '/'))
+                    hashed_name = force_text(saved_name.replace('\\', '/'))
                     processed = True
                 else:
                     # or handle the case in which neither processing nor
@@ -258,7 +258,7 @@ class CachedFilesMixin(object):
                     if not hashed_file_exists:
                         processed = True
                         saved_name = self._save(hashed_name, original_file)
-                        hashed_name = force_unicode(saved_name.replace('\\', '/'))
+                        hashed_name = force_text(saved_name.replace('\\', '/'))
 
                 # and then set the cache accordingly
                 hashed_paths[self.cache_key(name)] = hashed_name
diff --git a/django/contrib/syndication/views.py b/django/contrib/syndication/views.py
index 3c84f1f60c7..bce7ef7cfb8 100644
--- a/django/contrib/syndication/views.py
+++ b/django/contrib/syndication/views.py
@@ -6,7 +6,7 @@ from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
 from django.http import HttpResponse, Http404
 from django.template import loader, TemplateDoesNotExist, RequestContext
 from django.utils import feedgenerator, tzinfo
-from django.utils.encoding import force_unicode, iri_to_uri, smart_unicode
+from django.utils.encoding import force_text, iri_to_uri, smart_text
 from django.utils.html import escape
 from django.utils.timezone import is_naive
 
@@ -43,10 +43,10 @@ class Feed(object):
 
     def item_title(self, item):
         # Titles should be double escaped by default (see #6533)
-        return escape(force_unicode(item))
+        return escape(force_text(item))
 
     def item_description(self, item):
-        return force_unicode(item)
+        return force_text(item)
 
     def item_link(self, item):
         try:
@@ -154,9 +154,9 @@ class Feed(object):
             enc_url = self.__get_dynamic_attr('item_enclosure_url', item)
             if enc_url:
                 enc = feedgenerator.Enclosure(
-                    url = smart_unicode(enc_url),
-                    length = smart_unicode(self.__get_dynamic_attr('item_enclosure_length', item)),
-                    mime_type = smart_unicode(self.__get_dynamic_attr('item_enclosure_mime_type', item))
+                    url = smart_text(enc_url),
+                    length = smart_text(self.__get_dynamic_attr('item_enclosure_length', item)),
+                    mime_type = smart_text(self.__get_dynamic_attr('item_enclosure_mime_type', item))
                 )
             author_name = self.__get_dynamic_attr('item_author_name', item)
             if author_name is not None:
diff --git a/django/core/cache/backends/base.py b/django/core/cache/backends/base.py
index f7573b2e315..d527e44d8b3 100644
--- a/django/core/cache/backends/base.py
+++ b/django/core/cache/backends/base.py
@@ -3,7 +3,7 @@
 import warnings
 
 from django.core.exceptions import ImproperlyConfigured, DjangoRuntimeWarning
-from django.utils.encoding import smart_str
+from django.utils.encoding import smart_bytes
 from django.utils.importlib import import_module
 
 class InvalidCacheBackendError(ImproperlyConfigured):
@@ -23,7 +23,7 @@ def default_key_func(key, key_prefix, version):
     the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
     function with custom key making behavior.
     """
-    return ':'.join([key_prefix, str(version), smart_str(key)])
+    return ':'.join([key_prefix, str(version), smart_bytes(key)])
 
 def get_key_func(key_func):
     """
@@ -62,7 +62,7 @@ class BaseCache(object):
         except (ValueError, TypeError):
             self._cull_frequency = 3
 
-        self.key_prefix = smart_str(params.get('KEY_PREFIX', ''))
+        self.key_prefix = smart_bytes(params.get('KEY_PREFIX', ''))
         self.version = params.get('VERSION', 1)
         self.key_func = get_key_func(params.get('KEY_FUNCTION', None))
 
diff --git a/django/core/context_processors.py b/django/core/context_processors.py
index 325f64d224e..a503270cf4a 100644
--- a/django/core/context_processors.py
+++ b/django/core/context_processors.py
@@ -9,7 +9,7 @@ RequestContext.
 
 from django.conf import settings
 from django.middleware.csrf import get_token
-from django.utils.encoding import smart_str
+from django.utils.encoding import smart_bytes
 from django.utils.functional import lazy
 
 def csrf(request):
@@ -25,7 +25,7 @@ def csrf(request):
             # instead of returning an empty dict.
             return b'NOTPROVIDED'
         else:
-            return smart_str(token)
+            return smart_bytes(token)
     _get_val = lazy(_get_val, str)
 
     return {'csrf_token': _get_val() }
diff --git a/django/core/exceptions.py b/django/core/exceptions.py
index e3d1dc9c7e1..f0f14cffda3 100644
--- a/django/core/exceptions.py
+++ b/django/core/exceptions.py
@@ -43,7 +43,7 @@ class ValidationError(Exception):
     """An error while validating data."""
     def __init__(self, message, code=None, params=None):
         import operator
-        from django.utils.encoding import force_unicode
+        from django.utils.encoding import force_text
         """
         ValidationError can be passed any object that can be printed (usually
         a string), a list of objects or a dictionary.
@@ -54,11 +54,11 @@ class ValidationError(Exception):
             message = reduce(operator.add, message.values())
 
         if isinstance(message, list):
-            self.messages = [force_unicode(msg) for msg in message]
+            self.messages = [force_text(msg) for msg in message]
         else:
             self.code = code
             self.params = params
-            message = force_unicode(message)
+            message = force_text(message)
             self.messages = [message]
 
     def __str__(self):
diff --git a/django/core/files/base.py b/django/core/files/base.py
index 04853fad0c3..37b1be89b36 100644
--- a/django/core/files/base.py
+++ b/django/core/files/base.py
@@ -3,7 +3,7 @@ from __future__ import unicode_literals
 import os
 from io import BytesIO
 
-from django.utils.encoding import smart_str, smart_unicode
+from django.utils.encoding import smart_bytes, smart_text
 from django.core.files.utils import FileProxyMixin
 
 class File(FileProxyMixin):
@@ -18,10 +18,10 @@ class File(FileProxyMixin):
             self.mode = file.mode
 
     def __str__(self):
-        return smart_str(self.name or '')
+        return smart_bytes(self.name or '')
 
     def __unicode__(self):
-        return smart_unicode(self.name or '')
+        return smart_text(self.name or '')
 
     def __repr__(self):
         return "<%s: %s>" % (self.__class__.__name__, self or "None")
diff --git a/django/core/files/storage.py b/django/core/files/storage.py
index 51799805131..7542dcda46d 100644
--- a/django/core/files/storage.py
+++ b/django/core/files/storage.py
@@ -11,7 +11,7 @@ from django.conf import settings
 from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
 from django.core.files import locks, File
 from django.core.files.move import file_move_safe
-from django.utils.encoding import force_unicode, filepath_to_uri
+from django.utils.encoding import force_text, filepath_to_uri
 from django.utils.functional import LazyObject
 from django.utils.importlib import import_module
 from django.utils.text import get_valid_filename
@@ -48,7 +48,7 @@ class Storage(object):
         name = self._save(name, content)
 
         # Store filenames with forward slashes, even on Windows
-        return force_unicode(name.replace('\\', '/'))
+        return force_text(name.replace('\\', '/'))
 
     # These methods are part of the public API, with default implementations.
 
diff --git a/django/core/files/uploadedfile.py b/django/core/files/uploadedfile.py
index 97d53482e4c..3a6c6329759 100644
--- a/django/core/files/uploadedfile.py
+++ b/django/core/files/uploadedfile.py
@@ -8,7 +8,7 @@ from io import BytesIO
 from django.conf import settings
 from django.core.files.base import File
 from django.core.files import temp as tempfile
-from django.utils.encoding import smart_str
+from django.utils.encoding import smart_bytes
 
 __all__ = ('UploadedFile', 'TemporaryUploadedFile', 'InMemoryUploadedFile',
            'SimpleUploadedFile')
@@ -30,7 +30,7 @@ class UploadedFile(File):
         self.charset = charset
 
     def __repr__(self):
-        return smart_str("<%s: %s (%s)>" % (
+        return smart_bytes("<%s: %s (%s)>" % (
             self.__class__.__name__, self.name, self.content_type))
 
     def _get_name(self):
diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py
index 7fd7d19c4a8..5a6825f0a79 100644
--- a/django/core/handlers/base.py
+++ b/django/core/handlers/base.py
@@ -4,7 +4,7 @@ import sys
 
 from django import http
 from django.core import signals
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils.importlib import import_module
 from django.utils.log import getLogger
 from django.utils import six
@@ -250,7 +250,7 @@ def get_script_name(environ):
     """
     from django.conf import settings
     if settings.FORCE_SCRIPT_NAME is not None:
-        return force_unicode(settings.FORCE_SCRIPT_NAME)
+        return force_text(settings.FORCE_SCRIPT_NAME)
 
     # If Apache's mod_rewrite had a whack at the URL, Apache set either
     # SCRIPT_URL or REDIRECT_URL to the full resource URL before applying any
@@ -261,5 +261,5 @@ def get_script_name(environ):
     if not script_url:
         script_url = environ.get('REDIRECT_URL', '')
     if script_url:
-        return force_unicode(script_url[:-len(environ.get('PATH_INFO', ''))])
-    return force_unicode(environ.get('SCRIPT_NAME', ''))
+        return force_text(script_url[:-len(environ.get('PATH_INFO', ''))])
+    return force_text(environ.get('SCRIPT_NAME', ''))
diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py
index 51ad2be002a..70b23f85154 100644
--- a/django/core/handlers/wsgi.py
+++ b/django/core/handlers/wsgi.py
@@ -9,7 +9,7 @@ from django.core import signals
 from django.core.handlers import base
 from django.core.urlresolvers import set_script_prefix
 from django.utils import datastructures
-from django.utils.encoding import force_unicode, smart_str, iri_to_uri
+from django.utils.encoding import force_text, smart_bytes, iri_to_uri
 from django.utils.log import getLogger
 
 logger = getLogger('django.request')
@@ -127,7 +127,7 @@ class LimitedStream(object):
 class WSGIRequest(http.HttpRequest):
     def __init__(self, environ):
         script_name = base.get_script_name(environ)
-        path_info = force_unicode(environ.get('PATH_INFO', '/'))
+        path_info = force_text(environ.get('PATH_INFO', '/'))
         if not path_info or path_info == script_name:
             # Sometimes PATH_INFO exists, but is empty (e.g. accessing
             # the SCRIPT_NAME URL without a trailing slash). We really need to
@@ -246,5 +246,5 @@ class WSGIHandler(base.BaseHandler):
         response_headers = [(str(k), str(v)) for k, v in response.items()]
         for c in response.cookies.values():
             response_headers.append((str('Set-Cookie'), str(c.output(header=''))))
-        start_response(smart_str(status), response_headers)
+        start_response(smart_bytes(status), response_headers)
         return response
diff --git a/django/core/mail/message.py b/django/core/mail/message.py
index 629ad464f91..8f589ae33da 100644
--- a/django/core/mail/message.py
+++ b/django/core/mail/message.py
@@ -15,7 +15,7 @@ from io import BytesIO
 
 from django.conf import settings
 from django.core.mail.utils import DNS_NAME
-from django.utils.encoding import smart_str, force_unicode
+from django.utils.encoding import smart_bytes, force_text
 from django.utils import six
 
 
@@ -79,7 +79,7 @@ ADDRESS_HEADERS = set([
 def forbid_multi_line_headers(name, val, encoding):
     """Forbids multi-line headers, to prevent header injection."""
     encoding = encoding or settings.DEFAULT_CHARSET
-    val = force_unicode(val)
+    val = force_text(val)
     if '\n' in val or '\r' in val:
         raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name))
     try:
@@ -93,12 +93,12 @@ def forbid_multi_line_headers(name, val, encoding):
     else:
         if name.lower() == 'subject':
             val = Header(val)
-    return smart_str(name), val
+    return smart_bytes(name), val
 
 
 def sanitize_address(addr, encoding):
     if isinstance(addr, six.string_types):
-        addr = parseaddr(force_unicode(addr))
+        addr = parseaddr(force_text(addr))
     nm, addr = addr
     nm = str(Header(nm, encoding))
     try:
@@ -210,7 +210,7 @@ class EmailMessage(object):
 
     def message(self):
         encoding = self.encoding or settings.DEFAULT_CHARSET
-        msg = SafeMIMEText(smart_str(self.body, encoding),
+        msg = SafeMIMEText(smart_bytes(self.body, encoding),
                            self.content_subtype, encoding)
         msg = self._create_message(msg)
         msg['Subject'] = self.subject
@@ -293,7 +293,7 @@ class EmailMessage(object):
         basetype, subtype = mimetype.split('/', 1)
         if basetype == 'text':
             encoding = self.encoding or settings.DEFAULT_CHARSET
-            attachment = SafeMIMEText(smart_str(content, encoding), subtype, encoding)
+            attachment = SafeMIMEText(smart_bytes(content, encoding), subtype, encoding)
         else:
             # Encode non-text attachments with base64.
             attachment = MIMEBase(basetype, subtype)
diff --git a/django/core/management/commands/createcachetable.py b/django/core/management/commands/createcachetable.py
index fd6dbbbd2c5..411042ee764 100644
--- a/django/core/management/commands/createcachetable.py
+++ b/django/core/management/commands/createcachetable.py
@@ -4,7 +4,7 @@ from django.core.cache.backends.db import BaseDatabaseCache
 from django.core.management.base import LabelCommand, CommandError
 from django.db import connections, router, transaction, models, DEFAULT_DB_ALIAS
 from django.db.utils import DatabaseError
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 
 
 class Command(LabelCommand):
@@ -60,7 +60,7 @@ class Command(LabelCommand):
             transaction.rollback_unless_managed(using=db)
             raise CommandError(
                 "Cache table '%s' could not be created.\nThe error was: %s." %
-                    (tablename, force_unicode(e)))
+                    (tablename, force_text(e)))
         for statement in index_output:
             curs.execute(statement)
         transaction.commit_unless_managed(using=db)
diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py
index 34f8041d338..1896e53cee7 100644
--- a/django/core/management/commands/loaddata.py
+++ b/django/core/management/commands/loaddata.py
@@ -14,7 +14,7 @@ from django.core.management.color import no_style
 from django.db import (connections, router, transaction, DEFAULT_DB_ALIAS,
       IntegrityError, DatabaseError)
 from django.db.models import get_apps
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from itertools import product
 
 try:
@@ -189,7 +189,7 @@ class Command(BaseCommand):
                                                         'app_label': obj.object._meta.app_label,
                                                         'object_name': obj.object._meta.object_name,
                                                         'pk': obj.object.pk,
-                                                        'error_msg': force_unicode(e)
+                                                        'error_msg': force_text(e)
                                                     },)
                                                 raise
 
diff --git a/django/core/serializers/base.py b/django/core/serializers/base.py
index 19886f7d53c..78a01c70983 100644
--- a/django/core/serializers/base.py
+++ b/django/core/serializers/base.py
@@ -5,7 +5,7 @@ Module for abstract serializer/unserializer base classes.
 from io import BytesIO
 
 from django.db import models
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils import six
 
 class SerializerDoesNotExist(KeyError):
diff --git a/django/core/serializers/json.py b/django/core/serializers/json.py
index 8b56d0e7b89..3bac24d33ad 100644
--- a/django/core/serializers/json.py
+++ b/django/core/serializers/json.py
@@ -12,7 +12,7 @@ import json
 from django.core.serializers.base import DeserializationError
 from django.core.serializers.python import Serializer as PythonSerializer
 from django.core.serializers.python import Deserializer as PythonDeserializer
-from django.utils.encoding import smart_str
+from django.utils.encoding import smart_bytes
 from django.utils import six
 from django.utils.timezone import is_aware
 
diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py
index 83c6eb67392..348ff1dada4 100644
--- a/django/core/serializers/python.py
+++ b/django/core/serializers/python.py
@@ -8,7 +8,7 @@ from __future__ import unicode_literals
 from django.conf import settings
 from django.core.serializers import base
 from django.db import models, DEFAULT_DB_ALIAS
-from django.utils.encoding import smart_unicode, is_protected_type
+from django.utils.encoding import smart_text, is_protected_type
 from django.utils import six
 
 class Serializer(base.Serializer):
@@ -34,8 +34,8 @@ class Serializer(base.Serializer):
 
     def get_dump_object(self, obj):
         return {
-            "pk": smart_unicode(obj._get_pk_val(), strings_only=True),
-            "model": smart_unicode(obj._meta),
+            "pk": smart_text(obj._get_pk_val(), strings_only=True),
+            "model": smart_text(obj._meta),
             "fields": self._current
         }
 
@@ -65,7 +65,7 @@ class Serializer(base.Serializer):
             if self.use_natural_keys and hasattr(field.rel.to, 'natural_key'):
                 m2m_value = lambda value: value.natural_key()
             else:
-                m2m_value = lambda value: smart_unicode(value._get_pk_val(), strings_only=True)
+                m2m_value = lambda value: smart_text(value._get_pk_val(), strings_only=True)
             self._current[field.name] = [m2m_value(related)
                                for related in getattr(obj, field.name).iterator()]
 
@@ -90,7 +90,7 @@ def Deserializer(object_list, **options):
         # Handle each field
         for (field_name, field_value) in six.iteritems(d["fields"]):
             if isinstance(field_value, str):
-                field_value = smart_unicode(field_value, options.get("encoding", settings.DEFAULT_CHARSET), strings_only=True)
+                field_value = smart_text(field_value, options.get("encoding", settings.DEFAULT_CHARSET), strings_only=True)
 
             field = Model._meta.get_field(field_name)
 
@@ -101,9 +101,9 @@ def Deserializer(object_list, **options):
                         if hasattr(value, '__iter__'):
                             return field.rel.to._default_manager.db_manager(db).get_by_natural_key(*value).pk
                         else:
-                            return smart_unicode(field.rel.to._meta.pk.to_python(value))
+                            return smart_text(field.rel.to._meta.pk.to_python(value))
                 else:
-                    m2m_convert = lambda v: smart_unicode(field.rel.to._meta.pk.to_python(v))
+                    m2m_convert = lambda v: smart_text(field.rel.to._meta.pk.to_python(v))
                 m2m_data[field.name] = [m2m_convert(pk) for pk in field_value]
 
             # Handle FK fields
diff --git a/django/core/serializers/pyyaml.py b/django/core/serializers/pyyaml.py
index ac0e6cf82d1..9be1ea44925 100644
--- a/django/core/serializers/pyyaml.py
+++ b/django/core/serializers/pyyaml.py
@@ -12,7 +12,7 @@ from django.db import models
 from django.core.serializers.base import DeserializationError
 from django.core.serializers.python import Serializer as PythonSerializer
 from django.core.serializers.python import Deserializer as PythonDeserializer
-from django.utils.encoding import smart_str
+from django.utils.encoding import smart_bytes
 from django.utils import six
 
 
diff --git a/django/core/serializers/xml_serializer.py b/django/core/serializers/xml_serializer.py
index 9d9c023b647..c4e4dd189ec 100644
--- a/django/core/serializers/xml_serializer.py
+++ b/django/core/serializers/xml_serializer.py
@@ -8,7 +8,7 @@ from django.conf import settings
 from django.core.serializers import base
 from django.db import models, DEFAULT_DB_ALIAS
 from django.utils.xmlutils import SimplerXMLGenerator
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from xml.dom import pulldom
 
 class Serializer(base.Serializer):
@@ -46,11 +46,11 @@ class Serializer(base.Serializer):
         self.indent(1)
         obj_pk = obj._get_pk_val()
         if obj_pk is None:
-            attrs = {"model": smart_unicode(obj._meta),}
+            attrs = {"model": smart_text(obj._meta),}
         else:
             attrs = {
-                "pk": smart_unicode(obj._get_pk_val()),
-                "model": smart_unicode(obj._meta),
+                "pk": smart_text(obj._get_pk_val()),
+                "model": smart_text(obj._meta),
             }
 
         self.xml.startElement("object", attrs)
@@ -96,10 +96,10 @@ class Serializer(base.Serializer):
                 # Iterable natural keys are rolled out as subelements
                 for key_value in related:
                     self.xml.startElement("natural", {})
-                    self.xml.characters(smart_unicode(key_value))
+                    self.xml.characters(smart_text(key_value))
                     self.xml.endElement("natural")
             else:
-                self.xml.characters(smart_unicode(related_att))
+                self.xml.characters(smart_text(related_att))
         else:
             self.xml.addQuickElement("None")
         self.xml.endElement("field")
@@ -120,13 +120,13 @@ class Serializer(base.Serializer):
                     self.xml.startElement("object", {})
                     for key_value in natural:
                         self.xml.startElement("natural", {})
-                        self.xml.characters(smart_unicode(key_value))
+                        self.xml.characters(smart_text(key_value))
                         self.xml.endElement("natural")
                     self.xml.endElement("object")
             else:
                 def handle_m2m(value):
                     self.xml.addQuickElement("object", attrs={
-                        'pk' : smart_unicode(value._get_pk_val())
+                        'pk' : smart_text(value._get_pk_val())
                     })
             for relobj in getattr(obj, field.name).iterator():
                 handle_m2m(relobj)
@@ -141,7 +141,7 @@ class Serializer(base.Serializer):
         self.xml.startElement("field", {
             "name" : field.name,
             "rel"  : field.rel.__class__.__name__,
-            "to"   : smart_unicode(field.rel.to._meta),
+            "to"   : smart_text(field.rel.to._meta),
         })
 
 class Deserializer(base.Deserializer):
diff --git a/django/core/signing.py b/django/core/signing.py
index cd9759e536c..9ab8c5b8b0d 100644
--- a/django/core/signing.py
+++ b/django/core/signing.py
@@ -41,7 +41,7 @@ from django.conf import settings
 from django.core.exceptions import ImproperlyConfigured
 from django.utils import baseconv
 from django.utils.crypto import constant_time_compare, salted_hmac
-from django.utils.encoding import force_unicode, smart_str
+from django.utils.encoding import force_text, smart_bytes
 from django.utils.importlib import import_module
 
 
@@ -135,7 +135,7 @@ def loads(s, key=None, salt='django.core.signing', serializer=JSONSerializer, ma
     """
     Reverse of dumps(), raises BadSignature if signature fails
     """
-    base64d = smart_str(
+    base64d = smart_bytes(
         TimestampSigner(key, salt=salt).unsign(s, max_age=max_age))
     decompress = False
     if base64d[0] == '.':
@@ -159,16 +159,16 @@ class Signer(object):
         return base64_hmac(self.salt + 'signer', value, self.key)
 
     def sign(self, value):
-        value = smart_str(value)
+        value = smart_bytes(value)
         return '%s%s%s' % (value, self.sep, self.signature(value))
 
     def unsign(self, signed_value):
-        signed_value = smart_str(signed_value)
+        signed_value = smart_bytes(signed_value)
         if not self.sep in signed_value:
             raise BadSignature('No "%s" found in value' % self.sep)
         value, sig = signed_value.rsplit(self.sep, 1)
         if constant_time_compare(sig, self.signature(value)):
-            return force_unicode(value)
+            return force_text(value)
         raise BadSignature('Signature "%s" does not match' % sig)
 
 
@@ -178,7 +178,7 @@ class TimestampSigner(Signer):
         return baseconv.base62.encode(int(time.time()))
 
     def sign(self, value):
-        value = smart_str('%s%s%s' % (value, self.sep, self.timestamp()))
+        value = smart_bytes('%s%s%s' % (value, self.sep, self.timestamp()))
         return '%s%s%s' % (value, self.sep, self.signature(value))
 
     def unsign(self, value, max_age=None):
diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py
index c17168f8cb4..2fe744e8eb4 100644
--- a/django/core/urlresolvers.py
+++ b/django/core/urlresolvers.py
@@ -14,7 +14,7 @@ from threading import local
 from django.http import Http404
 from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
 from django.utils.datastructures import MultiValueDict
-from django.utils.encoding import iri_to_uri, force_unicode, smart_str
+from django.utils.encoding import iri_to_uri, force_text, smart_bytes
 from django.utils.functional import memoize, lazy
 from django.utils.importlib import import_module
 from django.utils.module_loading import module_has_submodule
@@ -163,7 +163,7 @@ class LocaleRegexProvider(object):
             if isinstance(self._regex, six.string_types):
                 regex = self._regex
             else:
-                regex = force_unicode(self._regex)
+                regex = force_text(self._regex)
             try:
                 compiled_regex = re.compile(regex, re.UNICODE)
             except re.error as e:
@@ -190,7 +190,7 @@ class RegexURLPattern(LocaleRegexProvider):
         self.name = name
 
     def __repr__(self):
-        return smart_str('<%s %s %s>' % (self.__class__.__name__, self.name, self.regex.pattern))
+        return smart_bytes('<%s %s %s>' % (self.__class__.__name__, self.name, self.regex.pattern))
 
     def add_prefix(self, prefix):
         """
@@ -240,7 +240,7 @@ class RegexURLResolver(LocaleRegexProvider):
         self._app_dict = {}
 
     def __repr__(self):
-        return smart_str('<%s %s (%s:%s) %s>' % (self.__class__.__name__, self.urlconf_name, self.app_name, self.namespace, self.regex.pattern))
+        return smart_bytes('<%s %s (%s:%s) %s>' % (self.__class__.__name__, self.urlconf_name, self.app_name, self.namespace, self.regex.pattern))
 
     def _populate(self):
         lookups = MultiValueDict()
@@ -373,7 +373,7 @@ class RegexURLResolver(LocaleRegexProvider):
                 if args:
                     if len(args) != len(params) + len(prefix_args):
                         continue
-                    unicode_args = [force_unicode(val) for val in args]
+                    unicode_args = [force_text(val) for val in args]
                     candidate =  (prefix_norm + result) % dict(zip(prefix_args + params, unicode_args))
                 else:
                     if set(kwargs.keys()) | set(defaults.keys()) != set(params) | set(defaults.keys()) | set(prefix_args):
@@ -385,7 +385,7 @@ class RegexURLResolver(LocaleRegexProvider):
                             break
                     if not matches:
                         continue
-                    unicode_kwargs = dict([(k, force_unicode(v)) for (k, v) in kwargs.items()])
+                    unicode_kwargs = dict([(k, force_text(v)) for (k, v) in kwargs.items()])
                     candidate = (prefix_norm + result) % unicode_kwargs
                 if re.search('^%s%s' % (_prefix, pattern), candidate, re.UNICODE):
                     return candidate
diff --git a/django/core/validators.py b/django/core/validators.py
index 91d6f62dcfb..fd5dfa28d6d 100644
--- a/django/core/validators.py
+++ b/django/core/validators.py
@@ -8,7 +8,7 @@ except ImportError:     # Python 2
 
 from django.core.exceptions import ValidationError
 from django.utils.translation import ugettext_lazy as _
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.ipv6 import is_valid_ipv6_address
 from django.utils import six
 
@@ -36,7 +36,7 @@ class RegexValidator(object):
         """
         Validates that the input matches the regular expression.
         """
-        if not self.regex.search(smart_unicode(value)):
+        if not self.regex.search(smart_text(value)):
             raise ValidationError(self.message, code=self.code)
 
 class URLValidator(RegexValidator):
@@ -54,7 +54,7 @@ class URLValidator(RegexValidator):
         except ValidationError as e:
             # Trivial case failed. Try for possible IDN domain
             if value:
-                value = smart_unicode(value)
+                value = smart_text(value)
                 scheme, netloc, path, query, fragment = urlsplit(value)
                 try:
                     netloc = netloc.encode('idna') # IDN -> ACE
diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index 6e23ad5bb52..96062451620 100644
--- a/django/db/backends/__init__.py
+++ b/django/db/backends/__init__.py
@@ -607,16 +607,16 @@ class BaseDatabaseOperations(object):
         exists for database backends to provide a better implementation
         according to their own quoting schemes.
         """
-        from django.utils.encoding import smart_unicode, force_unicode
+        from django.utils.encoding import smart_text, force_text
 
         # Convert params to contain Unicode values.
-        to_unicode = lambda s: force_unicode(s, strings_only=True, errors='replace')
+        to_unicode = lambda s: force_text(s, strings_only=True, errors='replace')
         if isinstance(params, (list, tuple)):
             u_params = tuple([to_unicode(val) for val in params])
         else:
             u_params = dict([(to_unicode(k), to_unicode(v)) for k, v in params.items()])
 
-        return smart_unicode(sql) % u_params
+        return smart_text(sql) % u_params
 
     def last_insert_id(self, cursor, table_name, pk_name):
         """
@@ -800,8 +800,8 @@ class BaseDatabaseOperations(object):
 
     def prep_for_like_query(self, x):
         """Prepares a value for use in a LIKE query."""
-        from django.utils.encoding import smart_unicode
-        return smart_unicode(x).replace("\\", "\\\\").replace("%", "\%").replace("_", "\_")
+        from django.utils.encoding import smart_text
+        return smart_text(x).replace("\\", "\\\\").replace("%", "\%").replace("_", "\_")
 
     # Same as prep_for_like_query(), but called for "iexact" matches, which
     # need not necessarily be implemented using "LIKE" in the backend.
diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index b08113fed76..0f161304778 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -53,7 +53,7 @@ from django.db.backends.signals import connection_created
 from django.db.backends.oracle.client import DatabaseClient
 from django.db.backends.oracle.creation import DatabaseCreation
 from django.db.backends.oracle.introspection import DatabaseIntrospection
-from django.utils.encoding import smart_str, force_unicode
+from django.utils.encoding import smart_bytes, force_text
 from django.utils import six
 from django.utils import timezone
 
@@ -64,9 +64,9 @@ IntegrityError = Database.IntegrityError
 # Check whether cx_Oracle was compiled with the WITH_UNICODE option.  This will
 # also be True in Python 3.0.
 if int(Database.version.split('.', 1)[0]) >= 5 and not hasattr(Database, 'UNICODE'):
-    convert_unicode = force_unicode
+    convert_unicode = force_text
 else:
-    convert_unicode = smart_str
+    convert_unicode = smart_bytes
 
 
 class DatabaseFeatures(BaseDatabaseFeatures):
@@ -162,7 +162,7 @@ WHEN (new.%(col_name)s IS NULL)
         if isinstance(value, Database.LOB):
             value = value.read()
             if field and field.get_internal_type() == 'TextField':
-                value = force_unicode(value)
+                value = force_text(value)
 
         # Oracle stores empty strings as null. We need to undo this in
         # order to adhere to the Django convention of using the empty
@@ -245,7 +245,7 @@ WHEN (new.%(col_name)s IS NULL)
     def process_clob(self, value):
         if value is None:
             return ''
-        return force_unicode(value.read())
+        return force_text(value.read())
 
     def quote_name(self, name):
         # SQL92 requires delimited (quoted) names to be case-sensitive.  When
@@ -595,9 +595,9 @@ class OracleParam(object):
             param = param.astimezone(timezone.utc).replace(tzinfo=None)
 
         if hasattr(param, 'bind_parameter'):
-            self.smart_str = param.bind_parameter(cursor)
+            self.smart_bytes = param.bind_parameter(cursor)
         else:
-            self.smart_str = convert_unicode(param, cursor.charset,
+            self.smart_bytes = convert_unicode(param, cursor.charset,
                                              strings_only)
         if hasattr(param, 'input_size'):
             # If parameter has `input_size` attribute, use that.
@@ -676,7 +676,7 @@ class FormatStylePlaceholderCursor(object):
         self.setinputsizes(*sizes)
 
     def _param_generator(self, params):
-        return [p.smart_str for p in params]
+        return [p.smart_bytes for p in params]
 
     def execute(self, query, params=None):
         if params is None:
@@ -831,7 +831,7 @@ def to_unicode(s):
     unchanged).
     """
     if isinstance(s, six.string_types):
-        return force_unicode(s)
+        return force_text(s)
     return s
 
 
diff --git a/django/db/models/base.py b/django/db/models/base.py
index a25c1062900..4568430bfaf 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -23,7 +23,7 @@ from django.db.models import signals
 from django.db.models.loading import register_models, get_model
 from django.utils.translation import ugettext_lazy as _
 from django.utils.functional import curry
-from django.utils.encoding import smart_str, force_unicode
+from django.utils.encoding import smart_bytes, force_text
 from django.utils import six
 from django.utils.text import get_text_list, capfirst
 
@@ -380,11 +380,11 @@ class Model(six.with_metaclass(ModelBase, object)):
             u = six.text_type(self)
         except (UnicodeEncodeError, UnicodeDecodeError):
             u = '[Bad Unicode data]'
-        return smart_str('<%s: %s>' % (self.__class__.__name__, u))
+        return smart_bytes('<%s: %s>' % (self.__class__.__name__, u))
 
     def __str__(self):
         if hasattr(self, '__unicode__'):
-            return force_unicode(self).encode('utf-8')
+            return force_text(self).encode('utf-8')
         return '%s object' % self.__class__.__name__
 
     def __eq__(self, other):
@@ -605,14 +605,14 @@ class Model(six.with_metaclass(ModelBase, object)):
 
     def _get_FIELD_display(self, field):
         value = getattr(self, field.attname)
-        return force_unicode(dict(field.flatchoices).get(value, value), strings_only=True)
+        return force_text(dict(field.flatchoices).get(value, value), strings_only=True)
 
     def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs):
         if not self.pk:
             raise ValueError("get_next/get_previous cannot be used on unsaved objects.")
         op = is_next and 'gt' or 'lt'
         order = not is_next and '-' or ''
-        param = smart_str(getattr(self, field.attname))
+        param = smart_bytes(getattr(self, field.attname))
         q = Q(**{'%s__%s' % (field.name, op): param})
         q = q|Q(**{field.name: param, 'pk__%s' % op: self.pk})
         qs = self.__class__._default_manager.using(self._state.db).filter(**kwargs).filter(q).order_by('%s%s' % (order, field.name), '%spk' % order)
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index de24a24ed13..2c738d6a20f 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -19,7 +19,7 @@ from django.utils.functional import curry, total_ordering
 from django.utils.text import capfirst
 from django.utils import timezone
 from django.utils.translation import ugettext_lazy as _
-from django.utils.encoding import smart_unicode, force_unicode
+from django.utils.encoding import smart_text, force_text
 from django.utils.ipv6 import clean_ipv6_address
 from django.utils import six
 
@@ -386,7 +386,7 @@ class Field(object):
         if self.has_default():
             if callable(self.default):
                 return self.default()
-            return force_unicode(self.default, strings_only=True)
+            return force_text(self.default, strings_only=True)
         if (not self.empty_strings_allowed or (self.null and
                    not connection.features.interprets_empty_strings_as_nulls)):
             return None
@@ -404,11 +404,11 @@ class Field(object):
         rel_model = self.rel.to
         if hasattr(self.rel, 'get_related_field'):
             lst = [(getattr(x, self.rel.get_related_field().attname),
-                        smart_unicode(x))
+                        smart_text(x))
                    for x in rel_model._default_manager.complex_filter(
                        self.rel.limit_choices_to)]
         else:
-            lst = [(x._get_pk_val(), smart_unicode(x))
+            lst = [(x._get_pk_val(), smart_text(x))
                    for x in rel_model._default_manager.complex_filter(
                        self.rel.limit_choices_to)]
         return first_choice + lst
@@ -435,7 +435,7 @@ class Field(object):
         Returns a string value of this field from the passed obj.
         This is used by the serialization framework.
         """
-        return smart_unicode(self._get_val_from_obj(obj))
+        return smart_text(self._get_val_from_obj(obj))
 
     def bind(self, fieldmapping, original, bound_field_class):
         return bound_field_class(self, fieldmapping, original)
@@ -629,7 +629,7 @@ class CharField(Field):
     def to_python(self, value):
         if isinstance(value, six.string_types) or value is None:
             return value
-        return smart_unicode(value)
+        return smart_text(value)
 
     def get_prep_value(self, value):
         return self.to_python(value)
@@ -1189,7 +1189,7 @@ class TextField(Field):
     def get_prep_value(self, value):
         if isinstance(value, six.string_types) or value is None:
             return value
-        return smart_unicode(value)
+        return smart_text(value)
 
     def formfield(self, **kwargs):
         defaults = {'widget': forms.Textarea}
diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py
index b51ef1d5d61..ad4c36ca0d1 100644
--- a/django/db/models/fields/files.py
+++ b/django/db/models/fields/files.py
@@ -8,7 +8,7 @@ from django.core.files.base import File
 from django.core.files.storage import default_storage
 from django.core.files.images import ImageFile
 from django.db.models import signals
-from django.utils.encoding import force_unicode, smart_str
+from django.utils.encoding import force_text, smart_bytes
 from django.utils import six
 from django.utils.translation import ugettext_lazy as _
 
@@ -280,7 +280,7 @@ class FileField(Field):
         setattr(cls, self.name, self.descriptor_class(self))
 
     def get_directory_name(self):
-        return os.path.normpath(force_unicode(datetime.datetime.now().strftime(smart_str(self.upload_to))))
+        return os.path.normpath(force_text(datetime.datetime.now().strftime(smart_bytes(self.upload_to))))
 
     def get_filename(self, filename):
         return os.path.normpath(self.storage.get_valid_name(os.path.basename(filename)))
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index bfa8feee9fa..eaa62c60613 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -9,7 +9,7 @@ from django.db.models.related import RelatedObject
 from django.db.models.query import QuerySet
 from django.db.models.query_utils import QueryWrapper
 from django.db.models.deletion import CASCADE
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils import six
 from django.utils.translation import ugettext_lazy as _, string_concat
 from django.utils.functional import curry, cached_property
@@ -999,7 +999,7 @@ class ForeignKey(RelatedField, Field):
             if not self.blank and self.choices:
                 choice_list = self.get_choices_default()
                 if len(choice_list) == 2:
-                    return smart_unicode(choice_list[1][0])
+                    return smart_text(choice_list[1][0])
         return Field.value_to_string(self, obj)
 
     def contribute_to_class(self, cls, name):
@@ -1205,7 +1205,7 @@ class ManyToManyField(RelatedField, Field):
                 choices_list = self.get_choices_default()
                 if len(choices_list) == 1:
                     data = [choices_list[0][0]]
-        return smart_unicode(data)
+        return smart_text(data)
 
     def contribute_to_class(self, cls, name):
         # To support multiple relations to self, it's useful to have a non-None
diff --git a/django/db/models/options.py b/django/db/models/options.py
index 9e8d4120e9f..239ad30b069 100644
--- a/django/db/models/options.py
+++ b/django/db/models/options.py
@@ -8,7 +8,7 @@ from django.db.models.fields import AutoField, FieldDoesNotExist
 from django.db.models.fields.proxy import OrderWrt
 from django.db.models.loading import get_models, app_cache_ready
 from django.utils.translation import activate, deactivate_all, get_language, string_concat
-from django.utils.encoding import force_unicode, smart_str
+from django.utils.encoding import force_text, smart_bytes
 from django.utils.datastructures import SortedDict
 from django.utils import six
 
@@ -199,7 +199,7 @@ class Options(object):
         return '<Options for %s>' % self.object_name
 
     def __str__(self):
-        return "%s.%s" % (smart_str(self.app_label), smart_str(self.module_name))
+        return "%s.%s" % (smart_bytes(self.app_label), smart_bytes(self.module_name))
 
     def verbose_name_raw(self):
         """
@@ -209,7 +209,7 @@ class Options(object):
         """
         lang = get_language()
         deactivate_all()
-        raw = force_unicode(self.verbose_name)
+        raw = force_text(self.verbose_name)
         activate(lang)
         return raw
     verbose_name_raw = property(verbose_name_raw)
diff --git a/django/db/models/related.py b/django/db/models/related.py
index 90995d749f5..a0dcec71328 100644
--- a/django/db/models/related.py
+++ b/django/db/models/related.py
@@ -1,4 +1,4 @@
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.db.models.fields import BLANK_CHOICE_DASH
 
 class BoundRelatedObject(object):
@@ -34,9 +34,9 @@ class RelatedObject(object):
         if limit_to_currently_related:
             queryset = queryset.complex_filter(
                 {'%s__isnull' % self.parent_model._meta.module_name: False})
-        lst = [(x._get_pk_val(), smart_unicode(x)) for x in queryset]
+        lst = [(x._get_pk_val(), smart_text(x)) for x in queryset]
         return first_choice + lst
-        
+
     def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False):
         # Defer to the actual field definition for db prep
         return self.field.get_db_prep_lookup(lookup_type, value,
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 9cf732f2632..69dda228bd7 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -10,7 +10,7 @@ all about the internals of models in order to get the information it needs.
 import copy
 
 from django.utils.datastructures import SortedDict
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils.tree import Node
 from django.utils import six
 from django.db import connections, DEFAULT_DB_ALIAS
@@ -1776,7 +1776,7 @@ class Query(object):
             else:
                 param_iter = iter([])
             for name, entry in select.items():
-                entry = force_unicode(entry)
+                entry = force_text(entry)
                 entry_params = []
                 pos = entry.find("%s")
                 while pos != -1:
diff --git a/django/db/models/sql/subqueries.py b/django/db/models/sql/subqueries.py
index cc7da0eeaf4..937505b9b0f 100644
--- a/django/db/models/sql/subqueries.py
+++ b/django/db/models/sql/subqueries.py
@@ -10,7 +10,7 @@ from django.db.models.sql.query import Query
 from django.db.models.sql.where import AND, Constraint
 from django.utils.datastructures import SortedDict
 from django.utils.functional import Promise
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils import six
 
 
@@ -105,7 +105,7 @@ class UpdateQuery(Query):
         saving models.
         """
         # Check that no Promise object passes to the query. Refs #10498.
-        values_seq = [(value[0], value[1], force_unicode(value[2]))
+        values_seq = [(value[0], value[1], force_text(value[2]))
                       if isinstance(value[2], Promise) else value
                       for value in values_seq]
         self.values.extend(values_seq)
@@ -171,7 +171,7 @@ class InsertQuery(Query):
             for obj in objs:
                 value = getattr(obj, field.attname)
                 if isinstance(value, Promise):
-                    setattr(obj, field.attname, force_unicode(value))
+                    setattr(obj, field.attname, force_text(value))
         self.objs = objs
         self.raw = raw
 
diff --git a/django/forms/fields.py b/django/forms/fields.py
index cdb1d7be676..7f0d26d1aa7 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -23,7 +23,7 @@ from django.forms.widgets import (TextInput, PasswordInput, HiddenInput,
     NullBooleanSelect, SelectMultiple, DateInput, DateTimeInput, TimeInput,
     SplitDateTimeWidget, SplitHiddenDateTimeWidget, FILE_INPUT_CONTRADICTION)
 from django.utils import formats
-from django.utils.encoding import smart_unicode, force_unicode
+from django.utils.encoding import smart_text, force_text
 from django.utils.ipv6 import clean_ipv6_address
 from django.utils import six
 from django.utils.translation import ugettext_lazy as _
@@ -78,13 +78,13 @@ class Field(object):
         # validators -- List of addtional validators to use
         # localize -- Boolean that specifies if the field should be localized.
         if label is not None:
-            label = smart_unicode(label)
+            label = smart_text(label)
         self.required, self.label, self.initial = required, label, initial
         self.show_hidden_initial = show_hidden_initial
         if help_text is None:
             self.help_text = ''
         else:
-            self.help_text = smart_unicode(help_text)
+            self.help_text = smart_text(help_text)
         widget = widget or self.widget
         if isinstance(widget, type):
             widget = widget()
@@ -195,7 +195,7 @@ class CharField(Field):
         "Returns a Unicode object."
         if value in validators.EMPTY_VALUES:
             return ''
-        return smart_unicode(value)
+        return smart_text(value)
 
     def widget_attrs(self, widget):
         attrs = super(CharField, self).widget_attrs(widget)
@@ -288,7 +288,7 @@ class DecimalField(Field):
             return None
         if self.localize:
             value = formats.sanitize_separators(value)
-        value = smart_unicode(value).strip()
+        value = smart_text(value).strip()
         try:
             value = Decimal(value)
         except DecimalException:
@@ -333,7 +333,7 @@ class BaseTemporalField(Field):
 
     def to_python(self, value):
         # Try to coerce the value to unicode.
-        unicode_value = force_unicode(value, strings_only=True)
+        unicode_value = force_text(value, strings_only=True)
         if isinstance(unicode_value, six.text_type):
             value = unicode_value.strip()
         # If unicode, try to strptime against each input format.
@@ -692,7 +692,7 @@ class ChoiceField(Field):
         "Returns a Unicode object."
         if value in validators.EMPTY_VALUES:
             return ''
-        return smart_unicode(value)
+        return smart_text(value)
 
     def validate(self, value):
         """
@@ -708,10 +708,10 @@ class ChoiceField(Field):
             if isinstance(v, (list, tuple)):
                 # This is an optgroup, so look inside the group for options
                 for k2, v2 in v:
-                    if value == smart_unicode(k2):
+                    if value == smart_text(k2):
                         return True
             else:
-                if value == smart_unicode(k):
+                if value == smart_text(k):
                     return True
         return False
 
@@ -752,7 +752,7 @@ class MultipleChoiceField(ChoiceField):
             return []
         elif not isinstance(value, (list, tuple)):
             raise ValidationError(self.error_messages['invalid_list'])
-        return [smart_unicode(val) for val in value]
+        return [smart_text(val) for val in value]
 
     def validate(self, value):
         """
diff --git a/django/forms/forms.py b/django/forms/forms.py
index 0f3fdb2e407..45b758202a1 100644
--- a/django/forms/forms.py
+++ b/django/forms/forms.py
@@ -12,7 +12,7 @@ from django.forms.util import flatatt, ErrorDict, ErrorList
 from django.forms.widgets import Media, media_property, TextInput, Textarea
 from django.utils.datastructures import SortedDict
 from django.utils.html import conditional_escape, format_html
-from django.utils.encoding import StrAndUnicode, smart_unicode, force_unicode
+from django.utils.encoding import StrAndUnicode, smart_text, force_text
 from django.utils.safestring import mark_safe
 from django.utils import six
 
@@ -150,7 +150,7 @@ class BaseForm(StrAndUnicode):
             bf_errors = self.error_class([conditional_escape(error) for error in bf.errors]) # Escape and cache in local variable.
             if bf.is_hidden:
                 if bf_errors:
-                    top_errors.extend(['(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors])
+                    top_errors.extend(['(Hidden field %s) %s' % (name, force_text(e)) for e in bf_errors])
                 hidden_fields.append(six.text_type(bf))
             else:
                 # Create a 'class="..."' atribute if the row should have any
@@ -160,10 +160,10 @@ class BaseForm(StrAndUnicode):
                     html_class_attr = ' class="%s"' % css_classes
 
                 if errors_on_separate_row and bf_errors:
-                    output.append(error_row % force_unicode(bf_errors))
+                    output.append(error_row % force_text(bf_errors))
 
                 if bf.label:
-                    label = conditional_escape(force_unicode(bf.label))
+                    label = conditional_escape(force_text(bf.label))
                     # Only add the suffix if the label does not end in
                     # punctuation.
                     if self.label_suffix:
@@ -174,20 +174,20 @@ class BaseForm(StrAndUnicode):
                     label = ''
 
                 if field.help_text:
-                    help_text = help_text_html % force_unicode(field.help_text)
+                    help_text = help_text_html % force_text(field.help_text)
                 else:
                     help_text = ''
 
                 output.append(normal_row % {
-                    'errors': force_unicode(bf_errors),
-                    'label': force_unicode(label),
+                    'errors': force_text(bf_errors),
+                    'label': force_text(label),
                     'field': six.text_type(bf),
                     'help_text': help_text,
                     'html_class_attr': html_class_attr
                 })
 
         if top_errors:
-            output.insert(0, error_row % force_unicode(top_errors))
+            output.insert(0, error_row % force_text(top_errors))
 
         if hidden_fields: # Insert any hidden fields in the last row.
             str_hidden = ''.join(hidden_fields)
@@ -535,8 +535,8 @@ class BoundField(StrAndUnicode):
         associated Form has specified auto_id. Returns an empty string otherwise.
         """
         auto_id = self.form.auto_id
-        if auto_id and '%s' in smart_unicode(auto_id):
-            return smart_unicode(auto_id) % self.html_name
+        if auto_id and '%s' in smart_text(auto_id):
+            return smart_text(auto_id) % self.html_name
         elif auto_id:
             return self.html_name
         return ''
diff --git a/django/forms/models.py b/django/forms/models.py
index a2b5448b14e..80d2a6536fc 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -13,7 +13,7 @@ from django.forms.formsets import BaseFormSet, formset_factory
 from django.forms.util import ErrorList
 from django.forms.widgets import (SelectMultiple, HiddenInput,
     MultipleHiddenInput, media_property)
-from django.utils.encoding import smart_unicode, force_unicode
+from django.utils.encoding import smart_text, force_text
 from django.utils.datastructures import SortedDict
 from django.utils import six
 from django.utils.text import get_text_list, capfirst
@@ -875,7 +875,7 @@ class InlineForeignKeyField(Field):
             orig = getattr(self.parent_instance, self.to_field)
         else:
             orig = self.parent_instance.pk
-        if force_unicode(value) != force_unicode(orig):
+        if force_text(value) != force_text(orig):
             raise ValidationError(self.error_messages['invalid_choice'])
         return self.parent_instance
 
@@ -953,7 +953,7 @@ class ModelChoiceField(ChoiceField):
         generate the labels for the choices presented by this object. Subclasses
         can override this method to customize the display of the choices.
         """
-        return smart_unicode(obj)
+        return smart_text(obj)
 
     def _get_choices(self):
         # If self._choices is set, then somebody must have manually set
@@ -1025,9 +1025,9 @@ class ModelMultipleChoiceField(ModelChoiceField):
             except ValueError:
                 raise ValidationError(self.error_messages['invalid_pk_value'] % pk)
         qs = self.queryset.filter(**{'%s__in' % key: value})
-        pks = set([force_unicode(getattr(o, key)) for o in qs])
+        pks = set([force_text(getattr(o, key)) for o in qs])
         for val in value:
-            if force_unicode(val) not in pks:
+            if force_text(val) not in pks:
                 raise ValidationError(self.error_messages['invalid_choice'] % val)
         # Since this overrides the inherited ModelChoiceField.clean
         # we run custom validators here
diff --git a/django/forms/util.py b/django/forms/util.py
index 8cf03d38aff..cd6b52df6fb 100644
--- a/django/forms/util.py
+++ b/django/forms/util.py
@@ -2,7 +2,7 @@ from __future__ import unicode_literals
 
 from django.conf import settings
 from django.utils.html import format_html, format_html_join
-from django.utils.encoding import StrAndUnicode, force_unicode
+from django.utils.encoding import StrAndUnicode, force_text
 from django.utils.safestring import mark_safe
 from django.utils import timezone
 from django.utils.translation import ugettext_lazy as _
@@ -35,12 +35,12 @@ class ErrorDict(dict, StrAndUnicode):
         if not self: return ''
         return format_html('<ul class="errorlist">{0}</ul>',
                            format_html_join('', '<li>{0}{1}</li>',
-                                            ((k, force_unicode(v))
+                                            ((k, force_text(v))
                                              for k, v in self.items())
                            ))
 
     def as_text(self):
-        return '\n'.join(['* %s\n%s' % (k, '\n'.join(['  * %s' % force_unicode(i) for i in v])) for k, v in self.items()])
+        return '\n'.join(['* %s\n%s' % (k, '\n'.join(['  * %s' % force_text(i) for i in v])) for k, v in self.items()])
 
 class ErrorList(list, StrAndUnicode):
     """
@@ -53,16 +53,16 @@ class ErrorList(list, StrAndUnicode):
         if not self: return ''
         return format_html('<ul class="errorlist">{0}</ul>',
                            format_html_join('', '<li>{0}</li>',
-                                            ((force_unicode(e),) for e in self)
+                                            ((force_text(e),) for e in self)
                                             )
                            )
 
     def as_text(self):
         if not self: return ''
-        return '\n'.join(['* %s' % force_unicode(e) for e in self])
+        return '\n'.join(['* %s' % force_text(e) for e in self])
 
     def __repr__(self):
-        return repr([force_unicode(e) for e in self])
+        return repr([force_text(e) for e in self])
 
 # Utilities for time zone support in DateTimeField et al.
 
diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index 13b7d8e7f6a..be9ac8eb8f9 100644
--- a/django/forms/widgets.py
+++ b/django/forms/widgets.py
@@ -17,7 +17,7 @@ from django.forms.util import flatatt, to_current_timezone
 from django.utils.datastructures import MultiValueDict, MergeDict
 from django.utils.html import conditional_escape, format_html, format_html_join
 from django.utils.translation import ugettext, ugettext_lazy
-from django.utils.encoding import StrAndUnicode, force_unicode
+from django.utils.encoding import StrAndUnicode, force_text
 from django.utils.safestring import mark_safe
 from django.utils import six
 from django.utils import datetime_safe, formats
@@ -223,7 +223,7 @@ class Widget(six.with_metaclass(MediaDefiningClass)):
             initial_value = ''
         else:
             initial_value = initial
-        if force_unicode(initial_value) != force_unicode(data_value):
+        if force_text(initial_value) != force_text(data_value):
             return True
         return False
 
@@ -257,7 +257,7 @@ class Input(Widget):
         final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
         if value != '':
             # Only add the 'value' attribute if a value is non-empty.
-            final_attrs['value'] = force_unicode(self._format_value(value))
+            final_attrs['value'] = force_text(self._format_value(value))
         return format_html('<input{0} />', flatatt(final_attrs))
 
 class TextInput(Input):
@@ -294,7 +294,7 @@ class MultipleHiddenInput(HiddenInput):
         id_ = final_attrs.get('id', None)
         inputs = []
         for i, v in enumerate(value):
-            input_attrs = dict(value=force_unicode(v), **final_attrs)
+            input_attrs = dict(value=force_text(v), **final_attrs)
             if id_:
                 # An ID attribute was given. Add a numeric index as a suffix
                 # so that the inputs don't all have the same ID attribute.
@@ -361,7 +361,7 @@ class ClearableFileInput(FileInput):
             template = self.template_with_initial
             substitutions['initial'] = format_html('<a href="{0}">{1}</a>',
                                                    value.url,
-                                                   force_unicode(value))
+                                                   force_text(value))
             if not self.is_required:
                 checkbox_name = self.clear_checkbox_name(name)
                 checkbox_id = self.clear_checkbox_id(checkbox_name)
@@ -398,7 +398,7 @@ class Textarea(Widget):
         final_attrs = self.build_attrs(attrs, name=name)
         return format_html('<textarea{0}>{1}</textarea>',
                            flatatt(final_attrs),
-                           force_unicode(value))
+                           force_text(value))
 
 class DateInput(Input):
     input_type = 'text'
@@ -515,7 +515,7 @@ class CheckboxInput(Widget):
             final_attrs['checked'] = 'checked'
         if not (value is True or value is False or value is None or value == ''):
             # Only add the 'value' attribute if a value is non-empty.
-            final_attrs['value'] = force_unicode(value)
+            final_attrs['value'] = force_text(value)
         return format_html('<input{0} />', flatatt(final_attrs))
 
     def value_from_datadict(self, data, files, name):
@@ -556,7 +556,7 @@ class Select(Widget):
         return mark_safe('\n'.join(output))
 
     def render_option(self, selected_choices, option_value, option_label):
-        option_value = force_unicode(option_value)
+        option_value = force_text(option_value)
         if option_value in selected_choices:
             selected_html = mark_safe(' selected="selected"')
             if not self.allow_multiple_selected:
@@ -567,15 +567,15 @@ class Select(Widget):
         return format_html('<option value="{0}"{1}>{2}</option>',
                            option_value,
                            selected_html,
-                           force_unicode(option_label))
+                           force_text(option_label))
 
     def render_options(self, choices, selected_choices):
         # Normalize to strings.
-        selected_choices = set(force_unicode(v) for v in selected_choices)
+        selected_choices = set(force_text(v) for v in selected_choices)
         output = []
         for option_value, option_label in chain(self.choices, choices):
             if isinstance(option_label, (list, tuple)):
-                output.append(format_html('<optgroup label="{0}">', force_unicode(option_value)))
+                output.append(format_html('<optgroup label="{0}">', force_text(option_value)))
                 for option in option_label:
                     output.append(self.render_option(selected_choices, *option))
                 output.append('</optgroup>')
@@ -643,8 +643,8 @@ class SelectMultiple(Select):
             data = []
         if len(initial) != len(data):
             return True
-        initial_set = set([force_unicode(value) for value in initial])
-        data_set = set([force_unicode(value) for value in data])
+        initial_set = set([force_text(value) for value in initial])
+        data_set = set([force_text(value) for value in data])
         return data_set != initial_set
 
 class RadioInput(SubWidget):
@@ -656,8 +656,8 @@ class RadioInput(SubWidget):
     def __init__(self, name, value, attrs, choice, index):
         self.name, self.value = name, value
         self.attrs = attrs
-        self.choice_value = force_unicode(choice[0])
-        self.choice_label = force_unicode(choice[1])
+        self.choice_value = force_text(choice[0])
+        self.choice_label = force_text(choice[1])
         self.index = index
 
     def __unicode__(self):
@@ -671,7 +671,7 @@ class RadioInput(SubWidget):
             label_for = format_html(' for="{0}_{1}"', self.attrs['id'], self.index)
         else:
             label_for = ''
-        choice_label = force_unicode(self.choice_label)
+        choice_label = force_text(self.choice_label)
         return format_html('<label{0}>{1} {2}</label>', label_for, self.tag(), choice_label)
 
     def is_checked(self):
@@ -709,7 +709,7 @@ class RadioFieldRenderer(StrAndUnicode):
         """Outputs a <ul> for this set of radio fields."""
         return format_html('<ul>\n{0}\n</ul>',
                            format_html_join('\n', '<li>{0}</li>',
-                                            [(force_unicode(w),) for w in self]
+                                            [(force_text(w),) for w in self]
                                             ))
 
 class RadioSelect(Select):
@@ -729,7 +729,7 @@ class RadioSelect(Select):
     def get_renderer(self, name, value, attrs=None, choices=()):
         """Returns an instance of the renderer."""
         if value is None: value = ''
-        str_value = force_unicode(value) # Normalize to string.
+        str_value = force_text(value) # Normalize to string.
         final_attrs = self.build_attrs(attrs)
         choices = list(chain(self.choices, choices))
         return self.renderer(name, str_value, final_attrs, choices)
@@ -753,7 +753,7 @@ class CheckboxSelectMultiple(SelectMultiple):
         final_attrs = self.build_attrs(attrs, name=name)
         output = ['<ul>']
         # Normalize to strings
-        str_values = set([force_unicode(v) for v in value])
+        str_values = set([force_text(v) for v in value])
         for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
             # If an ID attribute was given, add a numeric index as a suffix,
             # so that the checkboxes don't all have the same ID attribute.
@@ -764,9 +764,9 @@ class CheckboxSelectMultiple(SelectMultiple):
                 label_for = ''
 
             cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
-            option_value = force_unicode(option_value)
+            option_value = force_text(option_value)
             rendered_cb = cb.render(name, option_value)
-            option_label = force_unicode(option_label)
+            option_label = force_text(option_label)
             output.append(format_html('<li><label{0}>{1} {2}</label></li>',
                                       label_for, rendered_cb, option_label))
         output.append('</ul>')
diff --git a/django/http/__init__.py b/django/http/__init__.py
index 4c2db74890c..b23304f3462 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -61,14 +61,14 @@ else:
         if not _cookie_allows_colon_in_names:
             def load(self, rawdata):
                 self.bad_cookies = set()
-                super(SimpleCookie, self).load(smart_str(rawdata))
+                super(SimpleCookie, self).load(smart_bytes(rawdata))
                 for key in self.bad_cookies:
                     del self[key]
 
             # override private __set() method:
             # (needed for using our Morsel, and for laxness with CookieError
             def _BaseCookie__set(self, key, real_value, coded_value):
-                key = smart_str(key)
+                key = smart_bytes(key)
                 try:
                     M = self.get(key, Morsel())
                     M.set(key, real_value, coded_value)
@@ -85,7 +85,7 @@ from django.core.files import uploadhandler
 from django.http.multipartparser import MultiPartParser
 from django.http.utils import *
 from django.utils.datastructures import MultiValueDict, ImmutableList
-from django.utils.encoding import smart_str, iri_to_uri, force_unicode
+from django.utils.encoding import smart_bytes, iri_to_uri, force_text
 from django.utils.http import cookie_date
 from django.utils import six
 from django.utils import timezone
@@ -137,7 +137,7 @@ def build_request_repr(request, path_override=None, GET_override=None,
     except:
         meta = '<could not parse>'
     path = path_override if path_override is not None else request.path
-    return smart_str('<%s\npath:%s,\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' %
+    return smart_bytes('<%s\npath:%s,\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' %
                      (request.__class__.__name__,
                       path,
                       six.text_type(get),
@@ -385,8 +385,8 @@ class QueryDict(MultiValueDict):
             encoding = settings.DEFAULT_CHARSET
         self.encoding = encoding
         for key, value in parse_qsl((query_string or ''), True): # keep_blank_values=True
-            self.appendlist(force_unicode(key, encoding, errors='replace'),
-                            force_unicode(value, encoding, errors='replace'))
+            self.appendlist(force_text(key, encoding, errors='replace'),
+                            force_text(value, encoding, errors='replace'))
         self._mutable = mutable
 
     def _get_encoding(self):
@@ -481,13 +481,13 @@ class QueryDict(MultiValueDict):
         """
         output = []
         if safe:
-            safe = smart_str(safe, self.encoding)
+            safe = smart_bytes(safe, self.encoding)
             encode = lambda k, v: '%s=%s' % ((quote(k, safe), quote(v, safe)))
         else:
             encode = lambda k, v: urlencode({k: v})
         for k, list_ in self.lists():
-            k = smart_str(k, self.encoding)
-            output.extend([encode(k, smart_str(v, self.encoding))
+            k = smart_bytes(k, self.encoding)
+            output.extend([encode(k, smart_bytes(v, self.encoding))
                            for v in list_])
         return '&'.join(output)
 
@@ -648,7 +648,7 @@ class HttpResponse(object):
     def _get_content(self):
         if self.has_header('Content-Encoding'):
             return b''.join([str(e) for e in self._container])
-        return b''.join([smart_str(e, self._charset) for e in self._container])
+        return b''.join([smart_bytes(e, self._charset) for e in self._container])
 
     def _set_content(self, value):
         if hasattr(value, '__iter__'):
@@ -698,7 +698,7 @@ class HttpResponseRedirectBase(HttpResponse):
             raise SuspiciousOperation("Unsafe redirect to URL with protocol '%s'" % parsed.scheme)
         super(HttpResponseRedirectBase, self).__init__()
         self['Location'] = iri_to_uri(redirect_to)
-    
+
 class HttpResponseRedirect(HttpResponseRedirectBase):
     status_code = 302
 
@@ -735,7 +735,7 @@ def get_host(request):
     return request.get_host()
 
 # It's neither necessary nor appropriate to use
-# django.utils.encoding.smart_unicode for parsing URLs and form inputs. Thus,
+# django.utils.encoding.smart_text for parsing URLs and form inputs. Thus,
 # this slightly more restricted function.
 def str_to_unicode(s, encoding):
     """
diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py
index 0e28a55c3a1..1987ee53bcb 100644
--- a/django/http/multipartparser.py
+++ b/django/http/multipartparser.py
@@ -10,7 +10,7 @@ import cgi
 from django.conf import settings
 from django.core.exceptions import SuspiciousOperation
 from django.utils.datastructures import MultiValueDict
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils import six
 from django.utils.text import unescape_entities
 from django.core.files.uploadhandler import StopUpload, SkipFile, StopFutureHandlers
@@ -151,7 +151,7 @@ class MultiPartParser(object):
                 transfer_encoding = meta_data.get('content-transfer-encoding')
                 if transfer_encoding is not None:
                     transfer_encoding = transfer_encoding[0].strip()
-                field_name = force_unicode(field_name, encoding, errors='replace')
+                field_name = force_text(field_name, encoding, errors='replace')
 
                 if item_type == FIELD:
                     # This is a post field, we can just set it in the post
@@ -165,13 +165,13 @@ class MultiPartParser(object):
                         data = field_stream.read()
 
                     self._post.appendlist(field_name,
-                                          force_unicode(data, encoding, errors='replace'))
+                                          force_text(data, encoding, errors='replace'))
                 elif item_type == FILE:
                     # This is a file, use the handler...
                     file_name = disposition.get('filename')
                     if not file_name:
                         continue
-                    file_name = force_unicode(file_name, encoding, errors='replace')
+                    file_name = force_text(file_name, encoding, errors='replace')
                     file_name = self.IE_sanitize(unescape_entities(file_name))
 
                     content_type = meta_data.get('content-type', ('',))[0].strip()
@@ -245,7 +245,7 @@ class MultiPartParser(object):
             file_obj = handler.file_complete(counters[i])
             if file_obj:
                 # If it returns a file object, then set the files dict.
-                self._files.appendlist(force_unicode(old_field_name,
+                self._files.appendlist(force_text(old_field_name,
                                                      self._encoding,
                                                      errors='replace'),
                                        file_obj)
diff --git a/django/template/base.py b/django/template/base.py
index d5c24385000..661d8c092ad 100644
--- a/django/template/base.py
+++ b/django/template/base.py
@@ -11,7 +11,7 @@ from django.utils.importlib import import_module
 from django.utils.itercompat import is_iterable
 from django.utils.text import (smart_split, unescape_string_literal,
     get_text_list)
-from django.utils.encoding import smart_unicode, force_unicode, smart_str
+from django.utils.encoding import smart_text, force_text, smart_bytes
 from django.utils.translation import ugettext_lazy, pgettext_lazy
 from django.utils.safestring import (SafeData, EscapeData, mark_safe,
     mark_for_escaping)
@@ -89,7 +89,7 @@ class VariableDoesNotExist(Exception):
         return six.text_type(self).encode('utf-8')
 
     def __unicode__(self):
-        return self.msg % tuple([force_unicode(p, errors='replace')
+        return self.msg % tuple([force_text(p, errors='replace')
                                  for p in self.params])
 
 class InvalidTemplateLibrary(Exception):
@@ -117,7 +117,7 @@ class Template(object):
     def __init__(self, template_string, origin=None,
                  name='<Unknown Template>'):
         try:
-            template_string = smart_unicode(template_string)
+            template_string = smart_text(template_string)
         except UnicodeDecodeError:
             raise TemplateEncodingError("Templates can only be constructed "
                                         "from unicode or UTF-8 strings.")
@@ -831,7 +831,7 @@ class NodeList(list):
                 bit = self.render_node(node, context)
             else:
                 bit = node
-            bits.append(force_unicode(bit))
+            bits.append(force_text(bit))
         return mark_safe(''.join(bits))
 
     def get_nodes_by_type(self, nodetype):
@@ -849,7 +849,7 @@ class TextNode(Node):
         self.s = s
 
     def __repr__(self):
-        return "<Text Node: '%s'>" % smart_str(self.s[:25], 'ascii',
+        return "<Text Node: '%s'>" % smart_bytes(self.s[:25], 'ascii',
                 errors='replace')
 
     def render(self, context):
@@ -863,7 +863,7 @@ def _render_value_in_context(value, context):
     """
     value = template_localtime(value, use_tz=context.use_tz)
     value = localize(value, use_l10n=context.use_l10n)
-    value = force_unicode(value)
+    value = force_text(value)
     if ((context.autoescape and not isinstance(value, SafeData)) or
             isinstance(value, EscapeData)):
         return escape(value)
diff --git a/django/template/debug.py b/django/template/debug.py
index 61674034d62..c7ac007b48c 100644
--- a/django/template/debug.py
+++ b/django/template/debug.py
@@ -1,5 +1,5 @@
 from django.template.base import Lexer, Parser, tag_re, NodeList, VariableNode, TemplateSyntaxError
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils.html import escape
 from django.utils.safestring import SafeData, EscapeData
 from django.utils.formats import localize
@@ -84,7 +84,7 @@ class DebugVariableNode(VariableNode):
             output = self.filter_expression.resolve(context)
             output = template_localtime(output, use_tz=context.use_tz)
             output = localize(output, use_l10n=context.use_l10n)
-            output = force_unicode(output)
+            output = force_text(output)
         except UnicodeDecodeError:
             return ''
         except Exception as e:
diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py
index fa799cd46f6..16801fd5736 100644
--- a/django/template/defaultfilters.py
+++ b/django/template/defaultfilters.py
@@ -12,7 +12,7 @@ from django.template.base import Variable, Library, VariableDoesNotExist
 from django.conf import settings
 from django.utils import formats
 from django.utils.dateformat import format, time_format
-from django.utils.encoding import force_unicode, iri_to_uri
+from django.utils.encoding import force_text, iri_to_uri
 from django.utils.html import (conditional_escape, escapejs, fix_ampersands,
     escape, urlize as urlize_impl, linebreaks, strip_tags)
 from django.utils.http import urlquote
@@ -38,7 +38,7 @@ def stringfilter(func):
     def _dec(*args, **kwargs):
         if args:
             args = list(args)
-            args[0] = force_unicode(args[0])
+            args[0] = force_text(args[0])
             if (isinstance(args[0], SafeData) and
                 getattr(_dec._decorated_function, 'is_safe', False)):
                 return mark_safe(func(*args, **kwargs))
@@ -139,7 +139,7 @@ def floatformat(text, arg=-1):
     """
 
     try:
-        input_val = force_unicode(text)
+        input_val = force_text(text)
         d = Decimal(input_val)
     except UnicodeEncodeError:
         return ''
@@ -147,7 +147,7 @@ def floatformat(text, arg=-1):
         if input_val in special_floats:
             return input_val
         try:
-            d = Decimal(force_unicode(float(text)))
+            d = Decimal(force_text(float(text)))
         except (ValueError, InvalidOperation, TypeError, UnicodeEncodeError):
             return ''
     try:
@@ -192,7 +192,7 @@ def floatformat(text, arg=-1):
 @stringfilter
 def iriencode(value):
     """Escapes an IRI value for use in a URL."""
-    return force_unicode(iri_to_uri(value))
+    return force_text(iri_to_uri(value))
 
 @register.filter(is_safe=True, needs_autoescape=True)
 @stringfilter
@@ -462,7 +462,7 @@ def safeseq(value):
     individually, as safe, after converting them to unicode. Returns a list
     with the results.
     """
-    return [mark_safe(force_unicode(obj)) for obj in value]
+    return [mark_safe(force_text(obj)) for obj in value]
 
 @register.filter(is_safe=True)
 @stringfilter
@@ -521,7 +521,7 @@ def join(value, arg, autoescape=None):
     """
     Joins a list with a string, like Python's ``str.join(list)``.
     """
-    value = map(force_unicode, value)
+    value = map(force_text, value)
     if autoescape:
         value = [conditional_escape(v) for v in value]
     try:
@@ -661,7 +661,7 @@ def unordered_list(value, autoescape=None):
                 sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist,
                                                          indent, indent)
             output.append('%s<li>%s%s</li>' % (indent,
-                    escaper(force_unicode(title)), sublist))
+                    escaper(force_text(title)), sublist))
             i += 1
         return '\n'.join(output)
     value, converted = convert_old_style_list(value)
@@ -901,4 +901,4 @@ def pprint(value):
     try:
         return pformat(value)
     except Exception as e:
-        return "Error in formatting: %s" % force_unicode(e, errors="replace")
+        return "Error in formatting: %s" % force_text(e, errors="replace")
diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
index 7a00d60361c..dca47a3da8d 100644
--- a/django/template/defaulttags.py
+++ b/django/template/defaulttags.py
@@ -14,7 +14,7 @@ from django.template.base import (Node, NodeList, Template, Context, Library,
     VARIABLE_ATTRIBUTE_SEPARATOR, get_library, token_kwargs, kwarg_re)
 from django.template.smartif import IfParser, Literal
 from django.template.defaultfilters import date
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.safestring import mark_safe
 from django.utils.html import format_html
 from django.utils import six
@@ -104,7 +104,7 @@ class FirstOfNode(Node):
         for var in self.vars:
             value = var.resolve(context, True)
             if value:
-                return smart_unicode(value)
+                return smart_text(value)
         return ''
 
 class ForNode(Node):
@@ -393,7 +393,7 @@ class URLNode(Node):
     def render(self, context):
         from django.core.urlresolvers import reverse, NoReverseMatch
         args = [arg.resolve(context) for arg in self.args]
-        kwargs = dict([(smart_unicode(k, 'ascii'), v.resolve(context))
+        kwargs = dict([(smart_text(k, 'ascii'), v.resolve(context))
                        for k, v in self.kwargs.items()])
 
         view_name = self.view_name.resolve(context)
diff --git a/django/templatetags/l10n.py b/django/templatetags/l10n.py
index 1eac1de0712..667de2470e4 100644
--- a/django/templatetags/l10n.py
+++ b/django/templatetags/l10n.py
@@ -1,7 +1,7 @@
 from django.template import Node
 from django.template import TemplateSyntaxError, Library
 from django.utils import formats
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 
 register = Library()
 
@@ -11,7 +11,7 @@ def localize(value):
     Forces a value to be rendered as a localized value,
     regardless of the value of ``settings.USE_L10N``.
     """
-    return force_unicode(formats.localize(value, use_l10n=True))
+    return force_text(formats.localize(value, use_l10n=True))
 
 @register.filter(is_safe=False)
 def unlocalize(value):
@@ -19,7 +19,7 @@ def unlocalize(value):
     Forces a value to be rendered as a non-localized value,
     regardless of the value of ``settings.USE_L10N``.
     """
-    return force_unicode(value)
+    return force_text(value)
 
 class LocalizeNode(Node):
     def __init__(self, nodelist, use_l10n):
diff --git a/django/test/client.py b/django/test/client.py
index a18b7f88530..ef80a7129a3 100644
--- a/django/test/client.py
+++ b/django/test/client.py
@@ -19,7 +19,7 @@ from django.http import SimpleCookie, HttpRequest, QueryDict
 from django.template import TemplateDoesNotExist
 from django.test import signals
 from django.utils.functional import curry
-from django.utils.encoding import smart_str
+from django.utils.encoding import smart_bytes
 from django.utils.http import urlencode
 from django.utils.importlib import import_module
 from django.utils.itercompat import is_iterable
@@ -108,7 +108,7 @@ def encode_multipart(boundary, data):
     as an application/octet-stream; otherwise, str(value) will be sent.
     """
     lines = []
-    to_str = lambda s: smart_str(s, settings.DEFAULT_CHARSET)
+    to_str = lambda s: smart_bytes(s, settings.DEFAULT_CHARSET)
 
     # Not by any means perfect, but good enough for our purposes.
     is_file = lambda thing: hasattr(thing, "read") and callable(thing.read)
@@ -145,7 +145,7 @@ def encode_multipart(boundary, data):
     return '\r\n'.join(lines)
 
 def encode_file(boundary, key, file):
-    to_str = lambda s: smart_str(s, settings.DEFAULT_CHARSET)
+    to_str = lambda s: smart_bytes(s, settings.DEFAULT_CHARSET)
     content_type = mimetypes.guess_type(file.name)[0]
     if content_type is None:
         content_type = 'application/octet-stream'
@@ -220,7 +220,7 @@ class RequestFactory(object):
                 charset = match.group(1)
             else:
                 charset = settings.DEFAULT_CHARSET
-            return smart_str(data, encoding=charset)
+            return smart_bytes(data, encoding=charset)
 
     def _get_path(self, parsed):
         # If there are parameters, add them
@@ -291,7 +291,7 @@ class RequestFactory(object):
     def generic(self, method, path,
                 data='', content_type='application/octet-stream', **extra):
         parsed = urlparse(path)
-        data = smart_str(data, settings.DEFAULT_CHARSET)
+        data = smart_bytes(data, settings.DEFAULT_CHARSET)
         r = {
             'PATH_INFO':      self._get_path(parsed),
             'QUERY_STRING':   parsed[4],
diff --git a/django/test/html.py b/django/test/html.py
index 2a1421bf17a..143c3728be7 100644
--- a/django/test/html.py
+++ b/django/test/html.py
@@ -5,7 +5,7 @@ Comparing two html documents.
 from __future__ import unicode_literals
 
 import re
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils.html_parser import HTMLParser, HTMLParseError
 from django.utils import six
 
@@ -25,7 +25,7 @@ class Element(object):
 
     def append(self, element):
         if isinstance(element, six.string_types):
-            element = force_unicode(element)
+            element = force_text(element)
             element = normalize_whitespace(element)
             if self.children:
                 if isinstance(self.children[-1], six.string_types):
diff --git a/django/test/testcases.py b/django/test/testcases.py
index b60188bf303..3a0dc760c69 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -41,7 +41,7 @@ from django.test.utils import (get_warnings_state, restore_warnings_state,
     override_settings)
 from django.test.utils import ContextList
 from django.utils import unittest as ut2
-from django.utils.encoding import smart_str, force_unicode
+from django.utils.encoding import smart_bytes, force_text
 from django.utils import six
 from django.utils.unittest.util import safe_repr
 from django.views.static import serve
@@ -398,7 +398,7 @@ class SimpleTestCase(ut2.TestCase):
                 optional.clean(input)
             self.assertEqual(context_manager.exception.messages, errors)
         # test required inputs
-        error_required = [force_unicode(required.error_messages['required'])]
+        error_required = [force_text(required.error_messages['required'])]
         for e in EMPTY_VALUES:
             with self.assertRaises(ValidationError) as context_manager:
                 required.clean(e)
@@ -647,7 +647,7 @@ class TransactionTestCase(SimpleTestCase):
         self.assertEqual(response.status_code, status_code,
             msg_prefix + "Couldn't retrieve content: Response code was %d"
             " (expected %d)" % (response.status_code, status_code))
-        enc_text = smart_str(text, response._charset)
+        enc_text = smart_bytes(text, response._charset)
         content = response.content
         if html:
             content = assert_and_parse_html(self, content, None,
@@ -683,7 +683,7 @@ class TransactionTestCase(SimpleTestCase):
         self.assertEqual(response.status_code, status_code,
             msg_prefix + "Couldn't retrieve content: Response code was %d"
             " (expected %d)" % (response.status_code, status_code))
-        enc_text = smart_str(text, response._charset)
+        enc_text = smart_bytes(text, response._charset)
         content = response.content
         if html:
             content = assert_and_parse_html(self, content, None,
diff --git a/django/utils/_os.py b/django/utils/_os.py
index 884689fefcd..82dccd0efe1 100644
--- a/django/utils/_os.py
+++ b/django/utils/_os.py
@@ -1,7 +1,7 @@
 import os
 import stat
 from os.path import join, normcase, normpath, abspath, isabs, sep
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 
 try:
     WindowsError = WindowsError
@@ -37,8 +37,8 @@ def safe_join(base, *paths):
     The final path must be located inside of the base path component (otherwise
     a ValueError is raised).
     """
-    base = force_unicode(base)
-    paths = [force_unicode(p) for p in paths]
+    base = force_text(base)
+    paths = [force_text(p) for p in paths]
     final_path = abspathu(join(base, *paths))
     base_path = abspathu(base)
     base_path_len = len(base_path)
diff --git a/django/utils/cache.py b/django/utils/cache.py
index 8b81a2ffa22..42b0de4ce67 100644
--- a/django/utils/cache.py
+++ b/django/utils/cache.py
@@ -23,7 +23,7 @@ import time
 
 from django.conf import settings
 from django.core.cache import get_cache
-from django.utils.encoding import iri_to_uri, force_unicode
+from django.utils.encoding import iri_to_uri, force_text
 from django.utils.http import http_date
 from django.utils.timezone import get_current_timezone_name
 from django.utils.translation import get_language
@@ -169,7 +169,7 @@ def _i18n_cache_key_suffix(request, cache_key):
         # Windows is known to use non-standard, locale-dependant names.
         # User-defined tzinfo classes may return absolutely anything.
         # Hence this paranoid conversion to create a valid cache key.
-        tz_name = force_unicode(get_current_timezone_name(), errors='ignore')
+        tz_name = force_text(get_current_timezone_name(), errors='ignore')
         cache_key += '.%s' % tz_name.encode('ascii', 'ignore').replace(' ', '_')
     return cache_key
 
diff --git a/django/utils/crypto.py b/django/utils/crypto.py
index 9d46bdd7938..1edbb43eb37 100644
--- a/django/utils/crypto.py
+++ b/django/utils/crypto.py
@@ -23,7 +23,7 @@ except NotImplementedError:
     using_sysrandom = False
 
 from django.conf import settings
-from django.utils.encoding import smart_str
+from django.utils.encoding import smart_bytes
 from django.utils.six.moves import xrange
 
 
@@ -115,7 +115,7 @@ def _fast_hmac(key, msg, digest):
     A trimmed down version of Python's HMAC implementation
     """
     dig1, dig2 = digest(), digest()
-    key = smart_str(key)
+    key = smart_bytes(key)
     if len(key) > dig1.block_size:
         key = digest(key).digest()
     key += chr(0) * (dig1.block_size - len(key))
@@ -141,8 +141,8 @@ def pbkdf2(password, salt, iterations, dklen=0, digest=None):
     assert iterations > 0
     if not digest:
         digest = hashlib.sha256
-    password = smart_str(password)
-    salt = smart_str(salt)
+    password = smart_bytes(password)
+    salt = smart_bytes(salt)
     hlen = digest().digest_size
     if not dklen:
         dklen = hlen
diff --git a/django/utils/dateformat.py b/django/utils/dateformat.py
index c9a6138aed2..6a91a370e5b 100644
--- a/django/utils/dateformat.py
+++ b/django/utils/dateformat.py
@@ -20,7 +20,7 @@ import datetime
 from django.utils.dates import MONTHS, MONTHS_3, MONTHS_ALT, MONTHS_AP, WEEKDAYS, WEEKDAYS_ABBR
 from django.utils.tzinfo import LocalTimezone
 from django.utils.translation import ugettext as _
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils import six
 from django.utils.timezone import is_aware, is_naive
 
@@ -30,9 +30,9 @@ re_escaped = re.compile(r'\\(.)')
 class Formatter(object):
     def format(self, formatstr):
         pieces = []
-        for i, piece in enumerate(re_formatchars.split(force_unicode(formatstr))):
+        for i, piece in enumerate(re_formatchars.split(force_text(formatstr))):
             if i % 2:
-                pieces.append(force_unicode(getattr(self, piece)()))
+                pieces.append(force_text(getattr(self, piece)()))
             elif piece:
                 pieces.append(re_escaped.sub(r'\1', piece))
         return ''.join(pieces)
diff --git a/django/utils/encoding.py b/django/utils/encoding.py
index b5f4b76507e..eb60cfde8bd 100644
--- a/django/utils/encoding.py
+++ b/django/utils/encoding.py
@@ -24,9 +24,13 @@ class DjangoUnicodeDecodeError(UnicodeDecodeError):
 
 class StrAndUnicode(object):
     """
-    A class whose __str__ returns its __unicode__ as a UTF-8 bytestring.
+    A class that derives __str__ from __unicode__.
 
-    Useful as a mix-in.
+    On Python 2, __str__ returns the output of __unicode__ encoded as a UTF-8
+    bytestring. On Python 3, __str__ returns the output of __unicode__.
+
+    Useful as a mix-in. If you support Python 2 and 3 with a single code base,
+    you can inherit this mix-in and just define __unicode__.
     """
     if six.PY3:
         def __str__(self):
@@ -35,37 +39,36 @@ class StrAndUnicode(object):
         def __str__(self):
             return self.__unicode__().encode('utf-8')
 
-def smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
+def smart_text(s, encoding='utf-8', strings_only=False, errors='strict'):
     """
-    Returns a unicode object representing 's'. Treats bytestrings using the
-    'encoding' codec.
+    Returns a text object representing 's' -- unicode on Python 2 and str on
+    Python 3. Treats bytestrings using the 'encoding' codec.
 
     If strings_only is True, don't convert (some) non-string-like objects.
     """
     if isinstance(s, Promise):
         # The input is the result of a gettext_lazy() call.
         return s
-    return force_unicode(s, encoding, strings_only, errors)
+    return force_text(s, encoding, strings_only, errors)
 
 def is_protected_type(obj):
     """Determine if the object instance is of a protected type.
 
     Objects of protected types are preserved as-is when passed to
-    force_unicode(strings_only=True).
+    force_text(strings_only=True).
     """
     return isinstance(obj, six.integer_types + (type(None), float, Decimal,
         datetime.datetime, datetime.date, datetime.time))
 
-def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
+def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
     """
-    Similar to smart_unicode, except that lazy instances are resolved to
+    Similar to smart_text, except that lazy instances are resolved to
     strings, rather than kept as lazy objects.
 
     If strings_only is True, don't convert (some) non-string-like objects.
     """
-    # Handle the common case first, saves 30-40% in performance when s
-    # is an instance of unicode. This function gets called often in that
-    # setting.
+    # Handle the common case first, saves 30-40% when s is an instance of
+    # six.text_type. This function gets called often in that setting.
     if isinstance(s, six.text_type):
         return s
     if strings_only and is_protected_type(s):
@@ -92,7 +95,7 @@ def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
                     # without raising a further exception. We do an
                     # approximation to what the Exception's standard str()
                     # output should be.
-                    s = ' '.join([force_unicode(arg, encoding, strings_only,
+                    s = ' '.join([force_text(arg, encoding, strings_only,
                             errors) for arg in s])
         else:
             # Note: We use .decode() here, instead of six.text_type(s, encoding,
@@ -108,21 +111,26 @@ def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
             # working unicode method. Try to handle this without raising a
             # further exception by individually forcing the exception args
             # to unicode.
-            s = ' '.join([force_unicode(arg, encoding, strings_only,
+            s = ' '.join([force_text(arg, encoding, strings_only,
                     errors) for arg in s])
     return s
 
-def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
+def smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
     """
     Returns a bytestring version of 's', encoded as specified in 'encoding'.
 
     If strings_only is True, don't convert (some) non-string-like objects.
     """
+    if isinstance(s, bytes):
+        if encoding == 'utf-8':
+            return s
+        else:
+            return s.decode('utf-8', errors).encode(encoding, errors)
     if strings_only and (s is None or isinstance(s, int)):
         return s
     if isinstance(s, Promise):
         return six.text_type(s).encode(encoding, errors)
-    elif not isinstance(s, six.string_types):
+    if not isinstance(s, six.string_types):
         try:
             if six.PY3:
                 return six.text_type(s).encode(encoding)
@@ -133,15 +141,25 @@ def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
                 # An Exception subclass containing non-ASCII data that doesn't
                 # know how to print itself properly. We shouldn't raise a
                 # further exception.
-                return ' '.join([smart_str(arg, encoding, strings_only,
+                return ' '.join([smart_bytes(arg, encoding, strings_only,
                         errors) for arg in s])
             return six.text_type(s).encode(encoding, errors)
-    elif isinstance(s, six.text_type):
-        return s.encode(encoding, errors)
-    elif s and encoding != 'utf-8':
-        return s.decode('utf-8', errors).encode(encoding, errors)
     else:
-        return s
+        return s.encode(encoding, errors)
+
+if six.PY3:
+    smart_str = smart_text
+else:
+    smart_str = smart_bytes
+    # backwards compatibility for Python 2
+    smart_unicode = smart_text
+    force_unicode = force_text
+
+smart_str.__doc__ = """\
+Apply smart_text in Python 3 and smart_bytes in Python 2.
+
+This is suitable for writing to sys.stdout (for instance).
+"""
 
 def iri_to_uri(iri):
     """
@@ -168,7 +186,7 @@ def iri_to_uri(iri):
     # converted.
     if iri is None:
         return iri
-    return quote(smart_str(iri), safe=b"/#%[]=:;$&()+,!?*@'~")
+    return quote(smart_bytes(iri), safe=b"/#%[]=:;$&()+,!?*@'~")
 
 def filepath_to_uri(path):
     """Convert an file system path to a URI portion that is suitable for
@@ -187,7 +205,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 quote(smart_str(path).replace("\\", "/"), safe=b"/~!*()'")
+    return quote(smart_bytes(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
diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py
index 6498aaf57ce..1bf43bf0a7e 100644
--- a/django/utils/feedgenerator.py
+++ b/django/utils/feedgenerator.py
@@ -29,7 +29,7 @@ try:
 except ImportError:     # Python 2
     from urlparse import urlparse
 from django.utils.xmlutils import SimplerXMLGenerator
-from django.utils.encoding import force_unicode, iri_to_uri
+from django.utils.encoding import force_text, iri_to_uri
 from django.utils import datetime_safe
 from django.utils.timezone import is_aware
 
@@ -81,12 +81,12 @@ class SyndicationFeed(object):
     def __init__(self, title, link, description, language=None, author_email=None,
             author_name=None, author_link=None, subtitle=None, categories=None,
             feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, **kwargs):
-        to_unicode = lambda s: force_unicode(s, strings_only=True)
+        to_unicode = lambda s: force_text(s, strings_only=True)
         if categories:
-            categories = [force_unicode(c) for c in categories]
+            categories = [force_text(c) for c in categories]
         if ttl is not None:
             # Force ints to unicode
-            ttl = force_unicode(ttl)
+            ttl = force_text(ttl)
         self.feed = {
             'title': to_unicode(title),
             'link': iri_to_uri(link),
@@ -114,12 +114,12 @@ class SyndicationFeed(object):
         objects except pubdate, which is a datetime.datetime object, and
         enclosure, which is an instance of the Enclosure class.
         """
-        to_unicode = lambda s: force_unicode(s, strings_only=True)
+        to_unicode = lambda s: force_text(s, strings_only=True)
         if categories:
             categories = [to_unicode(c) for c in categories]
         if ttl is not None:
             # Force ints to unicode
-            ttl = force_unicode(ttl)
+            ttl = force_text(ttl)
         item = {
             'title': to_unicode(title),
             'link': iri_to_uri(link),
diff --git a/django/utils/html.py b/django/utils/html.py
index 4e888fc59bf..7dd53a1353e 100644
--- a/django/utils/html.py
+++ b/django/utils/html.py
@@ -11,7 +11,7 @@ except ImportError:     # Python 2
     from urlparse import urlsplit, urlunsplit
 
 from django.utils.safestring import SafeData, mark_safe
-from django.utils.encoding import smart_str, force_unicode
+from django.utils.encoding import smart_bytes, force_text
 from django.utils.functional import allow_lazy
 from django.utils import six
 from django.utils.text import normalize_newlines
@@ -39,7 +39,7 @@ def escape(text):
     """
     Returns the given text with ampersands, quotes and angle brackets encoded for use in HTML.
     """
-    return mark_safe(force_unicode(text).replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;'))
+    return mark_safe(force_text(text).replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;'))
 escape = allow_lazy(escape, six.text_type)
 
 _base_js_escapes = (
@@ -63,7 +63,7 @@ _js_escapes = (_base_js_escapes +
 def escapejs(value):
     """Hex encodes characters for use in JavaScript strings."""
     for bad, good in _js_escapes:
-        value = mark_safe(force_unicode(value).replace(bad, good))
+        value = mark_safe(force_text(value).replace(bad, good))
     return value
 escapejs = allow_lazy(escapejs, six.text_type)
 
@@ -120,22 +120,22 @@ linebreaks = allow_lazy(linebreaks, six.text_type)
 
 def strip_tags(value):
     """Returns the given HTML with all tags stripped."""
-    return re.sub(r'<[^>]*?>', '', force_unicode(value))
+    return re.sub(r'<[^>]*?>', '', force_text(value))
 strip_tags = allow_lazy(strip_tags)
 
 def strip_spaces_between_tags(value):
     """Returns the given HTML with spaces between tags removed."""
-    return re.sub(r'>\s+<', '><', force_unicode(value))
+    return re.sub(r'>\s+<', '><', force_text(value))
 strip_spaces_between_tags = allow_lazy(strip_spaces_between_tags, six.text_type)
 
 def strip_entities(value):
     """Returns the given HTML with all entities (&something;) stripped."""
-    return re.sub(r'&(?:\w+|#\d+);', '', force_unicode(value))
+    return re.sub(r'&(?:\w+|#\d+);', '', force_text(value))
 strip_entities = allow_lazy(strip_entities, six.text_type)
 
 def fix_ampersands(value):
     """Returns the given HTML with all unencoded ampersands encoded correctly."""
-    return unencoded_ampersands_re.sub('&amp;', force_unicode(value))
+    return unencoded_ampersands_re.sub('&amp;', force_text(value))
 fix_ampersands = allow_lazy(fix_ampersands, six.text_type)
 
 def smart_urlquote(url):
@@ -153,9 +153,9 @@ 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 = quote(smart_str(url), safe=b'!*\'();:@&=+$,/?#[]~')
+        url = quote(smart_bytes(url), safe=b'!*\'();:@&=+$,/?#[]~')
 
-    return force_unicode(url)
+    return force_text(url)
 
 def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
     """
@@ -176,7 +176,7 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
     """
     trim_url = lambda x, limit=trim_url_limit: limit is not None and (len(x) > limit and ('%s...' % x[:max(0, limit - 3)])) or x
     safe_input = isinstance(text, SafeData)
-    words = word_split_re.split(force_unicode(text))
+    words = word_split_re.split(force_text(text))
     for i, word in enumerate(words):
         match = None
         if '.' in word or '@' in word or ':' in word:
@@ -245,7 +245,7 @@ def clean_html(text):
           bottom of the text.
     """
     from django.utils.text import normalize_newlines
-    text = normalize_newlines(force_unicode(text))
+    text = normalize_newlines(force_text(text))
     text = re.sub(r'<(/?)\s*b\s*>', '<\\1strong>', text)
     text = re.sub(r'<(/?)\s*i\s*>', '<\\1em>', text)
     text = fix_ampersands(text)
diff --git a/django/utils/http.py b/django/utils/http.py
index 272e73f1902..22e81a33d7c 100644
--- a/django/utils/http.py
+++ b/django/utils/http.py
@@ -13,7 +13,7 @@ except ImportError:     # Python 2
 from email.utils import formatdate
 
 from django.utils.datastructures import MultiValueDict
-from django.utils.encoding import smart_str, force_unicode
+from django.utils.encoding import force_text, smart_str
 from django.utils.functional import allow_lazy
 from django.utils import six
 
@@ -37,7 +37,7 @@ def urlquote(url, safe='/'):
     can safely be used as part of an argument to a subsequent iri_to_uri() call
     without double-quoting occurring.
     """
-    return force_unicode(urllib_parse.quote(smart_str(url), smart_str(safe)))
+    return force_text(urllib_parse.quote(smart_str(url), smart_str(safe)))
 urlquote = allow_lazy(urlquote, six.text_type)
 
 def urlquote_plus(url, safe=''):
@@ -47,7 +47,7 @@ def urlquote_plus(url, safe=''):
     returned string can safely be used as part of an argument to a subsequent
     iri_to_uri() call without double-quoting occurring.
     """
-    return force_unicode(urllib_parse.quote_plus(smart_str(url), smart_str(safe)))
+    return force_text(urllib_parse.quote_plus(smart_str(url), smart_str(safe)))
 urlquote_plus = allow_lazy(urlquote_plus, six.text_type)
 
 def urlunquote(quoted_url):
@@ -55,7 +55,7 @@ def urlunquote(quoted_url):
     A wrapper for Python's urllib.unquote() function that can operate on
     the result of django.utils.http.urlquote().
     """
-    return force_unicode(urllib_parse.unquote(smart_str(quoted_url)))
+    return force_text(urllib_parse.unquote(smart_str(quoted_url)))
 urlunquote = allow_lazy(urlunquote, six.text_type)
 
 def urlunquote_plus(quoted_url):
@@ -63,7 +63,7 @@ def urlunquote_plus(quoted_url):
     A wrapper for Python's urllib.unquote_plus() function that can operate on
     the result of django.utils.http.urlquote_plus().
     """
-    return force_unicode(urllib_parse.unquote_plus(smart_str(quoted_url)))
+    return force_text(urllib_parse.unquote_plus(smart_str(quoted_url)))
 urlunquote_plus = allow_lazy(urlunquote_plus, six.text_type)
 
 def urlencode(query, doseq=0):
diff --git a/django/utils/text.py b/django/utils/text.py
index 43056aa6345..0838d79c652 100644
--- a/django/utils/text.py
+++ b/django/utils/text.py
@@ -7,13 +7,13 @@ from gzip import GzipFile
 from django.utils.six.moves import html_entities
 from io import BytesIO
 
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils.functional import allow_lazy, SimpleLazyObject
 from django.utils import six
 from django.utils.translation import ugettext_lazy, ugettext as _, pgettext
 
 # Capitalizes the first letter of a string.
-capfirst = lambda x: x and force_unicode(x)[0].upper() + force_unicode(x)[1:]
+capfirst = lambda x: x and force_text(x)[0].upper() + force_text(x)[1:]
 capfirst = allow_lazy(capfirst, six.text_type)
 
 # Set up regular expressions
@@ -26,7 +26,7 @@ def wrap(text, width):
     A word-wrap function that preserves existing line breaks and most spaces in
     the text. Expects that existing line breaks are posix newlines.
     """
-    text = force_unicode(text)
+    text = force_text(text)
     def _generator():
         it = iter(text.split(' '))
         word = next(it)
@@ -55,14 +55,14 @@ class Truncator(SimpleLazyObject):
     An object used to truncate text, either by characters or words.
     """
     def __init__(self, text):
-        super(Truncator, self).__init__(lambda: force_unicode(text))
+        super(Truncator, self).__init__(lambda: force_text(text))
 
     def add_truncation_text(self, text, truncate=None):
         if truncate is None:
             truncate = pgettext(
                 'String to return when truncating text',
                 '%(truncated_text)s...')
-        truncate = force_unicode(truncate)
+        truncate = force_text(truncate)
         if '%(truncated_text)s' in truncate:
             return truncate % {'truncated_text': text}
         # The truncation text didn't contain the %(truncated_text)s string
@@ -226,7 +226,7 @@ def get_valid_filename(s):
     >>> get_valid_filename("john's portrait in 2004.jpg")
     'johns_portrait_in_2004.jpg'
     """
-    s = force_unicode(s).strip().replace(' ', '_')
+    s = force_text(s).strip().replace(' ', '_')
     return re.sub(r'(?u)[^-\w.]', '', s)
 get_valid_filename = allow_lazy(get_valid_filename, six.text_type)
 
@@ -244,20 +244,20 @@ def get_text_list(list_, last_word=ugettext_lazy('or')):
     ''
     """
     if len(list_) == 0: return ''
-    if len(list_) == 1: return force_unicode(list_[0])
+    if len(list_) == 1: return force_text(list_[0])
     return '%s %s %s' % (
         # Translators: This string is used as a separator between list elements
-        _(', ').join([force_unicode(i) for i in list_][:-1]),
-        force_unicode(last_word), force_unicode(list_[-1]))
+        _(', ').join([force_text(i) for i in list_][:-1]),
+        force_text(last_word), force_text(list_[-1]))
 get_text_list = allow_lazy(get_text_list, six.text_type)
 
 def normalize_newlines(text):
-    return force_unicode(re.sub(r'\r\n|\r|\n', '\n', text))
+    return force_text(re.sub(r'\r\n|\r|\n', '\n', text))
 normalize_newlines = allow_lazy(normalize_newlines, six.text_type)
 
 def recapitalize(text):
     "Recapitalizes text, placing caps after end-of-sentence punctuation."
-    text = force_unicode(text).lower()
+    text = force_text(text).lower()
     capsRE = re.compile(r'(?:^|(?<=[\.\?\!] ))([a-z])')
     text = capsRE.sub(lambda x: x.group(1).upper(), text)
     return text
@@ -330,7 +330,7 @@ def smart_split(text):
     >>> list(smart_split(r'A "\"funky\" style" test.'))
     ['A', '"\\"funky\\" style"', 'test.']
     """
-    text = force_unicode(text)
+    text = force_text(text)
     for bit in smart_split_re.finditer(text):
         yield bit.group(0)
 smart_split = allow_lazy(smart_split, six.text_type)
diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py
index d31a7aebf19..febde404a52 100644
--- a/django/utils/translation/__init__.py
+++ b/django/utils/translation/__init__.py
@@ -3,7 +3,7 @@ Internationalization support.
 """
 from __future__ import unicode_literals
 
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils.functional import lazy
 from django.utils import six
 
@@ -139,7 +139,7 @@ def _string_concat(*strings):
     Lazy variant of string concatenation, needed for translations that are
     constructed from multiple parts.
     """
-    return ''.join([force_unicode(s) for s in strings])
+    return ''.join([force_text(s) for s in strings])
 string_concat = lazy(_string_concat, six.text_type)
 
 def get_language_info(lang_code):
diff --git a/django/utils/translation/trans_null.py b/django/utils/translation/trans_null.py
index 0fabc707ce2..5c514682048 100644
--- a/django/utils/translation/trans_null.py
+++ b/django/utils/translation/trans_null.py
@@ -3,7 +3,7 @@
 # settings.USE_I18N = False can use this module rather than trans_real.py.
 
 from django.conf import settings
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils.safestring import mark_safe, SafeData
 
 def ngettext(singular, plural, number):
@@ -12,7 +12,7 @@ def ngettext(singular, plural, number):
 ngettext_lazy = ngettext
 
 def ungettext(singular, plural, number):
-    return force_unicode(ngettext(singular, plural, number))
+    return force_text(ngettext(singular, plural, number))
 
 def pgettext(context, message):
     return ugettext(message)
@@ -44,7 +44,7 @@ def gettext(message):
     return result
 
 def ugettext(message):
-    return force_unicode(gettext(message))
+    return force_text(gettext(message))
 
 gettext_noop = gettext_lazy = _ = gettext
 
diff --git a/django/utils/tzinfo.py b/django/utils/tzinfo.py
index 05f4aa6d2fe..c40b4304118 100644
--- a/django/utils/tzinfo.py
+++ b/django/utils/tzinfo.py
@@ -5,7 +5,7 @@ from __future__ import unicode_literals
 import time
 from datetime import timedelta, tzinfo
 
-from django.utils.encoding import smart_unicode, smart_str, DEFAULT_LOCALE_ENCODING
+from django.utils.encoding import smart_text, smart_bytes, DEFAULT_LOCALE_ENCODING
 
 # Python's doc say: "A tzinfo subclass must have an __init__() method that can
 # be called with no arguments". FixedOffset and LocalTimezone don't honor this
@@ -53,7 +53,7 @@ class LocalTimezone(tzinfo):
         self._tzname = self.tzname(dt)
 
     def __repr__(self):
-        return smart_str(self._tzname)
+        return smart_bytes(self._tzname)
 
     def __getinitargs__(self):
         return self.__dt,
@@ -72,7 +72,7 @@ class LocalTimezone(tzinfo):
 
     def tzname(self, dt):
         try:
-            return smart_unicode(time.tzname[self._isdst(dt)],
+            return smart_text(time.tzname[self._isdst(dt)],
                                  DEFAULT_LOCALE_ENCODING)
         except UnicodeDecodeError:
             return None
diff --git a/django/views/debug.py b/django/views/debug.py
index 08341fe145c..b275ef9e73d 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -14,7 +14,7 @@ from django.template import Template, Context, TemplateDoesNotExist
 from django.template.defaultfilters import force_escape, pprint
 from django.utils.html import escape
 from django.utils.importlib import import_module
-from django.utils.encoding import smart_unicode, smart_str
+from django.utils.encoding import smart_text, smart_bytes
 from django.utils import six
 
 HIDDEN_SETTINGS = re.compile('API|TOKEN|KEY|SECRET|PASS|PROFANITIES_LIST|SIGNATURE')
@@ -256,7 +256,7 @@ class ExceptionReporter(object):
             end = getattr(self.exc_value, 'end', None)
             if start is not None and end is not None:
                 unicode_str = self.exc_value.args[1]
-                unicode_hint = smart_unicode(unicode_str[max(start-5, 0):min(end+5, len(unicode_str))], 'ascii', errors='replace')
+                unicode_hint = smart_text(unicode_str[max(start-5, 0):min(end+5, len(unicode_str))], 'ascii', errors='replace')
         from django import get_version
         c = {
             'is_email': self.is_email,
@@ -278,7 +278,7 @@ class ExceptionReporter(object):
         if self.exc_type:
             c['exception_type'] = self.exc_type.__name__
         if self.exc_value:
-            c['exception_value'] = smart_unicode(self.exc_value, errors='replace')
+            c['exception_value'] = smart_text(self.exc_value, errors='replace')
         if frames:
             c['lastframe'] = frames[-1]
         return c
@@ -440,7 +440,7 @@ def technical_404_response(request, exception):
         'root_urlconf': settings.ROOT_URLCONF,
         'request_path': request.path_info[1:], # Trim leading slash
         'urlpatterns': tried,
-        'reason': smart_str(exception, errors='replace'),
+        'reason': smart_bytes(exception, errors='replace'),
         'request': request,
         'settings': get_safe_settings(),
     })
diff --git a/django/views/generic/dates.py b/django/views/generic/dates.py
index 22a72bc4332..08b7318738f 100644
--- a/django/views/generic/dates.py
+++ b/django/views/generic/dates.py
@@ -5,7 +5,7 @@ from django.conf import settings
 from django.db import models
 from django.core.exceptions import ImproperlyConfigured
 from django.http import Http404
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils.functional import cached_property
 from django.utils.translation import ugettext as _
 from django.utils import timezone
@@ -365,7 +365,7 @@ class BaseDateListView(MultipleObjectMixin, DateMixin, View):
             is_empty = len(qs) == 0 if paginate_by is None else not qs.exists()
             if is_empty:
                 raise Http404(_("No %(verbose_name_plural)s available") % {
-                        'verbose_name_plural': force_unicode(qs.model._meta.verbose_name_plural)
+                        'verbose_name_plural': force_text(qs.model._meta.verbose_name_plural)
                 })
 
         return qs
@@ -380,7 +380,7 @@ class BaseDateListView(MultipleObjectMixin, DateMixin, View):
 
         date_list = queryset.dates(date_field, date_type)[::-1]
         if date_list is not None and not date_list and not allow_empty:
-            name = force_unicode(queryset.model._meta.verbose_name_plural)
+            name = force_text(queryset.model._meta.verbose_name_plural)
             raise Http404(_("No %(verbose_name_plural)s available") %
                           {'verbose_name_plural': name})
 
diff --git a/django/views/i18n.py b/django/views/i18n.py
index b0f64f49024..00ef224254e 100644
--- a/django/views/i18n.py
+++ b/django/views/i18n.py
@@ -6,7 +6,7 @@ from django.conf import settings
 from django.utils import importlib
 from django.utils.translation import check_for_language, activate, to_locale, get_language
 from django.utils.text import javascript_quote
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.formats import get_format_modules, get_format
 from django.utils import six
 
@@ -54,9 +54,9 @@ def get_formats():
     src = []
     for k, v in result.items():
         if isinstance(v, (six.string_types, int)):
-            src.append("formats['%s'] = '%s';\n" % (javascript_quote(k), javascript_quote(smart_unicode(v))))
+            src.append("formats['%s'] = '%s';\n" % (javascript_quote(k), javascript_quote(smart_text(v))))
         elif isinstance(v, (tuple, list)):
-            v = [javascript_quote(smart_unicode(value)) for value in v]
+            v = [javascript_quote(smart_text(value)) for value in v]
             src.append("formats['%s'] = ['%s'];\n" % (javascript_quote(k), "', '".join(v)))
     return ''.join(src)
 
diff --git a/docs/howto/custom-model-fields.txt b/docs/howto/custom-model-fields.txt
index 706cc251290..e73ef9aa42b 100644
--- a/docs/howto/custom-model-fields.txt
+++ b/docs/howto/custom-model-fields.txt
@@ -688,7 +688,7 @@ smoothly:
 2. Put a :meth:`__str__` or :meth:`__unicode__` method on the class you're
    wrapping up as a field. There are a lot of places where the default
    behavior of the field code is to call
-   :func:`~django.utils.encoding.force_unicode` on the value. (In our
+   :func:`~django.utils.encoding.force_text` on the value. (In our
    examples in this document, ``value`` would be a ``Hand`` instance, not a
    ``HandField``). So if your :meth:`__unicode__` method automatically
    converts to the string form of your Python object, you can save yourself
diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt
index 74e6b48f074..92b5665beac 100644
--- a/docs/ref/databases.txt
+++ b/docs/ref/databases.txt
@@ -238,7 +238,7 @@ to you, the developer, to handle the fact that you will receive bytestrings if
 you configure your table(s) to use ``utf8_bin`` collation. Django itself should
 mostly work smoothly with such columns (except for the ``contrib.sessions``
 ``Session`` and ``contrib.admin`` ``LogEntry`` tables described below), but
-your code must be prepared to call ``django.utils.encoding.smart_unicode()`` at
+your code must be prepared to call ``django.utils.encoding.smart_text()`` at
 times if it really wants to work with consistent data -- Django will not do
 this for you (the database backend layer and the model population layer are
 separated internally so the database layer doesn't know it needs to make this
diff --git a/docs/ref/models/instances.txt b/docs/ref/models/instances.txt
index 509ea9d30e0..14541ad0d1c 100644
--- a/docs/ref/models/instances.txt
+++ b/docs/ref/models/instances.txt
@@ -453,9 +453,9 @@ using ``__str__()`` like this::
         last_name = models.CharField(max_length=50)
 
         def __str__(self):
-            # Note use of django.utils.encoding.smart_str() here because
+            # Note use of django.utils.encoding.smart_bytes() here because
             # first_name and last_name will be unicode strings.
-            return smart_str('%s %s' % (self.first_name, self.last_name))
+            return smart_bytes('%s %s' % (self.first_name, self.last_name))
 
 ``get_absolute_url``
 --------------------
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index 72d60453c38..531ff33da2e 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -183,7 +183,7 @@ compose a prefix, version and key into a final cache key. The default
 implementation is equivalent to the function::
 
     def make_key(key, key_prefix, version):
-        return ':'.join([key_prefix, str(version), smart_str(key)])
+        return ':'.join([key_prefix, str(version), smart_bytes(key)])
 
 You may use any key function you want, as long as it has the same
 argument signature.
diff --git a/docs/ref/unicode.txt b/docs/ref/unicode.txt
index b9253e70b31..ffab647379e 100644
--- a/docs/ref/unicode.txt
+++ b/docs/ref/unicode.txt
@@ -129,7 +129,7 @@ Conversion functions
 The ``django.utils.encoding`` module contains a few functions that are handy
 for converting back and forth between Unicode and bytestrings.
 
-* ``smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict')``
+* ``smart_text(s, encoding='utf-8', strings_only=False, errors='strict')``
   converts its input to a Unicode string. The ``encoding`` parameter
   specifies the input encoding. (For example, Django uses this internally
   when processing form input data, which might not be UTF-8 encoded.) The
@@ -139,27 +139,27 @@ for converting back and forth between Unicode and bytestrings.
   that are accepted by Python's ``unicode()`` function for its error
   handling.
 
-  If you pass ``smart_unicode()`` an object that has a ``__unicode__``
+  If you pass ``smart_text()`` an object that has a ``__unicode__``
   method, it will use that method to do the conversion.
 
-* ``force_unicode(s, encoding='utf-8', strings_only=False,
-  errors='strict')`` is identical to ``smart_unicode()`` in almost all
+* ``force_text(s, encoding='utf-8', strings_only=False,
+  errors='strict')`` is identical to ``smart_text()`` in almost all
   cases. The difference is when the first argument is a :ref:`lazy
-  translation <lazy-translations>` instance. While ``smart_unicode()``
-  preserves lazy translations, ``force_unicode()`` forces those objects to a
+  translation <lazy-translations>` instance. While ``smart_text()``
+  preserves lazy translations, ``force_text()`` forces those objects to a
   Unicode string (causing the translation to occur). Normally, you'll want
-  to use ``smart_unicode()``. However, ``force_unicode()`` is useful in
+  to use ``smart_text()``. However, ``force_text()`` is useful in
   template tags and filters that absolutely *must* have a string to work
   with, not just something that can be converted to a string.
 
-* ``smart_str(s, encoding='utf-8', strings_only=False, errors='strict')``
-  is essentially the opposite of ``smart_unicode()``. It forces the first
+* ``smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict')``
+  is essentially the opposite of ``smart_text()``. It forces the first
   argument to a bytestring. The ``strings_only`` parameter has the same
-  behavior as for ``smart_unicode()`` and ``force_unicode()``. This is
+  behavior as for ``smart_text()`` and ``force_text()``. This is
   slightly different semantics from Python's builtin ``str()`` function,
   but the difference is needed in a few places within Django's internals.
 
-Normally, you'll only need to use ``smart_unicode()``. Call it as early as
+Normally, you'll only need to use ``smart_text()``. Call it as early as
 possible on any input data that might be either Unicode or a bytestring, and
 from then on, you can treat the result as always being Unicode.
 
@@ -324,7 +324,7 @@ A couple of tips to remember when writing your own template tags and filters:
 * Always return Unicode strings from a template tag's ``render()`` method
   and from template filters.
 
-* Use ``force_unicode()`` in preference to ``smart_unicode()`` in these
+* Use ``force_text()`` in preference to ``smart_text()`` in these
   places. Tag rendering and filter calls occur as the template is being
   rendered, so there is no advantage to postponing the conversion of lazy
   translation objects into strings. It's easier to work solely with Unicode
diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt
index 5157c399da7..b6cb1035d3d 100644
--- a/docs/ref/utils.txt
+++ b/docs/ref/utils.txt
@@ -178,33 +178,53 @@ The functions defined in this module share the following properties:
 
 .. class:: StrAndUnicode
 
-    A class whose ``__str__`` returns its ``__unicode__`` as a UTF-8
-    bytestring. Useful as a mix-in.
+    A class that derives ``__str__`` from ``__unicode__``.
 
-.. function:: smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict')
+    On Python 2, ``__str__`` returns the output of ``__unicode__`` encoded as
+    a UTF-8 bytestring. On Python 3, ``__str__`` returns the output of
+    ``__unicode__``.
 
-    Returns a ``unicode`` object representing ``s``. Treats bytestrings using
-    the 'encoding' codec.
+    Useful as a mix-in. If you support Python 2 and 3 with a single code base,
+    you can inherit this mix-in and just define ``__unicode__``.
+
+.. function:: smart_text(s, encoding='utf-8', strings_only=False, errors='strict')
+
+    .. versionadded:: 1.5
+
+    Returns a text object representing ``s`` -- ``unicode`` on Python 2 and
+    ``str`` on Python 3. Treats bytestrings using the ``encoding`` codec.
 
     If ``strings_only`` is ``True``, don't convert (some) non-string-like
     objects.
 
+.. function:: smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict')
+
+    Historical name of :func:`smart_text`. Only available under Python 2.
+
 .. function:: is_protected_type(obj)
 
     Determine if the object instance is of a protected type.
 
     Objects of protected types are preserved as-is when passed to
-    ``force_unicode(strings_only=True)``.
+    ``force_text(strings_only=True)``.
 
-.. function:: force_unicode(s, encoding='utf-8', strings_only=False, errors='strict')
+.. function:: force_text(s, encoding='utf-8', strings_only=False, errors='strict')
 
-    Similar to ``smart_unicode``, except that lazy instances are resolved to
+    .. versionadded:: 1.5
+
+    Similar to ``smart_text``, except that lazy instances are resolved to
     strings, rather than kept as lazy objects.
 
     If ``strings_only`` is ``True``, don't convert (some) non-string-like
     objects.
 
-.. function:: smart_str(s, encoding='utf-8', strings_only=False, errors='strict')
+.. function:: force_unicode(s, encoding='utf-8', strings_only=False, errors='strict')
+
+    Historical name of :func:`force_text`. Only available under Python 2.
+
+.. function:: smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict')
+
+    .. versionadded:: 1.5
 
     Returns a bytestring version of ``s``, encoded as specified in
     ``encoding``.
@@ -212,6 +232,14 @@ The functions defined in this module share the following properties:
     If ``strings_only`` is ``True``, don't convert (some) non-string-like
     objects.
 
+.. function:: smart_str(s, encoding='utf-8', strings_only=False, errors='strict')
+
+    Alias of :func:`smart_bytes` on Python 2 and :func:`smart_text` on Python
+    3. This function always returns a :class:`str`.
+
+    For instance, this is  suitable for writing to :attr:`sys.stdout` on
+    Python 2 and 3.
+
 .. function:: iri_to_uri(iri)
 
     Convert an Internationalized Resource Identifier (IRI) portion to a URI
@@ -406,7 +434,7 @@ escaping HTML.
 
     Returns the given text with ampersands, quotes and angle brackets encoded
     for use in HTML. The input is first passed through
-    :func:`~django.utils.encoding.force_unicode` and the output has
+    :func:`~django.utils.encoding.force_text` and the output has
     :func:`~django.utils.safestring.mark_safe` applied.
 
 .. function:: conditional_escape(text)
@@ -448,7 +476,7 @@ escaping HTML.
     interpolation, some of the formatting options provided by `str.format`_
     (e.g. number formatting) will not work, since all arguments are passed
     through :func:`conditional_escape` which (ultimately) calls
-    :func:`~django.utils.encoding.force_unicode` on the values.
+    :func:`~django.utils.encoding.force_text` on the values.
 
 
 .. _str.format: http://docs.python.org/library/stdtypes.html#str.format
diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt
index d58d3cadf4f..f789ebde40d 100644
--- a/docs/releases/1.5.txt
+++ b/docs/releases/1.5.txt
@@ -161,7 +161,7 @@ If you have written a :ref:`custom password hasher <auth_password_storage>`,
 your ``encode()``, ``verify()`` or ``safe_summary()`` methods should accept
 Unicode parameters (``password``, ``salt`` or ``encoded``). If any of the
 hashing methods need byte strings, you can use the
-:func:`~django.utils.encoding.smart_str` utility to encode the strings.
+:func:`~django.utils.encoding.smart_bytes` utility to encode the strings.
 
 Validation of previous_page_number and next_page_number
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/topics/cache.txt b/docs/topics/cache.txt
index d0bd9f69929..219b6c77957 100644
--- a/docs/topics/cache.txt
+++ b/docs/topics/cache.txt
@@ -864,7 +864,7 @@ key version to provide a final cache key. By default, the three parts
 are joined using colons to produce a final string::
 
     def make_key(key, key_prefix, version):
-        return ':'.join([key_prefix, str(version), smart_str(key)])
+        return ':'.join([key_prefix, str(version), smart_bytes(key)])
 
 If you want to combine the parts in different ways, or apply other
 processing to the final key (e.g., taking a hash digest of the key
diff --git a/docs/topics/serialization.txt b/docs/topics/serialization.txt
index 505ac17f09d..ac1a77ed987 100644
--- a/docs/topics/serialization.txt
+++ b/docs/topics/serialization.txt
@@ -173,12 +173,12 @@ In particular, :ref:`lazy translation objects <lazy-translations>` need a
 
     import json
     from django.utils.functional import Promise
-    from django.utils.encoding import force_unicode
+    from django.utils.encoding import force_text
 
     class LazyEncoder(json.JSONEncoder):
         def default(self, obj):
             if isinstance(obj, Promise):
-                return force_unicode(obj)
+                return force_text(obj)
             return super(LazyEncoder, self).default(obj)
 
 .. _special encoder: http://docs.python.org/library/json.html#encoders-and-decoders
diff --git a/tests/modeltests/field_subclassing/fields.py b/tests/modeltests/field_subclassing/fields.py
index a21085de9d5..0d4ff98aa76 100644
--- a/tests/modeltests/field_subclassing/fields.py
+++ b/tests/modeltests/field_subclassing/fields.py
@@ -3,7 +3,7 @@ from __future__ import unicode_literals
 import json
 
 from django.db import models
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils import six
 
 
@@ -16,7 +16,7 @@ class Small(object):
         self.first, self.second = first, second
 
     def __unicode__(self):
-        return '%s%s' % (force_unicode(self.first), force_unicode(self.second))
+        return '%s%s' % (force_text(self.first), force_text(self.second))
 
     def __str__(self):
         return six.text_type(self).encode('utf-8')
@@ -46,9 +46,9 @@ class SmallField(models.Field):
 
     def get_prep_lookup(self, lookup_type, value):
         if lookup_type == 'exact':
-            return force_unicode(value)
+            return force_text(value)
         if lookup_type == 'in':
-            return [force_unicode(v) for v in value]
+            return [force_text(v) for v in value]
         if lookup_type == 'isnull':
             return []
         raise TypeError('Invalid lookup type: %r' % lookup_type)
diff --git a/tests/modeltests/field_subclassing/models.py b/tests/modeltests/field_subclassing/models.py
index 5e3c3769761..2df9664cdc0 100644
--- a/tests/modeltests/field_subclassing/models.py
+++ b/tests/modeltests/field_subclassing/models.py
@@ -5,7 +5,7 @@ Tests for field subclassing.
 from __future__ import absolute_import
 
 from django.db import models
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 
 from .fields import SmallField, SmallerField, JSONField
 
@@ -15,7 +15,7 @@ class MyModel(models.Model):
     data = SmallField('small field')
 
     def __unicode__(self):
-        return force_unicode(self.name)
+        return force_text(self.name)
 
 class OtherModel(models.Model):
     data = SmallerField()
diff --git a/tests/regressiontests/admin_filters/tests.py b/tests/regressiontests/admin_filters/tests.py
index 72cc5d7ee5c..b92c2f4c8bd 100644
--- a/tests/regressiontests/admin_filters/tests.py
+++ b/tests/regressiontests/admin_filters/tests.py
@@ -10,7 +10,7 @@ from django.contrib.auth.models import User
 from django.core.exceptions import ImproperlyConfigured
 from django.test import TestCase, RequestFactory
 from django.test.utils import override_settings
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 
 from .models import Book, Department, Employee
 
@@ -160,7 +160,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][4]
-        self.assertEqual(force_unicode(filterspec.title), 'date registered')
+        self.assertEqual(force_text(filterspec.title), 'date registered')
         choice = select_by(filterspec.choices(changelist), "display", "Today")
         self.assertEqual(choice['selected'], True)
         self.assertEqual(choice['query_string'], '?date_registered__gte=%s'
@@ -181,7 +181,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][4]
-        self.assertEqual(force_unicode(filterspec.title), 'date registered')
+        self.assertEqual(force_text(filterspec.title), 'date registered')
         choice = select_by(filterspec.choices(changelist), "display", "This month")
         self.assertEqual(choice['selected'], True)
         self.assertEqual(choice['query_string'], '?date_registered__gte=%s'
@@ -202,7 +202,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][4]
-        self.assertEqual(force_unicode(filterspec.title), 'date registered')
+        self.assertEqual(force_text(filterspec.title), 'date registered')
         choice = select_by(filterspec.choices(changelist), "display", "This year")
         self.assertEqual(choice['selected'], True)
         self.assertEqual(choice['query_string'], '?date_registered__gte=%s'
@@ -219,7 +219,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][4]
-        self.assertEqual(force_unicode(filterspec.title), 'date registered')
+        self.assertEqual(force_text(filterspec.title), 'date registered')
         choice = select_by(filterspec.choices(changelist), "display", "Past 7 days")
         self.assertEqual(choice['selected'], True)
         self.assertEqual(choice['query_string'], '?date_registered__gte=%s'
@@ -243,7 +243,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the last choice is None and is selected
         filterspec = changelist.get_filters(request)[0][0]
-        self.assertEqual(force_unicode(filterspec.title), 'year')
+        self.assertEqual(force_text(filterspec.title), 'year')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(choices[-1]['selected'], True)
         self.assertEqual(choices[-1]['query_string'], '?year__isnull=True')
@@ -253,7 +253,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][0]
-        self.assertEqual(force_unicode(filterspec.title), 'year')
+        self.assertEqual(force_text(filterspec.title), 'year')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(choices[2]['selected'], True)
         self.assertEqual(choices[2]['query_string'], '?year=2002')
@@ -270,7 +270,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the last choice is None and is selected
         filterspec = changelist.get_filters(request)[0][1]
-        self.assertEqual(force_unicode(filterspec.title), 'Verbose Author')
+        self.assertEqual(force_text(filterspec.title), 'Verbose Author')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(choices[-1]['selected'], True)
         self.assertEqual(choices[-1]['query_string'], '?author__isnull=True')
@@ -280,7 +280,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][1]
-        self.assertEqual(force_unicode(filterspec.title), 'Verbose Author')
+        self.assertEqual(force_text(filterspec.title), 'Verbose Author')
         # order of choices depends on User model, which has no order
         choice = select_by(filterspec.choices(changelist), "display", "alfred")
         self.assertEqual(choice['selected'], True)
@@ -298,7 +298,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the last choice is None and is selected
         filterspec = changelist.get_filters(request)[0][2]
-        self.assertEqual(force_unicode(filterspec.title), 'Verbose Contributors')
+        self.assertEqual(force_text(filterspec.title), 'Verbose Contributors')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(choices[-1]['selected'], True)
         self.assertEqual(choices[-1]['query_string'], '?contributors__isnull=True')
@@ -308,7 +308,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][2]
-        self.assertEqual(force_unicode(filterspec.title), 'Verbose Contributors')
+        self.assertEqual(force_text(filterspec.title), 'Verbose Contributors')
         choice = select_by(filterspec.choices(changelist), "display", "bob")
         self.assertEqual(choice['selected'], True)
         self.assertEqual(choice['query_string'], '?contributors__id__exact=%d' % self.bob.pk)
@@ -326,7 +326,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the last choice is None and is selected
         filterspec = changelist.get_filters(request)[0][0]
-        self.assertEqual(force_unicode(filterspec.title), 'book')
+        self.assertEqual(force_text(filterspec.title), 'book')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(choices[-1]['selected'], True)
         self.assertEqual(choices[-1]['query_string'], '?books_authored__isnull=True')
@@ -336,7 +336,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][0]
-        self.assertEqual(force_unicode(filterspec.title), 'book')
+        self.assertEqual(force_text(filterspec.title), 'book')
         choice = select_by(filterspec.choices(changelist), "display", self.bio_book.title)
         self.assertEqual(choice['selected'], True)
         self.assertEqual(choice['query_string'], '?books_authored__id__exact=%d' % self.bio_book.pk)
@@ -351,7 +351,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the last choice is None and is selected
         filterspec = changelist.get_filters(request)[0][1]
-        self.assertEqual(force_unicode(filterspec.title), 'book')
+        self.assertEqual(force_text(filterspec.title), 'book')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(choices[-1]['selected'], True)
         self.assertEqual(choices[-1]['query_string'], '?books_contributed__isnull=True')
@@ -361,7 +361,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][1]
-        self.assertEqual(force_unicode(filterspec.title), 'book')
+        self.assertEqual(force_text(filterspec.title), 'book')
         choice = select_by(filterspec.choices(changelist), "display", self.django_book.title)
         self.assertEqual(choice['selected'], True)
         self.assertEqual(choice['query_string'], '?books_contributed__id__exact=%d' % self.django_book.pk)
@@ -387,7 +387,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][3]
-        self.assertEqual(force_unicode(filterspec.title), 'is best seller')
+        self.assertEqual(force_text(filterspec.title), 'is best seller')
         choice = select_by(filterspec.choices(changelist), "display", "No")
         self.assertEqual(choice['selected'], True)
         self.assertEqual(choice['query_string'], '?is_best_seller__exact=0')
@@ -401,7 +401,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][3]
-        self.assertEqual(force_unicode(filterspec.title), 'is best seller')
+        self.assertEqual(force_text(filterspec.title), 'is best seller')
         choice = select_by(filterspec.choices(changelist), "display", "Yes")
         self.assertEqual(choice['selected'], True)
         self.assertEqual(choice['query_string'], '?is_best_seller__exact=1')
@@ -415,7 +415,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][3]
-        self.assertEqual(force_unicode(filterspec.title), 'is best seller')
+        self.assertEqual(force_text(filterspec.title), 'is best seller')
         choice = select_by(filterspec.choices(changelist), "display", "Unknown")
         self.assertEqual(choice['selected'], True)
         self.assertEqual(choice['query_string'], '?is_best_seller__isnull=True')
@@ -434,7 +434,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][1]
-        self.assertEqual(force_unicode(filterspec.title), 'publication decade')
+        self.assertEqual(force_text(filterspec.title), 'publication decade')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(choices[0]['display'], 'All')
         self.assertEqual(choices[0]['selected'], True)
@@ -451,7 +451,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][1]
-        self.assertEqual(force_unicode(filterspec.title), 'publication decade')
+        self.assertEqual(force_text(filterspec.title), 'publication decade')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(choices[1]['display'], 'the 1980\'s')
         self.assertEqual(choices[1]['selected'], True)
@@ -468,7 +468,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][1]
-        self.assertEqual(force_unicode(filterspec.title), 'publication decade')
+        self.assertEqual(force_text(filterspec.title), 'publication decade')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(choices[2]['display'], 'the 1990\'s')
         self.assertEqual(choices[2]['selected'], True)
@@ -485,7 +485,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][1]
-        self.assertEqual(force_unicode(filterspec.title), 'publication decade')
+        self.assertEqual(force_text(filterspec.title), 'publication decade')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(choices[3]['display'], 'the 2000\'s')
         self.assertEqual(choices[3]['selected'], True)
@@ -502,14 +502,14 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choices are selected
         filterspec = changelist.get_filters(request)[0][1]
-        self.assertEqual(force_unicode(filterspec.title), 'publication decade')
+        self.assertEqual(force_text(filterspec.title), 'publication decade')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(choices[3]['display'], 'the 2000\'s')
         self.assertEqual(choices[3]['selected'], True)
         self.assertEqual(choices[3]['query_string'], '?publication-decade=the+00s&author__id__exact=%s' % self.alfred.pk)
 
         filterspec = changelist.get_filters(request)[0][0]
-        self.assertEqual(force_unicode(filterspec.title), 'Verbose Author')
+        self.assertEqual(force_text(filterspec.title), 'Verbose Author')
         choice = select_by(filterspec.choices(changelist), "display", "alfred")
         self.assertEqual(choice['selected'], True)
         self.assertEqual(choice['query_string'], '?publication-decade=the+00s&author__id__exact=%s' % self.alfred.pk)
@@ -561,7 +561,7 @@ class ListFiltersTests(TestCase):
         changelist = self.get_changelist(request, Book, modeladmin)
 
         filterspec = changelist.get_filters(request)[0][0]
-        self.assertEqual(force_unicode(filterspec.title), 'publication decade')
+        self.assertEqual(force_text(filterspec.title), 'publication decade')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(len(choices), 3)
 
@@ -591,7 +591,7 @@ class ListFiltersTests(TestCase):
         self.assertEqual(list(queryset), [self.bio_book])
 
         filterspec = changelist.get_filters(request)[0][-1]
-        self.assertEqual(force_unicode(filterspec.title), 'number')
+        self.assertEqual(force_text(filterspec.title), 'number')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(choices[2]['selected'], True)
         self.assertEqual(choices[2]['query_string'], '?no=207')
@@ -614,7 +614,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][0]
-        self.assertEqual(force_unicode(filterspec.title), 'publication decade')
+        self.assertEqual(force_text(filterspec.title), 'publication decade')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(choices[2]['display'], 'the 1990\'s')
         self.assertEqual(choices[2]['selected'], True)
@@ -631,7 +631,7 @@ class ListFiltersTests(TestCase):
 
         # Make sure the correct choice is selected
         filterspec = changelist.get_filters(request)[0][0]
-        self.assertEqual(force_unicode(filterspec.title), 'publication decade')
+        self.assertEqual(force_text(filterspec.title), 'publication decade')
         choices = list(filterspec.choices(changelist))
         self.assertEqual(choices[2]['display'], 'the 1990\'s')
         self.assertEqual(choices[2]['selected'], True)
@@ -657,7 +657,7 @@ class ListFiltersTests(TestCase):
         self.assertEqual(list(queryset), [jack, john])
 
         filterspec = changelist.get_filters(request)[0][-1]
-        self.assertEqual(force_unicode(filterspec.title), 'department')
+        self.assertEqual(force_text(filterspec.title), 'department')
         choices = list(filterspec.choices(changelist))
 
         self.assertEqual(choices[0]['display'], 'All')
@@ -682,7 +682,7 @@ class ListFiltersTests(TestCase):
         self.assertEqual(list(queryset), [john])
 
         filterspec = changelist.get_filters(request)[0][-1]
-        self.assertEqual(force_unicode(filterspec.title), 'department')
+        self.assertEqual(force_text(filterspec.title), 'department')
         choices = list(filterspec.choices(changelist))
 
         self.assertEqual(choices[0]['display'], 'All')
diff --git a/tests/regressiontests/admin_views/admin.py b/tests/regressiontests/admin_views/admin.py
index 6ec933f89b5..293ddfebf6a 100644
--- a/tests/regressiontests/admin_views/admin.py
+++ b/tests/regressiontests/admin_views/admin.py
@@ -630,7 +630,7 @@ site.register(UndeletableObject, UndeletableObjectAdmin)
 #     related OneToOne object registered in admin
 #     related OneToOne object not registered in admin
 # when deleting Book so as exercise all four troublesome (w.r.t escaping
-# and calling force_unicode to avoid problems on Python 2.3) paths through
+# and calling force_text to avoid problems on Python 2.3) paths through
 # contrib.admin.util's get_deleted_objects function.
 site.register(Book, inlines=[ChapterInline])
 site.register(Promo)
diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py
index 264ef74abd3..8fc749aaa27 100644
--- a/tests/regressiontests/cache/tests.py
+++ b/tests/regressiontests/cache/tests.py
@@ -28,7 +28,7 @@ from django.test.utils import (get_warnings_state, restore_warnings_state,
 from django.utils import timezone, translation, unittest
 from django.utils.cache import (patch_vary_headers, get_cache_key,
     learn_cache_key, patch_cache_control, patch_response_headers)
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.views.decorators.cache import cache_page
 
 from .models import Poll, expensive_calculation
@@ -1307,7 +1307,7 @@ class CacheI18nTest(TestCase):
         request = self._get_request()
         # This is tightly coupled to the implementation,
         # but it's the most straightforward way to test the key.
-        tz = force_unicode(timezone.get_current_timezone_name(), errors='ignore')
+        tz = force_text(timezone.get_current_timezone_name(), errors='ignore')
         tz = tz.encode('ascii', 'ignore').replace(' ', '_')
         response = HttpResponse()
         key = learn_cache_key(request, response)
@@ -1319,7 +1319,7 @@ class CacheI18nTest(TestCase):
     def test_cache_key_no_i18n (self):
         request = self._get_request()
         lang = translation.get_language()
-        tz = force_unicode(timezone.get_current_timezone_name(), errors='ignore')
+        tz = force_text(timezone.get_current_timezone_name(), errors='ignore')
         tz = tz.encode('ascii', 'ignore').replace(' ', '_')
         response = HttpResponse()
         key = learn_cache_key(request, response)
diff --git a/tests/regressiontests/forms/tests/extra.py b/tests/regressiontests/forms/tests/extra.py
index 28b6c124530..e0e62858d02 100644
--- a/tests/regressiontests/forms/tests/extra.py
+++ b/tests/regressiontests/forms/tests/extra.py
@@ -9,7 +9,7 @@ from django.forms.extras import SelectDateWidget
 from django.forms.util import ErrorList
 from django.test import TestCase
 from django.utils import translation
-from django.utils.encoding import force_unicode, smart_unicode
+from django.utils.encoding import force_text, smart_text
 
 from .error_messages import AssertFormErrorsMixin
 
@@ -551,7 +551,7 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
         f = GenericIPAddressField(unpack_ipv4=True)
         self.assertEqual(f.clean('::ffff:0a0a:0a0a'), '10.10.10.10')
 
-    def test_smart_unicode(self):
+    def test_smart_text(self):
         class Test:
             def __str__(self):
                return 'ŠĐĆŽćžšđ'.encode('utf-8')
@@ -562,10 +562,10 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
             def __unicode__(self):
                return '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
 
-        self.assertEqual(smart_unicode(Test()), '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
-        self.assertEqual(smart_unicode(TestU()), '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
-        self.assertEqual(smart_unicode(1), '1')
-        self.assertEqual(smart_unicode('foo'), 'foo')
+        self.assertEqual(smart_text(Test()), '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
+        self.assertEqual(smart_text(TestU()), '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
+        self.assertEqual(smart_text(1), '1')
+        self.assertEqual(smart_text('foo'), 'foo')
 
     def test_accessing_clean(self):
         class UserForm(Form):
@@ -591,7 +591,7 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
 
             def as_divs(self):
                 if not self: return ''
-                return '<div class="errorlist">%s</div>' % ''.join(['<div class="error">%s</div>' % force_unicode(e) for e in self])
+                return '<div class="errorlist">%s</div>' % ''.join(['<div class="error">%s</div>' % force_text(e) for e in self])
 
         class CommentForm(Form):
             name = CharField(max_length=50, required=False)
diff --git a/tests/regressiontests/signing/tests.py b/tests/regressiontests/signing/tests.py
index f3fe5f3ec71..2368405060e 100644
--- a/tests/regressiontests/signing/tests.py
+++ b/tests/regressiontests/signing/tests.py
@@ -4,7 +4,7 @@ import time
 
 from django.core import signing
 from django.test import TestCase
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 
 
 class TestSigner(TestCase):
@@ -48,7 +48,7 @@ class TestSigner(TestCase):
         )
         for example in examples:
             self.assertNotEqual(
-                force_unicode(example), force_unicode(signer.sign(example)))
+                force_text(example), force_text(signer.sign(example)))
             self.assertEqual(example, signer.unsign(signer.sign(example)))
 
     def unsign_detects_tampering(self):
diff --git a/tests/regressiontests/staticfiles_tests/tests.py b/tests/regressiontests/staticfiles_tests/tests.py
index 2c038e1713f..19951f100ba 100644
--- a/tests/regressiontests/staticfiles_tests/tests.py
+++ b/tests/regressiontests/staticfiles_tests/tests.py
@@ -17,7 +17,7 @@ from django.core.files.storage import default_storage
 from django.core.management import call_command
 from django.test import TestCase
 from django.test.utils import override_settings
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
 from django.utils.functional import empty
 from django.utils._os import rmtree_errorhandler
 from django.utils import six
@@ -80,7 +80,7 @@ class BaseStaticFilesTestCase(object):
         os.unlink(self._backup_filepath)
 
     def assertFileContains(self, filepath, text):
-        self.assertIn(text, self._get_file(smart_unicode(filepath)),
+        self.assertIn(text, self._get_file(smart_text(filepath)),
                         "'%s' not in '%s'" % (text, filepath))
 
     def assertFileNotFound(self, filepath):
@@ -199,7 +199,7 @@ class TestFindStatic(CollectionTestCase, TestDefaults):
         out.seek(0)
         lines = [l.strip() for l in out.readlines()]
         contents = codecs.open(
-            smart_unicode(lines[1].strip()), "r", "utf-8").read()
+            smart_text(lines[1].strip()), "r", "utf-8").read()
         return contents
 
     def test_all_files(self):

From a8b3ddec5f05268b67b3efe6a7dc6accb1bac715 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Sat, 21 Jul 2012 10:01:46 +0200
Subject: [PATCH 52/88] [py3] Applied minor fixes so the test suite starts

---
 django/core/management/base.py      |  4 +--
 django/db/models/base.py            | 47 +++++++++++++++--------------
 django/db/models/fields/__init__.py |  2 ++
 django/test/client.py               |  4 +--
 4 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/django/core/management/base.py b/django/core/management/base.py
index a204f6f0bcb..5e630d52070 100644
--- a/django/core/management/base.py
+++ b/django/core/management/base.py
@@ -6,7 +6,6 @@ be executed through ``django-admin.py`` or ``manage.py``).
 import os
 import sys
 
-from io import BytesIO
 from optparse import make_option, OptionParser
 import traceback
 
@@ -14,6 +13,7 @@ import django
 from django.core.exceptions import ImproperlyConfigured
 from django.core.management.color import color_style
 from django.utils.encoding import smart_str
+from django.utils.six import StringIO
 
 
 class CommandError(Exception):
@@ -273,7 +273,7 @@ class BaseCommand(object):
 
         """
         from django.core.management.validation import get_validation_errors
-        s = BytesIO()
+        s = StringIO()
         num_errors = get_validation_errors(s, app)
         if num_errors:
             s.seek(0)
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 4568430bfaf..35ae2231d66 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -28,6 +28,30 @@ from django.utils import six
 from django.utils.text import get_text_list, capfirst
 
 
+def subclass_exception(name, parents, module, attached_to=None):
+    """
+    Create exception subclass. Used by ModelBase below.
+
+    If 'attached_to' is supplied, the exception will be created in a way that
+    allows it to be pickled, assuming the returned exception class will be added
+    as an attribute to the 'attached_to' class.
+    """
+    class_dict = {'__module__': module}
+    if attached_to is not None:
+        def __reduce__(self):
+            # Exceptions are special - they've got state that isn't
+            # in self.__dict__. We assume it is all in self.args.
+            return (unpickle_inner_exception, (attached_to, name), self.args)
+
+        def __setstate__(self, args):
+            self.args = args
+
+        class_dict['__reduce__'] = __reduce__
+        class_dict['__setstate__'] = __setstate__
+
+    return type(name, parents, class_dict)
+
+
 class ModelBase(type):
     """
     Metaclass for all models.
@@ -929,29 +953,6 @@ def model_unpickle(model, attrs):
     return cls.__new__(cls)
 model_unpickle.__safe_for_unpickle__ = True
 
-def subclass_exception(name, parents, module, attached_to=None):
-    """
-    Create exception subclass.
-
-    If 'attached_to' is supplied, the exception will be created in a way that
-    allows it to be pickled, assuming the returned exception class will be added
-    as an attribute to the 'attached_to' class.
-    """
-    class_dict = {'__module__': module}
-    if attached_to is not None:
-        def __reduce__(self):
-            # Exceptions are special - they've got state that isn't
-            # in self.__dict__. We assume it is all in self.args.
-            return (unpickle_inner_exception, (attached_to, name), self.args)
-
-        def __setstate__(self, args):
-            self.args = args
-
-        class_dict['__reduce__'] = __reduce__
-        class_dict['__setstate__'] = __setstate__
-
-    return type(name, parents, class_dict)
-
 def unpickle_inner_exception(klass, exception_name):
     # Get the exception class from the class it is attached to:
     exception = getattr(klass, exception_name)
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 2c738d6a20f..2c38e8d72e0 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -135,6 +135,8 @@ class Field(object):
             return self.creation_counter < other.creation_counter
         return NotImplemented
 
+    __hash__ = object.__hash__
+
     def __deepcopy__(self, memodict):
         # We don't have to deepcopy very much here, since most things are not
         # intended to be altered after initial creation.
diff --git a/django/test/client.py b/django/test/client.py
index ef80a7129a3..a9ae7f5db10 100644
--- a/django/test/client.py
+++ b/django/test/client.py
@@ -194,9 +194,9 @@ class RequestFactory(object):
             'SERVER_NAME':       'testserver',
             'SERVER_PORT':       '80',
             'SERVER_PROTOCOL':   'HTTP/1.1',
-            'wsgi.version':      (1,0),
+            'wsgi.version':      (1, 0),
             'wsgi.url_scheme':   'http',
-            'wsgi.input':        FakePayload(''),
+            'wsgi.input':        FakePayload(b''),
             'wsgi.errors':       self.errors,
             'wsgi.multiprocess': True,
             'wsgi.multithread':  False,

From 67646dc28d6fc7b4032f1f5a18a5347e81755638 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Fri, 3 Aug 2012 23:00:22 +0200
Subject: [PATCH 53/88] [py3] Ported django.test.doctest.

Based on Vinay Sajip's branch.
---
 django/test/_doctest.py | 119 ++++++++++++++++++++++++++++++++++------
 1 file changed, 103 insertions(+), 16 deletions(-)

diff --git a/django/test/_doctest.py b/django/test/_doctest.py
index 316c785f336..82d4a6d08ef 100644
--- a/django/test/_doctest.py
+++ b/django/test/_doctest.py
@@ -105,7 +105,7 @@ import unittest, difflib, pdb, tempfile
 import warnings
 
 from django.utils import six
-from django.utils.six import StringIO
+from django.utils.six.moves import StringIO, xrange
 
 if sys.platform.startswith('java'):
     # On Jython, isclass() reports some modules as classes. Patch it.
@@ -501,11 +501,31 @@ class DocTest:
 
 
     # This lets us sort tests by name:
+    def _cmpkey(self):
+        return (self.name, self.filename, self.lineno, id(self))
     def __cmp__(self, other):
         if not isinstance(other, DocTest):
             return -1
-        return cmp((self.name, self.filename, self.lineno, id(self)),
-                   (other.name, other.filename, other.lineno, id(other)))
+        return cmp(self._cmpkey(), other._cmpkey())
+
+    def __lt__(self, other):
+        return self._cmpkey() < other._cmpkey()
+
+    def __le__(self, other):
+        return self._cmpkey() <= other._cmpkey()
+
+    def __gt__(self, other):
+        return self._cmpkey() > other._cmpkey()
+
+    def __ge__(self, other):
+        return self._cmpkey() >= other._cmpkey()
+
+    def __eq__(self, other):
+        return self._cmpkey() == other._cmpkey()
+
+    def __ne__(self, other):
+        return self._cmpkey() != other._cmpkey()
+
 
 ######################################################################
 ## 3. DocTestParser
@@ -1229,6 +1249,57 @@ class DocTestRunner:
             # __patched_linecache_getlines).
             filename = '<doctest %s[%d]>' % (test.name, examplenum)
 
+            # Doctest and Py3 issue:
+            # If the current example that we wish to run is going to fail
+            # because it expects a leading u"", then use an alternate displayhook
+            original_displayhook = sys.displayhook
+
+            if six.PY3:
+                 # only set alternate displayhook if Python 3.x or after
+                lines = []
+                def py3_displayhook(value):
+                    if value is None:
+                        # None should not be considered at all
+                        return original_displayhook(value)
+
+                    # Collect the repr output in one variable
+                    s = repr(value)
+                    # Strip b"" and u"" prefixes from the repr and expected output
+                    # TODO: better way of stripping the prefixes?
+                    expected = example.want
+                    expected = expected.strip() # be wary of newlines
+                    s = s.replace("u", "")
+                    s = s.replace("b", "")
+                    expected = expected.replace("u", "")
+                    expected = expected.replace("b", "")
+                    # single quote vs. double quote should not matter
+                    # default all quote marks to double quote
+                    s = s.replace("'", '"')
+                    expected = expected.replace("'", '"')
+
+                    # In case of multi-line expected result
+                    lines.append(s)
+
+                    # let them match
+                    if s == expected: # be wary of false positives here
+                        # they should be the same, print expected value
+                        sys.stdout.write("%s\n" % example.want.strip())
+
+                    # multi-line expected output, doctest uses loop
+                    elif len(expected.split("\n")) == len(lines):
+                        if "\n".join(lines) == expected:
+                            sys.stdout.write("%s\n" % example.want.strip())
+                        else:
+                            sys.stdout.write("%s\n" % repr(value))
+                    elif len(expected.split("\n")) != len(lines):
+                        # we are not done looping yet, do not print anything!
+                        pass
+
+                    else:
+                        sys.stdout.write("%s\n" % repr(value))
+
+                sys.displayhook = py3_displayhook
+
             # Run the example in the given context (globs), and record
             # any exception that gets raised.  (But don't intercept
             # keyboard interrupts.)
@@ -1243,9 +1314,14 @@ class DocTestRunner:
             except:
                 exception = sys.exc_info()
                 self.debugger.set_continue() # ==== Example Finished ====
+            finally:
+                # restore the original displayhook
+                sys.displayhook = original_displayhook
 
             got = self._fakeout.getvalue()  # the actual output
             self._fakeout.truncate(0)
+            # Python 3.1 requires seek after truncate
+            self._fakeout.seek(0)
             outcome = FAILURE   # guilty until proved innocent or insane
 
             # If the example executed without raising any exceptions,
@@ -1256,10 +1332,21 @@ class DocTestRunner:
 
             # The example raised an exception:  check if it was expected.
             else:
-                exc_info = sys.exc_info()
-                exc_msg = traceback.format_exception_only(*exc_info[:2])[-1]
+                exc_msg = traceback.format_exception_only(*exception[:2])[-1]
+                if six.PY3:
+                    # module name will be in group(1) and the expected
+                    # exception message will be in group(2)
+                    m = re.match(r'(.*)\.(\w+:.+\s)', exc_msg)
+                    # make sure there's a match
+                    if m != None:
+                        f_name = m.group(1)
+                        # check to see if m.group(1) contains the module name
+                        if f_name == exception[0].__module__:
+                            # strip the module name from exc_msg
+                            exc_msg = m.group(2)
+
                 if not quiet:
-                    got += _exception_traceback(exc_info)
+                    got += _exception_traceback(exception)
 
                 # If `example.exc_msg` is None, then we weren't expecting
                 # an exception.
@@ -1289,7 +1376,7 @@ class DocTestRunner:
             elif outcome is BOOM:
                 if not quiet:
                     self.report_unexpected_exception(out, test, example,
-                                                     exc_info)
+                                                     exception)
                 failures += 1
             else:
                 assert False, ("unknown outcome", outcome)
@@ -1629,8 +1716,8 @@ class DebugRunner(DocTestRunner):
          ...                                    {}, 'foo', 'foo.py', 0)
          >>> try:
          ...     runner.run(test)
-         ... except UnexpectedException as failure:
-         ...     pass
+         ... except UnexpectedException as e:
+         ...     failure = e
 
          >>> failure.test is test
          True
@@ -1657,8 +1744,8 @@ class DebugRunner(DocTestRunner):
 
          >>> try:
          ...    runner.run(test)
-         ... except DocTestFailure as failure:
-         ...    pass
+         ... except DocTestFailure as e:
+         ...    failure = e
 
        DocTestFailure objects provide access to the test:
 
@@ -2167,8 +2254,8 @@ class DocTestCase(unittest.TestCase):
              >>> case = DocTestCase(test)
              >>> try:
              ...     case.debug()
-             ... except UnexpectedException as failure:
-             ...     pass
+             ... except UnexpectedException as e:
+             ...     failure = e
 
            The UnexpectedException contains the test, the example, and
            the original exception:
@@ -2196,8 +2283,8 @@ class DocTestCase(unittest.TestCase):
 
              >>> try:
              ...    case.debug()
-             ... except DocTestFailure as failure:
-             ...    pass
+             ... except DocTestFailure as e:
+             ...    failure = e
 
            DocTestFailure objects provide access to the test:
 
@@ -2646,7 +2733,7 @@ __test__ = {"_TestClass": _TestClass,
             "whitespace normalization": r"""
                 If the whitespace normalization flag is used, then
                 differences in whitespace are ignored.
-                    >>> print(range(30)) #doctest: +NORMALIZE_WHITESPACE
+                    >>> print(list(xrange(30))) #doctest: +NORMALIZE_WHITESPACE
                     [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
                      15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
                      27, 28, 29]

From 13338a6314a6c7120b29a22d8256deb52465aa8f Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Sat, 4 Aug 2012 11:31:44 +0200
Subject: [PATCH 54/88] [py3] Minor cleanup in django.utils.archive.

---
 django/utils/archive.py | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/django/utils/archive.py b/django/utils/archive.py
index 6b5d73290f6..829b55dd283 100644
--- a/django/utils/archive.py
+++ b/django/utils/archive.py
@@ -23,7 +23,6 @@ THE SOFTWARE.
 """
 import os
 import shutil
-import sys
 import tarfile
 import zipfile
 
@@ -147,11 +146,11 @@ class TarArchive(BaseArchive):
             else:
                 try:
                     extracted = self._archive.extractfile(member)
-                except (KeyError, AttributeError):
+                except (KeyError, AttributeError) as exc:
                     # Some corrupt tar files seem to produce this
                     # (specifically bad symlinks)
-                    print ("In the tar file %s the member %s is invalid: %s" %
-                           (name, member.name, sys.exc_info()[1]))
+                    print("In the tar file %s the member %s is invalid: %s" %
+                            (name, member.name, exc))
                 else:
                     dirname = os.path.dirname(filename)
                     if dirname and not os.path.exists(dirname):

From b55e07771fdc9f9cc80fb099429774672aaf9be9 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Sat, 4 Aug 2012 11:17:04 +0200
Subject: [PATCH 55/88] [py3] Ported django.utils.baseconv.

---
 tests/regressiontests/utils/baseconv.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tests/regressiontests/utils/baseconv.py b/tests/regressiontests/utils/baseconv.py
index 75660d81198..cc413b4e8e0 100644
--- a/tests/regressiontests/utils/baseconv.py
+++ b/tests/regressiontests/utils/baseconv.py
@@ -1,10 +1,11 @@
 from unittest import TestCase
 from django.utils.baseconv import base2, base16, base36, base56, base62, base64, BaseConverter
+from django.utils.six.moves import xrange
 
 class TestBaseConv(TestCase):
 
     def test_baseconv(self):
-        nums = [-10 ** 10, 10 ** 10] + range(-100, 100)
+        nums = [-10 ** 10, 10 ** 10] + list(xrange(-100, 100))
         for converter in [base2, base16, base36, base56, base62, base64]:
             for i in nums:
                 self.assertEqual(i, converter.decode(converter.encode(i)))

From 127b461b11af985a52fb482f09c7cd7a08832f9d Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Sun, 5 Aug 2012 16:12:10 +0200
Subject: [PATCH 56/88] [py3] Ported django.utils.crypto.

---
 django/utils/crypto.py                | 11 ++++++-----
 tests/regressiontests/utils/crypto.py | 28 +++++++++++++++------------
 2 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/django/utils/crypto.py b/django/utils/crypto.py
index 1edbb43eb37..70a07e7fde4 100644
--- a/django/utils/crypto.py
+++ b/django/utils/crypto.py
@@ -50,7 +50,7 @@ def salted_hmac(key_salt, value, secret=None):
     # line is redundant and could be replaced by key = key_salt + secret, since
     # the hmac module does the same thing for keys longer than the block size.
     # However, we need to ensure that we *always* do this.
-    return hmac.new(key, msg=value, digestmod=hashlib.sha1)
+    return hmac.new(key, msg=smart_bytes(value), digestmod=hashlib.sha1)
 
 
 def get_random_string(length=12,
@@ -99,7 +99,7 @@ def _bin_to_long(x):
 
     This is a clever optimization for fast xor vector math
     """
-    return int(x.encode('hex'), 16)
+    return int(binascii.hexlify(x), 16)
 
 
 def _long_to_bin(x, hex_format_string):
@@ -112,13 +112,14 @@ def _long_to_bin(x, hex_format_string):
 
 def _fast_hmac(key, msg, digest):
     """
-    A trimmed down version of Python's HMAC implementation
+    A trimmed down version of Python's HMAC implementation.
+
+    This function operates on bytes.
     """
     dig1, dig2 = digest(), digest()
-    key = smart_bytes(key)
     if len(key) > dig1.block_size:
         key = digest(key).digest()
-    key += chr(0) * (dig1.block_size - len(key))
+    key += b'\x00' * (dig1.block_size - len(key))
     dig1.update(key.translate(_trans_36))
     dig1.update(msg)
     dig2.update(key.translate(_trans_5c))
diff --git a/tests/regressiontests/utils/crypto.py b/tests/regressiontests/utils/crypto.py
index 2bdc5ba5309..52a286cb27e 100644
--- a/tests/regressiontests/utils/crypto.py
+++ b/tests/regressiontests/utils/crypto.py
@@ -1,4 +1,6 @@
+from __future__ import unicode_literals
 
+import binascii
 import math
 import timeit
 import hashlib
@@ -108,15 +110,15 @@ class TestUtilsCryptoPBKDF2(unittest.TestCase):
                        "c4007d5298f9033c0241d5ab69305e7b64eceeb8d"
                        "834cfec"),
         },
-        # Check leading zeros are not stripped (#17481) 
+        # Check leading zeros are not stripped (#17481)
         {
-            "args": { 
-                "password": chr(186), 
-                "salt": "salt", 
-                "iterations": 1, 
-                "dklen": 20, 
-                "digest": hashlib.sha1, 
-            }, 
+            "args": {
+                "password": b'\xba',
+                "salt": "salt",
+                "iterations": 1,
+                "dklen": 20,
+                "digest": hashlib.sha1,
+            },
             "result": '0053d3b91a7f1e54effebd6d68771e8a6e0b2c5b',
         },
     ]
@@ -124,12 +126,14 @@ class TestUtilsCryptoPBKDF2(unittest.TestCase):
     def test_public_vectors(self):
         for vector in self.rfc_vectors:
             result = pbkdf2(**vector['args'])
-            self.assertEqual(result.encode('hex'), vector['result'])
+            self.assertEqual(binascii.hexlify(result).decode('ascii'),
+                             vector['result'])
 
     def test_regression_vectors(self):
         for vector in self.regression_vectors:
             result = pbkdf2(**vector['args'])
-            self.assertEqual(result.encode('hex'), vector['result'])
+            self.assertEqual(binascii.hexlify(result).decode('ascii'),
+                             vector['result'])
 
     def test_performance_scalability(self):
         """
@@ -140,11 +144,11 @@ class TestUtilsCryptoPBKDF2(unittest.TestCase):
         # to run the test suite and false positives caused by imprecise
         # measurement.
         n1, n2 = 200000, 800000
-        elapsed = lambda f: timeit.Timer(f, 
+        elapsed = lambda f: timeit.Timer(f,
                     'from django.utils.crypto import pbkdf2').timeit(number=1)
         t1 = elapsed('pbkdf2("password", "salt", iterations=%d)' % n1)
         t2 = elapsed('pbkdf2("password", "salt", iterations=%d)' % n2)
         measured_scale_exponent = math.log(t2 / t1, n2 / n1)
-        # This should be less than 1. We allow up to 1.2 so that tests don't 
+        # This should be less than 1. We allow up to 1.2 so that tests don't
         # fail nondeterministically too often.
         self.assertLess(measured_scale_exponent, 1.2)

From 02e6b6409b3df1766abdc3d6438b6f339a3163af Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Sat, 4 Aug 2012 13:22:39 +0200
Subject: [PATCH 57/88] [py3] Ported django.utils.decorators.

---
 tests/regressiontests/utils/decorators.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/regressiontests/utils/decorators.py b/tests/regressiontests/utils/decorators.py
index 96f4dd4e7a3..4d503df026a 100644
--- a/tests/regressiontests/utils/decorators.py
+++ b/tests/regressiontests/utils/decorators.py
@@ -105,4 +105,4 @@ class DecoratorFromMiddlewareTests(TestCase):
         response.render()
         self.assertTrue(getattr(request, 'process_response_reached', False))
         # Check that process_response saw the rendered content
-        self.assertEqual(request.process_response_content, "Hello world")
+        self.assertEqual(request.process_response_content, b"Hello world")

From 7e01e532c06e86e81558fea1d60f0f44b6ff50f2 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Sat, 4 Aug 2012 11:05:13 +0200
Subject: [PATCH 58/88] [py3] Ported django.utils.feedgenerator.

---
 django/utils/feedgenerator.py | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py
index 1bf43bf0a7e..f9126a67829 100644
--- a/django/utils/feedgenerator.py
+++ b/django/utils/feedgenerator.py
@@ -31,6 +31,8 @@ except ImportError:     # Python 2
 from django.utils.xmlutils import SimplerXMLGenerator
 from django.utils.encoding import force_text, iri_to_uri
 from django.utils import datetime_safe
+from django.utils import six
+from django.utils.six import StringIO
 from django.utils.timezone import is_aware
 
 def rfc2822_date(date):
@@ -44,25 +46,29 @@ def rfc2822_date(date):
     dow = days[date.weekday()]
     month = months[date.month - 1]
     time_str = date.strftime('%s, %%d %s %%Y %%H:%%M:%%S ' % (dow, month))
+    if not six.PY3:             # strftime returns a byte string in Python 2
+        time_str = time_str.decode('utf-8')
     if is_aware(date):
         offset = date.tzinfo.utcoffset(date)
         timezone = (offset.days * 24 * 60) + (offset.seconds // 60)
         hour, minute = divmod(timezone, 60)
-        return time_str + "%+03d%02d" % (hour, minute)
+        return time_str + '%+03d%02d' % (hour, minute)
     else:
         return time_str + '-0000'
 
 def rfc3339_date(date):
     # Support datetime objects older than 1900
     date = datetime_safe.new_datetime(date)
+    time_str = date.strftime('%Y-%m-%dT%H:%M:%S')
+    if not six.PY3:             # strftime returns a byte string in Python 2
+        time_str = time_str.decode('utf-8')
     if is_aware(date):
-        time_str = date.strftime('%Y-%m-%dT%H:%M:%S')
         offset = date.tzinfo.utcoffset(date)
         timezone = (offset.days * 24 * 60) + (offset.seconds // 60)
         hour, minute = divmod(timezone, 60)
-        return time_str + "%+03d:%02d" % (hour, minute)
+        return time_str + '%+03d:%02d' % (hour, minute)
     else:
-        return date.strftime('%Y-%m-%dT%H:%M:%SZ')
+        return time_str + 'Z'
 
 def get_tag_uri(url, date):
     """
@@ -178,8 +184,7 @@ class SyndicationFeed(object):
         """
         Returns the feed in the given encoding as a string.
         """
-        from io import BytesIO
-        s = BytesIO()
+        s = StringIO()
         self.write(s, encoding)
         return s.getvalue()
 
@@ -237,7 +242,7 @@ class RssFeed(SyndicationFeed):
             handler.addQuickElement("category", cat)
         if self.feed['feed_copyright'] is not None:
             handler.addQuickElement("copyright", self.feed['feed_copyright'])
-        handler.addQuickElement("lastBuildDate", rfc2822_date(self.latest_post_date()).decode('utf-8'))
+        handler.addQuickElement("lastBuildDate", rfc2822_date(self.latest_post_date()))
         if self.feed['ttl'] is not None:
             handler.addQuickElement("ttl", self.feed['ttl'])
 
@@ -271,7 +276,7 @@ class Rss201rev2Feed(RssFeed):
             handler.addQuickElement("dc:creator", item["author_name"], {"xmlns:dc": "http://purl.org/dc/elements/1.1/"})
 
         if item['pubdate'] is not None:
-            handler.addQuickElement("pubDate", rfc2822_date(item['pubdate']).decode('utf-8'))
+            handler.addQuickElement("pubDate", rfc2822_date(item['pubdate']))
         if item['comments'] is not None:
             handler.addQuickElement("comments", item['comments'])
         if item['unique_id'] is not None:
@@ -314,7 +319,7 @@ class Atom1Feed(SyndicationFeed):
         if self.feed['feed_url'] is not None:
             handler.addQuickElement("link", "", {"rel": "self", "href": self.feed['feed_url']})
         handler.addQuickElement("id", self.feed['id'])
-        handler.addQuickElement("updated", rfc3339_date(self.latest_post_date()).decode('utf-8'))
+        handler.addQuickElement("updated", rfc3339_date(self.latest_post_date()))
         if self.feed['author_name'] is not None:
             handler.startElement("author", {})
             handler.addQuickElement("name", self.feed['author_name'])
@@ -340,7 +345,7 @@ class Atom1Feed(SyndicationFeed):
         handler.addQuickElement("title", item['title'])
         handler.addQuickElement("link", "", {"href": item['link'], "rel": "alternate"})
         if item['pubdate'] is not None:
-            handler.addQuickElement("updated", rfc3339_date(item['pubdate']).decode('utf-8'))
+            handler.addQuickElement("updated", rfc3339_date(item['pubdate']))
 
         # Author information.
         if item['author_name'] is not None:

From fe8484efda257e151d9c1ca5151e546c9262bf0f Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Sat, 4 Aug 2012 15:55:53 +0200
Subject: [PATCH 59/88] [py3] Ported django.utils.functional.

---
 django/utils/functional.py                    | 58 ++++++++++++-------
 django/utils/safestring.py                    |  4 +-
 .../regressiontests/utils/simplelazyobject.py | 26 ++++++---
 3 files changed, 57 insertions(+), 31 deletions(-)

diff --git a/django/utils/functional.py b/django/utils/functional.py
index 177325dfb6e..085ec40b638 100644
--- a/django/utils/functional.py
+++ b/django/utils/functional.py
@@ -93,13 +93,19 @@ def lazy(func, *resultclasses):
                         if hasattr(cls, k):
                             continue
                         setattr(cls, k, meth)
-            cls._delegate_str = bytes in resultclasses
-            cls._delegate_unicode = six.text_type in resultclasses
-            assert not (cls._delegate_str and cls._delegate_unicode), "Cannot call lazy() with both str and unicode return types."
-            if cls._delegate_unicode:
-                cls.__unicode__ = cls.__unicode_cast
-            elif cls._delegate_str:
-                cls.__str__ = cls.__str_cast
+            cls._delegate_bytes = bytes in resultclasses
+            cls._delegate_text = six.text_type in resultclasses
+            assert not (cls._delegate_bytes and cls._delegate_text), "Cannot call lazy() with both bytes and text return types."
+            if cls._delegate_text:
+                if six.PY3:
+                    cls.__str__ = cls.__text_cast
+                else:
+                    cls.__unicode__ = cls.__text_cast
+            elif cls._delegate_bytes:
+                if six.PY3:
+                    cls.__bytes__ = cls.__bytes_cast
+                else:
+                    cls.__str__ = cls.__bytes_cast
         __prepare_class__ = classmethod(__prepare_class__)
 
         def __promise__(cls, klass, funcname, method):
@@ -120,17 +126,17 @@ def lazy(func, *resultclasses):
             return __wrapper__
         __promise__ = classmethod(__promise__)
 
-        def __unicode_cast(self):
+        def __text_cast(self):
             return func(*self.__args, **self.__kw)
 
-        def __str_cast(self):
-            return str(func(*self.__args, **self.__kw))
+        def __bytes_cast(self):
+            return bytes(func(*self.__args, **self.__kw))
 
         def __cast(self):
-            if self._delegate_str:
-                return self.__str_cast()
-            elif self._delegate_unicode:
-                return self.__unicode_cast()
+            if self._delegate_bytes:
+                return self.__bytes_cast()
+            elif self._delegate_text:
+                return self.__text_cast()
             else:
                 return func(*self.__args, **self.__kw)
 
@@ -144,10 +150,12 @@ def lazy(func, *resultclasses):
                 other = other.__cast()
             return self.__cast() < other
 
+        __hash__ = object.__hash__
+
         def __mod__(self, rhs):
-            if self._delegate_str:
-                return str(self) % rhs
-            elif self._delegate_unicode:
+            if self._delegate_bytes and not six.PY3:
+                return bytes(self) % rhs
+            elif self._delegate_text:
                 return six.text_type(self) % rhs
             else:
                 raise AssertionError('__mod__ not supported for non-string types')
@@ -234,6 +242,9 @@ class LazyObject(object):
     __dir__ = new_method_proxy(dir)
 
 
+# Workaround for http://bugs.python.org/issue12370
+_super = super
+
 class SimpleLazyObject(LazyObject):
     """
     A lazy object initialised from any function.
@@ -251,13 +262,17 @@ class SimpleLazyObject(LazyObject):
         value.
         """
         self.__dict__['_setupfunc'] = func
-        super(SimpleLazyObject, self).__init__()
+        _super(SimpleLazyObject, self).__init__()
 
     def _setup(self):
         self._wrapped = self._setupfunc()
 
-    __str__ = new_method_proxy(bytes)
-    __unicode__ = new_method_proxy(six.text_type)
+    if six.PY3:
+        __bytes__ = new_method_proxy(bytes)
+        __str__ = new_method_proxy(str)
+    else:
+        __str__ = new_method_proxy(str)
+        __unicode__ = new_method_proxy(unicode)
 
     def __deepcopy__(self, memo):
         if self._wrapped is empty:
@@ -284,7 +299,8 @@ class SimpleLazyObject(LazyObject):
     __class__ = property(new_method_proxy(operator.attrgetter("__class__")))
     __eq__ = new_method_proxy(operator.eq)
     __hash__ = new_method_proxy(hash)
-    __nonzero__ = new_method_proxy(bool)
+    __bool__ = new_method_proxy(bool)       # Python 3
+    __nonzero__ = __bool__                  # Python 2
 
 
 class lazy_property(property):
diff --git a/django/utils/safestring.py b/django/utils/safestring.py
index 1599fc2a662..bfaefd07eea 100644
--- a/django/utils/safestring.py
+++ b/django/utils/safestring.py
@@ -96,7 +96,7 @@ def mark_safe(s):
     """
     if isinstance(s, SafeData):
         return s
-    if isinstance(s, bytes) or (isinstance(s, Promise) and s._delegate_str):
+    if isinstance(s, bytes) or (isinstance(s, Promise) and s._delegate_bytes):
         return SafeString(s)
     if isinstance(s, (six.text_type, Promise)):
         return SafeUnicode(s)
@@ -112,7 +112,7 @@ def mark_for_escaping(s):
     """
     if isinstance(s, (SafeData, EscapeData)):
         return s
-    if isinstance(s, bytes) or (isinstance(s, Promise) and s._delegate_str):
+    if isinstance(s, bytes) or (isinstance(s, Promise) and s._delegate_bytes):
         return EscapeString(s)
     if isinstance(s, (six.text_type, Promise)):
         return EscapeUnicode(s)
diff --git a/tests/regressiontests/utils/simplelazyobject.py b/tests/regressiontests/utils/simplelazyobject.py
index 960a5e32018..3f81e8f6081 100644
--- a/tests/regressiontests/utils/simplelazyobject.py
+++ b/tests/regressiontests/utils/simplelazyobject.py
@@ -19,17 +19,27 @@ class _ComplexObject(object):
     def __hash__(self):
         return hash(self.name)
 
-    def __str__(self):
-        return "I am _ComplexObject(%r)" % self.name
+    if six.PY3:
+        def __bytes__(self):
+            return ("I am _ComplexObject(%r)" % self.name).encode("utf-8")
 
-    def __unicode__(self):
-        return six.text_type(self.name)
+        def __str__(self):
+            return self.name
+
+    else:
+        def __str__(self):
+            return b"I am _ComplexObject(%r)" % str(self.name)
+
+        def __unicode__(self):
+            return self.name
 
     def __repr__(self):
         return "_ComplexObject(%r)" % self.name
 
+
 complex_object = lambda: _ComplexObject("joe")
 
+
 class TestUtilsSimpleLazyObject(TestCase):
     """
     Tests for SimpleLazyObject
@@ -54,11 +64,11 @@ class TestUtilsSimpleLazyObject(TestCase):
         # proxy __repr__
         self.assertTrue("SimpleLazyObject" in repr(SimpleLazyObject(complex_object)))
 
-    def test_str(self):
-        self.assertEqual(str_prefix("I am _ComplexObject(%(_)s'joe')"),
-            str(SimpleLazyObject(complex_object)))
+    def test_bytes(self):
+        self.assertEqual(b"I am _ComplexObject('joe')",
+                bytes(SimpleLazyObject(complex_object)))
 
-    def test_unicode(self):
+    def test_text(self):
         self.assertEqual("joe", six.text_type(SimpleLazyObject(complex_object)))
 
     def test_class(self):

From 17da0aa893d4933bef52151243a72d90ad16d5de Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Sat, 4 Aug 2012 11:12:21 +0200
Subject: [PATCH 60/88] [py3] Ported django.utils.regex_helper.

---
 django/utils/regex_helper.py | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/django/utils/regex_helper.py b/django/utils/regex_helper.py
index 8953a21e955..7b40d141def 100644
--- a/django/utils/regex_helper.py
+++ b/django/utils/regex_helper.py
@@ -8,6 +8,7 @@ should be good enough for a large class of URLS, however.
 from __future__ import unicode_literals
 
 from django.utils import six
+from django.utils.six.moves import zip
 
 # Mapping of an escape character to a representative of that class. So, e.g.,
 # "\w" is replaced by "x" in a reverse URL. A value of None means to ignore
@@ -44,8 +45,8 @@ class NonCapture(list):
 
 def normalize(pattern):
     """
-    Given a reg-exp pattern, normalizes it to a list of forms that suffice for
-    reverse matching. This does the following:
+    Given a reg-exp pattern, normalizes it to an iterable of forms that
+    suffice for reverse matching. This does the following:
 
     (1) For any repeating sections, keeps the minimum number of occurrences
         permitted (this means zero for optional groups).
@@ -80,7 +81,7 @@ def normalize(pattern):
     try:
         ch, escaped = next(pattern_iter)
     except StopIteration:
-        return zip([''],  [[]])
+        return [('', [])]
 
     try:
         while True:
@@ -193,9 +194,9 @@ def normalize(pattern):
         pass
     except NotImplementedError:
         # A case of using the disjunctive form. No results for you!
-        return zip([''],  [[]])
+        return [('', [])]
 
-    return zip(*flatten_result(result))
+    return list(zip(*flatten_result(result)))
 
 def next_char(input_iter):
     """

From 9e8df02d685e1ce6181f285d1c487cd01e65ca74 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Sat, 21 Jul 2012 22:24:13 +0200
Subject: [PATCH 61/88] [py3] Ported django.utils.translation.

---
 django/utils/translation/trans_real.py | 41 +++++++++++++++-----------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py
index 9ebcbf54411..9e6eadcd489 100644
--- a/django/utils/translation/trans_real.py
+++ b/django/utils/translation/trans_real.py
@@ -9,7 +9,9 @@ import gettext as gettext_module
 from threading import local
 
 from django.utils.importlib import import_module
+from django.utils.encoding import smart_str, smart_text
 from django.utils.safestring import mark_safe, SafeData
+from django.utils import six
 from django.utils.six import StringIO
 
 
@@ -259,12 +261,14 @@ def do_translate(message, translation_function):
 def gettext(message):
     return do_translate(message, 'gettext')
 
-def ugettext(message):
-    return do_translate(message, 'ugettext')
+if six.PY3:
+    ugettext = gettext
+else:
+    def ugettext(message):
+        return do_translate(message, 'ugettext')
 
 def pgettext(context, message):
-    result = do_translate(
-        "%s%s%s" % (context, CONTEXT_SEPARATOR, message), 'ugettext')
+    result = ugettext("%s%s%s" % (context, CONTEXT_SEPARATOR, message))
     if CONTEXT_SEPARATOR in result:
         # Translation not found
         result = message
@@ -297,20 +301,23 @@ def ngettext(singular, plural, number):
     """
     return do_ntranslate(singular, plural, number, 'ngettext')
 
-def ungettext(singular, plural, number):
-    """
-    Returns a unicode strings of the translation of either the singular or
-    plural, based on the number.
-    """
-    return do_ntranslate(singular, plural, number, 'ungettext')
+if six.PY3:
+    ungettext = ngettext
+else:
+    def ungettext(singular, plural, number):
+        """
+        Returns a unicode strings of the translation of either the singular or
+        plural, based on the number.
+        """
+        return do_ntranslate(singular, plural, number, 'ungettext')
 
 def npgettext(context, singular, plural, number):
-    result = do_ntranslate("%s%s%s" % (context, CONTEXT_SEPARATOR, singular),
-                           "%s%s%s" % (context, CONTEXT_SEPARATOR, plural),
-                           number, 'ungettext')
+    result = ungettext("%s%s%s" % (context, CONTEXT_SEPARATOR, singular),
+                       "%s%s%s" % (context, CONTEXT_SEPARATOR, plural),
+                        number)
     if CONTEXT_SEPARATOR in result:
         # Translation not found
-        result = do_ntranslate(singular, plural, number, 'ungettext')
+        result = ungettext(singular, plural, number)
     return result
 
 def all_locale_paths():
@@ -440,7 +447,7 @@ def templatize(src, origin=None):
     from django.conf import settings
     from django.template import (Lexer, TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK,
             TOKEN_COMMENT, TRANSLATOR_COMMENT_MARK)
-    src = src.decode(settings.FILE_CHARSET)
+    src = smart_text(src, settings.FILE_CHARSET)
     out = StringIO()
     message_context = None
     intrans = False
@@ -455,7 +462,7 @@ def templatize(src, origin=None):
                 content = ''.join(comment)
                 translators_comment_start = None
                 for lineno, line in enumerate(content.splitlines(True)):
-                    if line.lstrip().startswith(TRANSLATOR_COMMENT_MARK):
+                    if line.lstrip().startswith(smart_text(TRANSLATOR_COMMENT_MARK)):
                         translators_comment_start = lineno
                 for lineno, line in enumerate(content.splitlines(True)):
                     if translators_comment_start is not None and lineno >= translators_comment_start:
@@ -570,7 +577,7 @@ def templatize(src, origin=None):
                 out.write(' # %s' % t.contents)
             else:
                 out.write(blankout(t.contents, 'X'))
-    return out.getvalue().encode('utf-8')
+    return smart_str(out.getvalue())
 
 def parse_accept_lang_header(lang_string):
     """

From 64e2e3562705dfee31a0922bbbe14bdf49d242d7 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Sat, 4 Aug 2012 11:24:30 +0200
Subject: [PATCH 62/88] [py3] Ported django.utils.tzinfo.

---
 django/utils/tzinfo.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/django/utils/tzinfo.py b/django/utils/tzinfo.py
index c40b4304118..208b7e7191b 100644
--- a/django/utils/tzinfo.py
+++ b/django/utils/tzinfo.py
@@ -5,7 +5,7 @@ from __future__ import unicode_literals
 import time
 from datetime import timedelta, tzinfo
 
-from django.utils.encoding import smart_text, smart_bytes, DEFAULT_LOCALE_ENCODING
+from django.utils.encoding import smart_text, smart_str, DEFAULT_LOCALE_ENCODING
 
 # Python's doc say: "A tzinfo subclass must have an __init__() method that can
 # be called with no arguments". FixedOffset and LocalTimezone don't honor this
@@ -53,7 +53,7 @@ class LocalTimezone(tzinfo):
         self._tzname = self.tzname(dt)
 
     def __repr__(self):
-        return smart_bytes(self._tzname)
+        return smart_str(self._tzname)
 
     def __getinitargs__(self):
         return self.__dt,

From 9e0a10ba77ad1737c4aaf49e5d4b4380f912bc0e Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Sun, 5 Aug 2012 14:46:18 +0200
Subject: [PATCH 63/88] [py3] Minor fix in django.contrib.gis.

---
 django/contrib/gis/gdal/geometries.py | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/django/contrib/gis/gdal/geometries.py b/django/contrib/gis/gdal/geometries.py
index d752104e0a8..373ece777d5 100644
--- a/django/contrib/gis/gdal/geometries.py
+++ b/django/contrib/gis/gdal/geometries.py
@@ -40,7 +40,7 @@
 """
 # Python library requisites.
 import sys
-from binascii import a2b_hex
+from binascii import a2b_hex, b2a_hex
 from ctypes import byref, string_at, c_char_p, c_double, c_ubyte, c_void_p
 
 # Getting GDAL prerequisites
@@ -322,8 +322,7 @@ class OGRGeometry(GDALBase):
     @property
     def hex(self):
         "Returns the hexadecimal representation of the WKB (a string)."
-        return str(self.wkb).encode('hex').upper()
-        #return b2a_hex(self.wkb).upper()
+        return b2a_hex(self.wkb).upper()
 
     @property
     def json(self):

From bf4da7a4420ccacf76090301a1e0efa1eea17751 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Fri, 3 Aug 2012 23:01:47 +0200
Subject: [PATCH 64/88] [py3] Made a small fix in django.http.

This is necessary for the 'utils' tests to pass.
---
 django/http/__init__.py | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/django/http/__init__.py b/django/http/__init__.py
index b23304f3462..d559fdf7c67 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -549,7 +549,12 @@ class HttpResponse(object):
         for value in values:
             if isinstance(value, six.text_type):
                 try:
-                    value = value.encode('us-ascii')
+                    if not six.PY3:
+                        value = value.encode('us-ascii')
+                    else:
+                        # In Python 3, use a string in headers,
+                        # but ensure in only contains ASCII characters.
+                        value.encode('us-ascii')
                 except UnicodeError as e:
                     e.reason += ', HTTP response headers must be in US-ASCII format'
                     raise

From 46cc530fad3c6ae4009557121971fe749742aef6 Mon Sep 17 00:00:00 2001
From: Alex Gaynor <alex.gaynor@gmail.com>
Date: Tue, 7 Aug 2012 07:22:25 -0700
Subject: [PATCH 65/88] Fix a test that relied on an exception outliving the
 `except` block, which doesn't happen on py3k.

---
 tests/modeltests/validation/models.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/modeltests/validation/models.py b/tests/modeltests/validation/models.py
index 0adc9fec320..26fff4b8638 100644
--- a/tests/modeltests/validation/models.py
+++ b/tests/modeltests/validation/models.py
@@ -101,6 +101,6 @@ try:
     class MultipleAutoFields(models.Model):
         auto1 = models.AutoField(primary_key=True)
         auto2 = models.AutoField(primary_key=True)
-except AssertionError as assertion_error:
-    pass # Fail silently
+except AssertionError as exc:
+    assertion_error = exc
 assert str(assertion_error) == "A model can't have more than one AutoField."

From 1ef1bceb3b79f73686e1857e5cdb051b8c11bc09 Mon Sep 17 00:00:00 2001
From: James Bennett <james@b-list.org>
Date: Tue, 7 Aug 2012 16:06:34 -0400
Subject: [PATCH 66/88] Add new security-policy documentation.

This formally describes our policies on reporting, notification and
disclosure of security issues, and provides a detailed explanation of
our full security-response process, for reference purposes.
---
 .../contributing/bugs-and-features.txt        |  44 +---
 docs/internals/release-process.txt            |  12 +-
 docs/internals/security.txt                   | 215 ++++++++++++++++++
 3 files changed, 232 insertions(+), 39 deletions(-)
 create mode 100644 docs/internals/security.txt

diff --git a/docs/internals/contributing/bugs-and-features.txt b/docs/internals/contributing/bugs-and-features.txt
index 76a2bd23743..30c7a5bb72b 100644
--- a/docs/internals/contributing/bugs-and-features.txt
+++ b/docs/internals/contributing/bugs-and-features.txt
@@ -2,7 +2,15 @@
 Reporting bugs and requesting features
 ======================================
 
-Before reporting a bug or requesting a new feature, please consider these
+.. Important::
+
+    Please report security issues **only** to security@djangoproject.com.
+    This is a private list only open to long-time, highly trusted Django
+    developers, and its archives are not public.
+
+For further details, please see :doc:`our security policies </internals/security>`.
+
+Otherwise, before reporting a bug or requesting a new feature, please consider these
 general points:
 
 * Check that someone hasn't already filed the bug or feature request by
@@ -55,40 +63,6 @@ To understand the lifecycle of your ticket once you have created it, refer to
 
 .. _reporting-security-issues:
 
-Reporting security issues
--------------------------
-
-.. Important::
-
-    Please report security issues **only** to security@djangoproject.com.
-    This is a private list only open to long-time, highly trusted Django
-    developers, and its archives are not publicly readable.
-
-In the event of a confirmed vulnerability in Django itself, we will take the
-following actions:
-
-* Acknowledge to the reporter that we've received the report and that a
-  fix is forthcoming. We'll give a rough timeline and ask the reporter
-  to keep the issue confidential until we announce it.
-
-* Focus on developing a fix as quickly as possible and produce patches
-  against the current and two previous releases.
-
-* Determine a go-public date for announcing the vulnerability and the fix.
-  To try to mitigate a possible "arms race" between those applying the
-  patch and those trying to exploit the hole, we will not announce
-  security problems immediately.
-
-* Pre-notify third-party distributors of Django ("vendors"). We will send
-  these vendor notifications through private email which will include
-  documentation of the vulnerability, links to the relevant patch(es), and
-  a request to keep the vulnerability confidential until the official
-  go-public date.
-
-* Publicly announce the vulnerability and the fix on the pre-determined
-  go-public date. This will probably mean a new release of Django, but
-  in some cases it may simply be patches against current releases.
-
 Reporting user interface bugs and features
 ------------------------------------------
 
diff --git a/docs/internals/release-process.txt b/docs/internals/release-process.txt
index 97adb4a3f6c..8affddb5e01 100644
--- a/docs/internals/release-process.txt
+++ b/docs/internals/release-process.txt
@@ -31,10 +31,14 @@ Since version 1.0, Django's release numbering works as follows:
   These are of the form ``A.B alpha/beta/rc N``, which means the ``Nth``
   alpha/beta/release candidate of version ``A.B``.
 
-In Subversion, each Django release will be tagged under ``tags/releases``.  If
-it's necessary to release a bug fix release or a security release that doesn't
-come from the trunk, we'll copy that tag to ``branches/releases`` to make the
-bug fix release.
+In git, each Django release will have a tag indicating its version
+number, signed with the Django release key. Additionally, each release
+series (X.Y) has its own branch, and bugfix/security releases will be
+issued from those branches.
+
+For more information about how the Django project issues new releases
+for security purposes, please see :doc:`our security policies
+<security>`.
 
 Major releases
 --------------
diff --git a/docs/internals/security.txt b/docs/internals/security.txt
new file mode 100644
index 00000000000..7121ff31eca
--- /dev/null
+++ b/docs/internals/security.txt
@@ -0,0 +1,215 @@
+==========================
+Django's security policies
+==========================
+
+Django's development team is strongly committed to responsible
+reporting and disclosure of security-related issues. As such, we've
+adopted and follow a set of policies which conform to that ideal and
+are geared toward allowing us to deliver timely security updates to
+the official distribution of Django, as well as to third-party
+distributions.
+
+.. _reporting-security-issues:
+
+Reporting security issues
+=========================
+
+**Short version: please report security issues by emailing
+security@djangoproject.com**.
+
+Most normal bugs in Django are reported to `our public Trac
+instance`_, but due to the sensitive nature of security issues, we ask
+that they *not* be publicly reported in this fashion.
+
+Instead, if you believe you've found something in Django which has
+security implications, please send a description of the issue via
+email to ``security@djangoproject.com``. Mail sent to that address
+reaches a subset of the core development team, who can forward
+security issues into the private committers' mailing list for broader
+discussion if needed.
+
+You can send encrypted email to this address; the public key ID for
+``security@djangoproject.com`` is ``0xfcb84b8d1d17f80b``, and this
+public key is available from most commonly-used keyservers.
+
+Once you've submitted an issue via email, you should receive an
+acknowledgment from a member of the Django development team within 48
+hours, and depending on the action to be taken, you may receive
+further followup emails.
+
+.. _our public Trac instance: https://code.djangoproject.com/query
+
+.. _security-support:
+
+Supported versions
+==================
+
+At any given time, the Django team provides official security support
+for several versions of Django:
+
+* The `master development branch`_, hosted on GitHub, which will
+  become the next release of Django, receives security support.
+
+* The two most recent Django release series receive security
+  support. For example, during the development cycle leading to the
+  release of Django 1.5, support will be provided for Django 1.4 and
+  Django 1.3. Upon the release of Django 1.5, Django 1.3's security
+  support will end.
+
+When new releases are issued for security reasons, the accompanying
+notice will include a list of affected versions. This list is
+comprised solely of *supported* versions of Django: older versions may
+also be affected, but we do not investigate to determine that, and
+will not issue patches or new releases for those versions.
+
+.. _master development branch: https://github.com/django/django/
+
+.. _security-disclosure:
+
+How Django discloses security issues
+====================================
+
+Our process for taking a security issue from private discussion to
+public disclosure involves multiple steps.
+
+Approximately one week before full public disclosure, we will send
+advance notification of the issue to a list of people and
+organizations, primarily composed of operating-system vendors and
+other distributors of Django. This notification will consist of an
+email message, signed with the Django release key, containing:
+
+* A full description of the issue and the affected versions of Django.
+
+* The steps we will be taking to remedy the issue.
+
+* The patch(es), if any, that will be applied to Django.
+
+* The date on which the Django team will apply these patches, issue
+  new releases and publicy disclose the issue.
+
+Simultaneously, the reporter of the issue will receive notification of
+the date on which we plan to take the issue public.
+
+On the day of disclosure, we will take the following steps:
+
+1. Apply the relevant patch(es) to Django's codebase. The commit
+   messages for these patches will indicate that they are for security
+   issues, but will not describe the issue in any detail; instead,
+   they will warn of upcoming disclosure.
+
+2. Issue the relevant release(s), by placing new packages on `the
+   Python Package Index`_ and on the Django website, and tagging the
+   new release(s) in Django's git repository.
+
+3. Post a public entry on `the official Django development blog`_,
+   describing the issue and its resolution in detail, pointing to the
+   relevant patches and new releases, and crediting the reporter of
+   the issue (if the reporter wishes to be publicly identified).
+
+.. _the Python Package Index: http://pypi.python.org/pypi
+.. _the official Django development blog: https://www.djangoproject.com/weblog/
+
+If a reported issue is believed to be particularly time-sensitive --
+due to a known exploit in the wild, for example -- the time between
+advance notification and public disclosure may be shortened
+considerably.
+
+Additionally, if we have reason to believe that an issue reported to
+us affects other frameworks or tools in the Python/web ecosystem, we
+may privately contact and discuss those issues with the appropriate
+maintainers, and coordinate our own disclosure and resolution with
+theirs.
+
+.. _security-notifications:
+
+Who receives advance notification
+=================================
+
+The full list of people and organizations who receive advance
+notification of security issues is not and will not be made public.
+
+We also aim to keep this list as small as effectively possible, in
+order to better manage the flow of confidential information prior to
+disclosure. As such, our notification list is *not* simply a list of
+users of Django, and merely being a user of Django is not sufficient
+reason to be placed on the notification list.
+
+In broad terms, recipients of security notifications fall into three
+groups:
+
+1. Operating-system vendors and other distributors of Django who
+   provide a suitably-generic (i.e., *not* an individual's personal
+   email address) contact address for reporting issues with their
+   Django package, or for general security reporting. In either case,
+   such addresses **must not** forward to public mailing lists or bug
+   trackers. Addresses which forward to the private email of an
+   individual maintainer or security-response contact are acceptable,
+   although private security trackers or security-response groups are
+   strongly preferred.
+
+2. On a case-by-case basis, individual package maintainers who have
+   demonstrated a commitment to responding to and responsibly acting
+   on these notifications.
+
+3. On a case-by-case basis, other entities who, in the judgment of the
+   Django development team, need to be made aware of a pending
+   security issue. Typically, membership in this group will consist of
+   some of the largest and/or most likely to be severely impacted
+   known users or distributors of Django, and will require a
+   demonstrated ability to responsibly receive, keep confidential and
+   act on these notifications.
+
+Additionally, a maximum of six days prior to disclosure, notification
+will be sent to the ``distros@vs.openwall.org`` mailing list, whose
+membership includes representatives of most major open-source
+operating system vendors.
+
+Requesting notifications
+========================
+
+If you believe that you, or an organization you are authorized to
+represent, fall into one of the groups listed above, you can ask to be
+added to Django's notification list by emailing
+``security@djangoproject.com``. Please use the subject line "Security
+notification request".
+
+Your request **must** include the following information:
+
+* Your full, real name and the name of the organization you represent,
+  if applicable, as well as your role within that organization.
+
+* A detailed explanation of how you or your organization fit at least
+  one set of criteria listed above.
+
+* A detailed explanation of why you are requesting security
+  notifications. Again, please keep in mind that this is *not* simply
+  a list for users of Django, and the overwhelming majority of users
+  of Django should not request notifications and will not be added to
+  our notification list if they do.
+
+* The email address you would like to have added to our notification
+  list.
+
+* An explanation of who will be receiving/reviewing mail sent to that
+  address, as well as information regarding any automated actions that
+  will be taken (i.e., filing of a confidential issue in a bug
+  tracker).
+
+* For individuals, the ID of a public key associated with your address
+  which can be used to verify email received from you and encrypt
+  email sent to you, as needed.
+
+Once submitted, your request will be considered by the Django
+development team; you will receive a reply notifying you of the result
+of your request within 30 days.
+
+Please also bear in mind that for any individual or organization,
+receiving security notifications is a privilege granted at the sole
+discretion of the Django development team, and that this privilege can
+be revoked at any time, with or without explanation.
+
+If you are added to the notification list, security-related emails
+will be sent to you by Django's release manager, and all notification
+emails will be signed with the same key used to sign Django releases;
+that key has the ID ``0x3684C0C08C8B2AE1``, and is available from most
+commonly-used keyservers.
\ No newline at end of file

From 483fb75049847d483f073b5ff81e42970d81ac07 Mon Sep 17 00:00:00 2001
From: James Bennett <james@b-list.org>
Date: Tue, 7 Aug 2012 16:25:21 -0400
Subject: [PATCH 67/88] Link security policies from internals index.

---
 docs/internals/index.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/docs/internals/index.txt b/docs/internals/index.txt
index 3dba550fed9..3ff4eb62d03 100644
--- a/docs/internals/index.txt
+++ b/docs/internals/index.txt
@@ -18,6 +18,7 @@ the hood".
 
    contributing/index
    committers
+   security
    release-process
    deprecation
    git

From 5c3bc25598bd8bcf726ac0cb6e35735b6fc1fcbf Mon Sep 17 00:00:00 2001
From: James Bennett <james@b-list.org>
Date: Tue, 7 Aug 2012 16:26:37 -0400
Subject: [PATCH 68/88] And link security policies from documentation index.

---
 docs/index.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/docs/index.txt b/docs/index.txt
index d5723186e6c..011ecdb0bc9 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -273,7 +273,8 @@ you can contribute:
   :doc:`How to get involved <internals/contributing/index>` |
   :doc:`The release process <internals/release-process>` |
   :doc:`Team of committers <internals/committers>` |
-  :doc:`The Django source code repository <internals/git>`
+  :doc:`The Django source code repository <internals/git>` |
+  :doc:`Security policies <internals/security>`
 
 * **Design philosophies:**
   :doc:`Overview <misc/design-philosophies>`

From 50c41e77e88e591b25080a8c870c8d08d47aa171 Mon Sep 17 00:00:00 2001
From: James Bennett <james@b-list.org>
Date: Tue, 7 Aug 2012 16:28:12 -0400
Subject: [PATCH 69/88] Put all the security-related notes in the same notice
 box.

---
 docs/internals/contributing/bugs-and-features.txt | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/docs/internals/contributing/bugs-and-features.txt b/docs/internals/contributing/bugs-and-features.txt
index 30c7a5bb72b..91a078cbc0e 100644
--- a/docs/internals/contributing/bugs-and-features.txt
+++ b/docs/internals/contributing/bugs-and-features.txt
@@ -4,11 +4,12 @@ Reporting bugs and requesting features
 
 .. Important::
 
-    Please report security issues **only** to security@djangoproject.com.
-    This is a private list only open to long-time, highly trusted Django
-    developers, and its archives are not public.
+    Please report security issues **only** to
+    security@djangoproject.com.  This is a private list only open to
+    long-time, highly trusted Django developers, and its archives are
+    not public. For further details, please see :doc:`our security
+    policies </internals/security>`.
 
-For further details, please see :doc:`our security policies </internals/security>`.
 
 Otherwise, before reporting a bug or requesting a new feature, please consider these
 general points:

From a4abe7ed56d44418c8203b4605085caf9b349654 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Wed, 8 Aug 2012 12:56:12 +0200
Subject: [PATCH 70/88] [py3] abspathu doesn't exist under Python 3.

---
 django/utils/_os.py | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/django/utils/_os.py b/django/utils/_os.py
index 82dccd0efe1..9eb5e5e8ea2 100644
--- a/django/utils/_os.py
+++ b/django/utils/_os.py
@@ -2,6 +2,7 @@ import os
 import stat
 from os.path import join, normcase, normpath, abspath, isabs, sep
 from django.utils.encoding import force_text
+from django.utils import six
 
 try:
     WindowsError = WindowsError
@@ -10,13 +11,12 @@ except NameError:
         pass
 
 
-# Define our own abspath function that can handle joining
-# unicode paths to a current working directory that has non-ASCII
-# characters in it.  This isn't necessary on Windows since the
-# Windows version of abspath handles this correctly.  The Windows
-# abspath also handles drive letters differently than the pure
-# Python implementation, so it's best not to replace it.
-if os.name == 'nt':
+# Under Python 2, define our own abspath function that can handle joining
+# unicode paths to a current working directory that has non-ASCII characters
+# in it.  This isn't necessary on Windows since the Windows version of abspath
+# handles this correctly. It also handles drive letters differently than the
+# pure Python implementation, so it's best not to replace it.
+if six.PY3 or os.name == 'nt':
     abspathu = abspath
 else:
     def abspathu(path):

From fa4cb348170134fce7e99eedf497ee8f5e0fe165 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Wed, 8 Aug 2012 13:07:49 +0200
Subject: [PATCH 71/88] [py3] Fixed filesystem encoding handling

in the app directories template loader.
---
 django/template/loaders/app_directories.py | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/django/template/loaders/app_directories.py b/django/template/loaders/app_directories.py
index 6e0f079de7a..887f8a0b729 100644
--- a/django/template/loaders/app_directories.py
+++ b/django/template/loaders/app_directories.py
@@ -12,9 +12,11 @@ from django.template.base import TemplateDoesNotExist
 from django.template.loader import BaseLoader
 from django.utils._os import safe_join
 from django.utils.importlib import import_module
+from django.utils import six
 
 # At compile time, cache the directories to search.
-fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
+if not six.PY3:
+    fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
 app_template_dirs = []
 for app in settings.INSTALLED_APPS:
     try:
@@ -23,7 +25,9 @@ for app in settings.INSTALLED_APPS:
         raise ImproperlyConfigured('ImportError %s: %s' % (app, e.args[0]))
     template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')
     if os.path.isdir(template_dir):
-        app_template_dirs.append(template_dir.decode(fs_encoding))
+        if not six.PY3:
+            template_dir = template_dir.decode(fs_encoding)
+        app_template_dirs.append(template_dir)
 
 # It won't change, so convert it to a tuple to save memory.
 app_template_dirs = tuple(app_template_dirs)

From 2da3af23aa10af3e06536a46134b1053f80eb8b2 Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Wed, 8 Aug 2012 13:43:21 +0200
Subject: [PATCH 72/88] [py3] Made gis.measure Python 3-compatible

---
 django/contrib/gis/measure.py | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/django/contrib/gis/measure.py b/django/contrib/gis/measure.py
index fa8bab13407..6e074be355b 100644
--- a/django/contrib/gis/measure.py
+++ b/django/contrib/gis/measure.py
@@ -143,7 +143,7 @@ class MeasureBase(object):
     def __rmul__(self, other):
         return self * other
 
-    def __div__(self, other):
+    def __truediv__(self, other):
         if isinstance(other, self.__class__):
             return self.standard / other.standard
         if isinstance(other, NUMERIC_TYPES):
@@ -151,16 +151,19 @@ class MeasureBase(object):
                 **{self.STANDARD_UNIT: (self.standard / other)})
         else:
             raise TypeError('%(class)s must be divided with number or %(class)s' % {"class":pretty_name(self)})
+    __div__ = __truediv__ # Python 2 compatibility
 
-    def __idiv__(self, other):
+    def __itruediv__(self, other):
         if isinstance(other, NUMERIC_TYPES):
             self.standard /= float(other)
             return self
         else:
             raise TypeError('%(class)s must be divided with number' % {"class":pretty_name(self)})
+    __idiv__ = __itruediv__ # Python 2 compatibility
 
-    def __nonzero__(self):
+    def __bool__(self):
         return bool(self.standard)
+    __nonzero__ = __bool__ # Python 2 compatibility
 
     def default_units(self, kwargs):
         """
@@ -305,12 +308,13 @@ class Area(MeasureBase):
     ALIAS = dict([(k, '%s%s' % (AREA_PREFIX, v)) for k, v in Distance.ALIAS.items()])
     LALIAS = dict([(k.lower(), v) for k, v in ALIAS.items()])
 
-    def __div__(self, other):
+    def __truediv__(self, other):
         if isinstance(other, NUMERIC_TYPES):
             return self.__class__(default_unit=self._default_unit,
                 **{self.STANDARD_UNIT: (self.standard / other)})
         else:
             raise TypeError('%(class)s must be divided by a number' % {"class":pretty_name(self)})
+    __div__ = __truediv__ # Python 2 compatibility
 
 
 # Shortcuts

From 396357741b88dfcd85486db673dbb822da8b2de0 Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Tue, 7 Aug 2012 15:41:54 +0200
Subject: [PATCH 73/88] [py3] Used compatible imports of StringIO.

---
 tests/modeltests/fixtures/tests.py                | 9 ++++-----
 tests/modeltests/serializers/tests.py             | 2 +-
 tests/modeltests/user_commands/tests.py           | 2 +-
 tests/regressiontests/bash_completion/tests.py    | 4 ++--
 tests/regressiontests/builtin_server/tests.py     | 3 +--
 tests/regressiontests/createsuperuser/tests.py    | 3 +--
 tests/regressiontests/file_uploads/tests.py       | 2 +-
 tests/regressiontests/i18n/commands/extraction.py | 2 +-
 tests/regressiontests/inspectdb/tests.py          | 3 +--
 tests/regressiontests/mail/tests.py               | 2 +-
 tests/regressiontests/middleware/tests.py         | 4 ++--
 tests/regressiontests/multiple_database/tests.py  | 2 +-
 tests/regressiontests/requests/tests.py           | 2 +-
 tests/regressiontests/templates/loaders.py        | 6 +++---
 tests/regressiontests/test_utils/tests.py         | 2 +-
 15 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/tests/modeltests/fixtures/tests.py b/tests/modeltests/fixtures/tests.py
index 1efa035e8a8..b3323484252 100644
--- a/tests/modeltests/fixtures/tests.py
+++ b/tests/modeltests/fixtures/tests.py
@@ -1,11 +1,10 @@
 from __future__ import absolute_import
 
-import StringIO
-
 from django.contrib.sites.models import Site
 from django.core import management
 from django.db import connection, IntegrityError
 from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature
+from django.utils.six import StringIO
 
 from .models import Article, Book, Spy, Tag, Visa
 
@@ -26,7 +25,7 @@ class FixtureLoadingTests(TestCase):
 
     def _dumpdata_assert(self, args, output, format='json', natural_keys=False,
                          use_base_manager=False, exclude_list=[]):
-        new_io = StringIO.StringIO()
+        new_io = StringIO()
         management.call_command('dumpdata', *args, **{'format':format,
                                                       'stdout':new_io,
                                                       'stderr':new_io,
@@ -43,7 +42,7 @@ class FixtureLoadingTests(TestCase):
         ])
 
     def test_loading_and_dumping(self):
-        new_io = StringIO.StringIO()
+        new_io = StringIO()
 
         Site.objects.all().delete()
         # Load fixture 1. Single JSON file, with two objects.
@@ -293,7 +292,7 @@ class FixtureLoadingTests(TestCase):
 
 class FixtureTransactionTests(TransactionTestCase):
     def _dumpdata_assert(self, args, output, format='json'):
-        new_io = StringIO.StringIO()
+        new_io = StringIO()
         management.call_command('dumpdata', *args, **{'format':format, 'stdout':new_io})
         command_output = new_io.getvalue().strip()
         self.assertEqual(command_output, output)
diff --git a/tests/modeltests/serializers/tests.py b/tests/modeltests/serializers/tests.py
index 9177227539a..ec3cc132db4 100644
--- a/tests/modeltests/serializers/tests.py
+++ b/tests/modeltests/serializers/tests.py
@@ -4,13 +4,13 @@ from __future__ import absolute_import, unicode_literals
 import json
 from datetime import datetime
 from xml.dom import minidom
-from StringIO import StringIO
 
 from django.conf import settings
 from django.core import serializers
 from django.db import transaction, connection
 from django.test import TestCase, TransactionTestCase, Approximate
 from django.utils import six
+from django.utils.six import StringIO
 from django.utils import unittest
 
 from .models import (Category, Author, Article, AuthorProfile, Actor, Movie,
diff --git a/tests/modeltests/user_commands/tests.py b/tests/modeltests/user_commands/tests.py
index 509f13f62f3..d25911c09fc 100644
--- a/tests/modeltests/user_commands/tests.py
+++ b/tests/modeltests/user_commands/tests.py
@@ -1,10 +1,10 @@
 import sys
-from StringIO import StringIO
 
 from django.core import management
 from django.core.management.base import CommandError
 from django.test import TestCase
 from django.utils import translation
+from django.utils.six import StringIO
 
 
 class CommandTests(TestCase):
diff --git a/tests/regressiontests/bash_completion/tests.py b/tests/regressiontests/bash_completion/tests.py
index e4b3bb58f34..ed8cedf1ab5 100644
--- a/tests/regressiontests/bash_completion/tests.py
+++ b/tests/regressiontests/bash_completion/tests.py
@@ -3,11 +3,11 @@ A series of tests to establish that the command-line bash completion works.
 """
 import os
 import sys
-import StringIO
 
 from django.conf import settings
 from django.core.management import ManagementUtility
 from django.utils import unittest
+from django.utils.six import StringIO
 
 
 class BashCompletionTests(unittest.TestCase):
@@ -20,7 +20,7 @@ class BashCompletionTests(unittest.TestCase):
     def setUp(self):
         self.old_DJANGO_AUTO_COMPLETE = os.environ.get('DJANGO_AUTO_COMPLETE')
         os.environ['DJANGO_AUTO_COMPLETE'] = '1'
-        self.output = StringIO.StringIO()
+        self.output = StringIO()
         self.old_stdout = sys.stdout
         sys.stdout = self.output
 
diff --git a/tests/regressiontests/builtin_server/tests.py b/tests/regressiontests/builtin_server/tests.py
index aeb5d9febf9..4a3b44176bc 100644
--- a/tests/regressiontests/builtin_server/tests.py
+++ b/tests/regressiontests/builtin_server/tests.py
@@ -1,6 +1,5 @@
-from StringIO import StringIO
-
 from django.core.servers.basehttp import ServerHandler
+from django.utils.six import StringIO
 from django.utils.unittest import TestCase
 
 #
diff --git a/tests/regressiontests/createsuperuser/tests.py b/tests/regressiontests/createsuperuser/tests.py
index 1c1bb0ed38c..7303b1f2e79 100644
--- a/tests/regressiontests/createsuperuser/tests.py
+++ b/tests/regressiontests/createsuperuser/tests.py
@@ -1,9 +1,8 @@
-from StringIO import StringIO
-
 from django.contrib.auth import models
 from django.contrib.auth.management.commands import changepassword
 from django.core.management import call_command
 from django.test import TestCase
+from django.utils.six import StringIO
 
 
 class MultiDBChangepasswordManagementCommandTestCase(TestCase):
diff --git a/tests/regressiontests/file_uploads/tests.py b/tests/regressiontests/file_uploads/tests.py
index 9fe3ca15a7d..d2362d71978 100644
--- a/tests/regressiontests/file_uploads/tests.py
+++ b/tests/regressiontests/file_uploads/tests.py
@@ -7,12 +7,12 @@ import hashlib
 import json
 import os
 import shutil
-from StringIO import StringIO
 
 from django.core.files import temp as tempfile
 from django.core.files.uploadedfile import SimpleUploadedFile
 from django.http.multipartparser import MultiPartParser
 from django.test import TestCase, client
+from django.utils.six import StringIO
 from django.utils import unittest
 
 from . import uploadhandler
diff --git a/tests/regressiontests/i18n/commands/extraction.py b/tests/regressiontests/i18n/commands/extraction.py
index cd6d50893ac..29d9e277ff1 100644
--- a/tests/regressiontests/i18n/commands/extraction.py
+++ b/tests/regressiontests/i18n/commands/extraction.py
@@ -3,10 +3,10 @@
 import os
 import re
 import shutil
-from StringIO import StringIO
 
 from django.core import management
 from django.test import TestCase
+from django.utils.six import StringIO
 
 
 LOCALE='de'
diff --git a/tests/regressiontests/inspectdb/tests.py b/tests/regressiontests/inspectdb/tests.py
index 29435b83751..aae7bc5cc7b 100644
--- a/tests/regressiontests/inspectdb/tests.py
+++ b/tests/regressiontests/inspectdb/tests.py
@@ -1,7 +1,6 @@
-from StringIO import StringIO
-
 from django.core.management import call_command
 from django.test import TestCase, skipUnlessDBFeature
+from django.utils.six import StringIO
 
 
 class InspectDBTestCase(TestCase):
diff --git a/tests/regressiontests/mail/tests.py b/tests/regressiontests/mail/tests.py
index 2215f565237..0d0af19427e 100644
--- a/tests/regressiontests/mail/tests.py
+++ b/tests/regressiontests/mail/tests.py
@@ -7,7 +7,6 @@ import os
 import shutil
 import smtpd
 import sys
-from StringIO import StringIO
 import tempfile
 import threading
 
@@ -18,6 +17,7 @@ from django.core.mail.backends import console, dummy, locmem, filebased, smtp
 from django.core.mail.message import BadHeaderError
 from django.test import TestCase
 from django.test.utils import override_settings
+from django.utils.six import StringIO
 from django.utils.translation import ugettext_lazy
 
 
diff --git a/tests/regressiontests/middleware/tests.py b/tests/regressiontests/middleware/tests.py
index ead34f46dbc..08a385e6cfd 100644
--- a/tests/regressiontests/middleware/tests.py
+++ b/tests/regressiontests/middleware/tests.py
@@ -3,7 +3,6 @@
 import gzip
 import re
 import random
-import StringIO
 
 from django.conf import settings
 from django.core import mail
@@ -16,6 +15,7 @@ from django.middleware.gzip import GZipMiddleware
 from django.test import TestCase, RequestFactory
 from django.test.utils import override_settings
 from django.utils.six.moves import xrange
+from django.utils.six import StringIO
 
 class CommonMiddlewareTest(TestCase):
     def setUp(self):
@@ -526,7 +526,7 @@ class GZipMiddlewareTest(TestCase):
 
     @staticmethod
     def decompress(gzipped_string):
-        return gzip.GzipFile(mode='rb', fileobj=StringIO.StringIO(gzipped_string)).read()
+        return gzip.GzipFile(mode='rb', fileobj=StringIO(gzipped_string)).read()
 
     def test_compress_response(self):
         """
diff --git a/tests/regressiontests/multiple_database/tests.py b/tests/regressiontests/multiple_database/tests.py
index 595c5edb3b0..08632fd4ce2 100644
--- a/tests/regressiontests/multiple_database/tests.py
+++ b/tests/regressiontests/multiple_database/tests.py
@@ -2,7 +2,6 @@ from __future__ import absolute_import, unicode_literals
 
 import datetime
 import pickle
-from StringIO import StringIO
 
 from django.conf import settings
 from django.contrib.auth.models import User
@@ -11,6 +10,7 @@ from django.core import management
 from django.db import connections, router, DEFAULT_DB_ALIAS
 from django.db.models import signals
 from django.test import TestCase
+from django.utils.six import StringIO
 
 from .models import Book, Person, Pet, Review, UserProfile
 
diff --git a/tests/regressiontests/requests/tests.py b/tests/regressiontests/requests/tests.py
index 146dca2b7b7..f1924592468 100644
--- a/tests/regressiontests/requests/tests.py
+++ b/tests/regressiontests/requests/tests.py
@@ -3,7 +3,6 @@ from __future__ import unicode_literals
 import time
 import warnings
 from datetime import datetime, timedelta
-from StringIO import StringIO
 
 from django.conf import settings
 from django.core.handlers.wsgi import WSGIRequest, LimitedStream
@@ -11,6 +10,7 @@ from django.http import HttpRequest, HttpResponse, parse_cookie, build_request_r
 from django.test.utils import str_prefix
 from django.utils import unittest
 from django.utils.http import cookie_date
+from django.utils.six import StringIO
 from django.utils.timezone import utc
 
 
diff --git a/tests/regressiontests/templates/loaders.py b/tests/regressiontests/templates/loaders.py
index 5c119163082..6b635c8f239 100644
--- a/tests/regressiontests/templates/loaders.py
+++ b/tests/regressiontests/templates/loaders.py
@@ -12,13 +12,13 @@ if __name__ == '__main__':
 import sys
 import pkg_resources
 import imp
-import StringIO
 import os.path
 
 from django.template import TemplateDoesNotExist, Context
 from django.template.loaders.eggs import Loader as EggLoader
 from django.template import loader
 from django.utils import unittest
+from django.utils.six import StringIO
 
 
 # Mock classes and objects for pkg_resources functions.
@@ -61,8 +61,8 @@ class EggLoaderTest(unittest.TestCase):
 
         self.empty_egg = create_egg("egg_empty", {})
         self.egg_1 = create_egg("egg_1", {
-            os.path.normcase('templates/y.html') : StringIO.StringIO("y"),
-            os.path.normcase('templates/x.txt') : StringIO.StringIO("x"),
+            os.path.normcase('templates/y.html') : StringIO("y"),
+            os.path.normcase('templates/x.txt') : StringIO("x"),
         })
         self._old_installed_apps = settings.INSTALLED_APPS
         settings.INSTALLED_APPS = []
diff --git a/tests/regressiontests/test_utils/tests.py b/tests/regressiontests/test_utils/tests.py
index 46479ebe8b5..f43a855a590 100644
--- a/tests/regressiontests/test_utils/tests.py
+++ b/tests/regressiontests/test_utils/tests.py
@@ -493,7 +493,7 @@ __test__ = {"API_TEST": r"""
 # Standard doctests do fairly
 >>> import json
 >>> from django.utils.xmlutils import SimplerXMLGenerator
->>> from StringIO import StringIO
+>>> from django.utils.six import StringIO
 
 >>> def produce_long():
 ...     return 42L

From 12cda89ffe6a03031a321d61ff8b91f9978e4b2e Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Tue, 7 Aug 2012 15:49:33 +0200
Subject: [PATCH 74/88] [py3] Fixed a loop that changed dictionary size.

---
 django/db/models/fields/__init__.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 2c38e8d72e0..3737a504bb1 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -489,7 +489,7 @@ class Field(object):
             # Many of the subclass-specific formfield arguments (min_value,
             # max_value) don't apply for choice fields, so be sure to only pass
             # the values that TypedChoiceField will understand.
-            for k in kwargs.keys():
+            for k in list(six.iterkeys(kwargs)):
                 if k not in ('coerce', 'empty_value', 'choices', 'required',
                              'widget', 'label', 'initial', 'help_text',
                              'error_messages', 'show_hidden_initial'):

From 576ec12f8e7024679202b6213b8664ccd8b451b7 Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Wed, 8 Aug 2012 14:52:21 +0200
Subject: [PATCH 75/88] [py3] Replaced __nonzero__ by __bool__

Of course, __nonzero__ alias has been kept for Python 2 compatibility.
---
 django/contrib/auth/context_processors.py | 3 ++-
 django/core/files/base.py                 | 6 ++++--
 django/db/models/query.py                 | 3 ++-
 django/dispatch/saferef.py                | 3 ++-
 django/forms/formsets.py                  | 3 ++-
 django/utils/tree.py                      | 3 ++-
 docs/topics/db/optimization.txt           | 2 +-
 7 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/django/contrib/auth/context_processors.py b/django/contrib/auth/context_processors.py
index 3ffab01e94b..1b6c2eedd0c 100644
--- a/django/contrib/auth/context_processors.py
+++ b/django/contrib/auth/context_processors.py
@@ -11,8 +11,9 @@ class PermLookupDict(object):
     def __getitem__(self, perm_name):
         return self.user.has_perm("%s.%s" % (self.module_name, perm_name))
 
-    def __nonzero__(self):
+    def __bool__(self):
         return self.user.has_module_perms(self.module_name)
+    __nonzero__ = __bool__ # Python 2
 
 
 class PermWrapper(object):
diff --git a/django/core/files/base.py b/django/core/files/base.py
index 37b1be89b36..d0b25250a5a 100644
--- a/django/core/files/base.py
+++ b/django/core/files/base.py
@@ -26,8 +26,9 @@ class File(FileProxyMixin):
     def __repr__(self):
         return "<%s: %s>" % (self.__class__.__name__, self or "None")
 
-    def __nonzero__(self):
+    def __bool__(self):
         return bool(self.name)
+    __nonzero__ = __bool__ # Python 2
 
     def __len__(self):
         return self.size
@@ -135,8 +136,9 @@ class ContentFile(File):
     def __str__(self):
         return 'Raw content'
 
-    def __nonzero__(self):
+    def __bool__(self):
         return True
+    __nonzero__ = __bool__ # Python 2
 
     def open(self, mode=None):
         self.seek(0)
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 6013233a0f3..4441c1a4ef4 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -120,7 +120,7 @@ class QuerySet(object):
             if len(self._result_cache) <= pos:
                 self._fill_cache()
 
-    def __nonzero__(self):
+    def __bool__(self):
         if self._prefetch_related_lookups and not self._prefetch_done:
             # We need all the results in order to be able to do the prefetch
             # in one go. To minimize code duplication, we use the __len__
@@ -134,6 +134,7 @@ class QuerySet(object):
         except StopIteration:
             return False
         return True
+    __nonzero__ = __bool__ # Python 2
 
     def __contains__(self, val):
         # The 'in' operator works without this method, due to __iter__. This
diff --git a/django/dispatch/saferef.py b/django/dispatch/saferef.py
index 2a2c8739fb7..d8728e219a4 100644
--- a/django/dispatch/saferef.py
+++ b/django/dispatch/saferef.py
@@ -152,9 +152,10 @@ class BoundMethodWeakref(object):
     
     __repr__ = __str__
     
-    def __nonzero__( self ):
+    def __bool__( self ):
         """Whether we are still a valid reference"""
         return self() is not None
+    __nonzero__ = __bool__ # Python 2
 
     def __eq__(self, other):
         """Compare with another reference"""
diff --git a/django/forms/formsets.py b/django/forms/formsets.py
index 1ec83404620..4ea8dc4ca92 100644
--- a/django/forms/formsets.py
+++ b/django/forms/formsets.py
@@ -65,9 +65,10 @@ class BaseFormSet(StrAndUnicode):
     def __len__(self):
         return len(self.forms)
 
-    def __nonzero__(self):
+    def __bool__(self):
         """All formsets have a management form which is not included in the length"""
         return True
+    __nonzero__ = __bool__ # Python 2
 
     def _management_form(self):
         """Returns the ManagementForm instance for this FormSet."""
diff --git a/django/utils/tree.py b/django/utils/tree.py
index 36b5977942c..717181d2b99 100644
--- a/django/utils/tree.py
+++ b/django/utils/tree.py
@@ -68,11 +68,12 @@ class Node(object):
         """
         return len(self.children)
 
-    def __nonzero__(self):
+    def __bool__(self):
         """
         For truth value testing.
         """
         return bool(self.children)
+    __nonzero__ = __bool__ # Python 2
 
     def __contains__(self, other):
         """
diff --git a/docs/topics/db/optimization.txt b/docs/topics/db/optimization.txt
index 573e1fd0aa6..772792d39d9 100644
--- a/docs/topics/db/optimization.txt
+++ b/docs/topics/db/optimization.txt
@@ -230,7 +230,7 @@ It is optimal because:
 #. Use of :ttag:`with` means that we store ``user.emails.all`` in a variable
    for later use, allowing its cache to be re-used.
 
-#. The line ``{% if emails %}`` causes ``QuerySet.__nonzero__()`` to be called,
+#. The line ``{% if emails %}`` causes ``QuerySet.__bool__()`` to be called,
    which causes the ``user.emails.all()`` query to be run on the database, and
    at the least the first line to be turned into an ORM object. If there aren't
    any results, it will return False, otherwise True.

From 4c97101b1f0815a3f311fc77483b935fe62966bb Mon Sep 17 00:00:00 2001
From: Alex Gaynor <alex.gaynor@gmail.com>
Date: Wed, 8 Aug 2012 07:33:15 -0700
Subject: [PATCH 76/88] remove a bunch of unnescesarry iterkeys() calls

---
 django/conf/__init__.py                        |  2 +-
 django/contrib/admin/options.py                |  4 ++--
 .../contrib/admin/templatetags/admin_list.py   |  2 +-
 django/contrib/auth/admin.py                   |  2 +-
 django/contrib/auth/tests/forms.py             |  2 +-
 django/contrib/formtools/wizard/views.py       |  2 +-
 .../gis/db/backends/mysql/operations.py        |  2 +-
 .../gis/db/backends/oracle/operations.py       |  2 +-
 .../gis/db/backends/postgis/operations.py      |  4 ++--
 .../gis/db/backends/spatialite/operations.py   |  2 +-
 django/contrib/gis/db/models/query.py          |  2 +-
 django/contrib/gis/db/models/sql/compiler.py   |  2 +-
 django/core/management/__init__.py             |  2 +-
 django/core/serializers/__init__.py            |  2 +-
 django/core/validators.py                      |  2 +-
 django/db/models/base.py                       |  4 ++--
 django/db/models/deletion.py                   |  2 +-
 django/db/models/fields/__init__.py            |  2 +-
 django/db/models/fields/related.py             |  8 ++++----
 django/db/models/options.py                    |  4 ++--
 django/db/models/query.py                      | 18 +++++++++---------
 django/db/models/sql/query.py                  |  6 +++---
 django/template/defaulttags.py                 |  2 +-
 django/utils/datastructures.py                 |  2 +-
 django/utils/dictconfig.py                     |  2 +-
 25 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/django/conf/__init__.py b/django/conf/__init__.py
index 6325ccb1a91..e1c3fd18080 100644
--- a/django/conf/__init__.py
+++ b/django/conf/__init__.py
@@ -158,7 +158,7 @@ class UserSettingsHolder(BaseSettings):
         return getattr(self.default_settings, name)
 
     def __dir__(self):
-        return list(six.iterkeys(self.__dict__)) + dir(self.default_settings)
+        return list(self.__dict__) + dir(self.default_settings)
 
     # For Python < 2.6:
     __members__ = property(lambda self: self.__dir__())
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 7708050e6f8..081d00121b1 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -425,7 +425,7 @@ class ModelAdmin(BaseModelAdmin):
         if self.declared_fieldsets:
             return self.declared_fieldsets
         form = self.get_form(request, obj)
-        fields = list(six.iterkeys(form.base_fields)) + list(self.get_readonly_fields(request, obj))
+        fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
         return [(None, {'fields': fields})]
 
     def get_form(self, request, obj=None, **kwargs):
@@ -1415,7 +1415,7 @@ class InlineModelAdmin(BaseModelAdmin):
         if self.declared_fieldsets:
             return self.declared_fieldsets
         form = self.get_formset(request, obj).form
-        fields = list(six.iterkeys(form.base_fields)) + list(self.get_readonly_fields(request, obj))
+        fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
         return [(None, {'fields': fields})]
 
     def queryset(self, request):
diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py
index b8b64d032f3..1873d449898 100644
--- a/django/contrib/admin/templatetags/admin_list.py
+++ b/django/contrib/admin/templatetags/admin_list.py
@@ -126,7 +126,7 @@ def result_headers(cl):
         if i in ordering_field_columns:
             sorted = True
             order_type = ordering_field_columns.get(i).lower()
-            sort_priority = list(six.iterkeys(ordering_field_columns)).index(i) + 1
+            sort_priority = list(ordering_field_columns).index(i) + 1
             th_classes.append('sorted %sending' % order_type)
             new_order_type = {'asc': 'desc', 'desc': 'asc'}[order_type]
 
diff --git a/django/contrib/auth/admin.py b/django/contrib/auth/admin.py
index cb09822f52b..ccf940d16d9 100644
--- a/django/contrib/auth/admin.py
+++ b/django/contrib/auth/admin.py
@@ -129,7 +129,7 @@ class UserAdmin(admin.ModelAdmin):
         else:
             form = self.change_password_form(user)
 
-        fieldsets = [(None, {'fields': list(six.iterkeys(form.base_fields))})]
+        fieldsets = [(None, {'fields': list(form.base_fields)})]
         adminForm = admin.helpers.AdminForm(form, fieldsets, {})
 
         context = {
diff --git a/django/contrib/auth/tests/forms.py b/django/contrib/auth/tests/forms.py
index f917ea26016..594b55c6336 100644
--- a/django/contrib/auth/tests/forms.py
+++ b/django/contrib/auth/tests/forms.py
@@ -204,7 +204,7 @@ class PasswordChangeFormTest(TestCase):
     def test_field_order(self):
         # Regression test - check the order of fields:
         user = User.objects.get(username='testclient')
-        self.assertEqual(list(six.iterkeys(PasswordChangeForm(user, {}).fields)),
+        self.assertEqual(list(PasswordChangeForm(user, {}).fields),
                          ['old_password', 'new_password1', 'new_password2'])
 
 
diff --git a/django/contrib/formtools/wizard/views.py b/django/contrib/formtools/wizard/views.py
index 741b7e52b6b..ea41e86852b 100644
--- a/django/contrib/formtools/wizard/views.py
+++ b/django/contrib/formtools/wizard/views.py
@@ -44,7 +44,7 @@ class StepsHelper(object):
     @property
     def all(self):
         "Returns the names of all steps/forms."
-        return list(six.iterkeys(self._wizard.get_form_list()))
+        return list(self._wizard.get_form_list())
 
     @property
     def count(self):
diff --git a/django/contrib/gis/db/backends/mysql/operations.py b/django/contrib/gis/db/backends/mysql/operations.py
index 277b7648102..7152f4682d4 100644
--- a/django/contrib/gis/db/backends/mysql/operations.py
+++ b/django/contrib/gis/db/backends/mysql/operations.py
@@ -32,7 +32,7 @@ class MySQLOperations(DatabaseOperations, BaseSpatialOperations):
         'within' : 'MBRWithin',
         }
 
-    gis_terms = dict([(term, None) for term in list(six.iterkeys(geometry_functions)) + ['isnull']])
+    gis_terms = dict([(term, None) for term in list(geometry_functions) + ['isnull']])
 
     def geo_db_type(self, f):
         return f.geom_type
diff --git a/django/contrib/gis/db/backends/oracle/operations.py b/django/contrib/gis/db/backends/oracle/operations.py
index 5db30e6fc69..392feb129be 100644
--- a/django/contrib/gis/db/backends/oracle/operations.py
+++ b/django/contrib/gis/db/backends/oracle/operations.py
@@ -128,7 +128,7 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
     geometry_functions.update(distance_functions)
 
     gis_terms = ['isnull']
-    gis_terms += list(six.iterkeys(geometry_functions))
+    gis_terms += list(geometry_functions)
     gis_terms = dict([(term, None) for term in gis_terms])
 
     truncate_params = {'relate' : None}
diff --git a/django/contrib/gis/db/backends/postgis/operations.py b/django/contrib/gis/db/backends/postgis/operations.py
index 92f8925a7d8..434d8719ccc 100644
--- a/django/contrib/gis/db/backends/postgis/operations.py
+++ b/django/contrib/gis/db/backends/postgis/operations.py
@@ -217,8 +217,8 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
 
         # Creating a dictionary lookup of all GIS terms for PostGIS.
         gis_terms = ['isnull']
-        gis_terms += list(six.iterkeys(self.geometry_operators))
-        gis_terms += list(six.iterkeys(self.geometry_functions))
+        gis_terms += list(self.geometry_operators)
+        gis_terms += list(self.geometry_functions)
         self.gis_terms = dict([(term, None) for term in gis_terms])
 
         self.area = prefix + 'Area'
diff --git a/django/contrib/gis/db/backends/spatialite/operations.py b/django/contrib/gis/db/backends/spatialite/operations.py
index 31c98212e99..60fe0a80696 100644
--- a/django/contrib/gis/db/backends/spatialite/operations.py
+++ b/django/contrib/gis/db/backends/spatialite/operations.py
@@ -131,7 +131,7 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
 
         # Creating the GIS terms dictionary.
         gis_terms = ['isnull']
-        gis_terms += list(six.iterkeys(self.geometry_functions))
+        gis_terms += list(self.geometry_functions)
         self.gis_terms = dict([(term, None) for term in gis_terms])
 
         if version >= (2, 4, 0):
diff --git a/django/contrib/gis/db/models/query.py b/django/contrib/gis/db/models/query.py
index 6dc36d6ab89..cc61dfa4d2f 100644
--- a/django/contrib/gis/db/models/query.py
+++ b/django/contrib/gis/db/models/query.py
@@ -26,7 +26,7 @@ class GeoQuerySet(QuerySet):
         flat = kwargs.pop('flat', False)
         if kwargs:
             raise TypeError('Unexpected keyword arguments to values_list: %s'
-                    % (list(six.iterkeys(kwargs)),))
+                    % (list(kwargs),))
         if flat and len(fields) > 1:
             raise TypeError("'flat' is not valid when values_list is called with more than one field.")
         return self._clone(klass=GeoValuesListQuerySet, setup=True, flat=flat,
diff --git a/django/contrib/gis/db/models/sql/compiler.py b/django/contrib/gis/db/models/sql/compiler.py
index 64d1a4d869d..5c8d2647f7f 100644
--- a/django/contrib/gis/db/models/sql/compiler.py
+++ b/django/contrib/gis/db/models/sql/compiler.py
@@ -171,7 +171,7 @@ class GeoSQLCompiler(compiler.SQLCompiler):
         objects.
         """
         values = []
-        aliases = list(six.iterkeys(self.query.extra_select))
+        aliases = list(self.query.extra_select)
 
         # Have to set a starting row number offset that is used for
         # determining the correct starting row index -- needed for
diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
index e2f9798dcd2..268cd63c388 100644
--- a/django/core/management/__init__.py
+++ b/django/core/management/__init__.py
@@ -295,7 +295,7 @@ class ManagementUtility(object):
         except IndexError:
             curr = ''
 
-        subcommands = list(six.iterkeys(get_commands())) + ['help']
+        subcommands = list(get_commands()) + ['help']
         options = [('--help', None)]
 
         # subcommand
diff --git a/django/core/serializers/__init__.py b/django/core/serializers/__init__.py
index 2d5e7624a45..cf7e66190f4 100644
--- a/django/core/serializers/__init__.py
+++ b/django/core/serializers/__init__.py
@@ -76,7 +76,7 @@ def get_serializer(format):
 def get_serializer_formats():
     if not _serializers:
         _load_serializers()
-    return list(six.iterkeys(_serializers))
+    return list(_serializers)
 
 def get_public_serializer_formats():
     if not _serializers:
diff --git a/django/core/validators.py b/django/core/validators.py
index fd5dfa28d6d..456fa3cec53 100644
--- a/django/core/validators.py
+++ b/django/core/validators.py
@@ -138,7 +138,7 @@ def ip_address_validators(protocol, unpack_ipv4):
         return ip_address_validator_map[protocol.lower()]
     except KeyError:
         raise ValueError("The protocol '%s' is unknown. Supported: %s"
-                         % (protocol, list(six.iterkeys(ip_address_validator_map))))
+                         % (protocol, list(ip_address_validator_map)))
 
 comma_separated_int_list_re = re.compile('^[\d,]+$')
 validate_comma_separated_integer_list = RegexValidator(comma_separated_int_list_re, _('Enter only digits separated by commas.'), 'invalid')
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 35ae2231d66..569b8e876c8 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -388,14 +388,14 @@ class Model(six.with_metaclass(ModelBase, object)):
                 setattr(self, field.attname, val)
 
         if kwargs:
-            for prop in list(six.iterkeys(kwargs)):
+            for prop in list(kwargs):
                 try:
                     if isinstance(getattr(self.__class__, prop), property):
                         setattr(self, prop, kwargs.pop(prop))
                 except AttributeError:
                     pass
             if kwargs:
-                raise TypeError("'%s' is an invalid keyword argument for this function" % list(six.iterkeys(kwargs))[0])
+                raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
         super(Model, self).__init__()
         signals.post_init.send(sender=self.__class__, instance=self)
 
diff --git a/django/db/models/deletion.py b/django/db/models/deletion.py
index 2e5ed53e636..4449b75a818 100644
--- a/django/db/models/deletion.py
+++ b/django/db/models/deletion.py
@@ -207,7 +207,7 @@ class Collector(object):
     def sort(self):
         sorted_models = []
         concrete_models = set()
-        models = list(six.iterkeys(self.data))
+        models = list(self.data)
         while len(sorted_models) < len(models):
             found = False
             for model in models:
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 3737a504bb1..d07851bbf57 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -489,7 +489,7 @@ class Field(object):
             # Many of the subclass-specific formfield arguments (min_value,
             # max_value) don't apply for choice fields, so be sure to only pass
             # the values that TypedChoiceField will understand.
-            for k in list(six.iterkeys(kwargs)):
+            for k in list(kwargs):
                 if k not in ('coerce', 'empty_value', 'choices', 'required',
                              'widget', 'label', 'initial', 'help_text',
                              'error_messages', 'show_hidden_initial'):
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index eaa62c60613..08cc0a747f3 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -241,7 +241,7 @@ class SingleRelatedObjectDescriptor(object):
         rel_obj_attr = attrgetter(self.related.field.attname)
         instance_attr = lambda obj: obj._get_pk_val()
         instances_dict = dict((instance_attr(inst), inst) for inst in instances)
-        params = {'%s__pk__in' % self.related.field.name: list(six.iterkeys(instances_dict))}
+        params = {'%s__pk__in' % self.related.field.name: list(instances_dict)}
         qs = self.get_query_set(instance=instances[0]).filter(**params)
         # Since we're going to assign directly in the cache,
         # we must manage the reverse relation cache manually.
@@ -335,9 +335,9 @@ class ReverseSingleRelatedObjectDescriptor(object):
         instance_attr = attrgetter(self.field.attname)
         instances_dict = dict((instance_attr(inst), inst) for inst in instances)
         if other_field.rel:
-            params = {'%s__pk__in' % self.field.rel.field_name: list(six.iterkeys(instances_dict))}
+            params = {'%s__pk__in' % self.field.rel.field_name: list(instances_dict)}
         else:
-            params = {'%s__in' % self.field.rel.field_name: list(six.iterkeys(instances_dict))}
+            params = {'%s__in' % self.field.rel.field_name: list(instances_dict)}
         qs = self.get_query_set(instance=instances[0]).filter(**params)
         # Since we're going to assign directly in the cache,
         # we must manage the reverse relation cache manually.
@@ -488,7 +488,7 @@ class ForeignRelatedObjectsDescriptor(object):
                 instance_attr = attrgetter(attname)
                 instances_dict = dict((instance_attr(inst), inst) for inst in instances)
                 db = self._db or router.db_for_read(self.model, instance=instances[0])
-                query = {'%s__%s__in' % (rel_field.name, attname): list(six.iterkeys(instances_dict))}
+                query = {'%s__%s__in' % (rel_field.name, attname): list(instances_dict)}
                 qs = super(RelatedManager, self).get_query_set().using(db).filter(**query)
                 # Since we just bypassed this class' get_query_set(), we must manage
                 # the reverse relation manually.
diff --git a/django/db/models/options.py b/django/db/models/options.py
index 239ad30b069..2e8ccb49ce7 100644
--- a/django/db/models/options.py
+++ b/django/db/models/options.py
@@ -258,7 +258,7 @@ class Options(object):
             self._m2m_cache
         except AttributeError:
             self._fill_m2m_cache()
-        return list(six.iterkeys(self._m2m_cache))
+        return list(self._m2m_cache)
     many_to_many = property(_many_to_many)
 
     def get_m2m_with_model(self):
@@ -416,7 +416,7 @@ class Options(object):
             cache = self._fill_related_many_to_many_cache()
         if local_only:
             return [k for k, v in cache.items() if not v]
-        return list(six.iterkeys(cache))
+        return list(cache)
 
     def get_all_related_m2m_objects_with_model(self):
         """
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 4441c1a4ef4..e8d6ae2a7b3 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -246,8 +246,8 @@ class QuerySet(object):
             requested = None
         max_depth = self.query.max_depth
 
-        extra_select = list(six.iterkeys(self.query.extra_select))
-        aggregate_select = list(six.iterkeys(self.query.aggregate_select))
+        extra_select = list(self.query.extra_select)
+        aggregate_select = list(self.query.aggregate_select)
 
         only_load = self.query.get_loaded_field_names()
         if not fill_cache:
@@ -594,7 +594,7 @@ class QuerySet(object):
         flat = kwargs.pop('flat', False)
         if kwargs:
             raise TypeError('Unexpected keyword arguments to values_list: %s'
-                    % (list(six.iterkeys(kwargs)),))
+                    % (list(kwargs),))
         if flat and len(fields) > 1:
             raise TypeError("'flat' is not valid when values_list is called with more than one field.")
         return self._clone(klass=ValuesListQuerySet, setup=True, flat=flat,
@@ -694,7 +694,7 @@ class QuerySet(object):
         depth = kwargs.pop('depth', 0)
         if kwargs:
             raise TypeError('Unexpected keyword arguments to select_related: %s'
-                    % (list(six.iterkeys(kwargs)),))
+                    % (list(kwargs),))
         obj = self._clone()
         if fields:
             if depth:
@@ -752,7 +752,7 @@ class QuerySet(object):
 
         obj = self._clone()
 
-        obj._setup_aggregate_query(list(six.iterkeys(kwargs)))
+        obj._setup_aggregate_query(list(kwargs))
 
         # Add the aggregates to the query
         for (alias, aggregate_expr) in kwargs.items():
@@ -967,9 +967,9 @@ class ValuesQuerySet(QuerySet):
 
     def iterator(self):
         # Purge any extra columns that haven't been explicitly asked for
-        extra_names = list(six.iterkeys(self.query.extra_select))
+        extra_names = list(self.query.extra_select)
         field_names = self.field_names
-        aggregate_names = list(six.iterkeys(self.query.aggregate_select))
+        aggregate_names = list(self.query.aggregate_select)
 
         names = extra_names + field_names + aggregate_names
 
@@ -1098,9 +1098,9 @@ class ValuesListQuerySet(ValuesQuerySet):
             # When extra(select=...) or an annotation is involved, the extra
             # cols are always at the start of the row, and we need to reorder
             # the fields to match the order in self._fields.
-            extra_names = list(six.iterkeys(self.query.extra_select))
+            extra_names = list(self.query.extra_select)
             field_names = self.field_names
-            aggregate_names = list(six.iterkeys(self.query.aggregate_select))
+            aggregate_names = list(self.query.aggregate_select)
 
             names = extra_names + field_names + aggregate_names
 
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 69dda228bd7..be257a54106 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1303,7 +1303,7 @@ class Query(object):
                         field, model, direct, m2m = opts.get_field_by_name(f.name)
                         break
                 else:
-                    names = opts.get_all_field_names() + list(six.iterkeys(self.aggregate_select))
+                    names = opts.get_all_field_names() + list(self.aggregate_select)
                     raise FieldError("Cannot resolve keyword %r into field. "
                             "Choices are: %s" % (name, ", ".join(names)))
 
@@ -1661,8 +1661,8 @@ class Query(object):
                 # from the model on which the lookup failed.
                 raise
             else:
-                names = sorted(opts.get_all_field_names() + list(six.iterkeys(self.extra))
-                               + list(six.iterkeys(self.aggregate_select)))
+                names = sorted(opts.get_all_field_names() + list(self.extra)
+                               + list(self.aggregate_select))
                 raise FieldError("Cannot resolve keyword %r into field. "
                                  "Choices are: %s" % (name, ", ".join(names)))
         self.remove_inherited_models()
diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
index dca47a3da8d..14391f08e1d 100644
--- a/django/template/defaulttags.py
+++ b/django/template/defaulttags.py
@@ -1189,7 +1189,7 @@ def templatetag(parser, token):
     if tag not in TemplateTagNode.mapping:
         raise TemplateSyntaxError("Invalid templatetag argument: '%s'."
                                   " Must be one of: %s" %
-                                  (tag, list(six.iterkeys(TemplateTagNode.mapping))))
+                                  (tag, list(TemplateTagNode.mapping)))
     return TemplateTagNode(tag)
 
 @register.tag
diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py
index bbd31ad36cf..ad175731045 100644
--- a/django/utils/datastructures.py
+++ b/django/utils/datastructures.py
@@ -129,7 +129,7 @@ class SortedDict(dict):
             data = list(data)
         super(SortedDict, self).__init__(data)
         if isinstance(data, dict):
-            self.keyOrder = list(six.iterkeys(data))
+            self.keyOrder = list(data)
         else:
             self.keyOrder = []
             seen = set()
diff --git a/django/utils/dictconfig.py b/django/utils/dictconfig.py
index f8d6eebf89b..c7b39819b59 100644
--- a/django/utils/dictconfig.py
+++ b/django/utils/dictconfig.py
@@ -363,7 +363,7 @@ class DictConfigurator(BaseConfigurator):
                 #which were in the previous configuration but
                 #which are not in the new configuration.
                 root = logging.root
-                existing = list(six.iterkeys(root.manager.loggerDict))
+                existing = list(root.manager.loggerDict)
                 #The list needs to be sorted so that we can
                 #avoid disabling child loggers of explicitly
                 #named loggers. With a sorted list it is easier

From 7515f6576b593c5f7a1ff2b2f934d5442b52b884 Mon Sep 17 00:00:00 2001
From: Alex Gaynor <alex.gaynor@gmail.com>
Date: Wed, 8 Aug 2012 07:37:10 -0700
Subject: [PATCH 77/88] Fix TestCase.assertQuerysetEqual on python 3, this is
 needed for a large number of tests

---
 django/test/testcases.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/django/test/testcases.py b/django/test/testcases.py
index 3a0dc760c69..56ba56caf12 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -796,9 +796,10 @@ class TransactionTestCase(SimpleTestCase):
             " the response" % template_name)
 
     def assertQuerysetEqual(self, qs, values, transform=repr, ordered=True):
+        items = six.moves.map(transform, qs)
         if not ordered:
-            return self.assertEqual(set(map(transform, qs)), set(values))
-        return self.assertEqual(map(transform, qs), values)
+            return self.assertEqual(set(items), set(values))
+        return self.assertEqual(list(items), values)
 
     def assertNumQueries(self, num, func=None, *args, **kwargs):
         using = kwargs.pop("using", DEFAULT_DB_ALIAS)

From 0955d16a165e9da2f69813cc9983fd10dddbfa62 Mon Sep 17 00:00:00 2001
From: Alex Gaynor <alex.gaynor@gmail.com>
Date: Wed, 8 Aug 2012 07:50:59 -0700
Subject: [PATCH 78/88] Switched to using the standard method for comparing
 querysets in teh templates.

---
 tests/regressiontests/multiple_database/tests.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tests/regressiontests/multiple_database/tests.py b/tests/regressiontests/multiple_database/tests.py
index 08632fd4ce2..74a5f2f550f 100644
--- a/tests/regressiontests/multiple_database/tests.py
+++ b/tests/regressiontests/multiple_database/tests.py
@@ -2,6 +2,7 @@ from __future__ import absolute_import, unicode_literals
 
 import datetime
 import pickle
+from operator import attrgetter
 
 from django.conf import settings
 from django.contrib.auth.models import User
@@ -873,10 +874,10 @@ class QueryTestCase(TestCase):
         dive = Book.objects.using('other').create(title="Dive into Python",
             published=datetime.date(2009, 5, 4))
         val = Book.objects.db_manager("other").raw('SELECT id FROM multiple_database_book')
-        self.assertEqual(map(lambda o: o.pk, val), [dive.pk])
+        self.assertQuerysetEqual(val, [dive.pk], attrgetter("pk"))
 
         val = Book.objects.raw('SELECT id FROM multiple_database_book').using('other')
-        self.assertEqual(map(lambda o: o.pk, val), [dive.pk])
+        self.assertQuerysetEqual(val, [dive.pk], attrgetter("pk"))
 
     def test_select_related(self):
         "Database assignment is retained if an object is retrieved with select_related()"

From db729266d6feb3b4b4519bd789c4693b9aac00d1 Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Wed, 8 Aug 2012 17:59:31 +0200
Subject: [PATCH 79/88] [py3] Fixed 'iterable but non string' detection

In Python 3, the str type has an __iter__ attribute. Therefore, the
presence of an __iter__ attribute is not sufficient to distinguish
'standard' iterables (list, tuple) from strings.
---
 django/contrib/admin/helpers.py   | 2 +-
 django/core/serializers/python.py | 4 ++--
 django/forms/models.py            | 2 +-
 django/http/__init__.py           | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py
index aeacd234a34..90370bd9783 100644
--- a/django/contrib/admin/helpers.py
+++ b/django/contrib/admin/helpers.py
@@ -94,7 +94,7 @@ class Fieldset(object):
 class Fieldline(object):
     def __init__(self, form, field, readonly_fields=None, model_admin=None):
         self.form = form # A django.forms.Form instance
-        if not hasattr(field, "__iter__"):
+        if not hasattr(field, "__iter__") or isinstance(field, six.text_type):
             self.fields = [field]
         else:
             self.fields = field
diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py
index 348ff1dada4..a1fff6f9bbc 100644
--- a/django/core/serializers/python.py
+++ b/django/core/serializers/python.py
@@ -98,7 +98,7 @@ def Deserializer(object_list, **options):
             if field.rel and isinstance(field.rel, models.ManyToManyRel):
                 if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
                     def m2m_convert(value):
-                        if hasattr(value, '__iter__'):
+                        if hasattr(value, '__iter__') and not isinstance(value, six.text_type):
                             return field.rel.to._default_manager.db_manager(db).get_by_natural_key(*value).pk
                         else:
                             return smart_text(field.rel.to._meta.pk.to_python(value))
@@ -110,7 +110,7 @@ def Deserializer(object_list, **options):
             elif field.rel and isinstance(field.rel, models.ManyToOneRel):
                 if field_value is not None:
                     if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
-                        if hasattr(field_value, '__iter__'):
+                        if hasattr(field_value, '__iter__') and not isinstance(field_value, six.text_type):
                             obj = field.rel.to._default_manager.db_manager(db).get_by_natural_key(*field_value)
                             value = getattr(obj, field.rel.field_name)
                             # If this is a natural foreign key to an object that
diff --git a/django/forms/models.py b/django/forms/models.py
index 80d2a6536fc..0b07d31d9a4 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -1035,6 +1035,6 @@ class ModelMultipleChoiceField(ModelChoiceField):
         return qs
 
     def prepare_value(self, value):
-        if hasattr(value, '__iter__'):
+        if hasattr(value, '__iter__') and not isinstance(value, six.text_type):
             return [super(ModelMultipleChoiceField, self).prepare_value(v) for v in value]
         return super(ModelMultipleChoiceField, self).prepare_value(value)
diff --git a/django/http/__init__.py b/django/http/__init__.py
index d559fdf7c67..cc138917b91 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -656,7 +656,7 @@ class HttpResponse(object):
         return b''.join([smart_bytes(e, self._charset) for e in self._container])
 
     def _set_content(self, value):
-        if hasattr(value, '__iter__'):
+        if hasattr(value, '__iter__') and not isinstance(value, (bytes, six.text_type)):
             self._container = value
             self._base_content_is_iter = True
         else:

From 7731cc8689b47ca83e988919b44bcec2c6728e4e Mon Sep 17 00:00:00 2001
From: James Bennett <james@b-list.org>
Date: Wed, 8 Aug 2012 12:49:28 -0400
Subject: [PATCH 80/88] Fix #18062: Document best practices for choices in
 model fields.

---
 docs/ref/models/fields.txt | 47 +++++++++++++++++++-------------------
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt
index 67bb0f141f1..a43163c5e9b 100644
--- a/docs/ref/models/fields.txt
+++ b/docs/ref/models/fields.txt
@@ -86,42 +86,43 @@ field.
 If this is given, Django's admin will use a select box instead of the standard
 text field and will limit choices to the choices given.
 
-A choices list looks like this::
+A choices list is an iterable of 2-tuples; the first element in each
+tuple is the actual value to be stored, and the second element is the
+human-readable name. For example::
 
     YEAR_IN_SCHOOL_CHOICES = (
         ('FR', 'Freshman'),
         ('SO', 'Sophomore'),
         ('JR', 'Junior'),
         ('SR', 'Senior'),
-        ('GR', 'Graduate'),
     )
 
-The first element in each tuple is the actual value to be stored. The second
-element is the human-readable name for the option.
+Generally, it's best to define choices inside a model class, and to
+define a suitably-named constant for each value::
 
-The choices list can be defined either as part of your model class::
-
-    class Foo(models.Model):
+    class Student(models.Model):
+        FRESHMAN = 'FR'
+        SOPHOMORE = 'SO'
+        JUNIOR = 'JR'
+        SENIOR = 'SR'
         YEAR_IN_SCHOOL_CHOICES = (
-            ('FR', 'Freshman'),
-            ('SO', 'Sophomore'),
-            ('JR', 'Junior'),
-            ('SR', 'Senior'),
-            ('GR', 'Graduate'),
+            (FRESHMAN, 'Freshman'),
+            (SOPHOMORE, 'Sophomore'),
+            (JUNIOR, 'Junior'),
+            (SENIOR, 'Senior'),
         )
-        year_in_school = models.CharField(max_length=2, choices=YEAR_IN_SCHOOL_CHOICES)
+        year_in_school = models.CharField(max_length=2,
+                                          choices=YEAR_IN_SCHOOL_CHOICES,
+                                          default=FRESHMAN)
 
-or outside your model class altogether::
+        def is_upperclass(self):
+	    return self.year_in_school in (self.JUNIOR, self.SENIOR)
 
-    YEAR_IN_SCHOOL_CHOICES = (
-        ('FR', 'Freshman'),
-        ('SO', 'Sophomore'),
-        ('JR', 'Junior'),
-        ('SR', 'Senior'),
-        ('GR', 'Graduate'),
-    )
-    class Foo(models.Model):
-        year_in_school = models.CharField(max_length=2, choices=YEAR_IN_SCHOOL_CHOICES)
+Though you can define a choices list outside of a model class and then
+refer to it, defining the choices and names for each choice inside the
+model class keeps all of that information with the class that uses it,
+and makes the choices easy to reference (e.g, ``Student.SOPHOMORE``
+will work anywhere that the ``Student`` model has been imported).
 
 You can also collect your available choices into named groups that can
 be used for organizational purposes::

From b8e49d70f2bbbb9008dbbf9d8b0dee46dcf25fa6 Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Wed, 8 Aug 2012 19:08:05 +0200
Subject: [PATCH 81/88] [py3] Replaced raw_input by input

The six addition has been borrowed from:
https://bitbucket.org/gutworth/six/changeset/733ef740
---
 django/contrib/auth/management/__init__.py                   | 5 +++--
 django/contrib/auth/management/commands/createsuperuser.py   | 5 +++--
 django/contrib/contenttypes/management.py                    | 3 ++-
 .../contrib/staticfiles/management/commands/collectstatic.py | 3 ++-
 django/core/management/commands/flush.py                     | 3 ++-
 django/db/backends/creation.py                               | 3 ++-
 django/db/backends/oracle/creation.py                        | 5 +++--
 django/db/backends/sqlite3/creation.py                       | 3 ++-
 django/utils/six.py                                          | 1 +
 9 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py
index 100acb6c5be..7abd2abcf44 100644
--- a/django/contrib/auth/management/__init__.py
+++ b/django/contrib/auth/management/__init__.py
@@ -9,6 +9,7 @@ import unicodedata
 from django.contrib.auth import models as auth_app
 from django.db.models import get_models, signals
 from django.contrib.auth.models import User
+from django.utils.six.moves import input
 
 
 def _get_permission_codename(action, opts):
@@ -66,10 +67,10 @@ def create_superuser(app, created_models, verbosity, db, **kwargs):
         msg = ("\nYou just installed Django's auth system, which means you "
             "don't have any superusers defined.\nWould you like to create one "
             "now? (yes/no): ")
-        confirm = raw_input(msg)
+        confirm = input(msg)
         while 1:
             if confirm not in ('yes', 'no'):
-                confirm = raw_input('Please enter either "yes" or "no": ')
+                confirm = input('Please enter either "yes" or "no": ')
                 continue
             if confirm == 'yes':
                 call_command("createsuperuser", interactive=True, database=db)
diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py
index f3f1a7b671c..6e0d0bc7541 100644
--- a/django/contrib/auth/management/commands/createsuperuser.py
+++ b/django/contrib/auth/management/commands/createsuperuser.py
@@ -12,6 +12,7 @@ from django.contrib.auth.management import get_default_username
 from django.core import exceptions
 from django.core.management.base import BaseCommand, CommandError
 from django.db import DEFAULT_DB_ALIAS
+from django.utils.six.moves import input
 from django.utils.translation import ugettext as _
 
 RE_VALID_USERNAME = re.compile('[\w.@+-]+$')
@@ -76,7 +77,7 @@ class Command(BaseCommand):
                         input_msg = 'Username'
                         if default_username:
                             input_msg += ' (leave blank to use %r)' % default_username
-                        username = raw_input(input_msg + ': ')
+                        username = input(input_msg + ': ')
                     if default_username and username == '':
                         username = default_username
                     if not RE_VALID_USERNAME.match(username):
@@ -94,7 +95,7 @@ class Command(BaseCommand):
                 # Get an email
                 while 1:
                     if not email:
-                        email = raw_input('E-mail address: ')
+                        email = input('E-mail address: ')
                     try:
                         is_valid_email(email)
                     except exceptions.ValidationError:
diff --git a/django/contrib/contenttypes/management.py b/django/contrib/contenttypes/management.py
index 11ca7e47634..9f287d494bf 100644
--- a/django/contrib/contenttypes/management.py
+++ b/django/contrib/contenttypes/management.py
@@ -2,6 +2,7 @@ from django.contrib.contenttypes.models import ContentType
 from django.db.models import get_apps, get_models, signals
 from django.utils.encoding import smart_text
 from django.utils import six
+from django.utils.six.moves import input
 
 def update_contenttypes(app, created_models, verbosity=2, **kwargs):
     """
@@ -49,7 +50,7 @@ def update_contenttypes(app, created_models, verbosity=2, **kwargs):
                 '    %s | %s' % (ct.app_label, ct.model)
                 for ct in to_remove
             ])
-            ok_to_delete = raw_input("""The following content types are stale and need to be deleted:
+            ok_to_delete = input("""The following content types are stale and need to be deleted:
 
 %s
 
diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py
index 45c5ecfe1fd..7dac0ffb4cb 100644
--- a/django/contrib/staticfiles/management/commands/collectstatic.py
+++ b/django/contrib/staticfiles/management/commands/collectstatic.py
@@ -8,6 +8,7 @@ from django.core.files.storage import FileSystemStorage
 from django.core.management.base import CommandError, NoArgsCommand
 from django.utils.encoding import smart_text
 from django.utils.datastructures import SortedDict
+from django.utils.six.moves import input
 
 from django.contrib.staticfiles import finders, storage
 
@@ -148,7 +149,7 @@ class Command(NoArgsCommand):
             clear_display = 'This will overwrite existing files!'
 
         if self.interactive:
-            confirm = raw_input("""
+            confirm = input("""
 You have requested to collect static files at the destination
 location as specified in your settings%s
 
diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py
index ac7b7a35993..b8b78434ceb 100644
--- a/django/core/management/commands/flush.py
+++ b/django/core/management/commands/flush.py
@@ -7,6 +7,7 @@ from django.core.management.base import NoArgsCommand, CommandError
 from django.core.management.color import no_style
 from django.core.management.sql import sql_flush, emit_post_sync_signal
 from django.utils.importlib import import_module
+from django.utils.six.moves import input
 
 
 class Command(NoArgsCommand):
@@ -45,7 +46,7 @@ class Command(NoArgsCommand):
         sql_list = sql_flush(self.style, connection, only_django=True, reset_sequences=reset_sequences)
 
         if interactive:
-            confirm = raw_input("""You have requested a flush of the database.
+            confirm = input("""You have requested a flush of the database.
 This will IRREVERSIBLY DESTROY all data currently in the %r database,
 and return each table to the state it was in after syncdb.
 Are you sure you want to do this?
diff --git a/django/db/backends/creation.py b/django/db/backends/creation.py
index fcc6ab75841..6ac55eb5ff0 100644
--- a/django/db/backends/creation.py
+++ b/django/db/backends/creation.py
@@ -3,6 +3,7 @@ import time
 
 from django.conf import settings
 from django.db.utils import load_backend
+from django.utils.six.moves import input
 
 # The prefix to put on the default database name when creating
 # the test database.
@@ -330,7 +331,7 @@ class BaseDatabaseCreation(object):
             sys.stderr.write(
                 "Got an error creating the test database: %s\n" % e)
             if not autoclobber:
-                confirm = raw_input(
+                confirm = input(
                     "Type 'yes' if you would like to try deleting the test "
                     "database '%s', or 'no' to cancel: " % test_database_name)
             if autoclobber or confirm == 'yes':
diff --git a/django/db/backends/oracle/creation.py b/django/db/backends/oracle/creation.py
index 2f096f735ad..d9bf3dfea2c 100644
--- a/django/db/backends/oracle/creation.py
+++ b/django/db/backends/oracle/creation.py
@@ -1,6 +1,7 @@
 import sys
 import time
 from django.db.backends.creation import BaseDatabaseCreation
+from django.utils.six.moves import input
 
 TEST_DATABASE_PREFIX = 'test_'
 PASSWORD = 'Im_a_lumberjack'
@@ -65,7 +66,7 @@ class DatabaseCreation(BaseDatabaseCreation):
             except Exception as e:
                 sys.stderr.write("Got an error creating the test database: %s\n" % e)
                 if not autoclobber:
-                    confirm = raw_input("It appears the test database, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_NAME)
+                    confirm = input("It appears the test database, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_NAME)
                 if autoclobber or confirm == 'yes':
                     try:
                         if verbosity >= 1:
@@ -87,7 +88,7 @@ class DatabaseCreation(BaseDatabaseCreation):
             except Exception as e:
                 sys.stderr.write("Got an error creating the test user: %s\n" % e)
                 if not autoclobber:
-                    confirm = raw_input("It appears the test user, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_USER)
+                    confirm = input("It appears the test user, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_USER)
                 if autoclobber or confirm == 'yes':
                     try:
                         if verbosity >= 1:
diff --git a/django/db/backends/sqlite3/creation.py b/django/db/backends/sqlite3/creation.py
index efdc457be0c..c022b56c858 100644
--- a/django/db/backends/sqlite3/creation.py
+++ b/django/db/backends/sqlite3/creation.py
@@ -1,6 +1,7 @@
 import os
 import sys
 from django.db.backends.creation import BaseDatabaseCreation
+from django.utils.six.moves import input
 
 class DatabaseCreation(BaseDatabaseCreation):
     # SQLite doesn't actually support most of these types, but it "does the right
@@ -53,7 +54,7 @@ class DatabaseCreation(BaseDatabaseCreation):
                 print("Destroying old test database '%s'..." % self.connection.alias)
             if os.access(test_database_name, os.F_OK):
                 if not autoclobber:
-                    confirm = raw_input("Type 'yes' if you would like to try deleting the test database '%s', or 'no' to cancel: " % test_database_name)
+                    confirm = input("Type 'yes' if you would like to try deleting the test database '%s', or 'no' to cancel: " % test_database_name)
                 if autoclobber or confirm == 'yes':
                   try:
                       os.remove(test_database_name)
diff --git a/django/utils/six.py b/django/utils/six.py
index e226bba09e4..ceb5d70e58f 100644
--- a/django/utils/six.py
+++ b/django/utils/six.py
@@ -113,6 +113,7 @@ class _MovedItems(types.ModuleType):
 _moved_attributes = [
     MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
     MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
+    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
     MovedAttribute("map", "itertools", "builtins", "imap", "map"),
     MovedAttribute("reload_module", "__builtin__", "imp", "reload"),
     MovedAttribute("reduce", "__builtin__", "functools"),

From e0988ecd1ea90fc7c75ecd9f0959cef5fd9021ff Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Wed, 8 Aug 2012 23:13:33 +0200
Subject: [PATCH 82/88] [py3] Made Element instances hashable

---
 django/test/html.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/django/test/html.py b/django/test/html.py
index 143c3728be7..acdb4ffd141 100644
--- a/django/test/html.py
+++ b/django/test/html.py
@@ -83,6 +83,8 @@ class Element(object):
             return False
         return True
 
+    __hash__ = object.__hash__
+
     def __ne__(self, element):
         return not self.__eq__(element)
 

From 180b672a652a8ea09484d9657957fa06dbcb83a8 Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Wed, 8 Aug 2012 23:22:27 +0200
Subject: [PATCH 83/88] [py3] Fixed Python 3 compatibility in localflavor forms

---
 django/contrib/localflavor/br/forms.py | 4 ++--
 django/contrib/localflavor/si/forms.py | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/django/contrib/localflavor/br/forms.py b/django/contrib/localflavor/br/forms.py
index 4d0d6815ba9..0f957be37f7 100644
--- a/django/contrib/localflavor/br/forms.py
+++ b/django/contrib/localflavor/br/forms.py
@@ -154,10 +154,10 @@ class BRCNPJField(Field):
             raise ValidationError(self.error_messages['max_digits'])
         orig_dv = value[-2:]
 
-        new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(5, 1, -1) + range(9, 1, -1))])
+        new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(list(range(5, 1, -1)) + list(range(9, 1, -1)))])
         new_1dv = DV_maker(new_1dv % 11)
         value = value[:-2] + str(new_1dv) + value[-1]
-        new_2dv = sum([i * int(value[idx]) for idx, i in enumerate(range(6, 1, -1) + range(9, 1, -1))])
+        new_2dv = sum([i * int(value[idx]) for idx, i in enumerate(list(range(6, 1, -1)) + list(range(9, 1, -1)))])
         new_2dv = DV_maker(new_2dv % 11)
         value = value[:-1] + str(new_2dv)
         if value[-2:] != orig_dv:
diff --git a/django/contrib/localflavor/si/forms.py b/django/contrib/localflavor/si/forms.py
index aa4b9dac5a8..bab35935fd8 100644
--- a/django/contrib/localflavor/si/forms.py
+++ b/django/contrib/localflavor/si/forms.py
@@ -41,7 +41,7 @@ class SIEMSOField(CharField):
         # Validate EMSO
         s = 0
         int_values = [int(i) for i in value]
-        for a, b in zip(int_values, range(7, 1, -1) * 2):
+        for a, b in zip(int_values, list(range(7, 1, -1)) * 2):
             s += a * b
         chk = s % 11
         if chk == 0:

From 96a6912ec5183e2b338bf2e1b655ea10760bfb54 Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Wed, 8 Aug 2012 23:40:20 +0200
Subject: [PATCH 84/88] [py3] Fixed compilemessages tests

---
 django/core/management/commands/compilemessages.py | 4 +++-
 tests/regressiontests/i18n/commands/compilation.py | 8 ++++----
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/django/core/management/commands/compilemessages.py b/django/core/management/commands/compilemessages.py
index fdc3535cf66..b7392b91733 100644
--- a/django/core/management/commands/compilemessages.py
+++ b/django/core/management/commands/compilemessages.py
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 import codecs
 import os
 import sys
@@ -7,7 +9,7 @@ from django.core.management.base import BaseCommand, CommandError
 def has_bom(fn):
     with open(fn, 'rb') as f:
         sample = f.read(4)
-    return sample[:3] == '\xef\xbb\xbf' or \
+    return sample[:3] == b'\xef\xbb\xbf' or \
             sample.startswith(codecs.BOM_UTF16_LE) or \
             sample.startswith(codecs.BOM_UTF16_BE)
 
diff --git a/tests/regressiontests/i18n/commands/compilation.py b/tests/regressiontests/i18n/commands/compilation.py
index d88e1feef63..b6119cf43d4 100644
--- a/tests/regressiontests/i18n/commands/compilation.py
+++ b/tests/regressiontests/i18n/commands/compilation.py
@@ -1,10 +1,10 @@
 import os
-from io import BytesIO
 
 from django.core.management import call_command, CommandError
 from django.test import TestCase
 from django.test.utils import override_settings
 from django.utils import translation
+from django.utils.six import StringIO
 
 test_dir = os.path.abspath(os.path.dirname(__file__))
 
@@ -26,7 +26,7 @@ class PoFileTests(MessageCompilationTests):
         os.chdir(test_dir)
         with self.assertRaisesRegexp(CommandError,
                 "file has a BOM \(Byte Order Mark\)"):
-            call_command('compilemessages', locale=self.LOCALE, stderr=BytesIO())
+            call_command('compilemessages', locale=self.LOCALE, stderr=StringIO())
         self.assertFalse(os.path.exists(self.MO_FILE))
 
 
@@ -42,7 +42,7 @@ class PoFileContentsTests(MessageCompilationTests):
 
     def test_percent_symbol_in_po_file(self):
         os.chdir(test_dir)
-        call_command('compilemessages', locale=self.LOCALE, stderr=BytesIO())
+        call_command('compilemessages', locale=self.LOCALE, stderr=StringIO())
         self.assertTrue(os.path.exists(self.MO_FILE))
 
 
@@ -57,7 +57,7 @@ class PercentRenderingTests(MessageCompilationTests):
     def test_percent_symbol_escaping(self):
         from django.template import Template, Context
         os.chdir(test_dir)
-        call_command('compilemessages', locale=self.LOCALE, stderr=BytesIO())
+        call_command('compilemessages', locale=self.LOCALE, stderr=StringIO())
         with translation.override(self.LOCALE):
             t = Template('{% load i18n %}{% trans "Looks like a str fmt spec %% o but shouldn\'t be interpreted as such" %}')
             rendered = t.render(Context({}))

From 5c09c59bc76510a5388623259b3827ee894cd66b Mon Sep 17 00:00:00 2001
From: Aymeric Augustin <aymeric.augustin@m4x.org>
Date: Thu, 9 Aug 2012 14:36:05 +0200
Subject: [PATCH 85/88] [py3] Renamed `next` to `__next__` in iterators.

See PEP 3114. `next` is retained as an alias for Python 2.
---
 django/core/serializers/base.py           |  4 +++-
 django/core/serializers/xml_serializer.py |  4 +++-
 django/db/backends/oracle/base.py         |  4 +++-
 django/http/__init__.py                   |  4 +++-
 django/http/multipartparser.py            | 16 ++++++++++++----
 5 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/django/core/serializers/base.py b/django/core/serializers/base.py
index 78a01c70983..bdb43db9f36 100644
--- a/django/core/serializers/base.py
+++ b/django/core/serializers/base.py
@@ -136,10 +136,12 @@ class Deserializer(object):
     def __iter__(self):
         return self
 
-    def next(self):
+    def __next__(self):
         """Iteration iterface -- return the next item in the stream"""
         raise NotImplementedError
 
+    next = __next__             # Python 2 compatibility
+
 class DeserializedObject(object):
     """
     A deserialized model.
diff --git a/django/core/serializers/xml_serializer.py b/django/core/serializers/xml_serializer.py
index c4e4dd189ec..666587dc776 100644
--- a/django/core/serializers/xml_serializer.py
+++ b/django/core/serializers/xml_serializer.py
@@ -154,13 +154,15 @@ class Deserializer(base.Deserializer):
         self.event_stream = pulldom.parse(self.stream)
         self.db = options.pop('using', DEFAULT_DB_ALIAS)
 
-    def next(self):
+    def __next__(self):
         for event, node in self.event_stream:
             if event == "START_ELEMENT" and node.nodeName == "object":
                 self.event_stream.expandNode(node)
                 return self._handle_object(node)
         raise StopIteration
 
+    next = __next__             # Python 2 compatibility
+
     def _handle_object(self, node):
         """
         Convert an <object> node to a DeserializedObject.
diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index 0f161304778..89cad12b6ce 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -774,9 +774,11 @@ class CursorIterator(object):
     def __iter__(self):
         return self
 
-    def next(self):
+    def __next__(self):
         return _rowfactory(next(self.iter), self.cursor)
 
+    next = __next__             # Python 2 compatibility
+
 
 def _rowfactory(row, cursor):
     # Cast numeric values as the appropriate Python type based upon the
diff --git a/django/http/__init__.py b/django/http/__init__.py
index cc138917b91..05824ad1d9d 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -669,12 +669,14 @@ class HttpResponse(object):
         self._iterator = iter(self._container)
         return self
 
-    def next(self):
+    def __next__(self):
         chunk = next(self._iterator)
         if isinstance(chunk, six.text_type):
             chunk = chunk.encode(self._charset)
         return str(chunk)
 
+    next = __next__             # Python 2 compatibility
+
     def close(self):
         if hasattr(self._container, 'close'):
             self._container.close()
diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py
index 1987ee53bcb..9c66827cbb8 100644
--- a/django/http/multipartparser.py
+++ b/django/http/multipartparser.py
@@ -305,7 +305,7 @@ class LazyStream(object):
         out = b''.join(parts())
         return out
 
-    def next(self):
+    def __next__(self):
         """
         Used when the exact number of bytes to read is unimportant.
 
@@ -322,6 +322,8 @@ class LazyStream(object):
         self.position += len(output)
         return output
 
+    next = __next__             # Python 2 compatibility
+
     def close(self):
         """
         Used to invalidate/disable this lazy stream.
@@ -376,7 +378,7 @@ class ChunkIter(object):
         self.flo = flo
         self.chunk_size = chunk_size
 
-    def next(self):
+    def __next__(self):
         try:
             data = self.flo.read(self.chunk_size)
         except InputStreamExhausted:
@@ -386,6 +388,8 @@ class ChunkIter(object):
         else:
             raise StopIteration()
 
+    next = __next__             # Python 2 compatibility
+
     def __iter__(self):
         return self
 
@@ -400,12 +404,14 @@ class InterBoundaryIter(object):
     def __iter__(self):
         return self
 
-    def next(self):
+    def __next__(self):
         try:
             return LazyStream(BoundaryIter(self._stream, self._boundary))
         except InputStreamExhausted:
             raise StopIteration()
 
+    next = __next__             # Python 2 compatibility
+
 class BoundaryIter(object):
     """
     A Producer that is sensitive to boundaries.
@@ -441,7 +447,7 @@ class BoundaryIter(object):
     def __iter__(self):
         return self
 
-    def next(self):
+    def __next__(self):
         if self._done:
             raise StopIteration()
 
@@ -482,6 +488,8 @@ class BoundaryIter(object):
                 stream.unget(chunk[-rollback:])
                 return chunk[:-rollback]
 
+    next = __next__             # Python 2 compatibility
+
     def _find_boundary(self, data, eof = False):
         """
         Finds a multipart boundary in data.

From 5f8da527abf6ce1d995d4f6454a07f7e442f7fd5 Mon Sep 17 00:00:00 2001
From: Alex Gaynor <alex.gaynor@gmail.com>
Date: Thu, 9 Aug 2012 07:25:35 -0700
Subject: [PATCH 86/88] [py3k] use the base64 module, instead of
 bytes.encode('base64')

---
 django/contrib/auth/hashers.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py
index c676cf84db1..45c1f88ab2c 100644
--- a/django/contrib/auth/hashers.py
+++ b/django/contrib/auth/hashers.py
@@ -1,5 +1,6 @@
 from __future__ import unicode_literals
 
+import base64
 import hashlib
 
 from django.dispatch import receiver
@@ -218,7 +219,7 @@ class PBKDF2PasswordHasher(BasePasswordHasher):
         if not iterations:
             iterations = self.iterations
         hash = pbkdf2(password, salt, iterations, digest=self.digest)
-        hash = hash.encode('base64').strip()
+        hash = base64.b64encode(hash).strip()
         return "%s$%d$%s$%s" % (self.algorithm, iterations, salt, hash)
 
     def verify(self, password, encoded):

From 751774c29f6ad8f6ad08bc48a4d085829dd279e0 Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Thu, 9 Aug 2012 12:12:22 +0200
Subject: [PATCH 87/88] [py3] Fixed mail tests with Python 3

---
 django/core/mail/message.py         | 34 +++++++++---------
 tests/regressiontests/mail/tests.py | 54 ++++++++++++++++-------------
 2 files changed, 46 insertions(+), 42 deletions(-)

diff --git a/django/core/mail/message.py b/django/core/mail/message.py
index 8f589ae33da..b332ffba04f 100644
--- a/django/core/mail/message.py
+++ b/django/core/mail/message.py
@@ -11,11 +11,10 @@ from email.mime.multipart import MIMEMultipart
 from email.mime.base import MIMEBase
 from email.header import Header
 from email.utils import formatdate, getaddresses, formataddr, parseaddr
-from io import BytesIO
 
 from django.conf import settings
 from django.core.mail.utils import DNS_NAME
-from django.utils.encoding import smart_bytes, force_text
+from django.utils.encoding import force_text
 from django.utils import six
 
 
@@ -83,34 +82,34 @@ def forbid_multi_line_headers(name, val, encoding):
     if '\n' in val or '\r' in val:
         raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name))
     try:
-        val = val.encode('ascii')
+        val.encode('ascii')
     except UnicodeEncodeError:
         if name.lower() in ADDRESS_HEADERS:
             val = ', '.join(sanitize_address(addr, encoding)
                 for addr in getaddresses((val,)))
         else:
-            val = str(Header(val, encoding))
+            val = Header(val, encoding).encode()
     else:
         if name.lower() == 'subject':
-            val = Header(val)
-    return smart_bytes(name), val
+            val = Header(val).encode()
+    return str(name), val
 
 
 def sanitize_address(addr, encoding):
     if isinstance(addr, six.string_types):
         addr = parseaddr(force_text(addr))
     nm, addr = addr
-    nm = str(Header(nm, encoding))
+    nm = Header(nm, encoding).encode()
     try:
-        addr = addr.encode('ascii')
+        addr.encode('ascii')
     except UnicodeEncodeError:  # IDN
         if '@' in addr:
             localpart, domain = addr.split('@', 1)
             localpart = str(Header(localpart, encoding))
-            domain = domain.encode('idna')
+            domain = domain.encode('idna').decode('ascii')
             addr = '@'.join([localpart, domain])
         else:
-            addr = str(Header(addr, encoding))
+            addr = Header(addr, encoding).encode()
     return formataddr((nm, addr))
 
 
@@ -132,7 +131,7 @@ class SafeMIMEText(MIMEText):
         This overrides the default as_string() implementation to not mangle
         lines that begin with 'From '. See bug #13433 for details.
         """
-        fp = BytesIO()
+        fp = six.StringIO()
         g = Generator(fp, mangle_from_ = False)
         g.flatten(self, unixfrom=unixfrom)
         return fp.getvalue()
@@ -156,7 +155,7 @@ class SafeMIMEMultipart(MIMEMultipart):
         This overrides the default as_string() implementation to not mangle
         lines that begin with 'From '. See bug #13433 for details.
         """
-        fp = BytesIO()
+        fp = six.StringIO()
         g = Generator(fp, mangle_from_ = False)
         g.flatten(self, unixfrom=unixfrom)
         return fp.getvalue()
@@ -210,8 +209,7 @@ class EmailMessage(object):
 
     def message(self):
         encoding = self.encoding or settings.DEFAULT_CHARSET
-        msg = SafeMIMEText(smart_bytes(self.body, encoding),
-                           self.content_subtype, encoding)
+        msg = SafeMIMEText(self.body, self.content_subtype, encoding)
         msg = self._create_message(msg)
         msg['Subject'] = self.subject
         msg['From'] = self.extra_headers.get('From', self.from_email)
@@ -293,7 +291,7 @@ class EmailMessage(object):
         basetype, subtype = mimetype.split('/', 1)
         if basetype == 'text':
             encoding = self.encoding or settings.DEFAULT_CHARSET
-            attachment = SafeMIMEText(smart_bytes(content, encoding), subtype, encoding)
+            attachment = SafeMIMEText(content, subtype, encoding)
         else:
             # Encode non-text attachments with base64.
             attachment = MIMEBase(basetype, subtype)
@@ -313,9 +311,11 @@ class EmailMessage(object):
         attachment = self._create_mime_attachment(content, mimetype)
         if filename:
             try:
-                filename = filename.encode('ascii')
+                filename.encode('ascii')
             except UnicodeEncodeError:
-                filename = ('utf-8', '', filename.encode('utf-8'))
+                if not six.PY3:
+                    filename = filename.encode('utf-8')
+                filename = ('utf-8', '', filename)
             attachment.add_header('Content-Disposition', 'attachment',
                                   filename=filename)
         return attachment
diff --git a/tests/regressiontests/mail/tests.py b/tests/regressiontests/mail/tests.py
index 0d0af19427e..c948662bc34 100644
--- a/tests/regressiontests/mail/tests.py
+++ b/tests/regressiontests/mail/tests.py
@@ -17,7 +17,7 @@ from django.core.mail.backends import console, dummy, locmem, filebased, smtp
 from django.core.mail.message import BadHeaderError
 from django.test import TestCase
 from django.test.utils import override_settings
-from django.utils.six import StringIO
+from django.utils.six import PY3, StringIO
 from django.utils.translation import ugettext_lazy
 
 
@@ -29,7 +29,7 @@ class MailTests(TestCase):
     def test_ascii(self):
         email = EmailMessage('Subject', 'Content', 'from@example.com', ['to@example.com'])
         message = email.message()
-        self.assertEqual(message['Subject'].encode(), 'Subject')
+        self.assertEqual(message['Subject'], 'Subject')
         self.assertEqual(message.get_payload(), 'Content')
         self.assertEqual(message['From'], 'from@example.com')
         self.assertEqual(message['To'], 'to@example.com')
@@ -37,7 +37,7 @@ class MailTests(TestCase):
     def test_multiple_recipients(self):
         email = EmailMessage('Subject', 'Content', 'from@example.com', ['to@example.com', 'other@example.com'])
         message = email.message()
-        self.assertEqual(message['Subject'].encode(), 'Subject')
+        self.assertEqual(message['Subject'], 'Subject')
         self.assertEqual(message.get_payload(), 'Content')
         self.assertEqual(message['From'], 'from@example.com')
         self.assertEqual(message['To'], 'to@example.com, other@example.com')
@@ -77,9 +77,10 @@ class MailTests(TestCase):
         """
         Test for space continuation character in long (ascii) subject headers (#7747)
         """
-        email = EmailMessage('Long subject lines that get wrapped should use a space continuation character to get expected behavior in Outlook and Thunderbird', 'Content', 'from@example.com', ['to@example.com'])
+        email = EmailMessage('Long subject lines that get wrapped should contain a space continuation character to get expected behavior in Outlook and Thunderbird', 'Content', 'from@example.com', ['to@example.com'])
         message = email.message()
-        self.assertEqual(message['Subject'], 'Long subject lines that get wrapped should use a space continuation\n character to get expected behavior in Outlook and Thunderbird')
+        # Note that in Python 3, maximum line length has increased from 76 to 78
+        self.assertEqual(message['Subject'].encode(), b'Long subject lines that get wrapped should contain a space continuation\n character to get expected behavior in Outlook and Thunderbird')
 
     def test_message_header_overrides(self):
         """
@@ -88,7 +89,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(), 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')
+        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')
 
     def test_from_header(self):
         """
@@ -160,7 +161,7 @@ class MailTests(TestCase):
         msg.attach_alternative(html_content, "text/html")
         msg.encoding = 'iso-8859-1'
         self.assertEqual(msg.message()['To'], '=?iso-8859-1?q?S=FCrname=2C_Firstname?= <to@example.com>')
-        self.assertEqual(msg.message()['Subject'].encode(), '=?iso-8859-1?q?Message_from_Firstname_S=FCrname?=')
+        self.assertEqual(msg.message()['Subject'], '=?iso-8859-1?q?Message_from_Firstname_S=FCrname?=')
 
     def test_encoding(self):
         """
@@ -170,7 +171,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(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.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.assertEqual(message.get_payload(), 'Firstname S=FCrname is a great guy.')
 
         # Make sure MIME attachments also works correctly with other encodings than utf-8
@@ -179,8 +180,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(), 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>')
+        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>')
 
     def test_attachments(self):
         """Regression test for #9367"""
@@ -291,31 +292,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(b'>From the future' in email.message().as_string())
+        self.assertFalse('>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(b'Content-Transfer-Encoding: base64' in msg.message().as_string())
+        self.assertFalse('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(b'Content-Transfer-Encoding: quoted-printable' in s)
-        self.assertTrue(b'Content-Transfer-Encoding: 7bit' in s)
+        self.assertFalse('Content-Transfer-Encoding: quoted-printable' in s)
+        self.assertTrue('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(b'Content-Transfer-Encoding: quoted-printable' in s)
-        self.assertTrue(b'Content-Transfer-Encoding: 8bit' in s)
+        self.assertFalse(str('Content-Transfer-Encoding: quoted-printable') in s)
+        self.assertTrue(str('Content-Transfer-Encoding: 8bit') in s)
 
         msg = EmailMessage('Subject', 'Body with non latin characters: А Б В Г Д Е Ж Ѕ З И І К Л М Н О П.', 'bounce@example.com', ['to@example.com'], headers={'From': 'from@example.com'})
         s = msg.message().as_string()
-        self.assertFalse(b'Content-Transfer-Encoding: quoted-printable' in s)
-        self.assertTrue(b'Content-Transfer-Encoding: 8bit' in s)
+        self.assertFalse(str('Content-Transfer-Encoding: quoted-printable') in s)
+        self.assertTrue(str('Content-Transfer-Encoding: 8bit') in s)
 
 
 class BaseEmailBackendTests(object):
@@ -440,7 +441,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(), 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: ')
+        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: ')
 
     def test_idn_send(self):
         """
@@ -519,9 +520,9 @@ 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), '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)
+            with open(os.path.join(self.tmp_dir, filename), 'r') as fp:
+                session = fp.read().split('\n' + ('-' * 79) + '\n')
+            messages.extend(email.message_from_string(str(m)) for m in session if m)
         return messages
 
     def test_file_sessions(self):
@@ -571,8 +572,8 @@ class ConsoleBackendTests(BaseEmailBackendTests, TestCase):
         self.stream = sys.stdout = StringIO()
 
     def get_mailbox_content(self):
-        messages = self.stream.getvalue().split(b'\n' + (b'-' * 79) + b'\n')
-        return [email.message_from_string(m) for m in messages if m]
+        messages = self.stream.getvalue().split('\n' + ('-' * 79) + '\n')
+        return [email.message_from_string(str(m)) for m in messages if m]
 
     def test_console_stream_kwarg(self):
         """
@@ -600,7 +601,10 @@ class FakeSMTPServer(smtpd.SMTPServer, threading.Thread):
 
     def process_message(self, peer, mailfrom, rcpttos, data):
         m = email.message_from_string(data)
-        maddr = email.Utils.parseaddr(m.get('from'))[1]
+        if PY3:
+            maddr = email.utils.parseaddr(m.get('from'))[1]
+        else:
+            maddr = email.Utils.parseaddr(m.get('from'))[1]
         if mailfrom != maddr:
             return "553 '%s' != '%s'" % (mailfrom, maddr)
         with self.sink_lock:

From 7275576235ae2e87f3de7b0facb3f9b0a2368f28 Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Thu, 9 Aug 2012 16:22:22 -0400
Subject: [PATCH 88/88] Clarified thread safety note in class based views;
 thanks rafadura for the patch.

---
 docs/ref/class-based-views/index.txt | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/docs/ref/class-based-views/index.txt b/docs/ref/class-based-views/index.txt
index c10e66b3969..f2271d2506d 100644
--- a/docs/ref/class-based-views/index.txt
+++ b/docs/ref/class-based-views/index.txt
@@ -32,9 +32,9 @@ A class-based view is deployed into a URL pattern using the
 
     Arguments passed to a view are shared between every instance of a view.
     This means that you shoudn't use a list, dictionary, or any other
-    variable object as an argument to a view. If you did, the actions of
-    one user visiting your view could have an effect on subsequent users
-    visiting the same view.
+    mutable object as an argument to a view. If you do and the shared object
+    is modified, the actions of one user visiting your view could have an
+    effect on subsequent users visiting the same view.
 
 Any argument passed into :meth:`~View.as_view()` will be assigned onto the
 instance that is used to service a request. Using the previous example,