diff --git a/sdk/python/kfp/components/_data_passing.py b/sdk/python/kfp/components/_data_passing.py index 10cf2e27b76..b4e022dfa78 100644 --- a/sdk/python/kfp/components/_data_passing.py +++ b/sdk/python/kfp/components/_data_passing.py @@ -44,11 +44,19 @@ def _deserialize_bool(s) -> bool: _bool_deserializer_code = _deserialize_bool.__name__ +def _serialize_json(obj) -> str: + import json + return json.dumps(obj) + + _converters = [ Converter([str], ['String', 'str'], str, 'str', None), Converter([int], ['Integer', 'int'], str, 'int', None), Converter([float], ['Float', 'float'], str, 'float', None), Converter([bool], ['Boolean', 'bool'], str, _bool_deserializer_code, _bool_deserializer_definitions), + Converter([list], ['JsonArray', 'List', 'list'], _serialize_json, 'json.loads', 'import json'), # ! JSON map keys are always strings. Python converts all keys to strings without warnings + Converter([dict], ['JsonObject', 'Dictionary', 'Dict', 'dict'], _serialize_json, 'json.loads', 'import json'), # ! JSON map keys are always strings. Python converts all keys to strings without warnings + Converter([], ['Json'], _serialize_json, 'json.loads', 'import json'), ] diff --git a/sdk/python/tests/components/test_python_op.py b/sdk/python/tests/components/test_python_op.py index a5a841f9cf0..d3d168a1b17 100644 --- a/sdk/python/tests/components/test_python_op.py +++ b/sdk/python/tests/components/test_python_op.py @@ -386,6 +386,25 @@ def assert_values_are_true_false( self.helper_test_2_in_1_out_component_using_local_call(func, op, arguments=[True, False]) + def test_handling_list_dict_arguments(self): + def assert_values_are_same( + list_param: list, + dict_param: dict, + ) -> int: + import unittest + unittest.TestCase().assertEqual(list_param, ["string", 1, 2.2, True, False, None, [3, 4], {'s': 5}]) + unittest.TestCase().assertEqual(dict_param, {'str': "string", 'int': 1, 'float': 2.2, 'false': False, 'true': True, 'none': None, 'list': [3, 4], 'dict': {'s': 4}}) + return 1 + + # ! JSON map keys are always strings. Python converts all keys to strings without warnings + func = assert_values_are_same + op = comp.func_to_container_op(func) + self.helper_test_2_in_1_out_component_using_local_call(func, op, arguments=[ + ["string", 1, 2.2, True, False, None, [3, 4], {'s': 5}], + {'str': "string", 'int': 1, 'float': 2.2, 'false': False, 'true': True, 'none': None, 'list': [3, 4], 'dict': {'s': 4}}, + ]) + + def test_end_to_end_python_component_pipeline_compilation(self): import kfp.components as comp