1
0
mirror of https://github.com/django/django.git synced 2025-03-31 19:46:42 +00:00

Refs #15053 -- Removed support for non-recursive template loading.

Per deprecation timeline.
This commit is contained in:
Tim Graham 2016-12-30 20:09:26 -05:00
parent 56a5760543
commit 5d8da093a9
12 changed files with 40 additions and 422 deletions

View File

@ -130,21 +130,11 @@ class Engine(object):
def find_template(self, name, dirs=None, skip=None): def find_template(self, name, dirs=None, skip=None):
tried = [] tried = []
for loader in self.template_loaders: for loader in self.template_loaders:
if loader.supports_recursion:
try: try:
template = loader.get_template( template = loader.get_template(name, skip=skip)
name, template_dirs=dirs, skip=skip,
)
return template, template.origin return template, template.origin
except TemplateDoesNotExist as e: except TemplateDoesNotExist as e:
tried.extend(e.tried) tried.extend(e.tried)
else:
# RemovedInDjango20Warning: Use old api for non-recursive
# loaders.
try:
return loader(name, dirs)
except TemplateDoesNotExist:
pass
raise TemplateDoesNotExist(name, tried=tried) raise TemplateDoesNotExist(name, tried=tried)
def from_string(self, template_code): def from_string(self, template_code):

View File

@ -19,10 +19,6 @@ BLOCK_CONTEXT_KEY = 'block_context'
logger = logging.getLogger('django.template') logger = logging.getLogger('django.template')
class ExtendsError(Exception):
pass
class BlockContext(object): class BlockContext(object):
def __init__(self): def __init__(self):
# Dictionary of FIFO queues. # Dictionary of FIFO queues.
@ -107,23 +103,6 @@ class ExtendsNode(Node):
passed as the skip argument. This enables extends to work recursively passed as the skip argument. This enables extends to work recursively
without extending the same template twice. without extending the same template twice.
""" """
# RemovedInDjango20Warning: If any non-recursive loaders are installed
# do a direct template lookup. If the same template name appears twice,
# raise an exception to avoid system recursion.
for loader in context.template.engine.template_loaders:
if not loader.supports_recursion:
history = context.render_context.setdefault(
self.context_key, [context.template.origin.template_name],
)
if template_name in history:
raise ExtendsError(
"Cannot extend templates recursively when using "
"non-recursive template loaders",
)
template = context.template.engine.get_template(template_name)
history.append(template_name)
return template
history = context.render_context.setdefault( history = context.render_context.setdefault(
self.context_key, [context.template.origin], self.context_key, [context.template.origin],
) )

View File

@ -1,8 +1,4 @@
import warnings from django.template import Template, TemplateDoesNotExist
from django.template import Origin, Template, TemplateDoesNotExist
from django.utils.deprecation import RemovedInDjango20Warning
from django.utils.inspect import func_supports_parameter
class Loader(object): class Loader(object):
@ -10,11 +6,7 @@ class Loader(object):
def __init__(self, engine): def __init__(self, engine):
self.engine = engine self.engine = engine
def __call__(self, template_name, template_dirs=None): def get_template(self, template_name, skip=None):
# RemovedInDjango20Warning: Allow loaders to be called like functions.
return self.load_template(template_name, template_dirs)
def get_template(self, template_name, template_dirs=None, skip=None):
""" """
Calls self.get_template_sources() and returns a Template object for Calls self.get_template_sources() and returns a Template object for
the first template matching template_name. If skip is provided, the first template matching template_name. If skip is provided,
@ -23,13 +15,7 @@ class Loader(object):
""" """
tried = [] tried = []
args = [template_name] for origin in self.get_template_sources(template_name):
# RemovedInDjango20Warning: Add template_dirs for compatibility with
# old loaders
if func_supports_parameter(self.get_template_sources, 'template_dirs'):
args.append(template_dirs)
for origin in self.get_template_sources(*args):
if skip is not None and origin in skip: if skip is not None and origin in skip:
tried.append((origin, 'Skipped')) tried.append((origin, 'Skipped'))
continue continue
@ -46,30 +32,6 @@ class Loader(object):
raise TemplateDoesNotExist(template_name, tried=tried) raise TemplateDoesNotExist(template_name, tried=tried)
def load_template(self, template_name, template_dirs=None):
warnings.warn(
'The load_template() method is deprecated. Use get_template() '
'instead.', RemovedInDjango20Warning,
)
source, display_name = self.load_template_source(
template_name, template_dirs,
)
origin = Origin(
name=display_name,
template_name=template_name,
loader=self,
)
try:
template = Template(source, origin, template_name, self.engine)
except TemplateDoesNotExist:
# If compiling the template we found raises TemplateDoesNotExist,
# back off to returning the source and display name for the
# template we were asked to load. This allows for correct
# identification of the actual template that does not exist.
return source, display_name
else:
return template, None
def get_template_sources(self, template_name): def get_template_sources(self, template_name):
""" """
An iterator that yields possible matching template paths for a An iterator that yields possible matching template paths for a
@ -79,26 +41,9 @@ class Loader(object):
'subclasses of Loader must provide a get_template_sources() method' 'subclasses of Loader must provide a get_template_sources() method'
) )
def load_template_source(self, template_name, template_dirs=None):
"""
RemovedInDjango20Warning: Returns a tuple containing the source and
origin for the given template name.
"""
raise NotImplementedError(
'subclasses of Loader must provide a load_template_source() method'
)
def reset(self): def reset(self):
""" """
Resets any state maintained by the loader instance (e.g. cached Resets any state maintained by the loader instance (e.g. cached
templates or cached loader modules). templates or cached loader modules).
""" """
pass pass
@property
def supports_recursion(self):
"""
RemovedInDjango20Warning: This is an internal property used by the
ExtendsNode during the deprecation of non-recursive loaders.
"""
return hasattr(self, 'get_contents')

View File

@ -4,13 +4,10 @@ to load templates from them in order, caching the result.
""" """
import hashlib import hashlib
import warnings
from django.template import Origin, Template, TemplateDoesNotExist from django.template import TemplateDoesNotExist
from django.template.backends.django import copy_exception from django.template.backends.django import copy_exception
from django.utils.deprecation import RemovedInDjango20Warning
from django.utils.encoding import force_bytes, force_text from django.utils.encoding import force_bytes, force_text
from django.utils.inspect import func_supports_parameter
from .base import Loader as BaseLoader from .base import Loader as BaseLoader
@ -19,7 +16,6 @@ class Loader(BaseLoader):
def __init__(self, engine, loaders): def __init__(self, engine, loaders):
self.template_cache = {} self.template_cache = {}
self.find_template_cache = {} # RemovedInDjango20Warning
self.get_template_cache = {} self.get_template_cache = {}
self.loaders = engine.get_template_loaders(loaders) self.loaders = engine.get_template_loaders(loaders)
super(Loader, self).__init__(engine) super(Loader, self).__init__(engine)
@ -27,7 +23,7 @@ class Loader(BaseLoader):
def get_contents(self, origin): def get_contents(self, origin):
return origin.loader.get_contents(origin) return origin.loader.get_contents(origin)
def get_template(self, template_name, template_dirs=None, skip=None): def get_template(self, template_name, skip=None):
""" """
Perform the caching that gives this loader its name. Often many of the Perform the caching that gives this loader its name. Often many of the
templates attempted will be missing, so memory use is of concern here. templates attempted will be missing, so memory use is of concern here.
@ -46,7 +42,7 @@ class Loader(BaseLoader):
memory leak. Thus, unraised copies of the exceptions are cached and memory leak. Thus, unraised copies of the exceptions are cached and
copies of those copies are raised after they're fetched from the cache. copies of those copies are raised after they're fetched from the cache.
""" """
key = self.cache_key(template_name, template_dirs, skip) key = self.cache_key(template_name, skip)
cached = self.get_template_cache.get(key) cached = self.get_template_cache.get(key)
if cached: if cached:
if isinstance(cached, type) and issubclass(cached, TemplateDoesNotExist): if isinstance(cached, type) and issubclass(cached, TemplateDoesNotExist):
@ -56,9 +52,7 @@ class Loader(BaseLoader):
return cached return cached
try: try:
template = super(Loader, self).get_template( template = super(Loader, self).get_template(template_name, skip)
template_name, template_dirs, skip,
)
except TemplateDoesNotExist as e: except TemplateDoesNotExist as e:
self.get_template_cache[key] = copy_exception(e) if self.engine.debug else TemplateDoesNotExist self.get_template_cache[key] = copy_exception(e) if self.engine.debug else TemplateDoesNotExist
raise raise
@ -67,17 +61,12 @@ class Loader(BaseLoader):
return template return template
def get_template_sources(self, template_name, template_dirs=None): def get_template_sources(self, template_name):
for loader in self.loaders: for loader in self.loaders:
args = [template_name] for origin in loader.get_template_sources(template_name):
# RemovedInDjango20Warning: Add template_dirs for compatibility
# with old loaders
if func_supports_parameter(loader.get_template_sources, 'template_dirs'):
args.append(template_dirs)
for origin in loader.get_template_sources(*args):
yield origin yield origin
def cache_key(self, template_name, template_dirs, skip=None): def cache_key(self, template_name, skip=None):
""" """
Generate a cache key for the template name, dirs, and skip. Generate a cache key for the template name, dirs, and skip.
@ -97,78 +86,12 @@ class Loader(BaseLoader):
if matching: if matching:
skip_prefix = self.generate_hash(matching) skip_prefix = self.generate_hash(matching)
if template_dirs:
dirs_prefix = self.generate_hash(template_dirs)
return '-'.join(filter(bool, [force_text(template_name), skip_prefix, dirs_prefix])) return '-'.join(filter(bool, [force_text(template_name), skip_prefix, dirs_prefix]))
def generate_hash(self, values): def generate_hash(self, values):
return hashlib.sha1(force_bytes('|'.join(values))).hexdigest() return hashlib.sha1(force_bytes('|'.join(values))).hexdigest()
@property
def supports_recursion(self):
"""
RemovedInDjango20Warning: This is an internal property used by the
ExtendsNode during the deprecation of non-recursive loaders.
"""
return all(hasattr(loader, 'get_contents') for loader in self.loaders)
def find_template(self, name, dirs=None):
"""
RemovedInDjango20Warning: An internal method to lookup the template
name in all the configured loaders.
"""
key = self.cache_key(name, dirs)
try:
result = self.find_template_cache[key]
except KeyError:
result = None
for loader in self.loaders:
try:
template, display_name = loader(name, dirs)
except TemplateDoesNotExist:
pass
else:
origin = Origin(
name=display_name,
template_name=name,
loader=loader,
)
result = template, origin
break
self.find_template_cache[key] = result
if result:
return result
else:
self.template_cache[key] = TemplateDoesNotExist
raise TemplateDoesNotExist(name)
def load_template(self, template_name, template_dirs=None):
warnings.warn(
'The load_template() method is deprecated. Use get_template() '
'instead.', RemovedInDjango20Warning,
)
key = self.cache_key(template_name, template_dirs)
template_tuple = self.template_cache.get(key)
# A cached previous failure:
if template_tuple is TemplateDoesNotExist:
raise TemplateDoesNotExist(template_name)
elif template_tuple is None:
template, origin = self.find_template(template_name, template_dirs)
if not hasattr(template, 'render'):
try:
template = Template(template, origin, template_name, self.engine)
except TemplateDoesNotExist:
# If compiling the template we found raises TemplateDoesNotExist,
# back off to returning the source and display name for the template
# we were asked to load. This allows for correct identification (later)
# of the actual template that does not exist.
self.template_cache[key] = (template, origin)
self.template_cache[key] = (template, None)
return self.template_cache[key]
def reset(self): def reset(self):
"Empty the template cache." "Empty the template cache."
self.template_cache.clear() self.template_cache.clear()
self.find_template_cache.clear() # RemovedInDjango20Warning
self.get_template_cache.clear() self.get_template_cache.clear()

View File

@ -54,21 +54,3 @@ class Loader(BaseLoader):
template_name=template_name, template_name=template_name,
loader=self, loader=self,
) )
def load_template_source(self, template_name, template_dirs=None):
"""
Loads templates from Python eggs via pkg_resource.resource_string.
For every installed app, it tries to get the resource (app, template_name).
"""
warnings.warn(
'The load_template_sources() method is deprecated. Use '
'get_template() or get_contents() instead.',
RemovedInDjango20Warning,
)
for origin in self.get_template_sources(template_name):
try:
return self.get_contents(origin), origin.name
except TemplateDoesNotExist:
pass
raise TemplateDoesNotExist(template_name)

View File

@ -4,12 +4,10 @@ Wrapper for loading templates from the filesystem.
import errno import errno
import io import io
import warnings
from django.core.exceptions import SuspiciousFileOperation from django.core.exceptions import SuspiciousFileOperation
from django.template import Origin, TemplateDoesNotExist from django.template import Origin, TemplateDoesNotExist
from django.utils._os import safe_join from django.utils._os import safe_join
from django.utils.deprecation import RemovedInDjango20Warning
from .base import Loader as BaseLoader from .base import Loader as BaseLoader
@ -32,15 +30,13 @@ class Loader(BaseLoader):
raise TemplateDoesNotExist(origin) raise TemplateDoesNotExist(origin)
raise raise
def get_template_sources(self, template_name, template_dirs=None): def get_template_sources(self, template_name):
""" """
Return an Origin object pointing to an absolute path in each directory Return an Origin object pointing to an absolute path in each directory
in template_dirs. For security reasons, if a path doesn't lie inside in template_dirs. For security reasons, if a path doesn't lie inside
one of the template_dirs it is excluded from the result set. one of the template_dirs it is excluded from the result set.
""" """
if not template_dirs: for template_dir in self.get_dirs():
template_dirs = self.get_dirs()
for template_dir in template_dirs:
try: try:
name = safe_join(template_dir, template_name) name = safe_join(template_dir, template_name)
except SuspiciousFileOperation: except SuspiciousFileOperation:
@ -53,16 +49,3 @@ class Loader(BaseLoader):
template_name=template_name, template_name=template_name,
loader=self, loader=self,
) )
def load_template_source(self, template_name, template_dirs=None):
warnings.warn(
'The load_template_sources() method is deprecated. Use '
'get_template() or get_contents() instead.',
RemovedInDjango20Warning,
)
for origin in self.get_template_sources(template_name, template_dirs):
try:
return self.get_contents(origin), origin.name
except TemplateDoesNotExist:
pass
raise TemplateDoesNotExist(template_name)

View File

@ -2,10 +2,7 @@
Wrapper for loading templates from a plain Python dict. Wrapper for loading templates from a plain Python dict.
""" """
import warnings
from django.template import Origin, TemplateDoesNotExist from django.template import Origin, TemplateDoesNotExist
from django.utils.deprecation import RemovedInDjango20Warning
from .base import Loader as BaseLoader from .base import Loader as BaseLoader
@ -28,14 +25,3 @@ class Loader(BaseLoader):
template_name=template_name, template_name=template_name,
loader=self, loader=self,
) )
def load_template_source(self, template_name, template_dirs=None):
warnings.warn(
'The load_template_sources() method is deprecated. Use '
'get_template() or get_contents() instead.',
RemovedInDjango20Warning,
)
try:
return self.templates_dict[template_name], template_name
except KeyError:
raise TemplateDoesNotExist(template_name)

View File

@ -1057,37 +1057,6 @@ Loader methods
:meth:`get_contents` for custom template loaders. ``get_template()`` :meth:`get_contents` for custom template loaders. ``get_template()``
will usually not need to be overridden. will usually not need to be overridden.
.. method:: load_template_source(template_name, template_dirs=None)
Returns a tuple of (``template_string``, ``template_origin``), where
``template_string`` is a string containing the template contents,
and ``template_origin`` is a string identifying the template source.
A filesystem-based loader may return the full path to the file as the
``template_origin``, for example.
``template_dirs`` is an optional argument used to control which
directories the loader will search.
This method is called automatically by :meth:`load_template` and should
be overridden when writing custom template loaders.
.. deprecated:: 1.9
Custom loaders should use :meth:`get_template` and
:meth:`get_contents` instead.
.. method:: load_template(template_name, template_dirs=None)
Returns a tuple of (``template``, ``template_origin``), where ``template``
is a ``Template`` object and ``template_origin`` is a string identifying
the template source. A filesystem-based loader may return the full
path to the file as the ``template_origin``, for example.
.. deprecated:: 1.9
Custom loaders should use :meth:`get_template` and
:meth:`get_contents` instead.
.. admonition:: Building your own .. admonition:: Building your own
For examples, `read the source code for Django's built-in loaders`_. For examples, `read the source code for Django's built-in loaders`_.

View File

@ -265,3 +265,23 @@ these features.
* The ``GeoManager`` and ``GeoQuerySet`` classes are removed. * The ``GeoManager`` and ``GeoQuerySet`` classes are removed.
* The ``django.contrib.gis.geoip`` module is removed. * The ``django.contrib.gis.geoip`` module is removed.
* The ``supports_recursion`` check for template loaders is removed from:
* ``django.template.engine.Engine.find_template()``
* ``django.template.loader_tags.ExtendsNode.find_template()``
* ``django.template.loaders.base.Loader.supports_recursion()``
* ``django.template.loaders.cached.Loader.supports_recursion()``
* The ``load_template`` and ``load_template_sources`` template loader methods
are removed.
* The ``template_dirs`` argument for template loaders is removed:
* ``django.template.loaders.base.Loader.get_template()``
* ``django.template.loaders.cached.Loader.cache_key()``
* ``django.template.loaders.cached.Loader.get_template()``
* ``django.template.loaders.cached.Loader.get_template_sources()``
* ``django.template.loaders.filesystem.Loader.get_template_sources()``
* ``django.template.loaders.base.Loader.__call__()`` is removed.

View File

@ -248,9 +248,6 @@ class IncludeTests(SimpleTestCase):
self.assertEqual(e.exception.args[0], 'missing.html') self.assertEqual(e.exception.args[0], 'missing.html')
def test_extends_include_missing_cachedloader(self): def test_extends_include_missing_cachedloader(self):
"""
Test the cache loader separately since it overrides load_template.
"""
engine = Engine(debug=True, loaders=[ engine = Engine(debug=True, loaders=[
('django.template.loaders.cached.Loader', [ ('django.template.loaders.cached.Loader', [
'django.template.loaders.app_directories.Loader', 'django.template.loaders.app_directories.Loader',

View File

@ -1,10 +1,7 @@
import os import os
from django.template import Context, Engine, TemplateDoesNotExist from django.template import Context, Engine, TemplateDoesNotExist
from django.template.loader_tags import ExtendsError from django.test import SimpleTestCase
from django.template.loaders.base import Loader
from django.test import SimpleTestCase, ignore_warnings
from django.utils.deprecation import RemovedInDjango20Warning
from .utils import ROOT from .utils import ROOT
@ -120,64 +117,3 @@ class ExtendsBehaviorTests(SimpleTestCase):
template = engine.get_template('base.html') template = engine.get_template('base.html')
output = template.render(Context({})) output = template.render(Context({}))
self.assertEqual(output.strip(), 'loader2 loader1') self.assertEqual(output.strip(), 'loader2 loader1')
class NonRecursiveLoader(Loader):
def __init__(self, engine, templates_dict):
self.templates_dict = templates_dict
super(NonRecursiveLoader, self).__init__(engine)
def load_template_source(self, template_name, template_dirs=None):
try:
return self.templates_dict[template_name], template_name
except KeyError:
raise TemplateDoesNotExist(template_name)
@ignore_warnings(category=RemovedInDjango20Warning)
class NonRecursiveLoaderExtendsTests(SimpleTestCase):
loaders = [
('template_tests.test_extends.NonRecursiveLoader', {
'base.html': 'base',
'index.html': '{% extends "base.html" %}',
'recursive.html': '{% extends "recursive.html" %}',
'other-recursive.html': '{% extends "recursive.html" %}',
'a.html': '{% extends "b.html" %}',
'b.html': '{% extends "a.html" %}',
}),
]
def test_extend(self):
engine = Engine(loaders=self.loaders)
output = engine.render_to_string('index.html')
self.assertEqual(output, 'base')
def test_extend_cached(self):
engine = Engine(loaders=[
('django.template.loaders.cached.Loader', self.loaders),
])
output = engine.render_to_string('index.html')
self.assertEqual(output, 'base')
cache = engine.template_loaders[0].template_cache
self.assertIn('base.html', cache)
self.assertIn('index.html', cache)
# Render a second time from cache
output = engine.render_to_string('index.html')
self.assertEqual(output, 'base')
def test_extend_error(self):
engine = Engine(loaders=self.loaders)
msg = 'Cannot extend templates recursively when using non-recursive template loaders'
with self.assertRaisesMessage(ExtendsError, msg):
engine.render_to_string('recursive.html')
with self.assertRaisesMessage(ExtendsError, msg):
engine.render_to_string('other-recursive.html')
with self.assertRaisesMessage(ExtendsError, msg):
engine.render_to_string('a.html')

View File

@ -91,62 +91,6 @@ class CachedLoaderTests(SimpleTestCase):
self.assertIsNone(e.__context__, error_msg) self.assertIsNone(e.__context__, error_msg)
self.assertIsNone(e.__cause__, error_msg) self.assertIsNone(e.__cause__, error_msg)
@ignore_warnings(category=RemovedInDjango20Warning)
def test_load_template(self):
loader = self.engine.template_loaders[0]
template, origin = loader.load_template('index.html')
self.assertEqual(template.origin.template_name, 'index.html')
cache = self.engine.template_loaders[0].template_cache
self.assertEqual(cache['index.html'][0], template)
# Run a second time from cache
loader = self.engine.template_loaders[0]
source, name = loader.load_template('index.html')
self.assertEqual(template.origin.template_name, 'index.html')
@ignore_warnings(category=RemovedInDjango20Warning)
def test_load_template_missing(self):
"""
#19949 -- TemplateDoesNotExist exceptions should be cached.
"""
loader = self.engine.template_loaders[0]
self.assertNotIn('missing.html', loader.template_cache)
with self.assertRaises(TemplateDoesNotExist):
loader.load_template("missing.html")
self.assertEqual(
loader.template_cache["missing.html"],
TemplateDoesNotExist,
"Cached loader failed to cache the TemplateDoesNotExist exception",
)
@ignore_warnings(category=RemovedInDjango20Warning)
def test_load_nonexistent_cached_template(self):
loader = self.engine.template_loaders[0]
template_name = 'nonexistent.html'
# fill the template cache
with self.assertRaises(TemplateDoesNotExist):
loader.find_template(template_name)
with self.assertRaisesMessage(TemplateDoesNotExist, template_name):
loader.get_template(template_name)
def test_templatedir_caching(self):
"""
#13573 -- Template directories should be part of the cache key.
"""
# Retrieve a template specifying a template directory to check
t1, name = self.engine.find_template('test.html', (os.path.join(TEMPLATE_DIR, 'first'),))
# Now retrieve the same template name, but from a different directory
t2, name = self.engine.find_template('test.html', (os.path.join(TEMPLATE_DIR, 'second'),))
# The two templates should not have the same content
self.assertNotEqual(t1.render(Context({})), t2.render(Context({})))
def test_template_name_leading_dash_caching(self): def test_template_name_leading_dash_caching(self):
""" """
#26536 -- A leading dash in a template name shouldn't be stripped #26536 -- A leading dash in a template name shouldn't be stripped
@ -239,20 +183,6 @@ class EggLoaderTests(SimpleTestCase):
output = template.render(Context({})) output = template.render(Context({}))
self.assertEqual(output, "y") self.assertEqual(output, "y")
@ignore_warnings(category=RemovedInDjango20Warning)
def test_load_template_source(self):
loader = self.engine.template_loaders[0]
templates = {
os.path.normcase('templates/y.html'): six.StringIO("y"),
}
with self.create_egg('egg', templates):
with override_settings(INSTALLED_APPS=['egg']):
source, name = loader.load_template_source('y.html')
self.assertEqual(source.strip(), 'y')
self.assertEqual(name, 'egg:egg:templates/y.html')
def test_non_existing(self): def test_non_existing(self):
""" """
Template loading fails if the template is not in the egg. Template loading fails if the template is not in the egg.
@ -323,13 +253,6 @@ class FileSystemLoaderTests(SimpleTestCase):
with self.assertRaises(TemplateDoesNotExist): with self.assertRaises(TemplateDoesNotExist):
engine.get_template('index.html') engine.get_template('index.html')
@ignore_warnings(category=RemovedInDjango20Warning)
def test_load_template_source(self):
loader = self.engine.template_loaders[0]
source, name = loader.load_template_source('index.html')
self.assertEqual(source.strip(), 'index')
self.assertEqual(name, os.path.join(TEMPLATE_DIR, 'index.html'))
def test_directory_security(self): def test_directory_security(self):
with self.source_checker(['/dir1', '/dir2']) as check_sources: with self.source_checker(['/dir1', '/dir2']) as check_sources:
check_sources('index.html', ['/dir1/index.html', '/dir2/index.html']) check_sources('index.html', ['/dir1/index.html', '/dir2/index.html'])
@ -353,10 +276,10 @@ class FileSystemLoaderTests(SimpleTestCase):
""" """
Invalid UTF-8 encoding in bytestrings should raise a useful error Invalid UTF-8 encoding in bytestrings should raise a useful error
""" """
engine = Engine() engine = self.engine
loader = engine.template_loaders[0] loader = engine.template_loaders[0]
with self.assertRaises(UnicodeDecodeError): with self.assertRaises(UnicodeDecodeError):
list(loader.get_template_sources(b'\xc3\xc3', ['/dir1'])) list(loader.get_template_sources(b'\xc3\xc3'))
def test_unicode_dir_name(self): def test_unicode_dir_name(self):
with self.source_checker([b'/Stra\xc3\x9fe']) as check_sources: with self.source_checker([b'/Stra\xc3\x9fe']) as check_sources:
@ -410,14 +333,6 @@ class AppDirectoriesLoaderTests(SimpleTestCase):
self.assertEqual(template.origin.template_name, 'index.html') self.assertEqual(template.origin.template_name, 'index.html')
self.assertEqual(template.origin.loader, self.engine.template_loaders[0]) self.assertEqual(template.origin.loader, self.engine.template_loaders[0])
@ignore_warnings(category=RemovedInDjango20Warning)
@override_settings(INSTALLED_APPS=['template_tests'])
def test_load_template_source(self):
loader = self.engine.template_loaders[0]
source, name = loader.load_template_source('index.html')
self.assertEqual(source.strip(), 'index')
self.assertEqual(name, os.path.join(TEMPLATE_DIR, 'index.html'))
@override_settings(INSTALLED_APPS=[]) @override_settings(INSTALLED_APPS=[])
def test_not_installed(self): def test_not_installed(self):
with self.assertRaises(TemplateDoesNotExist): with self.assertRaises(TemplateDoesNotExist):
@ -440,10 +355,3 @@ class LocmemLoaderTests(SimpleTestCase):
self.assertEqual(template.origin.name, 'index.html') self.assertEqual(template.origin.name, 'index.html')
self.assertEqual(template.origin.template_name, 'index.html') self.assertEqual(template.origin.template_name, 'index.html')
self.assertEqual(template.origin.loader, self.engine.template_loaders[0]) self.assertEqual(template.origin.loader, self.engine.template_loaders[0])
@ignore_warnings(category=RemovedInDjango20Warning)
def test_load_template_source(self):
loader = self.engine.template_loaders[0]
source, name = loader.load_template_source('index.html')
self.assertEqual(source.strip(), 'index')
self.assertEqual(name, 'index.html')