Skip to content

Commit accae0d

Browse files
olasdblueyed
authored andcommitted
Refine the django.conf module check to see if the settings really are configured (#668)
Some modules, e.g. hypothesis, load some Django modules for their own fixtures. This means that the `django.conf` module sometimes gets loaded, even though it's never used (and the settings are not initialized). This causes unrelated test failures when pytest_django is installed, as pytest_django considers that having a loaded django.conf means the settings are set up and ready to be modified. The Django settings object provides a flag to check this condition, which we now use. Add a regression test that mimics what hypothesis did which makes pytest-django fail. Closes #599.
1 parent fd8ff0b commit accae0d

File tree

2 files changed

+47
-10
lines changed

2 files changed

+47
-10
lines changed

pytest_django/lazy_django.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,18 @@ def skip_if_no_django():
1515

1616

1717
def django_settings_is_configured():
18-
# Avoid importing Django if it has not yet been imported
19-
if (
20-
not os.environ.get("DJANGO_SETTINGS_MODULE")
21-
and "django.conf" not in sys.modules
22-
):
23-
return False
24-
25-
# If DJANGO_SETTINGS_MODULE is defined at this point, Django is assumed to
26-
# always be loaded.
27-
return True
18+
"""Return whether the Django settings module has been configured.
19+
20+
This uses either the DJANGO_SETTINGS_MODULE environment variable, or the
21+
configured flag in the Django settings object if django.conf has already
22+
been imported.
23+
"""
24+
ret = bool(os.environ.get("DJANGO_SETTINGS_MODULE"))
25+
26+
if not ret and "django.conf" in sys.modules:
27+
return sys.modules["django.conf"].settings.configured
28+
29+
return ret
2830

2931

3032
def get_django_version():

tests/test_django_settings_module.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,41 @@ def test_cfg(pytestconfig):
406406
assert r.ret == 0
407407

408408

409+
def test_no_ds_but_django_conf_imported(testdir, monkeypatch):
410+
"""pytest-django should not bail out, if "django.conf" has been imported
411+
somewhere, e.g. via hypothesis (#599)."""
412+
413+
monkeypatch.delenv('DJANGO_SETTINGS_MODULE')
414+
415+
testdir.makepyfile("""
416+
import os
417+
import sys
418+
419+
# line copied from hypothesis/extras/django.py
420+
from django.conf import settings as django_settings
421+
422+
# Don't let pytest poke into this object, generating a
423+
# django.core.exceptions.ImproperlyConfigured
424+
del django_settings
425+
426+
from pytest_django.lazy_django import django_settings_is_configured
427+
428+
def test_django_settings_is_configured():
429+
assert django_settings_is_configured() is False
430+
431+
def test_django_conf_is_imported():
432+
assert 'django.conf' in sys.modules
433+
434+
def test_env():
435+
assert 'DJANGO_SETTINGS_MODULE' not in os.environ
436+
437+
def test_cfg(pytestconfig):
438+
assert pytestconfig.option.ds is None
439+
""")
440+
r = testdir.runpytest_subprocess('-s')
441+
assert r.ret == 0
442+
443+
409444
def test_no_django_settings_but_django_imported(testdir, monkeypatch):
410445
"""Make sure we do not crash when Django happens to be imported, but
411446
settings is not properly configured"""

0 commit comments

Comments
 (0)