diff --git a/django/template/loaders/eggs.py b/django/template/loaders/eggs.py deleted file mode 100644 index 3013a8586d..0000000000 --- a/django/template/loaders/eggs.py +++ /dev/null @@ -1,56 +0,0 @@ -# Wrapper for loading templates from eggs via pkg_resources.resource_string. -from __future__ import unicode_literals - -import warnings - -from django.apps import apps -from django.template import Origin, TemplateDoesNotExist -from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning - -from .base import Loader as BaseLoader - -try: - from pkg_resources import resource_string -except ImportError: - resource_string = None - -warnings.warn('The egg template loader is deprecated.', RemovedInDjango20Warning) - - -class EggOrigin(Origin): - - def __init__(self, app_name, pkg_name, *args, **kwargs): - self.app_name = app_name - self.pkg_name = pkg_name - super(EggOrigin, self).__init__(*args, **kwargs) - - -class Loader(BaseLoader): - - def __init__(self, engine): - if resource_string is None: - raise RuntimeError("Setuptools must be installed to use the egg loader") - super(Loader, self).__init__(engine) - - def get_contents(self, origin): - try: - source = resource_string(origin.app_name, origin.pkg_name) - except Exception: - raise TemplateDoesNotExist(origin) - - if six.PY2: - source = source.decode(self.engine.file_charset) - - return source - - def get_template_sources(self, template_name): - pkg_name = 'templates/' + template_name - for app_config in apps.get_app_configs(): - yield EggOrigin( - app_name=app_config.name, - pkg_name=pkg_name, - name="egg:%s:%s" % (app_config.name, pkg_name), - template_name=template_name, - loader=self, - ) diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt index 305945a856..c4ce1b84a5 100644 --- a/docs/ref/templates/api.txt +++ b/docs/ref/templates/api.txt @@ -910,19 +910,6 @@ loaders that come with Django: 'APP_DIRS': True, }] -``django.template.loaders.eggs.Loader`` - -.. class:: eggs.Loader - - .. deprecated:: 1.9 - - Distributing applications as eggs is not recommended. - - Just like ``app_directories`` above, but it loads templates from Python - eggs rather than from the filesystem. - - This loader is disabled by default. - ``django.template.loaders.cached.Loader`` .. class:: cached.Loader diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 42d6c5b540..61ca9f6df1 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -301,3 +301,5 @@ these features. is removed. * ``Field._get_val_from_obj()`` is removed. + +* ``django.template.loaders.eggs.Loader`` is removed. diff --git a/tests/template_tests/test_loaders.py b/tests/template_tests/test_loaders.py index 22fb1d812c..5f50923524 100644 --- a/tests/template_tests/test_loaders.py +++ b/tests/template_tests/test_loaders.py @@ -4,24 +4,17 @@ from __future__ import unicode_literals import os.path import sys import tempfile -import types import unittest from contextlib import contextmanager -from django.template import Context, TemplateDoesNotExist +from django.template import TemplateDoesNotExist from django.template.engine import Engine -from django.test import SimpleTestCase, ignore_warnings, override_settings +from django.test import SimpleTestCase, override_settings from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.functional import lazystr from .utils import TEMPLATE_DIR -try: - import pkg_resources -except ImportError: - pkg_resources = None - class CachedLoaderTests(SimpleTestCase): @@ -106,105 +99,6 @@ class CachedLoaderTests(SimpleTestCase): self.assertEqual(self.engine.template_loaders[0].cache_key(lazystr('template.html'), []), 'template.html') -@unittest.skipUnless(pkg_resources, 'setuptools is not installed') -class EggLoaderTests(SimpleTestCase): - - @contextmanager - def create_egg(self, name, resources): - """ - Creates a mock egg with a list of resources. - - name: The name of the module. - resources: A dictionary of template names mapped to file-like objects. - """ - - if six.PY2: - name = name.encode('utf-8') - - class MockLoader(object): - pass - - class MockProvider(pkg_resources.NullProvider): - def __init__(self, module): - pkg_resources.NullProvider.__init__(self, module) - self.module = module - - def _has(self, path): - return path in self.module._resources - - def _isdir(self, path): - return False - - def get_resource_stream(self, manager, resource_name): - return self.module._resources[resource_name] - - def _get(self, path): - return self.module._resources[path].read() - - def _fn(self, base, resource_name): - return os.path.normcase(resource_name) - - egg = types.ModuleType(name) - egg.__loader__ = MockLoader() - egg.__path__ = ['/some/bogus/path/'] - egg.__file__ = '/some/bogus/path/__init__.pyc' - egg._resources = resources - sys.modules[name] = egg - pkg_resources._provider_factories[MockLoader] = MockProvider - - try: - yield - finally: - del sys.modules[name] - del pkg_resources._provider_factories[MockLoader] - - @classmethod - @ignore_warnings(category=RemovedInDjango20Warning) - def setUpClass(cls): - cls.engine = Engine(loaders=[ - 'django.template.loaders.eggs.Loader', - ]) - cls.loader = cls.engine.template_loaders[0] - super(EggLoaderTests, cls).setUpClass() - - def test_get_template(self): - templates = { - os.path.normcase('templates/y.html'): six.StringIO("y"), - } - - with self.create_egg('egg', templates): - with override_settings(INSTALLED_APPS=['egg']): - template = self.engine.get_template("y.html") - - self.assertEqual(template.origin.name, 'egg:egg:templates/y.html') - self.assertEqual(template.origin.template_name, 'y.html') - self.assertEqual(template.origin.loader, self.engine.template_loaders[0]) - - output = template.render(Context({})) - self.assertEqual(output, "y") - - def test_non_existing(self): - """ - Template loading fails if the template is not in the egg. - """ - with self.create_egg('egg', {}): - with override_settings(INSTALLED_APPS=['egg']): - with self.assertRaises(TemplateDoesNotExist): - self.engine.get_template('not-existing.html') - - def test_not_installed(self): - """ - Template loading fails if the egg is not in INSTALLED_APPS. - """ - templates = { - os.path.normcase('templates/y.html'): six.StringIO("y"), - } - - with self.create_egg('egg', templates): - with self.assertRaises(TemplateDoesNotExist): - self.engine.get_template('y.html') - - class FileSystemLoaderTests(SimpleTestCase): @classmethod