]> granicus.if.org Git - python/commitdiff
Patch #415777: new grouping strategy.
authorMartin v. Löwis <martin@v.loewis.de>
Fri, 13 Apr 2001 08:09:50 +0000 (08:09 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Fri, 13 Apr 2001 08:09:50 +0000 (08:09 +0000)
fixes bug #414940, and redoes the fix for #129417 in a different way.
It also fixes a number of other problems with locale-specific formatting:
If there is leading or trailing spaces, then no grouping should be applied
in the spaces, and the total length of the string should not be changed
due to grouping.
Also added test case which works only if the en_US locale is available.

Lib/locale.py
Lib/test/output/test_locale [new file with mode: 0644]
Lib/test/test_locale.py [new file with mode: 0644]

index d26560d69d7ee83d02f7f4f3b1dc8244ac751ada..f88803c5f3fd1d9871093050e630954f778e4b0b 100644 (file)
@@ -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 (file)
index 0000000..602825e
--- /dev/null
@@ -0,0 +1 @@
+test_locale
diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py
new file mode 100644 (file)
index 0000000..4fb042a
--- /dev/null
@@ -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)