From 3f44dfe711e96beda6aa8622cf5b0baffa6eb0f2 Mon Sep 17 00:00:00 2001 From: Soumya Ghosh Date: Sun, 14 Jul 2024 00:35:38 +0530 Subject: [PATCH] Lowercase bool values in table properties (#924) --- pyiceberg/types.py | 2 +- tests/cli/test_console.py | 9 ++++++--- tests/test_types.py | 12 ++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/pyiceberg/types.py b/pyiceberg/types.py index cd662c7387..97ddea0e57 100644 --- a/pyiceberg/types.py +++ b/pyiceberg/types.py @@ -67,7 +67,7 @@ def transform_dict_value_to_str(dict: Dict[str, Any]) -> Dict[str, str]: for key, value in dict.items(): if value is None: raise ValueError(f"None type is not a supported value in properties: {key}") - return {k: str(v) for k, v in dict.items()} + return {k: str(v).lower() if isinstance(v, bool) else str(v) for k, v in dict.items()} def _parse_decimal_type(decimal: Any) -> Tuple[int, int]: diff --git a/tests/cli/test_console.py b/tests/cli/test_console.py index 92a7f80c7d..e55ff9a9ad 100644 --- a/tests/cli/test_console.py +++ b/tests/cli/test_console.py @@ -83,7 +83,7 @@ def mock_datetime_now(monkeypatch: pytest.MonkeyPatch) -> None: NestedField(3, "z", LongType(), required=True), ) TEST_TABLE_PARTITION_SPEC = PartitionSpec(PartitionField(name="x", transform=IdentityTransform(), source_id=1, field_id=1000)) -TEST_TABLE_PROPERTIES = {"read.split.target.size": "134217728"} +TEST_TABLE_PROPERTIES = {"read.split.target.size": "134217728", "write.parquet.bloom-filter-enabled.column.x": True} TEST_TABLE_UUID = uuid.UUID("d20125c8-7284-442c-9aea-15fee620737c") TEST_TIMESTAMP = 1602638573874 MOCK_ENVIRONMENT = {"PYICEBERG_CATALOG__PRODUCTION__URI": "test://doesnotexist"} @@ -367,7 +367,10 @@ def test_properties_get_table(catalog: InMemoryCatalog) -> None: runner = CliRunner() result = runner.invoke(run, ["properties", "get", "table", "default.my_table"]) assert result.exit_code == 0 - assert result.output == "read.split.target.size 134217728\n" + assert ( + result.output + == "read.split.target.size 134217728\nwrite.parquet.bloom-filter-enabled.column.x true \n" + ) def test_properties_get_table_specific_property(catalog: InMemoryCatalog) -> None: @@ -763,7 +766,7 @@ def test_json_properties_get_table(catalog: InMemoryCatalog) -> None: runner = CliRunner() result = runner.invoke(run, ["--output=json", "properties", "get", "table", "default.my_table"]) assert result.exit_code == 0 - assert result.output == """{"read.split.target.size": "134217728"}\n""" + assert result.output == """{"read.split.target.size": "134217728", "write.parquet.bloom-filter-enabled.column.x": "true"}\n""" def test_json_properties_get_table_specific_property(catalog: InMemoryCatalog) -> None: diff --git a/tests/test_types.py b/tests/test_types.py index 1e386bb748..52bdce4de8 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -44,6 +44,7 @@ TimeType, UUIDType, strtobool, + transform_dict_value_to_str, ) non_parameterized_types = [ @@ -649,3 +650,14 @@ def test_strtobool() -> None: for val in invalid_values: with pytest.raises(ValueError, match=f"Invalid truth value: {val!r}"): strtobool(val) + + +def test_transform_dict_value_to_str() -> None: + input_dict = {"key1": 1, "key2": 2.0, "key3": "3", "key4: ": True, "key5": False} + expected_dict = {"key1": "1", "key2": "2.0", "key3": "3", "key4: ": "true", "key5": "false"} + # valid values + assert transform_dict_value_to_str(input_dict) == expected_dict + # Null value not allowed, should raise ValueError + input_dict["key6"] = None + with pytest.raises(ValueError, match="None type is not a supported value in properties: key6"): + transform_dict_value_to_str(input_dict)