diff options
author | Daniel Sheffield <d.j.yotta@gmail.com> | 2023-03-29 06:31:03 +1300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-28 19:31:03 +0200 |
commit | c3ca1affc41db182873b6e98841def6213ad12d4 (patch) | |
tree | 521c2497ef99354f9d40601ff766eef72bb0220d | |
parent | 55b6a920553562c614b56541312ada053341e5cc (diff) | |
download | urwid-c3ca1affc41db182873b6e98841def6213ad12d4.tar.gz |
Resolve #499 and add tests (#500)
Resolves #499 - FloatEdit mangles decimals
-rw-r--r-- | urwid/numedit.py | 19 | ||||
-rw-r--r-- | urwid/tests/test_floatedit.py | 21 |
2 files changed, 26 insertions, 14 deletions
diff --git a/urwid/numedit.py b/urwid/numedit.py index 3152acb..0502fa6 100644 --- a/urwid/numedit.py +++ b/urwid/numedit.py @@ -21,7 +21,7 @@ from urwid import Edit -from decimal import Decimal +from decimal import Decimal, localcontext import re @@ -265,22 +265,13 @@ class FloatEdit(NumEdit): Return the numeric value of self.edit_text. """ if self.edit_text: - # integer part (before .) and fractional part (after .) - fmt = "{ip}.{fp}" - if self.significance: - # in case of preserved significance, construct the - # format string to fill with trailing 0 - fmt = "{{ip}}.{{fp:<0{sig}d}}".format(sig=self.significance) - # get the ip and fp, handles also the case that there is no '.' ip, fp = ([v for v in self.edit_text.split(self._decimalSeparator)] + [0])[0:2] - # in case the fp part surpasses the significance we round it - if self.significance and len(str(fp)) > self.significance: - fp = float(fp) / 10**(len(str(fp)) - self.significance) - fp = int(round(fp)) - - return Decimal(fmt.format(ip=ip, fp=int(fp))) + with localcontext() as ctx: + ctx = (self.significance or len(str(fp)))+1 + return Decimal(self.edit_text.replace( + self._decimalSeparator, '.')) * 1 return None diff --git a/urwid/tests/test_floatedit.py b/urwid/tests/test_floatedit.py new file mode 100644 index 0000000..77c581e --- /dev/null +++ b/urwid/tests/test_floatedit.py @@ -0,0 +1,21 @@ +import unittest +from urwid.numedit import FloatEdit +from decimal import Decimal, getcontext +from itertools import product +class FloatEditNoPreservePrecicionTest(unittest.TestCase): + def test(self): + for v in ('1.01', '2.5', '300', '4.100', '5.001'): + f = FloatEdit(preserveSignificance=False) + f.set_edit_text(v) + print(f.value(), Decimal(v)) + assert f.value() == Decimal(v), f'{f.value()} != {Decimal(v)}' + +class FloatEditPreservePrecicionTest(unittest.TestCase): + + def test(self): + for v, sig, sep in product(('1.010', '2.500', '300.000', '4.100', '5.001'), (1, 2, 3), ('.', ',')): + f = FloatEdit(preserveSignificance=True, default='0.' + '0'*sig, decimalSeparator=sep) + f.set_edit_text(v.replace('.', sep)) + getcontext().prec = sig+1 + print(f.value(), Decimal(v)) + assert str(f.value()) == str(Decimal(v) * 1), f'{str(f.value())} != {str(Decimal(v)*1)} (significance={sig})' |