Removed support for Python 3.3.

This commit is contained in:
Tim Graham 2015-06-15 09:43:35 -04:00
parent e5cb4e1411
commit 7f1168e387
17 changed files with 44 additions and 65 deletions

View File

@ -55,7 +55,7 @@ class AppConfig(object):
"""Attempt to determine app's filesystem path from its module.""" """Attempt to determine app's filesystem path from its module."""
# See #21874 for extended discussion of the behavior of this method in # See #21874 for extended discussion of the behavior of this method in
# various cases. # various cases.
# Convert paths to list because Python 3.3 _NamespacePath does not # Convert paths to list because Python 3's _NamespacePath does not
# support indexing. # support indexing.
paths = list(getattr(module, '__path__', [])) paths = list(getattr(module, '__path__', []))
if len(paths) != 1: if len(paths) != 1:

View File

@ -3,7 +3,6 @@ from __future__ import unicode_literals
import mimetypes import mimetypes
import os import os
import random import random
import sys
import time import time
from email import ( from email import (
charset as Charset, encoders as Encoders, generator, message_from_string, charset as Charset, encoders as Encoders, generator, message_from_string,
@ -170,12 +169,6 @@ class SafeMIMEText(MIMEMixin, MIMEText):
# We do it manually and trigger re-encoding of the payload. # We do it manually and trigger re-encoding of the payload.
MIMEText.__init__(self, _text, _subtype, None) MIMEText.__init__(self, _text, _subtype, None)
del self['Content-Transfer-Encoding'] del self['Content-Transfer-Encoding']
# Workaround for versions without http://bugs.python.org/issue19063
if (3, 2) < sys.version_info < (3, 3, 4):
payload = _text.encode(utf8_charset.output_charset)
self._payload = payload.decode('ascii', 'surrogateescape')
self.set_charset(utf8_charset)
else:
self.set_payload(_text, utf8_charset) self.set_payload(_text, utf8_charset)
self.replace_header('Content-Type', 'text/%s; charset="%s"' % (_subtype, _charset)) self.replace_header('Content-Type', 'text/%s; charset="%s"' % (_subtype, _charset))
elif _charset is None: elif _charset is None:

View File

@ -1,9 +1,8 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import sys
from django.db import utils from django.db import utils
from django.db.backends.base.features import BaseDatabaseFeatures from django.db.backends.base.features import BaseDatabaseFeatures
from django.utils import six
from django.utils.functional import cached_property from django.utils.functional import cached_property
from .base import Database from .base import Database
@ -50,7 +49,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
@cached_property @cached_property
def can_share_in_memory_db(self): def can_share_in_memory_db(self):
return ( return (
sys.version_info[:2] >= (3, 4) and six.PY3 and
Database.__name__ == 'sqlite3.dbapi2' and Database.__name__ == 'sqlite3.dbapi2' and
Database.sqlite_version_info >= (3, 7, 13) Database.sqlite_version_info >= (3, 7, 13)
) )

View File

@ -3,11 +3,12 @@ import threading
import warnings import warnings
import weakref import weakref
from django.utils import six
from django.utils.deprecation import RemovedInDjango21Warning from django.utils.deprecation import RemovedInDjango21Warning
from django.utils.inspect import func_accepts_kwargs from django.utils.inspect import func_accepts_kwargs
from django.utils.six.moves import range from django.utils.six.moves import range
if sys.version_info < (3, 4): if six.PY2:
from .weakref_backports import WeakMethod from .weakref_backports import WeakMethod
else: else:
from weakref import WeakMethod from weakref import WeakMethod
@ -108,7 +109,7 @@ class Signal(object):
if hasattr(receiver, '__self__') and hasattr(receiver, '__func__'): if hasattr(receiver, '__self__') and hasattr(receiver, '__func__'):
ref = WeakMethod ref = WeakMethod
receiver_object = receiver.__self__ receiver_object = receiver.__self__
if sys.version_info >= (3, 4): if six.PY3:
receiver = ref(receiver) receiver = ref(receiver)
weakref.finalize(receiver_object, self._remove_receiver) weakref.finalize(receiver_object, self._remove_receiver)
else: else:

View File

@ -251,7 +251,7 @@ class LazyObject(object):
self._setup() self._setup()
return self._wrapped.__dict__ return self._wrapped.__dict__
# Python 3.3 will call __reduce__ when pickling; this method is needed # Python 3 will call __reduce__ when pickling; this method is needed
# to serialize and deserialize correctly. # to serialize and deserialize correctly.
@classmethod @classmethod
def __newobj__(cls, *args): def __newobj__(cls, *args):

View File

@ -7,26 +7,11 @@ from django.utils import six
# backport of Python 3.4's glob.escape # backport of Python 3.4's glob.escape
try: if six.PY3:
from glob import escape as glob_escape from glob import escape as glob_escape
except ImportError: else:
_magic_check = re.compile('([*?[])') _magic_check = re.compile('([*?[])')
if six.PY3:
_magic_check_bytes = re.compile(b'([*?[])')
def glob_escape(pathname):
"""
Escape all special characters.
"""
drive, pathname = os.path.splitdrive(pathname)
if isinstance(pathname, bytes):
pathname = _magic_check_bytes.sub(br'[\1]', pathname)
else:
pathname = _magic_check.sub(r'[\1]', pathname)
return drive + pathname
else:
def glob_escape(pathname): def glob_escape(pathname):
""" """
Escape all special characters. Escape all special characters.

View File

@ -1,6 +1,7 @@
import re import re
import sys import sys
from django.utils import six
from django.utils.six.moves import html_parser as _html_parser from django.utils.six.moves import html_parser as _html_parser
current_version = sys.version_info current_version = sys.version_info
@ -15,7 +16,7 @@ except AttributeError:
pass pass
if not use_workaround: if not use_workaround:
if current_version >= (3, 4): if six.PY3:
class HTMLParser(_html_parser.HTMLParser): class HTMLParser(_html_parser.HTMLParser):
"""Explicitly set convert_charrefs to be False. """Explicitly set convert_charrefs to be False.

View File

@ -63,11 +63,8 @@ def autodiscover_modules(*args, **kwargs):
raise raise
if sys.version_info[:2] >= (3, 3): if six.PY3:
if sys.version_info[:2] >= (3, 4):
from importlib.util import find_spec as importlib_find from importlib.util import find_spec as importlib_find
else:
from importlib import find_loader as importlib_find
def module_has_submodule(package, module_name): def module_has_submodule(package, module_name):
"""See if 'module' is in 'package'.""" """See if 'module' is in 'package'."""

View File

@ -16,9 +16,9 @@ How do I get started?
What are Django's prerequisites? What are Django's prerequisites?
-------------------------------- --------------------------------
Django requires Python, specifically Python 2.7 or 3.3 and above. Other Python Django requires Python. See the table in the next question for the versions of
libraries may be required for some uses, but you'll receive an error about it Python that work with each version of Django. Other Python libraries may be
as they're needed. required for some uses, but you'll receive an error about it as they're needed.
For a development environment -- if you just want to experiment with Django -- For a development environment -- if you just want to experiment with Django --
you don't need to have a separate Web server installed; Django comes with its you don't need to have a separate Web server installed; Django comes with its
@ -47,13 +47,19 @@ Django version Python versions
============== =============== ============== ===============
1.4 2.5, 2.6, 2.7 1.4 2.5, 2.6, 2.7
**1.7, 1.8** **2.7** and **3.2, 3.3, 3.4** **1.7, 1.8** **2.7** and **3.2, 3.3, 3.4**
1.9 2.7, 3.3, 3.4, 3.5 1.9 2.7, 3.4, 3.5
============== =============== ============== ===============
For each version of Python, only the latest micro release (A.B.C) is officially For each version of Python, only the latest micro release (A.B.C) is officially
supported. You can find the latest micro version for each series on the `Python supported. You can find the latest micro version for each series on the `Python
download page <https://www.python.org/downloads/>`_. download page <https://www.python.org/downloads/>`_.
Typically, we will support a Python version up to and including the first
Django LTS release that will receive security updates until after security
support for that version of Python ends. For example, Python 3.3 security
support ends September 2017 and Django 1.8 LTS security support ends April
2018. Therefore Django 1.8 is the last version to support Python 3.3.
What Python version should I use with Django? What Python version should I use with Django?
--------------------------------------------- ---------------------------------------------

View File

@ -21,8 +21,8 @@ Running the unit tests
Quickstart Quickstart
~~~~~~~~~~ ~~~~~~~~~~
If you are on Python < 3.3, you'll first need to install a backport of the If you are on Python 2, you'll first need to install a backport of the
``unittest.mock`` module that's available in Python 3.3+. See ``unittest.mock`` module that's available in Python 3. See
:ref:`running-unit-tests-dependencies` for details on installing `mock`_ and :ref:`running-unit-tests-dependencies` for details on installing `mock`_ and
the other optional test dependencies. the other optional test dependencies.

View File

@ -9,9 +9,9 @@ that'll work while you walk through the introduction.
Install Python Install Python
-------------- --------------
Being a Python Web framework, Django requires Python. It works with Python 2.7 Being a Python Web framework, Django requires Python. See
and Python 3.3+. All these versions of Python include a lightweight database called :ref:`faq-python-version-support` for details. Python includes a lightweight
SQLite_ so you won't need to set up a database just yet. database called SQLite_ so you won't need to set up a database just yet.
.. _sqlite: http://sqlite.org/ .. _sqlite: http://sqlite.org/

View File

@ -22,7 +22,7 @@ tell Django is installed and which version by running the following command:
If Django is installed, you should see the version of your installation. If it If Django is installed, you should see the version of your installation. If it
isn't, you'll get an error telling "No module named django". isn't, you'll get an error telling "No module named django".
This tutorial is written for Django |version| and Python 3.3 or later. If the This tutorial is written for Django |version| and Python 3.4 or later. If the
Django version doesn't match, you can refer to the tutorial for your version Django version doesn't match, you can refer to the tutorial for your version
of Django by using the version switcher at the bottom right corner of this of Django by using the version switcher at the bottom right corner of this
page, or update Django to the newest version. If you are still using Python page, or update Django to the newest version. If you are still using Python

View File

@ -20,7 +20,7 @@ Python compatibility
Like Django 1.8, Django 1.9 requires Python 2.7 or above, though we Like Django 1.8, Django 1.9 requires Python 2.7 or above, though we
**highly recommend** the latest minor release. We've dropped support for **highly recommend** the latest minor release. We've dropped support for
Python 3.2 and added support for Python 3.5. Python 3.2 and 3.3, and added support for Python 3.5.
What's new in Django 1.9 What's new in Django 1.9
======================== ========================

View File

@ -1,7 +1,6 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import os import os
import sys
import warnings import warnings
from unittest import skipUnless from unittest import skipUnless
@ -367,9 +366,7 @@ class AppConfigTests(SimpleTestCase):
AppConfig('label', Stub(__path__=['a', 'b'])) AppConfig('label', Stub(__path__=['a', 'b']))
@skipUnless( @skipUnless(six.PY3, "Namespace packages sans __init__.py were added in Python 3.3")
sys.version_info > (3, 3, 0),
"Namespace packages sans __init__.py were added in Python 3.3")
class NamespacePackageAppTests(SimpleTestCase): class NamespacePackageAppTests(SimpleTestCase):
# We need nsapp to be top-level so our multiple-paths tests can add another # We need nsapp to be top-level so our multiple-paths tests can add another
# location for it (if its inside a normal package with an __init__.py that # location for it (if its inside a normal package with an __init__.py that

View File

@ -353,7 +353,7 @@ class TestUtilsHashPass(SimpleTestCase):
def test_load_library_importerror(self): def test_load_library_importerror(self):
PlainHasher = type(str('PlainHasher'), (BasePasswordHasher,), PlainHasher = type(str('PlainHasher'), (BasePasswordHasher,),
{'algorithm': 'plain', 'library': 'plain'}) {'algorithm': 'plain', 'library': 'plain'})
# Python 3.3 adds quotes around module name # Python 3 adds quotes around module name
with six.assertRaisesRegex(self, ValueError, with six.assertRaisesRegex(self, ValueError,
"Couldn't load 'PlainHasher' algorithm library: No module named '?plain'?"): "Couldn't load 'PlainHasher' algorithm library: No module named '?plain'?"):
PlainHasher()._load_library() PlainHasher()._load_library()

View File

@ -843,7 +843,7 @@ class MakeMigrationsTests(MigrationTestBase):
content = cmd("0001", migration_name_0001) content = cmd("0001", migration_name_0001)
self.assertIn("dependencies=[\n]", content) self.assertIn("dependencies=[\n]", content)
# Python 3.3+ importlib caches os.listdir() on some platforms like # Python 3 importlib caches os.listdir() on some platforms like
# Mac OS X (#23850). # Mac OS X (#23850).
if hasattr(importlib, 'invalidate_caches'): if hasattr(importlib, 'invalidate_caches'):
importlib.invalidate_caches() importlib.invalidate_caches()

View File

@ -1,11 +1,11 @@
import sys
import unittest import unittest
from django.test import TestCase from django.test import TestCase
from django.utils import six
@unittest.skipIf(sys.version_info < (3, 3), @unittest.skipIf(six.PY2,
'Python < 3.3 cannot import the project template because ' 'Python 2 cannot import the project template because '
'django/conf/project_template doesn\'t have an __init__.py file.') 'django/conf/project_template doesn\'t have an __init__.py file.')
class TestStartProjectSettings(TestCase): class TestStartProjectSettings(TestCase):