diff --git a/Lib/locale.py b/Lib/locale.py index d26560d69d7..f88803c5f3f 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -95,6 +95,12 @@ def _group(s): grouping=conv['grouping'] if not grouping:return s result="" + seps = 0 + spaces = "" + if s[-1] == ' ': + sp = s.find(' ') + spaces = s[sp:] + s = s[:sp] while s and grouping: # if grouping is -1, we are done if grouping[0]==CHAR_MAX: @@ -106,34 +112,48 @@ def _group(s): grouping=grouping[1:] if result: result=s[-group:]+conv['thousands_sep']+result + seps += 1 else: result=s[-group:] s=s[:-group] + if s and s[-1] not in "0123456789": + # the leading string is only spaces and signs + return s+result+spaces,seps if not result: - return s + return s+spaces,seps if s: result=s+conv['thousands_sep']+result - return result + seps += 1 + return result+spaces,seps def format(f,val,grouping=0): """Formats a value in the same way that the % formatting would use, but takes the current locale into account. Grouping is applied if the third parameter is true.""" - result = f % abs(val) + result = f % val fields = result.split(".") + seps = 0 if grouping: - fields[0]=_group(fields[0]) + fields[0],seps=_group(fields[0]) if len(fields)==2: - res = fields[0]+localeconv()['decimal_point']+fields[1] + result = fields[0]+localeconv()['decimal_point']+fields[1] elif len(fields)==1: - res = fields[0] + result = fields[0] else: raise Error, "Too many decimal points in result string" - if val < 0: - return '-'+res - else: - return res + while seps: + # If the number was formatted for a specific width, then it + # might have been filled with spaces to the left or right. If + # so, kill as much spaces as there where separators. + # Leading zeroes as fillers are not yet dealt with, as it is + # not clear how they should interact with grouping. + sp = result.find(" ") + if sp==-1:break + result = result[:sp]+result[sp+1:] + seps -= 1 + + return result def str(val): """Convert float to integer, taking the locale into account.""" diff --git a/Lib/test/output/test_locale b/Lib/test/output/test_locale new file mode 100644 index 00000000000..602825e611d --- /dev/null +++ b/Lib/test/output/test_locale @@ -0,0 +1 @@ +test_locale diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py new file mode 100644 index 00000000000..4fb042a7998 --- /dev/null +++ b/Lib/test/test_locale.py @@ -0,0 +1,37 @@ +from test_support import verbose +import locale + +oldlocale = locale.setlocale(locale.LC_NUMERIC) + +try: + locale.setlocale(locale.LC_NUMERIC, "en_US") +except locale.Error: + raise ImportError, "test locale en_US not supported" + +def testformat(formatstr, value, grouping = 0, output=None): + if verbose: + if output: + print "%s %% %s =? %s ..." %\ + (repr(formatstr), repr(value), repr(output)), + else: + print "%s %% %s works? ..." % (repr(formatstr), repr(value)), + result = locale.format(formatstr, value, grouping = grouping) + if output and result != output: + if verbose: + print 'no' + print "%s %% %s == %s != %s" %\ + (repr(formatstr), repr(value), repr(result), repr(output)) + else: + if verbose: + print "yes" + +try: + testformat("%f", 1024, grouping=1, output='1,024.000000') + testformat("%f", 102, grouping=1, output='102.000000') + testformat("%f", -42, grouping=1, output='-42.000000') + testformat("%+f", -42, grouping=1, output='-42.000000') + testformat("%20.f", -42, grouping=1, output=' -42') + testformat("%+10.f", -4200, grouping=1, output=' -4,200') + testformat("%-10.f", 4200, grouping=1, output='4,200 ') +finally: + locale.setlocale(locale.LC_NUMERIC, oldlocale)