Skip to content

Commit dfb5736

Browse files
committed
Fix --help/--version when a conftest imports Django models
pytest_load_initial_conftests returned early for --help/--version, skipping django.setup(). pytest still imports the initial conftests for these options, so a conftest.py with a top-level Django model import failed with AppRegistryNotReady, surfaced as a "could not load initial conftests" warning (a hard error under filterwarnings = error). Keep setting Django up for --help/--version so those conftests import cleanly. A broken configuration (e.g. an invalid DJANGO_SETTINGS_MODULE) is tolerated only for these options, so they keep working regardless of Django's state, preserving the behavior from #235; a real test run still fails loudly. Fixes #1152. Related to #1275, an earlier fix for the same issue.
1 parent 587b65f commit dfb5736

3 files changed

Lines changed: 60 additions & 5 deletions

File tree

docs/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Bugfixes
88
^^^^^^^^
99

1010
* Fixed type hints of assert methods to match actual signature (`PR #1271 <https://github.com/pytest-dev/pytest-django/pull/1271>`__)
11+
* Fixed ``--help``/``--version`` failing with ``AppRegistryNotReady`` (surfaced as a ``could not load initial conftests`` warning) when a ``conftest.py`` imports Django models at the top level. Django is now set up before the initial conftests are loaded for these options (`#1152 <https://github.com/pytest-dev/pytest-django/issues/1152>`__).
1112

1213
v4.12.0 (2026-02-14)
1314
--------------------

pytest_django/plugin.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,13 @@ def pytest_load_initial_conftests(
307307

308308
options = parser.parse_known_args(args)
309309

310-
if options.version or options.help:
311-
return
310+
# With `--help`/`--version`, pytest still imports the initial conftests
311+
# (it just doesn't run tests). We therefore keep setting Django up below,
312+
# so conftests with top-level model imports don't fail with
313+
# AppRegistryNotReady (issue #1152). A broken configuration is tolerated
314+
# for these options, so they keep working regardless of Django's state
315+
# (issue #235).
316+
is_help_or_version = bool(options.version or options.help)
312317

313318
django_find_project = _get_boolean_value(
314319
early_config.getini("django_find_project"), "django_find_project"
@@ -362,12 +367,22 @@ def _get_option_with_source(
362367
# ImproperlyConfigured if settings cannot be loaded.
363368
from django.conf import settings as dj_settings
364369

365-
with _handle_import_error(_django_project_scan_outcome):
366-
dj_settings.DATABASES # noqa: B018
370+
try:
371+
with _handle_import_error(_django_project_scan_outcome):
372+
dj_settings.DATABASES # noqa: B018
373+
except Exception:
374+
# A broken configuration must not stop `--help`/`--version` (#235).
375+
if not is_help_or_version:
376+
raise
367377

368378
early_config.stash[blocking_manager_key] = DjangoDbBlocker(_ispytest=True)
369379

370-
_setup_django(early_config)
380+
try:
381+
_setup_django(early_config)
382+
except Exception:
383+
# Likewise, `--help`/`--version` must work even if django.setup() fails.
384+
if not is_help_or_version:
385+
raise
371386

372387

373388
@pytest.hookimpl(trylast=True)

tests/test_initialization.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from textwrap import dedent
22

3+
import pytest
4+
35
from .helpers import DjangoPytester
46

57

@@ -60,3 +62,40 @@ def test_ds():
6062
]
6163
)
6264
assert result.ret == 0
65+
66+
67+
@pytest.mark.parametrize("option", ["--help", "--version"])
68+
def test_django_setup_with_help_and_version(
69+
django_pytester: DjangoPytester,
70+
option: str,
71+
) -> None:
72+
"""Django must be set up before conftest files are imported, even for
73+
``--help``/``--version``, so a top-level Django model import in a
74+
``conftest.py`` does not fail with ``AppRegistryNotReady``.
75+
76+
Regression test for https://github.com/pytest-dev/pytest-django/issues/1152
77+
"""
78+
django_pytester.makeconftest(
79+
"""
80+
import sys
81+
82+
from tpkg.app.models import Item # noqa: F401
83+
84+
# Only reached if the model import above succeeds (i.e. Django is set
85+
# up). With --version, pytest records but never prints the conftest
86+
# load failure, so we assert on this positive marker instead.
87+
print("conftest-imported-models", file=sys.stderr)
88+
"""
89+
)
90+
91+
# A single `--version`/`-V` is short-circuited before pytest loads any
92+
# conftests (pytest #13574), so it wouldn't exercise this path; passing
93+
# it twice forces full startup, which imports the initial conftests.
94+
args = [option, option] if option == "--version" else [option]
95+
result = django_pytester.runpytest_subprocess(*args)
96+
97+
output = result.stdout.str() + result.stderr.str()
98+
assert result.ret == 0
99+
assert "conftest-imported-models" in output
100+
assert "AppRegistryNotReady" not in output
101+
assert "could not load initial conftests" not in output

0 commit comments

Comments
 (0)