From 04489c7dbf8f69de84ca272a0a1710e7b6067e9d Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 5 Aug 2013 13:34:35 -0400 Subject: [PATCH] Fixed #17667 -- Prevented app loading from skipping nonexistent apps after the first try Thanks ea2100@ for the report and akaariai for the patch. --- django/db/models/loading.py | 2 +- tests/app_loading/tests.py | 30 ++++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/django/db/models/loading.py b/django/db/models/loading.py index f858f25c1d..6819134ae0 100644 --- a/django/db/models/loading.py +++ b/django/db/models/loading.py @@ -105,9 +105,9 @@ class AppCache(object): Loads the app with the provided fully qualified name, and returns the model module. """ + app_module = import_module(app_name) self.handled.add(app_name) self.nesting_level += 1 - app_module = import_module(app_name) try: models = import_module('%s.%s' % (app_name, MODELS_MODULE_NAME)) except ImportError: diff --git a/tests/app_loading/tests.py b/tests/app_loading/tests.py index bba2b234a2..dc25899646 100644 --- a/tests/app_loading/tests.py +++ b/tests/app_loading/tests.py @@ -7,7 +7,8 @@ import time from unittest import TestCase from django.conf import Settings -from django.db.models.loading import cache, load_app, get_model, get_models +from django.db.models.loading import cache, load_app, get_model, get_models, AppCache +from django.test.utils import override_settings from django.utils._os import upath @@ -61,12 +62,33 @@ class EggLoadingTest(TestCase): egg_name = '%s/brokenapp.egg' % self.egg_dir sys.path.append(egg_name) self.assertRaises(ImportError, load_app, 'broken_app') + raised = None try: load_app('broken_app') except ImportError as e: - # Make sure the message is indicating the actual - # problem in the broken app. - self.assertTrue("modelz" in e.args[0]) + raised = e + + # Make sure the message is indicating the actual + # problem in the broken app. + self.assertTrue(raised is not None) + self.assertTrue("modelz" in raised.args[0]) + + def test_missing_app(self): + """ + Test that repeated app loading doesn't succeed in case there is an + error. Refs #17667. + """ + # AppCache is a Borg, so we can instantiate one and change its + # loaded to False to force the following code to actually try to + # populate the cache. + a = AppCache() + a.loaded = False + try: + with override_settings(INSTALLED_APPS=('notexists',)): + self.assertRaises(ImportError, get_model, 'notexists', 'nomodel', seed_cache=True) + self.assertRaises(ImportError, get_model, 'notexists', 'nomodel', seed_cache=True) + finally: + a.loaded = True class GetModelsTest(TestCase):