diff --git a/django/utils/module_loading.py b/django/utils/module_loading.py index cd0c8bc5cc..a4e255842d 100644 --- a/django/utils/module_loading.py +++ b/django/utils/module_loading.py @@ -4,11 +4,8 @@ import copy from importlib import import_module import os import sys -import warnings -from django.core.exceptions import ImproperlyConfigured from django.utils import six -from django.utils.deprecation import RemovedInDjango19Warning def import_string(dotted_path): @@ -32,24 +29,6 @@ def import_string(dotted_path): six.reraise(ImportError, ImportError(msg), sys.exc_info()[2]) -def import_by_path(dotted_path, error_prefix=''): - """ - Import a dotted module path and return the attribute/class designated by the - last name in the path. Raise ImproperlyConfigured if something goes wrong. - """ - warnings.warn( - 'import_by_path() has been deprecated. Use import_string() instead.', - RemovedInDjango19Warning, stacklevel=2) - try: - attr = import_string(dotted_path) - except ImportError as e: - msg = '%sError importing module %s: "%s"' % ( - error_prefix, dotted_path, e) - six.reraise(ImproperlyConfigured, ImproperlyConfigured(msg), - sys.exc_info()[2]) - return attr - - def autodiscover_modules(*args, **kwargs): """ Auto-discover INSTALLED_APPS modules and fail silently when diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index f3e1520502..c82e55005e 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -755,15 +755,6 @@ Functions for working with Python modules. from django.core.exceptions import ValidationError -.. function:: import_by_path(dotted_path, error_prefix='') - - .. deprecated:: 1.7 - Use :meth:`~django.utils.module_loading.import_string` instead. - - Imports a dotted module path and returns the attribute/class designated by - the last name in the path. Raises :exc:`~django.core.exceptions.ImproperlyConfigured` - if something goes wrong. - ``django.utils.safestring`` =========================== diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index b8fe9b257f..93572ddfd3 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -1481,8 +1481,8 @@ versions prior to 2.7. They have been deprecated. ``django.utils.module_loading.import_by_path`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The current :meth:`~django.utils.module_loading.import_by_path` function -catches ``AttributeError``, ``ImportError`` and ``ValueError`` exceptions, +The current ``django.utils.module_loading.import_by_path`` function +catches ``AttributeError``, ``ImportError``, and ``ValueError`` exceptions, and re-raises :exc:`~django.core.exceptions.ImproperlyConfigured`. Such exception masking makes it needlessly hard to diagnose circular import problems, because it makes it look like the problem comes from inside Django. diff --git a/tests/utils_tests/test_module_loading.py b/tests/utils_tests/test_module_loading.py index 89c9d03b9e..2addc2649a 100644 --- a/tests/utils_tests/test_module_loading.py +++ b/tests/utils_tests/test_module_loading.py @@ -3,15 +3,12 @@ from importlib import import_module import os import sys import unittest -import warnings from zipimport import zipimporter -from django.core.exceptions import ImproperlyConfigured -from django.test import SimpleTestCase, ignore_warnings, modify_settings +from django.test import SimpleTestCase, modify_settings from django.test.utils import extend_sys_path from django.utils import six -from django.utils.deprecation import RemovedInDjango19Warning -from django.utils.module_loading import (autodiscover_modules, import_by_path, import_string, +from django.utils.module_loading import (autodiscover_modules, import_string, module_has_submodule) from django.utils._os import upath @@ -110,39 +107,7 @@ class EggLoader(unittest.TestCase): self.assertRaises(ImportError, import_module, 'egg_module.sub1.sub2.no_such_module') -@ignore_warnings(category=RemovedInDjango19Warning) class ModuleImportTestCase(unittest.TestCase): - def test_import_by_path(self): - cls = import_by_path('django.utils.module_loading.import_by_path') - self.assertEqual(cls, import_by_path) - - # Test exceptions raised - for path in ('no_dots_in_path', 'unexistent.path', 'utils_tests.unexistent'): - self.assertRaises(ImproperlyConfigured, import_by_path, path) - - with self.assertRaises(ImproperlyConfigured) as cm: - import_by_path('unexistent.module.path', error_prefix="Foo") - self.assertTrue(str(cm.exception).startswith('Foo')) - - def test_import_error_traceback(self): - """Test preserving the original traceback on an ImportError.""" - try: - import_by_path('test_module.bad_module.content') - except ImproperlyConfigured: - traceback = sys.exc_info()[2] - - self.assertIsNotNone(traceback.tb_next.tb_next, - 'Should have more than the calling frame in the traceback.') - - def test_import_by_path_pending_deprecation_warning(self): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always', category=RemovedInDjango19Warning) - cls = import_by_path('django.utils.module_loading.import_by_path') - self.assertEqual(cls, import_by_path) - self.assertEqual(len(w), 1) - self.assertTrue(issubclass(w[-1].category, RemovedInDjango19Warning)) - self.assertIn('deprecated', str(w[-1].message)) - def test_import_string(self): cls = import_string('django.utils.module_loading.import_string') self.assertEqual(cls, import_string) @@ -150,7 +115,6 @@ class ModuleImportTestCase(unittest.TestCase): # Test exceptions raised self.assertRaises(ImportError, import_string, 'no_dots_in_path') self.assertRaises(ImportError, import_string, 'utils_tests.unexistent') - self.assertRaises(ImportError, import_string, 'unexistent.path') @modify_settings(INSTALLED_APPS={'append': 'utils_tests.test_module'})