From 62cd04a2a75c4d952bc89e075dcb1c2e85ff36b8 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 7 Jan 2020 01:02:46 +0100 Subject: [PATCH 01/13] Drop support for Django < 1.11 Ref: https://github.com/pytest-dev/pytest-django/pull/793 --- .travis.yml | 10 +++------- setup.py | 3 --- tox.ini | 13 +++++-------- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 20fcba839..9d97a14fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,27 +39,23 @@ jobs: # Explicitly test (older) pytest 5.3. - python: 3.5 - env: TOXENV=py35-dj110-postgres-pytest53-coverage + env: TOXENV=py35-dj111-postgres-pytest53-coverage services: - postgresql - python: 3.4 - env: TOXENV=py34-dj19-sqlite_file-coverage + env: TOXENV=py34-dj111-sqlite_file-coverage - python: 2.7 env: TOXENV=py27-dj111-mysql_myisam-coverage services: - mysql - - python: 2.7 - env: TOXENV=py27-dj18-postgres-coverage - services: - - postgresql # pypy/pypy3: not included with coverage reports (much slower then). - python: pypy env: TOXENV=pypy-dj111-sqlite_file - python: pypy3 - env: TOXENV=pypy3-dj110-sqlite + env: TOXENV=pypy3-dj111-sqlite - stage: test_release python: 3.6 diff --git a/setup.py b/setup.py index 217593232..f76fc9891 100755 --- a/setup.py +++ b/setup.py @@ -47,9 +47,6 @@ def read(fname): }, classifiers=['Development Status :: 5 - Production/Stable', 'Framework :: Django', - 'Framework :: Django :: 1.8', - 'Framework :: Django :: 1.9', - 'Framework :: Django :: 1.10', 'Framework :: Django :: 1.11', 'Framework :: Django :: 2.0', 'Framework :: Django :: 2.1', diff --git a/tox.ini b/tox.ini index 2a75506b4..fd0e90c34 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,11 @@ [tox] envlist = py37-dj{30,22,21,20,111}-postgres - py36-dj{30,22,21,20,111,110,19,18}-postgres - py35-dj{22,21,20,111,110,19,18}-postgres - py34-dj{20,111,110}-postgres - py27-dj{111,110}-{mysql_innodb,mysql_myisam,postgres} - py27-dj{111,110,19,18}-postgres + py36-dj{30,22,21,20,111}-postgres + py35-dj{22,21,20,111}-postgres + py34-dj{20,111}-postgres + py27-dj{111}-{mysql_innodb,mysql_myisam,postgres} + py27-dj{111}-postgres checkqa [testenv] @@ -17,9 +17,6 @@ deps = dj21: Django>=2.1,<2.2 dj20: Django>=2.0,<2.1 dj111: Django>=1.11,<1.12 - dj110: Django>=1.10,<1.11 - dj19: Django>=1.9,<1.10 - dj18: Django>=1.8,<1.9 mysql_myisam: mysqlclient==1.4.2.post1 mysql_innodb: mysqlclient==1.4.2.post1 From c5a6278bdfa713144884e5e6e21e2fb32787aaf4 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 7 Jan 2020 01:22:11 +0100 Subject: [PATCH 02/13] remove some now dead code --- pytest_django/migrations.py | 9 +-------- pytest_django_test/settings_base.py | 5 ----- tests/conftest.py | 3 --- tests/test_db_setup.py | 28 ---------------------------- tests/test_environment.py | 5 +---- tests/test_fixtures.py | 9 +-------- 6 files changed, 3 insertions(+), 56 deletions(-) diff --git a/pytest_django/migrations.py b/pytest_django/migrations.py index 3c39cb9f6..9cdc91b62 100644 --- a/pytest_django/migrations.py +++ b/pytest_django/migrations.py @@ -1,16 +1,9 @@ # code snippet copied from https://gist.github.com/NotSqrt/5f3c76cd15e40ef62d09 -from pytest_django.lazy_django import get_django_version class DisableMigrations(object): - def __init__(self): - self._django_version = get_django_version() - def __contains__(self, item): return True def __getitem__(self, item): - if self._django_version >= (1, 9): - return None - else: - return "notmigrations" + return None diff --git a/pytest_django_test/settings_base.py b/pytest_django_test/settings_base.py index 050386299..4c9b456f9 100644 --- a/pytest_django_test/settings_base.py +++ b/pytest_django_test/settings_base.py @@ -1,5 +1,3 @@ -import django - ROOT_URLCONF = "pytest_django_test.urls" INSTALLED_APPS = [ "django.contrib.auth", @@ -20,9 +18,6 @@ "django.contrib.messages.middleware.MessageMiddleware", ] -if django.VERSION < (1, 10): - MIDDLEWARE_CLASSES = MIDDLEWARE - TEMPLATES = [ { diff --git a/tests/conftest.py b/tests/conftest.py index 8b76aba29..340491fd2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -81,9 +81,6 @@ def django_testdir(request, testdir, monkeypatch): 'django.contrib.messages.middleware.MessageMiddleware', ] - if django.VERSION < (1, 10): - MIDDLEWARE_CLASSES = MIDDLEWARE - TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', diff --git a/tests/test_db_setup.py b/tests/test_db_setup.py index 375cb8449..1f7460aab 100644 --- a/tests/test_db_setup.py +++ b/tests/test_db_setup.py @@ -1,6 +1,5 @@ import pytest -from pytest_django.lazy_django import get_django_version from pytest_django_test.db_helpers import ( db_exists, drop_database, @@ -151,7 +150,6 @@ def test_sqlite_test_name_used(self, django_testdir): """ import pytest from django.db import connections - from django import VERSION @pytest.mark.django_db def test_a(): @@ -453,32 +451,6 @@ def test_a(): result.stdout.fnmatch_lines(["*PASSED*test_a*"]) -@pytest.mark.skipif( - get_django_version() >= (1, 9), - reason=( - "Django 1.9 requires migration and has no concept of initial data fixtures" - ), -) -def test_initial_data(django_testdir_initial): - """Test that initial data gets loaded.""" - django_testdir_initial.create_test_module( - """ - import pytest - - from .app.models import Item - - @pytest.mark.django_db - def test_inner(): - assert [x.name for x in Item.objects.all()] \ - == ["mark_initial_data"] - """ - ) - - result = django_testdir_initial.runpytest_subprocess("--tb=short", "-v") - assert result.ret == 0 - result.stdout.fnmatch_lines(["*test_inner*PASSED*"]) - - class TestNativeMigrations(object): """ Tests for Django Migrations """ diff --git a/tests/test_environment.py b/tests/test_environment.py index 95f903a1b..cc07ed6a0 100644 --- a/tests/test_environment.py +++ b/tests/test_environment.py @@ -95,10 +95,7 @@ def test_ignore(client): ) result = django_testdir.runpytest_subprocess("-s", "--fail-on-template-vars") - if get_django_version() >= (1, 9): - origin = "'*/tpkg/app/templates/invalid_template_base.html'" - else: - origin = "'invalid_template.html'" + origin = "'*/tpkg/app/templates/invalid_template_base.html'" result.stdout.fnmatch_lines_random( [ "tpkg/test_the_test.py F.*", diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index 2c718c54f..c2ffba229 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -335,7 +335,6 @@ def test_change_settings(self, live_server, settings): def test_settings_restored(self): """Ensure that settings are restored after test_settings_before.""" - import django from django.conf import settings assert TestLiveServer._test_settings_before_run is True @@ -343,10 +342,7 @@ def test_settings_restored(self): "%s.%s" % (settings.__class__.__module__, settings.__class__.__name__) == "django.conf.Settings" ) - if django.VERSION >= (1, 11): - assert settings.ALLOWED_HOSTS == ["testserver"] - else: - assert settings.ALLOWED_HOSTS == ["*"] + assert settings.ALLOWED_HOSTS == ["testserver"] def test_transactions(self, live_server): if not connections_support_transactions(): @@ -445,9 +441,6 @@ def test_serve_static_dj17_without_staticfiles_app(self, live_server, settings): with pytest.raises(HTTPError): urlopen(live_server + "/static/a_file.txt").read() - @pytest.mark.skipif( - get_django_version() < (1, 11), reason="Django >= 1.11 required" - ) def test_specified_port_range_error_message_django_111(self, django_testdir): django_testdir.create_test_module( """ From 43a0ff88387d44804dfe7114395fab1fe688aec1 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 7 Jan 2020 01:23:46 +0100 Subject: [PATCH 03/13] remove some now dead code (live_server) --- pytest_django/fixtures.py | 22 ++++++++-------------- pytest_django/live_server_helper.py | 17 ++++++----------- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/pytest_django/fixtures.py b/pytest_django/fixtures.py index b2cc82580..38c5d69f4 100644 --- a/pytest_django/fixtures.py +++ b/pytest_django/fixtures.py @@ -385,27 +385,21 @@ def live_server(request): """ skip_if_no_django() - import django - addr = request.config.getvalue("liveserver") or os.getenv( "DJANGO_LIVE_TEST_SERVER_ADDRESS" ) if addr and ":" in addr: - if django.VERSION >= (1, 11): - ports = addr.split(":")[1] - if "-" in ports or "," in ports: - warnings.warn( - "Specifying multiple live server ports is not supported " - "in Django 1.11. This will be an error in a future " - "pytest-django release." - ) + ports = addr.split(":")[1] + if "-" in ports or "," in ports: + warnings.warn( + "Specifying multiple live server ports is not supported " + "in Django 1.11. This will be an error in a future " + "pytest-django release." + ) if not addr: - if django.VERSION < (1, 11): - addr = "localhost:8081,8100-8200" - else: - addr = "localhost" + addr = "localhost" server = live_server_helper.LiveServer(addr) request.addfinalizer(server.stop) diff --git a/pytest_django/live_server_helper.py b/pytest_django/live_server_helper.py index 94ded3315..87bdf00cc 100644 --- a/pytest_django/live_server_helper.py +++ b/pytest_django/live_server_helper.py @@ -10,7 +10,6 @@ class LiveServer(object): """ def __init__(self, addr): - import django from django.db import connections from django.test.testcases import LiveServerThread from django.test.utils import modify_settings @@ -39,17 +38,13 @@ def __init__(self, addr): liveserver_kwargs["static_handler"] = _StaticFilesHandler - if django.VERSION < (1, 11): - host, possible_ports = parse_addr(addr) - self.thread = LiveServerThread(host, possible_ports, **liveserver_kwargs) + try: + host, port = addr.split(":") + except ValueError: + host = addr else: - try: - host, port = addr.split(":") - except ValueError: - host = addr - else: - liveserver_kwargs["port"] = int(port) - self.thread = LiveServerThread(host, **liveserver_kwargs) + liveserver_kwargs["port"] = int(port) + self.thread = LiveServerThread(host, **liveserver_kwargs) self._live_server_modified_settings = modify_settings( ALLOWED_HOSTS={"append": host} From b61cef459e38a1048814fe6acbd7fee794cc568f Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 11 Jan 2020 23:59:53 +0100 Subject: [PATCH 04/13] Drop compat module --- pytest_django/compat.py | 15 --------------- pytest_django/fixtures.py | 2 +- 2 files changed, 1 insertion(+), 16 deletions(-) delete mode 100644 pytest_django/compat.py diff --git a/pytest_django/compat.py b/pytest_django/compat.py deleted file mode 100644 index 9203a50e1..000000000 --- a/pytest_django/compat.py +++ /dev/null @@ -1,15 +0,0 @@ -# This file cannot be imported from until Django sets up -try: - # Django 1.11 - from django.test.utils import setup_databases, teardown_databases # noqa: F401 -except ImportError: - # In Django prior to 1.11, teardown_databases is only available as a method on DiscoverRunner - from django.test.runner import ( # noqa: F401 - setup_databases, - DiscoverRunner as _DiscoverRunner, - ) - - def teardown_databases(db_cfg, verbosity): - _DiscoverRunner(verbosity=verbosity, interactive=False).teardown_databases( - db_cfg - ) diff --git a/pytest_django/fixtures.py b/pytest_django/fixtures.py index 38c5d69f4..189c58a9b 100644 --- a/pytest_django/fixtures.py +++ b/pytest_django/fixtures.py @@ -91,7 +91,7 @@ def django_db_setup( django_db_modify_db_settings, ): """Top level fixture to ensure test databases are available""" - from .compat import setup_databases, teardown_databases + from django.test.utils import setup_databases, teardown_databases setup_databases_args = {} From 5a32049178284172c738a3028661859447081cb2 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sun, 12 Jan 2020 00:01:21 +0100 Subject: [PATCH 05/13] remove now unused parse_addr --- pytest_django/live_server_helper.py | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/pytest_django/live_server_helper.py b/pytest_django/live_server_helper.py index 87bdf00cc..1fd52c7f8 100644 --- a/pytest_django/live_server_helper.py +++ b/pytest_django/live_server_helper.py @@ -74,31 +74,3 @@ def __add__(self, other): def __repr__(self): return "" % self.url - - -def parse_addr(specified_address): - """Parse the --liveserver argument into a host/IP address and port range""" - # This code is based on - # django.test.testcases.LiveServerTestCase.setUpClass - - # The specified ports may be of the form '8000-8010,8080,9200-9300' - # i.e. a comma-separated list of ports or ranges of ports, so we break - # it down into a detailed list of all possible ports. - possible_ports = [] - try: - host, port_ranges = specified_address.split(":") - for port_range in port_ranges.split(","): - # A port range can be of either form: '8000' or '8000-8010'. - extremes = list(map(int, port_range.split("-"))) - assert len(extremes) in (1, 2) - if len(extremes) == 1: - # Port range of the form '8000' - possible_ports.append(extremes[0]) - else: - # Port range of the form '8000-8010' - for port in range(extremes[0], extremes[1] + 1): - possible_ports.append(port) - except Exception: - raise Exception('Invalid address ("%s") for live server.' % specified_address) - - return host, possible_ports From 284e8dab182b1d244d7c419d7d791a615162fd7d Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sun, 12 Jan 2020 00:04:06 +0100 Subject: [PATCH 06/13] remove dead code --- tests/conftest.py | 17 ----------------- tests/test_urls.py | 6 ++---- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 340491fd2..cb3728a88 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -143,20 +143,3 @@ def create_app_file(code, filename): ) return testdir - - -@pytest.fixture -def django_testdir_initial(django_testdir): - """A django_testdir fixture which provides initial_data.""" - django_testdir.project_root.join("tpkg/app/migrations").remove() - django_testdir.makefile( - ".json", - initial_data=""" - [{ - "pk": 1, - "model": "app.item", - "fields": { "name": "mark_initial_data" } - }]""", - ) - - return django_testdir diff --git a/tests/test_urls.py b/tests/test_urls.py index 9001fddce..af7ccffc3 100644 --- a/tests/test_urls.py +++ b/tests/test_urls.py @@ -5,10 +5,8 @@ @pytest.mark.urls("pytest_django_test.urls_overridden") def test_urls(): - try: - from django.urls import is_valid_path - except ImportError: - from django.core.urlresolvers import is_valid_path + from django.urls import is_valid_path + assert settings.ROOT_URLCONF == "pytest_django_test.urls_overridden" assert is_valid_path("/overridden_url/") From 059f4540e975265840b9fe7c689cb873ec7a6197 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 14 Jan 2020 04:26:56 +0100 Subject: [PATCH 07/13] remove unused import fallback --- pytest_django/plugin.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pytest_django/plugin.py b/pytest_django/plugin.py index 5c59bd540..f00dd99be 100644 --- a/pytest_django/plugin.py +++ b/pytest_django/plugin.py @@ -590,13 +590,9 @@ def _django_set_urlconf(request): marker = request.node.get_closest_marker("urls") if marker: skip_if_no_django() - import django.conf - try: - from django.urls import clear_url_caches, set_urlconf - except ImportError: - # Removed in Django 2.0 - from django.core.urlresolvers import clear_url_caches, set_urlconf + import django.conf + from django.urls import clear_url_caches, set_urlconf urls = validate_urls(marker) original_urlconf = django.conf.settings.ROOT_URLCONF From 22ea48114c414ae6d15f6f781bfc1e072f7a1dc9 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 14 Jan 2020 04:27:55 +0100 Subject: [PATCH 08/13] remove use of django.core.urlresolvers --- tests/test_urls.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/test_urls.py b/tests/test_urls.py index af7ccffc3..9cce8db61 100644 --- a/tests/test_urls.py +++ b/tests/test_urls.py @@ -31,10 +31,7 @@ def fake_view(request): testdir.makepyfile( """ - try: - from django.urls import reverse, NoReverseMatch - except ImportError: # Django < 2.0 - from django.core.urlresolvers import reverse, NoReverseMatch + from django.urls import reverse, NoReverseMatch import pytest @pytest.mark.urls('myurls') @@ -78,10 +75,7 @@ def fake_view(request): testdir.makepyfile( """ - try: - from django.urls import reverse, NoReverseMatch - except ImportError: # Django < 2.0 - from django.core.urlresolvers import reverse, NoReverseMatch + from django.urls import reverse, NoReverseMatch import pytest @pytest.mark.urls('myurls') From dfa384afe5c81ba9ae7c42bb06fee6dc6aa9e2d7 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 14 Jan 2020 06:00:42 +0100 Subject: [PATCH 09/13] doc --- docs/helpers.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/helpers.rst b/docs/helpers.rst index 76b32492a..96507eefe 100644 --- a/docs/helpers.rst +++ b/docs/helpers.rst @@ -104,8 +104,7 @@ test will fail when trying to access the database. Ignore errors when using the ``--fail-on-template-vars`` option, i.e. do not cause tests to fail if your templates contain invalid variables. - This marker sets the ``string_if_invalid`` template option, or - the older ``settings.TEMPLATE_STRING_IF_INVALID=None`` (Django up to 1.10). + This marker sets the ``string_if_invalid`` template option. See :ref:`django:invalid-template-variables`. Example usage:: From 59bd1ae5deb747c7a40d6aa46963c50eedf4c847 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 14 Jan 2020 06:00:53 +0100 Subject: [PATCH 10/13] TEMPLATE_STRING_IF_INVALID --- pytest_django/plugin.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pytest_django/plugin.py b/pytest_django/plugin.py index f00dd99be..eaff29e4a 100644 --- a/pytest_django/plugin.py +++ b/pytest_django/plugin.py @@ -687,12 +687,7 @@ def __mod__(self, var): ): from django.conf import settings as dj_settings - if dj_settings.TEMPLATES: - dj_settings.TEMPLATES[0]["OPTIONS"][ - "string_if_invalid" - ] = InvalidVarException() - else: - dj_settings.TEMPLATE_STRING_IF_INVALID = InvalidVarException() + dj_settings.TEMPLATES[0]["OPTIONS"]["string_if_invalid"] = InvalidVarException() @pytest.fixture(autouse=True) From ceebacbda0480dbc954afe5932907bc0c47107e5 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 14 Jan 2020 06:01:00 +0100 Subject: [PATCH 11/13] test --- pytest_django/plugin.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pytest_django/plugin.py b/pytest_django/plugin.py index eaff29e4a..09d56d24b 100644 --- a/pytest_django/plugin.py +++ b/pytest_django/plugin.py @@ -652,6 +652,8 @@ def _get_origin(): if origin is not None: return origin + assert 0, "dead?" + from django.template import Template # finding the ``render`` needle in the stack From 8aaa3ddc72e867092c17675e13ec2b221e8986ce Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 14 Jan 2020 06:08:48 +0100 Subject: [PATCH 12/13] dead code for TEMPLATE_STRING_IF_INVALID --- pytest_django/plugin.py | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/pytest_django/plugin.py b/pytest_django/plugin.py index 09d56d24b..b3ea205c0 100644 --- a/pytest_django/plugin.py +++ b/pytest_django/plugin.py @@ -639,8 +639,7 @@ def __contains__(self, key): def _get_origin(): stack = inspect.stack() - # Try to use topmost `self.origin` first (Django 1.9+, and with - # TEMPLATE_DEBUG).. + # Find topmost `self.origin`. for f in stack[2:]: func = f[3] if func == "render": @@ -652,32 +651,10 @@ def _get_origin(): if origin is not None: return origin - assert 0, "dead?" - - from django.template import Template - - # finding the ``render`` needle in the stack - frame = reduce( - lambda x, y: y[3] == "render" and "base.py" in y[1] and y or x, stack - ) - # assert 0, stack - frame = frame[0] - # finding only the frame locals in all frame members - f_locals = reduce( - lambda x, y: y[0] == "f_locals" and y or x, inspect.getmembers(frame) - )[1] - # ``django.template.base.Template`` - template = f_locals["self"] - if isinstance(template, Template): - return template.name - def __mod__(self, var): """Handle TEMPLATE_STRING_IF_INVALID % var.""" origin = self._get_origin() - if origin: - msg = "Undefined template variable '%s' in '%s'" % (var, origin) - else: - msg = "Undefined template variable '%s'" % var + msg = "Undefined template variable '%s' in '%s'" % (var, origin) if self.fail: pytest.fail(msg) else: From 31bed71618114558eb3446dcc01433f171f7347b Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 14 Jan 2020 06:11:31 +0100 Subject: [PATCH 13/13] README: update compat for Django, Python --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 47255c882..6c284ff6d 100644 --- a/README.rst +++ b/README.rst @@ -28,9 +28,9 @@ pytest-django allows you to test your Django project/applications with the `_ * Version compatibility: - * Django: 1.8-1.11, 2.0-2.2, + * Django: 1.11, 2.0-2.2, and latest master branch (compatible at the time of each release) - * Python: CPython 2.7, 3.4-3.7 or PyPy 2, 3 + * Python: CPython 2.7, 3.4-3.8 or PyPy 2, 3 * pytest: >=3.6 * Licence: BSD