Fixed #23670 -- Prevented partial import state during module autodiscovery
Thanks kostko for the report.
This commit is contained in:
parent
c0c1bb9e64
commit
98da408964
|
@ -64,26 +64,26 @@ def autodiscover_modules(*args, **kwargs):
|
||||||
|
|
||||||
register_to = kwargs.get('register_to')
|
register_to = kwargs.get('register_to')
|
||||||
for app_config in apps.get_app_configs():
|
for app_config in apps.get_app_configs():
|
||||||
# Attempt to import the app's module.
|
for module_to_search in args:
|
||||||
try:
|
# Attempt to import the app's module.
|
||||||
if register_to:
|
try:
|
||||||
before_import_registry = copy.copy(register_to._registry)
|
if register_to:
|
||||||
|
before_import_registry = copy.copy(register_to._registry)
|
||||||
|
|
||||||
for module_to_search in args:
|
|
||||||
import_module('%s.%s' % (app_config.name, module_to_search))
|
import_module('%s.%s' % (app_config.name, module_to_search))
|
||||||
except:
|
except:
|
||||||
# Reset the model registry to the state before the last import as
|
# Reset the registry to the state before the last import
|
||||||
# this import will have to reoccur on the next request and this
|
# as this import will have to reoccur on the next request and
|
||||||
# could raise NotRegistered and AlreadyRegistered exceptions
|
# this could raise NotRegistered and AlreadyRegistered
|
||||||
# (see #8245).
|
# exceptions (see #8245).
|
||||||
if register_to:
|
if register_to:
|
||||||
register_to._registry = before_import_registry
|
register_to._registry = before_import_registry
|
||||||
|
|
||||||
# Decide whether to bubble up this error. If the app just
|
# Decide whether to bubble up this error. If the app just
|
||||||
# doesn't have an admin module, we can ignore the error
|
# doesn't have the module in question, we can ignore the error
|
||||||
# attempting to import it, otherwise we want it to bubble up.
|
# attempting to import it, otherwise we want it to bubble up.
|
||||||
if module_has_submodule(app_config.module, module_to_search):
|
if module_has_submodule(app_config.module, module_to_search):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
if sys.version_info[:2] >= (3, 3):
|
if sys.version_info[:2] >= (3, 3):
|
||||||
|
|
|
@ -1 +1,6 @@
|
||||||
|
from . import site
|
||||||
content = 'Another Good Module'
|
content = 'Another Good Module'
|
||||||
|
|
||||||
|
site._registry.update({
|
||||||
|
'lorem': 'ipsum',
|
||||||
|
})
|
||||||
|
|
|
@ -155,6 +155,15 @@ class ModuleImportTestCase(IgnoreDeprecationWarningsMixin, unittest.TestCase):
|
||||||
@modify_settings(INSTALLED_APPS={'append': 'utils_tests.test_module'})
|
@modify_settings(INSTALLED_APPS={'append': 'utils_tests.test_module'})
|
||||||
class AutodiscoverModulesTestCase(SimpleTestCase):
|
class AutodiscoverModulesTestCase(SimpleTestCase):
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
sys.path_importer_cache.clear()
|
||||||
|
|
||||||
|
sys.modules.pop('utils_tests.test_module.another_bad_module', None)
|
||||||
|
sys.modules.pop('utils_tests.test_module.another_good_module', None)
|
||||||
|
sys.modules.pop('utils_tests.test_module.bad_module', None)
|
||||||
|
sys.modules.pop('utils_tests.test_module.good_module', None)
|
||||||
|
sys.modules.pop('utils_tests.test_module', None)
|
||||||
|
|
||||||
def test_autodiscover_modules_found(self):
|
def test_autodiscover_modules_found(self):
|
||||||
autodiscover_modules('good_module')
|
autodiscover_modules('good_module')
|
||||||
|
|
||||||
|
@ -172,12 +181,28 @@ class AutodiscoverModulesTestCase(SimpleTestCase):
|
||||||
def test_autodiscover_modules_several_found(self):
|
def test_autodiscover_modules_several_found(self):
|
||||||
autodiscover_modules('good_module', 'another_good_module')
|
autodiscover_modules('good_module', 'another_good_module')
|
||||||
|
|
||||||
|
def test_autodiscover_modules_several_found_with_registry(self):
|
||||||
|
from .test_module import site
|
||||||
|
autodiscover_modules('good_module', 'another_good_module', register_to=site)
|
||||||
|
self.assertEqual(site._registry, {'lorem': 'ipsum'})
|
||||||
|
|
||||||
def test_validate_registry_keeps_intact(self):
|
def test_validate_registry_keeps_intact(self):
|
||||||
from .test_module import site
|
from .test_module import site
|
||||||
with six.assertRaisesRegex(self, Exception, "Some random exception."):
|
with six.assertRaisesRegex(self, Exception, "Some random exception."):
|
||||||
autodiscover_modules('another_bad_module', register_to=site)
|
autodiscover_modules('another_bad_module', register_to=site)
|
||||||
self.assertEqual(site._registry, {})
|
self.assertEqual(site._registry, {})
|
||||||
|
|
||||||
|
def test_validate_registry_resets_after_erroneous_module(self):
|
||||||
|
from .test_module import site
|
||||||
|
with six.assertRaisesRegex(self, Exception, "Some random exception."):
|
||||||
|
autodiscover_modules('another_good_module', 'another_bad_module', register_to=site)
|
||||||
|
self.assertEqual(site._registry, {'lorem': 'ipsum'})
|
||||||
|
|
||||||
|
def test_validate_registry_resets_after_missing_module(self):
|
||||||
|
from .test_module import site
|
||||||
|
autodiscover_modules('does_not_exist', 'another_good_module', 'does_not_exist2', register_to=site)
|
||||||
|
self.assertEqual(site._registry, {'lorem': 'ipsum'})
|
||||||
|
|
||||||
|
|
||||||
class ProxyFinder(object):
|
class ProxyFinder(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
Loading…
Reference in New Issue