This is an automated email from the ASF dual-hosted git repository.
kevinjqliu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-python.git
The following commit(s) were added to refs/heads/main by this push:
new af337ba83 fix: preserve empty property values in CLI (#3745)
af337ba83 is described below
commit af337ba830889d69868b18e255cdfb610d670a5e
Author: ChangHyeon Im <[email protected]>
AuthorDate: Tue Aug 4 01:01:57 2026 +0900
fix: preserve empty property values in CLI (#3745)
<!--
Thanks for opening a pull request!
-->
# Rationale for this change
The `properties get table` and `properties get namespace` commands used
a truthy check for property lookups. As a result, an existing property
with an empty string value was reported as missing.
This changes both lookups to check explicitly for `None`, preserving
empty strings while keeping the existing error for missing properties.
Related to #3713.
## Are these changes tested?
Yes. Added CLI regression tests for empty table and namespace property
values.
- `make lint`
- `uv run python -m pytest tests/cli/test_console.py`
## Are there any user-facing changes?
Yes. The table and namespace property commands now return an existing
empty string value instead of raising `NoSuchPropertyException`.
<!-- In the case of user-facing changes, please add the changelog label.
-->
---
pyiceberg/cli/console.py | 6 ++++--
tests/cli/test_console.py | 24 ++++++++++++++++++++++++
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/pyiceberg/cli/console.py b/pyiceberg/cli/console.py
index 3feed9fb2..940a9f028 100644
--- a/pyiceberg/cli/console.py
+++ b/pyiceberg/cli/console.py
@@ -327,7 +327,8 @@ def get_namespace(ctx: Context, identifier: str,
property_name: str) -> None:
namespace_properties = catalog.load_namespace_properties(identifier_tuple)
if property_name:
- if property_value := namespace_properties.get(property_name):
+ property_value = namespace_properties.get(property_name)
+ if property_value is not None:
output.text(property_value)
else:
raise NoSuchPropertyException(f"Could not find property
{property_name} on namespace {identifier}")
@@ -348,7 +349,8 @@ def get_table(ctx: Context, identifier: str, property_name:
str) -> None:
metadata = catalog.load_table(identifier_tuple).metadata
if property_name:
- if property_value := metadata.properties.get(property_name):
+ property_value = metadata.properties.get(property_name)
+ if property_value is not None:
output.text(property_value)
else:
raise NoSuchPropertyException(f"Could not find property
{property_name} on table {identifier}")
diff --git a/tests/cli/test_console.py b/tests/cli/test_console.py
index 27a1bfebe..408e369f7 100644
--- a/tests/cli/test_console.py
+++ b/tests/cli/test_console.py
@@ -440,6 +440,21 @@ def test_properties_get_table_specific_property(catalog:
InMemoryCatalog) -> Non
assert result.output == "134217728\n"
+def test_properties_get_table_specific_empty_property(catalog:
InMemoryCatalog) -> None:
+ catalog.create_namespace(TEST_TABLE_NAMESPACE)
+ catalog.create_table(
+ identifier=TEST_TABLE_IDENTIFIER,
+ schema=TEST_TABLE_SCHEMA,
+ partition_spec=TEST_TABLE_PARTITION_SPEC,
+ properties={"empty": ""},
+ )
+
+ runner = CliRunner()
+ result = runner.invoke(run, ["properties", "get", "table",
"default.my_table", "empty"])
+ assert result.exit_code == 0
+ assert result.output == "\n"
+
+
def test_properties_get_table_specific_property_that_doesnt_exist(catalog:
InMemoryCatalog) -> None:
catalog.create_namespace(TEST_TABLE_NAMESPACE)
catalog.create_table(
@@ -482,6 +497,15 @@ def
test_properties_get_namespace_specific_property(catalog: InMemoryCatalog, na
assert result.output == "s3://warehouse/database/location\n"
+def test_properties_get_namespace_specific_empty_property(catalog:
InMemoryCatalog) -> None:
+ catalog.create_namespace(TEST_TABLE_NAMESPACE, {"empty": ""})
+
+ runner = CliRunner()
+ result = runner.invoke(run, ["properties", "get", "namespace", "default",
"empty"])
+ assert result.exit_code == 0
+ assert result.output == "\n"
+
+
def test_properties_get_namespace_does_not_exist(catalog: InMemoryCatalog,
namespace_properties: Properties) -> None:
catalog.create_namespace(TEST_TABLE_NAMESPACE, namespace_properties)