Removed support for Python 3.3.
This commit is contained in:
parent
e5cb4e1411
commit
7f1168e387
@ -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:
|
||||||
|
@ -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,13 +169,7 @@ 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
|
self.set_payload(_text, utf8_charset)
|
||||||
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.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:
|
||||||
# the default value of '_charset' is 'us-ascii' on Python 2
|
# the default value of '_charset' is 'us-ascii' on Python 2
|
||||||
|
@ -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)
|
||||||
)
|
)
|
||||||
|
@ -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:
|
||||||
|
@ -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):
|
||||||
|
@ -7,30 +7,15 @@ 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:
|
def glob_escape(pathname):
|
||||||
_magic_check_bytes = re.compile(b'([*?[])')
|
"""
|
||||||
|
Escape all special characters.
|
||||||
def glob_escape(pathname):
|
"""
|
||||||
"""
|
drive, pathname = os.path.splitdrive(pathname)
|
||||||
Escape all special characters.
|
pathname = _magic_check.sub(r'[\1]', pathname)
|
||||||
"""
|
return drive + pathname
|
||||||
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):
|
|
||||||
"""
|
|
||||||
Escape all special characters.
|
|
||||||
"""
|
|
||||||
drive, pathname = os.path.splitdrive(pathname)
|
|
||||||
pathname = _magic_check.sub(r'[\1]', pathname)
|
|
||||||
return drive + pathname
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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'."""
|
||||||
|
@ -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?
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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/
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
========================
|
========================
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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):
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user