From db7ca99835fd73b803f8f01f3db0f5011d9010d2 Mon Sep 17 00:00:00 2001 From: Yuya Ebihara Date: Sun, 28 Jun 2026 08:49:58 +0900 Subject: [PATCH] Add support for reading Theta sketch Puffin file --- pyiceberg/table/theta_sketch.py | 74 +++++++++ pyproject.toml | 2 + tests/table/puffin/v1/theta-sketches.puffin | Bin 0 -> 843 bytes tests/table/test_theta_sketch.py | 166 ++++++++++++++++++++ uv.lock | 64 +++++++- 5 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 pyiceberg/table/theta_sketch.py create mode 100644 tests/table/puffin/v1/theta-sketches.puffin create mode 100644 tests/table/test_theta_sketch.py diff --git a/pyiceberg/table/theta_sketch.py b/pyiceberg/table/theta_sketch.py new file mode 100644 index 0000000000..aa6c121094 --- /dev/null +++ b/pyiceberg/table/theta_sketch.py @@ -0,0 +1,74 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +from typing import TYPE_CHECKING + +import zstandard + +from pyiceberg.table.puffin import PuffinBlobMetadata, PuffinFile + +if TYPE_CHECKING: + from datasketches import compact_theta_sketch + +BLOB_TYPE_APACHE_DATASKETCHES_THETA_V1 = "apache-datasketches-theta-v1" + + +class ThetaSketch: + field_id: int + _sketch: compact_theta_sketch + + def __init__(self, field_id: int, sketch: compact_theta_sketch) -> None: + self.field_id = field_id + self._sketch = sketch + + def get_estimate(self) -> float: + return self._sketch.get_estimate() + + def get_lower_bound(self, num_std_devs: int = 1) -> float: + return self._sketch.get_lower_bound(num_std_devs) + + def get_upper_bound(self, num_std_devs: int = 1) -> float: + return self._sketch.get_upper_bound(num_std_devs) + + def is_empty(self) -> bool: + return self._sketch.is_empty() + + def is_estimation_mode(self) -> bool: + return self._sketch.is_estimation_mode() + + @property + def sketch(self) -> compact_theta_sketch: + return self._sketch + + +def _theta_sketches_from_blob(blob: PuffinBlobMetadata, payload: bytes) -> list[ThetaSketch]: + from datasketches import compact_theta_sketch + + if blob.compression_codec == "zstd": + payload = zstandard.decompress(payload) + + sketch = compact_theta_sketch.deserialize(payload) + return [ThetaSketch(field_id=field_id, sketch=sketch) for field_id in blob.fields] + + +def theta_sketches_from_puffin_file(puffin_file: PuffinFile) -> list[ThetaSketch]: + sketches = [] + for blob in puffin_file.footer.blobs: + if blob.type == BLOB_TYPE_APACHE_DATASKETCHES_THETA_V1: + sketches.extend(_theta_sketches_from_blob(blob, puffin_file.get_blob_payload(blob))) + return sketches diff --git a/pyproject.toml b/pyproject.toml index fdcac80ade..9097e26706 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -98,6 +98,7 @@ datafusion = ["datafusion>=52,<53"] gcp-auth = ["google-auth>=2.4.0"] entra-auth = ["azure-identity>=1.25.1"] geoarrow = ["geoarrow-pyarrow>=0.2.0"] +datasketches = ["datasketches>=3.4.0,<6.0.0"] [dependency-groups] dev = [ @@ -124,6 +125,7 @@ dev = [ "papermill>=2.6.0", "nbformat>=5.10.0", "ipykernel>=6.29.0", + "datasketches>=3.4.0,<6.0.0", ] # for mkdocs docs = [ diff --git a/tests/table/puffin/v1/theta-sketches.puffin b/tests/table/puffin/v1/theta-sketches.puffin new file mode 100644 index 0000000000000000000000000000000000000000..9beca220d097a8962532f4fcb101046b5673ce26 GIT binary patch literal 843 zcmWG=b2QZ0s{dET;vgdf6EiadgVdSHtPCK~U@!W!_VnJig{%(u^d6qPZOd_Z`X8aj zg1K@}vlHK)XmC;3<*@nSEw;>9j`ceCaT>D5=BV_816zcWPNfCRnPMoqiC?RYdFtk% z1ofV_DZixh=6dWp*|CeY!YA)<08T>$@4Yz@&!8i<<+WYdlT#B^&dX@UsTEyN&uWT0cJic3;}mKGG{7o--IWTpZwu2#xRDFaHGD%IBNknCzB zid}7PJOIu%rr6nrCPoyy8|Vnsm`E;4O)N=G(M_rZMo36eW?sHRS!xj|1{F$Di%Xzv PU_@mwfwKw&D9r%?`JfwR literal 0 HcmV?d00001 diff --git a/tests/table/test_theta_sketch.py b/tests/table/test_theta_sketch.py new file mode 100644 index 0000000000..e1ad0e88d3 --- /dev/null +++ b/tests/table/test_theta_sketch.py @@ -0,0 +1,166 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +import json +from os import path + +import pytest +from datasketches import compact_theta_sketch, update_theta_sketch + +from pyiceberg.table.puffin import MAGIC_BYTES, PuffinFile +from pyiceberg.table.theta_sketch import ThetaSketch, theta_sketches_from_puffin_file + + +def _open_fixture(file: str) -> bytes: + cur_dir = path.dirname(path.realpath(__file__)) + with open(f"{cur_dir}/puffin/v1/{file}", "rb") as f: + return f.read() + + +def _make_sketch(values: list[int]) -> compact_theta_sketch: + ts = update_theta_sketch() + for v in values: + ts.update(v) + return ts.compact() + + +@pytest.fixture +def empty_sketch_bytes() -> bytes: + return update_theta_sketch().compact().serialize() + + +@pytest.fixture +def three_value_sketch_bytes() -> bytes: + return _make_sketch([1, 2, 3]).serialize() + + +def test_empty_sketch(empty_sketch_bytes: bytes) -> None: + sketch = compact_theta_sketch.deserialize(empty_sketch_bytes) + ts = ThetaSketch(field_id=1, sketch=sketch) + + assert ts.is_empty() + assert ts.get_estimate() == 0.0 + + +def test_sketch_estimate(three_value_sketch_bytes: bytes) -> None: + sketch = compact_theta_sketch.deserialize(three_value_sketch_bytes) + ts = ThetaSketch(field_id=1, sketch=sketch) + + assert not ts.is_empty() + assert ts.get_estimate() == pytest.approx(3.0) + assert not ts.is_estimation_mode() + + +def test_sketch_bounds_exact_mode(three_value_sketch_bytes: bytes) -> None: + sketch = compact_theta_sketch.deserialize(three_value_sketch_bytes) + ts = ThetaSketch(field_id=1, sketch=sketch) + + assert ts.get_lower_bound(1) == pytest.approx(3.0) + assert ts.get_upper_bound(1) == pytest.approx(3.0) + + +def test_sketch_field_id() -> None: + sketch = _make_sketch([10, 20, 30]) + ts = ThetaSketch(field_id=42, sketch=sketch) + + assert ts.field_id == 42 + + +def test_sketch_property() -> None: + sketch = _make_sketch([1, 2]) + ts = ThetaSketch(field_id=1, sketch=sketch) + + assert ts.sketch is sketch + + +def test_estimation_mode() -> None: + ts_builder = update_theta_sketch(lg_k=5) + for i in range(100): + ts_builder.update(i) + sketch = ts_builder.compact() + ts = ThetaSketch(field_id=1, sketch=sketch) + + assert ts.is_estimation_mode() + assert ts.get_estimate() > 0 + assert ts.get_lower_bound(1) <= ts.get_estimate() + assert ts.get_upper_bound(1) >= ts.get_estimate() + + +def _build_puffin_file(blob_bytes: bytes, field_ids: list[int], snapshot_id: int = 1) -> bytes: + # Puffin layout: magic(4) + blobs + footer_json + footer_size(4) + flags(4) + magic(4) + # Blob offsets are file-absolute; first blob starts immediately after the 4-byte magic. + blob_offset = 4 + footer = { + "blobs": [ + { + "type": "apache-datasketches-theta-v1", + "snapshot-id": snapshot_id, + "sequence-number": 1, + "fields": field_ids, + "offset": blob_offset, + "length": len(blob_bytes), + } + ], + "properties": {}, + } + footer_json = json.dumps(footer, separators=(",", ":")).encode("utf-8") + footer_size_bytes = len(footer_json).to_bytes(4, byteorder="little") + flags = b"\x00\x00\x00\x00" + return MAGIC_BYTES + blob_bytes + footer_json + footer_size_bytes + flags + MAGIC_BYTES + + +def test_theta_sketches_from_puffin_file_single_field(three_value_sketch_bytes: bytes) -> None: + puffin_bytes = _build_puffin_file(three_value_sketch_bytes, field_ids=[5]) + puffin_file = PuffinFile(puffin_bytes) + + sketches = theta_sketches_from_puffin_file(puffin_file) + + assert len(sketches) == 1 + assert sketches[0].field_id == 5 + assert sketches[0].get_estimate() == pytest.approx(3.0) + + +def test_theta_sketches_from_puffin_file_multiple_fields(three_value_sketch_bytes: bytes) -> None: + puffin_bytes = _build_puffin_file(three_value_sketch_bytes, field_ids=[1, 2, 3]) + puffin_file = PuffinFile(puffin_bytes) + + sketches = theta_sketches_from_puffin_file(puffin_file) + + assert len(sketches) == 3 + assert [s.field_id for s in sketches] == [1, 2, 3] + for sketch in sketches: + assert sketch.get_estimate() == pytest.approx(3.0) + + +def test_theta_sketches_from_puffin_file_empty_sketch(empty_sketch_bytes: bytes) -> None: + puffin_bytes = _build_puffin_file(empty_sketch_bytes, field_ids=[7]) + puffin_file = PuffinFile(puffin_bytes) + + sketches = theta_sketches_from_puffin_file(puffin_file) + + assert len(sketches) == 1 + assert sketches[0].is_empty() + assert sketches[0].get_estimate() == 0.0 + + +def test_theta_sketches_from_trino_written_puffin_file() -> None: + puffin_file = PuffinFile(_open_fixture("theta-sketches.puffin")) + sketches = theta_sketches_from_puffin_file(puffin_file) + + assert len(sketches) == 3 + assert [s.field_id for s in sketches] == [1, 2, 3] + for sketch in sketches: + assert sketch.get_estimate() == pytest.approx(5.0) diff --git a/uv.lock b/uv.lock index 896e7f42f5..e65f865b96 100644 --- a/uv.lock +++ b/uv.lock @@ -1220,6 +1220,46 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1c/48/01906ab5c1a70373c6874ac5192d03646fa7b94d9ff06e3f676cb6b0f43f/datafusion-52.3.0-cp310-abi3-win_amd64.whl", hash = "sha256:9fb35738cf4dbff672dbcfffc7332813024cb0ad2ab8cda1fb90b9054277ab0c", size = 33765807, upload-time = "2026-03-16T10:54:05.728Z" }, ] +[[package]] +name = "datasketches" +version = "5.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/34/cd/659ae9fc53f34d6deafbe12162977654be5bb0a584e6afa6656337e13952/datasketches-5.2.0.tar.gz", hash = "sha256:c00d61da4695e00036e63f590999f584cc39246cbb147b171f375f792604a612", size = 53213, upload-time = "2025-03-01T07:49:24.567Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/13/0146b96195819f528ecf3f77e0dd58054c321076468746fc67687c20ff19/datasketches-5.2.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:177e9545aafd7359c44e7935b995b0b0f9b08704a78f53e7840a7125d2d1fc9e", size = 652707, upload-time = "2025-03-01T07:48:01.904Z" }, + { url = "https://files.pythonhosted.org/packages/38/16/38fc321557d86be3542e63ab0c54eef4807c43a16e4d102b85fab64716d0/datasketches-5.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4d33a1d7894509556efb6a41f2ad530257d67a094a039e3b5a047a22934a951e", size = 584959, upload-time = "2025-03-01T07:48:03.875Z" }, + { url = "https://files.pythonhosted.org/packages/f0/a5/d3a92c4904207a2429de4c336b806cb1137ac86d96d053b73a9ed8b3d6ba/datasketches-5.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52c53f8c94c48b3f047ab488e9ea41ce8dbf6897c2c1f353cb8a79b22cb4a22b", size = 681874, upload-time = "2025-03-01T07:48:06.356Z" }, + { url = "https://files.pythonhosted.org/packages/c3/cc/b97554d566ca9a3b02645e5e8cb6047e80ee9409bc03f8924ee64e3eba4f/datasketches-5.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c13fcd9071147a377b587f590887751d85874df677ec5ed72ccdf3f7a19446a", size = 738419, upload-time = "2025-03-01T07:48:08.782Z" }, + { url = "https://files.pythonhosted.org/packages/fe/87/36c48c4af91ab732a09bfe06392df664b30ea780523d719e1be7819ec622/datasketches-5.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62aa8ddfb0e8f4d0e3e1e214e19e0de11b8ea1e34bf7752dfd987e6e9e3b1264", size = 1069353, upload-time = "2025-03-01T07:48:11.088Z" }, + { url = "https://files.pythonhosted.org/packages/4e/f2/abc65ff28286e4997c02d3d83f1236b72595c3e5ba9d3ba39274eab87eed/datasketches-5.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:95c2f6b2dea71385bfddf525cc14c9d8bf261f7aa98cbd65155dbaa0764f6cd9", size = 1131149, upload-time = "2025-03-01T07:48:13.893Z" }, + { url = "https://files.pythonhosted.org/packages/fa/4d/be6af6e5cf0bdef5b55d640852a47946a7f044c6fcad989e81619ebb46ab/datasketches-5.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:a8a0500c0de3012fda530e12b6c62d27278f7d6cce21008b9208895dfd337201", size = 506641, upload-time = "2025-03-01T07:48:15.779Z" }, + { url = "https://files.pythonhosted.org/packages/c3/b9/5c69df548b19fc2a20d5990f32023db4483cef43a263d775ba7e08bda00e/datasketches-5.2.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:dd8640866011c7dd346d8c9cf9ad0438de16d56788c13b12c96ecb38c5c7df9d", size = 653081, upload-time = "2025-03-01T07:48:17.643Z" }, + { url = "https://files.pythonhosted.org/packages/f5/0e/8baa3ec5ab48408c1ad7d2d4a9ecba07a4a7e16392b8e0d3480fe88b0285/datasketches-5.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e78a462b397c9a11e876a7fd8198d77d35b8bbe849a8d329c518962bc8463ad1", size = 585248, upload-time = "2025-03-01T07:48:19.778Z" }, + { url = "https://files.pythonhosted.org/packages/fc/99/011c7edd1c7971ca4a5c2e545a99889716d907498e25f96e1055c1a9c49f/datasketches-5.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cde9ce8f42b6a05930dd9b5d0da1b4420d1e8db53faaa41c6732ce7a1670c4a", size = 682144, upload-time = "2025-03-01T07:48:21.663Z" }, + { url = "https://files.pythonhosted.org/packages/ce/27/820dc70c6d4b23fc43187113a9386d4f8702c162f4387f459dfc5063ee63/datasketches-5.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:470111ef1b213bc75b3602e14153c3e70a1ebe0fe4b069a7800557685080c477", size = 738715, upload-time = "2025-03-01T07:48:24.085Z" }, + { url = "https://files.pythonhosted.org/packages/94/42/5e8bc5277891797e3207a02ab12db3b2ae7159a45aae917a510c690c5880/datasketches-5.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0208fb7bf40edca3f8cfcd9d1acdb95798abc10b685341b39557f59eb5bd862e", size = 1069861, upload-time = "2025-03-01T07:48:26.419Z" }, + { url = "https://files.pythonhosted.org/packages/62/43/765df9fd6ea2f6fffc1fd757e28e4736568abf9ff1789471d3d8d7dc9ad8/datasketches-5.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bfa6571373244a9e3a4a1f59919b8a41979a997b92be3db0219400d8c6e96d20", size = 1131346, upload-time = "2025-03-01T07:48:28.756Z" }, + { url = "https://files.pythonhosted.org/packages/4a/f4/76a267c596c0a9849241efc91ffb9791fd8b6d818b594d38ce0a322215e7/datasketches-5.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:516e67cd3fd2d14c58c9d2b593f50ac23aff3874406c325ba2589a9c989862ca", size = 507446, upload-time = "2025-03-01T07:48:30.823Z" }, + { url = "https://files.pythonhosted.org/packages/fe/88/ac2dc472e9d054e3edbce9a5d1288bab447fc080d5a0d85984455cf66808/datasketches-5.2.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:65b3e2bb6b2083dfdd6a611e4b07d058ca6625f838088b5cb0897335c4580e6d", size = 643447, upload-time = "2025-03-01T07:48:32.844Z" }, + { url = "https://files.pythonhosted.org/packages/00/0c/faca927b0575482d567eda4fa65ffe5ebe1ac04b6c5f0321faeb490d5b8e/datasketches-5.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bfc80979ccb2e11bf5e93996db7f1f486c9d3ef4a15c18f1f1bc37aaa4b2a038", size = 578736, upload-time = "2025-03-01T07:48:35.427Z" }, + { url = "https://files.pythonhosted.org/packages/ce/6f/9201d36b6775ec8dc3f7d4cc10e32b35b2012683b520d0cf83b0cb674866/datasketches-5.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a76731c0d876cff25cc2896ef9d80c54167f5aff7170f12b89db6a9b898fc714", size = 675679, upload-time = "2025-03-01T07:48:38.157Z" }, + { url = "https://files.pythonhosted.org/packages/af/87/56bbb0be6d6c49c9b1705f56bad3f4319f8cdbc546f79e811ac88bdfe2cc/datasketches-5.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9aa0c1dad8d00c242718c5dbb9f8cf1876ea099ee55c1c0634a8beecb589164", size = 748356, upload-time = "2025-03-01T07:48:40.344Z" }, + { url = "https://files.pythonhosted.org/packages/c9/37/0c25e113ae8a148201d60050f26efeada54f46e8417bd35082b40355eac3/datasketches-5.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:40e6cecb8656b6694e845d9319c5c3aaa083f754e992db6065f18806474685c1", size = 1070320, upload-time = "2025-03-01T07:48:43.218Z" }, + { url = "https://files.pythonhosted.org/packages/0f/43/5ea198ff05ba3c1f904a1118b23f1b36b0c60f16b15af791a3ab4ccee752/datasketches-5.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a673180dc5226bf3c84baeeadf36d9a4f1ee82e679dcd92776651f8ffcc09287", size = 1146824, upload-time = "2025-03-01T07:48:46.841Z" }, + { url = "https://files.pythonhosted.org/packages/8d/fc/1ca195f0fe524e3ffc12ac81c07f3cc3ce144499b4e3ec5e73a52167253f/datasketches-5.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:72cc339cb7775f82516c36fe8e9a70e9f504214a8d0ed06246332f53203b89f3", size = 509067, upload-time = "2025-03-01T07:48:48.784Z" }, + { url = "https://files.pythonhosted.org/packages/62/a7/2b69296c200bd59550cb6ee292d8ba6739ea2d847e10d38452d86120bb45/datasketches-5.2.0-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:a76c998ddf4d39f895b830a3ccc41d1df2d0454c74fc5e53844db119658e71a7", size = 643448, upload-time = "2025-03-01T07:48:50.808Z" }, + { url = "https://files.pythonhosted.org/packages/ed/56/ca425991d21e4b4e4b0a72276a77678201a92d5609acbb27ad7a05ddfce6/datasketches-5.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6c2be3884b28d24a3be103a5c285902f06eee85c076be57c62c9c5eecbe15d4d", size = 578736, upload-time = "2025-03-01T07:48:53.73Z" }, + { url = "https://files.pythonhosted.org/packages/2b/89/d8ce2f6eab2914a5091360f94fc52cb6f93b1e3852f1aa86dbba9833e20f/datasketches-5.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bcbf2687b436593f4e03ba73f57dd72fc6a7414d88db57e91f4c24f6e62ee45", size = 675679, upload-time = "2025-03-01T07:48:55.734Z" }, + { url = "https://files.pythonhosted.org/packages/62/33/351d1f0c700e143217597d29b333c77695db0f0b3757cf3c2b6e8cf58ea7/datasketches-5.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49e78e52d6a1d63b08a2990873f94bbc9d7427f6907f600af1257f0a9c901b1f", size = 748357, upload-time = "2025-03-01T07:48:57.901Z" }, + { url = "https://files.pythonhosted.org/packages/7d/6c/9ef89caf91c2d2b70fce5038607f2b5d8b09ee14db6bbe89027a8421ed88/datasketches-5.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6be79e382a4b4fe033a7d3de0033fe81b0e01ebc5124ae24f785214517a847a7", size = 1070320, upload-time = "2025-03-01T07:49:01.074Z" }, + { url = "https://files.pythonhosted.org/packages/82/22/a6281d53249af4570b36418de2367114a4ecebd16099e195346641e9d5e8/datasketches-5.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fbd6eab5af078eb65d678bf27fc468097a1c5db07800ac537a75fd983c437e57", size = 1146824, upload-time = "2025-03-01T07:49:04.782Z" }, + { url = "https://files.pythonhosted.org/packages/6f/da/c3feb5eca3d7c43d068069b56f77685c01d1ee67e687490cc6341ec920f1/datasketches-5.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:bf8f1cc1b1c4a35554924e27d6c2872e7b0dc065e2694ec83035ffbc203f17c3", size = 509058, upload-time = "2025-03-01T07:49:06.796Z" }, +] + [[package]] name = "debugpy" version = "1.8.21" @@ -1970,14 +2010,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f5/a1/1f7f0c555f5858fd2906fe9f7b0a3554fddb85cb70df7a6aaec41dc292c2/greenlet-3.5.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:c180d22d325fb613956b443c3c6f4406eb70e6defc70d3974da2a7b59e06f48c", size = 285838, upload-time = "2026-06-26T18:21:05.167Z" }, { url = "https://files.pythonhosted.org/packages/0a/29/be9f43ed61677a5759b38c8a9389248133c8c731bbfc0574ecdff66c99fc/greenlet-3.5.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:483d08c11181c83a6ce1a7a61df0f624a208ec40817a3bb2302714592eee4f04", size = 602342, upload-time = "2026-06-26T19:07:06.908Z" }, { url = "https://files.pythonhosted.org/packages/b9/42/ba41c97ec36aa4b3ec25e5aa691d79561254805fad7f2f826dd6770587e2/greenlet-3.5.3-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1dae6e0091eae084317e411f047f0b7cb241c6db570f7c45fd6b900a274914ce", size = 615541, upload-time = "2026-06-26T19:10:04.909Z" }, + { url = "https://files.pythonhosted.org/packages/2e/8c/231ca675b0df779816950ca66b40b1fa14dbff4a0ed9814a9a29ec399140/greenlet-3.5.3-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0f6ff50ff8dbd51fae9b37f4101648b04ea0df19b3f50ab2beb5061e7716a5c8", size = 622473, upload-time = "2026-06-26T19:24:12.786Z" }, { url = "https://files.pythonhosted.org/packages/f5/c7/28747042e1df8a9cd120a1ebe15529fc4be3b486e13e8d551ff307a82412/greenlet-3.5.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bcd2d72ccd70a1ec68ba6ef93e7fbb4420ef9997dabc7010d893bd4015e0bec", size = 615675, upload-time = "2026-06-26T18:32:14.444Z" }, + { url = "https://files.pythonhosted.org/packages/81/fe/dd97c483a3ff82849196ccd07851600edd3ac9de74669ca8a6022ada9ea1/greenlet-3.5.3-cp310-cp310-manylinux_2_39_riscv64.whl", hash = "sha256:37bf9c538f5ae6e63d643f88dec37c0c83bdf0e2ebc62961dedcf458822f7b71", size = 418421, upload-time = "2026-06-26T19:25:34.503Z" }, { url = "https://files.pythonhosted.org/packages/cc/a8/b85525a6c8fba9f009a5f7c8df1545de8fb0f0bf3e0179194ef4e500317f/greenlet-3.5.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:73f152c895e09907e0dbe24f6c2db37beb085cd63db91c3825a0fcd0064124a8", size = 1575057, upload-time = "2026-06-26T19:09:00.264Z" }, { url = "https://files.pythonhosted.org/packages/03/79/fb76edb218fe6735ab0edeba176c7ab80df9618f7c02ce4208979f3ae7db/greenlet-3.5.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8bdb43e1a1d1873721acab2be99c5befd4d2044ddfd52e4d610801019880a702", size = 1641692, upload-time = "2026-06-26T18:31:41.454Z" }, { url = "https://files.pythonhosted.org/packages/6b/79/86fe3ee50ed55d9b3907eecd3208b5c3fe8a79515519aae98b4753c3fa1d/greenlet-3.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:0909f9355a9f24845d3299f3112e266a06afb68302041989fd26bd68894933db", size = 238742, upload-time = "2026-06-26T18:20:40.758Z" }, { url = "https://files.pythonhosted.org/packages/51/58/5404031044f55afad7aad1aff8be3f22b1bed03e237cfeabbc7e5c8cfde0/greenlet-3.5.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:aca9b4ce85b152b5524ef7d88170efdff80dc0032aa8b75f9aaf7f3479ea95b4", size = 287424, upload-time = "2026-06-26T18:20:31.469Z" }, { url = "https://files.pythonhosted.org/packages/b4/bf/1c65e9b94a54d547068fa5b5a8a06f221f3316b48908e08668d29c77cb50/greenlet-3.5.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f71be4920368fe1fabeeaa53d1e3548337e2b223d9565f8ad5e392a75ba23fc", size = 606523, upload-time = "2026-06-26T19:07:08.859Z" }, { url = "https://files.pythonhosted.org/packages/b8/c7/b66baacc95775ad511287acb0137b95574a9ce5491902372b7564799d790/greenlet-3.5.3-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4d77e67f65f98449e3fb83f795b5d0a8437aead2f874ca89c96576caf4be3af6", size = 618315, upload-time = "2026-06-26T19:10:06.055Z" }, + { url = "https://files.pythonhosted.org/packages/b0/a0/68afd1ebad40db87dac0a28ffa120726b98bf9c7c40c481b0f63c105d298/greenlet-3.5.3-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e18619ba655ac05d78d80fc83cac4ba892bd6927b99e3b8237aee861aaacc8bb", size = 626155, upload-time = "2026-06-26T19:24:14.44Z" }, { url = "https://files.pythonhosted.org/packages/78/2b/28ed29463522fdbe4c15b1f63922041626a7478316b34ab4adda3f0a4aba/greenlet-3.5.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8540f1e6205bd13ca0ce685581037219ca54a1b41a0a15d228c6c9b8ad5903d7", size = 617381, upload-time = "2026-06-26T18:32:16.077Z" }, + { url = "https://files.pythonhosted.org/packages/07/7f/e327d912239ec4b3b49999e3967389bcf1ee8722b9ee9194d2752ecd558a/greenlet-3.5.3-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:d27c0c653a60d9535f690226474a5cc1036a8b0d7b57504d1c4f89c44a07a80c", size = 421083, upload-time = "2026-06-26T19:25:35.804Z" }, { url = "https://files.pythonhosted.org/packages/2a/7b/ad04e9d1337fc04965dc9fc616b6a72cb65a24b800a014c011ec812f5489/greenlet-3.5.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ef56fe650f50575bf843acde967b9c567687f3c22340941a899b7bc56e956a8", size = 1577771, upload-time = "2026-06-26T19:09:01.537Z" }, { url = "https://files.pythonhosted.org/packages/d8/33/6c87ab7ba663f70ca21f3022aad1ffe56d3f3e0521e836c2415e13abcc3c/greenlet-3.5.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5121af01cf911e70056c00d4b46d5e9b5d1415550038573d744138bacb59e6b8", size = 1644048, upload-time = "2026-06-26T18:31:42.996Z" }, { url = "https://files.pythonhosted.org/packages/1c/35/f0d8ee998b422cf8693b270f098e55d8d4ec8006b061b333f54f177d28d9/greenlet-3.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:0f41e4a05a3c0cb31b17023eff28dd111e1d16bf7d7d00406cd7df23f31398a7", size = 239137, upload-time = "2026-06-26T18:23:21.664Z" }, @@ -1985,7 +2029,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5d/6e/4c37d51a2b7f82d2ff11bb6b5f7d766d9a011726624af255e843727627a3/greenlet-3.5.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:719757059f5a53fd0dde23f78cffeafcdd97b21c850ddb7ca684a3c1a1f122e2", size = 288685, upload-time = "2026-06-26T18:22:08.977Z" }, { url = "https://files.pythonhosted.org/packages/7a/73/815dd90131c1b71ebdf53dbc7c276cafec2a1173b97559f97aba72724a87/greenlet-3.5.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:efa9f765dd09f9d0cdac651ffdf631ee59ec5dc6ee7a73e0c012ba9c52fbdf5b", size = 604761, upload-time = "2026-06-26T19:07:10.114Z" }, { url = "https://files.pythonhosted.org/packages/9f/57/079cfe76bcef36b153b25607ee91c6fcb58f17f8b23c86bbbeabe0c88d72/greenlet-3.5.3-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7faba15ac005376e02a0384504e0243be3370ce010296a44a820feb342b505ab", size = 617044, upload-time = "2026-06-26T19:10:07.25Z" }, + { url = "https://files.pythonhosted.org/packages/fb/fb/d97dc261209c80744b7c8132693a30d70ec6e7315e632cb0a10b3fec94dd/greenlet-3.5.3-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5795cd1101371140551c645f2d408b8d3c01a5a29cf8a9bce6e759c983682d23", size = 622351, upload-time = "2026-06-26T19:24:16.32Z" }, { url = "https://files.pythonhosted.org/packages/37/87/b4d095775a3fb1bcafbb483fc206b27ebb785724c83051447737085dc54e/greenlet-3.5.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:87142215824be6ac05e2e8e2786eec307ccbc27c36723c3881959df654af6861", size = 614244, upload-time = "2026-06-26T18:32:17.594Z" }, + { url = "https://files.pythonhosted.org/packages/8e/ac/e5fee13cbbd0e8de312d9a146584b8a51891c68847330ef9dc8b5109d23f/greenlet-3.5.3-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:af4923b3096e26a36d7e9cf24ab88083a20f97d191e3b97f253731ce9b41b28c", size = 425395, upload-time = "2026-06-26T19:25:37.144Z" }, { url = "https://files.pythonhosted.org/packages/8a/70/7559b609683650fa2b95b8ab84b4ab0b26556a635d19675e12aa832d826d/greenlet-3.5.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:215275b1b49320987352e6c1b054acca0064f965a2c66992bed9a6f7d913f149", size = 1574210, upload-time = "2026-06-26T19:09:03.077Z" }, { url = "https://files.pythonhosted.org/packages/ae/73/be55392074c60fc37655ca40fa6022457bfbf6718e9e342a7b0b41f96dd2/greenlet-3.5.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6b1b0eed82364b0e32c4ea0f221452d33e6bb17ae094d9f72aed9851812747ea", size = 1638627, upload-time = "2026-06-26T18:31:44.748Z" }, { url = "https://files.pythonhosted.org/packages/14/40/c57489acf8e37d74e2913d4eff63aa0dba17acccc4bdeef874dde2dbbec9/greenlet-3.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:cde8adafa2365676f74a979744629589999093bc86e2484214f58e61df08902c", size = 239882, upload-time = "2026-06-26T18:23:27.518Z" }, @@ -1993,7 +2039,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9b/ff/a620267401db30a50cc8450ee90730e2d4a85658c055c0e760d4ed47fb13/greenlet-3.5.3-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:c8d87c2134d871df96ecdea9cec7cbaab286dadab0f56476e57aaf9e8ac11550", size = 287609, upload-time = "2026-06-26T18:21:14.724Z" }, { url = "https://files.pythonhosted.org/packages/d6/fa/5401ac78021c826a25b6dde0c705e0a8f29b617509f9185a31dac15fbe1b/greenlet-3.5.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2d185dd1621757e70c3861cceffd5317ab4e7ed7eb09c82994828468527ade5", size = 607435, upload-time = "2026-06-26T19:07:11.412Z" }, { url = "https://files.pythonhosted.org/packages/e9/76/1dc144a2e56e65d36405078ed774224375ea520a1870a6e46e08bb4ac7bf/greenlet-3.5.3-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1c514a468149bf8fbbab874188a3535cd8a48a3e353eb53a3d424296f8dbacd3", size = 619787, upload-time = "2026-06-26T19:10:08.396Z" }, + { url = "https://files.pythonhosted.org/packages/57/61/2f5b1adf256d039f5dab8005de8d3d7ad2b0070a3219c0e036b3fbfeb440/greenlet-3.5.3-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9ad04dd75458c6300b047c61b8639092433d205a25a14e310d6582a480efcca1", size = 625580, upload-time = "2026-06-26T19:24:18.344Z" }, { url = "https://files.pythonhosted.org/packages/bf/87/c298cee62df1de4ad7fec32abda73526cff347fd143a6ed4ac369246668a/greenlet-3.5.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:915f887cf2682b66419b879423a2e072634aa7b7dce6f3ada4957cfced3f1e9a", size = 616786, upload-time = "2026-06-26T18:32:19.128Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d9/ab7fc9e543e44d6879b0a6ef9a4b2188940fd180cc65d6f646883ddf7201/greenlet-3.5.3-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:afaabdd554cd7ae9bbb3ca070b0d7fdfd207dbf1d16865f7233837709d354bda", size = 427933, upload-time = "2026-06-26T19:25:38.219Z" }, { url = "https://files.pythonhosted.org/packages/9e/2e/e6f009885ed0705ccf33fe0583c117cfd03cde77e31a596dd5785a30762b/greenlet-3.5.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:766cfd421c13e450feb340cd472a3ed9957d438727b7b4593ad7c76c5d2b0deb", size = 1574316, upload-time = "2026-06-26T19:09:04.273Z" }, { url = "https://files.pythonhosted.org/packages/ef/fe/43fd110b01e40da0adb7c90ac7ea744bef2d43dca00de5095fd2351c2a68/greenlet-3.5.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2ecda9ec22edf38fa389369eaed8c3d37c05f3c54e69f69438dbb2cc1de1458b", size = 1638614, upload-time = "2026-06-26T18:31:46.297Z" }, { url = "https://files.pythonhosted.org/packages/0f/7c/062447147a61f8b4337b156fe70d32a165fcf2f89d7ca6255e572806705c/greenlet-3.5.3-cp313-cp313-win_amd64.whl", hash = "sha256:c82304750f057167ff60d188df1d0cc1764ce9567eadf03e6a7443bcedd0b30b", size = 239850, upload-time = "2026-06-26T18:21:54.613Z" }, @@ -2001,7 +2049,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c3/93/43e116ee114b28737ba7e12952a0d4e2f55944d0f84e42bc91ba7192a3c9/greenlet-3.5.3-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:fd2e02fa07485778536a036222d616ab957b1d533f36b3ed98ce725d9c9d3117", size = 288202, upload-time = "2026-06-26T18:23:49.604Z" }, { url = "https://files.pythonhosted.org/packages/82/2f/146d218299046a43d1f029fd544b3d110d0f175a09c715c7e8da4a4a345d/greenlet-3.5.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df0a0628d1597eb0897b62f55d1343f772405fd25f3b2a796c76874b0c2e22e8", size = 654096, upload-time = "2026-06-26T19:07:12.71Z" }, { url = "https://files.pythonhosted.org/packages/a0/cc/04738cafb3f45fa991ea44f9de94c47dcec964f5a972300988a6751f49d9/greenlet-3.5.3-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ebd933a6adabc298bab47731a130fe6bfb888bd934eee37810f151159544540d", size = 666304, upload-time = "2026-06-26T19:10:09.503Z" }, + { url = "https://files.pythonhosted.org/packages/86/a9/73fa62893d5b84b4205544e6b673c654cc43aa5b9899bac00f04d64af73d/greenlet-3.5.3-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8d19fe6c39ebff9259f07bcc685d3290f8fa4ea2278e51dd0008e4d6b0f2d814", size = 670657, upload-time = "2026-06-26T19:24:19.967Z" }, { url = "https://files.pythonhosted.org/packages/ce/aa/4e0dad5e605c270c784ab911c43da6adb136ccd4d81180f763ca429a723d/greenlet-3.5.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4b9d501b40e80b70e32323c799dd9b420a5577a9601469d362ae1ffb690f3a7c", size = 663635, upload-time = "2026-06-26T18:32:20.802Z" }, + { url = "https://files.pythonhosted.org/packages/29/7e/2ffce64929fb3cab7b65d5a0b20aaf9764e227681d731b041077fc9a525a/greenlet-3.5.3-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:962c5df2db8cb446da51edf1ca5296c389d93b99c9d8aa2ee4c7d0d8f1218260", size = 473497, upload-time = "2026-06-26T19:25:39.421Z" }, { url = "https://files.pythonhosted.org/packages/d1/50/13efdbea246fe3d3b735e191fec08fb50809f53cd2383ebe123d0809e44b/greenlet-3.5.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a1fad1d11e7d6aab184107baa8e4ece11ccba3ec9599cd7efa5ff4d70d43256a", size = 1621252, upload-time = "2026-06-26T19:09:05.647Z" }, { url = "https://files.pythonhosted.org/packages/f7/22/c0a336ae4a1410fd5f5121098e5bfbf1865f64c5ef80b4b5412886c4a332/greenlet-3.5.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:fad5aec764399f1b5cc347ad250a59660f20c8f8888ea6bae1f93b769cce1154", size = 1684824, upload-time = "2026-06-26T18:31:47.738Z" }, { url = "https://files.pythonhosted.org/packages/7a/94/91aec0030bea75c4b3244251d0de60a1f3432d1ecb53ab6c437fb5c3ba61/greenlet-3.5.3-cp314-cp314-win_amd64.whl", hash = "sha256:7669aa24cf2a1041d6f7899575b494a3ab4cf68bfcc8609b1dc0be7272db835e", size = 240754, upload-time = "2026-06-26T18:22:15.669Z" }, @@ -2009,14 +2059,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/91/95/3e161213d7f1d378d15aa9e792093e9bfe01844680d04b7fd6e0107c9098/greenlet-3.5.3-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:271a8ea7c1024e8a0d7dd2be66dd66dda8a07193f41a17b9e924f7600f5b62be", size = 296389, upload-time = "2026-06-26T18:22:20.657Z" }, { url = "https://files.pythonhosted.org/packages/00/92/715c44721abe2b4d1ae9abde4179411868a5bff312479f54e105d372f131/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19131729ae0ddc3c2e1ef85e650169b5e37ee32e400f215f78b94d7b0d567310", size = 653382, upload-time = "2026-06-26T19:07:14.209Z" }, { url = "https://files.pythonhosted.org/packages/a0/83/37a10372a1090a6624cca8e74c12df1a36c2dc36429ed0255b7fb1aeee23/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1540dd8e5fc2a5aec40fbb98ef8e149fa47c89a4b4a1cf2575a14d3d1869d7a8", size = 659401, upload-time = "2026-06-26T19:10:10.876Z" }, + { url = "https://files.pythonhosted.org/packages/cb/73/8faec206b851c22b1733545fda900829a1f3f5b1c78ae7e0fb3dba57d9f4/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b897d97759425953f69a9c0fac67f8fe333ec0ce7377ef186fb2b0c3ad5e354d", size = 659582, upload-time = "2026-06-26T19:24:21.357Z" }, { url = "https://files.pythonhosted.org/packages/db/e2/d1509cad4207da559cc42986ecdd8fc67ad0d1bba2bf03023c467fd5e0f3/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e81fa194a1d20967877bdf9c7794db2bc99063e5be36aee710c08f04c5bb087f", size = 656969, upload-time = "2026-06-26T18:32:22.272Z" }, + { url = "https://files.pythonhosted.org/packages/b4/55/50c19e49f8045834ada71ef12f8ad048eba8517c6aa41161bed676328fae/greenlet-3.5.3-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:3236754d423955ea08e9bb5f6c04a7895f9e22c290b66aa7653fcb922d839eb0", size = 491037, upload-time = "2026-06-26T19:25:40.672Z" }, { url = "https://files.pythonhosted.org/packages/86/7d/eaf70de20aadca3a5884aec58362861c64ce45e7b277f47ed026926a3b89/greenlet-3.5.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:55cf4d777485d43110e47133cbba6d74a8885a87ec1227ef0267f9ee80c5aa21", size = 1617822, upload-time = "2026-06-26T19:09:06.893Z" }, { url = "https://files.pythonhosted.org/packages/8a/f9/414d38fc400ae4350d4185eaad1827676f7cf5287b9136e0ed1cbbe20a7f/greenlet-3.5.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:12a248ba75f6a9a236375f52296c498c89ff1d8badf32deb9eca7abd5853f7da", size = 1677983, upload-time = "2026-06-26T18:31:49.396Z" }, { url = "https://files.pythonhosted.org/packages/e4/15/7edb977e08f9bff702fe42d6c902702786ff6b9694058b4e6a2a6ac90e57/greenlet-3.5.3-cp314-cp314t-win_amd64.whl", hash = "sha256:efc6bd60ea02e085862c74a3ef64b147ffc6f1a5ea7d9f26e7a939943f68c1e3", size = 243626, upload-time = "2026-06-26T18:24:41.485Z" }, { url = "https://files.pythonhosted.org/packages/2c/8a/93928dce91e6b3598b5e779e8d1fd6576a504640c58e78627077f6a7a91a/greenlet-3.5.3-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:ea03f2f04367845d6b58eeed276e1e56e51f0b97d8ad5a88a7d20a91dc9056cc", size = 288860, upload-time = "2026-06-26T18:22:48.07Z" }, { url = "https://files.pythonhosted.org/packages/4f/ca/69db42d447a1378043e2c8f19c09cbbd1263371505053c496b49066d3d16/greenlet-3.5.3-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78dbef602fda6d97d957eb7937f70c9ce9e9527330347f8f6b6f9e554a9e7a47", size = 659747, upload-time = "2026-06-26T19:07:15.565Z" }, { url = "https://files.pythonhosted.org/packages/a8/0b/af7ac2ef8dd41e3da1a40dda6305c23b9a03e13ba975ec916357b50f8575/greenlet-3.5.3-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f73857adb8fee13fa56c172bd11262f888c0c648f9fea113e777bb2c7904a81", size = 670419, upload-time = "2026-06-26T19:10:12.293Z" }, + { url = "https://files.pythonhosted.org/packages/25/aa/952cf28c2ff949a8c971134fb43854dd7eaa737218723aaef758f8c9aead/greenlet-3.5.3-cp315-cp315-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cefa9cef4b371f9844c6053db71f1138bc6807bab1578b0dae5149c1f1141357", size = 674261, upload-time = "2026-06-26T19:24:22.79Z" }, { url = "https://files.pythonhosted.org/packages/51/1e/1d51640cacbfc455dbe9f9a9f594c49e4e244f63b9971a2f4764e46cc53d/greenlet-3.5.3-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:232fec92e823addaf02d9472cf7381e24a1d046a6ced1103c5caa4c21b9dfc1d", size = 668787, upload-time = "2026-06-26T18:32:24.298Z" }, + { url = "https://files.pythonhosted.org/packages/dc/f2/b00d6f5e63e531a93562b2ec1a4c320fbee91f580fc42e6417af69d706e5/greenlet-3.5.3-cp315-cp315-manylinux_2_39_riscv64.whl", hash = "sha256:6219b6d04dbf6ba6084d77dc609e8473060dc55f759cbf626d512122781fa128", size = 480322, upload-time = "2026-06-26T19:25:41.852Z" }, { url = "https://files.pythonhosted.org/packages/21/66/4030d5b0b5894500023f003bb054d9bb354dfbd1e186c3a296759172f5f5/greenlet-3.5.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:2421c3564da9429d5586d46ca31ebb26516b5498a802cf65c041a8e8a8980d34", size = 1626305, upload-time = "2026-06-26T19:09:08.281Z" }, { url = "https://files.pythonhosted.org/packages/0e/50/5221371c7550108dfa3c378debc41d032aa9c78e89abb01d8011cfc93289/greenlet-3.5.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e0f0d160f0b2e558e6c75f7930967183255dc9735e5f5b8cae58ee09c9576d8b", size = 1688631, upload-time = "2026-06-26T18:31:51.278Z" }, { url = "https://files.pythonhosted.org/packages/68/5d/00d469daae3c65d2bf620b10eee82eb022127d483c6bc8c69fae6f3fbf17/greenlet-3.5.3-cp315-cp315-win_amd64.whl", hash = "sha256:dd99329bbc15ca78dcc583dba05d0b1b0bae01ab6c2174989f5aaee3e41ac930", size = 241027, upload-time = "2026-06-26T18:22:38.203Z" }, @@ -2024,7 +2078,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1c/da/4f4a8450962fad137c1c8981a3f1b8919d06c829993d4d476f9c525d5173/greenlet-3.5.3-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:176bc16a721fa5fc294d70b87b4dfa5fbdd251b3da5d5372735ecef9bd7d6d0c", size = 297221, upload-time = "2026-06-26T18:23:27.176Z" }, { url = "https://files.pythonhosted.org/packages/57/66/b3bfae3e220a9b63ea539a0eea681800c69ab1aada757eae8789f183e7ce/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:629b614d2b786e89c50440e246f33eea78f58a962d0bdbbcc809e6d13605903f", size = 657221, upload-time = "2026-06-26T19:07:16.973Z" }, { url = "https://files.pythonhosted.org/packages/7b/81/b6d4d73a709684fc77e7fa034d7c2fe82cffa9fc920fadcaa659c2626213/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2b2e857ae16f5f72142edf75f9f176fe7526ba19a2841df1420516f83831c9f2", size = 663226, upload-time = "2026-06-26T19:10:13.723Z" }, + { url = "https://files.pythonhosted.org/packages/e9/39/0e0938a75115b939d42733a2a12e1d349653c9531fe6fe563e8a681f04e6/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:16d192579ed281051396dddd7f7754dac6259e6b1fb26378c87b66622f8e3f91", size = 663706, upload-time = "2026-06-26T19:24:24.312Z" }, { url = "https://files.pythonhosted.org/packages/f5/07/e210b02b589f16e74ff48b730690e4a34ffe984219fce4f3c1a0e7ec8545/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e515757e2e36bcbf1fad09a46e1557e8b1ae1797d4b44d09da7deed88ad28608", size = 660802, upload-time = "2026-06-26T18:32:26.081Z" }, + { url = "https://files.pythonhosted.org/packages/5b/41/35d1c678cdb3c3b9e6bee691728e563cfb294202b23c7a4c3c2ccc343589/greenlet-3.5.3-cp315-cp315t-manylinux_2_39_riscv64.whl", hash = "sha256:4399eb8d041f20b68d943918bc55502a93d6fdc0a37c14da7881c04139acee9d", size = 498803, upload-time = "2026-06-26T19:25:43.063Z" }, { url = "https://files.pythonhosted.org/packages/eb/2e/5303eb3fa06bca089060f479707182a93e360683bc252acf846c3090d34e/greenlet-3.5.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b363d46ed1ea431825fdb01471bb024fc08399bad1572a616e853c7684415adb", size = 1622157, upload-time = "2026-06-26T19:09:09.527Z" }, { url = "https://files.pythonhosted.org/packages/54/70/50de47a488f14df260b50ae34fb5d56016e308b098eab02c878b5223c26a/greenlet-3.5.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:e44da2f5bbdaabaf7d80b73dbb430c7035771e9f244e3c8b769715c9d8fa0a16", size = 1681159, upload-time = "2026-06-26T18:31:52.986Z" }, { url = "https://files.pythonhosted.org/packages/a7/13/1055e1dda7882073eda533e2b96c62e55bbd2db7fda6d5ece992febc7071/greenlet-3.5.3-cp315-cp315t-win_amd64.whl", hash = "sha256:8ff8bed3e3baa20a3ea261ce00526f1898ad4801d4886fd2220580ee0ad8fadf", size = 244007, upload-time = "2026-06-26T18:22:04.353Z" }, @@ -4909,6 +4965,9 @@ daft = [ datafusion = [ { name = "datafusion" }, ] +datasketches = [ + { name = "datasketches" }, +] duckdb = [ { name = "duckdb" }, { name = "pyarrow" }, @@ -4983,6 +5042,7 @@ sql-sqlite = [ dev = [ { name = "coverage", extra = ["toml"] }, { name = "cython" }, + { name = "datasketches" }, { name = "deptry" }, { name = "docutils" }, { name = "fastavro" }, @@ -5034,6 +5094,7 @@ requires-dist = [ { name = "click", specifier = ">=7.1.1" }, { name = "daft", marker = "extra == 'daft'", specifier = ">=0.7.10" }, { name = "datafusion", marker = "extra == 'datafusion'", specifier = ">=52,<53" }, + { name = "datasketches", marker = "extra == 'datasketches'", specifier = ">=3.4.0,<6.0.0" }, { name = "duckdb", marker = "extra == 'duckdb'", specifier = ">=0.5.0" }, { name = "fsspec", specifier = ">=2023.1.0" }, { name = "gcsfs", marker = "extra == 'gcsfs'", specifier = ">=2023.1.0" }, @@ -5069,12 +5130,13 @@ requires-dist = [ { name = "thrift-sasl", marker = "extra == 'hive-kerberos'", specifier = ">=0.4.3" }, { name = "zstandard", specifier = ">=0.13.0" }, ] -provides-extras = ["pyarrow", "pandas", "duckdb", "ray", "bodo", "daft", "polars", "snappy", "hive", "hive-kerberos", "s3fs", "glue", "adlfs", "dynamodb", "bigquery", "sql-postgres", "sql-sqlite", "gcsfs", "rest-sigv4", "hf", "pyiceberg-core", "datafusion", "gcp-auth", "entra-auth", "geoarrow"] +provides-extras = ["pyarrow", "pandas", "duckdb", "ray", "bodo", "daft", "polars", "snappy", "hive", "hive-kerberos", "s3fs", "glue", "adlfs", "dynamodb", "bigquery", "sql-postgres", "sql-sqlite", "gcsfs", "rest-sigv4", "hf", "pyiceberg-core", "datafusion", "gcp-auth", "entra-auth", "geoarrow", "datasketches"] [package.metadata.requires-dev] dev = [ { name = "coverage", extras = ["toml"], specifier = ">=7.4.2" }, { name = "cython", specifier = ">=3.0.0" }, + { name = "datasketches", specifier = ">=3.4.0,<6.0.0" }, { name = "deptry", specifier = ">=0.14" }, { name = "docutils", specifier = "!=0.21.post1" }, { name = "fastavro", specifier = "==1.12.2" },