From f9795186121fff6f5f9d52b5234e479714714cac Mon Sep 17 00:00:00 2001 From: Siddharth Asthana Date: Mon, 31 Aug 2026 03:11:25 +0530 Subject: [PATCH] fix: serialize purgeRequested as lowercase boolean in REST drop_table requests stringifies Python True/False as "True"/"False", which breaks OpenAPI boolean query params on strict REST catalogs. Fixes #3836 --- pyiceberg/catalog/rest/__init__.py | 2 +- tests/catalog/test_rest.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/pyiceberg/catalog/rest/__init__.py b/pyiceberg/catalog/rest/__init__.py index f568a08373..6818e89c34 100644 --- a/pyiceberg/catalog/rest/__init__.py +++ b/pyiceberg/catalog/rest/__init__.py @@ -1339,7 +1339,7 @@ def drop_table(self, identifier: str | Identifier, purge_requested: bool = False self._check_endpoint(Capability.V1_DELETE_TABLE) response = self._session.delete( self.url(Endpoints.drop_table, prefixed=True, **self._split_identifier_for_path(identifier)), - params={"purgeRequested": purge_requested}, + params={"purgeRequested": "true" if purge_requested else "false"}, ) try: response.raise_for_status() diff --git a/tests/catalog/test_rest.py b/tests/catalog/test_rest.py index f92bc12f7f..ea429dacb7 100644 --- a/tests/catalog/test_rest.py +++ b/tests/catalog/test_rest.py @@ -2015,6 +2015,21 @@ def test_delete_table_204(rest_mock: Mocker) -> None: RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN).drop_table(("example", "fokko")) +def test_drop_table_serializes_purge_requested_as_lowercase_bool(rest_mock: Mocker) -> None: + rest_mock.delete( + f"{TEST_URI}v1/namespaces/example/tables/fokko", + json={}, + status_code=204, + request_headers=TEST_HEADERS, + ) + RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN).drop_table(("example", "fokko"), purge_requested=True) + assert rest_mock.last_request is not None + assert rest_mock.last_request.qs == {"purgerequested": ["true"]} + + RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN).drop_table(("example", "fokko"), purge_requested=False) + assert rest_mock.last_request.qs == {"purgerequested": ["false"]} + + def test_delete_table_from_self_identifier_204( rest_mock: Mocker, example_table_metadata_with_snapshot_v1_rest_json: dict[str, Any] ) -> None: