Skip to content

Commit

Permalink
Call django.setup() directly after configuring settings
Browse files Browse the repository at this point in the history
  • Loading branch information
pelme committed Jul 27, 2014
1 parent 7f80222 commit 85581fb
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 36 deletions.
7 changes: 0 additions & 7 deletions pytest_django/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,3 @@


del _runner


try:
from django import setup
except ImportError:
# Emulate Django 1.7 django.setup() with get_models
from django.db.models import get_models as setup
20 changes: 6 additions & 14 deletions pytest_django/lazy_django.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,15 @@ def skip_if_no_django():


def django_settings_is_configured():
if not os.environ.get('DJANGO_SETTINGS_MODULE') \
and not 'django' in sys.modules:
# Avoid importing Django if it has not yet been imported
if not os.environ.get('DJANGO_SETTINGS_MODULE') and 'django' not in sys.modules:
return False

# If DJANGO_SETTINGS_MODULE is defined at this point, Django should always be loaded
from django.conf import settings
if settings.configured:
return True

from django.core.exceptions import ImproperlyConfigured
try:
settings.DATABASES
except (ImproperlyConfigured, ImportError):
e = sys.exc_info()[1]
raise pytest.UsageError(
"pytest_django: failed to load Django settings: %s" % (e.args))

return settings.configured
assert settings.configured is True
return True



def get_django_version():
Expand Down
33 changes: 23 additions & 10 deletions pytest_django/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

################ pytest hooks ################


def pytest_addoption(parser):
group = parser.getgroup('django')
group._addoption('--reuse-db',
Expand All @@ -52,7 +51,7 @@ def pytest_addoption(parser):
'Django settings module to use by pytest-django.')


def _load_settings(config, options):
def _load_settings_from_env(config, options):
# Configure DJANGO_SETTINGS_MODULE
ds = (options.ds or
config.getini(SETTINGS_MODULE_ENV) or
Expand All @@ -73,12 +72,29 @@ def _load_settings(config, options):
import configurations.importer
configurations.importer.install()

# Forcefully load django settings, throws ImportError or ImproperlyConfigured
# if settings cannot be loaded
from django.conf import settings
settings.DATABASES

_setup_django()


def _setup_django():
import django
if hasattr(django, 'setup'):
django.setup()
else:
# Emulate Django 1.7 django.setup() with get_models
from django.db.models import get_models
get_models()

if pytest.__version__[:3] >= "2.4":
def pytest_load_initial_conftests(early_config, parser, args):
_load_settings(early_config, parser.parse_known_args(args))
_load_settings_from_env(early_config, parser.parse_known_args(args))


@pytest.mark.trylast
def pytest_configure(config):
# Register the marks
config.addinivalue_line(
Expand All @@ -95,10 +111,10 @@ def pytest_configure(config):
'"my_app.test_urls".')

if pytest.__version__[:3] < "2.4":
_load_settings(config, config.option)

_load_settings_from_env(config, config.option)

################ Autouse fixtures ################
if django_settings_is_configured():
_setup_django()


@pytest.fixture(autouse=True, scope='session')
Expand All @@ -115,11 +131,8 @@ def _django_test_environment(request):
"""
if django_settings_is_configured():
from django.conf import settings
from .compat import (setup, setup_test_environment,
teardown_test_environment)
from .compat import setup_test_environment, teardown_test_environment
settings.DEBUG = False
setup()

setup_test_environment()
request.addfinalizer(teardown_test_environment)

Expand Down
57 changes: 52 additions & 5 deletions tests/test_django_settings_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
If these tests fail you probably forgot to run "python setup.py develop".
"""

import pytest
import django

BARE_SETTINGS = '''
# At least one database must be configured
DATABASES = {
Expand Down Expand Up @@ -76,11 +79,8 @@ def test_ds_non_existent(testdir, monkeypatch):
monkeypatch.setenv('DJANGO_SETTINGS_MODULE', 'DOES_NOT_EXIST')
testdir.makepyfile('def test_ds(): pass')
result = testdir.runpytest()
# NOTE: the error is on stdout, because it happens during the testrun.
result.stdout.fnmatch_lines(
["*ERROR at setup of test_ds*",
"*UsageError: pytest_django: failed to load Django settings: "
"Could not import settings 'DOES_NOT_EXIST' (Is it on sys.path?*): *"])
result.stderr.fnmatch_lines(
["*ImportError: Could not import settings 'DOES_NOT_EXIST' (Is it on sys.path?*): *"])


def test_ds_after_user_conftest(testdir, monkeypatch):
Expand Down Expand Up @@ -214,5 +214,52 @@ def pytest_configure():
def test_debug_is_false():
assert settings.DEBUG is False
""")

r = testdir.runpytest()
assert r.ret == 0


@pytest.mark.skipif(not hasattr(django, 'setup'),
reason="This Django version does not support app loading")
@pytest.mark.extra_settings("""
INSTALLED_APPS = [
'tpkg.app.apps.TestApp',
]
""")
def test_django_setup(django_testdir):
django_testdir.create_app_file("""
from django.apps import apps, AppConfig
from django.contrib.auth.models import AbstractUser
from django.db import models
class TestApp(AppConfig):
name = 'tpkg.app'
def ready(self):
print ('READY(): populating=%r' % apps._lock.locked())
""", 'apps.py')

django_testdir.create_app_file("""
from django.apps import apps
print ('IMPORT: populating=%r,ready=%r' % (apps._lock.locked(), apps.ready))
SOME_THING = 1234
""", 'models.py')

django_testdir.create_app_file("", '__init__.py')
django_testdir.makepyfile("""
from django.apps import apps
from tpkg.app.models import SOME_THING
def test_anything():
print ('TEST: populating=%r,ready=%r' % (apps._lock.locked(), apps.ready))
""")

result = django_testdir.runpytest('-s', '--tb=line')
result.stdout.fnmatch_lines(['*IMPORT: populating=True,ready=False*'])
result.stdout.fnmatch_lines(['*READY(): populating=True*'])
result.stdout.fnmatch_lines(['*TEST: populating=False,ready=True*'])

0 comments on commit 85581fb

Please sign in to comment.