diff --git a/src/nipanel/_convert.py b/src/nipanel/_convert.py index 9488f54..54888d9 100644 --- a/src/nipanel/_convert.py +++ b/src/nipanel/_convert.py @@ -54,6 +54,12 @@ def to_any(python_value: object) -> any_pb2.Any: """Convert a Python object to a protobuf Any.""" + best_matching_type = _get_best_matching_type(python_value) + converter = _CONVERTER_FOR_PYTHON_TYPE[best_matching_type] + return converter.to_protobuf_any(python_value) + + +def _get_best_matching_type(python_value: object) -> str: underlying_parents = type(python_value).mro() # This covers enum.IntEnum and similar container_type = None @@ -86,9 +92,7 @@ def to_any(python_value: object) -> any_pb2.Any: f"Unsupported type: ({container_type}, {payload_type}) with parents {underlying_parents}. Supported types are: {_SUPPORTED_PYTHON_TYPES}" ) _logger.debug(f"Best matching type for '{repr(python_value)}' resolved to {best_matching_type}") - - converter = _CONVERTER_FOR_PYTHON_TYPE[best_matching_type] - return converter.to_protobuf_any(python_value) + return best_matching_type def from_any(protobuf_any: any_pb2.Any) -> object: diff --git a/tests/unit/test_convert.py b/tests/unit/test_convert.py index a14a359..db97b2c 100644 --- a/tests/unit/test_convert.py +++ b/tests/unit/test_convert.py @@ -70,6 +70,51 @@ def test___python_panel_collection___to_any___valid_paneltype_value( assert unpack_dest.values == expected_value +# ======================================================== +# _get_best_matching_type() tests +# ======================================================== +@pytest.mark.parametrize( + "python_object, expected_type_string", + [ + (False, "bool"), + (b"mystr", "bytes"), + (456.2, "float"), + (123, "int"), + ("mystr", "str"), + ([False, False], "Collection.bool"), + ([b"mystr", b"mystr"], "Collection.bytes"), + ([456.2, 1.0], "Collection.float"), + ([123, 456], "Collection.int"), + (["mystr", "mystr"], "Collection.str"), + ((False, False), "Collection.bool"), + ((b"mystr", b"mystr"), "Collection.bytes"), + ((456.2, 1.0), "Collection.float"), + ((123, 456), "Collection.int"), + (("mystr", "mystr"), "Collection.str"), + ((False, False), "Collection.bool"), + ((b"mystr", b"mystr"), "Collection.bytes"), + ((456.2, 1.0), "Collection.float"), + ((123, 456), "Collection.int"), + (("mystr", "mystr"), "Collection.str"), + (set([False, True]), "Collection.bool"), + (set([b"mystr", b"mystr2"]), "Collection.bytes"), + (set([456.2, 1.0]), "Collection.float"), + (set([123, 456]), "Collection.int"), + (set(["mystr", "mystr2"]), "Collection.str"), + (frozenset([False, True]), "Collection.bool"), + (frozenset([b"mystr", b"mystr2"]), "Collection.bytes"), + (frozenset([456.2, 1.0]), "Collection.float"), + (frozenset([123, 456]), "Collection.int"), + (frozenset(["mystr", "mystr2"]), "Collection.str"), + ], +) +def test___various_python_objects___get_best_matching_type___returns_correct_type_string( + python_object: object, expected_type_string: str +) -> None: + type_string = nipanel._convert._get_best_matching_type(python_object) + assert type_string == expected_type_string + + # ======================================================== # Protobuf to Python # ========================================================