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 92a3e2fc Add missing catalog tests (#2955)
92a3e2fc is described below

commit 92a3e2fc0f0c7a25fba4133e9754f1ec67522831
Author: Alex Stephen <[email protected]>
AuthorDate: Wed Jan 28 20:14:11 2026 -0800

    Add missing catalog tests (#2955)
    
    <!--
    Thanks for opening a pull request!
    -->
    
    <!-- In the case this PR will resolve an issue, please replace
    ${GITHUB_ISSUE_ID} below with the actual Github issue id. -->
    <!-- Closes #${GITHUB_ISSUE_ID} -->
    
    # Rationale for this change
    There's a couple missing catalog tests around supporting namespaces +
    tables with slashes/dots. Along the way, I found an issue in how we
    create the CreateTableRequest + RegisterTableRequest
    
    ## Are these changes tested?
    Tests are included.
    
    ## Are there any user-facing changes?
    
    <!-- In the case of user-facing changes, please add the changelog label.
    -->
---
 pyiceberg/catalog/rest/__init__.py |   4 +-
 tests/integration/test_catalog.py  | 131 +++++++++++++++++++++++++++++++++++++
 2 files changed, 133 insertions(+), 2 deletions(-)

diff --git a/pyiceberg/catalog/rest/__init__.py 
b/pyiceberg/catalog/rest/__init__.py
index e3cc09ed..802be285 100644
--- a/pyiceberg/catalog/rest/__init__.py
+++ b/pyiceberg/catalog/rest/__init__.py
@@ -790,7 +790,7 @@ class RestCatalog(Catalog):
         if location:
             location = location.rstrip("/")
         request = CreateTableRequest(
-            name=namespace_and_table["table"],
+            name=self._identifier_to_validated_tuple(identifier)[-1],
             location=location,
             table_schema=fresh_schema,
             partition_spec=fresh_partition_spec,
@@ -869,7 +869,7 @@ class RestCatalog(Catalog):
         self._check_endpoint(Capability.V1_REGISTER_TABLE)
         namespace_and_table = self._split_identifier_for_path(identifier)
         request = RegisterTableRequest(
-            name=namespace_and_table["table"],
+            name=self._identifier_to_validated_tuple(identifier)[-1],
             metadata_location=metadata_location,
         )
         serialized_json = request.model_dump_json().encode(UTF8)
diff --git a/tests/integration/test_catalog.py 
b/tests/integration/test_catalog.py
index f9d174dd..0e39beb2 100644
--- a/tests/integration/test_catalog.py
+++ b/tests/integration/test_catalog.py
@@ -672,6 +672,29 @@ def test_incompatible_partitioned_schema_evolution(
     assert table.schema() == Schema(NestedField(2, "tpep_pickup_datetime", 
TimestampType(), False))
 
 
[email protected]
[email protected]("test_catalog", CATALOGS)
+def test_namespace_with_slash(test_catalog: Catalog) -> None:
+    if isinstance(test_catalog, HiveCatalog):
+        pytest.skip(f"{type(test_catalog).__name__} does not support slash in 
namespace")
+
+    namespace = ("new/db",)
+
+    if test_catalog.namespace_exists(namespace):
+        test_catalog.drop_namespace(namespace)
+
+    assert not test_catalog.namespace_exists(namespace)
+
+    test_catalog.create_namespace(namespace)
+    assert test_catalog.namespace_exists(namespace)
+
+    properties = test_catalog.load_namespace_properties(namespace)
+    assert properties is not None
+
+    test_catalog.drop_namespace(namespace)
+    assert not test_catalog.namespace_exists(namespace)
+
+
 @pytest.mark.integration
 @pytest.mark.parametrize("test_catalog", CATALOGS)
 def test_incompatible_sorted_schema_evolution(
@@ -692,3 +715,111 @@ def test_incompatible_sorted_schema_evolution(
     assert table.schema() == Schema(
         NestedField(1, "VendorID", IntegerType(), False), NestedField(2, 
"tpep_pickup_datetime", TimestampType(), False)
     )
+
+
[email protected]
[email protected]("test_catalog", CATALOGS)
+def test_namespace_with_dot(test_catalog: Catalog) -> None:
+    if isinstance(test_catalog, (HiveCatalog, SqlCatalog)):
+        pytest.skip(f"{type(test_catalog).__name__} does not support dot in 
namespace")
+
+    namespace = ("new.db",)
+
+    if test_catalog.namespace_exists(namespace):
+        test_catalog.drop_namespace(namespace)
+
+    assert not test_catalog.namespace_exists(namespace)
+
+    test_catalog.create_namespace(namespace)
+    assert test_catalog.namespace_exists(namespace)
+
+    # REST Catalog fixture treats this as a hierarchical namespace.
+    # Calling list namespaces will get `new`, not `new.db`.
+    if isinstance(test_catalog, RestCatalog):
+        namespaces = test_catalog.list_namespaces()
+        assert ("new",) in namespaces or ("new.db",) in namespaces
+    else:
+        assert namespace in test_catalog.list_namespaces()
+
+    properties = test_catalog.load_namespace_properties(namespace)
+    assert properties is not None
+
+    test_catalog.drop_namespace(namespace)
+    assert not test_catalog.namespace_exists(namespace)
+
+
[email protected]
[email protected]("test_catalog", CATALOGS)
+def test_table_name_with_slash(test_catalog: Catalog, table_schema_simple: 
Schema) -> None:
+    if isinstance(test_catalog, (HiveCatalog, SqlCatalog)):
+        pytest.skip(f"{type(test_catalog).__name__} does not support slash in 
table name")
+
+    namespace = ("ns_slash",)
+    table_ident = ("ns_slash", "tab/le")
+
+    if not test_catalog.namespace_exists(namespace):
+        test_catalog.create_namespace(namespace)
+
+    if test_catalog.table_exists(table_ident):
+        test_catalog.drop_table(table_ident)
+
+    assert not test_catalog.table_exists(table_ident)
+
+    test_catalog.create_table(table_ident, table_schema_simple)
+    assert test_catalog.table_exists(table_ident)
+
+    table = test_catalog.load_table(table_ident)
+    assert table.schema().as_struct() == table_schema_simple.as_struct()
+
+    test_catalog.drop_table(table_ident)
+    assert not test_catalog.table_exists(table_ident)
+
+
[email protected]
[email protected]("test_catalog", CATALOGS)
+def test_table_name_with_dot(test_catalog: Catalog, table_schema_simple: 
Schema) -> None:
+    if isinstance(test_catalog, (HiveCatalog, SqlCatalog)):
+        pytest.skip(f"{type(test_catalog).__name__} does not support dot in 
table name")
+
+    namespace = ("ns_dot",)
+    table_ident = ("ns_dot", "ta.ble")
+
+    if not test_catalog.namespace_exists(namespace):
+        test_catalog.create_namespace(namespace)
+
+    if test_catalog.table_exists(table_ident):
+        test_catalog.drop_table(table_ident)
+
+    assert not test_catalog.table_exists(table_ident)
+
+    test_catalog.create_table(table_ident, table_schema_simple)
+    assert test_catalog.table_exists(table_ident)
+
+    assert table_ident in test_catalog.list_tables(namespace)
+
+    table = test_catalog.load_table(table_ident)
+    assert table.schema().as_struct() == table_schema_simple.as_struct()
+
+    test_catalog.drop_table(table_ident)
+    assert not test_catalog.table_exists(table_ident)
+
+
[email protected]
[email protected]("test_catalog", CATALOGS)
+def test_drop_missing_table(test_catalog: Catalog, database_name: str) -> None:
+    test_catalog.create_namespace_if_not_exists(database_name)
+    table_ident = (database_name, "missing_table")
+    assert not test_catalog.table_exists(table_ident)
+    with pytest.raises(NoSuchTableError):
+        test_catalog.drop_table(table_ident)
+
+
[email protected]
[email protected]("test_catalog", CATALOGS)
+def test_drop_nonexistent_namespace(test_catalog: Catalog) -> None:
+    if isinstance(test_catalog, HiveCatalog):
+        pytest.skip("HiveCatalog raises NoSuchObjectException instead of 
NoSuchNamespaceError")
+
+    namespace = ("non_existent_namespace",)
+    with pytest.raises(NoSuchNamespaceError):
+        test_catalog.drop_namespace(namespace)

Reply via email to