diff --git a/src/pydase/utils/helpers.py b/src/pydase/utils/helpers.py index f5f83c2..7b685ab 100644 --- a/src/pydase/utils/helpers.py +++ b/src/pydase/utils/helpers.py @@ -122,16 +122,20 @@ def get_class_and_instance_attributes(obj: object) -> dict[str, Any]: def get_object_by_path_parts(target_obj: Any, path_parts: list[str]) -> Any: + """Gets nested attribute of `target_object` specified by `path_parts`. + + Raises: + AttributeError: Attribute does not exist. + KeyError: Key in dict does not exist. + IndexError: Index out of list range. + TypeError: List index in the path is not a valid integer. + """ for part in path_parts: if part.startswith("["): deserialized_part = parse_serialized_key(part) target_obj = target_obj[deserialized_part] else: - try: - target_obj = getattr(target_obj, part) - except AttributeError: - logger.debug("Attribute %a does not exist in the object.", part) - return None + target_obj = getattr(target_obj, part) return target_obj @@ -149,7 +153,10 @@ def get_object_attr_from_path(target_obj: Any, path: str) -> Any: the path does not exist, the function logs a debug message and returns None. Raises: - ValueError: If a list index in the path is not a valid integer. + AttributeError: Attribute does not exist. + KeyError: Key in dict does not exist. + IndexError: Index out of list range. + TypeError: List index in the path is not a valid integer. """ path_parts = parse_full_access_path(path) return get_object_by_path_parts(target_obj, path_parts) diff --git a/tests/utils/test_helpers.py b/tests/utils/test_helpers.py index 9fe9894..da7ff6e 100644 --- a/tests/utils/test_helpers.py +++ b/tests/utils/test_helpers.py @@ -103,9 +103,21 @@ def test_get_object_by_path_parts(path_parts: list[str], expected: Any) -> None: assert get_object_by_path_parts(service_instance, path_parts) == expected -def test_get_object_by_path_parts_error(caplog: pytest.LogCaptureFixture) -> None: - assert get_object_by_path_parts(service_instance, ["non_existent_attr"]) is None - assert "Attribute 'non_existent_attr' does not exist in the object." in caplog.text +@pytest.mark.parametrize( + "path_parts, expected_exception", + [ + (["non_existent_attr"], AttributeError), + (["dict_attr", '["non_existent_key"]'], KeyError), + (["list_attr", "[2]"], IndexError), + (["list_attr", "[1.0]"], TypeError), + (["list_attr", '["string_key"]'], TypeError), + ], +) +def test_get_object_by_path_parts_exception( + path_parts: list[str], expected_exception: type[Exception] +) -> None: + with pytest.raises(expected_exception): + get_object_by_path_parts(service_instance, path_parts) @pytest.mark.parametrize(