Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/nipanel/_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
45 changes: 45 additions & 0 deletions tests/unit/test_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
# ========================================================
Expand Down