Refs #23919 -- Removed misc references to Python 2.

This commit is contained in:
Tim Graham 2017-01-21 20:02:00 -05:00 committed by GitHub
parent c22212220a
commit d170c63351
34 changed files with 40 additions and 167 deletions

View File

@ -1,17 +1,10 @@
Thanks for downloading Django.
To install it, make sure you have Python 2.7 or greater installed. Then run
To install it, make sure you have Python 3.4 or greater installed. Then run
this command from the command prompt:
python setup.py install
If you're upgrading from a previous version, you need to remove it first.
AS AN ALTERNATIVE, you can just copy the entire "django" directory to Python's
site-packages directory, which is located wherever your Python installation
lives. Some places you might check are:
/usr/lib/python2.7/site-packages (Unix, Python 2.7)
C:\\PYTHON\site-packages (Windows)
For more detailed instructions, see docs/intro/install.txt.

View File

@ -17,7 +17,7 @@ class AppConfig:
self.name = app_name
# Root module for the application eg. <module 'django.contrib.admin'
# from 'django/contrib/admin/__init__.pyc'>.
# from 'django/contrib/admin/__init__.py'>.
self.module = app_module
# Reference to the Apps registry that holds this AppConfig. Set by the
@ -37,13 +37,12 @@ class AppConfig:
self.verbose_name = self.label.title()
# Filesystem path to the application directory eg.
# u'/usr/lib/python2.7/dist-packages/django/contrib/admin'. Unicode on
# Python 2 and a str on Python 3.
# '/path/to/django/contrib/admin'.
if not hasattr(self, 'path'):
self.path = self._path_from_module(app_module)
# Module containing models eg. <module 'django.contrib.admin.models'
# from 'django/contrib/admin/models.pyc'>. Set by import_models().
# from 'django/contrib/admin/models.py'>. Set by import_models().
# None if the application doesn't have a models module.
self.models_module = None

View File

@ -6,17 +6,10 @@ if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings")
try:
from django.core.management import execute_from_command_line
except ImportError:
# The above import may fail for some other reason. Ensure that the
# issue is really that Django is missing to avoid masking other
# exceptions on Python 2.
try:
import django
except ImportError:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
)
raise
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)

View File

@ -159,9 +159,6 @@ class MeasureBase:
else:
raise TypeError('%(class)s must be divided with number or %(class)s' % {"class": pretty_name(self)})
def __div__(self, other): # Python 2 compatibility
return type(self).__truediv__(self, other)
def __itruediv__(self, other):
if isinstance(other, NUMERIC_TYPES):
self.standard /= float(other)
@ -169,9 +166,6 @@ class MeasureBase:
else:
raise TypeError('%(class)s must be divided with number' % {"class": pretty_name(self)})
def __idiv__(self, other): # Python 2 compatibility
return type(self).__itruediv__(self, other)
def __bool__(self):
return bool(self.standard)
@ -333,9 +327,6 @@ class Area(MeasureBase):
else:
raise TypeError('%(class)s must be divided by a number' % {"class": pretty_name(self)})
def __div__(self, other): # Python 2 compatibility
return type(self).__truediv__(self, other)
# Shortcuts
D = Distance

View File

@ -64,7 +64,7 @@ def _check_lazy_references(apps, ignore=None):
operation, args, keywords = obj, [], {}
while hasattr(operation, 'func'):
# The or clauses are redundant but work around a bug (#25945) in
# functools.partial in Python 3 <= 3.5.1 and Python 2 <= 2.7.11.
# functools.partial in Python <= 3.5.1.
args.extend(getattr(operation, 'args', []) or [])
keywords.update(getattr(operation, 'keywords', {}) or {})
operation = operation.func

View File

@ -9,8 +9,8 @@ if the same flag is not provided [1][2]. Note that this does not address the
more general issue of opening a file for writing and reading in multiple
processes in a manner that works across platforms.
Also note that the custom version of NamedTemporaryFile does not support the
full range of keyword arguments available in Python 2.6+ and 3.0+.
The custom version of NamedTemporaryFile doesn't support the same keyword
arguments available in tempfile.NamedTemporaryFile.
1: https://mail.python.org/pipermail/python-list/2005-December/336957.html
2: http://bugs.python.org/issue14243
@ -30,10 +30,9 @@ if os.name == 'nt':
Temporary file object constructor that supports reopening of the
temporary file in Windows.
Note that unlike tempfile.NamedTemporaryFile from the standard library,
__init__() does not support the 'delete' keyword argument in
Python 2.6+, or the 'delete', 'buffering', 'encoding', or 'newline'
keyword arguments in Python 3.0+.
Unlike tempfile.NamedTemporaryFile from the standard library,
__init__() doesn't support the 'delete', 'buffering', 'encoding', or
'newline' keyword arguments.
"""
def __init__(self, mode='w+b', bufsize=-1, suffix='', prefix='', dir=None):
fd, name = tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir)

View File

@ -83,7 +83,6 @@ class WSGIServer(simple_server.WSGIServer):
super(WSGIServer, self).handle_error(request, client_address)
# Inheriting from object required on Python 2.
class ServerHandler(simple_server.ServerHandler):
def handle_error(self):
# Ignore broken pipe errors, otherwise pass on

View File

@ -2,7 +2,6 @@
MySQL database backend for Django.
Requires mysqlclient: https://pypi.python.org/pypi/mysqlclient/
MySQLdb is supported for Python 2 only: http://sourceforge.net/projects/mysql-python
"""
import re
import sys

View File

@ -81,7 +81,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
self.cache_bust_counter))
description = []
for desc in cursor.description:
name = force_text(desc[0]) # cx_Oracle always returns a 'str' on both Python 2 and 3
name = force_text(desc[0]) # cx_Oracle always returns a 'str'
internal_size, default = field_map[name]
name = name % {} # cx_Oracle, for some reason, doubles percent signs.
description.append(FieldInfo(*(name.lower(),) + desc[1:3] + (internal_size,) + desc[4:] + (default,)))

View File

@ -160,24 +160,14 @@ class FunctionTypeSerializer(BaseSerializer):
if "<" not in self.value.__qualname__: # Qualname can include <locals>
return "%s.%s" % \
(self.value.__module__, self.value.__qualname__), {"import %s" % self.value.__module__}
# Python 2/fallback version
# Fallback version
module_name = self.value.__module__
# Make sure it's actually there and not an unbound method
# Make sure it's actually there
module = import_module(module_name)
if not hasattr(module, self.value.__name__):
raise ValueError(
"Could not find function %s in %s.\n"
"Please note that due to Python 2 limitations, you cannot "
"serialize unbound method functions (e.g. a method "
"declared and used in the same class body). Please move "
"the function into the main module body to use migrations.\n"
"For more information, see "
"https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values"
% (self.value.__name__, module_name, get_docs_version())
"Could not find function %s in %s.\n" % (self.value.__name__, module_name)
)
# Needed on Python 2 only
if module_name == '__builtin__':
return self.value.__name__, set()
return "%s.%s" % (module_name, self.value.__name__), {"import %s" % module_name}

View File

@ -60,9 +60,6 @@ class Combinable:
def __truediv__(self, other):
return self._combine(other, self.DIV, False)
def __div__(self, other): # Python 2 compatibility
return type(self).__truediv__(self, other)
def __mod__(self, other):
return self._combine(other, self.MOD, False)
@ -103,9 +100,6 @@ class Combinable:
def __rtruediv__(self, other):
return self._combine(other, self.DIV, True)
def __rdiv__(self, other): # Python 2 compatibility
return type(self).__rtruediv__(self, other)
def __rmod__(self, other):
return self._combine(other, self.MOD, True)

View File

@ -27,11 +27,8 @@ class InvalidQuery(Exception):
def subclasses(cls):
yield cls
# Python 2 lacks 'yield from', which could replace the inner loop
for subclass in cls.__subclasses__():
# yield from subclasses(subclass)
for item in subclasses(subclass):
yield item
yield from subclasses(subclass)
class QueryWrapper:

View File

@ -875,14 +875,8 @@ class SQLCompiler:
try:
cursor.execute(sql, params)
except Exception:
try:
# Might fail for server-side cursors (e.g. connection closed)
cursor.close()
except Exception:
# Ignore clean up errors and raise the original error instead.
# Python 2 doesn't chain exceptions. Remove this error
# silencing when dropping Python 2 compatibility.
pass
# Might fail for server-side cursors (e.g. connection closed)
cursor.close()
raise
if result_type == CURSOR:

View File

@ -1,5 +1,6 @@
import json
import sys
from collections import UserList
from django.conf import settings
from django.core.exceptions import ValidationError # backwards compatibility
@ -8,11 +9,6 @@ from django.utils.encoding import force_text
from django.utils.html import escape, format_html, format_html_join, html_safe
from django.utils.translation import ugettext_lazy as _
try:
from collections import UserList
except ImportError: # Python 2
from UserList import UserList
def pretty_name(name):
"""Converts 'first_name' to 'First name'"""

View File

@ -310,7 +310,7 @@ def get_runner(settings, test_runner_class=None):
test_runner_class = settings.TEST_RUNNER
test_path = test_runner_class.split('.')
# Allow for Python 2.5 relative paths
# Allow for relative paths
if len(test_path) > 1:
test_module_name = '.'.join(test_path[:-1])
else:

View File

@ -24,7 +24,7 @@ def deconstructible(*args, **kwargs):
Returns a 3-tuple of class import path, positional arguments,
and keyword arguments.
"""
# Python 2/fallback version
# Fallback version
if path:
module_name, _, name = path.rpartition('.')
else:

View File

@ -172,9 +172,7 @@ def strip_tags(value):
while '<' in value and '>' in value:
new_value = _strip_once(value)
if len(new_value) >= len(value):
# _strip_once was not able to detect more tags or length increased
# due to http://bugs.python.org/issue20288
# (affects Python 2 < 2.7.7 and Python 3 < 3.3.5)
# _strip_once was not able to detect more tags
break
value = new_value
return value

View File

@ -11,9 +11,7 @@ except AttributeError:
class HTMLParser(html.parser.HTMLParser):
"""Explicitly set convert_charrefs to be False.
This silences a deprecation warning on Python 3.4, but we can't do
it at call time because Python 2.7 does not have the keyword
argument.
This silences a deprecation warning on Python 3.4.
"""
def __init__(self, convert_charrefs=False, **kwargs):
html.parser.HTMLParser.__init__(self, convert_charrefs=convert_charrefs, **kwargs)

View File

@ -101,7 +101,6 @@ class DjangoTranslation(gettext_module.GNUTranslations):
gettext_module.GNUTranslations.__init__(self)
if domain is not None:
self.domain = domain
self.set_output_charset('utf-8') # For Python 2 gettext() (#25720)
self.__language = language
self.__to_language = to_language(language)
@ -326,11 +325,7 @@ def do_translate(message, translation_function):
def gettext(message):
"""
Returns a string of the translation of the message.
Returns a string on Python 3 and an UTF-8-encoded bytestring on Python 2.
"""
"""Return a string of the translation of the message."""
return do_translate(message, 'gettext')
@ -372,8 +367,6 @@ def ngettext(singular, plural, number):
"""
Returns a string of the translation of either the singular or plural,
based on the number.
Returns a string on Python 3 and an UTF-8-encoded bytestring on Python 2.
"""
return do_ntranslate(singular, plural, number, 'ngettext')

View File

@ -206,12 +206,12 @@ Read-only attributes
.. attribute:: AppConfig.module
Root module for the application, e.g. ``<module 'django.contrib.admin' from
'django/contrib/admin/__init__.pyc'>``.
'django/contrib/admin/__init__.py'>``.
.. attribute:: AppConfig.models_module
Module containing the models, e.g. ``<module 'django.contrib.admin.models'
from 'django/contrib/admin/models.pyc'>``.
from 'django/contrib/admin/models.py'>``.
It may be ``None`` if the application doesn't contain a ``models`` module.
Note that the database related signals such as

View File

@ -568,10 +568,6 @@ class ChangeListTests(TestCase):
self.assertNotContains(response, '<a href="%s">' % link)
def test_tuple_list_display(self):
"""
Regression test for #17128
(ChangeList failing under Python 2.5 after r16319)
"""
swallow = Swallow.objects.create(origin='Africa', load='12.34', speed='22.2')
swallow2 = Swallow.objects.create(origin='Africa', load='12.34', speed='22.2')
swallow_o2o = SwallowOneToOne.objects.create(swallow=swallow2)

View File

@ -101,9 +101,6 @@ class AdminScriptTestCase(unittest.TestCase):
if sys.platform.startswith('java'):
# Jython produces module$py.class files
os.remove(re.sub(r'\.py$', '$py.class', full_name))
else:
# CPython produces module.pyc files
os.remove(full_name + 'c')
except OSError:
pass
# Also remove a __pycache__ directory, if it exists

View File

@ -971,8 +971,7 @@ site.register(RelatedWithUUIDPKModel)
# related ForeignKey object not registered in admin
# related OneToOne object registered in admin
# related OneToOne object not registered in admin
# when deleting Book so as exercise all four troublesome (w.r.t escaping
# and calling force_text to avoid problems on Python 2.3) paths through
# when deleting Book so as exercise all four paths through
# contrib.admin.utils's get_deleted_objects function.
site.register(Book, inlines=[ChapterInline])
site.register(Promo)

View File

@ -130,21 +130,7 @@ class AuthContextProcessorTests(TestCase):
# bug #12037 is tested by the {% url %} in the template:
self.assertContains(response, "url: /userpage/super/")
# See if this object can be used for queries where a Q() comparing
# a user can be used with another Q() (in an AND or OR fashion).
# This simulates what a template tag might do with the user from the
# context. Note that we don't need to execute a query, just build it.
#
# The failure case (bug #12049) on Python 2.4 with a LazyObject-wrapped
# User is a fatal TypeError: "function() takes at least 2 arguments
# (0 given)" deep inside deepcopy().
#
# Python 2.5 and 2.6 succeeded, but logged internally caught exception
# spew:
#
# Exception RuntimeError: 'maximum recursion depth exceeded while
# calling a Python object' in <type 'exceptions.AttributeError'>
# ignored"
# A Q() comparing a user and with another Q() (in an AND or OR fashion).
Q(user=response.context['user']) & Q(someflag=True)
# Tests for user equality. This is hard because User defines

View File

@ -62,11 +62,6 @@ class Unpicklable:
raise pickle.PickleError()
class UnpicklableType:
# Unpicklable using the default pickling protocol on Python 2.
__slots__ = 'a',
@override_settings(CACHES={
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
@ -1360,10 +1355,6 @@ class FileBasedCacheTests(BaseCacheTests, TestCase):
cache.set('foo', 'bar')
os.path.exists(self.dirname)
def test_cache_write_unpicklable_type(self):
# This fails if not using the highest pickling protocol on Python 2.
cache.set('unpicklable', UnpicklableType())
def test_get_ignores_enoent(self):
cache.set('foo', 'bar')
os.unlink(cache._key_to_file('foo'))

View File

@ -256,8 +256,8 @@ class MethodDecoratorTests(SimpleTestCase):
def test_bad_iterable(self):
decorators = {myattr_dec_m, myattr2_dec_m}
# The rest of the exception message differs between Python 2 and 3.
with self.assertRaisesMessage(TypeError, "'set' object"):
msg = "'set' object is not subscriptable"
with self.assertRaisesMessage(TypeError, msg):
@method_decorator(decorators, "method")
class TestIterable:
def method(self):

View File

@ -637,8 +637,6 @@ class CaseExpressionTests(TestCase):
def test_update_binary(self):
CaseTestModel.objects.update(
binary=Case(
# fails on postgresql on Python 2.7 if output_field is not
# set explicitly
When(integer=1, then=Value(b'one', output_field=models.BinaryField())),
When(integer=2, then=Value(b'two', output_field=models.BinaryField())),
default=Value(b'', output_field=models.BinaryField()),

View File

@ -139,9 +139,6 @@ class FileTests(unittest.TestCase):
test_file.seek(0)
wrapper = TextIOWrapper(test_file, 'utf-8', newline='\n')
self.assertEqual(wrapper.read(), content)
# The following seek() call is required on Windows Python 2 when
# switching from reading to writing.
wrapper.seek(0, 2)
wrapper.write(content)
wrapper.seek(0)
self.assertEqual(wrapper.read(), content * 2)

View File

@ -21,8 +21,7 @@ from django.template import Context, Template
from django.test import SimpleTestCase
from django.utils.datastructures import MultiValueDict
from django.utils.encoding import force_text
from django.utils.html import format_html
from django.utils.safestring import SafeData, mark_safe
from django.utils.safestring import mark_safe
class Person(Form):
@ -2028,22 +2027,6 @@ Password: <input type="password" name="password" required /></li>
form = PersonForm({})
self.assertEqual(form['name'].value(), 'John Doe')
def test_boundfield_rendering(self):
"""
Python 2 issue: Rendering a BoundField with bytestring content
doesn't lose it's safe string status (#22950).
"""
class CustomWidget(TextInput):
def render(self, name, value, attrs=None, choices=None,
renderer=None, extra_context=None):
return format_html(str('<input{} />'), ' id=custom')
class SampleForm(Form):
name = CharField(widget=CustomWidget)
f = SampleForm(data={'name': 'bar'})
self.assertIsInstance(force_text(f['name']), SafeData)
def test_custom_boundfield(self):
class CustomField(CharField):
def get_bound_field(self, form, name):

View File

@ -7,7 +7,7 @@ source_code_dir = os.path.dirname(__file__)
def copytree(src, dst):
shutil.copytree(src, dst, ignore=shutil.ignore_patterns('*.pyc', '__pycache__'))
shutil.copytree(src, dst, ignore=shutil.ignore_patterns('__pycache__'))
class POFileAssertionMixin:

View File

@ -1,7 +1,6 @@
from django.db.models import F, IntegerField, Value
from django.db.utils import DatabaseError
from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
from django.utils.six.moves import range
from .models import Number, ReservedName

View File

@ -305,8 +305,7 @@ class TestComplexSettingOverride(SimpleTestCase):
self.assertEqual(settings.TEST_WARN, 'override')
self.assertEqual(len(w), 1)
# File extension may by .py, .pyc, etc. Compare only basename.
self.assertEqual(os.path.splitext(w[0].filename)[0], os.path.splitext(__file__)[0])
self.assertEqual(w[0].filename, __file__)
self.assertEqual(str(w[0].message), 'Overriding setting TEST_WARN can lead to unexpected behavior.')

View File

@ -164,7 +164,7 @@ class SilentAttrClass:
class UTF8Class:
"Class whose __str__ returns non-ASCII data on Python 2"
"Class whose __str__ returns non-ASCII data"
def __str__(self):
return 'ŠĐĆŽćžšđ'

View File

@ -7,15 +7,10 @@ from django.utils.functional import SimpleLazyObject
class TestUtilsSimpleLazyObjectDjangoTestCase(TestCase):
def test_pickle_py2_regression(self):
# See ticket #20212
def test_pickle(self):
user = User.objects.create_user('johndoe', 'john@example.com', 'pass')
x = SimpleLazyObject(lambda: user)
# This would fail with "TypeError: can't pickle instancemethod objects",
# only on Python 2.X.
pickle.dumps(x)
# Try the variant protocol levels.
pickle.dumps(x, 0)
pickle.dumps(x, 1)