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)
 

Reply via email to