summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Jerdonek <chris.jerdonek@gmail.com>2012-03-28 20:42:23 -0700
committerChris Jerdonek <chris.jerdonek@gmail.com>2012-03-28 20:42:23 -0700
commit80dd7698985949c0bb9e7995bfb5389f0328531d (patch)
treedb20c1817e644ebc06c108ffe642075d13310938
parentc756f24366f4365d4ee6a7c39d00423f4f188d8e (diff)
downloadpystache-80dd7698985949c0bb9e7995bfb5389f0328531d.tar.gz
Simplified Renderer class: Renderer now uses new Loader class.
-rw-r--r--pystache/loader.py24
-rw-r--r--pystache/renderer.py67
-rw-r--r--tests/test_loader.py65
-rw-r--r--tests/test_renderer.py73
4 files changed, 88 insertions, 141 deletions
diff --git a/pystache/loader.py b/pystache/loader.py
index 968f1bd..706a2f7 100644
--- a/pystache/loader.py
+++ b/pystache/loader.py
@@ -11,6 +11,7 @@ import os
import sys
from . import defaults
+from .locator import Locator
class Loader(object):
@@ -78,3 +79,26 @@ class Loader(object):
text = f.read()
return self.unicode(text, encoding)
+
+ def load(self, obj, search_dirs):
+ """
+ Find and return the template associated to the given object.
+
+ Arguments:
+
+ obj: a string or object instance. If obj is a string, then obj
+ will be interpreted as the template name. Otherwise, obj will
+ be interpreted as an instance of a user-defined class.
+
+ search_dirs: the list of directories in which to search for
+ templates when loading a template by name.
+
+ """
+ locator = Locator(extension=self.extension)
+
+ if isinstance(obj, basestring):
+ path = locator.find_path_by_name(search_dirs, obj)
+ else:
+ path = locator.find_path_by_object(search_dirs, obj)
+
+ return self.read(path)
diff --git a/pystache/renderer.py b/pystache/renderer.py
index ece6d0e..adbac3e 100644
--- a/pystache/renderer.py
+++ b/pystache/renderer.py
@@ -11,9 +11,7 @@ import sys
from . import defaults
from .context import Context
-# TODO: remove this alias.
-from .loader import Loader as Reader
-from .locator import Locator
+from .loader import Loader
from .renderengine import RenderEngine
@@ -43,7 +41,7 @@ class Renderer(object):
"""
def __init__(self, file_encoding=None, default_encoding=None,
- decode_errors='strict', search_dirs=None, file_extension=None,
+ decode_errors=None, search_dirs=None, file_extension=None,
escape=None, partials=None):
"""
Construct an instance.
@@ -87,9 +85,8 @@ class Renderer(object):
encoding name returned by sys.getdefaultencoding().
decode_errors: the string to pass as the errors argument to the
- built-in function unicode() when converting to unicode any
- strings of type str encountered during the rendering process.
- Defaults to "strict".
+ built-in function unicode() when converting str strings to
+ unicode. Defaults to the package default.
search_dirs: the list of directories in which to search for
templates when loading a template by name. Defaults to the
@@ -101,6 +98,9 @@ class Renderer(object):
Defaults to the package default.
"""
+ if decode_errors is None:
+ decode_errors = defaults.DECODE_ERRORS
+
if default_encoding is None:
default_encoding = sys.getdefaultencoding()
@@ -169,32 +169,23 @@ class Renderer(object):
# the default_encoding and decode_errors attributes.
return unicode(s, self.default_encoding, self.decode_errors)
- def _make_reader(self):
- """
- Create a Reader instance using current attributes.
-
- """
- return Reader(encoding=self.file_encoding, decode_errors=self.decode_errors)
-
- def make_locator(self):
+ def _make_loader(self):
"""
- Create a Locator instance using current attributes.
+ Create a Loader instance using current attributes.
"""
- return Locator(extension=self.file_extension)
+ return Loader(encoding=self.file_encoding, decode_errors=self.decode_errors,
+ extension=self.file_extension)
def _make_load_template(self):
"""
Return a function that loads a template by name.
"""
- reader = self._make_reader()
- locator = self.make_locator()
+ loader = self._make_loader()
def load_template(template_name):
- template_path = locator.find_path_by_name(self.search_dirs, template_name)
-
- return reader.read(template_path)
+ return loader.load(template_name, self.search_dirs)
return load_template
@@ -237,18 +228,6 @@ class Renderer(object):
escape=self._escape_to_unicode)
return engine
- def read(self, path):
- """
- Read and return as a unicode string the file contents at path.
-
- This class uses this method whenever it needs to read a template
- file. This method uses the file_encoding and decode_errors
- attributes.
-
- """
- reader = self._make_reader()
- return reader.read(path)
-
# TODO: add unit tests for this method.
def load_template(self, template_name):
"""
@@ -258,19 +237,6 @@ class Renderer(object):
load_template = self._make_load_template()
return load_template(template_name)
- def get_associated_template(self, obj):
- """
- Find and return the template associated with an object.
-
- The function first searches the directory containing the object's
- class definition.
-
- """
- locator = self.make_locator()
- template_path = locator.find_path_by_object(self.search_dirs, obj)
-
- return self.read(template_path)
-
def _render_string(self, template, *context, **kwargs):
"""
Render the given template string using the given context.
@@ -291,8 +257,10 @@ class Renderer(object):
Render the template associated with the given object.
"""
+ loader = self._make_loader()
+ template = loader.load(obj, self.search_dirs)
+
context = [obj] + list(context)
- template = self.get_associated_template(obj)
return self._render_string(template, *context, **kwargs)
@@ -303,7 +271,8 @@ class Renderer(object):
Read the render() docstring for more information.
"""
- template = self.read(template_path)
+ loader = self._make_loader()
+ template = loader.read(template_path)
return self._render_string(template, *context, **kwargs)
diff --git a/tests/test_loader.py b/tests/test_loader.py
index 5e02058..1836466 100644
--- a/tests/test_loader.py
+++ b/tests/test_loader.py
@@ -10,40 +10,39 @@ import sys
import unittest
from .common import AssertStringMixin
-# TODO: remove this alias.
-from pystache.loader import Loader as Reader
+from pystache.loader import Loader
DATA_DIR = 'tests/data'
-class ReaderTestCase(unittest.TestCase, AssertStringMixin):
+class LoaderTestCase(unittest.TestCase, AssertStringMixin):
def _get_path(self, filename):
return os.path.join(DATA_DIR, filename)
def test_init__decode_errors(self):
# Test the default value.
- reader = Reader()
+ reader = Loader()
self.assertEquals(reader.decode_errors, 'strict')
- reader = Reader(decode_errors='replace')
+ reader = Loader(decode_errors='replace')
self.assertEquals(reader.decode_errors, 'replace')
def test_init__encoding(self):
# Test the default value.
- reader = Reader()
+ reader = Loader()
self.assertEquals(reader.encoding, sys.getdefaultencoding())
- reader = Reader(encoding='foo')
+ reader = Loader(encoding='foo')
self.assertEquals(reader.encoding, 'foo')
def test_init__extension(self):
# Test the default value.
- reader = Reader()
+ reader = Loader()
self.assertEquals(reader.extension, 'mustache')
- reader = Reader(extension='foo')
+ reader = Loader(extension='foo')
self.assertEquals(reader.extension, 'foo')
def test_unicode__basic__input_str(self):
@@ -51,7 +50,7 @@ class ReaderTestCase(unittest.TestCase, AssertStringMixin):
Test unicode(): default arguments with str input.
"""
- reader = Reader()
+ reader = Loader()
actual = reader.unicode("foo")
self.assertString(actual, u"foo")
@@ -61,7 +60,7 @@ class ReaderTestCase(unittest.TestCase, AssertStringMixin):
Test unicode(): default arguments with unicode input.
"""
- reader = Reader()
+ reader = Loader()
actual = reader.unicode(u"foo")
self.assertString(actual, u"foo")
@@ -76,7 +75,7 @@ class ReaderTestCase(unittest.TestCase, AssertStringMixin):
s = UnicodeSubclass(u"foo")
- reader = Reader()
+ reader = Loader()
actual = reader.unicode(s)
self.assertString(actual, u"foo")
@@ -86,7 +85,7 @@ class ReaderTestCase(unittest.TestCase, AssertStringMixin):
Test unicode(): encoding attribute.
"""
- reader = Reader()
+ reader = Loader()
non_ascii = u'é'.encode('utf-8')
@@ -100,65 +99,63 @@ class ReaderTestCase(unittest.TestCase, AssertStringMixin):
Test unicode(): encoding argument.
"""
- reader = Reader()
+ reader = Loader()
non_ascii = u'é'.encode('utf-8')
self.assertRaises(UnicodeDecodeError, reader.unicode, non_ascii)
- self.assertEquals(reader.unicode(non_ascii, encoding='utf-8'), u'é')
+ actual = reader.unicode(non_ascii, encoding='utf-8')
+ self.assertEquals(actual, u'é')
def test_read(self):
"""
Test read().
"""
- reader = Reader()
+ reader = Loader()
path = self._get_path('ascii.mustache')
- self.assertEquals(reader.read(path), 'ascii: abc')
-
- def test_read__returns_unicode(self):
- """
- Test that read() returns unicode strings.
-
- """
- reader = Reader()
- path = self._get_path('ascii.mustache')
- contents = reader.read(path)
- self.assertEqual(type(contents), unicode)
+ actual = reader.read(path)
+ self.assertString(actual, u'ascii: abc')
def test_read__encoding__attribute(self):
"""
Test read(): encoding attribute respected.
"""
- reader = Reader()
+ reader = Loader()
path = self._get_path('non_ascii.mustache')
self.assertRaises(UnicodeDecodeError, reader.read, path)
+
reader.encoding = 'utf-8'
- self.assertEquals(reader.read(path), u'non-ascii: é')
+ actual = reader.read(path)
+ self.assertString(actual, u'non-ascii: é')
def test_read__encoding__argument(self):
"""
Test read(): encoding argument respected.
"""
- reader = Reader()
+ reader = Loader()
path = self._get_path('non_ascii.mustache')
self.assertRaises(UnicodeDecodeError, reader.read, path)
- self.assertEquals(reader.read(path, encoding='utf-8'), u'non-ascii: é')
+
+ actual = reader.read(path, encoding='utf-8')
+ self.assertString(actual, u'non-ascii: é')
def test_get__decode_errors(self):
"""
Test get(): decode_errors attribute.
"""
- reader = Reader()
+ reader = Loader()
path = self._get_path('non_ascii.mustache')
self.assertRaises(UnicodeDecodeError, reader.read, path)
- reader.decode_errors = 'replace'
- self.assertEquals(reader.read(path), u'non-ascii: \ufffd\ufffd')
+
+ reader.decode_errors = 'ignore'
+ actual = reader.read(path)
+ self.assertString(actual, u'non-ascii: ')
diff --git a/tests/test_renderer.py b/tests/test_renderer.py
index 7a9b7cf..5c702d3 100644
--- a/tests/test_renderer.py
+++ b/tests/test_renderer.py
@@ -12,7 +12,7 @@ import unittest
from examples.simple import Simple
from pystache.renderer import Renderer
-from pystache.locator import Locator
+from pystache.loader import Loader
from .common import get_data_path
from .data.views import SayHello
@@ -182,76 +182,33 @@ class RendererTestCase(unittest.TestCase):
# U+FFFD is the official Unicode replacement character.
self.assertEquals(renderer.unicode(s), u'd\ufffd\ufffdf')
- ## Test the read() method.
+ ## Test the _make_loader() method.
- def _read(self, renderer, filename):
- path = get_data_path(filename)
- return renderer.read(path)
-
- def test_read(self):
- renderer = Renderer()
- actual = self._read(renderer, 'ascii.mustache')
- self.assertEquals(actual, 'ascii: abc')
-
- def test_read__returns_unicode(self):
- renderer = Renderer()
- actual = self._read(renderer, 'ascii.mustache')
- self.assertEquals(type(actual), unicode)
-
- def test_read__file_encoding(self):
- filename = 'non_ascii.mustache'
-
- renderer = Renderer()
- renderer.file_encoding = 'ascii'
-
- self.assertRaises(UnicodeDecodeError, self._read, renderer, filename)
- renderer.file_encoding = 'utf-8'
- actual = self._read(renderer, filename)
- self.assertEquals(actual, u'non-ascii: é')
-
- def test_read__decode_errors(self):
- filename = 'non_ascii.mustache'
- renderer = Renderer()
-
- self.assertRaises(UnicodeDecodeError, self._read, renderer, filename)
- renderer.decode_errors = 'ignore'
- actual = self._read(renderer, filename)
- self.assertEquals(actual, 'non-ascii: ')
-
- ## Test the make_locator() method.
-
- def test_make_locator__return_type(self):
+ def test__make_loader__return_type(self):
"""
- Test that make_locator() returns a Locator.
+ Test that _make_loader() returns a Loader.
"""
renderer = Renderer()
- locator = renderer.make_locator()
+ loader = renderer._make_loader()
- self.assertEquals(type(locator), Locator)
+ self.assertEquals(type(loader), Loader)
- def test_make_locator__file_extension(self):
+ def test__make_loader__attributes(self):
"""
- Test that make_locator() respects the file_extension attribute.
+ Test that _make_locator() sets all attributes correctly..
"""
renderer = Renderer()
- renderer.file_extension = 'foo'
-
- locator = renderer.make_locator()
-
- self.assertEquals(locator.template_extension, 'foo')
-
- # This test is a sanity check. Strictly speaking, it shouldn't
- # be necessary based on our tests above.
- def test_make_locator__default(self):
- renderer = Renderer()
- actual = renderer.make_locator()
+ renderer.decode_errors = 'dec'
+ renderer.file_encoding = 'enc'
+ renderer.file_extension = 'ext'
- expected = Locator()
+ loader = renderer._make_loader()
- self.assertEquals(type(actual), type(expected))
- self.assertEquals(actual.template_extension, expected.template_extension)
+ self.assertEquals(loader.decode_errors, 'dec')
+ self.assertEquals(loader.encoding, 'enc')
+ self.assertEquals(loader.extension, 'ext')
## Test the render() method.