From c55edcd97f4137041fa003e230eed0290014ba53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dtalo=20Johnny?= Date: Tue, 31 Dec 2024 10:13:31 -0300 Subject: [PATCH] fix: resolve data keyword conflict in template formatting (#5483) * fix: resolve data keyword conflict in template formatting * refactor: simplify code * test: add unit tests * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- src/backend/base/langflow/helpers/data.py | 7 +- src/backend/tests/unit/helpers/test_data.py | 114 ++++++++++++++++++++ 2 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 src/backend/tests/unit/helpers/test_data.py diff --git a/src/backend/base/langflow/helpers/data.py b/src/backend/base/langflow/helpers/data.py index af65adcff..07a3b65cc 100644 --- a/src/backend/base/langflow/helpers/data.py +++ b/src/backend/base/langflow/helpers/data.py @@ -49,8 +49,13 @@ def data_to_text_list(template: str, data: Data | list[Data]) -> tuple[list[str] Data(text=value) if not isinstance(value, Data) else value for value in data ] + formatted_text = [] + for value in data_: + # Prevent conflict with 'data' keyword in template formatting + kwargs = value.data.copy() + data = kwargs.pop("data", value.data) + formatted_text.append(template.format(data=data, **kwargs)) - formatted_text = [template.format(data=value.data, **value.data) for value in data_] return formatted_text, data_ diff --git a/src/backend/tests/unit/helpers/test_data.py b/src/backend/tests/unit/helpers/test_data.py new file mode 100644 index 000000000..82368951f --- /dev/null +++ b/src/backend/tests/unit/helpers/test_data.py @@ -0,0 +1,114 @@ +import pytest +from langflow.helpers.data import data_to_text_list +from langflow.schema import Data + + +@pytest.mark.parametrize( + ( + "template", + "data", + "expected", + ), + [ + ( + "{name} is {age} years old", + Data(data={"name": "Alice", "age": 25}), + (["Alice is 25 years old"], [Data(data={"name": "Alice", "age": 25})]), + ), + ( + "{name} is {age} years old", + [ + Data(data={"name": "Alice", "age": 25}), + Data(data={"name": "Bob", "age": 30}), + Data(data={"name": "Alex", "age": 35}), + ], + ( + [ + "Alice is 25 years old", + "Bob is 30 years old", + "Alex is 35 years old", + ], + [ + Data(data={"name": "Alice", "age": 25}), + Data(data={"name": "Bob", "age": 30}), + Data(data={"name": "Alex", "age": 35}), + ], + ), + ), + ], +) +def test_data_to_text_list(template, data, expected): + result = data_to_text_list(template, data) + assert result == expected + + +def test_data_to_text_list__template_empty(): + template = "" + data = Data(data={"key": "value"}) + + result = data_to_text_list(template, data) + + assert isinstance(result, tuple) + assert len(result) == 2 + assert isinstance(result[0], list) + assert isinstance(result[1], list) + assert template in result[0] + assert data in result[1] + + +def test_data_to_text_list__template_without_placeholder(): + template = "My favorite color is gray" + data = Data(data={"color": "silver"}) + + result = data_to_text_list(template, data) + + assert isinstance(result, tuple) + assert len(result) == 2 + assert isinstance(result[0], list) + assert isinstance(result[1], list) + assert template in result[0] + assert data in result[1] + + +def test_data_to_text_list__template_without_placeholder_and_data_attribute_empty(): + template = "My favorite color is gray" + data_list = [Data(data={})] + + result = data_to_text_list(template, data_list) + + assert isinstance(result, tuple) + assert len(result) == 2 + assert isinstance(result[0], list) + assert isinstance(result[1], list) + assert template in result[0] + assert data_list == result[1] + + +def test_data_to_text_list__template_wrong_placeholder(): + template = "My favorite color is {color}" + data = Data(data={"fruit": "apple"}) + + with pytest.raises(KeyError): + data_to_text_list(template, data) + + +def test_data_to_text_list__data_with_data_attribute_empty(): + template = "My favorite color is {color}" + data = Data(data={}) + + with pytest.raises(KeyError): + data_to_text_list(template, data) + + +def test_data_to_text_list__data_contains_nested_data_key(): + template = "My data is: {data}" + data = Data(data={"data": {"key": "value"}}) + + result = data_to_text_list(template, data) + + assert isinstance(result, tuple) + assert len(result) == 2 + assert isinstance(result[0], list) + assert isinstance(result[1], list) + assert template not in result[0] + assert data in result[1]