diff --git a/pyiceberg/catalog/sql.py b/pyiceberg/catalog/sql.py index 87446bd58b..da725be2fe 100644 --- a/pyiceberg/catalog/sql.py +++ b/pyiceberg/catalog/sql.py @@ -778,9 +778,17 @@ def close(self) -> None: """Close the catalog and release database connections. This method closes the SQLAlchemy engine and disposes of all connection pools. - This ensures that any cached connections are properly closed, which is especially - important for blobfuse scenarios where file handles need to be closed for - data to be flushed to persistent storage. + This is crucial for proper resource cleanup and must be called in test fixture + teardowns to prevent Python 3.13+ ResourceWarnings about unclosed connections. + + The connection pool lifecycle is managed by SQLAlchemy's engine. When dispose() + is called, it closes all idle connections and invalidates active ones. This is + especially important in test environments where fixtures create catalogs that + otherwise may not be explicitly closed, and in production scenarios with + blobfuse where file handles need to be closed for data to be flushed to + persistent storage. + + See: Issue #2530 (https://github.com/apache/iceberg-python/issues/2530) """ if hasattr(self, "engine"): self.engine.dispose() diff --git a/pyiceberg/table/__init__.py b/pyiceberg/table/__init__.py index 63b87d290e..50596ff25f 100644 --- a/pyiceberg/table/__init__.py +++ b/pyiceberg/table/__init__.py @@ -2471,8 +2471,9 @@ def plan_files(self) -> Iterable[FileScanTask]: options=self.options, ).plan_files( manifests=manifests, - manifest_entry_filter=lambda manifest_entry: manifest_entry.snapshot_id in append_snapshot_ids - and manifest_entry.status == ManifestEntryStatus.ADDED, + manifest_entry_filter=lambda manifest_entry: ( + manifest_entry.snapshot_id in append_snapshot_ids and manifest_entry.status == ManifestEntryStatus.ADDED + ), ) def to_arrow(self) -> pa.Table: diff --git a/pyproject.toml b/pyproject.toml index 76c8526712..25cb42a401 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -124,6 +124,8 @@ dev = [ "papermill>=2.6.0", "nbformat>=5.10.0", "ipykernel>=6.29.0", + "ruff>=0.15.22", + "pre-commit>=4.6.0", ] # for mkdocs docs = [ @@ -171,9 +173,10 @@ filterwarnings = [ "error", # Ignore Python version deprecation warning from google.api_core while we still support 3.10 "ignore:You are using a Python version.*which Google will stop supporting:FutureWarning:google.api_core", - # Python 3.13 sqlite3 module ResourceWarnings for unclosed database connections - "ignore:unclosed database in str: @pytest.fixture(scope="module") def catalog_memory(catalog_name: str, warehouse: Path) -> Generator[SqlCatalog, None, None]: + """In-memory SQLite catalog fixture. + + Calls catalog.close() during teardown to properly dispose SQLAlchemy + connection pools and prevent Python 3.13 ResourceWarning. See #2530. + """ props = { "uri": "sqlite:///:memory:", "warehouse": f"file://{warehouse}", @@ -56,10 +61,16 @@ def catalog_memory(catalog_name: str, warehouse: Path) -> Generator[SqlCatalog, catalog.create_tables() yield catalog catalog.destroy_tables() + catalog.close() @pytest.fixture(scope="module") def catalog_sqlite(catalog_name: str, warehouse: Path) -> Generator[SqlCatalog, None, None]: + """File-based SQLite catalog fixture. + + Calls catalog.close() during teardown to properly dispose SQLAlchemy + connection pools and prevent Python 3.13 ResourceWarning. See #2530. + """ props = { "uri": f"sqlite:////{warehouse}/sql-catalog", "warehouse": f"file://{warehouse}", @@ -68,6 +79,7 @@ def catalog_sqlite(catalog_name: str, warehouse: Path) -> Generator[SqlCatalog, catalog.create_tables() yield catalog catalog.destroy_tables() + catalog.close() @pytest.fixture(scope="module") @@ -76,8 +88,10 @@ def catalog_uri(warehouse: Path) -> str: @pytest.fixture(scope="module") -def alchemy_engine(catalog_uri: str) -> Engine: - return create_engine(catalog_uri) +def alchemy_engine(catalog_uri: str) -> Generator[Engine, None, None]: + engine = create_engine(catalog_uri) + yield engine + engine.dispose() def test_creation_with_no_uri(catalog_name: str) -> None: @@ -103,10 +117,13 @@ def test_creation_with_echo_parameter(catalog_name: str, warehouse: Path) -> Non if echo_param is not None: props["echo"] = echo_param catalog = SqlCatalog(catalog_name, **props) - assert catalog.engine._echo == expected_echo_value, ( - f"Assertion failed: expected echo value {expected_echo_value}, " - f"but got {catalog.engine._echo}. For echo_param={echo_param}" - ) + try: + assert catalog.engine._echo == expected_echo_value, ( + f"Assertion failed: expected echo value {expected_echo_value}, " + f"but got {catalog.engine._echo}. For echo_param={echo_param}" + ) + finally: + catalog.close() def test_creation_with_pool_pre_ping_parameter(catalog_name: str, warehouse: Path) -> None: @@ -127,24 +144,29 @@ def test_creation_with_pool_pre_ping_parameter(catalog_name: str, warehouse: Pat props["pool_pre_ping"] = pool_pre_ping_param catalog = SqlCatalog(catalog_name, **props) - assert catalog.engine.pool._pre_ping == expected_pool_pre_ping_value, ( - f"Assertion failed: expected pool_pre_ping value {expected_pool_pre_ping_value}, " - f"but got {catalog.engine.pool._pre_ping}. For pool_pre_ping_param={pool_pre_ping_param}" - ) + try: + assert catalog.engine.pool._pre_ping == expected_pool_pre_ping_value, ( + f"Assertion failed: expected pool_pre_ping value {expected_pool_pre_ping_value}, " + f"but got {catalog.engine.pool._pre_ping}. For pool_pre_ping_param={pool_pre_ping_param}" + ) + finally: + catalog.close() def test_creation_from_impl(catalog_name: str, warehouse: Path) -> None: - assert isinstance( - load_catalog( - catalog_name, - **{ - "py-catalog-impl": "pyiceberg.catalog.sql.SqlCatalog", - "uri": f"sqlite:////{warehouse}/sql-catalog", - "warehouse": f"file://{warehouse}", - }, - ), - SqlCatalog, + catalog = load_catalog( + catalog_name, + **{ + "py-catalog-impl": "pyiceberg.catalog.sql.SqlCatalog", + "uri": f"sqlite:////{warehouse}/sql-catalog", + "warehouse": f"file://{warehouse}", + }, ) + try: + assert isinstance(catalog, SqlCatalog) + finally: + if isinstance(catalog, SqlCatalog): + catalog.close() def confirm_no_tables_exist(alchemy_engine: Engine) -> None: @@ -182,7 +204,10 @@ def load_catalog_for_catalog_table_creation(catalog_name: str, catalog_uri: str) def test_creation_when_no_tables_exist(alchemy_engine: Engine, catalog_name: str, catalog_uri: str) -> None: confirm_no_tables_exist(alchemy_engine) catalog = load_catalog_for_catalog_table_creation(catalog_name=catalog_name, catalog_uri=catalog_uri) - confirm_all_tables_exist(catalog) + try: + confirm_all_tables_exist(catalog) + finally: + catalog.close() def test_creation_when_one_tables_exists(alchemy_engine: Engine, catalog_name: str, catalog_uri: str) -> None: @@ -194,7 +219,10 @@ def test_creation_when_one_tables_exists(alchemy_engine: Engine, catalog_name: s assert IcebergTables.__tablename__ in [t for t in inspector.get_table_names() if t in CATALOG_TABLES] catalog = load_catalog_for_catalog_table_creation(catalog_name=catalog_name, catalog_uri=catalog_uri) - confirm_all_tables_exist(catalog) + try: + confirm_all_tables_exist(catalog) + finally: + catalog.close() def test_creation_when_all_tables_exists(alchemy_engine: Engine, catalog_name: str, catalog_uri: str) -> None: @@ -207,7 +235,10 @@ def test_creation_when_all_tables_exists(alchemy_engine: Engine, catalog_name: s assert c in [t for t in inspector.get_table_names() if t in CATALOG_TABLES] catalog = load_catalog_for_catalog_table_creation(catalog_name=catalog_name, catalog_uri=catalog_uri) - confirm_all_tables_exist(catalog) + try: + confirm_all_tables_exist(catalog) + finally: + catalog.close() class TestSqlCatalogClose: @@ -261,3 +292,22 @@ def test_sql_catalog_multiple_close_calls(self, catalog_sqlite: SqlCatalog) -> N # Second close should not raise an exception catalog_sqlite.close() + + def test_catalog_fixture_closes_connections(self, warehouse: Path) -> None: + """Regression test: verify SqlCatalog properly closes all SQLAlchemy + connections to prevent Python 3.13 ResourceWarning about unclosed + database connections. See: apache/iceberg-python#2530""" + import gc + import warnings + + props = { + "uri": f"sqlite:////{warehouse}/test-regression-2530", + "warehouse": f"file://{warehouse}", + } + with warnings.catch_warnings(): + warnings.simplefilter("error", ResourceWarning) + catalog = SqlCatalog("regression_test", **props) + catalog.create_tables() + catalog.destroy_tables() + catalog.close() + gc.collect() # Force GC to catch any unclosed connections diff --git a/tests/conftest.py b/tests/conftest.py index eb0b712d1e..f1177ba02a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3149,6 +3149,12 @@ def catalog(request: pytest.FixtureRequest, tmp_path: Path) -> Generator[Catalog yield cat if hasattr(cat, "destroy_tables"): cat.destroy_tables() + # Use duck typing to safely call close() only if available. + # Not all catalog implementations (e.g., REST, Glue) have close(), but SQLCatalog does. + # This pattern prevents AttributeError while supporting proper resource cleanup for + # catalogs that manage connections. See issue #2530 for Python 3.13 ResourceWarning fix. + if hasattr(cat, "close"): + cat.close() @pytest.fixture(params=list(_CATALOG_FACTORIES.keys())) @@ -3161,6 +3167,12 @@ def catalog_with_warehouse( yield cat if hasattr(cat, "destroy_tables"): cat.destroy_tables() + # Use duck typing to safely call close() only if available. + # Not all catalog implementations (e.g., REST, Glue) have close(), but SQLCatalog does. + # This pattern prevents AttributeError while supporting proper resource cleanup for + # catalogs that manage connections. See issue #2530 for Python 3.13 ResourceWarning fix. + if hasattr(cat, "close"): + cat.close() @pytest.fixture(name="random_table_identifier") diff --git a/uv.lock b/uv.lock index 0aea046671..5449618a48 100644 --- a/uv.lock +++ b/uv.lock @@ -722,6 +722,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, ] +[[package]] +name = "cfgv" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, +] + [[package]] name = "cfn-lint" version = "1.52.1" @@ -1408,7 +1417,7 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [ @@ -2255,6 +2264,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4f/85/b505a99a133d9f99d21af182af416e9baef70bdeef019983479651e494c2/huggingface_hub-1.21.0-py3-none-any.whl", hash = "sha256:eadaa3678c512c82aea69e8675d90a184861e68de32f1105668628b4dce0e7cd", size = 721078, upload-time = "2026-06-25T13:09:24.402Z" }, ] +[[package]] +name = "identify" +version = "2.6.19" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/63/51723b5f116cc04b061cb6f5a561790abf249d25931d515cd375e063e0f4/identify-2.6.19.tar.gz", hash = "sha256:6be5020c38fcb07da56c53733538a3081ea5aa70d36a156f83044bfbf9173842", size = 99567, upload-time = "2026-04-17T18:39:50.265Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl", hash = "sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a", size = 99397, upload-time = "2026-04-17T18:39:49.221Z" }, +] + [[package]] name = "idna" version = "3.18" @@ -3738,6 +3756,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" }, ] +[[package]] +name = "nodeenv" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, +] + [[package]] name = "notebook-shim" version = "0.2.4" @@ -4276,6 +4303,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bf/b9/7c46fdbd1dbbaaf77f9512d7665609d7e4c4d8c8849edb9a16c471041075/polars_runtime_32-1.42.0-cp310-abi3-win_arm64.whl", hash = "sha256:b7c5d7721b7bb2563d72785050ac099da1e2000d412f9c72a0cfb7b07779e75d", size = 46728464, upload-time = "2026-06-24T05:18:52.505Z" }, ] +[[package]] +name = "pre-commit" +version = "4.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8e/22/2de9408ac81acbb8a7d05d4cc064a152ccf33b3d480ebe0cd292153db239/pre_commit-4.6.0.tar.gz", hash = "sha256:718d2208cef53fdc38206e40524a6d4d9576d103eb16f0fec11c875e7716e9d9", size = 198525, upload-time = "2026-04-21T20:31:41.613Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl", hash = "sha256:e2cf246f7299edcabcf15f9b0571fdce06058527f0a06535068a86d38089f29b", size = 226472, upload-time = "2026-04-21T20:31:40.092Z" }, +] + [[package]] name = "prek" version = "0.4.5" @@ -5004,6 +5047,7 @@ dev = [ { name = "mypy-boto3-glue" }, { name = "nbformat" }, { name = "papermill" }, + { name = "pre-commit" }, { name = "prek" }, { name = "protobuf" }, { name = "pyarrow-stubs" }, @@ -5013,6 +5057,7 @@ dev = [ { name = "pytest-lazy-fixtures" }, { name = "pytest-mock" }, { name = "requests-mock" }, + { name = "ruff" }, { name = "sqlalchemy" }, { name = "typing-extensions" }, ] @@ -5096,6 +5141,7 @@ dev = [ { name = "mypy-boto3-glue", specifier = ">=1.28.18" }, { name = "nbformat", specifier = ">=5.10.0" }, { name = "papermill", specifier = ">=2.6.0" }, + { name = "pre-commit", specifier = ">=4.6.0" }, { name = "prek", specifier = ">=0.2.1" }, { name = "protobuf", specifier = "==6.33.5" }, { name = "pyarrow-stubs", specifier = ">=20.0.0.20251107" }, @@ -5105,6 +5151,7 @@ dev = [ { name = "pytest-lazy-fixtures", specifier = "==1.4.0" }, { name = "pytest-mock", specifier = "==3.15.1" }, { name = "requests-mock", specifier = "==1.12.1" }, + { name = "ruff", specifier = ">=0.15.22" }, { name = "sqlalchemy", specifier = ">=2.0.18,<3" }, { name = "typing-extensions", specifier = "==4.15.0" }, ] @@ -6172,6 +6219,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ea/ea/e7b0251441da9adfeaebcf29601d10f2a1455fcf0772fae9e7e19032bd96/rpds_py-2026.5.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:8c43a8a973270fd173bf48cdf80bbe66312421cba68d40845034f174f2389049", size = 586326, upload-time = "2026-05-28T12:02:11.47Z" }, ] +[[package]] +name = "ruff" +version = "0.15.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/06/ae069393fc66e8ff33036d4b368003833bf6e88ccf182e17e7a2f1c754fd/ruff-0.15.22.tar.gz", hash = "sha256:3f15175b1fb580126f58285a5dae6b2ea89000136d980c64499211f116b54809", size = 4785063, upload-time = "2026-07-16T15:14:13.244Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/18/ee54b7ae1e121be7a28ea6da4b67564ebb0530e183a54415ab7e3bcd2c4e/ruff-0.15.22-py3-none-linux_armv6l.whl", hash = "sha256:44423e73493737f5e7c5b41d475483898ff37afcdae38bc3da5085e29af1c2d8", size = 10781258, upload-time = "2026-07-16T15:13:19.452Z" }, + { url = "https://files.pythonhosted.org/packages/2f/d2/2520cb14761ddbeaf57642a76942fc36adcbdbe53b4532241995f6fc485c/ruff-0.15.22-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b82c6482946e9eda7ff2e091d25b8bad3f718684e1916d41bd56873cee05b697", size = 10999477, upload-time = "2026-07-16T15:13:23.318Z" }, + { url = "https://files.pythonhosted.org/packages/c9/10/74e53572aa758dfaa678c2a2646b5c5515d884b7ca56be4d2ce03ca4b560/ruff-0.15.22-py3-none-macosx_11_0_arm64.whl", hash = "sha256:11c1c715af53a09f714e011106bffc419751ec8232fcb5da42173284ea3fec6f", size = 10466716, upload-time = "2026-07-16T15:13:26.162Z" }, + { url = "https://files.pythonhosted.org/packages/1e/cc/44eaaf0844e028182f2d0a8f2190d0f359159aed0a9e5ab861d892f1ae2a/ruff-0.15.22-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:742a29cf29bddb7c8327895d6a10e0e6c5b38a96dd407af9b5d0857f809c0576", size = 10892644, upload-time = "2026-07-16T15:13:29.229Z" }, + { url = "https://files.pythonhosted.org/packages/9f/21/8edf559014d2b0f82beea19cfb713993ad802ccda16868769979c6090a84/ruff-0.15.22-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72af58b951b0ae395935ae79763dc349bc0eb706319d28f7a33ad2cfb3cfc178", size = 10576719, upload-time = "2026-07-16T15:13:32.35Z" }, + { url = "https://files.pythonhosted.org/packages/bf/1e/3a13abd392a3b50b62e5938a831f9ab6e588358cacad5c18545b716d2182/ruff-0.15.22-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d425005c1835eb24e2ee4161cb90e8db263415f4a71c8c72c33abaa6c0c224", size = 11376494, upload-time = "2026-07-16T15:13:35.958Z" }, + { url = "https://files.pythonhosted.org/packages/bf/3e/422d3d95bcf04dd78e1aeac22184d4f9a8fb2c01865d39d44618484a0317/ruff-0.15.22-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8b9b3f8779a4f08c969defc3c8c35abffaa757e601ed5ae66d6d1db6519969a", size = 12208370, upload-time = "2026-07-16T15:13:39.185Z" }, + { url = "https://files.pythonhosted.org/packages/1e/91/5d065a0e0a02bf4813f5119ad278462eed081d2b832eb7c021ade0ec9e65/ruff-0.15.22-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e0dd1b2e4d3d585f897a0d137cbf4eaf6223bef4e8ce34d6bb12556c5f9249e", size = 11581098, upload-time = "2026-07-16T15:13:42.132Z" }, + { url = "https://files.pythonhosted.org/packages/f6/f9/a0d4871d12fae702eb1f41b686caf05f1f8b124dc6db6f784f53d74918fa/ruff-0.15.22-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365523eb91d9224e1bcb03b022fbf0facb8f9e23792a2c53d9d4b3924bdbdebb", size = 11399422, upload-time = "2026-07-16T15:13:45.2Z" }, + { url = "https://files.pythonhosted.org/packages/18/80/c843a5176cddbceb0b7e8dd41cf9993490796c1c469348d384f5a5c13c56/ruff-0.15.22-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:fabfd168afdf29fee5be98b831efa9683c94d7c5a3b58b9ce5a2e38444589a74", size = 11381683, upload-time = "2026-07-16T15:13:48.46Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/8485de0ae92239438a36cfc51350db9b9e85c9ebdfaea91b18e422706662/ruff-0.15.22-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:225dbf095a87f1d9f90f5fd7924d2613ee452a75a4308c63a8f50f761787aa7c", size = 10850295, upload-time = "2026-07-16T15:13:51.655Z" }, + { url = "https://files.pythonhosted.org/packages/fa/91/24977ec2ec72eaf15e4394ace2959fdff2dd1e14f03e005e838023407169/ruff-0.15.22-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1877d63b9d24ed278744f1523fd11b85540566d54641f97c566d7d9dc5ca5296", size = 10579640, upload-time = "2026-07-16T15:13:54.79Z" }, + { url = "https://files.pythonhosted.org/packages/9c/47/9b51216951974df1f263ac19da550d34252e0ed7218c25f10c5ef9ed7517/ruff-0.15.22-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a1606c510bd7215680d32efab38965f7cdec3ef69f5170a3f4791404ffdd5262", size = 11105077, upload-time = "2026-07-16T15:13:57.915Z" }, + { url = "https://files.pythonhosted.org/packages/c2/47/20e9d4a3b8016778acea5fc32bb50d35d207500a17ddb529ffa6996feef8/ruff-0.15.22-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:630479b18625f5ffc373f77603a22a9f8ac0acd7ff0501178b5db28ec71e9c64", size = 11490980, upload-time = "2026-07-16T15:14:01.032Z" }, + { url = "https://files.pythonhosted.org/packages/4d/76/3f72d8fc38c1cb77b38c56a70da9d0c17700cc1cc50f9649c9d3c8f5ba71/ruff-0.15.22-py3-none-win32.whl", hash = "sha256:e5ba0e4a13fd14abbed2a77b517a3911290c6c6c59ef67784328d1668fab76cf", size = 10789165, upload-time = "2026-07-16T15:14:04.16Z" }, + { url = "https://files.pythonhosted.org/packages/cb/46/4965251734c2b6fcdca1b1b187d20bcac3af0ee5b083b89c910bb961ce3a/ruff-0.15.22-py3-none-win_amd64.whl", hash = "sha256:9be63ba1eb936acd2d1342fb8337c356353706fce233b2a15a09a97037e6acde", size = 11938297, upload-time = "2026-07-16T15:14:07.316Z" }, + { url = "https://files.pythonhosted.org/packages/57/c9/e69b1ff4c8b69093ef08b8919ab767af0569666865b39c30a8795d88d3c6/ruff-0.15.22-py3-none-win_arm64.whl", hash = "sha256:e1168075b72158510839f250027659cdd78476f40507dd517892304c41318661", size = 11298172, upload-time = "2026-07-16T15:14:10.51Z" }, +] + [[package]] name = "s3fs" version = "2026.4.0" diff --git a/vendor/fb303/constants.py b/vendor/fb303/constants.py index 3361fd3904..9bb7eadcd5 100644 --- a/vendor/fb303/constants.py +++ b/vendor/fb303/constants.py @@ -23,4 +23,3 @@ # - diff --git a/vendor/hive_metastore/ThriftHiveMetastore.py b/vendor/hive_metastore/ThriftHiveMetastore.py index 4d25c087c7..ec83972a12 100644 --- a/vendor/hive_metastore/ThriftHiveMetastore.py +++ b/vendor/hive_metastore/ThriftHiveMetastore.py @@ -12201,9 +12201,9 @@ def __init__(self, handler): self._processMap["truncate_table_req"] = Processor.process_truncate_table_req self._processMap["get_tables"] = Processor.process_get_tables self._processMap["get_tables_by_type"] = Processor.process_get_tables_by_type - self._processMap[ - "get_all_materialized_view_objects_for_rewriting" - ] = Processor.process_get_all_materialized_view_objects_for_rewriting + self._processMap["get_all_materialized_view_objects_for_rewriting"] = ( + Processor.process_get_all_materialized_view_objects_for_rewriting + ) self._processMap["get_materialized_views_for_rewriting"] = Processor.process_get_materialized_views_for_rewriting self._processMap["get_table_meta"] = Processor.process_get_table_meta self._processMap["get_all_tables"] = Processor.process_get_all_tables @@ -12225,19 +12225,19 @@ def __init__(self, handler): self._processMap["add_partitions_pspec"] = Processor.process_add_partitions_pspec self._processMap["append_partition"] = Processor.process_append_partition self._processMap["add_partitions_req"] = Processor.process_add_partitions_req - self._processMap[ - "append_partition_with_environment_context" - ] = Processor.process_append_partition_with_environment_context + self._processMap["append_partition_with_environment_context"] = ( + Processor.process_append_partition_with_environment_context + ) self._processMap["append_partition_by_name"] = Processor.process_append_partition_by_name - self._processMap[ - "append_partition_by_name_with_environment_context" - ] = Processor.process_append_partition_by_name_with_environment_context + self._processMap["append_partition_by_name_with_environment_context"] = ( + Processor.process_append_partition_by_name_with_environment_context + ) self._processMap["drop_partition"] = Processor.process_drop_partition self._processMap["drop_partition_with_environment_context"] = Processor.process_drop_partition_with_environment_context self._processMap["drop_partition_by_name"] = Processor.process_drop_partition_by_name - self._processMap[ - "drop_partition_by_name_with_environment_context" - ] = Processor.process_drop_partition_by_name_with_environment_context + self._processMap["drop_partition_by_name_with_environment_context"] = ( + Processor.process_drop_partition_by_name_with_environment_context + ) self._processMap["drop_partitions_req"] = Processor.process_drop_partitions_req self._processMap["get_partition"] = Processor.process_get_partition self._processMap["get_partition_req"] = Processor.process_get_partition_req @@ -12266,9 +12266,9 @@ def __init__(self, handler): self._processMap["get_partitions_by_names_req"] = Processor.process_get_partitions_by_names_req self._processMap["alter_partition"] = Processor.process_alter_partition self._processMap["alter_partitions"] = Processor.process_alter_partitions - self._processMap[ - "alter_partitions_with_environment_context" - ] = Processor.process_alter_partitions_with_environment_context + self._processMap["alter_partitions_with_environment_context"] = ( + Processor.process_alter_partitions_with_environment_context + ) self._processMap["alter_partitions_req"] = Processor.process_alter_partitions_req self._processMap["alter_partition_with_environment_context"] = Processor.process_alter_partition_with_environment_context self._processMap["rename_partition"] = Processor.process_rename_partition @@ -12397,9 +12397,9 @@ def __init__(self, handler): self._processMap["drop_wm_pool"] = Processor.process_drop_wm_pool self._processMap["create_or_update_wm_mapping"] = Processor.process_create_or_update_wm_mapping self._processMap["drop_wm_mapping"] = Processor.process_drop_wm_mapping - self._processMap[ - "create_or_drop_wm_trigger_to_pool_mapping" - ] = Processor.process_create_or_drop_wm_trigger_to_pool_mapping + self._processMap["create_or_drop_wm_trigger_to_pool_mapping"] = ( + Processor.process_create_or_drop_wm_trigger_to_pool_mapping + ) self._processMap["create_ischema"] = Processor.process_create_ischema self._processMap["alter_ischema"] = Processor.process_alter_ischema self._processMap["get_ischema"] = Processor.process_get_ischema diff --git a/vendor/hive_metastore/constants.py b/vendor/hive_metastore/constants.py index 218e527553..bdbdf9cbbf 100644 --- a/vendor/hive_metastore/constants.py +++ b/vendor/hive_metastore/constants.py @@ -23,8 +23,6 @@ # - - DDL_TIME = "transient_lastDdlTime" ACCESSTYPE_NONE = 1 ACCESSTYPE_READONLY = 2