diff --git a/.travis.yml b/.travis.yml index aa2574e..9c429d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,8 @@ matrix: include: - python: 2.7 env: TOXENV=py27 + - python: 3.7 + env: TOXENV=py37 - python: pypy2.7-6.0 env: TOXENV=pypy diff --git a/README.python b/README.python index ad8c64b..666f406 100644 --- a/README.python +++ b/README.python @@ -88,20 +88,20 @@ Python: from template import Template template = Template() - print template.process("someblock") + print(template.process("someblock")) Or just: - print Template().process("someblock") + print(Template().process("someblock")) You can, of course, catch a raised exception to take special action. from template import Template, TemplateException try: - print Template().process("someblock") - except TemplateException, e: - print >>sys.stderr, "Got exception: ", e + print(Template().process("someblock")) + except TemplateException as e: + print("Got exception: ", e, file=sys.stderr) The OUTPUT and OUTPUT_PATH options are honored, but do not otherwise change the behavior of process(). @@ -380,7 +380,7 @@ I have tried to follow a principle of least surprise here. Dict lookup is attempted up to three times, first using the given key, then using the stringified key if possible, then using the key converted to an integer if possible. Therefore the previous template snippet would -print "number", and the other cases are exhibited thusly: +print("number"), and the other cases are exhibited thusly: mydict = { 1: "one", "2": "two" } @@ -473,9 +473,9 @@ Perl version: Python version: [% PYTHON %] - print context.include('myfile'), + print(context.include('myfile')), stash.set('foo', 'bar') - print 'foo value:', stash.get('foo'), + print('foo value:', stash.get('foo')), [% END %] Note that Python's print statement has semantics that may be @@ -540,15 +540,15 @@ syntax error, and should be avoided. An example of a block that will cause a syntax error: [% PYTHON %] - print "line 1" - print "line 2" + print("line 1") + print("line 2") [% END %] Another block that will cause a syntax error: [% PYTHON %] - print "line 1" - print "line 2" + print("line 1") + print("line 2") [% END %] Note that leading whitespace is stripped indiscriminately; tab and @@ -562,9 +562,9 @@ built-in Python function repr(). Example: [% x = 1; y = 2 %] [% PYTHON %] - print "x =", [% x | repr %], "; y =", [% y | repr %] + print("x =", [% x | repr %], "; y =", [% y | repr %]) # Or: - print "x = %s; y = %s" % ([% x | repr %], [% y | repr %]) + print("x = %s; y = %s" % ([% x | repr %], [% y | repr %])) [% END %] Finally, there is a standard filter "python", but it is more limited @@ -586,7 +586,7 @@ as described above. [% FILTER python %] x = f() y = g() - print "hello world" + print("hello world") [% END %] diff --git a/example.py b/example.py index 0b78d93..2121bc6 100644 --- a/example.py +++ b/example.py @@ -10,6 +10,6 @@ t = Template() try: - print t.processString(TEMPLATE_TEXT, { "thing": "world" }) -except TemplateException, e: - print "ERROR: %s" % e + print(t.processString(TEMPLATE_TEXT, { "thing": "world" })) +except TemplateException as e: + print("ERROR: %s" % e) diff --git a/examples/hello_world.py b/examples/hello_world.py index b8eb98d..0272df2 100644 --- a/examples/hello_world.py +++ b/examples/hello_world.py @@ -4,6 +4,6 @@ template = Template() source = Literal("Hello [% name or 'World' %]!") -print template.process(source); -print template.process(source, {'name':'Badger'}); +print(template.process(source)) +print(template.process(source, {'name':'Badger'})) diff --git a/t/args_test.py b/t/args_test.py index 8012f3c..c1c917f 100644 --- a/t/args_test.py +++ b/t/args_test.py @@ -69,3 +69,4 @@ def testArgs(self): """ +main() diff --git a/t/binop_test.py b/t/binop_test.py index e5e1d11..b5695f1 100644 --- a/t/binop_test.py +++ b/t/binop_test.py @@ -314,3 +314,4 @@ def reset(): counter[0] = 0; return counter[0] one is less than two """ +main() diff --git a/t/block_test.py b/t/block_test.py index ca2d822..2c89b1d 100644 --- a/t/block_test.py +++ b/t/block_test.py @@ -103,4 +103,5 @@ def testBlock(self): """ +main() diff --git a/t/blocks_test.py b/t/blocks_test.py index 430af9c..1bfbc40 100644 --- a/t/blocks_test.py +++ b/t/blocks_test.py @@ -69,4 +69,5 @@ def testBlocks(self): this is block two, b is brazen """ +main() diff --git a/t/capture_test.py b/t/capture_test.py index ba487cd..9112308 100644 --- a/t/capture_test.py +++ b/t/capture_test.py @@ -66,3 +66,4 @@ def testCapture(self): """ +main() diff --git a/t/case_test.py b/t/case_test.py index 5af9ffa..4147898 100644 --- a/t/case_test.py +++ b/t/case_test.py @@ -61,3 +61,4 @@ def testCase(self): 1 1 """ +main() diff --git a/t/chomp_test.py b/t/chomp_test.py index cefcd23..cf3bc51 100644 --- a/t/chomp_test.py +++ b/t/chomp_test.py @@ -171,3 +171,4 @@ def testChomp(self): """ +main() diff --git a/t/compile1_test.py b/t/compile1_test.py index 34ed659..aba29b0 100644 --- a/t/compile1_test.py +++ b/t/compile1_test.py @@ -48,3 +48,4 @@ def testCompile(self): """ +main() diff --git a/t/compile2_test.py b/t/compile2_test.py index e8144b9..af4f35e 100644 --- a/t/compile2_test.py +++ b/t/compile2_test.py @@ -61,4 +61,5 @@ def testCompile(self): """ +main() diff --git a/t/compile3_test.py b/t/compile3_test.py index 9fd116a..a73c17d 100644 --- a/t/compile3_test.py +++ b/t/compile3_test.py @@ -23,7 +23,7 @@ def testCompile(self): try: Template(ttcfg).process("evalpython", {}) self.fail("did not raise exception") - except TemplateException, e: + except TemplateException as e: self.assertEquals("python", e.type()) self.assertEquals("EVAL_PYTHON not set", e.info()) @@ -71,4 +71,5 @@ def testCompile(self): """ +main() diff --git a/t/compile4_test.py b/t/compile4_test.py index c7f4fa2..256308e 100644 --- a/t/compile4_test.py +++ b/t/compile4_test.py @@ -54,4 +54,5 @@ def testCompile(self): This is the blam file """ +main() diff --git a/t/compile5_test.py b/t/compile5_test.py index e3493a8..8800792 100644 --- a/t/compile5_test.py +++ b/t/compile5_test.py @@ -2,13 +2,10 @@ import re import shutil -import pytest - from template.test import TestCase, main class CompileTest(TestCase): - @pytest.mark.xfail def testCompile(self): dir = os.path.abspath("test") cdir = os.path.join(dir, "tmp", "cache") @@ -73,3 +70,4 @@ def twiddle(*args): This is the wam-bam file """ +main() diff --git a/t/config_test.py b/t/config_test.py index bd1bd92..4b241d6 100644 --- a/t/config_test.py +++ b/t/config_test.py @@ -10,86 +10,86 @@ def testConfig(self): # Parser: parser = factory.parser({ 'PRE_CHOMP': 1, 'INTERPOLATE': True }) self.assertTrue(parser) - self.assertEquals(1, parser.pre_chomp) - self.assertTrue(parser.interpolate) + self.assertEqual(1, parser.pre_chomp) + self.failUnless(parser.interpolate) parser = factory.parser({ 'POST_CHOMP': 1 }) - self.assertTrue(parser) + self.failUnless(parser) self.assertEquals(1, parser.post_chomp) # Provider: provider = factory.provider({ 'INCLUDE_PATH': 'here:there', 'PARSER': parser }) - self.assertTrue(provider) + self.failUnless(provider) self.assertEquals(['here', 'there'], provider.include_path()) self.assertEquals(1, provider.parser().post_chomp) provider = factory.provider({ 'INCLUDE_PATH': 'cat:mat', 'ANYCASE': True, 'INTERPOLATE': True }) - self.assertTrue(provider) + self.failUnless(provider) self.assertEquals(['cat', 'mat'], provider.include_path()) # Force the provider to instantiate a parser and check it uses the # correct parameters. text = 'The cat sat on the mat' - self.assertTrue(provider.fetch(Literal(text))) - self.assertTrue(provider.parser().anycase) - self.assertTrue(provider.parser().interpolate) + self.failUnless(provider.fetch(Literal(text))) + self.failUnless(provider.parser().anycase) + self.failUnless(provider.parser().interpolate) # Plugins: plugins = factory.plugins({ 'PLUGIN_BASE': ('my.plugins', 'MyPlugins') }) - self.assertTrue(plugins) + self.failUnless(plugins) self.assertEquals([('my.plugins', 'MyPlugins'), 'template.plugin'], plugins.plugin_base()) plugins = factory.plugins({ 'LOAD_PYTHON': True, 'PLUGIN_BASE': ('my.plugins', 'NewPlugins') }) - self.assertTrue(plugins) - self.assertTrue(plugins.load_python()) + self.failUnless(plugins) + self.failUnless(plugins.load_python()) self.assertEquals([('my.plugins', 'NewPlugins'), 'template.plugin'], plugins.plugin_base()) # Filters: filters = factory.filters({ 'TOLERANT': True }) - self.assertTrue(filters) - self.assertTrue(filters.tolerant()) + self.failUnless(filters) + self.failUnless(filters.tolerant()) filters = factory.filters({ 'TOLERANT': True }) - self.assertTrue(filters) - self.assertTrue(filters.tolerant()) + self.failUnless(filters) + self.failUnless(filters.tolerant()) # Stash: stash = factory.stash({ 'foo': 10, 'bar': 20 }) - self.assertTrue(stash) + self.failUnless(stash) self.assertEquals(10, stash.get('foo').value()) self.assertEquals(20, stash.get('bar').value()) stash = factory.stash({ 'foo': 30, 'bar': lambda *_: 'forty' }) - self.assertTrue(stash) + self.failUnless(stash) self.assertEquals(30, stash.get('foo').value()) self.assertEquals('forty', stash.get('bar').value()) # Context: context = factory.context({}) - self.assertTrue(context) + self.failUnless(context) context = factory.context({ 'INCLUDE_PATH': 'anywhere' }) - self.assertTrue(context) + self.failUnless(context) self.assertEquals('anywhere', context.load_templates()[0].include_path()[0]) context = factory.context({ 'LOAD_TEMPLATES': [ provider ], 'LOAD_PLUGINS': [ plugins ], 'LOAD_FILTERS': [ filters ], 'STASH': stash }) - self.assertTrue(context) + self.failUnless(context) self.assertEquals(30, context.stash().get('foo').value()) - self.assertTrue(context.load_templates()[0].parser().interpolate) - self.assertTrue(context.load_plugins()[0].load_python()) - self.assertTrue(context.load_filters()[0].tolerant()) + self.failUnless(context.load_templates()[0].parser().interpolate) + self.failUnless(context.load_plugins()[0].load_python()) + self.failUnless(context.load_filters()[0].tolerant()) # Service: service = factory.service({ 'INCLUDE_PATH': 'amsterdam' }) - self.assertTrue(service) + self.failUnless(service) self.assertEquals(['amsterdam'], service.context().load_templates()[0].include_path()) # Iterator: iterator = factory.iterator(['foo', 'bar', 'baz']) - self.assertTrue(iterator) + self.failUnless(iterator) self.assertEquals('foo', iterator.get_first()) self.assertEquals('bar', iterator.get_next()) self.assertEquals('baz', iterator.get_next()) @@ -98,3 +98,4 @@ def testConfig(self): # (later) +main() diff --git a/t/constants_test.py b/t/constants_test.py index b8db496..62e2a13 100644 --- a/t/constants_test.py +++ b/t/constants_test.py @@ -132,4 +132,5 @@ def counter(): c: abw """ +main() diff --git a/t/context_test.py b/t/context_test.py index 2b48dda..dcf02b7 100644 --- a/t/context_test.py +++ b/t/context_test.py @@ -35,7 +35,7 @@ def testContext(self): error = None try: tmpl = ctx.template('no_such_template') - except Exception, e: + except Exception as e: error = e self.assertTrue(error) self.assertEquals('file error - no_such_template: not found', str(error)) @@ -102,7 +102,7 @@ def __init__(self, text): try: plugin = ctx.plugin('no_such_plugin') self.fail('Exception not raised') - except Exception, e: + except Exception as e: self.assertEquals('plugin error - no_such_plugin: plugin not found', str(e)) @@ -147,3 +147,4 @@ def __init__(self, text): self.assertEquals('charlie', stash.get('a').value()) +main() diff --git a/t/datafile_test.py b/t/datafile_test.py index 286f277..2002a02 100644 --- a/t/datafile_test.py +++ b/t/datafile_test.py @@ -41,3 +41,4 @@ def testDatafile(self): """ +main() diff --git a/t/date_test.py b/t/date_test.py index 7ba43b8..af2bbf2 100644 --- a/t/date_test.py +++ b/t/date_test.py @@ -205,3 +205,4 @@ def testDate(self): """ +main() diff --git a/t/directive_test.py b/t/directive_test.py index 2479a31..16a16de 100644 --- a/t/directive_test.py +++ b/t/directive_test.py @@ -358,3 +358,4 @@ def testDirectives(self): """ +main() diff --git a/t/directory_test.py b/t/directory_test.py index dc1337e..8ee6cdc 100644 --- a/t/directory_test.py +++ b/t/directory_test.py @@ -247,3 +247,4 @@ def testDirectory(self): # """ +main() diff --git a/t/document_test.py b/t/document_test.py index ec20de4..8b789d2 100644 --- a/t/document_test.py +++ b/t/document_test.py @@ -117,3 +117,4 @@ def testDocument(self): two, three """ +main() diff --git a/t/error_test.py b/t/error_test.py index dabea4d..f902e85 100644 --- a/t/error_test.py +++ b/t/error_test.py @@ -8,8 +8,9 @@ def testError(self): try: tmpl.process("badinc") self.fail("Failed to raise exception") - except TemplateException, e: - self.assertEquals('file', e.type()) - self.assertEquals('nosuchfile: not found', e.info()) + except TemplateException as e: + self.assertEqual('file', e.type()) + self.assertEqual('nosuchfile: not found', e.info()) +main() diff --git a/t/evalpython_test.py b/t/evalpython_test.py index 88b2bf7..fbd3064 100644 --- a/t/evalpython_test.py +++ b/t/evalpython_test.py @@ -28,7 +28,7 @@ def testEvalPython(self): output = "author: [% template.author %]\n" stash.set('a', 'The cat sat on the mat') output += "more python generated output\n" - print output, + print(output), [% END %] [% CATCH %] Not allowed: [% error +%] @@ -101,7 +101,7 @@ def testEvalPython(self): output = "author: [% template.author %]\n" stash.set('a', 'The cat sat on the mat') output += "more python generated output\n" - print output, + print(output), [% END %] -- expect -- author: Andy Wardley @@ -118,7 +118,7 @@ def testEvalPython(self): output = "author: [% template.author %]\n" stash.set('a', 'The cat sat on the mat') output += "more python generated output\n" - print output, + print(output), [% END %] a: [% a +%] a: $a @@ -140,8 +140,8 @@ def testEvalPython(self): -- test -- [% BLOCK foo %]This is block foo[% END %] [% PYTHON %] -print context.include('foo'), -print "\nbar\n", +print(context.include('foo')), +print("\nbar\n"), [% END %] The end -- expect -- @@ -160,3 +160,4 @@ def testEvalPython(self): """ +main() diff --git a/t/exception_test.py b/t/exception_test.py index 5f46688..e5fabcb 100644 --- a/t/exception_test.py +++ b/t/exception_test.py @@ -7,21 +7,22 @@ def testException(self): text = "the current output buffer" e1 = TemplateException("e1.type", "e1.info") e2 = TemplateException("e2.type", "e2.info", StringBuffer(text)) - self.assertEquals("e1.type", e1.type()) - self.assertEquals("e2.info", e2.info()) + self.assertEqual("e1.type", e1.type()) + self.assertEqual("e2.info", e2.info()) ti = e1.type_info() - self.assertEquals("e1.type", ti[0]) - self.assertEquals("e1.info", ti[1]) - self.assertEquals("e2.type error - e2.info", str(e2)) - self.assertEquals("the current output buffer", e2.text()) + self.assertEqual("e1.type", ti[0]) + self.assertEqual("e1.info", ti[1]) + self.assertEqual("e2.type error - e2.info", str(e2)) + self.assertEqual("the current output buffer", e2.text()) prepend = "text to prepend " e2.text(StringBuffer(prepend)) - self.assertEquals("text to prepend the current output buffer", e2.text()) + self.assertEqual("text to prepend the current output buffer", e2.text()) handlers = ("something", "e2", "e1.type") - self.assertEquals("e1.type", e1.select_handler(handlers)) - self.assertEquals("e2", e2.select_handler(handlers)) + self.assertEqual("e1.type", e1.select_handler(handlers)) + self.assertEqual("e2", e2.select_handler(handlers)) e3 = TemplateException("e3.type", "e3.info", None) - self.assertEquals("", e3.text()) - self.assertEquals("e3.type error - e3.info", str(e3)) + self.assertEqual("", e3.text()) + self.assertEqual("e3.type error - e3.info", str(e3)) +main() diff --git a/t/factory_test.py b/t/factory_test.py index 5c1ac7a..4de56e8 100644 --- a/t/factory_test.py +++ b/t/factory_test.py @@ -31,3 +31,4 @@ def testFactory(self): 3.14 """ +main() diff --git a/t/file_test.py b/t/file_test.py index f000db2..13f05da 100644 --- a/t/file_test.py +++ b/t/file_test.py @@ -9,7 +9,7 @@ def testFile(self): vars = { 'dir': 'test', 'file': 'test/src/foo' } stat = os.stat(vars['file']) for key in file_plugin.STAT_KEYS: - vars[key] = getattr(stat, "st_" + key) + vars[key] = getattr(stat, 'st_'+ key) self.Expect(DATA, None, vars) @@ -153,4 +153,5 @@ def testFile(self): """ +main() diff --git a/t/filter_test.py b/t/filter_test.py index d09c895..56eeed5 100644 --- a/t/filter_test.py +++ b/t/filter_test.py @@ -1,4 +1,4 @@ -import cStringIO +from io import StringIO import os import re import sys @@ -8,10 +8,14 @@ from template.util import dynamic_filter +old_stderr = sys.stderr +sys.stderr = StringIO() + + class FilterTest(TestCase): def setUp(self): self.old_stderr = sys.stderr - sys.stderr = cStringIO.StringIO() + sys.stderr = StringIO() def tearDown(self): sys.stderr = self.old_stderr @@ -567,7 +571,7 @@ def sub(text): b = 20 stash['foo'] = a + b stash['bar'] = context.config()['BARVAL'] - print "all done", + print("all done"), [% END +%] foo: [% foo +%] bar: [% bar %] @@ -830,3 +834,7 @@ def xfilter(text): fOOBAR """ + +main() + +sys.stderr = old_stderr diff --git a/t/foreach_test.py b/t/foreach_test.py index 37d4693..4212768 100644 --- a/t/foreach_test.py +++ b/t/foreach_test.py @@ -597,4 +597,5 @@ def testForeach(self): 13 """ +main() diff --git a/t/format_test.py b/t/format_test.py index da85110..6f2d80f 100644 --- a/t/format_test.py +++ b/t/format_test.py @@ -56,3 +56,4 @@ def testFormat(self): """ +main() diff --git a/t/html_test.py b/t/html_test.py index b0ef282..c7301d2 100644 --- a/t/html_test.py +++ b/t/html_test.py @@ -1,4 +1,4 @@ -# coding: latin-1 +# coding: utf-8 import os from template.test import TestCase, main @@ -31,7 +31,7 @@ def testHtml(self): -- name html entity -- [% TRY; text = - "Léon Brocard" | html_entity; + "Léon Brocard" | html_entity; CATCH; error; END; @@ -94,3 +94,4 @@ def testHtml(self): """ +main() diff --git a/t/image_test.py b/t/image_test.py index a48826d..d29d9dc 100644 --- a/t/image_test.py +++ b/t/image_test.py @@ -1,14 +1,15 @@ import os import sys -import pytest - from template.test import TestCase, main -PIL = pytest.importorskip("PIL") +try: + import PIL +except ImportError: + print >>sys.stderr, "Failed to import PIL module; skipping test" + sys.exit(0) class ImageTest(TestCase): - @pytest.mark.skip(reason="flaky") def testImage(self): dir = os.path.join(os.pardir, "images") vars = { "dir": dir, @@ -79,3 +80,4 @@ def testImage(self): myfile """ +main() diff --git a/t/include_test.py b/t/include_test.py index 887983b..e228964 100644 --- a/t/include_test.py +++ b/t/include_test.py @@ -255,4 +255,5 @@ def testInclude(self): -- test -- """ +main() diff --git a/t/iterator_test.py b/t/iterator_test.py index 91e1d8d..44954a3 100644 --- a/t/iterator_test.py +++ b/t/iterator_test.py @@ -111,3 +111,4 @@ def testIterator(self): baz<-[qux] """ +main() diff --git a/t/list_test.py b/t/list_test.py index 49b051b..f054d59 100644 --- a/t/list_test.py +++ b/t/list_test.py @@ -164,3 +164,4 @@ def testList(self): romeo """ +main() diff --git a/t/macro_test.py b/t/macro_test.py index 2c91264..dca2ea8 100644 --- a/t/macro_test.py +++ b/t/macro_test.py @@ -138,10 +138,11 @@ def testMacro(self): -- name python macro -- [% MACRO triple(n) PYTHON %] n = stash.get('n').value() - print n * 3 + print(n * 3) [% END -%] [% triple(10) %] -- expect -- 30 """ +main() diff --git a/t/math_test.py b/t/math_test.py index 22c12ca..2f1dd2e 100644 --- a/t/math_test.py +++ b/t/math_test.py @@ -58,3 +58,4 @@ def testMath(self): 0.299339178269 """ +main() diff --git a/t/object_test.py b/t/object_test.py index af26c2c..cfa6d51 100644 --- a/t/object_test.py +++ b/t/object_test.py @@ -218,3 +218,4 @@ def testObject(self): . """ +main() diff --git a/t/output_test.py b/t/output_test.py index 3ca867f..2f7af7c 100644 --- a/t/output_test.py +++ b/t/output_test.py @@ -55,3 +55,4 @@ def testOutput(self): self.assertEquals("set binmode\n", intercept.message) +main() diff --git a/t/parser_test.py b/t/parser_test.py index ad6225b..ee2626c 100644 --- a/t/parser_test.py +++ b/t/parser_test.py @@ -15,15 +15,15 @@ def testParser(self): s1 = p2.new_style({"TAG_STYLE": "metatext", "PRE_CHOMP": 0, "POST_CHOMP": 1}) - self.assert_(s1) - self.assertEquals(r"%%", s1["START_TAG"]) - self.assertEquals(0, s1["PRE_CHOMP"]) - self.assertEquals(1, s1["POST_CHOMP"]) + self.assertTrue(s1) + self.assertEqual(r"%%", s1["START_TAG"]) + self.assertEqual(0, s1["PRE_CHOMP"]) + self.assertEqual(1, s1["POST_CHOMP"]) s2 = p2.old_style() - self.assert_(s2) - self.assertEquals(r"\[\*", s2["START_TAG"]) - self.assertEquals(1, s2["PRE_CHOMP"]) - self.assertEquals(0, s2["POST_CHOMP"]) + self.assertTrue(s2) + self.assertEqual(r"\[\*", s2["START_TAG"]) + self.assertEqual(1, s2["PRE_CHOMP"]) + self.assertEqual(0, s2["POST_CHOMP"]) p3 = Config.parser( {"TAG_STYLE": "html", "POST_CHOMP": 1, "ANYCASE": 1, "INTERPOLATE": 1}) p4 = Config.parser({"ANYCASE": 0}) @@ -209,3 +209,4 @@ def testParser(self): [% foo.bar.baz %] """ +main() diff --git a/t/plugins_test.py b/t/plugins_test.py index dead123..9175ff3 100644 --- a/t/plugins_test.py +++ b/t/plugins_test.py @@ -194,4 +194,5 @@ def testPlugins(self): """ +main() diff --git a/t/plusfile_test.py b/t/plusfile_test.py index f49aa31..2a715af 100644 --- a/t/plusfile_test.py +++ b/t/plusfile_test.py @@ -78,3 +78,4 @@ def testPlusfile(self): """ +main() diff --git a/t/prefix_test.py b/t/prefix_test.py index 3ca820d..87616fc 100644 --- a/t/prefix_test.py +++ b/t/prefix_test.py @@ -44,3 +44,4 @@ def testPrefix(self): """ +main() diff --git a/t/process_test.py b/t/process_test.py index 65fc6d3..013293e 100644 --- a/t/process_test.py +++ b/t/process_test.py @@ -62,4 +62,5 @@ def testProcess(self): """ +main() diff --git a/t/provider_test.py b/t/provider_test.py index 7d43d83..8922975 100644 --- a/t/provider_test.py +++ b/t/provider_test.py @@ -108,7 +108,7 @@ def update_file(*args): ttrel = Template({ "LOAD_TEMPLATES": [provrel] }) def dpaths(): - return [os.path.join(lib, x) for x in "one", "two"] + return [os.path.join(lib, x) for x in ("one", "two")] def badpaths(): return [badpaths] @@ -298,3 +298,4 @@ def badpaths(): file error - INCLUDE_PATH exceeds 42 directories """ +main() diff --git a/t/ref_test.py b/t/ref_test.py index 58114a2..7ed9ba1 100644 --- a/t/ref_test.py +++ b/t/ref_test.py @@ -71,4 +71,5 @@ def testRef(self): """ +main() diff --git a/t/service_test.py b/t/service_test.py index d50b3f6..8449a64 100644 --- a/t/service_test.py +++ b/t/service_test.py @@ -206,3 +206,4 @@ def testService(self): This comes after """ +main() diff --git a/t/stash_test.py b/t/stash_test.py index 894f908..1e11744 100644 --- a/t/stash_test.py +++ b/t/stash_test.py @@ -234,3 +234,4 @@ def biz(*args): ERROR: None error - HashObject instance has no attribute 'no_such_method' """ +main() diff --git a/t/stop_test.py b/t/stop_test.py index fc8c212..26a15be 100644 --- a/t/stop_test.py +++ b/t/stop_test.py @@ -103,3 +103,4 @@ def testStop(self): """ +main() diff --git a/t/strcat_test.py b/t/strcat_test.py index 95e6890..67af3e6 100644 --- a/t/strcat_test.py +++ b/t/strcat_test.py @@ -18,3 +18,4 @@ def testStrcat(self): """ +main() diff --git a/t/string_test.py b/t/string_test.py index 1b8deb2..d74954e 100644 --- a/t/string_test.py +++ b/t/string_test.py @@ -385,3 +385,4 @@ def testString(self): """ +main() diff --git a/t/switch_test.py b/t/switch_test.py index 76aa8cf..7c4fd2f 100644 --- a/t/switch_test.py +++ b/t/switch_test.py @@ -253,3 +253,4 @@ def testSwitch(self): """ +main() diff --git a/t/table_test.py b/t/table_test.py index f4e1460..ec76181 100644 --- a/t/table_test.py +++ b/t/table_test.py @@ -130,4 +130,5 @@ def testTable(self): < """ +main() diff --git a/t/tags_test.py b/t/tags_test.py index 7795010..ff04f0b 100644 --- a/t/tags_test.py +++ b/t/tags_test.py @@ -187,4 +187,5 @@ def testTags(self): a is 10 """ +main() diff --git a/t/template_test.py b/t/template_test.py index e082a5a..e7a1a48 100644 --- a/t/template_test.py +++ b/t/template_test.py @@ -14,8 +14,9 @@ def testTemplate(self): try: tt.process("this_file_does_not_exist") self.fail("exception not raised") - except TemplateException, e: + except TemplateException as e: self.assertEquals("file", e.type()) self.assertEquals("this_file_does_not_exist: not found", e.info()) +main() diff --git a/t/test/src/evalpython b/t/test/src/evalpython index 4ddb51a..55cc9f7 100644 --- a/t/test/src/evalpython +++ b/t/test/src/evalpython @@ -1 +1 @@ -This file includes a [% PYTHON %]print "python",[% END %] block. +This file includes a [% PYTHON %]print("python"),[% END %] block. diff --git a/t/text_test.py b/t/text_test.py index 02b6a59..7f28f11 100644 --- a/t/text_test.py +++ b/t/text_test.py @@ -149,4 +149,5 @@ def testText(self): """ +main() diff --git a/t/throw_test.py b/t/throw_test.py index d20b4bf..2858a36 100644 --- a/t/throw_test.py +++ b/t/throw_test.py @@ -79,3 +79,4 @@ def testThrow(self): """ +main() diff --git a/t/try_test.py b/t/try_test.py index 5269cbc..f0ea9f7 100644 --- a/t/try_test.py +++ b/t/try_test.py @@ -626,3 +626,4 @@ def throw_any(*_): """ +main() diff --git a/t/url_test.py b/t/url_test.py index 5af75c1..a2617ef 100644 --- a/t/url_test.py +++ b/t/url_test.py @@ -1,7 +1,6 @@ from template.plugin import url from template.test import TestCase, main -import pytest def no_escape(): url.JOINT = "&" @@ -20,7 +19,6 @@ def sort_params(query): class UrlTest(TestCase): - @pytest.mark.xfail def testUrl(self): urls = [{ "name": "view", "url": "/product" }, @@ -128,4 +126,5 @@ def testUrl(self): /product?action=edit&style=compact """ +main() diff --git a/t/vars_test.py b/t/vars_test.py index 91859a2..0817166 100644 --- a/t/vars_test.py +++ b/t/vars_test.py @@ -949,4 +949,5 @@ def yankee(): 55 """ +main() diff --git a/t/view_test.py b/t/view_test.py index b41bd6e..94661dd 100644 --- a/t/view_test.py +++ b/t/view_test.py @@ -746,3 +746,4 @@ def testView(self): """ +main() diff --git a/t/vmeth_hash_test.py b/t/vmeth_hash_test.py index 1021df0..ec62b60 100644 --- a/t/vmeth_hash_test.py +++ b/t/vmeth_hash_test.py @@ -117,4 +117,5 @@ def dump(dict): """ +main() diff --git a/t/vmeth_list_test.py b/t/vmeth_list_test.py index 9e9266b..b9cae89 100644 --- a/t/vmeth_list_test.py +++ b/t/vmeth_list_test.py @@ -403,3 +403,4 @@ def testListVmethods(self): """ +main() diff --git a/t/vmeth_replace_test.py b/t/vmeth_replace_test.py index 48dbb1c..a441d57 100644 --- a/t/vmeth_replace_test.py +++ b/t/vmeth_replace_test.py @@ -182,3 +182,4 @@ def testReplace(self): """ +main() diff --git a/t/vmeth_text_test.py b/t/vmeth_text_test.py index f0a2cec..b2c7d7f 100644 --- a/t/vmeth_text_test.py +++ b/t/vmeth_text_test.py @@ -336,3 +336,4 @@ def testTextVmethods(self): """ +main() diff --git a/t/while_test.py b/t/while_test.py index 0683946..296c79e 100644 --- a/t/while_test.py +++ b/t/while_test.py @@ -192,4 +192,5 @@ def next(): 1 """ +main() diff --git a/t/wrapper_test.py b/t/wrapper_test.py index 81ed23d..4ae14eb 100644 --- a/t/wrapper_test.py +++ b/t/wrapper_test.py @@ -175,3 +175,4 @@ def testWrapper(self): """ +main() diff --git a/template/__init__.py b/template/__init__.py index ef6472d..20a0514 100644 --- a/template/__init__.py +++ b/template/__init__.py @@ -95,13 +95,13 @@ class and gives a brief summary of configuration options and template try: # filename - print tt.process('welcome.tt2') + print(tt.process('welcome.tt2')) # template text - print tt.processString(text) + print(tt.processString(text)) # file object - print tt.process(os.fdopen(5)) - except template.TemplateException, e: - print 'Got exception:', e + print(tt.process(os.fdopen(5))) + except template.TemplateException as e: + print('Got exception:', e) The processed template output is returned. @@ -127,10 +127,10 @@ class and gives a brief summary of configuration options and template try: tt.process('somefile') - except template.TemplateException, e: - print 'error type:', e.type() - print 'error info:', e.info() - print e + except template.TemplateException as e: + print('error type:', e.type()) + print('error info:', e.info()) + print(e) service() @@ -523,8 +523,8 @@ class and gives a brief summary of configuration options and template [% PYTHON %] # python code goes here stash.set('foo', 10) - print "set 'foo' to ", stash.get('foo') - print context.include('footer', { 'var': val }) + print("set 'foo' to ", stash.get('foo')) + print(context.include('footer', { 'var': val })) [% END %] [% RAWPYTHON %] diff --git a/template/context.py b/template/context.py index 8d405e7..5382c59 100644 --- a/template/context.py +++ b/template/context.py @@ -7,7 +7,7 @@ # the terms under which this file may be distributed. # -import cStringIO +from io import StringIO import operator import os import re @@ -439,8 +439,8 @@ try: tt = context.template('header') - except TemplateException, e: - print 'Failed to fetch template:', e + except TemplateException as e: + print('Failed to fetch template:', e) plugin(name, args) @@ -669,7 +669,7 @@ def insert(self, files): else: files = [unscalar(files)] prefix = providers = text = None - output = cStringIO.StringIO() + output = StringIO() for file in files: prefix, name = split_prefix(file) @@ -683,7 +683,7 @@ def insert(self, files): for provider in providers: try: text = provider.load(name, prefix) - except Exception, e: + except Exception as e: self.throw(ERROR_FILE, str(e)) if text is not None: output.write(text) @@ -772,7 +772,7 @@ def process(self, template, params=None, localize=False): else: self.__stash.update(params) - output = cStringIO.StringIO() + output = StringIO() try: # save current component @@ -945,7 +945,7 @@ def template(self, name): for provider in providers: try: template = provider.fetch(shortname, prefix) - except Exception, e: + except Exception as e: if isinstance(e, TemplateException) and e.type() == ERROR_FILE: self.throw(e) else: @@ -1026,7 +1026,7 @@ def define_filter(self, name, filter, dynamic=False): try: provider.store(name, filter) return 1 - except Exception, e: + except Exception as e: self.throw(ERROR_FILTER, e) self.throw(ERROR_FILTER, "FILTER providers declined to store filter %s" % name) diff --git a/template/directive.py b/template/directive.py index 236d504..b9c9918 100644 --- a/template/directive.py +++ b/template/directive.py @@ -26,7 +26,7 @@ def template(self, block): Code.indent, block, Code.unindent, - "except Error, e:", + "except Error as e:", " error = context.catch(e, output)", " if error.type() != 'return':", " raise error", @@ -41,7 +41,7 @@ def anon_block(self, block): # [% BLOCK %] ... [% END %] Code.indent, block, Code.unindent, - "except Error, e:", + "except Error as e:", " error = context.catch(e, output)", " if error.type() != 'return':", " raise error", @@ -326,7 +326,7 @@ def try_(self, block, catches): # [% TRY %] ... [% CATCH %] ... [% END %] Code.indent, block, Code.unindent, - "except Exception, e:", + "except Exception as e:", Code.indent, "error = context.catch(e, output)", "if error.type() in ('return', 'stop'):", diff --git a/template/document.py b/template/document.py index e7cec94..5f9895c 100644 --- a/template/document.py +++ b/template/document.py @@ -7,7 +7,7 @@ # the terms under which this file may be distributed. # -import cStringIO +from io import StringIO import os import re import tempfile @@ -38,7 +38,7 @@ } }) - print doc.process(context) + print(doc.process(context)) DESCRIPTION @@ -121,7 +121,7 @@ class but can be manually instantiated or sub-classed to provide the context reference by parameter and then calls leave() in the context to allow cleanup. - print doc.process(context) + print(doc.process(context)) Returns a text string representing the generated output for the template. @@ -168,7 +168,7 @@ def __init__(self, doc): # same for any additional BLOCK definitions self.__defblocks = {} - for name, block in doc.get("DEFBLOCKS", {}).iteritems(): + for name, block in doc.get("DEFBLOCKS", {}).items(): self.__defblocks[name] = self.__compile(block) self.__meta = doc.get("METADATA", {}).copy() @@ -178,7 +178,7 @@ def __compile(self, block, debug=False): if callable(block): return block if debug: - print block + print(block) return self.evaluate(block) def __getattr__(self, name): @@ -213,7 +213,7 @@ def process(self, context): try: try: return self.__block(context) - except TemplateException, e: + except TemplateException as e: raise context.catch(e) finally: self.__hot = False @@ -229,7 +229,7 @@ def evaluate(cls, block, name="block"): block. The default name is 'block'. """ namespace = PYEVAL_NAMESPACE.copy() - exec block in namespace + exec(block, namespace) return namespace.get(name) @classmethod @@ -242,7 +242,7 @@ def evaluate_file(cls, path, name="document"): file. The default name is 'document'. """ namespace = PYEVAL_NAMESPACE.copy() - execfile(path, namespace) + exec(path, namespace) return namespace.get(name) @classmethod diff --git a/template/filters.py b/template/filters.py index 04dbcc7..07a47d0 100644 --- a/template/filters.py +++ b/template/filters.py @@ -31,7 +31,7 @@ try: filter = filters.fetch(name, args, context) - except TemplateException, e: + except TemplateException as e: # Handle error. if filter is None: # Request was declined. @@ -311,7 +311,7 @@ def filter(text): strings in a PYTHON block, eg: [% PYTHON %] - print 'My name is', [% name | repr %], 'and I live at', [% address | repr %] + print('My name is', [% name | repr %], 'and I live at', [% address | repr %]) [% END %] @@ -718,7 +718,7 @@ def fetch(self, name, args, context): filter = factory if not callable(filter): raise Error("invalid FILTER for '%s' (not callable)" % (name,)) - except Exception, e: + except Exception as e: if self.__tolerant: return None if not isinstance(e, TemplateException): @@ -957,7 +957,7 @@ def redirect_filter(text=""): try: try: os.makedirs(outpath) - except OSError, e: + except OSError as e: if e.errno != errno.EEXIST: raise outpath += "/" + str(file) @@ -968,7 +968,7 @@ def redirect_filter(text=""): fh = open(outpath, mode) fh.write(text) fh.close() - except Exception, e: + except Exception as e: raise TemplateException("redirect", e) return "" return redirect_filter diff --git a/template/grammar.py b/template/grammar.py index 4295bbc..0ed762e 100644 --- a/template/grammar.py +++ b/template/grammar.py @@ -68,7 +68,7 @@ def install_factory(self, new_factory): for keyword in RESERVED: LEXTABLE[keyword] = keyword -for op in CMPOP.iterkeys(): +for op in CMPOP.keys(): LEXTABLE[op] = "CMPOP" for op in "-", "*", "%": @@ -5715,7 +5715,7 @@ def rule(*args): @define(117, "range", 3) def rule(*args): - return "xrange(int(%s), int(%s) + 1)" % (args[1], args[3]) + return "range(int(%s), int(%s) + 1)" % (args[1], args[3]) @define(119, "hash", 0) diff --git a/template/iterator.py b/template/iterator.py index ebb8a29..b5538e7 100644 --- a/template/iterator.py +++ b/template/iterator.py @@ -332,7 +332,7 @@ def normalize_data(data): """ data = data or [] if isinstance(data, dict): - data = [{"key": key, "value": value} for key, value in data.iteritems()] + data = [{"key": key, "value": value} for key, value in data.items()] data.sort(key=operator.itemgetter("key")) elif isinstance(data, str): data = [data] diff --git a/template/namespace/constants.py b/template/namespace/constants.py index d432ba7..2449e2f 100644 --- a/template/namespace/constants.py +++ b/template/namespace/constants.py @@ -82,7 +82,7 @@ def ident(self, ident): save = ident[:] ident[:2] = [] nelems = len(ident) / 2 - for e in range(nelems): + for e in range(int(nelems)): # Node name must be a constant. if ident[e * 2].startswith("'") and ident[e * 2].endswith("'"): ident[e * 2] = ident[e * 2][1:-1] @@ -98,7 +98,7 @@ def ident(self, ident): ident[e * 2 + 1] = comp result = self.__stash.get(ident).value() - if len(str(result)) == 0 or not isinstance(result, (str, int, long)): + if len(str(result)) == 0 or not isinstance(result, (str, int)): return Directive.Ident(save) else: return repr(result) diff --git a/template/parser.py b/template/parser.py index c141e52..caa8d13 100644 --- a/template/parser.py +++ b/template/parser.py @@ -969,7 +969,7 @@ def _parse(self, tokens, info): codevars = [] try: coderet = code(self, *codevars) - except TemplateException, e: + except TemplateException as e: self._parse_error(str(e), info.name) # reduce stack by len_ if len_ > 0: diff --git a/template/plugin/datafile.py b/template/plugin/datafile.py index 7f1b46a..c83b3e3 100644 --- a/template/plugin/datafile.py +++ b/template/plugin/datafile.py @@ -89,7 +89,7 @@ def __init__(self, context, filename, params=None): try: f = open(filename) - except IOError, e: + except IOError as e: return self.fail("%s: %s" % (filename, e)) for line in f: diff --git a/template/plugin/date.py b/template/plugin/date.py index 22d9ad7..422ec91 100644 --- a/template/plugin/date.py +++ b/template/plugin/date.py @@ -171,7 +171,7 @@ def get(name): try: # If time is numeric, we assume it's seconds since the epoch: time = int(time) - except StandardError: + except Exception: # Otherwise, we try to parse it as a 'H:M:S D:M:Y' string: date = re.split(r"[-/ :]", str(time)) if len(date) < 6: diff --git a/template/plugin/directory.py b/template/plugin/directory.py index 958b4ee..089dd46 100644 --- a/template/plugin/directory.py +++ b/template/plugin/directory.py @@ -206,7 +206,7 @@ def scan(self, config=None): config["noscan"] = True try: files = os.listdir(self.abs) - except OSError, e: + except OSError as e: self.throw("%s: %s" % (self.abs, e)) self.files = [] self.dirs = [] diff --git a/template/plugin/file.py b/template/plugin/file.py index b961cd8..12bd214 100644 --- a/template/plugin/file.py +++ b/template/plugin/file.py @@ -254,8 +254,8 @@ """ -STAT_KEYS = ("dev", "ino", "mode", "nlink", "uid", "gid", "rdev", "size", - "atime", "mtime", "ctime", "blksize", "blocks") +STAT_KEYS = ("dev", "ino", "mode", "nlink", "uid", "gid", "size", + "atime", "mtime", "ctime", ) class File(Plugin): @@ -309,7 +309,7 @@ def __init__(self, context, path, config=None): if self.stat: try: stat = os.stat(abspath) - except OSError, e: + except OSError as e: self.throw("%s: %s" % (abspath, e)) for key in STAT_KEYS: setattr(self, key, getattr(stat, "st_%s" % key, None)) diff --git a/template/plugin/format.py b/template/plugin/format.py index f95fdd1..e8a5bd5 100644 --- a/template/plugin/format.py +++ b/template/plugin/format.py @@ -54,7 +54,7 @@ def formatter(*args): while True: try: return format % args - except TypeError, e: + except TypeError as e: if e.args[0].startswith("not enough arguments"): args += ("",) elif e.args[0].startswith("not all arguments converted"): diff --git a/template/plugin/image.py b/template/plugin/image.py index cb30420..3c364fb 100644 --- a/template/plugin/image.py +++ b/template/plugin/image.py @@ -175,7 +175,7 @@ def init(self): if self.__size is None: try: self.__size = PIL.Image.open(self.__file).size - except Exception, e: + except Exception as e: self.throw(e) self.__width, self.__height = self.__size self.__modtime = os.stat(self.__file).st_mtime diff --git a/template/plugin/math_plugin.py b/template/plugin/math_plugin.py index bae97a4..e767d30 100644 --- a/template/plugin/math_plugin.py +++ b/template/plugin/math_plugin.py @@ -37,8 +37,8 @@ All function arguments are automatically converted to numbers, if necessary, using Perlish semantics: - print math_plugin.cos('0') # prints '1' - print math_plugin.exp('x') # also prints '1' + print(math_plugin.cos('0')) # prints '1' + print(math_plugin.exp('x')) # also prints '1' * abs @@ -223,7 +223,7 @@ def sin(self, x): def sqrt(self, x): root = math.sqrt(numify(x)) - trunc = long(root) + trunc = int(root) # Try to return an integer, if possible: if root == trunc: return trunc diff --git a/template/plugin/table.py b/template/plugin/table.py index 452af5e..a7dd384 100644 --- a/template/plugin/table.py +++ b/template/plugin/table.py @@ -232,7 +232,7 @@ def __init__(self, context, data, params=None): # ensure keys are folded to upper case params.update(dict((str(key).upper(), value) - for key, value in params.iteritems())) + for key, value in params.items())) size = len(data) overlap = params.get("OVERLAP", 0) @@ -283,7 +283,7 @@ def row(self, row=None): return None index = row set = [] - for c in range(self._NCOLS): + for c in range(int(self._NCOLS)): if index < self._SIZE: set.append(self._DATA[index]) elif self._PAD: diff --git a/template/plugins.py b/template/plugins.py index f0bd3b3..d3eec28 100644 --- a/template/plugins.py +++ b/template/plugins.py @@ -509,7 +509,7 @@ def fetch(self, name, args=None, context=None): return factory(*args) else: raise Error("%s plugin is not callable" % (name,)) - except Exception, e: + except Exception as e: if self.__tolerant: return None else: diff --git a/template/provider.py b/template/provider.py index 19f4c22..5afcc16 100644 --- a/template/provider.py +++ b/template/provider.py @@ -443,10 +443,7 @@ def paths(self): If the optional parameter 'modtime' is present, the modification time of the file is stored in its 'modtime' attribute. - """ - - RELATIVE_PATH = re.compile(r"(?:^|/)\.+/") @@ -473,7 +470,7 @@ class Provider: DEBUG = False def __init__(self, params): - size = params.get("CACHE_SIZE") + size = params.get("CACHE_SIZE", -1) paths = params.get("INCLUDE_PATH", ".") cdir = params.get("COMPILE_DIR", "") dlim = params.get("DELIMITER", os.name == "nt" and r":(?!\/)" or ":") @@ -481,7 +478,8 @@ def __init__(self, params): if isinstance(paths, str): paths = re.split(dlim, paths) - if size == 1 or size < 0: + #if size == 1 or size < 0 or size == None: + if size==None: size = 2 if debug is not None: self.__debug = debug & (DEBUG_PROVIDER & DEBUG_FLAGS) @@ -664,13 +662,13 @@ def _compile(self, data, compfile=None): if not os.path.isdir(basedir): try: os.makedirs(basedir) - except IOError, e: + except IOError as e: error = Error("failed to create compiled templates " "directory: %s (%s)" % (basedir, e)) if not error: try: self.__document.write_python_file(compfile, parsedoc) - except Exception, e: + except Exception as e: error = Error("cache failed to write %s: %s" % ( os.path.basename(compfile), e)) if error is None and data.time is not None: @@ -839,7 +837,7 @@ def _refresh(self, slot): def _load_compiled(self, path): try: return Document.evaluate_file(path) - except TemplateException, e: + except TemplateException as e: raise Error("compiled template %s: %s" % (path, e)) def _store(self, name, data, compfile=None): @@ -966,7 +964,7 @@ def load(self, name, prefix=None): if path and not error: try: data = self._template_content(path) - except IOError, e: + except IOError as e: error = "%s: %s" % (name, e) if error: diff --git a/template/service.py b/template/service.py index 9f9ab13..0d645e7 100644 --- a/template/service.py +++ b/template/service.py @@ -36,7 +36,7 @@ try: output = service.process(template_name, replace) - except TemplateException, e: + except TemplateExceptiona as e: ... @@ -473,7 +473,7 @@ def process(self, template, params=None): try: for name in proc: procout.write(context.process(name)) - except TemplateException, e: + except TemplateException as e: procout.reset(self.__recover(e)) procout = procout.get() diff --git a/template/stash.py b/template/stash.py index 5a52c9a..95ca3e0 100644 --- a/template/stash.py +++ b/template/stash.py @@ -698,7 +698,7 @@ def hash_size(hash): @hash_op("each", "items") def hash_each(hash): - return [item for pair in hash.iteritems() for item in pair] + return [item for pair in hash.items() for item in pair] @hash_op("keys") @@ -764,7 +764,7 @@ def hash_sort(hash): @hash_op("nsort") def hash_nsort(hash): - return [pair[0] for pair in sorted(hash.items(), key=_by_value(_to_long))] + return [pair[0] for pair in sorted(hash.items(), key=_by_value(_to_int))] @list_op("item") @@ -890,9 +890,9 @@ def list_nsort(list, field=None): if len(list) <= 1: return list[:] elif field: - return sorted(list, key=_smartsort(field, _to_long)) + return sorted(list, key=_smartsort(field, _to_int)) else: - return sorted(list, key=_to_long) + return sorted(list, key=_to_int) @list_op("unique") @@ -966,15 +966,15 @@ def _to_lower(x): LONG_REGEX = re.compile(r"-?\d+") -def _to_long(x): +def _to_int(x): try: - return long(x) + return int(x) except ValueError: match = LONG_REGEX.match(str(x)) if match: - return long(match.group(0)) + return int(match.group(0)) else: - return 0L + return 0 def _by_value(func): diff --git a/template/test.py b/template/test.py index a32f6ca..f3bc2d4 100644 --- a/template/test.py +++ b/template/test.py @@ -71,16 +71,15 @@ def Expect(self, data, tproc=None, vars=None): try: out = tproc.processString(input, vars) - except Exception, e: - self.fail("Test #%d: %s process FAILED: %s\n%s" % ( - count + 1, name, subtext(input), e)) + except Exception as e: + self.fail("Test #%d: %s process FAILED: %s\n%s" % (count + 1, name, subtext(input), e)) match = re.match(r"(?i)\s*--+\s*process\s*--+\s*\n", expect) if match: expect = expect[match.end():] try: expect = tproc.processString(expect, vars) - except TemplateException, e: + except TemplateException as e: self.fail("Test #%d: Template process failed (expect): %s" % ( count + 1, e)) out = out.rstrip("\n") diff --git a/template/util.py b/template/util.py index b06c4c4..aee27e8 100644 --- a/template/util.py +++ b/template/util.py @@ -7,7 +7,7 @@ # the terms under which this file may be distributed. # -import cStringIO +from io import StringIO import os import re import sys @@ -91,7 +91,7 @@ def __init__(self, contents=None): """Initializes the object. If the contents argument is not None, it is immediately passed to the write method. """ - self.buffer = cStringIO.StringIO() + self.buffer = StringIO() if contents is not None: self.write(contents) @@ -370,7 +370,7 @@ def __int__(self): return int(self.__numify()) def __long__(self): - return long(self.__numify()) + return int(self.__numify()) def __float__(self): return float(self.__numify()) @@ -393,7 +393,7 @@ def __numify(self): def numify(value): """Converts any object to a number using Perl's rules.""" - if isinstance(value, (int, long, float)): + if isinstance(value, (int, float)): return value elif value is True: return 1 @@ -499,7 +499,7 @@ def EvaluateCode(code, context, stash): "stdout": sys.stdout, "output": stringbuf } try: - exec code in vars + exec(code, vars) finally: sys.stdout = old_stdout return stringbuf.get() @@ -547,12 +547,12 @@ def unscalar_list(seq): def ScalarList(*args): """Returns a PerlScalar that wraps a list containing the result of applying the unscalar function to each argument of this function-- - except for xrange objects, which are flattened into the output list + except for range objects, which are flattened into the output list instead. """ list = [] for arg in args: - if isinstance(arg, xrange): + if isinstance(arg, range): list.extend(arg) else: list.append(unscalar(arg)) @@ -624,7 +624,7 @@ def unpack(seq, n): ...and not suffer an error if there are fewer than three elements in the tuple returned by func. """ - return chop(seq, n).next() + return chop(seq, n).__next__() def listify(arg): diff --git a/template/view.py b/template/view.py index b06b4a5..bb65ca7 100644 --- a/template/view.py +++ b/template/view.py @@ -7,11 +7,12 @@ # the terms under which this file may be distributed. # -import cStringIO +from io import StringIO import re from template.constants import ERROR_VIEW from template.util import can, is_seq +from builtins import str """ @@ -460,7 +461,7 @@ def print_(self, *args): type = "ARRAY" elif isinstance(item, dict): type = "HASH" - elif isinstance(item, (basestring, int, long)): + elif isinstance(item, (str, int)): type = "TEXT" else: type = item.__class__.__name__ @@ -540,13 +541,13 @@ def template(self, name): e = None try: template = self._context.template(template) - except Exception, e: + except Exception as e: pass if e and self._base: try: template = self._base.template(name) e = None - except Exception, e: + except Exception as e: pass if e and self._notfound: template = self._blocks.get(self._notfound) @@ -554,7 +555,7 @@ def template(self, name): notfound = self.template_name(self._notfound) try: template = self._context.template(notfound) - except Exception, e: + except Exception as e: self._context.throw(ERROR_VIEW, e) elif e: self._context.throw(ERROR_VIEW, e) diff --git a/template/vmethods.py b/template/vmethods.py index 14339b1..e5e47e5 100644 --- a/template/vmethods.py +++ b/template/vmethods.py @@ -182,7 +182,7 @@ def hash_size(hash): @hash_op("each", "items") def hash_each(hash): - return [item for pair in hash.iteritems() for item in pair] + return [item for pair in hash.items() for item in pair] @hash_op("keys") @@ -248,7 +248,7 @@ def hash_sort(hash): @hash_op("nsort") def hash_nsort(hash): - return [pair[0] for pair in sorted(hash.items(), key=_by_value(_to_long))] + return [pair[0] for pair in sorted(hash.items(), key=_by_value(_to_int))] @list_op("item") @@ -374,9 +374,9 @@ def list_nsort(list, field=None): if len(list) <= 1: return list[:] elif field: - return sorted(list, key=_smartsort(field, _to_long)) + return sorted(list, key=_smartsort(field, _to_int)) else: - return sorted(list, key=_to_long) + return sorted(list, key=_to_int) @list_op("unique") @@ -450,15 +450,15 @@ def _to_lower(x): LONG_REGEX = re.compile(r"-?\d+") -def _to_long(x): +def _to_int(x): try: - return long(x) + return int(x) except ValueError: match = LONG_REGEX.match(str(x)) if match: - return long(match.group(0)) + return int(match.group(0)) else: - return 0L + return 0 def _by_value(func): diff --git a/tox.ini b/tox.ini index 5301921..8f0bdfb 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27,pypy +envlist = py27,py37,pypy [testenv] deps =