Skip to content

Commit 0612297

Browse files
committed
Require pytest>=7.0
1 parent b63d975 commit 0612297

20 files changed

+554
-441
lines changed

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pytest-django allows you to test your Django project/applications with the
3535
* Django: 3.2, 4.0, 4.1, 4.2 and latest main branch (compatible at the time of
3636
each release)
3737
* Python: CPython>=3.8 or PyPy 3
38-
* pytest: >=5.4
38+
* pytest: >=7.0
3939

4040
For compatibility with older versions, use the pytest-django 3.*.* series.
4141

pytest_django/fixtures.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def django_db_modify_db_settings_tox_suffix() -> None:
5858

5959

6060
@pytest.fixture(scope="session")
61-
def django_db_modify_db_settings_xdist_suffix(request) -> None:
61+
def django_db_modify_db_settings_xdist_suffix(request: pytest.FixtureRequest) -> None:
6262
skip_if_no_django()
6363

6464
xdist_suffix = getattr(request.config, "workerinput", {}).get("workerid")
@@ -83,23 +83,23 @@ def django_db_modify_db_settings(
8383

8484

8585
@pytest.fixture(scope="session")
86-
def django_db_use_migrations(request) -> bool:
86+
def django_db_use_migrations(request: pytest.FixtureRequest) -> bool:
8787
return not request.config.getvalue("nomigrations")
8888

8989

9090
@pytest.fixture(scope="session")
91-
def django_db_keepdb(request) -> bool:
91+
def django_db_keepdb(request: pytest.FixtureRequest) -> bool:
9292
return request.config.getvalue("reuse_db")
9393

9494

9595
@pytest.fixture(scope="session")
96-
def django_db_createdb(request) -> bool:
96+
def django_db_createdb(request: pytest.FixtureRequest) -> bool:
9797
return request.config.getvalue("create_db")
9898

9999

100100
@pytest.fixture(scope="session")
101101
def django_db_setup(
102-
request,
102+
request: pytest.FixtureRequest,
103103
django_test_environment: None,
104104
django_db_blocker,
105105
django_db_use_migrations: bool,
@@ -142,7 +142,7 @@ def teardown_database() -> None:
142142

143143
@pytest.fixture()
144144
def _django_db_helper(
145-
request,
145+
request: pytest.FixtureRequest,
146146
django_db_setup: None,
147147
django_db_blocker,
148148
) -> None:
@@ -518,7 +518,7 @@ def settings():
518518

519519

520520
@pytest.fixture(scope="session")
521-
def live_server(request):
521+
def live_server(request: pytest.FixtureRequest):
522522
"""Run a live Django server in the background during tests
523523
524524
The address the server is started from is taken from the
@@ -549,7 +549,7 @@ def live_server(request):
549549

550550

551551
@pytest.fixture(autouse=True, scope="function")
552-
def _live_server_helper(request) -> None:
552+
def _live_server_helper(request: pytest.FixtureRequest) -> None:
553553
"""Helper to make live_server work, internal to pytest-django.
554554
555555
This helper will dynamically request the transactional_db fixture

pytest_django/plugin.py

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464

6565

6666
@pytest.hookimpl()
67-
def pytest_addoption(parser) -> None:
67+
def pytest_addoption(parser: pytest.Parser) -> None:
6868
group = parser.getgroup("django")
6969
group.addoption(
7070
"--reuse-db",
@@ -259,8 +259,8 @@ def _get_boolean_value(
259259

260260
@pytest.hookimpl()
261261
def pytest_load_initial_conftests(
262-
early_config,
263-
parser,
262+
early_config: pytest.Config,
263+
parser: pytest.Parser,
264264
args: List[str],
265265
) -> None:
266266
# Register the marks
@@ -411,7 +411,7 @@ def get_order_number(test: pytest.Item) -> int:
411411

412412

413413
@pytest.fixture(autouse=True, scope="session")
414-
def django_test_environment(request) -> None:
414+
def django_test_environment(request: pytest.FixtureRequest) -> None:
415415
"""
416416
Ensure that Django is loaded and has its testing environment setup.
417417
@@ -459,7 +459,7 @@ def django_db_blocker() -> "Optional[_DatabaseBlocker]":
459459

460460

461461
@pytest.fixture(autouse=True)
462-
def _django_db_marker(request) -> None:
462+
def _django_db_marker(request: pytest.FixtureRequest) -> None:
463463
"""Implement the django_db marker, internal to pytest-django."""
464464
marker = request.node.get_closest_marker("django_db")
465465
if marker:
@@ -468,7 +468,7 @@ def _django_db_marker(request) -> None:
468468

469469
@pytest.fixture(autouse=True, scope="class")
470470
def _django_setup_unittest(
471-
request,
471+
request: pytest.FixtureRequest,
472472
django_db_blocker: "_DatabaseBlocker",
473473
) -> Generator[None, None, None]:
474474
"""Setup a django unittest, internal to pytest-django."""
@@ -521,7 +521,7 @@ def mailoutbox(
521521

522522
@pytest.fixture(scope="function")
523523
def django_mail_patch_dns(
524-
monkeypatch,
524+
monkeypatch: pytest.MonkeyPatch,
525525
django_mail_dnsname: str,
526526
) -> None:
527527
from django.core import mail
@@ -535,7 +535,7 @@ def django_mail_dnsname() -> str:
535535

536536

537537
@pytest.fixture(autouse=True, scope="function")
538-
def _django_set_urlconf(request) -> None:
538+
def _django_set_urlconf(request: pytest.FixtureRequest) -> None:
539539
"""Apply the @pytest.mark.urls marker, internal to pytest-django."""
540540
marker = request.node.get_closest_marker("urls")
541541
if marker:
@@ -628,30 +628,27 @@ def __mod__(self, var: str) -> str:
628628
else:
629629
return msg
630630

631-
# TODO: use pytest.MonkeyPatch once pytest<6.2 is not supported anymore
632-
NOT_SET = object()
633-
changed = False
634-
previous_value = NOT_SET
635-
if (
636-
os.environ.get(INVALID_TEMPLATE_VARS_ENV, "false") == "true"
637-
and django_settings_is_configured()
638-
):
639-
from django.conf import settings as dj_settings
631+
with pytest.MonkeyPatch.context() as mp:
632+
if (
633+
os.environ.get(INVALID_TEMPLATE_VARS_ENV, "false") == "true"
634+
and django_settings_is_configured()
635+
):
636+
from django.conf import settings as dj_settings
640637

641-
if dj_settings.TEMPLATES:
642-
previous_value = dj_settings.TEMPLATES[0]["OPTIONS"].get("string_if_invalid", NOT_SET)
643-
dj_settings.TEMPLATES[0]["OPTIONS"]["string_if_invalid"] = InvalidVarException()
644-
changed = True
645-
yield
646-
if changed:
647-
if previous_value is NOT_SET:
648-
del dj_settings.TEMPLATES[0]["OPTIONS"]["string_if_invalid"]
649-
else:
650-
dj_settings.TEMPLATES[0]["OPTIONS"]["string_if_invalid"] = previous_value
638+
if dj_settings.TEMPLATES:
639+
mp.setitem(
640+
dj_settings.TEMPLATES[0]["OPTIONS"],
641+
"string_if_invalid",
642+
InvalidVarException(),
643+
)
644+
yield
651645

652646

653647
@pytest.fixture(autouse=True)
654-
def _template_string_if_invalid_marker(monkeypatch, request) -> None:
648+
def _template_string_if_invalid_marker(
649+
monkeypatch: pytest.MonkeyPatch,
650+
request: pytest.FixtureRequest,
651+
) -> None:
655652
"""Apply the @pytest.mark.ignore_template_errors marker,
656653
internal to pytest-django."""
657654
marker = request.keywords.get("ignore_template_errors", None)

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ project_urls =
3535
packages = pytest_django
3636
python_requires = >=3.8
3737
setup_requires = setuptools_scm>=5.0.0
38-
install_requires = pytest>=5.4.0
38+
install_requires = pytest>=7.0.0
3939
zip_safe = no
4040

4141
[options.entry_points]

tests/__init__.py

Whitespace-only changes.

tests/conftest.py

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
import copy
22
import pathlib
33
import shutil
4+
from pathlib import Path
45
from textwrap import dedent
5-
from typing import Optional
6+
from typing import Optional, cast
67

78
import pytest
89
from django.conf import settings
910

11+
from .helpers import DjangoPytester
12+
1013

1114
pytest_plugins = "pytester"
1215

1316
REPOSITORY_ROOT = pathlib.Path(__file__).parent
1417

1518

16-
def pytest_configure(config) -> None:
19+
def pytest_configure(config: pytest.Config) -> None:
1720
config.addinivalue_line(
18-
"markers", "django_project: options for the django_testdir fixture"
21+
"markers", "django_project: options for the django_pytester fixture"
1922
)
2023

2124

@@ -32,13 +35,17 @@ def _marker_apifun(
3235

3336

3437
@pytest.fixture
35-
def testdir(testdir, monkeypatch):
38+
def pytester(pytester: pytest.Pytester, monkeypatch: pytest.MonkeyPatch) -> pytest.Pytester:
3639
monkeypatch.delenv("PYTEST_ADDOPTS", raising=False)
37-
return testdir
40+
return pytester
3841

3942

4043
@pytest.fixture(scope="function")
41-
def django_testdir(request, testdir, monkeypatch):
44+
def django_pytester(
45+
request: pytest.FixtureRequest,
46+
pytester: pytest.Pytester,
47+
monkeypatch: pytest.MonkeyPatch,
48+
) -> DjangoPytester:
4249
from pytest_django_test.db_helpers import (
4350
DB_NAME, SECOND_DB_NAME, SECOND_TEST_DB_NAME, TEST_DB_NAME,
4451
)
@@ -106,56 +113,60 @@ def django_testdir(request, testdir, monkeypatch):
106113
)
107114

108115
if options["project_root"]:
109-
project_root = testdir.mkdir(options["project_root"])
116+
project_root = pytester.mkdir(options["project_root"])
110117
else:
111-
project_root = testdir.tmpdir
118+
project_root = pytester.path
112119

113-
tpkg_path = project_root.mkdir("tpkg")
120+
tpkg_path = project_root / "tpkg"
121+
tpkg_path.mkdir()
114122

115123
if options["create_manage_py"]:
116-
project_root.ensure("manage.py")
124+
project_root.joinpath("manage.py").touch()
117125

118-
tpkg_path.ensure("__init__.py")
126+
tpkg_path.joinpath("__init__.py").touch()
119127

120128
app_source = REPOSITORY_ROOT / "../pytest_django_test/app"
121-
test_app_path = tpkg_path.join("app")
129+
test_app_path = tpkg_path / "app"
122130

123131
# Copy the test app to make it available in the new test run
124132
shutil.copytree(str(app_source), str(test_app_path))
125-
tpkg_path.join("the_settings.py").write(test_settings)
133+
tpkg_path.joinpath("the_settings.py").write_text(test_settings)
126134

127135
monkeypatch.setenv("DJANGO_SETTINGS_MODULE", "tpkg.the_settings")
128136

129-
def create_test_module(test_code: str, filename: str = "test_the_test.py"):
130-
r = tpkg_path.join(filename)
131-
r.write(dedent(test_code), ensure=True)
137+
def create_test_module(test_code: str, filename: str = "test_the_test.py") -> Path:
138+
r = tpkg_path.joinpath(filename)
139+
r.parent.mkdir(parents=True, exist_ok=True)
140+
r.write_text(dedent(test_code))
132141
return r
133142

134-
def create_app_file(code: str, filename: str):
135-
r = test_app_path.join(filename)
136-
r.write(dedent(code), ensure=True)
143+
def create_app_file(code: str, filename: str) -> Path:
144+
r = test_app_path.joinpath(filename)
145+
r.parent.mkdir(parents=True, exist_ok=True)
146+
r.write_text(dedent(code))
137147
return r
138148

139-
testdir.create_test_module = create_test_module
140-
testdir.create_app_file = create_app_file
141-
testdir.project_root = project_root
142-
143-
testdir.makeini(
149+
pytester.makeini(
144150
"""
145151
[pytest]
146152
addopts = --strict-markers
147153
console_output_style=classic
148154
"""
149155
)
150156

151-
return testdir
157+
django_pytester_ = cast(DjangoPytester, pytester)
158+
django_pytester_.create_test_module = create_test_module # type: ignore[method-assign]
159+
django_pytester_.create_app_file = create_app_file # type: ignore[method-assign]
160+
django_pytester_.project_root = project_root
161+
162+
return django_pytester_
152163

153164

154165
@pytest.fixture
155-
def django_testdir_initial(django_testdir):
156-
"""A django_testdir fixture which provides initial_data."""
157-
django_testdir.project_root.join("tpkg/app/migrations").remove()
158-
django_testdir.makefile(
166+
def django_pytester_initial(django_pytester: DjangoPytester) -> pytest.Pytester:
167+
"""A django_pytester fixture which provides initial_data."""
168+
shutil.rmtree(django_pytester.project_root.joinpath("tpkg/app/migrations"))
169+
django_pytester.makefile(
159170
".json",
160171
initial_data="""
161172
[{
@@ -165,4 +176,4 @@ def django_testdir_initial(django_testdir):
165176
}]""",
166177
)
167178

168-
return django_testdir
179+
return django_pytester

tests/helpers.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from pathlib import Path
2+
3+
import pytest
4+
5+
6+
class DjangoPytester(pytest.Pytester): # type: ignore[misc]
7+
project_root: Path
8+
9+
def create_test_module( # type: ignore[empty-body]
10+
self,
11+
test_code: str,
12+
filename: str = ...,
13+
) -> Path:
14+
...
15+
16+
def create_app_file(self, code: str, filename: str) -> Path: # type: ignore[empty-body]
17+
...

0 commit comments

Comments
 (0)