From e7acd44247a3457b520adadee4d1b9d3ddbfd426 Mon Sep 17 00:00:00 2001 From: Dom Sammut Date: Mon, 20 Jan 2020 21:15:33 +1100 Subject: [PATCH 1/6] Round Decimal to 9 places to support DynamoDB constraints --- rasa/core/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rasa/core/utils.py b/rasa/core/utils.py index b4e658d3044d..732168c57564 100644 --- a/rasa/core/utils.py +++ b/rasa/core/utils.py @@ -465,7 +465,7 @@ def replace_floats_with_decimals(obj: Union[List, Dict]) -> Any: Args: obj: A `List` or `Dict` object. - Returns: An object with all matching values and `float` type replaced by `Decimal`. + Returns: An object with all matching values and `float` type replaced by `Decimal` rounded to 9 decimal places. """ if isinstance(obj, list): @@ -477,7 +477,7 @@ def replace_floats_with_decimals(obj: Union[List, Dict]) -> Any: obj[j] = replace_floats_with_decimals(obj[j]) return obj elif isinstance(obj, float): - return Decimal(obj) + return round(Decimal(obj), 9) else: return obj From 07d1d37a0a8900475b741ffde64266676e04c31c Mon Sep 17 00:00:00 2001 From: Dom Sammut Date: Mon, 20 Jan 2020 21:36:09 +1100 Subject: [PATCH 2/6] Add changelog --- changelog/5092.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/5092.bugfix.rst diff --git a/changelog/5092.bugfix.rst b/changelog/5092.bugfix.rst new file mode 100644 index 000000000000..e8a56cd132ca --- /dev/null +++ b/changelog/5092.bugfix.rst @@ -0,0 +1 @@ +DynamoDB tracker store decimal values will now be rounded on save. Previously values exceeding 38 digits caused an unhandled error. \ No newline at end of file From 11789c070a953d306f8b867fd13d6cb0ba0f3152 Mon Sep 17 00:00:00 2001 From: Dom Sammut Date: Mon, 20 Jan 2020 22:57:26 +1100 Subject: [PATCH 3/6] Add test for rounding a long float value --- tests/core/test_utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/core/test_utils.py b/tests/core/test_utils.py index 4683a7f0e1d3..0a517512bd65 100644 --- a/tests/core/test_utils.py +++ b/tests/core/test_utils.py @@ -98,6 +98,7 @@ def test_float_conversion_to_decimal(): d = { "int": -1, "float": 2.1, + "float_round": 0.918040672051180450807805755175650119781494140625, "list": ["one", "two"], "list_of_floats": [1.0, -2.1, 3.2], "nested_dict_with_floats": {"list_with_floats": [4.5, -5.6], "float": 6.7}, @@ -106,6 +107,7 @@ def test_float_conversion_to_decimal(): assert isinstance(d_replaced["int"], int) assert isinstance(d_replaced["float"], Decimal) + assert d_replaced["float_round"] == Decimal('0.918040672') for t in d_replaced["list"]: assert isinstance(t, str) for f in d_replaced["list_of_floats"]: From 8d1823e48071ca304aad065779b0877595bb0b41 Mon Sep 17 00:00:00 2001 From: Dom Sammut Date: Tue, 21 Jan 2020 06:59:51 +1100 Subject: [PATCH 4/6] Requested changes - Update test to use a time.time() value instead of a confidence score - Add parameter to replace_floats_with_decimals() for setting the rounding precision defaulting to 9 decimal places --- rasa/core/utils.py | 9 ++++++--- tests/core/test_utils.py | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/rasa/core/utils.py b/rasa/core/utils.py index 732168c57564..27b26a364530 100644 --- a/rasa/core/utils.py +++ b/rasa/core/utils.py @@ -458,14 +458,17 @@ def handler(fut: Future) -> None: return handler -def replace_floats_with_decimals(obj: Union[List, Dict]) -> Any: +def replace_floats_with_decimals( + obj: Union[List, Dict], round_digits: int = 9 +) -> Any: """ Utility method to recursively walk a dictionary or list converting all `float` to `Decimal` as required by DynamoDb. Args: obj: A `List` or `Dict` object. + round_digits: A int value to set the rounding precision of Decimal values. - Returns: An object with all matching values and `float` type replaced by `Decimal` rounded to 9 decimal places. + Returns: An object with all matching values and `float` types replaced by `Decimal`s rounded to 9 decimal places. """ if isinstance(obj, list): @@ -477,7 +480,7 @@ def replace_floats_with_decimals(obj: Union[List, Dict]) -> Any: obj[j] = replace_floats_with_decimals(obj[j]) return obj elif isinstance(obj, float): - return round(Decimal(obj), 9) + return round(Decimal(obj), round_digits) else: return obj diff --git a/tests/core/test_utils.py b/tests/core/test_utils.py index 0a517512bd65..58da0f717a8b 100644 --- a/tests/core/test_utils.py +++ b/tests/core/test_utils.py @@ -98,7 +98,7 @@ def test_float_conversion_to_decimal(): d = { "int": -1, "float": 2.1, - "float_round": 0.918040672051180450807805755175650119781494140625, + "float_round": 1579507733.1107571125030517578125, "list": ["one", "two"], "list_of_floats": [1.0, -2.1, 3.2], "nested_dict_with_floats": {"list_with_floats": [4.5, -5.6], "float": 6.7}, @@ -107,7 +107,7 @@ def test_float_conversion_to_decimal(): assert isinstance(d_replaced["int"], int) assert isinstance(d_replaced["float"], Decimal) - assert d_replaced["float_round"] == Decimal('0.918040672') + assert d_replaced["float_round"] == Decimal("1579507733.110757113") for t in d_replaced["list"]: assert isinstance(t, str) for f in d_replaced["list_of_floats"]: From 35bce61f7ff982c1dc8348c1c4530a756a7c3c02 Mon Sep 17 00:00:00 2001 From: Dom Sammut Date: Tue, 21 Jan 2020 08:25:20 +1100 Subject: [PATCH 5/6] Lint fix :) --- rasa/core/utils.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/rasa/core/utils.py b/rasa/core/utils.py index 27b26a364530..698c96b88467 100644 --- a/rasa/core/utils.py +++ b/rasa/core/utils.py @@ -458,9 +458,7 @@ def handler(fut: Future) -> None: return handler -def replace_floats_with_decimals( - obj: Union[List, Dict], round_digits: int = 9 -) -> Any: +def replace_floats_with_decimals(obj: Union[List, Dict], round_digits: int = 9) -> Any: """ Utility method to recursively walk a dictionary or list converting all `float` to `Decimal` as required by DynamoDb. From fbcbab2e6e2aa9077a9a6811fb2cee4f759d6fb3 Mon Sep 17 00:00:00 2001 From: Dom Sammut Date: Wed, 22 Jan 2020 07:36:13 +1100 Subject: [PATCH 6/6] Update rasa/core/utils.py with documentation change Co-Authored-By: Tobias Wochinger --- rasa/core/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rasa/core/utils.py b/rasa/core/utils.py index 698c96b88467..4c5ba31aedcd 100644 --- a/rasa/core/utils.py +++ b/rasa/core/utils.py @@ -466,7 +466,7 @@ def replace_floats_with_decimals(obj: Union[List, Dict], round_digits: int = 9) obj: A `List` or `Dict` object. round_digits: A int value to set the rounding precision of Decimal values. - Returns: An object with all matching values and `float` types replaced by `Decimal`s rounded to 9 decimal places. + Returns: An object with all matching values and `float` types replaced by `Decimal`s rounded to `round_digits` decimal places. """ if isinstance(obj, list):