Skip to content

Commit d170c63

Browse files
authored
Refs #23919 -- Removed misc references to Python 2.
1 parent c222122 commit d170c63

File tree

34 files changed

+40
-167
lines changed

34 files changed

+40
-167
lines changed

INSTALL

+1-8
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
Thanks for downloading Django.
22

3-
To install it, make sure you have Python 2.7 or greater installed. Then run
3+
To install it, make sure you have Python 3.4 or greater installed. Then run
44
this command from the command prompt:
55

66
python setup.py install
77

88
If you're upgrading from a previous version, you need to remove it first.
99

10-
AS AN ALTERNATIVE, you can just copy the entire "django" directory to Python's
11-
site-packages directory, which is located wherever your Python installation
12-
lives. Some places you might check are:
13-
14-
/usr/lib/python2.7/site-packages (Unix, Python 2.7)
15-
C:\\PYTHON\site-packages (Windows)
16-
1710
For more detailed instructions, see docs/intro/install.txt.

django/apps/config.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def __init__(self, app_name, app_module):
1717
self.name = app_name
1818

1919
# Root module for the application eg. <module 'django.contrib.admin'
20-
# from 'django/contrib/admin/__init__.pyc'>.
20+
# from 'django/contrib/admin/__init__.py'>.
2121
self.module = app_module
2222

2323
# Reference to the Apps registry that holds this AppConfig. Set by the
@@ -37,13 +37,12 @@ def __init__(self, app_name, app_module):
3737
self.verbose_name = self.label.title()
3838

3939
# Filesystem path to the application directory eg.
40-
# u'/usr/lib/python2.7/dist-packages/django/contrib/admin'. Unicode on
41-
# Python 2 and a str on Python 3.
40+
# '/path/to/django/contrib/admin'.
4241
if not hasattr(self, 'path'):
4342
self.path = self._path_from_module(app_module)
4443

4544
# Module containing models eg. <module 'django.contrib.admin.models'
46-
# from 'django/contrib/admin/models.pyc'>. Set by import_models().
45+
# from 'django/contrib/admin/models.py'>. Set by import_models().
4746
# None if the application doesn't have a models module.
4847
self.models_module = None
4948

django/conf/project_template/manage.py-tpl

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

django/contrib/gis/measure.py

-9
Original file line numberDiff line numberDiff line change
@@ -159,19 +159,13 @@ def __truediv__(self, other):
159159
else:
160160
raise TypeError('%(class)s must be divided with number or %(class)s' % {"class": pretty_name(self)})
161161

162-
def __div__(self, other): # Python 2 compatibility
163-
return type(self).__truediv__(self, other)
164-
165162
def __itruediv__(self, other):
166163
if isinstance(other, NUMERIC_TYPES):
167164
self.standard /= float(other)
168165
return self
169166
else:
170167
raise TypeError('%(class)s must be divided with number' % {"class": pretty_name(self)})
171168

172-
def __idiv__(self, other): # Python 2 compatibility
173-
return type(self).__itruediv__(self, other)
174-
175169
def __bool__(self):
176170
return bool(self.standard)
177171

@@ -333,9 +327,6 @@ def __truediv__(self, other):
333327
else:
334328
raise TypeError('%(class)s must be divided by a number' % {"class": pretty_name(self)})
335329

336-
def __div__(self, other): # Python 2 compatibility
337-
return type(self).__truediv__(self, other)
338-
339330

340331
# Shortcuts
341332
D = Distance

django/core/checks/model_checks.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def extract_operation(obj):
6464
operation, args, keywords = obj, [], {}
6565
while hasattr(operation, 'func'):
6666
# The or clauses are redundant but work around a bug (#25945) in
67-
# functools.partial in Python 3 <= 3.5.1 and Python 2 <= 2.7.11.
67+
# functools.partial in Python <= 3.5.1.
6868
args.extend(getattr(operation, 'args', []) or [])
6969
keywords.update(getattr(operation, 'keywords', {}) or {})
7070
operation = operation.func

django/core/files/temp.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
more general issue of opening a file for writing and reading in multiple
1010
processes in a manner that works across platforms.
1111
12-
Also note that the custom version of NamedTemporaryFile does not support the
13-
full range of keyword arguments available in Python 2.6+ and 3.0+.
12+
The custom version of NamedTemporaryFile doesn't support the same keyword
13+
arguments available in tempfile.NamedTemporaryFile.
1414
1515
1: https://mail.python.org/pipermail/python-list/2005-December/336957.html
1616
2: http://bugs.python.org/issue14243
@@ -30,10 +30,9 @@ class TemporaryFile(FileProxyMixin):
3030
Temporary file object constructor that supports reopening of the
3131
temporary file in Windows.
3232
33-
Note that unlike tempfile.NamedTemporaryFile from the standard library,
34-
__init__() does not support the 'delete' keyword argument in
35-
Python 2.6+, or the 'delete', 'buffering', 'encoding', or 'newline'
36-
keyword arguments in Python 3.0+.
33+
Unlike tempfile.NamedTemporaryFile from the standard library,
34+
__init__() doesn't support the 'delete', 'buffering', 'encoding', or
35+
'newline' keyword arguments.
3736
"""
3837
def __init__(self, mode='w+b', bufsize=-1, suffix='', prefix='', dir=None):
3938
fd, name = tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir)

django/core/servers/basehttp.py

-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ def handle_error(self, request, client_address):
8383
super(WSGIServer, self).handle_error(request, client_address)
8484

8585

86-
# Inheriting from object required on Python 2.
8786
class ServerHandler(simple_server.ServerHandler):
8887
def handle_error(self):
8988
# Ignore broken pipe errors, otherwise pass on

django/db/backends/mysql/base.py

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
MySQL database backend for Django.
33
44
Requires mysqlclient: https://pypi.python.org/pypi/mysqlclient/
5-
MySQLdb is supported for Python 2 only: http://sourceforge.net/projects/mysql-python
65
"""
76
import re
87
import sys

django/db/backends/oracle/introspection.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def get_table_description(self, cursor, table_name):
8181
self.cache_bust_counter))
8282
description = []
8383
for desc in cursor.description:
84-
name = force_text(desc[0]) # cx_Oracle always returns a 'str' on both Python 2 and 3
84+
name = force_text(desc[0]) # cx_Oracle always returns a 'str'
8585
internal_size, default = field_map[name]
8686
name = name % {} # cx_Oracle, for some reason, doubles percent signs.
8787
description.append(FieldInfo(*(name.lower(),) + desc[1:3] + (internal_size,) + desc[4:] + (default,)))

django/db/migrations/serializer.py

+3-13
Original file line numberDiff line numberDiff line change
@@ -160,24 +160,14 @@ def serialize(self):
160160
if "<" not in self.value.__qualname__: # Qualname can include <locals>
161161
return "%s.%s" % \
162162
(self.value.__module__, self.value.__qualname__), {"import %s" % self.value.__module__}
163-
# Python 2/fallback version
163+
# Fallback version
164164
module_name = self.value.__module__
165-
# Make sure it's actually there and not an unbound method
165+
# Make sure it's actually there
166166
module = import_module(module_name)
167167
if not hasattr(module, self.value.__name__):
168168
raise ValueError(
169-
"Could not find function %s in %s.\n"
170-
"Please note that due to Python 2 limitations, you cannot "
171-
"serialize unbound method functions (e.g. a method "
172-
"declared and used in the same class body). Please move "
173-
"the function into the main module body to use migrations.\n"
174-
"For more information, see "
175-
"https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values"
176-
% (self.value.__name__, module_name, get_docs_version())
169+
"Could not find function %s in %s.\n" % (self.value.__name__, module_name)
177170
)
178-
# Needed on Python 2 only
179-
if module_name == '__builtin__':
180-
return self.value.__name__, set()
181171
return "%s.%s" % (module_name, self.value.__name__), {"import %s" % module_name}
182172

183173

django/db/models/expressions.py

-6
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,6 @@ def __mul__(self, other):
6060
def __truediv__(self, other):
6161
return self._combine(other, self.DIV, False)
6262

63-
def __div__(self, other): # Python 2 compatibility
64-
return type(self).__truediv__(self, other)
65-
6663
def __mod__(self, other):
6764
return self._combine(other, self.MOD, False)
6865

@@ -103,9 +100,6 @@ def __rmul__(self, other):
103100
def __rtruediv__(self, other):
104101
return self._combine(other, self.DIV, True)
105102

106-
def __rdiv__(self, other): # Python 2 compatibility
107-
return type(self).__rtruediv__(self, other)
108-
109103
def __rmod__(self, other):
110104
return self._combine(other, self.MOD, True)
111105

django/db/models/query_utils.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,8 @@ class InvalidQuery(Exception):
2727

2828
def subclasses(cls):
2929
yield cls
30-
# Python 2 lacks 'yield from', which could replace the inner loop
3130
for subclass in cls.__subclasses__():
32-
# yield from subclasses(subclass)
33-
for item in subclasses(subclass):
34-
yield item
31+
yield from subclasses(subclass)
3532

3633

3734
class QueryWrapper:

django/db/models/sql/compiler.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -875,14 +875,8 @@ def execute_sql(self, result_type=MULTI, chunked_fetch=False):
875875
try:
876876
cursor.execute(sql, params)
877877
except Exception:
878-
try:
879-
# Might fail for server-side cursors (e.g. connection closed)
880-
cursor.close()
881-
except Exception:
882-
# Ignore clean up errors and raise the original error instead.
883-
# Python 2 doesn't chain exceptions. Remove this error
884-
# silencing when dropping Python 2 compatibility.
885-
pass
878+
# Might fail for server-side cursors (e.g. connection closed)
879+
cursor.close()
886880
raise
887881

888882
if result_type == CURSOR:

django/forms/utils.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22
import sys
3+
from collections import UserList
34

45
from django.conf import settings
56
from django.core.exceptions import ValidationError # backwards compatibility
@@ -8,11 +9,6 @@
89
from django.utils.html import escape, format_html, format_html_join, html_safe
910
from django.utils.translation import ugettext_lazy as _
1011

11-
try:
12-
from collections import UserList
13-
except ImportError: # Python 2
14-
from UserList import UserList
15-
1612

1713
def pretty_name(name):
1814
"""Converts 'first_name' to 'First name'"""

django/test/utils.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ def get_runner(settings, test_runner_class=None):
310310
test_runner_class = settings.TEST_RUNNER
311311

312312
test_path = test_runner_class.split('.')
313-
# Allow for Python 2.5 relative paths
313+
# Allow for relative paths
314314
if len(test_path) > 1:
315315
test_module_name = '.'.join(test_path[:-1])
316316
else:

django/utils/deconstruct.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def deconstruct(obj):
2424
Returns a 3-tuple of class import path, positional arguments,
2525
and keyword arguments.
2626
"""
27-
# Python 2/fallback version
27+
# Fallback version
2828
if path:
2929
module_name, _, name = path.rpartition('.')
3030
else:

django/utils/html.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,7 @@ def strip_tags(value):
172172
while '<' in value and '>' in value:
173173
new_value = _strip_once(value)
174174
if len(new_value) >= len(value):
175-
# _strip_once was not able to detect more tags or length increased
176-
# due to http://bugs.python.org/issue20288
177-
# (affects Python 2 < 2.7.7 and Python 3 < 3.3.5)
175+
# _strip_once was not able to detect more tags
178176
break
179177
value = new_value
180178
return value

django/utils/html_parser.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ class HTMLParseError(Exception):
1111
class HTMLParser(html.parser.HTMLParser):
1212
"""Explicitly set convert_charrefs to be False.
1313
14-
This silences a deprecation warning on Python 3.4, but we can't do
15-
it at call time because Python 2.7 does not have the keyword
16-
argument.
14+
This silences a deprecation warning on Python 3.4.
1715
"""
1816
def __init__(self, convert_charrefs=False, **kwargs):
1917
html.parser.HTMLParser.__init__(self, convert_charrefs=convert_charrefs, **kwargs)

django/utils/translation/trans_real.py

+1-8
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ def __init__(self, language, domain=None, localedirs=None):
101101
gettext_module.GNUTranslations.__init__(self)
102102
if domain is not None:
103103
self.domain = domain
104-
self.set_output_charset('utf-8') # For Python 2 gettext() (#25720)
105104

106105
self.__language = language
107106
self.__to_language = to_language(language)
@@ -326,11 +325,7 @@ def do_translate(message, translation_function):
326325

327326

328327
def gettext(message):
329-
"""
330-
Returns a string of the translation of the message.
331-
332-
Returns a string on Python 3 and an UTF-8-encoded bytestring on Python 2.
333-
"""
328+
"""Return a string of the translation of the message."""
334329
return do_translate(message, 'gettext')
335330

336331

@@ -372,8 +367,6 @@ def ngettext(singular, plural, number):
372367
"""
373368
Returns a string of the translation of either the singular or plural,
374369
based on the number.
375-
376-
Returns a string on Python 3 and an UTF-8-encoded bytestring on Python 2.
377370
"""
378371
return do_ntranslate(singular, plural, number, 'ngettext')
379372

docs/ref/applications.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,12 @@ Read-only attributes
206206
.. attribute:: AppConfig.module
207207

208208
Root module for the application, e.g. ``<module 'django.contrib.admin' from
209-
'django/contrib/admin/__init__.pyc'>``.
209+
'django/contrib/admin/__init__.py'>``.
210210

211211
.. attribute:: AppConfig.models_module
212212

213213
Module containing the models, e.g. ``<module 'django.contrib.admin.models'
214-
from 'django/contrib/admin/models.pyc'>``.
214+
from 'django/contrib/admin/models.py'>``.
215215

216216
It may be ``None`` if the application doesn't contain a ``models`` module.
217217
Note that the database related signals such as

tests/admin_changelist/tests.py

-4
Original file line numberDiff line numberDiff line change
@@ -568,10 +568,6 @@ def test_no_list_display_links(self):
568568
self.assertNotContains(response, '<a href="%s">' % link)
569569

570570
def test_tuple_list_display(self):
571-
"""
572-
Regression test for #17128
573-
(ChangeList failing under Python 2.5 after r16319)
574-
"""
575571
swallow = Swallow.objects.create(origin='Africa', load='12.34', speed='22.2')
576572
swallow2 = Swallow.objects.create(origin='Africa', load='12.34', speed='22.2')
577573
swallow_o2o = SwallowOneToOne.objects.create(swallow=swallow2)

tests/admin_scripts/tests.py

-3
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,6 @@ def remove_settings(self, filename, is_dir=False):
101101
if sys.platform.startswith('java'):
102102
# Jython produces module$py.class files
103103
os.remove(re.sub(r'\.py$', '$py.class', full_name))
104-
else:
105-
# CPython produces module.pyc files
106-
os.remove(full_name + 'c')
107104
except OSError:
108105
pass
109106
# Also remove a __pycache__ directory, if it exists

tests/admin_views/admin.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -971,8 +971,7 @@ def get_formsets_with_inlines(self, request, obj=None):
971971
# related ForeignKey object not registered in admin
972972
# related OneToOne object registered in admin
973973
# related OneToOne object not registered in admin
974-
# when deleting Book so as exercise all four troublesome (w.r.t escaping
975-
# and calling force_text to avoid problems on Python 2.3) paths through
974+
# when deleting Book so as exercise all four paths through
976975
# contrib.admin.utils's get_deleted_objects function.
977976
site.register(Book, inlines=[ChapterInline])
978977
site.register(Promo)

tests/auth_tests/test_context_processors.py

+1-15
Original file line numberDiff line numberDiff line change
@@ -130,21 +130,7 @@ def test_user_attrs(self):
130130
# bug #12037 is tested by the {% url %} in the template:
131131
self.assertContains(response, "url: /userpage/super/")
132132

133-
# See if this object can be used for queries where a Q() comparing
134-
# a user can be used with another Q() (in an AND or OR fashion).
135-
# This simulates what a template tag might do with the user from the
136-
# context. Note that we don't need to execute a query, just build it.
137-
#
138-
# The failure case (bug #12049) on Python 2.4 with a LazyObject-wrapped
139-
# User is a fatal TypeError: "function() takes at least 2 arguments
140-
# (0 given)" deep inside deepcopy().
141-
#
142-
# Python 2.5 and 2.6 succeeded, but logged internally caught exception
143-
# spew:
144-
#
145-
# Exception RuntimeError: 'maximum recursion depth exceeded while
146-
# calling a Python object' in <type 'exceptions.AttributeError'>
147-
# ignored"
133+
# A Q() comparing a user and with another Q() (in an AND or OR fashion).
148134
Q(user=response.context['user']) & Q(someflag=True)
149135

150136
# Tests for user equality. This is hard because User defines

0 commit comments

Comments
 (0)