mirror of
https://github.com/python/cpython.git
synced 2025-12-05 00:52:25 +00:00
Fix small bugs in Template code.
* The parameterization of "delimiter" was incomplete. * safe_substitute's code for braced delimiters should only be executed when braced is not None. * Invalid pattern group names now raise a ValueError. Formerly, the convert code would fall off the end and improperly return None. Beefed-up tests. * Test delimiter override for all paths in substitute and safe_substitute. * Alter unittest invocation to match other modules (now it itemizes the tests as they are run).
This commit is contained in:
parent
23f1241dc6
commit
6d191113a6
2 changed files with 30 additions and 15 deletions
|
|
@ -152,6 +152,7 @@ class Template:
|
||||||
mapping = _multimap(kws, args[0])
|
mapping = _multimap(kws, args[0])
|
||||||
else:
|
else:
|
||||||
mapping = args[0]
|
mapping = args[0]
|
||||||
|
delimiter = self.delimiter[-1]
|
||||||
# Helper function for .sub()
|
# Helper function for .sub()
|
||||||
def convert(mo):
|
def convert(mo):
|
||||||
# Check the most common path first.
|
# Check the most common path first.
|
||||||
|
|
@ -162,9 +163,10 @@ class Template:
|
||||||
# fail if val is a Unicode containing non-ASCII characters.
|
# fail if val is a Unicode containing non-ASCII characters.
|
||||||
return '%s' % val
|
return '%s' % val
|
||||||
if mo.group('escaped') is not None:
|
if mo.group('escaped') is not None:
|
||||||
return '$'
|
return delimiter
|
||||||
if mo.group('invalid') is not None:
|
if mo.group('invalid') is not None:
|
||||||
self._invalid(mo)
|
self._invalid(mo)
|
||||||
|
raise ValueError('Unrecognized named group in pattern', pattern)
|
||||||
return self.pattern.sub(convert, self.template)
|
return self.pattern.sub(convert, self.template)
|
||||||
|
|
||||||
def safe_substitute(self, *args, **kws):
|
def safe_substitute(self, *args, **kws):
|
||||||
|
|
@ -176,6 +178,7 @@ class Template:
|
||||||
mapping = _multimap(kws, args[0])
|
mapping = _multimap(kws, args[0])
|
||||||
else:
|
else:
|
||||||
mapping = args[0]
|
mapping = args[0]
|
||||||
|
delimiter = self.delimiter[-1]
|
||||||
# Helper function for .sub()
|
# Helper function for .sub()
|
||||||
def convert(mo):
|
def convert(mo):
|
||||||
named = mo.group('named')
|
named = mo.group('named')
|
||||||
|
|
@ -185,16 +188,18 @@ class Template:
|
||||||
# will fail if val is a Unicode containing non-ASCII
|
# will fail if val is a Unicode containing non-ASCII
|
||||||
return '%s' % mapping[named]
|
return '%s' % mapping[named]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return '$' + named
|
return delimiter + named
|
||||||
braced = mo.group('braced')
|
braced = mo.group('braced')
|
||||||
try:
|
if braced is not None:
|
||||||
return '%s' % mapping[braced]
|
try:
|
||||||
except KeyError:
|
return '%s' % mapping[braced]
|
||||||
return '${' + braced + '}'
|
except KeyError:
|
||||||
|
return delimiter + '{' + braced + '}'
|
||||||
if mo.group('escaped') is not None:
|
if mo.group('escaped') is not None:
|
||||||
return '$'
|
return delimiter
|
||||||
if mo.group('invalid') is not None:
|
if mo.group('invalid') is not None:
|
||||||
self._invalid(mo)
|
self._invalid(mo)
|
||||||
|
raise ValueError('Unrecognized named group in pattern', pattern)
|
||||||
return self.pattern.sub(convert, self.template)
|
return self.pattern.sub(convert, self.template)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,17 +150,27 @@ class TestTemplate(unittest.TestCase):
|
||||||
raises(TypeError, s.substitute, d, {})
|
raises(TypeError, s.substitute, d, {})
|
||||||
raises(TypeError, s.safe_substitute, d, {})
|
raises(TypeError, s.safe_substitute, d, {})
|
||||||
|
|
||||||
|
def test_delimiter_override(self):
|
||||||
def suite():
|
class AmpersandTemplate(Template):
|
||||||
suite = unittest.TestSuite()
|
delimiter = '&'
|
||||||
suite.addTest(unittest.makeSuite(TestTemplate))
|
s = AmpersandTemplate('this &gift is for &{who} &&')
|
||||||
return suite
|
self.assertEqual(s.substitute(gift='bud', who='you'),
|
||||||
|
'this bud is for you &')
|
||||||
|
self.assertRaises(KeyError, s.substitute)
|
||||||
|
self.assertEqual(s.safe_substitute(gift='bud', who='you'),
|
||||||
|
'this bud is for you &')
|
||||||
|
self.assertEqual(s.safe_substitute(),
|
||||||
|
'this &gift is for &{who} &')
|
||||||
|
s = AmpersandTemplate('this &gift is for &{who} &')
|
||||||
|
self.assertRaises(ValueError, s.substitute,
|
||||||
|
dict(gift='bud', who='you'))
|
||||||
|
self.assertRaises(ValueError, s.safe_substitute)
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
from test import test_support
|
from test import test_support
|
||||||
test_support.run_suite(suite())
|
test_classes = [TestTemplate,]
|
||||||
|
test_support.run_unittest(*test_classes)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
test_main()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue