Use locale.localize() and new format to format Decimal

This allows to use the new format syntax on Decimal which prevents a
conversion to float.
As locale.localize() is not yet added to released Python, we monkey patch
older version.
We also replace locale.format by locale.format_string as it has been
deprecated in Python 3.7.

issue8574
review282011002
This commit is contained in:
Cédric Krier committed 2020-01-20 11:26:30 +01:00
1 parent 3378ee4674
commit 6ec6f4edd8
10 files changed
+54 -25

No files matched your search

+22
View File
@@ -2,6 +2,7 @@
# this repository contains the full copyright notices and license terms.
__version__ = "5.5.0"
import gi
import locale
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
@@ -16,3 +17,24 @@ try:
import goocalendar
except ImportError:
pass
if not hasattr(locale, 'localize'):
def localize(formatted, grouping=False, monetary=False):
if '.' in formatted:
seps = 0
parts = formatted.split('.')
if grouping:
parts[0], seps = locale._group(parts[0], monetary=monetary)
decimal_point = locale.localeconv()[
monetary and 'mon_decimal_point' or 'decimal_point']
formatted = decimal_point.join(parts)
if seps:
formatted = locale._strip_padding(formatted, seps)
else:
seps = 0
if grouping:
formatted, seps = locale._group(formatted, monetary=monetary)
if seps:
formatted = locale._strip_padding(formatted, seps)
return formatted
setattr(locale, 'localize', localize)
+2 -1
View File
@@ -319,7 +319,8 @@ def format_value(field, value, target=None, context=None):
digit = len(str(value * factor).rstrip('0').split('.')[1])
except IndexError:
digit = 0
return locale.format('%.*f', (digit, value * factor or 0), True)
return locale.localize(
'{0:.{1}f}'.format(value * factor or 0, digit), True)
def format_selection():
selections = dict(field['selection'])
+2 -1
View File
@@ -56,7 +56,8 @@ def format(value, converter=None):
for (k, _), v in zip(converter[:-3], values):
if v:
text.append(locale.format('%d', v, True) + _get_separators()[k])
text.append(
locale.format_string('%d', v, True) + _get_separators()[k])
if any(values[-3:]) or not text:
time = '%02d:%02d' % tuple(values[-3:-1])
if values[-1] or value:
+4 -4
View File
@@ -367,14 +367,14 @@ class FloatField(Field):
value = record.value.get(self.name)
if value is not None:
digits = self.digits(record, factor=factor)
d = value * factor
if not isinstance(d, Decimal):
d = Decimal(repr(d))
if digits:
p = int(digits[1])
else:
d = value * factor
if not isinstance(d, Decimal):
d = Decimal(repr(d))
p = -int(d.as_tuple().exponent)
return locale.format('%.*f', (p, value * factor), True)
return locale.localize('{0:.{1}f}'.format(d, p), True)
else:
return ''
@@ -238,7 +238,7 @@ class DictIntegerEntry(DictEntry):
def set_value(self, value):
if value is not None:
txt_val = locale.format('%d', value, True)
txt_val = locale.format_string('%d', value, True)
else:
txt_val = ''
self.widget.set_text(txt_val)
@@ -275,7 +275,8 @@ class DictFloatEntry(DictIntegerEntry):
self.widget.digits = None
self.widget.set_width_chars(self.width)
if value is not None:
txt_val = locale.format('%.*f', (digits[1], value), True)
txt_val = locale.localize(
'{0:.{1}f}'.format(value, digits[1]), True)
else:
txt_val = ''
self.widget.set_text(txt_val)
@@ -93,7 +93,8 @@ class Bar(Graph):
label = common.timedelta.format(
datetime.timedelta(seconds=bar.yval), converter)
else:
label = locale.format('%.2f', bar.yval, True)
label = locale.localize(
'{:.2f}'.format(bar.yval), True)
label += '\n'
label += str(self.labels[bar.xname])
self.popup.set_text(label)
@@ -178,7 +178,7 @@ class Graph(Gtk.DrawingArea):
for i in range(int(self.yrange / base) + 1):
val = int(self.minyval / base) * base + i * base
h = (val - self.minyval) * self.yscale
label = locale.format('%.2f', val, True)
label = locale.localize('{:.2f}'.format(val), True)
ylabels.append((h, label))
return ylabels
@@ -201,7 +201,8 @@ class Line(Graph):
yfields_timedelta[point.yname])
label += common.timedelta.format(point.yval, converter)
else:
label += locale.format('%.2f', point.yval, True)
label += locale.localize(
'{:2f}'.format(point.yval), True)
label += '\n'
label += str(self.labels[point.xname])
self.popup.set_text(label)
@@ -33,7 +33,7 @@ class Pie(Graph):
math.cos(normalisedAngle) * (self.radius + 10)
label = '%s (%s%%)' % (self.labels[slice.xname],
locale.format('%.2f', slice.fraction * 100))
locale.localize('{:.2f}'.format(slice.fraction * 100)))
extents = cr.text_extents(label)
labelWidth = extents[2]
labelHeight = extents[3]
@@ -156,12 +156,13 @@ class Pie(Graph):
sum = common.timedelta.format(
datetime.timedelta(seconds=self.sum), converter)
else:
value = locale.format('%.2f',
slice.fraction * self.sum)
sum = locale.format('%.2f', self.sum)
label = '%s (%s%%)\n%s/%s' % (self.labels[slice.xname],
locale.format('%.2f', slice.fraction * 100),
value, sum)
value = locale.localize(
'{:.2f}'.format(slice.fraction * self.sum))
sum = locale.localize('{:.2f}'.format(self.sum))
label = '%s (%s%%)\n%s/%s' % (
self.labels[slice.xname],
locale.localize('{:.2f}'.format(slice.fraction * 100)),
value, sum)
self.popup.set_text(label)
self.queue_draw()
else:
+8 -7
View File
@@ -1100,14 +1100,15 @@ class ViewTree(View):
selected_sum = common.timedelta.format(
selected_sum, converter)
sum_ = common.timedelta.format(sum_, converter)
elif digit:
selected_sum = locale.format(
'%.*f', (digit, selected_sum or 0), True)
sum_ = locale.format('%.*f', (digit, sum_ or 0), True)
elif digit is not None:
selected_sum = locale.localize(
'{0:.{1}f}'.format(selected_sum or 0, digit), True)
sum_ = locale.localize(
'{0:.{1}f}'.format(sum_ or 0, digit), True)
else:
selected_sum = locale.format(
'%s', selected_sum or 0, True)
sum_ = locale.format('%s', sum_ or 0, True)
selected_sum = locale.localize(
'{}'.format(selected_sum or 0), True)
sum_ = locale.localize('{}'.format(sum_ or 0), True)
text = '%s / %s' % (selected_sum, sum_)
else: