Merged revisions 80512 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r80512 | r.david.murray | 2010-04-26 17:17:14 -0400 (Mon, 26 Apr 2010) | 7 lines

  Issue #6656: fix locale.format_string to handle escaped percents and mappings.

  Refactors format_string.  Includes tests for the two problems noted in
  the issue, but as far as I can see there are no other tests that confirm
  that format_string conforms to normal % formatting rules.
........
This commit is contained in:
R. David Murray 2010-04-27 02:45:53 +00:00
parent 469b1f0d50
commit ad78d15acc
3 changed files with 45 additions and 14 deletions

View file

@ -227,22 +227,30 @@ def format_string(f, val, grouping=False):
percents = list(_percent_re.finditer(f)) percents = list(_percent_re.finditer(f))
new_f = _percent_re.sub('%s', f) new_f = _percent_re.sub('%s', f)
if isinstance(val, tuple): if isinstance(val, collections.Mapping):
new_val = list(val) new_val = []
for perc in percents:
if perc.group()[-1]=='%':
new_val.append('%')
else:
new_val.append(format(perc.group(), val, grouping))
else:
if not isinstance(val, tuple):
val = (val,)
new_val = []
i = 0 i = 0
for perc in percents: for perc in percents:
starcount = perc.group('modifiers').count('*') if perc.group()[-1]=='%':
new_val[i] = format(perc.group(), new_val[i], grouping, False, *new_val[i+1:i+1+starcount]) new_val.append('%')
del new_val[i+1:i+1+starcount] else:
i += (1 + starcount) starcount = perc.group('modifiers').count('*')
val = tuple(new_val) new_val.append(_format(perc.group(),
elif isinstance(val, collections.Mapping): val[i],
for perc in percents: grouping,
key = perc.group("key") False,
val[key] = format(perc.group(), val[key], grouping) *val[i+1:i+1+starcount]))
else: i += (1 + starcount)
# val is a single value val = tuple(new_val)
val = format(percents[0].group(), val, grouping)
return new_f % val return new_f % val

View file

@ -236,6 +236,25 @@ class TestFormatPatternArg(unittest.TestCase):
self.assertRaises(ValueError, locale.format, " %f", 'foo') self.assertRaises(ValueError, locale.format, " %f", 'foo')
self.assertRaises(ValueError, locale.format, "%fg", 'foo') self.assertRaises(ValueError, locale.format, "%fg", 'foo')
self.assertRaises(ValueError, locale.format, "%^g", 'foo') self.assertRaises(ValueError, locale.format, "%^g", 'foo')
self.assertRaises(ValueError, locale.format, "%f%%", 'foo')
class TestLocaleFormatString(unittest.TestCase):
"""General tests on locale.format_string"""
def test_percent_escape(self):
self.assertEqual(locale.format_string('%f%%', 1.0), '%f%%' % 1.0)
self.assertEqual(locale.format_string('%d %f%%d', (1, 1.0)),
'%d %f%%d' % (1, 1.0))
self.assertEqual(locale.format_string('%(foo)s %%d', {'foo': 'bar'}),
('%(foo)s %%d' % {'foo': 'bar'}))
def test_mapping(self):
self.assertEqual(locale.format_string('%(foo)s bing.', {'foo': 'bar'}),
('%(foo)s bing.' % {'foo': 'bar'}))
self.assertEqual(locale.format_string('%(foo)s', {'foo': 'bar'}),
('%(foo)s' % {'foo': 'bar'}))
class TestNumberFormatting(BaseLocalizedTest, EnUSNumberFormatting): class TestNumberFormatting(BaseLocalizedTest, EnUSNumberFormatting):
@ -377,6 +396,7 @@ def test_main():
tests = [ tests = [
TestMiscellaneous, TestMiscellaneous,
TestFormatPatternArg, TestFormatPatternArg,
TestLocaleFormatString,
TestEnUSNumberFormatting, TestEnUSNumberFormatting,
TestCNumberFormatting, TestCNumberFormatting,
TestFrFRNumberFormatting, TestFrFRNumberFormatting,

View file

@ -339,6 +339,9 @@ C-API
Library Library
------- -------
- Issue #6656: fix locale.format_string to handle escaped percents
and mappings.
- Issue #2302: Fix a race condition in SocketServer.BaseServer.shutdown, - Issue #2302: Fix a race condition in SocketServer.BaseServer.shutdown,
where the method could block indefinitely if called just before the where the method could block indefinitely if called just before the
event loop started running. This also fixes the occasional freezes event loop started running. This also fixes the occasional freezes