Commit 14d9932a by Chris Jerdonek

Switched the Loader class to using the new Reader class.

parent 7a4dbe22
......@@ -8,13 +8,15 @@ This module provides a Loader class.
import os
import sys
DEFAULT_DECODE_ERRORS = 'strict'
from .reader import Reader
DEFAULT_EXTENSION = 'mustache'
class Loader(object):
def __init__(self, search_dirs=None, extension=None, encoding=None, decode_errors=None):
def __init__(self, search_dirs=None, extension=None, reader=None):
"""
Construct a template loader.
......@@ -28,21 +30,13 @@ class Loader(object):
extension: the template file extension. Defaults to "mustache".
Pass False for no extension (i.e. extensionless template files).
encoding: the name of the encoding to use when converting file
contents to unicode. This name will be passed as the encoding
argument to the built-in function unicode(). Defaults to the
encoding name returned by sys.getdefaultencoding().
decode_errors: the string to pass as the "errors" argument to the
built-in function unicode() when converting file contents to
unicode. Defaults to "strict".
reader: the Reader instance to use to read file contents and
return them as unicode strings. Defaults to constructing
the default Reader with no constructor arguments.
"""
if decode_errors is None:
decode_errors = DEFAULT_DECODE_ERRORS
if encoding is None:
encoding = sys.getdefaultencoding()
if reader is None:
reader = Reader()
if extension is None:
extension = DEFAULT_EXTENSION
......@@ -53,11 +47,17 @@ class Loader(object):
if isinstance(search_dirs, basestring):
search_dirs = [search_dirs]
self.decode_errors = decode_errors
self.reader = reader
self.search_dirs = search_dirs
self.template_encoding = encoding
self.template_extension = extension
def _read(self, path):
"""
Read and return a template as a unicode string.
"""
return self.reader.read(path)
def make_file_name(self, template_name):
file_name = template_name
if self.template_extension is not False:
......@@ -79,23 +79,8 @@ class Loader(object):
for dir_path in search_dirs:
file_path = os.path.join(dir_path, file_name)
if os.path.exists(file_path):
return self._load_template_file(file_path)
return self._read(file_path)
# TODO: we should probably raise an exception of our own type.
raise IOError('"%s" not found in "%s"' % (template_name, ':'.join(search_dirs),))
def _load_template_file(self, file_path):
"""
Read a template file, and return it as a string.
"""
f = open(file_path, 'r')
try:
template = f.read()
finally:
f.close()
template = unicode(template, self.template_encoding, self.decode_errors)
return template
......@@ -10,6 +10,7 @@ import sys
from .context import Context
from .loader import Loader
from .reader import Reader
from .renderengine import RenderEngine
......@@ -86,7 +87,8 @@ class Renderer(object):
escape = lambda s: cgi.escape(s, quote=True)
if loader is None:
loader = Loader(encoding=default_encoding, decode_errors=decode_errors)
reader = Reader(encoding=default_encoding, decode_errors=decode_errors)
loader = Loader(reader=reader)
self.decode_errors = decode_errors
self.default_encoding = default_encoding
......
......@@ -10,6 +10,7 @@ from types import UnboundMethodType
from .context import Context
from .loader import Loader
from .reader import Reader
from .renderer import Renderer
......@@ -57,7 +58,8 @@ class View(object):
# user did not supply a load_template to the constructor)
# to let users set the template_extension attribute, etc. after
# View.__init__() has already been called.
loader = Loader(search_dirs=self.template_path, encoding=self.template_encoding,
reader = Reader(encoding=self.template_encoding)
loader = Loader(search_dirs=self.template_path, reader=reader,
extension=self.template_extension)
self._loader = loader
......
......@@ -5,6 +5,7 @@ import sys
import unittest
from pystache.loader import Loader
from pystache.reader import Reader
DATA_DIR = 'tests/data'
......@@ -23,22 +24,6 @@ class LoaderTestCase(unittest.TestCase):
loader = Loader(search_dirs=['foo'])
self.assertEquals(loader.search_dirs, ['foo'])
def test_init__decode_errors(self):
# Test the default value.
loader = Loader()
self.assertEquals(loader.decode_errors, 'strict')
loader = Loader(decode_errors='replace')
self.assertEquals(loader.decode_errors, 'replace')
def test_init__encoding(self):
# Test the default value.
loader = Loader()
self.assertEquals(loader.template_encoding, sys.getdefaultencoding())
loader = Loader(encoding='foo')
self.assertEquals(loader.template_encoding, 'foo')
def test_init__extension(self):
# Test the default value.
loader = Loader()
......@@ -50,6 +35,17 @@ class LoaderTestCase(unittest.TestCase):
loader = Loader(extension=False)
self.assertTrue(loader.template_extension is False)
def test_init__reader(self):
# Test the default value.
loader = Loader()
reader = loader.reader
self.assertEquals(reader.encoding, sys.getdefaultencoding())
self.assertEquals(reader.decode_errors, 'strict')
reader = Reader()
loader = Loader(reader=reader)
self.assertTrue(loader.reader is reader)
def test_make_file_name(self):
loader = Loader()
......@@ -103,25 +99,3 @@ class LoaderTestCase(unittest.TestCase):
actual = loader.get('ascii')
self.assertEqual(type(actual), unicode)
def test_get__encoding(self):
"""
Test get(): encoding attribute respected.
"""
loader = self._loader()
self.assertRaises(UnicodeDecodeError, loader.get, 'nonascii')
loader.template_encoding = 'utf-8'
self.assertEquals(loader.get('nonascii'), u'non-ascii: é')
def test_get__decode_errors(self):
"""
Test get(): decode_errors attribute.
"""
loader = self._loader()
self.assertRaises(UnicodeDecodeError, loader.get, 'nonascii')
loader.decode_errors = 'replace'
self.assertEquals(loader.get('nonascii'), u'non-ascii: \ufffd\ufffd')
......@@ -35,39 +35,35 @@ class RendererInitTestCase(unittest.TestCase):
Test that the default loader is constructed correctly.
"""
r = Renderer()
actual = r.loader
renderer = Renderer()
actual = renderer.loader
expected = Loader()
self.assertEquals(type(actual), type(expected))
self.assertEquals(actual.__dict__, expected.__dict__)
self.assertEquals(actual.template_extension, expected.template_extension)
self.assertEquals(actual.search_dirs, expected.search_dirs)
self.assertEquals(actual.reader.__dict__, expected.reader.__dict__)
def test_loader__default__default_encoding(self):
"""
Test that the default loader inherits the default_encoding.
Test that the default loader inherits default_encoding.
"""
r = Renderer(default_encoding='foo')
actual = r.loader
renderer = Renderer(default_encoding='foo')
reader = renderer.loader.reader
expected = Loader(encoding='foo')
self.assertEquals(actual.template_encoding, expected.template_encoding)
# Check all attributes for good measure.
self.assertEquals(actual.__dict__, expected.__dict__)
self.assertEquals(reader.encoding, 'foo')
def test_loader__default__decode_errors(self):
"""
Test that the default loader inherits the decode_errors.
Test that the default loader inherits decode_errors.
"""
r = Renderer(decode_errors='foo')
actual = r.loader
renderer = Renderer(decode_errors='foo')
reader = renderer.loader.reader
expected = Loader(decode_errors='foo')
self.assertEquals(actual.decode_errors, expected.decode_errors)
# Check all attributes for good measure.
self.assertEquals(actual.__dict__, expected.__dict__)
self.assertEquals(reader.decode_errors, 'foo')
def test_escape__default(self):
escape = Renderer().escape
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment