From fd8d96c5355669edf0a47afce662345e4dc38657 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 14 Apr 2022 14:58:09 -0400 Subject: [PATCH 1/8] fix decimal precision issue --- tabulate.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tabulate.py b/tabulate.py index 0579fb3..d89bdfd 100644 --- a/tabulate.py +++ b/tabulate.py @@ -5,6 +5,7 @@ from __future__ import print_function from __future__ import unicode_literals from collections import namedtuple +from decimal import Decimal import sys import re import math @@ -996,7 +997,7 @@ def _format(val, valtype, floatfmt, missingval="", has_invisible=True): formatted_val = format(float(raw_val), floatfmt) return val.replace(raw_val, formatted_val) else: - return format(float(val), floatfmt) + return format(Decimal(val), floatfmt) else: return "{0}".format(val) From ad23d3778b13a326ed86cbe63b7e20a0a9acdcb8 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 14 Apr 2022 15:04:53 -0400 Subject: [PATCH 2/8] fix other float to Decimal --- tabulate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tabulate.py b/tabulate.py index d89bdfd..2e77ebe 100644 --- a/tabulate.py +++ b/tabulate.py @@ -994,7 +994,7 @@ def _format(val, valtype, floatfmt, missingval="", has_invisible=True): ) if is_a_colored_number: raw_val = _strip_invisible(val) - formatted_val = format(float(raw_val), floatfmt) + formatted_val = format(Decimal(raw_val), floatfmt) return val.replace(raw_val, formatted_val) else: return format(Decimal(val), floatfmt) From dac53ae286dd59b4f6d61e617f1e5f0c68c77c21 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 14 Apr 2022 15:59:00 -0400 Subject: [PATCH 3/8] fix float precision --- tabulate.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tabulate.py b/tabulate.py index 2e77ebe..9e91f24 100644 --- a/tabulate.py +++ b/tabulate.py @@ -5,7 +5,7 @@ from __future__ import print_function from __future__ import unicode_literals from collections import namedtuple -from decimal import Decimal +from decimal import Decimal, getcontext, setcontext, Context import sys import re import math @@ -993,11 +993,23 @@ def _format(val, valtype, floatfmt, missingval="", has_invisible=True): val, (_text_type, _binary_type) ) if is_a_colored_number: + print("HIIIIII", val) raw_val = _strip_invisible(val) - formatted_val = format(Decimal(raw_val), floatfmt) + formatted_val = format(Decimal(str(raw_val)), floatfmt) return val.replace(raw_val, formatted_val) else: - return format(Decimal(val), floatfmt) + context = Context(clamp=1, prec=6) + setcontext(context) + try: + if "f" in floatfmt: + if int(Decimal(val)) == Decimal(val): + val = int(Decimal(val, context=context)) + val = Decimal(str(val), context=context) + else: + val = float(val) + except (OverflowError, ValueError): + val = float(val) + return format(val, floatfmt) else: return "{0}".format(val) From 07e9ef669cfcfd927db6e048378813b625be09f0 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 14 Apr 2022 16:05:44 -0400 Subject: [PATCH 4/8] add test --- test/test_output.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/test_output.py b/test/test_output.py index eed4489..1f103f2 100644 --- a/test/test_output.py +++ b/test/test_output.py @@ -1428,6 +1428,12 @@ def test_floatfmt_multi(): assert_equal(expected, result) +def test_floatfmt_precision(): + result = tabulate([[99999998999.999980]], floatfmt=".6f", tablefmt="plain") + expected = "99999998999.999980" + assert_equal(expected, result) + + def test_colalign_multi(): "Output: string columns with custom colalign" result = tabulate( From 810e744ba5cdd7a0479041e1fccff2d75a9703de Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 14 Apr 2022 16:06:27 -0400 Subject: [PATCH 5/8] clean up --- tabulate.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tabulate.py b/tabulate.py index 9e91f24..f5cd51f 100644 --- a/tabulate.py +++ b/tabulate.py @@ -5,7 +5,7 @@ from __future__ import print_function from __future__ import unicode_literals from collections import namedtuple -from decimal import Decimal, getcontext, setcontext, Context +from decimal import Decimal import sys import re import math @@ -993,18 +993,15 @@ def _format(val, valtype, floatfmt, missingval="", has_invisible=True): val, (_text_type, _binary_type) ) if is_a_colored_number: - print("HIIIIII", val) raw_val = _strip_invisible(val) - formatted_val = format(Decimal(str(raw_val)), floatfmt) + formatted_val = format(float(val), floatfmt) return val.replace(raw_val, formatted_val) else: - context = Context(clamp=1, prec=6) - setcontext(context) try: if "f" in floatfmt: if int(Decimal(val)) == Decimal(val): - val = int(Decimal(val, context=context)) - val = Decimal(str(val), context=context) + val = int(Decimal(val)) + val = Decimal(str(val)) else: val = float(val) except (OverflowError, ValueError): From 9990531aa8da61781873d139528adae03bc7b270 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 14 Apr 2022 16:10:07 -0400 Subject: [PATCH 6/8] fix bug --- tabulate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tabulate.py b/tabulate.py index f5cd51f..ad7f17e 100644 --- a/tabulate.py +++ b/tabulate.py @@ -994,7 +994,7 @@ def _format(val, valtype, floatfmt, missingval="", has_invisible=True): ) if is_a_colored_number: raw_val = _strip_invisible(val) - formatted_val = format(float(val), floatfmt) + formatted_val = format(float(raw_val), floatfmt) return val.replace(raw_val, formatted_val) else: try: From d4f0d919d22fad8d95501d67f51b17dc6b3daec3 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 14 Apr 2022 16:17:09 -0400 Subject: [PATCH 7/8] expand test --- tabulate.py | 4 +--- test/test_output.py | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tabulate.py b/tabulate.py index ad7f17e..ed8adec 100644 --- a/tabulate.py +++ b/tabulate.py @@ -998,9 +998,7 @@ def _format(val, valtype, floatfmt, missingval="", has_invisible=True): return val.replace(raw_val, formatted_val) else: try: - if "f" in floatfmt: - if int(Decimal(val)) == Decimal(val): - val = int(Decimal(val)) + if "f" in floatfmt and float('-inf') < float(val) < float('inf'): val = Decimal(str(val)) else: val = float(val) diff --git a/test/test_output.py b/test/test_output.py index 1f103f2..1820878 100644 --- a/test/test_output.py +++ b/test/test_output.py @@ -1429,8 +1429,8 @@ def test_floatfmt_multi(): def test_floatfmt_precision(): - result = tabulate([[99999998999.999980]], floatfmt=".6f", tablefmt="plain") - expected = "99999998999.999980" + result = tabulate([[99999998999.999980, 1234.5, 1.2345678, "inf"]], floatfmt=".6f", tablefmt="plain") + expected = "99999998999.999980 1234.500000 1.234568 inf" assert_equal(expected, result) From 0b1d392ee81389eb3c0f138b65e4457a56b9acfc Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 14 Apr 2022 17:10:17 -0400 Subject: [PATCH 8/8] fix test to get around weird precision issues in python2.7 --- test/test_output.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_output.py b/test/test_output.py index 1820878..38f1766 100644 --- a/test/test_output.py +++ b/test/test_output.py @@ -1429,7 +1429,7 @@ def test_floatfmt_multi(): def test_floatfmt_precision(): - result = tabulate([[99999998999.999980, 1234.5, 1.2345678, "inf"]], floatfmt=".6f", tablefmt="plain") + result = tabulate([["99999998999.999980", 1234.5, 1.2345678, "inf"]], floatfmt=".6f", tablefmt="plain") expected = "99999998999.999980 1234.500000 1.234568 inf" assert_equal(expected, result)