summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Godwin <andrew@aeracode.org>2013-07-02 10:49:53 +0100
committerAndrew Godwin <andrew@aeracode.org>2013-07-02 10:49:53 +0100
commitb1e0ec06f0d538eb2ab16a7c1ecefd1d896e6382 (patch)
treeb837c6144106f304a7aacdfd4fae47ea95f4158a
parent7a47ba6f6aeca36b8b092dbafd36abb342d34d4b (diff)
parent6c66a41c3dc697dc3bda4e31e8b05084d2ede915 (diff)
Merge branch 'master' into schema-alteration
-rw-r--r--INSTALL3
-rwxr-xr-xdjango/bin/daily_cleanup.py19
-rw-r--r--django/conf/__init__.py22
-rw-r--r--django/conf/global_settings.py2
-rw-r--r--django/conf/urls/shortcut.py2
-rw-r--r--django/contrib/admin/options.py2
-rw-r--r--django/contrib/admin/tests.py2
-rw-r--r--django/contrib/admin/util.py3
-rw-r--r--django/contrib/admin/views/main.py8
-rw-r--r--django/contrib/admindocs/tests/test_fields.py3
-rw-r--r--django/contrib/auth/forms.py6
-rw-r--r--django/contrib/auth/models.py39
-rw-r--r--django/contrib/auth/tests/test_hashers.py5
-rw-r--r--django/contrib/auth/tests/test_models.py39
-rw-r--r--django/contrib/auth/tests/test_tokens.py4
-rw-r--r--django/contrib/auth/tests/test_views.py22
-rw-r--r--django/contrib/auth/tests/utils.py3
-rw-r--r--django/contrib/auth/urls.py3
-rw-r--r--django/contrib/auth/views.py9
-rw-r--r--django/contrib/comments/__init__.py2
-rw-r--r--django/contrib/comments/templatetags/comments.py2
-rw-r--r--django/contrib/contenttypes/generic.py6
-rw-r--r--django/contrib/formtools/tests/tests.py2
-rw-r--r--django/contrib/gis/forms/fields.py6
-rw-r--r--django/contrib/gis/gdal/tests/test_driver.py5
-rw-r--r--django/contrib/gis/gdal/tests/test_ds.py4
-rw-r--r--django/contrib/gis/gdal/tests/test_envelope.py7
-rw-r--r--django/contrib/gis/gdal/tests/test_geom.py4
-rw-r--r--django/contrib/gis/gdal/tests/test_srs.py5
-rw-r--r--django/contrib/gis/geoip/tests.py5
-rw-r--r--django/contrib/gis/geos/tests/test_geos.py4
-rw-r--r--django/contrib/gis/geos/tests/test_geos_mutation.py4
-rw-r--r--django/contrib/gis/geos/tests/test_io.py2
-rw-r--r--django/contrib/gis/geos/tests/test_mutable_list.py4
-rw-r--r--django/contrib/gis/tests/distapp/tests.py3
-rw-r--r--django/contrib/gis/tests/geo3d/tests.py2
-rw-r--r--django/contrib/gis/tests/geoadmin/tests.py3
-rw-r--r--django/contrib/gis/tests/geoapp/test_feeds.py2
-rw-r--r--django/contrib/gis/tests/geoapp/test_regress.py2
-rw-r--r--django/contrib/gis/tests/geoapp/test_sitemaps.py2
-rw-r--r--django/contrib/gis/tests/geoapp/tests.py5
-rw-r--r--django/contrib/gis/tests/geogapp/tests.py2
-rw-r--r--django/contrib/gis/tests/inspectapp/tests.py2
-rw-r--r--django/contrib/gis/tests/layermap/tests.py6
-rw-r--r--django/contrib/gis/tests/relatedapp/tests.py3
-rw-r--r--django/contrib/gis/tests/test_geoforms.py7
-rw-r--r--django/contrib/gis/tests/test_measure.py3
-rw-r--r--django/contrib/gis/tests/test_spatialrefsys.py3
-rw-r--r--django/contrib/humanize/tests.py2
-rw-r--r--django/contrib/messages/tests/base.py3
-rw-r--r--django/contrib/messages/tests/test_middleware.py3
-rw-r--r--django/contrib/sessions/middleware.py7
-rw-r--r--django/contrib/sessions/tests.py2
-rw-r--r--django/contrib/sitemaps/tests/test_flatpages.py3
-rw-r--r--django/contrib/sitemaps/tests/test_http.py2
-rw-r--r--django/contrib/sitemaps/views.py17
-rw-r--r--django/core/files/storage.py1
-rw-r--r--django/core/management/commands/cleanup.py11
-rw-r--r--django/db/__init__.py4
-rw-r--r--django/db/backends/__init__.py34
-rw-r--r--django/db/backends/creation.py2
-rw-r--r--django/db/backends/mysql/base.py2
-rw-r--r--django/db/backends/sqlite3/base.py10
-rw-r--r--django/db/models/fields/files.py2
-rw-r--r--django/db/models/fields/related.py13
-rw-r--r--django/db/models/manager.py4
-rw-r--r--django/db/models/options.py8
-rw-r--r--django/db/models/query.py9
-rw-r--r--django/db/transaction.py26
-rw-r--r--django/db/utils.py9
-rw-r--r--django/forms/forms.py2
-rw-r--r--django/forms/models.py6
-rw-r--r--django/forms/widgets.py2
-rw-r--r--django/http/__init__.py8
-rw-r--r--django/http/response.py68
-rw-r--r--django/middleware/cache.py2
-rw-r--r--django/middleware/common.py2
-rw-r--r--django/middleware/doc.py2
-rw-r--r--django/middleware/transaction.py2
-rw-r--r--django/shortcuts/__init__.py8
-rw-r--r--django/template/defaulttags.py4
-rw-r--r--django/template/response.py10
-rw-r--r--django/test/_doctest.py2
-rw-r--r--django/test/runner.py4
-rw-r--r--django/test/simple.py4
-rw-r--r--django/test/testcases.py37
-rw-r--r--django/test/utils.py37
-rw-r--r--django/utils/datastructures.py26
-rw-r--r--django/utils/dictconfig.py5
-rw-r--r--django/utils/encoding.py24
-rw-r--r--django/utils/image.py2
-rw-r--r--django/utils/itercompat.py7
-rw-r--r--django/utils/log.py21
-rw-r--r--django/utils/simplejson.py31
-rw-r--r--django/utils/unittest.py11
-rw-r--r--django/utils/unittest/__init__.py80
-rw-r--r--django/utils/unittest/__main__.py10
-rw-r--r--django/utils/unittest/case.py1076
-rw-r--r--django/utils/unittest/collector.py9
-rw-r--r--django/utils/unittest/compatibility.py64
-rw-r--r--django/utils/unittest/loader.py322
-rw-r--r--django/utils/unittest/main.py241
-rw-r--r--django/utils/unittest/result.py183
-rw-r--r--django/utils/unittest/runner.py206
-rw-r--r--django/utils/unittest/signals.py57
-rw-r--r--django/utils/unittest/suite.py287
-rw-r--r--django/utils/unittest/util.py99
-rw-r--r--django/views/defaults.py2
-rw-r--r--django/views/generic/edit.py2
-rw-r--r--django/views/static.py8
-rw-r--r--docs/faq/install.txt53
-rw-r--r--docs/internals/deprecation.txt12
-rw-r--r--docs/intro/install.txt11
-rw-r--r--docs/ref/contrib/auth.txt14
-rw-r--r--docs/ref/contrib/contenttypes.txt6
-rw-r--r--docs/ref/django-admin.txt12
-rw-r--r--docs/ref/models/querysets.txt16
-rw-r--r--docs/ref/request-response.txt26
-rw-r--r--docs/ref/settings.txt22
-rw-r--r--docs/ref/template-response.txt6
-rw-r--r--docs/ref/utils.txt27
-rw-r--r--docs/releases/1.5-alpha-1.txt10
-rw-r--r--docs/releases/1.5-beta-1.txt12
-rw-r--r--docs/releases/1.5.txt12
-rw-r--r--docs/releases/1.6.txt6
-rw-r--r--docs/releases/1.7.txt47
-rw-r--r--docs/topics/auth/customizing.txt34
-rw-r--r--docs/topics/class-based-views/mixins.txt25
-rw-r--r--docs/topics/install.txt6
-rw-r--r--docs/topics/logging.txt11
-rw-r--r--docs/topics/testing/_images/django_unittest_classes_hierarchy.graffle250
-rw-r--r--docs/topics/testing/_images/django_unittest_classes_hierarchy.pdfbin51979 -> 37750 bytes
-rw-r--r--docs/topics/testing/_images/django_unittest_classes_hierarchy.svg2
-rw-r--r--docs/topics/testing/advanced.txt2
-rw-r--r--docs/topics/testing/overview.txt37
-rw-r--r--setup.cfg2
-rw-r--r--setup.py1
-rw-r--r--tests/.coveragerc2
-rw-r--r--tests/admin_scripts/app_with_import/models.py6
-rw-r--r--tests/admin_scripts/tests.py5
-rw-r--r--tests/admin_views/tests.py19
-rw-r--r--tests/admin_widgets/tests.py2
-rw-r--r--tests/aggregation_regress/tests.py1
-rw-r--r--tests/app_loading/tests.py3
-rw-r--r--tests/backends/tests.py18
-rw-r--r--tests/bash_completion/tests.py2
-rw-r--r--tests/bug639/tests.py2
-rw-r--r--tests/bug8245/tests.py3
-rw-r--r--tests/builtin_server/tests.py2
-rw-r--r--tests/cache/tests.py11
-rw-r--r--tests/db_typecasts/tests.py2
-rw-r--r--tests/decorators/tests.py2
-rw-r--r--tests/defaultfilters/tests.py3
-rw-r--r--tests/deprecation/tests.py2
-rw-r--r--tests/dispatch/tests/test_dispatcher.py2
-rw-r--r--tests/dispatch/tests/test_saferef.py3
-rw-r--r--tests/file_storage/tests.py10
-rw-r--r--tests/file_uploads/tests.py2
-rw-r--r--tests/files/tests.py2
-rw-r--r--tests/fixtures/tests.py56
-rw-r--r--tests/fixtures_model_package/tests.py7
-rw-r--r--tests/fixtures_regress/tests.py32
-rw-r--r--tests/forms_tests/tests/test_validators.py3
-rw-r--r--tests/generic_views/test_base.py2
-rw-r--r--tests/generic_views/test_dates.py2
-rw-r--r--tests/generic_views/test_edit.py8
-rw-r--r--tests/httpwrappers/tests.py27
-rw-r--r--tests/indexes/tests.py3
-rw-r--r--tests/inspectdb/tests.py2
-rw-r--r--tests/introspection/tests.py3
-rw-r--r--tests/invalid_models/tests.py3
-rw-r--r--tests/logging_tests/tests.py2
-rw-r--r--tests/max_lengths/tests.py4
-rw-r--r--tests/middleware/tests.py12
-rw-r--r--tests/model_fields/test_imagefield.py2
-rw-r--r--tests/model_fields/tests.py13
-rw-r--r--tests/model_forms/tests.py8
-rw-r--r--tests/model_forms_regress/tests.py6
-rw-r--r--tests/model_formsets/tests.py2
-rw-r--r--tests/model_inheritance_regress/tests.py4
-rw-r--r--tests/model_regress/tests.py2
-rw-r--r--tests/modeladmin/tests.py3
-rw-r--r--tests/multiple_database/tests.py21
-rw-r--r--tests/pagination/tests.py2
-rw-r--r--tests/proxy_models/tests.py2
-rw-r--r--tests/queries/tests.py2
-rw-r--r--tests/requests/tests.py6
-rw-r--r--tests/resolve_url/tests.py3
-rwxr-xr-xtests/runtests.py2
-rw-r--r--tests/select_for_update/tests.py2
-rw-r--r--tests/select_related/tests.py58
-rw-r--r--tests/select_related_onetoone/tests.py3
-rw-r--r--tests/serializers/tests.py2
-rw-r--r--tests/serializers_regress/tests.py4
-rw-r--r--tests/settings_tests/tests.py3
-rw-r--r--tests/str/tests.py2
-rw-r--r--tests/template_tests/loaders.py7
-rw-r--r--tests/template_tests/test_callables.py3
-rw-r--r--tests/template_tests/test_context.py4
-rw-r--r--tests/template_tests/test_custom.py3
-rw-r--r--tests/template_tests/test_nodelist.py3
-rw-r--r--tests/template_tests/test_parser.py3
-rw-r--r--tests/template_tests/test_smartif.py3
-rw-r--r--tests/template_tests/test_unicode.py3
-rw-r--r--tests/template_tests/tests.py4
-rw-r--r--tests/test_discovery_sample/tests_sample.py11
-rw-r--r--tests/test_runner/test_discover_runner.py35
-rw-r--r--tests/test_runner/tests.py9
-rw-r--r--tests/test_suite_override/tests.py8
-rw-r--r--tests/test_utils/tests.py41
-rw-r--r--tests/timezones/tests.py2
-rw-r--r--tests/transactions/tests.py10
-rw-r--r--tests/transactions_regress/tests.py15
-rw-r--r--tests/urlpatterns_reverse/tests.py4
-rw-r--r--tests/utils_tests/test_archive.py2
-rw-r--r--tests/utils_tests/test_baseconv.py3
-rw-r--r--tests/utils_tests/test_crypto.py4
-rw-r--r--tests/utils_tests/test_datastructures.py15
-rw-r--r--tests/utils_tests/test_dateformat.py4
-rw-r--r--tests/utils_tests/test_dateparse.py2
-rw-r--r--tests/utils_tests/test_encoding.py3
-rw-r--r--tests/utils_tests/test_feedgenerator.py5
-rw-r--r--tests/utils_tests/test_functional.py3
-rw-r--r--tests/utils_tests/test_html.py2
-rw-r--r--tests/utils_tests/test_http.py2
-rw-r--r--tests/utils_tests/test_ipv6.py3
-rw-r--r--tests/utils_tests/test_module_loading.py4
-rw-r--r--tests/utils_tests/test_os_utils.py2
-rw-r--r--tests/utils_tests/test_regex_helper.py3
-rw-r--r--tests/utils_tests/test_simplelazyobject.py2
-rw-r--r--tests/utils_tests/test_termcolors.py3
-rw-r--r--tests/utils_tests/test_timezone.py3
-rw-r--r--tests/utils_tests/test_tzinfo.py3
-rw-r--r--tests/validation/test_error_messages.py3
-rw-r--r--tests/validation/test_unique.py2
-rw-r--r--tests/validators/tests.py4
-rw-r--r--tests/version/tests.py2
-rw-r--r--tests/view_tests/tests/test_debug.py2
-rw-r--r--tests/view_tests/tests/test_i18n.py3
-rw-r--r--tests/wsgi/tests.py4
240 files changed, 694 insertions, 4096 deletions
diff --git a/INSTALL b/INSTALL
index 5ae2b26900..92be6da650 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,6 +1,6 @@
Thanks for downloading Django.
-To install it, make sure you have Python 2.6 or greater installed. Then run
+To install it, make sure you have Python 2.7 or greater installed. Then run
this command from the command prompt:
python setup.py install
@@ -12,7 +12,6 @@ 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)
- /usr/lib/python2.6/site-packages (Unix, Python 2.6)
C:\\PYTHON\site-packages (Windows)
For more detailed instructions, see docs/intro/install.txt.
diff --git a/django/bin/daily_cleanup.py b/django/bin/daily_cleanup.py
deleted file mode 100755
index 5a2ce210f4..0000000000
--- a/django/bin/daily_cleanup.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Daily cleanup job.
-
-Can be run as a cronjob to clean out old data from the database (only expired
-sessions at the moment).
-"""
-
-import warnings
-
-from django.core import management
-
-if __name__ == "__main__":
- warnings.warn(
- "The `daily_cleanup` script has been deprecated "
- "in favor of `django-admin.py clearsessions`.",
- DeprecationWarning)
- management.call_command('clearsessions')
diff --git a/django/conf/__init__.py b/django/conf/__init__.py
index 61584391cd..c4b9634d83 100644
--- a/django/conf/__init__.py
+++ b/django/conf/__init__.py
@@ -59,14 +59,10 @@ class LazySettings(LazyObject):
Setup logging from LOGGING_CONFIG and LOGGING settings.
"""
if not sys.warnoptions:
- try:
- # Route warnings through python logging
- logging.captureWarnings(True)
- # Allow DeprecationWarnings through the warnings filters
- warnings.simplefilter("default", DeprecationWarning)
- except AttributeError:
- # No captureWarnings on Python 2.6, DeprecationWarnings are on anyway
- pass
+ # Route warnings through python logging
+ logging.captureWarnings(True)
+ # Allow DeprecationWarnings through the warnings filters
+ warnings.simplefilter("default", DeprecationWarning)
if self.LOGGING_CONFIG:
from django.utils.log import DEFAULT_LOGGING
@@ -132,19 +128,17 @@ class Settings(BaseSettings):
% (self.SETTINGS_MODULE, e)
)
- # Settings that should be converted into tuples if they're mistakenly entered
- # as strings.
tuple_settings = ("INSTALLED_APPS", "TEMPLATE_DIRS")
for setting in dir(mod):
if setting == setting.upper():
setting_value = getattr(mod, setting)
+
if setting in tuple_settings and \
isinstance(setting_value, six.string_types):
- warnings.warn("The %s setting must be a tuple. Please fix your "
- "settings, as auto-correction is now deprecated." % setting,
- DeprecationWarning, stacklevel=2)
- setting_value = (setting_value,) # In case the user forgot the comma.
+ raise ImproperlyConfigured("The %s setting must be a tuple. "
+ "Please fix your settings." % setting)
+
setattr(self, setting, setting_value)
if not self.SECRET_KEY:
diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py
index 310b5c163f..7882b21b9b 100644
--- a/django/conf/global_settings.py
+++ b/django/conf/global_settings.py
@@ -562,7 +562,7 @@ MESSAGE_STORAGE = 'django.contrib.messages.storage.fallback.FallbackStorage'
###########
# The callable to use to configure logging
-LOGGING_CONFIG = 'django.utils.log.dictConfig'
+LOGGING_CONFIG = 'logging.config.dictConfig'
# Custom logging configuration.
LOGGING = {}
diff --git a/django/conf/urls/shortcut.py b/django/conf/urls/shortcut.py
index c00d176ad6..08ecd90aa3 100644
--- a/django/conf/urls/shortcut.py
+++ b/django/conf/urls/shortcut.py
@@ -3,7 +3,7 @@ import warnings
from django.conf.urls import patterns
warnings.warn("django.conf.urls.shortcut will be removed in Django 1.8.",
- PendingDeprecationWarning)
+ DeprecationWarning)
urlpatterns = patterns('django.views',
(r'^(?P<content_type_id>\d+)/(?P<object_id>.*)/$', 'defaults.shortcut'),
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index fd516cb512..9c92f7ae9c 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -76,7 +76,7 @@ csrf_protect_m = method_decorator(csrf_protect)
class RenameBaseModelAdminMethods(forms.MediaDefiningClass, RenameMethodsBase):
renamed_methods = (
- ('queryset', 'get_queryset', PendingDeprecationWarning),
+ ('queryset', 'get_queryset', DeprecationWarning),
)
diff --git a/django/contrib/admin/tests.py b/django/contrib/admin/tests.py
index 25ea230b28..82d0bdcb7b 100644
--- a/django/contrib/admin/tests.py
+++ b/django/contrib/admin/tests.py
@@ -1,8 +1,8 @@
import os
+from unittest import SkipTest
from django.test import LiveServerTestCase
from django.utils.module_loading import import_by_path
-from django.utils.unittest import SkipTest
from django.utils.translation import ugettext as _
diff --git a/django/contrib/admin/util.py b/django/contrib/admin/util.py
index a53cd367b4..dd9047c428 100644
--- a/django/contrib/admin/util.py
+++ b/django/contrib/admin/util.py
@@ -3,6 +3,7 @@ from __future__ import unicode_literals
import datetime
import decimal
+from django.contrib.auth import get_permission_codename
from django.db import models
from django.db.models.constants import LOOKUP_SEP
from django.db.models.deletion import Collector
@@ -119,7 +120,7 @@ def get_deleted_objects(objs, opts, user, admin_site, using):
opts.model_name),
None, (quote(obj._get_pk_val()),))
p = '%s.%s' % (opts.app_label,
- opts.get_delete_permission())
+ get_permission_codename('delete', opts))
if not user.has_perm(p):
perms_needed.add(opts.verbose_name)
# Display a link to the admin page.
diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py
index 56462dece8..f766031bf8 100644
--- a/django/contrib/admin/views/main.py
+++ b/django/contrib/admin/views/main.py
@@ -52,7 +52,7 @@ def _is_changelist_popup(request):
warnings.warn(
"The `%s` GET parameter has been renamed to `%s`." %
(IS_LEGACY_POPUP_VAR, IS_POPUP_VAR),
- PendingDeprecationWarning, 2)
+ DeprecationWarning, 2)
return True
return False
@@ -60,7 +60,7 @@ def _is_changelist_popup(request):
class RenameChangeListMethods(RenameMethodsBase):
renamed_methods = (
- ('get_query_set', 'get_queryset', PendingDeprecationWarning),
+ ('get_query_set', 'get_queryset', DeprecationWarning),
)
@@ -115,14 +115,14 @@ class ChangeList(six.with_metaclass(RenameChangeListMethods)):
def root_query_set(self):
warnings.warn("`ChangeList.root_query_set` is deprecated, "
"use `root_queryset` instead.",
- PendingDeprecationWarning, 2)
+ DeprecationWarning, 2)
return self.root_queryset
@property
def query_set(self):
warnings.warn("`ChangeList.query_set` is deprecated, "
"use `queryset` instead.",
- PendingDeprecationWarning, 2)
+ DeprecationWarning, 2)
return self.queryset
def get_filters_params(self, params=None):
diff --git a/django/contrib/admindocs/tests/test_fields.py b/django/contrib/admindocs/tests/test_fields.py
index c048f20287..b505d2deeb 100644
--- a/django/contrib/admindocs/tests/test_fields.py
+++ b/django/contrib/admindocs/tests/test_fields.py
@@ -1,9 +1,10 @@
from __future__ import absolute_import, unicode_literals
+import unittest
+
from django.contrib.admindocs import views
from django.db import models
from django.db.models import fields
-from django.utils import unittest
from django.utils.translation import ugettext as _
diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py
index 43f5303b63..2d7a7c14d4 100644
--- a/django/contrib/auth/forms.py
+++ b/django/contrib/auth/forms.py
@@ -1,7 +1,5 @@
from __future__ import unicode_literals
-import warnings
-
from django import forms
from django.forms.util import flatatt
from django.template import loader
@@ -200,10 +198,6 @@ class AuthenticationForm(forms.Form):
)
return self.cleaned_data
- def check_for_test_cookie(self):
- warnings.warn("check_for_test_cookie is deprecated; ensure your login "
- "view is CSRF-protected.", DeprecationWarning)
-
def get_user_id(self):
if self.user_cache:
return self.user_cache.id
diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py
index 5fec99a783..cf3d37e5c3 100644
--- a/django/contrib/auth/models.py
+++ b/django/contrib/auth/models.py
@@ -1,8 +1,6 @@
from __future__ import unicode_literals
import re
-import warnings
-from django.core.exceptions import ImproperlyConfigured
from django.core.mail import send_mail
from django.core import validators
from django.db import models
@@ -14,7 +12,6 @@ from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from django.contrib import auth
-# UNUSABLE_PASSWORD is still imported here for backwards compatibility
from django.contrib.auth.hashers import (
check_password, make_password, is_password_usable)
from django.contrib.auth.signals import user_logged_in
@@ -32,10 +29,6 @@ def update_last_login(sender, user, **kwargs):
user_logged_in.connect(update_last_login)
-class SiteProfileNotAvailable(Exception):
- pass
-
-
class PermissionManager(models.Manager):
def get_by_natural_key(self, codename, app_label, model):
return self.get(
@@ -413,38 +406,6 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin):
"""
send_mail(subject, message, from_email, [self.email])
- def get_profile(self):
- """
- Returns site-specific profile for this user. Raises
- SiteProfileNotAvailable if this site does not allow profiles.
- """
- warnings.warn("The use of AUTH_PROFILE_MODULE to define user profiles has been deprecated.",
- DeprecationWarning, stacklevel=2)
- if not hasattr(self, '_profile_cache'):
- from django.conf import settings
- if not getattr(settings, 'AUTH_PROFILE_MODULE', False):
- raise SiteProfileNotAvailable(
- 'You need to set AUTH_PROFILE_MODULE in your project '
- 'settings')
- try:
- app_label, model_name = settings.AUTH_PROFILE_MODULE.split('.')
- except ValueError:
- raise SiteProfileNotAvailable(
- 'app_label and model_name should be separated by a dot in '
- 'the AUTH_PROFILE_MODULE setting')
- try:
- model = models.get_model(app_label, model_name)
- if model is None:
- raise SiteProfileNotAvailable(
- 'Unable to load the profile model, check '
- 'AUTH_PROFILE_MODULE in your project settings')
- self._profile_cache = model._default_manager.using(
- self._state.db).get(user__id__exact=self.id)
- self._profile_cache.user = self
- except (ImportError, ImproperlyConfigured):
- raise SiteProfileNotAvailable
- return self._profile_cache
-
class User(AbstractUser):
"""
diff --git a/django/contrib/auth/tests/test_hashers.py b/django/contrib/auth/tests/test_hashers.py
index 9b7811a335..8e8119b741 100644
--- a/django/contrib/auth/tests/test_hashers.py
+++ b/django/contrib/auth/tests/test_hashers.py
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
+import unittest
+from unittest import skipUnless
+
from django.conf.global_settings import PASSWORD_HASHERS as default_hashers
from django.contrib.auth.hashers import (is_password_usable, BasePasswordHasher,
check_password, make_password, PBKDF2PasswordHasher, load_hashers, PBKDF2SHA1PasswordHasher,
get_hasher, identify_hasher, UNUSABLE_PASSWORD_PREFIX, UNUSABLE_PASSWORD_SUFFIX_LENGTH)
from django.utils import six
-from django.utils import unittest
-from django.utils.unittest import skipUnless
try:
diff --git a/django/contrib/auth/tests/test_models.py b/django/contrib/auth/tests/test_models.py
index b0a4559b42..fa20775a8d 100644
--- a/django/contrib/auth/tests/test_models.py
+++ b/django/contrib/auth/tests/test_models.py
@@ -1,46 +1,9 @@
-import warnings
-
-from django.conf import settings
from django.contrib.auth import get_user_model
-from django.contrib.auth.models import (Group, User, SiteProfileNotAvailable,
- UserManager)
+from django.contrib.auth.models import Group, User, UserManager
from django.contrib.auth.tests.utils import skipIfCustomUser
from django.db.models.signals import post_save
from django.test import TestCase
from django.test.utils import override_settings
-from django.utils import six
-
-
-@skipIfCustomUser
-@override_settings(USE_TZ=False, AUTH_PROFILE_MODULE='')
-class ProfileTestCase(TestCase):
-
- def test_site_profile_not_available(self):
- user = User.objects.create(username='testclient')
-
- # calling get_profile without AUTH_PROFILE_MODULE set
- del settings.AUTH_PROFILE_MODULE
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- with six.assertRaisesRegex(self, SiteProfileNotAvailable,
- "You need to set AUTH_PROFILE_MODULE in your project"):
- user.get_profile()
-
- # Bad syntax in AUTH_PROFILE_MODULE:
- settings.AUTH_PROFILE_MODULE = 'foobar'
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- with six.assertRaisesRegex(self, SiteProfileNotAvailable,
- "app_label and model_name should be separated by a dot"):
- user.get_profile()
-
- # module that doesn't exist
- settings.AUTH_PROFILE_MODULE = 'foo.bar'
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- with six.assertRaisesRegex(self, SiteProfileNotAvailable,
- "Unable to load the profile model"):
- user.get_profile()
@skipIfCustomUser
diff --git a/django/contrib/auth/tests/test_tokens.py b/django/contrib/auth/tests/test_tokens.py
index e8aeb46326..7afafc3e94 100644
--- a/django/contrib/auth/tests/test_tokens.py
+++ b/django/contrib/auth/tests/test_tokens.py
@@ -1,12 +1,12 @@
-import sys
from datetime import date, timedelta
+import sys
+import unittest
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.contrib.auth.tests.utils import skipIfCustomUser
from django.test import TestCase
-from django.utils import unittest
@skipIfCustomUser
diff --git a/django/contrib/auth/tests/test_views.py b/django/contrib/auth/tests/test_views.py
index ba06a6af4d..b939dff058 100644
--- a/django/contrib/auth/tests/test_views.py
+++ b/django/contrib/auth/tests/test_views.py
@@ -13,7 +13,7 @@ from django.core import mail
from django.core.urlresolvers import reverse, NoReverseMatch
from django.http import QueryDict, HttpRequest
from django.utils.encoding import force_text
-from django.utils.http import int_to_base36, urlsafe_base64_decode, urlquote
+from django.utils.http import urlquote
from django.utils._os import upath
from django.test import TestCase
from django.test.utils import override_settings, patch_logger
@@ -193,16 +193,6 @@ class PasswordResetTest(AuthViewsTestCase):
# redirect to a 'complete' page:
self.assertContains(response, "Please enter your new password")
- def test_confirm_valid_base36(self):
- # Remove in Django 1.7
- url, path = self._test_confirm_start()
- path_parts = path.strip("/").split("/")
- # construct an old style (base36) URL by converting the base64 ID
- path_parts[1] = int_to_base36(int(urlsafe_base64_decode(path_parts[1])))
- response = self.client.get("/%s/%s-%s/" % tuple(path_parts))
- # redirect to a 'complete' page:
- self.assertContains(response, "Please enter your new password")
-
def test_confirm_invalid(self):
url, path = self._test_confirm_start()
# Let's munge the token in the path, but keep the same length,
@@ -217,21 +207,11 @@ class PasswordResetTest(AuthViewsTestCase):
response = self.client.get('/reset/123456/1-1/')
self.assertContains(response, "The password reset link was invalid")
- def test_confirm_invalid_user_base36(self):
- # Remove in Django 1.7
- response = self.client.get('/reset/123456-1-1/')
- self.assertContains(response, "The password reset link was invalid")
-
def test_confirm_overflow_user(self):
# Ensure that we get a 200 response for a base36 user id that overflows int
response = self.client.get('/reset/zzzzzzzzzzzzz/1-1/')
self.assertContains(response, "The password reset link was invalid")
- def test_confirm_overflow_user_base36(self):
- # Remove in Django 1.7
- response = self.client.get('/reset/zzzzzzzzzzzzz-1-1/')
- self.assertContains(response, "The password reset link was invalid")
-
def test_confirm_invalid_post(self):
# Same as test_confirm_invalid, but trying
# to do a POST instead.
diff --git a/django/contrib/auth/tests/utils.py b/django/contrib/auth/tests/utils.py
index 6bb3d9994f..09b34156b5 100644
--- a/django/contrib/auth/tests/utils.py
+++ b/django/contrib/auth/tests/utils.py
@@ -1,5 +1,6 @@
+from unittest import skipIf
+
from django.conf import settings
-from django.utils.unittest import skipIf
def skipIfCustomUser(test_func):
diff --git a/django/contrib/auth/urls.py b/django/contrib/auth/urls.py
index 801d133437..85b8b2869d 100644
--- a/django/contrib/auth/urls.py
+++ b/django/contrib/auth/urls.py
@@ -12,9 +12,6 @@ urlpatterns = patterns('',
url(r'^password_change/done/$', 'django.contrib.auth.views.password_change_done', name='password_change_done'),
url(r'^password_reset/$', 'django.contrib.auth.views.password_reset', name='password_reset'),
url(r'^password_reset/done/$', 'django.contrib.auth.views.password_reset_done', name='password_reset_done'),
- # Support old style base36 password reset links; remove in Django 1.7
- url(r'^reset/(?P<uidb36>[0-9A-Za-z]{1,13})-(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
- 'django.contrib.auth.views.password_reset_confirm_uidb36'),
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
'django.contrib.auth.views.password_reset_confirm',
name='password_reset_confirm'),
diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py
index e9affb33cd..b731a2b3d1 100644
--- a/django/contrib/auth/views.py
+++ b/django/contrib/auth/views.py
@@ -228,15 +228,6 @@ def password_reset_confirm(request, uidb64=None, token=None,
return TemplateResponse(request, template_name, context,
current_app=current_app)
-def password_reset_confirm_uidb36(request, uidb36=None, **kwargs):
- # Support old password reset URLs that used base36 encoded user IDs.
- # Remove in Django 1.7
- try:
- uidb64 = force_text(urlsafe_base64_encode(force_bytes(base36_to_int(uidb36))))
- except ValueError:
- uidb64 = '1' # dummy invalid ID (incorrect padding for base64)
- return password_reset_confirm(request, uidb64=uidb64, **kwargs)
-
def password_reset_complete(request,
template_name='registration/password_reset_complete.html',
current_app=None, extra_context=None):
diff --git a/django/contrib/comments/__init__.py b/django/contrib/comments/__init__.py
index 007b77ad7b..0b3fcebc51 100644
--- a/django/contrib/comments/__init__.py
+++ b/django/contrib/comments/__init__.py
@@ -6,7 +6,7 @@ from django.contrib.comments.models import Comment
from django.contrib.comments.forms import CommentForm
from django.utils.importlib import import_module
-warnings.warn("django.contrib.comments is deprecated and will be removed before Django 1.8.", PendingDeprecationWarning)
+warnings.warn("django.contrib.comments is deprecated and will be removed before Django 1.8.", DeprecationWarning)
DEFAULT_COMMENTS_APP = 'django.contrib.comments'
diff --git a/django/contrib/comments/templatetags/comments.py b/django/contrib/comments/templatetags/comments.py
index d8eed76ad6..2b2cea5f20 100644
--- a/django/contrib/comments/templatetags/comments.py
+++ b/django/contrib/comments/templatetags/comments.py
@@ -12,7 +12,7 @@ register = template.Library()
class RenameBaseCommentNodeMethods(RenameMethodsBase):
renamed_methods = (
- ('get_query_set', 'get_queryset', PendingDeprecationWarning),
+ ('get_query_set', 'get_queryset', DeprecationWarning),
)
diff --git a/django/contrib/contenttypes/generic.py b/django/contrib/contenttypes/generic.py
index 26db4ab171..04d4894b8a 100644
--- a/django/contrib/contenttypes/generic.py
+++ b/django/contrib/contenttypes/generic.py
@@ -25,7 +25,7 @@ from django.utils.encoding import smart_text
class RenameGenericForeignKeyMethods(RenameMethodsBase):
renamed_methods = (
- ('get_prefetch_query_set', 'get_prefetch_queryset', PendingDeprecationWarning),
+ ('get_prefetch_query_set', 'get_prefetch_queryset', DeprecationWarning),
)
@@ -434,8 +434,8 @@ def generic_inlineformset_factory(model, form=ModelForm,
"""
Returns a ``GenericInlineFormSet`` for the given kwargs.
- You must provide ``ct_field`` and ``object_id`` if they different from the
- defaults ``content_type`` and ``object_id`` respectively.
+ You must provide ``ct_field`` and ``fk_field`` if they are different from
+ the defaults ``content_type`` and ``object_id`` respectively.
"""
opts = model._meta
# if there is no field called `ct_field` let the exception propagate
diff --git a/django/contrib/formtools/tests/tests.py b/django/contrib/formtools/tests/tests.py
index 58c59f4041..e1e6ab860b 100644
--- a/django/contrib/formtools/tests/tests.py
+++ b/django/contrib/formtools/tests/tests.py
@@ -3,6 +3,7 @@ from __future__ import unicode_literals
import datetime
import os
+import unittest
import warnings
from django import http
@@ -10,7 +11,6 @@ from django.contrib.formtools import preview, utils
from django.test import TestCase
from django.test.utils import override_settings
from django.utils._os import upath
-from django.utils import unittest
from django.contrib.formtools.tests.forms import *
diff --git a/django/contrib/gis/forms/fields.py b/django/contrib/gis/forms/fields.py
index 59e725926c..2fb8b545e0 100644
--- a/django/contrib/gis/forms/fields.py
+++ b/django/contrib/gis/forms/fields.py
@@ -1,7 +1,5 @@
from __future__ import unicode_literals
-import warnings
-
from django import forms
from django.utils import six
from django.utils.translation import ugettext_lazy as _
@@ -34,10 +32,6 @@ class GeometryField(forms.Field):
# defaults (e.g., allow None).
self.srid = kwargs.pop('srid', None)
self.geom_type = kwargs.pop('geom_type', self.geom_type)
- if 'null' in kwargs:
- kwargs.pop('null', True)
- warnings.warn("Passing 'null' keyword argument to GeometryField is deprecated.",
- DeprecationWarning, stacklevel=2)
super(GeometryField, self).__init__(**kwargs)
self.widget.attrs['geom_type'] = self.geom_type
diff --git a/django/contrib/gis/gdal/tests/test_driver.py b/django/contrib/gis/gdal/tests/test_driver.py
index c27302da72..af0ecf5dc8 100644
--- a/django/contrib/gis/gdal/tests/test_driver.py
+++ b/django/contrib/gis/gdal/tests/test_driver.py
@@ -1,6 +1,7 @@
+import unittest
+from unittest import skipUnless
+
from django.contrib.gis.gdal import HAS_GDAL
-from django.utils import unittest
-from django.utils.unittest import skipUnless
if HAS_GDAL:
from django.contrib.gis.gdal import Driver, OGRException
diff --git a/django/contrib/gis/gdal/tests/test_ds.py b/django/contrib/gis/gdal/tests/test_ds.py
index 3664f055f2..3ac2370fb7 100644
--- a/django/contrib/gis/gdal/tests/test_ds.py
+++ b/django/contrib/gis/gdal/tests/test_ds.py
@@ -1,9 +1,9 @@
import os
+import unittest
+from unittest import skipUnless
from django.contrib.gis.gdal import HAS_GDAL
from django.contrib.gis.geometry.test_data import get_ds_file, TestDS, TEST_DATA
-from django.utils import unittest
-from django.utils.unittest import skipUnless
if HAS_GDAL:
from django.contrib.gis.gdal import DataSource, Envelope, OGRGeometry, OGRException, OGRIndexError, GDAL_VERSION
diff --git a/django/contrib/gis/gdal/tests/test_envelope.py b/django/contrib/gis/gdal/tests/test_envelope.py
index 7518dc69aa..14258ff816 100644
--- a/django/contrib/gis/gdal/tests/test_envelope.py
+++ b/django/contrib/gis/gdal/tests/test_envelope.py
@@ -1,6 +1,7 @@
+import unittest
+from unittest import skipUnless
+
from django.contrib.gis.gdal import HAS_GDAL
-from django.utils import unittest
-from django.utils.unittest import skipUnless
if HAS_GDAL:
from django.contrib.gis.gdal import Envelope, OGRException
@@ -17,7 +18,7 @@ class EnvelopeTest(unittest.TestCase):
def setUp(self):
self.e = Envelope(0, 0, 5, 5)
-
+
def test01_init(self):
"Testing Envelope initilization."
e1 = Envelope((0, 0, 5, 5))
diff --git a/django/contrib/gis/gdal/tests/test_geom.py b/django/contrib/gis/gdal/tests/test_geom.py
index c048d2bb82..74b1e894e1 100644
--- a/django/contrib/gis/gdal/tests/test_geom.py
+++ b/django/contrib/gis/gdal/tests/test_geom.py
@@ -4,12 +4,12 @@ try:
from django.utils.six.moves import cPickle as pickle
except ImportError:
import pickle
+import unittest
+from unittest import skipUnless
from django.contrib.gis.gdal import HAS_GDAL
from django.contrib.gis.geometry.test_data import TestDataMixin
from django.utils.six.moves import xrange
-from django.utils import unittest
-from django.utils.unittest import skipUnless
if HAS_GDAL:
from django.contrib.gis.gdal import (OGRGeometry, OGRGeomType,
diff --git a/django/contrib/gis/gdal/tests/test_srs.py b/django/contrib/gis/gdal/tests/test_srs.py
index 363b597dae..cacff4be04 100644
--- a/django/contrib/gis/gdal/tests/test_srs.py
+++ b/django/contrib/gis/gdal/tests/test_srs.py
@@ -1,6 +1,7 @@
+import unittest
+from unittest import skipUnless
+
from django.contrib.gis.gdal import HAS_GDAL
-from django.utils import unittest
-from django.utils.unittest import skipUnless
if HAS_GDAL:
from django.contrib.gis.gdal import SpatialReference, CoordTransform, OGRException, SRSException
diff --git a/django/contrib/gis/geoip/tests.py b/django/contrib/gis/geoip/tests.py
index 3fa64bf6be..c49ffb5bf1 100644
--- a/django/contrib/gis/geoip/tests.py
+++ b/django/contrib/gis/geoip/tests.py
@@ -2,11 +2,12 @@
from __future__ import unicode_literals
import os
+import unittest
+from unittest import skipUnless
+
from django.conf import settings
from django.contrib.gis.geos import HAS_GEOS
from django.contrib.gis.geoip import HAS_GEOIP
-from django.utils import unittest
-from django.utils.unittest import skipUnless
from django.utils import six
diff --git a/django/contrib/gis/geos/tests/test_geos.py b/django/contrib/gis/geos/tests/test_geos.py
index c7fe5b2321..900a0adb40 100644
--- a/django/contrib/gis/geos/tests/test_geos.py
+++ b/django/contrib/gis/geos/tests/test_geos.py
@@ -3,6 +3,8 @@ from __future__ import unicode_literals
import ctypes
import json
import random
+import unittest
+from unittest import skipUnless
from binascii import a2b_hex, b2a_hex
from io import BytesIO
@@ -14,8 +16,6 @@ from django.contrib.gis.geometry.test_data import TestDataMixin
from django.utils.encoding import force_bytes
from django.utils import six
from django.utils.six.moves import xrange
-from django.utils import unittest
-from django.utils.unittest import skipUnless
from .. import HAS_GEOS
diff --git a/django/contrib/gis/geos/tests/test_geos_mutation.py b/django/contrib/gis/geos/tests/test_geos_mutation.py
index 40b708a0ef..337abb4d8b 100644
--- a/django/contrib/gis/geos/tests/test_geos_mutation.py
+++ b/django/contrib/gis/geos/tests/test_geos_mutation.py
@@ -2,8 +2,8 @@
# Modified from original contribution by Aryeh Leib Taurog, which was
# released under the New BSD license.
-from django.utils import unittest
-from django.utils.unittest import skipUnless
+import unittest
+from unittest import skipUnless
from .. import HAS_GEOS
diff --git a/django/contrib/gis/geos/tests/test_io.py b/django/contrib/gis/geos/tests/test_io.py
index 34eeaf95b9..2278be8a87 100644
--- a/django/contrib/gis/geos/tests/test_io.py
+++ b/django/contrib/gis/geos/tests/test_io.py
@@ -2,9 +2,9 @@ from __future__ import unicode_literals
import binascii
import unittest
+from unittest import skipUnless
from django.contrib.gis import memoryview
-from django.utils.unittest import skipUnless
from ..import HAS_GEOS
diff --git a/django/contrib/gis/geos/tests/test_mutable_list.py b/django/contrib/gis/geos/tests/test_mutable_list.py
index a4a56f2e5f..ae50a5f616 100644
--- a/django/contrib/gis/geos/tests/test_mutable_list.py
+++ b/django/contrib/gis/geos/tests/test_mutable_list.py
@@ -3,9 +3,11 @@
#
# Modified from original contribution by Aryeh Leib Taurog, which was
# released under the New BSD license.
+
+import unittest
+
from django.contrib.gis.geos.mutable_list import ListMixin
from django.utils import six
-from django.utils import unittest
class UserListA(ListMixin):
diff --git a/django/contrib/gis/tests/distapp/tests.py b/django/contrib/gis/tests/distapp/tests.py
index 2ed17a03bd..8915f01e50 100644
--- a/django/contrib/gis/tests/distapp/tests.py
+++ b/django/contrib/gis/tests/distapp/tests.py
@@ -1,5 +1,7 @@
from __future__ import absolute_import
+from unittest import skipUnless
+
from django.db import connection
from django.db.models import Q
from django.contrib.gis.geos import HAS_GEOS
@@ -8,7 +10,6 @@ from django.contrib.gis.tests.utils import (
HAS_SPATIAL_DB, mysql, oracle, postgis, spatialite, no_oracle, no_spatialite
)
from django.test import TestCase
-from django.utils.unittest import skipUnless
if HAS_GEOS and HAS_SPATIAL_DB:
from django.contrib.gis.geos import GEOSGeometry, LineString
diff --git a/django/contrib/gis/tests/geo3d/tests.py b/django/contrib/gis/tests/geo3d/tests.py
index df9f35690b..6c17003982 100644
--- a/django/contrib/gis/tests/geo3d/tests.py
+++ b/django/contrib/gis/tests/geo3d/tests.py
@@ -2,13 +2,13 @@ from __future__ import absolute_import, unicode_literals
import os
import re
+from unittest import skipUnless
from django.contrib.gis.gdal import HAS_GDAL
from django.contrib.gis.geos import HAS_GEOS
from django.contrib.gis.tests.utils import postgis
from django.test import TestCase
from django.utils._os import upath
-from django.utils.unittest import skipUnless
if HAS_GEOS:
from django.contrib.gis.db.models import Union, Extent3D
diff --git a/django/contrib/gis/tests/geoadmin/tests.py b/django/contrib/gis/tests/geoadmin/tests.py
index 15874758be..c34964a2da 100644
--- a/django/contrib/gis/tests/geoadmin/tests.py
+++ b/django/contrib/gis/tests/geoadmin/tests.py
@@ -1,9 +1,10 @@
from __future__ import absolute_import
+from unittest import skipUnless
+
from django.test import TestCase
from django.contrib.gis.geos import HAS_GEOS
from django.contrib.gis.tests.utils import HAS_SPATIAL_DB
-from django.utils.unittest import skipUnless
if HAS_GEOS and HAS_SPATIAL_DB:
from django.contrib.gis import admin
diff --git a/django/contrib/gis/tests/geoapp/test_feeds.py b/django/contrib/gis/tests/geoapp/test_feeds.py
index 778cadc9d4..b2953b4a70 100644
--- a/django/contrib/gis/tests/geoapp/test_feeds.py
+++ b/django/contrib/gis/tests/geoapp/test_feeds.py
@@ -1,5 +1,6 @@
from __future__ import absolute_import
+from unittest import skipUnless
from xml.dom import minidom
from django.conf import settings
@@ -7,7 +8,6 @@ from django.contrib.sites.models import Site
from django.contrib.gis.geos import HAS_GEOS
from django.contrib.gis.tests.utils import HAS_SPATIAL_DB
from django.test import TestCase
-from django.utils.unittest import skipUnless
if HAS_GEOS:
from .models import City
diff --git a/django/contrib/gis/tests/geoapp/test_regress.py b/django/contrib/gis/tests/geoapp/test_regress.py
index 43dbcfd852..2ffbaec9a9 100644
--- a/django/contrib/gis/tests/geoapp/test_regress.py
+++ b/django/contrib/gis/tests/geoapp/test_regress.py
@@ -2,6 +2,7 @@
from __future__ import absolute_import, unicode_literals
from datetime import datetime
+from unittest import skipUnless
from django.contrib.gis.geos import HAS_GEOS
from django.contrib.gis.tests.utils import no_mysql, no_spatialite
@@ -9,7 +10,6 @@ from django.contrib.gis.shortcuts import render_to_kmz
from django.contrib.gis.tests.utils import HAS_SPATIAL_DB
from django.db.models import Count, Min
from django.test import TestCase
-from django.utils.unittest import skipUnless
if HAS_GEOS:
from .models import City, PennsylvaniaCity, State, Truth
diff --git a/django/contrib/gis/tests/geoapp/test_sitemaps.py b/django/contrib/gis/tests/geoapp/test_sitemaps.py
index 337b4b75c6..facd94c247 100644
--- a/django/contrib/gis/tests/geoapp/test_sitemaps.py
+++ b/django/contrib/gis/tests/geoapp/test_sitemaps.py
@@ -1,6 +1,7 @@
from __future__ import absolute_import
from io import BytesIO
+from unittest import skipUnless
from xml.dom import minidom
import zipfile
@@ -9,7 +10,6 @@ from django.contrib.gis.geos import HAS_GEOS
from django.contrib.gis.tests.utils import HAS_SPATIAL_DB
from django.contrib.sites.models import Site
from django.test import TestCase
-from django.utils.unittest import skipUnless
if HAS_GEOS:
from .models import City, Country
diff --git a/django/contrib/gis/tests/geoapp/tests.py b/django/contrib/gis/tests/geoapp/tests.py
index cf6e316919..487f879674 100644
--- a/django/contrib/gis/tests/geoapp/tests.py
+++ b/django/contrib/gis/tests/geoapp/tests.py
@@ -1,6 +1,8 @@
from __future__ import absolute_import
import re
+import unittest
+from unittest import skipUnless
from django.db import connection
from django.contrib.gis import gdal
@@ -9,8 +11,7 @@ from django.contrib.gis.tests.utils import (
no_mysql, no_oracle, no_spatialite,
mysql, oracle, postgis, spatialite)
from django.test import TestCase
-from django.utils import six, unittest
-from django.utils.unittest import skipUnless
+from django.utils import six
if HAS_GEOS:
from django.contrib.gis.geos import (fromstr, GEOSGeometry,
diff --git a/django/contrib/gis/tests/geogapp/tests.py b/django/contrib/gis/tests/geogapp/tests.py
index ed54999f90..2a60f623fa 100644
--- a/django/contrib/gis/tests/geogapp/tests.py
+++ b/django/contrib/gis/tests/geogapp/tests.py
@@ -4,6 +4,7 @@ Tests for geography support in PostGIS 1.5+
from __future__ import absolute_import
import os
+from unittest import skipUnless
from django.contrib.gis.gdal import HAS_GDAL
from django.contrib.gis.geos import HAS_GEOS
@@ -11,7 +12,6 @@ from django.contrib.gis.measure import D
from django.contrib.gis.tests.utils import postgis
from django.test import TestCase
from django.utils._os import upath
-from django.utils.unittest import skipUnless
if HAS_GEOS:
from .models import City, County, Zipcode
diff --git a/django/contrib/gis/tests/inspectapp/tests.py b/django/contrib/gis/tests/inspectapp/tests.py
index 668b87ba86..34dab1ab7d 100644
--- a/django/contrib/gis/tests/inspectapp/tests.py
+++ b/django/contrib/gis/tests/inspectapp/tests.py
@@ -1,13 +1,13 @@
from __future__ import absolute_import
import os
+from unittest import skipUnless
from django.db import connections
from django.test import TestCase
from django.contrib.gis.gdal import HAS_GDAL
from django.contrib.gis.geometry.test_data import TEST_DATA
from django.contrib.gis.tests.utils import HAS_SPATIAL_DB
-from django.utils.unittest import skipUnless
if HAS_GDAL:
from django.contrib.gis.gdal import Driver
diff --git a/django/contrib/gis/tests/layermap/tests.py b/django/contrib/gis/tests/layermap/tests.py
index 8379311a2b..c4c27b353e 100644
--- a/django/contrib/gis/tests/layermap/tests.py
+++ b/django/contrib/gis/tests/layermap/tests.py
@@ -1,17 +1,17 @@
# coding: utf-8
from __future__ import absolute_import, unicode_literals
-import os
from copy import copy
from decimal import Decimal
+import os
+import unittest
+from unittest import skipUnless
from django.contrib.gis.gdal import HAS_GDAL
from django.contrib.gis.tests.utils import HAS_SPATIAL_DB, mysql
from django.db import router
from django.conf import settings
from django.test import TestCase
-from django.utils import unittest
-from django.utils.unittest import skipUnless
from django.utils._os import upath
if HAS_GDAL:
diff --git a/django/contrib/gis/tests/relatedapp/tests.py b/django/contrib/gis/tests/relatedapp/tests.py
index d93adbcd4c..653bda8aaf 100644
--- a/django/contrib/gis/tests/relatedapp/tests.py
+++ b/django/contrib/gis/tests/relatedapp/tests.py
@@ -1,9 +1,10 @@
from __future__ import absolute_import
+from unittest import skipUnless
+
from django.contrib.gis.geos import HAS_GEOS
from django.contrib.gis.tests.utils import HAS_SPATIAL_DB, mysql, oracle, no_mysql, no_oracle, no_spatialite
from django.test import TestCase
-from django.utils.unittest import skipUnless
if HAS_GEOS:
from django.contrib.gis.db.models import Collect, Count, Extent, F, Union
diff --git a/django/contrib/gis/tests/test_geoforms.py b/django/contrib/gis/tests/test_geoforms.py
index 402d9b944b..b04bdea71d 100644
--- a/django/contrib/gis/tests/test_geoforms.py
+++ b/django/contrib/gis/tests/test_geoforms.py
@@ -1,15 +1,16 @@
+from unittest import skipUnless
+
from django.forms import ValidationError
from django.contrib.gis.gdal import HAS_GDAL
from django.contrib.gis.tests.utils import HAS_SPATIALREFSYS
from django.test import SimpleTestCase
from django.utils import six
-from django.utils.unittest import skipUnless
-
if HAS_SPATIALREFSYS:
from django.contrib.gis import forms
from django.contrib.gis.geos import GEOSGeometry
+
@skipUnless(HAS_GDAL and HAS_SPATIALREFSYS, "GeometryFieldTest needs gdal support and a spatial database")
class GeometryFieldTest(SimpleTestCase):
@@ -143,7 +144,7 @@ class SpecializedFieldTest(SimpleTestCase):
def assertTextarea(self, geom, rendered):
"""Makes sure the wkt and a textarea are in the content"""
-
+
self.assertIn('<textarea ', rendered)
self.assertIn('required', rendered)
self.assertIn(geom.wkt, rendered)
diff --git a/django/contrib/gis/tests/test_measure.py b/django/contrib/gis/tests/test_measure.py
index 0428704d6c..8ce37994eb 100644
--- a/django/contrib/gis/tests/test_measure.py
+++ b/django/contrib/gis/tests/test_measure.py
@@ -3,8 +3,9 @@ Distance and Area objects to allow for sensible and convienient calculation
and conversions. Here are some tests.
"""
+import unittest
+
from django.contrib.gis.measure import Distance, Area, D, A
-from django.utils import unittest
class DistanceTest(unittest.TestCase):
diff --git a/django/contrib/gis/tests/test_spatialrefsys.py b/django/contrib/gis/tests/test_spatialrefsys.py
index f33883e9f1..8daa6acc23 100644
--- a/django/contrib/gis/tests/test_spatialrefsys.py
+++ b/django/contrib/gis/tests/test_spatialrefsys.py
@@ -1,8 +1,9 @@
+import unittest
+
from django.contrib.gis.gdal import HAS_GDAL
from django.contrib.gis.tests.utils import (no_mysql, oracle, postgis,
spatialite, HAS_SPATIALREFSYS, SpatialRefSys)
from django.utils import six
-from django.utils import unittest
test_srs = ({'srid' : 4326,
diff --git a/django/contrib/humanize/tests.py b/django/contrib/humanize/tests.py
index 54a60f8fd6..f1fcbf2bb3 100644
--- a/django/contrib/humanize/tests.py
+++ b/django/contrib/humanize/tests.py
@@ -1,6 +1,7 @@
from __future__ import unicode_literals
import datetime
from decimal import Decimal
+from unittest import skipIf
try:
import pytz
@@ -17,7 +18,6 @@ from django.utils.timezone import utc
from django.utils import translation
from django.utils.translation import ugettext as _
from django.utils import tzinfo
-from django.utils.unittest import skipIf
from i18n import TransRealMixin
diff --git a/django/contrib/messages/tests/base.py b/django/contrib/messages/tests/base.py
index 0d689729aa..7011a5779a 100644
--- a/django/contrib/messages/tests/base.py
+++ b/django/contrib/messages/tests/base.py
@@ -1,3 +1,5 @@
+from unittest import skipIf
+
from django import http
from django.conf import settings, global_settings
from django.contrib.messages import constants, utils, get_level, set_level
@@ -7,7 +9,6 @@ from django.contrib.messages.storage.base import Message
from django.core.urlresolvers import reverse
from django.test.utils import override_settings
from django.utils.translation import ugettext_lazy
-from django.utils.unittest import skipIf
def skipUnlessAuthIsInstalled(func):
diff --git a/django/contrib/messages/tests/test_middleware.py b/django/contrib/messages/tests/test_middleware.py
index 5618c2d2b2..855f6b32a7 100644
--- a/django/contrib/messages/tests/test_middleware.py
+++ b/django/contrib/messages/tests/test_middleware.py
@@ -1,6 +1,7 @@
+import unittest
+
from django import http
from django.contrib.messages.middleware import MessageMiddleware
-from django.utils import unittest
class MiddlewareTest(unittest.TestCase):
diff --git a/django/contrib/sessions/middleware.py b/django/contrib/sessions/middleware.py
index 9f65255f47..8bc2d37dd3 100644
--- a/django/contrib/sessions/middleware.py
+++ b/django/contrib/sessions/middleware.py
@@ -6,10 +6,13 @@ from django.utils.http import cookie_date
from django.utils.importlib import import_module
class SessionMiddleware(object):
- def process_request(self, request):
+ def __init__(self):
engine = import_module(settings.SESSION_ENGINE)
+ self.SessionStore = engine.SessionStore
+
+ def process_request(self, request):
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
- request.session = engine.SessionStore(session_key)
+ request.session = self.SessionStore(session_key)
def process_response(self, request, response):
"""
diff --git a/django/contrib/sessions/tests.py b/django/contrib/sessions/tests.py
index cd8191a6a4..f2a35c544e 100644
--- a/django/contrib/sessions/tests.py
+++ b/django/contrib/sessions/tests.py
@@ -4,6 +4,7 @@ import os
import shutil
import string
import tempfile
+import unittest
import warnings
from django.conf import settings
@@ -22,7 +23,6 @@ from django.test import TestCase, RequestFactory
from django.test.utils import override_settings, patch_logger
from django.utils import six
from django.utils import timezone
-from django.utils import unittest
from django.contrib.sessions.exceptions import InvalidSessionKey
diff --git a/django/contrib/sitemaps/tests/test_flatpages.py b/django/contrib/sitemaps/tests/test_flatpages.py
index 930f24f22c..e034a457c2 100644
--- a/django/contrib/sitemaps/tests/test_flatpages.py
+++ b/django/contrib/sitemaps/tests/test_flatpages.py
@@ -1,7 +1,8 @@
from __future__ import unicode_literals
+from unittest import skipUnless
+
from django.conf import settings
-from django.utils.unittest import skipUnless
from .base import SitemapTestsBase
diff --git a/django/contrib/sitemaps/tests/test_http.py b/django/contrib/sitemaps/tests/test_http.py
index a99025e6e2..f68f345815 100644
--- a/django/contrib/sitemaps/tests/test_http.py
+++ b/django/contrib/sitemaps/tests/test_http.py
@@ -2,13 +2,13 @@ from __future__ import unicode_literals
import os
from datetime import date
+from unittest import skipUnless
from django.conf import settings
from django.contrib.sitemaps import Sitemap, GenericSitemap
from django.contrib.sites.models import Site
from django.core.exceptions import ImproperlyConfigured
from django.test.utils import override_settings
-from django.utils.unittest import skipUnless
from django.utils.formats import localize
from django.utils._os import upath
from django.utils.translation import activate, deactivate
diff --git a/django/contrib/sitemaps/views.py b/django/contrib/sitemaps/views.py
index 95bc7eac54..7a94fb355d 100644
--- a/django/contrib/sitemaps/views.py
+++ b/django/contrib/sitemaps/views.py
@@ -1,4 +1,3 @@
-import warnings
from functools import wraps
from django.contrib.sites.models import get_current_site
@@ -19,13 +18,7 @@ def x_robots_tag(func):
@x_robots_tag
def index(request, sitemaps,
template_name='sitemap_index.xml', content_type='application/xml',
- sitemap_url_name='django.contrib.sitemaps.views.sitemap',
- mimetype=None):
-
- if mimetype:
- warnings.warn("The mimetype keyword argument is deprecated, use "
- "content_type instead", DeprecationWarning, stacklevel=2)
- content_type = mimetype
+ sitemap_url_name='django.contrib.sitemaps.views.sitemap'):
req_protocol = 'https' if request.is_secure() else 'http'
req_site = get_current_site(request)
@@ -47,13 +40,7 @@ def index(request, sitemaps,
@x_robots_tag
def sitemap(request, sitemaps, section=None,
- template_name='sitemap.xml', content_type='application/xml',
- mimetype=None):
-
- if mimetype:
- warnings.warn("The mimetype keyword argument is deprecated, use "
- "content_type instead", DeprecationWarning, stacklevel=2)
- content_type = mimetype
+ template_name='sitemap.xml', content_type='application/xml'):
req_protocol = 'https' if request.is_secure() else 'http'
req_site = get_current_site(request)
diff --git a/django/core/files/storage.py b/django/core/files/storage.py
index 977b6a68a8..5d301a317c 100644
--- a/django/core/files/storage.py
+++ b/django/core/files/storage.py
@@ -231,6 +231,7 @@ class FileSystemStorage(Storage):
return name
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.
# Note that there is a race between os.path.exists and os.remove:
diff --git a/django/core/management/commands/cleanup.py b/django/core/management/commands/cleanup.py
deleted file mode 100644
index e158ebb541..0000000000
--- a/django/core/management/commands/cleanup.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import warnings
-
-from django.contrib.sessions.management.commands import clearsessions
-
-
-class Command(clearsessions.Command):
- def handle_noargs(self, **options):
- warnings.warn(
- "The `cleanup` command has been deprecated in favor of `clearsessions`.",
- DeprecationWarning)
- super(Command, self).handle_noargs(**options)
diff --git a/django/db/__init__.py b/django/db/__init__.py
index 2421ddeab8..0d7fbe2a34 100644
--- a/django/db/__init__.py
+++ b/django/db/__init__.py
@@ -49,7 +49,7 @@ class DefaultBackendProxy(object):
@cached_property
def _backend(self):
warnings.warn("Accessing django.db.backend is deprecated.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
return load_backend(connections[DEFAULT_DB_ALIAS].settings_dict['ENGINE'])
def __getattr__(self, item):
@@ -66,7 +66,7 @@ backend = DefaultBackendProxy()
def close_connection(**kwargs):
warnings.warn(
"close_connection is superseded by close_old_connections.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
# Avoid circular imports
from django.db import transaction
for conn in connections:
diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index 26ca9a7fa1..451cf4baf1 100644
--- a/django/db/backends/__init__.py
+++ b/django/db/backends/__init__.py
@@ -204,7 +204,7 @@ class BaseDatabaseWrapper(object):
def _savepoint_allowed(self):
# Savepoints cannot be created outside a transaction
- return self.features.uses_savepoints and not self.autocommit
+ return self.features.uses_savepoints and not self.get_autocommit()
##### Generic savepoint management methods #####
@@ -279,15 +279,13 @@ class BaseDatabaseWrapper(object):
"""
self.validate_no_atomic_block()
- self.ensure_connection()
-
self.transaction_state.append(managed)
if not managed and self.is_dirty() and not forced:
self.commit()
self.set_clean()
- if managed == self.autocommit:
+ if managed == self.get_autocommit():
self.set_autocommit(not managed)
def leave_transaction_management(self):
@@ -298,8 +296,6 @@ class BaseDatabaseWrapper(object):
"""
self.validate_no_atomic_block()
- self.ensure_connection()
-
if self.transaction_state:
del self.transaction_state[-1]
else:
@@ -313,14 +309,21 @@ class BaseDatabaseWrapper(object):
if self._dirty:
self.rollback()
- if managed == self.autocommit:
+ if managed == self.get_autocommit():
self.set_autocommit(not managed)
raise TransactionManagementError(
"Transaction managed block ended with pending COMMIT/ROLLBACK")
- if managed == self.autocommit:
+ if managed == self.get_autocommit():
self.set_autocommit(not managed)
+ def get_autocommit(self):
+ """
+ Check the autocommit state.
+ """
+ self.ensure_connection()
+ return self.autocommit
+
def set_autocommit(self, autocommit):
"""
Enable or disable autocommit.
@@ -330,13 +333,22 @@ class BaseDatabaseWrapper(object):
self._set_autocommit(autocommit)
self.autocommit = autocommit
+ def get_rollback(self):
+ """
+ Get the "needs rollback" flag -- for *advanced use* only.
+ """
+ if not self.in_atomic_block:
+ raise TransactionManagementError(
+ "The rollback flag doesn't work outside of an 'atomic' block.")
+ return self.needs_rollback
+
def set_rollback(self, rollback):
"""
Set or unset the "needs rollback" flag -- for *advanced use* only.
"""
if not self.in_atomic_block:
raise TransactionManagementError(
- "needs_rollback doesn't work outside of an 'atomic' block.")
+ "The rollback flag doesn't work outside of an 'atomic' block.")
self.needs_rollback = rollback
def validate_no_atomic_block(self):
@@ -370,7 +382,7 @@ class BaseDatabaseWrapper(object):
to decide in a managed block of code to decide whether there are open
changes waiting for commit.
"""
- if not self.autocommit:
+ if not self.get_autocommit():
self._dirty = True
def set_clean(self):
@@ -436,7 +448,7 @@ class BaseDatabaseWrapper(object):
if self.connection is not None:
# If the application didn't restore the original autocommit setting,
# don't take chances, drop the connection.
- if self.autocommit != self.settings_dict['AUTOCOMMIT']:
+ if self.get_autocommit() != self.settings_dict['AUTOCOMMIT']:
self.close()
return
diff --git a/django/db/backends/creation.py b/django/db/backends/creation.py
index ef45cbeeff..2767fcb48d 100644
--- a/django/db/backends/creation.py
+++ b/django/db/backends/creation.py
@@ -468,7 +468,7 @@ class BaseDatabaseCreation(object):
"""
warnings.warn(
"set_autocommit was moved from BaseDatabaseCreation to "
- "BaseDatabaseWrapper.", PendingDeprecationWarning, stacklevel=2)
+ "BaseDatabaseWrapper.", DeprecationWarning, stacklevel=2)
return self.connection.set_autocommit(True)
def sql_table_creation_suffix(self):
diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
index 08b8106ddd..8a689f66ed 100644
--- a/django/db/backends/mysql/base.py
+++ b/django/db/backends/mysql/base.py
@@ -288,7 +288,7 @@ class DatabaseOperations(BaseDatabaseOperations):
# With MySQLdb, cursor objects have an (undocumented) "_last_executed"
# attribute where the exact query sent to the database is saved.
# See MySQLdb/cursors.py in the source distribution.
- return force_text(cursor._last_executed, errors='replace')
+ return force_text(getattr(cursor, '_last_executed', None), errors='replace')
def no_limit_value(self):
# 2**64 - 1, as recommended by the MySQL documentation
diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index 64da0a9f25..e330082108 100644
--- a/django/db/backends/sqlite3/base.py
+++ b/django/db/backends/sqlite3/base.py
@@ -79,14 +79,8 @@ Database.register_converter(str("decimal"), decoder(util.typecast_decimal))
Database.register_adapter(datetime.datetime, adapt_datetime_with_timezone_support)
Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal)
-if Database.version_info >= (2, 4, 1):
- # Starting in 2.4.1, the str type is not accepted anymore, therefore,
- # we convert all str objects to Unicode
- # As registering a adapter for a primitive type causes a small
- # slow-down, this adapter is only registered for sqlite3 versions
- # needing it (Python 2.6 and up).
- Database.register_adapter(str, lambda s: s.decode('utf-8'))
- Database.register_adapter(SafeBytes, lambda s: s.decode('utf-8'))
+Database.register_adapter(str, lambda s: s.decode('utf-8'))
+Database.register_adapter(SafeBytes, lambda s: s.decode('utf-8'))
class DatabaseFeatures(BaseDatabaseFeatures):
# SQLite cannot handle us only partially reading from a cursor's result set
diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py
index 0a913e908b..7663c8ab90 100644
--- a/django/db/models/fields/files.py
+++ b/django/db/models/fields/files.py
@@ -96,6 +96,8 @@ class FieldFile(File):
save.alters_data = True
def delete(self, save=True):
+ if not self:
+ return
# Only close the file if it's already open, which we know by the
# presence of self._file
if hasattr(self, '_file'):
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index 9f2e01e781..480c77ab77 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -89,7 +89,6 @@ def do_pending_lookups(sender, **kwargs):
signals.class_prepared.connect(do_pending_lookups)
-#HACK
class RelatedField(Field):
def db_type(self, connection):
'''By default related field will not have a column
@@ -142,8 +141,8 @@ class RelatedField(Field):
class RenameRelatedObjectDescriptorMethods(RenameMethodsBase):
renamed_methods = (
- ('get_query_set', 'get_queryset', PendingDeprecationWarning),
- ('get_prefetch_query_set', 'get_prefetch_queryset', PendingDeprecationWarning),
+ ('get_query_set', 'get_queryset', DeprecationWarning),
+ ('get_prefetch_query_set', 'get_prefetch_queryset', DeprecationWarning),
)
@@ -1166,7 +1165,7 @@ class ForeignKey(ForeignObject):
rel = self.rel
if self.rel.field_name:
kwargs['to_field'] = self.rel.field_name
- if isinstance(self.rel.to, basestring):
+ if isinstance(self.rel.to, six.string_types):
kwargs['to'] = self.rel.to
else:
kwargs['to'] = "%s.%s" % (self.rel.to._meta.app_label, self.rel.to._meta.object_name)
@@ -1367,9 +1366,7 @@ class ManyToManyField(RelatedField):
assert not to._meta.abstract, "%s cannot define a relation with abstract class %s" % (self.__class__.__name__, to._meta.object_name)
except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT
assert isinstance(to, six.string_types), "%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)
- # Python 2.6 and earlier require dictionary keys to be of str type,
- # not unicode and class names must be ASCII (in Python 2.x), so we
- # forcibly coerce it here (breaks early if there's a problem).
+ # 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)
kwargs['verbose_name'] = kwargs.get('verbose_name', None)
@@ -1397,7 +1394,7 @@ class ManyToManyField(RelatedField):
del kwargs['help_text']
# Rel needs more work.
rel = self.rel
- if isinstance(self.rel.to, basestring):
+ if isinstance(self.rel.to, six.string_types):
kwargs['to'] = self.rel.to
else:
kwargs['to'] = "%s.%s" % (self.rel.to._meta.app_label, self.rel.to._meta.object_name)
diff --git a/django/db/models/manager.py b/django/db/models/manager.py
index a1aa79f809..6817c9c8ee 100644
--- a/django/db/models/manager.py
+++ b/django/db/models/manager.py
@@ -50,8 +50,8 @@ signals.class_prepared.connect(ensure_default_manager)
class RenameManagerMethods(RenameMethodsBase):
renamed_methods = (
- ('get_query_set', 'get_queryset', PendingDeprecationWarning),
- ('get_prefetch_query_set', 'get_prefetch_queryset', PendingDeprecationWarning),
+ ('get_query_set', 'get_queryset', DeprecationWarning),
+ ('get_prefetch_query_set', 'get_prefetch_queryset', DeprecationWarning),
)
diff --git a/django/db/models/options.py b/django/db/models/options.py
index b173da9538..1cacbc776c 100644
--- a/django/db/models/options.py
+++ b/django/db/models/options.py
@@ -138,7 +138,7 @@ class Options(object):
"""
warnings.warn(
"Options.module_name has been deprecated in favor of model_name",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
return self.model_name
def _prepare(self, model):
@@ -429,7 +429,7 @@ class Options(object):
warnings.warn(
"`Options.get_add_permission` has been deprecated in favor "
"of `django.contrib.auth.get_permission_codename`.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
return 'add_%s' % self.model_name
def get_change_permission(self):
@@ -440,7 +440,7 @@ class Options(object):
warnings.warn(
"`Options.get_change_permission` has been deprecated in favor "
"of `django.contrib.auth.get_permission_codename`.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
return 'change_%s' % self.model_name
def get_delete_permission(self):
@@ -451,7 +451,7 @@ class Options(object):
warnings.warn(
"`Options.get_delete_permission` has been deprecated in favor "
"of `django.contrib.auth.get_permission_codename`.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
return 'delete_%s' % self.model_name
def get_all_related_objects(self, local_only=False, include_hidden=False,
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 27a87a3f65..34d8eaa6ff 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -5,7 +5,6 @@ The main QuerySet implementation. This provides the public API for the ORM.
import copy
import itertools
import sys
-import warnings
from django.conf import settings
from django.core import exceptions
@@ -648,10 +647,6 @@ class QuerySet(object):
If select_related(None) is called, the list is cleared.
"""
- if 'depth' in kwargs:
- warnings.warn('The "depth" keyword argument has been deprecated.\n'
- 'Use related field names instead.', DeprecationWarning, stacklevel=2)
- depth = kwargs.pop('depth', 0)
if kwargs:
raise TypeError('Unexpected keyword arguments to select_related: %s'
% (list(kwargs),))
@@ -659,13 +654,9 @@ class QuerySet(object):
if fields == (None,):
obj.query.select_related = False
elif fields:
- if depth:
- raise TypeError('Cannot pass both "depth" and fields to select_related()')
obj.query.add_select_related(fields)
else:
obj.query.select_related = True
- if depth:
- obj.query.max_depth = depth
return obj
def prefetch_related(self, *lookups):
diff --git a/django/db/transaction.py b/django/db/transaction.py
index 95b9ae165e..96be981e7b 100644
--- a/django/db/transaction.py
+++ b/django/db/transaction.py
@@ -101,19 +101,19 @@ def set_clean(using=None):
def is_managed(using=None):
warnings.warn("'is_managed' is deprecated.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
def managed(flag=True, using=None):
warnings.warn("'managed' no longer serves a purpose.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
def commit_unless_managed(using=None):
warnings.warn("'commit_unless_managed' is now a no-op.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
def rollback_unless_managed(using=None):
warnings.warn("'rollback_unless_managed' is now a no-op.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
###############
# Public APIs #
@@ -123,7 +123,7 @@ def get_autocommit(using=None):
"""
Get the autocommit status of the connection.
"""
- return get_connection(using).autocommit
+ return get_connection(using).get_autocommit()
def set_autocommit(autocommit, using=None):
"""
@@ -175,7 +175,7 @@ def get_rollback(using=None):
"""
Gets the "needs rollback" flag -- for *advanced use* only.
"""
- return get_connection(using).needs_rollback
+ return get_connection(using).get_rollback()
def set_rollback(rollback, using=None):
"""
@@ -229,15 +229,11 @@ class Atomic(object):
def __enter__(self):
connection = get_connection(self.using)
- # Ensure we have a connection to the database before testing
- # autocommit status.
- connection.ensure_connection()
-
if not connection.in_atomic_block:
# Reset state when entering an outermost atomic block.
connection.commit_on_exit = True
connection.needs_rollback = False
- if not connection.autocommit:
+ if not connection.get_autocommit():
# Some database adapters (namely sqlite3) don't handle
# transactions and savepoints properly when autocommit is off.
# Turning autocommit back on isn't an option; it would trigger
@@ -430,7 +426,7 @@ def autocommit(using=None):
your settings file and want the default behavior in some view functions.
"""
warnings.warn("autocommit is deprecated in favor of set_autocommit.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
def entering(using):
enter_transaction_management(managed=False, using=using)
@@ -448,7 +444,7 @@ def commit_on_success(using=None):
control in Web apps.
"""
warnings.warn("commit_on_success is deprecated in favor of atomic.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
def entering(using):
enter_transaction_management(using=using)
@@ -478,7 +474,7 @@ def commit_manually(using=None):
themselves.
"""
warnings.warn("commit_manually is deprecated in favor of set_autocommit.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
def entering(using):
enter_transaction_management(using=using)
@@ -500,7 +496,7 @@ def commit_on_success_unless_managed(using=None, savepoint=False):
legacy behavior.
"""
connection = get_connection(using)
- if connection.autocommit or connection.in_atomic_block:
+ if connection.get_autocommit() or connection.in_atomic_block:
return atomic(using, savepoint)
else:
def entering(using):
diff --git a/django/db/utils.py b/django/db/utils.py
index bd7e10d24c..36b89d9acf 100644
--- a/django/db/utils.py
+++ b/django/db/utils.py
@@ -85,12 +85,7 @@ class DatabaseErrorWrapper(object):
):
db_exc_type = getattr(self.wrapper.Database, dj_exc_type.__name__)
if issubclass(exc_type, db_exc_type):
- # Under Python 2.6, exc_value can still be a string.
- try:
- args = tuple(exc_value.args)
- except AttributeError:
- args = (exc_value,)
- dj_exc_value = dj_exc_type(*args)
+ dj_exc_value = dj_exc_type(*exc_value.args)
dj_exc_value.__cause__ = exc_value
# Only set the 'errors_occurred' flag for errors that may make
# the connection unusable.
@@ -174,7 +169,7 @@ class ConnectionHandler(object):
if settings.TRANSACTIONS_MANAGED:
warnings.warn(
"TRANSACTIONS_MANAGED is deprecated. Use AUTOCOMMIT instead.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
conn.setdefault('AUTOCOMMIT', False)
conn.setdefault('AUTOCOMMIT', True)
conn.setdefault('ENGINE', 'django.db.backends.dummy')
diff --git a/django/forms/forms.py b/django/forms/forms.py
index b25eeb30a4..6d59271d17 100644
--- a/django/forms/forms.py
+++ b/django/forms/forms.py
@@ -352,7 +352,7 @@ class BaseForm(object):
if hasattr(field.widget, '_has_changed'):
warnings.warn("The _has_changed method on widgets is deprecated,"
" define it at field level instead.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
if field.widget._has_changed(initial_value, data_value):
self._changed_data.append(name)
elif field._has_changed(initial_value, data_value):
diff --git a/django/forms/models.py b/django/forms/models.py
index 821f64199b..a0c3009d38 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -260,7 +260,7 @@ class ModelFormMetaclass(type):
warnings.warn("Creating a ModelForm without either the 'fields' attribute "
"or the 'exclude' attribute is deprecated - form %s "
"needs updating" % name,
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
if opts.fields == ALL_FIELDS:
# sentinel for fields_for_model to indicate "get the list of
@@ -513,7 +513,7 @@ def modelform_factory(model, form=ModelForm, fields=None, exclude=None,
getattr(Meta, 'exclude', None) is None):
warnings.warn("Calling modelform_factory without defining 'fields' or "
"'exclude' explicitly is deprecated",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
# Instatiate type(form) in order to use the same metaclass as form.
return type(form)(class_name, (form,), form_class_attrs)
@@ -796,7 +796,7 @@ def modelformset_factory(model, form=ModelForm, formfield_callback=None,
getattr(meta, 'exclude', exclude) is None):
warnings.warn("Calling modelformset_factory without defining 'fields' or "
"'exclude' explicitly is deprecated",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
form = modelform_factory(model, form=form, fields=fields, exclude=exclude,
formfield_callback=formfield_callback,
diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index 38d1b99b0d..a92e5a56ce 100644
--- a/django/forms/widgets.py
+++ b/django/forms/widgets.py
@@ -636,7 +636,7 @@ class RadioChoiceInput(ChoiceInput):
class RadioInput(RadioChoiceInput):
def __init__(self, *args, **kwargs):
msg = "RadioInput has been deprecated. Use RadioChoiceInput instead."
- warnings.warn(msg, PendingDeprecationWarning, stacklevel=2)
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
super(RadioInput, self).__init__(*args, **kwargs)
diff --git a/django/http/__init__.py b/django/http/__init__.py
index 46afa34ee7..be7b24b2e2 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -2,9 +2,9 @@ from django.http.cookie import SimpleCookie, parse_cookie
from django.http.request import (HttpRequest, QueryDict, UnreadablePostError,
build_request_repr)
from django.http.response import (HttpResponse, StreamingHttpResponse,
- CompatibleStreamingHttpResponse, HttpResponsePermanentRedirect,
- HttpResponseRedirect, HttpResponseNotModified, HttpResponseBadRequest,
- HttpResponseForbidden, HttpResponseNotFound, HttpResponseNotAllowed,
- HttpResponseGone, HttpResponseServerError, Http404, BadHeaderError)
+ HttpResponseRedirect, HttpResponsePermanentRedirect,
+ HttpResponseNotModified, HttpResponseBadRequest, HttpResponseForbidden,
+ HttpResponseNotFound, HttpResponseNotAllowed, HttpResponseGone,
+ HttpResponseServerError, Http404, BadHeaderError)
from django.http.utils import (fix_location_header, conditional_content_removal,
fix_IE_for_attach, fix_IE_for_vary)
diff --git a/django/http/response.py b/django/http/response.py
index 784f21174e..1f0849c0bf 100644
--- a/django/http/response.py
+++ b/django/http/response.py
@@ -2,7 +2,6 @@ from __future__ import absolute_import, unicode_literals
import datetime
import time
-import warnings
from email.header import Header
try:
from urllib.parse import urlparse
@@ -98,7 +97,7 @@ class HttpResponseBase(six.Iterator):
status_code = 200
reason_phrase = None # Use default reason phrase for status code.
- def __init__(self, content_type=None, status=None, reason=None, mimetype=None):
+ def __init__(self, content_type=None, status=None, reason=None):
# _headers is a mapping of the lower-case name to the original case of
# the header (required for working with legacy systems) and the header
# value. Both the name of the header and its value are ASCII strings.
@@ -108,11 +107,6 @@ class HttpResponseBase(six.Iterator):
# This parameter is set by the handler. It's necessary to preserve the
# historical behavior of request_finished.
self._handler_class = None
- if mimetype:
- warnings.warn("Using mimetype keyword argument is deprecated, use"
- " content_type instead",
- DeprecationWarning, stacklevel=2)
- content_type = mimetype
if not content_type:
content_type = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE,
self._charset)
@@ -337,53 +331,27 @@ class HttpResponse(HttpResponseBase):
else:
__str__ = serialize
- def _consume_content(self):
- # If the response was instantiated with an iterator, when its content
- # is accessed, the iterator is going be exhausted and the content
- # loaded in memory. At this point, it's better to abandon the original
- # iterator and save the content for later reuse. This is a temporary
- # solution. See the comment in __iter__ below for the long term plan.
- if self._base_content_is_iter:
- self.content = b''.join(self.make_bytes(e) for e in self._container)
-
@property
def content(self):
- self._consume_content()
return b''.join(self.make_bytes(e) for e in self._container)
@content.setter
def content(self, value):
if hasattr(value, '__iter__') and not isinstance(value, (bytes, six.string_types)):
- self._container = value
- self._base_content_is_iter = True
if hasattr(value, 'close'):
self._closable_objects.append(value)
- else:
- self._container = [value]
- self._base_content_is_iter = False
+ value = b''.join(self.make_bytes(e) for e in value)
+ self._container = [value]
def __iter__(self):
- # Raise a deprecation warning only if the content wasn't consumed yet,
- # because the response may be intended to be streamed.
- # Once the deprecation completes, iterators should be consumed upon
- # assignment rather than upon access. The _consume_content method
- # should be removed. See #6527.
- if self._base_content_is_iter:
- warnings.warn(
- 'Creating streaming responses with `HttpResponse` is '
- 'deprecated. Use `StreamingHttpResponse` instead '
- 'if you need the streaming behavior.',
- DeprecationWarning, stacklevel=2)
if not hasattr(self, '_iterator'):
self._iterator = iter(self._container)
return self
def write(self, content):
- self._consume_content()
self._container.append(content)
def tell(self):
- self._consume_content()
return len(self.content)
@@ -421,35 +389,6 @@ class StreamingHttpResponse(HttpResponseBase):
self._closable_objects.append(value)
-class CompatibleStreamingHttpResponse(StreamingHttpResponse):
- """
- This class maintains compatibility with middleware that doesn't know how
- to handle the content of a streaming response by exposing a `content`
- attribute that will consume and cache the content iterator when accessed.
-
- These responses will stream only if no middleware attempts to access the
- `content` attribute. Otherwise, they will behave like a regular response,
- and raise a `DeprecationWarning`.
- """
- @property
- def content(self):
- warnings.warn(
- 'Accessing the `content` attribute on a streaming response is '
- 'deprecated. Use the `streaming_content` attribute instead.',
- DeprecationWarning, stacklevel=2)
- content = b''.join(self)
- self.streaming_content = [content]
- return content
-
- @content.setter
- def content(self, content):
- warnings.warn(
- 'Accessing the `content` attribute on a streaming response is '
- 'deprecated. Use the `streaming_content` attribute instead.',
- DeprecationWarning, stacklevel=2)
- self.streaming_content = [content]
-
-
class HttpResponseRedirectBase(HttpResponse):
allowed_schemes = ['http', 'https', 'ftp']
@@ -483,7 +422,6 @@ class HttpResponseNotModified(HttpResponse):
if value:
raise AttributeError("You cannot set content to a 304 (Not Modified) response")
self._container = []
- self._base_content_is_iter = False
class HttpResponseBadRequest(HttpResponse):
diff --git a/django/middleware/cache.py b/django/middleware/cache.py
index e13a8c3918..55b61358ea 100644
--- a/django/middleware/cache.py
+++ b/django/middleware/cache.py
@@ -199,7 +199,7 @@ class CacheMiddleware(UpdateCacheMiddleware, FetchFromCacheMiddleware):
if self.cache_anonymous_only:
msg = "CACHE_MIDDLEWARE_ANONYMOUS_ONLY has been deprecated and will be removed in Django 1.8."
- warnings.warn(msg, PendingDeprecationWarning, stacklevel=1)
+ warnings.warn(msg, DeprecationWarning, stacklevel=1)
self.cache = get_cache(self.cache_alias, **cache_kwargs)
self.cache_timeout = self.cache.default_timeout
diff --git a/django/middleware/common.py b/django/middleware/common.py
index 2c76c47756..8f5923ac4a 100644
--- a/django/middleware/common.py
+++ b/django/middleware/common.py
@@ -110,7 +110,7 @@ class CommonMiddleware(object):
if settings.SEND_BROKEN_LINK_EMAILS:
warnings.warn("SEND_BROKEN_LINK_EMAILS is deprecated. "
"Use BrokenLinkEmailsMiddleware instead.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
BrokenLinkEmailsMiddleware().process_response(request, response)
if settings.USE_ETAGS:
diff --git a/django/middleware/doc.py b/django/middleware/doc.py
index 1af7b6150a..a2f00b6ded 100644
--- a/django/middleware/doc.py
+++ b/django/middleware/doc.py
@@ -1,6 +1,6 @@
"""XViewMiddleware has been moved to django.contrib.admindocs.middleware."""
import warnings
-warnings.warn(__doc__, PendingDeprecationWarning, stacklevel=2)
+warnings.warn(__doc__, DeprecationWarning, stacklevel=2)
from django.contrib.admindocs.middleware import XViewMiddleware
diff --git a/django/middleware/transaction.py b/django/middleware/transaction.py
index 95cc9a21f3..510176758a 100644
--- a/django/middleware/transaction.py
+++ b/django/middleware/transaction.py
@@ -14,7 +14,7 @@ class TransactionMiddleware(object):
def __init__(self):
warnings.warn(
"TransactionMiddleware is deprecated in favor of ATOMIC_REQUESTS.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
if connection.settings_dict['ATOMIC_REQUESTS']:
raise MiddlewareNotUsed
diff --git a/django/shortcuts/__init__.py b/django/shortcuts/__init__.py
index 21bd7a06d2..b096efdb44 100644
--- a/django/shortcuts/__init__.py
+++ b/django/shortcuts/__init__.py
@@ -3,8 +3,6 @@ This module collects helper functions and classes that "span" multiple levels
of MVC. In other words, these functions/classes introduce controlled coupling
for convenience's sake.
"""
-import warnings
-
from django.template import loader, RequestContext
from django.http import HttpResponse, Http404
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
@@ -20,12 +18,6 @@ def render_to_response(*args, **kwargs):
"""
httpresponse_kwargs = {'content_type': kwargs.pop('content_type', None)}
- mimetype = kwargs.pop('mimetype', None)
- if mimetype:
- warnings.warn("The mimetype keyword argument is deprecated, use "
- "content_type instead", DeprecationWarning, stacklevel=2)
- httpresponse_kwargs['content_type'] = mimetype
-
return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
def render(request, *args, **kwargs):
diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
index 959de3dea1..5b2a1b9501 100644
--- a/django/template/defaulttags.py
+++ b/django/template/defaulttags.py
@@ -568,7 +568,7 @@ def cycle(parser, token, escape=False):
"'The `cycle` template tag is changing to escape its arguments; "
"the non-autoescaping version is deprecated. Load it "
"from the `future` tag library to start using the new behavior.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
# Note: This returns the exact same node on each {% cycle name %} call;
# that is, the node object returned from {% cycle a b c as name %} and the
@@ -712,7 +712,7 @@ def firstof(parser, token, escape=False):
"'The `firstof` template tag is changing to escape its arguments; "
"the non-autoescaping version is deprecated. Load it "
"from the `future` tag library to start using the new behavior.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
bits = token.split_contents()[1:]
if len(bits) < 1:
diff --git a/django/template/response.py b/django/template/response.py
index 3b3b41331a..aa4f12af44 100644
--- a/django/template/response.py
+++ b/django/template/response.py
@@ -10,8 +10,7 @@ class ContentNotRenderedError(Exception):
class SimpleTemplateResponse(HttpResponse):
rendering_attrs = ['template_name', 'context_data', '_post_render_callbacks']
- def __init__(self, template, context=None, content_type=None, status=None,
- mimetype=None):
+ def __init__(self, template, context=None, content_type=None, status=None):
# It would seem obvious to call these next two members 'template' and
# 'context', but those names are reserved as part of the test Client
# API. To avoid the name collision, we use tricky-to-debug problems
@@ -23,8 +22,7 @@ class SimpleTemplateResponse(HttpResponse):
# content argument doesn't make sense here because it will be replaced
# with rendered template so we always pass empty string in order to
# prevent errors and provide shorter signature.
- super(SimpleTemplateResponse, self).__init__('', content_type, status,
- mimetype)
+ super(SimpleTemplateResponse, self).__init__('', content_type, status)
# _is_rendered tracks whether the template and context has been baked
# into a final response.
@@ -139,7 +137,7 @@ class TemplateResponse(SimpleTemplateResponse):
['_request', '_current_app']
def __init__(self, request, template, context=None, content_type=None,
- status=None, mimetype=None, current_app=None):
+ status=None, current_app=None):
# self.request gets over-written by django.test.client.Client - and
# unlike context_data and template_name the _request should not
# be considered part of the public API.
@@ -148,7 +146,7 @@ class TemplateResponse(SimpleTemplateResponse):
# having to avoid needing to create the RequestContext directly
self._current_app = current_app
super(TemplateResponse, self).__init__(
- template, context, content_type, status, mimetype)
+ template, context, content_type, status)
def resolve_context(self, context):
"""Convert context data into a full RequestContext object
diff --git a/django/test/_doctest.py b/django/test/_doctest.py
index 5381cff2f0..50d772cfad 100644
--- a/django/test/_doctest.py
+++ b/django/test/_doctest.py
@@ -54,7 +54,7 @@ import warnings
warnings.warn(
"The django.test._doctest module is deprecated; "
"use the doctest module from the Python standard library instead.",
- PendingDeprecationWarning)
+ DeprecationWarning)
__docformat__ = 'reStructuredText en'
diff --git a/django/test/runner.py b/django/test/runner.py
index 4d0517a4b4..6897906098 100644
--- a/django/test/runner.py
+++ b/django/test/runner.py
@@ -1,12 +1,12 @@
import os
from optparse import make_option
+import unittest
+from unittest import TestSuite, defaultTestLoader
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.test import TestCase
from django.test.utils import setup_test_environment, teardown_test_environment
-from django.utils import unittest
-from django.utils.unittest import TestSuite, defaultTestLoader
class DiscoverRunner(object):
diff --git a/django/test/simple.py b/django/test/simple.py
index f28b8a2830..019eff2421 100644
--- a/django/test/simple.py
+++ b/django/test/simple.py
@@ -12,6 +12,8 @@ from django.db.models import get_app, get_apps
from django.test import _doctest as doctest
from django.test import runner
from django.test.utils import compare_xml, strip_quotes
+# django.utils.unittest is deprecated, but so is django.test.simple,
+# and the latter will be removed before the former.
from django.utils import unittest
from django.utils.importlib import import_module
from django.utils.module_loading import module_has_submodule
@@ -21,7 +23,7 @@ __all__ = ('DjangoTestSuiteRunner',)
warnings.warn(
"The django.test.simple module and DjangoTestSuiteRunner are deprecated; "
"use django.test.runner.DiscoverRunner instead.",
- PendingDeprecationWarning)
+ DeprecationWarning)
# The module name for tests outside models.py
TEST_MODULE = 'tests'
diff --git a/django/test/testcases.py b/django/test/testcases.py
index 984d21ce18..c5299bdabc 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -8,14 +8,16 @@ import json
import os
import re
import sys
+import select
+import socket
+import threading
+import unittest
+from unittest import skipIf # Imported here for backward compatibility
+from unittest.util import safe_repr
try:
from urllib.parse import urlsplit, urlunsplit
except ImportError: # Python 2
from urlparse import urlsplit, urlunsplit
-import select
-import socket
-import threading
-import warnings
from django.conf import settings
from django.contrib.staticfiles.handlers import StaticFilesHandler
@@ -37,10 +39,8 @@ from django.test.html import HTMLParseError, parse_html
from django.test.signals import template_rendered
from django.test.utils import (CaptureQueriesContext, ContextList,
override_settings, compare_xml)
-from django.utils import six, unittest as ut2
+from django.utils import six
from django.utils.encoding import force_text
-from django.utils.unittest import skipIf # Imported here for backward compatibility
-from django.utils.unittest.util import safe_repr
from django.views.static import serve
@@ -156,16 +156,12 @@ class _AssertTemplateNotUsedContext(_AssertTemplateUsedContext):
return '%s was rendered.' % self.template_name
-class SimpleTestCase(ut2.TestCase):
+class SimpleTestCase(unittest.TestCase):
# The class we'll use for the test client self.client.
# Can be overridden in derived classes.
client_class = Client
- _warn_txt = ("save_warnings_state/restore_warnings_state "
- "django.test.*TestCase methods are deprecated. Use Python's "
- "warnings.catch_warnings context manager instead.")
-
def __call__(self, result=None):
"""
Wrapper around default __call__ method to perform common Django test
@@ -225,21 +221,6 @@ class SimpleTestCase(ut2.TestCase):
settings.ROOT_URLCONF = self._old_root_urlconf
clear_url_caches()
- def save_warnings_state(self):
- """
- Saves the state of the warnings module
- """
- warnings.warn(self._warn_txt, DeprecationWarning, stacklevel=2)
- self._warnings_state = warnings.filters[:]
-
- def restore_warnings_state(self):
- """
- Restores the state of the warnings module to the state
- saved by save_warnings_state()
- """
- warnings.warn(self._warn_txt, DeprecationWarning, stacklevel=2)
- warnings.filters = self._warnings_state[:]
-
def settings(self, **kwargs):
"""
A context manager that temporarily sets a setting and reverts
@@ -906,7 +887,7 @@ def _deferredSkip(condition, reason):
@wraps(test_func)
def skip_wrapper(*args, **kwargs):
if condition():
- raise ut2.SkipTest(reason)
+ raise unittest.SkipTest(reason)
return test_func(*args, **kwargs)
test_item = skip_wrapper
else:
diff --git a/django/test/utils.py b/django/test/utils.py
index 591c588933..70ce640239 100644
--- a/django/test/utils.py
+++ b/django/test/utils.py
@@ -124,31 +124,6 @@ def teardown_test_environment():
del mail.outbox
-warn_txt = ("get_warnings_state/restore_warnings_state functions from "
- "django.test.utils are deprecated. Use Python's warnings.catch_warnings() "
- "context manager instead.")
-
-
-def get_warnings_state():
- """
- Returns an object containing the state of the warnings module
- """
- # There is no public interface for doing this, but this implementation of
- # get_warnings_state and restore_warnings_state appears to work on Python
- # 2.4 to 2.7.
- warnings.warn(warn_txt, DeprecationWarning, stacklevel=2)
- return warnings.filters[:]
-
-
-def restore_warnings_state(state):
- """
- Restores the state of the warnings module when passed an object that was
- returned by get_warnings_state()
- """
- warnings.warn(warn_txt, DeprecationWarning, stacklevel=2)
- warnings.filters = state[:]
-
-
def get_runner(settings, test_runner_class=None):
if not test_runner_class:
test_runner_class = settings.TEST_RUNNER
@@ -402,13 +377,14 @@ class CaptureQueriesContext(object):
class IgnoreDeprecationWarningsMixin(object):
- warning_class = DeprecationWarning
+ warning_classes = [DeprecationWarning]
def setUp(self):
super(IgnoreDeprecationWarningsMixin, self).setUp()
self.catch_warnings = warnings.catch_warnings()
self.catch_warnings.__enter__()
- warnings.filterwarnings("ignore", category=self.warning_class)
+ for warning_class in self.warning_classes:
+ warnings.filterwarnings("ignore", category=warning_class)
def tearDown(self):
self.catch_warnings.__exit__(*sys.exc_info())
@@ -417,7 +393,12 @@ class IgnoreDeprecationWarningsMixin(object):
class IgnorePendingDeprecationWarningsMixin(IgnoreDeprecationWarningsMixin):
- warning_class = PendingDeprecationWarning
+ warning_classes = [PendingDeprecationWarning]
+
+
+class IgnoreAllDeprecationWarningsMixin(IgnoreDeprecationWarningsMixin):
+
+ warning_classes = [PendingDeprecationWarning, DeprecationWarning]
@contextmanager
diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py
index b0b1cd6b1d..20b771e95b 100644
--- a/django/utils/datastructures.py
+++ b/django/utils/datastructures.py
@@ -1,5 +1,4 @@
import copy
-import warnings
from django.utils import six
@@ -217,31 +216,6 @@ class SortedDict(dict):
self.keyOrder.append(key)
return super(SortedDict, self).setdefault(key, default)
- def value_for_index(self, index):
- """Returns the value of the item at the given zero-based index."""
- # This, and insert() are deprecated because they cannot be implemented
- # using collections.OrderedDict (Python 2.7 and up), which we'll
- # eventually switch to
- warnings.warn(
- "SortedDict.value_for_index is deprecated", DeprecationWarning,
- stacklevel=2
- )
- return self[self.keyOrder[index]]
-
- def insert(self, index, key, value):
- """Inserts the key, value pair before the item with the given index."""
- warnings.warn(
- "SortedDict.insert is deprecated", DeprecationWarning,
- stacklevel=2
- )
- if key in self.keyOrder:
- n = self.keyOrder.index(key)
- del self.keyOrder[n]
- if n < index:
- index -= 1
- self.keyOrder.insert(index, key)
- super(SortedDict, self).__setitem__(key, value)
-
def copy(self):
"""Returns a copy of this object."""
# This way of initializing the copy means it works for subclasses, too.
diff --git a/django/utils/dictconfig.py b/django/utils/dictconfig.py
index c7b39819b5..ed1440ce11 100644
--- a/django/utils/dictconfig.py
+++ b/django/utils/dictconfig.py
@@ -1,3 +1,8 @@
+import warnings
+
+warnings.warn("django.utils.dictconfig will be removed in Django 1.9.",
+ PendingDeprecationWarning, stacklevel=2)
+
# This is a copy of the Python logging.config.dictconfig module,
# reproduced with permission. It is provided here for backwards
# compatibility for Python versions prior to 2.7.
diff --git a/django/utils/encoding.py b/django/utils/encoding.py
index adab0d0712..aa0218ca6b 100644
--- a/django/utils/encoding.py
+++ b/django/utils/encoding.py
@@ -8,7 +8,6 @@ try:
from urllib.parse import quote
except ImportError: # Python 2
from urllib import quote
-import warnings
from django.utils.functional import Promise
from django.utils import six
@@ -23,29 +22,6 @@ class DjangoUnicodeDecodeError(UnicodeDecodeError):
return '%s. You passed in %r (%s)' % (original, self.obj,
type(self.obj))
-class StrAndUnicode(object):
- """
- A class that derives __str__ from __unicode__.
-
- On Python 2, __str__ returns the output of __unicode__ encoded as a UTF-8
- bytestring. On Python 3, __str__ returns the output of __unicode__.
-
- Useful as a mix-in. If you support Python 2 and 3 with a single code base,
- you can inherit this mix-in and just define __unicode__.
- """
- def __init__(self, *args, **kwargs):
- warnings.warn("StrAndUnicode is deprecated. Define a __str__ method "
- "and apply the @python_2_unicode_compatible decorator "
- "instead.", DeprecationWarning, stacklevel=2)
- super(StrAndUnicode, self).__init__(*args, **kwargs)
-
- if six.PY3:
- def __str__(self):
- return self.__unicode__()
- else:
- def __str__(self):
- return self.__unicode__().encode('utf-8')
-
def python_2_unicode_compatible(klass):
"""
A decorator that defines __unicode__ and __str__ methods under Python 2.
diff --git a/django/utils/image.py b/django/utils/image.py
index d251ab9d0b..2fd0c6e6b0 100644
--- a/django/utils/image.py
+++ b/django/utils/image.py
@@ -139,7 +139,7 @@ def _detect_image_library():
warnings.warn(
"Support for the PIL will be removed in Django 1.8. Please " +
"uninstall it & install Pillow instead.",
- PendingDeprecationWarning
+ DeprecationWarning
)
return PILImage, PIL_imaging, PILImageFile
diff --git a/django/utils/itercompat.py b/django/utils/itercompat.py
index c50dcfb779..1df1e57cb2 100644
--- a/django/utils/itercompat.py
+++ b/django/utils/itercompat.py
@@ -5,9 +5,7 @@ these implementations if necessary.
"""
import collections
-import itertools
import sys
-import warnings
def is_iterable(x):
@@ -29,8 +27,3 @@ def is_iterator(x):
if sys.version_info >= (2, 7):
return isinstance(x, collections.Iterator)
return isinstance(x, collections.Iterator) and hasattr(x, '__iter__')
-
-def product(*args, **kwds):
- warnings.warn("django.utils.itercompat.product is deprecated; use the native version instead",
- DeprecationWarning, stacklevel=2)
- return itertools.product(*args, **kwds)
diff --git a/django/utils/log.py b/django/utils/log.py
index 6734a7261e..f1af7a249e 100644
--- a/django/utils/log.py
+++ b/django/utils/log.py
@@ -6,22 +6,9 @@ from django.core import mail
from django.core.mail import get_connection
from django.views.debug import ExceptionReporter, get_exception_reporter_filter
-
-# Make sure a NullHandler is available
-# This was added in Python 2.7/3.2
-try:
- from logging import NullHandler
-except ImportError:
- class NullHandler(logging.Handler):
- def emit(self, record):
- pass
-
-# Make sure that dictConfig is available
-# This was added in Python 2.7/3.2
-try:
- from logging.config import dictConfig
-except ImportError:
- from django.utils.dictconfig import dictConfig
+# Imports kept for backwards-compatibility in Django 1.7.
+from logging import NullHandler
+from logging.config import dictConfig
getLogger = logging.getLogger
@@ -46,7 +33,7 @@ DEFAULT_LOGGING = {
'class': 'logging.StreamHandler',
},
'null': {
- 'class': 'django.utils.log.NullHandler',
+ 'class': 'logging.NullHandler',
},
'mail_admins': {
'level': 'ERROR',
diff --git a/django/utils/simplejson.py b/django/utils/simplejson.py
deleted file mode 100644
index d4032a6b34..0000000000
--- a/django/utils/simplejson.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Django 1.5 only supports Python >= 2.6, where the standard library includes
-# the json module. Previous version of Django shipped a copy for Python < 2.6.
-
-# For backwards compatibility, we're keeping an importable json module
-# at this location, with the same lookup sequence.
-
-# Avoid shadowing the simplejson module
-from __future__ import absolute_import
-
-import warnings
-warnings.warn("django.utils.simplejson is deprecated; use json instead.",
- DeprecationWarning, stacklevel=2)
-
-try:
- import simplejson
-except ImportError:
- use_simplejson = False
-else:
- # The system-installed version has priority providing it is either not an
- # earlier version or it contains the C speedups.
- from json import __version__ as stdlib_json_version
- use_simplejson = (hasattr(simplejson, '_speedups') or
- simplejson.__version__.split('.') >= stdlib_json_version.split('.'))
-
-# Make sure we copy over the version. See #17071
-if use_simplejson:
- from simplejson import *
- from simplejson import __version__
-else:
- from json import *
- from json import __version__
diff --git a/django/utils/unittest.py b/django/utils/unittest.py
new file mode 100644
index 0000000000..b9aa1bbd73
--- /dev/null
+++ b/django/utils/unittest.py
@@ -0,0 +1,11 @@
+from __future__ import absolute_import
+
+import warnings
+
+warnings.warn("django.utils.unittest will be removed in Django 1.9.",
+ PendingDeprecationWarning, stacklevel=2)
+
+try:
+ from unittest2 import *
+except ImportError:
+ from unittest import *
diff --git a/django/utils/unittest/__init__.py b/django/utils/unittest/__init__.py
deleted file mode 100644
index ac852a3757..0000000000
--- a/django/utils/unittest/__init__.py
+++ /dev/null
@@ -1,80 +0,0 @@
-"""
-unittest2
-
-unittest2 is a backport of the new features added to the unittest testing
-framework in Python 2.7. It is tested to run on Python 2.4 - 2.6.
-
-To use unittest2 instead of unittest simply replace ``import unittest`` with
-``import unittest2``.
-
-
-Copyright (c) 1999-2003 Steve Purcell
-Copyright (c) 2003-2010 Python Software Foundation
-This module is free software, and you may redistribute it and/or modify
-it under the same terms as Python itself, so long as this copyright message
-and disclaimer are retained in their original form.
-
-IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
-SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
-THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGE.
-
-THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
-AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
-SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-"""
-
-import sys
-
-# Django hackery to load the appropriate version of unittest
-
-try:
- # check the system path first
- from unittest2 import *
-except ImportError:
- if sys.version_info >= (2,7):
- # unittest2 features are native in Python 2.7
- from unittest import *
- else:
- # otherwise use our bundled version
- __all__ = ['TestResult', 'TestCase', 'TestSuite',
- 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main',
- 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless',
- 'expectedFailure', 'TextTestResult', '__version__', 'collector']
-
- __version__ = '0.5.1'
-
- # Expose obsolete functions for backwards compatibility
- __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
-
-
- from django.utils.unittest.collector import collector
- from django.utils.unittest.result import TestResult
- from django.utils.unittest.case import \
- TestCase, FunctionTestCase, SkipTest, skip, skipIf,\
- skipUnless, expectedFailure
-
- from django.utils.unittest.suite import BaseTestSuite, TestSuite
- from django.utils.unittest.loader import \
- TestLoader, defaultTestLoader, makeSuite, getTestCaseNames,\
- findTestCases
-
- from django.utils.unittest.main import TestProgram, main, main_
- from django.utils.unittest.runner import TextTestRunner, TextTestResult
-
- try:
- from django.utils.unittest.signals import\
- installHandler, registerResult, removeResult, removeHandler
- except ImportError:
- # Compatibility with platforms that don't have the signal module
- pass
- else:
- __all__.extend(['installHandler', 'registerResult', 'removeResult',
- 'removeHandler'])
-
- # deprecated
- _TextTestResult = TextTestResult
-
- __unittest = True
diff --git a/django/utils/unittest/__main__.py b/django/utils/unittest/__main__.py
deleted file mode 100644
index 68b893d139..0000000000
--- a/django/utils/unittest/__main__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-"""Main entry point"""
-
-import sys
-if sys.argv[0].endswith("__main__.py"):
- sys.argv[0] = "unittest2"
-
-__unittest = True
-
-from django.utils.unittest.main import main_
-main_()
diff --git a/django/utils/unittest/case.py b/django/utils/unittest/case.py
deleted file mode 100644
index fffd3c2524..0000000000
--- a/django/utils/unittest/case.py
+++ /dev/null
@@ -1,1076 +0,0 @@
-"""Test case implementation"""
-
-import sys
-import difflib
-import pprint
-import re
-import unittest
-import warnings
-
-from django.utils.unittest import result
-from django.utils.unittest.util import\
- safe_repr, safe_str, strclass,\
- unorderable_list_difference
-
-from django.utils.unittest.compatibility import wraps
-
-__unittest = True
-
-
-DIFF_OMITTED = ('\nDiff is %s characters long. '
- 'Set self.maxDiff to None to see it.')
-
-class SkipTest(Exception):
- """
- Raise this exception in a test to skip it.
-
- Usually you can use TestResult.skip() or one of the skipping decorators
- instead of raising this directly.
- """
-
-class _ExpectedFailure(Exception):
- """
- Raise this when a test is expected to fail.
-
- This is an implementation detail.
- """
-
- def __init__(self, exc_info):
- # can't use super because Python 2.4 exceptions are old style
- Exception.__init__(self)
- self.exc_info = exc_info
-
-class _UnexpectedSuccess(Exception):
- """
- The test was supposed to fail, but it didn't!
- """
-
-def _id(obj):
- return obj
-
-def skip(reason):
- """
- Unconditionally skip a test.
- """
- def decorator(test_item):
- if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
- @wraps(test_item)
- def skip_wrapper(*args, **kwargs):
- raise SkipTest(reason)
- test_item = skip_wrapper
-
- test_item.__unittest_skip__ = True
- test_item.__unittest_skip_why__ = reason
- return test_item
- return decorator
-
-def skipIf(condition, reason):
- """
- Skip a test if the condition is true.
- """
- if condition:
- return skip(reason)
- return _id
-
-def skipUnless(condition, reason):
- """
- Skip a test unless the condition is true.
- """
- if not condition:
- return skip(reason)
- return _id
-
-
-def expectedFailure(func):
- @wraps(func)
- def wrapper(*args, **kwargs):
- try:
- func(*args, **kwargs)
- except Exception:
- raise _ExpectedFailure(sys.exc_info())
- raise _UnexpectedSuccess
- return wrapper
-
-
-class _AssertRaisesContext(object):
- """A context manager used to implement TestCase.assertRaises* methods."""
-
- def __init__(self, expected, test_case, expected_regexp=None):
- self.expected = expected
- self.failureException = test_case.failureException
- self.expected_regexp = expected_regexp
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_value, tb):
- if exc_type is None:
- try:
- exc_name = self.expected.__name__
- except AttributeError:
- exc_name = str(self.expected)
- raise self.failureException(
- "%s not raised" % (exc_name,))
- if not issubclass(exc_type, self.expected):
- # let unexpected exceptions pass through
- return False
- self.exception = exc_value # store for later retrieval
- if self.expected_regexp is None:
- return True
-
- expected_regexp = self.expected_regexp
- if isinstance(expected_regexp, basestring):
- expected_regexp = re.compile(expected_regexp)
- if not expected_regexp.search(str(exc_value)):
- raise self.failureException('"%s" does not match "%s"' %
- (expected_regexp.pattern, str(exc_value)))
- return True
-
-
-class _TypeEqualityDict(object):
-
- def __init__(self, testcase):
- self.testcase = testcase
- self._store = {}
-
- def __setitem__(self, key, value):
- self._store[key] = value
-
- def __getitem__(self, key):
- value = self._store[key]
- if isinstance(value, basestring):
- return getattr(self.testcase, value)
- return value
-
- def get(self, key, default=None):
- if key in self._store:
- return self[key]
- return default
-
-
-class TestCase(unittest.TestCase):
- """A class whose instances are single test cases.
-
- By default, the test code itself should be placed in a method named
- 'runTest'.
-
- If the fixture may be used for many test cases, create as
- many test methods as are needed. When instantiating such a TestCase
- subclass, specify in the constructor arguments the name of the test method
- that the instance is to execute.
-
- Test authors should subclass TestCase for their own tests. Construction
- and deconstruction of the test's environment ('fixture') can be
- implemented by overriding the 'setUp' and 'tearDown' methods respectively.
-
- If it is necessary to override the __init__ method, the base class
- __init__ method must always be called. It is important that subclasses
- should not change the signature of their __init__ method, since instances
- of the classes are instantiated automatically by parts of the framework
- in order to be run.
- """
-
- # This attribute determines which exception will be raised when
- # the instance's assertion methods fail; test methods raising this
- # exception will be deemed to have 'failed' rather than 'errored'
-
- failureException = AssertionError
-
- # This attribute sets the maximum length of a diff in failure messages
- # by assert methods using difflib. It is looked up as an instance attribute
- # so can be configured by individual tests if required.
-
- maxDiff = 80*8
-
- # This attribute determines whether long messages (including repr of
- # objects used in assert methods) will be printed on failure in *addition*
- # to any explicit message passed.
-
- longMessage = True
-
- # Attribute used by TestSuite for classSetUp
-
- _classSetupFailed = False
-
- def __init__(self, methodName='runTest'):
- """Create an instance of the class that will use the named test
- method when executed. Raises a ValueError if the instance does
- not have a method with the specified name.
- """
- self._testMethodName = methodName
- self._resultForDoCleanups = None
- try:
- testMethod = getattr(self, methodName)
- except AttributeError:
- raise ValueError("no such test method in %s: %s" % \
- (self.__class__, methodName))
- self._testMethodDoc = testMethod.__doc__
- self._cleanups = []
-
- # Map types to custom assertEqual functions that will compare
- # instances of said type in more detail to generate a more useful
- # error message.
- self._type_equality_funcs = _TypeEqualityDict(self)
- self.addTypeEqualityFunc(dict, 'assertDictEqual')
- self.addTypeEqualityFunc(list, 'assertListEqual')
- self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
- self.addTypeEqualityFunc(set, 'assertSetEqual')
- self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
- self.addTypeEqualityFunc(unicode, 'assertMultiLineEqual')
-
- def addTypeEqualityFunc(self, typeobj, function):
- """Add a type specific assertEqual style function to compare a type.
-
- This method is for use by TestCase subclasses that need to register
- their own type equality functions to provide nicer error messages.
-
- Args:
- typeobj: The data type to call this function on when both values
- are of the same type in assertEqual().
- function: The callable taking two arguments and an optional
- msg= argument that raises self.failureException with a
- useful error message when the two arguments are not equal.
- """
- self._type_equality_funcs[typeobj] = function
-
- def addCleanup(self, function, *args, **kwargs):
- """Add a function, with arguments, to be called when the test is
- completed. Functions added are called on a LIFO basis and are
- called after tearDown on test failure or success.
-
- Cleanup items are called even if setUp fails (unlike tearDown)."""
- self._cleanups.append((function, args, kwargs))
-
- @classmethod
- def setUpClass(cls):
- "Hook method for setting up class fixture before running tests in the class."
-
- @classmethod
- def tearDownClass(cls):
- "Hook method for deconstructing the class fixture after running all tests in the class."
-
- def countTestCases(self):
- return 1
-
- def defaultTestResult(self):
- return result.TestResult()
-
- def shortDescription(self):
- """Returns a one-line description of the test, or None if no
- description has been provided.
-
- The default implementation of this method returns the first line of
- the specified test method's docstring.
- """
- doc = self._testMethodDoc
- return doc and doc.split("\n")[0].strip() or None
-
-
- def id(self):
- return "%s.%s" % (strclass(self.__class__), self._testMethodName)
-
- def __eq__(self, other):
- if type(self) is not type(other):
- return NotImplemented
-
- return self._testMethodName == other._testMethodName
-
- def __ne__(self, other):
- return not self == other
-
- def __hash__(self):
- return hash((type(self), self._testMethodName))
-
- def __str__(self):
- return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
-
- def __repr__(self):
- return "<%s testMethod=%s>" % \
- (strclass(self.__class__), self._testMethodName)
-
- def _addSkip(self, result, reason):
- addSkip = getattr(result, 'addSkip', None)
- if addSkip is not None:
- addSkip(self, reason)
- else:
- warnings.warn("Use of a TestResult without an addSkip method is deprecated",
- DeprecationWarning, 2)
- result.addSuccess(self)
-
- def run(self, result=None):
- orig_result = result
- if result is None:
- result = self.defaultTestResult()
- startTestRun = getattr(result, 'startTestRun', None)
- if startTestRun is not None:
- startTestRun()
-
- self._resultForDoCleanups = result
- result.startTest(self)
-
- testMethod = getattr(self, self._testMethodName)
-
- if (getattr(self.__class__, "__unittest_skip__", False) or
- getattr(testMethod, "__unittest_skip__", False)):
- # If the class or method was skipped.
- try:
- skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
- or getattr(testMethod, '__unittest_skip_why__', ''))
- self._addSkip(result, skip_why)
- finally:
- result.stopTest(self)
- return
- try:
- success = False
- try:
- self.setUp()
- except SkipTest as e:
- self._addSkip(result, str(e))
- except Exception:
- result.addError(self, sys.exc_info())
- else:
- try:
- testMethod()
- except self.failureException:
- result.addFailure(self, sys.exc_info())
- except _ExpectedFailure as e:
- addExpectedFailure = getattr(result, 'addExpectedFailure', None)
- if addExpectedFailure is not None:
- addExpectedFailure(self, e.exc_info)
- else:
- warnings.warn("Use of a TestResult without an addExpectedFailure method is deprecated",
- DeprecationWarning)
- result.addSuccess(self)
- except _UnexpectedSuccess:
- addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
- if addUnexpectedSuccess is not None:
- addUnexpectedSuccess(self)
- else:
- warnings.warn("Use of a TestResult without an addUnexpectedSuccess method is deprecated",
- DeprecationWarning)
- result.addFailure(self, sys.exc_info())
- except SkipTest as e:
- self._addSkip(result, str(e))
- except Exception:
- result.addError(self, sys.exc_info())
- else:
- success = True
-
- try:
- self.tearDown()
- except Exception:
- result.addError(self, sys.exc_info())
- success = False
-
- cleanUpSuccess = self.doCleanups()
- success = success and cleanUpSuccess
- if success:
- result.addSuccess(self)
- finally:
- result.stopTest(self)
- if orig_result is None:
- stopTestRun = getattr(result, 'stopTestRun', None)
- if stopTestRun is not None:
- stopTestRun()
-
- def doCleanups(self):
- """Execute all cleanup functions. Normally called for you after
- tearDown."""
- result = self._resultForDoCleanups
- ok = True
- while self._cleanups:
- function, args, kwargs = self._cleanups.pop(-1)
- try:
- function(*args, **kwargs)
- except Exception:
- ok = False
- result.addError(self, sys.exc_info())
- return ok
-
- def __call__(self, *args, **kwds):
- return self.run(*args, **kwds)
-
- def debug(self):
- """Run the test without collecting errors in a TestResult"""
- self.setUp()
- getattr(self, self._testMethodName)()
- self.tearDown()
- while self._cleanups:
- function, args, kwargs = self._cleanups.pop(-1)
- function(*args, **kwargs)
-
- def skipTest(self, reason):
- """Skip this test."""
- raise SkipTest(reason)
-
- def fail(self, msg=None):
- """Fail immediately, with the given message."""
- raise self.failureException(msg)
-
- def assertFalse(self, expr, msg=None):
- "Fail the test if the expression is true."
- if expr:
- msg = self._formatMessage(msg, "%s is not False" % safe_repr(expr))
- raise self.failureException(msg)
-
- def assertTrue(self, expr, msg=None):
- """Fail the test unless the expression is true."""
- if not expr:
- msg = self._formatMessage(msg, "%s is not True" % safe_repr(expr))
- raise self.failureException(msg)
-
- def _formatMessage(self, msg, standardMsg):
- """Honour the longMessage attribute when generating failure messages.
- If longMessage is False this means:
- * Use only an explicit message if it is provided
- * Otherwise use the standard message for the assert
-
- If longMessage is True:
- * Use the standard message
- * If an explicit message is provided, plus ' : ' and the explicit message
- """
- if not self.longMessage:
- return msg or standardMsg
- if msg is None:
- return standardMsg
- try:
- return '%s : %s' % (standardMsg, msg)
- except UnicodeDecodeError:
- return '%s : %s' % (safe_str(standardMsg), safe_str(msg))
-
-
- def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
- """Fail unless an exception of class excClass is thrown
- by callableObj when invoked with arguments args and keyword
- arguments kwargs. If a different type of exception is
- thrown, it will not be caught, and the test case will be
- deemed to have suffered an error, exactly as for an
- unexpected exception.
-
- If called with callableObj omitted or None, will return a
- context object used like this::
-
- with self.assertRaises(SomeException):
- do_something()
-
- The context manager keeps a reference to the exception as
- the 'exception' attribute. This allows you to inspect the
- exception after the assertion::
-
- with self.assertRaises(SomeException) as cm:
- do_something()
- the_exception = cm.exception
- self.assertEqual(the_exception.error_code, 3)
- """
- if callableObj is None:
- return _AssertRaisesContext(excClass, self)
- try:
- callableObj(*args, **kwargs)
- except excClass:
- return
-
- if hasattr(excClass,'__name__'):
- excName = excClass.__name__
- else:
- excName = str(excClass)
- raise self.failureException("%s not raised" % excName)
-
- def _getAssertEqualityFunc(self, first, second):
- """Get a detailed comparison function for the types of the two args.
-
- Returns: A callable accepting (first, second, msg=None) that will
- raise a failure exception if first != second with a useful human
- readable error message for those types.
- """
- #
- # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
- # and vice versa. I opted for the conservative approach in case
- # subclasses are not intended to be compared in detail to their super
- # class instances using a type equality func. This means testing
- # subtypes won't automagically use the detailed comparison. Callers
- # should use their type specific assertSpamEqual method to compare
- # subclasses if the detailed comparison is desired and appropriate.
- # See the discussion in http://bugs.python.org/issue2578.
- #
- if type(first) is type(second):
- asserter = self._type_equality_funcs.get(type(first))
- if asserter is not None:
- return asserter
-
- return self._baseAssertEqual
-
- def _baseAssertEqual(self, first, second, msg=None):
- """The default assertEqual implementation, not type specific."""
- if not first == second:
- standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
- msg = self._formatMessage(msg, standardMsg)
- raise self.failureException(msg)
-
- def assertEqual(self, first, second, msg=None):
- """Fail if the two objects are unequal as determined by the '=='
- operator.
- """
- assertion_func = self._getAssertEqualityFunc(first, second)
- assertion_func(first, second, msg=msg)
-
- def assertNotEqual(self, first, second, msg=None):
- """Fail if the two objects are equal as determined by the '=='
- operator.
- """
- if not first != second:
- msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
- safe_repr(second)))
- raise self.failureException(msg)
-
- def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None):
- """Fail if the two objects are unequal as determined by their
- difference rounded to the given number of decimal places
- (default 7) and comparing to zero, or by comparing that the
- between the two objects is more than the given delta.
-
- Note that decimal places (from zero) are usually not the same
- as significant digits (measured from the most signficant digit).
-
- If the two objects compare equal then they will automatically
- compare almost equal.
- """
- if first == second:
- # shortcut
- return
- if delta is not None and places is not None:
- raise TypeError("specify delta or places not both")
-
- if delta is not None:
- if abs(first - second) <= delta:
- return
-
- standardMsg = '%s != %s within %s delta' % (safe_repr(first),
- safe_repr(second),
- safe_repr(delta))
- else:
- if places is None:
- places = 7
-
- if round(abs(second-first), places) == 0:
- return
-
- standardMsg = '%s != %s within %r places' % (safe_repr(first),
- safe_repr(second),
- places)
- msg = self._formatMessage(msg, standardMsg)
- raise self.failureException(msg)
-
- def assertNotAlmostEqual(self, first, second, places=None, msg=None, delta=None):
- """Fail if the two objects are equal as determined by their
- difference rounded to the given number of decimal places
- (default 7) and comparing to zero, or by comparing that the
- between the two objects is less than the given delta.
-
- Note that decimal places (from zero) are usually not the same
- as significant digits (measured from the most signficant digit).
-
- Objects that are equal automatically fail.
- """
- if delta is not None and places is not None:
- raise TypeError("specify delta or places not both")
- if delta is not None:
- if not (first == second) and abs(first - second) > delta:
- return
- standardMsg = '%s == %s within %s delta' % (safe_repr(first),
- safe_repr(second),
- safe_repr(delta))
- else:
- if places is None:
- places = 7
- if not (first == second) and round(abs(second-first), places) != 0:
- return
- standardMsg = '%s == %s within %r places' % (safe_repr(first),
- safe_repr(second),
- places)
-
- msg = self._formatMessage(msg, standardMsg)
- raise self.failureException(msg)
-
- # Synonyms for assertion methods
-
- # The plurals are undocumented. Keep them that way to discourage use.
- # Do not add more. Do not remove.
- # Going through a deprecation cycle on these would annoy many people.
- assertEquals = assertEqual
- assertNotEquals = assertNotEqual
- assertAlmostEquals = assertAlmostEqual
- assertNotAlmostEquals = assertNotAlmostEqual
- assert_ = assertTrue
-
- # These fail* assertion method names are pending deprecation and will
- # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
- def _deprecate(original_func):
- def deprecated_func(*args, **kwargs):
- warnings.warn(
- ('Please use %s instead.' % original_func.__name__),
- PendingDeprecationWarning, 2)
- return original_func(*args, **kwargs)
- return deprecated_func
-
- failUnlessEqual = _deprecate(assertEqual)
- failIfEqual = _deprecate(assertNotEqual)
- failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
- failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
- failUnless = _deprecate(assertTrue)
- failUnlessRaises = _deprecate(assertRaises)
- failIf = _deprecate(assertFalse)
-
- def assertSequenceEqual(self, seq1, seq2,
- msg=None, seq_type=None, max_diff=80*8):
- """An equality assertion for ordered sequences (like lists and tuples).
-
- For the purposes of this function, a valid ordered sequence type is one
- which can be indexed, has a length, and has an equality operator.
-
- Args:
- seq1: The first sequence to compare.
- seq2: The second sequence to compare.
- seq_type: The expected datatype of the sequences, or None if no
- datatype should be enforced.
- msg: Optional message to use on failure instead of a list of
- differences.
- max_diff: Maximum size off the diff, larger diffs are not shown
- """
- if seq_type is not None:
- seq_type_name = seq_type.__name__
- if not isinstance(seq1, seq_type):
- raise self.failureException('First sequence is not a %s: %s'
- % (seq_type_name, safe_repr(seq1)))
- if not isinstance(seq2, seq_type):
- raise self.failureException('Second sequence is not a %s: %s'
- % (seq_type_name, safe_repr(seq2)))
- else:
- seq_type_name = "sequence"
-
- differing = None
- try:
- len1 = len(seq1)
- except (TypeError, NotImplementedError):
- differing = 'First %s has no length. Non-sequence?' % (
- seq_type_name)
-
- if differing is None:
- try:
- len2 = len(seq2)
- except (TypeError, NotImplementedError):
- differing = 'Second %s has no length. Non-sequence?' % (
- seq_type_name)
-
- if differing is None:
- if seq1 == seq2:
- return
-
- seq1_repr = repr(seq1)
- seq2_repr = repr(seq2)
- if len(seq1_repr) > 30:
- seq1_repr = seq1_repr[:30] + '...'
- if len(seq2_repr) > 30:
- seq2_repr = seq2_repr[:30] + '...'
- elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
- differing = '%ss differ: %s != %s\n' % elements
-
- for i in xrange(min(len1, len2)):
- try:
- item1 = seq1[i]
- except (TypeError, IndexError, NotImplementedError):
- differing += ('\nUnable to index element %d of first %s\n' %
- (i, seq_type_name))
- break
-
- try:
- item2 = seq2[i]
- except (TypeError, IndexError, NotImplementedError):
- differing += ('\nUnable to index element %d of second %s\n' %
- (i, seq_type_name))
- break
-
- if item1 != item2:
- differing += ('\nFirst differing element %d:\n%s\n%s\n' %
- (i, item1, item2))
- break
- else:
- if (len1 == len2 and seq_type is None and
- type(seq1) != type(seq2)):
- # The sequences are the same, but have differing types.
- return
-
- if len1 > len2:
- differing += ('\nFirst %s contains %d additional '
- 'elements.\n' % (seq_type_name, len1 - len2))
- try:
- differing += ('First extra element %d:\n%s\n' %
- (len2, seq1[len2]))
- except (TypeError, IndexError, NotImplementedError):
- differing += ('Unable to index element %d '
- 'of first %s\n' % (len2, seq_type_name))
- elif len1 < len2:
- differing += ('\nSecond %s contains %d additional '
- 'elements.\n' % (seq_type_name, len2 - len1))
- try:
- differing += ('First extra element %d:\n%s\n' %
- (len1, seq2[len1]))
- except (TypeError, IndexError, NotImplementedError):
- differing += ('Unable to index element %d '
- 'of second %s\n' % (len1, seq_type_name))
- standardMsg = differing
- diffMsg = '\n' + '\n'.join(
- difflib.ndiff(pprint.pformat(seq1).splitlines(),
- pprint.pformat(seq2).splitlines()))
-
- standardMsg = self._truncateMessage(standardMsg, diffMsg)
- msg = self._formatMessage(msg, standardMsg)
- self.fail(msg)
-
- def _truncateMessage(self, message, diff):
- max_diff = self.maxDiff
- if max_diff is None or len(diff) <= max_diff:
- return message + diff
- return message + (DIFF_OMITTED % len(diff))
-
- def assertListEqual(self, list1, list2, msg=None):
- """A list-specific equality assertion.
-
- Args:
- list1: The first list to compare.
- list2: The second list to compare.
- msg: Optional message to use on failure instead of a list of
- differences.
-
- """
- self.assertSequenceEqual(list1, list2, msg, seq_type=list)
-
- def assertTupleEqual(self, tuple1, tuple2, msg=None):
- """A tuple-specific equality assertion.
-
- Args:
- tuple1: The first tuple to compare.
- tuple2: The second tuple to compare.
- msg: Optional message to use on failure instead of a list of
- differences.
- """
- self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
-
- def assertSetEqual(self, set1, set2, msg=None):
- """A set-specific equality assertion.
-
- Args:
- set1: The first set to compare.
- set2: The second set to compare.
- msg: Optional message to use on failure instead of a list of
- differences.
-
- assertSetEqual uses ducktyping to support
- different types of sets, and is optimized for sets specifically
- (parameters must support a difference method).
- """
- try:
- difference1 = set1.difference(set2)
- except TypeError as e:
- self.fail('invalid type when attempting set difference: %s' % e)
- except AttributeError as e:
- self.fail('first argument does not support set difference: %s' % e)
-
- try:
- difference2 = set2.difference(set1)
- except TypeError as e:
- self.fail('invalid type when attempting set difference: %s' % e)
- except AttributeError as e:
- self.fail('second argument does not support set difference: %s' % e)
-
- if not (difference1 or difference2):
- return
-
- lines = []
- if difference1:
- lines.append('Items in the first set but not the second:')
- for item in difference1:
- lines.append(repr(item))
- if difference2:
- lines.append('Items in the second set but not the first:')
- for item in difference2:
- lines.append(repr(item))
-
- standardMsg = '\n'.join(lines)
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertIn(self, member, container, msg=None):
- """Just like self.assertTrue(a in b), but with a nicer default message."""
- if member not in container:
- standardMsg = '%s not found in %s' % (safe_repr(member),
- safe_repr(container))
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertNotIn(self, member, container, msg=None):
- """Just like self.assertTrue(a not in b), but with a nicer default message."""
- if member in container:
- standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
- safe_repr(container))
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertIs(self, expr1, expr2, msg=None):
- """Just like self.assertTrue(a is b), but with a nicer default message."""
- if expr1 is not expr2:
- standardMsg = '%s is not %s' % (safe_repr(expr1), safe_repr(expr2))
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertIsNot(self, expr1, expr2, msg=None):
- """Just like self.assertTrue(a is not b), but with a nicer default message."""
- if expr1 is expr2:
- standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertDictEqual(self, d1, d2, msg=None):
- self.assertTrue(isinstance(d1, dict), 'First argument is not a dictionary')
- self.assertTrue(isinstance(d2, dict), 'Second argument is not a dictionary')
-
- if d1 != d2:
- standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
- diff = ('\n' + '\n'.join(difflib.ndiff(
- pprint.pformat(d1).splitlines(),
- pprint.pformat(d2).splitlines())))
- standardMsg = self._truncateMessage(standardMsg, diff)
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertDictContainsSubset(self, expected, actual, msg=None):
- """Checks whether actual is a superset of expected."""
- missing = []
- mismatched = []
- for key, value in expected.iteritems():
- if key not in actual:
- missing.append(key)
- elif value != actual[key]:
- mismatched.append('%s, expected: %s, actual: %s' %
- (safe_repr(key), safe_repr(value),
- safe_repr(actual[key])))
-
- if not (missing or mismatched):
- return
-
- standardMsg = ''
- if missing:
- standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
- missing)
- if mismatched:
- if standardMsg:
- standardMsg += '; '
- standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
-
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
- """An unordered sequence specific comparison. It asserts that
- expected_seq and actual_seq contain the same elements. It is
- the equivalent of::
-
- self.assertEqual(sorted(expected_seq), sorted(actual_seq))
-
- Raises with an error message listing which elements of expected_seq
- are missing from actual_seq and vice versa if any.
-
- Asserts that each element has the same count in both sequences.
- Example:
- - [0, 1, 1] and [1, 0, 1] compare equal.
- - [0, 0, 1] and [0, 1] compare unequal.
- """
- try:
- expected = sorted(expected_seq)
- actual = sorted(actual_seq)
- except TypeError:
- # Unsortable items (example: set(), complex(), ...)
- expected = list(expected_seq)
- actual = list(actual_seq)
- missing, unexpected = unorderable_list_difference(
- expected, actual, ignore_duplicate=False
- )
- else:
- return self.assertSequenceEqual(expected, actual, msg=msg)
-
- errors = []
- if missing:
- errors.append('Expected, but missing:\n %s' %
- safe_repr(missing))
- if unexpected:
- errors.append('Unexpected, but present:\n %s' %
- safe_repr(unexpected))
- if errors:
- standardMsg = '\n'.join(errors)
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertMultiLineEqual(self, first, second, msg=None):
- """Assert that two multi-line strings are equal."""
- self.assertTrue(isinstance(first, basestring), (
- 'First argument is not a string'))
- self.assertTrue(isinstance(second, basestring), (
- 'Second argument is not a string'))
-
- if first != second:
- standardMsg = '%s != %s' % (safe_repr(first, True), safe_repr(second, True))
- diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
- second.splitlines(True)))
- standardMsg = self._truncateMessage(standardMsg, diff)
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertLess(self, a, b, msg=None):
- """Just like self.assertTrue(a < b), but with a nicer default message."""
- if not a < b:
- standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertLessEqual(self, a, b, msg=None):
- """Just like self.assertTrue(a <= b), but with a nicer default message."""
- if not a <= b:
- standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertGreater(self, a, b, msg=None):
- """Just like self.assertTrue(a > b), but with a nicer default message."""
- if not a > b:
- standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertGreaterEqual(self, a, b, msg=None):
- """Just like self.assertTrue(a >= b), but with a nicer default message."""
- if not a >= b:
- standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertIsNone(self, obj, msg=None):
- """Same as self.assertTrue(obj is None), with a nicer default message."""
- if obj is not None:
- standardMsg = '%s is not None' % (safe_repr(obj),)
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertIsNotNone(self, obj, msg=None):
- """Included for symmetry with assertIsNone."""
- if obj is None:
- standardMsg = 'unexpectedly None'
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertIsInstance(self, obj, cls, msg=None):
- """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
- default message."""
- if not isinstance(obj, cls):
- standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertNotIsInstance(self, obj, cls, msg=None):
- """Included for symmetry with assertIsInstance."""
- if isinstance(obj, cls):
- standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
- self.fail(self._formatMessage(msg, standardMsg))
-
- def assertRaisesRegexp(self, expected_exception, expected_regexp,
- callable_obj=None, *args, **kwargs):
- """Asserts that the message in a raised exception matches a regexp.
-
- Args:
- expected_exception: Exception class expected to be raised.
- expected_regexp: Regexp (re pattern object or string) expected
- to be found in error message.
- callable_obj: Function to be called.
- args: Extra args.
- kwargs: Extra kwargs.
- """
- if callable_obj is None:
- return _AssertRaisesContext(expected_exception, self, expected_regexp)
- try:
- callable_obj(*args, **kwargs)
- except expected_exception as exc_value:
- if isinstance(expected_regexp, basestring):
- expected_regexp = re.compile(expected_regexp)
- if not expected_regexp.search(str(exc_value)):
- raise self.failureException('"%s" does not match "%s"' %
- (expected_regexp.pattern, str(exc_value)))
- else:
- if hasattr(expected_exception, '__name__'):
- excName = expected_exception.__name__
- else:
- excName = str(expected_exception)
- raise self.failureException("%s not raised" % excName)
-
- def assertRegexpMatches(self, text, expected_regexp, msg=None):
- """Fail the test unless the text matches the regular expression."""
- if isinstance(expected_regexp, basestring):
- expected_regexp = re.compile(expected_regexp)
- if not expected_regexp.search(text):
- msg = msg or "Regexp didn't match"
- msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
- raise self.failureException(msg)
-
- def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
- """Fail the test if the text matches the regular expression."""
- if isinstance(unexpected_regexp, basestring):
- unexpected_regexp = re.compile(unexpected_regexp)
- match = unexpected_regexp.search(text)
- if match:
- msg = msg or "Regexp matched"
- msg = '%s: %r matches %r in %r' % (msg,
- text[match.start():match.end()],
- unexpected_regexp.pattern,
- text)
- raise self.failureException(msg)
-
-class FunctionTestCase(TestCase):
- """A test case that wraps a test function.
-
- This is useful for slipping pre-existing test functions into the
- unittest framework. Optionally, set-up and tidy-up functions can be
- supplied. As with TestCase, the tidy-up ('tearDown') function will
- always be called if the set-up ('setUp') function ran successfully.
- """
-
- def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
- super(FunctionTestCase, self).__init__()
- self._setUpFunc = setUp
- self._tearDownFunc = tearDown
- self._testFunc = testFunc
- self._description = description
-
- def setUp(self):
- if self._setUpFunc is not None:
- self._setUpFunc()
-
- def tearDown(self):
- if self._tearDownFunc is not None:
- self._tearDownFunc()
-
- def runTest(self):
- self._testFunc()
-
- def id(self):
- return self._testFunc.__name__
-
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
-
- return self._setUpFunc == other._setUpFunc and \
- self._tearDownFunc == other._tearDownFunc and \
- self._testFunc == other._testFunc and \
- self._description == other._description
-
- def __ne__(self, other):
- return not self == other
-
- def __hash__(self):
- return hash((type(self), self._setUpFunc, self._tearDownFunc,
- self._testFunc, self._description))
-
- def __str__(self):
- return "%s (%s)" % (strclass(self.__class__),
- self._testFunc.__name__)
-
- def __repr__(self):
- return "<%s testFunc=%s>" % (strclass(self.__class__),
- self._testFunc)
-
- def shortDescription(self):
- if self._description is not None:
- return self._description
- doc = self._testFunc.__doc__
- return doc and doc.split("\n")[0].strip() or None
diff --git a/django/utils/unittest/collector.py b/django/utils/unittest/collector.py
deleted file mode 100644
index 0f76fc3404..0000000000
--- a/django/utils/unittest/collector.py
+++ /dev/null
@@ -1,9 +0,0 @@
-import os
-import sys
-from django.utils.unittest.loader import defaultTestLoader
-
-def collector():
- # import __main__ triggers code re-execution
- __main__ = sys.modules['__main__']
- setupDir = os.path.abspath(os.path.dirname(__main__.__file__))
- return defaultTestLoader.discover(setupDir)
diff --git a/django/utils/unittest/compatibility.py b/django/utils/unittest/compatibility.py
deleted file mode 100644
index a0dc499cbf..0000000000
--- a/django/utils/unittest/compatibility.py
+++ /dev/null
@@ -1,64 +0,0 @@
-import os
-import sys
-
-try:
- from functools import wraps
-except ImportError:
- # only needed for Python 2.4
- def wraps(_):
- def _wraps(func):
- return func
- return _wraps
-
-__unittest = True
-
-def _relpath_nt(path, start=os.path.curdir):
- """Return a relative version of a path"""
-
- if not path:
- raise ValueError("no path specified")
- start_list = os.path.abspath(start).split(os.path.sep)
- path_list = os.path.abspath(path).split(os.path.sep)
- if start_list[0].lower() != path_list[0].lower():
- unc_path, rest = os.path.splitunc(path)
- unc_start, rest = os.path.splitunc(start)
- if bool(unc_path) ^ bool(unc_start):
- raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
- % (path, start))
- else:
- raise ValueError("path is on drive %s, start on drive %s"
- % (path_list[0], start_list[0]))
- # Work out how much of the filepath is shared by start and path.
- for i in range(min(len(start_list), len(path_list))):
- if start_list[i].lower() != path_list[i].lower():
- break
- else:
- i += 1
-
- rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
- if not rel_list:
- return os.path.curdir
- return os.path.join(*rel_list)
-
-# default to posixpath definition
-def _relpath_posix(path, start=os.path.curdir):
- """Return a relative version of a path"""
-
- if not path:
- raise ValueError("no path specified")
-
- start_list = os.path.abspath(start).split(os.path.sep)
- path_list = os.path.abspath(path).split(os.path.sep)
-
- # Work out how much of the filepath is shared by start and path.
- i = len(os.path.commonprefix([start_list, path_list]))
-
- rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
- if not rel_list:
- return os.path.curdir
- return os.path.join(*rel_list)
-
-if os.path is sys.modules.get('ntpath'):
- relpath = _relpath_nt
-else:
- relpath = _relpath_posix
diff --git a/django/utils/unittest/loader.py b/django/utils/unittest/loader.py
deleted file mode 100644
index 695bac40ef..0000000000
--- a/django/utils/unittest/loader.py
+++ /dev/null
@@ -1,322 +0,0 @@
-"""Loading unittests."""
-
-import os
-import re
-import sys
-import traceback
-import types
-import unittest
-
-from fnmatch import fnmatch
-
-from django.utils.unittest import case, suite
-
-try:
- from os.path import relpath
-except ImportError:
- from django.utils.unittest.compatibility import relpath
-
-__unittest = True
-
-
-def _CmpToKey(mycmp):
- 'Convert a cmp= function into a key= function'
- class K(object):
- def __init__(self, obj):
- self.obj = obj
- def __lt__(self, other):
- return mycmp(self.obj, other.obj) == -1
- return K
-
-
-# what about .pyc or .pyo (etc)
-# we would need to avoid loading the same tests multiple times
-# from '.py', '.pyc' *and* '.pyo'
-VALID_MODULE_NAME = re.compile(r'[_a-z]\w*\.py$', re.IGNORECASE)
-
-
-def _make_failed_import_test(name, suiteClass):
- message = 'Failed to import test module: %s' % name
- if hasattr(traceback, 'format_exc'):
- # Python 2.3 compatibility
- # format_exc returns two frames of discover.py as well
- message += '\n%s' % traceback.format_exc()
- return _make_failed_test('ModuleImportFailure', name, ImportError(message),
- suiteClass)
-
-def _make_failed_load_tests(name, exception, suiteClass):
- return _make_failed_test('LoadTestsFailure', name, exception, suiteClass)
-
-def _make_failed_test(classname, methodname, exception, suiteClass):
- def testFailure(self):
- raise exception
- attrs = {methodname: testFailure}
- TestClass = type(classname, (case.TestCase,), attrs)
- return suiteClass((TestClass(methodname),))
-
-
-class TestLoader(unittest.TestLoader):
- """
- This class is responsible for loading tests according to various criteria
- and returning them wrapped in a TestSuite
- """
- testMethodPrefix = 'test'
- sortTestMethodsUsing = cmp
- suiteClass = suite.TestSuite
- _top_level_dir = None
-
- def loadTestsFromTestCase(self, testCaseClass):
- """Return a suite of all tests cases contained in testCaseClass"""
- if issubclass(testCaseClass, suite.TestSuite):
- raise TypeError("Test cases should not be derived from TestSuite."
- " Maybe you meant to derive from TestCase?")
- testCaseNames = self.getTestCaseNames(testCaseClass)
- if not testCaseNames and hasattr(testCaseClass, 'runTest'):
- testCaseNames = ['runTest']
- loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
- return loaded_suite
-
- def loadTestsFromModule(self, module, use_load_tests=True):
- """Return a suite of all tests cases contained in the given module"""
- tests = []
- for name in dir(module):
- obj = getattr(module, name)
- if isinstance(obj, type) and issubclass(obj, unittest.TestCase):
- tests.append(self.loadTestsFromTestCase(obj))
-
- load_tests = getattr(module, 'load_tests', None)
- tests = self.suiteClass(tests)
- if use_load_tests and load_tests is not None:
- try:
- return load_tests(self, tests, None)
- except Exception as e:
- return _make_failed_load_tests(module.__name__, e,
- self.suiteClass)
- return tests
-
- def loadTestsFromName(self, name, module=None):
- """Return a suite of all tests cases given a string specifier.
-
- The name may resolve either to a module, a test case class, a
- test method within a test case class, or a callable object which
- returns a TestCase or TestSuite instance.
-
- The method optionally resolves the names relative to a given module.
- """
- parts = name.split('.')
- if module is None:
- parts_copy = parts[:]
- while parts_copy:
- try:
- module = __import__('.'.join(parts_copy))
- break
- except ImportError:
- del parts_copy[-1]
- if not parts_copy:
- raise
- parts = parts[1:]
- obj = module
- for part in parts:
- parent, obj = obj, getattr(obj, part)
-
- if isinstance(obj, types.ModuleType):
- return self.loadTestsFromModule(obj)
- elif isinstance(obj, type) and issubclass(obj, unittest.TestCase):
- return self.loadTestsFromTestCase(obj)
- elif (isinstance(obj, types.UnboundMethodType) and
- isinstance(parent, type) and
- issubclass(parent, unittest.TestCase)):
- return self.suiteClass([parent(obj.__name__)])
- elif isinstance(obj, unittest.TestSuite):
- return obj
- elif hasattr(obj, '__call__'):
- test = obj()
- if isinstance(test, unittest.TestSuite):
- return test
- elif isinstance(test, unittest.TestCase):
- return self.suiteClass([test])
- else:
- raise TypeError("calling %s returned %s, not a test" %
- (obj, test))
- else:
- raise TypeError("don't know how to make test from: %s" % obj)
-
- def loadTestsFromNames(self, names, module=None):
- """Return a suite of all tests cases found using the given sequence
- of string specifiers. See 'loadTestsFromName()'.
- """
- suites = [self.loadTestsFromName(name, module) for name in names]
- return self.suiteClass(suites)
-
- def getTestCaseNames(self, testCaseClass):
- """Return a sorted sequence of method names found within testCaseClass
- """
- def isTestMethod(attrname, testCaseClass=testCaseClass,
- prefix=self.testMethodPrefix):
- return attrname.startswith(prefix) and \
- hasattr(getattr(testCaseClass, attrname), '__call__')
- testFnNames = filter(isTestMethod, dir(testCaseClass))
- if self.sortTestMethodsUsing:
- testFnNames.sort(key=_CmpToKey(self.sortTestMethodsUsing))
- return testFnNames
-
- def discover(self, start_dir, pattern='test*.py', top_level_dir=None):
- """Find and return all test modules from the specified start
- directory, recursing into subdirectories to find them. Only test files
- that match the pattern will be loaded. (Using shell style pattern
- matching.)
-
- All test modules must be importable from the top level of the project.
- If the start directory is not the top level directory then the top
- level directory must be specified separately.
-
- If a test package name (directory with '__init__.py') matches the
- pattern then the package will be checked for a 'load_tests' function. If
- this exists then it will be called with loader, tests, pattern.
-
- If load_tests exists then discovery does *not* recurse into the package,
- load_tests is responsible for loading all tests in the package.
-
- The pattern is deliberately not stored as a loader attribute so that
- packages can continue discovery themselves. top_level_dir is stored so
- load_tests does not need to pass this argument in to loader.discover().
- """
- set_implicit_top = False
- if top_level_dir is None and self._top_level_dir is not None:
- # make top_level_dir optional if called from load_tests in a package
- top_level_dir = self._top_level_dir
- elif top_level_dir is None:
- set_implicit_top = True
- top_level_dir = start_dir
-
- top_level_dir = os.path.abspath(top_level_dir)
-
- if not top_level_dir in sys.path:
- # all test modules must be importable from the top level directory
- # should we *unconditionally* put the start directory in first
- # in sys.path to minimise likelihood of conflicts between installed
- # modules and development versions?
- sys.path.insert(0, top_level_dir)
- self._top_level_dir = top_level_dir
-
- is_not_importable = False
- if os.path.isdir(os.path.abspath(start_dir)):
- start_dir = os.path.abspath(start_dir)
- if start_dir != top_level_dir:
- is_not_importable = not os.path.isfile(os.path.join(start_dir, '__init__.py'))
- else:
- # support for discovery from dotted module names
- try:
- __import__(start_dir)
- except ImportError:
- is_not_importable = True
- else:
- the_module = sys.modules[start_dir]
- top_part = start_dir.split('.')[0]
- start_dir = os.path.abspath(os.path.dirname((the_module.__file__)))
- if set_implicit_top:
- self._top_level_dir = os.path.abspath(os.path.dirname(os.path.dirname(sys.modules[top_part].__file__)))
- sys.path.remove(top_level_dir)
-
- if is_not_importable:
- raise ImportError('Start directory is not importable: %r' % start_dir)
-
- tests = list(self._find_tests(start_dir, pattern))
- return self.suiteClass(tests)
-
- def _get_name_from_path(self, path):
- path = os.path.splitext(os.path.normpath(path))[0]
-
- _relpath = relpath(path, self._top_level_dir)
- assert not os.path.isabs(_relpath), "Path must be within the project"
- assert not _relpath.startswith('..'), "Path must be within the project"
-
- name = _relpath.replace(os.path.sep, '.')
- return name
-
- def _get_module_from_name(self, name):
- __import__(name)
- return sys.modules[name]
-
- def _match_path(self, path, full_path, pattern):
- # override this method to use alternative matching strategy
- return fnmatch(path, pattern)
-
- def _find_tests(self, start_dir, pattern):
- """Used by discovery. Yields test suites it loads."""
- paths = os.listdir(start_dir)
-
- for path in paths:
- full_path = os.path.join(start_dir, path)
- if os.path.isfile(full_path):
- if not VALID_MODULE_NAME.match(path):
- # valid Python identifiers only
- continue
- if not self._match_path(path, full_path, pattern):
- continue
- # if the test file matches, load it
- name = self._get_name_from_path(full_path)
- try:
- module = self._get_module_from_name(name)
- except:
- yield _make_failed_import_test(name, self.suiteClass)
- else:
- mod_file = os.path.abspath(getattr(module, '__file__', full_path))
- realpath = os.path.splitext(mod_file)[0]
- fullpath_noext = os.path.splitext(full_path)[0]
- if realpath.lower() != fullpath_noext.lower():
- module_dir = os.path.dirname(realpath)
- mod_name = os.path.splitext(os.path.basename(full_path))[0]
- expected_dir = os.path.dirname(full_path)
- msg = ("%r module incorrectly imported from %r. Expected %r. "
- "Is this module globally installed?")
- raise ImportError(msg % (mod_name, module_dir, expected_dir))
- yield self.loadTestsFromModule(module)
- elif os.path.isdir(full_path):
- if not os.path.isfile(os.path.join(full_path, '__init__.py')):
- continue
-
- load_tests = None
- tests = None
- if fnmatch(path, pattern):
- # only check load_tests if the package directory itself matches the filter
- name = self._get_name_from_path(full_path)
- package = self._get_module_from_name(name)
- load_tests = getattr(package, 'load_tests', None)
- tests = self.loadTestsFromModule(package, use_load_tests=False)
-
- if load_tests is None:
- if tests is not None:
- # tests loaded from package file
- yield tests
- # recurse into the package
- for test in self._find_tests(full_path, pattern):
- yield test
- else:
- try:
- yield load_tests(self, tests, pattern)
- except Exception as e:
- yield _make_failed_load_tests(package.__name__, e,
- self.suiteClass)
-
-defaultTestLoader = TestLoader()
-
-
-def _makeLoader(prefix, sortUsing, suiteClass=None):
- loader = TestLoader()
- loader.sortTestMethodsUsing = sortUsing
- loader.testMethodPrefix = prefix
- if suiteClass:
- loader.suiteClass = suiteClass
- return loader
-
-def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
- return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
-
-def makeSuite(testCaseClass, prefix='test', sortUsing=cmp,
- suiteClass=suite.TestSuite):
- return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
-
-def findTestCases(module, prefix='test', sortUsing=cmp,
- suiteClass=suite.TestSuite):
- return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
diff --git a/django/utils/unittest/main.py b/django/utils/unittest/main.py
deleted file mode 100644
index 659310babf..0000000000
--- a/django/utils/unittest/main.py
+++ /dev/null
@@ -1,241 +0,0 @@
-"""Unittest main program"""
-
-import sys
-import os
-import types
-
-from django.utils.unittest import loader, runner
-try:
- from django.utils.unittest.signals import installHandler
-except ImportError:
- installHandler = None
-
-__unittest = True
-
-FAILFAST = " -f, --failfast Stop on first failure\n"
-CATCHBREAK = " -c, --catch Catch control-C and display results\n"
-BUFFEROUTPUT = " -b, --buffer Buffer stdout and stderr during test runs\n"
-
-USAGE_AS_MAIN = """\
-Usage: %(progName)s [options] [tests]
-
-Options:
- -h, --help Show this message
- -v, --verbose Verbose output
- -q, --quiet Minimal output
-%(failfast)s%(catchbreak)s%(buffer)s
-Examples:
- %(progName)s test_module - run tests from test_module
- %(progName)s test_module.TestClass - run tests from
- test_module.TestClass
- %(progName)s test_module.TestClass.test_method - run specified test method
-
-[tests] can be a list of any number of test modules, classes and test
-methods.
-
-Alternative Usage: %(progName)s discover [options]
-
-Options:
- -v, --verbose Verbose output
-%(failfast)s%(catchbreak)s%(buffer)s -s directory Directory to start discovery ('.' default)
- -p pattern Pattern to match test files ('test*.py' default)
- -t directory Top level directory of project (default to
- start directory)
-
-For test discovery all test modules must be importable from the top
-level directory of the project.
-"""
-
-USAGE_FROM_MODULE = """\
-Usage: %(progName)s [options] [test] [...]
-
-Options:
- -h, --help Show this message
- -v, --verbose Verbose output
- -q, --quiet Minimal output
-%(failfast)s%(catchbreak)s%(buffer)s
-Examples:
- %(progName)s - run default set of tests
- %(progName)s MyTestSuite - run suite 'MyTestSuite'
- %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
- %(progName)s MyTestCase - run all 'test*' test methods
- in MyTestCase
-"""
-
-
-class TestProgram(object):
- """A command-line program that runs a set of tests; this is primarily
- for making test modules conveniently executable.
- """
- USAGE = USAGE_FROM_MODULE
-
- # defaults for testing
- failfast = catchbreak = buffer = progName = None
-
- def __init__(self, module='__main__', defaultTest=None,
- argv=None, testRunner=None,
- testLoader=loader.defaultTestLoader, exit=True,
- verbosity=1, failfast=None, catchbreak=None, buffer=None):
- if isinstance(module, basestring):
- self.module = __import__(module)
- for part in module.split('.')[1:]:
- self.module = getattr(self.module, part)
- else:
- self.module = module
- if argv is None:
- argv = sys.argv
-
- self.exit = exit
- self.verbosity = verbosity
- self.failfast = failfast
- self.catchbreak = catchbreak
- self.buffer = buffer
- self.defaultTest = defaultTest
- self.testRunner = testRunner
- self.testLoader = testLoader
- self.progName = os.path.basename(argv[0])
- self.parseArgs(argv)
- self.runTests()
-
- def usageExit(self, msg=None):
- if msg:
- print(msg)
- usage = {'progName': self.progName, 'catchbreak': '', 'failfast': '',
- 'buffer': ''}
- if self.failfast != False:
- usage['failfast'] = FAILFAST
- if self.catchbreak != False and installHandler is not None:
- usage['catchbreak'] = CATCHBREAK
- if self.buffer != False:
- usage['buffer'] = BUFFEROUTPUT
- print(self.USAGE % usage)
- sys.exit(2)
-
- def parseArgs(self, argv):
- if len(argv) > 1 and argv[1].lower() == 'discover':
- self._do_discovery(argv[2:])
- return
-
- import getopt
- long_opts = ['help', 'verbose', 'quiet', 'failfast', 'catch', 'buffer']
- try:
- options, args = getopt.getopt(argv[1:], 'hHvqfcb', long_opts)
- for opt, value in options:
- if opt in ('-h','-H','--help'):
- self.usageExit()
- if opt in ('-q','--quiet'):
- self.verbosity = 0
- if opt in ('-v','--verbose'):
- self.verbosity = 2
- if opt in ('-f','--failfast'):
- if self.failfast is None:
- self.failfast = True
- # Should this raise an exception if -f is not valid?
- if opt in ('-c','--catch'):
- if self.catchbreak is None and installHandler is not None:
- self.catchbreak = True
- # Should this raise an exception if -c is not valid?
- if opt in ('-b','--buffer'):
- if self.buffer is None:
- self.buffer = True
- # Should this raise an exception if -b is not valid?
- if len(args) == 0 and self.defaultTest is None:
- # createTests will load tests from self.module
- self.testNames = None
- elif len(args) > 0:
- self.testNames = args
- if __name__ == '__main__':
- # to support python -m unittest ...
- self.module = None
- else:
- self.testNames = (self.defaultTest,)
- self.createTests()
- except getopt.error as msg:
- self.usageExit(msg)
-
- def createTests(self):
- if self.testNames is None:
- self.test = self.testLoader.loadTestsFromModule(self.module)
- else:
- self.test = self.testLoader.loadTestsFromNames(self.testNames,
- self.module)
-
- def _do_discovery(self, argv, Loader=loader.TestLoader):
- # handle command line args for test discovery
- self.progName = '%s discover' % self.progName
- import optparse
- parser = optparse.OptionParser()
- parser.prog = self.progName
- parser.add_option('-v', '--verbose', dest='verbose', default=False,
- help='Verbose output', action='store_true')
- if self.failfast != False:
- parser.add_option('-f', '--failfast', dest='failfast', default=False,
- help='Stop on first fail or error',
- action='store_true')
- if self.catchbreak != False and installHandler is not None:
- parser.add_option('-c', '--catch', dest='catchbreak', default=False,
- help='Catch ctrl-C and display results so far',
- action='store_true')
- if self.buffer != False:
- parser.add_option('-b', '--buffer', dest='buffer', default=False,
- help='Buffer stdout and stderr during tests',
- action='store_true')
- parser.add_option('-s', '--start-directory', dest='start', default='.',
- help="Directory to start discovery ('.' default)")
- parser.add_option('-p', '--pattern', dest='pattern', default='test*.py',
- help="Pattern to match tests ('test*.py' default)")
- parser.add_option('-t', '--top-level-directory', dest='top', default=None,
- help='Top level directory of project (defaults to start directory)')
-
- options, args = parser.parse_args(argv)
- if len(args) > 3:
- self.usageExit()
-
- for name, value in zip(('start', 'pattern', 'top'), args):
- setattr(options, name, value)
-
- # only set options from the parsing here
- # if they weren't set explicitly in the constructor
- if self.failfast is None:
- self.failfast = options.failfast
- if self.catchbreak is None and installHandler is not None:
- self.catchbreak = options.catchbreak
- if self.buffer is None:
- self.buffer = options.buffer
-
- if options.verbose:
- self.verbosity = 2
-
- start_dir = options.start
- pattern = options.pattern
- top_level_dir = options.top
-
- loader = Loader()
- self.test = loader.discover(start_dir, pattern, top_level_dir)
-
- def runTests(self):
- if self.catchbreak:
- installHandler()
- if self.testRunner is None:
- self.testRunner = runner.TextTestRunner
- if isinstance(self.testRunner, (type, types.ClassType)):
- try:
- testRunner = self.testRunner(verbosity=self.verbosity,
- failfast=self.failfast,
- buffer=self.buffer)
- except TypeError:
- # didn't accept the verbosity, buffer or failfast arguments
- testRunner = self.testRunner()
- else:
- # it is assumed to be a TestRunner instance
- testRunner = self.testRunner
- self.result = testRunner.run(self.test)
- if self.exit:
- sys.exit(not self.result.wasSuccessful())
-
-main = TestProgram
-
-def main_():
- TestProgram.USAGE = USAGE_AS_MAIN
- main(module=None)
-
diff --git a/django/utils/unittest/result.py b/django/utils/unittest/result.py
deleted file mode 100644
index 2d2a1ada95..0000000000
--- a/django/utils/unittest/result.py
+++ /dev/null
@@ -1,183 +0,0 @@
-"""Test result object"""
-
-import sys
-import traceback
-import unittest
-
-from StringIO import StringIO
-
-from django.utils.unittest import util
-from django.utils.unittest.compatibility import wraps
-
-__unittest = True
-
-def failfast(method):
- @wraps(method)
- def inner(self, *args, **kw):
- if getattr(self, 'failfast', False):
- self.stop()
- return method(self, *args, **kw)
- return inner
-
-
-STDOUT_LINE = '\nStdout:\n%s'
-STDERR_LINE = '\nStderr:\n%s'
-
-class TestResult(unittest.TestResult):
- """Holder for test result information.
-
- Test results are automatically managed by the TestCase and TestSuite
- classes, and do not need to be explicitly manipulated by writers of tests.
-
- Each instance holds the total number of tests run, and collections of
- failures and errors that occurred among those test runs. The collections
- contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
- formatted traceback of the error that occurred.
- """
- _previousTestClass = None
- _moduleSetUpFailed = False
-
- def __init__(self):
- self.failfast = False
- self.failures = []
- self.errors = []
- self.testsRun = 0
- self.skipped = []
- self.expectedFailures = []
- self.unexpectedSuccesses = []
- self.shouldStop = False
- self.buffer = False
- self._stdout_buffer = None
- self._stderr_buffer = None
- self._original_stdout = sys.stdout
- self._original_stderr = sys.stderr
- self._mirrorOutput = False
-
- def startTest(self, test):
- "Called when the given test is about to be run"
- self.testsRun += 1
- self._mirrorOutput = False
- if self.buffer:
- if self._stderr_buffer is None:
- self._stderr_buffer = StringIO()
- self._stdout_buffer = StringIO()
- sys.stdout = self._stdout_buffer
- sys.stderr = self._stderr_buffer
-
- def startTestRun(self):
- """Called once before any tests are executed.
-
- See startTest for a method called before each test.
- """
-
- def stopTest(self, test):
- """Called when the given test has been run"""
- if self.buffer:
- if self._mirrorOutput:
- output = sys.stdout.getvalue()
- error = sys.stderr.getvalue()
- if output:
- if not output.endswith('\n'):
- output += '\n'
- self._original_stdout.write(STDOUT_LINE % output)
- if error:
- if not error.endswith('\n'):
- error += '\n'
- self._original_stderr.write(STDERR_LINE % error)
-
- sys.stdout = self._original_stdout
- sys.stderr = self._original_stderr
- self._stdout_buffer.seek(0)
- self._stdout_buffer.truncate()
- self._stderr_buffer.seek(0)
- self._stderr_buffer.truncate()
- self._mirrorOutput = False
-
-
- def stopTestRun(self):
- """Called once after all tests are executed.
-
- See stopTest for a method called after each test.
- """
-
- @failfast
- def addError(self, test, err):
- """Called when an error has occurred. 'err' is a tuple of values as
- returned by sys.exc_info().
- """
- self.errors.append((test, self._exc_info_to_string(err, test)))
- self._mirrorOutput = True
-
- @failfast
- def addFailure(self, test, err):
- """Called when an error has occurred. 'err' is a tuple of values as
- returned by sys.exc_info()."""
- self.failures.append((test, self._exc_info_to_string(err, test)))
- self._mirrorOutput = True
-
- def addSuccess(self, test):
- "Called when a test has completed successfully"
- pass
-
- def addSkip(self, test, reason):
- """Called when a test is skipped."""
- self.skipped.append((test, reason))
-
- def addExpectedFailure(self, test, err):
- """Called when an expected failure/error occured."""
- self.expectedFailures.append(
- (test, self._exc_info_to_string(err, test)))
-
- @failfast
- def addUnexpectedSuccess(self, test):
- """Called when a test was expected to fail, but succeed."""
- self.unexpectedSuccesses.append(test)
-
- def wasSuccessful(self):
- "Tells whether or not this result was a success"
- return (len(self.failures) + len(self.errors) == 0)
-
- def stop(self):
- "Indicates that the tests should be aborted"
- self.shouldStop = True
-
- def _exc_info_to_string(self, err, test):
- """Converts a sys.exc_info()-style tuple of values into a string."""
- exctype, value, tb = err
- # Skip test runner traceback levels
- while tb and self._is_relevant_tb_level(tb):
- tb = tb.tb_next
- if exctype is test.failureException:
- # Skip assert*() traceback levels
- length = self._count_relevant_tb_levels(tb)
- msgLines = traceback.format_exception(exctype, value, tb, length)
- else:
- msgLines = traceback.format_exception(exctype, value, tb)
-
- if self.buffer:
- output = sys.stdout.getvalue()
- error = sys.stderr.getvalue()
- if output:
- if not output.endswith('\n'):
- output += '\n'
- msgLines.append(STDOUT_LINE % output)
- if error:
- if not error.endswith('\n'):
- error += '\n'
- msgLines.append(STDERR_LINE % error)
- return ''.join(msgLines)
-
- def _is_relevant_tb_level(self, tb):
- return '__unittest' in tb.tb_frame.f_globals
-
- def _count_relevant_tb_levels(self, tb):
- length = 0
- while tb and not self._is_relevant_tb_level(tb):
- length += 1
- tb = tb.tb_next
- return length
-
- def __repr__(self):
- return "<%s run=%i errors=%i failures=%i>" % \
- (util.strclass(self.__class__), self.testsRun, len(self.errors),
- len(self.failures))
diff --git a/django/utils/unittest/runner.py b/django/utils/unittest/runner.py
deleted file mode 100644
index 242173ee31..0000000000
--- a/django/utils/unittest/runner.py
+++ /dev/null
@@ -1,206 +0,0 @@
-"""Running tests"""
-
-import sys
-import time
-import unittest
-
-from django.utils.unittest import result
-
-try:
- from django.utils.unittest.signals import registerResult
-except ImportError:
- def registerResult(_):
- pass
-
-__unittest = True
-
-
-class _WritelnDecorator(object):
- """Used to decorate file-like objects with a handy 'writeln' method"""
- def __init__(self,stream):
- self.stream = stream
-
- def __getattr__(self, attr):
- if attr in ('stream', '__getstate__'):
- raise AttributeError(attr)
- return getattr(self.stream,attr)
-
- def writeln(self, arg=None):
- if arg:
- self.write(arg)
- self.write('\n') # text-mode streams translate to \r\n if needed
-
-
-class TextTestResult(result.TestResult):
- """A test result class that can print formatted text results to a stream.
-
- Used by TextTestRunner.
- """
- separator1 = '=' * 70
- separator2 = '-' * 70
-
- def __init__(self, stream, descriptions, verbosity):
- super(TextTestResult, self).__init__()
- self.stream = stream
- self.showAll = verbosity > 1
- self.dots = verbosity == 1
- self.descriptions = descriptions
-
- def getDescription(self, test):
- doc_first_line = test.shortDescription()
- if self.descriptions and doc_first_line:
- return '\n'.join((str(test), doc_first_line))
- else:
- return str(test)
-
- def startTest(self, test):
- super(TextTestResult, self).startTest(test)
- if self.showAll:
- self.stream.write(self.getDescription(test))
- self.stream.write(" ... ")
- self.stream.flush()
-
- def addSuccess(self, test):
- super(TextTestResult, self).addSuccess(test)
- if self.showAll:
- self.stream.writeln("ok")
- elif self.dots:
- self.stream.write('.')
- self.stream.flush()
-
- def addError(self, test, err):
- super(TextTestResult, self).addError(test, err)
- if self.showAll:
- self.stream.writeln("ERROR")
- elif self.dots:
- self.stream.write('E')
- self.stream.flush()
-
- def addFailure(self, test, err):
- super(TextTestResult, self).addFailure(test, err)
- if self.showAll:
- self.stream.writeln("FAIL")
- elif self.dots:
- self.stream.write('F')
- self.stream.flush()
-
- def addSkip(self, test, reason):
- super(TextTestResult, self).addSkip(test, reason)
- if self.showAll:
- self.stream.writeln("skipped %r" % (reason,))
- elif self.dots:
- self.stream.write("s")
- self.stream.flush()
-
- def addExpectedFailure(self, test, err):
- super(TextTestResult, self).addExpectedFailure(test, err)
- if self.showAll:
- self.stream.writeln("expected failure")
- elif self.dots:
- self.stream.write("x")
- self.stream.flush()
-
- def addUnexpectedSuccess(self, test):
- super(TextTestResult, self).addUnexpectedSuccess(test)
- if self.showAll:
- self.stream.writeln("unexpected success")
- elif self.dots:
- self.stream.write("u")
- self.stream.flush()
-
- def printErrors(self):
- if self.dots or self.showAll:
- self.stream.writeln()
- self.printErrorList('ERROR', self.errors)
- self.printErrorList('FAIL', self.failures)
-
- def printErrorList(self, flavour, errors):
- for test, err in errors:
- self.stream.writeln(self.separator1)
- self.stream.writeln("%s: %s" % (flavour, self.getDescription(test)))
- self.stream.writeln(self.separator2)
- self.stream.writeln("%s" % err)
-
- def stopTestRun(self):
- super(TextTestResult, self).stopTestRun()
- self.printErrors()
-
-
-class TextTestRunner(unittest.TextTestRunner):
- """A test runner class that displays results in textual form.
-
- It prints out the names of tests as they are run, errors as they
- occur, and a summary of the results at the end of the test run.
- """
- resultclass = TextTestResult
-
- def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1,
- failfast=False, buffer=False, resultclass=None):
- self.stream = _WritelnDecorator(stream)
- self.descriptions = descriptions
- self.verbosity = verbosity
- self.failfast = failfast
- self.buffer = buffer
- if resultclass is not None:
- self.resultclass = resultclass
-
- def _makeResult(self):
- return self.resultclass(self.stream, self.descriptions, self.verbosity)
-
- def run(self, test):
- "Run the given test case or test suite."
- result = self._makeResult()
- result.failfast = self.failfast
- result.buffer = self.buffer
- registerResult(result)
-
- startTime = time.time()
- startTestRun = getattr(result, 'startTestRun', None)
- if startTestRun is not None:
- startTestRun()
- try:
- test(result)
- finally:
- stopTestRun = getattr(result, 'stopTestRun', None)
- if stopTestRun is not None:
- stopTestRun()
- else:
- result.printErrors()
- stopTime = time.time()
- timeTaken = stopTime - startTime
- if hasattr(result, 'separator2'):
- self.stream.writeln(result.separator2)
- run = result.testsRun
- self.stream.writeln("Ran %d test%s in %.3fs" %
- (run, run != 1 and "s" or "", timeTaken))
- self.stream.writeln()
-
- expectedFails = unexpectedSuccesses = skipped = 0
- try:
- results = map(len, (result.expectedFailures,
- result.unexpectedSuccesses,
- result.skipped))
- expectedFails, unexpectedSuccesses, skipped = results
- except AttributeError:
- pass
- infos = []
- if not result.wasSuccessful():
- self.stream.write("FAILED")
- failed, errored = map(len, (result.failures, result.errors))
- if failed:
- infos.append("failures=%d" % failed)
- if errored:
- infos.append("errors=%d" % errored)
- else:
- self.stream.write("OK")
- if skipped:
- infos.append("skipped=%d" % skipped)
- if expectedFails:
- infos.append("expected failures=%d" % expectedFails)
- if unexpectedSuccesses:
- infos.append("unexpected successes=%d" % unexpectedSuccesses)
- if infos:
- self.stream.writeln(" (%s)" % (", ".join(infos),))
- else:
- self.stream.write("\n")
- return result
diff --git a/django/utils/unittest/signals.py b/django/utils/unittest/signals.py
deleted file mode 100644
index f1731ea13d..0000000000
--- a/django/utils/unittest/signals.py
+++ /dev/null
@@ -1,57 +0,0 @@
-import signal
-import weakref
-
-from django.utils.unittest.compatibility import wraps
-
-__unittest = True
-
-
-class _InterruptHandler(object):
- def __init__(self, default_handler):
- self.called = False
- self.default_handler = default_handler
-
- def __call__(self, signum, frame):
- installed_handler = signal.getsignal(signal.SIGINT)
- if installed_handler is not self:
- # if we aren't the installed handler, then delegate immediately
- # to the default handler
- self.default_handler(signum, frame)
-
- if self.called:
- self.default_handler(signum, frame)
- self.called = True
- for result in _results.keys():
- result.stop()
-
-_results = weakref.WeakKeyDictionary()
-def registerResult(result):
- _results[result] = 1
-
-def removeResult(result):
- return bool(_results.pop(result, None))
-
-_interrupt_handler = None
-def installHandler():
- global _interrupt_handler
- if _interrupt_handler is None:
- default_handler = signal.getsignal(signal.SIGINT)
- _interrupt_handler = _InterruptHandler(default_handler)
- signal.signal(signal.SIGINT, _interrupt_handler)
-
-
-def removeHandler(method=None):
- if method is not None:
- @wraps(method)
- def inner(*args, **kwargs):
- initial = signal.getsignal(signal.SIGINT)
- removeHandler()
- try:
- return method(*args, **kwargs)
- finally:
- signal.signal(signal.SIGINT, initial)
- return inner
-
- global _interrupt_handler
- if _interrupt_handler is not None:
- signal.signal(signal.SIGINT, _interrupt_handler.default_handler)
diff --git a/django/utils/unittest/suite.py b/django/utils/unittest/suite.py
deleted file mode 100644
index da8ac2e2a8..0000000000
--- a/django/utils/unittest/suite.py
+++ /dev/null
@@ -1,287 +0,0 @@
-"""TestSuite"""
-
-import sys
-import unittest
-from django.utils.unittest import case, util
-
-__unittest = True
-
-
-class BaseTestSuite(unittest.TestSuite):
- """A simple test suite that doesn't provide class or module shared fixtures.
- """
- def __init__(self, tests=()):
- self._tests = []
- self.addTests(tests)
-
- def __repr__(self):
- return "<%s tests=%s>" % (util.strclass(self.__class__), list(self))
-
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- return list(self) == list(other)
-
- def __ne__(self, other):
- return not self == other
-
- # Can't guarantee hash invariant, so flag as unhashable
- __hash__ = None
-
- def __iter__(self):
- return iter(self._tests)
-
- def countTestCases(self):
- cases = 0
- for test in self:
- cases += test.countTestCases()
- return cases
-
- def addTest(self, test):
- # sanity checks
- if not hasattr(test, '__call__'):
- raise TypeError("%r is not callable" % (repr(test),))
- if isinstance(test, type) and issubclass(test,
- (case.TestCase, TestSuite)):
- raise TypeError("TestCases and TestSuites must be instantiated "
- "before passing them to addTest()")
- self._tests.append(test)
-
- def addTests(self, tests):
- if isinstance(tests, basestring):
- raise TypeError("tests must be an iterable of tests, not a string")
- for test in tests:
- self.addTest(test)
-
- def run(self, result):
- for test in self:
- if result.shouldStop:
- break
- test(result)
- return result
-
- def __call__(self, *args, **kwds):
- return self.run(*args, **kwds)
-
- def debug(self):
- """Run the tests without collecting errors in a TestResult"""
- for test in self:
- test.debug()
-
-
-class TestSuite(BaseTestSuite):
- """A test suite is a composite test consisting of a number of TestCases.
-
- For use, create an instance of TestSuite, then add test case instances.
- When all tests have been added, the suite can be passed to a test
- runner, such as TextTestRunner. It will run the individual test cases
- in the order in which they were added, aggregating the results. When
- subclassing, do not forget to call the base class constructor.
- """
-
-
- def run(self, result):
- self._wrapped_run(result)
- self._tearDownPreviousClass(None, result)
- self._handleModuleTearDown(result)
- return result
-
- def debug(self):
- """Run the tests without collecting errors in a TestResult"""
- debug = _DebugResult()
- self._wrapped_run(debug, True)
- self._tearDownPreviousClass(None, debug)
- self._handleModuleTearDown(debug)
-
- ################################
- # private methods
- def _wrapped_run(self, result, debug=False):
- for test in self:
- if result.shouldStop:
- break
-
- if _isnotsuite(test):
- self._tearDownPreviousClass(test, result)
- self._handleModuleFixture(test, result)
- self._handleClassSetUp(test, result)
- result._previousTestClass = test.__class__
-
- if (getattr(test.__class__, '_classSetupFailed', False) or
- getattr(result, '_moduleSetUpFailed', False)):
- continue
-
- if hasattr(test, '_wrapped_run'):
- test._wrapped_run(result, debug)
- elif not debug:
- test(result)
- else:
- test.debug()
-
- def _handleClassSetUp(self, test, result):
- previousClass = getattr(result, '_previousTestClass', None)
- currentClass = test.__class__
- if currentClass == previousClass:
- return
- if result._moduleSetUpFailed:
- return
- if getattr(currentClass, "__unittest_skip__", False):
- return
-
- try:
- currentClass._classSetupFailed = False
- except TypeError:
- # test may actually be a function
- # so its class will be a builtin-type
- pass
-
- setUpClass = getattr(currentClass, 'setUpClass', None)
- if setUpClass is not None:
- try:
- setUpClass()
- except Exception as e:
- if isinstance(result, _DebugResult):
- raise
- currentClass._classSetupFailed = True
- className = util.strclass(currentClass)
- errorName = 'setUpClass (%s)' % className
- self._addClassOrModuleLevelException(result, e, errorName)
-
- def _get_previous_module(self, result):
- previousModule = None
- previousClass = getattr(result, '_previousTestClass', None)
- if previousClass is not None:
- previousModule = previousClass.__module__
- return previousModule
-
-
- def _handleModuleFixture(self, test, result):
- previousModule = self._get_previous_module(result)
- currentModule = test.__class__.__module__
- if currentModule == previousModule:
- return
-
- self._handleModuleTearDown(result)
-
-
- result._moduleSetUpFailed = False
- try:
- module = sys.modules[currentModule]
- except KeyError:
- return
- setUpModule = getattr(module, 'setUpModule', None)
- if setUpModule is not None:
- try:
- setUpModule()
- except Exception as e:
- if isinstance(result, _DebugResult):
- raise
- result._moduleSetUpFailed = True
- errorName = 'setUpModule (%s)' % currentModule
- self._addClassOrModuleLevelException(result, e, errorName)
-
- def _addClassOrModuleLevelException(self, result, exception, errorName):
- error = _ErrorHolder(errorName)
- addSkip = getattr(result, 'addSkip', None)
- if addSkip is not None and isinstance(exception, case.SkipTest):
- addSkip(error, str(exception))
- else:
- result.addError(error, sys.exc_info())
-
- def _handleModuleTearDown(self, result):
- previousModule = self._get_previous_module(result)
- if previousModule is None:
- return
- if result._moduleSetUpFailed:
- return
-
- try:
- module = sys.modules[previousModule]
- except KeyError:
- return
-
- tearDownModule = getattr(module, 'tearDownModule', None)
- if tearDownModule is not None:
- try:
- tearDownModule()
- except Exception as e:
- if isinstance(result, _DebugResult):
- raise
- errorName = 'tearDownModule (%s)' % previousModule
- self._addClassOrModuleLevelException(result, e, errorName)
-
- def _tearDownPreviousClass(self, test, result):
- previousClass = getattr(result, '_previousTestClass', None)
- currentClass = test.__class__
- if currentClass == previousClass:
- return
- if getattr(previousClass, '_classSetupFailed', False):
- return
- if getattr(result, '_moduleSetUpFailed', False):
- return
- if getattr(previousClass, "__unittest_skip__", False):
- return
-
- tearDownClass = getattr(previousClass, 'tearDownClass', None)
- if tearDownClass is not None:
- try:
- tearDownClass()
- except Exception as e:
- if isinstance(result, _DebugResult):
- raise
- className = util.strclass(previousClass)
- errorName = 'tearDownClass (%s)' % className
- self._addClassOrModuleLevelException(result, e, errorName)
-
-
-class _ErrorHolder(object):
- """
- Placeholder for a TestCase inside a result. As far as a TestResult
- is concerned, this looks exactly like a unit test. Used to insert
- arbitrary errors into a test suite run.
- """
- # Inspired by the ErrorHolder from Twisted:
- # http://twistedmatrix.com/trac/browser/trunk/twisted/trial/runner.py
-
- # attribute used by TestResult._exc_info_to_string
- failureException = None
-
- def __init__(self, description):
- self.description = description
-
- def id(self):
- return self.description
-
- def shortDescription(self):
- return None
-
- def __repr__(self):
- return "<ErrorHolder description=%r>" % (self.description,)
-
- def __str__(self):
- return self.id()
-
- def run(self, result):
- # could call result.addError(...) - but this test-like object
- # shouldn't be run anyway
- pass
-
- def __call__(self, result):
- return self.run(result)
-
- def countTestCases(self):
- return 0
-
-def _isnotsuite(test):
- "A crude way to tell apart testcases and suites with duck-typing"
- try:
- iter(test)
- except TypeError:
- return True
- return False
-
-
-class _DebugResult(object):
- "Used by the TestSuite to hold previous class when running in debug."
- _previousTestClass = None
- _moduleSetUpFailed = False
- shouldStop = False
diff --git a/django/utils/unittest/util.py b/django/utils/unittest/util.py
deleted file mode 100644
index c45d008cc8..0000000000
--- a/django/utils/unittest/util.py
+++ /dev/null
@@ -1,99 +0,0 @@
-"""Various utility functions."""
-
-__unittest = True
-
-
-_MAX_LENGTH = 80
-def safe_repr(obj, short=False):
- try:
- result = repr(obj)
- except Exception:
- result = object.__repr__(obj)
- if not short or len(result) < _MAX_LENGTH:
- return result
- return result[:_MAX_LENGTH] + ' [truncated]...'
-
-def safe_str(obj):
- try:
- return str(obj)
- except Exception:
- return object.__str__(obj)
-
-def strclass(cls):
- return "%s.%s" % (cls.__module__, cls.__name__)
-
-def sorted_list_difference(expected, actual):
- """Finds elements in only one or the other of two, sorted input lists.
-
- Returns a two-element tuple of lists. The first list contains those
- elements in the "expected" list but not in the "actual" list, and the
- second contains those elements in the "actual" list but not in the
- "expected" list. Duplicate elements in either input list are ignored.
- """
- i = j = 0
- missing = []
- unexpected = []
- while True:
- try:
- e = expected[i]
- a = actual[j]
- if e < a:
- missing.append(e)
- i += 1
- while expected[i] == e:
- i += 1
- elif e > a:
- unexpected.append(a)
- j += 1
- while actual[j] == a:
- j += 1
- else:
- i += 1
- try:
- while expected[i] == e:
- i += 1
- finally:
- j += 1
- while actual[j] == a:
- j += 1
- except IndexError:
- missing.extend(expected[i:])
- unexpected.extend(actual[j:])
- break
- return missing, unexpected
-
-def unorderable_list_difference(expected, actual, ignore_duplicate=False):
- """Same behavior as sorted_list_difference but
- for lists of unorderable items (like dicts).
-
- As it does a linear search per item (remove) it
- has O(n*n) performance.
- """
- missing = []
- unexpected = []
- while expected:
- item = expected.pop()
- try:
- actual.remove(item)
- except ValueError:
- missing.append(item)
- if ignore_duplicate:
- for lst in expected, actual:
- try:
- while True:
- lst.remove(item)
- except ValueError:
- pass
- if ignore_duplicate:
- while actual:
- item = actual.pop()
- unexpected.append(item)
- try:
- while True:
- actual.remove(item)
- except ValueError:
- pass
- return missing, unexpected
-
- # anything left in actual is unexpected
- return missing, actual
diff --git a/django/views/defaults.py b/django/views/defaults.py
index c8a62fc753..e9d0f16a33 100644
--- a/django/views/defaults.py
+++ b/django/views/defaults.py
@@ -83,6 +83,6 @@ def shortcut(request, content_type_id, object_id):
warnings.warn(
"django.views.defaults.shortcut will be removed in Django 1.8. "
"Import it from django.contrib.contenttypes.views instead.",
- PendingDeprecationWarning, stacklevel=2)
+ DeprecationWarning, stacklevel=2)
from django.contrib.contenttypes.views import shortcut as real_shortcut
return real_shortcut(request, content_type_id, object_id)
diff --git a/django/views/generic/edit.py b/django/views/generic/edit.py
index fccacf0bd3..0a8301f0db 100644
--- a/django/views/generic/edit.py
+++ b/django/views/generic/edit.py
@@ -113,7 +113,7 @@ class ModelFormMixin(FormMixin, SingleObjectMixin):
if self.fields is None:
warnings.warn("Using ModelFormMixin (base class of %s) without "
"the 'fields' attribute is deprecated." % self.__class__.__name__,
- PendingDeprecationWarning)
+ DeprecationWarning)
return model_forms.modelform_factory(model, fields=self.fields)
diff --git a/django/views/static.py b/django/views/static.py
index 12af130796..470999bb9d 100644
--- a/django/views/static.py
+++ b/django/views/static.py
@@ -14,8 +14,8 @@ try:
except ImportError: # Python 2
from urllib import unquote
-from django.http import (CompatibleStreamingHttpResponse, Http404,
- HttpResponse, HttpResponseRedirect, HttpResponseNotModified)
+from django.http import (Http404, HttpResponse, HttpResponseRedirect,
+ HttpResponseNotModified, StreamingHttpResponse)
from django.template import loader, Template, Context, TemplateDoesNotExist
from django.utils.http import http_date, parse_http_date
from django.utils.translation import ugettext as _, ugettext_noop
@@ -63,8 +63,8 @@ def serve(request, path, document_root=None, show_indexes=False):
return HttpResponseNotModified()
content_type, encoding = mimetypes.guess_type(fullpath)
content_type = content_type or 'application/octet-stream'
- response = CompatibleStreamingHttpResponse(open(fullpath, 'rb'),
- content_type=content_type)
+ response = StreamingHttpResponse(open(fullpath, 'rb'),
+ content_type=content_type)
response["Last-Modified"] = http_date(statobj.st_mtime)
if stat.S_ISREG(statobj.st_mode):
response["Content-Length"] = statobj.st_size
diff --git a/docs/faq/install.txt b/docs/faq/install.txt
index d221f93d02..be45012961 100644
--- a/docs/faq/install.txt
+++ b/docs/faq/install.txt
@@ -16,8 +16,8 @@ How do I get started?
What are Django's prerequisites?
--------------------------------
-Django requires Python, specifically Python 2.6.5 - 2.7.x, or 3.2.3 and above.
-No other Python libraries are required for basic Django usage.
+Django requires Python, specifically Python 2.7 or 3.2 and above. No other
+Python libraries are required for basic Django usage.
For a development environment -- if you just want to experiment with Django --
you don't need to have a separate Web server installed; Django comes with its
@@ -38,22 +38,6 @@ PostgreSQL fans, and MySQL_, `SQLite 3`_, and Oracle_ are also supported.
.. _`SQLite 3`: http://www.sqlite.org/
.. _Oracle: http://www.oracle.com/
-Do I lose anything by using Python 2.6 versus newer Python versions, such as Python 2.7?
-----------------------------------------------------------------------------------------
-
-Not in the core framework. Currently, Django itself officially supports
-Python 2.6 (2.6.5 or higher), 2.7, 3.2.3 or higher. However, newer versions of
-Python are often faster, have more features, and are better supported. If you
-use a newer version of Python you will also have access to some APIs that
-aren't available under older versions of Python.
-
-Third-party applications for use with Django are, of course, free to set their
-own version requirements.
-
-All else being equal, we recommend that you use the latest 2.7 or 3.x release.
-This will let you take advantage of the numerous improvements and optimizations
-to the Python language since version 2.6.
-
What Python version can I use with Django?
------------------------------------------
@@ -65,20 +49,35 @@ Django version Python versions
1.2 2.4, 2.5, 2.6, 2.7
1.3 2.4, 2.5, 2.6, 2.7
1.4 2.5, 2.6, 2.7
-1.5 2.6.5, 2.7 and 3.2.3, 3.3 (experimental)
-**1.6** **2.6.5, 2.7** and **3.2.3, 3.3**
-*1.7 (future)* *2.7, 3.3 (to be confirmed)*
+1.5 2.6, 2.7 and 3.2, 3.3 (experimental)
+1.6 2.6, 2.7 and 3.2, 3.3
+**1.7** **2.7** and **3.2, 3.3**
============== ===============
-Can I use Django with Python 3?
--------------------------------
+For a given series of Python versions, only the latest release is officially
+supported. For instance, at the time of writing (July 1st, 2013), the latest
+release in the 2.7 series is 2.7.5.
-Yes, you can!
-
-Django 1.5 introduced experimental support for Python 3.2.3 and above.
+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`.
+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.
+
+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.
+
+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.
+Third-party applications for use with Django are, of course, free to set their
+own version requirements.
Will Django run under shared hosting (like TextDrive or Dreamhost)?
-------------------------------------------------------------------
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index 9672746717..b0f5566cb3 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -295,7 +295,7 @@ these changes.
:class:`~django.template.response.TemplateResponse`, will be removed.
``content_type`` should be used instead. This also applies to the
:func:`~django.shortcuts.render_to_response` shortcut and
- the sitemamp views, :func:`~django.contrib.sitemaps.views.index` and
+ the sitemap views, :func:`~django.contrib.sitemaps.views.index` and
:func:`~django.contrib.sitemaps.views.sitemap`.
* When :class:`~django.http.HttpResponse` is instantiated with an iterator,
@@ -404,6 +404,16 @@ these changes.
forms for ManyToMany model fields will not be performed by Django anymore
either at the model or forms layer.
+* The ``Model._meta.get_(add|change|delete)_permission`` methods will
+ be removed.
+
+1.9
+---
+
+* ``django.utils.dictconfig`` will be removed.
+
+* ``django.utils.unittest`` will be removed.
+
2.0
---
diff --git a/docs/intro/install.txt b/docs/intro/install.txt
index 3cbc8d88ab..3ef59dcafb 100644
--- a/docs/intro/install.txt
+++ b/docs/intro/install.txt
@@ -9,10 +9,9 @@ that'll work while you walk through the introduction.
Install Python
--------------
-Being a Python Web framework, Django requires Python. It works with any Python
-version from 2.6.5 to 2.7. It also features experimental support for versions
-3.2 and 3.3. All these versions of Python include a lightweight database
-called SQLite_ so you won't need to set up a database just yet.
+Being a Python Web framework, Django requires Python. It works with Python 2.7,
+3.2 or 3.3. All these versions of Python include a lightweight database called
+SQLite_ so you won't need to set up a database just yet.
.. _sqlite: http://sqlite.org/
@@ -29,8 +28,8 @@ probably already have it installed.
You can verify that Python is installed by typing ``python`` from your shell;
you should see something like::
- Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48)
- [GCC 4.4.5] on linux2
+ Python 2.7.3 (default, Jan 2 2013, 13:56:14)
+ [GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
diff --git a/docs/ref/contrib/auth.txt b/docs/ref/contrib/auth.txt
index afbc6ec048..dfda8add4b 100644
--- a/docs/ref/contrib/auth.txt
+++ b/docs/ref/contrib/auth.txt
@@ -218,20 +218,6 @@ Methods
Sends an email to the user. If ``from_email`` is ``None``, Django uses
the :setting:`DEFAULT_FROM_EMAIL`.
- .. method:: get_profile()
-
- .. deprecated:: 1.5
- With the introduction of :ref:`custom User models <auth-custom-user>`,
- the use of :setting:`AUTH_PROFILE_MODULE` to define a single profile
- model is no longer supported. See the
- :doc:`Django 1.5 release notes</releases/1.5>` for more information.
-
- Returns a site-specific profile for this user. Raises
- ``django.contrib.auth.models.SiteProfileNotAvailable`` if the
- current site doesn't allow profiles, or
- :exc:`django.core.exceptions.ObjectDoesNotExist` if the user does not
- have a profile.
-
Manager methods
---------------
diff --git a/docs/ref/contrib/contenttypes.txt b/docs/ref/contrib/contenttypes.txt
index de9c5dcbd6..199401c64a 100644
--- a/docs/ref/contrib/contenttypes.txt
+++ b/docs/ref/contrib/contenttypes.txt
@@ -506,9 +506,9 @@ information.
Returns a ``GenericInlineFormSet`` using
:func:`~django.forms.models.modelformset_factory`.
- You must provide ``ct_field`` and ``object_id`` if they different from the
- defaults, ``content_type`` and ``object_id`` respectively. Other parameters
- are similar to those documented in
+ You must provide ``ct_field`` and ``fk_field`` if they are different from
+ the defaults, ``content_type`` and ``object_id`` respectively. Other
+ parameters are similar to those documented in
:func:`~django.forms.models.modelformset_factory` and
:func:`~django.forms.models.inlineformset_factory`.
diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt
index c2c11e6db4..caee368e63 100644
--- a/docs/ref/django-admin.txt
+++ b/docs/ref/django-admin.txt
@@ -102,18 +102,6 @@ is compatible with the current version of Django.
Upon finding things that are incompatible or require notifying the user, it
issues a series of warnings.
-cleanup
--------
-
-.. django-admin:: cleanup
-
-Can be run as a cronjob or directly to clean out old data from the database
-(only expired sessions at the moment).
-
-.. versionchanged:: 1.5
-
- :djadmin:`cleanup` is deprecated. Use :djadmin:`clearsessions` instead.
-
compilemessages
---------------
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
index 2788143899..6fd8a42dee 100644
--- a/docs/ref/models/querysets.txt
+++ b/docs/ref/models/querysets.txt
@@ -764,8 +764,6 @@ You can refer to any :class:`~django.db.models.ForeignKey` or
:class:`~django.db.models.OneToOneField` relation in the list of fields
passed to ``select_related()``. This includes foreign keys that have
``null=True`` (which are omitted in a no-parameter ``select_related()`` call).
-It's an error to use both a list of fields and the ``depth`` parameter in the
-same ``select_related()`` call; they are conflicting options.
You can also refer to the reverse direction of a
:class:`~django.db.models.OneToOneField` in the list of fields passed to
@@ -781,20 +779,6 @@ If you need to clear the list of related fields added by past calls of
>>> without_relations = queryset.select_related(None)
-.. deprecated:: 1.5
- The ``depth`` parameter to ``select_related()`` has been deprecated. You
- should replace it with the use of the ``(*fields)`` listing specific
- related fields instead as documented above.
-
-A depth limit of relationships to follow can also be specified::
-
- b = Book.objects.select_related(depth=1).get(id=4)
- p = b.author # Doesn't hit the database.
- c = p.hometown # Requires a database call.
-
-A :class:`~django.db.models.OneToOneField` is not traversed in the reverse
-direction if you are performing a depth-based ``select_related()`` call.
-
prefetch_related
~~~~~~~~~~~~~~~~
diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt
index 578418b4ee..f1c5702d36 100644
--- a/docs/ref/request-response.txt
+++ b/docs/ref/request-response.txt
@@ -555,28 +555,12 @@ file-like object::
Passing iterators
~~~~~~~~~~~~~~~~~
-Finally, you can pass ``HttpResponse`` an iterator rather than strings. If you
-use this technique, the iterator should return strings.
+Finally, you can pass ``HttpResponse`` an iterator rather than strings.
+``HttpResponse`` will consume the iterator immediately, store its content as a
+string, and discard it.
-Passing an iterator as content to :class:`HttpResponse` creates a
-streaming response if (and only if) no middleware accesses the
-:attr:`HttpResponse.content` attribute before the response is returned.
-
-.. versionchanged:: 1.5
-
- This technique is fragile and was deprecated in Django 1.5. If you need the
- response to be streamed from the iterator to the client, you should use the
- :class:`StreamingHttpResponse` class instead.
-
- As of Django 1.7, when :class:`HttpResponse` is instantiated with an
- iterator, it will consume it immediately, store the response content as a
- string, and discard the iterator.
-
-.. versionchanged:: 1.5
-
- You can now use :class:`HttpResponse` as a file-like object even if it was
- instantiated with an iterator. Django will consume and save the content of
- the iterator on first access.
+If you need the response to be streamed from the iterator to the client, you
+must use the :class:`StreamingHttpResponse` class instead.
Setting header fields
~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index 215931768c..30e7e84fdb 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -1364,7 +1364,7 @@ __ https://github.com/django/django/blob/master/django/utils/log.py
LOGGING_CONFIG
--------------
-Default: ``'django.utils.log.dictConfig'``
+Default: ``'logging.config.dictConfig'``
A path to a callable that will be used to configure logging in the
Django project. Points at a instance of Python's `dictConfig`_
@@ -1373,6 +1373,10 @@ configuration method by default.
If you set :setting:`LOGGING_CONFIG` to ``None``, the logging
configuration process will be skipped.
+.. versionchanged:: 1.7
+
+ Previously, the default value was ``'django.utils.log.dictConfig'``.
+
.. _dictConfig: http://docs.python.org/library/logging.config.html#configuration-dictionary-schema
.. setting:: MANAGERS
@@ -2049,22 +2053,6 @@ A tuple of authentication backend classes (as strings) to use when attempting to
authenticate a user. See the :ref:`authentication backends documentation
<authentication-backends>` for details.
-.. setting:: AUTH_PROFILE_MODULE
-
-AUTH_PROFILE_MODULE
--------------------
-
-.. deprecated:: 1.5
- With the introduction of :ref:`custom User models <auth-custom-user>`,
- the use of :setting:`AUTH_PROFILE_MODULE` to define a single profile
- model is no longer supported. See the
- :doc:`Django 1.5 release notes</releases/1.5>` for more information.
-
-Default: Not defined
-
-The site-specific user profile model used by this site. See
-:ref:`User profiles <auth-profiles>`.
-
.. setting:: AUTH_USER_MODEL
AUTH_USER_MODEL
diff --git a/docs/ref/template-response.txt b/docs/ref/template-response.txt
index 4f34d150ed..a8fb8dfee6 100644
--- a/docs/ref/template-response.txt
+++ b/docs/ref/template-response.txt
@@ -82,8 +82,7 @@ Methods
deprecated), but since this is actually the value included in the HTTP
``Content-Type`` header, it can also include the character set
encoding, which makes it more than just a MIME type specification. If
- ``mimetype`` is specified (not ``None``), that value is used.
- Otherwise, ``content_type`` is used. If neither is given,
+ ``content_type`` is specified, then its value is used. Otherwise,
:setting:`DEFAULT_CONTENT_TYPE` is used.
@@ -175,8 +174,7 @@ Methods
deprecated), but since this is actually the value included in the HTTP
``Content-Type`` header, it can also include the character set
encoding, which makes it more than just a MIME type specification. If
- ``mimetype`` is specified (not ``None``), that value is used.
- Otherwise, ``content_type`` is used. If neither is given,
+ ``content_type`` is specified, then its value is used. Otherwise,
:setting:`DEFAULT_CONTENT_TYPE` is used.
``current_app``
diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt
index 8d722829fb..d7be7a4735 100644
--- a/docs/ref/utils.txt
+++ b/docs/ref/utils.txt
@@ -107,20 +107,6 @@ to distinguish caches by the ``Accept-language`` header.
The :class:`django.utils.datastructures.SortedDict` class is a dictionary
that keeps its keys in the order in which they're inserted.
- ``SortedDict`` adds two additional methods to the standard Python ``dict``
- class:
-
- .. method:: insert(index, key, value)
-
- .. deprecated:: 1.5
-
- Inserts the key, value pair before the item with the given index.
-
- .. method:: value_for_index(index)
-
- .. deprecated:: 1.5
-
- Returns the value of the item at the given zero-based index.
Creating a new SortedDict
-------------------------
@@ -202,18 +188,7 @@ The functions defined in this module share the following properties:
=========================
.. module:: django.utils.encoding
- :synopsis: A series of helper classes and function to manage character encoding.
-
-.. class:: StrAndUnicode
-
- A class that derives ``__str__`` from ``__unicode__``.
-
- On Python 2, ``__str__`` returns the output of ``__unicode__`` encoded as
- a UTF-8 bytestring. On Python 3, ``__str__`` returns the output of
- ``__unicode__``.
-
- Useful as a mix-in. If you support Python 2 and 3 with a single code base,
- you can inherit this mix-in and just define ``__unicode__``.
+ :synopsis: A series of helper functions to manage character encoding.
.. function:: python_2_unicode_compatible
diff --git a/docs/releases/1.5-alpha-1.txt b/docs/releases/1.5-alpha-1.txt
index 2588b85306..15169131df 100644
--- a/docs/releases/1.5-alpha-1.txt
+++ b/docs/releases/1.5-alpha-1.txt
@@ -575,8 +575,8 @@ Miscellaneous
Features deprecated in 1.5
==========================
-:setting:`AUTH_PROFILE_MODULE`
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+``AUTH_PROFILE_MODULE`` setting
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With the introduction of :ref:`custom User models <auth-custom-user>`, there is
no longer any need for a built-in mechanism to store user profile data.
@@ -584,8 +584,8 @@ no longer any need for a built-in mechanism to store user profile data.
You can still define user profiles models that have a one-to-one relation with
the User model - in fact, for many applications needing to associate data with
a User account, this will be an appropriate design pattern to follow. However,
-the :setting:`AUTH_PROFILE_MODULE` setting, and the
-:meth:`~django.contrib.auth.models.User.get_profile()` method for accessing
+the ``AUTH_PROFILE_MODULE`` setting, and the
+``django.contrib.auth.models.User.get_profile()`` method for accessing
the user profile model, should not be used any longer.
Streaming behavior of :class:`~django.http.HttpResponse`
@@ -615,7 +615,7 @@ explicitly.
``django.utils.encoding.StrAndUnicode``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The :class:`~django.utils.encoding.StrAndUnicode` mix-in has been deprecated.
+The ``django.utils.encoding.StrAndUnicode`` mix-in has been deprecated.
Define a ``__str__`` method and apply the
:func:`~django.utils.encoding.python_2_unicode_compatible` decorator instead.
diff --git a/docs/releases/1.5-beta-1.txt b/docs/releases/1.5-beta-1.txt
index 57b13ea6ce..69c591ac03 100644
--- a/docs/releases/1.5-beta-1.txt
+++ b/docs/releases/1.5-beta-1.txt
@@ -627,8 +627,8 @@ Features deprecated in 1.5
.. _simplejson-deprecation-beta-1:
-:setting:`AUTH_PROFILE_MODULE`
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+``AUTH_PROFILE_MODULE``
+~~~~~~~~~~~~~~~~~~~~~~~
With the introduction of :ref:`custom User models <auth-custom-user>`, there is
no longer any need for a built-in mechanism to store user profile data.
@@ -636,8 +636,8 @@ no longer any need for a built-in mechanism to store user profile data.
You can still define user profiles models that have a one-to-one relation with
the User model - in fact, for many applications needing to associate data with
a User account, this will be an appropriate design pattern to follow. However,
-the :setting:`AUTH_PROFILE_MODULE` setting, and the
-:meth:`~django.contrib.auth.models.User.get_profile()` method for accessing
+the ``AUTH_PROFILE_MODULE`` setting, and the
+``django.contrib.auth.models.User.get_profile()`` method for accessing
the user profile model, should not be used any longer.
Streaming behavior of :class:`~django.http.HttpResponse`
@@ -668,7 +668,7 @@ If you rely on features added to :mod:`simplejson` after it became Python's
``django.utils.encoding.StrAndUnicode``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The :class:`~django.utils.encoding.StrAndUnicode` mix-in has been deprecated.
+The ``django.utils.encoding.StrAndUnicode`` mix-in has been deprecated.
Define a ``__str__`` method and apply the
:func:`~django.utils.encoding.python_2_unicode_compatible` decorator instead.
@@ -689,7 +689,7 @@ framework.
``cleanup`` management command
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The :djadmin:`cleanup` management command has been deprecated and replaced by
+The ``cleanup`` management command has been deprecated and replaced by
:djadmin:`clearsessions`.
``daily_cleanup.py`` script
diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt
index a1b046776b..a4b03bc197 100644
--- a/docs/releases/1.5.txt
+++ b/docs/releases/1.5.txt
@@ -732,8 +732,8 @@ deprecation schedule. Direct use of python markup libraries or 3rd party tag
libraries is preferred to Django maintaining this functionality in the
framework.
-:setting:`AUTH_PROFILE_MODULE`
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+``AUTH_PROFILE_MODULE``
+~~~~~~~~~~~~~~~~~~~~~~~
With the introduction of :ref:`custom User models <auth-custom-user>`, there is
no longer any need for a built-in mechanism to store user profile data.
@@ -741,8 +741,8 @@ no longer any need for a built-in mechanism to store user profile data.
You can still define user profiles models that have a one-to-one relation with
the User model - in fact, for many applications needing to associate data with
a User account, this will be an appropriate design pattern to follow. However,
-the :setting:`AUTH_PROFILE_MODULE` setting, and the
-:meth:`~django.contrib.auth.models.User.get_profile()` method for accessing
+the ``AUTH_PROFILE_MODULE`` setting, and the
+``django.contrib.auth.models.User.get_profile()`` method for accessing
the user profile model, should not be used any longer.
Streaming behavior of :class:`~django.http.HttpResponse`
@@ -775,7 +775,7 @@ If you rely on features added to :mod:`simplejson` after it became Python's
``django.utils.encoding.StrAndUnicode``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The :class:`~django.utils.encoding.StrAndUnicode` mix-in has been deprecated.
+The ``django.utils.encoding.StrAndUnicode`` mix-in has been deprecated.
Define a ``__str__`` method and apply the
:func:`~django.utils.encoding.python_2_unicode_compatible` decorator instead.
@@ -788,7 +788,7 @@ the built-in :func:`itertools.product` instead.
``cleanup`` management command
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The :djadmin:`cleanup` management command has been deprecated and replaced by
+The ``cleanup`` management command has been deprecated and replaced by
:djadmin:`clearsessions`.
``daily_cleanup.py`` script
diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt
index 1fd98e1271..4219edb1a0 100644
--- a/docs/releases/1.6.txt
+++ b/docs/releases/1.6.txt
@@ -41,9 +41,9 @@ Simplified default project and app templates
The default templates used by :djadmin:`startproject` and :djadmin:`startapp`
have been simplified and modernized. The :doc:`admin
</ref/contrib/admin/index>` is now enabled by default in new projects; the
-:doc:`sites </ref/contrib/sites>` framework no longer is. :ref:`Language
-detection <how-django-discovers-language-preference>` and :ref:`clickjacking
-prevention <clickjacking-prevention>` are turned on.
+:doc:`sites </ref/contrib/sites>` framework no longer is. :ref:`clickjacking
+prevention <clickjacking-prevention>` is now on and the database defaults to
+SQLite.
If the default templates don't suit your tastes, you can use :ref:`custom
project and app templates <custom-app-and-project-templates>`.
diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt
new file mode 100644
index 0000000000..6955ef2030
--- /dev/null
+++ b/docs/releases/1.7.txt
@@ -0,0 +1,47 @@
+============================================
+Django 1.7 release notes - UNDER DEVELOPMENT
+============================================
+
+Welcome to Django 1.7!
+
+These release notes cover the `new features`_, as well as some `backwards
+incompatible changes`_ you'll want to be aware of when upgrading from Django
+1.6 or older versions. We've also dropped some features, which are detailed in
+:doc:`our deprecation plan </internals/deprecation>`, and we've `begun the
+deprecation process for some features`_.
+
+.. _`new features`: `What's new in Django 1.7`_
+.. _`backwards incompatible changes`: `Backwards incompatible changes in 1.7`_
+.. _`begun the deprecation process for some features`: `Features deprecated in 1.7`_
+
+What's new in Django 1.7
+========================
+
+Backwards incompatible changes in 1.7
+=====================================
+
+.. warning::
+
+ In addition to the changes outlined in this section, be sure to review the
+ :doc:`deprecation plan </internals/deprecation>` for any features that
+ have been removed. If you haven't updated your code within the
+ deprecation timeline for a given feature, its removal may appear as a
+ backwards incompatible change.
+
+Features deprecated in 1.7
+==========================
+
+``django.utils.dictconfig``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``django.utils.dictconfig`` was a copy of :mod:`logging.config` provided for
+Python versions prior to 2.7. It has been deprecated.
+
+``django.utils.unittest``
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``django.utils.unittest`` provided uniform access to the ``unittest2`` library
+on all Python versions. Since ``unittest2`` became the standard library's
+:mod:`unittest` module in Python 2.7, and Django 1.7 drops support for older
+Python versions, this module isn't useful anymore. It has been deprecated. Use
+:mod:`unittest` instead.
diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt
index ee1aedbd8c..24c622f77f 100644
--- a/docs/topics/auth/customizing.txt
+++ b/docs/topics/auth/customizing.txt
@@ -354,40 +354,6 @@ model and adding the related fields may be your better option. However
existing links to the default User model within your project's apps may justify
the extra database load.
-.. _auth-profiles:
-
-.. deprecated:: 1.5
- With the introduction of :ref:`custom User models <auth-custom-user>`,
- the use of :setting:`AUTH_PROFILE_MODULE` to define a single profile
- model is no longer supported. See the
- :doc:`Django 1.5 release notes</releases/1.5>` for more information.
-
-Prior to 1.5, a single profile model could be specified site-wide with the
-setting :setting:`AUTH_PROFILE_MODULE` with a string consisting of the
-following items, separated by a dot:
-
-1. The name of the application (case sensitive) in which the user
- profile model is defined (in other words, the
- name which was passed to :djadmin:`manage.py startapp <startapp>` to create
- the application).
-
-2. The name of the model (not case sensitive) class.
-
-For example, if the profile model was a class named ``UserProfile`` and was
-defined inside an application named ``accounts``, the appropriate setting would
-be::
-
- AUTH_PROFILE_MODULE = 'accounts.UserProfile'
-
-When a user profile model has been defined and specified in this manner, each
-:class:`~django.contrib.auth.models.User` object will have a method --
-:class:`~django.contrib.auth.models.User.get_profile()` -- which returns the
-instance of the user profile model associated with that
-:class:`~django.contrib.auth.models.User`.
-
-The method :class:`~django.contrib.auth.models.User.get_profile()`
-does not create a profile if one does not exist.
-
.. _auth-custom-user:
Substituting a custom User model
diff --git a/docs/topics/class-based-views/mixins.txt b/docs/topics/class-based-views/mixins.txt
index 84d7417233..df1a5505a5 100644
--- a/docs/topics/class-based-views/mixins.txt
+++ b/docs/topics/class-based-views/mixins.txt
@@ -286,18 +286,18 @@ One way to do this is to combine :class:`ListView` with
for the paginated list of books can hang off the publisher found as the single
object. In order to do this, we need to have two different querysets:
-``Publisher`` queryset for use in
- :meth:`~django.views.generic.detail.SingleObjectMixin.get_object()`
- We'll set the ``model`` attribute on the view and rely on the default
- implementation of ``get_object()`` to fetch the correct ``Publisher``
- object.
-
``Book`` queryset for use by :class:`~django.views.generic.list.ListView`
- The default implementation of ``get_queryset()`` uses the ``model`` attribute
- to construct the queryset. This conflicts with our use of this attribute
- for ``get_object()`` so we'll override that method and have it return
- the queryset of ``Book`` objects linked to the ``Publisher`` we're looking
- at.
+ Since we have access to the ``Publisher`` whose books we want to list, we
+ simply override ``get_queryset()`` and use the ``Publisher``'s
+ :ref:`reverse foreign key manager<backwards-related-objects>`.
+
+``Publisher`` queryset for use in :meth:`~django.views.generic.detail.SingleObjectMixin.get_object()`
+ We'll rely on the default implementation of ``get_object()`` to fetch the
+ correct ``Publisher`` object.
+ However, we need to explicitly pass a ``queryset`` argument because
+ otherwise the default implementation of ``get_object()`` would call
+ ``get_queryset()`` which we have overridden to return ``Book`` objects
+ instead of ``Publisher`` ones.
.. note::
@@ -317,12 +317,11 @@ Now we can write a new ``PublisherDetail``::
from books.models import Publisher
class PublisherDetail(SingleObjectMixin, ListView):
- model = Publisher # for SingleObjectMixin.get_object
paginate_by = 2
template_name = "books/publisher_detail.html"
def get(self, request, *args, **kwargs):
- self.object = self.get_object()
+ self.object = self.get_object(queryset=Publisher.objects.all())
return super(PublisherDetail, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
diff --git a/docs/topics/install.txt b/docs/topics/install.txt
index 1c99dc5d5a..9cf02d96de 100644
--- a/docs/topics/install.txt
+++ b/docs/topics/install.txt
@@ -7,10 +7,8 @@ This document will get you up and running with Django.
Install Python
==============
-Being a Python Web framework, Django requires Python.
-
-It works with any Python version from 2.6.5 to 2.7. It also features
-experimental support for versions from 3.2.3 to 3.3.
+Being a Python Web framework, Django requires Python. It works with Python 2.7,
+3.2 or 3.3.
Get Python at http://www.python.org. If you're running Linux or Mac OS X, you
probably already have it installed.
diff --git a/docs/topics/logging.txt b/docs/topics/logging.txt
index a88201ad47..66c517d615 100644
--- a/docs/topics/logging.txt
+++ b/docs/topics/logging.txt
@@ -205,13 +205,6 @@ Python's logging library provides several techniques to configure
logging, ranging from a programmatic interface to configuration files.
By default, Django uses the `dictConfig format`_.
-.. note::
- ``logging.dictConfig`` is a builtin library in Python 2.7. In
- order to make this library available for users of earlier Python
- versions, Django includes a copy as part of ``django.utils.log``.
- If you have Python 2.7 or later, the system native library will be used; if
- you have Python 2.6, Django's copy will be used.
-
In order to configure logging, you use :setting:`LOGGING` to define a
dictionary of logging settings. These settings describes the loggers,
handlers, filters and formatters that you want in your logging setup,
@@ -234,8 +227,6 @@ use in your project code.
.. _dictConfig format: http://docs.python.org/library/logging.config.html#configuration-dictionary-schema
-.. _a third-party library: http://bitbucket.org/vinay.sajip/dictconfig
-
An example
----------
@@ -264,7 +255,7 @@ complex logging setup, configured using :func:`logging.config.dictConfig`::
'handlers': {
'null': {
'level': 'DEBUG',
- 'class': 'django.utils.log.NullHandler',
+ 'class': 'logging.NullHandler',
},
'console':{
'level': 'DEBUG',
diff --git a/docs/topics/testing/_images/django_unittest_classes_hierarchy.graffle b/docs/topics/testing/_images/django_unittest_classes_hierarchy.graffle
index 7211c0f3be..c0edad721d 100644
--- a/docs/topics/testing/_images/django_unittest_classes_hierarchy.graffle
+++ b/docs/topics/testing/_images/django_unittest_classes_hierarchy.graffle
@@ -7,14 +7,14 @@
<key>ApplicationVersion</key>
<array>
<string>com.omnigroup.OmniGrafflePro</string>
- <string>139.16.0.171715</string>
+ <string>139.15.0.171074</string>
</array>
<key>AutoAdjust</key>
<true/>
<key>BackgroundGraphic</key>
<dict>
<key>Bounds</key>
- <string>{{0, 0}, {559.28997802734375, 782.8900146484375}}</string>
+ <string>{{0, 0}, {559, 783}}</string>
<key>Class</key>
<string>SolidGraphic</string>
<key>ID</key>
@@ -102,53 +102,6 @@
<key>Head</key>
<dict>
<key>ID</key>
- <integer>12</integer>
- <key>Info</key>
- <integer>1</integer>
- </dict>
- <key>ID</key>
- <integer>27</integer>
- <key>OrthogonalBarAutomatic</key>
- <true/>
- <key>OrthogonalBarPoint</key>
- <string>{0, 0}</string>
- <key>OrthogonalBarPosition</key>
- <real>-1</real>
- <key>Points</key>
- <array>
- <string>{135, 270}</string>
- <string>{369, 225}</string>
- </array>
- <key>Style</key>
- <dict>
- <key>stroke</key>
- <dict>
- <key>HeadArrow</key>
- <string>UMLInheritance</string>
- <key>HeadScale</key>
- <real>0.79999995231628418</real>
- <key>Legacy</key>
- <true/>
- <key>LineType</key>
- <integer>2</integer>
- <key>TailArrow</key>
- <string>0</string>
- </dict>
- </dict>
- <key>Tail</key>
- <dict>
- <key>ID</key>
- <integer>26</integer>
- <key>Position</key>
- <real>0.5</real>
- </dict>
- </dict>
- <dict>
- <key>Class</key>
- <string>LineGraphic</string>
- <key>Head</key>
- <dict>
- <key>ID</key>
<integer>10</integer>
</dict>
<key>ID</key>
@@ -162,7 +115,7 @@
<key>Points</key>
<array>
<string>{135, 315}</string>
- <string>{135, 225}</string>
+ <string>{135, 261}</string>
</array>
<key>Style</key>
<dict>
@@ -274,144 +227,7 @@
</dict>
<dict>
<key>Bounds</key>
- <string>{{378, 252}, {81, 27}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>FontInfo</key>
- <dict>
- <key>Font</key>
- <string>Helvetica</string>
- <key>Size</key>
- <real>12</real>
- </dict>
- <key>ID</key>
- <integer>22</integer>
- <key>Shape</key>
- <string>NoteShape</string>
- <key>Style</key>
- <dict>
- <key>stroke</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>b</key>
- <string>0</string>
- <key>g</key>
- <string>0.501961</string>
- <key>r</key>
- <string>0</string>
- </dict>
- </dict>
- </dict>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
-{\colortbl;\red255\green255\blue255;\red0\green128\blue0;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\i\fs24 \cf2 Python &lt; 2.7}</string>
- <key>VerticalPad</key>
- <integer>0</integer>
- </dict>
- <key>TextRelativeArea</key>
- <string>{{0, 0}, {1, 1}}</string>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{45, 252}, {81, 27}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>FontInfo</key>
- <dict>
- <key>Font</key>
- <string>Helvetica</string>
- <key>Size</key>
- <real>12</real>
- </dict>
- <key>ID</key>
- <integer>20</integer>
- <key>Shape</key>
- <string>NoteShape</string>
- <key>Style</key>
- <dict>
- <key>stroke</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>b</key>
- <string>0</string>
- <key>g</key>
- <string>0.501961</string>
- <key>r</key>
- <string>0</string>
- </dict>
- </dict>
- </dict>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
-{\colortbl;\red255\green255\blue255;\red0\green128\blue0;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\i\fs24 \cf2 Python \uc0\u8805 2.7}</string>
- <key>VerticalPad</key>
- <integer>0</integer>
- </dict>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{288, 198}, {162, 27}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>12</integer>
- <key>Magnets</key>
- <array>
- <string>{0, 1}</string>
- <string>{0, -1}</string>
- <string>{1, 0}</string>
- <string>{-1, 0}</string>
- </array>
- <key>Shape</key>
- <string>Rectangle</string>
- <key>Style</key>
- <dict>
- <key>fill</key>
- <dict>
- <key>FillType</key>
- <integer>2</integer>
- <key>GradientAngle</key>
- <real>90</real>
- <key>GradientColor</key>
- <dict>
- <key>w</key>
- <string>0.666667</string>
- </dict>
- </dict>
- <key>stroke</key>
- <dict>
- <key>CornerRadius</key>
- <real>5</real>
- </dict>
- </dict>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
-{\colortbl;\red255\green255\blue255;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\fs24 \cf0 TestCase}</string>
- </dict>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{54, 198}, {162, 27}}</string>
+ <string>{{54, 234}, {162, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
@@ -448,7 +264,7 @@
<key>Text</key>
<dict>
<key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
@@ -495,7 +311,7 @@
<key>Text</key>
<dict>
<key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
@@ -542,7 +358,7 @@
<key>Text</key>
<dict>
<key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
@@ -589,7 +405,7 @@
<key>Text</key>
<dict>
<key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
@@ -636,7 +452,7 @@
<key>Text</key>
<dict>
<key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
@@ -660,7 +476,7 @@
<key>Align</key>
<integer>2</integer>
<key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qr
@@ -672,7 +488,7 @@
</dict>
<dict>
<key>Bounds</key>
- <string>{{18, 153}, {225, 90}}</string>
+ <string>{{18, 216}, {468, 63}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
@@ -686,40 +502,16 @@
<key>Align</key>
<integer>2</integer>
<key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf390
+\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier-Oblique;\f1\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qr
-\f0\fs24 \cf0 django.utils.unittest\
-= unittest (standard library)}</string>
- </dict>
- <key>TextPlacement</key>
- <integer>0</integer>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{261, 153}, {225, 90}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>19</integer>
- <key>Shape</key>
- <string>Rectangle</string>
- <key>Style</key>
- <dict/>
- <key>Text</key>
- <dict>
- <key>Align</key>
- <integer>2</integer>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
-{\colortbl;\red255\green255\blue255;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qr
+\f0\i\fs24 \cf0 standard library\
-\f0\fs24 \cf0 django.utils.unittest\
-= unittest2 (bundled copy)}</string>
+\f1\i0 \
+\
+unittest}</string>
</dict>
<key>TextPlacement</key>
<integer>0</integer>
@@ -777,7 +569,7 @@
<key>MasterSheets</key>
<array/>
<key>ModificationDate</key>
- <string>2012-12-16 19:08:28 +0000</string>
+ <string>2013-07-01 11:48:06 +0000</string>
<key>Modifier</key>
<string>Aymeric Augustin</string>
<key>NotesVisible</key>
@@ -808,7 +600,7 @@
<key>NSPaperSize</key>
<array>
<string>size</string>
- <string>{595.28997802734375, 841.8900146484375}</string>
+ <string>{595, 842}</string>
</array>
<key>NSPrintReverseOrientation</key>
<array>
@@ -853,7 +645,7 @@
<key>ExpandedCanvases</key>
<array/>
<key>Frame</key>
- <string>{{9, 4}, {694, 874}}</string>
+ <string>{{613, 284}, {694, 774}}</string>
<key>ListView</key>
<true/>
<key>OutlineWidth</key>
@@ -867,7 +659,7 @@
<key>SidebarWidth</key>
<integer>120</integer>
<key>VisibleRegion</key>
- <string>{{0, 0}, {559, 735}}</string>
+ <string>{{0, 0}, {545, 620}}</string>
<key>Zoom</key>
<real>1</real>
<key>ZoomValues</key>
diff --git a/docs/topics/testing/_images/django_unittest_classes_hierarchy.pdf b/docs/topics/testing/_images/django_unittest_classes_hierarchy.pdf
index cedaba22ac..0835aec9ba 100644
--- a/docs/topics/testing/_images/django_unittest_classes_hierarchy.pdf
+++ b/docs/topics/testing/_images/django_unittest_classes_hierarchy.pdf
Binary files differ
diff --git a/docs/topics/testing/_images/django_unittest_classes_hierarchy.svg b/docs/topics/testing/_images/django_unittest_classes_hierarchy.svg
index 0482f044dd..63fee82d99 100644
--- a/docs/topics/testing/_images/django_unittest_classes_hierarchy.svg
+++ b/docs/topics/testing/_images/django_unittest_classes_hierarchy.svg
@@ -1,3 +1,3 @@
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="-2 137 508 391" width="508pt" height="391pt"><metadata xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:date>2012-12-16 19:08Z</dc:date><!-- Produced by OmniGraffle Professional 5.4.2 --></metadata><defs><filter id="Shadow" filterUnits="userSpaceOnUse"><feGaussianBlur in="SourceAlpha" result="blur" stdDeviation="3.488"/><feOffset in="blur" result="offset" dx="0" dy="4"/><feFlood flood-color="black" flood-opacity=".75" result="flood"/><feComposite in="flood" in2="offset" operator="in"/></filter><font-face font-family="Courier" font-size="12" units-per-em="1000" underline-position="-178.22266" underline-thickness="57.617188" slope="0" x-height="462.40234" cap-height="594.72656" ascent="753.90625" descent="-246.09375" font-weight="500"><font-face-src><font-face-name name="Courier"/></font-face-src></font-face><linearGradient x1="0" x2="1" id="Gradient" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="white"/><stop offset="1" stop-color="#aaa"/></linearGradient><linearGradient id="Obj_Gradient" xl:href="#Gradient" gradientTransform="translate(369 459) rotate(90) scale(27)"/><linearGradient id="Obj_Gradient_2" xl:href="#Gradient" gradientTransform="translate(135 459) rotate(90) scale(27)"/><linearGradient id="Obj_Gradient_3" xl:href="#Gradient" gradientTransform="translate(135 387) rotate(90) scale(27)"/><linearGradient id="Obj_Gradient_4" xl:href="#Gradient" gradientTransform="translate(135 315) rotate(90) scale(27)"/><linearGradient id="Obj_Gradient_5" xl:href="#Gradient" gradientTransform="translate(135 198) rotate(90) scale(27)"/><linearGradient id="Obj_Gradient_6" xl:href="#Gradient" gradientTransform="translate(369 198) rotate(90) scale(27)"/><font-face font-family="Helvetica" font-size="12" units-per-em="1000" underline-position="-75.683594" underline-thickness="49.316406" slope="-1e3" x-height="522.94922" cap-height="717.28516" ascent="770.01953" descent="-229.98047" font-style="italic" font-weight="500"><font-face-src><font-face-name name="Helvetica-Oblique"/></font-face-src></font-face><marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="UMLInheritance_Marker" viewBox="-1 -7 12 14" markerWidth="12" markerHeight="14" color="black"><g><path d="M 9.5999994 0 L 0 -5.5999997 L 0 5.5999997 Z" fill="none" stroke="currentColor" stroke-width="1"/></g></marker></defs><g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1"><title>Canevas 1</title><rect fill="white" width="559.28998" height="782.89"/><g><title>Calque 1</title><g><use xl:href="#id19_Graphic" filter="url(#Shadow)"/><use xl:href="#id18_Graphic" filter="url(#Shadow)"/><use xl:href="#id13_Graphic" filter="url(#Shadow)"/><use xl:href="#id6_Graphic" filter="url(#Shadow)"/><use xl:href="#id7_Graphic" filter="url(#Shadow)"/><use xl:href="#id8_Graphic" filter="url(#Shadow)"/><use xl:href="#id9_Graphic" filter="url(#Shadow)"/><use xl:href="#id10_Graphic" filter="url(#Shadow)"/><use xl:href="#id12_Graphic" filter="url(#Shadow)"/><use xl:href="#id20_Graphic" filter="url(#Shadow)"/><use xl:href="#id22_Graphic" filter="url(#Shadow)"/></g><g id="id19_Graphic"><rect x="261" y="153" width="225" height="90" fill="white"/><rect x="261" y="153" width="225" height="90" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(266 158)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="63.77539" y="11" textLength="151.22461">django.utils.unittest</tspan><tspan font-family="Courier" font-size="12" font-weight="500" x="27.769531" y="25" textLength="187.23047">= unittest2 (bundled copy)</tspan></text></g><g id="id18_Graphic"><rect x="18" y="153" width="225" height="90" fill="white"/><rect x="18" y="153" width="225" height="90" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(23 158)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="63.77539" y="11" textLength="151.22461">django.utils.unittest</tspan><tspan font-family="Courier" font-size="12" font-weight="500" x="6.1660156" y="25" textLength="208.83398">= unittest (standard library)</tspan></text></g><g id="id13_Graphic"><rect x="18" y="297" width="468" height="207" fill="white"/><rect x="18" y="297" width="468" height="207" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(23 302)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="378.7871" y="11" textLength="79.21289">django.test</tspan></text></g><g id="id6_Graphic"><path d="M 293 459 L 445 459 C 447.76142 459 450 461.23858 450 464 L 450 481 C 450 483.76142 447.76142 486 445 486 L 293 486 C 290.23858 486 288 483.76142 288 481 C 288 481 288 481 288 481 L 288 464 C 288 461.23858 290.23858 459 293 459 C 293 459 293 459 293 459 Z" fill="url(#Obj_Gradient)"/><path d="M 293 459 L 445 459 C 447.76142 459 450 461.23858 450 464 L 450 481 C 450 483.76142 447.76142 486 445 486 L 293 486 C 290.23858 486 288 483.76142 288 481 C 288 481 288 481 288 481 L 288 464 C 288 461.23858 290.23858 459 293 459 C 293 459 293 459 293 459 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(293 465.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="11.189453" y="11" textLength="129.62109">LiveServerTestCase</tspan></text></g><g id="id7_Graphic"><path d="M 59 459 L 211 459 C 213.76142 459 216 461.23858 216 464 L 216 481 C 216 483.76142 213.76142 486 211 486 L 59 486 C 56.238576 486 54 483.76142 54 481 C 54 481 54 481 54 481 L 54 464 C 54 461.23858 56.238576 459 59 459 C 59 459 59 459 59 459 Z" fill="url(#Obj_Gradient_2)"/><path d="M 59 459 L 211 459 C 213.76142 459 216 461.23858 216 464 L 216 481 C 216 483.76142 213.76142 486 211 486 L 59 486 C 56.238576 486 54 483.76142 54 481 C 54 481 54 481 54 481 L 54 464 C 54 461.23858 56.238576 459 59 459 C 59 459 59 459 59 459 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(59 465.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="47.195312" y="11" textLength="57.609375">TestCase</tspan></text></g><g id="id8_Graphic"><path d="M 59 387 L 211 387 C 213.76142 387 216 389.23858 216 392 L 216 409 C 216 411.76142 213.76142 414 211 414 L 59 414 C 56.238576 414 54 411.76142 54 409 C 54 409 54 409 54 409 L 54 392 C 54 389.23858 56.238576 387 59 387 C 59 387 59 387 59 387 Z" fill="url(#Obj_Gradient_3)"/><path d="M 59 387 L 211 387 C 213.76142 387 216 389.23858 216 392 L 216 409 C 216 411.76142 213.76142 414 211 414 L 59 414 C 56.238576 414 54 411.76142 54 409 C 54 409 54 409 54 409 L 54 392 C 54 389.23858 56.238576 387 59 387 C 59 387 59 387 59 387 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(59 393.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="7.588867" y="11" textLength="136.822266">TransactionTestCase</tspan></text></g><g id="id9_Graphic"><path d="M 59 315 L 211 315 C 213.76142 315 216 317.23858 216 320 L 216 337 C 216 339.76142 213.76142 342 211 342 L 59 342 C 56.238576 342 54 339.76142 54 337 C 54 337 54 337 54 337 L 54 320 C 54 317.23858 56.238576 315 59 315 C 59 315 59 315 59 315 Z" fill="url(#Obj_Gradient_4)"/><path d="M 59 315 L 211 315 C 213.76142 315 216 317.23858 216 320 L 216 337 C 216 339.76142 213.76142 342 211 342 L 59 342 C 56.238576 342 54 339.76142 54 337 C 54 337 54 337 54 337 L 54 320 C 54 317.23858 56.238576 315 59 315 C 59 315 59 315 59 315 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(59 321.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="25.591797" y="11" textLength="100.816406">SimpleTestCase</tspan></text></g><g id="id10_Graphic"><path d="M 59 198 L 211 198 C 213.76142 198 216 200.23858 216 203 L 216 220 C 216 222.76142 213.76142 225 211 225 L 59 225 C 56.238576 225 54 222.76142 54 220 C 54 220 54 220 54 220 L 54 203 C 54 200.23858 56.238576 198 59 198 C 59 198 59 198 59 198 Z" fill="url(#Obj_Gradient_5)"/><path d="M 59 198 L 211 198 C 213.76142 198 216 200.23858 216 203 L 216 220 C 216 222.76142 213.76142 225 211 225 L 59 225 C 56.238576 225 54 222.76142 54 220 C 54 220 54 220 54 220 L 54 203 C 54 200.23858 56.238576 198 59 198 C 59 198 59 198 59 198 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(59 204.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="47.195312" y="11" textLength="57.609375">TestCase</tspan></text></g><g id="id12_Graphic"><path d="M 293 198 L 445 198 C 447.76142 198 450 200.23858 450 203 L 450 220 C 450 222.76142 447.76142 225 445 225 L 293 225 C 290.23858 225 288 222.76142 288 220 C 288 220 288 220 288 220 L 288 203 C 288 200.23858 290.23858 198 293 198 C 293 198 293 198 293 198 Z" fill="url(#Obj_Gradient_6)"/><path d="M 293 198 L 445 198 C 447.76142 198 450 200.23858 450 203 L 450 220 C 450 222.76142 447.76142 225 445 225 L 293 225 C 290.23858 225 288 222.76142 288 220 C 288 220 288 220 288 220 L 288 203 C 288 200.23858 290.23858 198 293 198 C 293 198 293 198 293 198 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(293 204.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="47.195312" y="11" textLength="57.609375">TestCase</tspan></text></g><g id="id20_Graphic"><path d="M 126 259.9893 C 126 257.43159 124.9713 257.11515 117.45693 254.5839 L 117.37755 254.55771 C 109.82349 252 109.74492 252 101.99241 252 C 91.66977 252 45 252 45 252 L 45 279 L 126 279 L 126 259.9893 Z" fill="white"/><path d="M 126 259.9893 C 126 257.43159 124.9713 257.11515 117.45693 254.5839 L 117.37755 254.55771 C 109.82349 252 109.74492 252 101.99241 252 C 91.66977 252 45 252 45 252 L 45 279 L 126 279 L 126 259.9893 Z M 126 259.85754 C 126 257.43159 125.92062 257.43159 109.74492 257.43159 L 109.74492 257.43159 C 109.74492 252.02646 109.74492 252 102.46707 252" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(50 258.5)" fill="green"><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" fill="green" x="1.8525391" y="11" textLength="67.29492">Python ≥ 2.7</tspan></text></g><g id="id22_Graphic"><path d="M 459 259.9893 C 459 257.43159 457.9713 257.11515 450.45693 254.5839 L 450.37755 254.55771 C 442.8235 252 442.74492 252 434.9924 252 C 424.66977 252 378 252 378 252 L 378 279 L 459 279 L 459 259.9893 Z" fill="white"/><path d="M 459 259.9893 C 459 257.43159 457.9713 257.11515 450.45693 254.5839 L 450.37755 254.55771 C 442.8235 252 442.74492 252 434.9924 252 C 424.66977 252 378 252 378 252 L 378 279 L 459 279 L 459 259.9893 Z M 459 259.85754 C 459 257.43159 458.92062 257.43159 442.74492 257.43159 L 442.74492 257.43159 C 442.74492 252.02646 442.74492 252 435.46707 252" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(383 258.5)" fill="green"><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" fill="green" x="1.6416016" y="11" textLength="67.716797">Python &lt; 2.7</tspan></text></g><path d="M 135 459 L 135 445.9 L 135 427.1 L 135 425.1" marker-end="url(#UMLInheritance_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><path d="M 135 387 L 135 373.9 L 135 355.1 L 135 353.1" marker-end="url(#UMLInheritance_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><path d="M 135 315 L 135 301.9 L 135 238.1 L 135 236.1" marker-end="url(#UMLInheritance_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><path d="M 135 270 L 148.1 270 L 369 270 L 369 238.1 L 369 236.1" marker-end="url(#UMLInheritance_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><path d="M 369 459 L 369 445.9 L 369 400.5 L 229.1 400.5 L 227.1 400.5" marker-end="url(#UMLInheritance_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/></g></g></svg>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="-2 200 508 328" width="508pt" height="328pt"><metadata xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:date>2013-07-01 11:48Z</dc:date><!-- Produced by OmniGraffle Professional 5.4.1 --></metadata><defs><filter id="Shadow" filterUnits="userSpaceOnUse"><feGaussianBlur in="SourceAlpha" result="blur" stdDeviation="3.488"/><feOffset in="blur" result="offset" dx="0" dy="4"/><feFlood flood-color="black" flood-opacity=".75" result="flood"/><feComposite in="flood" in2="offset" operator="in"/></filter><font-face font-family="Courier" font-size="12" units-per-em="1000" underline-position="-178.22266" underline-thickness="57.617188" slope="-1e3" x-height="462.40234" cap-height="594.72656" ascent="753.90625" descent="-246.09375" font-style="italic" font-weight="500"><font-face-src><font-face-name name="Courier-Oblique"/></font-face-src></font-face><font-face font-family="Courier" font-size="12" units-per-em="1000" underline-position="-178.22266" underline-thickness="57.617188" slope="0" x-height="462.40234" cap-height="594.72656" ascent="753.90625" descent="-246.09375" font-weight="500"><font-face-src><font-face-name name="Courier"/></font-face-src></font-face><linearGradient x1="0" x2="1" id="Gradient" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="white"/><stop offset="1" stop-color="#aaa"/></linearGradient><linearGradient id="Obj_Gradient" xl:href="#Gradient" gradientTransform="translate(369 459) rotate(90) scale(27)"/><linearGradient id="Obj_Gradient_2" xl:href="#Gradient" gradientTransform="translate(135 459) rotate(90) scale(27)"/><linearGradient id="Obj_Gradient_3" xl:href="#Gradient" gradientTransform="translate(135 387) rotate(90) scale(27)"/><linearGradient id="Obj_Gradient_4" xl:href="#Gradient" gradientTransform="translate(135 315) rotate(90) scale(27)"/><linearGradient id="Obj_Gradient_5" xl:href="#Gradient" gradientTransform="translate(135 234) rotate(90) scale(27)"/><marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="UMLInheritance_Marker" viewBox="-1 -7 12 14" markerWidth="12" markerHeight="14" color="black"><g><path d="M 9.5999994 0 L 0 -5.5999997 L 0 5.5999997 Z" fill="none" stroke="currentColor" stroke-width="1"/></g></marker></defs><g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1"><title>Canevas 1</title><rect fill="white" width="559" height="783"/><g><title>Calque 1</title><g><use xl:href="#id18_Graphic" filter="url(#Shadow)"/><use xl:href="#id13_Graphic" filter="url(#Shadow)"/><use xl:href="#id6_Graphic" filter="url(#Shadow)"/><use xl:href="#id7_Graphic" filter="url(#Shadow)"/><use xl:href="#id8_Graphic" filter="url(#Shadow)"/><use xl:href="#id9_Graphic" filter="url(#Shadow)"/><use xl:href="#id10_Graphic" filter="url(#Shadow)"/></g><g id="id18_Graphic"><rect x="18" y="216" width="468" height="63" fill="white"/><rect x="18" y="216" width="468" height="63" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(23 221)" fill="black"><tspan font-family="Courier" font-size="12" font-style="italic" font-weight="500" x="342.78125" y="11" textLength="115.21875">standard library</tspan><tspan font-family="Courier" font-size="12" font-weight="500" x="400.39062" y="53" textLength="57.609375">unittest</tspan></text></g><g id="id13_Graphic"><rect x="18" y="297" width="468" height="207" fill="white"/><rect x="18" y="297" width="468" height="207" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(23 302)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="378.7871" y="11" textLength="79.21289">django.test</tspan></text></g><g id="id6_Graphic"><path d="M 293 459 L 445 459 C 447.76142 459 450 461.23858 450 464 L 450 481 C 450 483.76142 447.76142 486 445 486 L 293 486 C 290.23858 486 288 483.76142 288 481 C 288 481 288 481 288 481 L 288 464 C 288 461.23858 290.23858 459 293 459 C 293 459 293 459 293 459 Z" fill="url(#Obj_Gradient)"/><path d="M 293 459 L 445 459 C 447.76142 459 450 461.23858 450 464 L 450 481 C 450 483.76142 447.76142 486 445 486 L 293 486 C 290.23858 486 288 483.76142 288 481 C 288 481 288 481 288 481 L 288 464 C 288 461.23858 290.23858 459 293 459 C 293 459 293 459 293 459 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(293 465.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="11.189453" y="11" textLength="129.62109">LiveServerTestCase</tspan></text></g><g id="id7_Graphic"><path d="M 59 459 L 211 459 C 213.76142 459 216 461.23858 216 464 L 216 481 C 216 483.76142 213.76142 486 211 486 L 59 486 C 56.238576 486 54 483.76142 54 481 C 54 481 54 481 54 481 L 54 464 C 54 461.23858 56.238576 459 59 459 C 59 459 59 459 59 459 Z" fill="url(#Obj_Gradient_2)"/><path d="M 59 459 L 211 459 C 213.76142 459 216 461.23858 216 464 L 216 481 C 216 483.76142 213.76142 486 211 486 L 59 486 C 56.238576 486 54 483.76142 54 481 C 54 481 54 481 54 481 L 54 464 C 54 461.23858 56.238576 459 59 459 C 59 459 59 459 59 459 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(59 465.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="47.195312" y="11" textLength="57.609375">TestCase</tspan></text></g><g id="id8_Graphic"><path d="M 59 387 L 211 387 C 213.76142 387 216 389.23858 216 392 L 216 409 C 216 411.76142 213.76142 414 211 414 L 59 414 C 56.238576 414 54 411.76142 54 409 C 54 409 54 409 54 409 L 54 392 C 54 389.23858 56.238576 387 59 387 C 59 387 59 387 59 387 Z" fill="url(#Obj_Gradient_3)"/><path d="M 59 387 L 211 387 C 213.76142 387 216 389.23858 216 392 L 216 409 C 216 411.76142 213.76142 414 211 414 L 59 414 C 56.238576 414 54 411.76142 54 409 C 54 409 54 409 54 409 L 54 392 C 54 389.23858 56.238576 387 59 387 C 59 387 59 387 59 387 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(59 393.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="7.588867" y="11" textLength="136.822266">TransactionTestCase</tspan></text></g><g id="id9_Graphic"><path d="M 59 315 L 211 315 C 213.76142 315 216 317.23858 216 320 L 216 337 C 216 339.76142 213.76142 342 211 342 L 59 342 C 56.238576 342 54 339.76142 54 337 C 54 337 54 337 54 337 L 54 320 C 54 317.23858 56.238576 315 59 315 C 59 315 59 315 59 315 Z" fill="url(#Obj_Gradient_4)"/><path d="M 59 315 L 211 315 C 213.76142 315 216 317.23858 216 320 L 216 337 C 216 339.76142 213.76142 342 211 342 L 59 342 C 56.238576 342 54 339.76142 54 337 C 54 337 54 337 54 337 L 54 320 C 54 317.23858 56.238576 315 59 315 C 59 315 59 315 59 315 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(59 321.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="25.591797" y="11" textLength="100.816406">SimpleTestCase</tspan></text></g><g id="id10_Graphic"><path d="M 59 234 L 211 234 C 213.76142 234 216 236.23858 216 239 L 216 256 C 216 258.76142 213.76142 261 211 261 L 59 261 C 56.238576 261 54 258.76142 54 256 C 54 256 54 256 54 256 L 54 239 C 54 236.23858 56.238576 234 59 234 C 59 234 59 234 59 234 Z" fill="url(#Obj_Gradient_5)"/><path d="M 59 234 L 211 234 C 213.76142 234 216 236.23858 216 239 L 216 256 C 216 258.76142 213.76142 261 211 261 L 59 261 C 56.238576 261 54 258.76142 54 256 C 54 256 54 256 54 256 L 54 239 C 54 236.23858 56.238576 234 59 234 C 59 234 59 234 59 234 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(59 240.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="47.195312" y="11" textLength="57.609375">TestCase</tspan></text></g><path d="M 135 459 L 135 445.9 L 135 427.1 L 135 425.1" marker-end="url(#UMLInheritance_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><path d="M 135 387 L 135 373.9 L 135 355.1 L 135 353.1" marker-end="url(#UMLInheritance_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><path d="M 135 315 L 135 301.9 L 135 274.1 L 135 272.1" marker-end="url(#UMLInheritance_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><path d="M 369 459 L 369 445.9 L 369 400.5 L 229.1 400.5 L 227.1 400.5" marker-end="url(#UMLInheritance_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/></g></g></svg>
diff --git a/docs/topics/testing/advanced.txt b/docs/topics/testing/advanced.txt
index 8f7f093901..b8e70b592b 100644
--- a/docs/topics/testing/advanced.txt
+++ b/docs/topics/testing/advanced.txt
@@ -37,7 +37,7 @@ Example
The following is a simple unit test using the request factory::
- from django.utils import unittest
+ import unittest
from django.test.client import RequestFactory
class SimpleTest(unittest.TestCase):
diff --git a/docs/topics/testing/overview.txt b/docs/topics/testing/overview.txt
index d56b1be20f..6f75a3b7a8 100644
--- a/docs/topics/testing/overview.txt
+++ b/docs/topics/testing/overview.txt
@@ -21,27 +21,15 @@ module defines tests using a class-based approach.
.. admonition:: unittest2
- Python 2.7 introduced some major changes to the ``unittest`` library,
- adding some extremely useful features. To ensure that every Django
- project can benefit from these new features, Django ships with a
- copy of unittest2_, a copy of Python 2.7's ``unittest``, backported for
- Python 2.6 compatibility.
-
- To access this library, Django provides the
- ``django.utils.unittest`` module alias. If you are using Python
- 2.7, or you have installed ``unittest2`` locally, Django will map the alias
- to it. Otherwise, Django will use its own bundled version of ``unittest2``.
-
- To use this alias, simply use::
-
- from django.utils import unittest
+ .. deprecated:: 1.7
- wherever you would have historically used::
-
- import unittest
+ Python 2.7 introduced some major changes to the ``unittest`` library,
+ adding some extremely useful features. To ensure that every Django project
+ could benefit from these new features, Django used to ship with a copy of
+ Python 2.7's ``unittest`` backported for Python 2.6 compatibility.
- If you want to continue to use the legacy ``unittest`` library, you can --
- you just won't get any of the nice new ``unittest2`` features.
+ Since Django no longer supports Python versions older than 2.7,
+ ``django.utils.unittest`` is deprecated. Simply use ``unittest``.
.. _unittest2: http://pypi.python.org/pypi/unittest2
@@ -812,7 +800,7 @@ Example
The following is a simple unit test using the test client::
- from django.utils import unittest
+ import unittest
from django.test.client import Client
class SimpleTest(unittest.TestCase):
@@ -849,13 +837,10 @@ Normal Python unit test classes extend a base class of
.. figure:: _images/django_unittest_classes_hierarchy.*
:alt: Hierarchy of Django unit testing classes (TestCase subclasses)
:width: 508
- :height: 391
+ :height: 328
Hierarchy of Django unit testing classes
-Regardless of the version of Python you're using, if you've installed
-``unittest2``, ``django.utils.unittest`` will point to that library.
-
SimpleTestCase
~~~~~~~~~~~~~~
@@ -905,7 +890,7 @@ features like:
then you should use :class:`~django.test.TransactionTestCase` or
:class:`~django.test.TestCase` instead.
-``SimpleTestCase`` inherits from ``django.utils.unittest.TestCase``.
+``SimpleTestCase`` inherits from ``unittest.TestCase``.
TransactionTestCase
~~~~~~~~~~~~~~~~~~~
@@ -1158,7 +1143,7 @@ worry about state (such as cookies) carrying over from one test to another.
This means, instead of instantiating a ``Client`` in each test::
- from django.utils import unittest
+ import unittest
from django.test.client import Client
class SimpleTest(unittest.TestCase):
diff --git a/setup.cfg b/setup.cfg
index 330eff6977..4c25b840b5 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -6,4 +6,4 @@ install-script = scripts/rpm-install.sh
license-file = LICENSE
[wheel]
-universal = 1 # use py2.py3 tag for pure-python dist
+universal = 1
diff --git a/setup.py b/setup.py
index 2c64868d00..6278afa116 100644
--- a/setup.py
+++ b/setup.py
@@ -101,7 +101,6 @@ setup(
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
diff --git a/tests/.coveragerc b/tests/.coveragerc
index cd7fee3c89..1b4c087f14 100644
--- a/tests/.coveragerc
+++ b/tests/.coveragerc
@@ -1,5 +1,5 @@
[run]
-omit = */django/contrib/*/tests*,*/django/utils/unittest*,*/django/utils/simplejson*,*/django/utils/importlib.py,*/django/test/_doctest.py,*/django/core/servers/fastcgi.py,*/django/utils/autoreload.py,*/django/utils/dictconfig.py
+omit = */django/contrib/*/tests*,*/django/utils/unittest*,*/django/utils/importlib.py,*/django/test/_doctest.py,*/django/core/servers/fastcgi.py,*/django/utils/autoreload.py,*/django/utils/dictconfig.py
[html]
directory = coverage_html
diff --git a/tests/admin_scripts/app_with_import/models.py b/tests/admin_scripts/app_with_import/models.py
index 17a892bd17..89125c386f 100644
--- a/tests/admin_scripts/app_with_import/models.py
+++ b/tests/admin_scripts/app_with_import/models.py
@@ -1,8 +1,8 @@
from django.db import models
-from django.contrib.comments.models import Comment
+from django.contrib.auth.models import User
# Regression for #13368. This is an example of a model
# that imports a class that has an abstract base class.
-class CommentScore(models.Model):
- comment = models.OneToOneField(Comment, primary_key=True)
+class UserProfile(models.Model):
+ user = models.OneToOneField(User, primary_key=True)
diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py
index 2f399acb23..28f2dcb841 100644
--- a/tests/admin_scripts/tests.py
+++ b/tests/admin_scripts/tests.py
@@ -6,13 +6,14 @@ and default settings.py files.
"""
from __future__ import unicode_literals
+import codecs
import os
import re
import shutil
import socket
import subprocess
import sys
-import codecs
+import unittest
import django
from django import conf, get_version
@@ -20,7 +21,6 @@ from django.conf import settings
from django.core.management import BaseCommand, CommandError
from django.db import connection
from django.test.runner import DiscoverRunner
-from django.utils import unittest
from django.utils.encoding import force_text
from django.utils._os import upath
from django.utils.six import StringIO
@@ -1079,7 +1079,6 @@ class ManageValidate(AdminScriptTestCase):
"manage.py validate does not raise errors when an app imports a base class that itself has an abstract base"
self.write_settings('settings.py',
apps=['admin_scripts.app_with_import',
- 'django.contrib.comments',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sites'],
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index 235fe0cb54..101fcd90f6 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -4,6 +4,7 @@ from __future__ import absolute_import, unicode_literals
import os
import re
import datetime
+import unittest
try:
from urllib.parse import urljoin
except ImportError: # Python 2
@@ -15,6 +16,7 @@ from django.core.files import temp as tempfile
from django.core.urlresolvers import reverse
# Register auth models with the admin.
from django.contrib import admin
+from django.contrib.auth import get_permission_codename
from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
from django.contrib.admin.models import LogEntry, DELETION
from django.contrib.admin.sites import LOGIN_FORM_KEY
@@ -30,7 +32,8 @@ from django.forms.util import ErrorList
from django.template.response import TemplateResponse
from django.test import TestCase
from django.test.utils import patch_logger
-from django.utils import formats, translation, unittest
+from django.utils import formats
+from django.utils import translation
from django.utils.cache import get_max_age
from django.utils.encoding import iri_to_uri, force_bytes
from django.utils.html import escape
@@ -854,20 +857,20 @@ class AdminViewPermissionsTest(TestCase):
# User who can add Articles
add_user = User.objects.get(username='adduser')
add_user.user_permissions.add(get_perm(Article,
- opts.get_add_permission()))
+ get_permission_codename('add', opts)))
# User who can change Articles
change_user = User.objects.get(username='changeuser')
change_user.user_permissions.add(get_perm(Article,
- opts.get_change_permission()))
+ get_permission_codename('change', opts)))
# User who can delete Articles
delete_user = User.objects.get(username='deleteuser')
delete_user.user_permissions.add(get_perm(Article,
- opts.get_delete_permission()))
+ get_permission_codename('delete', opts)))
delete_user.user_permissions.add(get_perm(Section,
- Section._meta.get_delete_permission()))
+ get_permission_codename('delete', Section._meta)))
# login POST dicts
self.super_login = {
@@ -1210,7 +1213,7 @@ class AdminViewPermissionsTest(TestCase):
# Allow the add user to add sections too. Now they can see the "add
# section" link.
add_user = User.objects.get(username='adduser')
- perm = get_perm(Section, Section._meta.get_add_permission())
+ perm = get_perm(Section, get_permission_codename('add', Section._meta))
add_user.user_permissions.add(perm)
response = self.client.get(url)
self.assertContains(response, add_link_text)
@@ -1315,7 +1318,7 @@ class AdminViewsNoUrlTest(TestCase):
# User who can change Reports
change_user = User.objects.get(username='changeuser')
change_user.user_permissions.add(get_perm(Report,
- opts.get_change_permission()))
+ get_permission_codename('change', opts)))
# login POST dict
self.changeuser_login = {
@@ -1372,7 +1375,7 @@ class AdminViewDeletedObjectsTest(TestCase):
self.client.logout()
delete_user = User.objects.get(username='deleteuser')
delete_user.user_permissions.add(get_perm(Plot,
- Plot._meta.get_delete_permission()))
+ get_permission_codename('delete', Plot._meta)))
self.assertTrue(self.client.login(username='deleteuser',
password='secret'))
diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py
index 4823883f42..8edb2f5904 100644
--- a/tests/admin_widgets/tests.py
+++ b/tests/admin_widgets/tests.py
@@ -2,6 +2,7 @@
from __future__ import absolute_import, unicode_literals
from datetime import datetime
+from unittest import TestCase
from django import forms
from django.conf import settings
@@ -16,7 +17,6 @@ from django.test.utils import override_settings
from django.utils import six
from django.utils import translation
from django.utils.html import conditional_escape
-from django.utils.unittest import TestCase
from . import models
from .widgetadmin import site as widget_admin_site
diff --git a/tests/aggregation_regress/tests.py b/tests/aggregation_regress/tests.py
index 80441b9a60..35ac57d9be 100644
--- a/tests/aggregation_regress/tests.py
+++ b/tests/aggregation_regress/tests.py
@@ -10,7 +10,6 @@ from django.contrib.contenttypes.models import ContentType
from django.db.models import Count, Max, Avg, Sum, StdDev, Variance, F, Q
from django.test import TestCase, Approximate, skipUnlessDBFeature
from django.utils import six
-from django.utils.unittest import expectedFailure
from .models import (Author, Book, Publisher, Clues, Entries, HardbackBook,
ItemTag, WithManualPK)
diff --git a/tests/app_loading/tests.py b/tests/app_loading/tests.py
index 6dd0be2194..e0c7cbd78c 100644
--- a/tests/app_loading/tests.py
+++ b/tests/app_loading/tests.py
@@ -4,11 +4,12 @@ import copy
import os
import sys
import time
+from unittest import TestCase
from django.conf import Settings
from django.db.models.loading import cache, load_app, get_model, get_models
from django.utils._os import upath
-from django.utils.unittest import TestCase
+
class EggLoadingTest(TestCase):
diff --git a/tests/backends/tests.py b/tests/backends/tests.py
index c1a26df7fc..b1bfa4cb21 100644
--- a/tests/backends/tests.py
+++ b/tests/backends/tests.py
@@ -5,6 +5,7 @@ from __future__ import absolute_import, unicode_literals
import datetime
from decimal import Decimal
import threading
+import unittest
from django.conf import settings
from django.core.management.color import no_style
@@ -21,7 +22,7 @@ from django.db.utils import ConnectionHandler
from django.test import (TestCase, skipUnlessDBFeature, skipIfDBFeature,
TransactionTestCase)
from django.test.utils import override_settings, str_prefix
-from django.utils import six, unittest
+from django.utils import six
from django.utils.six.moves import xrange
from . import models
@@ -164,6 +165,17 @@ class DateQuotingTest(TestCase):
@override_settings(DEBUG=True)
class LastExecutedQueryTest(TestCase):
+ def test_last_executed_query(self):
+ """
+ last_executed_query should not raise an exception even if no previous
+ query has been run.
+ """
+ cursor = connection.cursor()
+ try:
+ connection.ops.last_executed_query(cursor, '', ())
+ except Exception:
+ self.fail("'last_executed_query' should not raise an exception.")
+
def test_debug_sql(self):
list(models.Reporter.objects.filter(first_name="test"))
sql = connection.queries[-1]['sql'].lower()
@@ -458,7 +470,7 @@ class BackendTestCase(TestCase):
def create_squares_with_executemany(self, args):
self.create_squares(args, 'format', True)
- def create_squares(self, args, paramstyle, multiple):
+ def create_squares(self, args, paramstyle, multiple):
cursor = connection.cursor()
opts = models.Square._meta
tbl = connection.introspection.table_name_converter(opts.db_table)
@@ -530,7 +542,7 @@ class BackendTestCase(TestCase):
# same test for DebugCursorWrapper
self.create_squares(args, 'pyformat', multiple=True)
self.assertEqual(models.Square.objects.count(), 9)
-
+
def test_unicode_fetches(self):
#6254: fetchone, fetchmany, fetchall return strings as unicode objects
qn = connection.ops.quote_name
diff --git a/tests/bash_completion/tests.py b/tests/bash_completion/tests.py
index 4fdb793feb..2da68b588a 100644
--- a/tests/bash_completion/tests.py
+++ b/tests/bash_completion/tests.py
@@ -3,10 +3,10 @@ A series of tests to establish that the command-line bash completion works.
"""
import os
import sys
+import unittest
from django.conf import settings
from django.core.management import ManagementUtility
-from django.utils import unittest
from django.utils.six import StringIO
diff --git a/tests/bug639/tests.py b/tests/bug639/tests.py
index fcc1e0f7d1..71c50e14aa 100644
--- a/tests/bug639/tests.py
+++ b/tests/bug639/tests.py
@@ -8,9 +8,9 @@ from __future__ import absolute_import
import os
import shutil
+import unittest
from django.core.files.uploadedfile import SimpleUploadedFile
-from django.utils import unittest
from django.utils._os import upath
from .models import Photo, PhotoForm, temp_storage_dir
diff --git a/tests/bug8245/tests.py b/tests/bug8245/tests.py
index 5da0b1f718..7a91d04af1 100644
--- a/tests/bug8245/tests.py
+++ b/tests/bug8245/tests.py
@@ -1,5 +1,6 @@
+from unittest import TestCase
+
from django.contrib import admin
-from django.utils.unittest import TestCase
class Bug8245Test(TestCase):
diff --git a/tests/builtin_server/tests.py b/tests/builtin_server/tests.py
index 662466a110..ef215ccf97 100644
--- a/tests/builtin_server/tests.py
+++ b/tests/builtin_server/tests.py
@@ -1,9 +1,9 @@
from __future__ import unicode_literals
from io import BytesIO
+from unittest import TestCase
from django.core.servers.basehttp import ServerHandler, MAX_SOCKET_CHUNK_SIZE
-from django.utils.unittest import TestCase
class DummyHandler(object):
diff --git a/tests/cache/tests.py b/tests/cache/tests.py
index 7413a4aae6..bccac6b5a8 100644
--- a/tests/cache/tests.py
+++ b/tests/cache/tests.py
@@ -6,13 +6,14 @@ from __future__ import absolute_import, unicode_literals
import hashlib
import os
+import pickle
import random
import re
import string
import tempfile
import time
+import unittest
import warnings
-import pickle
from django.conf import settings
from django.core import management
@@ -28,8 +29,10 @@ from django.middleware.cache import (FetchFromCacheMiddleware,
from django.template import Template
from django.template.response import TemplateResponse
from django.test import TestCase, TransactionTestCase, RequestFactory
-from django.test.utils import override_settings, IgnorePendingDeprecationWarningsMixin
-from django.utils import six, timezone, translation, unittest
+from django.test.utils import override_settings, IgnoreDeprecationWarningsMixin
+from django.utils import six
+from django.utils import timezone
+from django.utils import translation
from django.utils.cache import (patch_vary_headers, get_cache_key,
learn_cache_key, patch_cache_control, patch_response_headers)
from django.utils.encoding import force_text
@@ -1594,7 +1597,7 @@ def hello_world_view(request, value):
},
},
)
-class CacheMiddlewareTest(IgnorePendingDeprecationWarningsMixin, TestCase):
+class CacheMiddlewareTest(IgnoreDeprecationWarningsMixin, TestCase):
def setUp(self):
super(CacheMiddlewareTest, self).setUp()
diff --git a/tests/db_typecasts/tests.py b/tests/db_typecasts/tests.py
index 2cf835d94e..fc5305dcdd 100644
--- a/tests/db_typecasts/tests.py
+++ b/tests/db_typecasts/tests.py
@@ -1,10 +1,10 @@
# Unit tests for typecast functions in django.db.backends.util
import datetime
+import unittest
from django.db.backends import util as typecasts
from django.utils import six
-from django.utils import unittest
TEST_CASES = {
diff --git a/tests/decorators/tests.py b/tests/decorators/tests.py
index 05016be231..2aaea49500 100644
--- a/tests/decorators/tests.py
+++ b/tests/decorators/tests.py
@@ -1,4 +1,5 @@
from functools import wraps
+from unittest import TestCase
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.decorators import login_required, permission_required, user_passes_test
@@ -6,7 +7,6 @@ from django.http import HttpResponse, HttpRequest, HttpResponseNotAllowed
from django.middleware.clickjacking import XFrameOptionsMiddleware
from django.utils.decorators import method_decorator
from django.utils.functional import allow_lazy, lazy, memoize
-from django.utils.unittest import TestCase
from django.views.decorators.cache import cache_page, never_cache, cache_control
from django.views.decorators.clickjacking import xframe_options_deny, xframe_options_sameorigin, xframe_options_exempt
from django.views.decorators.http import require_http_methods, require_GET, require_POST, require_safe, condition
diff --git a/tests/defaultfilters/tests.py b/tests/defaultfilters/tests.py
index d0009c6e66..15b96be881 100644
--- a/tests/defaultfilters/tests.py
+++ b/tests/defaultfilters/tests.py
@@ -3,11 +3,12 @@ from __future__ import unicode_literals
import datetime
import decimal
+import unittest
from django.template.defaultfilters import *
from django.test import TestCase
from django.utils import six
-from django.utils import unittest, translation
+from django.utils import translation
from django.utils.safestring import SafeData
from django.utils.encoding import python_2_unicode_compatible
diff --git a/tests/deprecation/tests.py b/tests/deprecation/tests.py
index df752b3149..fda780c7e6 100644
--- a/tests/deprecation/tests.py
+++ b/tests/deprecation/tests.py
@@ -8,7 +8,7 @@ from django.utils.deprecation import RenameMethodsBase
class RenameManagerMethods(RenameMethodsBase):
renamed_methods = (
- ('old', 'new', PendingDeprecationWarning),
+ ('old', 'new', DeprecationWarning),
)
diff --git a/tests/dispatch/tests/test_dispatcher.py b/tests/dispatch/tests/test_dispatcher.py
index a1d4c7e176..5f7dca87cc 100644
--- a/tests/dispatch/tests/test_dispatcher.py
+++ b/tests/dispatch/tests/test_dispatcher.py
@@ -1,9 +1,9 @@
import gc
import sys
import time
+import unittest
from django.dispatch import Signal, receiver
-from django.utils import unittest
if sys.platform.startswith('java'):
diff --git a/tests/dispatch/tests/test_saferef.py b/tests/dispatch/tests/test_saferef.py
index 30eaddfe18..a9a246304e 100644
--- a/tests/dispatch/tests/test_saferef.py
+++ b/tests/dispatch/tests/test_saferef.py
@@ -1,6 +1,7 @@
+import unittest
+
from django.dispatch.saferef import safeRef
from django.utils.six.moves import xrange
-from django.utils import unittest
class Test1(object):
def x(self):
diff --git a/tests/file_storage/tests.py b/tests/file_storage/tests.py
index 6c3c559660..8cf4c33091 100644
--- a/tests/file_storage/tests.py
+++ b/tests/file_storage/tests.py
@@ -7,6 +7,7 @@ import shutil
import sys
import tempfile
import time
+import unittest
try:
from urllib.request import urlopen
except ImportError: # Python 2
@@ -28,7 +29,6 @@ from django.core.files.storage import FileSystemStorage, get_storage_class
from django.core.files.uploadedfile import UploadedFile
from django.test import LiveServerTestCase, SimpleTestCase
from django.utils import six
-from django.utils import unittest
from django.utils._os import upath
from django.test.utils import override_settings
@@ -364,6 +364,14 @@ class FileStorageTests(unittest.TestCase):
with self.assertRaises(IOError):
self.storage.save('error.file', f1)
+ def test_delete_no_name(self):
+ """
+ Calling delete with an empty name should not try to remove the base
+ storage directory, but fail loudly (#20660).
+ """
+ with self.assertRaises(AssertionError):
+ self.storage.delete('')
+
class CustomStorage(FileSystemStorage):
def get_available_name(self, name):
diff --git a/tests/file_uploads/tests.py b/tests/file_uploads/tests.py
index 45e7342abd..66bc4465a2 100644
--- a/tests/file_uploads/tests.py
+++ b/tests/file_uploads/tests.py
@@ -8,6 +8,7 @@ import json
import os
import shutil
import tempfile as sys_tempfile
+import unittest
from django.core.files import temp as tempfile
from django.core.files.uploadedfile import SimpleUploadedFile
@@ -16,7 +17,6 @@ from django.test import TestCase, client
from django.test.utils import override_settings
from django.utils.encoding import force_bytes
from django.utils.six import StringIO
-from django.utils import unittest
from . import uploadhandler
from .models import FileModel
diff --git a/tests/files/tests.py b/tests/files/tests.py
index f1e3d5b14b..54eeee13e4 100644
--- a/tests/files/tests.py
+++ b/tests/files/tests.py
@@ -4,6 +4,7 @@ import os
import gzip
import shutil
import tempfile
+import unittest
from django.core.cache import cache
from django.core.files import File
@@ -11,7 +12,6 @@ from django.core.files.move import file_move_safe
from django.core.files.base import ContentFile
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
-from django.utils import unittest
from django.utils.six import StringIO
from .models import Storage, temp_storage, temp_storage_location
diff --git a/tests/fixtures/tests.py b/tests/fixtures/tests.py
index d0942afdb7..6f2218b19e 100644
--- a/tests/fixtures/tests.py
+++ b/tests/fixtures/tests.py
@@ -56,7 +56,7 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
def test_loading_and_dumping(self):
Site.objects.all().delete()
# Load fixture 1. Single JSON file, with two objects.
- management.call_command('loaddata', 'fixture1.json', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture1.json', verbosity=0)
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: Time to reform copyright>',
'<Article: Poker has no place on ESPN>',
@@ -87,7 +87,7 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
self._dumpdata_assert(['fixtures.Category', 'sites'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 1, "model": "sites.site", "fields": {"domain": "example.com", "name": "example.com"}}]')
# Load fixture 2. JSON file imported by default. Overwrites some existing objects
- management.call_command('loaddata', 'fixture2.json', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture2.json', verbosity=0)
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: Django conquers world!>',
'<Article: Copyright is fine the way it is>',
@@ -95,7 +95,7 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
])
# Load fixture 3, XML format.
- management.call_command('loaddata', 'fixture3.xml', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture3.xml', verbosity=0)
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: XML identified as leading cause of cancer>',
'<Article: Django conquers world!>',
@@ -104,14 +104,14 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
])
# Load fixture 6, JSON file with dynamic ContentType fields. Testing ManyToOne.
- management.call_command('loaddata', 'fixture6.json', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture6.json', verbosity=0)
self.assertQuerysetEqual(Tag.objects.all(), [
'<Tag: <Article: Copyright is fine the way it is> tagged "copyright">',
'<Tag: <Article: Copyright is fine the way it is> tagged "law">',
], ordered=False)
# Load fixture 7, XML file with dynamic ContentType fields. Testing ManyToOne.
- management.call_command('loaddata', 'fixture7.xml', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture7.xml', verbosity=0)
self.assertQuerysetEqual(Tag.objects.all(), [
'<Tag: <Article: Copyright is fine the way it is> tagged "copyright">',
'<Tag: <Article: Copyright is fine the way it is> tagged "legal">',
@@ -120,7 +120,7 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
], ordered=False)
# Load fixture 8, JSON file with dynamic Permission fields. Testing ManyToMany.
- management.call_command('loaddata', 'fixture8.json', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture8.json', verbosity=0)
self.assertQuerysetEqual(Visa.objects.all(), [
'<Visa: Django Reinhardt Can add user, Can change user, Can delete user>',
'<Visa: Stephane Grappelli Can add user>',
@@ -128,7 +128,7 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
], ordered=False)
# Load fixture 9, XML file with dynamic Permission fields. Testing ManyToMany.
- management.call_command('loaddata', 'fixture9.xml', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture9.xml', verbosity=0)
self.assertQuerysetEqual(Visa.objects.all(), [
'<Visa: Django Reinhardt Can add user, Can change user, Can delete user>',
'<Visa: Stephane Grappelli Can add user, Can delete user>',
@@ -143,15 +143,13 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
# Loading a fixture that doesn't exist emits a warning
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
- management.call_command('loaddata', 'unknown.json', verbosity=0,
- commit=False)
+ management.call_command('loaddata', 'unknown.json', verbosity=0)
self.assertEqual(len(w), 1)
self.assertTrue(w[0].message, "No fixture named 'unknown' found.")
# An attempt to load a nonexistent 'initial_data' fixture isn't an error
with warnings.catch_warnings(record=True) as w:
- management.call_command('loaddata', 'initial_data.json', verbosity=0,
- commit=False)
+ management.call_command('loaddata', 'initial_data.json', verbosity=0)
self.assertEqual(len(w), 0)
# object list is unaffected
@@ -178,7 +176,7 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
def test_dumpdata_with_excludes(self):
# Load fixture1 which has a site, two articles, and a category
Site.objects.all().delete()
- management.call_command('loaddata', 'fixture1.json', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture1.json', verbosity=0)
# Excluding fixtures app should only leave sites
self._dumpdata_assert(
@@ -226,8 +224,8 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
self._dumpdata_assert(['fixtures.Spy'], '[{"pk": %d, "model": "fixtures.spy", "fields": {"cover_blown": true}}, {"pk": %d, "model": "fixtures.spy", "fields": {"cover_blown": false}}]' % (spy2.pk, spy1.pk), use_base_manager=True)
def test_dumpdata_with_pks(self):
- management.call_command('loaddata', 'fixture1.json', verbosity=0, commit=False)
- management.call_command('loaddata', 'fixture2.json', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture1.json', verbosity=0)
+ management.call_command('loaddata', 'fixture2.json', verbosity=0)
self._dumpdata_assert(
['fixtures.Article'],
'[{"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16T12:00:00"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Copyright is fine the way it is", "pub_date": "2006-06-16T14:00:00"}}]',
@@ -266,21 +264,21 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
def test_compress_format_loading(self):
# Load fixture 4 (compressed), using format specification
- management.call_command('loaddata', 'fixture4.json', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture4.json', verbosity=0)
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: Django pets kitten>',
])
def test_compressed_specified_loading(self):
# Load fixture 5 (compressed), using format *and* compression specification
- management.call_command('loaddata', 'fixture5.json.zip', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture5.json.zip', verbosity=0)
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: WoW subscribers now outnumber readers>',
])
def test_compressed_loading(self):
# Load fixture 5 (compressed), only compression specification
- management.call_command('loaddata', 'fixture5.zip', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture5.zip', verbosity=0)
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: WoW subscribers now outnumber readers>',
])
@@ -288,13 +286,13 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
def test_ambiguous_compressed_fixture(self):
# The name "fixture5" is ambigous, so loading it will raise an error
with self.assertRaises(management.CommandError) as cm:
- management.call_command('loaddata', 'fixture5', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture5', verbosity=0)
self.assertIn("Multiple fixtures named 'fixture5'", cm.exception.args[0])
def test_db_loading(self):
# Load db fixtures 1 and 2. These will load using the 'default' database identifier implicitly
- management.call_command('loaddata', 'db_fixture_1', verbosity=0, commit=False)
- management.call_command('loaddata', 'db_fixture_2', verbosity=0, commit=False)
+ management.call_command('loaddata', 'db_fixture_1', verbosity=0)
+ management.call_command('loaddata', 'db_fixture_2', verbosity=0)
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: Who needs more than one database?>',
'<Article: Who needs to use compressed data?>',
@@ -312,13 +310,13 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
if connection.vendor == 'mysql':
connection.cursor().execute("SET sql_mode = 'TRADITIONAL'")
with self.assertRaises(IntegrityError) as cm:
- management.call_command('loaddata', 'invalid.json', verbosity=0, commit=False)
+ management.call_command('loaddata', 'invalid.json', verbosity=0)
self.assertIn("Could not load fixtures.Article(pk=1):", cm.exception.args[0])
def test_loading_using(self):
# Load db fixtures 1 and 2. These will load using the 'default' database identifier explicitly
- management.call_command('loaddata', 'db_fixture_1', verbosity=0, using='default', commit=False)
- management.call_command('loaddata', 'db_fixture_2', verbosity=0, using='default', commit=False)
+ management.call_command('loaddata', 'db_fixture_1', verbosity=0, using='default')
+ management.call_command('loaddata', 'db_fixture_2', verbosity=0, using='default')
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: Who needs more than one database?>',
'<Article: Who needs to use compressed data?>',
@@ -327,18 +325,18 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
def test_unmatched_identifier_loading(self):
# Try to load db fixture 3. This won't load because the database identifier doesn't match
with warnings.catch_warnings(record=True):
- management.call_command('loaddata', 'db_fixture_3', verbosity=0, commit=False)
+ management.call_command('loaddata', 'db_fixture_3', verbosity=0)
with warnings.catch_warnings(record=True):
- management.call_command('loaddata', 'db_fixture_3', verbosity=0, using='default', commit=False)
+ management.call_command('loaddata', 'db_fixture_3', verbosity=0, using='default')
self.assertQuerysetEqual(Article.objects.all(), [])
def test_output_formats(self):
# Load back in fixture 1, we need the articles from it
- management.call_command('loaddata', 'fixture1', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture1', verbosity=0)
# Try to load fixture 6 using format discovery
- management.call_command('loaddata', 'fixture6', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture6', verbosity=0)
self.assertQuerysetEqual(Tag.objects.all(), [
'<Tag: <Article: Time to reform copyright> tagged "copyright">',
'<Tag: <Article: Time to reform copyright> tagged "law">'
@@ -364,7 +362,7 @@ class FixtureTransactionTests(DumpDataAssertMixin, TransactionTestCase):
@skipUnlessDBFeature('supports_forward_references')
def test_format_discovery(self):
# Load fixture 1 again, using format discovery
- management.call_command('loaddata', 'fixture1', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture1', verbosity=0)
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: Time to reform copyright>',
'<Article: Poker has no place on ESPN>',
@@ -386,7 +384,7 @@ class FixtureTransactionTests(DumpDataAssertMixin, TransactionTestCase):
self._dumpdata_assert(['fixtures'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16T12:00:00"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16T13:00:00"}}, {"pk": 10, "model": "fixtures.book", "fields": {"name": "Achieving self-awareness of Python programs", "authors": []}}]')
# Load fixture 4 (compressed), using format discovery
- management.call_command('loaddata', 'fixture4', verbosity=0, commit=False)
+ management.call_command('loaddata', 'fixture4', verbosity=0)
self.assertQuerysetEqual(Article.objects.all(), [
'<Article: Django pets kitten>',
'<Article: Time to reform copyright>',
diff --git a/tests/fixtures_model_package/tests.py b/tests/fixtures_model_package/tests.py
index dbcc721d8f..4b00e6dfb9 100644
--- a/tests/fixtures_model_package/tests.py
+++ b/tests/fixtures_model_package/tests.py
@@ -60,7 +60,6 @@ class TestNoInitialDataLoading(TransactionTestCase):
'flush',
verbosity=0,
interactive=False,
- commit=False,
load_initial_data=False
)
self.assertQuerysetEqual(Book.objects.all(), [])
@@ -83,7 +82,7 @@ class FixtureTestCase(TestCase):
def test_loaddata(self):
"Fixtures can load data into models defined in packages"
# Load fixture 1. Single JSON file, with two objects
- management.call_command("loaddata", "fixture1.json", verbosity=0, commit=False)
+ management.call_command("loaddata", "fixture1.json", verbosity=0)
self.assertQuerysetEqual(
Article.objects.all(), [
"Time to reform copyright",
@@ -94,7 +93,7 @@ class FixtureTestCase(TestCase):
# Load fixture 2. JSON file imported by default. Overwrites some
# existing objects
- management.call_command("loaddata", "fixture2.json", verbosity=0, commit=False)
+ management.call_command("loaddata", "fixture2.json", verbosity=0)
self.assertQuerysetEqual(
Article.objects.all(), [
"Django conquers world!",
@@ -107,7 +106,7 @@ class FixtureTestCase(TestCase):
# Load a fixture that doesn't exist
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
- management.call_command("loaddata", "unknown.json", verbosity=0, commit=False)
+ management.call_command("loaddata", "unknown.json", verbosity=0)
self.assertEqual(len(w), 1)
self.assertTrue(w[0].message, "No fixture named 'unknown' found.")
diff --git a/tests/fixtures_regress/tests.py b/tests/fixtures_regress/tests.py
index 0f6ac65976..a9d67ec9a2 100644
--- a/tests/fixtures_regress/tests.py
+++ b/tests/fixtures_regress/tests.py
@@ -45,7 +45,6 @@ class TestFixtures(TestCase):
'loaddata',
'sequence',
verbosity=0,
- commit=False
)
# Create a new animal. Without a sequence reset, this new object
@@ -84,7 +83,6 @@ class TestFixtures(TestCase):
'sequence_extra',
ignore=True,
verbosity=0,
- commit=False
)
self.assertEqual(Animal.specimens.all()[0].name, 'Lion')
@@ -98,7 +96,6 @@ class TestFixtures(TestCase):
'sequence_extra_xml',
ignore=True,
verbosity=0,
- commit=False
)
self.assertEqual(Animal.specimens.all()[0].name, 'Wolf')
@@ -113,7 +110,6 @@ class TestFixtures(TestCase):
'loaddata',
'pretty.xml',
verbosity=0,
- commit=False
)
self.assertEqual(Stuff.objects.all()[0].name, None)
self.assertEqual(Stuff.objects.all()[0].owner, None)
@@ -129,7 +125,6 @@ class TestFixtures(TestCase):
'loaddata',
'pretty.xml',
verbosity=0,
- commit=False
)
self.assertEqual(Stuff.objects.all()[0].name, '')
self.assertEqual(Stuff.objects.all()[0].owner, None)
@@ -152,7 +147,6 @@ class TestFixtures(TestCase):
'loaddata',
load_absolute_path,
verbosity=0,
- commit=False
)
self.assertEqual(Absolute.load_count, 1)
@@ -168,7 +162,6 @@ class TestFixtures(TestCase):
'loaddata',
'bad_fixture1.unkn',
verbosity=0,
- commit=False,
)
@override_settings(SERIALIZATION_MODULES={'unkn': 'unexistent.path'})
@@ -182,7 +175,6 @@ class TestFixtures(TestCase):
'loaddata',
'bad_fixture1.unkn',
verbosity=0,
- commit=False,
)
def test_invalid_data(self):
@@ -197,7 +189,6 @@ class TestFixtures(TestCase):
'loaddata',
'bad_fixture2.xml',
verbosity=0,
- commit=False,
)
def test_invalid_data_no_ext(self):
@@ -212,7 +203,6 @@ class TestFixtures(TestCase):
'loaddata',
'bad_fixture2',
verbosity=0,
- commit=False,
)
def test_empty(self):
@@ -226,7 +216,6 @@ class TestFixtures(TestCase):
'loaddata',
'empty',
verbosity=0,
- commit=False,
)
def test_error_message(self):
@@ -240,7 +229,6 @@ class TestFixtures(TestCase):
'bad_fixture2',
'animal',
verbosity=0,
- commit=False,
)
def test_pg_sequence_resetting_checks(self):
@@ -253,7 +241,6 @@ class TestFixtures(TestCase):
'loaddata',
'model-inheritance.json',
verbosity=0,
- commit=False
)
self.assertEqual(Parent.objects.all()[0].id, 1)
self.assertEqual(Child.objects.all()[0].id, 1)
@@ -270,7 +257,6 @@ class TestFixtures(TestCase):
'loaddata',
'big-fixture.json',
verbosity=0,
- commit=False
)
articles = Article.objects.exclude(id=9)
self.assertEqual(
@@ -297,7 +283,6 @@ class TestFixtures(TestCase):
'loaddata',
'animal.xml',
verbosity=0,
- commit=False,
)
self.assertEqual(
self.pre_save_checks,
@@ -319,13 +304,11 @@ class TestFixtures(TestCase):
'loaddata',
'animal.xml',
verbosity=0,
- commit=False,
)
management.call_command(
'loaddata',
'sequence.json',
verbosity=0,
- commit=False,
)
animal = Animal(
name='Platypus',
@@ -390,7 +373,6 @@ class TestFixtures(TestCase):
'loaddata',
'forward_ref.json',
verbosity=0,
- commit=False
)
self.assertEqual(Book.objects.all()[0].id, 1)
self.assertEqual(Person.objects.all()[0].id, 4)
@@ -405,7 +387,6 @@ class TestFixtures(TestCase):
'loaddata',
'forward_ref_bad_data.json',
verbosity=0,
- commit=False,
)
_cur_dir = os.path.dirname(os.path.abspath(upath(__file__)))
@@ -422,7 +403,6 @@ class TestFixtures(TestCase):
'forward_ref_1.json',
'forward_ref_2.json',
verbosity=0,
- commit=False
)
self.assertEqual(Book.objects.all()[0].id, 1)
self.assertEqual(Person.objects.all()[0].id, 4)
@@ -437,7 +417,6 @@ class TestFixtures(TestCase):
management.call_command(
'loaddata',
verbosity=0,
- commit=False,
)
def test_loaddata_not_existant_fixture_file(self):
@@ -447,7 +426,6 @@ class TestFixtures(TestCase):
'loaddata',
'this_fixture_doesnt_exist',
verbosity=2,
- commit=False,
stdout=stdout_output,
)
self.assertTrue("No fixture 'this_fixture_doesnt_exist' in" in
@@ -465,13 +443,11 @@ class NaturalKeyFixtureTests(TestCase):
'loaddata',
'model-inheritance.json',
verbosity=0,
- commit=False
)
management.call_command(
'loaddata',
'nk-inheritance.json',
verbosity=0,
- commit=False
)
self.assertEqual(
NKChild.objects.get(pk=1).data,
@@ -492,19 +468,16 @@ class NaturalKeyFixtureTests(TestCase):
'loaddata',
'model-inheritance.json',
verbosity=0,
- commit=False
)
management.call_command(
'loaddata',
'nk-inheritance.json',
verbosity=0,
- commit=False
)
management.call_command(
'loaddata',
'nk-inheritance2.xml',
verbosity=0,
- commit=False
)
self.assertEqual(
NKChild.objects.get(pk=2).data,
@@ -524,7 +497,6 @@ class NaturalKeyFixtureTests(TestCase):
'loaddata',
'forward_ref_lookup.json',
verbosity=0,
- commit=False
)
stdout = StringIO()
@@ -662,19 +634,16 @@ class NaturalKeyFixtureTests(TestCase):
'loaddata',
'non_natural_1.json',
verbosity=0,
- commit=False
)
management.call_command(
'loaddata',
'forward_ref_lookup.json',
verbosity=0,
- commit=False
)
management.call_command(
'loaddata',
'non_natural_2.xml',
verbosity=0,
- commit=False
)
books = Book.objects.all()
self.assertEqual(
@@ -696,7 +665,6 @@ class TestTicket11101(TransactionTestCase):
'loaddata',
'thingy.json',
verbosity=0,
- commit=False
)
self.assertEqual(Thingy.objects.count(), 1)
transaction.rollback()
diff --git a/tests/forms_tests/tests/test_validators.py b/tests/forms_tests/tests/test_validators.py
index 0598835cff..08fb96618c 100644
--- a/tests/forms_tests/tests/test_validators.py
+++ b/tests/forms_tests/tests/test_validators.py
@@ -1,9 +1,10 @@
from __future__ import unicode_literals
+from unittest import TestCase
+
from django import forms
from django.core import validators
from django.core.exceptions import ValidationError
-from django.utils.unittest import TestCase
class UserForm(forms.Form):
diff --git a/tests/generic_views/test_base.py b/tests/generic_views/test_base.py
index f95732f8b5..013a8f282c 100644
--- a/tests/generic_views/test_base.py
+++ b/tests/generic_views/test_base.py
@@ -1,11 +1,11 @@
from __future__ import absolute_import
import time
+import unittest
from django.core.exceptions import ImproperlyConfigured
from django.http import HttpResponse
from django.test import TestCase, RequestFactory
-from django.utils import unittest
from django.views.generic import View, TemplateView, RedirectView
from . import views
diff --git a/tests/generic_views/test_dates.py b/tests/generic_views/test_dates.py
index 263326322e..bff909f7d0 100644
--- a/tests/generic_views/test_dates.py
+++ b/tests/generic_views/test_dates.py
@@ -2,12 +2,12 @@ from __future__ import absolute_import
import time
import datetime
+from unittest import skipUnless
from django.core.exceptions import ImproperlyConfigured
from django.test import TestCase, skipUnlessDBFeature
from django.test.utils import override_settings
from django.utils import timezone
-from django.utils.unittest import skipUnless
from .models import Book, BookSigning
diff --git a/tests/generic_views/test_edit.py b/tests/generic_views/test_edit.py
index 84d18ebcb2..9ed18833e4 100644
--- a/tests/generic_views/test_edit.py
+++ b/tests/generic_views/test_edit.py
@@ -1,12 +1,12 @@
from __future__ import absolute_import
import warnings
+from unittest import expectedFailure
from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import reverse
from django import forms
from django.test import TestCase
-from django.utils.unittest import expectedFailure
from django.test.client import RequestFactory
from django.views.generic.base import View
from django.views.generic.edit import FormMixin, CreateView
@@ -146,7 +146,7 @@ class CreateViewTests(TestCase):
def test_create_view_all_fields(self):
with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always", PendingDeprecationWarning)
+ warnings.simplefilter("always", DeprecationWarning)
class MyCreateView(CreateView):
model = Author
@@ -160,7 +160,7 @@ class CreateViewTests(TestCase):
def test_create_view_without_explicit_fields(self):
with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always", PendingDeprecationWarning)
+ warnings.simplefilter("always", DeprecationWarning)
class MyCreateView(CreateView):
model = Author
@@ -171,7 +171,7 @@ class CreateViewTests(TestCase):
['name', 'slug'])
# but with a warning:
- self.assertEqual(w[0].category, PendingDeprecationWarning)
+ self.assertEqual(w[0].category, DeprecationWarning)
class UpdateViewTests(TestCase):
diff --git a/tests/httpwrappers/tests.py b/tests/httpwrappers/tests.py
index 194232e92f..3a2ec23864 100644
--- a/tests/httpwrappers/tests.py
+++ b/tests/httpwrappers/tests.py
@@ -4,6 +4,7 @@ from __future__ import unicode_literals
import copy
import os
import pickle
+import unittest
import warnings
from django.core.exceptions import SuspiciousOperation
@@ -18,7 +19,6 @@ from django.test import TestCase
from django.utils.encoding import smart_str
from django.utils._os import upath
from django.utils import six
-from django.utils import unittest
class QueryDictTests(unittest.TestCase):
@@ -324,19 +324,10 @@ class HttpResponseTests(unittest.TestCase):
r.content = [1, 2, 3]
self.assertEqual(r.content, b'123')
- #test retrieval explicitly using iter (deprecated) and odd inputs
+ #test odd inputs
r = HttpResponse()
r.content = ['1', '2', 3, '\u079e']
- with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always", DeprecationWarning)
- my_iter = iter(r)
- self.assertEqual(w[0].category, DeprecationWarning)
- with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always", DeprecationWarning)
- result = list(my_iter)
- self.assertEqual(w[0].category, DeprecationWarning)
#'\xde\x9e' == unichr(1950).encode('utf-8')
- self.assertEqual(result, [b'1', b'2', b'3', b'\xde\x9e'])
self.assertEqual(r.content, b'123\xde\x9e')
#with Content-Encoding header
@@ -344,9 +335,8 @@ class HttpResponseTests(unittest.TestCase):
r['Content-Encoding'] = 'winning'
r.content = [b'abc', b'def']
self.assertEqual(r.content, b'abcdef')
- r.content = ['\u079e']
self.assertRaises(TypeError if six.PY3 else UnicodeEncodeError,
- getattr, r, 'content')
+ setattr, r, 'content', ['\u079e'])
# .content can safely be accessed multiple times.
r = HttpResponse(iter(['hello', 'world']))
@@ -358,15 +348,12 @@ class HttpResponseTests(unittest.TestCase):
# accessing .content still works
self.assertEqual(r.content, b'helloworld')
- # XXX accessing .content doesn't work if the response was iterated first
- # XXX change this when the deprecation completes in HttpResponse
+ # Accessing .content also works if the response was iterated first.
r = HttpResponse(iter(['hello', 'world']))
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- self.assertEqual(b''.join(r), b'helloworld')
- self.assertEqual(r.content, b'') # not the expected result!
+ self.assertEqual(b''.join(r), b'helloworld')
+ self.assertEqual(r.content, b'helloworld')
- # additional content can be written to the response.
+ # Additional content can be written to the response.
r = HttpResponse(iter(['hello', 'world']))
self.assertEqual(r.content, b'helloworld')
r.write('!')
diff --git a/tests/indexes/tests.py b/tests/indexes/tests.py
index 672e35d286..605fe9037c 100644
--- a/tests/indexes/tests.py
+++ b/tests/indexes/tests.py
@@ -1,7 +1,8 @@
+from unittest import skipUnless
+
from django.core.management.color import no_style
from django.db import connections, DEFAULT_DB_ALIAS
from django.test import TestCase
-from django.utils.unittest import skipUnless
from .models import Article
diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py
index 79cbbfa3f2..c9093b9e9e 100644
--- a/tests/inspectdb/tests.py
+++ b/tests/inspectdb/tests.py
@@ -2,11 +2,11 @@
from __future__ import unicode_literals
import re
+from unittest import expectedFailure
from django.core.management import call_command
from django.db import connection
from django.test import TestCase, skipUnlessDBFeature
-from django.utils.unittest import expectedFailure
from django.utils.six import PY3, StringIO
if connection.vendor == 'oracle':
diff --git a/tests/introspection/tests.py b/tests/introspection/tests.py
index 67e0266a66..f1c87bbf14 100644
--- a/tests/introspection/tests.py
+++ b/tests/introspection/tests.py
@@ -1,8 +1,9 @@
from __future__ import absolute_import, unicode_literals
+import unittest
+
from django.db import connection
from django.test import TestCase, skipUnlessDBFeature, skipIfDBFeature
-from django.utils import unittest
from .models import Reporter, Article
diff --git a/tests/invalid_models/tests.py b/tests/invalid_models/tests.py
index f878525b3b..9c9db91da9 100644
--- a/tests/invalid_models/tests.py
+++ b/tests/invalid_models/tests.py
@@ -1,11 +1,10 @@
import copy
import sys
+import unittest
from django.core.management.validation import get_validation_errors
from django.db.models.loading import cache, load_app
-
from django.test.utils import override_settings
-from django.utils import unittest
from django.utils.six import StringIO
diff --git a/tests/logging_tests/tests.py b/tests/logging_tests/tests.py
index 0c2d269464..cae2860306 100644
--- a/tests/logging_tests/tests.py
+++ b/tests/logging_tests/tests.py
@@ -3,6 +3,7 @@ from __future__ import unicode_literals
import copy
import logging
import sys
+from unittest import skipUnless
import warnings
from django.conf import LazySettings
@@ -13,7 +14,6 @@ from django.utils.encoding import force_text
from django.utils.log import (CallbackFilter, RequireDebugFalse,
RequireDebugTrue)
from django.utils.six import StringIO
-from django.utils.unittest import skipUnless
from admin_scripts.tests import AdminScriptTestCase
diff --git a/tests/max_lengths/tests.py b/tests/max_lengths/tests.py
index 9dfcabff45..0f525864d5 100644
--- a/tests/max_lengths/tests.py
+++ b/tests/max_lengths/tests.py
@@ -1,6 +1,6 @@
from __future__ import absolute_import
-from django.utils import unittest
+import unittest
from .models import PersonWithDefaultMaxLengths, PersonWithCustomMaxLengths
@@ -36,4 +36,4 @@ class MaxLengthORMTests(unittest.TestCase):
new_args = args.copy()
new_args[field] = "X" * 250 # a value longer than any of the default fields could hold.
p = PersonWithCustomMaxLengths.objects.create(**new_args)
- self.assertEqual(getattr(p, field), ("X" * 250)) \ No newline at end of file
+ self.assertEqual(getattr(p, field), ("X" * 250))
diff --git a/tests/middleware/tests.py b/tests/middleware/tests.py
index 20645cf91f..5ceab2e594 100644
--- a/tests/middleware/tests.py
+++ b/tests/middleware/tests.py
@@ -5,6 +5,7 @@ import gzip
from io import BytesIO
import random
import re
+from unittest import expectedFailure, skipIf
import warnings
from django.conf import settings
@@ -18,11 +19,10 @@ from django.middleware.http import ConditionalGetMiddleware
from django.middleware.gzip import GZipMiddleware
from django.middleware.transaction import TransactionMiddleware
from django.test import TransactionTestCase, TestCase, RequestFactory
-from django.test.utils import override_settings, IgnorePendingDeprecationWarningsMixin
+from django.test.utils import override_settings, IgnoreDeprecationWarningsMixin
from django.utils import six
from django.utils.encoding import force_str
from django.utils.six.moves import xrange
-from django.utils.unittest import expectedFailure, skipIf
from .models import Band
@@ -249,7 +249,7 @@ class CommonMiddlewareTest(TestCase):
request = self._get_request('regular_url/that/does/not/exist')
request.META['HTTP_REFERER'] = '/another/url/'
with warnings.catch_warnings():
- warnings.simplefilter("ignore", PendingDeprecationWarning)
+ warnings.simplefilter("ignore", DeprecationWarning)
response = self.client.get(request.path)
CommonMiddleware().process_response(request, response)
self.assertEqual(len(mail.outbox), 1)
@@ -261,7 +261,7 @@ class CommonMiddlewareTest(TestCase):
def test_404_error_reporting_no_referer(self):
request = self._get_request('regular_url/that/does/not/exist')
with warnings.catch_warnings():
- warnings.simplefilter("ignore", PendingDeprecationWarning)
+ warnings.simplefilter("ignore", DeprecationWarning)
response = self.client.get(request.path)
CommonMiddleware().process_response(request, response)
self.assertEqual(len(mail.outbox), 0)
@@ -273,7 +273,7 @@ class CommonMiddlewareTest(TestCase):
request = self._get_request('foo_url/that/does/not/exist/either')
request.META['HTTP_REFERER'] = '/another/url/'
with warnings.catch_warnings():
- warnings.simplefilter("ignore", PendingDeprecationWarning)
+ warnings.simplefilter("ignore", DeprecationWarning)
response = self.client.get(request.path)
CommonMiddleware().process_response(request, response)
self.assertEqual(len(mail.outbox), 0)
@@ -703,7 +703,7 @@ class ETagGZipMiddlewareTest(TestCase):
self.assertNotEqual(gzip_etag, nogzip_etag)
-class TransactionMiddlewareTest(IgnorePendingDeprecationWarningsMixin, TransactionTestCase):
+class TransactionMiddlewareTest(IgnoreDeprecationWarningsMixin, TransactionTestCase):
"""
Test the transaction middleware.
"""
diff --git a/tests/model_fields/test_imagefield.py b/tests/model_fields/test_imagefield.py
index 457892ddb8..f6019bd77f 100644
--- a/tests/model_fields/test_imagefield.py
+++ b/tests/model_fields/test_imagefield.py
@@ -2,13 +2,13 @@ from __future__ import absolute_import
import os
import shutil
+from unittest import skipIf
from django.core.exceptions import ImproperlyConfigured
from django.core.files import File
from django.core.files.images import ImageFile
from django.test import TestCase
from django.utils._os import upath
-from django.utils.unittest import skipIf
try:
from .models import Image
diff --git a/tests/model_fields/tests.py b/tests/model_fields/tests.py
index ccff8b8cfa..6546c49ec7 100644
--- a/tests/model_fields/tests.py
+++ b/tests/model_fields/tests.py
@@ -2,6 +2,7 @@ from __future__ import absolute_import, unicode_literals
import datetime
from decimal import Decimal
+import unittest
from django import test
from django import forms
@@ -9,7 +10,6 @@ from django.core.exceptions import ValidationError
from django.db import connection, models, IntegrityError
from django.db.models.fields.files import FieldFile
from django.utils import six
-from django.utils import unittest
from .models import (Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post,
NullBooleanModel, BooleanModel, DataModel, Document, RenamedField,
@@ -432,6 +432,17 @@ class FileFieldTests(unittest.TestCase):
field.save_form_data(d, 'else.txt')
self.assertEqual(d.myfile, 'else.txt')
+ def test_delete_when_file_unset(self):
+ """
+ Calling delete on an unset FileField should not call the file deletion
+ process, but fail silently (#20660).
+ """
+ d = Document()
+ try:
+ d.myfile.delete()
+ except OSError:
+ self.fail("Deleting an unset FileField should not raise OSError.")
+
class BinaryFieldTests(test.TestCase):
binary_data = b'\x00\x46\xFE'
diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py
index 39be824798..09c62c5205 100644
--- a/tests/model_forms/tests.py
+++ b/tests/model_forms/tests.py
@@ -3,6 +3,7 @@ from __future__ import absolute_import, unicode_literals
import datetime
import os
from decimal import Decimal
+from unittest import skipUnless
import warnings
from django import forms
@@ -13,7 +14,6 @@ from django.db import connection
from django.db.models.query import EmptyQuerySet
from django.forms.models import model_to_dict
from django.utils._os import upath
-from django.utils.unittest import skipUnless
from django.test import TestCase
from django.utils import six
@@ -252,10 +252,12 @@ class StatusNoteCBM2mForm(forms.ModelForm):
fields = '__all__'
widgets = {'status': forms.CheckboxSelectMultiple}
+
class CustomErrorMessageForm(forms.ModelForm):
name1 = forms.CharField(error_messages={'invalid': 'Form custom error message.'})
class Meta:
+ fields = '__all__'
model = CustomErrorMessage
@@ -266,7 +268,7 @@ class ModelFormBaseTest(TestCase):
def test_missing_fields_attribute(self):
with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always", PendingDeprecationWarning)
+ warnings.simplefilter("always", DeprecationWarning)
class MissingFieldsForm(forms.ModelForm):
class Meta:
@@ -276,7 +278,7 @@ class ModelFormBaseTest(TestCase):
# if a warning has been seen already, the catch_warnings won't
# have recorded it. The following line therefore will not work reliably:
- # self.assertEqual(w[0].category, PendingDeprecationWarning)
+ # self.assertEqual(w[0].category, DeprecationWarning)
# Until end of the deprecation cycle, should still create the
# form as before:
diff --git a/tests/model_forms_regress/tests.py b/tests/model_forms_regress/tests.py
index 39ae857219..35e706ac4c 100644
--- a/tests/model_forms_regress/tests.py
+++ b/tests/model_forms_regress/tests.py
@@ -1,6 +1,7 @@
from __future__ import absolute_import, unicode_literals
from datetime import date
+import unittest
import warnings
from django import forms
@@ -9,7 +10,6 @@ from django.core.files.uploadedfile import SimpleUploadedFile
from django.forms.models import (modelform_factory, ModelChoiceField,
fields_for_model, construct_instance, ModelFormMetaclass)
from django.utils import six
-from django.utils import unittest
from django.test import TestCase
from .models import (Person, RealPerson, Triple, FilePathModel, Article,
@@ -566,10 +566,10 @@ class CustomMetaclassTestCase(TestCase):
class TestTicket19733(TestCase):
def test_modelform_factory_without_fields(self):
with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always", PendingDeprecationWarning)
+ warnings.simplefilter("always", DeprecationWarning)
# This should become an error once deprecation cycle is complete.
form = modelform_factory(Person)
- self.assertEqual(w[0].category, PendingDeprecationWarning)
+ self.assertEqual(w[0].category, DeprecationWarning)
def test_modelform_factory_with_all_fields(self):
form = modelform_factory(Person, fields="__all__")
diff --git a/tests/model_formsets/tests.py b/tests/model_formsets/tests.py
index 43509c471f..09a3ba1778 100644
--- a/tests/model_formsets/tests.py
+++ b/tests/model_formsets/tests.py
@@ -399,7 +399,7 @@ class ModelFormsetTest(TestCase):
super(BaseAuthorFormSet, self).__init__(*args, **kwargs)
self.queryset = Author.objects.filter(name__startswith='Charles')
- AuthorFormSet = modelformset_factory(Author, formset=BaseAuthorFormSet)
+ AuthorFormSet = modelformset_factory(Author, fields='__all__', formset=BaseAuthorFormSet)
formset = AuthorFormSet()
self.assertEqual(len(formset.get_queryset()), 1)
diff --git a/tests/model_inheritance_regress/tests.py b/tests/model_inheritance_regress/tests.py
index 28635a29a9..7ca16647fa 100644
--- a/tests/model_inheritance_regress/tests.py
+++ b/tests/model_inheritance_regress/tests.py
@@ -5,10 +5,10 @@ from __future__ import absolute_import, unicode_literals
import datetime
from operator import attrgetter
-from django import forms
+from unittest import expectedFailure
+from django import forms
from django.test import TestCase
-from django.utils.unittest import expectedFailure
from .models import (Place, Restaurant, ItalianRestaurant, ParkingLot,
ParkingLot2, ParkingLot3, Supplier, Wholesaler, Child, SelfRefParent,
diff --git a/tests/model_regress/tests.py b/tests/model_regress/tests.py
index 71ccb071d2..2924b220e6 100644
--- a/tests/model_regress/tests.py
+++ b/tests/model_regress/tests.py
@@ -3,12 +3,12 @@ from __future__ import absolute_import, unicode_literals
import datetime
from operator import attrgetter
import sys
+import unittest
from django.core.exceptions import ValidationError
from django.test import TestCase, skipUnlessDBFeature
from django.utils import six
from django.utils import tzinfo
-from django.utils import unittest
from django.db import connection, router
from django.db.models.sql import InsertQuery
diff --git a/tests/modeladmin/tests.py b/tests/modeladmin/tests.py
index 805b57c070..0d0fed394a 100644
--- a/tests/modeladmin/tests.py
+++ b/tests/modeladmin/tests.py
@@ -1,6 +1,7 @@
from __future__ import absolute_import, unicode_literals
from datetime import date
+import unittest
from django import forms
from django.conf import settings
@@ -15,7 +16,7 @@ from django.forms.models import BaseModelFormSet
from django.forms.widgets import Select
from django.test import TestCase
from django.test.utils import str_prefix
-from django.utils import unittest, six
+from django.utils import six
from .models import Band, Concert, ValidationTestModel, ValidationTestInlineModel
diff --git a/tests/multiple_database/tests.py b/tests/multiple_database/tests.py
index a0d937ce81..12a6379ca0 100644
--- a/tests/multiple_database/tests.py
+++ b/tests/multiple_database/tests.py
@@ -3,9 +3,7 @@ from __future__ import absolute_import, unicode_literals
import datetime
import pickle
from operator import attrgetter
-import warnings
-from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.core import management
@@ -1626,25 +1624,6 @@ class AuthTestCase(TestCase):
command_output = new_io.getvalue().strip()
self.assertTrue('"email": "alice@example.com"' in command_output)
-
-@override_settings(AUTH_PROFILE_MODULE='multiple_database.UserProfile')
-class UserProfileTestCase(TestCase):
-
- def test_user_profiles(self):
- alice = User.objects.create_user('alice', 'alice@example.com')
- bob = User.objects.db_manager('other').create_user('bob', 'bob@example.com')
-
- alice_profile = UserProfile(user=alice, flavor='chocolate')
- alice_profile.save()
-
- bob_profile = UserProfile(user=bob, flavor='crunchy frog')
- bob_profile.save()
-
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- self.assertEqual(alice.get_profile().flavor, 'chocolate')
- self.assertEqual(bob.get_profile().flavor, 'crunchy frog')
-
class AntiPetRouter(object):
# A router that only expresses an opinion on syncdb,
# passing pets to the 'other' database
diff --git a/tests/pagination/tests.py b/tests/pagination/tests.py
index 1dea4526e3..76799bec46 100644
--- a/tests/pagination/tests.py
+++ b/tests/pagination/tests.py
@@ -1,12 +1,12 @@
from __future__ import absolute_import, unicode_literals
from datetime import datetime
+import unittest
from django.core.paginator import (Paginator, EmptyPage, InvalidPage,
PageNotAnInteger)
from django.test import TestCase
from django.utils import six
-from django.utils import unittest
from .models import Article
from .custom import ValidAdjacentNumsPaginator
diff --git a/tests/proxy_models/tests.py b/tests/proxy_models/tests.py
index 77d2ba9a74..5cc5ef5478 100644
--- a/tests/proxy_models/tests.py
+++ b/tests/proxy_models/tests.py
@@ -358,7 +358,7 @@ class ProxyModelTests(TestCase):
)
def test_proxy_load_from_fixture(self):
- management.call_command('loaddata', 'mypeople.json', verbosity=0, commit=False)
+ management.call_command('loaddata', 'mypeople.json', verbosity=0)
p = MyPerson.objects.get(pk=100)
self.assertEqual(p.name, 'Elvis Presley')
diff --git a/tests/queries/tests.py b/tests/queries/tests.py
index 352e87a634..6520eb0176 100644
--- a/tests/queries/tests.py
+++ b/tests/queries/tests.py
@@ -4,6 +4,7 @@ import datetime
from operator import attrgetter
import pickle
import sys
+import unittest
from django.conf import settings
from django.core.exceptions import FieldError
@@ -13,7 +14,6 @@ from django.db.models.sql.where import WhereNode, EverythingNode, NothingNode
from django.db.models.sql.datastructures import EmptyResultSet
from django.test import TestCase, skipUnlessDBFeature
from django.test.utils import str_prefix
-from django.utils import unittest
from django.utils.datastructures import SortedDict
from .models import (
diff --git a/tests/requests/tests.py b/tests/requests/tests.py
index d9120db4e7..b00eec87a9 100644
--- a/tests/requests/tests.py
+++ b/tests/requests/tests.py
@@ -1,10 +1,11 @@
# -*- encoding: utf-8 -*-
from __future__ import unicode_literals
-import time
-import warnings
from datetime import datetime, timedelta
from io import BytesIO
+import time
+from unittest import skipIf
+import warnings
from django.db import connection, connections, DEFAULT_DB_ALIAS
from django.core import signals
@@ -15,7 +16,6 @@ from django.test import SimpleTestCase, TransactionTestCase
from django.test.client import FakePayload
from django.test.utils import override_settings, str_prefix
from django.utils import six
-from django.utils.unittest import skipIf
from django.utils.http import cookie_date, urlencode
from django.utils.timezone import utc
diff --git a/tests/resolve_url/tests.py b/tests/resolve_url/tests.py
index d0bf44abde..70f9e51781 100644
--- a/tests/resolve_url/tests.py
+++ b/tests/resolve_url/tests.py
@@ -1,8 +1,9 @@
from __future__ import unicode_literals
+from unittest import TestCase
+
from django.core.urlresolvers import NoReverseMatch
from django.contrib.auth.views import logout
-from django.utils.unittest import TestCase
from django.shortcuts import resolve_url
from .models import UnimportantThing
diff --git a/tests/runtests.py b/tests/runtests.py
index da4592ecc0..b604155190 100755
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -109,7 +109,7 @@ def setup(verbosity, test_labels):
# Load all the ALWAYS_INSTALLED_APPS.
with warnings.catch_warnings():
- warnings.filterwarnings('ignore', 'django.contrib.comments is deprecated and will be removed before Django 1.8.', PendingDeprecationWarning)
+ warnings.filterwarnings('ignore', 'django.contrib.comments is deprecated and will be removed before Django 1.8.', DeprecationWarning)
get_apps()
# Load all the test model apps.
diff --git a/tests/select_for_update/tests.py b/tests/select_for_update/tests.py
index f087ca123a..b8a8ad19bf 100644
--- a/tests/select_for_update/tests.py
+++ b/tests/select_for_update/tests.py
@@ -2,13 +2,13 @@ from __future__ import absolute_import
import sys
import time
+import unittest
from django.conf import settings
from django.db import transaction, connection
from django.db.utils import ConnectionHandler, DEFAULT_DB_ALIAS, DatabaseError
from django.test import (TransactionTestCase, skipIfDBFeature,
skipUnlessDBFeature)
-from django.utils import unittest
from .models import Person
diff --git a/tests/select_related/tests.py b/tests/select_related/tests.py
index baa141d123..e6723eac9b 100644
--- a/tests/select_related/tests.py
+++ b/tests/select_related/tests.py
@@ -1,7 +1,5 @@
from __future__ import absolute_import, unicode_literals
-import warnings
-
from django.test import TestCase
from .models import Domain, Kingdom, Phylum, Klass, Order, Family, Genus, Species
@@ -55,9 +53,7 @@ class SelectRelatedTests(TestCase):
extra queries
"""
with self.assertNumQueries(1):
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- person = Species.objects.select_related(depth=10).get(name="sapiens")
+ person = Species.objects.select_related('genus__family__order__klass__phylum__kingdom__domain').get(name="sapiens")
domain = person.genus.family.order.klass.phylum.kingdom.domain
self.assertEqual(domain.name, 'Eukaryota')
@@ -91,53 +87,27 @@ class SelectRelatedTests(TestCase):
'Hominidae',
])
- def test_depth(self, depth=1, expected=7):
- """
- The "depth" argument to select_related() will stop the descent at a
- particular level.
- """
- # Notice: one fewer queries than above because of depth=1
- with self.assertNumQueries(expected):
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- pea = Species.objects.select_related(depth=depth).get(name="sativum")
- self.assertEqual(
- pea.genus.family.order.klass.phylum.kingdom.domain.name,
- 'Eukaryota'
- )
-
- def test_larger_depth(self):
- """
- The "depth" argument to select_related() will stop the descent at a
- particular level. This tests a larger depth value.
- """
- self.test_depth(depth=5, expected=3)
-
def test_list_with_depth(self):
"""
- The "depth" argument to select_related() will stop the descent at a
- particular level. This can be used on lists as well.
+ Passing a relationship field lookup specifier to select_related() will
+ stop the descent at a particular level. This can be used on lists as
+ well.
"""
with self.assertNumQueries(5):
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- world = Species.objects.all().select_related(depth=2)
- orders = [o.genus.family.order.name for o in world]
+ world = Species.objects.all().select_related('genus__family')
+ orders = [o.genus.family.order.name for o in world]
self.assertEqual(sorted(orders),
['Agaricales', 'Diptera', 'Fabales', 'Primates'])
def test_select_related_with_extra(self):
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- s = Species.objects.all().select_related(depth=1)\
- .extra(select={'a': 'select_related_species.id + 10'})[0]
+ s = Species.objects.all().select_related()\
+ .extra(select={'a': 'select_related_species.id + 10'})[0]
self.assertEqual(s.id + 10, s.a)
def test_certain_fields(self):
"""
The optional fields passed to select_related() control which related
- models we pull in. This allows for smaller queries and can act as an
- alternative (or, in addition to) the depth parameter.
+ models we pull in. This allows for smaller queries.
In this case, we explicitly say to select the 'genus' and
'genus.family' models, leading to the same number of queries as before.
@@ -166,12 +136,10 @@ class SelectRelatedTests(TestCase):
self.assertEqual(s, 'Diptera')
def test_depth_fields_fails(self):
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- self.assertRaises(TypeError,
- Species.objects.select_related,
- 'genus__family__order', depth=4
- )
+ self.assertRaises(TypeError,
+ Species.objects.select_related,
+ 'genus__family__order', depth=4
+ )
def test_none_clears_list(self):
queryset = Species.objects.select_related('genus').select_related(None)
diff --git a/tests/select_related_onetoone/tests.py b/tests/select_related_onetoone/tests.py
index fce8fc4e73..d8ba4d0484 100644
--- a/tests/select_related_onetoone/tests.py
+++ b/tests/select_related_onetoone/tests.py
@@ -1,7 +1,8 @@
from __future__ import absolute_import
+import unittest
+
from django.test import TestCase
-from django.utils import unittest
from .models import (User, UserProfile, UserStat, UserStatResult, StatDetails,
AdvancedUserStat, Image, Product, Parent1, Parent2, Child1, Child2, Child3,
diff --git a/tests/serializers/tests.py b/tests/serializers/tests.py
index 038276ca21..bff7c53249 100644
--- a/tests/serializers/tests.py
+++ b/tests/serializers/tests.py
@@ -3,6 +3,7 @@ from __future__ import absolute_import, unicode_literals
# -*- coding: utf-8 -*-
import json
from datetime import datetime
+import unittest
from xml.dom import minidom
from django.conf import settings
@@ -11,7 +12,6 @@ from django.db import transaction, connection
from django.test import TestCase, TransactionTestCase, Approximate
from django.utils import six
from django.utils.six import StringIO
-from django.utils import unittest
from .models import (Category, Author, Article, AuthorProfile, Actor, Movie,
Score, Player, Team)
diff --git a/tests/serializers_regress/tests.py b/tests/serializers_regress/tests.py
index 04b4d4c839..1751816cee 100644
--- a/tests/serializers_regress/tests.py
+++ b/tests/serializers_regress/tests.py
@@ -10,7 +10,7 @@ from __future__ import absolute_import, unicode_literals
import datetime
import decimal
-from django.core.serializers.xml_serializer import DTDForbidden
+from unittest import expectedFailure, skipUnless
try:
import yaml
@@ -20,13 +20,13 @@ except ImportError:
from django.core import serializers
from django.core.serializers import SerializerDoesNotExist
from django.core.serializers.base import DeserializationError
+from django.core.serializers.xml_serializer import DTDForbidden
from django.db import connection, models
from django.http import HttpResponse
from django.test import TestCase
from django.utils import six
from django.utils.encoding import force_text
from django.utils.functional import curry
-from django.utils.unittest import expectedFailure, skipUnless
from .models import (BinaryData, BooleanData, CharData, DateData, DateTimeData, EmailData,
FileData, FilePathData, DecimalData, FloatData, IntegerData, IPAddressData,
diff --git a/tests/settings_tests/tests.py b/tests/settings_tests/tests.py
index 625c4f31df..bfd8d607a9 100644
--- a/tests/settings_tests/tests.py
+++ b/tests/settings_tests/tests.py
@@ -1,4 +1,5 @@
import os
+import unittest
import warnings
from django.conf import settings, global_settings
@@ -6,7 +7,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.http import HttpRequest
from django.test import SimpleTestCase, TransactionTestCase, TestCase, signals
from django.test.utils import override_settings
-from django.utils import unittest, six
+from django.utils import six
@override_settings(TEST='override', TEST_OUTER='outer')
diff --git a/tests/str/tests.py b/tests/str/tests.py
index bd85c48d05..d82908a0ee 100644
--- a/tests/str/tests.py
+++ b/tests/str/tests.py
@@ -2,10 +2,10 @@
from __future__ import absolute_import, unicode_literals
import datetime
+from unittest import skipIf
from django.test import TestCase
from django.utils import six
-from django.utils.unittest import skipIf
from .models import Article, BrokenArticle, InternationalArticle
diff --git a/tests/template_tests/loaders.py b/tests/template_tests/loaders.py
index b77965203f..497b422e7f 100644
--- a/tests/template_tests/loaders.py
+++ b/tests/template_tests/loaders.py
@@ -9,15 +9,16 @@ from django.conf import settings
if __name__ == '__main__':
settings.configure()
-import sys
-import pkg_resources
import imp
import os.path
+import pkg_resources
+import sys
+import unittest
from django.template import TemplateDoesNotExist, Context
from django.template.loaders.eggs import Loader as EggLoader
from django.template import loader
-from django.utils import unittest, six
+from django.utils import six
from django.utils._os import upath
from django.utils.six import StringIO
diff --git a/tests/template_tests/test_callables.py b/tests/template_tests/test_callables.py
index 882a8c6e06..718b7740d9 100644
--- a/tests/template_tests/test_callables.py
+++ b/tests/template_tests/test_callables.py
@@ -1,7 +1,8 @@
from __future__ import unicode_literals
+from unittest import TestCase
+
from django import template
-from django.utils.unittest import TestCase
class CallableVariablesTests(TestCase):
diff --git a/tests/template_tests/test_context.py b/tests/template_tests/test_context.py
index 05c1dd57b9..224b94d060 100644
--- a/tests/template_tests/test_context.py
+++ b/tests/template_tests/test_context.py
@@ -1,6 +1,8 @@
# coding: utf-8
+
+from unittest import TestCase
+
from django.template import Context
-from django.utils.unittest import TestCase
class ContextTests(TestCase):
diff --git a/tests/template_tests/test_custom.py b/tests/template_tests/test_custom.py
index 4aea08237d..e941bc223e 100644
--- a/tests/template_tests/test_custom.py
+++ b/tests/template_tests/test_custom.py
@@ -1,8 +1,9 @@
from __future__ import absolute_import, unicode_literals
+from unittest import TestCase
+
from django import template
from django.utils import six
-from django.utils.unittest import TestCase
from .templatetags import custom
diff --git a/tests/template_tests/test_nodelist.py b/tests/template_tests/test_nodelist.py
index 97aa5af6a7..755c0c3bea 100644
--- a/tests/template_tests/test_nodelist.py
+++ b/tests/template_tests/test_nodelist.py
@@ -1,6 +1,7 @@
+from unittest import TestCase
+
from django.template import VariableNode, Context
from django.template.loader import get_template_from_string
-from django.utils.unittest import TestCase
from django.test.utils import override_settings
class NodelistTest(TestCase):
diff --git a/tests/template_tests/test_parser.py b/tests/template_tests/test_parser.py
index 9422da80d7..e626bfd34f 100644
--- a/tests/template_tests/test_parser.py
+++ b/tests/template_tests/test_parser.py
@@ -3,10 +3,11 @@ Testing some internals of the template processing. These are *not* examples to b
"""
from __future__ import unicode_literals
+from unittest import TestCase
+
from django.template import (TokenParser, FilterExpression, Parser, Variable,
Template, TemplateSyntaxError)
from django.test.utils import override_settings
-from django.utils.unittest import TestCase
from django.utils import six
diff --git a/tests/template_tests/test_smartif.py b/tests/template_tests/test_smartif.py
index 3a705ca663..4345e04126 100644
--- a/tests/template_tests/test_smartif.py
+++ b/tests/template_tests/test_smartif.py
@@ -1,5 +1,6 @@
+import unittest
+
from django.template.smartif import IfParser
-from django.utils import unittest
class SmartIfTests(unittest.TestCase):
diff --git a/tests/template_tests/test_unicode.py b/tests/template_tests/test_unicode.py
index 7cb2a28d15..773dd543b7 100644
--- a/tests/template_tests/test_unicode.py
+++ b/tests/template_tests/test_unicode.py
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
+from unittest import TestCase
+
from django.template import Template, TemplateEncodingError, Context
from django.utils.safestring import SafeData
from django.utils import six
-from django.utils.unittest import TestCase
class UnicodeTests(TestCase):
diff --git a/tests/template_tests/tests.py b/tests/template_tests/tests.py
index 76712a09a6..6b8a106623 100644
--- a/tests/template_tests/tests.py
+++ b/tests/template_tests/tests.py
@@ -13,6 +13,7 @@ import time
import os
import sys
import traceback
+import unittest
try:
from urllib.parse import urljoin
except ImportError: # Python 2
@@ -27,7 +28,6 @@ from django.template.loaders import app_directories, filesystem, cached
from django.test import RequestFactory, TestCase
from django.test.utils import (setup_test_template_loader,
restore_template_loaders, override_settings)
-from django.utils import unittest
from django.utils.encoding import python_2_unicode_compatible
from django.utils.formats import date_format
from django.utils._os import upath
@@ -534,7 +534,7 @@ class TemplateTests(TransRealMixin, TestCase):
try:
with warnings.catch_warnings():
# Ignore pending deprecations of the old syntax of the 'cycle' and 'firstof' tags.
- warnings.filterwarnings("ignore", category=PendingDeprecationWarning, module='django.template.base')
+ warnings.filterwarnings("ignore", category=DeprecationWarning, module='django.template.base')
test_template = loader.get_template(name)
except ShouldNotExecuteException:
failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s', TEMPLATE_DEBUG=%s): %s -- FAILED. Template loading invoked method that shouldn't have been invoked." % (is_cached, invalid_str, template_debug, name))
diff --git a/tests/test_discovery_sample/tests_sample.py b/tests/test_discovery_sample/tests_sample.py
index c541bc4cd6..fb1e14c715 100644
--- a/tests/test_discovery_sample/tests_sample.py
+++ b/tests/test_discovery_sample/tests_sample.py
@@ -1,16 +1,9 @@
-from unittest import TestCase as UnitTestCase
+from unittest import TestCase
from django.test import TestCase as DjangoTestCase
-from django.utils.unittest import TestCase as UT2TestCase
-class TestVanillaUnittest(UnitTestCase):
-
- def test_sample(self):
- self.assertEqual(1, 1)
-
-
-class TestUnittest2(UT2TestCase):
+class TestVanillaUnittest(TestCase):
def test_sample(self):
self.assertEqual(1, 1)
diff --git a/tests/test_runner/test_discover_runner.py b/tests/test_runner/test_discover_runner.py
index 1a0fb88367..4494b2bd3b 100644
--- a/tests/test_runner/test_discover_runner.py
+++ b/tests/test_runner/test_discover_runner.py
@@ -1,15 +1,10 @@
from contextlib import contextmanager
import os
import sys
+from unittest import expectedFailure
from django.test import TestCase
from django.test.runner import DiscoverRunner
-from django.utils.unittest import expectedFailure
-
-try:
- import unittest2
-except ImportError:
- unittest2 = None
def expectedFailureIf(condition):
@@ -26,7 +21,7 @@ class DiscoverRunnerTest(TestCase):
["test_discovery_sample.tests_sample"],
).countTestCases()
- self.assertEqual(count, 3)
+ self.assertEqual(count, 2)
def test_dotted_test_class_vanilla_unittest(self):
count = DiscoverRunner().build_suite(
@@ -35,13 +30,6 @@ class DiscoverRunnerTest(TestCase):
self.assertEqual(count, 1)
- def test_dotted_test_class_unittest2(self):
- count = DiscoverRunner().build_suite(
- ["test_discovery_sample.tests_sample.TestUnittest2"],
- ).countTestCases()
-
- self.assertEqual(count, 1)
-
def test_dotted_test_class_django_testcase(self):
count = DiscoverRunner().build_suite(
["test_discovery_sample.tests_sample.TestDjangoTestCase"],
@@ -49,23 +37,6 @@ class DiscoverRunnerTest(TestCase):
self.assertEqual(count, 1)
- # this test fails if unittest2 is installed from PyPI on Python 2.6
- # refs https://code.djangoproject.com/ticket/20437
- @expectedFailureIf(sys.version_info < (2, 7) and unittest2)
- def test_dotted_test_method_vanilla_unittest(self):
- count = DiscoverRunner().build_suite(
- ["test_discovery_sample.tests_sample.TestVanillaUnittest.test_sample"],
- ).countTestCases()
-
- self.assertEqual(count, 1)
-
- def test_dotted_test_method_unittest2(self):
- count = DiscoverRunner().build_suite(
- ["test_discovery_sample.tests_sample.TestUnittest2.test_sample"],
- ).countTestCases()
-
- self.assertEqual(count, 1)
-
def test_dotted_test_method_django_testcase(self):
count = DiscoverRunner().build_suite(
["test_discovery_sample.tests_sample.TestDjangoTestCase.test_sample"],
@@ -96,4 +67,4 @@ class DiscoverRunnerTest(TestCase):
["test_discovery_sample/"],
).countTestCases()
- self.assertEqual(count, 4)
+ self.assertEqual(count, 3)
diff --git a/tests/test_runner/tests.py b/tests/test_runner/tests.py
index 0dc7a0155a..4e9e44bc12 100644
--- a/tests/test_runner/tests.py
+++ b/tests/test_runner/tests.py
@@ -3,16 +3,16 @@ Tests for django test runner
"""
from __future__ import absolute_import, unicode_literals
-import sys
from optparse import make_option
+import sys
+import unittest
from django.core.exceptions import ImproperlyConfigured
from django.core.management import call_command
from django import db
from django.test import runner, TestCase, TransactionTestCase, skipUnlessDBFeature
from django.test.testcases import connections_support_transactions
-from django.test.utils import IgnorePendingDeprecationWarningsMixin
-from django.utils import unittest
+from django.test.utils import IgnoreAllDeprecationWarningsMixin
from django.utils.importlib import import_module
from admin_scripts.tests import AdminScriptTestCase
@@ -225,7 +225,8 @@ class Ticket17477RegressionTests(AdminScriptTestCase):
self.assertNoOutput(err)
-class ModulesTestsPackages(IgnorePendingDeprecationWarningsMixin, unittest.TestCase):
+class ModulesTestsPackages(IgnoreAllDeprecationWarningsMixin, unittest.TestCase):
+
def test_get_tests(self):
"Check that the get_tests helper function can find tests in a directory"
from django.test.simple import get_tests
diff --git a/tests/test_suite_override/tests.py b/tests/test_suite_override/tests.py
index 35ca2b060b..e69dab12bf 100644
--- a/tests/test_suite_override/tests.py
+++ b/tests/test_suite_override/tests.py
@@ -1,6 +1,7 @@
+import unittest
+
from django.db.models import get_app
-from django.test.utils import IgnorePendingDeprecationWarningsMixin
-from django.utils import unittest
+from django.test.utils import IgnoreAllDeprecationWarningsMixin
def suite():
@@ -9,7 +10,8 @@ def suite():
return testSuite
-class SuiteOverrideTest(IgnorePendingDeprecationWarningsMixin, unittest.TestCase):
+class SuiteOverrideTest(IgnoreAllDeprecationWarningsMixin, unittest.TestCase):
+
def test_suite_override(self):
"""
Validate that you can define a custom suite when running tests with
diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py
index 5f7fb05eb4..2c2bc24d72 100644
--- a/tests/test_utils/tests.py
+++ b/tests/test_utils/tests.py
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
-import warnings
+
+import unittest
+from unittest import skip
from django.db import connection
from django.forms import EmailField, IntegerField
@@ -8,10 +10,8 @@ from django.http import HttpResponse
from django.template.loader import render_to_string
from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
from django.test.html import HTMLParseError, parse_html
-from django.test.utils import CaptureQueriesContext, IgnorePendingDeprecationWarningsMixin
+from django.test.utils import CaptureQueriesContext, IgnoreAllDeprecationWarningsMixin
from django.utils import six
-from django.utils import unittest
-from django.utils.unittest import skip
from .models import Person
@@ -270,37 +270,6 @@ class AssertTemplateUsedContextManagerTests(TestCase):
render_to_string('template_used/alternative.html')
-class SaveRestoreWarningState(TestCase):
- def test_save_restore_warnings_state(self):
- """
- Ensure save_warnings_state/restore_warnings_state work correctly.
- """
- # In reality this test could be satisfied by many broken implementations
- # of save_warnings_state/restore_warnings_state (e.g. just
- # warnings.resetwarnings()) , but it is difficult to test more.
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
-
- self.save_warnings_state()
-
- class MyWarning(Warning):
- pass
-
- # Add a filter that causes an exception to be thrown, so we can catch it
- warnings.simplefilter("error", MyWarning)
- self.assertRaises(Warning, lambda: warnings.warn("warn", MyWarning))
-
- # Now restore.
- self.restore_warnings_state()
- # After restoring, we shouldn't get an exception. But we don't want a
- # warning printed either, so we have to silence the warning.
- warnings.simplefilter("ignore", MyWarning)
- warnings.warn("warn", MyWarning)
-
- # Remove the filter we just added.
- self.restore_warnings_state()
-
-
class HTMLEqualTests(TestCase):
def test_html_parser(self):
element = parse_html('<div><p>Hello</p></div>')
@@ -623,7 +592,7 @@ class AssertFieldOutputTests(SimpleTestCase):
self.assertFieldOutput(MyCustomField, {}, {}, empty_value=None)
-class DoctestNormalizerTest(IgnorePendingDeprecationWarningsMixin, SimpleTestCase):
+class DoctestNormalizerTest(IgnoreAllDeprecationWarningsMixin, SimpleTestCase):
def test_normalizer(self):
from django.test.simple import make_doctest
diff --git a/tests/timezones/tests.py b/tests/timezones/tests.py
index dce5c3041d..49169f90f2 100644
--- a/tests/timezones/tests.py
+++ b/tests/timezones/tests.py
@@ -5,6 +5,7 @@ import os
import re
import sys
import time
+from unittest import skipIf, skipUnless
import warnings
from xml.dom.minidom import parseString
@@ -25,7 +26,6 @@ from django.test.utils import override_settings
from django.utils import six
from django.utils import timezone
from django.utils.tzinfo import FixedOffset
-from django.utils.unittest import skipIf, skipUnless
from .forms import EventForm, EventSplitForm, EventModelForm
from .models import Event, MaybeEvent, Session, SessionEvent, Timestamp, AllDayEvent
diff --git a/tests/transactions/tests.py b/tests/transactions/tests.py
index 756fa40abd..afb573f366 100644
--- a/tests/transactions/tests.py
+++ b/tests/transactions/tests.py
@@ -1,12 +1,12 @@
from __future__ import absolute_import
import sys
+from unittest import skipIf, skipUnless
from django.db import connection, transaction, DatabaseError, IntegrityError
from django.test import TransactionTestCase, skipUnlessDBFeature
-from django.test.utils import IgnorePendingDeprecationWarningsMixin
+from django.test.utils import IgnoreDeprecationWarningsMixin
from django.utils import six
-from django.utils.unittest import skipIf, skipUnless
from .models import Reporter
@@ -350,7 +350,7 @@ class AtomicMiscTests(TransactionTestCase):
transaction.atomic(Callable())
-class TransactionTests(IgnorePendingDeprecationWarningsMixin, TransactionTestCase):
+class TransactionTests(IgnoreDeprecationWarningsMixin, TransactionTestCase):
available_apps = ['transactions']
@@ -508,7 +508,7 @@ class TransactionTests(IgnorePendingDeprecationWarningsMixin, TransactionTestCas
)
-class TransactionRollbackTests(IgnorePendingDeprecationWarningsMixin, TransactionTestCase):
+class TransactionRollbackTests(IgnoreDeprecationWarningsMixin, TransactionTestCase):
available_apps = ['transactions']
@@ -528,7 +528,7 @@ class TransactionRollbackTests(IgnorePendingDeprecationWarningsMixin, Transactio
self.assertRaises(IntegrityError, execute_bad_sql)
transaction.rollback()
-class TransactionContextManagerTests(IgnorePendingDeprecationWarningsMixin, TransactionTestCase):
+class TransactionContextManagerTests(IgnoreDeprecationWarningsMixin, TransactionTestCase):
available_apps = ['transactions']
diff --git a/tests/transactions_regress/tests.py b/tests/transactions_regress/tests.py
index 8078f1d128..bd9e78b033 100644
--- a/tests/transactions_regress/tests.py
+++ b/tests/transactions_regress/tests.py
@@ -1,11 +1,12 @@
from __future__ import absolute_import
+from unittest import skipIf, skipUnless
+
from django.db import (connection, connections, transaction, DEFAULT_DB_ALIAS, DatabaseError,
IntegrityError)
from django.db.transaction import commit_on_success, commit_manually, TransactionManagementError
from django.test import TransactionTestCase, skipUnlessDBFeature
-from django.test.utils import override_settings, IgnorePendingDeprecationWarningsMixin
-from django.utils.unittest import skipIf, skipUnless
+from django.test.utils import override_settings, IgnoreDeprecationWarningsMixin
from .models import Mod, M2mA, M2mB, SubMod
@@ -30,7 +31,7 @@ class ModelInheritanceTests(TransactionTestCase):
self.assertEqual(SubMod.objects.count(), 1)
self.assertEqual(Mod.objects.count(), 1)
-class TestTransactionClosing(IgnorePendingDeprecationWarningsMixin, TransactionTestCase):
+class TestTransactionClosing(IgnoreDeprecationWarningsMixin, TransactionTestCase):
"""
Tests to make sure that transactions are properly closed
when they should be, and aren't left pending after operations
@@ -194,7 +195,7 @@ class TestTransactionClosing(IgnorePendingDeprecationWarningsMixin, TransactionT
(connection.settings_dict['NAME'] == ':memory:' or
not connection.settings_dict['NAME']),
'Test uses multiple connections, but in-memory sqlite does not support this')
-class TestNewConnection(IgnorePendingDeprecationWarningsMixin, TransactionTestCase):
+class TestNewConnection(IgnoreDeprecationWarningsMixin, TransactionTestCase):
"""
Check that new connections don't have special behaviour.
"""
@@ -242,7 +243,7 @@ class TestNewConnection(IgnorePendingDeprecationWarningsMixin, TransactionTestCa
@skipUnless(connection.vendor == 'postgresql',
"This test only valid for PostgreSQL")
-class TestPostgresAutocommitAndIsolation(IgnorePendingDeprecationWarningsMixin, TransactionTestCase):
+class TestPostgresAutocommitAndIsolation(IgnoreDeprecationWarningsMixin, TransactionTestCase):
"""
Tests to make sure psycopg2's autocommit mode and isolation level
is restored after entering and leaving transaction management.
@@ -326,7 +327,7 @@ class TestPostgresAutocommitAndIsolation(IgnorePendingDeprecationWarningsMixin,
self.assertTrue(connection.autocommit)
-class TestManyToManyAddTransaction(IgnorePendingDeprecationWarningsMixin, TransactionTestCase):
+class TestManyToManyAddTransaction(IgnoreDeprecationWarningsMixin, TransactionTestCase):
available_apps = ['transactions_regress']
@@ -344,7 +345,7 @@ class TestManyToManyAddTransaction(IgnorePendingDeprecationWarningsMixin, Transa
self.assertEqual(a.others.count(), 1)
-class SavepointTest(IgnorePendingDeprecationWarningsMixin, TransactionTestCase):
+class SavepointTest(IgnoreDeprecationWarningsMixin, TransactionTestCase):
available_apps = ['transactions_regress']
diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py
index 3962f69288..222ebe053b 100644
--- a/tests/urlpatterns_reverse/tests.py
+++ b/tests/urlpatterns_reverse/tests.py
@@ -3,6 +3,8 @@ Unit tests for reverse URL lookups.
"""
from __future__ import absolute_import, unicode_literals
+import unittest
+
from django.conf import settings
from django.contrib.auth.models import User
from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
@@ -12,7 +14,7 @@ from django.core.urlresolvers import (reverse, resolve, get_callable,
from django.http import HttpRequest, HttpResponseRedirect, HttpResponsePermanentRedirect
from django.shortcuts import redirect
from django.test import TestCase
-from django.utils import unittest, six
+from django.utils import six
from . import urlconf_outer, middleware, views
diff --git a/tests/utils_tests/test_archive.py b/tests/utils_tests/test_archive.py
index 8861b4a577..f00f25e855 100644
--- a/tests/utils_tests/test_archive.py
+++ b/tests/utils_tests/test_archive.py
@@ -1,7 +1,7 @@
import os
import shutil
import tempfile
-from django.utils import unittest
+import unittest
from django.utils.archive import Archive, extract
from django.utils._os import upath
diff --git a/tests/utils_tests/test_baseconv.py b/tests/utils_tests/test_baseconv.py
index d69a3a6412..d49dde1092 100644
--- a/tests/utils_tests/test_baseconv.py
+++ b/tests/utils_tests/test_baseconv.py
@@ -1,4 +1,5 @@
-from django.utils.unittest import TestCase
+from unittest import TestCase
+
from django.utils.baseconv import base2, base16, base36, base56, base62, base64, BaseConverter
from django.utils.six.moves import xrange
diff --git a/tests/utils_tests/test_crypto.py b/tests/utils_tests/test_crypto.py
index 5cf2934ab0..4c1d10bb5f 100644
--- a/tests/utils_tests/test_crypto.py
+++ b/tests/utils_tests/test_crypto.py
@@ -1,11 +1,11 @@
from __future__ import unicode_literals
import binascii
+import hashlib
import math
import timeit
-import hashlib
+import unittest
-from django.utils import unittest
from django.utils.crypto import constant_time_compare, pbkdf2
diff --git a/tests/utils_tests/test_datastructures.py b/tests/utils_tests/test_datastructures.py
index 5829e7c2d7..5563a0fc4f 100644
--- a/tests/utils_tests/test_datastructures.py
+++ b/tests/utils_tests/test_datastructures.py
@@ -4,7 +4,6 @@ Tests for stuff in django.utils.datastructures.
import copy
import pickle
-import warnings
from django.test import SimpleTestCase
from django.utils.datastructures import (DictWrapper, ImmutableList,
@@ -134,20 +133,6 @@ class SortedDictTests(SimpleTestCase):
self.assertEqual(list(reversed(self.d1)), [9, 1, 7])
self.assertEqual(list(reversed(self.d2)), [7, 0, 9, 1])
- def test_insert(self):
- d = SortedDict()
- with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always")
- d.insert(0, "hello", "world")
- assert w[0].category is DeprecationWarning
-
- def test_value_for_index(self):
- d = SortedDict({"a": 3})
- with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always")
- self.assertEqual(d.value_for_index(0), 3)
- assert w[0].category is DeprecationWarning
-
class MergeDictTests(SimpleTestCase):
diff --git a/tests/utils_tests/test_dateformat.py b/tests/utils_tests/test_dateformat.py
index 78cedaf764..15262121a0 100644
--- a/tests/utils_tests/test_dateformat.py
+++ b/tests/utils_tests/test_dateformat.py
@@ -3,9 +3,11 @@ from __future__ import unicode_literals
from datetime import datetime, date
import os
import time
+import unittest
from django.utils.dateformat import format
-from django.utils import dateformat, translation, unittest
+from django.utils import dateformat
+from django.utils import translation
from django.utils.timezone import utc
from django.utils.tzinfo import FixedOffset, LocalTimezone
diff --git a/tests/utils_tests/test_dateparse.py b/tests/utils_tests/test_dateparse.py
index 1a6ca646b8..836c26c573 100644
--- a/tests/utils_tests/test_dateparse.py
+++ b/tests/utils_tests/test_dateparse.py
@@ -1,9 +1,9 @@
from __future__ import unicode_literals
from datetime import date, time, datetime
+import unittest
from django.utils.dateparse import parse_date, parse_time, parse_datetime
-from django.utils import unittest
from django.utils.tzinfo import FixedOffset
diff --git a/tests/utils_tests/test_encoding.py b/tests/utils_tests/test_encoding.py
index 7aaba25a7a..72c35adec6 100644
--- a/tests/utils_tests/test_encoding.py
+++ b/tests/utils_tests/test_encoding.py
@@ -1,7 +1,8 @@
# -*- encoding: utf-8 -*-
from __future__ import unicode_literals
-from django.utils import unittest
+import unittest
+
from django.utils.encoding import force_bytes, filepath_to_uri
diff --git a/tests/utils_tests/test_feedgenerator.py b/tests/utils_tests/test_feedgenerator.py
index bcd53bb2a0..a801305f17 100644
--- a/tests/utils_tests/test_feedgenerator.py
+++ b/tests/utils_tests/test_feedgenerator.py
@@ -1,8 +1,11 @@
from __future__ import unicode_literals
import datetime
+import unittest
+
+from django.utils import feedgenerator
+from django.utils import tzinfo
-from django.utils import feedgenerator, tzinfo, unittest
class FeedgeneratorTest(unittest.TestCase):
"""
diff --git a/tests/utils_tests/test_functional.py b/tests/utils_tests/test_functional.py
index fc2256a1f2..66e051033e 100644
--- a/tests/utils_tests/test_functional.py
+++ b/tests/utils_tests/test_functional.py
@@ -1,4 +1,5 @@
-from django.utils import unittest
+import unittest
+
from django.utils.functional import lazy, lazy_property, cached_property
diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py
index b973f1c64f..1f2e19d8d5 100644
--- a/tests/utils_tests/test_html.py
+++ b/tests/utils_tests/test_html.py
@@ -2,11 +2,11 @@ from __future__ import unicode_literals
from datetime import datetime
import os
+from unittest import TestCase
from django.utils import html
from django.utils._os import upath
from django.utils.encoding import force_text
-from django.utils.unittest import TestCase
class TestUtilsHtml(TestCase):
diff --git a/tests/utils_tests/test_http.py b/tests/utils_tests/test_http.py
index 6d3bc025af..581eb1dcd7 100644
--- a/tests/utils_tests/test_http.py
+++ b/tests/utils_tests/test_http.py
@@ -1,12 +1,12 @@
from datetime import datetime
import sys
+import unittest
from django.http import HttpResponse, utils
from django.test import RequestFactory
from django.utils.datastructures import MultiValueDict
from django.utils import http
from django.utils import six
-from django.utils import unittest
class TestUtilsHttp(unittest.TestCase):
diff --git a/tests/utils_tests/test_ipv6.py b/tests/utils_tests/test_ipv6.py
index 1713de82b8..662e8b4135 100644
--- a/tests/utils_tests/test_ipv6.py
+++ b/tests/utils_tests/test_ipv6.py
@@ -1,6 +1,7 @@
from __future__ import unicode_literals
-from django.utils import unittest
+import unittest
+
from django.utils.ipv6 import is_valid_ipv6_address, clean_ipv6_address
class TestUtilsIPv6(unittest.TestCase):
diff --git a/tests/utils_tests/test_module_loading.py b/tests/utils_tests/test_module_loading.py
index 0a905ef2f1..5a43a927bf 100644
--- a/tests/utils_tests/test_module_loading.py
+++ b/tests/utils_tests/test_module_loading.py
@@ -1,10 +1,10 @@
+import imp
import os
import sys
-import imp
+import unittest
from zipimport import zipimporter
from django.core.exceptions import ImproperlyConfigured
-from django.utils import unittest
from django.utils.importlib import import_module
from django.utils.module_loading import import_by_path, module_has_submodule
from django.utils._os import upath
diff --git a/tests/utils_tests/test_os_utils.py b/tests/utils_tests/test_os_utils.py
index a205d67431..da54e93ac0 100644
--- a/tests/utils_tests/test_os_utils.py
+++ b/tests/utils_tests/test_os_utils.py
@@ -1,6 +1,6 @@
import os
+import unittest
-from django.utils import unittest
from django.utils._os import safe_join
diff --git a/tests/utils_tests/test_regex_helper.py b/tests/utils_tests/test_regex_helper.py
index 41f4a4f85d..055da89ee0 100644
--- a/tests/utils_tests/test_regex_helper.py
+++ b/tests/utils_tests/test_regex_helper.py
@@ -1,7 +1,8 @@
from __future__ import unicode_literals
+import unittest
+
from django.utils import regex_helper
-from django.utils import unittest
class NormalizeTests(unittest.TestCase):
diff --git a/tests/utils_tests/test_simplelazyobject.py b/tests/utils_tests/test_simplelazyobject.py
index 4c01bd3adf..7b681d9290 100644
--- a/tests/utils_tests/test_simplelazyobject.py
+++ b/tests/utils_tests/test_simplelazyobject.py
@@ -3,9 +3,9 @@ from __future__ import unicode_literals
import copy
import pickle
import sys
+from unittest import TestCase
from django.utils import six
-from django.utils.unittest import TestCase
from django.utils.functional import SimpleLazyObject, empty
diff --git a/tests/utils_tests/test_termcolors.py b/tests/utils_tests/test_termcolors.py
index 8cc28009cd..3a74244c09 100644
--- a/tests/utils_tests/test_termcolors.py
+++ b/tests/utils_tests/test_termcolors.py
@@ -1,4 +1,5 @@
-from django.utils import unittest
+import unittest
+
from django.utils.termcolors import (parse_color_setting, PALETTES,
DEFAULT_PALETTE, LIGHT_PALETTE, DARK_PALETTE, NOCOLOR_PALETTE, colorize)
diff --git a/tests/utils_tests/test_timezone.py b/tests/utils_tests/test_timezone.py
index 650198e8ff..2a13c10d7c 100644
--- a/tests/utils_tests/test_timezone.py
+++ b/tests/utils_tests/test_timezone.py
@@ -1,10 +1,11 @@
import copy
import datetime
import pickle
+import unittest
+
from django.test.utils import override_settings
from django.utils import timezone
from django.utils.tzinfo import FixedOffset
-from django.utils import unittest
EAT = FixedOffset(180) # Africa/Nairobi
diff --git a/tests/utils_tests/test_tzinfo.py b/tests/utils_tests/test_tzinfo.py
index cec92652cd..1867743fef 100644
--- a/tests/utils_tests/test_tzinfo.py
+++ b/tests/utils_tests/test_tzinfo.py
@@ -3,8 +3,9 @@ import datetime
import os
import pickle
import time
+import unittest
+
from django.utils.tzinfo import FixedOffset, LocalTimezone
-from django.utils import unittest
class TzinfoTests(unittest.TestCase):
diff --git a/tests/validation/test_error_messages.py b/tests/validation/test_error_messages.py
index 63c033a750..aa01db6007 100644
--- a/tests/validation/test_error_messages.py
+++ b/tests/validation/test_error_messages.py
@@ -1,10 +1,11 @@
# -*- encoding: utf-8 -*-
from __future__ import unicode_literals
+from unittest import TestCase
+
from django.core.exceptions import ValidationError
from django.db import models
from django.utils import six
-from django.utils.unittest import TestCase
class ValidationMessagesTest(TestCase):
diff --git a/tests/validation/test_unique.py b/tests/validation/test_unique.py
index 038da16494..a481fcb1c4 100644
--- a/tests/validation/test_unique.py
+++ b/tests/validation/test_unique.py
@@ -1,10 +1,10 @@
from __future__ import absolute_import, unicode_literals
import datetime
+import unittest
from django.core.exceptions import ValidationError
from django.test import TestCase
-from django.utils import unittest
from .models import (CustomPKModel, UniqueTogetherModel, UniqueFieldsModel,
UniqueForDateModel, ModelToValidate, Post, FlexibleDatePost,
diff --git a/tests/validators/tests.py b/tests/validators/tests.py
index a1555d8e91..ec3e2dc8c1 100644
--- a/tests/validators/tests.py
+++ b/tests/validators/tests.py
@@ -1,14 +1,14 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
+from datetime import datetime, timedelta
import re
import types
-from datetime import datetime, timedelta
+from unittest import TestCase
from django.core.exceptions import ValidationError
from django.core.validators import *
from django.test.utils import str_prefix
-from django.utils.unittest import TestCase
NOW = datetime.now()
diff --git a/tests/version/tests.py b/tests/version/tests.py
index 64621a5cb6..a5d49fc450 100644
--- a/tests/version/tests.py
+++ b/tests/version/tests.py
@@ -1,8 +1,8 @@
import re
+from unittest import TestCase
from django import get_version
from django.utils import six
-from django.utils.unittest import TestCase
class VersionTests(TestCase):
diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py
index f686eee0e0..bc77fc351a 100644
--- a/tests/view_tests/tests/test_debug.py
+++ b/tests/view_tests/tests/test_debug.py
@@ -8,6 +8,7 @@ import os
import shutil
import sys
from tempfile import NamedTemporaryFile, mkdtemp, mkstemp
+from unittest import skipIf
from django.core import mail
from django.core.files.uploadedfile import SimpleUploadedFile
@@ -22,7 +23,6 @@ from .. import BrokenException, except_args
from ..views import (sensitive_view, non_sensitive_view, paranoid_view,
custom_exception_reporter_filter_view, sensitive_method_view,
sensitive_args_function_caller, sensitive_kwargs_function_caller)
-from django.utils.unittest import skipIf
@override_settings(DEBUG=True, TEMPLATE_DEBUG=True)
diff --git a/tests/view_tests/tests/test_i18n.py b/tests/view_tests/tests/test_i18n.py
index b35b192fd0..c1852ee71f 100644
--- a/tests/view_tests/tests/test_i18n.py
+++ b/tests/view_tests/tests/test_i18n.py
@@ -4,12 +4,13 @@ from __future__ import absolute_import
import gettext
import os
from os import path
+import unittest
from django.conf import settings
from django.core.urlresolvers import reverse
from django.test import LiveServerTestCase, TestCase
from django.test.utils import override_settings
-from django.utils import six, unittest
+from django.utils import six
from django.utils._os import upath
from django.utils.translation import override
from django.utils.text import javascript_quote
diff --git a/tests/wsgi/tests.py b/tests/wsgi/tests.py
index a66258d4eb..afd59a6e1f 100644
--- a/tests/wsgi/tests.py
+++ b/tests/wsgi/tests.py
@@ -1,5 +1,7 @@
from __future__ import unicode_literals
+import unittest
+
from django.core.exceptions import ImproperlyConfigured
from django.core.servers.basehttp import get_internal_wsgi_application
from django.core.signals import request_started
@@ -8,7 +10,7 @@ from django.db import close_old_connections
from django.test import TestCase
from django.test.client import RequestFactory
from django.test.utils import override_settings
-from django.utils import six, unittest
+from django.utils import six
class WSGITest(TestCase):