183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Copyright (C) 2004 Python Software Foundation 283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Author: barry@python.org (Barry Warsaw) 383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# License: http://www.opensource.org/licenses/PythonSoftFoundation.php 483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport unittest 683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom string import Template 783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass Bag: 1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass Mapping: 1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __getitem__(self, name): 1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh obj = self 1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for part in name.split('.'): 1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh obj = getattr(obj, part) 1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except AttributeError: 1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise KeyError(name) 2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return obj 2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass TestTemplate(unittest.TestCase): 2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_regular_templates(self): 2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('$who likes to eat a bag of $what worth $$100') 2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(s.substitute(dict(who='tim', what='ham')), 2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 'tim likes to eat a bag of ham worth $100') 2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertRaises(KeyError, s.substitute, dict(who='tim')) 2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_regular_templates_with_braces(self): 3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('$who likes ${what} for ${meal}') 3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh d = dict(who='tim', what='ham', meal='dinner') 3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(s.substitute(d), 'tim likes ham for dinner') 3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertRaises(KeyError, s.substitute, 3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh dict(who='tim', what='ham')) 3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_escapes(self): 3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq = self.assertEqual 3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('$who likes to eat a bag of $$what worth $$100') 4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.substitute(dict(who='tim', what='ham')), 4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 'tim likes to eat a bag of $what worth $100') 4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('$who likes $$') 4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.substitute(dict(who='tim', what='ham')), 'tim likes $') 4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_percents(self): 4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq = self.assertEqual 4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('%(foo)s $foo ${foo}') 4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh d = dict(foo='baz') 4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.substitute(d), '%(foo)s baz baz') 5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(d), '%(foo)s baz baz') 5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_stringification(self): 5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq = self.assertEqual 5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('tim has eaten $count bags of ham today') 5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh d = dict(count=7) 5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.substitute(d), 'tim has eaten 7 bags of ham today') 5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(d), 'tim has eaten 7 bags of ham today') 5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('tim has eaten ${count} bags of ham today') 5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.substitute(d), 'tim has eaten 7 bags of ham today') 6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_tupleargs(self): 6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq = self.assertEqual 6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('$who ate ${meal}') 6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh d = dict(who=('tim', 'fred'), meal=('ham', 'kung pao')) 6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.substitute(d), "('tim', 'fred') ate ('ham', 'kung pao')") 6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(d), "('tim', 'fred') ate ('ham', 'kung pao')") 6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_SafeTemplate(self): 6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq = self.assertEqual 7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('$who likes ${what} for ${meal}') 7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(dict(who='tim')), 'tim likes ${what} for ${meal}') 7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(dict(what='ham')), '$who likes ham for ${meal}') 7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(dict(what='ham', meal='dinner')), 7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh '$who likes ham for dinner') 7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(dict(who='tim', what='ham')), 7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 'tim likes ham for ${meal}') 7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(dict(who='tim', what='ham', meal='dinner')), 7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 'tim likes ham for dinner') 7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_invalid_placeholders(self): 8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raises = self.assertRaises 8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('$who likes $') 8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raises(ValueError, s.substitute, dict(who='tim')) 8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('$who likes ${what)') 8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raises(ValueError, s.substitute, dict(who='tim')) 8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('$who likes $100') 8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raises(ValueError, s.substitute, dict(who='tim')) 8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_idpattern_override(self): 9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh class PathPattern(Template): 9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh idpattern = r'[_a-z][._a-z0-9]*' 9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh m = Mapping() 9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh m.bag = Bag() 9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh m.bag.foo = Bag() 9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh m.bag.foo.who = 'tim' 9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh m.bag.what = 'ham' 9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = PathPattern('$bag.foo.who likes to eat a bag of $bag.what') 9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham') 9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_pattern_override(self): 10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh class MyPattern(Template): 10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pattern = r""" 10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh (?P<escaped>@{2}) | 10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @(?P<named>[_a-z][._a-z0-9]*) | 10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @{(?P<braced>[_a-z][._a-z0-9]*)} | 10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh (?P<invalid>@) 10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """ 10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh m = Mapping() 10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh m.bag = Bag() 11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh m.bag.foo = Bag() 11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh m.bag.foo.who = 'tim' 11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh m.bag.what = 'ham' 11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = MyPattern('@bag.foo.who likes to eat a bag of @bag.what') 11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham') 11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh class BadPattern(Template): 11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pattern = r""" 11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh (?P<badname>.*) | 11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh (?P<escaped>@{2}) | 12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @(?P<named>[_a-z][._a-z0-9]*) | 12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh @{(?P<braced>[_a-z][._a-z0-9]*)} | 12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh (?P<invalid>@) | 12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """ 12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = BadPattern('@bag.foo.who likes to eat a bag of @bag.what') 12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertRaises(ValueError, s.substitute, {}) 12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertRaises(ValueError, s.safe_substitute, {}) 12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 12883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_unicode_values(self): 12983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('$who likes $what') 13083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh d = dict(who=u't\xffm', what=u'f\xfe\fed') 13183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(s.substitute(d), u't\xffm likes f\xfe\x0ced') 13283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 13383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_keyword_arguments(self): 13483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq = self.assertEqual 13583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('$who likes $what') 13683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.substitute(who='tim', what='ham'), 'tim likes ham') 13783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.substitute(dict(who='tim'), what='ham'), 'tim likes ham') 13883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.substitute(dict(who='fred', what='kung pao'), 13983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh who='tim', what='ham'), 14083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 'tim likes ham') 14183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('the mapping is $mapping') 14283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.substitute(dict(foo='none'), mapping='bozo'), 14383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 'the mapping is bozo') 14483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.substitute(dict(mapping='one'), mapping='two'), 14583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 'the mapping is two') 14683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 14783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_keyword_arguments_safe(self): 14883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq = self.assertEqual 14983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raises = self.assertRaises 15083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('$who likes $what') 15183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(who='tim', what='ham'), 'tim likes ham') 15283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(dict(who='tim'), what='ham'), 'tim likes ham') 15383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(dict(who='fred', what='kung pao'), 15483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh who='tim', what='ham'), 15583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 'tim likes ham') 15683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = Template('the mapping is $mapping') 15783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(dict(foo='none'), mapping='bozo'), 15883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 'the mapping is bozo') 15983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(dict(mapping='one'), mapping='two'), 16083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 'the mapping is two') 16183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh d = dict(mapping='one') 16283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raises(TypeError, s.substitute, d, {}) 16383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raises(TypeError, s.safe_substitute, d, {}) 16483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 16583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def test_delimiter_override(self): 16683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq = self.assertEqual 16783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raises = self.assertRaises 16883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh class AmpersandTemplate(Template): 16983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh delimiter = '&' 17083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = AmpersandTemplate('this &gift is for &{who} &&') 17183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.substitute(gift='bud', who='you'), 'this bud is for you &') 17283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raises(KeyError, s.substitute) 17383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(gift='bud', who='you'), 'this bud is for you &') 17483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(), 'this &gift is for &{who} &') 17583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = AmpersandTemplate('this &gift is for &{who} &') 17683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raises(ValueError, s.substitute, dict(gift='bud', who='you')) 17783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh eq(s.safe_substitute(), 'this &gift is for &{who} &') 17883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 17983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh class PieDelims(Template): 18083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh delimiter = '@' 18183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = PieDelims('@who likes to eat a bag of @{what} worth $100') 18283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.assertEqual(s.substitute(dict(who='tim', what='ham')), 18383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 'tim likes to eat a bag of ham worth $100') 18483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 18583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 18683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef test_main(): 18783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh from test import test_support 18883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh test_classes = [TestTemplate,] 18983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh test_support.run_unittest(*test_classes) 19083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 19183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 19283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehif __name__ == '__main__': 19383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh test_main() 194