Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pystache_custom
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
pystache_custom
Commits
80dd7698
Commit
80dd7698
authored
Mar 28, 2012
by
Chris Jerdonek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplified Renderer class: Renderer now uses new Loader class.
parent
c756f243
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
88 additions
and
141 deletions
+88
-141
pystache/loader.py
+24
-0
pystache/renderer.py
+18
-49
tests/test_loader.py
+31
-34
tests/test_renderer.py
+15
-58
No files found.
pystache/loader.py
View file @
80dd7698
...
...
@@ -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
)
pystache/renderer.py
View file @
80dd7698
...
...
@@ -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 Lo
cato
r instance using current attributes.
Create a Lo
ade
r 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
)
...
...
tests/test_loader.py
View file @
80dd7698
...
...
@@ -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
Re
aderTestCase
(
unittest
.
TestCase
,
AssertStringMixin
):
class
Lo
aderTestCase
(
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
=
Re
ader
()
reader
=
Lo
ader
()
self
.
assertEquals
(
reader
.
decode_errors
,
'strict'
)
reader
=
Re
ader
(
decode_errors
=
'replace'
)
reader
=
Lo
ader
(
decode_errors
=
'replace'
)
self
.
assertEquals
(
reader
.
decode_errors
,
'replace'
)
def
test_init__encoding
(
self
):
# Test the default value.
reader
=
Re
ader
()
reader
=
Lo
ader
()
self
.
assertEquals
(
reader
.
encoding
,
sys
.
getdefaultencoding
())
reader
=
Re
ader
(
encoding
=
'foo'
)
reader
=
Lo
ader
(
encoding
=
'foo'
)
self
.
assertEquals
(
reader
.
encoding
,
'foo'
)
def
test_init__extension
(
self
):
# Test the default value.
reader
=
Re
ader
()
reader
=
Lo
ader
()
self
.
assertEquals
(
reader
.
extension
,
'mustache'
)
reader
=
Re
ader
(
extension
=
'foo'
)
reader
=
Lo
ader
(
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
=
Re
ader
()
reader
=
Lo
ader
()
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
=
Re
ader
()
reader
=
Lo
ader
()
actual
=
reader
.
unicode
(
u"foo"
)
self
.
assertString
(
actual
,
u"foo"
)
...
...
@@ -76,7 +75,7 @@ class ReaderTestCase(unittest.TestCase, AssertStringMixin):
s
=
UnicodeSubclass
(
u"foo"
)
reader
=
Re
ader
()
reader
=
Lo
ader
()
actual
=
reader
.
unicode
(
s
)
self
.
assertString
(
actual
,
u"foo"
)
...
...
@@ -86,7 +85,7 @@ class ReaderTestCase(unittest.TestCase, AssertStringMixin):
Test unicode(): encoding attribute.
"""
reader
=
Re
ader
()
reader
=
Lo
ader
()
non_ascii
=
u'é'
.
encode
(
'utf-8'
)
...
...
@@ -100,65 +99,63 @@ class ReaderTestCase(unittest.TestCase, AssertStringMixin):
Test unicode(): encoding argument.
"""
reader
=
Re
ader
()
reader
=
Lo
ader
()
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
=
Re
ader
()
reader
=
Lo
ader
()
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
=
Re
ader
()
reader
=
Lo
ader
()
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
=
Re
ader
()
reader
=
Lo
ader
()
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
=
Re
ader
()
reader
=
Lo
ader
()
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: '
)
tests/test_renderer.py
View file @
80dd7698
...
...
@@ -12,7 +12,7 @@ import unittest
from
examples.simple
import
Simple
from
pystache.renderer
import
Renderer
from
pystache.lo
cator
import
Locato
r
from
pystache.lo
ader
import
Loade
r
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\ufffd
f'
)
## 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 Locato
r.
Test that
_make_loader() returns a Loade
r.
"""
renderer
=
Renderer
()
lo
cator
=
renderer
.
make_locato
r
()
lo
ader
=
renderer
.
_make_loade
r
()
self
.
assertEquals
(
type
(
lo
cator
),
Locato
r
)
self
.
assertEquals
(
type
(
lo
ader
),
Loade
r
)
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
=
Locato
r
()
loader
=
renderer
.
_make_loade
r
()
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.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment