Deprecated load_app().
Adjusted several tests that used it to add apps to the app cache and then attempted to remove them by manipulating attributes directly. Also renamed invalid_models to invalid_models_tests to avoid clashing application labels between the outer and the inner invalid_models applications.
This commit is contained in:
parent
439b364e1e
commit
f25fa9d859
|
@ -133,16 +133,6 @@ class AppCache(object):
|
||||||
|
|
||||||
self._models_loaded = True
|
self._models_loaded = True
|
||||||
|
|
||||||
def load_app(self, app_name):
|
|
||||||
"""
|
|
||||||
Loads the app with the provided fully qualified name, and returns the
|
|
||||||
model module.
|
|
||||||
"""
|
|
||||||
app_config = AppConfig(app_name)
|
|
||||||
app_config.import_models(self.all_models[app_config.label])
|
|
||||||
self.app_configs[app_config.label] = app_config
|
|
||||||
return app_config.models_module
|
|
||||||
|
|
||||||
def app_cache_ready(self):
|
def app_cache_ready(self):
|
||||||
"""
|
"""
|
||||||
Returns true if the model cache is fully populated.
|
Returns true if the model cache is fully populated.
|
||||||
|
@ -377,6 +367,19 @@ class AppCache(object):
|
||||||
|
|
||||||
### DEPRECATED METHODS GO BELOW THIS LINE ###
|
### DEPRECATED METHODS GO BELOW THIS LINE ###
|
||||||
|
|
||||||
|
def load_app(self, app_name):
|
||||||
|
"""
|
||||||
|
Loads the app with the provided fully qualified name, and returns the
|
||||||
|
model module.
|
||||||
|
"""
|
||||||
|
warnings.warn(
|
||||||
|
"load_app(app_name) is deprecated.",
|
||||||
|
PendingDeprecationWarning, stacklevel=2)
|
||||||
|
app_config = AppConfig(app_name)
|
||||||
|
app_config.import_models(self.all_models[app_config.label])
|
||||||
|
self.app_configs[app_config.label] = app_config
|
||||||
|
return app_config.models_module
|
||||||
|
|
||||||
def get_app(self, app_label):
|
def get_app(self, app_label):
|
||||||
"""
|
"""
|
||||||
Returns the module containing the models for the given app_label.
|
Returns the module containing the models for the given app_label.
|
||||||
|
@ -447,7 +450,7 @@ class AppCache(object):
|
||||||
Register a set of models as belonging to an app.
|
Register a set of models as belonging to an app.
|
||||||
"""
|
"""
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"register_models(app_label, models) is deprecated.",
|
"register_models(app_label, *models) is deprecated.",
|
||||||
PendingDeprecationWarning, stacklevel=2)
|
PendingDeprecationWarning, stacklevel=2)
|
||||||
for model in models:
|
for model in models:
|
||||||
self.register_model(app_label, model)
|
self.register_model(app_label, model)
|
||||||
|
|
|
@ -1094,7 +1094,7 @@ class ManageValidate(AdminScriptTestCase):
|
||||||
self.assertOutput(err, 'ImportError')
|
self.assertOutput(err, 'ImportError')
|
||||||
|
|
||||||
def test_complex_app(self):
|
def test_complex_app(self):
|
||||||
"manage.py validate does not raise an ImportError validating a complex app with nested calls to load_app"
|
"manage.py validate does not raise an ImportError validating a complex app"
|
||||||
self.write_settings('settings.py',
|
self.write_settings('settings.py',
|
||||||
apps=['admin_scripts.complex_app', 'admin_scripts.simple_app'],
|
apps=['admin_scripts.complex_app', 'admin_scripts.simple_app'],
|
||||||
sdict={'DEBUG': True})
|
sdict={'DEBUG': True})
|
||||||
|
|
|
@ -8,6 +8,7 @@ from django.core.apps import app_cache
|
||||||
from django.core.apps.cache import AppCache
|
from django.core.apps.cache import AppCache
|
||||||
from django.test.utils import override_settings
|
from django.test.utils import override_settings
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
|
from django.utils import six
|
||||||
|
|
||||||
|
|
||||||
class EggLoadingTest(TestCase):
|
class EggLoadingTest(TestCase):
|
||||||
|
@ -31,45 +32,41 @@ class EggLoadingTest(TestCase):
|
||||||
"""Models module can be loaded from an app in an egg"""
|
"""Models module can be loaded from an app in an egg"""
|
||||||
egg_name = '%s/modelapp.egg' % self.egg_dir
|
egg_name = '%s/modelapp.egg' % self.egg_dir
|
||||||
sys.path.append(egg_name)
|
sys.path.append(egg_name)
|
||||||
models = app_cache.load_app('app_with_models')
|
with app_cache._with_app('app_with_models'):
|
||||||
self.assertFalse(models is None)
|
models_module = app_cache.get_app_config('app_with_models').models_module
|
||||||
|
self.assertIsNotNone(models_module)
|
||||||
|
|
||||||
def test_egg2(self):
|
def test_egg2(self):
|
||||||
"""Loading an app from an egg that has no models returns no models (and no error)"""
|
"""Loading an app from an egg that has no models returns no models (and no error)"""
|
||||||
egg_name = '%s/nomodelapp.egg' % self.egg_dir
|
egg_name = '%s/nomodelapp.egg' % self.egg_dir
|
||||||
sys.path.append(egg_name)
|
sys.path.append(egg_name)
|
||||||
models = app_cache.load_app('app_no_models')
|
with app_cache._with_app('app_no_models'):
|
||||||
self.assertTrue(models is None)
|
models_module = app_cache.get_app_config('app_no_models').models_module
|
||||||
|
self.assertIsNone(models_module)
|
||||||
|
|
||||||
def test_egg3(self):
|
def test_egg3(self):
|
||||||
"""Models module can be loaded from an app located under an egg's top-level package"""
|
"""Models module can be loaded from an app located under an egg's top-level package"""
|
||||||
egg_name = '%s/omelet.egg' % self.egg_dir
|
egg_name = '%s/omelet.egg' % self.egg_dir
|
||||||
sys.path.append(egg_name)
|
sys.path.append(egg_name)
|
||||||
models = app_cache.load_app('omelet.app_with_models')
|
with app_cache._with_app('omelet.app_with_models'):
|
||||||
self.assertFalse(models is None)
|
models_module = app_cache.get_app_config('app_with_models').models_module
|
||||||
|
self.assertIsNotNone(models_module)
|
||||||
|
|
||||||
def test_egg4(self):
|
def test_egg4(self):
|
||||||
"""Loading an app with no models from under the top-level egg package generates no error"""
|
"""Loading an app with no models from under the top-level egg package generates no error"""
|
||||||
egg_name = '%s/omelet.egg' % self.egg_dir
|
egg_name = '%s/omelet.egg' % self.egg_dir
|
||||||
sys.path.append(egg_name)
|
sys.path.append(egg_name)
|
||||||
models = app_cache.load_app('omelet.app_no_models')
|
with app_cache._with_app('omelet.app_no_models'):
|
||||||
self.assertTrue(models is None)
|
models_module = app_cache.get_app_config('app_no_models').models_module
|
||||||
|
self.assertIsNone(models_module)
|
||||||
|
|
||||||
def test_egg5(self):
|
def test_egg5(self):
|
||||||
"""Loading an app from an egg that has an import error in its models module raises that error"""
|
"""Loading an app from an egg that has an import error in its models module raises that error"""
|
||||||
egg_name = '%s/brokenapp.egg' % self.egg_dir
|
egg_name = '%s/brokenapp.egg' % self.egg_dir
|
||||||
sys.path.append(egg_name)
|
sys.path.append(egg_name)
|
||||||
self.assertRaises(ImportError, app_cache.load_app, 'broken_app')
|
with six.assertRaisesRegex(self, ImportError, 'modelz'):
|
||||||
raised = None
|
with app_cache._with_app('broken_app'):
|
||||||
try:
|
app_cache.get_app_config('omelet.app_no_models').models_module
|
||||||
app_cache.load_app('broken_app')
|
|
||||||
except ImportError as e:
|
|
||||||
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):
|
def test_missing_app(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -18,14 +18,7 @@ class InvalidModelTestCase(unittest.TestCase):
|
||||||
self.stdout = StringIO()
|
self.stdout = StringIO()
|
||||||
sys.stdout = self.stdout
|
sys.stdout = self.stdout
|
||||||
|
|
||||||
# The models need to be removed after the test in order to prevent bad
|
|
||||||
# interactions with the flush operation in other tests.
|
|
||||||
self._old_models = app_cache.app_configs['invalid_models'].models.copy()
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
app_cache.app_configs['invalid_models'].models = self._old_models
|
|
||||||
app_cache.all_models['invalid_models'] = self._old_models
|
|
||||||
app_cache._get_models_cache = {}
|
|
||||||
sys.stdout = self.old_stdout
|
sys.stdout = self.old_stdout
|
||||||
|
|
||||||
# Technically, this isn't an override -- TEST_SWAPPED_MODEL must be
|
# Technically, this isn't an override -- TEST_SWAPPED_MODEL must be
|
||||||
|
@ -38,12 +31,10 @@ class InvalidModelTestCase(unittest.TestCase):
|
||||||
TEST_SWAPPED_MODEL_BAD_MODEL='not_an_app.Target',
|
TEST_SWAPPED_MODEL_BAD_MODEL='not_an_app.Target',
|
||||||
)
|
)
|
||||||
def test_invalid_models(self):
|
def test_invalid_models(self):
|
||||||
try:
|
with app_cache._with_app("invalid_models_tests.invalid_models"):
|
||||||
module = app_cache.load_app("invalid_models.invalid_models")
|
module = app_cache.get_app_config("invalid_models").models_module
|
||||||
except Exception:
|
|
||||||
self.fail('Unable to load invalid model module')
|
|
||||||
|
|
||||||
get_validation_errors(self.stdout, module)
|
get_validation_errors(self.stdout, module)
|
||||||
|
|
||||||
self.stdout.seek(0)
|
self.stdout.seek(0)
|
||||||
error_log = self.stdout.read()
|
error_log = self.stdout.read()
|
||||||
actual = error_log.split('\n')
|
actual = error_log.split('\n')
|
|
@ -124,7 +124,7 @@ class WriterTests(TestCase):
|
||||||
|
|
||||||
with override_settings(INSTALLED_APPS=test_apps):
|
with override_settings(INSTALLED_APPS=test_apps):
|
||||||
for app in test_apps:
|
for app in test_apps:
|
||||||
app_cache.load_app(app)
|
with app_cache._with_app(app):
|
||||||
migration = migrations.Migration('0001_initial', app.split('.')[-1])
|
migration = migrations.Migration('0001_initial', app.split('.')[-1])
|
||||||
expected_path = os.path.join(base_dir, *(app.split('.') + ['migrations', '0001_initial.py']))
|
expected_path = os.path.join(base_dir, *(app.split('.') + ['migrations', '0001_initial.py']))
|
||||||
writer = MigrationWriter(migration)
|
writer = MigrationWriter(migration)
|
||||||
|
|
|
@ -3,7 +3,6 @@ from __future__ import unicode_literals
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.core.apps import app_cache
|
from django.core.apps import app_cache
|
||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
from django.test import TestCase, TransactionTestCase
|
from django.test import TestCase, TransactionTestCase
|
||||||
|
@ -21,28 +20,21 @@ class ProxyModelInheritanceTests(TransactionTestCase):
|
||||||
for the proxied model (as described in #12286). This test creates two dummy
|
for the proxied model (as described in #12286). This test creates two dummy
|
||||||
apps and calls migrate, then verifies that the table has been created.
|
apps and calls migrate, then verifies that the table has been created.
|
||||||
"""
|
"""
|
||||||
|
available_apps = ['app1', 'app2']
|
||||||
available_apps = []
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.old_sys_path = sys.path[:]
|
self.old_sys_path = sys.path[:]
|
||||||
sys.path.append(os.path.dirname(os.path.abspath(upath(__file__))))
|
sys.path.append(os.path.dirname(os.path.abspath(upath(__file__))))
|
||||||
for app in settings.INSTALLED_APPS:
|
self._with_app1 = app_cache._begin_with_app('app1')
|
||||||
app_cache.load_app(app)
|
self._with_app2 = app_cache._begin_with_app('app2')
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
app_cache._end_with_app(self._with_app1)
|
||||||
|
app_cache._end_with_app(self._with_app2)
|
||||||
sys.path = self.old_sys_path
|
sys.path = self.old_sys_path
|
||||||
del app_cache.app_configs['app1']
|
|
||||||
del app_cache.app_configs['app2']
|
|
||||||
del app_cache.all_models['app1']
|
|
||||||
del app_cache.all_models['app2']
|
|
||||||
|
|
||||||
def test_table_exists(self):
|
def test_table_exists(self):
|
||||||
try:
|
|
||||||
app_cache.set_available_apps(settings.INSTALLED_APPS)
|
|
||||||
call_command('migrate', verbosity=0)
|
call_command('migrate', verbosity=0)
|
||||||
finally:
|
|
||||||
app_cache.unset_available_apps()
|
|
||||||
from .app1.models import ProxyModel
|
from .app1.models import ProxyModel
|
||||||
from .app2.models import NiceModel
|
from .app2.models import NiceModel
|
||||||
self.assertEqual(NiceModel.objects.all().count(), 0)
|
self.assertEqual(NiceModel.objects.all().count(), 0)
|
||||||
|
@ -56,7 +48,6 @@ class MultiTableInheritanceProxyTest(TestCase):
|
||||||
Deleting an instance of a model proxying a multi-table inherited
|
Deleting an instance of a model proxying a multi-table inherited
|
||||||
subclass should cascade delete down the whole inheritance chain (see
|
subclass should cascade delete down the whole inheritance chain (see
|
||||||
#18083).
|
#18083).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
instance = ConcreteModelSubclassProxy.objects.create()
|
instance = ConcreteModelSubclassProxy.objects.create()
|
||||||
instance.delete()
|
instance.delete()
|
||||||
|
|
|
@ -164,7 +164,8 @@ def setup(verbosity, test_labels):
|
||||||
if module_found_in_labels:
|
if module_found_in_labels:
|
||||||
if verbosity >= 2:
|
if verbosity >= 2:
|
||||||
print("Importing application %s" % module_name)
|
print("Importing application %s" % module_name)
|
||||||
app_cache.load_app(module_label)
|
# HACK.
|
||||||
|
app_cache._begin_with_app(module_label)
|
||||||
if module_label not in settings.INSTALLED_APPS:
|
if module_label not in settings.INSTALLED_APPS:
|
||||||
settings.INSTALLED_APPS.append(module_label)
|
settings.INSTALLED_APPS.append(module_label)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue