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 diff --git a/rasa/core/utils.py b/rasa/core/utils.py index b4e658d3044d..4c5ba31aedcd 100644 --- a/rasa/core/utils.py +++ b/rasa/core/utils.py @@ -458,14 +458,15 @@ 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`. + Returns: An object with all matching values and `float` types replaced by `Decimal`s rounded to `round_digits` decimal places. """ if isinstance(obj, list): @@ -477,7 +478,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), round_digits) else: return obj diff --git a/tests/core/test_utils.py b/tests/core/test_utils.py index 4683a7f0e1d3..58da0f717a8b 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": 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}, @@ -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("1579507733.110757113") for t in d_replaced["list"]: assert isinstance(t, str) for f in d_replaced["list_of_floats"]: