From f32feaa9010c8cb30e69469aa458714569e14e2d Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 30 Dec 2016 17:20:55 -0500 Subject: [PATCH 0001/3180] Bumped version; master is now 2.0 pre-alpha. --- django/__init__.py | 2 +- docs/conf.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/django/__init__.py b/django/__init__.py index 1584f27d4b39..ab50cac6242e 100644 --- a/django/__init__.py +++ b/django/__init__.py @@ -2,7 +2,7 @@ from django.utils.version import get_version -VERSION = (1, 11, 0, 'alpha', 0) +VERSION = (2, 0, 0, 'alpha', 0) __version__ = get_version(VERSION) diff --git a/docs/conf.py b/docs/conf.py index 5cba4e50bae8..1643559a1dc0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -81,7 +81,7 @@ # built documents. # # The short X.Y version. -version = '1.11' +version = '2.0' # The full version, including alpha/beta/rc tags. try: from django import VERSION, get_version @@ -97,7 +97,7 @@ def django_release(): release = django_release() # The "development version" of Django -django_next_version = '1.11' +django_next_version = '2.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. From e8dac72a553a0deedfef6ae90495d89d9bc089c8 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 7 Nov 2016 15:03:37 -0500 Subject: [PATCH 0002/3180] Added stub 2.0 release notes. --- docs/releases/2.0.txt | 235 ++++++++++++++++++++++++++++++++++++++++ docs/releases/index.txt | 6 + 2 files changed, 241 insertions(+) create mode 100644 docs/releases/2.0.txt diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt new file mode 100644 index 000000000000..738f48845653 --- /dev/null +++ b/docs/releases/2.0.txt @@ -0,0 +1,235 @@ +============================================ +Django 2.0 release notes - UNDER DEVELOPMENT +============================================ + +Welcome to Django 2.0! + +These release notes cover the :ref:`new features `, as well as +some :ref:`backwards incompatible changes ` you'll +want to be aware of when upgrading from Django 1.11 or earlier. We've +:ref:`dropped some features` that have reached the end of +their deprecation cycle, and we've :ref:`begun the deprecation process for some +features `. + +See the :doc:`/howto/upgrade-version` guide if you're updating an existing +project. + +Python compatibility +==================== + +Django 2.0 supports Python 3.5+. Since Django 1.11, support for Python 2.7 and +3.4 is removed. We **highly recommend** and only officially support the latest +release of each series. + +Third-party library support for older version of Django +======================================================= + +Following the release of Django 2.0, we suggest that third-party app authors +drop support for all versions of Django prior to 1.11. At that time, you should +be able run your package's tests using ``python -Wd`` so that deprecation +warnings do appear. After making the deprecation warning fixes, your app should +be compatible with Django 2.0. + +.. _whats-new-2.0: + +What's new in Django 2.0 +======================== + +Minor features +-------------- + +:mod:`django.contrib.admin` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.admindocs` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.auth` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.contenttypes` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.gis` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.messages` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.postgres` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.redirects` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.sessions` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.sitemaps` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.sites` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.staticfiles` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +:mod:`django.contrib.syndication` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +Cache +~~~~~ + +* ... + +CSRF +~~~~ + +* ... + +Database backends +~~~~~~~~~~~~~~~~~ + +* ... + +Email +~~~~~ + +* ... + +File Storage +~~~~~~~~~~~~ + +* ... + +File Uploads +~~~~~~~~~~~~ + +* ... + + +Forms +~~~~~ + +* ... + +Generic Views +~~~~~~~~~~~~~ + +* ... + +Internationalization +~~~~~~~~~~~~~~~~~~~~ + +* ... + +Management Commands +~~~~~~~~~~~~~~~~~~~ + +* ... + +Migrations +~~~~~~~~~~ + +* ... + +Models +~~~~~~ + +* ... + +Requests and Responses +~~~~~~~~~~~~~~~~~~~~~~ + +* ... + +Serialization +~~~~~~~~~~~~~ + +* ... + +Signals +~~~~~~~ + +* ... + +Templates +~~~~~~~~~ + +* ... + +Tests +~~~~~ + +* ... + +URLs +~~~~ + +* ... + +Validators +~~~~~~~~~~ + +* ... + +.. _backwards-incompatible-2.0: + +Backwards incompatible changes in 2.0 +===================================== + +Database backend API +-------------------- + +* ... + +Miscellaneous +------------- + +* ... + +.. _deprecated-features-2.0: + +Features deprecated in 2.0 +========================== + +Miscellaneous +------------- + +* ... + +.. _removed-features-2.0: + +Features removed in 2.0 +======================= + +These features have reached the end of their deprecation cycle and are removed +in Django 2.0. See :ref:`deprecated-features-1.9` and +:ref:`deprecated-features-1.10` for details, including how to remove usage of +these features. diff --git a/docs/releases/index.txt b/docs/releases/index.txt index a4aecfcbd252..237d526c5b23 100644 --- a/docs/releases/index.txt +++ b/docs/releases/index.txt @@ -20,6 +20,12 @@ versions of the documentation contain the release notes for any later releases. .. _development_release_notes: +2.0 release +----------- +.. toctree:: + :maxdepth: 1 + + 2.0 1.11 release ------------ From 03087f80d14969ebfc7b81f54096941c60c9b52b Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 7 Nov 2016 14:46:42 +0000 Subject: [PATCH 0003/3180] Refs #24205 -- Removed Signal.disconnect()'s weak argument. Per deprecation timeline. --- django/db/models/signals.py | 6 +----- django/dispatch/dispatcher.py | 6 +----- docs/releases/2.0.txt | 3 +++ docs/topics/signals.txt | 5 ----- tests/dispatch/test_removedindjango20.py | 24 ------------------------ 5 files changed, 5 insertions(+), 39 deletions(-) delete mode 100644 tests/dispatch/test_removedindjango20.py diff --git a/django/db/models/signals.py b/django/db/models/signals.py index 5047f11743db..9f9fbccde3d8 100644 --- a/django/db/models/signals.py +++ b/django/db/models/signals.py @@ -1,10 +1,8 @@ -import warnings from functools import partial from django.db.models.utils import make_model_tuple from django.dispatch import Signal from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning class_prepared = Signal(providing_args=["class"]) @@ -32,9 +30,7 @@ def connect(self, receiver, sender=None, weak=True, dispatch_uid=None, apps=None weak=weak, dispatch_uid=dispatch_uid, ) - def disconnect(self, receiver=None, sender=None, weak=None, dispatch_uid=None, apps=None): - if weak is not None: - warnings.warn("Passing `weak` to disconnect has no effect.", RemovedInDjango20Warning, stacklevel=2) + def disconnect(self, receiver=None, sender=None, dispatch_uid=None, apps=None): return self._lazy_method( super(ModelSignal, self).disconnect, apps, receiver, sender, dispatch_uid=dispatch_uid ) diff --git a/django/dispatch/dispatcher.py b/django/dispatch/dispatcher.py index 742acd198b79..db2f6839f8b9 100644 --- a/django/dispatch/dispatcher.py +++ b/django/dispatch/dispatcher.py @@ -1,10 +1,8 @@ import sys import threading -import warnings import weakref from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.inspect import func_accepts_kwargs from django.utils.six.moves import range @@ -126,7 +124,7 @@ def connect(self, receiver, sender=None, weak=True, dispatch_uid=None): self.receivers.append((lookup_key, receiver)) self.sender_receivers_cache.clear() - def disconnect(self, receiver=None, sender=None, weak=None, dispatch_uid=None): + def disconnect(self, receiver=None, sender=None, dispatch_uid=None): """ Disconnect receiver from sender for signal. @@ -145,8 +143,6 @@ def disconnect(self, receiver=None, sender=None, weak=None, dispatch_uid=None): dispatch_uid the unique identifier of the receiver to disconnect """ - if weak is not None: - warnings.warn("Passing `weak` to disconnect has no effect.", RemovedInDjango20Warning, stacklevel=2) if dispatch_uid: lookup_key = (dispatch_uid, _make_id(sender)) else: diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 738f48845653..ebd808901505 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -233,3 +233,6 @@ These features have reached the end of their deprecation cycle and are removed in Django 2.0. See :ref:`deprecated-features-1.9` and :ref:`deprecated-features-1.10` for details, including how to remove usage of these features. + +* The ``weak`` argument to ``django.dispatch.signals.Signal.disconnect()`` is + removed. diff --git a/docs/topics/signals.txt b/docs/topics/signals.txt index 19c0cd3d33e2..ad2b66f6df94 100644 --- a/docs/topics/signals.txt +++ b/docs/topics/signals.txt @@ -277,8 +277,3 @@ arguments are as described in :meth:`.Signal.connect`. The method returns The ``receiver`` argument indicates the registered receiver to disconnect. It may be ``None`` if ``dispatch_uid`` is used to identify the receiver. - -.. deprecated:: 1.9 - - The ``weak`` argument is deprecated as it has no effect. It will be removed - in Django 2.0. diff --git a/tests/dispatch/test_removedindjango20.py b/tests/dispatch/test_removedindjango20.py deleted file mode 100644 index 9b28cf789d71..000000000000 --- a/tests/dispatch/test_removedindjango20.py +++ /dev/null @@ -1,24 +0,0 @@ -import warnings - -from django.dispatch import Signal -from django.test import SimpleTestCase - -a_signal = Signal(providing_args=['val']) - - -def receiver_1_arg(val, **kwargs): - return val - - -class DispatcherTests(SimpleTestCase): - - def test_disconnect_weak_deprecated(self): - a_signal.connect(receiver_1_arg) - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') - a_signal.disconnect(receiver_1_arg, weak=True) - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - 'Passing `weak` to disconnect has no effect.', - ) From a3bd8672d87466649e5f5b0fa27634d1800a29a7 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 14:11:52 -0500 Subject: [PATCH 0004/3180] Refs #24154 -- Removed deprecated BaseDatabaseOperations.check_aggregate_support(). --- django/db/backends/base/operations.py | 9 --------- docs/releases/2.0.txt | 3 +++ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/django/db/backends/base/operations.py b/django/db/backends/base/operations.py index efa1a0b45750..f46ac955badd 100644 --- a/django/db/backends/base/operations.py +++ b/django/db/backends/base/operations.py @@ -1,6 +1,5 @@ import datetime import decimal -import warnings from importlib import import_module from django.conf import settings @@ -8,7 +7,6 @@ from django.db.backends import utils from django.utils import six, timezone from django.utils.dateparse import parse_duration -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text @@ -556,13 +554,6 @@ def convert_durationfield_value(self, value, expression, connection, context): value = parse_duration(value) return value - def check_aggregate_support(self, aggregate_func): - warnings.warn( - "check_aggregate_support has been deprecated. Use " - "check_expression_support instead.", - RemovedInDjango20Warning, stacklevel=2) - return self.check_expression_support(aggregate_func) - def check_expression_support(self, expression): """ Check that the backend supports the provided expression. diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index ebd808901505..462e86ad3fa1 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -236,3 +236,6 @@ these features. * The ``weak`` argument to ``django.dispatch.signals.Signal.disconnect()`` is removed. + +* ``django.db.backends.base.BaseDatabaseOperations.check_aggregate_support()`` + is removed. From 742d666da57b52a3b00aa9b1c527ece829e95245 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 7 Nov 2016 16:28:13 -0500 Subject: [PATCH 0005/3180] Refs #24219 -- Removed django.forms.extras per deprecation timeline. --- django/forms/extras/__init__.py | 12 ------------ django/forms/extras/widgets.py | 1 - docs/releases/2.0.txt | 2 ++ tests/forms_tests/field_tests/test_filepathfield.py | 2 -- tests/runtests.py | 5 ----- 5 files changed, 2 insertions(+), 20 deletions(-) delete mode 100644 django/forms/extras/__init__.py delete mode 100644 django/forms/extras/widgets.py diff --git a/django/forms/extras/__init__.py b/django/forms/extras/__init__.py deleted file mode 100644 index e1c8455f202f..000000000000 --- a/django/forms/extras/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -import warnings - -from django.forms.widgets import SelectDateWidget -from django.utils.deprecation import RemovedInDjango20Warning - -__all__ = ['SelectDateWidget'] - - -warnings.warn( - "django.forms.extras is deprecated. You can find " - "SelectDateWidget in django.forms.widgets instead.", - RemovedInDjango20Warning, stacklevel=2) diff --git a/django/forms/extras/widgets.py b/django/forms/extras/widgets.py deleted file mode 100644 index e53cb4069edb..000000000000 --- a/django/forms/extras/widgets.py +++ /dev/null @@ -1 +0,0 @@ -from django.forms.widgets import SelectDateWidget # NOQA diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 462e86ad3fa1..97e59ca26fc0 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -239,3 +239,5 @@ these features. * ``django.db.backends.base.BaseDatabaseOperations.check_aggregate_support()`` is removed. + +* The ``django.forms.extras`` package is removed. diff --git a/tests/forms_tests/field_tests/test_filepathfield.py b/tests/forms_tests/field_tests/test_filepathfield.py index d518e65db150..60336d0dcf1c 100644 --- a/tests/forms_tests/field_tests/test_filepathfield.py +++ b/tests/forms_tests/field_tests/test_filepathfield.py @@ -79,8 +79,6 @@ def test_filepathfield_4(self): expected = [ ('/django/forms/__init__.py', '__init__.py'), ('/django/forms/boundfield.py', 'boundfield.py'), - ('/django/forms/extras/__init__.py', 'extras/__init__.py'), - ('/django/forms/extras/widgets.py', 'extras/widgets.py'), ('/django/forms/fields.py', 'fields.py'), ('/django/forms/forms.py', 'forms.py'), ('/django/forms/formsets.py', 'formsets.py'), diff --git a/tests/runtests.py b/tests/runtests.py index dbd13e3d0f42..59f90646aaac 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -173,11 +173,6 @@ def no_available_apps(self): 'The GeoManager class is deprecated.', RemovedInDjango20Warning ) - warnings.filterwarnings( - 'ignore', - 'django.forms.extras is deprecated.', - RemovedInDjango20Warning - ) # Load all the ALWAYS_INSTALLED_APPS. django.setup() From f032bbc8b107ab9274542f8d233fc88aa1c6e04d Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 7 Nov 2016 18:19:34 -0500 Subject: [PATCH 0006/3180] Refs #18651 -- Removed assignment_tag per deprecation timeline. --- django/template/library.py | 10 ------- docs/howto/custom-template-tags.txt | 29 --------------------- docs/releases/1.9.txt | 5 ++-- docs/releases/2.0.txt | 2 ++ tests/template_tests/templatetags/custom.py | 17 ------------ tests/template_tests/test_custom.py | 23 ---------------- 6 files changed, 4 insertions(+), 82 deletions(-) diff --git a/django/template/library.py b/django/template/library.py index 04f4a7322dbb..8a6c98ee0983 100644 --- a/django/template/library.py +++ b/django/template/library.py @@ -1,9 +1,7 @@ import functools -import warnings from importlib import import_module from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.html import conditional_escape from django.utils.inspect import getargspec from django.utils.itercompat import is_iterable @@ -136,14 +134,6 @@ def compile_func(parser, token): else: raise ValueError("Invalid arguments provided to simple_tag") - def assignment_tag(self, func=None, takes_context=None, name=None): - warnings.warn( - "assignment_tag() is deprecated. Use simple_tag() instead", - RemovedInDjango20Warning, - stacklevel=2, - ) - return self.simple_tag(func, takes_context, name) - def inclusion_tag(self, filename, func=None, takes_context=None, name=None): """ Register a callable as an inclusion tag: diff --git a/docs/howto/custom-template-tags.txt b/docs/howto/custom-template-tags.txt index 53ea433137e6..448576784fe0 100644 --- a/docs/howto/custom-template-tags.txt +++ b/docs/howto/custom-template-tags.txt @@ -629,35 +629,6 @@ positional arguments. For example: {% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %} -Assignment tags ---------------- - -.. method:: django.template.Library.assignment_tag() - -.. deprecated:: 1.9 - - ``simple_tag`` can now store results in a template variable and should - be used instead. - -To ease the creation of tags setting a variable in the context, Django provides -a helper function, ``assignment_tag``. This function works the same way as -:meth:`~django.template.Library.simple_tag` except that it stores the tag's -result in a specified context variable instead of directly outputting it. - -Our earlier ``current_time`` function could thus be written like this:: - - @register.assignment_tag - def get_current_time(format_string): - return datetime.datetime.now().strftime(format_string) - -You may then store the result in a template variable using the ``as`` argument -followed by the variable name, and output it yourself where you see fit: - -.. code-block:: html+django - - {% get_current_time "%Y-%m-%d %I:%M %p" as the_time %} -

The time is {{ the_time }}.

- Advanced custom template tags ----------------------------- diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt index adcd6c949b2a..b7b489499de9 100644 --- a/docs/releases/1.9.txt +++ b/docs/releases/1.9.txt @@ -938,9 +938,8 @@ define built-in libraries via the ``'builtins'`` key of :setting:`OPTIONS In general, template tags do not autoescape their contents, and this behavior is :ref:`documented `. For tags like :class:`~django.template.Library.inclusion_tag`, this is not a problem because -the included template will perform autoescaping. For -:class:`~django.template.Library.assignment_tag`, the output will be escaped -when it is used as a variable in the template. +the included template will perform autoescaping. For ``assignment_tag()``, +the output will be escaped when it is used as a variable in the template. For the intended use cases of :class:`~django.template.Library.simple_tag`, however, it is very easy to end up with incorrect HTML and possibly an XSS diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 97e59ca26fc0..751b46cccf95 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -241,3 +241,5 @@ these features. is removed. * The ``django.forms.extras`` package is removed. + +* The ``assignment_tag`` helper is removed. diff --git a/tests/template_tests/templatetags/custom.py b/tests/template_tests/templatetags/custom.py index fffef022ac50..3c3e4ce8ed4d 100644 --- a/tests/template_tests/templatetags/custom.py +++ b/tests/template_tests/templatetags/custom.py @@ -1,5 +1,4 @@ import operator -import warnings from django import template from django.template.defaultfilters import stringfilter @@ -168,19 +167,3 @@ def minustwo_overridden_name(value): register.simple_tag(lambda x: x - 1, name='minusone') - - -with warnings.catch_warnings(): - warnings.simplefilter('ignore') - - @register.assignment_tag - def assignment_no_params(): - """Expected assignment_no_params __doc__""" - return "assignment_no_params - Expected result" - assignment_no_params.anything = "Expected assignment_no_params __dict__" - - @register.assignment_tag(takes_context=True) - def assignment_tag_without_context_parameter(arg): - """Expected assignment_tag_without_context_parameter __doc__""" - return "Expected result" - assignment_tag_without_context_parameter.anything = "Expected assignment_tag_without_context_parameter __dict__" diff --git a/tests/template_tests/test_custom.py b/tests/template_tests/test_custom.py index e6a876086e8c..b63882a9a865 100644 --- a/tests/template_tests/test_custom.py +++ b/tests/template_tests/test_custom.py @@ -306,29 +306,6 @@ def test_render_context_is_cleared(self): self.assertEqual(template.render(Context({})).strip(), 'one\ntwo') -class AssignmentTagTests(TagTestCase): - - def test_assignment_tags(self): - c = Context({'value': 42}) - - t = self.engine.from_string('{% load custom %}{% assignment_no_params as var %}The result is: {{ var }}') - self.assertEqual(t.render(c), 'The result is: assignment_no_params - Expected result') - - def test_assignment_tag_registration(self): - # The decorators preserve the decorated function's docstring, name, - # and attributes. - self.verify_tag(custom.assignment_no_params, 'assignment_no_params') - - def test_assignment_tag_missing_context(self): - # The 'context' parameter must be present when takes_context is True - msg = ( - "'assignment_tag_without_context_parameter' is decorated with " - "takes_context=True so it must have a first argument of 'context'" - ) - with self.assertRaisesMessage(TemplateSyntaxError, msg): - self.engine.from_string('{% load custom %}{% assignment_tag_without_context_parameter 123 as var %}') - - class TemplateTagLoadingTests(SimpleTestCase): @classmethod From 0f454f5d4df5d07b713e5f5633f8b56ae70c7cf9 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 16 Dec 2016 18:13:34 -0500 Subject: [PATCH 0007/3180] Refs #23960 -- Removed the host parameter for SimpleTestCase.assertRedirects(). Per deprecation timeline. --- django/test/testcases.py | 23 ++--------------------- docs/releases/2.0.txt | 4 ++++ docs/topics/testing/tools.txt | 5 ----- tests/test_client_regress/tests.py | 13 +------------ 4 files changed, 7 insertions(+), 38 deletions(-) diff --git a/django/test/testcases.py b/django/test/testcases.py index 8203a3837da3..253b2496798c 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -39,7 +39,7 @@ from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.utils.six.moves.urllib.parse import ( - unquote, urljoin, urlparse, urlsplit, urlunsplit, + unquote, urljoin, urlparse, urlsplit, ) from django.utils.six.moves.urllib.request import url2pathname from django.views.static import serve @@ -245,7 +245,7 @@ def modify_settings(self, **kwargs): return modify_settings(**kwargs) def assertRedirects(self, response, expected_url, status_code=302, - target_status_code=200, host=None, msg_prefix='', + target_status_code=200, msg_prefix='', fetch_redirect_response=True): """Asserts that a response redirected to a specific URL, and that the redirect URL can be loaded. @@ -254,12 +254,6 @@ def assertRedirects(self, response, expected_url, status_code=302, TestClient to do a request (use fetch_redirect_response=False to check such links without fetching them). """ - if host is not None: - warnings.warn( - "The host argument is deprecated and no longer used by assertRedirects", - RemovedInDjango20Warning, stacklevel=2 - ) - if msg_prefix: msg_prefix += ": " @@ -324,19 +318,6 @@ def assertRedirects(self, response, expected_url, status_code=302, % (path, redirect_response.status_code, target_status_code) ) - if url != expected_url: - # For temporary backwards compatibility, try to compare with a relative url - e_scheme, e_netloc, e_path, e_query, e_fragment = urlsplit(expected_url) - relative_url = urlunsplit(('', '', e_path, e_query, e_fragment)) - if url == relative_url: - warnings.warn( - "assertRedirects had to strip the scheme and domain from the " - "expected URL, as it was always added automatically to URLs " - "before Django 1.9. Please update your expected URLs by " - "removing the scheme and domain.", - RemovedInDjango20Warning, stacklevel=2) - expected_url = relative_url - self.assertEqual( url, expected_url, msg_prefix + "Response redirected to '%s', expected '%s'" % (url, expected_url) diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 751b46cccf95..984e13e9f191 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -243,3 +243,7 @@ these features. * The ``django.forms.extras`` package is removed. * The ``assignment_tag`` helper is removed. + +* The ``host`` argument to ``SimpleTestCase.assertsRedirects()`` is removed. + The compatibility layer which allows absolute URLs to be considered equal to + relative ones when the path is identical is also removed. diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt index 5ff8563dd191..7c40955a0cfc 100644 --- a/docs/topics/testing/tools.txt +++ b/docs/topics/testing/tools.txt @@ -1479,11 +1479,6 @@ your test suite. the original request's scheme is used. If present, the scheme in ``expected_url`` is the one used to make the comparisons to. - .. deprecated:: 1.9 - - The ``host`` argument is deprecated, as redirections are no longer - forced to be absolute URLs. - .. method:: SimpleTestCase.assertHTMLEqual(html1, html2, msg=None) Asserts that the strings ``html1`` and ``html2`` are equal. The comparison diff --git a/tests/test_client_regress/tests.py b/tests/test_client_regress/tests.py index 1e30017d5ad9..5598ed5280ec 100644 --- a/tests/test_client_regress/tests.py +++ b/tests/test_client_regress/tests.py @@ -15,14 +15,12 @@ ) from django.template.response import SimpleTemplateResponse from django.test import ( - Client, SimpleTestCase, TestCase, ignore_warnings, modify_settings, - override_settings, + Client, SimpleTestCase, TestCase, modify_settings, override_settings, ) from django.test.client import RedirectCycleError, RequestFactory, encode_file from django.test.utils import ContextList, str_prefix from django.urls import NoReverseMatch, reverse from django.utils._os import upath -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.translation import ugettext_lazy from .models import CustomUser @@ -514,15 +512,6 @@ def test_redirect_scheme(self): with self.assertRaises(AssertionError): self.assertRedirects(response, 'http://testserver/secure_view/', status_code=302) - @ignore_warnings(category=RemovedInDjango20Warning) - def test_full_path_in_expected_urls(self): - """ - Specifying a full URL as assertRedirects expected_url still - work as backwards compatible behavior until Django 2.0. - """ - response = self.client.get('/redirect_view/') - self.assertRedirects(response, 'http://testserver/get_view/') - @override_settings(ROOT_URLCONF='test_client_regress.urls') class AssertFormErrorTests(SimpleTestCase): From 625e9da9cac76ad6e7045d61b57834cc0c2d94d9 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 16 Dec 2016 18:19:52 -0500 Subject: [PATCH 0008/3180] Removed Field.rel and Field.remote_field.to per deprecation timeline. --- django/db/models/fields/__init__.py | 7 ------- django/db/models/fields/reverse_related.py | 11 ----------- docs/releases/2.0.txt | 2 ++ 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index b7d60f99218c..63a2fc8fa414 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -251,13 +251,6 @@ def _check_field_name(self): else: return [] - @property - def rel(self): - warnings.warn( - "Usage of field.rel has been deprecated. Use field.remote_field instead.", - RemovedInDjango20Warning, 2) - return self.remote_field - def _check_choices(self): if self.choices: if (isinstance(self.choices, six.string_types) or diff --git a/django/db/models/fields/reverse_related.py b/django/db/models/fields/reverse_related.py index 86e96ee133c9..82d9af64e711 100644 --- a/django/db/models/fields/reverse_related.py +++ b/django/db/models/fields/reverse_related.py @@ -11,10 +11,7 @@ from __future__ import unicode_literals -import warnings - from django.core import exceptions -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.utils.functional import cached_property @@ -56,14 +53,6 @@ def __init__(self, field, to, related_name=None, related_query_name=None, # __init__ as the field doesn't have its model yet. Calling these methods # before field.contribute_to_class() has been called will result in # AttributeError - @property - def to(self): - warnings.warn( - "Usage of ForeignObjectRel.to attribute has been deprecated. " - "Use the model attribute instead.", - RemovedInDjango20Warning, 2) - return self.model - @cached_property def hidden(self): return self.is_hidden() diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 984e13e9f191..6fd8c906ef8a 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -247,3 +247,5 @@ these features. * The ``host`` argument to ``SimpleTestCase.assertsRedirects()`` is removed. The compatibility layer which allows absolute URLs to be considered equal to relative ones when the path is identical is also removed. + +* ``Field.rel`` and ``Field.remote_field.to`` are removed. From ddd3268975dca9094d94ab1df56dae0a24a58865 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 30 Dec 2016 17:50:05 -0500 Subject: [PATCH 0009/3180] Refs #21127 -- Required on_delete for ForeignKey/OneToOneField. Per deprecation timeline. --- django/db/models/fields/related.py | 53 +---------- docs/ref/models/fields.txt | 5 -- docs/releases/2.0.txt | 3 + .../test_relative_fields.py | 87 ------------------- 4 files changed, 5 insertions(+), 143 deletions(-) diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index e551ed1dbeec..9716d65cd010 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -20,7 +20,6 @@ from django.utils.functional import cached_property, curry from django.utils.lru_cache import lru_cache from django.utils.translation import ugettext_lazy as _ -from django.utils.version import get_docs_version from . import Field from .related_descriptors import ( @@ -789,7 +788,7 @@ class ForeignKey(ForeignObject): } description = _("Foreign Key (type determined by related field)") - def __init__(self, to, on_delete=None, related_name=None, related_query_name=None, + def __init__(self, to, on_delete, related_name=None, related_query_name=None, limit_choices_to=None, parent_link=False, to_field=None, db_constraint=True, **kwargs): try: @@ -808,29 +807,6 @@ def __init__(self, to, on_delete=None, related_name=None, related_query_name=Non # be correct until contribute_to_class is called. Refs #12190. to_field = to_field or (to._meta.pk and to._meta.pk.name) - if on_delete is None: - warnings.warn( - "on_delete will be a required arg for %s in Django 2.0. Set " - "it to models.CASCADE on models and in existing migrations " - "if you want to maintain the current default behavior. " - "See https://docs.djangoproject.com/en/%s/ref/models/fields/" - "#django.db.models.ForeignKey.on_delete" % ( - self.__class__.__name__, - get_docs_version(), - ), - RemovedInDjango20Warning, 2) - on_delete = CASCADE - - elif not callable(on_delete): - warnings.warn( - "The signature for {0} will change in Django 2.0. " - "Pass to_field='{1}' as a kwarg instead of as an arg.".format( - self.__class__.__name__, - on_delete, - ), - RemovedInDjango20Warning, 2) - on_delete, to_field = to_field, on_delete - kwargs['rel'] = self.rel_class( self, to, to_field, related_name=related_name, @@ -1028,33 +1004,8 @@ class OneToOneField(ForeignKey): description = _("One-to-one relationship") - def __init__(self, to, on_delete=None, to_field=None, **kwargs): + def __init__(self, to, on_delete, to_field=None, **kwargs): kwargs['unique'] = True - - if on_delete is None: - warnings.warn( - "on_delete will be a required arg for %s in Django 2.0. Set " - "it to models.CASCADE on models and in existing migrations " - "if you want to maintain the current default behavior. " - "See https://docs.djangoproject.com/en/%s/ref/models/fields/" - "#django.db.models.ForeignKey.on_delete" % ( - self.__class__.__name__, - get_docs_version(), - ), - RemovedInDjango20Warning, 2) - on_delete = CASCADE - - elif not callable(on_delete): - warnings.warn( - "The signature for {0} will change in Django 2.0. " - "Pass to_field='{1}' as a kwarg instead of as an arg.".format( - self.__class__.__name__, - on_delete, - ), - RemovedInDjango20Warning, 2) - to_field = on_delete - on_delete = CASCADE # Avoid warning in superclass - super(OneToOneField, self).__init__(to, on_delete, to_field=to_field, **kwargs) def deconstruct(self): diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index ba01f5f0bcd0..1d03bf99f2a9 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -1277,11 +1277,6 @@ relation works. null=True, ) - .. deprecated:: 1.9 - - :attr:`~ForeignKey.on_delete` will become a required argument in Django - 2.0. In older versions it defaults to ``CASCADE``. - The possible values for :attr:`~ForeignKey.on_delete` are found in :mod:`django.db.models`: diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 6fd8c906ef8a..3958d27dd253 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -249,3 +249,6 @@ these features. relative ones when the path is identical is also removed. * ``Field.rel`` and ``Field.remote_field.to`` are removed. + +* The ``on_delete`` argument for ``ForeignKey`` and ``OneToOneField`` are now + required. diff --git a/tests/invalid_models_tests/test_relative_fields.py b/tests/invalid_models_tests/test_relative_fields.py index 7c20a0fb996c..2165e6dfb5e6 100644 --- a/tests/invalid_models_tests/test_relative_fields.py +++ b/tests/invalid_models_tests/test_relative_fields.py @@ -1,17 +1,12 @@ # -*- encoding: utf-8 -*- from __future__ import unicode_literals -import warnings - from django.core.checks import Error, Warning as DjangoWarning from django.db import models from django.db.models.fields.related import ForeignObject -from django.test import ignore_warnings from django.test.testcases import SimpleTestCase, skipIfDBFeature from django.test.utils import isolate_apps, override_settings from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning -from django.utils.version import get_docs_version @isolate_apps('invalid_models_tests') @@ -29,88 +24,6 @@ class Model(models.Model): errors = field.check() self.assertEqual(errors, []) - @ignore_warnings(category=RemovedInDjango20Warning) - def test_valid_foreign_key_without_on_delete(self): - class Target(models.Model): - model = models.IntegerField() - - class Model(models.Model): - field = models.ForeignKey(Target, related_name='+') - - def test_foreign_key_without_on_delete_warning(self): - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') # prevent warnings from appearing as errors - - class Target(models.Model): - model = models.IntegerField() - - class Model(models.Model): - field = models.ForeignKey(Target, related_name='+') - - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - 'on_delete will be a required arg for ForeignKey in Django ' - '2.0. Set it to models.CASCADE on models and in existing ' - 'migrations if you want to maintain the current default ' - 'behavior. See https://docs.djangoproject.com/en/%s/ref/models/fields/' - '#django.db.models.ForeignKey.on_delete' % get_docs_version(), - ) - - def test_foreign_key_to_field_as_arg(self): - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') # prevent warnings from appearing as errors - - class Target(models.Model): - model = models.IntegerField() - - class Model(models.Model): - field = models.ForeignKey(Target, 'id') - - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - "The signature for ForeignKey will change in Django 2.0. " - "Pass to_field='id' as a kwarg instead of as an arg." - ) - - def test_one_to_one_field_without_on_delete_warning(self): - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') # prevent warnings from appearing as errors - - class Target(models.Model): - model = models.IntegerField() - - class Model(models.Model): - field = models.OneToOneField(Target, related_name='+') - - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - 'on_delete will be a required arg for OneToOneField in Django ' - '2.0. Set it to models.CASCADE on models and in existing ' - 'migrations if you want to maintain the current default ' - 'behavior. See https://docs.djangoproject.com/en/%s/ref/models/fields/' - '#django.db.models.ForeignKey.on_delete' % get_docs_version(), - ) - - def test_one_to_one_field_to_field_as_arg(self): - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') # prevent warnings from appearing as errors - - class Target(models.Model): - model = models.IntegerField() - - class Model(models.Model): - field = models.OneToOneField(Target, 'id') - - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - "The signature for OneToOneField will change in Django 2.0. " - "Pass to_field='id' as a kwarg instead of as an arg." - ) - def test_foreign_key_to_missing_model(self): # Model names are resolved when a model is being created, so we cannot # test relative fields in isolation and we need to attach them to a From b2ffbb00a5b4526ab51c62a620f819c96a44902c Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 30 Dec 2016 17:55:03 -0500 Subject: [PATCH 0010/3180] Refs #24215 -- Removed add_lazy_relation() per deprecation timeline. --- django/db/models/fields/related.py | 15 --------------- docs/releases/2.0.txt | 2 ++ 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 9716d65cd010..256441c6a2bb 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals import inspect -import warnings from functools import partial from django import forms @@ -15,7 +14,6 @@ from django.db.models.query_utils import PathInfo from django.db.models.utils import make_model_tuple from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.utils.functional import cached_property, curry from django.utils.lru_cache import lru_cache @@ -84,19 +82,6 @@ def lazy_related_operation(function, model, *related_models, **kwargs): return apps.lazy_model_operation(partial(function, **kwargs), *model_keys) -def add_lazy_relation(cls, field, relation, operation): - warnings.warn( - "add_lazy_relation() has been superseded by lazy_related_operation() " - "and related methods on the Apps class.", - RemovedInDjango20Warning, stacklevel=2) - # Rearrange args for new Apps.lazy_model_operation - - def function(local, related, field): - return operation(field, related, local) - - lazy_related_operation(function, cls, relation, field=field) - - class RelatedField(Field): """ Base class that all relational fields inherit from. diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 3958d27dd253..9c1d80f081ab 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -252,3 +252,5 @@ these features. * The ``on_delete`` argument for ``ForeignKey`` and ``OneToOneField`` are now required. + +* ``django.db.models.fields.add_lazy_relation()`` is removed. From e707e4c709c2e3f2dad69643eb838f87491891f8 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 30 Dec 2016 18:04:09 -0500 Subject: [PATCH 0011/3180] Refs #19738 -- Removed timezone conversion in SQL queries executed outside of the ORM. Per deprecation timeline. --- django/db/backends/mysql/base.py | 23 ++--------------------- django/db/backends/oracle/base.py | 11 +---------- django/db/backends/sqlite3/base.py | 18 ------------------ docs/releases/2.0.txt | 5 +++++ 4 files changed, 8 insertions(+), 49 deletions(-) diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 7a59ecd61247..d7bb1297449f 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -6,18 +6,14 @@ """ from __future__ import unicode_literals -import datetime import re import sys -import warnings -from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.db import utils from django.db.backends import utils as backend_utils from django.db.backends.base.base import BaseDatabaseWrapper -from django.utils import six, timezone -from django.utils.deprecation import RemovedInDjango20Warning +from django.utils import six from django.utils.encoding import force_str from django.utils.functional import cached_property from django.utils.safestring import SafeBytes, SafeText @@ -31,7 +27,7 @@ ) from MySQLdb.constants import CLIENT, FIELD_TYPE # isort:skip -from MySQLdb.converters import Thing2Literal, conversions # isort:skip +from MySQLdb.converters import conversions # isort:skip # Some of these import MySQLdb, so import them after checking if it's installed. from .client import DatabaseClient # isort:skip @@ -51,20 +47,6 @@ raise ImproperlyConfigured("MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__) -def adapt_datetime_warn_on_aware_datetime(value, conv): - # Remove this function and rely on the default adapter in Django 2.0. - if settings.USE_TZ and timezone.is_aware(value): - warnings.warn( - "The MySQL database adapter received an aware datetime (%s), " - "probably from cursor.execute(). Update your code to pass a " - "naive datetime in the database connection's time zone (UTC by " - "default).", RemovedInDjango20Warning) - # This doesn't account for the database connection's timezone, - # which isn't known. (That's why this adapter is deprecated.) - value = value.astimezone(timezone.utc).replace(tzinfo=None) - return Thing2Literal(value.strftime("%Y-%m-%d %H:%M:%S.%f"), conv) - - # MySQLdb-1.2.1 returns TIME columns as timedelta -- they are more like # timedelta in terms of actual behavior as they are signed and include days -- # and Django expects time, so we still need to override that. We also need to @@ -75,7 +57,6 @@ def adapt_datetime_warn_on_aware_datetime(value, conv): FIELD_TYPE.TIME: backend_utils.typecast_time, FIELD_TYPE.DECIMAL: backend_utils.typecast_decimal, FIELD_TYPE.NEWDECIMAL: backend_utils.typecast_decimal, - datetime.datetime: adapt_datetime_warn_on_aware_datetime, }) # This should match the numerical portion of the version numbers (we can treat diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 8e23b95fed2b..c40a515f3382 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -10,14 +10,12 @@ import os import platform import sys -import warnings from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.db import utils from django.db.backends.base.base import BaseDatabaseWrapper -from django.utils import six, timezone -from django.utils.deprecation import RemovedInDjango20Warning +from django.utils import six from django.utils.encoding import force_bytes, force_text from django.utils.functional import cached_property @@ -326,13 +324,6 @@ def __init__(self, param, cursor, strings_only=False): # without being converted by DateTimeField.get_db_prep_value. if settings.USE_TZ and (isinstance(param, datetime.datetime) and not isinstance(param, Oracle_datetime)): - if timezone.is_aware(param): - warnings.warn( - "The Oracle database adapter received an aware datetime (%s), " - "probably from cursor.execute(). Update your code to pass a " - "naive datetime in the database connection's time zone (UTC by " - "default).", RemovedInDjango20Warning) - param = param.astimezone(timezone.utc).replace(tzinfo=None) param = Oracle_datetime.from_datetime(param) string_size = 0 diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py index 89ee9682f255..0c26882a5750 100644 --- a/django/db/backends/sqlite3/base.py +++ b/django/db/backends/sqlite3/base.py @@ -6,14 +6,12 @@ """ from __future__ import unicode_literals -import datetime import decimal import re import warnings import pytz -from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.db import utils from django.db.backends import utils as backend_utils @@ -22,7 +20,6 @@ from django.utils.dateparse import ( parse_date, parse_datetime, parse_duration, parse_time, ) -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.utils.safestring import SafeBytes @@ -43,20 +40,6 @@ from .schema import DatabaseSchemaEditor # isort:skip -def adapt_datetime_warn_on_aware_datetime(value): - # Remove this function and rely on the default adapter in Django 2.0. - if settings.USE_TZ and timezone.is_aware(value): - warnings.warn( - "The SQLite database adapter received an aware datetime (%s), " - "probably from cursor.execute(). Update your code to pass a " - "naive datetime in the database connection's time zone (UTC by " - "default).", RemovedInDjango20Warning) - # This doesn't account for the database connection's timezone, - # which isn't known. (That's why this adapter is deprecated.) - value = value.astimezone(timezone.utc).replace(tzinfo=None) - return value.isoformat(str(" ")) - - def decoder(conv_func): """ The Python sqlite3 interface returns always byte strings. This function converts the received value to a regular string before @@ -73,7 +56,6 @@ def decoder(conv_func): Database.register_converter(str("TIMESTAMP"), decoder(parse_datetime)) Database.register_converter(str("decimal"), decoder(backend_utils.typecast_decimal)) -Database.register_adapter(datetime.datetime, adapt_datetime_warn_on_aware_datetime) Database.register_adapter(decimal.Decimal, backend_utils.rev_typecast_decimal) if six.PY2: Database.register_adapter(str, lambda s: s.decode('utf-8')) diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 9c1d80f081ab..0982218b92db 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -254,3 +254,8 @@ these features. required. * ``django.db.models.fields.add_lazy_relation()`` is removed. + +* When time zone support is enabled, database backends that don't support time + zones no longer convert aware datetimes to naive values in UTC anymore when + such values are passed as parameters to SQL queries executed outside of the + ORM, e.g. with ``cursor.execute()``. From e90c745afdcf89bc3416c9cb2d4a06dfacb2a250 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 30 Dec 2016 18:10:04 -0500 Subject: [PATCH 0012/3180] Refs #22993 -- Removed skipIfCustomUser per deprecation timeline. --- django/contrib/auth/tests/__init__.py | 0 django/contrib/auth/tests/utils.py | 16 ---------------- docs/releases/2.0.txt | 2 ++ 3 files changed, 2 insertions(+), 16 deletions(-) delete mode 100644 django/contrib/auth/tests/__init__.py delete mode 100644 django/contrib/auth/tests/utils.py diff --git a/django/contrib/auth/tests/__init__.py b/django/contrib/auth/tests/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/django/contrib/auth/tests/utils.py b/django/contrib/auth/tests/utils.py deleted file mode 100644 index 035b3a5f4223..000000000000 --- a/django/contrib/auth/tests/utils.py +++ /dev/null @@ -1,16 +0,0 @@ -import warnings -from unittest import skipIf - -from django.conf import settings -from django.utils.deprecation import RemovedInDjango20Warning - - -def skipIfCustomUser(test_func): - """ - Skip a test if a custom user model is in use. - """ - warnings.warn( - "django.contrib.auth.tests.utils.skipIfCustomUser is deprecated.", - RemovedInDjango20Warning, stacklevel=2) - - return skipIf(settings.AUTH_USER_MODEL != 'auth.User', 'Custom user model in use')(test_func) diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 0982218b92db..c87faba78370 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -259,3 +259,5 @@ these features. zones no longer convert aware datetimes to naive values in UTC anymore when such values are passed as parameters to SQL queries executed outside of the ORM, e.g. with ``cursor.execute()``. + +* ``django.contrib.auth.tests.utils.skipIfCustomUser()`` is removed. From a0d166306fbdc41f49e6fadf4ec84b17eb147daa Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 7 Nov 2016 13:00:40 +0100 Subject: [PATCH 0013/3180] Removed GeoManager and GeoQuerySet per deprecation timeline. --- .../contrib/gis/db/backends/base/features.py | 22 - .../contrib/gis/db/backends/oracle/models.py | 1 - django/contrib/gis/db/models/__init__.py | 3 +- django/contrib/gis/db/models/fields.py | 21 - django/contrib/gis/db/models/manager.py | 26 - django/contrib/gis/db/models/query.py | 727 ------------------ docs/ref/contrib/gis/geoquerysets.txt | 595 +------------- docs/ref/contrib/gis/model-api.txt | 16 - docs/ref/models/querysets.txt | 9 +- docs/releases/1.2.txt | 8 +- docs/releases/2.0.txt | 2 + tests/gis_tests/distapp/models.py | 2 - tests/gis_tests/distapp/tests.py | 215 +----- tests/gis_tests/geo3d/models.py | 2 - tests/gis_tests/geo3d/tests.py | 105 +-- tests/gis_tests/geoapp/models.py | 2 - tests/gis_tests/geoapp/test_functions.py | 2 - tests/gis_tests/geoapp/test_regress.py | 2 +- tests/gis_tests/geoapp/tests.py | 380 +-------- tests/gis_tests/geogapp/models.py | 2 - tests/gis_tests/geogapp/tests.py | 29 +- tests/gis_tests/relatedapp/models.py | 3 - tests/gis_tests/relatedapp/tests.py | 33 +- tests/managers_regress/tests.py | 13 - tests/runtests.py | 6 - 25 files changed, 32 insertions(+), 2194 deletions(-) delete mode 100644 django/contrib/gis/db/models/manager.py delete mode 100644 django/contrib/gis/db/models/query.py diff --git a/django/contrib/gis/db/backends/base/features.py b/django/contrib/gis/db/backends/base/features.py index 166495a6cc1d..5ca28813301c 100644 --- a/django/contrib/gis/db/backends/base/features.py +++ b/django/contrib/gis/db/backends/base/features.py @@ -1,5 +1,4 @@ import re -from functools import partial from django.contrib.gis.db.models import aggregates @@ -71,17 +70,6 @@ def supports_relate_lookup(self): def supports_isvalid_lookup(self): return 'isvalid' in self.connection.ops.gis_operators - # For each of those methods, the class will have a property named - # `has__method` (defined in __init__) which accesses connection.ops - # to determine GIS method availability. - geoqueryset_methods = ( - 'area', 'bounding_circle', 'centroid', 'difference', 'distance', - 'distance_spheroid', 'envelope', 'force_rhr', 'geohash', 'gml', - 'intersection', 'kml', 'length', 'mem_size', 'num_geom', 'num_points', - 'perimeter', 'point_on_surface', 'reverse', 'scale', 'snap_to_grid', - 'svg', 'sym_difference', 'transform', 'translate', 'union', 'unionagg', - ) - # Is the aggregate supported by the database? @property def supports_collect_aggr(self): @@ -99,19 +87,9 @@ def supports_make_line_aggr(self): def supports_union_aggr(self): return aggregates.Union not in self.connection.ops.disallowed_aggregates - def __init__(self, *args): - super(BaseSpatialFeatures, self).__init__(*args) - for method in self.geoqueryset_methods: - # Add dynamically properties for each GQS method, e.g. has_force_rhr_method, etc. - setattr(self.__class__, 'has_%s_method' % method, - property(partial(BaseSpatialFeatures.has_ops_method, method=method))) - def __getattr__(self, name): m = re.match(r'has_(\w*)_function$', name) if m: func_name = m.group(1) return func_name not in self.connection.ops.unsupported_functions raise AttributeError - - def has_ops_method(self, method): - return getattr(self.connection.ops, method, False) diff --git a/django/contrib/gis/db/backends/oracle/models.py b/django/contrib/gis/db/backends/oracle/models.py index 02dcf212ea2b..e1bf49050b38 100644 --- a/django/contrib/gis/db/backends/oracle/models.py +++ b/django/contrib/gis/db/backends/oracle/models.py @@ -55,7 +55,6 @@ class OracleSpatialRefSys(models.Model, SpatialRefSysMixin): # Optional geometry representing the bounds of this coordinate # system. By default, all are NULL in the table. cs_bounds = models.PolygonField(null=True) - objects = models.GeoManager() class Meta: app_label = 'gis' diff --git a/django/contrib/gis/db/models/__init__.py b/django/contrib/gis/db/models/__init__.py index 84f84d32b056..5f6c2374a72f 100644 --- a/django/contrib/gis/db/models/__init__.py +++ b/django/contrib/gis/db/models/__init__.py @@ -7,11 +7,10 @@ MultiLineStringField, MultiPointField, MultiPolygonField, PointField, PolygonField, RasterField, ) -from django.contrib.gis.db.models.manager import GeoManager __all__ = models_all + aggregates_all __all__ += [ 'GeometryCollectionField', 'GeometryField', 'LineStringField', 'MultiLineStringField', 'MultiPointField', 'MultiPolygonField', 'PointField', - 'PolygonField', 'RasterField', 'GeoManager', + 'PolygonField', 'RasterField', ] diff --git a/django/contrib/gis/db/models/fields.py b/django/contrib/gis/db/models/fields.py index 2fd74da632b9..215a17b6b58e 100644 --- a/django/contrib/gis/db/models/fields.py +++ b/django/contrib/gis/db/models/fields.py @@ -346,27 +346,6 @@ def formfield(self, **kwargs): defaults['widget'] = forms.Textarea return super(GeometryField, self).formfield(**defaults) - def _get_db_prep_lookup(self, lookup_type, value, connection): - """ - Prepare for the database lookup, and return any spatial parameters - necessary for the query. This includes wrapping any geometry - parameters with a backend-specific adapter and formatting any distance - parameters into the correct units for the coordinate system of the - field. - - Only used by the deprecated GeoQuerySet and to be - RemovedInDjango20Warning. - """ - # Populating the parameters list, and wrapping the Geometry - # with the Adapter of the spatial backend. - if isinstance(value, (tuple, list)): - params = [connection.ops.Adapter(value[0])] - # Getting the distance parameter in the units of the field. - params += self.get_distance(value[1:], lookup_type, connection) - else: - params = [connection.ops.Adapter(value)] - return params - # The OpenGIS Geometry Type Fields class PointField(GeometryField): diff --git a/django/contrib/gis/db/models/manager.py b/django/contrib/gis/db/models/manager.py deleted file mode 100644 index 44f014009083..000000000000 --- a/django/contrib/gis/db/models/manager.py +++ /dev/null @@ -1,26 +0,0 @@ -import warnings - -from django.contrib.gis.db.models.query import GeoQuerySet -from django.db.models.manager import Manager -from django.utils.deprecation import RemovedInDjango20Warning - - -class GeoManager(Manager.from_queryset(GeoQuerySet)): - "Overrides Manager to return Geographic QuerySets." - - # This manager should be used for queries on related fields - # so that geometry columns on Oracle and MySQL are selected - # properly. - use_for_related_fields = True - - # No need to bother users with the use_for_related_fields - # deprecation for this manager which is itself deprecated. - silence_use_for_related_fields_deprecation = True - - def __init__(self, *args, **kwargs): - warnings.warn( - "The GeoManager class is deprecated. Simply use a normal manager " - "once you have replaced all calls to GeoQuerySet methods by annotations.", - RemovedInDjango20Warning, stacklevel=2 - ) - super(GeoManager, self).__init__(*args, **kwargs) diff --git a/django/contrib/gis/db/models/query.py b/django/contrib/gis/db/models/query.py deleted file mode 100644 index d1933721b620..000000000000 --- a/django/contrib/gis/db/models/query.py +++ /dev/null @@ -1,727 +0,0 @@ -import warnings - -from django.contrib.gis.db.models.fields import ( - GeometryField, LineStringField, PointField, get_srid_info, -) -from django.contrib.gis.db.models.lookups import GISLookup -from django.contrib.gis.db.models.sql import ( - AreaField, DistanceField, GeomField, GMLField, -) -from django.contrib.gis.geometry.backend import Geometry -from django.contrib.gis.measure import Area, Distance -from django.db import connections -from django.db.models.constants import LOOKUP_SEP -from django.db.models.expressions import RawSQL -from django.db.models.fields import Field -from django.db.models.query import QuerySet -from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning - - -class GeoQuerySet(QuerySet): - "The Geographic QuerySet." - - # ### GeoQuerySet Methods ### - def area(self, tolerance=0.05, **kwargs): - """ - Returns the area of the geographic field in an `area` attribute on - each element of this GeoQuerySet. - """ - # Performing setup here rather than in `_spatial_attribute` so that - # we can get the units for `AreaField`. - procedure_args, geo_field = self._spatial_setup( - 'area', field_name=kwargs.get('field_name')) - s = {'procedure_args': procedure_args, - 'geo_field': geo_field, - 'setup': False, - } - connection = connections[self.db] - backend = connection.ops - if backend.oracle: - s['procedure_fmt'] = '%(geo_col)s,%(tolerance)s' - s['procedure_args']['tolerance'] = tolerance - s['select_field'] = AreaField('sq_m') # Oracle returns area in units of meters. - elif backend.postgis or backend.spatialite: - if backend.geography: - # Geography fields support area calculation, returns square meters. - s['select_field'] = AreaField('sq_m') - elif not geo_field.geodetic(connection): - # Getting the area units of the geographic field. - s['select_field'] = AreaField(Area.unit_attname(geo_field.units_name(connection))) - else: - # TODO: Do we want to support raw number areas for geodetic fields? - raise Exception('Area on geodetic coordinate systems not supported.') - return self._spatial_attribute('area', s, **kwargs) - - def centroid(self, **kwargs): - """ - Returns the centroid of the geographic field in a `centroid` - attribute on each element of this GeoQuerySet. - """ - return self._geom_attribute('centroid', **kwargs) - - def difference(self, geom, **kwargs): - """ - Returns the spatial difference of the geographic field in a `difference` - attribute on each element of this GeoQuerySet. - """ - return self._geomset_attribute('difference', geom, **kwargs) - - def distance(self, geom, **kwargs): - """ - Returns the distance from the given geographic field name to the - given geometry in a `distance` attribute on each element of the - GeoQuerySet. - - Keyword Arguments: - `spheroid` => If the geometry field is geodetic and PostGIS is - the spatial database, then the more accurate - spheroid calculation will be used instead of the - quicker sphere calculation. - - `tolerance` => Used only for Oracle. The tolerance is - in meters -- a default of 5 centimeters (0.05) - is used. - """ - return self._distance_attribute('distance', geom, **kwargs) - - def envelope(self, **kwargs): - """ - Returns a Geometry representing the bounding box of the - Geometry field in an `envelope` attribute on each element of - the GeoQuerySet. - """ - return self._geom_attribute('envelope', **kwargs) - - def force_rhr(self, **kwargs): - """ - Returns a modified version of the Polygon/MultiPolygon in which - all of the vertices follow the Right-Hand-Rule. By default, - this is attached as the `force_rhr` attribute on each element - of the GeoQuerySet. - """ - return self._geom_attribute('force_rhr', **kwargs) - - def geojson(self, precision=8, crs=False, bbox=False, **kwargs): - """ - Returns a GeoJSON representation of the geometry field in a `geojson` - attribute on each element of the GeoQuerySet. - - The `crs` and `bbox` keywords may be set to True if the user wants - the coordinate reference system and the bounding box to be included - in the GeoJSON representation of the geometry. - """ - backend = connections[self.db].ops - if not backend.geojson: - raise NotImplementedError('Only PostGIS and SpatiaLite support GeoJSON serialization.') - - if not isinstance(precision, six.integer_types): - raise TypeError('Precision keyword must be set with an integer.') - - options = 0 - if crs and bbox: - options = 3 - elif bbox: - options = 1 - elif crs: - options = 2 - s = {'desc': 'GeoJSON', - 'procedure_args': {'precision': precision, 'options': options}, - 'procedure_fmt': '%(geo_col)s,%(precision)s,%(options)s', - } - return self._spatial_attribute('geojson', s, **kwargs) - - def geohash(self, precision=20, **kwargs): - """ - Returns a GeoHash representation of the given field in a `geohash` - attribute on each element of the GeoQuerySet. - - The `precision` keyword may be used to custom the number of - _characters_ used in the output GeoHash, the default is 20. - """ - s = {'desc': 'GeoHash', - 'procedure_args': {'precision': precision}, - 'procedure_fmt': '%(geo_col)s,%(precision)s', - } - return self._spatial_attribute('geohash', s, **kwargs) - - def gml(self, precision=8, version=2, **kwargs): - """ - Returns GML representation of the given field in a `gml` attribute - on each element of the GeoQuerySet. - """ - backend = connections[self.db].ops - s = {'desc': 'GML', 'procedure_args': {'precision': precision}} - if backend.postgis: - s['procedure_fmt'] = '%(version)s,%(geo_col)s,%(precision)s' - s['procedure_args'] = {'precision': precision, 'version': version} - if backend.oracle: - s['select_field'] = GMLField() - - return self._spatial_attribute('gml', s, **kwargs) - - def intersection(self, geom, **kwargs): - """ - Returns the spatial intersection of the Geometry field in - an `intersection` attribute on each element of this - GeoQuerySet. - """ - return self._geomset_attribute('intersection', geom, **kwargs) - - def kml(self, **kwargs): - """ - Returns KML representation of the geometry field in a `kml` - attribute on each element of this GeoQuerySet. - """ - s = {'desc': 'KML', - 'procedure_fmt': '%(geo_col)s,%(precision)s', - 'procedure_args': {'precision': kwargs.pop('precision', 8)}, - } - return self._spatial_attribute('kml', s, **kwargs) - - def length(self, **kwargs): - """ - Returns the length of the geometry field as a `Distance` object - stored in a `length` attribute on each element of this GeoQuerySet. - """ - return self._distance_attribute('length', None, **kwargs) - - def mem_size(self, **kwargs): - """ - Returns the memory size (number of bytes) that the geometry field takes - in a `mem_size` attribute on each element of this GeoQuerySet. - """ - return self._spatial_attribute('mem_size', {}, **kwargs) - - def num_geom(self, **kwargs): - """ - Returns the number of geometries if the field is a - GeometryCollection or Multi* Field in a `num_geom` - attribute on each element of this GeoQuerySet; otherwise - the sets with None. - """ - return self._spatial_attribute('num_geom', {}, **kwargs) - - def num_points(self, **kwargs): - """ - Returns the number of points in the first linestring in the - Geometry field in a `num_points` attribute on each element of - this GeoQuerySet; otherwise sets with None. - """ - return self._spatial_attribute('num_points', {}, **kwargs) - - def perimeter(self, **kwargs): - """ - Returns the perimeter of the geometry field as a `Distance` object - stored in a `perimeter` attribute on each element of this GeoQuerySet. - """ - return self._distance_attribute('perimeter', None, **kwargs) - - def point_on_surface(self, **kwargs): - """ - Returns a Point geometry guaranteed to lie on the surface of the - Geometry field in a `point_on_surface` attribute on each element - of this GeoQuerySet; otherwise sets with None. - """ - return self._geom_attribute('point_on_surface', **kwargs) - - def reverse_geom(self, **kwargs): - """ - Reverses the coordinate order of the geometry, and attaches as a - `reverse` attribute on each element of this GeoQuerySet. - """ - s = {'select_field': GeomField()} - kwargs.setdefault('model_att', 'reverse_geom') - if connections[self.db].ops.oracle: - s['geo_field_type'] = LineStringField - return self._spatial_attribute('reverse', s, **kwargs) - - def scale(self, x, y, z=0.0, **kwargs): - """ - Scales the geometry to a new size by multiplying the ordinates - with the given x,y,z scale factors. - """ - if connections[self.db].ops.spatialite: - if z != 0.0: - raise NotImplementedError('SpatiaLite does not support 3D scaling.') - s = {'procedure_fmt': '%(geo_col)s,%(x)s,%(y)s', - 'procedure_args': {'x': x, 'y': y}, - 'select_field': GeomField(), - } - else: - s = {'procedure_fmt': '%(geo_col)s,%(x)s,%(y)s,%(z)s', - 'procedure_args': {'x': x, 'y': y, 'z': z}, - 'select_field': GeomField(), - } - return self._spatial_attribute('scale', s, **kwargs) - - def snap_to_grid(self, *args, **kwargs): - """ - Snap all points of the input geometry to the grid. How the - geometry is snapped to the grid depends on how many arguments - were given: - - 1 argument : A single size to snap both the X and Y grids to. - - 2 arguments: X and Y sizes to snap the grid to. - - 4 arguments: X, Y sizes and the X, Y origins. - """ - if False in [isinstance(arg, (float,) + six.integer_types) for arg in args]: - raise TypeError('Size argument(s) for the grid must be a float or integer values.') - - nargs = len(args) - if nargs == 1: - size = args[0] - procedure_fmt = '%(geo_col)s,%(size)s' - procedure_args = {'size': size} - elif nargs == 2: - xsize, ysize = args - procedure_fmt = '%(geo_col)s,%(xsize)s,%(ysize)s' - procedure_args = {'xsize': xsize, 'ysize': ysize} - elif nargs == 4: - xsize, ysize, xorigin, yorigin = args - procedure_fmt = '%(geo_col)s,%(xorigin)s,%(yorigin)s,%(xsize)s,%(ysize)s' - procedure_args = {'xsize': xsize, 'ysize': ysize, - 'xorigin': xorigin, 'yorigin': yorigin} - else: - raise ValueError('Must provide 1, 2, or 4 arguments to `snap_to_grid`.') - - s = {'procedure_fmt': procedure_fmt, - 'procedure_args': procedure_args, - 'select_field': GeomField(), - } - - return self._spatial_attribute('snap_to_grid', s, **kwargs) - - def svg(self, relative=False, precision=8, **kwargs): - """ - Returns SVG representation of the geographic field in a `svg` - attribute on each element of this GeoQuerySet. - - Keyword Arguments: - `relative` => If set to True, this will evaluate the path in - terms of relative moves (rather than absolute). - - `precision` => May be used to set the maximum number of decimal - digits used in output (defaults to 8). - """ - relative = int(bool(relative)) - if not isinstance(precision, six.integer_types): - raise TypeError('SVG precision keyword argument must be an integer.') - s = { - 'desc': 'SVG', - 'procedure_fmt': '%(geo_col)s,%(rel)s,%(precision)s', - 'procedure_args': { - 'rel': relative, - 'precision': precision, - } - } - return self._spatial_attribute('svg', s, **kwargs) - - def sym_difference(self, geom, **kwargs): - """ - Returns the symmetric difference of the geographic field in a - `sym_difference` attribute on each element of this GeoQuerySet. - """ - return self._geomset_attribute('sym_difference', geom, **kwargs) - - def translate(self, x, y, z=0.0, **kwargs): - """ - Translates the geometry to a new location using the given numeric - parameters as offsets. - """ - if connections[self.db].ops.spatialite: - if z != 0.0: - raise NotImplementedError('SpatiaLite does not support 3D translation.') - s = {'procedure_fmt': '%(geo_col)s,%(x)s,%(y)s', - 'procedure_args': {'x': x, 'y': y}, - 'select_field': GeomField(), - } - else: - s = {'procedure_fmt': '%(geo_col)s,%(x)s,%(y)s,%(z)s', - 'procedure_args': {'x': x, 'y': y, 'z': z}, - 'select_field': GeomField(), - } - return self._spatial_attribute('translate', s, **kwargs) - - def transform(self, srid=4326, **kwargs): - """ - Transforms the given geometry field to the given SRID. If no SRID is - provided, the transformation will default to using 4326 (WGS84). - """ - if not isinstance(srid, six.integer_types): - raise TypeError('An integer SRID must be provided.') - field_name = kwargs.get('field_name') - self._spatial_setup('transform', field_name=field_name) - self.query.add_context('transformed_srid', srid) - return self._clone() - - def union(self, geom, **kwargs): - """ - Returns the union of the geographic field with the given - Geometry in a `union` attribute on each element of this GeoQuerySet. - """ - return self._geomset_attribute('union', geom, **kwargs) - - # ### Private API -- Abstracted DRY routines. ### - def _spatial_setup(self, att, desc=None, field_name=None, geo_field_type=None): - """ - Performs set up for executing the spatial function. - """ - # Does the spatial backend support this? - connection = connections[self.db] - func = getattr(connection.ops, att, False) - if desc is None: - desc = att - if not func: - raise NotImplementedError('%s stored procedure not available on ' - 'the %s backend.' % - (desc, connection.ops.name)) - - # Initializing the procedure arguments. - procedure_args = {'function': func} - - # Is there a geographic field in the model to perform this - # operation on? - geo_field = self._geo_field(field_name) - if not geo_field: - raise TypeError('%s output only available on GeometryFields.' % func) - - # If the `geo_field_type` keyword was used, then enforce that - # type limitation. - if geo_field_type is not None and not isinstance(geo_field, geo_field_type): - raise TypeError('"%s" stored procedures may only be called on %ss.' % (func, geo_field_type.__name__)) - - # Setting the procedure args. - procedure_args['geo_col'] = self._geocol_select(geo_field, field_name) - - return procedure_args, geo_field - - def _spatial_attribute(self, att, settings, field_name=None, model_att=None): - """ - DRY routine for calling a spatial stored procedure on a geometry column - and attaching its output as an attribute of the model. - - Arguments: - att: - The name of the spatial attribute that holds the spatial - SQL function to call. - - settings: - Dictionary of internal settings to customize for the spatial procedure. - - Public Keyword Arguments: - - field_name: - The name of the geographic field to call the spatial - function on. May also be a lookup to a geometry field - as part of a foreign key relation. - - model_att: - The name of the model attribute to attach the output of - the spatial function to. - """ - warnings.warn( - "The %s GeoQuerySet method is deprecated. See GeoDjango Functions " - "documentation to find the expression-based replacement." % att, - RemovedInDjango20Warning, stacklevel=2 - ) - # Default settings. - settings.setdefault('desc', None) - settings.setdefault('geom_args', ()) - settings.setdefault('geom_field', None) - settings.setdefault('procedure_args', {}) - settings.setdefault('procedure_fmt', '%(geo_col)s') - settings.setdefault('select_params', []) - - connection = connections[self.db] - - # Performing setup for the spatial column, unless told not to. - if settings.get('setup', True): - default_args, geo_field = self._spatial_setup( - att, desc=settings['desc'], field_name=field_name, - geo_field_type=settings.get('geo_field_type')) - for k, v in six.iteritems(default_args): - settings['procedure_args'].setdefault(k, v) - else: - geo_field = settings['geo_field'] - - # The attribute to attach to the model. - if not isinstance(model_att, six.string_types): - model_att = att - - # Special handling for any argument that is a geometry. - for name in settings['geom_args']: - # Using the field's get_placeholder() routine to get any needed - # transformation SQL. - geom = geo_field.get_prep_value(settings['procedure_args'][name]) - params = geo_field._get_db_prep_lookup('contains', geom, connection=connection) - geom_placeholder = geo_field.get_placeholder(geom, None, connection) - - # Replacing the procedure format with that of any needed - # transformation SQL. - old_fmt = '%%(%s)s' % name - new_fmt = geom_placeholder % '%%s' - settings['procedure_fmt'] = settings['procedure_fmt'].replace(old_fmt, new_fmt) - settings['select_params'].extend(params) - - # Getting the format for the stored procedure. - fmt = '%%(function)s(%s)' % settings['procedure_fmt'] - - # If the result of this function needs to be converted. - if settings.get('select_field'): - select_field = settings['select_field'] - if connection.ops.oracle: - select_field.empty_strings_allowed = False - else: - select_field = Field() - - # Finally, setting the extra selection attribute with - # the format string expanded with the stored procedure - # arguments. - self.query.add_annotation( - RawSQL(fmt % settings['procedure_args'], settings['select_params'], select_field), - model_att) - return self - - def _distance_attribute(self, func, geom=None, tolerance=0.05, spheroid=False, **kwargs): - """ - DRY routine for GeoQuerySet distance attribute routines. - """ - # Setting up the distance procedure arguments. - procedure_args, geo_field = self._spatial_setup(func, field_name=kwargs.get('field_name')) - - # If geodetic defaulting distance attribute to meters (Oracle and - # PostGIS spherical distances return meters). Otherwise, use the - # units of the geometry field. - connection = connections[self.db] - geodetic = geo_field.geodetic(connection) - geography = geo_field.geography - - if geodetic: - dist_att = 'm' - else: - dist_att = Distance.unit_attname(geo_field.units_name(connection)) - - # Shortcut booleans for what distance function we're using and - # whether the geometry field is 3D. - distance = func == 'distance' - length = func == 'length' - perimeter = func == 'perimeter' - if not (distance or length or perimeter): - raise ValueError('Unknown distance function: %s' % func) - geom_3d = geo_field.dim == 3 - - # The field's _get_db_prep_lookup() is used to get any - # extra distance parameters. Here we set up the - # parameters that will be passed in to field's function. - lookup_params = [geom or 'POINT (0 0)', 0] - - # Getting the spatial backend operations. - backend = connection.ops - - # If the spheroid calculation is desired, either by the `spheroid` - # keyword or when calculating the length of geodetic field, make - # sure the 'spheroid' distance setting string is passed in so we - # get the correct spatial stored procedure. - if spheroid or (backend.postgis and geodetic and - (not geography) and length): - lookup_params.append('spheroid') - lookup_params = geo_field.get_prep_value(lookup_params) - params = geo_field._get_db_prep_lookup('distance_lte', lookup_params, connection=connection) - - # The `geom_args` flag is set to true if a geometry parameter was - # passed in. - geom_args = bool(geom) - - if backend.oracle: - if distance: - procedure_fmt = '%(geo_col)s,%(geom)s,%(tolerance)s' - elif length or perimeter: - procedure_fmt = '%(geo_col)s,%(tolerance)s' - procedure_args['tolerance'] = tolerance - else: - # Getting whether this field is in units of degrees since the field may have - # been transformed via the `transform` GeoQuerySet method. - srid = self.query.get_context('transformed_srid') - if srid: - u, unit_name, s = get_srid_info(srid, connection) - geodetic = unit_name.lower() in geo_field.geodetic_units - - if geodetic and (not connection.features.supports_distance_geodetic or connection.ops.spatialite): - raise ValueError( - 'This database does not support linear distance ' - 'calculations on geodetic coordinate systems.' - ) - - if distance: - if srid: - # Setting the `geom_args` flag to false because we want to handle - # transformation SQL here, rather than the way done by default - # (which will transform to the original SRID of the field rather - # than to what was transformed to). - geom_args = False - procedure_fmt = '%s(%%(geo_col)s, %s)' % (backend.transform, srid) - if geom.srid is None or geom.srid == srid: - # If the geom parameter srid is None, it is assumed the coordinates - # are in the transformed units. A placeholder is used for the - # geometry parameter. `GeomFromText` constructor is also needed - # to wrap geom placeholder for SpatiaLite. - if backend.spatialite: - procedure_fmt += ', %s(%%%%s, %s)' % (backend.from_text, srid) - else: - procedure_fmt += ', %%s' - else: - # We need to transform the geom to the srid specified in `transform()`, - # so wrapping the geometry placeholder in transformation SQL. - # SpatiaLite also needs geometry placeholder wrapped in `GeomFromText` - # constructor. - if backend.spatialite: - procedure_fmt += (', %s(%s(%%%%s, %s), %s)' % ( - backend.transform, backend.from_text, - geom.srid, srid)) - else: - procedure_fmt += ', %s(%%%%s, %s)' % (backend.transform, srid) - else: - # `transform()` was not used on this GeoQuerySet. - procedure_fmt = '%(geo_col)s,%(geom)s' - - if not geography and geodetic: - # Spherical distance calculation is needed (because the geographic - # field is geodetic). However, the PostGIS ST_distance_sphere/spheroid() - # procedures may only do queries from point columns to point geometries - # some error checking is required. - if not backend.geography: - if not isinstance(geo_field, PointField): - raise ValueError('Spherical distance calculation only supported on PointFields.') - if not str(Geometry(six.memoryview(params[0].ewkb)).geom_type) == 'Point': - raise ValueError( - 'Spherical distance calculation only supported with ' - 'Point Geometry parameters' - ) - # The `function` procedure argument needs to be set differently for - # geodetic distance calculations. - if spheroid: - # Call to distance_spheroid() requires spheroid param as well. - procedure_fmt += ",'%(spheroid)s'" - procedure_args.update({'function': backend.distance_spheroid, 'spheroid': params[1]}) - else: - procedure_args.update({'function': backend.distance_sphere}) - elif length or perimeter: - procedure_fmt = '%(geo_col)s' - if not geography and geodetic and length: - # There's no `length_sphere`, and `length_spheroid` also - # works on 3D geometries. - procedure_fmt += ",'%(spheroid)s'" - procedure_args.update({'function': backend.length_spheroid, 'spheroid': params[1]}) - elif geom_3d and connection.features.supports_3d_functions: - # Use 3D variants of perimeter and length routines on supported backends. - if perimeter: - procedure_args.update({'function': backend.perimeter3d}) - elif length: - procedure_args.update({'function': backend.length3d}) - - # Setting up the settings for `_spatial_attribute`. - s = {'select_field': DistanceField(dist_att), - 'setup': False, - 'geo_field': geo_field, - 'procedure_args': procedure_args, - 'procedure_fmt': procedure_fmt, - } - if geom_args: - s['geom_args'] = ('geom',) - s['procedure_args']['geom'] = geom - elif geom: - # The geometry is passed in as a parameter because we handled - # transformation conditions in this routine. - s['select_params'] = [backend.Adapter(geom)] - return self._spatial_attribute(func, s, **kwargs) - - def _geom_attribute(self, func, tolerance=0.05, **kwargs): - """ - DRY routine for setting up a GeoQuerySet method that attaches a - Geometry attribute (e.g., `centroid`, `point_on_surface`). - """ - s = {'select_field': GeomField()} - if connections[self.db].ops.oracle: - s['procedure_fmt'] = '%(geo_col)s,%(tolerance)s' - s['procedure_args'] = {'tolerance': tolerance} - return self._spatial_attribute(func, s, **kwargs) - - def _geomset_attribute(self, func, geom, tolerance=0.05, **kwargs): - """ - DRY routine for setting up a GeoQuerySet method that attaches a - Geometry attribute and takes a Geoemtry parameter. This is used - for geometry set-like operations (e.g., intersection, difference, - union, sym_difference). - """ - s = { - 'geom_args': ('geom',), - 'select_field': GeomField(), - 'procedure_fmt': '%(geo_col)s,%(geom)s', - 'procedure_args': {'geom': geom}, - } - if connections[self.db].ops.oracle: - s['procedure_fmt'] += ',%(tolerance)s' - s['procedure_args']['tolerance'] = tolerance - return self._spatial_attribute(func, s, **kwargs) - - def _geocol_select(self, geo_field, field_name): - """ - Helper routine for constructing the SQL to select the geographic - column. Takes into account if the geographic field is in a - ForeignKey relation to the current model. - """ - compiler = self.query.get_compiler(self.db) - opts = self.model._meta - if geo_field not in opts.fields: - # Is this operation going to be on a related geographic field? - # If so, it'll have to be added to the select related information - # (e.g., if 'location__point' was given as the field name, then - # chop the non-relational field and add select_related('location')). - # Note: the operation really is defined as "must add select related!" - self.query.add_select_related([field_name.rsplit(LOOKUP_SEP, 1)[0]]) - # Call pre_sql_setup() so that compiler.select gets populated. - compiler.pre_sql_setup() - for col, _, _ in compiler.select: - if col.output_field == geo_field: - return col.as_sql(compiler, compiler.connection)[0] - raise ValueError("%r not in compiler's related_select_cols" % geo_field) - elif geo_field not in opts.local_fields: - # This geographic field is inherited from another model, so we have to - # use the db table for the _parent_ model instead. - parent_model = geo_field.model._meta.concrete_model - return self._field_column(compiler, geo_field, parent_model._meta.db_table) - else: - return self._field_column(compiler, geo_field) - - # Private API utilities, subject to change. - def _geo_field(self, field_name=None): - """ - Returns the first Geometry field encountered or the one specified via - the `field_name` keyword. The `field_name` may be a string specifying - the geometry field on this GeoQuerySet's model, or a lookup string - to a geometry field via a ForeignKey relation. - """ - if field_name is None: - # Incrementing until the first geographic field is found. - for field in self.model._meta.fields: - if isinstance(field, GeometryField): - return field - return False - else: - # Otherwise, check by the given field name -- which may be - # a lookup to a _related_ geographic field. - return GISLookup._check_geo_field(self.model._meta, field_name) - - def _field_column(self, compiler, field, table_alias=None, column=None): - """ - Helper function that returns the database column for the given field. - The table and column are returned (quoted) in the proper format, e.g., - `"geoapp_city"."point"`. If `table_alias` is not specified, the - database table associated with the model of this `GeoQuerySet` will be - used. If `column` is specified, it will be used instead of the value - in `field.column`. - """ - if table_alias is None: - table_alias = compiler.query.get_meta().db_table - return "%s.%s" % (compiler.quote_name_unless_alias(table_alias), - compiler.connection.ops.quote_name(column or field.column)) diff --git a/docs/ref/contrib/gis/geoquerysets.txt b/docs/ref/contrib/gis/geoquerysets.txt index 99bc4afbe4a1..8213e0292da4 100644 --- a/docs/ref/contrib/gis/geoquerysets.txt +++ b/docs/ref/contrib/gis/geoquerysets.txt @@ -1,11 +1,9 @@ -========================= -GeoQuerySet API Reference -========================= +========================== +GIS QuerySet API Reference +========================== .. currentmodule:: django.contrib.gis.db.models -.. class:: GeoQuerySet(model=None) - .. _spatial-lookups: Spatial Lookups @@ -720,593 +718,6 @@ SpatiaLite ``PtDistWithin(poly, geom, 5)`` SpatiaLite support was added. -.. _geoqueryset-methods: - -``GeoQuerySet`` Methods -======================= - -.. deprecated:: 1.9 - - Using ``GeoQuerySet`` methods is now deprecated in favor of the new - :doc:`functions`. Albeit a little more verbose, they are much more powerful - in how it is possible to combine them to build more complex queries. - -``GeoQuerySet`` methods specify that a spatial operation be performed -on each spatial operation on each geographic -field in the queryset and store its output in a new attribute on the model -(which is generally the name of the ``GeoQuerySet`` method). - -There are also aggregate ``GeoQuerySet`` methods which return a single value -instead of a queryset. This section will describe the API and availability -of every ``GeoQuerySet`` method available in GeoDjango. - -.. note:: - - What methods are available depend on your spatial backend. See - the :ref:`compatibility table ` - for more details. - -With a few exceptions, the following keyword arguments may be used with all -``GeoQuerySet`` methods: - -===================== ===================================================== -Keyword Argument Description -===================== ===================================================== -``field_name`` By default, ``GeoQuerySet`` methods use the first - geographic field encountered in the model. This - keyword should be used to specify another - geographic field (e.g., ``field_name='point2'``) - when there are multiple geographic fields in a model. - - On PostGIS, the ``field_name`` keyword may also be - used on geometry fields in models that are related - via a ``ForeignKey`` relation (e.g., - ``field_name='related__point'``). - -``model_att`` By default, ``GeoQuerySet`` methods typically attach - their output in an attribute with the same name as - the ``GeoQuerySet`` method. Setting this keyword - with the desired attribute name will override this - default behavior. For example, - ``qs = Zipcode.objects.centroid(model_att='c')`` will - attach the centroid of the ``Zipcode`` geometry field - in a ``c`` attribute on every model rather than in a - ``centroid`` attribute. - - This keyword is required if - a method name clashes with an existing - ``GeoQuerySet`` method -- if you wanted to use the - ``area()`` method on model with a ``PolygonField`` - named ``area``, for example. -===================== ===================================================== - -Measurement ------------ -*Availability*: PostGIS, Oracle, SpatiaLite - -``area`` -~~~~~~~~ - -.. method:: GeoQuerySet.area(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.Area` function - instead. - -Returns the area of the geographic field in an ``area`` attribute on -each element of this GeoQuerySet. - -``distance`` -~~~~~~~~~~~~ - -.. method:: GeoQuerySet.distance(geom, **kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.Distance` function - instead. - -This method takes a geometry as a parameter, and attaches a ``distance`` -attribute to every model in the returned queryset that contains the -distance (as a :class:`~django.contrib.gis.measure.Distance` object) to the given geometry. - -In the following example (taken from the `GeoDjango distance tests`__), -the distance from the `Tasmanian`__ city of Hobart to every other -:class:`PointField` in the ``AustraliaCity`` queryset is calculated:: - - >>> pnt = AustraliaCity.objects.get(name='Hobart').point - >>> for city in AustraliaCity.objects.distance(pnt): print(city.name, city.distance) - Wollongong 990071.220408 m - Shellharbour 972804.613941 m - Thirroul 1002334.36351 m - Mittagong 975691.632637 m - Batemans Bay 834342.185561 m - Canberra 598140.268959 m - Melbourne 575337.765042 m - Sydney 1056978.87363 m - Hobart 0.0 m - Adelaide 1162031.83522 m - Hillsdale 1049200.46122 m - -.. note:: - - Because the ``distance`` attribute is a - :class:`~django.contrib.gis.measure.Distance` object, you can easily express - the value in the units of your choice. For example, ``city.distance.mi`` is - the distance value in miles and ``city.distance.km`` is the distance value - in kilometers. See :doc:`measure` for usage details and the list of - :ref:`supported_units`. - -__ https://github.com/django/django/blob/master/tests/gis_tests/distapp/models.py -__ https://en.wikipedia.org/wiki/Tasmania - -``length`` -~~~~~~~~~~ - -.. method:: GeoQuerySet.length(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.Length` function - instead. - -Returns the length of the geometry field in a ``length`` attribute -(a :class:`~django.contrib.gis.measure.Distance` object) on each model in -the queryset. - -``perimeter`` -~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.perimeter(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.Perimeter` function - instead. - -Returns the perimeter of the geometry field in a ``perimeter`` attribute -(a :class:`~django.contrib.gis.measure.Distance` object) on each model in -the queryset. - -Geometry Relationships ----------------------- - -The following methods take no arguments, and attach geometry objects -each element of the :class:`GeoQuerySet` that is the result of relationship -function evaluated on the geometry field. - -``centroid`` -~~~~~~~~~~~~ - -.. method:: GeoQuerySet.centroid(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.Centroid` function - instead. - -*Availability*: PostGIS, Oracle, SpatiaLite - -Returns the ``centroid`` value for the geographic field in a ``centroid`` -attribute on each element of the ``GeoQuerySet``. - -``envelope`` -~~~~~~~~~~~~ - -.. method:: GeoQuerySet.envelope(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.Envelope` function - instead. - -*Availability*: PostGIS, SpatiaLite - -Returns a geometry representing the bounding box of the geometry field in -an ``envelope`` attribute on each element of the ``GeoQuerySet``. - -``point_on_surface`` -~~~~~~~~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.point_on_surface(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.PointOnSurface` - function instead. - -*Availability*: PostGIS, Oracle, SpatiaLite - -Returns a Point geometry guaranteed to lie on the surface of the -geometry field in a ``point_on_surface`` attribute on each element -of the queryset; otherwise sets with None. - -Geometry Editors ----------------- - -``force_rhr`` -~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.force_rhr(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.ForceRHR` function - instead. - -*Availability*: PostGIS - -Returns a modified version of the polygon/multipolygon in which all -of the vertices follow the Right-Hand-Rule, and attaches as a -``force_rhr`` attribute on each element of the queryset. - -``reverse_geom`` -~~~~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.reverse_geom(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.Reverse` function - instead. - -*Availability*: PostGIS, Oracle - -Reverse the coordinate order of the geometry field, and attaches as a -``reverse`` attribute on each element of the queryset. - -``scale`` -~~~~~~~~~ - -.. method:: GeoQuerySet.scale(x, y, z=0.0, **kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.Scale` function - instead. - -*Availability*: PostGIS, SpatiaLite - -``snap_to_grid`` -~~~~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.snap_to_grid(*args, **kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.SnapToGrid` function - instead. - -Snap all points of the input geometry to the grid. How the -geometry is snapped to the grid depends on how many numeric -(either float, integer, or long) arguments are given. - -=================== ===================================================== -Number of Arguments Description -=================== ===================================================== -1 A single size to snap bot the X and Y grids to. -2 X and Y sizes to snap the grid to. -4 X, Y sizes and the corresponding X, Y origins. -=================== ===================================================== - -``transform`` -~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.transform(srid=4326, **kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.Transform` function - instead. - -*Availability*: PostGIS, Oracle, SpatiaLite - -The ``transform`` method transforms the geometry field of a model to the spatial -reference system specified by the ``srid`` parameter. If no ``srid`` is given, -then 4326 (WGS84) is used by default. - -.. note:: - - Unlike other ``GeoQuerySet`` methods, ``transform`` stores its output - "in-place". In other words, no new attribute for the transformed - geometry is placed on the models. - -.. note:: - - What spatial reference system an integer SRID corresponds to may depend on - the spatial database used. In other words, the SRID numbers used for Oracle - are not necessarily the same as those used by PostGIS. - -Example:: - - >>> qs = Zipcode.objects.all().transform() # Transforms to WGS84 - >>> qs = Zipcode.objects.all().transform(32140) # Transforming to "NAD83 / Texas South Central" - >>> print(qs[0].poly.srid) - 32140 - >>> print(qs[0].poly) - POLYGON ((234055.1698884720099159 4937796.9232223574072123 ... - -``translate`` -~~~~~~~~~~~~~ -.. method:: GeoQuerySet.translate(x, y, z=0.0, **kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.Translate` function - instead. - -*Availability*: PostGIS, SpatiaLite - -Translates the geometry field to a new location using the given numeric -parameters as offsets. - -Geometry Operations -------------------- -*Availability*: PostGIS, Oracle, SpatiaLite - -The following methods all take a geometry as a parameter and attach a geometry -to each element of the ``GeoQuerySet`` that is the result of the operation. - -``difference`` -~~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.difference(geom) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.Difference` function - instead. - -Returns the spatial difference of the geographic field with the given -geometry in a ``difference`` attribute on each element of the -``GeoQuerySet``. - - -``intersection`` -~~~~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.intersection(geom) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.Intersection` - function instead. - -Returns the spatial intersection of the geographic field with the -given geometry in an ``intersection`` attribute on each element of the -``GeoQuerySet``. - -``sym_difference`` -~~~~~~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.sym_difference(geom) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.SymDifference` - function instead. - -Returns the symmetric difference of the geographic field with the -given geometry in a ``sym_difference`` attribute on each element of the -``GeoQuerySet``. - -``union`` -~~~~~~~~~ - -.. method:: GeoQuerySet.union(geom) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.Union` function - instead. - -Returns the union of the geographic field with the given -geometry in an ``union`` attribute on each element of the -``GeoQuerySet``. - -Geometry Output ---------------- - -The following ``GeoQuerySet`` methods will return an attribute that has the value -of the geometry field in each model converted to the requested output format. - -``geohash`` -~~~~~~~~~~~ - -.. method:: GeoQuerySet.geohash(precision=20, **kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.GeoHash` function - instead. - -Attaches a ``geohash`` attribute to every model the queryset -containing the `GeoHash`__ representation of the geometry. - -__ http://geohash.org/ - -``geojson`` -~~~~~~~~~~~ - -.. method:: GeoQuerySet.geojson(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.AsGeoJSON` function - instead. - -*Availability*: PostGIS, SpatiaLite - -Attaches a ``geojson`` attribute to every model in the queryset that contains the -`GeoJSON`__ representation of the geometry. - -===================== ===================================================== -Keyword Argument Description -===================== ===================================================== -``precision`` It may be used to specify the number of significant - digits for the coordinates in the GeoJSON - representation -- the default value is 8. - -``crs`` Set this to ``True`` if you want the coordinate - reference system to be included in the returned - GeoJSON. - -``bbox`` Set this to ``True`` if you want the bounding box - to be included in the returned GeoJSON. -===================== ===================================================== - -__ http://geojson.org/ - -``gml`` -~~~~~~~ - -.. method:: GeoQuerySet.gml(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.AsGML` function - instead. - -*Availability*: PostGIS, Oracle, SpatiaLite - -Attaches a ``gml`` attribute to every model in the queryset that contains the -`Geographic Markup Language (GML)`__ representation of the geometry. - -Example:: - - >>> qs = Zipcode.objects.all().gml() - >>> print(qs[0].gml) - -147.78711,70.245363 ... -147.78711,70.245363 - -===================== ===================================================== -Keyword Argument Description -===================== ===================================================== -``precision`` This keyword is for PostGIS only. It may be used - to specify the number of significant digits for the - coordinates in the GML representation -- the default - value is 8. - -``version`` This keyword is for PostGIS only. It may be used to - specify the GML version used, and may only be values - of 2 or 3. The default value is 2. -===================== ===================================================== - -__ https://en.wikipedia.org/wiki/Geography_Markup_Language - -``kml`` -~~~~~~~ - -.. method:: GeoQuerySet.kml(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.AsKML` function - instead. - -*Availability*: PostGIS, SpatiaLite - -Attaches a ``kml`` attribute to every model in the queryset that contains the -`Keyhole Markup Language (KML)`__ representation of the geometry fields. It -should be noted that the contents of the KML are transformed to WGS84 if -necessary. - -Example:: - - >>> qs = Zipcode.objects.all().kml() - >>> print(qs[0].kml) - -103.04135,36.217596,0 ... -103.04135,36.217596,0 - -===================== ===================================================== -Keyword Argument Description -===================== ===================================================== -``precision`` This keyword may be used to specify the number of - significant digits for the coordinates in the KML - representation -- the default value is 8. -===================== ===================================================== - -__ https://developers.google.com/kml/documentation/ - -``svg`` -~~~~~~~ - -.. method:: GeoQuerySet.svg(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.AsSVG` function - instead. - -*Availability*: PostGIS, SpatiaLite - -Attaches a ``svg`` attribute to every model in the queryset that contains -the `Scalable Vector Graphics (SVG)`__ path data of the geometry fields. - -===================== ===================================================== -Keyword Argument Description -===================== ===================================================== -``relative`` If set to ``True``, the path data will be implemented - in terms of relative moves. Defaults to ``False``, - meaning that absolute moves are used instead. - -``precision`` This keyword may be used to specify the number of - significant digits for the coordinates in the SVG - representation -- the default value is 8. -===================== ===================================================== - -__ http://www.w3.org/Graphics/SVG/ - -Miscellaneous -------------- - -``mem_size`` -~~~~~~~~~~~~ - -.. method:: GeoQuerySet.mem_size(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.MemSize` function - instead. - -*Availability*: PostGIS - -Returns the memory size (number of bytes) that the geometry field takes -in a ``mem_size`` attribute on each element of the ``GeoQuerySet``. - -``num_geom`` -~~~~~~~~~~~~ - -.. method:: GeoQuerySet.num_geom(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.NumGeometries` - function instead. - -*Availability*: PostGIS, Oracle, SpatiaLite - -Returns the number of geometries in a ``num_geom`` attribute on -each element of the ``GeoQuerySet`` if the geometry field is a -collection (e.g., a ``GEOMETRYCOLLECTION`` or ``MULTI*`` field); -otherwise sets with ``None``. - -``num_points`` -~~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.num_points(**kwargs) - -.. deprecated:: 1.9 - - Use the :class:`~django.contrib.gis.db.models.functions.NumPoints` function - instead. - -*Availability*: PostGIS, Oracle, SpatiaLite - -Returns the number of points in the first linestring in the -geometry field in a ``num_points`` attribute on each element of -the ``GeoQuerySet``; otherwise sets with ``None``. - Aggregate Functions ------------------- diff --git a/docs/ref/contrib/gis/model-api.txt b/docs/ref/contrib/gis/model-api.txt index 732b3f8f6ffa..54a6df4dc4c0 100644 --- a/docs/ref/contrib/gis/model-api.txt +++ b/docs/ref/contrib/gis/model-api.txt @@ -244,22 +244,6 @@ For more information, the PostGIS documentation contains a helpful section on determining `when to use geography data type over geometry data type `_. -``GeoManager`` -============== - -.. currentmodule:: django.contrib.gis.db.models -.. class:: GeoManager - -The ``GeoManager`` is required in order to use the legacy -:ref:`geoqueryset-methods`. - -.. deprecated:: 1.9 - - All ``GeoQuerySet`` methods have been deprecated and replaced by - :doc:`equivalent database functions `. As soon - as the legacy methods have been replaced in your code, you should be able - to remove the special ``GeoManager`` from your GIS-enabled classes. - .. rubric:: Footnotes .. [#fnogc] OpenGIS Consortium, Inc., `Simple Feature Specification For SQL `_. .. [#fnogcsrid] *See id.* at Ch. 2.3.8, p. 39 (Geometry Values and Spatial Reference Systems). diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index f5f0fbcc8b0a..ee48a3c6f0b1 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -149,11 +149,10 @@ Here's the formal declaration of a ``QuerySet``: .. note:: The ``query`` parameter to :class:`QuerySet` exists so that specialized - query subclasses such as - :class:`~django.contrib.gis.db.models.GeoQuerySet` can reconstruct - internal query state. The value of the parameter is an opaque - representation of that query state and is not part of a public API. - To put it simply: if you need to ask, you don't need to use it. + query subclasses can reconstruct internal query state. The value of the + parameter is an opaque representation of that query state and is not + part of a public API. To put it simply: if you need to ask, you don't + need to use it. .. currentmodule:: django.db.models.query.QuerySet diff --git a/docs/releases/1.2.txt b/docs/releases/1.2.txt index c2676a90cc38..3995ee7192c3 100644 --- a/docs/releases/1.2.txt +++ b/docs/releases/1.2.txt @@ -359,12 +359,8 @@ keyword to 3 in your :class:`~django.contrib.gis.db.models.GeometryField`. The :class:`~django.contrib.gis.db.models.Extent3D` aggregate and ``extent3d()`` ``GeoQuerySet`` method were added as a part of this feature. -The following :class:`~django.contrib.gis.db.models.GeoQuerySet` -methods are new in 1.2: - -* :meth:`~django.contrib.gis.db.models.GeoQuerySet.force_rhr` -* :meth:`~django.contrib.gis.db.models.GeoQuerySet.reverse_geom` -* :meth:`~django.contrib.gis.db.models.GeoQuerySet.geohash` +The ``force_rhr()``, ``reverse_geom()``, and ``geohash()`` ``GeoQuerySet`` +methods are new. The GEOS interface was updated to use thread-safe C library functions when available on the platform. diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index c87faba78370..88b24e9b553f 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -261,3 +261,5 @@ these features. ORM, e.g. with ``cursor.execute()``. * ``django.contrib.auth.tests.utils.skipIfCustomUser()`` is removed. + +* The ``GeoManager`` and ``GeoQuerySet`` classes are removed. diff --git a/tests/gis_tests/distapp/models.py b/tests/gis_tests/distapp/models.py index be4cf50f9590..43a2acacdff4 100644 --- a/tests/gis_tests/distapp/models.py +++ b/tests/gis_tests/distapp/models.py @@ -8,8 +8,6 @@ class NamedModel(models.Model): name = models.CharField(max_length=30) - objects = models.GeoManager() - class Meta: abstract = True required_db_features = ['gis_enabled'] diff --git a/tests/gis_tests/distapp/tests.py b/tests/gis_tests/distapp/tests.py index 3079afb9d73b..01f0a620dc16 100644 --- a/tests/gis_tests/distapp/tests.py +++ b/tests/gis_tests/distapp/tests.py @@ -1,7 +1,5 @@ from __future__ import unicode_literals -from unittest import skipIf - from django.contrib.gis.db.models.functions import ( Area, Distance, Length, Perimeter, Transform, ) @@ -9,8 +7,7 @@ from django.contrib.gis.measure import D # alias for Distance from django.db import connection from django.db.models import F, Q -from django.test import TestCase, ignore_warnings, skipUnlessDBFeature -from django.utils.deprecation import RemovedInDjango20Warning +from django.test import TestCase, skipUnlessDBFeature from ..utils import no_oracle, oracle, postgis, spatialite from .models import ( @@ -101,136 +98,6 @@ def test_dwithin(self): else: self.assertListEqual(au_cities, self.get_names(qs.filter(point__dwithin=(self.au_pnt, dist)))) - @skipUnlessDBFeature("has_distance_method") - @ignore_warnings(category=RemovedInDjango20Warning) - def test_distance_projected(self): - """ - Test the `distance` GeoQuerySet method on projected coordinate systems. - """ - # The point for La Grange, TX - lagrange = GEOSGeometry('POINT(-96.876369 29.905320)', 4326) - # Reference distances in feet and in meters. Got these values from - # using the provided raw SQL statements. - # SELECT ST_Distance(point, ST_Transform(ST_GeomFromText('POINT(-96.876369 29.905320)', 4326), 32140)) - # FROM distapp_southtexascity; - m_distances = [147075.069813, 139630.198056, 140888.552826, - 138809.684197, 158309.246259, 212183.594374, - 70870.188967, 165337.758878, 139196.085105] - # SELECT ST_Distance(point, ST_Transform(ST_GeomFromText('POINT(-96.876369 29.905320)', 4326), 2278)) - # FROM distapp_southtexascityft; - # Oracle 11 thinks this is not a projected coordinate system, so it's - # not tested. - ft_distances = [482528.79154625, 458103.408123001, 462231.860397575, - 455411.438904354, 519386.252102563, 696139.009211594, - 232513.278304279, 542445.630586414, 456679.155883207] - - # Testing using different variations of parameters and using models - # with different projected coordinate systems. - dist1 = SouthTexasCity.objects.distance(lagrange, field_name='point').order_by('id') - dist2 = SouthTexasCity.objects.distance(lagrange).order_by('id') # Using GEOSGeometry parameter - if oracle: - dist_qs = [dist1, dist2] - else: - dist3 = SouthTexasCityFt.objects.distance(lagrange.ewkt).order_by('id') # Using EWKT string parameter. - dist4 = SouthTexasCityFt.objects.distance(lagrange).order_by('id') - dist_qs = [dist1, dist2, dist3, dist4] - - # Original query done on PostGIS, have to adjust AlmostEqual tolerance - # for Oracle. - tol = 2 if oracle else 5 - - # Ensuring expected distances are returned for each distance queryset. - for qs in dist_qs: - for i, c in enumerate(qs): - self.assertAlmostEqual(m_distances[i], c.distance.m, tol) - self.assertAlmostEqual(ft_distances[i], c.distance.survey_ft, tol) - - @skipIf(spatialite, "distance method doesn't support geodetic coordinates on SpatiaLite.") - @skipUnlessDBFeature("has_distance_method", "supports_distance_geodetic") - @ignore_warnings(category=RemovedInDjango20Warning) - def test_distance_geodetic(self): - """ - Test the `distance` GeoQuerySet method on geodetic coordinate systems. - """ - tol = 2 if oracle else 4 - - # Testing geodetic distance calculation with a non-point geometry - # (a LineString of Wollongong and Shellharbour coords). - ls = LineString(((150.902, -34.4245), (150.87, -34.5789))) - - # Reference query: - # SELECT ST_distance_sphere(point, ST_GeomFromText('LINESTRING(150.9020 -34.4245,150.8700 -34.5789)', 4326)) - # FROM distapp_australiacity ORDER BY name; - distances = [1120954.92533513, 140575.720018241, 640396.662906304, - 60580.9693849269, 972807.955955075, 568451.8357838, - 40435.4335201384, 0, 68272.3896586844, 12375.0643697706, 0] - qs = AustraliaCity.objects.distance(ls).order_by('name') - for city, distance in zip(qs, distances): - # Testing equivalence to within a meter. - self.assertAlmostEqual(distance, city.distance.m, 0) - - # Got the reference distances using the raw SQL statements: - # SELECT ST_distance_spheroid(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326), - # 'SPHEROID["WGS 84",6378137.0,298.257223563]') FROM distapp_australiacity WHERE (NOT (id = 11)); - # SELECT ST_distance_sphere(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326)) - # FROM distapp_australiacity WHERE (NOT (id = 11)); st_distance_sphere - spheroid_distances = [ - 60504.0628957201, 77023.9489850262, 49154.8867574404, - 90847.4358768573, 217402.811919332, 709599.234564757, - 640011.483550888, 7772.00667991925, 1047861.78619339, - 1165126.55236034, - ] - sphere_distances = [ - 60580.9693849267, 77144.0435286473, 49199.4415344719, - 90804.7533823494, 217713.384600405, 709134.127242793, - 639828.157159169, 7786.82949717788, 1049204.06569028, - 1162623.7238134, - ] - # Testing with spheroid distances first. - hillsdale = AustraliaCity.objects.get(name='Hillsdale') - qs = AustraliaCity.objects.exclude(id=hillsdale.id).distance(hillsdale.point, spheroid=True).order_by('id') - for i, c in enumerate(qs): - self.assertAlmostEqual(spheroid_distances[i], c.distance.m, tol) - if postgis: - # PostGIS uses sphere-only distances by default, testing these as well. - qs = AustraliaCity.objects.exclude(id=hillsdale.id).distance(hillsdale.point).order_by('id') - for i, c in enumerate(qs): - self.assertAlmostEqual(sphere_distances[i], c.distance.m, tol) - - @no_oracle # Oracle already handles geographic distance calculation. - @skipUnlessDBFeature("has_distance_method") - @ignore_warnings(category=RemovedInDjango20Warning) - def test_distance_transform(self): - """ - Test the `distance` GeoQuerySet method used with `transform` on a geographic field. - """ - # We'll be using a Polygon (created by buffering the centroid - # of 77005 to 100m) -- which aren't allowed in geographic distance - # queries normally, however our field has been transformed to - # a non-geographic system. - z = SouthTexasZipcode.objects.get(name='77005') - - # Reference query: - # SELECT ST_Distance(ST_Transform("distapp_censuszipcode"."poly", 32140), - # ST_GeomFromText('', 32140)) - # FROM "distapp_censuszipcode"; - dists_m = [3553.30384972258, 1243.18391525602, 2186.15439472242] - - # Having our buffer in the SRID of the transformation and of the field - # -- should get the same results. The first buffer has no need for - # transformation SQL because it is the same SRID as what was given - # to `transform()`. The second buffer will need to be transformed, - # however. - buf1 = z.poly.centroid.buffer(100) - buf2 = buf1.transform(4269, clone=True) - ref_zips = ['77002', '77025', '77401'] - - for buf in [buf1, buf2]: - qs = CensusZipcode.objects.exclude(name='77005').transform(32140).distance(buf).order_by('name') - self.assertListEqual(ref_zips, self.get_names(qs)) - for i, z in enumerate(qs): - self.assertAlmostEqual(z.distance.m, dists_m[i], 5) - @skipUnlessDBFeature("supports_distances_lookups") def test_distance_lookups(self): """ @@ -347,86 +214,6 @@ def test_distance_lookups_with_expression_rhs(self): ).order_by('name') self.assertEqual(self.get_names(qs), ['Canberra', 'Hobart', 'Melbourne']) - @skipUnlessDBFeature("has_area_method") - @ignore_warnings(category=RemovedInDjango20Warning) - def test_area(self): - """ - Test the `area` GeoQuerySet method. - """ - # Reference queries: - # SELECT ST_Area(poly) FROM distapp_southtexaszipcode; - area_sq_m = [5437908.90234375, 10183031.4389648, 11254471.0073242, 9881708.91772461] - # Tolerance has to be lower for Oracle - tol = 2 - for i, z in enumerate(SouthTexasZipcode.objects.order_by('name').area()): - self.assertAlmostEqual(area_sq_m[i], z.area.sq_m, tol) - - @skipIf(spatialite, "length method doesn't support geodetic coordinates on SpatiaLite.") - @skipUnlessDBFeature("has_length_method") - @ignore_warnings(category=RemovedInDjango20Warning) - def test_length(self): - """ - Test the `length` GeoQuerySet method. - """ - # Reference query (should use `length_spheroid`). - # SELECT ST_length_spheroid(ST_GeomFromText('', 4326) 'SPHEROID["WGS 84",6378137,298.257223563, - # AUTHORITY["EPSG","7030"]]'); - len_m1 = 473504.769553813 - len_m2 = 4617.668 - - if connection.features.supports_distance_geodetic: - qs = Interstate.objects.length() - tol = 2 if oracle else 3 - self.assertAlmostEqual(len_m1, qs[0].length.m, tol) - else: - # Does not support geodetic coordinate systems. - with self.assertRaises(ValueError): - Interstate.objects.length() - - # Now doing length on a projected coordinate system. - i10 = SouthTexasInterstate.objects.length().get(name='I-10') - self.assertAlmostEqual(len_m2, i10.length.m, 2) - - @skipUnlessDBFeature("has_perimeter_method") - @ignore_warnings(category=RemovedInDjango20Warning) - def test_perimeter(self): - """ - Test the `perimeter` GeoQuerySet method. - """ - # Reference query: - # SELECT ST_Perimeter(distapp_southtexaszipcode.poly) FROM distapp_southtexaszipcode; - perim_m = [18404.3550889361, 15627.2108551001, 20632.5588368978, 17094.5996143697] - tol = 2 if oracle else 7 - for i, z in enumerate(SouthTexasZipcode.objects.order_by('name').perimeter()): - self.assertAlmostEqual(perim_m[i], z.perimeter.m, tol) - - # Running on points; should return 0. - for i, c in enumerate(SouthTexasCity.objects.perimeter(model_att='perim')): - self.assertEqual(0, c.perim.m) - - @skipUnlessDBFeature("has_area_method", "has_distance_method") - @ignore_warnings(category=RemovedInDjango20Warning) - def test_measurement_null_fields(self): - """ - Test the measurement GeoQuerySet methods on fields with NULL values. - """ - # Creating SouthTexasZipcode w/NULL value. - SouthTexasZipcode.objects.create(name='78212') - # Performing distance/area queries against the NULL PolygonField, - # and ensuring the result of the operations is None. - htown = SouthTexasCity.objects.get(name='Downtown Houston') - z = SouthTexasZipcode.objects.distance(htown.point).area().get(name='78212') - self.assertIsNone(z.distance) - self.assertIsNone(z.area) - - @skipUnlessDBFeature("has_distance_method") - @ignore_warnings(category=RemovedInDjango20Warning) - def test_distance_order_by(self): - qs = SouthTexasCity.objects.distance(Point(3, 3)).order_by( - 'distance' - ).values_list('name', flat=True).filter(name__in=('San Antonio', 'Pearland')) - self.assertSequenceEqual(qs, ['San Antonio', 'Pearland']) - ''' ============================= diff --git a/tests/gis_tests/geo3d/models.py b/tests/gis_tests/geo3d/models.py index f2ea0e02d9c3..42467c5ce483 100644 --- a/tests/gis_tests/geo3d/models.py +++ b/tests/gis_tests/geo3d/models.py @@ -6,8 +6,6 @@ class NamedModel(models.Model): name = models.CharField(max_length=30) - objects = models.GeoManager() - class Meta: abstract = True required_db_features = ['gis_enabled'] diff --git a/tests/gis_tests/geo3d/tests.py b/tests/gis_tests/geo3d/tests.py index f180387aac81..946928b91936 100644 --- a/tests/gis_tests/geo3d/tests.py +++ b/tests/gis_tests/geo3d/tests.py @@ -8,9 +8,8 @@ AsGeoJSON, AsKML, Length, Perimeter, Scale, Translate, ) from django.contrib.gis.geos import GEOSGeometry, LineString, Point, Polygon -from django.test import TestCase, ignore_warnings, skipUnlessDBFeature +from django.test import TestCase, skipUnlessDBFeature from django.utils._os import upath -from django.utils.deprecation import RemovedInDjango20Warning from .models import ( City3D, Interstate2D, Interstate3D, InterstateProj2D, InterstateProj3D, @@ -171,30 +170,6 @@ def test_3d_layermapping(self): lm.save() self.assertEqual(3, MultiPoint3D.objects.count()) - @ignore_warnings(category=RemovedInDjango20Warning) - def test_kml(self): - """ - Test GeoQuerySet.kml() with Z values. - """ - self._load_city_data() - h = City3D.objects.kml(precision=6).get(name='Houston') - # KML should be 3D. - # `SELECT ST_AsKML(point, 6) FROM geo3d_city3d WHERE name = 'Houston';` - ref_kml_regex = re.compile(r'^-95.363\d+,29.763\d+,18$') - self.assertTrue(ref_kml_regex.match(h.kml)) - - @ignore_warnings(category=RemovedInDjango20Warning) - def test_geojson(self): - """ - Test GeoQuerySet.geojson() with Z values. - """ - self._load_city_data() - h = City3D.objects.geojson(precision=6).get(name='Houston') - # GeoJSON should be 3D - # `SELECT ST_AsGeoJSON(point, 6) FROM geo3d_city3d WHERE name='Houston';` - ref_json_regex = re.compile(r'^{"type":"Point","coordinates":\[-95.363151,29.763374,18(\.0+)?\]}$') - self.assertTrue(ref_json_regex.match(h.geojson)) - @skipUnlessDBFeature("supports_3d_functions") def test_union(self): """ @@ -231,84 +206,6 @@ def check_extent3d(extent3d, tol=6): check_extent3d(extent) self.assertIsNone(City3D.objects.none().aggregate(Extent3D('point'))['point__extent3d']) - @ignore_warnings(category=RemovedInDjango20Warning) - @skipUnlessDBFeature("supports_3d_functions") - def test_perimeter(self): - """ - Testing GeoQuerySet.perimeter() on 3D fields. - """ - self._load_polygon_data() - # Reference query for values below: - # `SELECT ST_Perimeter3D(poly), ST_Perimeter2D(poly) FROM geo3d_polygon3d;` - ref_perim_3d = 76859.2620451 - ref_perim_2d = 76859.2577803 - tol = 6 - self.assertAlmostEqual(ref_perim_2d, - Polygon2D.objects.perimeter().get(name='2D BBox').perimeter.m, - tol) - self.assertAlmostEqual(ref_perim_3d, - Polygon3D.objects.perimeter().get(name='3D BBox').perimeter.m, - tol) - - @ignore_warnings(category=RemovedInDjango20Warning) - @skipUnlessDBFeature("supports_3d_functions") - def test_length(self): - """ - Testing GeoQuerySet.length() on 3D fields. - """ - # ST_Length_Spheroid Z-aware, and thus does not need to use - # a separate function internally. - # `SELECT ST_Length_Spheroid(line, 'SPHEROID["GRS 1980",6378137,298.257222101]') - # FROM geo3d_interstate[2d|3d];` - self._load_interstate_data() - tol = 3 - ref_length_2d = 4368.1721949481 - ref_length_3d = 4368.62547052088 - self.assertAlmostEqual(ref_length_2d, - Interstate2D.objects.length().get(name='I-45').length.m, - tol) - self.assertAlmostEqual(ref_length_3d, - Interstate3D.objects.length().get(name='I-45').length.m, - tol) - - # Making sure `ST_Length3D` is used on for a projected - # and 3D model rather than `ST_Length`. - # `SELECT ST_Length(line) FROM geo3d_interstateproj2d;` - ref_length_2d = 4367.71564892392 - # `SELECT ST_Length3D(line) FROM geo3d_interstateproj3d;` - ref_length_3d = 4368.16897234101 - self.assertAlmostEqual(ref_length_2d, - InterstateProj2D.objects.length().get(name='I-45').length.m, - tol) - self.assertAlmostEqual(ref_length_3d, - InterstateProj3D.objects.length().get(name='I-45').length.m, - tol) - - @ignore_warnings(category=RemovedInDjango20Warning) - @skipUnlessDBFeature("supports_3d_functions") - def test_scale(self): - """ - Testing GeoQuerySet.scale() on Z values. - """ - self._load_city_data() - # Mapping of City name to reference Z values. - zscales = (-3, 4, 23) - for zscale in zscales: - for city in City3D.objects.scale(1.0, 1.0, zscale): - self.assertEqual(city_dict[city.name][2] * zscale, city.scale.z) - - @ignore_warnings(category=RemovedInDjango20Warning) - @skipUnlessDBFeature("supports_3d_functions") - def test_translate(self): - """ - Testing GeoQuerySet.translate() on Z values. - """ - self._load_city_data() - ztranslations = (5.23, 23, -17) - for ztrans in ztranslations: - for city in City3D.objects.translate(0, 0, ztrans): - self.assertEqual(city_dict[city.name][2] + ztrans, city.translate.z) - @skipUnlessDBFeature("gis_enabled", "supports_3d_functions") class Geo3DFunctionsTests(Geo3DLoadingHelper, TestCase): diff --git a/tests/gis_tests/geoapp/models.py b/tests/gis_tests/geoapp/models.py index 62103d268da4..f5f4c38b428c 100644 --- a/tests/gis_tests/geoapp/models.py +++ b/tests/gis_tests/geoapp/models.py @@ -8,8 +8,6 @@ class NamedModel(models.Model): name = models.CharField(max_length=30) - objects = models.GeoManager() - class Meta: abstract = True required_db_features = ['gis_enabled'] diff --git a/tests/gis_tests/geoapp/test_functions.py b/tests/gis_tests/geoapp/test_functions.py index 61ae7dc9a620..e551de6890b2 100644 --- a/tests/gis_tests/geoapp/test_functions.py +++ b/tests/gis_tests/geoapp/test_functions.py @@ -19,7 +19,6 @@ class GISFunctionsTests(TestCase): """ Testing functions from django/contrib/gis/db/models/functions.py. - Several tests are taken and adapted from GeoQuerySetTest. Area/Distance/Length/Perimeter are tested in distapp/tests. Please keep the tests in function's alphabetic order. @@ -462,7 +461,6 @@ def test_translate(self): "has_Difference_function", "has_Intersection_function", "has_SymDifference_function", "has_Union_function") def test_diff_intersection_union(self): - "Testing the `difference`, `intersection`, `sym_difference`, and `union` GeoQuerySet methods." geom = Point(5, 23, srid=4326) qs = Country.objects.all().annotate( difference=functions.Difference('mpoly', geom), diff --git a/tests/gis_tests/geoapp/test_regress.py b/tests/gis_tests/geoapp/test_regress.py index 7aa99966e3eb..a075d447efa6 100644 --- a/tests/gis_tests/geoapp/test_regress.py +++ b/tests/gis_tests/geoapp/test_regress.py @@ -17,7 +17,7 @@ class GeoRegressionTests(TestCase): fixtures = ['initial'] def test_update(self): - "Testing GeoQuerySet.update(). See #10411." + "Testing QuerySet.update() (#10411)." pnt = City.objects.get(name='Pueblo').point bak = pnt.clone() pnt.y += 0.005 diff --git a/tests/gis_tests/geoapp/tests.py b/tests/gis_tests/geoapp/tests.py index 7c4e8b8dfb74..cbbf0357bc92 100644 --- a/tests/gis_tests/geoapp/tests.py +++ b/tests/gis_tests/geoapp/tests.py @@ -1,21 +1,19 @@ from __future__ import unicode_literals -import re import tempfile from django.contrib.gis import gdal -from django.contrib.gis.db.models import Extent, MakeLine, Union +from django.contrib.gis.db.models import Extent, MakeLine, Union, functions from django.contrib.gis.geos import ( GeometryCollection, GEOSGeometry, LinearRing, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, fromstr, ) from django.core.management import call_command from django.db import connection -from django.test import TestCase, ignore_warnings, skipUnlessDBFeature +from django.test import TestCase, skipUnlessDBFeature from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning -from ..utils import oracle, postgis, skipUnlessGISLookup, spatialite +from ..utils import no_oracle, oracle, postgis, skipUnlessGISLookup, spatialite from .models import ( City, Country, Feature, MinusOneSRID, NonConcreteModel, PennsylvaniaCity, State, Track, @@ -155,19 +153,22 @@ def test_geometryfield(self): self.assertIsInstance(f_4.geom, GeometryCollection) self.assertEqual(f_3.geom, f_4.geom[2]) + # TODO: fix on Oracle: ORA-22901: cannot compare nested table or VARRAY or + # LOB attributes of an object type. + @no_oracle @skipUnlessDBFeature("supports_transform") def test_inherited_geofields(self): - "Test GeoQuerySet methods on inherited Geometry fields." + "Database functions on inherited Geometry fields." # Creating a Pennsylvanian city. PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)') # All transformation SQL will need to be performed on the # _parent_ table. - qs = PennsylvaniaCity.objects.transform(32128) + qs = PennsylvaniaCity.objects.annotate(new_point=functions.Transform('point', srid=32128)) self.assertEqual(1, qs.count()) for pc in qs: - self.assertEqual(32128, pc.point.srid) + self.assertEqual(32128, pc.new_point.srid) def test_raw_sql_query(self): "Testing raw SQL query." @@ -412,8 +413,8 @@ def test_relate_lookup(self): pnt1 = fromstr('POINT (649287.0363174 4177429.4494686)', srid=2847) pnt2 = fromstr('POINT(-98.4919715741052 29.4333344025053)', srid=4326) - # Not passing in a geometry as first param should - # raise a type error when initializing the GeoQuerySet + # Not passing in a geometry as first param raises a TypeError when + # initializing the QuerySet. with self.assertRaises(ValueError): Country.objects.filter(mpoly__relate=(23, 'foo')) @@ -451,66 +452,10 @@ def test_relate_lookup(self): @skipUnlessDBFeature("gis_enabled") -@ignore_warnings(category=RemovedInDjango20Warning) class GeoQuerySetTest(TestCase): + # TODO: GeoQuerySet is removed, organize these test better. fixtures = ['initial'] - # Please keep the tests in GeoQuerySet method's alphabetic order - - @skipUnlessDBFeature("has_centroid_method") - def test_centroid(self): - "Testing the `centroid` GeoQuerySet method." - qs = State.objects.exclude(poly__isnull=True).centroid() - if oracle: - tol = 0.1 - elif spatialite: - tol = 0.000001 - else: - tol = 0.000000001 - for s in qs: - self.assertTrue(s.poly.centroid.equals_exact(s.centroid, tol)) - - @skipUnlessDBFeature( - "has_difference_method", "has_intersection_method", - "has_sym_difference_method", "has_union_method") - def test_diff_intersection_union(self): - "Testing the `difference`, `intersection`, `sym_difference`, and `union` GeoQuerySet methods." - geom = Point(5, 23) - qs = Country.objects.all().difference(geom).sym_difference(geom).union(geom) - - # XXX For some reason SpatiaLite does something screwy with the Texas geometry here. Also, - # XXX it doesn't like the null intersection. - if spatialite: - qs = qs.exclude(name='Texas') - else: - qs = qs.intersection(geom) - - for c in qs: - if oracle: - # Should be able to execute the queries; however, they won't be the same - # as GEOS (because Oracle doesn't use GEOS internally like PostGIS or - # SpatiaLite). - pass - else: - if spatialite: - # Spatialite `difference` doesn't have an SRID - self.assertEqual(c.mpoly.difference(geom).wkt, c.difference.wkt) - else: - self.assertEqual(c.mpoly.difference(geom), c.difference) - self.assertEqual(c.mpoly.intersection(geom), c.intersection) - # Ordering might differ in collections - self.assertSetEqual(set(g.wkt for g in c.mpoly.sym_difference(geom)), - set(g.wkt for g in c.sym_difference)) - self.assertSetEqual(set(g.wkt for g in c.mpoly.union(geom)), - set(g.wkt for g in c.union)) - - @skipUnlessDBFeature("has_envelope_method") - def test_envelope(self): - "Testing the `envelope` GeoQuerySet method." - countries = Country.objects.all().envelope() - for country in countries: - self.assertIsInstance(country.envelope, Polygon) - @skipUnlessDBFeature("supports_extent_aggr") def test_extent(self): """ @@ -536,132 +481,6 @@ def test_extent_with_limit(self): extent2 = City.objects.all()[:3].aggregate(Extent('point'))['point__extent'] self.assertNotEqual(extent1, extent2) - @skipUnlessDBFeature("has_force_rhr_method") - def test_force_rhr(self): - "Testing GeoQuerySet.force_rhr()." - rings = ( - ((0, 0), (5, 0), (0, 5), (0, 0)), - ((1, 1), (1, 3), (3, 1), (1, 1)), - ) - rhr_rings = ( - ((0, 0), (0, 5), (5, 0), (0, 0)), - ((1, 1), (3, 1), (1, 3), (1, 1)), - ) - State.objects.create(name='Foo', poly=Polygon(*rings)) - s = State.objects.force_rhr().get(name='Foo') - self.assertEqual(rhr_rings, s.force_rhr.coords) - - @skipUnlessDBFeature("has_geohash_method") - def test_geohash(self): - "Testing GeoQuerySet.geohash()." - # Reference query: - # SELECT ST_GeoHash(point) FROM geoapp_city WHERE name='Houston'; - # SELECT ST_GeoHash(point, 5) FROM geoapp_city WHERE name='Houston'; - ref_hash = '9vk1mfq8jx0c8e0386z6' - h1 = City.objects.geohash().get(name='Houston') - h2 = City.objects.geohash(precision=5).get(name='Houston') - self.assertEqual(ref_hash, h1.geohash) - self.assertEqual(ref_hash[:5], h2.geohash) - - def test_geojson(self): - "Testing GeoJSON output from the database using GeoQuerySet.geojson()." - # Only PostGIS and SpatiaLite support GeoJSON. - if not connection.ops.geojson: - with self.assertRaises(NotImplementedError): - Country.objects.all().geojson(field_name='mpoly') - return - - pueblo_json = '{"type":"Point","coordinates":[-104.609252,38.255001]}' - houston_json = ( - '{"type":"Point","crs":{"type":"name","properties":' - '{"name":"EPSG:4326"}},"coordinates":[-95.363151,29.763374]}' - ) - victoria_json = ( - '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],' - '"coordinates":[-123.305196,48.462611]}' - ) - chicago_json = ( - '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},' - '"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}' - ) - if spatialite: - victoria_json = ( - '{"type":"Point","bbox":[-123.305196,48.462611,-123.305196,48.462611],' - '"coordinates":[-123.305196,48.462611]}' - ) - - # Precision argument should only be an integer - with self.assertRaises(TypeError): - City.objects.geojson(precision='foo') - - # Reference queries and values. - # SELECT ST_AsGeoJson("geoapp_city"."point", 8, 0) - # FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Pueblo'; - self.assertEqual(pueblo_json, City.objects.geojson().get(name='Pueblo').geojson) - - # SELECT ST_AsGeoJson("geoapp_city"."point", 8, 2) FROM "geoapp_city" - # WHERE "geoapp_city"."name" = 'Houston'; - # This time we want to include the CRS by using the `crs` keyword. - self.assertEqual(houston_json, City.objects.geojson(crs=True, model_att='json').get(name='Houston').json) - - # SELECT ST_AsGeoJson("geoapp_city"."point", 8, 1) FROM "geoapp_city" - # WHERE "geoapp_city"."name" = 'Houston'; - # This time we include the bounding box by using the `bbox` keyword. - self.assertEqual(victoria_json, City.objects.geojson(bbox=True).get(name='Victoria').geojson) - - # SELECT ST_AsGeoJson("geoapp_city"."point", 5, 3) FROM "geoapp_city" - # WHERE "geoapp_city"."name" = 'Chicago'; - # Finally, we set every available keyword. - self.assertEqual( - chicago_json, - City.objects.geojson(bbox=True, crs=True, precision=5).get(name='Chicago').geojson - ) - - @skipUnlessDBFeature("has_gml_method") - def test_gml(self): - "Testing GML output from the database using GeoQuerySet.gml()." - # Should throw a TypeError when trying to obtain GML from a - # non-geometry field. - qs = City.objects.all() - with self.assertRaises(TypeError): - qs.gml(field_name='name') - ptown1 = City.objects.gml(field_name='point', precision=9).get(name='Pueblo') - ptown2 = City.objects.gml(precision=9).get(name='Pueblo') - - if oracle: - # No precision parameter for Oracle :-/ - gml_regex = re.compile( - r'^' - r'-104.60925\d+,38.25500\d+ ' - r'' - ) - else: - gml_regex = re.compile( - r'^' - r'-104\.60925\d+,38\.255001' - ) - - for ptown in [ptown1, ptown2]: - self.assertTrue(gml_regex.match(ptown.gml)) - - if postgis: - self.assertIn('', City.objects.gml(version=3).get(name='Pueblo').gml) - - @skipUnlessDBFeature("has_kml_method") - def test_kml(self): - "Testing KML output from the database using GeoQuerySet.kml()." - # Should throw a TypeError when trying to obtain KML from a - # non-geometry field. - qs = City.objects.all() - with self.assertRaises(TypeError): - qs.kml('name') - - # Ensuring the KML is as expected. - ptown1 = City.objects.kml(field_name='point', precision=9).get(name='Pueblo') - ptown2 = City.objects.kml(precision=9).get(name='Pueblo') - for ptown in [ptown1, ptown2]: - self.assertEqual('-104.609252,38.255001', ptown.kml) - def test_make_line(self): """ Testing the `MakeLine` aggregate. @@ -689,181 +508,6 @@ def test_make_line(self): "%s != %s" % (ref_line, line) ) - @skipUnlessDBFeature("has_num_geom_method") - def test_num_geom(self): - "Testing the `num_geom` GeoQuerySet method." - # Both 'countries' only have two geometries. - for c in Country.objects.num_geom(): - self.assertEqual(2, c.num_geom) - - for c in City.objects.filter(point__isnull=False).num_geom(): - # Oracle and PostGIS 2.0+ will return 1 for the number of - # geometries on non-collections. - self.assertEqual(1, c.num_geom) - - @skipUnlessDBFeature("supports_num_points_poly") - def test_num_points(self): - "Testing the `num_points` GeoQuerySet method." - for c in Country.objects.num_points(): - self.assertEqual(c.mpoly.num_points, c.num_points) - - if not oracle: - # Oracle cannot count vertices in Point geometries. - for c in City.objects.num_points(): - self.assertEqual(1, c.num_points) - - @skipUnlessDBFeature("has_point_on_surface_method") - def test_point_on_surface(self): - "Testing the `point_on_surface` GeoQuerySet method." - # Reference values. - if oracle: - # SELECT SDO_UTIL.TO_WKTGEOMETRY(SDO_GEOM.SDO_POINTONSURFACE(GEOAPP_COUNTRY.MPOLY, 0.05)) - # FROM GEOAPP_COUNTRY; - ref = {'New Zealand': fromstr('POINT (174.616364 -36.100861)', srid=4326), - 'Texas': fromstr('POINT (-103.002434 36.500397)', srid=4326), - } - - else: - # Using GEOSGeometry to compute the reference point on surface values - # -- since PostGIS also uses GEOS these should be the same. - ref = {'New Zealand': Country.objects.get(name='New Zealand').mpoly.point_on_surface, - 'Texas': Country.objects.get(name='Texas').mpoly.point_on_surface - } - - for c in Country.objects.point_on_surface(): - if spatialite: - # XXX This seems to be a WKT-translation-related precision issue? - tol = 0.00001 - else: - tol = 0.000000001 - self.assertTrue(ref[c.name].equals_exact(c.point_on_surface, tol)) - - @skipUnlessDBFeature("has_reverse_method") - def test_reverse_geom(self): - "Testing GeoQuerySet.reverse_geom()." - coords = [(-95.363151, 29.763374), (-95.448601, 29.713803)] - Track.objects.create(name='Foo', line=LineString(coords)) - t = Track.objects.reverse_geom().get(name='Foo') - coords.reverse() - self.assertEqual(tuple(coords), t.reverse_geom.coords) - if oracle: - with self.assertRaises(TypeError): - State.objects.reverse_geom() - - @skipUnlessDBFeature("has_scale_method") - def test_scale(self): - "Testing the `scale` GeoQuerySet method." - xfac, yfac = 2, 3 - tol = 5 # XXX The low precision tolerance is for SpatiaLite - qs = Country.objects.scale(xfac, yfac, model_att='scaled') - for c in qs: - for p1, p2 in zip(c.mpoly, c.scaled): - for r1, r2 in zip(p1, p2): - for c1, c2 in zip(r1.coords, r2.coords): - self.assertAlmostEqual(c1[0] * xfac, c2[0], tol) - self.assertAlmostEqual(c1[1] * yfac, c2[1], tol) - - @skipUnlessDBFeature("has_snap_to_grid_method") - def test_snap_to_grid(self): - "Testing GeoQuerySet.snap_to_grid()." - # Let's try and break snap_to_grid() with bad combinations of arguments. - for bad_args in ((), range(3), range(5)): - with self.assertRaises(ValueError): - Country.objects.snap_to_grid(*bad_args) - for bad_args in (('1.0',), (1.0, None), tuple(map(six.text_type, range(4)))): - with self.assertRaises(TypeError): - Country.objects.snap_to_grid(*bad_args) - - # Boundary for San Marino, courtesy of Bjorn Sandvik of thematicmapping.org - # from the world borders dataset he provides. - wkt = ('MULTIPOLYGON(((12.41580 43.95795,12.45055 43.97972,12.45389 43.98167,' - '12.46250 43.98472,12.47167 43.98694,12.49278 43.98917,' - '12.50555 43.98861,12.51000 43.98694,12.51028 43.98277,' - '12.51167 43.94333,12.51056 43.93916,12.49639 43.92333,' - '12.49500 43.91472,12.48778 43.90583,12.47444 43.89722,' - '12.46472 43.89555,12.45917 43.89611,12.41639 43.90472,' - '12.41222 43.90610,12.40782 43.91366,12.40389 43.92667,' - '12.40500 43.94833,12.40889 43.95499,12.41580 43.95795)))') - Country.objects.create(name='San Marino', mpoly=fromstr(wkt)) - - # Because floating-point arithmetic isn't exact, we set a tolerance - # to pass into GEOS `equals_exact`. - tol = 0.000000001 - - # SELECT AsText(ST_SnapToGrid("geoapp_country"."mpoly", 0.1)) FROM "geoapp_country" - # WHERE "geoapp_country"."name" = 'San Marino'; - ref = fromstr('MULTIPOLYGON(((12.4 44,12.5 44,12.5 43.9,12.4 43.9,12.4 44)))') - self.assertTrue(ref.equals_exact(Country.objects.snap_to_grid(0.1).get(name='San Marino').snap_to_grid, tol)) - - # SELECT AsText(ST_SnapToGrid("geoapp_country"."mpoly", 0.05, 0.23)) FROM "geoapp_country" - # WHERE "geoapp_country"."name" = 'San Marino'; - ref = fromstr('MULTIPOLYGON(((12.4 43.93,12.45 43.93,12.5 43.93,12.45 43.93,12.4 43.93)))') - self.assertTrue( - ref.equals_exact(Country.objects.snap_to_grid(0.05, 0.23).get(name='San Marino').snap_to_grid, tol) - ) - - # SELECT AsText(ST_SnapToGrid("geoapp_country"."mpoly", 0.5, 0.17, 0.05, 0.23)) FROM "geoapp_country" - # WHERE "geoapp_country"."name" = 'San Marino'; - ref = fromstr( - 'MULTIPOLYGON(((12.4 43.87,12.45 43.87,12.45 44.1,12.5 44.1,12.5 43.87,12.45 43.87,12.4 43.87)))' - ) - self.assertTrue( - ref.equals_exact( - Country.objects.snap_to_grid(0.05, 0.23, 0.5, 0.17).get(name='San Marino').snap_to_grid, - tol - ) - ) - - @skipUnlessDBFeature("has_svg_method") - def test_svg(self): - "Testing SVG output using GeoQuerySet.svg()." - - with self.assertRaises(TypeError): - City.objects.svg(precision='foo') - # SELECT AsSVG(geoapp_city.point, 0, 8) FROM geoapp_city WHERE name = 'Pueblo'; - svg1 = 'cx="-104.609252" cy="-38.255001"' - # Even though relative, only one point so it's practically the same except for - # the 'c' letter prefix on the x,y values. - svg2 = svg1.replace('c', '') - self.assertEqual(svg1, City.objects.svg().get(name='Pueblo').svg) - self.assertEqual(svg2, City.objects.svg(relative=5).get(name='Pueblo').svg) - - @skipUnlessDBFeature("has_transform_method") - def test_transform(self): - "Testing the transform() GeoQuerySet method." - # Pre-transformed points for Houston and Pueblo. - htown = fromstr('POINT(1947516.83115183 6322297.06040572)', srid=3084) - ptown = fromstr('POINT(992363.390841912 481455.395105533)', srid=2774) - prec = 3 # Precision is low due to version variations in PROJ and GDAL. - - # Asserting the result of the transform operation with the values in - # the pre-transformed points. Oracle does not have the 3084 SRID. - if not oracle: - h = City.objects.transform(htown.srid).get(name='Houston') - self.assertEqual(3084, h.point.srid) - self.assertAlmostEqual(htown.x, h.point.x, prec) - self.assertAlmostEqual(htown.y, h.point.y, prec) - - p1 = City.objects.transform(ptown.srid, field_name='point').get(name='Pueblo') - p2 = City.objects.transform(srid=ptown.srid).get(name='Pueblo') - for p in [p1, p2]: - self.assertEqual(2774, p.point.srid) - self.assertAlmostEqual(ptown.x, p.point.x, prec) - self.assertAlmostEqual(ptown.y, p.point.y, prec) - - @skipUnlessDBFeature("has_translate_method") - def test_translate(self): - "Testing the `translate` GeoQuerySet method." - xfac, yfac = 5, -23 - qs = Country.objects.translate(xfac, yfac, model_att='translated') - for c in qs: - for p1, p2 in zip(c.mpoly, c.translated): - for r1, r2 in zip(p1, p2): - for c1, c2 in zip(r1.coords, r2.coords): - # XXX The low precision is for SpatiaLite - self.assertAlmostEqual(c1[0] + xfac, c2[0], 5) - self.assertAlmostEqual(c1[1] + yfac, c2[1], 5) - @skipUnlessDBFeature('supports_union_aggr') def test_unionagg(self): """ diff --git a/tests/gis_tests/geogapp/models.py b/tests/gis_tests/geogapp/models.py index 3d2a12826a21..6bc5955923dc 100644 --- a/tests/gis_tests/geogapp/models.py +++ b/tests/gis_tests/geogapp/models.py @@ -6,8 +6,6 @@ class NamedModel(models.Model): name = models.CharField(max_length=30) - objects = models.GeoManager() - class Meta: abstract = True required_db_features = ['gis_enabled'] diff --git a/tests/gis_tests/geogapp/tests.py b/tests/gis_tests/geogapp/tests.py index 89a47405ce18..d9f02184eade 100644 --- a/tests/gis_tests/geogapp/tests.py +++ b/tests/gis_tests/geogapp/tests.py @@ -11,11 +11,8 @@ from django.contrib.gis.measure import D from django.db import connection from django.db.models.functions import Cast -from django.test import ( - TestCase, ignore_warnings, skipIfDBFeature, skipUnlessDBFeature, -) +from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature from django.utils._os import upath -from django.utils.deprecation import RemovedInDjango20Warning from ..utils import oracle, postgis, spatialite from .models import City, County, Zipcode @@ -32,7 +29,7 @@ def test01_fixture_load(self): @skipIf(spatialite, "SpatiaLite doesn't support distance lookups with Distance objects.") @skipUnlessDBFeature("supports_distances_lookups", "supports_distance_geodetic") def test02_distance_lookup(self): - "Testing GeoQuerySet distance lookup support on non-point geography fields." + "Testing distance lookup support on non-point geography fields." z = Zipcode.objects.get(code='77002') cities1 = list(City.objects .filter(point__distance_lte=(z.poly, D(mi=500))) @@ -45,15 +42,6 @@ def test02_distance_lookup(self): for cities in [cities1, cities2]: self.assertEqual(['Dallas', 'Houston', 'Oklahoma City'], cities) - @skipIf(spatialite, "distance() doesn't support geodetic coordinates on SpatiaLite.") - @skipUnlessDBFeature("has_distance_method", "supports_distance_geodetic") - @ignore_warnings(category=RemovedInDjango20Warning) - def test03_distance_method(self): - "Testing GeoQuerySet.distance() support on non-point geography fields." - # `GeoQuerySet.distance` is not allowed geometry fields. - htown = City.objects.get(name='Houston') - Zipcode.objects.distance(htown.point) - @skipUnless(postgis, "This is a PostGIS-specific test") def test04_invalid_operators_functions(self): "Ensuring exceptions are raised for operators & functions invalid on geography fields." @@ -101,19 +89,6 @@ def test05_geography_layermapping(self): self.assertEqual(name, c.name) self.assertEqual(state, c.state) - @skipIf(spatialite, "area() doesn't support geodetic coordinates on SpatiaLite.") - @skipUnlessDBFeature("has_area_method", "supports_distance_geodetic") - @ignore_warnings(category=RemovedInDjango20Warning) - def test06_geography_area(self): - "Testing that Area calculations work on geography columns." - # SELECT ST_Area(poly) FROM geogapp_zipcode WHERE code='77002'; - z = Zipcode.objects.area().get(code='77002') - # Round to the nearest thousand as possible values (depending on - # the database and geolib) include 5439084, 5439100, 5439101. - rounded_value = z.area.sq_m - rounded_value -= z.area.sq_m % 1000 - self.assertEqual(rounded_value, 5439000) - @skipUnlessDBFeature("gis_enabled") class GeographyFunctionTests(TestCase): diff --git a/tests/gis_tests/relatedapp/models.py b/tests/gis_tests/relatedapp/models.py index 32de25bd20a9..6d674588dd3c 100644 --- a/tests/gis_tests/relatedapp/models.py +++ b/tests/gis_tests/relatedapp/models.py @@ -3,9 +3,6 @@ class SimpleModel(models.Model): - - objects = models.GeoManager() - class Meta: abstract = True required_db_features = ['gis_enabled'] diff --git a/tests/gis_tests/relatedapp/tests.py b/tests/gis_tests/relatedapp/tests.py index 3ca4d91dbad6..861b6ee2d927 100644 --- a/tests/gis_tests/relatedapp/tests.py +++ b/tests/gis_tests/relatedapp/tests.py @@ -38,33 +38,6 @@ def test02_select_related(self): self.assertEqual(st, c.state) self.assertEqual(Point(lon, lat, srid=c.location.point.srid), c.location.point) - @skipUnlessDBFeature("has_transform_method") - def test03_transform_related(self): - "Testing the `transform` GeoQuerySet method on related geographic models." - # All the transformations are to state plane coordinate systems using - # US Survey Feet (thus a tolerance of 0 implies error w/in 1 survey foot). - tol = 0 - - def check_pnt(ref, pnt): - self.assertAlmostEqual(ref.x, pnt.x, tol) - self.assertAlmostEqual(ref.y, pnt.y, tol) - self.assertEqual(ref.srid, pnt.srid) - - # Each city transformed to the SRID of their state plane coordinate system. - transformed = (('Kecksburg', 2272, 'POINT(1490553.98959621 314792.131023984)'), - ('Roswell', 2257, 'POINT(481902.189077221 868477.766629735)'), - ('Aurora', 2276, 'POINT(2269923.2484839 7069381.28722222)'), - ) - - for name, srid, wkt in transformed: - # Doing this implicitly sets `select_related` select the location. - # TODO: Fix why this breaks on Oracle. - qs = list(City.objects.filter(name=name).transform(srid, field_name='location__point')) - check_pnt(GEOSGeometry(wkt, srid), qs[0].location.point) - - # Relations more than one level deep can be queried. - self.assertEqual(list(Parcel.objects.transform(srid, field_name='city__location__point')), []) - @skipUnlessDBFeature("supports_extent_aggr") def test_related_extent_aggregate(self): "Testing the `Extent` aggregate on related geographic models." @@ -190,13 +163,13 @@ def test06_f_expressions(self): self.assertEqual('P1', qs[0].name) def test07_values(self): - "Testing values() and values_list() and GeoQuerySets." + "Testing values() and values_list()." gqs = Location.objects.all() gvqs = Location.objects.values() gvlqs = Location.objects.values_list() # Incrementing through each of the models, dictionaries, and tuples - # returned by the different types of GeoQuerySets. + # returned by each QuerySet. for m, d, t in zip(gqs, gvqs, gvlqs): # The values should be Geometry objects and not raw strings returned # by the spatial database. @@ -234,7 +207,7 @@ def test09_pk_relations(self): # TODO: fix on Oracle -- qs2 returns an empty result for an unknown reason @no_oracle def test10_combine(self): - "Testing the combination of two GeoQuerySets. See #10807." + "Testing the combination of two QuerySets (#10807)." buf1 = City.objects.get(name='Aurora').location.point.buffer(0.1) buf2 = City.objects.get(name='Kecksburg').location.point.buffer(0.1) qs1 = City.objects.filter(location__point__within=buf1) diff --git a/tests/managers_regress/tests.py b/tests/managers_regress/tests.py index 1ff34dede345..031c8a815555 100644 --- a/tests/managers_regress/tests.py +++ b/tests/managers_regress/tests.py @@ -305,19 +305,6 @@ class TestModel(AbstractModel): @isolate_apps('managers_regress') class TestManagerDeprecations(TestCase): - def test_use_for_related_fields_on_geomanager(self): - from django.contrib.gis.db.models import GeoManager - - class MyModel(models.Model): - objects = GeoManager() - - # Shouldn't issue any warnings, since GeoManager itself will be - # deprecated at the same time as use_for_related_fields, there - # is no point annoying users with this deprecation. - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always', RemovedInDjango20Warning) - MyModel._base_manager - self.assertEqual(len(warns), 0) def test_use_for_related_fields_for_base_manager(self): class MyManager(models.Manager): diff --git a/tests/runtests.py b/tests/runtests.py index 59f90646aaac..6cec7d6e5c8c 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -168,12 +168,6 @@ def no_available_apps(self): 'fields.W901', # CommaSeparatedIntegerField deprecated ] - warnings.filterwarnings( - 'ignore', - 'The GeoManager class is deprecated.', - RemovedInDjango20Warning - ) - # Load all the ALWAYS_INSTALLED_APPS. django.setup() From 56a5760543f0428346a45f5efcffacf8caedd744 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 30 Dec 2016 18:56:34 -0500 Subject: [PATCH 0014/3180] Refs #25184 -- Removed contrib.gis.geoip per deprecation timeline. --- django/contrib/gis/geoip/__init__.py | 21 -- django/contrib/gis/geoip/base.py | 292 ------------------------- django/contrib/gis/geoip/libgeoip.py | 34 --- django/contrib/gis/geoip/prototypes.py | 132 ----------- docs/ref/contrib/gis/geoip.txt | 223 ------------------- docs/ref/contrib/gis/index.txt | 1 - docs/releases/2.0.txt | 2 + tests/gis_tests/test_geoip.py | 178 --------------- 8 files changed, 2 insertions(+), 881 deletions(-) delete mode 100644 django/contrib/gis/geoip/__init__.py delete mode 100644 django/contrib/gis/geoip/base.py delete mode 100644 django/contrib/gis/geoip/libgeoip.py delete mode 100644 django/contrib/gis/geoip/prototypes.py delete mode 100644 docs/ref/contrib/gis/geoip.txt delete mode 100644 tests/gis_tests/test_geoip.py diff --git a/django/contrib/gis/geoip/__init__.py b/django/contrib/gis/geoip/__init__.py deleted file mode 100644 index 237567dd8ad4..000000000000 --- a/django/contrib/gis/geoip/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -""" - This module houses the GeoIP object, a ctypes wrapper for the MaxMind GeoIP(R) - C API (http://www.maxmind.com/app/c). This is an alternative to the GPL - licensed Python GeoIP interface provided by MaxMind. - - GeoIP(R) is a registered trademark of MaxMind, LLC of Boston, Massachusetts. - - For IP-based geolocation, this module requires the GeoLite Country and City - datasets, in binary format (CSV will not work!). The datasets may be - downloaded from MaxMind at http://www.maxmind.com/download/geoip/database/. - Grab GeoIP.dat.gz and GeoLiteCity.dat.gz, and unzip them in the directory - corresponding to settings.GEOIP_PATH. -""" -__all__ = ['HAS_GEOIP'] - -try: - from .base import GeoIP, GeoIPException - HAS_GEOIP = True - __all__ += ['GeoIP', 'GeoIPException'] -except RuntimeError: # libgeoip.py raises a RuntimeError if no GeoIP library is found - HAS_GEOIP = False diff --git a/django/contrib/gis/geoip/base.py b/django/contrib/gis/geoip/base.py deleted file mode 100644 index d40ae7e9ae84..000000000000 --- a/django/contrib/gis/geoip/base.py +++ /dev/null @@ -1,292 +0,0 @@ -import os -import re -import warnings -from ctypes import c_char_p - -from django.contrib.gis.geoip.libgeoip import GEOIP_SETTINGS -from django.contrib.gis.geoip.prototypes import ( - GeoIP_country_code_by_addr, GeoIP_country_code_by_name, - GeoIP_country_name_by_addr, GeoIP_country_name_by_name, - GeoIP_database_info, GeoIP_delete, GeoIP_lib_version, GeoIP_open, - GeoIP_record_by_addr, GeoIP_record_by_name, -) -from django.core.validators import ipv4_re -from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning -from django.utils.encoding import force_bytes, force_text - -# Regular expressions for recognizing the GeoIP free database editions. -free_regex = re.compile(r'^GEO-\d{3}FREE') -lite_regex = re.compile(r'^GEO-\d{3}LITE') - - -class GeoIPException(Exception): - pass - - -class GeoIP(object): - # The flags for GeoIP memory caching. - # GEOIP_STANDARD - read database from filesystem, uses least memory. - # - # GEOIP_MEMORY_CACHE - load database into memory, faster performance - # but uses more memory - # - # GEOIP_CHECK_CACHE - check for updated database. If database has been - # updated, reload filehandle and/or memory cache. This option - # is not thread safe. - # - # GEOIP_INDEX_CACHE - just cache the most frequently accessed index - # portion of the database, resulting in faster lookups than - # GEOIP_STANDARD, but less memory usage than GEOIP_MEMORY_CACHE - - # useful for larger databases such as GeoIP Organization and - # GeoIP City. Note, for GeoIP Country, Region and Netspeed - # databases, GEOIP_INDEX_CACHE is equivalent to GEOIP_MEMORY_CACHE - # - # GEOIP_MMAP_CACHE - load database into mmap shared memory ( not available - # on Windows). - GEOIP_STANDARD = 0 - GEOIP_MEMORY_CACHE = 1 - GEOIP_CHECK_CACHE = 2 - GEOIP_INDEX_CACHE = 4 - GEOIP_MMAP_CACHE = 8 - cache_options = {opt: None for opt in (0, 1, 2, 4, 8)} - - # Paths to the city & country binary databases. - _city_file = '' - _country_file = '' - - # Initially, pointers to GeoIP file references are NULL. - _city = None - _country = None - - def __init__(self, path=None, cache=0, country=None, city=None): - """ - Initializes the GeoIP object, no parameters are required to use default - settings. Keyword arguments may be passed in to customize the locations - of the GeoIP data sets. - - * path: Base directory to where GeoIP data is located or the full path - to where the city or country data files (*.dat) are located. - Assumes that both the city and country data sets are located in - this directory; overrides the GEOIP_PATH settings attribute. - - * cache: The cache settings when opening up the GeoIP datasets, - and may be an integer in (0, 1, 2, 4, 8) corresponding to - the GEOIP_STANDARD, GEOIP_MEMORY_CACHE, GEOIP_CHECK_CACHE, - GEOIP_INDEX_CACHE, and GEOIP_MMAP_CACHE, `GeoIPOptions` C API - settings, respectively. Defaults to 0, meaning that the data is read - from the disk. - - * country: The name of the GeoIP country data file. Defaults to - 'GeoIP.dat'; overrides the GEOIP_COUNTRY settings attribute. - - * city: The name of the GeoIP city data file. Defaults to - 'GeoLiteCity.dat'; overrides the GEOIP_CITY settings attribute. - """ - - warnings.warn( - "django.contrib.gis.geoip is deprecated in favor of " - "django.contrib.gis.geoip2 and the MaxMind GeoLite2 database " - "format.", RemovedInDjango20Warning, 2 - ) - - # Checking the given cache option. - if cache in self.cache_options: - self._cache = cache - else: - raise GeoIPException('Invalid GeoIP caching option: %s' % cache) - - # Getting the GeoIP data path. - if not path: - path = GEOIP_SETTINGS.get('GEOIP_PATH') - if not path: - raise GeoIPException('GeoIP path must be provided via parameter or the GEOIP_PATH setting.') - if not isinstance(path, six.string_types): - raise TypeError('Invalid path type: %s' % type(path).__name__) - - if os.path.isdir(path): - # Constructing the GeoIP database filenames using the settings - # dictionary. If the database files for the GeoLite country - # and/or city datasets exist, then try and open them. - country_db = os.path.join(path, country or GEOIP_SETTINGS.get('GEOIP_COUNTRY', 'GeoIP.dat')) - if os.path.isfile(country_db): - self._country = GeoIP_open(force_bytes(country_db), cache) - self._country_file = country_db - - city_db = os.path.join(path, city or GEOIP_SETTINGS.get('GEOIP_CITY', 'GeoLiteCity.dat')) - if os.path.isfile(city_db): - self._city = GeoIP_open(force_bytes(city_db), cache) - self._city_file = city_db - elif os.path.isfile(path): - # Otherwise, some detective work will be needed to figure - # out whether the given database path is for the GeoIP country - # or city databases. - ptr = GeoIP_open(force_bytes(path), cache) - info = GeoIP_database_info(ptr) - if lite_regex.match(info): - # GeoLite City database detected. - self._city = ptr - self._city_file = path - elif free_regex.match(info): - # GeoIP Country database detected. - self._country = ptr - self._country_file = path - else: - raise GeoIPException('Unable to recognize database edition: %s' % info) - else: - raise GeoIPException('GeoIP path must be a valid file or directory.') - - def __del__(self): - # Cleaning any GeoIP file handles lying around. - if GeoIP_delete is None: - return - if self._country: - GeoIP_delete(self._country) - if self._city: - GeoIP_delete(self._city) - - def __repr__(self): - version = '' - if GeoIP_lib_version is not None: - version += ' [v%s]' % force_text(GeoIP_lib_version()) - return '<%(cls)s%(version)s _country_file="%(country)s", _city_file="%(city)s">' % { - 'cls': self.__class__.__name__, - 'version': version, - 'country': self._country_file, - 'city': self._city_file, - } - - def _check_query(self, query, country=False, city=False, city_or_country=False): - "Helper routine for checking the query and database availability." - # Making sure a string was passed in for the query. - if not isinstance(query, six.string_types): - raise TypeError('GeoIP query must be a string, not type %s' % type(query).__name__) - - # Extra checks for the existence of country and city databases. - if city_or_country and not (self._country or self._city): - raise GeoIPException('Invalid GeoIP country and city data files.') - elif country and not self._country: - raise GeoIPException('Invalid GeoIP country data file: %s' % self._country_file) - elif city and not self._city: - raise GeoIPException('Invalid GeoIP city data file: %s' % self._city_file) - - # Return the query string back to the caller. GeoIP only takes bytestrings. - return force_bytes(query) - - def city(self, query): - """ - Returns a dictionary of city information for the given IP address or - Fully Qualified Domain Name (FQDN). Some information in the dictionary - may be undefined (None). - """ - enc_query = self._check_query(query, city=True) - if ipv4_re.match(query): - # If an IP address was passed in - return GeoIP_record_by_addr(self._city, c_char_p(enc_query)) - else: - # If a FQDN was passed in. - return GeoIP_record_by_name(self._city, c_char_p(enc_query)) - - def country_code(self, query): - "Returns the country code for the given IP Address or FQDN." - enc_query = self._check_query(query, city_or_country=True) - if self._country: - if ipv4_re.match(query): - return GeoIP_country_code_by_addr(self._country, enc_query) - else: - return GeoIP_country_code_by_name(self._country, enc_query) - else: - return self.city(query)['country_code'] - - def country_name(self, query): - "Returns the country name for the given IP Address or FQDN." - enc_query = self._check_query(query, city_or_country=True) - if self._country: - if ipv4_re.match(query): - return GeoIP_country_name_by_addr(self._country, enc_query) - else: - return GeoIP_country_name_by_name(self._country, enc_query) - else: - return self.city(query)['country_name'] - - def country(self, query): - """ - Returns a dictionary with the country code and name when given an - IP address or a Fully Qualified Domain Name (FQDN). For example, both - '24.124.1.80' and 'djangoproject.com' are valid parameters. - """ - # Returning the country code and name - return {'country_code': self.country_code(query), - 'country_name': self.country_name(query), - } - - # #### Coordinate retrieval routines #### - def coords(self, query, ordering=('longitude', 'latitude')): - cdict = self.city(query) - if cdict is None: - return None - else: - return tuple(cdict[o] for o in ordering) - - def lon_lat(self, query): - "Returns a tuple of the (longitude, latitude) for the given query." - return self.coords(query) - - def lat_lon(self, query): - "Returns a tuple of the (latitude, longitude) for the given query." - return self.coords(query, ('latitude', 'longitude')) - - def geos(self, query): - "Returns a GEOS Point object for the given query." - ll = self.lon_lat(query) - if ll: - from django.contrib.gis.geos import Point - return Point(ll, srid=4326) - else: - return None - - # #### GeoIP Database Information Routines #### - @property - def country_info(self): - "Returns information about the GeoIP country database." - if self._country is None: - ci = 'No GeoIP Country data in "%s"' % self._country_file - else: - ci = GeoIP_database_info(self._country) - return ci - - @property - def city_info(self): - "Returns information about the GeoIP city database." - if self._city is None: - ci = 'No GeoIP City data in "%s"' % self._city_file - else: - ci = GeoIP_database_info(self._city) - return ci - - @property - def info(self): - "Returns information about the GeoIP library and databases in use." - info = '' - if GeoIP_lib_version: - info += 'GeoIP Library:\n\t%s\n' % GeoIP_lib_version() - return info + 'Country:\n\t%s\nCity:\n\t%s' % (self.country_info, self.city_info) - - # #### Methods for compatibility w/the GeoIP-Python API. #### - @classmethod - def open(cls, full_path, cache): - return GeoIP(full_path, cache) - - def _rec_by_arg(self, arg): - if self._city: - return self.city(arg) - else: - return self.country(arg) - region_by_addr = city - region_by_name = city - record_by_addr = _rec_by_arg - record_by_name = _rec_by_arg - country_code_by_addr = country_code - country_code_by_name = country_code - country_name_by_addr = country_name - country_name_by_name = country_name diff --git a/django/contrib/gis/geoip/libgeoip.py b/django/contrib/gis/geoip/libgeoip.py deleted file mode 100644 index c5f5d24b8272..000000000000 --- a/django/contrib/gis/geoip/libgeoip.py +++ /dev/null @@ -1,34 +0,0 @@ -import os -from ctypes import CDLL -from ctypes.util import find_library - -from django.conf import settings - -# Creating the settings dictionary with any settings, if needed. -GEOIP_SETTINGS = {key: getattr(settings, key) - for key in ('GEOIP_PATH', 'GEOIP_LIBRARY_PATH', 'GEOIP_COUNTRY', 'GEOIP_CITY') - if hasattr(settings, key)} -lib_path = GEOIP_SETTINGS.get('GEOIP_LIBRARY_PATH') - -# The shared library for the GeoIP C API. May be downloaded -# from http://www.maxmind.com/download/geoip/api/c/ -if lib_path: - lib_name = None -else: - # TODO: Is this really the library name for Windows? - lib_name = 'GeoIP' - -# Getting the path to the GeoIP library. -if lib_name: - lib_path = find_library(lib_name) -if lib_path is None: - raise RuntimeError('Could not find the GeoIP library (tried "%s"). ' - 'Try setting GEOIP_LIBRARY_PATH in your settings.' % lib_name) -lgeoip = CDLL(lib_path) - -# Getting the C `free` for the platform. -if os.name == 'nt': - libc = CDLL('msvcrt') -else: - libc = CDLL(None) -free = libc.free diff --git a/django/contrib/gis/geoip/prototypes.py b/django/contrib/gis/geoip/prototypes.py deleted file mode 100644 index 74b9b2142f0a..000000000000 --- a/django/contrib/gis/geoip/prototypes.py +++ /dev/null @@ -1,132 +0,0 @@ -from ctypes import POINTER, Structure, c_char_p, c_float, c_int, string_at - -from django.contrib.gis.geoip.libgeoip import free, lgeoip - - -# #### GeoIP C Structure definitions #### - -class GeoIPRecord(Structure): - _fields_ = [('country_code', c_char_p), - ('country_code3', c_char_p), - ('country_name', c_char_p), - ('region', c_char_p), - ('city', c_char_p), - ('postal_code', c_char_p), - ('latitude', c_float), - ('longitude', c_float), - # TODO: In 1.4.6 this changed from `int dma_code;` to - # `union {int metro_code; int dma_code;};`. Change - # to a `ctypes.Union` in to accommodate in future when - # pre-1.4.6 versions are no longer distributed. - ('dma_code', c_int), - ('area_code', c_int), - ('charset', c_int), - ('continent_code', c_char_p), - ] - - -geoip_char_fields = [name for name, ctype in GeoIPRecord._fields_ if ctype is c_char_p] -GEOIP_DEFAULT_ENCODING = 'iso-8859-1' -geoip_encodings = { - 0: 'iso-8859-1', - 1: 'utf8', -} - - -class GeoIPTag(Structure): - pass - - -RECTYPE = POINTER(GeoIPRecord) -DBTYPE = POINTER(GeoIPTag) - -# #### ctypes function prototypes #### - -# GeoIP_lib_version appeared in version 1.4.7. -if hasattr(lgeoip, 'GeoIP_lib_version'): - GeoIP_lib_version = lgeoip.GeoIP_lib_version - GeoIP_lib_version.argtypes = None - GeoIP_lib_version.restype = c_char_p -else: - GeoIP_lib_version = None - -# For freeing memory allocated within a record -GeoIPRecord_delete = lgeoip.GeoIPRecord_delete -GeoIPRecord_delete.argtypes = [RECTYPE] -GeoIPRecord_delete.restype = None - - -# For retrieving records by name or address. -def check_record(result, func, cargs): - if result: - # Checking the pointer to the C structure, if valid pull out elements - # into a dictionary. - rec = result.contents - record = {fld: getattr(rec, fld) for fld, ctype in rec._fields_} - - # Now converting the strings to unicode using the proper encoding. - encoding = geoip_encodings[record['charset']] - for char_field in geoip_char_fields: - if record[char_field]: - record[char_field] = record[char_field].decode(encoding) - - # Free the memory allocated for the struct & return. - GeoIPRecord_delete(result) - return record - else: - return None - - -def record_output(func): - func.argtypes = [DBTYPE, c_char_p] - func.restype = RECTYPE - func.errcheck = check_record - return func - - -GeoIP_record_by_addr = record_output(lgeoip.GeoIP_record_by_addr) -GeoIP_record_by_name = record_output(lgeoip.GeoIP_record_by_name) - - -# For opening & closing GeoIP database files. -GeoIP_open = lgeoip.GeoIP_open -GeoIP_open.restype = DBTYPE -GeoIP_delete = lgeoip.GeoIP_delete -GeoIP_delete.argtypes = [DBTYPE] -GeoIP_delete.restype = None - - -# This is so the string pointer can be freed within Python. -class geoip_char_p(c_char_p): - pass - - -def check_string(result, func, cargs): - if result: - s = string_at(result) - free(result) - else: - s = '' - return s.decode(GEOIP_DEFAULT_ENCODING) - - -GeoIP_database_info = lgeoip.GeoIP_database_info -GeoIP_database_info.restype = geoip_char_p -GeoIP_database_info.errcheck = check_string - - -# String output routines. -def string_output(func): - def _err_check(result, func, cargs): - if result: - return result.decode(GEOIP_DEFAULT_ENCODING) - return result - func.restype = c_char_p - func.errcheck = _err_check - return func - - -GeoIP_country_code_by_addr = string_output(lgeoip.GeoIP_country_code_by_addr) -GeoIP_country_code_by_name = string_output(lgeoip.GeoIP_country_code_by_name) -GeoIP_country_name_by_addr = string_output(lgeoip.GeoIP_country_name_by_addr) -GeoIP_country_name_by_name = string_output(lgeoip.GeoIP_country_name_by_name) diff --git a/docs/ref/contrib/gis/geoip.txt b/docs/ref/contrib/gis/geoip.txt deleted file mode 100644 index 212aee12afe6..000000000000 --- a/docs/ref/contrib/gis/geoip.txt +++ /dev/null @@ -1,223 +0,0 @@ -====================== -Geolocation with GeoIP -====================== - -.. module:: django.contrib.gis.geoip - :synopsis: High-level Python interface for MaxMind's GeoIP C library. - -.. deprecated:: 1.9 - - This module is deprecated in favor of :doc:`django.contrib.gis.geoip2 - `, which supports IPv6 and the GeoLite2 database - format. - -The :class:`GeoIP` object is a ctypes wrapper for the -`MaxMind GeoIP C API`__. [#]_ - -In order to perform IP-based geolocation, the :class:`GeoIP` object requires -the GeoIP C library and either the GeoIP `Country`__ or `City`__ -datasets in binary format (the CSV files will not work!). These datasets may be -`downloaded from MaxMind`__. Grab the ``GeoLiteCountry/GeoIP.dat.gz`` and -``GeoLiteCity.dat.gz`` files and unzip them in a directory corresponding to what -you set :setting:`GEOIP_PATH` with in your settings. See the example and -reference below for more details. - -__ https://www.maxmind.com/app/c -__ https://www.maxmind.com/app/country -__ https://www.maxmind.com/app/city -__ https://www.maxmind.com/download/geoip/database/ - -Example -======= - -Assuming you have the GeoIP C library installed, here is an example of its -usage:: - - >>> from django.contrib.gis.geoip import GeoIP - >>> g = GeoIP() - >>> g.country('google.com') - {'country_code': 'US', 'country_name': 'United States'} - >>> g.city('72.14.207.99') - {'area_code': 650, - 'city': 'Mountain View', - 'country_code': 'US', - 'country_code3': 'USA', - 'country_name': 'United States', - 'dma_code': 807, - 'latitude': 37.419200897216797, - 'longitude': -122.05740356445312, - 'postal_code': '94043', - 'region': 'CA'} - >>> g.lat_lon('salon.com') - (37.789798736572266, -122.39420318603516) - >>> g.lon_lat('uh.edu') - (-95.415199279785156, 29.77549934387207) - >>> g.geos('24.124.1.80').wkt - 'POINT (-95.2087020874023438 39.0392990112304688)' - -``GeoIP`` Settings -================== - -.. setting:: GEOIP_PATH - -``GEOIP_PATH`` --------------- - -A string specifying the directory where the GeoIP data files are -located. This setting is *required* unless manually specified -with ``path`` keyword when initializing the :class:`GeoIP` object. - -.. setting:: GEOIP_LIBRARY_PATH - -``GEOIP_LIBRARY_PATH`` ----------------------- - -A string specifying the location of the GeoIP C library. Typically, -this setting is only used if the GeoIP C library is in a non-standard -location (e.g., ``/home/sue/lib/libGeoIP.so``). - -.. setting:: GEOIP_COUNTRY - -``GEOIP_COUNTRY`` ------------------ - -The basename to use for the GeoIP country data file. -Defaults to ``'GeoIP.dat'``. - -.. setting:: GEOIP_CITY - -``GEOIP_CITY`` --------------- - -The basename to use for the GeoIP city data file. -Defaults to ``'GeoLiteCity.dat'``. - -``GeoIP`` API -============= - -.. class:: GeoIP(path=None, cache=0, country=None, city=None) - -The ``GeoIP`` object does not require any parameters to use the default -settings. However, at the very least the :setting:`GEOIP_PATH` setting -should be set with the path of the location of your GeoIP data sets. The -following initialization keywords may be used to customize any of the -defaults. - -=================== ======================================================= -Keyword Arguments Description -=================== ======================================================= -``path`` Base directory to where GeoIP data is located or the - full path to where the city or country data files - (.dat) are located. Assumes that both the city and - country data sets are located in this directory; - overrides the :setting:`GEOIP_PATH` settings attribute. - -``cache`` The cache settings when opening up the GeoIP datasets, - and may be an integer in (0, 1, 2, 4) corresponding to - the ``GEOIP_STANDARD``, ``GEOIP_MEMORY_CACHE``, - ``GEOIP_CHECK_CACHE``, and ``GEOIP_INDEX_CACHE`` - ``GeoIPOptions`` C API settings, respectively. - Defaults to 0 (``GEOIP_STANDARD``). - -``country`` The name of the GeoIP country data file. Defaults - to ``GeoIP.dat``. Setting this keyword overrides the - :setting:`GEOIP_COUNTRY` settings attribute. - -``city`` The name of the GeoIP city data file. Defaults to - ``GeoLiteCity.dat``. Setting this keyword overrides - the :setting:`GEOIP_CITY` settings attribute. -=================== ======================================================= - -``GeoIP`` Methods -================= - -Querying --------- - -All the following querying routines may take either a string IP address -or a fully qualified domain name (FQDN). For example, both -``'205.186.163.125'`` and ``'djangoproject.com'`` would be valid query -parameters. - -.. method:: GeoIP.city(query) - -Returns a dictionary of city information for the given query. Some -of the values in the dictionary may be undefined (``None``). - -.. method:: GeoIP.country(query) - -Returns a dictionary with the country code and country for the given -query. - -.. method:: GeoIP.country_code(query) - -Returns only the country code corresponding to the query. - -.. method:: GeoIP.country_name(query) - -Returns only the country name corresponding to the query. - -Coordinate Retrieval --------------------- - -.. method:: GeoIP.coords(query) - -Returns a coordinate tuple of (longitude, latitude). - -.. method:: GeoIP.lon_lat(query) - -Returns a coordinate tuple of (longitude, latitude). - -.. method:: GeoIP.lat_lon(query) - -Returns a coordinate tuple of (latitude, longitude), - -.. method:: GeoIP.geos(query) - -Returns a :class:`django.contrib.gis.geos.Point` object corresponding to the query. - -Database Information --------------------- - -.. attribute:: GeoIP.country_info - -This property returns information about the GeoIP country database. - -.. attribute:: GeoIP.city_info - -This property returns information about the GeoIP city database. - -.. attribute:: GeoIP.info - -This property returns information about all GeoIP databases (both city -and country), and the version of the GeoIP C library (if supported). - -GeoIP-Python API compatibility methods ----------------------------------------- - -These methods exist to ease compatibility with any code using MaxMind's -existing Python API. - -.. classmethod:: GeoIP.open(path, cache) - -This classmethod instantiates the GeoIP object from the given database path -and given cache setting. - -.. method:: GeoIP.region_by_addr(query) - -.. method:: GeoIP.region_by_name(query) - -.. method:: GeoIP.record_by_addr(query) - -.. method:: GeoIP.record_by_name(query) - -.. method:: GeoIP.country_code_by_addr(query) - -.. method:: GeoIP.country_code_by_name(query) - -.. method:: GeoIP.country_name_by_addr(query) - -.. method:: GeoIP.country_name_by_name(query) - -.. rubric:: Footnotes -.. [#] GeoIP(R) is a registered trademark of MaxMind, LLC of Boston, Massachusetts. diff --git a/docs/ref/contrib/gis/index.txt b/docs/ref/contrib/gis/index.txt index 7345a5140123..24d9172841cc 100644 --- a/docs/ref/contrib/gis/index.txt +++ b/docs/ref/contrib/gis/index.txt @@ -22,7 +22,6 @@ of spatially enabled data. measure geos gdal - geoip geoip2 utils commands diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 88b24e9b553f..35859c05ca7c 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -263,3 +263,5 @@ these features. * ``django.contrib.auth.tests.utils.skipIfCustomUser()`` is removed. * The ``GeoManager`` and ``GeoQuerySet`` classes are removed. + +* The ``django.contrib.gis.geoip`` module is removed. diff --git a/tests/gis_tests/test_geoip.py b/tests/gis_tests/test_geoip.py deleted file mode 100644 index 4871386ef848..000000000000 --- a/tests/gis_tests/test_geoip.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -import os -import socket -import unittest -import warnings -from unittest import skipUnless - -from django.conf import settings -from django.contrib.gis.geoip import HAS_GEOIP -from django.contrib.gis.geos import HAS_GEOS, GEOSGeometry -from django.test import ignore_warnings -from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning -from django.utils.encoding import force_text - -if HAS_GEOIP: - from django.contrib.gis.geoip import GeoIP, GeoIPException - from django.contrib.gis.geoip.prototypes import GeoIP_lib_version - - -# Note: Requires use of both the GeoIP country and city datasets. -# The GEOIP_DATA path should be the only setting set (the directory -# should contain links or the actual database files 'GeoIP.dat' and -# 'GeoLiteCity.dat'. - - -@skipUnless( - HAS_GEOIP and getattr(settings, "GEOIP_PATH", None), - "GeoIP is required along with the GEOIP_PATH setting." -) -@ignore_warnings(category=RemovedInDjango20Warning) -class GeoIPTest(unittest.TestCase): - addr = '162.242.220.127' - fqdn = 'www.djangoproject.com' - - def _is_dns_available(self, domain): - # Naive check to see if there is DNS available to use. - # Used to conditionally skip fqdn geoip checks. - # See #25407 for details. - ErrClass = socket.error if six.PY2 else OSError - try: - socket.gethostbyname(domain) - return True - except ErrClass: - return False - - def test01_init(self): - "Testing GeoIP initialization." - g1 = GeoIP() # Everything inferred from GeoIP path - path = settings.GEOIP_PATH - g2 = GeoIP(path, 0) # Passing in data path explicitly. - g3 = GeoIP.open(path, 0) # MaxMind Python API syntax. - - for g in (g1, g2, g3): - self.assertTrue(g._country) - self.assertTrue(g._city) - - # Only passing in the location of one database. - city = os.path.join(path, 'GeoLiteCity.dat') - cntry = os.path.join(path, 'GeoIP.dat') - g4 = GeoIP(city, country='') - self.assertIsNone(g4._country) - g5 = GeoIP(cntry, city='') - self.assertIsNone(g5._city) - - # Improper parameters. - bad_params = (23, 'foo', 15.23) - for bad in bad_params: - with self.assertRaises(GeoIPException): - GeoIP(cache=bad) - if isinstance(bad, six.string_types): - e = GeoIPException - else: - e = TypeError - with self.assertRaises(e): - GeoIP(bad, 0) - - def test02_bad_query(self): - "Testing GeoIP query parameter checking." - cntry_g = GeoIP(city='') - # No city database available, these calls should fail. - with self.assertRaises(GeoIPException): - cntry_g.city('google.com') - with self.assertRaises(GeoIPException): - cntry_g.coords('yahoo.com') - - # Non-string query should raise TypeError - with self.assertRaises(TypeError): - cntry_g.country_code(17) - with self.assertRaises(TypeError): - cntry_g.country_name(GeoIP) - - def test03_country(self): - "Testing GeoIP country querying methods." - g = GeoIP(city='') - - queries = [self.addr] - if self._is_dns_available(self.fqdn): - queries.append(self.fqdn) - for query in queries: - for func in (g.country_code, g.country_code_by_addr, g.country_code_by_name): - self.assertEqual('US', func(query), 'Failed for func %s and query %s' % (func, query)) - for func in (g.country_name, g.country_name_by_addr, g.country_name_by_name): - self.assertEqual('United States', func(query), 'Failed for func %s and query %s' % (func, query)) - self.assertEqual({'country_code': 'US', 'country_name': 'United States'}, - g.country(query)) - - @skipUnless(HAS_GEOS, "Geos is required") - def test04_city(self): - "Testing GeoIP city querying methods." - g = GeoIP(country='') - - queries = [self.addr] - if self._is_dns_available(self.fqdn): - queries.append(self.fqdn) - for query in queries: - # Country queries should still work. - for func in (g.country_code, g.country_code_by_addr, g.country_code_by_name): - self.assertEqual('US', func(query)) - for func in (g.country_name, g.country_name_by_addr, g.country_name_by_name): - self.assertEqual('United States', func(query)) - self.assertEqual({'country_code': 'US', 'country_name': 'United States'}, - g.country(query)) - - # City information dictionary. - d = g.city(query) - self.assertEqual('USA', d['country_code3']) - self.assertEqual('San Antonio', d['city']) - self.assertEqual('TX', d['region']) - self.assertEqual(210, d['area_code']) - geom = g.geos(query) - self.assertIsInstance(geom, GEOSGeometry) - lon, lat = (-98, 29) - lat_lon = g.lat_lon(query) - lat_lon = (lat_lon[1], lat_lon[0]) - for tup in (geom.tuple, g.coords(query), g.lon_lat(query), lat_lon): - self.assertAlmostEqual(lon, tup[0], 0) - self.assertAlmostEqual(lat, tup[1], 0) - - def test05_unicode_response(self): - "Testing that GeoIP strings are properly encoded, see #16553." - g = GeoIP() - fqdn = "hs-duesseldorf.de" - if self._is_dns_available(fqdn): - d = g.city(fqdn) - self.assertEqual('Düsseldorf', d['city']) - d = g.country('200.26.205.1') - # Some databases have only unaccented countries - self.assertIn(d['country_name'], ('Curaçao', 'Curacao')) - - def test_deprecation_warning(self): - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') - GeoIP() - - self.assertEqual(len(warns), 1) - msg = str(warns[0].message) - self.assertIn('django.contrib.gis.geoip is deprecated', msg) - - def test_repr(self): - path = settings.GEOIP_PATH - g = GeoIP(path=path) - country_path = g._country_file - city_path = g._city_file - if GeoIP_lib_version: - expected = '' % { - 'version': force_text(GeoIP_lib_version()), - 'country': country_path, - 'city': city_path, - } - else: - expected = '' % { - 'country': country_path, - 'city': city_path, - } - self.assertEqual(repr(g), expected) From 5d8da093a974f41e08573bbe0d32d5ffeaadd0ad Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 30 Dec 2016 20:09:26 -0500 Subject: [PATCH 0015/3180] Refs #15053 -- Removed support for non-recursive template loading. Per deprecation timeline. --- django/template/engine.py | 20 +--- django/template/loader_tags.py | 21 ---- django/template/loaders/base.py | 61 +----------- django/template/loaders/cached.py | 91 ++---------------- django/template/loaders/eggs.py | 18 ---- django/template/loaders/filesystem.py | 21 +--- django/template/loaders/locmem.py | 14 --- docs/ref/templates/api.txt | 31 ------ docs/releases/2.0.txt | 20 ++++ .../syntax_tests/test_include.py | 3 - tests/template_tests/test_extends.py | 66 +------------ tests/template_tests/test_loaders.py | 96 +------------------ 12 files changed, 40 insertions(+), 422 deletions(-) diff --git a/django/template/engine.py b/django/template/engine.py index 729c484a6731..154276a5b063 100644 --- a/django/template/engine.py +++ b/django/template/engine.py @@ -130,21 +130,11 @@ def find_template_loader(self, loader): def find_template(self, name, dirs=None, skip=None): tried = [] for loader in self.template_loaders: - if loader.supports_recursion: - try: - template = loader.get_template( - name, template_dirs=dirs, skip=skip, - ) - return template, template.origin - except TemplateDoesNotExist as e: - tried.extend(e.tried) - else: - # RemovedInDjango20Warning: Use old api for non-recursive - # loaders. - try: - return loader(name, dirs) - except TemplateDoesNotExist: - pass + try: + template = loader.get_template(name, skip=skip) + return template, template.origin + except TemplateDoesNotExist as e: + tried.extend(e.tried) raise TemplateDoesNotExist(name, tried=tried) def from_string(self, template_code): diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py index 2ed145c2489f..e5c44c88b08e 100644 --- a/django/template/loader_tags.py +++ b/django/template/loader_tags.py @@ -19,10 +19,6 @@ logger = logging.getLogger('django.template') -class ExtendsError(Exception): - pass - - class BlockContext(object): def __init__(self): # Dictionary of FIFO queues. @@ -107,23 +103,6 @@ def find_template(self, template_name, context): passed as the skip argument. This enables extends to work recursively without extending the same template twice. """ - # RemovedInDjango20Warning: If any non-recursive loaders are installed - # do a direct template lookup. If the same template name appears twice, - # raise an exception to avoid system recursion. - for loader in context.template.engine.template_loaders: - if not loader.supports_recursion: - history = context.render_context.setdefault( - self.context_key, [context.template.origin.template_name], - ) - if template_name in history: - raise ExtendsError( - "Cannot extend templates recursively when using " - "non-recursive template loaders", - ) - template = context.template.engine.get_template(template_name) - history.append(template_name) - return template - history = context.render_context.setdefault( self.context_key, [context.template.origin], ) diff --git a/django/template/loaders/base.py b/django/template/loaders/base.py index 5d49f9bfbad8..cb1807fd7e32 100644 --- a/django/template/loaders/base.py +++ b/django/template/loaders/base.py @@ -1,8 +1,4 @@ -import warnings - -from django.template import Origin, Template, TemplateDoesNotExist -from django.utils.deprecation import RemovedInDjango20Warning -from django.utils.inspect import func_supports_parameter +from django.template import Template, TemplateDoesNotExist class Loader(object): @@ -10,11 +6,7 @@ class Loader(object): def __init__(self, engine): self.engine = engine - def __call__(self, template_name, template_dirs=None): - # RemovedInDjango20Warning: Allow loaders to be called like functions. - return self.load_template(template_name, template_dirs) - - def get_template(self, template_name, template_dirs=None, skip=None): + def get_template(self, template_name, skip=None): """ Calls self.get_template_sources() and returns a Template object for the first template matching template_name. If skip is provided, @@ -23,13 +15,7 @@ def get_template(self, template_name, template_dirs=None, skip=None): """ tried = [] - args = [template_name] - # RemovedInDjango20Warning: Add template_dirs for compatibility with - # old loaders - if func_supports_parameter(self.get_template_sources, 'template_dirs'): - args.append(template_dirs) - - for origin in self.get_template_sources(*args): + for origin in self.get_template_sources(template_name): if skip is not None and origin in skip: tried.append((origin, 'Skipped')) continue @@ -46,30 +32,6 @@ def get_template(self, template_name, template_dirs=None, skip=None): raise TemplateDoesNotExist(template_name, tried=tried) - def load_template(self, template_name, template_dirs=None): - warnings.warn( - 'The load_template() method is deprecated. Use get_template() ' - 'instead.', RemovedInDjango20Warning, - ) - source, display_name = self.load_template_source( - template_name, template_dirs, - ) - origin = Origin( - name=display_name, - template_name=template_name, - loader=self, - ) - try: - template = Template(source, origin, template_name, self.engine) - except TemplateDoesNotExist: - # If compiling the template we found raises TemplateDoesNotExist, - # back off to returning the source and display name for the - # template we were asked to load. This allows for correct - # identification of the actual template that does not exist. - return source, display_name - else: - return template, None - def get_template_sources(self, template_name): """ An iterator that yields possible matching template paths for a @@ -79,26 +41,9 @@ def get_template_sources(self, template_name): 'subclasses of Loader must provide a get_template_sources() method' ) - def load_template_source(self, template_name, template_dirs=None): - """ - RemovedInDjango20Warning: Returns a tuple containing the source and - origin for the given template name. - """ - raise NotImplementedError( - 'subclasses of Loader must provide a load_template_source() method' - ) - def reset(self): """ Resets any state maintained by the loader instance (e.g. cached templates or cached loader modules). """ pass - - @property - def supports_recursion(self): - """ - RemovedInDjango20Warning: This is an internal property used by the - ExtendsNode during the deprecation of non-recursive loaders. - """ - return hasattr(self, 'get_contents') diff --git a/django/template/loaders/cached.py b/django/template/loaders/cached.py index 104a3356a73d..1b9ee98c952a 100644 --- a/django/template/loaders/cached.py +++ b/django/template/loaders/cached.py @@ -4,13 +4,10 @@ """ import hashlib -import warnings -from django.template import Origin, Template, TemplateDoesNotExist +from django.template import TemplateDoesNotExist from django.template.backends.django import copy_exception -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_bytes, force_text -from django.utils.inspect import func_supports_parameter from .base import Loader as BaseLoader @@ -19,7 +16,6 @@ class Loader(BaseLoader): def __init__(self, engine, loaders): self.template_cache = {} - self.find_template_cache = {} # RemovedInDjango20Warning self.get_template_cache = {} self.loaders = engine.get_template_loaders(loaders) super(Loader, self).__init__(engine) @@ -27,7 +23,7 @@ def __init__(self, engine, loaders): def get_contents(self, origin): return origin.loader.get_contents(origin) - def get_template(self, template_name, template_dirs=None, skip=None): + def get_template(self, template_name, skip=None): """ Perform the caching that gives this loader its name. Often many of the templates attempted will be missing, so memory use is of concern here. @@ -46,7 +42,7 @@ def get_template(self, template_name, template_dirs=None, skip=None): memory leak. Thus, unraised copies of the exceptions are cached and copies of those copies are raised after they're fetched from the cache. """ - key = self.cache_key(template_name, template_dirs, skip) + key = self.cache_key(template_name, skip) cached = self.get_template_cache.get(key) if cached: if isinstance(cached, type) and issubclass(cached, TemplateDoesNotExist): @@ -56,9 +52,7 @@ def get_template(self, template_name, template_dirs=None, skip=None): return cached try: - template = super(Loader, self).get_template( - template_name, template_dirs, skip, - ) + template = super(Loader, self).get_template(template_name, skip) except TemplateDoesNotExist as e: self.get_template_cache[key] = copy_exception(e) if self.engine.debug else TemplateDoesNotExist raise @@ -67,17 +61,12 @@ def get_template(self, template_name, template_dirs=None, skip=None): return template - def get_template_sources(self, template_name, template_dirs=None): + def get_template_sources(self, template_name): for loader in self.loaders: - args = [template_name] - # RemovedInDjango20Warning: Add template_dirs for compatibility - # with old loaders - if func_supports_parameter(loader.get_template_sources, 'template_dirs'): - args.append(template_dirs) - for origin in loader.get_template_sources(*args): + for origin in loader.get_template_sources(template_name): yield origin - def cache_key(self, template_name, template_dirs, skip=None): + def cache_key(self, template_name, skip=None): """ Generate a cache key for the template name, dirs, and skip. @@ -97,78 +86,12 @@ def cache_key(self, template_name, template_dirs, skip=None): if matching: skip_prefix = self.generate_hash(matching) - if template_dirs: - dirs_prefix = self.generate_hash(template_dirs) - return '-'.join(filter(bool, [force_text(template_name), skip_prefix, dirs_prefix])) def generate_hash(self, values): return hashlib.sha1(force_bytes('|'.join(values))).hexdigest() - @property - def supports_recursion(self): - """ - RemovedInDjango20Warning: This is an internal property used by the - ExtendsNode during the deprecation of non-recursive loaders. - """ - return all(hasattr(loader, 'get_contents') for loader in self.loaders) - - def find_template(self, name, dirs=None): - """ - RemovedInDjango20Warning: An internal method to lookup the template - name in all the configured loaders. - """ - key = self.cache_key(name, dirs) - try: - result = self.find_template_cache[key] - except KeyError: - result = None - for loader in self.loaders: - try: - template, display_name = loader(name, dirs) - except TemplateDoesNotExist: - pass - else: - origin = Origin( - name=display_name, - template_name=name, - loader=loader, - ) - result = template, origin - break - self.find_template_cache[key] = result - if result: - return result - else: - self.template_cache[key] = TemplateDoesNotExist - raise TemplateDoesNotExist(name) - - def load_template(self, template_name, template_dirs=None): - warnings.warn( - 'The load_template() method is deprecated. Use get_template() ' - 'instead.', RemovedInDjango20Warning, - ) - key = self.cache_key(template_name, template_dirs) - template_tuple = self.template_cache.get(key) - # A cached previous failure: - if template_tuple is TemplateDoesNotExist: - raise TemplateDoesNotExist(template_name) - elif template_tuple is None: - template, origin = self.find_template(template_name, template_dirs) - if not hasattr(template, 'render'): - try: - template = Template(template, origin, template_name, self.engine) - except TemplateDoesNotExist: - # If compiling the template we found raises TemplateDoesNotExist, - # back off to returning the source and display name for the template - # we were asked to load. This allows for correct identification (later) - # of the actual template that does not exist. - self.template_cache[key] = (template, origin) - self.template_cache[key] = (template, None) - return self.template_cache[key] - def reset(self): "Empty the template cache." self.template_cache.clear() - self.find_template_cache.clear() # RemovedInDjango20Warning self.get_template_cache.clear() diff --git a/django/template/loaders/eggs.py b/django/template/loaders/eggs.py index 90dfe685f0c8..3013a8586dda 100644 --- a/django/template/loaders/eggs.py +++ b/django/template/loaders/eggs.py @@ -54,21 +54,3 @@ def get_template_sources(self, template_name): template_name=template_name, loader=self, ) - - def load_template_source(self, template_name, template_dirs=None): - """ - Loads templates from Python eggs via pkg_resource.resource_string. - - For every installed app, it tries to get the resource (app, template_name). - """ - warnings.warn( - 'The load_template_sources() method is deprecated. Use ' - 'get_template() or get_contents() instead.', - RemovedInDjango20Warning, - ) - for origin in self.get_template_sources(template_name): - try: - return self.get_contents(origin), origin.name - except TemplateDoesNotExist: - pass - raise TemplateDoesNotExist(template_name) diff --git a/django/template/loaders/filesystem.py b/django/template/loaders/filesystem.py index da2c46ff0826..bd126a0c6ba2 100644 --- a/django/template/loaders/filesystem.py +++ b/django/template/loaders/filesystem.py @@ -4,12 +4,10 @@ import errno import io -import warnings from django.core.exceptions import SuspiciousFileOperation from django.template import Origin, TemplateDoesNotExist from django.utils._os import safe_join -from django.utils.deprecation import RemovedInDjango20Warning from .base import Loader as BaseLoader @@ -32,15 +30,13 @@ def get_contents(self, origin): raise TemplateDoesNotExist(origin) raise - def get_template_sources(self, template_name, template_dirs=None): + def get_template_sources(self, template_name): """ Return an Origin object pointing to an absolute path in each directory in template_dirs. For security reasons, if a path doesn't lie inside one of the template_dirs it is excluded from the result set. """ - if not template_dirs: - template_dirs = self.get_dirs() - for template_dir in template_dirs: + for template_dir in self.get_dirs(): try: name = safe_join(template_dir, template_name) except SuspiciousFileOperation: @@ -53,16 +49,3 @@ def get_template_sources(self, template_name, template_dirs=None): template_name=template_name, loader=self, ) - - def load_template_source(self, template_name, template_dirs=None): - warnings.warn( - 'The load_template_sources() method is deprecated. Use ' - 'get_template() or get_contents() instead.', - RemovedInDjango20Warning, - ) - for origin in self.get_template_sources(template_name, template_dirs): - try: - return self.get_contents(origin), origin.name - except TemplateDoesNotExist: - pass - raise TemplateDoesNotExist(template_name) diff --git a/django/template/loaders/locmem.py b/django/template/loaders/locmem.py index a27dcd845b53..1b77c9805b6d 100644 --- a/django/template/loaders/locmem.py +++ b/django/template/loaders/locmem.py @@ -2,10 +2,7 @@ Wrapper for loading templates from a plain Python dict. """ -import warnings - from django.template import Origin, TemplateDoesNotExist -from django.utils.deprecation import RemovedInDjango20Warning from .base import Loader as BaseLoader @@ -28,14 +25,3 @@ def get_template_sources(self, template_name): template_name=template_name, loader=self, ) - - def load_template_source(self, template_name, template_dirs=None): - warnings.warn( - 'The load_template_sources() method is deprecated. Use ' - 'get_template() or get_contents() instead.', - RemovedInDjango20Warning, - ) - try: - return self.templates_dict[template_name], template_name - except KeyError: - raise TemplateDoesNotExist(template_name) diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt index 2057c370f3ca..305945a856be 100644 --- a/docs/ref/templates/api.txt +++ b/docs/ref/templates/api.txt @@ -1057,37 +1057,6 @@ Loader methods :meth:`get_contents` for custom template loaders. ``get_template()`` will usually not need to be overridden. - .. method:: load_template_source(template_name, template_dirs=None) - - Returns a tuple of (``template_string``, ``template_origin``), where - ``template_string`` is a string containing the template contents, - and ``template_origin`` is a string identifying the template source. - A filesystem-based loader may return the full path to the file as the - ``template_origin``, for example. - - ``template_dirs`` is an optional argument used to control which - directories the loader will search. - - This method is called automatically by :meth:`load_template` and should - be overridden when writing custom template loaders. - - .. deprecated:: 1.9 - - Custom loaders should use :meth:`get_template` and - :meth:`get_contents` instead. - - .. method:: load_template(template_name, template_dirs=None) - - Returns a tuple of (``template``, ``template_origin``), where ``template`` - is a ``Template`` object and ``template_origin`` is a string identifying - the template source. A filesystem-based loader may return the full - path to the file as the ``template_origin``, for example. - - .. deprecated:: 1.9 - - Custom loaders should use :meth:`get_template` and - :meth:`get_contents` instead. - .. admonition:: Building your own For examples, `read the source code for Django's built-in loaders`_. diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 35859c05ca7c..a6d85697b50a 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -265,3 +265,23 @@ these features. * The ``GeoManager`` and ``GeoQuerySet`` classes are removed. * The ``django.contrib.gis.geoip`` module is removed. + +* The ``supports_recursion`` check for template loaders is removed from: + + * ``django.template.engine.Engine.find_template()`` + * ``django.template.loader_tags.ExtendsNode.find_template()`` + * ``django.template.loaders.base.Loader.supports_recursion()`` + * ``django.template.loaders.cached.Loader.supports_recursion()`` + +* The ``load_template`` and ``load_template_sources`` template loader methods + are removed. + +* The ``template_dirs`` argument for template loaders is removed: + + * ``django.template.loaders.base.Loader.get_template()`` + * ``django.template.loaders.cached.Loader.cache_key()`` + * ``django.template.loaders.cached.Loader.get_template()`` + * ``django.template.loaders.cached.Loader.get_template_sources()`` + * ``django.template.loaders.filesystem.Loader.get_template_sources()`` + +* ``django.template.loaders.base.Loader.__call__()`` is removed. diff --git a/tests/template_tests/syntax_tests/test_include.py b/tests/template_tests/syntax_tests/test_include.py index ca7ee6f5b0b8..1ef76c701107 100644 --- a/tests/template_tests/syntax_tests/test_include.py +++ b/tests/template_tests/syntax_tests/test_include.py @@ -248,9 +248,6 @@ def test_extends_include_missing_baseloader(self): self.assertEqual(e.exception.args[0], 'missing.html') def test_extends_include_missing_cachedloader(self): - """ - Test the cache loader separately since it overrides load_template. - """ engine = Engine(debug=True, loaders=[ ('django.template.loaders.cached.Loader', [ 'django.template.loaders.app_directories.Loader', diff --git a/tests/template_tests/test_extends.py b/tests/template_tests/test_extends.py index 1d7e00b60d08..270160a82a26 100644 --- a/tests/template_tests/test_extends.py +++ b/tests/template_tests/test_extends.py @@ -1,10 +1,7 @@ import os from django.template import Context, Engine, TemplateDoesNotExist -from django.template.loader_tags import ExtendsError -from django.template.loaders.base import Loader -from django.test import SimpleTestCase, ignore_warnings -from django.utils.deprecation import RemovedInDjango20Warning +from django.test import SimpleTestCase from .utils import ROOT @@ -120,64 +117,3 @@ def test_unique_history_per_loader(self): template = engine.get_template('base.html') output = template.render(Context({})) self.assertEqual(output.strip(), 'loader2 loader1') - - -class NonRecursiveLoader(Loader): - - def __init__(self, engine, templates_dict): - self.templates_dict = templates_dict - super(NonRecursiveLoader, self).__init__(engine) - - def load_template_source(self, template_name, template_dirs=None): - try: - return self.templates_dict[template_name], template_name - except KeyError: - raise TemplateDoesNotExist(template_name) - - -@ignore_warnings(category=RemovedInDjango20Warning) -class NonRecursiveLoaderExtendsTests(SimpleTestCase): - - loaders = [ - ('template_tests.test_extends.NonRecursiveLoader', { - 'base.html': 'base', - 'index.html': '{% extends "base.html" %}', - 'recursive.html': '{% extends "recursive.html" %}', - 'other-recursive.html': '{% extends "recursive.html" %}', - 'a.html': '{% extends "b.html" %}', - 'b.html': '{% extends "a.html" %}', - }), - ] - - def test_extend(self): - engine = Engine(loaders=self.loaders) - output = engine.render_to_string('index.html') - self.assertEqual(output, 'base') - - def test_extend_cached(self): - engine = Engine(loaders=[ - ('django.template.loaders.cached.Loader', self.loaders), - ]) - output = engine.render_to_string('index.html') - self.assertEqual(output, 'base') - - cache = engine.template_loaders[0].template_cache - self.assertIn('base.html', cache) - self.assertIn('index.html', cache) - - # Render a second time from cache - output = engine.render_to_string('index.html') - self.assertEqual(output, 'base') - - def test_extend_error(self): - engine = Engine(loaders=self.loaders) - msg = 'Cannot extend templates recursively when using non-recursive template loaders' - - with self.assertRaisesMessage(ExtendsError, msg): - engine.render_to_string('recursive.html') - - with self.assertRaisesMessage(ExtendsError, msg): - engine.render_to_string('other-recursive.html') - - with self.assertRaisesMessage(ExtendsError, msg): - engine.render_to_string('a.html') diff --git a/tests/template_tests/test_loaders.py b/tests/template_tests/test_loaders.py index 22f32941feb7..22fb1d812c1a 100644 --- a/tests/template_tests/test_loaders.py +++ b/tests/template_tests/test_loaders.py @@ -91,62 +91,6 @@ def test_cached_exception_no_traceback(self): self.assertIsNone(e.__context__, error_msg) self.assertIsNone(e.__cause__, error_msg) - @ignore_warnings(category=RemovedInDjango20Warning) - def test_load_template(self): - loader = self.engine.template_loaders[0] - template, origin = loader.load_template('index.html') - self.assertEqual(template.origin.template_name, 'index.html') - - cache = self.engine.template_loaders[0].template_cache - self.assertEqual(cache['index.html'][0], template) - - # Run a second time from cache - loader = self.engine.template_loaders[0] - source, name = loader.load_template('index.html') - self.assertEqual(template.origin.template_name, 'index.html') - - @ignore_warnings(category=RemovedInDjango20Warning) - def test_load_template_missing(self): - """ - #19949 -- TemplateDoesNotExist exceptions should be cached. - """ - loader = self.engine.template_loaders[0] - - self.assertNotIn('missing.html', loader.template_cache) - - with self.assertRaises(TemplateDoesNotExist): - loader.load_template("missing.html") - - self.assertEqual( - loader.template_cache["missing.html"], - TemplateDoesNotExist, - "Cached loader failed to cache the TemplateDoesNotExist exception", - ) - - @ignore_warnings(category=RemovedInDjango20Warning) - def test_load_nonexistent_cached_template(self): - loader = self.engine.template_loaders[0] - template_name = 'nonexistent.html' - - # fill the template cache - with self.assertRaises(TemplateDoesNotExist): - loader.find_template(template_name) - - with self.assertRaisesMessage(TemplateDoesNotExist, template_name): - loader.get_template(template_name) - - def test_templatedir_caching(self): - """ - #13573 -- Template directories should be part of the cache key. - """ - # Retrieve a template specifying a template directory to check - t1, name = self.engine.find_template('test.html', (os.path.join(TEMPLATE_DIR, 'first'),)) - # Now retrieve the same template name, but from a different directory - t2, name = self.engine.find_template('test.html', (os.path.join(TEMPLATE_DIR, 'second'),)) - - # The two templates should not have the same content - self.assertNotEqual(t1.render(Context({})), t2.render(Context({}))) - def test_template_name_leading_dash_caching(self): """ #26536 -- A leading dash in a template name shouldn't be stripped @@ -239,20 +183,6 @@ def test_get_template(self): output = template.render(Context({})) self.assertEqual(output, "y") - @ignore_warnings(category=RemovedInDjango20Warning) - def test_load_template_source(self): - loader = self.engine.template_loaders[0] - templates = { - os.path.normcase('templates/y.html'): six.StringIO("y"), - } - - with self.create_egg('egg', templates): - with override_settings(INSTALLED_APPS=['egg']): - source, name = loader.load_template_source('y.html') - - self.assertEqual(source.strip(), 'y') - self.assertEqual(name, 'egg:egg:templates/y.html') - def test_non_existing(self): """ Template loading fails if the template is not in the egg. @@ -323,13 +253,6 @@ def test_loaders_dirs_empty(self): with self.assertRaises(TemplateDoesNotExist): engine.get_template('index.html') - @ignore_warnings(category=RemovedInDjango20Warning) - def test_load_template_source(self): - loader = self.engine.template_loaders[0] - source, name = loader.load_template_source('index.html') - self.assertEqual(source.strip(), 'index') - self.assertEqual(name, os.path.join(TEMPLATE_DIR, 'index.html')) - def test_directory_security(self): with self.source_checker(['/dir1', '/dir2']) as check_sources: check_sources('index.html', ['/dir1/index.html', '/dir2/index.html']) @@ -353,10 +276,10 @@ def test_utf8_bytestring(self): """ Invalid UTF-8 encoding in bytestrings should raise a useful error """ - engine = Engine() + engine = self.engine loader = engine.template_loaders[0] with self.assertRaises(UnicodeDecodeError): - list(loader.get_template_sources(b'\xc3\xc3', ['/dir1'])) + list(loader.get_template_sources(b'\xc3\xc3')) def test_unicode_dir_name(self): with self.source_checker([b'/Stra\xc3\x9fe']) as check_sources: @@ -410,14 +333,6 @@ def test_get_template(self): self.assertEqual(template.origin.template_name, 'index.html') self.assertEqual(template.origin.loader, self.engine.template_loaders[0]) - @ignore_warnings(category=RemovedInDjango20Warning) - @override_settings(INSTALLED_APPS=['template_tests']) - def test_load_template_source(self): - loader = self.engine.template_loaders[0] - source, name = loader.load_template_source('index.html') - self.assertEqual(source.strip(), 'index') - self.assertEqual(name, os.path.join(TEMPLATE_DIR, 'index.html')) - @override_settings(INSTALLED_APPS=[]) def test_not_installed(self): with self.assertRaises(TemplateDoesNotExist): @@ -440,10 +355,3 @@ def test_get_template(self): self.assertEqual(template.origin.name, 'index.html') self.assertEqual(template.origin.template_name, 'index.html') self.assertEqual(template.origin.loader, self.engine.template_loaders[0]) - - @ignore_warnings(category=RemovedInDjango20Warning) - def test_load_template_source(self): - loader = self.engine.template_loaders[0] - source, name = loader.load_template_source('index.html') - self.assertEqual(source.strip(), 'index') - self.assertEqual(name, 'index.html') From 3cee9edd1b3e1a11ecdfeecef6f2247c10c859fb Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 07:05:37 -0500 Subject: [PATCH 0016/3180] Refs #24733 -- Removed support for error views without the exception parameter. Per deprecation timeline. --- django/core/handlers/exception.py | 15 +-------------- docs/releases/2.0.txt | 3 +++ 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/django/core/handlers/exception.py b/django/core/handlers/exception.py index f1c7b5789127..ab859405f389 100644 --- a/django/core/handlers/exception.py +++ b/django/core/handlers/exception.py @@ -2,7 +2,6 @@ import logging import sys -import warnings from functools import wraps from django.conf import settings @@ -12,7 +11,6 @@ from django.http.multipartparser import MultiPartParserError from django.urls import get_resolver, get_urlconf from django.utils.decorators import available_attrs -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.views import debug @@ -94,18 +92,7 @@ def response_for_exception(request, exc): def get_exception_response(request, resolver, status_code, exception, sender=None): try: callback, param_dict = resolver.resolve_error_handler(status_code) - # Unfortunately, inspect.getargspec result is not trustable enough - # depending on the callback wrapping in decorators (frequent for handlers). - # Falling back on try/except: - try: - response = callback(request, **dict(param_dict, exception=exception)) - except TypeError: - warnings.warn( - "Error handlers should accept an exception parameter. Update " - "your code as this parameter will be required in Django 2.0", - RemovedInDjango20Warning, stacklevel=2 - ) - response = callback(request, **param_dict) + response = callback(request, **dict(param_dict, exception=exception)) except Exception: signals.got_request_exception.send(sender=sender, request=request) response = handle_uncaught_exception(request, resolver, sys.exc_info()) diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index a6d85697b50a..aec9e9139225 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -285,3 +285,6 @@ these features. * ``django.template.loaders.filesystem.Loader.get_template_sources()`` * ``django.template.loaders.base.Loader.__call__()`` is removed. + +* Support for custom error views that don't accept an ``exception`` parameter + is removed. From c6de8cca208fb471723619970c09ecb3bd335362 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 07:10:04 -0500 Subject: [PATCH 0017/3180] Refs #24728 - Removed Atom1Feed/RssFeed mime_type attribute. Per deprecation timeline. --- django/utils/feedgenerator.py | 18 ------------------ docs/releases/2.0.txt | 3 +++ 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py index c9c1e787f892..a27eb1f2e93f 100644 --- a/django/utils/feedgenerator.py +++ b/django/utils/feedgenerator.py @@ -278,15 +278,6 @@ def add_root_elements(self, handler): def endChannelElement(self, handler): handler.endElement("channel") - @property - def mime_type(self): - warnings.warn( - 'The mime_type attribute of RssFeed is deprecated. ' - 'Use content_type instead.', - RemovedInDjango20Warning, stacklevel=2 - ) - return self.content_type - class RssUserland091Feed(RssFeed): _version = "0.91" @@ -445,15 +436,6 @@ def add_item_elements(self, handler, item): if item['item_copyright'] is not None: handler.addQuickElement("rights", item['item_copyright']) - @property - def mime_type(self): - warnings.warn( - 'The mime_type attribute of Atom1Feed is deprecated. ' - 'Use content_type instead.', - RemovedInDjango20Warning, stacklevel=2 - ) - return self.content_type - # This isolates the decision of what the system default is, so calling code can # do "feedgenerator.DefaultFeed" instead of "feedgenerator.Rss201rev2Feed". diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index aec9e9139225..348572a75ff7 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -288,3 +288,6 @@ these features. * Support for custom error views that don't accept an ``exception`` parameter is removed. + +* The ``mime_type`` attribute of ``django.utils.feedgenerator.Atom1Feed`` and + ``django.utils.feedgenerator.RssFeed`` is removed. From ad393beeb71e8774e4bf9ad842b97022e50f1231 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 10 Jan 2017 09:57:49 -0500 Subject: [PATCH 0018/3180] Refs #21927 -- Removed include()'s app_name argument per deprecation timeline. Also removed support for passing a 3-tuple to include() and support for setting an instance namespace without an application namespace. Thanks Marten Kenbeek for completing the patch. --- django/conf/urls/__init__.py | 25 +-- docs/ref/urls.txt | 24 +-- docs/releases/2.0.txt | 8 + .../included_namespace_urls.py | 7 +- tests/urlpatterns_reverse/namespace_urls.py | 17 +- tests/urlpatterns_reverse/tests.py | 159 ++++++++++-------- tests/urlpatterns_reverse/utils.py | 2 +- 7 files changed, 117 insertions(+), 125 deletions(-) diff --git a/django/conf/urls/__init__.py b/django/conf/urls/__init__.py index 03879bccd4ca..45af3a10d239 100644 --- a/django/conf/urls/__init__.py +++ b/django/conf/urls/__init__.py @@ -1,4 +1,3 @@ -import warnings from importlib import import_module from django.core.exceptions import ImproperlyConfigured @@ -6,7 +5,6 @@ LocaleRegexURLResolver, RegexURLPattern, RegexURLResolver, ) from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning __all__ = ['handler400', 'handler403', 'handler404', 'handler500', 'include', 'url'] @@ -16,16 +14,8 @@ handler500 = 'django.views.defaults.server_error' -def include(arg, namespace=None, app_name=None): - if app_name and not namespace: - raise ValueError('Must specify a namespace if specifying app_name.') - if app_name: - warnings.warn( - 'The app_name argument to django.conf.urls.include() is deprecated. ' - 'Set the app_name in the included URLconf instead.', - RemovedInDjango20Warning, stacklevel=2 - ) - +def include(arg, namespace=None): + app_name = None if isinstance(arg, tuple): # callable returning a namespace hint try: @@ -35,13 +25,11 @@ def include(arg, namespace=None, app_name=None): raise ImproperlyConfigured( 'Cannot override the namespace for a dynamic module that provides a namespace' ) - warnings.warn( - 'Passing a 3-tuple to django.conf.urls.include() is deprecated. ' + raise ImproperlyConfigured( + 'Passing a 3-tuple to django.conf.urls.include() is not supported. ' 'Pass a 2-tuple containing the list of patterns and app_name, ' 'and provide the namespace argument to include() instead.', - RemovedInDjango20Warning, stacklevel=2 ) - urlconf_module, app_name, namespace = arg else: # No namespace hint - use manually provided namespace urlconf_module = arg @@ -51,12 +39,11 @@ def include(arg, namespace=None, app_name=None): patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module) app_name = getattr(urlconf_module, 'app_name', app_name) if namespace and not app_name: - warnings.warn( + raise ImproperlyConfigured( 'Specifying a namespace in django.conf.urls.include() without ' - 'providing an app_name is deprecated. Set the app_name attribute ' + 'providing an app_name is not supported. Set the app_name attribute ' 'in the included module, or pass a 2-tuple containing the list of ' 'patterns and app_name instead.', - RemovedInDjango20Warning, stacklevel=2 ) namespace = namespace or app_name diff --git a/docs/ref/urls.txt b/docs/ref/urls.txt index d1464da66d26..505295ede43e 100644 --- a/docs/ref/urls.txt +++ b/docs/ref/urls.txt @@ -53,10 +53,9 @@ parameter is useful. ``include()`` ============= -.. function:: include(module, namespace=None, app_name=None) +.. function:: include(module, namespace=None) include(pattern_list) include((pattern_list, app_namespace), namespace=None) - include((pattern_list, app_namespace, instance_namespace)) A function that takes a full Python import path to another URLconf module that should be "included" in this place. Optionally, the :term:`application @@ -68,15 +67,12 @@ parameter is useful. can be used to set a different instance namespace. ``include()`` also accepts as an argument either an iterable that returns - URL patterns, a 2-tuple containing such iterable plus the names of the - application namespaces, or a 3-tuple containing the iterable and the names - of both the application and instance namespace. + URL patterns or a 2-tuple containing such iterable plus the names of the + application namespaces. :arg module: URLconf module (or module name) :arg namespace: Instance namespace for the URL entries being included :type namespace: string - :arg app_name: Application namespace for the URL entries being included - :type app_name: string :arg pattern_list: Iterable of :func:`django.conf.urls.url` instances :arg app_namespace: Application namespace for the URL entries being included :type app_namespace: string @@ -85,20 +81,6 @@ parameter is useful. See :ref:`including-other-urlconfs` and :ref:`namespaces-and-include`. -.. deprecated:: 1.9 - - Support for the ``app_name`` argument is deprecated and will be removed in - Django 2.0. Specify the ``app_name`` as explained in - :ref:`namespaces-and-include` instead. - - Support for passing a 3-tuple is also deprecated and will be removed in - Django 2.0. Pass a 2-tuple containing the pattern list and application - namespace, and use the ``namespace`` argument instead. - - Lastly, support for an instance namespace without an application namespace - has been deprecated and will be removed in Django 2.0. Specify the - application namespace or remove the instance namespace. - ``handler400`` ============== diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 348572a75ff7..0ae25a82952c 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -291,3 +291,11 @@ these features. * The ``mime_type`` attribute of ``django.utils.feedgenerator.Atom1Feed`` and ``django.utils.feedgenerator.RssFeed`` is removed. + +* The ``app_name`` argument to ``include()`` is removed. + +* Support for passing a 3-tuple as the first argument to ``include()`` is + removed. + +* Support for setting a URL instance namespace without an application namespace + is removed. diff --git a/tests/urlpatterns_reverse/included_namespace_urls.py b/tests/urlpatterns_reverse/included_namespace_urls.py index 4f68e4c6025b..75b0bf1971f3 100644 --- a/tests/urlpatterns_reverse/included_namespace_urls.py +++ b/tests/urlpatterns_reverse/included_namespace_urls.py @@ -6,6 +6,7 @@ testobj3 = URLObject('testapp', 'test-ns3') testobj4 = URLObject('testapp', 'test-ns4') +app_name = 'included_namespace_urls' urlpatterns = [ url(r'^normal/$', empty_view, name='inc-normal-view'), url(r'^normal/(?P[0-9]+)/(?P[0-9]+)/$', empty_view, name='inc-normal-view'), @@ -17,8 +18,8 @@ url(r'^view_class/(?P[0-9]+)/(?P[0-9]+)/$', view_class_instance, name='inc-view-class'), - url(r'^test3/', include(testobj3.urls)), - url(r'^test4/', include(testobj4.urls)), - url(r'^ns-included3/', include('urlpatterns_reverse.included_urls', namespace='inc-ns3')), + url(r'^test3/', include(*testobj3.urls)), + url(r'^test4/', include(*testobj4.urls)), + url(r'^ns-included3/', include(('urlpatterns_reverse.included_urls', 'included_urls'), namespace='inc-ns3')), url(r'^ns-included4/', include('urlpatterns_reverse.namespace_urls', namespace='inc-ns4')), ] diff --git a/tests/urlpatterns_reverse/namespace_urls.py b/tests/urlpatterns_reverse/namespace_urls.py index fa6359dec2bf..a92df2716a28 100644 --- a/tests/urlpatterns_reverse/namespace_urls.py +++ b/tests/urlpatterns_reverse/namespace_urls.py @@ -12,6 +12,7 @@ newappobj1 = URLObject('newapp') +app_name = 'namespace_urls' urlpatterns = [ url(r'^normal/$', views.empty_view, name='normal-view'), url(r'^normal/(?P[0-9]+)/(?P[0-9]+)/$', views.empty_view, name='normal-view'), @@ -27,12 +28,12 @@ url(r'^unnamed/normal/(?P[0-9]+)/(?P[0-9]+)/$', views.empty_view), url(r'^unnamed/view_class/(?P[0-9]+)/(?P[0-9]+)/$', views.view_class_instance), - url(r'^test1/', include(testobj1.urls)), - url(r'^test2/', include(testobj2.urls)), - url(r'^default/', include(default_testobj.urls)), + url(r'^test1/', include(*testobj1.urls)), + url(r'^test2/', include(*testobj2.urls)), + url(r'^default/', include(*default_testobj.urls)), - url(r'^other1/', include(otherobj1.urls)), - url(r'^other[246]/', include(otherobj2.urls)), + url(r'^other1/', include(*otherobj1.urls)), + url(r'^other[246]/', include(*otherobj2.urls)), url(r'^newapp1/', include(newappobj1.app_urls, 'new-ns1')), url(r'^new-default/', include(newappobj1.app_urls)), @@ -43,10 +44,12 @@ url(r'^ns-included[135]/', include('urlpatterns_reverse.included_namespace_urls', namespace='inc-ns1')), url(r'^ns-included2/', include('urlpatterns_reverse.included_namespace_urls', namespace='inc-ns2')), - url(r'^app-included/', include('urlpatterns_reverse.included_namespace_urls', 'inc-app', 'inc-app')), + url(r'^app-included/', include('urlpatterns_reverse.included_namespace_urls', 'inc-app')), url(r'^included/', include('urlpatterns_reverse.included_namespace_urls')), - url(r'^inc(?P[0-9]+)/', include('urlpatterns_reverse.included_urls', namespace='inc-ns5')), + url( + r'^inc(?P[0-9]+)/', include(('urlpatterns_reverse.included_urls', 'included_urls'), namespace='inc-ns5') + ), url(r'^included/([0-9]+)/', include('urlpatterns_reverse.included_namespace_urls')), url( diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py index b332ac4f7eb1..5f824469fa8f 100644 --- a/tests/urlpatterns_reverse/tests.py +++ b/tests/urlpatterns_reverse/tests.py @@ -18,16 +18,13 @@ HttpRequest, HttpResponsePermanentRedirect, HttpResponseRedirect, ) from django.shortcuts import redirect -from django.test import ( - SimpleTestCase, TestCase, ignore_warnings, override_settings, -) +from django.test import SimpleTestCase, TestCase, override_settings from django.test.utils import override_script_prefix from django.urls import ( NoReverseMatch, RegexURLPattern, RegexURLResolver, Resolver404, ResolverMatch, get_callable, get_resolver, resolve, reverse, reverse_lazy, ) from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from . import middleware, urlconf_outer, views from .utils import URLObject @@ -42,23 +39,27 @@ {'arg1': '42', 'arg2': '37'} ), ( - '/included/normal/42/37/', 'inc-normal-view', '', '', 'inc-normal-view', views.empty_view, tuple(), - {'arg1': '42', 'arg2': '37'} + '/included/normal/42/37/', 'inc-normal-view', 'included_namespace_urls', + 'included_namespace_urls', 'included_namespace_urls:inc-normal-view', + views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'} ), ( - '/included/view_class/42/37/', 'inc-view-class', '', '', 'inc-view-class', views.view_class_instance, tuple(), - {'arg1': '42', 'arg2': '37'} + '/included/view_class/42/37/', 'inc-view-class', 'included_namespace_urls', + 'included_namespace_urls', 'included_namespace_urls:inc-view-class', + views.view_class_instance, tuple(), {'arg1': '42', 'arg2': '37'} ), # Unnamed args are dropped if you have *any* kwargs in a pattern ('/mixed_args/42/37/', 'mixed-args', '', '', 'mixed-args', views.empty_view, tuple(), {'arg2': '37'}), ( - '/included/mixed_args/42/37/', 'inc-mixed-args', '', '', 'inc-mixed-args', views.empty_view, tuple(), - {'arg2': '37'} + '/included/mixed_args/42/37/', 'inc-mixed-args', 'included_namespace_urls', + 'included_namespace_urls', 'included_namespace_urls:inc-mixed-args', + views.empty_view, tuple(), {'arg2': '37'} ), ( - '/included/12/mixed_args/42/37/', 'inc-mixed-args', '', '', 'inc-mixed-args', views.empty_view, tuple(), - {'arg2': '37'} + '/included/12/mixed_args/42/37/', 'inc-mixed-args', 'included_namespace_urls', + 'included_namespace_urls', 'included_namespace_urls:inc-mixed-args', + views.empty_view, tuple(), {'arg2': '37'} ), # Unnamed views should have None as the url_name. Regression data for #21157. @@ -73,10 +74,15 @@ # If you have no kwargs, you get an args list. ('/no_kwargs/42/37/', 'no-kwargs', '', '', 'no-kwargs', views.empty_view, ('42', '37'), {}), - ('/included/no_kwargs/42/37/', 'inc-no-kwargs', '', '', 'inc-no-kwargs', views.empty_view, ('42', '37'), {}), ( - '/included/12/no_kwargs/42/37/', 'inc-no-kwargs', '', '', 'inc-no-kwargs', views.empty_view, - ('12', '42', '37'), {} + '/included/no_kwargs/42/37/', 'inc-no-kwargs', 'included_namespace_urls', + 'included_namespace_urls', 'included_namespace_urls:inc-no-kwargs', + views.empty_view, ('42', '37'), {} + ), + ( + '/included/12/no_kwargs/42/37/', 'inc-no-kwargs', 'included_namespace_urls', + 'included_namespace_urls', 'included_namespace_urls:inc-no-kwargs', + views.empty_view, ('12', '42', '37'), {} ), # Namespaces @@ -85,20 +91,23 @@ views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'} ), ( - '/included/test3/inner/42/37/', 'urlobject-view', 'testapp', 'test-ns3', 'test-ns3:urlobject-view', + '/included/test3/inner/42/37/', 'urlobject-view', 'included_namespace_urls:testapp', + 'included_namespace_urls:test-ns3', 'included_namespace_urls:test-ns3:urlobject-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'} ), ( - '/ns-included1/normal/42/37/', 'inc-normal-view', '', 'inc-ns1', 'inc-ns1:inc-normal-view', views.empty_view, - tuple(), {'arg1': '42', 'arg2': '37'} + '/ns-included1/normal/42/37/', 'inc-normal-view', 'included_namespace_urls', + 'inc-ns1', 'inc-ns1:inc-normal-view', + views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'} ), ( - '/included/test3/inner/42/37/', 'urlobject-view', 'testapp', 'test-ns3', 'test-ns3:urlobject-view', + '/included/test3/inner/42/37/', 'urlobject-view', 'included_namespace_urls:testapp', + 'included_namespace_urls:test-ns3', 'included_namespace_urls:test-ns3:urlobject-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'} ), ( - '/default/inner/42/37/', 'urlobject-view', 'testapp', 'testapp', 'testapp:urlobject-view', views.empty_view, - tuple(), {'arg1': '42', 'arg2': '37'} + '/default/inner/42/37/', 'urlobject-view', 'testapp', 'testapp', 'testapp:urlobject-view', + views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'} ), ( '/other2/inner/42/37/', 'urlobject-view', 'nodefault', 'other-ns2', 'other-ns2:urlobject-view', @@ -111,29 +120,37 @@ # Nested namespaces ( - '/ns-included1/test3/inner/42/37/', 'urlobject-view', 'testapp', 'inc-ns1:test-ns3', - 'inc-ns1:test-ns3:urlobject-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'} + '/ns-included1/test3/inner/42/37/', 'urlobject-view', 'included_namespace_urls:testapp', + 'inc-ns1:test-ns3', 'inc-ns1:test-ns3:urlobject-view', + views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'} ), ( - '/ns-included1/ns-included4/ns-included2/test3/inner/42/37/', 'urlobject-view', 'testapp', - 'inc-ns1:inc-ns4:inc-ns2:test-ns3', 'inc-ns1:inc-ns4:inc-ns2:test-ns3:urlobject-view', views.empty_view, - tuple(), {'arg1': '42', 'arg2': '37'} + '/ns-included1/ns-included4/ns-included2/test3/inner/42/37/', 'urlobject-view', + 'included_namespace_urls:namespace_urls:included_namespace_urls:testapp', + 'inc-ns1:inc-ns4:inc-ns2:test-ns3', + 'inc-ns1:inc-ns4:inc-ns2:test-ns3:urlobject-view', + views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'} ), ( - '/app-included/test3/inner/42/37/', 'urlobject-view', 'inc-app:testapp', 'inc-app:test-ns3', + '/app-included/test3/inner/42/37/', 'urlobject-view', 'included_namespace_urls:testapp', 'inc-app:test-ns3', 'inc-app:test-ns3:urlobject-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'} ), ( - '/app-included/ns-included4/ns-included2/test3/inner/42/37/', 'urlobject-view', 'inc-app:testapp', - 'inc-app:inc-ns4:inc-ns2:test-ns3', 'inc-app:inc-ns4:inc-ns2:test-ns3:urlobject-view', views.empty_view, - tuple(), {'arg1': '42', 'arg2': '37'} + '/app-included/ns-included4/ns-included2/test3/inner/42/37/', 'urlobject-view', + 'included_namespace_urls:namespace_urls:included_namespace_urls:testapp', + 'inc-app:inc-ns4:inc-ns2:test-ns3', + 'inc-app:inc-ns4:inc-ns2:test-ns3:urlobject-view', + views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'} ), # Namespaces capturing variables - ('/inc70/', 'inner-nothing', '', 'inc-ns5', 'inc-ns5:inner-nothing', views.empty_view, tuple(), {'outer': '70'}), ( - '/inc78/extra/foobar/', 'inner-extra', '', 'inc-ns5', 'inc-ns5:inner-extra', views.empty_view, tuple(), - {'outer': '78', 'extra': 'foobar'} + '/inc70/', 'inner-nothing', 'included_urls', 'inc-ns5', 'inc-ns5:inner-nothing', + views.empty_view, tuple(), {'outer': '70'} + ), + ( + '/inc78/extra/foobar/', 'inner-extra', 'included_urls', 'inc-ns5', 'inc-ns5:inner-extra', + views.empty_view, tuple(), {'outer': '78', 'extra': 'foobar'} ), ) @@ -355,7 +372,6 @@ def test_illegal_kwargs_message(self): class ResolverTests(SimpleTestCase): - @ignore_warnings(category=RemovedInDjango20Warning) def test_resolver_repr(self): """ Test repr of RegexURLResolver, especially when urlconf_name is a list @@ -576,7 +592,6 @@ def test_redirect_view_object(self): @override_settings(ROOT_URLCONF='urlpatterns_reverse.namespace_urls') -@ignore_warnings(category=RemovedInDjango20Warning) class NamespaceTests(SimpleTestCase): def test_ambiguous_object(self): @@ -613,10 +628,13 @@ def test_normal_name(self): def test_simple_included_name(self): "Normal lookups work on names included from other patterns" - self.assertEqual('/included/normal/', reverse('inc-normal-view')) - self.assertEqual('/included/normal/37/42/', reverse('inc-normal-view', args=[37, 42])) - self.assertEqual('/included/normal/42/37/', reverse('inc-normal-view', kwargs={'arg1': 42, 'arg2': 37})) - self.assertEqual('/included/+%5C$*/', reverse('inc-special-view')) + self.assertEqual('/included/normal/', reverse('included_namespace_urls:inc-normal-view')) + self.assertEqual('/included/normal/37/42/', reverse('included_namespace_urls:inc-normal-view', args=[37, 42])) + self.assertEqual( + '/included/normal/42/37/', + reverse('included_namespace_urls:inc-normal-view', kwargs={'arg1': 42, 'arg2': 37}) + ) + self.assertEqual('/included/+%5C$*/', reverse('included_namespace_urls:inc-special-view')) def test_namespace_object(self): "Dynamic URL objects can be found using a namespace" @@ -643,12 +661,17 @@ def test_app_object_default_namespace(self): def test_embedded_namespace_object(self): "Namespaces can be installed anywhere in the URL pattern tree" - self.assertEqual('/included/test3/inner/', reverse('test-ns3:urlobject-view')) - self.assertEqual('/included/test3/inner/37/42/', reverse('test-ns3:urlobject-view', args=[37, 42])) + self.assertEqual('/included/test3/inner/', reverse('included_namespace_urls:test-ns3:urlobject-view')) self.assertEqual( - '/included/test3/inner/42/37/', reverse('test-ns3:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}) + '/included/test3/inner/37/42/', reverse('included_namespace_urls:test-ns3:urlobject-view', args=[37, 42]) + ) + self.assertEqual( + '/included/test3/inner/42/37/', + reverse('included_namespace_urls:test-ns3:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}) + ) + self.assertEqual( + '/included/test3/inner/+%5C$*/', reverse('included_namespace_urls:test-ns3:urlobject-special-view') ) - self.assertEqual('/included/test3/inner/+%5C$*/', reverse('test-ns3:urlobject-special-view')) def test_namespace_pattern(self): "Namespaces can be applied to include()'d urlpatterns" @@ -718,17 +741,17 @@ def test_app_lookup_object(self): def test_app_lookup_object_with_default(self): "A default application namespace is sensitive to the 'current' app can be used for lookup" - self.assertEqual('/included/test3/inner/', reverse('testapp:urlobject-view', current_app='test-ns3')) + self.assertEqual('/default/inner/', reverse('testapp:urlobject-view', current_app='test-ns3')) self.assertEqual( - '/included/test3/inner/37/42/', + '/default/inner/37/42/', reverse('testapp:urlobject-view', args=[37, 42], current_app='test-ns3') ) self.assertEqual( - '/included/test3/inner/42/37/', + '/default/inner/42/37/', reverse('testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}, current_app='test-ns3') ) self.assertEqual( - '/included/test3/inner/+%5C$*/', reverse('testapp:urlobject-special-view', current_app='test-ns3') + '/default/inner/+%5C$*/', reverse('testapp:urlobject-special-view', current_app='test-ns3') ) def test_app_lookup_object_without_default(self): @@ -749,13 +772,16 @@ def test_app_lookup_object_without_default(self): self.assertEqual('/other1/inner/+%5C$*/', reverse('nodefault:urlobject-special-view', current_app='other-ns1')) def test_special_chars_namespace(self): - self.assertEqual('/+%5C$*/included/normal/', reverse('special:inc-normal-view')) - self.assertEqual('/+%5C$*/included/normal/37/42/', reverse('special:inc-normal-view', args=[37, 42])) + self.assertEqual('/+%5C$*/included/normal/', reverse('special:included_namespace_urls:inc-normal-view')) + self.assertEqual( + '/+%5C$*/included/normal/37/42/', + reverse('special:included_namespace_urls:inc-normal-view', args=[37, 42]) + ) self.assertEqual( '/+%5C$*/included/normal/42/37/', - reverse('special:inc-normal-view', kwargs={'arg1': 42, 'arg2': 37}) + reverse('special:included_namespace_urls:inc-normal-view', kwargs={'arg1': 42, 'arg2': 37}) ) - self.assertEqual('/+%5C$*/included/+%5C$*/', reverse('special:inc-special-view')) + self.assertEqual('/+%5C$*/included/+%5C$*/', reverse('special:included_namespace_urls:inc-special-view')) def test_namespaces_with_variables(self): "Namespace prefixes can capture variables: see #15900" @@ -965,7 +991,6 @@ def test_no_handler_exception(self): @override_settings(ROOT_URLCONF='urlpatterns_reverse.namespace_urls') class ResolverMatchTests(SimpleTestCase): - @ignore_warnings(category=RemovedInDjango20Warning) def test_urlpattern_resolve(self): for path, url_name, app_name, namespace, view_name, func, args, kwargs in resolve_test_data: # Test legacy support for extracting "function, args, kwargs" @@ -990,7 +1015,6 @@ def test_urlpattern_resolve(self): self.assertEqual(match[1], args) self.assertEqual(match[2], kwargs) - @ignore_warnings(category=RemovedInDjango20Warning) def test_resolver_match_on_request(self): response = self.client.get('/resolver_match/') resolver_match = response.resolver_match @@ -1042,34 +1066,21 @@ class IncludeTests(SimpleTestCase): ] app_urls = URLObject('inc-app') - def test_include_app_name_but_no_namespace(self): - msg = "Must specify a namespace if specifying app_name." - with self.assertRaisesMessage(ValueError, msg): - include(self.url_patterns, app_name='bar') - def test_include_urls(self): self.assertEqual(include(self.url_patterns), (self.url_patterns, None, None)) - @ignore_warnings(category=RemovedInDjango20Warning) def test_include_namespace(self): - # no app_name -> deprecated - self.assertEqual(include(self.url_patterns, 'namespace'), (self.url_patterns, None, 'namespace')) - - @ignore_warnings(category=RemovedInDjango20Warning) - def test_include_namespace_app_name(self): - # app_name argument to include -> deprecated - self.assertEqual( - include(self.url_patterns, 'namespace', 'app_name'), - (self.url_patterns, 'app_name', 'namespace') + msg = ( + "Specifying a namespace in django.conf.urls.include() without " + "providing an app_name is not supported." ) + with self.assertRaisesMessage(ImproperlyConfigured, msg): + include(self.url_patterns, 'namespace') - @ignore_warnings(category=RemovedInDjango20Warning) def test_include_3_tuple(self): - # 3-tuple -> deprecated - self.assertEqual( - include((self.url_patterns, 'app_name', 'namespace')), - (self.url_patterns, 'app_name', 'namespace') - ) + msg = 'Passing a 3-tuple to django.conf.urls.include() is not supported.' + with self.assertRaisesMessage(ImproperlyConfigured, msg): + include((self.url_patterns, 'app_name', 'namespace')) def test_include_2_tuple(self): self.assertEqual( diff --git a/tests/urlpatterns_reverse/utils.py b/tests/urlpatterns_reverse/utils.py index 6c3fe8a31dc2..adcb310fa543 100644 --- a/tests/urlpatterns_reverse/utils.py +++ b/tests/urlpatterns_reverse/utils.py @@ -18,7 +18,7 @@ def __init__(self, app_name, namespace=None): @property def urls(self): - return self.urlpatterns, self.app_name, self.namespace + return (self.urlpatterns, self.app_name), self.namespace @property def app_urls(self): From 733c7c703030d2546b729dfa20edfa5217d1da20 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 07:36:21 -0500 Subject: [PATCH 0019/3180] Refs #24716 -- Removed Field._get_val_from_obj() per deprecation timeline. --- django/db/models/fields/__init__.py | 14 +------------- docs/releases/2.0.txt | 2 ++ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 63a2fc8fa414..f5d6734aab4e 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -27,9 +27,7 @@ from django.utils.dateparse import ( parse_date, parse_datetime, parse_duration, parse_time, ) -from django.utils.deprecation import ( - RemovedInDjango20Warning, warn_about_renamed_method, -) +from django.utils.deprecation import RemovedInDjango20Warning from django.utils.duration import duration_string from django.utils.encoding import ( force_bytes, force_text, python_2_unicode_compatible, smart_text, @@ -810,16 +808,6 @@ def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH, limit_ limit_choices_to)] return first_choice + lst - @warn_about_renamed_method( - 'Field', '_get_val_from_obj', 'value_from_object', - RemovedInDjango20Warning - ) - def _get_val_from_obj(self, obj): - if obj is not None: - return getattr(obj, self.attname) - else: - return self.get_default() - def value_to_string(self, obj): """ Returns a string value of this field from the passed obj. diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 0ae25a82952c..42d6c5b5406b 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -299,3 +299,5 @@ these features. * Support for setting a URL instance namespace without an application namespace is removed. + +* ``Field._get_val_from_obj()`` is removed. From 8377abd59e05a5a6351d4cff9c63c3f50922d0f2 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 07:41:35 -0500 Subject: [PATCH 0020/3180] Refs #25120 -- Removed template.loaders.eggs.Loader per deprecation timeline. --- django/template/loaders/eggs.py | 56 -------------- docs/ref/templates/api.txt | 13 ---- docs/releases/2.0.txt | 2 + tests/template_tests/test_loaders.py | 110 +-------------------------- 4 files changed, 4 insertions(+), 177 deletions(-) delete mode 100644 django/template/loaders/eggs.py diff --git a/django/template/loaders/eggs.py b/django/template/loaders/eggs.py deleted file mode 100644 index 3013a8586dda..000000000000 --- a/django/template/loaders/eggs.py +++ /dev/null @@ -1,56 +0,0 @@ -# Wrapper for loading templates from eggs via pkg_resources.resource_string. -from __future__ import unicode_literals - -import warnings - -from django.apps import apps -from django.template import Origin, TemplateDoesNotExist -from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning - -from .base import Loader as BaseLoader - -try: - from pkg_resources import resource_string -except ImportError: - resource_string = None - -warnings.warn('The egg template loader is deprecated.', RemovedInDjango20Warning) - - -class EggOrigin(Origin): - - def __init__(self, app_name, pkg_name, *args, **kwargs): - self.app_name = app_name - self.pkg_name = pkg_name - super(EggOrigin, self).__init__(*args, **kwargs) - - -class Loader(BaseLoader): - - def __init__(self, engine): - if resource_string is None: - raise RuntimeError("Setuptools must be installed to use the egg loader") - super(Loader, self).__init__(engine) - - def get_contents(self, origin): - try: - source = resource_string(origin.app_name, origin.pkg_name) - except Exception: - raise TemplateDoesNotExist(origin) - - if six.PY2: - source = source.decode(self.engine.file_charset) - - return source - - def get_template_sources(self, template_name): - pkg_name = 'templates/' + template_name - for app_config in apps.get_app_configs(): - yield EggOrigin( - app_name=app_config.name, - pkg_name=pkg_name, - name="egg:%s:%s" % (app_config.name, pkg_name), - template_name=template_name, - loader=self, - ) diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt index 305945a856be..c4ce1b84a5fd 100644 --- a/docs/ref/templates/api.txt +++ b/docs/ref/templates/api.txt @@ -910,19 +910,6 @@ loaders that come with Django: 'APP_DIRS': True, }] -``django.template.loaders.eggs.Loader`` - -.. class:: eggs.Loader - - .. deprecated:: 1.9 - - Distributing applications as eggs is not recommended. - - Just like ``app_directories`` above, but it loads templates from Python - eggs rather than from the filesystem. - - This loader is disabled by default. - ``django.template.loaders.cached.Loader`` .. class:: cached.Loader diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 42d6c5b5406b..61ca9f6df1ba 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -301,3 +301,5 @@ these features. is removed. * ``Field._get_val_from_obj()`` is removed. + +* ``django.template.loaders.eggs.Loader`` is removed. diff --git a/tests/template_tests/test_loaders.py b/tests/template_tests/test_loaders.py index 22fb1d812c1a..5f5092352435 100644 --- a/tests/template_tests/test_loaders.py +++ b/tests/template_tests/test_loaders.py @@ -4,24 +4,17 @@ import os.path import sys import tempfile -import types import unittest from contextlib import contextmanager -from django.template import Context, TemplateDoesNotExist +from django.template import TemplateDoesNotExist from django.template.engine import Engine -from django.test import SimpleTestCase, ignore_warnings, override_settings +from django.test import SimpleTestCase, override_settings from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.functional import lazystr from .utils import TEMPLATE_DIR -try: - import pkg_resources -except ImportError: - pkg_resources = None - class CachedLoaderTests(SimpleTestCase): @@ -106,105 +99,6 @@ def test_template_name_lazy_string(self): self.assertEqual(self.engine.template_loaders[0].cache_key(lazystr('template.html'), []), 'template.html') -@unittest.skipUnless(pkg_resources, 'setuptools is not installed') -class EggLoaderTests(SimpleTestCase): - - @contextmanager - def create_egg(self, name, resources): - """ - Creates a mock egg with a list of resources. - - name: The name of the module. - resources: A dictionary of template names mapped to file-like objects. - """ - - if six.PY2: - name = name.encode('utf-8') - - class MockLoader(object): - pass - - class MockProvider(pkg_resources.NullProvider): - def __init__(self, module): - pkg_resources.NullProvider.__init__(self, module) - self.module = module - - def _has(self, path): - return path in self.module._resources - - def _isdir(self, path): - return False - - def get_resource_stream(self, manager, resource_name): - return self.module._resources[resource_name] - - def _get(self, path): - return self.module._resources[path].read() - - def _fn(self, base, resource_name): - return os.path.normcase(resource_name) - - egg = types.ModuleType(name) - egg.__loader__ = MockLoader() - egg.__path__ = ['/some/bogus/path/'] - egg.__file__ = '/some/bogus/path/__init__.pyc' - egg._resources = resources - sys.modules[name] = egg - pkg_resources._provider_factories[MockLoader] = MockProvider - - try: - yield - finally: - del sys.modules[name] - del pkg_resources._provider_factories[MockLoader] - - @classmethod - @ignore_warnings(category=RemovedInDjango20Warning) - def setUpClass(cls): - cls.engine = Engine(loaders=[ - 'django.template.loaders.eggs.Loader', - ]) - cls.loader = cls.engine.template_loaders[0] - super(EggLoaderTests, cls).setUpClass() - - def test_get_template(self): - templates = { - os.path.normcase('templates/y.html'): six.StringIO("y"), - } - - with self.create_egg('egg', templates): - with override_settings(INSTALLED_APPS=['egg']): - template = self.engine.get_template("y.html") - - self.assertEqual(template.origin.name, 'egg:egg:templates/y.html') - self.assertEqual(template.origin.template_name, 'y.html') - self.assertEqual(template.origin.loader, self.engine.template_loaders[0]) - - output = template.render(Context({})) - self.assertEqual(output, "y") - - def test_non_existing(self): - """ - Template loading fails if the template is not in the egg. - """ - with self.create_egg('egg', {}): - with override_settings(INSTALLED_APPS=['egg']): - with self.assertRaises(TemplateDoesNotExist): - self.engine.get_template('not-existing.html') - - def test_not_installed(self): - """ - Template loading fails if the egg is not in INSTALLED_APPS. - """ - templates = { - os.path.normcase('templates/y.html'): six.StringIO("y"), - } - - with self.create_egg('egg', templates): - with self.assertRaises(TemplateDoesNotExist): - self.engine.get_template('y.html') - - class FileSystemLoaderTests(SimpleTestCase): @classmethod From 9f9a3d643ec52c5cfb08c1546d6855fb60e702a9 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 08:05:01 -0500 Subject: [PATCH 0021/3180] Refs #24126 -- Removed auth views' current_app parameter per deprecation timeline. --- django/contrib/auth/views.py | 35 +---------- docs/releases/2.0.txt | 3 + docs/topics/auth/default.txt | 115 ++++++----------------------------- 3 files changed, 21 insertions(+), 132 deletions(-) diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py index be156286c654..1a004e7a84db 100644 --- a/django/contrib/auth/views.py +++ b/django/contrib/auth/views.py @@ -1,4 +1,3 @@ -import functools import warnings from django.conf import settings @@ -18,9 +17,7 @@ from django.template.response import TemplateResponse from django.urls import reverse, reverse_lazy from django.utils.decorators import method_decorator -from django.utils.deprecation import ( - RemovedInDjango20Warning, RemovedInDjango21Warning, -) +from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_text from django.utils.http import is_safe_url, urlsafe_base64_decode from django.utils.six.moves.urllib.parse import urlparse, urlunparse @@ -34,27 +31,6 @@ UserModel = get_user_model() -def deprecate_current_app(func): - """ - Handle deprecation of the current_app parameter of the views. - """ - @functools.wraps(func) - def inner(*args, **kwargs): - if 'current_app' in kwargs: - warnings.warn( - "Passing `current_app` as a keyword argument is deprecated. " - "Instead the caller of `{0}` should set " - "`request.current_app`.".format(func.__name__), - RemovedInDjango20Warning - ) - current_app = kwargs.pop('current_app') - request = kwargs.get('request', None) - if request and current_app is not None: - request.current_app = current_app - return func(*args, **kwargs) - return inner - - class SuccessURLAllowedHostsMixin(object): success_url_allowed_hosts = set() @@ -125,7 +101,6 @@ def get_context_data(self, **kwargs): return context -@deprecate_current_app def login(request, *args, **kwargs): warnings.warn( 'The login() view is superseded by the class-based LoginView().', @@ -190,7 +165,6 @@ def get_context_data(self, **kwargs): return context -@deprecate_current_app def logout(request, *args, **kwargs): warnings.warn( 'The logout() view is superseded by the class-based LogoutView().', @@ -202,7 +176,6 @@ def logout(request, *args, **kwargs): _sentinel = object() -@deprecate_current_app def logout_then_login(request, login_url=None, extra_context=_sentinel): """ Logs out the user if they are logged in. Then redirects to the log-in page. @@ -242,7 +215,6 @@ def redirect_to_login(next, login_url=None, # prompts for a new password # - password_reset_complete shows a success message for the above -@deprecate_current_app @csrf_protect def password_reset(request, template_name='registration/password_reset_form.html', @@ -289,7 +261,6 @@ def password_reset(request, return TemplateResponse(request, template_name, context) -@deprecate_current_app def password_reset_done(request, template_name='registration/password_reset_done.html', extra_context=None): @@ -308,7 +279,6 @@ def password_reset_done(request, # Doesn't need csrf_protect since no-one can guess the URL @sensitive_post_parameters() @never_cache -@deprecate_current_app def password_reset_confirm(request, uidb64=None, token=None, template_name='registration/password_reset_confirm.html', token_generator=default_token_generator, @@ -359,7 +329,6 @@ def password_reset_confirm(request, uidb64=None, token=None, return TemplateResponse(request, template_name, context) -@deprecate_current_app def password_reset_complete(request, template_name='registration/password_reset_complete.html', extra_context=None): @@ -518,7 +487,6 @@ def get_context_data(self, **kwargs): @sensitive_post_parameters() @csrf_protect @login_required -@deprecate_current_app def password_change(request, template_name='registration/password_change_form.html', post_change_redirect=None, @@ -552,7 +520,6 @@ def password_change(request, @login_required -@deprecate_current_app def password_change_done(request, template_name='registration/password_change_done.html', extra_context=None): diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 61ca9f6df1ba..eed80087a533 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -303,3 +303,6 @@ these features. * ``Field._get_val_from_obj()`` is removed. * ``django.template.loaders.eggs.Loader`` is removed. + +* The ``current_app`` parameter to the ``contrib.auth`` function-based views is + removed. diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt index f4090f77cbe4..5869ff0d30c9 100644 --- a/docs/topics/auth/default.txt +++ b/docs/topics/auth/default.txt @@ -955,7 +955,7 @@ All authentication views This is a list with all the views ``django.contrib.auth`` provides. For implementation details see :ref:`using-the-views`. -.. function:: login(request, template_name=`registration/login.html`, redirect_field_name='next', authentication_form=AuthenticationForm, current_app=None, extra_context=None, redirect_authenticated_user=False) +.. function:: login(request, template_name=`registration/login.html`, redirect_field_name='next', authentication_form=AuthenticationForm, extra_context=None, redirect_authenticated_user=False) .. deprecated:: 1.11 @@ -963,16 +963,7 @@ implementation details see :ref:`using-the-views`. :class:`LoginView`. The optional arguments of this view are similar to the class-based - ``LoginView`` attributes. In addition, it has: - - * ``current_app``: A hint indicating which application contains the - current view. See the :ref:`namespaced URL resolution strategy - ` for more information. - - .. deprecated:: 1.9 - - The ``current_app`` attribute is deprecated and will be removed in - Django 2.0. Callers should set ``request.current_app`` instead. + ``LoginView`` attributes. .. versionadded:: 1.10 @@ -1116,7 +1107,7 @@ implementation details see :ref:`using-the-views`. ``get_user()`` method which returns the authenticated user object (this method is only ever called after successful form validation). -.. function:: logout(request, next_page=None, template_name='registration/logged_out.html', redirect_field_name='next', current_app=None, extra_context=None) +.. function:: logout(request, next_page=None, template_name='registration/logged_out.html', redirect_field_name='next', extra_context=None) .. deprecated:: 1.11 @@ -1124,16 +1115,7 @@ implementation details see :ref:`using-the-views`. class-based :class:`LogoutView`. The optional arguments of this view are similar to the class-based - ``LogoutView`` attributes. In addition, it has: - - * ``current_app``: A hint indicating which application contains the - current view. See the :ref:`namespaced URL resolution strategy - ` for more information. - - .. deprecated:: 1.9 - - The ``current_app`` attribute is deprecated and will be removed in - Django 2.0. Callers should set ``request.current_app`` instead. + ``LogoutView`` attributes. .. class:: LogoutView @@ -1178,7 +1160,7 @@ implementation details see :ref:`using-the-views`. :attr:`request.META['SERVER_NAME'] `. For more on sites, see :doc:`/ref/contrib/sites`. -.. function:: logout_then_login(request, login_url=None, current_app=None, extra_context=None) +.. function:: logout_then_login(request, login_url=None, extra_context=None) Logs a user out, then redirects to the login page. @@ -1189,24 +1171,15 @@ implementation details see :ref:`using-the-views`. * ``login_url``: The URL of the login page to redirect to. Defaults to :setting:`settings.LOGIN_URL ` if not supplied. - * ``current_app``: A hint indicating which application contains the current - view. See the :ref:`namespaced URL resolution strategy - ` for more information. - * ``extra_context``: A dictionary of context data that will be added to the default context data passed to the template. - .. deprecated:: 1.9 - - The ``current_app`` parameter is deprecated and will be removed in - Django 2.0. Callers should set ``request.current_app`` instead. - .. deprecated:: 1.11 The unused ``extra_context`` parameter is deprecated and will be removed in Django 2.1. -.. function:: password_change(request, template_name='registration/password_change_form.html', post_change_redirect=None, password_change_form=PasswordChangeForm, current_app=None, extra_context=None) +.. function:: password_change(request, template_name='registration/password_change_form.html', post_change_redirect=None, password_change_form=PasswordChangeForm, extra_context=None) .. deprecated:: 1.11 @@ -1216,16 +1189,7 @@ implementation details see :ref:`using-the-views`. The optional arguments of this view are similar to the class-based ``PasswordChangeView`` attributes, except the ``post_change_redirect`` and ``password_change_form`` arguments which map to the ``success_url`` and - ``form_class`` attributes of the class-based view. In addition, it has: - - * ``current_app``: A hint indicating which application contains the current - view. See the :ref:`namespaced URL resolution strategy - ` for more information. - - .. deprecated:: 1.9 - - The ``current_app`` parameter is deprecated and will be removed in - Django 2.0. Callers should set ``request.current_app`` instead. + ``form_class`` attributes of the class-based view. .. class:: PasswordChangeView @@ -1256,7 +1220,7 @@ implementation details see :ref:`using-the-views`. * ``form``: The password change form (see ``form_class`` above). -.. function:: password_change_done(request, template_name='registration/password_change_done.html', current_app=None, extra_context=None) +.. function:: password_change_done(request, template_name='registration/password_change_done.html', extra_context=None) .. deprecated:: 1.11 @@ -1264,16 +1228,7 @@ implementation details see :ref:`using-the-views`. the class-based :class:`PasswordChangeDoneView`. The optional arguments of this view are similar to the class-based - ``PasswordChangeDoneView`` attributes. In addition, it has: - - * ``current_app``: A hint indicating which application contains the current - view. See the :ref:`namespaced URL resolution strategy - ` for more information. - - .. deprecated:: 1.9 - - The ``current_app`` parameter is deprecated and will be removed in - Django 2.0. Callers should set ``request.current_app`` instead. + ``PasswordChangeDoneView`` attributes. .. class:: PasswordChangeDoneView @@ -1292,7 +1247,7 @@ implementation details see :ref:`using-the-views`. * ``extra_context``: A dictionary of context data that will be added to the default context data passed to the template. -.. function:: password_reset(request, template_name='registration/password_reset_form.html', email_template_name='registration/password_reset_email.html', subject_template_name='registration/password_reset_subject.txt', password_reset_form=PasswordResetForm, token_generator=default_token_generator, post_reset_redirect=None, from_email=None, current_app=None, extra_context=None, html_email_template_name=None, extra_email_context=None) +.. function:: password_reset(request, template_name='registration/password_reset_form.html', email_template_name='registration/password_reset_email.html', subject_template_name='registration/password_reset_subject.txt', password_reset_form=PasswordResetForm, token_generator=default_token_generator, post_reset_redirect=None, from_email=None, extra_context=None, html_email_template_name=None, extra_email_context=None) .. deprecated:: 1.11 @@ -1302,16 +1257,7 @@ implementation details see :ref:`using-the-views`. The optional arguments of this view are similar to the class-based ``PasswordResetView`` attributes, except the ``post_reset_redirect`` and ``password_reset_form`` arguments which map to the ``success_url`` and - ``form_class`` attributes of the class-based view. In addition, it has: - - * ``current_app``: A hint indicating which application contains the current - view. See the :ref:`namespaced URL resolution strategy - ` for more information. - - .. deprecated:: 1.9 - - The ``current_app`` parameter is deprecated and will be removed in - Django 2.0. Callers should set ``request.current_app`` instead. + ``form_class`` attributes of the class-based view. .. class:: PasswordResetView @@ -1413,7 +1359,7 @@ implementation details see :ref:`using-the-views`. The same template context is used for subject template. Subject must be single line plain text string. -.. function:: password_reset_done(request, template_name='registration/password_reset_done.html', current_app=None, extra_context=None) +.. function:: password_reset_done(request, template_name='registration/password_reset_done.html', extra_context=None) .. deprecated:: 1.11 @@ -1421,16 +1367,7 @@ implementation details see :ref:`using-the-views`. the class-based :class:`PasswordResetDoneView`. The optional arguments of this view are similar to the class-based - ``PasswordResetDoneView`` attributes. In addition, it has: - - * ``current_app``: A hint indicating which application contains the current - view. See the :ref:`namespaced URL resolution strategy - ` for more information. - - .. deprecated:: 1.9 - - The ``current_app`` parameter is deprecated and will be removed in - Django 2.0. Callers should set ``request.current_app`` instead. + ``PasswordResetDoneView`` attributes. .. class:: PasswordResetDoneView @@ -1457,7 +1394,7 @@ implementation details see :ref:`using-the-views`. * ``extra_context``: A dictionary of context data that will be added to the default context data passed to the template. -.. function:: password_reset_confirm(request, uidb64=None, token=None, template_name='registration/password_reset_confirm.html', token_generator=default_token_generator, set_password_form=SetPasswordForm, post_reset_redirect=None, current_app=None, extra_context=None) +.. function:: password_reset_confirm(request, uidb64=None, token=None, template_name='registration/password_reset_confirm.html', token_generator=default_token_generator, set_password_form=SetPasswordForm, post_reset_redirect=None, extra_context=None) .. deprecated:: 1.11 @@ -1467,16 +1404,7 @@ implementation details see :ref:`using-the-views`. The optional arguments of this view are similar to the class-based ``PasswordResetConfirmView`` attributes, except the ``post_reset_redirect`` and ``set_password_form`` arguments which map to the ``success_url`` and - ``form_class`` attributes of the class-based view. In addition, it has: - - * ``current_app``: A hint indicating which application contains the current - view. See the :ref:`namespaced URL resolution strategy - ` for more information. - - .. deprecated:: 1.9 - - The ``current_app`` parameter is deprecated and will be removed in - Django 2.0. Callers should set ``request.current_app`` instead. + ``form_class`` attributes of the class-based view. .. class:: PasswordResetConfirmView @@ -1523,7 +1451,7 @@ implementation details see :ref:`using-the-views`. * ``validlink``: Boolean, True if the link (combination of ``uidb64`` and ``token``) is valid or unused yet. -.. function:: password_reset_complete(request, template_name='registration/password_reset_complete.html', current_app=None, extra_context=None) +.. function:: password_reset_complete(request, template_name='registration/password_reset_complete.html', extra_context=None) .. deprecated:: 1.11 @@ -1531,16 +1459,7 @@ implementation details see :ref:`using-the-views`. by the class-based :class:`PasswordResetCompleteView`. The optional arguments of this view are similar to the class-based - ``PasswordResetCompleteView`` attributes. In addition, it has: - - * ``current_app``: A hint indicating which application contains the current - view. See the :ref:`namespaced URL resolution strategy - ` for more information. - - .. deprecated:: 1.9 - - The ``current_app`` parameter is deprecated and will be removed in - Django 2.0. Callers should set ``request.current_app`` instead. + ``PasswordResetCompleteView`` attributes. .. class:: PasswordResetCompleteView From 7510b872e7a2c06e935b0469813320a65f679f64 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 08:10:37 -0500 Subject: [PATCH 0022/3180] Refs #25190 -- Removed callable_obj parameter to assertRaisesMessages(). Per deprecation timeline. --- django/test/testcases.py | 12 ++---------- docs/releases/2.0.txt | 3 +++ docs/topics/testing/tools.txt | 5 ----- tests/test_utils/tests.py | 22 +--------------------- 4 files changed, 6 insertions(+), 36 deletions(-) diff --git a/django/test/testcases.py b/django/test/testcases.py index 253b2496798c..e342ac282d16 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -6,7 +6,6 @@ import sys import threading import unittest -import warnings from collections import Counter from contextlib import contextmanager from copy import copy @@ -36,7 +35,6 @@ ) from django.utils import six from django.utils.decorators import classproperty -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.utils.six.moves.urllib.parse import ( unquote, urljoin, urlparse, urlsplit, @@ -606,14 +604,8 @@ def assertRaisesMessage(self, expected_exception, expected_message, *args, **kwa args: Function to be called and extra positional args. kwargs: Extra kwargs. """ - # callable_obj was a documented kwarg in Django 1.8 and older. - callable_obj = kwargs.pop('callable_obj', None) - if callable_obj: - warnings.warn( - 'The callable_obj kwarg is deprecated. Pass the callable ' - 'as a positional argument instead.', RemovedInDjango20Warning - ) - elif len(args): + callable_obj = None + if len(args): callable_obj = args[0] args = args[1:] diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index eed80087a533..d1edbf61800b 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -306,3 +306,6 @@ these features. * The ``current_app`` parameter to the ``contrib.auth`` function-based views is removed. + +* The ``callable_obj`` keyword argument to + ``SimpleTestCase.assertRaisesMessage()`` is removed. diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt index 7c40955a0cfc..5bb34be1a334 100644 --- a/docs/topics/testing/tools.txt +++ b/docs/topics/testing/tools.txt @@ -1351,11 +1351,6 @@ your test suite. with self.assertRaisesMessage(ValueError, 'invalid literal for int()'): int('a') - .. deprecated:: 1.9 - - Passing ``callable`` as a keyword argument called ``callable_obj`` is - deprecated. Pass the callable as a positional argument instead. - .. method:: SimpleTestCase.assertFieldOutput(fieldclass, valid, invalid, field_args=None, field_kwargs=None, empty_value='') Asserts that a form field behaves correctly with various inputs. diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py index 54b83f524b0f..2a199ec5bceb 100644 --- a/tests/test_utils/tests.py +++ b/tests/test_utils/tests.py @@ -3,7 +3,6 @@ import sys import unittest -import warnings from django.conf.urls import url from django.contrib.staticfiles.finders import get_finder, get_finders @@ -14,8 +13,7 @@ from django.http import HttpResponse from django.template.loader import render_to_string from django.test import ( - SimpleTestCase, TestCase, ignore_warnings, skipIfDBFeature, - skipUnlessDBFeature, + SimpleTestCase, TestCase, skipIfDBFeature, skipUnlessDBFeature, ) from django.test.html import HTMLParseError, parse_html from django.test.utils import ( @@ -25,7 +23,6 @@ from django.urls import NoReverseMatch, reverse from django.utils import six from django.utils._os import abspathu -from django.utils.deprecation import RemovedInDjango20Warning from .models import Car, Person, PossessedCar from .views import empty_response @@ -831,23 +828,6 @@ def func1(): with self.assertRaisesMessage(ValueError, "[.*x+]y?"): func1() - @ignore_warnings(category=RemovedInDjango20Warning) - def test_callable_obj_param(self): - # callable_obj was a documented kwarg in Django 1.8 and older. - def func1(): - raise ValueError("[.*x+]y?") - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') - self.assertRaisesMessage(ValueError, "[.*x+]y?", callable_obj=func1) - - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - 'The callable_obj kwarg is deprecated. Pass the callable ' - 'as a positional argument instead.' - ) - class AssertFieldOutputTests(SimpleTestCase): From d67a46e10459858b681176a3e1f8c6bca39d2ac7 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 08:26:23 -0500 Subject: [PATCH 0023/3180] Refs #25135 -- Removed support for the contrib.admin allow_tags attribute. Per deprecation timeline. --- django/contrib/admin/helpers.py | 14 +-------- .../contrib/admin/templatetags/admin_list.py | 11 ------- docs/ref/contrib/admin/index.txt | 8 ----- docs/releases/2.0.txt | 3 ++ tests/admin_changelist/tests.py | 31 +------------------ tests/admin_views/admin.py | 6 +--- tests/admin_views/tests.py | 14 +-------- 7 files changed, 7 insertions(+), 80 deletions(-) diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py index cbe03031a97c..604fcd5b260f 100644 --- a/django/contrib/admin/helpers.py +++ b/django/contrib/admin/helpers.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals import json -import warnings from django import forms from django.conf import settings @@ -14,7 +13,6 @@ from django.forms.utils import flatatt from django.template.defaultfilters import capfirst, linebreaksbr from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.utils.html import conditional_escape, format_html from django.utils.safestring import mark_safe @@ -218,17 +216,7 @@ def contents(self): if hasattr(value, "__html__"): result_repr = value else: - result_repr = force_text(value) - if getattr(attr, "allow_tags", False): - warnings.warn( - "Deprecated allow_tags attribute used on %s. " - "Use django.utils.html.format_html(), format_html_join(), " - "or django.utils.safestring.mark_safe() instead." % attr, - RemovedInDjango20Warning - ) - result_repr = mark_safe(value) - else: - result_repr = linebreaksbr(result_repr) + result_repr = linebreaksbr(force_text(value)) else: if isinstance(f.remote_field, ManyToManyRel) and value is not None: result_repr = ", ".join(map(six.text_type, value.all())) diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index ce2a80cbc258..ad6c03ea89ba 100644 --- a/django/contrib/admin/templatetags/admin_list.py +++ b/django/contrib/admin/templatetags/admin_list.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals import datetime -import warnings from django.contrib.admin.templatetags.admin_urls import add_preserved_filters from django.contrib.admin.utils import ( @@ -18,7 +17,6 @@ from django.templatetags.static import static from django.urls import NoReverseMatch from django.utils import formats -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.utils.html import format_html from django.utils.safestring import mark_safe @@ -223,17 +221,8 @@ def link_in_col(is_first, field_name, cl): if f is None or f.auto_created: if field_name == 'action_checkbox': row_classes = ['action-checkbox'] - allow_tags = getattr(attr, 'allow_tags', False) boolean = getattr(attr, 'boolean', False) result_repr = display_for_value(value, empty_value_display, boolean) - if allow_tags: - warnings.warn( - "Deprecated allow_tags attribute used on field {}. " - "Use django.utils.html.format_html(), format_html_join(), " - "or django.utils.safestring.mark_safe() instead.".format(field_name), - RemovedInDjango20Warning - ) - result_repr = mark_safe(result_repr) if isinstance(value, (datetime.date, datetime.time)): row_classes.append('nowrap') else: diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index 40acb7dd2966..b08d17421e1f 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -633,14 +633,6 @@ subclass:: class PersonAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'colored_name') - .. deprecated:: 1.9 - - In older versions, you could add an ``allow_tags`` attribute to the - method to prevent auto-escaping. This attribute is deprecated as it's - safer to use :func:`~django.utils.html.format_html`, - :func:`~django.utils.html.format_html_join`, or - :func:`~django.utils.safestring.mark_safe` instead. - * As some examples have already demonstrated, when using a callable, a model method, or a ``ModelAdmin`` method, you can customize the column's title by adding a ``short_description`` attribute to the callable. diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index d1edbf61800b..311a3d6da442 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -309,3 +309,6 @@ these features. * The ``callable_obj`` keyword argument to ``SimpleTestCase.assertRaisesMessage()`` is removed. + +* Support for the ``allow_tags`` attribute on ``ModelAdmin`` methods is + removed. diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index b2292a77a073..2f0f6ad46b2e 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -11,11 +11,10 @@ from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from django.template import Context, Template -from django.test import TestCase, ignore_warnings, override_settings +from django.test import TestCase, override_settings from django.test.client import RequestFactory from django.urls import reverse from django.utils import formats, six -from django.utils.deprecation import RemovedInDjango20Warning from .admin import ( BandAdmin, ChildAdmin, ChordsBandAdmin, ConcertAdmin, @@ -253,34 +252,6 @@ def test_result_list_editable(self): with self.assertRaises(IncorrectLookupParameters): ChangeList(request, Child, *get_changelist_args(m)) - @ignore_warnings(category=RemovedInDjango20Warning) - def test_result_list_with_allow_tags(self): - """ - Test for deprecation of allow_tags attribute - """ - new_parent = Parent.objects.create(name='parent') - for i in range(2): - Child.objects.create(name='name %s' % i, parent=new_parent) - request = self.factory.get('/child/') - m = ChildAdmin(Child, custom_site) - - def custom_method(self, obj=None): - return 'Unsafe html
' - custom_method.allow_tags = True - - # Add custom method with allow_tags attribute - m.custom_method = custom_method - m.list_display = ['id', 'name', 'parent', 'custom_method'] - - cl = ChangeList(request, Child, *get_changelist_args(m)) - FormSet = m.get_changelist_formset(request) - cl.formset = FormSet(queryset=cl.result_list) - template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}') - context = Context({'cl': cl}) - table_output = template.render(context) - custom_field_html = 'Unsafe html
' - self.assertInHTML(custom_field_html, table_output) - def test_custom_paginator(self): new_parent = Parent.objects.create(name='parent') for i in range(200): diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py index e8a1cf3bff0e..d85f5de059ae 100644 --- a/tests/admin_views/admin.py +++ b/tests/admin_views/admin.py @@ -447,7 +447,7 @@ class PostAdmin(admin.ModelAdmin): readonly_fields = ( 'posted', 'awesomeness_level', 'coolness', 'value', 'multiline', 'multiline_html', lambda obj: "foo", - 'multiline_html_allow_tags', 'readonly_content', + 'readonly_content', ) inlines = [ @@ -470,10 +470,6 @@ def multiline(self, instance): def multiline_html(self, instance): return mark_safe("Multiline
\nhtml
\ncontent") - def multiline_html_allow_tags(self, instance): - return "Multiline
html
content
with allow tags" - multiline_html_allow_tags.allow_tags = True - class FieldOverridePostForm(forms.ModelForm): model = FieldOverridePost diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index c952a9ebf27d..a724d57559b4 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -35,9 +35,7 @@ from django.utils import formats, six, translation from django.utils._os import upath from django.utils.cache import get_max_age -from django.utils.deprecation import ( - RemovedInDjango20Warning, RemovedInDjango21Warning, -) +from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_bytes, force_text, iri_to_uri from django.utils.html import escape from django.utils.http import urlencode @@ -4655,7 +4653,6 @@ def setUpTestData(cls): def setUp(self): self.client.force_login(self.superuser) - @ignore_warnings(category=RemovedInDjango20Warning) # for allow_tags deprecation def test_readonly_get(self): response = self.client.get(reverse('admin:admin_views_post_add')) self.assertEqual(response.status_code, 200) @@ -4673,12 +4670,6 @@ def test_readonly_get(self): self.assertContains(response, 'Multiline
test
string') self.assertContains(response, '
Multiline
html
content
', html=True) self.assertContains(response, 'InlineMultiline
test
string') - # Remove only this last line when the deprecation completes. - self.assertContains( - response, - '
Multiline
html
content
with allow tags
', - html=True - ) self.assertContains(response, formats.localize(datetime.date.today() - datetime.timedelta(days=7))) @@ -4708,7 +4699,6 @@ def test_readonly_get(self): response = self.client.get(reverse('admin:admin_views_post_change', args=(p.pk,))) self.assertContains(response, "%d amount of cool" % p.pk) - @ignore_warnings(category=RemovedInDjango20Warning) # for allow_tags deprecation def test_readonly_text_field(self): p = Post.objects.create( title="Readonly test", content="test", @@ -4802,7 +4792,6 @@ def test_readonly_onetoone_backwards_ref(self): field = self.get_admin_readonly_field(response, 'plotdetails') self.assertEqual(field.contents(), '-') # default empty value - @ignore_warnings(category=RemovedInDjango20Warning) # for allow_tags deprecation def test_readonly_field_overrides(self): """ Regression test for #22087 - ModelForm Meta overrides are ignored by @@ -5148,7 +5137,6 @@ def setUpTestData(cls): def setUp(self): self.client.force_login(self.superuser) - @ignore_warnings(category=RemovedInDjango20Warning) # for allow_tags deprecation def test_field_prefix_css_classes(self): """ Fields have a CSS class name with a 'field-' prefix. From 75cf9b5ac031feb8f94271c9906157c921a14520 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 08:27:32 -0500 Subject: [PATCH 0024/3180] Refs #13110 -- Removed SyndicationFeed.add_item()'s enclosure argument. Per deprecation timeline. --- django/utils/feedgenerator.py | 17 ++--------------- docs/ref/contrib/syndication.txt | 8 -------- docs/ref/utils.txt | 11 ++--------- docs/releases/2.0.txt | 3 +++ tests/syndication_tests/tests.py | 18 +----------------- 5 files changed, 8 insertions(+), 49 deletions(-) diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py index a27eb1f2e93f..d8a932b02002 100644 --- a/django/utils/feedgenerator.py +++ b/django/utils/feedgenerator.py @@ -24,10 +24,8 @@ from __future__ import unicode_literals import datetime -import warnings from django.utils import datetime_safe, six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text, iri_to_uri from django.utils.six import StringIO from django.utils.six.moves.urllib.parse import urlparse @@ -119,9 +117,8 @@ def to_unicode(s): def add_item(self, title, link, description, author_email=None, author_name=None, author_link=None, pubdate=None, comments=None, - unique_id=None, unique_id_is_permalink=None, enclosure=None, - categories=(), item_copyright=None, ttl=None, updateddate=None, - enclosures=None, **kwargs): + unique_id=None, unique_id_is_permalink=None, categories=(), + item_copyright=None, ttl=None, updateddate=None, enclosures=None, **kwargs): """ Adds an item to the feed. All args are expected to be Python Unicode objects except pubdate and updateddate, which are datetime.datetime @@ -135,16 +132,6 @@ def to_unicode(s): if ttl is not None: # Force ints to unicode ttl = force_text(ttl) - if enclosure is None: - enclosures = [] if enclosures is None else enclosures - else: - warnings.warn( - "The enclosure keyword argument is deprecated, " - "use enclosures instead.", - RemovedInDjango20Warning, - stacklevel=2, - ) - enclosures = [enclosure] item = { 'title': to_unicode(title), 'link': iri_to_uri(link), diff --git a/docs/ref/contrib/syndication.txt b/docs/ref/contrib/syndication.txt index 25851c94a390..3552f70f291e 100644 --- a/docs/ref/contrib/syndication.txt +++ b/docs/ref/contrib/syndication.txt @@ -963,7 +963,6 @@ They share this interface: * ``pubdate`` * ``comments`` * ``unique_id`` - * ``enclosure`` * ``enclosures`` * ``categories`` * ``item_copyright`` @@ -976,17 +975,10 @@ They share this interface: * ``pubdate`` should be a Python :class:`~datetime.datetime` object. * ``updateddate`` should be a Python :class:`~datetime.datetime` object. - * ``enclosure`` should be an instance of - :class:`django.utils.feedgenerator.Enclosure`. * ``enclosures`` should be a list of :class:`django.utils.feedgenerator.Enclosure` instances. * ``categories`` should be a sequence of Unicode objects. - .. deprecated:: 1.9 - - The ``enclosure`` keyword argument is deprecated in favor of the - ``enclosures`` keyword argument. - :meth:`.SyndicationFeed.write` Outputs the feed in the given encoding to outfile, which is a file-like object. diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index 18561781c1cd..1105dc9a169e 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -353,18 +353,11 @@ https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004 All parameters should be Unicode objects, except ``categories``, which should be a sequence of Unicode objects. - .. method:: add_item(title, link, description, author_email=None, author_name=None, author_link=None, pubdate=None, comments=None, unique_id=None, enclosure=None, categories=(), item_copyright=None, ttl=None, updateddate=None, enclosures=None, **kwargs) + .. method:: add_item(title, link, description, author_email=None, author_name=None, author_link=None, pubdate=None, comments=None, unique_id=None, categories=(), item_copyright=None, ttl=None, updateddate=None, enclosures=None, **kwargs) Adds an item to the feed. All args are expected to be Python ``unicode`` objects except ``pubdate`` and ``updateddate``, which are ``datetime.datetime`` - objects, ``enclosure``, which is an ``Enclosure`` instance, and - ``enclosures``, which is a list of ``Enclosure`` instances. - - .. deprecated:: 1.9 - - The ``enclosure`` keyword argument is deprecated in favor of the - new ``enclosures`` keyword argument which accepts a list of - ``Enclosure`` objects. + objects, and ``enclosures``, which is a list of ``Enclosure`` instances. .. method:: num_items() diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 311a3d6da442..13a47840c378 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -312,3 +312,6 @@ these features. * Support for the ``allow_tags`` attribute on ``ModelAdmin`` methods is removed. + +* The ``enclosure`` keyword argument to ``SyndicationFeed.add_item()`` is + removed. diff --git a/tests/syndication_tests/tests.py b/tests/syndication_tests/tests.py index f8948ac21d78..0fb860474cf5 100644 --- a/tests/syndication_tests/tests.py +++ b/tests/syndication_tests/tests.py @@ -9,10 +9,7 @@ from django.test import TestCase, override_settings from django.test.utils import requires_tz_support from django.utils import timezone -from django.utils.deprecation import RemovedInDjango20Warning -from django.utils.feedgenerator import ( - Enclosure, SyndicationFeed, rfc2822_date, rfc3339_date, -) +from django.utils.feedgenerator import rfc2822_date, rfc3339_date from .models import Article, Entry @@ -520,16 +517,3 @@ def test_add_domain(self): views.add_domain('example.com', '//example.com/foo/?arg=value'), 'http://example.com/foo/?arg=value' ) - - -class FeedgeneratorTestCase(TestCase): - def test_add_item_warns_when_enclosure_kwarg_is_used(self): - feed = SyndicationFeed(title='Example', link='http://example.com', description='Foo') - msg = 'The enclosure keyword argument is deprecated, use enclosures instead.' - with self.assertRaisesMessage(RemovedInDjango20Warning, msg): - feed.add_item( - title='Example Item', - link='https://example.com/item', - description='bar', - enclosure=Enclosure('http://example.com/favicon.ico', 0, 'image/png'), - ) From ff419de263138e905dff44c5cb806310c70f32aa Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 08:35:39 -0500 Subject: [PATCH 0025/3180] Refs #25466 -- Removed aliases for LoaderOrigin and StringOrigin. Per deprecation timeline. --- django/template/__init__.py | 3 +-- django/template/base.py | 9 +-------- django/template/loader.py | 9 --------- docs/releases/2.0.txt | 4 ++++ 4 files changed, 6 insertions(+), 19 deletions(-) diff --git a/django/template/__init__.py b/django/template/__init__.py index 9cf25754f8e4..b55b4491c699 100644 --- a/django/template/__init__.py +++ b/django/template/__init__.py @@ -58,8 +58,7 @@ # Template parts from .base import ( # NOQA isort:skip - Context, Node, NodeList, Origin, RequestContext, StringOrigin, Template, - Variable, + Context, Node, NodeList, Origin, RequestContext, Template, Variable, ) # Library management diff --git a/django/template/base.py b/django/template/base.py index afdf49cc0e98..dd604db23582 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -60,9 +60,7 @@ BaseContext, Context, ContextPopException, RequestContext, ) from django.utils import six -from django.utils.deprecation import ( - DeprecationInstanceCheck, RemovedInDjango20Warning, -) +from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import ( force_str, force_text, python_2_unicode_compatible, ) @@ -163,11 +161,6 @@ def loader_name(self): ) -class StringOrigin(six.with_metaclass(DeprecationInstanceCheck, Origin)): - alternative = 'django.template.Origin' - deprecation_warning = RemovedInDjango20Warning - - class Template(object): def __init__(self, template_string, origin=None, name=None, engine=None): try: diff --git a/django/template/loader.py b/django/template/loader.py index 44d5332b92e7..17b278812b50 100644 --- a/django/template/loader.py +++ b/django/template/loader.py @@ -1,10 +1,6 @@ from django.utils import six -from django.utils.deprecation import ( - DeprecationInstanceCheck, RemovedInDjango20Warning, -) from . import engines -from .base import Origin from .exceptions import TemplateDoesNotExist @@ -70,8 +66,3 @@ def render_to_string(template_name, context=None, request=None, using=None): def _engine_list(using=None): return engines.all() if using is None else [engines[using]] - - -class LoaderOrigin(six.with_metaclass(DeprecationInstanceCheck, Origin)): - alternative = 'django.template.Origin' - deprecation_warning = RemovedInDjango20Warning diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 13a47840c378..5a57c2289916 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -315,3 +315,7 @@ these features. * The ``enclosure`` keyword argument to ``SyndicationFeed.add_item()`` is removed. + +* The ``django.template.loader.LoaderOrigin`` and + ``django.template.base.StringOrigin`` aliases for + ``django.template.base.Origin`` are removed. From e0910dcc9283cd8f782cb97836c291f6f395f3f0 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 08:52:42 -0500 Subject: [PATCH 0026/3180] Refs #25604 -- Removed makemigrations --exit option per deprecation timeline. --- .../core/management/commands/makemigrations.py | 17 ----------------- docs/ref/django-admin.txt | 6 ------ docs/releases/1.8.txt | 2 +- docs/releases/2.0.txt | 2 ++ tests/migrations/test_commands.py | 16 +--------------- 5 files changed, 4 insertions(+), 39 deletions(-) diff --git a/django/core/management/commands/makemigrations.py b/django/core/management/commands/makemigrations.py index 50460691d898..b6a31d16fd85 100644 --- a/django/core/management/commands/makemigrations.py +++ b/django/core/management/commands/makemigrations.py @@ -1,7 +1,6 @@ import io import os import sys -import warnings from itertools import takewhile from django.apps import apps @@ -18,7 +17,6 @@ from django.db.migrations.state import ProjectState from django.db.migrations.utils import get_migration_name_timestamp from django.db.migrations.writer import MigrationWriter -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.six import iteritems from django.utils.six.moves import zip @@ -52,11 +50,6 @@ def add_arguments(self, parser): '-n', '--name', action='store', dest='name', default=None, help="Use this name for migration file(s).", ) - parser.add_argument( - '-e', '--exit', action='store_true', dest='exit_code', default=False, - help='Exit with error code 1 if no changes needing migrations are found. ' - 'Deprecated, use the --check option instead.', - ) parser.add_argument( '--check', action='store_true', dest='check_changes', help='Exit with a non-zero status if model changes are missing migrations.', @@ -69,15 +62,8 @@ def handle(self, *app_labels, **options): self.merge = options['merge'] self.empty = options['empty'] self.migration_name = options['name'] - self.exit_code = options['exit_code'] check_changes = options['check_changes'] - if self.exit_code: - warnings.warn( - "The --exit option is deprecated in favor of the --check option.", - RemovedInDjango20Warning - ) - # Make sure the app they asked for exists app_labels = set(app_labels) bad_app_labels = set() @@ -186,9 +172,6 @@ def handle(self, *app_labels, **options): self.stdout.write("No changes detected in apps '%s'" % ("', '".join(app_labels))) else: self.stdout.write("No changes detected") - - if self.exit_code: - sys.exit(1) else: self.write_migration_files(changes) if check_changes: diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt index 47cff8e8c6be..2a708036405f 100644 --- a/docs/ref/django-admin.txt +++ b/docs/ref/django-admin.txt @@ -704,12 +704,6 @@ Enables fixing of migration conflicts. Allows naming the generated migration(s) instead of using a generated name. -.. django-admin-option:: --exit, -e - -.. deprecated:: 1.10 - - Use the ``--check`` option instead. - Makes ``makemigrations`` exit with error code 1 when no migrations are created (or would have been created, if combined with ``--dry-run``). diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index 5cb91427c78b..6c45b455ecfb 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -445,7 +445,7 @@ Management Commands :setting:`FIXTURE_DIRS` contains duplicates or a default fixture directory path (``app_name/fixtures``), an exception is raised. -* The new :option:`makemigrations --exit` option allows exiting with an error +* The new ``makemigrations --exit`` option allows exiting with an error code if no migrations are created. * The new :djadmin:`showmigrations` command allows listing all migrations and diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 5a57c2289916..4c9347d554ae 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -319,3 +319,5 @@ these features. * The ``django.template.loader.LoaderOrigin`` and ``django.template.base.StringOrigin`` aliases for ``django.template.base.Origin`` are removed. + +* The ``makemigrations --exit`` option is removed. diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index 6477873e0da4..fd483b7f85bc 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -17,9 +17,8 @@ InconsistentMigrationHistory, MigrationSchemaMissing, ) from django.db.migrations.recorder import MigrationRecorder -from django.test import ignore_warnings, mock, override_settings +from django.test import mock, override_settings from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from .models import UnicodeModel, UnserializableModel @@ -1232,19 +1231,6 @@ def cmd(migration_count, migration_name, *args): self.assertIn("dependencies=[\n('migrations','0001_%s'),\n]" % migration_name_0001, content) self.assertIn("operations=[\n]", content) - @ignore_warnings(category=RemovedInDjango20Warning) - def test_makemigrations_exit(self): - """ - makemigrations --exit should exit with sys.exit(1) when there are no - changes to an app. - """ - with self.temporary_migration_module(): - call_command("makemigrations", "--exit", "migrations", verbosity=0) - - with self.temporary_migration_module(module="migrations.test_migrations_no_changes"): - with self.assertRaises(SystemExit): - call_command("makemigrations", "--exit", "migrations", verbosity=0) - def test_makemigrations_check(self): """ makemigrations --check should exit with a non-zero status when From ed251246cc6a22561217f38f7cf96598b22ff0fe Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 09:04:09 -0500 Subject: [PATCH 0027/3180] Refs #25550 -- Removed support for direct assignment to the reverse side of a related set. --- .../db/models/fields/related_descriptors.py | 22 +++-------- docs/ref/models/relations.txt | 23 ----------- docs/releases/2.0.txt | 3 ++ tests/many_to_many/tests.py | 38 ++++--------------- tests/many_to_one/tests.py | 5 +-- 5 files changed, 17 insertions(+), 74 deletions(-) diff --git a/django/db/models/fields/related_descriptors.py b/django/db/models/fields/related_descriptors.py index af6fdc3e25c1..19b465b8ada1 100644 --- a/django/db/models/fields/related_descriptors.py +++ b/django/db/models/fields/related_descriptors.py @@ -510,28 +510,16 @@ def __get__(self, instance, cls=None): return self.related_manager_cls(instance) def _get_set_deprecation_msg_params(self): - return ( # RemovedInDjango20Warning + return ( 'reverse side of a related set', self.rel.get_accessor_name(), ) def __set__(self, instance, value): - """ - Set the related objects through the reverse relation. - - With the example above, when setting ``parent.children = children``: - - - ``self`` is the descriptor managing the ``children`` attribute - - ``instance`` is the ``parent`` instance - - ``value`` is the ``children`` sequence on the right of the equal sign - """ - warnings.warn( - 'Direct assignment to the %s is deprecated due to the implicit ' - 'save() that happens. Use %s.set() instead.' % self._get_set_deprecation_msg_params(), - RemovedInDjango20Warning, stacklevel=2, + raise TypeError( + 'Direct assignment to the %s is prohibited. Use %s.set() instead.' + % self._get_set_deprecation_msg_params(), ) - manager = self.__get__(instance) - manager.set(value) def create_reverse_many_to_one_manager(superclass, rel): @@ -772,7 +760,7 @@ def related_manager_cls(self): ) def _get_set_deprecation_msg_params(self): - return ( # RemovedInDjango20Warning + return ( '%s side of a many-to-many set' % ('reverse' if self.reverse else 'forward'), self.rel.get_accessor_name() if self.reverse else self.field.name, ) diff --git a/docs/ref/models/relations.txt b/docs/ref/models/relations.txt index c34d3104b237..9cb61d14ed80 100644 --- a/docs/ref/models/relations.txt +++ b/docs/ref/models/relations.txt @@ -177,26 +177,3 @@ Related objects reference .. versionchanged:: 1.11 The clearing of the prefetched cache described above was added. - -Direct Assignment -================= - -A related object set can be replaced in bulk with one operation by assigning a -new iterable of objects to it:: - - >>> new_list = [obj1, obj2, obj3] - >>> e.related_set = new_list - -If the foreign key relationship has ``null=True``, then the related manager -will first disassociate any existing objects in the related set before adding -the contents of ``new_list``. Otherwise the objects in ``new_list`` will be -added to the existing related object set. - -.. deprecated:: 1.10 - - Direct assignment is deprecated in favor of the - :meth:`~django.db.models.fields.related.RelatedManager.set` method:: - - >>> e.related_set.set([obj1, obj2, obj3]) - - This prevents confusion about an assignment resulting in an implicit save. diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 4c9347d554ae..1d460674058c 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -321,3 +321,6 @@ these features. ``django.template.base.Origin`` are removed. * The ``makemigrations --exit`` option is removed. + +* Support for direct assignment to a reverse foreign key or many-to-many + relation is removed. diff --git a/tests/many_to_many/tests.py b/tests/many_to_many/tests.py index 291721447181..e5bc51be47a1 100644 --- a/tests/many_to_many/tests.py +++ b/tests/many_to_many/tests.py @@ -1,8 +1,7 @@ from __future__ import unicode_literals from django.db import transaction -from django.test import TestCase, ignore_warnings -from django.utils.deprecation import RemovedInDjango20Warning +from django.test import TestCase from .models import Article, InheritedArticleA, InheritedArticleB, Publication @@ -400,45 +399,22 @@ def test_set(self): self.a4.publications.set([], clear=True) self.assertQuerysetEqual(self.a4.publications.all(), []) - def test_assign_forward_deprecation(self): + def test_assign_forward(self): msg = ( "Direct assignment to the reverse side of a many-to-many set is " - "deprecated due to the implicit save() that happens. Use " - "article_set.set() instead." + "prohibited. Use article_set.set() instead." ) - with self.assertRaisesMessage(RemovedInDjango20Warning, msg): + with self.assertRaisesMessage(TypeError, msg): self.p2.article_set = [self.a4, self.a3] - def test_assign_reverse_deprecation(self): + def test_assign_reverse(self): msg = ( "Direct assignment to the forward side of a many-to-many " - "set is deprecated due to the implicit save() that happens. Use " - "publications.set() instead." + "set is prohibited. Use publications.set() instead." ) - with self.assertRaisesMessage(RemovedInDjango20Warning, msg): + with self.assertRaisesMessage(TypeError, msg): self.a1.publications = [self.p1, self.p2] - @ignore_warnings(category=RemovedInDjango20Warning) - def test_assign_deprecated(self): - self.p2.article_set = [self.a4, self.a3] - self.assertQuerysetEqual( - self.p2.article_set.all(), - [ - '', - '', - ] - ) - self.assertQuerysetEqual(self.a4.publications.all(), ['']) - self.a4.publications = [self.p3.id] - self.assertQuerysetEqual(self.p2.article_set.all(), ['']) - self.assertQuerysetEqual(self.a4.publications.all(), ['']) - - # An alternate to calling clear() is to assign the empty set - self.p2.article_set = [] - self.assertQuerysetEqual(self.p2.article_set.all(), []) - self.a4.publications = [] - self.assertQuerysetEqual(self.a4.publications.all(), []) - def test_assign(self): # Relation sets can be assigned using set(). self.p2.article_set.set([self.a4, self.a3]) diff --git a/tests/many_to_one/tests.py b/tests/many_to_one/tests.py index e29c485baaca..c0dd316f7929 100644 --- a/tests/many_to_one/tests.py +++ b/tests/many_to_one/tests.py @@ -115,10 +115,9 @@ def test_set(self): def test_reverse_assignment_deprecation(self): msg = ( "Direct assignment to the reverse side of a related set is " - "deprecated due to the implicit save() that happens. Use " - "article_set.set() instead." + "prohibited. Use article_set.set() instead." ) - with self.assertRaisesMessage(RemovedInDjango20Warning, msg): + with self.assertRaisesMessage(TypeError, msg): self.r2.article_set = [] def test_assign(self): From a0149848f7c068bc8507d3ec6f93cd2b7256098a Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 09:33:40 -0500 Subject: [PATCH 0028/3180] Refs #25665 -- Removed GEOSGeometry.get/set_srid() per deprecation timeline. --- django/contrib/gis/geos/geometry.py | 16 ---------------- docs/releases/2.0.txt | 3 +++ tests/gis_tests/geos_tests/test_geos.py | 8 -------- 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py index ffbbc0c859a1..cf5886dc07e0 100644 --- a/django/contrib/gis/geos/geometry.py +++ b/django/contrib/gis/geos/geometry.py @@ -5,7 +5,6 @@ from __future__ import unicode_literals import json -import warnings from ctypes import addressof, byref, c_double from django.contrib.gis import gdal @@ -22,7 +21,6 @@ ) from django.utils import six from django.utils.deconstruct import deconstructible -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_bytes, force_text @@ -385,20 +383,6 @@ def srid(self, srid): "Sets the SRID for the geometry." capi.geos_set_srid(self.ptr, 0 if srid is None else srid) - def get_srid(self): - warnings.warn( - "`get_srid()` is deprecated, use the `srid` property instead.", - RemovedInDjango20Warning, 2 - ) - return self.srid - - def set_srid(self, srid): - warnings.warn( - "`set_srid()` is deprecated, use the `srid` property instead.", - RemovedInDjango20Warning, 2 - ) - self.srid = srid - # #### Output Routines #### @property def ewkt(self): diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 1d460674058c..c4e3a90d8477 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -324,3 +324,6 @@ these features. * Support for direct assignment to a reverse foreign key or many-to-many relation is removed. + +* The ``get_srid()`` and ``set_srid()`` methods of + ``django.contrib.gis.geos.GEOSGeometry`` are removed. diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index 2aee39072da1..92f89ce88f14 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -1316,14 +1316,6 @@ def test_empty_point(self): p.transform(2774) self.assertEqual(p, Point(srid=2774)) - @ignore_warnings(category=RemovedInDjango20Warning) - def test_deprecated_srid_getters_setters(self): - p = Point(1, 2, srid=123) - self.assertEqual(p.get_srid(), p.srid) - - p.set_srid(321) - self.assertEqual(p.srid, 321) - @ignore_warnings(category=RemovedInDjango20Warning) def test_deprecated_point_coordinate_getters_setters(self): p = Point(1, 2, 3) From 19d8e64ac357271e708f6db377975ee85b7e4342 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 09:36:46 -0500 Subject: [PATCH 0029/3180] Refs #25665 -- Removed deprecated getters/setters of Point coordinate properties. --- django/contrib/gis/geos/point.py | 42 ------------------------- docs/releases/2.0.txt | 3 ++ tests/gis_tests/geos_tests/test_geos.py | 10 ------ 3 files changed, 3 insertions(+), 52 deletions(-) diff --git a/django/contrib/gis/geos/point.py b/django/contrib/gis/geos/point.py index c7b91f9bb57b..de21e0164400 100644 --- a/django/contrib/gis/geos/point.py +++ b/django/contrib/gis/geos/point.py @@ -140,48 +140,6 @@ def z(self, value): raise GEOSException('Cannot set Z on 2D Point.') self._cs.setOrdinate(2, 0, value) - def get_x(self): - warnings.warn( - "`get_x()` is deprecated, use the `x` property instead.", - RemovedInDjango20Warning, 2 - ) - return self.x - - def set_x(self, value): - warnings.warn( - "`set_x()` is deprecated, use the `x` property instead.", - RemovedInDjango20Warning, 2 - ) - self.x = value - - def get_y(self): - warnings.warn( - "`get_y()` is deprecated, use the `y` property instead.", - RemovedInDjango20Warning, 2 - ) - return self.y - - def set_y(self, value): - warnings.warn( - "`set_y()` is deprecated, use the `y` property instead.", - RemovedInDjango20Warning, 2 - ) - self.y = value - - def get_z(self): - warnings.warn( - "`get_z()` is deprecated, use the `z` property instead.", - RemovedInDjango20Warning, 2 - ) - return self.z - - def set_z(self, value): - warnings.warn( - "`set_z()` is deprecated, use the `z` property instead.", - RemovedInDjango20Warning, 2 - ) - self.z = value - # ### Tuple setting and retrieval routines. ### @property def tuple(self): diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index c4e3a90d8477..59a6e1f805ac 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -327,3 +327,6 @@ these features. * The ``get_srid()`` and ``set_srid()`` methods of ``django.contrib.gis.geos.GEOSGeometry`` are removed. + +* The ``get_x()``, ``set_x()``, ``get_y()``, ``set_y()``, ``get_z()``, and + ``set_z()`` methods of ``django.contrib.gis.geos.Point`` are removed. diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index 92f89ce88f14..6a689188d25c 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -1316,16 +1316,6 @@ def test_empty_point(self): p.transform(2774) self.assertEqual(p, Point(srid=2774)) - @ignore_warnings(category=RemovedInDjango20Warning) - def test_deprecated_point_coordinate_getters_setters(self): - p = Point(1, 2, 3) - self.assertEqual((p.get_x(), p.get_y(), p.get_z()), (p.x, p.y, p.z)) - - p.set_x(3) - p.set_y(2) - p.set_z(1) - self.assertEqual((p.x, p.y, p.z), (3, 2, 1)) - @ignore_warnings(category=RemovedInDjango20Warning) def test_deprecated_point_tuple_getters_setters(self): p = Point(1, 2, 3) From 997c9f709974ea79d9eb9e83eaf24e7bc0e7f9d4 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 09:42:27 -0500 Subject: [PATCH 0030/3180] Refs #25665 -- Removed deprecated getter/setter of Point.tuple. --- django/contrib/gis/geos/point.py | 16 ---------------- docs/releases/2.0.txt | 3 +++ tests/gis_tests/geos_tests/test_geos.py | 8 -------- 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/django/contrib/gis/geos/point.py b/django/contrib/gis/geos/point.py index de21e0164400..ec95cf1f637c 100644 --- a/django/contrib/gis/geos/point.py +++ b/django/contrib/gis/geos/point.py @@ -1,4 +1,3 @@ -import warnings from ctypes import c_uint from django.contrib.gis import gdal @@ -6,7 +5,6 @@ from django.contrib.gis.geos.error import GEOSException from django.contrib.gis.geos.geometry import GEOSGeometry from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.six.moves import range @@ -151,19 +149,5 @@ def tuple(self, tup): "Sets the coordinates of the point with the given tuple." self._cs[0] = tup - def get_coords(self): - warnings.warn( - "`get_coords()` is deprecated, use the `tuple` property instead.", - RemovedInDjango20Warning, 2 - ) - return self.tuple - - def set_coords(self, tup): - warnings.warn( - "`set_coords()` is deprecated, use the `tuple` property instead.", - RemovedInDjango20Warning, 2 - ) - self.tuple = tup - # The tuple and coords properties coords = tuple diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 59a6e1f805ac..6025e7de881e 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -330,3 +330,6 @@ these features. * The ``get_x()``, ``set_x()``, ``get_y()``, ``set_y()``, ``get_z()``, and ``set_z()`` methods of ``django.contrib.gis.geos.Point`` are removed. + +* The ``get_coords()`` and ``set_coords()`` methods of + ``django.contrib.gis.geos.Point`` are removed. diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index 6a689188d25c..4ee3c7309a3d 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -1316,14 +1316,6 @@ def test_empty_point(self): p.transform(2774) self.assertEqual(p, Point(srid=2774)) - @ignore_warnings(category=RemovedInDjango20Warning) - def test_deprecated_point_tuple_getters_setters(self): - p = Point(1, 2, 3) - self.assertEqual(p.get_coords(), (p.x, p.y, p.z)) - - p.set_coords((3, 2, 1)) - self.assertEqual(p.get_coords(), (3, 2, 1)) - @ignore_warnings(category=RemovedInDjango20Warning) def test_deprecated_cascaded_union(self): for geom in self.geometries.multipolygons: From 7e63e84572f076c3cb2988d753a334e204116ddb Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 09:45:55 -0500 Subject: [PATCH 0031/3180] Refs #25773 -- Removed deprecated geos.MultiPolygon.cascaded_union property. --- django/contrib/gis/geos/collections.py | 11 ----------- django/contrib/gis/geos/prototypes/topology.py | 1 - docs/ref/contrib/gis/geos.txt | 12 ------------ docs/releases/2.0.txt | 3 +++ tests/gis_tests/geos_tests/test_geos.py | 9 +-------- 5 files changed, 4 insertions(+), 32 deletions(-) diff --git a/django/contrib/gis/geos/collections.py b/django/contrib/gis/geos/collections.py index 7427a4569f7b..4935dbd1c3c6 100644 --- a/django/contrib/gis/geos/collections.py +++ b/django/contrib/gis/geos/collections.py @@ -3,7 +3,6 @@ GeometryCollection, MultiPoint, MultiLineString, and MultiPolygon """ import json -import warnings from ctypes import byref, c_int, c_uint from django.contrib.gis.geos import prototypes as capi @@ -13,7 +12,6 @@ from django.contrib.gis.geos.linestring import LinearRing, LineString from django.contrib.gis.geos.point import Point from django.contrib.gis.geos.polygon import Polygon -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.six.moves import range @@ -128,15 +126,6 @@ class MultiPolygon(GeometryCollection): _allowed = Polygon _typeid = 6 - @property - def cascaded_union(self): - "Returns a cascaded union of this MultiPolygon." - warnings.warn( - "`cascaded_union` is deprecated, use the `unary_union` property instead.", - RemovedInDjango20Warning, 2 - ) - return GEOSGeometry(capi.geos_cascaded_union(self.ptr), self.srid) - # Setting the allowed types here since GeometryCollection is defined before # its subclasses. diff --git a/django/contrib/gis/geos/prototypes/topology.py b/django/contrib/gis/geos/prototypes/topology.py index b2cf0681a8de..f8c36bc6f576 100644 --- a/django/contrib/gis/geos/prototypes/topology.py +++ b/django/contrib/gis/geos/prototypes/topology.py @@ -33,7 +33,6 @@ class Topology(GEOSFuncFactory): geos_symdifference = Topology('GEOSSymDifference', argtypes=[GEOM_PTR, GEOM_PTR]) geos_union = Topology('GEOSUnion', argtypes=[GEOM_PTR, GEOM_PTR]) -geos_cascaded_union = GEOSFuncFactory('GEOSUnionCascaded', argtypes=[GEOM_PTR], restype=GEOM_PTR) geos_unary_union = GEOSFuncFactory('GEOSUnaryUnion', argtypes=[GEOM_PTR], restype=GEOM_PTR) # GEOSRelate returns a string, not a geometry. diff --git a/docs/ref/contrib/gis/geos.txt b/docs/ref/contrib/gis/geos.txt index 165f3c075411..b92a91491abd 100644 --- a/docs/ref/contrib/gis/geos.txt +++ b/docs/ref/contrib/gis/geos.txt @@ -839,17 +839,6 @@ Geometry Collections In previous versions, an empty ``MultiPolygon`` couldn't be instantiated. - .. attribute:: cascaded_union - - .. deprecated:: 1.10 - - Use the :attr:`GEOSGeometry.unary_union` property instead. - - Returns a :class:`Polygon` that is the union of all of the component - polygons in this collection. The algorithm employed is significantly - more efficient (faster) than trying to union the geometries together - individually. [#fncascadedunion]_ - ``GeometryCollection`` ---------------------- @@ -1142,7 +1131,6 @@ include the SRID value (in other words, EWKB). .. rubric:: Footnotes .. [#fnogc] *See* `PostGIS EWKB, EWKT and Canonical Forms `_, PostGIS documentation at Ch. 4.1.2. -.. [#fncascadedunion] For more information, read Paul Ramsey's blog post about `(Much) Faster Unions in PostGIS 1.4 `_ and Martin Davis' blog post on `Fast polygon merging in JTS using Cascaded Union `_. Settings ======== diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 6025e7de881e..0bc5c8d388a9 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -333,3 +333,6 @@ these features. * The ``get_coords()`` and ``set_coords()`` methods of ``django.contrib.gis.geos.Point`` are removed. + +* The ``cascaded_union`` property of ``django.contrib.gis.geos.MultiPolygon`` + is removed. diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index 4ee3c7309a3d..46583c9605ac 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -18,9 +18,8 @@ from django.contrib.gis.shortcuts import numpy from django.template import Context from django.template.engine import Engine -from django.test import SimpleTestCase, ignore_warnings, mock +from django.test import SimpleTestCase, mock from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_bytes from django.utils.six.moves import range @@ -1315,9 +1314,3 @@ def test_empty_point(self): self.assertEqual(p.transform(2774, clone=True), Point(srid=2774)) p.transform(2774) self.assertEqual(p, Point(srid=2774)) - - @ignore_warnings(category=RemovedInDjango20Warning) - def test_deprecated_cascaded_union(self): - for geom in self.geometries.multipolygons: - mpoly = GEOSGeometry(geom.wkt) - self.assertEqual(mpoly.cascaded_union, mpoly.unary_union) From 9d304b26cf2ce071a682bf68a29dee04d0e4cfdb Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 09:52:31 -0500 Subject: [PATCH 0032/3180] Refs #20223 -- Removed deprecated django.utils.functional.allow_lazy(). --- django/utils/functional.py | 10 ---------- docs/ref/utils.txt | 7 ------- docs/releases/2.0.txt | 2 ++ tests/decorators/tests.py | 15 +-------------- 4 files changed, 3 insertions(+), 31 deletions(-) diff --git a/django/utils/functional.py b/django/utils/functional.py index 7d5b7feea550..794f31047c5e 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -1,10 +1,8 @@ import copy import operator -import warnings from functools import total_ordering, wraps from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning # You can't trivially replace this with `functools.partial` because this binds @@ -189,14 +187,6 @@ def lazystr(text): return lazy(force_text, six.text_type)(text) -def allow_lazy(func, *resultclasses): - warnings.warn( - "django.utils.functional.allow_lazy() is deprecated in favor of " - "django.utils.functional.keep_lazy()", - RemovedInDjango20Warning, 2) - return keep_lazy(*resultclasses)(func) - - def keep_lazy(*resultclasses): """ A decorator that allows a function to be called with one or more lazy diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index 1105dc9a169e..5870c955f6d9 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -518,13 +518,6 @@ https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004 z = person.friends # does not call x is z # is True -.. function:: allow_lazy(func, *resultclasses) - - .. deprecated:: 1.10 - - Works like :meth:`~django.utils.functional.keep_lazy` except that it can't - be used as a decorator. - .. function:: keep_lazy(func, *resultclasses) .. versionadded:: 1.10 diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 0bc5c8d388a9..1acfdb590095 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -336,3 +336,5 @@ these features. * The ``cascaded_union`` property of ``django.contrib.gis.geos.MultiPolygon`` is removed. + +* ``django.utils.functional.allow_lazy()`` is removed. diff --git a/tests/decorators/tests.py b/tests/decorators/tests.py index f8f8f4dc0a5a..851c2b8daa9b 100644 --- a/tests/decorators/tests.py +++ b/tests/decorators/tests.py @@ -8,13 +8,9 @@ from django.http import HttpRequest, HttpResponse, HttpResponseNotAllowed from django.middleware.clickjacking import XFrameOptionsMiddleware from django.test import SimpleTestCase -from django.utils import six from django.utils.decorators import method_decorator -from django.utils.deprecation import RemovedInDjango20Warning -from django.utils.encoding import force_text -from django.utils.functional import allow_lazy, keep_lazy, keep_lazy_text, lazy +from django.utils.functional import keep_lazy, keep_lazy_text, lazy from django.utils.safestring import mark_safe -from django.utils.translation import ugettext_lazy from django.views.decorators.cache import ( cache_control, cache_page, never_cache, ) @@ -155,15 +151,6 @@ def my_view(request): request.method = 'DELETE' self.assertIsInstance(my_safe_view(request), HttpResponseNotAllowed) - def test_deprecated_allow_lazy(self): - with self.assertRaises(RemovedInDjango20Warning): - def noop_text(text): - return force_text(text) - noop_text = allow_lazy(noop_text, six.text_type) - rendered = noop_text(ugettext_lazy("I am a text")) - self.assertEqual(type(rendered), six.text_type) - self.assertEqual(rendered, "I am a text") - # For testing method_decorator, a decorator that assumes a single argument. # We will get type arguments if there is a mismatch in the number of arguments. From f65b1aee71dfb17dcf5738545db3f3fdf980fe72 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 09:56:26 -0500 Subject: [PATCH 0033/3180] Refs #25838 -- Removed the deprecated shell --plain option. --- django/core/management/commands/shell.py | 14 -------------- docs/ref/django-admin.txt | 5 ----- docs/releases/2.0.txt | 2 ++ 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/django/core/management/commands/shell.py b/django/core/management/commands/shell.py index de8f33ed84ec..ce4d9daa7e9b 100644 --- a/django/core/management/commands/shell.py +++ b/django/core/management/commands/shell.py @@ -1,11 +1,9 @@ import os import select import sys -import warnings from django.core.management import BaseCommand, CommandError from django.utils.datastructures import OrderedSet -from django.utils.deprecation import RemovedInDjango20Warning class Command(BaseCommand): @@ -19,11 +17,6 @@ class Command(BaseCommand): shells = ['ipython', 'bpython', 'python'] def add_arguments(self, parser): - parser.add_argument( - '--plain', action='store_true', dest='plain', - help='Tells Django to use plain Python, not IPython or bpython. ' - 'Deprecated, use the `-i python` or `--interface python` option instead.', - ) parser.add_argument( '--no-startup', action='store_true', dest='no_startup', help='When using plain Python, ignore the PYTHONSTARTUP environment variable and ~/.pythonrc.py script.', @@ -83,13 +76,6 @@ def python(self, options): code.interact(local=imported_objects) def handle(self, **options): - if options['plain']: - warnings.warn( - "The --plain option is deprecated in favor of the -i python or --interface python option.", - RemovedInDjango20Warning - ) - options['interface'] = 'python' - # Execute the command and exit. if options['command']: exec(options['command']) diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt index 2a708036405f..aa9ebf7139ed 100644 --- a/docs/ref/django-admin.txt +++ b/docs/ref/django-admin.txt @@ -951,11 +951,6 @@ Python interpreter, use ``python`` as the interface name, like so:: django-admin shell -i python -.. deprecated:: 1.10 - - In older versions, use the ``--plain`` option instead of ``-i python``. This - is deprecated and will be removed in Django 2.0. - .. _IPython: https://ipython.org/ .. _bpython: http://bpython-interpreter.org/ diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 1acfdb590095..c01dc3d3583b 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -338,3 +338,5 @@ these features. is removed. * ``django.utils.functional.allow_lazy()`` is removed. + +* The ``shell --plain`` option is removed. From bc3540ce2c7cc59ec39a23ed16b14cc12f485bf3 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 09:59:51 -0500 Subject: [PATCH 0034/3180] Refs #26013 -- Removed deprecated django.core.urlresolvers module. --- django/core/urlresolvers.py | 9 --------- docs/ref/exceptions.txt | 6 ------ docs/ref/urlresolvers.txt | 6 ------ docs/releases/2.0.txt | 2 ++ 4 files changed, 2 insertions(+), 21 deletions(-) delete mode 100644 django/core/urlresolvers.py diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py deleted file mode 100644 index c7b5d2570c90..000000000000 --- a/django/core/urlresolvers.py +++ /dev/null @@ -1,9 +0,0 @@ -import warnings - -from django.urls import * # NOQA -from django.utils.deprecation import RemovedInDjango20Warning - -warnings.warn( - "Importing from django.core.urlresolvers is deprecated in favor of " - "django.urls.", RemovedInDjango20Warning, stacklevel=2 -) diff --git a/docs/ref/exceptions.txt b/docs/ref/exceptions.txt index 6ce52977e812..7245bccaf89b 100644 --- a/docs/ref/exceptions.txt +++ b/docs/ref/exceptions.txt @@ -173,12 +173,6 @@ URL Resolver exceptions URL Resolver exceptions are defined in ``django.urls``. -.. deprecated:: 1.10 - - In older versions, these exceptions are located in - ``django.core.urlresolvers``. Importing from the old location will continue - to work until Django 2.0. - ``Resolver404`` --------------- diff --git a/docs/ref/urlresolvers.txt b/docs/ref/urlresolvers.txt index 3c18bf3c875f..6e3ec595b16f 100644 --- a/docs/ref/urlresolvers.txt +++ b/docs/ref/urlresolvers.txt @@ -4,12 +4,6 @@ .. module:: django.urls -.. deprecated:: 1.10 - - In older versions, these functions are located in - ``django.core.urlresolvers``. Importing from the old location will continue - to work until Django 2.0. - ``reverse()`` ============= diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index c01dc3d3583b..723c69553383 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -340,3 +340,5 @@ these features. * ``django.utils.functional.allow_lazy()`` is removed. * The ``shell --plain`` option is removed. + +* The ``django.core.urlresolvers`` module is removed. From bcf3532ede16407f1a701717deaed835eda3e87b Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 10:30:41 -0500 Subject: [PATCH 0035/3180] Refs #26154 -- Removed deprecated CommaSeparatedIntegerField. --- django/db/backends/mysql/base.py | 1 - django/db/backends/oracle/base.py | 1 - django/db/backends/postgresql/base.py | 1 - django/db/backends/sqlite3/base.py | 1 - django/db/models/fields/__init__.py | 21 +++------- docs/ref/checks.txt | 5 ++- docs/ref/databases.txt | 3 +- docs/ref/models/fields.txt | 15 ------- docs/releases/2.0.txt | 3 ++ docs/topics/forms/modelforms.txt | 2 - tests/expressions_case/models.py | 1 - tests/expressions_case/tests.py | 14 ------- tests/inspectdb/models.py | 1 - tests/inspectdb/tests.py | 1 - .../test_deprecated_fields.py | 9 ++-- tests/model_fields/models.py | 40 +++++++++--------- tests/model_fields/test_promises.py | 15 ++----- tests/model_fields/tests.py | 2 +- tests/model_forms/models.py | 8 ---- tests/model_forms/tests.py | 41 +++---------------- tests/model_inheritance_regress/models.py | 1 - tests/runtests.py | 1 - 22 files changed, 48 insertions(+), 139 deletions(-) diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index d7bb1297449f..a2416c82cddc 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -135,7 +135,6 @@ class DatabaseWrapper(BaseDatabaseWrapper): 'BinaryField': 'longblob', 'BooleanField': 'bool', 'CharField': 'varchar(%(max_length)s)', - 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)', 'DateField': 'date', 'DateTimeField': 'datetime', 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)', diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index c40a515f3382..cf17f9fa6c73 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -89,7 +89,6 @@ class DatabaseWrapper(BaseDatabaseWrapper): 'BinaryField': 'BLOB', 'BooleanField': 'NUMBER(1)', 'CharField': 'NVARCHAR2(%(max_length)s)', - 'CommaSeparatedIntegerField': 'VARCHAR2(%(max_length)s)', 'DateField': 'DATE', 'DateTimeField': 'TIMESTAMP', 'DecimalField': 'NUMBER(%(max_digits)s, %(decimal_places)s)', diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py index c40a67b2e154..85a21a890588 100644 --- a/django/db/backends/postgresql/base.py +++ b/django/db/backends/postgresql/base.py @@ -76,7 +76,6 @@ class DatabaseWrapper(BaseDatabaseWrapper): 'BinaryField': 'bytea', 'BooleanField': 'boolean', 'CharField': 'varchar(%(max_length)s)', - 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)', 'DateField': 'date', 'DateTimeField': 'timestamp with time zone', 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)', diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py index 0c26882a5750..252293d9cca3 100644 --- a/django/db/backends/sqlite3/base.py +++ b/django/db/backends/sqlite3/base.py @@ -73,7 +73,6 @@ class DatabaseWrapper(BaseDatabaseWrapper): 'BinaryField': 'BLOB', 'BooleanField': 'bool', 'CharField': 'varchar(%(max_length)s)', - 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)', 'DateField': 'date', 'DateTimeField': 'datetime', 'DecimalField': 'decimal', diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index f5d6734aab4e..2018797564e1 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -1090,27 +1090,18 @@ def formfield(self, **kwargs): class CommaSeparatedIntegerField(CharField): default_validators = [validators.validate_comma_separated_integer_list] description = _("Comma-separated integers") - system_check_deprecated_details = { + system_check_removed_details = { 'msg': ( - 'CommaSeparatedIntegerField has been deprecated. Support ' - 'for it (except in historical migrations) will be removed ' - 'in Django 2.0.' + 'CommaSeparatedIntegerField is removed except for support in ' + 'historical migrations.' ), 'hint': ( - 'Use CharField(validators=[validate_comma_separated_integer_list]) instead.' + 'Use CharField(validators=[validate_comma_separated_integer_list]) ' + 'instead.' ), - 'id': 'fields.W901', + 'id': 'fields.E901', } - def formfield(self, **kwargs): - defaults = { - 'error_messages': { - 'invalid': _('Enter only digits separated by commas.'), - } - } - defaults.update(kwargs) - return super(CommaSeparatedIntegerField, self).formfield(**defaults) - class DateTimeCheckMixin(object): diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index d5d0bd4e0f78..fbdb34c7d999 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -174,7 +174,10 @@ Model fields (except in historical migrations) will be removed in Django 1.9. *This check appeared in Django 1.7 and 1.8*. * **fields.W901**: ``CommaSeparatedIntegerField`` has been deprecated. Support - for it (except in historical migrations) will be removed in Django 2.0. + for it (except in historical migrations) will be removed in Django 2.0. *This + check appeared in Django 1.10 and 1.11*. +* **fields.E901**: ``CommaSeparatedIntegerField`` is removed except for support + in historical migrations. File fields ~~~~~~~~~~~ diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt index 0c2465a9af0d..03fed7db248a 100644 --- a/docs/ref/databases.txt +++ b/docs/ref/databases.txt @@ -584,8 +584,7 @@ Character fields Any fields that are stored with ``VARCHAR`` column types have their ``max_length`` restricted to 255 characters if you are using ``unique=True`` for the field. This affects :class:`~django.db.models.CharField`, -:class:`~django.db.models.SlugField` and -:class:`~django.db.models.CommaSeparatedIntegerField`. +:class:`~django.db.models.SlugField`. ``TextField`` limitations ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index 1d03bf99f2a9..5e6e2e1c0ea7 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -480,21 +480,6 @@ The default form widget for this field is a :class:`~django.forms.TextInput`. of. Refer to the :ref:`MySQL database notes ` for details. -``CommaSeparatedIntegerField`` ------------------------------- - -.. class:: CommaSeparatedIntegerField(max_length=None, **options) - -.. deprecated:: 1.9 - - This field is deprecated in favor of :class:`~django.db.models.CharField` - with ``validators=[``\ :func:`validate_comma_separated_integer_list - `\ ``]``. - -A field of integers separated by commas. As in :class:`CharField`, the -:attr:`~CharField.max_length` argument is required and the note about database -portability mentioned there should be heeded. - ``DateField`` ------------- diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 723c69553383..9be5fda3cac9 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -342,3 +342,6 @@ these features. * The ``shell --plain`` option is removed. * The ``django.core.urlresolvers`` module is removed. + +* ``CommaSeparatedIntegerField`` is removed, except for support in historical + migrations. diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt index bc0c12401408..eb397a3d4ac5 100644 --- a/docs/topics/forms/modelforms.txt +++ b/docs/topics/forms/modelforms.txt @@ -70,8 +70,6 @@ Model field Form field :attr:`~django.forms.CharField.empty_value` set to ``None`` if ``null=True``. -:class:`CommaSeparatedIntegerField` :class:`~django.forms.CharField` - :class:`DateField` :class:`~django.forms.DateField` :class:`DateTimeField` :class:`~django.forms.DateTimeField` diff --git a/tests/expressions_case/models.py b/tests/expressions_case/models.py index 1471239896db..9f559a4f9d9c 100644 --- a/tests/expressions_case/models.py +++ b/tests/expressions_case/models.py @@ -18,7 +18,6 @@ class CaseTestModel(models.Model): big_integer = models.BigIntegerField(null=True) binary = models.BinaryField(default=b'') boolean = models.BooleanField(default=False) - comma_separated_integer = models.CommaSeparatedIntegerField(max_length=100, default='') date = models.DateField(null=True, db_column='date_field') date_time = models.DateTimeField(null=True) decimal = models.DecimalField(max_digits=2, decimal_places=1, null=True, db_column='decimal_field') diff --git a/tests/expressions_case/tests.py b/tests/expressions_case/tests.py index 91806c27647d..4617bcacb8c1 100644 --- a/tests/expressions_case/tests.py +++ b/tests/expressions_case/tests.py @@ -667,20 +667,6 @@ def test_update_boolean(self): transform=attrgetter('integer', 'boolean') ) - def test_update_comma_separated_integer(self): - CaseTestModel.objects.update( - comma_separated_integer=Case( - When(integer=1, then=Value('1')), - When(integer=2, then=Value('2,2')), - default=Value(''), - ), - ) - self.assertQuerysetEqual( - CaseTestModel.objects.all().order_by('pk'), - [(1, '1'), (2, '2,2'), (3, ''), (2, '2,2'), (3, ''), (3, ''), (4, '')], - transform=attrgetter('integer', 'comma_separated_integer') - ) - def test_update_date(self): CaseTestModel.objects.update( date=Case( diff --git a/tests/inspectdb/models.py b/tests/inspectdb/models.py index 4b17c0444f70..868f3ba4fe92 100644 --- a/tests/inspectdb/models.py +++ b/tests/inspectdb/models.py @@ -50,7 +50,6 @@ class ColumnTypes(models.Model): null_bool_field = models.NullBooleanField() char_field = models.CharField(max_length=10) null_char_field = models.CharField(max_length=10, blank=True, null=True) - comma_separated_int_field = models.CommaSeparatedIntegerField(max_length=99) date_field = models.DateField() date_time_field = models.DateTimeField() decimal_field = models.DecimalField(max_digits=6, decimal_places=1) diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py index 83eda4a7ded0..daa0800d7c68 100644 --- a/tests/inspectdb/tests.py +++ b/tests/inspectdb/tests.py @@ -60,7 +60,6 @@ def test_field_types(self): if not connection.features.interprets_empty_strings_as_nulls: assertFieldType('char_field', "models.CharField(max_length=10)") assertFieldType('null_char_field', "models.CharField(max_length=10, blank=True, null=True)") - assertFieldType('comma_separated_int_field', "models.CharField(max_length=99)") assertFieldType('email_field', "models.CharField(max_length=254)") assertFieldType('file_field', "models.CharField(max_length=100)") assertFieldType('file_path_field', "models.CharField(max_length=100)") diff --git a/tests/invalid_models_tests/test_deprecated_fields.py b/tests/invalid_models_tests/test_deprecated_fields.py index aca58cb607b9..ec713d95fffe 100644 --- a/tests/invalid_models_tests/test_deprecated_fields.py +++ b/tests/invalid_models_tests/test_deprecated_fields.py @@ -29,12 +29,11 @@ class CommaSeparatedIntegerModel(models.Model): model = CommaSeparatedIntegerModel() self.assertEqual( model.check(), - [checks.Warning( - 'CommaSeparatedIntegerField has been deprecated. Support ' - 'for it (except in historical migrations) will be removed ' - 'in Django 2.0.', + [checks.Error( + 'CommaSeparatedIntegerField is removed except for support in ' + 'historical migrations.', hint='Use CharField(validators=[validate_comma_separated_integer_list]) instead.', obj=CommaSeparatedIntegerModel._meta.get_field('csi'), - id='fields.W901', + id='fields.E901', )], ) diff --git a/tests/model_fields/models.py b/tests/model_fields/models.py index cd0f53c4f2e0..019301d5e2da 100644 --- a/tests/model_fields/models.py +++ b/tests/model_fields/models.py @@ -163,28 +163,27 @@ class VerboseNameField(models.Model): field1 = models.BigIntegerField("verbose field1") field2 = models.BooleanField("verbose field2", default=False) field3 = models.CharField("verbose field3", max_length=10) - field4 = models.CommaSeparatedIntegerField("verbose field4", max_length=99) - field5 = models.DateField("verbose field5") - field6 = models.DateTimeField("verbose field6") - field7 = models.DecimalField("verbose field7", max_digits=6, decimal_places=1) - field8 = models.EmailField("verbose field8") - field9 = models.FileField("verbose field9", upload_to="unused") - field10 = models.FilePathField("verbose field10") - field11 = models.FloatField("verbose field11") + field4 = models.DateField("verbose field4") + field5 = models.DateTimeField("verbose field5") + field6 = models.DecimalField("verbose field6", max_digits=6, decimal_places=1) + field7 = models.EmailField("verbose field7") + field8 = models.FileField("verbose field8", upload_to="unused") + field9 = models.FilePathField("verbose field9") + field10 = models.FloatField("verbose field10") # Don't want to depend on Pillow in this test # field_image = models.ImageField("verbose field") - field12 = models.IntegerField("verbose field12") - field13 = models.GenericIPAddressField("verbose field13", protocol="ipv4") - field14 = models.NullBooleanField("verbose field14") - field15 = models.PositiveIntegerField("verbose field15") - field16 = models.PositiveSmallIntegerField("verbose field16") - field17 = models.SlugField("verbose field17") - field18 = models.SmallIntegerField("verbose field18") - field19 = models.TextField("verbose field19") - field20 = models.TimeField("verbose field20") - field21 = models.URLField("verbose field21") - field22 = models.UUIDField("verbose field22") - field23 = models.DurationField("verbose field23") + field11 = models.IntegerField("verbose field11") + field12 = models.GenericIPAddressField("verbose field12", protocol="ipv4") + field13 = models.NullBooleanField("verbose field13") + field14 = models.PositiveIntegerField("verbose field14") + field15 = models.PositiveSmallIntegerField("verbose field15") + field16 = models.SlugField("verbose field16") + field17 = models.SmallIntegerField("verbose field17") + field18 = models.TextField("verbose field18") + field19 = models.TimeField("verbose field19") + field20 = models.URLField("verbose field20") + field21 = models.UUIDField("verbose field21") + field22 = models.DurationField("verbose field22") class GenericIPAddress(models.Model): @@ -322,7 +321,6 @@ class AllFieldsModel(models.Model): binary = models.BinaryField() boolean = models.BooleanField(default=False) char = models.CharField(max_length=10) - csv = models.CommaSeparatedIntegerField(max_length=10) date = models.DateField() datetime = models.DateTimeField() decimal = models.DecimalField(decimal_places=2, max_digits=2) diff --git a/tests/model_fields/test_promises.py b/tests/model_fields/test_promises.py index c1b476e75e5d..65d1b7ec991b 100644 --- a/tests/model_fields/test_promises.py +++ b/tests/model_fields/test_promises.py @@ -6,11 +6,10 @@ from django.db.models.fields import ( AutoField, BigIntegerField, BinaryField, BooleanField, CharField, - CommaSeparatedIntegerField, DateField, DateTimeField, DecimalField, - EmailField, FilePathField, FloatField, GenericIPAddressField, IntegerField, - IPAddressField, NullBooleanField, PositiveIntegerField, - PositiveSmallIntegerField, SlugField, SmallIntegerField, TextField, - TimeField, URLField, + DateField, DateTimeField, DecimalField, EmailField, FilePathField, + FloatField, GenericIPAddressField, IntegerField, IPAddressField, + NullBooleanField, PositiveIntegerField, PositiveSmallIntegerField, + SlugField, SmallIntegerField, TextField, TimeField, URLField, ) from django.db.models.fields.files import FileField, ImageField from django.test import SimpleTestCase @@ -43,12 +42,6 @@ def test_CharField(self): lazy_func = lazy(lambda: 0, int) self.assertIsInstance(CharField().get_prep_value(lazy_func()), six.text_type) - def test_CommaSeparatedIntegerField(self): - lazy_func = lazy(lambda: '1,2', six.text_type) - self.assertIsInstance(CommaSeparatedIntegerField().get_prep_value(lazy_func()), six.text_type) - lazy_func = lazy(lambda: 0, int) - self.assertIsInstance(CommaSeparatedIntegerField().get_prep_value(lazy_func()), six.text_type) - def test_DateField(self): lazy_func = lazy(lambda: datetime.date.today(), datetime.date) self.assertIsInstance(DateField().get_prep_value(lazy_func()), datetime.date) diff --git a/tests/model_fields/tests.py b/tests/model_fields/tests.py index 586919633543..76b3e5596a8b 100644 --- a/tests/model_fields/tests.py +++ b/tests/model_fields/tests.py @@ -42,7 +42,7 @@ def test_field_name(self): def test_field_verbose_name(self): m = VerboseNameField - for i in range(1, 24): + for i in range(1, 23): self.assertEqual(m._meta.get_field('field%d' % i).verbose_name, 'verbose field%d' % i) self.assertEqual(m._meta.get_field('id').verbose_name, 'verbose pk') diff --git a/tests/model_forms/models.py b/tests/model_forms/models.py index f873cfea972c..3675e080faea 100644 --- a/tests/model_forms/models.py +++ b/tests/model_forms/models.py @@ -218,14 +218,6 @@ def __str__(self): test_images = False -@python_2_unicode_compatible -class CommaSeparatedInteger(models.Model): - field = models.CommaSeparatedIntegerField(max_length=20) - - def __str__(self): - return self.field - - class Homepage(models.Model): url = models.URLField() diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index 1686629c3a5f..ef808f72f56a 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -24,12 +24,12 @@ from .models import ( Article, ArticleStatus, Author, Author1, Award, BetterWriter, BigInt, Book, - Category, Character, Colour, ColourfulItem, CommaSeparatedInteger, - CustomErrorMessage, CustomFF, CustomFieldForExclusionModel, DateTimePost, - DerivedBook, DerivedPost, Document, ExplicitPK, FilePathModel, - FlexibleDatePost, Homepage, ImprovedArticle, ImprovedArticleWithParentLink, - Inventory, NullableUniqueCharFieldModel, Person, Photo, Post, Price, - Product, Publication, PublicationDefaults, StrictAssignmentAll, + Category, Character, Colour, ColourfulItem, CustomErrorMessage, CustomFF, + CustomFieldForExclusionModel, DateTimePost, DerivedBook, DerivedPost, + Document, ExplicitPK, FilePathModel, FlexibleDatePost, Homepage, + ImprovedArticle, ImprovedArticleWithParentLink, Inventory, + NullableUniqueCharFieldModel, Person, Photo, Post, Price, Product, + Publication, PublicationDefaults, StrictAssignmentAll, StrictAssignmentFieldSpecific, Student, StumpJoke, TextFile, Triple, Writer, WriterProfile, test_images, ) @@ -2411,35 +2411,6 @@ def test_big_integer_field(self): self.assertFalse(bif.is_valid()) self.assertEqual(bif.errors, {'biggie': ['Ensure this value is less than or equal to 9223372036854775807.']}) - def test_comma_separated_integer_field(self): - class CommaSeparatedIntegerForm(forms.ModelForm): - class Meta: - model = CommaSeparatedInteger - fields = '__all__' - - f = CommaSeparatedIntegerForm({'field': '1'}) - self.assertTrue(f.is_valid()) - self.assertEqual(f.cleaned_data, {'field': '1'}) - f = CommaSeparatedIntegerForm({'field': '12'}) - self.assertTrue(f.is_valid()) - self.assertEqual(f.cleaned_data, {'field': '12'}) - f = CommaSeparatedIntegerForm({'field': '1,2,3'}) - self.assertTrue(f.is_valid()) - self.assertEqual(f.cleaned_data, {'field': '1,2,3'}) - f = CommaSeparatedIntegerForm({'field': '10,32'}) - self.assertTrue(f.is_valid()) - self.assertEqual(f.cleaned_data, {'field': '10,32'}) - f = CommaSeparatedIntegerForm({'field': '1a,2'}) - self.assertEqual(f.errors, {'field': ['Enter only digits separated by commas.']}) - f = CommaSeparatedIntegerForm({'field': ',,,,'}) - self.assertEqual(f.errors, {'field': ['Enter only digits separated by commas.']}) - f = CommaSeparatedIntegerForm({'field': '1.2'}) - self.assertEqual(f.errors, {'field': ['Enter only digits separated by commas.']}) - f = CommaSeparatedIntegerForm({'field': '1,a,2'}) - self.assertEqual(f.errors, {'field': ['Enter only digits separated by commas.']}) - f = CommaSeparatedIntegerForm({'field': '1,,2'}) - self.assertEqual(f.errors, {'field': ['Enter only digits separated by commas.']}) - def test_url_on_modelform(self): "Check basic URL field validation on model forms" class HomepageForm(forms.ModelForm): diff --git a/tests/model_inheritance_regress/models.py b/tests/model_inheritance_regress/models.py index 07d5a22c9bb8..8481e215164a 100644 --- a/tests/model_inheritance_regress/models.py +++ b/tests/model_inheritance_regress/models.py @@ -217,7 +217,6 @@ class Meta: class BusStation(Station): - bus_routes = models.CommaSeparatedIntegerField(max_length=128) inbound = models.BooleanField(default=False) diff --git a/tests/runtests.py b/tests/runtests.py index 6cec7d6e5c8c..a99ebd63c3fa 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -165,7 +165,6 @@ def no_available_apps(self): settings.LOGGING = log_config settings.SILENCED_SYSTEM_CHECKS = [ 'fields.W342', # ForeignKey(unique=True) -> OneToOneField - 'fields.W901', # CommaSeparatedIntegerField deprecated ] # Load all the ALWAYS_INSTALLED_APPS. From 740f63a3df2be086917c255421480c568c949f9b Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 11:02:10 -0500 Subject: [PATCH 0036/3180] Refs #26263 -- Removed deprecated Context.has_key(). --- django/template/context.py | 10 ---------- docs/releases/2.0.txt | 2 ++ tests/template_tests/test_context.py | 25 +------------------------ 3 files changed, 3 insertions(+), 34 deletions(-) diff --git a/django/template/context.py b/django/template/context.py index 166f60fe7507..c5a4949e95e9 100644 --- a/django/template/context.py +++ b/django/template/context.py @@ -1,9 +1,6 @@ -import warnings from contextlib import contextmanager from copy import copy -from django.utils.deprecation import RemovedInDjango20Warning - # Hard-coded processor for easier use of CSRF protection. _builtin_context_processors = ('django.template.context_processors.csrf',) @@ -90,13 +87,6 @@ def __delitem__(self, key): "Delete a variable from the current context" del self.dicts[-1][key] - def has_key(self, key): - warnings.warn( - "%s.has_key() is deprecated in favor of the 'in' operator." % self.__class__.__name__, - RemovedInDjango20Warning - ) - return key in self - def __contains__(self, key): for d in self.dicts: if key in d: diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 9be5fda3cac9..c679f6ea8589 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -345,3 +345,5 @@ these features. * ``CommaSeparatedIntegerField`` is removed, except for support in historical migrations. + +* The template ``Context.has_key()`` method is removed. diff --git a/tests/template_tests/test_context.py b/tests/template_tests/test_context.py index 79f7b067941f..41e469eaabda 100644 --- a/tests/template_tests/test_context.py +++ b/tests/template_tests/test_context.py @@ -1,13 +1,10 @@ # -*- coding: utf-8 -*- -import warnings - from django.http import HttpRequest from django.template import ( Context, Engine, RequestContext, Template, Variable, VariableDoesNotExist, ) from django.template.context import RenderContext -from django.test import RequestFactory, SimpleTestCase, ignore_warnings -from django.utils.deprecation import RemovedInDjango20Warning +from django.test import RequestFactory, SimpleTestCase class ContextTests(SimpleTestCase): @@ -184,26 +181,6 @@ def test_copy_request_context_twice(self): """ RequestContext(HttpRequest()).new().new() - @ignore_warnings(category=RemovedInDjango20Warning) - def test_has_key(self): - a = Context({'a': 1}) - b = RequestContext(HttpRequest(), {'a': 1}) - msg = "Context.has_key() is deprecated in favor of the 'in' operator." - msg2 = "RequestContext.has_key() is deprecated in favor of the 'in' operator." - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') - self.assertIs(a.has_key('a'), True) - self.assertIs(a.has_key('b'), False) - self.assertIs(b.has_key('a'), True) - self.assertIs(b.has_key('b'), False) - - self.assertEqual(len(warns), 4) - self.assertEqual(str(warns[0].message), msg) - self.assertEqual(str(warns[1].message), msg) - self.assertEqual(str(warns[2].message), msg2) - self.assertEqual(str(warns[3].message), msg2) - def test_set_upward(self): c = Context({'a': 1}) c.set_upward('a', 2) From 2d7fb779870583f8c6ee003f81bf67c4d7c21227 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 11:11:04 -0500 Subject: [PATCH 0037/3180] Refs #23832 -- Removed deprecated non-timezone aware Storage API. --- django/core/files/storage.py | 112 +---------------------------------- docs/ref/files/storage.txt | 33 ----------- docs/releases/2.0.txt | 3 + tests/file_storage/tests.py | 69 +-------------------- 4 files changed, 7 insertions(+), 210 deletions(-) diff --git a/django/core/files/storage.py b/django/core/files/storage.py index 98c89ddcfa96..9cd4196c23a8 100644 --- a/django/core/files/storage.py +++ b/django/core/files/storage.py @@ -1,6 +1,5 @@ import errno import os -import warnings from datetime import datetime from django.conf import settings @@ -12,7 +11,6 @@ from django.utils._os import abspathu, safe_join from django.utils.crypto import get_random_string from django.utils.deconstruct import deconstructible -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import filepath_to_uri, force_text from django.utils.functional import LazyObject, cached_property from django.utils.module_loading import import_string @@ -146,103 +144,26 @@ def url(self, name): """ raise NotImplementedError('subclasses of Storage must provide a url() method') - def accessed_time(self, name): - """ - Returns the last accessed time (as datetime object) of the file - specified by name. Deprecated: use get_accessed_time() instead. - """ - warnings.warn( - 'Storage.accessed_time() is deprecated in favor of get_accessed_time().', - RemovedInDjango20Warning, - stacklevel=2, - ) - raise NotImplementedError('subclasses of Storage must provide an accessed_time() method') - - def created_time(self, name): - """ - Returns the creation time (as datetime object) of the file - specified by name. Deprecated: use get_created_time() instead. - """ - warnings.warn( - 'Storage.created_time() is deprecated in favor of get_created_time().', - RemovedInDjango20Warning, - stacklevel=2, - ) - raise NotImplementedError('subclasses of Storage must provide a created_time() method') - - def modified_time(self, name): - """ - Returns the last modified time (as datetime object) of the file - specified by name. Deprecated: use get_modified_time() instead. - """ - warnings.warn( - 'Storage.modified_time() is deprecated in favor of get_modified_time().', - RemovedInDjango20Warning, - stacklevel=2, - ) - raise NotImplementedError('subclasses of Storage must provide a modified_time() method') - def get_accessed_time(self, name): """ Return the last accessed time (as a datetime) of the file specified by name. The datetime will be timezone-aware if USE_TZ=True. """ - # At the end of the deprecation: - # raise NotImplementedError('subclasses of Storage must provide a get_accessed_time() method') - warnings.warn( - 'Storage.accessed_time() is deprecated. ' - 'Storage backends should implement get_accessed_time().', - RemovedInDjango20Warning, - stacklevel=2, - ) - dt = self.accessed_time(name) - return _possibly_make_aware(dt) + raise NotImplementedError('subclasses of Storage must provide a get_accessed_time() method') def get_created_time(self, name): """ Return the creation time (as a datetime) of the file specified by name. The datetime will be timezone-aware if USE_TZ=True. """ - # At the end of the deprecation: - # raise NotImplementedError('subclasses of Storage must provide a get_created_time() method') - warnings.warn( - 'Storage.created_time() is deprecated. ' - 'Storage backends should implement get_created_time().', - RemovedInDjango20Warning, - stacklevel=2, - ) - dt = self.created_time(name) - return _possibly_make_aware(dt) + raise NotImplementedError('subclasses of Storage must provide a get_created_time() method') def get_modified_time(self, name): """ Return the last modified time (as a datetime) of the file specified by name. The datetime will be timezone-aware if USE_TZ=True. """ - # At the end of the deprecation: - # raise NotImplementedError('subclasses of Storage must provide a get_modified_time() method') - warnings.warn( - 'Storage.modified_time() is deprecated. ' - 'Storage backends should implement get_modified_time().', - RemovedInDjango20Warning, - stacklevel=2, - ) - dt = self.modified_time(name) - return _possibly_make_aware(dt) - - -def _possibly_make_aware(dt): - """ - Convert a datetime object in the local timezone to aware - in UTC, if USE_TZ is True. - """ - # This function is only needed to help with the deprecations above and can - # be removed in Django 2.0, RemovedInDjango20Warning. - if settings.USE_TZ: - tz = timezone.get_default_timezone() - return timezone.make_aware(dt, tz).astimezone(timezone.utc) - else: - return dt + raise NotImplementedError('subclasses of Storage must provide a get_modified_time() method') @deconstructible @@ -415,33 +336,6 @@ def url(self, name): url = url.lstrip('/') return urljoin(self.base_url, url) - def accessed_time(self, name): - warnings.warn( - 'FileSystemStorage.accessed_time() is deprecated in favor of ' - 'get_accessed_time().', - RemovedInDjango20Warning, - stacklevel=2, - ) - return datetime.fromtimestamp(os.path.getatime(self.path(name))) - - def created_time(self, name): - warnings.warn( - 'FileSystemStorage.created_time() is deprecated in favor of ' - 'get_created_time().', - RemovedInDjango20Warning, - stacklevel=2, - ) - return datetime.fromtimestamp(os.path.getctime(self.path(name))) - - def modified_time(self, name): - warnings.warn( - 'FileSystemStorage.modified_time() is deprecated in favor of ' - 'get_modified_time().', - RemovedInDjango20Warning, - stacklevel=2, - ) - return datetime.fromtimestamp(os.path.getmtime(self.path(name))) - def _datetime_from_timestamp(self, ts): """ If timezone support is enabled, make an aware datetime object in UTC; diff --git a/docs/ref/files/storage.txt b/docs/ref/files/storage.txt index 0e8303c7af44..61bf3c395146 100644 --- a/docs/ref/files/storage.txt +++ b/docs/ref/files/storage.txt @@ -77,28 +77,6 @@ The ``Storage`` class used will be the current value of ``os.environ['TZ']``; note that this is usually set from Django's :setting:`TIME_ZONE`. - .. method:: accessed_time(name) - - Returns a naive ``datetime`` object containing the last - accessed time of the file. For storage systems that aren't - able to return the last accessed time this will raise - ``NotImplementedError`` instead. - - .. deprecated:: 1.10 - - Use :meth:`get_accessed_time` instead. - - .. method:: created_time(name) - - Returns a naive ``datetime`` object containing the creation - time of the file. For storage systems that aren't able to - return the creation time this will raise - ``NotImplementedError`` instead. - - .. deprecated:: 1.10 - - Use :meth:`get_created_time` instead. - .. method:: delete(name) Deletes the file referenced by ``name``. If deletion is not supported @@ -186,17 +164,6 @@ The ``Storage`` class storage systems that aren't able to provide such a listing, this will raise a ``NotImplementedError`` instead. - .. method:: modified_time(name) - - Returns a naive ``datetime`` object containing the last - modified time. For storage systems that aren't able to return - the last modified time, this will raise - ``NotImplementedError`` instead. - - .. deprecated:: 1.10 - - Use :meth:`get_modified_time` instead. - .. method:: open(name, mode='rb') Opens the file given by ``name``. Note that although the returned file diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index c679f6ea8589..3bc2199a39b0 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -347,3 +347,6 @@ these features. migrations. * The template ``Context.has_key()`` method is removed. + +* Support for the ``django.core.files.storage.Storage.accessed_time()``, + ``created_time()``, and ``modified_time()`` methods is removed. diff --git a/tests/file_storage/tests.py b/tests/file_storage/tests.py index 3ac648362366..7a8b104665e6 100644 --- a/tests/file_storage/tests.py +++ b/tests/file_storage/tests.py @@ -20,14 +20,12 @@ ) from django.db.models.fields.files import FileDescriptor from django.test import ( - LiveServerTestCase, SimpleTestCase, TestCase, ignore_warnings, - override_settings, + LiveServerTestCase, SimpleTestCase, TestCase, override_settings, ) from django.test.utils import requires_tz_support from django.urls import NoReverseMatch, reverse_lazy from django.utils import six, timezone from django.utils._os import upath -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.six.moves.urllib.request import urlopen from .models import Storage, temp_storage, temp_storage_location @@ -227,21 +225,6 @@ def test_file_get_accessed_time(self): def test_file_get_accessed_time_timezone(self): self._test_file_time_getter(self.storage.get_accessed_time) - @ignore_warnings(category=RemovedInDjango20Warning) - def test_file_accessed_time(self): - """ - File storage returns a datetime for the last accessed time of a file. - """ - self.assertFalse(self.storage.exists('test.file')) - - f = ContentFile('custom contents') - f_name = self.storage.save('test.file', f) - self.addCleanup(self.storage.delete, f_name) - atime = self.storage.accessed_time(f_name) - - self.assertEqual(atime, datetime.fromtimestamp(os.path.getatime(self.storage.path(f_name)))) - self.assertLess(datetime.now() - self.storage.accessed_time(f_name), timedelta(seconds=2)) - def test_file_get_created_time(self): """ File storage returns a datetime for the creation time of a file. @@ -260,21 +243,6 @@ def test_file_get_created_time(self): def test_file_get_created_time_timezone(self): self._test_file_time_getter(self.storage.get_created_time) - @ignore_warnings(category=RemovedInDjango20Warning) - def test_file_created_time(self): - """ - File storage returns a datetime for the creation time of a file. - """ - self.assertFalse(self.storage.exists('test.file')) - - f = ContentFile('custom contents') - f_name = self.storage.save('test.file', f) - ctime = self.storage.created_time(f_name) - self.addCleanup(self.storage.delete, f_name) - - self.assertEqual(ctime, datetime.fromtimestamp(os.path.getctime(self.storage.path(f_name)))) - self.assertLess(datetime.now() - self.storage.created_time(f_name), timedelta(seconds=2)) - def test_file_get_modified_time(self): """ File storage returns a datetime for the last modified time of a file. @@ -293,21 +261,6 @@ def test_file_get_modified_time(self): def test_file_get_modified_time_timezone(self): self._test_file_time_getter(self.storage.get_modified_time) - @ignore_warnings(category=RemovedInDjango20Warning) - def test_file_modified_time(self): - """ - File storage returns a datetime for the last modified time of a file. - """ - self.assertFalse(self.storage.exists('test.file')) - - f = ContentFile('custom contents') - f_name = self.storage.save('test.file', f) - self.addCleanup(self.storage.delete, f_name) - mtime = self.storage.modified_time(f_name) - - self.assertEqual(mtime, datetime.fromtimestamp(os.path.getmtime(self.storage.path(f_name)))) - self.assertLess(datetime.now() - self.storage.modified_time(f_name), timedelta(seconds=2)) - def test_file_save_without_name(self): """ File storage extracts the filename from the content object if no @@ -613,26 +566,6 @@ def test_custom_get_available_name(self): self.storage.delete(second) -class CustomStorageLegacyDatetimeHandling(FileSystemStorage): - # Use the legacy accessed_time() et al from FileSystemStorage and the - # shim get_accessed_time() et al from the Storage baseclass. Both of those - # raise warnings, so the testcase class ignores them all. - - def get_accessed_time(self, name): - return super(FileSystemStorage, self).get_accessed_time(name) - - def get_created_time(self, name): - return super(FileSystemStorage, self).get_created_time(name) - - def get_modified_time(self, name): - return super(FileSystemStorage, self).get_modified_time(name) - - -@ignore_warnings(category=RemovedInDjango20Warning) -class CustomStorageLegacyDatetimeHandlingTests(FileStorageTests): - storage_class = CustomStorageLegacyDatetimeHandling - - class DiscardingFalseContentStorage(FileSystemStorage): def _save(self, name, content): if content: From bfe0d54514bf4f03bc4a956452541f0103134ba3 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 11:24:40 -0500 Subject: [PATCH 0038/3180] Refs #26230 -- Removed support for model name query lookups when using Meta.default_related_name. Per deprecation timeline. --- django/db/models/sql/query.py | 15 ------------ docs/ref/models/options.txt | 24 ------------------- docs/releases/2.0.txt | 3 +++ .../test_default_related_name.py | 15 ++++-------- 4 files changed, 7 insertions(+), 50 deletions(-) diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 5f657863737b..57ba7dfc8d38 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -7,7 +7,6 @@ all about the internals of models in order to get the information it needs. """ import copy -import warnings from collections import Counter, Iterator, Mapping, OrderedDict from itertools import chain, count, product from string import ascii_uppercase @@ -32,7 +31,6 @@ AND, OR, ExtraWhere, NothingNode, WhereNode, ) from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.utils.tree import Node @@ -1320,19 +1318,6 @@ def names_to_path(self, names, opts, allow_many=True, fail_on_missing=False): except FieldDoesNotExist: if name in self.annotation_select: field = self.annotation_select[name].output_field - elif pos == 0: - for rel in opts.related_objects: - if (name == rel.related_model._meta.model_name and - rel.related_name == rel.related_model._meta.default_related_name): - related_name = rel.related_name - field = opts.get_field(related_name) - warnings.warn( - "Query lookup '%s' is deprecated in favor of " - "Meta.default_related_name '%s'." - % (name, related_name), - RemovedInDjango20Warning, 2 - ) - break if field is not None: # Fields that contain one-to-many relations with a generic diff --git a/docs/ref/models/options.txt b/docs/ref/models/options.txt index 5d385adf24fa..23ea0c673e94 100644 --- a/docs/ref/models/options.txt +++ b/docs/ref/models/options.txt @@ -130,30 +130,6 @@ Django quotes column and table names behind the scenes. and the name of the model, both lowercased. See the paragraph on :ref:`related names for abstract models `. - .. deprecated:: 1.10 - - This attribute now affects ``related_query_name``. The old query lookup - name is deprecated:: - - from django.db import models - - class Foo(models.Model): - pass - - class Bar(models.Model): - foo = models.ForeignKey(Foo) - - class Meta: - default_related_name = 'bars' - - :: - - >>> bar = Bar.objects.get(pk=1) - >>> # Using model name "bar" as lookup string is deprecated. - >>> Foo.objects.get(bar=bar) - >>> # You should use default_related_name "bars". - >>> Foo.objects.get(bars=bar) - ``get_latest_by`` ----------------- diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 3bc2199a39b0..5734fdd5b245 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -350,3 +350,6 @@ these features. * Support for the ``django.core.files.storage.Storage.accessed_time()``, ``created_time()``, and ``modified_time()`` methods is removed. + +* Support for query lookups using the model name when + ``Meta.default_related_name`` is set is removed. diff --git a/tests/model_options/test_default_related_name.py b/tests/model_options/test_default_related_name.py index 695a3b856ba6..a6b7533e1d62 100644 --- a/tests/model_options/test_default_related_name.py +++ b/tests/model_options/test_default_related_name.py @@ -1,7 +1,5 @@ -import warnings - +from django.core.exceptions import FieldError from django.test import TestCase -from django.utils.deprecation import RemovedInDjango20Warning from .models.default_related_name import Author, Book, Editor @@ -24,15 +22,10 @@ def test_default_related_name(self): def test_default_related_name_in_queryset_lookup(self): self.assertEqual(Author.objects.get(books=self.book), self.author) - def test_show_deprecated_message_when_model_name_in_queryset_lookup(self): - msg = "Query lookup 'book' is deprecated in favor of Meta.default_related_name 'books'." - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('once') + def test_model_name_not_available_in_queryset_lookup(self): + msg = "Cannot resolve keyword 'book' into field." + with self.assertRaisesMessage(FieldError, msg): Author.objects.get(book=self.book) - self.assertEqual(len(warns), 1) - warning = warns.pop() - self.assertEqual(warning.category, RemovedInDjango20Warning) - self.assertEqual(str(warning.message), msg) def test_related_name_overrides_default_related_name(self): self.assertEqual(list(self.editor.edited_books.all()), [self.book]) From 5139832398624be75ee5361a6fac9348fdb61093 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 11:32:50 -0500 Subject: [PATCH 0039/3180] Refs #26285 -- Removed MySQL __search lookup per deprecation timeline. --- django/db/backends/base/operations.py | 9 -------- django/db/backends/mysql/operations.py | 4 ---- django/db/models/lookups.py | 18 --------------- docs/ref/models/querysets.txt | 27 ---------------------- docs/releases/2.0.txt | 2 ++ tests/lookup/models.py | 13 ----------- tests/lookup/tests.py | 32 ++------------------------ 7 files changed, 4 insertions(+), 101 deletions(-) diff --git a/django/db/backends/base/operations.py b/django/db/backends/base/operations.py index f46ac955badd..0539d7153907 100644 --- a/django/db/backends/base/operations.py +++ b/django/db/backends/base/operations.py @@ -191,15 +191,6 @@ def for_update_sql(self, nowait=False, skip_locked=False): else: return 'FOR UPDATE' - def fulltext_search_sql(self, field_name): - """ - Returns the SQL WHERE clause to use in order to perform a full-text - search of the given field_name. Note that the resulting string should - contain a '%s' placeholder for the value being searched against. - """ - # RemovedInDjango20Warning - raise NotImplementedError('Full-text search is not implemented for this database backend') - def last_executed_query(self, cursor, sql, params): """ Returns a string of the query last executed by the given cursor, with diff --git a/django/db/backends/mysql/operations.py b/django/db/backends/mysql/operations.py index 43c39441c250..6a55d7a88f75 100644 --- a/django/db/backends/mysql/operations.py +++ b/django/db/backends/mysql/operations.py @@ -110,10 +110,6 @@ def force_no_ordering(self): """ return [(None, ("NULL", [], False))] - def fulltext_search_sql(self, field_name): - # RemovedInDjango20Warning - return 'MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)' % field_name - def last_executed_query(self, cursor, sql, params): # With MySQLdb, cursor objects have an (undocumented) "_last_executed" # attribute where the exact query sent to the database is saved. diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py index 8f7db0723cae..b8093ddc3469 100644 --- a/django/db/models/lookups.py +++ b/django/db/models/lookups.py @@ -1,6 +1,5 @@ import itertools import math -import warnings from copy import copy from decimal import Decimal @@ -10,7 +9,6 @@ DateTimeField, DecimalField, Field, IntegerField, ) from django.db.models.query_utils import RegisterLookupMixin -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.functional import cached_property from django.utils.six.moves import range @@ -509,22 +507,6 @@ def as_sql(self, compiler, connection): return "%s IS NOT NULL" % sql, params -@Field.register_lookup -class Search(BuiltinLookup): - lookup_name = 'search' - prepare_rhs = False - - def as_sql(self, compiler, connection): - warnings.warn( - 'The `__search` lookup is deprecated. See the 1.10 release notes ' - 'for how to replace it.', RemovedInDjango20Warning, stacklevel=2 - ) - lhs, lhs_params = self.process_lhs(compiler, connection) - rhs, rhs_params = self.process_rhs(compiler, connection) - sql_template = connection.ops.fulltext_search_sql(field_name=lhs) - return sql_template, lhs_params + rhs_params - - @Field.register_lookup class Regex(BuiltinLookup): lookup_name = 'regex' diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index ee48a3c6f0b1..ec71fe0294cf 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -2918,33 +2918,6 @@ SQL equivalent:: SELECT ... WHERE pub_date IS NULL; -.. fieldlookup:: search - -``search`` -~~~~~~~~~~ - -.. deprecated:: 1.10 - - See :ref:`the 1.10 release notes ` for how to - replace it. - -A boolean full-text search, taking advantage of full-text indexing. This is -like :lookup:`contains` but is significantly faster due to full-text indexing. - -Example:: - - Entry.objects.filter(headline__search="+Django -jazz Python") - -SQL equivalent:: - - SELECT ... WHERE MATCH(tablename, headline) AGAINST (+Django -jazz Python IN BOOLEAN MODE); - -Note this is only available in MySQL and requires direct manipulation of the -database to add the full-text index. By default Django uses BOOLEAN MODE for -full text searches. See the `MySQL documentation`_ for additional details. - -.. _MySQL documentation: https://dev.mysql.com/doc/refman/en/fulltext-boolean.html - .. fieldlookup:: regex ``regex`` diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 5734fdd5b245..f0f5ff656615 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -353,3 +353,5 @@ these features. * Support for query lookups using the model name when ``Meta.default_related_name`` is set is removed. + +* The MySQL ``__search`` lookup is removed. diff --git a/tests/lookup/models.py b/tests/lookup/models.py index e8479f11d165..cfc0cecb9953 100644 --- a/tests/lookup/models.py +++ b/tests/lookup/models.py @@ -75,19 +75,6 @@ def __str__(self): return self.name -# To test __search lookup a fulltext index is needed. This -# is only available when using MySQL 5.6, or when using MyISAM -# tables. As 5.6 isn't common yet, lets use MyISAM table for -# testing. The table is manually created by the test method. -# RemovedInDjango20Warning -class MyISAMArticle(models.Model): - headline = models.CharField(max_length=100) - - class Meta: - db_table = 'myisam_article' - managed = False - - class Product(models.Model): name = models.CharField(max_length=80) qty_target = models.DecimalField(max_digits=6, decimal_places=2) diff --git a/tests/lookup/tests.py b/tests/lookup/tests.py index 1c8dd986fc7c..78e68dfc4a99 100644 --- a/tests/lookup/tests.py +++ b/tests/lookup/tests.py @@ -3,16 +3,11 @@ import collections from datetime import datetime from operator import attrgetter -from unittest import skipUnless from django.core.exceptions import FieldError -from django.db import connection -from django.test import ( - TestCase, TransactionTestCase, ignore_warnings, skipUnlessDBFeature, -) -from django.utils.deprecation import RemovedInDjango20Warning +from django.test import TestCase, skipUnlessDBFeature -from .models import Article, Author, Game, MyISAMArticle, Player, Season, Tag +from .models import Article, Author, Game, Player, Season, Tag class LookupTests(TestCase): @@ -775,26 +770,3 @@ def test_chain_date_time_lookups(self): ''], ordered=False ) - - -class LookupTransactionTests(TransactionTestCase): - available_apps = ['lookup'] - - @ignore_warnings(category=RemovedInDjango20Warning) - @skipUnless(connection.vendor == 'mysql', 'requires MySQL') - def test_mysql_lookup_search(self): - # To use fulltext indexes on MySQL either version 5.6 is needed, or one must use - # MyISAM tables. Neither of these combinations is currently available on CI, so - # lets manually create a MyISAM table for Article model. - with connection.cursor() as cursor: - cursor.execute( - "CREATE TEMPORARY TABLE myisam_article (" - " id INTEGER PRIMARY KEY AUTO_INCREMENT, " - " headline VARCHAR(100) NOT NULL " - ") ENGINE MYISAM") - dr = MyISAMArticle.objects.create(headline='Django Reinhardt') - MyISAMArticle.objects.create(headline='Ringo Star') - # NOTE: Needs to be created after the article has been saved. - cursor.execute( - 'CREATE FULLTEXT INDEX myisam_article_ft ON myisam_article (headline)') - self.assertSequenceEqual(MyISAMArticle.objects.filter(headline__search='Reinhardt'), [dr]) From b70094f0408384993e149ffcfc86cc2d405308d1 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 11:36:43 -0500 Subject: [PATCH 0040/3180] Refs #26226 -- Removed support for related manager classes without a _apply_rel_filters() method. Per deprecation timeline. --- django/db/models/query.py | 15 +-------------- docs/releases/2.0.txt | 3 +++ tests/prefetch_related/tests.py | 26 -------------------------- 3 files changed, 4 insertions(+), 40 deletions(-) diff --git a/django/db/models/query.py b/django/db/models/query.py index f9534f370019..2dbe3b746147 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -22,7 +22,6 @@ from django.db.models.query_utils import InvalidQuery, Q from django.db.models.sql.constants import CURSOR from django.utils import six, timezone -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.functional import cached_property, partition from django.utils.version import get_version @@ -1613,19 +1612,7 @@ def prefetch_one_level(instances, prefetcher, lookup, level): else: manager = getattr(obj, to_attr) if leaf and lookup.queryset is not None: - try: - apply_rel_filter = manager._apply_rel_filters - except AttributeError: - warnings.warn( - "The `%s.%s` class must implement a `_apply_rel_filters()` " - "method that accepts a `QuerySet` as its single " - "argument and returns an appropriately filtered version " - "of it." % (manager.__class__.__module__, manager.__class__.__name__), - RemovedInDjango20Warning, - ) - qs = manager.get_queryset() - else: - qs = apply_rel_filter(lookup.queryset) + qs = manager._apply_rel_filters(lookup.queryset) else: qs = manager.get_queryset() qs._result_cache = vals diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index f0f5ff656615..575197230889 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -355,3 +355,6 @@ these features. ``Meta.default_related_name`` is set is removed. * The MySQL ``__search`` lookup is removed. + +* The shim for supporting custom related manager classes without a + ``_apply_rel_filters()`` method is removed. diff --git a/tests/prefetch_related/tests.py b/tests/prefetch_related/tests.py index 7ddf4a4c966a..a6b5fd5cd302 100644 --- a/tests/prefetch_related/tests.py +++ b/tests/prefetch_related/tests.py @@ -1,7 +1,5 @@ from __future__ import unicode_literals -import warnings - from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist from django.db import connection @@ -711,30 +709,6 @@ def test_nested_prefetch_related_are_not_overwritten(self): self.room2_1 ) - def test_apply_rel_filters_deprecation_shim(self): - # Simulate a missing `_apply_rel_filters` method. - del Person.houses.related_manager_cls._apply_rel_filters - # Also remove `get_queryset` as it rely on `_apply_rel_filters`. - del Person.houses.related_manager_cls.get_queryset - try: - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') - list(Person.objects.prefetch_related( - Prefetch('houses', queryset=House.objects.filter(name='House 1')) - )) - finally: - # Deleting `related_manager_cls` will force the creation of a new - # class since it's a `cached_property`. - del Person.houses.related_manager_cls - msg = ( - 'The `django.db.models.fields.related_descriptors.ManyRelatedManager` class ' - 'must implement a `_apply_rel_filters()` method that accepts a `QuerySet` as ' - 'its single argument and returns an appropriately filtered version of it.' - ) - self.assertEqual(len(warns), 2) # Once person. - self.assertEqual(str(warns[0].message), msg) - self.assertEqual(str(warns[0].message), msg) - def test_values_queryset(self): with self.assertRaisesMessage(ValueError, 'Prefetch querysets cannot use values().'): Prefetch('houses', House.objects.values('pk')) From eba093e8b02989af1857b1915907ca0897f565ff Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 11:46:40 -0500 Subject: [PATCH 0041/3180] Refs #25847 -- Removed support for User.is_(anonymous|authenticated) as methods. Per deprecation timeline. --- django/contrib/auth/base_user.py | 5 ++-- django/contrib/auth/models.py | 5 ++-- django/utils/deprecation.py | 43 --------------------------- docs/ref/contrib/auth.txt | 10 ------- docs/releases/2.0.txt | 3 ++ docs/topics/auth/customizing.txt | 10 ------- tests/auth_tests/test_basic.py | 42 -------------------------- tests/utils_tests/test_deprecation.py | 31 ------------------- 8 files changed, 7 insertions(+), 142 deletions(-) delete mode 100644 tests/utils_tests/test_deprecation.py diff --git a/django/contrib/auth/base_user.py b/django/contrib/auth/base_user.py index 9ad5cde87fa8..104748ff69b5 100644 --- a/django/contrib/auth/base_user.py +++ b/django/contrib/auth/base_user.py @@ -12,7 +12,6 @@ ) from django.db import models from django.utils.crypto import get_random_string, salted_hmac -from django.utils.deprecation import CallableFalse, CallableTrue from django.utils.encoding import force_text, python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ @@ -91,7 +90,7 @@ def is_anonymous(self): Always return False. This is a way of comparing User objects to anonymous users. """ - return CallableFalse + return False @property def is_authenticated(self): @@ -99,7 +98,7 @@ def is_authenticated(self): Always return True. This is a way to tell if the user has been authenticated in templates. """ - return CallableTrue + return True def set_password(self, raw_password): self.password = make_password(raw_password) diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index 60555269416f..d91412eb5c11 100644 --- a/django/contrib/auth/models.py +++ b/django/contrib/auth/models.py @@ -9,7 +9,6 @@ from django.db import models from django.db.models.manager import EmptyManager from django.utils import six, timezone -from django.utils.deprecation import CallableFalse, CallableTrue from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ @@ -443,11 +442,11 @@ def has_module_perms(self, module): @property def is_anonymous(self): - return CallableTrue + return True @property def is_authenticated(self): - return CallableFalse + return False def get_username(self): return self.username diff --git a/django/utils/deprecation.py b/django/utils/deprecation.py index 2963e60214c2..b862a161b2c8 100644 --- a/django/utils/deprecation.py +++ b/django/utils/deprecation.py @@ -84,49 +84,6 @@ def __instancecheck__(self, instance): return super(DeprecationInstanceCheck, self).__instancecheck__(instance) -class CallableBool: - """ - An boolean-like object that is also callable for backwards compatibility. - """ - do_not_call_in_templates = True - - def __init__(self, value): - self.value = value - - def __bool__(self): - return self.value - - def __call__(self): - warnings.warn( - "Using user.is_authenticated() and user.is_anonymous() as a method " - "is deprecated. Remove the parentheses to use it as an attribute.", - RemovedInDjango20Warning, stacklevel=2 - ) - return self.value - - def __nonzero__(self): # Python 2 compatibility - return self.value - - def __repr__(self): - return 'CallableBool(%r)' % self.value - - def __eq__(self, other): - return self.value == other - - def __ne__(self, other): - return self.value != other - - def __or__(self, other): - return bool(self.value or other) - - def __hash__(self): - return hash(self.value) - - -CallableFalse = CallableBool(False) -CallableTrue = CallableBool(True) - - class MiddlewareMixin(object): def __init__(self, get_response=None): self.get_response = get_response diff --git a/docs/ref/contrib/auth.txt b/docs/ref/contrib/auth.txt index 6395949e3ea0..87dd58005121 100644 --- a/docs/ref/contrib/auth.txt +++ b/docs/ref/contrib/auth.txt @@ -137,11 +137,6 @@ Attributes (representing the currently logged-in user), you should know this attribute is ``True`` for any :class:`~models.User` instance. - .. versionchanged:: 1.10 - - In older versions, this was a method. Backwards-compatibility - support for using it as a method will be removed in Django 2.0. - .. attribute:: is_anonymous Read-only attribute which is always ``False``. This is a way of @@ -150,11 +145,6 @@ Attributes :attr:`~django.contrib.auth.models.User.is_authenticated` to this attribute. - .. versionchanged:: 1.10 - - In older versions, this was a method. Backwards-compatibility - support for using it as a method will be removed in Django 2.0. - .. attribute:: username_validator .. versionadded:: 1.10 diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 575197230889..f02520cb9e79 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -358,3 +358,6 @@ these features. * The shim for supporting custom related manager classes without a ``_apply_rel_filters()`` method is removed. + +* Using ``User.is_authenticated()`` and ``User.is_anonymous()`` as methods + rather than properties is no longer be supported. diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt index ff84fad19f70..40675d2ef6ed 100644 --- a/docs/topics/auth/customizing.txt +++ b/docs/topics/auth/customizing.txt @@ -695,11 +695,6 @@ The following attributes and methods are available on any subclass of (representing the currently logged-in user), you should know this attribute is ``True`` for any :class:`~models.User` instance. - .. versionchanged:: 1.10 - - In older versions, this was a method. Backwards-compatibility - support for using it as a method will be removed in Django 2.0. - .. attribute:: models.AbstractBaseUser.is_anonymous Read-only attribute which is always ``False``. This is a way of @@ -707,11 +702,6 @@ The following attributes and methods are available on any subclass of objects. Generally, you should prefer using :attr:`~models.User.is_authenticated` to this attribute. - .. versionchanged:: 1.10 - - In older versions, this was a method. Backwards-compatibility - support for using it as a method will be removed in Django 2.0. - .. method:: models.AbstractBaseUser.set_password(raw_password) Sets the user's password to the given raw string, taking care of the diff --git a/tests/auth_tests/test_basic.py b/tests/auth_tests/test_basic.py index 2e18260e4c9b..4555e282705d 100644 --- a/tests/auth_tests/test_basic.py +++ b/tests/auth_tests/test_basic.py @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -import warnings - from django.contrib.auth import get_user, get_user_model from django.contrib.auth.models import AnonymousUser, User from django.core.exceptions import ImproperlyConfigured @@ -56,26 +54,6 @@ def test_unicode_username(self): with self.assertRaises(IntegrityError): User.objects.create_user(omega_username) - def test_is_anonymous_authenticated_method_deprecation(self): - deprecation_message = ( - 'Using user.is_authenticated() and user.is_anonymous() as a ' - 'method is deprecated. Remove the parentheses to use it as an ' - 'attribute.' - ) - u = User.objects.create_user('testuser', 'test@example.com', 'testpw') - # Backwards-compatibility callables - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') - self.assertFalse(u.is_anonymous()) - self.assertEqual(len(warns), 1) - self.assertEqual(str(warns[0].message), deprecation_message) - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') - self.assertTrue(u.is_authenticated()) - self.assertEqual(len(warns), 1) - self.assertEqual(str(warns[0].message), deprecation_message) - def test_user_no_email(self): "Users can be created without an email" u = User.objects.create_user('testuser1') @@ -101,26 +79,6 @@ def test_anonymous_user(self): self.assertEqual(a.groups.all().count(), 0) self.assertEqual(a.user_permissions.all().count(), 0) - def test_anonymous_user_is_anonymous_authenticated_method_deprecation(self): - a = AnonymousUser() - deprecation_message = ( - 'Using user.is_authenticated() and user.is_anonymous() as a ' - 'method is deprecated. Remove the parentheses to use it as an ' - 'attribute.' - ) - # Backwards-compatibility callables - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') # prevent warnings from appearing as errors - self.assertTrue(a.is_anonymous()) - self.assertEqual(len(warns), 1) - self.assertEqual(str(warns[0].message), deprecation_message) - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') # prevent warnings from appearing as errors - self.assertFalse(a.is_authenticated()) - self.assertEqual(len(warns), 1) - self.assertEqual(str(warns[0].message), deprecation_message) - def test_superuser(self): "Check the creation and properties of a superuser" super = User.objects.create_superuser('super', 'super@example.com', 'super') diff --git a/tests/utils_tests/test_deprecation.py b/tests/utils_tests/test_deprecation.py deleted file mode 100644 index 56ba259a2f75..000000000000 --- a/tests/utils_tests/test_deprecation.py +++ /dev/null @@ -1,31 +0,0 @@ -from django.test import SimpleTestCase -from django.utils.deprecation import CallableFalse, CallableTrue - - -class TestCallableBool(SimpleTestCase): - def test_true(self): - self.assertTrue(CallableTrue) - self.assertEqual(CallableTrue, True) - self.assertFalse(CallableTrue != True) # noqa: E712 - self.assertNotEqual(CallableTrue, False) - - def test_false(self): - self.assertFalse(CallableFalse) - self.assertEqual(CallableFalse, False) - self.assertFalse(CallableFalse != False) # noqa: E712 - self.assertNotEqual(CallableFalse, True) - - def test_or(self): - self.assertIs(CallableTrue | CallableTrue, True) - self.assertIs(CallableTrue | CallableFalse, True) - self.assertIs(CallableFalse | CallableTrue, True) - self.assertIs(CallableFalse | CallableFalse, False) - - self.assertIs(CallableTrue | True, True) - self.assertIs(CallableTrue | False, True) - self.assertIs(CallableFalse | True, True) - self.assertFalse(CallableFalse | False, False) - - def test_set_membership(self): - self.assertIs(CallableTrue in {True}, True) - self.assertIs(CallableFalse not in {True}, True) From 933dc62742d2ba374fb0f03bd29022dfb60f52ec Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 11:54:49 -0500 Subject: [PATCH 0042/3180] Refs #16508 -- Removed virtual aliases of "private fields". Per deprecation timeline. --- django/db/models/fields/__init__.py | 10 +--------- django/db/models/options.py | 19 +------------------ docs/releases/2.0.txt | 5 +++++ 3 files changed, 7 insertions(+), 27 deletions(-) diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 2018797564e1..cf3aab481582 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -27,7 +27,6 @@ from django.utils.dateparse import ( parse_date, parse_datetime, parse_duration, parse_time, ) -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.duration import duration_string from django.utils.encoding import ( force_bytes, force_text, python_2_unicode_compatible, smart_text, @@ -673,7 +672,7 @@ def set_attributes_from_name(self, name): if self.verbose_name is None and self.name: self.verbose_name = self.name.replace('_', ' ') - def contribute_to_class(self, cls, name, private_only=False, virtual_only=NOT_PROVIDED): + def contribute_to_class(self, cls, name, private_only=False): """ Register the field with the model class it belongs to. @@ -681,13 +680,6 @@ def contribute_to_class(self, cls, name, private_only=False, virtual_only=NOT_PR created for every subclass of cls, even if cls is not an abstract model. """ - if virtual_only is not NOT_PROVIDED: - warnings.warn( - "The `virtual_only` argument of Field.contribute_to_class() " - "has been renamed to `private_only`.", - RemovedInDjango20Warning, stacklevel=2 - ) - private_only = virtual_only self.set_attributes_from_name(name) self.model = cls if private_only: diff --git a/django/db/models/options.py b/django/db/models/options.py index 335289beea94..c4652870e0b1 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -19,15 +19,12 @@ from django.utils.datastructures import ImmutableList, OrderedSet from django.utils.deprecation import ( RemovedInDjango20Warning, RemovedInDjango21Warning, - warn_about_renamed_method, ) from django.utils.encoding import force_text, python_2_unicode_compatible from django.utils.functional import cached_property from django.utils.text import camel_case_to_spaces, format_lazy from django.utils.translation import override -NOT_PROVIDED = object() - PROXY_PARENTS = object() EMPTY_RELATION_TREE = tuple() @@ -259,13 +256,7 @@ def add_manager(self, manager): self.local_managers.append(manager) self._expire_cache() - def add_field(self, field, private=False, virtual=NOT_PROVIDED): - if virtual is not NOT_PROVIDED: - warnings.warn( - "The `virtual` argument of Options.add_field() has been renamed to `private`.", - RemovedInDjango20Warning, stacklevel=2 - ) - private = virtual + def add_field(self, field, private=False): # Insert the given field in the order in which it was created, using # the "creation_counter" attribute of the field. # Move many-to-many related fields from self.fields into @@ -516,14 +507,6 @@ def concrete_fields(self): "concrete_fields", (f for f in self.fields if f.concrete) ) - @property - @warn_about_renamed_method( - 'Options', 'virtual_fields', 'private_fields', - RemovedInDjango20Warning - ) - def virtual_fields(self): - return self.private_fields - @cached_property def local_concrete_fields(self): """ diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index f02520cb9e79..385b25b28de6 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -361,3 +361,8 @@ these features. * Using ``User.is_authenticated()`` and ``User.is_anonymous()`` as methods rather than properties is no longer be supported. + +* The ``Model._meta.virtual_fields`` attribute is removed. + +* The keyword arguments ``virtual_only`` in ``Field.contribute_to_class()`` and + ``virtual`` in ``Model._meta.add_field()`` are removed. From 2b20e4148f4f54431834e6a43af6c39dc75e6362 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 12:10:37 -0500 Subject: [PATCH 0043/3180] Refs #19567 -- Removed deprecated javascript_catalog() and json_catalog() views. --- django/views/i18n.py | 125 +-------- docs/releases/1.9.txt | 4 +- docs/releases/2.0.txt | 2 + docs/topics/i18n/translation.txt | 133 ---------- .../view_tests/tests/test_i18n_deprecated.py | 244 ------------------ tests/view_tests/urls.py | 13 - 6 files changed, 5 insertions(+), 516 deletions(-) delete mode 100644 tests/view_tests/tests/test_i18n_deprecated.py diff --git a/django/views/i18n.py b/django/views/i18n.py index c3a813b0fe9b..ba8fce67e701 100644 --- a/django/views/i18n.py +++ b/django/views/i18n.py @@ -1,8 +1,6 @@ -import importlib import itertools import json import os -import warnings from django import http from django.apps import apps @@ -10,18 +8,15 @@ from django.template import Context, Engine from django.urls import translate_url from django.utils import six -from django.utils._os import upath -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.utils.formats import get_format from django.utils.http import is_safe_url, urlunquote from django.utils.translation import ( - LANGUAGE_SESSION_KEY, check_for_language, get_language, to_locale, + LANGUAGE_SESSION_KEY, check_for_language, get_language, ) from django.utils.translation.trans_real import DjangoTranslation from django.views.generic import View -DEFAULT_PACKAGES = ['django.conf'] LANGUAGE_QUERY_PARAMETER = 'language' @@ -210,69 +205,6 @@ def indent(s): return http.HttpResponse(template.render(context), 'text/javascript') -def get_javascript_catalog(locale, domain, packages): - app_configs = apps.get_app_configs() - allowable_packages = set(app_config.name for app_config in app_configs) - allowable_packages.update(DEFAULT_PACKAGES) - packages = [p for p in packages if p in allowable_packages] - paths = [] - # paths of requested packages - for package in packages: - p = importlib.import_module(package) - path = os.path.join(os.path.dirname(upath(p.__file__)), 'locale') - paths.append(path) - - trans = DjangoTranslation(locale, domain=domain, localedirs=paths) - trans_cat = trans._catalog - - plural = None - if '' in trans_cat: - for line in trans_cat[''].split('\n'): - if line.startswith('Plural-Forms:'): - plural = line.split(':', 1)[1].strip() - if plural is not None: - # this should actually be a compiled function of a typical plural-form: - # Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : - # n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2; - plural = [el.strip() for el in plural.split(';') if el.strip().startswith('plural=')][0].split('=', 1)[1] - - pdict = {} - maxcnts = {} - catalog = {} - trans_fallback_cat = trans._fallback._catalog if trans._fallback else {} - for key, value in itertools.chain(six.iteritems(trans_cat), six.iteritems(trans_fallback_cat)): - if key == '' or key in catalog: - continue - if isinstance(key, six.string_types): - catalog[key] = value - elif isinstance(key, tuple): - msgid = key[0] - cnt = key[1] - maxcnts[msgid] = max(cnt, maxcnts.get(msgid, 0)) - pdict.setdefault(msgid, {})[cnt] = value - else: - raise TypeError(key) - for k, v in pdict.items(): - catalog[k] = [v.get(i, '') for i in range(maxcnts[k] + 1)] - - return catalog, plural - - -def _get_locale(request): - language = request.GET.get(LANGUAGE_QUERY_PARAMETER) - if not (language and check_for_language(language)): - language = get_language() - return to_locale(language) - - -def _parse_packages(packages): - if packages is None: - packages = list(DEFAULT_PACKAGES) - elif isinstance(packages, six.string_types): - packages = packages.split('+') - return packages - - def null_javascript_catalog(request, domain=None, packages=None): """ Returns "identity" versions of the JavaScript i18n functions -- i.e., @@ -281,61 +213,6 @@ def null_javascript_catalog(request, domain=None, packages=None): return render_javascript_catalog() -def javascript_catalog(request, domain='djangojs', packages=None): - """ - Returns the selected language catalog as a javascript library. - - Receives the list of packages to check for translations in the - packages parameter either from an infodict or as a +-delimited - string from the request. Default is 'django.conf'. - - Additionally you can override the gettext domain for this view, - but usually you don't want to do that, as JavaScript messages - go to the djangojs domain. But this might be needed if you - deliver your JavaScript source from Django templates. - """ - warnings.warn( - "The javascript_catalog() view is deprecated in favor of the " - "JavaScriptCatalog view.", RemovedInDjango20Warning, stacklevel=2 - ) - locale = _get_locale(request) - packages = _parse_packages(packages) - catalog, plural = get_javascript_catalog(locale, domain, packages) - return render_javascript_catalog(catalog, plural) - - -def json_catalog(request, domain='djangojs', packages=None): - """ - Return the selected language catalog as a JSON object. - - Receives the same parameters as javascript_catalog(), but returns - a response with a JSON object of the following format: - - { - "catalog": { - # Translations catalog - }, - "formats": { - # Language formats for date, time, etc. - }, - "plural": '...' # Expression for plural forms, or null. - } - """ - warnings.warn( - "The json_catalog() view is deprecated in favor of the " - "JSONCatalog view.", RemovedInDjango20Warning, stacklevel=2 - ) - locale = _get_locale(request) - packages = _parse_packages(packages) - catalog, plural = get_javascript_catalog(locale, domain, packages) - data = { - 'catalog': catalog, - 'formats': get_formats(), - 'plural': plural, - } - return http.JsonResponse(data) - - class JavaScriptCatalog(View): """ Return the selected language catalog as a JavaScript library. diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt index b7b489499de9..9d0d9efd938b 100644 --- a/docs/releases/1.9.txt +++ b/docs/releases/1.9.txt @@ -384,7 +384,7 @@ Internationalization * The :func:`django.views.i18n.set_language` view now properly redirects to :ref:`translated URLs `, when available. -* The :func:`django.views.i18n.javascript_catalog` view now works correctly +* The ``django.views.i18n.javascript_catalog()`` view now works correctly if used multiple times with different configurations on the same page. * The :func:`django.utils.timezone.make_aware` function gained an ``is_dst`` @@ -394,7 +394,7 @@ Internationalization for languages which can be written in different scripts, for example Latin and Cyrillic (e.g. ``be@latin``). -* Added the :func:`django.views.i18n.json_catalog` view to help build a custom +* Added the ``django.views.i18n.json_catalog()`` view to help build a custom client-side i18n library upon Django translations. It returns a JSON object containing a translations catalog, formatting settings, and a plural rule. diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 385b25b28de6..210fc84dd0cb 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -366,3 +366,5 @@ these features. * The keyword arguments ``virtual_only`` in ``Field.contribute_to_class()`` and ``virtual`` in ``Model._meta.add_field()`` are removed. + +* The ``javascript_catalog()`` and ``json_catalog()`` views are removed. diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt index aa85aff90711..4605f998e5a3 100644 --- a/docs/topics/i18n/translation.txt +++ b/docs/topics/i18n/translation.txt @@ -1049,88 +1049,6 @@ If you use more than one ``JavaScriptCatalog`` view on a site and some of them define the same strings, the strings in the catalog that was loaded last take precedence. -The ``javascript_catalog`` view -------------------------------- - -.. function:: javascript_catalog(request, domain='djangojs', packages=None) - -.. deprecated:: 1.10 - - ``javascript_catalog()`` is deprecated in favor of - :class:`JavaScriptCatalog` and will be removed in Django 2.0. - -The main solution to these problems is the -:meth:`django.views.i18n.javascript_catalog` view, which sends out a JavaScript -code library with functions that mimic the ``gettext`` interface, plus an array -of translation strings. Those translation strings are taken from applications or -Django core, according to what you specify in either the ``info_dict`` or the -URL. Paths listed in :setting:`LOCALE_PATHS` are also included. - -You hook it up like this:: - - from django.views.i18n import javascript_catalog - - js_info_dict = { - 'packages': ('your.app.package',), - } - - urlpatterns = [ - url(r'^jsi18n/$', javascript_catalog, js_info_dict, name='javascript-catalog'), - ] - -Each string in ``packages`` should be in Python dotted-package syntax (the -same format as the strings in :setting:`INSTALLED_APPS`) and should refer to a -package that contains a ``locale`` directory. If you specify multiple packages, -all those catalogs are merged into one catalog. This is useful if you have -JavaScript that uses strings from different applications. - -The precedence of translations is such that the packages appearing later in the -``packages`` argument have higher precedence than the ones appearing at the -beginning, this is important in the case of clashing translations for the same -literal. - -By default, the view uses the ``djangojs`` gettext domain. This can be -changed by altering the ``domain`` argument. - -You can make the view dynamic by putting the packages into the URL pattern:: - - urlpatterns = [ - url(r'^jsi18n/(?P\S+?)/$', javascript_catalog, name='javascript-catalog'), - ] - -With this, you specify the packages as a list of package names delimited by '+' -signs in the URL. This is especially useful if your pages use code from -different apps and this changes often and you don't want to pull in one big -catalog file. As a security measure, these values can only be either -``django.conf`` or any package from the :setting:`INSTALLED_APPS` setting. - -You can also split the catalogs in multiple URLs and load them as you need in -your sites:: - - js_info_dict_app = { - 'packages': ('your.app.package',), - } - - js_info_dict_other_app = { - 'packages': ('your.other.app.package',), - } - - urlpatterns = [ - url(r'^jsi18n/app/$', javascript_catalog, js_info_dict_app), - url(r'^jsi18n/other_app/$', javascript_catalog, js_info_dict_other_app), - ] - -If you use more than one ``javascript_catalog`` on a site and some of them -define the same strings, the strings in the catalog that was loaded last take -precedence. - -The JavaScript translations found in the paths listed in the -:setting:`LOCALE_PATHS` setting are also always included. To keep consistency -with the translations lookup order algorithm used for Python and templates, the -directories listed in :setting:`LOCALE_PATHS` have the highest precedence with -the ones appearing first having higher precedence than the ones appearing -later. - Using the JavaScript translation catalog ---------------------------------------- @@ -1326,57 +1244,6 @@ The ``JSONCatalog`` view .. JSON doesn't allow comments so highlighting as JSON won't work here. -The ``json_catalog`` view -------------------------- - -.. function:: json_catalog(request, domain='djangojs', packages=None) - -.. deprecated:: 1.10 - - ``json_catalog()`` is deprecated in favor of :class:`JSONCatalog` and will - be removed in Django 2.0. - -In order to use another client-side library to handle translations, you may -want to take advantage of the ``json_catalog()`` view. It's similar to -:meth:`~django.views.i18n.javascript_catalog` but returns a JSON response. - -The JSON object contains i18n formatting settings (those available for -`get_format`_), a plural rule (as a ``plural`` part of a GNU gettext -``Plural-Forms`` expression), and translation strings. The translation strings -are taken from applications or Django's own translations, according to what is -specified either via ``urlpatterns`` arguments or as request parameters. Paths -listed in :setting:`LOCALE_PATHS` are also included. - -The view is hooked up to your application and configured in the same fashion as -:meth:`~django.views.i18n.javascript_catalog` (namely, the ``domain`` and -``packages`` arguments behave identically):: - - from django.views.i18n import json_catalog - - js_info_dict = { - 'packages': ('your.app.package',), - } - - urlpatterns = [ - url(r'^jsoni18n/$', json_catalog, js_info_dict), - ] - -The response format is as follows: - -.. code-block:: text - - { - "catalog": { - # Translations catalog - }, - "formats": { - # Language formats for date, time, etc. - }, - "plural": "..." # Expression for plural forms, or null. - } - -.. JSON doesn't allow comments so highlighting as JSON won't work here. - Note on performance ------------------- diff --git a/tests/view_tests/tests/test_i18n_deprecated.py b/tests/view_tests/tests/test_i18n_deprecated.py deleted file mode 100644 index e60a04ad0138..000000000000 --- a/tests/view_tests/tests/test_i18n_deprecated.py +++ /dev/null @@ -1,244 +0,0 @@ -# -*- coding:utf-8 -*- -from __future__ import unicode_literals - -import gettext -import json -from os import path - -from django.conf import settings -from django.test import ( - SimpleTestCase, ignore_warnings, modify_settings, override_settings, -) -from django.test.selenium import SeleniumTestCase -from django.utils import six -from django.utils._os import upath -from django.utils.deprecation import RemovedInDjango20Warning -from django.utils.translation import override - -from ..urls import locale_dir - - -@override_settings(ROOT_URLCONF='view_tests.urls') -@ignore_warnings(category=RemovedInDjango20Warning) -class JsI18NTests(SimpleTestCase): - """ - Tests deprecated django views in django/views/i18n.py - """ - def test_jsi18n(self): - """The javascript_catalog can be deployed with language settings""" - for lang_code in ['es', 'fr', 'ru']: - with override(lang_code): - catalog = gettext.translation('djangojs', locale_dir, [lang_code]) - if six.PY3: - trans_txt = catalog.gettext('this is to be translated') - else: - trans_txt = catalog.ugettext('this is to be translated') - response = self.client.get('/old_jsi18n/') - # response content must include a line like: - # "this is to be translated": - # json.dumps() is used to be able to check unicode strings - self.assertContains(response, json.dumps(trans_txt), 1) - if lang_code == 'fr': - # Message with context (msgctxt) - self.assertContains(response, '"month name\\u0004May": "mai"', 1) - - def test_jsoni18n(self): - """ - The json_catalog returns the language catalog and settings as JSON. - """ - with override('de'): - response = self.client.get('/old_jsoni18n/') - data = json.loads(response.content.decode('utf-8')) - self.assertIn('catalog', data) - self.assertIn('formats', data) - self.assertIn('plural', data) - self.assertEqual(data['catalog']['month name\x04May'], 'Mai') - self.assertIn('DATETIME_FORMAT', data['formats']) - self.assertEqual(data['plural'], '(n != 1)') - - def test_jsi18n_with_missing_en_files(self): - """ - The javascript_catalog shouldn't load the fallback language in the - case that the current selected language is actually the one translated - from, and hence missing translation files completely. - - This happens easily when you're translating from English to other - languages and you've set settings.LANGUAGE_CODE to some other language - than English. - """ - with self.settings(LANGUAGE_CODE='es'), override('en-us'): - response = self.client.get('/old_jsi18n/') - self.assertNotContains(response, 'esto tiene que ser traducido') - - def test_jsoni18n_with_missing_en_files(self): - """ - Same as above for the json_catalog view. Here we also check for the - expected JSON format. - """ - with self.settings(LANGUAGE_CODE='es'), override('en-us'): - response = self.client.get('/old_jsoni18n/') - data = json.loads(response.content.decode('utf-8')) - self.assertIn('catalog', data) - self.assertIn('formats', data) - self.assertIn('plural', data) - self.assertEqual(data['catalog'], {}) - self.assertIn('DATETIME_FORMAT', data['formats']) - self.assertIsNone(data['plural']) - - def test_jsi18n_fallback_language(self): - """ - Let's make sure that the fallback language is still working properly - in cases where the selected language cannot be found. - """ - with self.settings(LANGUAGE_CODE='fr'), override('fi'): - response = self.client.get('/old_jsi18n/') - self.assertContains(response, 'il faut le traduire') - self.assertNotContains(response, "Untranslated string") - - def test_i18n_fallback_language_plural(self): - """ - The fallback to a language with less plural forms maintains the real - language's number of plural forms. - """ - with self.settings(LANGUAGE_CODE='pt'), override('ru'): - response = self.client.get('/jsi18n/') - self.assertEqual( - response.context['catalog']['{count} plural3'], - ['{count} plural3', '{count} plural3s', '{count} plural3 p3t'] - ) - - def test_i18n_english_variant(self): - with override('en-gb'): - response = self.client.get('/old_jsi18n/') - self.assertIn( - '"this color is to be translated": "this colour is to be translated"', - response.context['catalog_str'] - ) - - def test_i18n_language_non_english_default(self): - """ - Check if the Javascript i18n view returns an empty language catalog - if the default language is non-English, the selected language - is English and there is not 'en' translation available. See #13388, - #3594 and #13726 for more details. - """ - with self.settings(LANGUAGE_CODE='fr'), override('en-us'): - response = self.client.get('/old_jsi18n/') - self.assertNotContains(response, 'Choisir une heure') - - @modify_settings(INSTALLED_APPS={'append': 'view_tests.app0'}) - def test_non_english_default_english_userpref(self): - """ - Same as above with the difference that there IS an 'en' translation - available. The Javascript i18n view must return a NON empty language catalog - with the proper English translations. See #13726 for more details. - """ - with self.settings(LANGUAGE_CODE='fr'), override('en-us'): - response = self.client.get('/old_jsi18n_english_translation/') - self.assertContains(response, 'this app0 string is to be translated') - - def test_i18n_language_non_english_fallback(self): - """ - Makes sure that the fallback language is still working properly - in cases where the selected language cannot be found. - """ - with self.settings(LANGUAGE_CODE='fr'), override('none'): - response = self.client.get('/old_jsi18n/') - self.assertContains(response, 'Choisir une heure') - - def test_escaping(self): - # Force a language via GET otherwise the gettext functions are a noop! - response = self.client.get('/old_jsi18n_admin/?language=de') - self.assertContains(response, '\\x04') - - @modify_settings(INSTALLED_APPS={'append': ['view_tests.app5']}) - def test_non_BMP_char(self): - """ - Non-BMP characters should not break the javascript_catalog (#21725). - """ - with self.settings(LANGUAGE_CODE='en-us'), override('fr'): - response = self.client.get('/old_jsi18n/app5/') - self.assertContains(response, 'emoji') - self.assertContains(response, '\\ud83d\\udca9') - - -@override_settings(ROOT_URLCONF='view_tests.urls') -@ignore_warnings(category=RemovedInDjango20Warning) -class JsI18NTestsMultiPackage(SimpleTestCase): - """ - Tests for django views in django/views/i18n.py that need to change - settings.LANGUAGE_CODE and merge JS translation from several packages. - """ - @modify_settings(INSTALLED_APPS={'append': ['view_tests.app1', 'view_tests.app2']}) - def test_i18n_language_english_default(self): - """ - Check if the JavaScript i18n view returns a complete language catalog - if the default language is en-us, the selected language has a - translation available and a catalog composed by djangojs domain - translations of multiple Python packages is requested. See #13388, - #3594 and #13514 for more details. - """ - with self.settings(LANGUAGE_CODE='en-us'), override('fr'): - response = self.client.get('/old_jsi18n_multi_packages1/') - self.assertContains(response, 'il faut traduire cette cha\\u00eene de caract\\u00e8res de app1') - - @modify_settings(INSTALLED_APPS={'append': ['view_tests.app3', 'view_tests.app4']}) - def test_i18n_different_non_english_languages(self): - """ - Similar to above but with neither default or requested language being - English. - """ - with self.settings(LANGUAGE_CODE='fr'), override('es-ar'): - response = self.client.get('/old_jsi18n_multi_packages2/') - self.assertContains(response, 'este texto de app3 debe ser traducido') - - def test_i18n_with_locale_paths(self): - extended_locale_paths = settings.LOCALE_PATHS + [ - path.join( - path.dirname(path.dirname(path.abspath(upath(__file__)))), - 'app3', - 'locale', - ), - ] - with self.settings(LANGUAGE_CODE='es-ar', LOCALE_PATHS=extended_locale_paths): - with override('es-ar'): - response = self.client.get('/old_jsi18n/') - self.assertContains(response, 'este texto de app3 debe ser traducido') - - -@override_settings(ROOT_URLCONF='view_tests.urls') -@ignore_warnings(category=RemovedInDjango20Warning) -class JavascriptI18nTests(SeleniumTestCase): - - # The test cases use fixtures & translations from these apps. - available_apps = [ - 'django.contrib.admin', 'django.contrib.auth', - 'django.contrib.contenttypes', 'view_tests', - ] - - @override_settings(LANGUAGE_CODE='de') - def test_javascript_gettext(self): - self.selenium.get('%s%s' % (self.live_server_url, '/old_jsi18n_template/')) - - elem = self.selenium.find_element_by_id("gettext") - self.assertEqual(elem.text, "Entfernen") - elem = self.selenium.find_element_by_id("ngettext_sing") - self.assertEqual(elem.text, "1 Element") - elem = self.selenium.find_element_by_id("ngettext_plur") - self.assertEqual(elem.text, "455 Elemente") - elem = self.selenium.find_element_by_id("pgettext") - self.assertEqual(elem.text, "Kann") - elem = self.selenium.find_element_by_id("npgettext_sing") - self.assertEqual(elem.text, "1 Resultat") - elem = self.selenium.find_element_by_id("npgettext_plur") - self.assertEqual(elem.text, "455 Resultate") - - @modify_settings(INSTALLED_APPS={'append': ['view_tests.app1', 'view_tests.app2']}) - @override_settings(LANGUAGE_CODE='fr') - def test_multiple_catalogs(self): - self.selenium.get('%s%s' % (self.live_server_url, '/old_jsi18n_multi_catalogs/')) - - elem = self.selenium.find_element_by_id('app1string') - self.assertEqual(elem.text, 'il faut traduire cette chaîne de caractères de app1') - elem = self.selenium.find_element_by_id('app2string') - self.assertEqual(elem.text, 'il faut traduire cette chaîne de caractères de app2') diff --git a/tests/view_tests/urls.py b/tests/view_tests/urls.py index 8d2e923a9395..128be09eb6fe 100644 --- a/tests/view_tests/urls.py +++ b/tests/view_tests/urls.py @@ -72,19 +72,6 @@ url(r'technical404/$', views.technical404, name="my404"), url(r'classbased404/$', views.Http404View.as_view()), - # deprecated i18n views - url(r'^old_jsi18n/$', i18n.javascript_catalog, js_info_dict), - url(r'^old_jsi18n/app1/$', i18n.javascript_catalog, js_info_dict_app1), - url(r'^old_jsi18n/app2/$', i18n.javascript_catalog, js_info_dict_app2), - url(r'^old_jsi18n/app5/$', i18n.javascript_catalog, js_info_dict_app5), - url(r'^old_jsi18n_english_translation/$', i18n.javascript_catalog, js_info_dict_english_translation), - url(r'^old_jsi18n_multi_packages1/$', i18n.javascript_catalog, js_info_dict_multi_packages1), - url(r'^old_jsi18n_multi_packages2/$', i18n.javascript_catalog, js_info_dict_multi_packages2), - url(r'^old_jsi18n_admin/$', i18n.javascript_catalog, js_info_dict_admin), - url(r'^old_jsi18n_template/$', views.old_jsi18n), - url(r'^old_jsi18n_multi_catalogs/$', views.old_jsi18n_multi_catalogs), - url(r'^old_jsoni18n/$', i18n.json_catalog, js_info_dict), - # i18n views url(r'^i18n/', include('django.conf.urls.i18n')), url(r'^jsi18n/$', i18n.JavaScriptCatalog.as_view(packages=['view_tests'])), From 169178265249949300df8288d8ebd048613f2205 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 12:13:00 -0500 Subject: [PATCH 0044/3180] Refs #26509 -- Removed contrib.gis.utils.precision_wkt() per deprecation timeline. --- django/contrib/gis/utils/__init__.py | 1 - django/contrib/gis/utils/wkt.py | 66 ---------------------------- docs/releases/2.0.txt | 2 + tests/gis_tests/test_wkt.py | 26 ----------- 4 files changed, 2 insertions(+), 93 deletions(-) delete mode 100644 django/contrib/gis/utils/wkt.py delete mode 100644 tests/gis_tests/test_wkt.py diff --git a/django/contrib/gis/utils/__init__.py b/django/contrib/gis/utils/__init__.py index 78b221663fc1..e59277d3a7e7 100644 --- a/django/contrib/gis/utils/__init__.py +++ b/django/contrib/gis/utils/__init__.py @@ -2,7 +2,6 @@ This module contains useful utilities for GeoDjango. """ from django.contrib.gis.gdal import HAS_GDAL -from django.contrib.gis.utils.wkt import precision_wkt # NOQA from django.core.exceptions import ImproperlyConfigured if HAS_GDAL: diff --git a/django/contrib/gis/utils/wkt.py b/django/contrib/gis/utils/wkt.py deleted file mode 100644 index 988ace4ec751..000000000000 --- a/django/contrib/gis/utils/wkt.py +++ /dev/null @@ -1,66 +0,0 @@ -""" - Utilities for manipulating Geometry WKT. -""" -import warnings - -from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning - - -def precision_wkt(geom, prec): - """ - Returns WKT text of the geometry according to the given precision (an - integer or a string). If the precision is an integer, then the decimal - places of coordinates WKT will be truncated to that number: - - >>> from django.contrib.gis.geos import Point - >>> pnt = Point(5, 23) - >>> pnt.wkt - 'POINT (5.0000000000000000 23.0000000000000000)' - >>> precision_wkt(pnt, 1) - 'POINT (5.0 23.0)' - - If the precision is a string, it must be valid Python format string - (e.g., '%20.7f') -- thus, you should know what you're doing. - """ - warnings.warn( - "precision_wkt() is deprecated in favor of the WKTWriter class.", - RemovedInDjango20Warning, stacklevel=2 - ) - - if isinstance(prec, int): - num_fmt = '%%.%df' % prec - elif isinstance(prec, six.string_types): - num_fmt = prec - else: - raise TypeError - - # TODO: Support 3D geometries. - coord_fmt = ' '.join([num_fmt, num_fmt]) - - def formatted_coords(coords): - return ','.join(coord_fmt % c[:2] for c in coords) - - def formatted_poly(poly): - return ','.join('(%s)' % formatted_coords(r) for r in poly) - - def formatted_geom(g): - gtype = str(g.geom_type).upper() - yield '%s(' % gtype - if gtype == 'POINT': - yield formatted_coords((g.coords,)) - elif gtype in ('LINESTRING', 'LINEARRING'): - yield formatted_coords(g.coords) - elif gtype in ('POLYGON', 'MULTILINESTRING'): - yield formatted_poly(g) - elif gtype == 'MULTIPOINT': - yield formatted_coords(g.coords) - elif gtype == 'MULTIPOLYGON': - yield ','.join('(%s)' % formatted_poly(p) for p in g) - elif gtype == 'GEOMETRYCOLLECTION': - yield ','.join(''.join(wkt for wkt in formatted_geom(child)) for child in g) - else: - raise TypeError - yield ')' - - return ''.join(wkt for wkt in formatted_geom(geom)) diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 210fc84dd0cb..9999e0ae1846 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -368,3 +368,5 @@ these features. ``virtual`` in ``Model._meta.add_field()`` are removed. * The ``javascript_catalog()`` and ``json_catalog()`` views are removed. + +* ``django.contrib.gis.utils.precision_wkt()`` is removed. diff --git a/tests/gis_tests/test_wkt.py b/tests/gis_tests/test_wkt.py deleted file mode 100644 index b9d15e23b16e..000000000000 --- a/tests/gis_tests/test_wkt.py +++ /dev/null @@ -1,26 +0,0 @@ -from unittest import skipUnless - -from django.contrib.gis.geos import HAS_GEOS, GEOSGeometry -from django.contrib.gis.utils.wkt import precision_wkt -from django.test import SimpleTestCase, ignore_warnings -from django.utils.deprecation import RemovedInDjango20Warning - - -@skipUnless(HAS_GEOS, "Requires GEOS support") -class WktTest(SimpleTestCase): - - @ignore_warnings(category=RemovedInDjango20Warning) - def test_wkt(self): - point = GEOSGeometry('POINT (951640.547328465 4219369.26171664)') - self.assertEqual('POINT(951640.547328 4219369.261717)', precision_wkt(point, 6)) - self.assertEqual('POINT(951640.5473 4219369.2617)', precision_wkt(point, '%.4f')) - - multipoint = GEOSGeometry( - "SRID=4326;MULTIPOINT((13.18634033203125 14.504356384277344)," - "(13.207969665527 14.490966796875),(13.177070617675 14.454917907714))" - ) - self.assertEqual( - "MULTIPOINT(13.186340332031 14.504356384277," - "13.207969665527 14.490966796875,13.177070617675 14.454917907714)", - precision_wkt(multipoint, 12) - ) From 9d0e8c1e7f479dd4b414ffb4179295671bf673a6 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 12:30:29 -0500 Subject: [PATCH 0045/3180] Refs #26320 -- Removed implicit OneToOnField parent_link per deprecation timeline. --- django/db/models/options.py | 7 +++---- docs/releases/2.0.txt | 3 +++ tests/invalid_models_tests/test_models.py | 18 +++--------------- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/django/db/models/options.py b/django/db/models/options.py index c4652870e0b1..8f6e2bd4246d 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -8,7 +8,7 @@ from django.apps import apps from django.conf import settings -from django.core.exceptions import FieldDoesNotExist +from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured from django.db import connections from django.db.models import Manager from django.db.models.fields import AutoField @@ -244,9 +244,8 @@ def _prepare(self, model): field.primary_key = True self.setup_pk(field) if not field.remote_field.parent_link: - warnings.warn( - 'Add parent_link=True to %s as an implicit link is ' - 'deprecated.' % field, RemovedInDjango20Warning + raise ImproperlyConfigured( + 'Add parent_link=True to %s.' % field, ) else: auto = AutoField(verbose_name='ID', primary_key=True, auto_created=True) diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 9999e0ae1846..c8aaab3e71bd 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -370,3 +370,6 @@ these features. * The ``javascript_catalog()`` and ``json_catalog()`` views are removed. * ``django.contrib.gis.utils.precision_wkt()`` is removed. + +* In multi-table inheritance, implicit promotion of a ``OneToOneField`` to a + ``parent_link`` is removed. diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py index 78f2164ed506..662035af7542 100644 --- a/tests/invalid_models_tests/test_models.py +++ b/tests/invalid_models_tests/test_models.py @@ -2,11 +2,11 @@ from __future__ import unicode_literals import unittest -import warnings from django.conf import settings from django.core.checks import Error from django.core.checks.model_checks import _check_lazy_references +from django.core.exceptions import ImproperlyConfigured from django.db import connections, models from django.db.models.signals import post_init from django.test import SimpleTestCase @@ -783,26 +783,14 @@ class Membership(models.Model): self.assertEqual(errors, expected) def test_missing_parent_link(self): - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') - + msg = 'Add parent_link=True to invalid_models_tests.ParkingLot.parent.' + with self.assertRaisesMessage(ImproperlyConfigured, msg): class Place(models.Model): pass class ParkingLot(Place): - # In lieu of any other connector, an existing OneToOneField will be - # promoted to the primary key. parent = models.OneToOneField(Place, models.CASCADE) - self.assertEqual(len(warns), 1) - msg = str(warns[0].message) - self.assertEqual( - msg, - 'Add parent_link=True to invalid_models_tests.ParkingLot.parent ' - 'as an implicit link is deprecated.' - ) - self.assertEqual(ParkingLot._meta.pk.name, 'parent') - def test_m2m_table_name_clash(self): class Foo(models.Model): bar = models.ManyToManyField('Bar', db_table='myapp_bar') From 58d3d14aeaf17a27c0fa663173dbf8dd92053923 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 12:34:00 -0500 Subject: [PATCH 0046/3180] Refs #26533 -- Removed support for Widget._format_value() per deprecation timeline. --- django/forms/widgets.py | 11 +---------- docs/ref/forms/widgets.txt | 5 ----- docs/releases/2.0.txt | 2 ++ 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/django/forms/widgets.py b/django/forms/widgets.py index a2f674fcdd47..71f408e783e7 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -15,9 +15,6 @@ from django.templatetags.static import static from django.utils import datetime_safe, formats, six from django.utils.dates import MONTHS -from django.utils.deprecation import ( - RemovedInDjango20Warning, RenameMethodsBase, -) from django.utils.encoding import ( force_str, force_text, python_2_unicode_compatible, ) @@ -160,13 +157,7 @@ def __new__(mcs, name, bases, attrs): return new_class -class RenameWidgetMethods(MediaDefiningClass, RenameMethodsBase): - renamed_methods = ( - ('_format_value', 'format_value', RemovedInDjango20Warning), - ) - - -class Widget(six.with_metaclass(RenameWidgetMethods)): +class Widget(six.with_metaclass(MediaDefiningClass)): needs_multipart_form = False # Determines does this widget need multipart form is_localized = False is_required = False diff --git a/docs/ref/forms/widgets.txt b/docs/ref/forms/widgets.txt index f0301c1eeeb3..2b9cf489f1b5 100644 --- a/docs/ref/forms/widgets.txt +++ b/docs/ref/forms/widgets.txt @@ -236,11 +236,6 @@ foundation for custom widgets. isn't guaranteed to be valid input, therefore subclass implementations should program defensively. - .. versionchanged:: 1.10 - - In older versions, this method is a private API named - ``_format_value()``. The old name will work until Django 2.0. - .. method:: get_context(name, value, attrs=None) .. versionadded:: 1.11 diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index c8aaab3e71bd..19ae47fc49cf 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -373,3 +373,5 @@ these features. * In multi-table inheritance, implicit promotion of a ``OneToOneField`` to a ``parent_link`` is removed. + +* Support for ``Widget._format_value()`` is removed. From 0dfc5479a8e50215866bbf43604bed8416a1b504 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 12:36:25 -0500 Subject: [PATCH 0047/3180] Refs #26058 -- Removed deprecated FileField.get_directory_name()/get_filename(). --- django/db/models/fields/files.py | 19 -------------- docs/releases/2.0.txt | 3 +++ tests/file_storage/test_generate_filename.py | 27 -------------------- 3 files changed, 3 insertions(+), 46 deletions(-) diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index e877fc7ef4c1..e52cc1164d1a 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -1,7 +1,5 @@ import datetime -import os import posixpath -import warnings from django import forms from django.core import checks @@ -12,7 +10,6 @@ from django.db.models import signals from django.db.models.fields import Field from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_str, force_text from django.utils.translation import ugettext_lazy as _ @@ -301,22 +298,6 @@ def contribute_to_class(self, cls, name, **kwargs): super(FileField, self).contribute_to_class(cls, name, **kwargs) setattr(cls, self.name, self.descriptor_class(self)) - def get_directory_name(self): - warnings.warn( - 'FileField now delegates file name and folder processing to the ' - 'storage. get_directory_name() will be removed in Django 2.0.', - RemovedInDjango20Warning, stacklevel=2 - ) - return os.path.normpath(force_text(datetime.datetime.now().strftime(force_str(self.upload_to)))) - - def get_filename(self, filename): - warnings.warn( - 'FileField now delegates file name and folder processing to the ' - 'storage. get_filename() will be removed in Django 2.0.', - RemovedInDjango20Warning, stacklevel=2 - ) - return os.path.normpath(self.storage.get_valid_name(os.path.basename(filename))) - def generate_filename(self, instance, filename): """ Apply (if callable) or prepend (if a string) upload_to to the filename, diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 19ae47fc49cf..dade7e0bda0b 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -375,3 +375,6 @@ these features. ``parent_link`` is removed. * Support for ``Widget._format_value()`` is removed. + +* ``FileField`` methods ``get_directory_name()`` and ``get_filename()`` are + removed. diff --git a/tests/file_storage/test_generate_filename.py b/tests/file_storage/test_generate_filename.py index 44320138509b..b4222f412162 100644 --- a/tests/file_storage/test_generate_filename.py +++ b/tests/file_storage/test_generate_filename.py @@ -1,5 +1,4 @@ import os -import warnings from django.core.files.base import ContentFile from django.core.files.storage import Storage @@ -38,32 +37,6 @@ def generate_filename(self, filename): class GenerateFilenameStorageTests(SimpleTestCase): - def test_filefield_get_directory_deprecation(self): - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') - f = FileField(upload_to='some/folder/') - self.assertEqual(f.get_directory_name(), os.path.normpath('some/folder/')) - - self.assertEqual(len(warns), 1) - self.assertEqual( - warns[0].message.args[0], - 'FileField now delegates file name and folder processing to the ' - 'storage. get_directory_name() will be removed in Django 2.0.' - ) - - def test_filefield_get_filename_deprecation(self): - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') - f = FileField(upload_to='some/folder/') - self.assertEqual(f.get_filename('some/folder/test.txt'), 'test.txt') - - self.assertEqual(len(warns), 1) - self.assertEqual( - warns[0].message.args[0], - 'FileField now delegates file name and folder processing to the ' - 'storage. get_filename() will be removed in Django 2.0.' - ) - def test_filefield_generate_filename(self): f = FileField(upload_to='some/folder/') self.assertEqual( From 60ca37d2e56e435521a4aa5ba56b1b11cb2a78e5 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 12:43:30 -0500 Subject: [PATCH 0048/3180] Refs #24046 -- Removed mark_for_escaping() per deprecation timeline. --- django/template/base.py | 23 +--------- django/template/defaultfilters.py | 10 +--- django/utils/safestring.py | 46 ------------------- docs/ref/templates/builtins.txt | 11 ----- docs/ref/utils.txt | 10 ---- docs/releases/2.0.txt | 6 +++ docs/topics/python3.txt | 12 ++--- .../filter_tests/test_chaining.py | 23 ++-------- .../filter_tests/test_escape.py | 7 +-- .../filter_tests/test_force_escape.py | 12 ++--- tests/utils_tests/test_safestring.py | 41 +---------------- 11 files changed, 25 insertions(+), 176 deletions(-) diff --git a/django/template/base.py b/django/template/base.py index dd604db23582..af3b6c5371e8 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -54,22 +54,18 @@ import inspect import logging import re -import warnings from django.template.context import ( # NOQA: imported for backwards compatibility BaseContext, Context, ContextPopException, RequestContext, ) from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import ( force_str, force_text, python_2_unicode_compatible, ) from django.utils.formats import localize from django.utils.html import conditional_escape, escape from django.utils.inspect import getargspec -from django.utils.safestring import ( - EscapeData, SafeData, mark_for_escaping, mark_safe, -) +from django.utils.safestring import SafeData, mark_safe from django.utils.text import ( get_text_list, smart_split, unescape_string_literal, ) @@ -713,7 +709,6 @@ def resolve(self, context, ignore_failures=False): obj = string_if_invalid else: obj = self.var - escape_isnt_last_filter = True for func, args in self.filters: arg_vals = [] for lookup, arg in args: @@ -729,22 +724,8 @@ def resolve(self, context, ignore_failures=False): new_obj = func(obj, *arg_vals) if getattr(func, 'is_safe', False) and isinstance(obj, SafeData): obj = mark_safe(new_obj) - elif isinstance(obj, EscapeData): - with warnings.catch_warnings(): - # Ignore mark_for_escaping deprecation as this will be - # removed in Django 2.0. - warnings.simplefilter('ignore', category=RemovedInDjango20Warning) - obj = mark_for_escaping(new_obj) - escape_isnt_last_filter = False else: obj = new_obj - if not escape_isnt_last_filter: - warnings.warn( - "escape isn't the last filter in %s and will be applied " - "immediately in Django 2.0 so the output may change." - % [func.__name__ for func, _ in self.filters], - RemovedInDjango20Warning, stacklevel=2 - ) return obj def args_check(name, func, provided): @@ -1015,7 +996,7 @@ def render_value_in_context(value, context): value = template_localtime(value, use_tz=context.use_tz) value = localize(value, use_l10n=context.use_l10n) value = force_text(value) - if context.autoescape or isinstance(value, EscapeData): + if context.autoescape: return conditional_escape(value) else: return value diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index a1f96f5e2e4a..e35415bdf754 100644 --- a/django/template/defaultfilters.py +++ b/django/template/defaultfilters.py @@ -3,7 +3,6 @@ import random as random_module import re -import warnings from decimal import ROUND_HALF_UP, Context, Decimal, InvalidOperation from functools import wraps from operator import itemgetter @@ -11,14 +10,13 @@ from django.utils import formats, six from django.utils.dateformat import format, time_format -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text, iri_to_uri from django.utils.html import ( avoid_wrapping, conditional_escape, escape, escapejs, linebreaks, strip_tags, urlize as _urlize, ) from django.utils.http import urlquote -from django.utils.safestring import SafeData, mark_for_escaping, mark_safe +from django.utils.safestring import SafeData, mark_safe from django.utils.text import ( Truncator, normalize_newlines, phone2numeric, slugify as _slugify, wrap, ) @@ -442,11 +440,7 @@ def escape_filter(value): """ Marks the value as a string that should be auto-escaped. """ - with warnings.catch_warnings(): - # Ignore mark_for_escaping deprecation -- this will use - # conditional_escape() in Django 2.0. - warnings.simplefilter('ignore', category=RemovedInDjango20Warning) - return mark_for_escaping(value) + return conditional_escape(value) @register.filter(is_safe=True) diff --git a/django/utils/safestring.py b/django/utils/safestring.py index 76136d0b0cc2..4355a050a057 100644 --- a/django/utils/safestring.py +++ b/django/utils/safestring.py @@ -4,39 +4,11 @@ that the producer of the string has already turned characters that should not be interpreted by the HTML engine (e.g. '<') into the appropriate entities. """ -import warnings from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.functional import Promise, curry, wraps -class EscapeData(object): - pass - - -class EscapeBytes(bytes, EscapeData): - """ - A byte string that should be HTML-escaped when output. - """ - pass - - -class EscapeText(six.text_type, EscapeData): - """ - A unicode string object that should be HTML-escaped when output. - """ - pass - - -if six.PY3: - EscapeString = EscapeText -else: - EscapeString = EscapeBytes - # backwards compatibility for Python 2 - EscapeUnicode = EscapeText - - class SafeData(object): def __html__(self): """ @@ -144,21 +116,3 @@ def mark_safe(s): if callable(s): return _safety_decorator(mark_safe, s) return SafeString(str(s)) - - -def mark_for_escaping(s): - """ - Explicitly mark a string as requiring HTML escaping upon output. Has no - effect on SafeData subclasses. - - Can be called multiple times on a single string (the resulting escaping is - only applied once). - """ - warnings.warn('mark_for_escaping() is deprecated.', RemovedInDjango20Warning) - if hasattr(s, '__html__') or isinstance(s, EscapeData): - return s - if isinstance(s, bytes) or (isinstance(s, Promise) and s._delegate_bytes): - return EscapeBytes(s) - if isinstance(s, (six.text_type, Promise)): - return EscapeText(s) - return EscapeString(str(s)) diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt index 6395f976077a..5925370843be 100644 --- a/docs/ref/templates/builtins.txt +++ b/docs/ref/templates/builtins.txt @@ -1636,11 +1636,6 @@ Escapes a string's HTML. Specifically, it makes these replacements: * ``"`` (double quote) is converted to ``"`` * ``&`` is converted to ``&`` -The escaping is only applied when the string is output, so it does not matter -where in a chained sequence of filters you put ``escape``: it will always be -applied as though it were the last filter. If you want escaping to be applied -immediately, use the :tfilter:`force_escape` filter. - Applying ``escape`` to a variable that would normally have auto-escaping applied to the result will only result in one round of escaping being done. So it is safe to use this function even in auto-escaping environments. If you want @@ -1652,12 +1647,6 @@ For example, you can apply ``escape`` to fields when :ttag:`autoescape` is off:: {{ title|escape }} {% endautoescape %} -.. deprecated:: 1.10 - - The "lazy" behavior of the ``escape`` filter is deprecated. It will change - to immediately apply :func:`~django.utils.html.conditional_escape` in - Django 2.0. - .. templatefilter:: escapejs ``escapejs`` diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index 5870c955f6d9..8beafb8268d4 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -841,16 +841,6 @@ appropriate entities. Added support for decorator usage. -.. function:: mark_for_escaping(s) - - .. deprecated:: 1.10 - - Explicitly mark a string as requiring HTML escaping upon output. Has no - effect on ``SafeData`` subclasses. - - Can be called multiple times on a single string (the resulting escaping is - only applied once). - ``django.utils.text`` ===================== diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index dade7e0bda0b..7e595e9cbfd0 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -378,3 +378,9 @@ these features. * ``FileField`` methods ``get_directory_name()`` and ``get_filename()`` are removed. + +* The ``mark_for_escaping()`` function and the classes it uses: ``EscapeData``, + ``EscapeBytes``, ``EscapeText``, ``EscapeString``, and ``EscapeUnicode`` are + removed. + +* The ``escape`` filter now uses ``django.utils.html.conditional_escape()``. diff --git a/docs/topics/python3.txt b/docs/topics/python3.txt index 04a975d8f292..9dd4d8373244 100644 --- a/docs/topics/python3.txt +++ b/docs/topics/python3.txt @@ -112,22 +112,18 @@ For forwards compatibility, the new names work as of Django 1.4.2. information. :mod:`django.utils.safestring` is mostly used via the -:func:`~django.utils.safestring.mark_safe` and -:func:`~django.utils.safestring.mark_for_escaping` functions, which didn't -change. In case you're using the internals, here are the name changes: +: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 ================== ================== -``EscapeString`` ``EscapeBytes`` -``EscapeUnicode`` ``EscapeText`` ``SafeString`` ``SafeBytes`` ``SafeUnicode`` ``SafeText`` ================== ================== -For backwards compatibility, the old names still work on Python 2. Under -Python 3, ``EscapeString`` and ``SafeString`` are aliases for ``EscapeText`` -and ``SafeText`` respectively. +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. diff --git a/tests/template_tests/filter_tests/test_chaining.py b/tests/template_tests/filter_tests/test_chaining.py index 1c12e252a031..9bc3976f375a 100644 --- a/tests/template_tests/filter_tests/test_chaining.py +++ b/tests/template_tests/filter_tests/test_chaining.py @@ -1,8 +1,4 @@ -import warnings - -from django.test import SimpleTestCase, ignore_warnings -from django.test.utils import reset_warning_registry -from django.utils.deprecation import RemovedInDjango20Warning +from django.test import SimpleTestCase from django.utils.safestring import mark_safe from ..utils import setup @@ -42,20 +38,9 @@ def test_chaining04(self): # Using a filter that forces safeness does not lead to double-escaping @setup({'chaining05': '{{ a|escape|capfirst }}'}) def test_chaining05(self): - reset_warning_registry() - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') - output = self.engine.render_to_string('chaining05', {'a': 'a < b'}) - self.assertEqual(output, 'A < b') - - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - "escape isn't the last filter in ['escape_filter', 'capfirst'] and " - "will be applied immediately in Django 2.0 so the output may change." - ) - - @ignore_warnings(category=RemovedInDjango20Warning) + output = self.engine.render_to_string('chaining05', {'a': 'a < b'}) + self.assertEqual(output, 'A < b') + @setup({'chaining06': '{% autoescape off %}{{ a|escape|capfirst }}{% endautoescape %}'}) def test_chaining06(self): output = self.engine.render_to_string('chaining06', {'a': 'a < b'}) diff --git a/tests/template_tests/filter_tests/test_escape.py b/tests/template_tests/filter_tests/test_escape.py index 644ed7ac9e7e..6f28b972a25b 100644 --- a/tests/template_tests/filter_tests/test_escape.py +++ b/tests/template_tests/filter_tests/test_escape.py @@ -1,7 +1,6 @@ from django.template.defaultfilters import escape -from django.test import SimpleTestCase, ignore_warnings +from django.test import SimpleTestCase from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.functional import Promise, lazy from django.utils.safestring import mark_safe @@ -24,15 +23,11 @@ def test_escape02(self): output = self.engine.render_to_string('escape02', {"a": "x&y", "b": mark_safe("x&y")}) self.assertEqual(output, "x&y x&y") - # It is only applied once, regardless of the number of times it - # appears in a chain (to be changed in Django 2.0). - @ignore_warnings(category=RemovedInDjango20Warning) @setup({'escape03': '{% autoescape off %}{{ a|escape|escape }}{% endautoescape %}'}) def test_escape03(self): output = self.engine.render_to_string('escape03', {"a": "x&y"}) self.assertEqual(output, "x&y") - @ignore_warnings(category=RemovedInDjango20Warning) @setup({'escape04': '{{ a|escape|escape }}'}) def test_escape04(self): output = self.engine.render_to_string('escape04', {"a": "x&y"}) diff --git a/tests/template_tests/filter_tests/test_force_escape.py b/tests/template_tests/filter_tests/test_force_escape.py index f163f2cd75c1..45f4efde6259 100644 --- a/tests/template_tests/filter_tests/test_force_escape.py +++ b/tests/template_tests/filter_tests/test_force_escape.py @@ -2,8 +2,7 @@ from __future__ import unicode_literals from django.template.defaultfilters import force_escape -from django.test import SimpleTestCase, ignore_warnings -from django.utils.deprecation import RemovedInDjango20Warning +from django.test import SimpleTestCase from django.utils.safestring import SafeData from ..utils import setup @@ -36,8 +35,7 @@ def test_force_escape04(self): self.assertEqual(output, "x&amp;y") # Because the result of force_escape is "safe", an additional - # escape filter has no effect (to be changed in Django 2.0). - @ignore_warnings(category=RemovedInDjango20Warning) + # escape filter has no effect. @setup({'force-escape05': '{% autoescape off %}{{ a|force_escape|escape }}{% endautoescape %}'}) def test_force_escape05(self): output = self.engine.render_to_string('force-escape05', {"a": "x&y"}) @@ -48,17 +46,15 @@ def test_force_escape06(self): output = self.engine.render_to_string('force-escape06', {"a": "x&y"}) self.assertEqual(output, "x&y") - @ignore_warnings(category=RemovedInDjango20Warning) @setup({'force-escape07': '{% autoescape off %}{{ a|escape|force_escape }}{% endautoescape %}'}) def test_force_escape07(self): output = self.engine.render_to_string('force-escape07', {"a": "x&y"}) - self.assertEqual(output, "x&y") + self.assertEqual(output, "x&amp;y") - @ignore_warnings(category=RemovedInDjango20Warning) @setup({'force-escape08': '{{ a|escape|force_escape }}'}) def test_force_escape08(self): output = self.engine.render_to_string('force-escape08', {"a": "x&y"}) - self.assertEqual(output, "x&y") + self.assertEqual(output, "x&amp;y") class FunctionTests(SimpleTestCase): diff --git a/tests/utils_tests/test_safestring.py b/tests/utils_tests/test_safestring.py index 6afcb3b1f7ba..abaf6a059655 100644 --- a/tests/utils_tests/test_safestring.py +++ b/tests/utils_tests/test_safestring.py @@ -1,14 +1,11 @@ from __future__ import unicode_literals from django.template import Context, Template -from django.test import SimpleTestCase, ignore_warnings +from django.test import SimpleTestCase from django.utils import html, six, text -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_bytes from django.utils.functional import lazy, lazystr -from django.utils.safestring import ( - EscapeData, SafeData, mark_for_escaping, mark_safe, -) +from django.utils.safestring import SafeData, mark_safe lazybytes = lazy(force_bytes, bytes) @@ -63,40 +60,6 @@ def test_mark_safe_result_implements_dunder_html(self): def test_mark_safe_lazy_result_implements_dunder_html(self): self.assertEqual(mark_safe(lazystr('a&b')).__html__(), 'a&b') - @ignore_warnings(category=RemovedInDjango20Warning) - def test_mark_for_escaping(self): - s = mark_for_escaping('a&b') - self.assertRenderEqual('{{ s }}', 'a&b', s=s) - self.assertRenderEqual('{{ s }}', 'a&b', s=mark_for_escaping(s)) - - @ignore_warnings(category=RemovedInDjango20Warning) - def test_mark_for_escaping_object_implementing_dunder_html(self): - e = customescape('') - s = mark_for_escaping(e) - self.assertIs(s, e) - - self.assertRenderEqual('{{ s }}', '<>', s=s) - self.assertRenderEqual('{{ s|force_escape }}', '<a&b>', s=s) - - @ignore_warnings(category=RemovedInDjango20Warning) - def test_mark_for_escaping_lazy(self): - s = lazystr('a&b') - b = lazybytes(b'a&b') - - self.assertIsInstance(mark_for_escaping(s), EscapeData) - self.assertIsInstance(mark_for_escaping(b), EscapeData) - self.assertRenderEqual('{% autoescape off %}{{ s }}{% endautoescape %}', 'a&b', s=mark_for_escaping(s)) - - @ignore_warnings(category=RemovedInDjango20Warning) - def test_mark_for_escaping_object_implementing_dunder_str(self): - class Obj(object): - def __str__(self): - return '' - - s = mark_for_escaping(Obj()) - - self.assertRenderEqual('{{ s }}', '<obj>', s=s) - def test_add_lazy_safe_text_and_safe_text(self): s = html.escape(lazystr('a')) s += mark_safe('&b') From 631f4ab06112aca5bd6a57b81159048f936050bf Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 13:07:35 -0500 Subject: [PATCH 0049/3180] Removed Manager.use_for_related_fields and Meta.manager_inheritance_from_future. Per deprecation timeline. Refs ed0ff913c648b16c4471fc9a9441d1ee48cb5420. --- django/db/migrations/state.py | 16 +- django/db/models/base.py | 76 +--- .../db/models/fields/related_descriptors.py | 32 +- django/db/models/options.py | 30 +- docs/releases/2.0.txt | 6 + tests/managers_regress/models.py | 3 - tests/managers_regress/tests.py | 364 +----------------- tests/many_to_one/tests.py | 15 +- tests/one_to_one/tests.py | 23 +- tests/serializers/models/multi_table.py | 3 - 10 files changed, 21 insertions(+), 547 deletions(-) diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index e44f737106e8..98724337d857 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals import copy -import warnings from collections import OrderedDict from contextlib import contextmanager @@ -14,7 +13,6 @@ from django.db.models.options import DEFAULT_NAMES, normalize_together from django.db.models.utils import make_model_tuple from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -604,18 +602,8 @@ def render(self, apps): # Restore managers body.update(self.construct_managers()) - - with warnings.catch_warnings(): - warnings.filterwarnings( - "ignore", "Managers from concrete parents will soon qualify as default managers", - RemovedInDjango20Warning) - - # Then, make a Model object (apps.register_model is called in __new__) - return type( - str(self.name), - bases, - body, - ) + # Then, make a Model object (apps.register_model is called in __new__) + return type(str(self.name), bases, body) def get_field_by_name(self, name): for fname, field in self.fields: diff --git a/django/db/models/base.py b/django/db/models/base.py index 53b761f45ab7..7ecfc06284af 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -29,7 +29,6 @@ ) from django.db.models.utils import make_model_tuple from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import ( force_str, force_text, python_2_unicode_compatible, ) @@ -358,7 +357,7 @@ def _prepare(cls): if get_absolute_url_override: setattr(cls, 'get_absolute_url', get_absolute_url_override) - if not opts.managers or cls._requires_legacy_default_manager(): + if not opts.managers: if any(f.name == 'objects' for f in opts.fields): raise ValueError( "Model %s must specify a custom Manager, because it has a " @@ -370,79 +369,6 @@ def _prepare(cls): class_prepared.send(sender=cls) - def _requires_legacy_default_manager(cls): # RemovedInDjango20Warning - opts = cls._meta - - if opts.manager_inheritance_from_future: - return False - - future_default_manager = opts.default_manager - - # Step 1: Locate a manager that would have been promoted - # to default manager with the legacy system. - for manager in opts.managers: - originating_model = manager._originating_model - if (cls is originating_model or cls._meta.proxy or - originating_model._meta.abstract): - - if manager is not cls._default_manager and not opts.default_manager_name: - warnings.warn( - "Managers from concrete parents will soon qualify as default " - "managers if they appear before any other managers in the " - "MRO. As a result, '{legacy_default_manager}' declared on " - "'{legacy_default_manager_model}' will no longer be the " - "default manager for '{model}' in favor of " - "'{future_default_manager}' declared on " - "'{future_default_manager_model}'. " - "You can redeclare '{legacy_default_manager}' on '{cls}' " - "to keep things the way they are or you can switch to the new " - "behavior right away by setting " - "`Meta.manager_inheritance_from_future` to `True`.".format( - cls=cls.__name__, - model=opts.label, - legacy_default_manager=manager.name, - legacy_default_manager_model=manager._originating_model._meta.label, - future_default_manager=future_default_manager.name, - future_default_manager_model=future_default_manager._originating_model._meta.label, - ), - RemovedInDjango20Warning, 2 - ) - - opts.default_manager_name = manager.name - opts._expire_cache() - - break - - # Step 2: Since there are managers but none of them qualified as - # default managers under the legacy system (meaning that there are - # managers from concrete parents that would be promoted under the - # new system), we need to create a new Manager instance for the - # 'objects' attribute as a deprecation shim. - else: - # If the "future" default manager was auto created there is no - # point warning the user since it's basically the same manager. - if not future_default_manager.auto_created: - warnings.warn( - "Managers from concrete parents will soon qualify as " - "default managers. As a result, the 'objects' manager " - "won't be created (or recreated) automatically " - "anymore on '{model}' and '{future_default_manager}' " - "declared on '{future_default_manager_model}' will be " - "promoted to default manager. You can declare " - "explicitly `objects = models.Manager()` on '{cls}' " - "to keep things the way they are or you can switch " - "to the new behavior right away by setting " - "`Meta.manager_inheritance_from_future` to `True`.".format( - cls=cls.__name__, - model=opts.label, - future_default_manager=future_default_manager.name, - future_default_manager_model=future_default_manager._originating_model._meta.label, - ), - RemovedInDjango20Warning, 2 - ) - - return True - @property def _base_manager(cls): return cls._meta.base_manager diff --git a/django/db/models/fields/related_descriptors.py b/django/db/models/fields/related_descriptors.py index 19b465b8ada1..d8d57a89ede5 100644 --- a/django/db/models/fields/related_descriptors.py +++ b/django/db/models/fields/related_descriptors.py @@ -65,13 +65,11 @@ class Child(Model): from __future__ import unicode_literals -import warnings from operator import attrgetter from django.db import connections, router, transaction from django.db.models import Q, signals from django.db.models.query import QuerySet -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.functional import cached_property @@ -107,20 +105,7 @@ def is_cached(self, instance): return hasattr(instance, self.cache_name) def get_queryset(self, **hints): - related_model = self.field.remote_field.model - - if getattr(related_model._default_manager, 'use_for_related_fields', False): - if not getattr(related_model._default_manager, 'silence_use_for_related_fields_deprecation', False): - warnings.warn( - "use_for_related_fields is deprecated, instead " - "set Meta.base_manager_name on '{}'.".format(related_model._meta.label), - RemovedInDjango20Warning, 2 - ) - manager = related_model._default_manager - else: - manager = related_model._base_manager - - return manager.db_manager(hints=hints).all() + return self.field.remote_field.model._base_manager.db_manager(hints=hints).all() def get_prefetch_queryset(self, instances, queryset=None): if queryset is None: @@ -323,20 +308,7 @@ def is_cached(self, instance): return hasattr(instance, self.cache_name) def get_queryset(self, **hints): - related_model = self.related.related_model - - if getattr(related_model._default_manager, 'use_for_related_fields', False): - if not getattr(related_model._default_manager, 'silence_use_for_related_fields_deprecation', False): - warnings.warn( - "use_for_related_fields is deprecated, instead " - "set Meta.base_manager_name on '{}'.".format(related_model._meta.label), - RemovedInDjango20Warning, 2 - ) - manager = related_model._default_manager - else: - manager = related_model._base_manager - - return manager.db_manager(hints=hints).all() + return self.related.related_model._base_manager.db_manager(hints=hints).all() def get_prefetch_queryset(self, instances, queryset=None): if queryset is None: diff --git a/django/db/models/options.py b/django/db/models/options.py index 8f6e2bd4246d..19a0de8dfd5c 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -17,9 +17,7 @@ from django.db.models.query_utils import PathInfo from django.utils import six from django.utils.datastructures import ImmutableList, OrderedSet -from django.utils.deprecation import ( - RemovedInDjango20Warning, RemovedInDjango21Warning, -) +from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_text, python_2_unicode_compatible from django.utils.functional import cached_property from django.utils.text import camel_case_to_spaces, format_lazy @@ -41,7 +39,7 @@ 'auto_created', 'index_together', 'apps', 'default_permissions', 'select_on_save', 'default_related_name', 'required_db_features', 'required_db_vendor', 'base_manager_name', 'default_manager_name', - 'manager_inheritance_from_future', 'indexes', + 'indexes', ) @@ -87,7 +85,6 @@ def __init__(self, meta, app_label=None): self.local_fields = [] self.local_many_to_many = [] self.private_fields = [] - self.manager_inheritance_from_future = False self.local_managers = [] self.base_manager_name = None self.default_manager_name = None @@ -375,10 +372,6 @@ def managers(self): seen_managers.add(manager.name) managers.append((depth, manager.creation_counter, manager)) - # Used for deprecation of legacy manager inheritance, - # remove afterwards. (RemovedInDjango20Warning) - manager._originating_model = base - return make_immutable_fields_list( "managers", (m[2] for m in sorted(managers)), @@ -410,25 +403,6 @@ def base_manager(self): ) ) - # Deprecation shim for `use_for_related_fields`. - for i, base_manager_class in enumerate(self.default_manager.__class__.mro()): - if getattr(base_manager_class, 'use_for_related_fields', False): - if not getattr(base_manager_class, 'silence_use_for_related_fields_deprecation', False): - warnings.warn( - "use_for_related_fields is deprecated, instead " - "set Meta.base_manager_name on '{}'.".format(self.model._meta.label), - RemovedInDjango20Warning, 2 - ) - - if i == 0: - manager = self.default_manager - else: - manager = base_manager_class() - manager.name = '_base_manager' - manager.model = self.model - - return manager - manager = Manager() manager.name = '_base_manager' manager.model = self.model diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 7e595e9cbfd0..b63331c479ab 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -384,3 +384,9 @@ these features. removed. * The ``escape`` filter now uses ``django.utils.html.conditional_escape()``. + +* ``Manager.use_for_related_fields`` is removed. + +* Model ``Manager`` inheritance follows MRO inheritance rules. The requirement + to use ``Meta.manager_inheritance_from_future`` to opt-in to the behavior is + removed. diff --git a/tests/managers_regress/models.py b/tests/managers_regress/models.py index 37c3a37dcfcc..b39e69b9adda 100644 --- a/tests/managers_regress/models.py +++ b/tests/managers_regress/models.py @@ -118,9 +118,6 @@ def __str__(self): class Child6(Child4): value = models.IntegerField() - class Meta: - manager_inheritance_from_future = True - class Child7(Parent): objects = models.Manager() diff --git a/tests/managers_regress/tests.py b/tests/managers_regress/tests.py index 031c8a815555..cda90ac2b679 100644 --- a/tests/managers_regress/tests.py +++ b/tests/managers_regress/tests.py @@ -1,13 +1,9 @@ from __future__ import unicode_literals -import warnings - from django.db import models -from django.db.utils import DatabaseError from django.template import Context, Template from django.test import TestCase, override_settings from django.test.utils import isolate_apps -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from .models import ( @@ -185,23 +181,20 @@ class PlainModel(models.Model): self.assertIsInstance(PlainModel._default_manager, CustomManager) class ModelWithAbstractParent(AbstractModel): - class Meta: - manager_inheritance_from_future = True + pass self.assertIsInstance(ModelWithAbstractParent._base_manager, models.Manager) self.assertIsInstance(ModelWithAbstractParent._default_manager, CustomManager) class ProxyModel(PlainModel): class Meta: - manager_inheritance_from_future = True proxy = True self.assertIsInstance(ProxyModel._base_manager, models.Manager) self.assertIsInstance(ProxyModel._default_manager, CustomManager) class MTIModel(PlainModel): - class Meta: - manager_inheritance_from_future = True + pass self.assertIsInstance(MTIModel._base_manager, models.Manager) self.assertIsInstance(MTIModel._default_manager, CustomManager) @@ -228,21 +221,18 @@ class Meta: self.assertIsInstance(PlainModel._default_manager, CustomManager) class ModelWithAbstractParent(AbstractModel): - class Meta: - manager_inheritance_from_future = True + pass self.assertIsInstance(ModelWithAbstractParent._default_manager, CustomManager) class ProxyModel(PlainModel): class Meta: - manager_inheritance_from_future = True proxy = True self.assertIsInstance(ProxyModel._default_manager, CustomManager) class MTIModel(PlainModel): - class Meta: - manager_inheritance_from_future = True + pass self.assertIsInstance(MTIModel._default_manager, CustomManager) @@ -268,21 +258,18 @@ class Meta: self.assertIsInstance(PlainModel._base_manager, CustomManager) class ModelWithAbstractParent(AbstractModel): - class Meta: - manager_inheritance_from_future = True + pass self.assertIsInstance(ModelWithAbstractParent._base_manager, CustomManager) class ProxyModel(PlainModel): class Meta: - manager_inheritance_from_future = True proxy = True self.assertIsInstance(ProxyModel._base_manager, CustomManager) class MTIModel(PlainModel): - class Meta: - manager_inheritance_from_future = True + pass self.assertIsInstance(MTIModel._base_manager, CustomManager) @@ -301,342 +288,3 @@ class TestModel(AbstractModel): self.assertEqual(TestModel._meta.managers, (TestModel.custom_manager,)) self.assertEqual(TestModel._meta.managers_map, {'custom_manager': TestModel.custom_manager}) - - -@isolate_apps('managers_regress') -class TestManagerDeprecations(TestCase): - - def test_use_for_related_fields_for_base_manager(self): - class MyManager(models.Manager): - use_for_related_fields = True - - class MyModel(models.Model): - objects = MyManager() - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always', RemovedInDjango20Warning) - MyModel._base_manager - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - "use_for_related_fields is deprecated, " - "instead set Meta.base_manager_name on " - "'managers_regress.MyModel'.", - ) - - # With the new base_manager_name API there shouldn't be any warnings. - class MyModel2(models.Model): - objects = MyManager() - - class Meta: - base_manager_name = 'objects' - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always', RemovedInDjango20Warning) - MyModel2._base_manager - self.assertEqual(len(warns), 0) - - def test_use_for_related_fields_for_many_to_one(self): - # Common objects - class MyManagerQuerySet(models.QuerySet): - pass - - class MyLegacyManagerQuerySet(models.QuerySet): - pass - - class MyManager(models.Manager): - def get_queryset(self): - return MyManagerQuerySet(model=self.model, using=self._db, hints=self._hints) - - class MyLegacyManager(models.Manager): - use_for_related_fields = True - - def get_queryset(self): - return MyLegacyManagerQuerySet(model=self.model, using=self._db, hints=self._hints) - - # With legacy config there should be a deprecation warning - class MyRelModel(models.Model): - objects = MyLegacyManager() - - class MyModel(models.Model): - fk = models.ForeignKey(MyRelModel, on_delete=models.DO_NOTHING) - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always', RemovedInDjango20Warning) - try: - MyModel(fk_id=42).fk - except DatabaseError: - pass - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - "use_for_related_fields is deprecated, " - "instead set Meta.base_manager_name on " - "'managers_regress.MyRelModel'.", - ) - - # With the new base_manager_name API there shouldn't be any warnings. - class MyRelModel2(models.Model): - objects = MyManager() - - class Meta: - base_manager_name = 'objects' - - class MyModel2(models.Model): - fk = models.ForeignKey(MyRelModel2, on_delete=models.DO_NOTHING) - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always', RemovedInDjango20Warning) - try: - MyModel2(fk_id=42).fk - except DatabaseError: - pass - self.assertEqual(len(warns), 0) - - # When mixing base_manager_name and use_for_related_fields, there - # should be warnings. - class MyRelModel3(models.Model): - my_base_manager = MyManager() - my_default_manager = MyLegacyManager() - - class Meta: - base_manager_name = 'my_base_manager' - default_manager_name = 'my_default_manager' - - class MyModel3(models.Model): - fk = models.ForeignKey(MyRelModel3, on_delete=models.DO_NOTHING) - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always', RemovedInDjango20Warning) - try: - MyModel3(fk_id=42).fk - except DatabaseError: - pass - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - "use_for_related_fields is deprecated, " - "instead set Meta.base_manager_name on " - "'managers_regress.MyRelModel3'.", - ) - with warnings.catch_warnings(record=True): - warnings.simplefilter('always', RemovedInDjango20Warning) - self.assertIsInstance(MyModel3.fk.get_queryset(), MyLegacyManagerQuerySet) - - def test_use_for_related_fields_for_one_to_one(self): - # Common objects - class MyManagerQuerySet(models.QuerySet): - pass - - class MyLegacyManagerQuerySet(models.QuerySet): - pass - - class MyManager(models.Manager): - def get_queryset(self): - return MyManagerQuerySet(model=self.model, using=self._db, hints=self._hints) - - class MyLegacyManager(models.Manager): - use_for_related_fields = True - - def get_queryset(self): - return MyLegacyManagerQuerySet(model=self.model, using=self._db, hints=self._hints) - - # With legacy config there should be a deprecation warning - class MyRelModel(models.Model): - objects = MyLegacyManager() - - class MyModel(models.Model): - o2o = models.OneToOneField(MyRelModel, on_delete=models.DO_NOTHING) - objects = MyLegacyManager() - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always', RemovedInDjango20Warning) - try: - MyModel(o2o_id=42).o2o - except DatabaseError: - pass - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - "use_for_related_fields is deprecated, " - "instead set Meta.base_manager_name on " - "'managers_regress.MyRelModel'.", - ) - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always', RemovedInDjango20Warning) - try: - MyRelModel(pk=42).mymodel - except DatabaseError: - pass - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - "use_for_related_fields is deprecated, " - "instead set Meta.base_manager_name on " - "'managers_regress.MyModel'.", - ) - - # With the new base_manager_name API there shouldn't be any warnings. - class MyRelModel2(models.Model): - objects = MyManager() - - class Meta: - base_manager_name = 'objects' - - class MyModel2(models.Model): - o2o = models.OneToOneField(MyRelModel2, on_delete=models.DO_NOTHING) - objects = MyManager() - - class Meta: - base_manager_name = 'objects' - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always', RemovedInDjango20Warning) - try: - MyModel2(o2o_id=42).o2o - except DatabaseError: - pass - try: - MyRelModel2(pk=42).mymodel2 - except DatabaseError: - pass - self.assertEqual(len(warns), 0) - - # When mixing base_manager_name and use_for_related_fields, there - # should be warnings. - class MyRelModel3(models.Model): - my_base_manager = MyManager() - my_default_manager = MyLegacyManager() - - class Meta: - base_manager_name = 'my_base_manager' - default_manager_name = 'my_default_manager' - - class MyModel3(models.Model): - o2o = models.OneToOneField(MyRelModel3, on_delete=models.DO_NOTHING) - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always', RemovedInDjango20Warning) - try: - MyModel3(o2o_id=42).o2o - except DatabaseError: - pass - - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - "use_for_related_fields is deprecated, " - "instead set Meta.base_manager_name on " - "'managers_regress.MyRelModel3'.", - ) - with warnings.catch_warnings(record=True): - warnings.simplefilter('always', RemovedInDjango20Warning) - self.assertIsInstance(MyModel3.o2o.get_queryset(), MyLegacyManagerQuerySet) - - def test_legacy_objects_is_created(self): - class ConcreteParentWithoutManager(models.Model): - pass - - class ConcreteParentWithManager(models.Model): - default = models.Manager() - - class AbstractParent(models.Model): - default = models.Manager() - - class Meta: - abstract = True - - # Shouldn't complain since the inherited manager - # is basically the same that would have been created. - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always', RemovedInDjango20Warning) - - class MyModel(ConcreteParentWithoutManager): - pass - self.assertEqual(len(warns), 0) - - # Should create 'objects' (set as default) and warn that - # it will no longer be the case in the future. - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always', RemovedInDjango20Warning) - - class MyModel2(ConcreteParentWithManager): - pass - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - "Managers from concrete parents will soon qualify as default " - "managers. As a result, the 'objects' manager won't be created " - "(or recreated) automatically anymore on " - "'managers_regress.MyModel2' and 'default' declared on " - "'managers_regress.ConcreteParentWithManager' will be promoted " - "to default manager. You can declare explicitly " - "`objects = models.Manager()` on 'MyModel2' to keep things the " - "way they are or you can switch to the new behavior right away " - "by setting `Meta.manager_inheritance_from_future` to `True`.", - ) - - self.assertIs(MyModel2.objects, MyModel2._default_manager) - - # When there is a local manager we shouldn't get any warning - # and 'objects' shouldn't be created. - class MyModel3(ConcreteParentWithManager): - default = models.Manager() - self.assertIs(MyModel3.default, MyModel3._default_manager) - self.assertIsNone(getattr(MyModel3, 'objects', None)) - - # When there is an inherited manager we shouldn't get any warning - # and 'objects' shouldn't be created. - class MyModel4(AbstractParent, ConcreteParentWithManager): - pass - self.assertIs(MyModel4.default, MyModel4._default_manager) - self.assertIsNone(getattr(MyModel4, 'objects', None)) - - # With `manager_inheritance_from_future = True` 'objects' - # shouldn't be created. - class MyModel5(ConcreteParentWithManager): - class Meta: - manager_inheritance_from_future = True - self.assertIs(MyModel5.default, MyModel5._default_manager) - self.assertIsNone(getattr(MyModel5, 'objects', None)) - - def test_legacy_default_manager_promotion(self): - class ConcreteParent(models.Model): - concrete = models.Manager() - - class AbstractParent(models.Model): - abstract = models.Manager() - - class Meta: - abstract = True - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always', RemovedInDjango20Warning) - - class MyModel(ConcreteParent, AbstractParent): - pass - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - "Managers from concrete parents will soon qualify as default " - "managers if they appear before any other managers in the " - "MRO. As a result, 'abstract' declared on " - "'managers_regress.AbstractParent' will no longer be the " - "default manager for 'managers_regress.MyModel' in favor of " - "'concrete' declared on 'managers_regress.ConcreteParent'. " - "You can redeclare 'abstract' on 'MyModel' to keep things the " - "way they are or you can switch to the new behavior right " - "away by setting `Meta.manager_inheritance_from_future` to " - "`True`.", - ) - self.assertIs(MyModel.abstract, MyModel._default_manager) - - class MyModel2(ConcreteParent, AbstractParent): - abstract = models.Manager() - self.assertIs(MyModel2.abstract, MyModel2._default_manager) - - class MyModel3(ConcreteParent, AbstractParent): - class Meta: - manager_inheritance_from_future = True - self.assertIs(MyModel3.concrete, MyModel3._default_manager) diff --git a/tests/many_to_one/tests.py b/tests/many_to_one/tests.py index c0dd316f7929..478a746669cf 100644 --- a/tests/many_to_one/tests.py +++ b/tests/many_to_one/tests.py @@ -4,8 +4,7 @@ from django.core.exceptions import FieldError, MultipleObjectsReturned from django.db import models, transaction from django.db.utils import IntegrityError -from django.test import TestCase, ignore_warnings -from django.utils.deprecation import RemovedInDjango20Warning +from django.test import TestCase from django.utils.translation import ugettext_lazy from .models import ( @@ -577,7 +576,6 @@ def test_relation_unsaved(self): with self.assertNumQueries(1): self.assertEqual(th.child_set.count(), 0) - @ignore_warnings(category=RemovedInDjango20Warning) # for use_for_related_fields deprecation def test_related_object(self): public_school = School.objects.create(is_public=True) public_student = Student.objects.create(school=public_school) @@ -595,17 +593,6 @@ def test_related_object(self): # allow it. self.assertEqual(private_student.school, private_school) - # If the manager is marked "use_for_related_fields", it'll get used instead - # of the "bare" queryset. Usually you'd define this as a property on the class, - # but this approximates that in a way that's easier in tests. - School._default_manager.use_for_related_fields = True - try: - private_student = Student.objects.get(pk=private_student.pk) - with self.assertRaises(School.DoesNotExist): - private_student.school - finally: - School._default_manager.use_for_related_fields = False - School._meta.base_manager_name = 'objects' School._meta._expire_cache() try: diff --git a/tests/one_to_one/tests.py b/tests/one_to_one/tests.py index 1bbf85c19342..3d98d78c27ca 100644 --- a/tests/one_to_one/tests.py +++ b/tests/one_to_one/tests.py @@ -1,8 +1,7 @@ from __future__ import unicode_literals from django.db import IntegrityError, connection, transaction -from django.test import TestCase, ignore_warnings -from django.utils.deprecation import RemovedInDjango20Warning +from django.test import TestCase from .models import ( Bar, Director, Favorites, HiddenPointer, ManualPrimaryKey, MultiModel, @@ -419,7 +418,6 @@ def test_hidden_accessor(self): hasattr(Target, HiddenPointer._meta.get_field('target').remote_field.get_accessor_name()) ) - @ignore_warnings(category=RemovedInDjango20Warning) # for use_for_related_fields deprecation def test_related_object(self): public_school = School.objects.create(is_public=True) public_director = Director.objects.create(school=public_school, is_temp=False) @@ -452,25 +450,6 @@ def test_related_object(self): # allow it. self.assertEqual(private_school.director, private_director) - # If the manager is marked "use_for_related_fields", it'll get used instead - # of the "bare" queryset. Usually you'd define this as a property on the class, - # but this approximates that in a way that's easier in tests. - School._default_manager.use_for_related_fields = True - try: - private_director = Director._base_manager.get(pk=private_director.pk) - with self.assertRaises(School.DoesNotExist): - private_director.school - finally: - School._default_manager.use_for_related_fields = False - - Director._default_manager.use_for_related_fields = True - try: - private_school = School._base_manager.get(pk=private_school.pk) - with self.assertRaises(Director.DoesNotExist): - private_school.director - finally: - Director._default_manager.use_for_related_fields = False - School._meta.base_manager_name = 'objects' School._meta._expire_cache() try: diff --git a/tests/serializers/models/multi_table.py b/tests/serializers/models/multi_table.py index 467ab5095540..ced2a94bb589 100644 --- a/tests/serializers/models/multi_table.py +++ b/tests/serializers/models/multi_table.py @@ -17,6 +17,3 @@ def natural_key(self): class Child(Parent): child_data = models.CharField(max_length=30, unique=True) - - class Meta: - manager_inheritance_from_future = True From d334f46b7a080fd3eb720141c19b37b10704a352 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 13:24:00 -0500 Subject: [PATCH 0050/3180] Refs #26601 -- Removed support for old-style middleware using settings.MIDDLEWARE_CLASSES. --- django/conf/global_settings.py | 7 +- django/contrib/flatpages/forms.py | 5 +- .../core/checks/compatibility/django_1_10.py | 4 +- django/core/checks/security/base.py | 13 +- django/core/checks/security/csrf.py | 8 +- django/core/checks/security/sessions.py | 8 +- django/core/checks/utils.py | 10 - django/core/handlers/base.py | 132 +-- django/views/debug.py | 8 +- docs/internals/deprecation.txt | 2 +- docs/ref/checks.txt | 22 +- docs/ref/settings.txt | 31 +- docs/releases/1.2.txt | 2 +- docs/releases/1.6.txt | 2 +- docs/releases/1.7.txt | 8 +- docs/releases/1.8.txt | 2 +- docs/releases/2.0.txt | 3 + docs/topics/http/middleware.txt | 22 +- tests/auth_tests/test_context_processors.py | 14 - tests/auth_tests/test_remote_user.py | 18 - tests/check_framework/test_security.py | 29 +- tests/flatpages_tests/test_csrf.py | 18 - tests/flatpages_tests/test_forms.py | 18 - tests/flatpages_tests/test_middleware.py | 34 - tests/middleware_exceptions/test_legacy.py | 908 ------------------ tests/redirects_tests/tests.py | 16 - tests/template_tests/test_response.py | 35 +- tests/view_tests/tests/test_csrf.py | 29 - tests/view_tests/tests/test_i18n.py | 45 - 29 files changed, 83 insertions(+), 1370 deletions(-) delete mode 100644 django/core/checks/utils.py delete mode 100644 tests/middleware_exceptions/test_legacy.py diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py index f732682b1cfe..9cf2732d30a9 100644 --- a/django/conf/global_settings.py +++ b/django/conf/global_settings.py @@ -447,12 +447,7 @@ def gettext_noop(s): # List of middleware to use. Order is important; in the request phase, these # middleware will be applied in the order given, and in the response # phase the middleware will be applied in reverse order. -MIDDLEWARE_CLASSES = [ - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', -] - -MIDDLEWARE = None +MIDDLEWARE = [] ############ # SESSIONS # diff --git a/django/contrib/flatpages/forms.py b/django/contrib/flatpages/forms.py index fbc7da04ded3..4735c1ca95bc 100644 --- a/django/contrib/flatpages/forms.py +++ b/django/contrib/flatpages/forms.py @@ -29,9 +29,8 @@ def clean_url(self): ugettext("URL is missing a leading slash."), code='missing_leading_slash', ) - if (settings.APPEND_SLASH and ( - (settings.MIDDLEWARE and 'django.middleware.common.CommonMiddleware' in settings.MIDDLEWARE) or - 'django.middleware.common.CommonMiddleware' in settings.MIDDLEWARE_CLASSES) and + if (settings.APPEND_SLASH and + 'django.middleware.common.CommonMiddleware' in settings.MIDDLEWARE and not url.endswith('/')): raise forms.ValidationError( ugettext("URL is missing a trailing slash."), diff --git a/django/core/checks/compatibility/django_1_10.py b/django/core/checks/compatibility/django_1_10.py index 0ab28df6f86c..120ef0b5b191 100644 --- a/django/core/checks/compatibility/django_1_10.py +++ b/django/core/checks/compatibility/django_1_10.py @@ -1,13 +1,13 @@ from __future__ import unicode_literals -from django.conf import global_settings, settings +from django.conf import settings from .. import Tags, Warning, register @register(Tags.compatibility) def check_duplicate_middleware_settings(app_configs, **kwargs): - if settings.MIDDLEWARE is not None and settings.MIDDLEWARE_CLASSES != global_settings.MIDDLEWARE_CLASSES: + if settings.MIDDLEWARE is not None and hasattr(settings, 'MIDDLEWARE_CLASSES'): return [Warning( "The MIDDLEWARE_CLASSES setting is deprecated in Django 1.10 " "and the MIDDLEWARE setting takes precedence. Since you've set " diff --git a/django/core/checks/security/base.py b/django/core/checks/security/base.py index f482f771532f..bc804c53df5b 100644 --- a/django/core/checks/security/base.py +++ b/django/core/checks/security/base.py @@ -1,7 +1,6 @@ from django.conf import settings from .. import Tags, Warning, register -from ..utils import patch_middleware_message SECRET_KEY_MIN_LENGTH = 50 SECRET_KEY_MIN_UNIQUE_CHARACTERS = 5 @@ -109,25 +108,23 @@ def _security_middleware(): - return ("django.middleware.security.SecurityMiddleware" in settings.MIDDLEWARE_CLASSES or - settings.MIDDLEWARE and "django.middleware.security.SecurityMiddleware" in settings.MIDDLEWARE) + return 'django.middleware.security.SecurityMiddleware' in settings.MIDDLEWARE def _xframe_middleware(): - return ("django.middleware.clickjacking.XFrameOptionsMiddleware" in settings.MIDDLEWARE_CLASSES or - settings.MIDDLEWARE and "django.middleware.clickjacking.XFrameOptionsMiddleware" in settings.MIDDLEWARE) + return 'django.middleware.clickjacking.XFrameOptionsMiddleware' in settings.MIDDLEWARE @register(Tags.security, deploy=True) def check_security_middleware(app_configs, **kwargs): passed_check = _security_middleware() - return [] if passed_check else [patch_middleware_message(W001)] + return [] if passed_check else [W001] @register(Tags.security, deploy=True) def check_xframe_options_middleware(app_configs, **kwargs): passed_check = _xframe_middleware() - return [] if passed_check else [patch_middleware_message(W002)] + return [] if passed_check else [W002] @register(Tags.security, deploy=True) @@ -205,7 +202,7 @@ def check_xframe_deny(app_configs, **kwargs): not _xframe_middleware() or settings.X_FRAME_OPTIONS == 'DENY' ) - return [] if passed_check else [patch_middleware_message(W019)] + return [] if passed_check else [W019] @register(Tags.security, deploy=True) diff --git a/django/core/checks/security/csrf.py b/django/core/checks/security/csrf.py index d9dd47b3eabe..75c9813e7f6b 100644 --- a/django/core/checks/security/csrf.py +++ b/django/core/checks/security/csrf.py @@ -1,7 +1,6 @@ from django.conf import settings from .. import Tags, Warning, register -from ..utils import patch_middleware_message W003 = Warning( "You don't appear to be using Django's built-in " @@ -22,14 +21,13 @@ def _csrf_middleware(): - return ("django.middleware.csrf.CsrfViewMiddleware" in settings.MIDDLEWARE_CLASSES or - settings.MIDDLEWARE and "django.middleware.csrf.CsrfViewMiddleware" in settings.MIDDLEWARE) + return 'django.middleware.csrf.CsrfViewMiddleware' in settings.MIDDLEWARE @register(Tags.security, deploy=True) def check_csrf_middleware(app_configs, **kwargs): passed_check = _csrf_middleware() - return [] if passed_check else [patch_middleware_message(W003)] + return [] if passed_check else [W003] @register(Tags.security, deploy=True) @@ -39,4 +37,4 @@ def check_csrf_cookie_secure(app_configs, **kwargs): not _csrf_middleware() or settings.CSRF_COOKIE_SECURE ) - return [] if passed_check else [patch_middleware_message(W016)] + return [] if passed_check else [W016] diff --git a/django/core/checks/security/sessions.py b/django/core/checks/security/sessions.py index bb361e7b50f0..1f31a167fad8 100644 --- a/django/core/checks/security/sessions.py +++ b/django/core/checks/security/sessions.py @@ -1,7 +1,6 @@ from django.conf import settings from .. import Tags, Warning, register -from ..utils import patch_middleware_message def add_session_cookie_message(message): @@ -71,7 +70,7 @@ def check_session_cookie_secure(app_configs, **kwargs): if _session_app(): errors.append(W010) if _session_middleware(): - errors.append(patch_middleware_message(W011)) + errors.append(W011) if len(errors) > 1: errors = [W012] return errors @@ -84,15 +83,14 @@ def check_session_cookie_httponly(app_configs, **kwargs): if _session_app(): errors.append(W013) if _session_middleware(): - errors.append(patch_middleware_message(W014)) + errors.append(W014) if len(errors) > 1: errors = [W015] return errors def _session_middleware(): - return ("django.contrib.sessions.middleware.SessionMiddleware" in settings.MIDDLEWARE_CLASSES or - settings.MIDDLEWARE and "django.contrib.sessions.middleware.SessionMiddleware" in settings.MIDDLEWARE) + return 'django.contrib.sessions.middleware.SessionMiddleware' in settings.MIDDLEWARE def _session_app(): diff --git a/django/core/checks/utils.py b/django/core/checks/utils.py deleted file mode 100644 index 995d8432c9bc..000000000000 --- a/django/core/checks/utils.py +++ /dev/null @@ -1,10 +0,0 @@ -import copy - -from django.conf import settings - - -def patch_middleware_message(error): - if settings.MIDDLEWARE is None: - error = copy.copy(error) - error.msg = error.msg.replace('MIDDLEWARE', 'MIDDLEWARE_CLASSES') - return error diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py index eddd576181b6..1d53fa9d94f7 100644 --- a/django/core/handlers/base.py +++ b/django/core/handlers/base.py @@ -1,23 +1,16 @@ from __future__ import unicode_literals import logging -import sys import types -import warnings from django.conf import settings -from django.core import signals from django.core.exceptions import ImproperlyConfigured, MiddlewareNotUsed from django.db import connections, transaction -from django.urls import get_resolver, get_urlconf, set_urlconf +from django.urls import get_resolver, set_urlconf from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.module_loading import import_string -from .exception import ( - convert_exception_to_response, get_exception_response, - handle_uncaught_exception, -) +from .exception import convert_exception_to_response, get_exception_response logger = logging.getLogger('django.request') @@ -34,8 +27,7 @@ def __init__(self): def load_middleware(self): """ - Populate middleware lists from settings.MIDDLEWARE (or the deprecated - MIDDLEWARE_CLASSES). + Populate middleware lists from settings.MIDDLEWARE. Must be called after the environment is fixed (see __call__ in subclasses). """ @@ -45,62 +37,32 @@ def load_middleware(self): self._response_middleware = [] self._exception_middleware = [] - if settings.MIDDLEWARE is None: - warnings.warn( - "Old-style middleware using settings.MIDDLEWARE_CLASSES is " - "deprecated. Update your middleware and use settings.MIDDLEWARE " - "instead.", RemovedInDjango20Warning - ) - handler = convert_exception_to_response(self._legacy_get_response) - for middleware_path in settings.MIDDLEWARE_CLASSES: - mw_class = import_string(middleware_path) - try: - mw_instance = mw_class() - except MiddlewareNotUsed as exc: - if settings.DEBUG: - if six.text_type(exc): - logger.debug('MiddlewareNotUsed(%r): %s', middleware_path, exc) - else: - logger.debug('MiddlewareNotUsed: %r', middleware_path) - continue - - if hasattr(mw_instance, 'process_request'): - self._request_middleware.append(mw_instance.process_request) - if hasattr(mw_instance, 'process_view'): - self._view_middleware.append(mw_instance.process_view) - if hasattr(mw_instance, 'process_template_response'): - self._template_response_middleware.insert(0, mw_instance.process_template_response) - if hasattr(mw_instance, 'process_response'): - self._response_middleware.insert(0, mw_instance.process_response) - if hasattr(mw_instance, 'process_exception'): - self._exception_middleware.insert(0, mw_instance.process_exception) - else: - handler = convert_exception_to_response(self._get_response) - for middleware_path in reversed(settings.MIDDLEWARE): - middleware = import_string(middleware_path) - try: - mw_instance = middleware(handler) - except MiddlewareNotUsed as exc: - if settings.DEBUG: - if six.text_type(exc): - logger.debug('MiddlewareNotUsed(%r): %s', middleware_path, exc) - else: - logger.debug('MiddlewareNotUsed: %r', middleware_path) - continue - - if mw_instance is None: - raise ImproperlyConfigured( - 'Middleware factory %s returned None.' % middleware_path - ) - - if hasattr(mw_instance, 'process_view'): - self._view_middleware.insert(0, mw_instance.process_view) - if hasattr(mw_instance, 'process_template_response'): - self._template_response_middleware.append(mw_instance.process_template_response) - if hasattr(mw_instance, 'process_exception'): - self._exception_middleware.append(mw_instance.process_exception) - - handler = convert_exception_to_response(mw_instance) + handler = convert_exception_to_response(self._get_response) + for middleware_path in reversed(settings.MIDDLEWARE): + middleware = import_string(middleware_path) + try: + mw_instance = middleware(handler) + except MiddlewareNotUsed as exc: + if settings.DEBUG: + if six.text_type(exc): + logger.debug('MiddlewareNotUsed(%r): %s', middleware_path, exc) + else: + logger.debug('MiddlewareNotUsed: %r', middleware_path) + continue + + if mw_instance is None: + raise ImproperlyConfigured( + 'Middleware factory %s returned None.' % middleware_path + ) + + if hasattr(mw_instance, 'process_view'): + self._view_middleware.insert(0, mw_instance.process_view) + if hasattr(mw_instance, 'process_template_response'): + self._template_response_middleware.append(mw_instance.process_template_response) + if hasattr(mw_instance, 'process_exception'): + self._exception_middleware.append(mw_instance.process_exception) + + handler = convert_exception_to_response(mw_instance) # We only assign to this when initialization is complete as it is used # as a flag for initialization being complete. @@ -123,22 +85,6 @@ def get_response(self, request): response = self._middleware_chain(request) - # This block is only needed for legacy MIDDLEWARE_CLASSES; if - # MIDDLEWARE is used, self._response_middleware will be empty. - try: - # Apply response middleware, regardless of the response - for middleware_method in self._response_middleware: - response = middleware_method(request, response) - # Complain if the response middleware returned None (a common error). - if response is None: - raise ValueError( - "%s.process_response didn't return an " - "HttpResponse object. It returned None instead." - % (middleware_method.__self__.__class__.__name__)) - except Exception: # Any exception should be gathered and handled - signals.got_request_exception.send(sender=self.__class__, request=request) - response = self.handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info()) - response._closable_objects.append(request) # If the exception handler returns a TemplateResponse that has not @@ -228,23 +174,3 @@ def process_exception_by_middleware(self, exception, request): if response: return response raise - - def handle_uncaught_exception(self, request, resolver, exc_info): - """Allow subclasses to override uncaught exception handling.""" - return handle_uncaught_exception(request, resolver, exc_info) - - def _legacy_get_response(self, request): - """ - Apply process_request() middleware and call the main _get_response(), - if needed. Used only for legacy MIDDLEWARE_CLASSES. - """ - response = None - # Apply request middleware - for middleware_method in self._request_middleware: - response = middleware_method(request) - if response: - break - - if response is None: - response = self._get_response(request) - return response diff --git a/django/views/debug.py b/django/views/debug.py index 0345859c747b..0fb5ab1a2d81 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -867,8 +867,8 @@ def default_urlconf(request): Installed Applications: {{ settings.INSTALLED_APPS|pprint }} Installed Middleware: -{% if settings.MIDDLEWARE is not None %}{{ settings.MIDDLEWARE|pprint }}""" -"""{% else %}{{ settings.MIDDLEWARE_CLASSES|pprint }}{% endif %} +{{ settings.MIDDLEWARE|pprint }}""" +""" {% if template_does_not_exist %}Template loader postmortem {% if postmortem %}Django tried loading these templates, in this order: @@ -1075,8 +1075,8 @@ def default_urlconf(request): Installed Applications: {{ settings.INSTALLED_APPS|pprint }} Installed Middleware: -{% if settings.MIDDLEWARE is not None %}{{ settings.MIDDLEWARE|pprint }}""" -"""{% else %}{{ settings.MIDDLEWARE_CLASSES|pprint }}{% endif %} +{{ settings.MIDDLEWARE|pprint }}""" +""" {% if template_does_not_exist %}Template loader postmortem {% if postmortem %}Django tried loading these templates, in this order: {% for entry in postmortem %} diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 42db85127f18..05100c43a99c 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -571,7 +571,7 @@ details on these changes. * The ``SEND_BROKEN_LINK_EMAILS`` setting will be removed. Add the :class:`django.middleware.common.BrokenLinkEmailsMiddleware` middleware to - your :setting:`MIDDLEWARE_CLASSES` setting instead. + your ``MIDDLEWARE_CLASSES`` setting instead. * ``django.middleware.doc.XViewMiddleware`` will be removed. Use ``django.contrib.admindocs.middleware.XViewMiddleware`` instead. diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index fbdb34c7d999..f30d07d921c5 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -323,19 +323,19 @@ The following checks are run if you use the :option:`check --deploy` option: * **security.W001**: You do not have :class:`django.middleware.security.SecurityMiddleware` in your - :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES` so the :setting:`SECURE_HSTS_SECONDS`, + :setting:`MIDDLEWARE` so the :setting:`SECURE_HSTS_SECONDS`, :setting:`SECURE_CONTENT_TYPE_NOSNIFF`, :setting:`SECURE_BROWSER_XSS_FILTER`, and :setting:`SECURE_SSL_REDIRECT` settings will have no effect. * **security.W002**: You do not have :class:`django.middleware.clickjacking.XFrameOptionsMiddleware` in your - :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`, so your pages will not be served with an + :setting:`MIDDLEWARE`, so your pages will not be served with an ``'x-frame-options'`` header. Unless there is a good reason for your site to be served in a frame, you should consider enabling this header to help prevent clickjacking attacks. * **security.W003**: You don't appear to be using Django's built-in cross-site request forgery protection via the middleware (:class:`django.middleware.csrf.CsrfViewMiddleware` is not in your - :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`). Enabling the middleware is the safest + :setting:`MIDDLEWARE`). Enabling the middleware is the safest approach to ensure you don't leave any holes. * **security.W004**: You have not set a value for the :setting:`SECURE_HSTS_SECONDS` setting. If your entire site is served only @@ -372,10 +372,9 @@ The following checks are run if you use the :option:`check --deploy` option: sessions. * **security.W011**: You have :class:`django.contrib.sessions.middleware.SessionMiddleware` in your - :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`, but you have not set - :setting:`SESSION_COOKIE_SECURE` to ``True``. Using a secure-only session - cookie makes it more difficult for network traffic sniffers to hijack user - sessions. + :setting:`MIDDLEWARE`, but you have not set :setting:`SESSION_COOKIE_SECURE` + to ``True``. Using a secure-only session cookie makes it more difficult for + network traffic sniffers to hijack user sessions. * **security.W012**: :setting:`SESSION_COOKIE_SECURE` is not set to ``True``. Using a secure-only session cookie makes it more difficult for network traffic sniffers to hijack user sessions. @@ -386,10 +385,9 @@ The following checks are run if you use the :option:`check --deploy` option: sessions. * **security.W014**: You have :class:`django.contrib.sessions.middleware.SessionMiddleware` in your - :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`, but you have not set - :setting:`SESSION_COOKIE_HTTPONLY` to ``True``. Using an ``HttpOnly`` session - cookie makes it more difficult for cross-site scripting attacks to hijack user - sessions. + :setting:`MIDDLEWARE`, but you have not set :setting:`SESSION_COOKIE_HTTPONLY` + to ``True``. Using an ``HttpOnly`` session cookie makes it more difficult for + cross-site scripting attacks to hijack user sessions. * **security.W015**: :setting:`SESSION_COOKIE_HTTPONLY` is not set to ``True``. Using an ``HttpOnly`` session cookie makes it more difficult for cross-site scripting attacks to hijack user sessions. @@ -405,7 +403,7 @@ The following checks are run if you use the :option:`check --deploy` option: deployment. * **security.W019**: You have :class:`django.middleware.clickjacking.XFrameOptionsMiddleware` in your - :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`, but :setting:`X_FRAME_OPTIONS` is not set to + :setting:`MIDDLEWARE`, but :setting:`X_FRAME_OPTIONS` is not set to ``'DENY'``. The default is ``'SAMEORIGIN'``, but unless there is a good reason for your site to serve other parts of itself in a frame, you should change it to ``'DENY'``. diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index e9c333081a19..97a67ffc3bfc 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -9,9 +9,9 @@ Settings .. warning:: Be careful when you override settings, especially when the default value - is a non-empty list or dictionary, such as :setting:`MIDDLEWARE_CLASSES` - and :setting:`STATICFILES_FINDERS`. Make sure you keep the components - required by the features of Django you wish to use. + is a non-empty list or dictionary, such as :setting:`STATICFILES_FINDERS`. + Make sure you keep the components required by the features of Django you + wish to use. Core Settings ============= @@ -1900,30 +1900,6 @@ Default:: ``None`` A list of middleware to use. See :doc:`/topics/http/middleware`. -.. setting:: MIDDLEWARE_CLASSES - -``MIDDLEWARE_CLASSES`` ----------------------- - -.. deprecated:: 1.10 - - Old-style middleware that uses ``settings.MIDDLEWARE_CLASSES`` are - deprecated. :ref:`Adapt old, custom middleware ` and - use the :setting:`MIDDLEWARE` setting. - -Default:: - - [ - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - ] - -A list of middleware classes to use. This was the default setting used in -Django 1.9 and earlier. Django 1.10 introduced a new style of middleware. If -you have an older project using this setting you should :ref:`update any -middleware you've written yourself ` to the new style -and then use the :setting:`MIDDLEWARE` setting. - .. setting:: MIGRATION_MODULES ``MIGRATION_MODULES`` @@ -3411,7 +3387,6 @@ HTTP * :setting:`FORCE_SCRIPT_NAME` * :setting:`INTERNAL_IPS` * :setting:`MIDDLEWARE` -* :setting:`MIDDLEWARE_CLASSES` * Security * :setting:`SECURE_BROWSER_XSS_FILTER` diff --git a/docs/releases/1.2.txt b/docs/releases/1.2.txt index 3995ee7192c3..e91c161bb40c 100644 --- a/docs/releases/1.2.txt +++ b/docs/releases/1.2.txt @@ -434,7 +434,7 @@ should be aware of: The upgrade notes have been removed in current Django docs. Please refer to the docs for Django 1.3 or older to find these instructions. -* ``CsrfViewMiddleware`` is included in :setting:`MIDDLEWARE_CLASSES` by +* ``CsrfViewMiddleware`` is included in ``MIDDLEWARE_CLASSES`` by default. This turns on CSRF protection by default, so views that accept POST requests need to be written to work with the middleware. Instructions on how to do this are found in the CSRF docs. diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt index 275f5bd2e45d..0ddd1e05dd3c 100644 --- a/docs/releases/1.6.txt +++ b/docs/releases/1.6.txt @@ -1060,7 +1060,7 @@ out into a new middleware: If you're relying on this feature, you should add ``'django.middleware.common.BrokenLinkEmailsMiddleware'`` to your -:setting:`MIDDLEWARE_CLASSES` setting and remove ``SEND_BROKEN_LINK_EMAILS`` +``MIDDLEWARE_CLASSES`` setting and remove ``SEND_BROKEN_LINK_EMAILS`` from your settings. ``_has_changed`` method on widgets diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index 05a6af190ed4..76cd19eeb5fb 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -1271,13 +1271,13 @@ in a test class which is a subclass of :class:`~django.test.TransactionTestCase` rather than :class:`~django.test.TestCase`. -Contrib middleware removed from default :setting:`MIDDLEWARE_CLASSES` ---------------------------------------------------------------------- +Contrib middleware removed from default ``MIDDLEWARE_CLASSES`` +-------------------------------------------------------------- The :ref:`app-loading refactor ` deprecated using models from apps which are not part of the :setting:`INSTALLED_APPS` setting. This exposed an incompatibility between -the default :setting:`INSTALLED_APPS` and :setting:`MIDDLEWARE_CLASSES` in the +the default :setting:`INSTALLED_APPS` and ``MIDDLEWARE_CLASSES`` in the global defaults (``django.conf.global_settings``). To bring these settings in sync and prevent deprecation warnings when doing things like testing reusable apps with minimal settings, @@ -1287,7 +1287,7 @@ apps with minimal settings, from the defaults. These classes will still be included in the default settings generated by :djadmin:`startproject`. Most projects will not be affected by this change but if you were not previously declaring the -:setting:`MIDDLEWARE_CLASSES` in your project settings and relying on the +``MIDDLEWARE_CLASSES`` in your project settings and relying on the global default you should ensure that the new defaults are in line with your project's needs. You should also check for any code that accesses ``django.conf.global_settings.MIDDLEWARE_CLASSES`` directly. diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index 6c45b455ecfb..578f53a5b46a 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -1641,7 +1641,7 @@ Using ``AuthenticationMiddleware`` without ``SessionAuthenticationMiddleware`` added in Django 1.7. In Django 1.7.2, its functionality was moved to ``auth.get_user()`` and, for backwards compatibility, enabled only if ``'django.contrib.auth.middleware.SessionAuthenticationMiddleware'`` appears in -:setting:`MIDDLEWARE_CLASSES`. +``MIDDLEWARE_CLASSES``. In Django 1.10, session verification will be enabled regardless of whether or not ``SessionAuthenticationMiddleware`` is enabled (at which point diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index b63331c479ab..ec5e0aada9be 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -390,3 +390,6 @@ these features. * Model ``Manager`` inheritance follows MRO inheritance rules. The requirement to use ``Meta.manager_inheritance_from_future`` to opt-in to the behavior is removed. + +* Support for old-style middleware using ``settings.MIDDLEWARE_CLASSES`` is + removed. diff --git a/docs/topics/http/middleware.txt b/docs/topics/http/middleware.txt index 3ead0208382b..d5e892706561 100644 --- a/docs/topics/http/middleware.txt +++ b/docs/topics/http/middleware.txt @@ -16,16 +16,6 @@ how to write your own middleware. Django ships with some built-in middleware you can use right out of the box. They're documented in the :doc:`built-in middleware reference `. -.. versionchanged:: 1.10 - - A new style of middleware was introduced for use with the new - :setting:`MIDDLEWARE` setting. If you're using the old - :setting:`MIDDLEWARE_CLASSES` setting, you'll need to :ref:`adapt old, - custom middleware ` before using the new setting. - This document describes new-style middleware. Refer to this page in older - versions of the documentation for a description of how old-style middleware - works. - Writing your own middleware =========================== @@ -311,7 +301,7 @@ Upgrading pre-Django 1.10-style middleware Django provides ``django.utils.deprecation.MiddlewareMixin`` to ease creating middleware classes that are compatible with both :setting:`MIDDLEWARE` and the -old :setting:`MIDDLEWARE_CLASSES`. All middleware classes included with Django +old ``MIDDLEWARE_CLASSES``. All middleware classes included with Django are compatible with both settings. The mixin provides an ``__init__()`` method that accepts an optional @@ -325,7 +315,7 @@ The ``__call__()`` method: #. Calls ``self.process_response(request, response)`` (if defined). #. Returns the response. -If used with :setting:`MIDDLEWARE_CLASSES`, the ``__call__()`` method will +If used with ``MIDDLEWARE_CLASSES``, the ``__call__()`` method will never be used; Django calls ``process_request()`` and ``process_response()`` directly. @@ -336,9 +326,9 @@ even beneficial to the existing middleware. In a few cases, a middleware class may need some changes to adjust to the new semantics. These are the behavioral differences between using :setting:`MIDDLEWARE` and -:setting:`MIDDLEWARE_CLASSES`: +``MIDDLEWARE_CLASSES``: -1. Under :setting:`MIDDLEWARE_CLASSES`, every middleware will always have its +1. Under ``MIDDLEWARE_CLASSES``, every middleware will always have its ``process_response`` method called, even if an earlier middleware short-circuited by returning a response from its ``process_request`` method. Under :setting:`MIDDLEWARE`, middleware behaves more like an onion: @@ -347,7 +337,7 @@ These are the behavioral differences between using :setting:`MIDDLEWARE` and that middleware and the ones before it in :setting:`MIDDLEWARE` will see the response. -2. Under :setting:`MIDDLEWARE_CLASSES`, ``process_exception`` is applied to +2. Under ``MIDDLEWARE_CLASSES``, ``process_exception`` is applied to exceptions raised from a middleware ``process_request`` method. Under :setting:`MIDDLEWARE`, ``process_exception`` applies only to exceptions raised from the view (or from the ``render`` method of a @@ -355,7 +345,7 @@ These are the behavioral differences between using :setting:`MIDDLEWARE` and a middleware are converted to the appropriate HTTP response and then passed to the next middleware. -3. Under :setting:`MIDDLEWARE_CLASSES`, if a ``process_response`` method raises +3. Under ``MIDDLEWARE_CLASSES``, if a ``process_response`` method raises an exception, the ``process_response`` methods of all earlier middleware are skipped and a ``500 Internal Server Error`` HTTP response is always returned (even if the exception raised was e.g. an diff --git a/tests/auth_tests/test_context_processors.py b/tests/auth_tests/test_context_processors.py index d9efdc3d5b46..3857917860df 100644 --- a/tests/auth_tests/test_context_processors.py +++ b/tests/auth_tests/test_context_processors.py @@ -4,8 +4,6 @@ from django.contrib.contenttypes.models import ContentType from django.db.models import Q from django.test import SimpleTestCase, TestCase, override_settings -from django.test.utils import ignore_warnings -from django.utils.deprecation import RemovedInDjango20Warning from .settings import AUTH_MIDDLEWARE, AUTH_TEMPLATES @@ -78,12 +76,6 @@ def test_session_not_accessed(self): response = self.client.get('/auth_processor_no_attr_access/') self.assertContains(response, "Session not accessed") - @ignore_warnings(category=RemovedInDjango20Warning) - @override_settings(MIDDLEWARE_CLASSES=AUTH_MIDDLEWARE, MIDDLEWARE=None) - def test_session_not_accessed_middleware_classes(self): - response = self.client.get('/auth_processor_no_attr_access/') - self.assertContains(response, "Session not accessed") - @override_settings(MIDDLEWARE=AUTH_MIDDLEWARE) def test_session_is_accessed(self): """ @@ -93,12 +85,6 @@ def test_session_is_accessed(self): response = self.client.get('/auth_processor_attr_access/') self.assertContains(response, "Session accessed") - @ignore_warnings(category=RemovedInDjango20Warning) - @override_settings(MIDDLEWARE_CLASSES=AUTH_MIDDLEWARE, MIDDLEWARE=None) - def test_session_is_accessed_middleware_classes(self): - response = self.client.get('/auth_processor_attr_access/') - self.assertContains(response, "Session accessed") - def test_perms_attrs(self): u = User.objects.create_user(username='normal', password='secret') u.user_permissions.add( diff --git a/tests/auth_tests/test_remote_user.py b/tests/auth_tests/test_remote_user.py index 05c76ff6e342..e03e0a3b95a3 100644 --- a/tests/auth_tests/test_remote_user.py +++ b/tests/auth_tests/test_remote_user.py @@ -6,9 +6,7 @@ from django.contrib.auth.middleware import RemoteUserMiddleware from django.contrib.auth.models import User from django.test import TestCase, modify_settings, override_settings -from django.test.utils import ignore_warnings from django.utils import timezone -from django.utils.deprecation import RemovedInDjango20Warning @override_settings(ROOT_URLCONF='auth_tests.urls') @@ -153,22 +151,6 @@ def test_inactive_user(self): self.assertTrue(response.context['user'].is_anonymous) -@ignore_warnings(category=RemovedInDjango20Warning) -@override_settings(MIDDLEWARE=None) -class RemoteUserTestMiddlewareClasses(RemoteUserTest): - - def setUp(self): - self.patched_settings = modify_settings( - AUTHENTICATION_BACKENDS={'append': self.backend}, - MIDDLEWARE_CLASSES={'append': [ - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - self.middleware, - ]}, - ) - self.patched_settings.enable() - - class RemoteUserNoCreateBackend(RemoteUserBackend): """Backend that doesn't create unknown users.""" create_unknown_user = False diff --git a/tests/check_framework/test_security.py b/tests/check_framework/test_security.py index 8c3b73d8bb1f..370fca533bc4 100644 --- a/tests/check_framework/test_security.py +++ b/tests/check_framework/test_security.py @@ -1,6 +1,5 @@ from django.conf import settings from django.core.checks.security import base, csrf, sessions -from django.core.checks.utils import patch_middleware_message from django.test import SimpleTestCase from django.test.utils import override_settings @@ -22,14 +21,6 @@ def test_session_cookie_secure_with_installed_app(self): """ self.assertEqual(self.func(None), [sessions.W010]) - @override_settings( - SESSION_COOKIE_SECURE=False, - INSTALLED_APPS=["django.contrib.sessions"], - MIDDLEWARE=None, - MIDDLEWARE_CLASSES=[]) - def test_session_cookie_secure_with_installed_app_middleware_classes(self): - self.assertEqual(self.func(None), [sessions.W010]) - @override_settings( SESSION_COOKIE_SECURE=False, INSTALLED_APPS=[], @@ -42,14 +33,6 @@ def test_session_cookie_secure_with_middleware(self): """ self.assertEqual(self.func(None), [sessions.W011]) - @override_settings( - SESSION_COOKIE_SECURE=False, - INSTALLED_APPS=[], - MIDDLEWARE=None, - MIDDLEWARE_CLASSES=["django.contrib.sessions.middleware.SessionMiddleware"]) - def test_session_cookie_secure_with_middleware_middleware_classes(self): - self.assertEqual(self.func(None), [patch_middleware_message(sessions.W011)]) - @override_settings( SESSION_COOKIE_SECURE=False, INSTALLED_APPS=["django.contrib.sessions"], @@ -61,14 +44,6 @@ def test_session_cookie_secure_both(self): """ self.assertEqual(self.func(None), [sessions.W012]) - @override_settings( - SESSION_COOKIE_SECURE=False, - INSTALLED_APPS=["django.contrib.sessions"], - MIDDLEWARE=None, - MIDDLEWARE_CLASSES=["django.contrib.sessions.middleware.SessionMiddleware"]) - def test_session_cookie_secure_both_middleware_classes(self): - self.assertEqual(self.func(None), [sessions.W012]) - @override_settings( SESSION_COOKIE_SECURE=True, INSTALLED_APPS=["django.contrib.sessions"], @@ -137,7 +112,7 @@ def func(self): from django.core.checks.security.csrf import check_csrf_middleware return check_csrf_middleware - @override_settings(MIDDLEWARE=[], MIDDLEWARE_CLASSES=[]) + @override_settings(MIDDLEWARE=[]) def test_no_csrf_middleware(self): """ Warn if CsrfViewMiddleware isn't in MIDDLEWARE. @@ -177,7 +152,7 @@ def test_use_sessions_with_csrf_cookie_secure_false(self): """ self.assertEqual(self.func(None), []) - @override_settings(MIDDLEWARE=[], MIDDLEWARE_CLASSES=[], CSRF_COOKIE_SECURE=False) + @override_settings(MIDDLEWARE=[], CSRF_COOKIE_SECURE=False) def test_with_csrf_cookie_secure_false_no_middleware(self): """ No warning if CsrfViewMiddleware isn't in MIDDLEWARE, even if diff --git a/tests/flatpages_tests/test_csrf.py b/tests/flatpages_tests/test_csrf.py index c71d9dfca636..aa0344a93052 100644 --- a/tests/flatpages_tests/test_csrf.py +++ b/tests/flatpages_tests/test_csrf.py @@ -2,8 +2,6 @@ from django.contrib.flatpages.models import FlatPage from django.contrib.sites.models import Site from django.test import Client, TestCase, modify_settings, override_settings -from django.test.utils import ignore_warnings -from django.utils.deprecation import RemovedInDjango20Warning from .settings import FLATPAGES_TEMPLATES @@ -99,19 +97,3 @@ def test_post_unknown_page(self): "POSTing to an unknown page isn't caught as a 403 CSRF error" response = self.client.post('/no_such_page/') self.assertEqual(response.status_code, 404) - - -@ignore_warnings(category=RemovedInDjango20Warning) -@override_settings( - MIDDLEWARE=None, - MIDDLEWARE_CLASSES=[ - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware', - ], -) -class FlatpageCSRFMiddlewareClassesTests(FlatpageCSRFTests): - pass diff --git a/tests/flatpages_tests/test_forms.py b/tests/flatpages_tests/test_forms.py index acf6687ea265..100669be5985 100644 --- a/tests/flatpages_tests/test_forms.py +++ b/tests/flatpages_tests/test_forms.py @@ -59,24 +59,6 @@ def test_flatpage_doesnt_requires_trailing_slash_without_append_slash(self): form = FlatpageForm(data=dict(url='/no_trailing_slash', **self.form_data)) self.assertTrue(form.is_valid()) - @override_settings( - APPEND_SLASH=True, MIDDLEWARE=None, - MIDDLEWARE_CLASSES=['django.middleware.common.CommonMiddleware'], - ) - def test_flatpage_requires_trailing_slash_with_append_slash_middleware_classes(self): - form = FlatpageForm(data=dict(url='/no_trailing_slash', **self.form_data)) - with translation.override('en'): - self.assertFalse(form.is_valid()) - self.assertEqual(form.errors['url'], ["URL is missing a trailing slash."]) - - @override_settings( - APPEND_SLASH=False, MIDDLEWARE=None, - MIDDLEWARE_CLASSES=['django.middleware.common.CommonMiddleware'], - ) - def test_flatpage_doesnt_requires_trailing_slash_without_append_slash_middleware_classes(self): - form = FlatpageForm(data=dict(url='/no_trailing_slash', **self.form_data)) - self.assertTrue(form.is_valid()) - def test_flatpage_admin_form_url_uniqueness_validation(self): "The flatpage admin form correctly enforces url uniqueness among flatpages of the same site" data = dict(url='/myflatpage1/', **self.form_data) diff --git a/tests/flatpages_tests/test_middleware.py b/tests/flatpages_tests/test_middleware.py index bba7d6becfda..dd1d9e02f778 100644 --- a/tests/flatpages_tests/test_middleware.py +++ b/tests/flatpages_tests/test_middleware.py @@ -3,8 +3,6 @@ from django.contrib.flatpages.models import FlatPage from django.contrib.sites.models import Site from django.test import TestCase, modify_settings, override_settings -from django.test.utils import ignore_warnings -from django.utils.deprecation import RemovedInDjango20Warning from .settings import FLATPAGES_TEMPLATES @@ -109,22 +107,6 @@ def test_fallback_flatpage_special_chars(self): self.assertContains(response, "

Isn't it special!

") -@ignore_warnings(category=RemovedInDjango20Warning) -@override_settings( - MIDDLEWARE=None, - MIDDLEWARE_CLASSES=[ - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware', - ], -) -class FlatpageMiddlewareClassesTests(FlatpageMiddlewareTests): - pass - - @modify_settings(INSTALLED_APPS={'append': 'django.contrib.flatpages'}) @override_settings( APPEND_SLASH=True, @@ -190,19 +172,3 @@ def test_redirect_fallback_flatpage_root(self): response = self.client.get('/') self.assertContains(response, "

Root

") - - -@ignore_warnings(category=RemovedInDjango20Warning) -@override_settings( - MIDDLEWARE=None, - MIDDLEWARE_CLASSES=[ - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware', - ], -) -class FlatpageAppendSlashMiddlewareClassesTests(FlatpageMiddlewareAppendSlashTests): - pass diff --git a/tests/middleware_exceptions/test_legacy.py b/tests/middleware_exceptions/test_legacy.py deleted file mode 100644 index b35deb90b225..000000000000 --- a/tests/middleware_exceptions/test_legacy.py +++ /dev/null @@ -1,908 +0,0 @@ -import sys - -from django.core.signals import got_request_exception -from django.http import HttpResponse -from django.template import engines -from django.template.response import TemplateResponse -from django.test import SimpleTestCase, override_settings -from django.test.utils import ignore_warnings -from django.utils.deprecation import MiddlewareMixin, RemovedInDjango20Warning - -from .tests import MiddlewareNotUsedTests - - -class TestException(Exception): - pass - - -# A middleware base class that tracks which methods have been called -class TestMiddleware(MiddlewareMixin): - def __init__(self, get_response=None): - self.process_request_called = False - self.process_view_called = False - self.process_response_called = False - self.process_template_response_called = False - self.process_exception_called = False - self.get_response = get_response - - def process_request(self, request): - self.process_request_called = True - - def process_view(self, request, view_func, view_args, view_kwargs): - self.process_view_called = True - - def process_template_response(self, request, response): - self.process_template_response_called = True - return response - - def process_response(self, request, response): - self.process_response_called = True - return response - - def process_exception(self, request, exception): - self.process_exception_called = True - - -# Middleware examples that do the right thing -class RequestMiddleware(TestMiddleware): - def process_request(self, request): - super(RequestMiddleware, self).process_request(request) - return HttpResponse('Request Middleware') - - -class ViewMiddleware(TestMiddleware): - def process_view(self, request, view_func, view_args, view_kwargs): - super(ViewMiddleware, self).process_view(request, view_func, view_args, view_kwargs) - return HttpResponse('View Middleware') - - -class TemplateResponseViewMiddleware(TestMiddleware): - def process_view(self, request, view_func, view_args, view_kwargs): - super(TemplateResponseViewMiddleware, self).process_view(request, view_func, view_args, view_kwargs) - template = engines['django'].from_string('TemplateResponse View Middleware') - return TemplateResponse(request, template) - - -class ResponseMiddleware(TestMiddleware): - def process_response(self, request, response): - super(ResponseMiddleware, self).process_response(request, response) - return HttpResponse('Response Middleware') - - -class ContentAccessingResponseMiddleware(TestMiddleware): - def process_response(self, request, response): - super(ContentAccessingResponseMiddleware, self).process_response(request, response) - return HttpResponse('Content-accessing Response Middleware: %d' % len(response.content)) - - -class TemplateResponseMiddleware(TestMiddleware): - def process_template_response(self, request, response): - super(TemplateResponseMiddleware, self).process_template_response(request, response) - template = engines['django'].from_string('Template Response Middleware') - return TemplateResponse(request, template) - - -class ExceptionMiddleware(TestMiddleware): - def process_exception(self, request, exception): - super(ExceptionMiddleware, self).process_exception(request, exception) - return HttpResponse('Exception Middleware') - - -# Sample middlewares that raise exceptions -class BadRequestMiddleware(TestMiddleware): - def process_request(self, request): - super(BadRequestMiddleware, self).process_request(request) - raise TestException('Test Request Exception') - - -class BadViewMiddleware(TestMiddleware): - def process_view(self, request, view_func, view_args, view_kwargs): - super(BadViewMiddleware, self).process_view(request, view_func, view_args, view_kwargs) - raise TestException('Test View Exception') - - -class BadTemplateResponseMiddleware(TestMiddleware): - def process_template_response(self, request, response): - super(BadTemplateResponseMiddleware, self).process_template_response(request, response) - raise TestException('Test Template Response Exception') - - -class BadResponseMiddleware(TestMiddleware): - def process_response(self, request, response): - super(BadResponseMiddleware, self).process_response(request, response) - raise TestException('Test Response Exception') - - -class BadExceptionMiddleware(TestMiddleware): - def process_exception(self, request, exception): - super(BadExceptionMiddleware, self).process_exception(request, exception) - raise TestException('Test Exception Exception') - - -# Sample middlewares that omit to return an HttpResonse -class NoTemplateResponseMiddleware(TestMiddleware): - def process_template_response(self, request, response): - super(NoTemplateResponseMiddleware, self).process_template_response(request, response) - - -class NoResponseMiddleware(TestMiddleware): - def process_response(self, request, response): - super(NoResponseMiddleware, self).process_response(request, response) - - -@ignore_warnings(category=RemovedInDjango20Warning) -@override_settings( - ROOT_URLCONF='middleware_exceptions.urls', - MIDDLEWARE_CLASSES=['django.middleware.common.CommonMiddleware'], - MIDDLEWARE=None, -) -class BaseMiddlewareExceptionTest(SimpleTestCase): - - def setUp(self): - self.exceptions = [] - got_request_exception.connect(self._on_request_exception) - self.client.handler.load_middleware() - - def tearDown(self): - got_request_exception.disconnect(self._on_request_exception) - self.exceptions = [] - - def _on_request_exception(self, sender, request, **kwargs): - self.exceptions.append(sys.exc_info()) - - def _add_middleware(self, middleware): - self.client.handler._request_middleware.insert(0, middleware.process_request) - self.client.handler._view_middleware.insert(0, middleware.process_view) - self.client.handler._template_response_middleware.append(middleware.process_template_response) - self.client.handler._response_middleware.append(middleware.process_response) - self.client.handler._exception_middleware.append(middleware.process_exception) - - def assert_exceptions_handled(self, url, errors, extra_error=None): - try: - self.client.get(url) - except TestException: - # Test client intentionally re-raises any exceptions being raised - # during request handling. Hence actual testing that exception was - # properly handled is done by relying on got_request_exception - # signal being sent. - pass - except Exception as e: - if type(extra_error) != type(e): - self.fail("Unexpected exception: %s" % e) - self.assertEqual(len(self.exceptions), len(errors)) - for i, error in enumerate(errors): - exception, value, tb = self.exceptions[i] - self.assertEqual(value.args, (error, )) - - def assert_middleware_usage(self, middleware, request, view, template_response, response, exception): - # include the middleware name for easier debugging of failures - self.assertEqual( - ( - middleware.__class__.__name__, - middleware.process_request_called, - middleware.process_view_called, - middleware.process_template_response_called, - middleware.process_response_called, - middleware.process_exception_called, - ), ( - middleware.__class__.__name__, - request, - view, - template_response, - response, - exception, - ) - ) - - -class MiddlewareTests(BaseMiddlewareExceptionTest): - - def test_process_request_middleware(self): - pre_middleware = TestMiddleware() - middleware = RequestMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/view/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, False, False, True, False) - self.assert_middleware_usage(middleware, True, False, False, True, False) - self.assert_middleware_usage(post_middleware, False, False, False, True, False) - - def test_process_view_middleware(self): - pre_middleware = TestMiddleware() - middleware = ViewMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/view/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, False, False, True, False) - - def test_process_response_middleware(self): - pre_middleware = TestMiddleware() - middleware = ResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/view/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, True, False, True, False) - - def test_process_template_response_middleware(self): - pre_middleware = TestMiddleware() - middleware = TemplateResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/template_response/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, True, True, False) - self.assert_middleware_usage(middleware, True, True, True, True, False) - self.assert_middleware_usage(post_middleware, True, True, True, True, False) - - def test_process_exception_middleware(self): - pre_middleware = TestMiddleware() - middleware = ExceptionMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/view/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, True, False, True, False) - - def test_process_request_middleware_not_found(self): - pre_middleware = TestMiddleware() - middleware = RequestMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/not_found/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, False, False, True, False) - self.assert_middleware_usage(middleware, True, False, False, True, False) - self.assert_middleware_usage(post_middleware, False, False, False, True, False) - - def test_process_view_middleware_not_found(self): - pre_middleware = TestMiddleware() - middleware = ViewMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/not_found/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, False, False, True, False) - - def test_process_template_response_middleware_not_found(self): - pre_middleware = TestMiddleware() - middleware = TemplateResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/not_found/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, True) - self.assert_middleware_usage(middleware, True, True, False, True, True) - self.assert_middleware_usage(post_middleware, True, True, False, True, True) - - def test_process_response_middleware_not_found(self): - pre_middleware = TestMiddleware() - middleware = ResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/not_found/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, True) - self.assert_middleware_usage(middleware, True, True, False, True, True) - self.assert_middleware_usage(post_middleware, True, True, False, True, True) - - def test_process_exception_middleware_not_found(self): - pre_middleware = TestMiddleware() - middleware = ExceptionMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/not_found/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(middleware, True, True, False, True, True) - self.assert_middleware_usage(post_middleware, True, True, False, True, True) - - def test_process_request_middleware_exception(self): - pre_middleware = TestMiddleware() - middleware = RequestMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/error/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, False, False, True, False) - self.assert_middleware_usage(middleware, True, False, False, True, False) - self.assert_middleware_usage(post_middleware, False, False, False, True, False) - - def test_process_view_middleware_exception(self): - pre_middleware = TestMiddleware() - middleware = ViewMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/error/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, False, False, True, False) - - def test_process_response_middleware_exception(self): - pre_middleware = TestMiddleware() - middleware = ResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/error/', ['Error in view'], Exception()) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, True) - self.assert_middleware_usage(middleware, True, True, False, True, True) - self.assert_middleware_usage(post_middleware, True, True, False, True, True) - - def test_process_exception_middleware_exception(self): - pre_middleware = TestMiddleware() - middleware = ExceptionMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/error/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(middleware, True, True, False, True, True) - self.assert_middleware_usage(post_middleware, True, True, False, True, True) - - def test_process_request_middleware_null_view(self): - pre_middleware = TestMiddleware() - middleware = RequestMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/null_view/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, False, False, True, False) - self.assert_middleware_usage(middleware, True, False, False, True, False) - self.assert_middleware_usage(post_middleware, False, False, False, True, False) - - def test_process_view_middleware_null_view(self): - pre_middleware = TestMiddleware() - middleware = ViewMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/null_view/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, False, False, True, False) - - def test_process_response_middleware_null_view(self): - pre_middleware = TestMiddleware() - middleware = ResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled( - '/middleware_exceptions/null_view/', [ - "The view middleware_exceptions.views.null_view didn't return " - "an HttpResponse object. It returned None instead." - ], - ValueError() - ) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, True, False, True, False) - - def test_process_exception_middleware_null_view(self): - pre_middleware = TestMiddleware() - middleware = ExceptionMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled( - '/middleware_exceptions/null_view/', [ - "The view middleware_exceptions.views.null_view didn't return " - "an HttpResponse object. It returned None instead." - ], - ValueError() - ) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, True, False, True, False) - - def test_process_request_middleware_permission_denied(self): - pre_middleware = TestMiddleware() - middleware = RequestMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, False, False, True, False) - self.assert_middleware_usage(middleware, True, False, False, True, False) - self.assert_middleware_usage(post_middleware, False, False, False, True, False) - - def test_process_view_middleware_permission_denied(self): - pre_middleware = TestMiddleware() - middleware = ViewMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, False, False, True, False) - - def test_process_response_middleware_permission_denied(self): - pre_middleware = TestMiddleware() - middleware = ResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, True) - self.assert_middleware_usage(middleware, True, True, False, True, True) - self.assert_middleware_usage(post_middleware, True, True, False, True, True) - - def test_process_exception_middleware_permission_denied(self): - pre_middleware = TestMiddleware() - middleware = ExceptionMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(middleware, True, True, False, True, True) - self.assert_middleware_usage(post_middleware, True, True, False, True, True) - - def test_process_template_response_error(self): - middleware = TestMiddleware() - self._add_middleware(middleware) - self.assert_exceptions_handled('/middleware_exceptions/template_response_error/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(middleware, True, True, True, True, False) - - def test_templateresponse_from_process_view_rendered(self): - view_middleware = TemplateResponseViewMiddleware() - # ContentAccessingResponseMiddleware tries to access response.content - # in its process_response(). - post_middleware = ContentAccessingResponseMiddleware() - self._add_middleware(view_middleware) - self._add_middleware(post_middleware) - self.assert_exceptions_handled('/middleware_exceptions/view/', []) - self.assert_middleware_usage(view_middleware, True, True, True, True, False) - self.assert_middleware_usage(post_middleware, True, True, True, True, False) - - def test_templateresponse_from_process_view_passed_to_template_response_middleware(self): - """ - TemplateResponses returned from process_view() should be passed to any - process_template_response(). - """ - view_middleware = TemplateResponseViewMiddleware() - resp_middleware = TemplateResponseMiddleware() - self._add_middleware(view_middleware) - self._add_middleware(resp_middleware) - self.assert_exceptions_handled('/middleware_exceptions/view/', []) - self.assert_middleware_usage(view_middleware, True, True, True, True, False) - self.assert_middleware_usage(resp_middleware, True, True, True, True, False) - - -class BadMiddlewareTests(BaseMiddlewareExceptionTest): - - def test_process_request_bad_middleware(self): - pre_middleware = TestMiddleware() - bad_middleware = BadRequestMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/view/', ['Test Request Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, False, False, True, False) - self.assert_middleware_usage(bad_middleware, True, False, False, True, False) - self.assert_middleware_usage(post_middleware, False, False, False, True, False) - - def test_process_view_bad_middleware(self): - pre_middleware = TestMiddleware() - bad_middleware = BadViewMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/view/', ['Test View Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(bad_middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, False, False, True, False) - - def test_process_template_response_bad_middleware(self): - pre_middleware = TestMiddleware() - bad_middleware = BadTemplateResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled( - '/middleware_exceptions/template_response/', - ['Test Template Response Exception'] - ) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(bad_middleware, True, True, True, True, False) - self.assert_middleware_usage(post_middleware, True, True, True, True, False) - - def test_process_response_bad_middleware(self): - pre_middleware = TestMiddleware() - bad_middleware = BadResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/view/', ['Test Response Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, False, False) - self.assert_middleware_usage(bad_middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, True, False, True, False) - - def test_process_exception_bad_middleware(self): - pre_middleware = TestMiddleware() - bad_middleware = BadExceptionMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/view/', []) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(bad_middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, True, False, True, False) - - def test_process_request_bad_middleware_not_found(self): - pre_middleware = TestMiddleware() - bad_middleware = BadRequestMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/not_found/', ['Test Request Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, False, False, True, False) - self.assert_middleware_usage(bad_middleware, True, False, False, True, False) - self.assert_middleware_usage(post_middleware, False, False, False, True, False) - - def test_process_view_bad_middleware_not_found(self): - pre_middleware = TestMiddleware() - bad_middleware = BadViewMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/not_found/', ['Test View Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(bad_middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, False, False, True, False) - - def test_process_response_bad_middleware_not_found(self): - pre_middleware = TestMiddleware() - bad_middleware = BadResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/not_found/', ['Test Response Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, False, True) - self.assert_middleware_usage(bad_middleware, True, True, False, True, True) - self.assert_middleware_usage(post_middleware, True, True, False, True, True) - - def test_process_exception_bad_middleware_not_found(self): - pre_middleware = TestMiddleware() - bad_middleware = BadExceptionMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/not_found/', ['Test Exception Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(bad_middleware, True, True, False, True, True) - self.assert_middleware_usage(post_middleware, True, True, False, True, True) - - def test_process_request_bad_middleware_exception(self): - pre_middleware = TestMiddleware() - bad_middleware = BadRequestMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/error/', ['Test Request Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, False, False, True, False) - self.assert_middleware_usage(bad_middleware, True, False, False, True, False) - self.assert_middleware_usage(post_middleware, False, False, False, True, False) - - def test_process_view_bad_middleware_exception(self): - pre_middleware = TestMiddleware() - bad_middleware = BadViewMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/error/', ['Test View Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(bad_middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, False, False, True, False) - - def test_process_response_bad_middleware_exception(self): - pre_middleware = TestMiddleware() - bad_middleware = BadResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/error/', ['Error in view', 'Test Response Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, False, True) - self.assert_middleware_usage(bad_middleware, True, True, False, True, True) - self.assert_middleware_usage(post_middleware, True, True, False, True, True) - - def test_process_exception_bad_middleware_exception(self): - pre_middleware = TestMiddleware() - bad_middleware = BadExceptionMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/error/', ['Test Exception Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(bad_middleware, True, True, False, True, True) - self.assert_middleware_usage(post_middleware, True, True, False, True, True) - - def test_process_request_bad_middleware_null_view(self): - pre_middleware = TestMiddleware() - bad_middleware = BadRequestMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/null_view/', ['Test Request Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, False, False, True, False) - self.assert_middleware_usage(bad_middleware, True, False, False, True, False) - self.assert_middleware_usage(post_middleware, False, False, False, True, False) - - def test_process_view_bad_middleware_null_view(self): - pre_middleware = TestMiddleware() - bad_middleware = BadViewMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/null_view/', ['Test View Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(bad_middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, False, False, True, False) - - def test_process_response_bad_middleware_null_view(self): - pre_middleware = TestMiddleware() - bad_middleware = BadResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled( - '/middleware_exceptions/null_view/', [ - "The view middleware_exceptions.views.null_view didn't return " - "an HttpResponse object. It returned None instead.", - 'Test Response Exception' - ] - ) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, False, False) - self.assert_middleware_usage(bad_middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, True, False, True, False) - - def test_process_exception_bad_middleware_null_view(self): - pre_middleware = TestMiddleware() - bad_middleware = BadExceptionMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled( - '/middleware_exceptions/null_view/', [ - "The view middleware_exceptions.views.null_view didn't return " - "an HttpResponse object. It returned None instead." - ], - ValueError() - ) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(bad_middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, True, False, True, False) - - def test_process_request_bad_middleware_permission_denied(self): - pre_middleware = TestMiddleware() - bad_middleware = BadRequestMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', ['Test Request Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, False, False, True, False) - self.assert_middleware_usage(bad_middleware, True, False, False, True, False) - self.assert_middleware_usage(post_middleware, False, False, False, True, False) - - def test_process_view_bad_middleware_permission_denied(self): - pre_middleware = TestMiddleware() - bad_middleware = BadViewMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', ['Test View Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(bad_middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, False, False, True, False) - - def test_process_response_bad_middleware_permission_denied(self): - pre_middleware = TestMiddleware() - bad_middleware = BadResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', ['Test Response Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, False, True) - self.assert_middleware_usage(bad_middleware, True, True, False, True, True) - self.assert_middleware_usage(post_middleware, True, True, False, True, True) - - def test_process_exception_bad_middleware_permission_denied(self): - pre_middleware = TestMiddleware() - bad_middleware = BadExceptionMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(bad_middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', ['Test Exception Exception']) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(bad_middleware, True, True, False, True, True) - self.assert_middleware_usage(post_middleware, True, True, False, True, True) - - def test_process_response_no_response_middleware(self): - pre_middleware = TestMiddleware() - middleware = NoResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled('/middleware_exceptions/view/', [ - "NoResponseMiddleware.process_response didn't return an HttpResponse object. It returned None instead." - ], - ValueError()) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, False, False) - self.assert_middleware_usage(middleware, True, True, False, True, False) - self.assert_middleware_usage(post_middleware, True, True, False, True, False) - - def test_process_template_response_no_response_middleware(self): - pre_middleware = TestMiddleware() - middleware = NoTemplateResponseMiddleware() - post_middleware = TestMiddleware() - self._add_middleware(post_middleware) - self._add_middleware(middleware) - self._add_middleware(pre_middleware) - self.assert_exceptions_handled( - '/middleware_exceptions/template_response/', [ - "NoTemplateResponseMiddleware.process_template_response didn't " - "return an HttpResponse object. It returned None instead." - ], - ValueError() - ) - - # The right middleware methods have been invoked - self.assert_middleware_usage(pre_middleware, True, True, False, True, False) - self.assert_middleware_usage(middleware, True, True, True, True, False) - self.assert_middleware_usage(post_middleware, True, True, True, True, False) - - -@ignore_warnings(category=RemovedInDjango20Warning) -@override_settings( - MIDDLEWARE_CLASSES=['django.middleware.common.CommonMiddleware'], - MIDDLEWARE=None, -) -class MiddlewareNotUsedMiddlewareClassesTests(MiddlewareNotUsedTests): - pass diff --git a/tests/redirects_tests/tests.py b/tests/redirects_tests/tests.py index d566b69006dd..29c88bd1dfaa 100644 --- a/tests/redirects_tests/tests.py +++ b/tests/redirects_tests/tests.py @@ -5,9 +5,7 @@ from django.contrib.sites.models import Site from django.core.exceptions import ImproperlyConfigured from django.test import TestCase, modify_settings, override_settings -from django.test.utils import ignore_warnings from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning @modify_settings(MIDDLEWARE={'append': 'django.contrib.redirects.middleware.RedirectFallbackMiddleware'}) @@ -44,20 +42,6 @@ def test_response_gone(self): response = self.client.get('/initial') self.assertEqual(response.status_code, 410) - @ignore_warnings(category=RemovedInDjango20Warning) - @override_settings(MIDDLEWARE=None) - @modify_settings(MIDDLEWARE_CLASSES={'append': 'django.contrib.redirects.middleware.RedirectFallbackMiddleware'}) - def test_redirect_middleware_classes(self): - self.test_redirect() - - @ignore_warnings(category=RemovedInDjango20Warning) - @override_settings(MIDDLEWARE=None) - @modify_settings(MIDDLEWARE_CLASSES={'append': 'django.contrib.redirects.middleware.RedirectFallbackMiddleware'}) - def test_more_redirects_middleware_classes(self): - self.test_redirect_with_append_slash() - self.test_redirect_with_append_slash_and_query_string() - self.test_response_gone() - @modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'}) def test_sites_not_installed(self): with self.assertRaises(ImproperlyConfigured): diff --git a/tests/template_tests/test_response.py b/tests/template_tests/test_response.py index 60839f5c6b2e..fa851a93f297 100644 --- a/tests/template_tests/test_response.py +++ b/tests/template_tests/test_response.py @@ -11,8 +11,8 @@ from django.test import ( RequestFactory, SimpleTestCase, modify_settings, override_settings, ) -from django.test.utils import ignore_warnings, require_jinja2 -from django.utils.deprecation import MiddlewareMixin, RemovedInDjango20Warning +from django.test.utils import require_jinja2 +from django.utils.deprecation import MiddlewareMixin from .utils import TEMPLATE_DIR @@ -362,34 +362,3 @@ def test_middleware_caching(self): self.assertEqual(response2.status_code, 200) self.assertNotEqual(response.content, response2.content) - - -@ignore_warnings(category=RemovedInDjango20Warning) -@override_settings( - MIDDLEWARE=None, - MIDDLEWARE_CLASSES=[ - 'django.middleware.cache.FetchFromCacheMiddleware', - 'django.middleware.cache.UpdateCacheMiddleware', - ], - CACHE_MIDDLEWARE_SECONDS=2.0, - ROOT_URLCONF='template_tests.alternate_urls' -) -class CacheMiddlewareClassesTest(SimpleTestCase): - def test_middleware_caching(self): - response = self.client.get('/template_response_view/') - self.assertEqual(response.status_code, 200) - - time.sleep(1.0) - - response2 = self.client.get('/template_response_view/') - self.assertEqual(response2.status_code, 200) - - self.assertEqual(response.content, response2.content) - - time.sleep(2.0) - - # Let the cache expire and test again - response2 = self.client.get('/template_response_view/') - self.assertEqual(response2.status_code, 200) - - self.assertNotEqual(response.content, response2.content) diff --git a/tests/view_tests/tests/test_csrf.py b/tests/view_tests/tests/test_csrf.py index 23dab04cd67e..d0dd07b9e177 100644 --- a/tests/view_tests/tests/test_csrf.py +++ b/tests/view_tests/tests/test_csrf.py @@ -2,8 +2,6 @@ from django.test import ( Client, RequestFactory, SimpleTestCase, override_settings, ) -from django.test.utils import ignore_warnings -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.translation import override from django.views.csrf import CSRF_FAILURE_TEMPLATE_NAME, csrf_failure @@ -40,33 +38,6 @@ def test_translation(self): "CSRF-verificatie mislukt. Verzoek afgebroken.", status_code=403) - @ignore_warnings(category=RemovedInDjango20Warning) - @override_settings( - USE_I18N=True, - MIDDLEWARE=None, - MIDDLEWARE_CLASSES=[ - 'django.middleware.locale.LocaleMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - ], - ) - def test_translation_middleware_classes(self): - """ - An invalid request is rejected with a localized error message. - """ - response = self.client.post('/') - self.assertContains(response, "Forbidden", status_code=403) - self.assertContains(response, - "CSRF verification failed. Request aborted.", - status_code=403) - - with self.settings(LANGUAGE_CODE='nl'), override('en-us'): - response = self.client.post('/') - self.assertContains(response, "Verboden", status_code=403) - self.assertContains(response, - "CSRF-verificatie mislukt. Verzoek afgebroken.", - status_code=403) - @override_settings( SECURE_PROXY_SSL_HEADER=('HTTP_X_FORWARDED_PROTO', 'https') ) diff --git a/tests/view_tests/tests/test_i18n.py b/tests/view_tests/tests/test_i18n.py index bde0ad42d482..725d72890ea1 100644 --- a/tests/view_tests/tests/test_i18n.py +++ b/tests/view_tests/tests/test_i18n.py @@ -10,11 +10,9 @@ SimpleTestCase, TestCase, modify_settings, override_settings, ) from django.test.selenium import SeleniumTestCase -from django.test.utils import ignore_warnings from django.urls import reverse from django.utils import six from django.utils._os import upath -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.translation import ( LANGUAGE_SESSION_KEY, get_language, override, ) @@ -157,27 +155,6 @@ def test_setlang_cookie(self): self.assertEqual(language_cookie['path'], '/test/') self.assertEqual(language_cookie['max-age'], 3600 * 7 * 2) - @ignore_warnings(category=RemovedInDjango20Warning) - def test_setlang_cookie_middleware_classes(self): - # we force saving language to a cookie rather than a session - # by excluding session middleware and those which do require it - test_settings = dict( - MIDDLEWARE=None, - MIDDLEWARE_CLASSES=['django.middleware.common.CommonMiddleware'], - LANGUAGE_COOKIE_NAME='mylanguage', - LANGUAGE_COOKIE_AGE=3600 * 7 * 2, - LANGUAGE_COOKIE_DOMAIN='.example.com', - LANGUAGE_COOKIE_PATH='/test/', - ) - with self.settings(**test_settings): - post_data = dict(language='pl', next='/views/') - response = self.client.post('/i18n/setlang/', data=post_data) - language_cookie = response.cookies.get('mylanguage') - self.assertEqual(language_cookie.value, 'pl') - self.assertEqual(language_cookie['domain'], '.example.com') - self.assertEqual(language_cookie['path'], '/test/') - self.assertEqual(language_cookie['max-age'], 3600 * 7 * 2) - def test_setlang_decodes_http_referer_url(self): """ The set_language view decodes the HTTP_REFERER URL. @@ -207,28 +184,6 @@ def test_lang_from_translated_i18n_pattern(self): ) self.assertRedirects(response, '/en/translated/') - @ignore_warnings(category=RemovedInDjango20Warning) - @override_settings( - MIDDLEWARE=None, - MIDDLEWARE_CLASSES=[ - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.locale.LocaleMiddleware', - ], - ) - def test_lang_from_translated_i18n_pattern_middleware_classes(self): - response = self.client.post( - '/i18n/setlang/', data={'language': 'nl'}, - follow=True, HTTP_REFERER='/en/translated/' - ) - self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], 'nl') - self.assertRedirects(response, '/nl/vertaald/') - # And reverse - response = self.client.post( - '/i18n/setlang/', data={'language': 'en'}, - follow=True, HTTP_REFERER='/nl/vertaald/' - ) - self.assertRedirects(response, '/en/translated/') - @override_settings(ROOT_URLCONF='view_tests.urls') class JsI18NTests(SimpleTestCase): From 401c5b2e42bf9134d9221f446765dd0777306f0b Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 13:58:42 -0500 Subject: [PATCH 0051/3180] Refs #23957 -- Removed the useless SessionAuthenticationMiddleware. --- django/contrib/auth/middleware.py | 13 ------------- docs/releases/2.0.txt | 4 +++- docs/topics/auth/default.txt | 9 --------- 3 files changed, 3 insertions(+), 23 deletions(-) diff --git a/django/contrib/auth/middleware.py b/django/contrib/auth/middleware.py index f179894e7311..f39a17bb9cd9 100644 --- a/django/contrib/auth/middleware.py +++ b/django/contrib/auth/middleware.py @@ -24,19 +24,6 @@ def process_request(self, request): request.user = SimpleLazyObject(lambda: get_user(request)) -class SessionAuthenticationMiddleware(MiddlewareMixin): - """ - Formerly, a middleware for invalidating a user's sessions that don't - correspond to the user's current session authentication hash. However, it - caused the "Vary: Cookie" header on all responses. - - It's now a shim to allow a single settings file to more easily support - multiple versions of Django. Will be RemovedInDjango20Warning. - """ - def process_request(self, request): - pass - - class RemoteUserMiddleware(MiddlewareMixin): """ Middleware for utilizing Web-server-provided authentication. diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index ec5e0aada9be..3ae58ed858a5 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -212,7 +212,9 @@ Database backend API Miscellaneous ------------- -* ... +* The ``SessionAuthenticationMiddleware`` class is removed. It provided no + functionality since session authentication is unconditionally enabled in + Django 1.10. .. _deprecated-features-2.0: diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt index 5869ff0d30c9..b1f111c092a2 100644 --- a/docs/topics/auth/default.txt +++ b/docs/topics/auth/default.txt @@ -824,15 +824,6 @@ user to the login page or issue an HTTP 403 Forbidden response. Session invalidation on password change ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionchanged:: 1.10 - - Session verification is enabled and mandatory in Django 1.10 (there's no - way to disable it) regardless of whether or not - ``SessionAuthenticationMiddleware`` is enabled. In older - versions, this protection only applies if - ``django.contrib.auth.middleware.SessionAuthenticationMiddleware`` - is enabled in :setting:`MIDDLEWARE`. - If your :setting:`AUTH_USER_MODEL` inherits from :class:`~django.contrib.auth.models.AbstractBaseUser` or implements its own :meth:`~django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash()` From e27e4c03399f610e0db1fb9b881095d762fda2b7 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 2 Jan 2017 10:25:57 -0500 Subject: [PATCH 0052/3180] Removed versionadded/changed annotations for 1.10. --- docs/howto/auth-remote-user.txt | 4 -- docs/howto/custom-management-commands.txt | 2 - docs/howto/custom-model-fields.txt | 4 -- docs/howto/writing-migrations.txt | 2 - .../contributing/writing-code/unit-tests.txt | 2 - docs/ref/applications.txt | 4 -- docs/ref/class-based-views/base.txt | 4 -- docs/ref/contrib/admin/index.txt | 21 ------- docs/ref/contrib/auth.txt | 25 -------- docs/ref/contrib/gis/db-api.txt | 6 -- docs/ref/contrib/gis/functions.txt | 20 ------ docs/ref/contrib/gis/gdal.txt | 18 ------ docs/ref/contrib/gis/geoquerysets.txt | 14 ----- docs/ref/contrib/gis/geos.txt | 62 ------------------- docs/ref/contrib/gis/serializers.txt | 4 -- docs/ref/contrib/postgres/lookups.txt | 2 - docs/ref/contrib/postgres/operations.txt | 2 - docs/ref/contrib/postgres/search.txt | 6 -- docs/ref/contrib/staticfiles.txt | 9 --- docs/ref/csrf.txt | 5 -- docs/ref/django-admin.txt | 26 -------- docs/ref/exceptions.txt | 4 -- docs/ref/files/storage.txt | 8 --- docs/ref/forms/api.txt | 2 - docs/ref/forms/widgets.txt | 4 -- docs/ref/middleware.txt | 8 --- docs/ref/migration-operations.txt | 13 ---- docs/ref/models/database-functions.txt | 4 -- docs/ref/models/expressions.txt | 7 --- docs/ref/models/fields.txt | 4 -- docs/ref/models/instances.txt | 11 ---- docs/ref/models/options.txt | 4 -- docs/ref/models/querysets.txt | 11 ---- docs/ref/request-response.txt | 13 ---- docs/ref/settings.txt | 33 ---------- docs/ref/signals.txt | 8 --- docs/ref/templates/api.txt | 9 --- docs/ref/templates/builtins.txt | 22 ------- docs/ref/utils.txt | 4 -- docs/ref/validators.txt | 4 -- docs/ref/views.txt | 16 ----- docs/topics/auth/customizing.txt | 9 --- docs/topics/auth/default.txt | 12 ---- docs/topics/auth/passwords.txt | 2 - docs/topics/checks.txt | 4 -- docs/topics/db/managers.txt | 7 --- docs/topics/db/models.txt | 14 ----- docs/topics/db/multi-db.txt | 5 -- docs/topics/forms/media.txt | 4 -- docs/topics/forms/modelforms.txt | 10 --- docs/topics/http/middleware.txt | 9 --- docs/topics/i18n/translation.txt | 19 ------ docs/topics/logging.txt | 6 -- docs/topics/migrations.txt | 9 --- docs/topics/serialization.txt | 4 -- docs/topics/templates.txt | 4 -- docs/topics/testing/tools.txt | 13 ---- 57 files changed, 562 deletions(-) diff --git a/docs/howto/auth-remote-user.txt b/docs/howto/auth-remote-user.txt index b695fbd6478c..7bc9ef08c0d9 100644 --- a/docs/howto/auth-remote-user.txt +++ b/docs/howto/auth-remote-user.txt @@ -75,10 +75,6 @@ regardless of ``AUTHENTICATION_BACKENDS``. :class:`~django.contrib.auth.backends.AllowAllUsersRemoteUserBackend` if you want to allow them to. - .. versionchanged:: 1.10 - - In older versions, inactive users weren't rejected as described above. - If your authentication mechanism uses a custom HTTP header and not ``REMOTE_USER``, you can subclass ``RemoteUserMiddleware`` and set the ``header`` attribute to the desired ``request.META`` key. For example:: diff --git a/docs/howto/custom-management-commands.txt b/docs/howto/custom-management-commands.txt index e6482a0da823..620681ab3532 100644 --- a/docs/howto/custom-management-commands.txt +++ b/docs/howto/custom-management-commands.txt @@ -227,8 +227,6 @@ All attributes can be set in your derived class and can be used in .. attribute:: BaseCommand.requires_migrations_checks - .. versionadded:: 1.10 - A boolean; if ``True``, the command prints a warning if the set of migrations on disk don't match the migrations in the database. A warning doesn't prevent the command from executing. Default value is ``False``. diff --git a/docs/howto/custom-model-fields.txt b/docs/howto/custom-model-fields.txt index 3c71f8f004ed..a5f204827265 100644 --- a/docs/howto/custom-model-fields.txt +++ b/docs/howto/custom-model-fields.txt @@ -464,10 +464,6 @@ need the foreign keys that point to that field to use the same data type:: def rel_db_type(self, connection): return 'integer UNSIGNED' -.. versionadded:: 1.10 - - The :meth:`~Field.rel_db_type` method was added. - .. _converting-values-to-python-objects: Converting values to Python objects diff --git a/docs/howto/writing-migrations.txt b/docs/howto/writing-migrations.txt index f850e927ebcc..35964f7ce851 100644 --- a/docs/howto/writing-migrations.txt +++ b/docs/howto/writing-migrations.txt @@ -189,8 +189,6 @@ the respective field according to your needs. Non-atomic migrations ~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 1.10 - On databases that support DDL transactions (SQLite and PostgreSQL), migrations will run inside a transaction by default. For use cases such as performing data migrations on large tables, you may want to prevent a migration from running in diff --git a/docs/internals/contributing/writing-code/unit-tests.txt b/docs/internals/contributing/writing-code/unit-tests.txt index 1bed50389827..7c0e65bf7167 100644 --- a/docs/internals/contributing/writing-code/unit-tests.txt +++ b/docs/internals/contributing/writing-code/unit-tests.txt @@ -428,8 +428,6 @@ a temporary ``Apps`` instance:: .. function:: django.test.utils.isolate_apps(*app_labels, attr_name=None, kwarg_name=None) -.. versionadded:: 1.10 - Since this pattern involves a lot of boilerplate, Django provides the :func:`~django.test.utils.isolate_apps` decorator. It's used like this:: diff --git a/docs/ref/applications.txt b/docs/ref/applications.txt index c3a06ab85543..8663e6522290 100644 --- a/docs/ref/applications.txt +++ b/docs/ref/applications.txt @@ -401,10 +401,6 @@ application registry. :setting:`FORCE_SCRIPT_NAME` if defined, or ``/`` otherwise. * Initializing the application registry. - .. versionchanged:: 1.10 - - The ability to set the URL resolver script prefix is new. - This function is called automatically: * When running an HTTP server via Django's WSGI support. diff --git a/docs/ref/class-based-views/base.txt b/docs/ref/class-based-views/base.txt index 80904ef76f53..c6959ca9efa0 100644 --- a/docs/ref/class-based-views/base.txt +++ b/docs/ref/class-based-views/base.txt @@ -22,10 +22,6 @@ MRO is an acronym for Method Resolution Order. this base class. It isn't strictly a generic view and thus can also be imported from ``django.views``. - .. versionchanged:: 1.10 - - The ability to import from ``django.views`` was added. - **Method Flowchart** 1. :meth:`dispatch()` diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index b08d17421e1f..1fa3843c73c3 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -1151,8 +1151,6 @@ subclass:: .. attribute:: ModelAdmin.save_as_continue - .. versionadded:: 1.10 - When :attr:`save_as=True `, the default redirect after saving the new object is to the change view for that object. If you set ``save_as_continue=False``, the redirect will be to the changelist view. @@ -1950,10 +1948,6 @@ To avoid conflicts with user-supplied scripts or libraries, Django's jQuery in your own admin JavaScript without including a second copy, you can use the ``django.jQuery`` object on changelist and add/edit views. -.. versionchanged:: 1.10 - - The embedded jQuery was upgraded from 2.1.4 to 2.2.3. - The :class:`ModelAdmin` class requires jQuery by default, so there is no need to add jQuery to your ``ModelAdmin``’s list of media resources unless you have a specific need. For example, if you require the jQuery library to be in the @@ -2100,8 +2094,6 @@ The ``InlineModelAdmin`` class adds: .. attribute:: InlineModelAdmin.classes - .. versionadded:: 1.10 - A list or tuple containing extra CSS classes to apply to the fieldset that is rendered for the inlines. Defaults to ``None``. As with classes configured in :attr:`~ModelAdmin.fieldsets`, inlines with a ``collapse`` @@ -2588,11 +2580,6 @@ Templates can override or extend base admin templates as described in the current request has ``request.META['SCRIPT_NAME']`` set and uses that value if ``site_url`` isn't set to something other than ``/``. - .. versionchanged:: 1.10 - - The ``SCRIPT_NAME`` support described in the previous paragraph was - added. - .. attribute:: AdminSite.index_title The text to put at the top of the admin index page (a string). By default, @@ -2892,12 +2879,6 @@ password box. advised to use the :meth:`get_change_message` method to retrieve this value instead of accessing it directly. - .. versionchanged:: 1.10 - - Previously, this attribute was always a plain string. It is - now JSON-structured so that the message can be translated in the current - user language. Old messages are untouched. - ``LogEntry`` methods -------------------- @@ -2907,8 +2888,6 @@ password box. .. method:: LogEntry.get_change_message() - .. versionadded:: 1.10 - Formats and translates :attr:`change_message` into the current user language. Messages created before Django 1.10 will always be displayed in the language in which they were logged. diff --git a/docs/ref/contrib/auth.txt b/docs/ref/contrib/auth.txt index 87dd58005121..c049deb4390e 100644 --- a/docs/ref/contrib/auth.txt +++ b/docs/ref/contrib/auth.txt @@ -41,10 +41,6 @@ Fields on Python 2, with the option to customize the behavior using :attr:`.User.username_validator`. - .. versionchanged:: 1.10 - - The ``max_length`` increased from 30 to 150 characters. - .. attribute:: first_name Optional. 30 characters or fewer. @@ -99,13 +95,6 @@ Fields authentication in the Django admin all return ``False`` for inactive users. - .. versionchanged:: 1.10 - - In older versions, - :class:`~django.contrib.auth.backends.ModelBackend` and - :class:`~django.contrib.auth.backends.RemoteUserBackend` allowed - inactive users to authenticate. - .. attribute:: is_superuser Boolean. Designates that this user has all permissions without @@ -147,8 +136,6 @@ Attributes .. attribute:: username_validator - .. versionadded:: 1.10 - Points to a validator instance used to validate usernames. Defaults to :class:`validators.UnicodeUsernameValidator` on Python 3 and :class:`validators.ASCIIUsernameValidator` on Python 2. @@ -402,16 +389,12 @@ Validators .. class:: validators.ASCIIUsernameValidator - .. versionadded:: 1.10 - A field validator allowing only ASCII letters, in addition to ``@``, ``.``, ``+``, ``-``, and ``_``. The default validator for ``User.username`` on Python 2. .. class:: validators.UnicodeUsernameValidator - .. versionadded:: 1.10 - A field validator allowing Unicode letters, in addition to ``@``, ``.``, ``+``, ``-``, and ``_``. The default validator for ``User.username`` on Python 3. @@ -568,8 +551,6 @@ The following backends are available in :mod:`django.contrib.auth.backends`: .. method:: ModelBackend.user_can_authenticate() - .. versionadded:: 1.10 - Returns whether the user is allowed to authenticate. To match the behavior of :class:`~django.contrib.auth.forms.AuthenticationForm` which :meth:`prohibits inactive users from logging in @@ -581,8 +562,6 @@ The following backends are available in :mod:`django.contrib.auth.backends`: .. class:: AllowAllUsersModelBackend - .. versionadded:: 1.10 - Same as :class:`ModelBackend` except that it doesn't reject inactive users because :meth:`~ModelBackend.user_can_authenticate` always returns ``True``. @@ -637,8 +616,6 @@ The following backends are available in :mod:`django.contrib.auth.backends`: .. method:: RemoteUserBackend.user_can_authenticate() - .. versionadded:: 1.10 - Returns whether the user is allowed to authenticate. This method returns ``False`` for users with :attr:`is_active=False `. Custom user models that don't @@ -647,8 +624,6 @@ The following backends are available in :mod:`django.contrib.auth.backends`: .. class:: AllowAllUsersRemoteUserBackend - .. versionadded:: 1.10 - Same as :class:`RemoteUserBackend` except that it doesn't reject inactive users because :attr:`~RemoteUserBackend.user_can_authenticate` always returns ``True``. diff --git a/docs/ref/contrib/gis/db-api.txt b/docs/ref/contrib/gis/db-api.txt index 2ed758db2860..daa32d75ec3a 100644 --- a/docs/ref/contrib/gis/db-api.txt +++ b/docs/ref/contrib/gis/db-api.txt @@ -56,10 +56,6 @@ Raster Support lookups are available for raster fields, but spatial database functions and aggregates aren't implemented for raster fields. -.. versionchanged:: 1.10 - - ``RasterField`` now supports spatial lookups. - Creating and Saving Models with Geometry Fields =============================================== @@ -173,8 +169,6 @@ GeoJSON , WKT, or HEXEWKB), and ``rst`` is a Raster Lookups -------------- -.. versionadded:: 1.10 - The raster lookup syntax is similar to the syntax for geometries. The only difference is that a band index can be specified as additional input. If no band index is specified, the first band is used by default (index ``0``). In that diff --git a/docs/ref/contrib/gis/functions.txt b/docs/ref/contrib/gis/functions.txt index 1fbe1fa21263..f60c3f3f6ee2 100644 --- a/docs/ref/contrib/gis/functions.txt +++ b/docs/ref/contrib/gis/functions.txt @@ -202,10 +202,6 @@ Accepts two geographic fields or expressions and returns the geometric difference, that is the part of geometry A that does not intersect with geometry B. -.. versionchanged:: 1.10 - - MySQL support was added. - ``Distance`` ============ @@ -288,10 +284,6 @@ representation of the geometry. The ``precision`` keyword argument controls the number of characters in the result. -.. versionchanged:: 1.10 - - SpatiaLite support was added. - __ https://en.wikipedia.org/wiki/Geohash ``Intersection`` @@ -304,17 +296,11 @@ __ https://en.wikipedia.org/wiki/Geohash Accepts two geographic fields or expressions and returns the geometric intersection between them. -.. versionchanged:: 1.10 - - MySQL support was added. - ``IsValid`` =========== .. class:: IsValid(expr) -.. versionadded:: 1.10 - *Availability*: PostGIS, Oracle, SpatiaLite (LWGEOM) Accepts a geographic field or expression and tests if the value is well formed. @@ -351,8 +337,6 @@ resource-intensive) with the ``spheroid`` keyword argument. .. class:: MakeValid(expr) -.. versionadded:: 1.10 - *Availability*: PostGIS, SpatiaLite (LWGEOM) Accepts a geographic field or expression and attempts to convert the value into @@ -469,10 +453,6 @@ Accepts two geographic fields or expressions and returns the geometric symmetric difference (union without the intersection) between the given parameters. -.. versionchanged:: 1.10 - - MySQL support was added. - ``Transform`` ============= diff --git a/docs/ref/contrib/gis/gdal.txt b/docs/ref/contrib/gis/gdal.txt index 3f9219dc0df9..9e6568cc7a00 100644 --- a/docs/ref/contrib/gis/gdal.txt +++ b/docs/ref/contrib/gis/gdal.txt @@ -1215,8 +1215,6 @@ blue. .. attribute:: srid - .. versionadded:: 1.10 - The Spatial Reference System Identifier (SRID) of the raster. This property is a shortcut to getting or setting the SRID through the :attr:`srs` attribute. @@ -1418,8 +1416,6 @@ blue. .. method:: statistics(refresh=False, approximate=False) - .. versionadded:: 1.10 - Compute statistics on the pixel values of this band. The return value is a tuple with the following structure: ``(minimum, maximum, mean, standard deviation)``. @@ -1455,15 +1451,11 @@ blue. .. attribute:: mean - .. versionadded:: 1.10 - The mean of all pixel values of the band (excluding the "no data" value). .. attribute:: std - .. versionadded:: 1.10 - The standard deviation of all pixel values of the band (excluding the "no data" value). @@ -1476,11 +1468,6 @@ blue. To delete an existing "no data" value, set this property to ``None`` (requires GDAL ≥ 2.1). - .. versionchanged:: 1.10 - - The "no data" value can now be deleted by setting the - ``nodata_value`` attribute to ``None``. - .. method:: datatype(as_string=False) The data type contained in the band, as an integer constant between 0 @@ -1550,11 +1537,6 @@ blue. [2, 2, 2, 2], [3, 3, 3, 3]], dtype=uint8) - .. versionchanged:: 1.10 - - The ``shape`` parameter and the ability to replicate data input when - setting ``GDALBand`` data was added. - Settings ======== diff --git a/docs/ref/contrib/gis/geoquerysets.txt b/docs/ref/contrib/gis/geoquerysets.txt index 8213e0292da4..63258890cbbd 100644 --- a/docs/ref/contrib/gis/geoquerysets.txt +++ b/docs/ref/contrib/gis/geoquerysets.txt @@ -17,10 +17,6 @@ For an introduction, see the :ref:`spatial lookups introduction compatible with a particular spatial backend, refer to the :ref:`spatial lookup compatibility table `. -.. versionchanged:: 1.10 - - Spatial lookups now support raster input. - Lookups with rasters -------------------- @@ -298,8 +294,6 @@ SpatiaLite ``Intersects(poly, geom)`` ``isvalid`` ----------- -.. versionadded:: 1.10 - *Availability*: PostGIS Tests if the geometry is valid. @@ -603,10 +597,6 @@ of ``ST_Distance_Sphere``. The simpler ``ST_Distance`` function is used with projected coordinate systems. Rasters are converted to geometries for spheroid based lookups. -.. versionadded:: 1.10 - - The ability to pass an expression as the distance value was added. - .. versionadded:: 1.11 Support for the ``'spheroid'`` option on SQLite was added. @@ -797,10 +787,6 @@ Example:: Returns a ``LineString`` constructed from the point field geometries in the ``QuerySet``. Currently, ordering the queryset has no effect. -.. versionchanged:: 1.10 - - SpatiaLite support was added. - Example:: >>> qs = City.objects.filter(name__in=('Houston', 'Dallas')).aggregate(MakeLine('poly')) diff --git a/docs/ref/contrib/gis/geos.txt b/docs/ref/contrib/gis/geos.txt index b92a91491abd..6df0daf5145d 100644 --- a/docs/ref/contrib/gis/geos.txt +++ b/docs/ref/contrib/gis/geos.txt @@ -379,10 +379,6 @@ another object. Returns the Well-Known Text of the geometry (an OGC standard). - .. versionchanged:: 1.10 - - Non-significant zeros are stripped from the output. - __ https://developers.google.com/kml/documentation/ Spatial Predicate Methods @@ -399,8 +395,6 @@ return a boolean. .. method:: GEOSGeometry.covers(other) - .. versionadded:: 1.10 - Returns ``True`` if this geometry covers the specified geometry. The ``covers`` predicate has the following equivalent definitions: @@ -569,8 +563,6 @@ Topological Properties .. attribute:: GEOSGeometry.unary_union - .. versionadded:: 1.10 - Computes the union of all the elements of this geometry. The result obeys the following contract: @@ -646,12 +638,6 @@ Other Properties & Methods doesn't impose any constraints on the geometry's SRID if called with a :class:`~django.contrib.gis.gdal.CoordTransform` object. - .. versionchanged:: 1.10 - - In previous versions, it required the geometry's SRID to be a - positive integer even if it was called with a - :class:`~django.contrib.gis.gdal.CoordTransform` object. - .. method:: GEOSGeometry.normalize() Converts this geometry to canonical form:: @@ -681,10 +667,6 @@ Other Properties & Methods >>> pnt = Point() >>> pnt = Point([]) - .. versionchanged:: 1.10 - - In previous versions, an empty ``Point`` couldn't be instantiated. - ``LineString`` -------------- @@ -709,14 +691,8 @@ Other Properties & Methods >>> ls = LineString() >>> ls = LineString([]) - .. versionchanged:: 1.10 - - In previous versions, an empty ``LineString`` couldn't be instantiated. - .. attribute:: closed - .. versionadded:: 1.10 - Returns whether or not this ``LineString`` is closed. ``LinearRing`` @@ -749,10 +725,6 @@ Other Properties & Methods >>> poly = Polygon(ext_coords, int_coords) >>> poly = Polygon(LinearRing(ext_coords), LinearRing(int_coords)) - .. versionchanged:: 1.10 - - In previous versions, an empty ``Polygon`` couldn't be instantiated. - .. classmethod:: from_bbox(bbox) Returns a polygon object from the given bounding-box, a 4-tuple @@ -787,10 +759,6 @@ Geometry Collections >>> mp = MultiPoint(Point(0, 0), Point(1, 1)) >>> mp = MultiPoint( (Point(0, 0), Point(1, 1)) ) - .. versionchanged:: 1.10 - - In previous versions, an empty ``MultiPoint`` couldn't be instantiated. - ``MultiLineString`` ------------------- @@ -805,11 +773,6 @@ Geometry Collections >>> mls = MultiLineString(ls1, ls2) >>> mls = MultiLineString([ls1, ls2]) - .. versionchanged:: 1.10 - - In previous versions, an empty ``MultiLineString`` couldn't be - instantiated. - .. attribute:: merged Returns a :class:`LineString` representing the line merge of @@ -817,8 +780,6 @@ Geometry Collections .. attribute:: closed - .. versionadded:: 1.10 - Returns ``True`` if and only if all elements are closed. Requires GEOS 3.5. ``MultiPolygon`` @@ -834,11 +795,6 @@ Geometry Collections >>> mp = MultiPolygon(p1, p2) >>> mp = MultiPolygon([p1, p2]) - .. versionchanged:: 1.10 - - In previous versions, an empty ``MultiPolygon`` couldn't be - instantiated. - ``GeometryCollection`` ---------------------- @@ -852,11 +808,6 @@ Geometry Collections >>> gc = GeometryCollection(Point(0, 0), MultiPoint(Point(0, 0), Point(1, 1)), poly) >>> gc = GeometryCollection((Point(0, 0), MultiPoint(Point(0, 0), Point(1, 1)), poly)) - .. versionchanged:: 1.10 - - In previous versions, an empty ``GeometryCollection`` couldn't be - instantiated. - .. _prepared-geometries: Prepared Geometries @@ -978,10 +929,6 @@ include the SRID value (in other words, EWKB). :attr:`WKBWriter.outdim` documentation for more details about the ``dim`` argument. - .. versionchanged:: 1.10 - - The ability to pass the ``dim`` argument to the constructor was added. - .. method:: WKBWriter.write(geom) Returns the WKB of the given geometry as a Python ``buffer`` object. @@ -1071,11 +1018,6 @@ include the SRID value (in other words, EWKB). :attr:`WKBWriter.outdim`, :attr:`trim`, and :attr:`precision` attributes for details about the constructor arguments. - .. versionchanged:: 1.10 - - The ability to pass the ``dim``, ``trim``, and ``precision`` arguments - to the constructor was added. - .. method:: WKTWriter.write(geom) Returns the WKT of the given geometry. Example:: @@ -1092,8 +1034,6 @@ include the SRID value (in other words, EWKB). .. attribute:: WKTWriter.trim - .. versionadded:: 1.10 - This property is used to enable or disable trimming of unnecessary decimals. @@ -1110,8 +1050,6 @@ include the SRID value (in other words, EWKB). .. attribute:: WKTWriter.precision - .. versionadded:: 1.10 - This property controls the rounding precision of coordinates; if set to ``None`` rounding is disabled. diff --git a/docs/ref/contrib/gis/serializers.txt b/docs/ref/contrib/gis/serializers.txt index ffd134936bb1..057462124d4b 100644 --- a/docs/ref/contrib/gis/serializers.txt +++ b/docs/ref/contrib/gis/serializers.txt @@ -66,7 +66,3 @@ Would output:: When the ``fields`` parameter is not specified, the ``geojson`` serializer adds a ``pk`` key to the ``properties`` dictionary with the primary key of the object as the value. - -.. versionchanged:: 1.10 - - The ``pk`` key was added to the ``properties`` dictionary. diff --git a/docs/ref/contrib/postgres/lookups.txt b/docs/ref/contrib/postgres/lookups.txt index 0176dba547d0..02ba6716de03 100644 --- a/docs/ref/contrib/postgres/lookups.txt +++ b/docs/ref/contrib/postgres/lookups.txt @@ -7,8 +7,6 @@ Trigram similarity .. fieldlookup:: trigram_similar -.. versionadded:: 1.10 - The ``trigram_similar`` lookup allows you to perform trigram lookups, measuring the number of trigrams (three consecutive characters) shared, using a dedicated PostgreSQL extension. A trigram lookup is given an expression and diff --git a/docs/ref/contrib/postgres/operations.txt b/docs/ref/contrib/postgres/operations.txt index eecac388a669..90cd00712154 100644 --- a/docs/ref/contrib/postgres/operations.txt +++ b/docs/ref/contrib/postgres/operations.txt @@ -80,8 +80,6 @@ run the query ``CREATE EXTENSION IF NOT EXISTS hstore;``. .. class:: TrigramExtension() - .. versionadded:: 1.10 - Installs the ``pg_trgm`` extension. ``UnaccentExtension`` diff --git a/docs/ref/contrib/postgres/search.txt b/docs/ref/contrib/postgres/search.txt index 6d3022116af0..e3f4f7296d44 100644 --- a/docs/ref/contrib/postgres/search.txt +++ b/docs/ref/contrib/postgres/search.txt @@ -2,8 +2,6 @@ Full text search ================ -.. versionadded:: 1.10 - The database functions in the ``django.contrib.postgres.search`` module ease the use of PostgreSQL's `full text search engine `_. @@ -203,8 +201,6 @@ operation. .. class:: TrigramSimilarity(expression, string, **extra) -.. versionadded:: 1.10 - Accepts a field name or expression, and a string or expression. Returns the trigram similarity between the two arguments. @@ -224,8 +220,6 @@ Usage example:: .. class:: TrigramDistance(expression, string, **extra) -.. versionadded:: 1.10 - Accepts a field name or expression, and a string or expression. Returns the trigram distance between the two arguments. diff --git a/docs/ref/contrib/staticfiles.txt b/docs/ref/contrib/staticfiles.txt index b8d91fddb87f..46f1ce54b179 100644 --- a/docs/ref/contrib/staticfiles.txt +++ b/docs/ref/contrib/staticfiles.txt @@ -129,8 +129,6 @@ For a full list of options, refer to the commands own help by running:: Customizing the ignored pattern list ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 1.10 - The default ignored pattern list, ``['CVS', '.*', '*~']``, can be customized in a more persistent way than providing the ``--ignore`` command option at each ``collectstatic`` invocation. Provide a custom :class:`~django.apps.AppConfig` @@ -320,13 +318,6 @@ following requirements are met: * you've collected all your static files by using the :djadmin:`collectstatic` management command -.. versionchanged:: 1.10 - - In older versions, you also had to use - ``{% load static from staticfiles %}`` in your template. The - :ttag:`static` template tag (``{% load static %}``) now uses - :mod:`django.contrib.staticfiles` if it's installed. - Since creating the MD5 hash can be a performance burden to your website during runtime, ``staticfiles`` will automatically store the mapping with hashed names for all processed files in a file called ``staticfiles.json``. diff --git a/docs/ref/csrf.txt b/docs/ref/csrf.txt index 3d1ecc123798..488d31187f90 100644 --- a/docs/ref/csrf.txt +++ b/docs/ref/csrf.txt @@ -315,11 +315,6 @@ the HOST header ` and that there aren't any (because XSS vulnerabilities already let an attacker do anything a CSRF vulnerability allows and much worse). -.. versionchanged:: 1.10 - - Added salting to the token and started changing it with each request - to protect against `BREACH`_ attacks. - .. _BREACH: http://breachattack.com/ Caching diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt index aa9ebf7139ed..6a36f7731051 100644 --- a/docs/ref/django-admin.txt +++ b/docs/ref/django-admin.txt @@ -138,8 +138,6 @@ make it part of your integration test suite. .. django-admin-option:: --fail-level {CRITICAL,ERROR,WARNING,INFO,DEBUG} -.. versionadded:: 1.10 - Specifies the message level that will cause the command to exit with a non-zero status. Default is ``ERROR``. @@ -393,11 +391,6 @@ table's lifecycle, you'll need to change the :attr:`~django.db.models.Options.managed` option to ``True`` (or simply remove it because ``True`` is its default value). -.. versionadded:: 1.10 - - Support for the ``table`` argument(s) to choose what tables should be - inspected was added. - .. django-admin-option:: --database DATABASE Specifies the database to introspect. Defaults to ``default``. @@ -709,8 +702,6 @@ Makes ``makemigrations`` exit with error code 1 when no migrations are created .. django-admin-option:: --check -.. versionadded:: 1.10 - Makes ``makemigrations`` exit with a non-zero status when model changes without migrations are detected. @@ -835,11 +826,6 @@ history of migrations is created at first run of ``runserver``. Logging of each request and response of the server is sent to the :ref:`django-server-logger` logger. -.. versionchanged:: 1.10 - - In older versions, log messages were written to ``sys.stderr`` instead of - being handled through Python logging. - .. django-admin-option:: --noreload Disables the auto-reloader. This means any Python code changes you make while @@ -962,8 +948,6 @@ variable or the ``~/.pythonrc.py`` script is read. .. django-admin-option:: --command COMMAND, -c COMMAND -.. versionadded:: 1.10 - Lets you pass a command as a string to execute it as Django, like so:: django-admin shell --command="import django; print(django.__version__)" @@ -1334,15 +1318,11 @@ don't. .. option:: --tag TAGS -.. versionadded:: 1.10 - Runs only tests :ref:`marked with the specified tags `. May be specified multiple times and combined with :option:`test --exclude-tag`. .. option:: --exclude-tag EXCLUDE_TAGS -.. versionadded:: 1.10 - Excludes tests :ref:`marked with the specified tags `. May be specified multiple times and combined with :option:`test --tag`. @@ -1803,12 +1783,6 @@ Command options which take multiple options are passed a list:: The return value of the ``call_command()`` function is the same as the return value of the ``handle()`` method of the command. -.. versionchanged:: 1.10 - - ``call_command()`` now returns the value received from the - ``command.handle()`` method. It now also accepts a command object as the - first argument. - Output redirection ================== diff --git a/docs/ref/exceptions.txt b/docs/ref/exceptions.txt index 7245bccaf89b..79afe702a142 100644 --- a/docs/ref/exceptions.txt +++ b/docs/ref/exceptions.txt @@ -223,10 +223,6 @@ 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.) -.. versionchanged:: 1.10 - - The ``__traceback__`` attribute described above was added. - .. exception:: models.ProtectedError Raised to prevent deletion of referenced objects when using diff --git a/docs/ref/files/storage.txt b/docs/ref/files/storage.txt index 61bf3c395146..0d0a11eb94aa 100644 --- a/docs/ref/files/storage.txt +++ b/docs/ref/files/storage.txt @@ -91,8 +91,6 @@ The ``Storage`` class .. method:: get_accessed_time(name) - .. versionadded:: 1.10 - Returns a :class:`~datetime.datetime` of the last accessed time of the file. For storage systems unable to return the last accessed time this will raise :exc:`NotImplementedError`. @@ -117,8 +115,6 @@ The ``Storage`` class .. method:: get_created_time(name) - .. versionadded:: 1.10 - Returns a :class:`~datetime.datetime` of the creation time of the file. For storage systems unable to return the creation time this will raise :exc:`NotImplementedError`. @@ -128,8 +124,6 @@ The ``Storage`` class .. method:: get_modified_time(name) - .. versionadded:: 1.10 - Returns a :class:`~datetime.datetime` of the last modified time of the file. For storage systems unable to return the last modified time this will raise :exc:`NotImplementedError`. @@ -144,8 +138,6 @@ The ``Storage`` class .. method:: generate_filename(filename) - .. versionadded:: 1.10 - Validates the ``filename`` by calling :attr:`get_valid_name()` and returns a filename to be passed to the :meth:`save` method. diff --git a/docs/ref/forms/api.txt b/docs/ref/forms/api.txt index c74cfaed4815..1c4185156d1c 100644 --- a/docs/ref/forms/api.txt +++ b/docs/ref/forms/api.txt @@ -711,8 +711,6 @@ using the ``label_suffix`` parameter to .. attribute:: Form.use_required_attribute -.. versionadded:: 1.10 - When set to ``True`` (the default), required form fields will have the ``required`` HTML attribute. diff --git a/docs/ref/forms/widgets.txt b/docs/ref/forms/widgets.txt index 2b9cf489f1b5..210e5ce93cba 100644 --- a/docs/ref/forms/widgets.txt +++ b/docs/ref/forms/widgets.txt @@ -291,8 +291,6 @@ foundation for custom widgets. .. method:: value_omitted_from_data(data, files, name) - .. versionadded:: 1.10.2 - Given ``data`` and ``files`` dictionaries and this widget's name, returns whether or not there's data or files for the widget. @@ -307,8 +305,6 @@ foundation for custom widgets. .. method:: use_required_attribute(initial) - .. versionadded:: 1.10.1 - Given a form field's ``initial`` value, returns whether or not the widget can be rendered with the ``required`` HTML attribute. Forms use this method along with :attr:`Field.required diff --git a/docs/ref/middleware.txt b/docs/ref/middleware.txt index dd0bae3bb3a2..22a2d1a50493 100644 --- a/docs/ref/middleware.txt +++ b/docs/ref/middleware.txt @@ -97,8 +97,6 @@ Exception middleware .. class:: ExceptionMiddleware -.. versionadded:: 1.10 - Catches exceptions raised during the request/response cycle and returns the appropriate response. @@ -161,12 +159,6 @@ If the response has an ``ETag`` header, the ETag is made weak to comply with You can apply GZip compression to individual views using the :func:`~django.views.decorators.gzip.gzip_page()` decorator. -.. versionchanged:: 1.10 - - In older versions, Django's CSRF protection mechanism was vulnerable to - BREACH attacks when compression was used. This is no longer the case, but - you should still take care not to compromise your own secrets this way. - Conditional GET middleware -------------------------- diff --git a/docs/ref/migration-operations.txt b/docs/ref/migration-operations.txt index bb5d4513795f..7e5f4d478490 100644 --- a/docs/ref/migration-operations.txt +++ b/docs/ref/migration-operations.txt @@ -281,10 +281,6 @@ be removed (elided) when :ref:`squashing migrations `. .. _sqlparse: https://pypi.python.org/pypi/sqlparse -.. versionadded:: 1.10 - - The ``elidable`` argument was added. - ``RunPython`` ------------- @@ -400,15 +396,6 @@ if ``atomic=True`` is passed to the ``RunPython`` operation. you want the operation not to do anything in the given direction. This is especially useful in making the operation reversible. -.. versionadded:: 1.10 - - The ``elidable`` argument was added. - -.. versionchanged:: 1.10 - - The ``atomic`` argument default was changed to ``None``, indicating that - the atomicity is controlled by the ``atomic`` attribute of the migration. - ``SeparateDatabaseAndState`` ---------------------------- diff --git a/docs/ref/models/database-functions.txt b/docs/ref/models/database-functions.txt index 231d023e11d2..18d547d90636 100644 --- a/docs/ref/models/database-functions.txt +++ b/docs/ref/models/database-functions.txt @@ -28,8 +28,6 @@ allows the field to have two "empty values", but it's important for the .. class:: Cast(expression, output_field) -.. versionadded:: 1.10 - Forces the result type of ``expression`` to be the one from ``output_field``. Usage example:: @@ -281,8 +279,6 @@ Date Functions .. module:: django.db.models.functions.datetime -.. versionadded:: 1.10 - We'll be using the following model in examples of each function:: class Experiment(models.Model): diff --git a/docs/ref/models/expressions.txt b/docs/ref/models/expressions.txt index 01db10375878..4ba63ba92877 100644 --- a/docs/ref/models/expressions.txt +++ b/docs/ref/models/expressions.txt @@ -278,8 +278,6 @@ The ``Func`` API is as follows: .. attribute:: arity - .. versionadded:: 1.10 - A class attribute that denotes the number of arguments the function accepts. If this attribute is set and the function is called with a different number of expressions, ``TypeError`` will be raised. Defaults @@ -308,11 +306,6 @@ The ``Func`` API is as follows: template="%(function)s('', %(expressions)s)", ) - .. versionchanged:: 1.10 - - Support for the ``arg_joiner`` and ``**extra_context`` parameters - was added. - The ``*expressions`` argument is a list of positional expressions that the function will be applied to. The expressions will be converted to strings, joined together with ``arg_joiner``, and then interpolated into the ``template`` diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index 5e6e2e1c0ea7..fc4290edb7ea 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -401,8 +401,6 @@ otherwise. See :ref:`automatic-primary-key-fields`. .. class:: BigAutoField(**options) -.. versionadded:: 1.10 - A 64-bit integer, much like an :class:`AutoField` except that it is guaranteed to fit numbers from ``1`` to ``9223372036854775807``. @@ -1777,8 +1775,6 @@ Field API reference .. method:: rel_db_type(connection) - .. versionadded:: 1.10 - Returns the database column data type for fields such as ``ForeignKey`` and ``OneToOneField`` that point to the :class:`Field`, taking into account the ``connection``. diff --git a/docs/ref/models/instances.txt b/docs/ref/models/instances.txt index 3c1f2e051be0..83f76f37ca7c 100644 --- a/docs/ref/models/instances.txt +++ b/docs/ref/models/instances.txt @@ -119,12 +119,6 @@ The example above shows a full ``from_db()`` implementation to clarify how that is done. In this case it would of course be possible to just use ``super()`` call in the ``from_db()`` method. -.. versionchanged:: 1.10 - - In older versions, you could check if all fields were loaded by consulting - ``cls._deferred``. This attribute is removed and - ``django.db.models.DEFERRED`` is new. - Refreshing objects from database ================================ @@ -135,11 +129,6 @@ value from the database:: >>> del obj.field >>> obj.field # Loads the field from the database -.. versionchanged:: 1.10 - - In older versions, accessing a deleted field raised ``AttributeError`` - instead of reloading it. - .. method:: Model.refresh_from_db(using=None, fields=None) If you need to reload a model's values from the database, you can use the diff --git a/docs/ref/models/options.txt b/docs/ref/models/options.txt index 23ea0c673e94..182c2f6c45cc 100644 --- a/docs/ref/models/options.txt +++ b/docs/ref/models/options.txt @@ -38,8 +38,6 @@ Available ``Meta`` options .. attribute:: Options.base_manager_name - .. versionadded:: 1.10 - The name of the manager to use for the model's :attr:`~django.db.models.Model._base_manager`. @@ -108,8 +106,6 @@ Django quotes column and table names behind the scenes. .. attribute:: Options.default_manager_name - .. versionadded:: 1.10 - The name of the manager to use for the model's :attr:`~django.db.models.Model._default_manager`. diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index ec71fe0294cf..ddacf25769e7 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -1949,11 +1949,6 @@ This has a number of caveats though: unless the database backend supports it (currently PostgreSQL). * It does not work with many-to-many relationships. -.. versionchanged:: 1.10 - - Support for setting primary keys on objects created using ``bulk_create()`` - when using PostgreSQL was added. - The ``batch_size`` parameter controls how many objects are created in single query. The default is to create all objects in one batch, except for SQLite where the default is such that at most 999 variables per query are used. @@ -2011,10 +2006,6 @@ Example:: If you pass ``in_bulk()`` an empty list, you'll get an empty dictionary. -.. versionchanged:: 1.10 - - In older versions, ``id_list`` was a required argument. - ``iterator()`` ~~~~~~~~~~~~~~ @@ -3206,8 +3197,6 @@ attribute: .. function:: prefetch_related_objects(model_instances, *related_lookups) -.. versionadded:: 1.10 - Prefetches the given lookups on an iterable of model instances. This is useful in code that receives a list of model instances as opposed to a ``QuerySet``; for example, when fetching models from a cache or instantiating them manually. diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt index b3d0f76a7e49..40ba20738e7c 100644 --- a/docs/ref/request-response.txt +++ b/docs/ref/request-response.txt @@ -86,15 +86,11 @@ All attributes should be considered read-only, unless stated otherwise. .. attribute:: HttpRequest.content_type - .. versionadded:: 1.10 - A string representing the MIME type of the request, parsed from the ``CONTENT_TYPE`` header. .. attribute:: HttpRequest.content_params - .. versionadded:: 1.10 - A dictionary of key/value parameters included in the ``CONTENT_TYPE`` header. @@ -639,11 +635,6 @@ generators are immediately closed. If you need the response to be streamed from the iterator to the client, you must use the :class:`StreamingHttpResponse` class instead. -.. versionchanged:: 1.10 - - Objects with a ``close()`` method used to be closed when the WSGI server - called ``close()`` on the response. - Setting header fields ~~~~~~~~~~~~~~~~~~~~~ @@ -846,15 +837,11 @@ Methods .. method:: HttpResponse.readable() - .. versionadded:: 1.10 - Always ``False``. This method makes an :class:`HttpResponse` instance a stream-like object. .. method:: HttpResponse.seekable() - .. versionadded:: 1.10 - Always ``False``. This method makes an :class:`HttpResponse` instance a stream-like object. diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index 97a67ffc3bfc..e379dc19f4f9 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -423,11 +423,6 @@ an :class:`~django.http.HttpResponseForbidden`. parameter that defaults to ``'403_csrf.html'``. If a template with that name exists, it will be used to render the page. -.. versionchanged:: 1.10 - - The ``template_name`` parameter and the behavior of searching for a template - called ``403_csrf.html`` were added to ``csrf_failure()``. - .. setting:: CSRF_HEADER_NAME ``CSRF_HEADER_NAME`` @@ -906,8 +901,6 @@ The maximum size that the DATAFILE_TMP is allowed to grow to. DATA_UPLOAD_MAX_MEMORY_SIZE --------------------------- -.. versionadded:: 1.10 - Default: ``2621440`` (i.e. 2.5 MB). The maximum size in bytes that a request body may be before a @@ -930,8 +923,6 @@ See also :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE`. DATA_UPLOAD_MAX_NUMBER_FIELDS ----------------------------- -.. versionadded:: 1.10 - Default: ``1000`` The maximum number of parameters that may be received via GET or POST before a @@ -1513,10 +1504,6 @@ of the preferred value or not supplied at all. It is also used by request/response cycle (e.g. in management commands and standalone scripts) to generate correct URLs when ``SCRIPT_NAME`` is not ``/``. -.. versionchanged:: 1.10 - - The setting's use in :func:`django.setup()` was added. - .. setting:: FORM_RENDERER ``FORM_RENDERER`` @@ -1894,8 +1881,6 @@ Example: ``"http://media.example.com/"`` ``MIDDLEWARE`` -------------- -.. versionadded:: 1.10 - Default:: ``None`` A list of middleware to use. See :doc:`/topics/http/middleware`. @@ -2775,8 +2760,6 @@ the URL in two places (``settings`` and URLconf). ``LOGOUT_REDIRECT_URL`` ----------------------- -.. versionadded:: 1.10 - Default: ``None`` The URL where requests are redirected after a user logs out using @@ -2817,22 +2800,6 @@ Default:: 'django.contrib.auth.hashers.BCryptPasswordHasher', ] -.. versionchanged:: 1.10 - - The following hashers were removed from the defaults:: - - 'django.contrib.auth.hashers.SHA1PasswordHasher' - 'django.contrib.auth.hashers.MD5PasswordHasher' - 'django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher' - 'django.contrib.auth.hashers.UnsaltedMD5PasswordHasher' - 'django.contrib.auth.hashers.CryptPasswordHasher' - - Consider using a :ref:`wrapped password hasher ` - to strengthen the hashes in your database. If that's not feasible, add this - setting to your project and add back any hashers that you need. - - Also, the ``Argon2PasswordHasher`` was added. - .. setting:: AUTH_PASSWORD_VALIDATORS ``AUTH_PASSWORD_VALIDATORS`` diff --git a/docs/ref/signals.txt b/docs/ref/signals.txt index f23bb9eb8cf9..58026d94258c 100644 --- a/docs/ref/signals.txt +++ b/docs/ref/signals.txt @@ -407,8 +407,6 @@ Arguments sent with this signal: The alias of database on which a command will operate. ``plan`` - .. versionadded:: 1.10 - The migration plan that is going to be used for the migration run. While the plan is not public API, this allows for the rare cases when it is necessary to know the plan. A plan is a list of two-tuples with the first @@ -416,8 +414,6 @@ Arguments sent with this signal: if the migration was rolled back (``True``) or applied (``False``). ``apps`` - .. versionadded:: 1.10 - An instance of :data:`Apps ` containing the state of the project before the migration run. It should be used instead of the global :attr:`apps ` registry to retrieve the models you @@ -466,8 +462,6 @@ Arguments sent with this signal: database. ``plan`` - .. versionadded:: 1.10 - The migration plan that was used for the migration run. While the plan is not public API, this allows for the rare cases when it is necessary to know the plan. A plan is a list of two-tuples with the first item being @@ -475,8 +469,6 @@ Arguments sent with this signal: migration was rolled back (``True``) or applied (``False``). ``apps`` - .. versionadded:: 1.10 - An instance of :data:`Apps ` containing the state of the project after the migration run. It should be used instead of the global :attr:`apps ` registry to retrieve the models you diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt index c4ce1b84a5fd..afa43f7abddf 100644 --- a/docs/ref/templates/api.txt +++ b/docs/ref/templates/api.txt @@ -71,10 +71,6 @@ what's passed by :class:`~django.template.backends.django.DjangoTemplates`. Only set it to ``False`` if you're rendering non-HTML templates! - .. versionadded:: 1.10 - - The ``autoescape`` option was added. - * ``context_processors`` is a list of dotted Python paths to callables that are used to populate the context when a template is rendered with a request. These callables take a request object as their argument and @@ -700,11 +696,6 @@ the request's IP address (``request.META['REMOTE_ADDR']``) is in the and how long it took. The list is in order by database alias and then by query. It's lazily generated on access. -.. versionchanged:: 1.10 - - In older versions, only the queries for the default database alias were - included. - ``django.template.context_processors.i18n`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt index 5925370843be..b4fe7f9665be 100644 --- a/docs/ref/templates/builtins.txt +++ b/docs/ref/templates/builtins.txt @@ -231,10 +231,6 @@ In ``template.html``, the following paths would be valid:: {% extends "../base1.html" %} {% extends "./my/base3.html" %} -.. versionadded:: 1.10 - - The ability to use relative paths was added. - .. templatetag:: filter ``filter`` @@ -538,8 +534,6 @@ Not contained within. This is the negation of the ``in`` operator. ``is`` operator ^^^^^^^^^^^^^^^ -.. versionadded:: 1.10 - Object identity. Tests if two values are the same object. Example:: {% if somevar is True %} @@ -553,8 +547,6 @@ Object identity. Tests if two values are the same object. Example:: ``is not`` operator ^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 1.10 - Negated object identity. Tests if two values are not the same object. This is the negation of the ``is`` operator. Example:: @@ -685,10 +677,6 @@ This example includes the contents of the template ``"foo/bar.html"``:: A string argument may be a relative path starting with ``./`` or ``../`` as described in the :ttag:`extends` tag. -.. versionadded:: 1.10 - - The ability to use a relative path was added. - This example includes the contents of the template whose name is contained in the variable ``template_name``:: @@ -1597,10 +1585,6 @@ produce empty output:: {{ values|dictsort:"0" }} -.. versionchanged:: 1.10 - - The ability to order a list of lists was added. - .. templatefilter:: dictsortreversed ``dictsortreversed`` @@ -2585,12 +2569,6 @@ slightly different call:: See :class:`~django.template.backends.jinja2.Jinja2` for information on using the ``static`` tag with Jinja2. -.. versionchanged:: 1.10 - - In older versions, you had to use ``{% load static from staticfiles %}`` in - your template to serve files from the storage defined in - :setting:`STATICFILES_STORAGE`. This is no longer required. - .. templatetag:: get_static_prefix ``get_static_prefix`` diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index 8beafb8268d4..79787227e2f0 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -520,8 +520,6 @@ https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004 .. function:: keep_lazy(func, *resultclasses) - .. versionadded:: 1.10 - Django offers many utility functions (particularly in ``django.utils``) that take a string as their first argument and do something to that string. These functions are used by template filters as well as directly in other @@ -565,8 +563,6 @@ https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004 .. function:: keep_lazy_text(func) - .. versionadded:: 1.10 - A shortcut for ``keep_lazy(six.text_type)(func)``. If you have a function that returns text and you want to be able to take diff --git a/docs/ref/validators.txt b/docs/ref/validators.txt index 417df517a4a3..635f76d1eba1 100644 --- a/docs/ref/validators.txt +++ b/docs/ref/validators.txt @@ -230,10 +230,6 @@ to, or in lieu of custom ``field.clean()`` methods. of integers separated by ``sep``. It allows negative integers when ``allow_negative`` is ``True``. - .. versionchanged:: 1.10 - - The ``allow_negative`` parameter was added. - ``MaxValueValidator`` --------------------- diff --git a/docs/ref/views.txt b/docs/ref/views.txt index 2b3568114cbe..93303527bc2d 100644 --- a/docs/ref/views.txt +++ b/docs/ref/views.txt @@ -87,10 +87,6 @@ Three things to note about 404 views: your 404 view will never be used, and your URLconf will be displayed instead, with some debug information. -.. versionchanged:: 1.10 - - Passing a nonexistent ``template_name`` will raise ``TemplateDoesNotExist``. - .. _http_internal_server_error_view: The 500 (server error) view @@ -111,10 +107,6 @@ If :setting:`DEBUG` is set to ``True`` (in your settings module), then your 500 view will never be used, and the traceback will be displayed instead, with some debug information. -.. versionchanged:: 1.10 - - Passing a nonexistent ``template_name`` will raise ``TemplateDoesNotExist``. - .. _http_forbidden_view: The 403 (HTTP Forbidden) view @@ -143,10 +135,6 @@ view you can use code like this:: raise PermissionDenied # ... -.. versionchanged:: 1.10 - - Passing a nonexistent ``template_name`` will raise ``TemplateDoesNotExist``. - .. _http_bad_request_view: The 400 (bad request) view @@ -167,7 +155,3 @@ context, as the exception message might contain sensitive information like filesystem paths. ``bad_request`` views are also only used when :setting:`DEBUG` is ``False``. - -.. versionchanged:: 1.10 - - Passing a nonexistent ``template_name`` will raise ``TemplateDoesNotExist``. diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt index 40675d2ef6ed..0f750adc2b0d 100644 --- a/docs/topics/auth/customizing.txt +++ b/docs/topics/auth/customizing.txt @@ -260,11 +260,6 @@ authenticated users do not. Do not forget to test for the ``is_active`` attribute of the user in your own backend permission methods. -.. versionchanged:: 1.10 - - In older versions, the :class:`~django.contrib.auth.backends.ModelBackend` - allowed inactive users to authenticate. - Handling object permissions ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -661,8 +656,6 @@ The following attributes and methods are available on any subclass of .. method:: clean() - .. versionadded:: 1.10 - Normalizes the username by calling :meth:`normalize_username`. If you override this method, be sure to call ``super()`` to retain the normalization. @@ -677,8 +670,6 @@ The following attributes and methods are available on any subclass of .. classmethod:: normalize_username(username) - .. versionadded:: 1.10 - Applies NFKC Unicode normalization to usernames so that visually identical characters with different Unicode code points are considered identical. diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt index b1f111c092a2..7aea283a104e 100644 --- a/docs/topics/auth/default.txt +++ b/docs/topics/auth/default.txt @@ -358,14 +358,6 @@ If you have an authenticated user you want to attach to the current session # Return an 'invalid login' error message. ... - .. versionchanged:: 1.10 - - In older versions, when you're manually logging a user in, you *must* - successfully authenticate the user with - :func:`~django.contrib.auth.authenticate()` before you call - :func:`~django.contrib.auth.login()`. Now you can set the backend using - the new ``backend`` argument. - Selecting the authentication backend ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -956,10 +948,6 @@ implementation details see :ref:`using-the-views`. The optional arguments of this view are similar to the class-based ``LoginView`` attributes. - .. versionadded:: 1.10 - - The ``redirect_authenticated_user`` parameter was added. - .. class:: LoginView .. versionadded:: 1.11 diff --git a/docs/topics/auth/passwords.txt b/docs/topics/auth/passwords.txt index 7015e654046b..128a2906cb80 100644 --- a/docs/topics/auth/passwords.txt +++ b/docs/topics/auth/passwords.txt @@ -76,8 +76,6 @@ to modify this setting. Using Argon2 with Django ------------------------ -.. versionadded:: 1.10 - Argon2_ is the winner of the 2015 `Password Hashing Competition`_, a community organized open competition to select a next generation hashing algorithm. It's designed not to be easier to compute on custom hardware than it is to compute diff --git a/docs/topics/checks.txt b/docs/topics/checks.txt index 355e85714e6e..59ead9d5a758 100644 --- a/docs/topics/checks.txt +++ b/docs/topics/checks.txt @@ -133,10 +133,6 @@ perform any extra checks you need, and append any messages to those generated by the base class. It's recommended that you delegate each check to separate methods. -.. versionchanged:: 1.10 - - Database backend checks were added. - Consider an example where you are implementing a custom field named ``RangedIntegerField``. This field adds ``min`` and ``max`` arguments to the constructor of ``IntegerField``. You may want to add a check to ensure that users diff --git a/docs/topics/db/managers.txt b/docs/topics/db/managers.txt index 2867db02d900..a8923e2e36a9 100644 --- a/docs/topics/db/managers.txt +++ b/docs/topics/db/managers.txt @@ -367,13 +367,6 @@ Here's how Django handles custom managers and :ref:`model inheritance `, or the first manager declared on the model, or the default manager of the first parent model. -.. versionchanged:: 1.10 - - In older versions, manager inheritance varied depending on the type of - model inheritance (i.e. :ref:`abstract-base-classes`, - :ref:`multi-table-inheritance`, or :ref:`proxy-models`), especially - with regards to electing the default manager. - These rules provide the necessary flexibility if you want to install a collection of custom managers on a group of models, via an abstract base class, but still customize the default manager. For example, suppose you have diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt index 07caa00b02bd..1ce164f532de 100644 --- a/docs/topics/db/models.txt +++ b/docs/topics/db/models.txt @@ -1034,11 +1034,6 @@ attribute was omitted, the reverse name for the ``m2m`` field would be ``childa_set`` in the ``ChildA`` case and ``childb_set`` for the ``ChildB`` field. -.. versionchanged:: 1.10 - - Interpolation of ``'%(app_label)s'`` and ``'%(class)s'`` for - ``related_query_name`` was added. - .. _multi-table-inheritance: Multi-table inheritance @@ -1236,11 +1231,6 @@ proxy model can inherit from any number of abstract model classes, providing they do *not* define any model fields. A proxy model may also inherit from any number of proxy models that share a common non-abstract parent class. -.. versionchanged:: 1.10 - - In earlier versions, a proxy model couldn't inherit more than one proxy - model that shared the same parent class. - Proxy model managers ~~~~~~~~~~~~~~~~~~~~ @@ -1374,10 +1364,6 @@ This restriction doesn't apply to model fields inherited from an abstract model. Such fields may be overridden with another field or value, or be removed by setting ``field_name = None``. -.. versionchanged:: 1.10 - - The ability to override abstract fields was added. - .. warning:: Model managers are inherited from abstract base classes. Overriding an diff --git a/docs/topics/db/multi-db.txt b/docs/topics/db/multi-db.txt index 83ac9b7c5e98..69885453b386 100644 --- a/docs/topics/db/multi-db.txt +++ b/docs/topics/db/multi-db.txt @@ -109,11 +109,6 @@ creating new migrations. By default, it checks only the ``default`` database, but it consults the :meth:`allow_migrate` method of :ref:`routers ` if any are installed. -.. versionchanged:: 1.10 - - Migration consistency checks were added. Checks based on database routers - were added in 1.10.1. - .. _topics-db-multi-db-routing: Automatic database routing diff --git a/docs/topics/forms/media.txt b/docs/topics/forms/media.txt index adbd2c377ed5..0bdf237a21d1 100644 --- a/docs/topics/forms/media.txt +++ b/docs/topics/forms/media.txt @@ -249,10 +249,6 @@ Or if :mod:`~django.contrib.staticfiles` is configured using the -.. versionchanged:: 1.10 - - Older versions didn't serve assets using :mod:`django.contrib.staticfiles`. - ``Media`` objects ================= diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt index eb397a3d4ac5..b0115cef7ebe 100644 --- a/docs/topics/forms/modelforms.txt +++ b/docs/topics/forms/modelforms.txt @@ -342,16 +342,6 @@ there is one, for that field. This behavior doesn't apply to fields that use form submission. Use a custom form field or widget if you're designing an API and want the default fallback for a :class:`~django.db.models.BooleanField`. -.. versionchanged:: 1.10.1 - - Older versions don't have the exception for - :class:`~django.forms.CheckboxInput` which means that unchecked checkboxes - receive a value of ``True`` if that's the model field default. - -.. versionchanged:: 1.10.2 - - The :meth:`~django.forms.Widget.value_omitted_from_data` method was added. - This ``save()`` method accepts an optional ``commit`` keyword argument, which accepts either ``True`` or ``False``. If you call ``save()`` with ``commit=False``, then it will return an object that hasn't yet been saved to diff --git a/docs/topics/http/middleware.txt b/docs/topics/http/middleware.txt index d5e892706561..09cf78557d71 100644 --- a/docs/topics/http/middleware.txt +++ b/docs/topics/http/middleware.txt @@ -86,15 +86,6 @@ caveats: * Unlike the ``__call__()`` method which is called once per request, ``__init__()`` is called only *once*, when the Web server starts. -.. versionchanged:: 1.10 - - In older versions, ``__init__()`` wasn't called until the Web server - responded to its first request. - - In older versions, ``__init__()`` didn't accept any arguments. To allow - your middleware to be used in Django 1.9 and earlier, make ``get_response`` - an optional argument (``get_response=None``). - Marking middleware as unused ---------------------------- diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt index 4605f998e5a3..bb3796a32eba 100644 --- a/docs/topics/i18n/translation.txt +++ b/docs/topics/i18n/translation.txt @@ -988,8 +988,6 @@ The ``JavaScriptCatalog`` view .. module:: django.views.i18n -.. versionadded:: 1.10 - .. class:: JavaScriptCatalog A view that produces a JavaScript code library with functions that mimic @@ -1216,8 +1214,6 @@ will render a conditional expression. This will evaluate to either a ``true`` The ``JSONCatalog`` view ------------------------ -.. versionadded:: 1.10 - .. class:: JSONCatalog In order to use another client-side library to handle translations, you may @@ -1379,22 +1375,12 @@ will be:: >>> reverse('news:index') '/nl/news/' -.. versionadded:: 1.10 - - The ``prefix_default_language`` parameter was added. - .. warning:: :func:`~django.conf.urls.i18n.i18n_patterns` is only allowed in a root URLconf. Using it within an included URLconf will throw an :exc:`~django.core.exceptions.ImproperlyConfigured` exception. -.. versionchanged:: 1.10 - - In older version, using ``i18n_patterns`` in a root URLconf different from - :setting:`ROOT_URLCONF` by setting :attr:`request.urlconf - ` wasn't supported. - .. warning:: Ensure that you don't have non-prefixed URL patterns that might collide @@ -1814,11 +1800,6 @@ set, to ``/``, depending on the nature of the request: parameter was set. Otherwise a 204 status code (No Content) will be returned. * For non-AJAX requests, the fallback will always be performed. -.. versionchanged:: 1.10 - - Returning a 204 status code for AJAX requests when no redirect is specified - is new. - Here's example HTML template code: .. code-block:: html+django diff --git a/docs/topics/logging.txt b/docs/topics/logging.txt index 15a49f0d4d92..859f18516df3 100644 --- a/docs/topics/logging.txt +++ b/docs/topics/logging.txt @@ -481,8 +481,6 @@ Messages to this logger have the following extra context: ``django.server`` ~~~~~~~~~~~~~~~~~ -.. versionadded:: 1.10 - Log messages related to the handling of requests received by the server invoked by the :djadmin:`runserver` command. HTTP 5XX responses are logged as ``ERROR`` messages, 4XX responses are logged as ``WARNING`` messages, and everything else @@ -584,10 +582,6 @@ Messages to this logger have ``params`` and ``sql`` in their extra context (but unlike ``django.db.backends``, not duration). The values have the same meaning as explained in :ref:`django-db-logger`. -.. versionadded:: 1.10 - - The ``extra`` context was added. - Handlers -------- diff --git a/docs/topics/migrations.txt b/docs/topics/migrations.txt index 2be05903aebe..e8675fe5457a 100644 --- a/docs/topics/migrations.txt +++ b/docs/topics/migrations.txt @@ -314,11 +314,6 @@ new migrations until it's fixed. When using multiple databases, you can use the ` to control which databases :djadmin:`makemigrations` checks for consistent history. -.. versionchanged:: 1.10 - - Migration consistency checks were added. Checks based on database routers - were added in 1.10.1. - Adding migrations to apps ========================= @@ -679,10 +674,6 @@ Django can serialize the following: - Any class reference (must be in module's top-level scope) - Anything with a custom ``deconstruct()`` method (:ref:`see below `) -.. versionchanged:: 1.10 - - Serialization support for ``enum.Enum`` was added. - .. versionchanged:: 1.11 Serialization support for ``uuid.UUID`` was added. diff --git a/docs/topics/serialization.txt b/docs/topics/serialization.txt index 5db5e656ecb0..9f7a4f41c683 100644 --- a/docs/topics/serialization.txt +++ b/docs/topics/serialization.txt @@ -305,10 +305,6 @@ The JSON serializer uses ``DjangoJSONEncoder`` for encoding. A subclass of :class:`~decimal.Decimal`, ``Promise`` (``django.utils.functional.lazy()`` objects), :class:`~uuid.UUID` A string representation of the object. -.. versionchanged:: 1.10 - - Support for ``Promise`` was added. - .. versionchanged:: 1.11 Support for :class:`~datetime.timedelta` was added. diff --git a/docs/topics/templates.txt b/docs/topics/templates.txt index 3ee9a01efdd1..a819acf3f01e 100644 --- a/docs/topics/templates.txt +++ b/docs/topics/templates.txt @@ -308,10 +308,6 @@ applications. This generic name was kept for backwards-compatibility. Only set it to ``False`` if you're rendering non-HTML templates! - .. versionadded:: 1.10 - - The ``autoescape`` option was added. - * ``'context_processors'``: a list of dotted Python paths to callables that are used to populate the context when a template is rendered with a request. These callables take a request object as their argument and return a diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt index 5bb34be1a334..b8c799619ec7 100644 --- a/docs/topics/testing/tools.txt +++ b/docs/topics/testing/tools.txt @@ -371,12 +371,6 @@ Use the ``django.test.Client`` class to make requests. :meth:`~django.contrib.auth.models.UserManager.create_user` helper method to create a new user with a correctly hashed password. - .. versionchanged:: 1.10 - - In previous versions, inactive users (:attr:`is_active=False - `) were not permitted - to login. - .. method:: Client.force_login(user, backend=None) If your site uses Django's :doc:`authentication @@ -795,11 +789,6 @@ The class: * Checks deferrable database constraints at the end of each test. -.. versionchanged:: 1.10 - - The check for deferrable database constraints at the end of each test was - added. - It also provides an additional method: .. classmethod:: TestCase.setUpTestData() @@ -1604,8 +1593,6 @@ your test suite. Tagging tests ------------- -.. versionadded:: 1.10 - You can tag your tests so you can easily run a particular subset. For example, you might label fast or slow tests:: From f8473082004ccdc764ad08beeb7c2a17b238dc85 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 10 Jan 2017 10:06:07 -0500 Subject: [PATCH 0053/3180] Advanced deprecation warnings for Django 2.0. --- django/utils/deprecation.py | 6 +++--- docs/internals/deprecation.txt | 8 ++++++++ tests/runtests.py | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/django/utils/deprecation.py b/django/utils/deprecation.py index b862a161b2c8..28405cf2c190 100644 --- a/django/utils/deprecation.py +++ b/django/utils/deprecation.py @@ -4,15 +4,15 @@ import warnings -class RemovedInDjango20Warning(DeprecationWarning): +class RemovedInDjango30Warning(PendingDeprecationWarning): pass -class RemovedInDjango21Warning(PendingDeprecationWarning): +class RemovedInDjango21Warning(DeprecationWarning): pass -RemovedInNextVersionWarning = RemovedInDjango20Warning +RemovedInNextVersionWarning = RemovedInDjango21Warning class warn_about_renamed_method(object): diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 05100c43a99c..eface82d4cfa 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -7,6 +7,14 @@ in a backward incompatible way, following their deprecation, as per the :ref:`deprecation policy `. More details about each item can often be found in the release notes of two versions prior. +.. _deprecation-removed-in-3.0: + +3.0 +--- + +See the :ref:`Django 2.0 release notes` for more +details on these changes. + .. _deprecation-removed-in-2.1: 2.1 diff --git a/tests/runtests.py b/tests/runtests.py index a99ebd63c3fa..82cd8207ba13 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -20,12 +20,12 @@ from django.utils import six from django.utils._os import upath from django.utils.deprecation import ( - RemovedInDjango20Warning, RemovedInDjango21Warning, + RemovedInDjango21Warning, RemovedInDjango30Warning, ) from django.utils.log import DEFAULT_LOGGING # Make deprecation warnings errors to ensure no usage of deprecated features. -warnings.simplefilter("error", RemovedInDjango20Warning) +warnings.simplefilter("error", RemovedInDjango30Warning) warnings.simplefilter("error", RemovedInDjango21Warning) # Make runtime warning errors to ensure no usage of error prone patterns. warnings.simplefilter("error", RuntimeWarning) From 0bf3228eecca5658066b2eed47620fcbac9fd05c Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 17 Jan 2017 09:54:04 -0500 Subject: [PATCH 0054/3180] Increased the default PBKDF2 iterations for the 1.11 release cycle. --- django/contrib/auth/hashers.py | 2 +- docs/releases/2.0.txt | 3 ++- tests/auth_tests/test_hashers.py | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py index 8056ec010a9e..c29b27d64b81 100644 --- a/django/contrib/auth/hashers.py +++ b/django/contrib/auth/hashers.py @@ -247,7 +247,7 @@ class PBKDF2PasswordHasher(BasePasswordHasher): safely but you must rename the algorithm if you change SHA256. """ algorithm = "pbkdf2_sha256" - iterations = 36000 + iterations = 100000 digest = hashlib.sha256 def encode(self, password, salt, iterations=None): diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 3ae58ed858a5..a4c4e75920ba 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -51,7 +51,8 @@ Minor features :mod:`django.contrib.auth` ~~~~~~~~~~~~~~~~~~~~~~~~~~ -* ... +* The default iteration count for the PBKDF2 password hasher is increased from + 36,000 to 100,000. :mod:`django.contrib.contenttypes` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/auth_tests/test_hashers.py b/tests/auth_tests/test_hashers.py index 1d0832da32c7..5a8e44bcd731 100644 --- a/tests/auth_tests/test_hashers.py +++ b/tests/auth_tests/test_hashers.py @@ -56,7 +56,7 @@ def test_simple(self): def test_pbkdf2(self): encoded = make_password('lètmein', 'seasalt', 'pbkdf2_sha256') - self.assertEqual(encoded, 'pbkdf2_sha256$36000$seasalt$mEUPPFJkT/xtwDU8rB7Q+puHRZnR07WRjerTkt/3HI0=') + self.assertEqual(encoded, 'pbkdf2_sha256$100000$seasalt$BNZ6eyaNc8qFTJPjrAq99hSYb73EgAdytAtdBg2Sdcc=') self.assertTrue(is_password_usable(encoded)) self.assertTrue(check_password('lètmein', encoded)) self.assertFalse(check_password('lètmeinz', encoded)) @@ -280,13 +280,13 @@ def test_bad_encoded(self): def test_low_level_pbkdf2(self): hasher = PBKDF2PasswordHasher() encoded = hasher.encode('lètmein', 'seasalt2') - self.assertEqual(encoded, 'pbkdf2_sha256$36000$seasalt2$QkIBVCvGmTmyjPJ5yox2y/jQB8isvgUNK98FxOU1UYo=') + self.assertEqual(encoded, 'pbkdf2_sha256$100000$seasalt2$Tl4GMr+Yt1zzO1sbKoUaDBdds5NkR3RxaDWuQsliFrI=') self.assertTrue(hasher.verify('lètmein', encoded)) def test_low_level_pbkdf2_sha1(self): hasher = PBKDF2SHA1PasswordHasher() encoded = hasher.encode('lètmein', 'seasalt2') - self.assertEqual(encoded, 'pbkdf2_sha1$36000$seasalt2$GoU+9AubJ/xRkO0WD1Xf3WPxWfE=') + self.assertEqual(encoded, 'pbkdf2_sha1$100000$seasalt2$dK/dL+ySBZ5zoR0+Zk3SB/VsH0U=') self.assertTrue(hasher.verify('lètmein', encoded)) @override_settings( From 98760ab0b2f1ce03234a5e6a52decd9f23d3994a Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 17 Jan 2017 10:03:23 -0500 Subject: [PATCH 0055/3180] Refs #25079 -- Removed obsolete system check for TEMPLATE_* settings. --- django/core/checks/__init__.py | 1 - .../core/checks/compatibility/django_1_8_0.py | 27 ----------------- docs/ref/checks.txt | 3 +- .../tests_1_8_compatibility.py | 29 ------------------- 4 files changed, 2 insertions(+), 58 deletions(-) delete mode 100644 django/core/checks/compatibility/django_1_8_0.py delete mode 100644 tests/check_framework/tests_1_8_compatibility.py diff --git a/django/core/checks/__init__.py b/django/core/checks/__init__.py index 4a7479ab2bbd..0aa23dbaf4bb 100644 --- a/django/core/checks/__init__.py +++ b/django/core/checks/__init__.py @@ -9,7 +9,6 @@ # Import these to force registration of checks import django.core.checks.caches # NOQA isort:skip -import django.core.checks.compatibility.django_1_8_0 # NOQA isort:skip import django.core.checks.compatibility.django_1_10 # NOQA isort:skip import django.core.checks.database # NOQA isort:skip import django.core.checks.model_checks # NOQA isort:skip diff --git a/django/core/checks/compatibility/django_1_8_0.py b/django/core/checks/compatibility/django_1_8_0.py deleted file mode 100644 index e5bbc6cfc5c5..000000000000 --- a/django/core/checks/compatibility/django_1_8_0.py +++ /dev/null @@ -1,27 +0,0 @@ -from __future__ import unicode_literals - -from django.conf import settings - -from .. import Tags, Warning, register - - -@register(Tags.compatibility) -def check_duplicate_template_settings(app_configs, **kwargs): - if settings.TEMPLATES: - values = [ - 'TEMPLATE_DIRS', - 'TEMPLATE_CONTEXT_PROCESSORS', - 'TEMPLATE_DEBUG', - 'TEMPLATE_LOADERS', - 'TEMPLATE_STRING_IF_INVALID', - ] - defined = [value for value in values if getattr(settings, value, None)] - if defined: - return [Warning( - "The standalone TEMPLATE_* settings were deprecated in Django " - "1.8 and the TEMPLATES dictionary takes precedence. You must " - "put the values of the following settings into your default " - "TEMPLATES dict: %s." % ", ".join(defined), - id='1_8.W001', - )] - return [] diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index f30d07d921c5..51083c5b2bf4 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -112,7 +112,8 @@ that might occur as a result of a version upgrade. Django 1.8 and the :setting:`TEMPLATES` dictionary takes precedence. You must put the values of the following settings into your defaults ``TEMPLATES`` dict: ``TEMPLATE_DIRS``, ``TEMPLATE_CONTEXT_PROCESSORS``, ``TEMPLATE_DEBUG``, - ``TEMPLATE_LOADERS``, ``TEMPLATE_STRING_IF_INVALID``. + ``TEMPLATE_LOADERS``, ``TEMPLATE_STRING_IF_INVALID``. *This check was removed + in Django 2.0*. * **1_10.W001**: The ``MIDDLEWARE_CLASSES`` setting is deprecated in Django 1.10 and the :setting:`MIDDLEWARE` setting takes precedence. Since you've set ``MIDDLEWARE``, the value of ``MIDDLEWARE_CLASSES`` is ignored. diff --git a/tests/check_framework/tests_1_8_compatibility.py b/tests/check_framework/tests_1_8_compatibility.py deleted file mode 100644 index d8601b106480..000000000000 --- a/tests/check_framework/tests_1_8_compatibility.py +++ /dev/null @@ -1,29 +0,0 @@ -from django.core.checks.compatibility.django_1_8_0 import \ - check_duplicate_template_settings -from django.test import SimpleTestCase -from django.test.utils import override_settings - - -class CheckDuplicateTemplateSettingsTest(SimpleTestCase): - - def test_not_raised_if_no_templates_setting(self): - self.assertEqual(check_duplicate_template_settings(None), []) - - @override_settings( - TEMPLATES=[{'BACKEND': 'django.template.backends.django.DjangoTemplates'}], - TEMPLATE_DIRS=['/path/to/dirs'], - ) - def test_duplicate_setting(self): - result = check_duplicate_template_settings(None) - self.assertEqual(result[0].id, '1_8.W001') - - @override_settings( - TEMPLATES=[{'BACKEND': 'django.template.backends.django.DjangoTemplates'}], - TEMPLATE_DIRS=['/path/to/dirs'], - TEMPLATE_DEBUG=True, - ) - def test_multiple_duplicate_settings(self): - result = check_duplicate_template_settings(None) - self.assertEqual(len(result), 1) - self.assertIn('TEMPLATE_DIRS', result[0].msg) - self.assertIn('TEMPLATE_DEBUG', result[0].msg) From 6192bffb130132461e55e5fe7a7eaaa9a166d08f Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 17 Jan 2017 10:06:02 -0500 Subject: [PATCH 0056/3180] Refs #26601 -- Removed obsolete system check for MIDDLEWARE_CLASSES setting. --- django/core/checks/__init__.py | 1 - django/core/checks/compatibility/django_1_10.py | 17 ----------------- docs/ref/checks.txt | 3 ++- .../check_framework/tests_1_10_compatibility.py | 17 ----------------- 4 files changed, 2 insertions(+), 36 deletions(-) delete mode 100644 django/core/checks/compatibility/django_1_10.py delete mode 100644 tests/check_framework/tests_1_10_compatibility.py diff --git a/django/core/checks/__init__.py b/django/core/checks/__init__.py index 0aa23dbaf4bb..f2194a3fc9fb 100644 --- a/django/core/checks/__init__.py +++ b/django/core/checks/__init__.py @@ -9,7 +9,6 @@ # Import these to force registration of checks import django.core.checks.caches # NOQA isort:skip -import django.core.checks.compatibility.django_1_10 # NOQA isort:skip import django.core.checks.database # NOQA isort:skip import django.core.checks.model_checks # NOQA isort:skip import django.core.checks.security.base # NOQA isort:skip diff --git a/django/core/checks/compatibility/django_1_10.py b/django/core/checks/compatibility/django_1_10.py deleted file mode 100644 index 120ef0b5b191..000000000000 --- a/django/core/checks/compatibility/django_1_10.py +++ /dev/null @@ -1,17 +0,0 @@ -from __future__ import unicode_literals - -from django.conf import settings - -from .. import Tags, Warning, register - - -@register(Tags.compatibility) -def check_duplicate_middleware_settings(app_configs, **kwargs): - if settings.MIDDLEWARE is not None and hasattr(settings, 'MIDDLEWARE_CLASSES'): - return [Warning( - "The MIDDLEWARE_CLASSES setting is deprecated in Django 1.10 " - "and the MIDDLEWARE setting takes precedence. Since you've set " - "MIDDLEWARE, the value of MIDDLEWARE_CLASSES is ignored.", - id='1_10.W001', - )] - return [] diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index 51083c5b2bf4..13ef44053ee6 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -116,7 +116,8 @@ that might occur as a result of a version upgrade. in Django 2.0*. * **1_10.W001**: The ``MIDDLEWARE_CLASSES`` setting is deprecated in Django 1.10 and the :setting:`MIDDLEWARE` setting takes precedence. Since you've - set ``MIDDLEWARE``, the value of ``MIDDLEWARE_CLASSES`` is ignored. + set ``MIDDLEWARE``, the value of ``MIDDLEWARE_CLASSES`` is ignored. *This + check was removed in Django 2.0*. Caches ------ diff --git a/tests/check_framework/tests_1_10_compatibility.py b/tests/check_framework/tests_1_10_compatibility.py deleted file mode 100644 index 388ac1b02431..000000000000 --- a/tests/check_framework/tests_1_10_compatibility.py +++ /dev/null @@ -1,17 +0,0 @@ -from django.core.checks.compatibility.django_1_10 import \ - check_duplicate_middleware_settings -from django.test import SimpleTestCase -from django.test.utils import override_settings - - -class CheckDuplicateMiddlwareSettingsTest(SimpleTestCase): - - @override_settings(MIDDLEWARE=[], MIDDLEWARE_CLASSES=['django.middleware.common.CommonMiddleware']) - def test_duplicate_setting(self): - result = check_duplicate_middleware_settings(None) - self.assertEqual(result[0].id, '1_10.W001') - - @override_settings(MIDDLEWARE=None) - def test_middleware_not_defined(self): - result = check_duplicate_middleware_settings(None) - self.assertEqual(len(result), 0) From 397b3705c5f762b359cdb494f9447c8a60685adf Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 17 Jan 2017 10:12:56 -0500 Subject: [PATCH 0057/3180] Removed settings.TEMPLATES upgrade guide. --- docs/ref/templates/index.txt | 1 - docs/ref/templates/upgrading.txt | 217 ------------------------------- docs/releases/1.10.txt | 4 +- docs/releases/1.8.txt | 5 +- 4 files changed, 3 insertions(+), 224 deletions(-) delete mode 100644 docs/ref/templates/upgrading.txt diff --git a/docs/ref/templates/index.txt b/docs/ref/templates/index.txt index e5730488c1a7..efc97494ae71 100644 --- a/docs/ref/templates/index.txt +++ b/docs/ref/templates/index.txt @@ -14,7 +14,6 @@ material, see :doc:`/topics/templates` topic guide. language builtins api - upgrading .. seealso:: diff --git a/docs/ref/templates/upgrading.txt b/docs/ref/templates/upgrading.txt deleted file mode 100644 index de2c6558ff79..000000000000 --- a/docs/ref/templates/upgrading.txt +++ /dev/null @@ -1,217 +0,0 @@ -================================= -Upgrading templates to Django 1.8 -================================= - -Django's template system was overhauled in Django 1.8 when it gained support -for multiple template engines. This document complements the :doc:`release -notes ` with detailed upgrade instructions on some topics. - -The :setting:`TEMPLATES` settings -================================= - -A new setting was introduced in Django 1.8: :setting:`TEMPLATES`. All existing -template-related settings were deprecated. - -During the deprecation period, Django will create a backwards-compatible -:setting:`TEMPLATES` based on the ``TEMPLATE_*`` settings if you don't define -it yourself. - -Here's how to define :setting:`TEMPLATES` in your settings module. - -If you're using the default value of ``TEMPLATE_LOADERS``, that is, if it -isn't defined in your settings file or if it's set to:: - - ['django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader'] - -then you should define :setting:`TEMPLATES` as follows:: - - TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [ - # insert your TEMPLATE_DIRS here - ], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this - # list if you haven't customized them: - 'django.contrib.auth.context_processors.auth', - 'django.template.context_processors.debug', - 'django.template.context_processors.i18n', - 'django.template.context_processors.media', - 'django.template.context_processors.static', - 'django.template.context_processors.tz', - 'django.contrib.messages.context_processors.messages', - ], - }, - }, - ] - -If you aren't using the default value of ``TEMPLATE_LOADERS``, then you should -define :setting:`TEMPLATES` as follows:: - - TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [ - # insert your TEMPLATE_DIRS here - ], - 'OPTIONS': { - 'context_processors': [ - # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this - # list if you haven't customized them: - 'django.contrib.auth.context_processors.auth', - 'django.template.context_processors.debug', - 'django.template.context_processors.i18n', - 'django.template.context_processors.media', - 'django.template.context_processors.static', - 'django.template.context_processors.tz', - 'django.contrib.messages.context_processors.messages', - ], - 'loaders': [ - # insert your TEMPLATE_LOADERS here - ] - }, - }, - ] - -Furthermore you should replace ``django.core.context_processors`` with -``django.template.context_processors`` in the names of context processors. - -If your settings module defines ``ALLOWED_INCLUDE_ROOTS`` or -``TEMPLATE_STRING_IF_INVALID``, include their values under the -``'allowed_include_roots'`` and ``'string_if_invalid'`` keys in the -``'OPTIONS'`` dictionary. - -If it sets ``TEMPLATE_DEBUG`` to a value that differs from :setting:`DEBUG`, -include that value under the ``'debug'`` key in ``'OPTIONS'``. - -Once you have defined :setting:`TEMPLATES`, you can safely remove -``ALLOWED_INCLUDE_ROOTS``, ``TEMPLATE_CONTEXT_PROCESSORS``, -``TEMPLATE_DEBUG``, ``TEMPLATE_DIRS``, ``TEMPLATE_LOADERS``, and -``TEMPLATE_STRING_IF_INVALID``. - -If you are overriding some of these settings in tests, you should override the -entire :setting:`TEMPLATES` setting instead. - -:mod:`django.template.loader` -============================= - -.. _get_template-upgrade-django-18: - -:func:`~django.template.loader.get_template` and :func:`~django.template.loader.select_template` ------------------------------------------------------------------------------------------------- - -In Django 1.8 :func:`~django.template.loader.get_template` and -:func:`~django.template.loader.select_template` return a backend-dependent -``Template`` instead of a :class:`django.template.Template`. - -For example, if :func:`~django.template.loader.get_template` loads a template -with a :class:`~django.template.backends.django.DjangoTemplates` backend, then -it returns a ``django.template.backends.django.Template``. - -``Template`` objects must provide a -:meth:`~django.template.backends.base.Template.render` method whose signature -differs slightly from the Django template language's -:meth:`~django.template.Template.render`. - -Instead of:: - - from django.template import Context - from django.template.loader import get_template - - template = get_template('hello.html') - html = template.render(Context({'name': 'world'})) - -You should write:: - - from django.template.loader import get_template - - template = get_template('hello.html') - html = template.render({'name': 'world'}) - -And instead of:: - - from django.template import RequestContext - from django.template.loader import get_template - - template = get_template('hello.html') - html = template.render(RequestContext(request, {'name': 'world'})) - -You should write:: - - from django.template.loader import get_template - - template = get_template('hello.html') - html = template.render({'name': 'world'}, request) - -Passing a :class:`~django.template.Context` or a -:class:`~django.template.RequestContext` is still possible when the template -is loaded by a :class:`~django.template.backends.django.DjangoTemplates` -backend but it's deprecated and won't be supported in Django 1.10. - -If you're loading a template while you're rendering another template with the -Django template language and you have access to the current context, for -instance in the ``render()`` method of a template tag, you can use the current -:class:`~django.template.Engine` directly. Instead of:: - - from django.template.loader import get_template - template = get_template('included.html') - -You can write:: - - template = context.template.engine.get_template('included.html') - -This will load the template with the current engine without triggering the -multiple template engines machinery, which is usually the desired behavior. -Unlike previous solutions, this returns a :class:`django.template.Template`, -like :func:`~django.template.loader.get_template` used to in Django 1.7 and -earlier, avoiding all backwards-compatibility problems. - -``get_template_from_string()`` ------------------------------- - -Private API ``get_template_from_string(template_code)`` was removed in Django -1.8 because it had no way to choose an engine to compile the template. - -Three alternatives are available. - -If you control the project's setting, you can use one of the configured -engines:: - - from django.template import engines - - template = engines['django'].from_string(template_code) - -This returns a backend-dependent ``Template`` object. - -For trivial templates that don't need context processors nor anything else, -you can create a bare-bones engine and use its ``from_string()`` method:: - - from django.template import Engine - - template = Engine().from_string(template_code) - -This returns a :class:`django.template.Template` because -:class:`~django.template.Engine` is part of the Django template language's -APIs. The multiple template engines machinery isn't involved here. - -Finally, if you have access to the current context, you can use the same trick -as above:: - - template = context.template.engine.from_string(template_code) - -``Template()`` -============== - -To a lesser extent, instantiating a template with ``Template(template_code)`` -suffers from the same issue as ``get_template_from_string()``. - -It still works when the :setting:`TEMPLATES` setting defines exactly one -:class:`~django.template.backends.django.DjangoTemplates` backend, but -pluggable applications can't control this requirement. - -The last two solutions described in the previous section are recommended in -that case. diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt index adca25e0ac9f..a84912941a40 100644 --- a/docs/releases/1.10.txt +++ b/docs/releases/1.10.txt @@ -1269,8 +1269,8 @@ to remove usage of these features. * The backwards compatibility shim to allow ``FormMixin.get_form()`` to be defined with no default value for its ``form_class`` argument is removed. -* The following settings are removed, and :doc:`you must upgrade - ` to the :setting:`TEMPLATES` setting: +* The following settings are removed, and you must upgrade to the + :setting:`TEMPLATES` setting: * ``ALLOWED_INCLUDE_ROOTS`` * ``TEMPLATE_CONTEXT_PROCESSORS`` diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index 578f53a5b46a..3e5778417bc6 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -61,7 +61,7 @@ built-in support for the Django template language and for :class:`~django.template.backends.jinja2.Jinja2`. It supports rendering templates with multiple engines within the same project. Learn more about the new features in the :doc:`topic guide ` and check the -:doc:`upgrade instructions ` for details. +upgrade instructions in older versions of the documentation. Security enhancements --------------------- @@ -1522,9 +1522,6 @@ Both classes provide a ``render()`` method, however, the former takes a :class:`dict`. This change is enforced through a deprecation path for Django templates. -Since it's easier to understand with examples, the :ref:`upgrade guide -` shows how to adapt affected code. - All this also applies to :func:`~django.template.loader.select_template()`. :class:`~django.template.Template` and :class:`~django.template.Context` classes in template responses From d7b9aaa366dd54ecc3142c588162e3adc7c2f7ac Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Sat, 19 Nov 2016 18:19:41 +0100 Subject: [PATCH 0058/3180] Refs #23919 -- Removed encoding preambles and future imports --- django/__init__.py | 2 -- django/conf/app_template/admin.py-tpl | 2 +- django/conf/app_template/apps.py-tpl | 2 +- django/conf/app_template/models.py-tpl | 2 +- django/conf/app_template/tests.py-tpl | 2 +- django/conf/app_template/views.py-tpl | 2 +- django/conf/global_settings.py | 2 -- django/conf/locale/__init__.py | 3 --- django/conf/locale/ar/formats.py | 3 --- django/conf/locale/az/formats.py | 3 --- django/conf/locale/bg/formats.py | 3 --- django/conf/locale/bn/formats.py | 3 --- django/conf/locale/bs/formats.py | 3 --- django/conf/locale/ca/formats.py | 3 --- django/conf/locale/cs/formats.py | 3 --- django/conf/locale/cy/formats.py | 3 --- django/conf/locale/da/formats.py | 3 --- django/conf/locale/de/formats.py | 3 --- django/conf/locale/de_CH/formats.py | 4 --- django/conf/locale/el/formats.py | 3 --- django/conf/locale/en/formats.py | 3 --- django/conf/locale/en_AU/formats.py | 3 --- django/conf/locale/en_GB/formats.py | 3 --- django/conf/locale/eo/formats.py | 3 --- django/conf/locale/es/formats.py | 3 --- django/conf/locale/es_AR/formats.py | 3 --- django/conf/locale/es_CO/formats.py | 3 --- django/conf/locale/es_MX/formats.py | 3 --- django/conf/locale/es_NI/formats.py | 3 --- django/conf/locale/es_PR/formats.py | 3 --- django/conf/locale/et/formats.py | 3 --- django/conf/locale/eu/formats.py | 3 --- django/conf/locale/fa/formats.py | 3 --- django/conf/locale/fi/formats.py | 3 --- django/conf/locale/fr/formats.py | 3 --- django/conf/locale/fy/formats.py | 3 --- django/conf/locale/ga/formats.py | 3 --- django/conf/locale/gd/formats.py | 3 --- django/conf/locale/gl/formats.py | 3 --- django/conf/locale/he/formats.py | 3 --- django/conf/locale/hi/formats.py | 3 --- django/conf/locale/hr/formats.py | 3 --- django/conf/locale/hu/formats.py | 3 --- django/conf/locale/id/formats.py | 3 --- django/conf/locale/is/formats.py | 3 --- django/conf/locale/it/formats.py | 3 --- django/conf/locale/ja/formats.py | 3 --- django/conf/locale/ka/formats.py | 3 --- django/conf/locale/km/formats.py | 3 --- django/conf/locale/kn/formats.py | 3 --- django/conf/locale/ko/formats.py | 3 --- django/conf/locale/lt/formats.py | 3 --- django/conf/locale/lv/formats.py | 3 --- django/conf/locale/mk/formats.py | 3 --- django/conf/locale/ml/formats.py | 3 --- django/conf/locale/mn/formats.py | 3 --- django/conf/locale/nb/formats.py | 3 --- django/conf/locale/nl/formats.py | 3 --- django/conf/locale/nn/formats.py | 3 --- django/conf/locale/pl/formats.py | 3 --- django/conf/locale/pt/formats.py | 3 --- django/conf/locale/pt_BR/formats.py | 3 --- django/conf/locale/ro/formats.py | 3 --- django/conf/locale/ru/formats.py | 3 --- django/conf/locale/sk/formats.py | 3 --- django/conf/locale/sl/formats.py | 3 --- django/conf/locale/sq/formats.py | 3 --- django/conf/locale/sr/formats.py | 3 --- django/conf/locale/sr_Latn/formats.py | 3 --- django/conf/locale/sv/formats.py | 3 --- django/conf/locale/ta/formats.py | 3 --- django/conf/locale/te/formats.py | 3 --- django/conf/locale/th/formats.py | 3 --- django/conf/locale/tr/formats.py | 3 --- django/conf/locale/uk/formats.py | 4 --- django/conf/locale/vi/formats.py | 3 --- django/conf/locale/zh_Hans/formats.py | 3 --- django/conf/locale/zh_Hant/formats.py | 3 --- django/contrib/admin/checks.py | 3 --- django/contrib/admin/forms.py | 2 -- django/contrib/admin/helpers.py | 2 -- .../contrib/admin/migrations/0001_initial.py | 3 --- .../0002_logentry_remove_auto_add.py | 3 --- django/contrib/admin/models.py | 2 -- django/contrib/admin/options.py | 2 -- .../contrib/admin/templatetags/admin_list.py | 2 -- django/contrib/admin/utils.py | 2 -- django/contrib/admin/widgets.py | 2 -- django/contrib/auth/backends.py | 2 -- django/contrib/auth/base_user.py | 2 -- django/contrib/auth/checks.py | 3 --- django/contrib/auth/forms.py | 2 -- django/contrib/auth/hashers.py | 2 -- django/contrib/auth/management/__init__.py | 2 -- .../management/commands/changepassword.py | 2 -- .../management/commands/createsuperuser.py | 2 -- .../contrib/auth/migrations/0001_initial.py | 3 --- .../0002_alter_permission_name_max_length.py | 3 --- .../0003_alter_user_email_max_length.py | 3 --- .../0004_alter_user_username_opts.py | 3 --- .../0005_alter_user_last_login_null.py | 3 --- .../0006_require_contenttypes_0002.py | 3 --- ...007_alter_validators_add_error_messages.py | 3 --- .../0008_alter_user_username_max_length.py | 3 --- django/contrib/auth/models.py | 2 -- django/contrib/auth/password_validation.py | 2 -- django/contrib/contenttypes/admin.py | 2 -- django/contrib/contenttypes/checks.py | 3 --- django/contrib/contenttypes/fields.py | 2 -- django/contrib/contenttypes/forms.py | 2 -- .../contenttypes/migrations/0001_initial.py | 3 --- .../0002_remove_content_type_name.py | 3 --- django/contrib/contenttypes/models.py | 2 -- django/contrib/contenttypes/views.py | 2 -- .../flatpages/migrations/0001_initial.py | 3 --- django/contrib/flatpages/models.py | 2 -- .../gis/db/backends/postgis/adapter.py | 2 -- django/contrib/gis/db/models/lookups.py | 2 -- .../contrib/gis/db/models/sql/conversion.py | 2 -- django/contrib/gis/feeds.py | 2 -- django/contrib/gis/forms/fields.py | 2 -- django/contrib/gis/forms/widgets.py | 2 -- django/contrib/gis/gdal/libgdal.py | 2 -- django/contrib/gis/geos/geometry.py | 2 -- django/contrib/gis/serializers/geojson.py | 2 -- django/contrib/gis/sitemaps/views.py | 2 -- django/contrib/gis/views.py | 2 -- .../contrib/humanize/templatetags/humanize.py | 3 --- django/contrib/messages/storage/base.py | 2 -- django/contrib/postgres/indexes.py | 2 -- django/contrib/postgres/utils.py | 2 -- django/contrib/redirects/middleware.py | 2 -- .../redirects/migrations/0001_initial.py | 3 --- django/contrib/sessions/backends/base.py | 2 -- django/contrib/sessions/base_session.py | 2 -- .../sessions/migrations/0001_initial.py | 3 --- django/contrib/sessions/models.py | 2 -- django/contrib/sites/managers.py | 3 --- .../contrib/sites/migrations/0001_initial.py | 3 --- .../migrations/0002_alter_domain_unique.py | 3 --- django/contrib/sites/models.py | 2 -- django/contrib/sites/requests.py | 2 -- django/contrib/sites/shortcuts.py | 2 -- .../management/commands/collectstatic.py | 2 -- .../management/commands/findstatic.py | 2 -- django/contrib/staticfiles/storage.py | 2 -- django/contrib/syndication/views.py | 2 -- django/core/cache/backends/base.py | 2 -- django/core/cache/utils.py | 2 -- django/core/checks/__init__.py | 3 --- django/core/checks/caches.py | 2 -- django/core/checks/messages.py | 3 --- django/core/checks/model_checks.py | 3 --- django/core/checks/registry.py | 3 --- django/core/checks/templates.py | 3 --- django/core/checks/urls.py | 2 -- django/core/files/base.py | 2 -- django/core/files/uploadhandler.py | 2 -- django/core/handlers/base.py | 2 -- django/core/handlers/exception.py | 2 -- django/core/handlers/wsgi.py | 2 -- django/core/mail/__init__.py | 2 -- django/core/mail/message.py | 2 -- django/core/management/__init__.py | 2 -- django/core/management/base.py | 3 --- django/core/management/commands/check.py | 3 --- .../management/commands/compilemessages.py | 2 -- django/core/management/commands/flush.py | 2 -- django/core/management/commands/inspectdb.py | 4 --- django/core/management/commands/loaddata.py | 2 -- .../core/management/commands/makemessages.py | 2 -- django/core/management/commands/migrate.py | 3 --- django/core/management/commands/runserver.py | 2 -- .../management/commands/showmigrations.py | 3 --- django/core/management/commands/sqlflush.py | 2 -- django/core/management/commands/sqlmigrate.py | 3 --- .../management/commands/sqlsequencereset.py | 2 -- django/core/management/sql.py | 2 -- django/core/management/templates.py | 2 -- django/core/management/utils.py | 2 -- django/core/serializers/json.py | 3 --- django/core/serializers/python.py | 2 -- django/core/serializers/xml_serializer.py | 2 -- django/core/servers/basehttp.py | 2 -- django/core/signing.py | 2 -- django/core/validators.py | 2 -- django/db/backends/mysql/base.py | 2 -- django/db/backends/mysql/operations.py | 2 -- django/db/backends/oracle/base.py | 2 -- django/db/backends/oracle/operations.py | 2 -- .../db/backends/postgresql/introspection.py | 2 -- django/db/backends/postgresql/operations.py | 2 -- django/db/backends/sqlite3/base.py | 2 -- django/db/backends/sqlite3/features.py | 2 -- django/db/backends/sqlite3/operations.py | 2 -- django/db/backends/utils.py | 2 -- django/db/migrations/autodetector.py | 2 -- django/db/migrations/exceptions.py | 2 -- django/db/migrations/executor.py | 2 -- django/db/migrations/graph.py | 2 -- django/db/migrations/loader.py | 2 -- django/db/migrations/migration.py | 2 -- django/db/migrations/operations/base.py | 2 -- django/db/migrations/operations/fields.py | 2 -- django/db/migrations/operations/models.py | 2 -- django/db/migrations/operations/special.py | 2 -- django/db/migrations/optimizer.py | 3 --- django/db/migrations/questioner.py | 2 -- django/db/migrations/recorder.py | 2 -- django/db/migrations/serializer.py | 2 -- django/db/migrations/state.py | 2 -- django/db/migrations/writer.py | 4 --- django/db/models/base.py | 2 -- django/db/models/fields/__init__.py | 3 --- django/db/models/fields/related.py | 2 -- .../db/models/fields/related_descriptors.py | 2 -- django/db/models/fields/reverse_related.py | 2 -- django/db/models/functions/datetime.py | 2 -- django/db/models/indexes.py | 2 -- django/db/models/options.py | 2 -- django/db/models/query_utils.py | 2 -- django/forms/boundfield.py | 2 -- django/forms/fields.py | 2 -- django/forms/forms.py | 2 -- django/forms/formsets.py | 2 -- django/forms/models.py | 2 -- django/forms/utils.py | 2 -- django/forms/widgets.py | 2 -- django/http/cookie.py | 2 -- django/http/multipartparser.py | 2 -- django/http/request.py | 2 -- django/http/response.py | 2 -- django/middleware/csrf.py | 2 -- django/template/backends/base.py | 3 --- django/template/backends/django.py | 3 --- django/template/backends/dummy.py | 3 --- django/template/backends/jinja2.py | 3 --- django/template/backends/utils.py | 3 --- django/template/base.py | 2 -- django/template/context_processors.py | 2 -- django/template/defaultfilters.py | 2 -- django/template/defaulttags.py | 2 -- django/templatetags/cache.py | 2 -- django/templatetags/i18n.py | 2 -- django/test/client.py | 2 -- django/test/html.py | 2 -- django/test/selenium.py | 2 -- django/test/testcases.py | 2 -- django/urls/base.py | 2 -- django/urls/exceptions.py | 2 -- django/urls/resolvers.py | 2 -- django/urls/utils.py | 2 -- django/utils/_os.py | 2 -- django/utils/cache.py | 2 -- django/utils/crypto.py | 2 -- django/utils/dateformat.py | 2 -- django/utils/deprecation.py | 2 -- django/utils/encoding.py | 3 --- django/utils/feedgenerator.py | 2 -- django/utils/glob.py | 2 -- django/utils/html.py | 2 -- django/utils/http.py | 2 -- django/utils/inspect.py | 2 -- django/utils/jslex.py | 2 -- django/utils/log.py | 2 -- django/utils/lorem_ipsum.py | 2 -- django/utils/numberformat.py | 2 -- django/utils/regex_helper.py | 2 -- django/utils/six.py | 2 -- django/utils/text.py | 2 -- django/utils/timesince.py | 2 -- django/utils/translation/__init__.py | 2 -- django/utils/translation/template.py | 2 -- django/utils/translation/trans_real.py | 2 -- django/utils/version.py | 2 -- django/views/debug.py | 2 -- django/views/generic/base.py | 2 -- django/views/generic/dates.py | 2 -- django/views/generic/detail.py | 2 -- django/views/generic/list.py | 2 -- django/views/static.py | 2 -- docs/conf.py | 4 --- docs/howto/writing-migrations.txt | 6 ----- docs/ref/files/file.txt | 1 - docs/ref/migration-operations.txt | 3 --- docs/topics/i18n/formatting.txt | 2 -- docs/topics/migrations.txt | 26 ------------------- docs/topics/templates.txt | 2 -- tests/admin_changelist/tests.py | 2 -- tests/admin_checks/tests.py | 2 -- tests/admin_custom_urls/tests.py | 2 -- tests/admin_docs/test_middleware.py | 2 -- tests/admin_docs/test_utils.py | 2 -- tests/admin_docs/test_views.py | 2 -- tests/admin_docs/tests.py | 2 -- tests/admin_filters/models.py | 2 -- tests/admin_filters/tests.py | 2 -- tests/admin_inlines/models.py | 3 --- tests/admin_inlines/test_templates.py | 2 -- tests/admin_inlines/tests.py | 2 -- tests/admin_ordering/models.py | 1 - tests/admin_ordering/tests.py | 2 -- tests/admin_registration/tests.py | 2 -- .../migrations/0001_initial.py | 2 -- .../another_app_waiting_migration/models.py | 2 -- .../app_raising_messages/models.py | 3 --- .../app_raising_warning/models.py | 3 --- .../migrations/0001_initial.py | 2 -- .../app_waiting_migration/models.py | 2 -- tests/admin_scripts/tests.py | 22 +--------------- tests/admin_utils/test_logentry.py | 3 --- tests/admin_utils/tests.py | 2 -- tests/admin_views/admin.py | 3 --- .../custom_has_permission_admin.py | 2 -- tests/admin_views/customadmin.py | 2 -- tests/admin_views/models.py | 3 --- tests/admin_views/test_adminsite.py | 2 -- tests/admin_views/test_templatetags.py | 2 -- tests/admin_views/tests.py | 3 --- tests/admin_widgets/models.py | 2 -- tests/admin_widgets/tests.py | 3 --- tests/aggregation/models.py | 1 - tests/aggregation/tests.py | 2 -- tests/aggregation_regress/models.py | 1 - tests/aggregation_regress/tests.py | 2 -- tests/annotations/models.py | 1 - tests/annotations/tests.py | 2 -- tests/app_loading/tests.py | 2 -- tests/apps/apps.py | 2 -- tests/apps/models.py | 2 -- tests/apps/tests.py | 2 -- tests/auth_tests/test_auth_backends.py | 2 -- tests/auth_tests/test_basic.py | 3 --- tests/auth_tests/test_checks.py | 2 -- tests/auth_tests/test_deprecated_views.py | 3 --- tests/auth_tests/test_forms.py | 3 --- tests/auth_tests/test_handlers.py | 2 -- tests/auth_tests/test_hashers.py | 3 --- tests/auth_tests/test_management.py | 2 -- tests/auth_tests/test_models.py | 3 --- tests/auth_tests/test_validators.py | 3 --- tests/auth_tests/test_views.py | 3 --- tests/backends/models.py | 2 -- tests/backends/test_mysql.py | 2 -- tests/backends/tests.py | 3 --- tests/base/models.py | 2 -- tests/basic/models.py | 1 - tests/basic/tests.py | 2 -- tests/builtin_server/tests.py | 2 -- tests/bulk_create/tests.py | 2 -- tests/cache/tests.py | 4 --- tests/check_framework/models.py | 3 --- tests/check_framework/tests.py | 3 --- tests/conditional_processing/tests.py | 3 --- tests/contenttypes_tests/models.py | 2 -- .../operations_migrations/0001_initial.py | 3 --- .../operations_migrations/0002_rename_foo.py | 3 --- tests/contenttypes_tests/test_models.py | 2 -- tests/contenttypes_tests/tests.py | 3 --- tests/contenttypes_tests/urls.py | 2 -- tests/csrf_tests/tests.py | 3 --- tests/csrf_tests/views.py | 2 -- tests/custom_columns/models.py | 2 -- tests/custom_columns/tests.py | 2 -- tests/custom_lookups/tests.py | 2 -- tests/custom_managers/models.py | 2 -- tests/custom_managers/tests.py | 2 -- tests/custom_methods/tests.py | 2 -- tests/custom_pk/models.py | 3 --- tests/custom_pk/tests.py | 3 --- tests/datatypes/tests.py | 2 -- tests/dates/models.py | 2 -- tests/dates/tests.py | 2 -- tests/datetimes/models.py | 2 -- tests/datetimes/tests.py | 2 -- tests/db_functions/models.py | 2 -- tests/db_functions/test_datetime.py | 2 -- tests/db_functions/tests.py | 2 -- tests/dbshell/test_postgresql_psycopg2.py | 3 --- tests/defer/tests.py | 2 -- tests/defer_regress/tests.py | 2 -- tests/delete/models.py | 2 -- tests/delete/tests.py | 2 -- tests/delete_regress/tests.py | 2 -- tests/deprecation/tests.py | 2 -- tests/distinct_on_fields/models.py | 2 -- tests/distinct_on_fields/tests.py | 2 -- tests/expressions/models.py | 2 -- tests/expressions/test_queryset_values.py | 2 -- tests/expressions/tests.py | 2 -- tests/expressions_case/models.py | 2 -- tests/expressions_case/tests.py | 2 -- tests/extra_regress/models.py | 2 -- tests/extra_regress/tests.py | 2 -- tests/field_deconstruction/tests.py | 2 -- tests/field_defaults/models.py | 1 - tests/field_subclassing/fields.py | 2 -- tests/field_subclassing/tests.py | 2 -- tests/file_storage/tests.py | 3 --- tests/file_uploads/tests.py | 3 --- tests/file_uploads/views.py | 2 -- tests/files/tests.py | 3 --- tests/fixtures/tests.py | 2 -- tests/fixtures_model_package/tests.py | 2 -- tests/fixtures_regress/models.py | 2 -- tests/fixtures_regress/tests.py | 3 --- tests/flatpages_tests/test_forms.py | 2 -- tests/flatpages_tests/test_models.py | 4 --- tests/flatpages_tests/test_sitemaps.py | 2 -- tests/force_insert_update/tests.py | 2 -- .../field_tests/test_booleanfield.py | 2 -- .../forms_tests/field_tests/test_charfield.py | 2 -- .../field_tests/test_choicefield.py | 3 --- .../field_tests/test_combofield.py | 2 -- .../forms_tests/field_tests/test_datefield.py | 1 - .../field_tests/test_datetimefield.py | 2 -- .../field_tests/test_decimalfield.py | 3 --- .../field_tests/test_durationfield.py | 2 -- .../field_tests/test_emailfield.py | 3 --- .../forms_tests/field_tests/test_filefield.py | 3 --- .../field_tests/test_filepathfield.py | 2 -- .../field_tests/test_floatfield.py | 2 -- .../field_tests/test_genericipaddressfield.py | 2 -- .../field_tests/test_imagefield.py | 2 -- .../field_tests/test_integerfield.py | 3 --- .../field_tests/test_multiplechoicefield.py | 2 -- .../field_tests/test_nullbooleanfield.py | 2 -- .../field_tests/test_regexfield.py | 3 --- .../forms_tests/field_tests/test_slugfield.py | 3 --- .../field_tests/test_splitdatetimefield.py | 2 -- .../forms_tests/field_tests/test_timefield.py | 2 -- .../field_tests/test_typedchoicefield.py | 2 -- .../test_typedmultiplechoicefield.py | 2 -- .../forms_tests/field_tests/test_urlfield.py | 3 --- .../forms_tests/field_tests/test_uuidfield.py | 2 -- tests/forms_tests/models.py | 3 --- .../forms_tests/tests/test_error_messages.py | 3 --- tests/forms_tests/tests/test_forms.py | 3 --- tests/forms_tests/tests/test_formsets.py | 3 --- tests/forms_tests/tests/test_i18n.py | 2 -- tests/forms_tests/tests/test_media.py | 1 - tests/forms_tests/tests/test_utils.py | 3 --- tests/forms_tests/tests/test_validators.py | 2 -- tests/forms_tests/tests/test_widgets.py | 2 -- tests/forms_tests/tests/tests.py | 3 --- tests/forms_tests/widget_tests/test_select.py | 3 --- .../widget_tests/test_textinput.py | 3 --- tests/forms_tests/widget_tests/test_widget.py | 2 -- tests/generic_inline_admin/tests.py | 3 --- tests/generic_relations/models.py | 2 -- tests/generic_relations/tests.py | 2 -- tests/generic_views/forms.py | 2 -- tests/generic_views/test_base.py | 2 -- tests/generic_views/test_dates.py | 3 --- tests/generic_views/test_detail.py | 3 --- tests/generic_views/test_edit.py | 2 -- tests/generic_views/test_list.py | 3 --- tests/generic_views/urls.py | 3 --- tests/generic_views/views.py | 2 -- tests/get_earliest_or_latest/tests.py | 2 -- tests/get_object_or_404/tests.py | 2 -- tests/get_or_create/models.py | 2 -- tests/get_or_create/tests.py | 2 -- tests/gis_tests/distapp/tests.py | 2 -- tests/gis_tests/gdal_tests/test_srs.py | 3 --- tests/gis_tests/geo3d/tests.py | 2 -- tests/gis_tests/geoadmin/tests.py | 2 -- tests/gis_tests/geoapp/feeds.py | 2 -- tests/gis_tests/geoapp/test_feeds.py | 2 -- tests/gis_tests/geoapp/test_functions.py | 2 -- tests/gis_tests/geoapp/test_regress.py | 3 --- tests/gis_tests/geoapp/test_serializers.py | 2 -- tests/gis_tests/geoapp/test_sitemaps.py | 2 -- tests/gis_tests/geoapp/tests.py | 2 -- tests/gis_tests/geoapp/urls.py | 2 -- tests/gis_tests/geogapp/tests.py | 2 -- tests/gis_tests/geos_tests/test_geos.py | 2 -- tests/gis_tests/geos_tests/test_io.py | 2 -- .../gis_tests/gis_migrations/test_commands.py | 2 -- .../gis_migrations/test_operations.py | 2 -- tests/gis_tests/inspectapp/tests.py | 2 -- tests/gis_tests/layermap/tests.py | 3 --- tests/gis_tests/relatedapp/tests.py | 2 -- tests/gis_tests/test_geoip2.py | 3 --- tests/handlers/tests.py | 4 --- tests/handlers/urls.py | 2 -- tests/handlers/views.py | 2 -- tests/httpwrappers/tests.py | 3 --- tests/humanize_tests/tests.py | 2 -- tests/i18n/contenttypes/tests.py | 3 --- tests/i18n/patterns/tests.py | 2 -- tests/i18n/test_compilation.py | 3 --- tests/i18n/test_extraction.py | 3 --- tests/i18n/test_percents.py | 3 --- tests/i18n/tests.py | 3 --- tests/i18n/urls.py | 2 -- tests/inline_formsets/models.py | 1 - tests/inline_formsets/tests.py | 2 -- tests/inspectdb/models.py | 3 --- tests/inspectdb/tests.py | 3 --- tests/introspection/models.py | 2 -- tests/introspection/tests.py | 2 -- .../test_backend_specific.py | 3 --- tests/invalid_models_tests/test_models.py | 3 --- .../test_ordinary_fields.py | 3 --- .../test_relative_fields.py | 3 --- tests/known_related_objects/tests.py | 2 -- tests/logging_tests/tests.py | 3 --- tests/logging_tests/urls.py | 2 -- tests/logging_tests/urls_i18n.py | 2 -- tests/logging_tests/views.py | 2 -- tests/lookup/models.py | 2 -- tests/lookup/test_timefield.py | 2 -- tests/lookup/tests.py | 2 -- tests/m2m_and_m2o/models.py | 2 -- tests/m2m_intermediary/models.py | 2 -- tests/m2m_intermediary/tests.py | 2 -- tests/m2m_multiple/tests.py | 2 -- tests/m2m_recursive/tests.py | 2 -- tests/m2m_regress/tests.py | 2 -- tests/m2m_through/tests.py | 2 -- tests/m2m_through_regress/models.py | 2 -- tests/m2m_through_regress/test_multitable.py | 2 -- tests/m2m_through_regress/tests.py | 2 -- tests/m2o_recursive/tests.py | 2 -- tests/mail/test_sendtestemail.py | 2 -- tests/mail/tests.py | 3 --- tests/managers_regress/tests.py | 2 -- tests/many_to_many/models.py | 2 -- tests/many_to_many/tests.py | 2 -- tests/many_to_one/models.py | 2 -- tests/many_to_one_null/tests.py | 2 -- tests/max_lengths/tests.py | 2 -- tests/middleware/tests.py | 3 --- tests/middleware_exceptions/middleware.py | 2 -- .../custom_migrations/0001_initial.py | 3 --- .../migrations/0001_initial.py | 3 --- .../migrations/0002_add_book.py | 3 --- .../0001_initial.py | 3 --- .../0002_remove_ipaddressfield_ip.py | 3 --- .../author_app/migrations/0001_initial.py | 3 --- .../author_app/migrations/0002_alter_id.py | 3 --- .../book_app/migrations/0001_initial.py | 3 --- .../migrations/0001_initial.py | 3 --- .../migrations/0002_conflicting_second.py | 3 --- .../migrations/0002_second.py | 3 --- .../lookuperror_a/migrations/0001_initial.py | 3 --- .../lookuperror_a/migrations/0002_a2.py | 3 --- .../lookuperror_a/migrations/0003_a3.py | 3 --- .../lookuperror_a/migrations/0004_a4.py | 3 --- .../lookuperror_b/migrations/0001_initial.py | 3 --- .../lookuperror_b/migrations/0002_b2.py | 3 --- .../lookuperror_b/migrations/0003_b3.py | 3 --- .../lookuperror_c/migrations/0001_initial.py | 3 --- .../lookuperror_c/migrations/0002_c2.py | 3 --- .../lookuperror_c/migrations/0003_c3.py | 3 --- .../migrated_app/migrations/0001_initial.py | 3 --- .../migrations/0001_initial.py | 3 --- .../mutate_state_a/migrations/0001_initial.py | 3 --- .../mutate_state_b/migrations/0001_initial.py | 3 --- .../migrations/0002_add_field.py | 3 --- .../unmigrated_app/models.py | 3 --- .../migrations/0001_initial.py | 3 --- .../migrations/0002_conflicting_second.py | 3 --- .../migrations/0002_second.py | 3 --- tests/migrations/models.py | 3 --- .../0001_initial.py | 2 -- .../0002_initial.py | 2 -- .../test_auto_now_add/0001_initial.py | 3 --- tests/migrations/test_autodetector.py | 1 - tests/migrations/test_commands.py | 9 ------- tests/migrations/test_loader.py | 2 -- .../test_migrations/0001_initial.py | 3 --- .../migrations/test_migrations/0002_second.py | 3 --- .../0001_initial.py | 3 --- .../0001_initial.py | 3 --- .../0002_second.py | 3 --- .../test_migrations_conflict/0001_initial.py | 3 --- .../0002_conflicting_second.py | 3 --- .../test_migrations_conflict/0002_second.py | 3 --- .../0001_initial.py | 3 --- .../0001_initial.py | 3 --- .../0002_second.py | 3 --- .../test_migrations_first/second.py | 3 --- .../test_migrations_first/thefirst.py | 3 --- .../0001_not_initial.py | 3 --- .../0001_initial.py | 3 --- .../0002_conflicting_second.py | 3 --- .../0002_second.py | 3 --- .../0001_initial.py | 3 --- .../test_migrations_no_changes/0002_second.py | 3 --- .../test_migrations_no_changes/0003_third.py | 3 --- .../0001_initial.py | 3 --- .../0001_initial.py | 3 --- .../migrations/test_migrations_order/0001.py | 3 --- .../0001_initial.py | 3 --- .../test_migrations_run_before/0002_second.py | 3 --- .../test_migrations_run_before/0003_third.py | 3 --- .../test_migrations_squashed/0001_initial.py | 3 --- .../0001_squashed_0002.py | 3 --- .../test_migrations_squashed/0002_second.py | 3 --- .../1_auto.py | 3 --- .../2_auto.py | 3 --- .../3_auto.py | 3 --- .../3_squashed_5.py | 3 --- .../4_auto.py | 3 --- .../5_auto.py | 3 --- .../6_auto.py | 3 --- .../7_auto.py | 3 --- .../app1/1_auto.py | 3 --- .../app1/2_auto.py | 3 --- .../app1/2_squashed_3.py | 3 --- .../app1/3_auto.py | 3 --- .../app1/4_auto.py | 3 --- .../app2/1_auto.py | 3 --- .../app2/1_squashed_2.py | 3 --- .../app2/2_auto.py | 3 --- .../1_auto.py | 3 --- .../2_auto.py | 3 --- .../3_squashed_5.py | 3 --- .../6_auto.py | 3 --- .../7_auto.py | 3 --- .../0001_initial.py | 3 --- .../0001_squashed_0002.py | 3 --- .../0002_second.py | 3 --- .../0003_third.py | 3 --- .../app1/1_auto.py | 3 --- .../app1/2_auto.py | 3 --- .../app1/2_squashed_3.py | 3 --- .../app1/3_auto.py | 3 --- .../app1/4_auto.py | 3 --- .../app2/1_auto.py | 3 --- .../app2/1_squashed_2.py | 3 --- .../app2/2_auto.py | 3 --- .../test_migrations_unmigdep/0001_initial.py | 3 --- tests/migrations/test_operations.py | 2 -- tests/migrations/test_optimizer.py | 2 -- tests/migrations/test_questioner.py | 2 -- tests/migrations/test_writer.py | 4 --- .../test_migrations_2/0001_initial.py | 3 --- .../test_migrations_2_first/0001_initial.py | 3 --- .../test_migrations_2_first/0002_second.py | 3 --- .../test_migrations_2_no_deps/0001_initial.py | 3 --- tests/model_fields/test_charfield.py | 3 --- tests/model_fields/test_imagefield.py | 2 -- tests/model_fields/test_promises.py | 2 -- tests/model_fields/test_slugfield.py | 3 --- tests/model_fields/test_textfield.py | 3 --- tests/model_forms/models.py | 2 -- tests/model_forms/test_uuid.py | 2 -- tests/model_forms/tests.py | 2 -- tests/model_formsets/models.py | 2 -- tests/model_formsets/tests.py | 2 -- tests/model_formsets_regress/tests.py | 2 -- tests/model_inheritance/models.py | 2 -- .../test_abstract_inheritance.py | 2 -- tests/model_inheritance/tests.py | 2 -- tests/model_inheritance_regress/models.py | 2 -- tests/model_inheritance_regress/tests.py | 2 -- tests/model_options/test_tablespaces.py | 2 -- tests/model_package/tests.py | 2 -- tests/model_regress/models.py | 3 --- tests/model_regress/tests.py | 2 -- tests/modeladmin/models.py | 1 - tests/modeladmin/test_checks.py | 2 -- tests/modeladmin/tests.py | 2 -- tests/multiple_database/routers.py | 2 -- tests/multiple_database/tests.py | 2 -- tests/nested_foreign_keys/tests.py | 2 -- tests/null_fk/tests.py | 2 -- tests/null_fk_ordering/models.py | 2 -- tests/null_fk_ordering/tests.py | 2 -- tests/null_queries/models.py | 2 -- tests/null_queries/tests.py | 2 -- tests/one_to_one/models.py | 2 -- tests/one_to_one/tests.py | 2 -- tests/or_lookups/tests.py | 3 --- tests/order_with_respect_to/base_tests.py | 2 -- tests/order_with_respect_to/tests.py | 2 -- tests/ordering/tests.py | 2 -- tests/pagination/tests.py | 2 -- .../array_default_migrations/0001_initial.py | 3 --- .../0002_integerarraymodel_field_2.py | 3 --- .../array_index_migrations/0001_initial.py | 3 --- .../migrations/0001_setup_extensions.py | 3 --- .../migrations/0002_create_test_models.py | 3 --- tests/postgres_tests/test_hstore.py | 3 --- tests/postgres_tests/test_json.py | 2 -- tests/postgres_tests/test_unaccent.py | 3 --- tests/prefetch_related/test_uuid.py | 2 -- tests/prefetch_related/tests.py | 2 -- tests/properties/tests.py | 2 -- tests/proxy_model_inheritance/tests.py | 2 -- tests/proxy_models/tests.py | 2 -- tests/queries/models.py | 2 -- tests/queries/test_qs_combinators.py | 2 -- tests/queries/tests.py | 2 -- tests/queryset_pickle/tests.py | 2 -- tests/raw_query/tests.py | 2 -- tests/requests/tests.py | 3 --- tests/reserved_names/tests.py | 2 -- tests/resolve_url/tests.py | 2 -- tests/responses/tests.py | 4 --- tests/reverse_lookup/tests.py | 2 -- tests/save_delete_hooks/models.py | 2 -- tests/save_delete_hooks/tests.py | 2 -- tests/select_for_update/tests.py | 2 -- tests/select_related/tests.py | 2 -- tests/select_related_onetoone/tests.py | 2 -- tests/select_related_regress/models.py | 2 -- tests/select_related_regress/tests.py | 2 -- tests/serializers/models/base.py | 2 -- tests/serializers/models/data.py | 2 -- tests/serializers/test_data.py | 2 -- tests/serializers/test_json.py | 3 --- tests/serializers/test_natural.py | 2 -- tests/serializers/test_xml.py | 3 --- tests/serializers/test_yaml.py | 3 --- tests/serializers/tests.py | 3 --- tests/servers/tests.py | 3 --- tests/signals/models.py | 2 -- tests/signals/tests.py | 2 -- tests/signed_cookies_tests/tests.py | 2 -- tests/signing/tests.py | 2 -- tests/sitemaps_tests/test_generic.py | 2 -- tests/sitemaps_tests/test_http.py | 2 -- tests/sitemaps_tests/test_https.py | 2 -- .../migrations/0001_initial.py | 3 --- tests/sites_tests/tests.py | 2 -- tests/staticfiles_tests/cases.py | 3 --- tests/staticfiles_tests/settings.py | 2 -- tests/staticfiles_tests/test_finders.py | 2 -- tests/staticfiles_tests/test_management.py | 2 -- tests/staticfiles_tests/test_storage.py | 2 -- tests/staticfiles_tests/test_templatetags.py | 2 -- tests/staticfiles_tests/test_views.py | 2 -- tests/str/models.py | 1 - tests/str/tests.py | 3 --- tests/string_lookup/models.py | 3 --- tests/string_lookup/tests.py | 3 --- tests/swappable_models/tests.py | 2 -- tests/syndication_tests/feeds.py | 2 -- tests/syndication_tests/tests.py | 2 -- tests/template_backends/test_dummy.py | 4 --- tests/template_backends/test_jinja2.py | 4 --- .../filter_tests/test_escapejs.py | 2 -- .../filter_tests/test_filesizeformat.py | 2 -- .../filter_tests/test_floatformat.py | 3 --- .../filter_tests/test_force_escape.py | 3 --- .../filter_tests/test_iriencode.py | 3 --- .../template_tests/filter_tests/test_lower.py | 3 --- .../filter_tests/test_slugify.py | 3 --- .../filter_tests/test_timesince.py | 2 -- .../filter_tests/test_timeuntil.py | 2 -- .../template_tests/filter_tests/test_title.py | 3 --- .../filter_tests/test_truncatechars_html.py | 3 --- .../filter_tests/test_truncatewords_html.py | 3 --- .../template_tests/filter_tests/test_upper.py | 3 --- .../filter_tests/test_urlencode.py | 3 --- .../filter_tests/test_urlize.py | 3 --- .../template_tests/syntax_tests/i18n/base.py | 2 -- .../syntax_tests/i18n/test_blocktrans.py | 3 --- .../syntax_tests/i18n/test_filters.py | 3 --- .../i18n/test_get_available_languages.py | 2 -- .../i18n/test_get_language_info.py | 3 --- .../i18n/test_get_language_info_list.py | 3 --- .../syntax_tests/i18n/test_trans.py | 2 -- .../i18n/test_underscore_syntax.py | 2 -- .../syntax_tests/test_filter_syntax.py | 3 --- tests/template_tests/syntax_tests/test_url.py | 1 - tests/template_tests/test_callables.py | 2 -- tests/template_tests/test_context.py | 1 - tests/template_tests/test_custom.py | 2 -- tests/template_tests/test_loaders.py | 3 --- tests/template_tests/test_logging.py | 2 -- tests/template_tests/test_parser.py | 2 -- tests/template_tests/test_response.py | 2 -- tests/template_tests/test_unicode.py | 3 --- tests/template_tests/tests.py | 3 --- tests/template_tests/urls.py | 3 --- tests/template_tests/utils.py | 4 --- .../test_conditional_content_removal.py | 2 -- tests/test_client/tests.py | 3 --- tests/test_client_regress/tests.py | 3 --- tests/test_runner/tests.py | 2 -- tests/test_utils/tests.py | 3 --- tests/timezones/tests.py | 2 -- tests/transactions/models.py | 2 -- tests/transactions/tests.py | 2 -- tests/unmanaged_models/tests.py | 2 -- tests/update/tests.py | 2 -- tests/update_only_fields/tests.py | 2 -- .../test_localeregexprovider.py | 2 -- tests/urlpatterns_reverse/tests.py | 3 --- tests/urlpatterns_reverse/utils.py | 2 -- tests/utils_tests/test_crypto.py | 2 -- tests/utils_tests/test_dateformat.py | 2 -- tests/utils_tests/test_dateparse.py | 2 -- tests/utils_tests/test_encoding.py | 3 --- tests/utils_tests/test_feedgenerator.py | 2 -- tests/utils_tests/test_functional.py | 3 --- tests/utils_tests/test_glob.py | 2 -- tests/utils_tests/test_html.py | 3 --- tests/utils_tests/test_http.py | 3 --- tests/utils_tests/test_ipv6.py | 2 -- tests/utils_tests/test_jslex.py | 2 -- tests/utils_tests/test_lazyobject.py | 2 -- tests/utils_tests/test_lorem_ipsum.py | 3 --- tests/utils_tests/test_numberformat.py | 3 --- tests/utils_tests/test_regex_helper.py | 2 -- tests/utils_tests/test_safestring.py | 2 -- tests/utils_tests/test_simplelazyobject.py | 2 -- tests/utils_tests/test_text.py | 3 --- tests/utils_tests/test_timesince.py | 2 -- tests/validation/models.py | 2 -- tests/validation/test_error_messages.py | 3 --- tests/validation/test_unique.py | 2 -- tests/validation/test_validators.py | 2 -- tests/validation/tests.py | 2 -- tests/validators/tests.py | 3 --- tests/view_tests/__init__.py | 4 --- tests/view_tests/generic_urls.py | 3 --- tests/view_tests/tests/test_debug.py | 5 ---- tests/view_tests/tests/test_defaults.py | 2 -- tests/view_tests/tests/test_i18n.py | 3 --- tests/view_tests/tests/test_json.py | 3 --- tests/view_tests/tests/test_specials.py | 3 --- tests/view_tests/tests/test_static.py | 2 -- tests/view_tests/urls.py | 1 - tests/view_tests/views.py | 2 -- tests/wsgi/tests.py | 2 -- 831 files changed, 6 insertions(+), 2066 deletions(-) diff --git a/django/__init__.py b/django/__init__.py index ab50cac6242e..4da99681eef8 100644 --- a/django/__init__.py +++ b/django/__init__.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.utils.version import get_version VERSION = (2, 0, 0, 'alpha', 0) diff --git a/django/conf/app_template/admin.py-tpl b/django/conf/app_template/admin.py-tpl index b2ff964e3ba1..8c38f3f3dad5 100644 --- a/django/conf/app_template/admin.py-tpl +++ b/django/conf/app_template/admin.py-tpl @@ -1,3 +1,3 @@ -{{ unicode_literals }}from django.contrib import admin +from django.contrib import admin # Register your models here. diff --git a/django/conf/app_template/apps.py-tpl b/django/conf/app_template/apps.py-tpl index 8d1a017751c8..9b2ce5289c52 100644 --- a/django/conf/app_template/apps.py-tpl +++ b/django/conf/app_template/apps.py-tpl @@ -1,4 +1,4 @@ -{{ unicode_literals }}from django.apps import AppConfig +from django.apps import AppConfig class {{ camel_case_app_name }}Config(AppConfig): diff --git a/django/conf/app_template/models.py-tpl b/django/conf/app_template/models.py-tpl index 7a54b3e371a6..71a836239075 100644 --- a/django/conf/app_template/models.py-tpl +++ b/django/conf/app_template/models.py-tpl @@ -1,3 +1,3 @@ -{{ unicode_literals }}from django.db import models +from django.db import models # Create your models here. diff --git a/django/conf/app_template/tests.py-tpl b/django/conf/app_template/tests.py-tpl index fa96c654d5df..7ce503c2dd97 100644 --- a/django/conf/app_template/tests.py-tpl +++ b/django/conf/app_template/tests.py-tpl @@ -1,3 +1,3 @@ -{{ unicode_literals }}from django.test import TestCase +from django.test import TestCase # Create your tests here. diff --git a/django/conf/app_template/views.py-tpl b/django/conf/app_template/views.py-tpl index 61821e705e82..91ea44a218fb 100644 --- a/django/conf/app_template/views.py-tpl +++ b/django/conf/app_template/views.py-tpl @@ -1,3 +1,3 @@ -{{ unicode_literals }}from django.shortcuts import render +from django.shortcuts import render # Create your views here. diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py index 9cf2732d30a9..754e6e5cdf7e 100644 --- a/django/conf/global_settings.py +++ b/django/conf/global_settings.py @@ -1,9 +1,7 @@ -# -*- coding: utf-8 -*- """ Default Django settings. Override these with settings in the module pointed to by the DJANGO_SETTINGS_MODULE environment variable. """ -from __future__ import unicode_literals # This is defined here as a do-nothing function because we can't import diff --git a/django/conf/locale/__init__.py b/django/conf/locale/__init__.py index 2cdda3cffd8f..89504ce1e535 100644 --- a/django/conf/locale/__init__.py +++ b/django/conf/locale/__init__.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - """ LANG_INFO is a dictionary structure to provide meta information about languages. diff --git a/django/conf/locale/ar/formats.py b/django/conf/locale/ar/formats.py index 1cdba2d98440..770b45344806 100644 --- a/django/conf/locale/ar/formats.py +++ b/django/conf/locale/ar/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F، Y' diff --git a/django/conf/locale/az/formats.py b/django/conf/locale/az/formats.py index ceb8165d651b..82470d1f161f 100644 --- a/django/conf/locale/az/formats.py +++ b/django/conf/locale/az/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j E Y' diff --git a/django/conf/locale/bg/formats.py b/django/conf/locale/bg/formats.py index 98820e703fef..4013dad1a8af 100644 --- a/django/conf/locale/bg/formats.py +++ b/django/conf/locale/bg/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'd F Y' diff --git a/django/conf/locale/bn/formats.py b/django/conf/locale/bn/formats.py index 2348c3afa356..ed03b21c6994 100644 --- a/django/conf/locale/bn/formats.py +++ b/django/conf/locale/bn/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F, Y' diff --git a/django/conf/locale/bs/formats.py b/django/conf/locale/bs/formats.py index cce3900f1e51..4018515dfbdf 100644 --- a/django/conf/locale/bs/formats.py +++ b/django/conf/locale/bs/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j. N Y.' diff --git a/django/conf/locale/ca/formats.py b/django/conf/locale/ca/formats.py index d42016b71651..baf47432bcf5 100644 --- a/django/conf/locale/ca/formats.py +++ b/django/conf/locale/ca/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = r'j \d\e F \d\e Y' diff --git a/django/conf/locale/cs/formats.py b/django/conf/locale/cs/formats.py index 3f2d3fa70ed9..ba4e3a1f8bb5 100644 --- a/django/conf/locale/cs/formats.py +++ b/django/conf/locale/cs/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j. E Y' diff --git a/django/conf/locale/cy/formats.py b/django/conf/locale/cy/formats.py index 4a69a88e6a04..031a40fff653 100644 --- a/django/conf/locale/cy/formats.py +++ b/django/conf/locale/cy/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F Y' # '25 Hydref 2006' diff --git a/django/conf/locale/da/formats.py b/django/conf/locale/da/formats.py index 90ba056f79bc..3af215895c74 100644 --- a/django/conf/locale/da/formats.py +++ b/django/conf/locale/da/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j. F Y' diff --git a/django/conf/locale/de/formats.py b/django/conf/locale/de/formats.py index cf1283b2a523..d47f57af3571 100644 --- a/django/conf/locale/de/formats.py +++ b/django/conf/locale/de/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j. F Y' diff --git a/django/conf/locale/de_CH/formats.py b/django/conf/locale/de_CH/formats.py index f8a9b90631e9..e09f9ffebda6 100644 --- a/django/conf/locale/de_CH/formats.py +++ b/django/conf/locale/de_CH/formats.py @@ -1,11 +1,7 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date -from __future__ import unicode_literals - DATE_FORMAT = 'j. F Y' TIME_FORMAT = 'H:i' DATETIME_FORMAT = 'j. F Y H:i' diff --git a/django/conf/locale/el/formats.py b/django/conf/locale/el/formats.py index bafa461094e6..3db1ad4829db 100644 --- a/django/conf/locale/el/formats.py +++ b/django/conf/locale/el/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'd/m/Y' diff --git a/django/conf/locale/en/formats.py b/django/conf/locale/en/formats.py index 63b23fa260d0..dd226fc129f0 100644 --- a/django/conf/locale/en/formats.py +++ b/django/conf/locale/en/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'N j, Y' diff --git a/django/conf/locale/en_AU/formats.py b/django/conf/locale/en_AU/formats.py index fe97ea98c195..378c18320750 100644 --- a/django/conf/locale/en_AU/formats.py +++ b/django/conf/locale/en_AU/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j M Y' # '25 Oct 2006' diff --git a/django/conf/locale/en_GB/formats.py b/django/conf/locale/en_GB/formats.py index 190ec7316d01..5f906881f724 100644 --- a/django/conf/locale/en_GB/formats.py +++ b/django/conf/locale/en_GB/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j M Y' # '25 Oct 2006' diff --git a/django/conf/locale/eo/formats.py b/django/conf/locale/eo/formats.py index 1e61912442a1..430fc8f24231 100644 --- a/django/conf/locale/eo/formats.py +++ b/django/conf/locale/eo/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = r'j\-\a \d\e F Y' # '26-a de julio 1887' diff --git a/django/conf/locale/es/formats.py b/django/conf/locale/es/formats.py index 701032aefda5..c89e66b30713 100644 --- a/django/conf/locale/es/formats.py +++ b/django/conf/locale/es/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = r'j \d\e F \d\e Y' diff --git a/django/conf/locale/es_AR/formats.py b/django/conf/locale/es_AR/formats.py index 9daf38d8eff1..30058a1398d3 100644 --- a/django/conf/locale/es_AR/formats.py +++ b/django/conf/locale/es_AR/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = r'j N Y' diff --git a/django/conf/locale/es_CO/formats.py b/django/conf/locale/es_CO/formats.py index 3671a0a25428..cefbe26dae5e 100644 --- a/django/conf/locale/es_CO/formats.py +++ b/django/conf/locale/es_CO/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - DATE_FORMAT = r'j \d\e F \d\e Y' TIME_FORMAT = 'H:i' DATETIME_FORMAT = r'j \d\e F \d\e Y \a \l\a\s H:i' diff --git a/django/conf/locale/es_MX/formats.py b/django/conf/locale/es_MX/formats.py index d15041660d79..228a821716d7 100644 --- a/django/conf/locale/es_MX/formats.py +++ b/django/conf/locale/es_MX/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - DATE_FORMAT = r'j \d\e F \d\e Y' TIME_FORMAT = 'H:i' DATETIME_FORMAT = r'j \d\e F \d\e Y \a \l\a\s H:i' diff --git a/django/conf/locale/es_NI/formats.py b/django/conf/locale/es_NI/formats.py index cc03b2cd2c2e..2eacf506ee51 100644 --- a/django/conf/locale/es_NI/formats.py +++ b/django/conf/locale/es_NI/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - DATE_FORMAT = r'j \d\e F \d\e Y' TIME_FORMAT = 'H:i' DATETIME_FORMAT = r'j \d\e F \d\e Y \a \l\a\s H:i' diff --git a/django/conf/locale/es_PR/formats.py b/django/conf/locale/es_PR/formats.py index c6680f7975b4..7f53ef9fe295 100644 --- a/django/conf/locale/es_PR/formats.py +++ b/django/conf/locale/es_PR/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - DATE_FORMAT = r'j \d\e F \d\e Y' TIME_FORMAT = 'H:i' DATETIME_FORMAT = r'j \d\e F \d\e Y \a \l\a\s H:i' diff --git a/django/conf/locale/et/formats.py b/django/conf/locale/et/formats.py index d43da89dd3e2..8c23b1053e93 100644 --- a/django/conf/locale/et/formats.py +++ b/django/conf/locale/et/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j. F Y' diff --git a/django/conf/locale/eu/formats.py b/django/conf/locale/eu/formats.py index 4ddf04ef5ab8..8d2785183f01 100644 --- a/django/conf/locale/eu/formats.py +++ b/django/conf/locale/eu/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = r'Yeko M\re\n d\a' diff --git a/django/conf/locale/fa/formats.py b/django/conf/locale/fa/formats.py index c1678b81cddf..419a9a24c193 100644 --- a/django/conf/locale/fa/formats.py +++ b/django/conf/locale/fa/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F Y' diff --git a/django/conf/locale/fi/formats.py b/django/conf/locale/fi/formats.py index b5c74211a3a8..2bdec1400e5d 100644 --- a/django/conf/locale/fi/formats.py +++ b/django/conf/locale/fi/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j. E Y' diff --git a/django/conf/locale/fr/formats.py b/django/conf/locale/fr/formats.py index ed6d8c7aaaa6..6db0b01dda89 100644 --- a/django/conf/locale/fr/formats.py +++ b/django/conf/locale/fr/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F Y' diff --git a/django/conf/locale/fy/formats.py b/django/conf/locale/fy/formats.py index 330c2f296e08..9dd995dde2d5 100644 --- a/django/conf/locale/fy/formats.py +++ b/django/conf/locale/fy/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date # DATE_FORMAT = diff --git a/django/conf/locale/ga/formats.py b/django/conf/locale/ga/formats.py index b3b19740767c..e47d873fa22c 100644 --- a/django/conf/locale/ga/formats.py +++ b/django/conf/locale/ga/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F Y' diff --git a/django/conf/locale/gd/formats.py b/django/conf/locale/gd/formats.py index 0eac9726690f..4a2db2313147 100644 --- a/django/conf/locale/gd/formats.py +++ b/django/conf/locale/gd/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F Y' diff --git a/django/conf/locale/gl/formats.py b/django/conf/locale/gl/formats.py index 996b8cd6b4f5..2dac9599d8f9 100644 --- a/django/conf/locale/gl/formats.py +++ b/django/conf/locale/gl/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = r'j \d\e F \d\e Y' diff --git a/django/conf/locale/he/formats.py b/django/conf/locale/he/formats.py index 274996f3a048..550d9bfefc7e 100644 --- a/django/conf/locale/he/formats.py +++ b/django/conf/locale/he/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j בF Y' diff --git a/django/conf/locale/hi/formats.py b/django/conf/locale/hi/formats.py index a2ea2e0bf6de..799168d83ab0 100644 --- a/django/conf/locale/hi/formats.py +++ b/django/conf/locale/hi/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F Y' diff --git a/django/conf/locale/hr/formats.py b/django/conf/locale/hr/formats.py index 59bcb8657d3f..921c709406e1 100644 --- a/django/conf/locale/hr/formats.py +++ b/django/conf/locale/hr/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j. E Y.' diff --git a/django/conf/locale/hu/formats.py b/django/conf/locale/hu/formats.py index e17e8c99adc4..33b9b6e22580 100644 --- a/django/conf/locale/hu/formats.py +++ b/django/conf/locale/hu/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'Y. F j.' diff --git a/django/conf/locale/id/formats.py b/django/conf/locale/id/formats.py index dc3dbf9dd805..065e0329d168 100644 --- a/django/conf/locale/id/formats.py +++ b/django/conf/locale/id/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j N Y' diff --git a/django/conf/locale/is/formats.py b/django/conf/locale/is/formats.py index 1b328eff1f25..6fbaa2a1c885 100644 --- a/django/conf/locale/is/formats.py +++ b/django/conf/locale/is/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j. F Y' diff --git a/django/conf/locale/it/formats.py b/django/conf/locale/it/formats.py index 054b973f0a13..b4819c02531d 100644 --- a/django/conf/locale/it/formats.py +++ b/django/conf/locale/it/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'd F Y' # 25 Ottobre 2006 diff --git a/django/conf/locale/ja/formats.py b/django/conf/locale/ja/formats.py index 63f043872a22..20194519b5ba 100644 --- a/django/conf/locale/ja/formats.py +++ b/django/conf/locale/ja/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'Y年n月j日' diff --git a/django/conf/locale/ka/formats.py b/django/conf/locale/ka/formats.py index 226f5f721ea2..e91c577c8dca 100644 --- a/django/conf/locale/ka/formats.py +++ b/django/conf/locale/ka/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'l, j F, Y' diff --git a/django/conf/locale/km/formats.py b/django/conf/locale/km/formats.py index 52ff4f95e844..b214a81c91d1 100644 --- a/django/conf/locale/km/formats.py +++ b/django/conf/locale/km/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j ខែ F ឆ្នាំ Y' diff --git a/django/conf/locale/kn/formats.py b/django/conf/locale/kn/formats.py index 4b8355165e0d..568c65dc65e3 100644 --- a/django/conf/locale/kn/formats.py +++ b/django/conf/locale/kn/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F Y' diff --git a/django/conf/locale/ko/formats.py b/django/conf/locale/ko/formats.py index 0344e9e16102..5183a78274c3 100644 --- a/django/conf/locale/ko/formats.py +++ b/django/conf/locale/ko/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'Y년 n월 j일' diff --git a/django/conf/locale/lt/formats.py b/django/conf/locale/lt/formats.py index d688669b7890..4fd47c0f77f6 100644 --- a/django/conf/locale/lt/formats.py +++ b/django/conf/locale/lt/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = r'Y \m. E j \d.' diff --git a/django/conf/locale/lv/formats.py b/django/conf/locale/lv/formats.py index e30a65388c62..8b6c730ee9ee 100644 --- a/django/conf/locale/lv/formats.py +++ b/django/conf/locale/lv/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = r'Y. \g\a\d\a j. F' diff --git a/django/conf/locale/mk/formats.py b/django/conf/locale/mk/formats.py index 2f01147a0a1a..ef168e5d2187 100644 --- a/django/conf/locale/mk/formats.py +++ b/django/conf/locale/mk/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'd F Y' diff --git a/django/conf/locale/ml/formats.py b/django/conf/locale/ml/formats.py index 63b23fa260d0..dd226fc129f0 100644 --- a/django/conf/locale/ml/formats.py +++ b/django/conf/locale/ml/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'N j, Y' diff --git a/django/conf/locale/mn/formats.py b/django/conf/locale/mn/formats.py index f41d532ba9ca..506e6143207e 100644 --- a/django/conf/locale/mn/formats.py +++ b/django/conf/locale/mn/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'd F Y' diff --git a/django/conf/locale/nb/formats.py b/django/conf/locale/nb/formats.py index 09fa857b4ce2..8cfb6f854cb1 100644 --- a/django/conf/locale/nb/formats.py +++ b/django/conf/locale/nb/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j. F Y' diff --git a/django/conf/locale/nl/formats.py b/django/conf/locale/nl/formats.py index 581848f6e4a8..69e8e8061559 100644 --- a/django/conf/locale/nl/formats.py +++ b/django/conf/locale/nl/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F Y' # '20 januari 2009' diff --git a/django/conf/locale/nn/formats.py b/django/conf/locale/nn/formats.py index b2e654c1e148..24289035fc51 100644 --- a/django/conf/locale/nn/formats.py +++ b/django/conf/locale/nn/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j. F Y' diff --git a/django/conf/locale/pl/formats.py b/django/conf/locale/pl/formats.py index 9cc17764947f..ddd82742cd7b 100644 --- a/django/conf/locale/pl/formats.py +++ b/django/conf/locale/pl/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j E Y' diff --git a/django/conf/locale/pt/formats.py b/django/conf/locale/pt/formats.py index 143351c0cde3..60f9b1b5fdfd 100644 --- a/django/conf/locale/pt/formats.py +++ b/django/conf/locale/pt/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = r'j \d\e F \d\e Y' diff --git a/django/conf/locale/pt_BR/formats.py b/django/conf/locale/pt_BR/formats.py index 9f728783c58a..0c0646c946d3 100644 --- a/django/conf/locale/pt_BR/formats.py +++ b/django/conf/locale/pt_BR/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = r'j \d\e F \d\e Y' diff --git a/django/conf/locale/ro/formats.py b/django/conf/locale/ro/formats.py index 4ed143b74542..ba3fd73b4a4c 100644 --- a/django/conf/locale/ro/formats.py +++ b/django/conf/locale/ro/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F Y' diff --git a/django/conf/locale/ru/formats.py b/django/conf/locale/ru/formats.py index 07b11812851f..c443ae1bd05a 100644 --- a/django/conf/locale/ru/formats.py +++ b/django/conf/locale/ru/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j E Y г.' diff --git a/django/conf/locale/sk/formats.py b/django/conf/locale/sk/formats.py index 04bdceb00039..c6a40bbc49e0 100644 --- a/django/conf/locale/sk/formats.py +++ b/django/conf/locale/sk/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j. F Y' diff --git a/django/conf/locale/sl/formats.py b/django/conf/locale/sl/formats.py index a4e9973a5522..65ad2592e127 100644 --- a/django/conf/locale/sl/formats.py +++ b/django/conf/locale/sl/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'd. F Y' diff --git a/django/conf/locale/sq/formats.py b/django/conf/locale/sq/formats.py index 0fb21a6583aa..ef9cb6a755d3 100644 --- a/django/conf/locale/sq/formats.py +++ b/django/conf/locale/sq/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'd F Y' diff --git a/django/conf/locale/sr/formats.py b/django/conf/locale/sr/formats.py index 5c5e48e20e41..06089d6a9169 100644 --- a/django/conf/locale/sr/formats.py +++ b/django/conf/locale/sr/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j. F Y.' diff --git a/django/conf/locale/sr_Latn/formats.py b/django/conf/locale/sr_Latn/formats.py index 5c5e48e20e41..06089d6a9169 100644 --- a/django/conf/locale/sr_Latn/formats.py +++ b/django/conf/locale/sr_Latn/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j. F Y.' diff --git a/django/conf/locale/sv/formats.py b/django/conf/locale/sv/formats.py index f2de0bc16bc4..3ab4b0b86dcc 100644 --- a/django/conf/locale/sv/formats.py +++ b/django/conf/locale/sv/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F Y' diff --git a/django/conf/locale/ta/formats.py b/django/conf/locale/ta/formats.py index 89282447096d..c1a1be6aee78 100644 --- a/django/conf/locale/ta/formats.py +++ b/django/conf/locale/ta/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F, Y' diff --git a/django/conf/locale/te/formats.py b/django/conf/locale/te/formats.py index 74420d0ea175..59693985e3ee 100644 --- a/django/conf/locale/te/formats.py +++ b/django/conf/locale/te/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F Y' diff --git a/django/conf/locale/th/formats.py b/django/conf/locale/th/formats.py index 1b0e2d4f917b..04ceda1c926f 100644 --- a/django/conf/locale/th/formats.py +++ b/django/conf/locale/th/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'j F Y' diff --git a/django/conf/locale/tr/formats.py b/django/conf/locale/tr/formats.py index c765f77489a7..6bb62fc1c49d 100644 --- a/django/conf/locale/tr/formats.py +++ b/django/conf/locale/tr/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'd F Y' diff --git a/django/conf/locale/uk/formats.py b/django/conf/locale/uk/formats.py index 938a97d42a97..515d48d8351a 100644 --- a/django/conf/locale/uk/formats.py +++ b/django/conf/locale/uk/formats.py @@ -1,9 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # - -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'd E Y р.' diff --git a/django/conf/locale/vi/formats.py b/django/conf/locale/vi/formats.py index ee87e2f3261a..78ec196d3860 100644 --- a/django/conf/locale/vi/formats.py +++ b/django/conf/locale/vi/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = r'\N\gà\y d \t\há\n\g n \nă\m Y' diff --git a/django/conf/locale/zh_Hans/formats.py b/django/conf/locale/zh_Hans/formats.py index b6bac2f90e29..863b8980dd4e 100644 --- a/django/conf/locale/zh_Hans/formats.py +++ b/django/conf/locale/zh_Hans/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'Y年n月j日' # 2016年9月5日 diff --git a/django/conf/locale/zh_Hant/formats.py b/django/conf/locale/zh_Hant/formats.py index b6bac2f90e29..863b8980dd4e 100644 --- a/django/conf/locale/zh_Hant/formats.py +++ b/django/conf/locale/zh_Hant/formats.py @@ -1,8 +1,5 @@ -# -*- encoding: utf-8 -*- # This file is distributed under the same license as the Django package. # -from __future__ import unicode_literals - # The *_FORMAT strings use the Django date format syntax, # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date DATE_FORMAT = 'Y年n月j日' # 2016年9月5日 diff --git a/django/contrib/admin/checks.py b/django/contrib/admin/checks.py index 286c1169a489..33c60a3ab872 100644 --- a/django/contrib/admin/checks.py +++ b/django/contrib/admin/checks.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from itertools import chain from django.apps import apps diff --git a/django/contrib/admin/forms.py b/django/contrib/admin/forms.py index ed71d63e4c18..7c3d196012d1 100644 --- a/django/contrib/admin/forms.py +++ b/django/contrib/admin/forms.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django import forms from django.contrib.auth.forms import AuthenticationForm, PasswordChangeForm from django.utils.translation import ugettext_lazy as _ diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py index 604fcd5b260f..ea56840445ea 100644 --- a/django/contrib/admin/helpers.py +++ b/django/contrib/admin/helpers.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import json from django import forms diff --git a/django/contrib/admin/migrations/0001_initial.py b/django/contrib/admin/migrations/0001_initial.py index c615bd79c3c7..f1e2804ce4c9 100644 --- a/django/contrib/admin/migrations/0001_initial.py +++ b/django/contrib/admin/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import django.contrib.admin.models from django.conf import settings from django.db import migrations, models diff --git a/django/contrib/admin/migrations/0002_logentry_remove_auto_add.py b/django/contrib/admin/migrations/0002_logentry_remove_auto_add.py index fb66c31bd3e3..a2b19162f28c 100644 --- a/django/contrib/admin/migrations/0002_logentry_remove_auto_add.py +++ b/django/contrib/admin/migrations/0002_logentry_remove_auto_add.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models from django.utils import timezone diff --git a/django/contrib/admin/models.py b/django/contrib/admin/models.py index a8245a20e4bb..724209dd0d30 100644 --- a/django/contrib/admin/models.py +++ b/django/contrib/admin/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import json from django.conf import settings diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index aef1e2c24e8a..edde9077ac92 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import copy import json import operator diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index ad6c03ea89ba..ec4356f5467f 100644 --- a/django/contrib/admin/templatetags/admin_list.py +++ b/django/contrib/admin/templatetags/admin_list.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from django.contrib.admin.templatetags.admin_urls import add_preserved_filters diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py index 1e13d13d31b0..cf1738154816 100644 --- a/django/contrib/admin/utils.py +++ b/django/contrib/admin/utils.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import decimal from collections import defaultdict diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index 5960f82d9114..9f93ae3a42fc 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -1,8 +1,6 @@ """ Form Widget classes specific to the Django admin site. """ -from __future__ import unicode_literals - import copy from django import forms diff --git a/django/contrib/auth/backends.py b/django/contrib/auth/backends.py index 8df95db5eeac..08a20c61ffc7 100644 --- a/django/contrib/auth/backends.py +++ b/django/contrib/auth/backends.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.auth import get_user_model from django.contrib.auth.models import Permission diff --git a/django/contrib/auth/base_user.py b/django/contrib/auth/base_user.py index 104748ff69b5..c6f4c9665cd7 100644 --- a/django/contrib/auth/base_user.py +++ b/django/contrib/auth/base_user.py @@ -2,8 +2,6 @@ This module allows importing AbstractBaseUser even when django.contrib.auth is not in INSTALLED_APPS. """ -from __future__ import unicode_literals - import unicodedata from django.contrib.auth import password_validation diff --git a/django/contrib/auth/checks.py b/django/contrib/auth/checks.py index 05487fe53641..ec133e80ee50 100644 --- a/django/contrib/auth/checks.py +++ b/django/contrib/auth/checks.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from itertools import chain from types import MethodType diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py index 02250d83da6f..51c513cb671d 100644 --- a/django/contrib/auth/forms.py +++ b/django/contrib/auth/forms.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import unicodedata from django import forms diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py index c29b27d64b81..4b8b12782e8b 100644 --- a/django/contrib/auth/hashers.py +++ b/django/contrib/auth/hashers.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import base64 import binascii import hashlib diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py index 659fe63282fb..17fd8dd11aac 100644 --- a/django/contrib/auth/management/__init__.py +++ b/django/contrib/auth/management/__init__.py @@ -1,8 +1,6 @@ """ Creates permissions for all installed apps that need permissions. """ -from __future__ import unicode_literals - import getpass import unicodedata diff --git a/django/contrib/auth/management/commands/changepassword.py b/django/contrib/auth/management/commands/changepassword.py index 1c4eee3b917d..c0c4ce3c6112 100644 --- a/django/contrib/auth/management/commands/changepassword.py +++ b/django/contrib/auth/management/commands/changepassword.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import getpass from django.contrib.auth import get_user_model diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py index 76971b7b7235..b9f13b7b0581 100644 --- a/django/contrib/auth/management/commands/createsuperuser.py +++ b/django/contrib/auth/management/commands/createsuperuser.py @@ -1,8 +1,6 @@ """ Management utility to create superusers. """ -from __future__ import unicode_literals - import getpass import sys diff --git a/django/contrib/auth/migrations/0001_initial.py b/django/contrib/auth/migrations/0001_initial.py index 65db802ed8ca..f97caae1e464 100644 --- a/django/contrib/auth/migrations/0001_initial.py +++ b/django/contrib/auth/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import django.contrib.auth.models from django.contrib.auth import validators from django.db import migrations, models diff --git a/django/contrib/auth/migrations/0002_alter_permission_name_max_length.py b/django/contrib/auth/migrations/0002_alter_permission_name_max_length.py index 8b58e7814b1a..556c320409c3 100644 --- a/django/contrib/auth/migrations/0002_alter_permission_name_max_length.py +++ b/django/contrib/auth/migrations/0002_alter_permission_name_max_length.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/django/contrib/auth/migrations/0003_alter_user_email_max_length.py b/django/contrib/auth/migrations/0003_alter_user_email_max_length.py index 0a082f2656a6..ee8a9bd607d8 100644 --- a/django/contrib/auth/migrations/0003_alter_user_email_max_length.py +++ b/django/contrib/auth/migrations/0003_alter_user_email_max_length.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/django/contrib/auth/migrations/0004_alter_user_username_opts.py b/django/contrib/auth/migrations/0004_alter_user_username_opts.py index e7a521fd6d70..f4afcf7bd87c 100644 --- a/django/contrib/auth/migrations/0004_alter_user_username_opts.py +++ b/django/contrib/auth/migrations/0004_alter_user_username_opts.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.contrib.auth import validators from django.db import migrations, models from django.utils import six diff --git a/django/contrib/auth/migrations/0005_alter_user_last_login_null.py b/django/contrib/auth/migrations/0005_alter_user_last_login_null.py index b8b9289787a9..97cd105a0f2f 100644 --- a/django/contrib/auth/migrations/0005_alter_user_last_login_null.py +++ b/django/contrib/auth/migrations/0005_alter_user_last_login_null.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/django/contrib/auth/migrations/0006_require_contenttypes_0002.py b/django/contrib/auth/migrations/0006_require_contenttypes_0002.py index 77c45e70b139..48c26be0117e 100644 --- a/django/contrib/auth/migrations/0006_require_contenttypes_0002.py +++ b/django/contrib/auth/migrations/0006_require_contenttypes_0002.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/django/contrib/auth/migrations/0007_alter_validators_add_error_messages.py b/django/contrib/auth/migrations/0007_alter_validators_add_error_messages.py index 8e5b14150391..6d44280856fc 100644 --- a/django/contrib/auth/migrations/0007_alter_validators_add_error_messages.py +++ b/django/contrib/auth/migrations/0007_alter_validators_add_error_messages.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.contrib.auth import validators from django.db import migrations, models from django.utils import six diff --git a/django/contrib/auth/migrations/0008_alter_user_username_max_length.py b/django/contrib/auth/migrations/0008_alter_user_username_max_length.py index 6349ad10c4dc..15b9cf8c9476 100644 --- a/django/contrib/auth/migrations/0008_alter_user_username_max_length.py +++ b/django/contrib/auth/migrations/0008_alter_user_username_max_length.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.contrib.auth import validators from django.db import migrations, models from django.utils import six diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index d91412eb5c11..2e9f3682d7b8 100644 --- a/django/contrib/auth/models.py +++ b/django/contrib/auth/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib import auth from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager from django.contrib.auth.signals import user_logged_in diff --git a/django/contrib/auth/password_validation.py b/django/contrib/auth/password_validation.py index 4ff2c409ec24..d802a5f5fde3 100644 --- a/django/contrib/auth/password_validation.py +++ b/django/contrib/auth/password_validation.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import gzip import os import re diff --git a/django/contrib/contenttypes/admin.py b/django/contrib/contenttypes/admin.py index f15f66b2e1e8..063c37698a3f 100644 --- a/django/contrib/contenttypes/admin.py +++ b/django/contrib/contenttypes/admin.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from functools import partial from django.contrib.admin.checks import InlineModelAdminChecks diff --git a/django/contrib/contenttypes/checks.py b/django/contrib/contenttypes/checks.py index 43a2fb7a7aee..2355a5e943df 100644 --- a/django/contrib/contenttypes/checks.py +++ b/django/contrib/contenttypes/checks.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from itertools import chain from django.apps import apps diff --git a/django/contrib/contenttypes/fields.py b/django/contrib/contenttypes/fields.py index a273cf034798..83e38af4415e 100644 --- a/django/contrib/contenttypes/fields.py +++ b/django/contrib/contenttypes/fields.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from collections import defaultdict from django.contrib.contenttypes.models import ContentType diff --git a/django/contrib/contenttypes/forms.py b/django/contrib/contenttypes/forms.py index ff8a60114cca..8e88c9a1cd72 100644 --- a/django/contrib/contenttypes/forms.py +++ b/django/contrib/contenttypes/forms.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.contenttypes.models import ContentType from django.db import models from django.forms import ModelForm, modelformset_factory diff --git a/django/contrib/contenttypes/migrations/0001_initial.py b/django/contrib/contenttypes/migrations/0001_initial.py index 68190b2a2b37..9bafd098e94e 100644 --- a/django/contrib/contenttypes/migrations/0001_initial.py +++ b/django/contrib/contenttypes/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import django.contrib.contenttypes.models from django.db import migrations, models diff --git a/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py b/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py index 8bd8032b41ec..c88e603147fd 100644 --- a/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py +++ b/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/django/contrib/contenttypes/models.py b/django/contrib/contenttypes/models.py index 26a3db17c902..6db6831fbc67 100644 --- a/django/contrib/contenttypes/models.py +++ b/django/contrib/contenttypes/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from collections import defaultdict from django.apps import apps diff --git a/django/contrib/contenttypes/views.py b/django/contrib/contenttypes/views.py index 3957788d0e6e..50c07d110926 100644 --- a/django/contrib/contenttypes/views.py +++ b/django/contrib/contenttypes/views.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django import http from django.apps import apps from django.contrib.contenttypes.models import ContentType diff --git a/django/contrib/flatpages/migrations/0001_initial.py b/django/contrib/flatpages/migrations/0001_initial.py index 13e417b41b55..b385ca5fd44b 100644 --- a/django/contrib/flatpages/migrations/0001_initial.py +++ b/django/contrib/flatpages/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/django/contrib/flatpages/models.py b/django/contrib/flatpages/models.py index add1fdd879ae..02c93d657d76 100644 --- a/django/contrib/flatpages/models.py +++ b/django/contrib/flatpages/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.sites.models import Site from django.db import models from django.urls import get_script_prefix diff --git a/django/contrib/gis/db/backends/postgis/adapter.py b/django/contrib/gis/db/backends/postgis/adapter.py index 9e107db6d6bd..c94268811b5a 100644 --- a/django/contrib/gis/db/backends/postgis/adapter.py +++ b/django/contrib/gis/db/backends/postgis/adapter.py @@ -1,8 +1,6 @@ """ This object provides quoting for GEOS geometries into PostgreSQL/PostGIS. """ -from __future__ import unicode_literals - from psycopg2 import Binary from psycopg2.extensions import ISQLQuote diff --git a/django/contrib/gis/db/models/lookups.py b/django/contrib/gis/db/models/lookups.py index 8d4e8229e763..b707a9cbff7d 100644 --- a/django/contrib/gis/db/models/lookups.py +++ b/django/contrib/gis/db/models/lookups.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import re from django.core.exceptions import FieldDoesNotExist diff --git a/django/contrib/gis/db/models/sql/conversion.py b/django/contrib/gis/db/models/sql/conversion.py index acc277ed6247..054628d481c8 100644 --- a/django/contrib/gis/db/models/sql/conversion.py +++ b/django/contrib/gis/db/models/sql/conversion.py @@ -2,8 +2,6 @@ This module holds simple classes to convert geospatial values from the database. """ -from __future__ import unicode_literals - from decimal import Decimal from django.contrib.gis.db.models.fields import GeoSelectFormatMixin diff --git a/django/contrib/gis/feeds.py b/django/contrib/gis/feeds.py index 1e12b4d64cc2..4240968f19b3 100644 --- a/django/contrib/gis/feeds.py +++ b/django/contrib/gis/feeds.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.syndication.views import Feed as BaseFeed from django.utils.feedgenerator import Atom1Feed, Rss201rev2Feed diff --git a/django/contrib/gis/forms/fields.py b/django/contrib/gis/forms/fields.py index 4ae56de88bff..ef0f4a9bee41 100644 --- a/django/contrib/gis/forms/fields.py +++ b/django/contrib/gis/forms/fields.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django import forms from django.contrib.gis.geos import GEOSException, GEOSGeometry from django.utils.translation import ugettext_lazy as _ diff --git a/django/contrib/gis/forms/widgets.py b/django/contrib/gis/forms/widgets.py index e331e1844db3..2e7e530cc2ee 100644 --- a/django/contrib/gis/forms/widgets.py +++ b/django/contrib/gis/forms/widgets.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import logging from django.conf import settings diff --git a/django/contrib/gis/gdal/libgdal.py b/django/contrib/gis/gdal/libgdal.py index 7d7292b7b8b3..79a73b5d885b 100644 --- a/django/contrib/gis/gdal/libgdal.py +++ b/django/contrib/gis/gdal/libgdal.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import logging import os import re diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py index cf5886dc07e0..deadbfaaf279 100644 --- a/django/contrib/gis/geos/geometry.py +++ b/django/contrib/gis/geos/geometry.py @@ -2,8 +2,6 @@ This module contains the 'base' GEOSGeometry object -- all GEOS Geometries inherit from this object. """ -from __future__ import unicode_literals - import json from ctypes import addressof, byref, c_double diff --git a/django/contrib/gis/serializers/geojson.py b/django/contrib/gis/serializers/geojson.py index dcdf153c3623..1b50ee30d83a 100644 --- a/django/contrib/gis/serializers/geojson.py +++ b/django/contrib/gis/serializers/geojson.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.gis.gdal import HAS_GDAL from django.core.serializers.base import SerializerDoesNotExist from django.core.serializers.json import Serializer as JSONSerializer diff --git a/django/contrib/gis/sitemaps/views.py b/django/contrib/gis/sitemaps/views.py index 948c3ec36c17..add465237375 100644 --- a/django/contrib/gis/sitemaps/views.py +++ b/django/contrib/gis/sitemaps/views.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.apps import apps from django.contrib.gis.db.models.fields import GeometryField from django.contrib.gis.db.models.functions import AsKML, Transform diff --git a/django/contrib/gis/views.py b/django/contrib/gis/views.py index 5d05d3a057f8..db0fa3d53d4a 100644 --- a/django/contrib/gis/views.py +++ b/django/contrib/gis/views.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.http import Http404 from django.utils.translation import ugettext as _ diff --git a/django/contrib/humanize/templatetags/humanize.py b/django/contrib/humanize/templatetags/humanize.py index d7d8f2f89731..5ba9897018e3 100644 --- a/django/contrib/humanize/templatetags/humanize.py +++ b/django/contrib/humanize/templatetags/humanize.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - import re from datetime import date, datetime from decimal import Decimal diff --git a/django/contrib/messages/storage/base.py b/django/contrib/messages/storage/base.py index a2e54486c736..2273e9720787 100644 --- a/django/contrib/messages/storage/base.py +++ b/django/contrib/messages/storage/base.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.conf import settings from django.contrib.messages import constants, utils from django.utils.encoding import force_text, python_2_unicode_compatible diff --git a/django/contrib/postgres/indexes.py b/django/contrib/postgres/indexes.py index 185ea7435c47..2edec371f4fd 100644 --- a/django/contrib/postgres/indexes.py +++ b/django/contrib/postgres/indexes.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db.models import Index __all__ = ['BrinIndex', 'GinIndex'] diff --git a/django/contrib/postgres/utils.py b/django/contrib/postgres/utils.py index a2bbb72f369d..a87d519477b0 100644 --- a/django/contrib/postgres/utils.py +++ b/django/contrib/postgres/utils.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.exceptions import ValidationError from django.utils.functional import SimpleLazyObject from django.utils.text import format_lazy diff --git a/django/contrib/redirects/middleware.py b/django/contrib/redirects/middleware.py index f5c9f8558841..317dca3fd25f 100644 --- a/django/contrib/redirects/middleware.py +++ b/django/contrib/redirects/middleware.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django import http from django.apps import apps from django.conf import settings diff --git a/django/contrib/redirects/migrations/0001_initial.py b/django/contrib/redirects/migrations/0001_initial.py index 905ec266aa56..fb0462f52cf1 100644 --- a/django/contrib/redirects/migrations/0001_initial.py +++ b/django/contrib/redirects/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/django/contrib/sessions/backends/base.py b/django/contrib/sessions/backends/base.py index 40c557ba0b7c..615eea45d2a9 100644 --- a/django/contrib/sessions/backends/base.py +++ b/django/contrib/sessions/backends/base.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import base64 import logging import string diff --git a/django/contrib/sessions/base_session.py b/django/contrib/sessions/base_session.py index 5fed0cd2d104..bd8e957aea15 100644 --- a/django/contrib/sessions/base_session.py +++ b/django/contrib/sessions/base_session.py @@ -2,8 +2,6 @@ This module allows importing AbstractBaseSession even when django.contrib.sessions is not in INSTALLED_APPS. """ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ diff --git a/django/contrib/sessions/migrations/0001_initial.py b/django/contrib/sessions/migrations/0001_initial.py index e9fd627b7989..39eaa6db4118 100644 --- a/django/contrib/sessions/migrations/0001_initial.py +++ b/django/contrib/sessions/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import django.contrib.sessions.models from django.db import migrations, models diff --git a/django/contrib/sessions/models.py b/django/contrib/sessions/models.py index 3ee3ce73d36c..a744267927cc 100644 --- a/django/contrib/sessions/models.py +++ b/django/contrib/sessions/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.sessions.base_session import ( AbstractBaseSession, BaseSessionManager, ) diff --git a/django/contrib/sites/managers.py b/django/contrib/sites/managers.py index a3a0f07fc353..52f91a51ea39 100644 --- a/django/contrib/sites/managers.py +++ b/django/contrib/sites/managers.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.conf import settings from django.core import checks from django.core.exceptions import FieldDoesNotExist diff --git a/django/contrib/sites/migrations/0001_initial.py b/django/contrib/sites/migrations/0001_initial.py index b1803682ae5c..a7639869fc98 100644 --- a/django/contrib/sites/migrations/0001_initial.py +++ b/django/contrib/sites/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import django.contrib.sites.models from django.contrib.sites.models import _simple_domain_name_validator from django.db import migrations, models diff --git a/django/contrib/sites/migrations/0002_alter_domain_unique.py b/django/contrib/sites/migrations/0002_alter_domain_unique.py index 468718cde3ce..6a26ebcde655 100644 --- a/django/contrib/sites/migrations/0002_alter_domain_unique.py +++ b/django/contrib/sites/migrations/0002_alter_domain_unique.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import django.contrib.sites.models from django.db import migrations, models diff --git a/django/contrib/sites/models.py b/django/contrib/sites/models.py index 7b237b087387..9f849fa5591f 100644 --- a/django/contrib/sites/models.py +++ b/django/contrib/sites/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import string from django.core.exceptions import ImproperlyConfigured, ValidationError diff --git a/django/contrib/sites/requests.py b/django/contrib/sites/requests.py index 233d8409457a..81f2ba42d6f3 100644 --- a/django/contrib/sites/requests.py +++ b/django/contrib/sites/requests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.utils.encoding import python_2_unicode_compatible diff --git a/django/contrib/sites/shortcuts.py b/django/contrib/sites/shortcuts.py index 12471dc9a596..7991c618284d 100644 --- a/django/contrib/sites/shortcuts.py +++ b/django/contrib/sites/shortcuts.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.apps import apps diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py index 801113e3c4d1..fac96e5bf471 100644 --- a/django/contrib/staticfiles/management/commands/collectstatic.py +++ b/django/contrib/staticfiles/management/commands/collectstatic.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os from collections import OrderedDict diff --git a/django/contrib/staticfiles/management/commands/findstatic.py b/django/contrib/staticfiles/management/commands/findstatic.py index b594ebcab209..992dae17697a 100644 --- a/django/contrib/staticfiles/management/commands/findstatic.py +++ b/django/contrib/staticfiles/management/commands/findstatic.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os from django.contrib.staticfiles import finders diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py index da0d2004e6be..b033243eccff 100644 --- a/django/contrib/staticfiles/storage.py +++ b/django/contrib/staticfiles/storage.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import hashlib import json import os diff --git a/django/contrib/syndication/views.py b/django/contrib/syndication/views.py index 1e3c08d313eb..fa9c5e7753fe 100644 --- a/django/contrib/syndication/views.py +++ b/django/contrib/syndication/views.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from calendar import timegm from django.conf import settings diff --git a/django/core/cache/backends/base.py b/django/core/cache/backends/base.py index 9cbfe0be1d07..856316b4004d 100644 --- a/django/core/cache/backends/base.py +++ b/django/core/cache/backends/base.py @@ -1,6 +1,4 @@ "Base Cache class." -from __future__ import unicode_literals - import time import warnings diff --git a/django/core/cache/utils.py b/django/core/cache/utils.py index c40e4eba0cdd..84676b9237bd 100644 --- a/django/core/cache/utils.py +++ b/django/core/cache/utils.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import hashlib from django.utils.encoding import force_bytes diff --git a/django/core/checks/__init__.py b/django/core/checks/__init__.py index f2194a3fc9fb..8ef3f5db90e4 100644 --- a/django/core/checks/__init__.py +++ b/django/core/checks/__init__.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from .messages import ( CRITICAL, DEBUG, ERROR, INFO, WARNING, CheckMessage, Critical, Debug, Error, Info, Warning, diff --git a/django/core/checks/caches.py b/django/core/checks/caches.py index 4a4141777d2f..0994a5b0e8a0 100644 --- a/django/core/checks/caches.py +++ b/django/core/checks/caches.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.conf import settings from django.core.cache import DEFAULT_CACHE_ALIAS diff --git a/django/core/checks/messages.py b/django/core/checks/messages.py index 345ebec1e12a..f1de41a63c87 100644 --- a/django/core/checks/messages.py +++ b/django/core/checks/messages.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.utils.encoding import force_str, python_2_unicode_compatible # Levels diff --git a/django/core/checks/model_checks.py b/django/core/checks/model_checks.py index 0c12f9b96a63..a8b565266247 100644 --- a/django/core/checks/model_checks.py +++ b/django/core/checks/model_checks.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import inspect import types from itertools import chain diff --git a/django/core/checks/registry.py b/django/core/checks/registry.py index 292e0cb73b24..4a2b358dc89b 100644 --- a/django/core/checks/registry.py +++ b/django/core/checks/registry.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from itertools import chain from django.utils.itercompat import is_iterable diff --git a/django/core/checks/templates.py b/django/core/checks/templates.py index 098371740e1d..bf526c871ebc 100644 --- a/django/core/checks/templates.py +++ b/django/core/checks/templates.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import copy from django.conf import settings diff --git a/django/core/checks/urls.py b/django/core/checks/urls.py index e950cb563755..d721bc901f53 100644 --- a/django/core/checks/urls.py +++ b/django/core/checks/urls.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from collections import Counter from django.conf import settings diff --git a/django/core/files/base.py b/django/core/files/base.py index be889c9bc41a..7499629459ba 100644 --- a/django/core/files/base.py +++ b/django/core/files/base.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os from io import BytesIO, StringIO, UnsupportedOperation diff --git a/django/core/files/uploadhandler.py b/django/core/files/uploadhandler.py index 05b431d05a76..748477c0fc3f 100644 --- a/django/core/files/uploadhandler.py +++ b/django/core/files/uploadhandler.py @@ -2,8 +2,6 @@ Base file upload handler classes, and the built-in concrete subclasses """ -from __future__ import unicode_literals - from io import BytesIO from django.conf import settings diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py index 1d53fa9d94f7..b37716b62c74 100644 --- a/django/core/handlers/base.py +++ b/django/core/handlers/base.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import logging import types diff --git a/django/core/handlers/exception.py b/django/core/handlers/exception.py index ab859405f389..5e489f64d32c 100644 --- a/django/core/handlers/exception.py +++ b/django/core/handlers/exception.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import logging import sys from functools import wraps diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index 4486754d4186..538373cd8d30 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import cgi import codecs import re diff --git a/django/core/mail/__init__.py b/django/core/mail/__init__.py index 5741f8a82984..23beae0cce55 100644 --- a/django/core/mail/__init__.py +++ b/django/core/mail/__init__.py @@ -1,8 +1,6 @@ """ Tools for sending email. """ -from __future__ import unicode_literals - from django.conf import settings # Imported for backwards compatibility and for the sake # of a cleaner namespace. These symbols used to be in diff --git a/django/core/mail/message.py b/django/core/mail/message.py index 3cebbaf9d245..2c68e8280918 100644 --- a/django/core/mail/message.py +++ b/django/core/mail/message.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import mimetypes import os import random diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py index fdc1af2aa2cf..6b89fff3518f 100644 --- a/django/core/management/__init__.py +++ b/django/core/management/__init__.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os import pkgutil import sys diff --git a/django/core/management/base.py b/django/core/management/base.py index cdc673a479af..192d529ef04b 100644 --- a/django/core/management/base.py +++ b/django/core/management/base.py @@ -1,10 +1,7 @@ -# -*- coding: utf-8 -*- """ Base classes for writing management commands (named commands which can be executed through ``django-admin`` or ``manage.py``). """ -from __future__ import unicode_literals - import os import sys from argparse import ArgumentParser diff --git a/django/core/management/commands/check.py b/django/core/management/commands/check.py index aa9685caa9a3..e119960f441c 100644 --- a/django/core/management/commands/check.py +++ b/django/core/management/commands/check.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.apps import apps from django.core import checks from django.core.checks.registry import registry diff --git a/django/core/management/commands/compilemessages.py b/django/core/management/commands/compilemessages.py index 874fea4b5a91..05fb9e5cfc60 100644 --- a/django/core/management/commands/compilemessages.py +++ b/django/core/management/commands/compilemessages.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import codecs import glob import os diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py index 68226355b87f..dbe870f322be 100644 --- a/django/core/management/commands/flush.py +++ b/django/core/management/commands/flush.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import sys from importlib import import_module diff --git a/django/core/management/commands/inspectdb.py b/django/core/management/commands/inspectdb.py index 69721b1283a2..09939f28dabe 100644 --- a/django/core/management/commands/inspectdb.py +++ b/django/core/management/commands/inspectdb.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import keyword import re from collections import OrderedDict @@ -56,8 +54,6 @@ def strip_prefix(s): "Django to create, modify, and delete the table" ) yield "# Feel free to rename the models, but don't rename db_table values or field names." - yield "from __future__ import unicode_literals" - yield '' yield 'from %s import models' % self.db_module known_models = [] tables_to_introspect = options['table'] or connection.introspection.table_names(cursor) diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index d824011a03bf..4b621205e65c 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import glob import gzip import os diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py index 527472e1c97b..1597f9347e79 100644 --- a/django/core/management/commands/makemessages.py +++ b/django/core/management/commands/makemessages.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import fnmatch import glob import io diff --git a/django/core/management/commands/migrate.py b/django/core/management/commands/migrate.py index ea9e7cd46bff..79ff872db025 100644 --- a/django/core/management/commands/migrate.py +++ b/django/core/management/commands/migrate.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import time from collections import OrderedDict from importlib import import_module diff --git a/django/core/management/commands/runserver.py b/django/core/management/commands/runserver.py index 0bfbd5b68e15..62370072c502 100644 --- a/django/core/management/commands/runserver.py +++ b/django/core/management/commands/runserver.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import errno import os import re diff --git a/django/core/management/commands/showmigrations.py b/django/core/management/commands/showmigrations.py index 890839b15097..1e20ec1745cf 100644 --- a/django/core/management/commands/showmigrations.py +++ b/django/core/management/commands/showmigrations.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.core.management.base import BaseCommand, CommandError from django.db import DEFAULT_DB_ALIAS, connections from django.db.migrations.loader import MigrationLoader diff --git a/django/core/management/commands/sqlflush.py b/django/core/management/commands/sqlflush.py index f0c7e3027071..da7d6b00e9a3 100644 --- a/django/core/management/commands/sqlflush.py +++ b/django/core/management/commands/sqlflush.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.management.base import BaseCommand from django.core.management.sql import sql_flush from django.db import DEFAULT_DB_ALIAS, connections diff --git a/django/core/management/commands/sqlmigrate.py b/django/core/management/commands/sqlmigrate.py index 5047d900c176..f6c67a5807e5 100644 --- a/django/core/management/commands/sqlmigrate.py +++ b/django/core/management/commands/sqlmigrate.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.core.management.base import BaseCommand, CommandError from django.db import DEFAULT_DB_ALIAS, connections from django.db.migrations.executor import MigrationExecutor diff --git a/django/core/management/commands/sqlsequencereset.py b/django/core/management/commands/sqlsequencereset.py index 6ac6e10d605d..788a923c72ca 100644 --- a/django/core/management/commands/sqlsequencereset.py +++ b/django/core/management/commands/sqlsequencereset.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.management.base import AppCommand from django.db import DEFAULT_DB_ALIAS, connections diff --git a/django/core/management/sql.py b/django/core/management/sql.py index c72519f30a3c..37830259003d 100644 --- a/django/core/management/sql.py +++ b/django/core/management/sql.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.apps import apps from django.db import models diff --git a/django/core/management/templates.py b/django/core/management/templates.py index ee6e284a63a9..805da991482d 100644 --- a/django/core/management/templates.py +++ b/django/core/management/templates.py @@ -113,8 +113,6 @@ def handle(self, app_or_project, name, target=None, **options): camel_case_name: camel_case_value, 'docs_version': get_docs_version(), 'django_version': django.__version__, - 'unicode_literals': '' if six.PY3 else '# -*- coding: utf-8 -*-\n' - 'from __future__ import unicode_literals\n\n', }), autoescape=False) # Setup a stub settings environment for template rendering diff --git a/django/core/management/utils.py b/django/core/management/utils.py index 7ea005a6f0b4..0fb8b0d25f71 100644 --- a/django/core/management/utils.py +++ b/django/core/management/utils.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os import sys from subprocess import PIPE, Popen diff --git a/django/core/serializers/json.py b/django/core/serializers/json.py index 9da8993ee649..b335605785f8 100644 --- a/django/core/serializers/json.py +++ b/django/core/serializers/json.py @@ -2,9 +2,6 @@ Serialize data to/from JSON """ -# Avoid shadowing the standard library json module -from __future__ import absolute_import, unicode_literals - import datetime import decimal import json diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py index 7a61999f15f1..a0cea1429731 100644 --- a/django/core/serializers/python.py +++ b/django/core/serializers/python.py @@ -3,8 +3,6 @@ and from basic Python data types (lists, dicts, strings, etc.). Useful as a basis for other serializers. """ -from __future__ import unicode_literals - from collections import OrderedDict from django.apps import apps diff --git a/django/core/serializers/xml_serializer.py b/django/core/serializers/xml_serializer.py index 5e151108fcf7..e209cb286a65 100644 --- a/django/core/serializers/xml_serializer.py +++ b/django/core/serializers/xml_serializer.py @@ -2,8 +2,6 @@ XML serializer. """ -from __future__ import unicode_literals - from collections import OrderedDict from xml.dom import pulldom from xml.sax import handler diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index 3928d8c3ff67..e27378e7a5dd 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -7,8 +7,6 @@ been reviewed for security issues. DON'T USE IT FOR PRODUCTION USE! """ -from __future__ import unicode_literals - import logging import socket import sys diff --git a/django/core/signing.py b/django/core/signing.py index 22b438315b80..f578da6f99c4 100644 --- a/django/core/signing.py +++ b/django/core/signing.py @@ -33,8 +33,6 @@ These functions make use of all of them. """ -from __future__ import unicode_literals - import base64 import datetime import json diff --git a/django/core/validators.py b/django/core/validators.py index 3f777254f481..221f3e0934c7 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os import re diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index a2416c82cddc..3d6cb7191533 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -4,8 +4,6 @@ Requires mysqlclient: https://pypi.python.org/pypi/mysqlclient/ MySQLdb is supported for Python 2 only: http://sourceforge.net/projects/mysql-python """ -from __future__ import unicode_literals - import re import sys diff --git a/django/db/backends/mysql/operations.py b/django/db/backends/mysql/operations.py index 6a55d7a88f75..4edc9272a964 100644 --- a/django/db/backends/mysql/operations.py +++ b/django/db/backends/mysql/operations.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import uuid from django.conf import settings diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index cf17f9fa6c73..317599253d39 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -3,8 +3,6 @@ Requires cx_Oracle: http://cx-oracle.sourceforge.net/ """ -from __future__ import unicode_literals - import datetime import decimal import os diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py index 9c382895b713..fd9d2d11795c 100644 --- a/django/db/backends/oracle/operations.py +++ b/django/db/backends/oracle/operations.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import re import uuid diff --git a/django/db/backends/postgresql/introspection.py b/django/db/backends/postgresql/introspection.py index e9d7d0225f23..34150c6f482e 100644 --- a/django/db/backends/postgresql/introspection.py +++ b/django/db/backends/postgresql/introspection.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import warnings from django.db.backends.base.introspection import ( diff --git a/django/db/backends/postgresql/operations.py b/django/db/backends/postgresql/operations.py index 20f60ab5ae69..542fe223cb96 100644 --- a/django/db/backends/postgresql/operations.py +++ b/django/db/backends/postgresql/operations.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from psycopg2.extras import Inet from django.conf import settings diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py index 252293d9cca3..0cd0516a0aba 100644 --- a/django/db/backends/sqlite3/base.py +++ b/django/db/backends/sqlite3/base.py @@ -4,8 +4,6 @@ Works with either the pysqlite2 module or the sqlite3 module in the standard library. """ -from __future__ import unicode_literals - import decimal import re import warnings diff --git a/django/db/backends/sqlite3/features.py b/django/db/backends/sqlite3/features.py index 4f8d3d5742b1..43a29b78f5df 100644 --- a/django/db/backends/sqlite3/features.py +++ b/django/db/backends/sqlite3/features.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import utils from django.db.backends.base.features import BaseDatabaseFeatures from django.utils import six diff --git a/django/db/backends/sqlite3/operations.py b/django/db/backends/sqlite3/operations.py index 1ab20767c452..529db944519b 100644 --- a/django/db/backends/sqlite3/operations.py +++ b/django/db/backends/sqlite3/operations.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import uuid diff --git a/django/db/backends/utils.py b/django/db/backends/utils.py index 73f1dbb6908e..b72840e989e1 100644 --- a/django/db/backends/utils.py +++ b/django/db/backends/utils.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import decimal import hashlib diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py index b2ee53917f18..84ecf90b9eba 100644 --- a/django/db/migrations/autodetector.py +++ b/django/db/migrations/autodetector.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import functools import re from itertools import chain diff --git a/django/db/migrations/exceptions.py b/django/db/migrations/exceptions.py index 7b10bd0394e5..d3da26940f11 100644 --- a/django/db/migrations/exceptions.py +++ b/django/db/migrations/exceptions.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db.utils import DatabaseError from django.utils.encoding import python_2_unicode_compatible diff --git a/django/db/migrations/executor.py b/django/db/migrations/executor.py index 1a0b6f6322c1..a590a0aca3f4 100644 --- a/django/db/migrations/executor.py +++ b/django/db/migrations/executor.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.apps.registry import apps as global_apps from django.db import migrations, router diff --git a/django/db/migrations/graph.py b/django/db/migrations/graph.py index 1a7a70322f81..83422361c4bd 100644 --- a/django/db/migrations/graph.py +++ b/django/db/migrations/graph.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import sys import warnings from collections import deque diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py index bbbde07a9843..8a42d96e9aa9 100644 --- a/django/db/migrations/loader.py +++ b/django/db/migrations/loader.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os import sys from importlib import import_module diff --git a/django/db/migrations/migration.py b/django/db/migrations/migration.py index 732dcb82e8ae..d8b993f72528 100644 --- a/django/db/migrations/migration.py +++ b/django/db/migrations/migration.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db.transaction import atomic from django.utils.encoding import python_2_unicode_compatible diff --git a/django/db/migrations/operations/base.py b/django/db/migrations/operations/base.py index 95829f716a59..f5acf9f3a8e8 100644 --- a/django/db/migrations/operations/base.py +++ b/django/db/migrations/operations/base.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import router diff --git a/django/db/migrations/operations/fields.py b/django/db/migrations/operations/fields.py index 4ce465a0c36b..431f87d7e677 100644 --- a/django/db/migrations/operations/fields.py +++ b/django/db/migrations/operations/fields.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db.models.fields import NOT_PROVIDED from django.utils.functional import cached_property diff --git a/django/db/migrations/operations/models.py b/django/db/migrations/operations/models.py index 16cadc7a2fbc..783cfcc5198b 100644 --- a/django/db/migrations/operations/models.py +++ b/django/db/migrations/operations/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models from django.db.migrations.operations.base import Operation from django.db.migrations.state import ModelState diff --git a/django/db/migrations/operations/special.py b/django/db/migrations/operations/special.py index 66c5a3af278f..706e691352dd 100644 --- a/django/db/migrations/operations/special.py +++ b/django/db/migrations/operations/special.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import router from .base import Operation diff --git a/django/db/migrations/optimizer.py b/django/db/migrations/optimizer.py index f1d51c75ba6c..ca7f9db60090 100644 --- a/django/db/migrations/optimizer.py +++ b/django/db/migrations/optimizer.py @@ -1,6 +1,3 @@ -from __future__ import unicode_literals - - class MigrationOptimizer(object): """ Powers the optimization process, where you provide a list of Operations diff --git a/django/db/migrations/questioner.py b/django/db/migrations/questioner.py index df08508a109f..d508ee9b7899 100644 --- a/django/db/migrations/questioner.py +++ b/django/db/migrations/questioner.py @@ -1,5 +1,3 @@ -from __future__ import print_function, unicode_literals - import importlib import os import sys diff --git a/django/db/migrations/recorder.py b/django/db/migrations/recorder.py index 2dcbe6c0426a..0dac81223df3 100644 --- a/django/db/migrations/recorder.py +++ b/django/db/migrations/recorder.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.apps.registry import Apps from django.db import models from django.db.utils import DatabaseError diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index 8f32fb986b43..b273097da4ea 100644 --- a/django/db/migrations/serializer.py +++ b/django/db/migrations/serializer.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import collections import datetime import decimal diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index 98724337d857..c88663ff3a72 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import copy from collections import OrderedDict from contextlib import contextmanager diff --git a/django/db/migrations/writer.py b/django/db/migrations/writer.py index df70f61eae87..ae51a1f0d9d5 100644 --- a/django/db/migrations/writer.py +++ b/django/db/migrations/writer.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os import re from importlib import import_module @@ -294,9 +292,7 @@ def serialize(cls, value): MIGRATION_TEMPLATE = """\ -# -*- coding: utf-8 -*- # Generated by Django %(version)s on %(timestamp)s -from __future__ import unicode_literals %(imports)s diff --git a/django/db/models/base.py b/django/db/models/base.py index 7ecfc06284af..2fbcf46a41d5 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import copy import inspect import warnings diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index cf3aab481582..ddfcbb4f394a 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import collections import copy import datetime diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 256441c6a2bb..aec362e84af5 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import inspect from functools import partial diff --git a/django/db/models/fields/related_descriptors.py b/django/db/models/fields/related_descriptors.py index d8d57a89ede5..696dc6f74968 100644 --- a/django/db/models/fields/related_descriptors.py +++ b/django/db/models/fields/related_descriptors.py @@ -63,8 +63,6 @@ class Child(Model): ``ReverseManyToManyDescriptor``, use ``ManyToManyDescriptor`` instead. """ -from __future__ import unicode_literals - from operator import attrgetter from django.db import connections, router, transaction diff --git a/django/db/models/fields/reverse_related.py b/django/db/models/fields/reverse_related.py index 82d9af64e711..1b706ba6eaeb 100644 --- a/django/db/models/fields/reverse_related.py +++ b/django/db/models/fields/reverse_related.py @@ -9,8 +9,6 @@ they're the closest concept currently available. """ -from __future__ import unicode_literals - from django.core import exceptions from django.utils.encoding import force_text from django.utils.functional import cached_property diff --git a/django/db/models/functions/datetime.py b/django/db/models/functions/datetime.py index 7b137eabef49..269b829e43e3 100644 --- a/django/db/models/functions/datetime.py +++ b/django/db/models/functions/datetime.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - from datetime import datetime from django.conf import settings diff --git a/django/db/models/indexes.py b/django/db/models/indexes.py index 59221312920e..c296f221636c 100644 --- a/django/db/models/indexes.py +++ b/django/db/models/indexes.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import hashlib from django.utils.encoding import force_bytes diff --git a/django/db/models/options.py b/django/db/models/options.py index 19a0de8dfd5c..943de0dd910a 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import copy import warnings from bisect import bisect diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py index fa245fcf073c..112c9586d071 100644 --- a/django/db/models/query_utils.py +++ b/django/db/models/query_utils.py @@ -5,8 +5,6 @@ large and/or so that they can be used by other modules without getting into circular import difficulties. """ -from __future__ import unicode_literals - import inspect from collections import namedtuple diff --git a/django/forms/boundfield.py b/django/forms/boundfield.py index a1063b2b057b..fa141b35ef93 100644 --- a/django/forms/boundfield.py +++ b/django/forms/boundfield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import warnings diff --git a/django/forms/fields.py b/django/forms/fields.py index 74cc3a6552db..65824fbd97d0 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -2,8 +2,6 @@ Field classes. """ -from __future__ import unicode_literals - import copy import datetime import itertools diff --git a/django/forms/forms.py b/django/forms/forms.py index 804434951731..0f1fbef6c854 100644 --- a/django/forms/forms.py +++ b/django/forms/forms.py @@ -2,8 +2,6 @@ Form classes """ -from __future__ import unicode_literals - import copy from collections import OrderedDict diff --git a/django/forms/formsets.py b/django/forms/formsets.py index 7d9e84113fc2..1e5ec8ee6be0 100644 --- a/django/forms/formsets.py +++ b/django/forms/formsets.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.exceptions import ValidationError from django.forms import Form from django.forms.fields import BooleanField, IntegerField diff --git a/django/forms/models.py b/django/forms/models.py index a0f3ff53b318..38f6812ba0e1 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -3,8 +3,6 @@ and database field objects. """ -from __future__ import unicode_literals - from collections import OrderedDict from itertools import chain diff --git a/django/forms/utils.py b/django/forms/utils.py index 88086b2c64bb..3e6991ea32f5 100644 --- a/django/forms/utils.py +++ b/django/forms/utils.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import json import sys diff --git a/django/forms/widgets.py b/django/forms/widgets.py index 71f408e783e7..3ddad40ebb04 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -2,8 +2,6 @@ HTML Widget classes """ -from __future__ import unicode_literals - import copy import datetime import re diff --git a/django/http/cookie.py b/django/http/cookie.py index 1f10eff95a74..49048787eb9c 100644 --- a/django/http/cookie.py +++ b/django/http/cookie.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import sys from django.utils import six diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index 616185f0217c..ecfbdf72522f 100644 --- a/django/http/multipartparser.py +++ b/django/http/multipartparser.py @@ -4,8 +4,6 @@ Exposes one class, ``MultiPartParser``, which feeds chunks of uploaded data to file upload handlers for processing. """ -from __future__ import unicode_literals - import base64 import binascii import cgi diff --git a/django/http/request.py b/django/http/request.py index 9ffcd23fbd0a..559081b50c43 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import copy import re import sys diff --git a/django/http/response.py b/django/http/response.py index e9e283e84064..597d68860277 100644 --- a/django/http/response.py +++ b/django/http/response.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import json import re diff --git a/django/middleware/csrf.py b/django/middleware/csrf.py index d7359e491219..14d3537f2915 100644 --- a/django/middleware/csrf.py +++ b/django/middleware/csrf.py @@ -4,8 +4,6 @@ This module provides a middleware that implements protection against request forgeries from other sites. """ -from __future__ import unicode_literals - import logging import re import string diff --git a/django/template/backends/base.py b/django/template/backends/base.py index 00b5fc4b2bc4..9f48fbfdca8b 100644 --- a/django/template/backends/base.py +++ b/django/template/backends/base.py @@ -1,6 +1,3 @@ -# Since this package contains a "django" module, this is required on Python 2. -from __future__ import absolute_import - from django.core.exceptions import ( ImproperlyConfigured, SuspiciousFileOperation, ) diff --git a/django/template/backends/django.py b/django/template/backends/django.py index afe1a7cd2313..7ae8141251e7 100644 --- a/django/template/backends/django.py +++ b/django/template/backends/django.py @@ -1,6 +1,3 @@ -# Since this package contains a "django" module, this is required on Python 2. -from __future__ import absolute_import - import sys from importlib import import_module from pkgutil import walk_packages diff --git a/django/template/backends/dummy.py b/django/template/backends/dummy.py index 1d6f446dec64..015cb8bda061 100644 --- a/django/template/backends/dummy.py +++ b/django/template/backends/dummy.py @@ -1,6 +1,3 @@ -# Since this package contains a "django" module, this is required on Python 2. -from __future__ import absolute_import - import errno import io import string diff --git a/django/template/backends/jinja2.py b/django/template/backends/jinja2.py index cf08858db940..2497df1b8414 100644 --- a/django/template/backends/jinja2.py +++ b/django/template/backends/jinja2.py @@ -1,6 +1,3 @@ -# Since this package contains a "django" module, this is required on Python 2. -from __future__ import absolute_import - import sys import jinja2 diff --git a/django/template/backends/utils.py b/django/template/backends/utils.py index 881d83acf27d..8147bb49889f 100644 --- a/django/template/backends/utils.py +++ b/django/template/backends/utils.py @@ -1,6 +1,3 @@ -# Since this package contains a "django" module, this is required on Python 2. -from __future__ import absolute_import - from django.middleware.csrf import get_token from django.utils.functional import lazy from django.utils.html import format_html diff --git a/django/template/base.py b/django/template/base.py index af3b6c5371e8..3aa7941879e3 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -49,8 +49,6 @@ '' """ -from __future__ import unicode_literals - import inspect import logging import re diff --git a/django/template/context_processors.py b/django/template/context_processors.py index da5276ce44bf..85cd3eaa5f1a 100644 --- a/django/template/context_processors.py +++ b/django/template/context_processors.py @@ -7,8 +7,6 @@ of a DjangoTemplates backend and used by RequestContext. """ -from __future__ import unicode_literals - import itertools from django.conf import settings diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index e35415bdf754..fc249953ea1b 100644 --- a/django/template/defaultfilters.py +++ b/django/template/defaultfilters.py @@ -1,6 +1,4 @@ """Default variable filters.""" -from __future__ import unicode_literals - import random as random_module import re from decimal import ROUND_HALF_UP, Context, Decimal, InvalidOperation diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index d35e80cfa95b..2c455aff7b6e 100644 --- a/django/template/defaulttags.py +++ b/django/template/defaulttags.py @@ -1,6 +1,4 @@ """Default tags used by the template system, available to all templates.""" -from __future__ import unicode_literals - import re import sys import warnings diff --git a/django/templatetags/cache.py b/django/templatetags/cache.py index 1b49bca1b6e4..3af6dc4df67f 100644 --- a/django/templatetags/cache.py +++ b/django/templatetags/cache.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.cache import InvalidCacheBackendError, caches from django.core.cache.utils import make_template_fragment_key from django.template import ( diff --git a/django/templatetags/i18n.py b/django/templatetags/i18n.py index 0c4f03e948e5..4a32e628c214 100644 --- a/django/templatetags/i18n.py +++ b/django/templatetags/i18n.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import sys from django.conf import settings diff --git a/django/test/client.py b/django/test/client.py index 05d3d7860349..7365b1d2aa36 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import json import mimetypes import os diff --git a/django/test/html.py b/django/test/html.py index dfff8d636926..94dc7f540e5f 100644 --- a/django/test/html.py +++ b/django/test/html.py @@ -2,8 +2,6 @@ Comparing two html documents. """ -from __future__ import unicode_literals - import re from django.utils import six diff --git a/django/test/selenium.py b/django/test/selenium.py index ae8e603a5848..de3744c91e73 100644 --- a/django/test/selenium.py +++ b/django/test/selenium.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import sys import unittest from contextlib import contextmanager diff --git a/django/test/testcases.py b/django/test/testcases.py index e342ac282d16..88d355311daa 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import difflib import json import posixpath diff --git a/django/urls/base.py b/django/urls/base.py index ddf3b64dabbc..8e30acb860b5 100644 --- a/django/urls/base.py +++ b/django/urls/base.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from threading import local from django.utils import six diff --git a/django/urls/exceptions.py b/django/urls/exceptions.py index 14967f7eb4a6..87bf5284f757 100644 --- a/django/urls/exceptions.py +++ b/django/urls/exceptions.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.http import Http404 diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py index 1de59a8763cc..4a66895de521 100644 --- a/django/urls/resolvers.py +++ b/django/urls/resolvers.py @@ -5,8 +5,6 @@ a string) and returns a ResolverMatch object which provides access to all attributes of the resolved URL match. """ -from __future__ import unicode_literals - import functools import re import threading diff --git a/django/urls/utils.py b/django/urls/utils.py index 1901c0a494b8..8558b82bbad0 100644 --- a/django/urls/utils.py +++ b/django/urls/utils.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from importlib import import_module from django.core.exceptions import ViewDoesNotExist diff --git a/django/utils/_os.py b/django/utils/_os.py index a874214a5890..994f766d498c 100644 --- a/django/utils/_os.py +++ b/django/utils/_os.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os import sys import tempfile diff --git a/django/utils/cache.py b/django/utils/cache.py index 0f6232b51b4a..fabdb363b9ab 100644 --- a/django/utils/cache.py +++ b/django/utils/cache.py @@ -16,8 +16,6 @@ An example: i18n middleware would need to distinguish caches by the "Accept-language" header. """ -from __future__ import unicode_literals - import hashlib import logging import re diff --git a/django/utils/crypto.py b/django/utils/crypto.py index 3804dd911117..a7257a1b3a6d 100644 --- a/django/utils/crypto.py +++ b/django/utils/crypto.py @@ -1,8 +1,6 @@ """ Django's standard crypto functions and utilities. """ -from __future__ import unicode_literals - import binascii import hashlib import hmac diff --git a/django/utils/dateformat.py b/django/utils/dateformat.py index 70650bf625b6..861bf8f9236a 100644 --- a/django/utils/dateformat.py +++ b/django/utils/dateformat.py @@ -10,8 +10,6 @@ 7th October 2003 11:39 >>> """ -from __future__ import unicode_literals - import calendar import datetime import re diff --git a/django/utils/deprecation.py b/django/utils/deprecation.py index 28405cf2c190..a37f2e3d69da 100644 --- a/django/utils/deprecation.py +++ b/django/utils/deprecation.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import inspect import warnings diff --git a/django/utils/encoding.py b/django/utils/encoding.py index 999ffae19a02..a3b07dcec6a9 100644 --- a/django/utils/encoding.py +++ b/django/utils/encoding.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - import codecs import datetime import locale diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py index d8a932b02002..64aa970e93da 100644 --- a/django/utils/feedgenerator.py +++ b/django/utils/feedgenerator.py @@ -21,8 +21,6 @@ For definitions of the different versions of RSS, see: http://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004/02/04/incompatible-rss """ -from __future__ import unicode_literals - import datetime from django.utils import datetime_safe, six diff --git a/django/utils/glob.py b/django/utils/glob.py index d3f9e081381c..92194d21eb2a 100644 --- a/django/utils/glob.py +++ b/django/utils/glob.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os.path import re diff --git a/django/utils/html.py b/django/utils/html.py index ff9adffc750e..384093a02f1c 100644 --- a/django/utils/html.py +++ b/django/utils/html.py @@ -1,7 +1,5 @@ """HTML utilities suitable for global use.""" -from __future__ import unicode_literals - import re from django.utils import six diff --git a/django/utils/http.py b/django/utils/http.py index cba2a080956a..f4e77b86f96c 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import base64 import calendar import datetime diff --git a/django/utils/inspect.py b/django/utils/inspect.py index 597b2c095e10..ffcbf3040730 100644 --- a/django/utils/inspect.py +++ b/django/utils/inspect.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import inspect from django.utils import six diff --git a/django/utils/jslex.py b/django/utils/jslex.py index bef61291888d..0958ac030cab 100644 --- a/django/utils/jslex.py +++ b/django/utils/jslex.py @@ -1,7 +1,5 @@ """JsLex: a lexer for Javascript""" # Originally from https://bitbucket.org/ned/jslex -from __future__ import unicode_literals - import re diff --git a/django/utils/log.py b/django/utils/log.py index 2b57c6beffe6..77e2f592502c 100644 --- a/django/utils/log.py +++ b/django/utils/log.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import logging import logging.config # needed when logging_config doesn't start with logging.config from copy import copy diff --git a/django/utils/lorem_ipsum.py b/django/utils/lorem_ipsum.py index 03426c152bef..87988d20507a 100644 --- a/django/utils/lorem_ipsum.py +++ b/django/utils/lorem_ipsum.py @@ -2,8 +2,6 @@ Utility functions for generating "lorem ipsum" Latin text. """ -from __future__ import unicode_literals - import random COMMON_P = ( diff --git a/django/utils/numberformat.py b/django/utils/numberformat.py index ae5a3b547410..d4c9ad74a5d3 100644 --- a/django/utils/numberformat.py +++ b/django/utils/numberformat.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from decimal import Decimal from django.conf import settings diff --git a/django/utils/regex_helper.py b/django/utils/regex_helper.py index d046b71d96e1..41f2459491ec 100644 --- a/django/utils/regex_helper.py +++ b/django/utils/regex_helper.py @@ -5,8 +5,6 @@ This is not, and is not intended to be, a complete reg-exp decompiler. It should be good enough for a large class of URLS, however. """ -from __future__ import unicode_literals - import warnings from django.utils import six diff --git a/django/utils/six.py b/django/utils/six.py index 52627592b750..b4038c72fac9 100644 --- a/django/utils/six.py +++ b/django/utils/six.py @@ -20,8 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from __future__ import absolute_import - import functools import itertools import operator diff --git a/django/utils/text.py b/django/utils/text.py index b0f139e03497..dcedc524b097 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import re import unicodedata from gzip import GzipFile diff --git a/django/utils/timesince.py b/django/utils/timesince.py index b0eefaf73437..f87d958f4f22 100644 --- a/django/utils/timesince.py +++ b/django/utils/timesince.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import calendar import datetime diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py index 6cdcaf9bf178..fd02fa16a33e 100644 --- a/django/utils/translation/__init__.py +++ b/django/utils/translation/__init__.py @@ -1,8 +1,6 @@ """ Internationalization support. """ -from __future__ import unicode_literals - import re import warnings diff --git a/django/utils/translation/template.py b/django/utils/translation/template.py index b8618c4dd2e9..04dac65e90e2 100644 --- a/django/utils/translation/template.py +++ b/django/utils/translation/template.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import re import warnings diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py index b3da22482a48..9f016e85249f 100644 --- a/django/utils/translation/trans_real.py +++ b/django/utils/translation/trans_real.py @@ -1,6 +1,4 @@ """Translation helper functions.""" -from __future__ import unicode_literals - import gettext as gettext_module import os import re diff --git a/django/utils/version.py b/django/utils/version.py index f5b0f109e6bf..dcf0c2186644 100644 --- a/django/utils/version.py +++ b/django/utils/version.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import os import subprocess diff --git a/django/views/debug.py b/django/views/debug.py index 0fb5ab1a2d81..7c33aa8eca3a 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import re import sys import types diff --git a/django/views/generic/base.py b/django/views/generic/base.py index fc04bcc311db..4187e70b12e2 100644 --- a/django/views/generic/base.py +++ b/django/views/generic/base.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import logging from functools import update_wrapper diff --git a/django/views/generic/dates.py b/django/views/generic/dates.py index 938c53853588..d03140a9738c 100644 --- a/django/views/generic/dates.py +++ b/django/views/generic/dates.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from django.conf import settings diff --git a/django/views/generic/detail.py b/django/views/generic/detail.py index 2b67ef5e5ceb..b84585804b4d 100644 --- a/django/views/generic/detail.py +++ b/django/views/generic/detail.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.exceptions import ImproperlyConfigured from django.db import models from django.http import Http404 diff --git a/django/views/generic/list.py b/django/views/generic/list.py index 2277ffd4d3ec..951c11f5a520 100644 --- a/django/views/generic/list.py +++ b/django/views/generic/list.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.exceptions import ImproperlyConfigured from django.core.paginator import InvalidPage, Paginator from django.db.models.query import QuerySet diff --git a/django/views/static.py b/django/views/static.py index 2af26621f392..bfa171357d38 100644 --- a/django/views/static.py +++ b/django/views/static.py @@ -2,8 +2,6 @@ Views and functions for serving static files. These are only to be used during development, and SHOULD NOT be used in a production setting. """ -from __future__ import unicode_literals - import mimetypes import os import posixpath diff --git a/docs/conf.py b/docs/conf.py index 1643559a1dc0..13a6dbd67e00 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# # Django documentation build configuration file, created by # sphinx-quickstart on Thu Mar 27 09:06:53 2008. # @@ -11,8 +9,6 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from __future__ import unicode_literals - import sys from os.path import abspath, dirname, join diff --git a/docs/howto/writing-migrations.txt b/docs/howto/writing-migrations.txt index 35964f7ce851..02579eeeb4ad 100644 --- a/docs/howto/writing-migrations.txt +++ b/docs/howto/writing-migrations.txt @@ -100,10 +100,7 @@ the respective field according to your needs. .. snippet:: :filename: 0006_remove_uuid_null.py - # -*- coding: utf-8 -*- # Generated by Django A.B on YYYY-MM-DD HH:MM - from __future__ import unicode_literals - from django.db import migrations, models import uuid @@ -154,10 +151,7 @@ the respective field according to your needs. .. snippet:: :filename: 0005_populate_uuid_values.py - # -*- coding: utf-8 -*- # Generated by Django A.B on YYYY-MM-DD HH:MM - from __future__ import unicode_literals - from django.db import migrations, models import uuid diff --git a/docs/ref/files/file.txt b/docs/ref/files/file.txt index 6c218e38b332..4169b74b8863 100644 --- a/docs/ref/files/file.txt +++ b/docs/ref/files/file.txt @@ -111,7 +111,6 @@ The ``ContentFile`` class but unlike :class:`~django.core.files.File` it operates on string content (bytes also supported), rather than an actual file. For example:: - from __future__ import unicode_literals from django.core.files.base import ContentFile f1 = ContentFile("esta sentencia está en español") diff --git a/docs/ref/migration-operations.txt b/docs/ref/migration-operations.txt index 7e5f4d478490..e6e6f73a99d1 100644 --- a/docs/ref/migration-operations.txt +++ b/docs/ref/migration-operations.txt @@ -310,9 +310,6 @@ class in the migration file, and just pass it to ``RunPython``. Here's an example of using ``RunPython`` to create some initial objects on a ``Country`` model:: - # -*- coding: utf-8 -*- - from __future__ import unicode_literals - from django.db import migrations, models def forwards_func(apps, schema_editor): diff --git a/docs/topics/i18n/formatting.txt b/docs/topics/i18n/formatting.txt index 248d6b0d23a9..4a0ce6d3e843 100644 --- a/docs/topics/i18n/formatting.txt +++ b/docs/topics/i18n/formatting.txt @@ -177,8 +177,6 @@ To customize the English formats, a structure like this would be needed:: where :file:`formats.py` contains custom format definitions. For example:: - from __future__ import unicode_literals - THOUSAND_SEPARATOR = '\xa0' to use a non-breaking space (Unicode ``00A0``) as a thousand separator, diff --git a/docs/topics/migrations.txt b/docs/topics/migrations.txt index e8675fe5457a..5475e7b385f7 100644 --- a/docs/topics/migrations.txt +++ b/docs/topics/migrations.txt @@ -454,10 +454,7 @@ the file in the right place, suggest a name, and add dependencies for you):: Then, open up the file; it should look something like this:: - # -*- coding: utf-8 -*- # Generated by Django A.B on YYYY-MM-DD HH:MM - from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): @@ -485,9 +482,6 @@ combined values of ``first_name`` and ``last_name`` (we've come to our senses and realized that not everyone has first and last names). All we need to do is use the historical model and iterate over the rows:: - # -*- coding: utf-8 -*- - from __future__ import unicode_literals - from django.db import migrations, models def combine_names(apps, schema_editor): @@ -757,26 +751,6 @@ The decorator adds logic to capture and preserve the arguments on their way into your constructor, and then returns those arguments exactly when deconstruct() is called. -Supporting Python 2 and 3 -========================= - -In order to generate migrations that support both Python 2 and 3, all string -literals used in your models and fields (e.g. ``verbose_name``, -``related_name``, etc.), must be consistently either bytestrings or text -(unicode) strings in both Python 2 and 3 (rather than bytes in Python 2 and -text in Python 3, the default situation for unmarked string literals.) -Otherwise running :djadmin:`makemigrations` under Python 3 will generate -spurious new migrations to convert all these string attributes to text. - -The easiest way to achieve this is to follow the advice in Django's -:doc:`Python 3 porting guide ` and make sure that all your -modules begin with ``from __future__ import unicode_literals``, so that all -unmarked string literals are always unicode, regardless of Python version. When -you add this to an app with existing migrations generated on Python 2, your -next run of :djadmin:`makemigrations` on Python 3 will likely generate many -changes as it converts all the bytestring attributes to text strings; this is -normal and should only happen once. - Supporting multiple Django versions =================================== diff --git a/docs/topics/templates.txt b/docs/topics/templates.txt index a819acf3f01e..23d74cbaa344 100644 --- a/docs/topics/templates.txt +++ b/docs/topics/templates.txt @@ -422,8 +422,6 @@ environment. For example, you can create ``myproject/jinja2.py`` with this content:: - from __future__ import absolute_import # Python 2 only - from django.contrib.staticfiles.storage import staticfiles_storage from django.urls import reverse diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index 2f0f6ad46b2e..48e746031450 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from django.contrib import admin diff --git a/tests/admin_checks/tests.py b/tests/admin_checks/tests.py index 3d629077c5cb..e8714fe1a803 100644 --- a/tests/admin_checks/tests.py +++ b/tests/admin_checks/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django import forms from django.contrib import admin from django.contrib.admin import AdminSite diff --git a/tests/admin_custom_urls/tests.py b/tests/admin_custom_urls/tests.py index 319e6f66534c..e0c2d4f74662 100644 --- a/tests/admin_custom_urls/tests.py +++ b/tests/admin_custom_urls/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.admin.utils import quote from django.contrib.auth.models import User from django.template.response import TemplateResponse diff --git a/tests/admin_docs/test_middleware.py b/tests/admin_docs/test_middleware.py index 426c78d58fb0..8a818e15d198 100644 --- a/tests/admin_docs/test_middleware.py +++ b/tests/admin_docs/test_middleware.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.auth.models import User from .tests import AdminDocsTestCase, TestDataMixin diff --git a/tests/admin_docs/test_utils.py b/tests/admin_docs/test_utils.py index 013d00391453..0c738e5e89a1 100644 --- a/tests/admin_docs/test_utils.py +++ b/tests/admin_docs/test_utils.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import unittest from django.contrib.admindocs.utils import ( diff --git a/tests/admin_docs/test_views.py b/tests/admin_docs/test_views.py index b48147fc852e..9f7f0ee268b5 100644 --- a/tests/admin_docs/test_views.py +++ b/tests/admin_docs/test_views.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import sys import unittest diff --git a/tests/admin_docs/tests.py b/tests/admin_docs/tests.py index c376a4cf5ec3..2a2f9d25e080 100644 --- a/tests/admin_docs/tests.py +++ b/tests/admin_docs/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.auth.models import User from django.test import TestCase, modify_settings, override_settings diff --git a/tests/admin_filters/models.py b/tests/admin_filters/models.py index 8860201d35a5..f508aa1f9b4e 100644 --- a/tests/admin_filters/models.py +++ b/tests/admin_filters/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.auth.models import User from django.contrib.contenttypes.fields import ( GenericForeignKey, GenericRelation, diff --git a/tests/admin_filters/tests.py b/tests/admin_filters/tests.py index e2da7ec59e59..0df02708a81f 100644 --- a/tests/admin_filters/tests.py +++ b/tests/admin_filters/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import sys import unittest diff --git a/tests/admin_inlines/models.py b/tests/admin_inlines/models.py index 15297c521ff3..e78511aaab06 100644 --- a/tests/admin_inlines/models.py +++ b/tests/admin_inlines/models.py @@ -1,9 +1,6 @@ """ Testing of admin inline formsets. - """ -from __future__ import unicode_literals - import random from django.contrib.contenttypes.fields import GenericForeignKey diff --git a/tests/admin_inlines/test_templates.py b/tests/admin_inlines/test_templates.py index 236ec5df7b0a..5c8d7ce0c105 100644 --- a/tests/admin_inlines/test_templates.py +++ b/tests/admin_inlines/test_templates.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import json from django.template.loader import render_to_string diff --git a/tests/admin_inlines/tests.py b/tests/admin_inlines/tests.py index 6922a9f82fd5..6deba9b1c240 100644 --- a/tests/admin_inlines/tests.py +++ b/tests/admin_inlines/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.admin import ModelAdmin, TabularInline from django.contrib.admin.helpers import InlineAdminForm from django.contrib.admin.tests import AdminSeleniumTestCase diff --git a/tests/admin_ordering/models.py b/tests/admin_ordering/models.py index cd26f2a710d0..b8098b9bccf9 100644 --- a/tests/admin_ordering/models.py +++ b/tests/admin_ordering/models.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from django.contrib import admin from django.db import models diff --git a/tests/admin_ordering/tests.py b/tests/admin_ordering/tests.py index def9b8b7c7b4..250b59dea8d9 100644 --- a/tests/admin_ordering/tests.py +++ b/tests/admin_ordering/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib import admin from django.contrib.admin.options import ModelAdmin from django.contrib.auth.models import User diff --git a/tests/admin_registration/tests.py b/tests/admin_registration/tests.py index db38265182b1..125d8eae6117 100644 --- a/tests/admin_registration/tests.py +++ b/tests/admin_registration/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib import admin from django.contrib.admin.decorators import register from django.contrib.admin.sites import site diff --git a/tests/admin_scripts/another_app_waiting_migration/migrations/0001_initial.py b/tests/admin_scripts/another_app_waiting_migration/migrations/0001_initial.py index 1486231d6b0b..d5fce1af362b 100644 --- a/tests/admin_scripts/another_app_waiting_migration/migrations/0001_initial.py +++ b/tests/admin_scripts/another_app_waiting_migration/migrations/0001_initial.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/admin_scripts/another_app_waiting_migration/models.py b/tests/admin_scripts/another_app_waiting_migration/models.py index 6c12c6ab5d5c..c089cb64e6e6 100644 --- a/tests/admin_scripts/another_app_waiting_migration/models.py +++ b/tests/admin_scripts/another_app_waiting_migration/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models diff --git a/tests/admin_scripts/app_raising_messages/models.py b/tests/admin_scripts/app_raising_messages/models.py index bd37ba458a37..400fc8f9079a 100644 --- a/tests/admin_scripts/app_raising_messages/models.py +++ b/tests/admin_scripts/app_raising_messages/models.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.core import checks from django.db import models diff --git a/tests/admin_scripts/app_raising_warning/models.py b/tests/admin_scripts/app_raising_warning/models.py index 0ae304263460..bc9b3b380f47 100644 --- a/tests/admin_scripts/app_raising_warning/models.py +++ b/tests/admin_scripts/app_raising_warning/models.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.core import checks from django.db import models diff --git a/tests/admin_scripts/app_waiting_migration/migrations/0001_initial.py b/tests/admin_scripts/app_waiting_migration/migrations/0001_initial.py index 52d594a94a69..aa47c4d47408 100644 --- a/tests/admin_scripts/app_waiting_migration/migrations/0001_initial.py +++ b/tests/admin_scripts/app_waiting_migration/migrations/0001_initial.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/admin_scripts/app_waiting_migration/models.py b/tests/admin_scripts/app_waiting_migration/models.py index 5e9f0e33148a..46fee9c8571b 100644 --- a/tests/admin_scripts/app_waiting_migration/models.py +++ b/tests/admin_scripts/app_waiting_migration/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index af3ada5bcc4c..08fe64553527 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -1,11 +1,8 @@ -# -*- coding: utf-8 -*- """ A series of tests to establish that the command-line management tools work as advertised - especially with regards to the handling of the DJANGO_SETTINGS_MODULE and default settings.py files. """ -from __future__ import unicode_literals - import codecs import os import re @@ -30,7 +27,7 @@ ) from django.utils._os import npath, upath from django.utils.encoding import force_text -from django.utils.six import PY2, PY3, StringIO +from django.utils.six import PY2, StringIO custom_templates_dir = os.path.join(os.path.dirname(upath(__file__)), 'custom_templates') @@ -67,7 +64,6 @@ def write_settings(self, filename, apps=None, is_dir=False, sdict=None, extra=No settings_file_path = os.path.join(self.test_dir, filename) with open(settings_file_path, 'w') as settings_file: - settings_file.write('# -*- coding: utf-8 -*\n') settings_file.write('# Settings file automatically generated by admin_scripts test case\n') if extra: settings_file.write("%s\n" % extra) @@ -614,26 +610,10 @@ def test_setup_environ(self): self.addCleanup(shutil.rmtree, app_path) self.assertNoOutput(err) self.assertTrue(os.path.exists(app_path)) - unicode_literals_import = "# -*- coding: utf-8 -*-\nfrom __future__ import unicode_literals\n\n" with open(os.path.join(app_path, 'apps.py'), 'r') as f: content = f.read() self.assertIn("class SettingsTestConfig(AppConfig)", content) self.assertIn("name = 'settings_test'", content) - if not PY3: - self.assertIn(unicode_literals_import, content) - if not PY3: - with open(os.path.join(app_path, 'models.py'), 'r') as fp: - content = fp.read() - self.assertIn(unicode_literals_import, content) - with open(os.path.join(app_path, 'views.py'), 'r') as fp: - content = fp.read() - self.assertIn(unicode_literals_import, content) - with open(os.path.join(app_path, 'admin.py'), 'r') as fp: - content = fp.read() - self.assertIn(unicode_literals_import, content) - with open(os.path.join(app_path, 'tests.py'), 'r') as fp: - content = fp.read() - self.assertIn(unicode_literals_import, content) def test_setup_environ_custom_template(self): "directory: startapp creates the correct directory with a custom template" diff --git a/tests/admin_utils/test_logentry.py b/tests/admin_utils/test_logentry.py index ba0e3c1bfd99..89b25f462b47 100644 --- a/tests/admin_utils/test_logentry.py +++ b/tests/admin_utils/test_logentry.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import json from datetime import datetime diff --git a/tests/admin_utils/tests.py b/tests/admin_utils/tests.py index 966a1f11f2d8..245334df4d24 100644 --- a/tests/admin_utils/tests.py +++ b/tests/admin_utils/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import datetime from decimal import Decimal diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py index d85f5de059ae..b8d35b6d81e3 100644 --- a/tests/admin_views/admin.py +++ b/tests/admin_views/admin.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import os import tempfile from wsgiref.util import FileWrapper diff --git a/tests/admin_views/custom_has_permission_admin.py b/tests/admin_views/custom_has_permission_admin.py index a578895b5a75..0c774ef57372 100644 --- a/tests/admin_views/custom_has_permission_admin.py +++ b/tests/admin_views/custom_has_permission_admin.py @@ -1,8 +1,6 @@ """ A custom AdminSite for AdminViewPermissionsTest.test_login_has_permission(). """ -from __future__ import unicode_literals - from django.contrib import admin from django.contrib.auth import get_permission_codename from django.contrib.auth.forms import AuthenticationForm diff --git a/tests/admin_views/customadmin.py b/tests/admin_views/customadmin.py index 644bbedae77e..5eb1f2baa237 100644 --- a/tests/admin_views/customadmin.py +++ b/tests/admin_views/customadmin.py @@ -1,8 +1,6 @@ """ A second, custom AdminSite -- see tests.CustomAdminSiteTests. """ -from __future__ import unicode_literals - from django.conf.urls import url from django.contrib import admin from django.contrib.auth.admin import UserAdmin diff --git a/tests/admin_views/models.py b/tests/admin_views/models.py index 86ab055f3027..54d8f5f96860 100644 --- a/tests/admin_views/models.py +++ b/tests/admin_views/models.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime import os import tempfile diff --git a/tests/admin_views/test_adminsite.py b/tests/admin_views/test_adminsite.py index 7077d4be58f1..088561535316 100644 --- a/tests/admin_views/test_adminsite.py +++ b/tests/admin_views/test_adminsite.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.conf.urls import url from django.contrib import admin from django.contrib.auth.models import User diff --git a/tests/admin_views/test_templatetags.py b/tests/admin_views/test_templatetags.py index a62c1caf8932..19a6450be821 100644 --- a/tests/admin_views/test_templatetags.py +++ b/tests/admin_views/test_templatetags.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.admin.templatetags.admin_modify import submit_row from django.contrib.auth.admin import UserAdmin from django.contrib.auth.models import User diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index a724d57559b4..2353a9ee7aaa 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime import json import os diff --git a/tests/admin_widgets/models.py b/tests/admin_widgets/models.py index 274c36e15ee3..43aa88e254a0 100644 --- a/tests/admin_widgets/models.py +++ b/tests/admin_widgets/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.auth.models import User from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py index b74df4e25136..8eadab07d577 100644 --- a/tests/admin_widgets/tests.py +++ b/tests/admin_widgets/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import gettext import os import re diff --git a/tests/aggregation/models.py b/tests/aggregation/models.py index 9d4794641864..37421dbb81a2 100644 --- a/tests/aggregation/models.py +++ b/tests/aggregation/models.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/aggregation/tests.py b/tests/aggregation/tests.py index 4711869cfd76..25a1e00827df 100644 --- a/tests/aggregation/tests.py +++ b/tests/aggregation/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import re from decimal import Decimal diff --git a/tests/aggregation_regress/models.py b/tests/aggregation_regress/models.py index e606beb304da..a9ab1cbdcea8 100644 --- a/tests/aggregation_regress/models.py +++ b/tests/aggregation_regress/models.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from django.contrib.contenttypes.fields import ( GenericForeignKey, GenericRelation, ) diff --git a/tests/aggregation_regress/tests.py b/tests/aggregation_regress/tests.py index 2958736fe9a3..afbc7c20b2e3 100644 --- a/tests/aggregation_regress/tests.py +++ b/tests/aggregation_regress/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import pickle from decimal import Decimal diff --git a/tests/annotations/models.py b/tests/annotations/models.py index a92ca0b43a9d..79648ffd961d 100644 --- a/tests/annotations/models.py +++ b/tests/annotations/models.py @@ -1,4 +1,3 @@ -# coding: utf-8 from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py index b90286b9daee..bffac69e219d 100644 --- a/tests/annotations/tests.py +++ b/tests/annotations/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from decimal import Decimal diff --git a/tests/app_loading/tests.py b/tests/app_loading/tests.py index a79bdaec04f7..021e711796b6 100644 --- a/tests/app_loading/tests.py +++ b/tests/app_loading/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os from django.apps import apps diff --git a/tests/apps/apps.py b/tests/apps/apps.py index 7faa63e43524..1096c1e4b881 100644 --- a/tests/apps/apps.py +++ b/tests/apps/apps.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.apps import AppConfig diff --git a/tests/apps/models.py b/tests/apps/models.py index 733be35d2edb..f5f5926ea63c 100644 --- a/tests/apps/models.py +++ b/tests/apps/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.apps.registry import Apps from django.db import models diff --git a/tests/apps/tests.py b/tests/apps/tests.py index a0f7ecbb10d3..d2adc681f21b 100644 --- a/tests/apps/tests.py +++ b/tests/apps/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os from unittest import skipUnless diff --git a/tests/auth_tests/test_auth_backends.py b/tests/auth_tests/test_auth_backends.py index 080270296bad..f06e82569830 100644 --- a/tests/auth_tests/test_auth_backends.py +++ b/tests/auth_tests/test_auth_backends.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import date from django.contrib.auth import ( diff --git a/tests/auth_tests/test_basic.py b/tests/auth_tests/test_basic.py index 4555e282705d..b2c70faffb7c 100644 --- a/tests/auth_tests/test_basic.py +++ b/tests/auth_tests/test_basic.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.contrib.auth import get_user, get_user_model from django.contrib.auth.models import AnonymousUser, User from django.core.exceptions import ImproperlyConfigured diff --git a/tests/auth_tests/test_checks.py b/tests/auth_tests/test_checks.py index 8dca3159d1a9..3f86e7a80ed2 100644 --- a/tests/auth_tests/test_checks.py +++ b/tests/auth_tests/test_checks.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.auth.checks import ( check_models_permissions, check_user_model, ) diff --git a/tests/auth_tests/test_deprecated_views.py b/tests/auth_tests/test_deprecated_views.py index 542833686a85..d084f4dcef0f 100644 --- a/tests/auth_tests/test_deprecated_views.py +++ b/tests/auth_tests/test_deprecated_views.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime import itertools import re diff --git a/tests/auth_tests/test_forms.py b/tests/auth_tests/test_forms.py index cc77288f56a1..36b4e8f4e729 100644 --- a/tests/auth_tests/test_forms.py +++ b/tests/auth_tests/test_forms.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime import re from unittest import skipIf diff --git a/tests/auth_tests/test_handlers.py b/tests/auth_tests/test_handlers.py index 0e2a42b80a97..57a43f877f20 100644 --- a/tests/auth_tests/test_handlers.py +++ b/tests/auth_tests/test_handlers.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.auth.handlers.modwsgi import ( check_password, groups_for_user, ) diff --git a/tests/auth_tests/test_hashers.py b/tests/auth_tests/test_hashers.py index 5a8e44bcd731..4b6aa8f7995b 100644 --- a/tests/auth_tests/test_hashers.py +++ b/tests/auth_tests/test_hashers.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from unittest import skipUnless from django.conf.global_settings import PASSWORD_HASHERS diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 976b318c7464..eaceafb44455 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import sys from datetime import date diff --git a/tests/auth_tests/test_models.py b/tests/auth_tests/test_models.py index bd649495019e..ebe3dc083793 100644 --- a/tests/auth_tests/test_models.py +++ b/tests/auth_tests/test_models.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.conf.global_settings import PASSWORD_HASHERS from django.contrib.auth import get_user_model from django.contrib.auth.base_user import AbstractBaseUser diff --git a/tests/auth_tests/test_validators.py b/tests/auth_tests/test_validators.py index e074716f46ed..19d75c8d3006 100644 --- a/tests/auth_tests/test_validators.py +++ b/tests/auth_tests/test_validators.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import os from django.contrib.auth import validators diff --git a/tests/auth_tests/test_views.py b/tests/auth_tests/test_views.py index 2d0d2ae96fbb..f25080092101 100644 --- a/tests/auth_tests/test_views.py +++ b/tests/auth_tests/test_views.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime import itertools import os diff --git a/tests/backends/models.py b/tests/backends/models.py index e57206ec6017..18423e1276c6 100644 --- a/tests/backends/models.py +++ b/tests/backends/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.contenttypes.fields import ( GenericForeignKey, GenericRelation, ) diff --git a/tests/backends/test_mysql.py b/tests/backends/test_mysql.py index db8aff12d0ef..d7030975f60d 100644 --- a/tests/backends/test_mysql.py +++ b/tests/backends/test_mysql.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import unittest from django.core.exceptions import ImproperlyConfigured diff --git a/tests/backends/tests.py b/tests/backends/tests.py index e17679a4ba28..7a102b040a30 100644 --- a/tests/backends/tests.py +++ b/tests/backends/tests.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Unit and doctests for specific database backends. -from __future__ import unicode_literals - import datetime import re import threading diff --git a/tests/base/models.py b/tests/base/models.py index 4a8a2ffd8175..077b93fbb800 100644 --- a/tests/base/models.py +++ b/tests/base/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models from django.utils import six diff --git a/tests/basic/models.py b/tests/basic/models.py index 91fbe7d64816..a6010f1291ff 100644 --- a/tests/basic/models.py +++ b/tests/basic/models.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Bare-bones model diff --git a/tests/basic/tests.py b/tests/basic/tests.py index dd7570c5b9e1..544a862766c8 100644 --- a/tests/basic/tests.py +++ b/tests/basic/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import threading from datetime import datetime, timedelta diff --git a/tests/builtin_server/tests.py b/tests/builtin_server/tests.py index 14253f70a457..2784571b0cd7 100644 --- a/tests/builtin_server/tests.py +++ b/tests/builtin_server/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import sys import traceback from io import BytesIO diff --git a/tests/bulk_create/tests.py b/tests/bulk_create/tests.py index 3378f0010af9..65d0f9ba8c6d 100644 --- a/tests/bulk_create/tests.py +++ b/tests/bulk_create/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from operator import attrgetter from django.db import connection diff --git a/tests/cache/tests.py b/tests/cache/tests.py index edf25cfc65df..5be3db0ef45f 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -1,9 +1,5 @@ -# -*- coding: utf-8 -*- - # Unit tests for cache framework # Uses whatever cache backend is set in the test settings file. -from __future__ import unicode_literals - import copy import io import os diff --git a/tests/check_framework/models.py b/tests/check_framework/models.py index fe573fce84db..f13010cc57f5 100644 --- a/tests/check_framework/models.py +++ b/tests/check_framework/models.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.core.checks import register from django.db import models diff --git a/tests/check_framework/tests.py b/tests/check_framework/tests.py index a64ef206ad2b..0e82c10b456d 100644 --- a/tests/check_framework/tests.py +++ b/tests/check_framework/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import sys from django.apps import apps diff --git a/tests/conditional_processing/tests.py b/tests/conditional_processing/tests.py index e4af9447e02d..fd0b10cef412 100644 --- a/tests/conditional_processing/tests.py +++ b/tests/conditional_processing/tests.py @@ -1,6 +1,3 @@ -# -*- coding:utf-8 -*- -from __future__ import unicode_literals - from datetime import datetime from django.test import SimpleTestCase, override_settings diff --git a/tests/contenttypes_tests/models.py b/tests/contenttypes_tests/models.py index fe1854e8a38f..1640ee3b8cc4 100644 --- a/tests/contenttypes_tests/models.py +++ b/tests/contenttypes_tests/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.contenttypes.fields import ( GenericForeignKey, GenericRelation, ) diff --git a/tests/contenttypes_tests/operations_migrations/0001_initial.py b/tests/contenttypes_tests/operations_migrations/0001_initial.py index f08a6a81867f..9d4311752950 100644 --- a/tests/contenttypes_tests/operations_migrations/0001_initial.py +++ b/tests/contenttypes_tests/operations_migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/contenttypes_tests/operations_migrations/0002_rename_foo.py b/tests/contenttypes_tests/operations_migrations/0002_rename_foo.py index 34c8cd8a80dd..3a1527dc03e1 100644 --- a/tests/contenttypes_tests/operations_migrations/0002_rename_foo.py +++ b/tests/contenttypes_tests/operations_migrations/0002_rename_foo.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/contenttypes_tests/test_models.py b/tests/contenttypes_tests/test_models.py index a51a343c839b..bb0f8c890f24 100644 --- a/tests/contenttypes_tests/test_models.py +++ b/tests/contenttypes_tests/test_models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.contenttypes.models import ContentType, ContentTypeManager from django.contrib.contenttypes.views import shortcut from django.contrib.sites.shortcuts import get_current_site diff --git a/tests/contenttypes_tests/tests.py b/tests/contenttypes_tests/tests.py index 95ec5e5e2b4d..a46c9f336578 100644 --- a/tests/contenttypes_tests/tests.py +++ b/tests/contenttypes_tests/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime from django.apps.registry import Apps, apps diff --git a/tests/contenttypes_tests/urls.py b/tests/contenttypes_tests/urls.py index 285a5a206850..779e8c4a6038 100644 --- a/tests/contenttypes_tests/urls.py +++ b/tests/contenttypes_tests/urls.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.conf.urls import url from django.contrib.contenttypes import views diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py index 4480f5348e3f..33f30a83537f 100644 --- a/tests/csrf_tests/tests.py +++ b/tests/csrf_tests/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import logging import re import warnings diff --git a/tests/csrf_tests/views.py b/tests/csrf_tests/views.py index e41f2d080511..d436ae6f7368 100644 --- a/tests/csrf_tests/views.py +++ b/tests/csrf_tests/views.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.http import HttpResponse from django.template import RequestContext, Template from django.template.context_processors import csrf diff --git a/tests/custom_columns/models.py b/tests/custom_columns/models.py index 3f619a7f0419..d5f5217ba5a9 100644 --- a/tests/custom_columns/models.py +++ b/tests/custom_columns/models.py @@ -15,8 +15,6 @@ """ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/custom_columns/tests.py b/tests/custom_columns/tests.py index 7102e4fdbe13..04aca1291479 100644 --- a/tests/custom_columns/tests.py +++ b/tests/custom_columns/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.exceptions import FieldError from django.test import TestCase from django.utils import six diff --git a/tests/custom_lookups/tests.py b/tests/custom_lookups/tests.py index 8ae94dda2612..e66a280e167b 100644 --- a/tests/custom_lookups/tests.py +++ b/tests/custom_lookups/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import contextlib import time import unittest diff --git a/tests/custom_managers/models.py b/tests/custom_managers/models.py index 51773b18b82e..1d47869af9f6 100644 --- a/tests/custom_managers/models.py +++ b/tests/custom_managers/models.py @@ -9,8 +9,6 @@ returns. """ -from __future__ import unicode_literals - from django.contrib.contenttypes.fields import ( GenericForeignKey, GenericRelation, ) diff --git a/tests/custom_managers/tests.py b/tests/custom_managers/tests.py index 3daaeab131f8..1bfaf5276621 100644 --- a/tests/custom_managers/tests.py +++ b/tests/custom_managers/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models from django.test import TestCase from django.utils import six diff --git a/tests/custom_methods/tests.py b/tests/custom_methods/tests.py index 9186a41794b3..bbcec1f9f23b 100644 --- a/tests/custom_methods/tests.py +++ b/tests/custom_methods/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import date from django.test import TestCase diff --git a/tests/custom_pk/models.py b/tests/custom_pk/models.py index 20b484c426ab..e0a318468c43 100644 --- a/tests/custom_pk/models.py +++ b/tests/custom_pk/models.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Using a custom primary key @@ -6,8 +5,6 @@ this behavior by explicitly adding ``primary_key=True`` to a field. """ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/custom_pk/tests.py b/tests/custom_pk/tests.py index fdcbd80e046d..01150a46d272 100644 --- a/tests/custom_pk/tests.py +++ b/tests/custom_pk/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import IntegrityError, transaction from django.test import TestCase, skipIfDBFeature from django.utils import six diff --git a/tests/datatypes/tests.py b/tests/datatypes/tests.py index f45c429ef231..b6899c7609cc 100644 --- a/tests/datatypes/tests.py +++ b/tests/datatypes/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from django.test import TestCase, skipIfDBFeature diff --git a/tests/dates/models.py b/tests/dates/models.py index 2161b2b356f7..978cf44e955f 100644 --- a/tests/dates/models.py +++ b/tests/dates/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models from django.utils import timezone from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/dates/tests.py b/tests/dates/tests.py index 503d921ee135..9cb77fe9e202 100644 --- a/tests/dates/tests.py +++ b/tests/dates/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from unittest import skipUnless diff --git a/tests/datetimes/models.py b/tests/datetimes/models.py index 2fcb72be0912..4d2ad9ac7add 100644 --- a/tests/datetimes/models.py +++ b/tests/datetimes/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/datetimes/tests.py b/tests/datetimes/tests.py index 273333e61cd8..50a83f0371fb 100644 --- a/tests/datetimes/tests.py +++ b/tests/datetimes/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from django.test import TestCase, override_settings diff --git a/tests/db_functions/models.py b/tests/db_functions/models.py index 7494680c233f..8d0fbc6debcf 100644 --- a/tests/db_functions/models.py +++ b/tests/db_functions/models.py @@ -1,8 +1,6 @@ """ Tests for built in Function expressions. """ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/db_functions/test_datetime.py b/tests/db_functions/test_datetime.py index c0e98a13a9e5..f517b2f699ea 100644 --- a/tests/db_functions/test_datetime.py +++ b/tests/db_functions/test_datetime.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import datetime import pytz diff --git a/tests/db_functions/tests.py b/tests/db_functions/tests.py index 26acc687ea6f..c86e8eb43fcb 100644 --- a/tests/db_functions/tests.py +++ b/tests/db_functions/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import datetime, timedelta from unittest import skipIf, skipUnless diff --git a/tests/dbshell/test_postgresql_psycopg2.py b/tests/dbshell/test_postgresql_psycopg2.py index c75db4b188b7..4c4a1ae25e27 100644 --- a/tests/dbshell/test_postgresql_psycopg2.py +++ b/tests/dbshell/test_postgresql_psycopg2.py @@ -1,6 +1,3 @@ -# -*- coding: utf8 -*- -from __future__ import unicode_literals - import locale import os diff --git a/tests/defer/tests.py b/tests/defer/tests.py index 65f1f2bb15b4..0eea9545dd34 100644 --- a/tests/defer/tests.py +++ b/tests/defer/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db.models.query_utils import InvalidQuery from django.test import TestCase diff --git a/tests/defer_regress/tests.py b/tests/defer_regress/tests.py index 611b22be6866..314584abb4f8 100644 --- a/tests/defer_regress/tests.py +++ b/tests/defer_regress/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from operator import attrgetter from django.contrib.contenttypes.models import ContentType diff --git a/tests/delete/models.py b/tests/delete/models.py index 8a6f4903d6d4..4064173df481 100644 --- a/tests/delete/models.py +++ b/tests/delete/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/delete/tests.py b/tests/delete/tests.py index f8203b2780cd..640dfabf4b5d 100644 --- a/tests/delete/tests.py +++ b/tests/delete/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from math import ceil from django.db import IntegrityError, connection, models diff --git a/tests/delete_regress/tests.py b/tests/delete_regress/tests.py index 2128733798d6..7472731e9436 100644 --- a/tests/delete_regress/tests.py +++ b/tests/delete_regress/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from django.db import connection, models, transaction diff --git a/tests/deprecation/tests.py b/tests/deprecation/tests.py index 2ad3576676f1..34056b663b4f 100644 --- a/tests/deprecation/tests.py +++ b/tests/deprecation/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import warnings from django.test import SimpleTestCase diff --git a/tests/distinct_on_fields/models.py b/tests/distinct_on_fields/models.py index 2c33f3ad8037..a4164724f3e3 100644 --- a/tests/distinct_on_fields/models.py +++ b/tests/distinct_on_fields/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/distinct_on_fields/tests.py b/tests/distinct_on_fields/tests.py index e7445003ce92..e1365dab888d 100644 --- a/tests/distinct_on_fields/tests.py +++ b/tests/distinct_on_fields/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db.models import Max from django.test import TestCase, skipUnlessDBFeature from django.test.utils import str_prefix diff --git a/tests/expressions/models.py b/tests/expressions/models.py index 6dc956c8fe22..e2bfb8ef679d 100644 --- a/tests/expressions/models.py +++ b/tests/expressions/models.py @@ -2,8 +2,6 @@ Tests for F() query expression syntax. """ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/expressions/test_queryset_values.py b/tests/expressions/test_queryset_values.py index f9d35b4385e8..e26459796807 100644 --- a/tests/expressions/test_queryset_values.py +++ b/tests/expressions/test_queryset_values.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db.models.aggregates import Sum from django.db.models.expressions import F from django.test import TestCase diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index 8399e3c0a92c..d3eabb6dbb73 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import unittest import uuid diff --git a/tests/expressions_case/models.py b/tests/expressions_case/models.py index 9f559a4f9d9c..8c2eaac3996d 100644 --- a/tests/expressions_case/models.py +++ b/tests/expressions_case/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/expressions_case/tests.py b/tests/expressions_case/tests.py index 4617bcacb8c1..414c4353a527 100644 --- a/tests/expressions_case/tests.py +++ b/tests/expressions_case/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import unittest from datetime import date, datetime, time, timedelta from decimal import Decimal diff --git a/tests/extra_regress/models.py b/tests/extra_regress/models.py index 893c32ddd673..b271d8701f2f 100644 --- a/tests/extra_regress/models.py +++ b/tests/extra_regress/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import copy import datetime diff --git a/tests/extra_regress/tests.py b/tests/extra_regress/tests.py index acafd8efde39..53106fa2493c 100644 --- a/tests/extra_regress/tests.py +++ b/tests/extra_regress/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from collections import OrderedDict diff --git a/tests/field_deconstruction/tests.py b/tests/field_deconstruction/tests.py index 1a6385dbf964..bb16f4d76e42 100644 --- a/tests/field_deconstruction/tests.py +++ b/tests/field_deconstruction/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.apps import apps from django.db import models from django.test import SimpleTestCase, override_settings diff --git a/tests/field_defaults/models.py b/tests/field_defaults/models.py index 4f062320115f..71129cb5c71e 100644 --- a/tests/field_defaults/models.py +++ b/tests/field_defaults/models.py @@ -1,4 +1,3 @@ -# coding: utf-8 """ Callable defaults diff --git a/tests/field_subclassing/fields.py b/tests/field_subclassing/fields.py index c2e4b50c763f..4eb170116f31 100644 --- a/tests/field_subclassing/fields.py +++ b/tests/field_subclassing/fields.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models diff --git a/tests/field_subclassing/tests.py b/tests/field_subclassing/tests.py index d291276c1fce..a1371cab4282 100644 --- a/tests/field_subclassing/tests.py +++ b/tests/field_subclassing/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import connection from django.test import SimpleTestCase diff --git a/tests/file_storage/tests.py b/tests/file_storage/tests.py index 7a8b104665e6..d02b6e2dbcc1 100644 --- a/tests/file_storage/tests.py +++ b/tests/file_storage/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import errno import os import shutil diff --git a/tests/file_uploads/tests.py b/tests/file_uploads/tests.py index 5f6a50250d54..769c06c9044a 100644 --- a/tests/file_uploads/tests.py +++ b/tests/file_uploads/tests.py @@ -1,6 +1,3 @@ -#! -*- coding: utf-8 -*- -from __future__ import unicode_literals - import base64 import errno import hashlib diff --git a/tests/file_uploads/views.py b/tests/file_uploads/views.py index 17d4a1b0f439..bba71b87c272 100644 --- a/tests/file_uploads/views.py +++ b/tests/file_uploads/views.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import contextlib import hashlib import json diff --git a/tests/files/tests.py b/tests/files/tests.py index 72a121fcfecb..276cbed54483 100644 --- a/tests/files/tests.py +++ b/tests/files/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import gzip import os import struct diff --git a/tests/fixtures/tests.py b/tests/fixtures/tests.py index ff85a9b7529b..df5067e2231c 100644 --- a/tests/fixtures/tests.py +++ b/tests/fixtures/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os import sys import tempfile diff --git a/tests/fixtures_model_package/tests.py b/tests/fixtures_model_package/tests.py index 6b508a199122..d26a81e3be5e 100644 --- a/tests/fixtures_model_package/tests.py +++ b/tests/fixtures_model_package/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core import management from django.core.management import CommandError from django.test import TestCase diff --git a/tests/fixtures_regress/models.py b/tests/fixtures_regress/models.py index 084b602b7c1a..63e883f7d541 100644 --- a/tests/fixtures_regress/models.py +++ b/tests/fixtures_regress/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.auth.models import User from django.db import models from django.utils import six diff --git a/tests/fixtures_regress/tests.py b/tests/fixtures_regress/tests.py index 657ea13b3671..3667fcbd4c69 100644 --- a/tests/fixtures_regress/tests.py +++ b/tests/fixtures_regress/tests.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Unittests for fixtures. -from __future__ import unicode_literals - import json import os import re diff --git a/tests/flatpages_tests/test_forms.py b/tests/flatpages_tests/test_forms.py index 100669be5985..228790a4485e 100644 --- a/tests/flatpages_tests/test_forms.py +++ b/tests/flatpages_tests/test_forms.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.conf import settings from django.contrib.flatpages.forms import FlatpageForm from django.contrib.flatpages.models import FlatPage diff --git a/tests/flatpages_tests/test_models.py b/tests/flatpages_tests/test_models.py index ccb73c799e19..19d61cfff777 100644 --- a/tests/flatpages_tests/test_models.py +++ b/tests/flatpages_tests/test_models.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - from django.contrib.flatpages.models import FlatPage from django.test import SimpleTestCase from django.test.utils import override_script_prefix diff --git a/tests/flatpages_tests/test_sitemaps.py b/tests/flatpages_tests/test_sitemaps.py index 5be4fe518a2b..10076798c0d8 100644 --- a/tests/flatpages_tests/test_sitemaps.py +++ b/tests/flatpages_tests/test_sitemaps.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.apps import apps from django.contrib.sites.models import Site from django.test import TestCase diff --git a/tests/force_insert_update/tests.py b/tests/force_insert_update/tests.py index ae8b771ed1f6..2232283cb8a9 100644 --- a/tests/force_insert_update/tests.py +++ b/tests/force_insert_update/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import DatabaseError, IntegrityError, transaction from django.test import TestCase diff --git a/tests/forms_tests/field_tests/test_booleanfield.py b/tests/forms_tests/field_tests/test_booleanfield.py index e267777b9438..d2ed9d79559c 100644 --- a/tests/forms_tests/field_tests/test_booleanfield.py +++ b/tests/forms_tests/field_tests/test_booleanfield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import pickle from django.forms import BooleanField, ValidationError diff --git a/tests/forms_tests/field_tests/test_charfield.py b/tests/forms_tests/field_tests/test_charfield.py index d8fa41b0739c..a59291e33a8e 100644 --- a/tests/forms_tests/field_tests/test_charfield.py +++ b/tests/forms_tests/field_tests/test_charfield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.forms import ( CharField, HiddenInput, PasswordInput, Textarea, TextInput, ValidationError, diff --git a/tests/forms_tests/field_tests/test_choicefield.py b/tests/forms_tests/field_tests/test_choicefield.py index 1d8fe5a3cfb0..f500c1868098 100644 --- a/tests/forms_tests/field_tests/test_choicefield.py +++ b/tests/forms_tests/field_tests/test_choicefield.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.forms import ChoiceField, Form, ValidationError from django.test import SimpleTestCase, ignore_warnings diff --git a/tests/forms_tests/field_tests/test_combofield.py b/tests/forms_tests/field_tests/test_combofield.py index 6ca91233bc8b..b40e7ba88587 100644 --- a/tests/forms_tests/field_tests/test_combofield.py +++ b/tests/forms_tests/field_tests/test_combofield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.forms import CharField, ComboField, EmailField, ValidationError from django.test import SimpleTestCase diff --git a/tests/forms_tests/field_tests/test_datefield.py b/tests/forms_tests/field_tests/test_datefield.py index b23b5a42ce34..77573e8dcfeb 100644 --- a/tests/forms_tests/field_tests/test_datefield.py +++ b/tests/forms_tests/field_tests/test_datefield.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from datetime import date, datetime from django.forms import ( diff --git a/tests/forms_tests/field_tests/test_datetimefield.py b/tests/forms_tests/field_tests/test_datetimefield.py index f83b9b7f7657..a1cfd220534c 100644 --- a/tests/forms_tests/field_tests/test_datetimefield.py +++ b/tests/forms_tests/field_tests/test_datetimefield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from django.forms import DateTimeField, ValidationError diff --git a/tests/forms_tests/field_tests/test_decimalfield.py b/tests/forms_tests/field_tests/test_decimalfield.py index 02600bcb5b47..c8fd95fd6848 100644 --- a/tests/forms_tests/field_tests/test_decimalfield.py +++ b/tests/forms_tests/field_tests/test_decimalfield.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import decimal from django.forms import DecimalField, NumberInput, ValidationError, Widget diff --git a/tests/forms_tests/field_tests/test_durationfield.py b/tests/forms_tests/field_tests/test_durationfield.py index 28fd245a7972..ce578ff82ff1 100644 --- a/tests/forms_tests/field_tests/test_durationfield.py +++ b/tests/forms_tests/field_tests/test_durationfield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from django.forms import DurationField diff --git a/tests/forms_tests/field_tests/test_emailfield.py b/tests/forms_tests/field_tests/test_emailfield.py index 906a6cf5ffd3..15481689b0ef 100644 --- a/tests/forms_tests/field_tests/test_emailfield.py +++ b/tests/forms_tests/field_tests/test_emailfield.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.forms import EmailField, ValidationError from django.test import SimpleTestCase diff --git a/tests/forms_tests/field_tests/test_filefield.py b/tests/forms_tests/field_tests/test_filefield.py index 2c08075f3f30..1862475a5a84 100644 --- a/tests/forms_tests/field_tests/test_filefield.py +++ b/tests/forms_tests/field_tests/test_filefield.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import pickle from django.core.files.uploadedfile import SimpleUploadedFile diff --git a/tests/forms_tests/field_tests/test_filepathfield.py b/tests/forms_tests/field_tests/test_filepathfield.py index 60336d0dcf1c..07ebe67f06ca 100644 --- a/tests/forms_tests/field_tests/test_filepathfield.py +++ b/tests/forms_tests/field_tests/test_filepathfield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os.path from django.forms import FilePathField, ValidationError, forms diff --git a/tests/forms_tests/field_tests/test_floatfield.py b/tests/forms_tests/field_tests/test_floatfield.py index d4ef4f496b9d..83209d7c6688 100644 --- a/tests/forms_tests/field_tests/test_floatfield.py +++ b/tests/forms_tests/field_tests/test_floatfield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.forms import FloatField, NumberInput, ValidationError from django.test import SimpleTestCase from django.utils import formats, translation diff --git a/tests/forms_tests/field_tests/test_genericipaddressfield.py b/tests/forms_tests/field_tests/test_genericipaddressfield.py index 011630fb0d08..97a83e38aedd 100644 --- a/tests/forms_tests/field_tests/test_genericipaddressfield.py +++ b/tests/forms_tests/field_tests/test_genericipaddressfield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.forms import GenericIPAddressField, ValidationError from django.test import SimpleTestCase diff --git a/tests/forms_tests/field_tests/test_imagefield.py b/tests/forms_tests/field_tests/test_imagefield.py index ee0e1e3b7397..326735bf60d2 100644 --- a/tests/forms_tests/field_tests/test_imagefield.py +++ b/tests/forms_tests/field_tests/test_imagefield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os import unittest diff --git a/tests/forms_tests/field_tests/test_integerfield.py b/tests/forms_tests/field_tests/test_integerfield.py index cd648279a660..f89885027b6e 100644 --- a/tests/forms_tests/field_tests/test_integerfield.py +++ b/tests/forms_tests/field_tests/test_integerfield.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.forms import IntegerField, Textarea, ValidationError from django.test import SimpleTestCase diff --git a/tests/forms_tests/field_tests/test_multiplechoicefield.py b/tests/forms_tests/field_tests/test_multiplechoicefield.py index 85b70498546d..dee916bd8eb0 100644 --- a/tests/forms_tests/field_tests/test_multiplechoicefield.py +++ b/tests/forms_tests/field_tests/test_multiplechoicefield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.forms import MultipleChoiceField, ValidationError from django.test import SimpleTestCase diff --git a/tests/forms_tests/field_tests/test_nullbooleanfield.py b/tests/forms_tests/field_tests/test_nullbooleanfield.py index ff4a16060e88..ff57394f07cb 100644 --- a/tests/forms_tests/field_tests/test_nullbooleanfield.py +++ b/tests/forms_tests/field_tests/test_nullbooleanfield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.forms import Form, HiddenInput, NullBooleanField, RadioSelect from django.test import SimpleTestCase diff --git a/tests/forms_tests/field_tests/test_regexfield.py b/tests/forms_tests/field_tests/test_regexfield.py index 02a627b8d266..bd8d6dda097b 100644 --- a/tests/forms_tests/field_tests/test_regexfield.py +++ b/tests/forms_tests/field_tests/test_regexfield.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import re from django.forms import RegexField, ValidationError diff --git a/tests/forms_tests/field_tests/test_slugfield.py b/tests/forms_tests/field_tests/test_slugfield.py index 1a522c9d4f3a..d883f7f5c950 100644 --- a/tests/forms_tests/field_tests/test_slugfield.py +++ b/tests/forms_tests/field_tests/test_slugfield.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.forms import SlugField from django.test import SimpleTestCase diff --git a/tests/forms_tests/field_tests/test_splitdatetimefield.py b/tests/forms_tests/field_tests/test_splitdatetimefield.py index db8df414414b..be70edd3d4de 100644 --- a/tests/forms_tests/field_tests/test_splitdatetimefield.py +++ b/tests/forms_tests/field_tests/test_splitdatetimefield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from django.forms import SplitDateTimeField, ValidationError diff --git a/tests/forms_tests/field_tests/test_timefield.py b/tests/forms_tests/field_tests/test_timefield.py index 3c73cc37b663..bd8a67992fd9 100644 --- a/tests/forms_tests/field_tests/test_timefield.py +++ b/tests/forms_tests/field_tests/test_timefield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from django.forms import TimeField, ValidationError diff --git a/tests/forms_tests/field_tests/test_typedchoicefield.py b/tests/forms_tests/field_tests/test_typedchoicefield.py index 26a7a25d0558..c08a8bb6110c 100644 --- a/tests/forms_tests/field_tests/test_typedchoicefield.py +++ b/tests/forms_tests/field_tests/test_typedchoicefield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import decimal from django.forms import TypedChoiceField, ValidationError diff --git a/tests/forms_tests/field_tests/test_typedmultiplechoicefield.py b/tests/forms_tests/field_tests/test_typedmultiplechoicefield.py index 94823e0594dd..b33d26bdaaec 100644 --- a/tests/forms_tests/field_tests/test_typedmultiplechoicefield.py +++ b/tests/forms_tests/field_tests/test_typedmultiplechoicefield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import decimal from django.forms import TypedMultipleChoiceField, ValidationError diff --git a/tests/forms_tests/field_tests/test_urlfield.py b/tests/forms_tests/field_tests/test_urlfield.py index d0b6d004822d..715e8e99e0d7 100644 --- a/tests/forms_tests/field_tests/test_urlfield.py +++ b/tests/forms_tests/field_tests/test_urlfield.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.forms import URLField, ValidationError from django.test import SimpleTestCase diff --git a/tests/forms_tests/field_tests/test_uuidfield.py b/tests/forms_tests/field_tests/test_uuidfield.py index fe432e072564..08498ab9c9e3 100644 --- a/tests/forms_tests/field_tests/test_uuidfield.py +++ b/tests/forms_tests/field_tests/test_uuidfield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import uuid from django.forms import UUIDField, ValidationError diff --git a/tests/forms_tests/models.py b/tests/forms_tests/models.py index cf770abb023d..be1b66bce664 100644 --- a/tests/forms_tests/models.py +++ b/tests/forms_tests/models.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime import itertools import tempfile diff --git a/tests/forms_tests/tests/test_error_messages.py b/tests/forms_tests/tests/test_error_messages.py index 4ae550efc25f..eb7debf936ba 100644 --- a/tests/forms_tests/tests/test_error_messages.py +++ b/tests/forms_tests/tests/test_error_messages.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.core.files.uploadedfile import SimpleUploadedFile from django.forms import ( BooleanField, CharField, ChoiceField, DateField, DateTimeField, diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py index 2b93575bf27f..b8ced2425c23 100644 --- a/tests/forms_tests/tests/test_forms.py +++ b/tests/forms_tests/tests/test_forms.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import copy import datetime import json diff --git a/tests/forms_tests/tests/test_formsets.py b/tests/forms_tests/tests/test_formsets.py index 29f0befc18df..125ed273e969 100644 --- a/tests/forms_tests/tests/test_formsets.py +++ b/tests/forms_tests/tests/test_formsets.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime from collections import Counter diff --git a/tests/forms_tests/tests/test_i18n.py b/tests/forms_tests/tests/test_i18n.py index 56225e0dd567..a8a2cf384678 100644 --- a/tests/forms_tests/tests/test_i18n.py +++ b/tests/forms_tests/tests/test_i18n.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.forms import ( CharField, ChoiceField, Form, IntegerField, RadioSelect, Select, TextInput, ) diff --git a/tests/forms_tests/tests/test_media.py b/tests/forms_tests/tests/test_media.py index d0d226d06e94..cd5cc1f8049a 100644 --- a/tests/forms_tests/tests/test_media.py +++ b/tests/forms_tests/tests/test_media.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from django.forms import CharField, Form, Media, MultiWidget, TextInput from django.template import Context, Template from django.test import SimpleTestCase, override_settings diff --git a/tests/forms_tests/tests/test_utils.py b/tests/forms_tests/tests/test_utils.py index f95c95632222..d0dfaad3703d 100644 --- a/tests/forms_tests/tests/test_utils.py +++ b/tests/forms_tests/tests/test_utils.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import copy from django.core.exceptions import ValidationError diff --git a/tests/forms_tests/tests/test_validators.py b/tests/forms_tests/tests/test_validators.py index 19d0d91fd5e2..c5e1f1e980dc 100644 --- a/tests/forms_tests/tests/test_validators.py +++ b/tests/forms_tests/tests/test_validators.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import re from unittest import TestCase diff --git a/tests/forms_tests/tests/test_widgets.py b/tests/forms_tests/tests/test_widgets.py index f67954fd3a5f..3e137532b97a 100644 --- a/tests/forms_tests/tests/test_widgets.py +++ b/tests/forms_tests/tests/test_widgets.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.admin.tests import AdminSeleniumTestCase from django.test import override_settings from django.urls import reverse diff --git a/tests/forms_tests/tests/tests.py b/tests/forms_tests/tests/tests.py index f0007fbe8f64..025b74976213 100644 --- a/tests/forms_tests/tests/tests.py +++ b/tests/forms_tests/tests/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime from django.core.files.uploadedfile import SimpleUploadedFile diff --git a/tests/forms_tests/widget_tests/test_select.py b/tests/forms_tests/widget_tests/test_select.py index d2660ea787d7..23d6126810e9 100644 --- a/tests/forms_tests/widget_tests/test_select.py +++ b/tests/forms_tests/widget_tests/test_select.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import copy from django.forms import Select diff --git a/tests/forms_tests/widget_tests/test_textinput.py b/tests/forms_tests/widget_tests/test_textinput.py index 65b5da4e0366..906687d97130 100644 --- a/tests/forms_tests/widget_tests/test_textinput.py +++ b/tests/forms_tests/widget_tests/test_textinput.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.forms import TextInput from django.utils.safestring import mark_safe diff --git a/tests/forms_tests/widget_tests/test_widget.py b/tests/forms_tests/widget_tests/test_widget.py index 595748a7b221..368c315be797 100644 --- a/tests/forms_tests/widget_tests/test_widget.py +++ b/tests/forms_tests/widget_tests/test_widget.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.forms import Widget from django.forms.widgets import Input diff --git a/tests/generic_inline_admin/tests.py b/tests/generic_inline_admin/tests.py index a25294beda21..203d9d7f3e84 100644 --- a/tests/generic_inline_admin/tests.py +++ b/tests/generic_inline_admin/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.contrib import admin from django.contrib.admin.sites import AdminSite from django.contrib.auth.models import User diff --git a/tests/generic_relations/models.py b/tests/generic_relations/models.py index 7522f5b4cd89..f1748b743326 100644 --- a/tests/generic_relations/models.py +++ b/tests/generic_relations/models.py @@ -9,8 +9,6 @@ from complete). """ -from __future__ import unicode_literals - from django.contrib.contenttypes.fields import ( GenericForeignKey, GenericRelation, ) diff --git a/tests/generic_relations/tests.py b/tests/generic_relations/tests.py index 540c3456f200..5bfea72cf1dc 100644 --- a/tests/generic_relations/tests.py +++ b/tests/generic_relations/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django import forms from django.contrib.contenttypes.forms import generic_inlineformset_factory from django.contrib.contenttypes.models import ContentType diff --git a/tests/generic_views/forms.py b/tests/generic_views/forms.py index 1ee26afc8fcf..fd8106d1a89d 100644 --- a/tests/generic_views/forms.py +++ b/tests/generic_views/forms.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django import forms from .models import Author diff --git a/tests/generic_views/test_base.py b/tests/generic_views/test_base.py index a667a4e49522..be89592dbc0d 100644 --- a/tests/generic_views/test_base.py +++ b/tests/generic_views/test_base.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import time import unittest diff --git a/tests/generic_views/test_dates.py b/tests/generic_views/test_dates.py index 9b7c20ec7386..d18c8189890c 100644 --- a/tests/generic_views/test_dates.py +++ b/tests/generic_views/test_dates.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime from django.core.exceptions import ImproperlyConfigured diff --git a/tests/generic_views/test_detail.py b/tests/generic_views/test_detail.py index 4c91f6eeb0c9..da20db066e26 100644 --- a/tests/generic_views/test_detail.py +++ b/tests/generic_views/test_detail.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist diff --git a/tests/generic_views/test_edit.py b/tests/generic_views/test_edit.py index c1b9eba9d89b..3a68fc409804 100644 --- a/tests/generic_views/test_edit.py +++ b/tests/generic_views/test_edit.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django import forms from django.core.exceptions import ImproperlyConfigured from django.test import SimpleTestCase, TestCase, override_settings diff --git a/tests/generic_views/test_list.py b/tests/generic_views/test_list.py index 5a22abd33b33..d5851d4ff809 100644 --- a/tests/generic_views/test_list.py +++ b/tests/generic_views/test_list.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime from django.core.exceptions import ImproperlyConfigured diff --git a/tests/generic_views/urls.py b/tests/generic_views/urls.py index 9f2d8429fc84..3475bfc3579e 100644 --- a/tests/generic_views/urls.py +++ b/tests/generic_views/urls.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.conf.urls import url from django.contrib.auth import views as auth_views from django.contrib.auth.decorators import login_required diff --git a/tests/generic_views/views.py b/tests/generic_views/views.py index e46bc091434d..b466f3a324ea 100644 --- a/tests/generic_views/views.py +++ b/tests/generic_views/views.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.auth.decorators import login_required from django.core.paginator import Paginator from django.urls import reverse, reverse_lazy diff --git a/tests/get_earliest_or_latest/tests.py b/tests/get_earliest_or_latest/tests.py index 56d48d071015..2322e0a91cbf 100644 --- a/tests/get_earliest_or_latest/tests.py +++ b/tests/get_earliest_or_latest/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import datetime from django.test import TestCase diff --git a/tests/get_object_or_404/tests.py b/tests/get_object_or_404/tests.py index bf10ea310972..b5a233568d9c 100644 --- a/tests/get_object_or_404/tests.py +++ b/tests/get_object_or_404/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.http import Http404 from django.shortcuts import get_list_or_404, get_object_or_404 from django.test import TestCase diff --git a/tests/get_or_create/models.py b/tests/get_or_create/models.py index 03944344081a..5d6e69de3a71 100644 --- a/tests/get_or_create/models.py +++ b/tests/get_or_create/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/get_or_create/tests.py b/tests/get_or_create/tests.py index d727bdee5d48..27a0cb77377f 100644 --- a/tests/get_or_create/tests.py +++ b/tests/get_or_create/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import time import traceback from datetime import date, datetime, timedelta diff --git a/tests/gis_tests/distapp/tests.py b/tests/gis_tests/distapp/tests.py index 01f0a620dc16..9d67b7b01398 100644 --- a/tests/gis_tests/distapp/tests.py +++ b/tests/gis_tests/distapp/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.gis.db.models.functions import ( Area, Distance, Length, Perimeter, Transform, ) diff --git a/tests/gis_tests/gdal_tests/test_srs.py b/tests/gis_tests/gdal_tests/test_srs.py index d03d8dcfd3e9..9bc6c0a2c5c5 100644 --- a/tests/gis_tests/gdal_tests/test_srs.py +++ b/tests/gis_tests/gdal_tests/test_srs.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import unittest from unittest import skipUnless diff --git a/tests/gis_tests/geo3d/tests.py b/tests/gis_tests/geo3d/tests.py index 946928b91936..e32611934a5a 100644 --- a/tests/gis_tests/geo3d/tests.py +++ b/tests/gis_tests/geo3d/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os import re diff --git a/tests/gis_tests/geoadmin/tests.py b/tests/gis_tests/geoadmin/tests.py index 88c39340209d..23fa8071b36c 100644 --- a/tests/gis_tests/geoadmin/tests.py +++ b/tests/gis_tests/geoadmin/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.gis import admin from django.contrib.gis.geos import Point from django.test import TestCase, override_settings, skipUnlessDBFeature diff --git a/tests/gis_tests/geoapp/feeds.py b/tests/gis_tests/geoapp/feeds.py index 4a0ec7647dee..185f3b56e374 100644 --- a/tests/gis_tests/geoapp/feeds.py +++ b/tests/gis_tests/geoapp/feeds.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.gis import feeds from .models import City diff --git a/tests/gis_tests/geoapp/test_feeds.py b/tests/gis_tests/geoapp/test_feeds.py index 09745547376a..c8fd32802f1d 100644 --- a/tests/gis_tests/geoapp/test_feeds.py +++ b/tests/gis_tests/geoapp/test_feeds.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from xml.dom import minidom from django.conf import settings diff --git a/tests/gis_tests/geoapp/test_functions.py b/tests/gis_tests/geoapp/test_functions.py index e551de6890b2..2767b7974b71 100644 --- a/tests/gis_tests/geoapp/test_functions.py +++ b/tests/gis_tests/geoapp/test_functions.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import re from decimal import Decimal diff --git a/tests/gis_tests/geoapp/test_regress.py b/tests/gis_tests/geoapp/test_regress.py index a075d447efa6..2d62349dbb7f 100644 --- a/tests/gis_tests/geoapp/test_regress.py +++ b/tests/gis_tests/geoapp/test_regress.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - from datetime import datetime from django.contrib.gis.db.models import Extent diff --git a/tests/gis_tests/geoapp/test_serializers.py b/tests/gis_tests/geoapp/test_serializers.py index f82edfa53e44..7f756e154476 100644 --- a/tests/gis_tests/geoapp/test_serializers.py +++ b/tests/gis_tests/geoapp/test_serializers.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import json from django.contrib.gis.geos import LinearRing, Point, Polygon diff --git a/tests/gis_tests/geoapp/test_sitemaps.py b/tests/gis_tests/geoapp/test_sitemaps.py index e17a48a62448..61e06df7285d 100644 --- a/tests/gis_tests/geoapp/test_sitemaps.py +++ b/tests/gis_tests/geoapp/test_sitemaps.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import zipfile from io import BytesIO from xml.dom import minidom diff --git a/tests/gis_tests/geoapp/tests.py b/tests/gis_tests/geoapp/tests.py index cbbf0357bc92..4324364c0da9 100644 --- a/tests/gis_tests/geoapp/tests.py +++ b/tests/gis_tests/geoapp/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import tempfile from django.contrib.gis import gdal diff --git a/tests/gis_tests/geoapp/urls.py b/tests/gis_tests/geoapp/urls.py index 40a48053c723..0e148bf4f38f 100644 --- a/tests/gis_tests/geoapp/urls.py +++ b/tests/gis_tests/geoapp/urls.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.conf.urls import url from django.contrib.gis import views as gis_views from django.contrib.gis.sitemaps import views as gis_sitemap_views diff --git a/tests/gis_tests/geogapp/tests.py b/tests/gis_tests/geogapp/tests.py index d9f02184eade..7112f0238eb0 100644 --- a/tests/gis_tests/geogapp/tests.py +++ b/tests/gis_tests/geogapp/tests.py @@ -1,8 +1,6 @@ """ Tests for geography support in PostGIS """ -from __future__ import unicode_literals - import os from unittest import skipIf, skipUnless diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index 46583c9605ac..ff28eebf0f52 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import ctypes import json import random diff --git a/tests/gis_tests/geos_tests/test_io.py b/tests/gis_tests/geos_tests/test_io.py index 47995bf88c57..81e0ff357fc7 100644 --- a/tests/gis_tests/geos_tests/test_io.py +++ b/tests/gis_tests/geos_tests/test_io.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import binascii from unittest import skipUnless diff --git a/tests/gis_tests/gis_migrations/test_commands.py b/tests/gis_tests/gis_migrations/test_commands.py index 65bd035b8c24..c9bf3773feca 100644 --- a/tests/gis_tests/gis_migrations/test_commands.py +++ b/tests/gis_tests/gis_migrations/test_commands.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.management import call_command from django.db import connection from django.test import TransactionTestCase, skipUnlessDBFeature diff --git a/tests/gis_tests/gis_migrations/test_operations.py b/tests/gis_tests/gis_migrations/test_operations.py index 26ff16feedeb..0c8853a9f3c1 100644 --- a/tests/gis_tests/gis_migrations/test_operations.py +++ b/tests/gis_tests/gis_migrations/test_operations.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from unittest import skipIf from django.contrib.gis.db.models import fields diff --git a/tests/gis_tests/inspectapp/tests.py b/tests/gis_tests/inspectapp/tests.py index 75865997dc8a..b451603e7ce1 100644 --- a/tests/gis_tests/inspectapp/tests.py +++ b/tests/gis_tests/inspectapp/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os import re diff --git a/tests/gis_tests/layermap/tests.py b/tests/gis_tests/layermap/tests.py index a8a352eda504..0f59132b0db3 100644 --- a/tests/gis_tests/layermap/tests.py +++ b/tests/gis_tests/layermap/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import os import unittest from copy import copy diff --git a/tests/gis_tests/relatedapp/tests.py b/tests/gis_tests/relatedapp/tests.py index 861b6ee2d927..b8da0f24f1d2 100644 --- a/tests/gis_tests/relatedapp/tests.py +++ b/tests/gis_tests/relatedapp/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.gis.db.models import Collect, Count, Extent, F, Union from django.contrib.gis.geometry.backend import Geometry from django.contrib.gis.geos import GEOSGeometry, MultiPoint, Point diff --git a/tests/gis_tests/test_geoip2.py b/tests/gis_tests/test_geoip2.py index 7db1648cca55..54f20412a4f7 100644 --- a/tests/gis_tests/test_geoip2.py +++ b/tests/gis_tests/test_geoip2.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import os import unittest from unittest import skipUnless diff --git a/tests/handlers/tests.py b/tests/handlers/tests.py index a4209174211b..bae20439189c 100644 --- a/tests/handlers/tests.py +++ b/tests/handlers/tests.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import unittest from django.core.exceptions import ImproperlyConfigured diff --git a/tests/handlers/urls.py b/tests/handlers/urls.py index 9d23fd3fa7c5..1a228590931a 100644 --- a/tests/handlers/urls.py +++ b/tests/handlers/urls.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.conf.urls import url from . import views diff --git a/tests/handlers/views.py b/tests/handlers/views.py index 21c1387f0812..22b94de3b90e 100644 --- a/tests/handlers/views.py +++ b/tests/handlers/views.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.exceptions import SuspiciousOperation from django.db import connection, transaction from django.http import HttpResponse, StreamingHttpResponse diff --git a/tests/httpwrappers/tests.py b/tests/httpwrappers/tests.py index 3ab21751f517..d9885ea40ccd 100644 --- a/tests/httpwrappers/tests.py +++ b/tests/httpwrappers/tests.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - import copy import json import os diff --git a/tests/humanize_tests/tests.py b/tests/humanize_tests/tests.py index a3cc512239e4..90a5155cfb8a 100644 --- a/tests/humanize_tests/tests.py +++ b/tests/humanize_tests/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from decimal import Decimal diff --git a/tests/i18n/contenttypes/tests.py b/tests/i18n/contenttypes/tests.py index 890fa1156b85..2a14e25972ca 100644 --- a/tests/i18n/contenttypes/tests.py +++ b/tests/i18n/contenttypes/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import os from django.contrib.contenttypes.models import ContentType diff --git a/tests/i18n/patterns/tests.py b/tests/i18n/patterns/tests.py index 6706e32e8409..a889125e82b8 100644 --- a/tests/i18n/patterns/tests.py +++ b/tests/i18n/patterns/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os from django.conf import settings diff --git a/tests/i18n/test_compilation.py b/tests/i18n/test_compilation.py index b33338800a28..d17078e29011 100644 --- a/tests/i18n/test_compilation.py +++ b/tests/i18n/test_compilation.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import gettext as gettext_module import os import stat diff --git a/tests/i18n/test_extraction.py b/tests/i18n/test_extraction.py index 9311a1e7f075..33e136e1dd1c 100644 --- a/tests/i18n/test_extraction.py +++ b/tests/i18n/test_extraction.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - import io import os import re diff --git a/tests/i18n/test_percents.py b/tests/i18n/test_percents.py index 6e39b59a7f72..48d62ada05b1 100644 --- a/tests/i18n/test_percents.py +++ b/tests/i18n/test_percents.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - import os from django.template import Context, Template diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py index 6e2269da4c67..2b9793109b43 100644 --- a/tests/i18n/tests.py +++ b/tests/i18n/tests.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - import datetime import decimal import gettext as gettext_module diff --git a/tests/i18n/urls.py b/tests/i18n/urls.py index af2abb9fb847..911a1cf8e78e 100644 --- a/tests/i18n/urls.py +++ b/tests/i18n/urls.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.conf.urls import url from django.conf.urls.i18n import i18n_patterns from django.http import HttpResponse, StreamingHttpResponse diff --git a/tests/inline_formsets/models.py b/tests/inline_formsets/models.py index 70f9008d8bfb..42cf810f5349 100644 --- a/tests/inline_formsets/models.py +++ b/tests/inline_formsets/models.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/inline_formsets/tests.py b/tests/inline_formsets/tests.py index 6e96f51e6feb..0fb2fd2f026d 100644 --- a/tests/inline_formsets/tests.py +++ b/tests/inline_formsets/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.forms.models import ModelForm, inlineformset_factory from django.test import TestCase, skipUnlessDBFeature from django.utils import six diff --git a/tests/inspectdb/models.py b/tests/inspectdb/models.py index 868f3ba4fe92..668fc51aed35 100644 --- a/tests/inspectdb/models.py +++ b/tests/inspectdb/models.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - from django.db import models diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py index daa0800d7c68..1293ff68acda 100644 --- a/tests/inspectdb/tests.py +++ b/tests/inspectdb/tests.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - import re from unittest import skipUnless diff --git a/tests/introspection/models.py b/tests/introspection/models.py index b8c7a83b9f90..023e622beb8a 100644 --- a/tests/introspection/models.py +++ b/tests/introspection/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/introspection/tests.py b/tests/introspection/tests.py index 816c4a9b37ac..a85748d958c5 100644 --- a/tests/introspection/tests.py +++ b/tests/introspection/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from unittest import skipUnless from django.db import connection diff --git a/tests/invalid_models_tests/test_backend_specific.py b/tests/invalid_models_tests/test_backend_specific.py index 05ba04a4ea1c..6321b6d7be45 100644 --- a/tests/invalid_models_tests/test_backend_specific.py +++ b/tests/invalid_models_tests/test_backend_specific.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - from django.core.checks import Error from django.db import connections, models from django.test import SimpleTestCase, mock diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py index 662035af7542..7bb949769085 100644 --- a/tests/invalid_models_tests/test_models.py +++ b/tests/invalid_models_tests/test_models.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - import unittest from django.conf import settings diff --git a/tests/invalid_models_tests/test_ordinary_fields.py b/tests/invalid_models_tests/test_ordinary_fields.py index 3f601e1fcfc7..61f93e85788b 100644 --- a/tests/invalid_models_tests/test_ordinary_fields.py +++ b/tests/invalid_models_tests/test_ordinary_fields.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - import unittest from django.core.checks import Error, Warning as DjangoWarning diff --git a/tests/invalid_models_tests/test_relative_fields.py b/tests/invalid_models_tests/test_relative_fields.py index 2165e6dfb5e6..5fd76229e916 100644 --- a/tests/invalid_models_tests/test_relative_fields.py +++ b/tests/invalid_models_tests/test_relative_fields.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - from django.core.checks import Error, Warning as DjangoWarning from django.db import models from django.db.models.fields.related import ForeignObject diff --git a/tests/known_related_objects/tests.py b/tests/known_related_objects/tests.py index bb664a810246..c0afe4f0b915 100644 --- a/tests/known_related_objects/tests.py +++ b/tests/known_related_objects/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import TestCase from .models import Organiser, Pool, PoolStyle, Tournament diff --git a/tests/logging_tests/tests.py b/tests/logging_tests/tests.py index 0557ea182ba2..134cc7180884 100644 --- a/tests/logging_tests/tests.py +++ b/tests/logging_tests/tests.py @@ -1,6 +1,3 @@ -# -*- coding:utf-8 -*- -from __future__ import unicode_literals - import logging from contextlib import contextmanager diff --git a/tests/logging_tests/urls.py b/tests/logging_tests/urls.py index ca6dd9b430df..fa2c0fcd0261 100644 --- a/tests/logging_tests/urls.py +++ b/tests/logging_tests/urls.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.conf.urls import url from . import views diff --git a/tests/logging_tests/urls_i18n.py b/tests/logging_tests/urls_i18n.py index 80ce990413c2..220f5e4732e3 100644 --- a/tests/logging_tests/urls_i18n.py +++ b/tests/logging_tests/urls_i18n.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.conf.urls import url from django.conf.urls.i18n import i18n_patterns from django.http import HttpResponse diff --git a/tests/logging_tests/views.py b/tests/logging_tests/views.py index a36250970030..cb7112e43528 100644 --- a/tests/logging_tests/views.py +++ b/tests/logging_tests/views.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.exceptions import DisallowedHost, SuspiciousOperation from django.http import HttpResponse diff --git a/tests/lookup/models.py b/tests/lookup/models.py index cfc0cecb9953..3490422f69a0 100644 --- a/tests/lookup/models.py +++ b/tests/lookup/models.py @@ -4,8 +4,6 @@ This demonstrates features of the database API. """ -from __future__ import unicode_literals - from django.db import models from django.utils import six from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/lookup/test_timefield.py b/tests/lookup/test_timefield.py index 0a96992a32ee..6ef1d794e228 100644 --- a/tests/lookup/test_timefield.py +++ b/tests/lookup/test_timefield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import TestCase from .models import Alarm diff --git a/tests/lookup/tests.py b/tests/lookup/tests.py index 78e68dfc4a99..1da7084e4813 100644 --- a/tests/lookup/tests.py +++ b/tests/lookup/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import collections from datetime import datetime from operator import attrgetter diff --git a/tests/m2m_and_m2o/models.py b/tests/m2m_and_m2o/models.py index 60f5c43733c9..621c56ca1aea 100644 --- a/tests/m2m_and_m2o/models.py +++ b/tests/m2m_and_m2o/models.py @@ -3,8 +3,6 @@ Make sure to set ``related_name`` if you use relationships to the same table. """ -from __future__ import unicode_literals - from django.db import models from django.utils import six from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/m2m_intermediary/models.py b/tests/m2m_intermediary/models.py index 3e73164e6fcf..dbd822df513a 100644 --- a/tests/m2m_intermediary/models.py +++ b/tests/m2m_intermediary/models.py @@ -9,8 +9,6 @@ field, which specifies the ``Reporter``'s position for the given article (e.g. "Staff writer"). """ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/m2m_intermediary/tests.py b/tests/m2m_intermediary/tests.py index ce4e1860045d..d429bf6516f1 100644 --- a/tests/m2m_intermediary/tests.py +++ b/tests/m2m_intermediary/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import datetime from django.test import TestCase diff --git a/tests/m2m_multiple/tests.py b/tests/m2m_multiple/tests.py index 9d605423ad2f..1fa27677649f 100644 --- a/tests/m2m_multiple/tests.py +++ b/tests/m2m_multiple/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import datetime from django.test import TestCase diff --git a/tests/m2m_recursive/tests.py b/tests/m2m_recursive/tests.py index c6573800a810..b2667a8d52cc 100644 --- a/tests/m2m_recursive/tests.py +++ b/tests/m2m_recursive/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from operator import attrgetter from django.test import TestCase diff --git a/tests/m2m_regress/tests.py b/tests/m2m_regress/tests.py index 3c882c595aa8..6d4a4f02edbc 100644 --- a/tests/m2m_regress/tests.py +++ b/tests/m2m_regress/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.exceptions import FieldError from django.test import TestCase diff --git a/tests/m2m_through/tests.py b/tests/m2m_through/tests.py index 47cbbeecda52..089018870378 100644 --- a/tests/m2m_through/tests.py +++ b/tests/m2m_through/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import datetime from operator import attrgetter diff --git a/tests/m2m_through_regress/models.py b/tests/m2m_through_regress/models.py index adde24dcf9d3..9f0f44cd2132 100644 --- a/tests/m2m_through_regress/models.py +++ b/tests/m2m_through_regress/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.auth.models import User from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/m2m_through_regress/test_multitable.py b/tests/m2m_through_regress/test_multitable.py index f07af40f6ded..1ae76376fc10 100644 --- a/tests/m2m_through_regress/test_multitable.py +++ b/tests/m2m_through_regress/test_multitable.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import TestCase from .models import ( diff --git a/tests/m2m_through_regress/tests.py b/tests/m2m_through_regress/tests.py index ca47830290f0..a1739f296023 100644 --- a/tests/m2m_through_regress/tests.py +++ b/tests/m2m_through_regress/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.auth.models import User from django.core import management from django.test import TestCase diff --git a/tests/m2o_recursive/tests.py b/tests/m2o_recursive/tests.py index 8e730d48a701..0f7ee9071d48 100644 --- a/tests/m2o_recursive/tests.py +++ b/tests/m2o_recursive/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import TestCase from .models import Category, Person diff --git a/tests/mail/test_sendtestemail.py b/tests/mail/test_sendtestemail.py index b1494bf3dfab..d7457c9a1c6c 100644 --- a/tests/mail/test_sendtestemail.py +++ b/tests/mail/test_sendtestemail.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core import mail from django.core.management import call_command from django.test import SimpleTestCase, override_settings diff --git a/tests/mail/tests.py b/tests/mail/tests.py index fd2a185fb534..ba7ff44714ef 100644 --- a/tests/mail/tests.py +++ b/tests/mail/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import asyncore import base64 import mimetypes diff --git a/tests/managers_regress/tests.py b/tests/managers_regress/tests.py index cda90ac2b679..1b3e0a1635ab 100644 --- a/tests/managers_regress/tests.py +++ b/tests/managers_regress/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models from django.template import Context, Template from django.test import TestCase, override_settings diff --git a/tests/many_to_many/models.py b/tests/many_to_many/models.py index a199cd77e24f..b0e708ebb45e 100644 --- a/tests/many_to_many/models.py +++ b/tests/many_to_many/models.py @@ -6,8 +6,6 @@ In this example, an ``Article`` can be published in multiple ``Publication`` objects, and a ``Publication`` has multiple ``Article`` objects. """ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/many_to_many/tests.py b/tests/many_to_many/tests.py index e5bc51be47a1..d81d88b17624 100644 --- a/tests/many_to_many/tests.py +++ b/tests/many_to_many/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import transaction from django.test import TestCase diff --git a/tests/many_to_one/models.py b/tests/many_to_one/models.py index abc9c7d82658..09578b56a31f 100644 --- a/tests/many_to_one/models.py +++ b/tests/many_to_one/models.py @@ -3,8 +3,6 @@ To define a many-to-one relationship, use ``ForeignKey()``. """ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/many_to_one_null/tests.py b/tests/many_to_one_null/tests.py index dc49c61f6902..77b8fd7c2581 100644 --- a/tests/many_to_one_null/tests.py +++ b/tests/many_to_one_null/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import TestCase from .models import Article, Car, Driver, Reporter diff --git a/tests/max_lengths/tests.py b/tests/max_lengths/tests.py index fa3cd4bddcf0..fb81a7f47302 100644 --- a/tests/max_lengths/tests.py +++ b/tests/max_lengths/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import unittest from .models import PersonWithCustomMaxLengths, PersonWithDefaultMaxLengths diff --git a/tests/middleware/tests.py b/tests/middleware/tests.py index 1d473ef558cb..43ea0748a0de 100644 --- a/tests/middleware/tests.py +++ b/tests/middleware/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import gzip import random import re diff --git a/tests/middleware_exceptions/middleware.py b/tests/middleware_exceptions/middleware.py index b1de76a5cee9..e704b9f2b5d4 100644 --- a/tests/middleware_exceptions/middleware.py +++ b/tests/middleware_exceptions/middleware.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.http import Http404, HttpResponse from django.template import engines from django.template.response import TemplateResponse diff --git a/tests/migrate_signals/custom_migrations/0001_initial.py b/tests/migrate_signals/custom_migrations/0001_initial.py index 6e969d29ed9e..91b106ef0cde 100644 --- a/tests/migrate_signals/custom_migrations/0001_initial.py +++ b/tests/migrate_signals/custom_migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migration_test_data_persistence/migrations/0001_initial.py b/tests/migration_test_data_persistence/migrations/0001_initial.py index 6c19c4c81c2e..0f455ed43b13 100644 --- a/tests/migration_test_data_persistence/migrations/0001_initial.py +++ b/tests/migration_test_data_persistence/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migration_test_data_persistence/migrations/0002_add_book.py b/tests/migration_test_data_persistence/migrations/0002_add_book.py index 6ce7fff26bec..51c13effd9a4 100644 --- a/tests/migration_test_data_persistence/migrations/0002_add_book.py +++ b/tests/migration_test_data_persistence/migrations/0002_add_book.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/deprecated_field_migrations/0001_initial.py b/tests/migrations/deprecated_field_migrations/0001_initial.py index 624ea680162e..8665d5b2ff4a 100644 --- a/tests/migrations/deprecated_field_migrations/0001_initial.py +++ b/tests/migrations/deprecated_field_migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/deprecated_field_migrations/0002_remove_ipaddressfield_ip.py b/tests/migrations/deprecated_field_migrations/0002_remove_ipaddressfield_ip.py index 12e9739bca2a..1b27bf536d29 100644 --- a/tests/migrations/deprecated_field_migrations/0002_remove_ipaddressfield_ip.py +++ b/tests/migrations/deprecated_field_migrations/0002_remove_ipaddressfield_ip.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/0001_initial.py b/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/0001_initial.py index 8df44dfeef27..48664b2a0413 100644 --- a/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/0001_initial.py +++ b/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/0002_alter_id.py b/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/0002_alter_id.py index ffce7dbd70a3..18bc91ad7251 100644 --- a/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/0002_alter_id.py +++ b/tests/migrations/migrations_test_apps/alter_fk/author_app/migrations/0002_alter_id.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/alter_fk/book_app/migrations/0001_initial.py b/tests/migrations/migrations_test_apps/alter_fk/book_app/migrations/0001_initial.py index 7769e4b32a61..46543caeee13 100644 --- a/tests/migrations/migrations_test_apps/alter_fk/book_app/migrations/0001_initial.py +++ b/tests/migrations/migrations_test_apps/alter_fk/book_app/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/conflicting_app_with_dependencies/migrations/0001_initial.py b/tests/migrations/migrations_test_apps/conflicting_app_with_dependencies/migrations/0001_initial.py index 146d6cee3e72..ddf070a8cd19 100644 --- a/tests/migrations/migrations_test_apps/conflicting_app_with_dependencies/migrations/0001_initial.py +++ b/tests/migrations/migrations_test_apps/conflicting_app_with_dependencies/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/conflicting_app_with_dependencies/migrations/0002_conflicting_second.py b/tests/migrations/migrations_test_apps/conflicting_app_with_dependencies/migrations/0002_conflicting_second.py index cbe5bfb13e6f..16fd7dbfee0a 100644 --- a/tests/migrations/migrations_test_apps/conflicting_app_with_dependencies/migrations/0002_conflicting_second.py +++ b/tests/migrations/migrations_test_apps/conflicting_app_with_dependencies/migrations/0002_conflicting_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/conflicting_app_with_dependencies/migrations/0002_second.py b/tests/migrations/migrations_test_apps/conflicting_app_with_dependencies/migrations/0002_second.py index 16d42f8736d1..d612af572684 100644 --- a/tests/migrations/migrations_test_apps/conflicting_app_with_dependencies/migrations/0002_second.py +++ b/tests/migrations/migrations_test_apps/conflicting_app_with_dependencies/migrations/0002_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0001_initial.py b/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0001_initial.py index 09cda3c61f23..6351b0d21232 100644 --- a/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0001_initial.py +++ b/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0002_a2.py b/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0002_a2.py index e528f9ee5ebf..ab943b9c777e 100644 --- a/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0002_a2.py +++ b/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0002_a2.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0003_a3.py b/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0003_a3.py index 8dd1bf977b96..42b5853d3c9d 100644 --- a/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0003_a3.py +++ b/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0003_a3.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0004_a4.py b/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0004_a4.py index 5a1ebfb68407..b7a0bcb8a7c0 100644 --- a/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0004_a4.py +++ b/tests/migrations/migrations_test_apps/lookuperror_a/migrations/0004_a4.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/lookuperror_b/migrations/0001_initial.py b/tests/migrations/migrations_test_apps/lookuperror_b/migrations/0001_initial.py index 9cd50e24b8ac..def52ae789ef 100644 --- a/tests/migrations/migrations_test_apps/lookuperror_b/migrations/0001_initial.py +++ b/tests/migrations/migrations_test_apps/lookuperror_b/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/lookuperror_b/migrations/0002_b2.py b/tests/migrations/migrations_test_apps/lookuperror_b/migrations/0002_b2.py index 7e91505cd2a0..a2ac5e1ba778 100644 --- a/tests/migrations/migrations_test_apps/lookuperror_b/migrations/0002_b2.py +++ b/tests/migrations/migrations_test_apps/lookuperror_b/migrations/0002_b2.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/lookuperror_b/migrations/0003_b3.py b/tests/migrations/migrations_test_apps/lookuperror_b/migrations/0003_b3.py index 746c49d0a10e..1c76e73ec138 100644 --- a/tests/migrations/migrations_test_apps/lookuperror_b/migrations/0003_b3.py +++ b/tests/migrations/migrations_test_apps/lookuperror_b/migrations/0003_b3.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/lookuperror_c/migrations/0001_initial.py b/tests/migrations/migrations_test_apps/lookuperror_c/migrations/0001_initial.py index bf9ec3d1718c..8453148b8750 100644 --- a/tests/migrations/migrations_test_apps/lookuperror_c/migrations/0001_initial.py +++ b/tests/migrations/migrations_test_apps/lookuperror_c/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/lookuperror_c/migrations/0002_c2.py b/tests/migrations/migrations_test_apps/lookuperror_c/migrations/0002_c2.py index ca557688aa15..a928da9ae012 100644 --- a/tests/migrations/migrations_test_apps/lookuperror_c/migrations/0002_c2.py +++ b/tests/migrations/migrations_test_apps/lookuperror_c/migrations/0002_c2.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/lookuperror_c/migrations/0003_c3.py b/tests/migrations/migrations_test_apps/lookuperror_c/migrations/0003_c3.py index f226cad45836..58119ac8ac06 100644 --- a/tests/migrations/migrations_test_apps/lookuperror_c/migrations/0003_c3.py +++ b/tests/migrations/migrations_test_apps/lookuperror_c/migrations/0003_c3.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/migrated_app/migrations/0001_initial.py b/tests/migrations/migrations_test_apps/migrated_app/migrations/0001_initial.py index 581d5368143f..344bebdfe326 100644 --- a/tests/migrations/migrations_test_apps/migrated_app/migrations/0001_initial.py +++ b/tests/migrations/migrations_test_apps/migrated_app/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/migrated_unapplied_app/migrations/0001_initial.py b/tests/migrations/migrations_test_apps/migrated_unapplied_app/migrations/0001_initial.py index 4913065b105b..800ceed7e4ff 100644 --- a/tests/migrations/migrations_test_apps/migrated_unapplied_app/migrations/0001_initial.py +++ b/tests/migrations/migrations_test_apps/migrated_unapplied_app/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/mutate_state_a/migrations/0001_initial.py b/tests/migrations/migrations_test_apps/mutate_state_a/migrations/0001_initial.py index 5fac74abf387..37c9bf7377fd 100644 --- a/tests/migrations/migrations_test_apps/mutate_state_a/migrations/0001_initial.py +++ b/tests/migrations/migrations_test_apps/mutate_state_a/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/mutate_state_b/migrations/0001_initial.py b/tests/migrations/migrations_test_apps/mutate_state_b/migrations/0001_initial.py index 73f436b20d6d..51c022dd7fd5 100644 --- a/tests/migrations/migrations_test_apps/mutate_state_b/migrations/0001_initial.py +++ b/tests/migrations/migrations_test_apps/mutate_state_b/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/mutate_state_b/migrations/0002_add_field.py b/tests/migrations/migrations_test_apps/mutate_state_b/migrations/0002_add_field.py index 45aca3074094..ae968382eb55 100644 --- a/tests/migrations/migrations_test_apps/mutate_state_b/migrations/0002_add_field.py +++ b/tests/migrations/migrations_test_apps/mutate_state_b/migrations/0002_add_field.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/unmigrated_app/models.py b/tests/migrations/migrations_test_apps/unmigrated_app/models.py index 793e03829fd3..03d397c45b75 100644 --- a/tests/migrations/migrations_test_apps/unmigrated_app/models.py +++ b/tests/migrations/migrations_test_apps/unmigrated_app/models.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import models diff --git a/tests/migrations/migrations_test_apps/unspecified_app_with_conflict/migrations/0001_initial.py b/tests/migrations/migrations_test_apps/unspecified_app_with_conflict/migrations/0001_initial.py index 581d5368143f..344bebdfe326 100644 --- a/tests/migrations/migrations_test_apps/unspecified_app_with_conflict/migrations/0001_initial.py +++ b/tests/migrations/migrations_test_apps/unspecified_app_with_conflict/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/unspecified_app_with_conflict/migrations/0002_conflicting_second.py b/tests/migrations/migrations_test_apps/unspecified_app_with_conflict/migrations/0002_conflicting_second.py index 43e03165e844..ad44031030c9 100644 --- a/tests/migrations/migrations_test_apps/unspecified_app_with_conflict/migrations/0002_conflicting_second.py +++ b/tests/migrations/migrations_test_apps/unspecified_app_with_conflict/migrations/0002_conflicting_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/migrations_test_apps/unspecified_app_with_conflict/migrations/0002_second.py b/tests/migrations/migrations_test_apps/unspecified_app_with_conflict/migrations/0002_second.py index cb8cfc96d24a..fbf5a9110caa 100644 --- a/tests/migrations/migrations_test_apps/unspecified_app_with_conflict/migrations/0002_second.py +++ b/tests/migrations/migrations_test_apps/unspecified_app_with_conflict/migrations/0002_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/models.py b/tests/migrations/models.py index 6f02e8088e21..b1a10210b6d8 100644 --- a/tests/migrations/models.py +++ b/tests/migrations/models.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.apps.registry import Apps from django.db import models from django.utils import six diff --git a/tests/migrations/test_add_many_to_many_field_initial/0001_initial.py b/tests/migrations/test_add_many_to_many_field_initial/0001_initial.py index b50b3c68b8e4..50fd06a35f48 100644 --- a/tests/migrations/test_add_many_to_many_field_initial/0001_initial.py +++ b/tests/migrations/test_add_many_to_many_field_initial/0001_initial.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_add_many_to_many_field_initial/0002_initial.py b/tests/migrations/test_add_many_to_many_field_initial/0002_initial.py index 65739a5bb40e..1bc6c8aafa6b 100644 --- a/tests/migrations/test_add_many_to_many_field_initial/0002_initial.py +++ b/tests/migrations/test_add_many_to_many_field_initial/0002_initial.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_auto_now_add/0001_initial.py b/tests/migrations/test_auto_now_add/0001_initial.py index f966cc0e7b33..f1bfb4465789 100644 --- a/tests/migrations/test_auto_now_add/0001_initial.py +++ b/tests/migrations/test_auto_now_add/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py index bf3183107184..e30aeb5d1918 100644 --- a/tests/migrations/test_autodetector.py +++ b/tests/migrations/test_autodetector.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import functools import re diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index fd483b7f85bc..ab2e47fabdf8 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime import importlib import io @@ -661,7 +658,6 @@ def test_files_content(self): with io.open(initial_file, 'r', encoding='utf-8') as fp: content = fp.read() - self.assertIn('# -*- coding: utf-8 -*-', content) self.assertIn('migrations.CreateModel', content) self.assertIn('initial = True', content) @@ -813,7 +809,6 @@ def test_makemigrations_empty_migration(self): with io.open(initial_file, 'r', encoding='utf-8') as fp: content = fp.read() - self.assertIn('# -*- coding: utf-8 -*-', content) # Remove all whitespace to check for empty dependencies and operations content = content.replace(' ', '') @@ -1040,8 +1035,6 @@ def test_makemigration_merge_dry_run_verbosity_3(self): # Additional output caused by verbosity 3 # The complete merge migration file that would be written - # '\n#' is to verify no bytestring prefix before # - self.assertIn("\n# -*- coding: utf-8 -*-", output) self.assertIn("class Migration(migrations.Migration):", output) self.assertIn("dependencies = [", output) self.assertIn("('migrations', '0002_second')", output) @@ -1087,7 +1080,6 @@ class Meta: # Additional output caused by verbosity 3 # The complete migrations file that would be written - self.assertIn("# -*- coding: utf-8 -*-", out.getvalue()) self.assertIn("class Migration(migrations.Migration):", out.getvalue()) self.assertIn("dependencies = [", out.getvalue()) self.assertIn("('migrations', '0001_initial'),", out.getvalue()) @@ -1211,7 +1203,6 @@ def cmd(migration_count, migration_name, *args): self.assertTrue(os.path.exists(migration_file)) with io.open(migration_file, "r", encoding="utf-8") as fp: content = fp.read() - self.assertIn("# -*- coding: utf-8 -*-", content) content = content.replace(" ", "") return content diff --git a/tests/migrations/test_loader.py b/tests/migrations/test_loader.py index b464209a984d..6c91a504301d 100644 --- a/tests/migrations/test_loader.py +++ b/tests/migrations/test_loader.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from unittest import skipIf from django.db import connection, connections diff --git a/tests/migrations/test_migrations/0001_initial.py b/tests/migrations/test_migrations/0001_initial.py index 1fa9664f6a00..8572afa1aac0 100644 --- a/tests/migrations/test_migrations/0001_initial.py +++ b/tests/migrations/test_migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations/0002_second.py b/tests/migrations/test_migrations/0002_second.py index 898676c9d8d0..71c300ceada7 100644 --- a/tests/migrations/test_migrations/0002_second.py +++ b/tests/migrations/test_migrations/0002_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_atomic_operation/0001_initial.py b/tests/migrations/test_migrations_atomic_operation/0001_initial.py index 11bd2f7ce2b0..415186423f36 100644 --- a/tests/migrations/test_migrations_atomic_operation/0001_initial.py +++ b/tests/migrations/test_migrations_atomic_operation/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_backwards_deps_1/0001_initial.py b/tests/migrations/test_migrations_backwards_deps_1/0001_initial.py index cb6f0891fda6..de3ea271734f 100644 --- a/tests/migrations/test_migrations_backwards_deps_1/0001_initial.py +++ b/tests/migrations/test_migrations_backwards_deps_1/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_backwards_deps_1/0002_second.py b/tests/migrations/test_migrations_backwards_deps_1/0002_second.py index 41d6684f9d51..6eb831e061fe 100644 --- a/tests/migrations/test_migrations_backwards_deps_1/0002_second.py +++ b/tests/migrations/test_migrations_backwards_deps_1/0002_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_conflict/0001_initial.py b/tests/migrations/test_migrations_conflict/0001_initial.py index 581d5368143f..344bebdfe326 100644 --- a/tests/migrations/test_migrations_conflict/0001_initial.py +++ b/tests/migrations/test_migrations_conflict/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_conflict/0002_conflicting_second.py b/tests/migrations/test_migrations_conflict/0002_conflicting_second.py index 405763617701..15ea1f063aa8 100644 --- a/tests/migrations/test_migrations_conflict/0002_conflicting_second.py +++ b/tests/migrations/test_migrations_conflict/0002_conflicting_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_conflict/0002_second.py b/tests/migrations/test_migrations_conflict/0002_second.py index e5fed5df1316..60a6999ee473 100644 --- a/tests/migrations/test_migrations_conflict/0002_second.py +++ b/tests/migrations/test_migrations_conflict/0002_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_custom_user/0001_initial.py b/tests/migrations/test_migrations_custom_user/0001_initial.py index dd1b6bc219c7..250aa9f51b6e 100644 --- a/tests/migrations/test_migrations_custom_user/0001_initial.py +++ b/tests/migrations/test_migrations_custom_user/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.conf import settings from django.db import migrations, models diff --git a/tests/migrations/test_migrations_fake_split_initial/0001_initial.py b/tests/migrations/test_migrations_fake_split_initial/0001_initial.py index 1f42af2fb8aa..2079c10be868 100644 --- a/tests/migrations/test_migrations_fake_split_initial/0001_initial.py +++ b/tests/migrations/test_migrations_fake_split_initial/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_fake_split_initial/0002_second.py b/tests/migrations/test_migrations_fake_split_initial/0002_second.py index 6730f1c65af2..6e9b28efb4fb 100644 --- a/tests/migrations/test_migrations_fake_split_initial/0002_second.py +++ b/tests/migrations/test_migrations_fake_split_initial/0002_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_first/second.py b/tests/migrations/test_migrations_first/second.py index d0929e6a6f61..e4cf995dcc13 100644 --- a/tests/migrations/test_migrations_first/second.py +++ b/tests/migrations/test_migrations_first/second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_first/thefirst.py b/tests/migrations/test_migrations_first/thefirst.py index 581d5368143f..344bebdfe326 100644 --- a/tests/migrations/test_migrations_first/thefirst.py +++ b/tests/migrations/test_migrations_first/thefirst.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_initial_false/0001_not_initial.py b/tests/migrations/test_migrations_initial_false/0001_not_initial.py index 934532177619..5347ad2934e3 100644 --- a/tests/migrations/test_migrations_initial_false/0001_not_initial.py +++ b/tests/migrations/test_migrations_initial_false/0001_not_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_no_ancestor/0001_initial.py b/tests/migrations/test_migrations_no_ancestor/0001_initial.py index 581d5368143f..344bebdfe326 100644 --- a/tests/migrations/test_migrations_no_ancestor/0001_initial.py +++ b/tests/migrations/test_migrations_no_ancestor/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_no_ancestor/0002_conflicting_second.py b/tests/migrations/test_migrations_no_ancestor/0002_conflicting_second.py index 3e8b270599ef..71625a71166d 100644 --- a/tests/migrations/test_migrations_no_ancestor/0002_conflicting_second.py +++ b/tests/migrations/test_migrations_no_ancestor/0002_conflicting_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_no_ancestor/0002_second.py b/tests/migrations/test_migrations_no_ancestor/0002_second.py index 898676c9d8d0..71c300ceada7 100644 --- a/tests/migrations/test_migrations_no_ancestor/0002_second.py +++ b/tests/migrations/test_migrations_no_ancestor/0002_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_no_changes/0001_initial.py b/tests/migrations/test_migrations_no_changes/0001_initial.py index 581d5368143f..344bebdfe326 100644 --- a/tests/migrations/test_migrations_no_changes/0001_initial.py +++ b/tests/migrations/test_migrations_no_changes/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_no_changes/0002_second.py b/tests/migrations/test_migrations_no_changes/0002_second.py index 898676c9d8d0..71c300ceada7 100644 --- a/tests/migrations/test_migrations_no_changes/0002_second.py +++ b/tests/migrations/test_migrations_no_changes/0002_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_no_changes/0003_third.py b/tests/migrations/test_migrations_no_changes/0003_third.py index 05b7535dc399..89b3bc030c99 100644 --- a/tests/migrations/test_migrations_no_changes/0003_third.py +++ b/tests/migrations/test_migrations_no_changes/0003_third.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_no_default/0001_initial.py b/tests/migrations/test_migrations_no_default/0001_initial.py index 2fd027f2d2ae..e9176c4958be 100644 --- a/tests/migrations/test_migrations_no_default/0001_initial.py +++ b/tests/migrations/test_migrations_no_default/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_non_atomic/0001_initial.py b/tests/migrations/test_migrations_non_atomic/0001_initial.py index 47a03a16f980..f1aa1ae37125 100644 --- a/tests/migrations/test_migrations_non_atomic/0001_initial.py +++ b/tests/migrations/test_migrations_non_atomic/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_order/0001.py b/tests/migrations/test_migrations_order/0001.py index 402c13e7f699..2ef88e957d40 100644 --- a/tests/migrations/test_migrations_order/0001.py +++ b/tests/migrations/test_migrations_order/0001.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_run_before/0001_initial.py b/tests/migrations/test_migrations_run_before/0001_initial.py index 7d44a8d7898c..186c7fbec9a2 100644 --- a/tests/migrations/test_migrations_run_before/0001_initial.py +++ b/tests/migrations/test_migrations_run_before/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_run_before/0002_second.py b/tests/migrations/test_migrations_run_before/0002_second.py index 6f1fbdd6a145..2be86bb439d2 100644 --- a/tests/migrations/test_migrations_run_before/0002_second.py +++ b/tests/migrations/test_migrations_run_before/0002_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_run_before/0003_third.py b/tests/migrations/test_migrations_run_before/0003_third.py index d5c098c730ea..d24d28ca1cb4 100644 --- a/tests/migrations/test_migrations_run_before/0003_third.py +++ b/tests/migrations/test_migrations_run_before/0003_third.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_squashed/0001_initial.py b/tests/migrations/test_migrations_squashed/0001_initial.py index 581d5368143f..344bebdfe326 100644 --- a/tests/migrations/test_migrations_squashed/0001_initial.py +++ b/tests/migrations/test_migrations_squashed/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_squashed/0001_squashed_0002.py b/tests/migrations/test_migrations_squashed/0001_squashed_0002.py index 3b87c54da442..1ba7f45e41c5 100644 --- a/tests/migrations/test_migrations_squashed/0001_squashed_0002.py +++ b/tests/migrations/test_migrations_squashed/0001_squashed_0002.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_squashed/0002_second.py b/tests/migrations/test_migrations_squashed/0002_second.py index e5fed5df1316..60a6999ee473 100644 --- a/tests/migrations/test_migrations_squashed/0002_second.py +++ b/tests/migrations/test_migrations_squashed/0002_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_migrations_squashed_complex/1_auto.py b/tests/migrations/test_migrations_squashed_complex/1_auto.py index bf1268806320..46fc1242c9da 100644 --- a/tests/migrations/test_migrations_squashed_complex/1_auto.py +++ b/tests/migrations/test_migrations_squashed_complex/1_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex/2_auto.py b/tests/migrations/test_migrations_squashed_complex/2_auto.py index 1d952ad0df53..1964bf81673c 100644 --- a/tests/migrations/test_migrations_squashed_complex/2_auto.py +++ b/tests/migrations/test_migrations_squashed_complex/2_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex/3_auto.py b/tests/migrations/test_migrations_squashed_complex/3_auto.py index d7809681154b..994ddf361952 100644 --- a/tests/migrations/test_migrations_squashed_complex/3_auto.py +++ b/tests/migrations/test_migrations_squashed_complex/3_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex/3_squashed_5.py b/tests/migrations/test_migrations_squashed_complex/3_squashed_5.py index f7dde035248e..e8f1eb527ee2 100644 --- a/tests/migrations/test_migrations_squashed_complex/3_squashed_5.py +++ b/tests/migrations/test_migrations_squashed_complex/3_squashed_5.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex/4_auto.py b/tests/migrations/test_migrations_squashed_complex/4_auto.py index c39b16e4544a..e7d0f09b55fb 100644 --- a/tests/migrations/test_migrations_squashed_complex/4_auto.py +++ b/tests/migrations/test_migrations_squashed_complex/4_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex/5_auto.py b/tests/migrations/test_migrations_squashed_complex/5_auto.py index 754fe2d25377..e7e25d9a7179 100644 --- a/tests/migrations/test_migrations_squashed_complex/5_auto.py +++ b/tests/migrations/test_migrations_squashed_complex/5_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex/6_auto.py b/tests/migrations/test_migrations_squashed_complex/6_auto.py index 65d829cd32bd..4438bb41968b 100644 --- a/tests/migrations/test_migrations_squashed_complex/6_auto.py +++ b/tests/migrations/test_migrations_squashed_complex/6_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex/7_auto.py b/tests/migrations/test_migrations_squashed_complex/7_auto.py index f1b3cd3e4976..f231edfed116 100644 --- a/tests/migrations/test_migrations_squashed_complex/7_auto.py +++ b/tests/migrations/test_migrations_squashed_complex/7_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/1_auto.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/1_auto.py index bf1268806320..46fc1242c9da 100644 --- a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/1_auto.py +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/1_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_auto.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_auto.py index 13a844275b71..83d6e0bedc09 100644 --- a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_auto.py +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_squashed_3.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_squashed_3.py index 521e70f5d262..838f68f99f39 100644 --- a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_squashed_3.py +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_squashed_3.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/3_auto.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/3_auto.py index aa0e86e5608a..8abccb5bed8d 100644 --- a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/3_auto.py +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/3_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/4_auto.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/4_auto.py index 145e495a1890..3b44a1d0ab21 100644 --- a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/4_auto.py +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/4_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_auto.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_auto.py index 13a844275b71..83d6e0bedc09 100644 --- a/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_auto.py +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_squashed_2.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_squashed_2.py index 6ef4dba71ed5..e12b5754ad57 100644 --- a/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_squashed_2.py +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_squashed_2.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/2_auto.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/2_auto.py index 35fc7b8c1c36..6726beb9d574 100644 --- a/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/2_auto.py +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/2_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_erroneous/1_auto.py b/tests/migrations/test_migrations_squashed_erroneous/1_auto.py index bf1268806320..46fc1242c9da 100644 --- a/tests/migrations/test_migrations_squashed_erroneous/1_auto.py +++ b/tests/migrations/test_migrations_squashed_erroneous/1_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_erroneous/2_auto.py b/tests/migrations/test_migrations_squashed_erroneous/2_auto.py index 1d952ad0df53..1964bf81673c 100644 --- a/tests/migrations/test_migrations_squashed_erroneous/2_auto.py +++ b/tests/migrations/test_migrations_squashed_erroneous/2_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_erroneous/3_squashed_5.py b/tests/migrations/test_migrations_squashed_erroneous/3_squashed_5.py index f7dde035248e..e8f1eb527ee2 100644 --- a/tests/migrations/test_migrations_squashed_erroneous/3_squashed_5.py +++ b/tests/migrations/test_migrations_squashed_erroneous/3_squashed_5.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_erroneous/6_auto.py b/tests/migrations/test_migrations_squashed_erroneous/6_auto.py index 65d829cd32bd..4438bb41968b 100644 --- a/tests/migrations/test_migrations_squashed_erroneous/6_auto.py +++ b/tests/migrations/test_migrations_squashed_erroneous/6_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_erroneous/7_auto.py b/tests/migrations/test_migrations_squashed_erroneous/7_auto.py index f1b3cd3e4976..f231edfed116 100644 --- a/tests/migrations/test_migrations_squashed_erroneous/7_auto.py +++ b/tests/migrations/test_migrations_squashed_erroneous/7_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_extra/0001_initial.py b/tests/migrations/test_migrations_squashed_extra/0001_initial.py index 9a330e106754..bd613aa95e0e 100644 --- a/tests/migrations/test_migrations_squashed_extra/0001_initial.py +++ b/tests/migrations/test_migrations_squashed_extra/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_extra/0001_squashed_0002.py b/tests/migrations/test_migrations_squashed_extra/0001_squashed_0002.py index 79beebea1c63..9d5581cc59e8 100644 --- a/tests/migrations/test_migrations_squashed_extra/0001_squashed_0002.py +++ b/tests/migrations/test_migrations_squashed_extra/0001_squashed_0002.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_extra/0002_second.py b/tests/migrations/test_migrations_squashed_extra/0002_second.py index 4b892a7e8b94..5ca710feb6ee 100644 --- a/tests/migrations/test_migrations_squashed_extra/0002_second.py +++ b/tests/migrations/test_migrations_squashed_extra/0002_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_extra/0003_third.py b/tests/migrations/test_migrations_squashed_extra/0003_third.py index b69ae8883bb6..cf27aa2990cb 100644 --- a/tests/migrations/test_migrations_squashed_extra/0003_third.py +++ b/tests/migrations/test_migrations_squashed_extra/0003_third.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_ref_squashed/app1/1_auto.py b/tests/migrations/test_migrations_squashed_ref_squashed/app1/1_auto.py index 9a330e106754..bd613aa95e0e 100644 --- a/tests/migrations/test_migrations_squashed_ref_squashed/app1/1_auto.py +++ b/tests/migrations/test_migrations_squashed_ref_squashed/app1/1_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_ref_squashed/app1/2_auto.py b/tests/migrations/test_migrations_squashed_ref_squashed/app1/2_auto.py index 4428c73fc44c..27d00f0cba6b 100644 --- a/tests/migrations/test_migrations_squashed_ref_squashed/app1/2_auto.py +++ b/tests/migrations/test_migrations_squashed_ref_squashed/app1/2_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_ref_squashed/app1/2_squashed_3.py b/tests/migrations/test_migrations_squashed_ref_squashed/app1/2_squashed_3.py index 80501ef177a0..c0361741321b 100644 --- a/tests/migrations/test_migrations_squashed_ref_squashed/app1/2_squashed_3.py +++ b/tests/migrations/test_migrations_squashed_ref_squashed/app1/2_squashed_3.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_ref_squashed/app1/3_auto.py b/tests/migrations/test_migrations_squashed_ref_squashed/app1/3_auto.py index 43863022a757..2203e4fdeee1 100644 --- a/tests/migrations/test_migrations_squashed_ref_squashed/app1/3_auto.py +++ b/tests/migrations/test_migrations_squashed_ref_squashed/app1/3_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_ref_squashed/app1/4_auto.py b/tests/migrations/test_migrations_squashed_ref_squashed/app1/4_auto.py index 6ce3ee7953f2..e9eddb16649d 100644 --- a/tests/migrations/test_migrations_squashed_ref_squashed/app1/4_auto.py +++ b/tests/migrations/test_migrations_squashed_ref_squashed/app1/4_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_ref_squashed/app2/1_auto.py b/tests/migrations/test_migrations_squashed_ref_squashed/app2/1_auto.py index 4428c73fc44c..27d00f0cba6b 100644 --- a/tests/migrations/test_migrations_squashed_ref_squashed/app2/1_auto.py +++ b/tests/migrations/test_migrations_squashed_ref_squashed/app2/1_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_ref_squashed/app2/1_squashed_2.py b/tests/migrations/test_migrations_squashed_ref_squashed/app2/1_squashed_2.py index aca9a46f61df..ac24a30c8579 100644 --- a/tests/migrations/test_migrations_squashed_ref_squashed/app2/1_squashed_2.py +++ b/tests/migrations/test_migrations_squashed_ref_squashed/app2/1_squashed_2.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_squashed_ref_squashed/app2/2_auto.py b/tests/migrations/test_migrations_squashed_ref_squashed/app2/2_auto.py index 77ab95584a9e..0b01988bbdac 100644 --- a/tests/migrations/test_migrations_squashed_ref_squashed/app2/2_auto.py +++ b/tests/migrations/test_migrations_squashed_ref_squashed/app2/2_auto.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations diff --git a/tests/migrations/test_migrations_unmigdep/0001_initial.py b/tests/migrations/test_migrations_unmigdep/0001_initial.py index a47805bf682f..91b58c3dad24 100644 --- a/tests/migrations/test_migrations_unmigdep/0001_initial.py +++ b/tests/migrations/test_migrations_unmigdep/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py index e1daabe8b522..f962f9cf8c0e 100644 --- a/tests/migrations/test_operations.py +++ b/tests/migrations/test_operations.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import unittest from django.db import connection, migrations, models, transaction diff --git a/tests/migrations/test_optimizer.py b/tests/migrations/test_optimizer.py index fc4f0ac5d7a8..be2db97ba44c 100644 --- a/tests/migrations/test_optimizer.py +++ b/tests/migrations/test_optimizer.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - from django.db import migrations, models from django.db.migrations import operations from django.db.migrations.optimizer import MigrationOptimizer diff --git a/tests/migrations/test_questioner.py b/tests/migrations/test_questioner.py index d5ba18a68402..45536410bbaa 100644 --- a/tests/migrations/test_questioner.py +++ b/tests/migrations/test_questioner.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db.migrations.questioner import MigrationQuestioner from django.test import SimpleTestCase from django.test.utils import override_settings diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index f06a215747f4..c03d8cfd38cd 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime import decimal import functools @@ -662,7 +659,6 @@ def test_migration_file_header_comments(self): self.assertTrue( output.startswith( - "# -*- coding: utf-8 -*-\n" "# Generated by Django %(version)s on 2015-07-31 04:40\n" % { 'version': get_version(), } diff --git a/tests/migrations2/test_migrations_2/0001_initial.py b/tests/migrations2/test_migrations_2/0001_initial.py index 02cbd97fcc77..6172f011e86a 100644 --- a/tests/migrations2/test_migrations_2/0001_initial.py +++ b/tests/migrations2/test_migrations_2/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations2/test_migrations_2_first/0001_initial.py b/tests/migrations2/test_migrations_2_first/0001_initial.py index e31d1d501fec..a290372312a4 100644 --- a/tests/migrations2/test_migrations_2_first/0001_initial.py +++ b/tests/migrations2/test_migrations_2_first/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations2/test_migrations_2_first/0002_second.py b/tests/migrations2/test_migrations_2_first/0002_second.py index a3ca7dac3934..67a422995d29 100644 --- a/tests/migrations2/test_migrations_2_first/0002_second.py +++ b/tests/migrations2/test_migrations_2_first/0002_second.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/migrations2/test_migrations_2_no_deps/0001_initial.py b/tests/migrations2/test_migrations_2_no_deps/0001_initial.py index 22137065942f..1314e3e1e11f 100644 --- a/tests/migrations2/test_migrations_2_no_deps/0001_initial.py +++ b/tests/migrations2/test_migrations_2_no_deps/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/model_fields/test_charfield.py b/tests/model_fields/test_charfield.py index 0bca108d2298..04ac1d3f92af 100644 --- a/tests/model_fields/test_charfield.py +++ b/tests/model_fields/test_charfield.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from unittest import skipIf from django.core.exceptions import ValidationError diff --git a/tests/model_fields/test_imagefield.py b/tests/model_fields/test_imagefield.py index e178760d2fc9..92985a99d967 100644 --- a/tests/model_fields/test_imagefield.py +++ b/tests/model_fields/test_imagefield.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os import shutil from unittest import skipIf diff --git a/tests/model_fields/test_promises.py b/tests/model_fields/test_promises.py index 65d1b7ec991b..bf5258cddf38 100644 --- a/tests/model_fields/test_promises.py +++ b/tests/model_fields/test_promises.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import unittest from decimal import Decimal diff --git a/tests/model_fields/test_slugfield.py b/tests/model_fields/test_slugfield.py index 45a4527ad979..3dc955d3adc4 100644 --- a/tests/model_fields/test_slugfield.py +++ b/tests/model_fields/test_slugfield.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.test import TestCase from .models import BigS, UnicodeSlugField diff --git a/tests/model_fields/test_textfield.py b/tests/model_fields/test_textfield.py index a3cd516cb4d1..a759b646482a 100644 --- a/tests/model_fields/test_textfield.py +++ b/tests/model_fields/test_textfield.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from unittest import skipIf from django.db import connection, models diff --git a/tests/model_forms/models.py b/tests/model_forms/models.py index 3675e080faea..da91fc88b7b6 100644 --- a/tests/model_forms/models.py +++ b/tests/model_forms/models.py @@ -6,8 +6,6 @@ and the examples are probably a poor fit for the ``ModelForm`` syntax. In other words, most of these tests should be rewritten. """ -from __future__ import unicode_literals - import datetime import os import tempfile diff --git a/tests/model_forms/test_uuid.py b/tests/model_forms/test_uuid.py index b30da6d4653f..1c566efcd867 100644 --- a/tests/model_forms/test_uuid.py +++ b/tests/model_forms/test_uuid.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django import forms from django.core.exceptions import ValidationError from django.test import TestCase diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index ef808f72f56a..0fc516b55c88 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import os from decimal import Decimal diff --git a/tests/model_formsets/models.py b/tests/model_formsets/models.py index 0bf56189a7d3..421d873704f2 100644 --- a/tests/model_formsets/models.py +++ b/tests/model_formsets/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import uuid diff --git a/tests/model_formsets/tests.py b/tests/model_formsets/tests.py index 4387fbf52d22..b928944097af 100644 --- a/tests/model_formsets/tests.py +++ b/tests/model_formsets/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import re from datetime import date diff --git a/tests/model_formsets_regress/tests.py b/tests/model_formsets_regress/tests.py index 1885ca78521a..a9b50b3699a1 100644 --- a/tests/model_formsets_regress/tests.py +++ b/tests/model_formsets_regress/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django import forms from django.forms.formsets import DELETION_FIELD_NAME, BaseFormSet from django.forms.models import ( diff --git a/tests/model_inheritance/models.py b/tests/model_inheritance/models.py index 45f22df0bcce..4c7d4a7c8a28 100644 --- a/tests/model_inheritance/models.py +++ b/tests/model_inheritance/models.py @@ -11,8 +11,6 @@ Both styles are demonstrated here. """ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/model_inheritance/test_abstract_inheritance.py b/tests/model_inheritance/test_abstract_inheritance.py index 71b8513a574a..6f0b89128bd6 100644 --- a/tests/model_inheritance/test_abstract_inheritance.py +++ b/tests/model_inheritance/test_abstract_inheritance.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.contenttypes.fields import ( GenericForeignKey, GenericRelation, ) diff --git a/tests/model_inheritance/tests.py b/tests/model_inheritance/tests.py index 079fbb75c4ad..8bb74d7ccbb2 100644 --- a/tests/model_inheritance/tests.py +++ b/tests/model_inheritance/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from operator import attrgetter from django.core.exceptions import FieldError, ValidationError diff --git a/tests/model_inheritance_regress/models.py b/tests/model_inheritance_regress/models.py index 8481e215164a..69ce0d9e2b75 100644 --- a/tests/model_inheritance_regress/models.py +++ b/tests/model_inheritance_regress/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from django.db import models diff --git a/tests/model_inheritance_regress/tests.py b/tests/model_inheritance_regress/tests.py index 3664fca44f27..9cb710c4b8e2 100644 --- a/tests/model_inheritance_regress/tests.py +++ b/tests/model_inheritance_regress/tests.py @@ -1,8 +1,6 @@ """ Regression tests for Model inheritance behavior. """ -from __future__ import unicode_literals - import datetime from operator import attrgetter from unittest import expectedFailure diff --git a/tests/model_options/test_tablespaces.py b/tests/model_options/test_tablespaces.py index 2d4b9073e83b..03a137603b52 100644 --- a/tests/model_options/test_tablespaces.py +++ b/tests/model_options/test_tablespaces.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.apps import apps from django.conf import settings from django.db import connection diff --git a/tests/model_package/tests.py b/tests/model_package/tests.py index 9d1b81fa2a66..bdb1cfba5a14 100644 --- a/tests/model_package/tests.py +++ b/tests/model_package/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import connection, models from django.db.backends.utils import truncate_name from django.test import TestCase diff --git a/tests/model_regress/models.py b/tests/model_regress/models.py index e7c2b3a49450..147116d7e292 100644 --- a/tests/model_regress/models.py +++ b/tests/model_regress/models.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/model_regress/tests.py b/tests/model_regress/tests.py index bd8e927be69d..808729979ffe 100644 --- a/tests/model_regress/tests.py +++ b/tests/model_regress/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from operator import attrgetter diff --git a/tests/modeladmin/models.py b/tests/modeladmin/models.py index 88a659795a8b..64cc86aa6658 100644 --- a/tests/modeladmin/models.py +++ b/tests/modeladmin/models.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from django.contrib.auth.models import User from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/modeladmin/test_checks.py b/tests/modeladmin/test_checks.py index 0c66544b6beb..93b35ecf5687 100644 --- a/tests/modeladmin/test_checks.py +++ b/tests/modeladmin/test_checks.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django import forms from django.contrib.admin import BooleanFieldListFilter, SimpleListFilter from django.contrib.admin.options import VERTICAL, ModelAdmin, TabularInline diff --git a/tests/modeladmin/tests.py b/tests/modeladmin/tests.py index 1f5d8a32364f..12ca86ff1ac6 100644 --- a/tests/modeladmin/tests.py +++ b/tests/modeladmin/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import date from django import forms diff --git a/tests/multiple_database/routers.py b/tests/multiple_database/routers.py index e467cf563fc6..e51c82b858c0 100644 --- a/tests/multiple_database/routers.py +++ b/tests/multiple_database/routers.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import DEFAULT_DB_ALIAS diff --git a/tests/multiple_database/tests.py b/tests/multiple_database/tests.py index 0ea3b6667e1f..7e936216b742 100644 --- a/tests/multiple_database/tests.py +++ b/tests/multiple_database/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import pickle from operator import attrgetter diff --git a/tests/nested_foreign_keys/tests.py b/tests/nested_foreign_keys/tests.py index 34a3703e6810..098023d23ab6 100644 --- a/tests/nested_foreign_keys/tests.py +++ b/tests/nested_foreign_keys/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import TestCase from .models import ( diff --git a/tests/null_fk/tests.py b/tests/null_fk/tests.py index 19b285e32ada..e587d6551b96 100644 --- a/tests/null_fk/tests.py +++ b/tests/null_fk/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db.models import Q from django.test import TestCase diff --git a/tests/null_fk_ordering/models.py b/tests/null_fk_ordering/models.py index 0bac5e1ab78e..e65c227f88c5 100644 --- a/tests/null_fk_ordering/models.py +++ b/tests/null_fk_ordering/models.py @@ -5,8 +5,6 @@ unexpected results """ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/null_fk_ordering/tests.py b/tests/null_fk_ordering/tests.py index 7215118b9456..897c03063fbc 100644 --- a/tests/null_fk_ordering/tests.py +++ b/tests/null_fk_ordering/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import TestCase from .models import Article, Author, Comment, Forum, Post, SystemInfo diff --git a/tests/null_queries/models.py b/tests/null_queries/models.py index 8d915ba11f97..b40f4539b37a 100644 --- a/tests/null_queries/models.py +++ b/tests/null_queries/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/null_queries/tests.py b/tests/null_queries/tests.py index 8f58b9dee14c..547b586e006c 100644 --- a/tests/null_queries/tests.py +++ b/tests/null_queries/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.exceptions import FieldError from django.test import TestCase diff --git a/tests/one_to_one/models.py b/tests/one_to_one/models.py index 0f4aa70f6c8f..c58114dce8d5 100644 --- a/tests/one_to_one/models.py +++ b/tests/one_to_one/models.py @@ -5,8 +5,6 @@ In this example, a ``Place`` optionally can be a ``Restaurant``. """ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/one_to_one/tests.py b/tests/one_to_one/tests.py index 3d98d78c27ca..2fb118538d07 100644 --- a/tests/one_to_one/tests.py +++ b/tests/one_to_one/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import IntegrityError, connection, transaction from django.test import TestCase diff --git a/tests/or_lookups/tests.py b/tests/or_lookups/tests.py index 5e8b3dd69481..dd93ed7efc71 100644 --- a/tests/or_lookups/tests.py +++ b/tests/or_lookups/tests.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - from datetime import datetime from operator import attrgetter diff --git a/tests/order_with_respect_to/base_tests.py b/tests/order_with_respect_to/base_tests.py index ed80ab13e52f..ad8925bf8892 100644 --- a/tests/order_with_respect_to/base_tests.py +++ b/tests/order_with_respect_to/base_tests.py @@ -2,8 +2,6 @@ The tests are shared with contenttypes_tests and so shouldn't import or reference any models directly. Subclasses should inherit django.test.TestCase. """ -from __future__ import unicode_literals - from operator import attrgetter diff --git a/tests/order_with_respect_to/tests.py b/tests/order_with_respect_to/tests.py index 7788fe3368c4..a047516caac1 100644 --- a/tests/order_with_respect_to/tests.py +++ b/tests/order_with_respect_to/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from operator import attrgetter from django.db import models diff --git a/tests/ordering/tests.py b/tests/ordering/tests.py index 399b8d70351a..de49626cf455 100644 --- a/tests/ordering/tests.py +++ b/tests/ordering/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import datetime from operator import attrgetter diff --git a/tests/pagination/tests.py b/tests/pagination/tests.py index 888cb813b081..fe967631ab0b 100644 --- a/tests/pagination/tests.py +++ b/tests/pagination/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import unittest from datetime import datetime diff --git a/tests/postgres_tests/array_default_migrations/0001_initial.py b/tests/postgres_tests/array_default_migrations/0001_initial.py index ebda628a5b53..eb523218ef10 100644 --- a/tests/postgres_tests/array_default_migrations/0001_initial.py +++ b/tests/postgres_tests/array_default_migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import django.contrib.postgres.fields from django.db import migrations, models diff --git a/tests/postgres_tests/array_default_migrations/0002_integerarraymodel_field_2.py b/tests/postgres_tests/array_default_migrations/0002_integerarraymodel_field_2.py index 9526a96735d1..679c9bb0d339 100644 --- a/tests/postgres_tests/array_default_migrations/0002_integerarraymodel_field_2.py +++ b/tests/postgres_tests/array_default_migrations/0002_integerarraymodel_field_2.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import django.contrib.postgres.fields from django.db import migrations, models diff --git a/tests/postgres_tests/array_index_migrations/0001_initial.py b/tests/postgres_tests/array_index_migrations/0001_initial.py index 10c1780a46a0..505e53e4e884 100644 --- a/tests/postgres_tests/array_index_migrations/0001_initial.py +++ b/tests/postgres_tests/array_index_migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import django.contrib.postgres.fields from django.db import migrations, models diff --git a/tests/postgres_tests/migrations/0001_setup_extensions.py b/tests/postgres_tests/migrations/0001_setup_extensions.py index 41628030b7fe..7add08c49915 100644 --- a/tests/postgres_tests/migrations/0001_setup_extensions.py +++ b/tests/postgres_tests/migrations/0001_setup_extensions.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations try: diff --git a/tests/postgres_tests/migrations/0002_create_test_models.py b/tests/postgres_tests/migrations/0002_create_test_models.py index 8f72183f5c69..489bedf29804 100644 --- a/tests/postgres_tests/migrations/0002_create_test_models.py +++ b/tests/postgres_tests/migrations/0002_create_test_models.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.core.serializers.json import DjangoJSONEncoder from django.db import migrations, models diff --git a/tests/postgres_tests/test_hstore.py b/tests/postgres_tests/test_hstore.py index 0fc427f67c06..2c6f93f1f641 100644 --- a/tests/postgres_tests/test_hstore.py +++ b/tests/postgres_tests/test_hstore.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import json from django.core import exceptions, serializers diff --git a/tests/postgres_tests/test_json.py b/tests/postgres_tests/test_json.py index 4e8851d4853b..2506fc36d625 100644 --- a/tests/postgres_tests/test_json.py +++ b/tests/postgres_tests/test_json.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import uuid from decimal import Decimal diff --git a/tests/postgres_tests/test_unaccent.py b/tests/postgres_tests/test_unaccent.py index e1e41710628b..018aedb64c89 100644 --- a/tests/postgres_tests/test_unaccent.py +++ b/tests/postgres_tests/test_unaccent.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.test import modify_settings from . import PostgreSQLTestCase diff --git a/tests/prefetch_related/test_uuid.py b/tests/prefetch_related/test_uuid.py index 08930fc5f458..11a2474f4ac3 100644 --- a/tests/prefetch_related/test_uuid.py +++ b/tests/prefetch_related/test_uuid.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import TestCase from .models import Flea, House, Person, Pet, Room diff --git a/tests/prefetch_related/tests.py b/tests/prefetch_related/tests.py index a6b5fd5cd302..126a8bc03598 100644 --- a/tests/prefetch_related/tests.py +++ b/tests/prefetch_related/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist from django.db import connection diff --git a/tests/properties/tests.py b/tests/properties/tests.py index 175bf0eb8323..a50a82595383 100644 --- a/tests/properties/tests.py +++ b/tests/properties/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import TestCase from .models import Person diff --git a/tests/proxy_model_inheritance/tests.py b/tests/proxy_model_inheritance/tests.py index b4b1c134351c..9bf8f1c04c5d 100644 --- a/tests/proxy_model_inheritance/tests.py +++ b/tests/proxy_model_inheritance/tests.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, unicode_literals - import os from django.core.management import call_command diff --git a/tests/proxy_models/tests.py b/tests/proxy_models/tests.py index 96d3c0914f7d..5fdfbfb6bf9f 100644 --- a/tests/proxy_models/tests.py +++ b/tests/proxy_models/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib import admin from django.contrib.auth.models import User as AuthUser from django.contrib.contenttypes.models import ContentType diff --git a/tests/queries/models.py b/tests/queries/models.py index 67a28e950ebc..8c1ba59b67cb 100644 --- a/tests/queries/models.py +++ b/tests/queries/models.py @@ -1,8 +1,6 @@ """ Various complex queries that have been problematic in the past. """ -from __future__ import unicode_literals - import threading from django.db import models diff --git a/tests/queries/test_qs_combinators.py b/tests/queries/test_qs_combinators.py index a0faab2eb79a..02a0df216d06 100644 --- a/tests/queries/test_qs_combinators.py +++ b/tests/queries/test_qs_combinators.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db.models import F, IntegerField, Value from django.db.utils import DatabaseError from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature diff --git a/tests/queries/tests.py b/tests/queries/tests.py index b0999be3f8e3..e2dd86bac185 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import pickle import unittest diff --git a/tests/queryset_pickle/tests.py b/tests/queryset_pickle/tests.py index d95878966a4b..9333e96fc300 100644 --- a/tests/queryset_pickle/tests.py +++ b/tests/queryset_pickle/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import pickle import unittest diff --git a/tests/raw_query/tests.py b/tests/raw_query/tests.py index 360dd31d5f9f..26b57dc13957 100644 --- a/tests/raw_query/tests.py +++ b/tests/raw_query/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import date from decimal import Decimal diff --git a/tests/requests/tests.py b/tests/requests/tests.py index 27dc439e5f63..c5a148ffbb12 100644 --- a/tests/requests/tests.py +++ b/tests/requests/tests.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - import time from datetime import datetime, timedelta from io import BytesIO diff --git a/tests/reserved_names/tests.py b/tests/reserved_names/tests.py index 429bb01e2d2e..7e2510cd97f2 100644 --- a/tests/reserved_names/tests.py +++ b/tests/reserved_names/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from django.test import TestCase diff --git a/tests/resolve_url/tests.py b/tests/resolve_url/tests.py index d56e08c97c5a..73556a93beac 100644 --- a/tests/resolve_url/tests.py +++ b/tests/resolve_url/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.shortcuts import resolve_url from django.test import SimpleTestCase, override_settings from django.urls import NoReverseMatch, reverse_lazy diff --git a/tests/responses/tests.py b/tests/responses/tests.py index 5dba0e04cbbd..8adf092ca0ec 100644 --- a/tests/responses/tests.py +++ b/tests/responses/tests.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - import io from django.conf import settings diff --git a/tests/reverse_lookup/tests.py b/tests/reverse_lookup/tests.py index dda3c29691a8..0e0093f38ea6 100644 --- a/tests/reverse_lookup/tests.py +++ b/tests/reverse_lookup/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.exceptions import FieldError from django.test import TestCase diff --git a/tests/save_delete_hooks/models.py b/tests/save_delete_hooks/models.py index e6a155a8e7b4..3d229daadad0 100644 --- a/tests/save_delete_hooks/models.py +++ b/tests/save_delete_hooks/models.py @@ -4,8 +4,6 @@ To execute arbitrary code around ``save()`` and ``delete()``, just subclass the methods. """ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/save_delete_hooks/tests.py b/tests/save_delete_hooks/tests.py index 0fd1ed4e0382..e0cb2f51ab43 100644 --- a/tests/save_delete_hooks/tests.py +++ b/tests/save_delete_hooks/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import TestCase from django.utils import six diff --git a/tests/select_for_update/tests.py b/tests/select_for_update/tests.py index 9e5ee598b0b8..722412454671 100644 --- a/tests/select_for_update/tests.py +++ b/tests/select_for_update/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import threading import time diff --git a/tests/select_related/tests.py b/tests/select_related/tests.py index d6c0c850dff1..04f762f6572a 100644 --- a/tests/select_related/tests.py +++ b/tests/select_related/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.exceptions import FieldError from django.test import SimpleTestCase, TestCase diff --git a/tests/select_related_onetoone/tests.py b/tests/select_related_onetoone/tests.py index a7d646e25d90..5868dc807c31 100644 --- a/tests/select_related_onetoone/tests.py +++ b/tests/select_related_onetoone/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.exceptions import FieldError from django.test import SimpleTestCase, TestCase diff --git a/tests/select_related_regress/models.py b/tests/select_related_regress/models.py index 8e748d3eef92..4ac8cc15182a 100644 --- a/tests/select_related_regress/models.py +++ b/tests/select_related_regress/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/select_related_regress/tests.py b/tests/select_related_regress/tests.py index 6c59192d2a9c..bb5f7774a3e7 100644 --- a/tests/select_related_regress/tests.py +++ b/tests/select_related_regress/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import TestCase from django.utils import six diff --git a/tests/serializers/models/base.py b/tests/serializers/models/base.py index 4889377e0981..5f9bdd833cd9 100644 --- a/tests/serializers/models/base.py +++ b/tests/serializers/models/base.py @@ -4,8 +4,6 @@ ``django.core.serializers`` provides interfaces to converting Django ``QuerySet`` objects to and from "flat" data (i.e. strings). """ -from __future__ import unicode_literals - from decimal import Decimal from django.db import models diff --git a/tests/serializers/models/data.py b/tests/serializers/models/data.py index 9c44d97e6b71..f6a1d108f6ca 100644 --- a/tests/serializers/models/data.py +++ b/tests/serializers/models/data.py @@ -4,8 +4,6 @@ NULL values, where allowed. The basic idea is to have a model for each Django data type. """ -from __future__ import unicode_literals - from django.contrib.contenttypes.fields import ( GenericForeignKey, GenericRelation, ) diff --git a/tests/serializers/test_data.py b/tests/serializers/test_data.py index f9cb9582fe30..2e9527f982b6 100644 --- a/tests/serializers/test_data.py +++ b/tests/serializers/test_data.py @@ -6,8 +6,6 @@ the serializers. This includes all valid data values, plus forward, backwards and self references. """ -from __future__ import unicode_literals - import datetime import decimal import uuid diff --git a/tests/serializers/test_json.py b/tests/serializers/test_json.py index b191ce664408..7713e0c3c408 100644 --- a/tests/serializers/test_json.py +++ b/tests/serializers/test_json.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime import decimal import json diff --git a/tests/serializers/test_natural.py b/tests/serializers/test_natural.py index 1a4f4d5ea05d..c4e2bedf1793 100644 --- a/tests/serializers/test_natural.py +++ b/tests/serializers/test_natural.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core import serializers from django.db import connection from django.test import TestCase diff --git a/tests/serializers/test_xml.py b/tests/serializers/test_xml.py index e516444c9571..71b38d48fa89 100644 --- a/tests/serializers/test_xml.py +++ b/tests/serializers/test_xml.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from xml.dom import minidom from django.core import serializers diff --git a/tests/serializers/test_yaml.py b/tests/serializers/test_yaml.py index 0b4b9b00d1b3..038227efeaea 100644 --- a/tests/serializers/test_yaml.py +++ b/tests/serializers/test_yaml.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import importlib import unittest diff --git a/tests/serializers/tests.py b/tests/serializers/tests.py index f765aea81568..656bc4b4db2c 100644 --- a/tests/serializers/tests.py +++ b/tests/serializers/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from datetime import datetime from django.core import serializers diff --git a/tests/servers/tests.py b/tests/servers/tests.py index 03e05d0957e8..ff1d4aff8c73 100644 --- a/tests/servers/tests.py +++ b/tests/servers/tests.py @@ -1,9 +1,6 @@ -# -*- encoding: utf-8 -*- """ Tests for django.core.servers. """ -from __future__ import unicode_literals - import contextlib import errno import os diff --git a/tests/signals/models.py b/tests/signals/models.py index 2f76343ecf13..4f8d72817c37 100644 --- a/tests/signals/models.py +++ b/tests/signals/models.py @@ -1,8 +1,6 @@ """ Testing signals before/after saving and deleting. """ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/signals/tests.py b/tests/signals/tests.py index 7fd04df36a88..9cb470b8cfe5 100644 --- a/tests/signals/tests.py +++ b/tests/signals/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.apps.registry import Apps from django.db import models from django.db.models import signals diff --git a/tests/signed_cookies_tests/tests.py b/tests/signed_cookies_tests/tests.py index 15b0a7c033c0..b7ea902bf49e 100644 --- a/tests/signed_cookies_tests/tests.py +++ b/tests/signed_cookies_tests/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core import signing from django.http import HttpRequest, HttpResponse from django.test import SimpleTestCase, override_settings diff --git a/tests/signing/tests.py b/tests/signing/tests.py index e2677dfc1e54..c6145d09cb37 100644 --- a/tests/signing/tests.py +++ b/tests/signing/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from django.core import signing diff --git a/tests/sitemaps_tests/test_generic.py b/tests/sitemaps_tests/test_generic.py index 96736c261ac6..db426e557feb 100644 --- a/tests/sitemaps_tests/test_generic.py +++ b/tests/sitemaps_tests/test_generic.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import override_settings from .base import SitemapTestsBase diff --git a/tests/sitemaps_tests/test_http.py b/tests/sitemaps_tests/test_http.py index 8367b495d87c..ec7d2be80f5d 100644 --- a/tests/sitemaps_tests/test_http.py +++ b/tests/sitemaps_tests/test_http.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os from datetime import date from unittest import skipUnless diff --git a/tests/sitemaps_tests/test_https.py b/tests/sitemaps_tests/test_https.py index 3b68baac43ac..ac6477f7a879 100644 --- a/tests/sitemaps_tests/test_https.py +++ b/tests/sitemaps_tests/test_https.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import date from django.test import override_settings diff --git a/tests/sites_framework/migrations/0001_initial.py b/tests/sites_framework/migrations/0001_initial.py index 78d26cab317b..f4a2ba9460ca 100644 --- a/tests/sites_framework/migrations/0001_initial.py +++ b/tests/sites_framework/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/tests/sites_tests/tests.py b/tests/sites_tests/tests.py index 3ea66be9bb5f..0179500f14d5 100644 --- a/tests/sites_tests/tests.py +++ b/tests/sites_tests/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.apps import apps from django.apps.registry import Apps from django.conf import settings diff --git a/tests/staticfiles_tests/cases.py b/tests/staticfiles_tests/cases.py index 009672ee1233..f278e6a97449 100644 --- a/tests/staticfiles_tests/cases.py +++ b/tests/staticfiles_tests/cases.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - import codecs import os import shutil diff --git a/tests/staticfiles_tests/settings.py b/tests/staticfiles_tests/settings.py index caf42b2505e5..c9bf851db7d2 100644 --- a/tests/staticfiles_tests/settings.py +++ b/tests/staticfiles_tests/settings.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os.path from django.utils._os import upath diff --git a/tests/staticfiles_tests/test_finders.py b/tests/staticfiles_tests/test_finders.py index 7355113ad617..0f5cf5bea213 100644 --- a/tests/staticfiles_tests/test_finders.py +++ b/tests/staticfiles_tests/test_finders.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os from django.conf import settings diff --git a/tests/staticfiles_tests/test_management.py b/tests/staticfiles_tests/test_management.py index bbb8567c2a1e..ad608ea24b94 100644 --- a/tests/staticfiles_tests/test_management.py +++ b/tests/staticfiles_tests/test_management.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import codecs import datetime import os diff --git a/tests/staticfiles_tests/test_storage.py b/tests/staticfiles_tests/test_storage.py index 4e1dec84f950..d1b7a49626ff 100644 --- a/tests/staticfiles_tests/test_storage.py +++ b/tests/staticfiles_tests/test_storage.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os import shutil import sys diff --git a/tests/staticfiles_tests/test_templatetags.py b/tests/staticfiles_tests/test_templatetags.py index 541b233855ad..cd3f7d4bfa5e 100644 --- a/tests/staticfiles_tests/test_templatetags.py +++ b/tests/staticfiles_tests/test_templatetags.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import override_settings from .cases import StaticFilesTestCase diff --git a/tests/staticfiles_tests/test_views.py b/tests/staticfiles_tests/test_views.py index 6d9096784f4c..fa817a6ef155 100644 --- a/tests/staticfiles_tests/test_views.py +++ b/tests/staticfiles_tests/test_views.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import posixpath from django.conf import settings diff --git a/tests/str/models.py b/tests/str/models.py index e606e912aab6..33e31857fae1 100644 --- a/tests/str/models.py +++ b/tests/str/models.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Adding __str__() or __unicode__() to models diff --git a/tests/str/tests.py b/tests/str/tests.py index 08fd554e5ecb..516560415cc3 100644 --- a/tests/str/tests.py +++ b/tests/str/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime from unittest import skipIf diff --git a/tests/string_lookup/models.py b/tests/string_lookup/models.py index 775ec2faf001..e8fd8a1b1217 100644 --- a/tests/string_lookup/models.py +++ b/tests/string_lookup/models.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/string_lookup/tests.py b/tests/string_lookup/tests.py index 805833a8e483..22b0c6b9cfa9 100644 --- a/tests/string_lookup/tests.py +++ b/tests/string_lookup/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.test import TestCase from .models import Article, Bar, Base, Child, Foo, Whiz diff --git a/tests/swappable_models/tests.py b/tests/swappable_models/tests.py index 548c7b328610..b67aece8c087 100644 --- a/tests/swappable_models/tests.py +++ b/tests/swappable_models/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from swappable_models.models import Article from django.contrib.auth.models import Permission diff --git a/tests/syndication_tests/feeds.py b/tests/syndication_tests/feeds.py index f4162b345e63..87c8d962b74b 100644 --- a/tests/syndication_tests/feeds.py +++ b/tests/syndication_tests/feeds.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib.syndication import views from django.utils import feedgenerator from django.utils.timezone import get_fixed_timezone diff --git a/tests/syndication_tests/tests.py b/tests/syndication_tests/tests.py index 0fb860474cf5..c9baa6537bd3 100644 --- a/tests/syndication_tests/tests.py +++ b/tests/syndication_tests/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from xml.dom import minidom diff --git a/tests/template_backends/test_dummy.py b/tests/template_backends/test_dummy.py index 83b42c7eb4bf..dededfe390a1 100644 --- a/tests/template_backends/test_dummy.py +++ b/tests/template_backends/test_dummy.py @@ -1,7 +1,3 @@ -# coding: utf-8 - -from __future__ import unicode_literals - import re from django.forms import CharField, Form, Media diff --git a/tests/template_backends/test_jinja2.py b/tests/template_backends/test_jinja2.py index a79c6bc4603f..117719fa0d20 100644 --- a/tests/template_backends/test_jinja2.py +++ b/tests/template_backends/test_jinja2.py @@ -1,7 +1,3 @@ -# Since this package contains a "jinja2" directory, this is required to -# silence an ImportWarning warning on Python 2. -from __future__ import absolute_import - from unittest import skipIf from django.template import TemplateSyntaxError diff --git a/tests/template_tests/filter_tests/test_escapejs.py b/tests/template_tests/filter_tests/test_escapejs.py index ccb9cd3c0fa0..3b038726b296 100644 --- a/tests/template_tests/filter_tests/test_escapejs.py +++ b/tests/template_tests/filter_tests/test_escapejs.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.template.defaultfilters import escapejs_filter from django.test import SimpleTestCase from django.utils import six diff --git a/tests/template_tests/filter_tests/test_filesizeformat.py b/tests/template_tests/filter_tests/test_filesizeformat.py index 9d143ca10015..2e425af8ac69 100644 --- a/tests/template_tests/filter_tests/test_filesizeformat.py +++ b/tests/template_tests/filter_tests/test_filesizeformat.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.template.defaultfilters import filesizeformat from django.test import SimpleTestCase from django.utils import translation diff --git a/tests/template_tests/filter_tests/test_floatformat.py b/tests/template_tests/filter_tests/test_floatformat.py index b1ffbe56c1b5..d4a4526d1dde 100644 --- a/tests/template_tests/filter_tests/test_floatformat.py +++ b/tests/template_tests/filter_tests/test_floatformat.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from decimal import Decimal, localcontext from django.template.defaultfilters import floatformat diff --git a/tests/template_tests/filter_tests/test_force_escape.py b/tests/template_tests/filter_tests/test_force_escape.py index 45f4efde6259..776dc8042d74 100644 --- a/tests/template_tests/filter_tests/test_force_escape.py +++ b/tests/template_tests/filter_tests/test_force_escape.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.template.defaultfilters import force_escape from django.test import SimpleTestCase from django.utils.safestring import SafeData diff --git a/tests/template_tests/filter_tests/test_iriencode.py b/tests/template_tests/filter_tests/test_iriencode.py index 837d6aa0f722..7d83b67f9df0 100644 --- a/tests/template_tests/filter_tests/test_iriencode.py +++ b/tests/template_tests/filter_tests/test_iriencode.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.template.defaultfilters import iriencode, urlencode from django.test import SimpleTestCase from django.utils.safestring import mark_safe diff --git a/tests/template_tests/filter_tests/test_lower.py b/tests/template_tests/filter_tests/test_lower.py index 974664387513..1db934c5fac0 100644 --- a/tests/template_tests/filter_tests/test_lower.py +++ b/tests/template_tests/filter_tests/test_lower.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.template.defaultfilters import lower from django.test import SimpleTestCase from django.utils.safestring import mark_safe diff --git a/tests/template_tests/filter_tests/test_slugify.py b/tests/template_tests/filter_tests/test_slugify.py index 5852417b2ec4..ec9f2bb73670 100644 --- a/tests/template_tests/filter_tests/test_slugify.py +++ b/tests/template_tests/filter_tests/test_slugify.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.template.defaultfilters import slugify from django.test import SimpleTestCase from django.utils import six diff --git a/tests/template_tests/filter_tests/test_timesince.py b/tests/template_tests/filter_tests/test_timesince.py index 0cb975a90ed0..1936a1d44f40 100644 --- a/tests/template_tests/filter_tests/test_timesince.py +++ b/tests/template_tests/filter_tests/test_timesince.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import datetime, timedelta from django.template.defaultfilters import timesince_filter diff --git a/tests/template_tests/filter_tests/test_timeuntil.py b/tests/template_tests/filter_tests/test_timeuntil.py index 1b06a21c937a..011b0a2e920e 100644 --- a/tests/template_tests/filter_tests/test_timeuntil.py +++ b/tests/template_tests/filter_tests/test_timeuntil.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import datetime, timedelta from django.template.defaultfilters import timeuntil_filter diff --git a/tests/template_tests/filter_tests/test_title.py b/tests/template_tests/filter_tests/test_title.py index cf4d1033c636..08a5fb0de405 100644 --- a/tests/template_tests/filter_tests/test_title.py +++ b/tests/template_tests/filter_tests/test_title.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.template.defaultfilters import title from django.test import SimpleTestCase diff --git a/tests/template_tests/filter_tests/test_truncatechars_html.py b/tests/template_tests/filter_tests/test_truncatechars_html.py index cf2623d74050..e225a319f5d3 100644 --- a/tests/template_tests/filter_tests/test_truncatechars_html.py +++ b/tests/template_tests/filter_tests/test_truncatechars_html.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.template.defaultfilters import truncatechars_html from django.test import SimpleTestCase diff --git a/tests/template_tests/filter_tests/test_truncatewords_html.py b/tests/template_tests/filter_tests/test_truncatewords_html.py index aec2abf2d4d0..32ef41302842 100644 --- a/tests/template_tests/filter_tests/test_truncatewords_html.py +++ b/tests/template_tests/filter_tests/test_truncatewords_html.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.template.defaultfilters import truncatewords_html from django.test import SimpleTestCase diff --git a/tests/template_tests/filter_tests/test_upper.py b/tests/template_tests/filter_tests/test_upper.py index f9c52bc0f8d1..a9efaf5322e1 100644 --- a/tests/template_tests/filter_tests/test_upper.py +++ b/tests/template_tests/filter_tests/test_upper.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.template.defaultfilters import upper from django.test import SimpleTestCase from django.utils.safestring import mark_safe diff --git a/tests/template_tests/filter_tests/test_urlencode.py b/tests/template_tests/filter_tests/test_urlencode.py index 82199f8f1cdf..d095bb8fae67 100644 --- a/tests/template_tests/filter_tests/test_urlencode.py +++ b/tests/template_tests/filter_tests/test_urlencode.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.template.defaultfilters import urlencode from django.test import SimpleTestCase diff --git a/tests/template_tests/filter_tests/test_urlize.py b/tests/template_tests/filter_tests/test_urlize.py index 6822092943c7..3096213a2277 100644 --- a/tests/template_tests/filter_tests/test_urlize.py +++ b/tests/template_tests/filter_tests/test_urlize.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.template.defaultfilters import urlize from django.test import SimpleTestCase from django.utils import six diff --git a/tests/template_tests/syntax_tests/i18n/base.py b/tests/template_tests/syntax_tests/i18n/base.py index b8c083d53684..690e5d3933ea 100644 --- a/tests/template_tests/syntax_tests/i18n/base.py +++ b/tests/template_tests/syntax_tests/i18n/base.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os from django.conf import settings diff --git a/tests/template_tests/syntax_tests/i18n/test_blocktrans.py b/tests/template_tests/syntax_tests/i18n/test_blocktrans.py index 552c08b0381c..9af60e5131e4 100644 --- a/tests/template_tests/syntax_tests/i18n/test_blocktrans.py +++ b/tests/template_tests/syntax_tests/i18n/test_blocktrans.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import os from threading import local diff --git a/tests/template_tests/syntax_tests/i18n/test_filters.py b/tests/template_tests/syntax_tests/i18n/test_filters.py index 6a5a3fd1d529..cf8e4573c302 100644 --- a/tests/template_tests/syntax_tests/i18n/test_filters.py +++ b/tests/template_tests/syntax_tests/i18n/test_filters.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.test import SimpleTestCase from django.utils import translation diff --git a/tests/template_tests/syntax_tests/i18n/test_get_available_languages.py b/tests/template_tests/syntax_tests/i18n/test_get_available_languages.py index 187aa4e7abaa..0be5a79528cd 100644 --- a/tests/template_tests/syntax_tests/i18n/test_get_available_languages.py +++ b/tests/template_tests/syntax_tests/i18n/test_get_available_languages.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import SimpleTestCase from ...utils import setup diff --git a/tests/template_tests/syntax_tests/i18n/test_get_language_info.py b/tests/template_tests/syntax_tests/i18n/test_get_language_info.py index f555f67b7a86..bc89c65fddbc 100644 --- a/tests/template_tests/syntax_tests/i18n/test_get_language_info.py +++ b/tests/template_tests/syntax_tests/i18n/test_get_language_info.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.test import SimpleTestCase from django.utils import translation diff --git a/tests/template_tests/syntax_tests/i18n/test_get_language_info_list.py b/tests/template_tests/syntax_tests/i18n/test_get_language_info_list.py index 4b782c94d691..4572f41f1482 100644 --- a/tests/template_tests/syntax_tests/i18n/test_get_language_info_list.py +++ b/tests/template_tests/syntax_tests/i18n/test_get_language_info_list.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.test import SimpleTestCase from django.utils import translation diff --git a/tests/template_tests/syntax_tests/i18n/test_trans.py b/tests/template_tests/syntax_tests/i18n/test_trans.py index dd3860817556..fec9f1728d70 100644 --- a/tests/template_tests/syntax_tests/i18n/test_trans.py +++ b/tests/template_tests/syntax_tests/i18n/test_trans.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from threading import local from django.template import Context, Template, TemplateSyntaxError diff --git a/tests/template_tests/syntax_tests/i18n/test_underscore_syntax.py b/tests/template_tests/syntax_tests/i18n/test_underscore_syntax.py index aed204d63b17..38d929e21421 100644 --- a/tests/template_tests/syntax_tests/i18n/test_underscore_syntax.py +++ b/tests/template_tests/syntax_tests/i18n/test_underscore_syntax.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.template import Context, Template from django.test import SimpleTestCase from django.utils import translation diff --git a/tests/template_tests/syntax_tests/test_filter_syntax.py b/tests/template_tests/syntax_tests/test_filter_syntax.py index 3e524a61eb9b..c8d764659afa 100644 --- a/tests/template_tests/syntax_tests/test_filter_syntax.py +++ b/tests/template_tests/syntax_tests/test_filter_syntax.py @@ -1,6 +1,3 @@ -# coding: utf-8 -from __future__ import unicode_literals - from django.template import TemplateSyntaxError from django.test import SimpleTestCase diff --git a/tests/template_tests/syntax_tests/test_url.py b/tests/template_tests/syntax_tests/test_url.py index e6e20d08f361..2103ba61598d 100644 --- a/tests/template_tests/syntax_tests/test_url.py +++ b/tests/template_tests/syntax_tests/test_url.py @@ -1,4 +1,3 @@ -# coding: utf-8 from django.template import RequestContext, TemplateSyntaxError from django.test import RequestFactory, SimpleTestCase, override_settings from django.urls import NoReverseMatch, resolve diff --git a/tests/template_tests/test_callables.py b/tests/template_tests/test_callables.py index b7ce2944033b..4cfb49db5c6a 100644 --- a/tests/template_tests/test_callables.py +++ b/tests/template_tests/test_callables.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from unittest import TestCase from django.template import Context, Engine diff --git a/tests/template_tests/test_context.py b/tests/template_tests/test_context.py index 41e469eaabda..5cd2ec2e820a 100644 --- a/tests/template_tests/test_context.py +++ b/tests/template_tests/test_context.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from django.http import HttpRequest from django.template import ( Context, Engine, RequestContext, Template, Variable, VariableDoesNotExist, diff --git a/tests/template_tests/test_custom.py b/tests/template_tests/test_custom.py index b63882a9a865..df8ea17fb0ec 100644 --- a/tests/template_tests/test_custom.py +++ b/tests/template_tests/test_custom.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os from unittest import skipUnless diff --git a/tests/template_tests/test_loaders.py b/tests/template_tests/test_loaders.py index 5f5092352435..6e9b6eb453b1 100644 --- a/tests/template_tests/test_loaders.py +++ b/tests/template_tests/test_loaders.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import os.path import sys import tempfile diff --git a/tests/template_tests/test_logging.py b/tests/template_tests/test_logging.py index a11af3c02d1f..9dd804640887 100644 --- a/tests/template_tests/test_logging.py +++ b/tests/template_tests/test_logging.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import logging from django.template import Context, Engine, Variable, VariableDoesNotExist diff --git a/tests/template_tests/test_parser.py b/tests/template_tests/test_parser.py index c6800f68dc3d..3b59424f4783 100644 --- a/tests/template_tests/test_parser.py +++ b/tests/template_tests/test_parser.py @@ -1,8 +1,6 @@ """ Testing some internals of the template processing. These are *not* examples to be copied in user code. """ -from __future__ import unicode_literals - from django.template import Library, TemplateSyntaxError from django.template.base import ( TOKEN_BLOCK, FilterExpression, Parser, Token, Variable, diff --git a/tests/template_tests/test_response.py b/tests/template_tests/test_response.py index fa851a93f297..62cd14799dc6 100644 --- a/tests/template_tests/test_response.py +++ b/tests/template_tests/test_response.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import pickle import time from datetime import datetime diff --git a/tests/template_tests/test_unicode.py b/tests/template_tests/test_unicode.py index 169f15a6ed97..f6471e72e0de 100644 --- a/tests/template_tests/test_unicode.py +++ b/tests/template_tests/test_unicode.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from unittest import TestCase from django.template import Context, Engine diff --git a/tests/template_tests/tests.py b/tests/template_tests/tests.py index 50ddee66743e..3ab215c094c2 100644 --- a/tests/template_tests/tests.py +++ b/tests/template_tests/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import sys from django.contrib.auth.models import Group diff --git a/tests/template_tests/urls.py b/tests/template_tests/urls.py index b0304e1c5451..a367696d43be 100644 --- a/tests/template_tests/urls.py +++ b/tests/template_tests/urls.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.conf.urls import include, url from . import views diff --git a/tests/template_tests/utils.py b/tests/template_tests/utils.py index 1747f080bc8f..cbc452c808e5 100644 --- a/tests/template_tests/utils.py +++ b/tests/template_tests/utils.py @@ -1,7 +1,3 @@ -# coding: utf-8 - -from __future__ import unicode_literals - import functools import os diff --git a/tests/test_client/test_conditional_content_removal.py b/tests/test_client/test_conditional_content_removal.py index 644eb23a066e..72bf7f238bb9 100644 --- a/tests/test_client/test_conditional_content_removal.py +++ b/tests/test_client/test_conditional_content_removal.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import gzip import io diff --git a/tests/test_client/tests.py b/tests/test_client/tests.py index 8b834e02e057..5981ca319e0b 100644 --- a/tests/test_client/tests.py +++ b/tests/test_client/tests.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Testing using the Test Client @@ -20,8 +19,6 @@ rather than the HTML rendered to the end-user. """ -from __future__ import unicode_literals - import tempfile from django.contrib.auth.models import User diff --git a/tests/test_client_regress/tests.py b/tests/test_client_regress/tests.py index 5598ed5280ec..0436ae99680d 100644 --- a/tests/test_client_regress/tests.py +++ b/tests/test_client_regress/tests.py @@ -1,9 +1,6 @@ -# -*- coding: utf-8 -*- """ Regression tests for the Test Client, especially the customized assertions. """ -from __future__ import unicode_literals - import itertools import os diff --git a/tests/test_runner/tests.py b/tests/test_runner/tests.py index d6e9af71a1b2..670bc6683ce3 100644 --- a/tests/test_runner/tests.py +++ b/tests/test_runner/tests.py @@ -1,8 +1,6 @@ """ Tests for django test runner """ -from __future__ import unicode_literals - import unittest from admin_scripts.tests import AdminScriptTestCase diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py index 2a199ec5bceb..e63c6774ae69 100644 --- a/tests/test_utils/tests.py +++ b/tests/test_utils/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import sys import unittest diff --git a/tests/timezones/tests.py b/tests/timezones/tests.py index 8f9bd23241de..7f7c8228e810 100644 --- a/tests/timezones/tests.py +++ b/tests/timezones/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import re import sys diff --git a/tests/transactions/models.py b/tests/transactions/models.py index f4400363e568..4154b3912307 100644 --- a/tests/transactions/models.py +++ b/tests/transactions/models.py @@ -6,8 +6,6 @@ commit-on-success behavior. Alternatively, you can manage the transaction manually. """ -from __future__ import unicode_literals - from django.db import models from django.utils.encoding import python_2_unicode_compatible diff --git a/tests/transactions/tests.py b/tests/transactions/tests.py index 7dc21cca4f66..12d2eb299dbf 100644 --- a/tests/transactions/tests.py +++ b/tests/transactions/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os import signal import sys diff --git a/tests/unmanaged_models/tests.py b/tests/unmanaged_models/tests.py index e98cee8ae178..250aaaa4354b 100644 --- a/tests/unmanaged_models/tests.py +++ b/tests/unmanaged_models/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import connection from django.test import TestCase diff --git a/tests/update/tests.py b/tests/update/tests.py index ca1c5ac4f972..55a8e24c6ac1 100644 --- a/tests/update/tests.py +++ b/tests/update/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.exceptions import FieldError from django.db.models import Count, F, Max from django.test import TestCase diff --git a/tests/update_only_fields/tests.py b/tests/update_only_fields/tests.py index 7627bcd378eb..743b5fda8d95 100644 --- a/tests/update_only_fields/tests.py +++ b/tests/update_only_fields/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db.models.signals import post_save, pre_save from django.test import TestCase diff --git a/tests/urlpatterns_reverse/test_localeregexprovider.py b/tests/urlpatterns_reverse/test_localeregexprovider.py index 401e9a1ad03f..53dc744c772c 100644 --- a/tests/urlpatterns_reverse/test_localeregexprovider.py +++ b/tests/urlpatterns_reverse/test_localeregexprovider.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import os from django.core.exceptions import ImproperlyConfigured diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py index 5f824469fa8f..a84e5bfb2462 100644 --- a/tests/urlpatterns_reverse/tests.py +++ b/tests/urlpatterns_reverse/tests.py @@ -1,9 +1,6 @@ -# -*- coding: utf-8 -*- """ Unit tests for reverse URL lookups. """ -from __future__ import unicode_literals - import sys import threading import unittest diff --git a/tests/urlpatterns_reverse/utils.py b/tests/urlpatterns_reverse/utils.py index adcb310fa543..22664480d168 100644 --- a/tests/urlpatterns_reverse/utils.py +++ b/tests/urlpatterns_reverse/utils.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.conf.urls import url from . import views diff --git a/tests/utils_tests/test_crypto.py b/tests/utils_tests/test_crypto.py index d36f82e5920f..bd0c111ff34a 100644 --- a/tests/utils_tests/test_crypto.py +++ b/tests/utils_tests/test_crypto.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import binascii import hashlib import unittest diff --git a/tests/utils_tests/test_dateformat.py b/tests/utils_tests/test_dateformat.py index bd99b31a426e..c11dd5591d70 100644 --- a/tests/utils_tests/test_dateformat.py +++ b/tests/utils_tests/test_dateformat.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import date, datetime from django.test import SimpleTestCase, override_settings diff --git a/tests/utils_tests/test_dateparse.py b/tests/utils_tests/test_dateparse.py index 0bb81ed0b017..0f48ff4ff982 100644 --- a/tests/utils_tests/test_dateparse.py +++ b/tests/utils_tests/test_dateparse.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import unittest from datetime import date, datetime, time, timedelta diff --git a/tests/utils_tests/test_encoding.py b/tests/utils_tests/test_encoding.py index 688b46194d67..1d6976fc7751 100644 --- a/tests/utils_tests/test_encoding.py +++ b/tests/utils_tests/test_encoding.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - import datetime import unittest diff --git a/tests/utils_tests/test_feedgenerator.py b/tests/utils_tests/test_feedgenerator.py index 9b249295c3f1..8c0edb4374a3 100644 --- a/tests/utils_tests/test_feedgenerator.py +++ b/tests/utils_tests/test_feedgenerator.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import unittest diff --git a/tests/utils_tests/test_functional.py b/tests/utils_tests/test_functional.py index 7a633620fc30..f7b12724af8a 100644 --- a/tests/utils_tests/test_functional.py +++ b/tests/utils_tests/test_functional.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - import unittest from django.utils import six diff --git a/tests/utils_tests/test_glob.py b/tests/utils_tests/test_glob.py index 7e72815ef851..5cd7fbbe28c8 100644 --- a/tests/utils_tests/test_glob.py +++ b/tests/utils_tests/test_glob.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import SimpleTestCase from django.utils.glob import glob_escape diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py index 39d590032fb1..ec818318b4be 100644 --- a/tests/utils_tests/test_html.py +++ b/tests/utils_tests/test_html.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import os from datetime import datetime diff --git a/tests/utils_tests/test_http.py b/tests/utils_tests/test_http.py index e90d5e397d82..30a884602192 100644 --- a/tests/utils_tests/test_http.py +++ b/tests/utils_tests/test_http.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - import sys import unittest from datetime import datetime diff --git a/tests/utils_tests/test_ipv6.py b/tests/utils_tests/test_ipv6.py index 84630d2ba066..4e434f3c3aa0 100644 --- a/tests/utils_tests/test_ipv6.py +++ b/tests/utils_tests/test_ipv6.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import unittest from django.utils.ipv6 import clean_ipv6_address, is_valid_ipv6_address diff --git a/tests/utils_tests/test_jslex.py b/tests/utils_tests/test_jslex.py index f77be16b7f89..6b4269736a84 100644 --- a/tests/utils_tests/test_jslex.py +++ b/tests/utils_tests/test_jslex.py @@ -1,7 +1,5 @@ -# -*- coding: utf-8 -*- """Tests for jslex.""" # originally from https://bitbucket.org/ned/jslex -from __future__ import unicode_literals from django.test import SimpleTestCase from django.utils.jslex import JsLexer, prepare_js_for_gettext diff --git a/tests/utils_tests/test_lazyobject.py b/tests/utils_tests/test_lazyobject.py index 9dc225b55f8a..588e85afc58a 100644 --- a/tests/utils_tests/test_lazyobject.py +++ b/tests/utils_tests/test_lazyobject.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import copy import pickle import sys diff --git a/tests/utils_tests/test_lorem_ipsum.py b/tests/utils_tests/test_lorem_ipsum.py index 9b160cd2fbc6..b90190298a6f 100644 --- a/tests/utils_tests/test_lorem_ipsum.py +++ b/tests/utils_tests/test_lorem_ipsum.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import unittest from django.utils.lorem_ipsum import paragraphs, words diff --git a/tests/utils_tests/test_numberformat.py b/tests/utils_tests/test_numberformat.py index 3dd1b0644ff2..dd6057bb6456 100644 --- a/tests/utils_tests/test_numberformat.py +++ b/tests/utils_tests/test_numberformat.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - from decimal import Decimal from sys import float_info from unittest import TestCase diff --git a/tests/utils_tests/test_regex_helper.py b/tests/utils_tests/test_regex_helper.py index f91fd1cec7ed..93383e1c1ad2 100644 --- a/tests/utils_tests/test_regex_helper.py +++ b/tests/utils_tests/test_regex_helper.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import unittest import warnings diff --git a/tests/utils_tests/test_safestring.py b/tests/utils_tests/test_safestring.py index abaf6a059655..96f42d5ddd06 100644 --- a/tests/utils_tests/test_safestring.py +++ b/tests/utils_tests/test_safestring.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.template import Context, Template from django.test import SimpleTestCase from django.utils import html, six, text diff --git a/tests/utils_tests/test_simplelazyobject.py b/tests/utils_tests/test_simplelazyobject.py index bad47a2f899d..8501b89e9297 100644 --- a/tests/utils_tests/test_simplelazyobject.py +++ b/tests/utils_tests/test_simplelazyobject.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import pickle from django.contrib.auth.models import User diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py index 3dfc33a12060..9128fb02476f 100644 --- a/tests/utils_tests/test_text.py +++ b/tests/utils_tests/test_text.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import json from django.test import SimpleTestCase diff --git a/tests/utils_tests/test_timesince.py b/tests/utils_tests/test_timesince.py index 645806a96bcd..3e2c5ce56efa 100644 --- a/tests/utils_tests/test_timesince.py +++ b/tests/utils_tests/test_timesince.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import unittest diff --git a/tests/validation/models.py b/tests/validation/models.py index 2e2a144cb6e3..90b2dbb79a5e 100644 --- a/tests/validation/models.py +++ b/tests/validation/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from datetime import datetime from django.core.exceptions import ValidationError diff --git a/tests/validation/test_error_messages.py b/tests/validation/test_error_messages.py index c71b8cd60ab5..d2fc3e493962 100644 --- a/tests/validation/test_error_messages.py +++ b/tests/validation/test_error_messages.py @@ -1,6 +1,3 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - from unittest import TestCase from django.core.exceptions import ValidationError diff --git a/tests/validation/test_unique.py b/tests/validation/test_unique.py index 0780b9ec4341..642154aaa706 100644 --- a/tests/validation/test_unique.py +++ b/tests/validation/test_unique.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import unittest diff --git a/tests/validation/test_validators.py b/tests/validation/test_validators.py index 4a3c99f08b17..733ff5c139d3 100644 --- a/tests/validation/test_validators.py +++ b/tests/validation/test_validators.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from . import ValidationTestCase from .models import ModelToValidate diff --git a/tests/validation/tests.py b/tests/validation/tests.py index e7a49b470d42..131ecda74dfc 100644 --- a/tests/validation/tests.py +++ b/tests/validation/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django import forms from django.core.exceptions import NON_FIELD_ERRORS from django.test import TestCase diff --git a/tests/validators/tests.py b/tests/validators/tests.py index 4ef8a524b121..d5fb2215ca54 100644 --- a/tests/validators/tests.py +++ b/tests/validators/tests.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import io import os import re diff --git a/tests/view_tests/__init__.py b/tests/view_tests/__init__.py index 638df1b91a6b..f48b197507df 100644 --- a/tests/view_tests/__init__.py +++ b/tests/view_tests/__init__.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - - class BrokenException(Exception): pass diff --git a/tests/view_tests/generic_urls.py b/tests/view_tests/generic_urls.py index 4ca2c8927adf..2c40383a2d84 100644 --- a/tests/view_tests/generic_urls.py +++ b/tests/view_tests/generic_urls.py @@ -1,6 +1,3 @@ -# -*- coding:utf-8 -*- -from __future__ import unicode_literals - from django.conf.urls import url from django.contrib.auth import views as auth_views from django.views.generic import RedirectView diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py index 24fa59362160..19ab456ba5bb 100644 --- a/tests/view_tests/tests/test_debug.py +++ b/tests/view_tests/tests/test_debug.py @@ -1,8 +1,3 @@ -# -*- coding: utf-8 -*- -# This coding header is significant for tests, as the debug view is parsing -# files to search for such a header to decode the source file content -from __future__ import unicode_literals - import importlib import inspect import os diff --git a/tests/view_tests/tests/test_defaults.py b/tests/view_tests/tests/test_defaults.py index 1b5ad2510270..4b002f363225 100644 --- a/tests/view_tests/tests/test_defaults.py +++ b/tests/view_tests/tests/test_defaults.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime from django.contrib.sites.models import Site diff --git a/tests/view_tests/tests/test_i18n.py b/tests/view_tests/tests/test_i18n.py index 725d72890ea1..fc7be41594b2 100644 --- a/tests/view_tests/tests/test_i18n.py +++ b/tests/view_tests/tests/test_i18n.py @@ -1,6 +1,3 @@ -# -*- coding:utf-8 -*- -from __future__ import unicode_literals - import gettext import json from os import path diff --git a/tests/view_tests/tests/test_json.py b/tests/view_tests/tests/test_json.py index 0d6bc09120e2..34e8fa359bb2 100644 --- a/tests/view_tests/tests/test_json.py +++ b/tests/view_tests/tests/test_json.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import json from django.test import SimpleTestCase, override_settings diff --git a/tests/view_tests/tests/test_specials.py b/tests/view_tests/tests/test_specials.py index 8ef766e86f0f..70ffb1d23ec2 100644 --- a/tests/view_tests/tests/test_specials.py +++ b/tests/view_tests/tests/test_specials.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.test import SimpleTestCase, override_settings diff --git a/tests/view_tests/tests/test_static.py b/tests/view_tests/tests/test_static.py index 457577264e4a..f1a992789fdc 100644 --- a/tests/view_tests/tests/test_static.py +++ b/tests/view_tests/tests/test_static.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import mimetypes import unittest from os import path diff --git a/tests/view_tests/urls.py b/tests/view_tests/urls.py index 128be09eb6fe..c536ea78edd5 100644 --- a/tests/view_tests/urls.py +++ b/tests/view_tests/urls.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from functools import partial from os import path diff --git a/tests/view_tests/views.py b/tests/view_tests/views.py index bfcdc20a1380..5c6311140544 100644 --- a/tests/view_tests/views.py +++ b/tests/view_tests/views.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import datetime import decimal import logging diff --git a/tests/wsgi/tests.py b/tests/wsgi/tests.py index e07f8d247833..68e8d4a86d41 100644 --- a/tests/wsgi/tests.py +++ b/tests/wsgi/tests.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.core.exceptions import ImproperlyConfigured from django.core.servers.basehttp import get_internal_wsgi_application from django.core.signals import request_started From f3c43ad1fd9556f0fd026a5dfa93c67a5cf186ca Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Sat, 19 Nov 2016 21:54:19 +0100 Subject: [PATCH 0059/3180] Refs #23919 -- Removed python_2_unicode_compatible decorator usage --- django/contrib/admin/models.py | 3 +- django/contrib/admin/options.py | 3 +- django/contrib/auth/base_user.py | 3 +- django/contrib/auth/models.py | 4 -- django/contrib/contenttypes/fields.py | 3 +- django/contrib/contenttypes/models.py | 3 +- django/contrib/flatpages/models.py | 3 +- django/contrib/gis/db/backends/base/models.py | 2 - .../contrib/gis/db/backends/oracle/models.py | 2 - .../contrib/gis/db/backends/postgis/models.py | 2 - .../gis/db/backends/spatialite/models.py | 2 - django/contrib/gis/gdal/raster/source.py | 5 +-- django/contrib/messages/storage/base.py | 3 +- django/contrib/redirects/models.py | 2 - django/contrib/sessions/base_session.py | 2 - django/contrib/sites/models.py | 2 - django/contrib/sites/requests.py | 4 -- django/core/checks/messages.py | 3 +- django/core/files/base.py | 6 +-- django/core/files/uploadhandler.py | 2 - django/db/migrations/exceptions.py | 2 - django/db/migrations/graph.py | 3 -- django/db/migrations/migration.py | 2 - django/db/migrations/recorder.py | 2 - django/db/models/base.py | 5 +-- django/db/models/fields/__init__.py | 5 +-- django/db/models/manager.py | 2 - django/db/models/options.py | 3 +- django/forms/boundfield.py | 4 +- django/forms/forms.py | 3 +- django/forms/formsets.py | 2 - django/forms/utils.py | 4 +- django/forms/widgets.py | 5 +-- django/template/base.py | 5 +-- django/test/html.py | 4 +- .../writing-code/coding-style.txt | 4 -- docs/intro/tutorial02.txt | 3 -- docs/ref/models/instances.txt | 5 --- docs/ref/unicode.txt | 27 ------------- docs/topics/python3.txt | 21 ---------- tests/admin_changelist/models.py | 3 -- tests/admin_checks/models.py | 2 - tests/admin_custom_urls/models.py | 2 - tests/admin_filters/models.py | 6 --- tests/admin_inlines/models.py | 4 -- tests/admin_utils/models.py | 3 -- tests/admin_views/models.py | 37 ------------------ tests/admin_widgets/models.py | 9 ----- tests/aggregation/models.py | 5 --- tests/aggregation_regress/models.py | 6 --- tests/annotations/models.py | 9 ----- tests/auth_tests/models/custom_permissions.py | 2 - tests/auth_tests/models/custom_user.py | 2 - tests/backends/models.py | 8 ---- tests/basic/models.py | 3 -- tests/choices/models.py | 2 - tests/contenttypes_tests/models.py | 9 ----- tests/custom_columns/models.py | 3 -- tests/custom_lookups/models.py | 3 -- tests/custom_managers/models.py | 8 ---- tests/custom_methods/models.py | 2 - tests/custom_pk/fields.py | 2 - tests/custom_pk/models.py | 4 -- tests/datatypes/models.py | 2 - tests/dates/models.py | 3 -- tests/datetimes/models.py | 3 -- tests/db_functions/models.py | 5 --- tests/defer/models.py | 2 - tests/defer_regress/models.py | 4 -- tests/delete/models.py | 2 - tests/distinct_on_fields/models.py | 5 --- tests/expressions/models.py | 8 ---- tests/expressions_case/models.py | 5 --- tests/extra_regress/models.py | 3 -- tests/field_defaults/models.py | 2 - tests/fixtures/models.py | 8 ---- .../fixtures_model_package/models/__init__.py | 2 - tests/fixtures_regress/models.py | 10 ----- tests/foreign_object/models/article.py | 2 - tests/foreign_object/models/empty_join.py | 2 - tests/foreign_object/models/person.py | 5 --- tests/forms_tests/models.py | 3 -- .../forms_tests/tests/test_error_messages.py | 2 - tests/forms_tests/tests/test_forms.py | 3 +- tests/forms_tests/tests/test_utils.py | 3 +- .../widget_tests/test_clearablefileinput.py | 6 --- tests/from_db_value/models.py | 2 - tests/generic_inline_admin/models.py | 2 - tests/generic_relations/models.py | 6 --- tests/generic_relations_regress/models.py | 8 ---- tests/generic_views/models.py | 4 -- tests/get_object_or_404/models.py | 3 -- tests/get_or_create/models.py | 2 - tests/gis_tests/distapp/models.py | 2 - tests/gis_tests/geo3d/models.py | 2 - tests/gis_tests/geoadmin/models.py | 2 - tests/gis_tests/geoapp/models.py | 2 - tests/gis_tests/geogapp/models.py | 2 - tests/gis_tests/layermap/models.py | 2 - tests/gis_tests/relatedapp/models.py | 4 -- tests/inline_formsets/models.py | 3 -- tests/introspection/models.py | 5 --- tests/lookup/models.py | 5 --- tests/m2m_and_m2o/models.py | 2 - tests/m2m_intermediary/models.py | 4 -- tests/m2m_multiple/models.py | 3 -- tests/m2m_recursive/models.py | 2 - tests/m2m_regress/models.py | 6 --- tests/m2m_signals/models.py | 4 -- tests/m2m_through/models.py | 8 ---- tests/m2m_through_regress/models.py | 8 ---- tests/m2o_recursive/models.py | 3 -- tests/managers_regress/models.py | 10 +---- tests/many_to_many/models.py | 4 -- tests/many_to_one/models.py | 7 ---- tests/many_to_one_null/models.py | 3 -- tests/migrations/models.py | 2 - tests/model_forms/models.py | 17 -------- tests/model_formsets/models.py | 19 --------- tests/model_formsets_regress/models.py | 2 - tests/model_inheritance/models.py | 9 ----- tests/model_inheritance_regress/models.py | 11 ------ tests/model_regress/models.py | 5 --- tests/modeladmin/models.py | 2 - tests/multiple_database/models.py | 5 --- tests/null_fk/models.py | 3 -- tests/null_fk_ordering/models.py | 4 -- tests/null_queries/models.py | 3 -- tests/one_to_one/models.py | 7 ---- tests/or_lookups/models.py | 2 - tests/order_with_respect_to/models.py | 3 -- tests/ordering/models.py | 2 - tests/pagination/models.py | 2 - tests/prefetch_related/models.py | 11 ------ tests/proxy_models/models.py | 6 --- tests/queries/models.py | 39 ------------------- tests/reserved_names/models.py | 2 - tests/reverse_lookup/models.py | 4 -- tests/save_delete_hooks/models.py | 2 - tests/schema/models.py | 2 - tests/select_related/models.py | 14 ------- tests/select_related_onetoone/models.py | 10 ----- tests/select_related_regress/models.py | 8 ---- tests/serializers/models/base.py | 10 ----- tests/signals/models.py | 5 --- tests/sites_framework/models.py | 2 - tests/str/models.py | 2 - tests/str/tests.py | 8 +--- tests/string_lookup/models.py | 7 ---- tests/syndication_tests/models.py | 3 -- .../filter_tests/test_unordered_list.py | 3 -- tests/template_tests/utils.py | 4 -- tests/test_utils/models.py | 4 -- tests/transaction_hooks/models.py | 2 - tests/transactions/models.py | 2 - tests/unmanaged_models/models.py | 7 ---- tests/update/models.py | 3 -- tests/update_only_fields/models.py | 3 -- tests/validation/models.py | 2 - tests/view_tests/models.py | 3 -- 160 files changed, 23 insertions(+), 757 deletions(-) diff --git a/django/contrib/admin/models.py b/django/contrib/admin/models.py index 724209dd0d30..e3483a85b27e 100644 --- a/django/contrib/admin/models.py +++ b/django/contrib/admin/models.py @@ -6,7 +6,7 @@ from django.db import models from django.urls import NoReverseMatch, reverse from django.utils import timezone -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import force_text from django.utils.text import get_text_list from django.utils.translation import ugettext, ugettext_lazy as _ @@ -31,7 +31,6 @@ def log_action(self, user_id, content_type_id, object_id, object_repr, action_fl ) -@python_2_unicode_compatible class LogEntry(models.Model): action_time = models.DateTimeField( _('action time'), diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index edde9077ac92..bb871513d7ff 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -38,7 +38,7 @@ from django.urls import reverse from django.utils import six from django.utils.decorators import method_decorator -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import force_text from django.utils.html import format_html from django.utils.http import urlencode, urlquote from django.utils.safestring import mark_safe @@ -480,7 +480,6 @@ def has_module_permission(self, request): return request.user.has_module_perms(self.opts.app_label) -@python_2_unicode_compatible class ModelAdmin(BaseModelAdmin): "Encapsulates all admin options and functionality for a given model." diff --git a/django/contrib/auth/base_user.py b/django/contrib/auth/base_user.py index c6f4c9665cd7..4ec18bee174e 100644 --- a/django/contrib/auth/base_user.py +++ b/django/contrib/auth/base_user.py @@ -10,7 +10,7 @@ ) from django.db import models from django.utils.crypto import get_random_string, salted_hmac -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import force_text from django.utils.translation import ugettext_lazy as _ @@ -45,7 +45,6 @@ def get_by_natural_key(self, username): return self.get(**{self.model.USERNAME_FIELD: username}) -@python_2_unicode_compatible class AbstractBaseUser(models.Model): password = models.CharField(_('password'), max_length=128) last_login = models.DateTimeField(_('last login'), blank=True, null=True) diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index 2e9f3682d7b8..51b0d8fa63fd 100644 --- a/django/contrib/auth/models.py +++ b/django/contrib/auth/models.py @@ -7,7 +7,6 @@ from django.db import models from django.db.models.manager import EmptyManager from django.utils import six, timezone -from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ from .validators import ASCIIUsernameValidator, UnicodeUsernameValidator @@ -35,7 +34,6 @@ def get_by_natural_key(self, codename, app_label, model): ) -@python_2_unicode_compatible class Permission(models.Model): """ The permissions system provides a way to assign permissions to specific @@ -96,7 +94,6 @@ def get_by_natural_key(self, name): return self.get(name=name) -@python_2_unicode_compatible class Group(models.Model): """ Groups are a generic way of categorizing users to apply permissions, or @@ -374,7 +371,6 @@ class Meta(AbstractUser.Meta): swappable = 'AUTH_USER_MODEL' -@python_2_unicode_compatible class AnonymousUser(object): id = None pk = None diff --git a/django/contrib/contenttypes/fields.py b/django/contrib/contenttypes/fields.py index 83e38af4415e..d2812e5d2a8b 100644 --- a/django/contrib/contenttypes/fields.py +++ b/django/contrib/contenttypes/fields.py @@ -11,11 +11,10 @@ lazy_related_operation, ) from django.db.models.query_utils import PathInfo -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import force_text from django.utils.functional import cached_property -@python_2_unicode_compatible class GenericForeignKey(object): """ Provide a generic many-to-one relation through the ``content_type`` and diff --git a/django/contrib/contenttypes/models.py b/django/contrib/contenttypes/models.py index 6db6831fbc67..9fe4a567673b 100644 --- a/django/contrib/contenttypes/models.py +++ b/django/contrib/contenttypes/models.py @@ -2,7 +2,7 @@ from django.apps import apps from django.db import models -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import force_text from django.utils.translation import ugettext_lazy as _ @@ -133,7 +133,6 @@ def _add_to_cache(self, using, ct): self._cache.setdefault(using, {})[ct.id] = ct -@python_2_unicode_compatible class ContentType(models.Model): app_label = models.CharField(max_length=100) model = models.CharField(_('python model class name'), max_length=100) diff --git a/django/contrib/flatpages/models.py b/django/contrib/flatpages/models.py index 02c93d657d76..38cc9fd0fec4 100644 --- a/django/contrib/flatpages/models.py +++ b/django/contrib/flatpages/models.py @@ -1,11 +1,10 @@ from django.contrib.sites.models import Site from django.db import models from django.urls import get_script_prefix -from django.utils.encoding import iri_to_uri, python_2_unicode_compatible +from django.utils.encoding import iri_to_uri from django.utils.translation import ugettext_lazy as _ -@python_2_unicode_compatible class FlatPage(models.Model): url = models.CharField(_('URL'), max_length=100, db_index=True) title = models.CharField(_('title'), max_length=200) diff --git a/django/contrib/gis/db/backends/base/models.py b/django/contrib/gis/db/backends/base/models.py index 8ae9f2b12657..8c8bdc6346be 100644 --- a/django/contrib/gis/db/backends/base/models.py +++ b/django/contrib/gis/db/backends/base/models.py @@ -1,9 +1,7 @@ from django.contrib.gis import gdal from django.utils import six -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class SpatialRefSysMixin(object): """ The SpatialRefSysMixin is a class used by the database-dependent diff --git a/django/contrib/gis/db/backends/oracle/models.py b/django/contrib/gis/db/backends/oracle/models.py index e1bf49050b38..13fbbcba4fca 100644 --- a/django/contrib/gis/db/backends/oracle/models.py +++ b/django/contrib/gis/db/backends/oracle/models.py @@ -9,10 +9,8 @@ """ from django.contrib.gis.db import models from django.contrib.gis.db.backends.base.models import SpatialRefSysMixin -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class OracleGeometryColumns(models.Model): "Maps to the Oracle USER_SDO_GEOM_METADATA table." table_name = models.CharField(max_length=32) diff --git a/django/contrib/gis/db/backends/postgis/models.py b/django/contrib/gis/db/backends/postgis/models.py index ddb3be1e5eaa..60090df99d66 100644 --- a/django/contrib/gis/db/backends/postgis/models.py +++ b/django/contrib/gis/db/backends/postgis/models.py @@ -3,10 +3,8 @@ """ from django.contrib.gis.db.backends.base.models import SpatialRefSysMixin from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class PostGISGeometryColumns(models.Model): """ The 'geometry_columns' view from PostGIS. See the PostGIS diff --git a/django/contrib/gis/db/backends/spatialite/models.py b/django/contrib/gis/db/backends/spatialite/models.py index 7dca8896eef6..82fed9fd195f 100644 --- a/django/contrib/gis/db/backends/spatialite/models.py +++ b/django/contrib/gis/db/backends/spatialite/models.py @@ -3,10 +3,8 @@ """ from django.contrib.gis.db.backends.base.models import SpatialRefSysMixin from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class SpatialiteGeometryColumns(models.Model): """ The 'geometry_columns' table from SpatiaLite. diff --git a/django/contrib/gis/gdal/raster/source.py b/django/contrib/gis/gdal/raster/source.py index 4aea283dd837..f3a565ddc8ff 100644 --- a/django/contrib/gis/gdal/raster/source.py +++ b/django/contrib/gis/gdal/raster/source.py @@ -11,9 +11,7 @@ from django.contrib.gis.gdal.srs import SpatialReference, SRSException from django.contrib.gis.geometry.regex import json_regex from django.utils import six -from django.utils.encoding import ( - force_bytes, force_text, python_2_unicode_compatible, -) +from django.utils.encoding import force_bytes, force_text from django.utils.functional import cached_property @@ -52,7 +50,6 @@ def y(self, value): self._raster.geotransform = gtf -@python_2_unicode_compatible class GDALRaster(GDALBase): """ Wraps a raster GDAL Data Source object. diff --git a/django/contrib/messages/storage/base.py b/django/contrib/messages/storage/base.py index 2273e9720787..66cd41684bfa 100644 --- a/django/contrib/messages/storage/base.py +++ b/django/contrib/messages/storage/base.py @@ -1,11 +1,10 @@ from django.conf import settings from django.contrib.messages import constants, utils -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import force_text LEVEL_TAGS = utils.get_level_tags() -@python_2_unicode_compatible class Message(object): """ Represents an actual message that can be stored in any of the supported diff --git a/django/contrib/redirects/models.py b/django/contrib/redirects/models.py index a52a89d64213..7a876ec76bfa 100644 --- a/django/contrib/redirects/models.py +++ b/django/contrib/redirects/models.py @@ -1,10 +1,8 @@ from django.contrib.sites.models import Site from django.db import models -from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ -@python_2_unicode_compatible class Redirect(models.Model): site = models.ForeignKey(Site, models.CASCADE, verbose_name=_('site')) old_path = models.CharField( diff --git a/django/contrib/sessions/base_session.py b/django/contrib/sessions/base_session.py index bd8e957aea15..e9cdcfe1c613 100644 --- a/django/contrib/sessions/base_session.py +++ b/django/contrib/sessions/base_session.py @@ -3,7 +3,6 @@ when django.contrib.sessions is not in INSTALLED_APPS. """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ @@ -24,7 +23,6 @@ def save(self, session_key, session_dict, expire_date): return s -@python_2_unicode_compatible class AbstractBaseSession(models.Model): session_key = models.CharField(_('session key'), max_length=40, primary_key=True) session_data = models.TextField(_('session data')) diff --git a/django/contrib/sites/models.py b/django/contrib/sites/models.py index 9f849fa5591f..782453d35da5 100644 --- a/django/contrib/sites/models.py +++ b/django/contrib/sites/models.py @@ -4,7 +4,6 @@ from django.db import models from django.db.models.signals import pre_delete, pre_save from django.http.request import split_domain_port -from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ SITE_CACHE = {} @@ -78,7 +77,6 @@ def get_by_natural_key(self, domain): return self.get(domain=domain) -@python_2_unicode_compatible class Site(models.Model): domain = models.CharField( diff --git a/django/contrib/sites/requests.py b/django/contrib/sites/requests.py index 81f2ba42d6f3..c5513d835881 100644 --- a/django/contrib/sites/requests.py +++ b/django/contrib/sites/requests.py @@ -1,7 +1,3 @@ -from django.utils.encoding import python_2_unicode_compatible - - -@python_2_unicode_compatible class RequestSite(object): """ A class that shares the primary interface of Site (i.e., it has diff --git a/django/core/checks/messages.py b/django/core/checks/messages.py index f1de41a63c87..da198d72b979 100644 --- a/django/core/checks/messages.py +++ b/django/core/checks/messages.py @@ -1,4 +1,4 @@ -from django.utils.encoding import force_str, python_2_unicode_compatible +from django.utils.encoding import force_str # Levels DEBUG = 10 @@ -8,7 +8,6 @@ CRITICAL = 50 -@python_2_unicode_compatible class CheckMessage(object): def __init__(self, level, msg, hint=None, obj=None, id=None): diff --git a/django/core/files/base.py b/django/core/files/base.py index 7499629459ba..f797158881f0 100644 --- a/django/core/files/base.py +++ b/django/core/files/base.py @@ -3,12 +3,9 @@ from django.core.files.utils import FileProxyMixin from django.utils import six -from django.utils.encoding import ( - force_bytes, force_str, force_text, python_2_unicode_compatible, -) +from django.utils.encoding import force_bytes, force_str, force_text -@python_2_unicode_compatible class File(FileProxyMixin): DEFAULT_CHUNK_SIZE = 64 * 2 ** 10 @@ -138,7 +135,6 @@ def close(self): self.file.close() -@python_2_unicode_compatible class ContentFile(File): """ A File-like object that takes just raw content, rather than an actual file. diff --git a/django/core/files/uploadhandler.py b/django/core/files/uploadhandler.py index 748477c0fc3f..3741f372b2db 100644 --- a/django/core/files/uploadhandler.py +++ b/django/core/files/uploadhandler.py @@ -8,7 +8,6 @@ from django.core.files.uploadedfile import ( InMemoryUploadedFile, TemporaryUploadedFile, ) -from django.utils.encoding import python_2_unicode_compatible from django.utils.module_loading import import_string __all__ = [ @@ -25,7 +24,6 @@ class UploadFileException(Exception): pass -@python_2_unicode_compatible class StopUpload(UploadFileException): """ This exception is raised when an upload must abort. diff --git a/django/db/migrations/exceptions.py b/django/db/migrations/exceptions.py index d3da26940f11..7b2a6abc6207 100644 --- a/django/db/migrations/exceptions.py +++ b/django/db/migrations/exceptions.py @@ -1,5 +1,4 @@ from django.db.utils import DatabaseError -from django.utils.encoding import python_2_unicode_compatible class AmbiguityError(Exception): @@ -44,7 +43,6 @@ class IrreversibleError(RuntimeError): pass -@python_2_unicode_compatible class NodeNotFoundError(LookupError): """ Raised when an attempt on a node is made that is not available in the graph. diff --git a/django/db/migrations/graph.py b/django/db/migrations/graph.py index 83422361c4bd..1729aa7b7a7d 100644 --- a/django/db/migrations/graph.py +++ b/django/db/migrations/graph.py @@ -6,7 +6,6 @@ from django.db.migrations.state import ProjectState from django.utils import six from django.utils.datastructures import OrderedSet -from django.utils.encoding import python_2_unicode_compatible from .exceptions import CircularDependencyError, NodeNotFoundError @@ -18,7 +17,6 @@ ) -@python_2_unicode_compatible @total_ordering class Node(object): """ @@ -102,7 +100,6 @@ def raise_error(self): raise NodeNotFoundError(self.error_message, self.key, origin=self.origin) -@python_2_unicode_compatible class MigrationGraph(object): """ Represents the digraph of all migrations in a project. diff --git a/django/db/migrations/migration.py b/django/db/migrations/migration.py index d8b993f72528..d1a24d436180 100644 --- a/django/db/migrations/migration.py +++ b/django/db/migrations/migration.py @@ -1,10 +1,8 @@ from django.db.transaction import atomic -from django.utils.encoding import python_2_unicode_compatible from .exceptions import IrreversibleError -@python_2_unicode_compatible class Migration(object): """ The base class for all migrations. diff --git a/django/db/migrations/recorder.py b/django/db/migrations/recorder.py index 0dac81223df3..7824228c979e 100644 --- a/django/db/migrations/recorder.py +++ b/django/db/migrations/recorder.py @@ -1,7 +1,6 @@ from django.apps.registry import Apps from django.db import models from django.db.utils import DatabaseError -from django.utils.encoding import python_2_unicode_compatible from django.utils.timezone import now from .exceptions import MigrationSchemaMissing @@ -20,7 +19,6 @@ class MigrationRecorder(object): a row in the table always means a migration is applied. """ - @python_2_unicode_compatible class Migration(models.Model): app = models.CharField(max_length=255) name = models.CharField(max_length=255) diff --git a/django/db/models/base.py b/django/db/models/base.py index 2fbcf46a41d5..e18615d76d03 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -27,9 +27,7 @@ ) from django.db.models.utils import make_model_tuple from django.utils import six -from django.utils.encoding import ( - force_str, force_text, python_2_unicode_compatible, -) +from django.utils.encoding import force_str, force_text from django.utils.functional import curry from django.utils.six.moves import zip from django.utils.text import capfirst, get_text_list @@ -37,7 +35,6 @@ from django.utils.version import get_version -@python_2_unicode_compatible class Deferred(object): def __repr__(self): return str('') diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index ddfcbb4f394a..2e21a4267293 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -25,9 +25,7 @@ parse_date, parse_datetime, parse_duration, parse_time, ) from django.utils.duration import duration_string -from django.utils.encoding import ( - force_bytes, force_text, python_2_unicode_compatible, smart_text, -) +from django.utils.encoding import force_bytes, force_text, smart_text from django.utils.functional import Promise, cached_property, curry from django.utils.ipv6 import clean_ipv6_address from django.utils.itercompat import is_iterable @@ -91,7 +89,6 @@ def return_None(): @total_ordering -@python_2_unicode_compatible class Field(RegisterLookupMixin): """Base class for all field types""" diff --git a/django/db/models/manager.py b/django/db/models/manager.py index 5a8ad632d54a..5b498d631b5d 100644 --- a/django/db/models/manager.py +++ b/django/db/models/manager.py @@ -5,10 +5,8 @@ from django.db import router from django.db.models.query import QuerySet from django.utils import six -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class BaseManager(object): # Tracks each time a Manager instance is created. Used to retain order. creation_counter = 0 diff --git a/django/db/models/options.py b/django/db/models/options.py index 943de0dd910a..a4593d125a95 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -16,7 +16,7 @@ from django.utils import six from django.utils.datastructures import ImmutableList, OrderedSet from django.utils.deprecation import RemovedInDjango21Warning -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import force_text from django.utils.functional import cached_property from django.utils.text import camel_case_to_spaces, format_lazy from django.utils.translation import override @@ -67,7 +67,6 @@ def make_immutable_fields_list(name, data): return ImmutableList(data, warning=IMMUTABLE_WARNING % name) -@python_2_unicode_compatible class Options(object): FORWARD_PROPERTIES = { 'fields', 'many_to_many', 'concrete_fields', 'local_concrete_fields', diff --git a/django/forms/boundfield.py b/django/forms/boundfield.py index fa141b35ef93..6faff6ffc94f 100644 --- a/django/forms/boundfield.py +++ b/django/forms/boundfield.py @@ -5,7 +5,7 @@ from django.forms.widgets import Textarea, TextInput from django.utils import six from django.utils.deprecation import RemovedInDjango21Warning -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import force_text from django.utils.functional import cached_property from django.utils.html import conditional_escape, format_html, html_safe from django.utils.inspect import func_supports_parameter @@ -16,7 +16,6 @@ @html_safe -@python_2_unicode_compatible class BoundField(object): "A Field plus data" def __init__(self, form, field, name): @@ -253,7 +252,6 @@ def build_widget_attrs(self, attrs, widget=None): @html_safe -@python_2_unicode_compatible class BoundWidget(object): """ A container class used for iterating over widgets. This is useful for diff --git a/django/forms/forms.py b/django/forms/forms.py index 0f1fbef6c854..3971893aa2ef 100644 --- a/django/forms/forms.py +++ b/django/forms/forms.py @@ -13,7 +13,7 @@ from django.forms.utils import ErrorDict, ErrorList, pretty_name # NOQA from django.forms.widgets import Media, MediaDefiningClass from django.utils import six -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import force_text from django.utils.functional import cached_property from django.utils.html import conditional_escape, html_safe from django.utils.safestring import mark_safe @@ -59,7 +59,6 @@ def __new__(mcs, name, bases, attrs): @html_safe -@python_2_unicode_compatible class BaseForm(object): # This is the main implementation of all the Form logic. Note that this # class is different than Form. See the comments by the Form class for more diff --git a/django/forms/formsets.py b/django/forms/formsets.py index 1e5ec8ee6be0..81788626e1b1 100644 --- a/django/forms/formsets.py +++ b/django/forms/formsets.py @@ -4,7 +4,6 @@ from django.forms.utils import ErrorList from django.forms.widgets import HiddenInput from django.utils import six -from django.utils.encoding import python_2_unicode_compatible from django.utils.functional import cached_property from django.utils.html import html_safe from django.utils.safestring import mark_safe @@ -46,7 +45,6 @@ def __init__(self, *args, **kwargs): @html_safe -@python_2_unicode_compatible class BaseFormSet(object): """ A collection of instances of the same Form class. diff --git a/django/forms/utils.py b/django/forms/utils.py index 3e6991ea32f5..3a86f419df7d 100644 --- a/django/forms/utils.py +++ b/django/forms/utils.py @@ -4,7 +4,7 @@ from django.conf import settings from django.core.exceptions import ValidationError # backwards compatibility from django.utils import six, timezone -from django.utils.encoding import force_text, python_2_unicode_compatible +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 _ @@ -48,7 +48,6 @@ def flatatt(attrs): @html_safe -@python_2_unicode_compatible class ErrorDict(dict): """ A collection of errors that knows how to display itself in various formats. @@ -81,7 +80,6 @@ def __str__(self): @html_safe -@python_2_unicode_compatible class ErrorList(UserList, list): """ A collection of errors that knows how to display itself in various formats. diff --git a/django/forms/widgets.py b/django/forms/widgets.py index 3ddad40ebb04..c4bbb7fe4fe2 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -13,9 +13,7 @@ from django.templatetags.static import static from django.utils import datetime_safe, formats, six from django.utils.dates import MONTHS -from django.utils.encoding import ( - force_str, force_text, python_2_unicode_compatible, -) +from django.utils.encoding import force_str, force_text from django.utils.formats import get_format from django.utils.html import format_html, html_safe from django.utils.safestring import mark_safe @@ -38,7 +36,6 @@ @html_safe -@python_2_unicode_compatible class Media(object): def __init__(self, media=None, **kwargs): if media: diff --git a/django/template/base.py b/django/template/base.py index 3aa7941879e3..aa30d2e2b308 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -57,9 +57,7 @@ BaseContext, Context, ContextPopException, RequestContext, ) from django.utils import six -from django.utils.encoding import ( - force_str, force_text, python_2_unicode_compatible, -) +from django.utils.encoding import force_str, force_text from django.utils.formats import localize from django.utils.html import conditional_escape, escape from django.utils.inspect import getargspec @@ -115,7 +113,6 @@ class TemplateEncodingError(Exception): pass -@python_2_unicode_compatible class VariableDoesNotExist(Exception): def __init__(self, msg, params=()): diff --git a/django/test/html.py b/django/test/html.py index 94dc7f540e5f..fd78e6b713dd 100644 --- a/django/test/html.py +++ b/django/test/html.py @@ -5,7 +5,7 @@ import re from django.utils import six -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import force_text from django.utils.html_parser import HTMLParseError, HTMLParser WHITESPACE = re.compile(r'\s+') @@ -15,7 +15,6 @@ def normalize_whitespace(string): return WHITESPACE.sub(' ', string) -@python_2_unicode_compatible class Element(object): def __init__(self, name, attributes): self.name = name @@ -139,7 +138,6 @@ def __repr__(self): return six.text_type(self) -@python_2_unicode_compatible class RootElement(Element): def __init__(self): super(RootElement, self).__init__(None, ()) diff --git a/docs/internals/contributing/writing-code/coding-style.txt b/docs/internals/contributing/writing-code/coding-style.txt index fe0a21c5a57c..abed891d630b 100644 --- a/docs/internals/contributing/writing-code/coding-style.txt +++ b/docs/internals/contributing/writing-code/coding-style.txt @@ -228,10 +228,6 @@ Model style first_name = models.CharField(max_length=20) last_name = models.CharField(max_length=40) -* If you define a ``__str__`` method (previously ``__unicode__`` before Python 3 - was supported), decorate the model class with - :func:`~django.utils.encoding.python_2_unicode_compatible`. - * The order of model inner classes and standard methods should be as follows (noting that these are not all required): diff --git a/docs/intro/tutorial02.txt b/docs/intro/tutorial02.txt index bd7e9c18cafc..f7bf85030948 100644 --- a/docs/intro/tutorial02.txt +++ b/docs/intro/tutorial02.txt @@ -452,15 +452,12 @@ of this object. Let's fix that by editing the ``Question`` model (in the :filename: polls/models.py from django.db import models - from django.utils.encoding import python_2_unicode_compatible - @python_2_unicode_compatible # only if you need to support Python 2 class Question(models.Model): # ... def __str__(self): return self.question_text - @python_2_unicode_compatible # only if you need to support Python 2 class Choice(models.Model): # ... def __str__(self): diff --git a/docs/ref/models/instances.txt b/docs/ref/models/instances.txt index 83f76f37ca7c..838a4bd4de68 100644 --- a/docs/ref/models/instances.txt +++ b/docs/ref/models/instances.txt @@ -601,9 +601,7 @@ representation of the model from the ``__str__()`` method. For example:: from django.db import models - from django.utils.encoding import python_2_unicode_compatible - @python_2_unicode_compatible # only if you need to support Python 2 class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) @@ -611,9 +609,6 @@ For example:: def __str__(self): return '%s %s' % (self.first_name, self.last_name) -If you'd like compatibility with Python 2, you can decorate your model class -with :func:`~django.utils.encoding.python_2_unicode_compatible` as shown above. - ``__eq__()`` ------------ diff --git a/docs/ref/unicode.txt b/docs/ref/unicode.txt index 3c29be550d5b..c167fd55b396 100644 --- a/docs/ref/unicode.txt +++ b/docs/ref/unicode.txt @@ -258,33 +258,6 @@ is *always* the case, even if the data could fit into an ASCII bytestring. You can pass in bytestrings when creating a model or populating a field, and Django will convert it to Unicode when it needs to. -Choosing between ``__str__()`` and ``__unicode__()`` ----------------------------------------------------- - -.. note:: - - If you are on Python 3, you can skip this section because you'll always - create ``__str__()`` rather than ``__unicode__()``. If you'd like - compatibility with Python 2, you can decorate your model class with - :func:`~django.utils.encoding.python_2_unicode_compatible`. - -One consequence of using Unicode by default is that you have to take some care -when printing data from the model. - -In particular, rather than giving your model a ``__str__()`` method, we -recommended you implement a ``__unicode__()`` method. In the ``__unicode__()`` -method, you can quite safely return the values of all your fields without -having to worry about whether they fit into a bytestring or not. (The way -Python works, the result of ``__str__()`` is *always* a bytestring, even if you -accidentally try to return a Unicode object). - -You can still create a ``__str__()`` method on your models if you want, of -course, but you shouldn't need to do this unless you have a good reason. -Django's ``Model`` base class automatically provides a ``__str__()`` -implementation that calls ``__unicode__()`` and encodes the result into UTF-8. -This means you'll normally only need to implement a ``__unicode__()`` method -and let Django handle the coercion to a bytestring when required. - Taking care in ``get_absolute_url()`` ------------------------------------- diff --git a/docs/topics/python3.txt b/docs/topics/python3.txt index 9dd4d8373244..5b40f57bd330 100644 --- a/docs/topics/python3.txt +++ b/docs/topics/python3.txt @@ -148,27 +148,6 @@ In Python 3, there's simply :meth:`~object.__str__`, which must return ``str`` (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``.) -Django provides a simple way to define :meth:`~object.__str__` and -` __unicode__()`_ methods that work on Python 2 and 3: you must -define a :meth:`~object.__str__` method returning text and to apply the -:func:`~django.utils.encoding.python_2_unicode_compatible` decorator. - -On Python 3, the decorator is a no-op. On Python 2, it defines appropriate -` __unicode__()`_ and :meth:`~object.__str__` methods (replacing the -original :meth:`~object.__str__` method in the process). Here's an example:: - - from __future__ import unicode_literals - from django.utils.encoding import python_2_unicode_compatible - - @python_2_unicode_compatible - class MyClass(object): - def __str__(self): - return "Instance of my class" - -This technique is the best match for Django's porting philosophy. - -For forwards compatibility, this decorator is available as of Django 1.4.2. - Finally, note that :meth:`~object.__repr__` must return a ``str`` on all versions of Python. diff --git a/tests/admin_changelist/models.py b/tests/admin_changelist/models.py index fb5f03cbd611..0abb0615489c 100644 --- a/tests/admin_changelist/models.py +++ b/tests/admin_changelist/models.py @@ -1,5 +1,4 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible class Event(models.Model): @@ -27,7 +26,6 @@ class Band(models.Model): genres = models.ManyToManyField(Genre) -@python_2_unicode_compatible class Musician(models.Model): name = models.CharField(max_length=30) @@ -35,7 +33,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Group(models.Model): name = models.CharField(max_length=30) members = models.ManyToManyField(Musician, through='Membership') diff --git a/tests/admin_checks/models.py b/tests/admin_checks/models.py index 822d695e4d97..3336ce878e6a 100644 --- a/tests/admin_checks/models.py +++ b/tests/admin_checks/models.py @@ -5,14 +5,12 @@ from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db import models -from django.utils.encoding import python_2_unicode_compatible class Album(models.Model): title = models.CharField(max_length=150) -@python_2_unicode_compatible class Song(models.Model): title = models.CharField(max_length=150) album = models.ForeignKey(Album, models.CASCADE) diff --git a/tests/admin_custom_urls/models.py b/tests/admin_custom_urls/models.py index 5365ee34bdad..840d9b9f3818 100644 --- a/tests/admin_custom_urls/models.py +++ b/tests/admin_custom_urls/models.py @@ -4,10 +4,8 @@ from django.db import models from django.http import HttpResponseRedirect from django.urls import reverse -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Action(models.Model): name = models.CharField(max_length=50, primary_key=True) description = models.CharField(max_length=70) diff --git a/tests/admin_filters/models.py b/tests/admin_filters/models.py index f508aa1f9b4e..d9ce5c7cfd5d 100644 --- a/tests/admin_filters/models.py +++ b/tests/admin_filters/models.py @@ -4,10 +4,8 @@ ) from django.contrib.contenttypes.models import ContentType from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Book(models.Model): title = models.CharField(max_length=50) year = models.PositiveIntegerField(null=True, blank=True) @@ -39,7 +37,6 @@ def __str__(self): return self.title -@python_2_unicode_compatible class Department(models.Model): code = models.CharField(max_length=4, unique=True) description = models.CharField(max_length=50, blank=True, null=True) @@ -48,7 +45,6 @@ def __str__(self): return self.description -@python_2_unicode_compatible class Employee(models.Model): department = models.ForeignKey(Department, models.CASCADE, to_field="code") name = models.CharField(max_length=100) @@ -57,7 +53,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class TaggedItem(models.Model): tag = models.SlugField() content_type = models.ForeignKey(ContentType, models.CASCADE, related_name='tagged_items') @@ -68,7 +63,6 @@ def __str__(self): return self.tag -@python_2_unicode_compatible class Bookmark(models.Model): url = models.URLField() tags = GenericRelation(TaggedItem) diff --git a/tests/admin_inlines/models.py b/tests/admin_inlines/models.py index e78511aaab06..31e692b60edd 100644 --- a/tests/admin_inlines/models.py +++ b/tests/admin_inlines/models.py @@ -6,10 +6,8 @@ from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Parent(models.Model): name = models.CharField(max_length=50) @@ -17,7 +15,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Teacher(models.Model): name = models.CharField(max_length=50) @@ -25,7 +22,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Child(models.Model): name = models.CharField(max_length=50) teacher = models.ForeignKey(Teacher, models.CASCADE) diff --git a/tests/admin_utils/models.py b/tests/admin_utils/models.py index 87060cbff8de..1af2f094110d 100644 --- a/tests/admin_utils/models.py +++ b/tests/admin_utils/models.py @@ -1,10 +1,8 @@ from django.db import models from django.utils import six -from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ -@python_2_unicode_compatible class Site(models.Model): domain = models.CharField(max_length=100) @@ -34,7 +32,6 @@ class Meta: proxy = True -@python_2_unicode_compatible class Count(models.Model): num = models.PositiveSmallIntegerField() parent = models.ForeignKey('self', models.CASCADE, null=True) diff --git a/tests/admin_views/models.py b/tests/admin_views/models.py index 54d8f5f96860..89373f6ed376 100644 --- a/tests/admin_views/models.py +++ b/tests/admin_views/models.py @@ -11,10 +11,8 @@ from django.core.exceptions import ValidationError from django.core.files.storage import FileSystemStorage from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Section(models.Model): """ A simple section that links to articles, to test linking to related items @@ -33,7 +31,6 @@ def name_property(self): return self.name -@python_2_unicode_compatible class Article(models.Model): """ A simple article to test admin views. Test backwards compatibility. @@ -59,7 +56,6 @@ def model_year_reversed(self): model_year_reversed.short_description = '' -@python_2_unicode_compatible class Book(models.Model): """ A simple book that has chapters. @@ -70,7 +66,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Promo(models.Model): name = models.CharField(max_length=100, verbose_name='¿Name?') book = models.ForeignKey(Book, models.CASCADE) @@ -79,7 +74,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Chapter(models.Model): title = models.CharField(max_length=100, verbose_name='¿Title?') content = models.TextField() @@ -93,7 +87,6 @@ class Meta: verbose_name = '¿Chapter?' -@python_2_unicode_compatible class ChapterXtra1(models.Model): chap = models.OneToOneField(Chapter, models.CASCADE, verbose_name='¿Chap?') xtra = models.CharField(max_length=100, verbose_name='¿Xtra?') @@ -102,7 +95,6 @@ def __str__(self): return '¿Xtra1: %s' % self.xtra -@python_2_unicode_compatible class ChapterXtra2(models.Model): chap = models.OneToOneField(Chapter, models.CASCADE, verbose_name='¿Chap?') xtra = models.CharField(max_length=100, verbose_name='¿Xtra?') @@ -120,7 +112,6 @@ class CustomArticle(models.Model): date = models.DateTimeField() -@python_2_unicode_compatible class ModelWithStringPrimaryKey(models.Model): string_pk = models.CharField(max_length=255, primary_key=True) @@ -131,7 +122,6 @@ def get_absolute_url(self): return '/dummy/%s/' % self.string_pk -@python_2_unicode_compatible class Color(models.Model): value = models.CharField(max_length=10) warm = models.BooleanField(default=False) @@ -146,7 +136,6 @@ class Meta: proxy = True -@python_2_unicode_compatible class Thing(models.Model): title = models.CharField(max_length=20) color = models.ForeignKey(Color, models.CASCADE, limit_choices_to={'warm': True}) @@ -156,7 +145,6 @@ def __str__(self): return self.title -@python_2_unicode_compatible class Actor(models.Model): name = models.CharField(max_length=50) age = models.IntegerField() @@ -166,7 +154,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Inquisition(models.Model): expected = models.BooleanField(default=False) leader = models.ForeignKey(Actor, models.CASCADE) @@ -176,7 +163,6 @@ def __str__(self): return "by %s from %s" % (self.leader, self.country) -@python_2_unicode_compatible class Sketch(models.Model): title = models.CharField(max_length=100) inquisition = models.ForeignKey( @@ -213,7 +199,6 @@ def today_callable_q(): return models.Q(last_action__gte=datetime.datetime.today()) -@python_2_unicode_compatible class Character(models.Model): username = models.CharField(max_length=100) last_action = models.DateTimeField() @@ -222,7 +207,6 @@ def __str__(self): return self.username -@python_2_unicode_compatible class StumpJoke(models.Model): variation = models.CharField(max_length=100) most_recently_fooled = models.ForeignKey( @@ -248,7 +232,6 @@ class Fabric(models.Model): surface = models.CharField(max_length=20, choices=NG_CHOICES) -@python_2_unicode_compatible class Person(models.Model): GENDER_CHOICES = ( (1, "Male"), @@ -263,7 +246,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Persona(models.Model): """ A simple persona associated with accounts, to test inlining of related @@ -275,7 +257,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Account(models.Model): """ A simple, generic account encapsulating the information shared by all @@ -299,7 +280,6 @@ class BarAccount(Account): servicename = 'bar' -@python_2_unicode_compatible class Subscriber(models.Model): name = models.CharField(blank=False, max_length=80) email = models.EmailField(blank=False, max_length=175) @@ -349,7 +329,6 @@ def clean(self): raise ValidationError('invalid') -@python_2_unicode_compatible class EmptyModel(models.Model): def __str__(self): return "Primary key = %s" % self.id @@ -433,7 +412,6 @@ class FancyDoodad(Doodad): expensive = models.BooleanField(default=True) -@python_2_unicode_compatible class Category(models.Model): collector = models.ForeignKey(Collector, models.CASCADE) order = models.PositiveIntegerField() @@ -489,7 +467,6 @@ class Meta: proxy = True -@python_2_unicode_compatible class Gadget(models.Model): name = models.CharField(max_length=100) @@ -497,7 +474,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Villain(models.Model): name = models.CharField(max_length=100) @@ -509,7 +485,6 @@ class SuperVillain(Villain): pass -@python_2_unicode_compatible class FunkyTag(models.Model): "Because we all know there's only one real use case for GFKs." name = models.CharField(max_length=25) @@ -521,7 +496,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Plot(models.Model): name = models.CharField(max_length=100) team_leader = models.ForeignKey(Villain, models.CASCADE, related_name='lead_plots') @@ -532,7 +506,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class PlotDetails(models.Model): details = models.CharField(max_length=100) plot = models.OneToOneField(Plot, models.CASCADE, null=True, blank=True) @@ -546,7 +519,6 @@ class Meta: proxy = True -@python_2_unicode_compatible class SecretHideout(models.Model): """ Secret! Not registered with the admin! """ location = models.CharField(max_length=100) @@ -556,7 +528,6 @@ def __str__(self): return self.location -@python_2_unicode_compatible class SuperSecretHideout(models.Model): """ Secret! Not registered with the admin! """ location = models.CharField(max_length=100) @@ -566,7 +537,6 @@ def __str__(self): return self.location -@python_2_unicode_compatible class Bookmark(models.Model): name = models.CharField(max_length=60) tag = GenericRelation(FunkyTag, related_query_name='bookmark') @@ -575,7 +545,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class CyclicOne(models.Model): name = models.CharField(max_length=25) two = models.ForeignKey('CyclicTwo', models.CASCADE) @@ -584,7 +553,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class CyclicTwo(models.Model): name = models.CharField(max_length=25) one = models.ForeignKey(CyclicOne, models.CASCADE) @@ -593,7 +561,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Topping(models.Model): name = models.CharField(max_length=20) @@ -625,7 +592,6 @@ class Question(models.Model): posted = models.DateField(default=datetime.date.today) -@python_2_unicode_compatible class Answer(models.Model): question = models.ForeignKey(Question, models.PROTECT) answer = models.CharField(max_length=20) @@ -660,7 +626,6 @@ class Meta: unique_together = (("driver", "restaurant"),) -@python_2_unicode_compatible class CoverLetter(models.Model): author = models.CharField(max_length=30) date_written = models.DateField(null=True, blank=True) @@ -679,7 +644,6 @@ class ShortMessage(models.Model): timestamp = models.DateTimeField(null=True, blank=True) -@python_2_unicode_compatible class Telegram(models.Model): title = models.CharField(max_length=30) date_sent = models.DateField(null=True, blank=True) @@ -745,7 +709,6 @@ class AdminOrderedCallable(models.Model): stuff = models.CharField(max_length=200) -@python_2_unicode_compatible class Report(models.Model): title = models.CharField(max_length=100) diff --git a/tests/admin_widgets/models.py b/tests/admin_widgets/models.py index 43aa88e254a0..fcc86ddeb820 100644 --- a/tests/admin_widgets/models.py +++ b/tests/admin_widgets/models.py @@ -1,13 +1,11 @@ from django.contrib.auth.models import User from django.db import models -from django.utils.encoding import python_2_unicode_compatible class MyFileField(models.FileField): pass -@python_2_unicode_compatible class Member(models.Model): name = models.CharField(max_length=100) birthdate = models.DateTimeField(blank=True, null=True) @@ -18,7 +16,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Band(models.Model): name = models.CharField(max_length=100) style = models.CharField(max_length=20) @@ -28,7 +25,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Album(models.Model): band = models.ForeignKey(Band, models.CASCADE) name = models.CharField(max_length=100) @@ -44,7 +40,6 @@ def get_queryset(self): return super(HiddenInventoryManager, self).get_queryset().filter(hidden=False) -@python_2_unicode_compatible class Inventory(models.Model): barcode = models.PositiveIntegerField(unique=True) parent = models.ForeignKey('self', models.SET_NULL, to_field='barcode', blank=True, null=True) @@ -79,7 +74,6 @@ class Event(models.Model): min_age = models.IntegerField(blank=True, null=True) -@python_2_unicode_compatible class Car(models.Model): owner = models.ForeignKey(User, models.CASCADE) make = models.CharField(max_length=30) @@ -134,7 +128,6 @@ class Advisor(models.Model): companies = models.ManyToManyField(Company) -@python_2_unicode_compatible class Student(models.Model): name = models.CharField(max_length=255) @@ -145,7 +138,6 @@ class Meta: ordering = ('name',) -@python_2_unicode_compatible class School(models.Model): name = models.CharField(max_length=255) students = models.ManyToManyField(Student, related_name='current_schools') @@ -155,7 +147,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Profile(models.Model): user = models.ForeignKey('auth.User', models.CASCADE, to_field='username') diff --git a/tests/aggregation/models.py b/tests/aggregation/models.py index 37421dbb81a2..fd441fe51d64 100644 --- a/tests/aggregation/models.py +++ b/tests/aggregation/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=100) age = models.IntegerField() @@ -12,7 +10,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Publisher(models.Model): name = models.CharField(max_length=255) num_awards = models.IntegerField() @@ -22,7 +19,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Book(models.Model): isbn = models.CharField(max_length=9) name = models.CharField(max_length=255) @@ -38,7 +34,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Store(models.Model): name = models.CharField(max_length=255) books = models.ManyToManyField(Book) diff --git a/tests/aggregation_regress/models.py b/tests/aggregation_regress/models.py index a9ab1cbdcea8..3498cbf1685c 100644 --- a/tests/aggregation_regress/models.py +++ b/tests/aggregation_regress/models.py @@ -3,10 +3,8 @@ ) from django.contrib.contenttypes.models import ContentType from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=100) age = models.IntegerField() @@ -16,7 +14,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Publisher(models.Model): name = models.CharField(max_length=255) num_awards = models.IntegerField() @@ -32,7 +29,6 @@ class ItemTag(models.Model): content_object = GenericForeignKey('content_type', 'object_id') -@python_2_unicode_compatible class Book(models.Model): isbn = models.CharField(max_length=9) name = models.CharField(max_length=255) @@ -52,7 +48,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Store(models.Model): name = models.CharField(max_length=255) books = models.ManyToManyField(Book) @@ -83,7 +78,6 @@ class WithManualPK(models.Model): id = models.IntegerField(primary_key=True) -@python_2_unicode_compatible class HardbackBook(Book): weight = models.FloatField() diff --git a/tests/annotations/models.py b/tests/annotations/models.py index 79648ffd961d..4aeda3c0931d 100644 --- a/tests/annotations/models.py +++ b/tests/annotations/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=100) age = models.IntegerField() @@ -12,7 +10,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Publisher(models.Model): name = models.CharField(max_length=255) num_awards = models.IntegerField() @@ -21,7 +18,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Book(models.Model): isbn = models.CharField(max_length=9) name = models.CharField(max_length=255) @@ -37,7 +33,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Store(models.Model): name = models.CharField(max_length=255) books = models.ManyToManyField(Book) @@ -48,7 +43,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class DepartmentStore(Store): chain = models.CharField(max_length=255) @@ -56,7 +50,6 @@ def __str__(self): return '%s - %s ' % (self.chain, self.name) -@python_2_unicode_compatible class Employee(models.Model): # The order of these fields matter, do not change. Certain backends # rely on field ordering to perform database conversions, and this @@ -72,7 +65,6 @@ def __str__(self): return '%s %s' % (self.first_name, self.last_name) -@python_2_unicode_compatible class Company(models.Model): name = models.CharField(max_length=200) motto = models.CharField(max_length=200, null=True, blank=True) @@ -85,7 +77,6 @@ def __str__(self): ) -@python_2_unicode_compatible class Ticket(models.Model): active_at = models.DateTimeField() duration = models.DurationField() diff --git a/tests/auth_tests/models/custom_permissions.py b/tests/auth_tests/models/custom_permissions.py index a6c5a1e96a85..73c10e50407e 100644 --- a/tests/auth_tests/models/custom_permissions.py +++ b/tests/auth_tests/models/custom_permissions.py @@ -5,7 +5,6 @@ """ from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin from django.db import models -from django.utils.encoding import python_2_unicode_compatible from .custom_user import CustomUserManager, RemoveGroupsAndPermissions @@ -19,7 +18,6 @@ def create_superuser(self, email, password, date_of_birth): with RemoveGroupsAndPermissions(): - @python_2_unicode_compatible class CustomPermissionsUser(AbstractBaseUser, PermissionsMixin): email = models.EmailField(verbose_name='email address', max_length=255, unique=True) date_of_birth = models.DateField() diff --git a/tests/auth_tests/models/custom_user.py b/tests/auth_tests/models/custom_user.py index fac51064baa0..049ae85e5c0b 100644 --- a/tests/auth_tests/models/custom_user.py +++ b/tests/auth_tests/models/custom_user.py @@ -3,7 +3,6 @@ PermissionsMixin, UserManager, ) from django.db import models -from django.utils.encoding import python_2_unicode_compatible # The custom user uses email as the unique identifier, and requires @@ -33,7 +32,6 @@ def create_superuser(self, email, password, date_of_birth): return u -@python_2_unicode_compatible class CustomUser(AbstractBaseUser): email = models.EmailField(verbose_name='email address', max_length=255, unique=True) is_active = models.BooleanField(default=True) diff --git a/tests/backends/models.py b/tests/backends/models.py index 18423e1276c6..6277e52525bc 100644 --- a/tests/backends/models.py +++ b/tests/backends/models.py @@ -3,10 +3,8 @@ ) from django.contrib.contenttypes.models import ContentType from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Square(models.Model): root = models.IntegerField() square = models.PositiveIntegerField() @@ -15,7 +13,6 @@ def __str__(self): return "%s ** 2 == %s" % (self.root, self.square) -@python_2_unicode_compatible class Person(models.Model): first_name = models.CharField(max_length=20) last_name = models.CharField(max_length=20) @@ -52,7 +49,6 @@ class Meta: db_table = 'CaseSensitive_Post' -@python_2_unicode_compatible class Reporter(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) @@ -66,7 +62,6 @@ class Meta: proxy = True -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100) pub_date = models.DateField() @@ -82,7 +77,6 @@ def __str__(self): return self.headline -@python_2_unicode_compatible class Item(models.Model): name = models.CharField(max_length=30) date = models.DateField() @@ -93,7 +87,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Object(models.Model): related_objects = models.ManyToManyField("self", db_constraint=False, symmetrical=False) @@ -101,7 +94,6 @@ def __str__(self): return str(self.id) -@python_2_unicode_compatible class ObjectReference(models.Model): obj = models.ForeignKey(Object, models.CASCADE, db_constraint=False) diff --git a/tests/basic/models.py b/tests/basic/models.py index a6010f1291ff..c08b147ac475 100644 --- a/tests/basic/models.py +++ b/tests/basic/models.py @@ -4,10 +4,8 @@ This is a basic model with only two non-primary-key fields. """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100, default='Default headline') pub_date = models.DateTimeField() @@ -25,7 +23,6 @@ class Meta: select_on_save = True -@python_2_unicode_compatible class SelfRef(models.Model): selfref = models.ForeignKey( 'self', diff --git a/tests/choices/models.py b/tests/choices/models.py index 3384947f93cf..de681183864f 100644 --- a/tests/choices/models.py +++ b/tests/choices/models.py @@ -10,7 +10,6 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible GENDER_CHOICES = ( ('M', 'Male'), @@ -18,7 +17,6 @@ ) -@python_2_unicode_compatible class Person(models.Model): name = models.CharField(max_length=20) gender = models.CharField(max_length=1, choices=GENDER_CHOICES) diff --git a/tests/contenttypes_tests/models.py b/tests/contenttypes_tests/models.py index 1640ee3b8cc4..0aa8bbf0bc75 100644 --- a/tests/contenttypes_tests/models.py +++ b/tests/contenttypes_tests/models.py @@ -4,11 +4,9 @@ from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import SiteManager from django.db import models -from django.utils.encoding import python_2_unicode_compatible from django.utils.http import urlquote -@python_2_unicode_compatible class Site(models.Model): domain = models.CharField(max_length=100) objects = SiteManager() @@ -17,7 +15,6 @@ def __str__(self): return self.domain -@python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=100) @@ -28,7 +25,6 @@ def get_absolute_url(self): return '/authors/%s/' % self.id -@python_2_unicode_compatible class Article(models.Model): title = models.CharField(max_length=100) slug = models.SlugField() @@ -39,7 +35,6 @@ def __str__(self): return self.title -@python_2_unicode_compatible class SchemeIncludedURL(models.Model): url = models.URLField(max_length=100) @@ -59,7 +54,6 @@ class Meta: proxy = True -@python_2_unicode_compatible class FooWithoutUrl(models.Model): """ Fake model not defining ``get_absolute_url`` for @@ -95,7 +89,6 @@ class Question(models.Model): answer_set = GenericRelation('Answer') -@python_2_unicode_compatible class Answer(models.Model): text = models.CharField(max_length=200) content_type = models.ForeignKey(ContentType, models.CASCADE) @@ -109,7 +102,6 @@ def __str__(self): return self.text -@python_2_unicode_compatible class Post(models.Model): """An ordered tag on an item.""" title = models.CharField(max_length=200) @@ -125,7 +117,6 @@ def __str__(self): return self.title -@python_2_unicode_compatible class ModelWithNullFKToSite(models.Model): title = models.CharField(max_length=200) site = models.ForeignKey(Site, null=True, on_delete=models.CASCADE) diff --git a/tests/custom_columns/models.py b/tests/custom_columns/models.py index d5f5217ba5a9..32d55af9f38f 100644 --- a/tests/custom_columns/models.py +++ b/tests/custom_columns/models.py @@ -16,10 +16,8 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Author(models.Model): Author_ID = models.AutoField(primary_key=True, db_column='Author ID') first_name = models.CharField(max_length=30, db_column='firstname') @@ -33,7 +31,6 @@ class Meta: ordering = ('last_name', 'first_name') -@python_2_unicode_compatible class Article(models.Model): Article_ID = models.AutoField(primary_key=True, db_column='Article ID') headline = models.CharField(max_length=100) diff --git a/tests/custom_lookups/models.py b/tests/custom_lookups/models.py index 97979dd95389..071858cd3d1b 100644 --- a/tests/custom_lookups/models.py +++ b/tests/custom_lookups/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=20) age = models.IntegerField(null=True) @@ -17,7 +15,6 @@ class Article(models.Model): author = models.ForeignKey(Author, on_delete=models.CASCADE) -@python_2_unicode_compatible class MySQLUnixTimestamp(models.Model): timestamp = models.PositiveIntegerField() diff --git a/tests/custom_managers/models.py b/tests/custom_managers/models.py index 1d47869af9f6..c5f224ea5155 100644 --- a/tests/custom_managers/models.py +++ b/tests/custom_managers/models.py @@ -13,7 +13,6 @@ GenericForeignKey, GenericRelation, ) from django.db import models -from django.utils.encoding import python_2_unicode_compatible class PersonManager(models.Manager): @@ -86,7 +85,6 @@ def get_queryset(self): return super(BoringPeopleManager, self).get_queryset().filter(fun=False) -@python_2_unicode_compatible class Person(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) @@ -109,7 +107,6 @@ def __str__(self): return "%s %s" % (self.first_name, self.last_name) -@python_2_unicode_compatible class FunPerson(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) @@ -130,7 +127,6 @@ def __str__(self): return "%s %s" % (self.first_name, self.last_name) -@python_2_unicode_compatible class Book(models.Model): title = models.CharField(max_length=50) author = models.CharField(max_length=30) @@ -158,7 +154,6 @@ def get_queryset(self): return super(FastCarManager, self).get_queryset().filter(top_speed__gt=150) -@python_2_unicode_compatible class Car(models.Model): name = models.CharField(max_length=10) mileage = models.IntegerField() @@ -187,7 +182,6 @@ def get_queryset(self): return super(RestrictedManager, self).get_queryset().filter(is_public=True) -@python_2_unicode_compatible class RelatedModel(models.Model): name = models.CharField(max_length=50) @@ -195,7 +189,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class RestrictedModel(models.Model): name = models.CharField(max_length=50) is_public = models.BooleanField(default=False) @@ -208,7 +201,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class OneToOneRestrictedModel(models.Model): name = models.CharField(max_length=50) is_public = models.BooleanField(default=False) diff --git a/tests/custom_methods/models.py b/tests/custom_methods/models.py index 7def1d6017b7..f44d1b8265b0 100644 --- a/tests/custom_methods/models.py +++ b/tests/custom_methods/models.py @@ -7,10 +7,8 @@ import datetime from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100) pub_date = models.DateField() diff --git a/tests/custom_pk/fields.py b/tests/custom_pk/fields.py index 3779fc6c4336..eb63f66679b4 100644 --- a/tests/custom_pk/fields.py +++ b/tests/custom_pk/fields.py @@ -3,10 +3,8 @@ from django.db import models from django.utils import six -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class MyWrapper(object): def __init__(self, value): self.value = value diff --git a/tests/custom_pk/models.py b/tests/custom_pk/models.py index e0a318468c43..0b272c113531 100644 --- a/tests/custom_pk/models.py +++ b/tests/custom_pk/models.py @@ -6,12 +6,10 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible from .fields import MyAutoField -@python_2_unicode_compatible class Employee(models.Model): employee_code = models.IntegerField(primary_key=True, db_column='code') first_name = models.CharField(max_length=20) @@ -24,7 +22,6 @@ def __str__(self): return "%s %s" % (self.first_name, self.last_name) -@python_2_unicode_compatible class Business(models.Model): name = models.CharField(max_length=20, primary_key=True) employees = models.ManyToManyField(Employee) @@ -36,7 +33,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Bar(models.Model): id = MyAutoField(primary_key=True, db_index=True) diff --git a/tests/datatypes/models.py b/tests/datatypes/models.py index cabe5297bd67..570b2ba8e066 100644 --- a/tests/datatypes/models.py +++ b/tests/datatypes/models.py @@ -4,10 +4,8 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Donut(models.Model): name = models.CharField(max_length=100) is_frosted = models.BooleanField(default=False) diff --git a/tests/dates/models.py b/tests/dates/models.py index 978cf44e955f..74f9db28ad57 100644 --- a/tests/dates/models.py +++ b/tests/dates/models.py @@ -1,9 +1,7 @@ from django.db import models from django.utils import timezone -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Article(models.Model): title = models.CharField(max_length=100) pub_date = models.DateField() @@ -15,7 +13,6 @@ def __str__(self): return self.title -@python_2_unicode_compatible class Comment(models.Model): article = models.ForeignKey(Article, models.CASCADE, related_name="comments") text = models.TextField() diff --git a/tests/datetimes/models.py b/tests/datetimes/models.py index 4d2ad9ac7add..c8b64ae52a43 100644 --- a/tests/datetimes/models.py +++ b/tests/datetimes/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Article(models.Model): title = models.CharField(max_length=100) pub_date = models.DateTimeField() @@ -14,7 +12,6 @@ def __str__(self): return self.title -@python_2_unicode_compatible class Comment(models.Model): article = models.ForeignKey(Article, models.CASCADE, related_name="comments") text = models.TextField() diff --git a/tests/db_functions/models.py b/tests/db_functions/models.py index 8d0fbc6debcf..bfcdb7759e5d 100644 --- a/tests/db_functions/models.py +++ b/tests/db_functions/models.py @@ -2,10 +2,8 @@ Tests for built in Function expressions. """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=50) alias = models.CharField(max_length=50, null=True, blank=True) @@ -16,7 +14,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Article(models.Model): authors = models.ManyToManyField(Author, related_name='articles') title = models.CharField(max_length=50) @@ -31,7 +28,6 @@ def __str__(self): return self.title -@python_2_unicode_compatible class Fan(models.Model): name = models.CharField(max_length=50) age = models.PositiveSmallIntegerField(default=30) @@ -41,7 +37,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class DTModel(models.Model): name = models.CharField(max_length=32) start_datetime = models.DateTimeField(null=True, blank=True) diff --git a/tests/defer/models.py b/tests/defer/models.py index b36b17350178..dbdce0b02563 100644 --- a/tests/defer/models.py +++ b/tests/defer/models.py @@ -3,7 +3,6 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible class Secondary(models.Model): @@ -11,7 +10,6 @@ class Secondary(models.Model): second = models.CharField(max_length=50) -@python_2_unicode_compatible class Primary(models.Model): name = models.CharField(max_length=50) value = models.CharField(max_length=50) diff --git a/tests/defer_regress/models.py b/tests/defer_regress/models.py index a73f539ba18f..55eac8c537c8 100644 --- a/tests/defer_regress/models.py +++ b/tests/defer_regress/models.py @@ -3,10 +3,8 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Item(models.Model): name = models.CharField(max_length=15) text = models.TextField(default="xyzzy") @@ -31,7 +29,6 @@ class Child(models.Model): value = models.IntegerField() -@python_2_unicode_compatible class Leaf(models.Model): name = models.CharField(max_length=10) child = models.ForeignKey(Child, models.CASCADE) @@ -52,7 +49,6 @@ class Meta: proxy = True -@python_2_unicode_compatible class SimpleItem(models.Model): name = models.CharField(max_length=15) value = models.IntegerField() diff --git a/tests/delete/models.py b/tests/delete/models.py index 4064173df481..2fc5ebe217db 100644 --- a/tests/delete/models.py +++ b/tests/delete/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class R(models.Model): is_default = models.BooleanField(default=False) diff --git a/tests/distinct_on_fields/models.py b/tests/distinct_on_fields/models.py index a4164724f3e3..06c4f349c066 100644 --- a/tests/distinct_on_fields/models.py +++ b/tests/distinct_on_fields/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Tag(models.Model): name = models.CharField(max_length=10) parent = models.ForeignKey( @@ -20,7 +18,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Celebrity(models.Model): name = models.CharField("Name", max_length=20) greatest_fan = models.ForeignKey( @@ -38,7 +35,6 @@ class Fan(models.Model): fan_of = models.ForeignKey(Celebrity, models.CASCADE) -@python_2_unicode_compatible class Staff(models.Model): id = models.IntegerField(primary_key=True) name = models.CharField(max_length=50) @@ -50,7 +46,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class StaffTag(models.Model): staff = models.ForeignKey(Staff, models.CASCADE) tag = models.ForeignKey(Tag, models.CASCADE) diff --git a/tests/expressions/models.py b/tests/expressions/models.py index e2bfb8ef679d..51042c845b1b 100644 --- a/tests/expressions/models.py +++ b/tests/expressions/models.py @@ -3,10 +3,8 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Employee(models.Model): firstname = models.CharField(max_length=50) lastname = models.CharField(max_length=50) @@ -16,7 +14,6 @@ def __str__(self): return '%s %s' % (self.firstname, self.lastname) -@python_2_unicode_compatible class Company(models.Model): name = models.CharField(max_length=100) num_employees = models.PositiveIntegerField() @@ -35,7 +32,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Number(models.Model): integer = models.BigIntegerField(db_column='the_integer') float = models.FloatField(null=True, db_column='the_float') @@ -59,7 +55,6 @@ def duration(self): return self.end - self.start -@python_2_unicode_compatible class Result(models.Model): experiment = models.ForeignKey(Experiment, models.CASCADE) result_time = models.DateTimeField() @@ -68,7 +63,6 @@ def __str__(self): return "Result at %s" % self.result_time -@python_2_unicode_compatible class Time(models.Model): time = models.TimeField(null=True) @@ -76,7 +70,6 @@ def __str__(self): return "%s" % self.time -@python_2_unicode_compatible class SimulationRun(models.Model): start = models.ForeignKey(Time, models.CASCADE, null=True, related_name='+') end = models.ForeignKey(Time, models.CASCADE, null=True, related_name='+') @@ -86,7 +79,6 @@ def __str__(self): return "%s (%s to %s)" % (self.midpoint, self.start, self.end) -@python_2_unicode_compatible class UUID(models.Model): uuid = models.UUIDField(null=True) diff --git a/tests/expressions_case/models.py b/tests/expressions_case/models.py index 8c2eaac3996d..7c1a8d75b793 100644 --- a/tests/expressions_case/models.py +++ b/tests/expressions_case/models.py @@ -1,5 +1,4 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible try: from PIL import Image @@ -7,7 +6,6 @@ Image = None -@python_2_unicode_compatible class CaseTestModel(models.Model): integer = models.IntegerField() integer2 = models.IntegerField(null=True) @@ -42,7 +40,6 @@ def __str__(self): return "%i, %s" % (self.integer, self.string) -@python_2_unicode_compatible class O2OCaseTestModel(models.Model): o2o = models.OneToOneField(CaseTestModel, models.CASCADE, related_name='o2o_rel') integer = models.IntegerField() @@ -51,7 +48,6 @@ def __str__(self): return "%i, %s" % (self.id, self.o2o) -@python_2_unicode_compatible class FKCaseTestModel(models.Model): fk = models.ForeignKey(CaseTestModel, models.CASCADE, related_name='fk_rel') integer = models.IntegerField() @@ -60,7 +56,6 @@ def __str__(self): return "%i, %s" % (self.id, self.fk) -@python_2_unicode_compatible class Client(models.Model): REGULAR = 'R' GOLD = 'G' diff --git a/tests/extra_regress/models.py b/tests/extra_regress/models.py index b271d8701f2f..1a5c2dedeb8e 100644 --- a/tests/extra_regress/models.py +++ b/tests/extra_regress/models.py @@ -3,10 +3,8 @@ from django.contrib.auth.models import User from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class RevisionableModel(models.Model): base = models.ForeignKey('self', models.SET_NULL, null=True) title = models.CharField(blank=True, max_length=255) @@ -34,7 +32,6 @@ class Order(models.Model): text = models.TextField() -@python_2_unicode_compatible class TestObject(models.Model): first = models.CharField(max_length=20) second = models.CharField(max_length=20) diff --git a/tests/field_defaults/models.py b/tests/field_defaults/models.py index 71129cb5c71e..e125dd1c4f00 100644 --- a/tests/field_defaults/models.py +++ b/tests/field_defaults/models.py @@ -12,10 +12,8 @@ from datetime import datetime from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100, default='Default headline') pub_date = models.DateTimeField(default=datetime.now) diff --git a/tests/fixtures/models.py b/tests/fixtures/models.py index 78161c84744e..b3ebb8fc5d3c 100644 --- a/tests/fixtures/models.py +++ b/tests/fixtures/models.py @@ -14,10 +14,8 @@ from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Category(models.Model): title = models.CharField(max_length=100) description = models.TextField() @@ -29,7 +27,6 @@ class Meta: ordering = ('title',) -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100, default='Default headline') pub_date = models.DateTimeField() @@ -41,7 +38,6 @@ class Meta: ordering = ('-pub_date', 'headline') -@python_2_unicode_compatible class Blog(models.Model): name = models.CharField(max_length=100) featured = models.ForeignKey(Article, models.CASCADE, related_name='fixtures_featured_set') @@ -52,7 +48,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Tag(models.Model): name = models.CharField(max_length=100) tagged_type = models.ForeignKey(ContentType, models.CASCADE, related_name="fixtures_tag_set") @@ -69,7 +64,6 @@ def get_by_natural_key(self, name): return self.get(name=name) -@python_2_unicode_compatible class Person(models.Model): objects = PersonManager() name = models.CharField(max_length=100) @@ -99,7 +93,6 @@ class Meta: proxy = True -@python_2_unicode_compatible class Visa(models.Model): person = models.ForeignKey(Person, models.CASCADE) permissions = models.ManyToManyField(Permission, blank=True) @@ -109,7 +102,6 @@ def __str__(self): ', '.join(p.name for p in self.permissions.all())) -@python_2_unicode_compatible class Book(models.Model): name = models.CharField(max_length=100) authors = models.ManyToManyField(Person) diff --git a/tests/fixtures_model_package/models/__init__.py b/tests/fixtures_model_package/models/__init__.py index 63d73f83f96f..5160f354e673 100644 --- a/tests/fixtures_model_package/models/__init__.py +++ b/tests/fixtures_model_package/models/__init__.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100, default='Default headline') pub_date = models.DateTimeField() diff --git a/tests/fixtures_regress/models.py b/tests/fixtures_regress/models.py index 63e883f7d541..a631fa44d105 100644 --- a/tests/fixtures_regress/models.py +++ b/tests/fixtures_regress/models.py @@ -1,10 +1,8 @@ from django.contrib.auth.models import User from django.db import models from django.utils import six -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Animal(models.Model): name = models.CharField(max_length=150) latin_name = models.CharField(max_length=150) @@ -26,7 +24,6 @@ class Meta: db_table = "Fixtures_regress_plant" -@python_2_unicode_compatible class Stuff(models.Model): name = models.CharField(max_length=20, null=True) owner = models.ForeignKey(User, models.SET_NULL, null=True) @@ -80,7 +77,6 @@ class Feature(CommonFeature): # Models to regression test #11428 -@python_2_unicode_compatible class Widget(models.Model): name = models.CharField(max_length=255) @@ -102,7 +98,6 @@ def get_by_natural_key(self, key): return self.get(name=key) -@python_2_unicode_compatible class Store(models.Model): objects = TestManager() name = models.CharField(max_length=255) @@ -118,7 +113,6 @@ def natural_key(self): return (self.name,) -@python_2_unicode_compatible class Person(models.Model): objects = TestManager() name = models.CharField(max_length=255) @@ -136,7 +130,6 @@ def natural_key(self): natural_key.dependencies = ['fixtures_regress.store'] -@python_2_unicode_compatible class Book(models.Model): name = models.CharField(max_length=255) author = models.ForeignKey(Person, models.CASCADE) @@ -158,7 +151,6 @@ def get_by_natural_key(self, data): return self.get(data=data) -@python_2_unicode_compatible class NKChild(Parent): data = models.CharField(max_length=10, unique=True) objects = NKManager() @@ -170,7 +162,6 @@ def __str__(self): return 'NKChild %s:%s' % (self.name, self.data) -@python_2_unicode_compatible class RefToNKChild(models.Model): text = models.CharField(max_length=10) nk_fk = models.ForeignKey(NKChild, models.CASCADE, related_name='ref_fks') @@ -250,7 +241,6 @@ class M2MToSelf(models.Model): parent = models.ManyToManyField("self", blank=True) -@python_2_unicode_compatible class BaseNKModel(models.Model): """ Base model with a natural_key and a manager with `get_by_natural_key` diff --git a/tests/foreign_object/models/article.py b/tests/foreign_object/models/article.py index 6e16784d2c60..e5c0c1f67372 100644 --- a/tests/foreign_object/models/article.py +++ b/tests/foreign_object/models/article.py @@ -1,6 +1,5 @@ from django.db import models from django.db.models.fields.related import ForwardManyToOneDescriptor -from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import get_language @@ -49,7 +48,6 @@ def get_extra_descriptor_filter(self, instance): return models.Q(lang=get_language()) -@python_2_unicode_compatible class Article(models.Model): active_translation = ActiveTranslationField( 'ArticleTranslation', diff --git a/tests/foreign_object/models/empty_join.py b/tests/foreign_object/models/empty_join.py index 28f3006c9471..5b58ffdafcc5 100644 --- a/tests/foreign_object/models/empty_join.py +++ b/tests/foreign_object/models/empty_join.py @@ -4,7 +4,6 @@ ) from django.db.models.lookups import StartsWith from django.db.models.query_utils import PathInfo -from django.utils.encoding import python_2_unicode_compatible class CustomForeignObjectRel(ForeignObjectRel): @@ -78,7 +77,6 @@ def get_extra_restriction(self, where_class, alias, related_alias): return None -@python_2_unicode_compatible class SlugPage(models.Model): slug = models.CharField(max_length=20, unique=True) descendants = StartsWithRelation( diff --git a/tests/foreign_object/models/person.py b/tests/foreign_object/models/person.py index 26d88007fbe7..a41d9d96d98d 100644 --- a/tests/foreign_object/models/person.py +++ b/tests/foreign_object/models/person.py @@ -1,10 +1,8 @@ import datetime from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Country(models.Model): # Table Column Fields name = models.CharField(max_length=50) @@ -13,7 +11,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Person(models.Model): # Table Column Fields name = models.CharField(max_length=128) @@ -35,7 +32,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Group(models.Model): # Table Column Fields name = models.CharField(max_length=128) @@ -49,7 +45,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Membership(models.Model): # Table Column Fields membership_country = models.ForeignKey(Country, models.CASCADE) diff --git a/tests/forms_tests/models.py b/tests/forms_tests/models.py index be1b66bce664..fa63d08fd1b2 100644 --- a/tests/forms_tests/models.py +++ b/tests/forms_tests/models.py @@ -4,7 +4,6 @@ from django.core.files.storage import FileSystemStorage from django.db import models -from django.utils.encoding import python_2_unicode_compatible callable_default_counter = itertools.count() @@ -55,7 +54,6 @@ class ChoiceModel(models.Model): null=True) -@python_2_unicode_compatible class ChoiceOptionModel(models.Model): """Destination for ChoiceFieldModel's ForeignKey. Can't reuse ChoiceModel because error_message tests require that it have no instances.""" @@ -132,7 +130,6 @@ class FileModel(models.Model): file = models.FileField(storage=temp_storage, upload_to='tests') -@python_2_unicode_compatible class Group(models.Model): name = models.CharField(max_length=10) diff --git a/tests/forms_tests/tests/test_error_messages.py b/tests/forms_tests/tests/test_error_messages.py index eb7debf936ba..10c7a92f7def 100644 --- a/tests/forms_tests/tests/test_error_messages.py +++ b/tests/forms_tests/tests/test_error_messages.py @@ -8,7 +8,6 @@ ) from django.template import Context, Template from django.test import SimpleTestCase, TestCase -from django.utils.encoding import python_2_unicode_compatible from django.utils.safestring import mark_safe from ..models import ChoiceModel @@ -216,7 +215,6 @@ class TestForm(Form): def clean(self): raise ValidationError("I like to be awkward.") - @python_2_unicode_compatible class CustomErrorList(utils.ErrorList): def __str__(self): return self.as_divs() diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py index b8ced2425c23..dacd7739d307 100644 --- a/tests/forms_tests/tests/test_forms.py +++ b/tests/forms_tests/tests/test_forms.py @@ -21,7 +21,7 @@ from django.test import SimpleTestCase from django.test.utils import str_prefix from django.utils.datastructures import MultiValueDict -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import force_text from django.utils.html import format_html from django.utils.safestring import SafeData, mark_safe @@ -3375,7 +3375,6 @@ def clean(self): ) def test_errorlist_override(self): - @python_2_unicode_compatible class DivErrorList(ErrorList): def __str__(self): return self.as_divs() diff --git a/tests/forms_tests/tests/test_utils.py b/tests/forms_tests/tests/test_utils.py index d0dfaad3703d..f06b60a620d6 100644 --- a/tests/forms_tests/tests/test_utils.py +++ b/tests/forms_tests/tests/test_utils.py @@ -4,7 +4,7 @@ from django.forms.utils import ErrorDict, ErrorList, flatatt from django.test import SimpleTestCase from django.utils import six -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import force_text from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy @@ -101,7 +101,6 @@ def test_validation_error(self): '' ) - @python_2_unicode_compatible class VeryBadError: def __str__(self): return "A very bad error." diff --git a/tests/forms_tests/widget_tests/test_clearablefileinput.py b/tests/forms_tests/widget_tests/test_clearablefileinput.py index 3727d0c0df9d..dd7f04d0acca 100644 --- a/tests/forms_tests/widget_tests/test_clearablefileinput.py +++ b/tests/forms_tests/widget_tests/test_clearablefileinput.py @@ -1,11 +1,9 @@ from django.core.files.uploadedfile import SimpleUploadedFile from django.forms import ClearableFileInput -from django.utils.encoding import python_2_unicode_compatible from .base import WidgetTest -@python_2_unicode_compatible class FakeFieldFile(object): """ Quacks like a FieldFile (has a .url and unicode representation), but @@ -39,7 +37,6 @@ def test_html_escaped(self): A ClearableFileInput should escape name, filename, and URL when rendering HTML (#15182). """ - @python_2_unicode_compatible class StrangeFieldFile(object): url = "something?chapter=1§=2©=3&lang=en" @@ -110,7 +107,6 @@ def test_html_does_not_mask_exceptions(self): A ClearableFileInput should not mask exceptions produced while checking that it has a value. """ - @python_2_unicode_compatible class FailingURLFieldFile(object): @property def url(self): @@ -123,7 +119,6 @@ def __str__(self): self.widget.render('myfile', FailingURLFieldFile()) def test_url_as_property(self): - @python_2_unicode_compatible class URLFieldFile(object): @property def url(self): @@ -136,7 +131,6 @@ def __str__(self): self.assertInHTML('value', html) def test_return_false_if_url_does_not_exists(self): - @python_2_unicode_compatible class NoURLFieldFile(object): def __str__(self): return 'value' diff --git a/tests/from_db_value/models.py b/tests/from_db_value/models.py index aa62b1f56725..fae9565a0241 100644 --- a/tests/from_db_value/models.py +++ b/tests/from_db_value/models.py @@ -1,7 +1,6 @@ import decimal from django.db import models -from django.utils.encoding import python_2_unicode_compatible class Cash(decimal.Decimal): @@ -24,7 +23,6 @@ def from_db_value(self, value, expression, connection, context): return cash -@python_2_unicode_compatible class CashModel(models.Model): cash = CashField() diff --git a/tests/generic_inline_admin/models.py b/tests/generic_inline_admin/models.py index e981612bd8db..96cb6fb5a32d 100644 --- a/tests/generic_inline_admin/models.py +++ b/tests/generic_inline_admin/models.py @@ -3,7 +3,6 @@ ) from django.contrib.contenttypes.models import ContentType from django.db import models -from django.utils.encoding import python_2_unicode_compatible class Episode(models.Model): @@ -12,7 +11,6 @@ class Episode(models.Model): author = models.CharField(max_length=100, blank=True) -@python_2_unicode_compatible class Media(models.Model): """ Media that can associated to any object. diff --git a/tests/generic_relations/models.py b/tests/generic_relations/models.py index f1748b743326..a2f68ff05a12 100644 --- a/tests/generic_relations/models.py +++ b/tests/generic_relations/models.py @@ -14,10 +14,8 @@ ) from django.contrib.contenttypes.models import ContentType from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class TaggedItem(models.Model): """A tag on an item.""" tag = models.SlugField() @@ -46,7 +44,6 @@ class AbstractComparison(models.Model): first_obj = GenericForeignKey(ct_field="content_type1", fk_field="object_id1") -@python_2_unicode_compatible class Comparison(AbstractComparison): """ A model that tests having multiple GenericForeignKeys. One is defined @@ -61,7 +58,6 @@ def __str__(self): return "%s is %s than %s" % (self.first_obj, self.comparative, self.other_obj) -@python_2_unicode_compatible class Animal(models.Model): common_name = models.CharField(max_length=150) latin_name = models.CharField(max_length=150) @@ -75,7 +71,6 @@ def __str__(self): return self.common_name -@python_2_unicode_compatible class Vegetable(models.Model): name = models.CharField(max_length=150) is_yucky = models.BooleanField(default=True) @@ -90,7 +85,6 @@ class Carrot(Vegetable): pass -@python_2_unicode_compatible class Mineral(models.Model): name = models.CharField(max_length=150) hardness = models.PositiveSmallIntegerField() diff --git a/tests/generic_relations_regress/models.py b/tests/generic_relations_regress/models.py index eb4f645d3450..d9cf692b75d5 100644 --- a/tests/generic_relations_regress/models.py +++ b/tests/generic_relations_regress/models.py @@ -4,14 +4,12 @@ from django.contrib.contenttypes.models import ContentType from django.db import models from django.db.models.deletion import ProtectedError -from django.utils.encoding import python_2_unicode_compatible __all__ = ('Link', 'Place', 'Restaurant', 'Person', 'Address', 'CharLink', 'TextLink', 'OddRelation1', 'OddRelation2', 'Contact', 'Organization', 'Note', 'Company') -@python_2_unicode_compatible class Link(models.Model): content_type = models.ForeignKey(ContentType, models.CASCADE) object_id = models.PositiveIntegerField() @@ -21,7 +19,6 @@ def __str__(self): return "Link to %s id=%s" % (self.content_type, self.object_id) -@python_2_unicode_compatible class Place(models.Model): name = models.CharField(max_length=100) links = GenericRelation(Link) @@ -30,13 +27,11 @@ def __str__(self): return "Place: %s" % self.name -@python_2_unicode_compatible class Restaurant(Place): def __str__(self): return "Restaurant: %s" % self.name -@python_2_unicode_compatible class Address(models.Model): street = models.CharField(max_length=80) city = models.CharField(max_length=50) @@ -50,7 +45,6 @@ def __str__(self): return '%s %s, %s %s' % (self.street, self.city, self.state, self.zipcode) -@python_2_unicode_compatible class Person(models.Model): account = models.IntegerField(primary_key=True) name = models.CharField(max_length=128) @@ -99,7 +93,6 @@ class Organization(models.Model): contacts = models.ManyToManyField(Contact, related_name='organizations') -@python_2_unicode_compatible class Company(models.Model): name = models.CharField(max_length=100) links = GenericRelation(Link) @@ -113,7 +106,6 @@ class Developer(models.Model): name = models.CharField(max_length=15) -@python_2_unicode_compatible class Team(models.Model): name = models.CharField(max_length=15) members = models.ManyToManyField(Developer) diff --git a/tests/generic_views/models.py b/tests/generic_views/models.py index a840df7d62dc..8f806b9a851f 100644 --- a/tests/generic_views/models.py +++ b/tests/generic_views/models.py @@ -2,10 +2,8 @@ from django.db.models import QuerySet from django.db.models.manager import BaseManager from django.urls import reverse -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Artist(models.Model): name = models.CharField(max_length=100) @@ -21,7 +19,6 @@ def get_absolute_url(self): return reverse('artist_detail', kwargs={'pk': self.id}) -@python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=100) slug = models.SlugField() @@ -41,7 +38,6 @@ def get(self, *args, **kwargs): DoesNotExistBookManager = BaseManager.from_queryset(DoesNotExistQuerySet) -@python_2_unicode_compatible class Book(models.Model): name = models.CharField(max_length=300) slug = models.SlugField() diff --git a/tests/get_object_or_404/models.py b/tests/get_object_or_404/models.py index 4460e46642c0..ce74bc04adb9 100644 --- a/tests/get_object_or_404/models.py +++ b/tests/get_object_or_404/models.py @@ -11,10 +11,8 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=50) @@ -27,7 +25,6 @@ def get_queryset(self): return super(ArticleManager, self).get_queryset().filter(authors__name__icontains='sir') -@python_2_unicode_compatible class Article(models.Model): authors = models.ManyToManyField(Author) title = models.CharField(max_length=50) diff --git a/tests/get_or_create/models.py b/tests/get_or_create/models.py index 5d6e69de3a71..cfde80ce85ad 100644 --- a/tests/get_or_create/models.py +++ b/tests/get_or_create/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Person(models.Model): first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) diff --git a/tests/gis_tests/distapp/models.py b/tests/gis_tests/distapp/models.py index 43a2acacdff4..1a5ef2cf9043 100644 --- a/tests/gis_tests/distapp/models.py +++ b/tests/gis_tests/distapp/models.py @@ -1,10 +1,8 @@ from django.contrib.gis.db import models -from django.utils.encoding import python_2_unicode_compatible from ..utils import gisfield_may_be_null -@python_2_unicode_compatible class NamedModel(models.Model): name = models.CharField(max_length=30) diff --git a/tests/gis_tests/geo3d/models.py b/tests/gis_tests/geo3d/models.py index 42467c5ce483..b7d3257f99b5 100644 --- a/tests/gis_tests/geo3d/models.py +++ b/tests/gis_tests/geo3d/models.py @@ -1,8 +1,6 @@ from django.contrib.gis.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class NamedModel(models.Model): name = models.CharField(max_length=30) diff --git a/tests/gis_tests/geoadmin/models.py b/tests/gis_tests/geoadmin/models.py index e57dcd7e9a3b..9303dc1228bb 100644 --- a/tests/gis_tests/geoadmin/models.py +++ b/tests/gis_tests/geoadmin/models.py @@ -1,10 +1,8 @@ from django.contrib.gis.db import models -from django.utils.encoding import python_2_unicode_compatible from ..admin import admin -@python_2_unicode_compatible class City(models.Model): name = models.CharField(max_length=30) point = models.PointField() diff --git a/tests/gis_tests/geoapp/models.py b/tests/gis_tests/geoapp/models.py index f5f4c38b428c..83e324204311 100644 --- a/tests/gis_tests/geoapp/models.py +++ b/tests/gis_tests/geoapp/models.py @@ -1,10 +1,8 @@ from django.contrib.gis.db import models -from django.utils.encoding import python_2_unicode_compatible from ..utils import gisfield_may_be_null -@python_2_unicode_compatible class NamedModel(models.Model): name = models.CharField(max_length=30) diff --git a/tests/gis_tests/geogapp/models.py b/tests/gis_tests/geogapp/models.py index 6bc5955923dc..3a658a6c47da 100644 --- a/tests/gis_tests/geogapp/models.py +++ b/tests/gis_tests/geogapp/models.py @@ -1,8 +1,6 @@ from django.contrib.gis.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class NamedModel(models.Model): name = models.CharField(max_length=30) diff --git a/tests/gis_tests/layermap/models.py b/tests/gis_tests/layermap/models.py index 25dd0e4bcdd4..7bb7717fe832 100644 --- a/tests/gis_tests/layermap/models.py +++ b/tests/gis_tests/layermap/models.py @@ -1,8 +1,6 @@ from django.contrib.gis.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class NamedModel(models.Model): name = models.CharField(max_length=25) diff --git a/tests/gis_tests/relatedapp/models.py b/tests/gis_tests/relatedapp/models.py index 6d674588dd3c..749f39f74c11 100644 --- a/tests/gis_tests/relatedapp/models.py +++ b/tests/gis_tests/relatedapp/models.py @@ -1,5 +1,4 @@ from django.contrib.gis.db import models -from django.utils.encoding import python_2_unicode_compatible class SimpleModel(models.Model): @@ -8,7 +7,6 @@ class Meta: required_db_features = ['gis_enabled'] -@python_2_unicode_compatible class Location(SimpleModel): point = models.PointField() @@ -16,7 +14,6 @@ def __str__(self): return self.point.wkt -@python_2_unicode_compatible class City(SimpleModel): name = models.CharField(max_length=50) state = models.CharField(max_length=2) @@ -35,7 +32,6 @@ class DirectoryEntry(SimpleModel): location = models.ForeignKey(AugmentedLocation, models.CASCADE) -@python_2_unicode_compatible class Parcel(SimpleModel): name = models.CharField(max_length=30) city = models.ForeignKey(City, models.CASCADE) diff --git a/tests/inline_formsets/models.py b/tests/inline_formsets/models.py index 42cf810f5349..90d434e12374 100644 --- a/tests/inline_formsets/models.py +++ b/tests/inline_formsets/models.py @@ -1,5 +1,4 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible class School(models.Model): @@ -17,7 +16,6 @@ class Child(models.Model): name = models.CharField(max_length=100) -@python_2_unicode_compatible class Poet(models.Model): name = models.CharField(max_length=100) @@ -25,7 +23,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Poem(models.Model): poet = models.ForeignKey(Poet, models.CASCADE) name = models.CharField(max_length=100) diff --git a/tests/introspection/models.py b/tests/introspection/models.py index 023e622beb8a..2a1746531d7c 100644 --- a/tests/introspection/models.py +++ b/tests/introspection/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class City(models.Model): id = models.BigAutoField(primary_key=True) name = models.CharField(max_length=50) @@ -11,7 +9,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class District(models.Model): city = models.ForeignKey(City, models.CASCADE, primary_key=True) name = models.CharField(max_length=50) @@ -20,7 +17,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Reporter(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) @@ -36,7 +32,6 @@ def __str__(self): return "%s %s" % (self.first_name, self.last_name) -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100) pub_date = models.DateField() diff --git a/tests/lookup/models.py b/tests/lookup/models.py index 3490422f69a0..9cf053d87300 100644 --- a/tests/lookup/models.py +++ b/tests/lookup/models.py @@ -6,7 +6,6 @@ from django.db import models from django.utils import six -from django.utils.encoding import python_2_unicode_compatible class Alarm(models.Model): @@ -24,7 +23,6 @@ class Meta: ordering = ('name', ) -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100) pub_date = models.DateTimeField() @@ -45,7 +43,6 @@ class Meta: ordering = ('name', ) -@python_2_unicode_compatible class Season(models.Model): year = models.PositiveSmallIntegerField() gt = models.IntegerField(null=True, blank=True) @@ -54,7 +51,6 @@ def __str__(self): return six.text_type(self.year) -@python_2_unicode_compatible class Game(models.Model): season = models.ForeignKey(Season, models.CASCADE, related_name='games') home = models.CharField(max_length=100) @@ -64,7 +60,6 @@ def __str__(self): return "%s at %s" % (self.away, self.home) -@python_2_unicode_compatible class Player(models.Model): name = models.CharField(max_length=100) games = models.ManyToManyField(Game, related_name='players') diff --git a/tests/m2m_and_m2o/models.py b/tests/m2m_and_m2o/models.py index 621c56ca1aea..7174e6369a72 100644 --- a/tests/m2m_and_m2o/models.py +++ b/tests/m2m_and_m2o/models.py @@ -5,14 +5,12 @@ """ from django.db import models from django.utils import six -from django.utils.encoding import python_2_unicode_compatible class User(models.Model): username = models.CharField(max_length=20) -@python_2_unicode_compatible class Issue(models.Model): num = models.IntegerField() cc = models.ManyToManyField(User, blank=True, related_name='test_issue_cc') diff --git a/tests/m2m_intermediary/models.py b/tests/m2m_intermediary/models.py index dbd822df513a..3101fd8a2d59 100644 --- a/tests/m2m_intermediary/models.py +++ b/tests/m2m_intermediary/models.py @@ -10,10 +10,8 @@ (e.g. "Staff writer"). """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Reporter(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) @@ -22,7 +20,6 @@ def __str__(self): return "%s %s" % (self.first_name, self.last_name) -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100) pub_date = models.DateField() @@ -31,7 +28,6 @@ def __str__(self): return self.headline -@python_2_unicode_compatible class Writer(models.Model): reporter = models.ForeignKey(Reporter, models.CASCADE) article = models.ForeignKey(Article, models.CASCADE) diff --git a/tests/m2m_multiple/models.py b/tests/m2m_multiple/models.py index a6db9425bd40..7a77044c2cd2 100644 --- a/tests/m2m_multiple/models.py +++ b/tests/m2m_multiple/models.py @@ -8,10 +8,8 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Category(models.Model): name = models.CharField(max_length=20) @@ -22,7 +20,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=50) pub_date = models.DateTimeField() diff --git a/tests/m2m_recursive/models.py b/tests/m2m_recursive/models.py index d224b3d572b4..fd4f4ad1665e 100644 --- a/tests/m2m_recursive/models.py +++ b/tests/m2m_recursive/models.py @@ -17,10 +17,8 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Person(models.Model): name = models.CharField(max_length=20) friends = models.ManyToManyField('self') diff --git a/tests/m2m_regress/models.py b/tests/m2m_regress/models.py index 57f02b8f90b5..70966bd0b859 100644 --- a/tests/m2m_regress/models.py +++ b/tests/m2m_regress/models.py @@ -1,11 +1,9 @@ from django.contrib.auth import models as auth from django.db import models -from django.utils.encoding import python_2_unicode_compatible # No related name is needed here, since symmetrical relations are not # explicitly reversible. -@python_2_unicode_compatible class SelfRefer(models.Model): name = models.CharField(max_length=10) references = models.ManyToManyField('self') @@ -15,7 +13,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Tag(models.Model): name = models.CharField(max_length=10) @@ -24,7 +21,6 @@ def __str__(self): # Regression for #11956 -- a many to many to the base class -@python_2_unicode_compatible class TagCollection(Tag): tags = models.ManyToManyField(Tag, related_name='tag_collections') @@ -34,7 +30,6 @@ def __str__(self): # A related_name is required on one of the ManyToManyField entries here because # they are both addressable as reverse relations from Tag. -@python_2_unicode_compatible class Entry(models.Model): name = models.CharField(max_length=10) topics = models.ManyToManyField(Tag) @@ -54,7 +49,6 @@ class SelfReferChildSibling(SelfRefer): # Many-to-Many relation between models, where one of the PK's isn't an Autofield -@python_2_unicode_compatible class Line(models.Model): name = models.CharField(max_length=100) diff --git a/tests/m2m_signals/models.py b/tests/m2m_signals/models.py index e4110ccf34ef..c156128c839c 100644 --- a/tests/m2m_signals/models.py +++ b/tests/m2m_signals/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Part(models.Model): name = models.CharField(max_length=20) @@ -13,7 +11,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Car(models.Model): name = models.CharField(max_length=20) default_parts = models.ManyToManyField(Part) @@ -30,7 +27,6 @@ class SportsCar(Car): price = models.IntegerField() -@python_2_unicode_compatible class Person(models.Model): name = models.CharField(max_length=20) fans = models.ManyToManyField('self', related_name='idols', symmetrical=False) diff --git a/tests/m2m_through/models.py b/tests/m2m_through/models.py index dab3be51645e..5f9fba27a7de 100644 --- a/tests/m2m_through/models.py +++ b/tests/m2m_through/models.py @@ -1,11 +1,9 @@ from datetime import datetime from django.db import models -from django.utils.encoding import python_2_unicode_compatible # M2M described on one of the models -@python_2_unicode_compatible class Person(models.Model): name = models.CharField(max_length=128) @@ -16,7 +14,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField(Person, through='Membership') @@ -34,7 +31,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Membership(models.Model): person = models.ForeignKey(Person, models.CASCADE) group = models.ForeignKey(Group, models.CASCADE) @@ -48,7 +44,6 @@ def __str__(self): return "%s is a member of %s" % (self.person.name, self.group.name) -@python_2_unicode_compatible class CustomMembership(models.Model): person = models.ForeignKey( Person, @@ -74,7 +69,6 @@ class TestNoDefaultsOrNulls(models.Model): nodefaultnonull = models.CharField(max_length=5) -@python_2_unicode_compatible class PersonSelfRefM2M(models.Model): name = models.CharField(max_length=5) friends = models.ManyToManyField('self', through="Friendship", symmetrical=False) @@ -90,7 +84,6 @@ class Friendship(models.Model): # Custom through link fields -@python_2_unicode_compatible class Event(models.Model): title = models.CharField(max_length=50) invitees = models.ManyToManyField( @@ -110,7 +103,6 @@ class Invitation(models.Model): invitee = models.ForeignKey(Person, models.CASCADE, related_name='invitations') -@python_2_unicode_compatible class Employee(models.Model): name = models.CharField(max_length=5) subordinates = models.ManyToManyField( diff --git a/tests/m2m_through_regress/models.py b/tests/m2m_through_regress/models.py index 9f0f44cd2132..1214c93ea13a 100644 --- a/tests/m2m_through_regress/models.py +++ b/tests/m2m_through_regress/models.py @@ -1,10 +1,8 @@ from django.contrib.auth.models import User from django.db import models -from django.utils.encoding import python_2_unicode_compatible # Forward declared intermediate model -@python_2_unicode_compatible class Membership(models.Model): person = models.ForeignKey('Person', models.CASCADE) group = models.ForeignKey('Group', models.CASCADE) @@ -15,7 +13,6 @@ def __str__(self): # using custom id column to test ticket #11107 -@python_2_unicode_compatible class UserMembership(models.Model): id = models.AutoField(db_column='usermembership_id', primary_key=True) user = models.ForeignKey(User, models.CASCADE) @@ -26,7 +23,6 @@ def __str__(self): return "%s is a user and member of %s" % (self.user.username, self.group.name) -@python_2_unicode_compatible class Person(models.Model): name = models.CharField(max_length=128) @@ -34,7 +30,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Group(models.Model): name = models.CharField(max_length=128) # Membership object defined as a class @@ -65,7 +60,6 @@ class B(models.Model): # Using to_field on the through model -@python_2_unicode_compatible class Car(models.Model): make = models.CharField(max_length=20, unique=True, null=True) drivers = models.ManyToManyField('Driver', through='CarDriver') @@ -74,7 +68,6 @@ def __str__(self): return "%s" % self.make -@python_2_unicode_compatible class Driver(models.Model): name = models.CharField(max_length=20, unique=True, null=True) @@ -85,7 +78,6 @@ class Meta: ordering = ('name',) -@python_2_unicode_compatible class CarDriver(models.Model): car = models.ForeignKey('Car', models.CASCADE, to_field='make') driver = models.ForeignKey('Driver', models.CASCADE, to_field='name') diff --git a/tests/m2o_recursive/models.py b/tests/m2o_recursive/models.py index d62c514a255d..bb7358980072 100644 --- a/tests/m2o_recursive/models.py +++ b/tests/m2o_recursive/models.py @@ -11,10 +11,8 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Category(models.Model): name = models.CharField(max_length=20) parent = models.ForeignKey('self', models.SET_NULL, blank=True, null=True, related_name='child_set') @@ -23,7 +21,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Person(models.Model): full_name = models.CharField(max_length=20) mother = models.ForeignKey('self', models.SET_NULL, null=True, related_name='mothers_child_set') diff --git a/tests/managers_regress/models.py b/tests/managers_regress/models.py index b39e69b9adda..f5fd648bff3e 100644 --- a/tests/managers_regress/models.py +++ b/tests/managers_regress/models.py @@ -7,7 +7,7 @@ ) from django.contrib.contenttypes.models import ContentType from django.db import models -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import force_text class OnlyFred(models.Manager): @@ -55,7 +55,6 @@ class Meta: abstract = True -@python_2_unicode_compatible class Parent(models.Model): name = models.CharField(max_length=50) @@ -68,7 +67,6 @@ def __str__(self): # Managers from base classes are inherited and, if no manager is specified # *and* the parent has a manager specified, the first one (in the MRO) will # become the default. -@python_2_unicode_compatible class Child1(AbstractBase1): data = models.CharField(max_length=25) @@ -76,7 +74,6 @@ def __str__(self): return self.data -@python_2_unicode_compatible class Child2(AbstractBase1, AbstractBase2): data = models.CharField(max_length=25) @@ -84,7 +81,6 @@ def __str__(self): return self.data -@python_2_unicode_compatible class Child3(AbstractBase1, AbstractBase3): data = models.CharField(max_length=25) @@ -92,7 +88,6 @@ def __str__(self): return self.data -@python_2_unicode_compatible class Child4(AbstractBase1): data = models.CharField(max_length=25) @@ -104,7 +99,6 @@ def __str__(self): return self.data -@python_2_unicode_compatible class Child5(AbstractBase3): name = models.CharField(max_length=25) @@ -124,7 +118,6 @@ class Child7(Parent): # RelatedManagers -@python_2_unicode_compatible class RelatedModel(models.Model): test_gfk = GenericRelation('RelationModel', content_type_field='gfk_ctype', object_id_field='gfk_id') exact = models.NullBooleanField() @@ -133,7 +126,6 @@ def __str__(self): return force_text(self.pk) -@python_2_unicode_compatible class RelationModel(models.Model): fk = models.ForeignKey(RelatedModel, models.CASCADE, related_name='test_fk') diff --git a/tests/many_to_many/models.py b/tests/many_to_many/models.py index b0e708ebb45e..cf3add7848d6 100644 --- a/tests/many_to_many/models.py +++ b/tests/many_to_many/models.py @@ -7,10 +7,8 @@ objects, and a ``Publication`` has multiple ``Article`` objects. """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Publication(models.Model): title = models.CharField(max_length=30) @@ -21,7 +19,6 @@ class Meta: ordering = ('title',) -@python_2_unicode_compatible class Tag(models.Model): id = models.BigAutoField(primary_key=True) name = models.CharField(max_length=50) @@ -30,7 +27,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100) # Assign a unicode string as name to make sure the intermediary model is diff --git a/tests/many_to_one/models.py b/tests/many_to_one/models.py index 09578b56a31f..93b8029b2f12 100644 --- a/tests/many_to_one/models.py +++ b/tests/many_to_one/models.py @@ -4,10 +4,8 @@ To define a many-to-one relationship, use ``ForeignKey()``. """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Reporter(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) @@ -17,7 +15,6 @@ def __str__(self): return "%s %s" % (self.first_name, self.last_name) -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100) pub_date = models.DateField() @@ -30,7 +27,6 @@ class Meta: ordering = ('headline',) -@python_2_unicode_compatible class City(models.Model): id = models.BigAutoField(primary_key=True) name = models.CharField(max_length=50) @@ -39,7 +35,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class District(models.Model): city = models.ForeignKey(City, models.CASCADE, related_name='districts', null=True) name = models.CharField(max_length=50) @@ -80,7 +75,6 @@ class ToFieldChild(models.Model): # Multiple paths to the same model (#7110, #7125) -@python_2_unicode_compatible class Category(models.Model): name = models.CharField(max_length=20) @@ -92,7 +86,6 @@ class Record(models.Model): category = models.ForeignKey(Category, models.CASCADE) -@python_2_unicode_compatible class Relation(models.Model): left = models.ForeignKey(Record, models.CASCADE, related_name='left_set') right = models.ForeignKey(Record, models.CASCADE, related_name='right_set') diff --git a/tests/many_to_one_null/models.py b/tests/many_to_one_null/models.py index 2a67623dc3ae..23b429459380 100644 --- a/tests/many_to_one_null/models.py +++ b/tests/many_to_one_null/models.py @@ -6,10 +6,8 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Reporter(models.Model): name = models.CharField(max_length=30) @@ -17,7 +15,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100) reporter = models.ForeignKey(Reporter, models.SET_NULL, null=True) diff --git a/tests/migrations/models.py b/tests/migrations/models.py index b1a10210b6d8..dea320c03312 100644 --- a/tests/migrations/models.py +++ b/tests/migrations/models.py @@ -1,7 +1,6 @@ from django.apps.registry import Apps from django.db import models from django.utils import six -from django.utils.encoding import python_2_unicode_compatible class CustomModelBase(models.base.ModelBase): @@ -12,7 +11,6 @@ class ModelWithCustomBase(six.with_metaclass(CustomModelBase, models.Model)): pass -@python_2_unicode_compatible class UnicodeModel(models.Model): title = models.CharField('ÚÑÍ¢ÓÐÉ', max_length=20, default='“Ðjáñgó”') diff --git a/tests/model_forms/models.py b/tests/model_forms/models.py index da91fc88b7b6..333a6050ab9f 100644 --- a/tests/model_forms/models.py +++ b/tests/model_forms/models.py @@ -17,7 +17,6 @@ from django.db import models from django.utils import six from django.utils._os import upath -from django.utils.encoding import python_2_unicode_compatible from django.utils.six.moves import range temp_storage_dir = tempfile.mkdtemp() @@ -40,7 +39,6 @@ class Person(models.Model): name = models.CharField(max_length=100) -@python_2_unicode_compatible class Category(models.Model): name = models.CharField(max_length=20) slug = models.SlugField(max_length=20) @@ -53,7 +51,6 @@ def __repr__(self): return self.__str__() -@python_2_unicode_compatible class Writer(models.Model): name = models.CharField(max_length=50, help_text='Use both first and last names.') @@ -64,7 +61,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=50) slug = models.SlugField() @@ -96,7 +92,6 @@ class BetterWriter(Writer): score = models.IntegerField() -@python_2_unicode_compatible class Publication(models.Model): title = models.CharField(max_length=30) date_published = models.DateField() @@ -135,7 +130,6 @@ class Author1(models.Model): full_name = models.CharField(max_length=255) -@python_2_unicode_compatible class WriterProfile(models.Model): writer = models.OneToOneField(Writer, models.CASCADE, primary_key=True) age = models.PositiveIntegerField() @@ -148,7 +142,6 @@ class Document(models.Model): myfile = models.FileField(upload_to='unused', blank=True) -@python_2_unicode_compatible class TextFile(models.Model): description = models.CharField(max_length=20) file = models.FileField(storage=temp_storage, upload_to='tests', max_length=15) @@ -177,7 +170,6 @@ class FilePathModel(models.Model): test_images = True - @python_2_unicode_compatible class ImageFile(models.Model): def custom_upload_path(self, filename): path = self.path or 'tests' @@ -196,7 +188,6 @@ def custom_upload_path(self, filename): def __str__(self): return self.description - @python_2_unicode_compatible class OptionalImageFile(models.Model): def custom_upload_path(self, filename): path = self.path or 'tests' @@ -220,7 +211,6 @@ class Homepage(models.Model): url = models.URLField() -@python_2_unicode_compatible class Product(models.Model): slug = models.SlugField(unique=True) @@ -228,7 +218,6 @@ def __str__(self): return self.slug -@python_2_unicode_compatible class Price(models.Model): price = models.DecimalField(max_digits=10, decimal_places=2) quantity = models.PositiveIntegerField() @@ -253,7 +242,6 @@ class ArticleStatus(models.Model): status = models.CharField(max_length=2, choices=ARTICLE_STATUS_CHAR, blank=True, null=True) -@python_2_unicode_compatible class Inventory(models.Model): barcode = models.PositiveIntegerField(unique=True) parent = models.ForeignKey('self', models.SET_NULL, to_field='barcode', blank=True, null=True) @@ -292,7 +280,6 @@ class DerivedBook(Book, BookXtra): pass -@python_2_unicode_compatible class ExplicitPK(models.Model): key = models.CharField(max_length=20, primary_key=True) desc = models.CharField(max_length=20, blank=True, unique=True) @@ -304,7 +291,6 @@ def __str__(self): return self.key -@python_2_unicode_compatible class Post(models.Model): title = models.CharField(max_length=50, unique_for_date='posted', blank=True) slug = models.CharField(max_length=50, unique_for_year='posted', blank=True) @@ -315,7 +301,6 @@ def __str__(self): return self.title -@python_2_unicode_compatible class DateTimePost(models.Model): title = models.CharField(max_length=50, unique_for_date='posted', blank=True) slug = models.CharField(max_length=50, unique_for_year='posted', blank=True) @@ -330,7 +315,6 @@ class DerivedPost(Post): pass -@python_2_unicode_compatible class BigInt(models.Model): biggie = models.BigIntegerField() @@ -363,7 +347,6 @@ class FlexibleDatePost(models.Model): posted = models.DateField(blank=True, null=True) -@python_2_unicode_compatible class Colour(models.Model): name = models.CharField(max_length=50) diff --git a/tests/model_formsets/models.py b/tests/model_formsets/models.py index 421d873704f2..b7b1f1edb917 100644 --- a/tests/model_formsets/models.py +++ b/tests/model_formsets/models.py @@ -3,10 +3,8 @@ from django.db import models from django.utils import six -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=100) @@ -21,7 +19,6 @@ class BetterAuthor(Author): write_speed = models.IntegerField() -@python_2_unicode_compatible class Book(models.Model): author = models.ForeignKey(Author, models.CASCADE) title = models.CharField(max_length=100) @@ -40,7 +37,6 @@ def clean(self): assert self.author.name is not None -@python_2_unicode_compatible class BookWithCustomPK(models.Model): my_pk = models.DecimalField(max_digits=5, decimal_places=0, primary_key=True) author = models.ForeignKey(Author, models.CASCADE) @@ -54,7 +50,6 @@ class Editor(models.Model): name = models.CharField(max_length=100) -@python_2_unicode_compatible class BookWithOptionalAltEditor(models.Model): author = models.ForeignKey(Author, models.CASCADE) # Optional secondary author @@ -70,7 +65,6 @@ def __str__(self): return self.title -@python_2_unicode_compatible class AlternateBook(Book): notes = models.CharField(max_length=100) @@ -78,7 +72,6 @@ def __str__(self): return '%s - %s' % (self.title, self.notes) -@python_2_unicode_compatible class AuthorMeeting(models.Model): name = models.CharField(max_length=100) authors = models.ManyToManyField(Author) @@ -96,7 +89,6 @@ class CustomPrimaryKey(models.Model): # models for inheritance tests. -@python_2_unicode_compatible class Place(models.Model): name = models.CharField(max_length=50) city = models.CharField(max_length=50) @@ -105,7 +97,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Owner(models.Model): auto_id = models.AutoField(primary_key=True) name = models.CharField(max_length=100) @@ -122,7 +113,6 @@ class Location(models.Model): lon = models.CharField(max_length=100) -@python_2_unicode_compatible class OwnerProfile(models.Model): owner = models.OneToOneField(Owner, models.CASCADE, primary_key=True) age = models.PositiveIntegerField() @@ -131,7 +121,6 @@ def __str__(self): return "%s is %d" % (self.owner.name, self.age) -@python_2_unicode_compatible class Restaurant(Place): serves_pizza = models.BooleanField(default=False) @@ -139,7 +128,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Product(models.Model): slug = models.SlugField(unique=True) @@ -147,7 +135,6 @@ def __str__(self): return self.slug -@python_2_unicode_compatible class Price(models.Model): price = models.DecimalField(max_digits=10, decimal_places=2) quantity = models.PositiveIntegerField() @@ -170,7 +157,6 @@ class ClassyMexicanRestaurant(MexicanRestaurant): # models for testing unique_together validation when a fk is involved and # using inlineformset_factory. -@python_2_unicode_compatible class Repository(models.Model): name = models.CharField(max_length=25) @@ -178,7 +164,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Revision(models.Model): repository = models.ForeignKey(Repository, models.CASCADE) revision = models.CharField(max_length=40) @@ -208,7 +193,6 @@ class Team(models.Model): name = models.CharField(max_length=100) -@python_2_unicode_compatible class Player(models.Model): team = models.ForeignKey(Team, models.SET_NULL, null=True) name = models.CharField(max_length=100) @@ -218,7 +202,6 @@ def __str__(self): # Models for testing custom ModelForm save methods in formsets and inline formsets -@python_2_unicode_compatible class Poet(models.Model): name = models.CharField(max_length=100) @@ -226,7 +209,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Poem(models.Model): poet = models.ForeignKey(Poet, models.CASCADE) name = models.CharField(max_length=100) @@ -235,7 +217,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Post(models.Model): title = models.CharField(max_length=50, unique_for_date='posted', blank=True) slug = models.CharField(max_length=50, unique_for_year='posted', blank=True) diff --git a/tests/model_formsets_regress/models.py b/tests/model_formsets_regress/models.py index 064cddd4a079..29d1194bc221 100644 --- a/tests/model_formsets_regress/models.py +++ b/tests/model_formsets_regress/models.py @@ -1,5 +1,4 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible class User(models.Model): @@ -40,7 +39,6 @@ class Network(models.Model): name = models.CharField(max_length=15) -@python_2_unicode_compatible class Host(models.Model): network = models.ForeignKey(Network, models.CASCADE) hostname = models.CharField(max_length=25) diff --git a/tests/model_inheritance/models.py b/tests/model_inheritance/models.py index 4c7d4a7c8a28..44bf752d0025 100644 --- a/tests/model_inheritance/models.py +++ b/tests/model_inheritance/models.py @@ -12,7 +12,6 @@ Both styles are demonstrated here. """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible # @@ -20,7 +19,6 @@ # -@python_2_unicode_compatible class CommonInfo(models.Model): name = models.CharField(max_length=50) age = models.PositiveIntegerField() @@ -52,7 +50,6 @@ class Post(models.Model): title = models.CharField(max_length=50) -@python_2_unicode_compatible class Attachment(models.Model): post = models.ForeignKey( Post, @@ -81,7 +78,6 @@ class Link(Attachment): # Multi-table inheritance # -@python_2_unicode_compatible class Chef(models.Model): name = models.CharField(max_length=50) @@ -89,7 +85,6 @@ def __str__(self): return "%s the chef" % self.name -@python_2_unicode_compatible class Place(models.Model): name = models.CharField(max_length=50) address = models.CharField(max_length=80) @@ -106,7 +101,6 @@ class Meta: ordering = ['-rating'] -@python_2_unicode_compatible class Restaurant(Place, Rating): serves_hot_dogs = models.BooleanField(default=False) serves_pizza = models.BooleanField(default=False) @@ -119,7 +113,6 @@ def __str__(self): return "%s the restaurant" % self.name -@python_2_unicode_compatible class ItalianRestaurant(Restaurant): serves_gnocchi = models.BooleanField(default=False) @@ -127,7 +120,6 @@ def __str__(self): return "%s the italian restaurant" % self.name -@python_2_unicode_compatible class Supplier(Place): customers = models.ManyToManyField(Restaurant, related_name='provider') @@ -135,7 +127,6 @@ def __str__(self): return "%s the supplier" % self.name -@python_2_unicode_compatible class ParkingLot(Place): # An explicit link to the parent (we can control the attribute name). parent = models.OneToOneField(Place, models.CASCADE, primary_key=True, parent_link=True) diff --git a/tests/model_inheritance_regress/models.py b/tests/model_inheritance_regress/models.py index 69ce0d9e2b75..358217554beb 100644 --- a/tests/model_inheritance_regress/models.py +++ b/tests/model_inheritance_regress/models.py @@ -1,10 +1,8 @@ import datetime from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Place(models.Model): name = models.CharField(max_length=50) address = models.CharField(max_length=80) @@ -16,7 +14,6 @@ def __str__(self): return "%s the place" % self.name -@python_2_unicode_compatible class Restaurant(Place): serves_hot_dogs = models.BooleanField(default=False) serves_pizza = models.BooleanField(default=False) @@ -25,7 +22,6 @@ def __str__(self): return "%s the restaurant" % self.name -@python_2_unicode_compatible class ItalianRestaurant(Restaurant): serves_gnocchi = models.BooleanField(default=False) @@ -33,7 +29,6 @@ def __str__(self): return "%s the italian restaurant" % self.name -@python_2_unicode_compatible class ParkingLot(Place): # An explicit link to the parent (we can control the attribute name). parent = models.OneToOneField(Place, models.CASCADE, primary_key=True, parent_link=True) @@ -65,7 +60,6 @@ class ParkingLot4B(Place, ParkingLot4): pass -@python_2_unicode_compatible class Supplier(models.Model): name = models.CharField(max_length=50) restaurant = models.ForeignKey(Restaurant, models.CASCADE) @@ -95,7 +89,6 @@ class SelfRefChild(SelfRefParent): child_data = models.IntegerField() -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100) pub_date = models.DateTimeField() @@ -130,7 +123,6 @@ class QualityControl(Evaluation): assignee = models.CharField(max_length=50) -@python_2_unicode_compatible class BaseM(models.Model): base_name = models.CharField(max_length=100) @@ -138,7 +130,6 @@ def __str__(self): return self.base_name -@python_2_unicode_compatible class DerivedM(BaseM): customPK = models.IntegerField(primary_key=True) derived_name = models.CharField(max_length=100) @@ -166,7 +157,6 @@ class InternalCertificationAudit(CertificationAudit): # Abstract classes don't get m2m tables autocreated. -@python_2_unicode_compatible class Person(models.Model): name = models.CharField(max_length=100) @@ -177,7 +167,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class AbstractEvent(models.Model): name = models.CharField(max_length=100) attendees = models.ManyToManyField(Person, related_name="%(class)s_set") diff --git a/tests/model_regress/models.py b/tests/model_regress/models.py index 147116d7e292..3208db90b878 100644 --- a/tests/model_regress/models.py +++ b/tests/model_regress/models.py @@ -1,5 +1,4 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible CHOICES = ( (1, 'first'), @@ -7,7 +6,6 @@ ) -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100, default='Default headline') pub_date = models.DateTimeField() @@ -38,7 +36,6 @@ class Event(models.Model): when = models.DateTimeField() -@python_2_unicode_compatible class Department(models.Model): id = models.PositiveIntegerField(primary_key=True) name = models.CharField(max_length=200) @@ -47,7 +44,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Worker(models.Model): department = models.ForeignKey(Department, models.CASCADE) name = models.CharField(max_length=200) @@ -56,7 +52,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class BrokenUnicodeMethod(models.Model): name = models.CharField(max_length=7) diff --git a/tests/modeladmin/models.py b/tests/modeladmin/models.py index 64cc86aa6658..861a2dbb9df7 100644 --- a/tests/modeladmin/models.py +++ b/tests/modeladmin/models.py @@ -1,9 +1,7 @@ from django.contrib.auth.models import User from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Band(models.Model): name = models.CharField(max_length=100) bio = models.TextField() diff --git a/tests/multiple_database/models.py b/tests/multiple_database/models.py index 367cd31d6395..55247f6e1878 100644 --- a/tests/multiple_database/models.py +++ b/tests/multiple_database/models.py @@ -4,10 +4,8 @@ ) from django.contrib.contenttypes.models import ContentType from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Review(models.Model): source = models.CharField(max_length=100) content_type = models.ForeignKey(ContentType, models.CASCADE) @@ -26,7 +24,6 @@ def get_by_natural_key(self, name): return self.get(name=name) -@python_2_unicode_compatible class Person(models.Model): objects = PersonManager() name = models.CharField(max_length=100) @@ -52,7 +49,6 @@ def get_or_create(self, *args, **kwargs): return super(BookManager, self).get_or_create(*args, **kwargs) -@python_2_unicode_compatible class Book(models.Model): objects = BookManager() title = models.CharField(max_length=100) @@ -69,7 +65,6 @@ class Meta: ordering = ('title',) -@python_2_unicode_compatible class Pet(models.Model): name = models.CharField(max_length=100) owner = models.ForeignKey(Person, models.CASCADE) diff --git a/tests/null_fk/models.py b/tests/null_fk/models.py index 6a7da8f620f4..5ebce93a6544 100644 --- a/tests/null_fk/models.py +++ b/tests/null_fk/models.py @@ -3,7 +3,6 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible class SystemDetails(models.Model): @@ -20,7 +19,6 @@ class Forum(models.Model): forum_name = models.CharField(max_length=32) -@python_2_unicode_compatible class Post(models.Model): forum = models.ForeignKey(Forum, models.SET_NULL, null=True) title = models.CharField(max_length=32) @@ -29,7 +27,6 @@ def __str__(self): return self.title -@python_2_unicode_compatible class Comment(models.Model): post = models.ForeignKey(Post, models.SET_NULL, null=True) comment_text = models.CharField(max_length=250) diff --git a/tests/null_fk_ordering/models.py b/tests/null_fk_ordering/models.py index e65c227f88c5..a7938cec5496 100644 --- a/tests/null_fk_ordering/models.py +++ b/tests/null_fk_ordering/models.py @@ -6,7 +6,6 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible # The first two models represent a very simple null FK ordering case. @@ -14,7 +13,6 @@ class Author(models.Model): name = models.CharField(max_length=150) -@python_2_unicode_compatible class Article(models.Model): title = models.CharField(max_length=150) author = models.ForeignKey(Author, models.SET_NULL, null=True) @@ -36,7 +34,6 @@ class Forum(models.Model): forum_name = models.CharField(max_length=32) -@python_2_unicode_compatible class Post(models.Model): forum = models.ForeignKey(Forum, models.SET_NULL, null=True) title = models.CharField(max_length=32) @@ -45,7 +42,6 @@ def __str__(self): return self.title -@python_2_unicode_compatible class Comment(models.Model): post = models.ForeignKey(Post, models.SET_NULL, null=True) comment_text = models.CharField(max_length=250) diff --git a/tests/null_queries/models.py b/tests/null_queries/models.py index b40f4539b37a..f2d4caa745ca 100644 --- a/tests/null_queries/models.py +++ b/tests/null_queries/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Poll(models.Model): question = models.CharField(max_length=200) @@ -10,7 +8,6 @@ def __str__(self): return "Q: %s " % self.question -@python_2_unicode_compatible class Choice(models.Model): poll = models.ForeignKey(Poll, models.CASCADE) choice = models.CharField(max_length=200) diff --git a/tests/one_to_one/models.py b/tests/one_to_one/models.py index c58114dce8d5..263633347d12 100644 --- a/tests/one_to_one/models.py +++ b/tests/one_to_one/models.py @@ -6,10 +6,8 @@ In this example, a ``Place`` optionally can be a ``Restaurant``. """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Place(models.Model): name = models.CharField(max_length=50) address = models.CharField(max_length=80) @@ -18,7 +16,6 @@ def __str__(self): return "%s the place" % self.name -@python_2_unicode_compatible class Restaurant(models.Model): place = models.OneToOneField(Place, models.CASCADE, primary_key=True) serves_hot_dogs = models.BooleanField(default=False) @@ -28,7 +25,6 @@ def __str__(self): return "%s the restaurant" % self.place.name -@python_2_unicode_compatible class Bar(models.Model): place = models.OneToOneField(Place, models.CASCADE) serves_cocktails = models.BooleanField(default=True) @@ -42,7 +38,6 @@ class UndergroundBar(models.Model): serves_cocktails = models.BooleanField(default=True) -@python_2_unicode_compatible class Waiter(models.Model): restaurant = models.ForeignKey(Restaurant, models.CASCADE) name = models.CharField(max_length=50) @@ -51,7 +46,6 @@ def __str__(self): return "%s the waiter at %s" % (self.name, self.restaurant) -@python_2_unicode_compatible class Favorites(models.Model): name = models.CharField(max_length=50) restaurants = models.ManyToManyField(Restaurant) @@ -70,7 +64,6 @@ class RelatedModel(models.Model): name = models.CharField(max_length=50) -@python_2_unicode_compatible class MultiModel(models.Model): link1 = models.OneToOneField(Place, models.CASCADE) link2 = models.OneToOneField(ManualPrimaryKey, models.CASCADE) diff --git a/tests/or_lookups/models.py b/tests/or_lookups/models.py index 7dea8cd49e3b..efe70ab8ddea 100644 --- a/tests/or_lookups/models.py +++ b/tests/or_lookups/models.py @@ -10,10 +10,8 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=50) pub_date = models.DateTimeField() diff --git a/tests/order_with_respect_to/models.py b/tests/order_with_respect_to/models.py index 17c09dfeaef8..8f50b42252ed 100644 --- a/tests/order_with_respect_to/models.py +++ b/tests/order_with_respect_to/models.py @@ -4,14 +4,12 @@ from django.db import models from django.utils import six -from django.utils.encoding import python_2_unicode_compatible class Question(models.Model): text = models.CharField(max_length=200) -@python_2_unicode_compatible class Answer(models.Model): text = models.CharField(max_length=200) question = models.ForeignKey(Question, models.CASCADE) @@ -23,7 +21,6 @@ def __str__(self): return six.text_type(self.text) -@python_2_unicode_compatible class Post(models.Model): title = models.CharField(max_length=200) parent = models.ForeignKey("self", models.SET_NULL, related_name="children", null=True) diff --git a/tests/ordering/models.py b/tests/ordering/models.py index 1f794ca3a1fb..d3024f5fc051 100644 --- a/tests/ordering/models.py +++ b/tests/ordering/models.py @@ -14,7 +14,6 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible class Author(models.Model): @@ -24,7 +23,6 @@ class Meta: ordering = ('-pk',) -@python_2_unicode_compatible class Article(models.Model): author = models.ForeignKey(Author, models.SET_NULL, null=True) second_author = models.ForeignKey(Author, models.SET_NULL, null=True, related_name='+') diff --git a/tests/pagination/models.py b/tests/pagination/models.py index 9dc8d4b776b4..d84dd42ee665 100644 --- a/tests/pagination/models.py +++ b/tests/pagination/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100, default='Default headline') pub_date = models.DateTimeField() diff --git a/tests/prefetch_related/models.py b/tests/prefetch_related/models.py index 064ce1dfbdac..c995acb684f7 100644 --- a/tests/prefetch_related/models.py +++ b/tests/prefetch_related/models.py @@ -5,13 +5,11 @@ ) from django.contrib.contenttypes.models import ContentType from django.db import models -from django.utils.encoding import python_2_unicode_compatible from django.utils.functional import cached_property # Basic tests -@python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=50, unique=True) first_book = models.ForeignKey('Book', models.CASCADE, related_name='first_time_authors') @@ -38,7 +36,6 @@ class Meta: ordering = ['id'] -@python_2_unicode_compatible class AuthorAddress(models.Model): author = models.ForeignKey(Author, models.CASCADE, to_field='name', related_name='addresses') address = models.TextField() @@ -50,7 +47,6 @@ def __str__(self): return self.address -@python_2_unicode_compatible class Book(models.Model): title = models.CharField(max_length=255) authors = models.ManyToManyField(Author, related_name='books') @@ -74,7 +70,6 @@ class Bio(models.Model): books = models.ManyToManyField(Book, blank=True) -@python_2_unicode_compatible class Reader(models.Model): name = models.CharField(max_length=50) books_read = models.ManyToManyField(Book, related_name='read_by') @@ -105,7 +100,6 @@ def get_queryset(self): return super(TeacherManager, self).get_queryset().prefetch_related('qualifications') -@python_2_unicode_compatible class Teacher(models.Model): name = models.CharField(max_length=50) qualifications = models.ManyToManyField(Qualification) @@ -129,7 +123,6 @@ class Meta: # GenericRelation/GenericForeignKey tests -@python_2_unicode_compatible class TaggedItem(models.Model): tag = models.SlugField() content_type = models.ForeignKey( @@ -230,7 +223,6 @@ class Meta: # Models for nullable FK tests -@python_2_unicode_compatible class Employee(models.Model): name = models.CharField(max_length=50) boss = models.ForeignKey('self', models.SET_NULL, null=True, related_name='serfs') @@ -244,7 +236,6 @@ class Meta: # Ticket #19607 -@python_2_unicode_compatible class LessonEntry(models.Model): name1 = models.CharField(max_length=200) name2 = models.CharField(max_length=200) @@ -253,7 +244,6 @@ def __str__(self): return "%s %s" % (self.name1, self.name2) -@python_2_unicode_compatible class WordEntry(models.Model): lesson_entry = models.ForeignKey(LessonEntry, models.CASCADE) name = models.CharField(max_length=200) @@ -264,7 +254,6 @@ def __str__(self): # Ticket #21410: Regression when related_name="+" -@python_2_unicode_compatible class Author2(models.Model): name = models.CharField(max_length=50, unique=True) first_book = models.ForeignKey('Book', models.CASCADE, related_name='first_time_authors+') diff --git a/tests/proxy_models/models.py b/tests/proxy_models/models.py index 6960042d78df..93430d615f42 100644 --- a/tests/proxy_models/models.py +++ b/tests/proxy_models/models.py @@ -5,7 +5,6 @@ providing a modified interface to the data from the base class. """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible # A couple of managers for testing managing overriding in proxy model cases. @@ -21,7 +20,6 @@ def get_queryset(self): return super(SubManager, self).get_queryset().exclude(name="wilma") -@python_2_unicode_compatible class Person(models.Model): """ A simple concrete base class. @@ -101,7 +99,6 @@ class LowerStatusPerson(MyPersonProxy): objects = models.Manager() -@python_2_unicode_compatible class User(models.Model): name = models.CharField(max_length=100) @@ -135,7 +132,6 @@ class Country(models.Model): name = models.CharField(max_length=50) -@python_2_unicode_compatible class State(models.Model): name = models.CharField(max_length=50) country = models.ForeignKey(Country, models.CASCADE) @@ -152,7 +148,6 @@ class Meta: # and select_related, even when mixed with model inheritance -@python_2_unicode_compatible class BaseUser(models.Model): name = models.CharField(max_length=255) @@ -169,7 +164,6 @@ class Meta: proxy = True -@python_2_unicode_compatible class Issue(models.Model): summary = models.CharField(max_length=255) assignee = models.ForeignKey(ProxyTrackerUser, models.CASCADE, related_name='issues') diff --git a/tests/queries/models.py b/tests/queries/models.py index 8c1ba59b67cb..4d5ed14ff0e1 100644 --- a/tests/queries/models.py +++ b/tests/queries/models.py @@ -5,7 +5,6 @@ from django.db import models from django.utils import six -from django.utils.encoding import python_2_unicode_compatible class DumbCategory(models.Model): @@ -17,7 +16,6 @@ class Meta: proxy = True -@python_2_unicode_compatible class NamedCategory(DumbCategory): name = models.CharField(max_length=10) @@ -25,7 +23,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Tag(models.Model): name = models.CharField(max_length=10) parent = models.ForeignKey( @@ -43,7 +40,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Note(models.Model): note = models.CharField(max_length=100) misc = models.CharField(max_length=10) @@ -63,7 +59,6 @@ def __init__(self, *args, **kwargs): self.lock = threading.Lock() -@python_2_unicode_compatible class Annotation(models.Model): name = models.CharField(max_length=10) tag = models.ForeignKey(Tag, models.CASCADE) @@ -73,7 +68,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class ExtraInfo(models.Model): info = models.CharField(max_length=100) note = models.ForeignKey(Note, models.CASCADE) @@ -86,7 +80,6 @@ def __str__(self): return self.info -@python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=10) num = models.IntegerField(unique=True) @@ -99,7 +92,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Item(models.Model): name = models.CharField(max_length=10) created = models.DateTimeField() @@ -115,7 +107,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Report(models.Model): name = models.CharField(max_length=10) creator = models.ForeignKey(Author, models.SET_NULL, to_field='num', null=True) @@ -124,7 +115,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Ranking(models.Model): rank = models.IntegerField() author = models.ForeignKey(Author, models.CASCADE) @@ -137,7 +127,6 @@ def __str__(self): return '%d: %s' % (self.rank, self.author.name) -@python_2_unicode_compatible class Cover(models.Model): title = models.CharField(max_length=50) item = models.ForeignKey(Item, models.CASCADE) @@ -149,7 +138,6 @@ def __str__(self): return self.title -@python_2_unicode_compatible class Number(models.Model): num = models.IntegerField() @@ -212,7 +200,6 @@ def get_queryset(self): return qs.filter(public=True, tag__name='t1') -@python_2_unicode_compatible class ManagedModel(models.Model): data = models.CharField(max_length=10) tag = models.ForeignKey(Tag, models.CASCADE) @@ -271,7 +258,6 @@ class CustomPkTag(models.Model): # path to another model, and a return path from that model. -@python_2_unicode_compatible class Celebrity(models.Model): name = models.CharField("Name", max_length=20) greatest_fan = models.ForeignKey("Fan", models.SET_NULL, null=True, unique=True) @@ -290,7 +276,6 @@ class Fan(models.Model): # Multiple foreign keys -@python_2_unicode_compatible class LeafA(models.Model): data = models.CharField(max_length=10) @@ -307,7 +292,6 @@ class Join(models.Model): b = models.ForeignKey(LeafB, models.CASCADE) -@python_2_unicode_compatible class ReservedName(models.Model): name = models.CharField(max_length=20) order = models.IntegerField() @@ -318,7 +302,6 @@ def __str__(self): # A simpler shared-foreign-key setup that can expose some problems. -@python_2_unicode_compatible class SharedConnection(models.Model): data = models.CharField(max_length=10) @@ -336,7 +319,6 @@ class PointerB(models.Model): # Multi-layer ordering -@python_2_unicode_compatible class SingleObject(models.Model): name = models.CharField(max_length=10) @@ -355,7 +337,6 @@ class Meta: ordering = ['single'] -@python_2_unicode_compatible class Plaything(models.Model): name = models.CharField(max_length=10) others = models.ForeignKey(RelatedObject, models.SET_NULL, null=True) @@ -367,7 +348,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Article(models.Model): name = models.CharField(max_length=20) created = models.DateTimeField() @@ -376,7 +356,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Food(models.Model): name = models.CharField(max_length=20, unique=True) @@ -384,7 +363,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Eaten(models.Model): food = models.ForeignKey(Food, models.SET_NULL, to_field="name", null=True) meal = models.CharField(max_length=20) @@ -393,7 +371,6 @@ def __str__(self): return "%s at %s" % (self.food, self.meal) -@python_2_unicode_compatible class Node(models.Model): num = models.IntegerField(unique=True) parent = models.ForeignKey("self", models.SET_NULL, to_field="num", null=True) @@ -404,7 +381,6 @@ def __str__(self): # Bug #12252 -@python_2_unicode_compatible class ObjectA(models.Model): name = models.CharField(max_length=50) @@ -425,7 +401,6 @@ class ChildObjectA(ObjectA): pass -@python_2_unicode_compatible class ObjectB(models.Model): name = models.CharField(max_length=50) objecta = models.ForeignKey(ObjectA, models.CASCADE) @@ -440,7 +415,6 @@ class Meta: proxy = True -@python_2_unicode_compatible class ObjectC(models.Model): name = models.CharField(max_length=50) objecta = models.ForeignKey(ObjectA, models.SET_NULL, null=True) @@ -451,7 +425,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class SimpleCategory(models.Model): name = models.CharField(max_length=15) @@ -459,7 +432,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class SpecialCategory(SimpleCategory): special_name = models.CharField(max_length=15) @@ -467,7 +439,6 @@ def __str__(self): return self.name + " " + self.special_name -@python_2_unicode_compatible class CategoryItem(models.Model): category = models.ForeignKey(SimpleCategory, models.CASCADE) @@ -475,7 +446,6 @@ def __str__(self): return "category item: " + str(self.category) -@python_2_unicode_compatible class OneToOneCategory(models.Model): new_name = models.CharField(max_length=15) category = models.OneToOneField(SimpleCategory, models.CASCADE) @@ -515,7 +485,6 @@ class ModelA(models.Model): d = models.ForeignKey(ModelD, models.CASCADE) -@python_2_unicode_compatible class Job(models.Model): name = models.CharField(max_length=20, unique=True) @@ -528,7 +497,6 @@ class JobResponsibilities(models.Model): responsibility = models.ForeignKey('Responsibility', models.CASCADE, to_field='description') -@python_2_unicode_compatible class Responsibility(models.Model): description = models.CharField(max_length=20, unique=True) jobs = models.ManyToManyField(Job, through=JobResponsibilities, @@ -561,7 +529,6 @@ class BaseA(models.Model): c = models.ForeignKey(FK3, models.SET_NULL, null=True) -@python_2_unicode_compatible class Identifier(models.Model): name = models.CharField(max_length=100) @@ -605,7 +572,6 @@ class MyObject(models.Model): # Models for #17600 regressions -@python_2_unicode_compatible class Order(models.Model): id = models.IntegerField(primary_key=True) @@ -616,7 +582,6 @@ def __str__(self): return '%s' % self.pk -@python_2_unicode_compatible class OrderItem(models.Model): order = models.ForeignKey(Order, models.CASCADE, related_name='items') status = models.IntegerField() @@ -632,7 +597,6 @@ class BaseUser(models.Model): pass -@python_2_unicode_compatible class Task(models.Model): title = models.CharField(max_length=10) owner = models.ForeignKey(BaseUser, models.CASCADE, related_name='owner') @@ -642,7 +606,6 @@ def __str__(self): return self.title -@python_2_unicode_compatible class Staff(models.Model): name = models.CharField(max_length=10) @@ -650,7 +613,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class StaffUser(BaseUser): staff = models.OneToOneField(Staff, models.CASCADE, related_name='user') @@ -673,7 +635,6 @@ class Person(models.Model): name = models.CharField(max_length=128) -@python_2_unicode_compatible class Company(models.Model): name = models.CharField(max_length=128) employees = models.ManyToManyField(Person, related_name='employers', through='Employment') diff --git a/tests/reserved_names/models.py b/tests/reserved_names/models.py index e3806ab550c3..4548f78e7e0e 100644 --- a/tests/reserved_names/models.py +++ b/tests/reserved_names/models.py @@ -8,10 +8,8 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Thing(models.Model): when = models.CharField(max_length=1, primary_key=True) join = models.CharField(max_length=1) diff --git a/tests/reverse_lookup/models.py b/tests/reverse_lookup/models.py index 51e879bf687a..e7db4272551e 100644 --- a/tests/reverse_lookup/models.py +++ b/tests/reverse_lookup/models.py @@ -5,10 +5,8 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class User(models.Model): name = models.CharField(max_length=200) @@ -16,7 +14,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Poll(models.Model): question = models.CharField(max_length=200) creator = models.ForeignKey(User, models.CASCADE) @@ -25,7 +22,6 @@ def __str__(self): return self.question -@python_2_unicode_compatible class Choice(models.Model): name = models.CharField(max_length=100) poll = models.ForeignKey(Poll, models.CASCADE, related_name="poll_choice") diff --git a/tests/save_delete_hooks/models.py b/tests/save_delete_hooks/models.py index 3d229daadad0..3573112cfa9c 100644 --- a/tests/save_delete_hooks/models.py +++ b/tests/save_delete_hooks/models.py @@ -5,10 +5,8 @@ the methods. """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Person(models.Model): first_name = models.CharField(max_length=20) last_name = models.CharField(max_length=20) diff --git a/tests/schema/models.py b/tests/schema/models.py index 7d13c775a360..e8a5f1c20ff8 100644 --- a/tests/schema/models.py +++ b/tests/schema/models.py @@ -1,6 +1,5 @@ from django.apps.registry import Apps from django.db import models -from django.utils.encoding import python_2_unicode_compatible # Because we want to test creation and deletion of these as separate things, # these models are all inserted into a separate Apps so the main test @@ -160,7 +159,6 @@ class Meta: # Based on tests/reserved_names/models.py -@python_2_unicode_compatible class Thing(models.Model): when = models.CharField(max_length=1, primary_key=True) diff --git a/tests/select_related/models.py b/tests/select_related/models.py index bef287373105..c8ecf831badc 100644 --- a/tests/select_related/models.py +++ b/tests/select_related/models.py @@ -12,13 +12,11 @@ ) from django.contrib.contenttypes.models import ContentType from django.db import models -from django.utils.encoding import python_2_unicode_compatible # Who remembers high school biology? -@python_2_unicode_compatible class Domain(models.Model): name = models.CharField(max_length=50) @@ -26,7 +24,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Kingdom(models.Model): name = models.CharField(max_length=50) domain = models.ForeignKey(Domain, models.CASCADE) @@ -35,7 +32,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Phylum(models.Model): name = models.CharField(max_length=50) kingdom = models.ForeignKey(Kingdom, models.CASCADE) @@ -44,7 +40,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Klass(models.Model): name = models.CharField(max_length=50) phylum = models.ForeignKey(Phylum, models.CASCADE) @@ -53,7 +48,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Order(models.Model): name = models.CharField(max_length=50) klass = models.ForeignKey(Klass, models.CASCADE) @@ -62,7 +56,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Family(models.Model): name = models.CharField(max_length=50) order = models.ForeignKey(Order, models.CASCADE) @@ -71,7 +64,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Genus(models.Model): name = models.CharField(max_length=50) family = models.ForeignKey(Family, models.CASCADE) @@ -80,7 +72,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Species(models.Model): name = models.CharField(max_length=50) genus = models.ForeignKey(Genus, models.CASCADE) @@ -91,7 +82,6 @@ def __str__(self): # and we'll invent a new thing so we have a model with two foreign keys -@python_2_unicode_compatible class HybridSpecies(models.Model): name = models.CharField(max_length=50) parent_1 = models.ForeignKey(Species, models.CASCADE, related_name='child_1') @@ -101,7 +91,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Topping(models.Model): name = models.CharField(max_length=30) @@ -109,7 +98,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Pizza(models.Model): name = models.CharField(max_length=100) toppings = models.ManyToManyField(Topping) @@ -118,7 +106,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class TaggedItem(models.Model): tag = models.CharField(max_length=30) @@ -130,7 +117,6 @@ def __str__(self): return self.tag -@python_2_unicode_compatible class Bookmark(models.Model): url = models.URLField() tags = GenericRelation(TaggedItem) diff --git a/tests/select_related_onetoone/models.py b/tests/select_related_onetoone/models.py index 76c45659afb6..0a20cc737555 100644 --- a/tests/select_related_onetoone/models.py +++ b/tests/select_related_onetoone/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class User(models.Model): username = models.CharField(max_length=100) email = models.EmailField() @@ -11,7 +9,6 @@ def __str__(self): return self.username -@python_2_unicode_compatible class UserProfile(models.Model): user = models.OneToOneField(User, models.CASCADE) city = models.CharField(max_length=100) @@ -21,7 +18,6 @@ def __str__(self): return "%s, %s" % (self.city, self.state) -@python_2_unicode_compatible class UserStatResult(models.Model): results = models.CharField(max_length=50) @@ -29,7 +25,6 @@ def __str__(self): return 'UserStatResults, results = %s' % (self.results,) -@python_2_unicode_compatible class UserStat(models.Model): user = models.OneToOneField(User, models.CASCADE, primary_key=True) posts = models.IntegerField() @@ -39,7 +34,6 @@ def __str__(self): return 'UserStat, posts = %s' % (self.posts,) -@python_2_unicode_compatible class StatDetails(models.Model): base_stats = models.OneToOneField(UserStat, models.CASCADE) comments = models.IntegerField() @@ -61,7 +55,6 @@ class Product(models.Model): image = models.OneToOneField(Image, models.SET_NULL, null=True) -@python_2_unicode_compatible class Parent1(models.Model): name1 = models.CharField(max_length=50) @@ -69,7 +62,6 @@ def __str__(self): return self.name1 -@python_2_unicode_compatible class Parent2(models.Model): # Avoid having two "id" fields in the Child1 subclass id2 = models.AutoField(primary_key=True) @@ -79,7 +71,6 @@ def __str__(self): return self.name2 -@python_2_unicode_compatible class Child1(Parent1, Parent2): value = models.IntegerField() @@ -87,7 +78,6 @@ def __str__(self): return self.name1 -@python_2_unicode_compatible class Child2(Parent1): parent2 = models.OneToOneField(Parent2, models.CASCADE) value = models.IntegerField() diff --git a/tests/select_related_regress/models.py b/tests/select_related_regress/models.py index 4ac8cc15182a..ed4d98544b73 100644 --- a/tests/select_related_regress/models.py +++ b/tests/select_related_regress/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Building(models.Model): name = models.CharField(max_length=10) @@ -10,7 +8,6 @@ def __str__(self): return "Building: %s" % self.name -@python_2_unicode_compatible class Device(models.Model): building = models.ForeignKey('Building', models.CASCADE) name = models.CharField(max_length=10) @@ -19,7 +16,6 @@ def __str__(self): return "device '%s' in building %s" % (self.name, self.building) -@python_2_unicode_compatible class Port(models.Model): device = models.ForeignKey('Device', models.CASCADE) port_number = models.CharField(max_length=10) @@ -28,7 +24,6 @@ def __str__(self): return "%s/%s" % (self.device.name, self.port_number) -@python_2_unicode_compatible class Connection(models.Model): start = models.ForeignKey( Port, @@ -102,7 +97,6 @@ class SpecialClient(Client): # Some model inheritance exercises -@python_2_unicode_compatible class Parent(models.Model): name = models.CharField(max_length=10) @@ -114,7 +108,6 @@ class Child(Parent): value = models.IntegerField() -@python_2_unicode_compatible class Item(models.Model): name = models.CharField(max_length=10) child = models.ForeignKey(Child, models.SET_NULL, null=True) @@ -125,7 +118,6 @@ def __str__(self): # Models for testing bug #19870. -@python_2_unicode_compatible class Fowl(models.Model): name = models.CharField(max_length=10) diff --git a/tests/serializers/models/base.py b/tests/serializers/models/base.py index 5f9bdd833cd9..aa55b87c61c1 100644 --- a/tests/serializers/models/base.py +++ b/tests/serializers/models/base.py @@ -8,7 +8,6 @@ from django.db import models from django.utils import six -from django.utils.encoding import python_2_unicode_compatible class CategoryMetaDataManager(models.Manager): @@ -17,7 +16,6 @@ def get_by_natural_key(self, kind, name): return self.get(kind=kind, name=name) -@python_2_unicode_compatible class CategoryMetaData(models.Model): kind = models.CharField(max_length=10) name = models.CharField(max_length=10) @@ -34,7 +32,6 @@ def natural_key(self): return (self.kind, self.name) -@python_2_unicode_compatible class Category(models.Model): name = models.CharField(max_length=20) meta_data = models.ForeignKey(CategoryMetaData, models.SET_NULL, null=True, default=None) @@ -46,7 +43,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=20) @@ -57,7 +53,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Article(models.Model): author = models.ForeignKey(Author, models.CASCADE) headline = models.CharField(max_length=50) @@ -72,7 +67,6 @@ def __str__(self): return self.headline -@python_2_unicode_compatible class AuthorProfile(models.Model): author = models.OneToOneField(Author, models.CASCADE, primary_key=True) date_of_birth = models.DateField() @@ -81,7 +75,6 @@ def __str__(self): return "Profile of %s" % self.author -@python_2_unicode_compatible class Actor(models.Model): name = models.CharField(max_length=20, primary_key=True) @@ -92,7 +85,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Movie(models.Model): actor = models.ForeignKey(Actor, models.CASCADE) title = models.CharField(max_length=50) @@ -109,7 +101,6 @@ class Score(models.Model): score = models.FloatField() -@python_2_unicode_compatible class Team(object): def __init__(self, title): self.title = title @@ -146,7 +137,6 @@ def deconstruct(self): return name, path, args, kwargs -@python_2_unicode_compatible class Player(models.Model): name = models.CharField(max_length=50) rank = models.IntegerField() diff --git a/tests/signals/models.py b/tests/signals/models.py index 4f8d72817c37..960df390de04 100644 --- a/tests/signals/models.py +++ b/tests/signals/models.py @@ -2,10 +2,8 @@ Testing signals before/after saving and deleting. """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Person(models.Model): first_name = models.CharField(max_length=20) last_name = models.CharField(max_length=20) @@ -14,7 +12,6 @@ def __str__(self): return "%s %s" % (self.first_name, self.last_name) -@python_2_unicode_compatible class Car(models.Model): make = models.CharField(max_length=20) model = models.CharField(max_length=20) @@ -23,7 +20,6 @@ def __str__(self): return "%s %s" % (self.make, self.model) -@python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=20) @@ -31,7 +27,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Book(models.Model): name = models.CharField(max_length=20) authors = models.ManyToManyField(Author) diff --git a/tests/sites_framework/models.py b/tests/sites_framework/models.py index ed0f4443a15c..fb6a9d4e79c3 100644 --- a/tests/sites_framework/models.py +++ b/tests/sites_framework/models.py @@ -1,10 +1,8 @@ from django.contrib.sites.managers import CurrentSiteManager from django.contrib.sites.models import Site from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class AbstractArticle(models.Model): title = models.CharField(max_length=50) diff --git a/tests/str/models.py b/tests/str/models.py index 33e31857fae1..12f024757035 100644 --- a/tests/str/models.py +++ b/tests/str/models.py @@ -14,7 +14,6 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible class Article(models.Model): @@ -27,7 +26,6 @@ def __str__(self): return self.headline -@python_2_unicode_compatible class InternationalArticle(models.Model): headline = models.CharField(max_length=100) pub_date = models.DateTimeField() diff --git a/tests/str/tests.py b/tests/str/tests.py index 516560415cc3..c4dd1d6b2675 100644 --- a/tests/str/tests.py +++ b/tests/str/tests.py @@ -25,13 +25,7 @@ def test_international(self): headline='Girl wins €12.500 in lottery', pub_date=datetime.datetime(2005, 7, 28) ) - if six.PY3: - self.assertEqual(str(a), 'Girl wins €12.500 in lottery') - else: - # On Python 2, the default str() output will be the UTF-8 encoded - # output of __unicode__() -- or __str__() when the - # python_2_unicode_compatible decorator is used. - self.assertEqual(str(a), b'Girl wins \xe2\x82\xac12.500 in lottery') + self.assertEqual(str(a), 'Girl wins €12.500 in lottery') @isolate_apps('str') def test_defaults(self): diff --git a/tests/string_lookup/models.py b/tests/string_lookup/models.py index e8fd8a1b1217..5351ee5fe931 100644 --- a/tests/string_lookup/models.py +++ b/tests/string_lookup/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Foo(models.Model): name = models.CharField(max_length=50) friend = models.CharField(max_length=50, blank=True) @@ -11,7 +9,6 @@ def __str__(self): return "Foo %s" % self.name -@python_2_unicode_compatible class Bar(models.Model): name = models.CharField(max_length=50) normal = models.ForeignKey(Foo, models.CASCADE, related_name='normal_foo') @@ -22,7 +19,6 @@ def __str__(self): return "Bar %s" % self.place.name -@python_2_unicode_compatible class Whiz(models.Model): name = models.CharField(max_length=50) @@ -30,7 +26,6 @@ def __str__(self): return "Whiz %s" % self.name -@python_2_unicode_compatible class Child(models.Model): parent = models.OneToOneField('Base', models.CASCADE) name = models.CharField(max_length=50) @@ -39,7 +34,6 @@ def __str__(self): return "Child %s" % self.name -@python_2_unicode_compatible class Base(models.Model): name = models.CharField(max_length=50) @@ -47,7 +41,6 @@ def __str__(self): return "Base %s" % self.name -@python_2_unicode_compatible class Article(models.Model): name = models.CharField(max_length=50) text = models.TextField() diff --git a/tests/syndication_tests/models.py b/tests/syndication_tests/models.py index 22b0f81fbb0d..f6c499ccca29 100644 --- a/tests/syndication_tests/models.py +++ b/tests/syndication_tests/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Entry(models.Model): title = models.CharField(max_length=200) updated = models.DateTimeField() @@ -18,7 +16,6 @@ def get_absolute_url(self): return "/blog/%s/" % self.pk -@python_2_unicode_compatible class Article(models.Model): title = models.CharField(max_length=200) entry = models.ForeignKey(Entry, models.CASCADE) diff --git a/tests/template_tests/filter_tests/test_unordered_list.py b/tests/template_tests/filter_tests/test_unordered_list.py index eab94427805d..659b1acc2bf4 100644 --- a/tests/template_tests/filter_tests/test_unordered_list.py +++ b/tests/template_tests/filter_tests/test_unordered_list.py @@ -1,6 +1,5 @@ from django.template.defaultfilters import unordered_list from django.test import SimpleTestCase -from django.utils.encoding import python_2_unicode_compatible from django.utils.safestring import mark_safe from ..utils import setup @@ -88,7 +87,6 @@ def test_autoescape_off(self): ) def test_ulitem(self): - @python_2_unicode_compatible class ULItem(object): def __init__(self, title): self.title = title @@ -115,7 +113,6 @@ def item_generator(): ) def test_ulitem_autoescape_off(self): - @python_2_unicode_compatible class ULItem(object): def __init__(self, title): self.title = title diff --git a/tests/template_tests/utils.py b/tests/template_tests/utils.py index cbc452c808e5..187d259f36a4 100644 --- a/tests/template_tests/utils.py +++ b/tests/template_tests/utils.py @@ -4,7 +4,6 @@ from django.template.engine import Engine from django.test.utils import override_settings from django.utils._os import upath -from django.utils.encoding import python_2_unicode_compatible from django.utils.safestring import mark_safe ROOT = os.path.dirname(os.path.abspath(upath(__file__))) @@ -165,7 +164,6 @@ def b(self): b = property(b) -@python_2_unicode_compatible class UTF8Class: "Class whose __str__ returns non-ASCII data on Python 2" def __str__(self): @@ -173,13 +171,11 @@ def __str__(self): # These two classes are used to test auto-escaping of unicode output. -@python_2_unicode_compatible class UnsafeClass: def __str__(self): return 'you & me' -@python_2_unicode_compatible class SafeClass: def __str__(self): return mark_safe('you > me') diff --git a/tests/test_utils/models.py b/tests/test_utils/models.py index 979b04855ff5..e94d44356b5a 100644 --- a/tests/test_utils/models.py +++ b/tests/test_utils/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Car(models.Model): name = models.CharField(max_length=100) @@ -10,7 +8,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class Person(models.Model): name = models.CharField(max_length=100) cars = models.ManyToManyField(Car, through='PossessedCar') @@ -19,7 +16,6 @@ def __str__(self): return self.name -@python_2_unicode_compatible class PossessedCar(models.Model): car = models.ForeignKey(Car, models.CASCADE) belongs_to = models.ForeignKey(Person, models.CASCADE) diff --git a/tests/transaction_hooks/models.py b/tests/transaction_hooks/models.py index cd2f22b514b9..d3abbfef91dc 100644 --- a/tests/transaction_hooks/models.py +++ b/tests/transaction_hooks/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Thing(models.Model): num = models.IntegerField() diff --git a/tests/transactions/models.py b/tests/transactions/models.py index 4154b3912307..2f2bac463a16 100644 --- a/tests/transactions/models.py +++ b/tests/transactions/models.py @@ -7,10 +7,8 @@ manually. """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Reporter(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) diff --git a/tests/unmanaged_models/models.py b/tests/unmanaged_models/models.py index e925752a0679..13824b7732fc 100644 --- a/tests/unmanaged_models/models.py +++ b/tests/unmanaged_models/models.py @@ -4,13 +4,11 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible # All of these models are created in the database by Django. -@python_2_unicode_compatible class A01(models.Model): f_a = models.CharField(max_length=10, db_index=True) f_b = models.IntegerField() @@ -22,7 +20,6 @@ def __str__(self): return self.f_a -@python_2_unicode_compatible class B01(models.Model): fk_a = models.ForeignKey(A01, models.CASCADE) f_a = models.CharField(max_length=10, db_index=True) @@ -37,7 +34,6 @@ def __str__(self): return self.f_a -@python_2_unicode_compatible class C01(models.Model): mm_a = models.ManyToManyField(A01, db_table='d01') f_a = models.CharField(max_length=10, db_index=True) @@ -54,7 +50,6 @@ def __str__(self): # since we have told Django they aren't managed by Django. -@python_2_unicode_compatible class A02(models.Model): f_a = models.CharField(max_length=10, db_index=True) @@ -66,7 +61,6 @@ def __str__(self): return self.f_a -@python_2_unicode_compatible class B02(models.Model): class Meta: db_table = 'b01' @@ -82,7 +76,6 @@ def __str__(self): # To re-use the many-to-many intermediate table, we need to manually set up # things up. -@python_2_unicode_compatible class C02(models.Model): mm_a = models.ManyToManyField(A02, through="Intermediate") f_a = models.CharField(max_length=10, db_index=True) diff --git a/tests/update/models.py b/tests/update/models.py index 648a7733184c..1fbab38ca936 100644 --- a/tests/update/models.py +++ b/tests/update/models.py @@ -5,10 +5,8 @@ from django.db import models from django.utils import six -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class DataPoint(models.Model): name = models.CharField(max_length=20) value = models.CharField(max_length=20) @@ -18,7 +16,6 @@ def __str__(self): return six.text_type(self.name) -@python_2_unicode_compatible class RelatedPoint(models.Model): name = models.CharField(max_length=20) data = models.ForeignKey(DataPoint, models.CASCADE) diff --git a/tests/update_only_fields/models.py b/tests/update_only_fields/models.py index a3be5088a28d..3d6a9ec8e64e 100644 --- a/tests/update_only_fields/models.py +++ b/tests/update_only_fields/models.py @@ -1,6 +1,5 @@ from django.db import models -from django.utils.encoding import python_2_unicode_compatible GENDER_CHOICES = ( ('M', 'Male'), @@ -12,7 +11,6 @@ class Account(models.Model): num = models.IntegerField() -@python_2_unicode_compatible class Person(models.Model): name = models.CharField(max_length=20) gender = models.CharField(max_length=1, choices=GENDER_CHOICES) @@ -28,7 +26,6 @@ class Employee(Person): accounts = models.ManyToManyField('Account', related_name='employees', blank=True) -@python_2_unicode_compatible class Profile(models.Model): name = models.CharField(max_length=200) salary = models.FloatField(default=1000.0) diff --git a/tests/validation/models.py b/tests/validation/models.py index 90b2dbb79a5e..043aa4ded71d 100644 --- a/tests/validation/models.py +++ b/tests/validation/models.py @@ -2,7 +2,6 @@ from django.core.exceptions import ValidationError from django.db import models -from django.utils.encoding import python_2_unicode_compatible def validate_answer_to_universe(value): @@ -89,7 +88,6 @@ def clean(self): self.pub_date = datetime.now() -@python_2_unicode_compatible class Post(models.Model): title = models.CharField(max_length=50, unique_for_date='posted', blank=True) slug = models.CharField(max_length=50, unique_for_year='posted', blank=True) diff --git a/tests/view_tests/models.py b/tests/view_tests/models.py index c891bcadee5b..04e31c43da06 100644 --- a/tests/view_tests/models.py +++ b/tests/view_tests/models.py @@ -3,10 +3,8 @@ """ from django.db import models -from django.utils.encoding import python_2_unicode_compatible -@python_2_unicode_compatible class Author(models.Model): name = models.CharField(max_length=100) @@ -17,7 +15,6 @@ def get_absolute_url(self): return '/authors/%s/' % self.id -@python_2_unicode_compatible class BaseArticle(models.Model): """ An abstract article Model so that we can create article models with and From e63d98b7beb16d1410168a2315cbe04c43c9c80d Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Wed, 18 Jan 2017 08:33:40 -0500 Subject: [PATCH 0060/3180] Removed formtools from intersphinx_mapping. --- docs/conf.py | 1 - docs/releases/1.7.txt | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 13a6dbd67e00..2b42f44268c7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -135,7 +135,6 @@ def django_release(): 'python': ('https://docs.python.org/3/', None), 'sphinx': ('http://sphinx-doc.org/', None), 'six': ('https://pythonhosted.org/six/', None), - 'formtools': ('https://django-formtools.readthedocs.io/en/latest/', None), 'psycopg2': ('http://initd.org/psycopg/docs/', None), } diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index 76cd19eeb5fb..c01c12b55875 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -436,9 +436,8 @@ Minor features ``django.contrib.formtools`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -* Calls to :meth:`WizardView.done() - ` now include a - ``form_dict`` to allow easier access to forms by their step name. +* Calls to ``WizardView.done()`` now include a ``form_dict`` to allow easier + access to forms by their step name. :mod:`django.contrib.gis` ~~~~~~~~~~~~~~~~~~~~~~~~~ From c716fe87821df00f9f03ecc761c914d1682591a2 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Thu, 1 Dec 2016 11:38:01 +0100 Subject: [PATCH 0061/3180] Refs #23919 -- Removed six.PY2/PY3 usage Thanks Tim Graham for the review. --- django/contrib/admindocs/views.py | 8 +- django/contrib/auth/management/__init__.py | 8 -- .../contrib/auth/migrations/0001_initial.py | 6 +- .../0004_alter_user_username_opts.py | 3 +- ...007_alter_validators_add_error_messages.py | 3 +- .../0008_alter_user_username_max_length.py | 3 +- django/contrib/auth/models.py | 4 +- django/contrib/auth/validators.py | 5 +- django/contrib/gis/utils/ogrinspect.py | 3 +- django/contrib/postgres/signals.py | 7 +- django/core/cache/backends/db.py | 6 +- django/core/exceptions.py | 6 +- django/core/files/base.py | 8 +- django/core/handlers/wsgi.py | 17 ++-- django/core/mail/backends/console.py | 6 +- django/core/mail/message.py | 46 +++------ django/core/management/commands/loaddata.py | 3 +- django/core/management/commands/runserver.py | 6 +- django/core/management/templates.py | 22 ++--- django/db/backends/mysql/base.py | 2 - django/db/backends/oracle/operations.py | 2 - django/db/backends/postgresql/base.py | 4 - django/db/backends/sqlite3/base.py | 4 - django/db/backends/sqlite3/features.py | 2 - django/db/migrations/questioner.py | 10 +- django/db/migrations/serializer.py | 12 +-- django/db/models/base.py | 4 +- django/db/models/fields/related.py | 9 +- django/db/models/manager.py | 5 +- django/db/utils.py | 2 +- django/dispatch/dispatcher.py | 15 +-- django/dispatch/weakref_backports.py | 67 ------------- django/http/cookie.py | 32 +------ django/http/multipartparser.py | 9 +- django/http/request.py | 29 ++---- django/http/response.py | 28 ++---- django/test/client.py | 10 +- django/test/signals.py | 4 +- django/test/testcases.py | 6 -- django/test/utils.py | 9 +- django/urls/resolvers.py | 6 +- django/utils/_os.py | 29 +----- django/utils/crypto.py | 3 +- django/utils/datastructures.py | 24 +---- django/utils/decorators.py | 9 +- django/utils/encoding.py | 35 ++----- django/utils/feedgenerator.py | 6 +- django/utils/functional.py | 26 ++--- django/utils/glob.py | 19 ---- django/utils/html.py | 26 ++--- django/utils/html_parser.py | 21 ++--- django/utils/http.py | 29 +----- django/utils/inspect.py | 48 +--------- django/utils/module_loading.py | 94 +++---------------- django/utils/safestring.py | 7 +- django/utils/text.py | 5 - django/utils/translation/template.py | 3 +- django/utils/translation/trans_real.py | 18 +--- django/views/debug.py | 10 +- setup.cfg | 2 +- tests/admin_docs/test_views.py | 4 +- tests/admin_scripts/tests.py | 20 ++-- tests/annotations/tests.py | 3 +- tests/apps/tests.py | 3 - tests/auth_tests/test_forms.py | 14 +-- tests/auth_tests/test_management.py | 3 - tests/auth_tests/test_tokens.py | 14 --- tests/backends/test_utils.py | 5 +- tests/base/models.py | 9 -- tests/cache/tests.py | 6 +- tests/dbshell/test_postgresql_psycopg2.py | 17 ++-- tests/file_uploads/tests.py | 6 +- tests/files/tests.py | 5 +- tests/fixtures_regress/tests.py | 21 +---- tests/handlers/tests.py | 20 ++-- tests/httpwrappers/tests.py | 34 ------- tests/i18n/test_compilation.py | 19 ++-- tests/i18n/tests.py | 52 +--------- tests/inspectdb/tests.py | 8 +- .../test_relative_fields.py | 10 +- tests/mail/tests.py | 43 ++------- tests/middleware/tests.py | 19 ---- tests/migrations/test_commands.py | 16 +--- tests/migrations/test_loader.py | 4 - tests/migrations/test_writer.py | 15 --- tests/model_fields/test_promises.py | 16 +--- tests/project_template/test_settings.py | 7 -- tests/queries/tests.py | 24 +---- tests/queryset_pickle/models.py | 5 +- tests/queryset_pickle/tests.py | 3 - tests/requests/tests.py | 8 +- tests/signing/tests.py | 5 - tests/staticfiles_tests/test_management.py | 3 +- tests/str/models.py | 27 ++---- tests/str/tests.py | 13 +-- .../syntax_tests/test_width_ratio.py | 6 +- tests/template_tests/test_custom.py | 3 - tests/template_tests/test_loaders.py | 2 - tests/template_tests/test_nodelist.py | 7 +- tests/test_runner/test_debug_sql.py | 3 - tests/test_runner/test_parallel.py | 6 +- tests/urlpatterns_reverse/tests.py | 9 +- tests/utils_tests/test_encoding.py | 31 ++---- tests/utils_tests/test_functional.py | 17 +--- tests/utils_tests/test_glob.py | 13 --- tests/utils_tests/test_html.py | 50 +++------- tests/utils_tests/test_http.py | 18 +--- tests/utils_tests/test_simplelazyobject.py | 7 -- tests/view_tests/tests/py3_test_debug.py | 45 --------- tests/view_tests/tests/test_debug.py | 48 ++++++---- tests/view_tests/tests/test_i18n.py | 6 +- 111 files changed, 308 insertions(+), 1299 deletions(-) delete mode 100644 django/dispatch/weakref_backports.py delete mode 100644 django/utils/glob.py delete mode 100644 tests/utils_tests/test_glob.py delete mode 100644 tests/view_tests/tests/py3_test_debug.py diff --git a/django/contrib/admindocs/views.py b/django/contrib/admindocs/views.py index 3488e9fb3aa0..4a8e1eb59901 100644 --- a/django/contrib/admindocs/views.py +++ b/django/contrib/admindocs/views.py @@ -15,7 +15,6 @@ from django.http import Http404 from django.template.engine import Engine from django.urls import get_mod_func, get_resolver, get_urlconf, reverse -from django.utils import six from django.utils.decorators import method_decorator from django.utils.inspect import ( func_accepts_kwargs, func_accepts_var_args, func_has_no_args, @@ -132,12 +131,7 @@ class ViewIndexView(BaseAdminDocsView): @staticmethod def _get_full_name(func): mod_name = func.__module__ - if six.PY3: - return '%s.%s' % (mod_name, func.__qualname__) - else: - # PY2 does not support __qualname__ - func_name = getattr(func, '__name__', func.__class__.__name__) - return '%s.%s' % (mod_name, func_name) + return '%s.%s' % (mod_name, func.__qualname__) def get_context_data(self, **kwargs): views = [] diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py index 17fd8dd11aac..0d3fca03eb4b 100644 --- a/django/contrib/auth/management/__init__.py +++ b/django/contrib/auth/management/__init__.py @@ -8,8 +8,6 @@ from django.contrib.auth import get_permission_codename from django.core import exceptions from django.db import DEFAULT_DB_ALIAS, router -from django.utils import six -from django.utils.encoding import DEFAULT_LOCALE_ENCODING def _get_all_permissions(opts): @@ -98,12 +96,6 @@ def get_system_username(): # if there is no corresponding entry in the /etc/passwd file # (a very restricted chroot environment, for example). return '' - if six.PY2: - try: - result = result.decode(DEFAULT_LOCALE_ENCODING) - except UnicodeDecodeError: - # UnicodeDecodeError - preventive treatment for non-latin Windows. - return '' return result diff --git a/django/contrib/auth/migrations/0001_initial.py b/django/contrib/auth/migrations/0001_initial.py index f97caae1e464..5ab80b64e006 100644 --- a/django/contrib/auth/migrations/0001_initial.py +++ b/django/contrib/auth/migrations/0001_initial.py @@ -1,7 +1,7 @@ import django.contrib.auth.models from django.contrib.auth import validators from django.db import migrations, models -from django.utils import six, timezone +from django.utils import timezone class Migration(migrations.Migration): @@ -63,9 +63,7 @@ class Migration(migrations.Migration): ('username', models.CharField( help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', unique=True, max_length=30, verbose_name='username', - validators=[ - validators.UnicodeUsernameValidator() if six.PY3 else validators.ASCIIUsernameValidator() - ], + validators=[validators.UnicodeUsernameValidator()], )), ('first_name', models.CharField(max_length=30, verbose_name='first name', blank=True)), ('last_name', models.CharField(max_length=30, verbose_name='last name', blank=True)), diff --git a/django/contrib/auth/migrations/0004_alter_user_username_opts.py b/django/contrib/auth/migrations/0004_alter_user_username_opts.py index f4afcf7bd87c..a16083ee3798 100644 --- a/django/contrib/auth/migrations/0004_alter_user_username_opts.py +++ b/django/contrib/auth/migrations/0004_alter_user_username_opts.py @@ -1,6 +1,5 @@ from django.contrib.auth import validators from django.db import migrations, models -from django.utils import six class Migration(migrations.Migration): @@ -16,7 +15,7 @@ class Migration(migrations.Migration): name='username', field=models.CharField( error_messages={'unique': 'A user with that username already exists.'}, max_length=30, - validators=[validators.UnicodeUsernameValidator() if six.PY3 else validators.ASCIIUsernameValidator()], + validators=[validators.UnicodeUsernameValidator()], help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', unique=True, verbose_name='username' ), diff --git a/django/contrib/auth/migrations/0007_alter_validators_add_error_messages.py b/django/contrib/auth/migrations/0007_alter_validators_add_error_messages.py index 6d44280856fc..42f508773093 100644 --- a/django/contrib/auth/migrations/0007_alter_validators_add_error_messages.py +++ b/django/contrib/auth/migrations/0007_alter_validators_add_error_messages.py @@ -1,6 +1,5 @@ from django.contrib.auth import validators from django.db import migrations, models -from django.utils import six class Migration(migrations.Migration): @@ -18,7 +17,7 @@ class Migration(migrations.Migration): help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=30, unique=True, - validators=[validators.UnicodeUsernameValidator() if six.PY3 else validators.ASCIIUsernameValidator()], + validators=[validators.UnicodeUsernameValidator()], verbose_name='username', ), ), diff --git a/django/contrib/auth/migrations/0008_alter_user_username_max_length.py b/django/contrib/auth/migrations/0008_alter_user_username_max_length.py index 15b9cf8c9476..7c9dae09500d 100644 --- a/django/contrib/auth/migrations/0008_alter_user_username_max_length.py +++ b/django/contrib/auth/migrations/0008_alter_user_username_max_length.py @@ -1,6 +1,5 @@ from django.contrib.auth import validators from django.db import migrations, models -from django.utils import six class Migration(migrations.Migration): @@ -18,7 +17,7 @@ class Migration(migrations.Migration): help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, - validators=[validators.UnicodeUsernameValidator() if six.PY3 else validators.ASCIIUsernameValidator()], + validators=[validators.UnicodeUsernameValidator()], verbose_name='username', ), ), diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index 51b0d8fa63fd..7155bd1199f1 100644 --- a/django/contrib/auth/models.py +++ b/django/contrib/auth/models.py @@ -9,7 +9,7 @@ from django.utils import six, timezone from django.utils.translation import ugettext_lazy as _ -from .validators import ASCIIUsernameValidator, UnicodeUsernameValidator +from .validators import UnicodeUsernameValidator def update_last_login(sender, user, **kwargs): @@ -297,7 +297,7 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin): Username and password are required. Other fields are optional. """ - username_validator = UnicodeUsernameValidator() if six.PY3 else ASCIIUsernameValidator() + username_validator = UnicodeUsernameValidator() username = models.CharField( _('username'), diff --git a/django/contrib/auth/validators.py b/django/contrib/auth/validators.py index 0691d22a8865..d8083de809e2 100644 --- a/django/contrib/auth/validators.py +++ b/django/contrib/auth/validators.py @@ -1,7 +1,6 @@ import re from django.core import validators -from django.utils import six from django.utils.deconstruct import deconstructible from django.utils.translation import ugettext_lazy as _ @@ -13,7 +12,7 @@ class ASCIIUsernameValidator(validators.RegexValidator): 'Enter a valid username. This value may contain only English letters, ' 'numbers, and @/./+/-/_ characters.' ) - flags = re.ASCII if six.PY3 else 0 + flags = re.ASCII @deconstructible @@ -23,4 +22,4 @@ class UnicodeUsernameValidator(validators.RegexValidator): 'Enter a valid username. This value may contain only letters, ' 'numbers, and @/./+/-/_ characters.' ) - flags = re.UNICODE if six.PY2 else 0 + flags = 0 diff --git a/django/contrib/gis/utils/ogrinspect.py b/django/contrib/gis/utils/ogrinspect.py index 3cf9b10fd567..71e4c6487844 100644 --- a/django/contrib/gis/utils/ogrinspect.py +++ b/django/contrib/gis/utils/ogrinspect.py @@ -235,5 +235,4 @@ def get_kwargs_str(field_name): if name_field: yield '' - yield ' def __%s__(self): return self.%s' % ( - 'str' if six.PY3 else 'unicode', name_field) + yield ' def __str__(self): return self.%s' % name_field diff --git a/django/contrib/postgres/signals.py b/django/contrib/postgres/signals.py index 183ba1d98300..682627de1d42 100644 --- a/django/contrib/postgres/signals.py +++ b/django/contrib/postgres/signals.py @@ -1,18 +1,13 @@ from psycopg2 import ProgrammingError from psycopg2.extras import register_hstore -from django.utils import six - def register_hstore_handler(connection, **kwargs): if connection.vendor != 'postgresql': return try: - if six.PY2: - register_hstore(connection.connection, globally=True, unicode=True) - else: - register_hstore(connection.connection, globally=True) + register_hstore(connection.connection, globally=True) except ProgrammingError: # Hstore is not available on the database. # diff --git a/django/core/cache/backends/db.py b/django/core/cache/backends/db.py index ce48018d911d..ad805324bd6c 100644 --- a/django/core/cache/backends/db.py +++ b/django/core/cache/backends/db.py @@ -5,7 +5,7 @@ from django.conf import settings from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache from django.db import DatabaseError, connections, models, router, transaction -from django.utils import six, timezone +from django.utils import timezone from django.utils.encoding import force_bytes try: @@ -112,11 +112,9 @@ def _base_set(self, mode, key, value, timeout=DEFAULT_TIMEOUT): if num > self._max_entries: self._cull(db, cursor, now) pickled = pickle.dumps(value, pickle.HIGHEST_PROTOCOL) - b64encoded = base64.b64encode(pickled) # The DB column is expecting a string, so make sure the value is a # string, not bytes. Refs #19274. - if six.PY3: - b64encoded = b64encoded.decode('latin1') + b64encoded = base64.b64encode(pickled).decode('latin1') try: # Note: typecasting for datetimes is needed by some 3rd party # database backends. All core backends work without typecasting, diff --git a/django/core/exceptions.py b/django/core/exceptions.py index 47c5359c7575..3bf52fab000f 100644 --- a/django/core/exceptions.py +++ b/django/core/exceptions.py @@ -1,7 +1,6 @@ """ Global Django exception and warning classes. """ -from django.utils import six from django.utils.encoding import force_text @@ -115,10 +114,7 @@ def __init__(self, message, code=None, params=None): if isinstance(message, ValidationError): if hasattr(message, 'error_dict'): message = message.error_dict - # PY2 has a `message` property which is always there so we can't - # duck-type on it. It was introduced in Python 2.5 and already - # deprecated in Python 2.6. - elif not hasattr(message, 'message' if six.PY3 else 'code'): + elif not hasattr(message, 'message'): message = message.error_list else: message, code, params = message.message, message.code, message.params diff --git a/django/core/files/base.py b/django/core/files/base.py index f797158881f0..dd07bc959a43 100644 --- a/django/core/files/base.py +++ b/django/core/files/base.py @@ -3,7 +3,7 @@ from django.core.files.utils import FileProxyMixin from django.utils import six -from django.utils.encoding import force_bytes, force_str, force_text +from django.utils.encoding import force_str, force_text class File(FileProxyMixin): @@ -140,11 +140,7 @@ class ContentFile(File): A File-like object that takes just raw content, rather than an actual file. """ def __init__(self, content, name=None): - if six.PY3: - stream_class = StringIO if isinstance(content, six.text_type) else BytesIO - else: - stream_class = BytesIO - content = force_bytes(content) + stream_class = StringIO if isinstance(content, six.text_type) else BytesIO super(ContentFile, self).__init__(stream_class(content), name=name) self.size = len(content) diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index 538373cd8d30..f4d3e6553acb 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -8,7 +8,6 @@ from django.core import signals from django.core.handlers import base from django.urls import set_script_prefix -from django.utils import six from django.utils.encoding import ( force_str, force_text, repercent_broken_unicode, ) @@ -212,22 +211,20 @@ def get_bytes_from_wsgi(environ, key, default): """ Get a value from the WSGI environ dictionary as bytes. - key and default should be str objects. Under Python 2 they may also be - unicode objects provided they only contain ASCII characters. + key and default should be str objects. """ value = environ.get(str(key), str(default)) - # Under Python 3, non-ASCII values in the WSGI environ are arbitrarily - # decoded with ISO-8859-1. This is wrong for Django websites where UTF-8 - # is the default. Re-encode to recover the original bytestring. - return value.encode(ISO_8859_1) if six.PY3 else value + # Non-ASCII values in the WSGI environ are arbitrarily decoded with + # ISO-8859-1. This is wrong for Django websites where UTF-8 is the default. + # Re-encode to recover the original bytestring. + return value.encode(ISO_8859_1) def get_str_from_wsgi(environ, key, default): """ Get a value from the WSGI environ dictionary as str. - key and default should be str objects. Under Python 2 they may also be - unicode objects provided they only contain ASCII characters. + key and default should be str objects. """ value = get_bytes_from_wsgi(environ, key, default) - return value.decode(UTF_8, errors='replace') if six.PY3 else value + return value.decode(UTF_8, errors='replace') diff --git a/django/core/mail/backends/console.py b/django/core/mail/backends/console.py index 0ce88534ea67..49ddade984be 100644 --- a/django/core/mail/backends/console.py +++ b/django/core/mail/backends/console.py @@ -5,7 +5,6 @@ import threading from django.core.mail.backends.base import BaseEmailBackend -from django.utils import six class EmailBackend(BaseEmailBackend): @@ -17,9 +16,8 @@ def __init__(self, *args, **kwargs): def write_message(self, message): msg = message.message() msg_data = msg.as_bytes() - if six.PY3: - charset = msg.get_charset().get_output_charset() if msg.get_charset() else 'utf-8' - msg_data = msg_data.decode(charset) + charset = msg.get_charset().get_output_charset() if msg.get_charset() else 'utf-8' + msg_data = msg_data.decode(charset) self.stream.write('%s\n' % msg_data) self.stream.write('-' * 79) self.stream.write('\n') diff --git a/django/core/mail/message.py b/django/core/mail/message.py index 2c68e8280918..c4df44fa9d7e 100644 --- a/django/core/mail/message.py +++ b/django/core/mail/message.py @@ -5,7 +5,9 @@ from email import ( charset as Charset, encoders as Encoders, generator, message_from_string, ) +from email.errors import InvalidHeaderDefect, NonASCIILocalPartDefect from email.header import Header +from email.headerregistry import Address from email.message import Message from email.mime.base import MIMEBase from email.mime.message import MIMEMessage @@ -139,18 +141,8 @@ def sanitize_address(addr, encoding): except UnicodeEncodeError: # IDN or non-ascii in the local part localpart, domain = split_addr(addr, encoding) - if six.PY2: - # On Python 2, use the stdlib since `email.headerregistry` doesn't exist. - from email.utils import formataddr - if localpart and domain: - addr = '@'.join([localpart, domain]) - return formataddr((nm, addr)) - - # On Python 3, an `email.headerregistry.Address` object is used since + # An `email.headerregistry.Address` object is used since # email.utils.formataddr() naively encodes the name as ascii (see #25986). - from email.headerregistry import Address - from email.errors import InvalidHeaderDefect, NonASCIILocalPartDefect - if localpart and domain: address = Address(nm, username=localpart, domain=domain) return str(address) @@ -174,27 +166,21 @@ def as_string(self, unixfrom=False, linesep='\n'): """ fp = six.StringIO() g = generator.Generator(fp, mangle_from_=False) - if six.PY2: - g.flatten(self, unixfrom=unixfrom) - else: - g.flatten(self, unixfrom=unixfrom, linesep=linesep) + g.flatten(self, unixfrom=unixfrom, linesep=linesep) return fp.getvalue() - if six.PY2: - as_bytes = as_string - else: - def as_bytes(self, unixfrom=False, linesep='\n'): - """Return the entire formatted message as bytes. - Optional `unixfrom' when True, means include the Unix From_ envelope - header. + def as_bytes(self, unixfrom=False, linesep='\n'): + """Return the entire formatted message as bytes. + Optional `unixfrom' when True, means include the Unix From_ envelope + header. - This overrides the default as_bytes() implementation to not mangle - lines that begin with 'From '. See bug #13433 for details. - """ - fp = BytesIO() - g = generator.BytesGenerator(fp, mangle_from_=False) - g.flatten(self, unixfrom=unixfrom, linesep=linesep) - return fp.getvalue() + This overrides the default as_bytes() implementation to not mangle + lines that begin with 'From '. See bug #13433 for details. + """ + fp = BytesIO() + g = generator.BytesGenerator(fp, mangle_from_=False) + g.flatten(self, unixfrom=unixfrom, linesep=linesep) + return fp.getvalue() class SafeMIMEMessage(MIMEMixin, MIMEMessage): @@ -450,8 +436,6 @@ def _create_attachment(self, filename, content, mimetype=None): try: filename.encode('ascii') except UnicodeEncodeError: - if six.PY2: - filename = filename.encode('utf-8') filename = ('utf-8', '', filename) attachment.add_header('Content-Disposition', 'attachment', filename=filename) diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index 4b621205e65c..9f71400862a2 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -20,7 +20,6 @@ from django.utils._os import upath from django.utils.encoding import force_text from django.utils.functional import cached_property -from django.utils.glob import glob_escape try: import bz2 @@ -238,7 +237,7 @@ def find_fixtures(self, fixture_label): self.stdout.write("Checking %s for fixtures..." % humanize(fixture_dir)) fixture_files_in_dir = [] path = os.path.join(fixture_dir, fixture_name) - for candidate in glob.iglob(glob_escape(path) + '*'): + for candidate in glob.iglob(glob.escape(path) + '*'): if os.path.basename(candidate) in targets: # Save the fixture_dir and fixture_name for future error messages. fixture_files_in_dir.append((candidate, fixture_dir, fixture_name)) diff --git a/django/core/management/commands/runserver.py b/django/core/management/commands/runserver.py index 62370072c502..e5dcaa1771f9 100644 --- a/django/core/management/commands/runserver.py +++ b/django/core/management/commands/runserver.py @@ -10,8 +10,8 @@ from django.core.servers.basehttp import ( WSGIServer, get_internal_wsgi_application, run, ) -from django.utils import autoreload, six -from django.utils.encoding import force_text, get_system_encoding +from django.utils import autoreload +from django.utils.encoding import force_text naiveip_re = re.compile(r"""^(?: @@ -125,8 +125,6 @@ def inner_run(self, *args, **options): # requires_migrations_check attribute. self.check_migrations() now = datetime.now().strftime('%B %d, %Y - %X') - if six.PY2: - now = now.decode(get_system_encoding()) self.stdout.write(now) self.stdout.write(( "Django version %(version)s, using settings %(settings)r\n" diff --git a/django/core/management/templates.py b/django/core/management/templates.py index 805da991482d..775e75201b5c 100644 --- a/django/core/management/templates.py +++ b/django/core/management/templates.py @@ -16,7 +16,7 @@ from django.core.management.base import BaseCommand, CommandError from django.core.management.utils import handle_extensions from django.template import Context, Engine -from django.utils import archive, six +from django.utils import archive from django.utils.six.moves.urllib.request import urlretrieve from django.utils.version import get_docs_version @@ -218,21 +218,11 @@ def validate_name(self, name, app_or_project): raise CommandError("you must provide %s %s name" % ( "an" if app_or_project == "app" else "a", app_or_project)) # If it's not a valid directory name. - if six.PY2: - if not re.search(r'^[_a-zA-Z]\w*$', name): - # Provide a smart error message, depending on the error. - if not re.search(r'^[_a-zA-Z]', name): - message = 'make sure the name begins with a letter or underscore' - else: - message = 'use only numbers, letters and underscores' - raise CommandError("%r is not a valid %s name. Please %s." % - (name, app_or_project, message)) - else: - if not name.isidentifier(): - raise CommandError( - "%r is not a valid %s name. Please make sure the name is " - "a valid identifier." % (name, app_or_project) - ) + if not name.isidentifier(): + raise CommandError( + "%r is not a valid %s name. Please make sure the name is " + "a valid identifier." % (name, app_or_project) + ) def download(self, url): """ diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 3d6cb7191533..495ca33221cd 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -219,8 +219,6 @@ def get_connection_params(self): 'conv': django_conversions, 'charset': 'utf8', } - if six.PY2: - kwargs['use_unicode'] = True settings_dict = self.settings_dict if settings_dict['USER']: kwargs['user'] = settings_dict['USER'] diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py index fd9d2d11795c..9878fbd9bb48 100644 --- a/django/db/backends/oracle/operations.py +++ b/django/db/backends/oracle/operations.py @@ -252,8 +252,6 @@ def last_executed_query(self, cursor, sql, params): # https://cx-oracle.readthedocs.io/en/latest/cursor.html#Cursor.statement # The DB API definition does not define this attribute. statement = cursor.statement - if statement and six.PY2 and not isinstance(statement, unicode): # NOQA: unicode undefined on PY3 - statement = statement.decode('utf-8') # Unlike Psycopg's `query` and MySQLdb`'s `_last_executed`, CxOracle's # `statement` doesn't contain the query parameters. refs #20010. return super(DatabaseOperations, self).last_executed_query(cursor, statement, params) diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py index 85a21a890588..10b54faa2098 100644 --- a/django/db/backends/postgresql/base.py +++ b/django/db/backends/postgresql/base.py @@ -12,7 +12,6 @@ from django.db import DEFAULT_DB_ALIAS from django.db.backends.base.base import BaseDatabaseWrapper from django.db.utils import DatabaseError as WrappedDatabaseError -from django.utils import six from django.utils.encoding import force_str from django.utils.functional import cached_property from django.utils.safestring import SafeBytes, SafeText @@ -46,9 +45,6 @@ def psycopg2_version(): from .utils import utc_tzinfo_factory # NOQA isort:skip from .version import get_version # NOQA isort:skip -if six.PY2: - psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) - psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY) psycopg2.extensions.register_adapter(SafeBytes, psycopg2.extensions.QuotedString) psycopg2.extensions.register_adapter(SafeText, psycopg2.extensions.QuotedString) psycopg2.extras.register_uuid() diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py index 0cd0516a0aba..de3aa400000b 100644 --- a/django/db/backends/sqlite3/base.py +++ b/django/db/backends/sqlite3/base.py @@ -19,7 +19,6 @@ parse_date, parse_datetime, parse_duration, parse_time, ) from django.utils.encoding import force_text -from django.utils.safestring import SafeBytes try: try: @@ -55,9 +54,6 @@ def decoder(conv_func): Database.register_converter(str("decimal"), decoder(backend_utils.typecast_decimal)) Database.register_adapter(decimal.Decimal, backend_utils.rev_typecast_decimal) -if six.PY2: - Database.register_adapter(str, lambda s: s.decode('utf-8')) - Database.register_adapter(SafeBytes, lambda s: s.decode('utf-8')) class DatabaseWrapper(BaseDatabaseWrapper): diff --git a/django/db/backends/sqlite3/features.py b/django/db/backends/sqlite3/features.py index 43a29b78f5df..5bf1997b4c63 100644 --- a/django/db/backends/sqlite3/features.py +++ b/django/db/backends/sqlite3/features.py @@ -1,6 +1,5 @@ from django.db import utils from django.db.backends.base.features import BaseDatabaseFeatures -from django.utils import six from django.utils.functional import cached_property from .base import Database @@ -48,7 +47,6 @@ def can_release_savepoints(self): @cached_property def can_share_in_memory_db(self): return ( - six.PY3 and Database.__name__ == 'sqlite3.dbapi2' and Database.sqlite_version_info >= (3, 7, 13) ) diff --git a/django/db/migrations/questioner.py b/django/db/migrations/questioner.py index d508ee9b7899..17b9da8eafc7 100644 --- a/django/db/migrations/questioner.py +++ b/django/db/migrations/questioner.py @@ -4,7 +4,7 @@ from django.apps import apps from django.db.models.fields import NOT_PROVIDED -from django.utils import datetime_safe, six, timezone +from django.utils import datetime_safe, timezone from django.utils.six.moves import input from .loader import MigrationLoader @@ -125,13 +125,7 @@ def _ask_default(self, default=''): prompt = "[default: {}] >>> ".format(default) else: prompt = ">>> " - if six.PY3: - # Six does not correctly abstract over the fact that - # py3 input returns a unicode string, while py2 raw_input - # returns a bytestring. - code = input(prompt) - else: - code = input(prompt).decode(sys.stdin.encoding) + code = input(prompt) if not code and default: code = default if not code: diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index b273097da4ea..261fcabd7393 100644 --- a/django/db/migrations/serializer.py +++ b/django/db/migrations/serializer.py @@ -53,11 +53,7 @@ def serialize(self): class ByteTypeSerializer(BaseSerializer): def serialize(self): - value_repr = repr(self.value) - if six.PY2: - # Prepend the `b` prefix since we're importing unicode_literals - value_repr = 'b' + value_repr - return value_repr, set() + return repr(self.value), set() class DatetimeSerializer(BaseSerializer): @@ -276,11 +272,7 @@ def serialize(self): class TextTypeSerializer(BaseSerializer): def serialize(self): - value_repr = repr(self.value) - if six.PY2: - # Strip the `u` prefix since we're importing unicode_literals - value_repr = value_repr[1:] - return value_repr, set() + return repr(self.value), set() class TimedeltaSerializer(BaseSerializer): diff --git a/django/db/models/base.py b/django/db/models/base.py index e18615d76d03..38d0b9621708 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -510,9 +510,7 @@ def __repr__(self): return force_str('<%s: %s>' % (self.__class__.__name__, u)) def __str__(self): - if six.PY2 and hasattr(self, '__unicode__'): - return force_text(self).encode('utf-8') - return str('%s object' % self.__class__.__name__) + return '%s object' % self.__class__.__name__ def __eq__(self, other): if not isinstance(other, Model): diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index aec362e84af5..7f7a6d3ea8d2 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -107,7 +107,6 @@ def check(self, **kwargs): return errors def _check_related_name_is_valid(self): - import re import keyword related_name = self.remote_field.related_name if related_name is None: @@ -115,12 +114,8 @@ def _check_related_name_is_valid(self): is_valid_id = True if keyword.iskeyword(related_name): is_valid_id = False - if six.PY3: - if not related_name.isidentifier(): - is_valid_id = False - else: - if not re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*\Z', related_name): - is_valid_id = False + if not related_name.isidentifier(): + is_valid_id = False if not (is_valid_id or related_name.endswith('+')): return [ checks.Error( diff --git a/django/db/models/manager.py b/django/db/models/manager.py index 5b498d631b5d..96c82e54ebb6 100644 --- a/django/db/models/manager.py +++ b/django/db/models/manager.py @@ -4,7 +4,6 @@ from django.db import router from django.db.models.query import QuerySet -from django.utils import six class BaseManager(object): @@ -86,9 +85,7 @@ def manager_method(self, *args, **kwargs): return manager_method new_methods = {} - # Refs http://bugs.python.org/issue1785. - predicate = inspect.isfunction if six.PY3 else inspect.ismethod - for name, method in inspect.getmembers(queryset_class, predicate=predicate): + for name, method in inspect.getmembers(queryset_class, predicate=inspect.isfunction): # Only copy missing methods. if hasattr(cls, name): continue diff --git a/django/db/utils.py b/django/db/utils.py index 92354b7bad8d..4451f5a60e5d 100644 --- a/django/db/utils.py +++ b/django/db/utils.py @@ -14,7 +14,7 @@ DJANGO_VERSION_PICKLE_KEY = '_django_version' -class Error(Exception if six.PY3 else StandardError): # NOQA: StandardError undefined on PY3 +class Error(Exception): pass diff --git a/django/dispatch/dispatcher.py b/django/dispatch/dispatcher.py index db2f6839f8b9..8cf1680b6ed2 100644 --- a/django/dispatch/dispatcher.py +++ b/django/dispatch/dispatcher.py @@ -2,15 +2,9 @@ import threading import weakref -from django.utils import six from django.utils.inspect import func_accepts_kwargs from django.utils.six.moves import range -if six.PY2: - from .weakref_backports import WeakMethod -else: - from weakref import WeakMethod - def _make_id(target): if hasattr(target, '__func__'): @@ -107,13 +101,10 @@ def connect(self, receiver, sender=None, weak=True, dispatch_uid=None): receiver_object = receiver # Check for bound methods if hasattr(receiver, '__self__') and hasattr(receiver, '__func__'): - ref = WeakMethod + ref = weakref.WeakMethod receiver_object = receiver.__self__ - if six.PY3: - receiver = ref(receiver) - weakref.finalize(receiver_object, self._remove_receiver) - else: - receiver = ref(receiver, self._remove_receiver) + receiver = ref(receiver) + weakref.finalize(receiver_object, self._remove_receiver) with self.lock: self._clear_dead_receivers() diff --git a/django/dispatch/weakref_backports.py b/django/dispatch/weakref_backports.py deleted file mode 100644 index 736f7e1ab832..000000000000 --- a/django/dispatch/weakref_backports.py +++ /dev/null @@ -1,67 +0,0 @@ -""" -weakref_backports is a partial backport of the weakref module for python -versions below 3.4. - -Copyright (C) 2013 Python Software Foundation, see LICENSE.python for details. - -The following changes were made to the original sources during backporting: - - * Added `self` to `super` calls. - * Removed `from None` when raising exceptions. - -""" -from weakref import ref - - -class WeakMethod(ref): - """ - A custom `weakref.ref` subclass which simulates a weak reference to - a bound method, working around the lifetime problem of bound methods. - """ - - __slots__ = "_func_ref", "_meth_type", "_alive", "__weakref__" - - def __new__(cls, meth, callback=None): - try: - obj = meth.__self__ - func = meth.__func__ - except AttributeError: - raise TypeError("argument should be a bound method, not {}" - .format(type(meth))) - def _cb(arg): - # The self-weakref trick is needed to avoid creating a reference - # cycle. - self = self_wr() - if self._alive: - self._alive = False - if callback is not None: - callback(self) - self = ref.__new__(cls, obj, _cb) - self._func_ref = ref(func, _cb) - self._meth_type = type(meth) - self._alive = True - self_wr = ref(self) - return self - - def __call__(self): - obj = super(WeakMethod, self).__call__() - func = self._func_ref() - if obj is None or func is None: - return None - return self._meth_type(func, obj) - - def __eq__(self, other): - if isinstance(other, WeakMethod): - if not self._alive or not other._alive: - return self is other - return ref.__eq__(self, other) and self._func_ref == other._func_ref - return False - - def __ne__(self, other): - if isinstance(other, WeakMethod): - if not self._alive or not other._alive: - return self is not other - return ref.__ne__(self, other) or self._func_ref != other._func_ref - return True - - __hash__ = ref.__hash__ diff --git a/django/http/cookie.py b/django/http/cookie.py index 49048787eb9c..7251d04c4079 100644 --- a/django/http/cookie.py +++ b/django/http/cookie.py @@ -1,12 +1,7 @@ import sys -from django.utils import six -from django.utils.encoding import force_str from django.utils.six.moves import http_cookies -# http://bugs.python.org/issue2193 is fixed in Python 3.3+. -_cookie_allows_colon_in_names = six.PY3 - # Cookie pickling bug is fixed in Python 2.7.9 and Python 3.4.3+ # http://bugs.python.org/issue22775 cookie_pickles_properly = ( @@ -14,7 +9,7 @@ sys.version_info >= (3, 4, 3) ) -if _cookie_allows_colon_in_names and cookie_pickles_properly: +if cookie_pickles_properly: SimpleCookie = http_cookies.SimpleCookie else: Morsel = http_cookies.Morsel @@ -30,37 +25,12 @@ def __setitem__(self, key, value): else: super(SimpleCookie, self).__setitem__(key, value) - if not _cookie_allows_colon_in_names: - def load(self, rawdata): - self.bad_cookies = set() - if isinstance(rawdata, six.text_type): - rawdata = force_str(rawdata) - super(SimpleCookie, self).load(rawdata) - for key in self.bad_cookies: - del self[key] - - # override private __set() method: - # (needed for using our Morsel, and for laxness with CookieError - def _BaseCookie__set(self, key, real_value, coded_value): - key = force_str(key) - try: - M = self.get(key, Morsel()) - M.set(key, real_value, coded_value) - dict.__setitem__(self, key, M) - except http_cookies.CookieError: - if not hasattr(self, 'bad_cookies'): - self.bad_cookies = set() - self.bad_cookies.add(key) - dict.__setitem__(self, key, http_cookies.Morsel()) - def parse_cookie(cookie): """ Return a dictionary parsed from a `Cookie:` header string. """ cookiedict = {} - if six.PY2: - cookie = force_str(cookie) for chunk in cookie.split(str(';')): if str('=') in chunk: key, val = chunk.split(str('='), 1) diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index ecfbdf72522f..812e83eff005 100644 --- a/django/http/multipartparser.py +++ b/django/http/multipartparser.py @@ -40,8 +40,6 @@ class InputStreamExhausted(Exception): FILE = "file" FIELD = "field" -_BASE64_DECODE_ERROR = TypeError if six.PY2 else binascii.Error - class MultiPartParser(object): """ @@ -190,7 +188,7 @@ def parse(self): num_bytes_read += len(raw_data) try: data = base64.b64decode(raw_data) - except _BASE64_DECODE_ERROR: + except binascii.Error: data = raw_data else: data = field_stream.read(size=read_size) @@ -684,10 +682,7 @@ def parse_header(line): value = p[i + 1:].strip() if has_encoding: encoding, lang, value = value.split(b"'") - if six.PY3: - value = unquote(value.decode(), encoding=encoding.decode()) - else: - value = unquote(value).decode(encoding) + value = unquote(value.decode(), encoding=encoding.decode()) if len(value) >= 2 and value[:1] == value[-1:] == b'"': value = value[1:-1] value = value.replace(b'\\\\', b'\\').replace(b'\\"', b'"') diff --git a/django/http/request.py b/django/http/request.py index 559081b50c43..b4053142ac93 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -14,7 +14,7 @@ from django.utils import six from django.utils.datastructures import ImmutableList, MultiValueDict from django.utils.encoding import ( - escape_uri_path, force_bytes, force_str, force_text, iri_to_uri, + escape_uri_path, force_bytes, force_str, iri_to_uri, ) from django.utils.http import is_same_domain, limited_parse_qsl from django.utils.six.moves.urllib.parse import ( @@ -381,24 +381,15 @@ def __init__(self, query_string=None, mutable=False, encoding=None): 'fields_limit': settings.DATA_UPLOAD_MAX_NUMBER_FIELDS, 'encoding': encoding, } - if six.PY3: - if isinstance(query_string, bytes): - # query_string normally contains URL-encoded data, a subset of ASCII. - try: - query_string = query_string.decode(encoding) - except UnicodeDecodeError: - # ... but some user agents are misbehaving :-( - query_string = query_string.decode('iso-8859-1') - for key, value in limited_parse_qsl(query_string, **parse_qsl_kwargs): - self.appendlist(key, value) - else: - for key, value in limited_parse_qsl(query_string, **parse_qsl_kwargs): - try: - value = value.decode(encoding) - except UnicodeDecodeError: - value = value.decode('iso-8859-1') - self.appendlist(force_text(key, encoding, errors='replace'), - value) + if isinstance(query_string, bytes): + # query_string normally contains URL-encoded data, a subset of ASCII. + try: + query_string = query_string.decode(encoding) + except UnicodeDecodeError: + # ... but some user agents are misbehaving :-( + query_string = query_string.decode('iso-8859-1') + for key, value in limited_parse_qsl(query_string, **parse_qsl_kwargs): + self.appendlist(key, value) self._mutable = mutable @classmethod diff --git a/django/http/response.py b/django/http/response.py index 597d68860277..e4cce4fdbec1 100644 --- a/django/http/response.py +++ b/django/http/response.py @@ -100,10 +100,7 @@ def to_bytes(val, encoding): ] return b'\r\n'.join(headers) - if six.PY3: - __bytes__ = serialize_headers - else: - __str__ = serialize_headers + __bytes__ = serialize_headers @property def _content_type_for_repr(self): @@ -122,20 +119,12 @@ def _convert_to_charset(self, value, charset, mime_encode=False): isinstance(value, six.text_type) and ('\n' in value or '\r' in value)): raise BadHeaderError("Header values can't contain newlines (got %r)" % value) try: - if six.PY3: - if isinstance(value, str): - # Ensure string is valid in given charset - value.encode(charset) - else: - # Convert bytestring using given charset - value = value.decode(charset) + if isinstance(value, str): + # Ensure string is valid in given charset + value.encode(charset) else: - if isinstance(value, str): - # Ensure string is valid in given charset - value.decode(charset) - else: - # Convert unicode string to given charset - value = value.encode(charset) + # Convert bytestring using given charset + value = value.decode(charset) except UnicodeError as e: if mime_encode: # Wrapping in str() is a workaround for #12422 under Python 2. @@ -311,10 +300,7 @@ def serialize(self): """Full HTTP message, including headers, as a bytestring.""" return self.serialize_headers() + b'\r\n\r\n' + self.content - if six.PY3: - __bytes__ = serialize - else: - __str__ = serialize + __bytes__ = serialize @property def content(self): diff --git a/django/test/client.py b/django/test/client.py index 7365b1d2aa36..8134c1725331 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -322,10 +322,10 @@ def _get_path(self, parsed): if parsed[3]: path += str(";") + force_str(parsed[3]) path = uri_to_iri(path).encode(UTF_8) - # Under Python 3, non-ASCII values in the WSGI environ are arbitrarily - # decoded with ISO-8859-1. We replicate this behavior here. + # Replace the behavior where non-ASCII values in the WSGI environ are + # arbitrarily decoded with ISO-8859-1. # Refs comment in `get_bytes_from_wsgi()`. - return path.decode(ISO_8859_1) if six.PY3 else path + return path.decode(ISO_8859_1) def get(self, path, data=None, secure=False, **extra): "Construct a GET request." @@ -406,10 +406,8 @@ def generic(self, method, path, data='', r.update(extra) # If QUERY_STRING is absent or empty, we want to extract it from the URL. if not r.get('QUERY_STRING'): - query_string = force_bytes(parsed[4]) # WSGI requires latin-1 encoded strings. See get_path_info(). - if six.PY3: - query_string = query_string.decode('iso-8859-1') + query_string = force_bytes(parsed[4]).decode('iso-8859-1') r['QUERY_STRING'] = query_string return self.request(**r) diff --git a/django/test/signals.py b/django/test/signals.py index 7b105eda3591..a623e756ce14 100644 --- a/django/test/signals.py +++ b/django/test/signals.py @@ -9,7 +9,7 @@ from django.db import connections, router from django.db.utils import ConnectionRouter from django.dispatch import Signal, receiver -from django.utils import six, timezone +from django.utils import timezone from django.utils.formats import FORMAT_SETTINGS, reset_format_cache from django.utils.functional import empty @@ -139,7 +139,7 @@ def complex_setting_changed(**kwargs): # Considering the current implementation of the signals framework, # this stacklevel shows the line containing the override_settings call. warnings.warn("Overriding setting %s can lead to unexpected behavior." - % kwargs['setting'], stacklevel=5 if six.PY2 else 6) + % kwargs['setting'], stacklevel=6) @receiver(setting_changed) diff --git a/django/test/testcases.py b/django/test/testcases.py index 88d355311daa..7e8cee5c0ded 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -775,12 +775,6 @@ def assertXMLNotEqual(self, xml1, xml2, msg=None): standardMsg = '%s == %s' % (safe_repr(xml1, True), safe_repr(xml2, True)) self.fail(self._formatMessage(msg, standardMsg)) - if six.PY2: - assertCountEqual = unittest.TestCase.assertItemsEqual - assertNotRegex = unittest.TestCase.assertNotRegexpMatches - assertRaisesRegex = unittest.TestCase.assertRaisesRegexp - assertRegex = unittest.TestCase.assertRegexpMatches - class TransactionTestCase(SimpleTestCase): diff --git a/django/test/utils.py b/django/test/utils.py index b24f2e8c80d3..5ed32dbab562 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -6,6 +6,7 @@ import warnings from contextlib import contextmanager from functools import wraps +from types import SimpleNamespace from unittest import TestCase, skipIf, skipUnless from xml.dom.minidom import Node, parseString @@ -25,12 +26,6 @@ from django.utils.encoding import force_str from django.utils.translation import deactivate -if six.PY3: - from types import SimpleNamespace -else: - class SimpleNamespace(object): - pass - try: import jinja2 except ImportError: @@ -615,7 +610,7 @@ def is_quoted_unicode(s): def str_prefix(s): - return s % {'_': '' if six.PY3 else 'u'} + return s % {'_': ''} class CaptureQueriesContext(object): diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py index 4a66895de521..4e8bded3dbb4 100644 --- a/django/urls/resolvers.py +++ b/django/urls/resolvers.py @@ -209,11 +209,7 @@ def lookup_str(self): callback = callback.func if not hasattr(callback, '__name__'): return callback.__module__ + "." + callback.__class__.__name__ - elif six.PY3: - return callback.__module__ + "." + callback.__qualname__ - else: - # PY2 does not support __qualname__ - return callback.__module__ + "." + callback.__name__ + return callback.__module__ + "." + callback.__qualname__ class RegexURLResolver(LocaleRegexProvider): diff --git a/django/utils/_os.py b/django/utils/_os.py index 994f766d498c..ddf2132f5fe6 100644 --- a/django/utils/_os.py +++ b/django/utils/_os.py @@ -1,41 +1,18 @@ import os -import sys import tempfile -from os.path import abspath, dirname, isabs, join, normcase, normpath, sep +from os.path import abspath, dirname, join, normcase, sep from django.core.exceptions import SuspiciousFileOperation -from django.utils import six from django.utils.encoding import force_text -if six.PY2: - fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() - -# Under Python 2, define our own abspath function that can handle joining -# unicode paths to a current working directory that has non-ASCII characters -# in it. This isn't necessary on Windows since the Windows version of abspath -# handles this correctly. It also handles drive letters differently than the -# pure Python implementation, so it's best not to replace it. -if six.PY3 or os.name == 'nt': - abspathu = abspath -else: - def abspathu(path): - """ - Version of os.path.abspath that uses the unicode representation - of the current working directory, thus avoiding a UnicodeDecodeError - in join when the cwd has non-ASCII characters. - """ - if not isabs(path): - path = join(os.getcwdu(), path) - return normpath(path) +abspathu = abspath def upath(path): """ Always return a unicode path. """ - if six.PY2 and not isinstance(path, six.text_type): - return path.decode(fs_encoding) return path @@ -44,8 +21,6 @@ def npath(path): Always return a native path, that is unicode on Python 3 and bytestring on Python 2. """ - if six.PY2 and not isinstance(path, bytes): - return path.encode(fs_encoding) return path diff --git a/django/utils/crypto.py b/django/utils/crypto.py index a7257a1b3a6d..554958b6eede 100644 --- a/django/utils/crypto.py +++ b/django/utils/crypto.py @@ -9,7 +9,6 @@ import time from django.conf import settings -from django.utils import six from django.utils.encoding import force_bytes from django.utils.six.moves import range @@ -94,7 +93,7 @@ def constant_time_compare(val1, val2): if len(val1) != len(val2): return False result = 0 - if six.PY3 and isinstance(val1, bytes) and isinstance(val2, bytes): + if isinstance(val1, bytes) and isinstance(val2, bytes): for x, y in zip(val1, val2): result |= x ^ y else: diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py index a95f8c351aa5..736792460023 100644 --- a/django/utils/datastructures.py +++ b/django/utils/datastructures.py @@ -179,7 +179,7 @@ def appendlist(self, key, value): """Appends an item to the internal list associated with key.""" self.setlistdefault(key).append(value) - def _iteritems(self): + def items(self): """ Yields (key, value) pairs, where value is the last item in the list associated with the key. @@ -187,33 +187,15 @@ def _iteritems(self): for key in self: yield key, self[key] - def _iterlists(self): + def lists(self): """Yields (key, list) pairs.""" return six.iteritems(super(MultiValueDict, self)) - def _itervalues(self): + def values(self): """Yield the last value on every key list.""" for key in self: yield self[key] - if six.PY3: - items = _iteritems - lists = _iterlists - values = _itervalues - else: - iteritems = _iteritems - iterlists = _iterlists - itervalues = _itervalues - - def items(self): - return list(self.iteritems()) - - def lists(self): - return list(self.iterlists()) - - def values(self): - return list(self.itervalues()) - def copy(self): """Returns a shallow copy of this object.""" return copy.copy(self) diff --git a/django/utils/decorators.py b/django/utils/decorators.py index 7ba31a32e323..071028930f46 100644 --- a/django/utils/decorators.py +++ b/django/utils/decorators.py @@ -7,8 +7,6 @@ from functools import WRAPPER_ASSIGNMENTS, update_wrapper, wraps -from django.utils import six - class classonlymethod(classmethod): def __get__(self, instance, cls=None): @@ -121,13 +119,10 @@ def decorator_from_middleware(middleware_class): def available_attrs(fn): """ Return the list of functools-wrappable attributes on a callable. - This is required as a workaround for http://bugs.python.org/issue3445 + This was required as a workaround for http://bugs.python.org/issue3445 under Python 2. """ - if six.PY3: - return WRAPPER_ASSIGNMENTS - else: - return tuple(a for a in WRAPPER_ASSIGNMENTS if hasattr(fn, a)) + return WRAPPER_ASSIGNMENTS def make_middleware_decorator(middleware_class): diff --git a/django/utils/encoding.py b/django/utils/encoding.py index a3b07dcec6a9..f0627f5d3908 100644 --- a/django/utils/encoding.py +++ b/django/utils/encoding.py @@ -2,13 +2,11 @@ import datetime import locale from decimal import Decimal +from urllib.parse import unquote_to_bytes from django.utils import six from django.utils.functional import Promise -from django.utils.six.moves.urllib.parse import quote, unquote - -if six.PY3: - from urllib.parse import unquote_to_bytes +from django.utils.six.moves.urllib.parse import quote class DjangoUnicodeDecodeError(UnicodeDecodeError): @@ -66,15 +64,10 @@ def force_text(s, encoding='utf-8', strings_only=False, errors='strict'): return s try: if not issubclass(type(s), six.string_types): - if six.PY3: - if isinstance(s, bytes): - s = six.text_type(s, encoding, errors) - else: - s = six.text_type(s) - elif hasattr(s, '__unicode__'): - s = six.text_type(s) + if isinstance(s, bytes): + s = six.text_type(s, encoding, errors) else: - s = six.text_type(bytes(s), encoding, errors) + s = six.text_type(s) else: # Note: We use .decode() here, instead of six.text_type(s, encoding, # errors), so that if s is a SafeBytes, it ends up being a @@ -127,10 +120,7 @@ def force_bytes(s, encoding='utf-8', strings_only=False, errors='strict'): return six.text_type(s).encode(encoding, errors) if not isinstance(s, six.string_types): try: - if six.PY3: - return six.text_type(s).encode(encoding) - else: - return bytes(s) + return six.text_type(s).encode(encoding) except UnicodeEncodeError: if isinstance(s, Exception): # An Exception subclass containing non-ASCII data that doesn't @@ -143,15 +133,8 @@ def force_bytes(s, encoding='utf-8', strings_only=False, errors='strict'): return s.encode(encoding, errors) -if six.PY3: - smart_str = smart_text - force_str = force_text -else: - smart_str = smart_bytes - force_str = force_bytes - # backwards compatibility for Python 2 - smart_unicode = smart_text - force_unicode = force_text +smart_str = smart_text +force_str = force_text smart_str.__doc__ = """ Apply smart_text in Python 3 and smart_bytes in Python 2. @@ -207,7 +190,7 @@ def uri_to_iri(uri): if uri is None: return uri uri = force_bytes(uri) - iri = unquote_to_bytes(uri) if six.PY3 else unquote(uri) + iri = unquote_to_bytes(uri) return repercent_broken_unicode(iri).decode('utf-8') diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py index 64aa970e93da..fbab58b905a8 100644 --- a/django/utils/feedgenerator.py +++ b/django/utils/feedgenerator.py @@ -23,7 +23,7 @@ """ import datetime -from django.utils import datetime_safe, six +from django.utils import datetime_safe from django.utils.encoding import force_text, iri_to_uri from django.utils.six import StringIO from django.utils.six.moves.urllib.parse import urlparse @@ -42,8 +42,6 @@ def rfc2822_date(date): dow = days[date.weekday()] month = months[date.month - 1] time_str = date.strftime('%s, %%d %s %%Y %%H:%%M:%%S ' % (dow, month)) - if six.PY2: # strftime returns a byte string in Python 2 - time_str = time_str.decode('utf-8') offset = date.utcoffset() # Historically, this function assumes that naive datetimes are in UTC. if offset is None: @@ -58,8 +56,6 @@ def rfc3339_date(date): # Support datetime objects older than 1900 date = datetime_safe.new_datetime(date) time_str = date.strftime('%Y-%m-%dT%H:%M:%S') - if six.PY2: # strftime returns a byte string in Python 2 - time_str = time_str.decode('utf-8') offset = date.utcoffset() # Historically, this function assumes that naive datetimes are in UTC. if offset is None: diff --git a/django/utils/functional.py b/django/utils/functional.py index 794f31047c5e..933085391d91 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -92,16 +92,9 @@ def __prepare_class__(cls): assert not (cls._delegate_bytes and cls._delegate_text), ( "Cannot call lazy() with both bytes and text return types.") if cls._delegate_text: - if six.PY3: - cls.__str__ = cls.__text_cast - else: - cls.__unicode__ = cls.__text_cast - cls.__str__ = cls.__bytes_cast_encoded + cls.__str__ = cls.__text_cast elif cls._delegate_bytes: - if six.PY3: - cls.__bytes__ = cls.__bytes_cast - else: - cls.__str__ = cls.__bytes_cast + cls.__bytes__ = cls.__bytes_cast @classmethod def __promise__(cls, method_name): @@ -154,9 +147,7 @@ def __hash__(self): return hash(self.__cast()) def __mod__(self, rhs): - if self._delegate_bytes and six.PY2: - return bytes(self) % rhs - elif self._delegate_text: + if self._delegate_text: return six.text_type(self) % rhs return self.__cast() % rhs @@ -316,14 +307,9 @@ def __deepcopy__(self, memo): return result return copy.deepcopy(self._wrapped, memo) - if six.PY3: - __bytes__ = new_method_proxy(bytes) - __str__ = new_method_proxy(str) - __bool__ = new_method_proxy(bool) - else: - __str__ = new_method_proxy(str) - __unicode__ = new_method_proxy(unicode) # NOQA: unicode undefined on PY3 - __nonzero__ = new_method_proxy(bool) + __bytes__ = new_method_proxy(bytes) + __str__ = new_method_proxy(str) + __bool__ = new_method_proxy(bool) # Introspection support __dir__ = new_method_proxy(dir) diff --git a/django/utils/glob.py b/django/utils/glob.py deleted file mode 100644 index 92194d21eb2a..000000000000 --- a/django/utils/glob.py +++ /dev/null @@ -1,19 +0,0 @@ -import os.path -import re - -from django.utils import six - -# backport of Python 3.4's glob.escape - -if six.PY3: - from glob import escape as glob_escape -else: - _magic_check = re.compile('([*?[])') - - def glob_escape(pathname): - """ - Escape all special characters. - """ - drive, pathname = os.path.splitdrive(pathname) - pathname = _magic_check.sub(r'[\1]', pathname) - return drive + pathname diff --git a/django/utils/html.py b/django/utils/html.py index 384093a02f1c..36b5d53283df 100644 --- a/django/utils/html.py +++ b/django/utils/html.py @@ -363,22 +363,12 @@ def html_safe(klass): "can't apply @html_safe to %s because it defines " "__html__()." % klass.__name__ ) - if six.PY2: - if '__unicode__' not in klass.__dict__: - raise ValueError( - "can't apply @html_safe to %s because it doesn't " - "define __unicode__()." % klass.__name__ - ) - klass_unicode = klass.__unicode__ - klass.__unicode__ = lambda self: mark_safe(klass_unicode(self)) - klass.__html__ = lambda self: unicode(self) # NOQA: unicode undefined on PY3 - else: - if '__str__' not in klass.__dict__: - raise ValueError( - "can't apply @html_safe to %s because it doesn't " - "define __str__()." % klass.__name__ - ) - klass_str = klass.__str__ - klass.__str__ = lambda self: mark_safe(klass_str(self)) - klass.__html__ = lambda self: str(self) + if '__str__' not in klass.__dict__: + raise ValueError( + "can't apply @html_safe to %s because it doesn't " + "define __str__()." % klass.__name__ + ) + klass_str = klass.__str__ + klass.__str__ = lambda self: mark_safe(klass_str(self)) + klass.__html__ = lambda self: str(self) return klass diff --git a/django/utils/html_parser.py b/django/utils/html_parser.py index 89646079dba9..d272004f77ba 100644 --- a/django/utils/html_parser.py +++ b/django/utils/html_parser.py @@ -1,4 +1,3 @@ -from django.utils import six from django.utils.six.moves import html_parser as _html_parser try: @@ -8,15 +7,13 @@ class HTMLParseError(Exception): pass -if six.PY3: - 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. - """ - def __init__(self, convert_charrefs=False, **kwargs): - _html_parser.HTMLParser.__init__(self, convert_charrefs=convert_charrefs, **kwargs) -else: - HTMLParser = _html_parser.HTMLParser +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. + """ + def __init__(self, convert_charrefs=False, **kwargs): + _html_parser.HTMLParser.__init__(self, convert_charrefs=convert_charrefs, **kwargs) diff --git a/django/utils/http.py b/django/utils/http.py index f4e77b86f96c..0308e14676a6 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -189,12 +189,7 @@ def base36_to_int(s): # is sufficient to base36-encode any 64-bit integer) if len(s) > 13: raise ValueError("Base36 input too large") - value = int(s, 36) - # ... then do a final check that the value will fit into an int to avoid - # returning a long (#15067). The long type was removed in Python 3. - if six.PY2 and value > sys.maxint: - raise ValueError("Base36 input too large") - return value + return int(s, 36) def int_to_base36(i): @@ -204,11 +199,6 @@ def int_to_base36(i): char_set = '0123456789abcdefghijklmnopqrstuvwxyz' if i < 0: raise ValueError("Negative base36 conversion input.") - if six.PY2: - if not isinstance(i, six.integer_types): - raise TypeError("Non-integer base36 conversion input.") - if i > sys.maxint: - raise ValueError("Base36 conversion input too large.") if i < 36: return char_set[i] b36 = '' @@ -296,11 +286,6 @@ def is_safe_url(url, host=None, allowed_hosts=None, require_https=False): url = url.strip() if not url: return False - if six.PY2: - try: - url = force_text(url) - except UnicodeDecodeError: - return False if allowed_hosts is None: allowed_hosts = set() if host: @@ -388,13 +373,9 @@ def limited_parse_qsl(qs, keep_blank_values=False, encoding='utf-8', else: continue if len(nv[1]) or keep_blank_values: - if six.PY3: - name = nv[0].replace('+', ' ') - name = unquote(name, encoding=encoding, errors=errors) - value = nv[1].replace('+', ' ') - value = unquote(value, encoding=encoding, errors=errors) - else: - name = unquote(nv[0].replace(b'+', b' ')) - value = unquote(nv[1].replace(b'+', b' ')) + name = nv[0].replace('+', ' ') + name = unquote(name, encoding=encoding, errors=errors) + value = nv[1].replace('+', ' ') + value = unquote(value, encoding=encoding, errors=errors) r.append((name, value)) return r diff --git a/django/utils/inspect.py b/django/utils/inspect.py index ffcbf3040730..9ef28bbf004f 100644 --- a/django/utils/inspect.py +++ b/django/utils/inspect.py @@ -1,12 +1,7 @@ import inspect -from django.utils import six - def getargspec(func): - if six.PY2: - return inspect.getargspec(func) - sig = inspect.signature(func) args = [ p.name for p in sig.parameters.values() @@ -30,10 +25,6 @@ def getargspec(func): def get_func_args(func): - if six.PY2: - argspec = inspect.getargspec(func) - return argspec.args[1:] # ignore 'self' - sig = inspect.signature(func) return [ arg_name for arg_name, param in sig.parameters.items() @@ -47,20 +38,6 @@ def get_func_full_args(func): does not have a default value, omit it in the tuple. Arguments such as *args and **kwargs are also included. """ - if six.PY2: - argspec = inspect.getargspec(func) - args = argspec.args[1:] # ignore 'self' - defaults = argspec.defaults or [] - # Split args into two lists depending on whether they have default value - no_default = args[:len(args) - len(defaults)] - with_default = args[len(args) - len(defaults):] - # Join the two lists and combine it with default values - args = [(arg,) for arg in no_default] + zip(with_default, defaults) - # Add possible *args and **kwargs and prepend them with '*' or '**' - varargs = [('*' + argspec.varargs,)] if argspec.varargs else [] - kwargs = [('**' + argspec.keywords,)] if argspec.keywords else [] - return args + varargs + kwargs - sig = inspect.signature(func) args = [] for arg_name, param in sig.parameters.items(): @@ -80,20 +57,6 @@ def get_func_full_args(func): def func_accepts_kwargs(func): - if six.PY2: - # Not all callables are inspectable with getargspec, so we'll - # try a couple different ways but in the end fall back on assuming - # it is -- we don't want to prevent registration of valid but weird - # callables. - try: - argspec = inspect.getargspec(func) - except TypeError: - try: - argspec = inspect.getargspec(func.__call__) - except (TypeError, AttributeError): - argspec = None - return not argspec or argspec[2] is not None - return any( p for p in inspect.signature(func).parameters.values() if p.kind == p.VAR_KEYWORD @@ -104,9 +67,6 @@ def func_accepts_var_args(func): """ Return True if function 'func' accepts positional arguments *args. """ - if six.PY2: - return inspect.getargspec(func)[1] is not None - return any( p for p in inspect.signature(func).parameters.values() if p.kind == p.VAR_POSITIONAL @@ -114,7 +74,7 @@ def func_accepts_var_args(func): def func_has_no_args(func): - args = inspect.getargspec(func)[0] if six.PY2 else [ + args = [ p for p in inspect.signature(func).parameters.values() if p.kind == p.POSITIONAL_OR_KEYWORD ] @@ -122,8 +82,4 @@ def func_has_no_args(func): def func_supports_parameter(func, parameter): - if six.PY3: - return parameter in inspect.signature(func).parameters - else: - args, varargs, varkw, defaults = inspect.getargspec(func) - return parameter in args + return parameter in inspect.signature(func).parameters diff --git a/django/utils/module_loading.py b/django/utils/module_loading.py index 9dcbc926b9ef..ed2b8da63515 100644 --- a/django/utils/module_loading.py +++ b/django/utils/module_loading.py @@ -2,6 +2,7 @@ import os import sys from importlib import import_module +from importlib.util import find_spec as importlib_find from django.utils import six @@ -63,88 +64,17 @@ def autodiscover_modules(*args, **kwargs): raise -if six.PY3: - from importlib.util import find_spec as importlib_find - - def module_has_submodule(package, module_name): - """See if 'module' is in 'package'.""" - try: - package_name = package.__name__ - package_path = package.__path__ - except AttributeError: - # package isn't a package. - return False - - full_module_name = package_name + '.' + module_name - return importlib_find(full_module_name, package_path) is not None - -else: - import imp - - def module_has_submodule(package, module_name): - """See if 'module' is in 'package'.""" - name = ".".join([package.__name__, module_name]) - try: - # None indicates a cached miss; see mark_miss() in Python/import.c. - return sys.modules[name] is not None - except KeyError: - pass - try: - package_path = package.__path__ # No __path__, then not a package. - except AttributeError: - # Since the remainder of this function assumes that we're dealing with - # a package (module with a __path__), so if it's not, then bail here. - return False - for finder in sys.meta_path: - if finder.find_module(name, package_path): - return True - for entry in package_path: - try: - # Try the cached finder. - finder = sys.path_importer_cache[entry] - if finder is None: - # Implicit import machinery should be used. - try: - file_, _, _ = imp.find_module(module_name, [entry]) - if file_: - file_.close() - return True - except ImportError: - continue - # Else see if the finder knows of a loader. - elif finder.find_module(name): - return True - else: - continue - except KeyError: - # No cached finder, so try and make one. - for hook in sys.path_hooks: - try: - finder = hook(entry) - # XXX Could cache in sys.path_importer_cache - if finder.find_module(name): - return True - else: - # Once a finder is found, stop the search. - break - except ImportError: - # Continue the search for a finder. - continue - else: - # No finder found. - # Try the implicit import machinery if searching a directory. - if os.path.isdir(entry): - try: - file_, _, _ = imp.find_module(module_name, [entry]) - if file_: - file_.close() - return True - except ImportError: - pass - # XXX Could insert None or NullImporter - else: - # Exhausted the search, so the module cannot be found. - return False +def module_has_submodule(package, module_name): + """See if 'module' is in 'package'.""" + try: + package_name = package.__name__ + package_path = package.__path__ + except AttributeError: + # package isn't a package. + return False + + full_module_name = package_name + '.' + module_name + return importlib_find(full_module_name, package_path) is not None def module_dir(module): diff --git a/django/utils/safestring.py b/django/utils/safestring.py index 4355a050a057..3f4b3d48fd86 100644 --- a/django/utils/safestring.py +++ b/django/utils/safestring.py @@ -83,12 +83,7 @@ def _proxy_method(self, *args, **kwargs): encode = curry(_proxy_method, method=six.text_type.encode) -if six.PY3: - SafeString = SafeText -else: - SafeString = SafeBytes - # backwards compatibility for Python 2 - SafeUnicode = SafeText +SafeString = SafeText def _safety_decorator(safety_marker, func): diff --git a/django/utils/text.py b/django/utils/text.py index dcedc524b097..fc8677cf4e6c 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -12,11 +12,6 @@ from django.utils.six.moves import html_entities from django.utils.translation import pgettext, ugettext as _, ugettext_lazy -if six.PY2: - # Import force_unicode even though this module doesn't use it, because some - # people rely on it being here. - from django.utils.encoding import force_unicode # NOQA - @keep_lazy_text def capfirst(x): diff --git a/django/utils/translation/template.py b/django/utils/translation/template.py index 04dac65e90e2..b6d8832f9c35 100644 --- a/django/utils/translation/template.py +++ b/django/utils/translation/template.py @@ -5,7 +5,6 @@ TOKEN_BLOCK, TOKEN_COMMENT, TOKEN_TEXT, TOKEN_VAR, TRANSLATOR_COMMENT_MARK, Lexer, ) -from django.utils import six from django.utils.encoding import force_text from django.utils.six import StringIO @@ -57,7 +56,7 @@ def templatize(src, origin=None, charset='utf-8'): comment_lineno_cache = None # Adding the u prefix allows gettext to recognize the Unicode string # (#26093). - raw_prefix = 'u' if six.PY3 else '' + raw_prefix = 'u' def join_tokens(tokens, trim=False): message = ''.join(tokens) diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py index 9f016e85249f..aca57ded0ebd 100644 --- a/django/utils/translation/trans_real.py +++ b/django/utils/translation/trans_real.py @@ -13,7 +13,7 @@ from django.core.exceptions import AppRegistryNotReady from django.core.signals import setting_changed from django.dispatch import receiver -from django.utils import lru_cache, six +from django.utils import lru_cache from django.utils._os import upath from django.utils.encoding import force_text from django.utils.safestring import SafeData, mark_safe @@ -336,11 +336,7 @@ def gettext(message): return do_translate(message, 'gettext') -if six.PY3: - ugettext = gettext -else: - def ugettext(message): - return do_translate(message, 'ugettext') +ugettext = gettext def pgettext(context, message): @@ -384,15 +380,7 @@ def ngettext(singular, plural, number): return do_ntranslate(singular, plural, number, 'ngettext') -if six.PY3: - ungettext = ngettext -else: - def ungettext(singular, plural, number): - """ - Returns a unicode strings of the translation of either the singular or - plural, based on the number. - """ - return do_ntranslate(singular, plural, number, 'ungettext') +ungettext = ngettext def npgettext(context, singular, plural, number): diff --git a/django/views/debug.py b/django/views/debug.py index 7c33aa8eca3a..2390995b5685 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -399,11 +399,9 @@ def explicit_or_implicit_cause(exc_value): if not exceptions: return frames - # In case there's just one exception (always in Python 2, - # sometimes in Python 3), take the traceback from self.tb (Python 2 - # doesn't have a __traceback__ attribute on Exception) + # In case there's just one exception, take the traceback from self.tb exc_value = exceptions.pop() - tb = self.tb if six.PY2 or not exceptions else exc_value.__traceback__ + tb = self.tb if not exceptions else exc_value.__traceback__ while tb is not None: # Support for __traceback_hide__ which is used by a few libraries @@ -438,9 +436,7 @@ def explicit_or_implicit_cause(exc_value): # If the traceback for current exception is consumed, try the # other exception. - if six.PY2: - tb = tb.tb_next - elif not tb.tb_next and exceptions: + if not tb.tb_next and exceptions: exc_value = exceptions.pop() tb = exc_value.__traceback__ else: diff --git a/setup.cfg b/setup.cfg index 9d336981dda5..c1ff45c56a9b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,7 +3,7 @@ doc_files = docs extras AUTHORS INSTALL LICENSE README.rst install-script = scripts/rpm-install.sh [flake8] -exclude = build,.git,.tox,./django/utils/lru_cache.py,./django/utils/six.py,./django/conf/app_template/*,./django/dispatch/weakref_backports.py,./tests/.env,./xmlrunner,tests/view_tests/tests/py3_test_debug.py,tests/template_tests/annotated_tag_function.py +exclude = build,.git,.tox,./django/utils/lru_cache.py,./django/utils/six.py,./django/conf/app_template/*,./tests/.env,./xmlrunner ignore = W601 max-line-length = 119 diff --git a/tests/admin_docs/test_views.py b/tests/admin_docs/test_views.py index 9f7f0ee268b5..34f6af6cdc07 100644 --- a/tests/admin_docs/test_views.py +++ b/tests/admin_docs/test_views.py @@ -10,7 +10,6 @@ from django.test import SimpleTestCase, modify_settings, override_settings from django.test.utils import captured_stderr from django.urls import reverse -from django.utils import six from .models import Company, Person from .tests import AdminDocsTestCase, TestDataMixin @@ -53,7 +52,6 @@ def test_view_index(self): self.assertContains(response, 'Views by namespace test') self.assertContains(response, 'Name: test:func.') - @unittest.skipIf(six.PY2, "Python 2 doesn't support __qualname__.") def test_view_index_with_method(self): """ Views that are methods are listed correctly. @@ -89,7 +87,7 @@ def test_view_detail_as_method(self): """ url = reverse('django-admindocs-views-detail', args=['django.contrib.admin.sites.AdminSite.index']) response = self.client.get(url) - self.assertEqual(response.status_code, 200 if six.PY3 else 404) + self.assertEqual(response.status_code, 200) def test_model_index(self): response = self.client.get(reverse('django-admindocs-models-index')) diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index 08fe64553527..e37e8a4256bd 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -27,7 +27,7 @@ ) from django.utils._os import npath, upath from django.utils.encoding import force_text -from django.utils.six import PY2, StringIO +from django.utils.six import StringIO custom_templates_dir = os.path.join(os.path.dirname(upath(__file__)), 'custom_templates') @@ -626,7 +626,6 @@ def test_setup_environ_custom_template(self): self.assertTrue(os.path.exists(app_path)) self.assertTrue(os.path.exists(os.path.join(app_path, 'api.py'))) - @unittest.skipIf(PY2, "Python 2 doesn't support Unicode package names.") def test_startapp_unicode_name(self): "directory: startapp creates the correct directory with unicode characters" args = ['startapp', 'こんにちは'] @@ -1897,18 +1896,11 @@ def test_invalid_project_name(self): self.addCleanup(shutil.rmtree, testproject_dir, True) out, err = self.run_django_admin(args) - if PY2: - self.assertOutput( - err, - "Error: '%s' is not a valid project name. Please make " - "sure the name begins with a letter or underscore." % bad_name - ) - else: - self.assertOutput( - err, - "Error: '%s' is not a valid project name. Please make " - "sure the name is a valid identifier." % bad_name - ) + self.assertOutput( + err, + "Error: '%s' is not a valid project name. Please make " + "sure the name is a valid identifier." % bad_name + ) self.assertFalse(os.path.exists(testproject_dir)) def test_simple_project_different_directory(self): diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py index bffac69e219d..65886b206311 100644 --- a/tests/annotations/tests.py +++ b/tests/annotations/tests.py @@ -8,7 +8,6 @@ ) from django.db.models.functions import Lower from django.test import TestCase, skipUnlessDBFeature -from django.utils import six from .models import ( Author, Book, Company, DepartmentStore, Employee, Publisher, Store, Ticket, @@ -24,7 +23,7 @@ def cxOracle_py3_bug(func): """ from unittest import expectedFailure from django.db import connection - return expectedFailure(func) if connection.vendor == 'oracle' and six.PY3 else func + return expectedFailure(func) if connection.vendor == 'oracle' else func class NonAggregateAnnotationTestCase(TestCase): diff --git a/tests/apps/tests.py b/tests/apps/tests.py index d2adc681f21b..9576420b5493 100644 --- a/tests/apps/tests.py +++ b/tests/apps/tests.py @@ -1,5 +1,4 @@ import os -from unittest import skipUnless from django.apps import AppConfig, apps from django.apps.registry import Apps @@ -8,7 +7,6 @@ from django.db import models from django.test import SimpleTestCase, override_settings from django.test.utils import extend_sys_path, isolate_apps -from django.utils import six from django.utils._os import upath from .default_config_app.apps import CustomConfig @@ -371,7 +369,6 @@ def test_duplicate_dunder_path_no_dunder_file(self): self.assertEqual(ac.path, 'a') -@skipUnless(six.PY3, "Namespace packages sans __init__.py were added in Python 3.3") class NamespacePackageAppTests(SimpleTestCase): # 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 diff --git a/tests/auth_tests/test_forms.py b/tests/auth_tests/test_forms.py index 36b4e8f4e729..c055b580424a 100644 --- a/tests/auth_tests/test_forms.py +++ b/tests/auth_tests/test_forms.py @@ -1,6 +1,5 @@ import datetime import re -from unittest import skipIf from django import forms from django.contrib.auth.forms import ( @@ -15,7 +14,7 @@ from django.core.mail import EmailMultiAlternatives from django.forms.fields import CharField, Field, IntegerField from django.test import SimpleTestCase, TestCase, mock, override_settings -from django.utils import six, translation +from django.utils import translation from django.utils.encoding import force_text from django.utils.text import capfirst from django.utils.translation import ugettext as _ @@ -114,14 +113,10 @@ def test_unicode_username(self): 'password2': 'test123', } form = UserCreationForm(data) - if six.PY3: - self.assertTrue(form.is_valid()) - u = form.save() - self.assertEqual(u.username, '宝') - else: - self.assertFalse(form.is_valid()) + self.assertTrue(form.is_valid()) + u = form.save() + self.assertEqual(u.username, '宝') - @skipIf(six.PY2, "Python 2 doesn't support unicode usernames by default.") def test_normalize_username(self): # The normalization happens in AbstractBaseUser.clean() and ModelForm # validation calls Model.clean(). @@ -137,7 +132,6 @@ def test_normalize_username(self): self.assertNotEqual(user.username, ohm_username) self.assertEqual(user.username, 'testΩ') # U+03A9 GREEK CAPITAL LETTER OMEGA - @skipIf(six.PY2, "Python 2 doesn't support unicode usernames by default.") def test_duplicate_normalized_unicode(self): """ To prevent almost identical usernames, visually identical but differing diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index eaceafb44455..ac57bbd511e0 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -32,9 +32,6 @@ def wrapped(*args): class mock_getpass: @staticmethod def getpass(prompt=b'Password: ', stream=None): - if six.PY2: - # getpass on Windows only supports prompt as bytestring (#19807) - assert isinstance(prompt, six.binary_type) if callable(inputs['password']): return inputs['password']() return inputs['password'] diff --git a/tests/auth_tests/test_tokens.py b/tests/auth_tests/test_tokens.py index 7ff3f15f3d80..0662ec513e38 100644 --- a/tests/auth_tests/test_tokens.py +++ b/tests/auth_tests/test_tokens.py @@ -1,11 +1,9 @@ -import unittest from datetime import date, timedelta from django.conf import settings from django.contrib.auth.models import User from django.contrib.auth.tokens import PasswordResetTokenGenerator from django.test import TestCase -from django.utils.six import PY3 class TokenGeneratorTest(TestCase): @@ -51,18 +49,6 @@ def _today(self): p2 = Mocked(date.today() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS + 1)) self.assertFalse(p2.check_token(user, tk1)) - @unittest.skipIf(PY3, "Unnecessary test with Python 3") - def test_date_length(self): - """ - Overly long dates, which are a potential DoS vector, aren't allowed. - """ - user = User.objects.create_user('ima1337h4x0r', 'test4@example.com', 'p4ssw0rd') - p0 = PasswordResetTokenGenerator() - - # This will put a 14-digit base36 timestamp into the token, which is too large. - with self.assertRaises(ValueError): - p0._make_token_with_timestamp(user, 175455491841851871349) - def test_check_token_with_nonexistent_token_and_user(self): user = User.objects.create_user('tokentestuser', 'test2@example.com', 'testpw') p0 = PasswordResetTokenGenerator() diff --git a/tests/backends/test_utils.py b/tests/backends/test_utils.py index 6f59d1b23b72..d158e2a5a280 100644 --- a/tests/backends/test_utils.py +++ b/tests/backends/test_utils.py @@ -1,7 +1,6 @@ from django.core.exceptions import ImproperlyConfigured from django.db.utils import load_backend from django.test import SimpleTestCase -from django.utils import six class TestLoadBackend(SimpleTestCase): @@ -10,7 +9,7 @@ def test_load_backend_invalid_name(self): "'foo' isn't an available database backend.\n" "Try using 'django.db.backends.XXX', where XXX is one of:\n" " 'mysql', 'oracle', 'postgresql', 'sqlite3'\n" - "Error was: No module named %s" - ) % "foo.base" if six.PY2 else "'foo'" + "Error was: No module named 'foo'" + ) with self.assertRaisesMessage(ImproperlyConfigured, msg): load_backend('foo') diff --git a/tests/base/models.py b/tests/base/models.py index 077b93fbb800..fb915227177a 100644 --- a/tests/base/models.py +++ b/tests/base/models.py @@ -13,12 +13,3 @@ class CustomBaseModel(models.base.ModelBase): class MyModel(six.with_metaclass(CustomBaseModel, models.Model)): """Model subclass with a custom base using six.with_metaclass.""" - - -# This is done to ensure that for Python2 only, defining metaclasses -# still does not fail to create the model. - -if six.PY2: - class MyPython2Model(models.Model): - """Model subclass with a custom base using __metaclass__.""" - __metaclass__ = CustomBaseModel diff --git a/tests/cache/tests.py b/tests/cache/tests.py index 5be3db0ef45f..caeb8a47dfc5 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -928,11 +928,7 @@ def my_callable(): self.assertEqual(cache.get_or_set('mykey', my_callable()), 'value') def test_get_or_set_version(self): - msg = ( - "get_or_set() missing 1 required positional argument: 'default'" - if six.PY3 - else 'get_or_set() takes at least 3 arguments' - ) + msg = "get_or_set() missing 1 required positional argument: 'default'" cache.get_or_set('brian', 1979, version=2) with self.assertRaisesMessage(TypeError, msg): cache.get_or_set('brian') diff --git a/tests/dbshell/test_postgresql_psycopg2.py b/tests/dbshell/test_postgresql_psycopg2.py index 4c4a1ae25e27..755464b3bbe7 100644 --- a/tests/dbshell/test_postgresql_psycopg2.py +++ b/tests/dbshell/test_postgresql_psycopg2.py @@ -3,7 +3,6 @@ from django.db.backends.postgresql.client import DatabaseClient from django.test import SimpleTestCase, mock -from django.utils import six from django.utils.encoding import force_bytes, force_str @@ -91,16 +90,12 @@ def test_accent(self): encoding = locale.getpreferredencoding() username = 'rôle' password = 'sésame' - try: - username_str = force_str(username, encoding) - password_str = force_str(password, encoding) - pgpass_bytes = force_bytes( - 'somehost:444:dbname:%s:%s' % (username, password), - encoding=encoding, - ) - except UnicodeEncodeError: - if six.PY2: - self.skipTest("Your locale can't run this test.") + username_str = force_str(username, encoding) + password_str = force_str(password, encoding) + pgpass_bytes = force_bytes( + 'somehost:444:dbname:%s:%s' % (username, password), + encoding=encoding, + ) self.assertEqual( self._run_it({ 'database': 'dbname', diff --git a/tests/file_uploads/tests.py b/tests/file_uploads/tests.py index 769c06c9044a..f9cecf96a20a 100644 --- a/tests/file_uploads/tests.py +++ b/tests/file_uploads/tests.py @@ -15,7 +15,7 @@ from django.test import SimpleTestCase, TestCase, client, override_settings from django.utils.encoding import force_bytes from django.utils.http import urlquote -from django.utils.six import PY2, StringIO +from django.utils.six import StringIO from . import uploadhandler from .models import FileModel @@ -102,9 +102,7 @@ def test_big_base64_upload(self): self._test_base64_upload("Big data" * 68000) # > 512Kb def test_big_base64_newlines_upload(self): - self._test_base64_upload( - # encodestring is a deprecated alias on Python 3 - "Big data" * 68000, encode=base64.encodestring if PY2 else base64.encodebytes) + self._test_base64_upload("Big data" * 68000, encode=base64.encodebytes) def test_unicode_file_name(self): tdir = sys_tempfile.mkdtemp() diff --git a/tests/files/tests.py b/tests/files/tests.py index 276cbed54483..a0ff3d4782f8 100644 --- a/tests/files/tests.py +++ b/tests/files/tests.py @@ -181,10 +181,7 @@ def test_content_file_input_type(self): retrieved content is of the same type. """ self.assertIsInstance(ContentFile(b"content").read(), bytes) - if six.PY3: - self.assertIsInstance(ContentFile("español").read(), six.text_type) - else: - self.assertIsInstance(ContentFile("español").read(), bytes) + self.assertIsInstance(ContentFile("español").read(), six.text_type) class DimensionClosingBug(unittest.TestCase): diff --git a/tests/fixtures_regress/tests.py b/tests/fixtures_regress/tests.py index 3667fcbd4c69..7ea9e6cc3ebd 100644 --- a/tests/fixtures_regress/tests.py +++ b/tests/fixtures_regress/tests.py @@ -2,10 +2,8 @@ import json import os import re -import unittest import warnings -import django from django.core import management, serializers from django.core.exceptions import ImproperlyConfigured from django.core.serializers.base import DeserializationError @@ -15,9 +13,8 @@ TestCase, TransactionTestCase, override_settings, skipIfDBFeature, skipUnlessDBFeature, ) -from django.utils import six from django.utils._os import upath -from django.utils.six import PY3, StringIO +from django.utils.six import StringIO from .models import ( Absolute, Animal, Article, Book, Child, Circle1, Circle2, Circle3, @@ -32,16 +29,6 @@ _cur_dir = os.path.dirname(os.path.abspath(upath(__file__))) -def is_ascii(s): - return all(ord(c) < 128 for c in s) - - -skipIfNonASCIIPath = unittest.skipIf( - not is_ascii(django.__file__) and six.PY2, - 'Python 2 crashes when checking non-ASCII exception messages.' -) - - class TestFixtures(TestCase): def animal_pre_save_check(self, signal, sender, instance, **kwargs): @@ -205,7 +192,6 @@ def test_unknown_format(self): verbosity=0, ) - @skipIfNonASCIIPath @override_settings(SERIALIZATION_MODULES={'unkn': 'unexistent.path'}) def test_unimportable_serializer(self): """ @@ -350,8 +336,8 @@ def test_field_value_coerce(self): self.assertEqual( self.pre_save_checks, [ - ("Count = 42 (<%s 'int'>)" % ('class' if PY3 else 'type'), - "Weight = 1.2 (<%s 'float'>)" % ('class' if PY3 else 'type')) + ("Count = 42 ()", + "Weight = 1.2 ()") ] ) finally: @@ -531,7 +517,6 @@ def test_fixture_dirs_with_duplicates(self): with self.assertRaisesMessage(ImproperlyConfigured, "settings.FIXTURE_DIRS contains duplicates."): management.call_command('loaddata', 'absolute.json', verbosity=0) - @skipIfNonASCIIPath @override_settings(FIXTURE_DIRS=[os.path.join(_cur_dir, 'fixtures')]) def test_fixture_dirs_with_default_fixture_path(self): """ diff --git a/tests/handlers/tests.py b/tests/handlers/tests.py index bae20439189c..72ba98b1d3b5 100644 --- a/tests/handlers/tests.py +++ b/tests/handlers/tests.py @@ -34,7 +34,7 @@ def test_bad_path_info(self): produces a 404. """ environ = RequestFactory().get('/').environ - environ['PATH_INFO'] = b'\xed' if six.PY2 else '\xed' + environ['PATH_INFO'] = '\xed' handler = WSGIHandler() response = handler(environ, lambda *a, **k: None) # The path of the request will be encoded to '/%ED'. @@ -53,25 +53,17 @@ def test_non_ascii_query_string(self): ] got = [] for raw_query_string in raw_query_strings: - if six.PY3: - # Simulate http.server.BaseHTTPRequestHandler.parse_request handling of raw request - environ['QUERY_STRING'] = str(raw_query_string, 'iso-8859-1') - else: - environ['QUERY_STRING'] = raw_query_string + # Simulate http.server.BaseHTTPRequestHandler.parse_request handling of raw request + environ['QUERY_STRING'] = str(raw_query_string, 'iso-8859-1') request = WSGIRequest(environ) got.append(request.GET['want']) - if six.PY2: - self.assertListEqual(got, ['café', 'café', 'café', 'café']) - else: - # On Python 3, %E9 is converted to the unicode replacement character by parse_qsl - self.assertListEqual(got, ['café', 'café', 'caf\ufffd', 'café']) + # %E9 is converted to the unicode replacement character by parse_qsl + self.assertListEqual(got, ['café', 'café', 'caf\ufffd', 'café']) def test_non_ascii_cookie(self): """Non-ASCII cookies set in JavaScript are properly decoded (#20557).""" environ = RequestFactory().get('/').environ - raw_cookie = 'want="café"' - if six.PY3: - raw_cookie = raw_cookie.encode('utf-8').decode('iso-8859-1') + raw_cookie = 'want="café"'.encode('utf-8').decode('iso-8859-1') environ['HTTP_COOKIE'] = raw_cookie request = WSGIRequest(environ) # If would be nicer if request.COOKIES returned unicode values. diff --git a/tests/httpwrappers/tests.py b/tests/httpwrappers/tests.py index d9885ea40ccd..9042f8ed6e8d 100644 --- a/tests/httpwrappers/tests.py +++ b/tests/httpwrappers/tests.py @@ -55,8 +55,6 @@ def test_immutable_get_with_default(self): def test_immutable_basic_operations(self): q = QueryDict() self.assertEqual(q.getlist('foo'), []) - if six.PY2: - self.assertIs(q.has_key('foo'), False) self.assertNotIn('foo', q) self.assertEqual(list(six.iteritems(q)), []) self.assertEqual(list(six.iterlists(q)), []) @@ -85,11 +83,7 @@ def test_single_key_value(self): with self.assertRaises(AttributeError): q.appendlist('foo', ['bar']) - if six.PY2: - self.assertTrue(q.has_key('foo')) self.assertIn('foo', q) - if six.PY2: - self.assertFalse(q.has_key('bar')) self.assertNotIn('bar', q) self.assertEqual(list(six.iteritems(q)), [('foo', 'bar')]) @@ -150,8 +144,6 @@ def test_basic_mutable_operations(self): q.appendlist('foo', 'another') self.assertEqual(q.getlist('foo'), ['bar', 'baz', 'another']) self.assertEqual(q['foo'], 'another') - if six.PY2: - self.assertTrue(q.has_key('foo')) self.assertIn('foo', q) self.assertListEqual(sorted(six.iteritems(q)), @@ -199,11 +191,7 @@ def test_multiple_keys(self): with self.assertRaises(AttributeError): q.appendlist('foo', ['bar']) - if six.PY2: - self.assertIs(q.has_key('vote'), True) self.assertIn('vote', q) - if six.PY2: - self.assertIs(q.has_key('foo'), False) self.assertNotIn('foo', q) self.assertEqual(list(six.iteritems(q)), [('vote', 'no')]) self.assertEqual(list(six.iterlists(q)), [('vote', ['yes', 'no'])]) @@ -224,19 +212,6 @@ def test_multiple_keys(self): with self.assertRaises(AttributeError): q.__delitem__('vote') - if six.PY2: - def test_invalid_input_encoding(self): - """ - QueryDicts must be able to handle invalid input encoding (in this - case, bad UTF-8 encoding), falling back to ISO-8859-1 decoding. - - This test doesn't apply under Python 3 because the URL is a string - and not a bytestring. - """ - q = QueryDict(str(b'foo=bar&foo=\xff')) - self.assertEqual(q['foo'], '\xff') - self.assertEqual(q.getlist('foo'), ['bar', '\xff']) - def test_pickle(self): q = QueryDict() q1 = pickle.loads(pickle.dumps(q, 2)) @@ -807,15 +782,6 @@ def test_load_dict(self): c.load({'name': 'val'}) self.assertEqual(c['name'].value, 'val') - @unittest.skipUnless(six.PY2, "PY3 throws an exception on invalid cookie keys.") - def test_bad_cookie(self): - """ - Regression test for #18403 - """ - r = HttpResponse() - r.set_cookie("a:.b/", 1) - self.assertEqual(len(r.cookies.bad_cookies), 1) - def test_pickle(self): rawdata = 'Customer="WILE_E_COYOTE"; Path=/acme; Version=1' expected_output = 'Set-Cookie: %s' % rawdata diff --git a/tests/i18n/test_compilation.py b/tests/i18n/test_compilation.py index d17078e29011..3f3bf773bff3 100644 --- a/tests/i18n/test_compilation.py +++ b/tests/i18n/test_compilation.py @@ -12,7 +12,7 @@ from django.core.management.utils import find_command from django.test import SimpleTestCase, mock, override_settings from django.test.utils import captured_stderr, captured_stdout -from django.utils import six, translation +from django.utils import translation from django.utils.encoding import force_text from django.utils.six import StringIO from django.utils.translation import ugettext @@ -144,18 +144,11 @@ def test_msgfmt_error_including_non_ascii(self): env = os.environ.copy() env.update({str('LANG'): str('C')}) with mock.patch('django.core.management.utils.Popen', lambda *args, **kwargs: Popen(*args, env=env, **kwargs)): - if six.PY2: - # Various assertRaises on PY2 don't support unicode error messages. - try: - call_command('compilemessages', locale=['ko'], verbosity=0) - except CommandError as err: - self.assertIn("' cannot start a field name", six.text_type(err)) - else: - cmd = MakeMessagesCommand() - if cmd.gettext_version < (0, 18, 3): - self.skipTest("python-brace-format is a recent gettext addition.") - with self.assertRaisesMessage(CommandError, "' cannot start a field name"): - call_command('compilemessages', locale=['ko'], verbosity=0) + cmd = MakeMessagesCommand() + if cmd.gettext_version < (0, 18, 3): + self.skipTest("python-brace-format is a recent gettext addition.") + with self.assertRaisesMessage(CommandError, "' cannot start a field name"): + call_command('compilemessages', locale=['ko'], verbosity=0) class ProjectAndAppTests(MessageCompilationTests): diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py index 2b9793109b43..d039d016cec7 100644 --- a/tests/i18n/tests.py +++ b/tests/i18n/tests.py @@ -6,7 +6,6 @@ from contextlib import contextmanager from importlib import import_module from threading import local -from unittest import skipUnless from django import forms from django.conf import settings @@ -23,13 +22,11 @@ ) from django.utils.numberformat import format as nformat from django.utils.safestring import SafeBytes, SafeText -from django.utils.six import PY3 from django.utils.translation import ( LANGUAGE_SESSION_KEY, activate, check_for_language, deactivate, - get_language, get_language_from_request, get_language_info, gettext, - gettext_lazy, ngettext_lazy, npgettext, npgettext_lazy, pgettext, - pgettext_lazy, trans_real, ugettext, ugettext_lazy, ungettext, - ungettext_lazy, + get_language, get_language_from_request, get_language_info, gettext_lazy, + ngettext_lazy, npgettext, npgettext_lazy, pgettext, trans_real, ugettext, + ugettext_lazy, ungettext, ungettext_lazy, ) from .forms import CompanyForm, I18nForm, SelectDateForm @@ -141,33 +138,6 @@ def test_lazy_objects(self): s4 = ugettext_lazy('Some other string') self.assertNotEqual(s, s4) - @skipUnless(six.PY2, "No more bytestring translations on PY3") - def test_bytestrings(self): - """gettext() returns a bytestring if input is bytestring.""" - - # Using repr() to check translated text and type - self.assertEqual(repr(gettext(b"Time")), repr(b"Time")) - self.assertEqual(repr(gettext("Time")), repr("Time")) - - with translation.override('de', deactivate=True): - self.assertEqual(repr(gettext(b"Time")), repr(b"Zeit")) - self.assertEqual(repr(gettext("Time")), repr(b"Zeit")) - - @skipUnless(six.PY2, "No more bytestring translations on PY3") - def test_lazy_and_bytestrings(self): - # On Python 2, (n)gettext_lazy should not transform a bytestring to unicode - self.assertEqual(gettext_lazy(b"test").upper(), b"TEST") - self.assertEqual((ngettext_lazy(b"%d test", b"%d tests") % 1).upper(), b"1 TEST") - - # Other versions of lazy functions always return unicode - self.assertEqual(ugettext_lazy(b"test").upper(), "TEST") - self.assertEqual((ungettext_lazy(b"%d test", b"%d tests") % 1).upper(), "1 TEST") - self.assertEqual(pgettext_lazy(b"context", b"test").upper(), "TEST") - self.assertEqual( - (npgettext_lazy(b"context", b"%d test", b"%d tests") % 1).upper(), - "1 TEST" - ) - def test_lazy_pickle(self): s1 = ugettext_lazy("test") self.assertEqual(six.text_type(s1), "test") @@ -223,20 +193,6 @@ def test_ungettext_lazy(self): with self.assertRaisesMessage(KeyError, 'Your dictionary lacks key'): complex_context_deferred % {'name': 'Jim'} - @skipUnless(six.PY2, "PY3 doesn't have distinct int and long types") - def test_ungettext_lazy_long(self): - """ - Regression test for #22820: int and long should be treated alike in ungettext_lazy. - """ - result = ungettext_lazy('%(name)s has %(num)d good result', '%(name)s has %(num)d good results', 4) - self.assertEqual(result % {'name': 'Joe', 'num': 4}, "Joe has 4 good results") - # Now with a long - result = ungettext_lazy( - '%(name)s has %(num)d good result', '%(name)s has %(num)d good results', - long(4) # NOQA: long undefined on PY3 - ) - self.assertEqual(result % {'name': 'Joe', 'num': 4}, "Joe has 4 good results") - def test_ungettext_lazy_bool(self): self.assertTrue(ungettext_lazy('%d good result', '%d good results')) self.assertFalse(ungettext_lazy('', '')) @@ -298,7 +254,7 @@ def setUp(self): self.d = datetime.date(2009, 12, 31) self.dt = datetime.datetime(2009, 12, 31, 20, 50) self.t = datetime.time(10, 15, 48) - self.long = 10000 if PY3 else long(10000) # NOQA: long undefined on PY3 + self.long = 10000 self.ctxt = Context({ 'n': self.n, 't': self.t, diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py index 1293ff68acda..8f17735929da 100644 --- a/tests/inspectdb/tests.py +++ b/tests/inspectdb/tests.py @@ -5,7 +5,7 @@ from django.db import connection from django.test import TestCase, mock, skipUnlessDBFeature from django.utils.encoding import force_text -from django.utils.six import PY3, StringIO +from django.utils.six import StringIO from .models import ColumnTypes @@ -196,11 +196,7 @@ def test_special_column_name_introspection(self): self.assertIn("field_field_0 = models.IntegerField(db_column='%s__')" % base_name, output) self.assertIn("field_field_1 = models.IntegerField(db_column='__field')", output) self.assertIn("prc_x = models.IntegerField(db_column='prc(%) x')", output) - if PY3: - # Python 3 allows non-ASCII identifiers - self.assertIn("tamaño = models.IntegerField()", output) - else: - self.assertIn("tama_o = models.IntegerField(db_column='tama\\xf1o')", output) + self.assertIn("tamaño = models.IntegerField()", output) def test_table_name_introspection(self): """ diff --git a/tests/invalid_models_tests/test_relative_fields.py b/tests/invalid_models_tests/test_relative_fields.py index 5fd76229e916..384d1fa03e92 100644 --- a/tests/invalid_models_tests/test_relative_fields.py +++ b/tests/invalid_models_tests/test_relative_fields.py @@ -3,7 +3,6 @@ from django.db.models.fields.related import ForeignObject from django.test.testcases import SimpleTestCase, skipIfDBFeature from django.test.utils import isolate_apps, override_settings -from django.utils import six @isolate_apps('invalid_models_tests') @@ -655,10 +654,8 @@ def test_related_field_has_invalid_related_name(self): 'with', # a Python keyword 'related_name\n', '', + ',', # non-ASCII ] - # Python 2 crashes on non-ASCII strings. - if six.PY3: - invalid_related_names.append(',') class Parent(models.Model): pass @@ -695,10 +692,9 @@ def test_related_field_has_valid_related_name(self): 'ends_with_plus+', '_+', '+', + '試', + '試驗+', ] - # Python 2 crashes on non-ASCII strings. - if six.PY3: - related_names.extend(['試', '試驗+']) class Parent(models.Model): pass diff --git a/tests/mail/tests.py b/tests/mail/tests.py index ba7ff44714ef..cfe2889aa66b 100644 --- a/tests/mail/tests.py +++ b/tests/mail/tests.py @@ -8,8 +8,10 @@ import sys import tempfile import threading +from email import message_from_binary_file, message_from_bytes from email.header import Header from email.mime.text import MIMEText +from email.utils import parseaddr from smtplib import SMTP, SMTPAuthenticationError, SMTPException from ssl import SSLError @@ -24,19 +26,9 @@ from django.test.utils import requires_tz_support from django.utils._os import upath from django.utils.encoding import force_bytes, force_text -from django.utils.six import PY3, StringIO, binary_type +from django.utils.six import StringIO, binary_type from django.utils.translation import ugettext_lazy -if PY3: - from email.utils import parseaddr - from email import message_from_bytes, message_from_binary_file -else: - from email.Utils import parseaddr - from email import ( - message_from_string as message_from_bytes, - message_from_file as message_from_binary_file, - ) - class HeadersCheckMixin(object): @@ -656,16 +648,10 @@ def test_sanitize_address(self): sanitize_address(('A name', 'to@example.com'), 'ascii'), 'A name ' ) - if PY3: - self.assertEqual( - sanitize_address(('A name', 'to@example.com'), 'utf-8'), - '=?utf-8?q?A_name?= ' - ) - else: - self.assertEqual( - sanitize_address(('A name', 'to@example.com'), 'utf-8'), - 'A name ' - ) + self.assertEqual( + sanitize_address(('A name', 'to@example.com'), 'utf-8'), + '=?utf-8?q?A_name?= ' + ) # Unicode characters are are supported in RFC-6532. self.assertEqual( @@ -1165,18 +1151,8 @@ def __init__(self, *args, **kwargs): self.active_lock = threading.Lock() self.sink_lock = threading.Lock() - if not PY3: - def handle_accept(self): - # copy of Python 2.7 smtpd.SMTPServer.handle_accept with hardcoded - # SMTPChannel replaced by self.channel_class - pair = self.accept() - if pair is not None: - conn, addr = pair - self.channel_class(self, conn, addr) - def process_message(self, peer, mailfrom, rcpttos, data): - if PY3: - data = data.encode('utf-8') + data = data.encode('utf-8') m = message_from_bytes(data) maddr = parseaddr(m.get('from'))[1] @@ -1448,8 +1424,7 @@ def mock_send(self, s): self.assertTrue(msg) - if PY3: - msg = msg.decode('utf-8') + msg = msg.decode('utf-8') # The message only contains CRLF and not combinations of CRLF, LF, and CR. msg = msg.replace('\r\n', '') self.assertNotIn('\r', msg) diff --git a/tests/middleware/tests.py b/tests/middleware/tests.py index 43ea0748a0de..3c0d3d81ea73 100644 --- a/tests/middleware/tests.py +++ b/tests/middleware/tests.py @@ -2,7 +2,6 @@ import random import re from io import BytesIO -from unittest import skipIf from django.conf import settings from django.core import mail @@ -401,24 +400,6 @@ def test_404_error_reporting_ignored_url(self): BrokenLinkEmailsMiddleware().process_response(self.req, self.resp) self.assertEqual(len(mail.outbox), 0) - @skipIf(six.PY3, "HTTP_REFERER is str type on Python 3") - def test_404_error_nonascii_referrer(self): - # Such referer strings should not happen, but anyway, if it happens, - # let's not crash - self.req.META['HTTP_REFERER'] = b'http://testserver/c/\xd0\xbb\xd0\xb8/' - BrokenLinkEmailsMiddleware().process_response(self.req, self.resp) - self.assertEqual(len(mail.outbox), 1) - - @skipIf(six.PY3, "HTTP_USER_AGENT is str type on Python 3") - def test_404_error_nonascii_user_agent(self): - # Such user agent strings should not happen, but anyway, if it happens, - # let's not crash - self.req.META['HTTP_REFERER'] = '/another/url/' - self.req.META['HTTP_USER_AGENT'] = b'\xd0\xbb\xd0\xb8\xff\xff' - BrokenLinkEmailsMiddleware().process_response(self.req, self.resp) - self.assertEqual(len(mail.outbox), 1) - self.assertIn('User agent: \u043b\u0438\ufffd\ufffd\n', mail.outbox[0].body) - def test_custom_request_checker(self): class SubclassedMiddleware(BrokenLinkEmailsMiddleware): ignored_user_agent_patterns = (re.compile(r'Spider.*'), re.compile(r'Robot.*')) diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index ab2e47fabdf8..ca6b42044ff2 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -661,18 +661,10 @@ def test_files_content(self): self.assertIn('migrations.CreateModel', content) self.assertIn('initial = True', content) - if six.PY3: - self.assertIn('úñí©óðé µóðéø', content) # Meta.verbose_name - self.assertIn('úñí©óðé µóðéøß', content) # Meta.verbose_name_plural - self.assertIn('ÚÑÍ¢ÓÐÉ', content) # title.verbose_name - self.assertIn('“Ðjáñgó”', content) # title.default - else: - # Meta.verbose_name - self.assertIn('\\xfa\\xf1\\xed\\xa9\\xf3\\xf0\\xe9 \\xb5\\xf3\\xf0\\xe9\\xf8', content) - # Meta.verbose_name_plural - self.assertIn('\\xfa\\xf1\\xed\\xa9\\xf3\\xf0\\xe9 \\xb5\\xf3\\xf0\\xe9\\xf8\\xdf', content) - self.assertIn('\\xda\\xd1\\xcd\\xa2\\xd3\\xd0\\xc9', content) # title.verbose_name - self.assertIn('\\u201c\\xd0j\\xe1\\xf1g\\xf3\\u201d', content) # title.default + self.assertIn('úñí©óðé µóðéø', content) # Meta.verbose_name + self.assertIn('úñí©óðé µóðéøß', content) # Meta.verbose_name_plural + self.assertIn('ÚÑÍ¢ÓÐÉ', content) # title.verbose_name + self.assertIn('“Ðjáñgó”', content) # title.default def test_makemigrations_order(self): """ diff --git a/tests/migrations/test_loader.py b/tests/migrations/test_loader.py index 6c91a504301d..b06ff8f89c6e 100644 --- a/tests/migrations/test_loader.py +++ b/tests/migrations/test_loader.py @@ -1,5 +1,3 @@ -from unittest import skipIf - from django.db import connection, connections from django.db.migrations.exceptions import ( AmbiguityError, InconsistentMigrationHistory, NodeNotFoundError, @@ -7,7 +5,6 @@ from django.db.migrations.loader import MigrationLoader from django.db.migrations.recorder import MigrationRecorder from django.test import TestCase, modify_settings, override_settings -from django.utils import six class RecorderTests(TestCase): @@ -170,7 +167,6 @@ def test_load_module_file(self): "App with migrations module file not in unmigrated apps." ) - @skipIf(six.PY2, "PY2 doesn't load empty dirs.") def test_load_empty_dir(self): with override_settings(MIGRATION_MODULES={"migrations": "migrations.faulty_migrations.namespace"}): loader = MigrationLoader(connection) diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index c03d8cfd38cd..b92675792084 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -47,12 +47,6 @@ def deconstruct(self): ) -class TestModel1(object): - def upload_to(self): - return "somewhere dynamic" - thing = models.FileField(upload_to=upload_to) - - class OperationWriterTests(SimpleTestCase): def test_empty_signature(self): @@ -486,15 +480,6 @@ def test_serialize_builtins(self): self.assertEqual(string, 'range') self.assertEqual(imports, set()) - @unittest.skipUnless(six.PY2, "Only applies on Python 2") - def test_serialize_direct_function_reference(self): - """ - Ticket #22436: You cannot use a function straight from its body - (e.g. define the method and use it in the same body) - """ - with self.assertRaises(ValueError): - self.serialize_round_trip(TestModel1.thing) - def test_serialize_local_function_reference(self): """ Neither py2 or py3 can serialize a reference in a local scope. diff --git a/tests/model_fields/test_promises.py b/tests/model_fields/test_promises.py index bf5258cddf38..0dcb1abf3b30 100644 --- a/tests/model_fields/test_promises.py +++ b/tests/model_fields/test_promises.py @@ -1,13 +1,12 @@ import datetime -import unittest from decimal import Decimal from django.db.models.fields import ( - AutoField, BigIntegerField, BinaryField, BooleanField, CharField, - DateField, DateTimeField, DecimalField, EmailField, FilePathField, - FloatField, GenericIPAddressField, IntegerField, IPAddressField, - NullBooleanField, PositiveIntegerField, PositiveSmallIntegerField, - SlugField, SmallIntegerField, TextField, TimeField, URLField, + AutoField, BinaryField, BooleanField, CharField, DateField, DateTimeField, + DecimalField, EmailField, FilePathField, FloatField, GenericIPAddressField, + IntegerField, IPAddressField, NullBooleanField, PositiveIntegerField, + PositiveSmallIntegerField, SlugField, SmallIntegerField, TextField, + TimeField, URLField, ) from django.db.models.fields.files import FileField, ImageField from django.test import SimpleTestCase @@ -21,11 +20,6 @@ def test_AutoField(self): lazy_func = lazy(lambda: 1, int) self.assertIsInstance(AutoField(primary_key=True).get_prep_value(lazy_func()), int) - @unittest.skipIf(six.PY3, 'Python 3 has no `long` type.') - def test_BigIntegerField(self): - lazy_func = lazy(lambda: long(9999999999999999999), long) # NOQA: long undefined on PY3 - self.assertIsInstance(BigIntegerField().get_prep_value(lazy_func()), long) # NOQA - def test_BinaryField(self): lazy_func = lazy(lambda: b'', bytes) self.assertIsInstance(BinaryField().get_prep_value(lazy_func()), bytes) diff --git a/tests/project_template/test_settings.py b/tests/project_template/test_settings.py index a0047dd836dc..5623df320b5c 100644 --- a/tests/project_template/test_settings.py +++ b/tests/project_template/test_settings.py @@ -1,18 +1,11 @@ import os import shutil -import unittest from django import conf from django.test import TestCase -from django.utils import six from django.utils._os import upath -@unittest.skipIf( - six.PY2, - 'Python 2 cannot import the project template because ' - 'django/conf/project_template doesn\'t have an __init__.py file.' -) class TestStartProjectSettings(TestCase): def setUp(self): # Ensure settings.py exists diff --git a/tests/queries/tests.py b/tests/queries/tests.py index e2dd86bac185..ed323be1542f 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -11,7 +11,6 @@ from django.db.models.sql.where import NothingNode, WhereNode from django.test import TestCase, skipUnlessDBFeature from django.test.utils import CaptureQueriesContext -from django.utils import six from django.utils.six.moves import range from .models import ( @@ -406,7 +405,7 @@ def test_avoid_infinite_loop_on_too_many_subqueries(self): local_recursion_limit = 127 msg = 'Maximum recursion depth exceeded: too many subqueries.' with self.assertRaisesMessage(RuntimeError, msg): - for i in six.moves.range(local_recursion_limit * 2): + for i in range(local_recursion_limit * 2): x = Tag.objects.filter(pk__in=x) def test_reasonable_number_of_subq_aliases(self): @@ -2249,25 +2248,6 @@ def test_slicing_with_steps_can_be_used(self): ] ) - @unittest.skipUnless(six.PY2, "Python 2 only -- Python 3 doesn't have longs.") - def test_slicing_works_with_longs(self): - # NOQA: long undefined on PY3 - self.assertEqual(self.get_ordered_articles()[long(0)].name, 'Article 1') # NOQA - self.assertQuerysetEqual(self.get_ordered_articles()[long(1):long(3)], # NOQA - ["", ""]) - self.assertQuerysetEqual( - self.get_ordered_articles()[::long(2)], [ # NOQA - "", - "", - "", - "" - ] - ) - - # And can be mixed with ints. - self.assertQuerysetEqual(self.get_ordered_articles()[1:long(3)], # NOQA - ["", ""]) - def test_slicing_without_step_is_lazy(self): with self.assertNumQueries(0): self.get_ordered_articles()[0:5] @@ -2965,8 +2945,6 @@ def test_invalid_qs_list(self): def test_invalid_order_by(self): msg = "Invalid order_by arguments: ['*']" - if six.PY2: - msg = msg.replace("[", "[u") with self.assertRaisesMessage(FieldError, msg): list(Article.objects.order_by('*')) diff --git a/tests/queryset_pickle/models.py b/tests/queryset_pickle/models.py index 5e60963272ad..4faad0175b06 100644 --- a/tests/queryset_pickle/models.py +++ b/tests/queryset_pickle/models.py @@ -1,7 +1,6 @@ import datetime from django.db import DJANGO_VERSION_PICKLE_KEY, models -from django.utils import six from django.utils.translation import ugettext_lazy as _ @@ -45,9 +44,7 @@ class Happening(models.Model): when = models.DateTimeField(blank=True, default=datetime.datetime.now) name = models.CharField(blank=True, max_length=100, default="test") number1 = models.IntegerField(blank=True, default=standalone_number) - if six.PY3: - # default serializable on Python 3 only - number2 = models.IntegerField(blank=True, default=Numbers.get_static_number) + number2 = models.IntegerField(blank=True, default=Numbers.get_static_number) class Container(object): diff --git a/tests/queryset_pickle/tests.py b/tests/queryset_pickle/tests.py index 9333e96fc300..ac5174051ffd 100644 --- a/tests/queryset_pickle/tests.py +++ b/tests/queryset_pickle/tests.py @@ -1,10 +1,8 @@ import datetime import pickle -import unittest from django.db import models from django.test import TestCase -from django.utils import six from django.utils.version import get_version from .models import Container, Event, Group, Happening, M2MModel @@ -33,7 +31,6 @@ def test_string_as_default(self): def test_standalone_method_as_default(self): self.assert_pickles(Happening.objects.filter(number1=1)) - @unittest.skipIf(six.PY2, "Field doesn't exist on Python 2.") def test_staticmethod_as_default(self): self.assert_pickles(Happening.objects.filter(number2=1)) diff --git a/tests/requests/tests.py b/tests/requests/tests.py index c5a148ffbb12..09b08540f4d9 100644 --- a/tests/requests/tests.py +++ b/tests/requests/tests.py @@ -12,7 +12,6 @@ from django.test import RequestFactory, SimpleTestCase, override_settings from django.test.client import FakePayload from django.test.utils import freeze_time, str_prefix -from django.utils import six from django.utils.encoding import force_str from django.utils.http import cookie_date, urlencode from django.utils.six.moves import http_cookies @@ -168,9 +167,8 @@ def test_wsgirequest_repr(self): def test_wsgirequest_path_info(self): def wsgi_str(path_info, encoding='utf-8'): - path_info = path_info.encode(encoding) # Actual URL sent by the browser (bytestring) - if six.PY3: - path_info = path_info.decode('iso-8859-1') # Value in the WSGI environ dict (native string) + path_info = path_info.encode(encoding) # Actual URL sent by the browser (bytestring) + path_info = path_info.decode('iso-8859-1') # Value in the WSGI environ dict (native string) return path_info # Regression for #19468 request = WSGIRequest({'PATH_INFO': wsgi_str("/سلام/"), 'REQUEST_METHOD': 'get', 'wsgi.input': BytesIO(b'')}) @@ -583,7 +581,7 @@ def test_set_encoding_clears_GET(self): request = WSGIRequest({ 'REQUEST_METHOD': 'GET', 'wsgi.input': '', - 'QUERY_STRING': b'name=Hello%20G%C3%BCnter' if six.PY2 else 'name=Hello%20G%C3%BCnter' + 'QUERY_STRING': 'name=Hello%20G%C3%BCnter', }) self.assertEqual(request.GET, {'name': ['Hello Günter']}) request.encoding = 'iso-8859-16' diff --git a/tests/signing/tests.py b/tests/signing/tests.py index c6145d09cb37..bc838d015f1e 100644 --- a/tests/signing/tests.py +++ b/tests/signing/tests.py @@ -3,7 +3,6 @@ from django.core import signing from django.test import SimpleTestCase from django.test.utils import freeze_time -from django.utils import six from django.utils.encoding import force_str @@ -45,8 +44,6 @@ def test_sign_unsign(self): 'jkw osanteuh ,rcuh nthu aou oauh ,ud du', '\u2019', ] - if six.PY2: - examples.append(b'a byte string') for example in examples: signed = signer.sign(example) self.assertIsInstance(signed, str) @@ -76,8 +73,6 @@ def test_dumps_loads(self): 'a unicode string \u2019', {'a': 'dictionary'}, ] - if six.PY2: - objects.append(b'a byte string') for o in objects: self.assertNotEqual(o, signing.dumps(o)) self.assertEqual(o, signing.loads(signing.dumps(o))) diff --git a/tests/staticfiles_tests/test_management.py b/tests/staticfiles_tests/test_management.py index ad608ea24b94..e8c00eb3f5ee 100644 --- a/tests/staticfiles_tests/test_management.py +++ b/tests/staticfiles_tests/test_management.py @@ -183,8 +183,7 @@ class TestInteractiveMessages(CollectionTestCase): @staticmethod def mock_input(stdout): def _input(msg): - # Python 2 reads bytes from the console output, use bytes for the StringIO - stdout.write(msg.encode('utf-8') if six.PY2 else msg) + stdout.write(msg) return 'yes' return _input diff --git a/tests/str/models.py b/tests/str/models.py index 12f024757035..d2f7a45c2045 100644 --- a/tests/str/models.py +++ b/tests/str/models.py @@ -1,31 +1,16 @@ """ -Adding __str__() or __unicode__() to models +Adding __str__() to models -Although it's not a strict requirement, each model should have a -``_str__()`` or ``__unicode__()`` method to return a "human-readable" -representation of the object. Do this not only for your own sanity when dealing -with the interactive prompt, but also because objects' representations are used -throughout Django's automatically-generated admin. - -Normally, you should write ``__unicode__()`` method, since this will work for -all field types (and Django will automatically provide an appropriate -``__str__()`` method). However, you can write a ``__str__()`` method directly, -if you prefer. You must be careful to encode the results correctly, though. +Although it's not a strict requirement, each model should have a ``_str__()`` +method to return a "human-readable" representation of the object. Do this not +only for your own sanity when dealing with the interactive prompt, but also +because objects' representations are used throughout Django's +automatically-generated admin. """ from django.db import models -class Article(models.Model): - headline = models.CharField(max_length=100) - pub_date = models.DateTimeField() - - def __str__(self): - # Caution: this is only safe if you are certain that headline will be - # in ASCII. - return self.headline - - class InternationalArticle(models.Model): headline = models.CharField(max_length=100) pub_date = models.DateTimeField() diff --git a/tests/str/tests.py b/tests/str/tests.py index c4dd1d6b2675..2d82c03ebfa5 100644 --- a/tests/str/tests.py +++ b/tests/str/tests.py @@ -1,25 +1,14 @@ import datetime -from unittest import skipIf from django.db import models from django.test import TestCase from django.test.utils import isolate_apps -from django.utils import six -from .models import Article, InternationalArticle +from .models import InternationalArticle class SimpleTests(TestCase): - @skipIf(six.PY3, "tests a __str__ method returning unicode under Python 2") - def test_basic(self): - a = Article.objects.create( - headline=b'Parrot programs in Python', - pub_date=datetime.datetime(2005, 7, 28) - ) - self.assertEqual(str(a), str('Parrot programs in Python')) - self.assertEqual(repr(a), str('')) - def test_international(self): a = InternationalArticle.objects.create( headline='Girl wins €12.500 in lottery', diff --git a/tests/template_tests/syntax_tests/test_width_ratio.py b/tests/template_tests/syntax_tests/test_width_ratio.py index 8206b83c58c7..bec7d93a4c44 100644 --- a/tests/template_tests/syntax_tests/test_width_ratio.py +++ b/tests/template_tests/syntax_tests/test_width_ratio.py @@ -1,6 +1,5 @@ from django.template import TemplateSyntaxError from django.test import SimpleTestCase -from django.utils import six from ..utils import setup @@ -36,11 +35,10 @@ def test_widthratio05(self): @setup({'widthratio06': '{% widthratio a b 100 %}'}) def test_widthratio06(self): """ - 62.5 should round to 63 on Python 2 and 62 on Python 3 - See http://docs.python.org/py3k/whatsnew/3.0.html + 62.5 should round to 62 """ output = self.engine.render_to_string('widthratio06', {'a': 50, 'b': 80}) - self.assertEqual(output, '62' if six.PY3 else '63') + self.assertEqual(output, '62') @setup({'widthratio07': '{% widthratio a b 100 %}'}) def test_widthratio07(self): diff --git a/tests/template_tests/test_custom.py b/tests/template_tests/test_custom.py index df8ea17fb0ec..03d43089378f 100644 --- a/tests/template_tests/test_custom.py +++ b/tests/template_tests/test_custom.py @@ -1,12 +1,10 @@ import os -from unittest import skipUnless from django.template import Context, Engine, TemplateSyntaxError from django.template.base import Node from django.template.library import InvalidTemplateLibrary from django.test import SimpleTestCase from django.test.utils import extend_sys_path -from django.utils import six from .templatetags import custom, inclusion from .utils import ROOT @@ -344,7 +342,6 @@ def test_load_working_egg(self): }) engine.from_string(ttext) - @skipUnless(six.PY3, "Python 3 only -- Python 2 doesn't have annotations.") def test_load_annotated_function(self): Engine(libraries={ 'annotated_tag_function': 'template_tests.annotated_tag_function', diff --git a/tests/template_tests/test_loaders.py b/tests/template_tests/test_loaders.py index 6e9b6eb453b1..c36e1ba6beef 100644 --- a/tests/template_tests/test_loaders.py +++ b/tests/template_tests/test_loaders.py @@ -7,7 +7,6 @@ from django.template import TemplateDoesNotExist from django.template.engine import Engine from django.test import SimpleTestCase, override_settings -from django.utils import six from django.utils.functional import lazystr from .utils import TEMPLATE_DIR @@ -64,7 +63,6 @@ def test_get_template_missing_debug_on(self): self.assertIsInstance(e, TemplateDoesNotExist) self.assertEqual(e.args[0], 'debug-template-missing.html') - @unittest.skipIf(six.PY2, "Python 2 doesn't set extra exception attributes") def test_cached_exception_no_traceback(self): """ When a TemplateDoesNotExist instance is cached, the cached instance diff --git a/tests/template_tests/test_nodelist.py b/tests/template_tests/test_nodelist.py index 042702e3c0d1..b69e7c063b74 100644 --- a/tests/template_tests/test_nodelist.py +++ b/tests/template_tests/test_nodelist.py @@ -2,7 +2,6 @@ from django.template import Context, Engine from django.template.base import TextNode, VariableNode -from django.utils import six class NodelistTest(TestCase): @@ -38,13 +37,11 @@ class TextNodeTest(TestCase): def test_textnode_repr(self): engine = Engine() for temptext, reprtext in [ - ("Hello, world!", ""), - ("One\ntwo.", ""), + ("Hello, world!", ""), + ("One\ntwo.", ""), ]: template = engine.from_string(temptext) texts = template.nodelist.get_nodes_by_type(TextNode) - if six.PY3: - reprtext = reprtext.replace("u'", "'") self.assertEqual(repr(texts[0]), reprtext) diff --git a/tests/test_runner/test_debug_sql.py b/tests/test_runner/test_debug_sql.py index e23006610093..c6b9b01dbc14 100644 --- a/tests/test_runner/test_debug_sql.py +++ b/tests/test_runner/test_debug_sql.py @@ -5,7 +5,6 @@ from django.test import TestCase from django.test.runner import DiscoverRunner from django.utils import six -from django.utils.encoding import force_text from .models import Person @@ -43,8 +42,6 @@ def _test_output(self, verbosity): ).run(suite) runner.teardown_databases(old_config) - if six.PY2: - stream.buflist = [force_text(x) for x in stream.buflist] return stream.getvalue() def test_output_normal(self): diff --git a/tests/test_runner/test_parallel.py b/tests/test_runner/test_parallel.py index b888dc62afb6..08731f68eb97 100644 --- a/tests/test_runner/test_parallel.py +++ b/tests/test_runner/test_parallel.py @@ -2,7 +2,6 @@ from django.test import SimpleTestCase from django.test.runner import RemoteTestResult -from django.utils import six try: import tblib @@ -28,7 +27,6 @@ class ParallelTestRunnerTest(SimpleTestCase): parallel. """ - @unittest.skipUnless(six.PY3, 'subtests were added in Python 3.4') def test_subtest(self): """ Passing subtests work. @@ -61,12 +59,10 @@ def test_pickle_errors_detection(self): result._confirm_picklable(picklable_error) msg = '__init__() missing 1 required positional argument' - if six.PY2: - msg = '__init__() takes exactly 2 arguments (1 given)' with self.assertRaisesMessage(TypeError, msg): result._confirm_picklable(not_unpicklable_error) - @unittest.skipUnless(six.PY3 and tblib is not None, 'requires tblib to be installed') + @unittest.skipUnless(tblib is not None, 'requires tblib to be installed') def test_add_failing_subtests(self): """ Failing subtests are added correctly using addSubTest(). diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py index a84e5bfb2462..157479a579e7 100644 --- a/tests/urlpatterns_reverse/tests.py +++ b/tests/urlpatterns_reverse/tests.py @@ -3,7 +3,6 @@ """ import sys import threading -import unittest from admin_scripts.tests import AdminScriptTestCase @@ -430,7 +429,7 @@ def test_404_tried_urls_have_names(self): [{'type': RegexURLResolver}, {'type': RegexURLPattern, 'name': None}], [{'type': RegexURLResolver}, {'type': RegexURLResolver}], ] - with self.assertRaisesMessage(Resolver404, b'tried' if six.PY2 else 'tried') as cm: + with self.assertRaisesMessage(Resolver404, 'tried') as cm: resolve('/included/non-existent-url', urlconf=urls) e = cm.exception # make sure we at least matched the root ('/') url resolver: @@ -463,7 +462,6 @@ def test_namespaced_view_detail(self): self.assertTrue(resolver._is_callback('urlpatterns_reverse.nested_urls.View3')) self.assertFalse(resolver._is_callback('urlpatterns_reverse.nested_urls.blub')) - @unittest.skipIf(six.PY2, "Python 2 doesn't support __qualname__.") def test_view_detail_as_method(self): # Views which have a class name as part of their path. resolver = get_resolver('urlpatterns_reverse.method_view_urls') @@ -503,11 +501,6 @@ def test_inserting_reverse_lazy_into_string(self): 'Some URL: %s' % reverse_lazy('some-login-page'), 'Some URL: /login/' ) - if six.PY2: - self.assertEqual( - b'Some URL: %s' % reverse_lazy('some-login-page'), - 'Some URL: /login/' - ) class ReverseLazySettingsTest(AdminScriptTestCase): diff --git a/tests/utils_tests/test_encoding.py b/tests/utils_tests/test_encoding.py index 1d6976fc7751..b4e7b9c0acef 100644 --- a/tests/utils_tests/test_encoding.py +++ b/tests/utils_tests/test_encoding.py @@ -21,10 +21,8 @@ def __str__(self): __unicode__ = __str__ - # str(s) raises a TypeError on python 3 if the result is not a text type. - # python 2 fails when it tries converting from str to unicode (via ASCII). - exception = TypeError if six.PY3 else UnicodeError - with self.assertRaises(exception): + # str(s) raises a TypeError if the result is not a text type. + with self.assertRaises(TypeError): force_text(MyString()) def test_force_text_lazy(self): @@ -47,26 +45,15 @@ def test_force_bytes_strings_only(self): def test_smart_text(self): class Test: - if six.PY3: - def __str__(self): - return 'ŠĐĆŽćžšđ' - else: - def __str__(self): - return 'ŠĐĆŽćžšđ'.encode('utf-8') + def __str__(self): + return 'ŠĐĆŽćžšđ' class TestU: - if six.PY3: - def __str__(self): - return 'ŠĐĆŽćžšđ' - - def __bytes__(self): - return b'Foo' - else: - def __str__(self): - return b'Foo' - - def __unicode__(self): - return '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111' + def __str__(self): + return 'ŠĐĆŽćžšđ' + + def __bytes__(self): + return b'Foo' self.assertEqual(smart_text(Test()), '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111') self.assertEqual(smart_text(TestU()), '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111') diff --git a/tests/utils_tests/test_functional.py b/tests/utils_tests/test_functional.py index f7b12724af8a..0ca534445fae 100644 --- a/tests/utils_tests/test_functional.py +++ b/tests/utils_tests/test_functional.py @@ -38,18 +38,11 @@ def method(self): def test_lazy_object_to_string(self): class Klazz(object): - if six.PY3: - def __str__(self): - return "Î am ā Ǩlâzz." - - def __bytes__(self): - return b"\xc3\x8e am \xc4\x81 binary \xc7\xa8l\xc3\xa2zz." - else: - def __unicode__(self): - return "Î am ā Ǩlâzz." - - def __str__(self): - return b"\xc3\x8e am \xc4\x81 binary \xc7\xa8l\xc3\xa2zz." + def __str__(self): + return "Î am ā Ǩlâzz." + + def __bytes__(self): + return b"\xc3\x8e am \xc4\x81 binary \xc7\xa8l\xc3\xa2zz." t = lazy(lambda: Klazz(), Klazz)() self.assertEqual(six.text_type(t), "Î am ā Ǩlâzz.") diff --git a/tests/utils_tests/test_glob.py b/tests/utils_tests/test_glob.py deleted file mode 100644 index 5cd7fbbe28c8..000000000000 --- a/tests/utils_tests/test_glob.py +++ /dev/null @@ -1,13 +0,0 @@ -from django.test import SimpleTestCase -from django.utils.glob import glob_escape - - -class TestUtilsGlob(SimpleTestCase): - def test_glob_escape(self): - filename = '/my/file?/name[with special chars*' - expected = '/my/file[?]/name[[]with special chars[*]' - filename_b = b'/my/file?/name[with special chars*' - expected_b = b'/my/file[?]/name[[]with special chars[*]' - - self.assertEqual(glob_escape(filename), expected) - self.assertEqual(glob_escape(filename_b), expected_b) diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py index ec818318b4be..8f887fd011b0 100644 --- a/tests/utils_tests/test_html.py +++ b/tests/utils_tests/test_html.py @@ -2,7 +2,7 @@ from datetime import datetime from django.test import SimpleTestCase -from django.utils import html, safestring, six +from django.utils import html, safestring from django.utils._os import upath from django.utils.encoding import force_text from django.utils.functional import lazystr @@ -168,12 +168,8 @@ def test_conditional_escape(self): def test_html_safe(self): @html.html_safe class HtmlClass(object): - if six.PY2: - def __unicode__(self): - return "

I'm a html class!

" - else: - def __str__(self): - return "

I'm a html class!

" + def __str__(self): + return "

I'm a html class!

" html_obj = HtmlClass() self.assertTrue(hasattr(HtmlClass, '__html__')) @@ -181,34 +177,19 @@ def __str__(self): self.assertEqual(force_text(html_obj), html_obj.__html__()) def test_html_safe_subclass(self): - if six.PY2: - class BaseClass(object): - def __html__(self): - # defines __html__ on its own - return 'some html content' + class BaseClass(object): + def __html__(self): + # defines __html__ on its own + return 'some html content' - def __unicode__(self): - return 'some non html content' + def __str__(self): + return 'some non html content' - @html.html_safe - class Subclass(BaseClass): - def __unicode__(self): - # overrides __unicode__ and is marked as html_safe - return 'some html safe content' - else: - class BaseClass(object): - def __html__(self): - # defines __html__ on its own - return 'some html content' - - def __str__(self): - return 'some non html content' - - @html.html_safe - class Subclass(BaseClass): - def __str__(self): - # overrides __str__ and is marked as html_safe - return 'some html safe content' + @html.html_safe + class Subclass(BaseClass): + def __str__(self): + # overrides __str__ and is marked as html_safe + return 'some html safe content' subclass_obj = Subclass() self.assertEqual(force_text(subclass_obj), subclass_obj.__html__()) @@ -222,8 +203,7 @@ def __html__(self): return "

I'm a html class!

" def test_html_safe_doesnt_define_str(self): - method_name = '__unicode__()' if six.PY2 else '__str__()' - msg = "can't apply @html_safe to HtmlClass because it doesn't define %s." % method_name + msg = "can't apply @html_safe to HtmlClass because it doesn't define __str__()." with self.assertRaisesMessage(ValueError, msg): @html.html_safe class HtmlClass(object): diff --git a/tests/utils_tests/test_http.py b/tests/utils_tests/test_http.py index 30a884602192..281fb77fbbb3 100644 --- a/tests/utils_tests/test_http.py +++ b/tests/utils_tests/test_http.py @@ -1,9 +1,8 @@ -import sys import unittest from datetime import datetime from django.test import ignore_warnings -from django.utils import http, six +from django.utils import http from django.utils.datastructures import MultiValueDict from django.utils.deprecation import RemovedInDjango21Warning @@ -51,15 +50,10 @@ def test_base36(self): # reciprocity works for n in [0, 1, 1000, 1000000]: self.assertEqual(n, http.base36_to_int(http.int_to_base36(n))) - if six.PY2: - self.assertEqual(sys.maxint, http.base36_to_int(http.int_to_base36(sys.maxint))) # bad input with self.assertRaises(ValueError): http.int_to_base36(-1) - if six.PY2: - with self.assertRaises(ValueError): - http.int_to_base36(sys.maxint + 1) for n in ['1', 'foo', {1: 2}, (1, 2, 3), 3.141]: with self.assertRaises(TypeError): http.int_to_base36(n) @@ -132,16 +126,6 @@ def test_is_safe_url(self): "%s should be allowed" % good_url, ) - if six.PY2: - # Check binary URLs, regression tests for #26308 - self.assertTrue( - http.is_safe_url(b'https://testserver/', allowed_hosts={'testserver'}), - "binary URLs should be allowed on Python 2" - ) - self.assertFalse(http.is_safe_url(b'\x08//example.com', allowed_hosts={'testserver'})) - self.assertTrue(http.is_safe_url('àview/'.encode('utf-8'), allowed_hosts={'testserver'})) - self.assertFalse(http.is_safe_url('àview'.encode('latin-1'), allowed_hosts={'testserver'})) - # Valid basic auth credentials are allowed. self.assertTrue(http.is_safe_url(r'http://user:pass@testserver/', allowed_hosts={'user:pass@testserver'})) # A path without host is allowed. diff --git a/tests/utils_tests/test_simplelazyobject.py b/tests/utils_tests/test_simplelazyobject.py index 8501b89e9297..a83c78bf4c33 100644 --- a/tests/utils_tests/test_simplelazyobject.py +++ b/tests/utils_tests/test_simplelazyobject.py @@ -2,7 +2,6 @@ from django.contrib.auth.models import User from django.test import TestCase -from django.utils import six from django.utils.functional import SimpleLazyObject @@ -21,9 +20,3 @@ def test_pickle_py2_regression(self): pickle.dumps(x, 0) pickle.dumps(x, 1) pickle.dumps(x, 2) - - if six.PY2: - import cPickle - - # This would fail with "TypeError: expected string or Unicode object, NoneType found". - cPickle.dumps(x) diff --git a/tests/view_tests/tests/py3_test_debug.py b/tests/view_tests/tests/py3_test_debug.py deleted file mode 100644 index 30201bae53f8..000000000000 --- a/tests/view_tests/tests/py3_test_debug.py +++ /dev/null @@ -1,45 +0,0 @@ -""" -Since this file contains Python 3 specific syntax, it's named without a test_ -prefix so the test runner won't try to import it. Instead, the test class is -imported in test_debug.py, but only on Python 3. - -This filename is also in setup.cfg flake8 exclude since the Python 2 syntax -error (raise ... from ...) can't be silenced using NOQA. -""" -import sys - -from django.test import RequestFactory, TestCase -from django.views.debug import ExceptionReporter - - -class Py3ExceptionReporterTests(TestCase): - - rf = RequestFactory() - - def test_reporting_of_nested_exceptions(self): - request = self.rf.get('/test_view/') - try: - try: - raise AttributeError('Top level') - except AttributeError as explicit: - try: - raise ValueError('Second exception') from explicit - except ValueError: - raise IndexError('Final exception') - except Exception: - # Custom exception handler, just pass it into ExceptionReporter - exc_type, exc_value, tb = sys.exc_info() - - explicit_exc = 'The above exception ({0}) was the direct cause of the following exception:' - implicit_exc = 'During handling of the above exception ({0}), another exception occurred:' - - reporter = ExceptionReporter(request, exc_type, exc_value, tb) - html = reporter.get_traceback_html() - # Both messages are twice on page -- one rendered as html, - # one as plain text (for pastebin) - self.assertEqual(2, html.count(explicit_exc.format("Top level"))) - self.assertEqual(2, html.count(implicit_exc.format("Second exception"))) - - text = reporter.get_traceback_text() - self.assertIn(explicit_exc.format("Top level"), text) - self.assertIn(implicit_exc.format("Second exception"), text) diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py index 19ab456ba5bb..1d8397c5efdf 100644 --- a/tests/view_tests/tests/test_debug.py +++ b/tests/view_tests/tests/test_debug.py @@ -4,7 +4,6 @@ import re import sys import tempfile -from unittest import skipIf from django.conf.urls import url from django.core import mail @@ -30,9 +29,6 @@ sensitive_method_view, sensitive_view, ) -if six.PY3: - from .py3_test_debug import Py3ExceptionReporterTests # NOQA - PY36 = sys.version_info >= (3, 6) @@ -352,6 +348,34 @@ def test_no_exception(self): self.assertIn('

Request information

', html) self.assertNotIn('

Request data not supplied

', html) + def test_reporting_of_nested_exceptions(self): + request = self.rf.get('/test_view/') + try: + try: + raise AttributeError('Top level') + except AttributeError as explicit: + try: + raise ValueError('Second exception') from explicit + except ValueError: + raise IndexError('Final exception') + except Exception: + # Custom exception handler, just pass it into ExceptionReporter + exc_type, exc_value, tb = sys.exc_info() + + explicit_exc = 'The above exception ({0}) was the direct cause of the following exception:' + implicit_exc = 'During handling of the above exception ({0}), another exception occurred:' + + reporter = ExceptionReporter(request, exc_type, exc_value, tb) + html = reporter.get_traceback_html() + # Both messages are twice on page -- one rendered as html, + # one as plain text (for pastebin) + self.assertEqual(2, html.count(explicit_exc.format("Top level"))) + self.assertEqual(2, html.count(implicit_exc.format("Second exception"))) + + text = reporter.get_traceback_text() + self.assertIn(explicit_exc.format("Top level"), text) + self.assertIn(implicit_exc.format("Second exception"), text) + def test_request_and_message(self): "A message can be provided in addition to a request" request = self.rf.get('/test_view/') @@ -426,11 +450,10 @@ def __repr__(self): self.assertEqual(len(html) // 1024 // 128, 0) # still fit in 128Kb self.assertIn('<trimmed %d bytes string>' % (large + repr_of_str_adds,), html) - @skipIf(six.PY2, 'Bug manifests on PY3 only') def test_unfrozen_importlib(self): """ importlib is not a frozen app, but its loader thinks it's frozen which - results in an ImportError on Python 3. Refs #21443. + results in an ImportError. Refs #21443. """ try: request = self.rf.get('/test_view/') @@ -478,10 +501,7 @@ def test_request_with_items_key(self): An exception report can be generated for requests with 'items' in request GET, POST, FILES, or COOKIES QueryDicts. """ - if six.PY3: - value = 'items
'Oops'
' - else: - value = 'items
u'Oops'
' + value = 'items
'Oops'
' # GET request = self.rf.get('/test_view/?items=Oops') reporter = ExceptionReporter(request, None, None, None) @@ -597,20 +617,16 @@ def test_request_with_items_key(self): An exception report can be generated for requests with 'items' in request GET, POST, FILES, or COOKIES QueryDicts. """ - if six.PY3: - value = "items = 'Oops'" - else: - value = "items = u'Oops'" # GET request = self.rf.get('/test_view/?items=Oops') reporter = ExceptionReporter(request, None, None, None) text = reporter.get_traceback_text() - self.assertIn(value, text) + self.assertIn("items = 'Oops'", text) # POST request = self.rf.post('/test_view/', data={'items': 'Oops'}) reporter = ExceptionReporter(request, None, None, None) text = reporter.get_traceback_text() - self.assertIn(value, text) + self.assertIn("items = 'Oops'", text) # FILES fp = six.StringIO('filecontent') request = self.rf.post('/test_view/', data={'name': 'filename', 'items': fp}) diff --git a/tests/view_tests/tests/test_i18n.py b/tests/view_tests/tests/test_i18n.py index fc7be41594b2..d330b60ff7b2 100644 --- a/tests/view_tests/tests/test_i18n.py +++ b/tests/view_tests/tests/test_i18n.py @@ -8,7 +8,6 @@ ) from django.test.selenium import SeleniumTestCase from django.urls import reverse -from django.utils import six from django.utils._os import upath from django.utils.translation import ( LANGUAGE_SESSION_KEY, get_language, override, @@ -193,10 +192,7 @@ def test_jsi18n(self): for lang_code in ['es', 'fr', 'ru']: with override(lang_code): catalog = gettext.translation('djangojs', locale_dir, [lang_code]) - if six.PY3: - trans_txt = catalog.gettext('this is to be translated') - else: - trans_txt = catalog.ugettext('this is to be translated') + trans_txt = catalog.gettext('this is to be translated') response = self.client.get('/jsi18n/') # response content must include a line like: # "this is to be translated": From f6acd1d271122d66de8061e75ae26137ddf02658 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Wed, 18 Jan 2017 11:51:29 -0500 Subject: [PATCH 0062/3180] Refs #23919 -- Removed Python 2 notes in docs. --- docs/conf.py | 1 - docs/faq/install.txt | 13 +- docs/faq/troubleshooting.txt | 9 - docs/howto/custom-management-commands.txt | 4 - docs/howto/custom-model-fields.txt | 10 +- docs/howto/deployment/checklist.txt | 16 - docs/howto/outputting-csv.txt | 21 - docs/index.txt | 1 - .../contributing/writing-code/javascript.txt | 4 +- .../contributing/writing-code/unit-tests.txt | 16 +- docs/intro/contributing.txt | 6 +- docs/intro/overview.txt | 4 +- docs/intro/reusable-apps.txt | 4 +- docs/ref/applications.txt | 11 +- docs/ref/checks.txt | 6 +- docs/ref/contrib/admin/actions.txt | 2 +- docs/ref/contrib/admin/index.txt | 16 +- docs/ref/contrib/auth.txt | 11 +- docs/ref/contrib/contenttypes.txt | 2 +- docs/ref/contrib/gis/commands.txt | 4 +- docs/ref/contrib/gis/layermapping.txt | 2 +- docs/ref/contrib/gis/tutorial.txt | 2 +- docs/ref/contrib/postgres/fields.txt | 8 +- docs/ref/databases.txt | 55 +-- docs/ref/exceptions.txt | 6 +- docs/ref/files/file.txt | 3 +- docs/ref/forms/api.txt | 8 +- docs/ref/forms/fields.txt | 11 +- docs/ref/models/querysets.txt | 2 +- docs/ref/request-response.txt | 21 - docs/ref/templates/language.txt | 6 +- docs/ref/unicode.txt | 35 +- docs/ref/urlresolvers.txt | 2 +- docs/ref/utils.txt | 69 ++-- docs/releases/1.4.11.txt | 2 +- docs/releases/1.4.17.txt | 2 +- docs/releases/1.4.18.txt | 2 +- docs/releases/1.5.6.txt | 2 +- docs/releases/1.5.txt | 6 +- docs/releases/1.6.2.txt | 2 +- docs/releases/1.6.3.txt | 2 +- docs/releases/1.6.9.txt | 2 +- docs/releases/1.7.2.txt | 2 +- docs/releases/1.8.7.txt | 2 +- docs/topics/auth/customizing.txt | 2 +- docs/topics/cache.txt | 3 +- .../class-based-views/generic-display.txt | 4 +- docs/topics/db/examples/many_to_many.txt | 4 +- docs/topics/db/examples/many_to_one.txt | 11 +- docs/topics/db/examples/one_to_one.txt | 6 +- docs/topics/db/models.txt | 9 +- docs/topics/db/queries.txt | 6 +- docs/topics/forms/modelforms.txt | 2 +- docs/topics/i18n/translation.txt | 6 +- docs/topics/index.txt | 1 - docs/topics/install.txt | 4 +- docs/topics/migrations.txt | 20 +- docs/topics/pagination.txt | 2 +- docs/topics/python3.txt | 369 ------------------ docs/topics/testing/overview.txt | 6 +- docs/topics/testing/tools.txt | 2 +- 61 files changed, 140 insertions(+), 732 deletions(-) delete mode 100644 docs/topics/python3.txt diff --git a/docs/conf.py b/docs/conf.py index 2b42f44268c7..14877cd05df7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -134,7 +134,6 @@ def django_release(): 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), } diff --git a/docs/faq/install.txt b/docs/faq/install.txt index ea27b11db802..622334348eb1 100644 --- a/docs/faq/install.txt +++ b/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. diff --git a/docs/faq/troubleshooting.txt b/docs/faq/troubleshooting.txt index 1b2efd552fdf..5a56c6daa30a 100644 --- a/docs/faq/troubleshooting.txt +++ b/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 ` diff --git a/docs/howto/custom-management-commands.txt b/docs/howto/custom-management-commands.txt index 620681ab3532..51db07e54067 100644 --- a/docs/howto/custom-management-commands.txt +++ b/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`. diff --git a/docs/howto/custom-model-fields.txt b/docs/howto/custom-model-fields.txt index a5f204827265..09d00e0928af 100644 --- a/docs/howto/custom-model-fields.txt +++ b/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 ================================ diff --git a/docs/howto/deployment/checklist.txt b/docs/howto/deployment/checklist.txt index 8d7c27b04f8f..d6820f7e7926 100644 --- a/docs/howto/deployment/checklist.txt +++ b/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 -`_ for more information. - -.. _-r: https://docs.python.org/2/using/cmdline.html#cmdoption-R diff --git a/docs/howto/outputting-csv.txt b/docs/howto/outputting-csv.txt index 26a0c4eb1f8b..98824284ed42 100644 --- a/docs/howto/outputting-csv.txt +++ b/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): diff --git a/docs/index.txt b/docs/index.txt index ab38fa02f907..9c4f393041ab 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -282,7 +282,6 @@ Django aims to be compatible with multiple different flavors and versions of Python: * :doc:`Jython support ` -* :doc:`Python 3 compatibility ` Geographic framework ==================== diff --git a/docs/internals/contributing/writing-code/javascript.txt b/docs/internals/contributing/writing-code/javascript.txt index 3d10c48f0039..be0e43a3b687 100644 --- a/docs/internals/contributing/writing-code/javascript.txt +++ b/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 diff --git a/docs/internals/contributing/writing-code/unit-tests.txt b/docs/internals/contributing/writing-code/unit-tests.txt index 7c0e65bf7167..74ec363b5a89 100644 --- a/docs/internals/contributing/writing-code/unit-tests.txt +++ b/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 ` -* 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 diff --git a/docs/intro/contributing.txt b/docs/intro/contributing.txt index 75414410f226..6ae51b850256 100644 --- a/docs/intro/contributing.txt +++ b/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 `_ 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 `_ or + with your operating system's package manager. .. admonition:: For Windows users diff --git a/docs/intro/overview.txt b/docs/intro/overview.txt index 011d1695a06b..1381892bb9b8 100644 --- a/docs/intro/overview.txt +++ b/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 diff --git a/docs/intro/reusable-apps.txt b/docs/intro/reusable-apps.txt index 69017660477c..c8ff7a7f839a 100644 --- a/docs/intro/reusable-apps.txt +++ b/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', ], diff --git a/docs/ref/applications.txt b/docs/ref/applications.txt index 8663e6522290..1cff9aafa46d 100644 --- a/docs/ref/applications.txt +++ b/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, diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index 13ef44053ee6..518ed507af2c 100644 --- a/docs/ref/checks.txt +++ b/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 diff --git a/docs/ref/contrib/admin/actions.txt b/docs/ref/contrib/admin/actions.txt index e98d8d2aef2b..039d8d37d6ca 100644 --- a/docs/ref/contrib/admin/actions.txt +++ b/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 diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index 1fa3843c73c3..74faef6a75ea 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/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') diff --git a/docs/ref/contrib/auth.txt b/docs/ref/contrib/auth.txt index c049deb4390e..a2692306437e 100644 --- a/docs/ref/contrib/auth.txt +++ b/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: diff --git a/docs/ref/contrib/contenttypes.txt b/docs/ref/contrib/contenttypes.txt index 33e690d97cdf..e5635ef59e5d 100644 --- a/docs/ref/contrib/contenttypes.txt +++ b/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 diff --git a/docs/ref/contrib/gis/commands.txt b/docs/ref/contrib/gis/commands.txt index 77fa91539618..eeb6ca0513fc 100644 --- a/docs/ref/contrib/gis/commands.txt +++ b/docs/ref/contrib/gis/commands.txt @@ -63,8 +63,8 @@ of using ``ogrinspect`` :ref:`in the tutorial `. .. 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 diff --git a/docs/ref/contrib/gis/layermapping.txt b/docs/ref/contrib/gis/layermapping.txt index 06cded679bcc..f273fa9c205b 100644 --- a/docs/ref/contrib/gis/layermapping.txt +++ b/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 diff --git a/docs/ref/contrib/gis/tutorial.txt b/docs/ref/contrib/gis/tutorial.txt index cc518a999caa..22e3b075ad75 100644 --- a/docs/ref/contrib/gis/tutorial.txt +++ b/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``. diff --git a/docs/ref/contrib/postgres/fields.txt b/docs/ref/contrib/postgres/fields.txt index 5a79d8879d85..f0f320b7258d 100644 --- a/docs/ref/contrib/postgres/fields.txt +++ b/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:: diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt index 03fed7db248a..5ba10664d408 100644 --- a/docs/ref/databases.txt +++ b/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 diff --git a/docs/ref/exceptions.txt b/docs/ref/exceptions.txt index 79afe702a142..7057b90804a3 100644 --- a/docs/ref/exceptions.txt +++ b/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 diff --git a/docs/ref/files/file.txt b/docs/ref/files/file.txt index 4169b74b8863..803f060c2963 100644 --- a/docs/ref/files/file.txt +++ b/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 diff --git a/docs/ref/forms/api.txt b/docs/ref/forms/api.txt index 1c4185156d1c..e64e25d24148 100644 --- a/docs/ref/forms/api.txt +++ b/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:: diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt index 8dfe26aa79a4..2008e65b9572 100644 --- a/docs/ref/forms/fields.txt +++ b/docs/ref/forms/fields.txt @@ -1183,12 +1183,11 @@ method:: ... - 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 diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index ddacf25769e7..18e81a7da83d 100644 --- a/docs/ref/models/querysets.txt +++ b/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()), diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt index 40ba20738e7c..a6f80feb2eb2 100644 --- a/docs/ref/request-response.txt +++ b/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() diff --git a/docs/ref/templates/language.txt b/docs/ref/templates/language.txt index d6f13a637f96..430ada3a2f11 100644 --- a/docs/ref/templates/language.txt +++ b/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. diff --git a/docs/ref/unicode.txt b/docs/ref/unicode.txt index c167fd55b396..d493ce56ade3 100644 --- a/docs/ref/unicode.txt +++ b/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 `. +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' diff --git a/docs/ref/urlresolvers.txt b/docs/ref/urlresolvers.txt index 6e3ec595b16f..9d462637ef3c 100644 --- a/docs/ref/urlresolvers.txt +++ b/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 '/' diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index 79787227e2f0..550facd14280 100644 --- a/docs/ref/utils.txt +++ b/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) diff --git a/docs/releases/1.4.11.txt b/docs/releases/1.4.11.txt index 990f511e7119..4d5c555fca9c 100644 --- a/docs/releases/1.4.11.txt +++ b/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()`` diff --git a/docs/releases/1.4.17.txt b/docs/releases/1.4.17.txt index 8c6a5de3bfd9..f66bca433dc1 100644 --- a/docs/releases/1.4.17.txt +++ b/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 diff --git a/docs/releases/1.4.18.txt b/docs/releases/1.4.18.txt index 418808d6cc6f..124d271bc42a 100644 --- a/docs/releases/1.4.18.txt +++ b/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. diff --git a/docs/releases/1.5.6.txt b/docs/releases/1.5.6.txt index 915dd7e22a6b..c5be83dd57fb 100644 --- a/docs/releases/1.5.6.txt +++ b/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). diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt index cbd1d48cfeac..af8de1ea12fe 100644 --- a/docs/releases/1.5.txt +++ b/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 -`. 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. diff --git a/docs/releases/1.6.2.txt b/docs/releases/1.6.2.txt index 90599bcb57db..d7a1bc099b2a 100644 --- a/docs/releases/1.6.2.txt +++ b/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). diff --git a/docs/releases/1.6.3.txt b/docs/releases/1.6.3.txt index 0cba7d59af9a..4091e793c557 100644 --- a/docs/releases/1.6.3.txt +++ b/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). diff --git a/docs/releases/1.6.9.txt b/docs/releases/1.6.9.txt index 38785f962391..239cd7c8968f 100644 --- a/docs/releases/1.6.9.txt +++ b/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 diff --git a/docs/releases/1.7.2.txt b/docs/releases/1.7.2.txt index 056f43297867..2b6725265e7a 100644 --- a/docs/releases/1.7.2.txt +++ b/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 diff --git a/docs/releases/1.8.7.txt b/docs/releases/1.8.7.txt index 7da30a1a026e..98598f665b51 100644 --- a/docs/releases/1.8.7.txt +++ b/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 diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt index 0f750adc2b0d..c4fd73cebc28 100644 --- a/docs/topics/auth/customizing.txt +++ b/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): diff --git a/docs/topics/cache.txt b/docs/topics/cache.txt index fc10025ce514..6c8c736363a5 100644 --- a/docs/topics/cache.txt +++ b/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). diff --git a/docs/topics/class-based-views/generic-display.txt b/docs/topics/class-based-views/generic-display.txt index 076afba6788c..bb848d614729 100644 --- a/docs/topics/class-based-views/generic-display.txt +++ b/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): diff --git a/docs/topics/db/examples/many_to_many.txt b/docs/topics/db/examples/many_to_many.txt index 5c77dc08e451..7173faaecafd 100644 --- a/docs/topics/db/examples/many_to_many.txt +++ b/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: diff --git a/docs/topics/db/examples/many_to_one.txt b/docs/topics/db/examples/many_to_one.txt index c57d9964606d..7ccaa94bc2fd 100644 --- a/docs/topics/db/examples/many_to_one.txt +++ b/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)) diff --git a/docs/topics/db/examples/one_to_one.txt b/docs/topics/db/examples/one_to_one.txt index 72d918861ee1..7588825a02fe 100644 --- a/docs/topics/db/examples/one_to_one.txt +++ b/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 diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt index 1ce164f532de..9bafb85120fa 100644 --- a/docs/topics/db/models.txt +++ b/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 `. 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 diff --git a/docs/topics/db/queries.txt b/docs/topics/db/queries.txt index 21ae388fa884..016aef9867a6 100644 --- a/docs/topics/db/queries.txt +++ b/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 diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt index b0115cef7ebe..a3a817916998 100644 --- a/docs/topics/forms/modelforms.txt +++ b/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): diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt index bb3796a32eba..2dd47bd8087a 100644 --- a/docs/topics/i18n/translation.txt +++ b/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:: diff --git a/docs/topics/index.txt b/docs/topics/index.txt index 6f85baddb6e2..6e9d7d74a5b0 100644 --- a/docs/topics/index.txt +++ b/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 diff --git a/docs/topics/install.txt b/docs/topics/install.txt index 5bdd98596d4b..dff170f73306 100644 --- a/docs/topics/install.txt +++ b/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 - ` walks through how to create a virtualenv on Python 3. + ` 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 ` 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: diff --git a/docs/topics/migrations.txt b/docs/topics/migrations.txt index 5475e7b385f7..3910d3132152 100644 --- a/docs/topics/migrations.txt +++ b/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 `) @@ -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 diff --git a/docs/topics/pagination.txt b/docs/topics/pagination.txt index d2737fd5229e..41ee51290e85 100644 --- a/docs/topics/pagination.txt +++ b/docs/topics/pagination.txt @@ -24,7 +24,7 @@ page:: 4 >>> p.num_pages 2 - >>> type(p.page_range) # `` in Python 2. + >>> type(p.page_range) >>> p.page_range range(1, 3) diff --git a/docs/topics/python3.txt b/docs/topics/python3.txt deleted file mode 100644 index 5b40f57bd330..000000000000 --- a/docs/topics/python3.txt +++ /dev/null @@ -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 -` 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 `. 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 ` 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 ` -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 ` 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 `) 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 diff --git a/docs/topics/testing/overview.txt b/docs/topics/testing/overview.txt index 245ee0707902..5687e07e2e8d 100644 --- a/docs/topics/testing/overview.txt +++ b/docs/topics/testing/overview.txt @@ -177,9 +177,9 @@ control the particular collation used by the test database. See the :doc:`settings documentation ` 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 `_ 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 +`_ 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? diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt index b8c799619ec7..91f96908271a 100644 --- a/docs/topics/testing/tools.txt +++ b/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): From 7b2f2e74adb36a4334e83130f6abc2f79d395235 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Thu, 29 Dec 2016 16:27:49 +0100 Subject: [PATCH 0063/3180] Refs #23919 -- Removed six._types usage Thanks Tim Graham and Simon Charette for the reviews. --- django/conf/urls/__init__.py | 3 +- django/contrib/admin/helpers.py | 5 +- django/contrib/admin/options.py | 10 ++-- django/contrib/admin/utils.py | 8 +-- django/contrib/admin/widgets.py | 3 +- django/contrib/auth/decorators.py | 3 +- django/contrib/auth/mixins.py | 3 +- django/contrib/auth/models.py | 9 +-- django/contrib/auth/password_validation.py | 5 +- django/contrib/auth/tokens.py | 6 +- django/contrib/gis/admin/widgets.py | 4 +- django/contrib/gis/db/backends/base/models.py | 3 +- .../gis/db/backends/oracle/operations.py | 3 +- .../gis/db/backends/postgis/operations.py | 5 +- .../db/backends/spatialite/introspection.py | 5 +- django/contrib/gis/db/models/fields.py | 3 +- django/contrib/gis/db/models/functions.py | 13 ++--- django/contrib/gis/db/models/lookups.py | 3 +- django/contrib/gis/db/models/proxy.py | 5 +- django/contrib/gis/forms/widgets.py | 4 +- django/contrib/gis/gdal/datasource.py | 5 +- django/contrib/gis/gdal/driver.py | 3 +- django/contrib/gis/gdal/feature.py | 3 +- django/contrib/gis/gdal/geometries.py | 10 ++-- django/contrib/gis/gdal/geomtype.py | 5 +- django/contrib/gis/gdal/layer.py | 3 +- .../contrib/gis/gdal/prototypes/errcheck.py | 7 +-- django/contrib/gis/gdal/raster/source.py | 7 +-- django/contrib/gis/gdal/srs.py | 7 +-- django/contrib/gis/geoip2/base.py | 5 +- django/contrib/gis/geos/factory.py | 2 +- django/contrib/gis/geos/geometry.py | 8 +-- django/contrib/gis/geos/mutable_list.py | 7 +-- django/contrib/gis/geos/point.py | 5 +- django/contrib/gis/geos/polygon.py | 3 +- django/contrib/gis/geos/prototypes/io.py | 4 +- django/contrib/gis/measure.py | 4 +- django/contrib/gis/utils/layermapping.py | 8 +-- django/contrib/gis/utils/ogrinspect.py | 5 +- django/contrib/messages/storage/session.py | 3 +- django/contrib/postgres/fields/array.py | 3 +- django/contrib/postgres/fields/hstore.py | 5 +- django/contrib/postgres/fields/ranges.py | 3 +- django/contrib/postgres/forms/array.py | 3 +- django/contrib/postgres/forms/hstore.py | 3 +- django/contrib/postgres/forms/jsonb.py | 7 +-- django/core/cache/backends/memcached.py | 3 +- django/core/checks/templates.py | 3 +- django/core/checks/urls.py | 3 +- django/core/files/base.py | 9 ++- django/core/handlers/base.py | 3 +- django/core/mail/backends/filebased.py | 3 +- django/core/mail/message.py | 10 ++-- django/core/management/utils.py | 2 +- django/core/paginator.py | 2 +- django/core/serializers/base.py | 2 +- django/core/serializers/json.py | 8 +-- django/core/serializers/python.py | 4 +- django/core/serializers/pyyaml.py | 2 +- django/core/validators.py | 5 +- django/db/backends/base/operations.py | 18 +++--- django/db/backends/base/schema.py | 6 +- django/db/backends/mysql/base.py | 2 +- django/db/backends/mysql/operations.py | 6 +- django/db/backends/oracle/base.py | 15 +---- django/db/backends/oracle/operations.py | 4 +- django/db/backends/oracle/schema.py | 7 +-- django/db/backends/sqlite3/base.py | 6 +- django/db/backends/sqlite3/operations.py | 6 +- django/db/backends/sqlite3/schema.py | 11 ++-- django/db/migrations/autodetector.py | 5 +- django/db/migrations/operations/models.py | 7 +-- django/db/migrations/serializer.py | 6 +- django/db/migrations/state.py | 15 ++--- django/db/models/base.py | 16 +++--- django/db/models/expressions.py | 3 +- django/db/models/fields/__init__.py | 29 +++++----- django/db/models/fields/files.py | 7 +-- django/db/models/fields/related.py | 36 ++++++------ django/db/models/options.py | 4 +- django/db/models/query.py | 2 +- django/db/models/signals.py | 3 +- django/db/models/utils.py | 5 +- django/db/utils.py | 2 +- django/forms/boundfield.py | 3 +- django/forms/fields.py | 8 +-- django/forms/forms.py | 4 +- django/forms/formsets.py | 7 +-- django/forms/models.py | 8 +-- django/forms/widgets.py | 9 +-- django/http/multipartparser.py | 2 +- django/http/request.py | 2 +- django/http/response.py | 10 ++-- django/shortcuts.py | 3 +- django/template/base.py | 3 +- django/template/defaultfilters.py | 10 ++-- django/template/engine.py | 4 +- django/template/library.py | 3 +- django/template/loader.py | 4 +- django/template/response.py | 3 +- django/templatetags/i18n.py | 2 +- django/templatetags/tz.py | 4 +- django/test/client.py | 4 +- django/test/html.py | 27 ++++----- django/test/testcases.py | 12 ++-- django/test/utils.py | 4 +- django/urls/base.py | 5 +- django/urls/resolvers.py | 9 ++- django/urls/utils.py | 4 +- django/utils/archive.py | 4 +- django/utils/dateformat.py | 5 +- django/utils/encoding.py | 24 ++++---- django/utils/formats.py | 20 +++---- django/utils/functional.py | 8 +-- django/utils/html.py | 4 +- django/utils/numberformat.py | 5 +- django/utils/regex_helper.py | 3 +- django/utils/safestring.py | 11 ++-- django/utils/text.py | 4 +- django/utils/timezone.py | 4 +- django/utils/translation/__init__.py | 13 ++--- django/views/debug.py | 10 ++-- django/views/defaults.py | 3 +- django/views/generic/list.py | 3 +- django/views/i18n.py | 4 +- tests/admin_changelist/tests.py | 10 ++-- tests/admin_utils/models.py | 3 +- tests/admin_utils/test_logentry.py | 10 ++-- tests/admin_views/tests.py | 10 ++-- tests/admin_widgets/tests.py | 4 +- tests/auth_tests/test_management.py | 2 +- tests/backends/tests.py | 5 +- tests/contenttypes_tests/test_models.py | 3 +- tests/csrf_tests/tests.py | 3 +- tests/custom_columns/tests.py | 9 ++- tests/custom_managers/tests.py | 9 ++- tests/custom_pk/fields.py | 5 +- tests/custom_pk/tests.py | 17 +++--- tests/datatypes/tests.py | 3 +- tests/expressions/tests.py | 3 +- tests/expressions_case/tests.py | 7 +-- tests/field_deconstruction/tests.py | 2 - tests/field_defaults/tests.py | 3 +- tests/file_uploads/views.py | 3 +- tests/files/tests.py | 7 +-- tests/fixtures_regress/models.py | 3 +- .../field_tests/test_filepathfield.py | 3 +- .../field_tests/test_typedchoicefield.py | 3 +- tests/forms_tests/tests/test_utils.py | 3 +- tests/forms_tests/tests/tests.py | 3 +- tests/gis_tests/geoadmin/tests.py | 2 +- tests/gis_tests/geoapp/test_functions.py | 3 +- tests/gis_tests/geos_tests/test_geos.py | 13 ++--- tests/gis_tests/geos_tests/test_io.py | 3 +- .../gis_tests/geos_tests/test_mutable_list.py | 3 +- tests/gis_tests/test_geoforms.py | 2 +- tests/gis_tests/test_geoip2.py | 3 +- tests/handlers/tests.py | 3 +- tests/httpwrappers/tests.py | 7 +-- tests/i18n/contenttypes/tests.py | 6 +- tests/i18n/test_extraction.py | 3 +- tests/i18n/tests.py | 6 +- tests/inline_formsets/tests.py | 5 +- tests/lookup/models.py | 3 +- tests/m2m_and_m2o/models.py | 3 +- tests/m2m_intermediary/tests.py | 5 +- tests/mail/tests.py | 4 +- tests/migrations/test_state.py | 9 ++- tests/migrations/test_writer.py | 2 +- tests/model_fields/test_foreignkey.py | 3 +- tests/model_fields/test_integerfield.py | 7 +-- tests/model_fields/test_promises.py | 55 +++++++++---------- tests/model_forms/models.py | 3 +- tests/model_forms/tests.py | 34 ++++++------ tests/model_formsets/models.py | 3 +- tests/model_formsets/tests.py | 25 ++++----- tests/model_formsets_regress/tests.py | 15 +++-- tests/model_inheritance/tests.py | 5 +- tests/model_regress/tests.py | 6 +- tests/order_with_respect_to/models.py | 3 +- tests/pagination/tests.py | 4 +- tests/prefetch_related/tests.py | 39 +++++++------ tests/queries/models.py | 3 +- tests/redirects_tests/tests.py | 3 +- tests/resolve_url/tests.py | 3 +- tests/runtests.py | 7 +-- tests/save_delete_hooks/tests.py | 3 +- tests/select_related_regress/tests.py | 5 +- tests/serializers/models/base.py | 3 +- tests/serializers/test_xml.py | 3 +- tests/serializers/test_yaml.py | 3 +- tests/servers/tests.py | 3 +- tests/signals/tests.py | 3 +- tests/staticfiles_tests/cases.py | 5 +- tests/staticfiles_tests/test_management.py | 6 +- tests/staticfiles_tests/test_storage.py | 2 +- .../filter_tests/test_escape.py | 3 +- .../filter_tests/test_escapejs.py | 3 +- .../filter_tests/test_floatformat.py | 7 +-- .../filter_tests/test_linebreaks.py | 3 +- .../filter_tests/test_slugify.py | 3 +- .../filter_tests/test_urlize.py | 3 +- tests/template_tests/templatetags/custom.py | 6 +- .../template_tests/templatetags/inclusion.py | 10 ++-- tests/template_tests/test_unicode.py | 3 +- tests/test_utils/tests.py | 2 +- tests/update/models.py | 5 +- tests/urlpatterns_reverse/tests.py | 8 --- tests/utils_tests/test_encoding.py | 3 +- tests/utils_tests/test_functional.py | 7 +-- tests/utils_tests/test_lazyobject.py | 2 +- tests/utils_tests/test_safestring.py | 4 +- tests/utils_tests/test_text.py | 3 +- 213 files changed, 574 insertions(+), 763 deletions(-) diff --git a/django/conf/urls/__init__.py b/django/conf/urls/__init__.py index 45af3a10d239..16db0f2feaa4 100644 --- a/django/conf/urls/__init__.py +++ b/django/conf/urls/__init__.py @@ -4,7 +4,6 @@ from django.urls import ( LocaleRegexURLResolver, RegexURLPattern, RegexURLResolver, ) -from django.utils import six __all__ = ['handler400', 'handler403', 'handler404', 'handler500', 'include', 'url'] @@ -34,7 +33,7 @@ def include(arg, namespace=None): # No namespace hint - use manually provided namespace urlconf_module = arg - if isinstance(urlconf_module, six.string_types): + if isinstance(urlconf_module, str): urlconf_module = import_module(urlconf_module) patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module) app_name = getattr(urlconf_module, 'app_name', app_name) diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py index ea56840445ea..628788b3fafd 100644 --- a/django/contrib/admin/helpers.py +++ b/django/contrib/admin/helpers.py @@ -10,7 +10,6 @@ from django.db.models.fields.related import ManyToManyRel from django.forms.utils import flatatt from django.template.defaultfilters import capfirst, linebreaksbr -from django.utils import six from django.utils.encoding import force_text from django.utils.html import conditional_escape, format_html from django.utils.safestring import mark_safe @@ -99,7 +98,7 @@ def __iter__(self): class Fieldline(object): def __init__(self, form, field, readonly_fields=None, model_admin=None): self.form = form # A django.forms.Form instance - if not hasattr(field, "__iter__") or isinstance(field, six.text_type): + if not hasattr(field, "__iter__") or isinstance(field, str): self.fields = [field] else: self.fields = field @@ -217,7 +216,7 @@ def contents(self): result_repr = linebreaksbr(force_text(value)) else: if isinstance(f.remote_field, ManyToManyRel) and value is not None: - result_repr = ", ".join(map(six.text_type, value.all())) + result_repr = ", ".join(map(str, value.all())) else: result_repr = display_for_field(value, f, self.empty_value_display) result_repr = linebreaksbr(result_repr) diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index bb871513d7ff..eaa99160566d 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -1068,8 +1068,8 @@ def response_add(self, request, obj, post_url_continue=None): attr = obj._meta.pk.attname value = obj.serializable_value(attr) popup_response_data = json.dumps({ - 'value': six.text_type(value), - 'obj': six.text_type(obj), + 'value': str(value), + 'obj': str(obj), }) return TemplateResponse(request, self.popup_response_template or [ 'admin/%s/%s/popup_response.html' % (opts.app_label, opts.model_name), @@ -1129,9 +1129,9 @@ def response_change(self, request, obj): new_value = obj.serializable_value(attr) popup_response_data = json.dumps({ 'action': 'change', - 'value': six.text_type(value), - 'obj': six.text_type(obj), - 'new_value': six.text_type(new_value), + 'value': str(value), + 'obj': str(obj), + 'new_value': str(new_value), }) return TemplateResponse(request, self.popup_response_template or [ 'admin/%s/%s/popup_response.html' % (opts.app_label, opts.model_name), diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py index cf1738154816..297796254df1 100644 --- a/django/contrib/admin/utils.py +++ b/django/contrib/admin/utils.py @@ -10,7 +10,7 @@ from django.db.models.sql.constants import QUERY_TERMS from django.forms.utils import pretty_name from django.urls import NoReverseMatch, reverse -from django.utils import formats, six, timezone +from django.utils import formats, timezone from django.utils.encoding import force_str, force_text, smart_text from django.utils.html import format_html from django.utils.text import capfirst @@ -68,7 +68,7 @@ def quote(s): Similar to urllib.quote, except that the quoting is slightly different so that it doesn't get automatically unquoted by the Web browser. """ - if not isinstance(s, six.string_types): + if not isinstance(s, str): return s res = list(s) for i in range(len(res)): @@ -342,7 +342,7 @@ def label_for_field(name, model, model_admin=None, return_attr=False): except FieldDoesNotExist: if name == "__unicode__": label = force_text(model._meta.verbose_name) - attr = six.text_type + attr = str elif name == "__str__": label = force_str(model._meta.verbose_name) attr = bytes @@ -430,7 +430,7 @@ def display_for_value(value, empty_value_display, boolean=False): return formats.localize(timezone.template_localtime(value)) elif isinstance(value, (datetime.date, datetime.time)): return formats.localize(value) - elif isinstance(value, six.integer_types + (decimal.Decimal, float)): + elif isinstance(value, (int, decimal.Decimal, float)): return formats.number_format(value) elif isinstance(value, (list, tuple)): return ', '.join(force_text(v) for v in value) diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index 9f93ae3a42fc..9f6fb412b2fe 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -7,7 +7,6 @@ from django.db.models.deletion import CASCADE from django.urls import reverse from django.urls.exceptions import NoReverseMatch -from django.utils import six from django.utils.encoding import force_text from django.utils.html import smart_urlquote from django.utils.safestring import mark_safe @@ -111,7 +110,7 @@ def url_params_from_lookup_dict(lookups): elif isinstance(v, bool): v = ('0', '1')[v] else: - v = six.text_type(v) + v = str(v) items.append((k, v)) params.update(dict(items)) return params diff --git a/django/contrib/auth/decorators.py b/django/contrib/auth/decorators.py index 9c44108c8915..f6e4c1d5b254 100644 --- a/django/contrib/auth/decorators.py +++ b/django/contrib/auth/decorators.py @@ -4,7 +4,6 @@ from django.contrib.auth import REDIRECT_FIELD_NAME from django.core.exceptions import PermissionDenied from django.shortcuts import resolve_url -from django.utils import six from django.utils.decorators import available_attrs from django.utils.six.moves.urllib.parse import urlparse @@ -60,7 +59,7 @@ def permission_required(perm, login_url=None, raise_exception=False): is raised. """ def check_perms(user): - if isinstance(perm, six.string_types): + if isinstance(perm, str): perms = (perm, ) else: perms = perm diff --git a/django/contrib/auth/mixins.py b/django/contrib/auth/mixins.py index 4a7759435b7f..c52b57365830 100644 --- a/django/contrib/auth/mixins.py +++ b/django/contrib/auth/mixins.py @@ -2,7 +2,6 @@ from django.contrib.auth import REDIRECT_FIELD_NAME from django.contrib.auth.views import redirect_to_login from django.core.exceptions import ImproperlyConfigured, PermissionDenied -from django.utils import six from django.utils.encoding import force_text @@ -73,7 +72,7 @@ def get_permission_required(self): '{0} is missing the permission_required attribute. Define {0}.permission_required, or override ' '{0}.get_permission_required().'.format(self.__class__.__name__) ) - if isinstance(self.permission_required, six.string_types): + if isinstance(self.permission_required, str): perms = (self.permission_required, ) else: perms = self.permission_required diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index 7155bd1199f1..0fc2ab41dac5 100644 --- a/django/contrib/auth/models.py +++ b/django/contrib/auth/models.py @@ -6,7 +6,7 @@ from django.core.mail import send_mail from django.db import models from django.db.models.manager import EmptyManager -from django.utils import six, timezone +from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from .validators import UnicodeUsernameValidator @@ -75,9 +75,10 @@ class Meta: def __str__(self): return "%s | %s | %s" % ( - six.text_type(self.content_type.app_label), - six.text_type(self.content_type), - six.text_type(self.name)) + self.content_type.app_label, + self.content_type, + self.name, + ) def natural_key(self): return (self.codename,) + self.content_type.natural_key() diff --git a/django/contrib/auth/password_validation.py b/django/contrib/auth/password_validation.py index d802a5f5fde3..1cf32e021988 100644 --- a/django/contrib/auth/password_validation.py +++ b/django/contrib/auth/password_validation.py @@ -13,7 +13,6 @@ from django.utils.functional import lazy from django.utils.html import format_html from django.utils.module_loading import import_string -from django.utils.six import string_types, text_type from django.utils.translation import ugettext as _, ungettext @@ -88,7 +87,7 @@ def _password_validators_help_text_html(password_validators=None): return '
    %s
' % ''.join(help_items) if help_items else '' -password_validators_help_text_html = lazy(_password_validators_help_text_html, text_type) +password_validators_help_text_html = lazy(_password_validators_help_text_html, str) class MinimumLengthValidator(object): @@ -141,7 +140,7 @@ def validate(self, password, user=None): for attribute_name in self.user_attributes: value = getattr(user, attribute_name, None) - if not value or not isinstance(value, string_types): + if not value or not isinstance(value, str): continue value_parts = re.split(r'\W+', value) + [value] for value_part in value_parts: diff --git a/django/contrib/auth/tokens.py b/django/contrib/auth/tokens.py index 6cf694cebbee..18ff42f19247 100644 --- a/django/contrib/auth/tokens.py +++ b/django/contrib/auth/tokens.py @@ -1,7 +1,6 @@ from datetime import date from django.conf import settings -from django.utils import six from django.utils.crypto import constant_time_compare, salted_hmac from django.utils.http import base36_to_int, int_to_base36 @@ -68,10 +67,7 @@ def _make_token_with_timestamp(self, user, timestamp): def _make_hash_value(self, user, timestamp): # Ensure results are consistent across DB backends login_timestamp = '' if user.last_login is None else user.last_login.replace(microsecond=0, tzinfo=None) - return ( - six.text_type(user.pk) + user.password + - six.text_type(login_timestamp) + six.text_type(timestamp) - ) + return str(user.pk) + user.password + str(login_timestamp) + str(timestamp) def _num_days(self, dt): return (dt - date(2001, 1, 1)).days diff --git a/django/contrib/gis/admin/widgets.py b/django/contrib/gis/admin/widgets.py index 014b3ad81891..b76e860324f6 100644 --- a/django/contrib/gis/admin/widgets.py +++ b/django/contrib/gis/admin/widgets.py @@ -3,7 +3,7 @@ from django.contrib.gis.gdal import GDALException from django.contrib.gis.geos import GEOSException, GEOSGeometry from django.forms.widgets import Textarea -from django.utils import six, translation +from django.utils import translation # Creating a template context that contains Django settings # values needed by admin map templates. @@ -30,7 +30,7 @@ def get_context(self, name, value, attrs=None): # If a string reaches here (via a validation error on another # field) then just reconstruct the Geometry. - if value and isinstance(value, six.string_types): + if value and isinstance(value, str): try: value = GEOSGeometry(value) except (GEOSException, ValueError) as err: diff --git a/django/contrib/gis/db/backends/base/models.py b/django/contrib/gis/db/backends/base/models.py index 8c8bdc6346be..8388a27f2556 100644 --- a/django/contrib/gis/db/backends/base/models.py +++ b/django/contrib/gis/db/backends/base/models.py @@ -1,5 +1,4 @@ from django.contrib.gis import gdal -from django.utils import six class SpatialRefSysMixin(object): @@ -134,4 +133,4 @@ def __str__(self): """ Returns the string representation, a 'pretty' OGC WKT. """ - return six.text_type(self.srs) + return str(self.srs) diff --git a/django/contrib/gis/db/backends/oracle/operations.py b/django/contrib/gis/db/backends/oracle/operations.py index 013ffa74f697..a431b916bed9 100644 --- a/django/contrib/gis/db/backends/oracle/operations.py +++ b/django/contrib/gis/db/backends/oracle/operations.py @@ -17,7 +17,6 @@ from django.contrib.gis.geometry.backend import Geometry from django.contrib.gis.measure import Distance from django.db.backends.oracle.operations import DatabaseOperations -from django.utils import six from django.utils.functional import cached_property DEFAULT_TOLERANCE = '0.05' @@ -45,7 +44,7 @@ class SDORelate(SpatialOperator): def check_relate_argument(self, arg): masks = 'TOUCH|OVERLAPBDYDISJOINT|OVERLAPBDYINTERSECT|EQUAL|INSIDE|COVEREDBY|CONTAINS|COVERS|ANYINTERACT|ON' mask_regex = re.compile(r'^(%s)(\+(%s))*$' % (masks, masks), re.I) - if not isinstance(arg, six.string_types) or not mask_regex.match(arg): + if not isinstance(arg, str) or not mask_regex.match(arg): raise ValueError('Invalid SDO_RELATE mask: "%s"' % arg) def as_sql(self, connection, lookup, template_params, sql_params): diff --git a/django/contrib/gis/db/backends/postgis/operations.py b/django/contrib/gis/db/backends/postgis/operations.py index ae0821694a68..678c420c2356 100644 --- a/django/contrib/gis/db/backends/postgis/operations.py +++ b/django/contrib/gis/db/backends/postgis/operations.py @@ -9,7 +9,6 @@ from django.core.exceptions import ImproperlyConfigured from django.db.backends.postgresql.operations import DatabaseOperations from django.db.utils import ProgrammingError -from django.utils import six from django.utils.functional import cached_property from .adapter import PostGISAdapter @@ -337,7 +336,7 @@ def get_geom_placeholder(self, f, value, compiler): # Get the srid for this object if value is None: value_srid = None - elif f.geom_type == 'RASTER' and isinstance(value, six.string_types): + elif f.geom_type == 'RASTER' and isinstance(value, str): value_srid = get_pgraster_srid(value) else: value_srid = value.srid @@ -346,7 +345,7 @@ def get_geom_placeholder(self, f, value, compiler): # is not equal to the field srid. if value_srid is None or value_srid == f.srid: placeholder = '%s' - elif f.geom_type == 'RASTER' and isinstance(value, six.string_types): + elif f.geom_type == 'RASTER' and isinstance(value, str): placeholder = '%s((%%s)::raster, %s)' % (self.transform, f.srid) else: placeholder = '%s(%%s, %s)' % (self.transform, f.srid) diff --git a/django/contrib/gis/db/backends/spatialite/introspection.py b/django/contrib/gis/db/backends/spatialite/introspection.py index 6c3ed1864c55..467e3a44f779 100644 --- a/django/contrib/gis/db/backends/spatialite/introspection.py +++ b/django/contrib/gis/db/backends/spatialite/introspection.py @@ -2,7 +2,6 @@ from django.db.backends.sqlite3.introspection import ( DatabaseIntrospection, FlexibleFieldLookupDict, ) -from django.utils import six class GeoFlexibleFieldLookupDict(FlexibleFieldLookupDict): @@ -41,7 +40,7 @@ def get_geometry_type(self, table_name, geo_col): # OGRGeomType does not require GDAL and makes it easy to convert # from OGC geom type name to Django field. ogr_type = row[2] - if isinstance(ogr_type, six.integer_types) and ogr_type > 1000: + if isinstance(ogr_type, int) and ogr_type > 1000: # SpatiaLite versions >= 4 use the new SFSQL 1.2 offsets # 1000 (Z), 2000 (M), and 3000 (ZM) to indicate the presence of # higher dimensional coordinates (M not yet supported by Django). @@ -54,7 +53,7 @@ def get_geometry_type(self, table_name, geo_col): field_params = {} if srid != 4326: field_params['srid'] = srid - if (isinstance(dim, six.string_types) and 'Z' in dim) or dim == 3: + if (isinstance(dim, str) and 'Z' in dim) or dim == 3: field_params['dim'] = 3 finally: cursor.close() diff --git a/django/contrib/gis/db/models/fields.py b/django/contrib/gis/db/models/fields.py index 215a17b6b58e..6435dc407714 100644 --- a/django/contrib/gis/db/models/fields.py +++ b/django/contrib/gis/db/models/fields.py @@ -10,7 +10,6 @@ from django.core.exceptions import ImproperlyConfigured from django.db.models.expressions import Expression from django.db.models.fields import Field -from django.utils import six from django.utils.translation import ugettext_lazy as _ # Local cache of the spatial_ref_sys table, which holds SRID data for each @@ -226,7 +225,7 @@ def get_prep_value(self, value): pass else: # Check if input is a candidate for conversion to raster or geometry. - is_candidate = isinstance(obj, (bytes, six.string_types)) or hasattr(obj, '__geo_interface__') + is_candidate = isinstance(obj, (bytes, str)) or hasattr(obj, '__geo_interface__') # Try to convert the input to raster. raster = self.get_raster_prep_value(obj, is_candidate) diff --git a/django/contrib/gis/db/models/functions.py b/django/contrib/gis/db/models/functions.py index 8a4d54aac100..77628afa3464 100644 --- a/django/contrib/gis/db/models/functions.py +++ b/django/contrib/gis/db/models/functions.py @@ -9,9 +9,8 @@ from django.core.exceptions import FieldError from django.db.models import BooleanField, FloatField, IntegerField, TextField from django.db.models.expressions import Func, Value -from django.utils import six -NUMERIC_TYPES = six.integer_types + (float, Decimal) +NUMERIC_TYPES = (int, float, Decimal) class GeoFunc(Func): @@ -161,7 +160,7 @@ class AsGeoJSON(GeoFunc): def __init__(self, expression, bbox=False, crs=False, precision=8, **extra): expressions = [expression] if precision is not None: - expressions.append(self._handle_param(precision, 'precision', six.integer_types)) + expressions.append(self._handle_param(precision, 'precision', int)) options = 0 if crs and bbox: options = 3 @@ -181,7 +180,7 @@ class AsGML(GeoFunc): def __init__(self, expression, version=2, precision=8, **extra): expressions = [version, expression] if precision is not None: - expressions.append(self._handle_param(precision, 'precision', six.integer_types)) + expressions.append(self._handle_param(precision, 'precision', int)) super(AsGML, self).__init__(*expressions, **extra) def as_oracle(self, compiler, connection, **extra_context): @@ -208,7 +207,7 @@ def __init__(self, expression, relative=False, precision=8, **extra): expressions = [ expression, relative, - self._handle_param(precision, 'precision', six.integer_types), + self._handle_param(precision, 'precision', int), ] super(AsSVG, self).__init__(*expressions, **extra) @@ -311,7 +310,7 @@ class GeoHash(GeoFunc): def __init__(self, expression, precision=None, **extra): expressions = [expression] if precision is not None: - expressions.append(self._handle_param(precision, 'precision', six.integer_types)) + expressions.append(self._handle_param(precision, 'precision', int)) super(GeoHash, self).__init__(*expressions, **extra) @@ -458,7 +457,7 @@ class Transform(GeoFunc): def __init__(self, expression, srid, **extra): expressions = [ expression, - self._handle_param(srid, 'srid', six.integer_types), + self._handle_param(srid, 'srid', int), ] if 'output_field' not in extra: extra['output_field'] = GeometryField(srid=srid) diff --git a/django/contrib/gis/db/models/lookups.py b/django/contrib/gis/db/models/lookups.py index b707a9cbff7d..3b2d4b8497a6 100644 --- a/django/contrib/gis/db/models/lookups.py +++ b/django/contrib/gis/db/models/lookups.py @@ -5,7 +5,6 @@ from django.db.models.expressions import Col, Expression from django.db.models.lookups import Lookup, Transform from django.db.models.sql.query import Query -from django.utils import six gis_lookups = {} @@ -389,7 +388,7 @@ def get_db_prep_lookup(self, value, connection): backend_op.check_relate_argument(value[1]) else: pattern = value[1] - if not isinstance(pattern, six.string_types) or not self.pattern_regex.match(pattern): + if not isinstance(pattern, str) or not self.pattern_regex.match(pattern): raise ValueError('Invalid intersection matrix pattern "%s".' % pattern) return super(RelateLookup, self).get_db_prep_lookup(value, connection) diff --git a/django/contrib/gis/db/models/proxy.py b/django/contrib/gis/db/models/proxy.py index 340e76f4bffb..86221daca766 100644 --- a/django/contrib/gis/db/models/proxy.py +++ b/django/contrib/gis/db/models/proxy.py @@ -6,7 +6,6 @@ Thanks to Robert Coup for providing this functionality (see #4322). """ from django.db.models.query_utils import DeferredAttribute -from django.utils import six class SpatialProxy(DeferredAttribute): @@ -58,7 +57,7 @@ def __set__(self, instance, value): # The geographic type of the field. gtype = self._field.geom_type - if gtype == 'RASTER' and (value is None or isinstance(value, six.string_types + (dict, self._klass))): + if gtype == 'RASTER' and (value is None or isinstance(value, (str, dict, self._klass))): # For raster fields, assure input is None or a string, dict, or # raster instance. pass @@ -68,7 +67,7 @@ def __set__(self, instance, value): if value.srid is None: # Assigning the field SRID if the geometry has no SRID. value.srid = self._field.srid - elif value is None or isinstance(value, six.string_types + (six.memoryview,)): + elif value is None or isinstance(value, (str, memoryview)): # Set geometries with None, WKT, HEX, or WKB pass else: diff --git a/django/contrib/gis/forms/widgets.py b/django/contrib/gis/forms/widgets.py index 2e7e530cc2ee..0c1fc23c81a1 100644 --- a/django/contrib/gis/forms/widgets.py +++ b/django/contrib/gis/forms/widgets.py @@ -4,7 +4,7 @@ from django.contrib.gis import gdal from django.contrib.gis.geos import GEOSException, GEOSGeometry from django.forms.widgets import Widget -from django.utils import six, translation +from django.utils import translation logger = logging.getLogger('django.contrib.gis') @@ -43,7 +43,7 @@ def deserialize(self, value): def get_context(self, name, value, attrs=None): # If a string reaches here (via a validation error on another # field) then just reconstruct the Geometry. - if value and isinstance(value, six.string_types): + if value and isinstance(value, str): value = self.deserialize(value) if value: diff --git a/django/contrib/gis/gdal/datasource.py b/django/contrib/gis/gdal/datasource.py index 4588a1731a36..1ff2326a635b 100644 --- a/django/contrib/gis/gdal/datasource.py +++ b/django/contrib/gis/gdal/datasource.py @@ -40,7 +40,6 @@ from django.contrib.gis.gdal.error import GDALException, OGRIndexError from django.contrib.gis.gdal.layer import Layer from django.contrib.gis.gdal.prototypes import ds as capi -from django.utils import six from django.utils.encoding import force_bytes, force_text from django.utils.six.moves import range @@ -64,7 +63,7 @@ def __init__(self, ds_input, ds_driver=False, write=False, encoding='utf-8'): Driver.ensure_registered() - if isinstance(ds_input, six.string_types): + if isinstance(ds_input, str): # The data source driver is a void pointer. ds_driver = Driver.ptr_type() try: @@ -93,7 +92,7 @@ def __iter__(self): def __getitem__(self, index): "Allows use of the index [] operator to get a layer at the index." - if isinstance(index, six.string_types): + if isinstance(index, str): layer = capi.get_layer_by_name(self.ptr, force_bytes(index)) if not layer: raise OGRIndexError('invalid OGR Layer name given: "%s"' % index) diff --git a/django/contrib/gis/gdal/driver.py b/django/contrib/gis/gdal/driver.py index 7ed45870733b..20ebaeff20b5 100644 --- a/django/contrib/gis/gdal/driver.py +++ b/django/contrib/gis/gdal/driver.py @@ -3,7 +3,6 @@ from django.contrib.gis.gdal.base import GDALBase from django.contrib.gis.gdal.error import GDALException from django.contrib.gis.gdal.prototypes import ds as vcapi, raster as rcapi -from django.utils import six from django.utils.encoding import force_bytes, force_text @@ -36,7 +35,7 @@ def __init__(self, dr_input): """ Initializes an GDAL/OGR driver on either a string or integer input. """ - if isinstance(dr_input, six.string_types): + if isinstance(dr_input, str): # If a string name of the driver was passed in self.ensure_registered() diff --git a/django/contrib/gis/gdal/feature.py b/django/contrib/gis/gdal/feature.py index 2335df733b6f..8975b9c0761e 100644 --- a/django/contrib/gis/gdal/feature.py +++ b/django/contrib/gis/gdal/feature.py @@ -3,7 +3,6 @@ from django.contrib.gis.gdal.field import Field from django.contrib.gis.gdal.geometries import OGRGeometry, OGRGeomType from django.contrib.gis.gdal.prototypes import ds as capi, geom as geom_api -from django.utils import six from django.utils.encoding import force_bytes, force_text from django.utils.six.moves import range @@ -35,7 +34,7 @@ def __getitem__(self, index): is not the field's _value_ -- use the `get` method instead to retrieve the value (e.g. an integer) instead of a Field instance. """ - if isinstance(index, six.string_types): + if isinstance(index, str): i = self.index(index) else: if index < 0 or index > self.num_fields: diff --git a/django/contrib/gis/gdal/geometries.py b/django/contrib/gis/gdal/geometries.py index 08d0a23767f0..28ef2907ac12 100644 --- a/django/contrib/gis/gdal/geometries.py +++ b/django/contrib/gis/gdal/geometries.py @@ -67,7 +67,7 @@ class OGRGeometry(GDALBase): def __init__(self, geom_input, srs=None): "Initializes Geometry on either WKT or an OGR pointer as input." - str_instance = isinstance(geom_input, six.string_types) + str_instance = isinstance(geom_input, str) # If HEX, unpack input to a binary buffer. if str_instance and hex_regex.match(geom_input): @@ -276,7 +276,7 @@ def _set_srs(self, srs): # (decremented) when this geometry's destructor is called. if isinstance(srs, SpatialReference): srs_ptr = srs.ptr - elif isinstance(srs, six.integer_types + six.string_types): + elif isinstance(srs, (int, str)): sr = SpatialReference(srs) srs_ptr = sr.ptr elif srs is None: @@ -295,7 +295,7 @@ def _get_srid(self): return None def _set_srid(self, srid): - if isinstance(srid, six.integer_types) or srid is None: + if isinstance(srid, int) or srid is None: self.srs = srid else: raise TypeError('SRID must be set with an integer.') @@ -403,7 +403,7 @@ def transform(self, coord_trans, clone=False): capi.geom_transform(self.ptr, coord_trans.ptr) elif isinstance(coord_trans, SpatialReference): capi.geom_transform_to(self.ptr, coord_trans.ptr) - elif isinstance(coord_trans, six.integer_types + six.string_types): + elif isinstance(coord_trans, (int, str)): sr = SpatialReference(coord_trans) capi.geom_transform_to(self.ptr, sr.ptr) else: @@ -675,7 +675,7 @@ def add(self, geom): capi.add_geom(self.ptr, g.ptr) else: capi.add_geom(self.ptr, geom.ptr) - elif isinstance(geom, six.string_types): + elif isinstance(geom, str): tmp = OGRGeometry(geom) capi.add_geom(self.ptr, tmp.ptr) else: diff --git a/django/contrib/gis/gdal/geomtype.py b/django/contrib/gis/gdal/geomtype.py index 0ed7e6634306..79c3356f5ea7 100644 --- a/django/contrib/gis/gdal/geomtype.py +++ b/django/contrib/gis/gdal/geomtype.py @@ -1,5 +1,4 @@ from django.contrib.gis.gdal.error import GDALException -from django.utils import six class OGRGeomType(object): @@ -34,7 +33,7 @@ def __init__(self, type_input): "Figures out the correct OGR Type based upon the input." if isinstance(type_input, OGRGeomType): num = type_input.num - elif isinstance(type_input, six.string_types): + elif isinstance(type_input, str): type_input = type_input.lower() if type_input == 'geometry': type_input = 'unknown' @@ -62,7 +61,7 @@ def __eq__(self, other): """ if isinstance(other, OGRGeomType): return self.num == other.num - elif isinstance(other, six.string_types): + elif isinstance(other, str): return self.name.lower() == other.lower() elif isinstance(other, int): return self.num == other diff --git a/django/contrib/gis/gdal/layer.py b/django/contrib/gis/gdal/layer.py index e7e13f9468d3..fbbede81b054 100644 --- a/django/contrib/gis/gdal/layer.py +++ b/django/contrib/gis/gdal/layer.py @@ -13,7 +13,6 @@ ds as capi, geom as geom_api, srs as srs_api, ) from django.contrib.gis.gdal.srs import SpatialReference -from django.utils import six from django.utils.encoding import force_bytes, force_text from django.utils.six.moves import range @@ -42,7 +41,7 @@ def __init__(self, layer_ptr, ds): def __getitem__(self, index): "Gets the Feature at the specified index." - if isinstance(index, six.integer_types): + if isinstance(index, int): # An integer index was given -- we cannot do a check based on the # number of features because the beginning and ending feature IDs # are not guaranteed to be 0 and len(layer)-1, respectively. diff --git a/django/contrib/gis/gdal/prototypes/errcheck.py b/django/contrib/gis/gdal/prototypes/errcheck.py index a7210876545d..9b8309513195 100644 --- a/django/contrib/gis/gdal/prototypes/errcheck.py +++ b/django/contrib/gis/gdal/prototypes/errcheck.py @@ -8,7 +8,6 @@ GDALException, SRSException, check_err, ) from django.contrib.gis.gdal.libgdal import lgdal -from django.utils import six # Helper routines for retrieving pointers and/or values from @@ -79,7 +78,7 @@ def check_geom(result, func, cargs): "Checks a function that returns a geometry." # OGR_G_Clone may return an integer, even though the # restype is set to c_void_p - if isinstance(result, six.integer_types): + if isinstance(result, int): result = c_void_p(result) if not result: raise GDALException('Invalid geometry pointer returned from "%s".' % func.__name__) @@ -95,7 +94,7 @@ def check_geom_offset(result, func, cargs, offset=-1): # ### Spatial Reference error-checking routines ### def check_srs(result, func, cargs): - if isinstance(result, six.integer_types): + if isinstance(result, int): result = c_void_p(result) if not result: raise SRSException('Invalid spatial reference pointer returned from "%s".' % func.__name__) @@ -121,7 +120,7 @@ def check_errcode(result, func, cargs, cpl=False): def check_pointer(result, func, cargs): "Makes sure the result pointer is valid." - if isinstance(result, six.integer_types): + if isinstance(result, int): result = c_void_p(result) if result: return result diff --git a/django/contrib/gis/gdal/raster/source.py b/django/contrib/gis/gdal/raster/source.py index f3a565ddc8ff..3cafe738a493 100644 --- a/django/contrib/gis/gdal/raster/source.py +++ b/django/contrib/gis/gdal/raster/source.py @@ -10,7 +10,6 @@ from django.contrib.gis.gdal.raster.const import GDAL_RESAMPLE_ALGORITHMS from django.contrib.gis.gdal.srs import SpatialReference, SRSException from django.contrib.gis.geometry.regex import json_regex -from django.utils import six from django.utils.encoding import force_bytes, force_text from django.utils.functional import cached_property @@ -62,11 +61,11 @@ def __init__(self, ds_input, write=False): # Preprocess json inputs. This converts json strings to dictionaries, # which are parsed below the same way as direct dictionary inputs. - if isinstance(ds_input, six.string_types) and json_regex.match(ds_input): + if isinstance(ds_input, str) and json_regex.match(ds_input): ds_input = json.loads(ds_input) # If input is a valid file path, try setting file as source. - if isinstance(ds_input, six.string_types): + if isinstance(ds_input, str): if not os.path.exists(ds_input): raise GDALException('Unable to read raster source input "{}"'.format(ds_input)) try: @@ -215,7 +214,7 @@ def srs(self, value): """ if isinstance(value, SpatialReference): srs = value - elif isinstance(value, six.integer_types + six.string_types): + elif isinstance(value, (int, str)): srs = SpatialReference(value) else: raise ValueError('Could not create a SpatialReference from input.') diff --git a/django/contrib/gis/gdal/srs.py b/django/contrib/gis/gdal/srs.py index 635cdc2b5a6b..9dc9080de766 100644 --- a/django/contrib/gis/gdal/srs.py +++ b/django/contrib/gis/gdal/srs.py @@ -31,7 +31,6 @@ from django.contrib.gis.gdal.base import GDALBase from django.contrib.gis.gdal.error import SRSException from django.contrib.gis.gdal.prototypes import srs as capi -from django.utils import six from django.utils.encoding import force_bytes, force_text @@ -55,7 +54,7 @@ def __init__(self, srs_input='', srs_type='user'): self.ptr = capi.new_srs(c_char_p(b'')) self.import_wkt(srs_input) return - elif isinstance(srs_input, six.string_types): + elif isinstance(srs_input, str): try: # If SRID is a string, e.g., '4326', then make acceptable # as user input. @@ -63,7 +62,7 @@ def __init__(self, srs_input='', srs_type='user'): srs_input = 'EPSG:%d' % srid except ValueError: pass - elif isinstance(srs_input, six.integer_types): + elif isinstance(srs_input, int): # EPSG integer code was input. srs_type = 'epsg' elif isinstance(srs_input, self.ptr_type): @@ -130,7 +129,7 @@ def attr_value(self, target, index=0): The attribute value for the given target node (e.g. 'PROJCS'). The index keyword specifies an index of the child node to return. """ - if not isinstance(target, six.string_types) or not isinstance(index, int): + if not isinstance(target, str) or not isinstance(index, int): raise TypeError return capi.get_attr_value(self.ptr, force_bytes(target), index) diff --git a/django/contrib/gis/geoip2/base.py b/django/contrib/gis/geoip2/base.py index 44164f1d71fd..1d1e2e00dc4f 100644 --- a/django/contrib/gis/geoip2/base.py +++ b/django/contrib/gis/geoip2/base.py @@ -5,7 +5,6 @@ from django.conf import settings from django.core.validators import ipv4_re -from django.utils import six from django.utils.ipv6 import is_valid_ipv6_address from .resources import City, Country @@ -78,7 +77,7 @@ def __init__(self, path=None, cache=0, country=None, city=None): path = GEOIP_SETTINGS['GEOIP_PATH'] if not path: raise GeoIP2Exception('GeoIP path must be provided via parameter or the GEOIP_PATH setting.') - if not isinstance(path, six.string_types): + if not isinstance(path, str): raise TypeError('Invalid path type: %s' % type(path).__name__) if os.path.isdir(path): @@ -146,7 +145,7 @@ def __repr__(self): def _check_query(self, query, country=False, city=False, city_or_country=False): "Helper routine for checking the query and database availability." # Making sure a string was passed in for the query. - if not isinstance(query, six.string_types): + if not isinstance(query, str): raise TypeError('GeoIP query must be a string, not type %s' % type(query).__name__) # Extra checks for the existence of country and city databases. diff --git a/django/contrib/gis/geos/factory.py b/django/contrib/gis/geos/factory.py index eb06da2c00d6..42cd10c75625 100644 --- a/django/contrib/gis/geos/factory.py +++ b/django/contrib/gis/geos/factory.py @@ -8,7 +8,7 @@ def fromfile(file_h): WKT, or HEX. """ # If given a file name, get a real handle. - if isinstance(file_h, six.string_types): + if isinstance(file_h, str): with open(file_h, 'rb') as file_h: buf = file_h.read() else: diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py index deadbfaaf279..f7bdf8937f5f 100644 --- a/django/contrib/gis/geos/geometry.py +++ b/django/contrib/gis/geos/geometry.py @@ -49,7 +49,7 @@ def __init__(self, geo_input, srid=None): """ if isinstance(geo_input, bytes): geo_input = force_text(geo_input) - if isinstance(geo_input, six.string_types): + if isinstance(geo_input, str): wkt_m = wkt_regex.match(geo_input) if wkt_m: # Handling WKT input. @@ -63,7 +63,7 @@ def __init__(self, geo_input, srid=None): # Handling GeoJSON input. g = wkb_r().read(gdal.OGRGeometry(geo_input).wkb) else: - raise ValueError('String or unicode input unrecognized as WKT EWKT, and HEXEWKB.') + raise ValueError('String input unrecognized as WKT EWKT, and HEXEWKB.') elif isinstance(geo_input, GEOM_PTR): # When the input is a pointer to a geometry (GEOM_PTR). g = geo_input @@ -169,7 +169,7 @@ def __eq__(self, other): Equivalence testing, a Geometry may be compared with another Geometry or an EWKT representation. """ - if isinstance(other, six.string_types): + if isinstance(other, str): if other.startswith('SRID=0;'): return self.ewkt == other[7:] # Test only WKT part of other return self.ewkt == other @@ -348,7 +348,7 @@ def relate_pattern(self, other, pattern): Returns true if the elements in the DE-9IM intersection matrix for the two Geometries match the elements in pattern. """ - if not isinstance(pattern, six.string_types) or len(pattern) > 9: + if not isinstance(pattern, str) or len(pattern) > 9: raise GEOSException('invalid intersection matrix pattern') return capi.geos_relatepattern(self.ptr, other.ptr, force_bytes(pattern)) diff --git a/django/contrib/gis/geos/mutable_list.py b/django/contrib/gis/geos/mutable_list.py index 8a613600c0d7..8896ebc51835 100644 --- a/django/contrib/gis/geos/mutable_list.py +++ b/django/contrib/gis/geos/mutable_list.py @@ -10,7 +10,6 @@ """ from functools import total_ordering -from django.utils import six from django.utils.six.moves import range @@ -82,12 +81,12 @@ def __getitem__(self, index): def __delitem__(self, index): "Delete the item(s) at the specified index/slice." - if not isinstance(index, six.integer_types + (slice,)): + if not isinstance(index, (int, slice)): raise TypeError("%s is not a legal index" % index) # calculate new length and dimensions origLen = len(self) - if isinstance(index, six.integer_types): + if isinstance(index, int): index = self._checkindex(index) indexRange = [index] else: @@ -195,7 +194,7 @@ def extend(self, vals): def insert(self, index, val): "Standard list insert method" - if not isinstance(index, six.integer_types): + if not isinstance(index, int): raise TypeError("%s is not a legal index" % index) self[index:index] = [val] diff --git a/django/contrib/gis/geos/point.py b/django/contrib/gis/geos/point.py index ec95cf1f637c..fadf5eb41420 100644 --- a/django/contrib/gis/geos/point.py +++ b/django/contrib/gis/geos/point.py @@ -4,7 +4,6 @@ from django.contrib.gis.geos import prototypes as capi from django.contrib.gis.geos.error import GEOSException from django.contrib.gis.geos.geometry import GEOSGeometry -from django.utils import six from django.utils.six.moves import range @@ -27,9 +26,9 @@ def __init__(self, x=None, y=None, z=None, srid=None): elif isinstance(x, (tuple, list)): # Here a tuple or list was passed in under the `x` parameter. coords = x - elif isinstance(x, six.integer_types + (float,)) and isinstance(y, six.integer_types + (float,)): + elif isinstance(x, (float, int)) and isinstance(y, (float, int)): # Here X, Y, and (optionally) Z were passed in individually, as parameters. - if isinstance(z, six.integer_types + (float,)): + if isinstance(z, (float, int)): coords = [x, y, z] else: coords = [x, y] diff --git a/django/contrib/gis/geos/polygon.py b/django/contrib/gis/geos/polygon.py index 434e27b4d97c..0b4de0d3c302 100644 --- a/django/contrib/gis/geos/polygon.py +++ b/django/contrib/gis/geos/polygon.py @@ -4,7 +4,6 @@ from django.contrib.gis.geos.geometry import GEOSGeometry from django.contrib.gis.geos.libgeos import GEOM_PTR, get_pointer_arr from django.contrib.gis.geos.linestring import LinearRing -from django.utils import six from django.utils.six.moves import range @@ -63,7 +62,7 @@ def from_bbox(cls, bbox): "Constructs a Polygon from a bounding box (4-tuple)." x0, y0, x1, y1 = bbox for z in bbox: - if not isinstance(z, six.integer_types + (float,)): + if not isinstance(z, (float, int)): return GEOSGeometry('POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))' % (x0, y0, x0, y1, x1, y1, x1, y0, x0, y0)) return Polygon(((x0, y0), (x0, y1), (x1, y1), (x1, y0), (x0, y0))) diff --git a/django/contrib/gis/geos/prototypes/io.py b/django/contrib/gis/geos/prototypes/io.py index c932a1a15f6f..1cc0ccb8f34a 100644 --- a/django/contrib/gis/geos/prototypes/io.py +++ b/django/contrib/gis/geos/prototypes/io.py @@ -135,7 +135,7 @@ class _WKTReader(IOBase): destructor = wkt_reader_destroy def read(self, wkt): - if not isinstance(wkt, (bytes, six.string_types)): + if not isinstance(wkt, (bytes, str)): raise TypeError return wkt_reader_read(self.ptr, force_bytes(wkt)) @@ -150,7 +150,7 @@ def read(self, wkb): if isinstance(wkb, six.memoryview): wkb_s = bytes(wkb) return wkb_reader_read(self.ptr, wkb_s, len(wkb_s)) - elif isinstance(wkb, (bytes, six.string_types)): + elif isinstance(wkb, (bytes, str)): return wkb_reader_read_hex(self.ptr, wkb, len(wkb)) else: raise TypeError diff --git a/django/contrib/gis/measure.py b/django/contrib/gis/measure.py index 71bc5ff83bc0..8691d009a630 100644 --- a/django/contrib/gis/measure.py +++ b/django/contrib/gis/measure.py @@ -42,7 +42,7 @@ __all__ = ['A', 'Area', 'D', 'Distance'] -NUMERIC_TYPES = six.integer_types + (float, Decimal) +NUMERIC_TYPES = (int, float, Decimal) AREA_PREFIX = "sq_" @@ -60,7 +60,7 @@ class MeasureBase(object): def __init__(self, default_unit=None, **kwargs): value, self._default_unit = self.default_units(kwargs) setattr(self, self.STANDARD_UNIT, value) - if default_unit and isinstance(default_unit, six.string_types): + if default_unit and isinstance(default_unit, str): self._default_unit = default_unit def _get_standard(self): diff --git a/django/contrib/gis/utils/layermapping.py b/django/contrib/gis/utils/layermapping.py index 22d7dd2579c2..a10e9bbeb89d 100644 --- a/django/contrib/gis/utils/layermapping.py +++ b/django/contrib/gis/utils/layermapping.py @@ -89,7 +89,7 @@ def __init__(self, model, data, mapping, layer=0, argument usage. """ # Getting the DataSource and the associated Layer. - if isinstance(data, six.string_types): + if isinstance(data, str): self.ds = DataSource(data, encoding=encoding) else: self.ds = data @@ -266,7 +266,7 @@ def check_srs(self, source_srs): sr = source_srs elif isinstance(source_srs, self.spatial_backend.spatial_ref_sys()): sr = source_srs.srs - elif isinstance(source_srs, (int, six.string_types)): + elif isinstance(source_srs, (int, str)): sr = SpatialReference(source_srs) else: # Otherwise just pulling the SpatialReference from the layer @@ -284,7 +284,7 @@ def check_unique(self, unique): for attr in unique: if attr not in self.mapping: raise ValueError - elif isinstance(unique, six.string_types): + elif isinstance(unique, str): # Only a single field passed in. if unique not in self.mapping: raise ValueError @@ -331,7 +331,7 @@ def unique_kwargs(self, kwargs): will construct and return the uniqueness keyword arguments -- a subset of the feature kwargs. """ - if isinstance(self.unique, six.string_types): + if isinstance(self.unique, str): return {self.unique: kwargs[self.unique]} else: return {fld: kwargs[fld] for fld in self.unique} diff --git a/django/contrib/gis/utils/ogrinspect.py b/django/contrib/gis/utils/ogrinspect.py index 71e4c6487844..c10364491dc5 100644 --- a/django/contrib/gis/utils/ogrinspect.py +++ b/django/contrib/gis/utils/ogrinspect.py @@ -8,7 +8,6 @@ OFTDate, OFTDateTime, OFTInteger, OFTInteger64, OFTReal, OFTString, OFTTime, ) -from django.utils import six from django.utils.six.moves import zip @@ -26,7 +25,7 @@ def mapping(data_source, geom_name='geom', layer_key=0, multi_geom=False): `multi_geom` => Boolean (default: False) - specify as multigeometry. """ - if isinstance(data_source, six.string_types): + if isinstance(data_source, str): # Instantiating the DataSource from the string. data_source = DataSource(data_source) elif isinstance(data_source, DataSource): @@ -129,7 +128,7 @@ def _ogrinspect(data_source, model_name, geom_name='geom', layer_key=0, srid=Non to the given data source. See the `ogrinspect` docstring for more details. """ # Getting the DataSource - if isinstance(data_source, six.string_types): + if isinstance(data_source, str): data_source = DataSource(data_source) elif isinstance(data_source, DataSource): pass diff --git a/django/contrib/messages/storage/session.py b/django/contrib/messages/storage/session.py index 624de42b8ced..2eb8024bfa08 100644 --- a/django/contrib/messages/storage/session.py +++ b/django/contrib/messages/storage/session.py @@ -5,7 +5,6 @@ from django.contrib.messages.storage.cookie import ( MessageDecoder, MessageEncoder, ) -from django.utils import six class SessionStorage(BaseStorage): @@ -44,6 +43,6 @@ def serialize_messages(self, messages): return encoder.encode(messages) def deserialize_messages(self, data): - if data and isinstance(data, six.string_types): + if data and isinstance(data, str): return json.loads(data, cls=MessageDecoder) return data diff --git a/django/contrib/postgres/fields/array.py b/django/contrib/postgres/fields/array.py index b70ae37a3af4..dc5b9b8d6b71 100644 --- a/django/contrib/postgres/fields/array.py +++ b/django/contrib/postgres/fields/array.py @@ -6,7 +6,6 @@ from django.core import checks, exceptions from django.db.models import Field, IntegerField, Transform from django.db.models.lookups import Exact, In -from django.utils import six from django.utils.translation import ugettext_lazy as _ from ..utils import prefix_validation_error @@ -98,7 +97,7 @@ def deconstruct(self): return name, path, args, kwargs def to_python(self, value): - if isinstance(value, six.string_types): + if isinstance(value, str): # Assume we're deserializing vals = json.loads(value) value = [self.base_field.to_python(val) for val in vals] diff --git a/django/contrib/postgres/fields/hstore.py b/django/contrib/postgres/fields/hstore.py index 605deaf62c53..fcd212bc4a4a 100644 --- a/django/contrib/postgres/fields/hstore.py +++ b/django/contrib/postgres/fields/hstore.py @@ -4,7 +4,6 @@ from django.contrib.postgres.fields.array import ArrayField from django.core import exceptions from django.db.models import Field, TextField, Transform -from django.utils import six from django.utils.encoding import force_text from django.utils.translation import ugettext_lazy as _ @@ -30,7 +29,7 @@ def get_transform(self, name): def validate(self, value, model_instance): super(HStoreField, self).validate(value, model_instance) for key, val in value.items(): - if not isinstance(val, six.string_types) and val is not None: + if not isinstance(val, str) and val is not None: raise exceptions.ValidationError( self.error_messages['not_a_string'], code='not_a_string', @@ -38,7 +37,7 @@ def validate(self, value, model_instance): ) def to_python(self, value): - if isinstance(value, six.string_types): + if isinstance(value, str): value = json.loads(value) return value diff --git a/django/contrib/postgres/fields/ranges.py b/django/contrib/postgres/fields/ranges.py index ab7708d288c1..840417a58f96 100644 --- a/django/contrib/postgres/fields/ranges.py +++ b/django/contrib/postgres/fields/ranges.py @@ -4,7 +4,6 @@ from django.contrib.postgres import forms, lookups from django.db import models -from django.utils import six from .utils import AttributeSetter @@ -45,7 +44,7 @@ def get_prep_value(self, value): return value def to_python(self, value): - if isinstance(value, six.string_types): + if isinstance(value, str): # Assume we're deserializing vals = json.loads(value) for end in ('lower', 'upper'): diff --git a/django/contrib/postgres/forms/array.py b/django/contrib/postgres/forms/array.py index 9830c8de4878..9a9e871a438d 100644 --- a/django/contrib/postgres/forms/array.py +++ b/django/contrib/postgres/forms/array.py @@ -6,7 +6,6 @@ ArrayMaxLengthValidator, ArrayMinLengthValidator, ) from django.core.exceptions import ValidationError -from django.utils import six from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ @@ -31,7 +30,7 @@ def __init__(self, base_field, delimiter=',', max_length=None, min_length=None, def prepare_value(self, value): if isinstance(value, list): - return self.delimiter.join(six.text_type(self.base_field.prepare_value(v)) for v in value) + return self.delimiter.join(str(self.base_field.prepare_value(v)) for v in value) return value def to_python(self, value): diff --git a/django/contrib/postgres/forms/hstore.py b/django/contrib/postgres/forms/hstore.py index 76d362999d54..25dceb9fb015 100644 --- a/django/contrib/postgres/forms/hstore.py +++ b/django/contrib/postgres/forms/hstore.py @@ -2,7 +2,6 @@ from django import forms from django.core.exceptions import ValidationError -from django.utils import six from django.utils.translation import ugettext_lazy as _ __all__ = ['HStoreField'] @@ -44,7 +43,7 @@ def to_python(self, value): # Cast everything to strings for ease. for key, val in value.items(): if val is not None: - val = six.text_type(val) + val = str(val) value[key] = val return value diff --git a/django/contrib/postgres/forms/jsonb.py b/django/contrib/postgres/forms/jsonb.py index 719de3ae664a..28429c717224 100644 --- a/django/contrib/postgres/forms/jsonb.py +++ b/django/contrib/postgres/forms/jsonb.py @@ -1,17 +1,16 @@ import json from django import forms -from django.utils import six from django.utils.translation import ugettext_lazy as _ __all__ = ['JSONField'] -class InvalidJSONInput(six.text_type): +class InvalidJSONInput(str): pass -class JSONString(six.text_type): +class JSONString(str): pass @@ -36,7 +35,7 @@ def to_python(self, value): code='invalid', params={'value': value}, ) - if isinstance(converted, six.text_type): + if isinstance(converted, str): return JSONString(converted) else: return converted diff --git a/django/core/cache/backends/memcached.py b/django/core/cache/backends/memcached.py index 4cf25fb4c6b0..82589a82b087 100644 --- a/django/core/cache/backends/memcached.py +++ b/django/core/cache/backends/memcached.py @@ -6,7 +6,6 @@ import warnings from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache -from django.utils import six from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_str from django.utils.functional import cached_property @@ -15,7 +14,7 @@ class BaseMemcachedCache(BaseCache): def __init__(self, server, params, library, value_not_found_exception): super(BaseMemcachedCache, self).__init__(params) - if isinstance(server, six.string_types): + if isinstance(server, str): self._servers = re.split('[;,]', server) else: self._servers = server diff --git a/django/core/checks/templates.py b/django/core/checks/templates.py index bf526c871ebc..6f60d33bd0df 100644 --- a/django/core/checks/templates.py +++ b/django/core/checks/templates.py @@ -1,7 +1,6 @@ import copy from django.conf import settings -from django.utils import six from . import Error, Tags, register @@ -32,7 +31,7 @@ def check_string_if_invalid_is_string(app_configs, **kwargs): errors = [] for conf in settings.TEMPLATES: string_if_invalid = conf.get('OPTIONS', {}).get('string_if_invalid', '') - if not isinstance(string_if_invalid, six.string_types): + if not isinstance(string_if_invalid, str): error = copy.copy(E002) error.msg = error.msg.format(string_if_invalid, type(string_if_invalid).__name__) errors.append(error) diff --git a/django/core/checks/urls.py b/django/core/checks/urls.py index d721bc901f53..c39010fb7d3e 100644 --- a/django/core/checks/urls.py +++ b/django/core/checks/urls.py @@ -1,7 +1,6 @@ from collections import Counter from django.conf import settings -from django.utils import six from . import Error, Tags, Warning, register @@ -72,7 +71,7 @@ def get_warning_for_invalid_pattern(pattern): describe_pattern() cannot be used here, because we cannot rely on the urlpattern having regex or name attributes. """ - if isinstance(pattern, six.string_types): + if isinstance(pattern, str): hint = ( "Try removing the string '{}'. The list of urlpatterns should not " "have a prefix string as the first element.".format(pattern) diff --git a/django/core/files/base.py b/django/core/files/base.py index dd07bc959a43..df29c94eee39 100644 --- a/django/core/files/base.py +++ b/django/core/files/base.py @@ -2,7 +2,6 @@ from io import BytesIO, StringIO, UnsupportedOperation from django.core.files.utils import FileProxyMixin -from django.utils import six from django.utils.encoding import force_str, force_text @@ -140,7 +139,7 @@ class ContentFile(File): A File-like object that takes just raw content, rather than an actual file. """ def __init__(self, content, name=None): - stream_class = StringIO if isinstance(content, six.text_type) else BytesIO + stream_class = StringIO if isinstance(content, str) else BytesIO super(ContentFile, self).__init__(stream_class(content), name=name) self.size = len(content) @@ -164,18 +163,18 @@ def endswith_cr(line): """ Return True if line (a text or byte string) ends with '\r'. """ - return line.endswith('\r' if isinstance(line, six.text_type) else b'\r') + return line.endswith('\r' if isinstance(line, str) else b'\r') def endswith_lf(line): """ Return True if line (a text or byte string) ends with '\n'. """ - return line.endswith('\n' if isinstance(line, six.text_type) else b'\n') + return line.endswith('\n' if isinstance(line, str) else b'\n') def equals_lf(line): """ Return True if line (a text or byte string) equals '\n'. """ - return line == ('\n' if isinstance(line, six.text_type) else b'\n') + return line == ('\n' if isinstance(line, str) else b'\n') diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py index b37716b62c74..c45023d1290c 100644 --- a/django/core/handlers/base.py +++ b/django/core/handlers/base.py @@ -5,7 +5,6 @@ from django.core.exceptions import ImproperlyConfigured, MiddlewareNotUsed from django.db import connections, transaction from django.urls import get_resolver, set_urlconf -from django.utils import six from django.utils.module_loading import import_string from .exception import convert_exception_to_response, get_exception_response @@ -42,7 +41,7 @@ def load_middleware(self): mw_instance = middleware(handler) except MiddlewareNotUsed as exc: if settings.DEBUG: - if six.text_type(exc): + if str(exc): logger.debug('MiddlewareNotUsed(%r): %s', middleware_path, exc) else: logger.debug('MiddlewareNotUsed: %r', middleware_path) diff --git a/django/core/mail/backends/filebased.py b/django/core/mail/backends/filebased.py index cfe033fb4873..40dc9ff7cc0d 100644 --- a/django/core/mail/backends/filebased.py +++ b/django/core/mail/backends/filebased.py @@ -7,7 +7,6 @@ from django.core.exceptions import ImproperlyConfigured from django.core.mail.backends.console import \ EmailBackend as ConsoleEmailBackend -from django.utils import six class EmailBackend(ConsoleEmailBackend): @@ -18,7 +17,7 @@ def __init__(self, *args, **kwargs): else: self.file_path = getattr(settings, 'EMAIL_FILE_PATH', None) # Make sure self.file_path is a string. - if not isinstance(self.file_path, six.string_types): + if not isinstance(self.file_path, str): raise ImproperlyConfigured('Path for saving emails is invalid: %r' % self.file_path) self.file_path = os.path.abspath(self.file_path) # Make sure that self.file_path is an directory if it exists. diff --git a/django/core/mail/message.py b/django/core/mail/message.py index c4df44fa9d7e..a8ea1f099198 100644 --- a/django/core/mail/message.py +++ b/django/core/mail/message.py @@ -244,25 +244,25 @@ def __init__(self, subject='', body='', from_email=None, to=None, bcc=None, necessary encoding conversions. """ if to: - if isinstance(to, six.string_types): + if isinstance(to, str): raise TypeError('"to" argument must be a list or tuple') self.to = list(to) else: self.to = [] if cc: - if isinstance(cc, six.string_types): + if isinstance(cc, str): raise TypeError('"cc" argument must be a list or tuple') self.cc = list(cc) else: self.cc = [] if bcc: - if isinstance(bcc, six.string_types): + if isinstance(bcc, str): raise TypeError('"bcc" argument must be a list or tuple') self.bcc = list(bcc) else: self.bcc = [] if reply_to: - if isinstance(reply_to, six.string_types): + if isinstance(reply_to, str): raise TypeError('"reply_to" argument must be a list or tuple') self.reply_to = list(reply_to) else: @@ -352,7 +352,7 @@ def attach(self, filename=None, content=None, mimetype=None): basetype, subtype = mimetype.split('/', 1) if basetype == 'text': - if isinstance(content, six.binary_type): + if isinstance(content, bytes): try: content = content.decode('utf-8') except UnicodeDecodeError: diff --git a/django/core/management/utils.py b/django/core/management/utils.py index 0fb8b0d25f71..07a14bd73139 100644 --- a/django/core/management/utils.py +++ b/django/core/management/utils.py @@ -55,7 +55,7 @@ def handle_extensions(extensions): def find_command(cmd, path=None, pathext=None): if path is None: path = os.environ.get('PATH', '').split(os.pathsep) - if isinstance(path, six.string_types): + if isinstance(path, str): path = [path] # check if there are funny path extensions for executables, e.g. Windows if pathext is None: diff --git a/django/core/paginator.py b/django/core/paginator.py index c77a62a1fe31..ae085bf83763 100644 --- a/django/core/paginator.py +++ b/django/core/paginator.py @@ -130,7 +130,7 @@ def __len__(self): return len(self.object_list) def __getitem__(self, index): - if not isinstance(index, (slice,) + six.integer_types): + if not isinstance(index, (int, slice)): raise TypeError # The object_list is converted to a list so that if it was a QuerySet # it won't be a database hit per __getitem__. diff --git a/django/core/serializers/base.py b/django/core/serializers/base.py index 46fb25ea7864..2a10fbe19edf 100644 --- a/django/core/serializers/base.py +++ b/django/core/serializers/base.py @@ -168,7 +168,7 @@ def __init__(self, stream_or_string, **options): Init this serializer given a stream or a string """ self.options = options - if isinstance(stream_or_string, six.string_types): + if isinstance(stream_or_string, str): self.stream = six.StringIO(stream_or_string) else: self.stream = stream_or_string diff --git a/django/core/serializers/json.py b/django/core/serializers/json.py index b335605785f8..b87d80757143 100644 --- a/django/core/serializers/json.py +++ b/django/core/serializers/json.py @@ -69,7 +69,7 @@ def Deserializer(stream_or_string, **options): """ Deserialize a stream or string of JSON data. """ - if not isinstance(stream_or_string, (bytes, six.string_types)): + if not isinstance(stream_or_string, (bytes, str)): stream_or_string = stream_or_string.read() if isinstance(stream_or_string, bytes): stream_or_string = stream_or_string.decode('utf-8') @@ -108,11 +108,7 @@ def default(self, o): return r elif isinstance(o, datetime.timedelta): return duration_iso_string(o) - elif isinstance(o, decimal.Decimal): + elif isinstance(o, (decimal.Decimal, uuid.UUID, Promise)): return str(o) - elif isinstance(o, uuid.UUID): - return str(o) - elif isinstance(o, Promise): - return six.text_type(o) else: return super(DjangoJSONEncoder, self).default(o) diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py index a0cea1429731..9db5c2e6a675 100644 --- a/django/core/serializers/python.py +++ b/django/core/serializers/python.py @@ -131,7 +131,7 @@ def Deserializer(object_list, **options): model = field.remote_field.model if hasattr(model._default_manager, 'get_by_natural_key'): def m2m_convert(value): - if hasattr(value, '__iter__') and not isinstance(value, six.text_type): + if hasattr(value, '__iter__') and not isinstance(value, str): return model._default_manager.db_manager(db).get_by_natural_key(*value).pk else: return force_text(model._meta.pk.to_python(value), strings_only=True) @@ -154,7 +154,7 @@ def m2m_convert(v): default_manager = model._default_manager field_name = field.remote_field.field_name if hasattr(default_manager, 'get_by_natural_key'): - if hasattr(field_value, '__iter__') and not isinstance(field_value, six.text_type): + if hasattr(field_value, '__iter__') and not isinstance(field_value, str): obj = default_manager.db_manager(db).get_by_natural_key(*field_value) value = getattr(obj, field.remote_field.field_name) # If this is a natural foreign key to an object that diff --git a/django/core/serializers/pyyaml.py b/django/core/serializers/pyyaml.py index 5dc847d4f5b8..16583782b9ac 100644 --- a/django/core/serializers/pyyaml.py +++ b/django/core/serializers/pyyaml.py @@ -71,7 +71,7 @@ def Deserializer(stream_or_string, **options): """ if isinstance(stream_or_string, bytes): stream_or_string = stream_or_string.decode('utf-8') - if isinstance(stream_or_string, six.string_types): + if isinstance(stream_or_string, str): stream = StringIO(stream_or_string) else: stream = stream_or_string diff --git a/django/core/validators.py b/django/core/validators.py index 221f3e0934c7..e2fcd6f72e1c 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -2,7 +2,6 @@ import re from django.core.exceptions import ValidationError -from django.utils import six from django.utils.deconstruct import deconstructible from django.utils.encoding import force_text from django.utils.functional import SimpleLazyObject @@ -18,7 +17,7 @@ def _lazy_re_compile(regex, flags=0): """Lazily compile a regex with flags.""" def _compile(): # Compile the regex if it was not passed pre-compiled. - if isinstance(regex, six.string_types): + if isinstance(regex, str): return re.compile(regex, flags) else: assert not flags, "flags must be empty if regex is passed pre-compiled" @@ -45,7 +44,7 @@ def __init__(self, regex=None, message=None, code=None, inverse_match=None, flag self.inverse_match = inverse_match if flags is not None: self.flags = flags - if self.flags and not isinstance(self.regex, six.string_types): + if self.flags and not isinstance(self.regex, str): raise TypeError("If the flags are set, regex must be a regular expression string.") self.regex = _lazy_re_compile(self.regex, self.flags) diff --git a/django/db/backends/base/operations.py b/django/db/backends/base/operations.py index 0539d7153907..6f1248efc140 100644 --- a/django/db/backends/base/operations.py +++ b/django/db/backends/base/operations.py @@ -5,7 +5,7 @@ from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.db.backends import utils -from django.utils import six, timezone +from django.utils import timezone from django.utils.dateparse import parse_duration from django.utils.encoding import force_text @@ -201,17 +201,17 @@ def last_executed_query(self, cursor, sql, params): exists for database backends to provide a better implementation according to their own quoting schemes. """ - # Convert params to contain Unicode values. - def to_unicode(s): + # Convert params to contain string values. + def to_string(s): return force_text(s, strings_only=True, errors='replace') if isinstance(params, (list, tuple)): - u_params = tuple(to_unicode(val) for val in params) + u_params = tuple(to_string(val) for val in params) elif params is None: u_params = () else: - u_params = {to_unicode(k): to_unicode(v) for k, v in params.items()} + u_params = {to_string(k): to_string(v) for k, v in params.items()} - return six.text_type("QUERY = %r - PARAMS = %r") % (sql, u_params) + return "QUERY = %r - PARAMS = %r" % (sql, u_params) def last_insert_id(self, cursor, table_name, pk_name): """ @@ -462,7 +462,7 @@ def adapt_datefield_value(self, value): """ if value is None: return None - return six.text_type(value) + return str(value) def adapt_datetimefield_value(self, value): """ @@ -471,7 +471,7 @@ def adapt_datetimefield_value(self, value): """ if value is None: return None - return six.text_type(value) + return str(value) def adapt_timefield_value(self, value): """ @@ -482,7 +482,7 @@ def adapt_timefield_value(self, value): return None if timezone.is_aware(value): raise ValueError("Django does not support timezone-aware times.") - return six.text_type(value) + return str(value) def adapt_decimalfield_value(self, value, max_digits=None, decimal_places=None): """ diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py index b00853b74d54..6cb6826a7fb9 100644 --- a/django/db/backends/base/schema.py +++ b/django/db/backends/base/schema.py @@ -4,7 +4,7 @@ from django.db.backends.utils import strip_quotes from django.db.transaction import TransactionManagementError, atomic -from django.utils import six, timezone +from django.utils import timezone from django.utils.encoding import force_bytes logger = logging.getLogger('django.db.backends.schema') @@ -206,9 +206,9 @@ def effective_default(self, field): default = field.get_default() elif not field.null and field.blank and field.empty_strings_allowed: if field.get_internal_type() == "BinaryField": - default = six.binary_type() + default = bytes() else: - default = six.text_type() + default = str() elif getattr(field, 'auto_now', False) or getattr(field, 'auto_now_add', False): default = datetime.now() internal_type = field.get_internal_type() diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 495ca33221cd..f674687ff186 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -256,7 +256,7 @@ def get_connection_params(self): def get_new_connection(self, conn_params): conn = Database.connect(**conn_params) - conn.encoders[SafeText] = conn.encoders[six.text_type] + conn.encoders[SafeText] = conn.encoders[str] conn.encoders[SafeBytes] = conn.encoders[bytes] return conn diff --git a/django/db/backends/mysql/operations.py b/django/db/backends/mysql/operations.py index 4edc9272a964..acb86c62ace9 100644 --- a/django/db/backends/mysql/operations.py +++ b/django/db/backends/mysql/operations.py @@ -2,7 +2,7 @@ from django.conf import settings from django.db.backends.base.operations import BaseDatabaseOperations -from django.utils import six, timezone +from django.utils import timezone from django.utils.encoding import force_text @@ -168,7 +168,7 @@ def adapt_datetimefield_value(self, value): if not self.connection.features.supports_microsecond_precision: value = value.replace(microsecond=0) - return six.text_type(value) + return str(value) def adapt_timefield_value(self, value): if value is None: @@ -182,7 +182,7 @@ def adapt_timefield_value(self, value): if timezone.is_aware(value): raise ValueError("MySQL backend does not support timezone-aware times.") - return six.text_type(value) + return str(value) def max_name_length(self): return 64 diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 317599253d39..c365c673c5b9 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -338,7 +338,7 @@ def __init__(self, param, cursor, strings_only=False): # To transmit to the database, we need Unicode if supported # To get size right, we must consider bytes. self.force_bytes = force_text(param, cursor.charset, strings_only) - if isinstance(self.force_bytes, six.string_types): + if isinstance(self.force_bytes, str): # We could optimize by only converting up to 4000 bytes here string_size = len(force_bytes(param, cursor.charset, strings_only)) if hasattr(param, 'input_size'): @@ -566,18 +566,5 @@ def _rowfactory(row, cursor): value = decimal.Decimal(value) else: value = int(value) - elif desc[1] in (Database.STRING, Database.FIXED_CHAR, - Database.LONG_STRING): - value = to_unicode(value) casted.append(value) return tuple(casted) - - -def to_unicode(s): - """ - Convert strings to Unicode objects (and return all other data types - unchanged). - """ - if isinstance(s, six.string_types): - return force_text(s) - return s diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py index 9878fbd9bb48..8d943199875a 100644 --- a/django/db/backends/oracle/operations.py +++ b/django/db/backends/oracle/operations.py @@ -5,7 +5,7 @@ from django.conf import settings from django.db.backends.base.operations import BaseDatabaseOperations from django.db.backends.utils import strip_quotes, truncate_name -from django.utils import six, timezone +from django.utils import timezone from django.utils.encoding import force_bytes, force_text from .base import Database @@ -490,7 +490,7 @@ def adapt_timefield_value(self, value): if hasattr(value, 'resolve_expression'): return value - if isinstance(value, six.string_types): + if isinstance(value, str): return datetime.datetime.strptime(value, '%H:%M:%S') # Oracle doesn't support tz-aware times diff --git a/django/db/backends/oracle/schema.py b/django/db/backends/oracle/schema.py index 15d361bf7a2d..44a1f3cd8d7d 100644 --- a/django/db/backends/oracle/schema.py +++ b/django/db/backends/oracle/schema.py @@ -5,7 +5,6 @@ from django.db.backends.base.schema import BaseDatabaseSchemaEditor from django.db.utils import DatabaseError -from django.utils import six from django.utils.text import force_text @@ -23,9 +22,9 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): def quote_value(self, value): if isinstance(value, (datetime.date, datetime.time, datetime.datetime)): return "'%s'" % value - elif isinstance(value, six.string_types): - return "'%s'" % six.text_type(value).replace("\'", "\'\'") - elif isinstance(value, six.buffer_types): + elif isinstance(value, str): + return "'%s'" % value.replace("\'", "\'\'") + elif isinstance(value, (bytes, bytearray, memoryview)): return "'%s'" % force_text(binascii.hexlify(value)) elif isinstance(value, bool): return "1" if value else "0" diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py index de3aa400000b..44f81c8ba111 100644 --- a/django/db/backends/sqlite3/base.py +++ b/django/db/backends/sqlite3/base.py @@ -14,7 +14,7 @@ from django.db import utils from django.db.backends import utils as backend_utils from django.db.backends.base.base import BaseDatabaseWrapper -from django.utils import six, timezone +from django.utils import timezone from django.utils.dateparse import ( parse_date, parse_datetime, parse_duration, parse_time, ) @@ -425,12 +425,12 @@ def _sqlite_format_dtdelta(conn, lhs, rhs): - A string representing a datetime """ try: - if isinstance(lhs, six.integer_types): + if isinstance(lhs, int): lhs = str(decimal.Decimal(lhs) / decimal.Decimal(1000000)) real_lhs = parse_duration(lhs) if real_lhs is None: real_lhs = backend_utils.typecast_timestamp(lhs) - if isinstance(rhs, six.integer_types): + if isinstance(rhs, int): rhs = str(decimal.Decimal(rhs) / decimal.Decimal(1000000)) real_rhs = parse_duration(rhs) if real_rhs is None: diff --git a/django/db/backends/sqlite3/operations.py b/django/db/backends/sqlite3/operations.py index 529db944519b..64486be737a3 100644 --- a/django/db/backends/sqlite3/operations.py +++ b/django/db/backends/sqlite3/operations.py @@ -7,7 +7,7 @@ from django.db.backends import utils as backend_utils from django.db.backends.base.operations import BaseDatabaseOperations from django.db.models import aggregates, fields -from django.utils import six, timezone +from django.utils import timezone from django.utils.dateparse import parse_date, parse_datetime, parse_time from django.utils.duration import duration_string @@ -178,7 +178,7 @@ def adapt_datetimefield_value(self, value): else: raise ValueError("SQLite backend does not support timezone-aware datetimes when USE_TZ is False.") - return six.text_type(value) + return str(value) def adapt_timefield_value(self, value): if value is None: @@ -192,7 +192,7 @@ def adapt_timefield_value(self, value): if timezone.is_aware(value): raise ValueError("SQLite backend does not support timezone-aware times.") - return six.text_type(value) + return str(value) def get_db_converters(self, expression): converters = super(DatabaseOperations, self).get_db_converters(expression) diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py index 36adb2258463..d74f59d21c64 100644 --- a/django/db/backends/sqlite3/schema.py +++ b/django/db/backends/sqlite3/schema.py @@ -5,7 +5,6 @@ from django.apps.registry import Apps from django.db.backends.base.schema import BaseDatabaseSchemaEditor -from django.utils import six class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): @@ -46,15 +45,13 @@ def quote_value(self, value): # Manual emulation of SQLite parameter quoting if isinstance(value, type(True)): return str(int(value)) - elif isinstance(value, (Decimal, float)): + elif isinstance(value, (Decimal, float, int)): return str(value) - elif isinstance(value, six.integer_types): - return str(value) - elif isinstance(value, six.string_types): - return "'%s'" % six.text_type(value).replace("\'", "\'\'") + elif isinstance(value, str): + return "'%s'" % value.replace("\'", "\'\'") elif value is None: return "NULL" - elif isinstance(value, (bytes, bytearray, six.memoryview)): + elif isinstance(value, (bytes, bytearray, memoryview)): # Bytes are only allowed for BLOB fields, encoded as string # literals containing hexadecimal data and preceded by a single "X" # character: diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py index 84ecf90b9eba..d2b6f6d49743 100644 --- a/django/db/migrations/autodetector.py +++ b/django/db/migrations/autodetector.py @@ -12,7 +12,6 @@ from django.db.migrations.utils import ( COMPILED_REGEX_TYPE, RegexObject, get_migration_name_timestamp, ) -from django.utils import six from .topological_sort import stable_topological_sort @@ -538,7 +537,7 @@ def generate_created_models(self): ] # Depend on all bases for base in model_state.bases: - if isinstance(base, six.string_types) and "." in base: + if isinstance(base, str) and "." in base: base_app_label, base_name = base.split(".", 1) dependencies.append((base_app_label, base_name, None, True)) # Depend on the other end of the primary key if it's a relation @@ -659,7 +658,7 @@ def generate_created_proxies(self): ] # Depend on all bases for base in model_state.bases: - if isinstance(base, six.string_types) and "." in base: + if isinstance(base, str) and "." in base: base_app_label, base_name = base.split(".", 1) dependencies.append((base_app_label, base_name, None, True)) # Generate creation operation diff --git a/django/db/migrations/operations/models.py b/django/db/migrations/operations/models.py index 783cfcc5198b..f37632458074 100644 --- a/django/db/migrations/operations/models.py +++ b/django/db/migrations/operations/models.py @@ -3,7 +3,6 @@ from django.db.migrations.state import ModelState from django.db.models.fields.related import RECURSIVE_RELATIONSHIP_CONSTANT from django.db.models.options import normalize_together -from django.utils import six from django.utils.functional import cached_property from .fields import ( @@ -57,7 +56,7 @@ def __init__(self, name, fields, options=None, bases=None, managers=None): _check_for_duplicates('fields', (name for name, _ in self.fields)) _check_for_duplicates('bases', ( base._meta.label_lower if hasattr(base, '_meta') else - base.lower() if isinstance(base, six.string_types) else base + base.lower() if isinstance(base, str) else base for base in self.bases )) _check_for_duplicates('managers', (name for name, _ in self.managers)) @@ -110,7 +109,7 @@ def references_model(self, name, app_label=None): # Check we didn't inherit from the model models_to_check = [ base for base in self.bases - if base is not models.Model and isinstance(base, (models.base.ModelBase, six.string_types)) + if base is not models.Model and isinstance(base, (models.base.ModelBase, str)) ] # Check we have no FKs/M2Ms with it for fname, field in self.fields: @@ -129,7 +128,7 @@ def model_to_key(self, model): Take either a model class or an "app_label.ModelName" string and return (app_label, object_name). """ - if isinstance(model, six.string_types): + if isinstance(model, str): return model.split(".", 1) else: return model._meta.app_label, model._meta.object_name diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index 261fcabd7393..bcd2268e2a1f 100644 --- a/django/db/migrations/serializer.py +++ b/django/db/migrations/serializer.py @@ -362,11 +362,11 @@ def serializer_factory(value): return SettingsReferenceSerializer(value) if isinstance(value, float): return FloatSerializer(value) - if isinstance(value, six.integer_types + (bool, type(None))): + if isinstance(value, (bool, int, type(None))): return BaseSimpleSerializer(value) - if isinstance(value, six.binary_type): + if isinstance(value, bytes): return ByteTypeSerializer(value) - if isinstance(value, six.text_type): + if isinstance(value, str): return TextTypeSerializer(value) if isinstance(value, decimal.Decimal): return DecimalSerializer(value) diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index c88663ff3a72..db42220918d7 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -10,7 +10,6 @@ from django.db.models.fields.related import RECURSIVE_RELATIONSHIP_CONSTANT from django.db.models.options import DEFAULT_NAMES, normalize_together from django.db.models.utils import make_model_tuple -from django.utils import six from django.utils.encoding import force_text from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -20,7 +19,7 @@ def _get_app_label_and_model_name(model, app_label=''): - if isinstance(model, six.string_types): + if isinstance(model, str): split = model.split('.', 1) return (tuple(split) if len(split) == 2 else (app_label, split[0])) else: @@ -37,7 +36,7 @@ def _get_related_models(m): ] related_fields_models = set() for f in m._meta.get_fields(include_parents=True, include_hidden=True): - if f.is_relation and f.related_model is not None and not isinstance(f.related_model, six.string_types): + if f.is_relation and f.related_model is not None and not isinstance(f.related_model, str): related_fields_models.add(f.model) related_models.append(f.related_model) # Reverse accessors of foreign keys to proxy models are attached to their @@ -458,7 +457,7 @@ def from_model(cls, model, exclude_rels=False): options[name] = set(normalize_together(it)) else: options[name] = model._meta.original_attrs[name] - # Force-convert all options to text_type (#23226) + # Force-convert all options to str (#23226) options = cls.force_text_recursive(options) # If we're ignoring relationships, remove all field-listing model # options (that option basically just means "make a stub model") @@ -496,7 +495,7 @@ def flatten_bases(model): for base in flattened_bases ) # Ensure at least one base inherits from models.Model - if not any((isinstance(base, six.string_types) or issubclass(base, models.Model)) for base in bases): + if not any((isinstance(base, str) or issubclass(base, models.Model)) for base in bases): bases = (models.Model,) managers = [] @@ -539,9 +538,7 @@ def flatten_bases(model): @classmethod def force_text_recursive(cls, value): - if isinstance(value, six.string_types): - return force_text(value) - elif isinstance(value, list): + if isinstance(value, list): return [cls.force_text_recursive(x) for x in value] elif isinstance(value, tuple): return tuple(cls.force_text_recursive(x) for x in value) @@ -588,7 +585,7 @@ def render(self, apps): # Then, work out our bases try: bases = tuple( - (apps.get_model(base) if isinstance(base, six.string_types) else base) + (apps.get_model(base) if isinstance(base, str) else base) for base in self.bases ) except LookupError: diff --git a/django/db/models/base.py b/django/db/models/base.py index 38d0b9621708..95700edb13c1 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -504,7 +504,7 @@ def from_db(cls, db, field_names, values): def __repr__(self): try: - u = six.text_type(self) + u = str(self) except (UnicodeEncodeError, UnicodeDecodeError): u = '[Bad Unicode data]' return force_str('<%s: %s>' % (self.__class__.__name__, u)) @@ -1089,12 +1089,12 @@ def date_error_message(self, lookup_type, field_name, unique_for): code='unique_for_date', params={ 'model': self, - 'model_name': six.text_type(capfirst(opts.verbose_name)), + 'model_name': capfirst(opts.verbose_name), 'lookup_type': lookup_type, 'field': field_name, - 'field_label': six.text_type(capfirst(field.verbose_name)), + 'field_label': capfirst(field.verbose_name), 'date_field': unique_for, - 'date_field_label': six.text_type(capfirst(opts.get_field(unique_for).verbose_name)), + 'date_field_label': capfirst(opts.get_field(unique_for).verbose_name), } ) @@ -1104,14 +1104,14 @@ def unique_error_message(self, model_class, unique_check): params = { 'model': self, 'model_class': model_class, - 'model_name': six.text_type(capfirst(opts.verbose_name)), + 'model_name': capfirst(opts.verbose_name), 'unique_check': unique_check, } # A unique field if len(unique_check) == 1: field = opts.get_field(unique_check[0]) - params['field_label'] = six.text_type(capfirst(field.verbose_name)) + params['field_label'] = capfirst(field.verbose_name) return ValidationError( message=field.error_messages['unique'], code='unique', @@ -1121,7 +1121,7 @@ def unique_error_message(self, model_class, unique_check): # unique_together else: field_labels = [capfirst(opts.get_field(f).verbose_name) for f in unique_check] - params['field_labels'] = six.text_type(get_text_list(field_labels, _('and'))) + params['field_labels'] = get_text_list(field_labels, _('and')) return ValidationError( message=_("%(model_name)s with this %(field_labels)s already exists."), code='unique_together', @@ -1647,7 +1647,7 @@ def _check_long_column_names(cls): for f in cls._meta.local_many_to_many: # Skip nonexistent models. - if isinstance(f.remote_field.through, six.string_types): + if isinstance(f.remote_field.through, str): continue # Check if auto-generated name for the M2M field is too long diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 36c2b969db12..960435f16966 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -5,7 +5,6 @@ from django.db.backends import utils as backend_utils from django.db.models import fields from django.db.models.query_utils import Q -from django.utils import six from django.utils.functional import cached_property @@ -149,7 +148,7 @@ def set_source_expressions(self, exprs): def _parse_expressions(self, *expressions): return [ arg if hasattr(arg, 'resolve_expression') else ( - F(arg) if isinstance(arg, six.string_types) else Value(arg) + F(arg) if isinstance(arg, str) else Value(arg) ) for arg in expressions ] diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 2e21a4267293..3ac04effc77a 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -19,7 +19,7 @@ from django.db import connection, connections, router from django.db.models.constants import LOOKUP_SEP from django.db.models.query_utils import DeferredAttribute, RegisterLookupMixin -from django.utils import six, timezone +from django.utils import timezone from django.utils.datastructures import DictWrapper from django.utils.dateparse import ( parse_date, parse_datetime, parse_duration, parse_time, @@ -244,8 +244,7 @@ def _check_field_name(self): def _check_choices(self): if self.choices: - if (isinstance(self.choices, six.string_types) or - not is_iterable(self.choices)): + if isinstance(self.choices, str) or not is_iterable(self.choices): return [ checks.Error( "'choices' must be an iterable (e.g., a list or tuple).", @@ -253,7 +252,7 @@ def _check_choices(self): id='fields.E004', ) ] - elif any(isinstance(choice, six.string_types) or + elif any(isinstance(choice, str) or not is_iterable(choice) or len(choice) != 2 for choice in self.choices): return [ @@ -763,7 +762,7 @@ def _get_default(self): if not self.empty_strings_allowed or self.null and not connection.features.interprets_empty_strings_as_nulls: return return_None - return six.text_type # returns empty string + return str # returns empty string def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH, limit_choices_to=None): """Returns choices with a default blank choices included, for use @@ -1038,7 +1037,7 @@ def _check_max_length_attribute(self, **kwargs): id='fields.E120', ) ] - elif not isinstance(self.max_length, six.integer_types) or self.max_length <= 0: + elif not isinstance(self.max_length, int) or self.max_length <= 0: return [ checks.Error( "'max_length' must be a positive integer.", @@ -1053,7 +1052,7 @@ def get_internal_type(self): return "CharField" def to_python(self, value): - if isinstance(value, six.string_types) or value is None: + if isinstance(value, str) or value is None: return value return force_text(value) @@ -1535,7 +1534,7 @@ def to_python(self, value): ) def _format(self, value): - if isinstance(value, six.string_types): + if isinstance(value, str): return value else: return self.format_number(value) @@ -1703,7 +1702,7 @@ def get_prep_value(self, value): value = super(FilePathField, self).get_prep_value(value) if value is None: return None - return six.text_type(value) + return str(value) def formfield(self, **kwargs): defaults = { @@ -1867,7 +1866,7 @@ def get_prep_value(self, value): value = super(IPAddressField, self).get_prep_value(value) if value is None: return None - return six.text_type(value) + return str(value) def get_internal_type(self): return "IPAddressField" @@ -1922,7 +1921,7 @@ def get_internal_type(self): def to_python(self, value): if value is None: return None - if not isinstance(value, six.string_types): + if not isinstance(value, str): value = force_text(value) value = value.strip() if ':' in value: @@ -1943,7 +1942,7 @@ def get_prep_value(self, value): return clean_ipv6_address(value, self.unpack_ipv4) except exceptions.ValidationError: pass - return six.text_type(value) + return str(value) def formfield(self, **kwargs): defaults = { @@ -2094,7 +2093,7 @@ def get_internal_type(self): return "TextField" def to_python(self, value): - if isinstance(value, six.string_types) or value is None: + if isinstance(value, str) or value is None: return value return force_text(value) @@ -2310,8 +2309,8 @@ def value_to_string(self, obj): def to_python(self, value): # If it's a string, it should be base64-encoded data - if isinstance(value, six.text_type): - return six.memoryview(b64decode(force_bytes(value))) + if isinstance(value, str): + return memoryview(b64decode(force_bytes(value))) return value diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index e52cc1164d1a..90b65154090e 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -9,7 +9,6 @@ from django.core.validators import validate_image_file_extension from django.db.models import signals from django.db.models.fields import Field -from django.utils import six from django.utils.encoding import force_str, force_text from django.utils.translation import ugettext_lazy as _ @@ -181,7 +180,7 @@ def __get__(self, instance, cls=None): # subclasses might also want to subclass the attribute class]. This # object understands how to convert a path to a file, and also how to # handle None. - if isinstance(file, six.string_types) or file is None: + if isinstance(file, str) or file is None: attr = self.field.attr_class(instance, self.field, file) instance.__dict__[self.field.name] = attr @@ -253,7 +252,7 @@ def _check_primary_key(self): return [] def _check_upload_to(self): - if isinstance(self.upload_to, six.string_types) and self.upload_to.startswith('/'): + if isinstance(self.upload_to, str) and self.upload_to.startswith('/'): return [ checks.Error( "%s's 'upload_to' argument must be a relative path, not an " @@ -284,7 +283,7 @@ def get_prep_value(self, value): # Need to convert File objects provided via a form to unicode for database insertion if value is None: return None - return six.text_type(value) + return str(value) def pre_save(self, model_instance, add): "Returns field's value just before saving." diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 7f7a6d3ea8d2..65d0da41e170 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -11,7 +11,6 @@ from django.db.models.deletion import CASCADE, SET_DEFAULT, SET_NULL from django.db.models.query_utils import PathInfo from django.db.models.utils import make_model_tuple -from django.utils import six from django.utils.encoding import force_text from django.utils.functional import cached_property, curry from django.utils.lru_cache import lru_cache @@ -52,7 +51,7 @@ def resolve_relation(scope_model, relation): relation = scope_model # Look for an "app.Model" relation - if isinstance(relation, six.string_types): + if isinstance(relation, str): if "." not in relation: relation = "%s.%s" % (scope_model._meta.app_label, relation) @@ -160,7 +159,7 @@ def _check_related_query_name_is_valid(self): def _check_relation_model_exists(self): rel_is_missing = self.remote_field.model not in self.opts.apps.get_models() - rel_is_string = isinstance(self.remote_field.model, six.string_types) + rel_is_string = isinstance(self.remote_field.model, str) model_name = self.remote_field.model if rel_is_string else self.remote_field.model._meta.object_name if rel_is_missing and (rel_is_string or not self.remote_field.model._meta.swapped): return [ @@ -175,7 +174,7 @@ def _check_relation_model_exists(self): def _check_referencing_to_swapped_model(self): if (self.remote_field.model not in self.opts.apps.get_models() and - not isinstance(self.remote_field.model, six.string_types) and + not isinstance(self.remote_field.model, str) and self.remote_field.model._meta.swapped): model = "%s.%s" % ( self.remote_field.model._meta.app_label, @@ -364,7 +363,7 @@ def swappable_setting(self): """ if self.swappable: # Work out string form of "to" - if isinstance(self.remote_field.model, six.string_types): + if isinstance(self.remote_field.model, str): to_string = self.remote_field.model else: to_string = self.remote_field.model._meta.label @@ -479,7 +478,7 @@ def check(self, **kwargs): def _check_to_fields_exist(self): # Skip nonexistent models. - if isinstance(self.remote_field.model, six.string_types): + if isinstance(self.remote_field.model, str): return [] errors = [] @@ -500,7 +499,7 @@ def _check_to_fields_exist(self): return errors def _check_unique_target(self): - rel_is_string = isinstance(self.remote_field.model, six.string_types) + rel_is_string = isinstance(self.remote_field.model, str) if rel_is_string or not self.requires_unique_target: return [] @@ -568,7 +567,7 @@ def deconstruct(self): if self.remote_field.parent_link: kwargs['parent_link'] = self.remote_field.parent_link # Work out string form of "to" - if isinstance(self.remote_field.model, six.string_types): + if isinstance(self.remote_field.model, str): kwargs['to'] = self.remote_field.model else: kwargs['to'] = "%s.%s" % ( @@ -598,7 +597,7 @@ def deconstruct(self): def resolve_related_fields(self): if len(self.from_fields) < 1 or len(self.from_fields) != len(self.to_fields): raise ValueError('Foreign Object from and to fields must be the same non-zero length') - if isinstance(self.remote_field.model, six.string_types): + if isinstance(self.remote_field.model, str): raise ValueError('Related model %r cannot be resolved' % self.remote_field.model) related_fields = [] for index in range(len(self.from_fields)): @@ -772,7 +771,7 @@ def __init__(self, to, on_delete, related_name=None, related_query_name=None, try: to._meta.model_name except AttributeError: - assert isinstance(to, six.string_types), ( + assert isinstance(to, str), ( "%s(%r) is invalid. First parameter to ForeignKey must be " "either a model, a model name, or the string %r" % ( self.__class__.__name__, to, @@ -926,7 +925,7 @@ def contribute_to_related_class(self, cls, related): def formfield(self, **kwargs): db = kwargs.pop('using', None) - if isinstance(self.remote_field.model, six.string_types): + if isinstance(self.remote_field.model, str): raise ValueError("Cannot create form field for %r yet, because " "its related model %r has not been loaded yet" % (self.name, self.remote_field.model)) @@ -948,7 +947,7 @@ def db_parameters(self, connection): return {"type": self.db_type(connection), "check": self.db_check(connection)} def convert_empty_strings(self, value, expression, connection, context): - if (not value) and isinstance(value, six.string_types): + if (not value) and isinstance(value, str): return None return value @@ -1082,14 +1081,11 @@ def __init__(self, to, related_name=None, related_query_name=None, try: to._meta except AttributeError: - assert isinstance(to, six.string_types), ( + assert isinstance(to, str), ( "%s(%r) is invalid. First parameter to ManyToManyField must be " "either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT) ) - # Class names must be ASCII in Python 2.x, so we forcibly coerce it - # here to break early if there's a problem. - to = str(to) if symmetrical is None: symmetrical = (to == RECURSIVE_RELATIONSHIP_CONSTANT) @@ -1197,7 +1193,7 @@ def _check_relationship_model(self, from_model=None, **kwargs): # Set some useful local variables to_model = resolve_relation(from_model, self.remote_field.model) from_model_name = from_model._meta.object_name - if isinstance(to_model, six.string_types): + if isinstance(to_model, str): to_model_name = to_model else: to_model_name = to_model._meta.object_name @@ -1368,7 +1364,7 @@ def _check_relationship_model(self, from_model=None, **kwargs): return errors def _check_table_uniqueness(self, **kwargs): - if isinstance(self.remote_field.through, six.string_types) or not self.remote_field.through._meta.managed: + if isinstance(self.remote_field.through, str) or not self.remote_field.through._meta.managed: return [] registered_tables = { model._meta.db_table: model @@ -1411,7 +1407,7 @@ def deconstruct(self): if self.remote_field.related_query_name is not None: kwargs['related_query_name'] = self.remote_field.related_query_name # Rel needs more work. - if isinstance(self.remote_field.model, six.string_types): + if isinstance(self.remote_field.model, str): kwargs['to'] = self.remote_field.model else: kwargs['to'] = "%s.%s" % ( @@ -1419,7 +1415,7 @@ def deconstruct(self): self.remote_field.model._meta.object_name, ) if getattr(self.remote_field, 'through', None) is not None: - if isinstance(self.remote_field.through, six.string_types): + if isinstance(self.remote_field.through, str): kwargs['through'] = self.remote_field.through elif not self.remote_field.through._meta.auto_created: kwargs['through'] = "%s.%s" % ( diff --git a/django/db/models/options.py b/django/db/models/options.py index a4593d125a95..cf3e0311047c 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -310,7 +310,7 @@ def can_migrate(self, connection): """ if self.proxy or self.swapped or not self.managed: return False - if isinstance(connection, six.string_types): + if isinstance(connection, str): connection = connections[connection] if self.required_db_vendor: return self.required_db_vendor == connection.vendor @@ -689,7 +689,7 @@ def _populate_directed_relation_graph(self): if f.is_relation and f.related_model is not None ) for f in fields_with_relations: - if not isinstance(f.remote_field.model, six.string_types): + if not isinstance(f.remote_field.model, str): related_objects_graph[f.remote_field.model._meta.concrete_model._meta].append(f) for model in all_models: diff --git a/django/db/models/query.py b/django/db/models/query.py index 2dbe3b746147..69f84d72a9da 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -260,7 +260,7 @@ def __getitem__(self, k): """ Retrieves an item or slice from the set of results. """ - if not isinstance(k, (slice,) + six.integer_types): + if not isinstance(k, (int, slice)): raise TypeError assert ((not isinstance(k, slice) and (k >= 0)) or (isinstance(k, slice) and (k.start is None or k.start >= 0) and diff --git a/django/db/models/signals.py b/django/db/models/signals.py index 9f9fbccde3d8..a511024342da 100644 --- a/django/db/models/signals.py +++ b/django/db/models/signals.py @@ -2,7 +2,6 @@ from django.db.models.utils import make_model_tuple from django.dispatch import Signal -from django.utils import six class_prepared = Signal(providing_args=["class"]) @@ -18,7 +17,7 @@ def _lazy_method(self, method, apps, receiver, sender, **kwargs): # This partial takes a single optional argument named "sender". partial_method = partial(method, receiver, **kwargs) - if isinstance(sender, six.string_types): + if isinstance(sender, str): apps = apps or Options.default_apps apps.lazy_model_operation(partial_method, make_model_tuple(sender)) else: diff --git a/django/db/models/utils.py b/django/db/models/utils.py index cda96277a608..7d563c4ae014 100644 --- a/django/db/models/utils.py +++ b/django/db/models/utils.py @@ -1,6 +1,3 @@ -from django.utils import six - - def make_model_tuple(model): """ Takes a model or a string of the form "app_label.ModelName" and returns a @@ -10,7 +7,7 @@ def make_model_tuple(model): try: if isinstance(model, tuple): model_tuple = model - elif isinstance(model, six.string_types): + elif isinstance(model, str): app_label, model_name = model.split(".") model_tuple = app_label, model_name.lower() else: diff --git a/django/db/utils.py b/django/db/utils.py index 4451f5a60e5d..a65510ea8075 100644 --- a/django/db/utils.py +++ b/django/db/utils.py @@ -247,7 +247,7 @@ def routers(self): self._routers = settings.DATABASE_ROUTERS routers = [] for r in self._routers: - if isinstance(r, six.string_types): + if isinstance(r, str): router = import_string(r)() else: router = r diff --git a/django/forms/boundfield.py b/django/forms/boundfield.py index 6faff6ffc94f..dc40bca50871 100644 --- a/django/forms/boundfield.py +++ b/django/forms/boundfield.py @@ -3,7 +3,6 @@ from django.forms.utils import flatatt, pretty_name from django.forms.widgets import Textarea, TextInput -from django.utils import six from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_text from django.utils.functional import cached_property @@ -63,7 +62,7 @@ def __len__(self): def __getitem__(self, idx): # Prevent unnecessary reevaluation when accessing BoundField's attrs # from templates. - if not isinstance(idx, six.integer_types + (slice,)): + if not isinstance(idx, (int, slice)): raise TypeError return self.subwidgets[idx] diff --git a/django/forms/fields.py b/django/forms/fields.py index 65824fbd97d0..5be10708c3d4 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -393,10 +393,10 @@ def __init__(self, input_formats=None, *args, **kwargs): def to_python(self, value): # Try to coerce the value to unicode. unicode_value = force_text(value, strings_only=True) - if isinstance(unicode_value, six.text_type): + if isinstance(unicode_value, str): value = unicode_value.strip() # If unicode, try to strptime against each input format. - if isinstance(value, six.text_type): + if isinstance(value, str): for format in self.input_formats: try: return self.strptime(value, format) @@ -521,7 +521,7 @@ def _get_regex(self): return self._regex def _set_regex(self, regex): - if isinstance(regex, six.string_types): + if isinstance(regex, str): regex = re.compile(regex, re.UNICODE) self._regex = regex if hasattr(self, '_regex_validator') and self._regex_validator in self.validators: @@ -712,7 +712,7 @@ def to_python(self, value): # will submit for False. Also check for '0', since this is what # RadioSelect will provide. Because bool("True") == bool('1') == True, # we don't need to handle that explicitly. - if isinstance(value, six.string_types) and value.lower() in ('false', '0'): + if isinstance(value, str) and value.lower() in ('false', '0'): value = False else: value = bool(value) diff --git a/django/forms/forms.py b/django/forms/forms.py index 3971893aa2ef..c8086b1361fa 100644 --- a/django/forms/forms.py +++ b/django/forms/forms.py @@ -209,7 +209,7 @@ def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_ top_errors.extend( [_('(Hidden field %(name)s) %(error)s') % {'name': name, 'error': force_text(e)} for e in bf_errors]) - hidden_fields.append(six.text_type(bf)) + hidden_fields.append(str(bf)) else: # Create a 'class="..."' attribute if the row should have any # CSS classes applied. @@ -234,7 +234,7 @@ def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_ output.append(normal_row % { 'errors': force_text(bf_errors), 'label': force_text(label), - 'field': six.text_type(bf), + 'field': str(bf), 'help_text': help_text, 'html_class_attr': html_class_attr, 'css_classes': css_classes, diff --git a/django/forms/formsets.py b/django/forms/formsets.py index 81788626e1b1..60638c475c3b 100644 --- a/django/forms/formsets.py +++ b/django/forms/formsets.py @@ -3,7 +3,6 @@ from django.forms.fields import BooleanField, IntegerField from django.forms.utils import ErrorList from django.forms.widgets import HiddenInput -from django.utils import six from django.utils.functional import cached_property from django.utils.html import html_safe from django.utils.safestring import mark_safe @@ -416,17 +415,17 @@ def as_table(self): # probably should be. It might make sense to render each form as a # table row with each field as a td. forms = ' '.join(form.as_table() for form in self) - return mark_safe('\n'.join([six.text_type(self.management_form), forms])) + return mark_safe('\n'.join([str(self.management_form), forms])) def as_p(self): "Returns this formset rendered as HTML

s." forms = ' '.join(form.as_p() for form in self) - return mark_safe('\n'.join([six.text_type(self.management_form), forms])) + return mark_safe('\n'.join([str(self.management_form), forms])) def as_ul(self): "Returns this formset rendered as HTML

  • s." forms = ' '.join(form.as_ul() for form in self) - return mark_safe('\n'.join([six.text_type(self.management_form), forms])) + return mark_safe('\n'.join([str(self.management_form), forms])) def formset_factory(form, formset=BaseFormSet, extra=1, can_order=False, diff --git a/django/forms/models.py b/django/forms/models.py index 38f6812ba0e1..c3a1b81c8cf4 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -220,7 +220,7 @@ def __new__(mcs, name, bases, attrs): # of ('foo',) for opt in ['fields', 'exclude', 'localized_fields']: value = getattr(opts, opt) - if isinstance(value, six.string_types) and value != ALL_FIELDS: + if isinstance(value, str) and value != ALL_FIELDS: msg = ("%(model)s.Meta.%(opt)s cannot be a string. " "Did you mean to type: ('%(value)s',)?" % { 'model': new_class.__name__, @@ -727,7 +727,7 @@ def get_unique_error_message(self, unique_check): } else: return ugettext("Please correct the duplicate data for %(field)s, which must be unique.") % { - "field": get_text_list(unique_check, six.text_type(_("and"))), + "field": get_text_list(unique_check, _("and")), } def get_date_error_message(self, date_check): @@ -737,7 +737,7 @@ def get_date_error_message(self, date_check): ) % { 'field_name': date_check[2], 'date_field': date_check[3], - 'lookup': six.text_type(date_check[1]), + 'lookup': str(date_check[1]), } def get_form_error(self): @@ -1305,7 +1305,7 @@ def _check_values(self, value): def prepare_value(self, value): if (hasattr(value, '__iter__') and - not isinstance(value, six.text_type) and + not isinstance(value, str) and not hasattr(value, '_meta')): return [super(ModelMultipleChoiceField, self).prepare_value(v) for v in value] return super(ModelMultipleChoiceField, self).prepare_value(value) diff --git a/django/forms/widgets.py b/django/forms/widgets.py index c4bbb7fe4fe2..e21dba06077a 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -498,7 +498,7 @@ def value_from_datadict(self, data, files, name): value = data.get(name) # Translate true and false strings to boolean values. values = {'true': True, 'false': False} - if isinstance(value, six.string_types): + if isinstance(value, str): value = values.get(value.lower(), value) return bool(value) @@ -671,10 +671,7 @@ def get_context(self, name, value, attrs=None): def _choice_has_empty_value(choice): """Return True if the choice's value is empty string or None.""" value, _ = choice - return ( - (isinstance(value, six.string_types) and not bool(value)) or - value is None - ) + return (isinstance(value, str) and not bool(value)) or value is None def use_required_attribute(self, initial): """ @@ -986,7 +983,7 @@ def format_value(self, value): year, month, day = None, None, None if isinstance(value, (datetime.date, datetime.datetime)): year, month, day = value.year, value.month, value.day - elif isinstance(value, six.string_types): + elif isinstance(value, str): if settings.USE_L10N: try: input_format = get_format('DATE_INPUT_FORMATS')[0] diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index 812e83eff005..b1db1f81ca44 100644 --- a/django/http/multipartparser.py +++ b/django/http/multipartparser.py @@ -84,7 +84,7 @@ def __init__(self, META, input_data, upload_handlers, encoding=None): # This means we shouldn't continue...raise an error. raise MultiPartParserError("Invalid content length: %r" % content_length) - if isinstance(boundary, six.text_type): + if isinstance(boundary, str): boundary = boundary.encode('ascii') self._boundary = boundary self._input_data = input_data diff --git a/django/http/request.py b/django/http/request.py index b4053142ac93..fe1684ee58bd 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -522,7 +522,7 @@ def bytes_to_text(s, encoding): Returns any non-basestring objects without change. """ if isinstance(s, bytes): - return six.text_type(s, encoding, 'replace') + return str(s, encoding, 'replace') else: return s diff --git a/django/http/response.py b/django/http/response.py index e4cce4fdbec1..1c2677035daf 100644 --- a/django/http/response.py +++ b/django/http/response.py @@ -113,10 +113,10 @@ def _convert_to_charset(self, value, charset, mime_encode=False): `value` can't be represented in the given charset, MIME-encoding is applied. """ - if not isinstance(value, (bytes, six.text_type)): + if not isinstance(value, (bytes, str)): value = str(value) if ((isinstance(value, bytes) and (b'\n' in value or b'\r' in value)) or - isinstance(value, six.text_type) and ('\n' in value or '\r' in value)): + isinstance(value, str) and ('\n' in value or '\r' in value)): raise BadHeaderError("Header values can't contain newlines (got %r)" % value) try: if isinstance(value, str): @@ -226,11 +226,11 @@ def make_bytes(self, value): # This doesn't make a copy when `value` already contains bytes. # Handle string types -- we can't rely on force_bytes here because: - # - under Python 3 it attempts str conversion first + # - Python attempts str conversion first # - when self._charset != 'utf-8' it re-encodes the content if isinstance(value, bytes): return bytes(value) - if isinstance(value, six.text_type): + if isinstance(value, str): return bytes(value.encode(self.charset)) # Handle non-string types (#16494) @@ -309,7 +309,7 @@ def content(self): @content.setter def content(self, value): # Consume iterators upon assignment to allow repeated iteration. - if hasattr(value, '__iter__') and not isinstance(value, (bytes, six.string_types)): + if hasattr(value, '__iter__') and not isinstance(value, (bytes, str)): content = b''.join(self.make_bytes(chunk) for chunk in value) if hasattr(value, 'close'): try: diff --git a/django/shortcuts.py b/django/shortcuts.py index f4fa0600ac9b..b27a75206f96 100644 --- a/django/shortcuts.py +++ b/django/shortcuts.py @@ -8,7 +8,6 @@ ) from django.template import loader from django.urls import NoReverseMatch, reverse -from django.utils import six from django.utils.encoding import force_text from django.utils.functional import Promise @@ -137,7 +136,7 @@ def resolve_url(to, *args, **kwargs): # further to some Python functions like urlparse. to = force_text(to) - if isinstance(to, six.string_types): + if isinstance(to, str): # Handle relative URLs if to.startswith(('./', '../')): return to diff --git a/django/template/base.py b/django/template/base.py index aa30d2e2b308..c7c2249aa089 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -56,7 +56,6 @@ from django.template.context import ( # NOQA: imported for backwards compatibility BaseContext, Context, ContextPopException, RequestContext, ) -from django.utils import six from django.utils.encoding import force_str, force_text from django.utils.formats import localize from django.utils.html import conditional_escape, escape @@ -771,7 +770,7 @@ def __init__(self, var): self.translate = False self.message_context = None - if not isinstance(var, six.string_types): + if not isinstance(var, str): raise TypeError( "Variable must be a string or number, got %s" % type(var)) try: diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index fc249953ea1b..828255b73ca8 100644 --- a/django/template/defaultfilters.py +++ b/django/template/defaultfilters.py @@ -6,7 +6,7 @@ from operator import itemgetter from pprint import pformat -from django.utils import formats, six +from django.utils import formats from django.utils.dateformat import format, time_format from django.utils.encoding import force_text, iri_to_uri from django.utils.html import ( @@ -168,7 +168,7 @@ def floatformat(text, arg=-1): # Avoid conversion to scientific notation by accessing `sign`, `digits` # and `exponent` from `Decimal.as_tuple()` directly. sign, digits, exponent = d.quantize(exp, ROUND_HALF_UP, Context(prec=prec)).as_tuple() - digits = [six.text_type(digit) for digit in reversed(digits)] + digits = [str(digit) for digit in reversed(digits)] while len(digits) <= abs(exponent): digits.append('0') digits.insert(-exponent, '.') @@ -194,7 +194,7 @@ def linenumbers(value, autoescape=True): lines = value.split('\n') # Find the maximum width of the line count, for use with zero padding # string format command - width = six.text_type(len(six.text_type(len(lines)))) + width = str(len(str(len(lines)))) if not autoescape or isinstance(value, SafeData): for i, line in enumerate(lines): lines[i] = ("%0" + width + "d. %s") % (i + 1, line) @@ -246,7 +246,7 @@ def stringformat(value, arg): for documentation of Python string formatting. """ try: - return ("%" + six.text_type(arg)) % value + return ("%" + str(arg)) % value except (ValueError, TypeError): return "" @@ -675,7 +675,7 @@ def walk_items(item_list): except StopIteration: yield item, None break - if not isinstance(next_item, six.string_types): + if not isinstance(next_item, str): try: iter(next_item) except TypeError: diff --git a/django/template/engine.py b/django/template/engine.py index 154276a5b063..6d73569e0221 100644 --- a/django/template/engine.py +++ b/django/template/engine.py @@ -1,5 +1,5 @@ from django.core.exceptions import ImproperlyConfigured -from django.utils import lru_cache, six +from django.utils import lru_cache from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -120,7 +120,7 @@ def find_template_loader(self, loader): else: args = [] - if isinstance(loader, six.string_types): + if isinstance(loader, str): loader_class = import_string(loader) return loader_class(self, *args) else: diff --git a/django/template/library.py b/django/template/library.py index 8a6c98ee0983..b7e3cad532d1 100644 --- a/django/template/library.py +++ b/django/template/library.py @@ -1,7 +1,6 @@ import functools from importlib import import_module -from django.utils import six from django.utils.html import conditional_escape from django.utils.inspect import getargspec from django.utils.itercompat import is_iterable @@ -220,7 +219,7 @@ def render(self, context): t = self.filename elif isinstance(getattr(self.filename, 'template', None), Template): t = self.filename.template - elif not isinstance(self.filename, six.string_types) and is_iterable(self.filename): + elif not isinstance(self.filename, str) and is_iterable(self.filename): t = context.template.engine.select_template(self.filename) else: t = context.template.engine.get_template(self.filename) diff --git a/django/template/loader.py b/django/template/loader.py index 17b278812b50..fe598bc816a3 100644 --- a/django/template/loader.py +++ b/django/template/loader.py @@ -1,5 +1,3 @@ -from django.utils import six - from . import engines from .exceptions import TemplateDoesNotExist @@ -29,7 +27,7 @@ def select_template(template_name_list, using=None): Raises TemplateDoesNotExist if no such template exists. """ - if isinstance(template_name_list, six.string_types): + if isinstance(template_name_list, str): raise TypeError( 'select_template() takes an iterable of template names but got a ' 'string: %r. Use get_template() if you want to load a single ' diff --git a/django/template/response.py b/django/template/response.py index 95cb335ab4d9..e5c1fbfa66c2 100644 --- a/django/template/response.py +++ b/django/template/response.py @@ -1,5 +1,4 @@ from django.http import HttpResponse -from django.utils import six from .loader import get_template, select_template @@ -62,7 +61,7 @@ def resolve_template(self, template): "Accepts a template object, path-to-template or list of paths" if isinstance(template, (list, tuple)): return select_template(template, using=self.using) - elif isinstance(template, six.string_types): + elif isinstance(template, str): return get_template(template, using=self.using) else: return template diff --git a/django/templatetags/i18n.py b/django/templatetags/i18n.py index 4a32e628c214..407ce87609d5 100644 --- a/django/templatetags/i18n.py +++ b/django/templatetags/i18n.py @@ -74,7 +74,7 @@ def __init__(self, filter_expression, noop, asvar=None, self.asvar = asvar self.message_context = message_context self.filter_expression = filter_expression - if isinstance(self.filter_expression.var, six.string_types): + if isinstance(self.filter_expression.var, str): self.filter_expression.var = Variable("'%s'" % self.filter_expression.var) diff --git a/django/templatetags/tz.py b/django/templatetags/tz.py index 4088ba7eb829..99d391e45d30 100644 --- a/django/templatetags/tz.py +++ b/django/templatetags/tz.py @@ -3,7 +3,7 @@ import pytz from django.template import Library, Node, TemplateSyntaxError -from django.utils import six, timezone +from django.utils import timezone register = Library() @@ -59,7 +59,7 @@ def do_timezone(value, arg): # Obtain a tzinfo instance if isinstance(arg, tzinfo): tz = arg - elif isinstance(arg, six.string_types): + elif isinstance(arg, str): try: tz = pytz.timezone(arg) except pytz.UnknownTimeZoneError: diff --git a/django/test/client.py b/django/test/client.py index 8134c1725331..1c08ada1cfba 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -197,7 +197,7 @@ def is_file(thing): for (key, value) in data.items(): if is_file(value): lines.extend(encode_file(boundary, key, value)) - elif not isinstance(value, six.string_types) and is_iterable(value): + elif not isinstance(value, str) and is_iterable(value): for item in value: if is_file(item): lines.extend(encode_file(boundary, key, item)) @@ -229,7 +229,7 @@ def to_bytes(s): # file.name might not be a string. For example, it's an int for # tempfile.TemporaryFile(). - file_has_string_name = hasattr(file, 'name') and isinstance(file.name, six.string_types) + file_has_string_name = hasattr(file, 'name') and isinstance(file.name, str) filename = os.path.basename(file.name) if file_has_string_name else '' if hasattr(file, 'content_type'): diff --git a/django/test/html.py b/django/test/html.py index fd78e6b713dd..d84b9770e115 100644 --- a/django/test/html.py +++ b/django/test/html.py @@ -4,8 +4,6 @@ import re -from django.utils import six -from django.utils.encoding import force_text from django.utils.html_parser import HTMLParseError, HTMLParser WHITESPACE = re.compile(r'\s+') @@ -22,11 +20,10 @@ def __init__(self, name, attributes): self.children = [] def append(self, element): - if isinstance(element, six.string_types): - element = force_text(element) + if isinstance(element, str): element = normalize_whitespace(element) if self.children: - if isinstance(self.children[-1], six.string_types): + if isinstance(self.children[-1], str): self.children[-1] += element self.children[-1] = normalize_whitespace(self.children[-1]) return @@ -34,7 +31,7 @@ def append(self, element): # removing last children if it is only whitespace # this can result in incorrect dom representations since # whitespace between inline tags like is significant - if isinstance(self.children[-1], six.string_types): + if isinstance(self.children[-1], str): if self.children[-1].isspace(): self.children.pop() if element: @@ -43,7 +40,7 @@ def append(self, element): def finalize(self): def rstrip_last_element(children): if children: - if isinstance(children[-1], six.string_types): + if isinstance(children[-1], str): children[-1] = children[-1].rstrip() if not children[-1]: children.pop() @@ -52,7 +49,7 @@ def rstrip_last_element(children): rstrip_last_element(self.children) for i, child in enumerate(self.children): - if isinstance(child, six.string_types): + if isinstance(child, str): self.children[i] = child.strip() elif hasattr(child, 'finalize'): child.finalize() @@ -88,7 +85,7 @@ def __ne__(self, element): return not self.__eq__(element) def _count(self, element, count=True): - if not isinstance(element, six.string_types): + if not isinstance(element, str): if self == element: return 1 if isinstance(element, RootElement): @@ -98,8 +95,8 @@ def _count(self, element, count=True): for child in self.children: # child is text content and element is also text content, then # make a simple "text" in "text" - if isinstance(child, six.string_types): - if isinstance(element, six.string_types): + if isinstance(child, str): + if isinstance(element, str): if count: i += child.count(element) elif element in child: @@ -128,14 +125,14 @@ def __str__(self): output += ' %s' % key if self.children: output += '>\n' - output += ''.join(six.text_type(c) for c in self.children) + output += ''.join(str(c) for c in self.children) output += '\n' % self.name else: output += ' />' return output def __repr__(self): - return six.text_type(self) + return str(self) class RootElement(Element): @@ -143,7 +140,7 @@ def __init__(self): super(RootElement, self).__init__(None, ()) def __str__(self): - return ''.join(six.text_type(c) for c in self.children) + return ''.join(str(c) for c in self.children) class Parser(HTMLParser): @@ -232,6 +229,6 @@ def parse_html(html): document.finalize() # Removing ROOT element if it's not necessary if len(document.children) == 1: - if not isinstance(document.children[0], six.string_types): + if not isinstance(document.children[0], str): document = document.children[0] return document diff --git a/django/test/testcases.py b/django/test/testcases.py index 7e8cee5c0ded..9d08940f5a12 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -674,8 +674,7 @@ def assertHTMLEqual(self, html1, html2, msg=None): standardMsg = '%s != %s' % ( safe_repr(dom1, True), safe_repr(dom2, True)) diff = ('\n' + '\n'.join(difflib.ndiff( - six.text_type(dom1).splitlines(), - six.text_type(dom2).splitlines(), + str(dom1).splitlines(), str(dom2).splitlines(), ))) standardMsg = self._truncateMessage(standardMsg, diff) self.fail(self._formatMessage(msg, standardMsg)) @@ -712,7 +711,7 @@ def assertJSONEqual(self, raw, expected_data, msg=None): data = json.loads(raw) except ValueError: self.fail("First argument is not valid JSON: %r" % raw) - if isinstance(expected_data, six.string_types): + if isinstance(expected_data, str): try: expected_data = json.loads(expected_data) except ValueError: @@ -729,7 +728,7 @@ def assertJSONNotEqual(self, raw, expected_data, msg=None): data = json.loads(raw) except ValueError: self.fail("First argument is not valid JSON: %r" % raw) - if isinstance(expected_data, six.string_types): + if isinstance(expected_data, str): try: expected_data = json.loads(expected_data) except ValueError: @@ -751,10 +750,7 @@ def assertXMLEqual(self, xml1, xml2, msg=None): if not result: standardMsg = '%s != %s' % (safe_repr(xml1, True), safe_repr(xml2, True)) diff = ('\n' + '\n'.join( - difflib.ndiff( - six.text_type(xml1).splitlines(), - six.text_type(xml2).splitlines(), - ) + difflib.ndiff(xml1.splitlines(), xml2.splitlines()) )) standardMsg = self._truncateMessage(standardMsg, diff) self.fail(self._formatMessage(msg, standardMsg)) diff --git a/django/test/utils.py b/django/test/utils.py index 5ed32dbab562..7395396fbbb4 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -61,7 +61,7 @@ class ContextList(list): in a list of context objects. """ def __getitem__(self, key): - if isinstance(key, six.string_types): + if isinstance(key, str): for subcontext in self: if key in subcontext: return subcontext[key] @@ -478,7 +478,7 @@ def enable(self): value = list(getattr(settings, name, [])) for action, items in operations.items(): # items my be a single value or an iterable. - if isinstance(items, six.string_types): + if isinstance(items, str): items = [items] if action == 'append': value = value + [item for item in items if item not in value] diff --git a/django/urls/base.py b/django/urls/base.py index 8e30acb860b5..c09eeed8f6c9 100644 --- a/django/urls/base.py +++ b/django/urls/base.py @@ -1,6 +1,5 @@ from threading import local -from django.utils import six from django.utils.encoding import force_text, iri_to_uri from django.utils.functional import lazy from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit @@ -34,7 +33,7 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None): prefix = get_script_prefix() - if not isinstance(viewname, six.string_types): + if not isinstance(viewname, str): view = viewname else: parts = viewname.split(':') @@ -89,7 +88,7 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None): return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))) -reverse_lazy = lazy(reverse, six.text_type) +reverse_lazy = lazy(reverse, str) def clear_url_caches(): diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py index 4e8bded3dbb4..cf2fe0ecec69 100644 --- a/django/urls/resolvers.py +++ b/django/urls/resolvers.py @@ -14,7 +14,7 @@ from django.core.checks import Warning from django.core.checks.urls import check_resolver from django.core.exceptions import ImproperlyConfigured -from django.utils import lru_cache, six +from django.utils import lru_cache from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_str, force_text from django.utils.functional import cached_property @@ -87,7 +87,7 @@ def __get__(self, instance, cls=None): # As a performance optimization, if the given regex string is a regular # string (not a lazily-translated string proxy), compile it once and # avoid per-language compilation. - if isinstance(instance._regex, six.string_types): + if isinstance(instance._regex, str): instance.__dict__['regex'] = self._compile(instance._regex) return instance.__dict__['regex'] language_code = get_language() @@ -103,8 +103,7 @@ def _compile(self, regex): return re.compile(regex, re.UNICODE) except re.error as e: raise ImproperlyConfigured( - '"%s" is not a valid regular expression: %s' % - (regex, six.text_type(e)) + '"%s" is not a valid regular expression: %s' % (regex, e) ) @@ -388,7 +387,7 @@ def resolve(self, path): @cached_property def urlconf_module(self): - if isinstance(self.urlconf_name, six.string_types): + if isinstance(self.urlconf_name, str): return import_module(self.urlconf_name) else: return self.urlconf_name diff --git a/django/urls/utils.py b/django/urls/utils.py index 8558b82bbad0..3cf5439e77f8 100644 --- a/django/urls/utils.py +++ b/django/urls/utils.py @@ -1,7 +1,7 @@ from importlib import import_module from django.core.exceptions import ViewDoesNotExist -from django.utils import lru_cache, six +from django.utils import lru_cache from django.utils.module_loading import module_has_submodule @@ -17,7 +17,7 @@ def get_callable(lookup_view): if callable(lookup_view): return lookup_view - if not isinstance(lookup_view, six.string_types): + if not isinstance(lookup_view, str): raise ViewDoesNotExist("'%s' is not a callable or a dot-notation path" % lookup_view) mod_name, func_name = get_mod_func(lookup_view) diff --git a/django/utils/archive.py b/django/utils/archive.py index 57e87658a655..456145a52066 100644 --- a/django/utils/archive.py +++ b/django/utils/archive.py @@ -27,8 +27,6 @@ import tarfile import zipfile -from django.utils import six - class ArchiveException(Exception): """ @@ -61,7 +59,7 @@ def __init__(self, file): @staticmethod def _archive_cls(file): cls = None - if isinstance(file, six.string_types): + if isinstance(file, str): filename = file else: try: diff --git a/django/utils/dateformat.py b/django/utils/dateformat.py index 861bf8f9236a..ded952df994c 100644 --- a/django/utils/dateformat.py +++ b/django/utils/dateformat.py @@ -15,7 +15,6 @@ import re import time -from django.utils import six from django.utils.dates import ( MONTHS, MONTHS_3, MONTHS_ALT, MONTHS_AP, WEEKDAYS, WEEKDAYS_ABBR, ) @@ -182,7 +181,7 @@ def T(self): pass if name is None: name = self.format('O') - return six.text_type(name) + return str(name) def u(self): "Microseconds; i.e. '000000' to '999999'" @@ -350,7 +349,7 @@ def W(self): def y(self): "Year, 2 digits; e.g. '99'" - return six.text_type(self.data.year)[2:] + return str(self.data.year)[2:] def Y(self): "Year, 4 digits; e.g. '1999'" diff --git a/django/utils/encoding.py b/django/utils/encoding.py index f0627f5d3908..abd17526c615 100644 --- a/django/utils/encoding.py +++ b/django/utils/encoding.py @@ -36,8 +36,8 @@ def smart_text(s, encoding='utf-8', strings_only=False, errors='strict'): return force_text(s, encoding, strings_only, errors) -_PROTECTED_TYPES = six.integer_types + ( - type(None), float, Decimal, datetime.datetime, datetime.date, datetime.time +_PROTECTED_TYPES = ( + type(None), int, float, Decimal, datetime.datetime, datetime.date, datetime.time, ) @@ -58,18 +58,18 @@ def force_text(s, encoding='utf-8', strings_only=False, errors='strict'): If strings_only is True, don't convert (some) non-string-like objects. """ # Handle the common case first for performance reasons. - if issubclass(type(s), six.text_type): + if issubclass(type(s), str): return s if strings_only and is_protected_type(s): return s try: - if not issubclass(type(s), six.string_types): + if not issubclass(type(s), str): if isinstance(s, bytes): - s = six.text_type(s, encoding, errors) + s = str(s, encoding, errors) else: - s = six.text_type(s) + s = str(s) else: - # Note: We use .decode() here, instead of six.text_type(s, encoding, + # Note: We use .decode() here, instead of str(s, encoding, # errors), so that if s is a SafeBytes, it ends up being a # SafeText at the end. s = s.decode(encoding, errors) @@ -114,13 +114,13 @@ def force_bytes(s, encoding='utf-8', strings_only=False, errors='strict'): return s.decode('utf-8', errors).encode(encoding, errors) if strings_only and is_protected_type(s): return s - if isinstance(s, six.memoryview): + if isinstance(s, memoryview): return bytes(s) if isinstance(s, Promise): - return six.text_type(s).encode(encoding, errors) - if not isinstance(s, six.string_types): + return str(s).encode(encoding, errors) + if not isinstance(s, str): try: - return six.text_type(s).encode(encoding) + return str(s).encode(encoding) except UnicodeEncodeError: if isinstance(s, Exception): # An Exception subclass containing non-ASCII data that doesn't @@ -128,7 +128,7 @@ def force_bytes(s, encoding='utf-8', strings_only=False, errors='strict'): # further exception. return b' '.join(force_bytes(arg, encoding, strings_only, errors) for arg in s) - return six.text_type(s).encode(encoding, errors) + return str(s).encode(encoding, errors) else: return s.encode(encoding, errors) diff --git a/django/utils/formats.py b/django/utils/formats.py index e381c1fbca2e..894003b4fab9 100644 --- a/django/utils/formats.py +++ b/django/utils/formats.py @@ -4,7 +4,7 @@ from importlib import import_module from django.conf import settings -from django.utils import dateformat, datetime_safe, numberformat, six +from django.utils import dateformat, datetime_safe, numberformat from django.utils.encoding import force_str from django.utils.functional import lazy from django.utils.safestring import mark_safe @@ -71,7 +71,7 @@ def iter_format_modules(lang, format_module_path=None): format_locations = [] if format_module_path: - if isinstance(format_module_path, six.string_types): + if isinstance(format_module_path, str): format_module_path = [format_module_path] for path in format_module_path: format_locations.append(path + '.%s') @@ -148,7 +148,7 @@ def get_format(format_type, lang=None, use_l10n=None): return val -get_format_lazy = lazy(get_format, six.text_type, list, tuple) +get_format_lazy = lazy(get_format, str, list, tuple) def date_format(value, format=None, use_l10n=None): @@ -201,11 +201,11 @@ def localize(value, use_l10n=None): If use_l10n is provided and is not None, that will force the value to be localized (or not), overriding the value of settings.USE_L10N. """ - if isinstance(value, six.string_types): # Handle strings first for performance reasons. + if isinstance(value, str): # Handle strings first for performance reasons. return value elif isinstance(value, bool): # Make sure booleans don't get treated as numbers - return mark_safe(six.text_type(value)) - elif isinstance(value, (decimal.Decimal, float) + six.integer_types): + return mark_safe(str(value)) + elif isinstance(value, (decimal.Decimal, float, int)): return number_format(value, use_l10n=use_l10n) elif isinstance(value, datetime.datetime): return date_format(value, 'DATETIME_FORMAT', use_l10n=use_l10n) @@ -221,11 +221,11 @@ def localize_input(value, default=None): Checks if an input value is a localizable type and returns it formatted with the appropriate formatting string of the current locale. """ - if isinstance(value, six.string_types): # Handle strings first for performance reasons. + if isinstance(value, str): # Handle strings first for performance reasons. return value elif isinstance(value, bool): # Don't treat booleans as numbers. - return six.text_type(value) - elif isinstance(value, (decimal.Decimal, float) + six.integer_types): + return str(value) + elif isinstance(value, (decimal.Decimal, float, int)): return number_format(value) elif isinstance(value, datetime.datetime): value = datetime_safe.new_datetime(value) @@ -246,7 +246,7 @@ def sanitize_separators(value): Sanitizes a value according to the current decimal and thousand separator setting. Used with form field input. """ - if settings.USE_L10N and isinstance(value, six.string_types): + if settings.USE_L10N and isinstance(value, str): parts = [] decimal_separator = get_format('DECIMAL_SEPARATOR') if decimal_separator in value: diff --git a/django/utils/functional.py b/django/utils/functional.py index 933085391d91..3e35582cbf31 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -88,7 +88,7 @@ def __prepare_class__(cls): meth = cls.__promise__(method_name) setattr(cls, method_name, meth) cls._delegate_bytes = bytes in resultclasses - cls._delegate_text = six.text_type in resultclasses + cls._delegate_text = str in resultclasses assert not (cls._delegate_bytes and cls._delegate_text), ( "Cannot call lazy() with both bytes and text return types.") if cls._delegate_text: @@ -148,7 +148,7 @@ def __hash__(self): def __mod__(self, rhs): if self._delegate_text: - return six.text_type(self) % rhs + return str(self) % rhs return self.__cast() % rhs def __deepcopy__(self, memo): @@ -175,7 +175,7 @@ def lazystr(text): Shortcut for the common case of a lazy callable that returns str. """ from django.utils.encoding import force_text # Avoid circular import - return lazy(force_text, six.text_type)(text) + return lazy(force_text, str)(text) def keep_lazy(*resultclasses): @@ -207,7 +207,7 @@ def keep_lazy_text(func): """ A decorator for functions that accept lazy arguments and return text. """ - return keep_lazy(six.text_type)(func) + return keep_lazy(str)(func) empty = object() diff --git a/django/utils/html.py b/django/utils/html.py index 36b5d53283df..430350fed641 100644 --- a/django/utils/html.py +++ b/django/utils/html.py @@ -33,7 +33,7 @@ simple_email_re = re.compile(r'^\S+@\S+\.\S+$') -@keep_lazy(six.text_type, SafeText) +@keep_lazy(str, SafeText) def escape(text): """ Returns the given text with ampersands, quotes and angle brackets encoded @@ -67,7 +67,7 @@ def escape(text): _js_escapes.update((ord('%c' % z), '\\u%04X' % z) for z in range(32)) -@keep_lazy(six.text_type, SafeText) +@keep_lazy(str, SafeText) def escapejs(value): """Hex encodes characters for use in JavaScript strings.""" return mark_safe(force_text(value).translate(_js_escapes)) diff --git a/django/utils/numberformat.py b/django/utils/numberformat.py index d4c9ad74a5d3..1931015e7be9 100644 --- a/django/utils/numberformat.py +++ b/django/utils/numberformat.py @@ -1,7 +1,6 @@ from decimal import Decimal from django.conf import settings -from django.utils import six from django.utils.safestring import mark_safe @@ -24,13 +23,13 @@ def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='', use_grouping = use_grouping and grouping != 0 # Make the common case fast if isinstance(number, int) and not use_grouping and not decimal_pos: - return mark_safe(six.text_type(number)) + return mark_safe(str(number)) # sign sign = '' if isinstance(number, Decimal): str_number = '{:f}'.format(number) else: - str_number = six.text_type(number) + str_number = str(number) if str_number[0] == '-': sign = '-' str_number = str_number[1:] diff --git a/django/utils/regex_helper.py b/django/utils/regex_helper.py index 41f2459491ec..bc4a09b35908 100644 --- a/django/utils/regex_helper.py +++ b/django/utils/regex_helper.py @@ -7,7 +7,6 @@ """ import warnings -from django.utils import six from django.utils.deprecation import RemovedInDjango21Warning from django.utils.six.moves import zip @@ -318,7 +317,7 @@ def flatten_result(source): result_args = [[]] pos = last = 0 for pos, elt in enumerate(source): - if isinstance(elt, six.string_types): + if isinstance(elt, str): continue piece = ''.join(source[last:pos]) if isinstance(elt, Group): diff --git a/django/utils/safestring.py b/django/utils/safestring.py index 3f4b3d48fd86..609f8f45acec 100644 --- a/django/utils/safestring.py +++ b/django/utils/safestring.py @@ -5,7 +5,6 @@ be interpreted by the HTML engine (e.g. '<') into the appropriate entities. """ -from django.utils import six from django.utils.functional import Promise, curry, wraps @@ -52,10 +51,10 @@ def _proxy_method(self, *args, **kwargs): decode = curry(_proxy_method, method=bytes.decode) -class SafeText(six.text_type, SafeData): +class SafeText(str, SafeData): """ - A unicode (Python 2) / str (Python 3) subclass that has been specifically - marked as "safe" for HTML output purposes. + A str subclass that has been specifically marked as "safe" for HTML output + purposes. """ def __add__(self, rhs): """ @@ -80,7 +79,7 @@ def _proxy_method(self, *args, **kwargs): else: return SafeText(data) - encode = curry(_proxy_method, method=six.text_type.encode) + encode = curry(_proxy_method, method=str.encode) SafeString = SafeText @@ -106,7 +105,7 @@ def mark_safe(s): return s if isinstance(s, bytes) or (isinstance(s, Promise) and s._delegate_bytes): return SafeBytes(s) - if isinstance(s, (six.text_type, Promise)): + if isinstance(s, (str, Promise)): return SafeText(s) if callable(s): return _safety_decorator(mark_safe, s) diff --git a/django/utils/text.py b/django/utils/text.py index fc8677cf4e6c..15a9b6160a0b 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -408,7 +408,7 @@ def unescape_string_literal(s): return s[1:-1].replace(r'\%s' % quote, quote).replace(r'\\', '\\') -@keep_lazy(six.text_type, SafeText) +@keep_lazy(str, SafeText) def slugify(value, allow_unicode=False): """ Convert to ASCII if 'allow_unicode' is False. Convert spaces to hyphens. @@ -441,4 +441,4 @@ def _format_lazy(format_string, *args, **kwargs): return format_string.format(*args, **kwargs) -format_lazy = lazy(_format_lazy, six.text_type) +format_lazy = lazy(_format_lazy, str) diff --git a/django/utils/timezone.py b/django/utils/timezone.py index 090750793a91..992e80086ab9 100644 --- a/django/utils/timezone.py +++ b/django/utils/timezone.py @@ -8,7 +8,7 @@ import pytz from django.conf import settings -from django.utils import lru_cache, six +from django.utils import lru_cache from django.utils.decorators import ContextDecorator __all__ = [ @@ -130,7 +130,7 @@ def activate(timezone): """ if isinstance(timezone, tzinfo): _active.value = timezone - elif isinstance(timezone, six.string_types): + elif isinstance(timezone, str): _active.value = pytz.timezone(timezone) else: raise ValueError("Invalid timezone: %r" % timezone) diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py index fd02fa16a33e..345015d99496 100644 --- a/django/utils/translation/__init__.py +++ b/django/utils/translation/__init__.py @@ -4,7 +4,6 @@ import re import warnings -from django.utils import six from django.utils.decorators import ContextDecorator from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_text @@ -100,12 +99,12 @@ def npgettext(context, singular, plural, number): gettext_lazy = lazy(gettext, str) -ugettext_lazy = lazy(ugettext, six.text_type) -pgettext_lazy = lazy(pgettext, six.text_type) +ugettext_lazy = lazy(ugettext, str) +pgettext_lazy = lazy(pgettext, str) def lazy_number(func, resultclass, number=None, **kwargs): - if isinstance(number, six.integer_types): + if isinstance(number, int): kwargs['number'] = number proxy = lazy(func, resultclass)(**kwargs) else: @@ -153,11 +152,11 @@ def ngettext_lazy(singular, plural, number=None): def ungettext_lazy(singular, plural, number=None): - return lazy_number(ungettext, six.text_type, singular=singular, plural=plural, number=number) + return lazy_number(ungettext, str, singular=singular, plural=plural, number=number) def npgettext_lazy(context, singular, plural, number=None): - return lazy_number(npgettext, six.text_type, context=context, singular=singular, plural=plural, number=number) + return lazy_number(npgettext, str, context=context, singular=singular, plural=plural, number=number) def activate(language): @@ -234,7 +233,7 @@ def _string_concat(*strings): return ''.join(force_text(s) for s in strings) -string_concat = lazy(_string_concat, six.text_type) +string_concat = lazy(_string_concat, str) def get_language_info(lang_code): diff --git a/django/views/debug.py b/django/views/debug.py index 2390995b5685..de8c4319bfc5 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -7,7 +7,7 @@ from django.template import Context, Engine, TemplateDoesNotExist from django.template.defaultfilters import force_escape, pprint from django.urls import Resolver404, resolve -from django.utils import lru_cache, six, timezone +from django.utils import lru_cache, timezone from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_bytes, force_text from django.utils.module_loading import import_string @@ -246,7 +246,7 @@ def __init__(self, request, exc_type, exc_value, tb, is_email=False): self.postmortem = None # Handle deprecated string exceptions - if isinstance(self.exc_type, six.string_types): + if isinstance(self.exc_type, str): self.exc_value = Exception('Deprecated String Exception: %r' % self.exc_type) self.exc_type = type(self.exc_value) @@ -263,7 +263,7 @@ def get_traceback_data(self): for k, v in frame['vars']: v = pprint(v) # The force_escape filter assume unicode, make sure that works - if isinstance(v, six.binary_type): + if isinstance(v, bytes): v = v.decode('utf-8', 'replace') # don't choke on non-utf-8 input # Trim large blobs of data if len(v) > 4096: @@ -361,7 +361,7 @@ def _get_lines_from_file(self, filename, lineno, context_lines, loader=None, mod # If we just read the source from a file, or if the loader did not # apply tokenize.detect_encoding to decode the source into a Unicode # string, then we should do that ourselves. - if isinstance(source[0], six.binary_type): + if isinstance(source[0], bytes): encoding = 'ascii' for line in source[:2]: # File coding may be specified. Match pattern from PEP-263 @@ -370,7 +370,7 @@ def _get_lines_from_file(self, filename, lineno, context_lines, loader=None, mod if match: encoding = match.group(1).decode('ascii') break - source = [six.text_type(sline, encoding, 'replace') for sline in source] + source = [str(sline, encoding, 'replace') for sline in source] lower_bound = max(0, lineno - context_lines) upper_bound = lineno + context_lines diff --git a/django/views/defaults.py b/django/views/defaults.py index 348837ed99d7..12218e8048bb 100644 --- a/django/views/defaults.py +++ b/django/views/defaults.py @@ -1,6 +1,5 @@ from django import http from django.template import Context, Engine, TemplateDoesNotExist, loader -from django.utils import six from django.utils.encoding import force_text from django.views.decorators.csrf import requires_csrf_token @@ -34,7 +33,7 @@ def page_not_found(request, exception, template_name=ERROR_404_TEMPLATE_NAME): except (AttributeError, IndexError): pass else: - if isinstance(message, six.text_type): + if isinstance(message, str): exception_repr = message context = { 'request_path': request.path, diff --git a/django/views/generic/list.py b/django/views/generic/list.py index 951c11f5a520..e37f4f1ac068 100644 --- a/django/views/generic/list.py +++ b/django/views/generic/list.py @@ -2,7 +2,6 @@ from django.core.paginator import InvalidPage, Paginator from django.db.models.query import QuerySet from django.http import Http404 -from django.utils import six from django.utils.translation import ugettext as _ from django.views.generic.base import ContextMixin, TemplateResponseMixin, View @@ -44,7 +43,7 @@ def get_queryset(self): ) ordering = self.get_ordering() if ordering: - if isinstance(ordering, six.string_types): + if isinstance(ordering, str): ordering = (ordering,) queryset = queryset.order_by(*ordering) diff --git a/django/views/i18n.py b/django/views/i18n.py index ba8fce67e701..1fc5461b1c18 100644 --- a/django/views/i18n.py +++ b/django/views/i18n.py @@ -75,7 +75,7 @@ def get_formats(): result[attr] = get_format(attr) formats = {} for k, v in result.items(): - if isinstance(v, (six.string_types, int)): + if isinstance(v, (int, str)): formats[k] = force_text(v) elif isinstance(v, (tuple, list)): formats[k] = [force_text(value) for value in v] @@ -268,7 +268,7 @@ def get_catalog(self): for key, value in itertools.chain(six.iteritems(trans_cat), six.iteritems(trans_fallback_cat)): if key == '' or key in catalog: continue - if isinstance(key, six.string_types): + if isinstance(key, str): catalog[key] = value elif isinstance(key, tuple): msgid = key[0] diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index 48e746031450..33bf85a9ffd4 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -12,7 +12,7 @@ from django.test import TestCase, override_settings from django.test.client import RequestFactory from django.urls import reverse -from django.utils import formats, six +from django.utils import formats from .admin import ( BandAdmin, ChildAdmin, ChordsBandAdmin, ConcertAdmin, @@ -466,7 +466,7 @@ def test_computed_list_display_localization(self): event = Event.objects.create(date=datetime.date.today()) response = self.client.get(reverse('admin:admin_changelist_event_changelist')) self.assertContains(response, formats.localize(event.date)) - self.assertNotContains(response, six.text_type(event.date)) + self.assertNotContains(response, str(event.date)) def test_dynamic_list_display(self): """ @@ -581,9 +581,9 @@ def test_tuple_list_display(self): request = self._mocked_authenticated_request('/swallow/', superuser) response = model_admin.changelist_view(request) # just want to ensure it doesn't blow up during rendering - self.assertContains(response, six.text_type(swallow.origin)) - self.assertContains(response, six.text_type(swallow.load)) - self.assertContains(response, six.text_type(swallow.speed)) + self.assertContains(response, str(swallow.origin)) + self.assertContains(response, str(swallow.load)) + self.assertContains(response, str(swallow.speed)) # Reverse one-to-one relations should work. self.assertContains(response, '-') self.assertContains(response, '%s' % swallow_o2o) diff --git a/tests/admin_utils/models.py b/tests/admin_utils/models.py index 1af2f094110d..cf90421e9a36 100644 --- a/tests/admin_utils/models.py +++ b/tests/admin_utils/models.py @@ -1,5 +1,4 @@ from django.db import models -from django.utils import six from django.utils.translation import ugettext_lazy as _ @@ -37,7 +36,7 @@ class Count(models.Model): parent = models.ForeignKey('self', models.CASCADE, null=True) def __str__(self): - return six.text_type(self.num) + return str(self.num) class Event(models.Model): diff --git a/tests/admin_utils/test_logentry.py b/tests/admin_utils/test_logentry.py index 89b25f462b47..c2eee96f48f6 100644 --- a/tests/admin_utils/test_logentry.py +++ b/tests/admin_utils/test_logentry.py @@ -7,7 +7,7 @@ from django.contrib.contenttypes.models import ContentType from django.test import TestCase, override_settings from django.urls import reverse -from django.utils import six, translation +from django.utils import translation from django.utils.encoding import force_bytes from django.utils.html import escape @@ -164,17 +164,17 @@ def test_logentry_unicode(self): log_entry = LogEntry() log_entry.action_flag = ADDITION - self.assertTrue(six.text_type(log_entry).startswith('Added ')) + self.assertTrue(str(log_entry).startswith('Added ')) log_entry.action_flag = CHANGE - self.assertTrue(six.text_type(log_entry).startswith('Changed ')) + self.assertTrue(str(log_entry).startswith('Changed ')) log_entry.action_flag = DELETION - self.assertTrue(six.text_type(log_entry).startswith('Deleted ')) + self.assertTrue(str(log_entry).startswith('Deleted ')) # Make sure custom action_flags works log_entry.action_flag = 4 - self.assertEqual(six.text_type(log_entry), 'LogEntry Object') + self.assertEqual(str(log_entry), 'LogEntry Object') def test_log_action(self): content_type_pk = ContentType.objects.get_for_model(Article).pk diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index 2353a9ee7aaa..fb404e5fd268 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -29,7 +29,7 @@ ) from django.test.utils import override_script_prefix, patch_logger from django.urls import NoReverseMatch, resolve, reverse -from django.utils import formats, six, translation +from django.utils import formats, translation from django.utils._os import upath from django.utils.cache import get_max_age from django.utils.deprecation import RemovedInDjango21Warning @@ -3759,7 +3759,7 @@ def test_edit_model_modeladmin_defer_qs(self): self.assertEqual(response.status_code, 200) self.assertEqual(ShortMessage.objects.count(), 1) # Message should contain non-ugly model verbose name. The ugly(!) - # instance representation is set by six.text_type() + # instance representation is set by __str__(). self.assertContains( response, '
  • The short message "' @@ -3806,7 +3806,7 @@ def test_edit_model_modeladmin_only_qs(self): self.assertEqual(response.status_code, 200) self.assertEqual(Paper.objects.count(), 1) # Message should contain non-ugly model verbose name. The ugly(!) - # instance representation is set by six.text_type() + # instance representation is set by __str__(). self.assertContains( response, '
  • The paper "' @@ -3863,8 +3863,8 @@ def test_inline_file_upload_edit_validation_error_post(self): "pictures-TOTAL_FORMS": "2", "pictures-INITIAL_FORMS": "1", "pictures-MAX_NUM_FORMS": "0", - "pictures-0-id": six.text_type(self.picture.id), - "pictures-0-gallery": six.text_type(self.gallery.id), + "pictures-0-id": str(self.picture.id), + "pictures-0-gallery": str(self.gallery.id), "pictures-0-name": "Test Picture", "pictures-0-image": "", "pictures-1-id": "", diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py index 8eadab07d577..ae8443565da6 100644 --- a/tests/admin_widgets/tests.py +++ b/tests/admin_widgets/tests.py @@ -17,7 +17,7 @@ from django.db.models import CharField, DateField, DateTimeField from django.test import SimpleTestCase, TestCase, override_settings from django.urls import reverse -from django.utils import six, translation +from django.utils import translation from .models import ( Advisor, Album, Band, Bee, Car, Company, Event, Honeycomb, Individual, @@ -180,7 +180,7 @@ class AdvisorAdmin(admin.ModelAdmin): ma = AdvisorAdmin(Advisor, admin.site) f = ma.formfield_for_dbfield(Advisor._meta.get_field('companies'), request=None) self.assertEqual( - six.text_type(f.help_text), + f.help_text, 'Hold down "Control", or "Command" on a Mac, to select more than one.' ) diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index ac57bbd511e0..9335b75dba2e 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -79,7 +79,7 @@ def tearDown(self): management.get_system_username = self.old_get_system_username def test_actual_implementation(self): - self.assertIsInstance(management.get_system_username(), six.text_type) + self.assertIsInstance(management.get_system_username(), str) def test_simple(self): management.get_system_username = lambda: 'joe' diff --git a/tests/backends/tests.py b/tests/backends/tests.py index 7a102b040a30..a7939ed8beb7 100644 --- a/tests/backends/tests.py +++ b/tests/backends/tests.py @@ -23,7 +23,6 @@ SimpleTestCase, TestCase, TransactionTestCase, mock, override_settings, skipIfDBFeature, skipUnlessDBFeature, ) -from django.utils import six from django.utils.six.moves import range from .models import ( @@ -101,7 +100,7 @@ def test_long_string(self): # than 4000 chars and read it properly with connection.cursor() as cursor: cursor.execute('CREATE TABLE ltext ("TEXT" NCLOB)') - long_str = ''.join(six.text_type(x) for x in range(4000)) + long_str = ''.join(str(x) for x in range(4000)) cursor.execute('INSERT INTO ltext VALUES (%s)', [long_str]) cursor.execute('SELECT text FROM ltext') row = cursor.fetchone() @@ -419,7 +418,7 @@ def test_query_encoding(self): sql, params = data.query.sql_with_params() cursor = data.query.get_compiler('default').execute_sql(CURSOR) last_sql = cursor.db.ops.last_executed_query(cursor, sql, params) - self.assertIsInstance(last_sql, six.text_type) + self.assertIsInstance(last_sql, str) @unittest.skipUnless(connection.vendor == 'sqlite', "This test is specific to SQLite.") diff --git a/tests/contenttypes_tests/test_models.py b/tests/contenttypes_tests/test_models.py index bb0f8c890f24..4c16e0b4aa05 100644 --- a/tests/contenttypes_tests/test_models.py +++ b/tests/contenttypes_tests/test_models.py @@ -3,7 +3,6 @@ from django.contrib.sites.shortcuts import get_current_site from django.http import Http404, HttpRequest from django.test import TestCase, override_settings -from django.utils import six from .models import ( ConcreteModel, FooWithBrokenAbsoluteUrl, FooWithoutUrl, FooWithUrl, @@ -242,7 +241,7 @@ def test_missing_model(self): app_label='contenttypes', model='OldModel', ) - self.assertEqual(six.text_type(ct), 'OldModel') + self.assertEqual(str(ct), 'OldModel') self.assertIsNone(ct.model_class()) # Make sure stale ContentTypes can be fetched like any other object. diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py index 33f30a83537f..49247b7af8b5 100644 --- a/tests/csrf_tests/tests.py +++ b/tests/csrf_tests/tests.py @@ -13,7 +13,6 @@ from django.test import SimpleTestCase, override_settings from django.test.utils import patch_logger from django.utils.encoding import force_bytes -from django.utils.six import text_type from django.views.decorators.csrf import csrf_exempt, requires_csrf_token from .views import ( @@ -65,7 +64,7 @@ def _get_POST_request_with_token(self): return req def _check_token_present(self, response, csrf_id=None): - text = text_type(response.content, response.charset) + text = str(response.content, response.charset) match = re.search("name='csrfmiddlewaretoken' value='(.*?)'", text) csrf_token = csrf_id or self._csrf_id self.assertTrue( diff --git a/tests/custom_columns/tests.py b/tests/custom_columns/tests.py index 04aca1291479..2d7044b8de14 100644 --- a/tests/custom_columns/tests.py +++ b/tests/custom_columns/tests.py @@ -1,6 +1,5 @@ from django.core.exceptions import FieldError from django.test import TestCase -from django.utils import six from .models import Article, Author @@ -20,7 +19,7 @@ def test_query_all_available_authors(self): Author.objects.all(), [ "Peter Jones", "John Smith", ], - six.text_type + str ) def test_get_first_name(self): @@ -34,7 +33,7 @@ def test_filter_first_name(self): Author.objects.filter(first_name__exact="John"), [ "John Smith", ], - six.text_type + str ) def test_field_error(self): @@ -54,7 +53,7 @@ def test_get_all_authors_for_an_article(self): "Peter Jones", "John Smith", ], - six.text_type + str ) def test_get_all_articles_for_an_author(self): @@ -70,7 +69,7 @@ def test_get_author_m2m_relation(self): self.article.authors.filter(last_name='Jones'), [ "Peter Jones" ], - six.text_type + str ) def test_author_querying(self): diff --git a/tests/custom_managers/tests.py b/tests/custom_managers/tests.py index 1bfaf5276621..54f3b58a7991 100644 --- a/tests/custom_managers/tests.py +++ b/tests/custom_managers/tests.py @@ -1,6 +1,5 @@ from django.db import models from django.test import TestCase -from django.utils import six from .models import ( Book, Car, CustomManager, CustomQuerySet, DeconstructibleCustomManager, @@ -34,7 +33,7 @@ def test_custom_manager_basic(self): Person.objects.get_fun_people(), [ "Bugs Bunny" ], - six.text_type + str ) def test_queryset_copied_to_default(self): @@ -67,12 +66,12 @@ def test_manager_use_queryset_methods(self): for manager_name in self.custom_manager_names: manager = getattr(Person, manager_name) queryset = manager.filter() - self.assertQuerysetEqual(queryset, ["Bugs Bunny"], six.text_type) + self.assertQuerysetEqual(queryset, ["Bugs Bunny"], str) self.assertIs(queryset._filter_CustomQuerySet, True) # Specialized querysets inherit from our custom queryset. queryset = manager.values_list('first_name', flat=True).filter() - self.assertEqual(list(queryset), [six.text_type("Bugs")]) + self.assertEqual(list(queryset), ["Bugs"]) self.assertIs(queryset._filter_CustomQuerySet, True) self.assertIsInstance(queryset.values(), CustomQuerySet) @@ -99,7 +98,7 @@ def test_queryset_and_manager(self): Queryset method doesn't override the custom manager method. """ queryset = Person.custom_queryset_custom_manager.filter() - self.assertQuerysetEqual(queryset, ["Bugs Bunny"], six.text_type) + self.assertQuerysetEqual(queryset, ["Bugs Bunny"], str) self.assertIs(queryset._filter_CustomManager, True) def test_related_manager(self): diff --git a/tests/custom_pk/fields.py b/tests/custom_pk/fields.py index eb63f66679b4..fa61a72a0d7e 100644 --- a/tests/custom_pk/fields.py +++ b/tests/custom_pk/fields.py @@ -2,7 +2,6 @@ import string from django.db import models -from django.utils import six class MyWrapper(object): @@ -50,12 +49,12 @@ def get_db_prep_save(self, value, connection): if not value: return if isinstance(value, MyWrapper): - return six.text_type(value) + return str(value) return value def get_db_prep_value(self, value, connection, prepared=False): if not value: return if isinstance(value, MyWrapper): - return six.text_type(value) + return str(value) return value diff --git a/tests/custom_pk/tests.py b/tests/custom_pk/tests.py index 01150a46d272..7c89b6d1201d 100644 --- a/tests/custom_pk/tests.py +++ b/tests/custom_pk/tests.py @@ -1,6 +1,5 @@ from django.db import IntegrityError, transaction from django.test import TestCase, skipIfDBFeature -from django.utils import six from .models import Bar, Business, Employee, Foo @@ -25,14 +24,14 @@ def test_querysets(self): Employee.objects.filter(pk=123), [ "Dan Jones", ], - six.text_type + str ) self.assertQuerysetEqual( Employee.objects.filter(employee_code=123), [ "Dan Jones", ], - six.text_type + str ) self.assertQuerysetEqual( @@ -40,7 +39,7 @@ def test_querysets(self): "Fran Bones", "Dan Jones", ], - six.text_type + str ) self.assertQuerysetEqual( @@ -48,7 +47,7 @@ def test_querysets(self): "Fran Bones", "Dan Jones", ], - six.text_type + str ) self.assertQuerysetEqual( @@ -73,7 +72,7 @@ def test_querysets_related_name(self): "Fran Bones", "Dan Jones", ], - six.text_type + str ) self.assertQuerysetEqual( self.fran.business_set.all(), [ @@ -91,14 +90,14 @@ def test_querysets_relational(self): "Fran Bones", "Dan Jones", ], - six.text_type, + str, ) self.assertQuerysetEqual( Employee.objects.filter(business__pk="Sears"), [ "Fran Bones", "Dan Jones", ], - six.text_type, + str, ) self.assertQuerysetEqual( @@ -173,7 +172,7 @@ def test_save(self): "Dan Jones", "Fran Jones", ], - six.text_type + str ) diff --git a/tests/datatypes/tests.py b/tests/datatypes/tests.py index b6899c7609cc..5c3dffa45767 100644 --- a/tests/datatypes/tests.py +++ b/tests/datatypes/tests.py @@ -1,7 +1,6 @@ import datetime from django.test import TestCase, skipIfDBFeature -from django.utils import six from django.utils.timezone import utc from .models import Donut, RumBaba @@ -75,7 +74,7 @@ def test_textfields_unicode(self): database should be unicode.""" d = Donut.objects.create(name='Jelly Donut', review='Outstanding') newd = Donut.objects.get(id=d.id) - self.assertIsInstance(newd.review, six.text_type) + self.assertIsInstance(newd.review, str) @skipIfDBFeature('supports_timezones') def test_error_on_timezone(self): diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index d3eabb6dbb73..0a414942178e 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -20,7 +20,6 @@ from django.db.models.sql.datastructures import Join from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature from django.test.utils import Approximate -from django.utils import six from .models import ( UUID, Company, Employee, Experiment, Number, Result, SimulationRun, Time, @@ -202,7 +201,7 @@ def test_update_with_fk(self): "Frank Meyer", "Max Mustermann", ], - lambda c: six.text_type(c.point_of_contact), + lambda c: str(c.point_of_contact), ordered=False ) diff --git a/tests/expressions_case/tests.py b/tests/expressions_case/tests.py index 414c4353a527..a662ffbc3b27 100644 --- a/tests/expressions_case/tests.py +++ b/tests/expressions_case/tests.py @@ -9,7 +9,6 @@ from django.db.models import F, Max, Min, Q, Sum, Value from django.db.models.expressions import Case, When from django.test import TestCase -from django.utils import six from .models import CaseTestModel, Client, FKCaseTestModel, O2OCaseTestModel @@ -648,7 +647,7 @@ def test_update_binary(self): self.assertQuerysetEqual( CaseTestModel.objects.all().order_by('pk'), [(1, b'one'), (2, b'two'), (3, b''), (2, b'two'), (3, b''), (3, b''), (4, b'')], - transform=lambda o: (o.integer, six.binary_type(o.binary)) + transform=lambda o: (o.integer, bytes(o.binary)) ) def test_update_boolean(self): @@ -757,7 +756,7 @@ def test_update_file(self): self.assertQuerysetEqual( CaseTestModel.objects.all().order_by('pk'), [(1, '~/1'), (2, '~/2'), (3, ''), (2, '~/2'), (3, ''), (3, ''), (4, '')], - transform=lambda o: (o.integer, six.text_type(o.file)) + transform=lambda o: (o.integer, str(o.file)) ) def test_update_file_path(self): @@ -798,7 +797,7 @@ def test_update_image(self): self.assertQuerysetEqual( CaseTestModel.objects.all().order_by('pk'), [(1, '~/1'), (2, '~/2'), (3, ''), (2, '~/2'), (3, ''), (3, ''), (4, '')], - transform=lambda o: (o.integer, six.text_type(o.image)) + transform=lambda o: (o.integer, str(o.image)) ) def test_update_generic_ip_address(self): diff --git a/tests/field_deconstruction/tests.py b/tests/field_deconstruction/tests.py index bb16f4d76e42..7b816b8bf0b2 100644 --- a/tests/field_deconstruction/tests.py +++ b/tests/field_deconstruction/tests.py @@ -2,7 +2,6 @@ from django.db import models from django.test import SimpleTestCase, override_settings from django.test.utils import isolate_lru_cache -from django.utils import six class FieldDeconstructionTests(SimpleTestCase): @@ -21,7 +20,6 @@ def test_name(self): field.set_attributes_from_name("is_awesome_test") name, path, args, kwargs = field.deconstruct() self.assertEqual(name, "is_awesome_test") - self.assertIsInstance(name, six.text_type) # Now try with a ForeignKey field = models.ForeignKey("some_fake.ModelName", models.CASCADE) name, path, args, kwargs = field.deconstruct() diff --git a/tests/field_defaults/tests.py b/tests/field_defaults/tests.py index 031fd75fe33a..19b05aa5374a 100644 --- a/tests/field_defaults/tests.py +++ b/tests/field_defaults/tests.py @@ -1,7 +1,6 @@ from datetime import datetime from django.test import TestCase -from django.utils import six from .models import Article @@ -12,6 +11,6 @@ def test_field_defaults(self): now = datetime.now() a.save() - self.assertIsInstance(a.id, six.integer_types) + self.assertIsInstance(a.id, int) self.assertEqual(a.headline, "Default headline") self.assertLess((now - a.pub_date).seconds, 5) diff --git a/tests/file_uploads/views.py b/tests/file_uploads/views.py index bba71b87c272..c4166087acc9 100644 --- a/tests/file_uploads/views.py +++ b/tests/file_uploads/views.py @@ -5,7 +5,6 @@ from django.core.files.uploadedfile import UploadedFile from django.http import HttpResponse, HttpResponseServerError -from django.utils import six from django.utils.encoding import force_bytes, force_str from .models import FileModel @@ -19,7 +18,7 @@ def file_upload_view(request): """ form_data = request.POST.copy() form_data.update(request.FILES) - if isinstance(form_data.get('file_field'), UploadedFile) and isinstance(form_data['name'], six.text_type): + if isinstance(form_data.get('file_field'), UploadedFile) and isinstance(form_data['name'], str): # If a file is posted, the dummy client should only post the file name, # not the full path. if os.path.dirname(form_data['file_field'].name) != '': diff --git a/tests/files/tests.py b/tests/files/tests.py index a0ff3d4782f8..50db4b7436c3 100644 --- a/tests/files/tests.py +++ b/tests/files/tests.py @@ -11,7 +11,6 @@ from django.core.files.temp import NamedTemporaryFile from django.core.files.uploadedfile import SimpleUploadedFile, UploadedFile from django.test import mock -from django.utils import six from django.utils._os import upath try: @@ -177,11 +176,11 @@ def test_content_file_custom_name(self): def test_content_file_input_type(self): """ - ContentFile can accept both bytes and unicode and that the - retrieved content is of the same type. + ContentFile can accept both bytes and strings and the retrieved content + is of the same type. """ self.assertIsInstance(ContentFile(b"content").read(), bytes) - self.assertIsInstance(ContentFile("español").read(), six.text_type) + self.assertIsInstance(ContentFile("español").read(), str) class DimensionClosingBug(unittest.TestCase): diff --git a/tests/fixtures_regress/models.py b/tests/fixtures_regress/models.py index a631fa44d105..d76642ac97b7 100644 --- a/tests/fixtures_regress/models.py +++ b/tests/fixtures_regress/models.py @@ -1,6 +1,5 @@ from django.contrib.auth.models import User from django.db import models -from django.utils import six class Animal(models.Model): @@ -29,7 +28,7 @@ class Stuff(models.Model): owner = models.ForeignKey(User, models.SET_NULL, null=True) def __str__(self): - return six.text_type(self.name) + ' is owned by ' + six.text_type(self.owner) + return self.name + ' is owned by ' + str(self.owner) class Absolute(models.Model): diff --git a/tests/forms_tests/field_tests/test_filepathfield.py b/tests/forms_tests/field_tests/test_filepathfield.py index 07ebe67f06ca..71164b5b7ac5 100644 --- a/tests/forms_tests/field_tests/test_filepathfield.py +++ b/tests/forms_tests/field_tests/test_filepathfield.py @@ -2,12 +2,11 @@ from django.forms import FilePathField, ValidationError, forms from django.test import SimpleTestCase -from django.utils import six from django.utils._os import upath def fix_os_paths(x): - if isinstance(x, six.string_types): + if isinstance(x, str): return x.replace('\\', '/') elif isinstance(x, tuple): return tuple(fix_os_paths(list(x))) diff --git a/tests/forms_tests/field_tests/test_typedchoicefield.py b/tests/forms_tests/field_tests/test_typedchoicefield.py index c08a8bb6110c..bf0fdb4d47c1 100644 --- a/tests/forms_tests/field_tests/test_typedchoicefield.py +++ b/tests/forms_tests/field_tests/test_typedchoicefield.py @@ -2,7 +2,6 @@ from django.forms import TypedChoiceField, ValidationError from django.test import SimpleTestCase -from django.utils import six class TypedChoiceFieldTest(SimpleTestCase): @@ -53,7 +52,7 @@ def test_typedchoicefield_has_changed(self): self.assertFalse(f.has_changed('1', '1')) f = TypedChoiceField( - choices=[('', '---------'), ('a', "a"), ('b', "b")], coerce=six.text_type, + choices=[('', '---------'), ('a', "a"), ('b', "b")], coerce=str, required=False, initial=None, empty_value=None, ) self.assertFalse(f.has_changed(None, '')) diff --git a/tests/forms_tests/tests/test_utils.py b/tests/forms_tests/tests/test_utils.py index f06b60a620d6..f52c1956377e 100644 --- a/tests/forms_tests/tests/test_utils.py +++ b/tests/forms_tests/tests/test_utils.py @@ -3,7 +3,6 @@ from django.core.exceptions import ValidationError from django.forms.utils import ErrorDict, ErrorList, flatatt from django.test import SimpleTestCase -from django.utils import six from django.utils.encoding import force_text from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy @@ -63,7 +62,7 @@ def test_validation_error(self): ) # Can take a unicode string. self.assertHTMLEqual( - six.text_type(ErrorList(ValidationError("Not \u03C0.").messages)), + str(ErrorList(ValidationError("Not \u03C0.").messages)), '
    • Not π.
    ' ) # Can take a lazy string. diff --git a/tests/forms_tests/tests/tests.py b/tests/forms_tests/tests/tests.py index 025b74976213..0119410fc86d 100644 --- a/tests/forms_tests/tests/tests.py +++ b/tests/forms_tests/tests/tests.py @@ -7,7 +7,6 @@ ) from django.forms.models import ModelFormMetaclass from django.test import SimpleTestCase, TestCase -from django.utils import six from ..models import ( BoundaryModel, ChoiceFieldModel, ChoiceModel, ChoiceOptionModel, Defaults, @@ -97,7 +96,7 @@ def test_no_empty_option(self): choices = list(ChoiceFieldForm().fields['choice'].choices) self.assertEqual(len(choices), 1) - self.assertEqual(choices[0], (option.pk, six.text_type(option))) + self.assertEqual(choices[0], (option.pk, str(option))) def test_callable_initial_value(self): "The initial value for a callable default returning a queryset is the pk (refs #13769)" diff --git a/tests/gis_tests/geoadmin/tests.py b/tests/gis_tests/geoadmin/tests.py index 23fa8071b36c..96877c26e3dd 100644 --- a/tests/gis_tests/geoadmin/tests.py +++ b/tests/gis_tests/geoadmin/tests.py @@ -96,6 +96,6 @@ def test_olwidget_invalid_string(self): self.assertEqual(len(logger_calls), 1) self.assertEqual( logger_calls[0], - "Error creating geometry from value 'INVALID()' (String or unicode input " + "Error creating geometry from value 'INVALID()' (String input " "unrecognized as WKT EWKT, and HEXEWKB.)" ) diff --git a/tests/gis_tests/geoapp/test_functions.py b/tests/gis_tests/geoapp/test_functions.py index 2767b7974b71..4d3913a7a3dc 100644 --- a/tests/gis_tests/geoapp/test_functions.py +++ b/tests/gis_tests/geoapp/test_functions.py @@ -7,7 +7,6 @@ from django.db import connection from django.db.models import Sum from django.test import TestCase, skipUnlessDBFeature -from django.utils import six from ..utils import mysql, oracle, postgis, spatialite from .models import City, Country, CountryWebMercator, State, Track @@ -361,7 +360,7 @@ def test_snap_to_grid(self): for bad_args in ((), range(3), range(5)): with self.assertRaises(ValueError): Country.objects.annotate(snap=functions.SnapToGrid('mpoly', *bad_args)) - for bad_args in (('1.0',), (1.0, None), tuple(map(six.text_type, range(4)))): + for bad_args in (('1.0',), (1.0, None), tuple(map(str, range(4)))): with self.assertRaises(TypeError): Country.objects.annotate(snap=functions.SnapToGrid('mpoly', *bad_args)) diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index ff28eebf0f52..7877e1f2d61e 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -17,7 +17,6 @@ from django.template import Context from django.template.engine import Engine from django.test import SimpleTestCase, mock -from django.utils import six from django.utils.encoding import force_bytes from django.utils.six.moves import range @@ -65,8 +64,8 @@ def test_hexewkb(self): self.assertIs(GEOSGeometry(hexewkb_3d).hasz, True) # Same for EWKB. - self.assertEqual(six.memoryview(a2b_hex(hexewkb_2d)), pnt_2d.ewkb) - self.assertEqual(six.memoryview(a2b_hex(hexewkb_3d)), pnt_3d.ewkb) + self.assertEqual(memoryview(a2b_hex(hexewkb_2d)), pnt_2d.ewkb) + self.assertEqual(memoryview(a2b_hex(hexewkb_3d)), pnt_3d.ewkb) # Redundant sanity check. self.assertEqual(4326, GEOSGeometry(hexewkb_2d).srid) @@ -88,7 +87,7 @@ def test_errors(self): # Bad WKB with self.assertRaises(GEOSException): - GEOSGeometry(six.memoryview(b'0')) + GEOSGeometry(memoryview(b'0')) class NotAGeometry(object): pass @@ -118,7 +117,7 @@ def test_create_hex(self): def test_create_wkb(self): "Testing creation from WKB." for g in self.geometries.hex_wkt: - wkb = six.memoryview(a2b_hex(g.hex.encode())) + wkb = memoryview(a2b_hex(g.hex.encode())) geom_h = GEOSGeometry(wkb) # we need to do this so decimal places get normalized geom_t = fromstr(g.wkt) @@ -1164,13 +1163,13 @@ def test_valid_reason(self): g = GEOSGeometry("POINT(0 0)") self.assertTrue(g.valid) - self.assertIsInstance(g.valid_reason, six.string_types) + self.assertIsInstance(g.valid_reason, str) self.assertEqual(g.valid_reason, "Valid Geometry") g = GEOSGeometry("LINESTRING(0 0, 0 0)") self.assertFalse(g.valid) - self.assertIsInstance(g.valid_reason, six.string_types) + self.assertIsInstance(g.valid_reason, str) self.assertTrue(g.valid_reason.startswith("Too few points in geometry component")) def test_linearref(self): diff --git a/tests/gis_tests/geos_tests/test_io.py b/tests/gis_tests/geos_tests/test_io.py index 81e0ff357fc7..98b2aba3b459 100644 --- a/tests/gis_tests/geos_tests/test_io.py +++ b/tests/gis_tests/geos_tests/test_io.py @@ -6,7 +6,6 @@ WKTWriter, ) from django.test import SimpleTestCase -from django.utils.six import memoryview @skipUnless(HAS_GEOS, "Geos is required.") @@ -25,7 +24,7 @@ def test01_wktreader(self): for geom in (g1, g2): self.assertEqual(ref, geom) - # Should only accept six.string_types objects. + # Should only accept string objects. with self.assertRaises(TypeError): wkt_r.read(1) with self.assertRaises(TypeError): diff --git a/tests/gis_tests/geos_tests/test_mutable_list.py b/tests/gis_tests/geos_tests/test_mutable_list.py index 3f7d8c30a17c..26bdeb804500 100644 --- a/tests/gis_tests/geos_tests/test_mutable_list.py +++ b/tests/gis_tests/geos_tests/test_mutable_list.py @@ -7,7 +7,6 @@ import unittest from django.contrib.gis.geos.mutable_list import ListMixin -from django.utils import six class UserListA(ListMixin): @@ -298,7 +297,7 @@ def removefcn(x, v): def test07_allowed_types(self): 'Type-restricted list' pl, ul = self.lists_of_len() - ul._allowed = six.integer_types + ul._allowed = int ul[1] = 50 ul[:2] = [60, 70, 80] diff --git a/tests/gis_tests/test_geoforms.py b/tests/gis_tests/test_geoforms.py index 27b80ce9b2d7..6fe0996721b8 100644 --- a/tests/gis_tests/test_geoforms.py +++ b/tests/gis_tests/test_geoforms.py @@ -132,7 +132,7 @@ class PointForm(forms.Form): self.assertEqual(len(logger_calls), 1) self.assertEqual( logger_calls[0], - "Error creating geometry from value 'PNT(0)' (String or unicode input " + "Error creating geometry from value 'PNT(0)' (String input " "unrecognized as WKT EWKT, and HEXEWKB.)" ) diff --git a/tests/gis_tests/test_geoip2.py b/tests/gis_tests/test_geoip2.py index 54f20412a4f7..d35dcc336ec9 100644 --- a/tests/gis_tests/test_geoip2.py +++ b/tests/gis_tests/test_geoip2.py @@ -6,7 +6,6 @@ from django.contrib.gis.geoip2 import HAS_GEOIP2 from django.contrib.gis.geos import HAS_GEOS, GEOSGeometry from django.test import mock -from django.utils import six if HAS_GEOIP2: from django.contrib.gis.geoip2 import GeoIP2, GeoIP2Exception @@ -48,7 +47,7 @@ def test01_init(self): for bad in bad_params: with self.assertRaises(GeoIP2Exception): GeoIP2(cache=bad) - if isinstance(bad, six.string_types): + if isinstance(bad, str): e = GeoIP2Exception else: e = TypeError diff --git a/tests/handlers/tests.py b/tests/handlers/tests.py index 72ba98b1d3b5..d7cfaadf6293 100644 --- a/tests/handlers/tests.py +++ b/tests/handlers/tests.py @@ -7,7 +7,6 @@ from django.test import ( RequestFactory, SimpleTestCase, TransactionTestCase, override_settings, ) -from django.utils import six from django.utils.encoding import force_str try: @@ -185,7 +184,7 @@ def test_invalid_urls(self): def test_environ_path_info_type(self): environ = RequestFactory().get('/%E2%A8%87%87%A5%E2%A8%A0').environ - self.assertIsInstance(environ['PATH_INFO'], six.text_type) + self.assertIsInstance(environ['PATH_INFO'], str) @unittest.skipIf(HTTPStatus is None, 'HTTPStatus only exists on Python 3.5+') def test_handle_accepts_httpstatus_enum_value(self): diff --git a/tests/httpwrappers/tests.py b/tests/httpwrappers/tests.py index 9042f8ed6e8d..b8d359de4154 100644 --- a/tests/httpwrappers/tests.py +++ b/tests/httpwrappers/tests.py @@ -578,7 +578,7 @@ def test_streaming_response(self): chunks = list(r) self.assertEqual(chunks, [b'hello', b'world']) for chunk in chunks: - self.assertIsInstance(chunk, six.binary_type) + self.assertIsInstance(chunk, bytes) # and the response can only be iterated once. self.assertEqual(list(r), []) @@ -595,7 +595,7 @@ def test_streaming_response(self): # '\xc3\xa9' == unichr(233).encode('utf-8') self.assertEqual(chunks, [b'hello', b'caf\xc3\xa9']) for chunk in chunks: - self.assertIsInstance(chunk, six.binary_type) + self.assertIsInstance(chunk, bytes) # streaming responses don't have a `content` attribute. self.assertFalse(hasattr(r, 'content')) @@ -616,8 +616,7 @@ def test_streaming_response(self): # coercing a streaming response to bytes doesn't return a complete HTTP # message like a regular response does. it only gives us the headers. r = StreamingHttpResponse(iter(['hello', 'world'])) - self.assertEqual( - six.binary_type(r), b'Content-Type: text/html; charset=utf-8') + self.assertEqual(bytes(r), b'Content-Type: text/html; charset=utf-8') # and this won't consume its content. self.assertEqual(list(r), [b'hello', b'world']) diff --git a/tests/i18n/contenttypes/tests.py b/tests/i18n/contenttypes/tests.py index 2a14e25972ca..94f355aba75a 100644 --- a/tests/i18n/contenttypes/tests.py +++ b/tests/i18n/contenttypes/tests.py @@ -2,7 +2,7 @@ from django.contrib.contenttypes.models import ContentType from django.test import TestCase, override_settings -from django.utils import six, translation +from django.utils import translation from django.utils._os import upath @@ -21,6 +21,6 @@ class ContentTypeTests(TestCase): def test_verbose_name(self): company_type = ContentType.objects.get(app_label='i18n', model='company') with translation.override('en'): - self.assertEqual(six.text_type(company_type), 'Company') + self.assertEqual(str(company_type), 'Company') with translation.override('fr'): - self.assertEqual(six.text_type(company_type), 'Société') + self.assertEqual(str(company_type), 'Société') diff --git a/tests/i18n/test_extraction.py b/tests/i18n/test_extraction.py index 33e136e1dd1c..b8342865a9ab 100644 --- a/tests/i18n/test_extraction.py +++ b/tests/i18n/test_extraction.py @@ -16,7 +16,6 @@ from django.core.management.utils import find_command from django.test import SimpleTestCase, mock, override_settings from django.test.utils import captured_stderr, captured_stdout -from django.utils import six from django.utils.encoding import force_text from django.utils.six import StringIO from django.utils.translation import TranslatorCommentWarning @@ -69,7 +68,7 @@ def _assertPoLocComment(self, assert_presence, po_filename, line_number, *commen path = os.path.join(cwd_prefix, *comment_parts) parts = [path] - if isinstance(line_number, six.string_types): + if isinstance(line_number, str): line_number = self._get_token_line_number(path, line_number) if line_number is not None: parts.append(':%d' % line_number) diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py index d039d016cec7..c3acdfe2fc4a 100644 --- a/tests/i18n/tests.py +++ b/tests/i18n/tests.py @@ -14,7 +14,7 @@ from django.test import ( RequestFactory, SimpleTestCase, TestCase, override_settings, ) -from django.utils import six, translation +from django.utils import translation from django.utils._os import upath from django.utils.formats import ( date_format, get_format, get_format_modules, iter_format_modules, localize, @@ -140,9 +140,9 @@ def test_lazy_objects(self): def test_lazy_pickle(self): s1 = ugettext_lazy("test") - self.assertEqual(six.text_type(s1), "test") + self.assertEqual(str(s1), "test") s2 = pickle.loads(pickle.dumps(s1)) - self.assertEqual(six.text_type(s2), "test") + self.assertEqual(str(s2), "test") @override_settings(LOCALE_PATHS=extended_locale_paths) def test_ungettext_lazy(self): diff --git a/tests/inline_formsets/tests.py b/tests/inline_formsets/tests.py index 0fb2fd2f026d..fd51714cdac1 100644 --- a/tests/inline_formsets/tests.py +++ b/tests/inline_formsets/tests.py @@ -1,6 +1,5 @@ from django.forms.models import ModelForm, inlineformset_factory from django.test import TestCase, skipUnlessDBFeature -from django.utils import six from .models import Child, Parent, Poem, Poet, School @@ -65,8 +64,8 @@ def test_change_form_deletion_when_invalid(self): 'poem_set-TOTAL_FORMS': '1', 'poem_set-INITIAL_FORMS': '1', 'poem_set-MAX_NUM_FORMS': '0', - 'poem_set-0-id': six.text_type(poem.id), - 'poem_set-0-poem': six.text_type(poem.id), + 'poem_set-0-id': str(poem.id), + 'poem_set-0-poem': str(poem.id), 'poem_set-0-name': 'x' * 1000, } formset = PoemFormSet(data, instance=poet) diff --git a/tests/lookup/models.py b/tests/lookup/models.py index 9cf053d87300..14742e8a8cec 100644 --- a/tests/lookup/models.py +++ b/tests/lookup/models.py @@ -5,7 +5,6 @@ """ from django.db import models -from django.utils import six class Alarm(models.Model): @@ -48,7 +47,7 @@ class Season(models.Model): gt = models.IntegerField(null=True, blank=True) def __str__(self): - return six.text_type(self.year) + return str(self.year) class Game(models.Model): diff --git a/tests/m2m_and_m2o/models.py b/tests/m2m_and_m2o/models.py index 7174e6369a72..d9da2bf53420 100644 --- a/tests/m2m_and_m2o/models.py +++ b/tests/m2m_and_m2o/models.py @@ -4,7 +4,6 @@ Make sure to set ``related_name`` if you use relationships to the same table. """ from django.db import models -from django.utils import six class User(models.Model): @@ -17,7 +16,7 @@ class Issue(models.Model): client = models.ForeignKey(User, models.CASCADE, related_name='test_issue_client') def __str__(self): - return six.text_type(self.num) + return str(self.num) class Meta: ordering = ('num',) diff --git a/tests/m2m_intermediary/tests.py b/tests/m2m_intermediary/tests.py index d429bf6516f1..215f6f86c6da 100644 --- a/tests/m2m_intermediary/tests.py +++ b/tests/m2m_intermediary/tests.py @@ -1,7 +1,6 @@ from datetime import datetime from django.test import TestCase -from django.utils import six from .models import Article, Reporter, Writer @@ -23,7 +22,7 @@ def test_intermeiary(self): ("John Smith", "Main writer"), ("Jane Doe", "Contributor"), ], - lambda w: (six.text_type(w.reporter), w.position) + lambda w: (str(w.reporter), w.position) ) self.assertEqual(w1.reporter, r1) self.assertEqual(w2.reporter, r2) @@ -35,5 +34,5 @@ def test_intermeiary(self): r1.writer_set.all(), [ ("John Smith", "Main writer") ], - lambda w: (six.text_type(w.reporter), w.position) + lambda w: (str(w.reporter), w.position) ) diff --git a/tests/mail/tests.py b/tests/mail/tests.py index cfe2889aa66b..7c2cd8342a83 100644 --- a/tests/mail/tests.py +++ b/tests/mail/tests.py @@ -26,7 +26,7 @@ from django.test.utils import requires_tz_support from django.utils._os import upath from django.utils.encoding import force_bytes, force_text -from django.utils.six import StringIO, binary_type +from django.utils.six import StringIO from django.utils.translation import ugettext_lazy @@ -40,7 +40,7 @@ def assertMessageHasHeaders(self, message, headers): with the contents of an email message. headers: should be a set of (header-name, header-value) tuples. """ - if isinstance(message, binary_type): + if isinstance(message, bytes): message = message_from_bytes(message) msg_headers = set(message.items()) self.assertTrue(headers.issubset(msg_headers), msg='Message is missing ' diff --git a/tests/migrations/test_state.py b/tests/migrations/test_state.py index c8eb1726baf4..a6b027e079ee 100644 --- a/tests/migrations/test_state.py +++ b/tests/migrations/test_state.py @@ -10,7 +10,6 @@ ) from django.test import SimpleTestCase, override_settings from django.test.utils import isolate_apps -from django.utils import six from .models import ( FoodManager, FoodQuerySet, ModelWithCustomBase, NoMigrationFoodManager, @@ -157,7 +156,7 @@ class Meta: # The default manager is used in migrations self.assertEqual([name for name, mgr in food_state.managers], ['food_mgr']) - self.assertTrue(all(isinstance(name, six.text_type) for name, mgr in food_state.managers)) + self.assertTrue(all(isinstance(name, str) for name, mgr in food_state.managers)) self.assertEqual(food_state.managers[0][1].args, ('a', 'b', 1, 2)) # No explicit managers defined. Migrations will fall back to the default @@ -167,13 +166,13 @@ class Meta: # default self.assertEqual([name for name, mgr in food_no_default_manager_state.managers], ['food_no_mgr', 'food_mgr']) - self.assertTrue(all(isinstance(name, six.text_type) for name, mgr in food_no_default_manager_state.managers)) + self.assertTrue(all(isinstance(name, str) for name, mgr in food_no_default_manager_state.managers)) self.assertEqual(food_no_default_manager_state.managers[0][1].__class__, models.Manager) self.assertIsInstance(food_no_default_manager_state.managers[1][1], FoodManager) self.assertEqual([name for name, mgr in food_order_manager_state.managers], ['food_mgr1', 'food_mgr2']) - self.assertTrue(all(isinstance(name, six.text_type) for name, mgr in food_order_manager_state.managers)) + self.assertTrue(all(isinstance(name, str) for name, mgr in food_order_manager_state.managers)) self.assertEqual([mgr.args for name, mgr in food_order_manager_state.managers], [('a', 'b', 1, 2), ('x', 'y', 3, 4)]) @@ -373,7 +372,7 @@ def test_render(self): Food = new_apps.get_model("migrations", "Food") self.assertEqual([mgr.name for mgr in Food._meta.managers], ['default', 'food_mgr1', 'food_mgr2']) - self.assertTrue(all(isinstance(mgr.name, six.text_type) for mgr in Food._meta.managers)) + self.assertTrue(all(isinstance(mgr.name, str) for mgr in Food._meta.managers)) self.assertEqual([mgr.__class__ for mgr in Food._meta.managers], [models.Manager, FoodManager, FoodManager]) diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index b92675792084..59fd8eece5e9 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -42,7 +42,7 @@ class Money(decimal.Decimal): def deconstruct(self): return ( '%s.%s' % (self.__class__.__module__, self.__class__.__name__), - [six.text_type(self)], + [str(self)], {} ) diff --git a/tests/model_fields/test_foreignkey.py b/tests/model_fields/test_foreignkey.py index a521d1aa23c7..2580e3b6504c 100644 --- a/tests/model_fields/test_foreignkey.py +++ b/tests/model_fields/test_foreignkey.py @@ -5,7 +5,6 @@ from django.db import models from django.test import TestCase, skipIfDBFeature from django.test.utils import isolate_apps -from django.utils import six from .models import Bar, FkToChar, Foo, PrimaryKeyCharModel @@ -50,7 +49,7 @@ class FKUniqueTrue(models.Model): def test_related_name_converted_to_text(self): rel_name = Bar._meta.get_field('a').remote_field.related_name - self.assertIsInstance(rel_name, six.text_type) + self.assertIsInstance(rel_name, str) def test_abstract_model_pending_operations(self): """ diff --git a/tests/model_fields/test_integerfield.py b/tests/model_fields/test_integerfield.py index a474e6e602c4..99d7b1797c0a 100644 --- a/tests/model_fields/test_integerfield.py +++ b/tests/model_fields/test_integerfield.py @@ -2,7 +2,6 @@ from django.core.exceptions import ValidationError from django.db import connection, models from django.test import SimpleTestCase, TestCase -from django.utils import six from .models import ( BigIntegerModel, IntegerModel, PositiveIntegerModel, @@ -121,11 +120,11 @@ def test_redundant_backend_range_validators(self): def test_types(self): instance = self.model(value=0) - self.assertIsInstance(instance.value, six.integer_types) + self.assertIsInstance(instance.value, int) instance.save() - self.assertIsInstance(instance.value, six.integer_types) + self.assertIsInstance(instance.value, int) instance = self.model.objects.get() - self.assertIsInstance(instance.value, six.integer_types) + self.assertIsInstance(instance.value, int) def test_coercing(self): self.model.objects.create(value='10') diff --git a/tests/model_fields/test_promises.py b/tests/model_fields/test_promises.py index 0dcb1abf3b30..afbf36651a08 100644 --- a/tests/model_fields/test_promises.py +++ b/tests/model_fields/test_promises.py @@ -10,7 +10,6 @@ ) from django.db.models.fields.files import FileField, ImageField from django.test import SimpleTestCase -from django.utils import six from django.utils.functional import lazy @@ -29,10 +28,10 @@ def test_BooleanField(self): self.assertIsInstance(BooleanField().get_prep_value(lazy_func()), bool) def test_CharField(self): - lazy_func = lazy(lambda: '', six.text_type) - self.assertIsInstance(CharField().get_prep_value(lazy_func()), six.text_type) + lazy_func = lazy(lambda: '', str) + self.assertIsInstance(CharField().get_prep_value(lazy_func()), str) lazy_func = lazy(lambda: 0, int) - self.assertIsInstance(CharField().get_prep_value(lazy_func()), six.text_type) + self.assertIsInstance(CharField().get_prep_value(lazy_func()), str) def test_DateField(self): lazy_func = lazy(lambda: datetime.date.today(), datetime.date) @@ -47,44 +46,44 @@ def test_DecimalField(self): self.assertIsInstance(DecimalField().get_prep_value(lazy_func()), Decimal) def test_EmailField(self): - lazy_func = lazy(lambda: 'mailbox@domain.com', six.text_type) - self.assertIsInstance(EmailField().get_prep_value(lazy_func()), six.text_type) + lazy_func = lazy(lambda: 'mailbox@domain.com', str) + self.assertIsInstance(EmailField().get_prep_value(lazy_func()), str) def test_FileField(self): - lazy_func = lazy(lambda: 'filename.ext', six.text_type) - self.assertIsInstance(FileField().get_prep_value(lazy_func()), six.text_type) + lazy_func = lazy(lambda: 'filename.ext', str) + self.assertIsInstance(FileField().get_prep_value(lazy_func()), str) lazy_func = lazy(lambda: 0, int) - self.assertIsInstance(FileField().get_prep_value(lazy_func()), six.text_type) + self.assertIsInstance(FileField().get_prep_value(lazy_func()), str) def test_FilePathField(self): - lazy_func = lazy(lambda: 'tests.py', six.text_type) - self.assertIsInstance(FilePathField().get_prep_value(lazy_func()), six.text_type) + lazy_func = lazy(lambda: 'tests.py', str) + self.assertIsInstance(FilePathField().get_prep_value(lazy_func()), str) lazy_func = lazy(lambda: 0, int) - self.assertIsInstance(FilePathField().get_prep_value(lazy_func()), six.text_type) + self.assertIsInstance(FilePathField().get_prep_value(lazy_func()), str) def test_FloatField(self): lazy_func = lazy(lambda: 1.2, float) self.assertIsInstance(FloatField().get_prep_value(lazy_func()), float) def test_ImageField(self): - lazy_func = lazy(lambda: 'filename.ext', six.text_type) - self.assertIsInstance(ImageField().get_prep_value(lazy_func()), six.text_type) + lazy_func = lazy(lambda: 'filename.ext', str) + self.assertIsInstance(ImageField().get_prep_value(lazy_func()), str) def test_IntegerField(self): lazy_func = lazy(lambda: 1, int) self.assertIsInstance(IntegerField().get_prep_value(lazy_func()), int) def test_IPAddressField(self): - lazy_func = lazy(lambda: '127.0.0.1', six.text_type) - self.assertIsInstance(IPAddressField().get_prep_value(lazy_func()), six.text_type) + lazy_func = lazy(lambda: '127.0.0.1', str) + self.assertIsInstance(IPAddressField().get_prep_value(lazy_func()), str) lazy_func = lazy(lambda: 0, int) - self.assertIsInstance(IPAddressField().get_prep_value(lazy_func()), six.text_type) + self.assertIsInstance(IPAddressField().get_prep_value(lazy_func()), str) def test_GenericIPAddressField(self): - lazy_func = lazy(lambda: '127.0.0.1', six.text_type) - self.assertIsInstance(GenericIPAddressField().get_prep_value(lazy_func()), six.text_type) + lazy_func = lazy(lambda: '127.0.0.1', str) + self.assertIsInstance(GenericIPAddressField().get_prep_value(lazy_func()), str) lazy_func = lazy(lambda: 0, int) - self.assertIsInstance(GenericIPAddressField().get_prep_value(lazy_func()), six.text_type) + self.assertIsInstance(GenericIPAddressField().get_prep_value(lazy_func()), str) def test_NullBooleanField(self): lazy_func = lazy(lambda: True, bool) @@ -99,25 +98,25 @@ def test_PositiveSmallIntegerField(self): self.assertIsInstance(PositiveSmallIntegerField().get_prep_value(lazy_func()), int) def test_SlugField(self): - lazy_func = lazy(lambda: 'slug', six.text_type) - self.assertIsInstance(SlugField().get_prep_value(lazy_func()), six.text_type) + lazy_func = lazy(lambda: 'slug', str) + self.assertIsInstance(SlugField().get_prep_value(lazy_func()), str) lazy_func = lazy(lambda: 0, int) - self.assertIsInstance(SlugField().get_prep_value(lazy_func()), six.text_type) + self.assertIsInstance(SlugField().get_prep_value(lazy_func()), str) def test_SmallIntegerField(self): lazy_func = lazy(lambda: 1, int) self.assertIsInstance(SmallIntegerField().get_prep_value(lazy_func()), int) def test_TextField(self): - lazy_func = lazy(lambda: 'Abc', six.text_type) - self.assertIsInstance(TextField().get_prep_value(lazy_func()), six.text_type) + lazy_func = lazy(lambda: 'Abc', str) + self.assertIsInstance(TextField().get_prep_value(lazy_func()), str) lazy_func = lazy(lambda: 0, int) - self.assertIsInstance(TextField().get_prep_value(lazy_func()), six.text_type) + self.assertIsInstance(TextField().get_prep_value(lazy_func()), str) def test_TimeField(self): lazy_func = lazy(lambda: datetime.datetime.now().time(), datetime.time) self.assertIsInstance(TimeField().get_prep_value(lazy_func()), datetime.time) def test_URLField(self): - lazy_func = lazy(lambda: 'http://domain.com', six.text_type) - self.assertIsInstance(URLField().get_prep_value(lazy_func()), six.text_type) + lazy_func = lazy(lambda: 'http://domain.com', str) + self.assertIsInstance(URLField().get_prep_value(lazy_func()), str) diff --git a/tests/model_forms/models.py b/tests/model_forms/models.py index 333a6050ab9f..0914fc2587a9 100644 --- a/tests/model_forms/models.py +++ b/tests/model_forms/models.py @@ -15,7 +15,6 @@ from django.core.exceptions import ValidationError from django.core.files.storage import FileSystemStorage from django.db import models -from django.utils import six from django.utils._os import upath from django.utils.six.moves import range @@ -319,7 +318,7 @@ class BigInt(models.Model): biggie = models.BigIntegerField() def __str__(self): - return six.text_type(self.biggie) + return str(self.biggie) class MarkupField(models.CharField): diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index 0fc516b55c88..27143e97f4c3 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -1162,7 +1162,7 @@ def test_initial_values(self): # inserted as 'initial' data in each Field. f = RoykoForm(auto_id=False, instance=self.w_royko) self.assertHTMLEqual( - six.text_type(f), + str(f), '''Name:
    Use both first and last names.''' ) @@ -1204,7 +1204,7 @@ def test_initial_values(self): 'headline': 'Test headline', 'slug': 'test-headline', 'pub_date': '1984-02-06', - 'writer': six.text_type(self.w_royko.pk), + 'writer': str(self.w_royko.pk), 'article': 'Hello.' }, instance=art) self.assertEqual(f.errors, {}) @@ -1294,7 +1294,7 @@ def test_multi_fields(self): # fields with the 'choices' attribute are represented by a ChoiceField. f = ArticleForm(auto_id=False) self.assertHTMLEqual( - six.text_type(f), + str(f), '''Headline: Slug: Pub date: @@ -1360,7 +1360,7 @@ class Meta: f = PartialArticleForm(auto_id=False) self.assertHTMLEqual( - six.text_type(f), + str(f), '''Headline: Pub date:''') @@ -1398,9 +1398,9 @@ def test_m2m_editing(self): 'headline': 'New headline', 'slug': 'new-headline', 'pub_date': '1988-01-04', - 'writer': six.text_type(self.w_royko.pk), + 'writer': str(self.w_royko.pk), 'article': 'Hello.', - 'categories': [six.text_type(self.c1.id), six.text_type(self.c2.id)] + 'categories': [str(self.c1.id), str(self.c2.id)] } # Create a new article, with categories, via the form. f = ArticleForm(form_data) @@ -1427,7 +1427,7 @@ def test_m2m_editing(self): # Create a new article, with categories, via the form, but use commit=False. # The m2m data won't be saved until save_m2m() is invoked on the form. - form_data['categories'] = [six.text_type(self.c1.id), six.text_type(self.c2.id)] + form_data['categories'] = [str(self.c1.id), str(self.c2.id)] f = ArticleForm(form_data) new_art = f.save(commit=False) @@ -1979,12 +1979,12 @@ class Meta: ) data = { - 'writer': six.text_type(self.w_woodward.pk), + 'writer': str(self.w_woodward.pk), 'age': '65', } form = WriterProfileForm(data) instance = form.save() - self.assertEqual(six.text_type(instance), 'Bob Woodward is 65') + self.assertEqual(str(instance), 'Bob Woodward is 65') form = WriterProfileForm(instance=instance) self.assertHTMLEqual( @@ -2062,14 +2062,14 @@ class Meta: fields = '__all__' form = DocumentForm() - self.assertIn('name="myfile"', six.text_type(form)) - self.assertNotIn('myfile-clear', six.text_type(form)) + self.assertIn('name="myfile"', str(form)) + self.assertNotIn('myfile-clear', str(form)) form = DocumentForm(files={'myfile': SimpleUploadedFile('something.txt', b'content')}) self.assertTrue(form.is_valid()) doc = form.save(commit=False) self.assertEqual(doc.myfile.name, 'something.txt') form = DocumentForm(instance=doc) - self.assertIn('myfile-clear', six.text_type(form)) + self.assertIn('myfile-clear', str(form)) form = DocumentForm(instance=doc, data={'myfile-clear': 'true'}) doc = form.save(commit=False) self.assertFalse(doc.myfile) @@ -2094,7 +2094,7 @@ class Meta: self.assertTrue(not form.is_valid()) self.assertEqual(form.errors['myfile'], ['Please either submit a file or check the clear checkbox, not both.']) - rendered = six.text_type(form) + rendered = str(form) self.assertIn('something.txt', rendered) self.assertIn('myfile-clear', rendered) @@ -2469,7 +2469,7 @@ def test_media_on_modelform(self): # the ModelForm. f = ModelFormWithMedia() self.assertHTMLEqual( - six.text_type(f.media), + str(f.media), ''' ''' ) @@ -2520,7 +2520,7 @@ def test_foreignkeys_which_use_to_field(self): (22, 'Pear'))) form = InventoryForm(instance=core) - self.assertHTMLEqual(six.text_type(form['parent']), ''' @@ -2543,7 +2543,7 @@ class Meta: ['description', 'url']) self.assertHTMLEqual( - six.text_type(CategoryForm()), + str(CategoryForm()), ''' @@ -2564,7 +2564,7 @@ def test_model_field_that_returns_none_to_exclude_itself_with_explicit_fields(se self.assertEqual(list(CustomFieldForExclusionForm.base_fields), ['name']) self.assertHTMLEqual( - six.text_type(CustomFieldForExclusionForm()), + str(CustomFieldForExclusionForm()), ''' ''' ) diff --git a/tests/model_formsets/models.py b/tests/model_formsets/models.py index b7b1f1edb917..744a7f601945 100644 --- a/tests/model_formsets/models.py +++ b/tests/model_formsets/models.py @@ -2,7 +2,6 @@ import uuid from django.db import models -from django.utils import six class Author(models.Model): @@ -172,7 +171,7 @@ class Meta: unique_together = (("repository", "revision"),) def __str__(self): - return "%s (%s)" % (self.revision, six.text_type(self.repository)) + return "%s (%s)" % (self.revision, str(self.repository)) # models for testing callable defaults (see bug #7975). If you define a model diff --git a/tests/model_formsets/tests.py b/tests/model_formsets/tests.py index b928944097af..832dbe63eedf 100644 --- a/tests/model_formsets/tests.py +++ b/tests/model_formsets/tests.py @@ -11,7 +11,6 @@ modelformset_factory, ) from django.test import TestCase, skipUnlessDBFeature -from django.utils import six from .models import ( AlternateBook, Author, AuthorMeeting, BetterAuthor, Book, BookWithCustomPK, @@ -54,11 +53,11 @@ def test_add_form_deletion_when_invalid(self): 'form-TOTAL_FORMS': '3', 'form-INITIAL_FORMS': '1', 'form-MAX_NUM_FORMS': '0', - 'form-0-id': six.text_type(poet.id), + 'form-0-id': str(poet.id), 'form-0-name': 'test', 'form-1-id': '', 'form-1-name': 'x' * 1000, # Too long - 'form-2-id': six.text_type(poet.id), # Violate unique constraint + 'form-2-id': str(poet.id), # Violate unique constraint 'form-2-name': 'test2', } formset = PoetFormSet(data, queryset=Poet.objects.all()) @@ -87,7 +86,7 @@ def test_change_form_deletion_when_invalid(self): 'form-TOTAL_FORMS': '1', 'form-INITIAL_FORMS': '1', 'form-MAX_NUM_FORMS': '0', - 'form-0-id': six.text_type(poet.id), + 'form-0-id': str(poet.id), 'form-0-name': 'x' * 1000, } formset = PoetFormSet(data, queryset=Poet.objects.all()) @@ -1109,7 +1108,7 @@ def test_custom_pk(self): 'owner_set-TOTAL_FORMS': '3', 'owner_set-INITIAL_FORMS': '1', 'owner_set-MAX_NUM_FORMS': '', - 'owner_set-0-auto_id': six.text_type(owner1.auto_id), + 'owner_set-0-auto_id': str(owner1.auto_id), 'owner_set-0-name': 'Joe Perry', 'owner_set-1-auto_id': '', 'owner_set-1-name': 'Jack Berry', @@ -1184,7 +1183,7 @@ def test_custom_pk(self): 'ownerprofile-TOTAL_FORMS': '1', 'ownerprofile-INITIAL_FORMS': '1', 'ownerprofile-MAX_NUM_FORMS': '1', - 'ownerprofile-0-owner': six.text_type(owner1.auto_id), + 'ownerprofile-0-owner': str(owner1.auto_id), 'ownerprofile-0-age': '55', } formset = FormSet(data, instance=owner1) @@ -1383,8 +1382,8 @@ def test_callable_defaults(self): 'membership_set-TOTAL_FORMS': '1', 'membership_set-INITIAL_FORMS': '0', 'membership_set-MAX_NUM_FORMS': '', - 'membership_set-0-date_joined': six.text_type(now.strftime('%Y-%m-%d %H:%M:%S')), - 'initial-membership_set-0-date_joined': six.text_type(now.strftime('%Y-%m-%d %H:%M:%S')), + 'membership_set-0-date_joined': now.strftime('%Y-%m-%d %H:%M:%S'), + 'initial-membership_set-0-date_joined': now.strftime('%Y-%m-%d %H:%M:%S'), 'membership_set-0-karma': '', } formset = FormSet(data, instance=person) @@ -1397,8 +1396,8 @@ def test_callable_defaults(self): 'membership_set-TOTAL_FORMS': '1', 'membership_set-INITIAL_FORMS': '0', 'membership_set-MAX_NUM_FORMS': '', - 'membership_set-0-date_joined': six.text_type(one_day_later.strftime('%Y-%m-%d %H:%M:%S')), - 'initial-membership_set-0-date_joined': six.text_type(now.strftime('%Y-%m-%d %H:%M:%S')), + 'membership_set-0-date_joined': one_day_later.strftime('%Y-%m-%d %H:%M:%S'), + 'initial-membership_set-0-date_joined': now.strftime('%Y-%m-%d %H:%M:%S'), 'membership_set-0-karma': '', } formset = FormSet(filled_data, instance=person) @@ -1429,9 +1428,9 @@ def __init__(self, **kwargs): 'membership_set-TOTAL_FORMS': '1', 'membership_set-INITIAL_FORMS': '0', 'membership_set-MAX_NUM_FORMS': '', - 'membership_set-0-date_joined_0': six.text_type(now.strftime('%Y-%m-%d')), - 'membership_set-0-date_joined_1': six.text_type(now.strftime('%H:%M:%S')), - 'initial-membership_set-0-date_joined': six.text_type(now.strftime('%Y-%m-%d %H:%M:%S')), + 'membership_set-0-date_joined_0': now.strftime('%Y-%m-%d'), + 'membership_set-0-date_joined_1': now.strftime('%H:%M:%S'), + 'initial-membership_set-0-date_joined': now.strftime('%Y-%m-%d %H:%M:%S'), 'membership_set-0-karma': '', } formset = FormSet(data, instance=person) diff --git a/tests/model_formsets_regress/tests.py b/tests/model_formsets_regress/tests.py index a9b50b3699a1..5bad8a741a89 100644 --- a/tests/model_formsets_regress/tests.py +++ b/tests/model_formsets_regress/tests.py @@ -6,7 +6,6 @@ ) from django.forms.utils import ErrorDict, ErrorList from django.test import TestCase -from django.utils import six from .models import ( Host, Manager, Network, ProfileNetwork, Restaurant, User, UserProfile, @@ -56,7 +55,7 @@ def test_formset_over_to_field(self): 'usersite_set-TOTAL_FORMS': '1', 'usersite_set-INITIAL_FORMS': '1', 'usersite_set-MAX_NUM_FORMS': '0', - 'usersite_set-0-id': six.text_type(usersite[0]['id']), + 'usersite_set-0-id': str(usersite[0]['id']), 'usersite_set-0-data': '11', 'usersite_set-0-user': 'apollo13' } @@ -74,7 +73,7 @@ def test_formset_over_to_field(self): 'usersite_set-TOTAL_FORMS': '2', 'usersite_set-INITIAL_FORMS': '1', 'usersite_set-MAX_NUM_FORMS': '0', - 'usersite_set-0-id': six.text_type(usersite[0]['id']), + 'usersite_set-0-id': str(usersite[0]['id']), 'usersite_set-0-data': '11', 'usersite_set-0-user': 'apollo13', 'usersite_set-1-data': '42', @@ -129,7 +128,7 @@ def test_formset_over_inherited_model(self): 'manager_set-TOTAL_FORMS': '1', 'manager_set-INITIAL_FORMS': '1', 'manager_set-MAX_NUM_FORMS': '0', - 'manager_set-0-id': six.text_type(manager[0]['id']), + 'manager_set-0-id': str(manager[0]['id']), 'manager_set-0-name': 'Terry Gilliam' } form_set = FormSet(data, instance=restaurant) @@ -145,7 +144,7 @@ def test_formset_over_inherited_model(self): 'manager_set-TOTAL_FORMS': '2', 'manager_set-INITIAL_FORMS': '1', 'manager_set-MAX_NUM_FORMS': '0', - 'manager_set-0-id': six.text_type(manager[0]['id']), + 'manager_set-0-id': str(manager[0]['id']), 'manager_set-0-name': 'Terry Gilliam', 'manager_set-1-name': 'John Cleese' } @@ -226,7 +225,7 @@ def test_save_as_new_with_new_inlines(self): 'host_set-TOTAL_FORMS': '2', 'host_set-INITIAL_FORMS': '1', 'host_set-MAX_NUM_FORMS': '0', - 'host_set-0-id': six.text_type(host1.id), + 'host_set-0-id': str(host1.id), 'host_set-0-hostname': 'tranquility.hub.dal.net', 'host_set-1-hostname': 'matrix.de.eu.dal.net' } @@ -505,7 +504,7 @@ def test_resubmit(self): 'usersite_set-TOTAL_FORMS': '1', 'usersite_set-INITIAL_FORMS': '1', 'usersite_set-MAX_NUM_FORMS': '1', - 'usersite_set-0-id': six.text_type(us.pk), + 'usersite_set-0-id': str(us.pk), 'usersite_set-0-data': '7', 'usersite_set-0-user': 'foo', 'usersite_set-0-DELETE': '1' @@ -531,7 +530,7 @@ def test_delete_already_deleted(self): 'usersite_set-TOTAL_FORMS': '1', 'usersite_set-INITIAL_FORMS': '1', 'usersite_set-MAX_NUM_FORMS': '1', - 'usersite_set-0-id': six.text_type(us.pk), + 'usersite_set-0-id': str(us.pk), 'usersite_set-0-data': '7', 'usersite_set-0-user': 'foo', 'usersite_set-0-DELETE': '1' diff --git a/tests/model_inheritance/tests.py b/tests/model_inheritance/tests.py index 8bb74d7ccbb2..feff4a140770 100644 --- a/tests/model_inheritance/tests.py +++ b/tests/model_inheritance/tests.py @@ -4,7 +4,6 @@ from django.db import connection, models from django.test import SimpleTestCase, TestCase from django.test.utils import CaptureQueriesContext, isolate_apps -from django.utils import six from .models import ( Base, Chef, CommonInfo, GrandChild, GrandParent, ItalianRestaurant, @@ -25,8 +24,8 @@ def test_abstract(self): s = Student.objects.create(name="Pebbles", age=5, school_class="1B") - self.assertEqual(six.text_type(w1), "Worker Fred") - self.assertEqual(six.text_type(s), "Student Pebbles") + self.assertEqual(str(w1), "Worker Fred") + self.assertEqual(str(s), "Student Pebbles") # The children inherit the Meta class of their parents (if they don't # specify their own). diff --git a/tests/model_regress/tests.py b/tests/model_regress/tests.py index 808729979ffe..e9374d9d931e 100644 --- a/tests/model_regress/tests.py +++ b/tests/model_regress/tests.py @@ -5,7 +5,6 @@ from django.db import router from django.db.models.sql import InsertQuery from django.test import TestCase, skipUnlessDBFeature -from django.utils import six from django.utils.timezone import get_fixed_timezone from .models import ( @@ -53,10 +52,9 @@ def test_empty_choice(self): # An empty choice field should return None for the display name. self.assertIs(a.get_status_display(), None) - # Empty strings should be returned as Unicode + # Empty strings should be returned as string a = Article.objects.get(pk=a.pk) self.assertEqual(a.misc_data, '') - self.assertIs(type(a.misc_data), six.text_type) def test_long_textfield(self): # TextFields can hold more than 4000 characters (this was broken in @@ -186,7 +184,7 @@ def test_primary_key_foreign_key_types(self): # Check Department and Worker (non-default PK type) d = Department.objects.create(id=10, name="IT") w = Worker.objects.create(department=d, name="Full-time") - self.assertEqual(six.text_type(w), "Full-time") + self.assertEqual(str(w), "Full-time") def test_broken_unicode(self): # Models with broken unicode methods should still have a printable repr diff --git a/tests/order_with_respect_to/models.py b/tests/order_with_respect_to/models.py index 8f50b42252ed..7f6cd8f8fdea 100644 --- a/tests/order_with_respect_to/models.py +++ b/tests/order_with_respect_to/models.py @@ -3,7 +3,6 @@ """ from django.db import models -from django.utils import six class Question(models.Model): @@ -18,7 +17,7 @@ class Meta: order_with_respect_to = 'question' def __str__(self): - return six.text_type(self.text) + return self.text class Post(models.Model): diff --git a/tests/pagination/tests.py b/tests/pagination/tests.py index fe967631ab0b..cc3a0efbc26f 100644 --- a/tests/pagination/tests.py +++ b/tests/pagination/tests.py @@ -256,7 +256,7 @@ def setUp(self): def test_first_page(self): paginator = Paginator(Article.objects.order_by('id'), 5) p = paginator.page(1) - self.assertEqual("", six.text_type(p)) + self.assertEqual("", str(p)) self.assertQuerysetEqual(p.object_list, [ "", "", @@ -276,7 +276,7 @@ def test_first_page(self): def test_last_page(self): paginator = Paginator(Article.objects.order_by('id'), 5) p = paginator.page(2) - self.assertEqual("", six.text_type(p)) + self.assertEqual("", str(p)) self.assertQuerysetEqual(p.object_list, [ "", "", diff --git a/tests/prefetch_related/tests.py b/tests/prefetch_related/tests.py index 126a8bc03598..33456069aa1b 100644 --- a/tests/prefetch_related/tests.py +++ b/tests/prefetch_related/tests.py @@ -5,7 +5,6 @@ from django.db.models.query import get_prefetcher from django.test import TestCase, override_settings from django.test.utils import CaptureQueriesContext -from django.utils import six from django.utils.encoding import force_text from .models import ( @@ -130,7 +129,7 @@ def test_m2m_then_m2m(self): """A m2m can be followed through another m2m.""" with self.assertNumQueries(3): qs = Author.objects.prefetch_related('books__read_by') - lists = [[[six.text_type(r) for r in b.read_by.all()] + lists = [[[str(r) for r in b.read_by.all()] for b in a.books.all()] for a in qs] self.assertEqual(lists, [ @@ -143,7 +142,7 @@ def test_m2m_then_m2m(self): def test_overriding_prefetch(self): with self.assertNumQueries(3): qs = Author.objects.prefetch_related('books', 'books__read_by') - lists = [[[six.text_type(r) for r in b.read_by.all()] + lists = [[[str(r) for r in b.read_by.all()] for b in a.books.all()] for a in qs] self.assertEqual(lists, [ @@ -154,7 +153,7 @@ def test_overriding_prefetch(self): ]) with self.assertNumQueries(3): qs = Author.objects.prefetch_related('books__read_by', 'books') - lists = [[[six.text_type(r) for r in b.read_by.all()] + lists = [[[str(r) for r in b.read_by.all()] for b in a.books.all()] for a in qs] self.assertEqual(lists, [ @@ -171,7 +170,7 @@ def test_get(self): # Need a double with self.assertNumQueries(3): author = Author.objects.prefetch_related('books__read_by').get(name="Charlotte") - lists = [[six.text_type(r) for r in b.read_by.all()] for b in author.books.all()] + lists = [[str(r) for r in b.read_by.all()] for b in author.books.all()] self.assertEqual(lists, [["Amy"], ["Belinda"]]) # Poems, Jane Eyre def test_foreign_key_then_m2m(self): @@ -181,7 +180,7 @@ def test_foreign_key_then_m2m(self): """ with self.assertNumQueries(2): qs = Author.objects.select_related('first_book').prefetch_related('first_book__read_by') - lists = [[six.text_type(r) for r in a.first_book.read_by.all()] + lists = [[str(r) for r in a.first_book.read_by.all()] for a in qs] self.assertEqual(lists, [["Amy"], ["Amy"], ["Amy"], ["Amy", "Belinda"]]) @@ -758,7 +757,7 @@ def test_m2m_then_m2m(self): # qualifications, since this will do one query per teacher. qs = Department.objects.prefetch_related('teachers') depts = "".join("%s department: %s\n" % - (dept.name, ", ".join(six.text_type(t) for t in dept.teachers.all())) + (dept.name, ", ".join(str(t) for t in dept.teachers.all())) for dept in qs) self.assertEqual(depts, @@ -895,8 +894,8 @@ def setUpTestData(cls): def test_foreignkey(self): with self.assertNumQueries(2): qs = AuthorWithAge.objects.prefetch_related('addresses') - addresses = [[six.text_type(address) for address in obj.addresses.all()] for obj in qs] - self.assertEqual(addresses, [[six.text_type(self.author_address)], [], []]) + addresses = [[str(address) for address in obj.addresses.all()] for obj in qs] + self.assertEqual(addresses, [[str(self.author_address)], [], []]) def test_foreignkey_to_inherited(self): with self.assertNumQueries(2): @@ -907,16 +906,16 @@ def test_foreignkey_to_inherited(self): def test_m2m_to_inheriting_model(self): qs = AuthorWithAge.objects.prefetch_related('books_with_year') with self.assertNumQueries(2): - lst = [[six.text_type(book) for book in author.books_with_year.all()] for author in qs] + lst = [[str(book) for book in author.books_with_year.all()] for author in qs] qs = AuthorWithAge.objects.all() - lst2 = [[six.text_type(book) for book in author.books_with_year.all()] for author in qs] + lst2 = [[str(book) for book in author.books_with_year.all()] for author in qs] self.assertEqual(lst, lst2) qs = BookWithYear.objects.prefetch_related('aged_authors') with self.assertNumQueries(2): - lst = [[six.text_type(author) for author in book.aged_authors.all()] for book in qs] + lst = [[str(author) for author in book.aged_authors.all()] for book in qs] qs = BookWithYear.objects.all() - lst2 = [[six.text_type(author) for author in book.aged_authors.all()] for book in qs] + lst2 = [[str(author) for author in book.aged_authors.all()] for book in qs] self.assertEqual(lst, lst2) def test_parent_link_prefetch(self): @@ -953,23 +952,23 @@ def setUpTestData(cls): def test_foreignkey(self): with self.assertNumQueries(2): qs = Author.objects.prefetch_related('addresses') - addresses = [[six.text_type(address) for address in obj.addresses.all()] + addresses = [[str(address) for address in obj.addresses.all()] for obj in qs] - self.assertEqual(addresses, [[six.text_type(self.author_address)], [], []]) + self.assertEqual(addresses, [[str(self.author_address)], [], []]) def test_m2m(self): with self.assertNumQueries(3): qs = Author.objects.all().prefetch_related('favorite_authors', 'favors_me') favorites = [( - [six.text_type(i_like) for i_like in author.favorite_authors.all()], - [six.text_type(likes_me) for likes_me in author.favors_me.all()] + [str(i_like) for i_like in author.favorite_authors.all()], + [str(likes_me) for likes_me in author.favors_me.all()] ) for author in qs] self.assertEqual( favorites, [ - ([six.text_type(self.author2)], [six.text_type(self.author3)]), - ([six.text_type(self.author3)], [six.text_type(self.author1)]), - ([six.text_type(self.author1)], [six.text_type(self.author2)]) + ([str(self.author2)], [str(self.author3)]), + ([str(self.author3)], [str(self.author1)]), + ([str(self.author1)], [str(self.author2)]) ] ) diff --git a/tests/queries/models.py b/tests/queries/models.py index 4d5ed14ff0e1..8c20e76dee6a 100644 --- a/tests/queries/models.py +++ b/tests/queries/models.py @@ -4,7 +4,6 @@ import threading from django.db import models -from django.utils import six class DumbCategory(models.Model): @@ -142,7 +141,7 @@ class Number(models.Model): num = models.IntegerField() def __str__(self): - return six.text_type(self.num) + return str(self.num) # Symmetrical m2m field with a normal field using the reverse accessor name # ("valid"). diff --git a/tests/redirects_tests/tests.py b/tests/redirects_tests/tests.py index 29c88bd1dfaa..558bbaaf7eaf 100644 --- a/tests/redirects_tests/tests.py +++ b/tests/redirects_tests/tests.py @@ -5,7 +5,6 @@ from django.contrib.sites.models import Site from django.core.exceptions import ImproperlyConfigured from django.test import TestCase, modify_settings, override_settings -from django.utils import six @modify_settings(MIDDLEWARE={'append': 'django.contrib.redirects.middleware.RedirectFallbackMiddleware'}) @@ -17,7 +16,7 @@ def setUp(self): def test_model(self): r1 = Redirect.objects.create(site=self.site, old_path='/initial', new_path='/new_target') - self.assertEqual(six.text_type(r1), "/initial ---> /new_target") + self.assertEqual(str(r1), "/initial ---> /new_target") def test_redirect(self): Redirect.objects.create(site=self.site, old_path='/initial', new_path='/new_target') diff --git a/tests/resolve_url/tests.py b/tests/resolve_url/tests.py index 73556a93beac..5a90282afa7a 100644 --- a/tests/resolve_url/tests.py +++ b/tests/resolve_url/tests.py @@ -1,7 +1,6 @@ from django.shortcuts import resolve_url from django.test import SimpleTestCase, override_settings from django.urls import NoReverseMatch, reverse_lazy -from django.utils import six from .models import UnimportantThing from .urls import some_view @@ -57,7 +56,7 @@ def test_lazy_reverse(self): string. """ resolved_url = resolve_url(reverse_lazy('some-view')) - self.assertIsInstance(resolved_url, six.text_type) + self.assertIsInstance(resolved_url, str) self.assertEqual('/some-url/', resolved_url) def test_valid_view_name(self): diff --git a/tests/runtests.py b/tests/runtests.py index 82cd8207ba13..6e86bf7a93b4 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -17,7 +17,6 @@ from django.test.runner import default_test_processes from django.test.selenium import SeleniumTestCaseBase from django.test.utils import get_runner -from django.utils import six from django.utils._os import upath from django.utils.deprecation import ( RemovedInDjango21Warning, RemovedInDjango30Warning, @@ -42,10 +41,8 @@ # so that children processes inherit it. tempfile.tempdir = os.environ['TMPDIR'] = TMPDIR -# Removing the temporary TMPDIR. Ensure we pass in unicode so that it will -# successfully remove temp trees containing non-ASCII filenames on Windows. -# (We're assuming the temp dir name itself only contains ASCII characters.) -atexit.register(shutil.rmtree, six.text_type(TMPDIR)) +# Removing the temporary TMPDIR. +atexit.register(shutil.rmtree, TMPDIR) SUBDIRS_TO_SKIP = [ diff --git a/tests/save_delete_hooks/tests.py b/tests/save_delete_hooks/tests.py index e0cb2f51ab43..874cb7eb7225 100644 --- a/tests/save_delete_hooks/tests.py +++ b/tests/save_delete_hooks/tests.py @@ -1,5 +1,4 @@ from django.test import TestCase -from django.utils import six from .models import Person @@ -18,7 +17,7 @@ def test_basic(self): Person.objects.all(), [ "John Smith", ], - six.text_type + str ) p.delete() diff --git a/tests/select_related_regress/tests.py b/tests/select_related_regress/tests.py index bb5f7774a3e7..753114a6d2f4 100644 --- a/tests/select_related_regress/tests.py +++ b/tests/select_related_regress/tests.py @@ -1,5 +1,4 @@ from django.test import TestCase -from django.utils import six from .models import ( A, B, Building, C, Chick, Child, Class, Client, ClientStatus, Connection, @@ -35,7 +34,7 @@ def test_regression_7110(self): connections = Connection.objects.filter(start__device__building=b, end__device__building=b).order_by('id') self.assertEqual( - [(c.id, six.text_type(c.start), six.text_type(c.end)) for c in connections], + [(c.id, str(c.start), str(c.end)) for c in connections], [(c1.id, 'router/4', 'switch/7'), (c2.id, 'switch/7', 'server/1')] ) @@ -46,7 +45,7 @@ def test_regression_7110(self): .order_by('id') ) self.assertEqual( - [(c.id, six.text_type(c.start), six.text_type(c.end)) for c in connections], + [(c.id, str(c.start), str(c.end)) for c in connections], [(c1.id, 'router/4', 'switch/7'), (c2.id, 'switch/7', 'server/1')] ) diff --git a/tests/serializers/models/base.py b/tests/serializers/models/base.py index aa55b87c61c1..942157847833 100644 --- a/tests/serializers/models/base.py +++ b/tests/serializers/models/base.py @@ -7,7 +7,6 @@ from decimal import Decimal from django.db import models -from django.utils import six class CategoryMetaDataManager(models.Manager): @@ -118,7 +117,7 @@ def __init__(self): super(TeamField, self).__init__(max_length=100) def get_db_prep_save(self, value, connection): - return six.text_type(value.title) + return str(value.title) def to_python(self, value): if isinstance(value, Team): diff --git a/tests/serializers/test_xml.py b/tests/serializers/test_xml.py index 71b38d48fa89..ea9677d87f66 100644 --- a/tests/serializers/test_xml.py +++ b/tests/serializers/test_xml.py @@ -3,7 +3,6 @@ from django.core import serializers from django.core.serializers.xml_serializer import DTDForbidden from django.test import TestCase, TransactionTestCase -from django.utils import six from .tests import SerializersTestBase, SerializersTransactionTestBase @@ -34,7 +33,7 @@ class XmlSerializerTestCase(SerializersTestBase, TestCase): def _comparison_value(value): # The XML serializer handles everything as strings, so comparisons # need to be performed on the stringified value - return six.text_type(value) + return str(value) @staticmethod def _validate_output(serial_str): diff --git a/tests/serializers/test_yaml.py b/tests/serializers/test_yaml.py index 038227efeaea..f3988d7ff15b 100644 --- a/tests/serializers/test_yaml.py +++ b/tests/serializers/test_yaml.py @@ -4,7 +4,6 @@ from django.core import management, serializers from django.core.serializers.base import DeserializationError from django.test import SimpleTestCase, TestCase, TransactionTestCase -from django.utils import six from django.utils.six import StringIO from .models import Author @@ -147,7 +146,7 @@ def _get_field_values(serial_str, field_name): # yaml.safe_load will return non-string objects for some # of the fields we are interested in, this ensures that # everything comes back as a string - if isinstance(field_value, six.string_types): + if isinstance(field_value, str): ret_list.append(field_value) else: ret_list.append(str(field_value)) diff --git a/tests/servers/tests.py b/tests/servers/tests.py index ff1d4aff8c73..ee0d8629cfc7 100644 --- a/tests/servers/tests.py +++ b/tests/servers/tests.py @@ -9,7 +9,6 @@ from django.test import LiveServerTestCase, override_settings from django.utils._os import upath from django.utils.http import urlencode -from django.utils.six import text_type from django.utils.six.moves.urllib.error import HTTPError from django.utils.six.moves.urllib.request import urlopen @@ -48,7 +47,7 @@ def setUpClass(cls): cls.live_server_url_test = [cls.live_server_url] def test_live_server_url_is_class_property(self): - self.assertIsInstance(self.live_server_url_test[0], text_type) + self.assertIsInstance(self.live_server_url_test[0], str) self.assertEqual(self.live_server_url_test[0], self.live_server_url) diff --git a/tests/signals/tests.py b/tests/signals/tests.py index 9cb470b8cfe5..88572ad44f84 100644 --- a/tests/signals/tests.py +++ b/tests/signals/tests.py @@ -4,7 +4,6 @@ from django.dispatch import receiver from django.test import TestCase, mock from django.test.utils import isolate_apps -from django.utils import six from .models import Author, Book, Car, Person @@ -160,7 +159,7 @@ def __call__(self, signal, sender, instance, **kwargs): Person.objects.all(), [ "James Jones", ], - six.text_type + str ) finally: signals.pre_delete.disconnect(pre_delete_handler) diff --git a/tests/staticfiles_tests/cases.py b/tests/staticfiles_tests/cases.py index f278e6a97449..069402c6f647 100644 --- a/tests/staticfiles_tests/cases.py +++ b/tests/staticfiles_tests/cases.py @@ -7,7 +7,6 @@ from django.core.management import call_command from django.template import Context, Template from django.test import SimpleTestCase, override_settings -from django.utils import six from django.utils.encoding import force_text from .settings import TEST_SETTINGS @@ -30,7 +29,7 @@ def assertFileNotFound(self, filepath): self._get_file(filepath) def render_template(self, template, **kwargs): - if isinstance(template, six.string_types): + if isinstance(template, str): template = Template(template) return template.render(Context(**kwargs)).strip() @@ -72,7 +71,7 @@ def setUp(self): self.patched_settings.enable() self.run_collectstatic() # Same comment as in runtests.teardown. - self.addCleanup(shutil.rmtree, six.text_type(temp_dir)) + self.addCleanup(shutil.rmtree, temp_dir) def tearDown(self): self.patched_settings.disable() diff --git a/tests/staticfiles_tests/test_management.py b/tests/staticfiles_tests/test_management.py index e8c00eb3f5ee..7d17f2abe1f1 100644 --- a/tests/staticfiles_tests/test_management.py +++ b/tests/staticfiles_tests/test_management.py @@ -166,7 +166,7 @@ def test_cleared_not_found(self): self.assertFileNotFound('cleared.txt') def test_dir_not_exists(self, **kwargs): - shutil.rmtree(six.text_type(settings.STATIC_ROOT)) + shutil.rmtree(settings.STATIC_ROOT) super(TestCollectionClear, self).run_collectstatic(clear=True) @override_settings(STATICFILES_STORAGE='staticfiles_tests.storage.PathNotImplementedStorage') @@ -210,7 +210,7 @@ def test_warning_when_overwriting_files_in_staticdir(self): def test_no_warning_when_staticdir_does_not_exist(self): stdout = six.StringIO() - shutil.rmtree(six.text_type(settings.STATIC_ROOT)) + shutil.rmtree(settings.STATIC_ROOT) call_command('collectstatic', interactive=True, stdout=stdout) output = force_text(stdout.getvalue()) self.assertNotIn(self.overwrite_warning_msg, output) @@ -222,7 +222,7 @@ def test_no_warning_for_empty_staticdir(self): static_dir = tempfile.mkdtemp(prefix='collectstatic_empty_staticdir_test') with override_settings(STATIC_ROOT=static_dir): call_command('collectstatic', interactive=True, stdout=stdout) - shutil.rmtree(six.text_type(static_dir)) + shutil.rmtree(static_dir) output = force_text(stdout.getvalue()) self.assertNotIn(self.overwrite_warning_msg, output) self.assertNotIn(self.delete_warning_msg, output) diff --git a/tests/staticfiles_tests/test_storage.py b/tests/staticfiles_tests/test_storage.py index d1b7a49626ff..6333be754926 100644 --- a/tests/staticfiles_tests/test_storage.py +++ b/tests/staticfiles_tests/test_storage.py @@ -350,7 +350,7 @@ def setUp(self): self.patched_settings = self.settings( STATICFILES_DIRS=settings.STATICFILES_DIRS + [temp_dir]) self.patched_settings.enable() - self.addCleanup(shutil.rmtree, six.text_type(temp_dir)) + self.addCleanup(shutil.rmtree, temp_dir) self._manifest_strict = storage.staticfiles_storage.manifest_strict def tearDown(self): diff --git a/tests/template_tests/filter_tests/test_escape.py b/tests/template_tests/filter_tests/test_escape.py index 6f28b972a25b..22d5ca7d5594 100644 --- a/tests/template_tests/filter_tests/test_escape.py +++ b/tests/template_tests/filter_tests/test_escape.py @@ -1,6 +1,5 @@ from django.template.defaultfilters import escape from django.test import SimpleTestCase -from django.utils import six from django.utils.functional import Promise, lazy from django.utils.safestring import mark_safe @@ -34,7 +33,7 @@ def test_escape04(self): self.assertEqual(output, "x&y") def test_escape_lazy_string(self): - add_html = lazy(lambda string: string + 'special characters > here', six.text_type) + add_html = lazy(lambda string: string + 'special characters > here', str) escaped = escape(add_html('this' + string, six.text_type) + append_script = lazy(lambda string: r'' + string, str) self.assertEqual( escapejs_filter(append_script('whitespace: \r\n\t\v\f\b')), '\\u003Cscript\\u003Ethis\\u003C/script\\u003E' diff --git a/tests/template_tests/filter_tests/test_floatformat.py b/tests/template_tests/filter_tests/test_floatformat.py index d4a4526d1dde..8474238f2132 100644 --- a/tests/template_tests/filter_tests/test_floatformat.py +++ b/tests/template_tests/filter_tests/test_floatformat.py @@ -2,7 +2,6 @@ from django.template.defaultfilters import floatformat from django.test import SimpleTestCase -from django.utils import six from django.utils.safestring import mark_safe from ..utils import setup @@ -64,13 +63,13 @@ def test_zero_values(self): def test_infinity(self): pos_inf = float(1e30000) - self.assertEqual(floatformat(pos_inf), six.text_type(pos_inf)) + self.assertEqual(floatformat(pos_inf), str(pos_inf)) neg_inf = float(-1e30000) - self.assertEqual(floatformat(neg_inf), six.text_type(neg_inf)) + self.assertEqual(floatformat(neg_inf), str(neg_inf)) nan = pos_inf / pos_inf - self.assertEqual(floatformat(nan), six.text_type(nan)) + self.assertEqual(floatformat(nan), str(nan)) def test_float_dunder_method(self): class FloatWrapper(object): diff --git a/tests/template_tests/filter_tests/test_linebreaks.py b/tests/template_tests/filter_tests/test_linebreaks.py index 50a66f3c47e2..0f3cd7a1177c 100644 --- a/tests/template_tests/filter_tests/test_linebreaks.py +++ b/tests/template_tests/filter_tests/test_linebreaks.py @@ -1,6 +1,5 @@ from django.template.defaultfilters import linebreaks_filter from django.test import SimpleTestCase -from django.utils import six from django.utils.functional import lazy from django.utils.safestring import mark_safe @@ -54,7 +53,7 @@ def test_autoescape_off(self): ) def test_lazy_string_input(self): - add_header = lazy(lambda string: 'Header\n\n' + string, six.text_type) + add_header = lazy(lambda string: 'Header\n\n' + string, str) self.assertEqual( linebreaks_filter(add_header('line 1\r\nline2')), '

    Header

    \n\n

    line 1
    line2

    ' diff --git a/tests/template_tests/filter_tests/test_slugify.py b/tests/template_tests/filter_tests/test_slugify.py index ec9f2bb73670..cb23e9b320e9 100644 --- a/tests/template_tests/filter_tests/test_slugify.py +++ b/tests/template_tests/filter_tests/test_slugify.py @@ -1,6 +1,5 @@ from django.template.defaultfilters import slugify from django.test import SimpleTestCase -from django.utils import six from django.utils.encoding import force_text from django.utils.functional import lazy from django.utils.safestring import mark_safe @@ -43,7 +42,7 @@ def test_non_string_input(self): self.assertEqual(slugify(123), '123') def test_slugify_lazy_string(self): - lazy_str = lazy(lambda string: force_text(string), six.text_type) + lazy_str = lazy(lambda string: force_text(string), str) self.assertEqual( slugify(lazy_str(' Jack & Jill like numbers 1,2,3 and 4 and silly characters ?%.$!/')), 'jack-jill-like-numbers-123-and-4-and-silly-characters', diff --git a/tests/template_tests/filter_tests/test_urlize.py b/tests/template_tests/filter_tests/test_urlize.py index 3096213a2277..2bf94126d408 100644 --- a/tests/template_tests/filter_tests/test_urlize.py +++ b/tests/template_tests/filter_tests/test_urlize.py @@ -1,6 +1,5 @@ from django.template.defaultfilters import urlize from django.test import SimpleTestCase -from django.utils import six from django.utils.functional import lazy from django.utils.safestring import mark_safe @@ -367,7 +366,7 @@ def test_autoescape_off(self): ) def test_lazystring(self): - prepend_www = lazy(lambda url: 'www.' + url, six.text_type) + prepend_www = lazy(lambda url: 'www.' + url, str) self.assertEqual( urlize(prepend_www('google.com')), '
    www.google.com', diff --git a/tests/template_tests/templatetags/custom.py b/tests/template_tests/templatetags/custom.py index 3c3e4ce8ed4d..363e7094cec0 100644 --- a/tests/template_tests/templatetags/custom.py +++ b/tests/template_tests/templatetags/custom.py @@ -94,7 +94,7 @@ def simple_one_default(one, two='hi'): def simple_unlimited_args(one, two='hi', *args): """Expected simple_unlimited_args __doc__""" return "simple_unlimited_args - Expected result: %s" % ( - ', '.join(six.text_type(arg) for arg in [one, two] + list(args)) + ', '.join(str(arg) for arg in [one, two] + list(args)) ) @@ -104,7 +104,7 @@ def simple_unlimited_args(one, two='hi', *args): @register.simple_tag def simple_only_unlimited_args(*args): """Expected simple_only_unlimited_args __doc__""" - return "simple_only_unlimited_args - Expected result: %s" % ', '.join(six.text_type(arg) for arg in args) + return "simple_only_unlimited_args - Expected result: %s" % ', '.join(str(arg) for arg in args) simple_only_unlimited_args.anything = "Expected simple_only_unlimited_args __dict__" @@ -116,7 +116,7 @@ def simple_unlimited_args_kwargs(one, two='hi', *args, **kwargs): # Sort the dictionary by key to guarantee the order for testing. sorted_kwarg = sorted(six.iteritems(kwargs), key=operator.itemgetter(0)) return "simple_unlimited_args_kwargs - Expected result: %s / %s" % ( - ', '.join(six.text_type(arg) for arg in [one, two] + list(args)), + ', '.join(str(arg) for arg in [one, two] + list(args)), ', '.join('%s=%s' % (k, v) for (k, v) in sorted_kwarg) ) diff --git a/tests/template_tests/templatetags/inclusion.py b/tests/template_tests/templatetags/inclusion.py index dbdfa45c9500..745dd7ffae83 100644 --- a/tests/template_tests/templatetags/inclusion.py +++ b/tests/template_tests/templatetags/inclusion.py @@ -152,7 +152,7 @@ def inclusion_unlimited_args(one, two='hi', *args): return { "result": ( "inclusion_unlimited_args - Expected result: %s" % ( - ', '.join(six.text_type(arg) for arg in [one, two] + list(args)) + ', '.join(str(arg) for arg in [one, two] + list(args)) ) ) } @@ -167,7 +167,7 @@ def inclusion_unlimited_args_from_template(one, two='hi', *args): return { "result": ( "inclusion_unlimited_args_from_template - Expected result: %s" % ( - ', '.join(six.text_type(arg) for arg in [one, two] + list(args)) + ', '.join(str(arg) for arg in [one, two] + list(args)) ) ) } @@ -181,7 +181,7 @@ def inclusion_only_unlimited_args(*args): """Expected inclusion_only_unlimited_args __doc__""" return { "result": "inclusion_only_unlimited_args - Expected result: %s" % ( - ', '.join(six.text_type(arg) for arg in args) + ', '.join(str(arg) for arg in args) ) } @@ -194,7 +194,7 @@ def inclusion_only_unlimited_args_from_template(*args): """Expected inclusion_only_unlimited_args_from_template __doc__""" return { "result": "inclusion_only_unlimited_args_from_template - Expected result: %s" % ( - ', '.join(six.text_type(arg) for arg in args) + ', '.join(str(arg) for arg in args) ) } @@ -217,7 +217,7 @@ def inclusion_unlimited_args_kwargs(one, two='hi', *args, **kwargs): # Sort the dictionary by key to guarantee the order for testing. sorted_kwarg = sorted(six.iteritems(kwargs), key=operator.itemgetter(0)) return {"result": "inclusion_unlimited_args_kwargs - Expected result: %s / %s" % ( - ', '.join(six.text_type(arg) for arg in [one, two] + list(args)), + ', '.join(str(arg) for arg in [one, two] + list(args)), ', '.join('%s=%s' % (k, v) for (k, v) in sorted_kwarg) )} diff --git a/tests/template_tests/test_unicode.py b/tests/template_tests/test_unicode.py index f6471e72e0de..dbd18eb4959e 100644 --- a/tests/template_tests/test_unicode.py +++ b/tests/template_tests/test_unicode.py @@ -2,7 +2,6 @@ from django.template import Context, Engine from django.template.base import TemplateEncodingError -from django.utils import six from django.utils.safestring import SafeData @@ -28,5 +27,5 @@ def test_template(self): # they all render the same (and are returned as unicode objects and # "safe" objects as well, for auto-escaping purposes). self.assertEqual(t1.render(c3), t2.render(c3)) - self.assertIsInstance(t1.render(c3), six.text_type) + self.assertIsInstance(t1.render(c3), str) self.assertIsInstance(t1.render(c3), SafeData) diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py index e63c6774ae69..4d29f1a491d8 100644 --- a/tests/test_utils/tests.py +++ b/tests/test_utils/tests.py @@ -226,7 +226,7 @@ def test_repeated_values(self): class CaptureQueriesContextManagerTests(TestCase): def setUp(self): - self.person_pk = six.text_type(Person.objects.create(name='test').pk) + self.person_pk = str(Person.objects.create(name='test').pk) def test_simple(self): with CaptureQueriesContext(connection) as captured_queries: diff --git a/tests/update/models.py b/tests/update/models.py index 1fbab38ca936..bfcc29bee9f3 100644 --- a/tests/update/models.py +++ b/tests/update/models.py @@ -4,7 +4,6 @@ """ from django.db import models -from django.utils import six class DataPoint(models.Model): @@ -13,7 +12,7 @@ class DataPoint(models.Model): another_value = models.CharField(max_length=20, blank=True) def __str__(self): - return six.text_type(self.name) + return self.name class RelatedPoint(models.Model): @@ -21,7 +20,7 @@ class RelatedPoint(models.Model): data = models.ForeignKey(DataPoint, models.CASCADE) def __str__(self): - return six.text_type(self.name) + return self.name class A(models.Model): diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py index 157479a579e7..62d199c030b9 100644 --- a/tests/urlpatterns_reverse/tests.py +++ b/tests/urlpatterns_reverse/tests.py @@ -20,7 +20,6 @@ NoReverseMatch, RegexURLPattern, RegexURLResolver, Resolver404, ResolverMatch, get_callable, get_resolver, resolve, reverse, reverse_lazy, ) -from django.utils import six from . import middleware, urlconf_outer, views from .utils import URLObject @@ -336,13 +335,6 @@ def test_script_name_escaping(self): '/script:name/optional/foo:bar/' ) - def test_reverse_returns_unicode(self): - name, expected, args, kwargs = test_data[0] - self.assertIsInstance( - reverse(name, args=args, kwargs=kwargs), - six.text_type - ) - def test_view_not_found_message(self): msg = ( "Reverse for 'non-existent-view' not found. 'non-existent-view' " diff --git a/tests/utils_tests/test_encoding.py b/tests/utils_tests/test_encoding.py index b4e7b9c0acef..faf30a59c0f6 100644 --- a/tests/utils_tests/test_encoding.py +++ b/tests/utils_tests/test_encoding.py @@ -1,7 +1,6 @@ import datetime import unittest -from django.utils import six from django.utils.encoding import ( escape_uri_path, filepath_to_uri, force_bytes, force_text, iri_to_uri, smart_text, uri_to_iri, @@ -27,7 +26,7 @@ def __str__(self): def test_force_text_lazy(self): s = SimpleLazyObject(lambda: 'x') - self.assertTrue(issubclass(type(force_text(s)), six.text_type)) + self.assertTrue(issubclass(type(force_text(s)), str)) def test_force_bytes_exception(self): """ diff --git a/tests/utils_tests/test_functional.py b/tests/utils_tests/test_functional.py index 0ca534445fae..f53e212f93b7 100644 --- a/tests/utils_tests/test_functional.py +++ b/tests/utils_tests/test_functional.py @@ -1,6 +1,5 @@ import unittest -from django.utils import six from django.utils.functional import cached_property, lazy @@ -45,8 +44,8 @@ def __bytes__(self): return b"\xc3\x8e am \xc4\x81 binary \xc7\xa8l\xc3\xa2zz." t = lazy(lambda: Klazz(), Klazz)() - self.assertEqual(six.text_type(t), "Î am ā Ǩlâzz.") - self.assertEqual(six.binary_type(t), b"\xc3\x8e am \xc4\x81 binary \xc7\xa8l\xc3\xa2zz.") + self.assertEqual(str(t), "Î am ā Ǩlâzz.") + self.assertEqual(bytes(t), b"\xc3\x8e am \xc4\x81 binary \xc7\xa8l\xc3\xa2zz.") def test_cached_property(self): """ @@ -99,7 +98,7 @@ def test_lazy_equality(self): def test_lazy_repr_text(self): original_object = 'Lazy translation text' - lazy_obj = lazy(lambda: original_object, six.text_type) + lazy_obj = lazy(lambda: original_object, str) self.assertEqual(repr(original_object), repr(lazy_obj())) def test_lazy_repr_int(self): diff --git a/tests/utils_tests/test_lazyobject.py b/tests/utils_tests/test_lazyobject.py index 588e85afc58a..8c9b997b3c3a 100644 --- a/tests/utils_tests/test_lazyobject.py +++ b/tests/utils_tests/test_lazyobject.py @@ -73,7 +73,7 @@ def test_bytes(self): def test_text(self): obj = self.lazy_wrap('foo') - self.assertEqual(six.text_type(obj), 'foo') + self.assertEqual(str(obj), 'foo') def test_bool(self): # Refs #21840 diff --git a/tests/utils_tests/test_safestring.py b/tests/utils_tests/test_safestring.py index 96f42d5ddd06..9e99b6e20b67 100644 --- a/tests/utils_tests/test_safestring.py +++ b/tests/utils_tests/test_safestring.py @@ -1,6 +1,6 @@ from django.template import Context, Template from django.test import SimpleTestCase -from django.utils import html, six, text +from django.utils import html, text from django.utils.encoding import force_bytes from django.utils.functional import lazy, lazystr from django.utils.safestring import SafeData, mark_safe @@ -8,7 +8,7 @@ lazybytes = lazy(force_bytes, bytes) -class customescape(six.text_type): +class customescape(str): def __html__(self): # implement specific and obviously wrong escaping # in order to be able to tell for sure when it runs diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py index 9128fb02476f..22695277a43b 100644 --- a/tests/utils_tests/test_text.py +++ b/tests/utils_tests/test_text.py @@ -1,7 +1,7 @@ import json from django.test import SimpleTestCase -from django.utils import six, text +from django.utils import text from django.utils.functional import lazystr from django.utils.text import format_lazy from django.utils.translation import override, ugettext_lazy @@ -161,7 +161,6 @@ def test_normalize_newlines_bytes(self): """normalize_newlines should be able to handle bytes too""" normalized = text.normalize_newlines(b"abc\ndef\rghi\r\n") self.assertEqual(normalized, "abc\ndef\nghi\n") - self.assertIsInstance(normalized, six.text_type) def test_phone2numeric(self): numeric = text.phone2numeric('0800 flowers') From 2b281cc35ed9d997614ca3c416928d7fabfef1ad Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Sat, 7 Jan 2017 12:11:46 +0100 Subject: [PATCH 0064/3180] Refs #23919 -- Removed most of remaining six usage Thanks Tim Graham for the review. --- django/contrib/admin/options.py | 5 +- django/contrib/admin/sites.py | 3 +- .../contrib/admin/templatetags/admin_urls.py | 3 +- django/contrib/auth/decorators.py | 2 +- .../management/commands/createsuperuser.py | 1 - django/contrib/auth/views.py | 2 +- django/contrib/contenttypes/checks.py | 3 +- .../contenttypes/management/__init__.py | 3 +- .../commands/remove_stale_contenttypes.py | 4 +- .../contrib/gis/db/backends/oracle/adapter.py | 1 - django/contrib/gis/gdal/datasource.py | 1 - django/contrib/gis/gdal/feature.py | 1 - django/contrib/gis/gdal/geometries.py | 8 +- django/contrib/gis/gdal/layer.py | 1 - django/contrib/gis/gdal/raster/band.py | 4 +- django/contrib/gis/geos/collections.py | 1 - django/contrib/gis/geos/coordseq.py | 1 - django/contrib/gis/geos/factory.py | 3 +- django/contrib/gis/geos/geometry.py | 5 +- django/contrib/gis/geos/linestring.py | 1 - django/contrib/gis/geos/mutable_list.py | 2 - django/contrib/gis/geos/point.py | 1 - django/contrib/gis/geos/polygon.py | 1 - django/contrib/gis/geos/prototypes/io.py | 5 +- django/contrib/gis/geos/prototypes/misc.py | 1 - django/contrib/gis/measure.py | 4 +- django/contrib/gis/utils/ogrinspect.py | 1 - django/contrib/messages/storage/cookie.py | 3 +- django/contrib/sessions/backends/cache.py | 1 - django/contrib/sessions/serializers.py | 7 +- django/contrib/sitemaps/__init__.py | 5 +- django/contrib/staticfiles/finders.py | 4 +- django/contrib/staticfiles/handlers.py | 5 +- .../management/commands/collectstatic.py | 1 - django/contrib/staticfiles/storage.py | 8 +- django/contrib/staticfiles/views.py | 2 +- django/contrib/syndication/views.py | 6 +- django/core/cache/backends/db.py | 6 +- django/core/cache/backends/filebased.py | 6 +- django/core/cache/backends/locmem.py | 7 +- django/core/files/storage.py | 2 +- django/core/mail/message.py | 5 +- django/core/management/__init__.py | 4 +- django/core/management/commands/flush.py | 1 - .../management/commands/makemigrations.py | 4 +- .../management/commands/squashmigrations.py | 3 +- django/core/management/templates.py | 2 +- django/core/paginator.py | 3 +- django/core/serializers/__init__.py | 3 +- django/core/serializers/base.py | 9 +- django/core/serializers/python.py | 3 +- django/core/servers/basehttp.py | 2 +- django/core/validators.py | 2 +- django/db/backends/base/base.py | 10 +- django/db/backends/base/creation.py | 3 +- django/db/backends/oracle/base.py | 2 +- django/db/backends/oracle/creation.py | 1 - django/db/backends/postgresql/client.py | 3 +- django/db/backends/sqlite3/creation.py | 1 - django/db/migrations/loader.py | 4 +- django/db/migrations/questioner.py | 1 - django/db/migrations/serializer.py | 5 +- django/db/models/base.py | 4 +- django/db/models/deletion.py | 19 ++- django/db/models/lookups.py | 1 - django/db/models/options.py | 3 +- django/db/models/query.py | 4 +- django/db/models/sql/compiler.py | 1 - django/db/models/sql/query.py | 17 ++- django/db/models/sql/subqueries.py | 5 +- django/dispatch/dispatcher.py | 1 - django/forms/fields.py | 2 +- django/forms/forms.py | 3 +- django/forms/formsets.py | 1 - django/forms/models.py | 5 +- django/forms/widgets.py | 5 +- django/http/cookie.py | 11 +- django/http/multipartparser.py | 10 +- django/http/request.py | 8 +- django/http/response.py | 9 +- django/middleware/common.py | 2 +- django/middleware/csrf.py | 3 +- django/template/defaulttags.py | 5 +- django/template/loader_tags.py | 5 +- django/templatetags/static.py | 3 +- django/test/client.py | 2 +- django/test/runner.py | 2 +- django/test/selenium.py | 3 +- django/test/testcases.py | 9 +- django/test/utils.py | 6 +- django/urls/base.py | 2 +- django/utils/_os.py | 1 - django/utils/autoreload.py | 7 +- django/utils/crypto.py | 1 - django/utils/datastructures.py | 6 +- django/utils/dateparse.py | 9 +- django/utils/encoding.py | 3 +- django/utils/feedgenerator.py | 4 +- django/utils/functional.py | 4 +- django/utils/html.py | 9 +- django/utils/html_parser.py | 8 +- django/utils/http.py | 8 +- django/utils/ipv6.py | 1 - django/utils/regex_helper.py | 1 - django/utils/termcolors.py | 4 +- django/utils/text.py | 7 +- django/utils/translation/template.py | 2 +- django/views/generic/base.py | 3 +- django/views/i18n.py | 3 +- django/views/static.py | 2 +- tests/admin_scripts/tests.py | 2 +- tests/admin_views/admin.py | 2 +- tests/admin_views/tests.py | 2 +- tests/aggregation_regress/tests.py | 3 +- tests/auth_tests/test_deprecated_views.py | 2 +- tests/auth_tests/test_management.py | 51 +++---- tests/auth_tests/test_views.py | 2 +- tests/backends/tests.py | 1 - tests/base/models.py | 5 +- tests/cache/tests.py | 14 +- tests/check_framework/tests.py | 2 +- tests/contenttypes_tests/tests.py | 10 +- tests/db_typecasts/tests.py | 3 +- tests/delete/tests.py | 1 - tests/deprecation/tests.py | 15 +-- tests/file_storage/tests.py | 11 +- tests/file_uploads/tests.py | 3 +- tests/fixtures/tests.py | 14 +- tests/fixtures_regress/tests.py | 2 +- tests/gis_tests/gdal_tests/test_geom.py | 8 +- tests/gis_tests/gdal_tests/test_raster.py | 3 +- tests/gis_tests/geoapp/tests.py | 4 +- tests/gis_tests/geos_tests/test_geos.py | 15 +-- tests/gis_tests/inspectapp/tests.py | 2 +- tests/gis_tests/test_data.py | 3 +- tests/httpwrappers/tests.py | 41 +++--- tests/i18n/test_compilation.py | 2 +- tests/i18n/test_extraction.py | 2 +- tests/inspectdb/tests.py | 2 +- tests/logging_tests/tests.py | 4 +- tests/m2m_through_regress/tests.py | 3 +- tests/mail/tests.py | 2 +- tests/middleware/tests.py | 9 +- tests/migrate_signals/tests.py | 7 +- tests/migrations/models.py | 3 +- tests/migrations/test_commands.py | 125 +++++++++--------- tests/migrations/test_writer.py | 5 +- tests/model_fields/models.py | 3 +- tests/model_fields/test_binaryfield.py | 3 +- tests/model_forms/models.py | 1 - tests/model_forms/tests.py | 3 +- tests/multiple_database/tests.py | 2 +- tests/pagination/tests.py | 3 +- tests/queries/tests.py | 1 - tests/requests/tests.py | 6 +- tests/serializers/test_data.py | 3 +- tests/serializers/test_yaml.py | 2 +- tests/serializers/tests.py | 2 +- tests/servers/tests.py | 4 +- tests/sessions_tests/tests.py | 14 +- tests/sitemaps_tests/test_utils.py | 3 +- tests/staticfiles_tests/test_forms.py | 3 +- tests/staticfiles_tests/test_liveserver.py | 2 +- tests/staticfiles_tests/test_management.py | 31 +++-- tests/staticfiles_tests/test_storage.py | 10 +- tests/swappable_models/tests.py | 5 +- .../syntax_tests/test_static.py | 3 +- tests/template_tests/templatetags/custom.py | 3 +- .../template_tests/templatetags/inclusion.py | 3 +- tests/test_client/views.py | 2 +- tests/test_client_regress/views.py | 2 +- tests/test_runner/test_debug_sql.py | 4 +- tests/test_utils/tests.py | 4 +- tests/timezones/tests.py | 10 +- tests/user_commands/tests.py | 2 +- tests/utils_tests/test_autoreload.py | 3 +- tests/utils_tests/test_baseconv.py | 1 - tests/utils_tests/test_datastructures.py | 12 +- tests/utils_tests/test_lazyobject.py | 3 +- tests/view_tests/tests/test_debug.py | 6 +- 180 files changed, 421 insertions(+), 559 deletions(-) diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index eaa99160566d..2d4bbbb933b2 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -36,7 +36,6 @@ from django.http.response import HttpResponseBase from django.template.response import SimpleTemplateResponse, TemplateResponse from django.urls import reverse -from django.utils import six from django.utils.decorators import method_decorator from django.utils.encoding import force_text from django.utils.html import format_html @@ -92,7 +91,7 @@ class IncorrectLookupParameters(Exception): csrf_protect_m = method_decorator(csrf_protect) -class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): +class BaseModelAdmin(metaclass=forms.MediaDefiningClass): """Functionality common to both ModelAdmin and InlineAdmin.""" raw_id_fields = () @@ -805,7 +804,7 @@ def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH): tuple (name, description). """ choices = [] + default_choices - for func, name, description in six.itervalues(self.get_actions(request)): + for func, name, description in self.get_actions(request).values(): choice = (name, description % model_format_dict(self.opts)) choices.append(choice) return choices diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index b3297d04f6f3..14b0da7df424 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -9,7 +9,6 @@ from django.http import Http404, HttpResponseRedirect from django.template.response import TemplateResponse from django.urls import NoReverseMatch, reverse -from django.utils import six from django.utils.text import capfirst from django.utils.translation import ugettext as _, ugettext_lazy from django.views.decorators.cache import never_cache @@ -169,7 +168,7 @@ def actions(self): """ Get all the enabled actions as an iterable of (name, func). """ - return six.iteritems(self._actions) + return iter(self._actions.items()) @property def empty_value_display(self): diff --git a/django/contrib/admin/templatetags/admin_urls.py b/django/contrib/admin/templatetags/admin_urls.py index 8e665ec9de57..097fbcf040dc 100644 --- a/django/contrib/admin/templatetags/admin_urls.py +++ b/django/contrib/admin/templatetags/admin_urls.py @@ -1,8 +1,9 @@ +from urllib.parse import parse_qsl, urlparse, urlunparse + from django import template from django.contrib.admin.utils import quote from django.urls import Resolver404, get_script_prefix, resolve from django.utils.http import urlencode -from django.utils.six.moves.urllib.parse import parse_qsl, urlparse, urlunparse register = template.Library() diff --git a/django/contrib/auth/decorators.py b/django/contrib/auth/decorators.py index f6e4c1d5b254..807ea8a3f61b 100644 --- a/django/contrib/auth/decorators.py +++ b/django/contrib/auth/decorators.py @@ -1,11 +1,11 @@ from functools import wraps +from urllib.parse import urlparse from django.conf import settings from django.contrib.auth import REDIRECT_FIELD_NAME from django.core.exceptions import PermissionDenied from django.shortcuts import resolve_url from django.utils.decorators import available_attrs -from django.utils.six.moves.urllib.parse import urlparse def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME): diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py index b9f13b7b0581..7a6d0b023156 100644 --- a/django/contrib/auth/management/commands/createsuperuser.py +++ b/django/contrib/auth/management/commands/createsuperuser.py @@ -11,7 +11,6 @@ from django.core.management.base import BaseCommand, CommandError from django.db import DEFAULT_DB_ALIAS from django.utils.encoding import force_str -from django.utils.six.moves import input from django.utils.text import capfirst diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py index 1a004e7a84db..bf95d11a1057 100644 --- a/django/contrib/auth/views.py +++ b/django/contrib/auth/views.py @@ -1,4 +1,5 @@ import warnings +from urllib.parse import urlparse, urlunparse from django.conf import settings # Avoid shadowing the login() and logout() views below. @@ -20,7 +21,6 @@ from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_text from django.utils.http import is_safe_url, urlsafe_base64_decode -from django.utils.six.moves.urllib.parse import urlparse, urlunparse from django.utils.translation import ugettext_lazy as _ from django.views.decorators.cache import never_cache from django.views.decorators.csrf import csrf_protect diff --git a/django/contrib/contenttypes/checks.py b/django/contrib/contenttypes/checks.py index 2355a5e943df..d21df40f46d3 100644 --- a/django/contrib/contenttypes/checks.py +++ b/django/contrib/contenttypes/checks.py @@ -1,7 +1,6 @@ from itertools import chain from django.apps import apps -from django.utils import six def check_generic_foreign_keys(app_configs=None, **kwargs): @@ -13,7 +12,7 @@ def check_generic_foreign_keys(app_configs=None, **kwargs): models = chain.from_iterable(app_config.get_models() for app_config in app_configs) errors = [] fields = ( - obj for model in models for obj in six.itervalues(vars(model)) + obj for model in models for obj in vars(model).values() if isinstance(obj, GenericForeignKey) ) for field in fields: diff --git a/django/contrib/contenttypes/management/__init__.py b/django/contrib/contenttypes/management/__init__.py index d0d5b52f098a..6799ef8a2360 100644 --- a/django/contrib/contenttypes/management/__init__.py +++ b/django/contrib/contenttypes/management/__init__.py @@ -1,7 +1,6 @@ from django.apps import apps as global_apps from django.db import DEFAULT_DB_ALIAS, migrations, router, transaction from django.db.utils import IntegrityError -from django.utils import six class RenameContentType(migrations.RunPython): @@ -126,7 +125,7 @@ def create_contenttypes(app_config, verbosity=2, interactive=True, using=DEFAULT app_label=app_label, model=model_name, ) - for (model_name, model) in six.iteritems(app_models) + for (model_name, model) in app_models.items() if model_name not in content_types ] ContentType.objects.using(using).bulk_create(cts) diff --git a/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py b/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py index 2a3b23b0d05f..e5f77dc7dfdd 100644 --- a/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py +++ b/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py @@ -3,8 +3,6 @@ from django.core.management import BaseCommand from django.db import DEFAULT_DB_ALIAS, router from django.db.models.deletion import Collector -from django.utils import six -from django.utils.six.moves import input from ...management import get_contenttypes_and_models @@ -32,7 +30,7 @@ def handle(self, **options): if not app_models: continue to_remove = [ - ct for (model_name, ct) in six.iteritems(content_types) + ct for (model_name, ct) in content_types.items() if model_name not in app_models ] # Confirm that the content type is stale before deletion. diff --git a/django/contrib/gis/db/backends/oracle/adapter.py b/django/contrib/gis/db/backends/oracle/adapter.py index 11eb0424aac8..7c43391f696a 100644 --- a/django/contrib/gis/db/backends/oracle/adapter.py +++ b/django/contrib/gis/db/backends/oracle/adapter.py @@ -2,7 +2,6 @@ from django.contrib.gis.db.backends.base.adapter import WKTAdapter from django.contrib.gis.geos import GeometryCollection, Polygon -from django.utils.six.moves import range class OracleSpatialAdapter(WKTAdapter): diff --git a/django/contrib/gis/gdal/datasource.py b/django/contrib/gis/gdal/datasource.py index 1ff2326a635b..3008da804cf4 100644 --- a/django/contrib/gis/gdal/datasource.py +++ b/django/contrib/gis/gdal/datasource.py @@ -41,7 +41,6 @@ from django.contrib.gis.gdal.layer import Layer from django.contrib.gis.gdal.prototypes import ds as capi from django.utils.encoding import force_bytes, force_text -from django.utils.six.moves import range # For more information, see the OGR C API source code: diff --git a/django/contrib/gis/gdal/feature.py b/django/contrib/gis/gdal/feature.py index 8975b9c0761e..47e8bb1ae31c 100644 --- a/django/contrib/gis/gdal/feature.py +++ b/django/contrib/gis/gdal/feature.py @@ -4,7 +4,6 @@ from django.contrib.gis.gdal.geometries import OGRGeometry, OGRGeomType from django.contrib.gis.gdal.prototypes import ds as capi, geom as geom_api from django.utils.encoding import force_bytes, force_text -from django.utils.six.moves import range # For more information, see the OGR C API source code: diff --git a/django/contrib/gis/gdal/geometries.py b/django/contrib/gis/gdal/geometries.py index 28ef2907ac12..50c1d9ff65c9 100644 --- a/django/contrib/gis/gdal/geometries.py +++ b/django/contrib/gis/gdal/geometries.py @@ -51,9 +51,7 @@ from django.contrib.gis.gdal.prototypes import geom as capi, srs as srs_api from django.contrib.gis.gdal.srs import CoordTransform, SpatialReference from django.contrib.gis.geometry.regex import hex_regex, json_regex, wkt_regex -from django.utils import six from django.utils.encoding import force_bytes -from django.utils.six.moves import range # For more information, see the OGR C API source code: @@ -71,7 +69,7 @@ def __init__(self, geom_input, srs=None): # If HEX, unpack input to a binary buffer. if str_instance and hex_regex.match(geom_input): - geom_input = six.memoryview(a2b_hex(geom_input.upper().encode())) + geom_input = memoryview(a2b_hex(geom_input.upper().encode())) str_instance = False # Constructing the geometry, @@ -96,7 +94,7 @@ def __init__(self, geom_input, srs=None): # (e.g., 'Point', 'POLYGON'). OGRGeomType(geom_input) g = capi.create_geom(OGRGeomType(geom_input).num) - elif isinstance(geom_input, six.memoryview): + elif isinstance(geom_input, memoryview): # WKB was passed in g = self._from_wkb(geom_input) elif isinstance(geom_input, OGRGeomType): @@ -353,7 +351,7 @@ def wkb(self): buf = (c_ubyte * sz)() capi.to_wkb(self.ptr, byteorder, byref(buf)) # Returning a buffer of the string at the pointer. - return six.memoryview(string_at(buf, sz)) + return memoryview(string_at(buf, sz)) @property def wkt(self): diff --git a/django/contrib/gis/gdal/layer.py b/django/contrib/gis/gdal/layer.py index fbbede81b054..119abf9459c6 100644 --- a/django/contrib/gis/gdal/layer.py +++ b/django/contrib/gis/gdal/layer.py @@ -14,7 +14,6 @@ ) from django.contrib.gis.gdal.srs import SpatialReference from django.utils.encoding import force_bytes, force_text -from django.utils.six.moves import range # For more information, see the OGR C API source code: diff --git a/django/contrib/gis/gdal/raster/band.py b/django/contrib/gis/gdal/raster/band.py index bb65cf197e40..141dc0e5b69a 100644 --- a/django/contrib/gis/gdal/raster/band.py +++ b/django/contrib/gis/gdal/raster/band.py @@ -4,9 +4,7 @@ from django.contrib.gis.gdal.error import GDALException from django.contrib.gis.gdal.prototypes import raster as capi from django.contrib.gis.shortcuts import numpy -from django.utils import six from django.utils.encoding import force_text -from django.utils.six.moves import range from .const import GDAL_INTEGER_TYPES, GDAL_PIXEL_TYPES, GDAL_TO_CTYPES @@ -207,7 +205,7 @@ def data(self, data=None, offset=None, size=None, shape=None, as_memoryview=Fals access_flag = 1 # Instantiate ctypes array holding the input data - if isinstance(data, (bytes, six.memoryview)) or (numpy and isinstance(data, numpy.ndarray)): + if isinstance(data, (bytes, memoryview)) or (numpy and isinstance(data, numpy.ndarray)): data_array = ctypes_array.from_buffer_copy(data) else: data_array = ctypes_array(*data) diff --git a/django/contrib/gis/geos/collections.py b/django/contrib/gis/geos/collections.py index 4935dbd1c3c6..e964a1de8f46 100644 --- a/django/contrib/gis/geos/collections.py +++ b/django/contrib/gis/geos/collections.py @@ -12,7 +12,6 @@ from django.contrib.gis.geos.linestring import LinearRing, LineString from django.contrib.gis.geos.point import Point from django.contrib.gis.geos.polygon import Polygon -from django.utils.six.moves import range class GeometryCollection(GEOSGeometry): diff --git a/django/contrib/gis/geos/coordseq.py b/django/contrib/gis/geos/coordseq.py index 8722874099f6..6908b040c08a 100644 --- a/django/contrib/gis/geos/coordseq.py +++ b/django/contrib/gis/geos/coordseq.py @@ -10,7 +10,6 @@ from django.contrib.gis.geos.error import GEOSException from django.contrib.gis.geos.libgeos import CS_PTR from django.contrib.gis.shortcuts import numpy -from django.utils.six.moves import range class GEOSCoordSeq(GEOSBase): diff --git a/django/contrib/gis/geos/factory.py b/django/contrib/gis/geos/factory.py index 42cd10c75625..54c19aab3709 100644 --- a/django/contrib/gis/geos/factory.py +++ b/django/contrib/gis/geos/factory.py @@ -1,5 +1,4 @@ from django.contrib.gis.geos.geometry import GEOSGeometry, hex_regex, wkt_regex -from django.utils import six def fromfile(file_h): @@ -25,7 +24,7 @@ def fromfile(file_h): else: return GEOSGeometry(buf) - return GEOSGeometry(six.memoryview(buf)) + return GEOSGeometry(memoryview(buf)) def fromstr(string, **kwargs): diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py index f7bdf8937f5f..f49ce2e0defb 100644 --- a/django/contrib/gis/geos/geometry.py +++ b/django/contrib/gis/geos/geometry.py @@ -17,7 +17,6 @@ from django.contrib.gis.geos.prototypes.io import ( ewkb_w, wkb_r, wkb_w, wkt_r, wkt_w, ) -from django.utils import six from django.utils.deconstruct import deconstructible from django.utils.encoding import force_bytes, force_text @@ -67,7 +66,7 @@ def __init__(self, geo_input, srid=None): elif isinstance(geo_input, GEOM_PTR): # When the input is a pointer to a geometry (GEOM_PTR). g = geo_input - elif isinstance(geo_input, six.memoryview): + elif isinstance(geo_input, memoryview): # When the input is a buffer (WKB). g = wkb_r().read(geo_input) elif isinstance(geo_input, GEOSGeometry): @@ -149,7 +148,7 @@ def __getstate__(self): def __setstate__(self, state): # Instantiating from the tuple state that was pickled. wkb, srid = state - ptr = wkb_r().read(six.memoryview(wkb)) + ptr = wkb_r().read(memoryview(wkb)) if not ptr: raise GEOSException('Invalid Geometry loaded from pickled state.') self.ptr = ptr diff --git a/django/contrib/gis/geos/linestring.py b/django/contrib/gis/geos/linestring.py index 7bfc0043700c..6caf6bef34b4 100644 --- a/django/contrib/gis/geos/linestring.py +++ b/django/contrib/gis/geos/linestring.py @@ -4,7 +4,6 @@ from django.contrib.gis.geos.geometry import GEOSGeometry, LinearGeometryMixin from django.contrib.gis.geos.point import Point from django.contrib.gis.shortcuts import numpy -from django.utils.six.moves import range class LineString(LinearGeometryMixin, GEOSGeometry): diff --git a/django/contrib/gis/geos/mutable_list.py b/django/contrib/gis/geos/mutable_list.py index 8896ebc51835..082f3b161a4c 100644 --- a/django/contrib/gis/geos/mutable_list.py +++ b/django/contrib/gis/geos/mutable_list.py @@ -10,8 +10,6 @@ """ from functools import total_ordering -from django.utils.six.moves import range - @total_ordering class ListMixin(object): diff --git a/django/contrib/gis/geos/point.py b/django/contrib/gis/geos/point.py index fadf5eb41420..72de47f9f6db 100644 --- a/django/contrib/gis/geos/point.py +++ b/django/contrib/gis/geos/point.py @@ -4,7 +4,6 @@ from django.contrib.gis.geos import prototypes as capi from django.contrib.gis.geos.error import GEOSException from django.contrib.gis.geos.geometry import GEOSGeometry -from django.utils.six.moves import range class Point(GEOSGeometry): diff --git a/django/contrib/gis/geos/polygon.py b/django/contrib/gis/geos/polygon.py index 0b4de0d3c302..58f1b28c293a 100644 --- a/django/contrib/gis/geos/polygon.py +++ b/django/contrib/gis/geos/polygon.py @@ -4,7 +4,6 @@ from django.contrib.gis.geos.geometry import GEOSGeometry from django.contrib.gis.geos.libgeos import GEOM_PTR, get_pointer_arr from django.contrib.gis.geos.linestring import LinearRing -from django.utils.six.moves import range class Polygon(GEOSGeometry): diff --git a/django/contrib/gis/geos/prototypes/io.py b/django/contrib/gis/geos/prototypes/io.py index 1cc0ccb8f34a..b8b1a06dbae8 100644 --- a/django/contrib/gis/geos/prototypes/io.py +++ b/django/contrib/gis/geos/prototypes/io.py @@ -7,7 +7,6 @@ check_geom, check_sized_string, check_string, ) from django.contrib.gis.geos.prototypes.geom import c_uchar_p, geos_char_p -from django.utils import six from django.utils.encoding import force_bytes @@ -147,7 +146,7 @@ class _WKBReader(IOBase): def read(self, wkb): "Returns a _pointer_ to C GEOS Geometry object from the given WKB." - if isinstance(wkb, six.memoryview): + if isinstance(wkb, memoryview): wkb_s = bytes(wkb) return wkb_reader_read(self.ptr, wkb_s, len(wkb_s)) elif isinstance(wkb, (bytes, str)): @@ -240,7 +239,7 @@ def write(self, geom): # Fix GEOS output for empty polygon. # See https://trac.osgeo.org/geos/ticket/680. wkb = wkb[:-8] + b'\0' * 4 - return six.memoryview(wkb) + return memoryview(wkb) def write_hex(self, geom): "Returns the HEXEWKB representation of the given geometry." diff --git a/django/contrib/gis/geos/prototypes/misc.py b/django/contrib/gis/geos/prototypes/misc.py index 4a82888d09d1..2d890c3d3161 100644 --- a/django/contrib/gis/geos/prototypes/misc.py +++ b/django/contrib/gis/geos/prototypes/misc.py @@ -7,7 +7,6 @@ from django.contrib.gis.geos.libgeos import GEOM_PTR, GEOSFuncFactory from django.contrib.gis.geos.prototypes.errcheck import check_dbl, check_string from django.contrib.gis.geos.prototypes.geom import geos_char_p -from django.utils.six.moves import range __all__ = ['geos_area', 'geos_distance', 'geos_length', 'geos_isvalidreason'] diff --git a/django/contrib/gis/measure.py b/django/contrib/gis/measure.py index 8691d009a630..a9b9e8a75f13 100644 --- a/django/contrib/gis/measure.py +++ b/django/contrib/gis/measure.py @@ -38,8 +38,6 @@ from decimal import Decimal from functools import total_ordering -from django.utils import six - __all__ = ['A', 'Area', 'D', 'Distance'] NUMERIC_TYPES = (int, float, Decimal) @@ -187,7 +185,7 @@ def default_units(self, kwargs): """ val = 0.0 default_unit = self.STANDARD_UNIT - for unit, value in six.iteritems(kwargs): + for unit, value in kwargs.items(): if not isinstance(value, float): value = float(value) if unit in self.UNITS: diff --git a/django/contrib/gis/utils/ogrinspect.py b/django/contrib/gis/utils/ogrinspect.py index c10364491dc5..52e0e655e419 100644 --- a/django/contrib/gis/utils/ogrinspect.py +++ b/django/contrib/gis/utils/ogrinspect.py @@ -8,7 +8,6 @@ OFTDate, OFTDateTime, OFTInteger, OFTInteger64, OFTReal, OFTString, OFTTime, ) -from django.utils.six.moves import zip def mapping(data_source, geom_name='geom', layer_key=0, multi_geom=False): diff --git a/django/contrib/messages/storage/cookie.py b/django/contrib/messages/storage/cookie.py index dec609dffaa7..b8d7f7474c8d 100644 --- a/django/contrib/messages/storage/cookie.py +++ b/django/contrib/messages/storage/cookie.py @@ -3,7 +3,6 @@ from django.conf import settings from django.contrib.messages.storage.base import BaseStorage, Message from django.http import SimpleCookie -from django.utils import six from django.utils.crypto import constant_time_compare, salted_hmac from django.utils.safestring import SafeData, mark_safe @@ -42,7 +41,7 @@ def process_messages(self, obj): return [self.process_messages(item) for item in obj] if isinstance(obj, dict): return {key: self.process_messages(value) - for key, value in six.iteritems(obj)} + for key, value in obj.items()} return obj def decode(self, s, **kwargs): diff --git a/django/contrib/sessions/backends/cache.py b/django/contrib/sessions/backends/cache.py index d50a17cdd843..c64d7f6a6ced 100644 --- a/django/contrib/sessions/backends/cache.py +++ b/django/contrib/sessions/backends/cache.py @@ -3,7 +3,6 @@ CreateError, SessionBase, UpdateError, ) from django.core.cache import caches -from django.utils.six.moves import range KEY_PREFIX = "django.contrib.sessions.cache" diff --git a/django/contrib/sessions/serializers.py b/django/contrib/sessions/serializers.py index b272c9c95d17..1badd17f46a8 100644 --- a/django/contrib/sessions/serializers.py +++ b/django/contrib/sessions/serializers.py @@ -1,9 +1,6 @@ -from django.core.signing import JSONSerializer as BaseJSONSerializer +import pickle -try: - from django.utils.six.moves import cPickle as pickle -except ImportError: - import pickle +from django.core.signing import JSONSerializer as BaseJSONSerializer class PickleSerializer(object): diff --git a/django/contrib/sitemaps/__init__.py b/django/contrib/sitemaps/__init__.py index 5721c8861d90..6e30a30f093f 100644 --- a/django/contrib/sitemaps/__init__.py +++ b/django/contrib/sitemaps/__init__.py @@ -1,11 +1,12 @@ +from urllib.parse import urlencode +from urllib.request import urlopen + from django.apps import apps as django_apps from django.conf import settings from django.core import paginator from django.core.exceptions import ImproperlyConfigured from django.urls import NoReverseMatch, reverse from django.utils import translation -from django.utils.six.moves.urllib.parse import urlencode -from django.utils.six.moves.urllib.request import urlopen PING_URL = "https://www.google.com/webmasters/tools/ping" diff --git a/django/contrib/staticfiles/finders.py b/django/contrib/staticfiles/finders.py index 81a919bf040a..c3da95ddd3bc 100644 --- a/django/contrib/staticfiles/finders.py +++ b/django/contrib/staticfiles/finders.py @@ -8,7 +8,7 @@ from django.core.files.storage import ( FileSystemStorage, Storage, default_storage, ) -from django.utils import lru_cache, six +from django.utils import lru_cache from django.utils._os import safe_join from django.utils.functional import LazyObject, empty from django.utils.module_loading import import_string @@ -143,7 +143,7 @@ def list(self, ignore_patterns): """ List all files in all app storages. """ - for storage in six.itervalues(self.storages): + for storage in self.storages.values(): if storage.exists(''): # check if storage location exists for path in utils.get_files(storage, ignore_patterns): yield path, storage diff --git a/django/contrib/staticfiles/handlers.py b/django/contrib/staticfiles/handlers.py index 8dedd60ce88b..ce8b7e20c179 100644 --- a/django/contrib/staticfiles/handlers.py +++ b/django/contrib/staticfiles/handlers.py @@ -1,9 +1,10 @@ +from urllib.parse import urlparse +from urllib.request import url2pathname + from django.conf import settings from django.contrib.staticfiles import utils from django.contrib.staticfiles.views import serve from django.core.handlers.wsgi import WSGIHandler, get_path_info -from django.utils.six.moves.urllib.parse import urlparse -from django.utils.six.moves.urllib.request import url2pathname class StaticFilesHandler(WSGIHandler): diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py index fac96e5bf471..3ee6d354afcd 100644 --- a/django/contrib/staticfiles/management/commands/collectstatic.py +++ b/django/contrib/staticfiles/management/commands/collectstatic.py @@ -9,7 +9,6 @@ from django.core.management.color import no_style from django.utils.encoding import force_text from django.utils.functional import cached_property -from django.utils.six.moves import input class Command(BaseCommand): diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py index b033243eccff..fe4a7c39f74e 100644 --- a/django/contrib/staticfiles/storage.py +++ b/django/contrib/staticfiles/storage.py @@ -4,6 +4,7 @@ import posixpath import re from collections import OrderedDict +from urllib.parse import unquote, urldefrag, urlsplit, urlunsplit from django.conf import settings from django.contrib.staticfiles.utils import check_settings, matches_patterns @@ -15,11 +16,6 @@ from django.core.files.storage import FileSystemStorage, get_storage_class from django.utils.encoding import force_bytes, force_text from django.utils.functional import LazyObject -from django.utils.six import iteritems -from django.utils.six.moves import range -from django.utils.six.moves.urllib.parse import ( - unquote, urldefrag, urlsplit, urlunsplit, -) class StaticFilesStorage(FileSystemStorage): @@ -293,7 +289,7 @@ def path_level(name): if name in adjustable_paths: old_hashed_name = hashed_name content = original_file.read().decode(settings.FILE_CHARSET) - for extension, patterns in iteritems(self._patterns): + for extension, patterns in self._patterns.items(): if matches_patterns(path, (extension,)): for pattern, template in patterns: converter = self.url_converter(name, hashed_files, template) diff --git a/django/contrib/staticfiles/views.py b/django/contrib/staticfiles/views.py index cec1247e5e0e..dfdbdac9e96f 100644 --- a/django/contrib/staticfiles/views.py +++ b/django/contrib/staticfiles/views.py @@ -5,11 +5,11 @@ """ import os import posixpath +from urllib.parse import unquote from django.conf import settings from django.contrib.staticfiles import finders from django.http import Http404 -from django.utils.six.moves.urllib.parse import unquote from django.views import static diff --git a/django/contrib/syndication/views.py b/django/contrib/syndication/views.py index fa9c5e7753fe..2cfe93033836 100644 --- a/django/contrib/syndication/views.py +++ b/django/contrib/syndication/views.py @@ -5,7 +5,7 @@ from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist from django.http import Http404, HttpResponse from django.template import TemplateDoesNotExist, loader -from django.utils import feedgenerator, six +from django.utils import feedgenerator from django.utils.encoding import force_text, iri_to_uri from django.utils.html import escape from django.utils.http import http_date @@ -83,9 +83,9 @@ def _get_dynamic_attr(self, attname, obj, default=None): # catching the TypeError, because something inside the function # may raise the TypeError. This technique is more accurate. try: - code = six.get_function_code(attr) + code = attr.__code__ except AttributeError: - code = six.get_function_code(attr.__call__) + code = attr.__call__.__code__ if code.co_argcount == 2: # one argument is 'self' return attr(obj) else: diff --git a/django/core/cache/backends/db.py b/django/core/cache/backends/db.py index ad805324bd6c..97f307e24dfb 100644 --- a/django/core/cache/backends/db.py +++ b/django/core/cache/backends/db.py @@ -1,5 +1,6 @@ "Database cache backend." import base64 +import pickle from datetime import datetime from django.conf import settings @@ -8,11 +9,6 @@ from django.utils import timezone from django.utils.encoding import force_bytes -try: - from django.utils.six.moves import cPickle as pickle -except ImportError: - import pickle - class Options(object): """A class that will quack like a Django model _meta class. diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py index 7c2c5c7edbb8..88509ed8de3e 100644 --- a/django/core/cache/backends/filebased.py +++ b/django/core/cache/backends/filebased.py @@ -4,6 +4,7 @@ import hashlib import io import os +import pickle import random import tempfile import time @@ -13,11 +14,6 @@ from django.core.files.move import file_move_safe from django.utils.encoding import force_bytes -try: - from django.utils.six.moves import cPickle as pickle -except ImportError: - import pickle - class FileBasedCache(BaseCache): cache_suffix = '.djcache' diff --git a/django/core/cache/backends/locmem.py b/django/core/cache/backends/locmem.py index 8916ad176c56..cf86dcaa0c47 100644 --- a/django/core/cache/backends/locmem.py +++ b/django/core/cache/backends/locmem.py @@ -1,17 +1,12 @@ "Thread-safe in-memory cache backend." +import pickle import time from contextlib import contextmanager from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache from django.utils.synch import RWLock -try: - from django.utils.six.moves import cPickle as pickle -except ImportError: - import pickle - - # Global in-memory store of cache data. Keyed by name, to provide # multiple named local memory caches. _caches = {} diff --git a/django/core/files/storage.py b/django/core/files/storage.py index 9cd4196c23a8..cf17eea33989 100644 --- a/django/core/files/storage.py +++ b/django/core/files/storage.py @@ -1,6 +1,7 @@ import errno import os from datetime import datetime +from urllib.parse import urljoin from django.conf import settings from django.core.exceptions import SuspiciousFileOperation @@ -14,7 +15,6 @@ from django.utils.encoding import filepath_to_uri, force_text from django.utils.functional import LazyObject, cached_property from django.utils.module_loading import import_string -from django.utils.six.moves.urllib.parse import urljoin from django.utils.text import get_valid_filename __all__ = ('Storage', 'FileSystemStorage', 'DefaultStorage', 'default_storage') diff --git a/django/core/mail/message.py b/django/core/mail/message.py index a8ea1f099198..117f2dddfc8d 100644 --- a/django/core/mail/message.py +++ b/django/core/mail/message.py @@ -14,11 +14,10 @@ from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.utils import formatdate, getaddresses, parseaddr -from io import BytesIO +from io import BytesIO, StringIO from django.conf import settings from django.core.mail.utils import DNS_NAME -from django.utils import six from django.utils.encoding import force_text # Don't BASE64-encode UTF-8 messages so that we avoid unwanted attention from @@ -164,7 +163,7 @@ def as_string(self, unixfrom=False, linesep='\n'): This overrides the default as_string() implementation to not mangle lines that begin with 'From '. See bug #13433 for details. """ - fp = six.StringIO() + fp = StringIO() g = generator.Generator(fp, mangle_from_=False) g.flatten(self, unixfrom=unixfrom, linesep=linesep) return fp.getvalue() diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py index 6b89fff3518f..00ee58a34be9 100644 --- a/django/core/management/__init__.py +++ b/django/core/management/__init__.py @@ -12,7 +12,7 @@ BaseCommand, CommandError, CommandParser, handle_default_options, ) from django.core.management.color import color_style -from django.utils import autoreload, lru_cache, six +from django.utils import autoreload, lru_cache from django.utils._os import npath, upath from django.utils.encoding import force_text @@ -154,7 +154,7 @@ def main_help_text(self, commands_only=False): "Available subcommands:", ] commands_dict = defaultdict(lambda: []) - for name, app in six.iteritems(get_commands()): + for name, app in get_commands().items(): if app == 'django.core': app = 'django' else: diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py index dbe870f322be..8d1621b11628 100644 --- a/django/core/management/commands/flush.py +++ b/django/core/management/commands/flush.py @@ -7,7 +7,6 @@ from django.core.management.sql import emit_post_migrate_signal, sql_flush from django.db import DEFAULT_DB_ALIAS, connections, transaction from django.utils import six -from django.utils.six.moves import input class Command(BaseCommand): diff --git a/django/core/management/commands/makemigrations.py b/django/core/management/commands/makemigrations.py index b6a31d16fd85..3364d958a976 100644 --- a/django/core/management/commands/makemigrations.py +++ b/django/core/management/commands/makemigrations.py @@ -17,8 +17,6 @@ from django.db.migrations.state import ProjectState from django.db.migrations.utils import get_migration_name_timestamp from django.db.migrations.writer import MigrationWriter -from django.utils.six import iteritems -from django.utils.six.moves import zip class Command(BaseCommand): @@ -102,7 +100,7 @@ def handle(self, *app_labels, **options): # If app_labels is specified, filter out conflicting migrations for unspecified apps if app_labels: conflicts = { - app_label: conflict for app_label, conflict in iteritems(conflicts) + app_label: conflict for app_label, conflict in conflicts.items() if app_label in app_labels } diff --git a/django/core/management/commands/squashmigrations.py b/django/core/management/commands/squashmigrations.py index dacc8fe6ce38..5556b2474506 100644 --- a/django/core/management/commands/squashmigrations.py +++ b/django/core/management/commands/squashmigrations.py @@ -7,7 +7,6 @@ from django.db.migrations.migration import SwappableTuple from django.db.migrations.optimizer import MigrationOptimizer from django.db.migrations.writer import MigrationWriter -from django.utils import six from django.utils.version import get_docs_version @@ -86,7 +85,7 @@ def handle(self, **options): if self.interactive: answer = None while not answer or answer not in "yn": - answer = six.moves.input("Do you wish to proceed? [yN] ") + answer = input("Do you wish to proceed? [yN] ") if not answer: answer = "n" break diff --git a/django/core/management/templates.py b/django/core/management/templates.py index 775e75201b5c..ccc4920fe379 100644 --- a/django/core/management/templates.py +++ b/django/core/management/templates.py @@ -10,6 +10,7 @@ import sys import tempfile from os import path +from urllib.request import urlretrieve import django from django.conf import settings @@ -17,7 +18,6 @@ from django.core.management.utils import handle_extensions from django.template import Context, Engine from django.utils import archive -from django.utils.six.moves.urllib.request import urlretrieve from django.utils.version import get_docs_version _drive_re = re.compile('^([a-z]):', re.I) diff --git a/django/core/paginator.py b/django/core/paginator.py index ae085bf83763..82aad33a157e 100644 --- a/django/core/paginator.py +++ b/django/core/paginator.py @@ -2,7 +2,6 @@ import warnings from math import ceil -from django.utils import six from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ @@ -99,7 +98,7 @@ def page_range(self): Returns a 1-based range of pages for iterating through within a template for loop. """ - return six.moves.range(1, self.num_pages + 1) + return range(1, self.num_pages + 1) def _check_object_list_is_ordered(self): """ diff --git a/django/core/serializers/__init__.py b/django/core/serializers/__init__.py index e62dbf75da7a..57d149cf0c99 100644 --- a/django/core/serializers/__init__.py +++ b/django/core/serializers/__init__.py @@ -21,7 +21,6 @@ from django.apps import apps from django.conf import settings from django.core.serializers.base import SerializerDoesNotExist -from django.utils import six # Built-in serializers BUILTIN_SERIALIZERS = { @@ -109,7 +108,7 @@ def get_serializer_formats(): def get_public_serializer_formats(): if not _serializers: _load_serializers() - return [k for k, v in six.iteritems(_serializers) if not v.Serializer.internal_use_only] + return [k for k, v in _serializers.items() if not v.Serializer.internal_use_only] def get_deserializer(format): diff --git a/django/core/serializers/base.py b/django/core/serializers/base.py index 2a10fbe19edf..bd35c0b79787 100644 --- a/django/core/serializers/base.py +++ b/django/core/serializers/base.py @@ -1,8 +1,9 @@ """ Module for abstract serializer/unserializer base classes. """ +from io import StringIO + from django.db import models -from django.utils import six class SerializerDoesNotExist(KeyError): @@ -59,7 +60,7 @@ class Serializer(object): # internal Django use. internal_use_only = False progress_class = ProgressBar - stream_class = six.StringIO + stream_class = StringIO def serialize(self, queryset, **options): """ @@ -158,7 +159,7 @@ def getvalue(self): return self.stream.getvalue() -class Deserializer(six.Iterator): +class Deserializer: """ Abstract base deserializer class. """ @@ -169,7 +170,7 @@ def __init__(self, stream_or_string, **options): """ self.options = options if isinstance(stream_or_string, str): - self.stream = six.StringIO(stream_or_string) + self.stream = StringIO(stream_or_string) else: self.stream = stream_or_string diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py index 9db5c2e6a675..7b7510be4154 100644 --- a/django/core/serializers/python.py +++ b/django/core/serializers/python.py @@ -9,7 +9,6 @@ from django.conf import settings from django.core.serializers import base from django.db import DEFAULT_DB_ALIAS, models -from django.utils import six from django.utils.encoding import force_text, is_protected_type @@ -113,7 +112,7 @@ def Deserializer(object_list, **options): field_names = field_names_cache[Model] # Handle each field - for (field_name, field_value) in six.iteritems(d["fields"]): + for (field_name, field_value) in d["fields"].items(): if ignore and field_name not in field_names: # skip fields no longer on model diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index e27378e7a5dd..da55eac58d32 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -9,6 +9,7 @@ import logging import socket +import socketserver import sys from wsgiref import simple_server @@ -16,7 +17,6 @@ from django.core.wsgi import get_wsgi_application from django.utils import six from django.utils.module_loading import import_string -from django.utils.six.moves import socketserver __all__ = ('WSGIServer', 'WSGIRequestHandler') diff --git a/django/core/validators.py b/django/core/validators.py index e2fcd6f72e1c..6e7220c8265f 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -1,12 +1,12 @@ import os import re +from urllib.parse import urlsplit, urlunsplit from django.core.exceptions import ValidationError from django.utils.deconstruct import deconstructible from django.utils.encoding import force_text from django.utils.functional import SimpleLazyObject from django.utils.ipv6 import is_valid_ipv6_address -from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit from django.utils.translation import ugettext_lazy as _, ungettext_lazy # These values, if given to validate(), will trigger the self.required check. diff --git a/django/db/backends/base/base.py b/django/db/backends/base/base.py index c50cf5266ace..ea976519ec74 100644 --- a/django/db/backends/base/base.py +++ b/django/db/backends/base/base.py @@ -4,6 +4,7 @@ from collections import deque from contextlib import contextmanager +import _thread import pytz from django.conf import settings @@ -16,7 +17,6 @@ from django.db.utils import DatabaseError, DatabaseErrorWrapper from django.utils import timezone from django.utils.functional import cached_property -from django.utils.six.moves import _thread as thread NO_DB_ALIAS = '__no_db__' @@ -82,7 +82,7 @@ def __init__(self, settings_dict, alias=DEFAULT_DB_ALIAS, # Thread-safety related attributes. self.allow_thread_sharing = allow_thread_sharing - self._thread_ident = thread.get_ident() + self._thread_ident = _thread.get_ident() # A list of no-argument functions to run when the transaction commits. # Each entry is an (sids, func) tuple, where sids is a set of the @@ -326,7 +326,7 @@ def savepoint(self): if not self._savepoint_allowed(): return - thread_ident = thread.get_ident() + thread_ident = _thread.get_ident() tid = str(thread_ident).replace('-', '') self.savepoint_state += 1 @@ -533,13 +533,13 @@ def validate_thread_sharing(self): authorized to be shared between threads (via the `allow_thread_sharing` property). Raises an exception if the validation fails. """ - if not (self.allow_thread_sharing or self._thread_ident == thread.get_ident()): + if not (self.allow_thread_sharing or self._thread_ident == _thread.get_ident()): raise DatabaseError( "DatabaseWrapper objects created in a " "thread can only be used in that same thread. The object " "with alias '%s' was created in thread id %s and this is " "thread id %s." - % (self.alias, self._thread_ident, thread.get_ident()) + % (self.alias, self._thread_ident, _thread.get_ident()) ) # ##### Miscellaneous ##### diff --git a/django/db/backends/base/creation.py b/django/db/backends/base/creation.py index 0cb6d75ff357..cf3e6c334795 100644 --- a/django/db/backends/base/creation.py +++ b/django/db/backends/base/creation.py @@ -1,11 +1,10 @@ import sys +from io import StringIO from django.apps import apps from django.conf import settings from django.core import serializers from django.db import router -from django.utils.six import StringIO -from django.utils.six.moves import input # The prefix to put on the default database name when creating # the test database. diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index c365c673c5b9..257dab0b9d51 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -516,7 +516,7 @@ def __iter__(self): return CursorIterator(self.cursor) -class CursorIterator(six.Iterator): +class CursorIterator: """ Cursor iterator wrapper that invokes our custom row factory. """ diff --git a/django/db/backends/oracle/creation.py b/django/db/backends/oracle/creation.py index d34f2a2d5079..adbf92b6a3cb 100644 --- a/django/db/backends/oracle/creation.py +++ b/django/db/backends/oracle/creation.py @@ -5,7 +5,6 @@ from django.db.utils import DatabaseError from django.utils.crypto import get_random_string from django.utils.functional import cached_property -from django.utils.six.moves import input TEST_DATABASE_PREFIX = 'test_' diff --git a/django/db/backends/postgresql/client.py b/django/db/backends/postgresql/client.py index dd3d40c0645a..005f43ddb83b 100644 --- a/django/db/backends/postgresql/client.py +++ b/django/db/backends/postgresql/client.py @@ -3,7 +3,6 @@ from django.core.files.temp import NamedTemporaryFile from django.db.backends.base.client import BaseDatabaseClient -from django.utils.six import print_ def _escape_pgpass(txt): @@ -40,7 +39,7 @@ def runshell_db(cls, conn_params): # Create temporary .pgpass file. temp_pgpass = NamedTemporaryFile(mode='w+') try: - print_( + print( _escape_pgpass(host) or '*', str(port) or '*', _escape_pgpass(dbname) or '*', diff --git a/django/db/backends/sqlite3/creation.py b/django/db/backends/sqlite3/creation.py index 33661e135756..e58a1303a7c9 100644 --- a/django/db/backends/sqlite3/creation.py +++ b/django/db/backends/sqlite3/creation.py @@ -5,7 +5,6 @@ from django.core.exceptions import ImproperlyConfigured from django.db.backends.base.creation import BaseDatabaseCreation from django.utils.encoding import force_text -from django.utils.six.moves import input class DatabaseCreation(BaseDatabaseCreation): diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py index 8a42d96e9aa9..492ad145fd8a 100644 --- a/django/db/migrations/loader.py +++ b/django/db/migrations/loader.py @@ -1,6 +1,6 @@ import os import sys -from importlib import import_module +from importlib import import_module, reload from django.apps import apps from django.conf import settings @@ -97,7 +97,7 @@ def load_disk(self): continue # Force a reload if it's already loaded (tests need this) if was_loaded: - six.moves.reload_module(module) + reload(module) self.migrated_apps.add(app_config.label) directory = os.path.dirname(module.__file__) # Scan for .py files diff --git a/django/db/migrations/questioner.py b/django/db/migrations/questioner.py index 17b9da8eafc7..caae498337eb 100644 --- a/django/db/migrations/questioner.py +++ b/django/db/migrations/questioner.py @@ -5,7 +5,6 @@ from django.apps import apps from django.db.models.fields import NOT_PROVIDED from django.utils import datetime_safe, timezone -from django.utils.six.moves import input from .loader import MigrationLoader diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index bcd2268e2a1f..4786e7b0120e 100644 --- a/django/db/migrations/serializer.py +++ b/django/db/migrations/serializer.py @@ -1,3 +1,4 @@ +import builtins import collections import datetime import decimal @@ -10,7 +11,7 @@ from django.db import models from django.db.migrations.operations.base import Operation from django.db.migrations.utils import COMPILED_REGEX_TYPE, RegexObject -from django.utils import datetime_safe, six +from django.utils import datetime_safe from django.utils.encoding import force_text from django.utils.functional import LazyObject, Promise from django.utils.timezone import utc @@ -305,7 +306,7 @@ def serialize(self): return string, set(imports) if hasattr(self.value, "__module__"): module = self.value.__module__ - if module == six.moves.builtins.__name__: + if module == builtins.__name__: return self.value.__name__, set() else: return "%s.%s" % (module, self.value.__name__), {"import %s" % module} diff --git a/django/db/models/base.py b/django/db/models/base.py index 95700edb13c1..b5f6c1e35372 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -26,10 +26,8 @@ class_prepared, post_init, post_save, pre_init, pre_save, ) from django.db.models.utils import make_model_tuple -from django.utils import six from django.utils.encoding import force_str, force_text from django.utils.functional import curry -from django.utils.six.moves import zip from django.utils.text import capfirst, get_text_list from django.utils.translation import ugettext_lazy as _ from django.utils.version import get_version @@ -385,7 +383,7 @@ def __init__(self, db=None): self.adding = True -class Model(six.with_metaclass(ModelBase)): +class Model(metaclass=ModelBase): def __init__(self, *args, **kwargs): # Alias some things as locals to avoid repeat global lookups diff --git a/django/db/models/deletion.py b/django/db/models/deletion.py index 26073be3ba71..0793475e65c2 100644 --- a/django/db/models/deletion.py +++ b/django/db/models/deletion.py @@ -3,7 +3,6 @@ from django.db import IntegrityError, connections, transaction from django.db.models import signals, sql -from django.utils import six class ProtectedError(IntegrityError): @@ -198,7 +197,7 @@ def collect(self, objs, source=None, nullable=False, collect_related=True, # Recursively collect concrete model's parent models, but not their # related objects. These will be found by meta.get_fields() concrete_model = model._meta.concrete_model - for ptr in six.itervalues(concrete_model._meta.parents): + for ptr in concrete_model._meta.parents.values(): if ptr: parent_objs = [getattr(obj, ptr.name) for obj in new_objs] self.collect(parent_objs, source=model, @@ -236,7 +235,7 @@ def related_objects(self, related, objs): ) def instances_with_model(self): - for model, instances in six.iteritems(self.data): + for model, instances in self.data.items(): for obj in instances: yield model, obj @@ -285,18 +284,18 @@ def delete(self): deleted_counter[qs.model._meta.label] += count # update fields - for model, instances_for_fieldvalues in six.iteritems(self.field_updates): + for model, instances_for_fieldvalues in self.field_updates.items(): query = sql.UpdateQuery(model) - for (field, value), instances in six.iteritems(instances_for_fieldvalues): + for (field, value), instances in instances_for_fieldvalues.items(): query.update_batch([obj.pk for obj in instances], {field.name: value}, self.using) # reverse instance collections - for instances in six.itervalues(self.data): + for instances in self.data.values(): instances.reverse() # delete instances - for model, instances in six.iteritems(self.data): + for model, instances in self.data.items(): query = sql.DeleteQuery(model) pk_list = [obj.pk for obj in instances] count = query.delete_batch(pk_list, self.using) @@ -309,11 +308,11 @@ def delete(self): ) # update collected instances - for model, instances_for_fieldvalues in six.iteritems(self.field_updates): - for (field, value), instances in six.iteritems(instances_for_fieldvalues): + for model, instances_for_fieldvalues in self.field_updates.items(): + for (field, value), instances in instances_for_fieldvalues.items(): for obj in instances: setattr(obj, field.attname, value) - for model, instances in six.iteritems(self.data): + for model, instances in self.data.items(): for instance in instances: setattr(instance, model._meta.pk.attname, None) return sum(deleted_counter.values()), dict(deleted_counter) diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py index b8093ddc3469..4b0914366162 100644 --- a/django/db/models/lookups.py +++ b/django/db/models/lookups.py @@ -10,7 +10,6 @@ ) from django.db.models.query_utils import RegisterLookupMixin from django.utils.functional import cached_property -from django.utils.six.moves import range class Lookup(object): diff --git a/django/db/models/options.py b/django/db/models/options.py index cf3e0311047c..7594b70fb287 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -13,7 +13,6 @@ from django.db.models.fields.proxy import OrderWrt from django.db.models.fields.related import OneToOneField from django.db.models.query_utils import PathInfo -from django.utils import six from django.utils.datastructures import ImmutableList, OrderedSet from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_text @@ -228,7 +227,7 @@ def _prepare(self, model): if self.parents: # Promote the first parent link in lieu of adding yet another # field. - field = next(six.itervalues(self.parents)) + field = next(iter(self.parents.values())) # Look for a local field with the same name as the # first parent link. If a local field has already been # created, use it instead of promoting the parent diff --git a/django/db/models/query.py b/django/db/models/query.py index 69f84d72a9da..1c20d9cbf652 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -480,7 +480,7 @@ def update_or_create(self, defaults=None, **kwargs): obj, created = self._create_object_from_params(lookup, params) if created: return obj, created - for k, v in six.iteritems(defaults): + for k, v in defaults.items(): setattr(obj, k, v() if callable(v) else v) obj.save(using=self.db) return obj, False @@ -1170,7 +1170,7 @@ def __instancecheck__(self, instance): return isinstance(instance, QuerySet) and instance.query.is_empty() -class EmptyQuerySet(six.with_metaclass(InstanceCheckMeta)): +class EmptyQuerySet(metaclass=InstanceCheckMeta): """ Marker class usable for checking if a queryset is empty by .none(): isinstance(qs.none(), EmptyQuerySet) -> True diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 37442c06c436..41733210c4c3 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -11,7 +11,6 @@ from django.db.models.sql.query import Query, get_order_dir from django.db.transaction import TransactionManagementError from django.db.utils import DatabaseError -from django.utils.six.moves import zip FORCE = object() diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 57ba7dfc8d38..3acef8faf5f3 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -30,7 +30,6 @@ from django.db.models.sql.where import ( AND, OR, ExtraWhere, NothingNode, WhereNode, ) -from django.utils import six from django.utils.encoding import force_text from django.utils.tree import Node @@ -104,7 +103,7 @@ def _execute_query(self): if params_type is tuple: params = tuple(adapter(val) for val in self.params) elif params_type is dict: - params = dict((key, adapter(val)) for key, val in six.iteritems(self.params)) + params = {key: adapter(val) for key, val in self.params.items()} else: raise RuntimeError("Unexpected params type: %s" % params_type) @@ -665,23 +664,23 @@ def deferred_to_data(self, target, callback): # slight complexity here is handling fields that exist on parent # models. workset = {} - for model, values in six.iteritems(seen): + for model, values in seen.items(): for field in model._meta.fields: if field in values: continue m = field.model._meta.concrete_model add_to_dict(workset, m, field) - for model, values in six.iteritems(must_include): + for model, values in must_include.items(): # If we haven't included a model in workset, we don't add the # corresponding must_include fields for that model, since an # empty set means "include all fields". That's why there's no # "else" branch here. if model in workset: workset[model].update(values) - for model, values in six.iteritems(workset): + for model, values in workset.items(): callback(target, model, values) else: - for model, values in six.iteritems(must_include): + for model, values in must_include.items(): if model in seen: seen[model].update(values) else: @@ -695,7 +694,7 @@ def deferred_to_data(self, target, callback): for model in orig_opts.get_parent_list(): if model not in seen: seen[model] = set() - for model, values in six.iteritems(seen): + for model, values in seen.items(): callback(target, model, values) def table_alias(self, table_name, create=False): @@ -813,7 +812,7 @@ def change_aliases(self, change_map): (key, col.relabeled_clone(change_map)) for key, col in self._annotations.items()) # 2. Rename the alias in the internal table/alias datastructures. - for old_alias, new_alias in six.iteritems(change_map): + for old_alias, new_alias in change_map.items(): if old_alias not in self.alias_map: continue alias_data = self.alias_map[old_alias].relabeled_clone(change_map) @@ -1698,7 +1697,7 @@ def set_group_by(self): self.group_by.append(col) if self.annotation_select: - for alias, annotation in six.iteritems(self.annotation_select): + for alias, annotation in self.annotation_select.items(): for col in annotation.get_group_by_cols(): self.group_by.append(col) diff --git a/django/db/models/sql/subqueries.py b/django/db/models/sql/subqueries.py index 089f04e04e0f..cfdadefdffef 100644 --- a/django/db/models/sql/subqueries.py +++ b/django/db/models/sql/subqueries.py @@ -9,7 +9,6 @@ CURSOR, GET_ITERATOR_CHUNK_SIZE, NO_RESULTS, ) from django.db.models.sql.query import Query -from django.utils import six __all__ = ['DeleteQuery', 'UpdateQuery', 'InsertQuery', 'AggregateQuery'] @@ -120,7 +119,7 @@ def add_update_values(self, values): querysets. """ values_seq = [] - for name, val in six.iteritems(values): + for name, val in values.items(): field = self.get_meta().get_field(name) direct = not (field.auto_created and not field.concrete) or not field.concrete model = field.model._meta.concrete_model @@ -164,7 +163,7 @@ def get_related_updates(self): if not self.related_updates: return [] result = [] - for model, values in six.iteritems(self.related_updates): + for model, values in self.related_updates.items(): query = UpdateQuery(model) query.values = values if self.related_ids is not None: diff --git a/django/dispatch/dispatcher.py b/django/dispatch/dispatcher.py index 8cf1680b6ed2..706c9eebbf71 100644 --- a/django/dispatch/dispatcher.py +++ b/django/dispatch/dispatcher.py @@ -3,7 +3,6 @@ import weakref from django.utils.inspect import func_accepts_kwargs -from django.utils.six.moves import range def _make_id(target): diff --git a/django/forms/fields.py b/django/forms/fields.py index 5be10708c3d4..94a7bbbfc244 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -11,6 +11,7 @@ import uuid from decimal import Decimal, DecimalException from io import BytesIO +from urllib.parse import urlsplit, urlunsplit from django.core import validators from django.core.exceptions import ValidationError @@ -30,7 +31,6 @@ from django.utils.duration import duration_string from django.utils.encoding import force_str, force_text from django.utils.ipv6 import clean_ipv6_address -from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit from django.utils.translation import ugettext_lazy as _, ungettext_lazy __all__ = ( diff --git a/django/forms/forms.py b/django/forms/forms.py index c8086b1361fa..de19edb668fa 100644 --- a/django/forms/forms.py +++ b/django/forms/forms.py @@ -12,7 +12,6 @@ # pretty_name is imported for backwards compatibility in Django 1.9 from django.forms.utils import ErrorDict, ErrorList, pretty_name # NOQA from django.forms.widgets import Media, MediaDefiningClass -from django.utils import six from django.utils.encoding import force_text from django.utils.functional import cached_property from django.utils.html import conditional_escape, html_safe @@ -504,7 +503,7 @@ def get_initial_for_field(self, field, field_name): return value -class Form(six.with_metaclass(DeclarativeFieldsMetaclass, BaseForm)): +class Form(BaseForm, metaclass=DeclarativeFieldsMetaclass): "A collection of Fields, plus their associated data." # This is a separate class from BaseForm in order to abstract the way # self.fields is specified. This class (Form) is the one that does the diff --git a/django/forms/formsets.py b/django/forms/formsets.py index 60638c475c3b..964a83d4cab7 100644 --- a/django/forms/formsets.py +++ b/django/forms/formsets.py @@ -6,7 +6,6 @@ from django.utils.functional import cached_property from django.utils.html import html_safe from django.utils.safestring import mark_safe -from django.utils.six.moves import range from django.utils.translation import ugettext as _, ungettext __all__ = ('BaseFormSet', 'formset_factory', 'all_valid') diff --git a/django/forms/models.py b/django/forms/models.py index c3a1b81c8cf4..093a7a607864 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -16,7 +16,6 @@ from django.forms.widgets import ( HiddenInput, MultipleHiddenInput, SelectMultiple, ) -from django.utils import six from django.utils.encoding import force_text from django.utils.text import capfirst, get_text_list from django.utils.translation import ugettext, ugettext_lazy as _ @@ -250,7 +249,7 @@ def __new__(mcs, name, bases, attrs): opts.field_classes) # make sure opts.fields doesn't specify an invalid field - none_model_fields = [k for k, v in six.iteritems(fields) if not v] + none_model_fields = [k for k, v in fields.items() if not v] missing_fields = (set(none_model_fields) - set(new_class.declared_fields.keys())) if missing_fields: @@ -457,7 +456,7 @@ def save(self, commit=True): save.alters_data = True -class ModelForm(six.with_metaclass(ModelFormMetaclass, BaseModelForm)): +class ModelForm(BaseModelForm, metaclass=ModelFormMetaclass): pass diff --git a/django/forms/widgets.py b/django/forms/widgets.py index e21dba06077a..b04864205c4b 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -11,13 +11,12 @@ from django.conf import settings from django.forms.utils import to_current_timezone from django.templatetags.static import static -from django.utils import datetime_safe, formats, six +from django.utils import datetime_safe, formats from django.utils.dates import MONTHS from django.utils.encoding import force_str, force_text from django.utils.formats import get_format from django.utils.html import format_html, html_safe from django.utils.safestring import mark_safe -from django.utils.six.moves import range from django.utils.translation import ugettext_lazy from .renderers import get_default_renderer @@ -152,7 +151,7 @@ def __new__(mcs, name, bases, attrs): return new_class -class Widget(six.with_metaclass(MediaDefiningClass)): +class Widget(metaclass=MediaDefiningClass): needs_multipart_form = False # Determines does this widget need multipart form is_localized = False is_required = False diff --git a/django/http/cookie.py b/django/http/cookie.py index 7251d04c4079..f45ef11295ac 100644 --- a/django/http/cookie.py +++ b/django/http/cookie.py @@ -1,6 +1,5 @@ import sys - -from django.utils.six.moves import http_cookies +from http import cookies # Cookie pickling bug is fixed in Python 2.7.9 and Python 3.4.3+ # http://bugs.python.org/issue22775 @@ -10,11 +9,11 @@ ) if cookie_pickles_properly: - SimpleCookie = http_cookies.SimpleCookie + SimpleCookie = cookies.SimpleCookie else: - Morsel = http_cookies.Morsel + Morsel = cookies.Morsel - class SimpleCookie(http_cookies.SimpleCookie): + class SimpleCookie(cookies.SimpleCookie): if not cookie_pickles_properly: def __setitem__(self, key, value): # Apply the fix from http://bugs.python.org/issue22775 where @@ -41,5 +40,5 @@ def parse_cookie(cookie): key, val = key.strip(), val.strip() if key or val: # unquote using Python's algorithm. - cookiedict[key] = http_cookies._unquote(val) + cookiedict[key] = cookies._unquote(val) return cookiedict diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index b1db1f81ca44..4cbb98afddfb 100644 --- a/django/http/multipartparser.py +++ b/django/http/multipartparser.py @@ -8,6 +8,7 @@ import binascii import cgi import sys +from urllib.parse import unquote from django.conf import settings from django.core.exceptions import ( @@ -19,7 +20,6 @@ from django.utils import six from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_text -from django.utils.six.moves.urllib.parse import unquote from django.utils.text import unescape_entities __all__ = ('MultiPartParser', 'MultiPartParserError', 'InputStreamExhausted') @@ -312,7 +312,7 @@ def _close_files(self): handler.file.close() -class LazyStream(six.Iterator): +class LazyStream: """ The LazyStream wrapper allows one to get and "unget" bytes from a stream. @@ -429,7 +429,7 @@ def _update_unget_history(self, num_bytes): ) -class ChunkIter(six.Iterator): +class ChunkIter: """ An iterable that will yield chunks of data. Given a file-like object as the constructor, this object will yield chunks of read operations from that @@ -453,7 +453,7 @@ def __iter__(self): return self -class InterBoundaryIter(six.Iterator): +class InterBoundaryIter: """ A Producer that will iterate over boundaries. """ @@ -471,7 +471,7 @@ def __next__(self): raise StopIteration() -class BoundaryIter(six.Iterator): +class BoundaryIter: """ A Producer that is sensitive to boundaries. diff --git a/django/http/request.py b/django/http/request.py index fe1684ee58bd..a930c93b264f 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -3,6 +3,7 @@ import sys from io import BytesIO from itertools import chain +from urllib.parse import quote, urlencode, urljoin, urlsplit from django.conf import settings from django.core import signing @@ -17,9 +18,6 @@ escape_uri_path, force_bytes, force_str, iri_to_uri, ) from django.utils.http import is_same_domain, limited_parse_qsl -from django.utils.six.moves.urllib.parse import ( - quote, urlencode, urljoin, urlsplit, -) RAISE_ERROR = object() host_validation_re = re.compile(r"^([a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9\.:]+\])(:\d+)?$") @@ -431,14 +429,14 @@ def __delitem__(self, key): def __copy__(self): result = self.__class__('', mutable=True, encoding=self.encoding) - for key, value in six.iterlists(self): + for key, value in self.lists(): result.setlist(key, value) return result def __deepcopy__(self, memo): result = self.__class__('', mutable=True, encoding=self.encoding) memo[id(self)] = result - for key, value in six.iterlists(self): + for key, value in self.lists(): result.setlist(copy.deepcopy(key, memo), copy.deepcopy(value, memo)) return result diff --git a/django/http/response.py b/django/http/response.py index 1c2677035daf..c5294acbbdc6 100644 --- a/django/http/response.py +++ b/django/http/response.py @@ -4,20 +4,19 @@ import sys import time from email.header import Header +from http.client import responses +from urllib.parse import urlparse from django.conf import settings from django.core import signals, signing from django.core.exceptions import DisallowedRedirect from django.core.serializers.json import DjangoJSONEncoder from django.http.cookie import SimpleCookie -from django.utils import six, timezone +from django.utils import timezone from django.utils.encoding import ( force_bytes, force_str, force_text, iri_to_uri, ) from django.utils.http import cookie_date -from django.utils.six.moves import map -from django.utils.six.moves.http_client import responses -from django.utils.six.moves.urllib.parse import urlparse _charset_from_content_type_re = re.compile(r';\s*charset=(?P[^\s;]+)', re.I) @@ -26,7 +25,7 @@ class BadHeaderError(ValueError): pass -class HttpResponseBase(six.Iterator): +class HttpResponseBase: """ An HTTP response base class with dictionary-accessed headers. diff --git a/django/middleware/common.py b/django/middleware/common.py index d18d23fa4353..304e6318c457 100644 --- a/django/middleware/common.py +++ b/django/middleware/common.py @@ -1,5 +1,6 @@ import re import warnings +from urllib.parse import urlparse from django import http from django.conf import settings @@ -11,7 +12,6 @@ ) from django.utils.deprecation import MiddlewareMixin, RemovedInDjango21Warning from django.utils.encoding import force_text -from django.utils.six.moves.urllib.parse import urlparse class CommonMiddleware(MiddlewareMixin): diff --git a/django/middleware/csrf.py b/django/middleware/csrf.py index 14d3537f2915..f6584cbea8c3 100644 --- a/django/middleware/csrf.py +++ b/django/middleware/csrf.py @@ -7,6 +7,7 @@ import logging import re import string +from urllib.parse import urlparse from django.conf import settings from django.core.exceptions import ImproperlyConfigured @@ -16,8 +17,6 @@ from django.utils.deprecation import MiddlewareMixin from django.utils.encoding import force_text from django.utils.http import is_same_domain -from django.utils.six.moves import zip -from django.utils.six.moves.urllib.parse import urlparse logger = logging.getLogger('django.security.csrf') diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index 2c455aff7b6e..888d837130f5 100644 --- a/django/template/defaulttags.py +++ b/django/template/defaulttags.py @@ -7,7 +7,7 @@ from itertools import cycle as itertools_cycle, groupby from django.conf import settings -from django.utils import six, timezone +from django.utils import timezone from django.utils.encoding import force_text from django.utils.html import conditional_escape, format_html from django.utils.lorem_ipsum import paragraphs, words @@ -521,8 +521,7 @@ def __repr__(self): return "" def render(self, context): - values = {key: val.resolve(context) for key, val in - six.iteritems(self.extra_context)} + values = {key: val.resolve(context) for key, val in self.extra_context.items()} with context.push(**values): return self.nodelist.render(context) diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py index e5c44c88b08e..2c2790223860 100644 --- a/django/template/loader_tags.py +++ b/django/template/loader_tags.py @@ -3,7 +3,6 @@ import warnings from collections import defaultdict -from django.utils import six from django.utils.deprecation import RemovedInDjango21Warning from django.utils.safestring import mark_safe @@ -25,7 +24,7 @@ def __init__(self): self.blocks = defaultdict(list) def add_blocks(self, blocks): - for name, block in six.iteritems(blocks): + for name, block in blocks.items(): self.blocks[name].insert(0, block) def pop(self, name): @@ -183,7 +182,7 @@ def render(self, context): cache[template_name] = template values = { name: var.resolve(context) - for name, var in six.iteritems(self.extra_context) + for name, var in self.extra_context.items() } if self.isolated_context: return template.render(context.new(values)) diff --git a/django/templatetags/static.py b/django/templatetags/static.py index e4789bda71b0..4b25eca6a74c 100644 --- a/django/templatetags/static.py +++ b/django/templatetags/static.py @@ -1,8 +1,9 @@ +from urllib.parse import quote, urljoin + from django import template from django.apps import apps from django.utils.encoding import iri_to_uri from django.utils.html import conditional_escape -from django.utils.six.moves.urllib.parse import quote, urljoin register = template.Library() diff --git a/django/test/client.py b/django/test/client.py index 1c08ada1cfba..3b31dae9bdd6 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -6,6 +6,7 @@ from copy import copy from importlib import import_module from io import BytesIO +from urllib.parse import urljoin, urlparse, urlsplit from django.conf import settings from django.core.handlers.base import BaseHandler @@ -24,7 +25,6 @@ from django.utils.functional import SimpleLazyObject, curry from django.utils.http import urlencode from django.utils.itercompat import is_iterable -from django.utils.six.moves.urllib.parse import urljoin, urlparse, urlsplit __all__ = ('Client', 'RedirectCycleError', 'RequestFactory', 'encode_file', 'encode_multipart') diff --git a/django/test/runner.py b/django/test/runner.py index 487ec7c682f0..77a309d8e677 100644 --- a/django/test/runner.py +++ b/django/test/runner.py @@ -8,6 +8,7 @@ import unittest import warnings from importlib import import_module +from io import StringIO from django.core.management import call_command from django.db import connections @@ -18,7 +19,6 @@ ) from django.utils.datastructures import OrderedSet from django.utils.deprecation import RemovedInDjango21Warning -from django.utils.six import StringIO try: import tblib.pickling_support diff --git a/django/test/selenium.py b/django/test/selenium.py index de3744c91e73..236f7d805343 100644 --- a/django/test/selenium.py +++ b/django/test/selenium.py @@ -4,7 +4,6 @@ from django.test import LiveServerTestCase, tag from django.utils.module_loading import import_string -from django.utils.six import with_metaclass from django.utils.text import capfirst @@ -54,7 +53,7 @@ def create_webdriver(self): @tag('selenium') -class SeleniumTestCase(with_metaclass(SeleniumTestCaseBase, LiveServerTestCase)): +class SeleniumTestCase(LiveServerTestCase, metaclass=SeleniumTestCaseBase): implicit_wait = 10 @classmethod diff --git a/django/test/testcases.py b/django/test/testcases.py index 9d08940f5a12..dad3fb2df026 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -9,6 +9,8 @@ from copy import copy from functools import wraps from unittest.util import safe_repr +from urllib.parse import unquote, urljoin, urlparse, urlsplit +from urllib.request import url2pathname from django.apps import apps from django.conf import settings @@ -31,13 +33,8 @@ CaptureQueriesContext, ContextList, compare_xml, modify_settings, override_settings, ) -from django.utils import six from django.utils.decorators import classproperty from django.utils.encoding import force_text -from django.utils.six.moves.urllib.parse import ( - unquote, urljoin, urlparse, urlsplit, -) -from django.utils.six.moves.urllib.request import url2pathname from django.views.static import serve __all__ = ('TestCase', 'TransactionTestCase', @@ -921,7 +918,7 @@ def _fixture_teardown(self): inhibit_post_migrate=inhibit_post_migrate) def assertQuerysetEqual(self, qs, values, transform=repr, ordered=True, msg=None): - items = six.moves.map(transform, qs) + items = map(transform, qs) if not ordered: return self.assertEqual(Counter(items), Counter(values), msg=msg) values = list(values) diff --git a/django/test/utils.py b/django/test/utils.py index 7395396fbbb4..55428ccf853b 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -6,6 +6,7 @@ import warnings from contextlib import contextmanager from functools import wraps +from io import StringIO from types import SimpleNamespace from unittest import TestCase, skipIf, skipUnless from xml.dom.minidom import Node, parseString @@ -21,7 +22,6 @@ from django.template import Template from django.test.signals import setting_changed, template_rendered from django.urls import get_script_prefix, set_script_prefix -from django.utils import six from django.utils.decorators import available_attrs from django.utils.encoding import force_str from django.utils.translation import deactivate @@ -728,7 +728,7 @@ def captured_output(stream_name): Note: This function and the following ``captured_std*`` are copied from CPython's ``test.support`` module.""" orig_stdout = getattr(sys, stream_name) - setattr(sys, stream_name, six.StringIO()) + setattr(sys, stream_name, StringIO()) try: yield getattr(sys, stream_name) finally: @@ -840,7 +840,7 @@ class LoggingCaptureMixin(object): def setUp(self): self.logger = logging.getLogger('django') self.old_stream = self.logger.handlers[0].stream - self.logger_output = six.StringIO() + self.logger_output = StringIO() self.logger.handlers[0].stream = self.logger_output def tearDown(self): diff --git a/django/urls/base.py b/django/urls/base.py index c09eeed8f6c9..408bc36eadb5 100644 --- a/django/urls/base.py +++ b/django/urls/base.py @@ -1,8 +1,8 @@ from threading import local +from urllib.parse import urlsplit, urlunsplit from django.utils.encoding import force_text, iri_to_uri from django.utils.functional import lazy -from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit from django.utils.translation import override from .exceptions import NoReverseMatch, Resolver404 diff --git a/django/utils/_os.py b/django/utils/_os.py index ddf2132f5fe6..6507e587645d 100644 --- a/django/utils/_os.py +++ b/django/utils/_os.py @@ -5,7 +5,6 @@ from django.core.exceptions import SuspiciousFileOperation from django.utils.encoding import force_text - abspathu = abspath diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py index e7c9acbaeae1..d6a5b1a319af 100644 --- a/django/utils/autoreload.py +++ b/django/utils/autoreload.py @@ -35,12 +35,13 @@ import time import traceback +import _thread + from django.apps import apps from django.conf import settings from django.core.signals import request_finished from django.utils import six from django.utils._os import npath -from django.utils.six.moves import _thread as thread # This import does nothing, but it's necessary to avoid some race conditions # in the threading module. See http://code.djangoproject.com/ticket/2330 . @@ -293,7 +294,7 @@ def restart_with_reloader(): def python_reloader(main_func, args, kwargs): if os.environ.get("RUN_MAIN") == "true": - thread.start_new_thread(main_func, args, kwargs) + _thread.start_new_thread(main_func, args, kwargs) try: reloader_thread() except KeyboardInterrupt: @@ -311,7 +312,7 @@ def python_reloader(main_func, args, kwargs): def jython_reloader(main_func, args, kwargs): from _systemrestart import SystemRestart - thread.start_new_thread(main_func, args) + _thread.start_new_thread(main_func, args) while True: if code_changed(): raise SystemRestart diff --git a/django/utils/crypto.py b/django/utils/crypto.py index 554958b6eede..74dd9fd7b087 100644 --- a/django/utils/crypto.py +++ b/django/utils/crypto.py @@ -10,7 +10,6 @@ from django.conf import settings from django.utils.encoding import force_bytes -from django.utils.six.moves import range # Use the system PRNG if possible try: diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py index 736792460023..bb8166a73496 100644 --- a/django/utils/datastructures.py +++ b/django/utils/datastructures.py @@ -1,8 +1,6 @@ import copy from collections import OrderedDict -from django.utils import six - class OrderedSet(object): """ @@ -189,7 +187,7 @@ def items(self): def lists(self): """Yields (key, list) pairs.""" - return six.iteritems(super(MultiValueDict, self)) + return iter(super(MultiValueDict, self).items()) def values(self): """Yield the last value on every key list.""" @@ -218,7 +216,7 @@ def update(self, *args, **kwargs): self.setlistdefault(key).append(value) except TypeError: raise ValueError("MultiValueDict.update() takes either a MultiValueDict or dictionary") - for key, value in six.iteritems(kwargs): + for key, value in kwargs.items(): self.setlistdefault(key).append(value) def dict(self): diff --git a/django/utils/dateparse.py b/django/utils/dateparse.py index b2020b5281f0..d091100a0dd1 100644 --- a/django/utils/dateparse.py +++ b/django/utils/dateparse.py @@ -8,7 +8,6 @@ import datetime import re -from django.utils import six from django.utils.timezone import get_fixed_timezone, utc date_re = re.compile( @@ -60,7 +59,7 @@ def parse_date(value): """ match = date_re.match(value) if match: - kw = {k: int(v) for k, v in six.iteritems(match.groupdict())} + kw = {k: int(v) for k, v in match.groupdict().items()} return datetime.date(**kw) @@ -78,7 +77,7 @@ def parse_time(value): kw = match.groupdict() if kw['microsecond']: kw['microsecond'] = kw['microsecond'].ljust(6, '0') - kw = {k: int(v) for k, v in six.iteritems(kw) if v is not None} + kw = {k: int(v) for k, v in kw.items() if v is not None} return datetime.time(**kw) @@ -105,7 +104,7 @@ def parse_datetime(value): if tzinfo[0] == '-': offset = -offset tzinfo = get_fixed_timezone(offset) - kw = {k: int(v) for k, v in six.iteritems(kw) if v is not None} + kw = {k: int(v) for k, v in kw.items() if v is not None} kw['tzinfo'] = tzinfo return datetime.datetime(**kw) @@ -127,5 +126,5 @@ def parse_duration(value): kw['microseconds'] = kw['microseconds'].ljust(6, '0') if kw.get('seconds') and kw.get('microseconds') and kw['seconds'].startswith('-'): kw['microseconds'] = '-' + kw['microseconds'] - kw = {k: float(v) for k, v in six.iteritems(kw) if v is not None} + kw = {k: float(v) for k, v in kw.items() if v is not None} return sign * datetime.timedelta(**kw) diff --git a/django/utils/encoding.py b/django/utils/encoding.py index abd17526c615..71c2985e27eb 100644 --- a/django/utils/encoding.py +++ b/django/utils/encoding.py @@ -2,11 +2,10 @@ import datetime import locale from decimal import Decimal -from urllib.parse import unquote_to_bytes +from urllib.parse import quote, unquote_to_bytes from django.utils import six from django.utils.functional import Promise -from django.utils.six.moves.urllib.parse import quote class DjangoUnicodeDecodeError(UnicodeDecodeError): diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py index fbab58b905a8..33ef20e16bd8 100644 --- a/django/utils/feedgenerator.py +++ b/django/utils/feedgenerator.py @@ -22,11 +22,11 @@ http://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004/02/04/incompatible-rss """ import datetime +from io import StringIO +from urllib.parse import urlparse from django.utils import datetime_safe from django.utils.encoding import force_text, iri_to_uri -from django.utils.six import StringIO -from django.utils.six.moves.urllib.parse import urlparse from django.utils.timezone import utc from django.utils.xmlutils import SimplerXMLGenerator diff --git a/django/utils/functional.py b/django/utils/functional.py index 3e35582cbf31..0efce6c63550 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -2,8 +2,6 @@ import operator from functools import total_ordering, wraps -from django.utils import six - # You can't trivially replace this with `functools.partial` because this binds # to classes and returns bound instances, whereas functools.partial (on @@ -193,7 +191,7 @@ def decorator(func): @wraps(func) def wrapper(*args, **kwargs): - for arg in list(args) + list(six.itervalues(kwargs)): + for arg in list(args) + list(kwargs.values()): if isinstance(arg, Promise): break else: diff --git a/django/utils/html.py b/django/utils/html.py index 430350fed641..1fb39bb9b663 100644 --- a/django/utils/html.py +++ b/django/utils/html.py @@ -1,15 +1,14 @@ """HTML utilities suitable for global use.""" import re +from urllib.parse import ( + parse_qsl, quote, unquote, urlencode, urlsplit, urlunsplit, +) -from django.utils import six from django.utils.encoding import force_str, force_text from django.utils.functional import keep_lazy, keep_lazy_text from django.utils.http import RFC3986_GENDELIMS, RFC3986_SUBDELIMS from django.utils.safestring import SafeData, SafeText, mark_safe -from django.utils.six.moves.urllib.parse import ( - parse_qsl, quote, unquote, urlencode, urlsplit, urlunsplit, -) from django.utils.text import normalize_newlines from .html_parser import HTMLParseError, HTMLParser @@ -93,7 +92,7 @@ def format_html(format_string, *args, **kwargs): of str.format or % interpolation to build up small HTML fragments. """ args_safe = map(conditional_escape, args) - kwargs_safe = {k: conditional_escape(v) for (k, v) in six.iteritems(kwargs)} + kwargs_safe = {k: conditional_escape(v) for (k, v) in kwargs.items()} return mark_safe(format_string.format(*args_safe, **kwargs_safe)) diff --git a/django/utils/html_parser.py b/django/utils/html_parser.py index d272004f77ba..e3e19ee9c3d0 100644 --- a/django/utils/html_parser.py +++ b/django/utils/html_parser.py @@ -1,14 +1,14 @@ -from django.utils.six.moves import html_parser as _html_parser +import html.parser try: - HTMLParseError = _html_parser.HTMLParseError + HTMLParseError = html.parser.HTMLParseError except AttributeError: # create a dummy class for Python 3.5+ where it's been removed class HTMLParseError(Exception): pass -class HTMLParser(_html_parser.HTMLParser): +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 @@ -16,4 +16,4 @@ class HTMLParser(_html_parser.HTMLParser): argument. """ def __init__(self, convert_charrefs=False, **kwargs): - _html_parser.HTMLParser.__init__(self, convert_charrefs=convert_charrefs, **kwargs) + html.parser.HTMLParser.__init__(self, convert_charrefs=convert_charrefs, **kwargs) diff --git a/django/utils/http.py b/django/utils/http.py index 0308e14676a6..ae23eec06ab6 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -7,6 +7,10 @@ import warnings from binascii import Error as BinasciiError from email.utils import formatdate +from urllib.parse import ( + quote, quote_plus, unquote, unquote_plus, urlencode as original_urlencode, + urlparse, +) from django.core.exceptions import TooManyFieldsSent from django.utils import six @@ -14,10 +18,6 @@ from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_bytes, force_str, force_text from django.utils.functional import keep_lazy_text -from django.utils.six.moves.urllib.parse import ( - quote, quote_plus, unquote, unquote_plus, urlencode as original_urlencode, - urlparse, -) # based on RFC 7232, Appendix C ETAG_MATCH = re.compile(r''' diff --git a/django/utils/ipv6.py b/django/utils/ipv6.py index c41f1e2b466c..a1e63be727ea 100644 --- a/django/utils/ipv6.py +++ b/django/utils/ipv6.py @@ -4,7 +4,6 @@ import re from django.core.exceptions import ValidationError -from django.utils.six.moves import range from django.utils.translation import ugettext_lazy as _ diff --git a/django/utils/regex_helper.py b/django/utils/regex_helper.py index bc4a09b35908..f5cfc57156df 100644 --- a/django/utils/regex_helper.py +++ b/django/utils/regex_helper.py @@ -8,7 +8,6 @@ import warnings from django.utils.deprecation import RemovedInDjango21Warning -from django.utils.six.moves import zip # Mapping of an escape character to a representative of that class. So, e.g., # "\w" is replaced by "x" in a reverse URL. A value of None means to ignore diff --git a/django/utils/termcolors.py b/django/utils/termcolors.py index 87ed8c11870c..f75e068187c4 100644 --- a/django/utils/termcolors.py +++ b/django/utils/termcolors.py @@ -2,8 +2,6 @@ termcolors.py """ -from django.utils import six - color_names = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white') foreground = {color_names[x]: '3%s' % x for x in range(8)} background = {color_names[x]: '4%s' % x for x in range(8)} @@ -44,7 +42,7 @@ def colorize(text='', opts=(), **kwargs): code_list = [] if text == '' and len(opts) == 1 and opts[0] == 'reset': return '\x1b[%sm' % RESET - for k, v in six.iteritems(kwargs): + for k, v in kwargs.items(): if k == 'fg': code_list.append(foreground[v]) elif k == 'bg': diff --git a/django/utils/text.py b/django/utils/text.py index 15a9b6160a0b..d716a0b34508 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -1,15 +1,14 @@ +import html.entities import re import unicodedata from gzip import GzipFile from io import BytesIO -from django.utils import six from django.utils.encoding import force_text from django.utils.functional import ( SimpleLazyObject, keep_lazy, keep_lazy_text, lazy, ) from django.utils.safestring import SafeText, mark_safe -from django.utils.six.moves import html_entities from django.utils.translation import pgettext, ugettext as _, ugettext_lazy @@ -369,12 +368,12 @@ def _replace_entity(match): c = int(text[1:], 16) else: c = int(text) - return six.unichr(c) + return chr(c) except ValueError: return match.group(0) else: try: - return six.unichr(html_entities.name2codepoint[text]) + return chr(html.entities.name2codepoint[text]) except (ValueError, KeyError): return match.group(0) diff --git a/django/utils/translation/template.py b/django/utils/translation/template.py index b6d8832f9c35..42ff84dc2706 100644 --- a/django/utils/translation/template.py +++ b/django/utils/translation/template.py @@ -1,12 +1,12 @@ import re import warnings +from io import StringIO from django.template.base import ( TOKEN_BLOCK, TOKEN_COMMENT, TOKEN_TEXT, TOKEN_VAR, TRANSLATOR_COMMENT_MARK, Lexer, ) from django.utils.encoding import force_text -from django.utils.six import StringIO from . import TranslatorCommentWarning, trim_whitespace diff --git a/django/views/generic/base.py b/django/views/generic/base.py index 4187e70b12e2..668aef776026 100644 --- a/django/views/generic/base.py +++ b/django/views/generic/base.py @@ -5,7 +5,6 @@ from django.core.exceptions import ImproperlyConfigured from django.template.response import TemplateResponse from django.urls import NoReverseMatch, reverse -from django.utils import six from django.utils.decorators import classonlymethod logger = logging.getLogger('django.request') @@ -38,7 +37,7 @@ def __init__(self, **kwargs): """ # Go through keyword arguments, and either save their values to our # instance, or raise an error. - for key, value in six.iteritems(kwargs): + for key, value in kwargs.items(): setattr(self, key, value) @classonlymethod diff --git a/django/views/i18n.py b/django/views/i18n.py index 1fc5461b1c18..ada2624795f1 100644 --- a/django/views/i18n.py +++ b/django/views/i18n.py @@ -7,7 +7,6 @@ from django.conf import settings from django.template import Context, Engine from django.urls import translate_url -from django.utils import six from django.utils.encoding import force_text from django.utils.formats import get_format from django.utils.http import is_safe_url, urlunquote @@ -265,7 +264,7 @@ def get_catalog(self): catalog = {} trans_cat = self.translation._catalog trans_fallback_cat = self.translation._fallback._catalog if self.translation._fallback else {} - for key, value in itertools.chain(six.iteritems(trans_cat), six.iteritems(trans_fallback_cat)): + for key, value in itertools.chain(iter(trans_cat.items()), iter(trans_fallback_cat.items())): if key == '' or key in catalog: continue if isinstance(key, str): diff --git a/django/views/static.py b/django/views/static.py index bfa171357d38..a0f4bdab563b 100644 --- a/django/views/static.py +++ b/django/views/static.py @@ -7,6 +7,7 @@ import posixpath import re import stat +from urllib.parse import unquote from django.http import ( FileResponse, Http404, HttpResponse, HttpResponseNotModified, @@ -14,7 +15,6 @@ ) from django.template import Context, Engine, TemplateDoesNotExist, loader from django.utils.http import http_date, parse_http_date -from django.utils.six.moves.urllib.parse import unquote from django.utils.translation import ugettext as _, ugettext_lazy diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index e37e8a4256bd..868d04196f93 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -12,6 +12,7 @@ import sys import tempfile import unittest +from io import StringIO import django from django import conf, get_version @@ -27,7 +28,6 @@ ) from django.utils._os import npath, upath from django.utils.encoding import force_text -from django.utils.six import StringIO custom_templates_dir = os.path.join(os.path.dirname(upath(__file__)), 'custom_templates') diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py index b8d35b6d81e3..ffce2c0f34aa 100644 --- a/tests/admin_views/admin.py +++ b/tests/admin_views/admin.py @@ -1,5 +1,6 @@ import os import tempfile +from io import StringIO from wsgiref.util import FileWrapper from django import forms @@ -17,7 +18,6 @@ from django.http import HttpResponse, StreamingHttpResponse from django.utils.html import format_html from django.utils.safestring import mark_safe -from django.utils.six import StringIO from .forms import MediaActionForm from .models import ( diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index fb404e5fd268..81b7e1f6a4b9 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -3,6 +3,7 @@ import os import re import unittest +from urllib.parse import parse_qsl, urljoin, urlparse from django.contrib.admin import AdminSite, ModelAdmin from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME @@ -36,7 +37,6 @@ from django.utils.encoding import force_bytes, force_text, iri_to_uri from django.utils.html import escape from django.utils.http import urlencode -from django.utils.six.moves.urllib.parse import parse_qsl, urljoin, urlparse from . import customadmin from .admin import CityAdmin, site, site2 diff --git a/tests/aggregation_regress/tests.py b/tests/aggregation_regress/tests.py index afbc7c20b2e3..bc501fc94e58 100644 --- a/tests/aggregation_regress/tests.py +++ b/tests/aggregation_regress/tests.py @@ -12,7 +12,6 @@ ) from django.test import TestCase, skipUnlessAnyDBFeature, skipUnlessDBFeature from django.test.utils import Approximate -from django.utils import six from .models import ( Alfa, Author, Book, Bravo, Charlie, Clues, Entries, HardbackBook, ItemTag, @@ -103,7 +102,7 @@ def setUpTestData(cls): s3.books.add(cls.b3, cls.b4, cls.b6) def assertObjectAttrs(self, obj, **kwargs): - for attr, value in six.iteritems(kwargs): + for attr, value in kwargs.items(): self.assertEqual(getattr(obj, attr), value) def test_annotation_with_value(self): diff --git a/tests/auth_tests/test_deprecated_views.py b/tests/auth_tests/test_deprecated_views.py index d084f4dcef0f..d5088b9d8a1d 100644 --- a/tests/auth_tests/test_deprecated_views.py +++ b/tests/auth_tests/test_deprecated_views.py @@ -1,6 +1,7 @@ import datetime import itertools import re +from urllib.parse import ParseResult, urlparse from django.conf import settings from django.contrib.auth import SESSION_KEY @@ -14,7 +15,6 @@ from django.test.utils import ignore_warnings, patch_logger from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_text -from django.utils.six.moves.urllib.parse import ParseResult, urlparse from .models import CustomUser, UUIDUser from .settings import AUTH_TEMPLATES diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 9335b75dba2e..4fd1563f84e8 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -1,5 +1,7 @@ +import builtins import sys from datetime import date +from io import StringIO from django.apps import apps from django.contrib.auth import management @@ -13,7 +15,6 @@ from django.core.management.base import CommandError from django.db import migrations from django.test import TestCase, mock, override_settings -from django.utils import six from django.utils.encoding import force_str from django.utils.translation import ugettext_lazy as _ @@ -49,14 +50,14 @@ def mock_input(prompt): return response old_getpass = createsuperuser.getpass - old_input = createsuperuser.input + old_input = builtins.input createsuperuser.getpass = mock_getpass - createsuperuser.input = mock_input + builtins.input = mock_input try: test_func(*args) finally: createsuperuser.getpass = old_getpass - createsuperuser.input = old_input + builtins.input = old_input return wrapped return inner @@ -105,8 +106,8 @@ class ChangepasswordManagementCommandTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='joe', password='qwerty') - self.stdout = six.StringIO() - self.stderr = six.StringIO() + self.stdout = StringIO() + self.stderr = StringIO() def tearDown(self): self.stdout.close() @@ -168,7 +169,7 @@ def test_that_changepassword_command_with_database_option_uses_given_db(self, mo user = User.objects.db_manager('other').create_user(username='joe', password='qwerty') self.assertTrue(user.check_password('qwerty')) - out = six.StringIO() + out = StringIO() call_command('changepassword', username='joe', database='other', stdout=out) command_output = out.getvalue().strip() @@ -188,7 +189,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): def test_basic_usage(self): "Check the operation of the createsuperuser management command" # We can use the management command to create a superuser - new_io = six.StringIO() + new_io = StringIO() call_command( "createsuperuser", interactive=False, @@ -212,7 +213,7 @@ def test_non_ascii_verbose_name(self): username_field = User._meta.get_field('username') old_verbose_name = username_field.verbose_name username_field.verbose_name = _('u\u017eivatel') - new_io = six.StringIO() + new_io = StringIO() try: call_command( "createsuperuser", @@ -228,7 +229,7 @@ def test_non_ascii_verbose_name(self): def test_verbosity_zero(self): # We can suppress output on the management command - new_io = six.StringIO() + new_io = StringIO() call_command( "createsuperuser", interactive=False, @@ -244,7 +245,7 @@ def test_verbosity_zero(self): self.assertFalse(u.has_usable_password()) def test_email_in_username(self): - new_io = six.StringIO() + new_io = StringIO() call_command( "createsuperuser", interactive=False, @@ -262,7 +263,7 @@ def test_swappable_user(self): # We can use the management command to create a superuser # We skip validation because the temporary substitution of the # swappable User model messes with validation. - new_io = six.StringIO() + new_io = StringIO() call_command( "createsuperuser", interactive=False, @@ -284,7 +285,7 @@ def test_swappable_user_missing_required_field(self): # We can use the management command to create a superuser # We skip validation because the temporary substitution of the # swappable User model messes with validation. - new_io = six.StringIO() + new_io = StringIO() with self.assertRaises(CommandError): call_command( "createsuperuser", @@ -306,7 +307,7 @@ def test_swappable_user_username_non_unique(self): 'password': 'nopasswd', }) def createsuperuser(): - new_io = six.StringIO() + new_io = StringIO() call_command( "createsuperuser", interactive=True, @@ -333,7 +334,7 @@ class FakeStdin(object): def isatty(self): return False - out = six.StringIO() + out = StringIO() call_command( "createsuperuser", stdin=FakeStdin(), @@ -355,8 +356,8 @@ def test_passing_stdin(self): call_command( command, stdin=sentinel, - stdout=six.StringIO(), - stderr=six.StringIO(), + stdout=StringIO(), + stderr=StringIO(), interactive=False, verbosity=0, username='janet', @@ -367,8 +368,8 @@ def test_passing_stdin(self): command = createsuperuser.Command() call_command( command, - stdout=six.StringIO(), - stderr=six.StringIO(), + stdout=StringIO(), + stderr=StringIO(), interactive=False, verbosity=0, username='joe', @@ -378,7 +379,7 @@ def test_passing_stdin(self): @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserWithFK') def test_fields_with_fk(self): - new_io = six.StringIO() + new_io = StringIO() group = Group.objects.create(name='mygroup') email = Email.objects.create(email='mymail@gmail.com') call_command( @@ -408,7 +409,7 @@ def test_fields_with_fk(self): @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserWithFK') def test_fields_with_fk_interactive(self): - new_io = six.StringIO() + new_io = StringIO() group = Group.objects.create(name='mygroup') email = Email.objects.create(email='mymail@gmail.com') @@ -438,7 +439,7 @@ def test_password_validation(self): """ Creation should fail if the password fails validation. """ - new_io = six.StringIO() + new_io = StringIO() # Returns '1234567890' the first two times it is called, then # 'password' subsequently. @@ -472,7 +473,7 @@ def test_validation_mismatched_passwords(self): """ Creation should fail if the user enters mismatched passwords. """ - new_io = six.StringIO() + new_io = StringIO() # The first two passwords do not match, but the second two do match and # are valid. @@ -505,7 +506,7 @@ def test_validation_blank_password_entered(self): """ Creation should fail if the user enters blank passwords. """ - new_io = six.StringIO() + new_io = StringIO() # The first two passwords are empty strings, but the second two are # valid. @@ -542,7 +543,7 @@ def test_createsuperuser_command_with_database_option(self): """ changepassword --database should operate on the specified DB. """ - new_io = six.StringIO() + new_io = StringIO() call_command( 'createsuperuser', interactive=False, diff --git a/tests/auth_tests/test_views.py b/tests/auth_tests/test_views.py index f25080092101..dd87a5bf00c7 100644 --- a/tests/auth_tests/test_views.py +++ b/tests/auth_tests/test_views.py @@ -3,6 +3,7 @@ import os import re from importlib import import_module +from urllib.parse import ParseResult, urlparse from django.apps import apps from django.conf import settings @@ -28,7 +29,6 @@ from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_text from django.utils.http import urlquote -from django.utils.six.moves.urllib.parse import ParseResult, urlparse from django.utils.translation import LANGUAGE_SESSION_KEY from .client import PasswordResetConfirmClient diff --git a/tests/backends/tests.py b/tests/backends/tests.py index a7939ed8beb7..89afb20760bb 100644 --- a/tests/backends/tests.py +++ b/tests/backends/tests.py @@ -23,7 +23,6 @@ SimpleTestCase, TestCase, TransactionTestCase, mock, override_settings, skipIfDBFeature, skipUnlessDBFeature, ) -from django.utils.six.moves import range from .models import ( Article, Item, Object, ObjectReference, Person, Post, RawData, Reporter, diff --git a/tests/base/models.py b/tests/base/models.py index fb915227177a..b179878704e0 100644 --- a/tests/base/models.py +++ b/tests/base/models.py @@ -1,5 +1,4 @@ from django.db import models -from django.utils import six # The models definitions below used to crash. Generating models dynamically @@ -11,5 +10,5 @@ class CustomBaseModel(models.base.ModelBase): pass -class MyModel(six.with_metaclass(CustomBaseModel, models.Model)): - """Model subclass with a custom base using six.with_metaclass.""" +class MyModel(models.Model, metaclass=CustomBaseModel): + """Model subclass with a custom base using metaclass.""" diff --git a/tests/cache/tests.py b/tests/cache/tests.py index caeb8a47dfc5..3bf39e247682 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -3,6 +3,7 @@ import copy import io import os +import pickle import re import shutil import tempfile @@ -33,7 +34,7 @@ ignore_warnings, mock, override_settings, ) from django.test.signals import setting_changed -from django.utils import six, timezone, translation +from django.utils import timezone, translation from django.utils.cache import ( get_cache_key, learn_cache_key, patch_cache_control, patch_response_headers, patch_vary_headers, @@ -44,11 +45,6 @@ from .models import Poll, expensive_calculation -try: # Use the same idiom as in cache backends - from django.utils.six.moves import cPickle as pickle -except ImportError: - import pickle - # functions/classes for complex data type tests def f(): @@ -978,7 +974,7 @@ def test_zero_cull(self): self._perform_cull_test(caches['zero_cull'], 50, 18) def test_second_call_doesnt_crash(self): - out = six.StringIO() + out = io.StringIO() management.call_command('createcachetable', stdout=out) self.assertEqual(out.getvalue(), "Cache table 'test cache table' already exists.\n" * len(settings.CACHES)) @@ -988,7 +984,7 @@ def test_second_call_doesnt_crash(self): LOCATION='createcachetable_dry_run_mode' )) def test_createcachetable_dry_run_mode(self): - out = six.StringIO() + out = io.StringIO() management.call_command('createcachetable', dry_run=True, stdout=out) output = out.getvalue() self.assertTrue(output.startswith("CREATE TABLE")) @@ -999,7 +995,7 @@ def test_createcachetable_with_table_argument(self): specifying the table name). """ self.drop_table() - out = six.StringIO() + out = io.StringIO() management.call_command( 'createcachetable', 'test cache table', diff --git a/tests/check_framework/tests.py b/tests/check_framework/tests.py index 0e82c10b456d..30e1353dc08a 100644 --- a/tests/check_framework/tests.py +++ b/tests/check_framework/tests.py @@ -1,4 +1,5 @@ import sys +from io import StringIO from django.apps import apps from django.core import checks @@ -12,7 +13,6 @@ isolate_apps, override_settings, override_system_checks, ) from django.utils.encoding import force_text -from django.utils.six import StringIO from .models import SimpleModel, my_check diff --git a/tests/contenttypes_tests/tests.py b/tests/contenttypes_tests/tests.py index a46c9f336578..c91c265eaff1 100644 --- a/tests/contenttypes_tests/tests.py +++ b/tests/contenttypes_tests/tests.py @@ -390,10 +390,7 @@ def test_interactive_true_with_dependent_objects(self): # A related object is needed to show that a custom collector with # can_fast_delete=False is needed. ModelWithNullFKToSite.objects.create(post=post) - with mock.patch( - 'django.contrib.contenttypes.management.commands.remove_stale_contenttypes.input', - return_value='yes' - ): + with mock.patch('builtins.input', return_value='yes'): with captured_stdout() as stdout: call_command('remove_stale_contenttypes', verbosity=2, stdout=stdout) self.assertEqual(Post.objects.count(), 0) @@ -409,10 +406,7 @@ def test_interactive_true_without_dependent_objects(self): interactive mode of remove_stale_contenttypes (the default) should delete stale contenttypes even if there aren't any dependent objects. """ - with mock.patch( - 'django.contrib.contenttypes.management.commands.remove_stale_contenttypes.input', - return_value='yes' - ): + with mock.patch('builtins.input', return_value='yes'): with captured_stdout() as stdout: call_command('remove_stale_contenttypes', verbosity=2) self.assertIn("Deleting stale content type", stdout.getvalue()) diff --git a/tests/db_typecasts/tests.py b/tests/db_typecasts/tests.py index fa9eab164d4c..56d37c112d97 100644 --- a/tests/db_typecasts/tests.py +++ b/tests/db_typecasts/tests.py @@ -4,7 +4,6 @@ import unittest from django.db.backends import utils as typecasts -from django.utils import six TEST_CASES = { 'typecast_date': ( @@ -53,7 +52,7 @@ class DBTypeCasts(unittest.TestCase): def test_typeCasts(self): - for k, v in six.iteritems(TEST_CASES): + for k, v in TEST_CASES.items(): for inpt, expected in v: got = getattr(typecasts, k)(inpt) self.assertEqual( diff --git a/tests/delete/tests.py b/tests/delete/tests.py index 640dfabf4b5d..5abae7622ee4 100644 --- a/tests/delete/tests.py +++ b/tests/delete/tests.py @@ -3,7 +3,6 @@ from django.db import IntegrityError, connection, models from django.db.models.sql.constants import GET_ITERATOR_CHUNK_SIZE from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature -from django.utils.six.moves import range from .models import ( MR, A, Avatar, Base, Child, HiddenUser, HiddenUserProfile, M, M2MFrom, diff --git a/tests/deprecation/tests.py b/tests/deprecation/tests.py index 34056b663b4f..5c2361f7a047 100644 --- a/tests/deprecation/tests.py +++ b/tests/deprecation/tests.py @@ -2,7 +2,6 @@ from django.test import SimpleTestCase from django.test.utils import reset_warning_registry -from django.utils import six from django.utils.deprecation import ( DeprecationInstanceCheck, RemovedInNextVersionWarning, RenameMethodsBase, ) @@ -29,7 +28,7 @@ def test_class_definition_warnings(self): with warnings.catch_warnings(record=True) as recorded: warnings.simplefilter('always') - class Manager(six.with_metaclass(RenameManagerMethods)): + class Manager(metaclass=RenameManagerMethods): def old(self): pass self.assertEqual(len(recorded), 1) @@ -43,7 +42,7 @@ def test_get_new_defined(self): with warnings.catch_warnings(record=True) as recorded: warnings.simplefilter('ignore') - class Manager(six.with_metaclass(RenameManagerMethods)): + class Manager(metaclass=RenameManagerMethods): def new(self): pass warnings.simplefilter('always') @@ -62,7 +61,7 @@ def test_get_old_defined(self): with warnings.catch_warnings(record=True) as recorded: warnings.simplefilter('ignore') - class Manager(six.with_metaclass(RenameManagerMethods)): + class Manager(metaclass=RenameManagerMethods): def old(self): pass warnings.simplefilter('always') @@ -82,7 +81,7 @@ def test_deprecated_subclass_renamed(self): with warnings.catch_warnings(record=True) as recorded: warnings.simplefilter('ignore') - class Renamed(six.with_metaclass(RenameManagerMethods)): + class Renamed(metaclass=RenameManagerMethods): def new(self): pass @@ -112,7 +111,7 @@ def test_renamed_subclass_deprecated(self): with warnings.catch_warnings(record=True) as recorded: warnings.simplefilter('ignore') - class Deprecated(six.with_metaclass(RenameManagerMethods)): + class Deprecated(metaclass=RenameManagerMethods): def old(self): pass @@ -137,7 +136,7 @@ class that renamed `old` and mixins that may or may not have renamed with warnings.catch_warnings(record=True) as recorded: warnings.simplefilter('ignore') - class Renamed(six.with_metaclass(RenameManagerMethods)): + class Renamed(metaclass=RenameManagerMethods): def new(self): pass @@ -168,7 +167,7 @@ class Deprecated(DeprecatedMixin, RenamedMixin, Renamed): class DeprecationInstanceCheckTest(SimpleTestCase): def test_warning(self): - class Manager(six.with_metaclass(DeprecationInstanceCheck)): + class Manager(metaclass=DeprecationInstanceCheck): alternative = 'fake.path.Foo' deprecation_warning = RemovedInNextVersionWarning diff --git a/tests/file_storage/tests.py b/tests/file_storage/tests.py index d02b6e2dbcc1..5aee127c8c77 100644 --- a/tests/file_storage/tests.py +++ b/tests/file_storage/tests.py @@ -7,6 +7,8 @@ import time import unittest from datetime import datetime, timedelta +from io import StringIO +from urllib.request import urlopen from django.core.cache import cache from django.core.exceptions import SuspiciousFileOperation, SuspiciousOperation @@ -21,9 +23,8 @@ ) from django.test.utils import requires_tz_support from django.urls import NoReverseMatch, reverse_lazy -from django.utils import six, timezone +from django.utils import timezone from django.utils._os import upath -from django.utils.six.moves.urllib.request import urlopen from .models import Storage, temp_storage, temp_storage_location @@ -301,7 +302,7 @@ def test_save_doesnt_close(self): self.assertFalse(file.closed) self.assertFalse(file.file.closed) - file = InMemoryUploadedFile(six.StringIO('1'), '', 'test', 'text/plain', 1, 'utf8') + file = InMemoryUploadedFile(StringIO('1'), '', 'test', 'text/plain', 1, 'utf8') with file: self.assertFalse(file.closed) self.storage.save('path/to/test.file', file) @@ -578,7 +579,7 @@ def test_custom_storage_discarding_empty_content(self): When Storage.save() wraps a file-like object in File, it should include the name argument so that bool(file) evaluates to True (#26495). """ - output = six.StringIO('content') + output = StringIO('content') self.storage.save('tests/stringio', output) self.assertTrue(self.storage.exists('tests/stringio')) @@ -788,7 +789,7 @@ def test_file_object(self): def test_stringio(self): # Test passing StringIO instance as content argument to save - output = six.StringIO() + output = StringIO() output.write('content') output.seek(0) diff --git a/tests/file_uploads/tests.py b/tests/file_uploads/tests.py index f9cecf96a20a..c7315ae14216 100644 --- a/tests/file_uploads/tests.py +++ b/tests/file_uploads/tests.py @@ -7,7 +7,7 @@ import sys import tempfile as sys_tempfile import unittest -from io import BytesIO +from io import BytesIO, StringIO from django.core.files import temp as tempfile from django.core.files.uploadedfile import SimpleUploadedFile @@ -15,7 +15,6 @@ from django.test import SimpleTestCase, TestCase, client, override_settings from django.utils.encoding import force_bytes from django.utils.http import urlquote -from django.utils.six import StringIO from . import uploadhandler from .models import FileModel diff --git a/tests/fixtures/tests.py b/tests/fixtures/tests.py index df5067e2231c..51d8eef51b43 100644 --- a/tests/fixtures/tests.py +++ b/tests/fixtures/tests.py @@ -3,6 +3,7 @@ import tempfile import unittest import warnings +from io import StringIO from django.apps import apps from django.contrib.sites.models import Site @@ -15,7 +16,6 @@ from django.test import ( TestCase, TransactionTestCase, mock, skipUnlessDBFeature, ) -from django.utils import six from django.utils.encoding import force_text from .models import ( @@ -52,7 +52,7 @@ class DumpDataAssertMixin(object): def _dumpdata_assert(self, args, output, format='json', filename=None, natural_foreign_keys=False, natural_primary_keys=False, use_base_manager=False, exclude_list=[], primary_keys=''): - new_io = six.StringIO() + new_io = StringIO() if filename: filename = os.path.join(tempfile.gettempdir(), filename) management.call_command('dumpdata', *args, **{'format': format, @@ -445,7 +445,7 @@ def test_dumpdata_with_pks(self): def test_dumpdata_with_uuid_pks(self): m1 = PrimaryKeyUUIDModel.objects.create() m2 = PrimaryKeyUUIDModel.objects.create() - output = six.StringIO() + output = StringIO() management.call_command( 'dumpdata', 'fixtures.PrimaryKeyUUIDModel', '--pks', ', '.join([str(m1.id), str(m2.id)]), stdout=output, @@ -471,7 +471,7 @@ def test_dumpdata_progressbar(self): stdout is a tty, and verbosity > 0. """ management.call_command('loaddata', 'fixture1.json', verbosity=0) - new_io = six.StringIO() + new_io = StringIO() new_io.isatty = lambda: True with NamedTemporaryFile() as file: options = { @@ -485,7 +485,7 @@ def test_dumpdata_progressbar(self): # Test no progress bar when verbosity = 0 options['verbosity'] = 0 - new_io = six.StringIO() + new_io = StringIO() new_io.isatty = lambda: True options.update({'stdout': new_io, 'stderr': new_io}) management.call_command('dumpdata', 'fixtures', **options) @@ -583,7 +583,7 @@ def test_loaddata_app_option(self): ]) def test_loaddata_verbosity_three(self): - output = six.StringIO() + output = StringIO() management.call_command('loaddata', 'fixture1.json', verbosity=3, stdout=output, stderr=output) command_output = force_text(output.getvalue()) self.assertIn( @@ -689,7 +689,7 @@ class NonExistentFixtureTests(TestCase): """ def test_loaddata_not_existent_fixture_file(self): - stdout_output = six.StringIO() + stdout_output = StringIO() with self.assertRaisesMessage(CommandError, "No fixture named 'this_fixture_doesnt_exist' found."): management.call_command('loaddata', 'this_fixture_doesnt_exist', stdout=stdout_output) diff --git a/tests/fixtures_regress/tests.py b/tests/fixtures_regress/tests.py index 7ea9e6cc3ebd..a3ac7f597762 100644 --- a/tests/fixtures_regress/tests.py +++ b/tests/fixtures_regress/tests.py @@ -3,6 +3,7 @@ import os import re import warnings +from io import StringIO from django.core import management, serializers from django.core.exceptions import ImproperlyConfigured @@ -14,7 +15,6 @@ skipUnlessDBFeature, ) from django.utils._os import upath -from django.utils.six import StringIO from .models import ( Absolute, Animal, Article, Book, Child, Circle1, Circle2, Circle3, diff --git a/tests/gis_tests/gdal_tests/test_geom.py b/tests/gis_tests/gdal_tests/test_geom.py index bc8219772cf5..4498ce7111e9 100644 --- a/tests/gis_tests/gdal_tests/test_geom.py +++ b/tests/gis_tests/gdal_tests/test_geom.py @@ -1,19 +1,13 @@ import json +import pickle import unittest from binascii import b2a_hex from unittest import skipUnless from django.contrib.gis.gdal import HAS_GDAL -from django.utils.six.moves import range from ..test_data import TestDataMixin -try: - from django.utils.six.moves import cPickle as pickle -except ImportError: - import pickle - - if HAS_GDAL: from django.contrib.gis.gdal import ( CoordTransform, GDALException, OGRGeometry, OGRGeomType, OGRIndexError, diff --git a/tests/gis_tests/gdal_tests/test_raster.py b/tests/gis_tests/gdal_tests/test_raster.py index 8649e9f23118..1a2753c7171d 100644 --- a/tests/gis_tests/gdal_tests/test_raster.py +++ b/tests/gis_tests/gdal_tests/test_raster.py @@ -49,7 +49,6 @@ from django.contrib.gis.gdal.error import GDALException from django.contrib.gis.shortcuts import numpy from django.test import SimpleTestCase -from django.utils import six from django.utils._os import upath from ..data.rasters.textrasters import JSON_RASTER @@ -505,7 +504,7 @@ def test_band_data_setters(self): self.assertEqual(result, block) # Set data from memoryview - bandmem.data(six.memoryview(packed_block), (1, 1), (2, 2)) + bandmem.data(memoryview(packed_block), (1, 1), (2, 2)) result = bandmem.data(offset=(1, 1), size=(2, 2)) if numpy: numpy.testing.assert_equal(result, numpy.array(block).reshape(2, 2)) diff --git a/tests/gis_tests/geoapp/tests.py b/tests/gis_tests/geoapp/tests.py index 4324364c0da9..bfb84c680005 100644 --- a/tests/gis_tests/geoapp/tests.py +++ b/tests/gis_tests/geoapp/tests.py @@ -1,4 +1,5 @@ import tempfile +from io import StringIO from django.contrib.gis import gdal from django.contrib.gis.db.models import Extent, MakeLine, Union, functions @@ -9,7 +10,6 @@ from django.core.management import call_command from django.db import connection from django.test import TestCase, skipUnlessDBFeature -from django.utils import six from ..utils import no_oracle, oracle, postgis, skipUnlessGISLookup, spatialite from .models import ( @@ -184,7 +184,7 @@ def test_dumpdata_loaddata_cycle(self): """ Test a dumpdata/loaddata cycle with geographic data. """ - out = six.StringIO() + out = StringIO() original_data = list(City.objects.all().order_by('name')) call_command('dumpdata', 'geoapp.City', stdout=out) result = out.getvalue() diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index 7877e1f2d61e..f7024e790e15 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -1,5 +1,6 @@ import ctypes import json +import pickle import random from binascii import a2b_hex, b2a_hex from io import BytesIO @@ -18,7 +19,6 @@ from django.template.engine import Engine from django.test import SimpleTestCase, mock from django.utils.encoding import force_bytes -from django.utils.six.moves import range from ..test_data import TestDataMixin @@ -1100,10 +1100,6 @@ def test_extent(self): def test_pickle(self): "Testing pickling and unpickling support." - # Using both pickle and cPickle -- just 'cause. - from django.utils.six.moves import cPickle - import pickle - # Creating a list of test geometries for pickling, # and setting the SRID on some of them. def get_geoms(lst, srid=None): @@ -1114,11 +1110,10 @@ def get_geoms(lst, srid=None): tgeoms.extend(get_geoms(self.geometries.multipolygons, 3857)) for geom in tgeoms: - s1, s2 = cPickle.dumps(geom), pickle.dumps(geom) - g1, g2 = cPickle.loads(s1), pickle.loads(s2) - for tmpg in (g1, g2): - self.assertEqual(geom, tmpg) - self.assertEqual(geom.srid, tmpg.srid) + s1 = pickle.dumps(geom) + g1 = pickle.loads(s1) + self.assertEqual(geom, g1) + self.assertEqual(geom.srid, g1.srid) def test_prepared(self): "Testing PreparedGeometry support." diff --git a/tests/gis_tests/inspectapp/tests.py b/tests/gis_tests/inspectapp/tests.py index b451603e7ce1..43cf2c2d66e1 100644 --- a/tests/gis_tests/inspectapp/tests.py +++ b/tests/gis_tests/inspectapp/tests.py @@ -1,12 +1,12 @@ import os import re +from io import StringIO from django.contrib.gis.gdal import HAS_GDAL from django.core.management import call_command from django.db import connection, connections from django.test import TestCase, skipUnlessDBFeature from django.test.utils import modify_settings -from django.utils.six import StringIO from ..test_data import TEST_DATA from ..utils import postgis diff --git a/tests/gis_tests/test_data.py b/tests/gis_tests/test_data.py index 7092bd27b114..9e31b5a599b6 100644 --- a/tests/gis_tests/test_data.py +++ b/tests/gis_tests/test_data.py @@ -5,7 +5,6 @@ import json import os -from django.utils import six from django.utils._os import upath from django.utils.functional import cached_property @@ -22,7 +21,7 @@ def tuplize(seq): def strconvert(d): "Converts all keys in dictionary to str type." - return {str(k): v for k, v in six.iteritems(d)} + return {str(k): v for k, v in d.items()} def get_ds_file(name, ext): diff --git a/tests/httpwrappers/tests.py b/tests/httpwrappers/tests.py index b8d359de4154..a4ea614175da 100644 --- a/tests/httpwrappers/tests.py +++ b/tests/httpwrappers/tests.py @@ -16,7 +16,6 @@ StreamingHttpResponse, parse_cookie, ) from django.test import SimpleTestCase -from django.utils import six from django.utils._os import upath from django.utils.encoding import force_str from django.utils.functional import lazystr @@ -56,10 +55,10 @@ def test_immutable_basic_operations(self): q = QueryDict() self.assertEqual(q.getlist('foo'), []) self.assertNotIn('foo', q) - self.assertEqual(list(six.iteritems(q)), []) - self.assertEqual(list(six.iterlists(q)), []) - self.assertEqual(list(six.iterkeys(q)), []) - self.assertEqual(list(six.itervalues(q)), []) + self.assertEqual(list(q.items()), []) + self.assertEqual(list(q.lists()), []) + self.assertEqual(list(q.keys()), []) + self.assertEqual(list(q.values()), []) self.assertEqual(len(q), 0) self.assertEqual(q.urlencode(), '') @@ -86,10 +85,10 @@ def test_single_key_value(self): self.assertIn('foo', q) self.assertNotIn('bar', q) - self.assertEqual(list(six.iteritems(q)), [('foo', 'bar')]) - self.assertEqual(list(six.iterlists(q)), [('foo', ['bar'])]) - self.assertEqual(list(six.iterkeys(q)), ['foo']) - self.assertEqual(list(six.itervalues(q)), ['bar']) + self.assertEqual(list(q.items()), [('foo', 'bar')]) + self.assertEqual(list(q.lists()), [('foo', ['bar'])]) + self.assertEqual(list(q.keys()), ['foo']) + self.assertEqual(list(q.values()), ['bar']) self.assertEqual(len(q), 1) with self.assertRaises(AttributeError): @@ -146,14 +145,10 @@ def test_basic_mutable_operations(self): self.assertEqual(q['foo'], 'another') self.assertIn('foo', q) - self.assertListEqual(sorted(six.iteritems(q)), - [('foo', 'another'), ('name', 'john')]) - self.assertListEqual(sorted(six.iterlists(q)), - [('foo', ['bar', 'baz', 'another']), ('name', ['john'])]) - self.assertListEqual(sorted(six.iterkeys(q)), - ['foo', 'name']) - self.assertListEqual(sorted(six.itervalues(q)), - ['another', 'john']) + self.assertListEqual(sorted(q.items()), [('foo', 'another'), ('name', 'john')]) + self.assertListEqual(sorted(q.lists()), [('foo', ['bar', 'baz', 'another']), ('name', ['john'])]) + self.assertListEqual(sorted(q.keys()), ['foo', 'name']) + self.assertListEqual(sorted(q.values()), ['another', 'john']) q.update({'foo': 'hello'}) self.assertEqual(q['foo'], 'hello') @@ -193,10 +188,10 @@ def test_multiple_keys(self): self.assertIn('vote', q) self.assertNotIn('foo', q) - self.assertEqual(list(six.iteritems(q)), [('vote', 'no')]) - self.assertEqual(list(six.iterlists(q)), [('vote', ['yes', 'no'])]) - self.assertEqual(list(six.iterkeys(q)), ['vote']) - self.assertEqual(list(six.itervalues(q)), ['no']) + self.assertEqual(list(q.items()), [('vote', 'no')]) + self.assertEqual(list(q.lists()), [('vote', ['yes', 'no'])]) + self.assertEqual(list(q.keys()), ['vote']) + self.assertEqual(list(q.values()), ['no']) self.assertEqual(len(q), 1) with self.assertRaises(AttributeError): @@ -234,11 +229,11 @@ def test_non_default_encoding(self): """#13572 - QueryDict with a non-default encoding""" q = QueryDict(str('cur=%A4'), encoding='iso-8859-15') self.assertEqual(q.encoding, 'iso-8859-15') - self.assertEqual(list(six.iteritems(q)), [('cur', '€')]) + self.assertEqual(list(q.items()), [('cur', '€')]) self.assertEqual(q.urlencode(), 'cur=%A4') q = q.copy() self.assertEqual(q.encoding, 'iso-8859-15') - self.assertEqual(list(six.iteritems(q)), [('cur', '€')]) + self.assertEqual(list(q.items()), [('cur', '€')]) self.assertEqual(q.urlencode(), 'cur=%A4') self.assertEqual(copy.copy(q).encoding, 'iso-8859-15') self.assertEqual(copy.deepcopy(q).encoding, 'iso-8859-15') diff --git a/tests/i18n/test_compilation.py b/tests/i18n/test_compilation.py index 3f3bf773bff3..159b6d91ec62 100644 --- a/tests/i18n/test_compilation.py +++ b/tests/i18n/test_compilation.py @@ -2,6 +2,7 @@ import os import stat import unittest +from io import StringIO from subprocess import Popen from django.core.management import ( @@ -14,7 +15,6 @@ from django.test.utils import captured_stderr, captured_stdout from django.utils import translation from django.utils.encoding import force_text -from django.utils.six import StringIO from django.utils.translation import ugettext from .utils import RunInTmpDirMixin, copytree diff --git a/tests/i18n/test_extraction.py b/tests/i18n/test_extraction.py index b8342865a9ab..aaa2a4e8b582 100644 --- a/tests/i18n/test_extraction.py +++ b/tests/i18n/test_extraction.py @@ -4,6 +4,7 @@ import shutil import time import warnings +from io import StringIO from unittest import skipUnless from admin_scripts.tests import AdminScriptTestCase @@ -17,7 +18,6 @@ from django.test import SimpleTestCase, mock, override_settings from django.test.utils import captured_stderr, captured_stdout from django.utils.encoding import force_text -from django.utils.six import StringIO from django.utils.translation import TranslatorCommentWarning from .utils import POFileAssertionMixin, RunInTmpDirMixin, copytree diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py index 8f17735929da..ef26233342ff 100644 --- a/tests/inspectdb/tests.py +++ b/tests/inspectdb/tests.py @@ -1,11 +1,11 @@ import re +from io import StringIO from unittest import skipUnless from django.core.management import call_command from django.db import connection from django.test import TestCase, mock, skipUnlessDBFeature from django.utils.encoding import force_text -from django.utils.six import StringIO from .models import ColumnTypes diff --git a/tests/logging_tests/tests.py b/tests/logging_tests/tests.py index 134cc7180884..a91bcd66bfe4 100644 --- a/tests/logging_tests/tests.py +++ b/tests/logging_tests/tests.py @@ -1,5 +1,6 @@ import logging from contextlib import contextmanager +from io import StringIO from admin_scripts.tests import AdminScriptTestCase @@ -10,7 +11,6 @@ from django.db import connection from django.test import RequestFactory, SimpleTestCase, override_settings from django.test.utils import LoggingCaptureMixin, patch_logger -from django.utils import six from django.utils.log import ( DEFAULT_LOGGING, AdminEmailHandler, CallbackFilter, RequireDebugFalse, RequireDebugTrue, ServerFormatter, @@ -513,7 +513,7 @@ def test_server_formatter_default_format(self): @contextmanager def patch_django_server_logger(): old_stream = logger.handlers[0].stream - new_stream = six.StringIO() + new_stream = StringIO() logger.handlers[0].stream = new_stream yield new_stream logger.handlers[0].stream = old_stream diff --git a/tests/m2m_through_regress/tests.py b/tests/m2m_through_regress/tests.py index a1739f296023..64be4252bd11 100644 --- a/tests/m2m_through_regress/tests.py +++ b/tests/m2m_through_regress/tests.py @@ -1,7 +1,8 @@ +from io import StringIO + from django.contrib.auth.models import User from django.core import management from django.test import TestCase -from django.utils.six import StringIO from .models import ( Car, CarDriver, Driver, Group, Membership, Person, UserMembership, diff --git a/tests/mail/tests.py b/tests/mail/tests.py index 7c2cd8342a83..77ea87fe7d4e 100644 --- a/tests/mail/tests.py +++ b/tests/mail/tests.py @@ -12,6 +12,7 @@ from email.header import Header from email.mime.text import MIMEText from email.utils import parseaddr +from io import StringIO from smtplib import SMTP, SMTPAuthenticationError, SMTPException from ssl import SSLError @@ -26,7 +27,6 @@ from django.test.utils import requires_tz_support from django.utils._os import upath from django.utils.encoding import force_bytes, force_text -from django.utils.six import StringIO from django.utils.translation import ugettext_lazy diff --git a/tests/middleware/tests.py b/tests/middleware/tests.py index 3c0d3d81ea73..8749a9ee501e 100644 --- a/tests/middleware/tests.py +++ b/tests/middleware/tests.py @@ -1,7 +1,9 @@ import gzip import random import re +import struct from io import BytesIO +from urllib.parse import quote from django.conf import settings from django.core import mail @@ -19,11 +21,10 @@ from django.test import ( RequestFactory, SimpleTestCase, ignore_warnings, override_settings, ) -from django.utils import six from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_str -from django.utils.six.moves import range -from django.utils.six.moves.urllib.parse import quote + +int2byte = struct.Struct(">B").pack @override_settings(ROOT_URLCONF='middleware.urls') @@ -732,7 +733,7 @@ class GZipMiddlewareTest(SimpleTestCase): """ short_string = b"This string is too short to be worth compressing." compressible_string = b'a' * 500 - incompressible_string = b''.join(six.int2byte(random.randint(0, 255)) for _ in range(500)) + incompressible_string = b''.join(int2byte(random.randint(0, 255)) for _ in range(500)) sequence = [b'a' * 500, b'b' * 200, b'a' * 300] sequence_unicode = ['a' * 500, 'é' * 200, 'a' * 300] diff --git a/tests/migrate_signals/tests.py b/tests/migrate_signals/tests.py index 84b6608f46eb..97f449e80548 100644 --- a/tests/migrate_signals/tests.py +++ b/tests/migrate_signals/tests.py @@ -1,9 +1,10 @@ +from io import StringIO + from django.apps import apps from django.core import management from django.db import migrations from django.db.models import signals from django.test import TransactionTestCase, override_settings -from django.utils import six APP_CONFIG = apps.get_app_config('migrate_signals') SIGNAL_ARGS = ['app_config', 'verbosity', 'interactive', 'using', 'plan', 'apps'] @@ -70,7 +71,7 @@ def test_args(self): post_migrate_receiver = Receiver(signals.post_migrate) management.call_command( 'migrate', database=MIGRATE_DATABASE, verbosity=MIGRATE_VERBOSITY, - interactive=MIGRATE_INTERACTIVE, stdout=six.StringIO(), + interactive=MIGRATE_INTERACTIVE, stdout=StringIO(), ) for receiver in [pre_migrate_receiver, post_migrate_receiver]: @@ -91,7 +92,7 @@ def test_migrations_only(self): """ pre_migrate_receiver = Receiver(signals.pre_migrate) post_migrate_receiver = Receiver(signals.post_migrate) - stdout = six.StringIO() + stdout = StringIO() management.call_command( 'migrate', database=MIGRATE_DATABASE, verbosity=MIGRATE_VERBOSITY, interactive=MIGRATE_INTERACTIVE, stdout=stdout, diff --git a/tests/migrations/models.py b/tests/migrations/models.py index dea320c03312..9a34edf349b6 100644 --- a/tests/migrations/models.py +++ b/tests/migrations/models.py @@ -1,13 +1,12 @@ from django.apps.registry import Apps from django.db import models -from django.utils import six class CustomModelBase(models.base.ModelBase): pass -class ModelWithCustomBase(six.with_metaclass(CustomModelBase, models.Model)): +class ModelWithCustomBase(models.Model, metaclass=CustomModelBase): pass diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index ca6b42044ff2..e6de83212e3b 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -15,7 +15,6 @@ ) from django.db.migrations.recorder import MigrationRecorder from django.test import mock, override_settings -from django.utils import six from django.utils.encoding import force_text from .models import UnicodeModel, UnserializableModel @@ -63,7 +62,7 @@ def test_migrate(self): 'migrations.migrations_test_apps.migrated_app', ]) def test_migrate_with_system_checks(self): - out = six.StringIO() + out = io.StringIO() call_command('migrate', skip_checks=False, no_color=True, stdout=out) self.assertIn('Apply all migrations: migrated_app', out.getvalue()) @@ -125,7 +124,7 @@ def test_migrate_fake_initial(self): with self.assertRaises(DatabaseError): call_command("migrate", "migrations", "0001", verbosity=0) # Run initial migration with an explicit --fake-initial - out = six.StringIO() + out = io.StringIO() with mock.patch('django.core.management.color.supports_color', lambda *args: False): call_command("migrate", "migrations", "0001", fake_initial=True, stdout=out, verbosity=1) call_command("migrate", "migrations", "0001", fake_initial=True, verbosity=0, database="other") @@ -177,7 +176,7 @@ def test_migrate_fake_split_initial(self): """ call_command("migrate", "migrations", "0002", verbosity=0) call_command("migrate", "migrations", "zero", fake=True, verbosity=0) - out = six.StringIO() + out = io.StringIO() with mock.patch('django.core.management.color.supports_color', lambda *args: False): call_command("migrate", "migrations", "0002", fake_initial=True, stdout=out, verbosity=1) value = out.getvalue().lower() @@ -202,7 +201,7 @@ def test_showmigrations_list(self): showmigrations --list displays migrations and whether or not they're applied. """ - out = six.StringIO() + out = io.StringIO() with mock.patch('django.core.management.color.supports_color', lambda *args: True): call_command("showmigrations", format='list', stdout=out, verbosity=0, no_color=False) self.assertEqual( @@ -214,7 +213,7 @@ def test_showmigrations_list(self): call_command("migrate", "migrations", "0001", verbosity=0) - out = six.StringIO() + out = io.StringIO() # Giving the explicit app_label tests for selective `show_list` in the command call_command("showmigrations", "migrations", format='list', stdout=out, verbosity=0, no_color=True) self.assertEqual( @@ -231,7 +230,7 @@ def test_showmigrations_plan(self): """ Tests --plan output of showmigrations command """ - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out) self.assertEqual( "[ ] migrations.0001_initial\n" @@ -240,7 +239,7 @@ def test_showmigrations_plan(self): out.getvalue().lower() ) - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out, verbosity=2) self.assertEqual( "[ ] migrations.0001_initial\n" @@ -250,7 +249,7 @@ def test_showmigrations_plan(self): ) call_command("migrate", "migrations", "0003", verbosity=0) - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out) self.assertEqual( "[x] migrations.0001_initial\n" @@ -259,7 +258,7 @@ def test_showmigrations_plan(self): out.getvalue().lower() ) - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out, verbosity=2) self.assertEqual( "[x] migrations.0001_initial\n" @@ -276,11 +275,11 @@ def test_showmigrations_plan_no_migrations(self): """ Tests --plan output of showmigrations command without migrations """ - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out) self.assertEqual("", out.getvalue().lower()) - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out, verbosity=2) self.assertEqual("", out.getvalue().lower()) @@ -289,7 +288,7 @@ def test_showmigrations_plan_squashed(self): """ Tests --plan output of showmigrations command with squashed migrations. """ - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out) self.assertEqual( "[ ] migrations.1_auto\n" @@ -300,7 +299,7 @@ def test_showmigrations_plan_squashed(self): out.getvalue().lower() ) - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out, verbosity=2) self.assertEqual( "[ ] migrations.1_auto\n" @@ -313,7 +312,7 @@ def test_showmigrations_plan_squashed(self): call_command("migrate", "migrations", "3_squashed_5", verbosity=0) - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out) self.assertEqual( "[x] migrations.1_auto\n" @@ -324,7 +323,7 @@ def test_showmigrations_plan_squashed(self): out.getvalue().lower() ) - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out, verbosity=2) self.assertEqual( "[x] migrations.1_auto\n" @@ -345,7 +344,7 @@ def test_showmigrations_plan_single_app_label(self): `showmigrations --plan app_label` output with a single app_label. """ # Single app with no dependencies on other apps. - out = six.StringIO() + out = io.StringIO() call_command('showmigrations', 'mutate_state_b', format='plan', stdout=out) self.assertEqual( '[ ] mutate_state_b.0001_initial\n' @@ -353,7 +352,7 @@ def test_showmigrations_plan_single_app_label(self): out.getvalue() ) # Single app with dependencies. - out = six.StringIO() + out = io.StringIO() call_command('showmigrations', 'author_app', format='plan', stdout=out) self.assertEqual( '[ ] author_app.0001_initial\n' @@ -363,7 +362,7 @@ def test_showmigrations_plan_single_app_label(self): ) # Some migrations already applied. call_command('migrate', 'author_app', '0001', verbosity=0) - out = six.StringIO() + out = io.StringIO() call_command('showmigrations', 'author_app', format='plan', stdout=out) self.assertEqual( '[X] author_app.0001_initial\n' @@ -385,7 +384,7 @@ def test_showmigrations_plan_multiple_app_labels(self): """ # Multiple apps: author_app depends on book_app; mutate_state_b doesn't # depend on other apps. - out = six.StringIO() + out = io.StringIO() call_command('showmigrations', 'mutate_state_b', 'author_app', format='plan', stdout=out) self.assertEqual( '[ ] author_app.0001_initial\n' @@ -397,7 +396,7 @@ def test_showmigrations_plan_multiple_app_labels(self): ) # Multiple apps: args order shouldn't matter (the same result is # expected as above). - out = six.StringIO() + out = io.StringIO() call_command('showmigrations', 'author_app', 'mutate_state_b', format='plan', stdout=out) self.assertEqual( '[ ] author_app.0001_initial\n' @@ -431,7 +430,7 @@ def test_sqlmigrate_forwards(self): """ sqlmigrate outputs forward looking SQL. """ - out = six.StringIO() + out = io.StringIO() call_command("sqlmigrate", "migrations", "0001", stdout=out) output = out.getvalue().lower() @@ -472,7 +471,7 @@ def test_sqlmigrate_backwards(self): # Cannot generate the reverse SQL unless we've applied the migration. call_command("migrate", "migrations", verbosity=0) - out = six.StringIO() + out = io.StringIO() call_command("sqlmigrate", "migrations", "0001", stdout=out, backwards=True) output = out.getvalue().lower() @@ -514,7 +513,7 @@ def test_sqlmigrate_for_non_atomic_migration(self): """ Transaction wrappers aren't shown for non-atomic migrations. """ - out = six.StringIO() + out = io.StringIO() call_command("sqlmigrate", "migrations", "0001", stdout=out) output = out.getvalue().lower() queries = [q.strip() for q in output.splitlines()] @@ -541,7 +540,7 @@ def test_regression_22823_unmigrated_fk_to_migrated_model(self): "B" was not included in the ProjectState that is used to detect soft-applied migrations (#22823). """ - call_command("migrate", "migrated_unapplied_app", stdout=six.StringIO()) + call_command("migrate", "migrated_unapplied_app", stdout=io.StringIO()) # unmigrated_app.SillyModel has a foreign key to 'migrations.Tribble', # but that model is only defined in a migration, so the global app @@ -570,7 +569,7 @@ def test_migrate_record_replaced(self): replaced migrations as run. """ recorder = MigrationRecorder(connection) - out = six.StringIO() + out = io.StringIO() call_command("migrate", "migrations", verbosity=0) call_command("showmigrations", "migrations", stdout=out, no_color=True) self.assertEqual( @@ -594,7 +593,7 @@ def test_migrate_record_squashed(self): recorder = MigrationRecorder(connection) recorder.record_applied("migrations", "0001_initial") recorder.record_applied("migrations", "0002_second") - out = six.StringIO() + out = io.StringIO() call_command("migrate", "migrations", verbosity=0) call_command("showmigrations", "migrations", stdout=out, no_color=True) self.assertEqual( @@ -683,7 +682,7 @@ def test_makemigrations_empty_connections(self): empty_connections = ConnectionHandler({'default': {}}) with mock.patch('django.core.management.commands.makemigrations.connections', new=empty_connections): # with no apps - out = six.StringIO() + out = io.StringIO() call_command('makemigrations', stdout=out) self.assertIn('No changes detected', out.getvalue()) # with an app @@ -767,7 +766,7 @@ def test_makemigrations_merge_no_conflict(self): """ makemigrations exits if in merge mode with no conflicts. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations"): call_command("makemigrations", merge=True, stdout=out) self.assertIn("No conflicts detected to merge.", out.getvalue()) @@ -776,7 +775,7 @@ def test_makemigrations_no_app_sys_exit(self): """ makemigrations exits if a non-existent app is specified. """ - err = six.StringIO() + err = io.StringIO() with self.assertRaises(SystemExit): call_command("makemigrations", "this_app_does_not_exist", stderr=err) self.assertIn("'this_app_does_not_exist' could not be found.", err.getvalue()) @@ -824,7 +823,7 @@ def test_makemigrations_no_changes_no_apps(self): """ makemigrations exits when there are no changes and no apps are specified. """ - out = six.StringIO() + out = io.StringIO() call_command("makemigrations", stdout=out) self.assertIn("No changes detected", out.getvalue()) @@ -832,7 +831,7 @@ def test_makemigrations_no_changes(self): """ makemigrations exits when there are no changes to an app. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_no_changes"): call_command("makemigrations", "migrations", stdout=out) self.assertIn("No changes detected in app 'migrations'", out.getvalue()) @@ -842,7 +841,7 @@ def test_makemigrations_no_apps_initial(self): makemigrations should detect initial is needed on empty migration modules if no app provided. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_empty"): call_command("makemigrations", stdout=out) self.assertIn("0001_initial.py", out.getvalue()) @@ -851,7 +850,7 @@ def test_makemigrations_migrations_announce(self): """ makemigrations announces the migration at the default verbosity level. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(): call_command("makemigrations", "migrations", stdout=out) self.assertIn("Migrations for 'migrations'", out.getvalue()) @@ -873,7 +872,7 @@ def test_makemigrations_interactive_reject(self): makemigrations enters and exits interactive mode properly. """ # Monkeypatch interactive questioner to auto reject - with mock.patch('django.db.migrations.questioner.input', mock.Mock(return_value='N')): + with mock.patch('builtins.input', mock.Mock(return_value='N')): with self.temporary_migration_module(module="migrations.test_migrations_conflict") as migration_dir: call_command("makemigrations", "migrations", name="merge", merge=True, interactive=True, verbosity=0) merge_file = os.path.join(migration_dir, '0003_merge.py') @@ -884,8 +883,8 @@ def test_makemigrations_interactive_accept(self): makemigrations enters interactive mode and merges properly. """ # Monkeypatch interactive questioner to auto accept - with mock.patch('django.db.migrations.questioner.input', mock.Mock(return_value='y')): - out = six.StringIO() + with mock.patch('builtins.input', mock.Mock(return_value='y')): + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_conflict") as migration_dir: call_command("makemigrations", "migrations", name="merge", merge=True, interactive=True, stdout=out) merge_file = os.path.join(migration_dir, '0003_merge.py') @@ -895,8 +894,8 @@ def test_makemigrations_interactive_accept(self): @mock.patch('django.db.migrations.utils.datetime') def test_makemigrations_default_merge_name(self, mock_datetime): mock_datetime.datetime.now.return_value = datetime.datetime(2016, 1, 2, 3, 4) - with mock.patch('django.db.migrations.questioner.input', mock.Mock(return_value='y')): - out = six.StringIO() + with mock.patch('builtins.input', mock.Mock(return_value='y')): + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_conflict") as migration_dir: call_command("makemigrations", "migrations", merge=True, interactive=True, stdout=out) merge_file = os.path.join(migration_dir, '0003_merge_20160102_0304.py') @@ -915,7 +914,7 @@ class SillyModel(models.Model): class Meta: app_label = "migrations" - out = six.StringIO() + out = io.StringIO() with self.assertRaises(SystemExit): with self.temporary_migration_module(module="migrations.test_migrations_no_default"): call_command("makemigrations", "migrations", interactive=False, stdout=out) @@ -933,7 +932,7 @@ class Author(models.Model): class Meta: app_label = "migrations" - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations"): call_command("makemigrations", "migrations", interactive=False, stdout=out) self.assertIn("Alter field slug on author", out.getvalue()) @@ -949,7 +948,7 @@ class RenamedModel(models.Model): class Meta: app_label = "migrations" - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_no_default"): call_command("makemigrations", "migrations", interactive=False, stdout=out) self.assertIn("Delete model SillyModel", out.getvalue()) @@ -966,7 +965,7 @@ class SillyModel(models.Model): class Meta: app_label = "migrations" - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_no_default"): call_command("makemigrations", "migrations", interactive=False, stdout=out) self.assertIn("Remove field silly_field from sillymodel", out.getvalue()) @@ -976,7 +975,7 @@ def test_makemigrations_handle_merge(self): """ makemigrations properly merges the conflicting migrations with --noinput. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_conflict") as migration_dir: call_command("makemigrations", "migrations", name="merge", merge=True, interactive=False, stdout=out) merge_file = os.path.join(migration_dir, '0003_merge.py') @@ -992,7 +991,7 @@ def test_makemigration_merge_dry_run(self): makemigrations respects --dry-run option when fixing migration conflicts (#24427). """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_conflict") as migration_dir: call_command( "makemigrations", "migrations", name="merge", dry_run=True, @@ -1011,7 +1010,7 @@ def test_makemigration_merge_dry_run_verbosity_3(self): `makemigrations --merge --dry-run` writes the merge migration file to stdout with `verbosity == 3` (#24427). """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_conflict") as migration_dir: call_command( "makemigrations", "migrations", name="merge", dry_run=True, @@ -1045,7 +1044,7 @@ class SillyModel(models.Model): class Meta: app_label = "migrations" - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_no_default"): call_command("makemigrations", "migrations", dry_run=True, stdout=out) # Output the expected changes directly, without asking for defaults @@ -1063,7 +1062,7 @@ class SillyModel(models.Model): class Meta: app_label = "migrations" - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_no_default"): call_command("makemigrations", "migrations", dry_run=True, stdout=out, verbosity=3) @@ -1091,7 +1090,7 @@ class SillyModel(models.Model): class Meta: app_label = "migrations" - out = six.StringIO() + out = io.StringIO() migration_module = "migrations.test_migrations_path_doesnt_exist.foo.bar" with self.temporary_migration_module(module=migration_module) as migration_dir: call_command("makemigrations", "migrations", stdout=out) @@ -1110,8 +1109,8 @@ def test_makemigrations_interactive_by_default(self): --noinput is specified. """ # Monkeypatch interactive questioner to auto reject - out = six.StringIO() - with mock.patch('django.db.migrations.questioner.input', mock.Mock(return_value='N')): + out = io.StringIO() + with mock.patch('builtins.input', mock.Mock(return_value='N')): with self.temporary_migration_module(module="migrations.test_migrations_conflict") as migration_dir: call_command("makemigrations", "migrations", name="merge", merge=True, stdout=out) merge_file = os.path.join(migration_dir, '0003_merge.py') @@ -1141,8 +1140,8 @@ def test_makemigrations_unspecified_app_with_conflict_merge(self): it has conflicting migrations. """ # Monkeypatch interactive questioner to auto accept - with mock.patch('django.db.migrations.questioner.input', mock.Mock(return_value='y')): - out = six.StringIO() + with mock.patch('builtins.input', mock.Mock(return_value='y')): + out = io.StringIO() with self.temporary_migration_module(app_label="migrated_app") as migration_dir: call_command("makemigrations", "migrated_app", name="merge", merge=True, interactive=True, stdout=out) merge_file = os.path.join(migration_dir, '0003_merge.py') @@ -1159,8 +1158,8 @@ def test_makemigrations_merge_dont_output_dependency_operations(self): don't belong to a given app. """ # Monkeypatch interactive questioner to auto accept - with mock.patch('django.db.migrations.questioner.input', mock.Mock(return_value='N')): - out = six.StringIO() + with mock.patch('builtins.input', mock.Mock(return_value='N')): + out = io.StringIO() with mock.patch('django.core.management.color.supports_color', lambda *args: False): call_command( "makemigrations", "conflicting_app_with_dependencies", @@ -1232,7 +1231,7 @@ def test_makemigrations_migration_path_output(self): they are outside of the current tree, in which case the absolute path should be shown. """ - out = six.StringIO() + out = io.StringIO() apps.register_model('migrations', UnicodeModel) with self.temporary_migration_module() as migration_dir: call_command("makemigrations", "migrations", stdout=out) @@ -1245,7 +1244,7 @@ def test_makemigrations_migration_path_output_valueerror(self): Windows if Django is installed on a different drive than where the migration files are created. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module() as migration_dir: with mock.patch('os.path.relpath', side_effect=ValueError): call_command('makemigrations', 'migrations', stdout=out) @@ -1263,7 +1262,7 @@ def test_makemigrations_inconsistent_history(self): with self.assertRaisesMessage(InconsistentMigrationHistory, msg): call_command("makemigrations") - @mock.patch('django.db.migrations.questioner.input', return_value='1') + @mock.patch('builtins.input', return_value='1') @mock.patch('django.db.migrations.questioner.sys.stdin', mock.MagicMock(encoding=sys.getdefaultencoding())) def test_makemigrations_auto_now_add_interactive(self, *args): """ @@ -1278,8 +1277,8 @@ class Meta: app_label = 'migrations' # Monkeypatch interactive questioner to auto accept - with mock.patch('django.db.migrations.questioner.sys.stdout', new_callable=six.StringIO) as prompt_stdout: - out = six.StringIO() + with mock.patch('django.db.migrations.questioner.sys.stdout', new_callable=io.StringIO) as prompt_stdout: + out = io.StringIO() with self.temporary_migration_module(module='migrations.test_auto_now_add'): call_command('makemigrations', 'migrations', interactive=True, stdout=out) output = out.getvalue() @@ -1316,7 +1315,7 @@ def test_squashmigrations_optimizes(self): """ squashmigrations optimizes operations. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations"): call_command("squashmigrations", "migrations", "0002", interactive=False, verbosity=1, stdout=out) self.assertIn("Optimized from 8 operations to 3 operations.", out.getvalue()) @@ -1325,7 +1324,7 @@ def test_ticket_23799_squashmigrations_no_optimize(self): """ squashmigrations --no-optimize doesn't optimize operations. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations"): call_command("squashmigrations", "migrations", "0002", interactive=False, verbosity=1, no_optimize=True, stdout=out) @@ -1335,7 +1334,7 @@ def test_squashmigrations_valid_start(self): """ squashmigrations accepts a starting migration. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_no_changes") as migration_dir: call_command("squashmigrations", "migrations", "0002", "0003", interactive=False, verbosity=1, stdout=out) diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index 59fd8eece5e9..fb16b441d183 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -8,6 +8,7 @@ import tokenize import unittest import uuid +from io import StringIO import custom_migration_operations.more_operations import custom_migration_operations.operations @@ -20,7 +21,7 @@ MigrationWriter, OperationWriter, SettingsReference, ) from django.test import SimpleTestCase, ignore_warnings, mock -from django.utils import datetime_safe, six +from django.utils import datetime_safe from django.utils._os import upath from django.utils.deconstruct import deconstructible from django.utils.encoding import force_str @@ -561,7 +562,7 @@ def test_simple_migration(self): self.assertIn("Migration", result) # In order to preserve compatibility with Python 3.2 unicode literals # prefix shouldn't be added to strings. - tokens = tokenize.generate_tokens(six.StringIO(str(output)).readline) + tokens = tokenize.generate_tokens(StringIO(str(output)).readline) for token_type, token_source, (srow, scol), __, line in tokens: if token_type == tokenize.STRING: self.assertFalse( diff --git a/tests/model_fields/models.py b/tests/model_fields/models.py index 019301d5e2da..4830fb9ed29f 100644 --- a/tests/model_fields/models.py +++ b/tests/model_fields/models.py @@ -12,7 +12,6 @@ from django.db.models.fields.related import ( ForeignKey, ForeignObject, ManyToManyField, OneToOneField, ) -from django.utils import six try: from PIL import Image @@ -51,7 +50,7 @@ class Whiz(models.Model): c = models.IntegerField(choices=CHOICES, null=True) -class Counter(six.Iterator): +class Counter: def __init__(self): self.n = 1 diff --git a/tests/model_fields/test_binaryfield.py b/tests/model_fields/test_binaryfield.py index 641dc1728765..9d97d1118fad 100644 --- a/tests/model_fields/test_binaryfield.py +++ b/tests/model_fields/test_binaryfield.py @@ -1,6 +1,5 @@ from django.core.exceptions import ValidationError from django.test import TestCase -from django.utils import six from .models import DataModel @@ -9,7 +8,7 @@ class BinaryFieldTests(TestCase): binary_data = b'\x00\x46\xFE' def test_set_and_retrieve(self): - data_set = (self.binary_data, six.memoryview(self.binary_data)) + data_set = (self.binary_data, memoryview(self.binary_data)) for bdata in data_set: dm = DataModel(data=bdata) dm.save() diff --git a/tests/model_forms/models.py b/tests/model_forms/models.py index 0914fc2587a9..f85ae8e1fda6 100644 --- a/tests/model_forms/models.py +++ b/tests/model_forms/models.py @@ -16,7 +16,6 @@ from django.core.files.storage import FileSystemStorage from django.db import models from django.utils._os import upath -from django.utils.six.moves import range temp_storage_dir = tempfile.mkdtemp() temp_storage = FileSystemStorage(temp_storage_dir) diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index 27143e97f4c3..adb90d6d146e 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -17,7 +17,6 @@ ) from django.template import Context, Template from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature -from django.utils import six from django.utils._os import upath from .models import ( @@ -2954,7 +2953,7 @@ def __new__(cls, name, bases, attrs): return new -class CustomMetaclassForm(six.with_metaclass(CustomMetaclass, forms.ModelForm)): +class CustomMetaclassForm(forms.ModelForm, metaclass=CustomMetaclass): pass diff --git a/tests/multiple_database/tests.py b/tests/multiple_database/tests.py index 7e936216b742..3487894fd981 100644 --- a/tests/multiple_database/tests.py +++ b/tests/multiple_database/tests.py @@ -1,5 +1,6 @@ import datetime import pickle +from io import StringIO from operator import attrgetter from django.contrib.auth.models import User @@ -9,7 +10,6 @@ from django.db.models import signals from django.db.utils import ConnectionRouter from django.test import SimpleTestCase, TestCase, override_settings -from django.utils.six import StringIO from .models import Book, Person, Pet, Review, UserProfile from .routers import AuthRouter, TestRouter, WriteRouter diff --git a/tests/pagination/tests.py b/tests/pagination/tests.py index cc3a0efbc26f..2e2e2d37db15 100644 --- a/tests/pagination/tests.py +++ b/tests/pagination/tests.py @@ -6,7 +6,6 @@ UnorderedObjectListWarning, ) from django.test import TestCase -from django.utils import six from .custom import ValidAdjacentNumsPaginator from .models import Article @@ -240,7 +239,7 @@ def test_page_range_iterator(self): """ Paginator.page_range should be an iterator. """ - self.assertIsInstance(Paginator([1, 2, 3], 2).page_range, type(six.moves.range(0))) + self.assertIsInstance(Paginator([1, 2, 3], 2).page_range, type(range(0))) class ModelPaginationTests(TestCase): diff --git a/tests/queries/tests.py b/tests/queries/tests.py index ed323be1542f..1f9094e49fa0 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -11,7 +11,6 @@ from django.db.models.sql.where import NothingNode, WhereNode from django.test import TestCase, skipUnlessDBFeature from django.test.utils import CaptureQueriesContext -from django.utils.six.moves import range from .models import ( FK1, Annotation, Article, Author, BaseA, Book, CategoryItem, diff --git a/tests/requests/tests.py b/tests/requests/tests.py index 09b08540f4d9..54fe797728b1 100644 --- a/tests/requests/tests.py +++ b/tests/requests/tests.py @@ -1,7 +1,9 @@ import time from datetime import datetime, timedelta +from http import cookies from io import BytesIO from itertools import chain +from urllib.parse import urlencode as original_urlencode from django.core.exceptions import SuspiciousOperation from django.core.handlers.wsgi import LimitedStream, WSGIRequest @@ -14,8 +16,6 @@ from django.test.utils import freeze_time, str_prefix from django.utils.encoding import force_str from django.utils.http import cookie_date, urlencode -from django.utils.six.moves import http_cookies -from django.utils.six.moves.urllib.parse import urlencode as original_urlencode from django.utils.timezone import utc @@ -262,7 +262,7 @@ def test_httponly_cookie(self): example_cookie = response.cookies['example'] # A compat cookie may be in use -- check that it has worked # both as an output string, and using the cookie attributes - self.assertIn('; %s' % http_cookies.Morsel._reserved['httponly'], str(example_cookie)) + self.assertIn('; %s' % cookies.Morsel._reserved['httponly'], str(example_cookie)) self.assertTrue(example_cookie['httponly']) def test_unicode_cookie(self): diff --git a/tests/serializers/test_data.py b/tests/serializers/test_data.py index 2e9527f982b6..966df682b2e6 100644 --- a/tests/serializers/test_data.py +++ b/tests/serializers/test_data.py @@ -13,7 +13,6 @@ from django.core import serializers from django.db import connection, models from django.test import TestCase -from django.utils import six from .models import ( Anchor, AutoNowDateTimeData, BigIntegerData, BinaryData, BooleanData, @@ -197,7 +196,7 @@ def inherited_compare(testcase, pk, klass, data): test_data = [ # Format: (data type, PK value, Model Class, data) - (data_obj, 1, BinaryData, six.memoryview(b"\x05\xFD\x00")), + (data_obj, 1, BinaryData, memoryview(b"\x05\xFD\x00")), (data_obj, 2, BinaryData, None), (data_obj, 5, BooleanData, True), (data_obj, 6, BooleanData, False), diff --git a/tests/serializers/test_yaml.py b/tests/serializers/test_yaml.py index f3988d7ff15b..542c28fb2efe 100644 --- a/tests/serializers/test_yaml.py +++ b/tests/serializers/test_yaml.py @@ -1,10 +1,10 @@ import importlib import unittest +from io import StringIO from django.core import management, serializers from django.core.serializers.base import DeserializationError from django.test import SimpleTestCase, TestCase, TransactionTestCase -from django.utils.six import StringIO from .models import Author from .tests import SerializersTestBase, SerializersTransactionTestBase diff --git a/tests/serializers/tests.py b/tests/serializers/tests.py index 656bc4b4db2c..5c30d66082c8 100644 --- a/tests/serializers/tests.py +++ b/tests/serializers/tests.py @@ -1,4 +1,5 @@ from datetime import datetime +from io import StringIO from django.core import serializers from django.core.serializers import SerializerDoesNotExist @@ -10,7 +11,6 @@ ) from django.test.utils import Approximate from django.utils.functional import curry -from django.utils.six import StringIO from .models import ( Actor, Article, Author, AuthorProfile, BaseModel, Category, ComplexModel, diff --git a/tests/servers/tests.py b/tests/servers/tests.py index ee0d8629cfc7..8f7e3253e71f 100644 --- a/tests/servers/tests.py +++ b/tests/servers/tests.py @@ -5,12 +5,12 @@ import errno import os import socket +from urllib.error import HTTPError +from urllib.request import urlopen from django.test import LiveServerTestCase, override_settings from django.utils._os import upath from django.utils.http import urlencode -from django.utils.six.moves.urllib.error import HTTPError -from django.utils.six.moves.urllib.request import urlopen from .models import Person diff --git a/tests/sessions_tests/tests.py b/tests/sessions_tests/tests.py index ae57f1d91973..29de5782d9b3 100644 --- a/tests/sessions_tests/tests.py +++ b/tests/sessions_tests/tests.py @@ -6,6 +6,7 @@ import tempfile import unittest from datetime import timedelta +from http import cookies from django.conf import settings from django.contrib.sessions.backends.base import UpdateError @@ -31,9 +32,8 @@ RequestFactory, TestCase, ignore_warnings, override_settings, ) from django.test.utils import patch_logger -from django.utils import six, timezone +from django.utils import timezone from django.utils.encoding import force_text -from django.utils.six.moves import http_cookies from .models import SessionStore as CustomDatabaseSession @@ -122,7 +122,7 @@ def test_iterkeys(self): self.session['x'] = 1 self.session.modified = False self.session.accessed = False - i = six.iterkeys(self.session) + i = iter(self.session.keys()) self.assertTrue(hasattr(i, '__iter__')) self.assertTrue(self.session.accessed) self.assertFalse(self.session.modified) @@ -132,7 +132,7 @@ def test_itervalues(self): self.session['x'] = 1 self.session.modified = False self.session.accessed = False - i = six.itervalues(self.session) + i = iter(self.session.values()) self.assertTrue(hasattr(i, '__iter__')) self.assertTrue(self.session.accessed) self.assertFalse(self.session.modified) @@ -142,7 +142,7 @@ def test_iteritems(self): self.session['x'] = 1 self.session.modified = False self.session.accessed = False - i = six.iteritems(self.session) + i = iter(self.session.items()) self.assertTrue(hasattr(i, '__iter__')) self.assertTrue(self.session.accessed) self.assertFalse(self.session.modified) @@ -661,7 +661,7 @@ def test_httponly_session_cookie(self): self.assertTrue( response.cookies[settings.SESSION_COOKIE_NAME]['httponly']) self.assertIn( - http_cookies.Morsel._reserved['httponly'], + cookies.Morsel._reserved['httponly'], str(response.cookies[settings.SESSION_COOKIE_NAME]) ) @@ -679,7 +679,7 @@ def test_no_httponly_session_cookie(self): response = middleware.process_response(request, response) self.assertFalse(response.cookies[settings.SESSION_COOKIE_NAME]['httponly']) - self.assertNotIn(http_cookies.Morsel._reserved['httponly'], + self.assertNotIn(cookies.Morsel._reserved['httponly'], str(response.cookies[settings.SESSION_COOKIE_NAME])) def test_session_save_on_500(self): diff --git a/tests/sitemaps_tests/test_utils.py b/tests/sitemaps_tests/test_utils.py index ba1eadd5d165..dc4d6511f362 100644 --- a/tests/sitemaps_tests/test_utils.py +++ b/tests/sitemaps_tests/test_utils.py @@ -1,9 +1,10 @@ +from urllib.parse import urlencode + from django.contrib.sitemaps import ( SitemapNotFound, _get_sitemap_full_url, ping_google, ) from django.core.exceptions import ImproperlyConfigured from django.test import mock, modify_settings, override_settings -from django.utils.six.moves.urllib.parse import urlencode from .base import SitemapTestsBase diff --git a/tests/staticfiles_tests/test_forms.py b/tests/staticfiles_tests/test_forms.py index e3d4772662d6..4666520bc1c2 100644 --- a/tests/staticfiles_tests/test_forms.py +++ b/tests/staticfiles_tests/test_forms.py @@ -1,8 +1,9 @@ +from urllib.parse import urljoin + from django.contrib.staticfiles import storage from django.contrib.staticfiles.templatetags.staticfiles import static from django.forms import Media from django.test import SimpleTestCase, override_settings -from django.utils.six.moves.urllib.parse import urljoin class StaticTestStorage(storage.StaticFilesStorage): diff --git a/tests/staticfiles_tests/test_liveserver.py b/tests/staticfiles_tests/test_liveserver.py index 1714ae8b1bfa..b3727bea12cf 100644 --- a/tests/staticfiles_tests/test_liveserver.py +++ b/tests/staticfiles_tests/test_liveserver.py @@ -6,12 +6,12 @@ import contextlib import os +from urllib.request import urlopen from django.contrib.staticfiles.testing import StaticLiveServerTestCase from django.core.exceptions import ImproperlyConfigured from django.test import modify_settings, override_settings from django.utils._os import upath -from django.utils.six.moves.urllib.request import urlopen TEST_ROOT = os.path.dirname(upath(__file__)) TEST_SETTINGS = { diff --git a/tests/staticfiles_tests/test_management.py b/tests/staticfiles_tests/test_management.py index 7d17f2abe1f1..310c152d06ab 100644 --- a/tests/staticfiles_tests/test_management.py +++ b/tests/staticfiles_tests/test_management.py @@ -4,6 +4,7 @@ import shutil import tempfile import unittest +from io import StringIO from admin_scripts.tests import AdminScriptTestCase @@ -14,7 +15,7 @@ from django.core.management import call_command from django.test import mock, override_settings from django.test.utils import extend_sys_path -from django.utils import six, timezone +from django.utils import timezone from django.utils._os import symlinks_supported from django.utils.encoding import force_text from django.utils.functional import empty @@ -38,7 +39,7 @@ class TestFindStatic(TestDefaults, CollectionTestCase): Test ``findstatic`` management command. """ def _get_file(self, filepath): - path = call_command('findstatic', filepath, all=False, verbosity=0, stdout=six.StringIO()) + path = call_command('findstatic', filepath, all=False, verbosity=0, stdout=StringIO()) with codecs.open(force_text(path), "r", "utf-8") as f: return f.read() @@ -46,7 +47,7 @@ def test_all_files(self): """ findstatic returns all candidate files if run without --first and -v1. """ - result = call_command('findstatic', 'test/file.txt', verbosity=1, stdout=six.StringIO()) + result = call_command('findstatic', 'test/file.txt', verbosity=1, stdout=StringIO()) lines = [l.strip() for l in result.split('\n')] self.assertEqual(len(lines), 3) # three because there is also the "Found here" line self.assertIn('project', force_text(lines[1])) @@ -56,7 +57,7 @@ def test_all_files_less_verbose(self): """ findstatic returns all candidate files if run without --first and -v0. """ - result = call_command('findstatic', 'test/file.txt', verbosity=0, stdout=six.StringIO()) + result = call_command('findstatic', 'test/file.txt', verbosity=0, stdout=StringIO()) lines = [l.strip() for l in result.split('\n')] self.assertEqual(len(lines), 2) self.assertIn('project', force_text(lines[0])) @@ -67,7 +68,7 @@ def test_all_files_more_verbose(self): findstatic returns all candidate files if run without --first and -v2. Also, test that findstatic returns the searched locations with -v2. """ - result = call_command('findstatic', 'test/file.txt', verbosity=2, stdout=six.StringIO()) + result = call_command('findstatic', 'test/file.txt', verbosity=2, stdout=StringIO()) lines = [l.strip() for l in result.split('\n')] self.assertIn('project', force_text(lines[1])) self.assertIn('apps', force_text(lines[2])) @@ -89,7 +90,7 @@ def test_all_files_more_verbose(self): class TestConfiguration(StaticFilesTestCase): def test_location_empty(self): msg = 'without having set the STATIC_ROOT setting to a filesystem path' - err = six.StringIO() + err = StringIO() for root in ['', None]: with override_settings(STATIC_ROOT=root): with self.assertRaisesMessage(ImproperlyConfigured, msg): @@ -188,10 +189,9 @@ def _input(msg): return _input def test_warning_when_clearing_staticdir(self): - stdout = six.StringIO() + stdout = StringIO() self.run_collectstatic() - with mock.patch('django.contrib.staticfiles.management.commands.collectstatic.input', - side_effect=self.mock_input(stdout)): + with mock.patch('builtins.input', side_effect=self.mock_input(stdout)): call_command('collectstatic', interactive=True, clear=True, stdout=stdout) output = force_text(stdout.getvalue()) @@ -199,17 +199,16 @@ def test_warning_when_clearing_staticdir(self): self.assertIn(self.delete_warning_msg, output) def test_warning_when_overwriting_files_in_staticdir(self): - stdout = six.StringIO() + stdout = StringIO() self.run_collectstatic() - with mock.patch('django.contrib.staticfiles.management.commands.collectstatic.input', - side_effect=self.mock_input(stdout)): + with mock.patch('builtins.input', side_effect=self.mock_input(stdout)): call_command('collectstatic', interactive=True, stdout=stdout) output = force_text(stdout.getvalue()) self.assertIn(self.overwrite_warning_msg, output) self.assertNotIn(self.delete_warning_msg, output) def test_no_warning_when_staticdir_does_not_exist(self): - stdout = six.StringIO() + stdout = StringIO() shutil.rmtree(settings.STATIC_ROOT) call_command('collectstatic', interactive=True, stdout=stdout) output = force_text(stdout.getvalue()) @@ -218,7 +217,7 @@ def test_no_warning_when_staticdir_does_not_exist(self): self.assertIn(self.files_copied_msg, output) def test_no_warning_for_empty_staticdir(self): - stdout = six.StringIO() + stdout = StringIO() static_dir = tempfile.mkdtemp(prefix='collectstatic_empty_staticdir_test') with override_settings(STATIC_ROOT=static_dir): call_command('collectstatic', interactive=True, stdout=stdout) @@ -347,7 +346,7 @@ def _collectstatic_output(self, **kwargs): the command at highest verbosity, which is why we can't just call e.g. BaseCollectionTestCase.run_collectstatic() """ - out = six.StringIO() + out = StringIO() call_command('collectstatic', interactive=False, verbosity=3, stdout=out, **kwargs) return force_text(out.getvalue()) @@ -407,7 +406,7 @@ def test_skips_newer_files_in_remote_storage(self): NeverCopyRemoteStorage.get_modified_time() returns a datetime in the future to simulate an unmodified file. """ - stdout = six.StringIO() + stdout = StringIO() self.run_collectstatic(stdout=stdout, verbosity=2) output = force_text(stdout.getvalue()) self.assertIn("Skipping 'test.txt' (not modified)", output) diff --git a/tests/staticfiles_tests/test_storage.py b/tests/staticfiles_tests/test_storage.py index 6333be754926..e299feea78de 100644 --- a/tests/staticfiles_tests/test_storage.py +++ b/tests/staticfiles_tests/test_storage.py @@ -3,6 +3,7 @@ import sys import tempfile import unittest +from io import StringIO from django.conf import settings from django.contrib.staticfiles import finders, storage @@ -11,7 +12,6 @@ from django.core.cache.backends.base import BaseCache from django.core.management import call_command from django.test import override_settings -from django.utils import six from django.utils.encoding import force_text from .cases import CollectionTestCase @@ -172,7 +172,7 @@ def test_template_tag_url(self): ) def test_import_loop(self): finders.get_finder.cache_clear() - err = six.StringIO() + err = StringIO() with self.assertRaisesMessage(RuntimeError, 'Max post-process passes exceeded'): call_command('collectstatic', interactive=False, verbosity=0, stderr=err) self.assertEqual("Post-processing 'All' failed!\n\n", err.getvalue()) @@ -225,7 +225,7 @@ def test_post_processing_failure(self): post_processing indicates the origin of the error when it fails. """ finders.get_finder.cache_clear() - err = six.StringIO() + err = StringIO() with self.assertRaises(Exception): call_command('collectstatic', interactive=False, verbosity=0, stderr=err) self.assertEqual("Post-processing 'faulty.css' failed!\n\n", err.getvalue()) @@ -429,7 +429,7 @@ def test_missing_entry(self): with self.assertRaisesMessage(ValueError, err_msg): self.hashed_file_path(missing_file_name) - content = six.StringIO() + content = StringIO() content.write('Found') configured_storage.save(missing_file_name, content) # File exists on disk @@ -566,7 +566,7 @@ def tearDown(self): def test_file_change_after_collectstatic(self): finders.get_finder.cache_clear() - err = six.StringIO() + err = StringIO() call_command('collectstatic', interactive=False, verbosity=0, stderr=err) with open(self.testimage_path, 'w+b') as f: f.write(b"new content of png file to change it's hash") diff --git a/tests/swappable_models/tests.py b/tests/swappable_models/tests.py index b67aece8c087..e9d15db01537 100644 --- a/tests/swappable_models/tests.py +++ b/tests/swappable_models/tests.py @@ -1,10 +1,11 @@ -from swappable_models.models import Article +from io import StringIO from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType from django.core import management from django.test import TestCase, override_settings -from django.utils.six import StringIO + +from .models import Article class SwappableModelTests(TestCase): diff --git a/tests/template_tests/syntax_tests/test_static.py b/tests/template_tests/syntax_tests/test_static.py index deb0ce6c7836..345f943cafdd 100644 --- a/tests/template_tests/syntax_tests/test_static.py +++ b/tests/template_tests/syntax_tests/test_static.py @@ -1,6 +1,7 @@ +from urllib.parse import urljoin + from django.conf import settings from django.test import SimpleTestCase, override_settings -from django.utils.six.moves.urllib.parse import urljoin from ..utils import setup diff --git a/tests/template_tests/templatetags/custom.py b/tests/template_tests/templatetags/custom.py index 363e7094cec0..485f49a82d0d 100644 --- a/tests/template_tests/templatetags/custom.py +++ b/tests/template_tests/templatetags/custom.py @@ -2,7 +2,6 @@ from django import template from django.template.defaultfilters import stringfilter -from django.utils import six from django.utils.html import escape, format_html register = template.Library() @@ -114,7 +113,7 @@ def simple_only_unlimited_args(*args): def simple_unlimited_args_kwargs(one, two='hi', *args, **kwargs): """Expected simple_unlimited_args_kwargs __doc__""" # Sort the dictionary by key to guarantee the order for testing. - sorted_kwarg = sorted(six.iteritems(kwargs), key=operator.itemgetter(0)) + sorted_kwarg = sorted(kwargs.items(), key=operator.itemgetter(0)) return "simple_unlimited_args_kwargs - Expected result: %s / %s" % ( ', '.join(str(arg) for arg in [one, two] + list(args)), ', '.join('%s=%s' % (k, v) for (k, v) in sorted_kwarg) diff --git a/tests/template_tests/templatetags/inclusion.py b/tests/template_tests/templatetags/inclusion.py index 745dd7ffae83..60f654ec00d7 100644 --- a/tests/template_tests/templatetags/inclusion.py +++ b/tests/template_tests/templatetags/inclusion.py @@ -1,7 +1,6 @@ import operator from django.template import Engine, Library -from django.utils import six engine = Engine(app_dirs=True) register = Library() @@ -215,7 +214,7 @@ def inclusion_tag_use_l10n(context): def inclusion_unlimited_args_kwargs(one, two='hi', *args, **kwargs): """Expected inclusion_unlimited_args_kwargs __doc__""" # Sort the dictionary by key to guarantee the order for testing. - sorted_kwarg = sorted(six.iteritems(kwargs), key=operator.itemgetter(0)) + sorted_kwarg = sorted(kwargs.items(), key=operator.itemgetter(0)) return {"result": "inclusion_unlimited_args_kwargs - Expected result: %s / %s" % ( ', '.join(str(arg) for arg in [one, two] + list(args)), ', '.join('%s=%s' % (k, v) for (k, v) in sorted_kwarg) diff --git a/tests/test_client/views.py b/tests/test_client/views.py index af30c4283d7e..e9a28449ec72 100644 --- a/tests/test_client/views.py +++ b/tests/test_client/views.py @@ -1,3 +1,4 @@ +from urllib.parse import urlencode from xml.dom.minidom import parseString from django.contrib.auth.decorators import login_required, permission_required @@ -13,7 +14,6 @@ from django.template import Context, Template from django.test import Client from django.utils.decorators import method_decorator -from django.utils.six.moves.urllib.parse import urlencode def get_view(request): diff --git a/tests/test_client_regress/views.py b/tests/test_client_regress/views.py index ce60c0398c8d..854cdc3bc0af 100644 --- a/tests/test_client_regress/views.py +++ b/tests/test_client_regress/views.py @@ -1,4 +1,5 @@ import json +from urllib.parse import urlencode from django.conf import settings from django.contrib.auth.decorators import login_required @@ -8,7 +9,6 @@ from django.template.loader import render_to_string from django.test import Client from django.test.client import CONTENT_TYPE_RE -from django.utils.six.moves.urllib.parse import urlencode class CustomTestException(Exception): diff --git a/tests/test_runner/test_debug_sql.py b/tests/test_runner/test_debug_sql.py index c6b9b01dbc14..1b36fbc8765b 100644 --- a/tests/test_runner/test_debug_sql.py +++ b/tests/test_runner/test_debug_sql.py @@ -1,10 +1,10 @@ import sys import unittest +from io import StringIO from django.db import connection from django.test import TestCase from django.test.runner import DiscoverRunner -from django.utils import six from .models import Person @@ -33,7 +33,7 @@ def _test_output(self, verbosity): suite.addTest(self.ErrorTest()) suite.addTest(self.PassingTest()) old_config = runner.setup_databases() - stream = six.StringIO() + stream = StringIO() resultclass = runner.get_resultclass() runner.test_runner( verbosity=verbosity, diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py index 4d29f1a491d8..f8eda7ed3925 100644 --- a/tests/test_utils/tests.py +++ b/tests/test_utils/tests.py @@ -1,5 +1,6 @@ import sys import unittest +from io import StringIO from django.conf.urls import url from django.contrib.staticfiles.finders import get_finder, get_finders @@ -18,7 +19,6 @@ setup_test_environment, ) from django.urls import NoReverseMatch, reverse -from django.utils import six from django.utils._os import abspathu from .models import Car, Person, PossessedCar @@ -117,7 +117,7 @@ class SkippedTestsSubclass(SkippedTests): test_suite.addTest(SkippedTestsSubclass('test_will_be_skipped')) except unittest.SkipTest: self.fail("SkipTest should not be raised at this stage") - result = unittest.TextTestRunner(stream=six.StringIO()).run(test_suite) + result = unittest.TextTestRunner(stream=StringIO()).run(test_suite) self.assertEqual(result.testsRun, 3) self.assertEqual(len(result.skipped), 2) self.assertEqual(result.skipped[0][1], 'Database has feature(s) __class__') diff --git a/tests/timezones/tests.py b/tests/timezones/tests.py index 7f7c8228e810..e5a67f745ec9 100644 --- a/tests/timezones/tests.py +++ b/tests/timezones/tests.py @@ -23,7 +23,7 @@ ) from django.test.utils import requires_tz_support from django.urls import reverse -from django.utils import six, timezone +from django.utils import timezone from django.utils.timezone import timedelta from .forms import ( @@ -888,8 +888,8 @@ def t(*result): } } - for k1, dt in six.iteritems(datetimes): - for k2, tpl in six.iteritems(templates): + for k1, dt in datetimes.items(): + for k2, tpl in templates.items(): ctx = Context({'dt': dt, 'ICT': ICT}) actual = tpl.render(ctx) expected = results[k1][k2] @@ -901,8 +901,8 @@ def t(*result): results['ict']['notag'] = t('ict', 'eat', 'utc', 'ict') with self.settings(USE_TZ=False): - for k1, dt in six.iteritems(datetimes): - for k2, tpl in six.iteritems(templates): + for k1, dt in datetimes.items(): + for k2, tpl in templates.items(): ctx = Context({'dt': dt, 'ICT': ICT}) actual = tpl.render(ctx) expected = results[k1][k2] diff --git a/tests/user_commands/tests.py b/tests/user_commands/tests.py index 4e4f5dc91197..cfc4f5fb2e56 100644 --- a/tests/user_commands/tests.py +++ b/tests/user_commands/tests.py @@ -1,4 +1,5 @@ import os +from io import StringIO from admin_scripts.tests import AdminScriptTestCase @@ -11,7 +12,6 @@ from django.test.utils import captured_stderr, extend_sys_path from django.utils import translation from django.utils._os import upath -from django.utils.six import StringIO from .management.commands import dance diff --git a/tests/utils_tests/test_autoreload.py b/tests/utils_tests/test_autoreload.py index 5d42af62c8f4..4036df8dd84a 100644 --- a/tests/utils_tests/test_autoreload.py +++ b/tests/utils_tests/test_autoreload.py @@ -4,13 +4,14 @@ import tempfile from importlib import import_module +import _thread + from django import conf from django.contrib import admin from django.test import SimpleTestCase, mock, override_settings from django.test.utils import extend_sys_path from django.utils import autoreload from django.utils._os import npath -from django.utils.six.moves import _thread from django.utils.translation import trans_real LOCALE_PATH = os.path.join(os.path.dirname(__file__), 'locale') diff --git a/tests/utils_tests/test_baseconv.py b/tests/utils_tests/test_baseconv.py index 538189bbe62a..948b991ad3c5 100644 --- a/tests/utils_tests/test_baseconv.py +++ b/tests/utils_tests/test_baseconv.py @@ -3,7 +3,6 @@ from django.utils.baseconv import ( BaseConverter, base2, base16, base36, base56, base62, base64, ) -from django.utils.six.moves import range class TestBaseConv(TestCase): diff --git a/tests/utils_tests/test_datastructures.py b/tests/utils_tests/test_datastructures.py index f917a2ae4e52..df7020eac576 100644 --- a/tests/utils_tests/test_datastructures.py +++ b/tests/utils_tests/test_datastructures.py @@ -5,7 +5,6 @@ import copy from django.test import SimpleTestCase -from django.utils import six from django.utils.datastructures import ( DictWrapper, ImmutableList, MultiValueDict, MultiValueDictKeyError, OrderedSet, @@ -40,12 +39,12 @@ def test_multivaluedict(self): self.assertEqual(d.get('name'), 'Simon') self.assertEqual(d.getlist('name'), ['Adrian', 'Simon']) self.assertEqual( - sorted(six.iteritems(d)), + sorted(d.items()), [('name', 'Simon'), ('position', 'Developer')] ) self.assertEqual( - sorted(six.iterlists(d)), + sorted(d.lists()), [('name', ['Adrian', 'Simon']), ('position', ['Developer'])] ) @@ -60,8 +59,7 @@ def test_multivaluedict(self): d.setlist('lastname', ['Holovaty', 'Willison']) self.assertEqual(d.getlist('lastname'), ['Holovaty', 'Willison']) - self.assertEqual(sorted(six.itervalues(d)), - ['Developer', 'Simon', 'Willison']) + self.assertEqual(sorted(d.values()), ['Developer', 'Simon', 'Willison']) def test_appendlist(self): d = MultiValueDict() @@ -95,8 +93,8 @@ def test_dict_translation(self): 'pm': ['Rory'], }) d = mvd.dict() - self.assertEqual(sorted(six.iterkeys(d)), sorted(six.iterkeys(mvd))) - for key in six.iterkeys(mvd): + self.assertEqual(sorted(d.keys()), sorted(mvd.keys())) + for key in mvd.keys(): self.assertEqual(d[key], mvd[key]) self.assertEqual({}, MultiValueDict().dict()) diff --git a/tests/utils_tests/test_lazyobject.py b/tests/utils_tests/test_lazyobject.py index 8c9b997b3c3a..513123ea004f 100644 --- a/tests/utils_tests/test_lazyobject.py +++ b/tests/utils_tests/test_lazyobject.py @@ -4,7 +4,6 @@ import warnings from unittest import TestCase -from django.utils import six from django.utils.functional import LazyObject, SimpleLazyObject, empty from .models import Category, CategoryInfo @@ -300,7 +299,7 @@ def test_repr(self): obj = self.lazy_wrap(42) # __repr__ contains __repr__ of setup function and does not evaluate # the SimpleLazyObject - six.assertRegex(self, repr(obj), '^ Date: Wed, 18 Jan 2017 21:30:21 +0100 Subject: [PATCH 0065/3180] Refs #23919 -- Stopped using django.utils.lru_cache(). --- django/apps/registry.py | 6 +- django/conf/urls/i18n.py | 5 +- django/contrib/auth/hashers.py | 6 +- django/contrib/auth/password_validation.py | 4 +- django/contrib/staticfiles/finders.py | 4 +- django/core/management/__init__.py | 5 +- django/core/management/color.py | 5 +- django/core/management/commands/loaddata.py | 4 +- django/db/models/fields/related.py | 4 +- django/db/models/query_utils.py | 4 +- django/forms/renderers.py | 4 +- django/template/engine.py | 5 +- django/template/utils.py | 4 +- django/urls/resolvers.py | 5 +- django/urls/utils.py | 4 +- django/utils/lru_cache.py | 175 +------------------- django/utils/timezone.py | 4 +- django/utils/translation/trans_real.py | 8 +- django/utils/version.py | 5 +- django/views/debug.py | 5 +- setup.cfg | 2 +- 21 files changed, 52 insertions(+), 216 deletions(-) diff --git a/django/apps/registry.py b/django/apps/registry.py index 453e4d42f623..c67c5ee0baa8 100644 --- a/django/apps/registry.py +++ b/django/apps/registry.py @@ -1,3 +1,4 @@ +import functools import sys import threading import warnings @@ -5,7 +6,6 @@ from functools import partial from django.core.exceptions import AppRegistryNotReady, ImproperlyConfigured -from django.utils import lru_cache from .config import AppConfig @@ -156,7 +156,7 @@ def get_app_config(self, app_label): raise LookupError(message) # This method is performance-critical at least for Django's test suite. - @lru_cache.lru_cache(maxsize=None) + @functools.lru_cache(maxsize=None) def get_models(self, include_auto_created=False, include_swapped=False): """ Returns a list of all installed models. @@ -268,7 +268,7 @@ def get_registered_model(self, app_label, model_name): "Model '%s.%s' not registered." % (app_label, model_name)) return model - @lru_cache.lru_cache(maxsize=None) + @functools.lru_cache(maxsize=None) def get_swappable_settings_name(self, to_string): """ For a given model string (e.g. "auth.User"), return the name of the diff --git a/django/conf/urls/i18n.py b/django/conf/urls/i18n.py index 14f4c6971b0c..23e4bbcd74bb 100644 --- a/django/conf/urls/i18n.py +++ b/django/conf/urls/i18n.py @@ -1,7 +1,8 @@ +import functools + from django.conf import settings from django.conf.urls import url from django.urls import LocaleRegexURLResolver, get_resolver -from django.utils import lru_cache from django.views.i18n import set_language @@ -18,7 +19,7 @@ def i18n_patterns(*urls, **kwargs): return [LocaleRegexURLResolver(list(urls), prefix_default_language=prefix_default_language)] -@lru_cache.lru_cache(maxsize=None) +@functools.lru_cache(maxsize=None) def is_language_prefix_patterns_used(urlconf): """ Return a tuple of two booleans: ( diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py index 4b8b12782e8b..871519257afe 100644 --- a/django/contrib/auth/hashers.py +++ b/django/contrib/auth/hashers.py @@ -1,5 +1,6 @@ import base64 import binascii +import functools import hashlib import importlib import warnings @@ -9,7 +10,6 @@ from django.core.exceptions import ImproperlyConfigured from django.core.signals import setting_changed from django.dispatch import receiver -from django.utils import lru_cache from django.utils.crypto import ( constant_time_compare, get_random_string, pbkdf2, ) @@ -82,7 +82,7 @@ def make_password(password, salt=None, hasher='default'): return hasher.encode(password, salt) -@lru_cache.lru_cache() +@functools.lru_cache() def get_hashers(): hashers = [] for hasher_path in settings.PASSWORD_HASHERS: @@ -95,7 +95,7 @@ def get_hashers(): return hashers -@lru_cache.lru_cache() +@functools.lru_cache() def get_hashers_by_algorithm(): return {hasher.algorithm: hasher for hasher in get_hashers()} diff --git a/django/contrib/auth/password_validation.py b/django/contrib/auth/password_validation.py index 1cf32e021988..dee1ebf67476 100644 --- a/django/contrib/auth/password_validation.py +++ b/django/contrib/auth/password_validation.py @@ -1,3 +1,4 @@ +import functools import gzip import os import re @@ -7,7 +8,6 @@ from django.core.exceptions import ( FieldDoesNotExist, ImproperlyConfigured, ValidationError, ) -from django.utils import lru_cache from django.utils._os import upath from django.utils.encoding import force_text from django.utils.functional import lazy @@ -16,7 +16,7 @@ from django.utils.translation import ugettext as _, ungettext -@lru_cache.lru_cache(maxsize=None) +@functools.lru_cache(maxsize=None) def get_default_password_validators(): return get_password_validators(settings.AUTH_PASSWORD_VALIDATORS) diff --git a/django/contrib/staticfiles/finders.py b/django/contrib/staticfiles/finders.py index c3da95ddd3bc..96dd705050a4 100644 --- a/django/contrib/staticfiles/finders.py +++ b/django/contrib/staticfiles/finders.py @@ -1,3 +1,4 @@ +import functools import os from collections import OrderedDict @@ -8,7 +9,6 @@ from django.core.files.storage import ( FileSystemStorage, Storage, default_storage, ) -from django.utils import lru_cache from django.utils._os import safe_join from django.utils.functional import LazyObject, empty from django.utils.module_loading import import_string @@ -264,7 +264,7 @@ def get_finders(): yield get_finder(finder_path) -@lru_cache.lru_cache(maxsize=None) +@functools.lru_cache(maxsize=None) def get_finder(import_path): """ Imports the staticfiles finder class described by import_path, where diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py index 00ee58a34be9..0200f77e7d08 100644 --- a/django/core/management/__init__.py +++ b/django/core/management/__init__.py @@ -1,3 +1,4 @@ +import functools import os import pkgutil import sys @@ -12,7 +13,7 @@ BaseCommand, CommandError, CommandParser, handle_default_options, ) from django.core.management.color import color_style -from django.utils import autoreload, lru_cache +from django.utils import autoreload from django.utils._os import npath, upath from django.utils.encoding import force_text @@ -39,7 +40,7 @@ class instance. All errors raised by the import process return module.Command() -@lru_cache.lru_cache(maxsize=None) +@functools.lru_cache(maxsize=None) def get_commands(): """ Returns a dictionary mapping command names to their callback applications. diff --git a/django/core/management/color.py b/django/core/management/color.py index 7a3237086086..76985420cba9 100644 --- a/django/core/management/color.py +++ b/django/core/management/color.py @@ -2,10 +2,11 @@ Sets up the terminal color scheme. """ +import functools import os import sys -from django.utils import lru_cache, termcolors +from django.utils import termcolors def supports_color(): @@ -57,7 +58,7 @@ def style_func(x): return style -@lru_cache.lru_cache(maxsize=None) +@functools.lru_cache(maxsize=None) def no_style(): """ Returns a Style object with no color scheme. diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index 9f71400862a2..9edd642b433c 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -1,3 +1,4 @@ +import functools import glob import gzip import os @@ -16,7 +17,6 @@ DEFAULT_DB_ALIAS, DatabaseError, IntegrityError, connections, router, transaction, ) -from django.utils import lru_cache from django.utils._os import upath from django.utils.encoding import force_text from django.utils.functional import cached_property @@ -202,7 +202,7 @@ def load_label(self, fixture_label): RuntimeWarning ) - @lru_cache.lru_cache(maxsize=None) + @functools.lru_cache(maxsize=None) def find_fixtures(self, fixture_label): """ Finds fixture files for a given label. diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 65d0da41e170..b5dd0a2d14b0 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -1,3 +1,4 @@ +import functools import inspect from functools import partial @@ -13,7 +14,6 @@ from django.db.models.utils import make_model_tuple from django.utils.encoding import force_text from django.utils.functional import cached_property, curry -from django.utils.lru_cache import lru_cache from django.utils.translation import ugettext_lazy as _ from . import Field @@ -710,7 +710,7 @@ def get_reverse_path_info(self): return pathinfos @classmethod - @lru_cache(maxsize=None) + @functools.lru_cache(maxsize=None) def get_lookups(cls): bases = inspect.getmro(cls) bases = bases[:bases.index(ForeignObject) + 1] diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py index 112c9586d071..03d133e72409 100644 --- a/django/db/models/query_utils.py +++ b/django/db/models/query_utils.py @@ -5,12 +5,12 @@ large and/or so that they can be used by other modules without getting into circular import difficulties. """ +import functools import inspect from collections import namedtuple from django.db.models.constants import LOOKUP_SEP from django.utils import tree -from django.utils.lru_cache import lru_cache # PathInfo is used when converting lookups (fk__somecol). The contents # describe the relation in Model terms (model Options and Fields for both @@ -137,7 +137,7 @@ def _get_lookup(cls, lookup_name): return cls.get_lookups().get(lookup_name, None) @classmethod - @lru_cache(maxsize=None) + @functools.lru_cache(maxsize=None) def get_lookups(cls): class_lookups = [parent.__dict__.get('class_lookups', {}) for parent in inspect.getmro(cls)] return cls.merge_dicts(class_lookups) diff --git a/django/forms/renderers.py b/django/forms/renderers.py index d0b3c3e2db08..2c31d7adc5a7 100644 --- a/django/forms/renderers.py +++ b/django/forms/renderers.py @@ -1,9 +1,9 @@ +import functools import os from django.conf import settings from django.template.backends.django import DjangoTemplates from django.template.loader import get_template -from django.utils import lru_cache from django.utils._os import upath from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -17,7 +17,7 @@ def Jinja2(params): ROOT = upath(os.path.dirname(__file__)) -@lru_cache.lru_cache() +@functools.lru_cache() def get_default_renderer(): renderer_class = import_string(settings.FORM_RENDERER) return renderer_class() diff --git a/django/template/engine.py b/django/template/engine.py index 6d73569e0221..d334926c45e8 100644 --- a/django/template/engine.py +++ b/django/template/engine.py @@ -1,5 +1,6 @@ +import functools + from django.core.exceptions import ImproperlyConfigured -from django.utils import lru_cache from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -52,7 +53,7 @@ def __init__(self, dirs=None, app_dirs=False, context_processors=None, self.template_builtins = self.get_template_builtins(self.builtins) @staticmethod - @lru_cache.lru_cache() + @functools.lru_cache() def get_default(): """ When only one DjangoTemplates backend is configured, returns it. diff --git a/django/template/utils.py b/django/template/utils.py index 3c7b3c98ace8..6ff2499dcbf5 100644 --- a/django/template/utils.py +++ b/django/template/utils.py @@ -1,10 +1,10 @@ +import functools import os from collections import Counter, OrderedDict from django.apps import apps from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from django.utils import lru_cache from django.utils._os import upath from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -89,7 +89,7 @@ def all(self): return [self[alias] for alias in self] -@lru_cache.lru_cache() +@functools.lru_cache() def get_app_template_dirs(dirname): """ Return an iterable of paths of directories to load app templates from. diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py index cf2fe0ecec69..7e344896af0b 100644 --- a/django/urls/resolvers.py +++ b/django/urls/resolvers.py @@ -14,7 +14,6 @@ from django.core.checks import Warning from django.core.checks.urls import check_resolver from django.core.exceptions import ImproperlyConfigured -from django.utils import lru_cache from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_str, force_text from django.utils.functional import cached_property @@ -60,7 +59,7 @@ def __repr__(self): ) -@lru_cache.lru_cache(maxsize=None) +@functools.lru_cache(maxsize=None) def get_resolver(urlconf=None): if urlconf is None: from django.conf import settings @@ -68,7 +67,7 @@ def get_resolver(urlconf=None): return RegexURLResolver(r'^/', urlconf) -@lru_cache.lru_cache(maxsize=None) +@functools.lru_cache(maxsize=None) def get_ns_resolver(ns_pattern, resolver): # Build a namespaced resolver for the given parent URLconf pattern. # This makes it possible to have captured parameters in the parent diff --git a/django/urls/utils.py b/django/urls/utils.py index 3cf5439e77f8..e59ab9fdbd0f 100644 --- a/django/urls/utils.py +++ b/django/urls/utils.py @@ -1,11 +1,11 @@ +import functools from importlib import import_module from django.core.exceptions import ViewDoesNotExist -from django.utils import lru_cache from django.utils.module_loading import module_has_submodule -@lru_cache.lru_cache(maxsize=None) +@functools.lru_cache(maxsize=None) def get_callable(lookup_view): """ Return a callable corresponding to lookup_view. diff --git a/django/utils/lru_cache.py b/django/utils/lru_cache.py index 543296e64815..f5187ded565e 100644 --- a/django/utils/lru_cache.py +++ b/django/utils/lru_cache.py @@ -1,172 +1,5 @@ -try: - from functools import lru_cache +from functools import lru_cache # noqa -except ImportError: - # backport of Python's 3.3 lru_cache, written by Raymond Hettinger and - # licensed under MIT license, from: - # - # Should be removed when Django only supports Python 3.2 and above. - - from collections import namedtuple - from functools import update_wrapper - from threading import RLock - - _CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"]) - - class _HashedSeq(list): - __slots__ = 'hashvalue' - - def __init__(self, tup, hash=hash): - self[:] = tup - self.hashvalue = hash(tup) - - def __hash__(self): - return self.hashvalue - - def _make_key(args, kwds, typed, - kwd_mark = (object(),), - fasttypes = {int, str, frozenset, type(None)}, - sorted=sorted, tuple=tuple, type=type, len=len): - 'Make a cache key from optionally typed positional and keyword arguments' - key = args - if kwds: - sorted_items = sorted(kwds.items()) - key += kwd_mark - for item in sorted_items: - key += item - if typed: - key += tuple(type(v) for v in args) - if kwds: - key += tuple(type(v) for k, v in sorted_items) - elif len(key) == 1 and type(key[0]) in fasttypes: - return key[0] - return _HashedSeq(key) - - def lru_cache(maxsize=100, typed=False): - """Least-recently-used cache decorator. - - If *maxsize* is set to None, the LRU features are disabled and the cache - can grow without bound. - - If *typed* is True, arguments of different types will be cached separately. - For example, f(3.0) and f(3) will be treated as distinct calls with - distinct results. - - Arguments to the cached function must be hashable. - - View the cache statistics named tuple (hits, misses, maxsize, currsize) with - f.cache_info(). Clear the cache and statistics with f.cache_clear(). - Access the underlying function with f.__wrapped__. - - See: https://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used - """ - - # Users should only access the lru_cache through its public API: - # cache_info, cache_clear, and f.__wrapped__ - # The internals of the lru_cache are encapsulated for thread safety and - # to allow the implementation to change (including a possible C version). - - def decorating_function(user_function): - - cache = dict() - stats = [0, 0] # make statistics updateable non-locally - HITS, MISSES = 0, 1 # names for the stats fields - make_key = _make_key - cache_get = cache.get # bound method to lookup key or return None - _len = len # localize the global len() function - lock = RLock() # because linkedlist updates aren't threadsafe - root = [] # root of the circular doubly linked list - root[:] = [root, root, None, None] # initialize by pointing to self - nonlocal_root = [root] # make updateable non-locally - PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields - - if maxsize == 0: - - def wrapper(*args, **kwds): - # no caching, just do a statistics update after a successful call - result = user_function(*args, **kwds) - stats[MISSES] += 1 - return result - - elif maxsize is None: - - def wrapper(*args, **kwds): - # simple caching without ordering or size limit - key = make_key(args, kwds, typed) - result = cache_get(key, root) # root used here as a unique not-found sentinel - if result is not root: - stats[HITS] += 1 - return result - result = user_function(*args, **kwds) - cache[key] = result - stats[MISSES] += 1 - return result - - else: - - def wrapper(*args, **kwds): - # size limited caching that tracks accesses by recency - key = make_key(args, kwds, typed) if kwds or typed else args - with lock: - link = cache_get(key) - if link is not None: - # record recent use of the key by moving it to the front of the list - root, = nonlocal_root - link_prev, link_next, key, result = link - link_prev[NEXT] = link_next - link_next[PREV] = link_prev - last = root[PREV] - last[NEXT] = root[PREV] = link - link[PREV] = last - link[NEXT] = root - stats[HITS] += 1 - return result - result = user_function(*args, **kwds) - with lock: - root, = nonlocal_root - if key in cache: - # getting here means that this same key was added to the - # cache while the lock was released. since the link - # update is already done, we need only return the - # computed result and update the count of misses. - pass - elif _len(cache) >= maxsize: - # use the old root to store the new key and result - oldroot = root - oldroot[KEY] = key - oldroot[RESULT] = result - # empty the oldest link and make it the new root - root = nonlocal_root[0] = oldroot[NEXT] - oldkey = root[KEY] - oldvalue = root[RESULT] - root[KEY] = root[RESULT] = None - # now update the cache dictionary for the new links - del cache[oldkey] - cache[key] = oldroot - else: - # put result in a new link at the front of the list - last = root[PREV] - link = [last, root, key, result] - last[NEXT] = root[PREV] = cache[key] = link - stats[MISSES] += 1 - return result - - def cache_info(): - """Report cache statistics""" - with lock: - return _CacheInfo(stats[HITS], stats[MISSES], maxsize, len(cache)) - - def cache_clear(): - """Clear the cache and cache statistics""" - with lock: - cache.clear() - root = nonlocal_root[0] - root[:] = [root, root, None, None] - stats[:] = [0, 0] - - wrapper.__wrapped__ = user_function - wrapper.cache_info = cache_info - wrapper.cache_clear = cache_clear - return update_wrapper(wrapper, user_function) - - return decorating_function +# Deprecate or remove this module when no supported version of Django still +# supports Python 2. Until then, keep it to allow pluggable apps to support +# Python 2 and Python 3 without raising a deprecation warning. diff --git a/django/utils/timezone.py b/django/utils/timezone.py index 992e80086ab9..66bfa00030a8 100644 --- a/django/utils/timezone.py +++ b/django/utils/timezone.py @@ -2,13 +2,13 @@ Timezone-related classes and functions. """ +import functools from datetime import datetime, timedelta, tzinfo from threading import local import pytz from django.conf import settings -from django.utils import lru_cache from django.utils.decorators import ContextDecorator __all__ = [ @@ -69,7 +69,7 @@ def get_fixed_timezone(offset): # In order to avoid accessing settings at compile time, # wrap the logic in a function and cache the result. -@lru_cache.lru_cache() +@functools.lru_cache() def get_default_timezone(): """ Returns the default time zone as a tzinfo instance. diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py index aca57ded0ebd..99acda9aabc5 100644 --- a/django/utils/translation/trans_real.py +++ b/django/utils/translation/trans_real.py @@ -1,4 +1,5 @@ """Translation helper functions.""" +import functools import gettext as gettext_module import os import re @@ -13,7 +14,6 @@ from django.core.exceptions import AppRegistryNotReady from django.core.signals import setting_changed from django.dispatch import receiver -from django.utils import lru_cache from django.utils._os import upath from django.utils.encoding import force_text from django.utils.safestring import SafeData, mark_safe @@ -403,7 +403,7 @@ def all_locale_paths(): return [globalpath] + list(settings.LOCALE_PATHS) -@lru_cache.lru_cache(maxsize=1000) +@functools.lru_cache(maxsize=1000) def check_for_language(lang_code): """ Checks whether there is a global language file for the given language @@ -423,7 +423,7 @@ def check_for_language(lang_code): return False -@lru_cache.lru_cache() +@functools.lru_cache() def get_languages(): """ Cache of settings.LANGUAGES in an OrderedDict for easy lookups by key. @@ -431,7 +431,7 @@ def get_languages(): return OrderedDict(settings.LANGUAGES) -@lru_cache.lru_cache(maxsize=1000) +@functools.lru_cache(maxsize=1000) def get_supported_language_variant(lang_code, strict=False): """ Returns the language-code that's listed in supported languages, possibly diff --git a/django/utils/version.py b/django/utils/version.py index dcf0c2186644..e9666f906e1a 100644 --- a/django/utils/version.py +++ b/django/utils/version.py @@ -1,9 +1,8 @@ import datetime +import functools import os import subprocess -from django.utils.lru_cache import lru_cache - def get_version(version=None): "Returns a PEP 440-compliant version number from VERSION." @@ -57,7 +56,7 @@ def get_docs_version(version=None): return '%d.%d' % version[:2] -@lru_cache() +@functools.lru_cache() def get_git_changeset(): """Returns a numeric identifier of the latest git changeset. diff --git a/django/views/debug.py b/django/views/debug.py index de8c4319bfc5..b457969427f6 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -1,3 +1,4 @@ +import functools import re import sys import types @@ -7,7 +8,7 @@ from django.template import Context, Engine, TemplateDoesNotExist from django.template.defaultfilters import force_escape, pprint from django.urls import Resolver404, resolve -from django.utils import lru_cache, timezone +from django.utils import timezone from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_bytes, force_text from django.utils.module_loading import import_string @@ -83,7 +84,7 @@ def technical_500_response(request, exc_type, exc_value, tb, status_code=500): return HttpResponse(html, status=status_code, content_type='text/html') -@lru_cache.lru_cache() +@functools.lru_cache() def get_default_exception_reporter_filter(): # Instantiate the default filter for the first time and cache it. return import_string(settings.DEFAULT_EXCEPTION_REPORTER_FILTER)() diff --git a/setup.cfg b/setup.cfg index c1ff45c56a9b..726bddb3af4e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,7 +3,7 @@ doc_files = docs extras AUTHORS INSTALL LICENSE README.rst install-script = scripts/rpm-install.sh [flake8] -exclude = build,.git,.tox,./django/utils/lru_cache.py,./django/utils/six.py,./django/conf/app_template/*,./tests/.env,./xmlrunner +exclude = build,.git,.tox,./django/utils/six.py,./django/conf/app_template/*,./tests/.env,./xmlrunner ignore = W601 max-line-length = 119 From eb422e476f3c0070dbf200bd62d97d12150c6fd9 Mon Sep 17 00:00:00 2001 From: Aymeric Augustin Date: Wed, 18 Jan 2017 21:35:59 +0100 Subject: [PATCH 0066/3180] Refs #23919 -- Removed obsolete __ne__() methods. __ne__() defaults to the opposite of __eq__() on Python 3 when it doesn't return NotImplemented. --- django/contrib/auth/models.py | 3 --- django/contrib/gis/gdal/geometries.py | 4 ---- django/contrib/gis/gdal/geomtype.py | 3 --- django/contrib/gis/geos/geometry.py | 4 ---- django/contrib/postgres/validators.py | 3 --- django/core/cache/__init__.py | 3 --- django/core/checks/messages.py | 3 --- django/core/validators.py | 3 --- django/db/__init__.py | 3 --- django/db/migrations/migration.py | 3 --- django/db/migrations/state.py | 6 ------ django/db/models/base.py | 3 --- django/db/models/fields/files.py | 3 --- django/db/models/indexes.py | 3 --- django/db/models/manager.py | 3 --- django/forms/utils.py | 3 --- django/template/base.py | 3 --- django/test/html.py | 3 --- django/utils/functional.py | 5 ----- 19 files changed, 64 deletions(-) diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index 0fc2ab41dac5..9eaf7a6e34d7 100644 --- a/django/contrib/auth/models.py +++ b/django/contrib/auth/models.py @@ -391,9 +391,6 @@ def __str__(self): def __eq__(self, other): return isinstance(other, self.__class__) - def __ne__(self, other): - return not self.__eq__(other) - def __hash__(self): return 1 # instances always return the same hash value diff --git a/django/contrib/gis/gdal/geometries.py b/django/contrib/gis/gdal/geometries.py index 50c1d9ff65c9..1dd85ac1397d 100644 --- a/django/contrib/gis/gdal/geometries.py +++ b/django/contrib/gis/gdal/geometries.py @@ -179,10 +179,6 @@ def __eq__(self, other): else: return False - def __ne__(self, other): - "Tests for inequality." - return not (self == other) - def __str__(self): "WKT is used for the string representation." return self.wkt diff --git a/django/contrib/gis/gdal/geomtype.py b/django/contrib/gis/gdal/geomtype.py index 79c3356f5ea7..37539c85443b 100644 --- a/django/contrib/gis/gdal/geomtype.py +++ b/django/contrib/gis/gdal/geomtype.py @@ -68,9 +68,6 @@ def __eq__(self, other): else: return False - def __ne__(self, other): - return not (self == other) - @property def name(self): "Returns a short-hand string form of the OGR Geometry type." diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py index f49ce2e0defb..e015fdc3d52a 100644 --- a/django/contrib/gis/geos/geometry.py +++ b/django/contrib/gis/geos/geometry.py @@ -177,10 +177,6 @@ def __eq__(self, other): else: return False - def __ne__(self, other): - "The not equals operator." - return not (self == other) - # ### Geometry set-like operations ### # Thanks to Sean Gillies for inspiration: # http://lists.gispython.org/pipermail/community/2007-July/001034.html diff --git a/django/contrib/postgres/validators.py b/django/contrib/postgres/validators.py index 5676da78b0fa..756ae7344062 100644 --- a/django/contrib/postgres/validators.py +++ b/django/contrib/postgres/validators.py @@ -66,9 +66,6 @@ def __eq__(self, other): self.strict == other.strict ) - def __ne__(self, other): - return not (self == other) - class RangeMaxValueValidator(MaxValueValidator): def compare(self, a, b): diff --git a/django/core/cache/__init__.py b/django/core/cache/__init__.py index cd2bb43886e4..2b253b1077f8 100644 --- a/django/core/cache/__init__.py +++ b/django/core/cache/__init__.py @@ -110,9 +110,6 @@ def __contains__(self, key): def __eq__(self, other): return caches[DEFAULT_CACHE_ALIAS] == other - def __ne__(self, other): - return caches[DEFAULT_CACHE_ALIAS] != other - cache = DefaultCacheProxy() diff --git a/django/core/checks/messages.py b/django/core/checks/messages.py index da198d72b979..5bb292503f7f 100644 --- a/django/core/checks/messages.py +++ b/django/core/checks/messages.py @@ -25,9 +25,6 @@ def __eq__(self, other): for attr in ['level', 'msg', 'hint', 'obj', 'id']) ) - def __ne__(self, other): - return not (self == other) - def __str__(self): from django.db import models diff --git a/django/core/validators.py b/django/core/validators.py index 6e7220c8265f..1bb247812977 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -68,9 +68,6 @@ def __eq__(self, other): (self.inverse_match == other.inverse_match) ) - def __ne__(self, other): - return not (self == other) - @deconstructible class URLValidator(RegexValidator): diff --git a/django/db/__init__.py b/django/db/__init__.py index d25a9f01168c..a00dc788dcef 100644 --- a/django/db/__init__.py +++ b/django/db/__init__.py @@ -41,9 +41,6 @@ def __delattr__(self, name): def __eq__(self, other): return connections[DEFAULT_DB_ALIAS] == other - def __ne__(self, other): - return connections[DEFAULT_DB_ALIAS] != other - connection = DefaultConnectionProxy() diff --git a/django/db/migrations/migration.py b/django/db/migrations/migration.py index d1a24d436180..5b6bb647c9d5 100644 --- a/django/db/migrations/migration.py +++ b/django/db/migrations/migration.py @@ -62,9 +62,6 @@ def __eq__(self, other): return False return (self.name == other.name) and (self.app_label == other.app_label) - def __ne__(self, other): - return not (self == other) - def __repr__(self): return "" % (self.app_label, self.name) diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index db42220918d7..6699b7771357 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -233,9 +233,6 @@ def __eq__(self, other): return False return all(model == other.models[key] for key, model in self.models.items()) - def __ne__(self, other): - return not (self == other) - class AppConfigStub(AppConfig): """ @@ -626,6 +623,3 @@ def __eq__(self, other): (self.bases == other.bases) and (self.managers == other.managers) ) - - def __ne__(self, other): - return not (self == other) diff --git a/django/db/models/base.py b/django/db/models/base.py index b5f6c1e35372..4ee7aa034943 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -520,9 +520,6 @@ def __eq__(self, other): return self is other return my_pk == other._get_pk_val() - def __ne__(self, other): - return not self.__eq__(other) - def __hash__(self): if self._get_pk_val() is None: raise TypeError("Model instances without primary key value are unhashable") diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index 90b65154090e..38dda4c1df2d 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -28,9 +28,6 @@ def __eq__(self, other): return self.name == other.name return self.name == other - def __ne__(self, other): - return not self.__eq__(other) - def __hash__(self): return hash(self.name) diff --git a/django/db/models/indexes.py b/django/db/models/indexes.py index c296f221636c..27390ccc1835 100644 --- a/django/db/models/indexes.py +++ b/django/db/models/indexes.py @@ -117,6 +117,3 @@ def __repr__(self): def __eq__(self, other): return (self.__class__ == other.__class__) and (self.deconstruct() == other.deconstruct()) - - def __ne__(self, other): - return not (self == other) diff --git a/django/db/models/manager.py b/django/db/models/manager.py index 96c82e54ebb6..bb3d61b08387 100644 --- a/django/db/models/manager.py +++ b/django/db/models/manager.py @@ -160,9 +160,6 @@ def __eq__(self, other): self._constructor_args == other._constructor_args ) - def __ne__(self, other): - return not (self == other) - def __hash__(self): return id(self) diff --git a/django/forms/utils.py b/django/forms/utils.py index 3a86f419df7d..59d70178f44b 100644 --- a/django/forms/utils.py +++ b/django/forms/utils.py @@ -133,9 +133,6 @@ def __contains__(self, item): def __eq__(self, other): return list(self) == other - def __ne__(self, other): - return list(self) != other - def __getitem__(self, i): error = self.data[i] if isinstance(error, ValidationError): diff --git a/django/template/base.py b/django/template/base.py index c7c2249aa089..7f18869dbbf8 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -140,9 +140,6 @@ def __eq__(self, other): self.loader == other.loader ) - def __ne__(self, other): - return not self.__eq__(other) - @property def loader_name(self): if self.loader: diff --git a/django/test/html.py b/django/test/html.py index d84b9770e115..67a2ad65e1cd 100644 --- a/django/test/html.py +++ b/django/test/html.py @@ -81,9 +81,6 @@ def __eq__(self, element): def __hash__(self): return hash((self.name,) + tuple(a for a in self.attributes)) - def __ne__(self, element): - return not self.__eq__(element) - def _count(self, element, count=True): if not isinstance(element, str): if self == element: diff --git a/django/utils/functional.py b/django/utils/functional.py index 0efce6c63550..2eeffa044721 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -126,11 +126,6 @@ def __str__(self): # a __str__() method from the proxied class. return str(self.__cast()) - def __ne__(self, other): - if isinstance(other, Promise): - other = other.__cast() - return self.__cast() != other - def __eq__(self, other): if isinstance(other, Promise): other = other.__cast() From a5563963397aeee30c32e3c1dab31bfe453ca89f Mon Sep 17 00:00:00 2001 From: Aymeric Augustin Date: Wed, 18 Jan 2017 22:05:41 +0100 Subject: [PATCH 0067/3180] Refs #23919 -- Replaced io.open() with open(). io.open() is an alias for open() on Python 3. --- django/core/cache/backends/filebased.py | 7 +++---- django/core/management/commands/makemessages.py | 15 +++++++-------- django/core/management/commands/makemigrations.py | 5 ++--- .../core/management/commands/squashmigrations.py | 4 +--- django/core/management/templates.py | 5 ++--- django/template/backends/dummy.py | 3 +-- django/template/loaders/filesystem.py | 3 +-- tests/cache/tests.py | 2 +- tests/i18n/test_extraction.py | 11 +++++------ tests/migrations/test_commands.py | 10 +++++----- tests/validators/tests.py | 5 ++--- 11 files changed, 30 insertions(+), 40 deletions(-) diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py index 88509ed8de3e..ae5b48c054f1 100644 --- a/django/core/cache/backends/filebased.py +++ b/django/core/cache/backends/filebased.py @@ -2,7 +2,6 @@ import errno import glob import hashlib -import io import os import pickle import random @@ -32,7 +31,7 @@ def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None): def get(self, key, default=None, version=None): fname = self._key_to_file(key, version) try: - with io.open(fname, 'rb') as f: + with open(fname, 'rb') as f: if not self._is_expired(f): return pickle.loads(zlib.decompress(f.read())) except IOError as e: @@ -47,7 +46,7 @@ def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None): fd, tmp_path = tempfile.mkstemp(dir=self._dir) renamed = False try: - with io.open(fd, 'wb') as f: + with open(fd, 'wb') as f: expiry = self.get_backend_timeout(timeout) f.write(pickle.dumps(expiry, pickle.HIGHEST_PROTOCOL)) f.write(zlib.compress(pickle.dumps(value, pickle.HIGHEST_PROTOCOL))) @@ -74,7 +73,7 @@ def _delete(self, fname): def has_key(self, key, version=None): fname = self._key_to_file(key, version) if os.path.exists(fname): - with io.open(fname, 'rb') as f: + with open(fname, 'rb') as f: return not self._is_expired(f) return False diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py index 1597f9347e79..dc505173b12e 100644 --- a/django/core/management/commands/makemessages.py +++ b/django/core/management/commands/makemessages.py @@ -1,6 +1,5 @@ import fnmatch import glob -import io import os import re import sys @@ -106,7 +105,7 @@ def preprocess(self): return encoding = settings.FILE_CHARSET if self.command.settings_available else 'utf-8' - with io.open(self.path, 'r', encoding=encoding) as fp: + with open(self.path, 'r', encoding=encoding) as fp: src_data = fp.read() if self.domain == 'djangojs': @@ -114,7 +113,7 @@ def preprocess(self): elif self.domain == 'django': content = templatize(src_data, origin=self.path[2:], charset=encoding) - with io.open(self.work_path, 'w', encoding='utf-8') as fp: + with open(self.work_path, 'w', encoding='utf-8') as fp: fp.write(content) def postprocess_messages(self, msgs): @@ -190,7 +189,7 @@ def write_pot_file(potfile, msgs): header_read = True lines.append(line) msgs = '\n'.join(lines) - with io.open(potfile, 'a', encoding='utf-8') as fp: + with open(potfile, 'a', encoding='utf-8') as fp: fp.write(msgs) @@ -412,7 +411,7 @@ def build_potfiles(self): elif self.verbosity > 0: self.stdout.write(errors) msgs = normalize_eols(msgs) - with io.open(potfile, 'w', encoding='utf-8') as fp: + with open(potfile, 'w', encoding='utf-8') as fp: fp.write(msgs) potfiles.append(potfile) return potfiles @@ -613,14 +612,14 @@ def write_po_file(self, potfile, locale): elif self.verbosity > 0: self.stdout.write(errors) else: - with io.open(potfile, 'r', encoding='utf-8') as fp: + with open(potfile, 'r', encoding='utf-8') as fp: msgs = fp.read() if not self.invoked_for_django: msgs = self.copy_plural_forms(msgs, locale) msgs = normalize_eols(msgs) msgs = msgs.replace( "#. #-#-#-#-# %s.pot (PACKAGE VERSION) #-#-#-#-#\n" % self.domain, "") - with io.open(pofile, 'w', encoding='utf-8') as fp: + with open(pofile, 'w', encoding='utf-8') as fp: fp.write(msgs) if self.no_obsolete: @@ -647,7 +646,7 @@ def copy_plural_forms(self, msgs, locale): for domain in domains: django_po = os.path.join(django_dir, 'conf', 'locale', locale, 'LC_MESSAGES', '%s.po' % domain) if os.path.exists(django_po): - with io.open(django_po, 'r', encoding='utf-8') as fp: + with open(django_po, 'r', encoding='utf-8') as fp: m = plural_forms_re.search(fp.read()) if m: plural_form_line = force_str(m.group('value')) diff --git a/django/core/management/commands/makemigrations.py b/django/core/management/commands/makemigrations.py index 3364d958a976..8572bbeb95b4 100644 --- a/django/core/management/commands/makemigrations.py +++ b/django/core/management/commands/makemigrations.py @@ -1,4 +1,3 @@ -import io import os import sys from itertools import takewhile @@ -210,7 +209,7 @@ def write_migration_files(self, changes): # We just do this once per app directory_created[app_label] = True migration_string = writer.as_string() - with io.open(writer.path, "w", encoding='utf-8') as fh: + with open(writer.path, "w", encoding='utf-8') as fh: fh.write(migration_string) elif self.verbosity == 3: # Alternatively, makemigrations --dry-run --verbosity 3 @@ -289,7 +288,7 @@ def all_items_equal(seq): if not self.dry_run: # Write the merge migrations file to the disk - with io.open(writer.path, "w", encoding='utf-8') as fh: + with open(writer.path, "w", encoding='utf-8') as fh: fh.write(writer.as_string()) if self.verbosity > 0: self.stdout.write("\nCreated new merge migration %s" % writer.path) diff --git a/django/core/management/commands/squashmigrations.py b/django/core/management/commands/squashmigrations.py index 5556b2474506..090e7c7dfbf7 100644 --- a/django/core/management/commands/squashmigrations.py +++ b/django/core/management/commands/squashmigrations.py @@ -1,5 +1,3 @@ -import io - from django.conf import settings from django.core.management.base import BaseCommand, CommandError from django.db import DEFAULT_DB_ALIAS, connections, migrations @@ -163,7 +161,7 @@ def handle(self, **options): # Write out the new migration file writer = MigrationWriter(new_migration) - with io.open(writer.path, "w", encoding='utf-8') as fh: + with open(writer.path, "w", encoding='utf-8') as fh: fh.write(writer.as_string()) if self.verbosity > 0: diff --git a/django/core/management/templates.py b/django/core/management/templates.py index ccc4920fe379..a53303ae3806 100644 --- a/django/core/management/templates.py +++ b/django/core/management/templates.py @@ -1,6 +1,5 @@ import cgi import errno -import io import mimetypes import os import posixpath @@ -158,11 +157,11 @@ def handle(self, app_or_project, name, target=None, **options): # Only render the Python files, as we don't want to # accidentally render Django templates files if new_path.endswith(extensions) or filename in extra_files: - with io.open(old_path, 'r', encoding='utf-8') as template_file: + with open(old_path, 'r', encoding='utf-8') as template_file: content = template_file.read() template = Engine().from_string(content) content = template.render(context) - with io.open(new_path, 'w', encoding='utf-8') as new_file: + with open(new_path, 'w', encoding='utf-8') as new_file: new_file.write(content) else: shutil.copyfile(old_path, new_path) diff --git a/django/template/backends/dummy.py b/django/template/backends/dummy.py index 015cb8bda061..ce658ec76447 100644 --- a/django/template/backends/dummy.py +++ b/django/template/backends/dummy.py @@ -1,5 +1,4 @@ import errno -import io import string from django.conf import settings @@ -30,7 +29,7 @@ def get_template(self, template_name): tried = [] for template_file in self.iter_template_filenames(template_name): try: - with io.open(template_file, encoding=settings.FILE_CHARSET) as fp: + with open(template_file, encoding=settings.FILE_CHARSET) as fp: template_code = fp.read() except IOError as e: if e.errno == errno.ENOENT: diff --git a/django/template/loaders/filesystem.py b/django/template/loaders/filesystem.py index bd126a0c6ba2..658e70214388 100644 --- a/django/template/loaders/filesystem.py +++ b/django/template/loaders/filesystem.py @@ -3,7 +3,6 @@ """ import errno -import io from django.core.exceptions import SuspiciousFileOperation from django.template import Origin, TemplateDoesNotExist @@ -23,7 +22,7 @@ def get_dirs(self): def get_contents(self, origin): try: - with io.open(origin.name, encoding=self.engine.file_charset) as fp: + with open(origin.name, encoding=self.engine.file_charset) as fp: return fp.read() except IOError as e: if e.errno == errno.ENOENT: diff --git a/tests/cache/tests.py b/tests/cache/tests.py index 3bf39e247682..dd886cd11b4f 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -1370,7 +1370,7 @@ def test_get_ignores_enoent(self): self.assertEqual(cache.get('foo', 'baz'), 'baz') def test_get_does_not_ignore_non_enoent_errno_values(self): - with mock.patch.object(io, 'open', side_effect=IOError): + with mock.patch('builtins.open', side_effect=IOError): with self.assertRaises(IOError): cache.get('foo') diff --git a/tests/i18n/test_extraction.py b/tests/i18n/test_extraction.py index aaa2a4e8b582..4189a9e168c1 100644 --- a/tests/i18n/test_extraction.py +++ b/tests/i18n/test_extraction.py @@ -1,4 +1,3 @@ -import io import os import re import shutil @@ -133,7 +132,7 @@ def test_use_i18n_false(self): """ management.call_command('makemessages', locale=[LOCALE], verbosity=0) self.assertTrue(os.path.exists(self.PO_FILE)) - with io.open(self.PO_FILE, 'r', encoding='utf-8') as fp: + with open(self.PO_FILE, 'r', encoding='utf-8') as fp: po_contents = fp.read() # Check two random strings self.assertIn('#. Translators: One-line translator comment #1', po_contents) @@ -142,7 +141,7 @@ def test_use_i18n_false(self): def test_comments_extractor(self): management.call_command('makemessages', locale=[LOCALE], verbosity=0) self.assertTrue(os.path.exists(self.PO_FILE)) - with io.open(self.PO_FILE, 'r', encoding='utf-8') as fp: + with open(self.PO_FILE, 'r', encoding='utf-8') as fp: po_contents = fp.read() self.assertNotIn('This comment should not be extracted', po_contents) @@ -175,7 +174,7 @@ def test_comments_extractor(self): def test_special_char_extracted(self): management.call_command('makemessages', locale=[LOCALE], verbosity=0) self.assertTrue(os.path.exists(self.PO_FILE)) - with io.open(self.PO_FILE, 'r', encoding='utf-8') as fp: + with open(self.PO_FILE, 'r', encoding='utf-8') as fp: po_contents = fp.read() self.assertMsgId("Non-breaking space\u00a0:", po_contents) @@ -390,7 +389,7 @@ def test_po_file_encoding_when_updating(self): shutil.copyfile(BR_PO_BASE + '.pristine', BR_PO_BASE + '.po') management.call_command('makemessages', locale=['pt_BR'], verbosity=0) self.assertTrue(os.path.exists(BR_PO_BASE + '.po')) - with io.open(BR_PO_BASE + '.po', 'r', encoding='utf-8') as fp: + with open(BR_PO_BASE + '.po', 'r', encoding='utf-8') as fp: po_contents = force_text(fp.read()) self.assertMsgStr("Größe", po_contents) @@ -515,7 +514,7 @@ def test_override_plural_forms(self): """Ticket #20311.""" management.call_command('makemessages', locale=['es'], extensions=['djtpl'], verbosity=0) self.assertTrue(os.path.exists(self.PO_FILE_ES)) - with io.open(self.PO_FILE_ES, 'r', encoding='utf-8') as fp: + with open(self.PO_FILE_ES, 'r', encoding='utf-8') as fp: po_contents = fp.read() found = re.findall(r'^(?P"Plural-Forms.+?\\n")\s*$', po_contents, re.MULTILINE | re.DOTALL) self.assertEqual(1, len(found)) diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index e6de83212e3b..421b4890a432 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -655,7 +655,7 @@ def test_files_content(self): initial_file = os.path.join(migration_dir, "0001_initial.py") self.assertTrue(os.path.exists(initial_file)) - with io.open(initial_file, 'r', encoding='utf-8') as fp: + with open(initial_file, 'r', encoding='utf-8') as fp: content = fp.read() self.assertIn('migrations.CreateModel', content) self.assertIn('initial = True', content) @@ -798,7 +798,7 @@ def test_makemigrations_empty_migration(self): initial_file = os.path.join(migration_dir, "0001_initial.py") self.assertTrue(os.path.exists(initial_file)) - with io.open(initial_file, 'r', encoding='utf-8') as fp: + with open(initial_file, 'r', encoding='utf-8') as fp: content = fp.read() # Remove all whitespace to check for empty dependencies and operations @@ -1192,7 +1192,7 @@ def cmd(migration_count, migration_name, *args): migration_file = os.path.join(migration_dir, "%s_%s.py" % (migration_count, migration_name)) # Check for existing migration file in migration folder self.assertTrue(os.path.exists(migration_file)) - with io.open(migration_file, "r", encoding="utf-8") as fp: + with open(migration_file, "r", encoding="utf-8") as fp: content = fp.read() content = content.replace(" ", "") return content @@ -1307,7 +1307,7 @@ def test_squashmigrations_initial_attribute(self): call_command("squashmigrations", "migrations", "0002", interactive=False, verbosity=0) squashed_migration_file = os.path.join(migration_dir, "0001_squashed_0002_second.py") - with io.open(squashed_migration_file, "r", encoding="utf-8") as fp: + with open(squashed_migration_file, "r", encoding="utf-8") as fp: content = fp.read() self.assertIn("initial = True", content) @@ -1340,7 +1340,7 @@ def test_squashmigrations_valid_start(self): interactive=False, verbosity=1, stdout=out) squashed_migration_file = os.path.join(migration_dir, "0002_second_squashed_0003_third.py") - with io.open(squashed_migration_file, "r", encoding="utf-8") as fp: + with open(squashed_migration_file, "r", encoding="utf-8") as fp: content = fp.read() self.assertIn(" ('migrations', '0001_initial')", content) self.assertNotIn("initial = True", content) diff --git a/tests/validators/tests.py b/tests/validators/tests.py index d5fb2215ca54..2f26efcaa5a0 100644 --- a/tests/validators/tests.py +++ b/tests/validators/tests.py @@ -1,4 +1,3 @@ -import io import os import re import types @@ -269,10 +268,10 @@ def create_path(filename): # Add valid and invalid URL tests. # This only tests the validator without extended schemes. -with io.open(create_path('valid_urls.txt'), encoding='utf8') as f: +with open(create_path('valid_urls.txt'), encoding='utf8') as f: for url in f: TEST_DATA.append((URLValidator(), url.strip(), None)) -with io.open(create_path('invalid_urls.txt'), encoding='utf8') as f: +with open(create_path('invalid_urls.txt'), encoding='utf8') as f: for url in f: TEST_DATA.append((URLValidator(), url.strip(), ValidationError)) From cecc079168e8669138728d31611ff3a1e7eb3a9f Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Thu, 19 Jan 2017 02:39:46 -0500 Subject: [PATCH 0068/3180] Refs #23919 -- Stopped inheriting from object to define new style classes. --- django/apps/config.py | 2 +- django/apps/registry.py | 2 +- django/conf/__init__.py | 4 +-- django/contrib/admin/checks.py | 2 +- django/contrib/admin/filters.py | 2 +- django/contrib/admin/helpers.py | 12 +++---- django/contrib/admin/sites.py | 2 +- django/contrib/admin/views/main.py | 2 +- django/contrib/auth/backends.py | 2 +- django/contrib/auth/context_processors.py | 4 +-- django/contrib/auth/hashers.py | 2 +- django/contrib/auth/mixins.py | 2 +- django/contrib/auth/models.py | 2 +- django/contrib/auth/password_validation.py | 8 ++--- django/contrib/auth/tokens.py | 2 +- django/contrib/auth/views.py | 4 +-- django/contrib/contenttypes/fields.py | 2 +- .../contrib/gis/db/backends/base/adapter.py | 2 +- .../contrib/gis/db/backends/base/features.py | 2 +- django/contrib/gis/db/backends/base/models.py | 2 +- .../gis/db/backends/base/operations.py | 2 +- .../gis/db/backends/postgis/adapter.py | 2 +- django/contrib/gis/db/backends/utils.py | 2 +- django/contrib/gis/db/models/fields.py | 2 +- django/contrib/gis/db/models/functions.py | 6 ++-- .../contrib/gis/db/models/sql/conversion.py | 2 +- django/contrib/gis/feeds.py | 2 +- django/contrib/gis/gdal/envelope.py | 2 +- django/contrib/gis/gdal/geomtype.py | 2 +- django/contrib/gis/geoip2/base.py | 2 +- django/contrib/gis/geos/geometry.py | 2 +- django/contrib/gis/geos/libgeos.py | 2 +- django/contrib/gis/geos/mutable_list.py | 2 +- .../contrib/gis/geos/prototypes/threadsafe.py | 2 +- django/contrib/gis/measure.py | 2 +- django/contrib/gis/ptr.py | 2 +- django/contrib/gis/serializers/geojson.py | 2 +- django/contrib/gis/utils/layermapping.py | 2 +- django/contrib/messages/storage/base.py | 4 +-- django/contrib/messages/views.py | 2 +- django/contrib/postgres/fields/array.py | 4 +-- django/contrib/postgres/fields/hstore.py | 2 +- django/contrib/postgres/fields/jsonb.py | 4 +-- django/contrib/postgres/fields/utils.py | 2 +- django/contrib/postgres/search.py | 4 +-- django/contrib/postgres/validators.py | 2 +- django/contrib/sessions/backends/base.py | 2 +- django/contrib/sessions/serializers.py | 2 +- django/contrib/sitemaps/__init__.py | 2 +- django/contrib/sites/requests.py | 2 +- django/contrib/staticfiles/finders.py | 2 +- django/contrib/staticfiles/storage.py | 4 +-- django/contrib/syndication/views.py | 2 +- django/core/cache/__init__.py | 4 +-- django/core/cache/backends/base.py | 2 +- django/core/cache/backends/db.py | 4 +-- django/core/checks/messages.py | 2 +- django/core/checks/registry.py | 4 +-- django/core/files/storage.py | 2 +- django/core/files/uploadhandler.py | 2 +- django/core/files/utils.py | 2 +- django/core/handlers/base.py | 2 +- django/core/handlers/wsgi.py | 2 +- django/core/mail/backends/base.py | 2 +- django/core/mail/message.py | 2 +- django/core/mail/utils.py | 2 +- django/core/management/__init__.py | 2 +- django/core/management/base.py | 4 +-- django/core/management/color.py | 2 +- .../core/management/commands/makemessages.py | 4 +-- django/core/paginator.py | 2 +- django/core/serializers/__init__.py | 4 +-- django/core/serializers/base.py | 6 ++-- django/core/servers/basehttp.py | 6 ++-- django/core/signing.py | 4 +-- django/core/validators.py | 10 +++--- django/db/__init__.py | 2 +- django/db/backends/base/base.py | 2 +- django/db/backends/base/client.py | 2 +- django/db/backends/base/creation.py | 2 +- django/db/backends/base/features.py | 2 +- django/db/backends/base/introspection.py | 2 +- django/db/backends/base/operations.py | 2 +- django/db/backends/base/schema.py | 2 +- django/db/backends/base/validation.py | 2 +- django/db/backends/mysql/base.py | 2 +- django/db/backends/oracle/base.py | 8 ++--- django/db/backends/oracle/utils.py | 2 +- django/db/backends/sqlite3/introspection.py | 2 +- django/db/backends/utils.py | 2 +- django/db/migrations/autodetector.py | 2 +- django/db/migrations/executor.py | 2 +- django/db/migrations/graph.py | 4 +-- django/db/migrations/loader.py | 2 +- django/db/migrations/migration.py | 2 +- django/db/migrations/operations/base.py | 2 +- django/db/migrations/optimizer.py | 2 +- django/db/migrations/questioner.py | 2 +- django/db/migrations/recorder.py | 2 +- django/db/migrations/serializer.py | 2 +- django/db/migrations/state.py | 4 +-- django/db/migrations/utils.py | 2 +- django/db/migrations/writer.py | 4 +-- django/db/models/base.py | 4 +-- django/db/models/deletion.py | 2 +- django/db/models/expressions.py | 4 +-- django/db/models/fields/__init__.py | 6 ++-- django/db/models/fields/files.py | 2 +- django/db/models/fields/related.py | 2 +- .../db/models/fields/related_descriptors.py | 6 ++-- django/db/models/fields/related_lookups.py | 4 +-- django/db/models/fields/reverse_related.py | 2 +- django/db/models/functions/datetime.py | 2 +- django/db/models/indexes.py | 2 +- django/db/models/lookups.py | 8 ++--- django/db/models/manager.py | 4 +-- django/db/models/options.py | 2 +- django/db/models/query.py | 10 +++--- django/db/models/query_utils.py | 6 ++-- django/db/models/sql/compiler.py | 2 +- django/db/models/sql/datastructures.py | 6 ++-- django/db/models/sql/query.py | 6 ++-- django/db/models/sql/where.py | 6 ++-- django/db/utils.py | 6 ++-- django/dispatch/dispatcher.py | 2 +- django/forms/boundfield.py | 4 +-- django/forms/fields.py | 4 +-- django/forms/forms.py | 2 +- django/forms/formsets.py | 2 +- django/forms/models.py | 10 +++--- django/forms/renderers.py | 4 +-- django/forms/widgets.py | 2 +- django/http/multipartparser.py | 4 +-- django/http/request.py | 2 +- django/template/backends/base.py | 2 +- django/template/backends/django.py | 2 +- django/template/backends/jinja2.py | 4 +-- django/template/base.py | 16 ++++----- django/template/context.py | 2 +- django/template/engine.py | 2 +- django/template/library.py | 2 +- django/template/loader_tags.py | 2 +- django/template/loaders/base.py | 2 +- django/template/smartif.py | 4 +-- django/template/utils.py | 2 +- django/templatetags/tz.py | 6 ++-- django/test/client.py | 4 +-- django/test/html.py | 2 +- django/test/runner.py | 6 ++-- django/test/testcases.py | 8 ++--- django/test/utils.py | 10 +++--- django/urls/resolvers.py | 6 ++-- django/utils/archive.py | 4 +-- django/utils/baseconv.py | 2 +- django/utils/datastructures.py | 2 +- django/utils/dateformat.py | 2 +- django/utils/decorators.py | 4 +-- django/utils/deprecation.py | 4 +-- django/utils/feedgenerator.py | 4 +-- django/utils/functional.py | 6 ++-- django/utils/jslex.py | 4 +-- django/utils/safestring.py | 2 +- django/utils/six.py | 8 ++--- django/utils/synch.py | 2 +- django/utils/text.py | 2 +- django/utils/translation/__init__.py | 2 +- django/utils/tree.py | 2 +- django/views/debug.py | 6 ++-- django/views/generic/base.py | 6 ++-- django/views/generic/dates.py | 10 +++--- django/views/generic/edit.py | 2 +- tests/admin_docs/tests.py | 2 +- tests/admin_inlines/tests.py | 2 +- tests/admin_ordering/tests.py | 4 +-- tests/admin_utils/tests.py | 6 ++-- tests/admin_views/test_multidb.py | 2 +- tests/admin_views/tests.py | 2 +- tests/admin_widgets/tests.py | 2 +- tests/apps/apps.py | 2 +- tests/apps/tests.py | 2 +- tests/auth_tests/models/custom_user.py | 2 +- tests/auth_tests/test_admin_multidb.py | 2 +- tests/auth_tests/test_auth_backends.py | 10 +++--- .../test_auth_backends_deprecation.py | 2 +- tests/auth_tests/test_context_processors.py | 4 +-- tests/auth_tests/test_decorators.py | 2 +- tests/auth_tests/test_forms.py | 2 +- tests/auth_tests/test_management.py | 4 +-- tests/backends/tests.py | 4 +-- tests/builtin_server/tests.py | 4 +-- tests/cache/closeable_cache.py | 2 +- tests/cache/liberal_backend.py | 2 +- tests/cache/tests.py | 10 +++--- tests/check_framework/test_multi_db.py | 2 +- tests/check_framework/tests.py | 2 +- tests/contenttypes_tests/tests.py | 2 +- tests/csrf_tests/tests.py | 2 +- tests/custom_lookups/tests.py | 4 +-- tests/custom_pk/fields.py | 2 +- tests/decorators/tests.py | 34 +++++++++---------- tests/defer/tests.py | 2 +- tests/deprecation/tests.py | 4 +-- tests/dispatch/tests.py | 2 +- tests/files/tests.py | 2 +- tests/fixtures/tests.py | 2 +- tests/flatpages_tests/test_middleware.py | 2 +- tests/flatpages_tests/test_views.py | 2 +- tests/foreign_object/models/article.py | 2 +- tests/forms_tests/field_tests/__init__.py | 2 +- tests/forms_tests/field_tests/test_base.py | 2 +- .../forms_tests/tests/test_error_messages.py | 2 +- tests/forms_tests/tests/test_renderers.py | 2 +- .../widget_tests/test_clearablefileinput.py | 10 +++--- tests/generic_inline_admin/tests.py | 6 ++-- tests/generic_views/test_dates.py | 2 +- tests/generic_views/views.py | 6 ++-- tests/get_object_or_404/tests.py | 2 +- tests/gis_tests/gdal_tests/test_envelope.py | 2 +- tests/gis_tests/geo3d/tests.py | 2 +- tests/gis_tests/geos_tests/test_geos.py | 2 +- tests/gis_tests/layermap/tests.py | 2 +- tests/gis_tests/test_data.py | 6 ++-- tests/gis_tests/tests.py | 2 +- tests/handlers/tests_custom_error_handlers.py | 2 +- tests/i18n/utils.py | 4 +-- tests/invalid_models_tests/test_models.py | 2 +- .../test_ordinary_fields.py | 4 +-- tests/logging_tests/tests.py | 2 +- tests/mail/tests.py | 4 +-- tests/messages_tests/base.py | 2 +- tests/messages_tests/test_api.py | 4 +-- tests/middleware_exceptions/middleware.py | 2 +- tests/middleware_exceptions/tests.py | 4 +-- tests/migrate_signals/tests.py | 4 +-- tests/migrations/models.py | 2 +- tests/migrations/routers.py | 4 +-- tests/migrations/test_autodetector.py | 2 +- tests/migrations/test_executor.py | 4 +-- tests/migrations/test_multidb.py | 8 ++--- tests/migrations/test_operations.py | 2 +- tests/migrations/test_writer.py | 6 ++-- tests/model_forms/tests.py | 2 +- tests/model_formsets_regress/tests.py | 2 +- tests/model_inheritance/models.py | 2 +- .../test_abstract_inheritance.py | 4 +-- tests/modeladmin/test_checks.py | 12 +++---- tests/modeladmin/tests.py | 6 ++-- tests/multiple_database/routers.py | 6 ++-- tests/multiple_database/tests.py | 14 ++++---- tests/order_with_respect_to/base_tests.py | 2 +- tests/pagination/tests.py | 4 +-- tests/postgres_tests/models.py | 2 +- tests/postgres_tests/test_search.py | 2 +- tests/queries/tests.py | 4 +-- tests/queryset_pickle/models.py | 4 +-- tests/serializers/models/base.py | 2 +- tests/serializers/test_yaml.py | 2 +- tests/serializers/tests.py | 6 ++-- tests/servers/test_basehttp.py | 2 +- tests/sessions_tests/tests.py | 2 +- tests/signals/tests.py | 4 +-- tests/sites_tests/tests.py | 2 +- tests/staticfiles_tests/cases.py | 4 +-- tests/staticfiles_tests/test_finders.py | 2 +- tests/staticfiles_tests/test_management.py | 2 +- tests/staticfiles_tests/test_storage.py | 2 +- .../filter_tests/test_floatformat.py | 2 +- .../filter_tests/test_unordered_list.py | 4 +-- tests/template_tests/test_callables.py | 8 ++--- tests/template_tests/test_logging.py | 2 +- tests/template_tests/utils.py | 6 ++-- tests/test_client/auth_backends.py | 2 +- tests/test_client/views.py | 2 +- tests/test_client_regress/tests.py | 4 +-- tests/test_runner/tests.py | 2 +- tests/transactions/tests.py | 2 +- tests/urlpatterns_reverse/method_view_urls.py | 2 +- tests/urlpatterns_reverse/tests.py | 2 +- tests/urlpatterns_reverse/utils.py | 2 +- tests/urlpatterns_reverse/views.py | 2 +- tests/utils_tests/test_archive.py | 2 +- tests/utils_tests/test_decorators.py | 12 +++---- tests/utils_tests/test_encoding.py | 2 +- tests/utils_tests/test_functional.py | 8 ++--- tests/utils_tests/test_html.py | 8 ++--- tests/utils_tests/test_inspect.py | 2 +- tests/utils_tests/test_lazyobject.py | 6 ++-- tests/utils_tests/test_module/__init__.py | 2 +- tests/utils_tests/test_module_loading.py | 6 ++-- tests/utils_tests/test_safestring.py | 2 +- tests/view_tests/tests/test_debug.py | 14 ++++---- tests/view_tests/views.py | 2 +- tests/wsgi/tests.py | 2 +- 293 files changed, 512 insertions(+), 514 deletions(-) diff --git a/django/apps/config.py b/django/apps/config.py index edb1146afc6d..024643a64521 100644 --- a/django/apps/config.py +++ b/django/apps/config.py @@ -8,7 +8,7 @@ MODELS_MODULE_NAME = 'models' -class AppConfig(object): +class AppConfig: """ Class representing a Django application and its configuration. """ diff --git a/django/apps/registry.py b/django/apps/registry.py index c67c5ee0baa8..870c4540670c 100644 --- a/django/apps/registry.py +++ b/django/apps/registry.py @@ -10,7 +10,7 @@ from .config import AppConfig -class Apps(object): +class Apps: """ A registry that stores the configuration of installed applications. diff --git a/django/conf/__init__.py b/django/conf/__init__.py index f99236a7784e..ec6efa8e96e1 100644 --- a/django/conf/__init__.py +++ b/django/conf/__init__.py @@ -97,7 +97,7 @@ def configured(self): return self._wrapped is not empty -class Settings(object): +class Settings: def __init__(self, settings_module): # update this dict from global settings (but only for ALL_CAPS settings) for setting in dir(global_settings): @@ -150,7 +150,7 @@ def __repr__(self): } -class UserSettingsHolder(object): +class UserSettingsHolder: """ Holder for user configured settings. """ diff --git a/django/contrib/admin/checks.py b/django/contrib/admin/checks.py index 33c60a3ab872..354d0a3a9c71 100644 --- a/django/contrib/admin/checks.py +++ b/django/contrib/admin/checks.py @@ -62,7 +62,7 @@ def check_dependencies(**kwargs): return errors -class BaseModelAdminChecks(object): +class BaseModelAdminChecks: def check(self, admin_obj, **kwargs): errors = [] diff --git a/django/contrib/admin/filters.py b/django/contrib/admin/filters.py index 87839c313064..923caa33e9a4 100644 --- a/django/contrib/admin/filters.py +++ b/django/contrib/admin/filters.py @@ -18,7 +18,7 @@ from django.utils.translation import ugettext_lazy as _ -class ListFilter(object): +class ListFilter: title = None # Human-readable title to appear in the right sidebar. template = 'admin/filter.html' diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py index 628788b3fafd..17aac7a85b9c 100644 --- a/django/contrib/admin/helpers.py +++ b/django/contrib/admin/helpers.py @@ -31,7 +31,7 @@ class ActionForm(forms.Form): checkbox = forms.CheckboxInput({'class': 'action-select'}, lambda value: False) -class AdminForm(object): +class AdminForm: def __init__(self, form, fieldsets, prepopulated_fields, readonly_fields=None, model_admin=None): self.form, self.fieldsets = form, fieldsets self.prepopulated_fields = [{ @@ -68,7 +68,7 @@ def media(self): return media -class Fieldset(object): +class Fieldset: def __init__(self, form, name=None, readonly_fields=(), fields=(), classes=(), description=None, model_admin=None): self.form = form @@ -95,7 +95,7 @@ def __iter__(self): yield Fieldline(self.form, field, self.readonly_fields, model_admin=self.model_admin) -class Fieldline(object): +class Fieldline: def __init__(self, form, field, readonly_fields=None, model_admin=None): self.form = form # A django.forms.Form instance if not hasattr(field, "__iter__") or isinstance(field, str): @@ -126,7 +126,7 @@ def errors(self): ) -class AdminField(object): +class AdminField: def __init__(self, form, field, is_first): self.field = form[field] # A django.forms.BoundField instance self.is_first = is_first # Whether this field is first on the line @@ -155,7 +155,7 @@ def errors(self): return mark_safe(self.field.errors.as_ul()) -class AdminReadonlyField(object): +class AdminReadonlyField: def __init__(self, form, field, is_first, model_admin=None): # Make self.field look a little bit like a field. This means that # {{ field.name }} must be a useful class name to identify the field. @@ -223,7 +223,7 @@ def contents(self): return conditional_escape(result_repr) -class InlineAdminFormSet(object): +class InlineAdminFormSet: """ A wrapper around an inline formset for use in the admin system. """ diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index 14b0da7df424..6adf13fdb80b 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -26,7 +26,7 @@ class NotRegistered(Exception): pass -class AdminSite(object): +class AdminSite: """ An AdminSite object encapsulates an instance of the Django admin application, ready to be hooked in to your URLconf. Models are registered with the AdminSite using the diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 81facb9b823f..20bce0c8d671 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -34,7 +34,7 @@ ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR, TO_FIELD_VAR) -class ChangeList(object): +class ChangeList: def __init__(self, request, model, list_display, list_display_links, list_filter, date_hierarchy, search_fields, list_select_related, list_per_page, list_max_show_all, list_editable, model_admin): diff --git a/django/contrib/auth/backends.py b/django/contrib/auth/backends.py index 08a20c61ffc7..e0fbd21b3819 100644 --- a/django/contrib/auth/backends.py +++ b/django/contrib/auth/backends.py @@ -4,7 +4,7 @@ UserModel = get_user_model() -class ModelBackend(object): +class ModelBackend: """ Authenticates against settings.AUTH_USER_MODEL. """ diff --git a/django/contrib/auth/context_processors.py b/django/contrib/auth/context_processors.py index ce1e42d5744b..f865fc1b7d06 100644 --- a/django/contrib/auth/context_processors.py +++ b/django/contrib/auth/context_processors.py @@ -2,7 +2,7 @@ # the template system can understand. -class PermLookupDict(object): +class PermLookupDict: def __init__(self, user, app_label): self.user, self.app_label = user, app_label @@ -24,7 +24,7 @@ def __nonzero__(self): # Python 2 compatibility return type(self).__bool__(self) -class PermWrapper(object): +class PermWrapper: def __init__(self, user): self.user = user diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py index 871519257afe..0446cf501f04 100644 --- a/django/contrib/auth/hashers.py +++ b/django/contrib/auth/hashers.py @@ -162,7 +162,7 @@ def mask_hash(hash, show=6, char="*"): return masked -class BasePasswordHasher(object): +class BasePasswordHasher: """ Abstract base class for password hashers diff --git a/django/contrib/auth/mixins.py b/django/contrib/auth/mixins.py index c52b57365830..e52311670f42 100644 --- a/django/contrib/auth/mixins.py +++ b/django/contrib/auth/mixins.py @@ -5,7 +5,7 @@ from django.utils.encoding import force_text -class AccessMixin(object): +class AccessMixin: """ Abstract CBV mixin that gives access mixins the same customizable functionality. diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index 9eaf7a6e34d7..bd185b58be62 100644 --- a/django/contrib/auth/models.py +++ b/django/contrib/auth/models.py @@ -372,7 +372,7 @@ class Meta(AbstractUser.Meta): swappable = 'AUTH_USER_MODEL' -class AnonymousUser(object): +class AnonymousUser: id = None pk = None username = '' diff --git a/django/contrib/auth/password_validation.py b/django/contrib/auth/password_validation.py index dee1ebf67476..a7319dbd52cd 100644 --- a/django/contrib/auth/password_validation.py +++ b/django/contrib/auth/password_validation.py @@ -90,7 +90,7 @@ def _password_validators_help_text_html(password_validators=None): password_validators_help_text_html = lazy(_password_validators_help_text_html, str) -class MinimumLengthValidator(object): +class MinimumLengthValidator: """ Validate whether the password is of a minimum length. """ @@ -117,7 +117,7 @@ def get_help_text(self): ) % {'min_length': self.min_length} -class UserAttributeSimilarityValidator(object): +class UserAttributeSimilarityValidator: """ Validate whether the password is sufficiently different from the user's attributes. @@ -159,7 +159,7 @@ def get_help_text(self): return _("Your password can't be too similar to your other personal information.") -class CommonPasswordValidator(object): +class CommonPasswordValidator: """ Validate whether the password is a common password. @@ -192,7 +192,7 @@ def get_help_text(self): return _("Your password can't be a commonly used password.") -class NumericPasswordValidator(object): +class NumericPasswordValidator: """ Validate whether the password is alphanumeric. """ diff --git a/django/contrib/auth/tokens.py b/django/contrib/auth/tokens.py index 18ff42f19247..f508327d94da 100644 --- a/django/contrib/auth/tokens.py +++ b/django/contrib/auth/tokens.py @@ -5,7 +5,7 @@ from django.utils.http import base36_to_int, int_to_base36 -class PasswordResetTokenGenerator(object): +class PasswordResetTokenGenerator: """ Strategy object used to generate and check tokens for the password reset mechanism. diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py index bf95d11a1057..cca52a6105c2 100644 --- a/django/contrib/auth/views.py +++ b/django/contrib/auth/views.py @@ -31,7 +31,7 @@ UserModel = get_user_model() -class SuccessURLAllowedHostsMixin(object): +class SuccessURLAllowedHostsMixin: success_url_allowed_hosts = set() def get_success_url_allowed_hosts(self): @@ -352,7 +352,7 @@ def password_reset_complete(request, # prompts for a new password # - PasswordResetCompleteView shows a success message for the above -class PasswordContextMixin(object): +class PasswordContextMixin: extra_context = None def get_context_data(self, **kwargs): diff --git a/django/contrib/contenttypes/fields.py b/django/contrib/contenttypes/fields.py index d2812e5d2a8b..efffbfd77a07 100644 --- a/django/contrib/contenttypes/fields.py +++ b/django/contrib/contenttypes/fields.py @@ -15,7 +15,7 @@ from django.utils.functional import cached_property -class GenericForeignKey(object): +class GenericForeignKey: """ Provide a generic many-to-one relation through the ``content_type`` and ``object_id`` fields. diff --git a/django/contrib/gis/db/backends/base/adapter.py b/django/contrib/gis/db/backends/base/adapter.py index 9b12c4320cfa..b9b05c4472ba 100644 --- a/django/contrib/gis/db/backends/base/adapter.py +++ b/django/contrib/gis/db/backends/base/adapter.py @@ -1,4 +1,4 @@ -class WKTAdapter(object): +class WKTAdapter: """ This provides an adaptor for Geometries sent to the MySQL and Oracle database backends. diff --git a/django/contrib/gis/db/backends/base/features.py b/django/contrib/gis/db/backends/base/features.py index 5ca28813301c..85faba2d4209 100644 --- a/django/contrib/gis/db/backends/base/features.py +++ b/django/contrib/gis/db/backends/base/features.py @@ -3,7 +3,7 @@ from django.contrib.gis.db.models import aggregates -class BaseSpatialFeatures(object): +class BaseSpatialFeatures: gis_enabled = True # Does the database contain a SpatialRefSys model to store SRID information? diff --git a/django/contrib/gis/db/backends/base/models.py b/django/contrib/gis/db/backends/base/models.py index 8388a27f2556..89c89a734838 100644 --- a/django/contrib/gis/db/backends/base/models.py +++ b/django/contrib/gis/db/backends/base/models.py @@ -1,7 +1,7 @@ from django.contrib.gis import gdal -class SpatialRefSysMixin(object): +class SpatialRefSysMixin: """ The SpatialRefSysMixin is a class used by the database-dependent SpatialRefSys objects to reduce redundant code. diff --git a/django/contrib/gis/db/backends/base/operations.py b/django/contrib/gis/db/backends/base/operations.py index 436a703e3e28..23989da9fc8c 100644 --- a/django/contrib/gis/db/backends/base/operations.py +++ b/django/contrib/gis/db/backends/base/operations.py @@ -1,4 +1,4 @@ -class BaseSpatialOperations(object): +class BaseSpatialOperations: """ This module holds the base `BaseSpatialBackend` object, which is instantiated by each spatial database backend with the features diff --git a/django/contrib/gis/db/backends/postgis/adapter.py b/django/contrib/gis/db/backends/postgis/adapter.py index c94268811b5a..84ec5bfae934 100644 --- a/django/contrib/gis/db/backends/postgis/adapter.py +++ b/django/contrib/gis/db/backends/postgis/adapter.py @@ -8,7 +8,7 @@ from django.contrib.gis.geometry.backend import Geometry -class PostGISAdapter(object): +class PostGISAdapter: def __init__(self, obj, geography=False): """ Initialize on the spatial object. diff --git a/django/contrib/gis/db/backends/utils.py b/django/contrib/gis/db/backends/utils.py index 9c3b700852ca..d479009d4eb2 100644 --- a/django/contrib/gis/db/backends/utils.py +++ b/django/contrib/gis/db/backends/utils.py @@ -4,7 +4,7 @@ """ -class SpatialOperator(object): +class SpatialOperator: """ Class encapsulating the behavior specific to a GIS operation (used by lookups). """ diff --git a/django/contrib/gis/db/models/fields.py b/django/contrib/gis/db/models/fields.py index 6435dc407714..101975ed8790 100644 --- a/django/contrib/gis/db/models/fields.py +++ b/django/contrib/gis/db/models/fields.py @@ -48,7 +48,7 @@ def get_srid_info(srid, connection): return _srid_cache[alias][srid] -class GeoSelectFormatMixin(object): +class GeoSelectFormatMixin: def select_format(self, compiler, sql, params): """ Returns the selection format string, depending on the requirements diff --git a/django/contrib/gis/db/models/functions.py b/django/contrib/gis/db/models/functions.py index 77628afa3464..0a5c14f7a76a 100644 --- a/django/contrib/gis/db/models/functions.py +++ b/django/contrib/gis/db/models/functions.py @@ -100,7 +100,7 @@ def __init__(self, expression, geom, *expressions, **extra): super(GeoFuncWithGeoParam, self).__init__(expression, GeomValue(geom), *expressions, **extra) -class SQLiteDecimalToFloatMixin(object): +class SQLiteDecimalToFloatMixin: """ By default, Decimal values are converted to str by the SQLite backend, which is not acceptable by the GIS functions expecting numeric values. @@ -112,7 +112,7 @@ def as_sqlite(self, compiler, connection): return super(SQLiteDecimalToFloatMixin, self).as_sql(compiler, connection) -class OracleToleranceMixin(object): +class OracleToleranceMixin: tolerance = 0.05 def as_oracle(self, compiler, connection): @@ -230,7 +230,7 @@ class Difference(OracleToleranceMixin, GeoFuncWithGeoParam): arity = 2 -class DistanceResultMixin(object): +class DistanceResultMixin: def source_is_geography(self): return self.get_source_fields()[0].geography and self.srid == 4326 diff --git a/django/contrib/gis/db/models/sql/conversion.py b/django/contrib/gis/db/models/sql/conversion.py index 054628d481c8..ed414ca76ef2 100644 --- a/django/contrib/gis/db/models/sql/conversion.py +++ b/django/contrib/gis/db/models/sql/conversion.py @@ -9,7 +9,7 @@ from django.contrib.gis.measure import Area, Distance -class BaseField(object): +class BaseField: empty_strings_allowed = True def get_db_converters(self, connection): diff --git a/django/contrib/gis/feeds.py b/django/contrib/gis/feeds.py index 4240968f19b3..807a313bf444 100644 --- a/django/contrib/gis/feeds.py +++ b/django/contrib/gis/feeds.py @@ -2,7 +2,7 @@ from django.utils.feedgenerator import Atom1Feed, Rss201rev2Feed -class GeoFeedMixin(object): +class GeoFeedMixin: """ This mixin provides the necessary routines for SyndicationFeed subclasses to produce simple GeoRSS or W3C Geo elements. diff --git a/django/contrib/gis/gdal/envelope.py b/django/contrib/gis/gdal/envelope.py index 64cac5baa072..e7c7e3dde1b7 100644 --- a/django/contrib/gis/gdal/envelope.py +++ b/django/contrib/gis/gdal/envelope.py @@ -27,7 +27,7 @@ class OGREnvelope(Structure): ] -class Envelope(object): +class Envelope: """ The Envelope object is a C structure that contains the minimum and maximum X, Y coordinates for a rectangle bounding box. The naming diff --git a/django/contrib/gis/gdal/geomtype.py b/django/contrib/gis/gdal/geomtype.py index 37539c85443b..e727d495fb92 100644 --- a/django/contrib/gis/gdal/geomtype.py +++ b/django/contrib/gis/gdal/geomtype.py @@ -1,7 +1,7 @@ from django.contrib.gis.gdal.error import GDALException -class OGRGeomType(object): +class OGRGeomType: "Encapsulates OGR Geometry Types." wkb25bit = -2147483648 diff --git a/django/contrib/gis/geoip2/base.py b/django/contrib/gis/geoip2/base.py index 1d1e2e00dc4f..5f8abfc00885 100644 --- a/django/contrib/gis/geoip2/base.py +++ b/django/contrib/gis/geoip2/base.py @@ -21,7 +21,7 @@ class GeoIP2Exception(Exception): pass -class GeoIP2(object): +class GeoIP2: # The flags for GeoIP memory caching. # Try MODE_MMAP_EXT, MODE_MMAP, MODE_FILE in that order. MODE_AUTO = 0 diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py index e015fdc3d52a..2ff4037764e4 100644 --- a/django/contrib/gis/geos/geometry.py +++ b/django/contrib/gis/geos/geometry.py @@ -656,7 +656,7 @@ def clone(self): return GEOSGeometry(capi.geom_clone(self.ptr), srid=self.srid) -class LinearGeometryMixin(object): +class LinearGeometryMixin: """ Used for LineString and MultiLineString. """ diff --git a/django/contrib/gis/geos/libgeos.py b/django/contrib/gis/geos/libgeos.py index 48532d5c53ad..faf29de0c1b5 100644 --- a/django/contrib/gis/geos/libgeos.py +++ b/django/contrib/gis/geos/libgeos.py @@ -139,7 +139,7 @@ def get_pointer_arr(n): lgeos = SimpleLazyObject(load_geos) -class GEOSFuncFactory(object): +class GEOSFuncFactory: """ Lazy loading of GEOS functions. """ diff --git a/django/contrib/gis/geos/mutable_list.py b/django/contrib/gis/geos/mutable_list.py index 082f3b161a4c..d6e36db31ab3 100644 --- a/django/contrib/gis/geos/mutable_list.py +++ b/django/contrib/gis/geos/mutable_list.py @@ -12,7 +12,7 @@ @total_ordering -class ListMixin(object): +class ListMixin: """ A base class which provides complete list interface. Derived classes must call ListMixin's __init__() function diff --git a/django/contrib/gis/geos/prototypes/threadsafe.py b/django/contrib/gis/geos/prototypes/threadsafe.py index a293671b5fb2..606b8f5aec8a 100644 --- a/django/contrib/gis/geos/prototypes/threadsafe.py +++ b/django/contrib/gis/geos/prototypes/threadsafe.py @@ -28,7 +28,7 @@ class GEOSContext(threading.local): thread_context = GEOSContext() -class GEOSFunc(object): +class GEOSFunc: """ Class that serves as a wrapper for GEOS C Functions, and will use thread-safe function variants when available. diff --git a/django/contrib/gis/measure.py b/django/contrib/gis/measure.py index a9b9e8a75f13..bc426b597b06 100644 --- a/django/contrib/gis/measure.py +++ b/django/contrib/gis/measure.py @@ -49,7 +49,7 @@ def pretty_name(obj): @total_ordering -class MeasureBase(object): +class MeasureBase: STANDARD_UNIT = None ALIAS = {} UNITS = {} diff --git a/django/contrib/gis/ptr.py b/django/contrib/gis/ptr.py index 7d6a21a12f45..afc83fdd228f 100644 --- a/django/contrib/gis/ptr.py +++ b/django/contrib/gis/ptr.py @@ -1,7 +1,7 @@ from ctypes import c_void_p -class CPointerBase(object): +class CPointerBase: """ Base class for objects that have a pointer access property that controls access to the underlying C pointer. diff --git a/django/contrib/gis/serializers/geojson.py b/django/contrib/gis/serializers/geojson.py index 1b50ee30d83a..3a4c0c87bf55 100644 --- a/django/contrib/gis/serializers/geojson.py +++ b/django/contrib/gis/serializers/geojson.py @@ -65,6 +65,6 @@ def handle_field(self, obj, field): super(Serializer, self).handle_field(obj, field) -class Deserializer(object): +class Deserializer: def __init__(self, *args, **kwargs): raise SerializerDoesNotExist("geojson is a serialization-only serializer") diff --git a/django/contrib/gis/utils/layermapping.py b/django/contrib/gis/utils/layermapping.py index a10e9bbeb89d..9093ae84d6f0 100644 --- a/django/contrib/gis/utils/layermapping.py +++ b/django/contrib/gis/utils/layermapping.py @@ -45,7 +45,7 @@ class MissingForeignKey(LayerMapError): pass -class LayerMapping(object): +class LayerMapping: "A class that maps OGR Layers to GeoDjango Models." # Acceptable 'base' types for a multi-geometry type. diff --git a/django/contrib/messages/storage/base.py b/django/contrib/messages/storage/base.py index 66cd41684bfa..28c81599a783 100644 --- a/django/contrib/messages/storage/base.py +++ b/django/contrib/messages/storage/base.py @@ -5,7 +5,7 @@ LEVEL_TAGS = utils.get_level_tags() -class Message(object): +class Message: """ Represents an actual message that can be stored in any of the supported storage classes (typically session- or cookie-based) and rendered in a view @@ -51,7 +51,7 @@ def level_tag(self): return force_text(LEVEL_TAGS.get(self.level, ''), strings_only=True) -class BaseStorage(object): +class BaseStorage: """ This is the base backend for temporary message storage. diff --git a/django/contrib/messages/views.py b/django/contrib/messages/views.py index 3c2ca355ba45..adb3f194b9fb 100644 --- a/django/contrib/messages/views.py +++ b/django/contrib/messages/views.py @@ -1,7 +1,7 @@ from django.contrib import messages -class SuccessMessageMixin(object): +class SuccessMessageMixin: """ Adds a success message on successful form submission. """ diff --git a/django/contrib/postgres/fields/array.py b/django/contrib/postgres/fields/array.py index dc5b9b8d6b71..ce4c7b8c3d07 100644 --- a/django/contrib/postgres/fields/array.py +++ b/django/contrib/postgres/fields/array.py @@ -264,7 +264,7 @@ def output_field(self): return self.base_field -class IndexTransformFactory(object): +class IndexTransformFactory: def __init__(self, index, base_field): self.index = index @@ -286,7 +286,7 @@ def as_sql(self, compiler, connection): return '%s[%s:%s]' % (lhs, self.start, self.end), params -class SliceTransformFactory(object): +class SliceTransformFactory: def __init__(self, start, end): self.start = start diff --git a/django/contrib/postgres/fields/hstore.py b/django/contrib/postgres/fields/hstore.py index fcd212bc4a4a..5e2e6c3155dc 100644 --- a/django/contrib/postgres/fields/hstore.py +++ b/django/contrib/postgres/fields/hstore.py @@ -88,7 +88,7 @@ def as_sql(self, compiler, connection): return "(%s -> '%s')" % (lhs, self.key_name), params -class KeyTransformFactory(object): +class KeyTransformFactory: def __init__(self, key_name): self.key_name = key_name diff --git a/django/contrib/postgres/fields/jsonb.py b/django/contrib/postgres/fields/jsonb.py index 0722a05a69c2..43997050feed 100644 --- a/django/contrib/postgres/fields/jsonb.py +++ b/django/contrib/postgres/fields/jsonb.py @@ -118,7 +118,7 @@ class KeyTextTransform(KeyTransform): _output_field = TextField() -class KeyTransformTextLookupMixin(object): +class KeyTransformTextLookupMixin: """ Mixin for combining with a lookup expecting a text lhs from a JSONField key lookup. Make use of the ->> operator instead of casting key values to @@ -174,7 +174,7 @@ class KeyTransformIRegex(KeyTransformTextLookupMixin, builtin_lookups.IRegex): KeyTransform.register_lookup(KeyTransformIRegex) -class KeyTransformFactory(object): +class KeyTransformFactory: def __init__(self, key_name): self.key_name = key_name diff --git a/django/contrib/postgres/fields/utils.py b/django/contrib/postgres/fields/utils.py index 424a78f52134..82da93e892b0 100644 --- a/django/contrib/postgres/fields/utils.py +++ b/django/contrib/postgres/fields/utils.py @@ -1,3 +1,3 @@ -class AttributeSetter(object): +class AttributeSetter: def __init__(self, name, value): setattr(self, name, value) diff --git a/django/contrib/postgres/search.py b/django/contrib/postgres/search.py index fb2f41b524dd..bc9bb1052bd3 100644 --- a/django/contrib/postgres/search.py +++ b/django/contrib/postgres/search.py @@ -33,7 +33,7 @@ def db_type(self, connection): return 'tsquery' -class SearchVectorCombinable(object): +class SearchVectorCombinable: ADD = '||' def _combine(self, other, connector, reversed, node=None): @@ -92,7 +92,7 @@ def __init__(self, lhs, connector, rhs, config, output_field=None): super(CombinedSearchVector, self).__init__(lhs, connector, rhs, output_field) -class SearchQueryCombinable(object): +class SearchQueryCombinable: BITAND = '&&' BITOR = '||' diff --git a/django/contrib/postgres/validators.py b/django/contrib/postgres/validators.py index 756ae7344062..a1aef1201550 100644 --- a/django/contrib/postgres/validators.py +++ b/django/contrib/postgres/validators.py @@ -24,7 +24,7 @@ class ArrayMinLengthValidator(MinLengthValidator): @deconstructible -class KeysValidator(object): +class KeysValidator: """A validator designed for HStore to require/restrict keys.""" messages = { diff --git a/django/contrib/sessions/backends/base.py b/django/contrib/sessions/backends/base.py index 615eea45d2a9..009efe94e1ff 100644 --- a/django/contrib/sessions/backends/base.py +++ b/django/contrib/sessions/backends/base.py @@ -33,7 +33,7 @@ class UpdateError(Exception): pass -class SessionBase(object): +class SessionBase: """ Base class for all Session classes. """ diff --git a/django/contrib/sessions/serializers.py b/django/contrib/sessions/serializers.py index 1badd17f46a8..1df6d9c49e82 100644 --- a/django/contrib/sessions/serializers.py +++ b/django/contrib/sessions/serializers.py @@ -3,7 +3,7 @@ from django.core.signing import JSONSerializer as BaseJSONSerializer -class PickleSerializer(object): +class PickleSerializer: """ Simple wrapper around pickle to be used in signing.dumps and signing.loads. diff --git a/django/contrib/sitemaps/__init__.py b/django/contrib/sitemaps/__init__.py index 6e30a30f093f..71d36e6a3cd4 100644 --- a/django/contrib/sitemaps/__init__.py +++ b/django/contrib/sitemaps/__init__.py @@ -50,7 +50,7 @@ def _get_sitemap_full_url(sitemap_url): return 'http://%s%s' % (current_site.domain, sitemap_url) -class Sitemap(object): +class Sitemap: # This limit is defined by Google. See the index documentation at # http://www.sitemaps.org/protocol.html#index. limit = 50000 diff --git a/django/contrib/sites/requests.py b/django/contrib/sites/requests.py index c5513d835881..cdf57321da49 100644 --- a/django/contrib/sites/requests.py +++ b/django/contrib/sites/requests.py @@ -1,4 +1,4 @@ -class RequestSite(object): +class RequestSite: """ A class that shares the primary interface of Site (i.e., it has ``domain`` and ``name`` attributes) but gets its data from a Django diff --git a/django/contrib/staticfiles/finders.py b/django/contrib/staticfiles/finders.py index 96dd705050a4..08b25181bcef 100644 --- a/django/contrib/staticfiles/finders.py +++ b/django/contrib/staticfiles/finders.py @@ -17,7 +17,7 @@ searched_locations = [] -class BaseFinder(object): +class BaseFinder: """ A base file finder to be used for custom staticfiles finder classes. """ diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py index fe4a7c39f74e..46b751b09409 100644 --- a/django/contrib/staticfiles/storage.py +++ b/django/contrib/staticfiles/storage.py @@ -47,7 +47,7 @@ def path(self, name): return super(StaticFilesStorage, self).path(name) -class HashedFilesMixin(object): +class HashedFilesMixin: default_template = """url("%s")""" max_post_process_passes = 5 patterns = ( @@ -434,7 +434,7 @@ def stored_name(self, name): return urlunsplit(unparsed_name) -class _MappingCache(object): +class _MappingCache: """ A small dict-like wrapper for a given cache backend instance. """ diff --git a/django/contrib/syndication/views.py b/django/contrib/syndication/views.py index 2cfe93033836..8104d6104b77 100644 --- a/django/contrib/syndication/views.py +++ b/django/contrib/syndication/views.py @@ -26,7 +26,7 @@ class FeedDoesNotExist(ObjectDoesNotExist): pass -class Feed(object): +class Feed: feed_type = feedgenerator.DefaultFeed title_template = None description_template = None diff --git a/django/core/cache/__init__.py b/django/core/cache/__init__.py index 2b253b1077f8..d51c1cb38e91 100644 --- a/django/core/cache/__init__.py +++ b/django/core/cache/__init__.py @@ -55,7 +55,7 @@ def _create_cache(backend, **kwargs): return backend_cls(location, params) -class CacheHandler(object): +class CacheHandler: """ A Cache Handler to manage access to Cache instances. @@ -88,7 +88,7 @@ def all(self): caches = CacheHandler() -class DefaultCacheProxy(object): +class DefaultCacheProxy: """ Proxy access to the default Cache object's attributes. diff --git a/django/core/cache/backends/base.py b/django/core/cache/backends/base.py index 856316b4004d..2d5b0634a1e5 100644 --- a/django/core/cache/backends/base.py +++ b/django/core/cache/backends/base.py @@ -47,7 +47,7 @@ def get_key_func(key_func): return default_key_func -class BaseCache(object): +class BaseCache: def __init__(self, params): timeout = params.get('timeout', params.get('TIMEOUT', 300)) if timeout is not None: diff --git a/django/core/cache/backends/db.py b/django/core/cache/backends/db.py index 97f307e24dfb..50d897b62176 100644 --- a/django/core/cache/backends/db.py +++ b/django/core/cache/backends/db.py @@ -10,7 +10,7 @@ from django.utils.encoding import force_bytes -class Options(object): +class Options: """A class that will quack like a Django model _meta class. This allows cache operations to be controlled by the router @@ -33,7 +33,7 @@ def __init__(self, table, params): BaseCache.__init__(self, params) self._table = table - class CacheEntry(object): + class CacheEntry: _meta = Options(table) self.cache_model_class = CacheEntry diff --git a/django/core/checks/messages.py b/django/core/checks/messages.py index 5bb292503f7f..0c44d350959d 100644 --- a/django/core/checks/messages.py +++ b/django/core/checks/messages.py @@ -8,7 +8,7 @@ CRITICAL = 50 -class CheckMessage(object): +class CheckMessage: def __init__(self, level, msg, hint=None, obj=None, id=None): assert isinstance(level, int), "The first argument should be level." diff --git a/django/core/checks/registry.py b/django/core/checks/registry.py index 4a2b358dc89b..581783ad0bb3 100644 --- a/django/core/checks/registry.py +++ b/django/core/checks/registry.py @@ -3,7 +3,7 @@ from django.utils.itercompat import is_iterable -class Tags(object): +class Tags: """ Built-in tags for internal checks. """ @@ -18,7 +18,7 @@ class Tags(object): urls = 'urls' -class CheckRegistry(object): +class CheckRegistry: def __init__(self): self.registered_checks = [] diff --git a/django/core/files/storage.py b/django/core/files/storage.py index cf17eea33989..6f2d6bfd9178 100644 --- a/django/core/files/storage.py +++ b/django/core/files/storage.py @@ -20,7 +20,7 @@ __all__ = ('Storage', 'FileSystemStorage', 'DefaultStorage', 'default_storage') -class Storage(object): +class Storage: """ A base storage class, providing some default behaviors that all other storage systems can inherit or override, as necessary. diff --git a/django/core/files/uploadhandler.py b/django/core/files/uploadhandler.py index 3741f372b2db..e8f87845c98b 100644 --- a/django/core/files/uploadhandler.py +++ b/django/core/files/uploadhandler.py @@ -58,7 +58,7 @@ class StopFutureHandlers(UploadFileException): pass -class FileUploadHandler(object): +class FileUploadHandler: """ Base class for streaming upload handlers. """ diff --git a/django/core/files/utils.py b/django/core/files/utils.py index 8e891bf23f8a..96bfbe46c2e1 100644 --- a/django/core/files/utils.py +++ b/django/core/files/utils.py @@ -1,4 +1,4 @@ -class FileProxyMixin(object): +class FileProxyMixin: """ A mixin class used to forward file methods to an underlaying file object. The internal file object has to be called "file":: diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py index c45023d1290c..9b794395698f 100644 --- a/django/core/handlers/base.py +++ b/django/core/handlers/base.py @@ -12,7 +12,7 @@ logger = logging.getLogger('django.request') -class BaseHandler(object): +class BaseHandler: def __init__(self): self._request_middleware = None diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index f4d3e6553acb..69b5f1c54d3d 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -19,7 +19,7 @@ _slashes_re = re.compile(br'/+') -class LimitedStream(object): +class LimitedStream: ''' LimitedStream wraps another stream in order to not allow reading from it past specified amount of bytes. diff --git a/django/core/mail/backends/base.py b/django/core/mail/backends/base.py index 4914f479b9cd..e0d2e3626b37 100644 --- a/django/core/mail/backends/base.py +++ b/django/core/mail/backends/base.py @@ -1,7 +1,7 @@ """Base email backend class.""" -class BaseEmailBackend(object): +class BaseEmailBackend: """ Base class for email backend implementations. diff --git a/django/core/mail/message.py b/django/core/mail/message.py index 117f2dddfc8d..f8fd6c2d2527 100644 --- a/django/core/mail/message.py +++ b/django/core/mail/message.py @@ -223,7 +223,7 @@ def __setitem__(self, name, val): MIMEMultipart.__setitem__(self, name, val) -class EmailMessage(object): +class EmailMessage: """ A container for email information. """ diff --git a/django/core/mail/utils.py b/django/core/mail/utils.py index 9295759fadd0..d18dfe46672b 100644 --- a/django/core/mail/utils.py +++ b/django/core/mail/utils.py @@ -7,7 +7,7 @@ # Cache the hostname, but do it lazily: socket.getfqdn() can take a couple of # seconds, which slows down the restart of the server. -class CachedDnsName(object): +class CachedDnsName: def __str__(self): return self.get_fqdn() diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py index 0200f77e7d08..1b59dac68680 100644 --- a/django/core/management/__init__.py +++ b/django/core/management/__init__.py @@ -129,7 +129,7 @@ def call_command(command_name, *args, **options): return command.execute(*args, **defaults) -class ManagementUtility(object): +class ManagementUtility: """ Encapsulates the logic of the django-admin and manage.py utilities. diff --git a/django/core/management/base.py b/django/core/management/base.py index 192d529ef04b..ae8c6731c960 100644 --- a/django/core/management/base.py +++ b/django/core/management/base.py @@ -73,7 +73,7 @@ def handle_default_options(options): sys.path.insert(0, options.pythonpath) -class OutputWrapper(object): +class OutputWrapper: """ Wrapper around stdout/stderr """ @@ -107,7 +107,7 @@ def write(self, msg, style_func=None, ending=None): self._out.write(force_str(style_func(msg))) -class BaseCommand(object): +class BaseCommand: """ The base class from which all management commands ultimately derive. diff --git a/django/core/management/color.py b/django/core/management/color.py index 76985420cba9..4519d2902576 100644 --- a/django/core/management/color.py +++ b/django/core/management/color.py @@ -24,7 +24,7 @@ def supports_color(): return True -class Style(object): +class Style: pass diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py index dc505173b12e..830b6efe05ef 100644 --- a/django/core/management/commands/makemessages.py +++ b/django/core/management/commands/makemessages.py @@ -36,7 +36,7 @@ def check_programs(*programs): @total_ordering -class TranslatableFile(object): +class TranslatableFile: def __init__(self, dirpath, file_name, locale_dir): self.file = file_name self.dirpath = dirpath @@ -59,7 +59,7 @@ def path(self): return os.path.join(self.dirpath, self.file) -class BuildFile(object): +class BuildFile: """ Represents the state of a translatable file during the build process. """ diff --git a/django/core/paginator.py b/django/core/paginator.py index 82aad33a157e..abc29b3603c5 100644 --- a/django/core/paginator.py +++ b/django/core/paginator.py @@ -22,7 +22,7 @@ class EmptyPage(InvalidPage): pass -class Paginator(object): +class Paginator: def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True): diff --git a/django/core/serializers/__init__.py b/django/core/serializers/__init__.py index 57d149cf0c99..3d0ed9a13ff4 100644 --- a/django/core/serializers/__init__.py +++ b/django/core/serializers/__init__.py @@ -33,7 +33,7 @@ _serializers = {} -class BadSerializer(object): +class BadSerializer: """ Stub serializer to hold exception raised during registration @@ -71,7 +71,7 @@ def register_serializer(format, serializer_module, serializers=None): except ImportError as exc: bad_serializer = BadSerializer(exc) - module = type('BadSerializerModule', (object,), { + module = type('BadSerializerModule', (), { 'Deserializer': bad_serializer, 'Serializer': bad_serializer, }) diff --git a/django/core/serializers/base.py b/django/core/serializers/base.py index bd35c0b79787..d1a534406426 100644 --- a/django/core/serializers/base.py +++ b/django/core/serializers/base.py @@ -28,7 +28,7 @@ def WithData(cls, original_exc, model, fk, field_value): return cls("%s: (%s:pk=%s) field_value was '%s'" % (original_exc, model, fk, field_value)) -class ProgressBar(object): +class ProgressBar: progress_width = 75 def __init__(self, output, total_count): @@ -51,7 +51,7 @@ def update(self, count): self.output.flush() -class Serializer(object): +class Serializer: """ Abstract serializer base class. """ @@ -182,7 +182,7 @@ def __next__(self): raise NotImplementedError('subclasses of Deserializer must provide a __next__() method') -class DeserializedObject(object): +class DeserializedObject: """ A deserialized model. diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index da55eac58d32..0b76b14f0466 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -60,7 +60,7 @@ def is_broken_pipe_error(): return issubclass(exc_type, socket.error) and exc_value.args[0] == 32 -class WSGIServer(simple_server.WSGIServer, object): +class WSGIServer(simple_server.WSGIServer): """BaseHTTPServer that implements the Python WSGI protocol""" request_queue_size = 10 @@ -84,14 +84,14 @@ def handle_error(self, request, client_address): # Inheriting from object required on Python 2. -class ServerHandler(simple_server.ServerHandler, object): +class ServerHandler(simple_server.ServerHandler): def handle_error(self): # Ignore broken pipe errors, otherwise pass on if not is_broken_pipe_error(): super(ServerHandler, self).handle_error() -class WSGIRequestHandler(simple_server.WSGIRequestHandler, object): +class WSGIRequestHandler(simple_server.WSGIRequestHandler): def address_string(self): # Short-circuit parent method to not call socket.getfqdn return self.client_address[0] diff --git a/django/core/signing.py b/django/core/signing.py index f578da6f99c4..811d23396fc2 100644 --- a/django/core/signing.py +++ b/django/core/signing.py @@ -82,7 +82,7 @@ def get_cookie_signer(salt='django.core.signing.get_cookie_signer'): return Signer(b'django.http.cookies' + key, salt=salt) -class JSONSerializer(object): +class JSONSerializer: """ Simple wrapper around json to be used in signing.dumps and signing.loads. @@ -147,7 +147,7 @@ def loads(s, key=None, salt='django.core.signing', serializer=JSONSerializer, ma return serializer().loads(data) -class Signer(object): +class Signer: def __init__(self, key=None, sep=':', salt=None): # Use of native strings in all versions of Python diff --git a/django/core/validators.py b/django/core/validators.py index 1bb247812977..715d81bdbaf4 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -26,7 +26,7 @@ def _compile(): @deconstructible -class RegexValidator(object): +class RegexValidator: regex = '' message = _('Enter a valid value.') code = 'invalid' @@ -162,7 +162,7 @@ def validate_integer(value): @deconstructible -class EmailValidator(object): +class EmailValidator: message = _('Enter a valid email address.') code = 'invalid' user_regex = _lazy_re_compile( @@ -305,7 +305,7 @@ def int_list_validator(sep=',', message=None, code='invalid', allow_negative=Fal @deconstructible -class BaseValidator(object): +class BaseValidator: message = _('Ensure this value is %(limit_value)s (it is %(show_value)s).') code = 'limit_value' @@ -384,7 +384,7 @@ def clean(self, x): @deconstructible -class DecimalValidator(object): +class DecimalValidator: """ Validate that the input does not exceed the maximum number of digits expected, otherwise raise ValidationError. @@ -453,7 +453,7 @@ def __eq__(self, other): @deconstructible -class FileExtensionValidator(object): +class FileExtensionValidator: message = _( "File extension '%(extension)s' is not allowed. " "Allowed extensions are: '%(allowed_extensions)s'." diff --git a/django/db/__init__.py b/django/db/__init__.py index a00dc788dcef..5708c1c5de45 100644 --- a/django/db/__init__.py +++ b/django/db/__init__.py @@ -23,7 +23,7 @@ # that the database backends care about. # We load all these up for backwards compatibility, you should use # connections['default'] instead. -class DefaultConnectionProxy(object): +class DefaultConnectionProxy: """ Proxy for accessing the default DatabaseWrapper object's attributes. If you need to access the DatabaseWrapper object itself, use diff --git a/django/db/backends/base/base.py b/django/db/backends/base/base.py index ea976519ec74..d255bf3e0f30 100644 --- a/django/db/backends/base/base.py +++ b/django/db/backends/base/base.py @@ -21,7 +21,7 @@ NO_DB_ALIAS = '__no_db__' -class BaseDatabaseWrapper(object): +class BaseDatabaseWrapper: """ Represents a database connection. """ diff --git a/django/db/backends/base/client.py b/django/db/backends/base/client.py index aced8e7ebd4f..69e061b4e976 100644 --- a/django/db/backends/base/client.py +++ b/django/db/backends/base/client.py @@ -1,4 +1,4 @@ -class BaseDatabaseClient(object): +class BaseDatabaseClient: """ This class encapsulates all backend-specific methods for opening a client shell. diff --git a/django/db/backends/base/creation.py b/django/db/backends/base/creation.py index cf3e6c334795..a291f43f5591 100644 --- a/django/db/backends/base/creation.py +++ b/django/db/backends/base/creation.py @@ -11,7 +11,7 @@ TEST_DATABASE_PREFIX = 'test_' -class BaseDatabaseCreation(object): +class BaseDatabaseCreation: """ This class encapsulates all backend-specific differences that pertain to creation and destruction of the test database. diff --git a/django/db/backends/base/features.py b/django/db/backends/base/features.py index dfcb719eae08..8f9fbdcfea38 100644 --- a/django/db/backends/base/features.py +++ b/django/db/backends/base/features.py @@ -3,7 +3,7 @@ from django.utils.functional import cached_property -class BaseDatabaseFeatures(object): +class BaseDatabaseFeatures: gis_enabled = False allows_group_by_pk = False allows_group_by_selected_pks = False diff --git a/django/db/backends/base/introspection.py b/django/db/backends/base/introspection.py index 55fffb993e5d..07f1312356e6 100644 --- a/django/db/backends/base/introspection.py +++ b/django/db/backends/base/introspection.py @@ -7,7 +7,7 @@ FieldInfo = namedtuple('FieldInfo', 'name type_code display_size internal_size precision scale null_ok default') -class BaseDatabaseIntrospection(object): +class BaseDatabaseIntrospection: """ This class encapsulates all backend-specific introspection utilities """ diff --git a/django/db/backends/base/operations.py b/django/db/backends/base/operations.py index 6f1248efc140..22beb0d41739 100644 --- a/django/db/backends/base/operations.py +++ b/django/db/backends/base/operations.py @@ -10,7 +10,7 @@ from django.utils.encoding import force_text -class BaseDatabaseOperations(object): +class BaseDatabaseOperations: """ This class encapsulates all backend-specific differences, such as the way a backend performs ordering or calculates the ID of a recently-inserted diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py index 6cb6826a7fb9..70edc0518383 100644 --- a/django/db/backends/base/schema.py +++ b/django/db/backends/base/schema.py @@ -19,7 +19,7 @@ def _related_non_m2m_objects(old_field, new_field): ) -class BaseDatabaseSchemaEditor(object): +class BaseDatabaseSchemaEditor: """ This class (and its subclasses) are responsible for emitting schema-changing statements to the databases - model creation/removal/alteration, field diff --git a/django/db/backends/base/validation.py b/django/db/backends/base/validation.py index 23761b41612e..d8a05aceaf32 100644 --- a/django/db/backends/base/validation.py +++ b/django/db/backends/base/validation.py @@ -1,4 +1,4 @@ -class BaseDatabaseValidation(object): +class BaseDatabaseValidation: """ This class encapsulates all backend-specific validation. """ diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index f674687ff186..3239ba104fdc 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -69,7 +69,7 @@ # standard backend_utils.CursorDebugWrapper can be used. Also, using sql_mode # TRADITIONAL will automatically cause most warnings to be treated as errors. -class CursorWrapper(object): +class CursorWrapper: """ A thin wrapper around MySQLdb's normal cursor class so that we can catch particular exception instances and reraise them with the right types. diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 257dab0b9d51..7e3591f60ca8 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -59,7 +59,7 @@ def _setup_environment(environ): from .utils import Oracle_datetime # NOQA isort:skip -class _UninitializedOperatorsDescriptor(object): +class _UninitializedOperatorsDescriptor: def __get__(self, instance, cls=None): # If connection.operators is looked up before a connection has been @@ -306,7 +306,7 @@ def oracle_version(self): return None -class OracleParam(object): +class OracleParam: """ Wrapper object for formatting parameters for Oracle. If the string representation of the value is large enough (greater than 4000 characters) @@ -351,7 +351,7 @@ def __init__(self, param, cursor, strings_only=False): self.input_size = None -class VariableWrapper(object): +class VariableWrapper: """ An adapter class for cursor variables that prevents the wrapped object from being converted into a string when used to instantiate an OracleParam. @@ -375,7 +375,7 @@ def __setattr__(self, key, value): setattr(self.var, key, value) -class FormatStylePlaceholderCursor(object): +class FormatStylePlaceholderCursor: """ Django uses "format" (e.g. '%s') style placeholders, but Oracle uses ":var" style. This fixes it -- but note that if you want to use a literal "%s" in diff --git a/django/db/backends/oracle/utils.py b/django/db/backends/oracle/utils.py index e89a9b70cb30..f958655f940e 100644 --- a/django/db/backends/oracle/utils.py +++ b/django/db/backends/oracle/utils.py @@ -3,7 +3,7 @@ from .base import Database -class InsertIdVar(object): +class InsertIdVar: """ A late-binding cursor variable that can be passed to Cursor.execute as a parameter, in order to receive the id of the row created by an diff --git a/django/db/backends/sqlite3/introspection.py b/django/db/backends/sqlite3/introspection.py index 7d24ca6f2614..730793879d85 100644 --- a/django/db/backends/sqlite3/introspection.py +++ b/django/db/backends/sqlite3/introspection.py @@ -18,7 +18,7 @@ def get_field_size(name): # This light wrapper "fakes" a dictionary interface, because some SQLite data # types include variables in them -- e.g. "varchar(30)" -- and can't be matched # as a simple dictionary lookup. -class FlexibleFieldLookupDict(object): +class FlexibleFieldLookupDict: # Maps SQL types to Django Field types. Some of the SQL types have multiple # entries here because SQLite allows for anything and doesn't normalize the # field type; it uses whatever was given. diff --git a/django/db/backends/utils.py b/django/db/backends/utils.py index b72840e989e1..f6cb59a08604 100644 --- a/django/db/backends/utils.py +++ b/django/db/backends/utils.py @@ -11,7 +11,7 @@ logger = logging.getLogger('django.db.backends') -class CursorWrapper(object): +class CursorWrapper: def __init__(self, cursor, db): self.cursor = cursor self.db = db diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py index d2b6f6d49743..b8ac6c942b0a 100644 --- a/django/db/migrations/autodetector.py +++ b/django/db/migrations/autodetector.py @@ -16,7 +16,7 @@ from .topological_sort import stable_topological_sort -class MigrationAutodetector(object): +class MigrationAutodetector: """ Takes a pair of ProjectStates, and compares them to see what the first would need doing to make it match the second (the second diff --git a/django/db/migrations/executor.py b/django/db/migrations/executor.py index a590a0aca3f4..13ae9a68a1b4 100644 --- a/django/db/migrations/executor.py +++ b/django/db/migrations/executor.py @@ -7,7 +7,7 @@ from .state import ProjectState -class MigrationExecutor(object): +class MigrationExecutor: """ End-to-end migration execution - loads migrations, and runs them up or down to a specified set of targets. diff --git a/django/db/migrations/graph.py b/django/db/migrations/graph.py index 1729aa7b7a7d..1d144d7d253b 100644 --- a/django/db/migrations/graph.py +++ b/django/db/migrations/graph.py @@ -18,7 +18,7 @@ @total_ordering -class Node(object): +class Node: """ A single node in the migration graph. Contains direct links to adjacent nodes in either direction. @@ -100,7 +100,7 @@ def raise_error(self): raise NodeNotFoundError(self.error_message, self.key, origin=self.origin) -class MigrationGraph(object): +class MigrationGraph: """ Represents the digraph of all migrations in a project. diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py index 492ad145fd8a..1237a37c2619 100644 --- a/django/db/migrations/loader.py +++ b/django/db/migrations/loader.py @@ -16,7 +16,7 @@ MIGRATIONS_MODULE_NAME = 'migrations' -class MigrationLoader(object): +class MigrationLoader: """ Loads migration files from disk, and their status from the database. diff --git a/django/db/migrations/migration.py b/django/db/migrations/migration.py index 5b6bb647c9d5..eb0bfa8b374e 100644 --- a/django/db/migrations/migration.py +++ b/django/db/migrations/migration.py @@ -3,7 +3,7 @@ from .exceptions import IrreversibleError -class Migration(object): +class Migration: """ The base class for all migrations. diff --git a/django/db/migrations/operations/base.py b/django/db/migrations/operations/base.py index f5acf9f3a8e8..8e1f02d7ca60 100644 --- a/django/db/migrations/operations/base.py +++ b/django/db/migrations/operations/base.py @@ -1,7 +1,7 @@ from django.db import router -class Operation(object): +class Operation: """ Base class for migration operations. diff --git a/django/db/migrations/optimizer.py b/django/db/migrations/optimizer.py index ca7f9db60090..9948d5b4bb2f 100644 --- a/django/db/migrations/optimizer.py +++ b/django/db/migrations/optimizer.py @@ -1,4 +1,4 @@ -class MigrationOptimizer(object): +class MigrationOptimizer: """ Powers the optimization process, where you provide a list of Operations and you are returned a list of equal or shorter length - operations diff --git a/django/db/migrations/questioner.py b/django/db/migrations/questioner.py index caae498337eb..f1bc6648286c 100644 --- a/django/db/migrations/questioner.py +++ b/django/db/migrations/questioner.py @@ -9,7 +9,7 @@ from .loader import MigrationLoader -class MigrationQuestioner(object): +class MigrationQuestioner: """ Gives the autodetector responses to questions it might have. This base class has a built-in noninteractive mode, but the diff --git a/django/db/migrations/recorder.py b/django/db/migrations/recorder.py index 7824228c979e..1c4adea1f291 100644 --- a/django/db/migrations/recorder.py +++ b/django/db/migrations/recorder.py @@ -6,7 +6,7 @@ from .exceptions import MigrationSchemaMissing -class MigrationRecorder(object): +class MigrationRecorder: """ Deals with storing migration records in the database. diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index 4786e7b0120e..9e5d74afb964 100644 --- a/django/db/migrations/serializer.py +++ b/django/db/migrations/serializer.py @@ -24,7 +24,7 @@ enum = None -class BaseSerializer(object): +class BaseSerializer: def __init__(self, value): self.value = value diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index 6699b7771357..c0eb583374c0 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -80,7 +80,7 @@ def get_related_models_recursive(model): return seen - {(model._meta.app_label, model._meta.model_name)} -class ProjectState(object): +class ProjectState: """ Represents the entire project's overall state. This is the item that is passed around - we do it here rather than at the @@ -356,7 +356,7 @@ def unregister_model(self, app_label, model_name): pass -class ModelState(object): +class ModelState: """ Represents a Django Model. We don't use the actual Model class as it's not designed to have its options changed - instead, we diff --git a/django/db/migrations/utils.py b/django/db/migrations/utils.py index b54d7ed120d2..8939794e59c0 100644 --- a/django/db/migrations/utils.py +++ b/django/db/migrations/utils.py @@ -4,7 +4,7 @@ COMPILED_REGEX_TYPE = type(re.compile('')) -class RegexObject(object): +class RegexObject: def __init__(self, obj): self.pattern = obj.pattern self.flags = obj.flags diff --git a/django/db/migrations/writer.py b/django/db/migrations/writer.py index ae51a1f0d9d5..be0fece25e99 100644 --- a/django/db/migrations/writer.py +++ b/django/db/migrations/writer.py @@ -34,7 +34,7 @@ def __init__(self, value, setting_name): self.setting_name = setting_name -class OperationWriter(object): +class OperationWriter: def __init__(self, operation, indentation=2): self.operation = operation self.buff = [] @@ -134,7 +134,7 @@ def render(self): return '\n'.join(self.buff) -class MigrationWriter(object): +class MigrationWriter: """ Takes a Migration instance and is able to produce the contents of the migration file from it. diff --git a/django/db/models/base.py b/django/db/models/base.py index 4ee7aa034943..8cba12bb6e39 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -33,7 +33,7 @@ from django.utils.version import get_version -class Deferred(object): +class Deferred: def __repr__(self): return str('') @@ -371,7 +371,7 @@ def _default_manager(cls): return cls._meta.default_manager -class ModelState(object): +class ModelState: """ A class for storing instance state """ diff --git a/django/db/models/deletion.py b/django/db/models/deletion.py index 0793475e65c2..b0c61d179924 100644 --- a/django/db/models/deletion.py +++ b/django/db/models/deletion.py @@ -60,7 +60,7 @@ def get_candidate_relations_to_delete(opts): ) -class Collector(object): +class Collector: def __init__(self, using): self.using = using # Initially, {model: {instances}}, later values become lists. diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 960435f16966..de60a160e070 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -8,7 +8,7 @@ from django.utils.functional import cached_property -class Combinable(object): +class Combinable: """ Provides the ability to combine one or two objects with some connector. For example F('foo') + F('bar'). @@ -123,7 +123,7 @@ def __ror__(self, other): ) -class BaseExpression(object): +class BaseExpression: """ Base class for all query expressions. """ diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 3ac04effc77a..26b0bb237807 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -46,7 +46,7 @@ )] -class Empty(object): +class Empty: pass @@ -1088,7 +1088,7 @@ class CommaSeparatedIntegerField(CharField): } -class DateTimeCheckMixin(object): +class DateTimeCheckMixin: def check(self, **kwargs): errors = super(DateTimeCheckMixin, self).check(**kwargs) @@ -2003,7 +2003,7 @@ def formfield(self, **kwargs): return super(NullBooleanField, self).formfield(**defaults) -class PositiveIntegerRelDbTypeMixin(object): +class PositiveIntegerRelDbTypeMixin: def rel_db_type(self, connection): """ diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index 38dda4c1df2d..1235f657303d 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -131,7 +131,7 @@ def __getstate__(self): return {'name': self.name, 'closed': False, '_committed': True, '_file': None} -class FileDescriptor(object): +class FileDescriptor: """ The descriptor for the file attribute on the model instance. Returns a FieldFile when accessed so you can do stuff like:: diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index b5dd0a2d14b0..bc447452f3c8 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -1023,7 +1023,7 @@ def set_managed(model, related, through): to = 'to_%s' % to from_ = 'from_%s' % from_ - meta = type(str('Meta'), (object,), { + meta = type(str('Meta'), (), { 'db_table': field._get_m2m_db_table(klass._meta), 'auto_created': klass, 'app_label': klass._meta.app_label, diff --git a/django/db/models/fields/related_descriptors.py b/django/db/models/fields/related_descriptors.py index 696dc6f74968..dda455800b8d 100644 --- a/django/db/models/fields/related_descriptors.py +++ b/django/db/models/fields/related_descriptors.py @@ -71,7 +71,7 @@ class Child(Model): from django.utils.functional import cached_property -class ForwardManyToOneDescriptor(object): +class ForwardManyToOneDescriptor: """ Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation. @@ -275,7 +275,7 @@ def get_object(self, instance): return super(ForwardOneToOneDescriptor, self).get_object(instance) -class ReverseOneToOneDescriptor(object): +class ReverseOneToOneDescriptor: """ Accessor to the related object on the reverse side of a one-to-one relation. @@ -435,7 +435,7 @@ def __set__(self, instance, value): setattr(value, self.related.field.get_cache_name(), instance) -class ReverseManyToOneDescriptor(object): +class ReverseManyToOneDescriptor: """ Accessor to the related objects manager on the reverse side of a many-to-one relation. diff --git a/django/db/models/fields/related_lookups.py b/django/db/models/fields/related_lookups.py index bb3194ecd78b..bc80c7cb0238 100644 --- a/django/db/models/fields/related_lookups.py +++ b/django/db/models/fields/related_lookups.py @@ -4,7 +4,7 @@ ) -class MultiColSource(object): +class MultiColSource: contains_aggregate = False def __init__(self, alias, targets, sources, field): @@ -94,7 +94,7 @@ def as_sql(self, compiler, connection): return super(RelatedIn, self).as_sql(compiler, connection) -class RelatedLookupMixin(object): +class RelatedLookupMixin: def get_prep_lookup(self): if not isinstance(self.lhs, MultiColSource) and self.rhs_is_direct_value(): # If we get here, we are dealing with single-column relations. diff --git a/django/db/models/fields/reverse_related.py b/django/db/models/fields/reverse_related.py index 1b706ba6eaeb..4e835e83023e 100644 --- a/django/db/models/fields/reverse_related.py +++ b/django/db/models/fields/reverse_related.py @@ -16,7 +16,7 @@ from . import BLANK_CHOICE_DASH -class ForeignObjectRel(object): +class ForeignObjectRel: """ Used by ForeignObject to store information about the relation. diff --git a/django/db/models/functions/datetime.py b/django/db/models/functions/datetime.py index 269b829e43e3..8bfd8cafef86 100644 --- a/django/db/models/functions/datetime.py +++ b/django/db/models/functions/datetime.py @@ -11,7 +11,7 @@ from django.utils.functional import cached_property -class TimezoneMixin(object): +class TimezoneMixin: tzinfo = None def get_tzname(self): diff --git a/django/db/models/indexes.py b/django/db/models/indexes.py index 27390ccc1835..03aa06fa5240 100644 --- a/django/db/models/indexes.py +++ b/django/db/models/indexes.py @@ -8,7 +8,7 @@ MAX_NAME_LENGTH = 30 -class Index(object): +class Index: suffix = 'idx' def __init__(self, fields=[], name=None): diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py index 4b0914366162..1536ecdc63d2 100644 --- a/django/db/models/lookups.py +++ b/django/db/models/lookups.py @@ -12,7 +12,7 @@ from django.utils.functional import cached_property -class Lookup(object): +class Lookup: lookup_name = None prepare_rhs = True @@ -173,7 +173,7 @@ def get_rhs_op(self, connection, rhs): return connection.operators[self.lookup_name] % rhs -class FieldGetDbPrepValueMixin(object): +class FieldGetDbPrepValueMixin: """ Some lookups require Field.get_db_prep_value() to be called on their inputs. @@ -284,7 +284,7 @@ class LessThanOrEqual(FieldGetDbPrepValueMixin, BuiltinLookup): lookup_name = 'lte' -class IntegerFieldFloatRounding(object): +class IntegerFieldFloatRounding: """ Allow floats to work as query values for IntegerField. Without this, the decimal portion of the float would always be discarded. @@ -305,7 +305,7 @@ class IntegerLessThan(IntegerFieldFloatRounding, LessThan): pass -class DecimalComparisonLookup(object): +class DecimalComparisonLookup: def as_sqlite(self, compiler, connection): lhs_sql, params = self.process_lhs(compiler, connection) rhs_sql, rhs_params = self.process_rhs(compiler, connection) diff --git a/django/db/models/manager.py b/django/db/models/manager.py index bb3d61b08387..2680f699867a 100644 --- a/django/db/models/manager.py +++ b/django/db/models/manager.py @@ -6,7 +6,7 @@ from django.db.models.query import QuerySet -class BaseManager(object): +class BaseManager: # Tracks each time a Manager instance is created. Used to retain order. creation_counter = 0 @@ -168,7 +168,7 @@ class Manager(BaseManager.from_queryset(QuerySet)): pass -class ManagerDescriptor(object): +class ManagerDescriptor: def __init__(self, manager): self.manager = manager diff --git a/django/db/models/options.py b/django/db/models/options.py index 7594b70fb287..8f5603ada4aa 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -66,7 +66,7 @@ def make_immutable_fields_list(name, data): return ImmutableList(data, warning=IMMUTABLE_WARNING % name) -class Options(object): +class Options: FORWARD_PROPERTIES = { 'fields', 'many_to_many', 'concrete_fields', 'local_concrete_fields', '_forward_fields_map', 'managers', 'managers_map', 'base_manager', diff --git a/django/db/models/query.py b/django/db/models/query.py index 1c20d9cbf652..b536521fa44a 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -32,7 +32,7 @@ EmptyResultSet = sql.EmptyResultSet -class BaseIterable(object): +class BaseIterable: def __init__(self, queryset, chunked_fetch=False): self.queryset = queryset self.chunked_fetch = chunked_fetch @@ -152,7 +152,7 @@ def __iter__(self): yield row[0] -class QuerySet(object): +class QuerySet: """ Represents a lazy database lookup for a set of objects. """ @@ -1180,7 +1180,7 @@ def __init__(self, *args, **kwargs): raise TypeError("EmptyQuerySet can't be instantiated") -class RawQuerySet(object): +class RawQuerySet: """ Provides an iterator which converts the results of raw SQL queries into annotated model instances. @@ -1298,7 +1298,7 @@ def model_fields(self): return model_fields -class Prefetch(object): +class Prefetch: def __init__(self, lookup, queryset=None, to_attr=None): # `prefetch_through` is the path we traverse to perform the prefetch. self.prefetch_through = lookup @@ -1623,7 +1623,7 @@ def prefetch_one_level(instances, prefetcher, lookup, level): return all_related_objects, additional_lookups -class RelatedPopulator(object): +class RelatedPopulator: """ RelatedPopulator is used for select_related() object instantiation. diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py index 03d133e72409..54088b4fbb2e 100644 --- a/django/db/models/query_utils.py +++ b/django/db/models/query_utils.py @@ -34,7 +34,7 @@ def subclasses(cls): yield item -class QueryWrapper(object): +class QueryWrapper: """ A type that indicates the contents are an SQL fragment and the associate parameters. Can be used to pass opaque data to a where-clause, for example. @@ -90,7 +90,7 @@ def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize return clause -class DeferredAttribute(object): +class DeferredAttribute: """ A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed. @@ -130,7 +130,7 @@ def _check_parent_chain(self, instance, name): return None -class RegisterLookupMixin(object): +class RegisterLookupMixin: @classmethod def _get_lookup(cls, lookup_name): diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 41733210c4c3..1be406d7044b 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -15,7 +15,7 @@ FORCE = object() -class SQLCompiler(object): +class SQLCompiler: def __init__(self, query, connection, using): self.query = query self.connection = connection diff --git a/django/db/models/sql/datastructures.py b/django/db/models/sql/datastructures.py index 02e4f930e17e..81b6cabdc695 100644 --- a/django/db/models/sql/datastructures.py +++ b/django/db/models/sql/datastructures.py @@ -19,11 +19,11 @@ def __init__(self, names_pos, path_with_names): self.names_with_path = path_with_names -class Empty(object): +class Empty: pass -class Join(object): +class Join: """ Used by sql.Query and sql.SQLCompiler to generate JOIN clauses into the FROM entry. For example, the SQL generated could be @@ -125,7 +125,7 @@ def promote(self): return new -class BaseTable(object): +class BaseTable: """ The BaseTable class is used for base table references in FROM clause. For example, the SQL "foo" in diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 3acef8faf5f3..67d5738976c6 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -43,7 +43,7 @@ def get_field_names_from_opts(opts): )) -class RawQuery(object): +class RawQuery: """ A single raw SQL query """ @@ -111,7 +111,7 @@ def _execute_query(self): self.cursor.execute(self.sql, params) -class Query(object): +class Query: """ A single SQL query. """ @@ -2049,7 +2049,7 @@ def is_reverse_o2o(field): return field.is_relation and field.one_to_one and not field.concrete -class JoinPromoter(object): +class JoinPromoter: """ A class to abstract away join promotion problems for complex filter conditions. diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py index bb4e9252b44f..7ce7617bfaa9 100644 --- a/django/db/models/sql/where.py +++ b/django/db/models/sql/where.py @@ -172,7 +172,7 @@ def is_summary(self): return any(child.is_summary for child in self.children) -class NothingNode(object): +class NothingNode: """ A node that matches nothing. """ @@ -182,7 +182,7 @@ def as_sql(self, compiler=None, connection=None): raise EmptyResultSet -class ExtraWhere(object): +class ExtraWhere: # The contents are a black box - assume no aggregates are used. contains_aggregate = False @@ -195,7 +195,7 @@ def as_sql(self, compiler=None, connection=None): return " AND ".join(sqls), list(self.params or ()) -class SubqueryConstraint(object): +class SubqueryConstraint: # Even if aggregates would be used in a subquery, the outer query isn't # interested about those. contains_aggregate = False diff --git a/django/db/utils.py b/django/db/utils.py index a65510ea8075..8ca3f860b3fe 100644 --- a/django/db/utils.py +++ b/django/db/utils.py @@ -50,7 +50,7 @@ class NotSupportedError(DatabaseError): pass -class DatabaseErrorWrapper(object): +class DatabaseErrorWrapper: """ Context manager and decorator that re-throws backend-specific database exceptions using Django's common wrappers. @@ -141,7 +141,7 @@ class ConnectionDoesNotExist(Exception): pass -class ConnectionHandler(object): +class ConnectionHandler: def __init__(self, databases=None): """ databases is an optional dictionary of database definitions (structured @@ -234,7 +234,7 @@ def close_all(self): connection.close() -class ConnectionRouter(object): +class ConnectionRouter: def __init__(self, routers=None): """ If routers is not specified, will default to settings.DATABASE_ROUTERS. diff --git a/django/dispatch/dispatcher.py b/django/dispatch/dispatcher.py index 706c9eebbf71..09992c5b8cd2 100644 --- a/django/dispatch/dispatcher.py +++ b/django/dispatch/dispatcher.py @@ -17,7 +17,7 @@ def _make_id(target): NO_RECEIVERS = object() -class Signal(object): +class Signal: """ Base class for all signals diff --git a/django/forms/boundfield.py b/django/forms/boundfield.py index dc40bca50871..8bed2a8a52ce 100644 --- a/django/forms/boundfield.py +++ b/django/forms/boundfield.py @@ -15,7 +15,7 @@ @html_safe -class BoundField(object): +class BoundField: "A Field plus data" def __init__(self, form, field, name): self.form = form @@ -251,7 +251,7 @@ def build_widget_attrs(self, attrs, widget=None): @html_safe -class BoundWidget(object): +class BoundWidget: """ A container class used for iterating over widgets. This is useful for widgets that have choices. For example, the following can be used in a diff --git a/django/forms/fields.py b/django/forms/fields.py index 94a7bbbfc244..20521b26eaab 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -44,7 +44,7 @@ ) -class Field(object): +class Field: widget = TextInput # Default widget to use when rendering this type of Field. hidden_widget = HiddenInput # Default widget to use when rendering this as "hidden". default_validators = [] # Default set of validators @@ -755,7 +755,7 @@ def validate(self, value): pass -class CallableChoiceIterator(object): +class CallableChoiceIterator: def __init__(self, choices_func): self.choices_func = choices_func diff --git a/django/forms/forms.py b/django/forms/forms.py index de19edb668fa..7fccdc2b65c8 100644 --- a/django/forms/forms.py +++ b/django/forms/forms.py @@ -58,7 +58,7 @@ def __new__(mcs, name, bases, attrs): @html_safe -class BaseForm(object): +class BaseForm: # This is the main implementation of all the Form logic. Note that this # class is different than Form. See the comments by the Form class for more # information. Any improvements to the form API should be made to *this* diff --git a/django/forms/formsets.py b/django/forms/formsets.py index 964a83d4cab7..18a8cabefaa0 100644 --- a/django/forms/formsets.py +++ b/django/forms/formsets.py @@ -43,7 +43,7 @@ def __init__(self, *args, **kwargs): @html_safe -class BaseFormSet(object): +class BaseFormSet: """ A collection of instances of the same Form class. """ diff --git a/django/forms/models.py b/django/forms/models.py index 093a7a607864..e5a589bfbaaf 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -184,7 +184,7 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None, return field_dict -class ModelFormOptions(object): +class ModelFormOptions: def __init__(self, options=None): self.model = getattr(options, 'model', None) self.fields = getattr(options, 'fields', None) @@ -517,10 +517,8 @@ def modelform_factory(model, form=ModelForm, fields=None, exclude=None, # If parent form class already has an inner Meta, the Meta we're # creating needs to inherit from the parent's inner meta. - parent = (object,) - if hasattr(form, 'Meta'): - parent = (form.Meta, object) - Meta = type(str('Meta'), parent, attrs) + bases = (form.Meta,) if hasattr(form, 'Meta') else () + Meta = type(str('Meta'), bases, attrs) if formfield_callback: Meta.formfield_callback = staticmethod(formfield_callback) # Give this new form class a reasonable name. @@ -1099,7 +1097,7 @@ def has_changed(self, initial, data): return False -class ModelChoiceIterator(object): +class ModelChoiceIterator: def __init__(self, field): self.field = field self.queryset = field.queryset diff --git a/django/forms/renderers.py b/django/forms/renderers.py index 2c31d7adc5a7..3023d477e483 100644 --- a/django/forms/renderers.py +++ b/django/forms/renderers.py @@ -23,7 +23,7 @@ def get_default_renderer(): return renderer_class() -class BaseRenderer(object): +class BaseRenderer: def get_template(self, template_name): raise NotImplementedError('subclasses must implement get_template()') @@ -32,7 +32,7 @@ def render(self, template_name, context, request=None): return template.render(context, request=request).strip() -class EngineMixin(object): +class EngineMixin: def get_template(self, template_name): return self.engine.get_template(template_name) diff --git a/django/forms/widgets.py b/django/forms/widgets.py index b04864205c4b..d8b4d6a4dc48 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -35,7 +35,7 @@ @html_safe -class Media(object): +class Media: def __init__(self, media=None, **kwargs): if media: media_attrs = media.__dict__ diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index 4cbb98afddfb..ff7e36e32185 100644 --- a/django/http/multipartparser.py +++ b/django/http/multipartparser.py @@ -41,7 +41,7 @@ class InputStreamExhausted(Exception): FIELD = "field" -class MultiPartParser(object): +class MultiPartParser: """ A rfc2388 multipart/form-data parser. @@ -646,7 +646,7 @@ def _parse_header(line): return (TYPE, outdict, stream) -class Parser(object): +class Parser: def __init__(self, stream, boundary): self._stream = stream self._separator = b'--' + boundary diff --git a/django/http/request.py b/django/http/request.py index a930c93b264f..4ca2ed25fad3 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -36,7 +36,7 @@ class RawPostDataException(Exception): pass -class HttpRequest(object): +class HttpRequest: """A basic HTTP request.""" # The encoding used in GET/POST dicts. None means use default setting. diff --git a/django/template/backends/base.py b/django/template/backends/base.py index 9f48fbfdca8b..ad53089f2277 100644 --- a/django/template/backends/base.py +++ b/django/template/backends/base.py @@ -6,7 +6,7 @@ from django.utils.functional import cached_property -class BaseEngine(object): +class BaseEngine: # Core methods: engines have to provide their own implementation # (except for from_string which is optional). diff --git a/django/template/backends/django.py b/django/template/backends/django.py index 7ae8141251e7..33022d8bbbfd 100644 --- a/django/template/backends/django.py +++ b/django/template/backends/django.py @@ -47,7 +47,7 @@ def get_templatetag_libraries(self, custom_libraries): return libraries -class Template(object): +class Template: def __init__(self, template, backend): self.template = template diff --git a/django/template/backends/jinja2.py b/django/template/backends/jinja2.py index 2497df1b8414..df2eefa92535 100644 --- a/django/template/backends/jinja2.py +++ b/django/template/backends/jinja2.py @@ -56,7 +56,7 @@ def template_context_processors(self): return [import_string(path) for path in self.context_processors] -class Template(object): +class Template: def __init__(self, template, backend): self.template = template @@ -78,7 +78,7 @@ def render(self, context=None, request=None): return self.template.render(context) -class Origin(object): +class Origin: """ A container to hold debug information as described in the template API documentation. diff --git a/django/template/base.py b/django/template/base.py index 7f18869dbbf8..ce3cc2c7c095 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -122,7 +122,7 @@ def __str__(self): return self.msg % tuple(force_text(p, errors='replace') for p in self.params) -class Origin(object): +class Origin: def __init__(self, name, template_name=None, loader=None): self.name = name self.template_name = template_name @@ -148,7 +148,7 @@ def loader_name(self): ) -class Template(object): +class Template: def __init__(self, template_string, origin=None, name=None, engine=None): try: template_string = force_text(template_string) @@ -301,7 +301,7 @@ def linebreak_iter(template_source): yield len(template_source) + 1 -class Token(object): +class Token: def __init__(self, token_type, contents, position=None, lineno=None): """ A token representing a string from the template. @@ -346,7 +346,7 @@ def split_contents(self): return split -class Lexer(object): +class Lexer: def __init__(self, template_string): self.template_string = template_string self.verbatim = False @@ -423,7 +423,7 @@ def tokenize(self): return result -class Parser(object): +class Parser: def __init__(self, tokens, libraries=None, builtins=None, origin=None): self.tokens = tokens self.tags = {} @@ -624,7 +624,7 @@ def find_filter(self, filter_name): filter_re = re.compile(filter_raw_string, re.UNICODE | re.VERBOSE) -class FilterExpression(object): +class FilterExpression: """ Parses a variable token and its optional filters (all as a single string), and return a list of tuples of the filter name and arguments. @@ -741,7 +741,7 @@ def __str__(self): return self.token -class Variable(object): +class Variable: """ A template variable, resolvable against a given context. The variable may be a hard-coded string (if it begins and ends with single or double quote @@ -898,7 +898,7 @@ def _resolve_lookup(self, context): return current -class Node(object): +class Node: # Set this to True for nodes that must be first in the template (although # they can be preceded by text nodes. must_be_first = False diff --git a/django/template/context.py b/django/template/context.py index c5a4949e95e9..dfc4ed69a6b1 100644 --- a/django/template/context.py +++ b/django/template/context.py @@ -24,7 +24,7 @@ def __exit__(self, *args, **kwargs): self.context.pop() -class BaseContext(object): +class BaseContext: def __init__(self, dict_=None): self._reset_dicts(dict_) diff --git a/django/template/engine.py b/django/template/engine.py index d334926c45e8..026ecb144e34 100644 --- a/django/template/engine.py +++ b/django/template/engine.py @@ -10,7 +10,7 @@ from .library import import_library -class Engine(object): +class Engine: default_builtins = [ 'django.template.defaulttags', 'django.template.defaultfilters', diff --git a/django/template/library.py b/django/template/library.py index b7e3cad532d1..0b66aad3e9bb 100644 --- a/django/template/library.py +++ b/django/template/library.py @@ -13,7 +13,7 @@ class InvalidTemplateLibrary(Exception): pass -class Library(object): +class Library: """ A class for registering template tags and filters. Compiled filter and template tag functions are stored in the filters and tags attributes. diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py index 2c2790223860..b4f3f29be686 100644 --- a/django/template/loader_tags.py +++ b/django/template/loader_tags.py @@ -18,7 +18,7 @@ logger = logging.getLogger('django.template') -class BlockContext(object): +class BlockContext: def __init__(self): # Dictionary of FIFO queues. self.blocks = defaultdict(list) diff --git a/django/template/loaders/base.py b/django/template/loaders/base.py index cb1807fd7e32..041f9c47507c 100644 --- a/django/template/loaders/base.py +++ b/django/template/loaders/base.py @@ -1,7 +1,7 @@ from django.template import Template, TemplateDoesNotExist -class Loader(object): +class Loader: def __init__(self, engine): self.engine = engine diff --git a/django/template/smartif.py b/django/template/smartif.py index d0cebadc0111..02e005c5ec74 100644 --- a/django/template/smartif.py +++ b/django/template/smartif.py @@ -8,7 +8,7 @@ # 'bp' = binding power (left = lbp, right = rbp) -class TokenBase(object): +class TokenBase: """ Base class for operators and literals, mainly for debugging and for throwing syntax errors. @@ -147,7 +147,7 @@ def nud(self, parser): EndToken = EndToken() -class IfParser(object): +class IfParser: error_class = ValueError def __init__(self, tokens): diff --git a/django/template/utils.py b/django/template/utils.py index 6ff2499dcbf5..852baca5660e 100644 --- a/django/template/utils.py +++ b/django/template/utils.py @@ -14,7 +14,7 @@ class InvalidTemplateEngineError(ImproperlyConfigured): pass -class EngineHandler(object): +class EngineHandler: def __init__(self, templates=None): """ templates is an optional list of template engine definitions diff --git a/django/templatetags/tz.py b/django/templatetags/tz.py index 99d391e45d30..4769d1e09dbb 100644 --- a/django/templatetags/tz.py +++ b/django/templatetags/tz.py @@ -8,9 +8,9 @@ register = Library() -# HACK: datetime is an old-style class, create a new-style equivalent -# so we can define additional attributes. -class datetimeobject(datetime, object): +# HACK: datetime instances cannot be assigned new attributes. Define a subclass +# in order to define new attributes in do_timezone(). +class datetimeobject(datetime): pass diff --git a/django/test/client.py b/django/test/client.py index 3b31dae9bdd6..c8c6e96a7ffb 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -46,7 +46,7 @@ def __init__(self, message, last_response): self.redirect_chain = last_response.redirect_chain -class FakePayload(object): +class FakePayload: """ A wrapper around BytesIO that restricts what can be read since data from the network can't be seeked and cannot be read outside of its content @@ -253,7 +253,7 @@ def to_bytes(s): ] -class RequestFactory(object): +class RequestFactory: """ Class that lets you create mock Request objects for use in testing. diff --git a/django/test/html.py b/django/test/html.py index 67a2ad65e1cd..319fd87a0fb1 100644 --- a/django/test/html.py +++ b/django/test/html.py @@ -13,7 +13,7 @@ def normalize_whitespace(string): return WHITESPACE.sub(' ', string) -class Element(object): +class Element: def __init__(self, name, attributes): self.name = name self.attributes = sorted(attributes) diff --git a/django/test/runner.py b/django/test/runner.py index 77a309d8e677..090adcec950d 100644 --- a/django/test/runner.py +++ b/django/test/runner.py @@ -66,7 +66,7 @@ def printErrorList(self, flavour, errors): self.stream.writeln("%s" % sql_debug) -class RemoteTestResult(object): +class RemoteTestResult: """ Record information about which tests have succeeded and which have failed. @@ -230,7 +230,7 @@ def addUnexpectedSuccess(self, test): self.stop_if_failfast() -class RemoteTestRunner(object): +class RemoteTestRunner: """ Run tests and record everything but don't display anything. @@ -389,7 +389,7 @@ def run(self, result): return result -class DiscoverRunner(object): +class DiscoverRunner: """ A Django test runner that uses unittest2 test discovery. """ diff --git a/django/test/testcases.py b/django/test/testcases.py index dad3fb2df026..02398433d97a 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -84,7 +84,7 @@ def __exit__(self, exc_type, exc_value, traceback): ) -class _AssertTemplateUsedContext(object): +class _AssertTemplateUsedContext: def __init__(self, test_case, template_name): self.test_case = test_case self.template_name = template_name @@ -130,7 +130,7 @@ def message(self): return '%s was rendered.' % self.template_name -class _CursorFailure(object): +class _CursorFailure: def __init__(self, cls_name, wrapped): self.cls_name = cls_name self.wrapped = wrapped @@ -1047,7 +1047,7 @@ def _should_check_constraints(self, connection): ) -class CheckCondition(object): +class CheckCondition: """Descriptor class for deferred condition checking""" def __init__(self, *conditions): self.conditions = conditions @@ -1334,7 +1334,7 @@ def tearDownClass(cls): super(LiveServerTestCase, cls).tearDownClass() -class SerializeMixin(object): +class SerializeMixin: """ Mixin to enforce serialization of TestCases that share a common resource. diff --git a/django/test/utils.py b/django/test/utils.py index 55428ccf853b..7cff683dff13 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -42,7 +42,7 @@ TZ_SUPPORT = hasattr(time, 'tzset') -class Approximate(object): +class Approximate: def __init__(self, val, places=7): self.val = val self.places = places @@ -102,7 +102,7 @@ def instrumented_test_render(self, context): return self.nodelist.render(context) -class _TestState(object): +class _TestState: pass @@ -322,7 +322,7 @@ def get_runner(settings, test_runner_class=None): return test_runner -class TestContextDecorator(object): +class TestContextDecorator: """ A base class that can either be used as a context manager during tests or as a test function or unittest.TestCase subclass decorator to perform @@ -613,7 +613,7 @@ def str_prefix(s): return s % {'_': ''} -class CaptureQueriesContext(object): +class CaptureQueriesContext: """ Context manager that captures queries executed by the specified connection. """ @@ -832,7 +832,7 @@ def disable(self): set_script_prefix(self.old_prefix) -class LoggingCaptureMixin(object): +class LoggingCaptureMixin: """ Capture the output from the 'django' logger and store it on the class's logger_output attribute. diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py index 7e344896af0b..36586feab03a 100644 --- a/django/urls/resolvers.py +++ b/django/urls/resolvers.py @@ -25,7 +25,7 @@ from .utils import get_callable -class ResolverMatch(object): +class ResolverMatch: def __init__(self, func, args, kwargs, url_name=None, app_names=None, namespaces=None): self.func = func self.args = args @@ -76,7 +76,7 @@ def get_ns_resolver(ns_pattern, resolver): return RegexURLResolver(r'^/', [ns_resolver]) -class LocaleRegexDescriptor(object): +class LocaleRegexDescriptor: def __get__(self, instance, cls=None): """ Return a compiled regular expression based on the active language. @@ -106,7 +106,7 @@ def _compile(self, regex): ) -class LocaleRegexProvider(object): +class LocaleRegexProvider: """ A mixin to provide a default regex property which can vary by active language. diff --git a/django/utils/archive.py b/django/utils/archive.py index 456145a52066..1dd3f9d66032 100644 --- a/django/utils/archive.py +++ b/django/utils/archive.py @@ -49,7 +49,7 @@ def extract(path, to_path=''): archive.extract(to_path) -class Archive(object): +class Archive: """ The external API class that encapsulates an archive implementation. """ @@ -93,7 +93,7 @@ def close(self): self._archive.close() -class BaseArchive(object): +class BaseArchive: """ Base Archive class. Implementations should inherit this class. """ diff --git a/django/utils/baseconv.py b/django/utils/baseconv.py index 158f0b0d92ba..28099affaec1 100644 --- a/django/utils/baseconv.py +++ b/django/utils/baseconv.py @@ -45,7 +45,7 @@ BASE64_ALPHABET = BASE62_ALPHABET + '-_' -class BaseConverter(object): +class BaseConverter: decimal_digits = '0123456789' def __init__(self, digits, sign='-'): diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py index bb8166a73496..a89af1780be5 100644 --- a/django/utils/datastructures.py +++ b/django/utils/datastructures.py @@ -2,7 +2,7 @@ from collections import OrderedDict -class OrderedSet(object): +class OrderedSet: """ A set which keeps the ordering of the inserted items. Currently backs onto OrderedDict. diff --git a/django/utils/dateformat.py b/django/utils/dateformat.py index ded952df994c..f55b97c2edf3 100644 --- a/django/utils/dateformat.py +++ b/django/utils/dateformat.py @@ -26,7 +26,7 @@ re_escaped = re.compile(r'\\(.)') -class Formatter(object): +class Formatter: def format(self, formatstr): pieces = [] for i, piece in enumerate(re_formatchars.split(force_text(formatstr))): diff --git a/django/utils/decorators.py b/django/utils/decorators.py index 071028930f46..3b2a002e7b01 100644 --- a/django/utils/decorators.py +++ b/django/utils/decorators.py @@ -169,7 +169,7 @@ def callback(response): if ContextDecorator is None: # ContextDecorator was introduced in Python 3.2 # See https://docs.python.org/3/library/contextlib.html#contextlib.ContextDecorator - class ContextDecorator(object): + class ContextDecorator: """ A base class that enables a context manager to also be used as a decorator. """ @@ -181,7 +181,7 @@ def inner(*args, **kwargs): return inner -class classproperty(object): +class classproperty: def __init__(self, method=None): self.fget = method diff --git a/django/utils/deprecation.py b/django/utils/deprecation.py index a37f2e3d69da..2ef95bc34376 100644 --- a/django/utils/deprecation.py +++ b/django/utils/deprecation.py @@ -13,7 +13,7 @@ class RemovedInDjango21Warning(DeprecationWarning): RemovedInNextVersionWarning = RemovedInDjango21Warning -class warn_about_renamed_method(object): +class warn_about_renamed_method: def __init__(self, class_name, old_method_name, new_method_name, deprecation_warning): self.class_name = class_name self.old_method_name = old_method_name @@ -82,7 +82,7 @@ def __instancecheck__(self, instance): return super(DeprecationInstanceCheck, self).__instancecheck__(instance) -class MiddlewareMixin(object): +class MiddlewareMixin: def __init__(self, get_response=None): self.get_response = get_response super(MiddlewareMixin, self).__init__() diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py index 33ef20e16bd8..4772acb1c9f5 100644 --- a/django/utils/feedgenerator.py +++ b/django/utils/feedgenerator.py @@ -79,7 +79,7 @@ def get_tag_uri(url, date): return 'tag:%s%s:%s/%s' % (bits.hostname, d, bits.path, bits.fragment) -class SyndicationFeed(object): +class SyndicationFeed: "Base class for all syndication feeds. Subclasses should provide write()" def __init__(self, title, link, description, language=None, author_email=None, author_name=None, author_link=None, subtitle=None, categories=None, @@ -209,7 +209,7 @@ def latest_post_date(self): return latest_date or datetime.datetime.utcnow().replace(tzinfo=utc) -class Enclosure(object): +class Enclosure: "Represents an RSS enclosure" def __init__(self, url, length, mime_type): "All args are expected to be Python Unicode objects" diff --git a/django/utils/functional.py b/django/utils/functional.py index 2eeffa044721..30e484eaa3a1 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -12,7 +12,7 @@ def _curried(*moreargs, **morekwargs): return _curried -class cached_property(object): +class cached_property: """ Decorator that converts a method with a single self argument into a property cached on the instance. @@ -32,7 +32,7 @@ def __get__(self, instance, cls=None): return res -class Promise(object): +class Promise: """ This is just a base class for the proxy class created in the closure of the lazy function. It can be used to recognize @@ -214,7 +214,7 @@ def inner(self, *args): return inner -class LazyObject(object): +class LazyObject: """ A wrapper for another class that can be used to delay instantiation of the wrapped class. diff --git a/django/utils/jslex.py b/django/utils/jslex.py index 0958ac030cab..98b5d56e9d0c 100644 --- a/django/utils/jslex.py +++ b/django/utils/jslex.py @@ -3,7 +3,7 @@ import re -class Tok(object): +class Tok: """ A specification for a token class. """ @@ -27,7 +27,7 @@ def literals(choices, prefix="", suffix=""): return "|".join(prefix + re.escape(c) + suffix for c in choices.split()) -class Lexer(object): +class Lexer: """ A generic multi-state regex-based lexer. """ diff --git a/django/utils/safestring.py b/django/utils/safestring.py index 609f8f45acec..fe5ca422c3fd 100644 --- a/django/utils/safestring.py +++ b/django/utils/safestring.py @@ -8,7 +8,7 @@ from django.utils.functional import Promise, curry, wraps -class SafeData(object): +class SafeData: def __html__(self): """ Returns the html representation of a string for interoperability. diff --git a/django/utils/six.py b/django/utils/six.py index b4038c72fac9..95f16f58d99d 100644 --- a/django/utils/six.py +++ b/django/utils/six.py @@ -55,7 +55,7 @@ MAXSIZE = int((1 << 31) - 1) else: # It's possible to have sizeof(long) != sizeof(Py_ssize_t). - class X(object): + class X: def __len__(self): return 1 << 31 @@ -81,7 +81,7 @@ def _import_module(name): return sys.modules[name] -class _LazyDescr(object): +class _LazyDescr: def __init__(self, name): self.name = name @@ -159,7 +159,7 @@ def _resolve(self): return getattr(module, self.attr) -class _SixMetaPathImporter(object): +class _SixMetaPathImporter: """ A meta path importer to import six.moves and its submodules. @@ -550,7 +550,7 @@ def create_bound_method(func, obj): def create_unbound_method(func, cls): return types.MethodType(func, None, cls) - class Iterator(object): + class Iterator: def next(self): return type(self).__next__(self) diff --git a/django/utils/synch.py b/django/utils/synch.py index c8ef2f07bdbe..d944bfd242c2 100644 --- a/django/utils/synch.py +++ b/django/utils/synch.py @@ -10,7 +10,7 @@ import threading -class RWLock(object): +class RWLock: """ Classic implementation of reader-writer lock with preference to writers. diff --git a/django/utils/text.py b/django/utils/text.py index d716a0b34508..20df82c85b2e 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -291,7 +291,7 @@ def compress_string(s): return zbuf.getvalue() -class StreamingBuffer(object): +class StreamingBuffer: def __init__(self): self.vals = [] diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py index 345015d99496..4dc4c16c283a 100644 --- a/django/utils/translation/__init__.py +++ b/django/utils/translation/__init__.py @@ -38,7 +38,7 @@ class TranslatorCommentWarning(SyntaxWarning): # replace the functions with their real counterparts (once we do access the # settings). -class Trans(object): +class Trans: """ The purpose of this class is to store the actual translation function upon receiving the first call to that function. After this is done, changes to diff --git a/django/utils/tree.py b/django/utils/tree.py index 3eb352935479..2c8ab3fe1c0d 100644 --- a/django/utils/tree.py +++ b/django/utils/tree.py @@ -8,7 +8,7 @@ from django.utils.encoding import force_str, force_text -class Node(object): +class Node: """ A single internal node in the tree graph. A Node should be viewed as a connection (the root) with the children being either leaf nodes or other diff --git a/django/views/debug.py b/django/views/debug.py index b457969427f6..28e0fe6eb278 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -23,7 +23,7 @@ CLEANSED_SUBSTITUTE = '********************' -class CallableSettingWrapper(object): +class CallableSettingWrapper: """ Object to wrap callable appearing in settings * Not to call in the debug page (#21345). @@ -95,7 +95,7 @@ def get_exception_reporter_filter(request): return getattr(request, 'exception_reporter_filter', default_filter) -class ExceptionReporterFilter(object): +class ExceptionReporterFilter: """ Base for all exception reporter filter classes. All overridable hooks contain lenient default behaviors. @@ -230,7 +230,7 @@ def get_traceback_frame_variables(self, request, tb_frame): return cleansed.items() -class ExceptionReporter(object): +class ExceptionReporter: """ A class to organize and coordinate reporting on exceptions. """ diff --git a/django/views/generic/base.py b/django/views/generic/base.py index 668aef776026..4d4617c0a8e0 100644 --- a/django/views/generic/base.py +++ b/django/views/generic/base.py @@ -10,7 +10,7 @@ logger = logging.getLogger('django.request') -class ContextMixin(object): +class ContextMixin: """ A default context mixin that passes the keyword arguments received by get_context_data as the template context. @@ -22,7 +22,7 @@ def get_context_data(self, **kwargs): return kwargs -class View(object): +class View: """ Intentionally simple parent class for all views. Only implements dispatch-by-method and simple sanity checking. @@ -104,7 +104,7 @@ def _allowed_methods(self): return [m.upper() for m in self.http_method_names if hasattr(self, m)] -class TemplateResponseMixin(object): +class TemplateResponseMixin: """ A mixin that can be used to render a template. """ diff --git a/django/views/generic/dates.py b/django/views/generic/dates.py index d03140a9738c..86a49f8bd379 100644 --- a/django/views/generic/dates.py +++ b/django/views/generic/dates.py @@ -17,7 +17,7 @@ ) -class YearMixin(object): +class YearMixin: """ Mixin for views manipulating year-based data. """ @@ -73,7 +73,7 @@ def _get_current_year(self, date): return date.replace(month=1, day=1) -class MonthMixin(object): +class MonthMixin: """ Mixin for views manipulating month-based data. """ @@ -132,7 +132,7 @@ def _get_current_month(self, date): return date.replace(day=1) -class DayMixin(object): +class DayMixin: """ Mixin for views manipulating day-based data. """ @@ -188,7 +188,7 @@ def _get_current_day(self, date): return date -class WeekMixin(object): +class WeekMixin: """ Mixin for views manipulating week-based data. """ @@ -258,7 +258,7 @@ def _get_weekday(self, date): raise ValueError("unknown week format: %s" % week_format) -class DateMixin(object): +class DateMixin: """ Mixin class for views manipulating date-based data. """ diff --git a/django/views/generic/edit.py b/django/views/generic/edit.py index 9b5bd3873690..258d624812c8 100644 --- a/django/views/generic/edit.py +++ b/django/views/generic/edit.py @@ -248,7 +248,7 @@ class UpdateView(SingleObjectTemplateResponseMixin, BaseUpdateView): template_name_suffix = '_form' -class DeletionMixin(object): +class DeletionMixin: """ A mixin providing the ability to delete objects """ diff --git a/tests/admin_docs/tests.py b/tests/admin_docs/tests.py index 2a2f9d25e080..dfe6104a3357 100644 --- a/tests/admin_docs/tests.py +++ b/tests/admin_docs/tests.py @@ -2,7 +2,7 @@ from django.test import TestCase, modify_settings, override_settings -class TestDataMixin(object): +class TestDataMixin: @classmethod def setUpTestData(cls): diff --git a/tests/admin_inlines/tests.py b/tests/admin_inlines/tests.py index 6deba9b1c240..20fa9c024171 100644 --- a/tests/admin_inlines/tests.py +++ b/tests/admin_inlines/tests.py @@ -18,7 +18,7 @@ INLINE_CHANGELINK_HTML = 'class="inlinechangelink">Change' -class TestDataMixin(object): +class TestDataMixin: @classmethod def setUpTestData(cls): diff --git a/tests/admin_ordering/tests.py b/tests/admin_ordering/tests.py index 250b59dea8d9..77597d0fb5af 100644 --- a/tests/admin_ordering/tests.py +++ b/tests/admin_ordering/tests.py @@ -9,11 +9,11 @@ ) -class MockRequest(object): +class MockRequest: pass -class MockSuperUser(object): +class MockSuperUser: def has_perm(self, perm): return True diff --git a/tests/admin_utils/tests.py b/tests/admin_utils/tests.py index 245334df4d24..1c14615e714c 100644 --- a/tests/admin_utils/tests.py +++ b/tests/admin_utils/tests.py @@ -105,7 +105,7 @@ def test_values_from_lookup_field(self): SIMPLE_FUNCTION = 'function' INSTANCE_ATTRIBUTE = 'attr' - class MockModelAdmin(object): + class MockModelAdmin: def get_admin_value(self, obj): return ADMIN_METHOD @@ -259,7 +259,7 @@ def test_callable(obj): ) self.assertEqual(label_for_field('site_id', Article), 'Site id') - class MockModelAdmin(object): + class MockModelAdmin: def test_from_model(self, obj): return "nothing" test_from_model.short_description = "not Really the Model" @@ -276,7 +276,7 @@ def test_from_model(self, obj): def test_label_for_property(self): # NOTE: cannot use @property decorator, because of # AttributeError: 'property' object has no attribute 'short_description' - class MockModelAdmin(object): + class MockModelAdmin: def my_property(self): return "this if from property" my_property.short_description = 'property short description' diff --git a/tests/admin_views/test_multidb.py b/tests/admin_views/test_multidb.py index 102cf35a5dc3..0273b7aaef2a 100644 --- a/tests/admin_views/test_multidb.py +++ b/tests/admin_views/test_multidb.py @@ -8,7 +8,7 @@ from .models import Book -class Router(object): +class Router: target_db = None def db_for_read(self, model, **hints): diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index 81b7e1f6a4b9..ae3ebdd54d4e 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -65,7 +65,7 @@ for a staff account. Note that both fields may be case-sensitive." -class AdminFieldExtractionMixin(object): +class AdminFieldExtractionMixin: """ Helper methods for extracting data from AdminForm. """ diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py index ae8443565da6..b9462498cca9 100644 --- a/tests/admin_widgets/tests.py +++ b/tests/admin_widgets/tests.py @@ -26,7 +26,7 @@ from .widgetadmin import site as widget_admin_site -class TestDataMixin(object): +class TestDataMixin: @classmethod def setUpTestData(cls): diff --git a/tests/apps/apps.py b/tests/apps/apps.py index 1096c1e4b881..d322b28f2b94 100644 --- a/tests/apps/apps.py +++ b/tests/apps/apps.py @@ -16,7 +16,7 @@ class BadConfig(AppConfig): """This class doesn't supply the mandatory 'name' attribute.""" -class NotAConfig(object): +class NotAConfig: name = 'apps' diff --git a/tests/apps/tests.py b/tests/apps/tests.py index 9576420b5493..e2706624361d 100644 --- a/tests/apps/tests.py +++ b/tests/apps/tests.py @@ -296,7 +296,7 @@ class LazyC(models.Model): self.assertListEqual(model_classes, [LazyA, LazyB, LazyB, LazyC, LazyA]) -class Stub(object): +class Stub: def __init__(self, **kwargs): self.__dict__.update(kwargs) diff --git a/tests/auth_tests/models/custom_user.py b/tests/auth_tests/models/custom_user.py index 049ae85e5c0b..60fcc494c4d5 100644 --- a/tests/auth_tests/models/custom_user.py +++ b/tests/auth_tests/models/custom_user.py @@ -74,7 +74,7 @@ def is_staff(self): return self.is_admin -class RemoveGroupsAndPermissions(object): +class RemoveGroupsAndPermissions: """ A context manager to temporarily remove the groups and user_permissions M2M fields from the AbstractUser class, so they don't clash with the diff --git a/tests/auth_tests/test_admin_multidb.py b/tests/auth_tests/test_admin_multidb.py index 9d0d999739c5..122cb7887629 100644 --- a/tests/auth_tests/test_admin_multidb.py +++ b/tests/auth_tests/test_admin_multidb.py @@ -7,7 +7,7 @@ from django.urls import reverse -class Router(object): +class Router: target_db = None def db_for_read(self, model, **hints): diff --git a/tests/auth_tests/test_auth_backends.py b/tests/auth_tests/test_auth_backends.py index f06e82569830..033df9c68205 100644 --- a/tests/auth_tests/test_auth_backends.py +++ b/tests/auth_tests/test_auth_backends.py @@ -29,7 +29,7 @@ def encode(self, *args, **kwargs): return super(CountingMD5PasswordHasher, self).encode(*args, **kwargs) -class BaseModelBackendTest(object): +class BaseModelBackendTest: """ A base class for tests that need to validate the ModelBackend with different User models. Subclasses should define a class @@ -319,11 +319,11 @@ def test_login(self): self.assertEqual(UUIDUser.objects.get(pk=self.client.session[SESSION_KEY]), user) -class TestObj(object): +class TestObj: pass -class SimpleRowlevelBackend(object): +class SimpleRowlevelBackend: def has_perm(self, user, perm, obj=None): if not obj: return # We only support row level perms @@ -468,7 +468,7 @@ def test_has_module_perms(self): self.assertIs(self.user1.has_module_perms("app2"), False) -class PermissionDeniedBackend(object): +class PermissionDeniedBackend: """ Always raises PermissionDenied in `authenticate`, `has_perm` and `has_module_perms`. """ @@ -573,7 +573,7 @@ def test_changed_backend_settings(self): self.assertTrue(user.is_anonymous) -class TypeErrorBackend(object): +class TypeErrorBackend: """ Always raises TypeError. """ diff --git a/tests/auth_tests/test_auth_backends_deprecation.py b/tests/auth_tests/test_auth_backends_deprecation.py index 61789365356d..fc39d0be2261 100644 --- a/tests/auth_tests/test_auth_backends_deprecation.py +++ b/tests/auth_tests/test_auth_backends_deprecation.py @@ -4,7 +4,7 @@ from django.test import SimpleTestCase, override_settings -class NoRequestBackend(object): +class NoRequestBackend: def authenticate(self, username=None, password=None): # Doesn't accept a request parameter. pass diff --git a/tests/auth_tests/test_context_processors.py b/tests/auth_tests/test_context_processors.py index 3857917860df..d66b28cb9c95 100644 --- a/tests/auth_tests/test_context_processors.py +++ b/tests/auth_tests/test_context_processors.py @@ -8,7 +8,7 @@ from .settings import AUTH_MIDDLEWARE, AUTH_TEMPLATES -class MockUser(object): +class MockUser: def has_module_perms(self, perm): if perm == 'mockapp': return True @@ -24,7 +24,7 @@ class PermWrapperTests(SimpleTestCase): """ Test some details of the PermWrapper implementation. """ - class EQLimiterObject(object): + class EQLimiterObject: """ This object makes sure __eq__ will not be called endlessly. """ diff --git a/tests/auth_tests/test_decorators.py b/tests/auth_tests/test_decorators.py index dc3482de22c3..55c422bdc6ca 100644 --- a/tests/auth_tests/test_decorators.py +++ b/tests/auth_tests/test_decorators.py @@ -19,7 +19,7 @@ def testCallable(self): """ login_required is assignable to callable objects. """ - class CallableView(object): + class CallableView: def __call__(self, *args, **kwargs): pass login_required(CallableView()) diff --git a/tests/auth_tests/test_forms.py b/tests/auth_tests/test_forms.py index c055b580424a..ae6fa313deaa 100644 --- a/tests/auth_tests/test_forms.py +++ b/tests/auth_tests/test_forms.py @@ -27,7 +27,7 @@ from .settings import AUTH_TEMPLATES -class TestDataMixin(object): +class TestDataMixin: @classmethod def setUpTestData(cls): diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 4fd1563f84e8..12d029ffcdbb 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -62,7 +62,7 @@ def mock_input(prompt): return inner -class MockTTY(object): +class MockTTY: """ A fake stdin object that pretends to be a TTY to be used in conjunction with mock_inputs. @@ -329,7 +329,7 @@ def test_skip_if_not_in_TTY(self): If the command is not called from a TTY, it should be skipped and a message should be displayed (#7423). """ - class FakeStdin(object): + class FakeStdin: """A fake stdin object that has isatty() return False.""" def isatty(self): return False diff --git a/tests/backends/tests.py b/tests/backends/tests.py index 89afb20760bb..662cdc4140a1 100644 --- a/tests/backends/tests.py +++ b/tests/backends/tests.py @@ -234,7 +234,7 @@ def test_version_detection(self): """Test PostgreSQL version detection""" # Helper mocks - class CursorMock(object): + class CursorMock: "Very simple mock of DB-API cursor" def execute(self, arg): pass @@ -248,7 +248,7 @@ def __enter__(self): def __exit__(self, type, value, traceback): pass - class OlderConnectionMock(object): + class OlderConnectionMock: "Mock of psycopg2 (< 2.0.12) connection" def cursor(self): return CursorMock() diff --git a/tests/builtin_server/tests.py b/tests/builtin_server/tests.py index 2784571b0cd7..6e234c1ba4a2 100644 --- a/tests/builtin_server/tests.py +++ b/tests/builtin_server/tests.py @@ -9,7 +9,7 @@ MAX_SOCKET_CHUNK_SIZE = 32 * 1024 * 1024 # 32 MB -class ServerHandler(simple_server.ServerHandler, object): +class ServerHandler(simple_server.ServerHandler): error_status = str("500 INTERNAL SERVER ERROR") def write(self, data): @@ -38,7 +38,7 @@ def error_output(self, environ, start_response): return ['\n'.join(traceback.format_exception(*sys.exc_info()))] -class DummyHandler(object): +class DummyHandler: def log_request(self, *args, **kwargs): pass diff --git a/tests/cache/closeable_cache.py b/tests/cache/closeable_cache.py index 1ac868dde990..a9e99a62cdf0 100644 --- a/tests/cache/closeable_cache.py +++ b/tests/cache/closeable_cache.py @@ -1,7 +1,7 @@ from django.core.cache.backends.locmem import LocMemCache -class CloseHookMixin(object): +class CloseHookMixin: closed = False def close(self, **kwargs): diff --git a/tests/cache/liberal_backend.py b/tests/cache/liberal_backend.py index 339066b0ff81..93dc39a0d7c3 100644 --- a/tests/cache/liberal_backend.py +++ b/tests/cache/liberal_backend.py @@ -1,7 +1,7 @@ from django.core.cache.backends.locmem import LocMemCache -class LiberalKeyValidationMixin(object): +class LiberalKeyValidationMixin: def validate_key(self, key): pass diff --git a/tests/cache/tests.py b/tests/cache/tests.py index dd886cd11b4f..bfceff9b0258 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -56,12 +56,12 @@ def m(n): return 24 -class Unpicklable(object): +class Unpicklable: def __getstate__(self): raise pickle.PickleError() -class UnpicklableType(object): +class UnpicklableType: # Unpicklable using the default pickling protocol on Python 2. __slots__ = 'a', @@ -251,7 +251,7 @@ def caches_setting_for_tests(base=None, exclude=None, **params): return setting -class BaseCacheTests(object): +class BaseCacheTests: # A common set of tests to apply to all cache backends def setUp(self): @@ -1010,7 +1010,7 @@ class DBCacheWithTimeZoneTests(DBCacheTests): pass -class DBCacheRouter(object): +class DBCacheRouter: """A router that puts the cache table on the 'other' database.""" def db_for_read(self, model, **hints): @@ -1061,7 +1061,7 @@ def test_createcachetable_observes_database_router(self): verbosity=0, interactive=False) -class PicklingSideEffect(object): +class PicklingSideEffect: def __init__(self, cache): self.cache = cache diff --git a/tests/check_framework/test_multi_db.py b/tests/check_framework/test_multi_db.py index f273d397e2cb..700553f47bdb 100644 --- a/tests/check_framework/test_multi_db.py +++ b/tests/check_framework/test_multi_db.py @@ -3,7 +3,7 @@ from django.test.utils import isolate_apps, override_settings -class TestRouter(object): +class TestRouter: """ Routes to the 'other' database if the model name starts with 'Other'. """ diff --git a/tests/check_framework/tests.py b/tests/check_framework/tests.py index 30e1353dc08a..46e4095a380e 100644 --- a/tests/check_framework/tests.py +++ b/tests/check_framework/tests.py @@ -17,7 +17,7 @@ from .models import SimpleModel, my_check -class DummyObj(object): +class DummyObj: def __repr__(self): return "obj" diff --git a/tests/contenttypes_tests/tests.py b/tests/contenttypes_tests/tests.py index c91c265eaff1..0ae2ddbb640c 100644 --- a/tests/contenttypes_tests/tests.py +++ b/tests/contenttypes_tests/tests.py @@ -432,7 +432,7 @@ def test_unavailable_content_type_model(self): self.assertEqual(ContentType.objects.count(), self.before_count + 1) -class TestRouter(object): +class TestRouter: def db_for_read(self, model, **hints): return 'other' diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py index 49247b7af8b5..f68b0f037bf4 100644 --- a/tests/csrf_tests/tests.py +++ b/tests/csrf_tests/tests.py @@ -35,7 +35,7 @@ def is_secure(self): return getattr(self, '_is_secure_override', False) -class CsrfViewMiddlewareTestMixin(object): +class CsrfViewMiddlewareTestMixin: """ Shared methods and tests for session-based and cookie-based tokens. """ diff --git a/tests/custom_lookups/tests.py b/tests/custom_lookups/tests.py index e66a280e167b..7b8cca664658 100644 --- a/tests/custom_lookups/tests.py +++ b/tests/custom_lookups/tests.py @@ -134,7 +134,7 @@ def get_rhs_op(self, connection, rhs): return connection.operators['exact'] % rhs -class SQLFuncMixin(object): +class SQLFuncMixin: def as_sql(self, compiler, connection): return '%s()', [self.name] @@ -155,7 +155,7 @@ def __init__(self, name, *args, **kwargs): self.name = name -class SQLFuncFactory(object): +class SQLFuncFactory: def __init__(self, key, name): self.key = key diff --git a/tests/custom_pk/fields.py b/tests/custom_pk/fields.py index fa61a72a0d7e..2be2288ed8e2 100644 --- a/tests/custom_pk/fields.py +++ b/tests/custom_pk/fields.py @@ -4,7 +4,7 @@ from django.db import models -class MyWrapper(object): +class MyWrapper: def __init__(self, value): self.value = value diff --git a/tests/decorators/tests.py b/tests/decorators/tests.py index 851c2b8daa9b..c2116a05cefb 100644 --- a/tests/decorators/tests.py +++ b/tests/decorators/tests.py @@ -109,10 +109,10 @@ def callback(request): callback = user_passes_test(test1)(callback) callback = user_passes_test(test2)(callback) - class DummyUser(object): + class DummyUser: pass - class DummyRequest(object): + class DummyRequest: pass request = DummyRequest() @@ -184,7 +184,7 @@ def wrapper(*args, **kwargs): myattr2_dec_m = method_decorator(myattr2_dec) -class ClsDec(object): +class ClsDec: def __init__(self, myattr): self.myattr = myattr @@ -200,7 +200,7 @@ class MethodDecoratorTests(SimpleTestCase): Tests for method_decorator """ def test_preserve_signature(self): - class Test(object): + class Test: @simple_dec_m def say(self, arg): return arg @@ -218,7 +218,7 @@ def func(): self.assertIs(getattr(func, 'myattr2', False), True) # Decorate using method_decorator() on the method. - class TestPlain(object): + class TestPlain: @myattr_dec_m @myattr2_dec_m def method(self): @@ -229,7 +229,7 @@ def method(self): # The decorators applied to the methods are applied before the ones # applied to the class. @method_decorator(myattr_dec_m, "method") - class TestMethodAndClass(object): + class TestMethodAndClass: @method_decorator(myattr2_dec_m) def method(self): "A method" @@ -239,7 +239,7 @@ def method(self): decorators = (myattr_dec_m, myattr2_dec_m) @method_decorator(decorators, "method") - class TestIterable(object): + class TestIterable: def method(self): "A method" pass @@ -259,14 +259,14 @@ def test_bad_iterable(self): # The rest of the exception message differs between Python 2 and 3. with self.assertRaisesMessage(TypeError, "'set' object"): @method_decorator(decorators, "method") - class TestIterable(object): + class TestIterable: def method(self): "A method" pass # Test for argumented decorator def test_argumented(self): - class Test(object): + class Test: @method_decorator(ClsDec(False)) def method(self): return True @@ -283,7 +283,7 @@ def _wrapped(arg): method_dec = method_decorator(original_dec) - class bound_wrapper(object): + class bound_wrapper: def __init__(self, wrapped): self.wrapped = wrapped self.__name__ = wrapped.__name__ @@ -294,7 +294,7 @@ def __call__(self, arg): def __get__(self, instance, cls=None): return self - class descriptor_wrapper(object): + class descriptor_wrapper: def __init__(self, wrapped): self.wrapped = wrapped self.__name__ = wrapped.__name__ @@ -302,7 +302,7 @@ def __init__(self, wrapped): def __get__(self, instance, cls=None): return bound_wrapper(self.wrapped.__get__(instance, cls)) - class Test(object): + class Test: @method_dec @descriptor_wrapper def method(self, arg): @@ -320,7 +320,7 @@ def _wrapper(*args, **kwargs): return _wrapper @method_decorator(deco, name="method") - class Test(object): + class Test: def method(self): return False @@ -349,11 +349,11 @@ def _wrapper(*args, **kwargs): decorators = (add_exclamation_mark, add_question_mark) @method_decorator(decorators, name="method") - class TestFirst(object): + class TestFirst: def method(self): return "hello world" - class TestSecond(object): + class TestSecond: @method_decorator(decorators) def method(self): return "hello world" @@ -371,7 +371,7 @@ def test_invalid_non_callable_attribute_decoration(self): ) with self.assertRaisesMessage(TypeError, msg): @method_decorator(lambda: None, name="prop") - class Test(object): + class Test: prop = 1 @classmethod @@ -388,7 +388,7 @@ def test_invalid_method_name_to_decorate(self): ) with self.assertRaisesMessage(ValueError, msg): @method_decorator(lambda: None, name="non_existing_method") - class Test(object): + class Test: @classmethod def __module__(cls): return "tests" diff --git a/tests/defer/tests.py b/tests/defer/tests.py index 0eea9545dd34..6badd7056e81 100644 --- a/tests/defer/tests.py +++ b/tests/defer/tests.py @@ -6,7 +6,7 @@ ) -class AssertionMixin(object): +class AssertionMixin: def assert_delayed(self, obj, num): """ Instances with deferred fields look the same as normal instances when diff --git a/tests/deprecation/tests.py b/tests/deprecation/tests.py index 5c2361f7a047..220010d9090d 100644 --- a/tests/deprecation/tests.py +++ b/tests/deprecation/tests.py @@ -140,11 +140,11 @@ class Renamed(metaclass=RenameManagerMethods): def new(self): pass - class RenamedMixin(object): + class RenamedMixin: def new(self): super(RenamedMixin, self).new() - class DeprecatedMixin(object): + class DeprecatedMixin: def old(self): super(DeprecatedMixin, self).old() diff --git a/tests/dispatch/tests.py b/tests/dispatch/tests.py index d36dde97207b..04fb39454de3 100644 --- a/tests/dispatch/tests.py +++ b/tests/dispatch/tests.py @@ -29,7 +29,7 @@ def receiver_1_arg(val, **kwargs): return val -class Callable(object): +class Callable: def __call__(self, val, **kwargs): return val diff --git a/tests/files/tests.py b/tests/files/tests.py index 50db4b7436c3..4515b1cab182 100644 --- a/tests/files/tests.py +++ b/tests/files/tests.py @@ -209,7 +209,7 @@ def test_closing_of_filenames(self): # get_image_dimensions will call our catching_open instead of the # regular builtin one. - class FileWrapper(object): + class FileWrapper: _closed = [] def __init__(self, f): diff --git a/tests/fixtures/tests.py b/tests/fixtures/tests.py index 51d8eef51b43..ca60dd70e8e9 100644 --- a/tests/fixtures/tests.py +++ b/tests/fixtures/tests.py @@ -47,7 +47,7 @@ def testClassFixtures(self): self.assertEqual(Article.objects.count(), 0) -class DumpDataAssertMixin(object): +class DumpDataAssertMixin: def _dumpdata_assert(self, args, output, format='json', filename=None, natural_foreign_keys=False, natural_primary_keys=False, diff --git a/tests/flatpages_tests/test_middleware.py b/tests/flatpages_tests/test_middleware.py index dd1d9e02f778..b7ca196db12c 100644 --- a/tests/flatpages_tests/test_middleware.py +++ b/tests/flatpages_tests/test_middleware.py @@ -7,7 +7,7 @@ from .settings import FLATPAGES_TEMPLATES -class TestDataMixin(object): +class TestDataMixin: @classmethod def setUpTestData(cls): diff --git a/tests/flatpages_tests/test_views.py b/tests/flatpages_tests/test_views.py index a5104ce62091..42d3e2e8cc0a 100644 --- a/tests/flatpages_tests/test_views.py +++ b/tests/flatpages_tests/test_views.py @@ -7,7 +7,7 @@ from .settings import FLATPAGES_TEMPLATES -class TestDataMixin(object): +class TestDataMixin: @classmethod def setUpTestData(cls): diff --git a/tests/foreign_object/models/article.py b/tests/foreign_object/models/article.py index e5c0c1f67372..940ec003fb32 100644 --- a/tests/foreign_object/models/article.py +++ b/tests/foreign_object/models/article.py @@ -15,7 +15,7 @@ def __set__(self, instance, value): setattr(value, self.field.related.get_cache_name(), instance) -class ColConstraint(object): +class ColConstraint: # Anything with as_sql() method works in get_extra_restriction(). def __init__(self, alias, col, value): self.alias, self.col, self.value = alias, col, value diff --git a/tests/forms_tests/field_tests/__init__.py b/tests/forms_tests/field_tests/__init__.py index b984c6fb4048..4aae30282bd1 100644 --- a/tests/forms_tests/field_tests/__init__.py +++ b/tests/forms_tests/field_tests/__init__.py @@ -1,7 +1,7 @@ from django import forms -class FormFieldAssertionsMixin(object): +class FormFieldAssertionsMixin: def assertWidgetRendersTo(self, field, to): class Form(forms.Form): diff --git a/tests/forms_tests/field_tests/test_base.py b/tests/forms_tests/field_tests/test_base.py index 67c300339394..721c0a935a1f 100644 --- a/tests/forms_tests/field_tests/test_base.py +++ b/tests/forms_tests/field_tests/test_base.py @@ -9,7 +9,7 @@ def test_field_sets_widget_is_required(self): self.assertFalse(Field(required=False).widget.is_required) def test_cooperative_multiple_inheritance(self): - class A(object): + class A: def __init__(self): self.class_a_var = True super(A, self).__init__() diff --git a/tests/forms_tests/tests/test_error_messages.py b/tests/forms_tests/tests/test_error_messages.py index 10c7a92f7def..40b085f55bff 100644 --- a/tests/forms_tests/tests/test_error_messages.py +++ b/tests/forms_tests/tests/test_error_messages.py @@ -13,7 +13,7 @@ from ..models import ChoiceModel -class AssertFormErrorsMixin(object): +class AssertFormErrorsMixin: def assertFormErrors(self, expected, the_callable, *args, **kwargs): with self.assertRaises(ValidationError) as cm: the_callable(*args, **kwargs) diff --git a/tests/forms_tests/tests/test_renderers.py b/tests/forms_tests/tests/test_renderers.py index 2ce6be66af9a..df9c9cf367e0 100644 --- a/tests/forms_tests/tests/test_renderers.py +++ b/tests/forms_tests/tests/test_renderers.py @@ -13,7 +13,7 @@ jinja2 = None -class SharedTests(object): +class SharedTests: expected_widget_dir = 'templates' def test_installed_apps_template_found(self): diff --git a/tests/forms_tests/widget_tests/test_clearablefileinput.py b/tests/forms_tests/widget_tests/test_clearablefileinput.py index dd7f04d0acca..eea705454192 100644 --- a/tests/forms_tests/widget_tests/test_clearablefileinput.py +++ b/tests/forms_tests/widget_tests/test_clearablefileinput.py @@ -4,7 +4,7 @@ from .base import WidgetTest -class FakeFieldFile(object): +class FakeFieldFile: """ Quacks like a FieldFile (has a .url and unicode representation), but doesn't require us to care about storages etc. @@ -37,7 +37,7 @@ def test_html_escaped(self): A ClearableFileInput should escape name, filename, and URL when rendering HTML (#15182). """ - class StrangeFieldFile(object): + class StrangeFieldFile: url = "something?chapter=1§=2©=3&lang=en" def __str__(self): @@ -107,7 +107,7 @@ def test_html_does_not_mask_exceptions(self): A ClearableFileInput should not mask exceptions produced while checking that it has a value. """ - class FailingURLFieldFile(object): + class FailingURLFieldFile: @property def url(self): raise ValueError('Canary') @@ -119,7 +119,7 @@ def __str__(self): self.widget.render('myfile', FailingURLFieldFile()) def test_url_as_property(self): - class URLFieldFile(object): + class URLFieldFile: @property def url(self): return 'https://www.python.org/' @@ -131,7 +131,7 @@ def __str__(self): self.assertInHTML('value', html) def test_return_false_if_url_does_not_exists(self): - class NoURLFieldFile(object): + class NoURLFieldFile: def __str__(self): return 'value' diff --git a/tests/generic_inline_admin/tests.py b/tests/generic_inline_admin/tests.py index 203d9d7f3e84..26a53f998578 100644 --- a/tests/generic_inline_admin/tests.py +++ b/tests/generic_inline_admin/tests.py @@ -15,7 +15,7 @@ from .models import Category, Episode, EpisodePermanent, Media, PhoneNumber -class TestDataMixin(object): +class TestDataMixin: @classmethod def setUpTestData(cls): @@ -386,11 +386,11 @@ def test_no_deletion(self): self.assertFalse(formset.can_delete) -class MockRequest(object): +class MockRequest: pass -class MockSuperUser(object): +class MockSuperUser: def has_perm(self, perm): return True diff --git a/tests/generic_views/test_dates.py b/tests/generic_views/test_dates.py index d18c8189890c..bf462b44fb2b 100644 --- a/tests/generic_views/test_dates.py +++ b/tests/generic_views/test_dates.py @@ -17,7 +17,7 @@ def _make_books(n, base_date): pubdate=base_date - datetime.timedelta(days=i)) -class TestDataMixin(object): +class TestDataMixin: @classmethod def setUpTestData(cls): diff --git a/tests/generic_views/views.py b/tests/generic_views/views.py index b466f3a324ea..05d5ec2f00b8 100644 --- a/tests/generic_views/views.py +++ b/tests/generic_views/views.py @@ -189,7 +189,7 @@ class SpecializedAuthorDelete(generic.DeleteView): success_url = reverse_lazy('authors_list') -class BookConfig(object): +class BookConfig: queryset = Book.objects.all() date_field = 'pubdate' @@ -266,7 +266,7 @@ class CustomSingleObjectView(generic.detail.SingleObjectMixin, generic.View): object = Book(name="dummy") -class BookSigningConfig(object): +class BookSigningConfig: model = BookSigning date_field = 'event_date' # use the same templates as for books @@ -303,7 +303,7 @@ class BookSigningDetail(BookSigningConfig, generic.DateDetailView): context_object_name = 'book' -class NonModel(object): +class NonModel: id = "non_model_1" _meta = None diff --git a/tests/get_object_or_404/tests.py b/tests/get_object_or_404/tests.py index b5a233568d9c..fa3c0cb32406 100644 --- a/tests/get_object_or_404/tests.py +++ b/tests/get_object_or_404/tests.py @@ -83,7 +83,7 @@ def test_bad_class(self): with self.assertRaisesMessage(ValueError, msg): get_object_or_404(str("Article"), title__icontains="Run") - class CustomClass(object): + class CustomClass: pass msg = "First argument to get_object_or_404() must be a Model, Manager, or QuerySet, not 'CustomClass'." diff --git a/tests/gis_tests/gdal_tests/test_envelope.py b/tests/gis_tests/gdal_tests/test_envelope.py index 8ea06ff4269a..b6cf4ab4f323 100644 --- a/tests/gis_tests/gdal_tests/test_envelope.py +++ b/tests/gis_tests/gdal_tests/test_envelope.py @@ -7,7 +7,7 @@ from django.contrib.gis.gdal import Envelope, GDALException -class TestPoint(object): +class TestPoint: def __init__(self, x, y): self.x = x self.y = y diff --git a/tests/gis_tests/geo3d/tests.py b/tests/gis_tests/geo3d/tests.py index e32611934a5a..72be66401402 100644 --- a/tests/gis_tests/geo3d/tests.py +++ b/tests/gis_tests/geo3d/tests.py @@ -66,7 +66,7 @@ ) -class Geo3DLoadingHelper(object): +class Geo3DLoadingHelper: def _load_interstate_data(self): # Interstate (2D / 3D and Geographic/Projected variants) for name, line, exp_z in interstate_data: diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index f7024e790e15..8626c4f2003d 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -89,7 +89,7 @@ def test_errors(self): with self.assertRaises(GEOSException): GEOSGeometry(memoryview(b'0')) - class NotAGeometry(object): + class NotAGeometry: pass # Some other object diff --git a/tests/gis_tests/layermap/tests.py b/tests/gis_tests/layermap/tests.py index 0f59132b0db3..ce4b0c90d543 100644 --- a/tests/gis_tests/layermap/tests.py +++ b/tests/gis_tests/layermap/tests.py @@ -318,7 +318,7 @@ def test_encoded_name(self): self.assertEqual(City.objects.all()[0].name, "Zürich") -class OtherRouter(object): +class OtherRouter: def db_for_read(self, model, **hints): return 'other' diff --git a/tests/gis_tests/test_data.py b/tests/gis_tests/test_data.py index 9e31b5a599b6..23df42c00792 100644 --- a/tests/gis_tests/test_data.py +++ b/tests/gis_tests/test_data.py @@ -31,7 +31,7 @@ def get_ds_file(name, ext): ) -class TestObj(object): +class TestObj: """ Base testing object, turns keyword args into attributes. """ @@ -76,7 +76,7 @@ def __init__(self, **kwargs): super(TestGeom, self).__init__(**kwargs) -class TestGeomSet(object): +class TestGeomSet: """ Each attribute of this object is a list of `TestGeom` instances. """ @@ -85,7 +85,7 @@ def __init__(self, **kwargs): setattr(self, key, [TestGeom(**strconvert(kw)) for kw in value]) -class TestDataMixin(object): +class TestDataMixin: """ Mixin used for GEOS/GDAL test cases that defines a `geometries` property, which returns and/or loads the reference geometry data. diff --git a/tests/gis_tests/tests.py b/tests/gis_tests/tests.py index 59b8fcf7b523..6b689cf9b016 100644 --- a/tests/gis_tests/tests.py +++ b/tests/gis_tests/tests.py @@ -23,7 +23,7 @@ if HAS_POSTGRES: - class FakeConnection(object): + class FakeConnection: def __init__(self): self.settings_dict = { 'NAME': 'test', diff --git a/tests/handlers/tests_custom_error_handlers.py b/tests/handlers/tests_custom_error_handlers.py index 04f58fbe2a5b..3821783f798a 100644 --- a/tests/handlers/tests_custom_error_handlers.py +++ b/tests/handlers/tests_custom_error_handlers.py @@ -4,7 +4,7 @@ from django.test import SimpleTestCase, modify_settings, override_settings -class MiddlewareAccessingContent(object): +class MiddlewareAccessingContent: def __init__(self, get_response): self.get_response = get_response diff --git a/tests/i18n/utils.py b/tests/i18n/utils.py index c198afbc43f9..b2267cd3eb96 100644 --- a/tests/i18n/utils.py +++ b/tests/i18n/utils.py @@ -12,7 +12,7 @@ def copytree(src, dst): shutil.copytree(src, dst, ignore=shutil.ignore_patterns('*.pyc', '__pycache__')) -class POFileAssertionMixin(object): +class POFileAssertionMixin: def _assertPoKeyword(self, keyword, expected_value, haystack, use_quotes=True): q = '"' @@ -30,7 +30,7 @@ def assertMsgId(self, msgid, haystack, use_quotes=True): return self._assertPoKeyword('msgid', msgid, haystack, use_quotes=use_quotes) -class RunInTmpDirMixin(object): +class RunInTmpDirMixin: """ Allow i18n tests that need to generate .po/.mo files to run in an isolated temporary filesystem tree created by tempfile.mkdtemp() that contains a diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py index 7bb949769085..d35f9aa0639b 100644 --- a/tests/invalid_models_tests/test_models.py +++ b/tests/invalid_models_tests/test_models.py @@ -910,7 +910,7 @@ class DummyModel(models.Model): class Meta: app_label = 'invalid_models_tests' - class DummyClass(object): + class DummyClass: def __call__(self, **kwargs): pass diff --git a/tests/invalid_models_tests/test_ordinary_fields.py b/tests/invalid_models_tests/test_ordinary_fields.py index 61f93e85788b..f1f1f07766e5 100644 --- a/tests/invalid_models_tests/test_ordinary_fields.py +++ b/tests/invalid_models_tests/test_ordinary_fields.py @@ -155,7 +155,7 @@ class Model(models.Model): self.assertEqual(errors, expected) def test_iterable_of_iterable_choices(self): - class ThingItem(object): + class ThingItem: def __init__(self, value, display): self.value = value self.display = display @@ -166,7 +166,7 @@ def __iter__(self): def __len__(self): return 2 - class Things(object): + class Things: def __iter__(self): return (x for x in [ThingItem(1, 2), ThingItem(3, 4)]) diff --git a/tests/logging_tests/tests.py b/tests/logging_tests/tests.py index a91bcd66bfe4..6033cac289f1 100644 --- a/tests/logging_tests/tests.py +++ b/tests/logging_tests/tests.py @@ -64,7 +64,7 @@ def test_require_debug_true_filter(self): self.assertIs(filter_.filter("record is not used"), False) -class SetupDefaultLoggingMixin(object): +class SetupDefaultLoggingMixin: @classmethod def setUpClass(cls): diff --git a/tests/mail/tests.py b/tests/mail/tests.py index 77ea87fe7d4e..8ba4d6442384 100644 --- a/tests/mail/tests.py +++ b/tests/mail/tests.py @@ -30,7 +30,7 @@ from django.utils.translation import ugettext_lazy -class HeadersCheckMixin(object): +class HeadersCheckMixin: def assertMessageHasHeaders(self, message, headers): """ @@ -708,7 +708,7 @@ def test_8bit_non_latin(self): self.assertIn(str('Content-Transfer-Encoding: base64'), txt.as_string()) -class BaseEmailBackendTests(HeadersCheckMixin, object): +class BaseEmailBackendTests(HeadersCheckMixin): email_backend = None def setUp(self): diff --git a/tests/messages_tests/base.py b/tests/messages_tests/base.py index 889bcc043ad4..8082d468fee5 100644 --- a/tests/messages_tests/base.py +++ b/tests/messages_tests/base.py @@ -36,7 +36,7 @@ def disable(self): base.LEVEL_TAGS = self.old_level_tags -class BaseTests(object): +class BaseTests: storage_class = default_storage levels = { 'debug': constants.DEBUG, diff --git a/tests/messages_tests/test_api.py b/tests/messages_tests/test_api.py index 8baff57c70a5..3de6b81b7b85 100644 --- a/tests/messages_tests/test_api.py +++ b/tests/messages_tests/test_api.py @@ -2,7 +2,7 @@ from django.test import RequestFactory, SimpleTestCase -class DummyStorage(object): +class DummyStorage: """ dummy message-store to test the api methods """ @@ -44,7 +44,7 @@ def test_middleware_missing_silently(self): self.assertEqual(self.storage.store, []) -class CustomRequest(object): +class CustomRequest: def __init__(self, request): self._request = request diff --git a/tests/middleware_exceptions/middleware.py b/tests/middleware_exceptions/middleware.py index e704b9f2b5d4..49e5d43189a4 100644 --- a/tests/middleware_exceptions/middleware.py +++ b/tests/middleware_exceptions/middleware.py @@ -5,7 +5,7 @@ log = [] -class BaseMiddleware(object): +class BaseMiddleware: def __init__(self, get_response): self.get_response = get_response diff --git a/tests/middleware_exceptions/tests.py b/tests/middleware_exceptions/tests.py index 230d062c886d..0c39f09f9156 100644 --- a/tests/middleware_exceptions/tests.py +++ b/tests/middleware_exceptions/tests.py @@ -104,7 +104,7 @@ def test_missing_root_urlconf(self): self.client.get("/middleware_exceptions/view/") -class MyMiddleware(object): +class MyMiddleware: def __init__(self, get_response=None): raise MiddlewareNotUsed @@ -113,7 +113,7 @@ def process_request(self, request): pass -class MyMiddlewareWithExceptionMessage(object): +class MyMiddlewareWithExceptionMessage: def __init__(self, get_response=None): raise MiddlewareNotUsed('spam eggs') diff --git a/tests/migrate_signals/tests.py b/tests/migrate_signals/tests.py index 97f449e80548..563be2a82d1c 100644 --- a/tests/migrate_signals/tests.py +++ b/tests/migrate_signals/tests.py @@ -13,7 +13,7 @@ MIGRATE_INTERACTIVE = False -class Receiver(object): +class Receiver: def __init__(self, signal): self.call_counter = 0 self.call_args = None @@ -24,7 +24,7 @@ def __call__(self, signal, sender, **kwargs): self.call_args = kwargs -class OneTimeReceiver(object): +class OneTimeReceiver: """ Special receiver for handle the fact that test runner calls migrate for several databases and several times for some of them. diff --git a/tests/migrations/models.py b/tests/migrations/models.py index 9a34edf349b6..51679e56bb07 100644 --- a/tests/migrations/models.py +++ b/tests/migrations/models.py @@ -23,7 +23,7 @@ def __str__(self): return self.title -class Unserializable(object): +class Unserializable: """ An object that migration doesn't know how to serialize. """ diff --git a/tests/migrations/routers.py b/tests/migrations/routers.py index 9857363937f9..21dfc561bd71 100644 --- a/tests/migrations/routers.py +++ b/tests/migrations/routers.py @@ -1,8 +1,8 @@ -class EmptyRouter(object): +class EmptyRouter: pass -class TestRouter(object): +class TestRouter: def allow_migrate(self, db, app_label, model_name=None, **hints): """ The Tribble model should be the only one to appear in the 'other' db. diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py index e30aeb5d1918..df35181d926e 100644 --- a/tests/migrations/test_autodetector.py +++ b/tests/migrations/test_autodetector.py @@ -17,7 +17,7 @@ from .models import FoodManager, FoodQuerySet -class DeconstructibleObject(object): +class DeconstructibleObject: """ A custom deconstructible object. """ diff --git a/tests/migrations/test_executor.py b/tests/migrations/test_executor.py index 60e7ec977155..d6cc8021494d 100644 --- a/tests/migrations/test_executor.py +++ b/tests/migrations/test_executor.py @@ -642,13 +642,13 @@ def test_migrate_marks_replacement_applied_even_if_it_did_nothing(self): ) -class FakeLoader(object): +class FakeLoader: def __init__(self, graph, applied): self.graph = graph self.applied_migrations = applied -class FakeMigration(object): +class FakeMigration: """Really all we need is any object with a debug-useful repr.""" def __init__(self, name): self.name = name diff --git a/tests/migrations/test_multidb.py b/tests/migrations/test_multidb.py index c6ca4a844eba..16cd8f33d1a1 100644 --- a/tests/migrations/test_multidb.py +++ b/tests/migrations/test_multidb.py @@ -12,7 +12,7 @@ sqlparse = None -class AgnosticRouter(object): +class AgnosticRouter: """ A router that doesn't have an opinion regarding migrating. """ @@ -20,7 +20,7 @@ def allow_migrate(self, db, app_label, **hints): return None -class MigrateNothingRouter(object): +class MigrateNothingRouter: """ A router that doesn't allow migrating. """ @@ -28,7 +28,7 @@ def allow_migrate(self, db, app_label, **hints): return False -class MigrateEverythingRouter(object): +class MigrateEverythingRouter: """ A router that always allows migrating. """ @@ -36,7 +36,7 @@ def allow_migrate(self, db, app_label, **hints): return True -class MigrateWhenFooRouter(object): +class MigrateWhenFooRouter: """ A router that allows migrating depending on a hint. """ diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py index f962f9cf8c0e..7943b59a44a7 100644 --- a/tests/migrations/test_operations.py +++ b/tests/migrations/test_operations.py @@ -18,7 +18,7 @@ sqlparse = None -class Mixin(object): +class Mixin: pass diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index fb16b441d183..ff5e22ac5e1e 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -485,7 +485,7 @@ def test_serialize_local_function_reference(self): """ Neither py2 or py3 can serialize a reference in a local scope. """ - class TestModel2(object): + class TestModel2: def upload_to(self): return "somewhere dynamic" thing = models.FileField(upload_to=upload_to) @@ -496,7 +496,7 @@ def test_serialize_local_function_reference_message(self): """ Make sure user is seeing which module/function is the issue """ - class TestModel2(object): + class TestModel2: def upload_to(self): return "somewhere dynamic" thing = models.FileField(upload_to=upload_to) @@ -671,7 +671,7 @@ def test_deconstruct_class_arguments(self): # Yes, it doesn't make sense to use a class as a default for a # CharField. It does make sense for custom fields though, for example # an enumfield that takes the enum class as an argument. - class DeconstructibleInstances(object): + class DeconstructibleInstances: def deconstruct(self): return ('DeconstructibleInstances', [], {}) diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index adb90d6d146e..da28fcc7d689 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -2721,7 +2721,7 @@ class Meta: model = Writer fields = '__all__' - class Mixin(object): + class Mixin: age = None class Form(forms.Form): diff --git a/tests/model_formsets_regress/tests.py b/tests/model_formsets_regress/tests.py index 5bad8a741a89..64d933f90cc2 100644 --- a/tests/model_formsets_regress/tests.py +++ b/tests/model_formsets_regress/tests.py @@ -312,7 +312,7 @@ class Meta: localized_fields = ('data',) -class Callback(object): +class Callback: def __init__(self): self.log = [] diff --git a/tests/model_inheritance/models.py b/tests/model_inheritance/models.py index 44bf752d0025..62003f032ea0 100644 --- a/tests/model_inheritance/models.py +++ b/tests/model_inheritance/models.py @@ -157,7 +157,7 @@ class Meta: abstract = True -class Mixin(object): +class Mixin: def __init__(self): self.other_attr = 1 super(Mixin, self).__init__() diff --git a/tests/model_inheritance/test_abstract_inheritance.py b/tests/model_inheritance/test_abstract_inheritance.py index 6f0b89128bd6..d74cae7a3bc7 100644 --- a/tests/model_inheritance/test_abstract_inheritance.py +++ b/tests/model_inheritance/test_abstract_inheritance.py @@ -301,10 +301,10 @@ class AbstractModel(models.Model): class Meta: abstract = True - class Mixin(object): + class Mixin: age = None - class Mixin2(object): + class Mixin2: age = 2 class DescendantMixin(Mixin): diff --git a/tests/modeladmin/test_checks.py b/tests/modeladmin/test_checks.py index 93b35ecf5687..c90ed649583b 100644 --- a/tests/modeladmin/test_checks.py +++ b/tests/modeladmin/test_checks.py @@ -198,7 +198,7 @@ class TestModelAdmin(ModelAdmin): class FormCheckTests(CheckTestCase): def test_invalid_type(self): - class FakeForm(object): + class FakeForm: pass class TestModelAdmin(ModelAdmin): @@ -578,7 +578,7 @@ class TestModelAdmin(ModelAdmin): ) def test_not_filter(self): - class RandomClass(object): + class RandomClass: pass class TestModelAdmin(ModelAdmin): @@ -590,7 +590,7 @@ class TestModelAdmin(ModelAdmin): 'admin.E113') def test_not_filter_again(self): - class RandomClass(object): + class RandomClass: pass class TestModelAdmin(ModelAdmin): @@ -869,7 +869,7 @@ class TestModelAdmin(ModelAdmin): ) def test_not_model_admin(self): - class ValidationTestInline(object): + class ValidationTestInline: pass class TestModelAdmin(ModelAdmin): @@ -894,7 +894,7 @@ class TestModelAdmin(ModelAdmin): 'admin.E105') def test_invalid_model_type(self): - class SomethingBad(object): + class SomethingBad: pass class ValidationTestInline(TabularInline): @@ -1034,7 +1034,7 @@ class TestModelAdmin(ModelAdmin): class FormsetCheckTests(CheckTestCase): def test_invalid_type(self): - class FakeFormSet(object): + class FakeFormSet: pass class ValidationTestInline(TabularInline): diff --git a/tests/modeladmin/tests.py b/tests/modeladmin/tests.py index 12ca86ff1ac6..1cded986faac 100644 --- a/tests/modeladmin/tests.py +++ b/tests/modeladmin/tests.py @@ -14,11 +14,11 @@ from .models import Band, Concert -class MockRequest(object): +class MockRequest: pass -class MockSuperUser(object): +class MockSuperUser: def has_perm(self, perm): return True @@ -589,7 +589,7 @@ def test_log_actions(self): class ModelAdminPermissionTests(SimpleTestCase): - class MockUser(object): + class MockUser: def has_module_perms(self, app_label): if app_label == "modeladmin": return True diff --git a/tests/multiple_database/routers.py b/tests/multiple_database/routers.py index e51c82b858c0..cb12a907c9af 100644 --- a/tests/multiple_database/routers.py +++ b/tests/multiple_database/routers.py @@ -1,7 +1,7 @@ from django.db import DEFAULT_DB_ALIAS -class TestRouter(object): +class TestRouter: """ Vaguely behave like primary/replica, but the databases aren't assumed to propagate changes. @@ -22,7 +22,7 @@ def allow_migrate(self, db, app_label, **hints): return True -class AuthRouter(object): +class AuthRouter: """ Control all database operations on models in the contrib.auth application. """ @@ -54,7 +54,7 @@ def allow_migrate(self, db, app_label, **hints): return None -class WriteRouter(object): +class WriteRouter: # A router that only expresses an opinion on writes def db_for_write(self, model, **hints): return 'writer' diff --git a/tests/multiple_database/tests.py b/tests/multiple_database/tests.py index 3487894fd981..ec04a37e2ff7 100644 --- a/tests/multiple_database/tests.py +++ b/tests/multiple_database/tests.py @@ -1529,7 +1529,7 @@ def test_dumpdata(self): self.assertIn('"email": "alice@example.com"', command_output) -class AntiPetRouter(object): +class AntiPetRouter: # A router that only expresses an opinion on migrate, # passing pets to the 'other' database @@ -1590,7 +1590,7 @@ def test_pickling(self): self.assertEqual(qs.db, pickle.loads(pickle.dumps(qs)).db) -class DatabaseReceiver(object): +class DatabaseReceiver: """ Used in the tests for the database argument in signals (#13552) """ @@ -1598,7 +1598,7 @@ def __call__(self, signal, sender, **kwargs): self._database = kwargs['using'] -class WriteToOtherRouter(object): +class WriteToOtherRouter: """ A router that sends all writes to the other database. """ @@ -1698,7 +1698,7 @@ def test_database_arg_m2m(self): self.assertEqual(receiver._database, "other") -class AttributeErrorRouter(object): +class AttributeErrorRouter: "A router to test the exception handling of ConnectionRouter" def db_for_read(self, model, **hints): raise AttributeError @@ -1751,7 +1751,7 @@ def test_attribute_error_m2m(self): b.authors.set([p]) -class ModelMetaRouter(object): +class ModelMetaRouter: "A router to ensure model arguments are real model classes" def db_for_write(self, model, **hints): if not hasattr(model, '_meta'): @@ -1785,7 +1785,7 @@ def test_foreignkey_collection(self): person.delete() -class SyncOnlyDefaultDatabaseRouter(object): +class SyncOnlyDefaultDatabaseRouter: def allow_migrate(self, db, app_label, **hints): return db == DEFAULT_DB_ALIAS @@ -1828,7 +1828,7 @@ def __init__(self, mode, model, hints): class RouteForWriteTestCase(TestCase): multi_db = True - class WriteCheckRouter(object): + class WriteCheckRouter: def db_for_write(self, model, **hints): raise RouterUsed(mode=RouterUsed.WRITE, model=model, hints=hints) diff --git a/tests/order_with_respect_to/base_tests.py b/tests/order_with_respect_to/base_tests.py index ad8925bf8892..3ca7ada80094 100644 --- a/tests/order_with_respect_to/base_tests.py +++ b/tests/order_with_respect_to/base_tests.py @@ -5,7 +5,7 @@ from operator import attrgetter -class BaseOrderWithRespectToTests(object): +class BaseOrderWithRespectToTests: # Hook to allow subclasses to run these tests with alternate models. Answer = None Post = None diff --git a/tests/pagination/tests.py b/tests/pagination/tests.py index 2e2e2d37db15..4aaaa3c3deb7 100644 --- a/tests/pagination/tests.py +++ b/tests/pagination/tests.py @@ -124,7 +124,7 @@ def test_invalid_page_number(self): self.assertEqual(paginator.validate_number(1), 1) def test_paginate_misc_classes(self): - class CountContainer(object): + class CountContainer: def count(self): return 42 # Paginator can be passed other objects with a count() method. @@ -134,7 +134,7 @@ def count(self): self.assertEqual([1, 2, 3, 4, 5], list(paginator.page_range)) # Paginator can be passed other objects that implement __len__. - class LenContainer(object): + class LenContainer: def __len__(self): return 42 paginator = Paginator(LenContainer(), 10) diff --git a/tests/postgres_tests/models.py b/tests/postgres_tests/models.py index 2a0d69b21ab4..a77fc4b1527e 100644 --- a/tests/postgres_tests/models.py +++ b/tests/postgres_tests/models.py @@ -8,7 +8,7 @@ ) -class Tag(object): +class Tag: def __init__(self, tag_id): self.tag_id = tag_id diff --git a/tests/postgres_tests/test_search.py b/tests/postgres_tests/test_search.py index 0bf2df50f1d6..2108beb181ff 100644 --- a/tests/postgres_tests/test_search.py +++ b/tests/postgres_tests/test_search.py @@ -15,7 +15,7 @@ from .models import Character, Line, Scene -class GrailTestData(object): +class GrailTestData: @classmethod def setUpTestData(cls): diff --git a/tests/queries/tests.py b/tests/queries/tests.py index 1f9094e49fa0..4107dada0e57 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -2862,11 +2862,11 @@ def test_evaluated_proxy_count(self): class WhereNodeTest(TestCase): - class DummyNode(object): + class DummyNode: def as_sql(self, compiler, connection): return 'dummy', [] - class MockCompiler(object): + class MockCompiler: def compile(self, node): return node.as_sql(self, connection) diff --git a/tests/queryset_pickle/models.py b/tests/queryset_pickle/models.py index 4faad0175b06..dbd570a30ba2 100644 --- a/tests/queryset_pickle/models.py +++ b/tests/queryset_pickle/models.py @@ -8,7 +8,7 @@ def standalone_number(): return 1 -class Numbers(object): +class Numbers: @staticmethod def get_static_number(): return 2 @@ -47,7 +47,7 @@ class Happening(models.Model): number2 = models.IntegerField(blank=True, default=Numbers.get_static_number) -class Container(object): +class Container: # To test pickling we need a class that isn't defined on module, but # is still available from app-cache. So, the Container class moves # SomeModel outside of module level diff --git a/tests/serializers/models/base.py b/tests/serializers/models/base.py index 942157847833..78d832140f56 100644 --- a/tests/serializers/models/base.py +++ b/tests/serializers/models/base.py @@ -100,7 +100,7 @@ class Score(models.Model): score = models.FloatField() -class Team(object): +class Team: def __init__(self, title): self.title = title diff --git a/tests/serializers/test_yaml.py b/tests/serializers/test_yaml.py index 542c28fb2efe..5a9fa5e87344 100644 --- a/tests/serializers/test_yaml.py +++ b/tests/serializers/test_yaml.py @@ -18,7 +18,7 @@ YAML_IMPORT_ERROR_MESSAGE = r'No module named yaml' -class YamlImportModuleMock(object): +class YamlImportModuleMock: """Provides a wrapped import_module function to simulate yaml ImportError In order to run tests that verify the behavior of the YAML serializer diff --git a/tests/serializers/tests.py b/tests/serializers/tests.py index 5c30d66082c8..5750c146a2f4 100644 --- a/tests/serializers/tests.py +++ b/tests/serializers/tests.py @@ -88,7 +88,7 @@ def test_get_unknown_deserializer(self): serializers.get_deserializer("nonsense") -class SerializersTestBase(object): +class SerializersTestBase: serializer_name = None # Set by subclasses to the serialization format name @staticmethod @@ -349,7 +349,7 @@ def test_serialize_proxy_model(self): class SerializerAPITests(SimpleTestCase): def test_stream_class(self): - class File(object): + class File: def __init__(self): self.lines = [] @@ -369,7 +369,7 @@ class Serializer(serializers.json.Serializer): self.assertEqual(data, '[{"model": "serializers.score", "pk": 1, "fields": {"score": 3.4}}]') -class SerializersTransactionTestBase(object): +class SerializersTransactionTestBase: available_apps = ['serializers'] diff --git a/tests/servers/test_basehttp.py b/tests/servers/test_basehttp.py index cd9bcd2e86e5..cf0f8ac41bc9 100644 --- a/tests/servers/test_basehttp.py +++ b/tests/servers/test_basehttp.py @@ -8,7 +8,7 @@ from django.test.utils import patch_logger -class Stub(object): +class Stub: def __init__(self, **kwargs): self.__dict__.update(kwargs) diff --git a/tests/sessions_tests/tests.py b/tests/sessions_tests/tests.py index 29de5782d9b3..d4a486b90e73 100644 --- a/tests/sessions_tests/tests.py +++ b/tests/sessions_tests/tests.py @@ -38,7 +38,7 @@ from .models import SessionStore as CustomDatabaseSession -class SessionTestsMixin(object): +class SessionTestsMixin: # This does not inherit from TestCase to avoid any tests being run with this # class, which wouldn't work, and to allow different TestCase subclasses to # be used. diff --git a/tests/signals/tests.py b/tests/signals/tests.py index 88572ad44f84..0c1c885dc41c 100644 --- a/tests/signals/tests.py +++ b/tests/signals/tests.py @@ -122,7 +122,7 @@ def pre_delete_handler(signal, sender, instance, **kwargs): ) # #8285: signals can be any callable - class PostDeleteHandler(object): + class PostDeleteHandler: def __init__(self, data): self.data = data @@ -247,7 +247,7 @@ def test_disconnect_in_dispatch(self): dispatching. """ - class Handler(object): + class Handler: def __init__(self, param): self.param = param self._run = False diff --git a/tests/sites_tests/tests.py b/tests/sites_tests/tests.py index 0179500f14d5..9e2d7ad4fc12 100644 --- a/tests/sites_tests/tests.py +++ b/tests/sites_tests/tests.py @@ -226,7 +226,7 @@ def test_requestsite_delete_notimplemented_msg(self): RequestSite(request).delete() -class JustOtherRouter(object): +class JustOtherRouter: def allow_migrate(self, db, app_label, **hints): return db == 'other' diff --git a/tests/staticfiles_tests/cases.py b/tests/staticfiles_tests/cases.py index 069402c6f647..537fbac6a05d 100644 --- a/tests/staticfiles_tests/cases.py +++ b/tests/staticfiles_tests/cases.py @@ -12,7 +12,7 @@ from .settings import TEST_SETTINGS -class BaseStaticFilesMixin(object): +class BaseStaticFilesMixin: """ Test case with a couple utility assertions. """ @@ -89,7 +89,7 @@ def _get_file(self, filepath): return f.read() -class TestDefaults(object): +class TestDefaults: """ A few standard test cases. """ diff --git a/tests/staticfiles_tests/test_finders.py b/tests/staticfiles_tests/test_finders.py index 0f5cf5bea213..7df8c50a0d63 100644 --- a/tests/staticfiles_tests/test_finders.py +++ b/tests/staticfiles_tests/test_finders.py @@ -9,7 +9,7 @@ from .settings import TEST_ROOT -class TestFinders(object): +class TestFinders: """ Base finder test mixin. diff --git a/tests/staticfiles_tests/test_management.py b/tests/staticfiles_tests/test_management.py index 310c152d06ab..f0160c60d8b1 100644 --- a/tests/staticfiles_tests/test_management.py +++ b/tests/staticfiles_tests/test_management.py @@ -25,7 +25,7 @@ from .storage import DummyStorage -class TestNoFilesCreated(object): +class TestNoFilesCreated: def test_no_files_created(self): """ diff --git a/tests/staticfiles_tests/test_storage.py b/tests/staticfiles_tests/test_storage.py index e299feea78de..c72100ccb193 100644 --- a/tests/staticfiles_tests/test_storage.py +++ b/tests/staticfiles_tests/test_storage.py @@ -23,7 +23,7 @@ def hashed_file_path(test, path): return fullpath.replace(settings.STATIC_URL, '') -class TestHashedFiles(object): +class TestHashedFiles: hashed_file_path = hashed_file_path def setUp(self): diff --git a/tests/template_tests/filter_tests/test_floatformat.py b/tests/template_tests/filter_tests/test_floatformat.py index 8474238f2132..e0f7666ff0d1 100644 --- a/tests/template_tests/filter_tests/test_floatformat.py +++ b/tests/template_tests/filter_tests/test_floatformat.py @@ -72,7 +72,7 @@ def test_infinity(self): self.assertEqual(floatformat(nan), str(nan)) def test_float_dunder_method(self): - class FloatWrapper(object): + class FloatWrapper: def __init__(self, value): self.value = value diff --git a/tests/template_tests/filter_tests/test_unordered_list.py b/tests/template_tests/filter_tests/test_unordered_list.py index 659b1acc2bf4..b4d624345b43 100644 --- a/tests/template_tests/filter_tests/test_unordered_list.py +++ b/tests/template_tests/filter_tests/test_unordered_list.py @@ -87,7 +87,7 @@ def test_autoescape_off(self): ) def test_ulitem(self): - class ULItem(object): + class ULItem: def __init__(self, title): self.title = title @@ -113,7 +113,7 @@ def item_generator(): ) def test_ulitem_autoescape_off(self): - class ULItem(object): + class ULItem: def __init__(self, title): self.title = title diff --git a/tests/template_tests/test_callables.py b/tests/template_tests/test_callables.py index 4cfb49db5c6a..6a361e8409ea 100644 --- a/tests/template_tests/test_callables.py +++ b/tests/template_tests/test_callables.py @@ -12,7 +12,7 @@ def setUpClass(cls): def test_callable(self): - class Doodad(object): + class Doodad: def __init__(self, value): self.num_calls = 0 self.value = value @@ -41,7 +41,7 @@ def __call__(self): def test_alters_data(self): - class Doodad(object): + class Doodad: alters_data = True def __init__(self, value): @@ -68,7 +68,7 @@ def __call__(self): def test_do_not_call(self): - class Doodad(object): + class Doodad: do_not_call_in_templates = True def __init__(self, value): @@ -100,7 +100,7 @@ def test_do_not_call_and_alters_data(self): # ``alters_data`` attribute will not make any difference in the # template system's behavior. - class Doodad(object): + class Doodad: do_not_call_in_templates = True alters_data = True diff --git a/tests/template_tests/test_logging.py b/tests/template_tests/test_logging.py index 9dd804640887..e03809d86464 100644 --- a/tests/template_tests/test_logging.py +++ b/tests/template_tests/test_logging.py @@ -31,7 +31,7 @@ class VariableResolveLoggingTests(BaseTemplateLoggingTestCase): loglevel = logging.DEBUG def test_log_on_variable_does_not_exist_silent(self): - class TestObject(object): + class TestObject: class SilentDoesNotExist(Exception): silent_variable_failure = True diff --git a/tests/template_tests/utils.py b/tests/template_tests/utils.py index 187d259f36a4..8ee66a65239a 100644 --- a/tests/template_tests/utils.py +++ b/tests/template_tests/utils.py @@ -142,7 +142,7 @@ def method(self): return 'OtherClass.method' -class TestObj(object): +class TestObj: def is_true(self): return True @@ -153,12 +153,12 @@ def is_bad(self): raise ShouldNotExecuteException() -class SilentGetItemClass(object): +class SilentGetItemClass: def __getitem__(self, key): raise SomeException -class SilentAttrClass(object): +class SilentAttrClass: def b(self): raise SomeException b = property(b) diff --git a/tests/test_client/auth_backends.py b/tests/test_client/auth_backends.py index 1bb1d96eeb5b..97a2763aaab3 100644 --- a/tests/test_client/auth_backends.py +++ b/tests/test_client/auth_backends.py @@ -5,5 +5,5 @@ class TestClientBackend(ModelBackend): pass -class BackendWithoutGetUserMethod(object): +class BackendWithoutGetUserMethod: pass diff --git a/tests/test_client/views.py b/tests/test_client/views.py index e9a28449ec72..bc6a59f7608f 100644 --- a/tests/test_client/views.py +++ b/tests/test_client/views.py @@ -248,7 +248,7 @@ def _permission_protected_view(request): ) -class _ViewManager(object): +class _ViewManager: @method_decorator(login_required) def login_protected_view(self, request): t = Template('This is a login protected test using a method. ' diff --git a/tests/test_client_regress/tests.py b/tests/test_client_regress/tests.py index 0436ae99680d..16b344e0ae64 100644 --- a/tests/test_client_regress/tests.py +++ b/tests/test_client_regress/tests.py @@ -24,7 +24,7 @@ from .views import CustomTestException -class TestDataMixin(object): +class TestDataMixin: @classmethod def setUpTestData(cls): @@ -1298,7 +1298,7 @@ def test_unicode_payload_non_utf(self): self.assertEqual(response.content, json.encode('koi8-r')) -class DummyFile(object): +class DummyFile: def __init__(self, filename): self.name = filename diff --git a/tests/test_runner/tests.py b/tests/test_runner/tests.py index 670bc6683ce3..51810fe7bcd6 100644 --- a/tests/test_runner/tests.py +++ b/tests/test_runner/tests.py @@ -129,7 +129,7 @@ def test_own_alias_dependency(self): dependency_ordered(raw, dependencies=dependencies) -class MockTestRunner(object): +class MockTestRunner: def __init__(self, *args, **kwargs): pass diff --git a/tests/transactions/tests.py b/tests/transactions/tests.py index 12d2eb299dbf..033619c0c813 100644 --- a/tests/transactions/tests.py +++ b/tests/transactions/tests.py @@ -413,7 +413,7 @@ class AtomicMiscTests(TransactionTestCase): def test_wrap_callable_instance(self): """#20028 -- Atomic must support wrapping callable instances.""" - class Callable(object): + class Callable: def __call__(self): pass diff --git a/tests/urlpatterns_reverse/method_view_urls.py b/tests/urlpatterns_reverse/method_view_urls.py index c28958e6a96f..e91966b4ace1 100644 --- a/tests/urlpatterns_reverse/method_view_urls.py +++ b/tests/urlpatterns_reverse/method_view_urls.py @@ -1,7 +1,7 @@ from django.conf.urls import url -class ViewContainer(object): +class ViewContainer: def method_view(self, request): pass diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py index 62d199c030b9..efb30dc2ff5e 100644 --- a/tests/urlpatterns_reverse/tests.py +++ b/tests/urlpatterns_reverse/tests.py @@ -518,7 +518,7 @@ class ReverseShortcutTests(SimpleTestCase): def test_redirect_to_object(self): # We don't really need a model; just something with a get_absolute_url - class FakeObj(object): + class FakeObj: def get_absolute_url(self): return "/hi-there/" diff --git a/tests/urlpatterns_reverse/utils.py b/tests/urlpatterns_reverse/utils.py index 22664480d168..8c96d8ca724f 100644 --- a/tests/urlpatterns_reverse/utils.py +++ b/tests/urlpatterns_reverse/utils.py @@ -3,7 +3,7 @@ from . import views -class URLObject(object): +class URLObject: urlpatterns = [ url(r'^inner/$', views.empty_view, name='urlobject-view'), url(r'^inner/(?P[0-9]+)/(?P[0-9]+)/$', views.empty_view, name='urlobject-view'), diff --git a/tests/urlpatterns_reverse/views.py b/tests/urlpatterns_reverse/views.py index e8765367be70..584c70a6e526 100644 --- a/tests/urlpatterns_reverse/views.py +++ b/tests/urlpatterns_reverse/views.py @@ -35,7 +35,7 @@ def pass_resolver_match_view(request, *args, **kwargs): uncallable = None # neither a callable nor a string -class ViewClass(object): +class ViewClass: def __call__(self, request, *args, **kwargs): return HttpResponse('') diff --git a/tests/utils_tests/test_archive.py b/tests/utils_tests/test_archive.py index b207a1290acf..f50e18d75c7e 100644 --- a/tests/utils_tests/test_archive.py +++ b/tests/utils_tests/test_archive.py @@ -11,7 +11,7 @@ TEST_DIR = os.path.join(os.path.dirname(upath(__file__)), 'archives') -class ArchiveTester(object): +class ArchiveTester: archive = None def setUp(self): diff --git a/tests/utils_tests/test_decorators.py b/tests/utils_tests/test_decorators.py index a4d080e2d7ff..fe5db876ef58 100644 --- a/tests/utils_tests/test_decorators.py +++ b/tests/utils_tests/test_decorators.py @@ -5,7 +5,7 @@ from django.utils.decorators import classproperty, decorator_from_middleware -class ProcessViewMiddleware(object): +class ProcessViewMiddleware: def process_view(self, request, view_func, view_args, view_kwargs): pass @@ -18,7 +18,7 @@ def process_view(request): return HttpResponse() -class ClassProcessView(object): +class ClassProcessView: def __call__(self, request): return HttpResponse() @@ -26,7 +26,7 @@ def __call__(self, request): class_process_view = process_view_dec(ClassProcessView()) -class FullMiddleware(object): +class FullMiddleware: def process_request(self, request): request.process_request_reached = True @@ -112,7 +112,7 @@ def template_response_view(request): class ClassPropertyTest(SimpleTestCase): def test_getter(self): - class Foo(object): + class Foo: foo_attr = 123 def __init__(self): @@ -122,7 +122,7 @@ def __init__(self): def foo(cls): return cls.foo_attr - class Bar(object): + class Bar: bar = classproperty() @bar.getter @@ -135,7 +135,7 @@ def bar(cls): self.assertEqual(Bar().bar, 123) def test_override_getter(self): - class Foo(object): + class Foo: @classproperty def foo(cls): return 123 diff --git a/tests/utils_tests/test_encoding.py b/tests/utils_tests/test_encoding.py index faf30a59c0f6..ca9343674df7 100644 --- a/tests/utils_tests/test_encoding.py +++ b/tests/utils_tests/test_encoding.py @@ -14,7 +14,7 @@ def test_force_text_exception(self): """ Broken __unicode__/__str__ actually raises an error. """ - class MyString(object): + class MyString: def __str__(self): return b'\xc3\xb6\xc3\xa4\xc3\xbc' diff --git a/tests/utils_tests/test_functional.py b/tests/utils_tests/test_functional.py index f53e212f93b7..befbcf931ce4 100644 --- a/tests/utils_tests/test_functional.py +++ b/tests/utils_tests/test_functional.py @@ -11,7 +11,7 @@ def test_lazy(self): def test_lazy_base_class(self): """lazy also finds base class methods in the proxy object""" - class Base(object): + class Base: def base_method(self): pass @@ -23,7 +23,7 @@ class Klazz(Base): def test_lazy_base_class_override(self): """lazy finds the correct (overridden) method implementation""" - class Base(object): + class Base: def method(self): return 'Base' @@ -36,7 +36,7 @@ def method(self): def test_lazy_object_to_string(self): - class Klazz(object): + class Klazz: def __str__(self): return "Î am ā Ǩlâzz." @@ -51,7 +51,7 @@ def test_cached_property(self): """ cached_property caches its value and that it behaves like a property """ - class A(object): + class A: @cached_property def value(self): diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py index 8f887fd011b0..5ffccdae83c6 100644 --- a/tests/utils_tests/test_html.py +++ b/tests/utils_tests/test_html.py @@ -167,7 +167,7 @@ def test_conditional_escape(self): def test_html_safe(self): @html.html_safe - class HtmlClass(object): + class HtmlClass: def __str__(self): return "

    I'm a html class!

    " @@ -177,7 +177,7 @@ def __str__(self): self.assertEqual(force_text(html_obj), html_obj.__html__()) def test_html_safe_subclass(self): - class BaseClass(object): + class BaseClass: def __html__(self): # defines __html__ on its own return 'some html content' @@ -198,7 +198,7 @@ def test_html_safe_defines_html_error(self): msg = "can't apply @html_safe to HtmlClass because it defines __html__()." with self.assertRaisesMessage(ValueError, msg): @html.html_safe - class HtmlClass(object): + class HtmlClass: def __html__(self): return "

    I'm a html class!

    " @@ -206,5 +206,5 @@ def test_html_safe_doesnt_define_str(self): msg = "can't apply @html_safe to HtmlClass because it doesn't define __str__()." with self.assertRaisesMessage(ValueError, msg): @html.html_safe - class HtmlClass(object): + class HtmlClass: pass diff --git a/tests/utils_tests/test_inspect.py b/tests/utils_tests/test_inspect.py index e9a2cd086fcf..7464a9226dd1 100644 --- a/tests/utils_tests/test_inspect.py +++ b/tests/utils_tests/test_inspect.py @@ -3,7 +3,7 @@ from django.utils import inspect -class Person(object): +class Person: def no_arguments(self): return None diff --git a/tests/utils_tests/test_lazyobject.py b/tests/utils_tests/test_lazyobject.py index 513123ea004f..11bf16374763 100644 --- a/tests/utils_tests/test_lazyobject.py +++ b/tests/utils_tests/test_lazyobject.py @@ -9,7 +9,7 @@ from .models import Category, CategoryInfo -class Foo(object): +class Foo: """ A simple class with just one attribute. """ @@ -167,7 +167,7 @@ def test_iter(self): # Tests whether an object's custom `__iter__` method is being # used when iterating over it. - class IterObject(object): + class IterObject: def __init__(self, values): self.values = values @@ -356,7 +356,7 @@ def test_list_set(self): self.assertEqual(len(lazy_set), 4) -class BaseBaz(object): +class BaseBaz: """ A base class with a funky __reduce__ method, meant to simulate the __reduce__ method of Model, which sets self._django_version. diff --git a/tests/utils_tests/test_module/__init__.py b/tests/utils_tests/test_module/__init__.py index 29ee11b722fd..d8a5fe2ed9f5 100644 --- a/tests/utils_tests/test_module/__init__.py +++ b/tests/utils_tests/test_module/__init__.py @@ -1,4 +1,4 @@ -class SiteMock(object): +class SiteMock: _registry = {} diff --git a/tests/utils_tests/test_module_loading.py b/tests/utils_tests/test_module_loading.py index 2a524a2cf2aa..e979b3e7ba04 100644 --- a/tests/utils_tests/test_module_loading.py +++ b/tests/utils_tests/test_module_loading.py @@ -179,7 +179,7 @@ def test_validate_registry_resets_after_missing_module(self): self.assertEqual(site._registry, {'lorem': 'ipsum'}) -class ProxyFinder(object): +class ProxyFinder: def __init__(self): self._cache = {} @@ -208,7 +208,7 @@ def load_module(self, fullname): fd.close() -class TestFinder(object): +class TestFinder: def __init__(self, *args, **kwargs): self.importer = zipimporter(*args, **kwargs) @@ -219,7 +219,7 @@ def find_module(self, path): return TestLoader(importer) -class TestLoader(object): +class TestLoader: def __init__(self, importer): self.importer = importer diff --git a/tests/utils_tests/test_safestring.py b/tests/utils_tests/test_safestring.py index 9e99b6e20b67..d1ef28944ee6 100644 --- a/tests/utils_tests/test_safestring.py +++ b/tests/utils_tests/test_safestring.py @@ -44,7 +44,7 @@ def test_mark_safe_lazy(self): self.assertRenderEqual('{{ s }}', 'a&b', s=mark_safe(s)) def test_mark_safe_object_implementing_dunder_str(self): - class Obj(object): + class Obj: def __str__(self): return '' diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py index 7a9cea826bd6..a3938ce8489b 100644 --- a/tests/view_tests/tests/test_debug.py +++ b/tests/view_tests/tests/test_debug.py @@ -32,7 +32,7 @@ PY36 = sys.version_info >= (3, 6) -class User(object): +class User: def __str__(self): return 'jacob' @@ -45,7 +45,7 @@ class CallableSettingWrapperTests(SimpleTestCase): """ Unittests for CallableSettingWrapper """ def test_repr(self): - class WrappedCallable(object): + class WrappedCallable: def __repr__(self): return "repr from the wrapped callable" @@ -422,7 +422,7 @@ def __repr__(self): def test_unprintable_values_handling(self): "Unprintable values should not make the output generation choke." try: - class OomOutput(object): + class OomOutput: def __repr__(self): raise MemoryError('OOM') oomvalue = OomOutput() # NOQA @@ -438,7 +438,7 @@ def test_too_large_values_handling(self): large = 256 * 1024 repr_of_str_adds = len(repr('')) try: - class LargeOutput(object): + class LargeOutput: def __repr__(self): return repr('A' * large) largevalue = LargeOutput() # NOQA @@ -535,7 +535,7 @@ def test_exception_fetching_user(self): The error page can be rendered if the current user can't be retrieved (such as when the database is unavailable). """ - class ExceptionUser(object): + class ExceptionUser: def __str__(self): raise Exception() @@ -654,7 +654,7 @@ def test_disallowed_host(self): self.assertIn("http://evil.com/", text) -class ExceptionReportTestMixin(object): +class ExceptionReportTestMixin: # Mixin used in the ExceptionReporterFilterTests and # AjaxResponseExceptionReporterFilter tests below @@ -951,7 +951,7 @@ def test_callable_settings_forbidding_to_set_attributes(self): Callable settings which forbid to set attributes should not break the debug page (#23070). """ - class CallableSettingWithSlots(object): + class CallableSettingWithSlots: __slots__ = [] def __call__(self): diff --git a/tests/view_tests/views.py b/tests/view_tests/views.py index 5c6311140544..2e47037470c4 100644 --- a/tests/view_tests/views.py +++ b/tests/view_tests/views.py @@ -241,7 +241,7 @@ def custom_exception_reporter_filter_view(request): return technical_500_response(request, *exc_info) -class Klass(object): +class Klass: @sensitive_variables('sauce') def method(self, request): diff --git a/tests/wsgi/tests.py b/tests/wsgi/tests.py index 68e8d4a86d41..13c55365201e 100644 --- a/tests/wsgi/tests.py +++ b/tests/wsgi/tests.py @@ -49,7 +49,7 @@ def test_file_wrapper(self): """ FileResponse uses wsgi.file_wrapper. """ - class FileWrapper(object): + class FileWrapper: def __init__(self, filelike, blksize=8192): filelike.close() application = get_wsgi_application() From 7d200949968002d2c2b4390953e8bda7153a49c9 Mon Sep 17 00:00:00 2001 From: james mike dupont Date: Thu, 19 Jan 2017 05:00:41 -0500 Subject: [PATCH 0069/3180] Fixed spelling mistakes in code and comments. --- django/db/backends/mysql/base.py | 4 ++-- django/db/backends/utils.py | 6 +++--- tests/inspectdb/models.py | 2 +- tests/inspectdb/tests.py | 4 ++-- tests/model_fields/test_foreignkey.py | 6 +++--- tests/model_fields/test_manytomanyfield.py | 8 ++++---- tests/urlpatterns_reverse/tests.py | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 3239ba104fdc..9f911343258e 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -116,8 +116,8 @@ def __enter__(self): return self def __exit__(self, type, value, traceback): - # Ticket #17671 - Close instead of passing thru to avoid backend - # specific behavior. + # Close instead of passing through to avoid backend-specific behavior + # (#17671). self.close() diff --git a/django/db/backends/utils.py b/django/db/backends/utils.py index f6cb59a08604..3baff0d3d5b9 100644 --- a/django/db/backends/utils.py +++ b/django/db/backends/utils.py @@ -34,9 +34,9 @@ def __enter__(self): return self def __exit__(self, type, value, traceback): - # Ticket #17671 - Close instead of passing thru to avoid backend - # specific behavior. Catch errors liberally because errors in cleanup - # code aren't useful. + # Close instead of passing through to avoid backend-specific behavior + # (#17671). Catch errors liberally because errors in cleanup code + # aren't useful. try: self.close() except self.db.Database.Error: diff --git a/tests/inspectdb/models.py b/tests/inspectdb/models.py index 668fc51aed35..1a001b653e12 100644 --- a/tests/inspectdb/models.py +++ b/tests/inspectdb/models.py @@ -55,7 +55,7 @@ class ColumnTypes(models.Model): file_path_field = models.FilePathField() float_field = models.FloatField() int_field = models.IntegerField() - gen_ip_adress_field = models.GenericIPAddressField(protocol="ipv4") + gen_ip_address_field = models.GenericIPAddressField(protocol="ipv4") pos_int_field = models.PositiveIntegerField() pos_small_int_field = models.PositiveSmallIntegerField() slug_field = models.SlugField() diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py index ef26233342ff..726a65cd8f8f 100644 --- a/tests/inspectdb/tests.py +++ b/tests/inspectdb/tests.py @@ -66,9 +66,9 @@ def test_field_types(self): assertFieldType('date_field', "models.DateField()") assertFieldType('date_time_field', "models.DateTimeField()") if connection.features.can_introspect_ip_address_field: - assertFieldType('gen_ip_adress_field', "models.GenericIPAddressField()") + assertFieldType('gen_ip_address_field', "models.GenericIPAddressField()") elif not connection.features.interprets_empty_strings_as_nulls: - assertFieldType('gen_ip_adress_field', "models.CharField(max_length=39)") + assertFieldType('gen_ip_address_field', "models.CharField(max_length=39)") if connection.features.can_introspect_time_field: assertFieldType('time_field', "models.TimeField()") if connection.features.has_native_uuid_field: diff --git a/tests/model_fields/test_foreignkey.py b/tests/model_fields/test_foreignkey.py index 2580e3b6504c..1617f7f310c9 100644 --- a/tests/model_fields/test_foreignkey.py +++ b/tests/model_fields/test_foreignkey.py @@ -74,14 +74,14 @@ class Meta: @isolate_apps('model_fields', 'model_fields.tests') def test_abstract_model_app_relative_foreign_key(self): class AbstractReferent(models.Model): - reference = models.ForeignKey('Refered', on_delete=models.CASCADE) + reference = models.ForeignKey('Referred', on_delete=models.CASCADE) class Meta: app_label = 'model_fields' abstract = True def assert_app_model_resolved(label): - class Refered(models.Model): + class Referred(models.Model): class Meta: app_label = label @@ -89,7 +89,7 @@ class ConcreteReferent(AbstractReferent): class Meta: app_label = label - self.assertEqual(ConcreteReferent._meta.get_field('reference').related_model, Refered) + self.assertEqual(ConcreteReferent._meta.get_field('reference').related_model, Referred) assert_app_model_resolved('model_fields') assert_app_model_resolved('tests') diff --git a/tests/model_fields/test_manytomanyfield.py b/tests/model_fields/test_manytomanyfield.py index e4f1c0469d4d..b270048bd8ef 100644 --- a/tests/model_fields/test_manytomanyfield.py +++ b/tests/model_fields/test_manytomanyfield.py @@ -39,19 +39,19 @@ class Meta: @isolate_apps('model_fields', 'model_fields.tests') def test_abstract_model_app_relative_foreign_key(self): class AbstractReferent(models.Model): - reference = models.ManyToManyField('Refered', through='Through') + reference = models.ManyToManyField('Referred', through='Through') class Meta: app_label = 'model_fields' abstract = True def assert_app_model_resolved(label): - class Refered(models.Model): + class Referred(models.Model): class Meta: app_label = label class Through(models.Model): - refered = models.ForeignKey('Refered', on_delete=models.CASCADE) + referred = models.ForeignKey('Referred', on_delete=models.CASCADE) referent = models.ForeignKey('ConcreteReferent', on_delete=models.CASCADE) class Meta: @@ -61,7 +61,7 @@ class ConcreteReferent(AbstractReferent): class Meta: app_label = label - self.assertEqual(ConcreteReferent._meta.get_field('reference').related_model, Refered) + self.assertEqual(ConcreteReferent._meta.get_field('reference').related_model, Referred) self.assertEqual(ConcreteReferent.reference.through, Through) assert_app_model_resolved('model_fields') diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py index efb30dc2ff5e..a7f7c2fcc8a2 100644 --- a/tests/urlpatterns_reverse/tests.py +++ b/tests/urlpatterns_reverse/tests.py @@ -391,7 +391,7 @@ def test_non_regex(self): A Resolver404 is raised if resolving doesn't meet the basic requirements of a path to match - i.e., at the very least, it matches the root pattern '^/'. Never return None from resolve() to prevent a - TypeError from occuring later (#10834). + TypeError from occurring later (#10834). """ with self.assertRaises(Resolver404): resolve('') From 5320fa77c3b2bc02ac232c3e0f5279d99a528e6a Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 19 Jan 2017 08:50:28 -0500 Subject: [PATCH 0070/3180] Refs #23919 -- Removed obsolete contextlib.closing() calls (for Python 2). --- tests/file_uploads/views.py | 3 +-- tests/servers/tests.py | 11 +++++------ tests/staticfiles_tests/test_liveserver.py | 3 +-- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/tests/file_uploads/views.py b/tests/file_uploads/views.py index c4166087acc9..789cc2a3652f 100644 --- a/tests/file_uploads/views.py +++ b/tests/file_uploads/views.py @@ -1,4 +1,3 @@ -import contextlib import hashlib import json import os @@ -98,7 +97,7 @@ def file_upload_echo_content(request): Simple view to echo back the content of uploaded files for tests. """ def read_and_close(f): - with contextlib.closing(f): + with f: return f.read().decode('utf-8') r = {k: read_and_close(f) for k, f in request.FILES.items()} return HttpResponse(json.dumps(r)) diff --git a/tests/servers/tests.py b/tests/servers/tests.py index 8f7e3253e71f..bf87306cce58 100644 --- a/tests/servers/tests.py +++ b/tests/servers/tests.py @@ -1,7 +1,6 @@ """ Tests for django.core.servers. """ -import contextlib import errno import os import socket @@ -58,11 +57,11 @@ def test_404(self): self.assertEqual(err.exception.code, 404, 'Expected 404 response') def test_view(self): - with contextlib.closing(self.urlopen('/example_view/')) as f: + with self.urlopen('/example_view/') as f: self.assertEqual(f.read(), b'example view') def test_static_files(self): - with contextlib.closing(self.urlopen('/static/example_static_file.txt')) as f: + with self.urlopen('/static/example_static_file.txt') as f: self.assertEqual(f.read().rstrip(b'\r\n'), b'example static file') def test_no_collectstatic_emulation(self): @@ -76,11 +75,11 @@ def test_no_collectstatic_emulation(self): self.assertEqual(err.exception.code, 404, 'Expected 404 response') def test_media_files(self): - with contextlib.closing(self.urlopen('/media/example_media_file.txt')) as f: + with self.urlopen('/media/example_media_file.txt') as f: self.assertEqual(f.read().rstrip(b'\r\n'), b'example media file') def test_environ(self): - with contextlib.closing(self.urlopen('/environ_view/?%s' % urlencode({'q': 'тест'}))) as f: + with self.urlopen('/environ_view/?%s' % urlencode({'q': 'тест'})) as f: self.assertIn(b"QUERY_STRING: 'q=%D1%82%D0%B5%D1%81%D1%82'", f.read()) @@ -90,7 +89,7 @@ def test_fixtures_loaded(self): """ Fixtures are properly loaded and visible to the live server thread. """ - with contextlib.closing(self.urlopen('/model_view/')) as f: + with self.urlopen('/model_view/') as f: self.assertEqual(f.read().splitlines(), [b'jane', b'robert']) def test_database_writes(self): diff --git a/tests/staticfiles_tests/test_liveserver.py b/tests/staticfiles_tests/test_liveserver.py index b3727bea12cf..717de5cf6416 100644 --- a/tests/staticfiles_tests/test_liveserver.py +++ b/tests/staticfiles_tests/test_liveserver.py @@ -4,7 +4,6 @@ django.test.LiveServerTestCase. """ -import contextlib import os from urllib.request import urlopen @@ -86,5 +85,5 @@ def test_collectstatic_emulation(self): StaticLiveServerTestCase use of staticfiles' serve() allows it to discover app's static assets without having to collectstatic first. """ - with contextlib.closing(self.urlopen('/static/test/file.txt')) as f: + with self.urlopen('/static/test/file.txt') as f: self.assertEqual(f.read().rstrip(b'\r\n'), b'In static directory.') From 56aee8d59f2946343cb83de6fde08adcc236a837 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 19 Jan 2017 09:10:01 -0500 Subject: [PATCH 0071/3180] Removed xmlrunner from flake8 exclude. This is an obsolete thing that Jenkins builds needed. --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 726bddb3af4e..d84a4aefc76d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,7 +3,7 @@ doc_files = docs extras AUTHORS INSTALL LICENSE README.rst install-script = scripts/rpm-install.sh [flake8] -exclude = build,.git,.tox,./django/utils/six.py,./django/conf/app_template/*,./tests/.env,./xmlrunner +exclude = build,.git,.tox,./django/utils/six.py,./django/conf/app_template/*,./tests/.env ignore = W601 max-line-length = 119 From e5c67f099159f522d140148fa1a6c876d38288f4 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 19 Jan 2017 10:56:00 -0500 Subject: [PATCH 0072/3180] Refs #23919 -- Removed reset_warning_registry() workaround for Python < 3.4.2. --- django/test/utils.py | 14 -------------- tests/deprecation/tests.py | 2 -- 2 files changed, 16 deletions(-) diff --git a/django/test/utils.py b/django/test/utils.py index 7cff683dff13..4fa379b4a7c1 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -768,20 +768,6 @@ def captured_stdin(): return captured_output("stdin") -def reset_warning_registry(): - """ - Clear warning registry for all modules. This is required in some tests - because of a bug in Python that prevents warnings.simplefilter("always") - from always making warnings appear: http://bugs.python.org/issue4180 - - The bug was fixed in Python 3.4.2. - """ - key = "__warningregistry__" - for mod in sys.modules.values(): - if hasattr(mod, key): - getattr(mod, key).clear() - - @contextmanager def freeze_time(t): """ diff --git a/tests/deprecation/tests.py b/tests/deprecation/tests.py index 220010d9090d..1afd52f94327 100644 --- a/tests/deprecation/tests.py +++ b/tests/deprecation/tests.py @@ -1,7 +1,6 @@ import warnings from django.test import SimpleTestCase -from django.test.utils import reset_warning_registry from django.utils.deprecation import ( DeprecationInstanceCheck, RemovedInNextVersionWarning, RenameMethodsBase, ) @@ -24,7 +23,6 @@ def test_class_definition_warnings(self): Ensure a warning is raised upon class definition to suggest renaming the faulty method. """ - reset_warning_registry() with warnings.catch_warnings(record=True) as recorded: warnings.simplefilter('always') From 53f3d53ed413d44c88d7e83ee11cff113e84ff4d Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Thu, 19 Jan 2017 17:07:17 +0100 Subject: [PATCH 0073/3180] Updated translation catalogs Forward port of 518693bef559bb719e68b08904a9250abfd9237c from stable/1.11.x --- django/conf/locale/en/LC_MESSAGES/django.po | 41 ++++++++++++++----- .../admin/locale/en/LC_MESSAGES/django.po | 7 ++-- .../admindocs/locale/en/LC_MESSAGES/django.po | 15 ++----- .../gis/locale/en/LC_MESSAGES/django.po | 8 +--- .../postgres/locale/en/LC_MESSAGES/django.po | 8 ++-- 5 files changed, 42 insertions(+), 37 deletions(-) diff --git a/django/conf/locale/en/LC_MESSAGES/django.po b/django/conf/locale/en/LC_MESSAGES/django.po index 01fa3b1534b5..a1709b8de4c7 100644 --- a/django/conf/locale/en/LC_MESSAGES/django.po +++ b/django/conf/locale/en/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: Django\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-06-29 20:57+0200\n" +"POT-Creation-Date: 2017-01-19 16:49+0100\n" "PO-Revision-Date: 2010-05-13 15:35+0200\n" "Last-Translator: Django team\n" "Language-Team: English \n" @@ -381,7 +381,19 @@ msgstr "" msgid "Syndication" msgstr "" -#: core/validators.py:33 +#: core/paginator.py:43 +msgid "That page number is not an integer" +msgstr "" + +#: core/paginator.py:45 +msgid "That page number is less than 1" +msgstr "" + +#: core/paginator.py:50 +msgid "That page contains no results" +msgstr "" + +#: core/validators.py:34 msgid "Enter a valid value." msgstr "" @@ -484,7 +496,14 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: db/models/base.py:1095 forms/models.py:727 +#: core/validators.py:464 +#, python-format +msgid "" +"File extension '%(extension)s' is not allowed. Allowed extensions are: " +"'%(allowed_extensions)s'." +msgstr "" + +#: db/models/base.py:1205 forms/models.py:732 msgid "and" msgstr "" @@ -890,16 +909,16 @@ msgid "" "may be ambiguous or it may not exist." msgstr "" -#: forms/widgets.py:353 -msgid "Currently" +#: forms/widgets.py:378 +msgid "Clear" msgstr "" -#: forms/widgets.py:354 -msgid "Change" +#: forms/widgets.py:379 +msgid "Currently" msgstr "" -#: forms/widgets.py:355 -msgid "Clear" +#: forms/widgets.py:380 +msgid "Change" msgstr "" #: forms/widgets.py:570 @@ -1365,8 +1384,8 @@ msgstr "" #: views/debug.py:511 msgid "" -"Of course, you haven't actually done any work yet. Next, start your first " -"app by running python manage.py startapp [app_label]." +"Next, start your first app by running python manage.py startapp " +"[app_label]." msgstr "" #: views/debug.py:513 diff --git a/django/contrib/admin/locale/en/LC_MESSAGES/django.po b/django/contrib/admin/locale/en/LC_MESSAGES/django.po index 172c8224c3d6..7ff80586691d 100644 --- a/django/contrib/admin/locale/en/LC_MESSAGES/django.po +++ b/django/contrib/admin/locale/en/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: Django\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-05-17 23:12+0200\n" +"POT-Creation-Date: 2017-01-19 16:49+0100\n" "PO-Revision-Date: 2010-05-13 15:35+0200\n" "Last-Translator: Django team\n" "Language-Team: English \n" @@ -250,10 +250,9 @@ msgstr "" msgid "The %(name)s \"%(obj)s\" was deleted successfully." msgstr "" -#: contrib/admin/options.py:1424 contrib/admin/options.py:1682 -#: contrib/admin/options.py:1738 +#: contrib/admin/options.py:1397 #, python-format -msgid "%(name)s object with primary key %(key)r does not exist." +msgid "%(name)s with ID \"%(key)s\" doesn't exist. Perhaps it was deleted?" msgstr "" #: contrib/admin/options.py:1475 diff --git a/django/contrib/admindocs/locale/en/LC_MESSAGES/django.po b/django/contrib/admindocs/locale/en/LC_MESSAGES/django.po index 444d7b2c9408..d4cd33bed68e 100644 --- a/django/contrib/admindocs/locale/en/LC_MESSAGES/django.po +++ b/django/contrib/admindocs/locale/en/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: Django\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-05-17 23:12+0200\n" +"POT-Creation-Date: 2017-01-19 16:49+0100\n" "PO-Revision-Date: 2010-05-13 15:35+0200\n" "Last-Translator: Django team\n" "Language-Team: English \n" @@ -301,17 +301,8 @@ msgid "" "code>.\n" msgstr "" -#: contrib/admindocs/tests/test_fields.py:32 -msgid "Boolean (Either True or False)" -msgstr "" - -#: contrib/admindocs/tests/test_fields.py:42 -#, python-format -msgid "Field of type: %(field_type)s" -msgstr "" - -#: contrib/admindocs/views.py:75 contrib/admindocs/views.py:77 -#: contrib/admindocs/views.py:79 +#: contrib/admindocs/views.py:78 contrib/admindocs/views.py:80 +#: contrib/admindocs/views.py:82 msgid "tag:" msgstr "" diff --git a/django/contrib/gis/locale/en/LC_MESSAGES/django.po b/django/contrib/gis/locale/en/LC_MESSAGES/django.po index 997f5f440531..060b2a2ac401 100644 --- a/django/contrib/gis/locale/en/LC_MESSAGES/django.po +++ b/django/contrib/gis/locale/en/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: Django\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-10-09 17:42+0200\n" +"POT-Creation-Date: 2017-01-19 16:49+0100\n" "PO-Revision-Date: 2010-05-13 15:35+0200\n" "Last-Translator: Django team\n" "Language-Team: English \n" @@ -89,11 +89,7 @@ msgstr "" msgid "WKT debugging window:" msgstr "" -#: contrib/gis/templates/gis/google/google-map.html:4 -msgid "Google Maps via GeoDjango" -msgstr "" - -#: contrib/gis/templates/gis/openlayers.html:19 +#: contrib/gis/templates/gis/openlayers.html:13 msgid "Debugging window (serialized value)" msgstr "" diff --git a/django/contrib/postgres/locale/en/LC_MESSAGES/django.po b/django/contrib/postgres/locale/en/LC_MESSAGES/django.po index 2c0df915d694..0e00e7484b59 100644 --- a/django/contrib/postgres/locale/en/LC_MESSAGES/django.po +++ b/django/contrib/postgres/locale/en/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: Django\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-07-15 09:44+0200\n" +"POT-Creation-Date: 2017-01-19 16:49+0100\n" "PO-Revision-Date: 2015-01-18 20:56+0100\n" "Last-Translator: Django team\n" "Language-Team: English \n" @@ -28,13 +28,13 @@ msgstr "" msgid "Nested arrays must have the same length." msgstr "" -#: contrib/postgres/fields/hstore.py:15 -msgid "Map of strings to strings" +#: contrib/postgres/fields/hstore.py:16 +msgid "Map of strings to strings/nulls" msgstr "" #: contrib/postgres/fields/hstore.py:17 #, python-format -msgid "The value of \"%(key)s\" is not a string." +msgid "The value of \"%(key)s\" is not a string or null." msgstr "" #: contrib/postgres/fields/jsonb.py:15 From 4c5ed3e683576ece880ae99398a1e7d8c5829617 Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Thu, 19 Jan 2017 09:55:03 -0500 Subject: [PATCH 0074/3180] Refs #23919 -- Removed __nonzero__() methods (for Python 2). Thanks Tim for the review. --- django/contrib/auth/context_processors.py | 3 --- django/contrib/gis/measure.py | 3 --- django/core/files/base.py | 6 ------ django/db/models/query.py | 3 --- django/forms/formsets.py | 3 --- django/utils/datastructures.py | 3 --- django/utils/translation/__init__.py | 3 --- django/utils/tree.py | 3 --- tests/generic_relations_regress/models.py | 5 ++--- tests/generic_relations_regress/tests.py | 10 ++++++---- 10 files changed, 8 insertions(+), 34 deletions(-) diff --git a/django/contrib/auth/context_processors.py b/django/contrib/auth/context_processors.py index f865fc1b7d06..1938568401b0 100644 --- a/django/contrib/auth/context_processors.py +++ b/django/contrib/auth/context_processors.py @@ -20,9 +20,6 @@ def __iter__(self): def __bool__(self): return self.user.has_module_perms(self.app_label) - def __nonzero__(self): # Python 2 compatibility - return type(self).__bool__(self) - class PermWrapper: def __init__(self, user): diff --git a/django/contrib/gis/measure.py b/django/contrib/gis/measure.py index bc426b597b06..fa3d7c34f288 100644 --- a/django/contrib/gis/measure.py +++ b/django/contrib/gis/measure.py @@ -175,9 +175,6 @@ def __idiv__(self, other): # Python 2 compatibility def __bool__(self): return bool(self.standard) - def __nonzero__(self): # Python 2 compatibility - return type(self).__bool__(self) - def default_units(self, kwargs): """ Return the unit value and the default units specified diff --git a/django/core/files/base.py b/django/core/files/base.py index df29c94eee39..0834c56b8d6e 100644 --- a/django/core/files/base.py +++ b/django/core/files/base.py @@ -25,9 +25,6 @@ def __repr__(self): def __bool__(self): return bool(self.name) - def __nonzero__(self): # Python 2 compatibility - return type(self).__bool__(self) - def __len__(self): return self.size @@ -149,9 +146,6 @@ def __str__(self): def __bool__(self): return True - def __nonzero__(self): # Python 2 compatibility - return type(self).__bool__(self) - def open(self, mode=None): self.seek(0) diff --git a/django/db/models/query.py b/django/db/models/query.py index b536521fa44a..f4d56a269bf1 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -253,9 +253,6 @@ def __bool__(self): self._fetch_all() return bool(self._result_cache) - def __nonzero__(self): # Python 2 compatibility - return type(self).__bool__(self) - def __getitem__(self, k): """ Retrieves an item or slice from the set of results. diff --git a/django/forms/formsets.py b/django/forms/formsets.py index 18a8cabefaa0..1afb72fb85db 100644 --- a/django/forms/formsets.py +++ b/django/forms/formsets.py @@ -78,9 +78,6 @@ def __bool__(self): """All formsets have a management form which is not included in the length""" return True - def __nonzero__(self): # Python 2 compatibility - return type(self).__bool__(self) - @cached_property def management_form(self): """Returns the ManagementForm instance for this FormSet.""" diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py index a89af1780be5..a61a445ab01b 100644 --- a/django/utils/datastructures.py +++ b/django/utils/datastructures.py @@ -32,9 +32,6 @@ def __contains__(self, item): def __bool__(self): return bool(self.dict) - def __nonzero__(self): # Python 2 compatibility - return type(self).__bool__(self) - def __len__(self): return len(self.dict) diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py index 4dc4c16c283a..a8f3b751b44a 100644 --- a/django/utils/translation/__init__.py +++ b/django/utils/translation/__init__.py @@ -114,9 +114,6 @@ class NumberAwareString(resultclass): def __bool__(self): return bool(kwargs['singular']) - def __nonzero__(self): # Python 2 compatibility - return type(self).__bool__(self) - def __mod__(self, rhs): if isinstance(rhs, dict) and number: try: diff --git a/django/utils/tree.py b/django/utils/tree.py index 2c8ab3fe1c0d..5c86e73da8c2 100644 --- a/django/utils/tree.py +++ b/django/utils/tree.py @@ -71,9 +71,6 @@ def __bool__(self): """ return bool(self.children) - def __nonzero__(self): # Python 2 compatibility - return type(self).__bool__(self) - def __contains__(self, other): """ Returns True is 'other' is a direct child of this instance. diff --git a/tests/generic_relations_regress/models.py b/tests/generic_relations_regress/models.py index d9cf692b75d5..fae8aadaa50f 100644 --- a/tests/generic_relations_regress/models.py +++ b/tests/generic_relations_regress/models.py @@ -121,9 +121,8 @@ class Guild(models.Model): name = models.CharField(max_length=15) members = models.ManyToManyField(Developer) - def __nonzero__(self): - - return self.members.count() + def __bool__(self): + return False class Tag(models.Model): diff --git a/tests/generic_relations_regress/tests.py b/tests/generic_relations_regress/tests.py index d3986b6916df..0dac7040e451 100644 --- a/tests/generic_relations_regress/tests.py +++ b/tests/generic_relations_regress/tests.py @@ -119,10 +119,12 @@ def test_target_model_len_zero(self): note = Note(note='Deserve a bonus', content_object=team1) note.save() - def test_target_model_nonzero_false(self): - """Test related to #13085""" - # __nonzero__() returns False -- This actually doesn't currently fail. - # This test validates that + def test_target_model_bool_false(self): + """ + Saving a model with a GenericForeignKey to a model instance whose + __bool__ method returns False (Guild.__bool__() here) shouldn't fail + (#13085). + """ g1 = Guild.objects.create(name='First guild') note = Note(note='Note for guild', content_object=g1) note.save() From 41e0033caf1267edda2b780ae50a3881c3de94ef Mon Sep 17 00:00:00 2001 From: Chillar Anand Date: Thu, 19 Jan 2017 21:58:30 +0530 Subject: [PATCH 0075/3180] Refs #23919 -- Removed usage of django.utils.decorators.ContextDecorator. --- django/db/transaction.py | 3 ++- django/utils/decorators.py | 22 ++-------------------- django/utils/timezone.py | 2 +- django/utils/translation/__init__.py | 2 +- 4 files changed, 6 insertions(+), 23 deletions(-) diff --git a/django/db/transaction.py b/django/db/transaction.py index e392c13b329d..b83aaa644072 100644 --- a/django/db/transaction.py +++ b/django/db/transaction.py @@ -1,7 +1,8 @@ +from contextlib import ContextDecorator + from django.db import ( DEFAULT_DB_ALIAS, DatabaseError, Error, ProgrammingError, connections, ) -from django.utils.decorators import ContextDecorator class TransactionManagementError(ProgrammingError): diff --git a/django/utils/decorators.py b/django/utils/decorators.py index 3b2a002e7b01..a3af946b3350 100644 --- a/django/utils/decorators.py +++ b/django/utils/decorators.py @@ -1,10 +1,7 @@ "Functions that help with dynamically creating decorators for views." -try: - from contextlib import ContextDecorator -except ImportError: - ContextDecorator = None - +# For backwards compatibility in Django 2.0. +from contextlib import ContextDecorator # noqa from functools import WRAPPER_ASSIGNMENTS, update_wrapper, wraps @@ -166,21 +163,6 @@ def callback(response): return _make_decorator -if ContextDecorator is None: - # ContextDecorator was introduced in Python 3.2 - # See https://docs.python.org/3/library/contextlib.html#contextlib.ContextDecorator - class ContextDecorator: - """ - A base class that enables a context manager to also be used as a decorator. - """ - def __call__(self, func): - @wraps(func, assigned=available_attrs(func)) - def inner(*args, **kwargs): - with self: - return func(*args, **kwargs) - return inner - - class classproperty: def __init__(self, method=None): self.fget = method diff --git a/django/utils/timezone.py b/django/utils/timezone.py index 66bfa00030a8..bc6d60e228ce 100644 --- a/django/utils/timezone.py +++ b/django/utils/timezone.py @@ -3,13 +3,13 @@ """ import functools +from contextlib import ContextDecorator from datetime import datetime, timedelta, tzinfo from threading import local import pytz from django.conf import settings -from django.utils.decorators import ContextDecorator __all__ = [ 'utc', 'get_fixed_timezone', diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py index a8f3b751b44a..2c508572b854 100644 --- a/django/utils/translation/__init__.py +++ b/django/utils/translation/__init__.py @@ -3,8 +3,8 @@ """ import re import warnings +from contextlib import ContextDecorator -from django.utils.decorators import ContextDecorator from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_text from django.utils.functional import lazy From 9695b149820cff31cfa48973efe4256c80811e87 Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Thu, 19 Jan 2017 09:48:01 -0500 Subject: [PATCH 0076/3180] Refs #23919 -- Removed str() conversion of type and method __name__. --- django/core/servers/basehttp.py | 2 +- django/db/migrations/autodetector.py | 2 +- django/db/migrations/state.py | 4 ++-- django/db/models/fields/related.py | 4 ++-- django/db/models/fields/related_descriptors.py | 4 ++-- django/forms/formsets.py | 2 +- django/forms/models.py | 4 ++-- tests/apps/tests.py | 16 ++++++++-------- tests/auth_tests/test_hashers.py | 2 +- .../invalid_models_tests/test_relative_fields.py | 4 ++-- tests/migrations/test_state.py | 2 +- tests/migrations/test_writer.py | 10 +++++----- tests/model_forms/tests.py | 12 ++++++------ .../test_abstract_inheritance.py | 10 +++++----- tests/queryset_pickle/tests.py | 3 +-- tests/servers/tests.py | 2 +- tests/validation/test_unique.py | 2 +- 17 files changed, 42 insertions(+), 43 deletions(-) diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index 0b76b14f0466..b706f74ec859 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -161,7 +161,7 @@ def handle(self): def run(addr, port, wsgi_handler, ipv6=False, threading=False, server_cls=WSGIServer): server_address = (addr, port) if threading: - httpd_cls = type(str('WSGIServer'), (socketserver.ThreadingMixIn, server_cls), {}) + httpd_cls = type('WSGIServer', (socketserver.ThreadingMixIn, server_cls), {}) else: httpd_cls = server_cls httpd = httpd_cls(server_address, WSGIRequestHandler, ipv6=ipv6) diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py index b8ac6c942b0a..8818cb36a7d3 100644 --- a/django/db/migrations/autodetector.py +++ b/django/db/migrations/autodetector.py @@ -306,7 +306,7 @@ def _build_migration_list(self, graph=None): # Make a migration! Well, only if there's stuff to put in it if dependencies or chopped: if not self.generated_operations[app_label] or chop_mode: - subclass = type(str("Migration"), (Migration,), {"operations": [], "dependencies": []}) + subclass = type("Migration", (Migration,), {"operations": [], "dependencies": []}) instance = subclass("auto_%i" % (len(self.migrations.get(app_label, [])) + 1), app_label) instance.dependencies = list(dependencies) instance.operations = chopped diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index c0eb583374c0..d8b256018632 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -578,7 +578,7 @@ def render(self, apps): # First, make a Meta object meta_contents = {'app_label': self.app_label, "apps": apps} meta_contents.update(self.options) - meta = type(str("Meta"), tuple(), meta_contents) + meta = type("Meta", tuple(), meta_contents) # Then, work out our bases try: bases = tuple( @@ -595,7 +595,7 @@ def render(self, apps): # Restore managers body.update(self.construct_managers()) # Then, make a Model object (apps.register_model is called in __new__) - return type(str(self.name), bases, body) + return type(self.name, bases, body) def get_field_by_name(self, name): for fname, field in self.fields: diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index bc447452f3c8..855bf38ea075 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -1023,7 +1023,7 @@ def set_managed(model, related, through): to = 'to_%s' % to from_ = 'from_%s' % from_ - meta = type(str('Meta'), (), { + meta = type('Meta', (), { 'db_table': field._get_m2m_db_table(klass._meta), 'auto_created': klass, 'app_label': klass._meta.app_label, @@ -1034,7 +1034,7 @@ def set_managed(model, related, through): 'apps': field.model._meta.apps, }) # Construct and return the new class. - return type(str(name), (models.Model,), { + return type(name, (models.Model,), { 'Meta': meta, '__module__': klass.__module__, from_: models.ForeignKey( diff --git a/django/db/models/fields/related_descriptors.py b/django/db/models/fields/related_descriptors.py index dda455800b8d..a878a79acde1 100644 --- a/django/db/models/fields/related_descriptors.py +++ b/django/db/models/fields/related_descriptors.py @@ -94,7 +94,7 @@ def RelatedObjectDoesNotExist(self): # related model might not be resolved yet; `rel.model` might still be # a string model reference. return type( - str('RelatedObjectDoesNotExist'), + 'RelatedObjectDoesNotExist', (self.field.remote_field.model.DoesNotExist, AttributeError), {} ) @@ -297,7 +297,7 @@ def RelatedObjectDoesNotExist(self): # The exception isn't created at initialization time for the sake of # consistency with `ForwardManyToOneDescriptor`. return type( - str('RelatedObjectDoesNotExist'), + 'RelatedObjectDoesNotExist', (self.related.related_model.DoesNotExist, AttributeError), {} ) diff --git a/django/forms/formsets.py b/django/forms/formsets.py index 1afb72fb85db..8a830916f9e7 100644 --- a/django/forms/formsets.py +++ b/django/forms/formsets.py @@ -441,7 +441,7 @@ def formset_factory(form, formset=BaseFormSet, extra=1, can_order=False, 'min_num': min_num, 'max_num': max_num, 'absolute_max': absolute_max, 'validate_min': validate_min, 'validate_max': validate_max} - return type(form.__name__ + str('FormSet'), (formset,), attrs) + return type(form.__name__ + 'FormSet', (formset,), attrs) def all_valid(formsets): diff --git a/django/forms/models.py b/django/forms/models.py index e5a589bfbaaf..de1fb1e2bdd0 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -518,11 +518,11 @@ def modelform_factory(model, form=ModelForm, fields=None, exclude=None, # If parent form class already has an inner Meta, the Meta we're # creating needs to inherit from the parent's inner meta. bases = (form.Meta,) if hasattr(form, 'Meta') else () - Meta = type(str('Meta'), bases, attrs) + Meta = type('Meta', bases, attrs) if formfield_callback: Meta.formfield_callback = staticmethod(formfield_callback) # Give this new form class a reasonable name. - class_name = model.__name__ + str('Form') + class_name = model.__name__ + 'Form' # Class attributes for the new form class. form_class_attrs = { diff --git a/tests/apps/tests.py b/tests/apps/tests.py index e2706624361d..0263af897f39 100644 --- a/tests/apps/tests.py +++ b/tests/apps/tests.py @@ -197,10 +197,10 @@ def test_dynamic_load(self): 'app_label': "apps", 'apps': new_apps, } - meta = type(str("Meta"), tuple(), meta_contents) + meta = type("Meta", tuple(), meta_contents) body['Meta'] = meta body['__module__'] = TotallyNormal.__module__ - temp_model = type(str("SouthPonies"), (models.Model,), body) + temp_model = type("SouthPonies", (models.Model,), body) # Make sure it appeared in the right place! self.assertListEqual(list(apps.get_app_config("apps").get_models()), old_models) with self.assertRaises(LookupError): @@ -218,15 +218,15 @@ def test_model_clash(self): } body = {} - body['Meta'] = type(str("Meta"), tuple(), meta_contents) + body['Meta'] = type("Meta", tuple(), meta_contents) body['__module__'] = TotallyNormal.__module__ - type(str("SouthPonies"), (models.Model,), body) + type("SouthPonies", (models.Model,), body) # When __name__ and __module__ match we assume the module # was reloaded and issue a warning. This use-case is # useful for REPL. Refs #23621. body = {} - body['Meta'] = type(str("Meta"), tuple(), meta_contents) + body['Meta'] = type("Meta", tuple(), meta_contents) body['__module__'] = TotallyNormal.__module__ msg = ( "Model 'apps.southponies' was already registered. " @@ -234,15 +234,15 @@ def test_model_clash(self): "most notably with related models." ) with self.assertRaisesMessage(RuntimeWarning, msg): - type(str("SouthPonies"), (models.Model,), body) + type("SouthPonies", (models.Model,), body) # If it doesn't appear to be a reloaded module then we expect # a RuntimeError. body = {} - body['Meta'] = type(str("Meta"), tuple(), meta_contents) + body['Meta'] = type("Meta", tuple(), meta_contents) body['__module__'] = TotallyNormal.__module__ + '.whatever' with self.assertRaisesMessage(RuntimeError, "Conflicting 'southponies' models in application 'apps':"): - type(str("SouthPonies"), (models.Model,), body) + type("SouthPonies", (models.Model,), body) def test_get_containing_app_config_apps_not_ready(self): """ diff --git a/tests/auth_tests/test_hashers.py b/tests/auth_tests/test_hashers.py index 4b6aa8f7995b..59de85ad9f1d 100644 --- a/tests/auth_tests/test_hashers.py +++ b/tests/auth_tests/test_hashers.py @@ -429,7 +429,7 @@ def test_load_library_no_algorithm(self): self.assertEqual("Hasher 'BasePasswordHasher' doesn't specify a library attribute", str(e.exception)) def test_load_library_importerror(self): - PlainHasher = type(str('PlainHasher'), (BasePasswordHasher,), {'algorithm': 'plain', 'library': 'plain'}) + PlainHasher = type('PlainHasher', (BasePasswordHasher,), {'algorithm': 'plain', 'library': 'plain'}) # Python 3 adds quotes around module name msg = "Couldn't load 'PlainHasher' algorithm library: No module named '?plain'?" with self.assertRaisesRegex(ValueError, msg): diff --git a/tests/invalid_models_tests/test_relative_fields.py b/tests/invalid_models_tests/test_relative_fields.py index 384d1fa03e92..db677bd67083 100644 --- a/tests/invalid_models_tests/test_relative_fields.py +++ b/tests/invalid_models_tests/test_relative_fields.py @@ -661,7 +661,7 @@ class Parent(models.Model): pass for invalid_related_name in invalid_related_names: - Child = type(str('Child%s') % str(invalid_related_name), (models.Model,), { + Child = type('Child%s' % invalid_related_name, (models.Model,), { 'parent': models.ForeignKey('Parent', models.CASCADE, related_name=invalid_related_name), '__module__': Parent.__module__, }) @@ -700,7 +700,7 @@ class Parent(models.Model): pass for related_name in related_names: - Child = type(str('Child%s') % str(related_name), (models.Model,), { + Child = type('Child%s' % related_name, (models.Model,), { 'parent': models.ForeignKey('Parent', models.CASCADE, related_name=related_name), '__module__': Parent.__module__, }) diff --git a/tests/migrations/test_state.py b/tests/migrations/test_state.py index a6b027e079ee..badd45a5aaeb 100644 --- a/tests/migrations/test_state.py +++ b/tests/migrations/test_state.py @@ -1058,7 +1058,7 @@ def create_model(self, name, foreign_keys=[], bases=(), abstract=False, proxy=Fa 'apps': self.apps, 'proxy': proxy, } - meta = type(str("Meta"), tuple(), meta_contents) + meta = type("Meta", tuple(), meta_contents) if not bases: bases = (models.Model,) body = { diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index ff5e22ac5e1e..ab6280856a45 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -542,7 +542,7 @@ def test_simple_migration(self): 'verbose_name_plural': 'My models', } - migration = type(str("Migration"), (migrations.Migration,), { + migration = type("Migration", (migrations.Migration,), { "operations": [ migrations.CreateModel("MyModel", tuple(fields.items()), options, (models.Model,)), migrations.CreateModel("MyModel2", tuple(fields.items()), bases=(models.Model,)), @@ -593,7 +593,7 @@ def test_migration_path(self): self.assertEqual(writer.path, expected_path) def test_custom_operation(self): - migration = type(str("Migration"), (migrations.Migration,), { + migration = type("Migration", (migrations.Migration,), { "operations": [ custom_migration_operations.operations.TestOperation(), custom_migration_operations.operations.CreateModel(), @@ -615,7 +615,7 @@ def test_sorted_imports(self): """ #24155 - Tests ordering of imports. """ - migration = type(str("Migration"), (migrations.Migration,), { + migration = type("Migration", (migrations.Migration,), { "operations": [ migrations.AddField("mymodel", "myfield", models.DateTimeField( default=datetime.datetime(2012, 1, 1, 1, 1, tzinfo=utc), @@ -635,7 +635,7 @@ def test_migration_file_header_comments(self): """ Test comments at top of file. """ - migration = type(str("Migration"), (migrations.Migration,), { + migration = type("Migration", (migrations.Migration,), { "operations": [] }) dt = datetime.datetime(2015, 7, 31, 4, 40, 0, 0, tzinfo=utc) @@ -655,7 +655,7 @@ def test_models_import_omitted(self): """ django.db.models shouldn't be imported if unused. """ - migration = type(str("Migration"), (migrations.Migration,), { + migration = type("Migration", (migrations.Migration,), { "operations": [ migrations.AlterModelOptions( name='model', diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index da28fcc7d689..108c91758744 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -2731,12 +2731,12 @@ class Form2(forms.Form): foo = forms.IntegerField() self.assertEqual(list(ModelForm().fields.keys()), ['name']) - self.assertEqual(list(type(str('NewForm'), (Mixin, Form), {})().fields.keys()), []) - self.assertEqual(list(type(str('NewForm'), (Form2, Mixin, Form), {})().fields.keys()), ['foo']) - self.assertEqual(list(type(str('NewForm'), (Mixin, ModelForm, Form), {})().fields.keys()), ['name']) - self.assertEqual(list(type(str('NewForm'), (ModelForm, Mixin, Form), {})().fields.keys()), ['name']) - self.assertEqual(list(type(str('NewForm'), (ModelForm, Form, Mixin), {})().fields.keys()), ['name', 'age']) - self.assertEqual(list(type(str('NewForm'), (ModelForm, Form), {'age': None})().fields.keys()), ['name']) + self.assertEqual(list(type('NewForm', (Mixin, Form), {})().fields.keys()), []) + self.assertEqual(list(type('NewForm', (Form2, Mixin, Form), {})().fields.keys()), ['foo']) + self.assertEqual(list(type('NewForm', (Mixin, ModelForm, Form), {})().fields.keys()), ['name']) + self.assertEqual(list(type('NewForm', (ModelForm, Mixin, Form), {})().fields.keys()), ['name']) + self.assertEqual(list(type('NewForm', (ModelForm, Form, Mixin), {})().fields.keys()), ['name', 'age']) + self.assertEqual(list(type('NewForm', (ModelForm, Form), {'age': None})().fields.keys()), ['name']) def test_field_removal_name_clashes(self): """ diff --git a/tests/model_inheritance/test_abstract_inheritance.py b/tests/model_inheritance/test_abstract_inheritance.py index d74cae7a3bc7..4bd0654e46af 100644 --- a/tests/model_inheritance/test_abstract_inheritance.py +++ b/tests/model_inheritance/test_abstract_inheritance.py @@ -322,11 +322,11 @@ def fields(model): return list((f.name, f.__class__) for f in model._meta.get_fields()) model_dict = {'__module__': 'model_inheritance'} - model1 = type(str('Model1'), (AbstractModel, Mixin), model_dict.copy()) - model2 = type(str('Model2'), (Mixin2, AbstractModel), model_dict.copy()) - model3 = type(str('Model3'), (DescendantMixin, AbstractModel), model_dict.copy()) - model4 = type(str('Model4'), (Mixin2, Mixin, AbstractModel), model_dict.copy()) - model5 = type(str('Model5'), (Mixin2, ConcreteModel2, Mixin, AbstractModel), model_dict.copy()) + model1 = type('Model1', (AbstractModel, Mixin), model_dict.copy()) + model2 = type('Model2', (Mixin2, AbstractModel), model_dict.copy()) + model3 = type('Model3', (DescendantMixin, AbstractModel), model_dict.copy()) + model4 = type('Model4', (Mixin2, Mixin, AbstractModel), model_dict.copy()) + model5 = type('Model5', (Mixin2, ConcreteModel2, Mixin, AbstractModel), model_dict.copy()) self.assertEqual( fields(model1), diff --git a/tests/queryset_pickle/tests.py b/tests/queryset_pickle/tests.py index ac5174051ffd..61ffba6c0b5c 100644 --- a/tests/queryset_pickle/tests.py +++ b/tests/queryset_pickle/tests.py @@ -82,8 +82,7 @@ def test_model_pickle_m2m(self): def test_model_pickle_dynamic(self): class Meta: proxy = True - dynclass = type(str("DynamicEventSubclass"), (Event, ), - {'Meta': Meta, '__module__': Event.__module__}) + dynclass = type("DynamicEventSubclass", (Event, ), {'Meta': Meta, '__module__': Event.__module__}) original = dynclass(pk=1) dumped = pickle.dumps(original) reloaded = pickle.loads(dumped) diff --git a/tests/servers/tests.py b/tests/servers/tests.py index bf87306cce58..82c9bea49380 100644 --- a/tests/servers/tests.py +++ b/tests/servers/tests.py @@ -111,7 +111,7 @@ def test_port_bind(self): Each LiveServerTestCase binds to a unique port or fails to start a server thread when run concurrently (#26011). """ - TestCase = type(str("TestCase"), (LiveServerBase,), {}) + TestCase = type("TestCase", (LiveServerBase,), {}) try: TestCase.setUpClass() except socket.error as e: diff --git a/tests/validation/test_unique.py b/tests/validation/test_unique.py index 642154aaa706..11d06eeb4d85 100644 --- a/tests/validation/test_unique.py +++ b/tests/validation/test_unique.py @@ -53,7 +53,7 @@ class M(models.Model): bar = models.IntegerField() baz = models.IntegerField() - Meta = type(str('Meta'), (), { + Meta = type('Meta', (), { 'unique_together': unique_together, 'apps': Apps() }) From d4bb37593ed1cc0831404b6c5e8581e628d00f3b Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 19 Jan 2017 11:55:23 -0500 Subject: [PATCH 0077/3180] Refs #23919 -- Removed obsolete compare_digest() and pbkdf2() implementations. --- django/utils/crypto.py | 124 ++++------------------------------------- 1 file changed, 12 insertions(+), 112 deletions(-) diff --git a/django/utils/crypto.py b/django/utils/crypto.py index 74dd9fd7b087..e5ae2108f29e 100644 --- a/django/utils/crypto.py +++ b/django/utils/crypto.py @@ -1,11 +1,9 @@ """ Django's standard crypto functions and utilities. """ -import binascii import hashlib import hmac import random -import struct import time from django.conf import settings @@ -73,115 +71,17 @@ def get_random_string(length=12, return ''.join(random.choice(allowed_chars) for i in range(length)) -if hasattr(hmac, "compare_digest"): - # Prefer the stdlib implementation, when available. - def constant_time_compare(val1, val2): - return hmac.compare_digest(force_bytes(val1), force_bytes(val2)) -else: - def constant_time_compare(val1, val2): - """ - Returns True if the two strings are equal, False otherwise. +def constant_time_compare(val1, val2): + """Return True if the two strings are equal, False otherwise.""" + return hmac.compare_digest(force_bytes(val1), force_bytes(val2)) - The time taken is independent of the number of characters that match. - For the sake of simplicity, this function executes in constant time only - when the two strings have the same length. It short-circuits when they - have different lengths. Since Django only uses it to compare hashes of - known expected length, this is acceptable. - """ - if len(val1) != len(val2): - return False - result = 0 - if isinstance(val1, bytes) and isinstance(val2, bytes): - for x, y in zip(val1, val2): - result |= x ^ y - else: - for x, y in zip(val1, val2): - result |= ord(x) ^ ord(y) - return result == 0 - - -def _bin_to_long(x): - """ - Convert a binary string into a long integer - - This is a clever optimization for fast xor vector math - """ - return int(binascii.hexlify(x), 16) - - -def _long_to_bin(x, hex_format_string): - """ - Convert a long integer into a binary string. - hex_format_string is like "%020x" for padding 10 characters. - """ - return binascii.unhexlify((hex_format_string % x).encode('ascii')) - - -if hasattr(hashlib, "pbkdf2_hmac"): - def pbkdf2(password, salt, iterations, dklen=0, digest=None): - """ - Implements PBKDF2 with the same API as Django's existing - implementation, using the stdlib. - - This is used in Python 2.7.8+ and 3.4+. - """ - if digest is None: - digest = hashlib.sha256 - if not dklen: - dklen = None - password = force_bytes(password) - salt = force_bytes(salt) - return hashlib.pbkdf2_hmac( - digest().name, password, salt, iterations, dklen) -else: - def pbkdf2(password, salt, iterations, dklen=0, digest=None): - """ - Implements PBKDF2 as defined in RFC 2898, section 5.2 - - HMAC+SHA256 is used as the default pseudo random function. - - As of 2014, 100,000 iterations was the recommended default which took - 100ms on a 2.7Ghz Intel i7 with an optimized implementation. This is - probably the bare minimum for security given 1000 iterations was - recommended in 2001. This code is very well optimized for CPython and - is about five times slower than OpenSSL's implementation. Look in - django.contrib.auth.hashers for the present default, it is lower than - the recommended 100,000 because of the performance difference between - this and an optimized implementation. - """ - assert iterations > 0 - if not digest: - digest = hashlib.sha256 - password = force_bytes(password) - salt = force_bytes(salt) - hlen = digest().digest_size - if not dklen: - dklen = hlen - if dklen > (2 ** 32 - 1) * hlen: - raise OverflowError('dklen too big') - L = -(-dklen // hlen) - r = dklen - (L - 1) * hlen - - hex_format_string = "%%0%ix" % (hlen * 2) - - inner, outer = digest(), digest() - if len(password) > inner.block_size: - password = digest(password).digest() - password += b'\x00' * (inner.block_size - len(password)) - inner.update(password.translate(hmac.trans_36)) - outer.update(password.translate(hmac.trans_5C)) - - def F(i): - u = salt + struct.pack(b'>I', i) - result = 0 - for j in range(int(iterations)): - dig1, dig2 = inner.copy(), outer.copy() - dig1.update(u) - dig2.update(dig1.digest()) - u = dig2.digest() - result ^= _bin_to_long(u) - return _long_to_bin(result, hex_format_string) - - T = [F(x) for x in range(1, L)] - return b''.join(T) + F(L)[:r] +def pbkdf2(password, salt, iterations, dklen=0, digest=None): + """Return the hash of password using pbkdf2.""" + if digest is None: + digest = hashlib.sha256 + if not dklen: + dklen = None + password = force_bytes(password) + salt = force_bytes(salt) + return hashlib.pbkdf2_hmac(digest().name, password, salt, iterations, dklen) From 9e917cc29181ad32abc21488ee70e739ce805f3a Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 19 Jan 2017 12:58:19 -0500 Subject: [PATCH 0078/3180] Fixed #23905, refs #23919 -- Used make_msgid() from stdlib. --- django/core/mail/message.py | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/django/core/mail/message.py b/django/core/mail/message.py index f8fd6c2d2527..228084f2d1e6 100644 --- a/django/core/mail/message.py +++ b/django/core/mail/message.py @@ -1,7 +1,5 @@ import mimetypes import os -import random -import time from email import ( charset as Charset, encoders as Encoders, generator, message_from_string, ) @@ -13,7 +11,7 @@ from email.mime.message import MIMEMessage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText -from email.utils import formatdate, getaddresses, parseaddr +from email.utils import formatdate, getaddresses, make_msgid, parseaddr from io import BytesIO, StringIO from django.conf import settings @@ -38,35 +36,6 @@ class BadHeaderError(ValueError): pass -# Copied from Python 3.2+ standard library, with the following modifications: -# * Used cached hostname for performance. -# TODO: replace with email.utils.make_msgid(.., domain=DNS_NAME) when dropping -# Python 2 (Python 2's version doesn't have domain parameter) (#23905). -def make_msgid(idstring=None, domain=None): - """Returns a string suitable for RFC 5322 compliant Message-ID, e.g: - - <20020201195627.33539.96671@nightshade.la.mastaler.com> - - Optional idstring if given is a string used to strengthen the - uniqueness of the message id. Optional domain if given provides the - portion of the message id after the '@'. It defaults to the locally - defined hostname. - """ - timeval = time.time() - utcdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(timeval)) - pid = os.getpid() - randint = random.randrange(100000) - if idstring is None: - idstring = '' - else: - idstring = '.' + idstring - if domain is None: - # stdlib uses socket.getfqdn() here instead - domain = DNS_NAME - msgid = '<%s.%s.%s%s@%s>' % (utcdate, pid, randint, idstring, domain) - return msgid - - # Header names that contain structured address data (RFC #5322) ADDRESS_HEADERS = { 'from', From 9d27478958b50f2f689a103e39bf998fe7486675 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 19 Jan 2017 13:19:26 -0500 Subject: [PATCH 0079/3180] Refs #23919 -- Removed docs references to long integers. --- django/contrib/admin/templatetags/admin_list.py | 2 +- docs/intro/tutorial02.txt | 5 +---- docs/ref/forms/fields.txt | 2 +- docs/ref/models/querysets.txt | 5 ----- docs/topics/migrations.txt | 2 +- 5 files changed, 4 insertions(+), 12 deletions(-) diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index ec4356f5467f..c9dd6d7d30a1 100644 --- a/django/contrib/admin/templatetags/admin_list.py +++ b/django/contrib/admin/templatetags/admin_list.py @@ -251,7 +251,7 @@ def link_in_col(is_first, field_name, cl): else: url = add_preserved_filters({'preserved_filters': cl.preserved_filters, 'opts': cl.opts}, url) # Convert the pk to something that can be used in Javascript. - # Problem cases are long ints (23L) and non-ASCII strings. + # Problem cases are non-ASCII strings. if cl.to_field: attr = str(cl.to_field) else: diff --git a/docs/intro/tutorial02.txt b/docs/intro/tutorial02.txt index f7bf85030948..48e4ac7e7dc0 100644 --- a/docs/intro/tutorial02.txt +++ b/docs/intro/tutorial02.txt @@ -421,10 +421,7 @@ Once you're in the shell, explore the :doc:`database API `:: # Save the object into the database. You have to call save() explicitly. >>> q.save() - # Now it has an ID. Note that this might say "1L" instead of "1", depending - # on which database you're using. That's no biggie; it just means your - # database backend prefers to return integers as Python long integer - # objects. + # Now it has an ID. >>> q.id 1 diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt index 2008e65b9572..b135532b2d7f 100644 --- a/docs/ref/forms/fields.txt +++ b/docs/ref/forms/fields.txt @@ -722,7 +722,7 @@ For each field, we describe the default widget used if you don't specify * Default widget: :class:`NumberInput` when :attr:`Field.localize` is ``False``, else :class:`TextInput`. * Empty value: ``None`` - * Normalizes to: A Python integer or long integer. + * Normalizes to: A Python integer. * Validates that the given value is an integer. Leading and trailing whitespace is allowed, as in Python's ``int()`` function. * Error message keys: ``required``, ``invalid``, ``max_value``, diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index 18e81a7da83d..2893c91b8ea2 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -1974,11 +1974,6 @@ should always use ``count()`` rather than loading all of the record into Python objects and calling ``len()`` on the result (unless you need to load the objects into memory anyway, in which case ``len()`` will be faster). -Depending on which database you're using (e.g. PostgreSQL vs. MySQL), -``count()`` may return a long integer instead of a normal Python integer. This -is an underlying implementation quirk that shouldn't pose any real-world -problems. - Note that if you want the number of items in a ``QuerySet`` and are also retrieving model instances from it (for example, by iterating over it), it's probably more efficient to use ``len(queryset)`` which won't cause an extra diff --git a/docs/topics/migrations.txt b/docs/topics/migrations.txt index 3910d3132152..5b872cb58413 100644 --- a/docs/topics/migrations.txt +++ b/docs/topics/migrations.txt @@ -653,7 +653,7 @@ for basic values, and doesn't specify import paths). Django can serialize the following: -- ``int``, ``long``, ``float``, ``bool``, ``str``, ``unicode``, ``bytes``, ``None`` +- ``int``, ``float``, ``bool``, ``str``, ``unicode``, ``bytes``, ``None`` - ``list``, ``set``, ``tuple``, ``dict`` - ``datetime.date``, ``datetime.time``, and ``datetime.datetime`` instances (include those that are timezone-aware) From d29fd3f9a63f1e515fa8ed863b08a5389938b05f Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 19 Jan 2017 13:21:54 -0500 Subject: [PATCH 0080/3180] Fixed django/utils/http.py comment typo. --- django/utils/http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django/utils/http.py b/django/utils/http.py index ae23eec06ab6..579185681319 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -185,7 +185,7 @@ def base36_to_int(s): input won't fit into an int. """ # To prevent overconsumption of server resources, reject any - # base36 string that is long than 13 base36 digits (13 digits + # base36 string that is longer than 13 base36 digits (13 digits # is sufficient to base36-encode any 64-bit integer) if len(s) > 13: raise ValueError("Base36 input too large") From 9ee47ce7b45eaf1a9313f8c1680649a68cbb5681 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 19 Jan 2017 13:55:20 -0500 Subject: [PATCH 0081/3180] Refs #23919 -- Removed enum ImportError handling for Python 2. --- django/db/migrations/serializer.py | 9 ++------- django/db/migrations/writer.py | 6 ------ tests/migrations/test_writer.py | 8 +------- 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index 9e5d74afb964..eff3ebe0d708 100644 --- a/django/db/migrations/serializer.py +++ b/django/db/migrations/serializer.py @@ -2,6 +2,7 @@ import collections import datetime import decimal +import enum import functools import math import types @@ -17,12 +18,6 @@ from django.utils.timezone import utc from django.utils.version import get_docs_version -try: - import enum -except ImportError: - # No support on Python 2 if enum34 isn't installed. - enum = None - class BaseSerializer: def __init__(self, value): @@ -349,7 +344,7 @@ def serializer_factory(value): return TupleSerializer(value) if isinstance(value, dict): return DictionarySerializer(value) - if enum and isinstance(value, enum.Enum): + if isinstance(value, enum.Enum): return EnumSerializer(value) if isinstance(value, datetime.datetime): return DatetimeSerializer(value) diff --git a/django/db/migrations/writer.py b/django/db/migrations/writer.py index be0fece25e99..5a3378fe4b37 100644 --- a/django/db/migrations/writer.py +++ b/django/db/migrations/writer.py @@ -13,12 +13,6 @@ from django.utils.module_loading import module_dir from django.utils.timezone import now -try: - import enum -except ImportError: - # No support on Python 2 if enum34 isn't installed. - enum = None - class SettingsReference(str): """ diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index ab6280856a45..a51842e02d37 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -1,12 +1,12 @@ import datetime import decimal +import enum import functools import math import os import re import sys import tokenize -import unittest import uuid from io import StringIO @@ -31,11 +31,6 @@ from .models import FoodManager, FoodQuerySet -try: - import enum -except ImportError: - enum = None - PY36 = sys.version_info >= (3, 6) @@ -259,7 +254,6 @@ def test_serialize_lazy_objects(self): lazy_pattern = SimpleLazyObject(lambda: pattern) self.assertEqual(self.serialize_round_trip(lazy_pattern), pattern) - @unittest.skipUnless(enum, "enum34 is required on Python 2") def test_serialize_enums(self): class TextEnum(enum.Enum): A = 'a-value' From eb0b921c29ace8643a5a4cd136c433727c53dead Mon Sep 17 00:00:00 2001 From: Srinivas Reddy Thatiparthy Date: Thu, 19 Jan 2017 23:46:22 +0530 Subject: [PATCH 0082/3180] Refs #23919 -- Removed SessionBase.iterkeys(), itervalues(), iteritems(). These methods only work on Python 2. --- django/contrib/sessions/backends/base.py | 9 --------- tests/sessions_tests/tests.py | 20 +++++--------------- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/django/contrib/sessions/backends/base.py b/django/contrib/sessions/backends/base.py index 009efe94e1ff..e50db0c07f5b 100644 --- a/django/contrib/sessions/backends/base.py +++ b/django/contrib/sessions/backends/base.py @@ -131,15 +131,6 @@ def values(self): def items(self): return self._session.items() - def iterkeys(self): - return self._session.iterkeys() - - def itervalues(self): - return self._session.itervalues() - - def iteritems(self): - return self._session.iteritems() - def clear(self): # To avoid unnecessary persistent storage accesses, we set up the # internals directly (loading data wastes time, since we are going to diff --git a/tests/sessions_tests/tests.py b/tests/sessions_tests/tests.py index d4a486b90e73..177903b18fe5 100644 --- a/tests/sessions_tests/tests.py +++ b/tests/sessions_tests/tests.py @@ -116,37 +116,27 @@ def test_values(self): self.assertEqual(list(self.session.values()), []) self.assertTrue(self.session.accessed) self.session['some key'] = 1 - self.assertEqual(list(self.session.values()), [1]) - - def test_iterkeys(self): - self.session['x'] = 1 self.session.modified = False self.session.accessed = False - i = iter(self.session.keys()) - self.assertTrue(hasattr(i, '__iter__')) + self.assertEqual(list(self.session.values()), [1]) self.assertTrue(self.session.accessed) self.assertFalse(self.session.modified) - self.assertEqual(list(i), ['x']) - def test_itervalues(self): + def test_keys(self): self.session['x'] = 1 self.session.modified = False self.session.accessed = False - i = iter(self.session.values()) - self.assertTrue(hasattr(i, '__iter__')) + self.assertEqual(list(self.session.keys()), ['x']) self.assertTrue(self.session.accessed) self.assertFalse(self.session.modified) - self.assertEqual(list(i), [1]) - def test_iteritems(self): + def test_items(self): self.session['x'] = 1 self.session.modified = False self.session.accessed = False - i = iter(self.session.items()) - self.assertTrue(hasattr(i, '__iter__')) + self.assertEqual(list(self.session.items()), [('x', 1)]) self.assertTrue(self.session.accessed) self.assertFalse(self.session.modified) - self.assertEqual(list(i), [('x', 1)]) def test_clear(self): self.session['x'] = 1 From fedda6d9bdbb7624ae36a791ef91aeca9ba6ab8d Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 19 Jan 2017 20:06:03 -0500 Subject: [PATCH 0083/3180] Refs #23919 -- Removed Python 2 version check in django.http.cookie. --- django/http/cookie.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/django/http/cookie.py b/django/http/cookie.py index f45ef11295ac..fb0a7786ef95 100644 --- a/django/http/cookie.py +++ b/django/http/cookie.py @@ -1,28 +1,20 @@ import sys from http import cookies -# Cookie pickling bug is fixed in Python 2.7.9 and Python 3.4.3+ +# Cookie pickling bug is fixed in Python 3.4.3+ # http://bugs.python.org/issue22775 -cookie_pickles_properly = ( - (sys.version_info[:2] == (2, 7) and sys.version_info >= (2, 7, 9)) or - sys.version_info >= (3, 4, 3) -) - -if cookie_pickles_properly: +if sys.version_info >= (3, 4, 3): SimpleCookie = cookies.SimpleCookie else: Morsel = cookies.Morsel class SimpleCookie(cookies.SimpleCookie): - if not cookie_pickles_properly: - def __setitem__(self, key, value): - # Apply the fix from http://bugs.python.org/issue22775 where - # it's not fixed in Python itself - if isinstance(value, Morsel): - # allow assignment of constructed Morsels (e.g. for pickling) - dict.__setitem__(self, key, value) - else: - super(SimpleCookie, self).__setitem__(key, value) + def __setitem__(self, key, value): + if isinstance(value, Morsel): + # allow assignment of constructed Morsels (e.g. for pickling) + dict.__setitem__(self, key, value) + else: + super(SimpleCookie, self).__setitem__(key, value) def parse_cookie(cookie): From bf1c9570270b46e9e92b256fb9be394258029bbf Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Fri, 20 Jan 2017 04:20:14 +0100 Subject: [PATCH 0084/3180] Refs #23919 -- Removed Python 2 workaround for hashing Oracle params (refs #27632). --- django/db/backends/oracle/base.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 7e3591f60ca8..8d6b48e52a64 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -443,17 +443,12 @@ def _fix_for_params(self, query, params, unify_by_values=False): # values. It can be used only in single query execute() because # executemany() shares the formatted query with each of the params # list. e.g. for input params = [0.75, 2, 0.75, 'sth', 0.75] - # params_dict = { - # (2, ): ':arg2', - # (0.75, ): ':arg1', - # ('sth', ): ':arg0', - # } + # params_dict = {0.75: ':arg0', 2: ':arg1', 'sth': ':arg2'} # args = [':arg0', ':arg1', ':arg0', ':arg2', ':arg0'] # params = {':arg0': 0.75, ':arg1': 2, ':arg2': 'sth'} - params = [(param, type(param)) for param in params] params_dict = {param: ':arg%d' % i for i, param in enumerate(set(params))} args = [params_dict[param] for param in params] - params = {value: key[0] for key, value in params_dict.items()} + params = {value: key for key, value in params_dict.items()} query = query % tuple(args) else: # Handle params as sequence From dc8834cad41aa407f402dc54788df3cd37ab3e22 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Wed, 11 Jan 2017 23:17:25 +0100 Subject: [PATCH 0085/3180] Refs #23919 -- Removed unneeded force_str calls --- django/contrib/admin/utils.py | 7 ++--- django/contrib/auth/hashers.py | 6 ++-- .../management/commands/changepassword.py | 3 +- .../management/commands/createsuperuser.py | 11 ++++--- django/core/cache/backends/memcached.py | 5 ---- django/core/checks/messages.py | 4 +-- django/core/files/base.py | 4 +-- django/core/files/uploadedfile.py | 4 +-- django/core/handlers/wsgi.py | 9 ++---- django/core/mail/backends/smtp.py | 3 +- django/core/management/base.py | 10 +++---- .../core/management/commands/makemessages.py | 6 ++-- django/core/signing.py | 17 ++++------- django/db/backends/mysql/base.py | 3 +- django/db/backends/postgresql/base.py | 3 +- django/db/models/base.py | 4 +-- django/db/models/fields/files.py | 4 +-- django/forms/fields.py | 8 ++--- django/forms/widgets.py | 4 +-- django/http/request.py | 10 ++----- django/http/response.py | 5 +--- django/template/base.py | 5 ++-- django/test/client.py | 10 +++---- django/test/utils.py | 3 +- django/urls/resolvers.py | 4 +-- django/utils/formats.py | 8 ++--- django/utils/html.py | 6 ++-- django/utils/tree.py | 6 ++-- django/views/debug.py | 4 +-- django/views/generic/dates.py | 4 +-- tests/admin_scripts/tests.py | 2 +- tests/admin_utils/tests.py | 6 +--- tests/auth_tests/test_management.py | 3 +- tests/contenttypes_tests/tests.py | 4 +-- tests/dbshell/test_postgresql_psycopg2.py | 30 +++++++------------ tests/file_uploads/views.py | 6 ++-- tests/generic_views/test_list.py | 3 +- tests/handlers/tests.py | 6 +--- tests/httpwrappers/tests.py | 10 ++----- tests/middleware/tests.py | 3 +- tests/migrations/test_writer.py | 3 +- tests/or_lookups/tests.py | 5 ++-- tests/requests/tests.py | 3 +- tests/signing/tests.py | 3 +- 44 files changed, 100 insertions(+), 167 deletions(-) diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py index 297796254df1..c55173d6c9e6 100644 --- a/django/contrib/admin/utils.py +++ b/django/contrib/admin/utils.py @@ -11,7 +11,7 @@ from django.forms.utils import pretty_name from django.urls import NoReverseMatch, reverse from django.utils import formats, timezone -from django.utils.encoding import force_str, force_text, smart_text +from django.utils.encoding import force_text, smart_text from django.utils.html import format_html from django.utils.text import capfirst from django.utils.translation import ( @@ -340,12 +340,9 @@ def label_for_field(name, model, model_admin=None, return_attr=False): # field is likely a ForeignObjectRel label = field.related_model._meta.verbose_name except FieldDoesNotExist: - if name == "__unicode__": + if name == "__str__": label = force_text(model._meta.verbose_name) attr = str - elif name == "__str__": - label = force_str(model._meta.verbose_name) - attr = bytes else: if callable(name): attr = name diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py index 0446cf501f04..c52f31db59ab 100644 --- a/django/contrib/auth/hashers.py +++ b/django/contrib/auth/hashers.py @@ -13,7 +13,7 @@ from django.utils.crypto import ( constant_time_compare, get_random_string, pbkdf2, ) -from django.utils.encoding import force_bytes, force_str, force_text +from django.utils.encoding import force_bytes, force_text from django.utils.module_loading import import_string from django.utils.translation import ugettext_noop as _ @@ -627,7 +627,7 @@ def salt(self): def encode(self, password, salt): crypt = self._load_library() assert len(salt) == 2 - data = crypt.crypt(force_str(password), salt) + data = crypt.crypt(password, salt) assert data is not None # A platform like OpenBSD with a dummy crypt module. # we don't need to store the salt, but Django used to do this return "%s$%s$%s" % (self.algorithm, '', data) @@ -636,7 +636,7 @@ def verify(self, password, encoded): crypt = self._load_library() algorithm, salt, data = encoded.split('$', 2) assert algorithm == self.algorithm - return constant_time_compare(data, crypt.crypt(force_str(password), data)) + return constant_time_compare(data, crypt.crypt(password, data)) def safe_summary(self, encoded): algorithm, salt, data = encoded.split('$', 2) diff --git a/django/contrib/auth/management/commands/changepassword.py b/django/contrib/auth/management/commands/changepassword.py index c0c4ce3c6112..f4ec15a43901 100644 --- a/django/contrib/auth/management/commands/changepassword.py +++ b/django/contrib/auth/management/commands/changepassword.py @@ -5,7 +5,6 @@ from django.core.exceptions import ValidationError from django.core.management.base import BaseCommand, CommandError from django.db import DEFAULT_DB_ALIAS -from django.utils.encoding import force_str UserModel = get_user_model() @@ -16,7 +15,7 @@ class Command(BaseCommand): requires_system_checks = False def _get_pass(self, prompt="Password: "): - p = getpass.getpass(prompt=force_str(prompt)) + p = getpass.getpass(prompt=prompt) if not p: raise CommandError("aborted") return p diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py index 7a6d0b023156..d9fd70b6f1e1 100644 --- a/django/contrib/auth/management/commands/createsuperuser.py +++ b/django/contrib/auth/management/commands/createsuperuser.py @@ -10,7 +10,6 @@ from django.core import exceptions from django.core.management.base import BaseCommand, CommandError from django.db import DEFAULT_DB_ALIAS -from django.utils.encoding import force_str from django.utils.text import capfirst @@ -103,12 +102,12 @@ def handle(self, *args, **options): if default_username: input_msg += " (leave blank to use '%s')" % default_username username_rel = self.username_field.remote_field - input_msg = force_str('%s%s: ' % ( + input_msg = '%s%s: ' % ( input_msg, ' (%s.%s)' % ( username_rel.model._meta.object_name, username_rel.field_name - ) if username_rel else '') + ) if username_rel else '' ) username = self.get_input_data(self.username_field, input_msg, default_username) if not username: @@ -126,13 +125,13 @@ def handle(self, *args, **options): field = self.UserModel._meta.get_field(field_name) user_data[field_name] = options[field_name] while user_data[field_name] is None: - message = force_str('%s%s: ' % ( + message = '%s%s: ' % ( capfirst(field.verbose_name), ' (%s.%s)' % ( field.remote_field.model._meta.object_name, field.remote_field.field_name, ) if field.remote_field else '', - )) + ) input_value = self.get_input_data(field, message) user_data[field_name] = input_value fake_user_data[field_name] = input_value @@ -144,7 +143,7 @@ def handle(self, *args, **options): # Get a password while password is None: password = getpass.getpass() - password2 = getpass.getpass(force_str('Password (again): ')) + password2 = getpass.getpass('Password (again): ') if password != password2: self.stderr.write("Error: Your passwords didn't match.") password = None diff --git a/django/core/cache/backends/memcached.py b/django/core/cache/backends/memcached.py index 82589a82b087..29bd2a95cdde 100644 --- a/django/core/cache/backends/memcached.py +++ b/django/core/cache/backends/memcached.py @@ -7,7 +7,6 @@ from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache from django.utils.deprecation import RemovedInDjango21Warning -from django.utils.encoding import force_str from django.utils.functional import cached_property @@ -65,10 +64,6 @@ def get_backend_timeout(self, timeout=DEFAULT_TIMEOUT): timeout += int(time.time()) return int(timeout) - def make_key(self, key, version=None): - # Python 2 memcache requires the key to be a byte string. - return force_str(super(BaseMemcachedCache, self).make_key(key, version)) - def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None): key = self.make_key(key, version=version) return self._cache.add(key, value, self.get_backend_timeout(timeout)) diff --git a/django/core/checks/messages.py b/django/core/checks/messages.py index 0c44d350959d..bb0e2b335c20 100644 --- a/django/core/checks/messages.py +++ b/django/core/checks/messages.py @@ -1,4 +1,4 @@ -from django.utils.encoding import force_str +from django.utils.encoding import force_text # Levels DEBUG = 10 @@ -35,7 +35,7 @@ def __str__(self): # method doesn't return "applabel.modellabel" and cannot be changed. obj = self.obj._meta.label else: - obj = force_str(self.obj) + obj = force_text(self.obj) id = "(%s) " % self.id if self.id else "" hint = "\n\tHINT: %s" % self.hint if self.hint else '' return "%s: %s%s%s" % (obj, id, self.msg, hint) diff --git a/django/core/files/base.py b/django/core/files/base.py index 0834c56b8d6e..225c6dd3494e 100644 --- a/django/core/files/base.py +++ b/django/core/files/base.py @@ -2,7 +2,7 @@ from io import BytesIO, StringIO, UnsupportedOperation from django.core.files.utils import FileProxyMixin -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text class File(FileProxyMixin): @@ -20,7 +20,7 @@ def __str__(self): return force_text(self.name or '') def __repr__(self): - return force_str("<%s: %s>" % (self.__class__.__name__, self or "None")) + return "<%s: %s>" % (self.__class__.__name__, self or "None") def __bool__(self): return bool(self.name) diff --git a/django/core/files/uploadedfile.py b/django/core/files/uploadedfile.py index 6f71fc3b95ff..aa1038ae783e 100644 --- a/django/core/files/uploadedfile.py +++ b/django/core/files/uploadedfile.py @@ -9,7 +9,6 @@ from django.conf import settings from django.core.files import temp as tempfile from django.core.files.base import File -from django.utils.encoding import force_str __all__ = ('UploadedFile', 'TemporaryUploadedFile', 'InMemoryUploadedFile', 'SimpleUploadedFile') @@ -33,8 +32,7 @@ def __init__(self, file=None, name=None, content_type=None, size=None, charset=N self.content_type_extra = content_type_extra def __repr__(self): - return force_str("<%s: %s (%s)>" % ( - self.__class__.__name__, self.name, self.content_type)) + return "<%s: %s (%s)>" % (self.__class__.__name__, self.name, self.content_type) def _get_name(self): return self._name diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index 69b5f1c54d3d..c61dae1dfa07 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -8,13 +8,10 @@ from django.core import signals from django.core.handlers import base from django.urls import set_script_prefix -from django.utils.encoding import ( - force_str, force_text, repercent_broken_unicode, -) +from django.utils.encoding import force_text, repercent_broken_unicode from django.utils.functional import cached_property -# encode() and decode() expect the charset to be a native string. -ISO_8859_1, UTF_8 = str('iso-8859-1'), str('utf-8') +ISO_8859_1, UTF_8 = 'iso-8859-1', 'utf-8' _slashes_re = re.compile(br'/+') @@ -159,7 +156,7 @@ def __call__(self, environ, start_response): response_headers = [(str(k), str(v)) for k, v in response.items()] for c in response.cookies.values(): response_headers.append((str('Set-Cookie'), str(c.output(header='')))) - start_response(force_str(status), response_headers) + start_response(status, response_headers) if getattr(response, 'file_to_stream', None) is not None and environ.get('wsgi.file_wrapper'): response = environ['wsgi.file_wrapper'](response.file_to_stream) return response diff --git a/django/core/mail/backends/smtp.py b/django/core/mail/backends/smtp.py index dbff399d8c21..b6d5c2fed38d 100644 --- a/django/core/mail/backends/smtp.py +++ b/django/core/mail/backends/smtp.py @@ -8,7 +8,6 @@ from django.core.mail.backends.base import BaseEmailBackend from django.core.mail.message import sanitize_address from django.core.mail.utils import DNS_NAME -from django.utils.encoding import force_str class EmailBackend(BaseEmailBackend): @@ -68,7 +67,7 @@ def open(self): if not self.use_ssl and self.use_tls: self.connection.starttls(keyfile=self.ssl_keyfile, certfile=self.ssl_certfile) if self.username and self.password: - self.connection.login(force_str(self.username), force_str(self.password)) + self.connection.login(self.username, self.password) return True except (smtplib.SMTPException, socket.error): if not self.fail_silently: diff --git a/django/core/management/base.py b/django/core/management/base.py index ae8c6731c960..80f7e0a5756a 100644 --- a/django/core/management/base.py +++ b/django/core/management/base.py @@ -5,6 +5,7 @@ import os import sys from argparse import ArgumentParser +from io import TextIOBase import django from django.core import checks @@ -12,7 +13,6 @@ from django.core.management.color import color_style, no_style from django.db import DEFAULT_DB_ALIAS, connections from django.db.migrations.exceptions import MigrationSchemaMissing -from django.utils.encoding import force_str class CommandError(Exception): @@ -73,7 +73,7 @@ def handle_default_options(options): sys.path.insert(0, options.pythonpath) -class OutputWrapper: +class OutputWrapper(TextIOBase): """ Wrapper around stdout/stderr """ @@ -104,7 +104,7 @@ def write(self, msg, style_func=None, ending=None): if ending and not msg.endswith(ending): msg += ending style_func = style_func or self.style_func - self._out.write(force_str(style_func(msg))) + self._out.write(style_func(msg)) class BaseCommand: @@ -377,9 +377,9 @@ def check(self, app_configs=None, tags=None, display_num_errors=False, if issues: visible_issue_count += len(issues) formatted = ( - self.style.ERROR(force_str(e)) + self.style.ERROR(str(e)) if e.is_serious() - else self.style.WARNING(force_str(e)) + else self.style.WARNING(str(e)) for e in issues) formatted = "\n".join(sorted(formatted)) body += '\n%s:\n%s\n' % (group_name, formatted) diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py index 830b6efe05ef..48ed70845abc 100644 --- a/django/core/management/commands/makemessages.py +++ b/django/core/management/commands/makemessages.py @@ -15,7 +15,7 @@ find_command, handle_extensions, popen_wrapper, ) from django.utils._os import upath -from django.utils.encoding import DEFAULT_LOCALE_ENCODING, force_str +from django.utils.encoding import DEFAULT_LOCALE_ENCODING from django.utils.functional import cached_property from django.utils.jslex import prepare_js_for_gettext from django.utils.text import get_text_list @@ -557,7 +557,7 @@ def process_locale_dir(self, locale_dir, files): input_files = [bf.work_path for bf in build_files] with NamedTemporaryFile(mode='w+') as input_files_list: - input_files_list.write(force_str('\n'.join(input_files), encoding=DEFAULT_LOCALE_ENCODING)) + input_files_list.write(('\n'.join(input_files))) input_files_list.flush() args.extend(['--files-from', input_files_list.name]) args.extend(self.xgettext_options) @@ -649,7 +649,7 @@ def copy_plural_forms(self, msgs, locale): with open(django_po, 'r', encoding='utf-8') as fp: m = plural_forms_re.search(fp.read()) if m: - plural_form_line = force_str(m.group('value')) + plural_form_line = m.group('value') if self.verbosity > 1: self.stdout.write("copying plural forms: %s\n" % plural_form_line) lines = [] diff --git a/django/core/signing.py b/django/core/signing.py index 811d23396fc2..b6bb7492471a 100644 --- a/django/core/signing.py +++ b/django/core/signing.py @@ -43,7 +43,7 @@ from django.conf import settings from django.utils import baseconv from django.utils.crypto import constant_time_compare, salted_hmac -from django.utils.encoding import force_bytes, force_str, force_text +from django.utils.encoding import force_bytes, force_text from django.utils.module_loading import import_string _SEP_UNSAFE = re.compile(r'^[A-z0-9-_=]*$') @@ -152,25 +152,21 @@ class Signer: def __init__(self, key=None, sep=':', salt=None): # Use of native strings in all versions of Python self.key = key or settings.SECRET_KEY - self.sep = force_str(sep) + self.sep = sep if _SEP_UNSAFE.match(self.sep): raise ValueError( 'Unsafe Signer separator: %r (cannot be empty or consist of ' 'only A-z0-9-_=)' % sep, ) - self.salt = force_str(salt or '%s.%s' % (self.__class__.__module__, self.__class__.__name__)) + self.salt = salt or '%s.%s' % (self.__class__.__module__, self.__class__.__name__) def signature(self, value): - signature = base64_hmac(self.salt + 'signer', value, self.key) - # Convert the signature from bytes to str only on Python 3 - return force_str(signature) + return force_text(base64_hmac(self.salt + 'signer', value, self.key)) def sign(self, value): - value = force_str(value) - return str('%s%s%s') % (value, self.sep, self.signature(value)) + return '%s%s%s' % (value, self.sep, self.signature(value)) def unsign(self, signed_value): - signed_value = force_str(signed_value) if self.sep not in signed_value: raise BadSignature('No "%s" found in value' % self.sep) value, sig = signed_value.rsplit(self.sep, 1) @@ -185,8 +181,7 @@ def timestamp(self): return baseconv.base62.encode(int(time.time())) def sign(self, value): - value = force_str(value) - value = str('%s%s%s') % (value, self.sep, self.timestamp()) + value = '%s%s%s' % (force_text(value), self.sep, self.timestamp()) return super(TimestampSigner, self).sign(value) def unsign(self, value, max_age=None): diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 9f911343258e..d056392753a2 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -12,7 +12,6 @@ from django.db.backends import utils as backend_utils from django.db.backends.base.base import BaseDatabaseWrapper from django.utils import six -from django.utils.encoding import force_str from django.utils.functional import cached_property from django.utils.safestring import SafeBytes, SafeText @@ -225,7 +224,7 @@ def get_connection_params(self): if settings_dict['NAME']: kwargs['db'] = settings_dict['NAME'] if settings_dict['PASSWORD']: - kwargs['passwd'] = force_str(settings_dict['PASSWORD']) + kwargs['passwd'] = settings_dict['PASSWORD'] if settings_dict['HOST'].startswith('/'): kwargs['unix_socket'] = settings_dict['HOST'] elif settings_dict['HOST']: diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py index 10b54faa2098..a3b293ee366a 100644 --- a/django/db/backends/postgresql/base.py +++ b/django/db/backends/postgresql/base.py @@ -12,7 +12,6 @@ from django.db import DEFAULT_DB_ALIAS from django.db.backends.base.base import BaseDatabaseWrapper from django.db.utils import DatabaseError as WrappedDatabaseError -from django.utils.encoding import force_str from django.utils.functional import cached_property from django.utils.safestring import SafeBytes, SafeText @@ -160,7 +159,7 @@ def get_connection_params(self): if settings_dict['USER']: conn_params['user'] = settings_dict['USER'] if settings_dict['PASSWORD']: - conn_params['password'] = force_str(settings_dict['PASSWORD']) + conn_params['password'] = settings_dict['PASSWORD'] if settings_dict['HOST']: conn_params['host'] = settings_dict['HOST'] if settings_dict['PORT']: diff --git a/django/db/models/base.py b/django/db/models/base.py index 8cba12bb6e39..047f90ec733c 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -26,7 +26,7 @@ class_prepared, post_init, post_save, pre_init, pre_save, ) from django.db.models.utils import make_model_tuple -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.functional import curry from django.utils.text import capfirst, get_text_list from django.utils.translation import ugettext_lazy as _ @@ -505,7 +505,7 @@ def __repr__(self): u = str(self) except (UnicodeEncodeError, UnicodeDecodeError): u = '[Bad Unicode data]' - return force_str('<%s: %s>' % (self.__class__.__name__, u)) + return '<%s: %s>' % (self.__class__.__name__, u) def __str__(self): return '%s object' % self.__class__.__name__ diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index 1235f657303d..d1937bd5dbe1 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -9,7 +9,7 @@ from django.core.validators import validate_image_file_extension from django.db.models import signals from django.db.models.fields import Field -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.translation import ugettext_lazy as _ @@ -304,7 +304,7 @@ def generate_filename(self, instance, filename): if callable(self.upload_to): filename = self.upload_to(instance, filename) else: - dirname = force_text(datetime.datetime.now().strftime(force_str(self.upload_to))) + dirname = force_text(datetime.datetime.now().strftime(self.upload_to)) filename = posixpath.join(dirname, filename) return self.storage.generate_filename(filename) diff --git a/django/forms/fields.py b/django/forms/fields.py index 20521b26eaab..b7846d43a685 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -29,7 +29,7 @@ from django.utils import formats, six from django.utils.dateparse import parse_duration from django.utils.duration import duration_string -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.ipv6 import clean_ipv6_address from django.utils.translation import ugettext_lazy as _, ungettext_lazy @@ -429,7 +429,7 @@ def to_python(self, value): return super(DateField, self).to_python(value) def strptime(self, value, format): - return datetime.datetime.strptime(force_str(value), format).date() + return datetime.datetime.strptime(value, format).date() class TimeField(BaseTemporalField): @@ -451,7 +451,7 @@ def to_python(self, value): return super(TimeField, self).to_python(value) def strptime(self, value, format): - return datetime.datetime.strptime(force_str(value), format).time() + return datetime.datetime.strptime(value, format).time() class DateTimeField(BaseTemporalField): @@ -482,7 +482,7 @@ def to_python(self, value): return from_current_timezone(result) def strptime(self, value, format): - return datetime.datetime.strptime(force_str(value), format) + return datetime.datetime.strptime(value, format) class DurationField(Field): diff --git a/django/forms/widgets.py b/django/forms/widgets.py index d8b4d6a4dc48..a8760623d208 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -13,7 +13,7 @@ from django.templatetags.static import static from django.utils import datetime_safe, formats from django.utils.dates import MONTHS -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.formats import get_format from django.utils.html import format_html, html_safe from django.utils.safestring import mark_safe @@ -986,7 +986,7 @@ def format_value(self, value): if settings.USE_L10N: try: input_format = get_format('DATE_INPUT_FORMATS')[0] - d = datetime.datetime.strptime(force_str(value), input_format) + d = datetime.datetime.strptime(value, input_format) year, month, day = d.year, d.month, d.day except ValueError: pass diff --git a/django/http/request.py b/django/http/request.py index 4ca2ed25fad3..6f3b0c9951e7 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -14,9 +14,7 @@ from django.http.multipartparser import MultiPartParser, MultiPartParserError from django.utils import six from django.utils.datastructures import ImmutableList, MultiValueDict -from django.utils.encoding import ( - escape_uri_path, force_bytes, force_str, iri_to_uri, -) +from django.utils.encoding import escape_uri_path, force_bytes, iri_to_uri from django.utils.http import is_same_domain, limited_parse_qsl RAISE_ERROR = object() @@ -64,10 +62,8 @@ def __init__(self): def __repr__(self): if self.method is None or not self.get_full_path(): - return force_str('<%s>' % self.__class__.__name__) - return force_str( - '<%s: %s %r>' % (self.__class__.__name__, self.method, force_str(self.get_full_path())) - ) + return '<%s>' % self.__class__.__name__ + return '<%s: %s %r>' % (self.__class__.__name__, self.method, self.get_full_path()) def _get_raw_host(self): """ diff --git a/django/http/response.py b/django/http/response.py index c5294acbbdc6..e992adaed544 100644 --- a/django/http/response.py +++ b/django/http/response.py @@ -13,9 +13,7 @@ from django.core.serializers.json import DjangoJSONEncoder from django.http.cookie import SimpleCookie from django.utils import timezone -from django.utils.encoding import ( - force_bytes, force_str, force_text, iri_to_uri, -) +from django.utils.encoding import force_bytes, force_text, iri_to_uri from django.utils.http import cookie_date _charset_from_content_type_re = re.compile(r';\s*charset=(?P[^\s;]+)', re.I) @@ -170,7 +168,6 @@ def set_cookie(self, key, value='', max_age=None, expires=None, path='/', - an aware ``datetime.datetime`` object in any time zone. If it is a ``datetime.datetime`` object then ``max_age`` will be calculated. """ - value = force_str(value) self.cookies[key] = value if expires is not None: if isinstance(expires, datetime.datetime): diff --git a/django/template/base.py b/django/template/base.py index ce3cc2c7c095..f6259ec7cfcc 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -56,7 +56,7 @@ from django.template.context import ( # NOQA: imported for backwards compatibility BaseContext, Context, ContextPopException, RequestContext, ) -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.formats import localize from django.utils.html import conditional_escape, escape from django.utils.inspect import getargspec @@ -971,8 +971,7 @@ def __init__(self, s): self.s = s def __repr__(self): - rep = "<%s: %r>" % (self.__class__.__name__, self.s[:25]) - return force_str(rep, 'ascii', errors='replace') + return "<%s: %r>" % (self.__class__.__name__, self.s[:25]) def render(self, context): return self.s diff --git a/django/test/client.py b/django/test/client.py index c8c6e96a7ffb..20c968bb3f1d 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -21,7 +21,7 @@ from django.test.utils import ContextList from django.urls import resolve from django.utils import six -from django.utils.encoding import force_bytes, force_str, uri_to_iri +from django.utils.encoding import force_bytes, uri_to_iri from django.utils.functional import SimpleLazyObject, curry from django.utils.http import urlencode from django.utils.itercompat import is_iterable @@ -317,10 +317,10 @@ def _encode_data(self, data, content_type): return force_bytes(data, encoding=charset) def _get_path(self, parsed): - path = force_str(parsed[2]) + path = parsed.path # If there are parameters, add them - if parsed[3]: - path += str(";") + force_str(parsed[3]) + if parsed.params: + path += ";" + parsed.params path = uri_to_iri(path).encode(UTF_8) # Replace the behavior where non-ASCII values in the WSGI environ are # arbitrarily decoded with ISO-8859-1. @@ -389,7 +389,7 @@ def generic(self, method, path, data='', content_type='application/octet-stream', secure=False, **extra): """Constructs an arbitrary HTTP request.""" - parsed = urlparse(force_str(path)) + parsed = urlparse(str(path)) # path can be lazy data = force_bytes(data, settings.DEFAULT_CHARSET) r = { 'PATH_INFO': self._get_path(parsed), diff --git a/django/test/utils.py b/django/test/utils.py index 4fa379b4a7c1..a587e1fa9651 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -23,7 +23,6 @@ from django.test.signals import setting_changed, template_rendered from django.urls import get_script_prefix, set_script_prefix from django.utils.decorators import available_attrs -from django.utils.encoding import force_str from django.utils.translation import deactivate try: @@ -317,7 +316,7 @@ def get_runner(settings, test_runner_class=None): test_module_name = '.'.join(test_path[:-1]) else: test_module_name = '.' - test_module = __import__(test_module_name, {}, {}, force_str(test_path[-1])) + test_module = __import__(test_module_name, {}, {}, test_path[-1]) test_runner = getattr(test_module, test_path[-1]) return test_runner diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py index 36586feab03a..6084684d7379 100644 --- a/django/urls/resolvers.py +++ b/django/urls/resolvers.py @@ -15,7 +15,7 @@ from django.core.checks.urls import check_resolver from django.core.exceptions import ImproperlyConfigured from django.utils.datastructures import MultiValueDict -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.functional import cached_property from django.utils.http import RFC3986_SUBDELIMS, urlquote from django.utils.regex_helper import normalize @@ -160,7 +160,7 @@ def __init__(self, regex, callback, default_args=None, name=None): self.name = name def __repr__(self): - return force_str('<%s %s %s>' % (self.__class__.__name__, self.name, self.regex.pattern)) + return '<%s %s %s>' % (self.__class__.__name__, self.name, self.regex.pattern) def check(self): warnings = self._check_pattern_name() diff --git a/django/utils/formats.py b/django/utils/formats.py index 894003b4fab9..74af39eade3c 100644 --- a/django/utils/formats.py +++ b/django/utils/formats.py @@ -5,7 +5,6 @@ from django.conf import settings from django.utils import dateformat, datetime_safe, numberformat -from django.utils.encoding import force_str from django.utils.functional import lazy from django.utils.safestring import mark_safe from django.utils.translation import ( @@ -111,7 +110,6 @@ def get_format(format_type, lang=None, use_l10n=None): If use_l10n is provided and is not None, that will force the value to be localized (or not), overriding the value of settings.USE_L10N. """ - format_type = force_str(format_type) use_l10n = use_l10n or (use_l10n is None and settings.USE_L10N) if use_l10n and lang is None: lang = get_language() @@ -229,14 +227,14 @@ def localize_input(value, default=None): return number_format(value) elif isinstance(value, datetime.datetime): value = datetime_safe.new_datetime(value) - format = force_str(default or get_format('DATETIME_INPUT_FORMATS')[0]) + format = default or get_format('DATETIME_INPUT_FORMATS')[0] return value.strftime(format) elif isinstance(value, datetime.date): value = datetime_safe.new_date(value) - format = force_str(default or get_format('DATE_INPUT_FORMATS')[0]) + format = default or get_format('DATE_INPUT_FORMATS')[0] return value.strftime(format) elif isinstance(value, datetime.time): - format = force_str(default or get_format('TIME_INPUT_FORMATS')[0]) + format = default or get_format('TIME_INPUT_FORMATS')[0] return value.strftime(format) return value diff --git a/django/utils/html.py b/django/utils/html.py index 1fb39bb9b663..63335d74b41f 100644 --- a/django/utils/html.py +++ b/django/utils/html.py @@ -5,7 +5,7 @@ parse_qsl, quote, unquote, urlencode, urlsplit, urlunsplit, ) -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.functional import keep_lazy, keep_lazy_text from django.utils.http import RFC3986_GENDELIMS, RFC3986_SUBDELIMS from django.utils.safestring import SafeData, SafeText, mark_safe @@ -189,7 +189,7 @@ def strip_spaces_between_tags(value): def smart_urlquote(url): "Quotes a URL if it isn't already quoted." def unquote_quote(segment): - segment = unquote(force_str(segment)) + segment = unquote(segment) # Tilde is part of RFC3986 Unreserved Characters # http://tools.ietf.org/html/rfc3986#section-2.3 # See also http://bugs.python.org/issue16285 @@ -211,7 +211,7 @@ def unquote_quote(segment): if query: # Separately unquoting key/value, so as to not mix querystring separators # included in query values. See #22267. - query_parts = [(unquote(force_str(q[0])), unquote(force_str(q[1]))) + query_parts = [(unquote(q[0]), unquote(q[1])) for q in parse_qsl(query, keep_blank_values=True)] # urlencode will take care of quoting query = urlencode(query_parts) diff --git a/django/utils/tree.py b/django/utils/tree.py index 5c86e73da8c2..7f27fc7aac1c 100644 --- a/django/utils/tree.py +++ b/django/utils/tree.py @@ -5,7 +5,7 @@ import copy -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text class Node: @@ -45,10 +45,10 @@ def _new_instance(cls, children=None, connector=None, negated=False): def __str__(self): template = '(NOT (%s: %s))' if self.negated else '(%s: %s)' - return force_str(template % (self.connector, ', '.join(force_text(c) for c in self.children))) + return template % (self.connector, ', '.join(force_text(c) for c in self.children)) def __repr__(self): - return str("<%s: %s>") % (self.__class__.__name__, self) + return "<%s: %s>" % (self.__class__.__name__, self) def __deepcopy__(self, memodict): """ diff --git a/django/views/debug.py b/django/views/debug.py index 28e0fe6eb278..7094299e60c9 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -10,7 +10,7 @@ from django.urls import Resolver404, resolve from django.utils import timezone from django.utils.datastructures import MultiValueDict -from django.utils.encoding import force_bytes, force_text +from django.utils.encoding import force_text from django.utils.module_loading import import_string from django.utils.translation import ugettext as _ @@ -505,7 +505,7 @@ def technical_404_response(request, exception): 'root_urlconf': settings.ROOT_URLCONF, 'request_path': error_url, 'urlpatterns': tried, - 'reason': force_bytes(exception, errors='replace'), + 'reason': str(exception), 'request': request, 'settings': get_safe_settings(), 'raising_view_name': caller, diff --git a/django/views/generic/dates.py b/django/views/generic/dates.py index 86a49f8bd379..c738be8986c7 100644 --- a/django/views/generic/dates.py +++ b/django/views/generic/dates.py @@ -5,7 +5,7 @@ from django.db import models from django.http import Http404 from django.utils import timezone -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.functional import cached_property from django.utils.translation import ugettext as _ from django.views.generic.base import View @@ -687,7 +687,7 @@ def _date_from_string(year, year_format, month='', month_format='', day='', day_ format = delim.join((year_format, month_format, day_format)) datestr = delim.join((year, month, day)) try: - return datetime.datetime.strptime(force_str(datestr), format).date() + return datetime.datetime.strptime(datestr, format).date() except ValueError: raise Http404(_("Invalid date string '%(datestr)s' given format '%(format)s'") % { 'datestr': datestr, diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index 868d04196f93..50e034e03e51 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -1397,7 +1397,7 @@ def test_empty_allowed_hosts_error(self): class ManageTestserver(AdminScriptTestCase): from django.core.management.commands.testserver import Command as TestserverCommand - @mock.patch.object(TestserverCommand, 'handle') + @mock.patch.object(TestserverCommand, 'handle', return_value='') def test_testserver_handle_params(self, mock_handle): out = StringIO() call_command('testserver', 'blah.json', stdout=out) diff --git a/tests/admin_utils/tests.py b/tests/admin_utils/tests.py index 1c14615e714c..09136ea72ad7 100644 --- a/tests/admin_utils/tests.py +++ b/tests/admin_utils/tests.py @@ -217,13 +217,9 @@ def test_label_for_field(self): ("History", None) ) - self.assertEqual( - label_for_field("__unicode__", Article), - "article" - ) self.assertEqual( label_for_field("__str__", Article), - str("article") + "article" ) with self.assertRaises(AttributeError): diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 12d029ffcdbb..00864be47a0d 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -15,7 +15,6 @@ from django.core.management.base import CommandError from django.db import migrations from django.test import TestCase, mock, override_settings -from django.utils.encoding import force_str from django.utils.translation import ugettext_lazy as _ from .models import ( @@ -44,7 +43,7 @@ def mock_input(prompt): assert str('__proxy__') not in prompt response = '' for key, val in inputs.items(): - if force_str(key) in prompt.lower(): + if key in prompt.lower(): response = val break return response diff --git a/tests/contenttypes_tests/tests.py b/tests/contenttypes_tests/tests.py index 0ae2ddbb640c..7fedcb7abdeb 100644 --- a/tests/contenttypes_tests/tests.py +++ b/tests/contenttypes_tests/tests.py @@ -15,7 +15,7 @@ SimpleTestCase, TestCase, TransactionTestCase, mock, override_settings, ) from django.test.utils import captured_stdout, isolate_apps -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from .models import ( Article, Author, ModelWithNullFKToSite, Post, SchemeIncludedURL, @@ -144,7 +144,7 @@ def test_str(self): class Model(models.Model): field = GenericForeignKey() expected = "contenttypes_tests.Model.field" - actual = force_str(Model.field) + actual = force_text(Model.field) self.assertEqual(expected, actual) def test_missing_content_type_field(self): diff --git a/tests/dbshell/test_postgresql_psycopg2.py b/tests/dbshell/test_postgresql_psycopg2.py index 755464b3bbe7..f0848ac7b895 100644 --- a/tests/dbshell/test_postgresql_psycopg2.py +++ b/tests/dbshell/test_postgresql_psycopg2.py @@ -1,9 +1,7 @@ -import locale import os from django.db.backends.postgresql.client import DatabaseClient from django.test import SimpleTestCase, mock -from django.utils.encoding import force_bytes, force_str class PostgreSqlDbshellCommandTestCase(SimpleTestCase): @@ -13,13 +11,12 @@ def _run_it(self, dbinfo): That function invokes the runshell command, while mocking subprocess.call. It returns a 2-tuple with: - The command line list - - The binary content of file pointed by environment PGPASSFILE, or - None. + - The content of the file pointed by environment PGPASSFILE, or None. """ def _mock_subprocess_call(*args): self.subprocess_args = list(*args) if 'PGPASSFILE' in os.environ: - with open(os.environ['PGPASSFILE'], 'rb') as f: + with open(os.environ['PGPASSFILE'], 'r') as f: self.pgpass = f.read().strip() # ignore line endings else: self.pgpass = None @@ -40,7 +37,7 @@ def test_basic(self): 'port': '444', }), ( ['psql', '-U', 'someuser', '-h', 'somehost', '-p', '444', 'dbname'], - b'somehost:444:dbname:someuser:somepassword', + 'somehost:444:dbname:someuser:somepassword', ) ) @@ -67,7 +64,7 @@ def test_column(self): 'port': '444', }), ( ['psql', '-U', 'some:user', '-h', '::1', '-p', '444', 'dbname'], - b'\\:\\:1:444:dbname:some\\:user:some\\:password', + '\\:\\:1:444:dbname:some\\:user:some\\:password', ) ) @@ -81,30 +78,23 @@ def test_escape_characters(self): 'port': '444', }), ( ['psql', '-U', 'some\\user', '-h', 'somehost', '-p', '444', 'dbname'], - b'somehost:444:dbname:some\\\\user:some\\\\password', + 'somehost:444:dbname:some\\\\user:some\\\\password', ) ) def test_accent(self): - # The pgpass temporary file needs to be encoded using the system locale. - encoding = locale.getpreferredencoding() username = 'rôle' password = 'sésame' - username_str = force_str(username, encoding) - password_str = force_str(password, encoding) - pgpass_bytes = force_bytes( - 'somehost:444:dbname:%s:%s' % (username, password), - encoding=encoding, - ) + pgpass_string = 'somehost:444:dbname:%s:%s' % (username, password) self.assertEqual( self._run_it({ 'database': 'dbname', - 'user': username_str, - 'password': password_str, + 'user': username, + 'password': password, 'host': 'somehost', 'port': '444', }), ( - ['psql', '-U', username_str, '-h', 'somehost', '-p', '444', 'dbname'], - pgpass_bytes, + ['psql', '-U', username, '-h', 'somehost', '-p', '444', 'dbname'], + pgpass_string, ) ) diff --git a/tests/file_uploads/views.py b/tests/file_uploads/views.py index 789cc2a3652f..3eca47fe3580 100644 --- a/tests/file_uploads/views.py +++ b/tests/file_uploads/views.py @@ -4,7 +4,7 @@ from django.core.files.uploadedfile import UploadedFile from django.http import HttpResponse, HttpResponseServerError -from django.utils.encoding import force_bytes, force_str +from django.utils.encoding import force_bytes, force_text from .models import FileModel from .tests import UNICODE_FILENAME, UPLOAD_TO @@ -152,9 +152,7 @@ def file_upload_content_type_extra(request): """ params = {} for file_name, uploadedfile in request.FILES.items(): - params[file_name] = { - k: force_str(v) for k, v in uploadedfile.content_type_extra.items() - } + params[file_name] = {k: force_text(v) for k, v in uploadedfile.content_type_extra.items()} return HttpResponse(json.dumps(params)) diff --git a/tests/generic_views/test_list.py b/tests/generic_views/test_list.py index d5851d4ff809..429d46f50c97 100644 --- a/tests/generic_views/test_list.py +++ b/tests/generic_views/test_list.py @@ -2,7 +2,6 @@ from django.core.exceptions import ImproperlyConfigured from django.test import TestCase, override_settings -from django.utils.encoding import force_str from django.views.generic.base import View from .models import Artist, Author, Book, Page @@ -235,7 +234,7 @@ def test_paginated_list_view_returns_useful_message_on_invalid_page(self): self._make_authors(1) res = self.client.get('/list/authors/paginated/2/') self.assertEqual(res.status_code, 404) - self.assertEqual(force_str(res.context.get('reason')), "Invalid page (2): That page contains no results") + self.assertEqual(res.context.get('reason'), "Invalid page (2): That page contains no results") def _make_authors(self, n): Author.objects.all().delete() diff --git a/tests/handlers/tests.py b/tests/handlers/tests.py index d7cfaadf6293..ffb8a1f14555 100644 --- a/tests/handlers/tests.py +++ b/tests/handlers/tests.py @@ -7,7 +7,6 @@ from django.test import ( RequestFactory, SimpleTestCase, TransactionTestCase, override_settings, ) -from django.utils.encoding import force_str try: from http import HTTPStatus @@ -65,10 +64,7 @@ def test_non_ascii_cookie(self): raw_cookie = 'want="café"'.encode('utf-8').decode('iso-8859-1') environ['HTTP_COOKIE'] = raw_cookie request = WSGIRequest(environ) - # If would be nicer if request.COOKIES returned unicode values. - # However the current cookie parser doesn't do this and fixing it is - # much more work than fixing #20557. Feel free to remove force_str()! - self.assertEqual(request.COOKIES['want'], force_str("café")) + self.assertEqual(request.COOKIES['want'], "café") def test_invalid_unicode_cookie(self): """ diff --git a/tests/httpwrappers/tests.py b/tests/httpwrappers/tests.py index a4ea614175da..fe2ad1a216ab 100644 --- a/tests/httpwrappers/tests.py +++ b/tests/httpwrappers/tests.py @@ -17,7 +17,6 @@ ) from django.test import SimpleTestCase from django.utils._os import upath -from django.utils.encoding import force_str from django.utils.functional import lazystr @@ -294,13 +293,8 @@ def test_headers_type(self): self.assertIsInstance(r['key'], str) self.assertIn(b'test', r.serialize_headers()) - # Latin-1 unicode or bytes values are also converted to native strings. + # Non-ASCII values are serialized to Latin-1. r['key'] = 'café' - self.assertEqual(r['key'], force_str('café', 'latin-1')) - self.assertIsInstance(r['key'], str) - r['key'] = 'café'.encode('latin-1') - self.assertEqual(r['key'], force_str('café', 'latin-1')) - self.assertIsInstance(r['key'], str) self.assertIn('café'.encode('latin-1'), r.serialize_headers()) # Other unicode values are MIME-encoded (there's no way to pass them as bytes). @@ -759,7 +753,7 @@ def test_invalid_cookies(self): # More characters the spec forbids. self.assertEqual(parse_cookie('a b,c<>@:/[]?{}=d " =e,f g'), {'a b,c<>@:/[]?{}': 'd " =e,f g'}) # Unicode characters. The spec only allows ASCII. - self.assertEqual(parse_cookie('saint=André Bessette'), {'saint': force_str('André Bessette')}) + self.assertEqual(parse_cookie('saint=André Bessette'), {'saint': 'André Bessette'}) # Browsers don't send extra whitespace or semicolons in Cookie headers, # but parse_cookie() should parse whitespace the same way # document.cookie parses whitespace. diff --git a/tests/middleware/tests.py b/tests/middleware/tests.py index 8749a9ee501e..bd2ba8984834 100644 --- a/tests/middleware/tests.py +++ b/tests/middleware/tests.py @@ -22,7 +22,6 @@ RequestFactory, SimpleTestCase, ignore_warnings, override_settings, ) from django.utils.deprecation import RemovedInDjango21Warning -from django.utils.encoding import force_str int2byte = struct.Struct(">B").pack @@ -350,7 +349,7 @@ def test_disallowed_user_agents(self): def test_non_ascii_query_string_does_not_crash(self): """Regression test for #15152""" request = self.rf.get('/slash') - request.META['QUERY_STRING'] = force_str('drink=café') + request.META['QUERY_STRING'] = 'drink=café' r = CommonMiddleware().process_request(request) self.assertEqual(r.status_code, 301) diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index a51842e02d37..46126bb760d4 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -24,7 +24,6 @@ from django.utils import datetime_safe from django.utils._os import upath from django.utils.deconstruct import deconstructible -from django.utils.encoding import force_str from django.utils.functional import SimpleLazyObject from django.utils.timezone import FixedOffset, get_default_timezone, utc from django.utils.translation import ugettext_lazy as _ @@ -170,7 +169,7 @@ class WriterTests(SimpleTestCase): def safe_exec(self, string, value=None): d = {} try: - exec(force_str(string), globals(), d) + exec(string, globals(), d) except Exception as e: if value: self.fail("Could not exec %r (from value %r): %s" % (string.strip(), value, e)) diff --git a/tests/or_lookups/tests.py b/tests/or_lookups/tests.py index dd93ed7efc71..fd4cc3369b94 100644 --- a/tests/or_lookups/tests.py +++ b/tests/or_lookups/tests.py @@ -3,7 +3,6 @@ from django.db.models import Q from django.test import TestCase -from django.utils.encoding import force_str from .models import Article @@ -124,9 +123,9 @@ def test_pk_in(self): def test_q_repr(self): or_expr = Q(baz=Article(headline="Foö")) - self.assertEqual(repr(or_expr), force_str("))>")) + self.assertEqual(repr(or_expr), "))>") negated_or = ~Q(baz=Article(headline="Foö")) - self.assertEqual(repr(negated_or), force_str(")))>")) + self.assertEqual(repr(negated_or), ")))>") def test_q_negated(self): # Q objects can be negated diff --git a/tests/requests/tests.py b/tests/requests/tests.py index 54fe797728b1..0dcaebbca52b 100644 --- a/tests/requests/tests.py +++ b/tests/requests/tests.py @@ -14,7 +14,6 @@ from django.test import RequestFactory, SimpleTestCase, override_settings from django.test.client import FakePayload from django.test.utils import freeze_time, str_prefix -from django.utils.encoding import force_str from django.utils.http import cookie_date, urlencode from django.utils.timezone import utc @@ -270,7 +269,7 @@ def test_unicode_cookie(self): response = HttpResponse() cookie_value = '清風' response.set_cookie('test', cookie_value) - self.assertEqual(force_str(cookie_value), response.cookies['test'].value) + self.assertEqual(cookie_value, response.cookies['test'].value) def test_limited_stream(self): # Read all of a limited stream diff --git a/tests/signing/tests.py b/tests/signing/tests.py index bc838d015f1e..a55457efdd53 100644 --- a/tests/signing/tests.py +++ b/tests/signing/tests.py @@ -3,7 +3,6 @@ from django.core import signing from django.test import SimpleTestCase from django.test.utils import freeze_time -from django.utils.encoding import force_str class TestSigner(SimpleTestCase): @@ -47,7 +46,7 @@ def test_sign_unsign(self): for example in examples: signed = signer.sign(example) self.assertIsInstance(signed, str) - self.assertNotEqual(force_str(example), signed) + self.assertNotEqual(example, signed) self.assertEqual(example, signer.unsign(signed)) def test_unsign_detects_tampering(self): From 109b33f64c8d3f48c9e0bd3ea8d42fe6f3cb02b7 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 19 Jan 2017 21:10:33 -0500 Subject: [PATCH 0086/3180] Refs #23919 -- Simplified assertRaisesRegex()'s that accounted for Python 2. --- tests/auth_tests/test_hashers.py | 18 +++++++++++------- tests/file_storage/tests.py | 5 ++--- tests/fixtures_regress/tests.py | 2 +- .../forms_tests/field_tests/test_regexfield.py | 6 +++--- .../field_tests/test_splitdatetimefield.py | 4 ++-- tests/forms_tests/tests/test_forms.py | 8 +++----- tests/migrations/test_writer.py | 2 +- tests/template_backends/test_utils.py | 4 ++-- tests/template_tests/test_custom.py | 16 ++++++---------- tests/template_tests/test_parser.py | 2 +- tests/test_utils/tests.py | 14 +++++++++----- tests/utils_tests/test_module_loading.py | 4 ++-- 12 files changed, 43 insertions(+), 42 deletions(-) diff --git a/tests/auth_tests/test_hashers.py b/tests/auth_tests/test_hashers.py index 59de85ad9f1d..57982017eb3f 100644 --- a/tests/auth_tests/test_hashers.py +++ b/tests/auth_tests/test_hashers.py @@ -251,7 +251,7 @@ def test_unusable(self): self.assertFalse(check_password('', encoded)) self.assertFalse(check_password('lètmein', encoded)) self.assertFalse(check_password('lètmeinz', encoded)) - with self.assertRaises(ValueError): + with self.assertRaisesMessage(ValueError, 'Unknown password hashing algorith'): identify_hasher(encoded) # Assert that the unusable passwords actually contain a random part. # This might fail one day due to a hash collision. @@ -265,9 +265,13 @@ def test_unspecified_password(self): self.assertFalse(check_password(None, make_password('lètmein'))) def test_bad_algorithm(self): - with self.assertRaises(ValueError): + msg = ( + "Unknown password hashing algorithm '%s'. Did you specify it in " + "the PASSWORD_HASHERS setting?" + ) + with self.assertRaisesMessage(ValueError, msg % 'lolcat'): make_password('lètmein', hasher='lolcat') - with self.assertRaises(ValueError): + with self.assertRaisesMessage(ValueError, msg % 'lolcat'): identify_hasher('lolcat$salt$hash') def test_bad_encoded(self): @@ -424,15 +428,15 @@ def test_check_password_calls_harden_runtime(self): self.assertEqual(hasher.harden_runtime.call_count, 1) def test_load_library_no_algorithm(self): - with self.assertRaises(ValueError) as e: + msg = "Hasher 'BasePasswordHasher' doesn't specify a library attribute" + with self.assertRaisesMessage(ValueError, msg): BasePasswordHasher()._load_library() - self.assertEqual("Hasher 'BasePasswordHasher' doesn't specify a library attribute", str(e.exception)) def test_load_library_importerror(self): PlainHasher = type('PlainHasher', (BasePasswordHasher,), {'algorithm': 'plain', 'library': 'plain'}) # Python 3 adds quotes around module name - msg = "Couldn't load 'PlainHasher' algorithm library: No module named '?plain'?" - with self.assertRaisesRegex(ValueError, msg): + msg = "Couldn't load 'PlainHasher' algorithm library: No module named 'plain'" + with self.assertRaisesMessage(ValueError, msg): PlainHasher()._load_library() diff --git a/tests/file_storage/tests.py b/tests/file_storage/tests.py index 5aee127c8c77..7912eb7efa6f 100644 --- a/tests/file_storage/tests.py +++ b/tests/file_storage/tests.py @@ -45,7 +45,7 @@ def test_get_invalid_storage_module(self): """ get_storage_class raises an error if the requested import don't exist. """ - with self.assertRaisesRegex(ImportError, "No module named '?storage'?"): + with self.assertRaisesMessage(ImportError, "No module named 'storage'"): get_storage_class('storage.NonExistingStorage') def test_get_nonexisting_storage_class(self): @@ -59,8 +59,7 @@ def test_get_nonexisting_storage_module(self): """ get_storage_class raises an error if the requested module don't exist. """ - # Error message may or may not be the fully qualified path. - with self.assertRaisesRegex(ImportError, "No module named '?(django.core.files.)?non_existing_storage'?"): + with self.assertRaisesMessage(ImportError, "No module named 'django.core.files.non_existing_storage'"): get_storage_class('django.core.files.non_existing_storage.NonExistingStorage') diff --git a/tests/fixtures_regress/tests.py b/tests/fixtures_regress/tests.py index a3ac7f597762..538fee55a253 100644 --- a/tests/fixtures_regress/tests.py +++ b/tests/fixtures_regress/tests.py @@ -197,7 +197,7 @@ def test_unimportable_serializer(self): """ Failing serializer import raises the proper error """ - with self.assertRaisesRegex(ImportError, r"No module named.*unexistent"): + with self.assertRaisesMessage(ImportError, "No module named 'unexistent'"): management.call_command( 'loaddata', 'bad_fixture1.unkn', diff --git a/tests/forms_tests/field_tests/test_regexfield.py b/tests/forms_tests/field_tests/test_regexfield.py index bd8d6dda097b..6f4cc440e976 100644 --- a/tests/forms_tests/field_tests/test_regexfield.py +++ b/tests/forms_tests/field_tests/test_regexfield.py @@ -42,10 +42,10 @@ def test_regexfield_4(self): f = RegexField('^[0-9]+$', min_length=5, max_length=10) with self.assertRaisesMessage(ValidationError, "'Ensure this value has at least 5 characters (it has 3).'"): f.clean('123') - with self.assertRaisesRegex( + with self.assertRaisesMessage( ValidationError, - r"'Ensure this value has at least 5 characters \(it has 3\)\.'," - r" u?'Enter a valid value\.'", + "'Ensure this value has at least 5 characters (it has 3).', " + "'Enter a valid value.'", ): f.clean('abc') self.assertEqual('12345', f.clean('12345')) diff --git a/tests/forms_tests/field_tests/test_splitdatetimefield.py b/tests/forms_tests/field_tests/test_splitdatetimefield.py index be70edd3d4de..940d03b8a927 100644 --- a/tests/forms_tests/field_tests/test_splitdatetimefield.py +++ b/tests/forms_tests/field_tests/test_splitdatetimefield.py @@ -20,7 +20,7 @@ def test_splitdatetimefield_1(self): f.clean('') with self.assertRaisesMessage(ValidationError, "'Enter a list of values.'"): f.clean('hello') - with self.assertRaisesRegex(ValidationError, r"'Enter a valid date\.', u?'Enter a valid time\.'"): + with self.assertRaisesMessage(ValidationError, "'Enter a valid date.', 'Enter a valid time.'"): f.clean(['hello', 'there']) with self.assertRaisesMessage(ValidationError, "'Enter a valid time.'"): f.clean(['2006-01-10', 'there']) @@ -40,7 +40,7 @@ def test_splitdatetimefield_2(self): self.assertIsNone(f.clean(['', ''])) with self.assertRaisesMessage(ValidationError, "'Enter a list of values.'"): f.clean('hello') - with self.assertRaisesRegex(ValidationError, r"'Enter a valid date\.', u?'Enter a valid time\.'"): + with self.assertRaisesMessage(ValidationError, "'Enter a valid date.', 'Enter a valid time.'"): f.clean(['hello', 'there']) with self.assertRaisesMessage(ValidationError, "'Enter a valid time.'"): f.clean(['2006-01-10', 'there']) diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py index dacd7739d307..dc70519dacf3 100644 --- a/tests/forms_tests/tests/test_forms.py +++ b/tests/forms_tests/tests/test_forms.py @@ -2954,10 +2954,8 @@ def compress(self, data_list): with self.assertRaisesMessage(ValidationError, "'Enter a complete value.'"): f.clean(['+61']) self.assertEqual('+61.287654321 ext. 123 (label: )', f.clean(['+61', '287654321', '123'])) - self.assertRaisesRegex( - ValidationError, - r"'Enter a complete value\.', u?'Enter an extension\.'", f.clean, ['', '', '', 'Home'] - ) + with self.assertRaisesMessage(ValidationError, "'Enter a complete value.', 'Enter an extension.'"): + f.clean(['', '', '', 'Home']) with self.assertRaisesMessage(ValidationError, "'Enter a valid country code.'"): f.clean(['61', '287654321', '123', 'Home']) @@ -2970,7 +2968,7 @@ def compress(self, data_list): with self.assertRaisesMessage(ValidationError, "'Enter a complete value.'"): f.clean(['+61']) self.assertEqual('+61.287654321 ext. 123 (label: )', f.clean(['+61', '287654321', '123'])) - with self.assertRaisesRegex(ValidationError, r"'Enter a complete value\.', u?'Enter an extension\.'"): + with self.assertRaisesMessage(ValidationError, "'Enter a complete value.', 'Enter an extension.'"): f.clean(['', '', '', 'Home']) with self.assertRaisesMessage(ValidationError, "'Enter a valid country code.'"): f.clean(['61', '287654321', '123', 'Home']) diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index 46126bb760d4..83de774aee80 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -450,7 +450,7 @@ def test_serialize_class_based_validators(self): self.assertEqual(string, "migrations.test_writer.EmailValidator(message='hello')") validator = deconstructible(path="custom.EmailValidator")(EmailValidator)(message="hello") - with self.assertRaisesRegex(ImportError, "No module named '?custom'?"): + with self.assertRaisesMessage(ImportError, "No module named 'custom'"): MigrationWriter.serialize(validator) validator = deconstructible(path="django.core.validators.EmailValidator2")(EmailValidator)(message="hello") diff --git a/tests/template_backends/test_utils.py b/tests/template_backends/test_utils.py index d1f3aaa7935a..d0bd01cdc26b 100644 --- a/tests/template_backends/test_utils.py +++ b/tests/template_backends/test_utils.py @@ -11,9 +11,9 @@ def test_backend_import_error(self): Failing to import a backend keeps raising the original import error (#24265). """ - with self.assertRaisesRegex(ImportError, "No module named '?raise"): + with self.assertRaisesMessage(ImportError, "No module named 'raise"): engines.all() - with self.assertRaisesRegex(ImportError, "No module named '?raise"): + with self.assertRaisesMessage(ImportError, "No module named 'raise"): engines.all() @override_settings(TEMPLATES=[{ diff --git a/tests/template_tests/test_custom.py b/tests/template_tests/test_custom.py index 03d43089378f..8eec22504c34 100644 --- a/tests/template_tests/test_custom.py +++ b/tests/template_tests/test_custom.py @@ -313,25 +313,21 @@ def test_load_error(self): msg = ( "Invalid template library specified. ImportError raised when " "trying to load 'template_tests.broken_tag': cannot import name " - "'?Xtemplate'?" + "'Xtemplate'" ) - with self.assertRaisesRegex(InvalidTemplateLibrary, msg): - Engine(libraries={ - 'broken_tag': 'template_tests.broken_tag', - }) + with self.assertRaisesMessage(InvalidTemplateLibrary, msg): + Engine(libraries={'broken_tag': 'template_tests.broken_tag'}) def test_load_error_egg(self): egg_name = '%s/tagsegg.egg' % self.egg_dir msg = ( "Invalid template library specified. ImportError raised when " "trying to load 'tagsegg.templatetags.broken_egg': cannot " - "import name '?Xtemplate'?" + "import name 'Xtemplate'" ) with extend_sys_path(egg_name): - with self.assertRaisesRegex(InvalidTemplateLibrary, msg): - Engine(libraries={ - 'broken_egg': 'tagsegg.templatetags.broken_egg', - }) + with self.assertRaisesMessage(InvalidTemplateLibrary, msg): + Engine(libraries={'broken_egg': 'tagsegg.templatetags.broken_egg'}) def test_load_working_egg(self): ttext = "{% load working_egg %}" diff --git a/tests/template_tests/test_parser.py b/tests/template_tests/test_parser.py index 3b59424f4783..cd2f2ddc05b6 100644 --- a/tests/template_tests/test_parser.py +++ b/tests/template_tests/test_parser.py @@ -68,7 +68,7 @@ def test_variable_parsing(self): Variable("article._hidden") # Variables should raise on non string type - with self.assertRaisesRegex(TypeError, "Variable must be a string or number, got <(class|type) 'dict'>"): + with self.assertRaisesMessage(TypeError, "Variable must be a string or number, got "): Variable({}) def test_filter_args_count(self): diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py index f8eda7ed3925..b1c35d1f807a 100644 --- a/tests/test_utils/tests.py +++ b/tests/test_utils/tests.py @@ -362,22 +362,26 @@ def test_not_used(self): pass def test_error_message(self): - with self.assertRaisesRegex(AssertionError, r'^template_used/base\.html'): + msg = 'template_used/base.html was not rendered. No template was rendered.' + with self.assertRaisesMessage(AssertionError, msg): with self.assertTemplateUsed('template_used/base.html'): pass - with self.assertRaisesRegex(AssertionError, r'^template_used/base\.html'): + with self.assertRaisesMessage(AssertionError, msg): with self.assertTemplateUsed(template_name='template_used/base.html'): pass - with self.assertRaisesRegex(AssertionError, r'^template_used/base\.html.*template_used/alternative\.html$'): + msg2 = ( + 'template_used/base.html was not rendered. Following templates ' + 'were rendered: template_used/alternative.html' + ) + with self.assertRaisesMessage(AssertionError, msg2): with self.assertTemplateUsed('template_used/base.html'): render_to_string('template_used/alternative.html') - with self.assertRaises(AssertionError) as cm: + with self.assertRaisesMessage(AssertionError, 'No templates used to render the response'): response = self.client.get('/test_utils/no_template_used/') self.assertTemplateUsed(response, 'template_used/base.html') - self.assertEqual(cm.exception.args[0], "No templates used to render the response") def test_failure(self): with self.assertRaises(TypeError): diff --git a/tests/utils_tests/test_module_loading.py b/tests/utils_tests/test_module_loading.py index e979b3e7ba04..8e6806e8d571 100644 --- a/tests/utils_tests/test_module_loading.py +++ b/tests/utils_tests/test_module_loading.py @@ -146,11 +146,11 @@ def test_autodiscover_modules_not_found(self): autodiscover_modules('missing_module') def test_autodiscover_modules_found_but_bad_module(self): - with self.assertRaisesRegex(ImportError, "No module named '?a_package_name_that_does_not_exist'?"): + with self.assertRaisesMessage(ImportError, "No module named 'a_package_name_that_does_not_exist'"): autodiscover_modules('bad_module') def test_autodiscover_modules_several_one_bad_module(self): - with self.assertRaisesRegex(ImportError, "No module named '?a_package_name_that_does_not_exist'?"): + with self.assertRaisesMessage(ImportError, "No module named 'a_package_name_that_does_not_exist'"): autodiscover_modules('good_module', 'bad_module') def test_autodiscover_modules_several_found(self): From ec4c1d6717da7a9d09d5b3ce84cccac819bb592c Mon Sep 17 00:00:00 2001 From: Srinivas Reddy Thatiparthy Date: Fri, 20 Jan 2017 18:08:17 +0530 Subject: [PATCH 0087/3180] Removed u'' prefx in django/core/signing.py comment. --- django/core/signing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django/core/signing.py b/django/core/signing.py index b6bb7492471a..7d73611817b0 100644 --- a/django/core/signing.py +++ b/django/core/signing.py @@ -14,7 +14,7 @@ If the signature fails, a BadSignature exception is raised. >>> signing.loads("ImhlbGxvIg:1QaUZC:YIye-ze3TTx7gtSv422nZA4sgmk") -u'hello' +'hello' >>> signing.loads("ImhlbGxvIg:1QaUZC:YIye-ze3TTx7gtSv422nZA4sgmk-modified") ... BadSignature: Signature failed: ImhlbGxvIg:1QaUZC:YIye-ze3TTx7gtSv422nZA4sgmk-modified From 4e729feaa647547f25debb1cb63dec989dc41a20 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 20 Jan 2017 08:01:02 -0500 Subject: [PATCH 0088/3180] Refs #23919 -- Removed django.utils._os.upath()/npath()/abspathu() usage. These functions do nothing on Python 3. --- django/apps/config.py | 3 +-- django/contrib/auth/password_validation.py | 3 +-- django/core/files/storage.py | 4 ++-- django/core/management/__init__.py | 5 ++--- .../core/management/commands/compilemessages.py | 7 +++---- django/core/management/commands/loaddata.py | 3 +-- django/core/management/commands/makemessages.py | 3 +-- django/db/migrations/writer.py | 5 ++--- django/db/utils.py | 5 ++--- django/forms/renderers.py | 3 +-- django/template/utils.py | 3 +-- django/utils/_os.py | 11 +++++------ django/utils/autoreload.py | 3 +-- django/utils/translation/trans_real.py | 5 ++--- tests/admin_scripts/tests.py | 11 +++++------ tests/admin_scripts/urls.py | 3 +-- tests/admin_views/tests.py | 5 ++--- tests/app_loading/tests.py | 3 +-- tests/apps/namespace_package_base/nsapp/apps.py | 3 +-- tests/apps/tests.py | 7 +++---- tests/auth_tests/settings.py | 4 +--- tests/auth_tests/test_validators.py | 3 +-- tests/file_storage/tests.py | 3 +-- tests/files/tests.py | 11 +++++------ tests/fixtures_regress/tests.py | 5 ++--- .../forms_tests/field_tests/test_filepathfield.py | 15 +++++---------- tests/forms_tests/field_tests/test_imagefield.py | 3 +-- tests/forms_tests/tests/test_renderers.py | 5 ++--- tests/gis_tests/gdal_tests/test_raster.py | 8 +++----- tests/gis_tests/geo3d/tests.py | 3 +-- tests/gis_tests/geogapp/tests.py | 3 +-- tests/gis_tests/layermap/tests.py | 3 +-- tests/gis_tests/test_data.py | 3 +-- tests/httpwrappers/tests.py | 5 ++--- tests/i18n/contenttypes/tests.py | 3 +-- tests/i18n/patterns/tests.py | 5 ++--- tests/i18n/test_percents.py | 3 +-- tests/i18n/tests.py | 3 +-- tests/i18n/utils.py | 4 +--- tests/mail/tests.py | 3 +-- tests/migrations/test_writer.py | 3 +-- tests/model_fields/test_imagefield.py | 5 ++--- tests/model_forms/models.py | 3 +-- tests/model_forms/tests.py | 7 +++---- tests/project_template/test_settings.py | 3 +-- tests/proxy_model_inheritance/tests.py | 3 +-- tests/runtests.py | 5 ++--- tests/servers/tests.py | 3 +-- tests/sitemaps_tests/test_http.py | 5 ++--- tests/staticfiles_tests/settings.py | 4 +--- tests/staticfiles_tests/test_liveserver.py | 3 +-- tests/template_tests/syntax_tests/i18n/base.py | 3 +-- tests/template_tests/utils.py | 3 +-- tests/test_client_regress/tests.py | 3 +-- tests/test_utils/tests.py | 4 ++-- .../test_localeregexprovider.py | 3 +-- tests/user_commands/tests.py | 3 +-- tests/utils_tests/test_archive.py | 3 +-- tests/utils_tests/test_autoreload.py | 15 +++++++-------- tests/utils_tests/test_html.py | 3 +-- tests/utils_tests/test_module_loading.py | 3 +-- tests/validators/tests.py | 3 +-- tests/view_tests/tests/test_i18n.py | 3 +-- tests/view_tests/urls.py | 3 +-- 64 files changed, 108 insertions(+), 178 deletions(-) diff --git a/django/apps/config.py b/django/apps/config.py index 024643a64521..78762dd61208 100644 --- a/django/apps/config.py +++ b/django/apps/config.py @@ -2,7 +2,6 @@ from importlib import import_module from django.core.exceptions import ImproperlyConfigured -from django.utils._os import upath from django.utils.module_loading import module_has_submodule MODELS_MODULE_NAME = 'models' @@ -80,7 +79,7 @@ def _path_from_module(self, module): "The app module %r has no filesystem location, " "you must configure this app with an AppConfig subclass " "with a 'path' class attribute." % (module,)) - return upath(paths[0]) + return paths[0] @classmethod def create(cls, entry): diff --git a/django/contrib/auth/password_validation.py b/django/contrib/auth/password_validation.py index a7319dbd52cd..23b2b6f18514 100644 --- a/django/contrib/auth/password_validation.py +++ b/django/contrib/auth/password_validation.py @@ -8,7 +8,6 @@ from django.core.exceptions import ( FieldDoesNotExist, ImproperlyConfigured, ValidationError, ) -from django.utils._os import upath from django.utils.encoding import force_text from django.utils.functional import lazy from django.utils.html import format_html @@ -168,7 +167,7 @@ class CommonPasswordValidator: https://xato.net/passwords/more-top-worst-passwords/ """ DEFAULT_PASSWORD_LIST_PATH = os.path.join( - os.path.dirname(os.path.realpath(upath(__file__))), 'common-passwords.txt.gz' + os.path.dirname(os.path.realpath(__file__)), 'common-passwords.txt.gz' ) def __init__(self, password_list_path=DEFAULT_PASSWORD_LIST_PATH): diff --git a/django/core/files/storage.py b/django/core/files/storage.py index 6f2d6bfd9178..a8814ddc4855 100644 --- a/django/core/files/storage.py +++ b/django/core/files/storage.py @@ -9,7 +9,7 @@ from django.core.files.move import file_move_safe from django.core.signals import setting_changed from django.utils import timezone -from django.utils._os import abspathu, safe_join +from django.utils._os import safe_join from django.utils.crypto import get_random_string from django.utils.deconstruct import deconstructible from django.utils.encoding import filepath_to_uri, force_text @@ -201,7 +201,7 @@ def base_location(self): @cached_property def location(self): - return abspathu(self.base_location) + return os.path.abspath(self.base_location) @cached_property def base_url(self): diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py index 1b59dac68680..ce0903dbdfd0 100644 --- a/django/core/management/__init__.py +++ b/django/core/management/__init__.py @@ -14,7 +14,6 @@ ) from django.core.management.color import color_style from django.utils import autoreload -from django.utils._os import npath, upath from django.utils.encoding import force_text @@ -26,7 +25,7 @@ def find_commands(management_dir): Returns an empty list if no commands are defined. """ command_dir = os.path.join(management_dir, 'commands') - return [name for _, name, is_pkg in pkgutil.iter_modules([npath(command_dir)]) + return [name for _, name, is_pkg in pkgutil.iter_modules([command_dir]) if not is_pkg and not name.startswith('_')] @@ -63,7 +62,7 @@ def get_commands(): The dictionary is cached on the first call and reused on subsequent calls. """ - commands = {name: 'django.core' for name in find_commands(upath(__path__[0]))} + commands = {name: 'django.core' for name in find_commands(__path__[0])} if not settings.configured: return commands diff --git a/django/core/management/commands/compilemessages.py b/django/core/management/commands/compilemessages.py index 05fb9e5cfc60..c5c7f225836d 100644 --- a/django/core/management/commands/compilemessages.py +++ b/django/core/management/commands/compilemessages.py @@ -4,7 +4,6 @@ from django.core.management.base import BaseCommand, CommandError from django.core.management.utils import find_command, popen_wrapper -from django.utils._os import npath, upath def has_bom(fn): @@ -62,7 +61,7 @@ def handle(self, **options): basedirs = [os.path.join('conf', 'locale'), 'locale'] if os.environ.get('DJANGO_SETTINGS_MODULE'): from django.conf import settings - basedirs.extend(upath(path) for path in settings.LOCALE_PATHS) + basedirs.extend(settings.LOCALE_PATHS) # Walk entire tree, looking for locale directories for dirpath, dirnames, filenames in os.walk('.', topdown=True): @@ -115,13 +114,13 @@ def compile_messages(self, locations): base_path = os.path.splitext(po_path)[0] # Check writability on first location - if i == 0 and not is_writable(npath(base_path + '.mo')): + if i == 0 and not is_writable(base_path + '.mo'): self.stderr.write("The po files under %s are in a seemingly not writable location. " "mo files will not be updated/created." % dirpath) return args = [self.program] + self.program_options + [ - '-o', npath(base_path + '.mo'), npath(base_path + '.po') + '-o', base_path + '.mo', base_path + '.po' ] output, errors, status = popen_wrapper(args) if status: diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index 9edd642b433c..4556d9b9d817 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -17,7 +17,6 @@ DEFAULT_DB_ALIAS, DatabaseError, IntegrityError, connections, router, transaction, ) -from django.utils._os import upath from django.utils.encoding import force_text from django.utils.functional import cached_property @@ -287,7 +286,7 @@ def fixture_dirs(self): dirs.append(app_dir) dirs.extend(list(fixture_dirs)) dirs.append('') - dirs = [upath(os.path.abspath(os.path.realpath(d))) for d in dirs] + dirs = [os.path.abspath(os.path.realpath(d)) for d in dirs] return dirs def parse_name(self, fixture_name): diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py index 48ed70845abc..5b74ddaa0d17 100644 --- a/django/core/management/commands/makemessages.py +++ b/django/core/management/commands/makemessages.py @@ -14,7 +14,6 @@ from django.core.management.utils import ( find_command, handle_extensions, popen_wrapper, ) -from django.utils._os import upath from django.utils.encoding import DEFAULT_LOCALE_ENCODING from django.utils.functional import cached_property from django.utils.jslex import prepare_js_for_gettext @@ -638,7 +637,7 @@ def copy_plural_forms(self, msgs, locale): the msgs string, inserting it at the right place. msgs should be the contents of a newly created .po file. """ - django_dir = os.path.normpath(os.path.join(os.path.dirname(upath(django.__file__)))) + django_dir = os.path.normpath(os.path.join(os.path.dirname(django.__file__))) if self.domain == 'djangojs': domains = ('djangojs', 'django') else: diff --git a/django/db/migrations/writer.py b/django/db/migrations/writer.py index 5a3378fe4b37..09d8f1f13b11 100644 --- a/django/db/migrations/writer.py +++ b/django/db/migrations/writer.py @@ -7,7 +7,6 @@ from django.db import migrations from django.db.migrations.loader import MigrationLoader from django.db.migrations.serializer import serializer_factory -from django.utils._os import upath from django.utils.encoding import force_text from django.utils.inspect import get_func_args from django.utils.module_loading import module_dir @@ -229,7 +228,7 @@ def basedir(self): pass else: try: - return upath(module_dir(migrations_module)) + return module_dir(migrations_module) except ValueError: pass @@ -250,7 +249,7 @@ def basedir(self): continue else: try: - base_dir = upath(module_dir(base_module)) + base_dir = module_dir(base_module) except ValueError: continue else: diff --git a/django/db/utils.py b/django/db/utils.py index 8ca3f860b3fe..a35de01ffa91 100644 --- a/django/db/utils.py +++ b/django/db/utils.py @@ -6,7 +6,6 @@ from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.utils import six -from django.utils._os import npath, upath from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -116,10 +115,10 @@ def load_backend(backend_name): except ImportError as e_user: # The database backend wasn't found. Display a helpful error message # listing all possible (built-in) database backends. - backend_dir = os.path.join(os.path.dirname(upath(__file__)), 'backends') + backend_dir = os.path.join(os.path.dirname(__file__), 'backends') try: builtin_backends = [ - name for _, name, ispkg in pkgutil.iter_modules([npath(backend_dir)]) + name for _, name, ispkg in pkgutil.iter_modules([backend_dir]) if ispkg and name not in {'base', 'dummy', 'postgresql_psycopg2'} ] except EnvironmentError: diff --git a/django/forms/renderers.py b/django/forms/renderers.py index 3023d477e483..435a12d852d0 100644 --- a/django/forms/renderers.py +++ b/django/forms/renderers.py @@ -4,7 +4,6 @@ from django.conf import settings from django.template.backends.django import DjangoTemplates from django.template.loader import get_template -from django.utils._os import upath from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -14,7 +13,7 @@ def Jinja2(params): raise ImportError("jinja2 isn't installed") -ROOT = upath(os.path.dirname(__file__)) +ROOT = os.path.dirname(__file__) @functools.lru_cache() diff --git a/django/template/utils.py b/django/template/utils.py index 852baca5660e..fde2f64d1342 100644 --- a/django/template/utils.py +++ b/django/template/utils.py @@ -5,7 +5,6 @@ from django.apps import apps from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from django.utils._os import upath from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -103,6 +102,6 @@ def get_app_template_dirs(dirname): continue template_dir = os.path.join(app_config.path, dirname) if os.path.isdir(template_dir): - template_dirs.append(upath(template_dir)) + template_dirs.append(template_dir) # Immutable return value because it will be cached and shared by callers. return tuple(template_dirs) diff --git a/django/utils/_os.py b/django/utils/_os.py index 6507e587645d..8309e08fbf93 100644 --- a/django/utils/_os.py +++ b/django/utils/_os.py @@ -5,20 +5,19 @@ from django.core.exceptions import SuspiciousFileOperation from django.utils.encoding import force_text +# For backwards-compatibility in Django 2.0 abspathu = abspath def upath(path): - """ - Always return a unicode path. - """ + """Always return a unicode path (did something for Python 2).""" return path def npath(path): """ Always return a native path, that is unicode on Python 3 and bytestring on - Python 2. + Python 2. Noop for Python 3. """ return path @@ -33,8 +32,8 @@ def safe_join(base, *paths): """ base = force_text(base) paths = [force_text(p) for p in paths] - final_path = abspathu(join(base, *paths)) - base_path = abspathu(base) + final_path = abspath(join(base, *paths)) + base_path = abspath(base) # Ensure final_path starts with base_path (using normcase to ensure we # don't false-negative on case insensitive operating systems like Windows), # further, one of the following conditions must be true: diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py index d6a5b1a319af..6255da1c8443 100644 --- a/django/utils/autoreload.py +++ b/django/utils/autoreload.py @@ -41,7 +41,6 @@ from django.conf import settings from django.core.signals import request_finished from django.utils import six -from django.utils._os import npath # This import does nothing, but it's necessary to avoid some race conditions # in the threading module. See http://code.djangoproject.com/ticket/2330 . @@ -111,7 +110,7 @@ def gen_filenames(only_new=False): 'conf', 'locale'), 'locale'] for app_config in reversed(list(apps.get_app_configs())): - basedirs.append(os.path.join(npath(app_config.path), 'locale')) + basedirs.append(os.path.join(app_config.path, 'locale')) basedirs.extend(settings.LOCALE_PATHS) basedirs = [os.path.abspath(basedir) for basedir in basedirs if os.path.isdir(basedir)] diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py index 99acda9aabc5..14bb0ce786ec 100644 --- a/django/utils/translation/trans_real.py +++ b/django/utils/translation/trans_real.py @@ -14,7 +14,6 @@ from django.core.exceptions import AppRegistryNotReady from django.core.signals import setting_changed from django.dispatch import receiver -from django.utils._os import upath from django.utils.encoding import force_text from django.utils.safestring import SafeData, mark_safe from django.utils.translation import LANGUAGE_SESSION_KEY @@ -155,7 +154,7 @@ def _new_gnu_trans(self, localedir, use_null_fallback=True): def _init_translation_catalog(self): """Creates a base catalog using global django translations.""" - settingsfile = upath(sys.modules[settings.__module__].__file__) + settingsfile = sys.modules[settings.__module__].__file__ localedir = os.path.join(os.path.dirname(settingsfile), 'locale') translation = self._new_gnu_trans(localedir) self.merge(translation) @@ -399,7 +398,7 @@ def all_locale_paths(): Returns a list of paths to user-provides languages files. """ globalpath = os.path.join( - os.path.dirname(upath(sys.modules[settings.__module__].__file__)), 'locale') + os.path.dirname(sys.modules[settings.__module__].__file__), 'locale') return [globalpath] + list(settings.LOCALE_PATHS) diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index 50e034e03e51..25e6487a0fb4 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -26,10 +26,9 @@ from django.test import ( LiveServerTestCase, SimpleTestCase, TestCase, mock, override_settings, ) -from django.utils._os import npath, upath from django.utils.encoding import force_text -custom_templates_dir = os.path.join(os.path.dirname(upath(__file__)), 'custom_templates') +custom_templates_dir = os.path.join(os.path.dirname(__file__), 'custom_templates') PY36 = sys.version_info >= (3, 6) SYSTEM_CHECK_MSG = 'System check identified no issues' @@ -128,7 +127,7 @@ def _ext_backend_paths(self): def run_test(self, script, args, settings_file=None, apps=None): base_dir = os.path.dirname(self.test_dir) # The base dir for Django's tests is one level up. - tests_dir = os.path.dirname(os.path.dirname(upath(__file__))) + tests_dir = os.path.dirname(os.path.dirname(__file__)) # The base dir for Django is one level above the test dir. We don't use # `import django` to figure that out, so we don't pick up a Django # from site-packages or similar. @@ -152,7 +151,7 @@ def run_test(self, script, args, settings_file=None, apps=None): python_path = [base_dir, django_dir, tests_dir] python_path.extend(ext_backend_base_dirs) # Use native strings for better compatibility - test_environ[str(python_path_var_name)] = npath(os.pathsep.join(python_path)) + test_environ[str(python_path_var_name)] = os.pathsep.join(python_path) test_environ[str('PYTHONWARNINGS')] = str('') # Move to the test directory and run @@ -168,7 +167,7 @@ def run_test(self, script, args, settings_file=None, apps=None): return out, err def run_django_admin(self, args, settings_file=None): - script_dir = os.path.abspath(os.path.join(os.path.dirname(upath(django.__file__)), 'bin')) + script_dir = os.path.abspath(os.path.join(os.path.dirname(django.__file__), 'bin')) return self.run_test(os.path.join(script_dir, 'django-admin.py'), args, settings_file) def run_manage(self, args, settings_file=None): @@ -178,7 +177,7 @@ def safe_remove(path): except OSError: pass - conf_dir = os.path.dirname(upath(conf.__file__)) + conf_dir = os.path.dirname(conf.__file__) template_manage_py = os.path.join(conf_dir, 'project_template', 'manage.py-tpl') test_manage_py = os.path.join(self.test_dir, 'manage.py') diff --git a/tests/admin_scripts/urls.py b/tests/admin_scripts/urls.py index d258641fbe31..edb5e1f3b007 100644 --- a/tests/admin_scripts/urls.py +++ b/tests/admin_scripts/urls.py @@ -1,10 +1,9 @@ import os from django.conf.urls import url -from django.utils._os import upath from django.views.static import serve -here = os.path.dirname(upath(__file__)) +here = os.path.dirname(__file__) urlpatterns = [ url(r'^custom_templates/(?P.*)$', serve, { diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index ae3ebdd54d4e..cd423f6a01b6 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -31,7 +31,6 @@ from django.test.utils import override_script_prefix, patch_logger from django.urls import NoReverseMatch, resolve, reverse from django.utils import formats, translation -from django.utils._os import upath from django.utils.cache import get_max_age from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_bytes, force_text, iri_to_uri @@ -919,8 +918,8 @@ def test_adminsite_display_site_url(self): # Put this app's and the shared tests templates dirs in DIRS to take precedence # over the admin's templates dir. 'DIRS': [ - os.path.join(os.path.dirname(upath(__file__)), 'templates'), - os.path.join(os.path.dirname(os.path.dirname(upath(__file__))), 'templates'), + os.path.join(os.path.dirname(__file__), 'templates'), + os.path.join(os.path.dirname(os.path.dirname(__file__)), 'templates'), ], 'APP_DIRS': True, 'OPTIONS': { diff --git a/tests/app_loading/tests.py b/tests/app_loading/tests.py index 021e711796b6..698ce563813a 100644 --- a/tests/app_loading/tests.py +++ b/tests/app_loading/tests.py @@ -3,13 +3,12 @@ from django.apps import apps from django.test import SimpleTestCase from django.test.utils import extend_sys_path -from django.utils._os import upath class EggLoadingTest(SimpleTestCase): def setUp(self): - self.egg_dir = '%s/eggs' % os.path.dirname(upath(__file__)) + self.egg_dir = '%s/eggs' % os.path.dirname(__file__) def tearDown(self): apps.clear_cache() diff --git a/tests/apps/namespace_package_base/nsapp/apps.py b/tests/apps/namespace_package_base/nsapp/apps.py index 3e864ae5b420..a878449bf9c1 100644 --- a/tests/apps/namespace_package_base/nsapp/apps.py +++ b/tests/apps/namespace_package_base/nsapp/apps.py @@ -1,9 +1,8 @@ import os from django.apps import AppConfig -from django.utils._os import upath class NSAppConfig(AppConfig): name = 'nsapp' - path = upath(os.path.dirname(__file__)) + path = os.path.dirname(__file__) diff --git a/tests/apps/tests.py b/tests/apps/tests.py index 0263af897f39..76bac55a83f4 100644 --- a/tests/apps/tests.py +++ b/tests/apps/tests.py @@ -7,7 +7,6 @@ from django.db import models from django.test import SimpleTestCase, override_settings from django.test.utils import extend_sys_path, isolate_apps -from django.utils._os import upath from .default_config_app.apps import CustomConfig from .models import SoAlternative, TotallyNormal, new_apps @@ -29,7 +28,7 @@ 'django.contrib.auth', ] + SOME_INSTALLED_APPS[2:] -HERE = os.path.dirname(upath(__file__)) +HERE = os.path.dirname(__file__) class AppsTests(SimpleTestCase): @@ -385,7 +384,7 @@ def test_single_path(self): with extend_sys_path(self.base_location): with self.settings(INSTALLED_APPS=['nsapp']): app_config = apps.get_app_config('nsapp') - self.assertEqual(app_config.path, upath(self.app_path)) + self.assertEqual(app_config.path, self.app_path) def test_multiple_paths(self): """ @@ -410,4 +409,4 @@ def test_multiple_paths_explicit_path(self): with extend_sys_path(self.base_location, self.other_location): with self.settings(INSTALLED_APPS=['nsapp.apps.NSAppConfig']): app_config = apps.get_app_config('nsapp') - self.assertEqual(app_config.path, upath(self.app_path)) + self.assertEqual(app_config.path, self.app_path) diff --git a/tests/auth_tests/settings.py b/tests/auth_tests/settings.py index 8c295387c430..9fd71dfe875a 100644 --- a/tests/auth_tests/settings.py +++ b/tests/auth_tests/settings.py @@ -1,7 +1,5 @@ import os -from django.utils._os import upath - AUTH_MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', @@ -9,7 +7,7 @@ AUTH_TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(os.path.dirname(upath(__file__)), 'templates')], + 'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ diff --git a/tests/auth_tests/test_validators.py b/tests/auth_tests/test_validators.py index 19d75c8d3006..e9dc1f7f3f54 100644 --- a/tests/auth_tests/test_validators.py +++ b/tests/auth_tests/test_validators.py @@ -13,7 +13,6 @@ from django.db import models from django.test import TestCase, override_settings from django.test.utils import isolate_apps -from django.utils._os import upath @override_settings(AUTH_PASSWORD_VALIDATORS=[ @@ -171,7 +170,7 @@ def test_validate(self): self.assertEqual(cm.exception.messages, [expected_error]) def test_validate_custom_list(self): - path = os.path.join(os.path.dirname(os.path.realpath(upath(__file__))), 'common-passwords-custom.txt') + path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'common-passwords-custom.txt') validator = CommonPasswordValidator(password_list_path=path) expected_error = "This password is too common." self.assertIsNone(validator.validate('a-safe-password')) diff --git a/tests/file_storage/tests.py b/tests/file_storage/tests.py index 7912eb7efa6f..d33ca67c337b 100644 --- a/tests/file_storage/tests.py +++ b/tests/file_storage/tests.py @@ -24,7 +24,6 @@ from django.test.utils import requires_tz_support from django.urls import NoReverseMatch, reverse_lazy from django.utils import timezone -from django.utils._os import upath from .models import Storage, temp_storage, temp_storage_location @@ -108,7 +107,7 @@ def test_empty_location(self): """ storage = self.storage_class(location='') self.assertEqual(storage.base_location, '') - self.assertEqual(storage.location, upath(os.getcwd())) + self.assertEqual(storage.location, os.getcwd()) def test_file_access_options(self): """ diff --git a/tests/files/tests.py b/tests/files/tests.py index 4515b1cab182..7323b6987e06 100644 --- a/tests/files/tests.py +++ b/tests/files/tests.py @@ -11,7 +11,6 @@ from django.core.files.temp import NamedTemporaryFile from django.core.files.uploadedfile import SimpleUploadedFile, UploadedFile from django.test import mock -from django.utils._os import upath try: from PIL import Image @@ -227,7 +226,7 @@ def catching_open(*args): images.open = catching_open try: - images.get_image_dimensions(os.path.join(os.path.dirname(upath(__file__)), "test1.png")) + images.get_image_dimensions(os.path.join(os.path.dirname(__file__), "test1.png")) finally: del images.open self.assertTrue(FileWrapper._closed) @@ -243,7 +242,7 @@ def test_multiple_calls(self): """ Multiple calls of get_image_dimensions() should return the same size. """ - img_path = os.path.join(os.path.dirname(upath(__file__)), "test.png") + img_path = os.path.join(os.path.dirname(__file__), "test.png") with open(img_path, 'rb') as fh: image = images.ImageFile(fh) image_pil = Image.open(fh) @@ -258,7 +257,7 @@ def test_bug_19457(self): Regression test for #19457 get_image_dimensions fails on some pngs, while Image.size is working good on them """ - img_path = os.path.join(os.path.dirname(upath(__file__)), "magic.png") + img_path = os.path.join(os.path.dirname(__file__), "magic.png") size = images.get_image_dimensions(img_path) with open(img_path, 'rb') as fh: self.assertEqual(size, Image.open(fh).size) @@ -275,7 +274,7 @@ def test_invalid_image(self): brokenimg.png is not a valid image and it has been generated by: $ echo "123" > brokenimg.png """ - img_path = os.path.join(os.path.dirname(upath(__file__)), "brokenimg.png") + img_path = os.path.join(os.path.dirname(__file__), "brokenimg.png") with open(img_path, 'rb') as fh: size = images.get_image_dimensions(fh) self.assertEqual(size, (None, None)) @@ -288,7 +287,7 @@ def test_valid_image(self): Emulates the Parser feed error. Since the error is raised on every feed attempt, the resulting image size should be invalid: (None, None). """ - img_path = os.path.join(os.path.dirname(upath(__file__)), "test.png") + img_path = os.path.join(os.path.dirname(__file__), "test.png") with mock.patch('PIL.ImageFile.Parser.feed', side_effect=struct.error): with open(img_path, 'rb') as fh: size = images.get_image_dimensions(fh) diff --git a/tests/fixtures_regress/tests.py b/tests/fixtures_regress/tests.py index 538fee55a253..3ca508499512 100644 --- a/tests/fixtures_regress/tests.py +++ b/tests/fixtures_regress/tests.py @@ -14,7 +14,6 @@ TestCase, TransactionTestCase, override_settings, skipIfDBFeature, skipUnlessDBFeature, ) -from django.utils._os import upath from .models import ( Absolute, Animal, Article, Book, Child, Circle1, Circle2, Circle3, @@ -26,7 +25,7 @@ Person, RefToNKChild, Store, Stuff, Thingy, Widget, ) -_cur_dir = os.path.dirname(os.path.abspath(upath(__file__))) +_cur_dir = os.path.dirname(os.path.abspath(__file__)) class TestFixtures(TestCase): @@ -142,7 +141,7 @@ def test_absolute_path(self): fixture directory. """ load_absolute_path = os.path.join( - os.path.dirname(upath(__file__)), + os.path.dirname(__file__), 'fixtures', 'absolute.json' ) diff --git a/tests/forms_tests/field_tests/test_filepathfield.py b/tests/forms_tests/field_tests/test_filepathfield.py index 71164b5b7ac5..cbdf97b4c23e 100644 --- a/tests/forms_tests/field_tests/test_filepathfield.py +++ b/tests/forms_tests/field_tests/test_filepathfield.py @@ -2,7 +2,6 @@ from django.forms import FilePathField, ValidationError, forms from django.test import SimpleTestCase -from django.utils._os import upath def fix_os_paths(x): @@ -19,13 +18,11 @@ def fix_os_paths(x): class FilePathFieldTest(SimpleTestCase): def test_filepathfield_1(self): - path = os.path.abspath(upath(forms.__file__)) - path = os.path.dirname(path) + '/' + path = os.path.dirname(os.path.abspath(forms.__file__)) + '/' self.assertTrue(fix_os_paths(path).endswith('/django/forms/')) def test_filepathfield_2(self): - path = upath(forms.__file__) - path = os.path.dirname(os.path.abspath(path)) + '/' + path = os.path.dirname(os.path.abspath(forms.__file__)) + '/' f = FilePathField(path=path) f.choices = [p for p in f.choices if p[0].endswith('.py')] f.choices.sort() @@ -49,8 +46,7 @@ def test_filepathfield_2(self): self.assertTrue(fix_os_paths(f.clean(path + 'fields.py')).endswith('/django/forms/fields.py')) def test_filepathfield_3(self): - path = upath(forms.__file__) - path = os.path.dirname(os.path.abspath(path)) + '/' + path = os.path.dirname(os.path.abspath(forms.__file__)) + '/' f = FilePathField(path=path, match=r'^.*?\.py$') f.choices.sort() expected = [ @@ -69,8 +65,7 @@ def test_filepathfield_3(self): self.assertTrue(got[0].endswith(exp[0])) def test_filepathfield_4(self): - path = os.path.abspath(upath(forms.__file__)) - path = os.path.dirname(path) + '/' + path = os.path.dirname(os.path.abspath(forms.__file__)) + '/' f = FilePathField(path=path, recursive=True, match=r'^.*?\.py$') f.choices.sort() expected = [ @@ -89,7 +84,7 @@ def test_filepathfield_4(self): self.assertTrue(got[0].endswith(exp[0])) def test_filepathfield_folders(self): - path = os.path.abspath(os.path.join(upath(__file__), '..', '..')) + '/tests/filepath_test_files/' + path = os.path.abspath(os.path.join(__file__, '..', '..')) + '/tests/filepath_test_files/' f = FilePathField(path=path, allow_folders=True, allow_files=False) f.choices.sort() expected = [ diff --git a/tests/forms_tests/field_tests/test_imagefield.py b/tests/forms_tests/field_tests/test_imagefield.py index 326735bf60d2..6fb4bed03cdb 100644 --- a/tests/forms_tests/field_tests/test_imagefield.py +++ b/tests/forms_tests/field_tests/test_imagefield.py @@ -4,7 +4,6 @@ from django.core.files.uploadedfile import SimpleUploadedFile from django.forms import ImageField from django.test import SimpleTestCase -from django.utils._os import upath try: from PIL import Image @@ -13,7 +12,7 @@ def get_img_path(path): - return os.path.join(os.path.abspath(os.path.join(upath(__file__), '..', '..')), 'tests', path) + return os.path.join(os.path.abspath(os.path.join(__file__, '..', '..')), 'tests', path) @unittest.skipUnless(Image, "Pillow is required to test ImageField") diff --git a/tests/forms_tests/tests/test_renderers.py b/tests/forms_tests/tests/test_renderers.py index df9c9cf367e0..47452fa489f3 100644 --- a/tests/forms_tests/tests/test_renderers.py +++ b/tests/forms_tests/tests/test_renderers.py @@ -5,7 +5,6 @@ BaseRenderer, DjangoTemplates, Jinja2, TemplatesSetting, ) from django.test import SimpleTestCase -from django.utils._os import upath try: import jinja2 @@ -23,12 +22,12 @@ def test_installed_apps_template_found(self): tpl = renderer.get_template('forms_tests/custom_widget.html') expected_path = os.path.abspath( os.path.join( - upath(os.path.dirname(__file__)), + os.path.dirname(__file__), '..', self.expected_widget_dir + '/forms_tests/custom_widget.html', ) ) - self.assertEqual(upath(tpl.origin.name), expected_path) + self.assertEqual(tpl.origin.name, expected_path) class BaseTemplateRendererTests(SimpleTestCase): diff --git a/tests/gis_tests/gdal_tests/test_raster.py b/tests/gis_tests/gdal_tests/test_raster.py index 1a2753c7171d..cd850af9a127 100644 --- a/tests/gis_tests/gdal_tests/test_raster.py +++ b/tests/gis_tests/gdal_tests/test_raster.py @@ -49,7 +49,6 @@ from django.contrib.gis.gdal.error import GDALException from django.contrib.gis.shortcuts import numpy from django.test import SimpleTestCase -from django.utils._os import upath from ..data.rasters.textrasters import JSON_RASTER @@ -64,8 +63,7 @@ class GDALRasterTests(SimpleTestCase): Test a GDALRaster instance created from a file (GeoTiff). """ def setUp(self): - self.rs_path = os.path.join(os.path.dirname(upath(__file__)), - '../data/rasters/raster.tif') + self.rs_path = os.path.join(os.path.dirname(__file__), '../data/rasters/raster.tif') self.rs = GDALRaster(self.rs_path) def test_rs_name_repr(self): @@ -388,7 +386,7 @@ def test_raster_transform(self): @unittest.skipUnless(HAS_GDAL, "GDAL is required") class GDALBandTests(SimpleTestCase): def setUp(self): - self.rs_path = os.path.join(os.path.dirname(upath(__file__)), '../data/rasters/raster.tif') + self.rs_path = os.path.join(os.path.dirname(__file__), '../data/rasters/raster.tif') rs = GDALRaster(self.rs_path) self.band = rs.bands[0] @@ -403,7 +401,7 @@ def test_band_data(self): if numpy: data = self.band.data() assert_array = numpy.loadtxt( - os.path.join(os.path.dirname(upath(__file__)), '../data/rasters/raster.numpy.txt') + os.path.join(os.path.dirname(__file__), '../data/rasters/raster.numpy.txt') ) numpy.testing.assert_equal(data, assert_array) self.assertEqual(data.shape, (self.band.height, self.band.width)) diff --git a/tests/gis_tests/geo3d/tests.py b/tests/gis_tests/geo3d/tests.py index 72be66401402..f05e2e35ce98 100644 --- a/tests/gis_tests/geo3d/tests.py +++ b/tests/gis_tests/geo3d/tests.py @@ -7,14 +7,13 @@ ) from django.contrib.gis.geos import GEOSGeometry, LineString, Point, Polygon from django.test import TestCase, skipUnlessDBFeature -from django.utils._os import upath from .models import ( City3D, Interstate2D, Interstate3D, InterstateProj2D, InterstateProj3D, MultiPoint3D, Point2D, Point3D, Polygon2D, Polygon3D, ) -data_path = os.path.realpath(os.path.join(os.path.dirname(upath(__file__)), '..', 'data')) +data_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'data')) city_file = os.path.join(data_path, 'cities', 'cities.shp') vrt_file = os.path.join(data_path, 'test_vrt', 'test_vrt.vrt') diff --git a/tests/gis_tests/geogapp/tests.py b/tests/gis_tests/geogapp/tests.py index 7112f0238eb0..551fda4b833a 100644 --- a/tests/gis_tests/geogapp/tests.py +++ b/tests/gis_tests/geogapp/tests.py @@ -10,7 +10,6 @@ from django.db import connection from django.db.models.functions import Cast from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature -from django.utils._os import upath from ..utils import oracle, postgis, spatialite from .models import City, County, Zipcode @@ -66,7 +65,7 @@ def test05_geography_layermapping(self): from django.contrib.gis.utils import LayerMapping # Getting the shapefile and mapping dictionary. - shp_path = os.path.realpath(os.path.join(os.path.dirname(upath(__file__)), '..', 'data')) + shp_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'data')) co_shp = os.path.join(shp_path, 'counties', 'counties.shp') co_mapping = {'name': 'Name', 'state': 'State', diff --git a/tests/gis_tests/layermap/tests.py b/tests/gis_tests/layermap/tests.py index ce4b0c90d543..82bc534fbfa3 100644 --- a/tests/gis_tests/layermap/tests.py +++ b/tests/gis_tests/layermap/tests.py @@ -8,7 +8,6 @@ from django.contrib.gis.geos import HAS_GEOS from django.db import connection from django.test import TestCase, override_settings, skipUnlessDBFeature -from django.utils._os import upath if HAS_GEOS and HAS_GDAL: from django.contrib.gis.utils.layermapping import ( @@ -23,7 +22,7 @@ ) -shp_path = os.path.realpath(os.path.join(os.path.dirname(upath(__file__)), os.pardir, 'data')) +shp_path = os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir, 'data')) city_shp = os.path.join(shp_path, 'cities', 'cities.shp') co_shp = os.path.join(shp_path, 'counties', 'counties.shp') inter_shp = os.path.join(shp_path, 'interstates', 'interstates.shp') diff --git a/tests/gis_tests/test_data.py b/tests/gis_tests/test_data.py index 23df42c00792..4bec3c677e1c 100644 --- a/tests/gis_tests/test_data.py +++ b/tests/gis_tests/test_data.py @@ -5,11 +5,10 @@ import json import os -from django.utils._os import upath from django.utils.functional import cached_property # Path where reference test data is located. -TEST_DATA = os.path.join(os.path.dirname(upath(__file__)), 'data') +TEST_DATA = os.path.join(os.path.dirname(__file__), 'data') def tuplize(seq): diff --git a/tests/httpwrappers/tests.py b/tests/httpwrappers/tests.py index fe2ad1a216ab..612cbb45ef52 100644 --- a/tests/httpwrappers/tests.py +++ b/tests/httpwrappers/tests.py @@ -16,7 +16,6 @@ StreamingHttpResponse, parse_cookie, ) from django.test import SimpleTestCase -from django.utils._os import upath from django.utils.functional import lazystr @@ -634,7 +633,7 @@ def tearDown(self): request_finished.connect(close_old_connections) def test_response(self): - filename = os.path.join(os.path.dirname(upath(__file__)), 'abc.txt') + filename = os.path.join(os.path.dirname(__file__), 'abc.txt') # file isn't closed until we close the response. file1 = open(filename) @@ -652,7 +651,7 @@ def test_response(self): self.assertTrue(file2.closed) def test_streaming_response(self): - filename = os.path.join(os.path.dirname(upath(__file__)), 'abc.txt') + filename = os.path.join(os.path.dirname(__file__), 'abc.txt') # file isn't closed until we close the response. file1 = open(filename) diff --git a/tests/i18n/contenttypes/tests.py b/tests/i18n/contenttypes/tests.py index 94f355aba75a..e2b715769222 100644 --- a/tests/i18n/contenttypes/tests.py +++ b/tests/i18n/contenttypes/tests.py @@ -3,13 +3,12 @@ from django.contrib.contenttypes.models import ContentType from django.test import TestCase, override_settings from django.utils import translation -from django.utils._os import upath @override_settings( USE_I18N=True, LOCALE_PATHS=[ - os.path.join(os.path.dirname(upath(__file__)), 'locale'), + os.path.join(os.path.dirname(__file__), 'locale'), ], LANGUAGE_CODE='en', LANGUAGES=[ diff --git a/tests/i18n/patterns/tests.py b/tests/i18n/patterns/tests.py index a889125e82b8..35b879d11a29 100644 --- a/tests/i18n/patterns/tests.py +++ b/tests/i18n/patterns/tests.py @@ -10,7 +10,6 @@ from django.test.utils import override_script_prefix from django.urls import clear_url_caches, reverse, translate_url from django.utils import translation -from django.utils._os import upath class PermanentRedirectLocaleMiddleWare(LocaleMiddleware): @@ -20,7 +19,7 @@ class PermanentRedirectLocaleMiddleWare(LocaleMiddleware): @override_settings( USE_I18N=True, LOCALE_PATHS=[ - os.path.join(os.path.dirname(upath(__file__)), 'locale'), + os.path.join(os.path.dirname(__file__), 'locale'), ], LANGUAGE_CODE='en-us', LANGUAGES=[ @@ -35,7 +34,7 @@ class PermanentRedirectLocaleMiddleWare(LocaleMiddleware): ROOT_URLCONF='i18n.patterns.urls.default', TEMPLATES=[{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(os.path.dirname(upath(__file__)), 'templates')], + 'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')], 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.i18n', diff --git a/tests/i18n/test_percents.py b/tests/i18n/test_percents.py index 48d62ada05b1..22ea73b790e6 100644 --- a/tests/i18n/test_percents.py +++ b/tests/i18n/test_percents.py @@ -2,13 +2,12 @@ from django.template import Context, Template from django.test import SimpleTestCase, override_settings -from django.utils._os import upath from django.utils.encoding import force_text from django.utils.translation import activate, get_language, trans_real from .utils import POFileAssertionMixin -SAMPLEPROJECT_DIR = os.path.join(os.path.dirname(os.path.abspath(upath(__file__))), 'sampleproject') +SAMPLEPROJECT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'sampleproject') SAMPLEPROJECT_LOCALE = os.path.join(SAMPLEPROJECT_DIR, 'locale') diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py index c3acdfe2fc4a..181de62bea4f 100644 --- a/tests/i18n/tests.py +++ b/tests/i18n/tests.py @@ -15,7 +15,6 @@ RequestFactory, SimpleTestCase, TestCase, override_settings, ) from django.utils import translation -from django.utils._os import upath from django.utils.formats import ( date_format, get_format, get_format_modules, iter_format_modules, localize, localize_input, reset_format_cache, sanitize_separators, time_format, @@ -32,7 +31,7 @@ from .forms import CompanyForm, I18nForm, SelectDateForm from .models import Company, TestModel -here = os.path.dirname(os.path.abspath(upath(__file__))) +here = os.path.dirname(os.path.abspath(__file__)) extended_locale_paths = settings.LOCALE_PATHS + [ os.path.join(here, 'other', 'locale'), ] diff --git a/tests/i18n/utils.py b/tests/i18n/utils.py index b2267cd3eb96..2bf4f3e63e7c 100644 --- a/tests/i18n/utils.py +++ b/tests/i18n/utils.py @@ -3,9 +3,7 @@ import shutil import tempfile -from django.utils._os import upath - -source_code_dir = os.path.dirname(upath(__file__)) +source_code_dir = os.path.dirname(__file__) def copytree(src, dst): diff --git a/tests/mail/tests.py b/tests/mail/tests.py index 8ba4d6442384..8019f3ccf882 100644 --- a/tests/mail/tests.py +++ b/tests/mail/tests.py @@ -25,7 +25,6 @@ from django.core.mail.message import BadHeaderError, sanitize_address from django.test import SimpleTestCase, override_settings from django.test.utils import requires_tz_support -from django.utils._os import upath from django.utils.encoding import force_bytes, force_text from django.utils.translation import ugettext_lazy @@ -411,7 +410,7 @@ def test_attach_file(self): email = EmailMessage('subject', 'body', 'from@example.com', ['to@example.com']) self.assertEqual(mimetypes.guess_type(basename)[0], real_mimetype) self.assertEqual(email.attachments, []) - file_path = os.path.join(os.path.dirname(upath(__file__)), 'attachments', basename) + file_path = os.path.join(os.path.dirname(__file__), 'attachments', basename) email.attach_file(file_path, mimetype=mimetype) self.assertEqual(len(email.attachments), 1) self.assertIn(basename, email.attachments[0]) diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index 83de774aee80..0528583fccd2 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -22,7 +22,6 @@ ) from django.test import SimpleTestCase, ignore_warnings, mock from django.utils import datetime_safe -from django.utils._os import upath from django.utils.deconstruct import deconstructible from django.utils.functional import SimpleLazyObject from django.utils.timezone import FixedOffset, get_default_timezone, utc @@ -576,7 +575,7 @@ def test_migration_path(self): 'migrations.migrations_test_apps.without_init_file', ] - base_dir = os.path.dirname(os.path.dirname(upath(__file__))) + base_dir = os.path.dirname(os.path.dirname(__file__)) for app in test_apps: with self.modify_settings(INSTALLED_APPS={'append': app}): diff --git a/tests/model_fields/test_imagefield.py b/tests/model_fields/test_imagefield.py index 92985a99d967..96fa8c839b15 100644 --- a/tests/model_fields/test_imagefield.py +++ b/tests/model_fields/test_imagefield.py @@ -7,7 +7,6 @@ from django.core.files.images import ImageFile from django.test import TestCase from django.test.testcases import SerializeMixin -from django.utils._os import upath try: from .models import Image @@ -51,10 +50,10 @@ def setUp(self): shutil.rmtree(temp_storage_dir) os.mkdir(temp_storage_dir) - file_path1 = os.path.join(os.path.dirname(upath(__file__)), "4x8.png") + file_path1 = os.path.join(os.path.dirname(__file__), '4x8.png') self.file1 = self.File(open(file_path1, 'rb'), name='4x8.png') - file_path2 = os.path.join(os.path.dirname(upath(__file__)), "8x4.png") + file_path2 = os.path.join(os.path.dirname(__file__), '8x4.png') self.file2 = self.File(open(file_path2, 'rb'), name='8x4.png') def tearDown(self): diff --git a/tests/model_forms/models.py b/tests/model_forms/models.py index f85ae8e1fda6..c1c97270fc37 100644 --- a/tests/model_forms/models.py +++ b/tests/model_forms/models.py @@ -15,7 +15,6 @@ from django.core.exceptions import ValidationError from django.core.files.storage import FileSystemStorage from django.db import models -from django.utils._os import upath temp_storage_dir = tempfile.mkdtemp() temp_storage = FileSystemStorage(temp_storage_dir) @@ -160,7 +159,7 @@ class CustomFF(models.Model): class FilePathModel(models.Model): - path = models.FilePathField(path=os.path.dirname(upath(__file__)), match=r".*\.py$", blank=True) + path = models.FilePathField(path=os.path.dirname(__file__), match=r".*\.py$", blank=True) try: diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index 108c91758744..3c8f7ed10866 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -17,7 +17,6 @@ ) from django.template import Context, Template from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature -from django.utils._os import upath from .models import ( Article, ArticleStatus, Author, Author1, Award, BetterWriter, BigInt, Book, @@ -2221,7 +2220,7 @@ class Meta: fields = '__all__' # Grab an image for testing. - filename = os.path.join(os.path.dirname(upath(__file__)), "test.png") + filename = os.path.join(os.path.dirname(__file__), 'test.png') with open(filename, "rb") as fp: img = fp.read() @@ -2260,9 +2259,9 @@ def test_image_field(self): # it comes to validation. This specifically tests that #6302 is fixed for # both file fields and image fields. - with open(os.path.join(os.path.dirname(upath(__file__)), "test.png"), 'rb') as fp: + with open(os.path.join(os.path.dirname(__file__), 'test.png'), 'rb') as fp: image_data = fp.read() - with open(os.path.join(os.path.dirname(upath(__file__)), "test2.png"), 'rb') as fp: + with open(os.path.join(os.path.dirname(__file__), 'test2.png'), 'rb') as fp: image_data2 = fp.read() f = ImageFileForm( diff --git a/tests/project_template/test_settings.py b/tests/project_template/test_settings.py index 5623df320b5c..50fa31d8f3a9 100644 --- a/tests/project_template/test_settings.py +++ b/tests/project_template/test_settings.py @@ -3,14 +3,13 @@ from django import conf from django.test import TestCase -from django.utils._os import upath class TestStartProjectSettings(TestCase): def setUp(self): # Ensure settings.py exists project_dir = os.path.join( - os.path.dirname(upath(conf.__file__)), + os.path.dirname(conf.__file__), 'project_template', 'project_name', ) diff --git a/tests/proxy_model_inheritance/tests.py b/tests/proxy_model_inheritance/tests.py index 9bf8f1c04c5d..9fb5f4e92465 100644 --- a/tests/proxy_model_inheritance/tests.py +++ b/tests/proxy_model_inheritance/tests.py @@ -3,7 +3,6 @@ from django.core.management import call_command from django.test import TestCase, TransactionTestCase from django.test.utils import extend_sys_path -from django.utils._os import upath from .models import ( ConcreteModel, ConcreteModelSubclass, ConcreteModelSubclassProxy, @@ -20,7 +19,7 @@ class ProxyModelInheritanceTests(TransactionTestCase): available_apps = [] def test_table_exists(self): - with extend_sys_path(os.path.dirname(os.path.abspath(upath(__file__)))): + with extend_sys_path(os.path.dirname(os.path.abspath(__file__))): with self.modify_settings(INSTALLED_APPS={'append': ['app1', 'app2']}): call_command('migrate', verbosity=0, run_syncdb=True) from app1.models import ProxyModel diff --git a/tests/runtests.py b/tests/runtests.py index 6e86bf7a93b4..57ba84d3db46 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -17,7 +17,6 @@ from django.test.runner import default_test_processes from django.test.selenium import SeleniumTestCaseBase from django.test.utils import get_runner -from django.utils._os import upath from django.utils.deprecation import ( RemovedInDjango21Warning, RemovedInDjango30Warning, ) @@ -31,7 +30,7 @@ # Ignore known warnings in test dependencies. warnings.filterwarnings("ignore", "'U' mode is deprecated", DeprecationWarning, module='docutils.io') -RUNTESTS_DIR = os.path.abspath(os.path.dirname(upath(__file__))) +RUNTESTS_DIR = os.path.abspath(os.path.dirname(__file__)) TEMPLATE_DIR = os.path.join(RUNTESTS_DIR, 'templates') @@ -276,7 +275,7 @@ def django_tests(verbosity, interactive, failfast, keepdb, reverse, def get_subprocess_args(options): subprocess_args = [ - sys.executable, upath(__file__), '--settings=%s' % options.settings + sys.executable, __file__, '--settings=%s' % options.settings ] if options.failfast: subprocess_args.append('--failfast') diff --git a/tests/servers/tests.py b/tests/servers/tests.py index 82c9bea49380..d6d0392bcddf 100644 --- a/tests/servers/tests.py +++ b/tests/servers/tests.py @@ -8,12 +8,11 @@ from urllib.request import urlopen from django.test import LiveServerTestCase, override_settings -from django.utils._os import upath from django.utils.http import urlencode from .models import Person -TEST_ROOT = os.path.dirname(upath(__file__)) +TEST_ROOT = os.path.dirname(__file__) TEST_SETTINGS = { 'MEDIA_URL': '/media/', 'MEDIA_ROOT': os.path.join(TEST_ROOT, 'media'), diff --git a/tests/sitemaps_tests/test_http.py b/tests/sitemaps_tests/test_http.py index ec7d2be80f5d..a93d87916401 100644 --- a/tests/sitemaps_tests/test_http.py +++ b/tests/sitemaps_tests/test_http.py @@ -8,7 +8,6 @@ from django.contrib.sites.models import Site from django.core.exceptions import ImproperlyConfigured from django.test import modify_settings, override_settings -from django.utils._os import upath from django.utils.formats import localize from django.utils.translation import activate, deactivate @@ -30,7 +29,7 @@ def test_simple_sitemap_index(self): @override_settings(TEMPLATES=[{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(os.path.dirname(upath(__file__)), 'templates')], + 'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')], }]) def test_simple_sitemap_custom_index(self): "A simple sitemap index can be rendered with a custom template" @@ -65,7 +64,7 @@ def test_simple_sitemap(self): @override_settings(TEMPLATES=[{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(os.path.dirname(upath(__file__)), 'templates')], + 'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')], }]) def test_simple_custom_sitemap(self): "A simple sitemap can be rendered with a custom template" diff --git a/tests/staticfiles_tests/settings.py b/tests/staticfiles_tests/settings.py index c9bf851db7d2..0c944b8191b6 100644 --- a/tests/staticfiles_tests/settings.py +++ b/tests/staticfiles_tests/settings.py @@ -1,8 +1,6 @@ import os.path -from django.utils._os import upath - -TEST_ROOT = os.path.dirname(upath(__file__)) +TEST_ROOT = os.path.dirname(__file__) TEST_SETTINGS = { 'MEDIA_URL': '/media/', diff --git a/tests/staticfiles_tests/test_liveserver.py b/tests/staticfiles_tests/test_liveserver.py index 717de5cf6416..f45a95ba890a 100644 --- a/tests/staticfiles_tests/test_liveserver.py +++ b/tests/staticfiles_tests/test_liveserver.py @@ -10,9 +10,8 @@ from django.contrib.staticfiles.testing import StaticLiveServerTestCase from django.core.exceptions import ImproperlyConfigured from django.test import modify_settings, override_settings -from django.utils._os import upath -TEST_ROOT = os.path.dirname(upath(__file__)) +TEST_ROOT = os.path.dirname(__file__) TEST_SETTINGS = { 'MEDIA_URL': '/media/', 'STATIC_URL': '/static/', diff --git a/tests/template_tests/syntax_tests/i18n/base.py b/tests/template_tests/syntax_tests/i18n/base.py index 690e5d3933ea..61d2bbdb1c97 100644 --- a/tests/template_tests/syntax_tests/i18n/base.py +++ b/tests/template_tests/syntax_tests/i18n/base.py @@ -2,10 +2,9 @@ from django.conf import settings from django.test import SimpleTestCase -from django.utils._os import upath from django.utils.translation import activate, get_language -here = os.path.dirname(os.path.dirname(os.path.abspath(upath(__file__)))) +here = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) pdir = os.path.split(os.path.split(os.path.abspath(here))[0])[0] extended_locale_paths = settings.LOCALE_PATHS + [ os.path.join(pdir, 'i18n', 'other', 'locale'), diff --git a/tests/template_tests/utils.py b/tests/template_tests/utils.py index 8ee66a65239a..e2a9305b5ef9 100644 --- a/tests/template_tests/utils.py +++ b/tests/template_tests/utils.py @@ -3,10 +3,9 @@ from django.template.engine import Engine from django.test.utils import override_settings -from django.utils._os import upath from django.utils.safestring import mark_safe -ROOT = os.path.dirname(os.path.abspath(upath(__file__))) +ROOT = os.path.dirname(os.path.abspath(__file__)) TEMPLATE_DIR = os.path.join(ROOT, 'templates') diff --git a/tests/test_client_regress/tests.py b/tests/test_client_regress/tests.py index 16b344e0ae64..4589ac33bd0b 100644 --- a/tests/test_client_regress/tests.py +++ b/tests/test_client_regress/tests.py @@ -17,7 +17,6 @@ from django.test.client import RedirectCycleError, RequestFactory, encode_file from django.test.utils import ContextList, str_prefix from django.urls import NoReverseMatch, reverse -from django.utils._os import upath from django.utils.translation import ugettext_lazy from .models import CustomUser @@ -874,7 +873,7 @@ class TemplateExceptionTests(SimpleTestCase): @override_settings(TEMPLATES=[{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(os.path.dirname(upath(__file__)), 'bad_templates')], + 'DIRS': [os.path.join(os.path.dirname(__file__), 'bad_templates')], }]) def test_bad_404_template(self): "Errors found when rendering 404 error templates are re-raised" diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py index b1c35d1f807a..ea094bbd5530 100644 --- a/tests/test_utils/tests.py +++ b/tests/test_utils/tests.py @@ -1,3 +1,4 @@ +import os import sys import unittest from io import StringIO @@ -19,7 +20,6 @@ setup_test_environment, ) from django.urls import NoReverseMatch, reverse -from django.utils._os import abspathu from .models import Car, Person, PossessedCar from .views import empty_response @@ -968,7 +968,7 @@ def test_override_static_root(self): django.contrib.staticfiles.storage.staticfiles_storage. """ with self.settings(STATIC_ROOT='/tmp/test'): - self.assertEqual(staticfiles_storage.location, abspathu('/tmp/test')) + self.assertEqual(staticfiles_storage.location, os.path.abspath('/tmp/test')) def test_override_staticfiles_storage(self): """ diff --git a/tests/urlpatterns_reverse/test_localeregexprovider.py b/tests/urlpatterns_reverse/test_localeregexprovider.py index 53dc744c772c..f05c446eb905 100644 --- a/tests/urlpatterns_reverse/test_localeregexprovider.py +++ b/tests/urlpatterns_reverse/test_localeregexprovider.py @@ -5,9 +5,8 @@ from django.urls import LocaleRegexProvider from django.urls.resolvers import LocaleRegexDescriptor from django.utils import translation -from django.utils._os import upath -here = os.path.dirname(upath(os.path.abspath(__file__))) +here = os.path.dirname(os.path.abspath(__file__)) @override_settings(LOCALE_PATHS=[os.path.join(here, 'translations', 'locale')]) diff --git a/tests/user_commands/tests.py b/tests/user_commands/tests.py index cfc4f5fb2e56..a18d49868bd4 100644 --- a/tests/user_commands/tests.py +++ b/tests/user_commands/tests.py @@ -11,7 +11,6 @@ from django.test import SimpleTestCase, mock, override_settings from django.test.utils import captured_stderr, extend_sys_path from django.utils import translation -from django.utils._os import upath from .management.commands import dance @@ -92,7 +91,7 @@ def test_discover_commands_in_eggs(self): """ Management commands can also be loaded from Python eggs. """ - egg_dir = '%s/eggs' % os.path.dirname(upath(__file__)) + egg_dir = '%s/eggs' % os.path.dirname(__file__) egg_name = '%s/basic.egg' % egg_dir with extend_sys_path(egg_name): with self.settings(INSTALLED_APPS=['commandegg']): diff --git a/tests/utils_tests/test_archive.py b/tests/utils_tests/test_archive.py index f50e18d75c7e..d58d211ae5f1 100644 --- a/tests/utils_tests/test_archive.py +++ b/tests/utils_tests/test_archive.py @@ -5,10 +5,9 @@ import tempfile import unittest -from django.utils._os import upath from django.utils.archive import Archive, extract -TEST_DIR = os.path.join(os.path.dirname(upath(__file__)), 'archives') +TEST_DIR = os.path.join(os.path.dirname(__file__), 'archives') class ArchiveTester: diff --git a/tests/utils_tests/test_autoreload.py b/tests/utils_tests/test_autoreload.py index 4036df8dd84a..6925da1834a7 100644 --- a/tests/utils_tests/test_autoreload.py +++ b/tests/utils_tests/test_autoreload.py @@ -11,7 +11,6 @@ from django.test import SimpleTestCase, mock, override_settings from django.test.utils import extend_sys_path from django.utils import autoreload -from django.utils._os import npath from django.utils.translation import trans_real LOCALE_PATH = os.path.join(os.path.dirname(__file__), 'locale') @@ -26,23 +25,23 @@ def clear_autoreload_caches(self): def assertFileFound(self, filename): self.clear_autoreload_caches() # Test uncached access - self.assertIn(npath(filename), autoreload.gen_filenames()) + self.assertIn(filename, autoreload.gen_filenames()) # Test cached access - self.assertIn(npath(filename), autoreload.gen_filenames()) + self.assertIn(filename, autoreload.gen_filenames()) def assertFileNotFound(self, filename): self.clear_autoreload_caches() # Test uncached access - self.assertNotIn(npath(filename), autoreload.gen_filenames()) + self.assertNotIn(filename, autoreload.gen_filenames()) # Test cached access - self.assertNotIn(npath(filename), autoreload.gen_filenames()) + self.assertNotIn(filename, autoreload.gen_filenames()) def assertFileFoundOnlyNew(self, filename): self.clear_autoreload_caches() # Test uncached access - self.assertIn(npath(filename), autoreload.gen_filenames(only_new=True)) + self.assertIn(filename, autoreload.gen_filenames(only_new=True)) # Test cached access - self.assertNotIn(npath(filename), autoreload.gen_filenames(only_new=True)) + self.assertNotIn(filename, autoreload.gen_filenames(only_new=True)) def test_django_locales(self): """ @@ -122,7 +121,7 @@ def test_only_new_files(self): with extend_sys_path(dirname): import_module('test_only_new_module') filenames = set(autoreload.gen_filenames(only_new=True)) - self.assertEqual(filenames, {npath(filename)}) + self.assertEqual(filenames, {filename}) def test_deleted_removed(self): """ diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py index 5ffccdae83c6..c2a64699cb1b 100644 --- a/tests/utils_tests/test_html.py +++ b/tests/utils_tests/test_html.py @@ -3,7 +3,6 @@ from django.test import SimpleTestCase from django.utils import html, safestring -from django.utils._os import upath from django.utils.encoding import force_text from django.utils.functional import lazystr @@ -98,7 +97,7 @@ def test_strip_tags(self): # Test with more lengthy content (also catching performance regressions) for filename in ('strip_tags1.html', 'strip_tags2.txt'): - path = os.path.join(os.path.dirname(upath(__file__)), 'files', filename) + path = os.path.join(os.path.dirname(__file__), 'files', filename) with open(path, 'r') as fp: content = force_text(fp.read()) start = datetime.now() diff --git a/tests/utils_tests/test_module_loading.py b/tests/utils_tests/test_module_loading.py index 8e6806e8d571..ad1135aa1987 100644 --- a/tests/utils_tests/test_module_loading.py +++ b/tests/utils_tests/test_module_loading.py @@ -7,7 +7,6 @@ from django.test import SimpleTestCase, TestCase, modify_settings from django.test.utils import extend_sys_path -from django.utils._os import upath from django.utils.module_loading import ( autodiscover_modules, import_string, module_has_submodule, ) @@ -58,7 +57,7 @@ def test_loader(self): class EggLoader(unittest.TestCase): def setUp(self): - self.egg_dir = '%s/eggs' % os.path.dirname(upath(__file__)) + self.egg_dir = '%s/eggs' % os.path.dirname(__file__) def tearDown(self): sys.path_importer_cache.clear() diff --git a/tests/validators/tests.py b/tests/validators/tests.py index 2f26efcaa5a0..124c2b1c6810 100644 --- a/tests/validators/tests.py +++ b/tests/validators/tests.py @@ -17,7 +17,6 @@ ) from django.test import SimpleTestCase from django.test.utils import str_prefix -from django.utils._os import upath try: from PIL import Image # noqa @@ -263,7 +262,7 @@ def create_path(filename): - return os.path.abspath(os.path.join(os.path.dirname(upath(__file__)), filename)) + return os.path.abspath(os.path.join(os.path.dirname(__file__), filename)) # Add valid and invalid URL tests. diff --git a/tests/view_tests/tests/test_i18n.py b/tests/view_tests/tests/test_i18n.py index d330b60ff7b2..f9c49ad3bb56 100644 --- a/tests/view_tests/tests/test_i18n.py +++ b/tests/view_tests/tests/test_i18n.py @@ -8,7 +8,6 @@ ) from django.test.selenium import SeleniumTestCase from django.urls import reverse -from django.utils._os import upath from django.utils.translation import ( LANGUAGE_SESSION_KEY, get_language, override, ) @@ -373,7 +372,7 @@ def test_i18n_different_non_english_languages(self): def test_i18n_with_locale_paths(self): extended_locale_paths = settings.LOCALE_PATHS + [ path.join( - path.dirname(path.dirname(path.abspath(upath(__file__)))), + path.dirname(path.dirname(path.abspath(__file__))), 'app3', 'locale', ), diff --git a/tests/view_tests/urls.py b/tests/view_tests/urls.py index c536ea78edd5..c046336b7f0c 100644 --- a/tests/view_tests/urls.py +++ b/tests/view_tests/urls.py @@ -3,13 +3,12 @@ from django.conf.urls import include, url from django.conf.urls.i18n import i18n_patterns -from django.utils._os import upath from django.utils.translation import ugettext_lazy as _ from django.views import defaults, i18n, static from . import views -base_dir = path.dirname(path.abspath(upath(__file__))) +base_dir = path.dirname(path.abspath(__file__)) media_dir = path.join(base_dir, 'media') locale_dir = path.join(base_dir, 'locale') From 042b7350a080cc964f913faf1cf7f0097f650a58 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Fri, 20 Jan 2017 10:20:53 +0100 Subject: [PATCH 0089/3180] Refs #23919 -- Removed unneeded str() calls --- django/contrib/gis/admin/widgets.py | 2 +- .../gis/db/backends/postgis/adapter.py | 4 +-- django/contrib/gis/db/models/functions.py | 2 +- django/contrib/gis/gdal/datasource.py | 2 +- django/contrib/gis/gdal/driver.py | 4 +-- django/contrib/gis/gdal/envelope.py | 4 +-- django/contrib/gis/gdal/geometries.py | 4 +-- django/contrib/gis/geos/coordseq.py | 2 +- django/contrib/gis/geos/geometry.py | 2 +- django/contrib/gis/geos/mutable_list.py | 4 +-- django/contrib/gis/geos/point.py | 2 +- django/core/handlers/wsgi.py | 8 ++--- django/core/mail/message.py | 2 +- .../core/management/commands/makemessages.py | 8 ++--- django/core/management/commands/runserver.py | 2 +- django/core/servers/basehttp.py | 2 +- django/db/backends/sqlite3/base.py | 14 ++++----- django/db/models/base.py | 8 ++--- django/db/models/fields/__init__.py | 6 ++-- django/db/models/fields/files.py | 2 +- django/db/models/indexes.py | 2 +- django/http/cookie.py | 8 ++--- django/http/request.py | 4 +-- django/http/response.py | 3 +- django/test/client.py | 24 +++++++------- django/test/selenium.py | 2 +- django/urls/resolvers.py | 2 +- django/utils/html.py | 2 +- django/utils/http.py | 6 ++-- django/utils/safestring.py | 2 +- django/utils/translation/trans_real.py | 3 +- django/utils/version.py | 2 +- tests/admin_scripts/tests.py | 7 ++--- tests/auth_tests/test_management.py | 5 +-- tests/builtin_server/tests.py | 8 ++--- tests/forms_tests/tests/tests.py | 4 +-- tests/get_object_or_404/tests.py | 2 +- tests/get_or_create/tests.py | 2 +- tests/httpwrappers/tests.py | 31 +++++++------------ tests/i18n/test_compilation.py | 2 +- tests/i18n/tests.py | 22 +++---------- tests/mail/tests.py | 20 ++++++------ tests/migrations/test_writer.py | 21 ++----------- tests/servers/test_basehttp.py | 2 +- tests/str/tests.py | 4 +-- tests/urlpatterns_reverse/tests.py | 4 +-- tests/utils_tests/test_encoding.py | 4 +-- 47 files changed, 117 insertions(+), 165 deletions(-) diff --git a/django/contrib/gis/admin/widgets.py b/django/contrib/gis/admin/widgets.py index b76e860324f6..4dca40150ffb 100644 --- a/django/contrib/gis/admin/widgets.py +++ b/django/contrib/gis/admin/widgets.py @@ -83,7 +83,7 @@ def map_options(self): # JavaScript construction utilities for the Bounds and Projection. def ol_bounds(extent): - return 'new OpenLayers.Bounds(%s)' % str(extent) + return 'new OpenLayers.Bounds(%s)' % extent def ol_projection(srid): return 'new OpenLayers.Projection("EPSG:%s")' % srid diff --git a/django/contrib/gis/db/backends/postgis/adapter.py b/django/contrib/gis/db/backends/postgis/adapter.py index 84ec5bfae934..a3ec99de4660 100644 --- a/django/contrib/gis/db/backends/postgis/adapter.py +++ b/django/contrib/gis/db/backends/postgis/adapter.py @@ -58,9 +58,9 @@ def getquoted(self): """ if self.is_geometry: # Psycopg will figure out whether to use E'\\000' or '\000'. - return str('%s(%s)' % ( + return '%s(%s)' % ( 'ST_GeogFromWKB' if self.geography else 'ST_GeomFromEWKB', - self._adapter.getquoted().decode()) + self._adapter.getquoted().decode() ) else: # For rasters, add explicit type cast to WKB string. diff --git a/django/contrib/gis/db/models/functions.py b/django/contrib/gis/db/models/functions.py index 0a5c14f7a76a..5454b2a7409e 100644 --- a/django/contrib/gis/db/models/functions.py +++ b/django/contrib/gis/db/models/functions.py @@ -65,7 +65,7 @@ def _handle_param(self, value, param_name='', check_types=None): if check_types and not isinstance(value, check_types): raise TypeError( "The %s parameter has the wrong type: should be %s." % ( - param_name, str(check_types)) + param_name, check_types) ) return value diff --git a/django/contrib/gis/gdal/datasource.py b/django/contrib/gis/gdal/datasource.py index 3008da804cf4..7759fd79ae0f 100644 --- a/django/contrib/gis/gdal/datasource.py +++ b/django/contrib/gis/gdal/datasource.py @@ -109,7 +109,7 @@ def __len__(self): def __str__(self): "Returns OGR GetName and Driver for the Data Source." - return '%s (%s)' % (self.name, str(self.driver)) + return '%s (%s)' % (self.name, self.driver) @property def layer_count(self): diff --git a/django/contrib/gis/gdal/driver.py b/django/contrib/gis/gdal/driver.py index 20ebaeff20b5..fb348bb3773a 100644 --- a/django/contrib/gis/gdal/driver.py +++ b/django/contrib/gis/gdal/driver.py @@ -60,11 +60,11 @@ def __init__(self, dr_input): elif isinstance(dr_input, c_void_p): driver = dr_input else: - raise GDALException('Unrecognized input type for GDAL/OGR Driver: %s' % str(type(dr_input))) + raise GDALException('Unrecognized input type for GDAL/OGR Driver: %s' % type(dr_input)) # Making sure we get a valid pointer to the OGR Driver if not driver: - raise GDALException('Could not initialize GDAL/OGR Driver on input: %s' % str(dr_input)) + raise GDALException('Could not initialize GDAL/OGR Driver on input: %s' % dr_input) self.ptr = driver def __str__(self): diff --git a/django/contrib/gis/gdal/envelope.py b/django/contrib/gis/gdal/envelope.py index e7c7e3dde1b7..4cf30c06d961 100644 --- a/django/contrib/gis/gdal/envelope.py +++ b/django/contrib/gis/gdal/envelope.py @@ -51,7 +51,7 @@ def __init__(self, *args): else: self._from_sequence(args[0]) else: - raise TypeError('Incorrect type of argument: %s' % str(type(args[0]))) + raise TypeError('Incorrect type of argument: %s' % type(args[0])) elif len(args) == 4: # Individual parameters passed in. # Thanks to ww for the help @@ -123,7 +123,7 @@ def expand_to_include(self, *args): else: raise GDALException('Incorrect number of tuple elements (%d).' % len(args[0])) else: - raise TypeError('Incorrect type of argument: %s' % str(type(args[0]))) + raise TypeError('Incorrect type of argument: %s' % type(args[0])) elif len(args) == 2: # An x and an y parameter were passed in return self.expand_to_include((args[0], args[1], args[0], args[1])) diff --git a/django/contrib/gis/gdal/geometries.py b/django/contrib/gis/gdal/geometries.py index 1dd85ac1397d..b1acc5bf5bd7 100644 --- a/django/contrib/gis/gdal/geometries.py +++ b/django/contrib/gis/gdal/geometries.py @@ -109,7 +109,7 @@ def __init__(self, geom_input, srs=None): # Now checking the Geometry pointer before finishing initialization # by setting the pointer for the object. if not g: - raise GDALException('Cannot create OGR Geometry from input: %s' % str(geom_input)) + raise GDALException('Cannot create OGR Geometry from input: %s' % geom_input) self.ptr = g # Assigning the SpatialReference object to the geometry, if valid. @@ -549,7 +549,7 @@ def __getitem__(self, index): elif dim == 3: return (x.value, y.value, z.value) else: - raise OGRIndexError('index out of range: %s' % str(index)) + raise OGRIndexError('index out of range: %s' % index) def __iter__(self): "Iterates over each point in the LineString." diff --git a/django/contrib/gis/geos/coordseq.py b/django/contrib/gis/geos/coordseq.py index 6908b040c08a..f40d99865e2d 100644 --- a/django/contrib/gis/geos/coordseq.py +++ b/django/contrib/gis/geos/coordseq.py @@ -73,7 +73,7 @@ def _checkindex(self, index): "Checks the given index." sz = self.size if (sz < 1) or (index < 0) or (index >= sz): - raise IndexError('invalid GEOS Geometry index: %s' % str(index)) + raise IndexError('invalid GEOS Geometry index: %s' % index) def _checkdim(self, dim): "Checks the given dimension." diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py index 2ff4037764e4..f47350653981 100644 --- a/django/contrib/gis/geos/geometry.py +++ b/django/contrib/gis/geos/geometry.py @@ -73,7 +73,7 @@ def __init__(self, geo_input, srid=None): g = capi.geom_clone(geo_input.ptr) else: # Invalid geometry type. - raise TypeError('Improper geometry input type: %s' % str(type(geo_input))) + raise TypeError('Improper geometry input type: %s' % type(geo_input)) if g: # Setting the pointer object with a valid pointer. diff --git a/django/contrib/gis/geos/mutable_list.py b/django/contrib/gis/geos/mutable_list.py index d6e36db31ab3..c7fb703ce1c9 100644 --- a/django/contrib/gis/geos/mutable_list.py +++ b/django/contrib/gis/geos/mutable_list.py @@ -179,7 +179,7 @@ def index(self, val): for i in range(0, len(self)): if self[i] == val: return i - raise ValueError('%s not found in object' % str(val)) + raise ValueError('%s not found in object' % val) # ## Mutating ## def append(self, val): @@ -242,7 +242,7 @@ def _checkindex(self, index, correct=True): return index if correct and -length <= index < 0: return index + length - raise IndexError('invalid index: %s' % str(index)) + raise IndexError('invalid index: %s' % index) def _check_allowed(self, items): if hasattr(self, '_allowed'): diff --git a/django/contrib/gis/geos/point.py b/django/contrib/gis/geos/point.py index 72de47f9f6db..6486b2a5e136 100644 --- a/django/contrib/gis/geos/point.py +++ b/django/contrib/gis/geos/point.py @@ -56,7 +56,7 @@ def _create_point(cls, ndim, coords): return capi.create_point(None) if ndim < 2 or ndim > 3: - raise TypeError('Invalid point dimension: %s' % str(ndim)) + raise TypeError('Invalid point dimension: %s' % ndim) cs = capi.create_cs(c_uint(1), c_uint(ndim)) i = iter(coords) diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index c61dae1dfa07..7d8a12176a5c 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -153,9 +153,9 @@ def __call__(self, environ, start_response): response._handler_class = self.__class__ status = '%d %s' % (response.status_code, response.reason_phrase) - response_headers = [(str(k), str(v)) for k, v in response.items()] + response_headers = list(response.items()) for c in response.cookies.values(): - response_headers.append((str('Set-Cookie'), str(c.output(header='')))) + response_headers.append(('Set-Cookie', c.output(header=''))) start_response(status, response_headers) if getattr(response, 'file_to_stream', None) is not None and environ.get('wsgi.file_wrapper'): response = environ['wsgi.file_wrapper'](response.file_to_stream) @@ -208,9 +208,9 @@ def get_bytes_from_wsgi(environ, key, default): """ Get a value from the WSGI environ dictionary as bytes. - key and default should be str objects. + key and default should be strings. """ - value = environ.get(str(key), str(default)) + value = environ.get(key, default) # Non-ASCII values in the WSGI environ are arbitrarily decoded with # ISO-8859-1. This is wrong for Django websites where UTF-8 is the default. # Re-encode to recover the original bytestring. diff --git a/django/core/mail/message.py b/django/core/mail/message.py index 228084f2d1e6..dd5e1e6d7bb4 100644 --- a/django/core/mail/message.py +++ b/django/core/mail/message.py @@ -68,7 +68,7 @@ def forbid_multi_line_headers(name, val, encoding): else: if name.lower() == 'subject': val = Header(val).encode() - return str(name), val + return name, val def split_addr(addr, encoding): diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py index 5b74ddaa0d17..029d5163a531 100644 --- a/django/core/management/commands/makemessages.py +++ b/django/core/management/commands/makemessages.py @@ -398,7 +398,7 @@ def build_potfiles(self): self.process_files(file_list) potfiles = [] for path in self.locale_paths: - potfile = os.path.join(path, '%s.pot' % str(self.domain)) + potfile = os.path.join(path, '%s.pot' % self.domain) if not os.path.exists(potfile): continue args = ['msguniq'] + self.msguniq_options + [potfile] @@ -417,7 +417,7 @@ def build_potfiles(self): def remove_potfiles(self): for path in self.locale_paths: - pot_path = os.path.join(path, '%s.pot' % str(self.domain)) + pot_path = os.path.join(path, '%s.pot' % self.domain) if os.path.exists(pot_path): os.unlink(pot_path) @@ -583,7 +583,7 @@ def process_locale_dir(self, locale_dir, files): ) for build_file in build_files: msgs = build_file.postprocess_messages(msgs) - potfile = os.path.join(locale_dir, '%s.pot' % str(self.domain)) + potfile = os.path.join(locale_dir, '%s.pot' % self.domain) write_pot_file(potfile, msgs) for build_file in build_files: @@ -599,7 +599,7 @@ def write_po_file(self, potfile, locale): basedir = os.path.join(os.path.dirname(potfile), locale, 'LC_MESSAGES') if not os.path.isdir(basedir): os.makedirs(basedir) - pofile = os.path.join(basedir, '%s.po' % str(self.domain)) + pofile = os.path.join(basedir, '%s.po' % self.domain) if os.path.exists(pofile): args = ['msgmerge'] + self.msgmerge_options + [pofile, potfile] diff --git a/django/core/management/commands/runserver.py b/django/core/management/commands/runserver.py index e5dcaa1771f9..61a275d61f4a 100644 --- a/django/core/management/commands/runserver.py +++ b/django/core/management/commands/runserver.py @@ -56,7 +56,7 @@ def execute(self, *args, **options): # We rely on the environment because it's currently the only # way to reach WSGIRequestHandler. This seems an acceptable # compromise considering `runserver` runs indefinitely. - os.environ[str("DJANGO_COLORS")] = str("nocolor") + os.environ["DJANGO_COLORS"] = "nocolor" super(Command, self).execute(*args, **options) def get_handler(self, *args, **options): diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index b706f74ec859..a9ab0668f79a 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -103,7 +103,7 @@ def log_message(self, format, *args): } if args[1][0] == '4': # 0x16 = Handshake, 0x03 = SSL 3.0 or TLS 1.x - if args[0].startswith(str('\x16\x03')): + if args[0].startswith('\x16\x03'): extra['status_code'] = 500 logger.error( "You're accessing the development server over HTTPS, but " diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py index 44f81c8ba111..07c4ceb1e74c 100644 --- a/django/db/backends/sqlite3/base.py +++ b/django/db/backends/sqlite3/base.py @@ -45,13 +45,13 @@ def decoder(conv_func): return lambda s: conv_func(s.decode('utf-8')) -Database.register_converter(str("bool"), decoder(lambda s: s == '1')) -Database.register_converter(str("time"), decoder(parse_time)) -Database.register_converter(str("date"), decoder(parse_date)) -Database.register_converter(str("datetime"), decoder(parse_datetime)) -Database.register_converter(str("timestamp"), decoder(parse_datetime)) -Database.register_converter(str("TIMESTAMP"), decoder(parse_datetime)) -Database.register_converter(str("decimal"), decoder(backend_utils.typecast_decimal)) +Database.register_converter("bool", decoder(lambda s: s == '1')) +Database.register_converter("time", decoder(parse_time)) +Database.register_converter("date", decoder(parse_date)) +Database.register_converter("datetime", decoder(parse_datetime)) +Database.register_converter("timestamp", decoder(parse_datetime)) +Database.register_converter("TIMESTAMP", decoder(parse_datetime)) +Database.register_converter("decimal", decoder(backend_utils.typecast_decimal)) Database.register_adapter(decimal.Decimal, backend_utils.rev_typecast_decimal) diff --git a/django/db/models/base.py b/django/db/models/base.py index 047f90ec733c..66b671698d32 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -35,10 +35,10 @@ class Deferred: def __repr__(self): - return str('') + return '' def __str__(self): - return str('') + return '' DEFERRED = Deferred() @@ -118,7 +118,7 @@ def __new__(cls, name, bases, attrs): new_class.add_to_class( 'DoesNotExist', subclass_exception( - str('DoesNotExist'), + 'DoesNotExist', tuple( x.DoesNotExist for x in parents if hasattr(x, '_meta') and not x._meta.abstract ) or (ObjectDoesNotExist,), @@ -127,7 +127,7 @@ def __new__(cls, name, bases, attrs): new_class.add_to_class( 'MultipleObjectsReturned', subclass_exception( - str('MultipleObjectsReturned'), + 'MultipleObjectsReturned', tuple( x.MultipleObjectsReturned for x in parents if hasattr(x, '_meta') and not x._meta.abstract ) or (MultipleObjectsReturned,), diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 26b0bb237807..fabd291159e3 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -32,9 +32,7 @@ from django.utils.text import capfirst from django.utils.translation import ugettext_lazy as _ -# Avoid "TypeError: Item in ``from list'' not a string" -- unicode_literals -# makes these strings unicode -__all__ = [str(x) for x in ( +__all__ = [ 'AutoField', 'BLANK_CHOICE_DASH', 'BigAutoField', 'BigIntegerField', 'BinaryField', 'BooleanField', 'CharField', 'CommaSeparatedIntegerField', 'DateField', 'DateTimeField', 'DecimalField', 'DurationField', @@ -43,7 +41,7 @@ 'NOT_PROVIDED', 'NullBooleanField', 'PositiveIntegerField', 'PositiveSmallIntegerField', 'SlugField', 'SmallIntegerField', 'TextField', 'TimeField', 'URLField', 'UUIDField', -)] +] class Empty: diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index d1937bd5dbe1..4e678ea67278 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -277,7 +277,7 @@ def get_internal_type(self): def get_prep_value(self, value): "Returns field's value prepared for saving into a database." value = super(FileField, self).get_prep_value(value) - # Need to convert File objects provided via a form to unicode for database insertion + # Need to convert File objects provided via a form to string for database insertion if value is None: return None return str(value) diff --git a/django/db/models/indexes.py b/django/db/models/indexes.py index 03aa06fa5240..7721826380c8 100644 --- a/django/db/models/indexes.py +++ b/django/db/models/indexes.py @@ -2,7 +2,7 @@ from django.utils.encoding import force_bytes -__all__ = [str('Index')] +__all__ = ['Index'] # The max length of the names of the indexes (restricted to 30 due to Oracle) MAX_NAME_LENGTH = 30 diff --git a/django/http/cookie.py b/django/http/cookie.py index fb0a7786ef95..36945ce106de 100644 --- a/django/http/cookie.py +++ b/django/http/cookie.py @@ -22,13 +22,13 @@ def parse_cookie(cookie): Return a dictionary parsed from a `Cookie:` header string. """ cookiedict = {} - for chunk in cookie.split(str(';')): - if str('=') in chunk: - key, val = chunk.split(str('='), 1) + for chunk in cookie.split(';'): + if '=' in chunk: + key, val = chunk.split('=', 1) else: # Assume an empty name per # https://bugzilla.mozilla.org/show_bug.cgi?id=169091 - key, val = str(''), chunk + key, val = '', chunk key, val = key.strip(), val.strip() if key or val: # unquote using Python's algorithm. diff --git a/django/http/request.py b/django/http/request.py index 6f3b0c9951e7..554e05217d84 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -509,11 +509,11 @@ def encode(k, v): # this slightly more restricted function, used by QueryDict. def bytes_to_text(s, encoding): """ - Converts basestring objects to unicode, using the given encoding. Illegally + Convert bytes objects to strings, using the given encoding. Illegally encoded input characters are replaced with Unicode "unknown" codepoint (\ufffd). - Returns any non-basestring objects without change. + Return any non-bytes objects without change. """ if isinstance(s, bytes): return str(s, encoding, 'replace') diff --git a/django/http/response.py b/django/http/response.py index e992adaed544..9c697f5b88b3 100644 --- a/django/http/response.py +++ b/django/http/response.py @@ -124,8 +124,7 @@ def _convert_to_charset(self, value, charset, mime_encode=False): value = value.decode(charset) except UnicodeError as e: if mime_encode: - # Wrapping in str() is a workaround for #12422 under Python 2. - value = str(Header(value, 'utf-8', maxlinelen=sys.maxsize).encode()) + value = Header(value, 'utf-8', maxlinelen=sys.maxsize).encode() else: e.reason += ', HTTP response headers must be in %s format' % charset raise diff --git a/django/test/client.py b/django/test/client.py index 20c968bb3f1d..f09051d2d5ad 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -281,15 +281,15 @@ def _base_environ(self, **request): # See http://www.python.org/dev/peps/pep-3333/#environ-variables environ = { 'HTTP_COOKIE': self.cookies.output(header='', sep='; '), - 'PATH_INFO': str('/'), - 'REMOTE_ADDR': str('127.0.0.1'), - 'REQUEST_METHOD': str('GET'), - 'SCRIPT_NAME': str(''), - 'SERVER_NAME': str('testserver'), - 'SERVER_PORT': str('80'), - 'SERVER_PROTOCOL': str('HTTP/1.1'), + 'PATH_INFO': '/', + 'REMOTE_ADDR': '127.0.0.1', + 'REQUEST_METHOD': 'GET', + 'SCRIPT_NAME': '', + 'SERVER_NAME': 'testserver', + 'SERVER_PORT': '80', + 'SERVER_PROTOCOL': 'HTTP/1.1', 'wsgi.version': (1, 0), - 'wsgi.url_scheme': str('http'), + 'wsgi.url_scheme': 'http', 'wsgi.input': FakePayload(b''), 'wsgi.errors': self.errors, 'wsgi.multiprocess': True, @@ -393,14 +393,14 @@ def generic(self, method, path, data='', data = force_bytes(data, settings.DEFAULT_CHARSET) r = { 'PATH_INFO': self._get_path(parsed), - 'REQUEST_METHOD': str(method), - 'SERVER_PORT': str('443') if secure else str('80'), - 'wsgi.url_scheme': str('https') if secure else str('http'), + 'REQUEST_METHOD': method, + 'SERVER_PORT': '443' if secure else '80', + 'wsgi.url_scheme': 'https' if secure else 'http', } if data: r.update({ 'CONTENT_LENGTH': len(data), - 'CONTENT_TYPE': str(content_type), + 'CONTENT_TYPE': content_type, 'wsgi.input': FakePayload(data), }) r.update(extra) diff --git a/django/test/selenium.py b/django/test/selenium.py index 236f7d805343..e1415339dd14 100644 --- a/django/test/selenium.py +++ b/django/test/selenium.py @@ -35,7 +35,7 @@ def __new__(cls, name, bases, attrs): for browser in test_class.browsers[1:]: browser_test_class = cls.__new__( cls, - str("%s%s" % (capfirst(browser), name)), + "%s%s" % (capfirst(browser), name), (test_class,), {'browser': browser, '__module__': test_class.__module__} ) diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py index 6084684d7379..376aedc3c1d6 100644 --- a/django/urls/resolvers.py +++ b/django/urls/resolvers.py @@ -236,7 +236,7 @@ def __repr__(self): urlconf_repr = '<%s list>' % self.urlconf_name[0].__class__.__name__ else: urlconf_repr = repr(self.urlconf_name) - return str('<%s %s (%s:%s) %s>') % ( + return '<%s %s (%s:%s) %s>' % ( self.__class__.__name__, urlconf_repr, self.app_name, self.namespace, self.regex.pattern, ) diff --git a/django/utils/html.py b/django/utils/html.py index 63335d74b41f..fb9c18219c67 100644 --- a/django/utils/html.py +++ b/django/utils/html.py @@ -193,7 +193,7 @@ def unquote_quote(segment): # Tilde is part of RFC3986 Unreserved Characters # http://tools.ietf.org/html/rfc3986#section-2.3 # See also http://bugs.python.org/issue16285 - segment = quote(segment, safe=RFC3986_SUBDELIMS + RFC3986_GENDELIMS + str('~')) + segment = quote(segment, safe=RFC3986_SUBDELIMS + RFC3986_GENDELIMS + '~') return force_text(segment) # Handle IDN before quoting. diff --git a/django/utils/http.py b/django/utils/http.py index 579185681319..7b15dc281253 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -40,8 +40,8 @@ RFC850_DATE = re.compile(r'^\w{6,9}, %s-%s-%s %s GMT$' % (__D, __M, __Y2, __T)) ASCTIME_DATE = re.compile(r'^\w{3} %s %s %s %s$' % (__M, __D2, __T, __Y)) -RFC3986_GENDELIMS = str(":/?#[]@") -RFC3986_SUBDELIMS = str("!$&'()*+,;=") +RFC3986_GENDELIMS = ":/?#[]@" +RFC3986_SUBDELIMS = "!$&'()*+,;=" FIELDS_MATCH = re.compile('[&;]') @@ -365,7 +365,7 @@ def limited_parse_qsl(qs, keep_blank_values=False, encoding='utf-8', for name_value in pairs: if not name_value: continue - nv = name_value.split(str('='), 1) + nv = name_value.split('=', 1) if len(nv) != 2: # Handle case of a control-name with no equal sign if keep_blank_values: diff --git a/django/utils/safestring.py b/django/utils/safestring.py index fe5ca422c3fd..2dfbd01cfe6c 100644 --- a/django/utils/safestring.py +++ b/django/utils/safestring.py @@ -95,7 +95,7 @@ def wrapped(*args, **kwargs): def mark_safe(s): """ Explicitly mark a string as safe for (HTML) output purposes. The returned - object can be used everywhere a string or unicode object is appropriate. + object can be used everywhere a string is appropriate. If used on a method as a decorator, mark the returned data as safe. diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py index 14bb0ce786ec..62ff122621ba 100644 --- a/django/utils/translation/trans_real.py +++ b/django/utils/translation/trans_real.py @@ -307,8 +307,7 @@ def do_translate(message, translation_function): """ global _default - # str() is allowing a bytestring message to remain bytestring on Python 2 - eol_message = message.replace(str('\r\n'), str('\n')).replace(str('\r'), str('\n')) + eol_message = message.replace('\r\n', '\n').replace('\r', '\n') if len(eol_message) == 0: # Returns an empty value of the corresponding type if an empty message diff --git a/django/utils/version.py b/django/utils/version.py index e9666f906e1a..b80d445d0c8f 100644 --- a/django/utils/version.py +++ b/django/utils/version.py @@ -25,7 +25,7 @@ def get_version(version=None): mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'rc'} sub = mapping[version[3]] + str(version[4]) - return str(main + sub) + return main + sub def get_main_version(version=None): diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index 25e6487a0fb4..bccefc2d19d9 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -145,14 +145,13 @@ def run_test(self, script, args, settings_file=None, apps=None): # Set the test environment if settings_file: - test_environ['DJANGO_SETTINGS_MODULE'] = str(settings_file) + test_environ['DJANGO_SETTINGS_MODULE'] = settings_file elif 'DJANGO_SETTINGS_MODULE' in test_environ: del test_environ['DJANGO_SETTINGS_MODULE'] python_path = [base_dir, django_dir, tests_dir] python_path.extend(ext_backend_base_dirs) - # Use native strings for better compatibility - test_environ[str(python_path_var_name)] = os.pathsep.join(python_path) - test_environ[str('PYTHONWARNINGS')] = str('') + test_environ[python_path_var_name] = os.pathsep.join(python_path) + test_environ['PYTHONWARNINGS'] = '' # Move to the test directory and run os.chdir(self.test_dir) diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 00864be47a0d..15ff551211b5 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -37,10 +37,7 @@ def getpass(prompt=b'Password: ', stream=None): return inputs['password'] def mock_input(prompt): - # prompt should be encoded in Python 2. This line will raise an - # Exception if prompt contains unencoded non-ASCII on Python 2. - prompt = str(prompt) - assert str('__proxy__') not in prompt + assert '__proxy__' not in prompt response = '' for key, val in inputs.items(): if key in prompt.lower(): diff --git a/tests/builtin_server/tests.py b/tests/builtin_server/tests.py index 6e234c1ba4a2..a294339f85dd 100644 --- a/tests/builtin_server/tests.py +++ b/tests/builtin_server/tests.py @@ -10,7 +10,7 @@ class ServerHandler(simple_server.ServerHandler): - error_status = str("500 INTERNAL SERVER ERROR") + error_status = "500 INTERNAL SERVER ERROR" def write(self, data): """'write()' callable as specified by PEP 3333""" @@ -55,12 +55,12 @@ def sendfile(self): def wsgi_app(environ, start_response): - start_response(str('200 OK'), [(str('Content-Type'), str('text/plain'))]) + start_response('200 OK', [('Content-Type', 'text/plain')]) return [b'Hello World!'] def wsgi_app_file_wrapper(environ, start_response): - start_response(str('200 OK'), [(str('Content-Type'), str('text/plain'))]) + start_response('200 OK', [('Content-Type', 'text/plain')]) return environ['wsgi.file_wrapper'](BytesIO(b'foo')) @@ -113,7 +113,7 @@ def _write(self, data): def send_big_data_app(environ, start_response): - start_response(str('200 OK'), [(str('Content-Type'), str('text/plain'))]) + start_response('200 OK', [('Content-Type', 'text/plain')]) # Return a blob of data that is 1.5 times the maximum chunk size. return [b'x' * (MAX_SOCKET_CHUNK_SIZE + MAX_SOCKET_CHUNK_SIZE // 2)] diff --git a/tests/forms_tests/tests/tests.py b/tests/forms_tests/tests/tests.py index 0119410fc86d..fe72474537f5 100644 --- a/tests/forms_tests/tests/tests.py +++ b/tests/forms_tests/tests/tests.py @@ -248,7 +248,7 @@ class Meta: fields = '__all__' with self.assertRaises(ValueError): - ModelFormMetaclass(str('Form'), (ModelForm,), {'Meta': Meta}) + ModelFormMetaclass('Form', (ModelForm,), {'Meta': Meta}) class B(models.Model): pass @@ -267,7 +267,7 @@ class Meta: model = C fields = '__all__' - self.assertTrue(issubclass(ModelFormMetaclass(str('Form'), (ModelForm,), {'Meta': Meta}), ModelForm)) + self.assertTrue(issubclass(ModelFormMetaclass('Form', (ModelForm,), {'Meta': Meta}), ModelForm)) class ManyToManyExclusionTestCase(TestCase): diff --git a/tests/get_object_or_404/tests.py b/tests/get_object_or_404/tests.py index fa3c0cb32406..a72b766524be 100644 --- a/tests/get_object_or_404/tests.py +++ b/tests/get_object_or_404/tests.py @@ -81,7 +81,7 @@ def test_bad_class(self): # raises a helpful ValueError message msg = "First argument to get_object_or_404() must be a Model, Manager, or QuerySet, not 'str'." with self.assertRaisesMessage(ValueError, msg): - get_object_or_404(str("Article"), title__icontains="Run") + get_object_or_404("Article", title__icontains="Run") class CustomClass: pass diff --git a/tests/get_or_create/tests.py b/tests/get_or_create/tests.py index 27a0cb77377f..a2a6e5a5a573 100644 --- a/tests/get_or_create/tests.py +++ b/tests/get_or_create/tests.py @@ -201,7 +201,7 @@ def test_get_or_create_raises_IntegrityError_plus_traceback(self): ManualPrimaryKeyTest.objects.get_or_create(id=1, data="Different") except IntegrityError: formatted_traceback = traceback.format_exc() - self.assertIn(str('obj.save'), formatted_traceback) + self.assertIn('obj.save', formatted_traceback) # MySQL emits a warning when broken data is saved @ignore_warnings(module='django.db.backends.mysql.base') diff --git a/tests/httpwrappers/tests.py b/tests/httpwrappers/tests.py index 612cbb45ef52..c58163b014d7 100644 --- a/tests/httpwrappers/tests.py +++ b/tests/httpwrappers/tests.py @@ -21,7 +21,7 @@ class QueryDictTests(SimpleTestCase): def test_create_with_no_args(self): - self.assertEqual(QueryDict(), QueryDict(str(''))) + self.assertEqual(QueryDict(), QueryDict('')) def test_missing_key(self): q = QueryDict() @@ -63,7 +63,7 @@ def test_immutable_basic_operations(self): def test_single_key_value(self): """Test QueryDict with one key/value pair""" - q = QueryDict(str('foo=bar')) + q = QueryDict('foo=bar') self.assertEqual(q['foo'], 'bar') with self.assertRaises(KeyError): q.__getitem__('bar') @@ -166,7 +166,7 @@ def test_basic_mutable_operations(self): def test_multiple_keys(self): """Test QueryDict with two key/value pairs with same keys.""" - q = QueryDict(str('vote=yes&vote=no')) + q = QueryDict('vote=yes&vote=no') self.assertEqual(q['vote'], 'no') with self.assertRaises(AttributeError): @@ -209,23 +209,23 @@ def test_pickle(self): q = QueryDict() q1 = pickle.loads(pickle.dumps(q, 2)) self.assertEqual(q, q1) - q = QueryDict(str('a=b&c=d')) + q = QueryDict('a=b&c=d') q1 = pickle.loads(pickle.dumps(q, 2)) self.assertEqual(q, q1) - q = QueryDict(str('a=b&c=d&a=1')) + q = QueryDict('a=b&c=d&a=1') q1 = pickle.loads(pickle.dumps(q, 2)) self.assertEqual(q, q1) def test_update_from_querydict(self): """Regression test for #8278: QueryDict.update(QueryDict)""" - x = QueryDict(str("a=1&a=2"), mutable=True) - y = QueryDict(str("a=3&a=4")) + x = QueryDict("a=1&a=2", mutable=True) + y = QueryDict("a=3&a=4") x.update(y) self.assertEqual(x.getlist('a'), ['1', '2', '3', '4']) def test_non_default_encoding(self): """#13572 - QueryDict with a non-default encoding""" - q = QueryDict(str('cur=%A4'), encoding='iso-8859-15') + q = QueryDict('cur=%A4', encoding='iso-8859-15') self.assertEqual(q.encoding, 'iso-8859-15') self.assertEqual(list(q.items()), [('cur', '€')]) self.assertEqual(q.urlencode(), 'cur=%A4') @@ -280,16 +280,11 @@ class HttpResponseTests(unittest.TestCase): def test_headers_type(self): r = HttpResponse() - # The following tests explicitly test types in addition to values - # because in Python 2 u'foo' == b'foo'. - - # ASCII unicode or bytes values are converted to native strings. + # ASCII unicode or bytes values are converted to strings. r['key'] = 'test' - self.assertEqual(r['key'], str('test')) - self.assertIsInstance(r['key'], str) + self.assertEqual(r['key'], 'test') r['key'] = 'test'.encode('ascii') - self.assertEqual(r['key'], str('test')) - self.assertIsInstance(r['key'], str) + self.assertEqual(r['key'], 'test') self.assertIn(b'test', r.serialize_headers()) # Non-ASCII values are serialized to Latin-1. @@ -298,8 +293,7 @@ def test_headers_type(self): # Other unicode values are MIME-encoded (there's no way to pass them as bytes). r['key'] = '†' - self.assertEqual(r['key'], str('=?utf-8?b?4oCg?=')) - self.assertIsInstance(r['key'], str) + self.assertEqual(r['key'], '=?utf-8?b?4oCg?=') self.assertIn(b'=?utf-8?b?4oCg?=', r.serialize_headers()) # The response also converts unicode or bytes keys to strings, but requires @@ -310,7 +304,6 @@ def test_headers_type(self): headers = list(r.items()) self.assertEqual(len(headers), 1) self.assertEqual(headers[0], ('foo', 'bar')) - self.assertIsInstance(headers[0][0], str) r = HttpResponse() del r['Content-Type'] diff --git a/tests/i18n/test_compilation.py b/tests/i18n/test_compilation.py index 159b6d91ec62..5244832e2d5c 100644 --- a/tests/i18n/test_compilation.py +++ b/tests/i18n/test_compilation.py @@ -142,7 +142,7 @@ def test_msgfmt_error_including_non_ascii(self): # po file contains invalid msgstr content (triggers non-ascii error content). # Make sure the output of msgfmt is unaffected by the current locale. env = os.environ.copy() - env.update({str('LANG'): str('C')}) + env.update({'LANG': 'C'}) with mock.patch('django.core.management.utils.Popen', lambda *args, **kwargs: Popen(*args, env=env, **kwargs)): cmd = MakeMessagesCommand() if cmd.gettext_version < (0, 18, 3): diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py index 181de62bea4f..4f4801ba2c87 100644 --- a/tests/i18n/tests.py +++ b/tests/i18n/tests.py @@ -24,8 +24,8 @@ from django.utils.translation import ( LANGUAGE_SESSION_KEY, activate, check_for_language, deactivate, get_language, get_language_from_request, get_language_info, gettext_lazy, - ngettext_lazy, npgettext, npgettext_lazy, pgettext, trans_real, ugettext, - ugettext_lazy, ungettext, ungettext_lazy, + npgettext, npgettext_lazy, pgettext, trans_real, ugettext, ugettext_lazy, + ungettext, ungettext_lazy, ) from .forms import CompanyForm, I18nForm, SelectDateForm @@ -146,14 +146,11 @@ def test_lazy_pickle(self): @override_settings(LOCALE_PATHS=extended_locale_paths) def test_ungettext_lazy(self): simple_with_format = ungettext_lazy('%d good result', '%d good results') - simple_str_with_format = ngettext_lazy(str('%d good result'), str('%d good results')) simple_context_with_format = npgettext_lazy('Exclamation', '%d good result', '%d good results') simple_without_format = ungettext_lazy('good result', 'good results') with translation.override('de'): self.assertEqual(simple_with_format % 1, '1 gutes Resultat') self.assertEqual(simple_with_format % 4, '4 guten Resultate') - self.assertEqual(simple_str_with_format % 1, str('1 gutes Resultat')) - self.assertEqual(simple_str_with_format % 4, str('4 guten Resultate')) self.assertEqual(simple_context_with_format % 1, '1 gutes Resultat!') self.assertEqual(simple_context_with_format % 4, '4 guten Resultate!') self.assertEqual(simple_without_format % 1, 'gutes Resultat') @@ -163,12 +160,6 @@ def test_ungettext_lazy(self): complex_deferred = ungettext_lazy( 'Hi %(name)s, %(num)d good result', 'Hi %(name)s, %(num)d good results', 'num' ) - complex_str_nonlazy = ngettext_lazy( - str('Hi %(name)s, %(num)d good result'), str('Hi %(name)s, %(num)d good results'), 4 - ) - complex_str_deferred = ngettext_lazy( - str('Hi %(name)s, %(num)d good result'), str('Hi %(name)s, %(num)d good results'), 'num' - ) complex_context_nonlazy = npgettext_lazy( 'Greeting', 'Hi %(name)s, %(num)d good result', 'Hi %(name)s, %(num)d good results', 4 ) @@ -181,11 +172,6 @@ def test_ungettext_lazy(self): self.assertEqual(complex_deferred % {'name': 'Jim', 'num': 5}, 'Hallo Jim, 5 guten Resultate') with self.assertRaisesMessage(KeyError, 'Your dictionary lacks key'): complex_deferred % {'name': 'Jim'} - self.assertEqual(complex_str_nonlazy % {'num': 4, 'name': 'Jim'}, str('Hallo Jim, 4 guten Resultate')) - self.assertEqual(complex_str_deferred % {'name': 'Jim', 'num': 1}, str('Hallo Jim, 1 gutes Resultat')) - self.assertEqual(complex_str_deferred % {'name': 'Jim', 'num': 5}, str('Hallo Jim, 5 guten Resultate')) - with self.assertRaisesMessage(KeyError, 'Your dictionary lacks key'): - complex_str_deferred % {'name': 'Jim'} self.assertEqual(complex_context_nonlazy % {'num': 4, 'name': 'Jim'}, 'Willkommen Jim, 4 guten Resultate') self.assertEqual(complex_context_deferred % {'name': 'Jim', 'num': 1}, 'Willkommen Jim, 1 gutes Resultat') self.assertEqual(complex_context_deferred % {'name': 'Jim', 'num': 5}, 'Willkommen Jim, 5 guten Resultate') @@ -917,8 +903,8 @@ def test_get_format_modules_lang(self): def test_get_format_modules_stability(self): with self.settings(FORMAT_MODULE_PATH='i18n.other.locale'): with translation.override('de', deactivate=True): - old = str("%r") % get_format_modules(reverse=True) - new = str("%r") % get_format_modules(reverse=True) # second try + old = "%r" % get_format_modules(reverse=True) + new = "%r" % get_format_modules(reverse=True) # second try self.assertEqual(new, old, 'Value returned by get_formats_modules() must be preserved between calls.') def test_localize_templatetag_and_filter(self): diff --git a/tests/mail/tests.py b/tests/mail/tests.py index 8019f3ccf882..f30734d72f87 100644 --- a/tests/mail/tests.py +++ b/tests/mail/tests.py @@ -576,7 +576,7 @@ def test_dont_base64_encode(self): s = msg.message().as_bytes() self.assertIn(b'Content-Transfer-Encoding: 8bit', s) s = msg.message().as_string() - self.assertIn(str('Content-Transfer-Encoding: 8bit'), s) + self.assertIn('Content-Transfer-Encoding: 8bit', s) msg = EmailMessage( 'Subject', 'Body with non latin characters: А Б В Г Д Е Ж Ѕ З И І К Л М Н О П.', 'bounce@example.com', @@ -585,7 +585,7 @@ def test_dont_base64_encode(self): s = msg.message().as_bytes() self.assertIn(b'Content-Transfer-Encoding: 8bit', s) s = msg.message().as_string() - self.assertIn(str('Content-Transfer-Encoding: 8bit'), s) + self.assertIn('Content-Transfer-Encoding: 8bit', s) def test_dont_base64_encode_message_rfc822(self): # Ticket #18967 @@ -608,7 +608,7 @@ def test_dont_base64_encode_message_rfc822(self): parent_s = parent_msg.message().as_string() # The child message header is not base64 encoded - self.assertIn(str('Child Subject'), parent_s) + self.assertIn('Child Subject', parent_s) # Feature test: try attaching email.Message object directly to the mail. parent_msg = EmailMessage( @@ -619,7 +619,7 @@ def test_dont_base64_encode_message_rfc822(self): parent_s = parent_msg.message().as_string() # The child message header is not base64 encoded - self.assertIn(str('Child Subject'), parent_s) + self.assertIn('Child Subject', parent_s) # Feature test: try attaching Django's EmailMessage object directly to the mail. parent_msg = EmailMessage( @@ -630,7 +630,7 @@ def test_dont_base64_encode_message_rfc822(self): parent_s = parent_msg.message().as_string() # The child message header is not base64 encoded - self.assertIn(str('Child Subject'), parent_s) + self.assertIn('Child Subject', parent_s) def test_sanitize_address(self): """ @@ -700,11 +700,11 @@ def test_7bit(self): def test_8bit_latin(self): txt = MIMEText('Body with latin characters: àáä.', 'plain', 'utf-8') - self.assertIn(str('Content-Transfer-Encoding: base64'), txt.as_string()) + self.assertIn('Content-Transfer-Encoding: base64', txt.as_string()) def test_8bit_non_latin(self): txt = MIMEText('Body with non latin characters: А Б В Г Д Е Ж Ѕ З И І К Л М Н О П.', 'plain', 'utf-8') - self.assertIn(str('Content-Transfer-Encoding: base64'), txt.as_string()) + self.assertIn('Content-Transfer-Encoding: base64', txt.as_string()) class BaseEmailBackendTests(HeadersCheckMixin): @@ -1091,7 +1091,7 @@ def flush_mailbox(self): self.stream = sys.stdout = StringIO() def get_mailbox_content(self): - messages = self.stream.getvalue().split(str('\n' + ('-' * 79) + '\n')) + messages = self.stream.getvalue().split('\n' + ('-' * 79) + '\n') return [message_from_bytes(force_bytes(m)) for m in messages if m] def test_console_stream_kwarg(self): @@ -1127,9 +1127,9 @@ def smtp_AUTH(self, arg): # This is only the first part of the login process. But it's enough # for our tests. challenge = base64.b64encode(b'somerandomstring13579') - self.push(str('334 %s' % challenge.decode())) + self.push('334 %s' % challenge.decode()) else: - self.push(str('502 Error: login "%s" not implemented' % arg)) + self.push('502 Error: login "%s" not implemented' % arg) class FakeSMTPServer(smtpd.SMTPServer, threading.Thread): diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index 0528583fccd2..ec48e2ee8e30 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -6,9 +6,7 @@ import os import re import sys -import tokenize import uuid -from io import StringIO import custom_migration_operations.more_operations import custom_migration_operations.operations @@ -20,7 +18,7 @@ from django.db.migrations.writer import ( MigrationWriter, OperationWriter, SettingsReference, ) -from django.test import SimpleTestCase, ignore_warnings, mock +from django.test import SimpleTestCase, mock from django.utils import datetime_safe from django.utils.deconstruct import deconstructible from django.utils.functional import SimpleLazyObject @@ -552,22 +550,7 @@ def test_simple_migration(self): # Just make sure it runs for now, and that things look alright. result = self.safe_exec(output) self.assertIn("Migration", result) - # In order to preserve compatibility with Python 3.2 unicode literals - # prefix shouldn't be added to strings. - tokens = tokenize.generate_tokens(StringIO(str(output)).readline) - for token_type, token_source, (srow, scol), __, line in tokens: - if token_type == tokenize.STRING: - self.assertFalse( - token_source.startswith('u'), - "Unicode literal prefix found at %d:%d: %r" % ( - srow, scol, line.strip() - ) - ) - - # Silence warning on Python 2: Not importing directory - # 'tests/migrations/migrations_test_apps/without_init_file/migrations': - # missing __init__.py - @ignore_warnings(category=ImportWarning) + def test_migration_path(self): test_apps = [ 'migrations.migrations_test_apps.normal', diff --git a/tests/servers/test_basehttp.py b/tests/servers/test_basehttp.py index cf0f8ac41bc9..2e547c430563 100644 --- a/tests/servers/test_basehttp.py +++ b/tests/servers/test_basehttp.py @@ -60,7 +60,7 @@ def test_https(self): handler = WSGIRequestHandler(request, '192.168.0.2', None) with patch_logger('django.server', 'error') as messages: - handler.log_message("GET %s %s", str('\x16\x03'), "4") + handler.log_message("GET %s %s", '\x16\x03', "4") self.assertIn( "You're accessing the development server over HTTPS, " "but it only supports HTTP.", diff --git a/tests/str/tests.py b/tests/str/tests.py index 2d82c03ebfa5..db21ccb2d939 100644 --- a/tests/str/tests.py +++ b/tests/str/tests.py @@ -30,5 +30,5 @@ class Default(models.Model): # coerce the returned value. self.assertIsInstance(obj.__str__(), str) self.assertIsInstance(obj.__repr__(), str) - self.assertEqual(str(obj), str('Default object')) - self.assertEqual(repr(obj), str('')) + self.assertEqual(str(obj), 'Default object') + self.assertEqual(repr(obj), '') diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py index a7f7c2fcc8a2..a1241b2fabd2 100644 --- a/tests/urlpatterns_reverse/tests.py +++ b/tests/urlpatterns_reverse/tests.py @@ -356,7 +356,7 @@ def test_illegal_args_message(self): def test_illegal_kwargs_message(self): msg = "Reverse for 'places' with keyword arguments '{'arg1': 2}' not found. 1 pattern(s) tried:" with self.assertRaisesMessage(NoReverseMatch, msg): - reverse('places', kwargs={str('arg1'): 2}) + reverse('places', kwargs={'arg1': 2}) class ResolverTests(SimpleTestCase): @@ -436,7 +436,7 @@ def test_404_tried_urls_have_names(self): ) for tried, expected in zip(e.args[0]['tried'], url_types_names): for t, e in zip(tried, expected): - self.assertIsInstance(t, e['type']), str('%s is not an instance of %s') % (t, e['type']) + self.assertIsInstance(t, e['type']), '%s is not an instance of %s' % (t, e['type']) if 'name' in e: if not e['name']: self.assertIsNone(t.name, 'Expected no URL name but found %s.' % t.name) diff --git a/tests/utils_tests/test_encoding.py b/tests/utils_tests/test_encoding.py index ca9343674df7..963d0a9a1641 100644 --- a/tests/utils_tests/test_encoding.py +++ b/tests/utils_tests/test_encoding.py @@ -12,14 +12,12 @@ class TestEncodingUtils(unittest.TestCase): def test_force_text_exception(self): """ - Broken __unicode__/__str__ actually raises an error. + Broken __str__ actually raises an error. """ class MyString: def __str__(self): return b'\xc3\xb6\xc3\xa4\xc3\xbc' - __unicode__ = __str__ - # str(s) raises a TypeError if the result is not a text type. with self.assertRaises(TypeError): force_text(MyString()) From 7aba69145dcb436539a7798086748b73a39121e5 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 19 Jan 2017 12:16:04 -0500 Subject: [PATCH 0090/3180] Refs #23919 -- Removed django.test.mock Python 2 compatibility shim. --- django/test/__init__.py | 9 --------- tests/admin_scripts/tests.py | 3 ++- tests/admin_views/test_multidb.py | 4 +++- tests/auth_tests/test_admin_multidb.py | 4 +++- tests/auth_tests/test_auth_backends.py | 3 ++- tests/auth_tests/test_forms.py | 3 ++- tests/auth_tests/test_hashers.py | 4 ++-- tests/auth_tests/test_management.py | 3 ++- tests/auth_tests/test_mixins.py | 4 +++- tests/auth_tests/test_models.py | 4 +++- tests/backends/test_features.py | 4 ++-- tests/backends/tests.py | 3 ++- tests/cache/tests.py | 3 ++- tests/check_framework/test_database.py | 3 ++- tests/check_framework/test_multi_db.py | 4 +++- tests/contenttypes_tests/tests.py | 3 ++- tests/dbshell/test_postgresql_psycopg2.py | 3 ++- tests/files/tests.py | 2 +- tests/fixtures/tests.py | 5 ++--- tests/forms_tests/tests/test_formsets.py | 3 ++- tests/gis_tests/gdal_tests/test_driver.py | 2 +- tests/gis_tests/geos_tests/test_geos.py | 4 ++-- tests/gis_tests/test_geoip2.py | 3 +-- tests/gis_tests/test_ptr.py | 3 ++- tests/i18n/test_compilation.py | 3 ++- tests/i18n/test_extraction.py | 4 ++-- tests/inspectdb/tests.py | 4 ++-- tests/introspection/tests.py | 4 ++-- tests/invalid_models_tests/test_backend_specific.py | 4 +++- tests/migrations/test_autodetector.py | 3 ++- tests/migrations/test_commands.py | 3 ++- tests/migrations/test_writer.py | 3 ++- .../postgres_tests/migrations/0001_setup_extensions.py | 3 ++- tests/requirements/py2.txt | 5 ----- tests/runtests.py | 10 ---------- tests/schema/tests.py | 3 ++- tests/select_for_update/tests.py | 3 ++- tests/serializers/tests.py | 5 ++--- tests/shell/tests.py | 3 ++- tests/signals/tests.py | 4 +++- tests/sitemaps_tests/test_management.py | 3 ++- tests/sitemaps_tests/test_utils.py | 3 ++- tests/staticfiles_tests/test_management.py | 3 ++- tests/test_runner/tests.py | 3 ++- tests/test_utils/test_transactiontestcase.py | 4 +++- tests/urlpatterns_reverse/test_localeregexprovider.py | 3 ++- tests/user_commands/tests.py | 3 ++- tests/utils_tests/test_autoreload.py | 3 ++- tests/utils_tests/test_timezone.py | 3 ++- 49 files changed, 97 insertions(+), 81 deletions(-) delete mode 100644 tests/requirements/py2.txt diff --git a/django/test/__init__.py b/django/test/__init__.py index 63baf8753412..e3561f5ae7bb 100644 --- a/django/test/__init__.py +++ b/django/test/__init__.py @@ -18,12 +18,3 @@ 'skipUnlessAnyDBFeature', 'skipUnlessDBFeature', 'ignore_warnings', 'modify_settings', 'override_settings', 'override_system_checks', 'tag', ] - -# To simplify Django's test suite; not meant as a public API -try: - from unittest import mock # NOQA -except ImportError: - try: - import mock # NOQA - except ImportError: - pass diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index bccefc2d19d9..8494d76f4cd6 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -13,6 +13,7 @@ import tempfile import unittest from io import StringIO +from unittest import mock import django from django import conf, get_version @@ -24,7 +25,7 @@ from django.db.migrations.exceptions import MigrationSchemaMissing from django.db.migrations.recorder import MigrationRecorder from django.test import ( - LiveServerTestCase, SimpleTestCase, TestCase, mock, override_settings, + LiveServerTestCase, SimpleTestCase, TestCase, override_settings, ) from django.utils.encoding import force_text diff --git a/tests/admin_views/test_multidb.py b/tests/admin_views/test_multidb.py index 0273b7aaef2a..3687bec16fa2 100644 --- a/tests/admin_views/test_multidb.py +++ b/tests/admin_views/test_multidb.py @@ -1,8 +1,10 @@ +from unittest import mock + from django.conf.urls import url from django.contrib import admin from django.contrib.auth.models import User from django.db import connections -from django.test import TestCase, mock, override_settings +from django.test import TestCase, override_settings from django.urls import reverse from .models import Book diff --git a/tests/auth_tests/test_admin_multidb.py b/tests/auth_tests/test_admin_multidb.py index 122cb7887629..6b36b50a1623 100644 --- a/tests/auth_tests/test_admin_multidb.py +++ b/tests/auth_tests/test_admin_multidb.py @@ -1,9 +1,11 @@ +from unittest import mock + from django.conf.urls import url from django.contrib import admin from django.contrib.auth.admin import UserAdmin from django.contrib.auth.models import User from django.db import connections -from django.test import TestCase, mock, override_settings +from django.test import TestCase, override_settings from django.urls import reverse diff --git a/tests/auth_tests/test_auth_backends.py b/tests/auth_tests/test_auth_backends.py index 033df9c68205..3d929698c904 100644 --- a/tests/auth_tests/test_auth_backends.py +++ b/tests/auth_tests/test_auth_backends.py @@ -1,4 +1,5 @@ from datetime import date +from unittest import mock from django.contrib.auth import ( BACKEND_SESSION_KEY, SESSION_KEY, authenticate, get_user, signals, @@ -10,7 +11,7 @@ from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.http import HttpRequest from django.test import ( - SimpleTestCase, TestCase, mock, modify_settings, override_settings, + SimpleTestCase, TestCase, modify_settings, override_settings, ) from .models import ( diff --git a/tests/auth_tests/test_forms.py b/tests/auth_tests/test_forms.py index ae6fa313deaa..bbcd75124a16 100644 --- a/tests/auth_tests/test_forms.py +++ b/tests/auth_tests/test_forms.py @@ -1,5 +1,6 @@ import datetime import re +from unittest import mock from django import forms from django.contrib.auth.forms import ( @@ -13,7 +14,7 @@ from django.core import mail from django.core.mail import EmailMultiAlternatives from django.forms.fields import CharField, Field, IntegerField -from django.test import SimpleTestCase, TestCase, mock, override_settings +from django.test import SimpleTestCase, TestCase, override_settings from django.utils import translation from django.utils.encoding import force_text from django.utils.text import capfirst diff --git a/tests/auth_tests/test_hashers.py b/tests/auth_tests/test_hashers.py index 57982017eb3f..4e7bae280dea 100644 --- a/tests/auth_tests/test_hashers.py +++ b/tests/auth_tests/test_hashers.py @@ -1,4 +1,4 @@ -from unittest import skipUnless +from unittest import mock, skipUnless from django.conf.global_settings import PASSWORD_HASHERS from django.contrib.auth.hashers import ( @@ -7,7 +7,7 @@ check_password, get_hasher, identify_hasher, is_password_usable, make_password, ) -from django.test import SimpleTestCase, mock +from django.test import SimpleTestCase from django.test.utils import override_settings from django.utils.encoding import force_bytes diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 15ff551211b5..b1b629021fc9 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -2,6 +2,7 @@ import sys from datetime import date from io import StringIO +from unittest import mock from django.apps import apps from django.contrib.auth import management @@ -14,7 +15,7 @@ from django.core.management import call_command from django.core.management.base import CommandError from django.db import migrations -from django.test import TestCase, mock, override_settings +from django.test import TestCase, override_settings from django.utils.translation import ugettext_lazy as _ from .models import ( diff --git a/tests/auth_tests/test_mixins.py b/tests/auth_tests/test_mixins.py index 4f74890304f7..0a0c5ccdf4a8 100644 --- a/tests/auth_tests/test_mixins.py +++ b/tests/auth_tests/test_mixins.py @@ -1,3 +1,5 @@ +from unittest import mock + from django.contrib.auth import models from django.contrib.auth.mixins import ( LoginRequiredMixin, PermissionRequiredMixin, UserPassesTestMixin, @@ -5,7 +7,7 @@ from django.contrib.auth.models import AnonymousUser from django.core.exceptions import PermissionDenied from django.http import HttpResponse -from django.test import RequestFactory, TestCase, mock +from django.test import RequestFactory, TestCase from django.views.generic import View diff --git a/tests/auth_tests/test_models.py b/tests/auth_tests/test_models.py index ebe3dc083793..f688c5ae74ab 100644 --- a/tests/auth_tests/test_models.py +++ b/tests/auth_tests/test_models.py @@ -1,3 +1,5 @@ +from unittest import mock + from django.conf.global_settings import PASSWORD_HASHERS from django.contrib.auth import get_user_model from django.contrib.auth.base_user import AbstractBaseUser @@ -8,7 +10,7 @@ from django.contrib.contenttypes.models import ContentType from django.core import mail from django.db.models.signals import post_save -from django.test import TestCase, mock, override_settings +from django.test import TestCase, override_settings from .models.with_custom_email_field import CustomEmailField diff --git a/tests/backends/test_features.py b/tests/backends/test_features.py index e7cb3dbfe814..7bd57f042330 100644 --- a/tests/backends/test_features.py +++ b/tests/backends/test_features.py @@ -1,7 +1,7 @@ -from unittest import skipUnless +from unittest import mock, skipUnless from django.db import connection -from django.test import TestCase, mock +from django.test import TestCase class TestDatabaseFeatures(TestCase): diff --git a/tests/backends/tests.py b/tests/backends/tests.py index 662cdc4140a1..214852ea7793 100644 --- a/tests/backends/tests.py +++ b/tests/backends/tests.py @@ -5,6 +5,7 @@ import unittest import warnings from decimal import Decimal, Rounded +from unittest import mock from django.core.exceptions import ImproperlyConfigured from django.core.management.color import no_style @@ -20,7 +21,7 @@ from django.db.models.sql.constants import CURSOR from django.db.utils import ConnectionHandler from django.test import ( - SimpleTestCase, TestCase, TransactionTestCase, mock, override_settings, + SimpleTestCase, TestCase, TransactionTestCase, override_settings, skipIfDBFeature, skipUnlessDBFeature, ) diff --git a/tests/cache/tests.py b/tests/cache/tests.py index bfceff9b0258..5c3ec0fe04ae 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -11,6 +11,7 @@ import time import unittest import warnings +from unittest import mock from django.conf import settings from django.core import management, signals @@ -31,7 +32,7 @@ from django.template.response import TemplateResponse from django.test import ( RequestFactory, SimpleTestCase, TestCase, TransactionTestCase, - ignore_warnings, mock, override_settings, + ignore_warnings, override_settings, ) from django.test.signals import setting_changed from django.utils import timezone, translation diff --git a/tests/check_framework/test_database.py b/tests/check_framework/test_database.py index 594f4ccee6a2..80824ab8e082 100644 --- a/tests/check_framework/test_database.py +++ b/tests/check_framework/test_database.py @@ -1,9 +1,10 @@ import unittest +from unittest import mock from django.core.checks import Tags, run_checks from django.core.checks.registry import CheckRegistry from django.db import connection -from django.test import TestCase, mock +from django.test import TestCase class DatabaseCheckTests(TestCase): diff --git a/tests/check_framework/test_multi_db.py b/tests/check_framework/test_multi_db.py index 700553f47bdb..3080b52fdaf2 100644 --- a/tests/check_framework/test_multi_db.py +++ b/tests/check_framework/test_multi_db.py @@ -1,5 +1,7 @@ +from unittest import mock + from django.db import connections, models -from django.test import TestCase, mock +from django.test import TestCase from django.test.utils import isolate_apps, override_settings diff --git a/tests/contenttypes_tests/tests.py b/tests/contenttypes_tests/tests.py index 7fedcb7abdeb..eecdaa91daaa 100644 --- a/tests/contenttypes_tests/tests.py +++ b/tests/contenttypes_tests/tests.py @@ -1,4 +1,5 @@ import datetime +from unittest import mock from django.apps.registry import Apps, apps from django.conf import settings @@ -12,7 +13,7 @@ from django.core.management import call_command from django.db import connections, migrations, models from django.test import ( - SimpleTestCase, TestCase, TransactionTestCase, mock, override_settings, + SimpleTestCase, TestCase, TransactionTestCase, override_settings, ) from django.test.utils import captured_stdout, isolate_apps from django.utils.encoding import force_text diff --git a/tests/dbshell/test_postgresql_psycopg2.py b/tests/dbshell/test_postgresql_psycopg2.py index f0848ac7b895..26090fb7f180 100644 --- a/tests/dbshell/test_postgresql_psycopg2.py +++ b/tests/dbshell/test_postgresql_psycopg2.py @@ -1,7 +1,8 @@ import os +from unittest import mock from django.db.backends.postgresql.client import DatabaseClient -from django.test import SimpleTestCase, mock +from django.test import SimpleTestCase class PostgreSqlDbshellCommandTestCase(SimpleTestCase): diff --git a/tests/files/tests.py b/tests/files/tests.py index 7323b6987e06..f7d05574d20c 100644 --- a/tests/files/tests.py +++ b/tests/files/tests.py @@ -4,13 +4,13 @@ import tempfile import unittest from io import BytesIO, StringIO, TextIOWrapper +from unittest import mock from django.core.files import File from django.core.files.base import ContentFile from django.core.files.move import file_move_safe from django.core.files.temp import NamedTemporaryFile from django.core.files.uploadedfile import SimpleUploadedFile, UploadedFile -from django.test import mock try: from PIL import Image diff --git a/tests/fixtures/tests.py b/tests/fixtures/tests.py index ca60dd70e8e9..89edea424e90 100644 --- a/tests/fixtures/tests.py +++ b/tests/fixtures/tests.py @@ -4,6 +4,7 @@ import unittest import warnings from io import StringIO +from unittest import mock from django.apps import apps from django.contrib.sites.models import Site @@ -13,9 +14,7 @@ from django.core.management.commands.dumpdata import ProxyModelWarning from django.core.serializers.base import ProgressBar from django.db import IntegrityError, connection -from django.test import ( - TestCase, TransactionTestCase, mock, skipUnlessDBFeature, -) +from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature from django.utils.encoding import force_text from .models import ( diff --git a/tests/forms_tests/tests/test_formsets.py b/tests/forms_tests/tests/test_formsets.py index 125ed273e969..ed8331ad72d1 100644 --- a/tests/forms_tests/tests/test_formsets.py +++ b/tests/forms_tests/tests/test_formsets.py @@ -1,5 +1,6 @@ import datetime from collections import Counter +from unittest import mock from django.forms import ( BaseForm, CharField, DateField, FileField, Form, IntegerField, @@ -7,7 +8,7 @@ ) from django.forms.formsets import BaseFormSet, formset_factory from django.forms.utils import ErrorList -from django.test import SimpleTestCase, mock +from django.test import SimpleTestCase from django.utils.encoding import force_text diff --git a/tests/gis_tests/gdal_tests/test_driver.py b/tests/gis_tests/gdal_tests/test_driver.py index 74d6019db648..6e7e149ed717 100644 --- a/tests/gis_tests/gdal_tests/test_driver.py +++ b/tests/gis_tests/gdal_tests/test_driver.py @@ -1,7 +1,7 @@ import unittest +from unittest import mock from django.contrib.gis.gdal import HAS_GDAL -from django.test import mock if HAS_GDAL: from django.contrib.gis.gdal import Driver, GDALException diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index 8626c4f2003d..b74d3ab7084f 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -4,7 +4,7 @@ import random from binascii import a2b_hex, b2a_hex from io import BytesIO -from unittest import skipUnless +from unittest import mock, skipUnless from django.contrib.gis import gdal from django.contrib.gis.gdal import HAS_GDAL @@ -17,7 +17,7 @@ from django.contrib.gis.shortcuts import numpy from django.template import Context from django.template.engine import Engine -from django.test import SimpleTestCase, mock +from django.test import SimpleTestCase from django.utils.encoding import force_bytes from ..test_data import TestDataMixin diff --git a/tests/gis_tests/test_geoip2.py b/tests/gis_tests/test_geoip2.py index d35dcc336ec9..a362aed9538b 100644 --- a/tests/gis_tests/test_geoip2.py +++ b/tests/gis_tests/test_geoip2.py @@ -1,11 +1,10 @@ import os import unittest -from unittest import skipUnless +from unittest import mock, skipUnless from django.conf import settings from django.contrib.gis.geoip2 import HAS_GEOIP2 from django.contrib.gis.geos import HAS_GEOS, GEOSGeometry -from django.test import mock if HAS_GEOIP2: from django.contrib.gis.geoip2 import GeoIP2, GeoIP2Exception diff --git a/tests/gis_tests/test_ptr.py b/tests/gis_tests/test_ptr.py index 1b8beaf4e79d..ca318a28eb6d 100644 --- a/tests/gis_tests/test_ptr.py +++ b/tests/gis_tests/test_ptr.py @@ -1,7 +1,8 @@ import ctypes +from unittest import mock from django.contrib.gis.ptr import CPointerBase -from django.test import SimpleTestCase, mock +from django.test import SimpleTestCase class CPointerBaseTests(SimpleTestCase): diff --git a/tests/i18n/test_compilation.py b/tests/i18n/test_compilation.py index 5244832e2d5c..ca7dfd4309d8 100644 --- a/tests/i18n/test_compilation.py +++ b/tests/i18n/test_compilation.py @@ -4,6 +4,7 @@ import unittest from io import StringIO from subprocess import Popen +from unittest import mock from django.core.management import ( CommandError, call_command, execute_from_command_line, @@ -11,7 +12,7 @@ from django.core.management.commands.makemessages import \ Command as MakeMessagesCommand from django.core.management.utils import find_command -from django.test import SimpleTestCase, mock, override_settings +from django.test import SimpleTestCase, override_settings from django.test.utils import captured_stderr, captured_stdout from django.utils import translation from django.utils.encoding import force_text diff --git a/tests/i18n/test_extraction.py b/tests/i18n/test_extraction.py index 4189a9e168c1..0adf3d0f1c18 100644 --- a/tests/i18n/test_extraction.py +++ b/tests/i18n/test_extraction.py @@ -4,7 +4,7 @@ import time import warnings from io import StringIO -from unittest import skipUnless +from unittest import mock, skipUnless from admin_scripts.tests import AdminScriptTestCase @@ -14,7 +14,7 @@ from django.core.management.commands.makemessages import \ Command as MakeMessagesCommand from django.core.management.utils import find_command -from django.test import SimpleTestCase, mock, override_settings +from django.test import SimpleTestCase, override_settings from django.test.utils import captured_stderr, captured_stdout from django.utils.encoding import force_text from django.utils.translation import TranslatorCommentWarning diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py index 726a65cd8f8f..49b1819c2651 100644 --- a/tests/inspectdb/tests.py +++ b/tests/inspectdb/tests.py @@ -1,10 +1,10 @@ import re from io import StringIO -from unittest import skipUnless +from unittest import mock, skipUnless from django.core.management import call_command from django.db import connection -from django.test import TestCase, mock, skipUnlessDBFeature +from django.test import TestCase, skipUnlessDBFeature from django.utils.encoding import force_text from .models import ColumnTypes diff --git a/tests/introspection/tests.py b/tests/introspection/tests.py index a85748d958c5..2993592e4f63 100644 --- a/tests/introspection/tests.py +++ b/tests/introspection/tests.py @@ -1,8 +1,8 @@ -from unittest import skipUnless +from unittest import mock, skipUnless from django.db import connection from django.db.utils import DatabaseError -from django.test import TransactionTestCase, mock, skipUnlessDBFeature +from django.test import TransactionTestCase, skipUnlessDBFeature from django.test.utils import ignore_warnings from django.utils.deprecation import RemovedInDjango21Warning diff --git a/tests/invalid_models_tests/test_backend_specific.py b/tests/invalid_models_tests/test_backend_specific.py index 6321b6d7be45..0bdd8995b099 100644 --- a/tests/invalid_models_tests/test_backend_specific.py +++ b/tests/invalid_models_tests/test_backend_specific.py @@ -1,6 +1,8 @@ +from unittest import mock + from django.core.checks import Error from django.db import connections, models -from django.test import SimpleTestCase, mock +from django.test import SimpleTestCase from django.test.utils import isolate_apps diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py index df35181d926e..997c81f29ed6 100644 --- a/tests/migrations/test_autodetector.py +++ b/tests/migrations/test_autodetector.py @@ -1,5 +1,6 @@ import functools import re +from unittest import mock from django.apps import apps from django.conf import settings @@ -11,7 +12,7 @@ from django.db.migrations.loader import MigrationLoader from django.db.migrations.questioner import MigrationQuestioner from django.db.migrations.state import ModelState, ProjectState -from django.test import TestCase, mock, override_settings +from django.test import TestCase, override_settings from django.test.utils import isolate_lru_cache from .models import FoodManager, FoodQuerySet diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index 421b4890a432..f5d7887c355e 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -3,6 +3,7 @@ import io import os import sys +from unittest import mock from django.apps import apps from django.core.management import CommandError, call_command @@ -14,7 +15,7 @@ InconsistentMigrationHistory, MigrationSchemaMissing, ) from django.db.migrations.recorder import MigrationRecorder -from django.test import mock, override_settings +from django.test import override_settings from django.utils.encoding import force_text from .models import UnicodeModel, UnserializableModel diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index ec48e2ee8e30..c1384f6933d4 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -7,6 +7,7 @@ import re import sys import uuid +from unittest import mock import custom_migration_operations.more_operations import custom_migration_operations.operations @@ -18,7 +19,7 @@ from django.db.migrations.writer import ( MigrationWriter, OperationWriter, SettingsReference, ) -from django.test import SimpleTestCase, mock +from django.test import SimpleTestCase from django.utils import datetime_safe from django.utils.deconstruct import deconstructible from django.utils.functional import SimpleLazyObject diff --git a/tests/postgres_tests/migrations/0001_setup_extensions.py b/tests/postgres_tests/migrations/0001_setup_extensions.py index 7add08c49915..6342ba7732df 100644 --- a/tests/postgres_tests/migrations/0001_setup_extensions.py +++ b/tests/postgres_tests/migrations/0001_setup_extensions.py @@ -1,3 +1,5 @@ +from unittest import mock + from django.db import migrations try: @@ -6,7 +8,6 @@ TrigramExtension, UnaccentExtension, ) except ImportError: - from django.test import mock BtreeGinExtension = mock.Mock() CreateExtension = mock.Mock() HStoreExtension = mock.Mock() diff --git a/tests/requirements/py2.txt b/tests/requirements/py2.txt deleted file mode 100644 index 0ed845bb7e1e..000000000000 --- a/tests/requirements/py2.txt +++ /dev/null @@ -1,5 +0,0 @@ --r base.txt -enum34 -# Due to https://github.com/linsomniac/python-memcached/issues/79 in newer versions. -python-memcached <= 1.53 -mock diff --git a/tests/runtests.py b/tests/runtests.py index 57ba84d3db46..4cb36049fda1 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -437,16 +437,6 @@ def paired_tests(paired_test, options, test_labels, parallel): options = parser.parse_args() - # mock is a required dependency - try: - from django.test import mock # NOQA - except ImportError: - print( - "Please install test dependencies first: \n" - "$ pip install -r requirements/py%s.txt" % sys.version_info.major - ) - sys.exit(1) - # Allow including a trailing slash on app_labels for tab completion convenience options.modules = [os.path.normpath(labels) for labels in options.modules] diff --git a/tests/schema/tests.py b/tests/schema/tests.py index 73c1371cfe59..4f62333dbafa 100644 --- a/tests/schema/tests.py +++ b/tests/schema/tests.py @@ -2,6 +2,7 @@ import itertools import unittest from copy import copy +from unittest import mock from django.db import ( DatabaseError, IntegrityError, OperationalError, connection, @@ -19,7 +20,7 @@ from django.db.models.indexes import Index from django.db.transaction import TransactionManagementError, atomic from django.test import ( - TransactionTestCase, mock, skipIfDBFeature, skipUnlessDBFeature, + TransactionTestCase, skipIfDBFeature, skipUnlessDBFeature, ) from django.test.utils import CaptureQueriesContext from django.utils import timezone diff --git a/tests/select_for_update/tests.py b/tests/select_for_update/tests.py index 722412454671..ac1d5b037e46 100644 --- a/tests/select_for_update/tests.py +++ b/tests/select_for_update/tests.py @@ -1,5 +1,6 @@ import threading import time +from unittest import mock from multiple_database.routers import TestRouter @@ -7,7 +8,7 @@ DatabaseError, connection, connections, router, transaction, ) from django.test import ( - TransactionTestCase, mock, override_settings, skipIfDBFeature, + TransactionTestCase, override_settings, skipIfDBFeature, skipUnlessDBFeature, ) from django.test.utils import CaptureQueriesContext diff --git a/tests/serializers/tests.py b/tests/serializers/tests.py index 5750c146a2f4..da453831e0a6 100644 --- a/tests/serializers/tests.py +++ b/tests/serializers/tests.py @@ -1,14 +1,13 @@ from datetime import datetime from io import StringIO +from unittest import mock from django.core import serializers from django.core.serializers import SerializerDoesNotExist from django.core.serializers.base import ProgressBar from django.db import connection, transaction from django.http import HttpResponse -from django.test import ( - SimpleTestCase, mock, override_settings, skipUnlessDBFeature, -) +from django.test import SimpleTestCase, override_settings, skipUnlessDBFeature from django.test.utils import Approximate from django.utils.functional import curry diff --git a/tests/shell/tests.py b/tests/shell/tests.py index f2d1d0e392c5..6d39af3a71b3 100644 --- a/tests/shell/tests.py +++ b/tests/shell/tests.py @@ -1,9 +1,10 @@ import sys import unittest +from unittest import mock from django import __version__ from django.core.management import CommandError, call_command -from django.test import SimpleTestCase, mock +from django.test import SimpleTestCase from django.test.utils import captured_stdin, captured_stdout, patch_logger diff --git a/tests/signals/tests.py b/tests/signals/tests.py index 0c1c885dc41c..c6453b83d040 100644 --- a/tests/signals/tests.py +++ b/tests/signals/tests.py @@ -1,8 +1,10 @@ +from unittest import mock + from django.apps.registry import Apps from django.db import models from django.db.models import signals from django.dispatch import receiver -from django.test import TestCase, mock +from django.test import TestCase from django.test.utils import isolate_apps from .models import Author, Book, Car, Person diff --git a/tests/sitemaps_tests/test_management.py b/tests/sitemaps_tests/test_management.py index 459a1d1b3c52..f0be10224ba4 100644 --- a/tests/sitemaps_tests/test_management.py +++ b/tests/sitemaps_tests/test_management.py @@ -1,5 +1,6 @@ +from unittest import mock + from django.core.management import call_command -from django.test import mock from .base import SitemapTestsBase diff --git a/tests/sitemaps_tests/test_utils.py b/tests/sitemaps_tests/test_utils.py index dc4d6511f362..158f1625ceff 100644 --- a/tests/sitemaps_tests/test_utils.py +++ b/tests/sitemaps_tests/test_utils.py @@ -1,10 +1,11 @@ +from unittest import mock from urllib.parse import urlencode from django.contrib.sitemaps import ( SitemapNotFound, _get_sitemap_full_url, ping_google, ) from django.core.exceptions import ImproperlyConfigured -from django.test import mock, modify_settings, override_settings +from django.test import modify_settings, override_settings from .base import SitemapTestsBase diff --git a/tests/staticfiles_tests/test_management.py b/tests/staticfiles_tests/test_management.py index f0160c60d8b1..a9aeb68c3a69 100644 --- a/tests/staticfiles_tests/test_management.py +++ b/tests/staticfiles_tests/test_management.py @@ -5,6 +5,7 @@ import tempfile import unittest from io import StringIO +from unittest import mock from admin_scripts.tests import AdminScriptTestCase @@ -13,7 +14,7 @@ from django.contrib.staticfiles.management.commands import collectstatic from django.core.exceptions import ImproperlyConfigured from django.core.management import call_command -from django.test import mock, override_settings +from django.test import override_settings from django.test.utils import extend_sys_path from django.utils import timezone from django.utils._os import symlinks_supported diff --git a/tests/test_runner/tests.py b/tests/test_runner/tests.py index 51810fe7bcd6..2de81221356e 100644 --- a/tests/test_runner/tests.py +++ b/tests/test_runner/tests.py @@ -2,6 +2,7 @@ Tests for django test runner """ import unittest +from unittest import mock from admin_scripts.tests import AdminScriptTestCase @@ -10,7 +11,7 @@ from django.core.exceptions import ImproperlyConfigured from django.core.management import call_command from django.test import ( - TestCase, TransactionTestCase, mock, skipUnlessDBFeature, testcases, + TestCase, TransactionTestCase, skipUnlessDBFeature, testcases, ) from django.test.runner import DiscoverRunner from django.test.testcases import connections_support_transactions diff --git a/tests/test_utils/test_transactiontestcase.py b/tests/test_utils/test_transactiontestcase.py index 34588ddefd8d..593c06f7e3a3 100644 --- a/tests/test_utils/test_transactiontestcase.py +++ b/tests/test_utils/test_transactiontestcase.py @@ -1,4 +1,6 @@ -from django.test import TransactionTestCase, mock +from unittest import mock + +from django.test import TransactionTestCase class TestSerializedRollbackInhibitsPostMigrate(TransactionTestCase): diff --git a/tests/urlpatterns_reverse/test_localeregexprovider.py b/tests/urlpatterns_reverse/test_localeregexprovider.py index f05c446eb905..1fbba849c6bf 100644 --- a/tests/urlpatterns_reverse/test_localeregexprovider.py +++ b/tests/urlpatterns_reverse/test_localeregexprovider.py @@ -1,7 +1,8 @@ import os +from unittest import mock from django.core.exceptions import ImproperlyConfigured -from django.test import SimpleTestCase, mock, override_settings +from django.test import SimpleTestCase, override_settings from django.urls import LocaleRegexProvider from django.urls.resolvers import LocaleRegexDescriptor from django.utils import translation diff --git a/tests/user_commands/tests.py b/tests/user_commands/tests.py index a18d49868bd4..6d11068f5b0f 100644 --- a/tests/user_commands/tests.py +++ b/tests/user_commands/tests.py @@ -1,5 +1,6 @@ import os from io import StringIO +from unittest import mock from admin_scripts.tests import AdminScriptTestCase @@ -8,7 +9,7 @@ from django.core.management import BaseCommand, CommandError, find_commands from django.core.management.utils import find_command, popen_wrapper from django.db import connection -from django.test import SimpleTestCase, mock, override_settings +from django.test import SimpleTestCase, override_settings from django.test.utils import captured_stderr, extend_sys_path from django.utils import translation diff --git a/tests/utils_tests/test_autoreload.py b/tests/utils_tests/test_autoreload.py index 6925da1834a7..130f5c8c2a67 100644 --- a/tests/utils_tests/test_autoreload.py +++ b/tests/utils_tests/test_autoreload.py @@ -3,12 +3,13 @@ import shutil import tempfile from importlib import import_module +from unittest import mock import _thread from django import conf from django.contrib import admin -from django.test import SimpleTestCase, mock, override_settings +from django.test import SimpleTestCase, override_settings from django.test.utils import extend_sys_path from django.utils import autoreload from django.utils.translation import trans_real diff --git a/tests/utils_tests/test_timezone.py b/tests/utils_tests/test_timezone.py index 85b396ab1205..3c0b092d8ab1 100644 --- a/tests/utils_tests/test_timezone.py +++ b/tests/utils_tests/test_timezone.py @@ -1,9 +1,10 @@ import datetime import pickle +from unittest import mock import pytz -from django.test import SimpleTestCase, mock, override_settings +from django.test import SimpleTestCase, override_settings from django.utils import timezone CET = pytz.timezone("Europe/Paris") From 289fc1bfa54af563d17549ade8d77553711453a1 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Fri, 20 Jan 2017 15:24:05 +0100 Subject: [PATCH 0091/3180] Refs #23919 -- Removed str_prefix usage --- tests/distinct_on_fields/tests.py | 4 +- tests/forms_tests/tests/test_forms.py | 5 +-- tests/requests/tests.py | 14 +++---- .../filter_tests/test_make_list.py | 9 ++--- tests/test_client_regress/tests.py | 39 +++++++++---------- tests/validators/tests.py | 13 +++---- 6 files changed, 37 insertions(+), 47 deletions(-) diff --git a/tests/distinct_on_fields/tests.py b/tests/distinct_on_fields/tests.py index e1365dab888d..6bb518d2b1ec 100644 --- a/tests/distinct_on_fields/tests.py +++ b/tests/distinct_on_fields/tests.py @@ -1,6 +1,5 @@ from django.db.models import Max from django.test import TestCase, skipUnlessDBFeature -from django.test.utils import str_prefix from .models import Celebrity, Fan, Staff, StaffTag, Tag @@ -78,8 +77,7 @@ def test_basic_distinct_on(self): ( (Staff.objects.distinct('id').order_by('id', 'coworkers__name'). values_list('id', 'coworkers__name')), - [str_prefix("(1, %(_)s'p2')"), str_prefix("(2, %(_)s'p1')"), - str_prefix("(3, %(_)s'p1')"), "(4, None)"] + ["(1, 'p2')", "(2, 'p1')", "(3, 'p1')", "(4, None)"] ), ) for qset, expected in qsets: diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py index dc70519dacf3..98c5ee878325 100644 --- a/tests/forms_tests/tests/test_forms.py +++ b/tests/forms_tests/tests/test_forms.py @@ -19,7 +19,6 @@ from django.http import QueryDict from django.template import Context, Template from django.test import SimpleTestCase -from django.test.utils import str_prefix from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_text from django.utils.html import format_html @@ -2519,9 +2518,7 @@ def my_function(method, post_data): # Case 3: POST with valid data (the success message).) self.assertEqual( my_function('POST', {'username': 'adrian', 'password1': 'secret', 'password2': 'secret'}), - str_prefix( - "VALID: [('password1', %(_)s'secret'), ('password2', %(_)s'secret'), ('username', %(_)s'adrian')]" - ) + "VALID: [('password1', 'secret'), ('password2', 'secret'), ('username', 'adrian')]" ) def test_templates_with_forms(self): diff --git a/tests/requests/tests.py b/tests/requests/tests.py index 0dcaebbca52b..ac331232aa61 100644 --- a/tests/requests/tests.py +++ b/tests/requests/tests.py @@ -13,7 +13,7 @@ from django.http.request import split_domain_port from django.test import RequestFactory, SimpleTestCase, override_settings from django.test.client import FakePayload -from django.test.utils import freeze_time, str_prefix +from django.test.utils import freeze_time from django.utils.http import cookie_date, urlencode from django.utils.timezone import utc @@ -57,17 +57,17 @@ def test_httprequest_repr(self): request.POST = {'post-key': 'post-value'} request.COOKIES = {'post-key': 'post-value'} request.META = {'post-key': 'post-value'} - self.assertEqual(repr(request), str_prefix("")) + self.assertEqual(repr(request), "") def test_httprequest_repr_invalid_method_and_path(self): request = HttpRequest() - self.assertEqual(repr(request), str_prefix("")) + self.assertEqual(repr(request), "") request = HttpRequest() request.method = "GET" - self.assertEqual(repr(request), str_prefix("")) + self.assertEqual(repr(request), "") request = HttpRequest() request.path = "" - self.assertEqual(repr(request), str_prefix("")) + self.assertEqual(repr(request), "") def test_wsgirequest(self): request = WSGIRequest({ @@ -156,13 +156,13 @@ def test_wsgirequest_path_with_force_script_name_trailing_slash(self): def test_wsgirequest_repr(self): request = WSGIRequest({'REQUEST_METHOD': 'get', 'wsgi.input': BytesIO(b'')}) - self.assertEqual(repr(request), str_prefix("")) + self.assertEqual(repr(request), "") request = WSGIRequest({'PATH_INFO': '/somepath/', 'REQUEST_METHOD': 'get', 'wsgi.input': BytesIO(b'')}) request.GET = {'get-key': 'get-value'} request.POST = {'post-key': 'post-value'} request.COOKIES = {'post-key': 'post-value'} request.META = {'post-key': 'post-value'} - self.assertEqual(repr(request), str_prefix("")) + self.assertEqual(repr(request), "") def test_wsgirequest_path_info(self): def wsgi_str(path_info, encoding='utf-8'): diff --git a/tests/template_tests/filter_tests/test_make_list.py b/tests/template_tests/filter_tests/test_make_list.py index 454b394d3b42..17c4cac48036 100644 --- a/tests/template_tests/filter_tests/test_make_list.py +++ b/tests/template_tests/filter_tests/test_make_list.py @@ -1,6 +1,5 @@ from django.template.defaultfilters import make_list from django.test import SimpleTestCase -from django.test.utils import str_prefix from django.utils.safestring import mark_safe from ..utils import setup @@ -15,22 +14,22 @@ class MakeListTests(SimpleTestCase): @setup({'make_list01': '{% autoescape off %}{{ a|make_list }}{% endautoescape %}'}) def test_make_list01(self): output = self.engine.render_to_string('make_list01', {"a": mark_safe("&")}) - self.assertEqual(output, str_prefix("[%(_)s'&']")) + self.assertEqual(output, "['&']") @setup({'make_list02': '{{ a|make_list }}'}) def test_make_list02(self): output = self.engine.render_to_string('make_list02', {"a": mark_safe("&")}) - self.assertEqual(output, str_prefix("[%(_)s'&']")) + self.assertEqual(output, "['&']") @setup({'make_list03': '{% autoescape off %}{{ a|make_list|stringformat:"s"|safe }}{% endautoescape %}'}) def test_make_list03(self): output = self.engine.render_to_string('make_list03', {"a": mark_safe("&")}) - self.assertEqual(output, str_prefix("[%(_)s'&']")) + self.assertEqual(output, "['&']") @setup({'make_list04': '{{ a|make_list|stringformat:"s"|safe }}'}) def test_make_list04(self): output = self.engine.render_to_string('make_list04', {"a": mark_safe("&")}) - self.assertEqual(output, str_prefix("[%(_)s'&']")) + self.assertEqual(output, "['&']") class FunctionTests(SimpleTestCase): diff --git a/tests/test_client_regress/tests.py b/tests/test_client_regress/tests.py index 4589ac33bd0b..d3263d07a61f 100644 --- a/tests/test_client_regress/tests.py +++ b/tests/test_client_regress/tests.py @@ -15,7 +15,7 @@ Client, SimpleTestCase, TestCase, modify_settings, override_settings, ) from django.test.client import RedirectCycleError, RequestFactory, encode_file -from django.test.utils import ContextList, str_prefix +from django.test.utils import ContextList from django.urls import NoReverseMatch, reverse from django.utils.translation import ugettext_lazy @@ -595,21 +595,19 @@ def test_unknown_error(self): self.assertFormError(response, 'form', 'email', 'Some error.') except AssertionError as e: self.assertIn( - str_prefix( - "The field 'email' on form 'form' in context 0 does not " - "contain the error 'Some error.' (actual errors: " - "[%(_)s'Enter a valid email address.'])" - ), str(e) + "The field 'email' on form 'form' in context 0 does not " + "contain the error 'Some error.' (actual errors: " + "['Enter a valid email address.'])", + str(e) ) try: self.assertFormError(response, 'form', 'email', 'Some error.', msg_prefix='abc') except AssertionError as e: self.assertIn( - str_prefix( - "abc: The field 'email' on form 'form' in context 0 does " - "not contain the error 'Some error.' (actual errors: " - "[%(_)s'Enter a valid email address.'])", - ), str(e) + "abc: The field 'email' on form 'form' in context 0 does " + "not contain the error 'Some error.' (actual errors: " + "['Enter a valid email address.'])", + str(e) ) def test_unknown_nonfield_error(self): @@ -719,10 +717,10 @@ def test_no_error_field(self): def test_unknown_error(self): "An assertion is raised if the field doesn't contain the specified error" for prefix, kwargs in self.msg_prefixes: - msg = str_prefix( - prefix + "The field 'email' on formset 'my_formset', form 0 " + msg = prefix + ( + "The field 'email' on formset 'my_formset', form 0 " "in context 0 does not contain the error 'Some error.' " - "(actual errors: [%(_)s'Enter a valid email address.'])" + "(actual errors: ['Enter a valid email address.'])" ) with self.assertRaisesMessage(AssertionError, msg): self.assertFormsetError(self.response_form_errors, 'my_formset', 0, 'email', 'Some error.', **kwargs) @@ -743,10 +741,10 @@ def test_no_nonfield_error(self): def test_unknown_nonfield_error(self): "An assertion is raised if the formsets non-field errors doesn't contain the provided error." for prefix, kwargs in self.msg_prefixes: - msg = str_prefix( - prefix + "The formset 'my_formset', form 0 in context 0 does not " + msg = prefix + ( + "The formset 'my_formset', form 0 in context 0 does not " "contain the non-field error 'Some error.' (actual errors: " - "[%(_)s'Non-field error.'])" + "['Non-field error.'])" ) with self.assertRaisesMessage(AssertionError, msg): self.assertFormsetError(self.response_form_errors, 'my_formset', 0, None, 'Some error.', **kwargs) @@ -766,11 +764,10 @@ def test_no_nonform_error(self): def test_unknown_nonform_error(self): "An assertion is raised if the formsets non-form errors doesn't contain the provided error." for prefix, kwargs in self.msg_prefixes: - msg = str_prefix( - prefix + + msg = prefix + ( "The formset 'my_formset' in context 0 does not contain the " - "non-form error 'Some error.' (actual errors: [%(_)s'Forms " - "in a set must have distinct email addresses.'])" + "non-form error 'Some error.' (actual errors: ['Forms in a set " + "must have distinct email addresses.'])" ) with self.assertRaisesMessage(AssertionError, msg): self.assertFormsetError( diff --git a/tests/validators/tests.py b/tests/validators/tests.py index 124c2b1c6810..ba7038094c0f 100644 --- a/tests/validators/tests.py +++ b/tests/validators/tests.py @@ -16,7 +16,6 @@ validate_unicode_slug, ) from django.test import SimpleTestCase -from django.test.utils import str_prefix try: from PIL import Image # noqa @@ -314,18 +313,18 @@ def test_func(self): class TestSimpleValidators(SimpleTestCase): def test_single_message(self): v = ValidationError('Not Valid') - self.assertEqual(str(v), str_prefix("[%(_)s'Not Valid']")) - self.assertEqual(repr(v), str_prefix("ValidationError([%(_)s'Not Valid'])")) + self.assertEqual(str(v), "['Not Valid']") + self.assertEqual(repr(v), "ValidationError(['Not Valid'])") def test_message_list(self): v = ValidationError(['First Problem', 'Second Problem']) - self.assertEqual(str(v), str_prefix("[%(_)s'First Problem', %(_)s'Second Problem']")) - self.assertEqual(repr(v), str_prefix("ValidationError([%(_)s'First Problem', %(_)s'Second Problem'])")) + self.assertEqual(str(v), "['First Problem', 'Second Problem']") + self.assertEqual(repr(v), "ValidationError(['First Problem', 'Second Problem'])") def test_message_dict(self): v = ValidationError({'first': ['First Problem']}) - self.assertEqual(str(v), str_prefix("{%(_)s'first': [%(_)s'First Problem']}")) - self.assertEqual(repr(v), str_prefix("ValidationError({%(_)s'first': [%(_)s'First Problem']})")) + self.assertEqual(str(v), "{'first': ['First Problem']}") + self.assertEqual(repr(v), "ValidationError({'first': ['First Problem']})") def test_regex_validator_flags(self): with self.assertRaises(TypeError): From 1b06d5e6f6be8e567ce78c892c485af039830d7d Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 20 Jan 2017 18:21:15 -0500 Subject: [PATCH 0092/3180] Refs #23919 -- Removed pysqlite support (it's Python 2 only). --- django/contrib/gis/db/backends/spatialite/base.py | 13 ++++--------- django/db/backends/sqlite3/base.py | 15 ++------------- docs/ref/contrib/gis/install/index.txt | 6 +++--- docs/ref/databases.txt | 12 ------------ 4 files changed, 9 insertions(+), 37 deletions(-) diff --git a/django/contrib/gis/db/backends/spatialite/base.py b/django/contrib/gis/db/backends/spatialite/base.py index 1f0386894566..799e9f167107 100644 --- a/django/contrib/gis/db/backends/spatialite/base.py +++ b/django/contrib/gis/db/backends/spatialite/base.py @@ -4,7 +4,7 @@ from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.db.backends.sqlite3.base import ( - Database, DatabaseWrapper as SQLiteDatabaseWrapper, SQLiteCursorWrapper, + DatabaseWrapper as SQLiteDatabaseWrapper, SQLiteCursorWrapper, ) from django.utils import six @@ -24,11 +24,6 @@ class DatabaseWrapper(SQLiteDatabaseWrapper): ops_class = SpatiaLiteOperations def __init__(self, *args, **kwargs): - # Before we get too far, make sure pysqlite 2.5+ is installed. - if Database.version_info < (2, 5, 0): - raise ImproperlyConfigured('Only versions of pysqlite 2.5+ are ' - 'compatible with SpatiaLite and GeoDjango.') - # Trying to find the location of the SpatiaLite library. # Here we are figuring out the path to the SpatiaLite library # (`libspatialite`). If it's not in the system library path (e.g., it @@ -50,9 +45,9 @@ def get_new_connection(self, conn_params): conn.enable_load_extension(True) except AttributeError: raise ImproperlyConfigured( - 'The pysqlite library does not support C extension loading. ' - 'Both SQLite and pysqlite must be configured to allow ' - 'the loading of extensions to use SpatiaLite.') + 'SpatiaLite requires SQLite to be configured to allow ' + 'extension loading.' + ) # Loading the SpatiaLite library extension on the connection, and returning # the created cursor. cur = conn.cursor(factory=SQLiteCursorWrapper) diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py index 07c4ceb1e74c..2db7276e4067 100644 --- a/django/db/backends/sqlite3/base.py +++ b/django/db/backends/sqlite3/base.py @@ -1,12 +1,10 @@ """ -SQLite3 backend for django. - -Works with either the pysqlite2 module or the sqlite3 module in the -standard library. +SQLite3 backend for the sqlite3 module in the standard library. """ import decimal import re import warnings +from sqlite3 import dbapi2 as Database import pytz @@ -20,15 +18,6 @@ ) from django.utils.encoding import force_text -try: - try: - from pysqlite2 import dbapi2 as Database - except ImportError: - from sqlite3 import dbapi2 as Database -except ImportError as exc: - raise ImproperlyConfigured("Error loading either pysqlite2 or sqlite3 modules (tried in that order): %s" % exc) - -# Some of these import sqlite3, so import them after checking if it's installed. from .client import DatabaseClient # isort:skip from .creation import DatabaseCreation # isort:skip from .features import DatabaseFeatures # isort:skip diff --git a/docs/ref/contrib/gis/install/index.txt b/docs/ref/contrib/gis/install/index.txt index cb919628d05b..06990943ef3d 100644 --- a/docs/ref/contrib/gis/install/index.txt +++ b/docs/ref/contrib/gis/install/index.txt @@ -61,7 +61,7 @@ Database Library Requirements Supported Versions Notes PostgreSQL GEOS, GDAL, PROJ.4, PostGIS 9.3+ Requires PostGIS. MySQL GEOS, GDAL 5.5+ Not OGC-compliant; :ref:`limited functionality `. Oracle GEOS, GDAL 11.2+ XE not supported. -SQLite GEOS, GDAL, PROJ.4, SpatiaLite 3.6.+ Requires SpatiaLite 4.0+, pysqlite2 2.5+ +SQLite GEOS, GDAL, PROJ.4, SpatiaLite 3.6.+ Requires SpatiaLite 4.0+ ================== ============================== ================== ========================================= See also `this comparison matrix`__ on the OSGeo Wiki for @@ -268,8 +268,8 @@ KyngChaos packages William Kyngesburye provides a number of `geospatial library binary packages`__ that make it simple to get GeoDjango installed on OS X without compiling them from source. However, the `Apple Developer Tools`_ are still necessary -for compiling the Python database adapters :ref:`psycopg2_kyngchaos` (for PostGIS) -and `pysqlite2 `_ (for SpatiaLite). +for compiling the Python database adapters :ref:`psycopg2_kyngchaos` (for +PostGIS). .. note:: diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt index 5ba10664d408..db622439f4ba 100644 --- a/docs/ref/databases.txt +++ b/docs/ref/databases.txt @@ -663,18 +663,6 @@ substring filtering. .. _documented at sqlite.org: https://www.sqlite.org/faq.html#q18 -.. _using-newer-versions-of-pysqlite: - -Using newer versions of the SQLite DB-API 2.0 driver ----------------------------------------------------- - -Django will use a ``pysqlite2`` module in preference to ``sqlite3`` as shipped -with the Python standard library if it finds one is available. - -This provides the ability to upgrade both the DB-API 2.0 interface or SQLite 3 -itself to versions newer than the ones included with your particular Python -binary distribution, if needed. - "Database is locked" errors --------------------------- From 503e944ac792498e7b38c799d8e4b06f74e9d65a Mon Sep 17 00:00:00 2001 From: Alasdair Nicol Date: Thu, 19 Jan 2017 20:56:39 +0000 Subject: [PATCH 0093/3180] Refs #16859 -- Updated CSRF FAQ to mention CSRF_USE_SESSIONS setting. --- docs/ref/csrf.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/ref/csrf.txt b/docs/ref/csrf.txt index 488d31187f90..fe5a70845ec7 100644 --- a/docs/ref/csrf.txt +++ b/docs/ref/csrf.txt @@ -527,13 +527,16 @@ Some security audit tools flag this as a problem but as mentioned before, an attacker cannot steal a user's browser's CSRF cookie. "Stealing" or modifying *your own* token using Firebug, Chrome dev tools, etc. isn't a vulnerability. -Is the fact that Django's CSRF protection isn't linked to a session a problem? ------------------------------------------------------------------------------- +Is it a problem that Django's CSRF protection isn't linked to a session by default? +----------------------------------------------------------------------------------- No, this is by design. Not linking CSRF protection to a session allows using the protection on sites such as a `pastebin` that allow submissions from anonymous users which don't have a session. +If you wish to store the CSRF token in the user's session, use the +:setting:`CSRF_USE_SESSIONS` setting. + Why might a user encounter a CSRF validation failure after logging in? ---------------------------------------------------------------------- From a76d12ceb437a68efb6a19a588fb29a7a0e5a5e2 Mon Sep 17 00:00:00 2001 From: Arkadiusz Adamski Date: Sat, 21 Jan 2017 13:40:33 +0100 Subject: [PATCH 0094/3180] Removed unused imports in example migrations. --- docs/howto/writing-migrations.txt | 2 +- docs/ref/migration-operations.txt | 2 +- docs/topics/migrations.txt | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/howto/writing-migrations.txt b/docs/howto/writing-migrations.txt index 02579eeeb4ad..bd1968ccb800 100644 --- a/docs/howto/writing-migrations.txt +++ b/docs/howto/writing-migrations.txt @@ -152,7 +152,7 @@ the respective field according to your needs. :filename: 0005_populate_uuid_values.py # Generated by Django A.B on YYYY-MM-DD HH:MM - from django.db import migrations, models + from django.db import migrations import uuid def gen_uuid(apps, schema_editor): diff --git a/docs/ref/migration-operations.txt b/docs/ref/migration-operations.txt index e6e6f73a99d1..a977317a8045 100644 --- a/docs/ref/migration-operations.txt +++ b/docs/ref/migration-operations.txt @@ -310,7 +310,7 @@ class in the migration file, and just pass it to ``RunPython``. Here's an example of using ``RunPython`` to create some initial objects on a ``Country`` model:: - from django.db import migrations, models + from django.db import migrations def forwards_func(apps, schema_editor): # We get the model from the versioned app registry; diff --git a/docs/topics/migrations.txt b/docs/topics/migrations.txt index 5b872cb58413..0acf1a21106b 100644 --- a/docs/topics/migrations.txt +++ b/docs/topics/migrations.txt @@ -455,7 +455,7 @@ the file in the right place, suggest a name, and add dependencies for you):: Then, open up the file; it should look something like this:: # Generated by Django A.B on YYYY-MM-DD HH:MM - from django.db import migrations, models + from django.db import migrations class Migration(migrations.Migration): initial = True @@ -482,7 +482,7 @@ combined values of ``first_name`` and ``last_name`` (we've come to our senses and realized that not everyone has first and last names). All we need to do is use the historical model and iterate over the rows:: - from django.db import migrations, models + from django.db import migrations def combine_names(apps, schema_editor): # We can't import the Person model directly as it may be a newer From 8249c5b38237172152835784bda2b55c2c7a672e Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 21 Jan 2017 13:06:52 -0500 Subject: [PATCH 0095/3180] Added a missing floatformat test and simplified another. --- tests/template_tests/filter_tests/test_floatformat.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/template_tests/filter_tests/test_floatformat.py b/tests/template_tests/filter_tests/test_floatformat.py index e0f7666ff0d1..cfc3eaf73b24 100644 --- a/tests/template_tests/filter_tests/test_floatformat.py +++ b/tests/template_tests/filter_tests/test_floatformat.py @@ -29,6 +29,7 @@ def test_inputs(self): self.assertEqual(floatformat(0.07), '0.1') self.assertEqual(floatformat(0.007), '0.0') self.assertEqual(floatformat(0.0), '0') + self.assertEqual(floatformat(7.7, 0), '8') self.assertEqual(floatformat(7.7, 3), '7.700') self.assertEqual(floatformat(6.000000, 3), '6.000') self.assertEqual(floatformat(6.200000, 3), '6.200') @@ -63,13 +64,10 @@ def test_zero_values(self): def test_infinity(self): pos_inf = float(1e30000) - self.assertEqual(floatformat(pos_inf), str(pos_inf)) - neg_inf = float(-1e30000) - self.assertEqual(floatformat(neg_inf), str(neg_inf)) - - nan = pos_inf / pos_inf - self.assertEqual(floatformat(nan), str(nan)) + self.assertEqual(floatformat(pos_inf), 'inf') + self.assertEqual(floatformat(neg_inf), '-inf') + self.assertEqual(floatformat(pos_inf / pos_inf), 'nan') def test_float_dunder_method(self): class FloatWrapper: From 9e6e32bf5dce69f3257fcbe4ce80839fb65ab3df Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 21 Jan 2017 13:20:17 -0500 Subject: [PATCH 0096/3180] Refs #23919 -- Removed django.utils.decorators.available_attrs() usage. It's only needed to workaround a bug on Python 2. --- django/contrib/auth/decorators.py | 3 +-- django/core/handlers/exception.py | 3 +-- django/test/utils.py | 3 +-- django/utils/decorators.py | 5 +++-- django/views/decorators/cache.py | 8 +++----- django/views/decorators/clickjacking.py | 8 +++----- django/views/decorators/csrf.py | 4 ++-- django/views/decorators/http.py | 6 +++--- django/views/decorators/vary.py | 5 ++--- 9 files changed, 19 insertions(+), 26 deletions(-) diff --git a/django/contrib/auth/decorators.py b/django/contrib/auth/decorators.py index 807ea8a3f61b..55a23ade56a8 100644 --- a/django/contrib/auth/decorators.py +++ b/django/contrib/auth/decorators.py @@ -5,7 +5,6 @@ from django.contrib.auth import REDIRECT_FIELD_NAME from django.core.exceptions import PermissionDenied from django.shortcuts import resolve_url -from django.utils.decorators import available_attrs def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME): @@ -16,7 +15,7 @@ def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIE """ def decorator(view_func): - @wraps(view_func, assigned=available_attrs(view_func)) + @wraps(view_func) def _wrapped_view(request, *args, **kwargs): if test_func(request.user): return view_func(request, *args, **kwargs) diff --git a/django/core/handlers/exception.py b/django/core/handlers/exception.py index 5e489f64d32c..febe5d8c87bd 100644 --- a/django/core/handlers/exception.py +++ b/django/core/handlers/exception.py @@ -8,7 +8,6 @@ from django.http import Http404 from django.http.multipartparser import MultiPartParserError from django.urls import get_resolver, get_urlconf -from django.utils.decorators import available_attrs from django.utils.encoding import force_text from django.views import debug @@ -28,7 +27,7 @@ def convert_exception_to_response(get_response): no middleware leaks an exception and that the next middleware in the stack can rely on getting a response instead of an exception. """ - @wraps(get_response, assigned=available_attrs(get_response)) + @wraps(get_response) def inner(request): try: response = get_response(request) diff --git a/django/test/utils.py b/django/test/utils.py index a587e1fa9651..2bd6bb4d0f66 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -22,7 +22,6 @@ from django.template import Template from django.test.signals import setting_changed, template_rendered from django.urls import get_script_prefix, set_script_prefix -from django.utils.decorators import available_attrs from django.utils.translation import deactivate try: @@ -370,7 +369,7 @@ def tearDown(inner_self): raise TypeError('Can only decorate subclasses of unittest.TestCase') def decorate_callable(self, func): - @wraps(func, assigned=available_attrs(func)) + @wraps(func) def inner(*args, **kwargs): with self as context: if self.kwarg_name: diff --git a/django/utils/decorators.py b/django/utils/decorators.py index a3af946b3350..7621d2fabdf4 100644 --- a/django/utils/decorators.py +++ b/django/utils/decorators.py @@ -79,7 +79,7 @@ def dummy(*args, **kwargs): # Don't worry about making _dec look similar to a list/tuple as it's rather # meaningless. if not hasattr(decorator, '__iter__'): - update_wrapper(_dec, decorator, assigned=available_attrs(decorator)) + update_wrapper(_dec, decorator) # Change the name to aid debugging. if hasattr(decorator, '__name__'): _dec.__name__ = 'method_decorator(%s)' % decorator.__name__ @@ -113,6 +113,7 @@ def decorator_from_middleware(middleware_class): return make_middleware_decorator(middleware_class)() +# Unused, for backwards compatibility in Django 2.0. def available_attrs(fn): """ Return the list of functools-wrappable attributes on a callable. @@ -127,7 +128,7 @@ def _make_decorator(*m_args, **m_kwargs): middleware = middleware_class(*m_args, **m_kwargs) def _decorator(view_func): - @wraps(view_func, assigned=available_attrs(view_func)) + @wraps(view_func) def _wrapped_view(request, *args, **kwargs): if hasattr(middleware, 'process_request'): result = middleware.process_request(request) diff --git a/django/views/decorators/cache.py b/django/views/decorators/cache.py index 07e0e70946d3..18238aaae7e0 100644 --- a/django/views/decorators/cache.py +++ b/django/views/decorators/cache.py @@ -2,9 +2,7 @@ from django.middleware.cache import CacheMiddleware from django.utils.cache import add_never_cache_headers, patch_cache_control -from django.utils.decorators import ( - available_attrs, decorator_from_middleware_with_args, -) +from django.utils.decorators import decorator_from_middleware_with_args def cache_page(*args, **kwargs): @@ -38,7 +36,7 @@ def cache_page(*args, **kwargs): def cache_control(**kwargs): def _cache_controller(viewfunc): - @wraps(viewfunc, assigned=available_attrs(viewfunc)) + @wraps(viewfunc) def _cache_controlled(request, *args, **kw): response = viewfunc(request, *args, **kw) patch_cache_control(response, **kwargs) @@ -52,7 +50,7 @@ def never_cache(view_func): Decorator that adds headers to a response so that it will never be cached. """ - @wraps(view_func, assigned=available_attrs(view_func)) + @wraps(view_func) def _wrapped_view_func(request, *args, **kwargs): response = view_func(request, *args, **kwargs) add_never_cache_headers(response) diff --git a/django/views/decorators/clickjacking.py b/django/views/decorators/clickjacking.py index bb63c500962b..828ae3c1fd3f 100644 --- a/django/views/decorators/clickjacking.py +++ b/django/views/decorators/clickjacking.py @@ -1,7 +1,5 @@ from functools import wraps -from django.utils.decorators import available_attrs - def xframe_options_deny(view_func): """ @@ -20,7 +18,7 @@ def wrapped_view(*args, **kwargs): if resp.get('X-Frame-Options') is None: resp['X-Frame-Options'] = 'DENY' return resp - return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view) + return wraps(view_func)(wrapped_view) def xframe_options_sameorigin(view_func): @@ -40,7 +38,7 @@ def wrapped_view(*args, **kwargs): if resp.get('X-Frame-Options') is None: resp['X-Frame-Options'] = 'SAMEORIGIN' return resp - return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view) + return wraps(view_func)(wrapped_view) def xframe_options_exempt(view_func): @@ -58,4 +56,4 @@ def wrapped_view(*args, **kwargs): resp = view_func(*args, **kwargs) resp.xframe_options_exempt = True return resp - return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view) + return wraps(view_func)(wrapped_view) diff --git a/django/views/decorators/csrf.py b/django/views/decorators/csrf.py index d8c89c176ca0..d5ff6da90e89 100644 --- a/django/views/decorators/csrf.py +++ b/django/views/decorators/csrf.py @@ -1,7 +1,7 @@ from functools import wraps from django.middleware.csrf import CsrfViewMiddleware, get_token -from django.utils.decorators import available_attrs, decorator_from_middleware +from django.utils.decorators import decorator_from_middleware csrf_protect = decorator_from_middleware(CsrfViewMiddleware) csrf_protect.__name__ = "csrf_protect" @@ -57,4 +57,4 @@ def csrf_exempt(view_func): def wrapped_view(*args, **kwargs): return view_func(*args, **kwargs) wrapped_view.csrf_exempt = True - return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view) + return wraps(view_func)(wrapped_view) diff --git a/django/views/decorators/http.py b/django/views/decorators/http.py index 21b56a3202f0..f0eeeb00053e 100644 --- a/django/views/decorators/http.py +++ b/django/views/decorators/http.py @@ -9,7 +9,7 @@ from django.http import HttpResponseNotAllowed from django.middleware.http import ConditionalGetMiddleware from django.utils.cache import get_conditional_response -from django.utils.decorators import available_attrs, decorator_from_middleware +from django.utils.decorators import decorator_from_middleware from django.utils.http import http_date, quote_etag conditional_page = decorator_from_middleware(ConditionalGetMiddleware) @@ -29,7 +29,7 @@ def my_view(request): Note that request methods should be in uppercase. """ def decorator(func): - @wraps(func, assigned=available_attrs(func)) + @wraps(func) def inner(request, *args, **kwargs): if request.method not in request_method_list: logger.warning( @@ -75,7 +75,7 @@ def condition(etag_func=None, last_modified_func=None): already have them. """ def decorator(func): - @wraps(func, assigned=available_attrs(func)) + @wraps(func) def inner(request, *args, **kwargs): # Compute values (if any) for the requested resource. def get_last_modified(): diff --git a/django/views/decorators/vary.py b/django/views/decorators/vary.py index df92c65c5ce1..68b783ed3a01 100644 --- a/django/views/decorators/vary.py +++ b/django/views/decorators/vary.py @@ -1,7 +1,6 @@ from functools import wraps from django.utils.cache import patch_vary_headers -from django.utils.decorators import available_attrs def vary_on_headers(*headers): @@ -16,7 +15,7 @@ def index(request): Note that the header names are not case-sensitive. """ def decorator(func): - @wraps(func, assigned=available_attrs(func)) + @wraps(func) def inner_func(*args, **kwargs): response = func(*args, **kwargs) patch_vary_headers(response, headers) @@ -34,7 +33,7 @@ def vary_on_cookie(func): def index(request): ... """ - @wraps(func, assigned=available_attrs(func)) + @wraps(func) def inner_func(*args, **kwargs): response = func(*args, **kwargs) patch_vary_headers(response, ('Cookie',)) From 990ce6386c3c96961ee9fa7197b6c97cc5617d5e Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 21 Jan 2017 13:53:35 -0500 Subject: [PATCH 0097/3180] Refs #5748 -- Removed obsolete Python/Windows workarounds in floatformat filter. --- django/template/defaultfilters.py | 56 ++++++++++--------------------- 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index 828255b73ca8..a85e54524253 100644 --- a/django/template/defaultfilters.py +++ b/django/template/defaultfilters.py @@ -83,19 +83,6 @@ def escapejs_filter(value): return escapejs(value) -# Values for testing floatformat input against infinity and NaN representations, -# which differ across platforms and Python versions. Some (i.e. old Windows -# ones) are not recognized by Decimal but we want to return them unchanged vs. -# returning an empty string as we do for completely invalid input. Note these -# need to be built up from values that are not inf/nan, since inf/nan values do -# not reload properly from .pyc files on Windows prior to some level of Python 2.5 -# (see Python Issue757815 and Issue1080440). -pos_inf = 1e200 * 1e200 -neg_inf = -1e200 * 1e200 -nan = (1e200 * 1e200) // (1e200 * 1e200) -special_floats = [str(pos_inf), str(neg_inf), str(nan)] - - @register.filter(is_safe=True) def floatformat(text, arg=-1): """ @@ -132,14 +119,10 @@ def floatformat(text, arg=-1): try: input_val = repr(text) d = Decimal(input_val) - except UnicodeEncodeError: - return '' except InvalidOperation: - if input_val in special_floats: - return input_val try: d = Decimal(force_text(float(text))) - except (ValueError, InvalidOperation, TypeError, UnicodeEncodeError): + except (ValueError, InvalidOperation, TypeError): return '' try: p = int(arg) @@ -158,26 +141,23 @@ def floatformat(text, arg=-1): exp = Decimal(1) else: exp = Decimal('1.0') / (Decimal(10) ** abs(p)) - try: - # Set the precision high enough to avoid an exception, see #15789. - tupl = d.as_tuple() - units = len(tupl[1]) - units += -tupl[2] if m else tupl[2] - prec = abs(p) + units + 1 - - # Avoid conversion to scientific notation by accessing `sign`, `digits` - # and `exponent` from `Decimal.as_tuple()` directly. - sign, digits, exponent = d.quantize(exp, ROUND_HALF_UP, Context(prec=prec)).as_tuple() - digits = [str(digit) for digit in reversed(digits)] - while len(digits) <= abs(exponent): - digits.append('0') - digits.insert(-exponent, '.') - if sign: - digits.append('-') - number = ''.join(reversed(digits)) - return mark_safe(formats.number_format(number, abs(p))) - except InvalidOperation: - return input_val + # Set the precision high enough to avoid an exception (#15789). + tupl = d.as_tuple() + units = len(tupl[1]) + units += -tupl[2] if m else tupl[2] + prec = abs(p) + units + 1 + + # Avoid conversion to scientific notation by accessing `sign`, `digits`, + # and `exponent` from Decimal.as_tuple() directly. + sign, digits, exponent = d.quantize(exp, ROUND_HALF_UP, Context(prec=prec)).as_tuple() + digits = [str(digit) for digit in reversed(digits)] + while len(digits) <= abs(exponent): + digits.append('0') + digits.insert(-exponent, '.') + if sign: + digits.append('-') + number = ''.join(reversed(digits)) + return mark_safe(formats.number_format(number, abs(p))) @register.filter(is_safe=True) From c22212220a7900173358a1f16179dcfc9e03de78 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Wed, 18 Jan 2017 22:52:25 +0100 Subject: [PATCH 0098/3180] Refs #23919 -- Removed re.U and re.UNICODE (default on Python 3). --- django/core/validators.py | 2 +- django/db/migrations/serializer.py | 8 ++++++-- django/forms/fields.py | 2 +- django/template/base.py | 2 +- django/urls/resolvers.py | 6 +++--- django/utils/text.py | 8 ++++---- tests/migrations/test_writer.py | 14 +++++++------- 7 files changed, 23 insertions(+), 19 deletions(-) diff --git a/django/core/validators.py b/django/core/validators.py index 715d81bdbaf4..b3b76f25f9ac 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -241,7 +241,7 @@ def __eq__(self, other): 'invalid' ) -slug_unicode_re = _lazy_re_compile(r'^[-\w]+\Z', re.U) +slug_unicode_re = _lazy_re_compile(r'^[-\w]+\Z') validate_unicode_slug = RegexValidator( slug_unicode_re, _("Enter a valid 'slug' consisting of Unicode letters, numbers, underscores, or hyphens."), diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index eff3ebe0d708..e15ffd87b5fd 100644 --- a/django/db/migrations/serializer.py +++ b/django/db/migrations/serializer.py @@ -5,6 +5,7 @@ import enum import functools import math +import re import types import uuid from importlib import import_module @@ -241,11 +242,14 @@ class RegexSerializer(BaseSerializer): def serialize(self): imports = {"import re"} regex_pattern, pattern_imports = serializer_factory(self.value.pattern).serialize() - regex_flags, flag_imports = serializer_factory(self.value.flags).serialize() + # Turn off default implicit flags (e.g. re.U) because regexes with the + # same implicit and explicit flags aren't equal. + flags = self.value.flags ^ re.compile('').flags + regex_flags, flag_imports = serializer_factory(flags).serialize() imports.update(pattern_imports) imports.update(flag_imports) args = [regex_pattern] - if self.value.flags: + if flags: args.append(regex_flags) return "re.compile(%s)" % ', '.join(args), imports diff --git a/django/forms/fields.py b/django/forms/fields.py index b7846d43a685..b88f3ea61a92 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -522,7 +522,7 @@ def _get_regex(self): def _set_regex(self, regex): if isinstance(regex, str): - regex = re.compile(regex, re.UNICODE) + regex = re.compile(regex) self._regex = regex if hasattr(self, '_regex_validator') and self._regex_validator in self.validators: self.validators.remove(self._regex_validator) diff --git a/django/template/base.py b/django/template/base.py index f6259ec7cfcc..b4d129c0a45a 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -621,7 +621,7 @@ def find_filter(self, filter_name): 'arg_sep': re.escape(FILTER_ARGUMENT_SEPARATOR), } -filter_re = re.compile(filter_raw_string, re.UNICODE | re.VERBOSE) +filter_re = re.compile(filter_raw_string, re.VERBOSE) class FilterExpression: diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py index 376aedc3c1d6..0dc6b8974544 100644 --- a/django/urls/resolvers.py +++ b/django/urls/resolvers.py @@ -99,7 +99,7 @@ def _compile(self, regex): Compile and return the given regular expression. """ try: - return re.compile(regex, re.UNICODE) + return re.compile(regex) except re.error as e: raise ImproperlyConfigured( '"%s" is not a valid regular expression: %s' % (regex, e) @@ -453,7 +453,7 @@ def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs): # Then, if we have a match, redo the substitution with quoted # arguments in order to return a properly encoded URL. candidate_pat = _prefix.replace('%', '%%') + result - if re.search('^%s%s' % (re.escape(_prefix), pattern), candidate_pat % candidate_subs, re.UNICODE): + if re.search('^%s%s' % (re.escape(_prefix), pattern), candidate_pat % candidate_subs): # safe characters from `pchar` definition of RFC 3986 url = urlquote(candidate_pat % candidate_subs, safe=RFC3986_SUBDELIMS + str('/~:@')) # Don't allow construction of scheme relative urls. @@ -513,5 +513,5 @@ def regex(self): regex_string = '' else: regex_string = '^%s/' % language_code - self._regex_dict[language_code] = re.compile(regex_string, re.UNICODE) + self._regex_dict[language_code] = re.compile(regex_string) return self._regex_dict[language_code] diff --git a/django/utils/text.py b/django/utils/text.py index 20df82c85b2e..26a8b859ef89 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -19,8 +19,8 @@ def capfirst(x): # Set up regular expressions -re_words = re.compile(r'<.*?>|((?:\w[-\w]*|&.*?;)+)', re.U | re.S) -re_chars = re.compile(r'<.*?>|(.)', re.U | re.S) +re_words = re.compile(r'<.*?>|((?:\w[-\w]*|&.*?;)+)', re.S) +re_chars = re.compile(r'<.*?>|(.)', re.S) re_tag = re.compile(r'<(/)?([^ ]+?)(?:(\s*/)| .*?)?>', re.S) re_newlines = re.compile(r'\r\n|\r') # Used in normalize_newlines re_camel_case = re.compile(r'(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))') @@ -417,8 +417,8 @@ def slugify(value, allow_unicode=False): value = force_text(value) if allow_unicode: value = unicodedata.normalize('NFKC', value) - value = re.sub(r'[^\w\s-]', '', value, flags=re.U).strip().lower() - return mark_safe(re.sub(r'[-\s]+', '-', value, flags=re.U)) + value = re.sub(r'[^\w\s-]', '', value).strip().lower() + return mark_safe(re.sub(r'[-\s]+', '-', value)) value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii') value = re.sub(r'[^\w\s-]', '', value).strip().lower() return mark_safe(re.sub(r'[-\s]+', '-', value)) diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index c1384f6933d4..1de0fec0aaa5 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -247,7 +247,7 @@ def test_serialize_builtin_types(self): ) def test_serialize_lazy_objects(self): - pattern = re.compile(r'^foo$', re.UNICODE) + pattern = re.compile(r'^foo$') lazy_pattern = SimpleLazyObject(lambda: pattern) self.assertEqual(self.serialize_round_trip(lazy_pattern), pattern) @@ -403,7 +403,7 @@ def test_serialize_compiled_regex(self): """ Make sure compiled regex can be serialized. """ - regex = re.compile(r'^\w+$', re.U) + regex = re.compile(r'^\w+$') self.assertSerializedEqual(regex) def test_serialize_class_based_validators(self): @@ -417,18 +417,18 @@ def test_serialize_class_based_validators(self): self.serialize_round_trip(validator) # Test with a compiled regex. - validator = RegexValidator(regex=re.compile(r'^\w+$', re.U)) + validator = RegexValidator(regex=re.compile(r'^\w+$')) string = MigrationWriter.serialize(validator)[0] - self.assertEqual(string, "django.core.validators.RegexValidator(regex=re.compile('^\\\\w+$', 32))") + self.assertEqual(string, "django.core.validators.RegexValidator(regex=re.compile('^\\\\w+$'))") self.serialize_round_trip(validator) # Test a string regex with flag - validator = RegexValidator(r'^[0-9]+$', flags=re.U) + validator = RegexValidator(r'^[0-9]+$', flags=re.S) string = MigrationWriter.serialize(validator)[0] if PY36: - self.assertEqual(string, "django.core.validators.RegexValidator('^[0-9]+$', flags=re.RegexFlag(32))") + self.assertEqual(string, "django.core.validators.RegexValidator('^[0-9]+$', flags=re.RegexFlag(16))") else: - self.assertEqual(string, "django.core.validators.RegexValidator('^[0-9]+$', flags=32)") + self.assertEqual(string, "django.core.validators.RegexValidator('^[0-9]+$', flags=16)") self.serialize_round_trip(validator) # Test message and code From d170c63351944fd91b2206d10f89e7ff75b53b76 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 21 Jan 2017 20:02:00 -0500 Subject: [PATCH 0099/3180] Refs #23919 -- Removed misc references to Python 2. --- INSTALL | 9 +-------- django/apps/config.py | 7 +++---- django/conf/project_template/manage.py-tpl | 19 ++++++------------- django/contrib/gis/measure.py | 9 --------- django/core/checks/model_checks.py | 2 +- django/core/files/temp.py | 11 +++++------ django/core/servers/basehttp.py | 1 - django/db/backends/mysql/base.py | 1 - django/db/backends/oracle/introspection.py | 2 +- django/db/migrations/serializer.py | 16 +++------------- django/db/models/expressions.py | 6 ------ django/db/models/query_utils.py | 5 +---- django/db/models/sql/compiler.py | 10 ++-------- django/forms/utils.py | 6 +----- django/test/utils.py | 2 +- django/utils/deconstruct.py | 2 +- django/utils/html.py | 4 +--- django/utils/html_parser.py | 4 +--- django/utils/translation/trans_real.py | 9 +-------- docs/ref/applications.txt | 4 ++-- tests/admin_changelist/tests.py | 4 ---- tests/admin_scripts/tests.py | 3 --- tests/admin_views/admin.py | 3 +-- tests/auth_tests/test_context_processors.py | 16 +--------------- tests/cache/tests.py | 9 --------- tests/decorators/tests.py | 4 ++-- tests/expressions_case/tests.py | 2 -- tests/files/tests.py | 3 --- tests/forms_tests/tests/test_forms.py | 19 +------------------ tests/i18n/utils.py | 2 +- tests/queries/test_qs_combinators.py | 1 - tests/settings_tests/tests.py | 3 +-- tests/template_tests/utils.py | 2 +- tests/utils_tests/test_simplelazyobject.py | 7 +------ 34 files changed, 40 insertions(+), 167 deletions(-) diff --git a/INSTALL b/INSTALL index 92be6da6506d..be6487747665 100644 --- a/INSTALL +++ b/INSTALL @@ -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. diff --git a/django/apps/config.py b/django/apps/config.py index 78762dd61208..1bc684b3cac7 100644 --- a/django/apps/config.py +++ b/django/apps/config.py @@ -17,7 +17,7 @@ def __init__(self, app_name, app_module): self.name = app_name # Root module for the application eg. . + # 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 @@ def __init__(self, app_name, app_module): 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. . 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 diff --git a/django/conf/project_template/manage.py-tpl b/django/conf/project_template/manage.py-tpl index 41309844e019..9f83e65491f7 100755 --- a/django/conf/project_template/manage.py-tpl +++ b/django/conf/project_template/manage.py-tpl @@ -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) diff --git a/django/contrib/gis/measure.py b/django/contrib/gis/measure.py index fa3d7c34f288..d19737a1184a 100644 --- a/django/contrib/gis/measure.py +++ b/django/contrib/gis/measure.py @@ -159,9 +159,6 @@ def __truediv__(self, other): 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 @@ def __itruediv__(self, other): 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 @@ def __truediv__(self, other): 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 diff --git a/django/core/checks/model_checks.py b/django/core/checks/model_checks.py index a8b565266247..2397fe3bb28a 100644 --- a/django/core/checks/model_checks.py +++ b/django/core/checks/model_checks.py @@ -64,7 +64,7 @@ def extract_operation(obj): 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 diff --git a/django/core/files/temp.py b/django/core/files/temp.py index f5aea1a9a805..d5c56a0ad013 100644 --- a/django/core/files/temp.py +++ b/django/core/files/temp.py @@ -9,8 +9,8 @@ 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 @@ class TemporaryFile(FileProxyMixin): 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) diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index a9ab0668f79a..5a551b8ab1da 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -83,7 +83,6 @@ def handle_error(self, request, client_address): 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 diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index d056392753a2..1b5dc864b012 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -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 diff --git a/django/db/backends/oracle/introspection.py b/django/db/backends/oracle/introspection.py index 7af2a18a8ddd..8a648dba3fbb 100644 --- a/django/db/backends/oracle/introspection.py +++ b/django/db/backends/oracle/introspection.py @@ -81,7 +81,7 @@ def get_table_description(self, cursor, table_name): 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,))) diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index e15ffd87b5fd..58f90beaa20a 100644 --- a/django/db/migrations/serializer.py +++ b/django/db/migrations/serializer.py @@ -160,24 +160,14 @@ def serialize(self): if "<" not in self.value.__qualname__: # Qualname can include 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} diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index de60a160e070..a1cec2393afe 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -60,9 +60,6 @@ def __mul__(self, other): 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 @@ def __rmul__(self, other): 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) diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py index 54088b4fbb2e..c94a03f5496c 100644 --- a/django/db/models/query_utils.py +++ b/django/db/models/query_utils.py @@ -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: diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 1be406d7044b..5e5984dfb35b 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -875,14 +875,8 @@ def execute_sql(self, result_type=MULTI, chunked_fetch=False): 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: diff --git a/django/forms/utils.py b/django/forms/utils.py index 59d70178f44b..b23e6be0cccb 100644 --- a/django/forms/utils.py +++ b/django/forms/utils.py @@ -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.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'""" diff --git a/django/test/utils.py b/django/test/utils.py index 2bd6bb4d0f66..ef837ce5c73c 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -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: diff --git a/django/utils/deconstruct.py b/django/utils/deconstruct.py index 848b939b408c..6bc70f7e53db 100644 --- a/django/utils/deconstruct.py +++ b/django/utils/deconstruct.py @@ -24,7 +24,7 @@ def deconstruct(obj): 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: diff --git a/django/utils/html.py b/django/utils/html.py index fb9c18219c67..f7f9a63350d1 100644 --- a/django/utils/html.py +++ b/django/utils/html.py @@ -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 diff --git a/django/utils/html_parser.py b/django/utils/html_parser.py index e3e19ee9c3d0..6b46ddc3687a 100644 --- a/django/utils/html_parser.py +++ b/django/utils/html_parser.py @@ -11,9 +11,7 @@ class HTMLParseError(Exception): 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) diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py index 62ff122621ba..c8913feb7168 100644 --- a/django/utils/translation/trans_real.py +++ b/django/utils/translation/trans_real.py @@ -101,7 +101,6 @@ def __init__(self, language, domain=None, localedirs=None): 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') diff --git a/docs/ref/applications.txt b/docs/ref/applications.txt index 1cff9aafa46d..edd88ceec825 100644 --- a/docs/ref/applications.txt +++ b/docs/ref/applications.txt @@ -206,12 +206,12 @@ Read-only attributes .. attribute:: AppConfig.module Root module for the application, e.g. ````. + 'django/contrib/admin/__init__.py'>``. .. attribute:: AppConfig.models_module Module containing the models, e.g. ````. + 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 diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index 33bf85a9ffd4..b6060ff9a317 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -568,10 +568,6 @@ def test_no_list_display_links(self): self.assertNotContains(response, '' % 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) diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index 8494d76f4cd6..c8f5d2a20df5 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -101,9 +101,6 @@ def remove_settings(self, filename, is_dir=False): 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 diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py index ffce2c0f34aa..3a5f7503098c 100644 --- a/tests/admin_views/admin.py +++ b/tests/admin_views/admin.py @@ -971,8 +971,7 @@ def get_formsets_with_inlines(self, request, obj=None): # 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) diff --git a/tests/auth_tests/test_context_processors.py b/tests/auth_tests/test_context_processors.py index d66b28cb9c95..5b938003867a 100644 --- a/tests/auth_tests/test_context_processors.py +++ b/tests/auth_tests/test_context_processors.py @@ -130,21 +130,7 @@ def test_user_attrs(self): # 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 - # 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 diff --git a/tests/cache/tests.py b/tests/cache/tests.py index 5c3ec0fe04ae..ef77b284582e 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -62,11 +62,6 @@ def __getstate__(self): 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 @@ def test_creates_cache_dir_if_nonexistent(self): 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')) diff --git a/tests/decorators/tests.py b/tests/decorators/tests.py index c2116a05cefb..8fedacec2242 100644 --- a/tests/decorators/tests.py +++ b/tests/decorators/tests.py @@ -256,8 +256,8 @@ def method(self): 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): diff --git a/tests/expressions_case/tests.py b/tests/expressions_case/tests.py index a662ffbc3b27..20d1e801ec74 100644 --- a/tests/expressions_case/tests.py +++ b/tests/expressions_case/tests.py @@ -637,8 +637,6 @@ def test_update_big_integer(self): 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()), diff --git a/tests/files/tests.py b/tests/files/tests.py index f7d05574d20c..4036fc5e7956 100644 --- a/tests/files/tests.py +++ b/tests/files/tests.py @@ -139,9 +139,6 @@ def test_io_wrapper(self): 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) diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py index 98c5ee878325..c13fbdf5c8a2 100644 --- a/tests/forms_tests/tests/test_forms.py +++ b/tests/forms_tests/tests/test_forms.py @@ -21,8 +21,7 @@ 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 @@ class PersonForm(Form): 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(''), ' 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): diff --git a/tests/i18n/utils.py b/tests/i18n/utils.py index 2bf4f3e63e7c..43cb75656419 100644 --- a/tests/i18n/utils.py +++ b/tests/i18n/utils.py @@ -7,7 +7,7 @@ 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: diff --git a/tests/queries/test_qs_combinators.py b/tests/queries/test_qs_combinators.py index 02a0df216d06..0528f1c08db0 100644 --- a/tests/queries/test_qs_combinators.py +++ b/tests/queries/test_qs_combinators.py @@ -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 diff --git a/tests/settings_tests/tests.py b/tests/settings_tests/tests.py index bf015affc2d3..fa51c0af2032 100644 --- a/tests/settings_tests/tests.py +++ b/tests/settings_tests/tests.py @@ -305,8 +305,7 @@ def test_complex_override_warning(self): 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.') diff --git a/tests/template_tests/utils.py b/tests/template_tests/utils.py index e2a9305b5ef9..3ebacf7bcb47 100644 --- a/tests/template_tests/utils.py +++ b/tests/template_tests/utils.py @@ -164,7 +164,7 @@ def b(self): class UTF8Class: - "Class whose __str__ returns non-ASCII data on Python 2" + "Class whose __str__ returns non-ASCII data" def __str__(self): return 'ŠĐĆŽćžšđ' diff --git a/tests/utils_tests/test_simplelazyobject.py b/tests/utils_tests/test_simplelazyobject.py index a83c78bf4c33..d6386fe79c39 100644 --- a/tests/utils_tests/test_simplelazyobject.py +++ b/tests/utils_tests/test_simplelazyobject.py @@ -7,15 +7,10 @@ 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) From 6e55e1d88a5c4453e25f0caf7ffb68973de5c0ba Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Sat, 7 Jan 2017 20:13:29 +0100 Subject: [PATCH 0100/3180] Refs #23919 -- Replaced six.reraise by raise --- django/contrib/admin/views/main.py | 4 +-- .../gis/db/backends/oracle/introspection.py | 12 +++------ .../gis/db/backends/spatialite/base.py | 11 +++----- .../gis/db/backends/spatialite/operations.py | 15 +++++------ django/contrib/gis/utils/layermapping.py | 8 +++--- django/core/management/commands/flush.py | 13 +++++----- django/core/management/utils.py | 8 ++---- django/core/serializers/json.py | 9 +++---- django/core/serializers/pyyaml.py | 9 +++---- django/core/servers/basehttp.py | 16 ++++-------- django/db/backends/mysql/base.py | 14 +++++----- django/db/backends/oracle/base.py | 4 +-- django/db/migrations/graph.py | 22 +++++----------- django/db/migrations/loader.py | 9 ++----- django/db/models/query.py | 4 +-- django/db/utils.py | 3 +-- django/forms/fields.py | 9 +++---- django/forms/utils.py | 21 ++++++--------- django/http/multipartparser.py | 7 ++--- django/http/request.py | 8 +++--- django/template/backends/django.py | 4 +-- django/template/backends/jinja2.py | 11 ++------ django/templatetags/i18n.py | 26 +++++++++---------- django/test/client.py | 3 +-- django/utils/autoreload.py | 3 +-- django/utils/http.py | 6 ++--- django/utils/module_loading.py | 14 ++++------ tests/gis_tests/tests.py | 4 +-- 28 files changed, 100 insertions(+), 177 deletions(-) diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 20bce0c8d671..b48d00740929 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -1,4 +1,3 @@ -import sys from collections import OrderedDict from django.contrib.admin import FieldListFilter @@ -17,7 +16,6 @@ from django.core.paginator import InvalidPage from django.db import models from django.urls import reverse -from django.utils import six from django.utils.encoding import force_text from django.utils.http import urlencode from django.utils.translation import ugettext @@ -151,7 +149,7 @@ def get_filters(self, request): use_distinct = use_distinct or lookup_needs_distinct(self.lookup_opts, key) return filter_specs, bool(filter_specs), lookup_params, use_distinct except FieldDoesNotExist as e: - six.reraise(IncorrectLookupParameters, IncorrectLookupParameters(e), sys.exc_info()[2]) + raise IncorrectLookupParameters(e) from e def get_query_string(self, new_params=None, remove=None): if new_params is None: diff --git a/django/contrib/gis/db/backends/oracle/introspection.py b/django/contrib/gis/db/backends/oracle/introspection.py index 764ce7d24314..886441a9d034 100644 --- a/django/contrib/gis/db/backends/oracle/introspection.py +++ b/django/contrib/gis/db/backends/oracle/introspection.py @@ -1,9 +1,6 @@ -import sys - import cx_Oracle from django.db.backends.oracle.introspection import DatabaseIntrospection -from django.utils import six class OracleIntrospection(DatabaseIntrospection): @@ -24,12 +21,11 @@ def get_geometry_type(self, table_name, geo_col): (table_name.upper(), geo_col.upper()) ) row = cursor.fetchone() - except Exception as msg: - new_msg = ( + except Exception as exc: + raise Exception( 'Could not find entry in USER_SDO_GEOM_METADATA ' - 'corresponding to "%s"."%s"\n' - 'Error message: %s.') % (table_name, geo_col, msg) - six.reraise(Exception, Exception(new_msg), sys.exc_info()[2]) + 'corresponding to "%s"."%s"' % (table_name, geo_col) + ) from exc # TODO: Research way to find a more specific geometry field type for # the column's contents. diff --git a/django/contrib/gis/db/backends/spatialite/base.py b/django/contrib/gis/db/backends/spatialite/base.py index 799e9f167107..287c643ce82c 100644 --- a/django/contrib/gis/db/backends/spatialite/base.py +++ b/django/contrib/gis/db/backends/spatialite/base.py @@ -1,4 +1,3 @@ -import sys from ctypes.util import find_library from django.conf import settings @@ -6,7 +5,6 @@ from django.db.backends.sqlite3.base import ( DatabaseWrapper as SQLiteDatabaseWrapper, SQLiteCursorWrapper, ) -from django.utils import six from .client import SpatiaLiteClient from .features import DatabaseFeatures @@ -53,11 +51,10 @@ def get_new_connection(self, conn_params): cur = conn.cursor(factory=SQLiteCursorWrapper) try: cur.execute("SELECT load_extension(%s)", (self.spatialite_lib,)) - except Exception as msg: - new_msg = ( - 'Unable to load the SpatiaLite library extension ' - '"%s" because: %s') % (self.spatialite_lib, msg) - six.reraise(ImproperlyConfigured, ImproperlyConfigured(new_msg), sys.exc_info()[2]) + except Exception as exc: + raise ImproperlyConfigured( + 'Unable to load the SpatiaLite library extension "%s"' % self.spatialite_lib + ) from exc cur.close() return conn diff --git a/django/contrib/gis/db/backends/spatialite/operations.py b/django/contrib/gis/db/backends/spatialite/operations.py index cc46b4b91fbd..5fab0b4df7e0 100644 --- a/django/contrib/gis/db/backends/spatialite/operations.py +++ b/django/contrib/gis/db/backends/spatialite/operations.py @@ -4,7 +4,6 @@ http://www.gaia-gis.it/gaia-sins/spatialite-sql-4.2.1.html """ import re -import sys from django.contrib.gis.db.backends.base.operations import \ BaseSpatialOperations @@ -15,7 +14,6 @@ from django.contrib.gis.measure import Distance from django.core.exceptions import ImproperlyConfigured from django.db.backends.sqlite3.operations import DatabaseOperations -from django.utils import six from django.utils.functional import cached_property @@ -123,12 +121,13 @@ def spatial_version(self): """Determine the version of the SpatiaLite library.""" try: version = self.spatialite_version_tuple()[1:] - except Exception as msg: - new_msg = ( - 'Cannot determine the SpatiaLite version for the "%s" ' - 'database (error was "%s"). Was the SpatiaLite initialization ' - 'SQL loaded on this database?') % (self.connection.settings_dict['NAME'], msg) - six.reraise(ImproperlyConfigured, ImproperlyConfigured(new_msg), sys.exc_info()[2]) + except Exception as exc: + raise ImproperlyConfigured( + 'Cannot determine the SpatiaLite version for the "%s" database. ' + 'Was the SpatiaLite initialization SQL loaded on this database?' % ( + self.connection.settings_dict['NAME'], + ) + ) from exc if version < (4, 0, 0): raise ImproperlyConfigured('GeoDjango only supports SpatiaLite versions 4.0.0 and above.') return version diff --git a/django/contrib/gis/utils/layermapping.py b/django/contrib/gis/utils/layermapping.py index 9093ae84d6f0..621ee49752ba 100644 --- a/django/contrib/gis/utils/layermapping.py +++ b/django/contrib/gis/utils/layermapping.py @@ -20,7 +20,6 @@ ) from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist from django.db import connections, models, router, transaction -from django.utils import six from django.utils.encoding import force_text @@ -456,9 +455,10 @@ def coord_transform(self): # Creating the CoordTransform object return CoordTransform(self.source_srs, target_srs) - except Exception as msg: - new_msg = 'Could not translate between the data source and model geometry: %s' % msg - six.reraise(LayerMapError, LayerMapError(new_msg), sys.exc_info()[2]) + except Exception as exc: + raise LayerMapError( + 'Could not translate between the data source and model geometry.' + ) from exc def geometry_field(self): "Returns the GeometryField instance associated with the geographic column." diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py index 8d1621b11628..7a77c38bdd2d 100644 --- a/django/core/management/commands/flush.py +++ b/django/core/management/commands/flush.py @@ -1,4 +1,3 @@ -import sys from importlib import import_module from django.apps import apps @@ -6,7 +5,6 @@ from django.core.management.color import no_style from django.core.management.sql import emit_post_migrate_signal, sql_flush from django.db import DEFAULT_DB_ALIAS, connections, transaction -from django.utils import six class Command(BaseCommand): @@ -67,16 +65,17 @@ def handle(self, **options): with connection.cursor() as cursor: for sql in sql_list: cursor.execute(sql) - except Exception as e: - new_msg = ( + except Exception as exc: + raise CommandError( "Database %s couldn't be flushed. Possible reasons:\n" " * The database isn't running or isn't configured correctly.\n" " * At least one of the expected database tables doesn't exist.\n" " * The SQL was invalid.\n" "Hint: Look at the output of 'django-admin sqlflush'. " - "That's the SQL this command wasn't able to run.\n" - "The full error: %s") % (connection.settings_dict['NAME'], e) - six.reraise(CommandError, CommandError(new_msg), sys.exc_info()[2]) + "That's the SQL this command wasn't able to run.\n" % ( + connection.settings_dict['NAME'], + ) + ) from exc # Empty sql_list may signify an empty database and post_migrate would then crash if sql_list and not inhibit_post_migrate: diff --git a/django/core/management/utils.py b/django/core/management/utils.py index 07a14bd73139..5903e53341e3 100644 --- a/django/core/management/utils.py +++ b/django/core/management/utils.py @@ -1,9 +1,7 @@ import os -import sys from subprocess import PIPE, Popen from django.apps import apps as installed_apps -from django.utils import six from django.utils.crypto import get_random_string from django.utils.encoding import DEFAULT_LOCALE_ENCODING, force_text @@ -18,10 +16,8 @@ def popen_wrapper(args, os_err_exc_type=CommandError, stdout_encoding='utf-8'): """ try: p = Popen(args, shell=False, stdout=PIPE, stderr=PIPE, close_fds=os.name != 'nt') - except OSError as e: - strerror = force_text(e.strerror, DEFAULT_LOCALE_ENCODING, strings_only=True) - six.reraise(os_err_exc_type, os_err_exc_type('Error executing %s: %s' % - (args[0], strerror)), sys.exc_info()[2]) + except OSError as err: + raise os_err_exc_type('Error executing %s' % args[0]) from err output, errors = p.communicate() return ( force_text(output, stdout_encoding, strings_only=True, errors='strict'), diff --git a/django/core/serializers/json.py b/django/core/serializers/json.py index b87d80757143..79db71cadf50 100644 --- a/django/core/serializers/json.py +++ b/django/core/serializers/json.py @@ -5,14 +5,12 @@ import datetime import decimal import json -import sys import uuid from django.core.serializers.base import DeserializationError from django.core.serializers.python import ( Deserializer as PythonDeserializer, Serializer as PythonSerializer, ) -from django.utils import six from django.utils.duration import duration_iso_string from django.utils.functional import Promise from django.utils.timezone import is_aware @@ -77,11 +75,10 @@ def Deserializer(stream_or_string, **options): objects = json.loads(stream_or_string) for obj in PythonDeserializer(objects, **options): yield obj - except GeneratorExit: + except (GeneratorExit, DeserializationError): raise - except Exception as e: - # Map to deserializer error - six.reraise(DeserializationError, DeserializationError(e), sys.exc_info()[2]) + except Exception as exc: + raise DeserializationError() from exc class DjangoJSONEncoder(json.JSONEncoder): diff --git a/django/core/serializers/pyyaml.py b/django/core/serializers/pyyaml.py index 16583782b9ac..89594728cb3a 100644 --- a/django/core/serializers/pyyaml.py +++ b/django/core/serializers/pyyaml.py @@ -6,7 +6,6 @@ import collections import decimal -import sys from io import StringIO import yaml @@ -16,7 +15,6 @@ Deserializer as PythonDeserializer, Serializer as PythonSerializer, ) from django.db import models -from django.utils import six # Use the C (faster) implementation if possible try: @@ -78,8 +76,7 @@ def Deserializer(stream_or_string, **options): try: for obj in PythonDeserializer(yaml.load(stream, Loader=SafeLoader), **options): yield obj - except GeneratorExit: + except (GeneratorExit, DeserializationError): raise - except Exception as e: - # Map to deserializer error - six.reraise(DeserializationError, DeserializationError(e), sys.exc_info()[2]) + except Exception as exc: + raise DeserializationError() from exc diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index 5a551b8ab1da..3e1141122bd5 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -15,7 +15,6 @@ from django.core.exceptions import ImproperlyConfigured from django.core.wsgi import get_wsgi_application -from django.utils import six from django.utils.module_loading import import_string __all__ = ('WSGIServer', 'WSGIRequestHandler') @@ -43,16 +42,11 @@ def get_internal_wsgi_application(): try: return import_string(app_path) - except ImportError as e: - msg = ( - "WSGI application '%(app_path)s' could not be loaded; " - "Error importing module: '%(exception)s'" % ({ - 'app_path': app_path, - 'exception': e, - }) - ) - six.reraise(ImproperlyConfigured, ImproperlyConfigured(msg), - sys.exc_info()[2]) + except ImportError as err: + raise ImproperlyConfigured( + "WSGI application '%s' could not be loaded; " + "Error importing module." % app_path + ) from err def is_broken_pipe_error(): diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 1b5dc864b012..38c349caeaf4 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -4,23 +4,21 @@ Requires mysqlclient: https://pypi.python.org/pypi/mysqlclient/ """ import re -import sys from django.core.exceptions import ImproperlyConfigured from django.db import utils from django.db.backends import utils as backend_utils from django.db.backends.base.base import BaseDatabaseWrapper -from django.utils import six from django.utils.functional import cached_property from django.utils.safestring import SafeBytes, SafeText try: import MySQLdb as Database -except ImportError as e: +except ImportError as err: raise ImproperlyConfigured( - 'Error loading MySQLdb module: %s.\n' - 'Did you install mysqlclient or MySQL-python?' % e - ) + 'Error loading MySQLdb module.\n' + 'Did you install mysqlclient or MySQL-python?' + ) from err from MySQLdb.constants import CLIENT, FIELD_TYPE # isort:skip from MySQLdb.converters import conversions # isort:skip @@ -88,7 +86,7 @@ def execute(self, query, args=None): # Map some error codes to IntegrityError, since they seem to be # misclassified and Django would prefer the more logical place. if e.args[0] in self.codes_for_integrityerror: - six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2]) + raise utils.IntegrityError(*tuple(e.args)) raise def executemany(self, query, args): @@ -98,7 +96,7 @@ def executemany(self, query, args): # Map some error codes to IntegrityError, since they seem to be # misclassified and Django would prefer the more logical place. if e.args[0] in self.codes_for_integrityerror: - six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2]) + raise utils.IntegrityError(*tuple(e.args)) raise def __getattr__(self, attr): diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 8d6b48e52a64..fbbee227ee59 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -7,13 +7,11 @@ import decimal import os import platform -import sys from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.db import utils from django.db.backends.base.base import BaseDatabaseWrapper -from django.utils import six from django.utils.encoding import force_bytes, force_text from django.utils.functional import cached_property @@ -261,7 +259,7 @@ def _commit(self): x = e.args[0] if hasattr(x, 'code') and hasattr(x, 'message') \ and x.code == 2091 and 'ORA-02291' in x.message: - six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2]) + raise utils.IntegrityError(*tuple(e.args)) raise # Oracle doesn't support releasing savepoints. But we fake them when query diff --git a/django/db/migrations/graph.py b/django/db/migrations/graph.py index 1d144d7d253b..7fdc850a7798 100644 --- a/django/db/migrations/graph.py +++ b/django/db/migrations/graph.py @@ -1,10 +1,8 @@ -import sys import warnings from collections import deque from functools import total_ordering from django.db.migrations.state import ProjectState -from django.utils import six from django.utils.datastructures import OrderedSet from .exceptions import CircularDependencyError, NodeNotFoundError @@ -178,16 +176,12 @@ def remove_replaced_nodes(self, replacement, replaced): replaced = set(replaced) try: replacement_node = self.node_map[replacement] - except KeyError as exc: - exc_value = NodeNotFoundError( + except KeyError as err: + raise NodeNotFoundError( "Unable to find replacement node %r. It was either never added" " to the migration graph, or has been removed." % (replacement, ), replacement - ) - exc_value.__cause__ = exc - if not hasattr(exc, '__traceback__'): - exc.__traceback__ = sys.exc_info()[2] - six.reraise(NodeNotFoundError, exc_value, sys.exc_info()[2]) + ) from err for replaced_key in replaced: self.nodes.pop(replaced_key, None) replaced_node = self.node_map.pop(replaced_key, None) @@ -218,16 +212,12 @@ def remove_replacement_node(self, replacement, replaced): self.nodes.pop(replacement, None) try: replacement_node = self.node_map.pop(replacement) - except KeyError as exc: - exc_value = NodeNotFoundError( + except KeyError as err: + raise NodeNotFoundError( "Unable to remove replacement node %r. It was either never added" " to the migration graph, or has been removed already." % (replacement, ), replacement - ) - exc_value.__cause__ = exc - if not hasattr(exc, '__traceback__'): - exc.__traceback__ = sys.exc_info()[2] - six.reraise(NodeNotFoundError, exc_value, sys.exc_info()[2]) + ) from err replaced_nodes = set() replaced_nodes_parents = set() for key in replaced: diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py index 1237a37c2619..b980aaf2f367 100644 --- a/django/db/migrations/loader.py +++ b/django/db/migrations/loader.py @@ -6,7 +6,6 @@ from django.conf import settings from django.db.migrations.graph import MigrationGraph from django.db.migrations.recorder import MigrationRecorder -from django.utils import six from .exceptions import ( AmbiguityError, BadMigrationError, InconsistentMigrationHistory, @@ -256,7 +255,7 @@ def build_graph(self): is_replaced = any(candidate in self.graph.nodes for candidate in candidates) if not is_replaced: tries = ', '.join('%s.%s' % c for c in candidates) - exc_value = NodeNotFoundError( + raise NodeNotFoundError( "Migration {0} depends on nonexistent node ('{1}', '{2}'). " "Django tried to replace migration {1}.{2} with any of [{3}] " "but wasn't able to because some of the replaced migrations " @@ -264,11 +263,7 @@ def build_graph(self): exc.origin, exc.node[0], exc.node[1], tries ), exc.node - ) - exc_value.__cause__ = exc - if not hasattr(exc, '__traceback__'): - exc.__traceback__ = sys.exc_info()[2] - six.reraise(NodeNotFoundError, exc_value, sys.exc_info()[2]) + ) from exc raise exc def check_consistent_history(self, connection): diff --git a/django/db/models/query.py b/django/db/models/query.py index f4d56a269bf1..dcb136005450 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -21,7 +21,7 @@ from django.db.models.functions import Trunc from django.db.models.query_utils import InvalidQuery, Q from django.db.models.sql.constants import CURSOR -from django.utils import six, timezone +from django.utils import timezone from django.utils.functional import cached_property, partition from django.utils.version import get_version @@ -498,7 +498,7 @@ def _create_object_from_params(self, lookup, params): return self.get(**lookup), False except self.model.DoesNotExist: pass - six.reraise(*exc_info) + raise exc_info[0](exc_info[1]).with_traceback(exc_info[2]) def _extract_model_params(self, defaults, **kwargs): """ diff --git a/django/db/utils.py b/django/db/utils.py index a35de01ffa91..7ef57fd8a3f6 100644 --- a/django/db/utils.py +++ b/django/db/utils.py @@ -5,7 +5,6 @@ from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from django.utils import six from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -90,7 +89,7 @@ def __exit__(self, exc_type, exc_value, traceback): # the connection unusable. if dj_exc_type not in (DataError, IntegrityError): self.wrapper.errors_occurred = True - six.reraise(dj_exc_type, dj_exc_value, traceback) + raise dj_exc_value.with_traceback(traceback) def __call__(self, func): # Note that we are intentionally not using @wraps here for performance diff --git a/django/forms/fields.py b/django/forms/fields.py index b88f3ea61a92..a3bdcd1713af 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -7,7 +7,6 @@ import itertools import os import re -import sys import uuid from decimal import Decimal, DecimalException from io import BytesIO @@ -26,7 +25,7 @@ SplitDateTimeWidget, SplitHiddenDateTimeWidget, TextInput, TimeInput, URLInput, ) -from django.utils import formats, six +from django.utils import formats from django.utils.dateparse import parse_duration from django.utils.duration import duration_string from django.utils.encoding import force_text @@ -650,12 +649,12 @@ def to_python(self, data): # Pillow doesn't detect the MIME type of all formats. In those # cases, content_type will be None. f.content_type = Image.MIME.get(image.format) - except Exception: + except Exception as exc: # Pillow doesn't recognize it as an image. - six.reraise(ValidationError, ValidationError( + raise ValidationError( self.error_messages['invalid_image'], code='invalid_image', - ), sys.exc_info()[2]) + ) from exc if hasattr(f, 'seek') and callable(f.seek): f.seek(0) return f diff --git a/django/forms/utils.py b/django/forms/utils.py index b23e6be0cccb..b199803cccbe 100644 --- a/django/forms/utils.py +++ b/django/forms/utils.py @@ -1,10 +1,9 @@ import json -import sys from collections import UserList from django.conf import settings from django.core.exceptions import ValidationError # backwards compatibility -from django.utils import six, timezone +from django.utils import timezone 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 _ @@ -156,18 +155,14 @@ def from_current_timezone(value): current_timezone = timezone.get_current_timezone() try: return timezone.make_aware(value, current_timezone) - except Exception: - message = _( - '%(datetime)s couldn\'t be interpreted ' - 'in time zone %(current_timezone)s; it ' - 'may be ambiguous or it may not exist.' - ) - params = {'datetime': value, 'current_timezone': current_timezone} - six.reraise(ValidationError, ValidationError( - message, + except Exception as exc: + raise ValidationError( + _('%(datetime)s couldn\'t be interpreted ' + 'in time zone %(current_timezone)s; it ' + 'may be ambiguous or it may not exist.'), code='ambiguous_timezone', - params=params, - ), sys.exc_info()[2]) + params={'datetime': value, 'current_timezone': current_timezone} + ) from exc return value diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index ff7e36e32185..6a0ff2c86c91 100644 --- a/django/http/multipartparser.py +++ b/django/http/multipartparser.py @@ -7,7 +7,6 @@ import base64 import binascii import cgi -import sys from urllib.parse import unquote from django.conf import settings @@ -17,7 +16,6 @@ from django.core.files.uploadhandler import ( SkipFile, StopFutureHandlers, StopUpload, ) -from django.utils import six from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_text from django.utils.text import unescape_entities @@ -247,10 +245,9 @@ def parse(self): try: chunk = base64.b64decode(stripped_chunk) - except Exception as e: + except Exception as exc: # Since this is only a chunk, any error is an unfixable error. - msg = "Could not decode base64 data: %r" % e - six.reraise(MultiPartParserError, MultiPartParserError(msg), sys.exc_info()[2]) + raise MultiPartParserError("Could not decode base64 data.") from exc for i, handler in enumerate(handlers): chunk_length = len(chunk) diff --git a/django/http/request.py b/django/http/request.py index 554e05217d84..bae0b6f3ecde 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -1,6 +1,5 @@ import copy import re -import sys from io import BytesIO from itertools import chain from urllib.parse import quote, urlencode, urljoin, urlsplit @@ -12,7 +11,6 @@ ) from django.core.files import uploadhandler from django.http.multipartparser import MultiPartParser, MultiPartParserError -from django.utils import six from django.utils.datastructures import ImmutableList, MultiValueDict from django.utils.encoding import escape_uri_path, force_bytes, iri_to_uri from django.utils.http import is_same_domain, limited_parse_qsl @@ -263,7 +261,7 @@ def body(self): try: self._body = self.read() except IOError as e: - six.reraise(UnreadablePostError, UnreadablePostError(*e.args), sys.exc_info()[2]) + raise UnreadablePostError(*e.args) from e self._stream = BytesIO(self._body) return self._body @@ -322,14 +320,14 @@ def read(self, *args, **kwargs): try: return self._stream.read(*args, **kwargs) except IOError as e: - six.reraise(UnreadablePostError, UnreadablePostError(*e.args), sys.exc_info()[2]) + raise UnreadablePostError(*e.args) from e def readline(self, *args, **kwargs): self._read_started = True try: return self._stream.readline(*args, **kwargs) except IOError as e: - six.reraise(UnreadablePostError, UnreadablePostError(*e.args), sys.exc_info()[2]) + raise UnreadablePostError(*e.args) from e def xreadlines(self): while True: diff --git a/django/template/backends/django.py b/django/template/backends/django.py index 33022d8bbbfd..eaa7c8fdc25f 100644 --- a/django/template/backends/django.py +++ b/django/template/backends/django.py @@ -1,4 +1,3 @@ -import sys from importlib import import_module from pkgutil import walk_packages @@ -8,7 +7,6 @@ from django.template.context import make_context from django.template.engine import Engine from django.template.library import InvalidTemplateLibrary -from django.utils import six from .base import BaseEngine @@ -83,7 +81,7 @@ def reraise(exc, backend): Reraise TemplateDoesNotExist while maintaining template debug information. """ new = copy_exception(exc, backend) - six.reraise(exc.__class__, new, sys.exc_info()[2]) + raise new from exc def get_installed_libraries(): diff --git a/django/template/backends/jinja2.py b/django/template/backends/jinja2.py index df2eefa92535..3c5f7231bfc5 100644 --- a/django/template/backends/jinja2.py +++ b/django/template/backends/jinja2.py @@ -1,10 +1,7 @@ -import sys - import jinja2 from django.conf import settings from django.template import TemplateDoesNotExist, TemplateSyntaxError -from django.utils import six from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -41,15 +38,11 @@ def get_template(self, template_name): try: return Template(self.env.get_template(template_name), self) except jinja2.TemplateNotFound as exc: - six.reraise( - TemplateDoesNotExist, - TemplateDoesNotExist(exc.name, backend=self), - sys.exc_info()[2], - ) + raise TemplateDoesNotExist(exc.name, backend=self) from exc except jinja2.TemplateSyntaxError as exc: new = TemplateSyntaxError(exc.args) new.template_debug = get_exception_info(exc) - six.reraise(TemplateSyntaxError, new, sys.exc_info()[2]) + raise new from exc @cached_property def template_context_processors(self): diff --git a/django/templatetags/i18n.py b/django/templatetags/i18n.py index 407ce87609d5..456c5071ac6a 100644 --- a/django/templatetags/i18n.py +++ b/django/templatetags/i18n.py @@ -1,10 +1,8 @@ -import sys - from django.conf import settings from django.template import Library, Node, TemplateSyntaxError, Variable from django.template.base import TOKEN_TEXT, TOKEN_VAR, render_value_in_context from django.template.defaulttags import token_kwargs -from django.utils import six, translation +from django.utils import translation from django.utils.safestring import SafeData, mark_safe register = Library() @@ -388,8 +386,9 @@ def do_translate(parser, token): try: value = remaining.pop(0) except IndexError: - msg = "No argument provided to the '%s' tag for the context option." % bits[0] - six.reraise(TemplateSyntaxError, TemplateSyntaxError(msg), sys.exc_info()[2]) + raise TemplateSyntaxError( + "No argument provided to the '%s' tag for the context option." % bits[0] + ) if value in invalid_context: raise TemplateSyntaxError( "Invalid argument '%s' provided to the '%s' tag for the context option" % (value, bits[0]), @@ -399,8 +398,9 @@ def do_translate(parser, token): try: value = remaining.pop(0) except IndexError: - msg = "No argument provided to the '%s' tag for the as option." % bits[0] - six.reraise(TemplateSyntaxError, TemplateSyntaxError(msg), sys.exc_info()[2]) + raise TemplateSyntaxError( + "No argument provided to the '%s' tag for the as option." % bits[0] + ) asvar = value else: raise TemplateSyntaxError( @@ -481,18 +481,18 @@ def do_block_translate(parser, token): value = remaining_bits.pop(0) value = parser.compile_filter(value) except Exception: - msg = ( - '"context" in %r tag expected ' - 'exactly one argument.') % bits[0] - six.reraise(TemplateSyntaxError, TemplateSyntaxError(msg), sys.exc_info()[2]) + raise TemplateSyntaxError( + '"context" in %r tag expected exactly one argument.' % bits[0] + ) elif option == "trimmed": value = True elif option == "asvar": try: value = remaining_bits.pop(0) except IndexError: - msg = "No argument provided to the '%s' tag for the asvar option." % bits[0] - six.reraise(TemplateSyntaxError, TemplateSyntaxError(msg), sys.exc_info()[2]) + raise TemplateSyntaxError( + "No argument provided to the '%s' tag for the asvar option." % bits[0] + ) asvar = value else: raise TemplateSyntaxError('Unknown argument for %r tag: %r.' % diff --git a/django/test/client.py b/django/test/client.py index f09051d2d5ad..e793dac7752e 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -20,7 +20,6 @@ from django.test import signals from django.test.utils import ContextList from django.urls import resolve -from django.utils import six from django.utils.encoding import force_bytes, uri_to_iri from django.utils.functional import SimpleLazyObject, curry from django.utils.http import urlencode @@ -494,7 +493,7 @@ def request(self, **request): if self.exc_info: exc_info = self.exc_info self.exc_info = None - six.reraise(*exc_info) + raise exc_info[0](exc_info[1]).with_traceback(exc_info[2]) # Save the client and request that stimulated the response. response.client = self diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py index 6255da1c8443..3fe47200ee34 100644 --- a/django/utils/autoreload.py +++ b/django/utils/autoreload.py @@ -40,7 +40,6 @@ from django.apps import apps from django.conf import settings from django.core.signals import request_finished -from django.utils import six # This import does nothing, but it's necessary to avoid some race conditions # in the threading module. See http://code.djangoproject.com/ticket/2330 . @@ -247,7 +246,7 @@ def wrapper(*args, **kwargs): def raise_last_exception(): global _exception if _exception is not None: - six.reraise(*_exception) + raise _exception[0](_exception[1]).with_traceback(_exception[2]) def ensure_echo_on(): diff --git a/django/utils/http.py b/django/utils/http.py index 7b15dc281253..afa7368ee84a 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -2,7 +2,6 @@ import calendar import datetime import re -import sys import unicodedata import warnings from binascii import Error as BinasciiError @@ -13,7 +12,6 @@ ) from django.core.exceptions import TooManyFieldsSent -from django.utils import six from django.utils.datastructures import MultiValueDict from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_bytes, force_str, force_text @@ -163,8 +161,8 @@ def parse_http_date(date): sec = int(m.group('sec')) result = datetime.datetime(year, month, day, hour, min, sec) return calendar.timegm(result.utctimetuple()) - except Exception: - six.reraise(ValueError, ValueError("%r is not a valid date" % date), sys.exc_info()[2]) + except Exception as exc: + raise ValueError("%r is not a valid date" % date) from exc def parse_http_date_safe(date): diff --git a/django/utils/module_loading.py b/django/utils/module_loading.py index ed2b8da63515..5e5fa0e69edf 100644 --- a/django/utils/module_loading.py +++ b/django/utils/module_loading.py @@ -1,11 +1,8 @@ import copy import os -import sys from importlib import import_module from importlib.util import find_spec as importlib_find -from django.utils import six - def import_string(dotted_path): """ @@ -14,18 +11,17 @@ def import_string(dotted_path): """ try: module_path, class_name = dotted_path.rsplit('.', 1) - except ValueError: - msg = "%s doesn't look like a module path" % dotted_path - six.reraise(ImportError, ImportError(msg), sys.exc_info()[2]) + except ValueError as err: + raise ImportError("%s doesn't look like a module path" % dotted_path) from err module = import_module(module_path) try: return getattr(module, class_name) - except AttributeError: - msg = 'Module "%s" does not define a "%s" attribute/class' % ( + except AttributeError as err: + raise ImportError('Module "%s" does not define a "%s" attribute/class' % ( module_path, class_name) - six.reraise(ImportError, ImportError(msg), sys.exc_info()[2]) + ) from err def autodiscover_modules(*args, **kwargs): diff --git a/tests/gis_tests/tests.py b/tests/gis_tests/tests.py index 6b689cf9b016..0cbfd97dcc4c 100644 --- a/tests/gis_tests/tests.py +++ b/tests/gis_tests/tests.py @@ -1,9 +1,7 @@ -import sys import unittest from django.core.exceptions import ImproperlyConfigured from django.db import ProgrammingError -from django.utils import six try: from django.contrib.gis.db.backends.postgis.operations import PostGISOperations @@ -19,7 +17,7 @@ if e.args and e.args[0].startswith('Could not import user-defined GEOMETRY_BACKEND'): HAS_POSTGRES = False else: - six.reraise(*sys.exc_info()) + raise if HAS_POSTGRES: From 8377a98ca5a9d51f6cf705d75276cb0380fffad6 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Sun, 22 Jan 2017 21:13:00 +0100 Subject: [PATCH 0101/3180] Removed obsolete force_text_recursive --- django/db/migrations/state.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index d8b256018632..9e73fb20fd8d 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -454,8 +454,6 @@ def from_model(cls, model, exclude_rels=False): options[name] = set(normalize_together(it)) else: options[name] = model._meta.original_attrs[name] - # Force-convert all options to str (#23226) - options = cls.force_text_recursive(options) # If we're ignoring relationships, remove all field-listing model # options (that option basically just means "make a stub model") if exclude_rels: @@ -533,21 +531,6 @@ def flatten_bases(model): managers, ) - @classmethod - def force_text_recursive(cls, value): - if isinstance(value, list): - return [cls.force_text_recursive(x) for x in value] - elif isinstance(value, tuple): - return tuple(cls.force_text_recursive(x) for x in value) - elif isinstance(value, set): - return set(cls.force_text_recursive(x) for x in value) - elif isinstance(value, dict): - return { - cls.force_text_recursive(k): cls.force_text_recursive(v) - for k, v in value.items() - } - return value - def construct_managers(self): "Deep-clone the managers using deconstruction" # Sort all managers by their creation counter From ecd5944666558bbb3a12b0aa0058685a81ce7162 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Mon, 23 Jan 2017 04:33:27 -0800 Subject: [PATCH 0102/3180] Removed ChoiceWidget.render() as it duplicates parent implementation. --- django/forms/widgets.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/django/forms/widgets.py b/django/forms/widgets.py index a8760623d208..5e6eddaf911b 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -539,10 +539,6 @@ def subwidgets(self, name, value, attrs=None): for option in self.options(name, value, attrs): yield option - def render(self, name, value, attrs=None, renderer=None): - context = self.get_context(name, value, attrs) - return self._render(self.template_name, context, renderer) - def options(self, name, value, attrs=None): """Yield a flat list of options for this widgets.""" for group in self.optgroups(name, value, attrs): From 88183117c28a8d669054e9064e7bd4de19ebcd28 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Mon, 23 Jan 2017 04:44:57 -0800 Subject: [PATCH 0103/3180] Fixed #27761 -- Fixed quote location in multiple_input.html forms templates. --- .../django/forms/widgets/multiple_input.html | 2 +- .../django/forms/widgets/multiple_input.html | 2 +- .../test_checkboxselectmultiple.py | 35 +++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/django/forms/jinja2/django/forms/widgets/multiple_input.html b/django/forms/jinja2/django/forms/widgets/multiple_input.html index be3d4499266a..349db54104e4 100644 --- a/django/forms/jinja2/django/forms/widgets/multiple_input.html +++ b/django/forms/jinja2/django/forms/widgets/multiple_input.html @@ -1,5 +1,5 @@ {% set id = widget.attrs.id %}{% for group, options, index in widget.optgroups %}{% if group %} -
  • {{ group }}{% endif %}{% for widget in options %} +
  • {{ group }}{% endif %}{% for widget in options %}
  • {% include widget.template_name %}
  • {% endfor %}{% if group %} {% endif %}{% endfor %} diff --git a/django/forms/templates/django/forms/widgets/multiple_input.html b/django/forms/templates/django/forms/widgets/multiple_input.html index 60282ff887c8..2362aff4e63f 100644 --- a/django/forms/templates/django/forms/widgets/multiple_input.html +++ b/django/forms/templates/django/forms/widgets/multiple_input.html @@ -1,5 +1,5 @@ {% with id=widget.attrs.id %}{% for group, options, index in widget.optgroups %}{% if group %} -
  • {{ group }}{% endif %}{% for option in options %} +
  • {{ group }}{% endif %}{% for option in options %}
  • {% include option.template_name with widget=option %}
  • {% endfor %}{% if group %} {% endif %}{% endfor %} {% endwith %} diff --git a/tests/forms_tests/widget_tests/test_checkboxselectmultiple.py b/tests/forms_tests/widget_tests/test_checkboxselectmultiple.py index a92e5533e2cb..6ec5c7880382 100644 --- a/tests/forms_tests/widget_tests/test_checkboxselectmultiple.py +++ b/tests/forms_tests/widget_tests/test_checkboxselectmultiple.py @@ -78,6 +78,41 @@ def test_nested_choices(self): attrs={'id': 'media'}, html=html, ) + def test_nested_choices_without_id(self): + nested_choices = ( + ('unknown', 'Unknown'), + ('Audio', (('vinyl', 'Vinyl'), ('cd', 'CD'))), + ('Video', (('vhs', 'VHS'), ('dvd', 'DVD'))), + ) + html = """ +
      +
    • + +
    • +
    • Audio
        +
      • + +
      • +
      • + +
      • +
    • +
    • Video
        +
      • + +
      • +
      • + +
      • +
    • +
    + """ + self.check_html(self.widget(choices=nested_choices), 'nestchoice', ('vinyl', 'dvd'), html=html) + def test_separate_ids(self): """ Each input gets a separate ID. From 5fa390ee81c5a963fc4476e8de6c1e5e1fc57e22 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Sun, 22 Jan 2017 10:15:56 -0800 Subject: [PATCH 0104/3180] Fixed #27759 -- Prevented forms attrs.html template from rendering False attrs. Regression in b52c73008a9d67e9ddbb841872dc15cdd3d6ee01. --- django/forms/jinja2/django/forms/widgets/attrs.html | 2 +- django/forms/templates/django/forms/widgets/attrs.html | 2 +- tests/forms_tests/widget_tests/test_widget.py | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/django/forms/jinja2/django/forms/widgets/attrs.html b/django/forms/jinja2/django/forms/widgets/attrs.html index b45d30c449db..7fbda39ce51e 100644 --- a/django/forms/jinja2/django/forms/widgets/attrs.html +++ b/django/forms/jinja2/django/forms/widgets/attrs.html @@ -1 +1 @@ -{% for name, value in widget.attrs.items() %} {{ name }}{% if not value is sameas True %}="{{ value }}"{% endif %}{% endfor %} +{% for name, value in widget.attrs.items() %}{% if value is not sameas False %} {{ name }}{% if not value is sameas True %}="{{ value }}"{% endif %}{% endif %}{% endfor %} diff --git a/django/forms/templates/django/forms/widgets/attrs.html b/django/forms/templates/django/forms/widgets/attrs.html index caca0cd80c03..fdb1a56d90de 100644 --- a/django/forms/templates/django/forms/widgets/attrs.html +++ b/django/forms/templates/django/forms/widgets/attrs.html @@ -1 +1 @@ -{% for name, value in widget.attrs.items %} {{ name }}{% if not value is True %}="{{ value }}"{% endif %}{% endfor %} \ No newline at end of file +{% for name, value in widget.attrs.items %}{% if value is not False %} {{ name }}{% if not value is True %}="{{ value }}"{% endif %}{% endif %}{% endfor %} \ No newline at end of file diff --git a/tests/forms_tests/widget_tests/test_widget.py b/tests/forms_tests/widget_tests/test_widget.py index 368c315be797..3ad3c23a4863 100644 --- a/tests/forms_tests/widget_tests/test_widget.py +++ b/tests/forms_tests/widget_tests/test_widget.py @@ -13,3 +13,7 @@ def test_value_omitted_from_data(self): def test_no_trailing_newline_in_attrs(self): self.check_html(Input(), 'name', 'value', strict=True, html='') + + def test_attr_false_not_rendered(self): + html = '' + self.check_html(Input(), 'name', 'value', html=html, attrs={'readonly': False}) From 248d54569ecbc0dd6e0ad444aaa8be6466f12d5d Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 23 Jan 2017 10:44:02 -0500 Subject: [PATCH 0105/3180] Removed MySQL decimal casting. Added in Django 1.0: 92c35a0617836b09aef3b6909579ee368004969b Unknown when it became obsolete. --- django/db/backends/mysql/base.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 38c349caeaf4..60cf4b9df507 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -49,8 +49,6 @@ django_conversions = conversions.copy() django_conversions.update({ FIELD_TYPE.TIME: backend_utils.typecast_time, - FIELD_TYPE.DECIMAL: backend_utils.typecast_decimal, - FIELD_TYPE.NEWDECIMAL: backend_utils.typecast_decimal, }) # This should match the numerical portion of the version numbers (we can treat From f0573aad4befcea969c73fa5f9a624ac22603164 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Mon, 23 Jan 2017 10:14:00 -0800 Subject: [PATCH 0106/3180] Replaced "not var is ..." with "is not" in attrs.html. --- django/forms/jinja2/django/forms/widgets/attrs.html | 2 +- django/forms/templates/django/forms/widgets/attrs.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/django/forms/jinja2/django/forms/widgets/attrs.html b/django/forms/jinja2/django/forms/widgets/attrs.html index 7fbda39ce51e..76926d79fe7e 100644 --- a/django/forms/jinja2/django/forms/widgets/attrs.html +++ b/django/forms/jinja2/django/forms/widgets/attrs.html @@ -1 +1 @@ -{% for name, value in widget.attrs.items() %}{% if value is not sameas False %} {{ name }}{% if not value is sameas True %}="{{ value }}"{% endif %}{% endif %}{% endfor %} +{% for name, value in widget.attrs.items() %}{% if value is not sameas False %} {{ name }}{% if value is not sameas True %}="{{ value }}"{% endif %}{% endif %}{% endfor %} diff --git a/django/forms/templates/django/forms/widgets/attrs.html b/django/forms/templates/django/forms/widgets/attrs.html index fdb1a56d90de..c8bba9f35c56 100644 --- a/django/forms/templates/django/forms/widgets/attrs.html +++ b/django/forms/templates/django/forms/widgets/attrs.html @@ -1 +1 @@ -{% for name, value in widget.attrs.items %}{% if value is not False %} {{ name }}{% if not value is True %}="{{ value }}"{% endif %}{% endif %}{% endfor %} \ No newline at end of file +{% for name, value in widget.attrs.items %}{% if value is not False %} {{ name }}{% if value is not True %}="{{ value }}"{% endif %}{% endif %}{% endfor %} \ No newline at end of file From d2e7d15b4c594f64ee9d37bf40e61920cea41487 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Mon, 23 Jan 2017 17:44:25 +0100 Subject: [PATCH 0107/3180] Assumed iri_to_uri always returns a string Thanks Tim Graham for the review. --- django/template/defaultfilters.py | 2 +- django/urls/base.py | 4 ++-- django/utils/encoding.py | 16 +++++++++------- docs/ref/models/instances.txt | 3 +-- docs/ref/utils.txt | 10 +++++----- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index a85e54524253..c6472bce1619 100644 --- a/django/template/defaultfilters.py +++ b/django/template/defaultfilters.py @@ -164,7 +164,7 @@ def floatformat(text, arg=-1): @stringfilter def iriencode(value): """Escapes an IRI value for use in a URL.""" - return force_text(iri_to_uri(value)) + return iri_to_uri(value) @register.filter(is_safe=True, needs_autoescape=True) diff --git a/django/urls/base.py b/django/urls/base.py index 408bc36eadb5..6dccdd2e7d47 100644 --- a/django/urls/base.py +++ b/django/urls/base.py @@ -1,7 +1,7 @@ from threading import local from urllib.parse import urlsplit, urlunsplit -from django.utils.encoding import force_text, iri_to_uri +from django.utils.encoding import iri_to_uri from django.utils.functional import lazy from django.utils.translation import override @@ -85,7 +85,7 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None): if ns_pattern: resolver = get_ns_resolver(ns_pattern, resolver) - return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))) + return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)) reverse_lazy = lazy(reverse, str) diff --git a/django/utils/encoding.py b/django/utils/encoding.py index 71c2985e27eb..d0fd2f19e71c 100644 --- a/django/utils/encoding.py +++ b/django/utils/encoding.py @@ -151,13 +151,13 @@ def iri_to_uri(iri): Convert an Internationalized Resource Identifier (IRI) portion to a URI portion that is suitable for inclusion in a URL. - This is the algorithm from section 3.1 of RFC 3987. However, since we are - assuming input is either UTF-8 or unicode already, we can simplify things a - little from the full method. + This is the algorithm from section 3.1 of RFC 3987, slightly simplified + since the input is assumed to be a string rather than an arbitrary byte + stream. - Takes an IRI in UTF-8 bytes (e.g. '/I \xe2\x99\xa5 Django/') or unicode - (e.g. '/I ♥ Django/') and returns ASCII bytes containing the encoded result - (e.g. '/I%20%E2%99%A5%20Django/'). + Take an IRI (string or UTF-8 bytes, e.g. '/I ♥ Django/' or + b'/I \xe2\x99\xa5 Django/') and return a string containing the encoded + result with ASCII chars only (e.g. '/I%20%E2%99%A5%20Django/'). """ # The list of safe characters here is constructed from the "reserved" and # "unreserved" characters specified in sections 2.2 and 2.3 of RFC 3986: @@ -173,7 +173,9 @@ def iri_to_uri(iri): # converted. if iri is None: return iri - return quote(force_bytes(iri), safe=b"/#%[]=:;$&()+,!?*@'~") + elif isinstance(iri, Promise): + iri = str(iri) + return quote(iri, safe="/#%[]=:;$&()+,!?*@'~") def uri_to_iri(uri): diff --git a/docs/ref/models/instances.txt b/docs/ref/models/instances.txt index 838a4bd4de68..058fd59512f2 100644 --- a/docs/ref/models/instances.txt +++ b/docs/ref/models/instances.txt @@ -733,8 +733,7 @@ in ``get_absolute_url()`` and have all your other code call that one place. Code and templates calling ``get_absolute_url()`` should be able to use the result directly without any further processing. You may wish to use the ``django.utils.encoding.iri_to_uri()`` function to help with this if you - are using unicode strings containing characters outside the ASCII range at - all. + are using strings containing characters outside the ASCII range. Extra instance methods ====================== diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index 550facd14280..056f228bdf1d 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -262,12 +262,12 @@ The functions defined in this module share the following properties: Convert an Internationalized Resource Identifier (IRI) portion to a URI portion that is suitable for inclusion in a URL. - This is the algorithm from section 3.1 of :rfc:`3987#section-3.1`. However, - since we are assuming input is either UTF-8 or unicode already, we can - simplify things a little from the full method. + This is the algorithm from section 3.1 of :rfc:`3987#section-3.1`, slightly + simplified since the input is assumed to be a string rather than an + arbitrary byte stream. - Takes an IRI in UTF-8 bytes and returns ASCII bytes containing the encoded - result. + Takes an IRI (string or UTF-8 bytes) and returns a string containing the + encoded result. .. function:: uri_to_iri(uri) From 0d74c41981687598d3fa0a7eb9712ce4c387ca19 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Mon, 23 Jan 2017 16:13:49 -0800 Subject: [PATCH 0108/3180] Replaced dict() usage with dict literals. Literals are faster and more idiomatic. --- django/forms/widgets.py | 20 +++++++------- django/test/runner.py | 10 +++---- tests/admin_views/tests.py | 42 ++++++++++++++++------------- tests/view_tests/tests/test_i18n.py | 14 +++++----- 4 files changed, 46 insertions(+), 40 deletions(-) diff --git a/django/forms/widgets.py b/django/forms/widgets.py index 5e6eddaf911b..71169d96189a 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -593,16 +593,16 @@ def create_option(self, name, value, label, selected, index, subindex=None, attr option_attrs.update(self.checked_attribute) if 'id' in option_attrs: option_attrs['id'] = self.id_for_label(option_attrs['id'], index) - return dict( - name=name, - value=value, - label=label, - selected=selected, - index=index, - attrs=option_attrs, - type=self.input_type, - template_name=self.option_template_name, - ) + return { + 'name': name, + 'value': value, + 'label': label, + 'selected': selected, + 'index': index, + 'attrs': option_attrs, + 'type': self.input_type, + 'template_name': self.option_template_name, + } def get_context(self, name, value, attrs=None): context = super(ChoiceWidget, self).get_context(name, value, attrs) diff --git a/django/test/runner.py b/django/test/runner.py index 090adcec950d..a0648b2f97fb 100644 --- a/django/test/runner.py +++ b/django/test/runner.py @@ -550,11 +550,11 @@ def get_resultclass(self): return DebugSQLTextTestResult if self.debug_sql else None def get_test_runner_kwargs(self): - return dict( - failfast=self.failfast, - resultclass=self.get_resultclass(), - verbosity=self.verbosity, - ) + return { + 'failfast': self.failfast, + 'resultclass': self.get_resultclass(), + 'verbosity': self.verbosity, + } def run_checks(self): # Checks are run after database creation since some checks require diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index cd423f6a01b6..e36dfa31419f 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -582,24 +582,30 @@ def test_relation_spanning_filters(self): response = self.client.get(changelist_url) self.assertContains(response, '
    ') filters = { - 'chap__id__exact': dict( - values=[c.id for c in Chapter.objects.all()], - test=lambda obj, value: obj.chap.id == value), - 'chap__title': dict( - values=[c.title for c in Chapter.objects.all()], - test=lambda obj, value: obj.chap.title == value), - 'chap__book__id__exact': dict( - values=[b.id for b in Book.objects.all()], - test=lambda obj, value: obj.chap.book.id == value), - 'chap__book__name': dict( - values=[b.name for b in Book.objects.all()], - test=lambda obj, value: obj.chap.book.name == value), - 'chap__book__promo__id__exact': dict( - values=[p.id for p in Promo.objects.all()], - test=lambda obj, value: obj.chap.book.promo_set.filter(id=value).exists()), - 'chap__book__promo__name': dict( - values=[p.name for p in Promo.objects.all()], - test=lambda obj, value: obj.chap.book.promo_set.filter(name=value).exists()), + 'chap__id__exact': { + 'values': [c.id for c in Chapter.objects.all()], + 'test': lambda obj, value: obj.chap.id == value, + }, + 'chap__title': { + 'values': [c.title for c in Chapter.objects.all()], + 'test': lambda obj, value: obj.chap.title == value, + }, + 'chap__book__id__exact': { + 'values': [b.id for b in Book.objects.all()], + 'test': lambda obj, value: obj.chap.book.id == value, + }, + 'chap__book__name': { + 'values': [b.name for b in Book.objects.all()], + 'test': lambda obj, value: obj.chap.book.name == value, + }, + 'chap__book__promo__id__exact': { + 'values': [p.id for p in Promo.objects.all()], + 'test': lambda obj, value: obj.chap.book.promo_set.filter(id=value).exists(), + }, + 'chap__book__promo__name': { + 'values': [p.name for p in Promo.objects.all()], + 'test': lambda obj, value: obj.chap.book.promo_set.filter(name=value).exists(), + }, } for filter_path, params in filters.items(): for value in params['values']: diff --git a/tests/view_tests/tests/test_i18n.py b/tests/view_tests/tests/test_i18n.py index f9c49ad3bb56..7d3d22154946 100644 --- a/tests/view_tests/tests/test_i18n.py +++ b/tests/view_tests/tests/test_i18n.py @@ -134,13 +134,13 @@ def test_setlang_reversal(self): def test_setlang_cookie(self): # we force saving language to a cookie rather than a session # by excluding session middleware and those which do require it - test_settings = dict( - MIDDLEWARE=['django.middleware.common.CommonMiddleware'], - LANGUAGE_COOKIE_NAME='mylanguage', - LANGUAGE_COOKIE_AGE=3600 * 7 * 2, - LANGUAGE_COOKIE_DOMAIN='.example.com', - LANGUAGE_COOKIE_PATH='/test/', - ) + test_settings = { + 'MIDDLEWARE': ['django.middleware.common.CommonMiddleware'], + 'LANGUAGE_COOKIE_NAME': 'mylanguage', + 'LANGUAGE_COOKIE_AGE': 3600 * 7 * 2, + 'LANGUAGE_COOKIE_DOMAIN': '.example.com', + 'LANGUAGE_COOKIE_PATH': '/test/', + } with self.settings(**test_settings): post_data = dict(language='pl', next='/views/') response = self.client.post('/i18n/setlang/', data=post_data) From e5c2e43cc832028a974399af07a1c3ba6afa2467 Mon Sep 17 00:00:00 2001 From: Nick Mavrakis Date: Tue, 24 Jan 2017 02:24:47 +0200 Subject: [PATCH 0109/3180] Fixed #27743 -- Prevented admin's "+" button icon from overlapping its label. --- django/contrib/admin/static/admin/css/base.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django/contrib/admin/static/admin/css/base.css b/django/contrib/admin/static/admin/css/base.css index 466b36bceccc..b2a40c49b20f 100644 --- a/django/contrib/admin/static/admin/css/base.css +++ b/django/contrib/admin/static/admin/css/base.css @@ -738,7 +738,7 @@ a.deletelink:focus, a.deletelink:hover { .object-tools a.viewsitelink, .object-tools a.golink,.object-tools a.addlink { background-repeat: no-repeat; - background-position: 93% center; + background-position: right 7px center; padding-right: 26px; } From 435e4bf38e97255acd97eacadeb8fe312ba97aff Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 24 Jan 2017 08:31:58 -0500 Subject: [PATCH 0110/3180] Refs #23919 -- Removed __traceback__ setting needed for Python 2. Partially reverted refs #25761 and refs #16245. --- django/db/utils.py | 2 -- django/dispatch/dispatcher.py | 6 +----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/django/db/utils.py b/django/db/utils.py index 7ef57fd8a3f6..dfdeff9c5166 100644 --- a/django/db/utils.py +++ b/django/db/utils.py @@ -83,8 +83,6 @@ def __exit__(self, exc_type, exc_value, traceback): if issubclass(exc_type, db_exc_type): dj_exc_value = dj_exc_type(*exc_value.args) dj_exc_value.__cause__ = exc_value - if not hasattr(exc_value, '__traceback__'): - exc_value.__traceback__ = traceback # Only set the 'errors_occurred' flag for errors that may make # the connection unusable. if dj_exc_type not in (DataError, IntegrityError): diff --git a/django/dispatch/dispatcher.py b/django/dispatch/dispatcher.py index 09992c5b8cd2..5599b9fdfcb7 100644 --- a/django/dispatch/dispatcher.py +++ b/django/dispatch/dispatcher.py @@ -1,4 +1,3 @@ -import sys import threading import weakref @@ -200,8 +199,7 @@ def send_robust(self, sender, **named): If any receiver raises an error (specifically any subclass of Exception), the error instance is returned as the result for that - receiver. The traceback is always attached to the error at - ``__traceback__``. + receiver. """ if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS: return [] @@ -213,8 +211,6 @@ def send_robust(self, sender, **named): try: response = receiver(signal=self, sender=sender, **named) except Exception as err: - if not hasattr(err, '__traceback__'): - err.__traceback__ = sys.exc_info()[2] responses.append((receiver, err)) else: responses.append((receiver, response)) From a87d6b69a75d0f9a66652e3f0bd1c2c85624c7d5 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 24 Jan 2017 08:33:26 -0500 Subject: [PATCH 0111/3180] Tidied djang.db.utils.load_backend(). Removed an unneeded EnvironmentError catching and used "raise from exc" syntax. --- django/db/utils.py | 26 +++++++++++--------------- tests/backends/test_utils.py | 6 +++--- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/django/db/utils.py b/django/db/utils.py index dfdeff9c5166..1bf44cbe26bd 100644 --- a/django/db/utils.py +++ b/django/db/utils.py @@ -111,23 +111,19 @@ def load_backend(backend_name): return import_module('%s.base' % backend_name) except ImportError as e_user: # The database backend wasn't found. Display a helpful error message - # listing all possible (built-in) database backends. + # listing all built-in database backends. backend_dir = os.path.join(os.path.dirname(__file__), 'backends') - try: - builtin_backends = [ - name for _, name, ispkg in pkgutil.iter_modules([backend_dir]) - if ispkg and name not in {'base', 'dummy', 'postgresql_psycopg2'} - ] - except EnvironmentError: - builtin_backends = [] - if backend_name not in ['django.db.backends.%s' % b for b in - builtin_backends]: + builtin_backends = [ + name for _, name, ispkg in pkgutil.iter_modules([backend_dir]) + if ispkg and name not in {'base', 'dummy', 'postgresql_psycopg2'} + ] + if backend_name not in ['django.db.backends.%s' % b for b in builtin_backends]: backend_reprs = map(repr, sorted(builtin_backends)) - error_msg = ("%r isn't an available database backend.\n" - "Try using 'django.db.backends.XXX', where XXX " - "is one of:\n %s\nError was: %s" % - (backend_name, ", ".join(backend_reprs), e_user)) - raise ImproperlyConfigured(error_msg) + raise ImproperlyConfigured( + "%r isn't an available database backend.\n" + "Try using 'django.db.backends.XXX', where XXX is one of:\n" + " %s" % (backend_name, ", ".join(backend_reprs)) + ) from e_user else: # If there's some other error, this must be an error in Django raise diff --git a/tests/backends/test_utils.py b/tests/backends/test_utils.py index d158e2a5a280..165820edae24 100644 --- a/tests/backends/test_utils.py +++ b/tests/backends/test_utils.py @@ -8,8 +8,8 @@ def test_load_backend_invalid_name(self): msg = ( "'foo' isn't an available database backend.\n" "Try using 'django.db.backends.XXX', where XXX is one of:\n" - " 'mysql', 'oracle', 'postgresql', 'sqlite3'\n" - "Error was: No module named 'foo'" + " 'mysql', 'oracle', 'postgresql', 'sqlite3'" ) - with self.assertRaisesMessage(ImproperlyConfigured, msg): + with self.assertRaisesMessage(ImproperlyConfigured, msg) as cm: load_backend('foo') + self.assertEqual(str(cm.exception.__cause__), "No module named 'foo'") From 5b95d421f7ab8deadaf3c1ad3f341bdfc85bfca4 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 23 Jan 2017 10:36:48 -0500 Subject: [PATCH 0112/3180] Refs #23919 -- Removed a MySQLdb workaround (refs #6052) for Python 2. --- django/db/backends/mysql/base.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 60cf4b9df507..76a4313a721e 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -10,7 +10,6 @@ from django.db.backends import utils as backend_utils from django.db.backends.base.base import BaseDatabaseWrapper from django.utils.functional import cached_property -from django.utils.safestring import SafeBytes, SafeText try: import MySQLdb as Database @@ -43,9 +42,7 @@ # MySQLdb-1.2.1 returns TIME columns as timedelta -- they are more like # timedelta in terms of actual behavior as they are signed and include days -- -# and Django expects time, so we still need to override that. We also need to -# add special handling for SafeText and SafeBytes as MySQLdb's type -# checking is too tight to catch those (see Django ticket #6052). +# and Django expects time. django_conversions = conversions.copy() django_conversions.update({ FIELD_TYPE.TIME: backend_utils.typecast_time, @@ -249,10 +246,7 @@ def get_connection_params(self): return kwargs def get_new_connection(self, conn_params): - conn = Database.connect(**conn_params) - conn.encoders[SafeText] = conn.encoders[str] - conn.encoders[SafeBytes] = conn.encoders[bytes] - return conn + return Database.connect(**conn_params) def init_connection_state(self): assignments = [] From 2366100872ec17dde06abc63c1ad74dcf746b134 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Tue, 24 Jan 2017 12:22:42 +0100 Subject: [PATCH 0113/3180] Removed unneeded force_text calls in the test suite --- tests/admin_filters/tests.py | 69 +++++++++---------- tests/admin_scripts/tests.py | 5 +- tests/auth_tests/test_deprecated_views.py | 3 +- tests/auth_tests/test_forms.py | 25 ++++--- tests/auth_tests/test_templates.py | 4 +- tests/auth_tests/test_views.py | 2 +- tests/cache/tests.py | 5 +- tests/check_framework/tests.py | 15 ++-- tests/contenttypes_tests/tests.py | 7 +- tests/csrf_tests/test_context_processor.py | 5 +- tests/fixtures/tests.py | 3 +- tests/forms_tests/tests/test_forms.py | 7 +- tests/forms_tests/tests/test_formsets.py | 3 +- tests/forms_tests/tests/test_media.py | 3 +- tests/forms_tests/tests/test_utils.py | 5 +- tests/i18n/test_compilation.py | 11 ++- tests/i18n/test_extraction.py | 36 +++++----- tests/i18n/test_percents.py | 3 +- tests/inspectdb/tests.py | 3 +- tests/managers_regress/models.py | 5 +- tests/managers_regress/tests.py | 3 +- tests/migrations/test_commands.py | 3 +- tests/migrations/test_graph.py | 5 +- tests/prefetch_related/tests.py | 3 +- tests/sessions_tests/tests.py | 3 +- tests/staticfiles_tests/cases.py | 3 +- tests/staticfiles_tests/test_management.py | 31 ++++----- tests/staticfiles_tests/test_storage.py | 3 +- .../filter_tests/test_slugify.py | 3 +- tests/utils_tests/test_encoding.py | 2 +- tests/utils_tests/test_html.py | 7 +- tests/view_tests/tests/test_debug.py | 12 ++-- 32 files changed, 132 insertions(+), 165 deletions(-) diff --git a/tests/admin_filters/tests.py b/tests/admin_filters/tests.py index 0df02708a81f..4dc6c3365a17 100644 --- a/tests/admin_filters/tests.py +++ b/tests/admin_filters/tests.py @@ -11,7 +11,6 @@ from django.contrib.auth.models import User from django.core.exceptions import ImproperlyConfigured from django.test import RequestFactory, TestCase, override_settings -from django.utils.encoding import force_text from .models import Book, Bookmark, Department, Employee, TaggedItem @@ -332,7 +331,7 @@ def test_datefieldlistfilter(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][4] - self.assertEqual(force_text(filterspec.title), 'date registered') + self.assertEqual(filterspec.title, 'date registered') choice = select_by(filterspec.choices(changelist), "display", "Today") self.assertIs(choice['selected'], True) self.assertEqual( @@ -357,7 +356,7 @@ def test_datefieldlistfilter(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][4] - self.assertEqual(force_text(filterspec.title), 'date registered') + self.assertEqual(filterspec.title, 'date registered') choice = select_by(filterspec.choices(changelist), "display", "This month") self.assertIs(choice['selected'], True) self.assertEqual( @@ -382,7 +381,7 @@ def test_datefieldlistfilter(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][4] - self.assertEqual(force_text(filterspec.title), 'date registered') + self.assertEqual(filterspec.title, 'date registered') choice = select_by(filterspec.choices(changelist), "display", "This year") self.assertIs(choice['selected'], True) self.assertEqual( @@ -405,7 +404,7 @@ def test_datefieldlistfilter(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][4] - self.assertEqual(force_text(filterspec.title), 'date registered') + self.assertEqual(filterspec.title, 'date registered') choice = select_by(filterspec.choices(changelist), "display", "Past 7 days") self.assertIs(choice['selected'], True) self.assertEqual( @@ -427,7 +426,7 @@ def test_datefieldlistfilter(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][4] - self.assertEqual(force_text(filterspec.title), 'date registered') + self.assertEqual(filterspec.title, 'date registered') choice = select_by(filterspec.choices(changelist), 'display', 'No date') self.assertIs(choice['selected'], True) self.assertEqual(choice['query_string'], '?date_registered__isnull=True') @@ -442,7 +441,7 @@ def test_datefieldlistfilter(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][4] - self.assertEqual(force_text(filterspec.title), 'date registered') + self.assertEqual(filterspec.title, 'date registered') choice = select_by(filterspec.choices(changelist), 'display', 'Has date') self.assertIs(choice['selected'], True) self.assertEqual(choice['query_string'], '?date_registered__isnull=False') @@ -469,7 +468,7 @@ def test_allvaluesfieldlistfilter(self): # Make sure the last choice is None and is selected filterspec = changelist.get_filters(request)[0][0] - self.assertEqual(force_text(filterspec.title), 'year') + self.assertEqual(filterspec.title, 'year') choices = list(filterspec.choices(changelist)) self.assertIs(choices[-1]['selected'], True) self.assertEqual(choices[-1]['query_string'], '?year__isnull=True') @@ -479,7 +478,7 @@ def test_allvaluesfieldlistfilter(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][0] - self.assertEqual(force_text(filterspec.title), 'year') + self.assertEqual(filterspec.title, 'year') choices = list(filterspec.choices(changelist)) self.assertIs(choices[2]['selected'], True) self.assertEqual(choices[2]['query_string'], '?year=2002') @@ -520,7 +519,7 @@ def test_relatedfieldlistfilter_foreignkey(self): # Make sure the last choice is None and is selected filterspec = changelist.get_filters(request)[0][1] - self.assertEqual(force_text(filterspec.title), 'Verbose Author') + self.assertEqual(filterspec.title, 'Verbose Author') choices = list(filterspec.choices(changelist)) self.assertIs(choices[-1]['selected'], True) self.assertEqual(choices[-1]['query_string'], '?author__isnull=True') @@ -530,7 +529,7 @@ def test_relatedfieldlistfilter_foreignkey(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][1] - self.assertEqual(force_text(filterspec.title), 'Verbose Author') + self.assertEqual(filterspec.title, 'Verbose Author') # order of choices depends on User model, which has no order choice = select_by(filterspec.choices(changelist), "display", "alfred") self.assertIs(choice['selected'], True) @@ -556,7 +555,7 @@ def test_relatedfieldlistfilter_manytomany(self): # Make sure the last choice is None and is selected filterspec = changelist.get_filters(request)[0][2] - self.assertEqual(force_text(filterspec.title), 'Verbose Contributors') + self.assertEqual(filterspec.title, 'Verbose Contributors') choices = list(filterspec.choices(changelist)) self.assertIs(choices[-1]['selected'], True) self.assertEqual(choices[-1]['query_string'], '?contributors__isnull=True') @@ -566,7 +565,7 @@ def test_relatedfieldlistfilter_manytomany(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][2] - self.assertEqual(force_text(filterspec.title), 'Verbose Contributors') + self.assertEqual(filterspec.title, 'Verbose Contributors') choice = select_by(filterspec.choices(changelist), "display", "bob") self.assertIs(choice['selected'], True) self.assertEqual(choice['query_string'], '?contributors__id__exact=%d' % self.bob.pk) @@ -584,7 +583,7 @@ def test_relatedfieldlistfilter_reverse_relationships(self): # Make sure the last choice is None and is selected filterspec = changelist.get_filters(request)[0][0] - self.assertEqual(force_text(filterspec.title), 'book') + self.assertEqual(filterspec.title, 'book') choices = list(filterspec.choices(changelist)) self.assertIs(choices[-1]['selected'], True) self.assertEqual(choices[-1]['query_string'], '?books_authored__isnull=True') @@ -594,7 +593,7 @@ def test_relatedfieldlistfilter_reverse_relationships(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][0] - self.assertEqual(force_text(filterspec.title), 'book') + self.assertEqual(filterspec.title, 'book') choice = select_by(filterspec.choices(changelist), "display", self.bio_book.title) self.assertIs(choice['selected'], True) self.assertEqual(choice['query_string'], '?books_authored__id__exact=%d' % self.bio_book.pk) @@ -609,7 +608,7 @@ def test_relatedfieldlistfilter_reverse_relationships(self): # Make sure the last choice is None and is selected filterspec = changelist.get_filters(request)[0][1] - self.assertEqual(force_text(filterspec.title), 'book') + self.assertEqual(filterspec.title, 'book') choices = list(filterspec.choices(changelist)) self.assertIs(choices[-1]['selected'], True) self.assertEqual(choices[-1]['query_string'], '?books_contributed__isnull=True') @@ -619,7 +618,7 @@ def test_relatedfieldlistfilter_reverse_relationships(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][1] - self.assertEqual(force_text(filterspec.title), 'book') + self.assertEqual(filterspec.title, 'book') choice = select_by(filterspec.choices(changelist), "display", self.django_book.title) self.assertIs(choice['selected'], True) self.assertEqual(choice['query_string'], '?books_contributed__id__exact=%d' % self.django_book.pk) @@ -715,7 +714,7 @@ def verify_booleanfieldlistfilter(self, modeladmin): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][3] - self.assertEqual(force_text(filterspec.title), 'is best seller') + self.assertEqual(filterspec.title, 'is best seller') choice = select_by(filterspec.choices(changelist), "display", "No") self.assertIs(choice['selected'], True) self.assertEqual(choice['query_string'], '?is_best_seller__exact=0') @@ -729,7 +728,7 @@ def verify_booleanfieldlistfilter(self, modeladmin): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][3] - self.assertEqual(force_text(filterspec.title), 'is best seller') + self.assertEqual(filterspec.title, 'is best seller') choice = select_by(filterspec.choices(changelist), "display", "Yes") self.assertIs(choice['selected'], True) self.assertEqual(choice['query_string'], '?is_best_seller__exact=1') @@ -743,7 +742,7 @@ def verify_booleanfieldlistfilter(self, modeladmin): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][3] - self.assertEqual(force_text(filterspec.title), 'is best seller') + self.assertEqual(filterspec.title, 'is best seller') choice = select_by(filterspec.choices(changelist), "display", "Unknown") self.assertIs(choice['selected'], True) self.assertEqual(choice['query_string'], '?is_best_seller__isnull=True') @@ -777,7 +776,7 @@ def test_simplelistfilter(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][1] - self.assertEqual(force_text(filterspec.title), 'publication decade') + self.assertEqual(filterspec.title, 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[0]['display'], 'All') self.assertIs(choices[0]['selected'], True) @@ -793,7 +792,7 @@ def test_simplelistfilter(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][1] - self.assertEqual(force_text(filterspec.title), 'publication decade') + self.assertEqual(filterspec.title, 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[1]['display'], 'the 1980\'s') self.assertIs(choices[1]['selected'], True) @@ -809,7 +808,7 @@ def test_simplelistfilter(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][1] - self.assertEqual(force_text(filterspec.title), 'publication decade') + self.assertEqual(filterspec.title, 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[2]['display'], 'the 1990\'s') self.assertIs(choices[2]['selected'], True) @@ -825,7 +824,7 @@ def test_simplelistfilter(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][1] - self.assertEqual(force_text(filterspec.title), 'publication decade') + self.assertEqual(filterspec.title, 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[3]['display'], 'the 2000\'s') self.assertIs(choices[3]['selected'], True) @@ -841,7 +840,7 @@ def test_simplelistfilter(self): # Make sure the correct choices are selected filterspec = changelist.get_filters(request)[0][1] - self.assertEqual(force_text(filterspec.title), 'publication decade') + self.assertEqual(filterspec.title, 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[3]['display'], 'the 2000\'s') self.assertIs(choices[3]['selected'], True) @@ -851,7 +850,7 @@ def test_simplelistfilter(self): ) filterspec = changelist.get_filters(request)[0][0] - self.assertEqual(force_text(filterspec.title), 'Verbose Author') + self.assertEqual(filterspec.title, 'Verbose Author') choice = select_by(filterspec.choices(changelist), "display", "alfred") self.assertIs(choice['selected'], True) self.assertEqual(choice['query_string'], '?author__id__exact=%s&publication-decade=the+00s' % self.alfred.pk) @@ -903,7 +902,7 @@ def test_simplelistfilter_with_queryset_based_lookups(self): changelist = self.get_changelist(request, Book, modeladmin) filterspec = changelist.get_filters(request)[0][0] - self.assertEqual(force_text(filterspec.title), 'publication decade') + self.assertEqual(filterspec.title, 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(len(choices), 3) @@ -932,7 +931,7 @@ def test_two_characters_long_field(self): self.assertEqual(list(queryset), [self.bio_book]) filterspec = changelist.get_filters(request)[0][-1] - self.assertEqual(force_text(filterspec.title), 'number') + self.assertEqual(filterspec.title, 'number') choices = list(filterspec.choices(changelist)) self.assertIs(choices[2]['selected'], True) self.assertEqual(choices[2]['query_string'], '?no=207') @@ -953,7 +952,7 @@ def test_parameter_ends_with__in__or__isnull(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][0] - self.assertEqual(force_text(filterspec.title), 'publication decade') + self.assertEqual(filterspec.title, 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[2]['display'], 'the 1990\'s') self.assertIs(choices[2]['selected'], True) @@ -970,7 +969,7 @@ def test_parameter_ends_with__in__or__isnull(self): # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][0] - self.assertEqual(force_text(filterspec.title), 'publication decade') + self.assertEqual(filterspec.title, 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[2]['display'], 'the 1990\'s') self.assertIs(choices[2]['selected'], True) @@ -990,7 +989,7 @@ def test_lookup_with_non_string_value(self): self.assertEqual(list(queryset), [self.john]) filterspec = changelist.get_filters(request)[0][-1] - self.assertEqual(force_text(filterspec.title), 'department') + self.assertEqual(filterspec.title, 'department') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[1]['display'], 'DEV') self.assertIs(choices[1]['selected'], True) @@ -1010,7 +1009,7 @@ def test_lookup_with_non_string_value_underscored(self): self.assertEqual(list(queryset), [self.john]) filterspec = changelist.get_filters(request)[0][-1] - self.assertEqual(force_text(filterspec.title), 'department') + self.assertEqual(filterspec.title, 'department') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[1]['display'], 'DEV') self.assertIs(choices[1]['selected'], True) @@ -1030,7 +1029,7 @@ def test_fk_with_to_field(self): self.assertEqual(list(queryset), [self.jack, self.john]) filterspec = changelist.get_filters(request)[0][-1] - self.assertEqual(force_text(filterspec.title), 'department') + self.assertEqual(filterspec.title, 'department') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[0]['display'], 'All') @@ -1055,7 +1054,7 @@ def test_fk_with_to_field(self): self.assertEqual(list(queryset), [self.john]) filterspec = changelist.get_filters(request)[0][-1] - self.assertEqual(force_text(filterspec.title), 'department') + self.assertEqual(filterspec.title, 'department') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[0]['display'], 'All') @@ -1079,7 +1078,7 @@ def test_lookup_with_dynamic_value(self): def _test_choices(request, expected_displays): changelist = self.get_changelist(request, Book, modeladmin) filterspec = changelist.get_filters(request)[0][0] - self.assertEqual(force_text(filterspec.title), 'publication decade') + self.assertEqual(filterspec.title, 'publication decade') choices = tuple(c['display'] for c in filterspec.choices(changelist)) self.assertEqual(choices, expected_displays) diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index c8f5d2a20df5..88a0260358ae 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -27,7 +27,6 @@ from django.test import ( LiveServerTestCase, SimpleTestCase, TestCase, override_settings, ) -from django.utils.encoding import force_text custom_templates_dir = os.path.join(os.path.dirname(__file__), 'custom_templates') @@ -196,7 +195,6 @@ def assertNoOutput(self, stream): def assertOutput(self, stream, msg, regex=False): "Utility assertion: assert that the given message exists in the output" - stream = force_text(stream) if regex: self.assertIsNotNone( re.search(msg, stream), @@ -207,7 +205,6 @@ def assertOutput(self, stream, msg, regex=False): def assertNotInOutput(self, stream, msg): "Utility assertion: assert that the given message doesn't exist in the output" - stream = force_text(stream) self.assertNotIn(msg, stream, "'%s' matches actual output text '%s'" % (msg, stream)) ########################################################################## @@ -2021,7 +2018,7 @@ def test_custom_project_template_context_variables(self): self.assertNoOutput(err) test_manage_py = os.path.join(testproject_dir, 'manage.py') with open(test_manage_py, 'r') as fp: - content = force_text(fp.read()) + content = fp.read() self.assertIn("project_name = 'another_project'", content) self.assertIn("project_directory = '%s'" % testproject_dir, content) diff --git a/tests/auth_tests/test_deprecated_views.py b/tests/auth_tests/test_deprecated_views.py index d5088b9d8a1d..285638027eb5 100644 --- a/tests/auth_tests/test_deprecated_views.py +++ b/tests/auth_tests/test_deprecated_views.py @@ -14,7 +14,6 @@ from django.test import TestCase, override_settings from django.test.utils import ignore_warnings, patch_logger from django.utils.deprecation import RemovedInDjango21Warning -from django.utils.encoding import force_text from .models import CustomUser, UUIDUser from .settings import AUTH_TEMPLATES @@ -52,7 +51,7 @@ def logout(self): def assertFormError(self, response, error): """Assert that error is found in response.context['form'] errors""" form_errors = list(itertools.chain(*response.context['form'].errors.values())) - self.assertIn(force_text(error), form_errors) + self.assertIn(str(error), form_errors) def assertURLEqual(self, url, expected, parse_qs=False): """ diff --git a/tests/auth_tests/test_forms.py b/tests/auth_tests/test_forms.py index bbcd75124a16..abd5b0f8df75 100644 --- a/tests/auth_tests/test_forms.py +++ b/tests/auth_tests/test_forms.py @@ -16,7 +16,6 @@ from django.forms.fields import CharField, Field, IntegerField from django.test import SimpleTestCase, TestCase, override_settings from django.utils import translation -from django.utils.encoding import force_text from django.utils.text import capfirst from django.utils.translation import ugettext as _ @@ -51,7 +50,7 @@ def test_user_already_exists(self): form = UserCreationForm(data) self.assertFalse(form.is_valid()) self.assertEqual(form["username"].errors, - [force_text(User._meta.get_field('username').error_messages['unique'])]) + [str(User._meta.get_field('username').error_messages['unique'])]) def test_invalid_data(self): data = { @@ -62,7 +61,7 @@ def test_invalid_data(self): form = UserCreationForm(data) self.assertFalse(form.is_valid()) validator = next(v for v in User._meta.get_field('username').validators if v.code == 'invalid') - self.assertEqual(form["username"].errors, [force_text(validator.message)]) + self.assertEqual(form["username"].errors, [str(validator.message)]) def test_password_verification(self): # The verification password is incorrect. @@ -74,13 +73,13 @@ def test_password_verification(self): form = UserCreationForm(data) self.assertFalse(form.is_valid()) self.assertEqual(form["password2"].errors, - [force_text(form.error_messages['password_mismatch'])]) + [str(form.error_messages['password_mismatch'])]) def test_both_passwords(self): # One (or both) passwords weren't given data = {'username': 'jsmith'} form = UserCreationForm(data) - required_error = [force_text(Field.default_error_messages['required'])] + required_error = [str(Field.default_error_messages['required'])] self.assertFalse(form.is_valid()) self.assertEqual(form['password1'].errors, required_error) self.assertEqual(form['password2'].errors, required_error) @@ -257,9 +256,9 @@ def test_invalid_username(self): self.assertFalse(form.is_valid()) self.assertEqual( form.non_field_errors(), [ - force_text(form.error_messages['invalid_login'] % { + form.error_messages['invalid_login'] % { 'username': User._meta.get_field('username').verbose_name - }) + } ] ) @@ -271,7 +270,7 @@ def test_inactive_user(self): } form = AuthenticationForm(None, data) self.assertFalse(form.is_valid()) - self.assertEqual(form.non_field_errors(), [force_text(form.error_messages['inactive'])]) + self.assertEqual(form.non_field_errors(), [str(form.error_messages['inactive'])]) def test_login_failed(self): signal_calls = [] @@ -300,7 +299,7 @@ def test_inactive_user_i18n(self): } form = AuthenticationForm(None, data) self.assertFalse(form.is_valid()) - self.assertEqual(form.non_field_errors(), [force_text(form.error_messages['inactive'])]) + self.assertEqual(form.non_field_errors(), [str(form.error_messages['inactive'])]) def test_custom_login_allowed_policy(self): # The user is inactive, but our custom form policy allows them to log in. @@ -421,7 +420,7 @@ def test_password_verification(self): self.assertFalse(form.is_valid()) self.assertEqual( form["new_password2"].errors, - [force_text(form.error_messages['password_mismatch'])] + [str(form.error_messages['password_mismatch'])] ) @mock.patch('django.contrib.auth.password_validation.password_changed') @@ -499,7 +498,7 @@ def test_incorrect_password(self): } form = PasswordChangeForm(user, data) self.assertFalse(form.is_valid()) - self.assertEqual(form["old_password"].errors, [force_text(form.error_messages['password_incorrect'])]) + self.assertEqual(form["old_password"].errors, [str(form.error_messages['password_incorrect'])]) def test_password_verification(self): # The two new passwords do not match. @@ -511,7 +510,7 @@ def test_password_verification(self): } form = PasswordChangeForm(user, data) self.assertFalse(form.is_valid()) - self.assertEqual(form["new_password2"].errors, [force_text(form.error_messages['password_mismatch'])]) + self.assertEqual(form["new_password2"].errors, [str(form.error_messages['password_mismatch'])]) @mock.patch('django.contrib.auth.password_validation.password_changed') def test_success(self, password_changed): @@ -557,7 +556,7 @@ def test_username_validity(self): form = UserChangeForm(data, instance=user) self.assertFalse(form.is_valid()) validator = next(v for v in User._meta.get_field('username').validators if v.code == 'invalid') - self.assertEqual(form["username"].errors, [force_text(validator.message)]) + self.assertEqual(form["username"].errors, [str(validator.message)]) def test_bug_14242(self): # A regression test, introduce by adding an optimization for the diff --git a/tests/auth_tests/test_templates.py b/tests/auth_tests/test_templates.py index a1d14c977421..b2c1d654a620 100644 --- a/tests/auth_tests/test_templates.py +++ b/tests/auth_tests/test_templates.py @@ -7,7 +7,7 @@ ) from django.test import RequestFactory, TestCase, override_settings from django.urls import reverse -from django.utils.encoding import force_bytes, force_text +from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_encode from .client import PasswordResetConfirmClient @@ -48,7 +48,7 @@ def test_PasswordResetConfirmView_valid_token(self): client = PasswordResetConfirmClient() default_token_generator = PasswordResetTokenGenerator() token = default_token_generator.make_token(self.user) - uidb64 = force_text(urlsafe_base64_encode(force_bytes(self.user.pk))) + uidb64 = urlsafe_base64_encode(force_bytes(self.user.pk)).decode() url = reverse('password_reset_confirm', kwargs={'uidb64': uidb64, 'token': token}) response = client.get(url) self.assertContains(response, 'Enter new password') diff --git a/tests/auth_tests/test_views.py b/tests/auth_tests/test_views.py index dd87a5bf00c7..1e18e0c73b6b 100644 --- a/tests/auth_tests/test_views.py +++ b/tests/auth_tests/test_views.py @@ -68,7 +68,7 @@ def logout(self): def assertFormError(self, response, error): """Assert that error is found in response.context['form'] errors""" form_errors = list(itertools.chain(*response.context['form'].errors.values())) - self.assertIn(force_text(error), form_errors) + self.assertIn(str(error), form_errors) def assertURLEqual(self, url, expected, parse_qs=False): """ diff --git a/tests/cache/tests.py b/tests/cache/tests.py index ef77b284582e..79a5120f715d 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -41,7 +41,6 @@ patch_response_headers, patch_vary_headers, ) from django.utils.deprecation import RemovedInDjango21Warning -from django.utils.encoding import force_text from django.views.decorators.cache import cache_page from .models import Poll, expensive_calculation @@ -1789,7 +1788,7 @@ def test_cache_key_i18n_timezone(self): request = self.factory.get(self.path) # This is tightly coupled to the implementation, # but it's the most straightforward way to test the key. - tz = force_text(timezone.get_current_timezone_name(), errors='ignore') + tz = timezone.get_current_timezone_name() tz = tz.encode('ascii', 'ignore').decode('ascii').replace(' ', '_') response = HttpResponse() key = learn_cache_key(request, response) @@ -1801,7 +1800,7 @@ def test_cache_key_i18n_timezone(self): def test_cache_key_no_i18n(self): request = self.factory.get(self.path) lang = translation.get_language() - tz = force_text(timezone.get_current_timezone_name(), errors='ignore') + tz = timezone.get_current_timezone_name() tz = tz.encode('ascii', 'ignore').decode('ascii').replace(' ', '_') response = HttpResponse() key = learn_cache_key(request, response) diff --git a/tests/check_framework/tests.py b/tests/check_framework/tests.py index 46e4095a380e..2128da3dc684 100644 --- a/tests/check_framework/tests.py +++ b/tests/check_framework/tests.py @@ -12,7 +12,6 @@ from django.test.utils import ( isolate_apps, override_settings, override_system_checks, ) -from django.utils.encoding import force_text from .models import SimpleModel, my_check @@ -73,39 +72,39 @@ class MessageTests(SimpleTestCase): def test_printing(self): e = Error("Message", hint="Hint", obj=DummyObj()) expected = "obj: Message\n\tHINT: Hint" - self.assertEqual(force_text(e), expected) + self.assertEqual(str(e), expected) def test_printing_no_hint(self): e = Error("Message", obj=DummyObj()) expected = "obj: Message" - self.assertEqual(force_text(e), expected) + self.assertEqual(str(e), expected) def test_printing_no_object(self): e = Error("Message", hint="Hint") expected = "?: Message\n\tHINT: Hint" - self.assertEqual(force_text(e), expected) + self.assertEqual(str(e), expected) def test_printing_with_given_id(self): e = Error("Message", hint="Hint", obj=DummyObj(), id="ID") expected = "obj: (ID) Message\n\tHINT: Hint" - self.assertEqual(force_text(e), expected) + self.assertEqual(str(e), expected) def test_printing_field_error(self): field = SimpleModel._meta.get_field('field') e = Error("Error", obj=field) expected = "check_framework.SimpleModel.field: Error" - self.assertEqual(force_text(e), expected) + self.assertEqual(str(e), expected) def test_printing_model_error(self): e = Error("Error", obj=SimpleModel) expected = "check_framework.SimpleModel: Error" - self.assertEqual(force_text(e), expected) + self.assertEqual(str(e), expected) def test_printing_manager_error(self): manager = SimpleModel.manager e = Error("Error", obj=manager) expected = "check_framework.SimpleModel.manager: Error" - self.assertEqual(force_text(e), expected) + self.assertEqual(str(e), expected) def test_equal_to_self(self): e = Error("Error", obj=SimpleModel) diff --git a/tests/contenttypes_tests/tests.py b/tests/contenttypes_tests/tests.py index eecdaa91daaa..794b1e34ef6b 100644 --- a/tests/contenttypes_tests/tests.py +++ b/tests/contenttypes_tests/tests.py @@ -16,7 +16,6 @@ SimpleTestCase, TestCase, TransactionTestCase, override_settings, ) from django.test.utils import captured_stdout, isolate_apps -from django.utils.encoding import force_text from .models import ( Article, Author, ModelWithNullFKToSite, Post, SchemeIncludedURL, @@ -134,7 +133,7 @@ class Meta: ct = ContentType.objects.get_for_model(ModelCreatedOnTheFly) self.assertEqual(ct.app_label, 'my_great_app') self.assertEqual(ct.model, 'modelcreatedonthefly') - self.assertEqual(force_text(ct), 'modelcreatedonthefly') + self.assertEqual(str(ct), 'modelcreatedonthefly') @override_settings(SILENCED_SYSTEM_CHECKS=['fields.W342']) # ForeignKey(unique=True) @@ -144,9 +143,7 @@ class GenericForeignKeyTests(SimpleTestCase): def test_str(self): class Model(models.Model): field = GenericForeignKey() - expected = "contenttypes_tests.Model.field" - actual = force_text(Model.field) - self.assertEqual(expected, actual) + self.assertEqual(str(Model.field), "contenttypes_tests.Model.field") def test_missing_content_type_field(self): class TaggedItem(models.Model): diff --git a/tests/csrf_tests/test_context_processor.py b/tests/csrf_tests/test_context_processor.py index 5db0116db0e2..62e4365cd84c 100644 --- a/tests/csrf_tests/test_context_processor.py +++ b/tests/csrf_tests/test_context_processor.py @@ -2,14 +2,13 @@ from django.middleware.csrf import _compare_salted_tokens as equivalent_tokens from django.template.context_processors import csrf from django.test import SimpleTestCase -from django.utils.encoding import force_text class TestContextProcessor(SimpleTestCase): - def test_force_text_on_token(self): + def test_force_token_to_string(self): request = HttpRequest() test_token = '1bcdefghij2bcdefghij3bcdefghij4bcdefghij5bcdefghij6bcdefghijABCD' request.META['CSRF_COOKIE'] = test_token token = csrf(request).get('csrf_token') - self.assertTrue(equivalent_tokens(force_text(token), test_token)) + self.assertTrue(equivalent_tokens(str(token), test_token)) diff --git a/tests/fixtures/tests.py b/tests/fixtures/tests.py index 89edea424e90..a25eae18a6ae 100644 --- a/tests/fixtures/tests.py +++ b/tests/fixtures/tests.py @@ -15,7 +15,6 @@ from django.core.serializers.base import ProgressBar from django.db import IntegrityError, connection from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature -from django.utils.encoding import force_text from .models import ( Article, Category, PrimaryKeyUUIDModel, ProxySpy, Spy, Tag, Visa, @@ -584,7 +583,7 @@ def test_loaddata_app_option(self): def test_loaddata_verbosity_three(self): output = StringIO() management.call_command('loaddata', 'fixture1.json', verbosity=3, stdout=output, stderr=output) - command_output = force_text(output.getvalue()) + command_output = output.getvalue() self.assertIn( "\rProcessed 1 object(s).\rProcessed 2 object(s)." "\rProcessed 3 object(s).\rProcessed 4 object(s).\n", diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py index c13fbdf5c8a2..2a1ec44f66be 100644 --- a/tests/forms_tests/tests/test_forms.py +++ b/tests/forms_tests/tests/test_forms.py @@ -20,7 +20,6 @@ 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.safestring import mark_safe @@ -3361,7 +3360,7 @@ def as_divs(self): if not self: return '' return '
    %s
    ' % ''.join( - '
    %s
    ' % force_text(e) for e in self) + '
    %s
    ' % e for e in self) class CommentForm(Form): name = CharField(max_length=50, required=False) @@ -3471,9 +3470,9 @@ class SimpleForm(Form): form = SimpleForm() self.assertTrue(hasattr(SimpleForm, '__html__')) - self.assertEqual(force_text(form), form.__html__()) + self.assertEqual(str(form), form.__html__()) self.assertTrue(hasattr(form['username'], '__html__')) - self.assertEqual(force_text(form['username']), form['username'].__html__()) + self.assertEqual(str(form['username']), form['username'].__html__()) def test_use_required_attribute_true(self): class MyForm(Form): diff --git a/tests/forms_tests/tests/test_formsets.py b/tests/forms_tests/tests/test_formsets.py index ed8331ad72d1..3c3228fafc3c 100644 --- a/tests/forms_tests/tests/test_formsets.py +++ b/tests/forms_tests/tests/test_formsets.py @@ -9,7 +9,6 @@ from django.forms.formsets import BaseFormSet, formset_factory from django.forms.utils import ErrorList from django.test import SimpleTestCase -from django.utils.encoding import force_text class Choice(Form): @@ -1251,7 +1250,7 @@ def test_formset_total_error_count_with_non_form_errors(self): def test_html_safe(self): formset = self.make_choiceformset() self.assertTrue(hasattr(formset, '__html__')) - self.assertEqual(force_text(formset), formset.__html__()) + self.assertEqual(str(formset), formset.__html__()) data = { diff --git a/tests/forms_tests/tests/test_media.py b/tests/forms_tests/tests/test_media.py index cd5cc1f8049a..72db13ef21ef 100644 --- a/tests/forms_tests/tests/test_media.py +++ b/tests/forms_tests/tests/test_media.py @@ -1,7 +1,6 @@ from django.forms import CharField, Form, Media, MultiWidget, TextInput from django.template import Context, Template from django.test import SimpleTestCase, override_settings -from django.utils.encoding import force_text @override_settings( @@ -518,4 +517,4 @@ class Media: def test_html_safe(self): media = Media(css={'all': ['/path/to/css']}, js=['/path/to/js']) self.assertTrue(hasattr(Media, '__html__')) - self.assertEqual(force_text(media), media.__html__()) + self.assertEqual(str(media), media.__html__()) diff --git a/tests/forms_tests/tests/test_utils.py b/tests/forms_tests/tests/test_utils.py index f52c1956377e..68991319e222 100644 --- a/tests/forms_tests/tests/test_utils.py +++ b/tests/forms_tests/tests/test_utils.py @@ -3,7 +3,6 @@ from django.core.exceptions import ValidationError from django.forms.utils import ErrorDict, ErrorList, flatatt from django.test import SimpleTestCase -from django.utils.encoding import force_text from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy @@ -158,9 +157,9 @@ def test_error_dict_html_safe(self): e = ErrorDict() e['username'] = 'Invalid username.' self.assertTrue(hasattr(ErrorDict, '__html__')) - self.assertEqual(force_text(e), e.__html__()) + self.assertEqual(str(e), e.__html__()) def test_error_list_html_safe(self): e = ErrorList(['Invalid username.']) self.assertTrue(hasattr(ErrorList, '__html__')) - self.assertEqual(force_text(e), e.__html__()) + self.assertEqual(str(e), e.__html__()) diff --git a/tests/i18n/test_compilation.py b/tests/i18n/test_compilation.py index ca7dfd4309d8..7d3215d4a87e 100644 --- a/tests/i18n/test_compilation.py +++ b/tests/i18n/test_compilation.py @@ -15,7 +15,6 @@ from django.test import SimpleTestCase, override_settings from django.test.utils import captured_stderr, captured_stdout from django.utils import translation -from django.utils.encoding import force_text from django.utils.translation import ugettext from .utils import RunInTmpDirMixin, copytree @@ -49,7 +48,7 @@ def test_no_write_access(self): try: call_command('compilemessages', locale=['en'], stderr=err_buffer, verbosity=0) err = err_buffer.getvalue() - self.assertIn("not writable location", force_text(err)) + self.assertIn("not writable location", err) finally: os.chmod(mo_file_en, old_mode) @@ -168,15 +167,15 @@ def test_nofuzzy_compiling(self): with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, 'locale')]): call_command('compilemessages', locale=[self.LOCALE], stdout=StringIO()) with translation.override(self.LOCALE): - self.assertEqual(ugettext('Lenin'), force_text('Ленин')) - self.assertEqual(ugettext('Vodka'), force_text('Vodka')) + self.assertEqual(ugettext('Lenin'), 'Ленин') + self.assertEqual(ugettext('Vodka'), 'Vodka') def test_fuzzy_compiling(self): with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, 'locale')]): call_command('compilemessages', locale=[self.LOCALE], fuzzy=True, stdout=StringIO()) with translation.override(self.LOCALE): - self.assertEqual(ugettext('Lenin'), force_text('Ленин')) - self.assertEqual(ugettext('Vodka'), force_text('Водка')) + self.assertEqual(ugettext('Lenin'), 'Ленин') + self.assertEqual(ugettext('Vodka'), 'Водка') class AppCompilationTest(ProjectAndAppTests): diff --git a/tests/i18n/test_extraction.py b/tests/i18n/test_extraction.py index 0adf3d0f1c18..585feda3ac4a 100644 --- a/tests/i18n/test_extraction.py +++ b/tests/i18n/test_extraction.py @@ -16,7 +16,6 @@ from django.core.management.utils import find_command from django.test import SimpleTestCase, override_settings from django.test.utils import captured_stderr, captured_stdout -from django.utils.encoding import force_text from django.utils.translation import TranslatorCommentWarning from .utils import POFileAssertionMixin, RunInTmpDirMixin, copytree @@ -56,7 +55,7 @@ def assertNotMsgId(self, msgid, s, use_quotes=True): def _assertPoLocComment(self, assert_presence, po_filename, line_number, *comment_parts): with open(po_filename, 'r') as fp: - po_contents = force_text(fp.read()) + po_contents = fp.read() if os.name == 'nt': # #: .\path\to\file.html:123 cwd_prefix = '%s%s' % (os.curdir, os.sep) @@ -82,7 +81,7 @@ def _assertPoLocComment(self, assert_presence, po_filename, line_number, *commen def _get_token_line_number(self, path, token): with open(path) as f: for line, content in enumerate(f, 1): - if token in force_text(content): + if token in content: return line self.fail("The token '%s' could not be found in %s, please check the test config" % (token, path)) @@ -182,7 +181,7 @@ def test_blocktrans_trimmed(self): management.call_command('makemessages', locale=[LOCALE], verbosity=0) self.assertTrue(os.path.exists(self.PO_FILE)) with open(self.PO_FILE, 'r') as fp: - po_contents = force_text(fp.read()) + po_contents = fp.read() # should not be trimmed self.assertNotMsgId('Text with a few line breaks.', po_contents) # should be trimmed @@ -209,8 +208,7 @@ def test_unicode_decode_error(self): shutil.copyfile('./not_utf8.sample', './not_utf8.txt') out = StringIO() management.call_command('makemessages', locale=[LOCALE], stdout=out) - self.assertIn("UnicodeDecodeError: skipped file not_utf8.txt in .", - force_text(out.getvalue())) + self.assertIn("UnicodeDecodeError: skipped file not_utf8.txt in .", out.getvalue()) def test_unicode_file_name(self): open(os.path.join(self.test_dir, 'vidéo.txt'), 'a').close() @@ -221,7 +219,7 @@ def test_extraction_warning(self): shutil.copyfile('./code.sample', './code_sample.py') out = StringIO() management.call_command('makemessages', locale=[LOCALE], stdout=out) - self.assertIn("code_sample.py:4", force_text(out.getvalue())) + self.assertIn("code_sample.py:4", out.getvalue()) def test_template_message_context_extractor(self): """ @@ -231,7 +229,7 @@ def test_template_message_context_extractor(self): management.call_command('makemessages', locale=[LOCALE], verbosity=0) self.assertTrue(os.path.exists(self.PO_FILE)) with open(self.PO_FILE, 'r') as fp: - po_contents = force_text(fp.read()) + po_contents = fp.read() # {% trans %} self.assertIn('msgctxt "Special trans context #1"', po_contents) self.assertMsgId("Translatable literal #7a", po_contents) @@ -261,7 +259,7 @@ def test_context_in_single_quotes(self): management.call_command('makemessages', locale=[LOCALE], verbosity=0) self.assertTrue(os.path.exists(self.PO_FILE)) with open(self.PO_FILE, 'r') as fp: - po_contents = force_text(fp.read()) + po_contents = fp.read() # {% trans %} self.assertIn('msgctxt "Context wrapped in double quotes"', po_contents) self.assertIn('msgctxt "Context wrapped in single quotes"', po_contents) @@ -301,7 +299,7 @@ def test_template_comments(self): # Now test .po file contents self.assertTrue(os.path.exists(self.PO_FILE)) with open(self.PO_FILE, 'r') as fp: - po_contents = force_text(fp.read()) + po_contents = fp.read() self.assertMsgId('Translatable literal #9a', po_contents) self.assertNotIn('ignored comment #1', po_contents) @@ -390,7 +388,7 @@ def test_po_file_encoding_when_updating(self): management.call_command('makemessages', locale=['pt_BR'], verbosity=0) self.assertTrue(os.path.exists(BR_PO_BASE + '.po')) with open(BR_PO_BASE + '.po', 'r', encoding='utf-8') as fp: - po_contents = force_text(fp.read()) + po_contents = fp.read() self.assertMsgStr("Größe", po_contents) @@ -492,7 +490,7 @@ def test_symlink(self): management.call_command('makemessages', locale=[LOCALE], verbosity=0, symlinks=True) self.assertTrue(os.path.exists(self.PO_FILE)) with open(self.PO_FILE, 'r') as fp: - po_contents = force_text(fp.read()) + po_contents = fp.read() self.assertMsgId('This literal should be included.', po_contents) self.assertLocationCommentPresent(self.PO_FILE, None, 'templates_symlinked', 'test.html') else: @@ -507,7 +505,7 @@ def test_copy_plural_forms(self): management.call_command('makemessages', locale=[LOCALE], verbosity=0) self.assertTrue(os.path.exists(self.PO_FILE)) with open(self.PO_FILE, 'r') as fp: - po_contents = force_text(fp.read()) + po_contents = fp.read() self.assertIn('Plural-Forms: nplurals=2; plural=(n != 1)', po_contents) def test_override_plural_forms(self): @@ -528,7 +526,7 @@ def test_trans_and_plural_blocktrans_collision(self): management.call_command('makemessages', locale=[LOCALE], extensions=['html', 'djtpl'], verbosity=0) self.assertTrue(os.path.exists(self.PO_FILE)) with open(self.PO_FILE, 'r') as fp: - po_contents = force_text(fp.read()) + po_contents = fp.read() self.assertNotIn("#-#-#-#-# django.pot (PACKAGE VERSION) #-#-#-#-#\\n", po_contents) self.assertMsgId('First `trans`, then `blocktrans` with a plural', po_contents) self.assertMsgIdPlural('Plural for a `trans` and `blocktrans` collision case', po_contents) @@ -540,7 +538,7 @@ def test_no_wrap_enabled(self): management.call_command('makemessages', locale=[LOCALE], verbosity=0, no_wrap=True) self.assertTrue(os.path.exists(self.PO_FILE)) with open(self.PO_FILE, 'r') as fp: - po_contents = force_text(fp.read()) + po_contents = fp.read() self.assertMsgId( 'This literal should also be included wrapped or not wrapped ' 'depending on the use of the --no-wrap option.', @@ -551,7 +549,7 @@ def test_no_wrap_disabled(self): management.call_command('makemessages', locale=[LOCALE], verbosity=0, no_wrap=False) self.assertTrue(os.path.exists(self.PO_FILE)) with open(self.PO_FILE, 'r') as fp: - po_contents = force_text(fp.read()) + po_contents = fp.read() self.assertMsgId( '""\n"This literal should also be included wrapped or not ' 'wrapped depending on the "\n"use of the --no-wrap option."', @@ -583,7 +581,7 @@ def test_location_comments_for_templatized_files(self): management.call_command('makemessages', locale=[LOCALE], verbosity=0) self.assertTrue(os.path.exists(self.PO_FILE)) with open(self.PO_FILE, 'r') as fp: - po_contents = force_text(fp.read()) + po_contents = fp.read() self.assertMsgId('#: templates/test.html.py', po_contents) self.assertLocationCommentNotPresent(self.PO_FILE, None, '.html.py') self.assertLocationCommentPresent(self.PO_FILE, 5, 'templates', 'test.html') @@ -695,11 +693,11 @@ def test_project_locale_paths(self): self.assertTrue(os.path.exists(app_de_locale)) with open(project_de_locale, 'r') as fp: - po_contents = force_text(fp.read()) + po_contents = fp.read() self.assertMsgId('This app has no locale directory', po_contents) self.assertMsgId('This is a project-level string', po_contents) with open(app_de_locale, 'r') as fp: - po_contents = force_text(fp.read()) + po_contents = fp.read() self.assertMsgId('This app has a locale directory', po_contents) diff --git a/tests/i18n/test_percents.py b/tests/i18n/test_percents.py index 22ea73b790e6..bf14e020f561 100644 --- a/tests/i18n/test_percents.py +++ b/tests/i18n/test_percents.py @@ -2,7 +2,6 @@ from django.template import Context, Template from django.test import SimpleTestCase, override_settings -from django.utils.encoding import force_text from django.utils.translation import activate, get_language, trans_real from .utils import POFileAssertionMixin @@ -40,7 +39,7 @@ class ExtractingStringsWithPercentSigns(POFileAssertionMixin, FrenchTestCase): def setUp(self): super(ExtractingStringsWithPercentSigns, self).setUp() with open(self.PO_FILE, 'r') as fp: - self.po_contents = force_text(fp.read()) + self.po_contents = fp.read() def test_trans_tag_with_percent_symbol_at_the_end(self): self.assertMsgId('Literal with a percent symbol at the end %%', self.po_contents) diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py index 49b1819c2651..b060f7e25bc4 100644 --- a/tests/inspectdb/tests.py +++ b/tests/inspectdb/tests.py @@ -5,7 +5,6 @@ from django.core.management import call_command from django.db import connection from django.test import TestCase, skipUnlessDBFeature -from django.utils.encoding import force_text from .models import ColumnTypes @@ -264,7 +263,7 @@ def test_introspection_errors(self): with mock.patch('django.db.backends.base.introspection.BaseDatabaseIntrospection.table_names', return_value=['nonexistent']): call_command('inspectdb', stdout=out) - output = force_text(out.getvalue()) + output = out.getvalue() self.assertIn("# Unable to inspect table 'nonexistent'", output) # The error message depends on the backend self.assertIn("# The error was:", output) diff --git a/tests/managers_regress/models.py b/tests/managers_regress/models.py index f5fd648bff3e..1c274d870412 100644 --- a/tests/managers_regress/models.py +++ b/tests/managers_regress/models.py @@ -7,7 +7,6 @@ ) from django.contrib.contenttypes.models import ContentType from django.db import models -from django.utils.encoding import force_text class OnlyFred(models.Manager): @@ -123,7 +122,7 @@ class RelatedModel(models.Model): exact = models.NullBooleanField() def __str__(self): - return force_text(self.pk) + return str(self.pk) class RelationModel(models.Model): @@ -136,4 +135,4 @@ class RelationModel(models.Model): gfk = GenericForeignKey(ct_field='gfk_ctype', fk_field='gfk_id') def __str__(self): - return force_text(self.pk) + return str(self.pk) diff --git a/tests/managers_regress/tests.py b/tests/managers_regress/tests.py index 1b3e0a1635ab..a05a24e59764 100644 --- a/tests/managers_regress/tests.py +++ b/tests/managers_regress/tests.py @@ -2,7 +2,6 @@ from django.template import Context, Template from django.test import TestCase, override_settings from django.test.utils import isolate_apps -from django.utils.encoding import force_text from .models import ( AbstractBase1, AbstractBase2, AbstractBase3, Child1, Child2, Child3, @@ -148,7 +147,7 @@ def test_regress_3871(self): self.assertEqual( t.render(Context({'related': related})), - ''.join([force_text(relation.pk)] * 3), + ''.join([str(relation.pk)] * 3), ) def test_field_can_be_called_exact(self): diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index f5d7887c355e..cacbcab74387 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -16,7 +16,6 @@ ) from django.db.migrations.recorder import MigrationRecorder from django.test import override_settings -from django.utils.encoding import force_text from .models import UnicodeModel, UnserializableModel from .routers import TestRouter @@ -649,7 +648,7 @@ def test_files_content(self): self.assertTrue(os.path.exists(init_file)) with open(init_file, 'r') as fp: - content = force_text(fp.read()) + content = fp.read() self.assertEqual(content, '') # Check for existing 0001_initial.py file in migration folder diff --git a/tests/migrations/test_graph.py b/tests/migrations/test_graph.py index 26a5f1832821..d19839405a9c 100644 --- a/tests/migrations/test_graph.py +++ b/tests/migrations/test_graph.py @@ -5,7 +5,6 @@ ) from django.db.migrations.graph import RECURSION_DEPTH_WARNING, MigrationGraph from django.test import SimpleTestCase -from django.utils.encoding import force_text class GraphTests(SimpleTestCase): @@ -395,7 +394,7 @@ def test_infinite_loop(self): def test_stringify(self): graph = MigrationGraph() - self.assertEqual(force_text(graph), "Graph: 0 nodes, 0 edges") + self.assertEqual(str(graph), "Graph: 0 nodes, 0 edges") graph.add_node(("app_a", "0001"), None) graph.add_node(("app_a", "0002"), None) @@ -406,5 +405,5 @@ def test_stringify(self): graph.add_dependency("app_a.0003", ("app_a", "0003"), ("app_a", "0002")) graph.add_dependency("app_a.0003", ("app_a", "0003"), ("app_b", "0002")) - self.assertEqual(force_text(graph), "Graph: 5 nodes, 3 edges") + self.assertEqual(str(graph), "Graph: 5 nodes, 3 edges") self.assertEqual(repr(graph), "") diff --git a/tests/prefetch_related/tests.py b/tests/prefetch_related/tests.py index 33456069aa1b..f59a030bc786 100644 --- a/tests/prefetch_related/tests.py +++ b/tests/prefetch_related/tests.py @@ -5,7 +5,6 @@ from django.db.models.query import get_prefetcher from django.test import TestCase, override_settings from django.test.utils import CaptureQueriesContext -from django.utils.encoding import force_text from .models import ( Author, Author2, AuthorAddress, AuthorWithAge, Bio, Book, Bookmark, @@ -1260,7 +1259,7 @@ def setUp(self): def test_bug(self): prefetcher = get_prefetcher(self.rooms[0], 'house', 'house')[0] queryset = prefetcher.get_prefetch_queryset(list(Room.objects.all()))[0] - self.assertNotIn(' JOIN ', force_text(queryset.query)) + self.assertNotIn(' JOIN ', str(queryset.query)) class Ticket25546Tests(TestCase): diff --git a/tests/sessions_tests/tests.py b/tests/sessions_tests/tests.py index 177903b18fe5..54b8ac53a579 100644 --- a/tests/sessions_tests/tests.py +++ b/tests/sessions_tests/tests.py @@ -33,7 +33,6 @@ ) from django.test.utils import patch_logger from django.utils import timezone -from django.utils.encoding import force_text from .models import SessionStore as CustomDatabaseSession @@ -388,7 +387,7 @@ def test_session_str(self): session_key = self.session.session_key s = self.model.objects.get(session_key=session_key) - self.assertEqual(force_text(s), session_key) + self.assertEqual(str(s), session_key) def test_session_get_decoded(self): """ diff --git a/tests/staticfiles_tests/cases.py b/tests/staticfiles_tests/cases.py index 537fbac6a05d..2305b3452776 100644 --- a/tests/staticfiles_tests/cases.py +++ b/tests/staticfiles_tests/cases.py @@ -7,7 +7,6 @@ from django.core.management import call_command from django.template import Context, Template from django.test import SimpleTestCase, override_settings -from django.utils.encoding import force_text from .settings import TEST_SETTINGS @@ -20,7 +19,7 @@ class BaseStaticFilesMixin: def assertFileContains(self, filepath, text): self.assertIn( text, - self._get_file(force_text(filepath)), + self._get_file(filepath), "'%s' not in '%s'" % (text, filepath), ) diff --git a/tests/staticfiles_tests/test_management.py b/tests/staticfiles_tests/test_management.py index a9aeb68c3a69..5e1f49a5d300 100644 --- a/tests/staticfiles_tests/test_management.py +++ b/tests/staticfiles_tests/test_management.py @@ -18,7 +18,6 @@ from django.test.utils import extend_sys_path from django.utils import timezone from django.utils._os import symlinks_supported -from django.utils.encoding import force_text from django.utils.functional import empty from .cases import CollectionTestCase, StaticFilesTestCase, TestDefaults @@ -41,7 +40,7 @@ class TestFindStatic(TestDefaults, CollectionTestCase): """ def _get_file(self, filepath): path = call_command('findstatic', filepath, all=False, verbosity=0, stdout=StringIO()) - with codecs.open(force_text(path), "r", "utf-8") as f: + with codecs.open(path, "r", "utf-8") as f: return f.read() def test_all_files(self): @@ -51,8 +50,8 @@ def test_all_files(self): result = call_command('findstatic', 'test/file.txt', verbosity=1, stdout=StringIO()) lines = [l.strip() for l in result.split('\n')] self.assertEqual(len(lines), 3) # three because there is also the "Found here" line - self.assertIn('project', force_text(lines[1])) - self.assertIn('apps', force_text(lines[2])) + self.assertIn('project', lines[1]) + self.assertIn('apps', lines[2]) def test_all_files_less_verbose(self): """ @@ -61,8 +60,8 @@ def test_all_files_less_verbose(self): result = call_command('findstatic', 'test/file.txt', verbosity=0, stdout=StringIO()) lines = [l.strip() for l in result.split('\n')] self.assertEqual(len(lines), 2) - self.assertIn('project', force_text(lines[0])) - self.assertIn('apps', force_text(lines[1])) + self.assertIn('project', lines[0]) + self.assertIn('apps', lines[1]) def test_all_files_more_verbose(self): """ @@ -71,10 +70,10 @@ def test_all_files_more_verbose(self): """ result = call_command('findstatic', 'test/file.txt', verbosity=2, stdout=StringIO()) lines = [l.strip() for l in result.split('\n')] - self.assertIn('project', force_text(lines[1])) - self.assertIn('apps', force_text(lines[2])) - self.assertIn("Looking in the following locations:", force_text(lines[3])) - searched_locations = ', '.join(force_text(x) for x in lines[4:]) + self.assertIn('project', lines[1]) + self.assertIn('apps', lines[2]) + self.assertIn("Looking in the following locations:", lines[3]) + searched_locations = ', '.join(lines[4:]) # AppDirectoriesFinder searched locations self.assertIn(os.path.join('staticfiles_tests', 'apps', 'test', 'static'), searched_locations) self.assertIn(os.path.join('staticfiles_tests', 'apps', 'no_label', 'static'), searched_locations) @@ -195,7 +194,7 @@ def test_warning_when_clearing_staticdir(self): with mock.patch('builtins.input', side_effect=self.mock_input(stdout)): call_command('collectstatic', interactive=True, clear=True, stdout=stdout) - output = force_text(stdout.getvalue()) + output = stdout.getvalue() self.assertNotIn(self.overwrite_warning_msg, output) self.assertIn(self.delete_warning_msg, output) @@ -204,7 +203,7 @@ def test_warning_when_overwriting_files_in_staticdir(self): self.run_collectstatic() with mock.patch('builtins.input', side_effect=self.mock_input(stdout)): call_command('collectstatic', interactive=True, stdout=stdout) - output = force_text(stdout.getvalue()) + output = stdout.getvalue() self.assertIn(self.overwrite_warning_msg, output) self.assertNotIn(self.delete_warning_msg, output) @@ -212,7 +211,7 @@ def test_no_warning_when_staticdir_does_not_exist(self): stdout = StringIO() shutil.rmtree(settings.STATIC_ROOT) call_command('collectstatic', interactive=True, stdout=stdout) - output = force_text(stdout.getvalue()) + output = stdout.getvalue() self.assertNotIn(self.overwrite_warning_msg, output) self.assertNotIn(self.delete_warning_msg, output) self.assertIn(self.files_copied_msg, output) @@ -223,7 +222,7 @@ def test_no_warning_for_empty_staticdir(self): with override_settings(STATIC_ROOT=static_dir): call_command('collectstatic', interactive=True, stdout=stdout) shutil.rmtree(static_dir) - output = force_text(stdout.getvalue()) + output = stdout.getvalue() self.assertNotIn(self.overwrite_warning_msg, output) self.assertNotIn(self.delete_warning_msg, output) self.assertIn(self.files_copied_msg, output) @@ -349,7 +348,7 @@ def _collectstatic_output(self, **kwargs): """ out = StringIO() call_command('collectstatic', interactive=False, verbosity=3, stdout=out, **kwargs) - return force_text(out.getvalue()) + return out.getvalue() def test_no_warning(self): """ @@ -409,7 +408,7 @@ def test_skips_newer_files_in_remote_storage(self): """ stdout = StringIO() self.run_collectstatic(stdout=stdout, verbosity=2) - output = force_text(stdout.getvalue()) + output = stdout.getvalue() self.assertIn("Skipping 'test.txt' (not modified)", output) diff --git a/tests/staticfiles_tests/test_storage.py b/tests/staticfiles_tests/test_storage.py index c72100ccb193..2bbe91250744 100644 --- a/tests/staticfiles_tests/test_storage.py +++ b/tests/staticfiles_tests/test_storage.py @@ -12,7 +12,6 @@ from django.core.cache.backends.base import BaseCache from django.core.management import call_command from django.test import override_settings -from django.utils.encoding import force_text from .cases import CollectionTestCase from .settings import TEST_ROOT @@ -380,7 +379,7 @@ def test_loaded_cache(self): manifest_content = storage.staticfiles_storage.read_manifest() self.assertIn( '"version": "%s"' % storage.staticfiles_storage.manifest_version, - force_text(manifest_content) + manifest_content ) def test_parse_cache(self): diff --git a/tests/template_tests/filter_tests/test_slugify.py b/tests/template_tests/filter_tests/test_slugify.py index cb23e9b320e9..b1d617f5bc63 100644 --- a/tests/template_tests/filter_tests/test_slugify.py +++ b/tests/template_tests/filter_tests/test_slugify.py @@ -1,6 +1,5 @@ from django.template.defaultfilters import slugify from django.test import SimpleTestCase -from django.utils.encoding import force_text from django.utils.functional import lazy from django.utils.safestring import mark_safe @@ -42,7 +41,7 @@ def test_non_string_input(self): self.assertEqual(slugify(123), '123') def test_slugify_lazy_string(self): - lazy_str = lazy(lambda string: force_text(string), str) + lazy_str = lazy(lambda string: string, str) self.assertEqual( slugify(lazy_str(' Jack & Jill like numbers 1,2,3 and 4 and silly characters ?%.$!/')), 'jack-jill-like-numbers-123-and-4-and-silly-characters', diff --git a/tests/utils_tests/test_encoding.py b/tests/utils_tests/test_encoding.py index 963d0a9a1641..2efdd24ff8d4 100644 --- a/tests/utils_tests/test_encoding.py +++ b/tests/utils_tests/test_encoding.py @@ -24,7 +24,7 @@ def __str__(self): def test_force_text_lazy(self): s = SimpleLazyObject(lambda: 'x') - self.assertTrue(issubclass(type(force_text(s)), str)) + self.assertTrue(type(force_text(s)), str) def test_force_bytes_exception(self): """ diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py index c2a64699cb1b..3d4a6508a1de 100644 --- a/tests/utils_tests/test_html.py +++ b/tests/utils_tests/test_html.py @@ -3,7 +3,6 @@ from django.test import SimpleTestCase from django.utils import html, safestring -from django.utils.encoding import force_text from django.utils.functional import lazystr @@ -99,7 +98,7 @@ def test_strip_tags(self): for filename in ('strip_tags1.html', 'strip_tags2.txt'): path = os.path.join(os.path.dirname(__file__), 'files', filename) with open(path, 'r') as fp: - content = force_text(fp.read()) + content = fp.read() start = datetime.now() stripped = html.strip_tags(content) elapsed = datetime.now() - start @@ -173,7 +172,7 @@ def __str__(self): html_obj = HtmlClass() self.assertTrue(hasattr(HtmlClass, '__html__')) self.assertTrue(hasattr(html_obj, '__html__')) - self.assertEqual(force_text(html_obj), html_obj.__html__()) + self.assertEqual(str(html_obj), html_obj.__html__()) def test_html_safe_subclass(self): class BaseClass: @@ -191,7 +190,7 @@ def __str__(self): return 'some html safe content' subclass_obj = Subclass() - self.assertEqual(force_text(subclass_obj), subclass_obj.__html__()) + self.assertEqual(str(subclass_obj), subclass_obj.__html__()) def test_html_safe_defines_html_error(self): msg = "can't apply @html_safe to HtmlClass because it defines __html__()." diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py index a3938ce8489b..dcec795f6825 100644 --- a/tests/view_tests/tests/test_debug.py +++ b/tests/view_tests/tests/test_debug.py @@ -14,7 +14,7 @@ from django.test import RequestFactory, SimpleTestCase, override_settings from django.test.utils import LoggingCaptureMixin, patch_logger from django.urls import reverse -from django.utils.encoding import force_bytes, force_text +from django.utils.encoding import force_bytes from django.utils.functional import SimpleLazyObject from django.views.debug import ( CLEANSED_SUBSTITUTE, CallableSettingWrapper, ExceptionReporter, @@ -740,14 +740,14 @@ def verify_unsafe_email(self, view, check_for_POST_params=True): email = mail.outbox[0] # Frames vars are never shown in plain text email reports. - body_plain = force_text(email.body) + body_plain = str(email.body) self.assertNotIn('cooked_eggs', body_plain) self.assertNotIn('scrambled', body_plain) self.assertNotIn('sauce', body_plain) self.assertNotIn('worcestershire', body_plain) # Frames vars are shown in html email reports. - body_html = force_text(email.alternatives[0][0]) + body_html = str(email.alternatives[0][0]) self.assertIn('cooked_eggs', body_html) self.assertIn('scrambled', body_html) self.assertIn('sauce', body_html) @@ -773,14 +773,14 @@ def verify_safe_email(self, view, check_for_POST_params=True): email = mail.outbox[0] # Frames vars are never shown in plain text email reports. - body_plain = force_text(email.body) + body_plain = str(email.body) self.assertNotIn('cooked_eggs', body_plain) self.assertNotIn('scrambled', body_plain) self.assertNotIn('sauce', body_plain) self.assertNotIn('worcestershire', body_plain) # Frames vars are shown in html email reports. - body_html = force_text(email.alternatives[0][0]) + body_html = str(email.alternatives[0][0]) self.assertIn('cooked_eggs', body_html) self.assertIn('scrambled', body_html) self.assertIn('sauce', body_html) @@ -812,7 +812,7 @@ def verify_paranoid_email(self, view): self.assertEqual(len(mail.outbox), 1) email = mail.outbox[0] # Frames vars are never shown in plain text email reports. - body = force_text(email.body) + body = str(email.body) self.assertNotIn('cooked_eggs', body) self.assertNotIn('scrambled', body) self.assertNotIn('sauce', body) From 5890d6ab03ebc7dac46ce7d9540b5768785caa34 Mon Sep 17 00:00:00 2001 From: Paolo Melchiorre Date: Wed, 25 Jan 2017 13:46:18 +0100 Subject: [PATCH 0114/3180] Fixed typo in docs/ref/models/expressions.txt. --- docs/ref/models/expressions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ref/models/expressions.txt b/docs/ref/models/expressions.txt index 4ba63ba92877..f53f791ffcab 100644 --- a/docs/ref/models/expressions.txt +++ b/docs/ref/models/expressions.txt @@ -551,7 +551,7 @@ within the last day:: ... post=OuterRef('pk'), ... created_at__gte=one_day_ago, ... ) - >>> Post.objects.annotate(recent_comment=Exists(recent_comments) + >>> Post.objects.annotate(recent_comment=Exists(recent_comments)) On PostgreSQL, the SQL looks like: From ebf34c3cdcd2c75349c60a064427ac255958bf9b Mon Sep 17 00:00:00 2001 From: Mads Jensen Date: Wed, 25 Jan 2017 15:14:05 +0100 Subject: [PATCH 0115/3180] Removed unused variables that are overwritten. --- django/contrib/admindocs/views.py | 1 - django/core/validators.py | 1 - django/db/backends/mysql/creation.py | 2 +- django/db/backends/postgresql/creation.py | 2 +- django/db/models/sql/compiler.py | 1 - django/http/multipartparser.py | 4 ---- django/template/base.py | 2 +- django/utils/dateformat.py | 1 - django/utils/ipv6.py | 1 - tests/bulk_create/tests.py | 2 -- tests/migrations/test_base.py | 2 +- tests/urlpatterns_reverse/tests.py | 1 - 12 files changed, 4 insertions(+), 16 deletions(-) diff --git a/django/contrib/admindocs/views.py b/django/contrib/admindocs/views.py index 4a8e1eb59901..f049c5f36763 100644 --- a/django/contrib/admindocs/views.py +++ b/django/contrib/admindocs/views.py @@ -296,7 +296,6 @@ def get_context_data(self, **kwargs): }) else: arguments = get_func_full_args(func) - print_arguments = arguments # Join arguments with ', ' and in case of default value, # join it with '='. Use repr() so that strings will be # correctly displayed. diff --git a/django/core/validators.py b/django/core/validators.py index b3b76f25f9ac..1dc0f2fbcd2d 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -140,7 +140,6 @@ def __call__(self, value): validate_ipv6_address(potential_ip) except ValidationError: raise ValidationError(self.message, code=self.code) - url = value # The maximum length of a full host name is 253 characters per RFC 1034 # section 3.1. It's defined to be 255 bytes or less, but this includes diff --git a/django/db/backends/mysql/creation.py b/django/db/backends/mysql/creation.py index ae4370935a27..c53b9f83353d 100644 --- a/django/db/backends/mysql/creation.py +++ b/django/db/backends/mysql/creation.py @@ -25,7 +25,7 @@ def _clone_test_db(self, number, verbosity, keepdb=False): with self._nodb_connection.cursor() as cursor: try: cursor.execute("CREATE DATABASE %s" % qn(target_database_name)) - except Exception as e: + except Exception: if keepdb: return try: diff --git a/django/db/backends/postgresql/creation.py b/django/db/backends/postgresql/creation.py index 2f26b14e5227..c47bb534f2d5 100644 --- a/django/db/backends/postgresql/creation.py +++ b/django/db/backends/postgresql/creation.py @@ -41,7 +41,7 @@ def _clone_test_db(self, number, verbosity, keepdb=False): with self._nodb_connection.cursor() as cursor: try: cursor.execute(creation_sql) - except Exception as e: + except Exception: if keepdb: return try: diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 5e5984dfb35b..560ea2ef6dc7 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -823,7 +823,6 @@ def results_iter(self, results=None): """ Returns an iterator over the results from executing this query. """ - converters = None if results is None: results = self.execute_sql(MULTI) fields = [s[0] for s in self.select[0:self.col_count]] diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index 6a0ff2c86c91..adb4e08dbec4 100644 --- a/django/http/multipartparser.py +++ b/django/http/multipartparser.py @@ -571,15 +571,11 @@ def exhaust(stream_or_iterable): Raise a MultiPartParserError if the argument is not a stream or an iterable. """ - iterator = None try: iterator = iter(stream_or_iterable) except TypeError: iterator = ChunkIter(stream_or_iterable, 16384) - if iterator is None: - raise MultiPartParserError('multipartparser.exhaust() was passed a non-iterable or stream parameter') - for __ in iterator: pass diff --git a/django/template/base.py b/django/template/base.py index b4d129c0a45a..0c796ceaf2bb 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -853,7 +853,7 @@ def _resolve_lookup(self, context): if isinstance(current, BaseContext) and getattr(type(current), bit): raise AttributeError current = getattr(current, bit) - except (TypeError, AttributeError) as e: + except (TypeError, AttributeError): # Reraise if the exception was raised by a @property if not isinstance(current, BaseContext) and bit in dir(current): raise diff --git a/django/utils/dateformat.py b/django/utils/dateformat.py index f55b97c2edf3..67968e5d732c 100644 --- a/django/utils/dateformat.py +++ b/django/utils/dateformat.py @@ -324,7 +324,6 @@ def w(self): def W(self): "ISO-8601 week number of year, weeks starting on Monday" # Algorithm from http://www.personal.ecu.edu/mccartyr/ISOwdALG.txt - week_number = None jan1_weekday = self.data.replace(month=1, day=1).weekday() + 1 weekday = self.data.weekday() + 1 day_of_year = self.z() diff --git a/django/utils/ipv6.py b/django/utils/ipv6.py index a1e63be727ea..93a1bfd1b2de 100644 --- a/django/utils/ipv6.py +++ b/django/utils/ipv6.py @@ -227,7 +227,6 @@ def _explode_shorthand_ip_string(ip_str): # We've already got a longhand ip_str. return ip_str - new_ip = [] hextet = ip_str.split('::') # If there is a ::, we need to expand it with zeroes diff --git a/tests/bulk_create/tests.py b/tests/bulk_create/tests.py index 65d0f9ba8c6d..97a8f821171c 100644 --- a/tests/bulk_create/tests.py +++ b/tests/bulk_create/tests.py @@ -206,7 +206,6 @@ def test_bulk_insert_expressions(self): @skipUnlessDBFeature('can_return_ids_from_bulk_insert') def test_set_pk_and_insert_single_item(self): - countries = [] with self.assertNumQueries(1): countries = Country.objects.bulk_create([self.data[0]]) self.assertEqual(len(countries), 1) @@ -214,7 +213,6 @@ def test_set_pk_and_insert_single_item(self): @skipUnlessDBFeature('can_return_ids_from_bulk_insert') def test_set_pk_and_query_efficiency(self): - countries = [] with self.assertNumQueries(1): countries = Country.objects.bulk_create(self.data) self.assertEqual(len(countries), 4) diff --git a/tests/migrations/test_base.py b/tests/migrations/test_base.py index 7f7f96c013c5..007c7c0ba90d 100644 --- a/tests/migrations/test_base.py +++ b/tests/migrations/test_base.py @@ -77,7 +77,7 @@ def assertFKExists(self, table, columns, to, value=True, using='default'): ), ) - def assertFKNotExists(self, table, columns, to, value=True): + def assertFKNotExists(self, table, columns, to): return self.assertFKExists(table, columns, to, False) @contextmanager diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py index a1241b2fabd2..b2d7e1ad3836 100644 --- a/tests/urlpatterns_reverse/tests.py +++ b/tests/urlpatterns_reverse/tests.py @@ -426,7 +426,6 @@ def test_404_tried_urls_have_names(self): e = cm.exception # make sure we at least matched the root ('/') url resolver: self.assertIn('tried', e.args[0]) - tried = e.args[0]['tried'] self.assertEqual( len(e.args[0]['tried']), len(url_types_names), From 3f0c4fe18fe9850bb2f56be138012add4b54873d Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Wed, 25 Jan 2017 09:23:04 -0500 Subject: [PATCH 0116/3180] Refs #25175 -- Deprecated db.backends.postgresql_psycopg2 module. --- django/db/backends/postgresql_psycopg2/__init__.py | 9 +++++++++ docs/internals/deprecation.txt | 2 ++ docs/releases/2.0.txt | 7 ++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/django/db/backends/postgresql_psycopg2/__init__.py b/django/db/backends/postgresql_psycopg2/__init__.py index e69de29bb2d1..db97c5bcc9d4 100644 --- a/django/db/backends/postgresql_psycopg2/__init__.py +++ b/django/db/backends/postgresql_psycopg2/__init__.py @@ -0,0 +1,9 @@ +import warnings + +from django.utils.deprecation import RemovedInDjango30Warning + +warnings.warn( + "The django.db.backends.postgresql_psycopg2 module is deprecated in " + "favor of django.db.backends.postgresql.", + RemovedInDjango30Warning, stacklevel=2 +) diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index eface82d4cfa..d6123b6b5352 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -15,6 +15,8 @@ about each item can often be found in the release notes of two versions prior. See the :ref:`Django 2.0 release notes` for more details on these changes. +* The ``django.db.backends.postgresql_psycopg2`` module will be removed. + .. _deprecation-removed-in-2.1: 2.1 diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index a4c4e75920ba..519b7cd9471d 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -225,7 +225,12 @@ Features deprecated in 2.0 Miscellaneous ------------- -* ... +* The ``django.db.backends.postgresql_psycopg2`` module is deprecated in favor + of ``django.db.backends.postgresql``. It's been an alias since Django 1.9. + This only affects code that imports from the module directly. The + ``DATABASES`` setting can still use + ``'django.db.backends.postgresql_psycopg2'``, though you can simplify that by + using the ``'django.db.backends.postgresql'`` name added in Django 1.9. .. _removed-features-2.0: From 632c4ffd9cb1da273303bcd8005fff216506c795 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Wed, 25 Jan 2017 10:13:08 -0500 Subject: [PATCH 0117/3180] Refs #23919 -- Replaced errno checking with PEP 3151 exceptions. --- django/contrib/sessions/backends/file.py | 12 ++++----- django/core/cache/backends/filebased.py | 21 ++++++---------- django/core/files/move.py | 4 +-- django/core/files/storage.py | 32 ++++++++++-------------- django/core/files/uploadedfile.py | 12 ++++----- django/core/management/templates.py | 9 +++---- django/template/backends/dummy.py | 15 +++++------ django/template/loaders/filesystem.py | 8 ++---- tests/cache/tests.py | 2 +- tests/file_storage/tests.py | 17 ++++++------- tests/file_uploads/tests.py | 4 +-- tests/staticfiles_tests/storage.py | 6 ++--- 12 files changed, 55 insertions(+), 87 deletions(-) diff --git a/django/contrib/sessions/backends/file.py b/django/contrib/sessions/backends/file.py index 594973ec91a1..83baa35ef29b 100644 --- a/django/contrib/sessions/backends/file.py +++ b/django/contrib/sessions/backends/file.py @@ -1,5 +1,4 @@ import datetime -import errno import logging import os import shutil @@ -133,13 +132,12 @@ def save(self, must_create=False): flags |= os.O_EXCL | os.O_CREAT fd = os.open(session_file_name, flags) os.close(fd) - - except OSError as e: - if must_create and e.errno == errno.EEXIST: - raise CreateError - if not must_create and e.errno == errno.ENOENT: + except FileNotFoundError: + if not must_create: raise UpdateError - raise + except FileExistsError: + if must_create: + raise CreateError # Write the session file without interfering with other threads # or processes. By writing to an atomically generated temporary diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py index ae5b48c054f1..896f798e9524 100644 --- a/django/core/cache/backends/filebased.py +++ b/django/core/cache/backends/filebased.py @@ -1,5 +1,4 @@ "File-based cache backend" -import errno import glob import hashlib import os @@ -34,9 +33,8 @@ def get(self, key, default=None, version=None): with open(fname, 'rb') as f: if not self._is_expired(f): return pickle.loads(zlib.decompress(f.read())) - except IOError as e: - if e.errno != errno.ENOENT: - raise + except FileNotFoundError: + pass return default def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None): @@ -64,11 +62,9 @@ def _delete(self, fname): return try: os.remove(fname) - except OSError as e: - # ENOENT can happen if the cache file is removed (by another - # process) after the os.path.exists check. - if e.errno != errno.ENOENT: - raise + except FileNotFoundError: + # The file may have been removed by another process. + pass def has_key(self, key, version=None): fname = self._key_to_file(key, version) @@ -99,11 +95,8 @@ def _createdir(self): if not os.path.exists(self._dir): try: os.makedirs(self._dir, 0o700) - except OSError as e: - if e.errno != errno.EEXIST: - raise EnvironmentError( - "Cache directory '%s' does not exist " - "and could not be created'" % self._dir) + except FileExistsError: + pass def _key_to_file(self, key, version=None): """ diff --git a/django/core/files/move.py b/django/core/files/move.py index f3972c5f984d..9e6cfe768448 100644 --- a/django/core/files/move.py +++ b/django/core/files/move.py @@ -71,10 +71,10 @@ def file_move_safe(old_file_name, new_file_name, chunk_size=1024 * 64, allow_ove try: os.remove(old_file_name) - except OSError as e: + except PermissionError as e: # Certain operating systems (Cygwin and Windows) # fail when deleting opened files, ignore it. (For the # systems where this happens, temporary files will be auto-deleted # on close anyway.) - if getattr(e, 'winerror', 0) != 32 and getattr(e, 'errno', 0) != 13: + if getattr(e, 'winerror', 0) != 32: raise diff --git a/django/core/files/storage.py b/django/core/files/storage.py index a8814ddc4855..df4db9f2e857 100644 --- a/django/core/files/storage.py +++ b/django/core/files/storage.py @@ -1,4 +1,3 @@ -import errno import os from datetime import datetime from urllib.parse import urljoin @@ -224,9 +223,6 @@ def _save(self, name, content): full_path = self.path(name) # Create any intermediate directories that do not exist. - # Note that there is a race between os.path.exists and os.makedirs: - # if os.makedirs fails with EEXIST, the directory was created - # concurrently, and we can continue normally. Refs #16082. directory = os.path.dirname(full_path) if not os.path.exists(directory): try: @@ -240,9 +236,11 @@ def _save(self, name, content): os.umask(old_umask) else: os.makedirs(directory) - except OSError as e: - if e.errno != errno.EEXIST: - raise + except FileNotFoundError: + # There's a race between os.path.exists() and os.makedirs(). + # If os.makedirs() fails with FileNotFoundError, the directory + # was created concurrently. + pass if not os.path.isdir(directory): raise IOError("%s exists and is not a directory." % directory) @@ -280,13 +278,10 @@ def _save(self, name, content): _file.close() else: os.close(fd) - except OSError as e: - if e.errno == errno.EEXIST: - # Ooops, the file exists. We need a new file name. - name = self.get_available_name(name) - full_path = self.path(name) - else: - raise + except FileExistsError: + # A new name is needed if the file exists. + name = self.get_available_name(name) + full_path = self.path(name) else: # OK, the file save worked. Break out of the loop. break @@ -301,13 +296,12 @@ def delete(self, name): assert name, "The name argument is not allowed to be empty." name = self.path(name) # If the file exists, delete it from the filesystem. - # If os.remove() fails with ENOENT, the file may have been removed - # concurrently, and it's safe to continue normally. try: os.remove(name) - except OSError as e: - if e.errno != errno.ENOENT: - raise + except FileNotFoundError: + # If os.remove() fails with FileNotFoundError, the file may have + # been removed concurrently. + pass def exists(self, name): return os.path.exists(self.path(name)) diff --git a/django/core/files/uploadedfile.py b/django/core/files/uploadedfile.py index aa1038ae783e..f5ab68f0fc23 100644 --- a/django/core/files/uploadedfile.py +++ b/django/core/files/uploadedfile.py @@ -2,7 +2,6 @@ Classes representing uploaded files. """ -import errno import os from io import BytesIO @@ -71,12 +70,11 @@ def temporary_file_path(self): def close(self): try: return self.file.close() - except OSError as e: - if e.errno != errno.ENOENT: - # Means the file was moved or deleted before the tempfile - # could unlink it. Still sets self.file.close_called and - # calls self.file.file.close() before the exception - raise + except FileNotFoundError: + # The file was moved or deleted before the tempfile could unlink + # it. Still sets self.file.close_called and calls + # self.file.file.close() before the exception. + pass class InMemoryUploadedFile(UploadedFile): diff --git a/django/core/management/templates.py b/django/core/management/templates.py index a53303ae3806..772f20b93ff5 100644 --- a/django/core/management/templates.py +++ b/django/core/management/templates.py @@ -1,5 +1,4 @@ import cgi -import errno import mimetypes import os import posixpath @@ -76,12 +75,10 @@ def handle(self, app_or_project, name, target=None, **options): top_dir = path.join(os.getcwd(), name) try: os.makedirs(top_dir) + except FileExistsError: + raise CommandError("'%s' already exists" % top_dir) except OSError as e: - if e.errno == errno.EEXIST: - message = "'%s' already exists" % top_dir - else: - message = e - raise CommandError(message) + raise CommandError(e) else: top_dir = os.path.abspath(path.expanduser(target)) if not os.path.exists(top_dir): diff --git a/django/template/backends/dummy.py b/django/template/backends/dummy.py index ce658ec76447..992465cd02ff 100644 --- a/django/template/backends/dummy.py +++ b/django/template/backends/dummy.py @@ -1,4 +1,3 @@ -import errno import string from django.conf import settings @@ -31,14 +30,12 @@ def get_template(self, template_name): try: with open(template_file, encoding=settings.FILE_CHARSET) as fp: template_code = fp.read() - except IOError as e: - if e.errno == errno.ENOENT: - tried.append(( - Origin(template_file, template_name, self), - 'Source does not exist', - )) - continue - raise + except FileNotFoundError: + tried.append(( + Origin(template_file, template_name, self), + 'Source does not exist', + )) + continue return Template(template_code) diff --git a/django/template/loaders/filesystem.py b/django/template/loaders/filesystem.py index 658e70214388..e3dda299b3b6 100644 --- a/django/template/loaders/filesystem.py +++ b/django/template/loaders/filesystem.py @@ -2,8 +2,6 @@ Wrapper for loading templates from the filesystem. """ -import errno - from django.core.exceptions import SuspiciousFileOperation from django.template import Origin, TemplateDoesNotExist from django.utils._os import safe_join @@ -24,10 +22,8 @@ def get_contents(self, origin): try: with open(origin.name, encoding=self.engine.file_charset) as fp: return fp.read() - except IOError as e: - if e.errno == errno.ENOENT: - raise TemplateDoesNotExist(origin) - raise + except FileNotFoundError: + raise TemplateDoesNotExist(origin) def get_template_sources(self, template_name): """ diff --git a/tests/cache/tests.py b/tests/cache/tests.py index 79a5120f715d..7c61837ab0be 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -1360,7 +1360,7 @@ def test_get_ignores_enoent(self): # Returns the default instead of erroring. self.assertEqual(cache.get('foo', 'baz'), 'baz') - def test_get_does_not_ignore_non_enoent_errno_values(self): + def test_get_does_not_ignore_non_filenotfound_exceptions(self): with mock.patch('builtins.open', side_effect=IOError): with self.assertRaises(IOError): cache.get('foo') diff --git a/tests/file_storage/tests.py b/tests/file_storage/tests.py index d33ca67c337b..ba77622067ae 100644 --- a/tests/file_storage/tests.py +++ b/tests/file_storage/tests.py @@ -1,4 +1,3 @@ -import errno import os import shutil import sys @@ -416,9 +415,9 @@ def fake_makedirs(path): real_makedirs(path) elif path == os.path.join(self.temp_dir, 'raced'): real_makedirs(path) - raise OSError(errno.EEXIST, 'simulated EEXIST') + raise FileNotFoundError() elif path == os.path.join(self.temp_dir, 'error'): - raise OSError(errno.EACCES, 'simulated EACCES') + raise FileExistsError() else: self.fail('unexpected argument %r' % path) @@ -433,8 +432,8 @@ def fake_makedirs(path): with self.storage.open('raced/test.file') as f: self.assertEqual(f.read(), b'saved with race') - # OSErrors aside from EEXIST are still raised. - with self.assertRaises(OSError): + # Exceptions aside from FileNotFoundError are raised. + with self.assertRaises(FileExistsError): self.storage.save('error/test.file', ContentFile('not saved')) finally: os.makedirs = real_makedirs @@ -452,9 +451,9 @@ def fake_remove(path): real_remove(path) elif path == os.path.join(self.temp_dir, 'raced.file'): real_remove(path) - raise OSError(errno.ENOENT, 'simulated ENOENT') + raise FileNotFoundError() elif path == os.path.join(self.temp_dir, 'error.file'): - raise OSError(errno.EACCES, 'simulated EACCES') + raise PermissionError() else: self.fail('unexpected argument %r' % path) @@ -469,9 +468,9 @@ def fake_remove(path): self.storage.delete('raced.file') self.assertFalse(self.storage.exists('normal.file')) - # OSErrors aside from ENOENT are still raised. + # Exceptions aside from FileNotFoundError are raised. self.storage.save('error.file', ContentFile('delete with error')) - with self.assertRaises(OSError): + with self.assertRaises(PermissionError): self.storage.delete('error.file') finally: os.remove = real_remove diff --git a/tests/file_uploads/tests.py b/tests/file_uploads/tests.py index c7315ae14216..827083412e76 100644 --- a/tests/file_uploads/tests.py +++ b/tests/file_uploads/tests.py @@ -1,5 +1,4 @@ import base64 -import errno import hashlib import json import os @@ -564,9 +563,8 @@ def test_readonly_root(self): """Permission errors are not swallowed""" os.chmod(MEDIA_ROOT, 0o500) self.addCleanup(os.chmod, MEDIA_ROOT, 0o700) - with self.assertRaises(OSError) as cm: + with self.assertRaises(PermissionError): self.obj.testfile.save('foo.txt', SimpleUploadedFile('foo.txt', b'x'), save=False) - self.assertEqual(cm.exception.errno, errno.EACCES) def test_not_a_directory(self): """The correct IOError is raised when the upload directory name exists but isn't a directory""" diff --git a/tests/staticfiles_tests/storage.py b/tests/staticfiles_tests/storage.py index 79e6245f5967..7a1f72c1303e 100644 --- a/tests/staticfiles_tests/storage.py +++ b/tests/staticfiles_tests/storage.py @@ -1,4 +1,3 @@ -import errno import os from datetime import datetime, timedelta @@ -51,9 +50,8 @@ def delete(self, name): name = self._path(name) try: os.remove(name) - except OSError as e: - if e.errno != errno.ENOENT: - raise + except FileNotFoundError: + pass def path(self, name): raise NotImplementedError From 2d96c027f5eb32c2c09bd57df2240ae1d343b98e Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Wed, 25 Jan 2017 10:16:10 -0500 Subject: [PATCH 0118/3180] Refs #23919 -- Removed obsolete MySQLdb references. --- django/db/backends/mysql/base.py | 23 +++-------- django/db/backends/mysql/features.py | 6 +-- docs/ref/databases.txt | 62 +++++----------------------- docs/ref/models/fields.txt | 14 ------- 4 files changed, 17 insertions(+), 88 deletions(-) diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 76a4313a721e..2f20b727edff 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -16,7 +16,7 @@ except ImportError as err: raise ImproperlyConfigured( 'Error loading MySQLdb module.\n' - 'Did you install mysqlclient or MySQL-python?' + 'Did you install mysqlclient?' ) from err from MySQLdb.constants import CLIENT, FIELD_TYPE # isort:skip @@ -31,18 +31,14 @@ from .schema import DatabaseSchemaEditor # isort:skip from .validation import DatabaseValidation # isort:skip -# We want version (1, 2, 1, 'final', 2) or later. We can't just use -# lexicographic ordering in this check because then (1, 2, 1, 'gamma') -# inadvertently passes the version test. version = Database.version_info -if (version < (1, 2, 1) or ( - version[:3] == (1, 2, 1) and (len(version) < 5 or version[3] != 'final' or version[4] < 2))): - raise ImproperlyConfigured("MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__) +if version < (1, 3, 3): + raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__) -# MySQLdb-1.2.1 returns TIME columns as timedelta -- they are more like -# timedelta in terms of actual behavior as they are signed and include days -- -# and Django expects time. +# MySQLdb returns TIME columns as timedelta -- they are more like timedelta in +# terms of actual behavior as they are signed and include days -- and Django +# expects time. django_conversions = conversions.copy() django_conversions.update({ FIELD_TYPE.TIME: backend_utils.typecast_time, @@ -53,13 +49,6 @@ server_version_re = re.compile(r'(\d{1,2})\.(\d{1,2})\.(\d{1,2})') -# MySQLdb-1.2.1 and newer automatically makes use of SHOW WARNINGS on -# MySQL-4.1 and newer, so the MysqlDebugWrapper is unnecessary. Since the -# point is to raise Warnings as exceptions, this can be done with the Python -# warning module, and this is setup when the connection is created, and the -# standard backend_utils.CursorDebugWrapper can be used. Also, using sql_mode -# TRADITIONAL will automatically cause most warnings to be treated as errors. - class CursorWrapper: """ A thin wrapper around MySQLdb's normal cursor class so that we can catch diff --git a/django/db/backends/mysql/features.py b/django/db/backends/mysql/features.py index 412887793c84..89cb2c00db68 100644 --- a/django/db/backends/mysql/features.py +++ b/django/db/backends/mysql/features.py @@ -1,8 +1,6 @@ from django.db.backends.base.features import BaseDatabaseFeatures from django.utils.functional import cached_property -from .base import Database - class DatabaseFeatures(BaseDatabaseFeatures): empty_fetchmany_value = () @@ -48,9 +46,7 @@ def can_introspect_foreign_keys(self): @cached_property def supports_microsecond_precision(self): - # See https://github.com/farcepest/MySQLdb1/issues/24 for the reason - # about requiring MySQLdb 1.2.5 - return self.connection.mysql_version >= (5, 6, 4) and Database.version_info >= (1, 2, 5) + return self.connection.mysql_version >= (5, 6, 4) @cached_property def has_zoneinfo_database(self): diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt index db622439f4ba..0628cef2e115 100644 --- a/docs/ref/databases.txt +++ b/docs/ref/databases.txt @@ -284,11 +284,11 @@ MySQL has a couple drivers that implement the Python Database API described in .. _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. +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 -MySQL Connector/Python includes `its own`_. +drivers from its ORM. Django provides an adapter for mysqlclient while MySQL +Connector/Python includes `its own`_. .. _its own: https://dev.mysql.com/doc/connector-python/en/connector-python-django-backend.html @@ -348,46 +348,9 @@ comparisons being done in a *case-insensitive* manner. That is, ``"Fred"`` and ``"freD"`` are considered equal at the database level. If you have a unique constraint on a field, it would be illegal to try to insert both ``"aa"`` and ``"AA"`` into the same column, since they compare as equal (and, hence, -non-unique) with the default collation. - -In many cases, this default will not be a problem. However, if you really want -case-sensitive comparisons on a particular column or table, you would change -the column or table to use the ``utf8_bin`` collation. The main thing to be -aware of in this case is that if you are using MySQLdb 1.2.2, the database -backend in Django will then return bytestrings (instead of unicode strings) for -any character fields it receive from the database. This is a strong variation -from Django's normal practice of *always* returning unicode strings. It is up -to you, the developer, to handle the fact that you will receive bytestrings if -you configure your table(s) to use ``utf8_bin`` collation. Django itself should -mostly work smoothly with such columns (except for the ``contrib.sessions`` -``Session`` and ``contrib.admin`` ``LogEntry`` tables described below), but -your code must be prepared to call ``django.utils.encoding.force_text()`` at -times if it really wants to work with consistent data -- Django will not do -this for you (the database backend layer and the model population layer are -separated internally so the database layer doesn't know it needs to make this -conversion in this one particular case). - -If you're using MySQLdb 1.2.1p2, Django's standard -:class:`~django.db.models.CharField` class will return unicode strings even -with ``utf8_bin`` collation. However, :class:`~django.db.models.TextField` -fields will be returned as an ``array.array`` instance (from Python's standard -``array`` module). There isn't a lot Django can do about that, since, again, -the information needed to make the necessary conversions isn't available when -the data is read in from the database. This problem was `fixed in MySQLdb -1.2.2`_, so if you want to use :class:`~django.db.models.TextField` with -``utf8_bin`` collation, upgrading to version 1.2.2 and then dealing with the -bytestrings (which shouldn't be too difficult) as described above is the -recommended solution. - -Should you decide to use ``utf8_bin`` collation for some of your tables with -MySQLdb 1.2.1p2 or 1.2.2, you should still use ``utf8_general_ci`` -(the default) collation for the ``django.contrib.sessions.models.Session`` -table (usually called ``django_session``) and the -:class:`django.contrib.admin.models.LogEntry` table (usually called -``django_admin_log``). Those are the two standard tables that use -:class:`~django.db.models.TextField` internally. - -.. _fixed in MySQLdb 1.2.2: http://sourceforge.net/tracker/index.php?func=detail&aid=1495765&group_id=22307&atid=374932 +non-unique) with the default collation. If you want case-sensitive comparisons +on a particular column or table, change the column or table to use the +``utf8_bin`` collation. Please note that according to `MySQL Unicode Character Sets`_, comparisons for the ``utf8_general_ci`` collation are faster, but slightly less correct, than @@ -441,12 +404,11 @@ Here's a sample configuration which uses a MySQL option file:: password = PASSWORD default-character-set = utf8 -Several other MySQLdb connection options may be useful, such as ``ssl``, -``init_command``, and ``sql_mode``. Consult the `MySQLdb documentation`_ for -more details. +Several other `MySQLdb connection options`_ may be useful, such as ``ssl``, +``init_command``, and ``sql_mode``. .. _MySQL option file: https://dev.mysql.com/doc/refman/en/option-files.html -.. _MySQLdb documentation: http://mysql-python.sourceforge.net/ +.. _MySQLdb connection options: https://mysqlclient.readthedocs.io/en/latest/user_guide.html#functions-and-attributes .. _mysql-sql-mode: @@ -575,11 +537,7 @@ Fractional seconds support for Time and DateTime fields MySQL 5.6.4 and later can store fractional seconds, provided that the column definition includes a fractional indication (e.g. ``DATETIME(6)``). -Earlier versions do not support them at all. In addition, versions of MySQLdb -older than 1.2.5 have `a bug`_ that also prevents the use of fractional seconds -with MySQL. - -.. _a bug: https://github.com/farcepest/MySQLdb1/issues/24 +Earlier versions do not support them at all. Django will not upgrade existing columns to include fractional seconds if the database server supports it. If you want to enable them on an existing database, diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index fc4290edb7ea..983bef2c8034 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -471,13 +471,6 @@ The default form widget for this field is a :class:`~django.forms.TextInput`. ``max_length`` for some backends. Refer to the :doc:`database backend notes ` for details. -.. admonition:: MySQL users - - If you are using this field with MySQLdb 1.2.2 and the ``utf8_bin`` - collation (which is *not* the default), there are some issues to be aware - of. Refer to the :ref:`MySQL database notes ` for - details. - ``DateField`` ------------- @@ -1080,13 +1073,6 @@ If you specify a ``max_length`` attribute, it will be reflected in the However it is not enforced at the model or database level. Use a :class:`CharField` for that. -.. admonition:: MySQL users - - If you are using this field with MySQLdb 1.2.1p2 and the ``utf8_bin`` - collation (which is *not* the default), there are some issues to be aware - of. Refer to the :ref:`MySQL database notes ` for - details. - ``TimeField`` ------------- From dc165ec8e5698ffc6dee6b510f1f92c9fd7467fe Mon Sep 17 00:00:00 2001 From: chillaranand Date: Sun, 22 Jan 2017 12:27:14 +0530 Subject: [PATCH 0119/3180] Refs #23919 -- Replaced super(ClassName, self) with super() in docs. --- docs/_ext/djangodocs.py | 2 +- docs/howto/custom-lookups.txt | 2 +- docs/howto/custom-management-commands.txt | 2 +- docs/howto/custom-model-fields.txt | 16 ++++++------ docs/ref/class-based-views/base.txt | 4 +-- .../ref/class-based-views/generic-display.txt | 4 +-- .../ref/class-based-views/generic-editing.txt | 2 +- docs/ref/class-based-views/mixins-simple.txt | 2 +- docs/ref/contrib/admin/actions.txt | 2 +- docs/ref/contrib/admin/index.txt | 26 +++++++++---------- docs/ref/contrib/sitemaps.txt | 2 +- docs/ref/contrib/staticfiles.txt | 2 +- docs/ref/contrib/syndication.txt | 6 ++--- docs/ref/forms/fields.txt | 4 +-- docs/ref/forms/validation.txt | 18 ++++++------- docs/ref/forms/widgets.txt | 2 +- docs/ref/models/expressions.txt | 6 ++--- docs/ref/models/instances.txt | 4 +-- docs/releases/1.4.txt | 2 +- docs/topics/auth/customizing.txt | 2 +- docs/topics/auth/passwords.txt | 2 +- docs/topics/checks.txt | 6 ++--- .../class-based-views/generic-display.txt | 6 ++--- .../class-based-views/generic-editing.txt | 8 +++--- docs/topics/class-based-views/intro.txt | 2 +- docs/topics/class-based-views/mixins.txt | 17 ++++++------ docs/topics/db/managers.txt | 6 ++--- docs/topics/db/models.txt | 6 ++--- docs/topics/db/multi-db.txt | 12 ++++----- docs/topics/forms/formsets.txt | 6 ++--- docs/topics/forms/modelforms.txt | 8 +++--- docs/topics/http/sessions.txt | 2 +- docs/topics/i18n/translation.txt | 4 +-- docs/topics/serialization.txt | 2 +- docs/topics/templates.txt | 2 +- docs/topics/testing/tools.txt | 8 +++--- 36 files changed, 103 insertions(+), 104 deletions(-) diff --git a/docs/_ext/djangodocs.py b/docs/_ext/djangodocs.py index a5d545f46b67..d86568d6c7df 100644 --- a/docs/_ext/djangodocs.py +++ b/docs/_ext/djangodocs.py @@ -307,7 +307,7 @@ class DjangoStandaloneHTMLBuilder(StandaloneHTMLBuilder): name = 'djangohtml' def finish(self): - super(DjangoStandaloneHTMLBuilder, self).finish() + super().finish() self.info(bold("writing templatebuiltins.js...")) xrefs = self.env.domaindata["std"]["objects"] templatebuiltins = { diff --git a/docs/howto/custom-lookups.txt b/docs/howto/custom-lookups.txt index 0b1cd717b9ef..64f7e5aca444 100644 --- a/docs/howto/custom-lookups.txt +++ b/docs/howto/custom-lookups.txt @@ -294,7 +294,7 @@ would override ``get_lookup`` with something like:: pass else: return get_coordinate_lookup(dimension) - return super(CoordinatesField, self).get_lookup(lookup_name) + return super().get_lookup(lookup_name) You would then define ``get_coordinate_lookup`` appropriately to return a ``Lookup`` subclass which handles the relevant value of ``dimension``. diff --git a/docs/howto/custom-management-commands.txt b/docs/howto/custom-management-commands.txt index 51db07e54067..b5212e305c1e 100644 --- a/docs/howto/custom-management-commands.txt +++ b/docs/howto/custom-management-commands.txt @@ -274,7 +274,7 @@ the :meth:`~BaseCommand.handle` method must be implemented. class Command(BaseCommand): def __init__(self, *args, **kwargs): - super(Command, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # ... .. method:: BaseCommand.add_arguments(parser) diff --git a/docs/howto/custom-model-fields.txt b/docs/howto/custom-model-fields.txt index 09d00e0928af..500cf58eaaee 100644 --- a/docs/howto/custom-model-fields.txt +++ b/docs/howto/custom-model-fields.txt @@ -168,7 +168,7 @@ behave like any existing field, so we'll subclass directly from def __init__(self, *args, **kwargs): kwargs['max_length'] = 104 - super(HandField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) Our ``HandField`` accepts most of the standard field options (see the list below), but we ensure it has a fixed length, since it only needs to hold 52 @@ -262,10 +262,10 @@ we can drop it from the keyword arguments for readability:: def __init__(self, *args, **kwargs): kwargs['max_length'] = 104 - super(HandField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def deconstruct(self): - name, path, args, kwargs = super(HandField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() del kwargs["max_length"] return name, path, args, kwargs @@ -279,10 +279,10 @@ into ``kwargs`` yourself:: def __init__(self, separator=",", *args, **kwargs): self.separator = separator - super(CommaSepField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def deconstruct(self): - name, path, args, kwargs = super(CommaSepField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() # Only include kwarg if it's not the default if self.separator != ",": kwargs['separator'] = self.separator @@ -435,7 +435,7 @@ time -- i.e., when the class is instantiated. To do that, just implement class BetterCharField(models.Field): def __init__(self, max_length, *args, **kwargs): self.max_length = max_length - super(BetterCharField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def db_type(self, connection): return 'char(%s)' % self.max_length @@ -576,7 +576,7 @@ For example, Django uses the following method for its :class:`BinaryField`:: def get_db_prep_value(self, value, connection, prepared=False): - value = super(BinaryField, self).get_db_prep_value(value, connection, prepared) + value = super().get_db_prep_value(value, connection, prepared) if value is not None: return connection.Database.Binary(value) return value @@ -633,7 +633,7 @@ as:: # while letting the caller override them. defaults = {'form_class': MyFormField} defaults.update(kwargs) - return super(HandField, self).formfield(**defaults) + return super().formfield(**defaults) This assumes we've imported a ``MyFormField`` field class (which has its own default widget). This document doesn't cover the details of writing custom form diff --git a/docs/ref/class-based-views/base.txt b/docs/ref/class-based-views/base.txt index c6959ca9efa0..2d0f4728393c 100644 --- a/docs/ref/class-based-views/base.txt +++ b/docs/ref/class-based-views/base.txt @@ -131,7 +131,7 @@ MRO is an acronym for Method Resolution Order. template_name = "home.html" def get_context_data(self, **kwargs): - context = super(HomePageView, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) context['latest_articles'] = Article.objects.all()[:5] return context @@ -194,7 +194,7 @@ MRO is an acronym for Method Resolution Order. def get_redirect_url(self, *args, **kwargs): article = get_object_or_404(Article, pk=kwargs['pk']) article.update_counter() - return super(ArticleCounterRedirectView, self).get_redirect_url(*args, **kwargs) + return super().get_redirect_url(*args, **kwargs) **Example urls.py**:: diff --git a/docs/ref/class-based-views/generic-display.txt b/docs/ref/class-based-views/generic-display.txt index b97d3674cd37..70da1803d660 100644 --- a/docs/ref/class-based-views/generic-display.txt +++ b/docs/ref/class-based-views/generic-display.txt @@ -48,7 +48,7 @@ many projects they are typically the most commonly used views. model = Article def get_context_data(self, **kwargs): - context = super(ArticleDetailView, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) context['now'] = timezone.now() return context @@ -117,7 +117,7 @@ many projects they are typically the most commonly used views. model = Article def get_context_data(self, **kwargs): - context = super(ArticleListView, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) context['now'] = timezone.now() return context diff --git a/docs/ref/class-based-views/generic-editing.txt b/docs/ref/class-based-views/generic-editing.txt index 43dd349bffa9..65cd7725367b 100644 --- a/docs/ref/class-based-views/generic-editing.txt +++ b/docs/ref/class-based-views/generic-editing.txt @@ -68,7 +68,7 @@ editing content: # This method is called when valid form data has been POSTed. # It should return an HttpResponse. form.send_email() - return super(ContactView, self).form_valid(form) + return super().form_valid(form) **Example myapp/contact.html**: diff --git a/docs/ref/class-based-views/mixins-simple.txt b/docs/ref/class-based-views/mixins-simple.txt index b039967c46ff..a2601a1b089e 100644 --- a/docs/ref/class-based-views/mixins-simple.txt +++ b/docs/ref/class-based-views/mixins-simple.txt @@ -15,7 +15,7 @@ Simple mixins arguments provided will make up the returned context. Example usage:: def get_context_data(self, **kwargs): - context = super(RandomNumberView, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) context['number'] = random.randrange(1, 100) return context diff --git a/docs/ref/contrib/admin/actions.txt b/docs/ref/contrib/admin/actions.txt index 039d8d37d6ca..c6f210b1de96 100644 --- a/docs/ref/contrib/admin/actions.txt +++ b/docs/ref/contrib/admin/actions.txt @@ -351,7 +351,7 @@ Conditionally enabling or disabling actions ... def get_actions(self, request): - actions = super(MyModelAdmin, self).get_actions(request) + actions = super().get_actions(request) if request.user.username[0].upper() != 'J': if 'delete_selected' in actions: del actions['delete_selected'] diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index 74faef6a75ea..d858a5741d4d 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -910,11 +910,11 @@ subclass:: def lookups(self, request, model_admin): if request.user.is_superuser: - return super(AuthDecadeBornListFilter, self).lookups(request, model_admin) + return super().lookups(request, model_admin) def queryset(self, request, queryset): if request.user.is_superuser: - return super(AuthDecadeBornListFilter, self).queryset(request, queryset) + return super().queryset(request, queryset) Also as a convenience, the ``ModelAdmin`` object is passed to the ``lookups`` method, for example if you want to base the @@ -1342,7 +1342,7 @@ templates used by the :class:`ModelAdmin` views: class ArticleAdmin(admin.ModelAdmin): def save_model(self, request, obj, form, change): obj.user = request.user - super(ArticleAdmin, self).save_model(request, obj, form, change) + super().save_model(request, obj, form, change) .. method:: ModelAdmin.delete_model(request, obj) @@ -1409,7 +1409,7 @@ templates used by the :class:`ModelAdmin` views: search_fields = ('name',) def get_search_results(self, request, queryset, search_term): - queryset, use_distinct = super(PersonAdmin, self).get_search_results(request, queryset, search_term) + queryset, use_distinct = super().get_search_results(request, queryset, search_term) try: search_term_as_int = int(search_term) except ValueError: @@ -1526,7 +1526,7 @@ templates used by the :class:`ModelAdmin` views: class MyModelAdmin(admin.ModelAdmin): def get_urls(self): - urls = super(MyModelAdmin, self).get_urls() + urls = super().get_urls() my_urls = [ url(r'^my_view/$', self.my_view), ] @@ -1578,7 +1578,7 @@ templates used by the :class:`ModelAdmin` views: class MyModelAdmin(admin.ModelAdmin): def get_urls(self): - urls = super(MyModelAdmin, self).get_urls() + urls = super().get_urls() my_urls = [ url(r'^my_view/$', self.admin_site.admin_view(self.my_view)) ] @@ -1615,7 +1615,7 @@ templates used by the :class:`ModelAdmin` views: def get_form(self, request, obj=None, **kwargs): if request.user.is_superuser: kwargs['form'] = MySuperuserForm - return super(MyModelAdmin, self).get_form(request, obj, **kwargs) + return super().get_form(request, obj, **kwargs) You may also simply return a custom :class:`~django.forms.ModelForm` class directly. @@ -1648,7 +1648,7 @@ templates used by the :class:`ModelAdmin` views: def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == "car": kwargs["queryset"] = Car.objects.filter(owner=request.user) - return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) + return super().formfield_for_foreignkey(db_field, request, **kwargs) This uses the ``HttpRequest`` instance to filter the ``Car`` foreign key field to only display the cars owned by the ``User`` instance. @@ -1666,7 +1666,7 @@ templates used by the :class:`ModelAdmin` views: def formfield_for_manytomany(self, db_field, request, **kwargs): if db_field.name == "cars": kwargs["queryset"] = Car.objects.filter(owner=request.user) - return super(MyModelAdmin, self).formfield_for_manytomany(db_field, request, **kwargs) + return super().formfield_for_manytomany(db_field, request, **kwargs) .. method:: ModelAdmin.formfield_for_choice_field(db_field, request, **kwargs) @@ -1685,7 +1685,7 @@ templates used by the :class:`ModelAdmin` views: ) if request.user.is_superuser: kwargs['choices'] += (('ready', 'Ready for deployment'),) - return super(MyModelAdmin, self).formfield_for_choice_field(db_field, request, **kwargs) + return super().formfield_for_choice_field(db_field, request, **kwargs) .. admonition:: Note @@ -1740,7 +1740,7 @@ templates used by the :class:`ModelAdmin` views: class MyModelAdmin(admin.ModelAdmin): def get_changelist_formset(self, request, **kwargs): kwargs['formset'] = MyAdminFormSet - return super(MyModelAdmin, self).get_changelist_formset(request, **kwargs) + return super().get_changelist_formset(request, **kwargs) .. method:: ModelAdmin.has_add_permission(request) @@ -1783,7 +1783,7 @@ templates used by the :class:`ModelAdmin` views: class MyModelAdmin(admin.ModelAdmin): def get_queryset(self, request): - qs = super(MyModelAdmin, self).get_queryset(request) + qs = super().get_queryset(request) if request.user.is_superuser: return qs return qs.filter(author=request.user) @@ -1902,7 +1902,7 @@ provided some extra mapping data that would not otherwise be available:: def change_view(self, request, object_id, form_url='', extra_context=None): extra_context = extra_context or {} extra_context['osm_data'] = self.get_osm_info() - return super(MyModelAdmin, self).change_view( + return super().change_view( request, object_id, form_url, extra_context=extra_context, ) diff --git a/docs/ref/contrib/sitemaps.txt b/docs/ref/contrib/sitemaps.txt index d3ce1cdb7fd1..b89a9a13b02c 100644 --- a/docs/ref/contrib/sitemaps.txt +++ b/docs/ref/contrib/sitemaps.txt @@ -509,7 +509,7 @@ method:: class Entry(models.Model): # ... def save(self, force_insert=False, force_update=False): - super(Entry, self).save(force_insert, force_update) + super().save(force_insert, force_update) try: ping_google() except Exception: diff --git a/docs/ref/contrib/staticfiles.txt b/docs/ref/contrib/staticfiles.txt index 46f1ce54b179..2c2db2109017 100644 --- a/docs/ref/contrib/staticfiles.txt +++ b/docs/ref/contrib/staticfiles.txt @@ -79,7 +79,7 @@ respectively. For example:: def __init__(self, *args, **kwargs): kwargs['file_permissions_mode'] = 0o640 kwargs['directory_permissions_mode'] = 0o760 - super(MyStaticFilesStorage, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) Then set the :setting:`STATICFILES_STORAGE` setting to ``'path.to.MyStaticFilesStorage'``. diff --git a/docs/ref/contrib/syndication.txt b/docs/ref/contrib/syndication.txt index 3552f70f291e..8c32cef191a6 100644 --- a/docs/ref/contrib/syndication.txt +++ b/docs/ref/contrib/syndication.txt @@ -155,7 +155,7 @@ into those elements. return Article.objects.order_by('-pub_date')[:5] def get_context_data(self, **kwargs): - context = super(ArticlesFeed, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) context['foo'] = 'bar' return context @@ -1057,12 +1057,12 @@ For example, you might start implementing an iTunes RSS feed generator like so:: class iTunesFeed(Rss201rev2Feed): def root_attributes(self): - attrs = super(iTunesFeed, self).root_attributes() + attrs = super().root_attributes() attrs['xmlns:itunes'] = 'http://www.itunes.com/dtds/podcast-1.0.dtd' return attrs def add_root_elements(self, handler): - super(iTunesFeed, self).add_root_elements(handler) + super().add_root_elements(handler) handler.addQuickElement('itunes:explicit', 'clean') Obviously there's a lot more work to be done for a complete custom feed class, diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt index b135532b2d7f..2949ad0a9b4c 100644 --- a/docs/ref/forms/fields.txt +++ b/docs/ref/forms/fields.txt @@ -1029,7 +1029,7 @@ Slightly complex built-in ``Field`` classes required=False, ), ) - super(PhoneField, self).__init__( + super().__init__( error_messages=error_messages, fields=fields, require_all_fields=False, *args, **kwargs ) @@ -1100,7 +1100,7 @@ method:: foo_select = forms.ModelMultipleChoiceField(queryset=None) def __init__(self, *args, **kwargs): - super(FooMultipleChoiceForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.fields['foo_select'].queryset = ... ``ModelChoiceField`` diff --git a/docs/ref/forms/validation.txt b/docs/ref/forms/validation.txt index b57f44cb6c72..6d3edf93e390 100644 --- a/docs/ref/forms/validation.txt +++ b/docs/ref/forms/validation.txt @@ -272,7 +272,7 @@ containing comma-separated email addresses. The full class looks like this:: def validate(self, value): """Check if value consists only of valid emails.""" # Use the parent's handling of required fields, etc. - super(MultiEmailField, self).validate(value) + super().validate(value) for email in value: validate_email(email) @@ -352,7 +352,7 @@ example:: ... def clean(self): - cleaned_data = super(ContactForm, self).clean() + cleaned_data = super().clean() cc_myself = cleaned_data.get("cc_myself") subject = cleaned_data.get("subject") @@ -367,14 +367,14 @@ example:: In this code, if the validation error is raised, the form will display an error message at the top of the form (normally) describing the problem. -The call to ``super(ContactForm, self).clean()`` in the example code ensures -that any validation logic in parent classes is maintained. If your form -inherits another that doesn't return a ``cleaned_data`` dictionary in its -``clean()`` method (doing so is optional), then don't assign ``cleaned_data`` -to the result of the ``super()`` call and use ``self.cleaned_data`` instead:: +The call to ``super().clean()`` in the example code ensures that any validation +logic in parent classes is maintained. If your form inherits another that +doesn't return a ``cleaned_data`` dictionary in its ``clean()`` method (doing +so is optional), then don't assign ``cleaned_data`` to the result of the +``super()`` call and use ``self.cleaned_data`` instead:: def clean(self): - super(ContactForm, self).clean() + super().clean() cc_myself = self.cleaned_data.get("cc_myself") ... @@ -393,7 +393,7 @@ work out what works effectively in your particular situation. Our new code ... def clean(self): - cleaned_data = super(ContactForm, self).clean() + cleaned_data = super().clean() cc_myself = cleaned_data.get("cc_myself") subject = cleaned_data.get("subject") diff --git a/docs/ref/forms/widgets.txt b/docs/ref/forms/widgets.txt index 210e5ce93cba..9f3ea2840c9f 100644 --- a/docs/ref/forms/widgets.txt +++ b/docs/ref/forms/widgets.txt @@ -410,7 +410,7 @@ foundation for custom widgets. widgets.Select(attrs=attrs, choices=months), widgets.Select(attrs=attrs, choices=years), ) - super(DateSelectorWidget, self).__init__(_widgets, attrs) + super().__init__(_widgets, attrs) def decompress(self, value): if value: diff --git a/docs/ref/models/expressions.txt b/docs/ref/models/expressions.txt index f53f791ffcab..6947b1855451 100644 --- a/docs/ref/models/expressions.txt +++ b/docs/ref/models/expressions.txt @@ -300,7 +300,7 @@ The ``Func`` API is as follows: ... def as_mysql(self, compiler, connection): - return super(ConcatPair, self).as_sql( + return super().as_sql( compiler, connection, function='CONCAT_WS', template="%(function)s('', %(expressions)s)", @@ -388,7 +388,7 @@ SQL that is generated. Here's a brief example:: template = '%(function)s(%(distinct)s%(expressions)s)' def __init__(self, expression, distinct=False, **extra): - super(Count, self).__init__( + super().__init__( expression, distinct='DISTINCT ' if distinct else '', output_field=IntegerField(), @@ -776,7 +776,7 @@ an ``__init__()`` method to set some attributes:: template = 'COALESCE( %(expressions)s )' def __init__(self, expressions, output_field): - super(Coalesce, self).__init__(output_field=output_field) + super().__init__(output_field=output_field) if len(expressions) < 2: raise ValueError('expressions must have at least 2 elements') for expression in expressions: diff --git a/docs/ref/models/instances.txt b/docs/ref/models/instances.txt index 058fd59512f2..5510105ccb2c 100644 --- a/docs/ref/models/instances.txt +++ b/docs/ref/models/instances.txt @@ -113,7 +113,7 @@ are loaded from the database:: if not self._state.adding and ( self.creator_id != self._loaded_values['creator_id']): raise ValueError("Updating the value of creator isn't allowed") - super(...).save(*args, **kwargs) + super().save(*args, **kwargs) The example above shows a full ``from_db()`` implementation to clarify how that is done. In this case it would of course be possible to just use ``super()`` call @@ -184,7 +184,7 @@ all of the instance's fields when a deferred field is reloaded:: if fields.intersection(deferred_fields): # then load all of them fields = fields.union(deferred_fields) - super(ExampleModel, self).refresh_from_db(using, fields, **kwargs) + super().refresh_from_db(using, fields, **kwargs) .. method:: Model.get_deferred_fields() diff --git a/docs/releases/1.4.txt b/docs/releases/1.4.txt index 8954aefd07e2..3a8b52db572e 100644 --- a/docs/releases/1.4.txt +++ b/docs/releases/1.4.txt @@ -929,7 +929,7 @@ comment model manager to exclude the user group, like this:: class BanningCommentManager(CommentManager): def get_query_set(self): - qs = super(BanningCommentManager, self).get_query_set() + qs = super().get_query_set() if getattr(settings, 'COMMENTS_BANNED_USERS_GROUP', None): where = ['user_id NOT IN (SELECT user_id FROM auth_user_groups WHERE group_id = %s)'] params = [settings.COMMENTS_BANNED_USERS_GROUP] diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt index c4fd73cebc28..b3c3335a73fe 100644 --- a/docs/topics/auth/customizing.txt +++ b/docs/topics/auth/customizing.txt @@ -1111,7 +1111,7 @@ code would be required in the app's ``admin.py`` file:: def save(self, commit=True): # Save the provided password in hashed format - user = super(UserCreationForm, self).save(commit=False) + user = super().save(commit=False) user.set_password(self.cleaned_data["password1"]) if commit: user.save() diff --git a/docs/topics/auth/passwords.txt b/docs/topics/auth/passwords.txt index 128a2906cb80..9cf868ca2112 100644 --- a/docs/topics/auth/passwords.txt +++ b/docs/topics/auth/passwords.txt @@ -292,7 +292,7 @@ First, we'll add the custom hasher: algorithm = 'pbkdf2_wrapped_sha1' def encode_sha1_hash(self, sha1_hash, salt, iterations=None): - return super(PBKDF2WrappedSHA1PasswordHasher, self).encode(sha1_hash, salt, iterations) + return super().encode(sha1_hash, salt, iterations) def encode(self, password, salt, iterations=None): _, _, sha1_hash = SHA1PasswordHasher().encode(password, salt).split('$', 2) diff --git a/docs/topics/checks.txt b/docs/topics/checks.txt index 59ead9d5a758..f4cea90447c5 100644 --- a/docs/topics/checks.txt +++ b/docs/topics/checks.txt @@ -144,13 +144,13 @@ code snippet shows how you can implement this check:: class RangedIntegerField(models.IntegerField): def __init__(self, min=None, max=None, **kwargs): - super(RangedIntegerField, self).__init__(**kwargs) + super().__init__(**kwargs) self.min = min self.max = max def check(self, **kwargs): # Call the superclass - errors = super(RangedIntegerField, self).check(**kwargs) + errors = super().check(**kwargs) # Do some custom checks and add messages to `errors`: errors.extend(self._check_min_max_values(**kwargs)) @@ -182,7 +182,7 @@ the only difference is that the check is a classmethod, not an instance method:: class MyModel(models.Model): @classmethod def check(cls, **kwargs): - errors = super(MyModel, cls).check(**kwargs) + errors = super().check(**kwargs) # ... your own checks ... return errors diff --git a/docs/topics/class-based-views/generic-display.txt b/docs/topics/class-based-views/generic-display.txt index bb848d614729..456c953cb15e 100644 --- a/docs/topics/class-based-views/generic-display.txt +++ b/docs/topics/class-based-views/generic-display.txt @@ -218,7 +218,7 @@ template, but you can override it to send more:: def get_context_data(self, **kwargs): # Call the base implementation first to get a context - context = super(PublisherDetail, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) # Add in a QuerySet of all the books context['book_list'] = Book.objects.all() return context @@ -365,7 +365,7 @@ use it in the template:: def get_context_data(self, **kwargs): # Call the base implementation first to get a context - context = super(PublisherBookList, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) # Add in the publisher context['publisher'] = self.publisher return context @@ -419,7 +419,7 @@ object -- so we simply override it and wrap the call:: def get_object(self): # Call the superclass - object = super(AuthorDetailView, self).get_object() + object = super().get_object() # Record the last accessed date object.last_accessed = timezone.now() object.save() diff --git a/docs/topics/class-based-views/generic-editing.txt b/docs/topics/class-based-views/generic-editing.txt index 6cc83ef5638e..8643b71f8c7c 100644 --- a/docs/topics/class-based-views/generic-editing.txt +++ b/docs/topics/class-based-views/generic-editing.txt @@ -48,7 +48,7 @@ The view can be constructed using a ``FormView``: # This method is called when valid form data has been POSTed. # It should return an HttpResponse. form.send_email() - return super(ContactView, self).form_valid(form) + return super().form_valid(form) Notes: @@ -215,7 +215,7 @@ to edit, and override def form_valid(self, form): form.instance.created_by = self.request.user - return super(AuthorCreate, self).form_valid(form) + return super().form_valid(form) Note that you'll need to :ref:`decorate this view` using @@ -239,7 +239,7 @@ works for AJAX requests as well as 'normal' form POSTs:: Must be used with an object-based FormView (e.g. CreateView) """ def form_invalid(self, form): - response = super(AjaxableResponseMixin, self).form_invalid(form) + response = super().form_invalid(form) if self.request.is_ajax(): return JsonResponse(form.errors, status=400) else: @@ -249,7 +249,7 @@ works for AJAX requests as well as 'normal' form POSTs:: # We make sure to call the parent's form_valid() method because # it might do some processing (in the case of CreateView, it will # call form.save() for example). - response = super(AjaxableResponseMixin, self).form_valid(form) + response = super().form_valid(form) if self.request.is_ajax(): data = { 'pk': self.object.pk, diff --git a/docs/topics/class-based-views/intro.txt b/docs/topics/class-based-views/intro.txt index 70852ee1e080..32562a8744ca 100644 --- a/docs/topics/class-based-views/intro.txt +++ b/docs/topics/class-based-views/intro.txt @@ -277,7 +277,7 @@ that it can be used on an instance method. For example:: @method_decorator(login_required) def dispatch(self, *args, **kwargs): - return super(ProtectedView, self).dispatch(*args, **kwargs) + return super().dispatch(*args, **kwargs) Or, more succinctly, you can decorate the class instead and pass the name of the method to be decorated as the keyword argument ``name``:: diff --git a/docs/topics/class-based-views/mixins.txt b/docs/topics/class-based-views/mixins.txt index 8573c971be98..7165ab6a8854 100644 --- a/docs/topics/class-based-views/mixins.txt +++ b/docs/topics/class-based-views/mixins.txt @@ -321,10 +321,10 @@ Now we can write a new ``PublisherDetail``:: def get(self, request, *args, **kwargs): self.object = self.get_object(queryset=Publisher.objects.all()) - return super(PublisherDetail, self).get(request, *args, **kwargs) + return super().get(request, *args, **kwargs) def get_context_data(self, **kwargs): - context = super(PublisherDetail, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) context['publisher'] = self.object return context @@ -461,7 +461,7 @@ Our new ``AuthorDetail`` looks like this:: return reverse('author-detail', kwargs={'pk': self.object.pk}) def get_context_data(self, **kwargs): - context = super(AuthorDetail, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) context['form'] = self.get_form() return context @@ -478,7 +478,7 @@ Our new ``AuthorDetail`` looks like this:: def form_valid(self, form): # Here, we would record the user's interest using the message # passed in form.cleaned_data['message'] - return super(AuthorDetail, self).form_valid(form) + return super().form_valid(form) ``get_success_url()`` is just providing somewhere to redirect to, which gets used in the default implementation of @@ -531,7 +531,7 @@ write our own ``get_context_data()`` to make the model = Author def get_context_data(self, **kwargs): - context = super(AuthorDisplay, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) context['form'] = AuthorInterestForm() return context @@ -555,7 +555,7 @@ template as ``AuthorDisplay`` is using on ``GET``:: if not request.user.is_authenticated: return HttpResponseForbidden() self.object = self.get_object() - return super(AuthorInterest, self).post(request, *args, **kwargs) + return super().post(request, *args, **kwargs) def get_success_url(self): return reverse('author-detail', kwargs={'pk': self.object.pk}) @@ -679,10 +679,9 @@ that the user requested:: if self.request.GET.get('format') == 'json': return self.render_to_json_response(context) else: - return super(HybridDetailView, self).render_to_response(context) + return super().render_to_response(context) Because of the way that Python resolves method overloading, the call to -``super(HybridDetailView, self).render_to_response(context)`` ends up -calling the +``super().render_to_response(context)`` ends up calling the :meth:`~django.views.generic.base.TemplateResponseMixin.render_to_response()` implementation of :class:`~django.views.generic.base.TemplateResponseMixin`. diff --git a/docs/topics/db/managers.txt b/docs/topics/db/managers.txt index a8923e2e36a9..87756dc2b468 100644 --- a/docs/topics/db/managers.txt +++ b/docs/topics/db/managers.txt @@ -121,7 +121,7 @@ all objects, and one that returns only the books by Roald Dahl:: # First, define the Manager subclass. class DahlBookManager(models.Manager): def get_queryset(self): - return super(DahlBookManager, self).get_queryset().filter(author='Roald Dahl') + return super().get_queryset().filter(author='Roald Dahl') # Then hook it into the Book model explicitly. class Book(models.Model): @@ -152,11 +152,11 @@ For example:: class AuthorManager(models.Manager): def get_queryset(self): - return super(AuthorManager, self).get_queryset().filter(role='A') + return super().get_queryset().filter(role='A') class EditorManager(models.Manager): def get_queryset(self): - return super(EditorManager, self).get_queryset().filter(role='E') + return super().get_queryset().filter(role='E') class Person(models.Model): first_name = models.CharField(max_length=50) diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt index 9bafb85120fa..5f24a8e3f2a6 100644 --- a/docs/topics/db/models.txt +++ b/docs/topics/db/models.txt @@ -804,7 +804,7 @@ to happen whenever you save an object. For example (see def save(self, *args, **kwargs): do_something() - super(Blog, self).save(*args, **kwargs) # Call the "real" save() method. + super().save(*args, **kwargs) # Call the "real" save() method. do_something_else() You can also prevent saving:: @@ -819,10 +819,10 @@ You can also prevent saving:: if self.name == "Yoko Ono's blog": return # Yoko shall never have her own blog! else: - super(Blog, self).save(*args, **kwargs) # Call the "real" save() method. + super().save(*args, **kwargs) # Call the "real" save() method. It's important to remember to call the superclass method -- that's -that ``super(Blog, self).save(*args, **kwargs)`` business -- to ensure +that ``super().save(*args, **kwargs)`` business -- to ensure that the object still gets saved into the database. If you forget to call the superclass method, the default behavior won't happen and the database won't get touched. diff --git a/docs/topics/db/multi-db.txt b/docs/topics/db/multi-db.txt index 69885453b386..cff3adac2157 100644 --- a/docs/topics/db/multi-db.txt +++ b/docs/topics/db/multi-db.txt @@ -592,17 +592,17 @@ multiple-database support:: def get_queryset(self, request): # Tell Django to look for objects on the 'other' database. - return super(MultiDBModelAdmin, self).get_queryset(request).using(self.using) + return super().get_queryset(request).using(self.using) def formfield_for_foreignkey(self, db_field, request, **kwargs): # Tell Django to populate ForeignKey widgets using a query # on the 'other' database. - return super(MultiDBModelAdmin, self).formfield_for_foreignkey(db_field, request, using=self.using, **kwargs) + return super().formfield_for_foreignkey(db_field, request, using=self.using, **kwargs) def formfield_for_manytomany(self, db_field, request, **kwargs): # Tell Django to populate ManyToMany widgets using a query # on the 'other' database. - return super(MultiDBModelAdmin, self).formfield_for_manytomany(db_field, request, using=self.using, **kwargs) + return super().formfield_for_manytomany(db_field, request, using=self.using, **kwargs) The implementation provided here implements a multi-database strategy where all objects of a given type are stored on a specific database @@ -618,17 +618,17 @@ similar fashion. They require three customized methods:: def get_queryset(self, request): # Tell Django to look for inline objects on the 'other' database. - return super(MultiDBTabularInline, self).get_queryset(request).using(self.using) + return super().get_queryset(request).using(self.using) def formfield_for_foreignkey(self, db_field, request, **kwargs): # Tell Django to populate ForeignKey widgets using a query # on the 'other' database. - return super(MultiDBTabularInline, self).formfield_for_foreignkey(db_field, request, using=self.using, **kwargs) + return super().formfield_for_foreignkey(db_field, request, using=self.using, **kwargs) def formfield_for_manytomany(self, db_field, request, **kwargs): # Tell Django to populate ManyToMany widgets using a query # on the 'other' database. - return super(MultiDBTabularInline, self).formfield_for_manytomany(db_field, request, using=self.using, **kwargs) + return super().formfield_for_manytomany(db_field, request, using=self.using, **kwargs) Once you've written your model admin definitions, they can be registered with any ``Admin`` instance:: diff --git a/docs/topics/forms/formsets.txt b/docs/topics/forms/formsets.txt index f1419b6a9281..a41c4a019601 100644 --- a/docs/topics/forms/formsets.txt +++ b/docs/topics/forms/formsets.txt @@ -533,7 +533,7 @@ default fields/attributes of the order and deletion fields:: >>> from myapp.forms import ArticleForm >>> class BaseArticleFormSet(BaseFormSet): ... def add_fields(self, form, index): - ... super(BaseArticleFormSet, self).add_fields(form, index) + ... super().add_fields(form, index) ... form.fields["my_field"] = forms.CharField() >>> ArticleFormSet = formset_factory(ArticleForm, formset=BaseArticleFormSet) @@ -559,7 +559,7 @@ You can pass this parameter when instantiating the formset:: >>> class MyArticleForm(ArticleForm): ... def __init__(self, *args, **kwargs): ... self.user = kwargs.pop('user') - ... super(MyArticleForm, self).__init__(*args, **kwargs) + ... super().__init__(*args, **kwargs) >>> ArticleFormSet = formset_factory(MyArticleForm) >>> formset = ArticleFormSet(form_kwargs={'user': request.user}) @@ -574,7 +574,7 @@ argument - the index of the form in the formset. The index is ``None`` for the >>> class BaseArticleFormSet(BaseFormSet): ... def get_form_kwargs(self, index): - ... kwargs = super(BaseArticleFormSet, self).get_form_kwargs(index) + ... kwargs = super().get_form_kwargs(index) ... kwargs['custom_kwarg'] = index ... return kwargs diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt index a3a817916998..e638009c8c75 100644 --- a/docs/topics/forms/modelforms.txt +++ b/docs/topics/forms/modelforms.txt @@ -797,7 +797,7 @@ Alternatively, you can create a subclass that sets ``self.queryset`` in class BaseAuthorFormSet(BaseModelFormSet): def __init__(self, *args, **kwargs): - super(BaseAuthorFormSet, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.queryset = Author.objects.filter(name__startswith='O') Then, pass your ``BaseAuthorFormSet`` class to the factory function:: @@ -1002,7 +1002,7 @@ class's ``clean`` method:: class MyModelFormSet(BaseModelFormSet): def clean(self): - super(MyModelFormSet, self).clean() + super().clean() # example custom validation across forms in the formset for form in self.forms: # your custom formset validation @@ -1018,7 +1018,7 @@ to modify a value in ``ModelFormSet.clean()`` you must modify class MyModelFormSet(BaseModelFormSet): def clean(self): - super(MyModelFormSet, self).clean() + super().clean() for form in self.forms: name = form.cleaned_data['name'].upper() @@ -1164,7 +1164,7 @@ For example, if you want to override ``clean()``:: class CustomInlineFormSet(BaseInlineFormSet): def clean(self): - super(CustomInlineFormSet, self).clean() + super().clean() # example custom validation across forms in the formset for form in self.forms: # your custom formset validation diff --git a/docs/topics/http/sessions.txt b/docs/topics/http/sessions.txt index 39c64f525da5..656044ee3f24 100644 --- a/docs/topics/http/sessions.txt +++ b/docs/topics/http/sessions.txt @@ -810,7 +810,7 @@ to query the database for all active sessions for an account):: return CustomSession def create_model_instance(self, data): - obj = super(SessionStore, self).create_model_instance(data) + obj = super().create_model_instance(data) try: account_id = int(data.get('_auth_user_id')) except (ValueError, TypeError): diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt index 2dd47bd8087a..46c77f1d0d75 100644 --- a/docs/topics/i18n/translation.txt +++ b/docs/topics/i18n/translation.txt @@ -1735,7 +1735,7 @@ If you need more flexibility, you could also add a new argument to your custom class Command(makemessages.Command): def add_arguments(self, parser): - super(Command, self).add_arguments(parser) + super().add_arguments(parser) parser.add_argument( '--extra-keyword', dest='xgettext_keywords', @@ -1749,7 +1749,7 @@ If you need more flexibility, you could also add a new argument to your custom makemessages.Command.xgettext_options[:] + ['--keyword=%s' % kwd for kwd in xgettext_keywords] ) - super(Command, self).handle(*args, **options) + super().handle(*args, **options) Miscellaneous ============= diff --git a/docs/topics/serialization.txt b/docs/topics/serialization.txt index 9f7a4f41c683..fd1c8876ec94 100644 --- a/docs/topics/serialization.txt +++ b/docs/topics/serialization.txt @@ -263,7 +263,7 @@ work:: def default(self, obj): if isinstance(obj, YourCustomType): return force_text(obj) - return super(LazyEncoder, self).default(obj) + return super().default(obj) You can then pass ``cls=LazyEncoder`` to the ``serializers.serialize()`` function:: diff --git a/docs/topics/templates.txt b/docs/topics/templates.txt index 23d74cbaa344..c44388000469 100644 --- a/docs/topics/templates.txt +++ b/docs/topics/templates.txt @@ -479,7 +479,7 @@ fictional ``foobar`` template library:: def __init__(self, params): params = params.copy() options = params.pop('OPTIONS').copy() - super(FooBar, self).__init__(params) + super().__init__(params) self.engine = foobar.Engine(**options) diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt index 91f96908271a..258e205aad9b 100644 --- a/docs/topics/testing/tools.txt +++ b/docs/topics/testing/tools.txt @@ -704,13 +704,13 @@ If your tests make any database queries, use subclasses @classmethod def setUpClass(cls): - super(MyTestCase, cls).setUpClass() + super().setUpClass() ... @classmethod def tearDownClass(cls): ... - super(MyTestCase, cls).tearDownClass() + super().tearDownClass() Be sure to account for Python's behavior if an exception is raised during ``setUpClass()``. If that happens, neither the tests in the class nor @@ -880,14 +880,14 @@ The code for this test may look as follows:: @classmethod def setUpClass(cls): - super(MySeleniumTests, cls).setUpClass() + super().setUpClass() cls.selenium = WebDriver() cls.selenium.implicitly_wait(10) @classmethod def tearDownClass(cls): cls.selenium.quit() - super(MySeleniumTests, cls).tearDownClass() + super().tearDownClass() def test_login(self): self.selenium.get('%s%s' % (self.live_server_url, '/login/')) From d6eaf7c0183cd04b78f2a55e1d60bb7e59598310 Mon Sep 17 00:00:00 2001 From: chillaranand Date: Sat, 21 Jan 2017 18:43:44 +0530 Subject: [PATCH 0120/3180] Refs #23919 -- Replaced super(ClassName, self) with super(). --- django/conf/__init__.py | 8 +- django/contrib/admin/apps.py | 2 +- django/contrib/admin/checks.py | 6 +- django/contrib/admin/filters.py | 20 +-- django/contrib/admin/helpers.py | 6 +- django/contrib/admin/options.py | 12 +- django/contrib/admin/sites.py | 2 +- .../contrib/admin/templatetags/admin_list.py | 2 +- django/contrib/admin/utils.py | 6 +- django/contrib/admin/widgets.py | 30 ++-- django/contrib/admindocs/views.py | 20 +-- django/contrib/auth/admin.py | 17 +- django/contrib/auth/base_user.py | 4 +- django/contrib/auth/forms.py | 20 +-- .../management/commands/createsuperuser.py | 4 +- django/contrib/auth/mixins.py | 6 +- django/contrib/auth/models.py | 2 +- django/contrib/auth/views.py | 32 ++-- django/contrib/contenttypes/fields.py | 27 ++- django/contrib/contenttypes/forms.py | 6 +- .../contenttypes/management/__init__.py | 2 +- django/contrib/contenttypes/models.py | 2 +- django/contrib/flatpages/forms.py | 2 +- django/contrib/gis/admin/options.py | 4 +- .../gis/db/backends/base/operations.py | 2 +- .../gis/db/backends/mysql/operations.py | 2 +- .../contrib/gis/db/backends/mysql/schema.py | 12 +- .../gis/db/backends/oracle/operations.py | 8 +- .../contrib/gis/db/backends/oracle/schema.py | 12 +- .../contrib/gis/db/backends/postgis/base.py | 4 +- .../gis/db/backends/postgis/introspection.py | 2 +- .../gis/db/backends/postgis/operations.py | 8 +- .../contrib/gis/db/backends/postgis/schema.py | 8 +- .../gis/db/backends/spatialite/base.py | 6 +- .../db/backends/spatialite/introspection.py | 2 +- .../gis/db/backends/spatialite/operations.py | 4 +- .../gis/db/backends/spatialite/schema.py | 14 +- django/contrib/gis/db/models/aggregates.py | 8 +- django/contrib/gis/db/models/fields.py | 24 +-- django/contrib/gis/db/models/functions.py | 62 +++---- django/contrib/gis/db/models/lookups.py | 8 +- django/contrib/gis/db/models/proxy.py | 4 +- django/contrib/gis/feeds.py | 18 +- django/contrib/gis/forms/fields.py | 4 +- django/contrib/gis/forms/widgets.py | 2 +- django/contrib/gis/gdal/geometries.py | 2 +- django/contrib/gis/geos/collections.py | 6 +- django/contrib/gis/geos/io.py | 4 +- django/contrib/gis/geos/linestring.py | 4 +- django/contrib/gis/geos/mutable_list.py | 2 +- django/contrib/gis/geos/point.py | 4 +- django/contrib/gis/geos/polygon.py | 4 +- .../contrib/gis/geos/prototypes/coordseq.py | 4 +- django/contrib/gis/geos/prototypes/geom.py | 4 +- django/contrib/gis/geos/prototypes/io.py | 4 +- django/contrib/gis/geos/prototypes/misc.py | 2 +- .../gis/management/commands/inspectdb.py | 2 +- django/contrib/gis/serializers/geojson.py | 6 +- django/contrib/messages/storage/base.py | 2 +- django/contrib/messages/storage/cookie.py | 4 +- django/contrib/messages/storage/fallback.py | 2 +- django/contrib/messages/storage/session.py | 2 +- django/contrib/messages/views.py | 2 +- django/contrib/postgres/aggregates/general.py | 2 +- .../contrib/postgres/aggregates/statistics.py | 8 +- django/contrib/postgres/fields/array.py | 30 ++-- django/contrib/postgres/fields/hstore.py | 10 +- django/contrib/postgres/fields/jsonb.py | 16 +- django/contrib/postgres/fields/ranges.py | 6 +- django/contrib/postgres/forms/array.py | 12 +- django/contrib/postgres/forms/hstore.py | 2 +- django/contrib/postgres/forms/ranges.py | 4 +- django/contrib/postgres/functions.py | 2 +- django/contrib/postgres/indexes.py | 10 +- django/contrib/postgres/lookups.py | 2 +- django/contrib/postgres/operations.py | 2 +- django/contrib/postgres/search.py | 24 +-- django/contrib/redirects/middleware.py | 2 +- django/contrib/sessions/backends/cache.py | 2 +- django/contrib/sessions/backends/cached_db.py | 8 +- django/contrib/sessions/backends/db.py | 2 +- django/contrib/sessions/backends/file.py | 2 +- django/contrib/sites/managers.py | 7 +- django/contrib/staticfiles/finders.py | 8 +- django/contrib/staticfiles/handlers.py | 6 +- .../management/commands/collectstatic.py | 2 +- .../management/commands/findstatic.py | 2 +- .../management/commands/runserver.py | 4 +- django/contrib/staticfiles/storage.py | 16 +- django/core/cache/backends/filebased.py | 2 +- django/core/cache/backends/memcached.py | 10 +- django/core/checks/messages.py | 10 +- django/core/exceptions.py | 2 +- django/core/files/base.py | 2 +- django/core/files/uploadedfile.py | 9 +- django/core/files/uploadhandler.py | 6 +- django/core/handlers/wsgi.py | 2 +- django/core/mail/backends/console.py | 2 +- django/core/mail/backends/filebased.py | 2 +- django/core/mail/backends/locmem.py | 2 +- django/core/mail/backends/smtp.py | 2 +- django/core/mail/message.py | 2 +- django/core/management/base.py | 6 +- django/core/management/commands/migrate.py | 2 +- django/core/management/commands/runserver.py | 2 +- django/core/management/commands/sqlflush.py | 2 +- django/core/management/commands/sqlmigrate.py | 2 +- .../management/commands/sqlsequencereset.py | 2 +- django/core/management/commands/startapp.py | 2 +- .../core/management/commands/startproject.py | 2 +- django/core/management/commands/test.py | 4 +- django/core/serializers/json.py | 4 +- django/core/serializers/pyyaml.py | 4 +- django/core/serializers/xml_serializer.py | 8 +- django/core/servers/basehttp.py | 10 +- django/core/signing.py | 4 +- django/core/validators.py | 6 +- django/db/backends/mysql/introspection.py | 2 +- django/db/backends/mysql/operations.py | 4 +- django/db/backends/mysql/schema.py | 10 +- django/db/backends/mysql/validation.py | 4 +- django/db/backends/oracle/base.py | 2 +- django/db/backends/oracle/compiler.py | 10 +- django/db/backends/oracle/features.py | 2 +- django/db/backends/oracle/functions.py | 4 +- django/db/backends/oracle/introspection.py | 2 +- django/db/backends/oracle/operations.py | 10 +- django/db/backends/oracle/schema.py | 6 +- django/db/backends/postgresql/base.py | 4 +- .../db/backends/postgresql/introspection.py | 2 +- django/db/backends/postgresql/operations.py | 2 +- django/db/backends/postgresql/schema.py | 8 +- django/db/backends/sqlite3/operations.py | 4 +- django/db/backends/sqlite3/schema.py | 6 +- django/db/backends/utils.py | 4 +- django/db/migrations/graph.py | 2 +- django/db/migrations/operations/fields.py | 12 +- django/db/migrations/operations/models.py | 26 +-- django/db/migrations/serializer.py | 2 +- django/db/migrations/state.py | 4 +- django/db/models/aggregates.py | 18 +- django/db/models/base.py | 4 +- django/db/models/deletion.py | 2 +- django/db/models/expressions.py | 42 ++--- django/db/models/fields/__init__.py | 165 +++++++++--------- django/db/models/fields/files.py | 30 ++-- django/db/models/fields/proxy.py | 4 +- django/db/models/fields/related.py | 51 +++--- .../db/models/fields/related_descriptors.py | 20 +-- django/db/models/fields/related_lookups.py | 8 +- django/db/models/fields/reverse_related.py | 6 +- django/db/models/functions/base.py | 32 ++-- django/db/models/functions/datetime.py | 10 +- django/db/models/lookups.py | 31 ++-- django/db/models/manager.py | 8 +- django/db/models/query_utils.py | 2 +- django/db/models/signals.py | 4 +- django/db/models/sql/compiler.py | 6 +- django/db/models/sql/subqueries.py | 6 +- django/forms/fields.py | 82 ++++----- django/forms/formsets.py | 2 +- django/forms/models.py | 29 ++- django/forms/utils.py | 2 +- django/forms/widgets.py | 48 ++--- django/http/cookie.py | 2 +- django/http/request.py | 20 +-- django/http/response.py | 14 +- django/template/backends/django.py | 2 +- django/template/backends/dummy.py | 2 +- django/template/backends/jinja2.py | 2 +- django/template/context.py | 13 +- django/template/defaulttags.py | 2 +- django/template/exceptions.py | 2 +- django/template/library.py | 4 +- django/template/loader_tags.py | 2 +- django/template/loaders/cached.py | 4 +- django/template/loaders/filesystem.py | 2 +- django/template/loaders/locmem.py | 2 +- django/template/response.py | 9 +- django/test/client.py | 34 ++-- django/test/html.py | 2 +- django/test/runner.py | 12 +- django/test/selenium.py | 6 +- django/test/testcases.py | 40 ++--- django/test/utils.py | 14 +- django/urls/resolvers.py | 4 +- django/utils/datastructures.py | 19 +- django/utils/decorators.py | 2 +- django/utils/deprecation.py | 6 +- django/utils/functional.py | 2 +- django/utils/jslex.py | 2 +- django/utils/log.py | 4 +- django/utils/safestring.py | 4 +- django/utils/six.py | 6 +- django/utils/text.py | 2 +- django/views/decorators/csrf.py | 2 +- django/views/generic/dates.py | 2 +- django/views/generic/detail.py | 4 +- django/views/generic/edit.py | 14 +- django/views/generic/list.py | 4 +- tests/admin_changelist/admin.py | 13 +- tests/admin_changelist/models.py | 2 +- tests/admin_checks/tests.py | 2 +- tests/admin_custom_urls/models.py | 8 +- tests/admin_filters/tests.py | 4 +- tests/admin_inlines/admin.py | 2 +- tests/admin_inlines/models.py | 2 +- tests/admin_ordering/tests.py | 4 +- .../commands/custom_startproject.py | 2 +- tests/admin_scripts/tests.py | 4 +- tests/admin_views/admin.py | 48 ++--- tests/admin_views/customadmin.py | 8 +- tests/admin_views/models.py | 2 +- tests/admin_widgets/models.py | 2 +- tests/admin_widgets/tests.py | 6 +- tests/admin_widgets/widgetadmin.py | 2 +- tests/aggregation/tests.py | 6 +- tests/auth_tests/client.py | 4 +- tests/auth_tests/test_auth_backends.py | 2 +- tests/auth_tests/test_deprecated_views.py | 2 +- tests/auth_tests/test_forms.py | 4 +- tests/auth_tests/test_remote_user.py | 4 +- tests/auth_tests/test_views.py | 2 +- tests/auth_tests/urls.py | 2 +- tests/auth_tests/urls_custom_user_admin.py | 2 +- tests/basic/tests.py | 2 +- tests/builtin_server/tests.py | 8 +- tests/cache/tests.py | 14 +- tests/check_framework/test_templates.py | 2 +- tests/csrf_tests/tests.py | 4 +- tests/custom_lookups/tests.py | 12 +- tests/custom_managers/models.py | 20 +-- tests/custom_pk/fields.py | 2 +- tests/defer/models.py | 2 +- tests/deprecation/tests.py | 8 +- tests/extra_regress/models.py | 4 +- tests/file_storage/tests.py | 4 +- tests/file_uploads/tests.py | 10 +- tests/file_uploads/uploadhandler.py | 2 +- tests/fixtures/models.py | 2 +- tests/flatpages_tests/test_sitemaps.py | 2 +- tests/foreign_object/models/article.py | 2 +- tests/foreign_object/models/empty_join.py | 4 +- tests/forms_tests/field_tests/test_base.py | 4 +- .../field_tests/test_multivaluefield.py | 6 +- tests/forms_tests/tests/test_forms.py | 20 +-- tests/forms_tests/tests/test_formsets.py | 6 +- tests/forms_tests/tests/test_media.py | 6 +- tests/forms_tests/widget_tests/base.py | 2 +- .../widget_tests/test_multiwidget.py | 8 +- tests/from_db_value/models.py | 4 +- tests/generic_relations/models.py | 2 +- tests/generic_relations/tests.py | 2 +- tests/generic_relations_regress/models.py | 2 +- tests/generic_views/test_base.py | 2 +- tests/generic_views/views.py | 21 +-- tests/get_object_or_404/models.py | 2 +- tests/gis_tests/geoapp/models.py | 2 +- tests/gis_tests/geoapp/test_sitemaps.py | 2 +- tests/gis_tests/geos_tests/test_geos.py | 2 +- .../gis_tests/geos_tests/test_mutable_list.py | 2 +- .../gis_migrations/test_operations.py | 4 +- tests/gis_tests/test_data.py | 4 +- tests/i18n/test_compilation.py | 6 +- tests/i18n/test_extraction.py | 4 +- tests/i18n/test_percents.py | 2 +- tests/i18n/tests.py | 14 +- tests/indexes/models.py | 2 +- tests/inline_formsets/tests.py | 2 +- tests/logging_tests/tests.py | 4 +- tests/mail/custombackend.py | 2 +- tests/mail/tests.py | 22 +-- tests/managers_regress/models.py | 6 +- tests/many_to_one/models.py | 2 +- tests/messages_tests/base.py | 4 +- tests/messages_tests/test_api.py | 4 +- tests/messages_tests/test_fallback.py | 2 +- tests/messages_tests/test_session.py | 2 +- tests/middleware/tests.py | 2 +- tests/migrations/models.py | 2 +- tests/migrations/test_commands.py | 4 +- tests/model_fields/models.py | 4 +- tests/model_fields/test_field_flags.py | 2 +- tests/model_forms/models.py | 12 +- tests/model_forms/tests.py | 6 +- tests/model_formsets/tests.py | 10 +- tests/model_formsets_regress/tests.py | 2 +- tests/model_inheritance/models.py | 2 +- tests/model_regress/test_pickle.py | 4 +- tests/modeladmin/tests.py | 8 +- tests/multiple_database/models.py | 4 +- tests/one_to_one/models.py | 4 +- tests/pagination/custom.py | 4 +- tests/postgres_tests/__init__.py | 2 +- tests/postgres_tests/fields.py | 6 +- tests/postgres_tests/models.py | 2 +- tests/prefetch_related/models.py | 2 +- tests/proxy_models/models.py | 4 +- tests/queries/models.py | 6 +- tests/queryset_pickle/models.py | 4 +- tests/raw_query/models.py | 2 +- tests/save_delete_hooks/models.py | 6 +- tests/schema/fields.py | 4 +- tests/serializers/models/base.py | 4 +- tests/serializers/models/data.py | 2 +- tests/serializers/test_json.py | 2 +- tests/serializers/test_yaml.py | 4 +- tests/servers/tests.py | 2 +- tests/sessions_tests/models.py | 2 +- tests/sessions_tests/tests.py | 6 +- tests/settings_tests/tests.py | 4 +- tests/signals/tests.py | 2 +- tests/sitemaps_tests/base.py | 2 +- tests/staticfiles_tests/cases.py | 4 +- tests/staticfiles_tests/test_finders.py | 6 +- tests/staticfiles_tests/test_liveserver.py | 8 +- tests/staticfiles_tests/test_management.py | 15 +- tests/staticfiles_tests/test_storage.py | 20 +-- tests/syndication_tests/feeds.py | 10 +- tests/syndication_tests/tests.py | 2 +- tests/template_backends/test_dummy.py | 2 +- .../template_tests/syntax_tests/test_cache.py | 2 +- .../syntax_tests/test_if_changed.py | 2 +- tests/template_tests/test_callables.py | 2 +- tests/template_tests/test_custom.py | 4 +- tests/template_tests/test_loaders.py | 6 +- tests/template_tests/test_logging.py | 4 +- tests/template_tests/test_nodelist.py | 2 +- tests/test_client_regress/session.py | 2 +- tests/test_runner/runner.py | 4 +- tests/test_runner/test_parallel.py | 2 +- tests/test_utils/tests.py | 4 +- tests/timezones/tests.py | 2 +- tests/utils_tests/test_lazyobject.py | 7 +- tests/utils_tests/test_module_loading.py | 4 +- tests/utils_tests/test_numberformat.py | 2 +- tests/validation/models.py | 2 +- tests/view_tests/tests/test_csrf.py | 2 +- tests/view_tests/tests/test_static.py | 4 +- 339 files changed, 1221 insertions(+), 1296 deletions(-) diff --git a/django/conf/__init__.py b/django/conf/__init__.py index ec6efa8e96e1..2f2cec6f8415 100644 --- a/django/conf/__init__.py +++ b/django/conf/__init__.py @@ -67,13 +67,13 @@ def __setattr__(self, name, value): self.__dict__.clear() else: self.__dict__.pop(name, None) - super(LazySettings, self).__setattr__(name, value) + super().__setattr__(name, value) def __delattr__(self, name): """ Delete a setting and clear it from cache if needed. """ - super(LazySettings, self).__delattr__(name) + super().__delattr__(name) self.__dict__.pop(name, None) def configure(self, default_settings=global_settings, **options): @@ -173,12 +173,12 @@ def __getattr__(self, name): def __setattr__(self, name, value): self._deleted.discard(name) - super(UserSettingsHolder, self).__setattr__(name, value) + super().__setattr__(name, value) def __delattr__(self, name): self._deleted.add(name) if hasattr(self, name): - super(UserSettingsHolder, self).__delattr__(name) + super().__delattr__(name) def __dir__(self): return sorted( diff --git a/django/contrib/admin/apps.py b/django/contrib/admin/apps.py index 194ec9f89d16..6fa406cc446e 100644 --- a/django/contrib/admin/apps.py +++ b/django/contrib/admin/apps.py @@ -19,5 +19,5 @@ class AdminConfig(SimpleAdminConfig): """The default AppConfig for admin which does autodiscovery.""" def ready(self): - super(AdminConfig, self).ready() + super().ready() self.module.autodiscover() diff --git a/django/contrib/admin/checks.py b/django/contrib/admin/checks.py index 354d0a3a9c71..dad809a8264d 100644 --- a/django/contrib/admin/checks.py +++ b/django/contrib/admin/checks.py @@ -513,7 +513,7 @@ def _check_readonly_fields_item(self, obj, model, field_name, label): class ModelAdminChecks(BaseModelAdminChecks): def check(self, admin_obj, **kwargs): - errors = super(ModelAdminChecks, self).check(admin_obj) + errors = super().check(admin_obj) errors.extend(self._check_save_as(admin_obj)) errors.extend(self._check_save_on_top(admin_obj)) errors.extend(self._check_inlines(admin_obj)) @@ -866,7 +866,7 @@ def _check_date_hierarchy(self, obj): class InlineModelAdminChecks(BaseModelAdminChecks): def check(self, inline_obj, **kwargs): - errors = super(InlineModelAdminChecks, self).check(inline_obj) + errors = super().check(inline_obj) parent_model = inline_obj.parent_model errors.extend(self._check_relation(inline_obj, parent_model)) errors.extend(self._check_exclude_of_parent_model(inline_obj, parent_model)) @@ -879,7 +879,7 @@ def check(self, inline_obj, **kwargs): def _check_exclude_of_parent_model(self, obj, parent_model): # Do not perform more specific checks if the base checks result in an # error. - errors = super(InlineModelAdminChecks, self)._check_exclude(obj) + errors = super()._check_exclude(obj) if errors: return [] diff --git a/django/contrib/admin/filters.py b/django/contrib/admin/filters.py index 923caa33e9a4..1b056e07e1c1 100644 --- a/django/contrib/admin/filters.py +++ b/django/contrib/admin/filters.py @@ -64,8 +64,7 @@ class SimpleListFilter(ListFilter): parameter_name = None def __init__(self, request, params, model, model_admin): - super(SimpleListFilter, self).__init__( - request, params, model, model_admin) + super().__init__(request, params, model, model_admin) if self.parameter_name is None: raise ImproperlyConfigured( "The list filter '%s' does not specify " @@ -122,8 +121,7 @@ def __init__(self, field, request, params, model, model_admin, field_path): self.field = field self.field_path = field_path self.title = getattr(field, 'verbose_name', field_path) - super(FieldListFilter, self).__init__( - request, params, model, model_admin) + super().__init__(request, params, model, model_admin) for p in self.expected_parameters(): if p in params: value = params.pop(p) @@ -165,8 +163,7 @@ def __init__(self, field, request, params, model, model_admin, field_path): self.lookup_kwarg_isnull = '%s__isnull' % field_path self.lookup_val = request.GET.get(self.lookup_kwarg) self.lookup_val_isnull = request.GET.get(self.lookup_kwarg_isnull) - super(RelatedFieldListFilter, self).__init__( - field, request, params, model, model_admin, field_path) + super().__init__(field, request, params, model, model_admin, field_path) self.lookup_choices = self.field_choices(field, request, model_admin) if hasattr(field, 'verbose_name'): self.lookup_title = field.verbose_name @@ -232,7 +229,7 @@ def __init__(self, field, request, params, model, model_admin, field_path): self.lookup_kwarg2 = '%s__isnull' % field_path self.lookup_val = request.GET.get(self.lookup_kwarg) self.lookup_val2 = request.GET.get(self.lookup_kwarg2) - super(BooleanFieldListFilter, self).__init__(field, request, params, model, model_admin, field_path) + super().__init__(field, request, params, model, model_admin, field_path) if (self.used_parameters and self.lookup_kwarg in self.used_parameters and self.used_parameters[self.lookup_kwarg] in ('1', '0')): self.used_parameters[self.lookup_kwarg] = bool(int(self.used_parameters[self.lookup_kwarg])) @@ -274,8 +271,7 @@ def __init__(self, field, request, params, model, model_admin, field_path): self.lookup_kwarg_isnull = '%s__isnull' % field_path self.lookup_val = request.GET.get(self.lookup_kwarg) self.lookup_val_isnull = request.GET.get(self.lookup_kwarg_isnull) - super(ChoicesFieldListFilter, self).__init__( - field, request, params, model, model_admin, field_path) + super().__init__(field, request, params, model, model_admin, field_path) def expected_parameters(self): return [self.lookup_kwarg, self.lookup_kwarg_isnull] @@ -362,8 +358,7 @@ def __init__(self, field, request, params, model, model_admin, field_path): (_('No date'), {self.field_generic + 'isnull': 'True'}), (_('Has date'), {self.field_generic + 'isnull': 'False'}), ) - super(DateFieldListFilter, self).__init__( - field, request, params, model, model_admin, field_path) + super().__init__(field, request, params, model, model_admin, field_path) def expected_parameters(self): params = [self.lookup_kwarg_since, self.lookup_kwarg_until] @@ -404,8 +399,7 @@ def __init__(self, field, request, params, model, model_admin, field_path): .distinct() .order_by(field.name) .values_list(field.name, flat=True)) - super(AllValuesFieldListFilter, self).__init__( - field, request, params, model, model_admin, field_path) + super().__init__(field, request, params, model, model_admin, field_path) def expected_parameters(self): return [self.lookup_kwarg, self.lookup_kwarg_isnull] diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py index 17aac7a85b9c..dc150c67009c 100644 --- a/django/contrib/admin/helpers.py +++ b/django/contrib/admin/helpers.py @@ -324,7 +324,7 @@ def __init__(self, formset, form, fieldsets, prepopulated_fields, original, self.original = original self.show_url = original and view_on_site_url is not None self.absolute_url = view_on_site_url - super(InlineAdminForm, self).__init__(form, fieldsets, prepopulated_fields, readonly_fields, model_admin) + super().__init__(form, fieldsets, prepopulated_fields, readonly_fields, model_admin) def __iter__(self): for name, options in self.fieldsets: @@ -366,7 +366,7 @@ def ordering_field(self): class InlineFieldset(Fieldset): def __init__(self, formset, *args, **kwargs): self.formset = formset - super(InlineFieldset, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def __iter__(self): fk = getattr(self.formset, "fk", None) @@ -381,7 +381,7 @@ class AdminErrorList(forms.utils.ErrorList): Stores all errors for the form/formsets in an add/change stage view. """ def __init__(self, form, inline_formsets): - super(AdminErrorList, self).__init__() + super().__init__() if form.is_bound: self.extend(form.errors.values()) diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 2d4bbbb933b2..ffca8163ecf9 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -519,7 +519,7 @@ def __init__(self, model, admin_site): self.model = model self.opts = model._meta self.admin_site = admin_site - super(ModelAdmin, self).__init__() + super().__init__() def __str__(self): return "%s.%s" % (self.model._meta.app_label, self.__class__.__name__) @@ -1842,7 +1842,7 @@ def __init__(self, parent_model, admin_site): self.parent_model = parent_model self.opts = self.model._meta self.has_registered_model = admin_site.is_registered(self.model) - super(InlineModelAdmin, self).__init__() + super().__init__() if self.verbose_name is None: self.verbose_name = self.model._meta.verbose_name if self.verbose_name_plural is None: @@ -1936,7 +1936,7 @@ def hand_clean_DELETE(self): raise ValidationError(msg, code='deleting_protected', params=params) def is_valid(self): - result = super(DeleteProtectedModelForm, self).is_valid() + result = super().is_valid() self.hand_clean_DELETE() return result @@ -1954,7 +1954,7 @@ def get_fields(self, request, obj=None): return list(form.base_fields) + list(self.get_readonly_fields(request, obj)) def get_queryset(self, request): - queryset = super(InlineModelAdmin, self).get_queryset(request) + queryset = super().get_queryset(request) if not self.has_change_permission(request): queryset = queryset.none() return queryset @@ -1966,7 +1966,7 @@ def has_add_permission(self, request): # to have the change permission for the related model in order to # be able to do anything with the intermediate model. return self.has_change_permission(request) - return super(InlineModelAdmin, self).has_add_permission(request) + return super().has_add_permission(request) def has_change_permission(self, request, obj=None): opts = self.opts @@ -1987,7 +1987,7 @@ def has_delete_permission(self, request, obj=None): # to have the change permission for the related model in order to # be able to do anything with the intermediate model. return self.has_change_permission(request, obj) - return super(InlineModelAdmin, self).has_delete_permission(request, obj) + return super().has_delete_permission(request, obj) class StackedInline(InlineModelAdmin): diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index 6adf13fdb80b..414c7ab9835a 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -198,7 +198,7 @@ class MyAdminSite(AdminSite): def get_urls(self): from django.conf.urls import url - urls = super(MyAdminSite, self).get_urls() + urls = super().get_urls() urls += [ url(r'^my_view/$', self.admin_view(some_view)) ] diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index c9dd6d7d30a1..81b533436d07 100644 --- a/django/contrib/admin/templatetags/admin_list.py +++ b/django/contrib/admin/templatetags/admin_list.py @@ -291,7 +291,7 @@ class ResultList(list): # compatibility with existing admin templates. def __init__(self, form, *items): self.form = form - super(ResultList, self).__init__(*items) + super().__init__(*items) def results(cl): diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py index c55173d6c9e6..b890d9e3af63 100644 --- a/django/contrib/admin/utils.py +++ b/django/contrib/admin/utils.py @@ -175,7 +175,7 @@ def format_callback(obj): class NestedObjects(Collector): def __init__(self, *args, **kwargs): - super(NestedObjects, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.edges = {} # {from_instance: [to_instances]} self.protected = set() self.model_objs = defaultdict(set) @@ -195,12 +195,12 @@ def collect(self, objs, source=None, source_attr=None, **kwargs): self.add_edge(None, obj) self.model_objs[obj._meta.model].add(obj) try: - return super(NestedObjects, self).collect(objs, source_attr=source_attr, **kwargs) + return super().collect(objs, source_attr=source_attr, **kwargs) except models.ProtectedError as e: self.protected.update(e.protected_objects) def related_objects(self, related, objs): - qs = super(NestedObjects, self).related_objects(related, objs) + qs = super().related_objects(related, objs) return qs.select_related(related.field.name) def _nested(self, obj, seen, format_callback): diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index 9f6fb412b2fe..380e0ad3a15a 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -29,10 +29,10 @@ def media(self): def __init__(self, verbose_name, is_stacked, attrs=None, choices=()): self.verbose_name = verbose_name self.is_stacked = is_stacked - super(FilteredSelectMultiple, self).__init__(attrs, choices) + super().__init__(attrs, choices) def get_context(self, name, value, attrs=None): - context = super(FilteredSelectMultiple, self).get_context(name, value, attrs) + context = super().get_context(name, value, attrs) context['widget']['attrs']['class'] = 'selectfilter' if self.is_stacked: context['widget']['attrs']['class'] += 'stacked' @@ -51,7 +51,7 @@ def __init__(self, attrs=None, format=None): final_attrs = {'class': 'vDateField', 'size': '10'} if attrs is not None: final_attrs.update(attrs) - super(AdminDateWidget, self).__init__(attrs=final_attrs, format=format) + super().__init__(attrs=final_attrs, format=format) class AdminTimeWidget(forms.TimeInput): @@ -64,7 +64,7 @@ def __init__(self, attrs=None, format=None): final_attrs = {'class': 'vTimeField', 'size': '8'} if attrs is not None: final_attrs.update(attrs) - super(AdminTimeWidget, self).__init__(attrs=final_attrs, format=format) + super().__init__(attrs=final_attrs, format=format) class AdminSplitDateTime(forms.SplitDateTimeWidget): @@ -80,7 +80,7 @@ def __init__(self, attrs=None): forms.MultiWidget.__init__(self, widgets, attrs) def get_context(self, name, value, attrs): - context = super(AdminSplitDateTime, self).get_context(name, value, attrs) + context = super().get_context(name, value, attrs) context['date_label'] = _('Date:') context['time_label'] = _('Time:') return context @@ -127,10 +127,10 @@ def __init__(self, rel, admin_site, attrs=None, using=None): self.rel = rel self.admin_site = admin_site self.db = using - super(ForeignKeyRawIdWidget, self).__init__(attrs) + super().__init__(attrs) def get_context(self, name, value, attrs=None): - context = super(ForeignKeyRawIdWidget, self).get_context(name, value, attrs) + context = super().get_context(name, value, attrs) rel_to = self.rel.model if rel_to in self.admin_site._registry: # The related object is registered with the same AdminSite @@ -197,7 +197,7 @@ class ManyToManyRawIdWidget(ForeignKeyRawIdWidget): template_name = 'admin/widgets/many_to_many_raw_id.html' def get_context(self, name, value, attrs=None): - context = super(ManyToManyRawIdWidget, self).get_context(name, value, attrs) + context = super().get_context(name, value, attrs) if self.rel.model in self.admin_site._registry: # The related object is registered with the same AdminSite context['widget']['attrs']['class'] = 'vManyToManyRawIdAdminField' @@ -310,7 +310,7 @@ def __init__(self, attrs=None): final_attrs = {'class': 'vLargeTextField'} if attrs is not None: final_attrs.update(attrs) - super(AdminTextareaWidget, self).__init__(attrs=final_attrs) + super().__init__(attrs=final_attrs) class AdminTextInputWidget(forms.TextInput): @@ -318,7 +318,7 @@ def __init__(self, attrs=None): final_attrs = {'class': 'vTextField'} if attrs is not None: final_attrs.update(attrs) - super(AdminTextInputWidget, self).__init__(attrs=final_attrs) + super().__init__(attrs=final_attrs) class AdminEmailInputWidget(forms.EmailInput): @@ -326,7 +326,7 @@ def __init__(self, attrs=None): final_attrs = {'class': 'vTextField'} if attrs is not None: final_attrs.update(attrs) - super(AdminEmailInputWidget, self).__init__(attrs=final_attrs) + super().__init__(attrs=final_attrs) class AdminURLFieldWidget(forms.URLInput): @@ -336,17 +336,17 @@ def __init__(self, attrs=None): final_attrs = {'class': 'vURLField'} if attrs is not None: final_attrs.update(attrs) - super(AdminURLFieldWidget, self).__init__(attrs=final_attrs) + super().__init__(attrs=final_attrs) def get_context(self, name, value, attrs): - context = super(AdminURLFieldWidget, self).get_context(name, value, attrs) + context = super().get_context(name, value, attrs) context['current_label'] = _('Currently:') context['change_label'] = _('Change:') context['widget']['href'] = smart_urlquote(context['widget']['value']) return context def format_value(self, value): - value = super(AdminURLFieldWidget, self).format_value(value) + value = super().format_value(value) return force_text(value) @@ -357,7 +357,7 @@ def __init__(self, attrs=None): final_attrs = {'class': self.class_name} if attrs is not None: final_attrs.update(attrs) - super(AdminIntegerFieldWidget, self).__init__(attrs=final_attrs) + super().__init__(attrs=final_attrs) class AdminBigIntegerFieldWidget(AdminIntegerFieldWidget): diff --git a/django/contrib/admindocs/views.py b/django/contrib/admindocs/views.py index f049c5f36763..a3a70b095c2f 100644 --- a/django/contrib/admindocs/views.py +++ b/django/contrib/admindocs/views.py @@ -37,19 +37,19 @@ def dispatch(self, request, *args, **kwargs): # Display an error message for people without docutils self.template_name = 'admin_doc/missing_docutils.html' return self.render_to_response(admin.site.each_context(request)) - return super(BaseAdminDocsView, self).dispatch(request, *args, **kwargs) + return super().dispatch(request, *args, **kwargs) def get_context_data(self, **kwargs): kwargs.update({'root_path': reverse('admin:index')}) kwargs.update(admin.site.each_context(self.request)) - return super(BaseAdminDocsView, self).get_context_data(**kwargs) + return super().get_context_data(**kwargs) class BookmarkletsView(BaseAdminDocsView): template_name = 'admin_doc/bookmarklets.html' def get_context_data(self, **kwargs): - context = super(BookmarkletsView, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) context.update({ 'admin_url': "%s://%s%s" % ( self.request.scheme, self.request.get_host(), context['root_path']) @@ -88,7 +88,7 @@ def get_context_data(self, **kwargs): 'library': tag_library, }) kwargs.update({'tags': tags}) - return super(TemplateTagIndexView, self).get_context_data(**kwargs) + return super().get_context_data(**kwargs) class TemplateFilterIndexView(BaseAdminDocsView): @@ -122,7 +122,7 @@ def get_context_data(self, **kwargs): 'library': tag_library, }) kwargs.update({'filters': filters}) - return super(TemplateFilterIndexView, self).get_context_data(**kwargs) + return super().get_context_data(**kwargs) class ViewIndexView(BaseAdminDocsView): @@ -146,7 +146,7 @@ def get_context_data(self, **kwargs): 'name': name, }) kwargs.update({'views': views}) - return super(ViewIndexView, self).get_context_data(**kwargs) + return super().get_context_data(**kwargs) class ViewDetailView(BaseAdminDocsView): @@ -194,7 +194,7 @@ def get_context_data(self, **kwargs): 'body': body, 'meta': metadata, }) - return super(ViewDetailView, self).get_context_data(**kwargs) + return super().get_context_data(**kwargs) class ModelIndexView(BaseAdminDocsView): @@ -203,7 +203,7 @@ class ModelIndexView(BaseAdminDocsView): def get_context_data(self, **kwargs): m_list = [m._meta for m in apps.get_models()] kwargs.update({'models': m_list}) - return super(ModelIndexView, self).get_context_data(**kwargs) + return super().get_context_data(**kwargs) class ModelDetailView(BaseAdminDocsView): @@ -333,7 +333,7 @@ def get_context_data(self, **kwargs): 'fields': fields, 'methods': methods, }) - return super(ModelDetailView, self).get_context_data(**kwargs) + return super().get_context_data(**kwargs) class TemplateDetailView(BaseAdminDocsView): @@ -366,7 +366,7 @@ def get_context_data(self, **kwargs): 'name': template, 'templates': templates, }) - return super(TemplateDetailView, self).get_context_data(**kwargs) + return super().get_context_data(**kwargs) #################### diff --git a/django/contrib/auth/admin.py b/django/contrib/auth/admin.py index f3c69023be82..0f8e89567d6b 100644 --- a/django/contrib/auth/admin.py +++ b/django/contrib/auth/admin.py @@ -36,8 +36,7 @@ def formfield_for_manytomany(self, db_field, request=None, **kwargs): # Avoid a major performance hit resolving permission names which # triggers a content_type load: kwargs['queryset'] = qs.select_related('content_type') - return super(GroupAdmin, self).formfield_for_manytomany( - db_field, request=request, **kwargs) + return super().formfield_for_manytomany(db_field, request=request, **kwargs) @admin.register(User) @@ -69,7 +68,7 @@ class UserAdmin(admin.ModelAdmin): def get_fieldsets(self, request, obj=None): if not obj: return self.add_fieldsets - return super(UserAdmin, self).get_fieldsets(request, obj) + return super().get_fieldsets(request, obj) def get_form(self, request, obj=None, **kwargs): """ @@ -79,7 +78,7 @@ def get_form(self, request, obj=None, **kwargs): if obj is None: defaults['form'] = self.add_form defaults.update(kwargs) - return super(UserAdmin, self).get_form(request, obj, **defaults) + return super().get_form(request, obj, **defaults) def get_urls(self): return [ @@ -88,13 +87,13 @@ def get_urls(self): self.admin_site.admin_view(self.user_change_password), name='auth_user_password_change', ), - ] + super(UserAdmin, self).get_urls() + ] + super().get_urls() def lookup_allowed(self, lookup, value): # See #20078: we don't want to allow any lookups involving passwords. if lookup.startswith('password'): return False - return super(UserAdmin, self).lookup_allowed(lookup, value) + return super().lookup_allowed(lookup, value) @sensitive_post_parameters_m @csrf_protect_m @@ -127,8 +126,7 @@ def _add_view(self, request, form_url='', extra_context=None): 'username_help_text': username_field.help_text, } extra_context.update(defaults) - return super(UserAdmin, self).add_view(request, form_url, - extra_context) + return super().add_view(request, form_url, extra_context) @sensitive_post_parameters_m def user_change_password(self, request, id, form_url=''): @@ -207,5 +205,4 @@ def response_add(self, request, obj, post_url_continue=None): if '_addanother' not in request.POST and IS_POPUP_VAR not in request.POST: request.POST = request.POST.copy() request.POST['_continue'] = 1 - return super(UserAdmin, self).response_add(request, obj, - post_url_continue) + return super().response_add(request, obj, post_url_continue) diff --git a/django/contrib/auth/base_user.py b/django/contrib/auth/base_user.py index 4ec18bee174e..de33baf3d7e1 100644 --- a/django/contrib/auth/base_user.py +++ b/django/contrib/auth/base_user.py @@ -61,7 +61,7 @@ def get_username(self): return getattr(self, self.USERNAME_FIELD) def __init__(self, *args, **kwargs): - super(AbstractBaseUser, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Stores the raw password if set_password() is called so that it can # be passed to password_changed() after the model is saved. self._password = None @@ -73,7 +73,7 @@ def clean(self): setattr(self, self.USERNAME_FIELD, self.normalize_username(self.get_username())) def save(self, *args, **kwargs): - super(AbstractBaseUser, self).save(*args, **kwargs) + super().save(*args, **kwargs) if self._password is not None: password_validation.password_changed(self._password, self) self._password = None diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py index 51c513cb671d..0a7961d64928 100644 --- a/django/contrib/auth/forms.py +++ b/django/contrib/auth/forms.py @@ -24,7 +24,7 @@ class ReadOnlyPasswordHashWidget(forms.Widget): template_name = 'auth/widgets/read_only_password_hash.html' def get_context(self, name, value, attrs): - context = super(ReadOnlyPasswordHashWidget, self).get_context(name, value, attrs) + context = super().get_context(name, value, attrs) summary = [] if not value or value.startswith(UNUSABLE_PASSWORD_PREFIX): summary.append({'label': ugettext("No password set.")}) @@ -45,7 +45,7 @@ class ReadOnlyPasswordHashField(forms.Field): def __init__(self, *args, **kwargs): kwargs.setdefault("required", False) - super(ReadOnlyPasswordHashField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def bound_data(self, data, initial): # Always return initial because the widget doesn't @@ -58,7 +58,7 @@ def has_changed(self, initial, data): class UsernameField(forms.CharField): def to_python(self, value): - return unicodedata.normalize('NFKC', super(UsernameField, self).to_python(value)) + return unicodedata.normalize('NFKC', super().to_python(value)) class UserCreationForm(forms.ModelForm): @@ -88,7 +88,7 @@ class Meta: field_classes = {'username': UsernameField} def __init__(self, *args, **kwargs): - super(UserCreationForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) if self._meta.model.USERNAME_FIELD in self.fields: self.fields[self._meta.model.USERNAME_FIELD].widget.attrs.update({'autofocus': True}) @@ -105,7 +105,7 @@ def clean_password2(self): return password2 def save(self, commit=True): - user = super(UserCreationForm, self).save(commit=False) + user = super().save(commit=False) user.set_password(self.cleaned_data["password1"]) if commit: user.save() @@ -128,7 +128,7 @@ class Meta: field_classes = {'username': UsernameField} def __init__(self, *args, **kwargs): - super(UserChangeForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) f = self.fields.get('user_permissions') if f is not None: f.queryset = f.queryset.select_related('content_type') @@ -170,7 +170,7 @@ def __init__(self, request=None, *args, **kwargs): """ self.request = request self.user_cache = None - super(AuthenticationForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Set the label for the "username" field. self.username_field = UserModel._meta.get_field(UserModel.USERNAME_FIELD) @@ -310,7 +310,7 @@ class SetPasswordForm(forms.Form): def __init__(self, user, *args, **kwargs): self.user = user - super(SetPasswordForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def clean_new_password2(self): password1 = self.cleaned_data.get('new_password1') @@ -384,7 +384,7 @@ class AdminPasswordChangeForm(forms.Form): def __init__(self, user, *args, **kwargs): self.user = user - super(AdminPasswordChangeForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def clean_password2(self): password1 = self.cleaned_data.get('password1') @@ -410,7 +410,7 @@ def save(self, commit=True): @property def changed_data(self): - data = super(AdminPasswordChangeForm, self).changed_data + data = super().changed_data for name in self.fields.keys(): if name not in data: return [] diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py index d9fd70b6f1e1..b027d2c326a8 100644 --- a/django/contrib/auth/management/commands/createsuperuser.py +++ b/django/contrib/auth/management/commands/createsuperuser.py @@ -22,7 +22,7 @@ class Command(BaseCommand): requires_migrations_checks = True def __init__(self, *args, **kwargs): - super(Command, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.UserModel = get_user_model() self.username_field = self.UserModel._meta.get_field(self.UserModel.USERNAME_FIELD) @@ -56,7 +56,7 @@ def add_arguments(self, parser): def execute(self, *args, **options): self.stdin = options.get('stdin', sys.stdin) # Used for testing - return super(Command, self).execute(*args, **options) + return super().execute(*args, **options) def handle(self, *args, **options): username = options[self.UserModel.USERNAME_FIELD] diff --git a/django/contrib/auth/mixins.py b/django/contrib/auth/mixins.py index e52311670f42..0b52c0286d86 100644 --- a/django/contrib/auth/mixins.py +++ b/django/contrib/auth/mixins.py @@ -52,7 +52,7 @@ class LoginRequiredMixin(AccessMixin): def dispatch(self, request, *args, **kwargs): if not request.user.is_authenticated: return self.handle_no_permission() - return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs) + return super().dispatch(request, *args, **kwargs) class PermissionRequiredMixin(AccessMixin): @@ -88,7 +88,7 @@ def has_permission(self): def dispatch(self, request, *args, **kwargs): if not self.has_permission(): return self.handle_no_permission() - return super(PermissionRequiredMixin, self).dispatch(request, *args, **kwargs) + return super().dispatch(request, *args, **kwargs) class UserPassesTestMixin(AccessMixin): @@ -112,4 +112,4 @@ def dispatch(self, request, *args, **kwargs): user_test_result = self.get_test_func()() if not user_test_result: return self.handle_no_permission() - return super(UserPassesTestMixin, self).dispatch(request, *args, **kwargs) + return super().dispatch(request, *args, **kwargs) diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index bd185b58be62..7476a695178e 100644 --- a/django/contrib/auth/models.py +++ b/django/contrib/auth/models.py @@ -340,7 +340,7 @@ class Meta: abstract = True def clean(self): - super(AbstractUser, self).clean() + super().clean() self.email = self.__class__.objects.normalize_email(self.email) def get_full_name(self): diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py index cca52a6105c2..6208b5fe4144 100644 --- a/django/contrib/auth/views.py +++ b/django/contrib/auth/views.py @@ -63,7 +63,7 @@ def dispatch(self, request, *args, **kwargs): "your LOGIN_REDIRECT_URL doesn't point to a login page." ) return HttpResponseRedirect(redirect_to) - return super(LoginView, self).dispatch(request, *args, **kwargs) + return super().dispatch(request, *args, **kwargs) def get_success_url(self): """Ensure the user-originating redirection URL is safe.""" @@ -89,7 +89,7 @@ def form_valid(self, form): return HttpResponseRedirect(self.get_success_url()) def get_context_data(self, **kwargs): - context = super(LoginView, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) current_site = get_current_site(self.request) context.update({ self.redirect_field_name: self.get_success_url(), @@ -125,7 +125,7 @@ def dispatch(self, request, *args, **kwargs): if next_page: # Redirect to this page until the session has been cleared. return HttpResponseRedirect(next_page) - return super(LogoutView, self).dispatch(request, *args, **kwargs) + return super().dispatch(request, *args, **kwargs) def get_next_page(self): if self.next_page is not None: @@ -153,7 +153,7 @@ def get_next_page(self): return next_page def get_context_data(self, **kwargs): - context = super(LogoutView, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) current_site = get_current_site(self.request) context.update({ 'site': current_site, @@ -356,7 +356,7 @@ class PasswordContextMixin: extra_context = None def get_context_data(self, **kwargs): - context = super(PasswordContextMixin, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) context['title'] = self.title if self.extra_context is not None: context.update(self.extra_context) @@ -377,7 +377,7 @@ class PasswordResetView(PasswordContextMixin, FormView): @method_decorator(csrf_protect) def dispatch(self, *args, **kwargs): - return super(PasswordResetView, self).dispatch(*args, **kwargs) + return super().dispatch(*args, **kwargs) def form_valid(self, form): opts = { @@ -391,7 +391,7 @@ def form_valid(self, form): 'extra_email_context': self.extra_email_context, } form.save(**opts) - return super(PasswordResetView, self).form_valid(form) + return super().form_valid(form) INTERNAL_RESET_URL_TOKEN = 'set-password' @@ -426,7 +426,7 @@ def dispatch(self, *args, **kwargs): if self.token_generator.check_token(self.user, session_token): # If the token is valid, display the password reset form. self.validlink = True - return super(PasswordResetConfirmView, self).dispatch(*args, **kwargs) + return super().dispatch(*args, **kwargs) else: if self.token_generator.check_token(self.user, token): # Store the token in the session and redirect to the @@ -450,7 +450,7 @@ def get_user(self, uidb64): return user def get_form_kwargs(self): - kwargs = super(PasswordResetConfirmView, self).get_form_kwargs() + kwargs = super().get_form_kwargs() kwargs['user'] = self.user return kwargs @@ -459,10 +459,10 @@ def form_valid(self, form): if self.post_reset_login: auth_login(self.request, user) del self.request.session[INTERNAL_RESET_SESSION_TOKEN] - return super(PasswordResetConfirmView, self).form_valid(form) + return super().form_valid(form) def get_context_data(self, **kwargs): - context = super(PasswordResetConfirmView, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) if self.validlink: context['validlink'] = True else: @@ -479,7 +479,7 @@ class PasswordResetCompleteView(PasswordContextMixin, TemplateView): title = _('Password reset complete') def get_context_data(self, **kwargs): - context = super(PasswordResetCompleteView, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) context['login_url'] = resolve_url(settings.LOGIN_URL) return context @@ -545,10 +545,10 @@ class PasswordChangeView(PasswordContextMixin, FormView): @method_decorator(csrf_protect) @method_decorator(login_required) def dispatch(self, *args, **kwargs): - return super(PasswordChangeView, self).dispatch(*args, **kwargs) + return super().dispatch(*args, **kwargs) def get_form_kwargs(self): - kwargs = super(PasswordChangeView, self).get_form_kwargs() + kwargs = super().get_form_kwargs() kwargs['user'] = self.request.user return kwargs @@ -557,7 +557,7 @@ def form_valid(self, form): # Updating the password logs out all other sessions for the user # except the current one. update_session_auth_hash(self.request, form.user) - return super(PasswordChangeView, self).form_valid(form) + return super().form_valid(form) class PasswordChangeDoneView(PasswordContextMixin, TemplateView): @@ -566,4 +566,4 @@ class PasswordChangeDoneView(PasswordContextMixin, TemplateView): @method_decorator(login_required) def dispatch(self, *args, **kwargs): - return super(PasswordChangeDoneView, self).dispatch(*args, **kwargs) + return super().dispatch(*args, **kwargs) diff --git a/django/contrib/contenttypes/fields.py b/django/contrib/contenttypes/fields.py index efffbfd77a07..37a9df14a02e 100644 --- a/django/contrib/contenttypes/fields.py +++ b/django/contrib/contenttypes/fields.py @@ -261,12 +261,10 @@ class GenericRel(ForeignObjectRel): """ def __init__(self, field, to, related_name=None, related_query_name=None, limit_choices_to=None): - super(GenericRel, self).__init__( - field, to, - related_name=related_query_name or '+', + super().__init__( + field, to, related_name=related_query_name or '+', related_query_name=related_query_name, - limit_choices_to=limit_choices_to, - on_delete=DO_NOTHING, + limit_choices_to=limit_choices_to, on_delete=DO_NOTHING, ) @@ -303,15 +301,14 @@ def __init__(self, to, object_id_field='object_id', content_type_field='content_ # isn't direct, the join is generated reverse along foreign key. So, # the from_field is object_id field, to_field is pk because of the # reverse join. - super(GenericRelation, self).__init__( - to, from_fields=[object_id_field], to_fields=[], **kwargs) + super().__init__(to, from_fields=[object_id_field], to_fields=[], **kwargs) self.object_id_field_name = object_id_field self.content_type_field_name = content_type_field self.for_concrete_model = for_concrete_model def check(self, **kwargs): - errors = super(GenericRelation, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_generic_foreign_key_existence()) return errors @@ -403,7 +400,7 @@ def value_to_string(self, obj): def contribute_to_class(self, cls, name, **kwargs): kwargs['private_only'] = True - super(GenericRelation, self).contribute_to_class(cls, name, **kwargs) + super().contribute_to_class(cls, name, **kwargs) self.model = cls setattr(cls, self.name, ReverseGenericManyToOneDescriptor(self.remote_field)) @@ -480,7 +477,7 @@ def create_generic_related_manager(superclass, rel): class GenericRelatedObjectManager(superclass): def __init__(self, instance=None): - super(GenericRelatedObjectManager, self).__init__() + super().__init__() self.instance = instance @@ -521,12 +518,12 @@ def get_queryset(self): try: return self.instance._prefetched_objects_cache[self.prefetch_cache_name] except (AttributeError, KeyError): - queryset = super(GenericRelatedObjectManager, self).get_queryset() + queryset = super().get_queryset() return self._apply_rel_filters(queryset) def get_prefetch_queryset(self, instances, queryset=None): if queryset is None: - queryset = super(GenericRelatedObjectManager, self).get_queryset() + queryset = super().get_queryset() queryset._add_hints(instance=instances[0]) queryset = queryset.using(queryset._db or self._db) @@ -634,21 +631,21 @@ def create(self, **kwargs): kwargs[self.content_type_field_name] = self.content_type kwargs[self.object_id_field_name] = self.pk_val db = router.db_for_write(self.model, instance=self.instance) - return super(GenericRelatedObjectManager, self).using(db).create(**kwargs) + return super().using(db).create(**kwargs) create.alters_data = True def get_or_create(self, **kwargs): kwargs[self.content_type_field_name] = self.content_type kwargs[self.object_id_field_name] = self.pk_val db = router.db_for_write(self.model, instance=self.instance) - return super(GenericRelatedObjectManager, self).using(db).get_or_create(**kwargs) + return super().using(db).get_or_create(**kwargs) get_or_create.alters_data = True def update_or_create(self, **kwargs): kwargs[self.content_type_field_name] = self.content_type kwargs[self.object_id_field_name] = self.pk_val db = router.db_for_write(self.model, instance=self.instance) - return super(GenericRelatedObjectManager, self).using(db).update_or_create(**kwargs) + return super().using(db).update_or_create(**kwargs) update_or_create.alters_data = True return GenericRelatedObjectManager diff --git a/django/contrib/contenttypes/forms.py b/django/contrib/contenttypes/forms.py index 8e88c9a1cd72..32b4012d8a89 100644 --- a/django/contrib/contenttypes/forms.py +++ b/django/contrib/contenttypes/forms.py @@ -27,11 +27,7 @@ def __init__(self, data=None, files=None, instance=None, save_as_new=None, self.instance, for_concrete_model=self.for_concrete_model), self.ct_fk_field.name: self.instance.pk, }) - super(BaseGenericInlineFormSet, self).__init__( - queryset=qs, data=data, files=files, - prefix=prefix, - **kwargs - ) + super().__init__(queryset=qs, data=data, files=files, prefix=prefix, **kwargs) @classmethod def get_default_prefix(cls): diff --git a/django/contrib/contenttypes/management/__init__.py b/django/contrib/contenttypes/management/__init__.py index 6799ef8a2360..a77c9d67b92e 100644 --- a/django/contrib/contenttypes/management/__init__.py +++ b/django/contrib/contenttypes/management/__init__.py @@ -8,7 +8,7 @@ def __init__(self, app_label, old_model, new_model): self.app_label = app_label self.old_model = old_model self.new_model = new_model - super(RenameContentType, self).__init__(self.rename_forward, self.rename_backward) + super().__init__(self.rename_forward, self.rename_backward) def _rename(self, apps, schema_editor, old_model, new_model): ContentType = apps.get_model('contenttypes', 'ContentType') diff --git a/django/contrib/contenttypes/models.py b/django/contrib/contenttypes/models.py index 9fe4a567673b..ce9afdb8adaf 100644 --- a/django/contrib/contenttypes/models.py +++ b/django/contrib/contenttypes/models.py @@ -10,7 +10,7 @@ class ContentTypeManager(models.Manager): use_in_migrations = True def __init__(self, *args, **kwargs): - super(ContentTypeManager, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Cache shared by all the get_for_* methods to speed up # ContentType retrieval. self._cache = {} diff --git a/django/contrib/flatpages/forms.py b/django/contrib/flatpages/forms.py index 4735c1ca95bc..3933df8e4e96 100644 --- a/django/contrib/flatpages/forms.py +++ b/django/contrib/flatpages/forms.py @@ -55,4 +55,4 @@ def clean(self): params={'url': url, 'site': site}, ) - return super(FlatpageForm, self).clean() + return super().clean() diff --git a/django/contrib/gis/admin/options.py b/django/contrib/gis/admin/options.py index 4ae61661d318..20bfa743790f 100644 --- a/django/contrib/gis/admin/options.py +++ b/django/contrib/gis/admin/options.py @@ -46,7 +46,7 @@ class GeoModelAdmin(ModelAdmin): @property def media(self): "Injects OpenLayers JavaScript into the admin." - media = super(GeoModelAdmin, self).media + media = super().media media.add_js([self.openlayers_url]) media.add_js(self.extra_js) return media @@ -62,7 +62,7 @@ def formfield_for_dbfield(self, db_field, request, **kwargs): kwargs['widget'] = self.get_map_widget(db_field) return db_field.formfield(**kwargs) else: - return super(GeoModelAdmin, self).formfield_for_dbfield(db_field, request, **kwargs) + return super().formfield_for_dbfield(db_field, request, **kwargs) def get_map_widget(self, db_field): """ diff --git a/django/contrib/gis/db/backends/base/operations.py b/django/contrib/gis/db/backends/base/operations.py index 23989da9fc8c..3d46f5f46c86 100644 --- a/django/contrib/gis/db/backends/base/operations.py +++ b/django/contrib/gis/db/backends/base/operations.py @@ -116,7 +116,7 @@ def check_expression_support(self, expression): raise NotImplementedError( "%s spatial aggregation is not supported by this database backend." % expression.name ) - super(BaseSpatialOperations, self).check_expression_support(expression) + super().check_expression_support(expression) def spatial_aggregate_name(self, agg_name): raise NotImplementedError('Aggregate support not implemented for this spatial backend.') diff --git a/django/contrib/gis/db/backends/mysql/operations.py b/django/contrib/gis/db/backends/mysql/operations.py index 7d8adbf1585e..6408d76fa445 100644 --- a/django/contrib/gis/db/backends/mysql/operations.py +++ b/django/contrib/gis/db/backends/mysql/operations.py @@ -97,7 +97,7 @@ def get_geom_placeholder(self, f, value, compiler): return placeholder def get_db_converters(self, expression): - converters = super(MySQLOperations, self).get_db_converters(expression) + converters = super().get_db_converters(expression) if isinstance(expression.output_field, GeometryField) and self.uses_invalid_empty_geometry_collection: converters.append(self.convert_invalid_empty_geometry_collection) return converters diff --git a/django/contrib/gis/db/backends/mysql/schema.py b/django/contrib/gis/db/backends/mysql/schema.py index a9b1b4867a35..699fab60e936 100644 --- a/django/contrib/gis/db/backends/mysql/schema.py +++ b/django/contrib/gis/db/backends/mysql/schema.py @@ -12,18 +12,18 @@ class MySQLGISSchemaEditor(DatabaseSchemaEditor): sql_drop_spatial_index = 'DROP INDEX %(index)s ON %(table)s' def __init__(self, *args, **kwargs): - super(MySQLGISSchemaEditor, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.geometry_sql = [] def skip_default(self, field): return ( - super(MySQLGISSchemaEditor, self).skip_default(field) or + super().skip_default(field) or # Geometry fields are stored as BLOB/TEXT and can't have defaults. isinstance(field, GeometryField) ) def column_sql(self, model, field, include_default=False): - column_sql = super(MySQLGISSchemaEditor, self).column_sql(model, field, include_default) + column_sql = super().column_sql(model, field, include_default) # MySQL doesn't support spatial indexes on NULL columns if isinstance(field, GeometryField) and field.spatial_index and not field.null: qn = self.connection.ops.quote_name @@ -38,11 +38,11 @@ def column_sql(self, model, field, include_default=False): return column_sql def create_model(self, model): - super(MySQLGISSchemaEditor, self).create_model(model) + super().create_model(model) self.create_spatial_indexes() def add_field(self, model, field): - super(MySQLGISSchemaEditor, self).add_field(model, field) + super().add_field(model, field) self.create_spatial_indexes() def remove_field(self, model, field): @@ -60,7 +60,7 @@ def remove_field(self, model, field): "if your storage engine doesn't support them).", sql ) - super(MySQLGISSchemaEditor, self).remove_field(model, field) + super().remove_field(model, field) def _create_spatial_index_name(self, model, field): return '%s_%s_id' % (model._meta.db_table, field.column) diff --git a/django/contrib/gis/db/backends/oracle/operations.py b/django/contrib/gis/db/backends/oracle/operations.py index a431b916bed9..6fc4fb69aa7b 100644 --- a/django/contrib/gis/db/backends/oracle/operations.py +++ b/django/contrib/gis/db/backends/oracle/operations.py @@ -49,7 +49,7 @@ def check_relate_argument(self, arg): def as_sql(self, connection, lookup, template_params, sql_params): template_params['mask'] = sql_params.pop() - return super(SDORelate, self).as_sql(connection, lookup, template_params, sql_params) + return super().as_sql(connection, lookup, template_params, sql_params) class SDOIsValid(SpatialOperator): @@ -143,10 +143,10 @@ def unsupported_functions(self): return unsupported def geo_quote_name(self, name): - return super(OracleOperations, self).geo_quote_name(name).upper() + return super().geo_quote_name(name).upper() def get_db_converters(self, expression): - converters = super(OracleOperations, self).get_db_converters(expression) + converters = super().get_db_converters(expression) internal_type = expression.output_field.get_internal_type() geometry_fields = ( 'PointField', 'GeometryField', 'LineStringField', @@ -271,4 +271,4 @@ def modify_insert_params(self, placeholder, params): """ if placeholder == 'NULL': return [] - return super(OracleOperations, self).modify_insert_params(placeholder, params) + return super().modify_insert_params(placeholder, params) diff --git a/django/contrib/gis/db/backends/oracle/schema.py b/django/contrib/gis/db/backends/oracle/schema.py index 78470da07d90..d90e6cfad646 100644 --- a/django/contrib/gis/db/backends/oracle/schema.py +++ b/django/contrib/gis/db/backends/oracle/schema.py @@ -25,14 +25,14 @@ class OracleGISSchemaEditor(DatabaseSchemaEditor): ) def __init__(self, *args, **kwargs): - super(OracleGISSchemaEditor, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.geometry_sql = [] def geo_quote_name(self, name): return self.connection.ops.geo_quote_name(name) def column_sql(self, model, field, include_default=False): - column_sql = super(OracleGISSchemaEditor, self).column_sql(model, field, include_default) + column_sql = super().column_sql(model, field, include_default) if isinstance(field, GeometryField): db_table = model._meta.db_table self.geometry_sql.append( @@ -58,17 +58,17 @@ def column_sql(self, model, field, include_default=False): return column_sql def create_model(self, model): - super(OracleGISSchemaEditor, self).create_model(model) + super().create_model(model) self.run_geometry_sql() def delete_model(self, model): - super(OracleGISSchemaEditor, self).delete_model(model) + super().delete_model(model) self.execute(self.sql_clear_geometry_table_metadata % { 'table': self.geo_quote_name(model._meta.db_table), }) def add_field(self, model, field): - super(OracleGISSchemaEditor, self).add_field(model, field) + super().add_field(model, field) self.run_geometry_sql() def remove_field(self, model, field): @@ -81,7 +81,7 @@ def remove_field(self, model, field): self.execute(self.sql_drop_spatial_index % { 'index': self.quote_name(self._create_spatial_index_name(model, field)), }) - super(OracleGISSchemaEditor, self).remove_field(model, field) + super().remove_field(model, field) def run_geometry_sql(self): for sql in self.geometry_sql: diff --git a/django/contrib/gis/db/backends/postgis/base.py b/django/contrib/gis/db/backends/postgis/base.py index 203e3ba075eb..c14df8ccfa09 100644 --- a/django/contrib/gis/db/backends/postgis/base.py +++ b/django/contrib/gis/db/backends/postgis/base.py @@ -12,14 +12,14 @@ class DatabaseWrapper(Psycopg2DatabaseWrapper): SchemaEditorClass = PostGISSchemaEditor def __init__(self, *args, **kwargs): - super(DatabaseWrapper, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) if kwargs.get('alias', '') != NO_DB_ALIAS: self.features = DatabaseFeatures(self) self.ops = PostGISOperations(self) self.introspection = PostGISIntrospection(self) def prepare_database(self): - super(DatabaseWrapper, self).prepare_database() + super().prepare_database() # Check that postgis extension is installed. with self.cursor() as cursor: cursor.execute("CREATE EXTENSION IF NOT EXISTS postgis") diff --git a/django/contrib/gis/db/backends/postgis/introspection.py b/django/contrib/gis/db/backends/postgis/introspection.py index 5e7c34aeedc4..43007c72d3ee 100644 --- a/django/contrib/gis/db/backends/postgis/introspection.py +++ b/django/contrib/gis/db/backends/postgis/introspection.py @@ -79,7 +79,7 @@ def get_field_type(self, data_type, description): # performed -- in other words, when this function is called. self.postgis_types_reverse = self.get_postgis_types() self.data_types_reverse.update(self.postgis_types_reverse) - return super(PostGISIntrospection, self).get_field_type(data_type, description) + return super().get_field_type(data_type, description) def get_geometry_type(self, table_name, geo_col): """ diff --git a/django/contrib/gis/db/backends/postgis/operations.py b/django/contrib/gis/db/backends/postgis/operations.py index 678c420c2356..e29b2558d95d 100644 --- a/django/contrib/gis/db/backends/postgis/operations.py +++ b/django/contrib/gis/db/backends/postgis/operations.py @@ -29,7 +29,7 @@ def __init__(self, geography=False, raster=False, **kwargs): # polygons. If the raster argument is set to BILATERAL, then the # operator cannot handle mixed geom-raster lookups. self.raster = raster - super(PostGISOperator, self).__init__(**kwargs) + super().__init__(**kwargs) def as_sql(self, connection, lookup, template_params, *args): if lookup.lhs.output_field.geography and not self.geography: @@ -37,7 +37,7 @@ def as_sql(self, connection, lookup, template_params, *args): 'function/operator.' % (self.func or self.op,)) template_params = self.check_raster(lookup, template_params) - return super(PostGISOperator, self).as_sql(connection, lookup, template_params, *args) + return super().as_sql(connection, lookup, template_params, *args) def check_raster(self, lookup, template_params): # Get rhs value. @@ -100,7 +100,7 @@ def as_sql(self, connection, lookup, template_params, sql_params): else: template_params.update({'op': self.op, 'func': connection.ops.spatial_function_name('DistanceSphere')}) return sql_template % template_params, sql_params - return super(PostGISDistanceOperator, self).as_sql(connection, lookup, template_params, sql_params) + return super().as_sql(connection, lookup, template_params, sql_params) class PostGISOperations(BaseSpatialOperations, DatabaseOperations): @@ -149,7 +149,7 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations): unsupported_functions = set() def __init__(self, connection): - super(PostGISOperations, self).__init__(connection) + super().__init__(connection) prefix = self.geom_func_prefix diff --git a/django/contrib/gis/db/backends/postgis/schema.py b/django/contrib/gis/db/backends/postgis/schema.py index d88901b50d8c..7a7f88f02d52 100644 --- a/django/contrib/gis/db/backends/postgis/schema.py +++ b/django/contrib/gis/db/backends/postgis/schema.py @@ -15,11 +15,11 @@ def geo_quote_name(self, name): def _field_should_be_indexed(self, model, field): if getattr(field, 'spatial_index', False): return True - return super(PostGISSchemaEditor, self)._field_should_be_indexed(model, field) + return super()._field_should_be_indexed(model, field) def _create_index_sql(self, model, fields, suffix="", sql=None): if len(fields) != 1 or not hasattr(fields[0], 'geodetic'): - return super(PostGISSchemaEditor, self)._create_index_sql(model, fields, suffix=suffix, sql=sql) + return super()._create_index_sql(model, fields, suffix=suffix, sql=sql) field = fields[0] field_column = self.quote_name(field.column) @@ -45,9 +45,7 @@ def _alter_column_type_sql(self, table, old_field, new_field, new_type): Special case when dimension changed. """ if not hasattr(old_field, 'dim') or not hasattr(new_field, 'dim'): - return super(PostGISSchemaEditor, self)._alter_column_type_sql( - table, old_field, new_field, new_type - ) + return super()._alter_column_type_sql(table, old_field, new_field, new_type) if old_field.dim == 2 and new_field.dim == 3: sql_alter = self.sql_alter_column_to_3d diff --git a/django/contrib/gis/db/backends/spatialite/base.py b/django/contrib/gis/db/backends/spatialite/base.py index 287c643ce82c..2b2a342b114f 100644 --- a/django/contrib/gis/db/backends/spatialite/base.py +++ b/django/contrib/gis/db/backends/spatialite/base.py @@ -34,10 +34,10 @@ def __init__(self, *args, **kwargs): 'Make sure it is in your library path, or set ' 'SPATIALITE_LIBRARY_PATH in your settings.' ) - super(DatabaseWrapper, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def get_new_connection(self, conn_params): - conn = super(DatabaseWrapper, self).get_new_connection(conn_params) + conn = super().get_new_connection(conn_params) # Enabling extension loading on the SQLite connection. try: conn.enable_load_extension(True) @@ -59,7 +59,7 @@ def get_new_connection(self, conn_params): return conn def prepare_database(self): - super(DatabaseWrapper, self).prepare_database() + super().prepare_database() # Check if spatial metadata have been initialized in the database with self.cursor() as cursor: cursor.execute("PRAGMA table_info(geometry_columns);") diff --git a/django/contrib/gis/db/backends/spatialite/introspection.py b/django/contrib/gis/db/backends/spatialite/introspection.py index 467e3a44f779..e06cd5a4e1e4 100644 --- a/django/contrib/gis/db/backends/spatialite/introspection.py +++ b/django/contrib/gis/db/backends/spatialite/introspection.py @@ -61,7 +61,7 @@ def get_geometry_type(self, table_name, geo_col): return field_type, field_params def get_constraints(self, cursor, table_name): - constraints = super(SpatiaLiteIntrospection, self).get_constraints(cursor, table_name) + constraints = super().get_constraints(cursor, table_name) cursor.execute('SELECT f_geometry_column ' 'FROM geometry_columns ' 'WHERE f_table_name=%s AND spatial_index_enabled=1', (table_name,)) diff --git a/django/contrib/gis/db/backends/spatialite/operations.py b/django/contrib/gis/db/backends/spatialite/operations.py index 5fab0b4df7e0..03e994ac9d0c 100644 --- a/django/contrib/gis/db/backends/spatialite/operations.py +++ b/django/contrib/gis/db/backends/spatialite/operations.py @@ -28,7 +28,7 @@ def as_sql(self, connection, lookup, template_params, sql_params): }) sql_params.insert(1, len(lookup.rhs) == 3 and lookup.rhs[-1] == 'spheroid') return sql_template % template_params, sql_params - return super(SpatiaLiteDistanceOperator, self).as_sql(connection, lookup, template_params, sql_params) + return super().as_sql(connection, lookup, template_params, sql_params) class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations): @@ -261,7 +261,7 @@ def spatial_ref_sys(self): return SpatialiteSpatialRefSys def get_db_converters(self, expression): - converters = super(SpatiaLiteOperations, self).get_db_converters(expression) + converters = super().get_db_converters(expression) if hasattr(expression.output_field, 'geom_type'): converters.append(self.convert_geometry) return converters diff --git a/django/contrib/gis/db/backends/spatialite/schema.py b/django/contrib/gis/db/backends/spatialite/schema.py index 401fbf2b786c..6f4e3380db06 100644 --- a/django/contrib/gis/db/backends/spatialite/schema.py +++ b/django/contrib/gis/db/backends/spatialite/schema.py @@ -28,7 +28,7 @@ class SpatialiteSchemaEditor(DatabaseSchemaEditor): ] def __init__(self, *args, **kwargs): - super(SpatialiteSchemaEditor, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.geometry_sql = [] def geo_quote_name(self, name): @@ -37,7 +37,7 @@ def geo_quote_name(self, name): def column_sql(self, model, field, include_default=False): from django.contrib.gis.db.models.fields import GeometryField if not isinstance(field, GeometryField): - return super(SpatialiteSchemaEditor, self).column_sql(model, field, include_default) + return super().column_sql(model, field, include_default) # Geometry columns are created by the `AddGeometryColumn` function self.geometry_sql.append( @@ -75,7 +75,7 @@ def remove_geometry_metadata(self, model, field): ) def create_model(self, model): - super(SpatialiteSchemaEditor, self).create_model(model) + super().create_model(model) # Create geometry columns for sql in self.geometry_sql: self.execute(sql) @@ -98,7 +98,7 @@ def delete_model(self, model, **kwargs): ) except DatabaseError: pass - super(SpatialiteSchemaEditor, self).delete_model(model, **kwargs) + super().delete_model(model, **kwargs) def add_field(self, model, field): from django.contrib.gis.db.models.fields import GeometryField @@ -109,7 +109,7 @@ def add_field(self, model, field): self.execute(sql) self.geometry_sql = [] else: - super(SpatialiteSchemaEditor, self).add_field(model, field) + super().add_field(model, field) def remove_field(self, model, field): from django.contrib.gis.db.models.fields import GeometryField @@ -121,7 +121,7 @@ def remove_field(self, model, field): if isinstance(field, GeometryField): self._remake_table(model, delete_field=field) else: - super(SpatialiteSchemaEditor, self).remove_field(model, field) + super().remove_field(model, field) def alter_db_table(self, model, old_db_table, new_db_table): from django.contrib.gis.db.models.fields import GeometryField @@ -135,7 +135,7 @@ def alter_db_table(self, model, old_db_table, new_db_table): } ) # Alter table - super(SpatialiteSchemaEditor, self).alter_db_table(model, old_db_table, new_db_table) + super().alter_db_table(model, old_db_table, new_db_table) # Repoint any straggler names for geom_table in self.geometry_tables: try: diff --git a/django/contrib/gis/db/models/aggregates.py b/django/contrib/gis/db/models/aggregates.py index 416481f9cac9..95dce944c5af 100644 --- a/django/contrib/gis/db/models/aggregates.py +++ b/django/contrib/gis/db/models/aggregates.py @@ -13,7 +13,7 @@ def as_sql(self, compiler, connection): # we get the spatial_aggregate_name connection.ops.check_expression_support(self) self.function = connection.ops.spatial_aggregate_name(self.name) - return super(GeoAggregate, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) def as_oracle(self, compiler, connection): if not hasattr(self, 'tolerance'): @@ -24,7 +24,7 @@ def as_oracle(self, compiler, connection): return self.as_sql(compiler, connection) def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False): - c = super(GeoAggregate, self).resolve_expression(query, allow_joins, reuse, summarize, for_save) + c = super().resolve_expression(query, allow_joins, reuse, summarize, for_save) for expr in c.get_source_expressions(): if not hasattr(expr.field, 'geom_type'): raise ValueError('Geospatial aggregates only allowed on geometry fields.') @@ -40,7 +40,7 @@ class Extent(GeoAggregate): is_extent = '2D' def __init__(self, expression, **extra): - super(Extent, self).__init__(expression, output_field=ExtentField(), **extra) + super().__init__(expression, output_field=ExtentField(), **extra) def convert_value(self, value, expression, connection, context): return connection.ops.convert_extent(value, context.get('transformed_srid')) @@ -51,7 +51,7 @@ class Extent3D(GeoAggregate): is_extent = '3D' def __init__(self, expression, **extra): - super(Extent3D, self).__init__(expression, output_field=ExtentField(), **extra) + super().__init__(expression, output_field=ExtentField(), **extra) def convert_value(self, value, expression, connection, context): return connection.ops.convert_extent3d(value, context.get('transformed_srid')) diff --git a/django/contrib/gis/db/models/fields.py b/django/contrib/gis/db/models/fields.py index 101975ed8790..d6cd529dc1e1 100644 --- a/django/contrib/gis/db/models/fields.py +++ b/django/contrib/gis/db/models/fields.py @@ -110,10 +110,10 @@ def __init__(self, verbose_name=None, srid=4326, spatial_index=True, **kwargs): # first parameter, so this works like normal fields. kwargs['verbose_name'] = verbose_name - super(BaseSpatialField, self).__init__(**kwargs) + super().__init__(**kwargs) def deconstruct(self): - name, path, args, kwargs = super(BaseSpatialField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() # Always include SRID for less fragility; include spatial index if it's # not the default value. kwargs['srid'] = self.srid @@ -207,7 +207,7 @@ def get_prep_value(self, value): geometry or raster value properly and preserves any other lookup parameters. """ - value = super(BaseSpatialField, self).get_prep_value(value) + value = super().get_prep_value(value) # For IsValid lookups, boolean values are allowed. if isinstance(value, (Expression, bool)): @@ -292,10 +292,10 @@ def __init__(self, verbose_name=None, dim=2, geography=False, **kwargs): self._extent = kwargs.pop('extent', (-180.0, -90.0, 180.0, 90.0)) self._tolerance = kwargs.pop('tolerance', 0.05) - super(GeometryField, self).__init__(verbose_name=verbose_name, **kwargs) + super().__init__(verbose_name=verbose_name, **kwargs) def deconstruct(self): - name, path, args, kwargs = super(GeometryField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() # Include kwargs if they're not the default values. if self.dim != 2: kwargs['dim'] = self.dim @@ -314,7 +314,7 @@ def get_distance(self, value, lookup_type, connection): def get_db_prep_value(self, value, connection, *args, **kwargs): return connection.ops.Adapter( - super(GeometryField, self).get_db_prep_value(value, connection, *args, **kwargs), + super().get_db_prep_value(value, connection, *args, **kwargs), **({'geography': True} if self.geography else {}) ) @@ -329,7 +329,7 @@ def from_db_value(self, value, expression, connection, context): # ### Routines overloaded from Field ### def contribute_to_class(self, cls, name, **kwargs): - super(GeometryField, self).contribute_to_class(cls, name, **kwargs) + super().contribute_to_class(cls, name, **kwargs) # Setup for lazy-instantiated Geometry object. setattr(cls, self.attname, SpatialProxy(Geometry, self)) @@ -343,7 +343,7 @@ def formfield(self, **kwargs): if (self.dim > 2 and 'widget' not in kwargs and not getattr(defaults['form_class'].widget, 'supports_3d', False)): defaults['widget'] = forms.Textarea - return super(GeometryField, self).formfield(**defaults) + return super().formfield(**defaults) # The OpenGIS Geometry Type Fields @@ -414,7 +414,7 @@ def _check_connection(self, connection): def db_type(self, connection): self._check_connection(connection) - return super(RasterField, self).db_type(connection) + return super().db_type(connection) def from_db_value(self, value, expression, connection, context): return connection.ops.parse_raster(value) @@ -424,10 +424,10 @@ def get_db_prep_value(self, value, connection, prepared=False): # Prepare raster for writing to database. if not prepared: value = connection.ops.deconstruct_raster(value) - return super(RasterField, self).get_db_prep_value(value, connection, prepared) + return super().get_db_prep_value(value, connection, prepared) def contribute_to_class(self, cls, name, **kwargs): - super(RasterField, self).contribute_to_class(cls, name, **kwargs) + super().contribute_to_class(cls, name, **kwargs) # Setup for lazy-instantiated Raster object. For large querysets, the # instantiation of all GDALRasters can potentially be expensive. This # delays the instantiation of the objects to the moment of evaluation @@ -444,4 +444,4 @@ def get_transform(self, name): ) except ValueError: pass - return super(RasterField, self).get_transform(name) + return super().get_transform(name) diff --git a/django/contrib/gis/db/models/functions.py b/django/contrib/gis/db/models/functions.py index 5454b2a7409e..01b2c93446e1 100644 --- a/django/contrib/gis/db/models/functions.py +++ b/django/contrib/gis/db/models/functions.py @@ -21,7 +21,7 @@ class GeoFunc(Func): def __init__(self, *expressions, **extra): if 'output_field' not in extra and self.output_field_class: extra['output_field'] = self.output_field_class() - super(GeoFunc, self).__init__(*expressions, **extra) + super().__init__(*expressions, **extra) @property def name(self): @@ -46,10 +46,10 @@ def as_sql(self, compiler, connection, **extra_context): self.function = connection.ops.spatial_function_name(self.name) if any(isinstance(field, RasterField) for field in self.get_source_fields()): raise TypeError("Geometry functions not supported for raster fields.") - return super(GeoFunc, self).as_sql(compiler, connection, **extra_context) + return super().as_sql(compiler, connection, **extra_context) def resolve_expression(self, *args, **kwargs): - res = super(GeoFunc, self).resolve_expression(*args, **kwargs) + res = super().resolve_expression(*args, **kwargs) base_srid = res.srid if not base_srid: raise TypeError("Geometry functions can only operate on geometric content.") @@ -88,7 +88,7 @@ def as_postgresql(self, compiler, connection): self.value = connection.ops.Adapter(self.value, geography=self.geography) else: self.value = connection.ops.Adapter(self.value) - return super(GeomValue, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) class GeoFuncWithGeoParam(GeoFunc): @@ -97,7 +97,7 @@ def __init__(self, expression, geom, *expressions, **extra): raise TypeError("Please provide a geometry object.") if not hasattr(geom, 'srid') or not geom.srid: raise ValueError("Please provide a geometry attribute with a defined SRID.") - super(GeoFuncWithGeoParam, self).__init__(expression, GeomValue(geom), *expressions, **extra) + super().__init__(expression, GeomValue(geom), *expressions, **extra) class SQLiteDecimalToFloatMixin: @@ -109,7 +109,7 @@ def as_sqlite(self, compiler, connection): for expr in self.get_source_expressions(): if hasattr(expr, 'value') and isinstance(expr.value, Decimal): expr.value = float(expr.value) - return super(SQLiteDecimalToFloatMixin, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) class OracleToleranceMixin: @@ -118,7 +118,7 @@ class OracleToleranceMixin: def as_oracle(self, compiler, connection): tol = self.extra.get('tolerance', self.tolerance) self.template = "%%(function)s(%%(expressions)s, %s)" % tol - return super(OracleToleranceMixin, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) class Area(OracleToleranceMixin, GeoFunc): @@ -141,11 +141,11 @@ def as_sql(self, compiler, connection, **extra_context): units_name = geo_field.units_name(connection) if units_name: self.output_field.area_att = AreaMeasure.unit_attname(units_name) - return super(Area, self).as_sql(compiler, connection, **extra_context) + return super().as_sql(compiler, connection, **extra_context) def as_oracle(self, compiler, connection): self.output_field = AreaField('sq_m') # Oracle returns area in units of meters. - return super(Area, self).as_oracle(compiler, connection) + return super().as_oracle(compiler, connection) def as_sqlite(self, compiler, connection, **extra_context): if self.geo_field.geodetic(connection): @@ -170,7 +170,7 @@ def __init__(self, expression, bbox=False, crs=False, precision=8, **extra): options = 2 if options: expressions.append(options) - super(AsGeoJSON, self).__init__(*expressions, **extra) + super().__init__(*expressions, **extra) class AsGML(GeoFunc): @@ -181,7 +181,7 @@ def __init__(self, expression, version=2, precision=8, **extra): expressions = [version, expression] if precision is not None: expressions.append(self._handle_param(precision, 'precision', int)) - super(AsGML, self).__init__(*expressions, **extra) + super().__init__(*expressions, **extra) def as_oracle(self, compiler, connection, **extra_context): source_expressions = self.get_source_expressions() @@ -196,7 +196,7 @@ class AsKML(AsGML): def as_sqlite(self, compiler, connection): # No version parameter self.source_expressions.pop(0) - return super(AsKML, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) class AsSVG(GeoFunc): @@ -209,12 +209,12 @@ def __init__(self, expression, relative=False, precision=8, **extra): relative, self._handle_param(precision, 'precision', int), ] - super(AsSVG, self).__init__(*expressions, **extra) + super().__init__(*expressions, **extra) class BoundingCircle(OracleToleranceMixin, GeoFunc): def __init__(self, expression, num_seg=48, **extra): - super(BoundingCircle, self).__init__(*[expression, num_seg], **extra) + super().__init__(*[expression, num_seg], **extra) def as_oracle(self, compiler, connection): clone = self.copy() @@ -260,7 +260,7 @@ def __init__(self, expr1, expr2, spheroid=None, **extra): if spheroid is not None: self.spheroid = spheroid expressions += (self._handle_param(spheroid, 'spheroid', bool),) - super(Distance, self).__init__(*expressions, **extra) + super().__init__(*expressions, **extra) def as_postgresql(self, compiler, connection): geo_field = GeometryField(srid=self.srid) # Fake field to get SRID info @@ -279,12 +279,12 @@ def as_postgresql(self, compiler, connection): self.source_expressions[2] = Value(geo_field._spheroid) else: self.function = connection.ops.spatial_function_name('DistanceSphere') - return super(Distance, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) def as_oracle(self, compiler, connection): if self.spheroid: self.source_expressions.pop(2) - return super(Distance, self).as_oracle(compiler, connection) + return super().as_oracle(compiler, connection) def as_sqlite(self, compiler, connection, **extra_context): if self.spheroid: @@ -293,7 +293,7 @@ def as_sqlite(self, compiler, connection, **extra_context): # SpatiaLite returns NULL instead of zero on geodetic coordinates extra_context['template'] = 'COALESCE(%(function)s(%(expressions)s, %(spheroid)s), 0)' extra_context['spheroid'] = int(bool(self.spheroid)) - return super(Distance, self).as_sql(compiler, connection, **extra_context) + return super().as_sql(compiler, connection, **extra_context) class Envelope(GeoFunc): @@ -311,7 +311,7 @@ def __init__(self, expression, precision=None, **extra): expressions = [expression] if precision is not None: expressions.append(self._handle_param(precision, 'precision', int)) - super(GeoHash, self).__init__(*expressions, **extra) + super().__init__(*expressions, **extra) class Intersection(OracleToleranceMixin, GeoFuncWithGeoParam): @@ -322,7 +322,7 @@ class IsValid(OracleToleranceMixin, GeoFunc): output_field_class = BooleanField def as_oracle(self, compiler, connection, **extra_context): - sql, params = super(IsValid, self).as_oracle(compiler, connection, **extra_context) + sql, params = super().as_oracle(compiler, connection, **extra_context) return "CASE %s WHEN 'TRUE' THEN 1 ELSE 0 END" % sql, params @@ -331,13 +331,13 @@ class Length(DistanceResultMixin, OracleToleranceMixin, GeoFunc): def __init__(self, expr1, spheroid=True, **extra): self.spheroid = spheroid - super(Length, self).__init__(expr1, **extra) + super().__init__(expr1, **extra) def as_sql(self, compiler, connection): geo_field = GeometryField(srid=self.srid) # Fake field to get SRID info if geo_field.geodetic(connection) and not connection.features.supports_length_geodetic: raise NotImplementedError("This backend doesn't support Length on geodetic fields") - return super(Length, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) def as_postgresql(self, compiler, connection): geo_field = GeometryField(srid=self.srid) # Fake field to get SRID info @@ -351,7 +351,7 @@ def as_postgresql(self, compiler, connection): dim = min(f.dim for f in self.get_source_fields() if f) if dim > 2: self.function = connection.ops.length3d - return super(Length, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) def as_sqlite(self, compiler, connection): geo_field = GeometryField(srid=self.srid) @@ -360,7 +360,7 @@ def as_sqlite(self, compiler, connection): self.function = 'GeodesicLength' else: self.function = 'GreatCircleLength' - return super(Length, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) class MakeValid(GeoFunc): @@ -385,7 +385,7 @@ def as_sql(self, compiler, connection): if self.source_expressions[self.geom_param_pos].output_field.geom_type != 'LINESTRING': if not connection.features.supports_num_points_poly: raise TypeError('NumPoints can only operate on LineString content on this database.') - return super(NumPoints, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) class Perimeter(DistanceResultMixin, OracleToleranceMixin, GeoFunc): @@ -399,13 +399,13 @@ def as_postgresql(self, compiler, connection): dim = min(f.dim for f in self.get_source_fields()) if dim > 2: self.function = connection.ops.perimeter3d - return super(Perimeter, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) def as_sqlite(self, compiler, connection): geo_field = GeometryField(srid=self.srid) # Fake field to get SRID info if geo_field.geodetic(connection): raise NotImplementedError("Perimeter cannot use a non-projected field.") - return super(Perimeter, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) class PointOnSurface(OracleToleranceMixin, GeoFunc): @@ -425,7 +425,7 @@ def __init__(self, expression, x, y, z=0.0, **extra): ] if z != 0.0: expressions.append(self._handle_param(z, 'z', NUMERIC_TYPES)) - super(Scale, self).__init__(*expressions, **extra) + super().__init__(*expressions, **extra) class SnapToGrid(SQLiteDecimalToFloatMixin, GeoFunc): @@ -446,7 +446,7 @@ def __init__(self, expression, *args, **extra): ) else: raise ValueError('Must provide 1, 2, or 4 arguments to `SnapToGrid`.') - super(SnapToGrid, self).__init__(*expressions, **extra) + super().__init__(*expressions, **extra) class SymDifference(OracleToleranceMixin, GeoFuncWithGeoParam): @@ -461,7 +461,7 @@ def __init__(self, expression, srid, **extra): ] if 'output_field' not in extra: extra['output_field'] = GeometryField(srid=srid) - super(Transform, self).__init__(*expressions, **extra) + super().__init__(*expressions, **extra) @property def srid(self): @@ -474,7 +474,7 @@ def as_sqlite(self, compiler, connection): if len(self.source_expressions) < 4: # Always provide the z parameter for ST_Translate self.source_expressions.append(Value(0)) - return super(Translate, self).as_sqlite(compiler, connection) + return super().as_sqlite(compiler, connection) class Union(OracleToleranceMixin, GeoFuncWithGeoParam): diff --git a/django/contrib/gis/db/models/lookups.py b/django/contrib/gis/db/models/lookups.py index 3b2d4b8497a6..ada589087291 100644 --- a/django/contrib/gis/db/models/lookups.py +++ b/django/contrib/gis/db/models/lookups.py @@ -22,7 +22,7 @@ class GISLookup(Lookup): band_lhs = None def __init__(self, *args, **kwargs): - super(GISLookup, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.template_params = {} @classmethod @@ -100,7 +100,7 @@ def get_db_prep_lookup(self, value, connection): def process_rhs(self, compiler, connection): if isinstance(self.rhs, Query): # If rhs is some Query, don't touch it. - return super(GISLookup, self).process_rhs(compiler, connection) + return super().process_rhs(compiler, connection) geom = self.rhs if isinstance(self.rhs, Col): @@ -124,7 +124,7 @@ def process_rhs(self, compiler, connection): elif isinstance(self.lhs, RasterBandTransform): self.process_band_indices(only_lhs=True) - rhs, rhs_params = super(GISLookup, self).process_rhs(compiler, connection) + rhs, rhs_params = super().process_rhs(compiler, connection) rhs = connection.ops.get_geom_placeholder(self.lhs.output_field, geom, compiler) return rhs, rhs_params @@ -390,7 +390,7 @@ def get_db_prep_lookup(self, value, connection): pattern = value[1] if not isinstance(pattern, str) or not self.pattern_regex.match(pattern): raise ValueError('Invalid intersection matrix pattern "%s".' % pattern) - return super(RelateLookup, self).get_db_prep_lookup(value, connection) + return super().get_db_prep_lookup(value, connection) gis_lookups['relate'] = RelateLookup diff --git a/django/contrib/gis/db/models/proxy.py b/django/contrib/gis/db/models/proxy.py index 86221daca766..8f6a8a602d8b 100644 --- a/django/contrib/gis/db/models/proxy.py +++ b/django/contrib/gis/db/models/proxy.py @@ -16,7 +16,7 @@ def __init__(self, klass, field): """ self._field = field self._klass = klass - super(SpatialProxy, self).__init__(field.attname, klass) + super().__init__(field.attname, klass) def __get__(self, instance, cls=None): """ @@ -33,7 +33,7 @@ def __get__(self, instance, cls=None): try: geo_value = instance.__dict__[self._field.attname] except KeyError: - geo_value = super(SpatialProxy, self).__get__(instance, cls) + geo_value = super().__get__(instance, cls) if isinstance(geo_value, self._klass): geo_obj = geo_value diff --git a/django/contrib/gis/feeds.py b/django/contrib/gis/feeds.py index 807a313bf444..b98e59653adf 100644 --- a/django/contrib/gis/feeds.py +++ b/django/contrib/gis/feeds.py @@ -82,46 +82,46 @@ def add_georss_element(self, handler, item, w3c_geo=False): # ### SyndicationFeed subclasses ### class GeoRSSFeed(Rss201rev2Feed, GeoFeedMixin): def rss_attributes(self): - attrs = super(GeoRSSFeed, self).rss_attributes() + attrs = super().rss_attributes() attrs['xmlns:georss'] = 'http://www.georss.org/georss' return attrs def add_item_elements(self, handler, item): - super(GeoRSSFeed, self).add_item_elements(handler, item) + super().add_item_elements(handler, item) self.add_georss_element(handler, item) def add_root_elements(self, handler): - super(GeoRSSFeed, self).add_root_elements(handler) + super().add_root_elements(handler) self.add_georss_element(handler, self.feed) class GeoAtom1Feed(Atom1Feed, GeoFeedMixin): def root_attributes(self): - attrs = super(GeoAtom1Feed, self).root_attributes() + attrs = super().root_attributes() attrs['xmlns:georss'] = 'http://www.georss.org/georss' return attrs def add_item_elements(self, handler, item): - super(GeoAtom1Feed, self).add_item_elements(handler, item) + super().add_item_elements(handler, item) self.add_georss_element(handler, item) def add_root_elements(self, handler): - super(GeoAtom1Feed, self).add_root_elements(handler) + super().add_root_elements(handler) self.add_georss_element(handler, self.feed) class W3CGeoFeed(Rss201rev2Feed, GeoFeedMixin): def rss_attributes(self): - attrs = super(W3CGeoFeed, self).rss_attributes() + attrs = super().rss_attributes() attrs['xmlns:geo'] = 'http://www.w3.org/2003/01/geo/wgs84_pos#' return attrs def add_item_elements(self, handler, item): - super(W3CGeoFeed, self).add_item_elements(handler, item) + super().add_item_elements(handler, item) self.add_georss_element(handler, item, w3c_geo=True) def add_root_elements(self, handler): - super(W3CGeoFeed, self).add_root_elements(handler) + super().add_root_elements(handler) self.add_georss_element(handler, self.feed, w3c_geo=True) diff --git a/django/contrib/gis/forms/fields.py b/django/contrib/gis/forms/fields.py index ef0f4a9bee41..f435bd5ab1d1 100644 --- a/django/contrib/gis/forms/fields.py +++ b/django/contrib/gis/forms/fields.py @@ -27,7 +27,7 @@ def __init__(self, **kwargs): # defaults (e.g., allow None). self.srid = kwargs.pop('srid', None) self.geom_type = kwargs.pop('geom_type', self.geom_type) - super(GeometryField, self).__init__(**kwargs) + super().__init__(**kwargs) self.widget.attrs['geom_type'] = self.geom_type def to_python(self, value): @@ -58,7 +58,7 @@ def clean(self, value): object (which is returned). A ValidationError is raised if the value cannot be instantiated as a Geometry. """ - geom = super(GeometryField, self).clean(value) + geom = super().clean(value) if geom is None: return geom diff --git a/django/contrib/gis/forms/widgets.py b/django/contrib/gis/forms/widgets.py index 0c1fc23c81a1..0ec98a3f4a99 100644 --- a/django/contrib/gis/forms/widgets.py +++ b/django/contrib/gis/forms/widgets.py @@ -103,7 +103,7 @@ class OSMWidget(OpenLayersWidget): map_srid = 3857 def __init__(self, attrs=None): - super(OSMWidget, self).__init__() + super().__init__() for key in ('default_lon', 'default_lat'): self.attrs[key] = getattr(self, key) if attrs: diff --git a/django/contrib/gis/gdal/geometries.py b/django/contrib/gis/gdal/geometries.py index b1acc5bf5bd7..4b4f33607177 100644 --- a/django/contrib/gis/gdal/geometries.py +++ b/django/contrib/gis/gdal/geometries.py @@ -502,7 +502,7 @@ class Point(OGRGeometry): def _geos_ptr(self): from django.contrib.gis import geos - return geos.Point._create_empty() if self.empty else super(Point, self)._geos_ptr() + return geos.Point._create_empty() if self.empty else super()._geos_ptr() @classmethod def _create_empty(cls): diff --git a/django/contrib/gis/geos/collections.py b/django/contrib/gis/geos/collections.py index e964a1de8f46..a3b0e74faae6 100644 --- a/django/contrib/gis/geos/collections.py +++ b/django/contrib/gis/geos/collections.py @@ -37,7 +37,7 @@ def __init__(self, *args, **kwargs): # Creating the geometry pointer array. collection = self._create_collection(len(init_geoms), iter(init_geoms)) - super(GeometryCollection, self).__init__(collection, **kwargs) + super().__init__(collection, **kwargs) def __iter__(self): "Iterates over each Geometry in the Collection." @@ -89,7 +89,7 @@ def json(self): for geom in self ], }) - return super(GeometryCollection, self).json + return super().json geojson = json @property @@ -118,7 +118,7 @@ class MultiLineString(LinearGeometryMixin, GeometryCollection): def closed(self): if geos_version_info()['version'] < '3.5': raise GEOSException("MultiLineString.closed requires GEOS >= 3.5.0.") - return super(MultiLineString, self).closed + return super().closed class MultiPolygon(GeometryCollection): diff --git a/django/contrib/gis/geos/io.py b/django/contrib/gis/geos/io.py index daf67dd28c2a..11abe10e3d50 100644 --- a/django/contrib/gis/geos/io.py +++ b/django/contrib/gis/geos/io.py @@ -15,10 +15,10 @@ class WKBReader(_WKBReader): def read(self, wkb): "Returns a GEOSGeometry for the given WKB buffer." - return GEOSGeometry(super(WKBReader, self).read(wkb)) + return GEOSGeometry(super().read(wkb)) class WKTReader(_WKTReader): def read(self, wkt): "Returns a GEOSGeometry for the given WKT string." - return GEOSGeometry(super(WKTReader, self).read(wkt)) + return GEOSGeometry(super().read(wkt)) diff --git a/django/contrib/gis/geos/linestring.py b/django/contrib/gis/geos/linestring.py index 6caf6bef34b4..667c2da37957 100644 --- a/django/contrib/gis/geos/linestring.py +++ b/django/contrib/gis/geos/linestring.py @@ -37,7 +37,7 @@ def __init__(self, *args, **kwargs): ncoords = len(coords) if not ncoords: - super(LineString, self).__init__(self._init_func(None), srid=srid) + super().__init__(self._init_func(None), srid=srid) return if ncoords < self._minlength: @@ -86,7 +86,7 @@ def __init__(self, *args, **kwargs): # Calling the base geometry initialization with the returned pointer # from the function. - super(LineString, self).__init__(self._init_func(cs.ptr), srid=srid) + super().__init__(self._init_func(cs.ptr), srid=srid) def __iter__(self): "Allows iteration over this LineString." diff --git a/django/contrib/gis/geos/mutable_list.py b/django/contrib/gis/geos/mutable_list.py index c7fb703ce1c9..fa5faccd1ea4 100644 --- a/django/contrib/gis/geos/mutable_list.py +++ b/django/contrib/gis/geos/mutable_list.py @@ -67,7 +67,7 @@ def __init__(self, *args, **kwargs): self._set_single = self._set_single_rebuild self._assign_extended_slice = self._assign_extended_slice_rebuild - super(ListMixin, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def __getitem__(self, index): "Get the item(s) at the specified index/slice." diff --git a/django/contrib/gis/geos/point.py b/django/contrib/gis/geos/point.py index 6486b2a5e136..aeb6303e39e9 100644 --- a/django/contrib/gis/geos/point.py +++ b/django/contrib/gis/geos/point.py @@ -38,10 +38,10 @@ def __init__(self, x=None, y=None, z=None, srid=None): # Initializing using the address returned from the GEOS # createPoint factory. - super(Point, self).__init__(point, srid=srid) + super().__init__(point, srid=srid) def _ogr_ptr(self): - return gdal.geometries.Point._create_empty() if self.empty else super(Point, self)._ogr_ptr() + return gdal.geometries.Point._create_empty() if self.empty else super()._ogr_ptr() @classmethod def _create_empty(cls): diff --git a/django/contrib/gis/geos/polygon.py b/django/contrib/gis/geos/polygon.py index 58f1b28c293a..42d351a84fa2 100644 --- a/django/contrib/gis/geos/polygon.py +++ b/django/contrib/gis/geos/polygon.py @@ -27,7 +27,7 @@ def __init__(self, *args, **kwargs): ... ((4, 4), (4, 6), (6, 6), (6, 4), (4, 4))) """ if not args: - super(Polygon, self).__init__(self._create_polygon(0, None), **kwargs) + super().__init__(self._create_polygon(0, None), **kwargs) return # Getting the ext_ring and init_holes parameters from the argument list @@ -45,7 +45,7 @@ def __init__(self, *args, **kwargs): n_holes = len(init_holes) polygon = self._create_polygon(n_holes + 1, (ext_ring,) + init_holes) - super(Polygon, self).__init__(polygon, **kwargs) + super().__init__(polygon, **kwargs) def __iter__(self): "Iterates over each ring in the polygon." diff --git a/django/contrib/gis/geos/prototypes/coordseq.py b/django/contrib/gis/geos/prototypes/coordseq.py index 982ce3261304..a21c64946d46 100644 --- a/django/contrib/gis/geos/prototypes/coordseq.py +++ b/django/contrib/gis/geos/prototypes/coordseq.py @@ -48,7 +48,7 @@ def get_func(self, ordinate=False, get=False): self.argtypes = [CS_PTR, c_uint, c_uint, dbl_param] else: self.argtypes = [CS_PTR, c_uint, dbl_param] - return super(CsOperation, self).get_func() + return super().get_func() class CsOutput(GEOSFuncFactory): @@ -56,7 +56,7 @@ class CsOutput(GEOSFuncFactory): def get_func(self, argtypes): self.argtypes = argtypes - return super(CsOutput, self).get_func() + return super().get_func() @staticmethod def errcheck(result, func, cargs): diff --git a/django/contrib/gis/geos/prototypes/geom.py b/django/contrib/gis/geos/prototypes/geom.py index 9e14f214dc92..cb6aa2c9a156 100644 --- a/django/contrib/gis/geos/prototypes/geom.py +++ b/django/contrib/gis/geos/prototypes/geom.py @@ -43,7 +43,7 @@ class GeomOutput(GEOSFuncFactory): def get_func(self, argtypes): self.argtypes = argtypes - return super(GeomOutput, self).get_func() + return super().get_func() class IntFromGeom(GEOSFuncFactory): @@ -56,7 +56,7 @@ def get_func(self, zero=False): self.errcheck = check_zero else: self.errcheck = check_minus_one - return super(IntFromGeom, self).get_func() + return super().get_func() class StringFromGeom(GEOSFuncFactory): diff --git a/django/contrib/gis/geos/prototypes/io.py b/django/contrib/gis/geos/prototypes/io.py index b8b1a06dbae8..8cbc3c560d5d 100644 --- a/django/contrib/gis/geos/prototypes/io.py +++ b/django/contrib/gis/geos/prototypes/io.py @@ -165,7 +165,7 @@ class WKTWriter(IOBase): _precision = None def __init__(self, dim=2, trim=False, precision=None): - super(WKTWriter, self).__init__() + super().__init__() if bool(trim) != self._trim: self.trim = trim if precision is not None: @@ -215,7 +215,7 @@ class WKBWriter(IOBase): destructor = wkb_writer_destroy def __init__(self, dim=2): - super(WKBWriter, self).__init__() + super().__init__() self.outdim = dim def _handle_empty_point(self, geom): diff --git a/django/contrib/gis/geos/prototypes/misc.py b/django/contrib/gis/geos/prototypes/misc.py index 2d890c3d3161..1f809ebe708f 100644 --- a/django/contrib/gis/geos/prototypes/misc.py +++ b/django/contrib/gis/geos/prototypes/misc.py @@ -23,7 +23,7 @@ def get_func(self, num_geom=1): argtypes = [GEOM_PTR for i in range(num_geom)] argtypes += [POINTER(c_double)] self.argtypes = argtypes - return super(DblFromGeom, self).get_func() + return super().get_func() # ### ctypes prototypes ### diff --git a/django/contrib/gis/management/commands/inspectdb.py b/django/contrib/gis/management/commands/inspectdb.py index 27345c59d464..012ca14fed9b 100644 --- a/django/contrib/gis/management/commands/inspectdb.py +++ b/django/contrib/gis/management/commands/inspectdb.py @@ -6,7 +6,7 @@ class Command(InspectDBCommand): db_module = 'django.contrib.gis.db' def get_field_type(self, connection, table_name, row): - field_type, field_params, field_notes = super(Command, self).get_field_type(connection, table_name, row) + field_type, field_params, field_notes = super().get_field_type(connection, table_name, row) if field_type == 'GeometryField': geo_col = row[0] # Getting a more specific field type and any additional parameters diff --git a/django/contrib/gis/serializers/geojson.py b/django/contrib/gis/serializers/geojson.py index 3a4c0c87bf55..fe3a32871ff5 100644 --- a/django/contrib/gis/serializers/geojson.py +++ b/django/contrib/gis/serializers/geojson.py @@ -11,7 +11,7 @@ class Serializer(JSONSerializer): Convert a queryset to GeoJSON, http://geojson.org/ """ def _init_options(self): - super(Serializer, self)._init_options() + super()._init_options() self.geometry_field = self.json_kwargs.pop('geometry_field', None) self.srid = self.json_kwargs.pop('srid', 4326) if (self.selected_fields is not None and self.geometry_field is not None and @@ -29,7 +29,7 @@ def end_serialization(self): self.stream.write(']}') def start_object(self, obj): - super(Serializer, self).start_object(obj) + super().start_object(obj) self._geometry = None if self.geometry_field is None: # Find the first declared geometry field @@ -62,7 +62,7 @@ def handle_field(self, obj, field): if field.name == self.geometry_field: self._geometry = field.value_from_object(obj) else: - super(Serializer, self).handle_field(obj, field) + super().handle_field(obj, field) class Deserializer: diff --git a/django/contrib/messages/storage/base.py b/django/contrib/messages/storage/base.py index 28c81599a783..2e67c84f4ad6 100644 --- a/django/contrib/messages/storage/base.py +++ b/django/contrib/messages/storage/base.py @@ -64,7 +64,7 @@ def __init__(self, request, *args, **kwargs): self._queued_messages = [] self.used = False self.added_new = False - super(BaseStorage, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def __len__(self): return len(self._loaded_messages) + len(self._queued_messages) diff --git a/django/contrib/messages/storage/cookie.py b/django/contrib/messages/storage/cookie.py index b8d7f7474c8d..353dc12761e1 100644 --- a/django/contrib/messages/storage/cookie.py +++ b/django/contrib/messages/storage/cookie.py @@ -21,7 +21,7 @@ def default(self, obj): if obj.extra_tags: message.append(obj.extra_tags) return message - return super(MessageEncoder, self).default(obj) + return super().default(obj) class MessageDecoder(json.JSONDecoder): @@ -45,7 +45,7 @@ def process_messages(self, obj): return obj def decode(self, s, **kwargs): - decoded = super(MessageDecoder, self).decode(s, **kwargs) + decoded = super().decode(s, **kwargs) return self.process_messages(decoded) diff --git a/django/contrib/messages/storage/fallback.py b/django/contrib/messages/storage/fallback.py index 24dd6561d06f..d599833dc1f6 100644 --- a/django/contrib/messages/storage/fallback.py +++ b/django/contrib/messages/storage/fallback.py @@ -11,7 +11,7 @@ class FallbackStorage(BaseStorage): storage_classes = (CookieStorage, SessionStorage) def __init__(self, *args, **kwargs): - super(FallbackStorage, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.storages = [storage_class(*args, **kwargs) for storage_class in self.storage_classes] self._used_storages = set() diff --git a/django/contrib/messages/storage/session.py b/django/contrib/messages/storage/session.py index 2eb8024bfa08..ca859a35a095 100644 --- a/django/contrib/messages/storage/session.py +++ b/django/contrib/messages/storage/session.py @@ -18,7 +18,7 @@ def __init__(self, request, *args, **kwargs): "message storage requires session middleware to be installed, "\ "and come before the message middleware in the "\ "MIDDLEWARE%s list." % ("_CLASSES" if settings.MIDDLEWARE is None else "") - super(SessionStorage, self).__init__(request, *args, **kwargs) + super().__init__(request, *args, **kwargs) def _get(self, *args, **kwargs): """ diff --git a/django/contrib/messages/views.py b/django/contrib/messages/views.py index adb3f194b9fb..246340edb299 100644 --- a/django/contrib/messages/views.py +++ b/django/contrib/messages/views.py @@ -8,7 +8,7 @@ class SuccessMessageMixin: success_message = '' def form_valid(self, form): - response = super(SuccessMessageMixin, self).form_valid(form) + response = super().form_valid(form) success_message = self.get_success_message(form.cleaned_data) if success_message: messages.success(self.request, success_message) diff --git a/django/contrib/postgres/aggregates/general.py b/django/contrib/postgres/aggregates/general.py index 5b3d22bf9817..ac18a516d6c1 100644 --- a/django/contrib/postgres/aggregates/general.py +++ b/django/contrib/postgres/aggregates/general.py @@ -47,7 +47,7 @@ class StringAgg(Aggregate): def __init__(self, expression, delimiter, distinct=False, **extra): distinct = 'DISTINCT ' if distinct else '' - super(StringAgg, self).__init__(expression, delimiter=delimiter, distinct=distinct, **extra) + super().__init__(expression, delimiter=delimiter, distinct=distinct, **extra) def convert_value(self, value, expression, connection, context): if not value: diff --git a/django/contrib/postgres/aggregates/statistics.py b/django/contrib/postgres/aggregates/statistics.py index 89949580be0f..2af5b6b3590a 100644 --- a/django/contrib/postgres/aggregates/statistics.py +++ b/django/contrib/postgres/aggregates/statistics.py @@ -11,7 +11,7 @@ class StatAggregate(Aggregate): def __init__(self, y, x, output_field=FloatField()): if not x or not y: raise ValueError('Both y and x must be provided.') - super(StatAggregate, self).__init__(y=y, x=x, output_field=output_field) + super().__init__(y=y, x=x, output_field=output_field) self.x = x self.y = y self.source_expressions = self._parse_expressions(self.y, self.x) @@ -23,7 +23,7 @@ def set_source_expressions(self, exprs): self.y, self.x = exprs def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False): - return super(Aggregate, self).resolve_expression(query, allow_joins, reuse, summarize) + return super().resolve_expression(query, allow_joins, reuse, summarize) class Corr(StatAggregate): @@ -33,7 +33,7 @@ class Corr(StatAggregate): class CovarPop(StatAggregate): def __init__(self, y, x, sample=False): self.function = 'COVAR_SAMP' if sample else 'COVAR_POP' - super(CovarPop, self).__init__(y, x) + super().__init__(y, x) class RegrAvgX(StatAggregate): @@ -48,7 +48,7 @@ class RegrCount(StatAggregate): function = 'REGR_COUNT' def __init__(self, y, x): - super(RegrCount, self).__init__(y=y, x=x, output_field=IntegerField()) + super().__init__(y=y, x=x, output_field=IntegerField()) def convert_value(self, value, expression, connection, context): if value is None: diff --git a/django/contrib/postgres/fields/array.py b/django/contrib/postgres/fields/array.py index ce4c7b8c3d07..15cbf5e45e8b 100644 --- a/django/contrib/postgres/fields/array.py +++ b/django/contrib/postgres/fields/array.py @@ -31,7 +31,7 @@ def __init__(self, base_field, size=None, **kwargs): # implements it. if hasattr(self.base_field, 'from_db_value'): self.from_db_value = self._from_db_value - super(ArrayField, self).__init__(**kwargs) + super().__init__(**kwargs) @property def model(self): @@ -46,7 +46,7 @@ def model(self, model): self.base_field.model = model def check(self, **kwargs): - errors = super(ArrayField, self).check(**kwargs) + errors = super().check(**kwargs) if self.base_field.remote_field: errors.append( checks.Error( @@ -70,7 +70,7 @@ def check(self, **kwargs): return errors def set_attributes_from_name(self, name): - super(ArrayField, self).set_attributes_from_name(name) + super().set_attributes_from_name(name) self.base_field.set_attributes_from_name(name) @property @@ -87,7 +87,7 @@ def get_db_prep_value(self, value, connection, prepared=False): return value def deconstruct(self): - name, path, args, kwargs = super(ArrayField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() if path == 'django.contrib.postgres.fields.array.ArrayField': path = 'django.contrib.postgres.fields.ArrayField' kwargs.update({ @@ -125,7 +125,7 @@ def value_to_string(self, obj): return json.dumps(values) def get_transform(self, name): - transform = super(ArrayField, self).get_transform(name) + transform = super().get_transform(name) if transform: return transform if '_' not in name: @@ -146,7 +146,7 @@ def get_transform(self, name): return SliceTransformFactory(start, end) def validate(self, value, model_instance): - super(ArrayField, self).validate(value, model_instance) + super().validate(value, model_instance) for index, part in enumerate(value): try: self.base_field.validate(part, model_instance) @@ -165,7 +165,7 @@ def validate(self, value, model_instance): ) def run_validators(self, value): - super(ArrayField, self).run_validators(value) + super().run_validators(value) for index, part in enumerate(value): try: self.base_field.run_validators(part) @@ -184,13 +184,13 @@ def formfield(self, **kwargs): 'max_length': self.size, } defaults.update(kwargs) - return super(ArrayField, self).formfield(**defaults) + return super().formfield(**defaults) @ArrayField.register_lookup class ArrayContains(lookups.DataContains): def as_sql(self, qn, connection): - sql, params = super(ArrayContains, self).as_sql(qn, connection) + sql, params = super().as_sql(qn, connection) sql = '%s::%s' % (sql, self.lhs.output_field.db_type(connection)) return sql, params @@ -198,7 +198,7 @@ def as_sql(self, qn, connection): @ArrayField.register_lookup class ArrayContainedBy(lookups.ContainedBy): def as_sql(self, qn, connection): - sql, params = super(ArrayContainedBy, self).as_sql(qn, connection) + sql, params = super().as_sql(qn, connection) sql = '%s::%s' % (sql, self.lhs.output_field.db_type(connection)) return sql, params @@ -206,7 +206,7 @@ def as_sql(self, qn, connection): @ArrayField.register_lookup class ArrayExact(Exact): def as_sql(self, qn, connection): - sql, params = super(ArrayExact, self).as_sql(qn, connection) + sql, params = super().as_sql(qn, connection) sql = '%s::%s' % (sql, self.lhs.output_field.db_type(connection)) return sql, params @@ -214,7 +214,7 @@ def as_sql(self, qn, connection): @ArrayField.register_lookup class ArrayOverlap(lookups.Overlap): def as_sql(self, qn, connection): - sql, params = super(ArrayOverlap, self).as_sql(qn, connection) + sql, params = super().as_sql(qn, connection) sql = '%s::%s' % (sql, self.lhs.output_field.db_type(connection)) return sql, params @@ -236,7 +236,7 @@ def as_sql(self, compiler, connection): @ArrayField.register_lookup class ArrayInLookup(In): def get_prep_lookup(self): - values = super(ArrayInLookup, self).get_prep_lookup() + values = super().get_prep_lookup() # In.process_rhs() expects values to be hashable, so convert lists # to tuples. prepared_values = [] @@ -251,7 +251,7 @@ def get_prep_lookup(self): class IndexTransform(Transform): def __init__(self, index, base_field, *args, **kwargs): - super(IndexTransform, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.index = index self.base_field = base_field @@ -277,7 +277,7 @@ def __call__(self, *args, **kwargs): class SliceTransform(Transform): def __init__(self, start, end, *args, **kwargs): - super(SliceTransform, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.start = start self.end = end diff --git a/django/contrib/postgres/fields/hstore.py b/django/contrib/postgres/fields/hstore.py index 5e2e6c3155dc..28b7c19c7de6 100644 --- a/django/contrib/postgres/fields/hstore.py +++ b/django/contrib/postgres/fields/hstore.py @@ -21,13 +21,13 @@ def db_type(self, connection): return 'hstore' def get_transform(self, name): - transform = super(HStoreField, self).get_transform(name) + transform = super().get_transform(name) if transform: return transform return KeyTransformFactory(name) def validate(self, value, model_instance): - super(HStoreField, self).validate(value, model_instance) + super().validate(value, model_instance) for key, val in value.items(): if not isinstance(val, str) and val is not None: raise exceptions.ValidationError( @@ -49,10 +49,10 @@ def formfield(self, **kwargs): 'form_class': forms.HStoreField, } defaults.update(kwargs) - return super(HStoreField, self).formfield(**defaults) + return super().formfield(**defaults) def get_prep_value(self, value): - value = super(HStoreField, self).get_prep_value(value) + value = super().get_prep_value(value) if isinstance(value, dict): prep_value = {} @@ -80,7 +80,7 @@ class KeyTransform(Transform): output_field = TextField() def __init__(self, key_name, *args, **kwargs): - super(KeyTransform, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.key_name = key_name def as_sql(self, compiler, connection): diff --git a/django/contrib/postgres/fields/jsonb.py b/django/contrib/postgres/fields/jsonb.py index 43997050feed..0bb6e7bed1f7 100644 --- a/django/contrib/postgres/fields/jsonb.py +++ b/django/contrib/postgres/fields/jsonb.py @@ -18,7 +18,7 @@ class JsonAdapter(Json): """ def __init__(self, adapted, dumps=None, encoder=None): self.encoder = encoder - super(JsonAdapter, self).__init__(adapted, dumps=dumps) + super().__init__(adapted, dumps=dumps) def dumps(self, obj): options = {'cls': self.encoder} if self.encoder else {} @@ -36,19 +36,19 @@ def __init__(self, verbose_name=None, name=None, encoder=None, **kwargs): if encoder and not callable(encoder): raise ValueError("The encoder parameter must be a callable object.") self.encoder = encoder - super(JSONField, self).__init__(verbose_name, name, **kwargs) + super().__init__(verbose_name, name, **kwargs) def db_type(self, connection): return 'jsonb' def deconstruct(self): - name, path, args, kwargs = super(JSONField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() if self.encoder is not None: kwargs['encoder'] = self.encoder return name, path, args, kwargs def get_transform(self, name): - transform = super(JSONField, self).get_transform(name) + transform = super().get_transform(name) if transform: return transform return KeyTransformFactory(name) @@ -59,7 +59,7 @@ def get_prep_value(self, value): return value def validate(self, value, model_instance): - super(JSONField, self).validate(value, model_instance) + super().validate(value, model_instance) options = {'cls': self.encoder} if self.encoder else {} try: json.dumps(value, **options) @@ -76,7 +76,7 @@ def value_to_string(self, obj): def formfield(self, **kwargs): defaults = {'form_class': forms.JSONField} defaults.update(kwargs) - return super(JSONField, self).formfield(**defaults) + return super().formfield(**defaults) JSONField.register_lookup(lookups.DataContains) @@ -91,7 +91,7 @@ class KeyTransform(Transform): nested_operator = '#>' def __init__(self, key_name, *args, **kwargs): - super(KeyTransform, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.key_name = key_name def as_sql(self, compiler, connection): @@ -129,7 +129,7 @@ def __init__(self, key_transform, *args, **kwargs): key_text_transform = KeyTextTransform( key_transform.key_name, *key_transform.source_expressions, **key_transform.extra ) - super(KeyTransformTextLookupMixin, self).__init__(key_text_transform, *args, **kwargs) + super().__init__(key_text_transform, *args, **kwargs) class KeyTransformIExact(KeyTransformTextLookupMixin, builtin_lookups.IExact): diff --git a/django/contrib/postgres/fields/ranges.py b/django/contrib/postgres/fields/ranges.py index 840417a58f96..41acc8dcb260 100644 --- a/django/contrib/postgres/fields/ranges.py +++ b/django/contrib/postgres/fields/ranges.py @@ -20,7 +20,7 @@ def __init__(self, *args, **kwargs): # Initializing base_field here ensures that its model matches the model for self. if hasattr(self, 'base_field'): self.base_field = self.base_field() - super(RangeField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) @property def model(self): @@ -56,7 +56,7 @@ def to_python(self, value): return value def set_attributes_from_name(self, name): - super(RangeField, self).set_attributes_from_name(name) + super().set_attributes_from_name(name) self.base_field.set_attributes_from_name(name) def value_to_string(self, obj): @@ -78,7 +78,7 @@ def value_to_string(self, obj): def formfield(self, **kwargs): kwargs.setdefault('form_class', self.form_field) - return super(RangeField, self).formfield(**kwargs) + return super().formfield(**kwargs) class IntegerRangeField(RangeField): diff --git a/django/contrib/postgres/forms/array.py b/django/contrib/postgres/forms/array.py index 9a9e871a438d..d9d864e4f2c1 100644 --- a/django/contrib/postgres/forms/array.py +++ b/django/contrib/postgres/forms/array.py @@ -20,7 +20,7 @@ class SimpleArrayField(forms.CharField): def __init__(self, base_field, delimiter=',', max_length=None, min_length=None, *args, **kwargs): self.base_field = base_field self.delimiter = delimiter - super(SimpleArrayField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) if min_length is not None: self.min_length = min_length self.validators.append(ArrayMinLengthValidator(int(min_length))) @@ -57,7 +57,7 @@ def to_python(self, value): return values def validate(self, value): - super(SimpleArrayField, self).validate(value) + super().validate(value) errors = [] for index, item in enumerate(value): try: @@ -73,7 +73,7 @@ def validate(self, value): raise ValidationError(errors) def run_validators(self, value): - super(SimpleArrayField, self).run_validators(value) + super().run_validators(value) errors = [] for index, item in enumerate(value): try: @@ -94,7 +94,7 @@ class SplitArrayWidget(forms.Widget): def __init__(self, widget, size, **kwargs): self.widget = widget() if isinstance(widget, type) else widget self.size = size - super(SplitArrayWidget, self).__init__(**kwargs) + super().__init__(**kwargs) @property def is_hidden(self): @@ -141,7 +141,7 @@ def media(self): return self.widget.media def __deepcopy__(self, memo): - obj = super(SplitArrayWidget, self).__deepcopy__(memo) + obj = super().__deepcopy__(memo) obj.widget = copy.deepcopy(self.widget) return obj @@ -161,7 +161,7 @@ def __init__(self, base_field, size, remove_trailing_nulls=False, **kwargs): self.remove_trailing_nulls = remove_trailing_nulls widget = SplitArrayWidget(widget=base_field.widget, size=size) kwargs.setdefault('widget', widget) - super(SplitArrayField, self).__init__(**kwargs) + super().__init__(**kwargs) def clean(self, value): cleaned_data = [] diff --git a/django/contrib/postgres/forms/hstore.py b/django/contrib/postgres/forms/hstore.py index 25dceb9fb015..7e046ead37ee 100644 --- a/django/contrib/postgres/forms/hstore.py +++ b/django/contrib/postgres/forms/hstore.py @@ -55,4 +55,4 @@ def has_changed(self, initial, data): # the same as an empty dict, if the data or initial value we get # is None, replace it w/ {}. initial_value = self.to_python(initial) - return super(HStoreField, self).has_changed(initial_value, data) + return super().has_changed(initial_value, data) diff --git a/django/contrib/postgres/forms/ranges.py b/django/contrib/postgres/forms/ranges.py index 9ed95cd7c5fc..5be166f7d0c0 100644 --- a/django/contrib/postgres/forms/ranges.py +++ b/django/contrib/postgres/forms/ranges.py @@ -21,7 +21,7 @@ def __init__(self, **kwargs): kwargs['fields'] = [self.base_field(required=False), self.base_field(required=False)] kwargs.setdefault('required', False) kwargs.setdefault('require_all_fields', False) - super(BaseRangeField, self).__init__(**kwargs) + super().__init__(**kwargs) def prepare_value(self, value): lower_base, upper_base = self.fields @@ -84,7 +84,7 @@ class DateRangeField(BaseRangeField): class RangeWidget(MultiWidget): def __init__(self, base_widget, attrs=None): widgets = (base_widget, base_widget) - super(RangeWidget, self).__init__(widgets, attrs) + super().__init__(widgets, attrs) def decompress(self, value): if value: diff --git a/django/contrib/postgres/functions.py b/django/contrib/postgres/functions.py index fc0dae8ece91..d17f9cb37d59 100644 --- a/django/contrib/postgres/functions.py +++ b/django/contrib/postgres/functions.py @@ -7,4 +7,4 @@ class TransactionNow(Func): def __init__(self, output_field=None, **extra): if output_field is None: output_field = DateTimeField() - super(TransactionNow, self).__init__(output_field=output_field, **extra) + super().__init__(output_field=output_field, **extra) diff --git a/django/contrib/postgres/indexes.py b/django/contrib/postgres/indexes.py index 2edec371f4fd..60578e6c1619 100644 --- a/django/contrib/postgres/indexes.py +++ b/django/contrib/postgres/indexes.py @@ -10,7 +10,7 @@ def __init__(self, fields=[], name=None, pages_per_range=None): if pages_per_range is not None and pages_per_range <= 0: raise ValueError('pages_per_range must be None or a positive integer') self.pages_per_range = pages_per_range - super(BrinIndex, self).__init__(fields, name) + super().__init__(fields, name) def __repr__(self): if self.pages_per_range is not None: @@ -20,15 +20,15 @@ def __repr__(self): 'pages_per_range': self.pages_per_range, } else: - return super(BrinIndex, self).__repr__() + return super().__repr__() def deconstruct(self): - path, args, kwargs = super(BrinIndex, self).deconstruct() + path, args, kwargs = super().deconstruct() kwargs['pages_per_range'] = self.pages_per_range return path, args, kwargs def get_sql_create_template_values(self, model, schema_editor, using): - parameters = super(BrinIndex, self).get_sql_create_template_values(model, schema_editor, using=' USING brin') + parameters = super().get_sql_create_template_values(model, schema_editor, using=' USING brin') if self.pages_per_range is not None: parameters['extra'] = ' WITH (pages_per_range={})'.format( schema_editor.quote_value(self.pages_per_range)) + parameters['extra'] @@ -39,4 +39,4 @@ class GinIndex(Index): suffix = 'gin' def create_sql(self, model, schema_editor): - return super(GinIndex, self).create_sql(model, schema_editor, using=' USING gin') + return super().create_sql(model, schema_editor, using=' USING gin') diff --git a/django/contrib/postgres/lookups.py b/django/contrib/postgres/lookups.py index 53a62eacd16f..8521b26c6e19 100644 --- a/django/contrib/postgres/lookups.py +++ b/django/contrib/postgres/lookups.py @@ -58,7 +58,7 @@ class SearchLookup(SearchVectorExact): def process_lhs(self, qn, connection): if not isinstance(self.lhs.output_field, SearchVectorField): self.lhs = SearchVector(self.lhs) - lhs, lhs_params = super(SearchLookup, self).process_lhs(qn, connection) + lhs, lhs_params = super().process_lhs(qn, connection) return lhs, lhs_params diff --git a/django/contrib/postgres/operations.py b/django/contrib/postgres/operations.py index cb45d4f705ed..7544e386137c 100644 --- a/django/contrib/postgres/operations.py +++ b/django/contrib/postgres/operations.py @@ -41,7 +41,7 @@ def __init__(self): self.name = 'hstore' def database_forwards(self, app_label, schema_editor, from_state, to_state): - super(HStoreExtension, self).database_forwards(app_label, schema_editor, from_state, to_state) + super().database_forwards(app_label, schema_editor, from_state, to_state) # Register hstore straight away as it cannot be done before the # extension is installed, a subsequent data migration would use the # same connection diff --git a/django/contrib/postgres/search.py b/django/contrib/postgres/search.py index bc9bb1052bd3..9a773db1d548 100644 --- a/django/contrib/postgres/search.py +++ b/django/contrib/postgres/search.py @@ -11,7 +11,7 @@ def process_rhs(self, qn, connection): if not hasattr(self.rhs, 'resolve_expression'): config = getattr(self.lhs, 'config', None) self.rhs = SearchQuery(self.rhs, config=config) - rhs, rhs_params = super(SearchVectorExact, self).process_rhs(qn, connection) + rhs, rhs_params = super().process_rhs(qn, connection) return rhs, rhs_params def as_sql(self, qn, connection): @@ -51,7 +51,7 @@ class SearchVector(SearchVectorCombinable, Func): config = None def __init__(self, *expressions, **extra): - super(SearchVector, self).__init__(*expressions, **extra) + super().__init__(*expressions, **extra) self.source_expressions = [ Coalesce(expression, Value('')) for expression in self.source_expressions ] @@ -62,7 +62,7 @@ def __init__(self, *expressions, **extra): self.weight = weight def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False): - resolved = super(SearchVector, self).resolve_expression(query, allow_joins, reuse, summarize, for_save) + resolved = super().resolve_expression(query, allow_joins, reuse, summarize, for_save) if self.config: if not hasattr(self.config, 'resolve_expression'): resolved.config = Value(self.config).resolve_expression(query, allow_joins, reuse, summarize, for_save) @@ -78,7 +78,7 @@ def as_sql(self, compiler, connection, function=None, template=None): template = "%(function)s({}::regconfig, %(expressions)s)".format(config_sql.replace('%', '%%')) else: template = self.template - sql, params = super(SearchVector, self).as_sql(compiler, connection, function=function, template=template) + sql, params = super().as_sql(compiler, connection, function=function, template=template) extra_params = [] if self.weight: weight_sql, extra_params = compiler.compile(self.weight) @@ -89,7 +89,7 @@ def as_sql(self, compiler, connection, function=None, template=None): class CombinedSearchVector(SearchVectorCombinable, CombinedExpression): def __init__(self, lhs, connector, rhs, config, output_field=None): self.config = config - super(CombinedSearchVector, self).__init__(lhs, connector, rhs, output_field) + super().__init__(lhs, connector, rhs, output_field) class SearchQueryCombinable: @@ -132,10 +132,10 @@ class SearchQuery(SearchQueryCombinable, Value): def __init__(self, value, output_field=None, **extra): self.config = extra.pop('config', self.config) self.invert = extra.pop('invert', self.invert) - super(SearchQuery, self).__init__(value, output_field=output_field) + super().__init__(value, output_field=output_field) def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False): - resolved = super(SearchQuery, self).resolve_expression(query, allow_joins, reuse, summarize, for_save) + resolved = super().resolve_expression(query, allow_joins, reuse, summarize, for_save) if self.config: if not hasattr(self.config, 'resolve_expression'): resolved.config = Value(self.config).resolve_expression(query, allow_joins, reuse, summarize, for_save) @@ -156,7 +156,7 @@ def as_sql(self, compiler, connection): return template, params def _combine(self, other, connector, reversed, node=None): - combined = super(SearchQuery, self)._combine(other, connector, reversed, node) + combined = super()._combine(other, connector, reversed, node) combined.output_field = SearchQueryField() return combined @@ -171,7 +171,7 @@ def __invert__(self): class CombinedSearchQuery(SearchQueryCombinable, CombinedExpression): def __init__(self, lhs, connector, rhs, config, output_field=None): self.config = config - super(CombinedSearchQuery, self).__init__(lhs, connector, rhs, output_field) + super().__init__(lhs, connector, rhs, output_field) class SearchRank(Func): @@ -187,7 +187,7 @@ def __init__(self, vector, query, **extra): if weights is not None and not hasattr(weights, 'resolve_expression'): weights = Value(weights) self.weights = weights - super(SearchRank, self).__init__(vector, query, **extra) + super().__init__(vector, query, **extra) def as_sql(self, compiler, connection, function=None, template=None): extra_params = [] @@ -197,7 +197,7 @@ def as_sql(self, compiler, connection, function=None, template=None): template = '%(function)s(%(weights)s, %(expressions)s)' weight_sql, extra_params = compiler.compile(self.weights) extra_context['weights'] = weight_sql - sql, params = super(SearchRank, self).as_sql( + sql, params = super().as_sql( compiler, connection, function=function, template=template, **extra_context ) @@ -211,7 +211,7 @@ class TrigramBase(Func): def __init__(self, expression, string, **extra): if not hasattr(string, 'resolve_expression'): string = Value(string) - super(TrigramBase, self).__init__(expression, string, output_field=FloatField(), **extra) + super().__init__(expression, string, output_field=FloatField(), **extra) class TrigramSimilarity(TrigramBase): diff --git a/django/contrib/redirects/middleware.py b/django/contrib/redirects/middleware.py index 317dca3fd25f..8bf4e26ec843 100644 --- a/django/contrib/redirects/middleware.py +++ b/django/contrib/redirects/middleware.py @@ -18,7 +18,7 @@ def __init__(self, get_response=None): "You cannot use RedirectFallbackMiddleware when " "django.contrib.sites is not installed." ) - super(RedirectFallbackMiddleware, self).__init__(get_response) + super().__init__(get_response) def process_response(self, request, response): # No need to check for a redirect for non-404 responses. diff --git a/django/contrib/sessions/backends/cache.py b/django/contrib/sessions/backends/cache.py index c64d7f6a6ced..c0d17ca45a60 100644 --- a/django/contrib/sessions/backends/cache.py +++ b/django/contrib/sessions/backends/cache.py @@ -15,7 +15,7 @@ class SessionStore(SessionBase): def __init__(self, session_key=None): self._cache = caches[settings.SESSION_CACHE_ALIAS] - super(SessionStore, self).__init__(session_key) + super().__init__(session_key) @property def cache_key(self): diff --git a/django/contrib/sessions/backends/cached_db.py b/django/contrib/sessions/backends/cached_db.py index 3f33e78c896d..f830e072e7a4 100644 --- a/django/contrib/sessions/backends/cached_db.py +++ b/django/contrib/sessions/backends/cached_db.py @@ -22,7 +22,7 @@ class SessionStore(DBStore): def __init__(self, session_key=None): self._cache = caches[settings.SESSION_CACHE_ALIAS] - super(SessionStore, self).__init__(session_key) + super().__init__(session_key) @property def cache_key(self): @@ -57,14 +57,14 @@ def load(self): def exists(self, session_key): if session_key and (self.cache_key_prefix + session_key) in self._cache: return True - return super(SessionStore, self).exists(session_key) + return super().exists(session_key) def save(self, must_create=False): - super(SessionStore, self).save(must_create) + super().save(must_create) self._cache.set(self.cache_key, self._session, self.get_expiry_age()) def delete(self, session_key=None): - super(SessionStore, self).delete(session_key) + super().delete(session_key) if session_key is None: if self.session_key is None: return diff --git a/django/contrib/sessions/backends/db.py b/django/contrib/sessions/backends/db.py index 95c2f0d2250d..a345e7515751 100644 --- a/django/contrib/sessions/backends/db.py +++ b/django/contrib/sessions/backends/db.py @@ -15,7 +15,7 @@ class SessionStore(SessionBase): Implements database session store. """ def __init__(self, session_key=None): - super(SessionStore, self).__init__(session_key) + super().__init__(session_key) @classmethod def get_model_class(cls): diff --git a/django/contrib/sessions/backends/file.py b/django/contrib/sessions/backends/file.py index 83baa35ef29b..fab83530ca1f 100644 --- a/django/contrib/sessions/backends/file.py +++ b/django/contrib/sessions/backends/file.py @@ -21,7 +21,7 @@ class SessionStore(SessionBase): def __init__(self, session_key=None): self.storage_path = type(self)._get_storage_path() self.file_prefix = settings.SESSION_COOKIE_NAME - super(SessionStore, self).__init__(session_key) + super().__init__(session_key) @classmethod def _get_storage_path(cls): diff --git a/django/contrib/sites/managers.py b/django/contrib/sites/managers.py index 52f91a51ea39..91c034e96712 100644 --- a/django/contrib/sites/managers.py +++ b/django/contrib/sites/managers.py @@ -10,11 +10,11 @@ class CurrentSiteManager(models.Manager): use_in_migrations = True def __init__(self, field_name=None): - super(CurrentSiteManager, self).__init__() + super().__init__() self.__field_name = field_name def check(self, **kwargs): - errors = super(CurrentSiteManager, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_field_name()) return errors @@ -57,5 +57,4 @@ def _get_field_name(self): return self.__field_name def get_queryset(self): - return super(CurrentSiteManager, self).get_queryset().filter( - **{self._get_field_name() + '__id': settings.SITE_ID}) + return super().get_queryset().filter(**{self._get_field_name() + '__id': settings.SITE_ID}) diff --git a/django/contrib/staticfiles/finders.py b/django/contrib/staticfiles/finders.py index 08b25181bcef..fcb31c854722 100644 --- a/django/contrib/staticfiles/finders.py +++ b/django/contrib/staticfiles/finders.py @@ -71,7 +71,7 @@ def __init__(self, app_names=None, *args, **kwargs): filesystem_storage = FileSystemStorage(location=root) filesystem_storage.prefix = prefix self.storages[root] = filesystem_storage - super(FileSystemFinder, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def find(self, path, all=False): """ @@ -137,7 +137,7 @@ def __init__(self, app_names=None, *args, **kwargs): self.storages[app_config.name] = app_storage if app_config.name not in self.apps: self.apps.append(app_config.name) - super(AppDirectoriesFinder, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def list(self, ignore_patterns): """ @@ -194,7 +194,7 @@ def __init__(self, storage=None, *args, **kwargs): # Make sure we have an storage instance here. if not isinstance(self.storage, (Storage, LazyObject)): self.storage = self.storage() - super(BaseStorageFinder, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def find(self, path, all=False): """ @@ -229,7 +229,7 @@ class DefaultStorageFinder(BaseStorageFinder): storage = default_storage def __init__(self, *args, **kwargs): - super(DefaultStorageFinder, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) base_location = getattr(self.storage, 'base_location', empty) if not base_location: raise ImproperlyConfigured("The storage backend of the " diff --git a/django/contrib/staticfiles/handlers.py b/django/contrib/staticfiles/handlers.py index ce8b7e20c179..91b66d7a39bc 100644 --- a/django/contrib/staticfiles/handlers.py +++ b/django/contrib/staticfiles/handlers.py @@ -19,7 +19,7 @@ class StaticFilesHandler(WSGIHandler): def __init__(self, application): self.application = application self.base_url = urlparse(self.get_base_url()) - super(StaticFilesHandler, self).__init__() + super().__init__() def get_base_url(self): utils.check_settings() @@ -57,9 +57,9 @@ def get_response(self, request): if settings.DEBUG: from django.views import debug return debug.technical_404_response(request, e) - return super(StaticFilesHandler, self).get_response(request) + return super().get_response(request) def __call__(self, environ, start_response): if not self._should_handle(get_path_info(environ)): return self.application(environ, start_response) - return super(StaticFilesHandler, self).__call__(environ, start_response) + return super().__call__(environ, start_response) diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py index 3ee6d354afcd..6fdb797e5e22 100644 --- a/django/contrib/staticfiles/management/commands/collectstatic.py +++ b/django/contrib/staticfiles/management/commands/collectstatic.py @@ -20,7 +20,7 @@ class Command(BaseCommand): requires_system_checks = False def __init__(self, *args, **kwargs): - super(Command, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.copied_files = [] self.symlinked_files = [] self.unmodified_files = [] diff --git a/django/contrib/staticfiles/management/commands/findstatic.py b/django/contrib/staticfiles/management/commands/findstatic.py index 992dae17697a..067b229f6df8 100644 --- a/django/contrib/staticfiles/management/commands/findstatic.py +++ b/django/contrib/staticfiles/management/commands/findstatic.py @@ -10,7 +10,7 @@ class Command(LabelCommand): label = 'staticfile' def add_arguments(self, parser): - super(Command, self).add_arguments(parser) + super().add_arguments(parser) parser.add_argument( '--first', action='store_false', dest='all', default=True, diff --git a/django/contrib/staticfiles/management/commands/runserver.py b/django/contrib/staticfiles/management/commands/runserver.py index c25ac1f36952..9146a12385a5 100644 --- a/django/contrib/staticfiles/management/commands/runserver.py +++ b/django/contrib/staticfiles/management/commands/runserver.py @@ -8,7 +8,7 @@ class Command(RunserverCommand): help = "Starts a lightweight Web server for development and also serves static files." def add_arguments(self, parser): - super(Command, self).add_arguments(parser) + super().add_arguments(parser) parser.add_argument( '--nostatic', action="store_false", dest='use_static_handler', default=True, help='Tells Django to NOT automatically serve static files at STATIC_URL.', @@ -24,7 +24,7 @@ def get_handler(self, *args, **options): if static files should be served. Otherwise just returns the default handler. """ - handler = super(Command, self).get_handler(*args, **options) + handler = super().get_handler(*args, **options) use_static_handler = options['use_static_handler'] insecure_serving = options['insecure_serving'] if use_static_handler and (settings.DEBUG or insecure_serving): diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py index 46b751b09409..6648d2c7053e 100644 --- a/django/contrib/staticfiles/storage.py +++ b/django/contrib/staticfiles/storage.py @@ -31,8 +31,7 @@ def __init__(self, location=None, base_url=None, *args, **kwargs): if base_url is None: base_url = settings.STATIC_URL check_settings(base_url) - super(StaticFilesStorage, self).__init__(location, base_url, - *args, **kwargs) + super().__init__(location, base_url, *args, **kwargs) # FileSystemStorage fallbacks to MEDIA_ROOT when location # is empty, so we restore the empty value. if not location: @@ -44,7 +43,7 @@ def path(self, name): raise ImproperlyConfigured("You're using the staticfiles app " "without having set the STATIC_ROOT " "setting to a filesystem path.") - return super(StaticFilesStorage, self).path(name) + return super().path(name) class HashedFilesMixin: @@ -58,7 +57,7 @@ class HashedFilesMixin: ) def __init__(self, *args, **kwargs): - super(HashedFilesMixin, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self._patterns = OrderedDict() self.hashed_files = {} for extension, patterns in self.patterns: @@ -134,7 +133,7 @@ def _url(self, hashed_name_func, name, force=False, hashed_files=None): args += (hashed_files,) hashed_name = hashed_name_func(*args) - final_url = super(HashedFilesMixin, self).url(hashed_name) + final_url = super().url(hashed_name) # Special casing for a @font-face hack, like url(myfont.eot?#iefix") # http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax @@ -376,7 +375,7 @@ class ManifestFilesMixin(HashedFilesMixin): manifest_strict = True def __init__(self, *args, **kwargs): - super(ManifestFilesMixin, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.hashed_files = self.load_manifest() def read_manifest(self): @@ -403,8 +402,7 @@ def load_manifest(self): def post_process(self, *args, **kwargs): self.hashed_files = OrderedDict() - all_post_processed = super(ManifestFilesMixin, - self).post_process(*args, **kwargs) + all_post_processed = super().post_process(*args, **kwargs) for post_processed in all_post_processed: yield post_processed self.save_manifest() @@ -465,7 +463,7 @@ def get(self, key, default=None): class CachedFilesMixin(HashedFilesMixin): def __init__(self, *args, **kwargs): - super(CachedFilesMixin, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) try: self.hashed_files = _MappingCache(caches['staticfiles']) except InvalidCacheBackendError: diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py index 896f798e9524..a381ebc265fa 100644 --- a/django/core/cache/backends/filebased.py +++ b/django/core/cache/backends/filebased.py @@ -17,7 +17,7 @@ class FileBasedCache(BaseCache): cache_suffix = '.djcache' def __init__(self, dir, params): - super(FileBasedCache, self).__init__(params) + super().__init__(params) self._dir = os.path.abspath(dir) self._createdir() diff --git a/django/core/cache/backends/memcached.py b/django/core/cache/backends/memcached.py index 29bd2a95cdde..6be2378e56c3 100644 --- a/django/core/cache/backends/memcached.py +++ b/django/core/cache/backends/memcached.py @@ -12,7 +12,7 @@ class BaseMemcachedCache(BaseCache): def __init__(self, server, params, library, value_not_found_exception): - super(BaseMemcachedCache, self).__init__(params) + super().__init__(params) if isinstance(server, str): self._servers = re.split('[;,]', server) else: @@ -154,9 +154,7 @@ class MemcachedCache(BaseMemcachedCache): "An implementation of a cache binding using python-memcached" def __init__(self, server, params): import memcache - super(MemcachedCache, self).__init__(server, params, - library=memcache, - value_not_found_exception=ValueError) + super().__init__(server, params, library=memcache, value_not_found_exception=ValueError) @property def _cache(self): @@ -171,9 +169,7 @@ class PyLibMCCache(BaseMemcachedCache): "An implementation of a cache binding using pylibmc" def __init__(self, server, params): import pylibmc - super(PyLibMCCache, self).__init__(server, params, - library=pylibmc, - value_not_found_exception=pylibmc.NotFound) + super().__init__(server, params, library=pylibmc, value_not_found_exception=pylibmc.NotFound) # The contents of `OPTIONS` was formerly only used to set the behaviors # attribute, but is now passed directly to the Client constructor. As such, diff --git a/django/core/checks/messages.py b/django/core/checks/messages.py index bb0e2b335c20..62bd909c6f6f 100644 --- a/django/core/checks/messages.py +++ b/django/core/checks/messages.py @@ -54,24 +54,24 @@ def is_silenced(self): class Debug(CheckMessage): def __init__(self, *args, **kwargs): - super(Debug, self).__init__(DEBUG, *args, **kwargs) + super().__init__(DEBUG, *args, **kwargs) class Info(CheckMessage): def __init__(self, *args, **kwargs): - super(Info, self).__init__(INFO, *args, **kwargs) + super().__init__(INFO, *args, **kwargs) class Warning(CheckMessage): def __init__(self, *args, **kwargs): - super(Warning, self).__init__(WARNING, *args, **kwargs) + super().__init__(WARNING, *args, **kwargs) class Error(CheckMessage): def __init__(self, *args, **kwargs): - super(Error, self).__init__(ERROR, *args, **kwargs) + super().__init__(ERROR, *args, **kwargs) class Critical(CheckMessage): def __init__(self, *args, **kwargs): - super(Critical, self).__init__(CRITICAL, *args, **kwargs) + super().__init__(CRITICAL, *args, **kwargs) diff --git a/django/core/exceptions.py b/django/core/exceptions.py index 3bf52fab000f..983053ca5ba2 100644 --- a/django/core/exceptions.py +++ b/django/core/exceptions.py @@ -109,7 +109,7 @@ def __init__(self, message, code=None, params=None): """ # PY2 can't pickle naive exception: http://bugs.python.org/issue1692335. - super(ValidationError, self).__init__(message, code, params) + super().__init__(message, code, params) if isinstance(message, ValidationError): if hasattr(message, 'error_dict'): diff --git a/django/core/files/base.py b/django/core/files/base.py index 225c6dd3494e..9030ed91555d 100644 --- a/django/core/files/base.py +++ b/django/core/files/base.py @@ -137,7 +137,7 @@ class ContentFile(File): """ def __init__(self, content, name=None): stream_class = StringIO if isinstance(content, str) else BytesIO - super(ContentFile, self).__init__(stream_class(content), name=name) + super().__init__(stream_class(content), name=name) self.size = len(content) def __str__(self): diff --git a/django/core/files/uploadedfile.py b/django/core/files/uploadedfile.py index f5ab68f0fc23..9f1efde41994 100644 --- a/django/core/files/uploadedfile.py +++ b/django/core/files/uploadedfile.py @@ -24,7 +24,7 @@ class UploadedFile(File): DEFAULT_CHUNK_SIZE = 64 * 2 ** 10 def __init__(self, file=None, name=None, content_type=None, size=None, charset=None, content_type_extra=None): - super(UploadedFile, self).__init__(file, name) + super().__init__(file, name) self.size = size self.content_type = content_type self.charset = charset @@ -59,7 +59,7 @@ class TemporaryUploadedFile(UploadedFile): """ def __init__(self, name, content_type, size, charset, content_type_extra=None): file = tempfile.NamedTemporaryFile(suffix='.upload', dir=settings.FILE_UPLOAD_TEMP_DIR) - super(TemporaryUploadedFile, self).__init__(file, name, content_type, size, charset, content_type_extra) + super().__init__(file, name, content_type, size, charset, content_type_extra) def temporary_file_path(self): """ @@ -82,7 +82,7 @@ class InMemoryUploadedFile(UploadedFile): A file uploaded into memory (i.e. stream-to-memory). """ def __init__(self, file, field_name, name, content_type, size, charset, content_type_extra=None): - super(InMemoryUploadedFile, self).__init__(file, name, content_type, size, charset, content_type_extra) + super().__init__(file, name, content_type, size, charset, content_type_extra) self.field_name = field_name def open(self, mode=None): @@ -103,8 +103,7 @@ class SimpleUploadedFile(InMemoryUploadedFile): """ def __init__(self, name, content, content_type='text/plain'): content = content or b'' - super(SimpleUploadedFile, self).__init__(BytesIO(content), None, name, - content_type, len(content), None, None) + super().__init__(BytesIO(content), None, name, content_type, len(content), None, None) @classmethod def from_dict(cls, file_dict): diff --git a/django/core/files/uploadhandler.py b/django/core/files/uploadhandler.py index e8f87845c98b..a6832491c14f 100644 --- a/django/core/files/uploadhandler.py +++ b/django/core/files/uploadhandler.py @@ -133,13 +133,13 @@ class TemporaryFileUploadHandler(FileUploadHandler): Upload handler that streams data into a temporary file. """ def __init__(self, *args, **kwargs): - super(TemporaryFileUploadHandler, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def new_file(self, *args, **kwargs): """ Create the file object to append to as data is coming in. """ - super(TemporaryFileUploadHandler, self).new_file(*args, **kwargs) + super().new_file(*args, **kwargs) self.file = TemporaryUploadedFile(self.file_name, self.content_type, 0, self.charset, self.content_type_extra) def receive_data_chunk(self, raw_data, start): @@ -168,7 +168,7 @@ def handle_raw_input(self, input_data, META, content_length, boundary, encoding= self.activated = True def new_file(self, *args, **kwargs): - super(MemoryFileUploadHandler, self).new_file(*args, **kwargs) + super().new_file(*args, **kwargs) if self.activated: self.file = BytesIO() raise StopFutureHandlers() diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index 7d8a12176a5c..2b3c355b9de5 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -141,7 +141,7 @@ class WSGIHandler(base.BaseHandler): request_class = WSGIRequest def __init__(self, *args, **kwargs): - super(WSGIHandler, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.load_middleware() def __call__(self, environ, start_response): diff --git a/django/core/mail/backends/console.py b/django/core/mail/backends/console.py index 49ddade984be..a8bdcbd2c07e 100644 --- a/django/core/mail/backends/console.py +++ b/django/core/mail/backends/console.py @@ -11,7 +11,7 @@ class EmailBackend(BaseEmailBackend): def __init__(self, *args, **kwargs): self.stream = kwargs.pop('stream', sys.stdout) self._lock = threading.RLock() - super(EmailBackend, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def write_message(self, message): msg = message.message() diff --git a/django/core/mail/backends/filebased.py b/django/core/mail/backends/filebased.py index 40dc9ff7cc0d..b051fe6313c6 100644 --- a/django/core/mail/backends/filebased.py +++ b/django/core/mail/backends/filebased.py @@ -40,7 +40,7 @@ def __init__(self, *args, **kwargs): # Since we're using the console-based backend as a base, # force the stream to be None, so we don't default to stdout kwargs['stream'] = None - super(EmailBackend, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def write_message(self, message): self.stream.write(message.message().as_bytes() + b'\n') diff --git a/django/core/mail/backends/locmem.py b/django/core/mail/backends/locmem.py index 54d3847c03d6..f022236dd7c3 100644 --- a/django/core/mail/backends/locmem.py +++ b/django/core/mail/backends/locmem.py @@ -15,7 +15,7 @@ class EmailBackend(BaseEmailBackend): The dummy outbox is accessible through the outbox instance attribute. """ def __init__(self, *args, **kwargs): - super(EmailBackend, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) if not hasattr(mail, 'outbox'): mail.outbox = [] diff --git a/django/core/mail/backends/smtp.py b/django/core/mail/backends/smtp.py index b6d5c2fed38d..97b5df97e81e 100644 --- a/django/core/mail/backends/smtp.py +++ b/django/core/mail/backends/smtp.py @@ -18,7 +18,7 @@ def __init__(self, host=None, port=None, username=None, password=None, use_tls=None, fail_silently=False, use_ssl=None, timeout=None, ssl_keyfile=None, ssl_certfile=None, **kwargs): - super(EmailBackend, self).__init__(fail_silently=fail_silently) + super().__init__(fail_silently=fail_silently) self.host = host or settings.EMAIL_HOST self.port = port or settings.EMAIL_PORT self.username = settings.EMAIL_HOST_USER if username is None else username diff --git a/django/core/mail/message.py b/django/core/mail/message.py index dd5e1e6d7bb4..f4f3eb1352e5 100644 --- a/django/core/mail/message.py +++ b/django/core/mail/message.py @@ -429,7 +429,7 @@ def __init__(self, subject='', body='', from_email=None, to=None, bcc=None, bytestrings). The SafeMIMEText class will handle any necessary encoding conversions. """ - super(EmailMultiAlternatives, self).__init__( + super().__init__( subject, body, from_email, to, bcc, connection, attachments, headers, cc, reply_to, ) diff --git a/django/core/management/base.py b/django/core/management/base.py index 80f7e0a5756a..b0f454381a53 100644 --- a/django/core/management/base.py +++ b/django/core/management/base.py @@ -45,18 +45,18 @@ class CommandParser(ArgumentParser): """ def __init__(self, cmd, **kwargs): self.cmd = cmd - super(CommandParser, self).__init__(**kwargs) + super().__init__(**kwargs) def parse_args(self, args=None, namespace=None): # Catch missing argument for a better error message if (hasattr(self.cmd, 'missing_args_message') and not (args or any(not arg.startswith('-') for arg in args))): self.error(self.cmd.missing_args_message) - return super(CommandParser, self).parse_args(args, namespace) + return super().parse_args(args, namespace) def error(self, message): if self.cmd._called_from_command_line: - super(CommandParser, self).error(message) + super().error(message) else: raise CommandError("Error: %s" % message) diff --git a/django/core/management/commands/migrate.py b/django/core/management/commands/migrate.py index 79ff872db025..91c52f96eee2 100644 --- a/django/core/management/commands/migrate.py +++ b/django/core/management/commands/migrate.py @@ -56,7 +56,7 @@ def add_arguments(self, parser): def _run_checks(self, **kwargs): issues = run_checks(tags=[Tags.database]) - issues.extend(super(Command, self)._run_checks(**kwargs)) + issues.extend(super()._run_checks(**kwargs)) return issues def handle(self, *args, **options): diff --git a/django/core/management/commands/runserver.py b/django/core/management/commands/runserver.py index 61a275d61f4a..2523c1b5f343 100644 --- a/django/core/management/commands/runserver.py +++ b/django/core/management/commands/runserver.py @@ -57,7 +57,7 @@ def execute(self, *args, **options): # way to reach WSGIRequestHandler. This seems an acceptable # compromise considering `runserver` runs indefinitely. os.environ["DJANGO_COLORS"] = "nocolor" - super(Command, self).execute(*args, **options) + super().execute(*args, **options) def get_handler(self, *args, **options): """ diff --git a/django/core/management/commands/sqlflush.py b/django/core/management/commands/sqlflush.py index da7d6b00e9a3..60e69e67bf50 100644 --- a/django/core/management/commands/sqlflush.py +++ b/django/core/management/commands/sqlflush.py @@ -12,7 +12,7 @@ class Command(BaseCommand): output_transaction = True def add_arguments(self, parser): - super(Command, self).add_arguments(parser) + super().add_arguments(parser) parser.add_argument( '--database', default=DEFAULT_DB_ALIAS, help='Nominates a database to print the SQL for. Defaults to the "default" database.', diff --git a/django/core/management/commands/sqlmigrate.py b/django/core/management/commands/sqlmigrate.py index f6c67a5807e5..0d04a54af348 100644 --- a/django/core/management/commands/sqlmigrate.py +++ b/django/core/management/commands/sqlmigrate.py @@ -27,7 +27,7 @@ def execute(self, *args, **options): # no_color=True so that the BEGIN/COMMIT statements added by # output_transaction don't get colored either. options['no_color'] = True - return super(Command, self).execute(*args, **options) + return super().execute(*args, **options) def handle(self, *args, **options): # Get the database we're operating from diff --git a/django/core/management/commands/sqlsequencereset.py b/django/core/management/commands/sqlsequencereset.py index 788a923c72ca..d23f89ce1f1e 100644 --- a/django/core/management/commands/sqlsequencereset.py +++ b/django/core/management/commands/sqlsequencereset.py @@ -8,7 +8,7 @@ class Command(AppCommand): output_transaction = True def add_arguments(self, parser): - super(Command, self).add_arguments(parser) + super().add_arguments(parser) parser.add_argument( '--database', default=DEFAULT_DB_ALIAS, help='Nominates a database to print the SQL for. Defaults to the "default" database.', diff --git a/django/core/management/commands/startapp.py b/django/core/management/commands/startapp.py index 32e9454a3ce0..63ecba437247 100644 --- a/django/core/management/commands/startapp.py +++ b/django/core/management/commands/startapp.py @@ -26,4 +26,4 @@ def handle(self, **options): "cannot be used as an app name. Please try another name." % app_name ) - super(Command, self).handle('app', app_name, target, **options) + super().handle('app', app_name, target, **options) diff --git a/django/core/management/commands/startproject.py b/django/core/management/commands/startproject.py index d7307e141b2f..bc64faa6805f 100644 --- a/django/core/management/commands/startproject.py +++ b/django/core/management/commands/startproject.py @@ -31,4 +31,4 @@ def handle(self, **options): # Create a random SECRET_KEY to put it in the main settings. options['secret_key'] = get_random_secret_key() - super(Command, self).handle('project', project_name, target, **options) + super().handle('project', project_name, target, **options) diff --git a/django/core/management/commands/test.py b/django/core/management/commands/test.py index b1186f20fcd6..da2e4f595260 100644 --- a/django/core/management/commands/test.py +++ b/django/core/management/commands/test.py @@ -13,7 +13,7 @@ class Command(BaseCommand): def __init__(self): self.test_runner = None - super(Command, self).__init__() + super().__init__() def run_from_argv(self, argv): """ @@ -26,7 +26,7 @@ def run_from_argv(self, argv): if arg.startswith(option): self.test_runner = arg[len(option):] break - super(Command, self).run_from_argv(argv) + super().run_from_argv(argv) def add_arguments(self, parser): parser.add_argument( diff --git a/django/core/serializers/json.py b/django/core/serializers/json.py index 79db71cadf50..b2ab87b17102 100644 --- a/django/core/serializers/json.py +++ b/django/core/serializers/json.py @@ -59,7 +59,7 @@ def end_object(self, obj): self._current = None def getvalue(self): - # Grand-parent super + # Grandparent super return super(PythonSerializer, self).getvalue() @@ -108,4 +108,4 @@ def default(self, o): elif isinstance(o, (decimal.Decimal, uuid.UUID, Promise)): return str(o) else: - return super(DjangoJSONEncoder, self).default(o) + return super().default(o) diff --git a/django/core/serializers/pyyaml.py b/django/core/serializers/pyyaml.py index 89594728cb3a..fcebd107aa3b 100644 --- a/django/core/serializers/pyyaml.py +++ b/django/core/serializers/pyyaml.py @@ -53,13 +53,13 @@ def handle_field(self, obj, field): if isinstance(field, models.TimeField) and getattr(obj, field.name) is not None: self._current[field.name] = str(getattr(obj, field.name)) else: - super(Serializer, self).handle_field(obj, field) + super().handle_field(obj, field) def end_serialization(self): yaml.dump(self.objects, self.stream, Dumper=DjangoSafeDumper, **self.options) def getvalue(self): - # Grand-parent super + # Grandparent super return super(PythonSerializer, self).getvalue() diff --git a/django/core/serializers/xml_serializer.py b/django/core/serializers/xml_serializer.py index e209cb286a65..ddf0bf3e1a76 100644 --- a/django/core/serializers/xml_serializer.py +++ b/django/core/serializers/xml_serializer.py @@ -158,7 +158,7 @@ class Deserializer(base.Deserializer): """ def __init__(self, stream_or_string, **options): - super(Deserializer, self).__init__(stream_or_string, **options) + super().__init__(stream_or_string, **options) self.event_stream = pulldom.parse(self.stream, self._make_parser()) self.db = options.pop('using', DEFAULT_DB_ALIAS) self.ignore = options.pop('ignorenonexistent', False) @@ -356,7 +356,7 @@ def __repr__(self): class DTDForbidden(DefusedXmlException): """Document type definition is forbidden.""" def __init__(self, name, sysid, pubid): - super(DTDForbidden, self).__init__() + super().__init__() self.name = name self.sysid = sysid self.pubid = pubid @@ -369,7 +369,7 @@ def __str__(self): class EntitiesForbidden(DefusedXmlException): """Entity definition is forbidden.""" def __init__(self, name, value, base, sysid, pubid, notation_name): - super(EntitiesForbidden, self).__init__() + super().__init__() self.name = name self.value = value self.base = base @@ -385,7 +385,7 @@ def __str__(self): class ExternalReferenceForbidden(DefusedXmlException): """Resolving an external reference is forbidden.""" def __init__(self, context, base, sysid, pubid): - super(ExternalReferenceForbidden, self).__init__() + super().__init__() self.context = context self.base = base self.sysid = sysid diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index 3e1141122bd5..ef2edc0f8092 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -63,25 +63,25 @@ def __init__(self, *args, **kwargs): if kwargs.pop('ipv6', False): self.address_family = socket.AF_INET6 self.allow_reuse_address = kwargs.pop('allow_reuse_address', True) - super(WSGIServer, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def server_bind(self): """Override server_bind to store the server name.""" - super(WSGIServer, self).server_bind() + super().server_bind() self.setup_environ() def handle_error(self, request, client_address): if is_broken_pipe_error(): logger.info("- Broken pipe from %s\n", client_address) else: - super(WSGIServer, self).handle_error(request, client_address) + super().handle_error(request, client_address) class ServerHandler(simple_server.ServerHandler): def handle_error(self): # Ignore broken pipe errors, otherwise pass on if not is_broken_pipe_error(): - super(ServerHandler, self).handle_error() + super().handle_error() class WSGIRequestHandler(simple_server.WSGIRequestHandler): @@ -128,7 +128,7 @@ def get_environ(self): if '_' in k: del self.headers[k] - return super(WSGIRequestHandler, self).get_environ() + return super().get_environ() def handle(self): """Copy of WSGIRequestHandler, but with different ServerHandler""" diff --git a/django/core/signing.py b/django/core/signing.py index 7d73611817b0..b6a9a974c463 100644 --- a/django/core/signing.py +++ b/django/core/signing.py @@ -182,14 +182,14 @@ def timestamp(self): def sign(self, value): value = '%s%s%s' % (force_text(value), self.sep, self.timestamp()) - return super(TimestampSigner, self).sign(value) + return super().sign(value) def unsign(self, value, max_age=None): """ Retrieve original value and check it wasn't signed more than max_age seconds ago. """ - result = super(TimestampSigner, self).unsign(value) + result = super().unsign(value) value, timestamp = result.rsplit(self.sep, 1) timestamp = baseconv.base62.decode(timestamp) if max_age is not None: diff --git a/django/core/validators.py b/django/core/validators.py index 1dc0f2fbcd2d..0b90b4345cd8 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -102,7 +102,7 @@ class URLValidator(RegexValidator): schemes = ['http', 'https', 'ftp', 'ftps'] def __init__(self, schemes=None, **kwargs): - super(URLValidator, self).__init__(**kwargs) + super().__init__(**kwargs) if schemes is not None: self.schemes = schemes @@ -115,7 +115,7 @@ def __call__(self, value): # Then check full URL try: - super(URLValidator, self).__call__(value) + super().__call__(value) except ValidationError as e: # Trivial case failed. Try for possible IDN domain if value: @@ -128,7 +128,7 @@ def __call__(self, value): except UnicodeError: # invalid domain part raise e url = urlunsplit((scheme, netloc, path, query, fragment)) - super(URLValidator, self).__call__(url) + super().__call__(url) else: raise else: diff --git a/django/db/backends/mysql/introspection.py b/django/db/backends/mysql/introspection.py index 457c8b7f4866..20e017120c80 100644 --- a/django/db/backends/mysql/introspection.py +++ b/django/db/backends/mysql/introspection.py @@ -39,7 +39,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): } def get_field_type(self, data_type, description): - field_type = super(DatabaseIntrospection, self).get_field_type(data_type, description) + field_type = super().get_field_type(data_type, description) if 'auto_increment' in description.extra: if field_type == 'IntegerField': return 'AutoField' diff --git a/django/db/backends/mysql/operations.py b/django/db/backends/mysql/operations.py index acb86c62ace9..881ada60c7ff 100644 --- a/django/db/backends/mysql/operations.py +++ b/django/db/backends/mysql/operations.py @@ -202,10 +202,10 @@ def combine_expression(self, connector, sub_expressions): elif connector == '>>': lhs, rhs = sub_expressions return 'FLOOR(%(lhs)s / POW(2, %(rhs)s))' % {'lhs': lhs, 'rhs': rhs} - return super(DatabaseOperations, self).combine_expression(connector, sub_expressions) + return super().combine_expression(connector, sub_expressions) def get_db_converters(self, expression): - converters = super(DatabaseOperations, self).get_db_converters(expression) + converters = super().get_db_converters(expression) internal_type = expression.output_field.get_internal_type() if internal_type == 'TextField': converters.append(self.convert_textfield_value) diff --git a/django/db/backends/mysql/schema.py b/django/db/backends/mysql/schema.py index f89088ef5b9d..455fd1b0e34b 100644 --- a/django/db/backends/mysql/schema.py +++ b/django/db/backends/mysql/schema.py @@ -45,7 +45,7 @@ def skip_default(self, field): ) def add_field(self, model, field): - super(DatabaseSchemaEditor, self).add_field(model, field) + super().add_field(model, field) # Simulate the effect of a one-off default. # field.default may be unhashable, so a set isn't used for "in" check. @@ -57,7 +57,7 @@ def add_field(self, model, field): }, [effective_default]) def _field_should_be_indexed(self, model, field): - create_index = super(DatabaseSchemaEditor, self)._field_should_be_indexed(model, field) + create_index = super()._field_should_be_indexed(model, field) storage = self.connection.introspection.get_storage_engine( self.connection.cursor(), model._meta.db_table ) @@ -85,7 +85,7 @@ def _delete_composed_index(self, model, fields, *args): constraint_names = self._constraint_names(model, [first_field.column], index=True) if not constraint_names: self.execute(self._create_index_sql(model, [first_field], suffix="")) - return super(DatabaseSchemaEditor, self)._delete_composed_index(model, fields, *args) + return super()._delete_composed_index(model, fields, *args) def _set_field_new_type_null_status(self, field, new_type): """ @@ -100,8 +100,8 @@ def _set_field_new_type_null_status(self, field, new_type): def _alter_column_type_sql(self, table, old_field, new_field, new_type): new_type = self._set_field_new_type_null_status(old_field, new_type) - return super(DatabaseSchemaEditor, self)._alter_column_type_sql(table, old_field, new_field, new_type) + return super()._alter_column_type_sql(table, old_field, new_field, new_type) def _rename_field_sql(self, table, old_field, new_field, new_type): new_type = self._set_field_new_type_null_status(old_field, new_type) - return super(DatabaseSchemaEditor, self)._rename_field_sql(table, old_field, new_field, new_type) + return super()._rename_field_sql(table, old_field, new_field, new_type) diff --git a/django/db/backends/mysql/validation.py b/django/db/backends/mysql/validation.py index 3492034eba3d..358520d5179f 100644 --- a/django/db/backends/mysql/validation.py +++ b/django/db/backends/mysql/validation.py @@ -5,7 +5,7 @@ class DatabaseValidation(BaseDatabaseValidation): def check(self, **kwargs): - issues = super(DatabaseValidation, self).check(**kwargs) + issues = super().check(**kwargs) issues.extend(self._check_sql_mode(**kwargs)) return issues @@ -32,7 +32,7 @@ def check_field(self, field, **kwargs): No character (varchar) fields can have a length exceeding 255 characters if they have a unique index on them. """ - errors = super(DatabaseValidation, self).check_field(field, **kwargs) + errors = super().check_field(field, **kwargs) # Ignore any related fields. if getattr(field, 'remote_field', None): diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index fbbee227ee59..0cc21b639b77 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -175,7 +175,7 @@ class DatabaseWrapper(BaseDatabaseWrapper): ops_class = DatabaseOperations def __init__(self, *args, **kwargs): - super(DatabaseWrapper, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) use_returning_into = self.settings_dict["OPTIONS"].get('use_returning_into', True) self.features.can_return_id_from_insert = use_returning_into diff --git a/django/db/backends/oracle/compiler.py b/django/db/backends/oracle/compiler.py index 9aa4acc0fe57..4eb841f41fb0 100644 --- a/django/db/backends/oracle/compiler.py +++ b/django/db/backends/oracle/compiler.py @@ -16,15 +16,9 @@ def as_sql(self, with_limits=True, with_col_aliases=False): # the SQL needed to use limit/offset with Oracle. do_offset = with_limits and (self.query.high_mark is not None or self.query.low_mark) if not do_offset: - sql, params = super(SQLCompiler, self).as_sql( - with_limits=False, - with_col_aliases=with_col_aliases, - ) + sql, params = super().as_sql(with_limits=False, with_col_aliases=with_col_aliases) else: - sql, params = super(SQLCompiler, self).as_sql( - with_limits=False, - with_col_aliases=True, - ) + sql, params = super().as_sql(with_limits=False, with_col_aliases=True) # Wrap the base query in an outer SELECT * with boundaries on # the "_RN" column. This is the canonical way to emulate LIMIT # and OFFSET on Oracle. diff --git a/django/db/backends/oracle/features.py b/django/db/backends/oracle/features.py index d30c149ad206..0e85f267f2ef 100644 --- a/django/db/backends/oracle/features.py +++ b/django/db/backends/oracle/features.py @@ -49,4 +49,4 @@ def introspected_boolean_field_type(self, field=None, created_separately=False): """ if self.connection.oracle_full_version < '11.2.0.2' and field and field.has_default() and created_separately: return 'IntegerField' - return super(DatabaseFeatures, self).introspected_boolean_field_type(field, created_separately) + return super().introspected_boolean_field_type(field, created_separately) diff --git a/django/db/backends/oracle/functions.py b/django/db/backends/oracle/functions.py index 384f092fd4eb..7e9b6a62042c 100644 --- a/django/db/backends/oracle/functions.py +++ b/django/db/backends/oracle/functions.py @@ -12,7 +12,7 @@ class IntervalToSeconds(Func): def __init__(self, expression, **extra): output_field = extra.pop('output_field', DecimalField()) - super(IntervalToSeconds, self).__init__(expression, output_field=output_field, **extra) + super().__init__(expression, output_field=output_field, **extra) class SecondsToInterval(Func): @@ -21,4 +21,4 @@ class SecondsToInterval(Func): def __init__(self, expression, **extra): output_field = extra.pop('output_field', DurationField()) - super(SecondsToInterval, self).__init__(expression, output_field=output_field, **extra) + super().__init__(expression, output_field=output_field, **extra) diff --git a/django/db/backends/oracle/introspection.py b/django/db/backends/oracle/introspection.py index 8a648dba3fbb..1250a02f1d39 100644 --- a/django/db/backends/oracle/introspection.py +++ b/django/db/backends/oracle/introspection.py @@ -48,7 +48,7 @@ def get_field_type(self, data_type, description): elif scale == -127: return 'FloatField' - return super(DatabaseIntrospection, self).get_field_type(data_type, description) + return super().get_field_type(data_type, description) def get_table_list(self, cursor): """ diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py index 8d943199875a..5a182d59e9cb 100644 --- a/django/db/backends/oracle/operations.py +++ b/django/db/backends/oracle/operations.py @@ -40,7 +40,7 @@ class DatabaseOperations(BaseDatabaseOperations): /""" def __init__(self, *args, **kwargs): - super(DatabaseOperations, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.set_operators['difference'] = 'MINUS' def autoinc_sql(self, table, column): @@ -165,7 +165,7 @@ def time_trunc_sql(self, lookup_type, field_name): return sql def get_db_converters(self, expression): - converters = super(DatabaseOperations, self).get_db_converters(expression) + converters = super().get_db_converters(expression) internal_type = expression.output_field.get_internal_type() if internal_type == 'TextField': converters.append(self.convert_textfield_value) @@ -254,7 +254,7 @@ def last_executed_query(self, cursor, sql, params): statement = cursor.statement # Unlike Psycopg's `query` and MySQLdb`'s `_last_executed`, CxOracle's # `statement` doesn't contain the query parameters. refs #20010. - return super(DatabaseOperations, self).last_executed_query(cursor, statement, params) + return super().last_executed_query(cursor, statement, params) def last_insert_id(self, cursor, table_name, pk_name): sq_name = self._get_sequence_name(table_name) @@ -514,7 +514,7 @@ def combine_expression(self, connector, sub_expressions): return 'FLOOR(%(lhs)s / POWER(2, %(rhs)s))' % {'lhs': lhs, 'rhs': rhs} elif connector == '^': return 'POWER(%s)' % ','.join(sub_expressions) - return super(DatabaseOperations, self).combine_expression(connector, sub_expressions) + return super().combine_expression(connector, sub_expressions) def _get_sequence_name(self, table): name_length = self.max_name_length() - 3 @@ -537,4 +537,4 @@ def subtract_temporals(self, internal_type, lhs, rhs): lhs_sql, lhs_params = lhs rhs_sql, rhs_params = rhs return "NUMTODSINTERVAL(%s - %s, 'DAY')" % (lhs_sql, rhs_sql), lhs_params + rhs_params - return super(DatabaseOperations, self).subtract_temporals(internal_type, lhs, rhs) + return super().subtract_temporals(internal_type, lhs, rhs) diff --git a/django/db/backends/oracle/schema.py b/django/db/backends/oracle/schema.py index 44a1f3cd8d7d..1ce27dc29d45 100644 --- a/django/db/backends/oracle/schema.py +++ b/django/db/backends/oracle/schema.py @@ -33,7 +33,7 @@ def quote_value(self, value): def delete_model(self, model): # Run superclass action - super(DatabaseSchemaEditor, self).delete_model(model) + super().delete_model(model) # Clean up any autoincrement trigger self.execute(""" DECLARE @@ -49,7 +49,7 @@ def delete_model(self, model): def alter_field(self, model, old_field, new_field, strict=False): try: - super(DatabaseSchemaEditor, self).alter_field(model, old_field, new_field, strict) + super().alter_field(model, old_field, new_field, strict) except DatabaseError as e: description = str(e) # If we're changing type to an unsupported type we need a @@ -100,7 +100,7 @@ def _alter_field_type_workaround(self, model, old_field, new_field): # Drop the old field self.remove_field(model, old_field) # Rename and possibly make the new field NOT NULL - super(DatabaseSchemaEditor, self).alter_field(model, new_temp_field, new_field) + super().alter_field(model, new_temp_field, new_field) def normalize_name(self, name): """ diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py index a3b293ee366a..2459748f1b41 100644 --- a/django/db/backends/postgresql/base.py +++ b/django/db/backends/postgresql/base.py @@ -141,7 +141,7 @@ class DatabaseWrapper(BaseDatabaseWrapper): ops_class = DatabaseOperations def __init__(self, *args, **kwargs): - super(DatabaseWrapper, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self._named_cursor_idx = 0 def get_connection_params(self): @@ -248,7 +248,7 @@ def is_usable(self): @property def _nodb_connection(self): - nodb_connection = super(DatabaseWrapper, self)._nodb_connection + nodb_connection = super()._nodb_connection try: nodb_connection.ensure_connection() except (Database.DatabaseError, WrappedDatabaseError): diff --git a/django/db/backends/postgresql/introspection.py b/django/db/backends/postgresql/introspection.py index 34150c6f482e..d663de61e5d1 100644 --- a/django/db/backends/postgresql/introspection.py +++ b/django/db/backends/postgresql/introspection.py @@ -43,7 +43,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): AND c.relname = %s""" def get_field_type(self, data_type, description): - field_type = super(DatabaseIntrospection, self).get_field_type(data_type, description) + field_type = super().get_field_type(data_type, description) if description.default and 'nextval' in description.default: if field_type == 'IntegerField': return 'AutoField' diff --git a/django/db/backends/postgresql/operations.py b/django/db/backends/postgresql/operations.py index 542fe223cb96..e612a60ca88d 100644 --- a/django/db/backends/postgresql/operations.py +++ b/django/db/backends/postgresql/operations.py @@ -261,7 +261,7 @@ def subtract_temporals(self, internal_type, lhs, rhs): lhs_sql, lhs_params = lhs rhs_sql, rhs_params = rhs return "age(%s, %s)" % (lhs_sql, rhs_sql), lhs_params + rhs_params - return super(DatabaseOperations, self).subtract_temporals(internal_type, lhs, rhs) + return super().subtract_temporals(internal_type, lhs, rhs) def fulltext_search_sql(self, field_name): raise NotImplementedError( diff --git a/django/db/backends/postgresql/schema.py b/django/db/backends/postgresql/schema.py index bffa8bd45b3e..e9928999dbf5 100644 --- a/django/db/backends/postgresql/schema.py +++ b/django/db/backends/postgresql/schema.py @@ -23,7 +23,7 @@ def quote_value(self, value): return psycopg2.extensions.adapt(value) def _field_indexes_sql(self, model, field): - output = super(DatabaseSchemaEditor, self)._field_indexes_sql(model, field) + output = super()._field_indexes_sql(model, field) like_index_statement = self._create_like_index_sql(model, field) if like_index_statement is not None: output.append(like_index_statement) @@ -101,13 +101,11 @@ def _alter_column_type_sql(self, table, old_field, new_field, new_type): ], ) else: - return super(DatabaseSchemaEditor, self)._alter_column_type_sql( - table, old_field, new_field, new_type - ) + return super()._alter_column_type_sql(table, old_field, new_field, new_type) def _alter_field(self, model, old_field, new_field, old_type, new_type, old_db_params, new_db_params, strict=False): - super(DatabaseSchemaEditor, self)._alter_field( + super()._alter_field( model, old_field, new_field, old_type, new_type, old_db_params, new_db_params, strict, ) diff --git a/django/db/backends/sqlite3/operations.py b/django/db/backends/sqlite3/operations.py index 64486be737a3..4f66b66de993 100644 --- a/django/db/backends/sqlite3/operations.py +++ b/django/db/backends/sqlite3/operations.py @@ -195,7 +195,7 @@ def adapt_timefield_value(self, value): return str(value) def get_db_converters(self, expression): - converters = super(DatabaseOperations, self).get_db_converters(expression) + converters = super().get_db_converters(expression) internal_type = expression.output_field.get_internal_type() if internal_type == 'DateTimeField': converters.append(self.convert_datetimefield_value) @@ -256,7 +256,7 @@ def combine_expression(self, connector, sub_expressions): # user-defined function django_power that's registered in connect(). if connector == '^': return 'django_power(%s)' % ','.join(sub_expressions) - return super(DatabaseOperations, self).combine_expression(connector, sub_expressions) + return super().combine_expression(connector, sub_expressions) def combine_duration_expression(self, connector, sub_expressions): if connector not in ['+', '-']: diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py index d74f59d21c64..bf2824aa1fed 100644 --- a/django/db/backends/sqlite3/schema.py +++ b/django/db/backends/sqlite3/schema.py @@ -23,10 +23,10 @@ def __enter__(self): c.execute('PRAGMA foreign_keys') self._initial_pragma_fk = c.fetchone()[0] c.execute('PRAGMA foreign_keys = 0') - return super(DatabaseSchemaEditor, self).__enter__() + return super().__enter__() def __exit__(self, exc_type, exc_value, traceback): - super(DatabaseSchemaEditor, self).__exit__(exc_type, exc_value, traceback) + super().__exit__(exc_type, exc_value, traceback) with self.connection.cursor() as c: # Restore initial FK setting - PRAGMA values can't be parametrized c.execute('PRAGMA foreign_keys = %s' % int(self._initial_pragma_fk)) @@ -216,7 +216,7 @@ def altered_table_name(model, temporary_table_name): def delete_model(self, model, handle_autom2m=True): if handle_autom2m: - super(DatabaseSchemaEditor, self).delete_model(model) + super().delete_model(model) else: # Delete the table (and only that) self.execute(self.sql_delete_table % { diff --git a/django/db/backends/utils.py b/django/db/backends/utils.py index 3baff0d3d5b9..5da4e04478ce 100644 --- a/django/db/backends/utils.py +++ b/django/db/backends/utils.py @@ -74,7 +74,7 @@ class CursorDebugWrapper(CursorWrapper): def execute(self, sql, params=None): start = time() try: - return super(CursorDebugWrapper, self).execute(sql, params) + return super().execute(sql, params) finally: stop = time() duration = stop - start @@ -91,7 +91,7 @@ def execute(self, sql, params=None): def executemany(self, sql, param_list): start = time() try: - return super(CursorDebugWrapper, self).executemany(sql, param_list) + return super().executemany(sql, param_list) finally: stop = time() duration = stop - start diff --git a/django/db/migrations/graph.py b/django/db/migrations/graph.py index 7fdc850a7798..e8c67184a5cf 100644 --- a/django/db/migrations/graph.py +++ b/django/db/migrations/graph.py @@ -77,7 +77,7 @@ def descendants(self): class DummyNode(Node): def __init__(self, key, origin, error_message): - super(DummyNode, self).__init__(key) + super().__init__(key) self.origin = origin self.error_message = error_message diff --git a/django/db/migrations/operations/fields.py b/django/db/migrations/operations/fields.py index 431f87d7e677..20c1265d706f 100644 --- a/django/db/migrations/operations/fields.py +++ b/django/db/migrations/operations/fields.py @@ -31,7 +31,7 @@ def references_field(self, model_name, name, app_label=None): def reduce(self, operation, in_between, app_label=None): return ( - super(FieldOperation, self).reduce(operation, in_between, app_label=app_label) or + super().reduce(operation, in_between, app_label=app_label) or not operation.references_field(self.model_name, self.name, app_label) ) @@ -44,7 +44,7 @@ class AddField(FieldOperation): def __init__(self, model_name, name, field, preserve_default=True): self.field = field self.preserve_default = preserve_default - super(AddField, self).__init__(model_name, name) + super().__init__(model_name, name) def deconstruct(self): kwargs = { @@ -114,7 +114,7 @@ def reduce(self, operation, in_between, app_label=None): field=self.field, ), ] - return super(AddField, self).reduce(operation, in_between, app_label=app_label) + return super().reduce(operation, in_between, app_label=app_label) class RemoveField(FieldOperation): @@ -169,7 +169,7 @@ class AlterField(FieldOperation): def __init__(self, model_name, name, field, preserve_default=True): self.field = field self.preserve_default = preserve_default - super(AlterField, self).__init__(model_name, name) + super().__init__(model_name, name) def deconstruct(self): kwargs = { @@ -232,7 +232,7 @@ def reduce(self, operation, in_between, app_label=None): field=self.field, ), ] - return super(AlterField, self).reduce(operation, in_between, app_label=app_label) + return super().reduce(operation, in_between, app_label=app_label) class RenameField(FieldOperation): @@ -243,7 +243,7 @@ class RenameField(FieldOperation): def __init__(self, model_name, old_name, new_name): self.old_name = old_name self.new_name = new_name - super(RenameField, self).__init__(model_name, old_name) + super().__init__(model_name, old_name) @cached_property def old_name_lower(self): diff --git a/django/db/migrations/operations/models.py b/django/db/migrations/operations/models.py index f37632458074..34a0c4e2ef5b 100644 --- a/django/db/migrations/operations/models.py +++ b/django/db/migrations/operations/models.py @@ -33,7 +33,7 @@ def references_model(self, name, app_label=None): def reduce(self, operation, in_between, app_label=None): return ( - super(ModelOperation, self).reduce(operation, in_between, app_label=app_label) or + super().reduce(operation, in_between, app_label=app_label) or not operation.references_model(self.name, app_label) ) @@ -50,7 +50,7 @@ def __init__(self, name, fields, options=None, bases=None, managers=None): self.options = options or {} self.bases = bases or (models.Model,) self.managers = managers or [] - super(CreateModel, self).__init__(name) + super().__init__(name) # Sanity-check that there are no duplicated field names, bases, or # manager names _check_for_duplicates('fields', (name for name, _ in self.fields)) @@ -223,7 +223,7 @@ def reduce(self, operation, in_between, app_label=None): managers=self.managers, ), ] - return super(CreateModel, self).reduce(operation, in_between, app_label=app_label) + return super().reduce(operation, in_between, app_label=app_label) class DeleteModel(ModelOperation): @@ -266,7 +266,7 @@ class RenameModel(ModelOperation): def __init__(self, old_name, new_name): self.old_name = old_name self.new_name = new_name - super(RenameModel, self).__init__(old_name) + super().__init__(old_name) @cached_property def old_name_lower(self): @@ -429,7 +429,7 @@ class AlterModelTable(ModelOperation): def __init__(self, name, table): self.table = table - super(AlterModelTable, self).__init__(name) + super().__init__(name) def deconstruct(self): kwargs = { @@ -476,14 +476,14 @@ def describe(self): def reduce(self, operation, in_between, app_label=None): if isinstance(operation, (AlterModelTable, DeleteModel)) and self.name_lower == operation.name_lower: return [operation] - return super(AlterModelTable, self).reduce(operation, in_between, app_label=app_label) + return super().reduce(operation, in_between, app_label=app_label) class ModelOptionOperation(ModelOperation): def reduce(self, operation, in_between, app_label=None): if isinstance(operation, (self.__class__, DeleteModel)) and self.name_lower == operation.name_lower: return [operation] - return super(ModelOptionOperation, self).reduce(operation, in_between, app_label=app_label) + return super().reduce(operation, in_between, app_label=app_label) class FieldRelatedOptionOperation(ModelOptionOperation): @@ -492,7 +492,7 @@ def reduce(self, operation, in_between, app_label=None): self.name_lower == operation.model_name_lower and not self.references_field(operation.model_name, operation.name)): return [operation, self] - return super(FieldRelatedOptionOperation, self).reduce(operation, in_between, app_label=app_label) + return super().reduce(operation, in_between, app_label=app_label) class AlterUniqueTogether(FieldRelatedOptionOperation): @@ -505,7 +505,7 @@ class AlterUniqueTogether(FieldRelatedOptionOperation): def __init__(self, name, unique_together): unique_together = normalize_together(unique_together) self.unique_together = set(tuple(cons) for cons in unique_together) - super(AlterUniqueTogether, self).__init__(name) + super().__init__(name) def deconstruct(self): kwargs = { @@ -559,7 +559,7 @@ class AlterIndexTogether(FieldRelatedOptionOperation): def __init__(self, name, index_together): index_together = normalize_together(index_together) self.index_together = set(tuple(cons) for cons in index_together) - super(AlterIndexTogether, self).__init__(name) + super().__init__(name) def deconstruct(self): kwargs = { @@ -610,7 +610,7 @@ class AlterOrderWithRespectTo(FieldRelatedOptionOperation): def __init__(self, name, order_with_respect_to): self.order_with_respect_to = order_with_respect_to - super(AlterOrderWithRespectTo, self).__init__(name) + super().__init__(name) def deconstruct(self): kwargs = { @@ -685,7 +685,7 @@ class AlterModelOptions(ModelOptionOperation): def __init__(self, name, options): self.options = options - super(AlterModelOptions, self).__init__(name) + super().__init__(name) def deconstruct(self): kwargs = { @@ -726,7 +726,7 @@ class AlterModelManagers(ModelOptionOperation): def __init__(self, name, managers): self.managers = managers - super(AlterModelManagers, self).__init__(name) + super().__init__(name) def deconstruct(self): return ( diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index 58f90beaa20a..fac8e4c189a6 100644 --- a/django/db/migrations/serializer.py +++ b/django/db/migrations/serializer.py @@ -136,7 +136,7 @@ class FloatSerializer(BaseSimpleSerializer): def serialize(self): if math.isnan(self.value) or math.isinf(self.value): return 'float("{}")'.format(self.value), set() - return super(FloatSerializer, self).serialize() + return super().serialize() class FrozensetSerializer(BaseSequenceSerializer): diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index 9e73fb20fd8d..de0b17422a5f 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -246,7 +246,7 @@ def __init__(self, label): # App-label and app-name are not the same thing, so technically passing # in the label here is wrong. In practice, migrations don't care about # the app name, but we need something unique, and the label works fine. - super(AppConfigStub, self).__init__(label, None) + super().__init__(label, None) def import_models(self): self.models = self.apps.all_models[self.label] @@ -271,7 +271,7 @@ def __init__(self, real_apps, models, ignore_swappable=False): # Populate the app registry with a stub for each application. app_labels = {model_state.app_label for model_state in models.values()} app_configs = [AppConfigStub(label) for label in sorted(real_apps + list(app_labels))] - super(StateApps, self).__init__(app_configs) + super().__init__(app_configs) # The lock gets in the way of copying as implemented in clone(), which # is called whenever Django duplicates a StateApps before updating it. diff --git a/django/db/models/aggregates.py b/django/db/models/aggregates.py index 6c320ed8284f..095455f8c105 100644 --- a/django/db/models/aggregates.py +++ b/django/db/models/aggregates.py @@ -16,7 +16,7 @@ class Aggregate(Func): def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False): # Aggregates are not allowed in UPDATE queries, so ignore for_save - c = super(Aggregate, self).resolve_expression(query, allow_joins, reuse, summarize) + c = super().resolve_expression(query, allow_joins, reuse, summarize) if not summarize: expressions = c.get_source_expressions() for index, expr in enumerate(expressions): @@ -45,7 +45,7 @@ def _resolve_output_field(self): source_field = self.get_source_fields()[0] if isinstance(source_field, (IntegerField, DecimalField)): self._output_field = FloatField() - super(Avg, self)._resolve_output_field() + super()._resolve_output_field() def as_oracle(self, compiler, connection): if self.output_field.get_internal_type() == 'DurationField': @@ -54,7 +54,7 @@ def as_oracle(self, compiler, connection): return compiler.compile( SecondsToInterval(Avg(IntervalToSeconds(expression))) ) - return super(Avg, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) class Count(Aggregate): @@ -65,8 +65,10 @@ class Count(Aggregate): def __init__(self, expression, distinct=False, **extra): if expression == '*': expression = Star() - super(Count, self).__init__( - expression, distinct='DISTINCT ' if distinct else '', output_field=IntegerField(), **extra) + super().__init__( + expression, distinct='DISTINCT ' if distinct else '', + output_field=IntegerField(), **extra + ) def __repr__(self): return "{}({}, distinct={})".format( @@ -96,7 +98,7 @@ class StdDev(Aggregate): def __init__(self, expression, sample=False, **extra): self.function = 'STDDEV_SAMP' if sample else 'STDDEV_POP' - super(StdDev, self).__init__(expression, output_field=FloatField(), **extra) + super().__init__(expression, output_field=FloatField(), **extra) def __repr__(self): return "{}({}, sample={})".format( @@ -122,7 +124,7 @@ def as_oracle(self, compiler, connection): return compiler.compile( SecondsToInterval(Sum(IntervalToSeconds(expression))) ) - return super(Sum, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) class Variance(Aggregate): @@ -130,7 +132,7 @@ class Variance(Aggregate): def __init__(self, expression, sample=False, **extra): self.function = 'VAR_SAMP' if sample else 'VAR_POP' - super(Variance, self).__init__(expression, output_field=FloatField(), **extra) + super().__init__(expression, output_field=FloatField(), **extra) def __repr__(self): return "{}({}, sample={})".format( diff --git a/django/db/models/base.py b/django/db/models/base.py index 66b671698d32..497a18f51a86 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -73,7 +73,7 @@ class ModelBase(type): Metaclass for all models. """ def __new__(cls, name, bases, attrs): - super_new = super(ModelBase, cls).__new__ + super_new = super().__new__ # Also ensure initialization is only performed for subclasses of Model # (excluding Model class itself). @@ -486,7 +486,7 @@ def __init__(self, *args, **kwargs): pass if kwargs: raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0]) - super(Model, self).__init__() + super().__init__() post_init.send(sender=cls, instance=self) @classmethod diff --git a/django/db/models/deletion.py b/django/db/models/deletion.py index b0c61d179924..9da5caaedbdc 100644 --- a/django/db/models/deletion.py +++ b/django/db/models/deletion.py @@ -8,7 +8,7 @@ class ProtectedError(IntegrityError): def __init__(self, msg, protected_objects): self.protected_objects = protected_objects - super(ProtectedError, self).__init__(msg, protected_objects) + super().__init__(msg, protected_objects) def CASCADE(collector, field, sub_objs, using): diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index a1cec2393afe..fcbf867b9658 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -157,7 +157,7 @@ def as_sql(self, compiler, connection): ``` def override_as_sql(self, compiler, connection): # custom logic - return super(Expression, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) setattr(Expression, 'as_' + connection.vendor, override_as_sql) ``` @@ -351,7 +351,7 @@ class Expression(BaseExpression, Combinable): class CombinedExpression(Expression): def __init__(self, lhs, connector, rhs, output_field=None): - super(CombinedExpression, self).__init__(output_field=output_field) + super().__init__(output_field=output_field) self.connector = connector self.lhs = lhs self.rhs = rhs @@ -437,7 +437,7 @@ def as_sql(self, compiler, connection): class TemporalSubtraction(CombinedExpression): def __init__(self, lhs, rhs): - super(TemporalSubtraction, self).__init__(lhs, self.SUB, rhs, output_field=fields.DurationField()) + super().__init__(lhs, self.SUB, rhs, output_field=fields.DurationField()) def as_sql(self, compiler, connection): connection.ops.check_expression_support(self) @@ -517,7 +517,7 @@ def __init__(self, *expressions, **extra): ) ) output_field = extra.pop('output_field', None) - super(Func, self).__init__(output_field=output_field) + super().__init__(output_field=output_field) self.source_expressions = self._parse_expressions(*expressions) self.extra = extra @@ -573,7 +573,7 @@ def as_sqlite(self, compiler, connection): return sql, params def copy(self): - copy = super(Func, self).copy() + copy = super().copy() copy.source_expressions = self.source_expressions[:] copy.extra = self.extra.copy() return copy @@ -592,7 +592,7 @@ def __init__(self, value, output_field=None): * output_field: an instance of the model field type that this expression will return, such as IntegerField() or CharField(). """ - super(Value, self).__init__(output_field=output_field) + super().__init__(output_field=output_field) self.value = value def __repr__(self): @@ -617,7 +617,7 @@ def as_sql(self, compiler, connection): return '%s', [val] def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False): - c = super(Value, self).resolve_expression(query, allow_joins, reuse, summarize, for_save) + c = super().resolve_expression(query, allow_joins, reuse, summarize, for_save) c.for_save = for_save return c @@ -629,7 +629,7 @@ class DurationValue(Value): def as_sql(self, compiler, connection): connection.ops.check_expression_support(self) if connection.features.has_native_duration_field: - return super(DurationValue, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) return connection.ops.date_interval_sql(self.value) @@ -638,7 +638,7 @@ def __init__(self, sql, params, output_field=None): if output_field is None: output_field = fields.Field() self.sql, self.params = sql, params - super(RawSQL, self).__init__(output_field=output_field) + super().__init__(output_field=output_field) def __repr__(self): return "{}({}, {})".format(self.__class__.__name__, self.sql, self.params) @@ -660,7 +660,7 @@ def as_sql(self, compiler, connection): class Random(Expression): def __init__(self): - super(Random, self).__init__(output_field=fields.FloatField()) + super().__init__(output_field=fields.FloatField()) def __repr__(self): return "Random()" @@ -676,7 +676,7 @@ class Col(Expression): def __init__(self, alias, target, output_field=None): if output_field is None: output_field = target - super(Col, self).__init__(output_field=output_field) + super().__init__(output_field=output_field) self.alias, self.target = alias, target def __repr__(self): @@ -706,7 +706,7 @@ class Ref(Expression): qs.annotate(sum_cost=Sum('cost')) query. """ def __init__(self, refs, source): - super(Ref, self).__init__() + super().__init__() self.refs, self.source = refs, source def __repr__(self): @@ -740,7 +740,7 @@ class ExpressionWrapper(Expression): """ def __init__(self, expression, output_field): - super(ExpressionWrapper, self).__init__(output_field=output_field) + super().__init__(output_field=output_field) self.expression = expression def set_source_expressions(self, exprs): @@ -764,7 +764,7 @@ def __init__(self, condition=None, then=None, **lookups): condition, lookups = Q(**lookups), None if condition is None or not isinstance(condition, Q) or lookups: raise TypeError("__init__() takes either a Q object or lookups as keyword arguments") - super(When, self).__init__(output_field=None) + super().__init__(output_field=None) self.condition = condition self.result = self._parse_expressions(then)[0] @@ -833,7 +833,7 @@ def __init__(self, *cases, **extra): raise TypeError("Positional arguments must all be When objects.") default = extra.pop('default', None) output_field = extra.pop('output_field', None) - super(Case, self).__init__(output_field) + super().__init__(output_field) self.cases = list(cases) self.default = self._parse_expressions(default)[0] self.extra = extra @@ -860,7 +860,7 @@ def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize return c def copy(self): - c = super(Case, self).copy() + c = super().copy() c.cases = c.cases[:] return c @@ -905,10 +905,10 @@ def __init__(self, queryset, output_field=None, **extra): self.extra = extra if output_field is None and len(self.queryset.query.select) == 1: output_field = self.queryset.query.select[0].field - super(Subquery, self).__init__(output_field) + super().__init__(output_field) def copy(self): - clone = super(Subquery, self).copy() + clone = super().copy() clone.queryset = clone.queryset.all() return clone @@ -985,7 +985,7 @@ class Exists(Subquery): def __init__(self, *args, **kwargs): self.negated = kwargs.pop('negated', False) - super(Exists, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def __invert__(self): return type(self)(self.queryset, self.output_field, negated=(not self.negated), **self.extra) @@ -998,10 +998,10 @@ def resolve_expression(self, query=None, **kwargs): # As a performance optimization, remove ordering since EXISTS doesn't # care about it, just whether or not a row matches. self.queryset = self.queryset.order_by() - return super(Exists, self).resolve_expression(query, **kwargs) + return super().resolve_expression(query, **kwargs) def as_sql(self, compiler, connection, template=None, **extra_context): - sql, params = super(Exists, self).as_sql(compiler, connection, template, **extra_context) + sql, params = super().as_sql(compiler, connection, template, **extra_context) if self.negated: sql = 'NOT {}'.format(sql) return sql, params diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index fabd291159e3..bcaf0597a7e2 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -184,7 +184,7 @@ def __str__(self): models. """ if not hasattr(self, 'model'): - return super(Field, self).__str__() + return super().__str__() model = self.model app = model._meta.app_label return '%s.%s.%s' % (app, model._meta.object_name, self.name) @@ -867,10 +867,10 @@ class AutoField(Field): def __init__(self, *args, **kwargs): kwargs['blank'] = True - super(AutoField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def check(self, **kwargs): - errors = super(AutoField, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_primary_key()) return errors @@ -887,7 +887,7 @@ def _check_primary_key(self): return [] def deconstruct(self): - name, path, args, kwargs = super(AutoField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() del kwargs['blank'] kwargs['primary_key'] = True return name, path, args, kwargs @@ -920,14 +920,14 @@ def get_db_prep_value(self, value, connection, prepared=False): return value def get_prep_value(self, value): - value = super(AutoField, self).get_prep_value(value) + value = super().get_prep_value(value) if value is None: return None return int(value) def contribute_to_class(self, cls, name, **kwargs): assert not cls._meta.auto_field, "A model can't have more than one AutoField." - super(AutoField, self).contribute_to_class(cls, name, **kwargs) + super().contribute_to_class(cls, name, **kwargs) cls._meta.auto_field = self def formfield(self, **kwargs): @@ -953,10 +953,10 @@ class BooleanField(Field): def __init__(self, *args, **kwargs): kwargs['blank'] = True - super(BooleanField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def check(self, **kwargs): - errors = super(BooleanField, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_null(**kwargs)) return errors @@ -974,7 +974,7 @@ def _check_null(self, **kwargs): return [] def deconstruct(self): - name, path, args, kwargs = super(BooleanField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() del kwargs['blank'] return name, path, args, kwargs @@ -997,7 +997,7 @@ def to_python(self, value): ) def get_prep_value(self, value): - value = super(BooleanField, self).get_prep_value(value) + value = super().get_prep_value(value) if value is None: return None return self.to_python(value) @@ -1011,18 +1011,18 @@ def formfield(self, **kwargs): else: defaults = {'form_class': forms.BooleanField} defaults.update(kwargs) - return super(BooleanField, self).formfield(**defaults) + return super().formfield(**defaults) class CharField(Field): description = _("String (up to %(max_length)s)") def __init__(self, *args, **kwargs): - super(CharField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.validators.append(validators.MaxLengthValidator(self.max_length)) def check(self, **kwargs): - errors = super(CharField, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_max_length_attribute(**kwargs)) return errors @@ -1055,7 +1055,7 @@ def to_python(self, value): return force_text(value) def get_prep_value(self, value): - value = super(CharField, self).get_prep_value(value) + value = super().get_prep_value(value) return self.to_python(value) def formfield(self, **kwargs): @@ -1067,7 +1067,7 @@ def formfield(self, **kwargs): if self.null and not connection.features.interprets_empty_strings_as_nulls: defaults['empty_value'] = None defaults.update(kwargs) - return super(CharField, self).formfield(**defaults) + return super().formfield(**defaults) class CommaSeparatedIntegerField(CharField): @@ -1089,7 +1089,7 @@ class CommaSeparatedIntegerField(CharField): class DateTimeCheckMixin: def check(self, **kwargs): - errors = super(DateTimeCheckMixin, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_mutually_exclusive_options()) errors.extend(self._check_fix_default_value()) return errors @@ -1133,7 +1133,7 @@ def __init__(self, verbose_name=None, name=None, auto_now=False, if auto_now or auto_now_add: kwargs['editable'] = False kwargs['blank'] = True - super(DateField, self).__init__(verbose_name, name, **kwargs) + super().__init__(verbose_name, name, **kwargs) def _check_fix_default_value(self): """ @@ -1179,7 +1179,7 @@ def _check_fix_default_value(self): return [] def deconstruct(self): - name, path, args, kwargs = super(DateField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() if self.auto_now: kwargs['auto_now'] = True if self.auto_now_add: @@ -1228,10 +1228,10 @@ def pre_save(self, model_instance, add): setattr(model_instance, self.attname, value) return value else: - return super(DateField, self).pre_save(model_instance, add) + return super().pre_save(model_instance, add) def contribute_to_class(self, cls, name, **kwargs): - super(DateField, self).contribute_to_class(cls, name, **kwargs) + super().contribute_to_class(cls, name, **kwargs) if not self.null: setattr( cls, 'get_next_by_%s' % self.name, @@ -1243,7 +1243,7 @@ def contribute_to_class(self, cls, name, **kwargs): ) def get_prep_value(self, value): - value = super(DateField, self).get_prep_value(value) + value = super().get_prep_value(value) return self.to_python(value) def get_db_prep_value(self, value, connection, prepared=False): @@ -1259,7 +1259,7 @@ def value_to_string(self, obj): def formfield(self, **kwargs): defaults = {'form_class': forms.DateField} defaults.update(kwargs) - return super(DateField, self).formfield(**defaults) + return super().formfield(**defaults) class DateTimeField(DateField): @@ -1380,13 +1380,13 @@ def pre_save(self, model_instance, add): setattr(model_instance, self.attname, value) return value else: - return super(DateTimeField, self).pre_save(model_instance, add) + return super().pre_save(model_instance, add) # contribute_to_class is inherited from DateField, it registers # get_next_by_FOO and get_prev_by_FOO def get_prep_value(self, value): - value = super(DateTimeField, self).get_prep_value(value) + value = super().get_prep_value(value) value = self.to_python(value) if value is not None and settings.USE_TZ and timezone.is_naive(value): # For backwards compatibility, interpret naive datetimes in local @@ -1417,7 +1417,7 @@ def value_to_string(self, obj): def formfield(self, **kwargs): defaults = {'form_class': forms.DateTimeField} defaults.update(kwargs) - return super(DateTimeField, self).formfield(**defaults) + return super().formfield(**defaults) class DecimalField(Field): @@ -1430,10 +1430,10 @@ class DecimalField(Field): def __init__(self, verbose_name=None, name=None, max_digits=None, decimal_places=None, **kwargs): self.max_digits, self.decimal_places = max_digits, decimal_places - super(DecimalField, self).__init__(verbose_name, name, **kwargs) + super().__init__(verbose_name, name, **kwargs) def check(self, **kwargs): - errors = super(DecimalField, self).check(**kwargs) + errors = super().check(**kwargs) digits_errors = self._check_decimal_places() digits_errors.extend(self._check_max_digits()) @@ -1504,12 +1504,12 @@ def _check_decimal_places_and_max_digits(self, **kwargs): @cached_property def validators(self): - return super(DecimalField, self).validators + [ + return super().validators + [ validators.DecimalValidator(self.max_digits, self.decimal_places) ] def deconstruct(self): - name, path, args, kwargs = super(DecimalField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() if self.max_digits is not None: kwargs['max_digits'] = self.max_digits if self.decimal_places is not None: @@ -1555,7 +1555,7 @@ def get_db_prep_save(self, value, connection): return connection.ops.adapt_decimalfield_value(self.to_python(value), self.max_digits, self.decimal_places) def get_prep_value(self, value): - value = super(DecimalField, self).get_prep_value(value) + value = super().get_prep_value(value) return self.to_python(value) def formfield(self, **kwargs): @@ -1565,7 +1565,7 @@ def formfield(self, **kwargs): 'form_class': forms.DecimalField, } defaults.update(kwargs) - return super(DecimalField, self).formfield(**defaults) + return super().formfield(**defaults) class DurationField(Field): @@ -1615,7 +1615,7 @@ def get_db_converters(self, connection): converters = [] if not connection.features.has_native_duration_field: converters.append(connection.ops.convert_durationfield_value) - return converters + super(DurationField, self).get_db_converters(connection) + return converters + super().get_db_converters(connection) def value_to_string(self, obj): val = self.value_from_object(obj) @@ -1626,7 +1626,7 @@ def formfield(self, **kwargs): 'form_class': forms.DurationField, } defaults.update(kwargs) - return super(DurationField, self).formfield(**defaults) + return super().formfield(**defaults) class EmailField(CharField): @@ -1636,10 +1636,10 @@ class EmailField(CharField): def __init__(self, *args, **kwargs): # max_length=254 to be compliant with RFCs 3696 and 5321 kwargs['max_length'] = kwargs.get('max_length', 254) - super(EmailField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def deconstruct(self): - name, path, args, kwargs = super(EmailField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() # We do not exclude max_length if it matches default as we want to change # the default in future. return name, path, args, kwargs @@ -1651,7 +1651,7 @@ def formfield(self, **kwargs): 'form_class': forms.EmailField, } defaults.update(kwargs) - return super(EmailField, self).formfield(**defaults) + return super().formfield(**defaults) class FilePathField(Field): @@ -1662,10 +1662,10 @@ def __init__(self, verbose_name=None, name=None, path='', match=None, self.path, self.match, self.recursive = path, match, recursive self.allow_files, self.allow_folders = allow_files, allow_folders kwargs['max_length'] = kwargs.get('max_length', 100) - super(FilePathField, self).__init__(verbose_name, name, **kwargs) + super().__init__(verbose_name, name, **kwargs) def check(self, **kwargs): - errors = super(FilePathField, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_allowing_files_or_folders(**kwargs)) return errors @@ -1681,7 +1681,7 @@ def _check_allowing_files_or_folders(self, **kwargs): return [] def deconstruct(self): - name, path, args, kwargs = super(FilePathField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() if self.path != '': kwargs['path'] = self.path if self.match is not None: @@ -1697,7 +1697,7 @@ def deconstruct(self): return name, path, args, kwargs def get_prep_value(self, value): - value = super(FilePathField, self).get_prep_value(value) + value = super().get_prep_value(value) if value is None: return None return str(value) @@ -1712,7 +1712,7 @@ def formfield(self, **kwargs): 'allow_folders': self.allow_folders, } defaults.update(kwargs) - return super(FilePathField, self).formfield(**defaults) + return super().formfield(**defaults) def get_internal_type(self): return "FilePathField" @@ -1726,7 +1726,7 @@ class FloatField(Field): description = _("Floating point number") def get_prep_value(self, value): - value = super(FloatField, self).get_prep_value(value) + value = super().get_prep_value(value) if value is None: return None return float(value) @@ -1749,7 +1749,7 @@ def to_python(self, value): def formfield(self, **kwargs): defaults = {'form_class': forms.FloatField} defaults.update(kwargs) - return super(FloatField, self).formfield(**defaults) + return super().formfield(**defaults) class IntegerField(Field): @@ -1760,7 +1760,7 @@ class IntegerField(Field): description = _("Integer") def check(self, **kwargs): - errors = super(IntegerField, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_max_length_warning()) return errors @@ -1780,7 +1780,7 @@ def _check_max_length_warning(self): def validators(self): # These validators can't be added at field initialization time since # they're based on values retrieved from `connection`. - validators_ = super(IntegerField, self).validators + validators_ = super().validators internal_type = self.get_internal_type() min_value, max_value = connection.ops.integer_field_range(internal_type) if min_value is not None: @@ -1798,7 +1798,7 @@ def validators(self): return validators_ def get_prep_value(self, value): - value = super(IntegerField, self).get_prep_value(value) + value = super().get_prep_value(value) if value is None: return None return int(value) @@ -1821,7 +1821,7 @@ def to_python(self, value): def formfield(self, **kwargs): defaults = {'form_class': forms.IntegerField} defaults.update(kwargs) - return super(IntegerField, self).formfield(**defaults) + return super().formfield(**defaults) class BigIntegerField(IntegerField): @@ -1836,7 +1836,7 @@ def formfield(self, **kwargs): defaults = {'min_value': -BigIntegerField.MAX_BIGINT - 1, 'max_value': BigIntegerField.MAX_BIGINT} defaults.update(kwargs) - return super(BigIntegerField, self).formfield(**defaults) + return super().formfield(**defaults) class IPAddressField(Field): @@ -1853,15 +1853,15 @@ class IPAddressField(Field): def __init__(self, *args, **kwargs): kwargs['max_length'] = 15 - super(IPAddressField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def deconstruct(self): - name, path, args, kwargs = super(IPAddressField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() del kwargs['max_length'] return name, path, args, kwargs def get_prep_value(self, value): - value = super(IPAddressField, self).get_prep_value(value) + value = super().get_prep_value(value) if value is None: return None return str(value) @@ -1883,11 +1883,10 @@ def __init__(self, verbose_name=None, name=None, protocol='both', validators.ip_address_validators(protocol, unpack_ipv4) self.default_error_messages['invalid'] = invalid_error_message kwargs['max_length'] = 39 - super(GenericIPAddressField, self).__init__(verbose_name, name, *args, - **kwargs) + super().__init__(verbose_name, name, *args, **kwargs) def check(self, **kwargs): - errors = super(GenericIPAddressField, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_blank_and_null_values(**kwargs)) return errors @@ -1904,7 +1903,7 @@ def _check_blank_and_null_values(self, **kwargs): return [] def deconstruct(self): - name, path, args, kwargs = super(GenericIPAddressField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() if self.unpack_ipv4 is not False: kwargs['unpack_ipv4'] = self.unpack_ipv4 if self.protocol != "both": @@ -1932,7 +1931,7 @@ def get_db_prep_value(self, value, connection, prepared=False): return connection.ops.adapt_ipaddressfield_value(value) def get_prep_value(self, value): - value = super(GenericIPAddressField, self).get_prep_value(value) + value = super().get_prep_value(value) if value is None: return None if value and ':' in value: @@ -1948,7 +1947,7 @@ def formfield(self, **kwargs): 'form_class': forms.GenericIPAddressField, } defaults.update(kwargs) - return super(GenericIPAddressField, self).formfield(**defaults) + return super().formfield(**defaults) class NullBooleanField(Field): @@ -1961,10 +1960,10 @@ class NullBooleanField(Field): def __init__(self, *args, **kwargs): kwargs['null'] = True kwargs['blank'] = True - super(NullBooleanField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def deconstruct(self): - name, path, args, kwargs = super(NullBooleanField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() del kwargs['null'] del kwargs['blank'] return name, path, args, kwargs @@ -1990,7 +1989,7 @@ def to_python(self, value): ) def get_prep_value(self, value): - value = super(NullBooleanField, self).get_prep_value(value) + value = super().get_prep_value(value) if value is None: return None return self.to_python(value) @@ -1998,7 +1997,7 @@ def get_prep_value(self, value): def formfield(self, **kwargs): defaults = {'form_class': forms.NullBooleanField} defaults.update(kwargs) - return super(NullBooleanField, self).formfield(**defaults) + return super().formfield(**defaults) class PositiveIntegerRelDbTypeMixin: @@ -2027,7 +2026,7 @@ def get_internal_type(self): def formfield(self, **kwargs): defaults = {'min_value': 0} defaults.update(kwargs) - return super(PositiveIntegerField, self).formfield(**defaults) + return super().formfield(**defaults) class PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField): @@ -2039,7 +2038,7 @@ def get_internal_type(self): def formfield(self, **kwargs): defaults = {'min_value': 0} defaults.update(kwargs) - return super(PositiveSmallIntegerField, self).formfield(**defaults) + return super().formfield(**defaults) class SlugField(CharField): @@ -2054,10 +2053,10 @@ def __init__(self, *args, **kwargs): self.allow_unicode = kwargs.pop('allow_unicode', False) if self.allow_unicode: self.default_validators = [validators.validate_unicode_slug] - super(SlugField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def deconstruct(self): - name, path, args, kwargs = super(SlugField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() if kwargs.get("max_length") == 50: del kwargs['max_length'] if self.db_index is False: @@ -2074,7 +2073,7 @@ def get_internal_type(self): def formfield(self, **kwargs): defaults = {'form_class': forms.SlugField, 'allow_unicode': self.allow_unicode} defaults.update(kwargs) - return super(SlugField, self).formfield(**defaults) + return super().formfield(**defaults) class SmallIntegerField(IntegerField): @@ -2096,7 +2095,7 @@ def to_python(self, value): return force_text(value) def get_prep_value(self, value): - value = super(TextField, self).get_prep_value(value) + value = super().get_prep_value(value) return self.to_python(value) def formfield(self, **kwargs): @@ -2105,7 +2104,7 @@ def formfield(self, **kwargs): # the value in the form field (to pass into widget for example). defaults = {'max_length': self.max_length, 'widget': forms.Textarea} defaults.update(kwargs) - return super(TextField, self).formfield(**defaults) + return super().formfield(**defaults) class TimeField(DateTimeCheckMixin, Field): @@ -2124,7 +2123,7 @@ def __init__(self, verbose_name=None, name=None, auto_now=False, if auto_now or auto_now_add: kwargs['editable'] = False kwargs['blank'] = True - super(TimeField, self).__init__(verbose_name, name, **kwargs) + super().__init__(verbose_name, name, **kwargs) def _check_fix_default_value(self): """ @@ -2173,7 +2172,7 @@ def _check_fix_default_value(self): return [] def deconstruct(self): - name, path, args, kwargs = super(TimeField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() if self.auto_now is not False: kwargs["auto_now"] = self.auto_now if self.auto_now_add is not False: @@ -2220,10 +2219,10 @@ def pre_save(self, model_instance, add): setattr(model_instance, self.attname, value) return value else: - return super(TimeField, self).pre_save(model_instance, add) + return super().pre_save(model_instance, add) def get_prep_value(self, value): - value = super(TimeField, self).get_prep_value(value) + value = super().get_prep_value(value) return self.to_python(value) def get_db_prep_value(self, value, connection, prepared=False): @@ -2239,7 +2238,7 @@ def value_to_string(self, obj): def formfield(self, **kwargs): defaults = {'form_class': forms.TimeField} defaults.update(kwargs) - return super(TimeField, self).formfield(**defaults) + return super().formfield(**defaults) class URLField(CharField): @@ -2248,10 +2247,10 @@ class URLField(CharField): def __init__(self, verbose_name=None, name=None, **kwargs): kwargs['max_length'] = kwargs.get('max_length', 200) - super(URLField, self).__init__(verbose_name, name, **kwargs) + super().__init__(verbose_name, name, **kwargs) def deconstruct(self): - name, path, args, kwargs = super(URLField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() if kwargs.get("max_length") == 200: del kwargs['max_length'] return name, path, args, kwargs @@ -2263,7 +2262,7 @@ def formfield(self, **kwargs): 'form_class': forms.URLField, } defaults.update(kwargs) - return super(URLField, self).formfield(**defaults) + return super().formfield(**defaults) class BinaryField(Field): @@ -2272,12 +2271,12 @@ class BinaryField(Field): def __init__(self, *args, **kwargs): kwargs['editable'] = False - super(BinaryField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) if self.max_length is not None: self.validators.append(validators.MaxLengthValidator(self.max_length)) def deconstruct(self): - name, path, args, kwargs = super(BinaryField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() del kwargs['editable'] return name, path, args, kwargs @@ -2290,13 +2289,13 @@ def get_placeholder(self, value, compiler, connection): def get_default(self): if self.has_default() and not callable(self.default): return self.default - default = super(BinaryField, self).get_default() + default = super().get_default() if default == '': return b'' return default def get_db_prep_value(self, value, connection, prepared=False): - value = super(BinaryField, self).get_db_prep_value(value, connection, prepared) + value = super().get_db_prep_value(value, connection, prepared) if value is not None: return connection.Database.Binary(value) return value @@ -2321,10 +2320,10 @@ class UUIDField(Field): def __init__(self, verbose_name=None, **kwargs): kwargs['max_length'] = 32 - super(UUIDField, self).__init__(verbose_name, **kwargs) + super().__init__(verbose_name, **kwargs) def deconstruct(self): - name, path, args, kwargs = super(UUIDField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() del kwargs['max_length'] return name, path, args, kwargs @@ -2358,4 +2357,4 @@ def formfield(self, **kwargs): 'form_class': forms.UUIDField, } defaults.update(kwargs) - return super(UUIDField, self).formfield(**defaults) + return super().formfield(**defaults) diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index 4e678ea67278..60ac33ff63f3 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -15,7 +15,7 @@ class FieldFile(File): def __init__(self, instance, field, name): - super(FieldFile, self).__init__(None, name) + super().__init__(None, name) self.instance = instance self.field = field self.storage = field.storage @@ -228,10 +228,10 @@ def __init__(self, verbose_name=None, name=None, upload_to='', storage=None, **k self.upload_to = upload_to kwargs['max_length'] = kwargs.get('max_length', 100) - super(FileField, self).__init__(verbose_name, name, **kwargs) + super().__init__(verbose_name, name, **kwargs) def check(self, **kwargs): - errors = super(FileField, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_primary_key()) errors.extend(self._check_upload_to()) return errors @@ -263,7 +263,7 @@ def _check_upload_to(self): return [] def deconstruct(self): - name, path, args, kwargs = super(FileField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() if kwargs.get("max_length") == 100: del kwargs["max_length"] kwargs['upload_to'] = self.upload_to @@ -276,7 +276,7 @@ def get_internal_type(self): def get_prep_value(self, value): "Returns field's value prepared for saving into a database." - value = super(FileField, self).get_prep_value(value) + value = super().get_prep_value(value) # Need to convert File objects provided via a form to string for database insertion if value is None: return None @@ -284,14 +284,14 @@ def get_prep_value(self, value): def pre_save(self, model_instance, add): "Returns field's value just before saving." - file = super(FileField, self).pre_save(model_instance, add) + file = super().pre_save(model_instance, add) if file and not file._committed: # Commit the file to storage prior to saving the model file.save(file.name, file.file, save=False) return file def contribute_to_class(self, cls, name, **kwargs): - super(FileField, self).contribute_to_class(cls, name, **kwargs) + super().contribute_to_class(cls, name, **kwargs) setattr(cls, self.name, self.descriptor_class(self)) def generate_filename(self, instance, filename): @@ -330,7 +330,7 @@ def formfield(self, **kwargs): if 'initial' in kwargs: defaults['required'] = False defaults.update(kwargs) - return super(FileField, self).formfield(**defaults) + return super().formfield(**defaults) class ImageFileDescriptor(FileDescriptor): @@ -340,7 +340,7 @@ class ImageFileDescriptor(FileDescriptor): """ def __set__(self, instance, value): previous_file = instance.__dict__.get(self.field.name) - super(ImageFileDescriptor, self).__set__(instance, value) + super().__set__(instance, value) # To prevent recalculating image dimensions when we are instantiating # an object from the database (bug #11084), only update dimensions if @@ -360,7 +360,7 @@ def delete(self, save=True): # Clear the image dimensions cache if hasattr(self, '_dimensions_cache'): del self._dimensions_cache - super(ImageFieldFile, self).delete(save) + super().delete(save) class ImageField(FileField): @@ -371,10 +371,10 @@ class ImageField(FileField): def __init__(self, verbose_name=None, name=None, width_field=None, height_field=None, **kwargs): self.width_field, self.height_field = width_field, height_field - super(ImageField, self).__init__(verbose_name, name, **kwargs) + super().__init__(verbose_name, name, **kwargs) def check(self, **kwargs): - errors = super(ImageField, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_image_library_installed()) return errors @@ -395,7 +395,7 @@ def _check_image_library_installed(self): return [] def deconstruct(self): - name, path, args, kwargs = super(ImageField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() if self.width_field: kwargs['width_field'] = self.width_field if self.height_field: @@ -403,7 +403,7 @@ def deconstruct(self): return name, path, args, kwargs def contribute_to_class(self, cls, name, **kwargs): - super(ImageField, self).contribute_to_class(cls, name, **kwargs) + super().contribute_to_class(cls, name, **kwargs) # Attach update_dimension_fields so that dimension fields declared # after their corresponding image field don't stay cleared by # Model.__init__, see bug #11196. @@ -471,4 +471,4 @@ def update_dimension_fields(self, instance, force=False, *args, **kwargs): def formfield(self, **kwargs): defaults = {'form_class': forms.ImageField} defaults.update(kwargs) - return super(ImageField, self).formfield(**defaults) + return super().formfield(**defaults) diff --git a/django/db/models/fields/proxy.py b/django/db/models/fields/proxy.py index 19beb89011e4..f89cd3db4668 100644 --- a/django/db/models/fields/proxy.py +++ b/django/db/models/fields/proxy.py @@ -15,9 +15,9 @@ class OrderWrt(fields.IntegerField): def __init__(self, *args, **kwargs): kwargs['name'] = '_order' kwargs['editable'] = False - super(OrderWrt, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def deconstruct(self): - name, path, args, kwargs = super(OrderWrt, self).deconstruct() + name, path, args, kwargs = super().deconstruct() del kwargs['editable'] return name, path, args, kwargs diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 855bf38ea075..dd84d780fb42 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -97,7 +97,7 @@ def related_model(self): return self.remote_field.model def check(self, **kwargs): - errors = super(RelatedField, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_related_name_is_valid()) errors.extend(self._check_related_query_name_is_valid()) errors.extend(self._check_relation_model_exists()) @@ -294,7 +294,7 @@ def db_type(self, connection): def contribute_to_class(self, cls, name, private_only=False, **kwargs): - super(RelatedField, self).contribute_to_class(cls, name, private_only=private_only, **kwargs) + super().contribute_to_class(cls, name, private_only=private_only, **kwargs) self.opts = cls._meta @@ -412,7 +412,7 @@ def formfield(self, **kwargs): 'limit_choices_to': limit_choices_to, }) defaults.update(kwargs) - return super(RelatedField, self).formfield(**defaults) + return super().formfield(**defaults) def related_query_name(self): """ @@ -464,14 +464,14 @@ def __init__(self, to, on_delete, from_fields, to_fields, rel=None, related_name on_delete=on_delete, ) - super(ForeignObject, self).__init__(rel=rel, **kwargs) + super().__init__(rel=rel, **kwargs) self.from_fields = from_fields self.to_fields = to_fields self.swappable = swappable def check(self, **kwargs): - errors = super(ForeignObject, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_to_fields_exist()) errors.extend(self._check_unique_target()) return errors @@ -555,7 +555,7 @@ def _check_unique_target(self): return [] def deconstruct(self): - name, path, args, kwargs = super(ForeignObject, self).deconstruct() + name, path, args, kwargs = super().deconstruct() kwargs['on_delete'] = self.remote_field.on_delete kwargs['from_fields'] = self.from_fields kwargs['to_fields'] = self.to_fields @@ -653,7 +653,7 @@ def get_instance_value_for_fields(instance, fields): return tuple(ret) def get_attname_column(self): - attname, column = super(ForeignObject, self).get_attname_column() + attname, column = super().get_attname_column() return attname, None def get_joining_columns(self, reverse_join=False): @@ -718,7 +718,7 @@ def get_lookups(cls): return cls.merge_dicts(class_lookups) def contribute_to_class(self, cls, name, private_only=False, **kwargs): - super(ForeignObject, self).contribute_to_class(cls, name, private_only=private_only, **kwargs) + super().contribute_to_class(cls, name, private_only=private_only, **kwargs) setattr(cls, self.name, self.forward_related_accessor_class(self)) def contribute_to_related_class(self, cls, related): @@ -795,13 +795,12 @@ def __init__(self, to, on_delete, related_name=None, related_query_name=None, kwargs['db_index'] = kwargs.get('db_index', True) - super(ForeignKey, self).__init__( - to, on_delete, from_fields=['self'], to_fields=[to_field], **kwargs) + super().__init__(to, on_delete, from_fields=['self'], to_fields=[to_field], **kwargs) self.db_constraint = db_constraint def check(self, **kwargs): - errors = super(ForeignKey, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_on_delete()) errors.extend(self._check_unique()) return errors @@ -840,7 +839,7 @@ def _check_unique(self, **kwargs): ] if self.unique else [] def deconstruct(self): - name, path, args, kwargs = super(ForeignKey, self).deconstruct() + name, path, args, kwargs = super().deconstruct() del kwargs['to_fields'] del kwargs['from_fields'] # Handle the simpler arguments @@ -873,7 +872,7 @@ def get_reverse_path_info(self): def validate(self, value, model_instance): if self.remote_field.parent_link: return - super(ForeignKey, self).validate(value, model_instance) + super().validate(value, model_instance) if value is None: return @@ -902,7 +901,7 @@ def get_attname_column(self): def get_default(self): "Here we check if the default value is an object and return the to_field if so." - field_default = super(ForeignKey, self).get_default() + field_default = super().get_default() if isinstance(field_default, self.remote_field.model): return getattr(field_default, self.target_field.attname) return field_default @@ -919,7 +918,7 @@ def get_db_prep_value(self, value, connection, prepared=False): return self.target_field.get_db_prep_value(value, connection, prepared) def contribute_to_related_class(self, cls, related): - super(ForeignKey, self).contribute_to_related_class(cls, related) + super().contribute_to_related_class(cls, related) if self.remote_field.field_name is None: self.remote_field.field_name = cls._meta.pk.name @@ -935,7 +934,7 @@ def formfield(self, **kwargs): 'to_field_name': self.remote_field.field_name, } defaults.update(kwargs) - return super(ForeignKey, self).formfield(**defaults) + return super().formfield(**defaults) def db_check(self, connection): return [] @@ -952,13 +951,13 @@ def convert_empty_strings(self, value, expression, connection, context): return value def get_db_converters(self, connection): - converters = super(ForeignKey, self).get_db_converters(connection) + converters = super().get_db_converters(connection) if connection.features.interprets_empty_strings_as_nulls: converters += [self.convert_empty_strings] return converters def get_col(self, alias, output_field=None): - return super(ForeignKey, self).get_col(alias, output_field or self.target_field) + return super().get_col(alias, output_field or self.target_field) class OneToOneField(ForeignKey): @@ -983,10 +982,10 @@ class OneToOneField(ForeignKey): def __init__(self, to, on_delete, to_field=None, **kwargs): kwargs['unique'] = True - super(OneToOneField, self).__init__(to, on_delete, to_field=to_field, **kwargs) + super().__init__(to, on_delete, to_field=to_field, **kwargs) def deconstruct(self): - name, path, args, kwargs = super(OneToOneField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() if "unique" in kwargs: del kwargs['unique'] return name, path, args, kwargs @@ -994,7 +993,7 @@ def deconstruct(self): def formfield(self, **kwargs): if self.remote_field.parent_link: return None - return super(OneToOneField, self).formfield(**kwargs) + return super().formfield(**kwargs) def save_form_data(self, instance, data): if isinstance(data, self.remote_field.model): @@ -1107,13 +1106,13 @@ def __init__(self, to, related_name=None, related_query_name=None, ) self.has_null_arg = 'null' in kwargs - super(ManyToManyField, self).__init__(**kwargs) + super().__init__(**kwargs) self.db_table = db_table self.swappable = swappable def check(self, **kwargs): - errors = super(ManyToManyField, self).check(**kwargs) + errors = super().check(**kwargs) errors.extend(self._check_unique(**kwargs)) errors.extend(self._check_relationship_model(**kwargs)) errors.extend(self._check_ignored_options(**kwargs)) @@ -1396,7 +1395,7 @@ def _get_field_name(model): return [] def deconstruct(self): - name, path, args, kwargs = super(ManyToManyField, self).deconstruct() + name, path, args, kwargs = super().deconstruct() # Handle the simpler arguments. if self.db_table is not None: kwargs['db_table'] = self.db_table @@ -1558,7 +1557,7 @@ def contribute_to_class(self, cls, name, **kwargs): # clashes between multiple m2m fields with related_name == '+'. self.remote_field.related_name = "_%s_%s_+" % (cls.__name__.lower(), name) - super(ManyToManyField, self).contribute_to_class(cls, name, **kwargs) + super().contribute_to_class(cls, name, **kwargs) # The intermediate m2m model is not auto created if: # 1) There is a manually specified intermediate, or @@ -1624,7 +1623,7 @@ def formfield(self, **kwargs): if callable(initial): initial = initial() defaults['initial'] = [i._get_pk_val() for i in initial] - return super(ManyToManyField, self).formfield(**defaults) + return super().formfield(**defaults) def db_check(self, connection): return None diff --git a/django/db/models/fields/related_descriptors.py b/django/db/models/fields/related_descriptors.py index a878a79acde1..b3e87cd482d2 100644 --- a/django/db/models/fields/related_descriptors.py +++ b/django/db/models/fields/related_descriptors.py @@ -272,7 +272,7 @@ def get_object(self, instance): if not any(field in fields for field in deferred): kwargs = {field: getattr(instance, field) for field in fields} return rel_model(**kwargs) - return super(ForwardOneToOneDescriptor, self).get_object(instance) + return super().get_object(instance) class ReverseOneToOneDescriptor: @@ -502,7 +502,7 @@ def create_reverse_many_to_one_manager(superclass, rel): class RelatedManager(superclass): def __init__(self, instance): - super(RelatedManager, self).__init__() + super().__init__() self.instance = instance self.model = rel.related_model @@ -545,12 +545,12 @@ def get_queryset(self): try: return self.instance._prefetched_objects_cache[self.field.related_query_name()] except (AttributeError, KeyError): - queryset = super(RelatedManager, self).get_queryset() + queryset = super().get_queryset() return self._apply_rel_filters(queryset) def get_prefetch_queryset(self, instances, queryset=None): if queryset is None: - queryset = super(RelatedManager, self).get_queryset() + queryset = super().get_queryset() queryset._add_hints(instance=instances[0]) queryset = queryset.using(queryset._db or self._db) @@ -708,7 +708,7 @@ class built by ``create_forward_many_to_many_manager()`` defined below. """ def __init__(self, rel, reverse=False): - super(ManyToManyDescriptor, self).__init__(rel) + super().__init__(rel) self.reverse = reverse @@ -746,7 +746,7 @@ def create_forward_many_to_many_manager(superclass, rel, reverse): class ManyRelatedManager(superclass): def __init__(self, instance=None): - super(ManyRelatedManager, self).__init__() + super().__init__() self.instance = instance @@ -834,12 +834,12 @@ def get_queryset(self): try: return self.instance._prefetched_objects_cache[self.prefetch_cache_name] except (AttributeError, KeyError): - queryset = super(ManyRelatedManager, self).get_queryset() + queryset = super().get_queryset() return self._apply_rel_filters(queryset) def get_prefetch_queryset(self, instances, queryset=None): if queryset is None: - queryset = super(ManyRelatedManager, self).get_queryset() + queryset = super().get_queryset() queryset._add_hints(instance=instances[0]) queryset = queryset.using(queryset._db or self._db) @@ -914,7 +914,7 @@ def clear(self): model=self.model, pk_set=None, using=db, ) self._remove_prefetched_objects() - filters = self._build_remove_filters(super(ManyRelatedManager, self).get_queryset().using(db)) + filters = self._build_remove_filters(super().get_queryset().using(db)) self.through._default_manager.using(db).filter(filters).delete() signals.m2m_changed.send( @@ -1091,7 +1091,7 @@ def _remove_items(self, source_field_name, target_field_name, *objs): instance=self.instance, reverse=self.reverse, model=self.model, pk_set=old_ids, using=db, ) - target_model_qs = super(ManyRelatedManager, self).get_queryset() + target_model_qs = super().get_queryset() if target_model_qs._has_filters(): old_vals = target_model_qs.using(db).filter(**{ '%s__in' % self.target_field.target_field.attname: old_ids}) diff --git a/django/db/models/fields/related_lookups.py b/django/db/models/fields/related_lookups.py index bc80c7cb0238..8063ea801a26 100644 --- a/django/db/models/fields/related_lookups.py +++ b/django/db/models/fields/related_lookups.py @@ -54,7 +54,7 @@ def get_prep_lookup(self): # only one as we don't get to the direct value branch otherwise. target_field = self.lhs.output_field.get_path_info()[-1].target_fields[-1] self.rhs = [target_field.get_prep_value(v) for v in self.rhs] - return super(RelatedIn, self).get_prep_lookup() + return super().get_prep_lookup() def as_sql(self, compiler, connection): if isinstance(self.lhs, MultiColSource): @@ -91,7 +91,7 @@ def as_sql(self, compiler, connection): else: target_field = self.lhs.field.target_field.name self.rhs.add_fields([target_field], True) - return super(RelatedIn, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) class RelatedLookupMixin: @@ -109,7 +109,7 @@ def get_prep_lookup(self): target_field = self.lhs.output_field.get_path_info()[-1].target_fields[-1] self.rhs = target_field.get_prep_value(self.rhs) - return super(RelatedLookupMixin, self).get_prep_lookup() + return super().get_prep_lookup() def as_sql(self, compiler, connection): if isinstance(self.lhs, MultiColSource): @@ -122,7 +122,7 @@ def as_sql(self, compiler, connection): root_constraint.add( lookup_class(target.get_col(self.lhs.alias, source), val), AND) return root_constraint.as_sql(compiler, connection) - return super(RelatedLookupMixin, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) class RelatedExact(RelatedLookupMixin, Exact): diff --git a/django/db/models/fields/reverse_related.py b/django/db/models/fields/reverse_related.py index 4e835e83023e..3d5439ab84e8 100644 --- a/django/db/models/fields/reverse_related.py +++ b/django/db/models/fields/reverse_related.py @@ -187,7 +187,7 @@ class ManyToOneRel(ForeignObjectRel): def __init__(self, field, to, field_name, related_name=None, related_query_name=None, limit_choices_to=None, parent_link=False, on_delete=None): - super(ManyToOneRel, self).__init__( + super().__init__( field, to, related_name=related_name, related_query_name=related_query_name, @@ -226,7 +226,7 @@ class OneToOneRel(ManyToOneRel): def __init__(self, field, to, field_name, related_name=None, related_query_name=None, limit_choices_to=None, parent_link=False, on_delete=None): - super(OneToOneRel, self).__init__( + super().__init__( field, to, field_name, related_name=related_name, related_query_name=related_query_name, @@ -249,7 +249,7 @@ class ManyToManyRel(ForeignObjectRel): def __init__(self, field, to, related_name=None, related_query_name=None, limit_choices_to=None, symmetrical=True, through=None, through_fields=None, db_constraint=True): - super(ManyToManyRel, self).__init__( + super().__init__( field, to, related_name=related_name, related_query_name=related_query_name, diff --git a/django/db/models/functions/base.py b/django/db/models/functions/base.py index ca73340b85ee..e9bf01ff0dca 100644 --- a/django/db/models/functions/base.py +++ b/django/db/models/functions/base.py @@ -18,12 +18,12 @@ class Cast(Func): } def __init__(self, expression, output_field): - super(Cast, self).__init__(expression, output_field=output_field) + super().__init__(expression, output_field=output_field) def as_sql(self, compiler, connection, **extra_context): if 'db_type' not in extra_context: extra_context['db_type'] = self._output_field.db_type(connection) - return super(Cast, self).as_sql(compiler, connection, **extra_context) + return super().as_sql(compiler, connection, **extra_context) def as_mysql(self, compiler, connection): extra_context = {} @@ -46,7 +46,7 @@ class Coalesce(Func): def __init__(self, *expressions, **extra): if len(expressions) < 2: raise ValueError('Coalesce must take at least two expressions') - super(Coalesce, self).__init__(*expressions, **extra) + super().__init__(*expressions, **extra) def as_oracle(self, compiler, connection): # we can't mix TextField (NCLOB) and CharField (NVARCHAR), so convert @@ -72,7 +72,7 @@ class ConcatPair(Func): function = 'CONCAT' def __init__(self, left, right, **extra): - super(ConcatPair, self).__init__(left, right, **extra) + super().__init__(left, right, **extra) def as_sqlite(self, compiler, connection): coalesced = self.coalesce() @@ -82,7 +82,7 @@ def as_sqlite(self, compiler, connection): def as_mysql(self, compiler, connection): # Use CONCAT_WS with an empty separator so that NULLs are ignored. - return super(ConcatPair, self).as_sql( + return super().as_sql( compiler, connection, function='CONCAT_WS', template="%(function)s('', %(expressions)s)" ) @@ -109,7 +109,7 @@ def __init__(self, *expressions, **extra): if len(expressions) < 2: raise ValueError('Concat must take at least two expressions') paired = self._paired(expressions) - super(Concat, self).__init__(paired, **extra) + super().__init__(paired, **extra) def _paired(self, expressions): # wrap pairs of expressions in successive concat functions @@ -133,11 +133,11 @@ class Greatest(Func): def __init__(self, *expressions, **extra): if len(expressions) < 2: raise ValueError('Greatest must take at least two expressions') - super(Greatest, self).__init__(*expressions, **extra) + super().__init__(*expressions, **extra) def as_sqlite(self, compiler, connection): """Use the MAX function on SQLite.""" - return super(Greatest, self).as_sql(compiler, connection, function='MAX') + return super().as_sql(compiler, connection, function='MAX') class Least(Func): @@ -153,11 +153,11 @@ class Least(Func): def __init__(self, *expressions, **extra): if len(expressions) < 2: raise ValueError('Least must take at least two expressions') - super(Least, self).__init__(*expressions, **extra) + super().__init__(*expressions, **extra) def as_sqlite(self, compiler, connection): """Use the MIN function on SQLite.""" - return super(Least, self).as_sql(compiler, connection, function='MIN') + return super().as_sql(compiler, connection, function='MIN') class Length(Transform): @@ -167,10 +167,10 @@ class Length(Transform): def __init__(self, expression, **extra): output_field = extra.pop('output_field', fields.IntegerField()) - super(Length, self).__init__(expression, output_field=output_field, **extra) + super().__init__(expression, output_field=output_field, **extra) def as_mysql(self, compiler, connection): - return super(Length, self).as_sql(compiler, connection, function='CHAR_LENGTH') + return super().as_sql(compiler, connection, function='CHAR_LENGTH') class Lower(Transform): @@ -184,7 +184,7 @@ class Now(Func): def __init__(self, output_field=None, **extra): if output_field is None: output_field = fields.DateTimeField() - super(Now, self).__init__(output_field=output_field, **extra) + super().__init__(output_field=output_field, **extra) def as_postgresql(self, compiler, connection): # Postgres' CURRENT_TIMESTAMP means "the time at the start of the @@ -211,13 +211,13 @@ def __init__(self, expression, pos, length=None, **extra): if not hasattr(length, 'resolve_expression'): length = Value(length) expressions.append(length) - super(Substr, self).__init__(*expressions, **extra) + super().__init__(*expressions, **extra) def as_sqlite(self, compiler, connection): - return super(Substr, self).as_sql(compiler, connection, function='SUBSTR') + return super().as_sql(compiler, connection, function='SUBSTR') def as_oracle(self, compiler, connection): - return super(Substr, self).as_sql(compiler, connection, function='SUBSTR') + return super().as_sql(compiler, connection, function='SUBSTR') class Upper(Transform): diff --git a/django/db/models/functions/datetime.py b/django/db/models/functions/datetime.py index 8bfd8cafef86..19afc271b520 100644 --- a/django/db/models/functions/datetime.py +++ b/django/db/models/functions/datetime.py @@ -37,7 +37,7 @@ def __init__(self, expression, lookup_name=None, tzinfo=None, **extra): if self.lookup_name is None: raise ValueError('lookup_name must be provided') self.tzinfo = tzinfo - super(Extract, self).__init__(expression, **extra) + super().__init__(expression, **extra) def as_sql(self, compiler, connection): sql, params = compiler.compile(self.lhs) @@ -57,7 +57,7 @@ def as_sql(self, compiler, connection): return sql, params def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False): - copy = super(Extract, self).resolve_expression(query, allow_joins, reuse, summarize, for_save) + copy = super().resolve_expression(query, allow_joins, reuse, summarize, for_save) field = copy.lhs.output_field if not isinstance(field, (DateField, DateTimeField, TimeField)): raise ValueError('Extract input expression must be DateField, DateTimeField, or TimeField.') @@ -142,7 +142,7 @@ class TruncBase(TimezoneMixin, Transform): def __init__(self, expression, output_field=None, tzinfo=None, **extra): self.tzinfo = tzinfo - super(TruncBase, self).__init__(expression, output_field=output_field, **extra) + super().__init__(expression, output_field=output_field, **extra) def as_sql(self, compiler, connection): inner_sql, inner_params = compiler.compile(self.lhs) @@ -162,7 +162,7 @@ def as_sql(self, compiler, connection): return sql, inner_params + params def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False): - copy = super(TruncBase, self).resolve_expression(query, allow_joins, reuse, summarize, for_save) + copy = super().resolve_expression(query, allow_joins, reuse, summarize, for_save) field = copy.lhs.output_field # DateTimeField is a subclass of DateField so this works for both. assert isinstance(field, (DateField, TimeField)), ( @@ -210,7 +210,7 @@ class Trunc(TruncBase): def __init__(self, expression, kind, output_field=None, tzinfo=None, **extra): self.kind = kind - super(Trunc, self).__init__(expression, output_field=output_field, tzinfo=tzinfo, **extra) + super().__init__(expression, output_field=output_field, tzinfo=tzinfo, **extra) class TruncYear(TruncBase): diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py index 1536ecdc63d2..d96c4468f59a 100644 --- a/django/db/models/lookups.py +++ b/django/db/models/lookups.py @@ -153,8 +153,7 @@ def get_bilateral_transforms(self): class BuiltinLookup(Lookup): def process_lhs(self, compiler, connection, lhs=None): - lhs_sql, params = super(BuiltinLookup, self).process_lhs( - compiler, connection, lhs) + lhs_sql, params = super().process_lhs(compiler, connection, lhs) field_internal_type = self.lhs.output_field.get_internal_type() db_type = self.lhs.output_field.db_type(connection=connection) lhs_sql = connection.ops.field_cast_sql( @@ -223,7 +222,7 @@ def process_rhs(self, compiler, connection): # to prepare/transform those values. return self.batch_process_rhs(compiler, connection) else: - return super(FieldGetDbPrepValueIterableMixin, self).process_rhs(compiler, connection) + return super().process_rhs(compiler, connection) def resolve_expression_parameter(self, compiler, connection, sql, param): params = [param] @@ -234,7 +233,7 @@ def resolve_expression_parameter(self, compiler, connection, sql, param): return sql, params def batch_process_rhs(self, compiler, connection, rhs=None): - pre_processed = super(FieldGetDbPrepValueIterableMixin, self).batch_process_rhs(compiler, connection, rhs) + pre_processed = super().batch_process_rhs(compiler, connection, rhs) # The params list may contain expressions which compile to a # sql/param pair. Zip them to get sql and param pairs that refer to the # same argument and attempt to replace them with the result of @@ -258,7 +257,7 @@ class IExact(BuiltinLookup): prepare_rhs = False def process_rhs(self, qn, connection): - rhs, params = super(IExact, self).process_rhs(qn, connection) + rhs, params = super().process_rhs(qn, connection) if params: params[0] = connection.ops.prep_for_iexact_query(params[0]) return rhs, params @@ -292,7 +291,7 @@ class IntegerFieldFloatRounding: def get_prep_lookup(self): if isinstance(self.rhs, float): self.rhs = math.ceil(self.rhs) - return super(IntegerFieldFloatRounding, self).get_prep_lookup() + return super().get_prep_lookup() @IntegerField.register_lookup @@ -366,7 +365,7 @@ def process_rhs(self, compiler, connection): placeholder = '(' + ', '.join(sqls) + ')' return (placeholder, sqls_params) else: - return super(In, self).process_rhs(compiler, connection) + return super().process_rhs(compiler, connection) def get_rhs_op(self, connection, rhs): return 'IN %s' % rhs @@ -375,7 +374,7 @@ def as_sql(self, compiler, connection): max_in_list_size = connection.ops.max_in_list_size() if self.rhs_is_direct_value() and max_in_list_size and len(self.rhs) > max_in_list_size: return self.split_parameter_list_as_sql(compiler, connection) - return super(In, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) def split_parameter_list_as_sql(self, compiler, connection): # This is a special case for databases which limit the number of @@ -416,7 +415,7 @@ def get_rhs_op(self, connection, rhs): pattern = connection.pattern_ops[self.lookup_name].format(connection.pattern_esc) return pattern.format(rhs) else: - return super(PatternLookup, self).get_rhs_op(connection, rhs) + return super().get_rhs_op(connection, rhs) @Field.register_lookup @@ -425,7 +424,7 @@ class Contains(PatternLookup): prepare_rhs = False def process_rhs(self, qn, connection): - rhs, params = super(Contains, self).process_rhs(qn, connection) + rhs, params = super().process_rhs(qn, connection) if params and not self.bilateral_transforms: params[0] = "%%%s%%" % connection.ops.prep_for_like_query(params[0]) return rhs, params @@ -443,7 +442,7 @@ class StartsWith(PatternLookup): prepare_rhs = False def process_rhs(self, qn, connection): - rhs, params = super(StartsWith, self).process_rhs(qn, connection) + rhs, params = super().process_rhs(qn, connection) if params and not self.bilateral_transforms: params[0] = "%s%%" % connection.ops.prep_for_like_query(params[0]) return rhs, params @@ -455,7 +454,7 @@ class IStartsWith(PatternLookup): prepare_rhs = False def process_rhs(self, qn, connection): - rhs, params = super(IStartsWith, self).process_rhs(qn, connection) + rhs, params = super().process_rhs(qn, connection) if params and not self.bilateral_transforms: params[0] = "%s%%" % connection.ops.prep_for_like_query(params[0]) return rhs, params @@ -467,7 +466,7 @@ class EndsWith(PatternLookup): prepare_rhs = False def process_rhs(self, qn, connection): - rhs, params = super(EndsWith, self).process_rhs(qn, connection) + rhs, params = super().process_rhs(qn, connection) if params and not self.bilateral_transforms: params[0] = "%%%s" % connection.ops.prep_for_like_query(params[0]) return rhs, params @@ -479,7 +478,7 @@ class IEndsWith(PatternLookup): prepare_rhs = False def process_rhs(self, qn, connection): - rhs, params = super(IEndsWith, self).process_rhs(qn, connection) + rhs, params = super().process_rhs(qn, connection) if params and not self.bilateral_transforms: params[0] = "%%%s" % connection.ops.prep_for_like_query(params[0]) return rhs, params @@ -513,7 +512,7 @@ class Regex(BuiltinLookup): def as_sql(self, compiler, connection): if self.lookup_name in connection.operators: - return super(Regex, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) else: lhs, lhs_params = self.process_lhs(compiler, connection) rhs, rhs_params = self.process_rhs(compiler, connection) @@ -571,7 +570,7 @@ def as_sql(self, compiler, connection): except (IndexError, TypeError, ValueError): # Can't determine the bounds before executing the query, so skip # optimizations by falling back to a standard exact comparison. - return super(Exact, self).as_sql(compiler, connection) + return super().as_sql(compiler, connection) bounds = self.year_lookup_bounds(connection, rhs_params[0]) params.extend(bounds) return '%s BETWEEN %%s AND %%s' % lhs_sql, params diff --git a/django/db/models/manager.py b/django/db/models/manager.py index 2680f699867a..dd97272d3802 100644 --- a/django/db/models/manager.py +++ b/django/db/models/manager.py @@ -19,12 +19,12 @@ class BaseManager: def __new__(cls, *args, **kwargs): # We capture the arguments to make returning them trivial - obj = super(BaseManager, cls).__new__(cls) + obj = super().__new__(cls) obj._constructor_args = (args, kwargs) return obj def __init__(self): - super(BaseManager, self).__init__() + super().__init__() self._set_creation_counter() self.model = None self.name = None @@ -196,8 +196,8 @@ def __get__(self, instance, cls=None): class EmptyManager(Manager): def __init__(self, model): - super(EmptyManager, self).__init__() + super().__init__() self.model = model def get_queryset(self): - return super(EmptyManager, self).get_queryset().none() + return super().get_queryset().none() diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py index c94a03f5496c..7b1c46f15ce6 100644 --- a/django/db/models/query_utils.py +++ b/django/db/models/query_utils.py @@ -56,7 +56,7 @@ class Q(tree.Node): default = AND def __init__(self, *args, **kwargs): - super(Q, self).__init__(children=list(args) + list(kwargs.items())) + super().__init__(children=list(args) + list(kwargs.items())) def _combine(self, other, conn): if not isinstance(other, Q): diff --git a/django/db/models/signals.py b/django/db/models/signals.py index a511024342da..dafd49fd0509 100644 --- a/django/db/models/signals.py +++ b/django/db/models/signals.py @@ -25,13 +25,13 @@ def _lazy_method(self, method, apps, receiver, sender, **kwargs): def connect(self, receiver, sender=None, weak=True, dispatch_uid=None, apps=None): self._lazy_method( - super(ModelSignal, self).connect, apps, receiver, sender, + super().connect, apps, receiver, sender, weak=weak, dispatch_uid=dispatch_uid, ) def disconnect(self, receiver=None, sender=None, dispatch_uid=None, apps=None): return self._lazy_method( - super(ModelSignal, self).disconnect, apps, receiver, sender, dispatch_uid=dispatch_uid + super().disconnect, apps, receiver, sender, dispatch_uid=dispatch_uid ) diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 560ea2ef6dc7..76a595d2b17a 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -928,7 +928,7 @@ class SQLInsertCompiler(SQLCompiler): def __init__(self, *args, **kwargs): self.return_id = False - super(SQLInsertCompiler, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def field_as_sql(self, field, val): """ @@ -1181,7 +1181,7 @@ def execute_sql(self, result_type): non-empty query that is executed. Row counts for any subsequent, related queries are not available. """ - cursor = super(SQLUpdateCompiler, self).execute_sql(result_type) + cursor = super().execute_sql(result_type) try: rows = cursor.rowcount if cursor else 0 is_empty = cursor is None @@ -1217,7 +1217,7 @@ def pre_sql_setup(self): query._extra = {} query.select = [] query.add_fields([query.get_meta().pk.name]) - super(SQLUpdateCompiler, self).pre_sql_setup() + super().pre_sql_setup() must_pre_select = count > 1 and not self.connection.features.update_can_self_select diff --git a/django/db/models/sql/subqueries.py b/django/db/models/sql/subqueries.py index cfdadefdffef..03a5155b9bba 100644 --- a/django/db/models/sql/subqueries.py +++ b/django/db/models/sql/subqueries.py @@ -88,7 +88,7 @@ class UpdateQuery(Query): compiler = 'SQLUpdateCompiler' def __init__(self, *args, **kwargs): - super(UpdateQuery, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self._setup_query() def _setup_query(self): @@ -103,7 +103,7 @@ def _setup_query(self): self.related_updates = {} def clone(self, klass=None, **kwargs): - return super(UpdateQuery, self).clone(klass, related_updates=self.related_updates.copy(), **kwargs) + return super().clone(klass, related_updates=self.related_updates.copy(), **kwargs) def update_batch(self, pk_list, values, using): self.add_update_values(values) @@ -176,7 +176,7 @@ class InsertQuery(Query): compiler = 'SQLInsertCompiler' def __init__(self, *args, **kwargs): - super(InsertQuery, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.fields = [] self.objs = [] diff --git a/django/forms/fields.py b/django/forms/fields.py index a3bdcd1713af..e0c4edad52a6 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -121,7 +121,7 @@ def __init__(self, required=True, widget=None, label=None, initial=None, self.validators = list(itertools.chain(self.default_validators, validators)) - super(Field, self).__init__() + super().__init__() def prepare_value(self, value): return value @@ -222,7 +222,7 @@ def __init__(self, max_length=None, min_length=None, strip=True, empty_value='', self.min_length = min_length self.strip = strip self.empty_value = empty_value - super(CharField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) if min_length is not None: self.validators.append(validators.MinLengthValidator(int(min_length))) if max_length is not None: @@ -238,7 +238,7 @@ def to_python(self, value): return value def widget_attrs(self, widget): - attrs = super(CharField, self).widget_attrs(widget) + attrs = super().widget_attrs(widget) if self.max_length is not None and not widget.is_hidden: # The HTML attribute is maxlength, not max_length. attrs['maxlength'] = str(self.max_length) @@ -259,8 +259,8 @@ def __init__(self, max_value=None, min_value=None, *args, **kwargs): self.max_value, self.min_value = max_value, min_value if kwargs.get('localize') and self.widget == NumberInput: # Localized number input is not well supported on most browsers - kwargs.setdefault('widget', super(IntegerField, self).widget) - super(IntegerField, self).__init__(*args, **kwargs) + kwargs.setdefault('widget', super().widget) + super().__init__(*args, **kwargs) if max_value is not None: self.validators.append(validators.MaxValueValidator(max_value)) @@ -272,7 +272,7 @@ def to_python(self, value): Validates that int() can be called on the input. Returns the result of int(). Returns None for empty values. """ - value = super(IntegerField, self).to_python(value) + value = super().to_python(value) if value in self.empty_values: return None if self.localize: @@ -285,7 +285,7 @@ def to_python(self, value): return value def widget_attrs(self, widget): - attrs = super(IntegerField, self).widget_attrs(widget) + attrs = super().widget_attrs(widget) if isinstance(widget, NumberInput): if self.min_value is not None: attrs['min'] = self.min_value @@ -316,7 +316,7 @@ def to_python(self, value): return value def validate(self, value): - super(FloatField, self).validate(value) + super().validate(value) # Check for NaN (which is the only thing not equal to itself) and +/- infinity if value != value or value in (Decimal('Inf'), Decimal('-Inf')): @@ -325,7 +325,7 @@ def validate(self, value): return value def widget_attrs(self, widget): - attrs = super(FloatField, self).widget_attrs(widget) + attrs = super().widget_attrs(widget) if isinstance(widget, NumberInput) and 'step' not in widget.attrs: attrs.setdefault('step', 'any') return attrs @@ -338,7 +338,7 @@ class DecimalField(IntegerField): def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs): self.max_digits, self.decimal_places = max_digits, decimal_places - super(DecimalField, self).__init__(max_value, min_value, *args, **kwargs) + super().__init__(max_value, min_value, *args, **kwargs) self.validators.append(validators.DecimalValidator(max_digits, decimal_places)) def to_python(self, value): @@ -360,7 +360,7 @@ def to_python(self, value): return value def validate(self, value): - super(DecimalField, self).validate(value) + super().validate(value) if value in self.empty_values: return # Check for NaN, Inf and -Inf values. We can't compare directly for NaN, @@ -370,7 +370,7 @@ def validate(self, value): raise ValidationError(self.error_messages['invalid'], code='invalid') def widget_attrs(self, widget): - attrs = super(DecimalField, self).widget_attrs(widget) + attrs = super().widget_attrs(widget) if isinstance(widget, NumberInput) and 'step' not in widget.attrs: if self.decimal_places is not None: # Use exponential notation for small values since they might @@ -385,7 +385,7 @@ def widget_attrs(self, widget): class BaseTemporalField(Field): def __init__(self, input_formats=None, *args, **kwargs): - super(BaseTemporalField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) if input_formats is not None: self.input_formats = input_formats @@ -425,7 +425,7 @@ def to_python(self, value): return value.date() if isinstance(value, datetime.date): return value - return super(DateField, self).to_python(value) + return super().to_python(value) def strptime(self, value, format): return datetime.datetime.strptime(value, format).date() @@ -447,7 +447,7 @@ def to_python(self, value): return None if isinstance(value, datetime.time): return value - return super(TimeField, self).to_python(value) + return super().to_python(value) def strptime(self, value, format): return datetime.datetime.strptime(value, format).time() @@ -477,7 +477,7 @@ def to_python(self, value): if isinstance(value, datetime.date): result = datetime.datetime(value.year, value.month, value.day) return from_current_timezone(result) - result = super(DateTimeField, self).to_python(value) + result = super().to_python(value) return from_current_timezone(result) def strptime(self, value, format): @@ -513,7 +513,7 @@ def __init__(self, regex, max_length=None, min_length=None, error_message=None, 'Enter a valid value' is too generic for you. """ kwargs.setdefault('strip', False) - super(RegexField, self).__init__(max_length, min_length, *args, **kwargs) + super().__init__(max_length, min_length, *args, **kwargs) self._set_regex(regex) def _get_regex(self): @@ -536,7 +536,7 @@ class EmailField(CharField): default_validators = [validators.validate_email] def __init__(self, *args, **kwargs): - super(EmailField, self).__init__(*args, strip=True, **kwargs) + super().__init__(*args, strip=True, **kwargs) class FileField(Field): @@ -555,7 +555,7 @@ class FileField(Field): def __init__(self, *args, **kwargs): self.max_length = kwargs.pop('max_length', None) self.allow_empty_file = kwargs.pop('allow_empty_file', False) - super(FileField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def to_python(self, data): if data in self.empty_values: @@ -595,7 +595,7 @@ def clean(self, data, initial=None): data = None if not data and initial: return initial - return super(FileField, self).clean(data) + return super().clean(data) def bound_data(self, data, initial): if data in (None, FILE_INPUT_CONTRADICTION): @@ -621,7 +621,7 @@ def to_python(self, data): Checks that the file-upload field data contains a valid image (GIF, JPG, PNG, possibly others -- whatever the Python Imaging Library supports). """ - f = super(ImageField, self).to_python(data) + f = super().to_python(data) if f is None: return None @@ -668,7 +668,7 @@ class URLField(CharField): default_validators = [validators.URLValidator()] def __init__(self, *args, **kwargs): - super(URLField, self).__init__(*args, strip=True, **kwargs) + super().__init__(*args, strip=True, **kwargs) def to_python(self, value): @@ -684,7 +684,7 @@ def split_url(url): # misformatted URLs. raise ValidationError(self.error_messages['invalid'], code='invalid') - value = super(URLField, self).to_python(value) + value = super().to_python(value) if value: url_fields = split_url(value) if not url_fields[0]: @@ -715,7 +715,7 @@ def to_python(self, value): value = False else: value = bool(value) - return super(BooleanField, self).to_python(value) + return super().to_python(value) def validate(self, value): if not value and self.required: @@ -771,14 +771,14 @@ class ChoiceField(Field): def __init__(self, choices=(), required=True, widget=None, label=None, initial=None, help_text='', *args, **kwargs): - super(ChoiceField, self).__init__( + super().__init__( required=required, widget=widget, label=label, initial=initial, help_text=help_text, *args, **kwargs ) self.choices = choices def __deepcopy__(self, memo): - result = super(ChoiceField, self).__deepcopy__(memo) + result = super().__deepcopy__(memo) result._choices = copy.deepcopy(self._choices, memo) return result @@ -808,7 +808,7 @@ def validate(self, value): """ Validates that the input is in self.choices. """ - super(ChoiceField, self).validate(value) + super().validate(value) if value and not self.valid_value(value): raise ValidationError( self.error_messages['invalid_choice'], @@ -835,7 +835,7 @@ class TypedChoiceField(ChoiceField): def __init__(self, *args, **kwargs): self.coerce = kwargs.pop('coerce', lambda val: val) self.empty_value = kwargs.pop('empty_value', '') - super(TypedChoiceField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def _coerce(self, value): """ @@ -854,7 +854,7 @@ def _coerce(self, value): return value def clean(self, value): - value = super(TypedChoiceField, self).clean(value) + value = super().clean(value) return self._coerce(value) @@ -904,7 +904,7 @@ class TypedMultipleChoiceField(MultipleChoiceField): def __init__(self, *args, **kwargs): self.coerce = kwargs.pop('coerce', lambda val: val) self.empty_value = kwargs.pop('empty_value', []) - super(TypedMultipleChoiceField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def _coerce(self, value): """ @@ -926,12 +926,12 @@ def _coerce(self, value): return new_value def clean(self, value): - value = super(TypedMultipleChoiceField, self).clean(value) + value = super().clean(value) return self._coerce(value) def validate(self, value): if value != self.empty_value: - super(TypedMultipleChoiceField, self).validate(value) + super().validate(value) elif self.required: raise ValidationError(self.error_messages['required'], code='required') @@ -941,7 +941,7 @@ class ComboField(Field): A Field whose clean() method calls multiple Field clean() methods. """ def __init__(self, fields=(), *args, **kwargs): - super(ComboField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Set 'required' to False on the individual fields, because the # required validation will be handled by ComboField, not by those # individual fields. @@ -954,7 +954,7 @@ def clean(self, value): Validates the given value against all of self.fields, which is a list of Field instances. """ - super(ComboField, self).clean(value) + super().clean(value) for field in self.fields: value = field.clean(value) return value @@ -984,7 +984,7 @@ class MultiValueField(Field): def __init__(self, fields=(), *args, **kwargs): self.require_all_fields = kwargs.pop('require_all_fields', True) - super(MultiValueField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) for f in fields: f.error_messages.setdefault('incomplete', self.error_messages['incomplete']) @@ -996,7 +996,7 @@ def __init__(self, fields=(), *args, **kwargs): self.fields = fields def __deepcopy__(self, memo): - result = super(MultiValueField, self).__deepcopy__(memo) + result = super().__deepcopy__(memo) result.fields = tuple(x.__deepcopy__(memo) for x in self.fields) return result @@ -1088,7 +1088,7 @@ def __init__(self, path, match=None, recursive=False, allow_files=True, initial=None, help_text='', *args, **kwargs): self.path, self.match, self.recursive = path, match, recursive self.allow_files, self.allow_folders = allow_files, allow_folders - super(FilePathField, self).__init__( + super().__init__( choices=(), required=required, widget=widget, label=label, initial=initial, help_text=help_text, *args, **kwargs ) @@ -1152,7 +1152,7 @@ def __init__(self, input_date_formats=None, input_time_formats=None, *args, **kw error_messages={'invalid': errors['invalid_time']}, localize=localize), ) - super(SplitDateTimeField, self).__init__(fields, *args, **kwargs) + super().__init__(fields, *args, **kwargs) def compress(self, data_list): if data_list: @@ -1171,7 +1171,7 @@ class GenericIPAddressField(CharField): def __init__(self, protocol='both', unpack_ipv4=False, *args, **kwargs): self.unpack_ipv4 = unpack_ipv4 self.default_validators = validators.ip_address_validators(protocol, unpack_ipv4)[0] - super(GenericIPAddressField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def to_python(self, value): if value in self.empty_values: @@ -1189,7 +1189,7 @@ def __init__(self, *args, **kwargs): self.allow_unicode = kwargs.pop('allow_unicode', False) if self.allow_unicode: self.default_validators = [validators.validate_unicode_slug] - super(SlugField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) class UUIDField(CharField): @@ -1203,7 +1203,7 @@ def prepare_value(self, value): return value def to_python(self, value): - value = super(UUIDField, self).to_python(value) + value = super().to_python(value) if value in self.empty_values: return None if not isinstance(value, uuid.UUID): diff --git a/django/forms/formsets.py b/django/forms/formsets.py index 8a830916f9e7..4d8259c2c561 100644 --- a/django/forms/formsets.py +++ b/django/forms/formsets.py @@ -39,7 +39,7 @@ def __init__(self, *args, **kwargs): # code. The POST value of them returned from the client is not checked. self.base_fields[MIN_NUM_FORM_COUNT] = IntegerField(required=False, widget=HiddenInput) self.base_fields[MAX_NUM_FORM_COUNT] = IntegerField(required=False, widget=HiddenInput) - super(ManagementForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) @html_safe diff --git a/django/forms/models.py b/django/forms/models.py index de1fb1e2bdd0..a95f281b453b 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -289,7 +289,7 @@ def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, # It is False by default so overriding self.clean() and failing to call # super will stop validate_unique from being called. self._validate_unique = False - super(BaseModelForm, self).__init__( + super().__init__( data, files, auto_id, prefix, object_data, error_class, label_suffix, empty_permitted, use_required_attribute=use_required_attribute, ) @@ -558,13 +558,13 @@ def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, self.initial_extra = kwargs.pop('initial', None) defaults = {'data': data, 'files': files, 'auto_id': auto_id, 'prefix': prefix} defaults.update(kwargs) - super(BaseModelFormSet, self).__init__(**defaults) + super().__init__(**defaults) def initial_form_count(self): """Returns the number of forms that are required in this FormSet.""" if not (self.data or self.files): return len(self.get_queryset()) - return super(BaseModelFormSet, self).initial_form_count() + return super().initial_form_count() def _existing_object(self, pk): if not hasattr(self, '_object_dict'): @@ -596,7 +596,7 @@ def _construct_form(self, i, **kwargs): kwargs['initial'] = self.initial_extra[i - self.initial_form_count()] except IndexError: pass - return super(BaseModelFormSet, self)._construct_form(i, **kwargs) + return super()._construct_form(i, **kwargs) def get_queryset(self): if not hasattr(self, '_queryset'): @@ -821,7 +821,7 @@ def pk_is_not_editable(pk): else: widget = HiddenInput form.fields[self._pk_field.name] = ModelChoiceField(qs, initial=pk_value, required=False, widget=widget) - super(BaseModelFormSet, self).add_fields(form, index) + super().add_fields(form, index) def modelformset_factory(model, form=ModelForm, formfield_callback=None, @@ -871,8 +871,7 @@ def __init__(self, data=None, files=None, instance=None, else: qs = queryset.none() self.unique_fields = {self.fk.name} - super(BaseInlineFormSet, self).__init__(data, files, prefix=prefix, - queryset=qs, **kwargs) + super().__init__(data, files, prefix=prefix, queryset=qs, **kwargs) # Add the generated field to form._meta.fields if it's defined to make # sure validation isn't skipped on that field. @@ -884,10 +883,10 @@ def __init__(self, data=None, files=None, instance=None, def initial_form_count(self): if self.save_as_new: return 0 - return super(BaseInlineFormSet, self).initial_form_count() + return super().initial_form_count() def _construct_form(self, i, **kwargs): - form = super(BaseInlineFormSet, self)._construct_form(i, **kwargs) + form = super()._construct_form(i, **kwargs) if self.save_as_new: # Remove the primary key from the form's data, we are only # creating new instances @@ -926,7 +925,7 @@ def save_new(self, form, commit=True): return obj def add_fields(self, form, index): - super(BaseInlineFormSet, self).add_fields(form, index) + super().add_fields(form, index) if self._pk_field == self.fk: name = self._pk_field.name kwargs = {'pk_field': True} @@ -954,7 +953,7 @@ def add_fields(self, form, index): def get_unique_error_message(self, unique_check): unique_check = [field for field in unique_check if field != self.fk.name] - return super(BaseInlineFormSet, self).get_unique_error_message(unique_check) + return super().get_unique_error_message(unique_check) def _get_foreign_key(parent_model, model, fk_name=None, can_fail=False): @@ -1076,7 +1075,7 @@ def __init__(self, parent_instance, *args, **kwargs): else: kwargs["initial"] = self.parent_instance.pk kwargs["required"] = False - super(InlineForeignKeyField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def clean(self, value): if value in self.empty_values: @@ -1205,7 +1204,7 @@ def prepare_value(self, value): return value.serializable_value(self.to_field_name) else: return value.pk - return super(ModelChoiceField, self).prepare_value(value) + return super().prepare_value(value) def to_python(self, value): if value in self.empty_values: @@ -1239,7 +1238,7 @@ class ModelMultipleChoiceField(ModelChoiceField): def __init__(self, queryset, required=True, widget=None, label=None, initial=None, help_text='', *args, **kwargs): - super(ModelMultipleChoiceField, self).__init__( + super().__init__( queryset, None, required, widget, label, initial, help_text, *args, **kwargs ) @@ -1305,7 +1304,7 @@ def prepare_value(self, value): not isinstance(value, str) and not hasattr(value, '_meta')): return [super(ModelMultipleChoiceField, self).prepare_value(v) for v in value] - return super(ModelMultipleChoiceField, self).prepare_value(value) + return super().prepare_value(value) def has_changed(self, initial, data): if initial is None: diff --git a/django/forms/utils.py b/django/forms/utils.py index b199803cccbe..bda4694e4fea 100644 --- a/django/forms/utils.py +++ b/django/forms/utils.py @@ -80,7 +80,7 @@ class ErrorList(UserList, list): A collection of errors that knows how to display itself in various formats. """ def __init__(self, initlist=None, error_class=None): - super(ErrorList, self).__init__(initlist) + super().__init__(initlist) if error_class is None: self.error_class = 'errorlist' diff --git a/django/forms/widgets.py b/django/forms/widgets.py index 71169d96189a..4317a0fc39b9 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -255,10 +255,10 @@ def __init__(self, attrs=None): if attrs is not None: attrs = attrs.copy() self.input_type = attrs.pop('type', self.input_type) - super(Input, self).__init__(attrs) + super().__init__(attrs) def get_context(self, name, value, attrs=None): - context = super(Input, self).get_context(name, value, attrs) + context = super().get_context(name, value, attrs) context['widget']['type'] = self.input_type return context @@ -288,13 +288,13 @@ class PasswordInput(Input): template_name = 'django/forms/widgets/password.html' def __init__(self, attrs=None, render_value=False): - super(PasswordInput, self).__init__(attrs) + super().__init__(attrs) self.render_value = render_value def get_context(self, name, value, attrs): if not self.render_value: value = None - return super(PasswordInput, self).get_context(name, value, attrs) + return super().get_context(name, value, attrs) class HiddenInput(Input): @@ -310,7 +310,7 @@ class MultipleHiddenInput(HiddenInput): template_name = 'django/forms/widgets/multiple_hidden.html' def get_context(self, name, value, attrs=None): - context = super(MultipleHiddenInput, self).get_context(name, value, attrs) + context = super().get_context(name, value, attrs) final_attrs = context['widget']['attrs'] id_ = context['widget']['attrs'].get('id') @@ -392,7 +392,7 @@ def format_value(self, value): return value def get_context(self, name, value, attrs=None): - context = super(ClearableFileInput, self).get_context(name, value, attrs) + context = super().get_context(name, value, attrs) checkbox_name = self.clear_checkbox_name(name) checkbox_id = self.clear_checkbox_id(checkbox_name) context.update({ @@ -406,7 +406,7 @@ def get_context(self, name, value, attrs=None): return context def value_from_datadict(self, data, files, name): - upload = super(ClearableFileInput, self).value_from_datadict(data, files, name) + upload = super().value_from_datadict(data, files, name) if not self.is_required and CheckboxInput().value_from_datadict( data, files, self.clear_checkbox_name(name)): @@ -420,7 +420,7 @@ def value_from_datadict(self, data, files, name): return upload def use_required_attribute(self, initial): - return super(ClearableFileInput, self).use_required_attribute(initial) and not initial + return super().use_required_attribute(initial) and not initial class Textarea(Widget): @@ -431,7 +431,7 @@ def __init__(self, attrs=None): default_attrs = {'cols': '40', 'rows': '10'} if attrs: default_attrs.update(attrs) - super(Textarea, self).__init__(default_attrs) + super().__init__(default_attrs) class DateTimeBaseInput(TextInput): @@ -439,7 +439,7 @@ class DateTimeBaseInput(TextInput): supports_microseconds = False def __init__(self, attrs=None, format=None): - super(DateTimeBaseInput, self).__init__(attrs) + super().__init__(attrs) self.format = format if format else None def format_value(self, value): @@ -471,7 +471,7 @@ class CheckboxInput(Input): template_name = 'django/forms/widgets/checkbox.html' def __init__(self, attrs=None, check_test=None): - super(CheckboxInput, self).__init__(attrs) + super().__init__(attrs) # check_test is a callable that takes a value and returns True # if the checkbox should be checked for that value. self.check_test = boolean_check if check_test is None else check_test @@ -487,7 +487,7 @@ def get_context(self, name, value, attrs=None): if attrs is None: attrs = {} attrs['checked'] = True - return super(CheckboxInput, self).get_context(name, value, attrs) + return super().get_context(name, value, attrs) def value_from_datadict(self, data, files, name): if name not in data: @@ -517,7 +517,7 @@ class ChoiceWidget(Widget): option_inherits_attrs = True def __init__(self, attrs=None, choices=()): - super(ChoiceWidget, self).__init__(attrs) + super().__init__(attrs) # choices can be any iterable, but we may need to render this widget # multiple times. Thus, collapse it into a list so it can be consumed # more than once. @@ -605,7 +605,7 @@ def create_option(self, name, value, label, selected, index, subindex=None, attr } def get_context(self, name, value, attrs=None): - context = super(ChoiceWidget, self).get_context(name, value, attrs) + context = super().get_context(name, value, attrs) context['widget']['optgroups'] = self.optgroups(name, context['widget']['value'], attrs) context['wrap_label'] = True return context @@ -657,7 +657,7 @@ class Select(ChoiceWidget): option_inherits_attrs = False def get_context(self, name, value, attrs=None): - context = super(Select, self).get_context(name, value, attrs) + context = super().get_context(name, value, attrs) if self.allow_multiple_selected: context['widget']['attrs']['multiple'] = 'multiple' return context @@ -673,7 +673,7 @@ def use_required_attribute(self, initial): Don't render 'required' if the first
    -{% if unicode_hint %} -
    -

    Unicode error hint

    -

    The string that could not be encoded/decoded was: {{ unicode_hint|force_escape }}

    -
    -{% endif %} -{% if template_does_not_exist %} -
    -

    Template-loader postmortem

    - {% if postmortem %} -

    Django tried loading these templates, in this order:

    - {% for entry in postmortem %} -

    Using engine {{ entry.backend.name }}:

    -
      - {% if entry.tried %} - {% for attempt in entry.tried %} -
    • {{ attempt.0.loader_name }}: {{ attempt.0.name }} ({{ attempt.1 }})
    • - {% endfor %} - {% else %} -
    • This engine did not provide a list of tried templates.
    • - {% endif %} -
    - {% endfor %} - {% else %} -

    No templates were found because your 'TEMPLATES' setting is not configured.

    - {% endif %} -
    -{% endif %} -{% if template_info %} -
    -

    Error during template rendering

    -

    In template {{ template_info.name }}, error at line {{ template_info.line }}

    -

    {{ template_info.message }}

    - - {% for source_line in template_info.source_lines %} - {% if source_line.0 == template_info.line %} - - - - {% else %} - - - {% endif %} - {% endfor %} -
    {{ source_line.0 }}{{ template_info.before }}""" - """{{ template_info.during }}""" - """{{ template_info.after }}
    {{ source_line.0 }}{{ source_line.1 }}
    -
    -{% endif %} -{% if frames %} -
    -

    Traceback {% if not is_email %} - Switch to copy-and-paste view{% endif %} -

    - {% autoescape off %} -
    -
      - {% for frame in frames %} - {% ifchanged frame.exc_cause %}{% if frame.exc_cause %} -
    • - {% if frame.exc_cause_explicit %} - The above exception ({{ frame.exc_cause }}) was the direct cause of the following exception: - {% else %} - During handling of the above exception ({{ frame.exc_cause }}), another exception occurred: - {% endif %} -

    • - {% endif %}{% endifchanged %} -
    • - {{ frame.filename|escape }} in {{ frame.function|escape }} - - {% if frame.context_line %} -
      - {% if frame.pre_context and not is_email %} -
        - {% for line in frame.pre_context %} -
      1. {{ line|escape }}
      2. - {% endfor %} -
      - {% endif %} -
        -
      1. -"""            """{{ frame.context_line|escape }}
        {% if not is_email %} ...{% endif %}
      - {% if frame.post_context and not is_email %} -
        - {% for line in frame.post_context %} -
      1. {{ line|escape }}
      2. - {% endfor %} -
      - {% endif %} -
      - {% endif %} - - {% if frame.vars %} -
      - {% if is_email %} -

      Local Vars

      - {% else %} - Local vars - {% endif %} -
      - - - - - - - - - {% for var in frame.vars|dictsort:0 %} - - - - - {% endfor %} - -
      VariableValue
      {{ var.0|force_escape }}
      {{ var.1 }}
      - {% endif %} -
    • - {% endfor %} -
    -
    - {% endautoescape %} -
    -{% if not is_email %} -
    - - - - - -

    - -
    -
    -
    -{% endif %} -{% endif %} - -
    -

    Request information

    - -{% if request %} - {% if user_str %} -

    USER

    -

    {{ user_str }}

    - {% endif %} - -

    GET

    - {% if request.GET %} - - - - - - - - - {% for k, v in request_GET_items %} - - - - - {% endfor %} - -
    VariableValue
    {{ k }}
    {{ v|pprint }}
    - {% else %} -

    No GET data

    - {% endif %} - -

    POST

    - {% if filtered_POST_items %} - - - - - - - - - {% for k, v in filtered_POST_items %} - - - - - {% endfor %} - -
    VariableValue
    {{ k }}
    {{ v|pprint }}
    - {% else %} -

    No POST data

    - {% endif %} -

    FILES

    - {% if request.FILES %} - - - - - - - - - {% for k, v in request_FILES_items %} - - - - - {% endfor %} - -
    VariableValue
    {{ k }}
    {{ v|pprint }}
    - {% else %} -

    No FILES data

    - {% endif %} - - - - {% if request.COOKIES %} - - - - - - - - - {% for k, v in request_COOKIES_items %} - - - - - {% endfor %} - -
    VariableValue
    {{ k }}
    {{ v|pprint }}
    - {% else %} -

    No cookie data

    - {% endif %} - -

    META

    - - - - - - - - - {% for var in request.META.items|dictsort:0 %} - - - - - {% endfor %} - -
    VariableValue
    {{ var.0 }}
    {{ var.1|pprint }}
    -{% else %} -

    Request data not supplied

    -{% endif %} - -

    Settings

    -

    Using settings module {{ settings.SETTINGS_MODULE }}

    - - - - - - - - - {% for var in settings.items|dictsort:0 %} - - - - - {% endfor %} - -
    SettingValue
    {{ var.0 }}
    {{ var.1|pprint }}
    - -
    -{% if not is_email %} -
    -

    - You're seeing this error because you have DEBUG = True in your - Django settings file. Change that to False, and Django will - display a standard page generated by the handler for this status code. -

    -
    -{% endif %} - - -""") # NOQA - -TECHNICAL_500_TEXT_TEMPLATE = ("""""" -"""{% firstof exception_type 'Report' %}{% if request %} at {{ request.path_info }}{% endif %} -{% firstof exception_value 'No exception message supplied' %} -{% if request %} -Request Method: {{ request.META.REQUEST_METHOD }} -Request URL: {{ request.get_raw_uri }}{% endif %} -Django Version: {{ django_version_info }} -Python Executable: {{ sys_executable }} -Python Version: {{ sys_version_info }} -Python Path: {{ sys_path }} -Server time: {{server_time|date:"r"}} -Installed Applications: -{{ settings.INSTALLED_APPS|pprint }} -Installed Middleware: -{{ settings.MIDDLEWARE|pprint }}""" -""" -{% if template_does_not_exist %}Template loader postmortem -{% if postmortem %}Django tried loading these templates, in this order: -{% for entry in postmortem %} -Using engine {{ entry.backend.name }}: -{% if entry.tried %}{% for attempt in entry.tried %}""" -""" * {{ attempt.0.loader_name }}: {{ attempt.0.name }} ({{ attempt.1 }}) -{% endfor %}{% else %} This engine did not provide a list of tried templates. -{% endif %}{% endfor %} -{% else %}No templates were found because your 'TEMPLATES' setting is not configured. -{% endif %} -{% endif %}{% if template_info %} -Template error: -In template {{ template_info.name }}, error at line {{ template_info.line }} - {{ template_info.message }} -{% for source_line in template_info.source_lines %}""" -"{% if source_line.0 == template_info.line %}" -" {{ source_line.0 }} : {{ template_info.before }} {{ template_info.during }} {{ template_info.after }}" -"{% else %}" -" {{ source_line.0 }} : {{ source_line.1 }}" -"""{% endif %}{% endfor %}{% endif %}{% if frames %} - -Traceback:""" -"{% for frame in frames %}" -"{% ifchanged frame.exc_cause %}" -" {% if frame.exc_cause %}" """ - {% if frame.exc_cause_explicit %} - The above exception ({{ frame.exc_cause }}) was the direct cause of the following exception: - {% else %} - During handling of the above exception ({{ frame.exc_cause }}), another exception occurred: - {% endif %} - {% endif %} -{% endifchanged %} -File "{{ frame.filename }}" in {{ frame.function }} -{% if frame.context_line %} {{ frame.lineno }}. {{ frame.context_line }}{% endif %} -{% endfor %} -{% if exception_type %}Exception Type: {{ exception_type }}{% if request %} at {{ request.path_info }}{% endif %} -{% if exception_value %}Exception Value: {{ exception_value }}{% endif %}{% endif %}{% endif %} -{% if request %}Request information: -{% if user_str %}USER: {{ user_str }}{% endif %} - -GET:{% for k, v in request_GET_items %} -{{ k }} = {{ v|stringformat:"r" }}{% empty %} No GET data{% endfor %} - -POST:{% for k, v in filtered_POST_items %} -{{ k }} = {{ v|stringformat:"r" }}{% empty %} No POST data{% endfor %} - -FILES:{% for k, v in request_FILES_items %} -{{ k }} = {{ v|stringformat:"r" }}{% empty %} No FILES data{% endfor %} - -COOKIES:{% for k, v in request_COOKIES_items %} -{{ k }} = {{ v|stringformat:"r" }}{% empty %} No cookie data{% endfor %} - -META:{% for k, v in request.META.items|dictsort:0 %} -{{ k }} = {{ v|stringformat:"r" }}{% endfor %} -{% else %}Request data not supplied -{% endif %} -Settings: -Using settings module {{ settings.SETTINGS_MODULE }}{% for k, v in settings.items|dictsort:0 %} -{{ k }} = {{ v|stringformat:"r" }}{% endfor %} - -{% if not is_email %} -You're seeing this error because you have DEBUG = True in your -Django settings file. Change that to False, and Django will -display a standard page generated by the handler for this status code. -{% endif %} -""") # NOQA - -TECHNICAL_404_TEMPLATE = """ - - - - - Page not found at {{ request.path_info|escape }} - - - - -
    -

    Page not found (404)

    - - - - - - - - - - {% if raising_view_name %} - - - - - {% endif %} -
    Request Method:{{ request.META.REQUEST_METHOD }}
    Request URL:{{ request.build_absolute_uri|escape }}
    Raised by:{{ raising_view_name }}
    -
    -
    - {% if urlpatterns %} -

    - Using the URLconf defined in {{ urlconf }}, - Django tried these URL patterns, in this order: -

    -
      - {% for pattern in urlpatterns %} -
    1. - {% for pat in pattern %} - {{ pat.regex.pattern }} - {% if forloop.last and pat.name %}[name='{{ pat.name }}']{% endif %} - {% endfor %} -
    2. - {% endfor %} -
    -

    - {% if request_path %} - The current path, {{ request_path|escape }},{% else %} - The empty path{% endif %} didn't match any of these. -

    - {% else %} -

    {{ reason }}

    - {% endif %} -
    - -
    -

    - You're seeing this error because you have DEBUG = True in - your Django settings file. Change that to False, and Django - will display a standard 404 page. -

    -
    - - -""" - -DEFAULT_URLCONF_TEMPLATE = """ - - - - {{ title }} - - - - -
    -

    {{ heading }}

    -

    {{ subheading }}

    -
    - -
    -

    - {{ instructions|safe }} -

    -
    - -
    -

    - {{ explanation|safe }} -

    -
    - -""" diff --git a/django/views/templates/default_urlconf.html b/django/views/templates/default_urlconf.html new file mode 100644 index 000000000000..f080a4ea292a --- /dev/null +++ b/django/views/templates/default_urlconf.html @@ -0,0 +1,44 @@ + + + + {{ title }} + + + + +
    +

    {{ heading }}

    +

    {{ subheading }}

    +
    + +
    +

    {{ instructions|safe }}

    +
    + +
    +

    {{ explanation|safe }}

    +
    + diff --git a/django/views/templates/technical_404.html b/django/views/templates/technical_404.html new file mode 100644 index 000000000000..b88fecf2eb75 --- /dev/null +++ b/django/views/templates/technical_404.html @@ -0,0 +1,79 @@ + + + + + Page not found at {{ request.path_info|escape }} + + + + +
    +

    Page not found (404)

    + + + + + + + + + + {% if raising_view_name %} + + + + + {% endif %} +
    Request Method:{{ request.META.REQUEST_METHOD }}
    Request URL:{{ request.build_absolute_uri|escape }}
    Raised by:{{ raising_view_name }}
    +
    +
    + {% if urlpatterns %} +

    + Using the URLconf defined in {{ urlconf }}, + Django tried these URL patterns, in this order: +

    +
      + {% for pattern in urlpatterns %} +
    1. + {% for pat in pattern %} + {{ pat.regex.pattern }} + {% if forloop.last and pat.name %}[name='{{ pat.name }}']{% endif %} + {% endfor %} +
    2. + {% endfor %} +
    +

    + {% if request_path %} + The current path, {{ request_path|escape }},{% else %} + The empty path{% endif %} didn't match any of these. +

    + {% else %} +

    {{ reason }}

    + {% endif %} +
    + +
    +

    + You're seeing this error because you have DEBUG = True in + your Django settings file. Change that to False, and Django + will display a standard 404 page. +

    +
    + + diff --git a/django/views/templates/technical_500.html b/django/views/templates/technical_500.html new file mode 100644 index 000000000000..945c27827a3d --- /dev/null +++ b/django/views/templates/technical_500.html @@ -0,0 +1,503 @@ + + + + + + {% if exception_type %}{{ exception_type }}{% else %}Report{% endif %} + {% if request %} at {{ request.path_info|escape }}{% endif %} + + {% if not is_email %} + + {% endif %} + + +
    +

    {% if exception_type %}{{ exception_type }}{% else %}Report{% endif %} + {% if request %} at {{ request.path_info|escape }}{% endif %}

    +
    {% if exception_value %}{{ exception_value|force_escape }}{% else %}No exception message supplied{% endif %}
    + +{% if request %} + + + + + + + + +{% endif %} + + + + +{% if exception_type %} + + + + +{% endif %} +{% if exception_type and exception_value %} + + + + +{% endif %} +{% if lastframe %} + + + + +{% endif %} + + + + + + + + + + + + + + + + +
    Request Method:{{ request.META.REQUEST_METHOD }}
    Request URL:{{ request.get_raw_uri|escape }}
    Django Version:{{ django_version_info }}
    Exception Type:{{ exception_type }}
    Exception Value:
    {{ exception_value|force_escape }}
    Exception Location:{{ lastframe.filename|escape }} in {{ lastframe.function|escape }}, line {{ lastframe.lineno }}
    Python Executable:{{ sys_executable|escape }}
    Python Version:{{ sys_version_info }}
    Python Path:
    {{ sys_path|pprint }}
    Server time:{{server_time|date:"r"}}
    +
    +{% if unicode_hint %} +
    +

    Unicode error hint

    +

    The string that could not be encoded/decoded was: {{ unicode_hint|force_escape }}

    +
    +{% endif %} +{% if template_does_not_exist %} +
    +

    Template-loader postmortem

    + {% if postmortem %} +

    Django tried loading these templates, in this order:

    + {% for entry in postmortem %} +

    Using engine {{ entry.backend.name }}:

    +
      + {% if entry.tried %} + {% for attempt in entry.tried %} +
    • {{ attempt.0.loader_name }}: {{ attempt.0.name }} ({{ attempt.1 }})
    • + {% endfor %} + {% else %} +
    • This engine did not provide a list of tried templates.
    • + {% endif %} +
    + {% endfor %} + {% else %} +

    No templates were found because your 'TEMPLATES' setting is not configured.

    + {% endif %} +
    +{% endif %} +{% if template_info %} +
    +

    Error during template rendering

    +

    In template {{ template_info.name }}, error at line {{ template_info.line }}

    +

    {{ template_info.message }}

    + + {% for source_line in template_info.source_lines %} + {% if source_line.0 == template_info.line %} + + + + {% else %} + + + {% endif %} + {% endfor %} +
    {{ source_line.0 }}{{ template_info.before }}{{ template_info.during }}{{ template_info.after }}
    {{ source_line.0 }}{{ source_line.1 }}
    +
    +{% endif %} +{% if frames %} +
    +

    Traceback {% if not is_email %} + Switch to copy-and-paste view{% endif %} +

    + {% autoescape off %} +
    +
      + {% for frame in frames %} + {% ifchanged frame.exc_cause %}{% if frame.exc_cause %} +
    • + {% if frame.exc_cause_explicit %} + The above exception ({{ frame.exc_cause }}) was the direct cause of the following exception: + {% else %} + During handling of the above exception ({{ frame.exc_cause }}), another exception occurred: + {% endif %} +

    • + {% endif %}{% endifchanged %} +
    • + {{ frame.filename|escape }} in {{ frame.function|escape }} + + {% if frame.context_line %} +
      + {% if frame.pre_context and not is_email %} +
        + {% for line in frame.pre_context %} +
      1. {{ line|escape }}
      2. + {% endfor %} +
      + {% endif %} +
        +
      1. {{ frame.context_line|escape }}
        {% if not is_email %} ...{% endif %}
      2. +
      + {% if frame.post_context and not is_email %} +
        + {% for line in frame.post_context %} +
      1. {{ line|escape }}
      2. + {% endfor %} +
      + {% endif %} +
      + {% endif %} + + {% if frame.vars %} +
      + {% if is_email %} +

      Local Vars

      + {% else %} + Local vars + {% endif %} +
      + + + + + + + + + {% for var in frame.vars|dictsort:0 %} + + + + + {% endfor %} + +
      VariableValue
      {{ var.0|force_escape }}
      {{ var.1 }}
      + {% endif %} +
    • + {% endfor %} +
    +
    + {% endautoescape %} +
    +{% if not is_email %} +
    + + + + + +

    + +
    +
    +
    +{% endif %} +{% endif %} + +
    +

    Request information

    + +{% if request %} + {% if user_str %} +

    USER

    +

    {{ user_str }}

    + {% endif %} + +

    GET

    + {% if request.GET %} + + + + + + + + + {% for k, v in request_GET_items %} + + + + + {% endfor %} + +
    VariableValue
    {{ k }}
    {{ v|pprint }}
    + {% else %} +

    No GET data

    + {% endif %} + +

    POST

    + {% if filtered_POST_items %} + + + + + + + + + {% for k, v in filtered_POST_items %} + + + + + {% endfor %} + +
    VariableValue
    {{ k }}
    {{ v|pprint }}
    + {% else %} +

    No POST data

    + {% endif %} +

    FILES

    + {% if request.FILES %} + + + + + + + + + {% for k, v in request_FILES_items %} + + + + + {% endfor %} + +
    VariableValue
    {{ k }}
    {{ v|pprint }}
    + {% else %} +

    No FILES data

    + {% endif %} + + + + {% if request.COOKIES %} + + + + + + + + + {% for k, v in request_COOKIES_items %} + + + + + {% endfor %} + +
    VariableValue
    {{ k }}
    {{ v|pprint }}
    + {% else %} +

    No cookie data

    + {% endif %} + +

    META

    + + + + + + + + + {% for var in request.META.items|dictsort:0 %} + + + + + {% endfor %} + +
    VariableValue
    {{ var.0 }}
    {{ var.1|pprint }}
    +{% else %} +

    Request data not supplied

    +{% endif %} + +

    Settings

    +

    Using settings module {{ settings.SETTINGS_MODULE }}

    + + + + + + + + + {% for var in settings.items|dictsort:0 %} + + + + + {% endfor %} + +
    SettingValue
    {{ var.0 }}
    {{ var.1|pprint }}
    + +
    +{% if not is_email %} +
    +

    + You're seeing this error because you have DEBUG = True in your + Django settings file. Change that to False, and Django will + display a standard page generated by the handler for this status code. +

    +
    +{% endif %} + + diff --git a/django/views/templates/technical_500.txt b/django/views/templates/technical_500.txt new file mode 100644 index 000000000000..1777051906f4 --- /dev/null +++ b/django/views/templates/technical_500.txt @@ -0,0 +1,66 @@ +{% firstof exception_type 'Report' %}{% if request %} at {{ request.path_info }}{% endif %} +{% firstof exception_value 'No exception message supplied' %} +{% if request %} +Request Method: {{ request.META.REQUEST_METHOD }} +Request URL: {{ request.get_raw_uri }}{% endif %} +Django Version: {{ django_version_info }} +Python Executable: {{ sys_executable }} +Python Version: {{ sys_version_info }} +Python Path: {{ sys_path }} +Server time: {{server_time|date:"r"}} +Installed Applications: +{{ settings.INSTALLED_APPS|pprint }} +Installed Middleware: +{{ settings.MIDDLEWARE|pprint }} +{% if template_does_not_exist %}Template loader postmortem +{% if postmortem %}Django tried loading these templates, in this order: +{% for entry in postmortem %} +Using engine {{ entry.backend.name }}: +{% if entry.tried %}{% for attempt in entry.tried %} * {{ attempt.0.loader_name }}: {{ attempt.0.name }} ({{ attempt.1 }}) +{% endfor %}{% else %} This engine did not provide a list of tried templates. +{% endif %}{% endfor %} +{% else %}No templates were found because your 'TEMPLATES' setting is not configured. +{% endif %} +{% endif %}{% if template_info %} +Template error: +In template {{ template_info.name }}, error at line {{ template_info.line }} + {{ template_info.message }} +{% for source_line in template_info.source_lines %}{% if source_line.0 == template_info.line %} {{ source_line.0 }} : {{ template_info.before }} {{ template_info.during }} {{ template_info.after }}{% else %} {{ source_line.0 }} : {{ source_line.1 }}{% endif %}{% endfor %}{% endif %}{% if frames %} + +Traceback: +{% for frame in frames %}{% ifchanged frame.exc_cause %}{% if frame.exc_cause %} +{% if frame.exc_cause_explicit %}The above exception ({{ frame.exc_cause }}) was the direct cause of the following exception:{% else %}During handling of the above exception ({{ frame.exc_cause }}), another exception occurred:{% endif %} +{% endif %}{% endifchanged %} +File "{{ frame.filename }}" in {{ frame.function }} +{% if frame.context_line %} {{ frame.lineno }}. {{ frame.context_line }}{% endif %} +{% endfor %} +{% if exception_type %}Exception Type: {{ exception_type }}{% if request %} at {{ request.path_info }}{% endif %} +{% if exception_value %}Exception Value: {{ exception_value }}{% endif %}{% endif %}{% endif %} +{% if request %}Request information: +{% if user_str %}USER: {{ user_str }}{% endif %} + +GET:{% for k, v in request_GET_items %} +{{ k }} = {{ v|stringformat:"r" }}{% empty %} No GET data{% endfor %} + +POST:{% for k, v in filtered_POST_items %} +{{ k }} = {{ v|stringformat:"r" }}{% empty %} No POST data{% endfor %} + +FILES:{% for k, v in request_FILES_items %} +{{ k }} = {{ v|stringformat:"r" }}{% empty %} No FILES data{% endfor %} + +COOKIES:{% for k, v in request_COOKIES_items %} +{{ k }} = {{ v|stringformat:"r" }}{% empty %} No cookie data{% endfor %} + +META:{% for k, v in request.META.items|dictsort:0 %} +{{ k }} = {{ v|stringformat:"r" }}{% endfor %} +{% else %}Request data not supplied +{% endif %} +Settings: +Using settings module {{ settings.SETTINGS_MODULE }}{% for k, v in settings.items|dictsort:0 %} +{{ k }} = {{ v|stringformat:"r" }}{% endfor %} + +{% if not is_email %} +You're seeing this error because you have DEBUG = True in your +Django settings file. Change that to False, and Django will +display a standard page generated by the handler for this status code. +{% endif %} diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py index 828d59a88f96..b026618b4df7 100644 --- a/tests/view_tests/tests/test_debug.py +++ b/tests/view_tests/tests/test_debug.py @@ -279,7 +279,7 @@ def test_request_and_exception(self): exc_type, exc_value, tb = sys.exc_info() reporter = ExceptionReporter(request, exc_type, exc_value, tb) html = reporter.get_traceback_html() - self.assertIn('

    ValueError at /test_view/

    ', html) + self.assertInHTML('

    ValueError at /test_view/

    ', html) self.assertIn('
    Can't find my keys
    ', html) self.assertIn('Request Method:', html) self.assertIn('Request URL:', html) @@ -299,7 +299,7 @@ def test_no_request(self): exc_type, exc_value, tb = sys.exc_info() reporter = ExceptionReporter(None, exc_type, exc_value, tb) html = reporter.get_traceback_html() - self.assertIn('

    ValueError

    ', html) + self.assertInHTML('

    ValueError

    ', html) self.assertIn('
    Can't find my keys
    ', html) self.assertNotIn('Request Method:', html) self.assertNotIn('Request URL:', html) @@ -333,7 +333,7 @@ def test_no_exception(self): request = self.rf.get('/test_view/') reporter = ExceptionReporter(request, None, None, None) html = reporter.get_traceback_html() - self.assertIn('

    Report at /test_view/

    ', html) + self.assertInHTML('

    Report at /test_view/

    ', html) self.assertIn('
    No exception message supplied
    ', html) self.assertIn('Request Method:', html) self.assertIn('Request URL:', html) @@ -376,7 +376,7 @@ def test_request_and_message(self): request = self.rf.get('/test_view/') reporter = ExceptionReporter(request, None, "I'm a little teapot", None) html = reporter.get_traceback_html() - self.assertIn('

    Report at /test_view/

    ', html) + self.assertInHTML('

    Report at /test_view/

    ', html) self.assertIn('
    I'm a little teapot
    ', html) self.assertIn('Request Method:', html) self.assertIn('Request URL:', html) @@ -389,7 +389,7 @@ def test_request_and_message(self): def test_message_only(self): reporter = ExceptionReporter(None, None, "I'm a little teapot", None) html = reporter.get_traceback_html() - self.assertIn('

    Report

    ', html) + self.assertInHTML('

    Report

    ', html) self.assertIn('
    I'm a little teapot
    ', html) self.assertNotIn('Request Method:', html) self.assertNotIn('Request URL:', html) @@ -457,7 +457,7 @@ def test_unfrozen_importlib(self): exc_type, exc_value, tb = sys.exc_info() reporter = ExceptionReporter(request, exc_type, exc_value, tb) html = reporter.get_traceback_html() - self.assertIn('

    %sError at /test_view/

    ' % 'ModuleNotFound' if PY36 else 'Import', html) + self.assertInHTML('

    %sError at /test_view/

    ' % ('ModuleNotFound' if PY36 else 'Import'), html) def test_ignore_traceback_evaluation_exceptions(self): """ @@ -544,7 +544,7 @@ def __str__(self): reporter = ExceptionReporter(request, exc_type, exc_value, tb) html = reporter.get_traceback_html() - self.assertIn('

    ValueError at /test_view/

    ', html) + self.assertInHTML('

    ValueError at /test_view/

    ', html) self.assertIn('
    Oops
    ', html) self.assertIn('

    USER

    ', html) self.assertIn('

    [unable to retrieve the current user]

    ', html) From 6d5bb6ae9e7928155a0035e936ba74ac9c52e409 Mon Sep 17 00:00:00 2001 From: Sergey Fedoseev Date: Sun, 9 Apr 2017 08:18:56 +0500 Subject: [PATCH 0459/3180] Refs #28024 -- Optimized LineString.__init__() by avoiding superfluous index and dimension checks. --- django/contrib/gis/geos/linestring.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/django/contrib/gis/geos/linestring.py b/django/contrib/gis/geos/linestring.py index 9f98ed7e237c..eb339658e97f 100644 --- a/django/contrib/gis/geos/linestring.py +++ b/django/contrib/gis/geos/linestring.py @@ -73,16 +73,18 @@ def __init__(self, *args, **kwargs): numpy_coords = True # Creating a coordinate sequence object because it is easier to - # set the points using GEOSCoordSeq.__setitem__(). + # set the points using its methods. cs = GEOSCoordSeq(capi.create_cs(ncoords, ndim), z=bool(ndim == 3)) + point_setter = cs._set_point_3d if ndim == 3 else cs._set_point_2d for i in range(ncoords): if numpy_coords: - cs[i] = coords[i, :] + point_coords = coords[i, :] elif isinstance(coords[i], Point): - cs[i] = coords[i].tuple + point_coords = coords[i].tuple else: - cs[i] = coords[i] + point_coords = coords[i] + point_setter(i, point_coords) # Calling the base geometry initialization with the returned pointer # from the function. From e1253bc26facfa1d0fca161f43925e99c2591ced Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Thu, 13 Apr 2017 20:20:01 +0200 Subject: [PATCH 0460/3180] Refs #25406 -- Removed exception hiding in MySQL test database creation during --keepdb. Thanks Adam Johnson, Simon Charette and Tim Graham for reviews. --- django/db/backends/mysql/creation.py | 35 ++++++++++++++++++++----- tests/backends/test_creation.py | 38 ++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/django/db/backends/mysql/creation.py b/django/db/backends/mysql/creation.py index c53b9f83353d..546fb6a6295b 100644 --- a/django/db/backends/mysql/creation.py +++ b/django/db/backends/mysql/creation.py @@ -17,24 +17,45 @@ def sql_table_creation_suffix(self): suffix.append('COLLATE %s' % test_settings['COLLATION']) return ' '.join(suffix) + def _execute_create_test_db(self, cursor, parameters, keepdb=False): + try: + if keepdb: + # If the database should be kept, add "IF NOT EXISTS" to avoid + # "database exists" error, also temporarily disable "database + # exists" warning. + cursor.execute(''' + SET @_tmp_sql_notes := @@sql_notes, sql_notes = 0; + CREATE DATABASE IF NOT EXISTS %(dbname)s %(suffix)s; + SET sql_notes = @_tmp_sql_notes; + ''' % parameters) + else: + super()._execute_create_test_db(cursor, parameters, keepdb) + except Exception as e: + if len(e.args) < 1 or e.args[0] != 1007: + # All errors except "database exists" (1007) cancel tests. + sys.stderr.write('Got an error creating the test database: %s\n' % e) + sys.exit(2) + else: + raise e + def _clone_test_db(self, number, verbosity, keepdb=False): - qn = self.connection.ops.quote_name source_database_name = self.connection.settings_dict['NAME'] target_database_name = self.get_test_db_clone_settings(number)['NAME'] - + test_db_params = { + 'dbname': self.connection.ops.quote_name(target_database_name), + 'suffix': self.sql_table_creation_suffix(), + } with self._nodb_connection.cursor() as cursor: try: - cursor.execute("CREATE DATABASE %s" % qn(target_database_name)) + self._execute_create_test_db(cursor, test_db_params, keepdb) except Exception: - if keepdb: - return try: if verbosity >= 1: print("Destroying old test database for alias %s..." % ( self._get_database_display_str(verbosity, target_database_name), )) - cursor.execute("DROP DATABASE %s" % qn(target_database_name)) - cursor.execute("CREATE DATABASE %s" % qn(target_database_name)) + cursor.execute('DROP DATABASE %(dbname)s' % test_db_params) + self._execute_create_test_db(cursor, test_db_params, keepdb) except Exception as e: sys.stderr.write("Got an error recreating the test database: %s\n" % e) sys.exit(2) diff --git a/tests/backends/test_creation.py b/tests/backends/test_creation.py index f96102117b54..2ecd03ce2dc0 100644 --- a/tests/backends/test_creation.py +++ b/tests/backends/test_creation.py @@ -8,6 +8,8 @@ from django.db.backends.base.creation import ( TEST_DATABASE_PREFIX, BaseDatabaseCreation, ) +from django.db.backends.mysql.creation import \ + DatabaseCreation as MySQLDatabaseCreation from django.db.backends.oracle.creation import \ DatabaseCreation as OracleDatabaseCreation from django.db.backends.postgresql.creation import \ @@ -191,3 +193,39 @@ def test_create_test_user(self, *mocked_objects): creation._create_test_db(verbosity=0, keepdb=False) with self.assertRaises(SystemExit): creation._create_test_db(verbosity=0, keepdb=True) + + +@unittest.skipUnless(connection.vendor == 'mysql', "MySQL specific tests") +class MySQLDatabaseCreationTests(SimpleTestCase): + + def _execute_raise_database_exists(self, cursor, parameters, keepdb=False): + raise DatabaseError(1007, "Can't create database '%s'; database exists" % parameters['dbname']) + + def _execute_raise_access_denied(self, cursor, parameters, keepdb=False): + raise DatabaseError(1044, "Access denied for user") + + def patch_test_db_creation(self, execute_create_test_db): + return mock.patch.object(BaseDatabaseCreation, '_execute_create_test_db', execute_create_test_db) + + @mock.patch('sys.stdout', new_callable=StringIO) + @mock.patch('sys.stderr', new_callable=StringIO) + def test_create_test_db_database_exists(self, *mocked_objects): + # Simulate test database creation raising "database exists" + creation = MySQLDatabaseCreation(connection) + with self.patch_test_db_creation(self._execute_raise_database_exists): + with mock.patch('builtins.input', return_value='no'): + with self.assertRaises(SystemExit): + # SystemExit is raised if the user answers "no" to the + # prompt asking if it's okay to delete the test database. + creation._create_test_db(verbosity=0, autoclobber=False, keepdb=False) + # "Database exists" shouldn't appear when keepdb is on + creation._create_test_db(verbosity=0, autoclobber=False, keepdb=True) + + @mock.patch('sys.stdout', new_callable=StringIO) + @mock.patch('sys.stderr', new_callable=StringIO) + def test_create_test_db_unexpected_error(self, *mocked_objects): + # Simulate test database creation raising unexpected error + creation = MySQLDatabaseCreation(connection) + with self.patch_test_db_creation(self._execute_raise_access_denied): + with self.assertRaises(SystemExit): + creation._create_test_db(verbosity=0, autoclobber=False, keepdb=False) From 7741d4e8787809b38df970aa11df8bdad4f22dd8 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Fri, 14 Apr 2017 08:44:11 +0200 Subject: [PATCH 0461/3180] Double quoted HTML attributes in widget docs --- docs/ref/forms/widgets.txt | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/ref/forms/widgets.txt b/docs/ref/forms/widgets.txt index 828033352ac7..1dc57a1f7ef5 100644 --- a/docs/ref/forms/widgets.txt +++ b/docs/ref/forms/widgets.txt @@ -516,7 +516,7 @@ These widgets make use of the HTML elements ``input`` and ``textarea``. * ``input_type``: ``'password'`` * ``template_name``: ``'django/forms/widgets/password.html'`` - * Renders as: ```` + * Renders as: ```` Takes one optional argument: @@ -532,7 +532,7 @@ These widgets make use of the HTML elements ``input`` and ``textarea``. * ``input_type``: ``'hidden'`` * ``template_name``: ``'django/forms/widgets/hidden.html'`` - * Renders as: ```` + * Renders as: ```` Note that there also is a :class:`MultipleHiddenInput` widget that encapsulates a set of hidden input elements. @@ -544,7 +544,7 @@ These widgets make use of the HTML elements ``input`` and ``textarea``. * ``input_type``: ``'text'`` * ``template_name``: ``'django/forms/widgets/date.html'`` - * Renders as: ```` + * Renders as: ```` Takes same arguments as :class:`TextInput`, with one more optional argument: @@ -563,7 +563,7 @@ These widgets make use of the HTML elements ``input`` and ``textarea``. * ``input_type``: ``'text'`` * ``template_name``: ``'django/forms/widgets/datetime.html'`` - * Renders as: ```` + * Renders as: ```` Takes same arguments as :class:`TextInput`, with one more optional argument: @@ -586,7 +586,7 @@ These widgets make use of the HTML elements ``input`` and ``textarea``. * ``input_type``: ``'text'`` * ``template_name``: ``'django/forms/widgets/time.html'`` - * Renders as: ```` + * Renders as: ```` Takes same arguments as :class:`TextInput`, with one more optional argument: @@ -614,7 +614,7 @@ Selector and checkbox widgets ----------------------------- These widgets make use of the HTML elements ````, and ````. +````, and ````. Widgets that render multiple choices have an ``option_template_name`` attribute that specifies the template used to render each choice. For example, for the @@ -628,7 +628,7 @@ that specifies the template used to render each choice. For example, for the * ``input_type``: ``'checkbox'`` * ``template_name``: ``'django/forms/widgets/checkbox.html'`` - * Renders as: ```` + * Renders as: ```` Takes one optional argument: @@ -671,7 +671,7 @@ that specifies the template used to render each choice. For example, for the * ``option_template_name``: ``'django/forms/widgets/select_option.html'`` Similar to :class:`Select`, but allows multiple selection: - ```` + ```` ``RadioSelect`` ~~~~~~~~~~~~~~~ @@ -687,7 +687,7 @@ that specifies the template used to render each choice. For example, for the .. code-block:: html
      -
    • +
    • ...
    @@ -782,7 +782,7 @@ that specifies the template used to render each choice. For example, for the .. code-block:: html
      -
    • +
    • ...
    @@ -809,7 +809,7 @@ File upload widgets .. class:: FileInput * ``template_name``: ``'django/forms/widgets/file.html'`` - * Renders as: ```` + * Renders as: ```` ``ClearableFileInput`` ~~~~~~~~~~~~~~~~~~~~~~ @@ -817,7 +817,7 @@ File upload widgets .. class:: ClearableFileInput * ``template_name``: ``'django/forms/widgets/clearable_file_input.html'`` - * Renders as: ```` with an additional checkbox + * Renders as: ```` with an additional checkbox input to clear the field's value, if the field is not required and has initial data. @@ -832,7 +832,7 @@ Composite widgets .. class:: MultipleHiddenInput * ``template_name``: ``'django/forms/widgets/multiple_hidden.html'`` - * Renders as: multiple ```` tags + * Renders as: multiple ```` tags A widget that handles multiple hidden widgets for fields that have a list of values. From 83cbb8d080299669de3569941a40789e5d32b009 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 14 Apr 2017 08:05:58 -0400 Subject: [PATCH 0462/3180] Fixed #28067 -- Clarified __str__() return type when using python_2_unicode_compatible(). --- docs/ref/utils.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index c9ab5e39759b..19e8361a6756 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -199,7 +199,8 @@ The functions defined in this module share the following properties: Python 2. Under Python 3 it does nothing. To support Python 2 and 3 with a single code base, define a ``__str__`` - method returning text and apply this decorator to the class. + method returning text (use ``six.text_type()`` if you're doing some + casting) and apply this decorator to the class. .. function:: smart_text(s, encoding='utf-8', strings_only=False, errors='strict') From 941b8691351d4739cd9391b0a1326abd0b1c29c0 Mon Sep 17 00:00:00 2001 From: Abhishek Gautam Date: Fri, 14 Apr 2017 17:42:14 +0530 Subject: [PATCH 0463/3180] Fixed #28008 -- Replaced getElementsByClassName() JavaScript in debug view template. --- AUTHORS | 1 + django/views/templates/technical_500.html | 24 ++++------------------- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/AUTHORS b/AUTHORS index 35d80ec85c62..7c211983d61a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -8,6 +8,7 @@ answer newbie questions, and generally made Django that much better: Aaron Cannon Aaron Swartz Aaron T. Myers + Abhishek Gautam Adam Johnson Adam Malinowski Adam Vandenberg diff --git a/django/views/templates/technical_500.html b/django/views/templates/technical_500.html index 945c27827a3d..413bedc53721 100644 --- a/django/views/templates/technical_500.html +++ b/django/views/templates/technical_500.html @@ -65,32 +65,16 @@ {% if not is_email %} +

    +

    + @@ -76,6 +77,7 @@ +