Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python / Jython 2.2 support for v0.5.0 #103

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/lambdas.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from pystache.compat import *
from pystache import TemplateSpec

def rot(s, n=13):
Expand Down
52 changes: 52 additions & 0 deletions pystache/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# -*- coding: us-ascii -*-
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
#
# pythonbackports - support newer code on older Python implementations
# Copyright (C) 2011-2012 Chris Clark
"""New stuff is simply exposed in this module (does not mess with builtins)

So for now simply issue:

from pystache.compat import *
"""


try:
basestring
except NameError:
# probably Python 2.2 or earlier
basestring = (str, unicode)

try:
reversed
except NameError:
# reversed was added in Python 2.4
# NOTE this is not an iterator/generator...
def reversed(in_list):
out_list = []
for i in range(1, len(in_list) + 1):
out_list.append(in_list[-1])
return out_list

try:
UnicodeDecodeError
UnicodeEncodeError
except NameError:
# probably Python 2.2 or earlier
UnicodeDecodeError = UnicodeError
UnicodeEncodeError = UnicodeError

try:
sorted
except NameError:
# sorted was added in Python 2.4
def sorted(iterable, cmp=None, key=None, reverse=None):
if cmp:
raise NotImplementedError('cmp not yet implemented')
if key:
raise NotImplementedError('key not yet implemented')
if reverse:
raise NotImplementedError('reverse not yet implemented')
out_list = list(iterable)[:]
out_list.sort()
return out_list
5 changes: 4 additions & 1 deletion pystache/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

"""

from pystache.compat import *


class NotFound(object): pass
# We use this private global variable as a return value to represent a key
# not being found on lookup. This lets us distinguish between the case
Expand Down Expand Up @@ -102,7 +105,6 @@ def __repr__(self):
"""
return "%s%s" % (self.__class__.__name__, tuple(self._stack))

@staticmethod
def create(*context, **kwargs):
"""
Build a Context instance from a sequence of context-like items.
Expand Down Expand Up @@ -157,6 +159,7 @@ def create(*context, **kwargs):
context.push(kwargs)

return context
create = staticmethod(create)

def get(self, key, default=None):
"""
Expand Down
7 changes: 7 additions & 0 deletions pystache/locator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@

"""

from pystache.compat import *
import os
import re
import sys

from pystache import defaults


try:
os.path.extsep
except AttributeError:
# monkey patch and guess, probably Python 2.2
os.path.extsep = '.'

class Locator(object):

def __init__(self, extension=None):
Expand Down
4 changes: 2 additions & 2 deletions pystache/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ def parse(self, template, index=0, section_key=None):

# Normalize the matches dictionary.
if matches['change'] is not None:
matches.update(tag='=', tag_key=matches['delims'])
matches.update({'tag': '=', 'tag_key': matches['delims']})
elif matches['raw'] is not None:
matches.update(tag='&', tag_key=matches['raw_name'])
matches.update({'tag': '&', 'tag_key': matches['raw_name']})

tag_type = matches['tag']
tag_key = matches['tag_key']
Expand Down
1 change: 1 addition & 0 deletions pystache/renderengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

"""

from pystache.compat import *
import re

from parser import Parser
Expand Down
3 changes: 2 additions & 1 deletion pystache/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

"""

from pystache.compat import *
from pystache import defaults
from pystache.context import Context
from pystache.loader import Loader
Expand Down Expand Up @@ -125,13 +126,13 @@ def __init__(self, file_encoding=None, string_encoding=None,
# but instead letting the caller pass the initial context to the
# main render() method by reference. This approach would probably
# be less likely to be misused.
@property
def context(self):
"""
Return the current rendering context [experimental].

"""
return self._context
context = property(context)

def _to_unicode_soft(self, s):
"""
Expand Down
3 changes: 2 additions & 1 deletion tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,6 @@ class AssertIsMixin:

# unittest.assertIs() is not available until Python 2.7:
# http://docs.python.org/library/unittest.html#unittest.TestCase.assertIsNone
# assertTrue not available until 2.4?
def assertIs(self, first, second):
self.assertTrue(first is second, msg="%s is not %s" % (repr(first), repr(second)))
self.assert_(first is second, msg="%s is not %s" % (repr(first), repr(second)))
3 changes: 3 additions & 0 deletions tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@ def testMainSimple(self):

def tearDown(self):
sys.stdout = ORIGINAL_STDOUT

if __name__ == '__main__':
unittest.main()
7 changes: 5 additions & 2 deletions tests/test_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def foo_callable(self):

item = {"foo": foo_callable}
self.assertNotEquals(_get_value(item, "foo"), "bar")
self.assertTrue(_get_value(item, "foo") is foo_callable)
self.assert_(_get_value(item, "foo") is foo_callable)

def test_dictionary__key_missing(self):
"""
Expand Down Expand Up @@ -323,7 +323,7 @@ def test_get__key_missing(self):

"""
context = Context()
self.assertTrue(context.get("foo") is None)
self.assert_(context.get("foo") is None)

def test_get__default(self):
"""
Expand Down Expand Up @@ -398,3 +398,6 @@ def test_copy(self):
# Confirm the original is unchanged.
self.assertEquals(original.get(key), "buzz")


if __name__ == '__main__':
unittest.main()
4 changes: 4 additions & 0 deletions tests/test_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

"""

from pystache.compat import *
import os
import sys
import unittest
Expand Down Expand Up @@ -196,3 +197,6 @@ def test_reader__to_unicode__attribute(self):
#actual = reader.read(path)
#self.assertString(actual, u'non-ascii: ')


if __name__ == '__main__':
unittest.main()
11 changes: 7 additions & 4 deletions tests/test_locator.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def test_init__extension(self):
self.assertEquals(locator.template_extension, 'txt')

locator = Locator(extension=False)
self.assertTrue(locator.template_extension is False)
self.assert_(locator.template_extension is False)

def test_get_object_directory(self):
locator = Locator()
Expand Down Expand Up @@ -79,7 +79,7 @@ def test_find_name__using_list_of_paths(self):
locator = Locator()
path = locator.find_name(search_dirs=['doesnt_exist', 'examples'], template_name='simple')

self.assertTrue(path)
self.assert_(path)

def test_find_name__precedence(self):
"""
Expand All @@ -91,8 +91,8 @@ def test_find_name__precedence(self):
dir1 = DATA_DIR
dir2 = os.path.join(DATA_DIR, 'locator')

self.assertTrue(locator.find_name(search_dirs=[dir1], template_name='duplicate'))
self.assertTrue(locator.find_name(search_dirs=[dir2], template_name='duplicate'))
self.assert_(locator.find_name(search_dirs=[dir1], template_name='duplicate'))
self.assert_(locator.find_name(search_dirs=[dir2], template_name='duplicate'))

path = locator.find_name(search_dirs=[dir2, dir1], template_name='duplicate')
dirpath = os.path.dirname(path)
Expand Down Expand Up @@ -148,3 +148,6 @@ class FooBar(object):
foo = FooBar()

self.assertEquals(locator.make_template_name(foo), 'foo_bar')

if __name__ == '__main__':
unittest.main()
3 changes: 3 additions & 0 deletions tests/test_pystache.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,6 @@ def test_later_list_section_with_escapable_character(self):
template = """{{#s1}}foo{{/s1}} {{#s2}}<{{/s2}}"""
context = {'s1': True, 's2': [True]}
self._assert_rendered("foo <", template, context)

if __name__ == '__main__':
unittest.main()
7 changes: 5 additions & 2 deletions tests/test_renderengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,11 @@ def test_section__lambda(self):
def test_section__iterable(self):
"""
Check that objects supporting iteration (aside from dicts) behave like lists.

"""

template = '{{#iterable}}{{.}}{{/iterable}}'

context = {'iterable': (i for i in range(3))} # type 'generator'
context = {'iterable': xrange(3)} # type 'generator'
self._assert_render(u'012', template, context)

context = {'iterable': xrange(4)} # type 'xrange'
Expand Down Expand Up @@ -453,3 +453,6 @@ def test_custom_delimiters__not_retroactive(self):
expected = u' {{foo}} '
self._assert_render(expected, '{{=$ $=}} {{foo}} ')
self._assert_render(expected, '{{=$ $=}} {{foo}} $={{ }}=$') # was yielding u' '.

if __name__ == '__main__':
unittest.main()
10 changes: 7 additions & 3 deletions tests/test_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

"""

from pystache.compat import *
import codecs
import os
import sys
Expand Down Expand Up @@ -33,7 +34,7 @@ def test_partials__default(self):

"""
renderer = Renderer()
self.assertTrue(renderer.partials is None)
self.assert_(renderer.partials is None)

def test_partials(self):
"""
Expand Down Expand Up @@ -482,7 +483,7 @@ class MyUnicode(unicode):
s = MyUnicode("abc")

self.assertEquals(type(s), MyUnicode)
self.assertTrue(isinstance(s, unicode))
self.assert_(isinstance(s, unicode))
self.assertEquals(type(literal(s)), unicode)

## Test the engine's escape attribute.
Expand Down Expand Up @@ -551,6 +552,9 @@ class MyUnicode(unicode):
s = MyUnicode("abc")

self.assertEquals(type(s), MyUnicode)
self.assertTrue(isinstance(s, unicode))
self.assert_(isinstance(s, unicode))
self.assertEquals(type(escape(s)), unicode)


if __name__ == '__main__':
unittest.main()
3 changes: 3 additions & 0 deletions tests/test_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,6 @@ def test_template_partial_extension(self):
-------

## Again, Welcome! ##""")

if __name__ == '__main__':
unittest.main()
8 changes: 6 additions & 2 deletions tests/test_template_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

"""

from pystache.compat import *
import os.path
import sys
import unittest
Expand Down Expand Up @@ -337,7 +338,7 @@ def test_find__with_directory(self):

view = SampleView()
view.template_rel_path = 'foo/bar.txt'
self.assertTrue(locator._find_relative(view)[0] is not None)
self.assert_(locator._find_relative(view)[0] is not None)

actual = locator._find(view)
expected = os.path.abspath(os.path.join(DATA_DIR, 'foo/bar.txt'))
Expand All @@ -352,7 +353,7 @@ def test_find__without_directory(self):
locator = self._make_locator()

view = SampleView()
self.assertTrue(locator._find_relative(view)[0] is None)
self.assert_(locator._find_relative(view)[0] is None)

actual = locator._find(view)
expected = os.path.abspath(os.path.join(DATA_DIR, 'sample_view.mustache'))
Expand Down Expand Up @@ -386,3 +387,6 @@ def test_get_template__template_encoding(self):

view.template_encoding = 'utf-8'
self._assert_get_template(view, u"non-ascii: é")

if __name__ == '__main__':
unittest.main()