From da08999c63a58778c99de5b96e42350c8b81e061 Mon Sep 17 00:00:00 2001 From: David Dallakyan Date: Sat, 15 Aug 2026 13:49:27 +0400 Subject: [PATCH] fix: treat empty property strings as present in helpers Walrus `.get` truthiness treated "" as missing. Match the is-not-None check from #3660/#3745 so a present empty value is parsed (or returned) instead of falling back. --- pyiceberg/utils/properties.py | 8 +++---- tests/utils/test_properties.py | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/pyiceberg/utils/properties.py b/pyiceberg/utils/properties.py index 2a95b39a50..8d958cf9e9 100644 --- a/pyiceberg/utils/properties.py +++ b/pyiceberg/utils/properties.py @@ -30,7 +30,7 @@ def property_as_int( property_name: str, default: int | None = None, ) -> int | None: - if value := properties.get(property_name): + if (value := properties.get(property_name)) is not None: try: return int(value) except ValueError as e: @@ -44,7 +44,7 @@ def property_as_float( property_name: str, default: float | None = None, ) -> float | None: - if value := properties.get(property_name): + if (value := properties.get(property_name)) is not None: try: return float(value) except ValueError as e: @@ -58,7 +58,7 @@ def property_as_bool( property_name: str, default: bool, ) -> bool: - if value := properties.get(property_name): + if (value := properties.get(property_name)) is not None: try: return strtobool(value) except ValueError as e: @@ -71,7 +71,7 @@ def get_first_property_value( *property_names: str, ) -> Any | None: for property_name in property_names: - if property_value := properties.get(property_name): + if (property_value := properties.get(property_name)) is not None: return property_value return None diff --git a/tests/utils/test_properties.py b/tests/utils/test_properties.py index 2cb4ea5ace..55124a8d73 100644 --- a/tests/utils/test_properties.py +++ b/tests/utils/test_properties.py @@ -88,6 +88,36 @@ def test_property_as_bool_with_invalid_value() -> None: assert "Could not parse table property some_bool_prop to a boolean: invalid" in str(exc.value) +def test_property_as_int_with_empty_string() -> None: + properties = { + "some_int_prop": "", + } + + with pytest.raises(ValueError) as exc: + property_as_int(properties, "some_int_prop", default=1) + assert "Could not parse table property some_int_prop to an integer: " in str(exc.value) + + +def test_property_as_float_with_empty_string() -> None: + properties = { + "some_float_prop": "", + } + + with pytest.raises(ValueError) as exc: + property_as_float(properties, "some_float_prop", default=1.0) + assert "Could not parse table property some_float_prop to a float: " in str(exc.value) + + +def test_property_as_bool_with_empty_string() -> None: + properties = { + "some_bool_prop": "", + } + + with pytest.raises(ValueError) as exc: + property_as_bool(properties, "some_bool_prop", default=True) + assert "Could not parse table property some_bool_prop to a boolean: " in str(exc.value) + + def test_get_first_property_value() -> None: properties = { "prop_1": "value_1", @@ -96,3 +126,13 @@ def test_get_first_property_value() -> None: assert get_first_property_value(properties, "prop_2", "prop_1") == "value_2" assert get_first_property_value(properties, "missing", "prop_1") == "value_1" + + +def test_get_first_property_value_with_empty_string() -> None: + properties = { + "empty": "", + "prop_1": "value_1", + } + + assert get_first_property_value(properties, "empty", "prop_1") == "" + assert get_first_property_value(properties, "missing", "empty") == ""