diff --git a/pytest_django/plugin.py b/pytest_django/plugin.py index f7811e1e..957223be 100644 --- a/pytest_django/plugin.py +++ b/pytest_django/plugin.py @@ -362,8 +362,15 @@ def _get_option_with_source( @pytest.hookimpl(trylast=True) def pytest_configure(config: pytest.Config) -> None: - # Allow Django settings to be configured in a user pytest_configure call, - # but make sure we call django.setup() + if config.getoption("version", 0) > 0 or config.getoption("help", False): + return + + # Normally Django is set up in `pytest_load_initial_conftests`, but we also + # allow users to not set DJANGO_SETTINGS_MODULE/`--ds` and instead + # configure the Django settings in a `pytest_configure` hookimpl using e.g. + # `settings.configure(...)`. In this case, the `_setup_django` call in + # `pytest_load_initial_conftests` only partially initializes Django, and + # it's fully initialized here. _setup_django(config) diff --git a/tests/test_manage_py_scan.py b/tests/test_manage_py_scan.py index d2504eb4..053c5c2a 100644 --- a/tests/test_manage_py_scan.py +++ b/tests/test_manage_py_scan.py @@ -144,6 +144,37 @@ def test_django_project_found_invalid_settings_version( result.stdout.fnmatch_lines(["*usage:*"]) +@pytest.mark.django_project(project_root="django_project_root", create_manage_py=True) +def test_django_project_late_settings_version( + django_pytester: DjangoPytester, + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Late configuration should not cause an error with --help or --version.""" + monkeypatch.delenv("DJANGO_SETTINGS_MODULE") + django_pytester.makepyfile( + t="WAT = 1", + ) + django_pytester.makeconftest( + """ + import os + + def pytest_configure(): + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 't') + from django.conf import settings + settings.WAT + """ + ) + + result = django_pytester.runpytest_subprocess("django_project_root", "--version", "--version") + assert result.ret == 0 + + result.stdout.fnmatch_lines(["*This is pytest version*"]) + + result = django_pytester.runpytest_subprocess("django_project_root", "--help") + assert result.ret == 0 + result.stdout.fnmatch_lines(["*usage:*"]) + + @pytest.mark.django_project(project_root="django_project_root", create_manage_py=True) def test_runs_without_error_on_long_args(django_pytester: DjangoPytester) -> None: django_pytester.create_test_module(