Browse Source

Refs #23919 -- Removed Python 2 notes in docs.

Tim Graham 8 years ago
parent
commit
f6acd1d271
61 changed files with 140 additions and 732 deletions
  1. 0 1
      docs/conf.py
  2. 3 10
      docs/faq/install.txt
  3. 0 9
      docs/faq/troubleshooting.txt
  4. 0 4
      docs/howto/custom-management-commands.txt
  5. 4 6
      docs/howto/custom-model-fields.txt
  6. 0 16
      docs/howto/deployment/checklist.txt
  7. 0 21
      docs/howto/outputting-csv.txt
  8. 0 1
      docs/index.txt
  9. 2 2
      docs/internals/contributing/writing-code/javascript.txt
  10. 5 11
      docs/internals/contributing/writing-code/unit-tests.txt
  11. 3 3
      docs/intro/contributing.txt
  12. 2 2
      docs/intro/overview.txt
  13. 1 3
      docs/intro/reusable-apps.txt
  14. 5 6
      docs/ref/applications.txt
  15. 3 3
      docs/ref/checks.txt
  16. 1 1
      docs/ref/contrib/admin/actions.txt
  17. 6 10
      docs/ref/contrib/admin/index.txt
  18. 4 7
      docs/ref/contrib/auth.txt
  19. 1 1
      docs/ref/contrib/contenttypes.txt
  20. 2 2
      docs/ref/contrib/gis/commands.txt
  21. 1 1
      docs/ref/contrib/gis/layermapping.txt
  22. 1 1
      docs/ref/contrib/gis/tutorial.txt
  23. 4 4
      docs/ref/contrib/postgres/fields.txt
  24. 6 49
      docs/ref/databases.txt
  25. 1 5
      docs/ref/exceptions.txt
  26. 1 2
      docs/ref/files/file.txt
  27. 3 5
      docs/ref/forms/api.txt
  28. 5 6
      docs/ref/forms/fields.txt
  29. 1 1
      docs/ref/models/querysets.txt
  30. 0 21
      docs/ref/request-response.txt
  31. 3 3
      docs/ref/templates/language.txt
  32. 3 32
      docs/ref/unicode.txt
  33. 1 1
      docs/ref/urlresolvers.txt
  34. 29 40
      docs/ref/utils.txt
  35. 1 1
      docs/releases/1.4.11.txt
  36. 1 1
      docs/releases/1.4.17.txt
  37. 1 1
      docs/releases/1.4.18.txt
  38. 1 1
      docs/releases/1.5.6.txt
  39. 3 3
      docs/releases/1.5.txt
  40. 1 1
      docs/releases/1.6.2.txt
  41. 1 1
      docs/releases/1.6.3.txt
  42. 1 1
      docs/releases/1.6.9.txt
  43. 1 1
      docs/releases/1.7.2.txt
  44. 1 1
      docs/releases/1.8.7.txt
  45. 1 1
      docs/topics/auth/customizing.txt
  46. 1 2
      docs/topics/cache.txt
  47. 2 2
      docs/topics/class-based-views/generic-display.txt
  48. 2 2
      docs/topics/db/examples/many_to_many.txt
  49. 2 9
      docs/topics/db/examples/many_to_one.txt
  50. 3 3
      docs/topics/db/examples/one_to_one.txt
  51. 3 6
      docs/topics/db/models.txt
  52. 3 3
      docs/topics/db/queries.txt
  53. 1 1
      docs/topics/forms/modelforms.txt
  54. 1 5
      docs/topics/i18n/translation.txt
  55. 0 1
      docs/topics/index.txt
  56. 2 2
      docs/topics/install.txt
  57. 1 19
      docs/topics/migrations.txt
  58. 1 1
      docs/topics/pagination.txt
  59. 0 369
      docs/topics/python3.txt
  60. 3 3
      docs/topics/testing/overview.txt
  61. 1 1
      docs/topics/testing/tools.txt

+ 0 - 1
docs/conf.py

@@ -134,7 +134,6 @@ pygments_style = 'trac'
 intersphinx_mapping = {
     'python': ('https://docs.python.org/3/', None),
     'sphinx': ('http://sphinx-doc.org/', None),
-    'six': ('https://pythonhosted.org/six/', None),
     'psycopg2': ('http://initd.org/psycopg/docs/', None),
 }
 

+ 3 - 10
docs/faq/install.txt

@@ -65,18 +65,11 @@ is the last version to support Python 3.3.
 What Python version should I use with Django?
 =============================================
 
-As of Django 1.6, Python 3 support is considered stable and you can safely use
-it in production. See also :doc:`/topics/python3`. However, the community is
-still in the process of migrating third-party packages and applications to
-Python 3.
-
-If you're starting a new project, and the dependencies you plan to use work on
-Python 3, you should use Python 3. If they don't, consider contributing to the
-porting efforts, or stick to Python 2.
+Python 3 is recommended. Django 1.11 is the last version to support Python 2.7.
+Support for Python 2.7 and Django 1.11 ends in 2020.
 
 Since newer versions of Python are often faster, have more features, and are
-better supported, all else being equal, we recommend that you use the latest
-2.x.y or 3.x.y release.
+better supported, the latest version of Python 3 is recommended.
 
 You don't lose anything in Django by using an older release, but you don't take
 advantage of the improvements and optimizations in newer Python releases.

+ 0 - 9
docs/faq/troubleshooting.txt

@@ -55,15 +55,6 @@ pitfalls producing this error:
   case, please refer to your system documentation to learn how you can change
   this to a UTF-8 locale.
 
-* You created raw bytestrings, which is easy to do on Python 2::
-
-      my_string = 'café'
-
-  Either use the ``u''`` prefix or even better, add the
-  ``from __future__ import unicode_literals`` line at the top of your file
-  so that your code will be compatible with Python 3.2 which doesn't support
-  the ``u''`` prefix.
-
 Related resources:
 
 * :doc:`Unicode in Django </ref/unicode>`

+ 0 - 4
docs/howto/custom-management-commands.txt

@@ -26,10 +26,6 @@ directory whose name doesn't begin with an underscore. For example::
         tests.py
         views.py
 
-On Python 2, be sure to include ``__init__.py`` files in both the
-``management`` and ``management/commands`` directories as done above or your
-command will not be detected.
-
 In this example, the ``closepoll`` command will be made available to any project
 that includes the ``polls`` application in :setting:`INSTALLED_APPS`.
 

+ 4 - 6
docs/howto/custom-model-fields.txt

@@ -704,14 +704,12 @@ smoothly:
    a field that's similar to what you want and extend it a little bit,
    instead of creating an entirely new field from scratch.
 
-2. Put a ``__str__()`` (``__unicode__()`` on Python 2) 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
+2. Put a ``__str__()`` 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_text` on the value. (In our
    examples in this document, ``value`` would be a ``Hand`` instance, not a
-   ``HandField``). So if your ``__str__()`` method (``__unicode__()`` on
-   Python 2) automatically converts to the string form of your Python object,
-   you can save yourself a lot of work.
+   ``HandField``). So if your ``__str__()`` method automatically converts to
+   the string form of your Python object, you can save yourself a lot of work.
 
 Writing a ``FileField`` subclass
 ================================

+ 0 - 16
docs/howto/deployment/checklist.txt

@@ -250,19 +250,3 @@ details about the default templates:
 * :ref:`http_internal_server_error_view`
 * :ref:`http_forbidden_view`
 * :ref:`http_bad_request_view`
-
-Python Options
-==============
-
-It's strongly recommended that you invoke the Python process running your
-Django application using the `-R`_ option or with the :envvar:`PYTHONHASHSEED`
-environment variable set to ``random``. This option is enabled by default
-starting with Python 3.3.
-
-These options help protect your site from denial-of-service (DoS)
-attacks triggered by carefully crafted inputs. Such an attack can
-drastically increase CPU usage by causing worst-case performance when
-creating ``dict`` instances. See `oCERT advisory #2011-003
-<http://www.ocert.org/advisories/ocert-2011-003.html>`_ for more information.
-
-.. _-r: https://docs.python.org/2/using/cmdline.html#cmdoption-R

+ 0 - 21
docs/howto/outputting-csv.txt

@@ -53,26 +53,6 @@ mention:
   about escaping strings with quotes or commas in them. Just pass
   ``writerow()`` your raw strings, and it'll do the right thing.
 
-.. admonition:: Handling Unicode on Python 2
-
-    Python 2's :mod:`csv` module does not support Unicode input. Since Django
-    uses Unicode internally this means strings read from sources such as
-    :class:`~django.http.HttpRequest` are potentially problematic. There are a
-    few options for handling this:
-
-    * Manually encode all Unicode objects to a compatible encoding.
-
-    * Use the ``UnicodeWriter`` class provided in the `csv module's examples
-      section`_.
-
-    * Use the `python-unicodecsv module`_, which aims to be a drop-in
-      replacement for :mod:`csv` that gracefully handles Unicode.
-
-    For more information, see the Python documentation of the :mod:`csv` module.
-
-    .. _`csv module's examples section`: https://docs.python.org/2/library/csv.html#examples
-    .. _`python-unicodecsv module`: https://github.com/jdunck/python-unicodecsv
-
 .. _streaming-csv-files:
 
 Streaming large CSV files
@@ -89,7 +69,6 @@ the assembly and transmission of a large CSV file::
 
     import csv
 
-    from django.utils.six.moves import range
     from django.http import StreamingHttpResponse
 
     class Echo(object):

+ 0 - 1
docs/index.txt

@@ -282,7 +282,6 @@ Django aims to be compatible with multiple different flavors and versions of
 Python:
 
 * :doc:`Jython support <howto/jython>`
-* :doc:`Python 3 compatibility <topics/python3>`
 
 Geographic framework
 ====================

+ 2 - 2
docs/internals/contributing/writing-code/javascript.txt

@@ -122,8 +122,8 @@ browser.
 To measure code coverage when running the tests, you need to view that file
 over HTTP. To view code coverage:
 
-* Execute ``python -m http.server`` (or ``python -m SimpleHTTPServer`` on
-  Python 2) from the root directory (not from inside ``js_tests``).
+* Execute ``python -m http.server`` from the root directory (not from inside
+  ``js_tests``).
 * Open http://localhost:8000/js_tests/tests.html in your web browser.
 
 Testing from the command line

+ 5 - 11
docs/internals/contributing/writing-code/unit-tests.txt

@@ -31,7 +31,7 @@ Next, clone your fork, install some requirements, and run the tests::
    $ git clone git@github.com:YourGitHubName/django.git django-repo
    $ cd django-repo/tests
    $ pip install -e ..
-   $ pip install -r requirements/py3.txt  # Python 2: py2.txt
+   $ pip install -r requirements/py3.txt
    $ ./runtests.py
 
 Installing the requirements will likely require some operating system packages
@@ -39,8 +39,7 @@ that your computer doesn't have installed. You can usually figure out which
 package to install by doing a Web search for the last line or so of the error
 message. Try adding your operating system to the search query if needed.
 
-If you have trouble installing the requirements, you can skip that step, except
-on Python 2, where you must ``pip install mock``. See
+If you have trouble installing the requirements, you can skip that step. See
 :ref:`running-unit-tests-dependencies` for details on installing the optional
 test dependencies. If you don't have an optional dependency installed, the
 tests that require it will be skipped.
@@ -75,9 +74,8 @@ command from any place in the Django source tree::
 By default, ``tox`` runs the test suite with the bundled test settings file for
 SQLite, ``flake8``, ``isort``, and the documentation spelling checker. In
 addition to the system dependencies noted elsewhere in this documentation,
-the commands ``python2`` and ``python3`` must be on your path and linked to
-the appropriate versions of Python. A list of default environments can be seen
-as follows::
+the command ``python3`` must be on your path and linked to the appropriate
+version of Python. A list of default environments can be seen as follows::
 
     $ tox -l
     py3
@@ -225,7 +223,6 @@ dependencies:
 *  argon2-cffi_ 16.1.0+
 *  bcrypt_
 *  docutils_
-*  enum34_ (Python 2 only)
 *  geoip2_
 *  jinja2_ 2.7+
 *  numpy_
@@ -234,7 +231,6 @@ dependencies:
 *  pytz_ (required)
 *  setuptools_
 *  memcached_, plus a :ref:`supported Python binding <memcached>`
-*  mock_ (for Python 2)
 *  gettext_ (:ref:`gettext_on_windows`)
 *  selenium_
 *  sqlparse_
@@ -243,7 +239,7 @@ You can find these dependencies in `pip requirements files`_ inside the
 ``tests/requirements`` directory of the Django source tree and install them
 like so::
 
-   $ pip install -r tests/requirements/py3.txt  # Python 2: py2.txt
+   $ pip install -r tests/requirements/py3.txt
 
 If you encounter an error during the installation, your system might be missing
 a dependency for one or more of the Python packages. Consult the failing
@@ -265,7 +261,6 @@ associated tests will be skipped.
 .. _argon2-cffi: https://pypi.python.org/pypi/argon2_cffi
 .. _bcrypt: https://pypi.python.org/pypi/bcrypt
 .. _docutils: https://pypi.python.org/pypi/docutils
-.. _enum34: https://pypi.python.org/pypi/enum34
 .. _geoip2: https://pypi.python.org/pypi/geoip2
 .. _jinja2: https://pypi.python.org/pypi/jinja2
 .. _numpy: https://pypi.python.org/pypi/numpy
@@ -274,7 +269,6 @@ associated tests will be skipped.
 .. _pytz: https://pypi.python.org/pypi/pytz/
 .. _setuptools: https://pypi.python.org/pypi/setuptools/
 .. _memcached: http://memcached.org/
-.. _mock: https://pypi.python.org/pypi/mock
 .. _gettext: https://www.gnu.org/software/gettext/manual/gettext.html
 .. _selenium: https://pypi.python.org/pypi/selenium
 .. _sqlparse: https://pypi.python.org/pypi/sqlparse

+ 3 - 3
docs/intro/contributing.txt

@@ -70,9 +70,9 @@ probably got the answers.
 
 .. admonition:: Python 3 required!
 
-    This tutorial assumes you are using Python 3. Get the latest version at
-    `Python's download page <https://www.python.org/download/>`_ or with your
-    operating system's package manager.
+    The current development version of Django doesn't support Python 2.7. Get
+    Python 3 at `Python's download page <https://www.python.org/download/>`_ or
+    with your operating system's package manager.
 
 .. admonition:: For Windows users
 

+ 2 - 2
docs/intro/overview.txt

@@ -33,7 +33,7 @@ database-schema problems. Here's a quick example:
     class Reporter(models.Model):
         full_name = models.CharField(max_length=70)
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.full_name
 
     class Article(models.Model):
@@ -42,7 +42,7 @@ database-schema problems. Here's a quick example:
         content = models.TextField()
         reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.headline
 
 Install it

+ 1 - 3
docs/intro/reusable-apps.txt

@@ -220,10 +220,8 @@ this. For a small app like polls, this process isn't too difficult.
                'License :: OSI Approved :: BSD License',  # example license
                'Operating System :: OS Independent',
                'Programming Language :: Python',
-               # Replace these appropriately if you are stuck on Python 2.
-               'Programming Language :: Python :: 3',
-               'Programming Language :: Python :: 3.4',
                'Programming Language :: Python :: 3.5',
+               'Programming Language :: Python :: 3.6',
                'Topic :: Internet :: WWW/HTTP',
                'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
            ],

+ 5 - 6
docs/ref/applications.txt

@@ -295,13 +295,12 @@ Methods
 
 .. _namespace package:
 
-Namespace packages as apps (Python 3.3+)
-----------------------------------------
+Namespace packages as apps
+--------------------------
 
-Python versions 3.3 and later support Python packages without an
-``__init__.py`` file. These packages are known as "namespace packages" and may
-be spread across multiple directories at different locations on ``sys.path``
-(see :pep:`420`).
+Python packages without an ``__init__.py`` file are known as "namespace
+packages" and may be spread across multiple directories at different locations
+on ``sys.path`` (see :pep:`420`).
 
 Django applications require a single base filesystem path where Django
 (depending on configuration) will search for templates, static assets,

+ 3 - 3
docs/ref/checks.txt

@@ -45,9 +45,9 @@ Constructor arguments are:
 ``obj``
     Optional. An object providing context for the message (for example, the
     model where the problem was discovered). The object should be a model,
-    field, or manager or any other object that defines ``__str__`` method (on
-    Python 2 you need to define ``__unicode__`` method). The method is used
-    while reporting all messages and its result precedes the message.
+    field, or manager or any other object that defines a ``__str__()`` method.
+    The method is used while reporting all messages and its result precedes the
+    message.
 
 ``id``
     Optional string. A unique identifier for the issue. Identifiers should

+ 1 - 1
docs/ref/contrib/admin/actions.txt

@@ -57,7 +57,7 @@ simple news application with an ``Article`` model::
         body = models.TextField()
         status = models.CharField(max_length=1, choices=STATUS_CHOICES)
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.title
 
 A common task we might perform with a model like this is to update an

+ 6 - 10
docs/ref/contrib/admin/index.txt

@@ -137,10 +137,8 @@ The ``register`` decorator
 
     You can't use this decorator if you have to reference your model admin
     class in its ``__init__()`` method, e.g.
-    ``super(PersonAdmin, self).__init__(*args, **kwargs)``. If you are using
-    Python 3 and don't have to worry about supporting Python 2, you can
-    use ``super().__init__(*args, **kwargs)`` . Otherwise, you'll have to use
-    ``admin.site.register()`` instead of this decorator.
+    ``super(PersonAdmin, self).__init__(*args, **kwargs)``. You can use
+    ``super().__init__(*args, **kwargs)``.
 
 Discovery of admin files
 ------------------------
@@ -543,8 +541,7 @@ subclass::
         list_display = ('first_name', 'last_name')
 
     If you don't set ``list_display``, the admin site will display a single
-    column that displays the ``__str__()`` (``__unicode__()`` on Python 2)
-    representation of each object.
+    column that displays the ``__str__()`` representation of each object.
 
     You have four possible values that can be used in ``list_display``:
 
@@ -594,7 +591,7 @@ subclass::
     A few special cases to note about ``list_display``:
 
     * If the field is a ``ForeignKey``, Django will display the
-      ``__str__()`` (``__unicode__()`` on Python 2) of the related object.
+      ``__str__()`` of the related object.
 
     * ``ManyToManyField`` fields aren't supported, because that would
       entail executing a separate SQL statement for each row in the table.
@@ -681,9 +678,8 @@ subclass::
           class PersonAdmin(admin.ModelAdmin):
               list_display = ('name', 'born_in_fifties')
 
-    * The ``__str__()`` (``__unicode__()`` on Python 2) method is just
-      as valid in ``list_display`` as any other model method, so it's
-      perfectly OK to do this::
+    * The ``__str__()`` method is just as valid in ``list_display`` as any
+      other model method, so it's perfectly OK to do this::
 
           list_display = ('__str__', 'some_other_field')
 

+ 4 - 7
docs/ref/contrib/auth.txt

@@ -137,12 +137,11 @@ Attributes
     .. attribute:: username_validator
 
         Points to a validator instance used to validate usernames. Defaults to
-        :class:`validators.UnicodeUsernameValidator` on Python 3 and
-        :class:`validators.ASCIIUsernameValidator` on Python 2.
+        :class:`validators.UnicodeUsernameValidator`.
 
         To change the default username validator, you can subclass the ``User``
         model and set this attribute to a different validator instance. For
-        example, to use ASCII usernames on Python 3::
+        example, to use ASCII usernames::
 
             from django.contrib.auth.models import User
             from django.contrib.auth.validators import ASCIIUsernameValidator
@@ -390,14 +389,12 @@ Validators
 .. class:: validators.ASCIIUsernameValidator
 
     A field validator allowing only ASCII letters, in addition to ``@``, ``.``,
-    ``+``, ``-``, and ``_``. The default validator for ``User.username`` on
-    Python 2.
+    ``+``, ``-``, and ``_``.
 
 .. class:: validators.UnicodeUsernameValidator
 
     A field validator allowing Unicode letters, in addition to ``@``, ``.``,
-    ``+``, ``-``, and ``_``. The default validator for ``User.username`` on
-    Python 3.
+    ``+``, ``-``, and ``_``. The default validator for ``User.username``.
 
 .. _topics-auth-signals:
 

+ 1 - 1
docs/ref/contrib/contenttypes.txt

@@ -251,7 +251,7 @@ A simple example is a tagging system, which might look like this::
         object_id = models.PositiveIntegerField()
         content_object = GenericForeignKey('content_type', 'object_id')
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.tag
 
 A normal :class:`~django.db.models.ForeignKey` can only "point

+ 2 - 2
docs/ref/contrib/gis/commands.txt

@@ -63,8 +63,8 @@ of using ``ogrinspect`` :ref:`in the tutorial <ogrinspect-intro>`.
 
 .. django-admin-option:: --name-field NAME_FIELD
 
-    Generates a ``__str__`` routine (``__unicode__`` on Python 2) on the model
-    that will return the given field name.
+    Generates a ``__str__()`` method on the model that returns the given field
+    name.
 
 .. django-admin-option:: --no-imports
 

+ 1 - 1
docs/ref/contrib/gis/layermapping.txt

@@ -58,7 +58,7 @@ Example
         name = models.CharField(max_length=25) # corresponds to the 'str' field
         poly = models.PolygonField(srid=4269) # we want our model in a different SRID
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return 'Name: %s' % self.name
 
 3. Use :class:`LayerMapping` to extract all the features and place them in the

+ 1 - 1
docs/ref/contrib/gis/tutorial.txt

@@ -216,7 +216,7 @@ model to represent this data::
         mpoly = models.MultiPolygonField()
 
         # Returns the string representation of the model.
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.name
 
 Note that the ``models`` module is imported from ``django.contrib.gis.db``.

+ 4 - 4
docs/ref/contrib/postgres/fields.txt

@@ -104,7 +104,7 @@ We will use the following example model::
         name = models.CharField(max_length=200)
         tags = ArrayField(models.CharField(max_length=200), blank=True)
 
-        def __str__(self):  # __unicode__ on Python 2
+        def __str__(self):
             return self.name
 
 .. fieldlookup:: arrayfield.contains
@@ -313,7 +313,7 @@ We will use the following example model::
         name = models.CharField(max_length=200)
         data = HStoreField()
 
-        def __str__(self):  # __unicode__ on Python 2
+        def __str__(self):
             return self.name
 
 .. fieldlookup:: hstorefield.key
@@ -521,7 +521,7 @@ We will use the following example model::
         name = models.CharField(max_length=200)
         data = JSONField()
 
-        def __str__(self):  # __unicode__ on Python 2
+        def __str__(self):
             return self.name
 
 .. fieldlookup:: jsonfield.key
@@ -680,7 +680,7 @@ model::
         ages = IntegerRangeField()
         start = models.DateTimeField()
 
-        def __str__(self):  # __unicode__ on Python 2
+        def __str__(self):
             return self.name
 
 We will also use the following example objects::

+ 6 - 49
docs/ref/databases.txt

@@ -273,24 +273,18 @@ running ``migrate``::
 MySQL DB API Drivers
 --------------------
 
-The Python Database API is described in :pep:`249`. MySQL has three prominent
-drivers that implement this API:
-
-- `MySQLdb`_ is a native driver that has been developed and supported for over
-  a decade by Andy Dustman.
-- `mysqlclient`_ is a fork of ``MySQLdb`` which notably supports Python 3 and
-  can be used as a drop-in replacement for MySQLdb. At the time of this writing,
-  this is **the recommended choice** for using MySQL with Django.
+MySQL has a couple drivers that implement the Python Database API described in
+:pep:`249`:
+
+- `mysqlclient`_ is a native driver. It's **the recommended choice**.
 - `MySQL Connector/Python`_ is a pure Python driver from Oracle that does not
   require the MySQL client library or any Python modules outside the standard
   library.
 
-.. _MySQLdb: https://pypi.python.org/pypi/MySQL-python/1.2.4
 .. _mysqlclient: https://pypi.python.org/pypi/mysqlclient
 .. _MySQL Connector/Python: https://dev.mysql.com/downloads/connector/python
 
-All these drivers are thread-safe and provide connection pooling. ``MySQLdb``
-is the only one not supporting Python 3 currently.
+All these drivers are thread-safe and provide connection pooling.
 
 In addition to a DB API driver, Django needs an adapter to access the database
 drivers from its ORM. Django provides an adapter for MySQLdb/mysqlclient while
@@ -298,30 +292,10 @@ MySQL Connector/Python includes `its own`_.
 
 .. _its own: https://dev.mysql.com/doc/connector-python/en/connector-python-django-backend.html
 
-MySQLdb
-~~~~~~~
-
-Django requires MySQLdb version 1.2.1p2 or later.
-
-At the time of writing, the latest release of MySQLdb (1.2.5) doesn't support
-Python 3. In order to use MySQLdb under Python 3, you'll have to install
-``mysqlclient`` instead.
-
-.. note::
-    There are known issues with the way MySQLdb converts date strings into
-    datetime objects. Specifically, date strings with value ``0000-00-00`` are
-    valid for MySQL but will be converted into ``None`` by MySQLdb.
-
-    This means you should be careful while using :djadmin:`loaddata` and
-    :djadmin:`dumpdata` with rows that may have ``0000-00-00`` values, as they
-    will be converted to ``None``.
-
 mysqlclient
 ~~~~~~~~~~~
 
-Django requires `mysqlclient`_ 1.3.3 or later. Note that Python 3.2 is not
-supported. Except for the Python 3.3+ support, mysqlclient should mostly behave
-the same as MySQLDB.
+Django requires `mysqlclient`_ 1.3.3 or later.
 
 MySQL Connector/Python
 ~~~~~~~~~~~~~~~~~~~~~~
@@ -689,23 +663,6 @@ substring filtering.
 
 .. _documented at sqlite.org: https://www.sqlite.org/faq.html#q18
 
-Old SQLite and ``CASE`` expressions
------------------------------------
-
-SQLite 3.6.23.1 and older contains a bug when `handling query parameters`_ in
-a ``CASE`` expression that contains an ``ELSE`` and arithmetic.
-
-SQLite 3.6.23.1 was released in March 2010, and most current binary
-distributions for different platforms include a newer version of SQLite, with
-the notable exception of the Python 2.7 installers for Windows.
-
-As of this writing, the latest release for Windows - Python 2.7.10 - includes
-SQLite 3.6.21. You can install ``pysqlite2`` or replace ``sqlite3.dll`` (by
-default installed in ``C:\Python27\DLLs``) with a newer version from
-https://www.sqlite.org/ to remedy this issue.
-
-.. _handling query parameters: https://code.djangoproject.com/ticket/24148
-
 .. _using-newer-versions-of-pysqlite:
 
 Using newer versions of the SQLite DB-API 2.0 driver

+ 1 - 5
docs/ref/exceptions.txt

@@ -217,11 +217,7 @@ Specification v2.0, for further information.
 
 As per :pep:`3134`, a ``__cause__`` attribute is set with the original
 (underlying) database exception, allowing access to any additional
-information provided. (Note that this attribute is available under
-both Python 2 and Python 3, although :pep:`3134` normally only applies
-to Python 3. To avoid unexpected differences with Python 3, Django will also
-ensure that the exception made available via ``__cause__`` has a usable
-``__traceback__`` attribute.)
+information provided.
 
 .. exception:: models.ProtectedError
 

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

@@ -97,8 +97,7 @@ The ``File`` class
 
     .. versionchanged:: 1.11
 
-        The ``readable()`` and ``writable()`` methods were added and the
-        ``seekable()`` method was made available on Python 2.
+        The ``readable()`` and ``writable()`` methods were added.
 
 .. currentmodule:: django.core.files.base
 

+ 3 - 5
docs/ref/forms/api.txt

@@ -810,12 +810,11 @@ Customizing the error list format
 
 By default, forms use ``django.forms.utils.ErrorList`` to format validation
 errors. If you'd like to use an alternate class for displaying errors, you can
-pass that in at construction time (replace ``__str__`` by ``__unicode__`` on
-Python 2)::
+pass that in at construction time::
 
     >>> from django.forms.utils import ErrorList
     >>> class DivErrorList(ErrorList):
-    ...     def __str__(self):              # __unicode__ on Python 2
+    ...     def __str__(self):
     ...         return self.as_divs()
     ...     def as_divs(self):
     ...         if not self: return ''
@@ -840,8 +839,7 @@ 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 ``__str__()`` (``__unicode__`` on Python 2) method of this
-   object displays the HTML for this field.
+   The ``__str__()`` method of this object displays the HTML for this field.
 
 To retrieve a single ``BoundField``, use dictionary lookup syntax on your form
 using the field's name as the key::

+ 5 - 6
docs/ref/forms/fields.txt

@@ -1183,12 +1183,11 @@ method::
             ...
             </select>
 
-    The ``__str__`` (``__unicode__`` on Python 2) method of the model will be
-    called to generate string representations of the objects for use in the
-    field's choices; to provide customized representations, subclass
-    ``ModelChoiceField`` and override ``label_from_instance``. This method will
-    receive a model object, and should return a string suitable for representing
-    it. For example::
+    The ``__str__()`` method of the model will be called to generate string
+    representations of the objects for use in the field's choices. To provide
+    customized representations, subclass ``ModelChoiceField`` and override
+    ``label_from_instance``. This method will receive a model object and should
+    return a string suitable for representing it. For example::
 
         from django.forms import ModelChoiceField
 

+ 1 - 1
docs/ref/models/querysets.txt

@@ -1002,7 +1002,7 @@ For example, suppose you have these models::
         name = models.CharField(max_length=50)
         toppings = models.ManyToManyField(Topping)
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return "%s (%s)" % (
                 self.name,
                 ", ".join(topping.name for topping in self.toppings.all()),

+ 0 - 21
docs/ref/request-response.txt

@@ -480,21 +480,6 @@ a subclass of dictionary. Exceptions are outlined here:
         >>> q.items()
         [('a', '3')]
 
-.. method:: QueryDict.iteritems()
-
-    Just like the standard dictionary ``iteritems()`` method. Like
-    :meth:`QueryDict.items()` this uses the same last-value logic as
-    :meth:`QueryDict.__getitem__()`.
-
-    Available only on Python 2.
-
-.. method:: QueryDict.iterlists()
-
-    Like :meth:`QueryDict.iteritems()` except it includes all values, as a list,
-    for each member of the dictionary.
-
-    Available only on Python 2.
-
 .. method:: QueryDict.values()
 
     Just like the standard dictionary ``values()`` method, except this uses the
@@ -504,12 +489,6 @@ a subclass of dictionary. Exceptions are outlined here:
         >>> q.values()
         ['3']
 
-.. method:: QueryDict.itervalues()
-
-    Just like :meth:`QueryDict.values()`, except an iterator.
-
-    Available only on Python 2.
-
 In addition, ``QueryDict`` has the following methods:
 
 .. method:: QueryDict.copy()

+ 3 - 3
docs/ref/templates/language.txt

@@ -105,13 +105,13 @@ Use a dot (``.``) to access attributes of a variable.
     override dictionary lookup. For example, consider the following code snippet
     that attempts to loop over a ``collections.defaultdict``::
 
-        {% for k, v in defaultdict.iteritems %}
+        {% for k, v in defaultdict.items %}
             Do something with k and v here...
         {% endfor %}
 
     Because dictionary lookup happens first, that behavior kicks in and provides
-    a default value instead of using the intended ``.iteritems()``
-    method. In this case, consider converting to a dictionary first.
+    a default value instead of using the intended ``.items()`` method. In this
+    case, consider converting to a dictionary first.
 
 In the above example, ``{{ section.title }}`` will be replaced with the
 ``title`` attribute of the ``section`` object.

+ 3 - 32
docs/ref/unicode.txt

@@ -48,29 +48,7 @@ General string handling
 
 Whenever you use strings with Django -- e.g., in database lookups, template
 rendering or anywhere else -- you have two choices for encoding those strings.
-You can use Unicode strings, or you can use normal strings (sometimes called
-"bytestrings") that are encoded using UTF-8.
-
-In Python 3, the logic is reversed, that is normal strings are Unicode, and
-when you want to specifically create a bytestring, you have to prefix the
-string with a 'b'. As we are doing in Django code from version 1.5,
-we recommend that you import ``unicode_literals`` from the __future__ library
-in your code. Then, when you specifically want to create a bytestring literal,
-prefix the string with 'b'.
-
-Python 2 legacy::
-
-    my_string = "This is a bytestring"
-    my_unicode = u"This is an Unicode string"
-
-Python 2 with unicode literals or Python 3::
-
-    from __future__ import unicode_literals
-
-    my_string = b"This is a bytestring"
-    my_unicode = "This is an Unicode string"
-
-See also :doc:`Python 3 compatibility </topics/python3>`.
+You can use normal Unicode strings or bytestrings (starting with a 'b').
 
 .. warning::
 
@@ -114,7 +92,7 @@ imported.
 Normally, you won't have to worry about lazy translations. Just be aware that
 if you examine an object and it claims to be a
 ``django.utils.functional.__proxy__`` object, it is a lazy translation.
-Calling ``unicode()`` with the lazy translation as the argument will generate a
+Calling ``str()`` with the lazy translation as the argument will generate a
 Unicode string in the current locale.
 
 For more details about lazy translation objects, refer to the
@@ -140,12 +118,9 @@ for converting back and forth between Unicode and bytestrings.
   ``strings_only`` parameter, if set to True, will result in Python
   numbers, booleans and ``None`` not being converted to a string (they keep
   their original types). The ``errors`` parameter takes any of the values
-  that are accepted by Python's ``unicode()`` function for its error
+  that are accepted by Python's ``str()`` function for its error
   handling.
 
-  If you pass ``smart_text()`` an object that has a ``__unicode__``
-  method, it will use that method to do the conversion.
-
 * ``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
@@ -292,8 +267,6 @@ You can pass either Unicode strings or UTF-8 bytestrings as arguments to
 ``filter()`` methods and the like in the database API. The following two
 querysets are identical::
 
-    from __future__ import unicode_literals
-
     qs = People.objects.filter(name__contains='Å')
     qs = People.objects.filter(name__contains=b'\xc3\x85') # UTF-8 encoding of Å
 
@@ -302,7 +275,6 @@ Templates
 
 You can use either Unicode or bytestrings when creating templates manually::
 
-    from __future__ import unicode_literals
     from django.template import Template
     t1 = Template(b'This is a bytestring template.')
     t2 = Template('This is a Unicode template.')
@@ -373,7 +345,6 @@ characters.
 The following code example demonstrates that everything except email addresses
 can be non-ASCII::
 
-    from __future__ import unicode_literals
     from django.core.mail import EmailMessage
 
     subject = 'My visit to Sør-Trøndelag'

+ 1 - 1
docs/ref/urlresolvers.txt

@@ -175,9 +175,9 @@ A :class:`ResolverMatch` object can also be assigned to a triple::
 One possible use of :func:`~django.urls.resolve` would be to test whether a
 view would raise a ``Http404`` error before redirecting to it::
 
+    from urllib.parse import urlparse
     from django.urls import resolve
     from django.http import HttpResponseRedirect, Http404
-    from django.utils.six.moves.urllib.parse import urlparse
 
     def myview(request):
         next = request.META.get('HTTP_REFERER', None) or '/'

+ 29 - 40
docs/ref/utils.txt

@@ -203,16 +203,12 @@ The functions defined in this module share the following properties:
 
 .. function:: smart_text(s, encoding='utf-8', strings_only=False, errors='strict')
 
-    Returns a text object representing ``s`` -- ``unicode`` on Python 2 and
-    ``str`` on Python 3. Treats bytestrings using the ``encoding`` codec.
+    Returns a ``str`` object representing ``s``. 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.
@@ -228,10 +224,6 @@ The functions defined in this module share the following properties:
     If ``strings_only`` is ``True``, don't convert (some) non-string-like
     objects.
 
-.. 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')
 
     Returns a bytestring version of ``s``, encoded as specified in
@@ -250,16 +242,20 @@ The functions defined in this module share the following properties:
 
 .. 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 returns a ``str`` or a lazy string.
+    Alias of :func:`smart_text`. This function returns a ``str`` or a lazy
+    string.
+
+    For instance, this is suitable for writing to :data:`sys.stdout`.
 
-    For instance, this is  suitable for writing to :data:`sys.stdout` on
-    Python 2 and 3.
+    Alias of :func:`smart_bytes` on Python 2 (in older versions of Django that
+    support it).
 
 .. function:: force_str(s, encoding='utf-8', strings_only=False, errors='strict')
 
-    Alias of :func:`force_bytes` on Python 2 and :func:`force_text` on Python
-    3. This function always returns a ``str``.
+    Alias of :func:`force_text`. This function always returns a ``str``.
+
+    Alias of :func:`force_bytes` on Python 2 (in older versions of Django that
+    support it).
 
 .. function:: iri_to_uri(iri)
 
@@ -538,23 +534,22 @@ https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004
 
     For example::
 
-        from django.utils import six
         from django.utils.functional import keep_lazy, keep_lazy_text
 
         def fancy_utility_function(s, ...):
             # Do some conversion on string 's'
             ...
-        fancy_utility_function = keep_lazy(six.text_type)(fancy_utility_function)
+        fancy_utility_function = keep_lazy(str)(fancy_utility_function)
 
         # Or more succinctly:
-        @keep_lazy(six.text_type)
+        @keep_lazy(str)
         def fancy_utility_function(s, ...):
             ...
 
     The ``keep_lazy()`` decorator takes a number of extra arguments (``*args``)
     specifying the type(s) that the original function can return. A common
     use case is to have functions that return text. For these, you can just
-    pass the ``six.text_type`` type to ``keep_lazy`` (or even simpler, use the
+    pass the ``str`` type to ``keep_lazy`` (or even simpler, use the
     :func:`keep_lazy_text` decorator described in the next section).
 
     Using this decorator means you can write your function and assume that the
@@ -563,16 +558,15 @@ https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004
 
 .. function:: keep_lazy_text(func)
 
-    A shortcut for ``keep_lazy(six.text_type)(func)``.
+    A shortcut for ``keep_lazy(str)(func)``.
 
     If you have a function that returns text and you want to be able to take
     lazy arguments while delaying their evaluation, simply use this decorator::
 
-        from django.utils import six
         from django.utils.functional import keep_lazy, keep_lazy_text
 
         # Our previous example was:
-        @keep_lazy(six.text_type)
+        @keep_lazy(str)
         def fancy_utility_function(s, ...):
             ...
 
@@ -680,11 +674,9 @@ escaping HTML.
     classes whose output doesn't require HTML escaping.
 
     This decorator defines the ``__html__()`` method on the decorated class
-    by wrapping the ``__unicode__()`` (Python 2) or ``__str__()`` (Python 3)
-    in :meth:`~django.utils.safestring.mark_safe`. Ensure the ``__unicode__()``
-    or ``__str__()`` method does indeed return text that doesn't require HTML
-    escaping.
-
+    by wrapping ``__str__()`` in :meth:`~django.utils.safestring.mark_safe`.
+    Ensure the ``__str__()`` method does indeed return text that doesn't
+    require HTML escaping.
 
 ``django.utils.http``
 =====================
@@ -737,13 +729,11 @@ escaping HTML.
 
 .. function:: base36_to_int(s)
 
-    Converts a base 36 string to an integer. On Python 2 the output is
-    guaranteed to be an ``int`` and not a ``long``.
+    Converts a base 36 string to an integer.
 
 .. function:: int_to_base36(i)
 
-    Converts a positive integer to a base 36 string. On Python 2 ``i`` must be
-    smaller than `sys.maxint`_.
+    Converts a positive integer to a base 36 string.
 
     .. _sys.maxint: https://docs.python.org/2/library/sys.html#sys.maxint
 
@@ -798,17 +788,16 @@ appropriate entities.
 .. class:: SafeString
 
     A ``str`` subclass that has been specifically marked as "safe"
-    (requires no further escaping) for HTML output purposes. This is
-    :class:`SafeBytes` on Python 2 and :class:`SafeText` on Python 3.
+    (requires no further escaping) for HTML output purposes. Alias of
+    :class:`SafeText`.
 
-.. class:: SafeText
+    Alias of :class:`SafeBytes` on Python 2 (in older versions of Django that
+    support it).
 
-    A ``str`` (in Python 3) or ``unicode`` (in Python 2) subclass
-    that has been specifically marked as "safe" for HTML output purposes.
-
-.. class:: SafeUnicode
+.. class:: SafeText
 
-    Historical name of :class:`SafeText`. Only available under Python 2.
+    A ``str`` subclass that has been specifically marked as "safe" for HTML
+    output purposes.
 
 .. function:: mark_safe(s)
 

+ 1 - 1
docs/releases/1.4.11.txt

@@ -5,7 +5,7 @@ Django 1.4.11 release notes
 *April 21, 2014*
 
 Django 1.4.11 fixes three security issues in 1.4.10. Additionally,
-Django's vendored version of six, :mod:`django.utils.six`, has been
+Django's vendored version of six, ``django.utils.six``, has been
 upgraded to the latest release (1.6.1).
 
 Unexpected code execution using ``reverse()``

+ 1 - 1
docs/releases/1.4.17.txt

@@ -6,7 +6,7 @@ Django 1.4.17 release notes
 
 Django 1.4.17 fixes a regression in the 1.4.14 security release.
 
-Additionally, Django's vendored version of six, :mod:`django.utils.six`, has
+Additionally, Django's vendored version of six, ``django.utils.six``, has
 been upgraded to the latest release (1.9.0).
 
 Bugfixes

+ 1 - 1
docs/releases/1.4.18.txt

@@ -64,5 +64,5 @@ Bugfixes
 ========
 
 * To maintain compatibility with Python 2.5, Django's vendored version of six,
-  :mod:`django.utils.six`, has been downgraded to 1.8.0 which is the last
+  ``django.utils.six``, has been downgraded to 1.8.0 which is the last
   version to support Python 2.5.

+ 1 - 1
docs/releases/1.5.6.txt

@@ -113,5 +113,5 @@ Bugfixes
   ``UnboundLocalError`` if :func:`~django.contrib.auth.get_user_model`
   raised an error (#21439).
 
-Additionally, Django's vendored version of six, :mod:`django.utils.six`,
+Additionally, Django's vendored version of six, ``django.utils.six``,
 has been upgraded to the latest release (1.6.1).

+ 3 - 3
docs/releases/1.5.txt

@@ -107,9 +107,9 @@ to Python 3, so it's unlikely that a real-world application will have all its
 dependencies satisfied under Python 3.
 
 Thus, we're recommending that Django 1.5 not be used in production under Python
-3. Instead, use this opportunity to begin :doc:`porting applications to Python 3
-</topics/python3>`. If you're an author of a pluggable component, we encourage you
-to start porting now.
+3. Instead, use this opportunity to begin porting applications to Python 3. If
+you're an author of a pluggable component, we encourage you to start porting
+now.
 
 We plan to offer first-class, production-ready support for Python 3 in our next
 release, Django 1.6.

+ 1 - 1
docs/releases/1.6.2.txt

@@ -48,5 +48,5 @@ several bugs in 1.6.1:
   through :func:`~django.utils.safestring.mark_safe` and could end up being
   double-escaped (:ticket:`21882`).
 
-Additionally, Django's vendored version of six, :mod:`django.utils.six` has been
+Additionally, Django's vendored version of six, ``django.utils.six`` has been
 upgraded to the latest release (1.5.2).

+ 1 - 1
docs/releases/1.6.3.txt

@@ -179,5 +179,5 @@ Other bugfixes and changes
   query to include an unnecessary join
   (:ticket:`21760`).
 
-Additionally, Django's vendored version of six, :mod:`django.utils.six` has been
+Additionally, Django's vendored version of six, ``django.utils.six`` has been
 upgraded to the latest release (1.6.1).

+ 1 - 1
docs/releases/1.6.9.txt

@@ -6,7 +6,7 @@ Django 1.6.9 release notes
 
 Django 1.6.9 fixes a regression in the 1.6.6 security release.
 
-Additionally, Django's vendored version of six, :mod:`django.utils.six`, has
+Additionally, Django's vendored version of six, ``django.utils.six``, has
 been upgraded to the latest release (1.9.0).
 
 Bugfixes

+ 1 - 1
docs/releases/1.7.2.txt

@@ -6,7 +6,7 @@ Django 1.7.2 release notes
 
 Django 1.7.2 fixes several bugs in 1.7.1.
 
-Additionally, Django's vendored version of six, :mod:`django.utils.six`, has
+Additionally, Django's vendored version of six, ``django.utils.six``, has
 been upgraded to the latest release (1.9.0).
 
 Bugfixes

+ 1 - 1
docs/releases/1.8.7.txt

@@ -6,7 +6,7 @@ Django 1.8.7 release notes
 
 Django 1.8.7 fixes a security issue and several bugs in 1.8.6.
 
-Additionally, Django's vendored version of six, :mod:`django.utils.six`, has
+Additionally, Django's vendored version of six, ``django.utils.six``, has
 been upgraded to the latest release (1.10.0).
 
 Fixed settings leak possibility in ``date`` template filter

+ 1 - 1
docs/topics/auth/customizing.txt

@@ -1060,7 +1060,7 @@ authentication app::
             # The user is identified by their email address
             return self.email
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.email
 
         def has_perm(self, perm, obj=None):

+ 1 - 2
docs/topics/cache.txt

@@ -805,8 +805,7 @@ The basic interface is ``set(key, value, timeout)`` and ``get(key)``::
     >>> cache.get('my_key')
     'hello, world!'
 
-``key`` should be a ``str`` (or ``unicode`` on Python 2), and ``value`` can be
-any picklable Python object.
+``key`` should be a ``str``, and ``value`` can be any picklable Python object.
 
 The ``timeout`` argument is optional and defaults to the ``timeout`` argument
 of the appropriate backend in the :setting:`CACHES` setting (explained above).

+ 2 - 2
docs/topics/class-based-views/generic-display.txt

@@ -87,7 +87,7 @@ We'll be using these models::
         class Meta:
             ordering = ["-name"]
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.name
 
     class Author(models.Model):
@@ -96,7 +96,7 @@ We'll be using these models::
         email = models.EmailField()
         headshot = models.ImageField(upload_to='author_headshots')
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.name
 
     class Book(models.Model):

+ 2 - 2
docs/topics/db/examples/many_to_many.txt

@@ -17,7 +17,7 @@ objects, and a ``Publication`` has multiple ``Article`` objects:
     class Publication(models.Model):
         title = models.CharField(max_length=30)
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.title
 
         class Meta:
@@ -27,7 +27,7 @@ objects, and a ``Publication`` has multiple ``Article`` objects:
         headline = models.CharField(max_length=100)
         publications = models.ManyToManyField(Publication)
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.headline
 
         class Meta:

+ 2 - 9
docs/topics/db/examples/many_to_one.txt

@@ -11,7 +11,7 @@ To define a many-to-one relationship, use :class:`~django.db.models.ForeignKey`:
         last_name = models.CharField(max_length=30)
         email = models.EmailField()
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return "%s %s" % (self.first_name, self.last_name)
 
     class Article(models.Model):
@@ -19,7 +19,7 @@ To define a many-to-one relationship, use :class:`~django.db.models.ForeignKey`:
         pub_date = models.DateField()
         reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.headline
 
         class Meta:
@@ -64,13 +64,6 @@ Article objects have access to their related Reporter objects::
 
     >>> r = a.reporter
 
-On Python 2, these are strings of type ``str`` instead of unicode strings
-because that's what was used in the creation of this reporter (and we haven't
-refreshed the data from the database, which always returns unicode strings)::
-
-    >>> r.first_name, r.last_name
-    ('John', 'Smith')
-
 Create an Article via the Reporter object::
 
     >>> new_article = r.article_set.create(headline="John's second story", pub_date=date(2005, 7, 29))

+ 3 - 3
docs/topics/db/examples/one_to_one.txt

@@ -13,7 +13,7 @@ In this example, a ``Place`` optionally can be a ``Restaurant``::
         name = models.CharField(max_length=50)
         address = models.CharField(max_length=80)
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return "%s the place" % self.name
 
     class Restaurant(models.Model):
@@ -25,14 +25,14 @@ In this example, a ``Place`` optionally can be a ``Restaurant``::
         serves_hot_dogs = models.BooleanField(default=False)
         serves_pizza = models.BooleanField(default=False)
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return "%s the restaurant" % self.place.name
 
     class Waiter(models.Model):
         restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
         name = models.CharField(max_length=50)
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return "%s the waiter at %s" % (self.name, self.restaurant)
 
 What follows are examples of operations that can be performed using the Python

+ 3 - 6
docs/topics/db/models.txt

@@ -445,14 +445,14 @@ something like this::
     class Person(models.Model):
         name = models.CharField(max_length=128)
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.name
 
     class Group(models.Model):
         name = models.CharField(max_length=128)
         members = models.ManyToManyField(Person, through='Membership')
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.name
 
     class Membership(models.Model):
@@ -761,7 +761,7 @@ of :ref:`methods automatically given to each model <model-instance-methods>`.
 You can override most of these -- see `overriding predefined model methods`_,
 below -- but there are a couple that you'll almost always want to define:
 
-:meth:`~Model.__str__` (Python 3)
+:meth:`~Model.__str__`
     A Python "magic method" that returns a unicode "representation" of any
     object. This is what Python and Django will use whenever a model
     instance needs to be coerced and displayed as a plain string. Most
@@ -771,9 +771,6 @@ below -- but there are a couple that you'll almost always want to define:
     You'll always want to define this method; the default isn't very helpful
     at all.
 
-``__unicode__()`` (Python 2)
-    Python 2 equivalent of ``__str__()``.
-
 :meth:`~Model.get_absolute_url`
     This tells Django how to calculate the URL for an object. Django uses
     this in its admin interface, and any time it needs to figure out a URL

+ 3 - 3
docs/topics/db/queries.txt

@@ -23,14 +23,14 @@ models, which comprise a Weblog application:
         name = models.CharField(max_length=100)
         tagline = models.TextField()
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.name
 
     class Author(models.Model):
         name = models.CharField(max_length=200)
         email = models.EmailField()
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.name
 
     class Entry(models.Model):
@@ -44,7 +44,7 @@ models, which comprise a Weblog application:
         n_pingbacks = models.IntegerField()
         rating = models.IntegerField()
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.headline
 
 Creating objects

+ 1 - 1
docs/topics/forms/modelforms.txt

@@ -169,7 +169,7 @@ Consider this set of models::
         title = models.CharField(max_length=3, choices=TITLE_CHOICES)
         birth_date = models.DateField(blank=True, null=True)
 
-        def __str__(self):              # __unicode__ on Python 2
+        def __str__(self):
             return self.name
 
     class Book(models.Model):

+ 1 - 5
docs/topics/i18n/translation.txt

@@ -431,9 +431,6 @@ strings before passing them to non-Django code::
 
     requests.post('https://example.com/send', data={'body': str(body)})
 
-Use ``unicode`` in place of ``str`` on Python 2, or :data:`six.text_type` to
-support Python 2 and 3.
-
 If you try to use a ``ugettext_lazy()`` result where a bytestring (a
 :class:`bytes` object) is expected, things won't work as expected since a
 ``ugettext_lazy()`` object doesn't know how to convert itself to a bytestring.
@@ -534,12 +531,11 @@ For any other case where you would like to delay the translation, but have to
 pass the translatable string as argument to another function, you can wrap
 this function inside a lazy call yourself. For example::
 
-    from django.utils import six  # Python 3 compatibility
     from django.utils.functional import lazy
     from django.utils.safestring import mark_safe
     from django.utils.translation import ugettext_lazy as _
 
-    mark_safe_lazy = lazy(mark_safe, six.text_type)
+    mark_safe_lazy = lazy(mark_safe, str)
 
 And then later::
 

+ 0 - 1
docs/topics/index.txt

@@ -24,7 +24,6 @@ Introductions to all the key parts of Django you'll need to know:
    i18n/index
    logging
    pagination
-   python3
    security
    performance
    serialization

+ 2 - 2
docs/topics/install.txt

@@ -171,7 +171,7 @@ This is the recommended way to install Django.
    isolated Python environments, which are more practical than installing
    packages systemwide. They also allow installing packages without
    administrator privileges. The :doc:`contributing tutorial
-   </intro/contributing>` walks through how to create a virtualenv on Python 3.
+   </intro/contributing>` walks through how to create a virtualenv.
 
 3. After you've created and activated a virtual environment, enter the command
    ``pip install Django`` at the shell prompt.
@@ -227,7 +227,7 @@ latest bug fixes and improvements, follow these instructions:
 3. Make sure that the Python interpreter can load Django's code. The most
    convenient way to do this is to use virtualenv_, virtualenvwrapper_, and
    pip_. The :doc:`contributing tutorial </intro/contributing>` walks through
-   how to create a virtualenv on Python 3.
+   how to create a virtualenv.
 
 4. After setting up and activating the virtualenv, run the following command:
 

+ 1 - 19
docs/topics/migrations.txt

@@ -665,6 +665,7 @@ Django can serialize the following:
 - ``LazyObject`` instances which wrap a serializable value.
 - Any Django field
 - Any function or method reference (e.g. ``datetime.datetime.today``) (must be in module's top-level scope)
+- Unbound methods used from within the class body
 - Any class reference (must be in module's top-level scope)
 - Anything with a custom ``deconstruct()`` method (:ref:`see below <custom-deconstruct-method>`)
 
@@ -672,31 +673,12 @@ Django can serialize the following:
 
     Serialization support for ``uuid.UUID`` was added.
 
-Django can serialize the following on Python 3 only:
-
-- Unbound methods used from within the class body (see below)
-
 Django cannot serialize:
 
 - Nested classes
 - Arbitrary class instances (e.g. ``MyClass(4.3, 5.7)``)
 - Lambdas
 
-Due to the fact ``__qualname__`` was only introduced in Python 3, Django can only
-serialize the following pattern (an unbound method used within the class body)
-on Python 3, and will fail to serialize a reference to it on Python 2::
-
-    class MyModel(models.Model):
-
-        def upload_to(self):
-            return "something dynamic"
-
-        my_file = models.FileField(upload_to=upload_to)
-
-If you are using Python 2, we recommend you move your methods for upload_to
-and similar arguments that accept callables (e.g. ``default``) to live in
-the main module body, rather than the class body.
-
 .. _custom-deconstruct-method:
 
 Adding a ``deconstruct()`` method

+ 1 - 1
docs/topics/pagination.txt

@@ -24,7 +24,7 @@ page::
     4
     >>> p.num_pages
     2
-    >>> type(p.page_range)  # `<type 'rangeiterator'>` in Python 2.
+    >>> type(p.page_range)
     <class 'range_iterator'>
     >>> p.page_range
     range(1, 3)

+ 0 - 369
docs/topics/python3.txt

@@ -1,369 +0,0 @@
-===================
-Porting to Python 3
-===================
-
-Django 1.5 is the first version of Django to support Python 3. The same code
-runs both on Python 2 (≥ 2.6.5) and Python 3 (≥ 3.2), thanks to the six_
-compatibility layer.
-
-.. _six: https://pythonhosted.org/six/
-
-This document is primarily targeted at authors of pluggable applications
-who want to support both Python 2 and 3. It also describes guidelines that
-apply to Django's code.
-
-Philosophy
-==========
-
-This document assumes that you are familiar with the changes between Python 2
-and Python 3. If you aren't, read :ref:`Python's official porting guide
-<pyporting-howto>` first. Refreshing your knowledge of unicode handling on
-Python 2 and 3 will help; the `Pragmatic Unicode`_ presentation is a good
-resource.
-
-Django uses the *Python 2/3 Compatible Source* strategy. Of course, you're
-free to chose another strategy for your own code, especially if you don't need
-to stay compatible with Python 2. But authors of pluggable applications are
-encouraged to use the same porting strategy as Django itself.
-
-Writing compatible code is much easier if you target Python ≥ 2.6. Django 1.5
-introduces compatibility tools such as :mod:`django.utils.six`, which is a
-customized version of the :mod:`six module <six>`. For convenience,
-forwards-compatible aliases were introduced in Django 1.4.2. If your
-application takes advantage of these tools, it will require Django ≥ 1.4.2.
-
-Obviously, writing compatible source code adds some overhead, and that can
-cause frustration. Django's developers have found that attempting to write
-Python 3 code that's compatible with Python 2 is much more rewarding than the
-opposite. Not only does that make your code more future-proof, but Python 3's
-advantages (like the saner string handling) start shining quickly. Dealing
-with Python 2 becomes a backwards compatibility requirement, and we as
-developers are used to dealing with such constraints.
-
-Porting tools provided by Django are inspired by this philosophy, and it's
-reflected throughout this guide.
-
-.. _Pragmatic Unicode: http://nedbatchelder.com/text/unipain.html
-
-Porting tips
-============
-
-Unicode literals
-----------------
-
-This step consists in:
-
-- Adding ``from __future__ import unicode_literals`` at the top of your Python
-  modules -- it's best to put it in each and every module, otherwise you'll
-  keep checking the top of your files to see which mode is in effect;
-- Removing the ``u`` prefix before unicode strings;
-- Adding a ``b`` prefix before bytestrings.
-
-Performing these changes systematically guarantees backwards compatibility.
-
-However, Django applications generally don't need bytestrings, since Django
-only exposes unicode interfaces to the programmer. Python 3 discourages using
-bytestrings, except for binary data or byte-oriented interfaces. Python 2
-makes bytestrings and unicode strings effectively interchangeable, as long as
-they only contain ASCII data. Take advantage of this to use unicode strings
-wherever possible and avoid the ``b`` prefixes.
-
-.. note::
-
-    Python 2's ``u`` prefix is a syntax error in Python 3.2 but it will be
-    allowed again in Python 3.3 thanks to :pep:`414`. Thus, this
-    transformation is optional if you target Python ≥ 3.3. It's still
-    recommended, per the "write Python 3 code" philosophy.
-
-String handling
----------------
-
-Python 2's `unicode`_ type was renamed :class:`str` in Python 3,
-``str()`` was renamed :class:`bytes`, and `basestring`_ disappeared.
-six_ provides :ref:`tools <string-handling-with-six>` to deal with these
-changes.
-
-Django also contains several string related classes and functions in the
-:mod:`django.utils.encoding` and :mod:`django.utils.safestring` modules. Their
-names used the words ``str``, which doesn't mean the same thing in Python 2
-and Python 3, and ``unicode``, which doesn't exist in Python 3. In order to
-avoid ambiguity and confusion these concepts were renamed ``bytes`` and
-``text``.
-
-Here are the name changes in :mod:`django.utils.encoding`:
-
-==================  ==================
-Old name            New name
-==================  ==================
-``smart_str``       ``smart_bytes``
-``smart_unicode``   ``smart_text``
-``force_unicode``   ``force_text``
-==================  ==================
-
-For backwards compatibility, the old names still work on Python 2. Under
-Python 3, ``smart_str`` is an alias for ``smart_text``.
-
-For forwards compatibility, the new names work as of Django 1.4.2.
-
-.. note::
-
-    :mod:`django.utils.encoding` was deeply refactored in Django 1.5 to
-    provide a more consistent API. Check its documentation for more
-    information.
-
-:mod:`django.utils.safestring` is mostly used via the
-:func:`~django.utils.safestring.mark_safe` function, which didn't change. In
-case you're using the internals, here are the name changes:
-
-==================  ==================
-Old name            New name
-==================  ==================
-``SafeString``      ``SafeBytes``
-``SafeUnicode``     ``SafeText``
-==================  ==================
-
-For backwards compatibility, the old names still work on Python 2. On Python 3,
-``SafeString`` is an alias for ``SafeText``.
-
-For forwards compatibility, the new names work as of Django 1.4.2.
-
-``__str__()`` and ``__unicode__()`` methods
--------------------------------------------
-
-In Python 2, the object model specifies :meth:`~object.__str__` and
-` __unicode__()`_ methods. If these methods exist, they must return
-``str`` (bytes) and ``unicode`` (text) respectively.
-
-The ``print`` statement and the :class:`str` built-in call
-:meth:`~object.__str__` to determine the human-readable representation of an
-object. The ``unicode`` built-in calls ` __unicode__()`_ if it
-exists, and otherwise falls back to :meth:`~object.__str__` and decodes the
-result with the system encoding. Conversely, the
-:class:`~django.db.models.Model` base class automatically derives
-:meth:`~object.__str__` from ` __unicode__()`_ by encoding to UTF-8.
-
-In Python 3, there's simply :meth:`~object.__str__`, which must return ``str``
-(text).
-
-(It is also possible to define :meth:`~object.__bytes__`, but Django applications
-have little use for that method, because they hardly ever deal with ``bytes``.)
-
-Finally, note that :meth:`~object.__repr__` must return a ``str`` on all
-versions of Python.
-
-:class:`dict` and :class:`dict`-like classes
---------------------------------------------
-
-:meth:`dict.keys`, :meth:`dict.items` and :meth:`dict.values` return lists in
-Python 2 and iterators in Python 3. :class:`~django.http.QueryDict` and the
-:class:`dict`-like classes defined in ``django.utils.datastructures``
-behave likewise in Python 3.
-
-six_ provides compatibility functions to work around this change:
-:func:`~six.iterkeys`, :func:`~six.iteritems`, and :func:`~six.itervalues`.
-It also contains an undocumented ``iterlists`` function that works well for
-``django.utils.datastructures.MultiValueDict`` and its subclasses.
-
-:class:`~django.http.HttpRequest` and :class:`~django.http.HttpResponse` objects
---------------------------------------------------------------------------------
-
-According to :pep:`3333`:
-
-- headers are always ``str`` objects,
-- input and output streams are always ``bytes`` objects.
-
-Specifically, :attr:`HttpResponse.content <django.http.HttpResponse.content>`
-contains ``bytes``, which may become an issue if you compare it with a
-``str`` in your tests. The preferred solution is to rely on
-:meth:`~django.test.SimpleTestCase.assertContains` and
-:meth:`~django.test.SimpleTestCase.assertNotContains`. These methods accept a
-response and a unicode string as arguments.
-
-Coding guidelines
-=================
-
-The following guidelines are enforced in Django's source code. They're also
-recommended for third-party applications that follow the same porting strategy.
-
-Syntax requirements
--------------------
-
-Unicode
-~~~~~~~
-
-In Python 3, all strings are considered Unicode by default. The ``unicode``
-type from Python 2 is called ``str`` in Python 3, and ``str`` becomes
-``bytes``.
-
-You mustn't use the ``u`` prefix before a unicode string literal because it's
-a syntax error in Python 3.2. You must prefix byte strings with ``b``.
-
-In order to enable the same behavior in Python 2, every module must import
-``unicode_literals`` from ``__future__``::
-
-    from __future__ import unicode_literals
-
-    my_string = "This is an unicode literal"
-    my_bytestring = b"This is a bytestring"
-
-If you need a byte string literal under Python 2 and a unicode string literal
-under Python 3, use the :class:`str` builtin::
-
-    str('my string')
-
-In Python 3, there aren't any automatic conversions between ``str`` and
-``bytes``, and the :mod:`codecs` module became more strict. :meth:`str.encode`
-always returns ``bytes``, and ``bytes.decode`` always returns ``str``. As a
-consequence, the following pattern is sometimes necessary::
-
-    value = value.encode('ascii', 'ignore').decode('ascii')
-
-Be cautious if you have to `index bytestrings`_.
-
-.. _index bytestrings: https://docs.python.org/3/howto/pyporting.html#text-versus-binary-data
-
-Exceptions
-~~~~~~~~~~
-
-When you capture exceptions, use the ``as`` keyword::
-
-    try:
-        ...
-    except MyException as exc:
-        ...
-
-This older syntax was removed in Python 3::
-
-    try:
-        ...
-    except MyException, exc:    # Don't do that!
-        ...
-
-The syntax to reraise an exception with a different traceback also changed.
-Use :func:`six.reraise`.
-
-Magic methods
--------------
-
-Use the patterns below to handle magic methods renamed in Python 3.
-
-Iterators
-~~~~~~~~~
-
-::
-
-    class MyIterator(six.Iterator):
-        def __iter__(self):
-            return self             # implement some logic here
-
-        def __next__(self):
-            raise StopIteration     # implement some logic here
-
-Boolean evaluation
-~~~~~~~~~~~~~~~~~~
-
-::
-
-    class MyBoolean(object):
-
-        def __bool__(self):
-            return True             # implement some logic here
-
-        def __nonzero__(self):      # Python 2 compatibility
-            return type(self).__bool__(self)
-
-Division
-~~~~~~~~
-
-::
-
-    class MyDivisible(object):
-
-        def __truediv__(self, other):
-            return self / other     # implement some logic here
-
-        def __div__(self, other):   # Python 2 compatibility
-            return type(self).__truediv__(self, other)
-
-        def __itruediv__(self, other):
-            return self // other    # implement some logic here
-
-        def __idiv__(self, other):  # Python 2 compatibility
-            return type(self).__itruediv__(self, other)
-
-Special methods are looked up on the class and not on the instance to reflect
-the behavior of the Python interpreter.
-
-.. module: django.utils.six
-
-Writing compatible code with six
---------------------------------
-
-six_ is the canonical compatibility library for supporting Python 2 and 3 in
-a single codebase. Read its documentation!
-
-A :mod:`customized version of six <django.utils.six>` is bundled with Django
-as of version 1.4.2. You can import it as ``django.utils.six``.
-
-Here are the most common changes required to write compatible code.
-
-.. _string-handling-with-six:
-
-String handling
-~~~~~~~~~~~~~~~
-
-The ``basestring`` and ``unicode`` types were removed in Python 3, and the
-meaning of ``str`` changed. To test these types, use the following idioms::
-
-    isinstance(myvalue, six.string_types)       # replacement for basestring
-    isinstance(myvalue, six.text_type)          # replacement for unicode
-    isinstance(myvalue, bytes)                  # replacement for str
-
-Python ≥ 2.6 provides ``bytes`` as an alias for ``str``, so you don't need
-:data:`six.binary_type`.
-
-``long``
-~~~~~~~~
-
-The ``long`` type no longer exists in Python 3. ``1L`` is a syntax error. Use
-:data:`six.integer_types` check if a value is an integer or a long::
-
-    isinstance(myvalue, six.integer_types)      # replacement for (int, long)
-
-``xrange``
-~~~~~~~~~~
-
-If you use ``xrange`` on Python 2, import ``six.moves.range`` and use that
-instead. You can also import ``six.moves.xrange`` (it's equivalent to
-``six.moves.range``) but the first technique allows you to simply drop the
-import when dropping support for Python 2.
-
-Moved modules
-~~~~~~~~~~~~~
-
-Some modules were renamed in Python 3. The ``django.utils.six.moves``
-module (based on the :mod:`six.moves module <six.moves>`) provides a
-compatible location to import them.
-
-``PY2``
-~~~~~~~
-
-If you need different code in Python 2 and Python 3, check :data:`six.PY2`::
-
-    if six.PY2:
-        # compatibility code for Python 2
-
-This is a last resort solution when :mod:`six` doesn't provide an appropriate
-function.
-
-.. module:: django.utils.six
-
-Django customized version of ``six``
-------------------------------------
-
-The version of six bundled with Django (``django.utils.six``) includes a few
-customizations for internal use only.
-
-.. _unicode: https://docs.python.org/2/library/functions.html#unicode
-.. _ __unicode__(): https://docs.python.org/2/reference/datamodel.html#object.__unicode__
-.. _basestring: https://docs.python.org/2/library/functions.html#basestring

+ 3 - 3
docs/topics/testing/overview.txt

@@ -177,9 +177,9 @@ control the particular collation used by the test database. See the
 :doc:`settings documentation </ref/settings>` for details of these
 and other advanced settings.
 
-If using an SQLite in-memory database with Python 3.4+ and SQLite 3.7.13+,
-`shared cache <https://www.sqlite.org/sharedcache.html>`_ will be enabled, so
-you can write tests with ability to share the database between threads.
+If using an SQLite in-memory database with SQLite 3.7.13+, `shared cache
+<https://www.sqlite.org/sharedcache.html>`_ is enabled, so you can write tests
+with ability to share the database between threads.
 
 .. admonition:: Finding data from your production database when running tests?
 

+ 1 - 1
docs/topics/testing/tools.txt

@@ -1708,9 +1708,9 @@ Management commands can be tested with the
 :func:`~django.core.management.call_command` function. The output can be
 redirected into a ``StringIO`` instance::
 
+    from io import StringIO
     from django.core.management import call_command
     from django.test import TestCase
-    from django.utils.six import StringIO
 
     class ClosepollTest(TestCase):
         def test_command_output(self):