mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	Fixed #30116 -- Dropped support for Python 3.5.
This commit is contained in:
		
							
								
								
									
										2
									
								
								INSTALL
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								INSTALL
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| Thanks for downloading Django. | ||||
|  | ||||
| To install it, make sure you have Python 3.5 or greater installed. Then run | ||||
| To install it, make sure you have Python 3.6 or greater installed. Then run | ||||
| this command from the command prompt: | ||||
|  | ||||
|     python setup.py install | ||||
|   | ||||
| @@ -77,10 +77,8 @@ def _check_lazy_references(apps, ignore=None): | ||||
|         """ | ||||
|         operation, args, keywords = obj, [], {} | ||||
|         while hasattr(operation, 'func'): | ||||
|             # The or clauses are redundant but work around a bug (#25945) in | ||||
|             # functools.partial in Python <= 3.5.1. | ||||
|             args.extend(getattr(operation, 'args', []) or []) | ||||
|             keywords.update(getattr(operation, 'keywords', {}) or {}) | ||||
|             args.extend(getattr(operation, 'args', [])) | ||||
|             keywords.update(getattr(operation, 'keywords', {})) | ||||
|             operation = operation.func | ||||
|         return operation, args, keywords | ||||
|  | ||||
|   | ||||
| @@ -160,10 +160,6 @@ class BaseDatabaseFeatures: | ||||
|     # Support for the DISTINCT ON clause | ||||
|     can_distinct_on_fields = False | ||||
|  | ||||
|     # Does the backend decide to commit before SAVEPOINT statements | ||||
|     # when autocommit is disabled? https://bugs.python.org/issue8145#msg109965 | ||||
|     autocommits_when_autocommit_is_off = False | ||||
|  | ||||
|     # Does the backend prevent running SQL queries in broken transactions? | ||||
|     atomic_transactions = True | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,3 @@ | ||||
| import sys | ||||
|  | ||||
| from django.db.backends.base.features import BaseDatabaseFeatures | ||||
|  | ||||
| from .base import Database | ||||
| @@ -15,7 +13,6 @@ class DatabaseFeatures(BaseDatabaseFeatures): | ||||
|     supports_timezones = False | ||||
|     max_query_params = 999 | ||||
|     supports_mixed_date_datetime_comparisons = False | ||||
|     autocommits_when_autocommit_is_off = sys.version_info < (3, 6) | ||||
|     can_introspect_autofield = True | ||||
|     can_introspect_decimal_field = False | ||||
|     can_introspect_duration_field = False | ||||
|   | ||||
| @@ -173,14 +173,6 @@ class Atomic(ContextDecorator): | ||||
|             connection.commit_on_exit = True | ||||
|             connection.needs_rollback = False | ||||
|             if not connection.get_autocommit(): | ||||
|                 # sqlite3 in Python < 3.6 doesn't handle transactions and | ||||
|                 # savepoints properly when autocommit is off. | ||||
|                 # Turning autocommit back on isn't an option; it would trigger | ||||
|                 # a premature commit. Give up if that happens. | ||||
|                 if connection.features.autocommits_when_autocommit_is_off: | ||||
|                     raise TransactionManagementError( | ||||
|                         "Your database backend doesn't behave properly when " | ||||
|                         "autocommit is off. Turn it on before using 'atomic'.") | ||||
|                 # Pretend we're already in an atomic block to bypass the code | ||||
|                 # that disables autocommit to enter a transaction, and make a | ||||
|                 # note to deal with this case in __exit__. | ||||
|   | ||||
| @@ -3,8 +3,6 @@ import itertools | ||||
| import operator | ||||
| from functools import total_ordering, wraps | ||||
|  | ||||
| from django.utils.version import PY36, get_docs_version | ||||
|  | ||||
|  | ||||
| # You can't trivially replace this with `functools.partial` because this binds | ||||
| # to classes and returns bound instances, whereas functools.partial (on | ||||
| @@ -22,8 +20,8 @@ class cached_property: | ||||
|  | ||||
|     A cached property can be made out of an existing method: | ||||
|     (e.g. ``url = cached_property(get_absolute_url)``). | ||||
|     On Python < 3.6, the optional ``name`` argument must be provided, e.g. | ||||
|     ``url = cached_property(get_absolute_url, name='url')``. | ||||
|     The optional ``name`` argument is obsolete as of Python 3.6 and will be | ||||
|     deprecated in Django 4.0 (#30127). | ||||
|     """ | ||||
|     name = None | ||||
|  | ||||
| @@ -34,29 +32,8 @@ class cached_property: | ||||
|             '__set_name__() on it.' | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def _is_mangled(name): | ||||
|         return name.startswith('__') and not name.endswith('__') | ||||
|  | ||||
|     def __init__(self, func, name=None): | ||||
|         if PY36: | ||||
|             self.real_func = func | ||||
|         else: | ||||
|             func_name = func.__name__ | ||||
|             name = name or func_name | ||||
|             if not (isinstance(name, str) and name.isidentifier()): | ||||
|                 raise ValueError( | ||||
|                     "%r can't be used as the name of a cached_property." % name, | ||||
|                 ) | ||||
|             if self._is_mangled(name): | ||||
|                 raise ValueError( | ||||
|                     'cached_property does not work with mangled methods on ' | ||||
|                     'Python < 3.6 without the appropriate `name` argument. See ' | ||||
|                     'https://docs.djangoproject.com/en/%s/ref/utils/' | ||||
|                     '#cached-property-mangled-name' % get_docs_version(), | ||||
|                 ) | ||||
|             self.name = name | ||||
|             self.func = func | ||||
|         self.real_func = func | ||||
|         self.__doc__ = getattr(func, '__doc__') | ||||
|  | ||||
|     def __set_name__(self, owner, name): | ||||
|   | ||||
| @@ -72,11 +72,10 @@ def module_has_submodule(package, module_name): | ||||
|     full_module_name = package_name + '.' + module_name | ||||
|     try: | ||||
|         return importlib_find(full_module_name, package_path) is not None | ||||
|     except (ImportError, AttributeError): | ||||
|         # When module_name is an invalid dotted path, Python raises ImportError | ||||
|         # (or ModuleNotFoundError in Python 3.6+). AttributeError may be raised | ||||
|     except (ModuleNotFoundError, AttributeError): | ||||
|         # When module_name is an invalid dotted path, Python raises | ||||
|         # ModuleNotFoundError. AttributeError is raised on PY36 (fixed in PY37) | ||||
|         # if the penultimate part of the path is not a package. | ||||
|         # (https://bugs.python.org/issue30436) | ||||
|         return False | ||||
|  | ||||
|  | ||||
| @@ -87,7 +86,7 @@ def module_dir(module): | ||||
|     Raise ValueError otherwise, e.g. for namespace packages that are split | ||||
|     over several directories. | ||||
|     """ | ||||
|     # Convert to list because _NamespacePath does not support indexing on 3.3. | ||||
|     # Convert to list because _NamespacePath does not support indexing. | ||||
|     paths = list(getattr(module, '__path__', [])) | ||||
|     if len(paths) == 1: | ||||
|         return paths[0] | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| How to install Django on Windows | ||||
| ================================ | ||||
|  | ||||
| This document will guide you through installing Python 3.5 and Django on | ||||
| This document will guide you through installing Python 3.7 and Django on | ||||
| Windows. It also provides instructions for installing `virtualenv`_ and | ||||
| `virtualenvwrapper`_, which make it easier to work on Python projects. This is | ||||
| meant as a beginner's guide for users working on Django projects and does not | ||||
| @@ -17,12 +17,12 @@ Install Python | ||||
| ============== | ||||
|  | ||||
| Django is a Python web framework, thus requiring Python to be installed on your | ||||
| machine. At the time of writing, Python 3.5 is the latest version. | ||||
| machine. At the time of writing, Python 3.7 is the latest version. | ||||
|  | ||||
| To install Python on your machine go to https://python.org/downloads/. The | ||||
| website should offer you a download button for the latest Python version. | ||||
| Download the executable installer and run it. Check the box next to ``Add | ||||
| Python 3.5 to PATH`` and then click ``Install Now``. | ||||
| Python 3.7 to PATH`` and then click ``Install Now``. | ||||
|  | ||||
| After installation, open the command prompt and check that the Python version | ||||
| matches the version you installed by executing:: | ||||
|   | ||||
| @@ -90,12 +90,12 @@ In addition to the default environments, ``tox`` supports running unit tests | ||||
| for other versions of Python and other database backends. Since Django's test | ||||
| suite doesn't bundle a settings file for database backends other than SQLite, | ||||
| however, you must :ref:`create and provide your own test settings | ||||
| <running-unit-tests-settings>`. For example, to run the tests on Python 3.5 | ||||
| <running-unit-tests-settings>`. For example, to run the tests on Python 3.7 | ||||
| using PostgreSQL:: | ||||
|  | ||||
|     $ tox -e py35-postgres -- --settings=my_postgres_settings | ||||
|     $ tox -e py37-postgres -- --settings=my_postgres_settings | ||||
|  | ||||
| This command sets up a Python 3.5 virtual environment, installs Django's | ||||
| This command sets up a Python 3.7 virtual environment, installs Django's | ||||
| test suite dependencies (including those for PostgreSQL), and calls | ||||
| ``runtests.py`` with the supplied arguments (in this case, | ||||
| ``--settings=my_postgres_settings``). | ||||
|   | ||||
| @@ -219,8 +219,8 @@ this. For a small app like polls, this process isn't too difficult. | ||||
|                'License :: OSI Approved :: BSD License',  # example license | ||||
|                'Operating System :: OS Independent', | ||||
|                'Programming Language :: Python', | ||||
|                'Programming Language :: Python :: 3.5', | ||||
|                'Programming Language :: Python :: 3.6', | ||||
|                'Programming Language :: Python :: 3.7', | ||||
|                'Topic :: Internet :: WWW/HTTP', | ||||
|                'Topic :: Internet :: WWW/HTTP :: Dynamic Content', | ||||
|            ], | ||||
|   | ||||
| @@ -23,7 +23,7 @@ in a shell prompt (indicated by the $ prefix): | ||||
| If Django is installed, you should see the version of your installation. If it | ||||
| isn't, you'll get an error telling "No module named django". | ||||
|  | ||||
| This tutorial is written for Django |version|, which supports Python 3.5 and | ||||
| This tutorial is written for Django |version|, which supports Python 3.6 and | ||||
| later. If the Django version doesn't match, you can refer to the tutorial for | ||||
| your version of Django by using the version switcher at the bottom right corner | ||||
| of this page, or update Django to the newest version. If you're using an older | ||||
|   | ||||
| @@ -514,18 +514,6 @@ https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004 | ||||
|         z = person.friends         # does not call | ||||
|         x is z                     # is True | ||||
|  | ||||
|     .. warning:: | ||||
|  | ||||
|         .. _cached-property-mangled-name: | ||||
|  | ||||
|         On Python < 3.6, ``cached_property`` doesn't work properly with a | ||||
|         mangled__ name unless it's passed a ``name`` of the form | ||||
|         ``_Class__attribute``:: | ||||
|  | ||||
|             __friends = cached_property(get_friends, name='_Person__friends') | ||||
|  | ||||
|         __ https://docs.python.org/faq/programming.html#i-try-to-use-spam-and-i-get-an-error-about-someclassname-spam | ||||
|  | ||||
| .. function:: keep_lazy(func, *resultclasses) | ||||
|  | ||||
|     Django offers many utility functions (particularly in ``django.utils``) | ||||
|   | ||||
| @@ -1329,23 +1329,6 @@ The decorator can also be applied to test case classes:: | ||||
|     decorator. For a given class, :func:`~django.test.modify_settings` is | ||||
|     always applied after :func:`~django.test.override_settings`. | ||||
|  | ||||
| .. admonition:: Considerations with Python 3.5 | ||||
|  | ||||
|     If using Python 3.5 (or older, if using an older version of Django), avoid | ||||
|     mixing  ``remove`` with ``append`` and ``prepend`` in | ||||
|     :func:`~django.test.modify_settings`. In some cases it matters whether a | ||||
|     value is first added and then removed or vice versa, and dictionary key | ||||
|     order isn't preserved until Python 3.6. Instead, apply the decorator twice | ||||
|     to guarantee the order of operations. For example, to ensure that | ||||
|     ``SessionMiddleware`` appears first in ``MIDDLEWARE``:: | ||||
|  | ||||
|         @modify_settings(MIDDLEWARE={ | ||||
|             'remove': ['django.contrib.sessions.middleware.SessionMiddleware'], | ||||
|         ) | ||||
|         @modify_settings(MIDDLEWARE={ | ||||
|             'prepend': ['django.contrib.sessions.middleware.SessionMiddleware'], | ||||
|         }) | ||||
|  | ||||
| .. warning:: | ||||
|  | ||||
|     The settings file contains some settings that are only consulted during | ||||
|   | ||||
							
								
								
									
										3
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								setup.py
									
									
									
									
									
								
							| @@ -5,7 +5,7 @@ from distutils.sysconfig import get_python_lib | ||||
| from setuptools import find_packages, setup | ||||
|  | ||||
| CURRENT_PYTHON = sys.version_info[:2] | ||||
| REQUIRED_PYTHON = (3, 5) | ||||
| REQUIRED_PYTHON = (3, 6) | ||||
|  | ||||
| # This check and everything above must remain compatible with Python 2.7. | ||||
| if CURRENT_PYTHON < REQUIRED_PYTHON: | ||||
| @@ -98,7 +98,6 @@ setup( | ||||
|         'Operating System :: OS Independent', | ||||
|         'Programming Language :: Python', | ||||
|         'Programming Language :: Python :: 3', | ||||
|         'Programming Language :: Python :: 3.5', | ||||
|         'Programming Language :: Python :: 3.6', | ||||
|         'Programming Language :: Python :: 3.7', | ||||
|         'Programming Language :: Python :: 3 :: Only', | ||||
|   | ||||
| @@ -32,7 +32,6 @@ from django.db.migrations.recorder import MigrationRecorder | ||||
| from django.test import ( | ||||
|     LiveServerTestCase, SimpleTestCase, TestCase, override_settings, | ||||
| ) | ||||
| from django.utils.version import PY36 | ||||
|  | ||||
| custom_templates_dir = os.path.join(os.path.dirname(__file__), 'custom_templates') | ||||
|  | ||||
| @@ -1145,7 +1144,7 @@ class ManageCheck(AdminScriptTestCase): | ||||
|         args = ['check'] | ||||
|         out, err = self.run_manage(args) | ||||
|         self.assertNoOutput(out) | ||||
|         self.assertOutput(err, 'ModuleNotFoundError' if PY36 else 'ImportError') | ||||
|         self.assertOutput(err, 'ModuleNotFoundError') | ||||
|         self.assertOutput(err, 'No module named') | ||||
|         self.assertOutput(err, 'admin_scriptz') | ||||
|  | ||||
|   | ||||
| @@ -1211,10 +1211,7 @@ class FakeSMTPServer(smtpd.SMTPServer, threading.Thread): | ||||
|  | ||||
|     def __init__(self, *args, **kwargs): | ||||
|         threading.Thread.__init__(self) | ||||
|         # New kwarg added in Python 3.5; default switching to False in 3.6. | ||||
|         # Setting a value only silences a deprecation warning in Python 3.5. | ||||
|         kwargs['decode_data'] = True | ||||
|         smtpd.SMTPServer.__init__(self, *args, **kwargs) | ||||
|         smtpd.SMTPServer.__init__(self, *args, decode_data=True, **kwargs) | ||||
|         self._sink = [] | ||||
|         self.active = False | ||||
|         self.active_lock = threading.Lock() | ||||
|   | ||||
| @@ -22,7 +22,6 @@ from django.utils.deconstruct import deconstructible | ||||
| from django.utils.functional import SimpleLazyObject | ||||
| from django.utils.timezone import get_default_timezone, get_fixed_timezone, utc | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
| from django.utils.version import PY36 | ||||
|  | ||||
| from .models import FoodManager, FoodQuerySet | ||||
|  | ||||
| @@ -413,10 +412,7 @@ class WriterTests(SimpleTestCase): | ||||
|         # Test a string regex with flag | ||||
|         validator = RegexValidator(r'^[0-9]+$', flags=re.S) | ||||
|         string = MigrationWriter.serialize(validator)[0] | ||||
|         if PY36: | ||||
|             self.assertEqual(string, "django.core.validators.RegexValidator('^[0-9]+$', flags=re.RegexFlag(16))") | ||||
|         else: | ||||
|             self.assertEqual(string, "django.core.validators.RegexValidator('^[0-9]+$', flags=16)") | ||||
|         self.assertEqual(string, "django.core.validators.RegexValidator('^[0-9]+$', flags=re.RegexFlag(16))") | ||||
|         self.serialize_round_trip(validator) | ||||
|  | ||||
|         # Test message and code | ||||
|   | ||||
| @@ -1,11 +1,9 @@ | ||||
| import unittest | ||||
| from operator import attrgetter | ||||
|  | ||||
| from django.core.exceptions import FieldError, ValidationError | ||||
| from django.db import connection, models | ||||
| from django.test import SimpleTestCase, TestCase | ||||
| from django.test.utils import CaptureQueriesContext, isolate_apps | ||||
| from django.utils.version import PY36 | ||||
|  | ||||
| from .models import ( | ||||
|     Base, Chef, CommonInfo, GrandChild, GrandParent, ItalianRestaurant, | ||||
| @@ -176,7 +174,6 @@ class ModelInheritanceTests(TestCase): | ||||
|  | ||||
|         self.assertIs(C._meta.parents[A], C._meta.get_field('a')) | ||||
|  | ||||
|     @unittest.skipUnless(PY36, 'init_subclass is new in Python 3.6') | ||||
|     @isolate_apps('model_inheritance') | ||||
|     def test_init_subclass(self): | ||||
|         saved_kwargs = {} | ||||
| @@ -193,7 +190,6 @@ class ModelInheritanceTests(TestCase): | ||||
|  | ||||
|         self.assertEqual(saved_kwargs, kwargs) | ||||
|  | ||||
|     @unittest.skipUnless(PY36, '__set_name__ is new in Python 3.6') | ||||
|     @isolate_apps('model_inheritance') | ||||
|     def test_set_name(self): | ||||
|         class ClassAttr: | ||||
|   | ||||
| @@ -234,7 +234,7 @@ def teardown(state): | ||||
|     # Discard the multiprocessing.util finalizer that tries to remove a | ||||
|     # temporary directory that's already removed by this script's | ||||
|     # atexit.register(shutil.rmtree, TMPDIR) handler. Prevents | ||||
|     # FileNotFoundError at the end of a test run on Python 3.6+ (#27890). | ||||
|     # FileNotFoundError at the end of a test run (#27890). | ||||
|     from multiprocessing.util import _finalizer_registry | ||||
|     _finalizer_registry.pop((-100, 0), None) | ||||
|  | ||||
|   | ||||
| @@ -228,7 +228,6 @@ class AtomicInsideTransactionTests(AtomicTests): | ||||
|         self.atomic.__exit__(*sys.exc_info()) | ||||
|  | ||||
|  | ||||
| @skipIfDBFeature('autocommits_when_autocommit_is_off') | ||||
| class AtomicWithoutAutocommitTests(AtomicTests): | ||||
|     """All basic tests for atomic should also pass when autocommit is turned off.""" | ||||
|  | ||||
| @@ -480,7 +479,6 @@ class AtomicMiscTests(TransactionTestCase): | ||||
|         Reporter.objects.create() | ||||
|  | ||||
|  | ||||
| @skipIfDBFeature('autocommits_when_autocommit_is_off') | ||||
| class NonAutocommitTests(TransactionTestCase): | ||||
|  | ||||
|     available_apps = [] | ||||
|   | ||||
| @@ -1,8 +1,5 @@ | ||||
| import unittest | ||||
|  | ||||
| from django.test import SimpleTestCase | ||||
| from django.utils.functional import cached_property, lazy | ||||
| from django.utils.version import PY36 | ||||
|  | ||||
|  | ||||
| class FunctionalTests(SimpleTestCase): | ||||
| @@ -104,7 +101,6 @@ class FunctionalTests(SimpleTestCase): | ||||
|         for attr in attrs: | ||||
|             self.assertCachedPropertyWorks(attr, Class) | ||||
|  | ||||
|     @unittest.skipUnless(PY36, '__set_name__ is new in Python 3.6') | ||||
|     def test_cached_property_auto_name(self): | ||||
|         """ | ||||
|         cached_property caches its value and behaves like a property | ||||
| @@ -132,7 +128,6 @@ class FunctionalTests(SimpleTestCase): | ||||
|         obj.other2 | ||||
|         self.assertFalse(hasattr(obj, 'different_name')) | ||||
|  | ||||
|     @unittest.skipUnless(PY36, '__set_name__ is new in Python 3.6') | ||||
|     def test_cached_property_reuse_different_names(self): | ||||
|         """Disallow this case because the decorated function wouldn't be cached.""" | ||||
|         with self.assertRaises(RuntimeError) as ctx: | ||||
| @@ -151,7 +146,6 @@ class FunctionalTests(SimpleTestCase): | ||||
|             )) | ||||
|         ) | ||||
|  | ||||
|     @unittest.skipUnless(PY36, '__set_name__ is new in Python 3.6') | ||||
|     def test_cached_property_reuse_same_name(self): | ||||
|         """ | ||||
|         Reusing a cached_property on different classes under the same name is | ||||
| @@ -177,7 +171,6 @@ class FunctionalTests(SimpleTestCase): | ||||
|         self.assertEqual(b.cp, 2) | ||||
|         self.assertEqual(a.cp, 1) | ||||
|  | ||||
|     @unittest.skipUnless(PY36, '__set_name__ is new in Python 3.6') | ||||
|     def test_cached_property_set_name_not_called(self): | ||||
|         cp = cached_property(lambda s: None) | ||||
|  | ||||
| @@ -189,29 +182,6 @@ class FunctionalTests(SimpleTestCase): | ||||
|         with self.assertRaisesMessage(TypeError, msg): | ||||
|             Foo().cp | ||||
|  | ||||
|     @unittest.skipIf(PY36, '__set_name__ is new in Python 3.6') | ||||
|     def test_cached_property_mangled_error(self): | ||||
|         msg = ( | ||||
|             'cached_property does not work with mangled methods on ' | ||||
|             'Python < 3.6 without the appropriate `name` argument.' | ||||
|         ) | ||||
|         with self.assertRaisesMessage(ValueError, msg): | ||||
|             @cached_property | ||||
|             def __value(self): | ||||
|                 pass | ||||
|         with self.assertRaisesMessage(ValueError, msg): | ||||
|             def func(self): | ||||
|                 pass | ||||
|             cached_property(func, name='__value') | ||||
|  | ||||
|     @unittest.skipIf(PY36, '__set_name__ is new in Python 3.6') | ||||
|     def test_cached_property_name_validation(self): | ||||
|         msg = "%s can't be used as the name of a cached_property." | ||||
|         with self.assertRaisesMessage(ValueError, msg % "'<lambda>'"): | ||||
|             cached_property(lambda x: None) | ||||
|         with self.assertRaisesMessage(ValueError, msg % 42): | ||||
|             cached_property(str, name=42) | ||||
|  | ||||
|     def test_lazy_equality(self): | ||||
|         """ | ||||
|         == and != work correctly for Promises. | ||||
|   | ||||
| @@ -17,7 +17,6 @@ from django.test.utils import LoggingCaptureMixin | ||||
| from django.urls import path, reverse | ||||
| from django.utils.functional import SimpleLazyObject | ||||
| from django.utils.safestring import mark_safe | ||||
| from django.utils.version import PY36 | ||||
| from django.views.debug import ( | ||||
|     CLEANSED_SUBSTITUTE, CallableSettingWrapper, ExceptionReporter, | ||||
|     cleanse_setting, technical_500_response, | ||||
| @@ -515,7 +514,7 @@ class ExceptionReporterTests(SimpleTestCase): | ||||
|             exc_type, exc_value, tb = sys.exc_info() | ||||
|         reporter = ExceptionReporter(request, exc_type, exc_value, tb) | ||||
|         html = reporter.get_traceback_html() | ||||
|         self.assertInHTML('<h1>%sError at /test_view/</h1>' % ('ModuleNotFound' if PY36 else 'Import'), html) | ||||
|         self.assertInHTML('<h1>ModuleNotFoundError at /test_view/</h1>', html) | ||||
|  | ||||
|     def test_ignore_traceback_evaluation_exceptions(self): | ||||
|         """ | ||||
|   | ||||
							
								
								
									
										2
									
								
								tox.ini
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								tox.ini
									
									
									
									
									
								
							| @@ -21,7 +21,7 @@ passenv = DJANGO_SETTINGS_MODULE PYTHONPATH HOME DISPLAY | ||||
| setenv = | ||||
|     PYTHONDONTWRITEBYTECODE=1 | ||||
| deps = | ||||
|     py{3,35,36,37}: -rtests/requirements/py3.txt | ||||
|     py{3,36,37}: -rtests/requirements/py3.txt | ||||
|     postgres: -rtests/requirements/postgres.txt | ||||
|     mysql: -rtests/requirements/mysql.txt | ||||
|     oracle: -rtests/requirements/oracle.txt | ||||
|   | ||||
		Reference in New Issue
	
	Block a user