summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Sheffield <d.j.yotta@gmail.com>2023-03-29 06:31:03 +1300
committerGitHub <noreply@github.com>2023-03-28 19:31:03 +0200
commitc3ca1affc41db182873b6e98841def6213ad12d4 (patch)
tree521c2497ef99354f9d40601ff766eef72bb0220d
parent55b6a920553562c614b56541312ada053341e5cc (diff)
downloadurwid-c3ca1affc41db182873b6e98841def6213ad12d4.tar.gz
Resolve #499 and add tests (#500)
Resolves #499 - FloatEdit mangles decimals
-rw-r--r--urwid/numedit.py19
-rw-r--r--urwid/tests/test_floatedit.py21
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})'