diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 61092da..c06e381 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -152,6 +152,44 @@ jobs: - name: Run CLI tests run: uv run pytest tests/cli/ -v + + clickhouse-cli-tests: + runs-on: ubuntu-latest + + env: + JETBASE_SQLALCHEMY_URL: clickhouse://default:@localhost:8123/default + + services: + clickhouse: + image: clickhouse/clickhouse-server:latest + env: + CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1 + CLICKHOUSE_PASSWORD: "" + ports: + - 8123:8123 + - 9000:9000 + options: >- + --health-cmd "wget --spider -q http://localhost:8123/ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - uses: actions/checkout@v5 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install uv + uses: astral-sh/setup-uv@v6 + + - name: Install dependencies + run: uv sync --dev --extra clickhouse + + - name: Run CLI tests + run: uv run pytest tests/cli/ -v # TEMP REMOVE: due to snowflake account being down # snowflake-integration-tests: diff --git a/jetbase/commands/lock_status.py b/jetbase/commands/lock_status.py index 9e1bad0..fe690a9 100644 --- a/jetbase/commands/lock_status.py +++ b/jetbase/commands/lock_status.py @@ -1,3 +1,6 @@ +from jetbase.config import get_config +from jetbase.database.queries.base import detect_db +from jetbase.enums import DatabaseType from jetbase.logging import logger from jetbase.models import LockStatus from jetbase.repositories.lock_repo import fetch_lock_status, lock_table_exists @@ -11,9 +14,16 @@ def lock_status_cmd() -> None: Queries the jetbase_lock table to check if migrations are currently locked. If locked, displays the timestamp when the lock was acquired. + For ClickHouse, displays a message that locking is not supported. + Returns: None: Prints "LOCKED" with timestamp or "UNLOCKED" to stdout. """ + # Check for ClickHouse first + sqlalchemy_url: str = get_config(required={"sqlalchemy_url"}).sqlalchemy_url + if detect_db(sqlalchemy_url) == DatabaseType.CLICKHOUSE: + logger.info("ClickHouse does not support database locking.") + return if not lock_table_exists() or not migrations_table_exists(): logger.info("Status: UNLOCKED") diff --git a/jetbase/commands/unlock.py b/jetbase/commands/unlock.py index 1437a1a..ca19d8e 100644 --- a/jetbase/commands/unlock.py +++ b/jetbase/commands/unlock.py @@ -1,3 +1,6 @@ +from jetbase.config import get_config +from jetbase.database.queries.base import detect_db +from jetbase.enums import DatabaseType from jetbase.logging import logger from jetbase.repositories.lock_repo import ( lock_table_exists, @@ -14,9 +17,16 @@ def unlock_cmd() -> None: Use this only if you are certain that no migration is currently running, as unlocking during an active migration can cause database corruption. + For ClickHouse, displays a message that locking is not supported. + Returns: None: Prints "Unlock successful." to stdout. """ + # Check for ClickHouse first + sqlalchemy_url: str = get_config(required={"sqlalchemy_url"}).sqlalchemy_url + if detect_db(sqlalchemy_url) == DatabaseType.CLICKHOUSE: + logger.info("ClickHouse does not support database locking. No lock to release.") + return if not lock_table_exists() or not migrations_table_exists(): logger.info("Unlock successful.") diff --git a/jetbase/database/queries/clickhouse.py b/jetbase/database/queries/clickhouse.py new file mode 100644 index 0000000..4af37e2 --- /dev/null +++ b/jetbase/database/queries/clickhouse.py @@ -0,0 +1,185 @@ +from sqlalchemy import TextClause, text + +from jetbase.database.queries.base import BaseQueries +from jetbase.enums import MigrationType + + +class ClickHouseQueries(BaseQueries): + @staticmethod + def create_migrations_table_stmt() -> TextClause: + return text( + """ + CREATE TABLE IF NOT EXISTS jetbase_migrations ( + order_executed UInt64, + version Nullable(String), + description String, + filename String, + migration_type String, + applied_at DateTime64(6) DEFAULT now64(6), + checksum String + ) ENGINE = MergeTree() + ORDER BY order_executed + """ + ) + + @staticmethod + def insert_version_stmt() -> TextClause: + return text( + """ + INSERT INTO jetbase_migrations (order_executed, version, description, filename, migration_type, checksum, applied_at) + SELECT + (SELECT COALESCE(MAX(order_executed), 0) + 1 FROM jetbase_migrations), + :version, + :description, + :filename, + :migration_type, + :checksum, + now64(6) + """ + ) + + @staticmethod + def check_if_migrations_table_exists_query() -> TextClause: + return text( + """ + SELECT count() > 0 AS table_exists + FROM system.tables + WHERE database = currentDatabase() + AND name = 'jetbase_migrations' + """ + ) + + @staticmethod + def check_if_lock_table_exists_query() -> TextClause: + return text("SELECT 0 AS table_exists") + + @staticmethod + def latest_version_query() -> TextClause: + return text( + f""" + SELECT + version + FROM + jetbase_migrations + WHERE + migration_type = '{MigrationType.VERSIONED.value}' + ORDER BY + order_executed DESC + LIMIT 1 + """ + ) + + @staticmethod + def latest_versions_query() -> TextClause: + return text( + f""" + SELECT + version + FROM + jetbase_migrations + WHERE + migration_type = '{MigrationType.VERSIONED.value}' + ORDER BY + order_executed DESC + LIMIT :limit + """ + ) + + @staticmethod + def latest_versions_by_starting_version_query() -> TextClause: + return text( + f""" + SELECT + version + FROM + jetbase_migrations + WHERE order_executed > + (SELECT order_executed FROM jetbase_migrations + WHERE version = :starting_version AND migration_type = '{MigrationType.VERSIONED.value}') + AND migration_type = '{MigrationType.VERSIONED.value}' + ORDER BY + order_executed DESC + """ + ) + + @staticmethod + def delete_version_stmt() -> TextClause: + return text( + f""" + ALTER TABLE jetbase_migrations DELETE + WHERE version = :version + AND migration_type = '{MigrationType.VERSIONED.value}' + SETTINGS mutations_sync = 1 + """ + ) + + @staticmethod + def update_repeatable_migration_stmt() -> TextClause: + return text( + """ + ALTER TABLE jetbase_migrations + UPDATE checksum = :checksum, applied_at = now64(6) + WHERE filename = :filename + AND migration_type = :migration_type + SETTINGS mutations_sync = 1 + """ + ) + + @staticmethod + def repair_migration_checksum_stmt() -> TextClause: + return text( + f""" + ALTER TABLE jetbase_migrations + UPDATE checksum = :checksum + WHERE version = :version + AND migration_type = '{MigrationType.VERSIONED.value}' + SETTINGS mutations_sync = 1 + """ + ) + + @staticmethod + def delete_missing_version_stmt() -> TextClause: + return text( + f""" + ALTER TABLE jetbase_migrations DELETE + WHERE version = :version + AND migration_type = '{MigrationType.VERSIONED.value}' + SETTINGS mutations_sync = 1 + """ + ) + + @staticmethod + def delete_missing_repeatable_stmt() -> TextClause: + return text( + f""" + ALTER TABLE jetbase_migrations DELETE + WHERE filename = :filename + AND migration_type IN ('{MigrationType.RUNS_ALWAYS.value}', '{MigrationType.RUNS_ON_CHANGE.value}') + SETTINGS mutations_sync = 1 + """ + ) + + @staticmethod + def migration_records_query( + ascending: bool = True, + all_repeatables: bool = False, + migration_type: MigrationType | None = None, + ) -> TextClause: + query: str = f""" + SELECT + order_executed, + version, + description, + filename, + migration_type, + applied_at, + checksum + FROM + jetbase_migrations + {"WHERE migration_type = " + f"'{migration_type.value}'" if migration_type else ""} + {"WHERE migration_type IN ('RUNS_ON_CHANGE', 'RUNS_ALWAYS')" if all_repeatables else ""} + ORDER BY + order_executed {"ASC" if ascending else "DESC"} + """ + + return text(query) diff --git a/jetbase/database/queries/query_loader.py b/jetbase/database/queries/query_loader.py index 174a9fc..babff07 100644 --- a/jetbase/database/queries/query_loader.py +++ b/jetbase/database/queries/query_loader.py @@ -2,6 +2,7 @@ from jetbase.config import get_config from jetbase.database.queries.base import BaseQueries, QueryMethod +from jetbase.database.queries.clickhouse import ClickHouseQueries from jetbase.database.queries.databricks import DatabricksQueries from jetbase.database.queries.mysql import MySQLQueries from jetbase.database.queries.postgres import PostgresQueries @@ -37,6 +38,8 @@ def get_database_type() -> DatabaseType: return DatabaseType.MYSQL elif dialect_name == "databricks": return DatabaseType.DATABRICKS + elif dialect_name == "clickhouse": + return DatabaseType.CLICKHOUSE else: raise ValueError(f"Unsupported database type: {dialect_name}") @@ -66,6 +69,8 @@ def get_queries() -> type[BaseQueries]: return MySQLQueries elif db_type == DatabaseType.DATABRICKS: return DatabricksQueries + elif db_type == DatabaseType.CLICKHOUSE: + return ClickHouseQueries else: raise ValueError(f"Unsupported database type: {db_type}") diff --git a/jetbase/engine/lock.py b/jetbase/engine/lock.py index 55968b1..5e73cb0 100644 --- a/jetbase/engine/lock.py +++ b/jetbase/engine/lock.py @@ -4,9 +4,18 @@ from sqlalchemy.engine import CursorResult +from jetbase.config import get_config +from jetbase.database.queries.base import detect_db +from jetbase.enums import DatabaseType from jetbase.repositories.lock_repo import lock_database, release_lock +def _is_clickhouse() -> bool: + """Check if the current database is ClickHouse.""" + sqlalchemy_url: str = get_config(required={"sqlalchemy_url"}).sqlalchemy_url + return detect_db(sqlalchemy_url) == DatabaseType.CLICKHOUSE + + def acquire_lock() -> str: """ Acquire the migration lock immediately. @@ -46,6 +55,8 @@ def migration_lock() -> Generator[None, None, None]: even if an exception occurs. Fails immediately if the lock is already held by another process. + For ClickHouse, locking is not supported. + Yields: None: Yields control to the context block. @@ -56,6 +67,11 @@ def migration_lock() -> Generator[None, None, None]: >>> with migration_lock(): ... run_migration() """ + # ClickHouse doesn't support reliable locking - skip entirely + if _is_clickhouse(): + yield + return + process_id: str | None = None try: process_id = acquire_lock() diff --git a/jetbase/enums.py b/jetbase/enums.py index 75e8aa9..d3044e2 100644 --- a/jetbase/enums.py +++ b/jetbase/enums.py @@ -24,3 +24,4 @@ class DatabaseType(Enum): SNOWFLAKE = "snowflake" MYSQL = "mysql" DATABRICKS = "databricks" + CLICKHOUSE = "clickhouse" diff --git a/jetbase/repositories/lock_repo.py b/jetbase/repositories/lock_repo.py index d48f984..dd812f0 100644 --- a/jetbase/repositories/lock_repo.py +++ b/jetbase/repositories/lock_repo.py @@ -3,12 +3,20 @@ from sqlalchemy import Result, Row from sqlalchemy.engine import CursorResult +from jetbase.config import get_config from jetbase.database.connection import get_db_connection -from jetbase.database.queries.base import QueryMethod +from jetbase.database.queries.base import QueryMethod, detect_db from jetbase.database.queries.query_loader import get_query +from jetbase.enums import DatabaseType from jetbase.models import LockStatus +def _is_clickhouse() -> bool: + """Check if the current database is ClickHouse.""" + sqlalchemy_url: str = get_config(required={"sqlalchemy_url"}).sqlalchemy_url + return detect_db(sqlalchemy_url) == DatabaseType.CLICKHOUSE + + def lock_table_exists() -> bool: """ Check if the jetbase_lock table exists in the database. @@ -34,9 +42,16 @@ def create_lock_table_if_not_exists() -> None: Creates the lock table and initializes it with a single unlocked record. This table is used to prevent concurrent migrations. + Skipped for ClickHouse as its does not support + reliable database locking. + Returns: None: Table is created as a side effect. """ + # ClickHouse doesn't support reliable locking - skip lock table creation + if _is_clickhouse(): + return + with get_db_connection() as connection: connection.execute(get_query(query_name=QueryMethod.CREATE_LOCK_TABLE_STMT)) diff --git a/pyproject.toml b/pyproject.toml index 4dc0a42..ffba3e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "jetbase" -version = "0.17.3" +version = "0.18.0" description = "Jetbase is a Python database migration tool" readme = "README.md" authors = [ @@ -34,6 +34,7 @@ dev = [ "snowflake-sqlalchemy>=1.8.2", "cryptography>=46.0.3", "pymysql>=1.1.2", + "clickhouse-sqlalchemy>=0.3.0", ] [project.optional-dependencies] @@ -44,6 +45,9 @@ snowflake = [ databricks = [ "databricks-sqlalchemy>=2.0.1", ] +clickhouse = [ + "clickhouse-sqlalchemy>=0.3.0", +] [tool.pytest.ini_options] diff --git a/tests/cli/migrations_clickhouse/RA__ra.sql b/tests/cli/migrations_clickhouse/RA__ra.sql new file mode 100644 index 0000000..cd49328 --- /dev/null +++ b/tests/cli/migrations_clickhouse/RA__ra.sql @@ -0,0 +1 @@ +INSERT INTO users (name) VALUES ('always mike'); \ No newline at end of file diff --git a/tests/cli/migrations_clickhouse/ROC__roc.sql b/tests/cli/migrations_clickhouse/ROC__roc.sql new file mode 100644 index 0000000..5b9e097 --- /dev/null +++ b/tests/cli/migrations_clickhouse/ROC__roc.sql @@ -0,0 +1 @@ +INSERT INTO users (name) VALUES ('on change mike'); \ No newline at end of file diff --git a/tests/cli/migrations_clickhouse/V1__m1.sql b/tests/cli/migrations_clickhouse/V1__m1.sql new file mode 100644 index 0000000..a2768b6 --- /dev/null +++ b/tests/cli/migrations_clickhouse/V1__m1.sql @@ -0,0 +1,7 @@ +CREATE TABLE users +( + id UUID DEFAULT generateUUIDv4(), + name String +) +ENGINE = MergeTree +ORDER BY id; \ No newline at end of file diff --git a/tests/cli/migrations_clickhouse/V21__mi21.sql b/tests/cli/migrations_clickhouse/V21__mi21.sql new file mode 100644 index 0000000..02c5516 --- /dev/null +++ b/tests/cli/migrations_clickhouse/V21__mi21.sql @@ -0,0 +1,4 @@ +INSERT INTO users (name) VALUES ('mike21'); + +--rollback +DELETE FROM users WHERE name = 'mike21'; \ No newline at end of file diff --git a/tests/cli/migrations_clickhouse/V2__m2.sql b/tests/cli/migrations_clickhouse/V2__m2.sql new file mode 100644 index 0000000..5fe57b8 --- /dev/null +++ b/tests/cli/migrations_clickhouse/V2__m2.sql @@ -0,0 +1,4 @@ +INSERT INTO users (name) VALUES ('mike2'); + +--rollback +DELETE FROM users WHERE name = 'mike2'; \ No newline at end of file diff --git a/tests/cli/migrations_clickhouse/V3__m3.sql b/tests/cli/migrations_clickhouse/V3__m3.sql new file mode 100644 index 0000000..d8b8813 --- /dev/null +++ b/tests/cli/migrations_clickhouse/V3__m3.sql @@ -0,0 +1,4 @@ +INSERT INTO users (name) VALUES ('mike3'); + +--rollback +DELETE FROM users WHERE name = 'mike3'; \ No newline at end of file diff --git a/tests/cli/migrations_clickhouse/V4__m4.sql b/tests/cli/migrations_clickhouse/V4__m4.sql new file mode 100644 index 0000000..d75843f --- /dev/null +++ b/tests/cli/migrations_clickhouse/V4__m4.sql @@ -0,0 +1,4 @@ +INSERT INTO users (name) VALUES ('mike4'); + +--rollback +DELETE FROM users WHERE name = 'mike4'; \ No newline at end of file diff --git a/tests/cli/migrations_clickhouse_versions_only/V1__m1.sql b/tests/cli/migrations_clickhouse_versions_only/V1__m1.sql new file mode 100644 index 0000000..a2768b6 --- /dev/null +++ b/tests/cli/migrations_clickhouse_versions_only/V1__m1.sql @@ -0,0 +1,7 @@ +CREATE TABLE users +( + id UUID DEFAULT generateUUIDv4(), + name String +) +ENGINE = MergeTree +ORDER BY id; \ No newline at end of file diff --git a/tests/cli/migrations_clickhouse_versions_only/V21__mi21.sql b/tests/cli/migrations_clickhouse_versions_only/V21__mi21.sql new file mode 100644 index 0000000..02c5516 --- /dev/null +++ b/tests/cli/migrations_clickhouse_versions_only/V21__mi21.sql @@ -0,0 +1,4 @@ +INSERT INTO users (name) VALUES ('mike21'); + +--rollback +DELETE FROM users WHERE name = 'mike21'; \ No newline at end of file diff --git a/tests/cli/migrations_clickhouse_versions_only/V2__m2.sql b/tests/cli/migrations_clickhouse_versions_only/V2__m2.sql new file mode 100644 index 0000000..5fe57b8 --- /dev/null +++ b/tests/cli/migrations_clickhouse_versions_only/V2__m2.sql @@ -0,0 +1,4 @@ +INSERT INTO users (name) VALUES ('mike2'); + +--rollback +DELETE FROM users WHERE name = 'mike2'; \ No newline at end of file diff --git a/tests/cli/migrations_clickhouse_versions_only/V3__m3.sql b/tests/cli/migrations_clickhouse_versions_only/V3__m3.sql new file mode 100644 index 0000000..d8b8813 --- /dev/null +++ b/tests/cli/migrations_clickhouse_versions_only/V3__m3.sql @@ -0,0 +1,4 @@ +INSERT INTO users (name) VALUES ('mike3'); + +--rollback +DELETE FROM users WHERE name = 'mike3'; \ No newline at end of file diff --git a/tests/cli/migrations_clickhouse_versions_only/V4__m4.sql b/tests/cli/migrations_clickhouse_versions_only/V4__m4.sql new file mode 100644 index 0000000..d75843f --- /dev/null +++ b/tests/cli/migrations_clickhouse_versions_only/V4__m4.sql @@ -0,0 +1,4 @@ +INSERT INTO users (name) VALUES ('mike4'); + +--rollback +DELETE FROM users WHERE name = 'mike4'; \ No newline at end of file diff --git a/tests/cli/test_lock_status.py b/tests/cli/test_lock_status.py index 82e7a19..077b064 100644 --- a/tests/cli/test_lock_status.py +++ b/tests/cli/test_lock_status.py @@ -2,11 +2,14 @@ import os import uuid +import pytest from sqlalchemy import text from jetbase.cli.main import app +from tests.utils import is_clickhouse +@pytest.mark.skipif(is_clickhouse(), reason="ClickHouse doesn't support locking") def test_lock_status_unlocked( runner, test_db_url, clean_db, setup_migrations_versions_only, caplog ): @@ -22,6 +25,7 @@ def test_lock_status_unlocked( assert "unlocked" in caplog.text.lower() +@pytest.mark.skipif(is_clickhouse(), reason="ClickHouse doesn't support locking") def test_lock_status_locked( runner, test_db_url, clean_db, setup_migrations_versions_only, caplog ): diff --git a/tests/cli/test_rollback.py b/tests/cli/test_rollback.py index 78136a8..33d4cf5 100644 --- a/tests/cli/test_rollback.py +++ b/tests/cli/test_rollback.py @@ -1,10 +1,10 @@ import os +import pytest from sqlalchemy import text from jetbase.cli.main import app from jetbase.exceptions import VersionNotFoundError -import pytest @pytest.mark.snowflake @@ -32,8 +32,8 @@ def test_rollback(runner, test_db_url, clean_db, setup_migrations): migrations_result = connection.execute( text("SELECT COUNT(*) FROM jetbase_migrations") ) - count = migrations_result.scalar() - assert count == 6 + count = migrations_result.scalar() + assert count == 6 def test_rollback_with_count(runner, test_db_url, clean_db, setup_migrations): diff --git a/tests/cli/test_unlock.py b/tests/cli/test_unlock.py index 0174c66..e807c05 100644 --- a/tests/cli/test_unlock.py +++ b/tests/cli/test_unlock.py @@ -2,11 +2,14 @@ import os import uuid +import pytest from sqlalchemy import text from jetbase.cli.main import app +from tests.utils import is_clickhouse +@pytest.mark.skipif(is_clickhouse(), reason="ClickHouse doesn't support locking") def test_unlock_already_unlocked( runner, test_db_url, clean_db, setup_migrations_versions_only, caplog ): @@ -22,6 +25,7 @@ def test_unlock_already_unlocked( assert "unlock" in caplog.text.lower() +@pytest.mark.skipif(is_clickhouse(), reason="ClickHouse doesn't support locking") def test_lock_status_locked( runner, test_db_url, clean_db, setup_migrations_versions_only, caplog ): @@ -33,13 +37,15 @@ def test_lock_status_locked( assert result.exit_code == 0 connection.execute( - text(""" + text( + """ UPDATE jetbase_lock SET is_locked = TRUE, locked_at = :locked_at, process_id = :process_id WHERE id = 1 AND is_locked = FALSE - """), + """ + ), { "locked_at": dt.datetime.now(dt.timezone.utc), "process_id": str(uuid.uuid4()), diff --git a/tests/conftest.py b/tests/conftest.py index 7d4bb9f..129968f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -77,6 +77,9 @@ def migrations_fixture_dir(test_db_url): if detect_db(test_db_url) == DatabaseType.DATABRICKS: return base_path / "migrations_databricks" + if detect_db(test_db_url) == DatabaseType.CLICKHOUSE: + return base_path / "migrations_clickhouse" + return base_path / "migrations" @@ -94,6 +97,9 @@ def migrations_versions_only_fixture_dir(test_db_url): if detect_db(test_db_url) == DatabaseType.DATABRICKS: return base_path / "migrations_databricks_versions_only" + if detect_db(test_db_url) == DatabaseType.CLICKHOUSE: + return base_path / "migrations_clickhouse_versions_only" + return base_path / "migrations_versions_only" diff --git a/tests/unit/engine/test_lock.py b/tests/unit/engine/test_lock.py index 1f00f68..a64cba4 100644 --- a/tests/unit/engine/test_lock.py +++ b/tests/unit/engine/test_lock.py @@ -32,26 +32,43 @@ def test_raises_runtime_error_when_already_locked( class TestMigrationLock: """Tests for the migration_lock context manager.""" + @pytest.mark.parametrize("is_clickhouse", [False, True]) @patch("jetbase.engine.lock.release_lock") @patch("jetbase.engine.lock.acquire_lock", return_value="test-id") def test_acquires_and_releases_lock( - self, mock_acquire: Mock, mock_release: Mock + self, mock_acquire: Mock, mock_release: Mock, is_clickhouse: bool ) -> None: - """Test that lock is acquired on entry and released on exit.""" - with migration_lock(): - pass + """Test that lock is acquired on entry and released on exit (non-ClickHouse) + or skipped entirely (ClickHouse).""" + with patch("jetbase.engine.lock._is_clickhouse", return_value=is_clickhouse): + with migration_lock(): + pass - mock_acquire.assert_called_once() - mock_release.assert_called_once() + if is_clickhouse: + # ClickHouse skips locking entirely + mock_acquire.assert_not_called() + mock_release.assert_not_called() + else: + # Normal databases acquire and release lock + mock_acquire.assert_called_once() + mock_release.assert_called_once() + @pytest.mark.parametrize("is_clickhouse", [False, True]) @patch("jetbase.engine.lock.release_lock") @patch("jetbase.engine.lock.acquire_lock", return_value="test-id") def test_releases_lock_on_exception( - self, mock_acquire: Mock, mock_release: Mock + self, mock_acquire: Mock, mock_release: Mock, is_clickhouse: bool ) -> None: - """Test that lock is released even when an exception occurs.""" - with pytest.raises(ValueError): - with migration_lock(): - raise ValueError("test error") + """Test that lock is released even when an exception occurs (non-ClickHouse) + or skipped entirely (ClickHouse).""" + with patch("jetbase.engine.lock._is_clickhouse", return_value=is_clickhouse): + with pytest.raises(ValueError): + with migration_lock(): + raise ValueError("test error") - mock_release.assert_called_once() + if is_clickhouse: + # ClickHouse skips locking entirely + mock_release.assert_not_called() + else: + # Normal databases release lock even on exception + mock_release.assert_called_once() diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 0000000..a7234e6 --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,6 @@ +import os + + +def is_clickhouse(): + url = os.environ.get("JETBASE_SQLALCHEMY_URL", "") + return "clickhouse" in url.lower() diff --git a/uv.lock b/uv.lock index 4cca2c5..3f77d45 100644 --- a/uv.lock +++ b/uv.lock @@ -18,6 +18,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl", hash = "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67", size = 105045, upload-time = "2022-03-15T14:46:51.055Z" }, ] +[[package]] +name = "asynch" +version = "0.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ciso8601" }, + { name = "leb128" }, + { name = "lz4" }, + { name = "pytz" }, + { name = "tzlocal" }, + { name = "zstd" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/ce/f11ee2cafa6010d295db3ddee089f14cfc5fa9b8a19d0a21356c18a49267/asynch-0.3.1.tar.gz", hash = "sha256:d8bb3c1793a74a2e9d44cc7e8406ead3cf3818c11ecd6d8405b702b23148c584", size = 59825, upload-time = "2025-11-11T15:20:22.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/b0/9547aeadb577cb0c590162661b31110f7c3c02c1b23653a1b33222c7ff70/asynch-0.3.1-py3-none-any.whl", hash = "sha256:32b30a4409b70514077f7bf8ef713a248158fe5e63504c2769a4c7f772828412", size = 76502, upload-time = "2025-11-11T15:20:21.46Z" }, +] + [[package]] name = "boto3" version = "1.42.25" @@ -226,6 +243,58 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, ] +[[package]] +name = "ciso8601" +version = "2.3.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c1/8a/075724aea06c98626109bfd670c27c248c87b9ba33e637f069bf46e8c4c3/ciso8601-2.3.3.tar.gz", hash = "sha256:db5d78d9fb0de8686fbad1c1c2d168ed52efb6e8bf8774ae26226e5034a46dae", size = 31909, upload-time = "2025-08-20T16:31:33.51Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/c1/ebdb2614bb7a7a8ea7b496709bdec4cd0842ef38cde44203f4986df2d8f9/ciso8601-2.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf67a1d47a52dad19aaffb136de63263910dcab6e50d428f27416733ce81f183", size = 16077, upload-time = "2025-08-20T16:30:18.097Z" }, + { url = "https://files.pythonhosted.org/packages/e8/bb/0d100a3774c8d15b432f693e8897891c3af4536a36b0c8ed7a527f319c8f/ciso8601-2.3.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:67316d2a2d278fad3d569771b032e9bd8484c8aab842e1a2524f6433260cf9ac", size = 24112, upload-time = "2025-08-20T16:30:19.261Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b8/52af79a935073c4f2a31a3e73ab531dd5f41e8544eafd84ef5cc14b0c198/ciso8601-2.3.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:48e0ac5d411d186865fdf0d30529fb7ae6df7c8d622540d5274b453f0e7b935a", size = 15868, upload-time = "2025-08-20T16:30:20.436Z" }, + { url = "https://files.pythonhosted.org/packages/36/b0/6a9f59dc68dab198df18fcb47999d9d18b67765706f7d9292814def99dac/ciso8601-2.3.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9063aa362b291a72d395980e1b6479366061ec77d98ae7375aa5891abe0c6b9d", size = 40017, upload-time = "2025-08-20T16:30:21.441Z" }, + { url = "https://files.pythonhosted.org/packages/31/1f/662b51464c2873ba345db671048e441267437e1ce802f079e024e9305b5b/ciso8601-2.3.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe7b832298a70ac39ef0b3cd1ce860289a2b45d2fdca2c2acd26551e29273487", size = 40519, upload-time = "2025-08-20T16:30:22.369Z" }, + { url = "https://files.pythonhosted.org/packages/14/ec/8f9ebbc8e3330d3c2374983cfe7553592d53cdeb59a35078ce135c81d83d/ciso8601-2.3.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c0e81268f84f6ed5a8f07026abed8ffa4fa54953e5763802b259e170f7bd7fb0", size = 39986, upload-time = "2025-08-20T16:30:23.582Z" }, + { url = "https://files.pythonhosted.org/packages/24/c4/cff2f87395514ae70938b71ce4ceba975e71b000fd507ad000a8cd917a0b/ciso8601-2.3.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:44fdb272acdc59e94282f6155eacbff8cd9687a2a84df0bbbed2b1bd53fa8406", size = 40236, upload-time = "2025-08-20T16:30:24.827Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7e/aef1d665c5097f71ed58684009d4b5c1cbfdb02373bbb04f22e0930dff6c/ciso8601-2.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:74b14ffaddb890a48d03b3b97cc3f56875a4a93b3116b023add408e45b010c22", size = 17520, upload-time = "2025-08-20T16:30:25.77Z" }, + { url = "https://files.pythonhosted.org/packages/fc/30/5744492f9e7dbe60a3c92968cdb8987566f5389b8d0e5c60f6d633da45fe/ciso8601-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f068fb60b801640b4d729a3cf79f5b3075c071f0dad3a08e5bf68b89ca41aef7", size = 16076, upload-time = "2025-08-20T16:30:27.005Z" }, + { url = "https://files.pythonhosted.org/packages/e0/c6/ce97f28a3b936a9a6c0abba9905382cb89022b8e1abb37a2150c1caf71d6/ciso8601-2.3.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:2f347401756cdd552420a4596a0535a4f8193298ff401e41fb31603e182ae302", size = 24110, upload-time = "2025-08-20T16:30:28.243Z" }, + { url = "https://files.pythonhosted.org/packages/dc/89/1af026c7959d39bdbaa6400b76ffb54437fa52698b801d51ddaa14063f0e/ciso8601-2.3.3-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:77e8e691ade14dd0e2ae1bcdd98475c25cd76be34b1cf43d9138bbb7ea7a8a37", size = 15871, upload-time = "2025-08-20T16:30:30.059Z" }, + { url = "https://files.pythonhosted.org/packages/a4/1a/9ae630bf75a51755bf701660a65207b8efa2f95590408832b38e58834d57/ciso8601-2.3.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a5839ea7d2edf22e0199587e2ea71bc082b0e7ffce90389c7bdd407c05dbf230", size = 40380, upload-time = "2025-08-20T16:30:31.211Z" }, + { url = "https://files.pythonhosted.org/packages/4f/3c/8671bde2bbf6abb8ceee82db0bc6bcd08066e7104680e3866eda6047adc1/ciso8601-2.3.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de0476ced02b965ef82c20191757f26e14878c76ce8d32a94c1e9ee14658ec6e", size = 40914, upload-time = "2025-08-20T16:30:32.096Z" }, + { url = "https://files.pythonhosted.org/packages/8e/bc/433f91f19ff553653f340e77dbb12afe46de8a84a407ae01483d22ea8f7a/ciso8601-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe9303131af07e3596583e9d7faebb755d44c52c16f8077beeea1b297541fb61", size = 40154, upload-time = "2025-08-20T16:30:33.325Z" }, + { url = "https://files.pythonhosted.org/packages/48/b7/39b905b09f77f2140724707919edea2a3d34b00a9366cd7ad541aefb464e/ciso8601-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4c443761b899e4e350a647b3439f8e999d6c925dc4e83887b3063b13c2a9b195", size = 40428, upload-time = "2025-08-20T16:30:34.626Z" }, + { url = "https://files.pythonhosted.org/packages/f2/11/e676e1ac5dd8523dfc2e06c799840103343dc13c650d6ed06c63a8e41d5a/ciso8601-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:e3a395ebc5932982a72841820a6bf6e5cd1d41a760cd15ffafd1d4e963c9b802", size = 17519, upload-time = "2025-08-20T16:30:35.539Z" }, + { url = "https://files.pythonhosted.org/packages/62/aa/b723a6981cfc42bbe992da23179f5dd1556e9054067985108ec6cbe34dd3/ciso8601-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e7ef14610446211c4102bf6c67f32619ab341e56db15bad6884385b43c12b064", size = 16111, upload-time = "2025-08-20T16:30:36.781Z" }, + { url = "https://files.pythonhosted.org/packages/0a/e9/e547ec4dd75f28d8d217488130fa07767bc42fd643d61a18870487133c0e/ciso8601-2.3.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:523901aec6b0ccdf255c863ef161f476197f177c5cd33f2fbb35955c5f97fdb4", size = 24193, upload-time = "2025-08-20T16:30:38.067Z" }, + { url = "https://files.pythonhosted.org/packages/14/c8/801b78e30667cb31b4524e9dc26cbc2c03c012f9aa3f5ae21676461dc622/ciso8601-2.3.3-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:45f8254d1fb0a41e20f98e93075db7b56504adddf65e4c8b397671feba4861ca", size = 15917, upload-time = "2025-08-20T16:30:39.375Z" }, + { url = "https://files.pythonhosted.org/packages/44/6b/dfc56a2a4e572a2a3f8c88a66dea6a9186a8e10da7c36cc84abc31bf795c/ciso8601-2.3.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:202ca99077577683e6a84d394ff2677ec19d9f406fbf35734f68be85d2bcd3f1", size = 41324, upload-time = "2025-08-20T16:30:40.321Z" }, + { url = "https://files.pythonhosted.org/packages/7c/57/cf66171cb5807fe345b03ce9e32fd91b3a8b6e5bd95710618a9a1b0f3fab/ciso8601-2.3.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a7cec4e31c363e87221f2561e7083ce055a82de041e822e7c3775f8ce6250a7e", size = 41804, upload-time = "2025-08-20T16:30:41.204Z" }, + { url = "https://files.pythonhosted.org/packages/75/91/15e8871d7ae2ff0f756128e246348bdede58c08edba13cd886450ceeb304/ciso8601-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:389fef3ccc3065fa21cb6ef7d03aee63ab980591b5d87b9f0bbe349f52b16bdc", size = 41209, upload-time = "2025-08-20T16:30:42.46Z" }, + { url = "https://files.pythonhosted.org/packages/30/54/7563e20a158a4bdf3e8d13c63e02b71f9b73c662edc83cb4d5ab67171a7d/ciso8601-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c4499cfbe4da092dea95ab81aefc78b98e2d7464518e6e80107cf2b9b1f65fa2", size = 41368, upload-time = "2025-08-20T16:30:43.397Z" }, + { url = "https://files.pythonhosted.org/packages/cc/d5/6182006dd86365bb21d1f658f70c41e266ce0f97eaf353f9d7069c51851f/ciso8601-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:1df1ca3791c6f2d543f091d88e728a60a31681ff900d9eb02f1403cf31e9c177", size = 17566, upload-time = "2025-08-20T16:30:44.706Z" }, + { url = "https://files.pythonhosted.org/packages/01/16/88154fe8247e4dcfdbaed8c6b8ccf32b1dd4389c6c95b1986bf31649eb00/ciso8601-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8afa073802c926c3244e1e5fcc5818afd3acb90fb7826a90f91ddbda0636ea70", size = 16109, upload-time = "2025-08-20T16:30:45.655Z" }, + { url = "https://files.pythonhosted.org/packages/be/46/8d46372b3802c7201c20c8b316569f27253aaafba0cdd2cd033985e8b77e/ciso8601-2.3.3-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:8a04e518b4adf8e35e030feaecdb4a835d39b9bb44d207e926aea8ce3447ad7c", size = 24189, upload-time = "2025-08-20T16:30:46.958Z" }, + { url = "https://files.pythonhosted.org/packages/13/80/1890e097cb76e41995de82f29c0289ca590d7135e0be3707e5b78f54350d/ciso8601-2.3.3-cp313-cp313-macosx_11_0_x86_64.whl", hash = "sha256:f79ad8372463ba4265981016d1648bc05f4922bc8044c4243fcbaef7a12ee9f7", size = 15925, upload-time = "2025-08-20T16:30:48.082Z" }, + { url = "https://files.pythonhosted.org/packages/a7/e9/690a2a6beefd9d982c20adde3f09ff54a23291a699b0df7cf0c59027d9cf/ciso8601-2.3.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d5894a33f119b5ac1082df187dc58c74fe13c9c092e19ba36495c2b7cee3540b", size = 41352, upload-time = "2025-08-20T16:30:49.294Z" }, + { url = "https://files.pythonhosted.org/packages/2f/34/9a498ceb0ebd23f538e6685721c9fc4666701372c651874ed22ec46b1423/ciso8601-2.3.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09deebf3e326ec59d80019b4ad35175c90b99cde789c644b1496811fe3340587", size = 41866, upload-time = "2025-08-20T16:30:50.262Z" }, + { url = "https://files.pythonhosted.org/packages/f7/0a/ee0981502aa1c9f28f7e89cf6cee08bdff2c6ed9d4289b00cceb8a1c500e/ciso8601-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3aa43ed59b2117baccc5bb760e5e53dad77cacba671d757c1e82e0a367b1f42a", size = 41271, upload-time = "2025-08-20T16:30:51.198Z" }, + { url = "https://files.pythonhosted.org/packages/fb/65/24a888240324188d8350bc24fb58a6d759c0ca43adfa77210f3d60370b56/ciso8601-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:289515aa3a3b86a9c3450bf482f634138b98788332d136751507bfdfe46e6031", size = 41411, upload-time = "2025-08-20T16:30:52.439Z" }, + { url = "https://files.pythonhosted.org/packages/3d/1f/febc9de191acb461e02e616e5366bc2b7757277a11b4bf215d4fb79516a8/ciso8601-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:e7288068a5bffbcc50cbe9cdaf3971f541fcd209c194fa6a59ad06066a3dcff0", size = 17573, upload-time = "2025-08-20T16:30:53.759Z" }, + { url = "https://files.pythonhosted.org/packages/ef/3a/54ad0ae2257870076b4990545a8f16221470fecea0aa7a4e1f39506db8c5/ciso8601-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:82db4047d74d8b1d129e7a8da578518729912c3bd19cb71541b147e41f426381", size = 16115, upload-time = "2025-08-20T16:30:54.971Z" }, + { url = "https://files.pythonhosted.org/packages/23/fb/9fe767d44520691e2b706769466852fbdeb44a82dc294c2766bce1049d22/ciso8601-2.3.3-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:a553f3fc03a2ed5ca6f5716de0b314fa166461df01b45d8b36043ccac3a5e79f", size = 24214, upload-time = "2025-08-20T16:30:56.359Z" }, + { url = "https://files.pythonhosted.org/packages/a1/ac/984fd3948f372c46c436a2b48da43f4fb7bc6f156a6f4bc858adaab79d42/ciso8601-2.3.3-cp314-cp314-macosx_11_0_x86_64.whl", hash = "sha256:ff59c26083b7bef6df4f0d96e4b649b484806d3d7bcc2de14ad43147c3aafb04", size = 15929, upload-time = "2025-08-20T16:30:58.352Z" }, + { url = "https://files.pythonhosted.org/packages/de/3a/5572917d4e0bec2c1ef0eda8652f9dc8d1850d29d3eef9e5e82ffe5d6791/ciso8601-2.3.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:99a1fa5a730790431d0bfcd1f3a6387f60cddc6853d8dcc5c2e140cd4d67a928", size = 41578, upload-time = "2025-08-20T16:30:59.351Z" }, + { url = "https://files.pythonhosted.org/packages/5e/cf/07321ce5cf099b98de0c02cd4bab4818610da69743003e94c8fb6e8a59cb/ciso8601-2.3.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c35265c1b0bd2ac30ed29b49818dd38b0d1dfda43086af605d8b91722727dec0", size = 42085, upload-time = "2025-08-20T16:31:00.338Z" }, + { url = "https://files.pythonhosted.org/packages/d3/c7/3c521d6779ee433d9596eb3fcded79549bbe371843f25e62006c04f74dc9/ciso8601-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:aa9df2f84ab25454f14df92b2dd4f9aae03dbfa581565a716b3e89b8e2110c03", size = 41313, upload-time = "2025-08-20T16:31:01.313Z" }, + { url = "https://files.pythonhosted.org/packages/f9/93/efd40db0d6b512be1cbe4e7e750882c2e88f580e17f35b3e9cc9c23004b5/ciso8601-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:32e06a35eb251cfc4bbe01a858c598da0a160e4ad7f42ff52477157ceaf48061", size = 41443, upload-time = "2025-08-20T16:31:02.357Z" }, + { url = "https://files.pythonhosted.org/packages/21/8e/515f9404faa39af8df5e2b899cafbca5dbe7cd2ffe5cc124ef393ffdaf1c/ciso8601-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:7657ba9730dc1340d73b9e61eca14f341c41dd308128c808b8b084d2b85bc03e", size = 17977, upload-time = "2025-08-20T16:31:03.429Z" }, + { url = "https://files.pythonhosted.org/packages/83/e5/eee65bc8c91e5981ed3440dbd4e546ff14b67deba07f6f346de1a61f28c0/ciso8601-2.3.3-pp310-pypy310_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1d88ab28ecb3626e3417c564e8aec9d0245b4eb75e773d2e7f3f095ea9897ded", size = 16956, upload-time = "2025-08-20T16:31:24.869Z" }, + { url = "https://files.pythonhosted.org/packages/38/fc/809cba0f1928d1d45a4e5c9d789b06fd092a145702d32a41394f4b9665ca/ciso8601-2.3.3-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8d5a37798bf0cab6144daa2b6d07657ab1a63df540de24c23a809fb2bdf36149", size = 18285, upload-time = "2025-08-20T16:31:26.143Z" }, + { url = "https://files.pythonhosted.org/packages/f1/1d/025db546af38ab5236086f462292c50a1f9a4b248a309129a85bb1113996/ciso8601-2.3.3-pp311-pypy311_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d5b18c75c66499ef22cb47b429e3b5a137db5a68674365b9ca3cd0e4488d229f", size = 16957, upload-time = "2025-08-20T16:31:27.503Z" }, + { url = "https://files.pythonhosted.org/packages/22/fc/976d9c4b79e28cbda95b1acf574b00f811d9aec0fce55b63d573d6fa446b/ciso8601-2.3.3-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:58799673ffdf621fe138fb8af6a89daf4ddefdf7ca4a10777ad8d55f3f171b6e", size = 18284, upload-time = "2025-08-20T16:31:28.43Z" }, +] + [[package]] name = "click" version = "8.3.0" @@ -238,6 +307,98 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" }, ] +[[package]] +name = "clickhouse-driver" +version = "0.2.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytz" }, + { name = "tzlocal" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/46/9e/d8e40b29b6269a84552441a553fc64dff28f2d7e2d92e81c6be84fe12b4c/clickhouse_driver-0.2.10.tar.gz", hash = "sha256:925fc6ecda1e5314e3f03bcb493955c068b070cdba221fb8ce27329ee8a7f71b", size = 409448, upload-time = "2025-11-10T22:49:58.764Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/82/a7ddf5d34abb71fd82c3dec4da75e5b4d1c91a3ba7a407686e9bb43f2bcc/clickhouse_driver-0.2.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1dc2b570b3c02baf1ba759f1db3cc5d49b4f968f32dd56710ca4f892700079c1", size = 212722, upload-time = "2025-11-10T22:47:07.407Z" }, + { url = "https://files.pythonhosted.org/packages/f4/8f/67d3a1b81f8eb4ace6b18d0cb930a4a1cf1537c281fc9ee083adf16d0c77/clickhouse_driver-0.2.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5be143e33e330e856e65d40cdfdd38c0f215ba5140807aee5e923fd0c8cf04c8", size = 208490, upload-time = "2025-11-10T22:47:09.514Z" }, + { url = "https://files.pythonhosted.org/packages/b9/eb/c5aed06221c229108f4e6774eda4425e1db9fc6b4cc3a16dbb328f7017f8/clickhouse_driver-0.2.10-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27397d41661b8aa29b304c70e06ba820c8158e8c6708beac4edb360aa56e7755", size = 952844, upload-time = "2025-11-10T22:47:12.502Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ff/2e15d7ff029637a31d9549f17cd2ec87153f09b7e29d7e95b8fd47ed9379/clickhouse_driver-0.2.10-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca517354471a43e35852da6943c9a005f420e20e75c6444f8d640277d2eb026a", size = 1007221, upload-time = "2025-11-10T22:47:15.306Z" }, + { url = "https://files.pythonhosted.org/packages/02/eb/611132def5e1fa1c466655fa60342f58fdba8c80e70ad3dd171ab0802cc4/clickhouse_driver-0.2.10-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea3a0c852f227d0217bf72f536b8056804c9fc932ea8a48845d68f68e473b242", size = 1017177, upload-time = "2025-11-10T22:47:18.003Z" }, + { url = "https://files.pythonhosted.org/packages/86/df/cf6e9059f289c4a779ace15e7988fb63ca09560c5128dcc8881e3fd151f1/clickhouse_driver-0.2.10-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ea94c2f6d42263395d0d86ce21788c167009451044046b825ecffb6746803b67", size = 943615, upload-time = "2025-11-10T22:47:20.242Z" }, + { url = "https://files.pythonhosted.org/packages/36/34/477ce6b3e23f0610f07fef59de11316527b7cca2875a21628b1ec3b18d7d/clickhouse_driver-0.2.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:46aebe903aff48452ed64de81c6a218c37f9617c9a1ea1eb84ed4c410899c620", size = 922447, upload-time = "2025-11-10T22:47:22.254Z" }, + { url = "https://files.pythonhosted.org/packages/ab/d4/1553fead669cb4ef2c0cc3be19d884b3ac0128e5248181c8a7a383e60d7e/clickhouse_driver-0.2.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:908b69d2f2c51cf0603a5464be51df5f0e3e670b75f1d17a3b51a4bb8481620a", size = 971509, upload-time = "2025-11-10T22:47:24.722Z" }, + { url = "https://files.pythonhosted.org/packages/ab/c4/c44f339e9e11ff79d77547d18a4d61f1da79ba6802262b418ceee0d0233b/clickhouse_driver-0.2.10-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:4a61dac61cbed12789ad0bced043f6215e0253e0a41a2e8ee419d0be84f2acfb", size = 960931, upload-time = "2025-11-10T22:47:27.182Z" }, + { url = "https://files.pythonhosted.org/packages/1a/6c/04b7de8132e38e4a459f32b5266b24ec3325164f8dc901eabe569b1ee0e0/clickhouse_driver-0.2.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b97c257b90cc23a0ce64ecabc79ec627bbc51b5fb129607e79974139f62eb86e", size = 921846, upload-time = "2025-11-10T22:47:29.684Z" }, + { url = "https://files.pythonhosted.org/packages/a8/45/123351a3c95a2a3200f5dcae5d156458c2d9d28e3d258b8b24fce42932ff/clickhouse_driver-0.2.10-cp310-cp310-win32.whl", hash = "sha256:deb2463626345e36bfa59747f2fcc016f963a4d46e949d1e0a570a9f4a0dabfc", size = 190525, upload-time = "2025-11-10T22:47:31.174Z" }, + { url = "https://files.pythonhosted.org/packages/ab/7d/29249f47803ac3b051dbb041cab26863c5057801d2dbee2da20687022927/clickhouse_driver-0.2.10-cp310-cp310-win_amd64.whl", hash = "sha256:b1641dcef0af756e34e77d96761abbeacbe490e750ed048f35ca6e939b230067", size = 203074, upload-time = "2025-11-10T22:47:32.365Z" }, + { url = "https://files.pythonhosted.org/packages/13/9d/bb9ee6df5a8fb60b56f9ca76cb9b22beb6d47d45ce561dca4ef9a63c1d4a/clickhouse_driver-0.2.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946daf834f021d69acbebee7abde87bd4ad5aa46fa7b7643805abc7ff487a91f", size = 212466, upload-time = "2025-11-10T22:47:33.591Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e0/1ae285f4d5bb61bb62016deb38dc175a2b8cbe578dffdad5e1a5a02a176c/clickhouse_driver-0.2.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3572e74cd65828f72284bf607de259c059178b44b19a93cb67766b7e7458cf8e", size = 208477, upload-time = "2025-11-10T22:47:34.925Z" }, + { url = "https://files.pythonhosted.org/packages/28/04/e2fb47a4aaf9653c9ed872e1505e997d42f834b0891351ef54169e100c5c/clickhouse_driver-0.2.10-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:767af2b2d2e02fb7abd8fc9619f8aa2de65be010d3024029d68bc9b1be564466", size = 1006131, upload-time = "2025-11-10T22:47:36.386Z" }, + { url = "https://files.pythonhosted.org/packages/e3/52/626cf3a908dde51638213a6c414e86bc66c47e384cb379c4a0533930a329/clickhouse_driver-0.2.10-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b00005a89f0e40ec0bc313f7e131d958aa17e6af5c3260dbb5c7daf5370c5443", size = 1059838, upload-time = "2025-11-10T22:47:38.266Z" }, + { url = "https://files.pythonhosted.org/packages/12/57/a5917930760e4032e98017916bd6770308e146d44c58e450da6fa87f2d4b/clickhouse_driver-0.2.10-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a62ad120dab6bcc68b6413b7ef0dbaef75ab5ca985d490a9e1ec13d93bf33dc3", size = 1069504, upload-time = "2025-11-10T22:47:40.681Z" }, + { url = "https://files.pythonhosted.org/packages/f5/08/4419ce43b27b6349fd14af0d8f5d8594d270b9bb24cbaca575bacfec630e/clickhouse_driver-0.2.10-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9f65e71c99f0c8a64afa348977793967f897c4f731984ed54fed4eca8d375a0", size = 998284, upload-time = "2025-11-10T22:47:42.713Z" }, + { url = "https://files.pythonhosted.org/packages/36/10/edbe55be3554e2cea7c68ed1761aaa2bea0153474d81a467a0ac862b3478/clickhouse_driver-0.2.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c120b182ea7e9713b119ba2b518dd75503c18f26cb001a6e436326765fddd123", size = 971989, upload-time = "2025-11-10T22:47:44.642Z" }, + { url = "https://files.pythonhosted.org/packages/2f/18/d0b883af04067c70e99c22dbab1f085062ae764a063f22d4e144e833048d/clickhouse_driver-0.2.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d3da6f6d05f14780f3183f8b7b23ed9826d1e0f2f73c2471037d5335b474782e", size = 1022107, upload-time = "2025-11-10T22:47:46.148Z" }, + { url = "https://files.pythonhosted.org/packages/fe/40/11446c52c5330123354f2f88151c620e1b38ca6d5131b2cc71786ec3c067/clickhouse_driver-0.2.10-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9617c6ef154e58c6693be6e1169000957238f83d21fe20d57bb492412cc6128d", size = 1015750, upload-time = "2025-11-10T22:47:47.702Z" }, + { url = "https://files.pythonhosted.org/packages/36/9b/32abe3c76fe8494ad1642febbe4c59dfd46477e27c401d2ac8cc8a0a6117/clickhouse_driver-0.2.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b8c2dbee2083295c6d9789a10cb0c967c4e123e6315e3192e4ad935cd55967c3", size = 975901, upload-time = "2025-11-10T22:47:49.136Z" }, + { url = "https://files.pythonhosted.org/packages/5f/50/0cbbe783bf14381add11a241b4ba35349f5512d1765aabde63d7175c1f0b/clickhouse_driver-0.2.10-cp311-cp311-win32.whl", hash = "sha256:293f47bd36a5b69ede39638ea8f7c1eb3fa7e55f35778a3feb9a3615749100c4", size = 190097, upload-time = "2025-11-10T22:47:50.463Z" }, + { url = "https://files.pythonhosted.org/packages/1c/12/7bb65617527b2b9a2b4ca8cc0d1ea2d4bdbd6d05a4d9d141cef0083342db/clickhouse_driver-0.2.10-cp311-cp311-win_amd64.whl", hash = "sha256:c9aeebbb0c159173de37deef494b28a4423a767cd7c4b2d596556f7a072f90a6", size = 203591, upload-time = "2025-11-10T22:47:51.562Z" }, + { url = "https://files.pythonhosted.org/packages/a9/54/0a82bcfc66bbab7a36c37b4bd8b8d088d9001da93661e278b7f6c87a3791/clickhouse_driver-0.2.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1851f5f8b84ead0be6373ef001e8f09d48d45ec0628377e199a223e70417cd40", size = 213107, upload-time = "2025-11-10T22:47:53.314Z" }, + { url = "https://files.pythonhosted.org/packages/32/7b/8e526f6ffb9983c0c6d082e358df4b20fe1a9e95f453e704bc7a25ef4aab/clickhouse_driver-0.2.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:188775d38ff7cb36e7045441aabf3a6a8751127d8b37b6eb1b1518494eaac5bd", size = 207193, upload-time = "2025-11-10T22:47:55.146Z" }, + { url = "https://files.pythonhosted.org/packages/65/96/40f274896abf287c378575f025c602fa4e834278930dd63574ff548815c4/clickhouse_driver-0.2.10-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ff5cba860df61845d6ae12f31d4a70ff4ae3be4e6a8a876e68af8aa4b0e45bc", size = 1046187, upload-time = "2025-11-10T22:47:58.246Z" }, + { url = "https://files.pythonhosted.org/packages/0c/80/7b6e110c3b803fa8b3f8cdba0e08553a62c5f64e5ad57e56de3ea95cd9e1/clickhouse_driver-0.2.10-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fad865009d96de44d548f1691ed92adee971f72c001cf4466b3ba2ac7d9db47b", size = 1088806, upload-time = "2025-11-10T22:47:59.834Z" }, + { url = "https://files.pythonhosted.org/packages/c5/d6/7f77bd00fc01df9db2e573de21bbc1f66083549d004864b892877dee8a76/clickhouse_driver-0.2.10-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cf0fe791e7c2adc0ab41d4770953c00f8a88bdd7e3ee83bb849a661a6c93d4ef", size = 1109839, upload-time = "2025-11-10T22:48:01.405Z" }, + { url = "https://files.pythonhosted.org/packages/55/f7/57a80ff9cc44a333021e2caf8d35fc23da6ec7b602bbc3bf8dfac0253a6e/clickhouse_driver-0.2.10-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5744daafdd0ff7520c6ae95a78211a0ff5c2cfb3513a20f5602d2bc7eed580d", size = 1049773, upload-time = "2025-11-10T22:48:03.089Z" }, + { url = "https://files.pythonhosted.org/packages/f6/3e/fcf8e9cb9edc717ce6c467a9ec7c96b4495d5f8ec4859175952149fbdaa8/clickhouse_driver-0.2.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f02f6c9f71ae5c06e3b760d3d9f4f758b32acf6f71504b6d90bacca9abbfec18", size = 1006817, upload-time = "2025-11-10T22:48:05.038Z" }, + { url = "https://files.pythonhosted.org/packages/95/ab/1bc25a385012c03595b91311d8341205a5790375207d80425e2285055d42/clickhouse_driver-0.2.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:6df571410f149e16e0a0e5529f1c2a9e41bb62b9357a3c8b0bd0647d6bb0fd1e", size = 1051047, upload-time = "2025-11-10T22:48:07.115Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e1/9dd7331d08495beacf4291a6fbe5514fd0f6f8d53014121a8d70d8bd6c1e/clickhouse_driver-0.2.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1e891162226a44fa169bdc996efd49b22bcf59372c35118ec5785e936fe97178", size = 1052014, upload-time = "2025-11-10T22:48:08.608Z" }, + { url = "https://files.pythonhosted.org/packages/ee/e9/af10e0ddbbd90c4ead933effff1b8914bc687bd52a70d244404db4c91529/clickhouse_driver-0.2.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3a261947ba0cf0034d044c30563ad151d1cf8156a5ff419b017c423b4235e0ac", size = 1020937, upload-time = "2025-11-10T22:48:10.993Z" }, + { url = "https://files.pythonhosted.org/packages/f8/78/dbb93037939a7f9424451d10feeb0daa0d5a76163ef2e62407f4d18705ea/clickhouse_driver-0.2.10-cp312-cp312-win32.whl", hash = "sha256:d94f4db3c338ed41b28379931756852586920c5cbac1f07fcc8b7f109b3e69db", size = 190729, upload-time = "2025-11-10T22:48:12.742Z" }, + { url = "https://files.pythonhosted.org/packages/b6/86/74bddbfaa3c116da34d8c762f728c59d9842a65f202b0b746f5d9a597869/clickhouse_driver-0.2.10-cp312-cp312-win_amd64.whl", hash = "sha256:3ce051f55bdb33396f76a77702936bfa973dfd98f7cf00a72817a1e01c9b7406", size = 204141, upload-time = "2025-11-10T22:48:14.452Z" }, + { url = "https://files.pythonhosted.org/packages/76/7f/ee5d539611b782a04845545ba391208634124f67c4d57a32d4a46eadfb58/clickhouse_driver-0.2.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e76c1189a6273c79d906ee8274b9d3c7bf8df597ee6199cb75449ee2702deb8a", size = 210645, upload-time = "2025-11-10T22:48:15.995Z" }, + { url = "https://files.pythonhosted.org/packages/34/92/ee5a2d7a812b65d9690e46222218f33064c4bd44f3535b1ba564fb4b528b/clickhouse_driver-0.2.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8be64c77d58d4a33b3c957cdb7c5a4deeac56bf93f4188dbfb5c5454eb04c985", size = 205158, upload-time = "2025-11-10T22:48:17.745Z" }, + { url = "https://files.pythonhosted.org/packages/03/00/6c532a0aea89e3d09dd4150b1df0b92e787a306b8711d54d003d18fd1ddd/clickhouse_driver-0.2.10-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23abafd0c883ccc1baea527c1d05a6bc0c59aae6c29ae65e1b84d498b265f8c0", size = 1033476, upload-time = "2025-11-10T22:48:19.239Z" }, + { url = "https://files.pythonhosted.org/packages/ea/9b/137ea1ff9539da77cd022331ec4fa079cbefbd4ebbcb5c51bdd7dcd0bca0/clickhouse_driver-0.2.10-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:77ffe2063469c637c5e57bf0713ca1b617b612d55a8392799f97e34c353e6908", size = 1079495, upload-time = "2025-11-10T22:48:20.744Z" }, + { url = "https://files.pythonhosted.org/packages/ec/1c/e13766af7e4e174c6f17b1fbc5a078b28584f53adc91f103caacc73f569b/clickhouse_driver-0.2.10-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:df2d77779fcc1ddb68614b75bf45b8db61cf63f42a03d5624ce6922a305e609f", size = 1100658, upload-time = "2025-11-10T22:48:22.277Z" }, + { url = "https://files.pythonhosted.org/packages/41/e5/0686ad3ef1b594c16e8b13394c73ee4860fd025d70211a360f797dd7a28a/clickhouse_driver-0.2.10-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85e46e31e4b14626571819e669341a3017376ce935d25b2cc0bfea9343b1b562", size = 1034175, upload-time = "2025-11-10T22:48:24.117Z" }, + { url = "https://files.pythonhosted.org/packages/d8/32/fea4e971297b50e5af3318fd90d400269ae1c74ad4d83a9453b89f578d3c/clickhouse_driver-0.2.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d7435d1ff2bc577aeedf8f01d94b5777af382484f8973a9c5018d5afd0dd175c", size = 995963, upload-time = "2025-11-10T22:48:25.824Z" }, + { url = "https://files.pythonhosted.org/packages/02/c4/d42f2b69ab5903e5bc9119b179f55c9aef79fe667f77cab4d8ae90492dcd/clickhouse_driver-0.2.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b60c7e3321214eec4568811bcd953836671fa078c57f6607f236414447636de2", size = 1044626, upload-time = "2025-11-10T22:48:27.927Z" }, + { url = "https://files.pythonhosted.org/packages/78/36/043b6b2d967396172a60f10bf26de2c83248857f9a1e75b481f02218d1d7/clickhouse_driver-0.2.10-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13fdf6571e20ac79992605ad65058296ac0f2437c1e7428a98dd6d173753119e", size = 1045772, upload-time = "2025-11-10T22:48:29.439Z" }, + { url = "https://files.pythonhosted.org/packages/0c/cf/bc5c807cbe68ce9eeac6a1997b937c81774ca86b2ab593c6efb9121a9f08/clickhouse_driver-0.2.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:06b6b683af086f9049d0c5e7e660fb76013439efa640e6c8ff6673622c3838fa", size = 1006716, upload-time = "2025-11-10T22:48:31.086Z" }, + { url = "https://files.pythonhosted.org/packages/d9/21/9b0e4814aa6c78d717c22cf51e3a5bd73b4f09c4078fc3f274f8a17c3658/clickhouse_driver-0.2.10-cp313-cp313-win32.whl", hash = "sha256:8fc51b0991dc9b89ea2379a0bc0995a9ed24428aad834f6af7841cc94488b82f", size = 189789, upload-time = "2025-11-10T22:48:33.039Z" }, + { url = "https://files.pythonhosted.org/packages/85/7d/46195e09d4b43f59bc9053f81f6d0c0f25e44c8ef94218fe3c972067cdf4/clickhouse_driver-0.2.10-cp313-cp313-win_amd64.whl", hash = "sha256:fbfe244d2f06824e175492a54033d8282f0ec5644db8e7e3805f7a9d076f5fcf", size = 203020, upload-time = "2025-11-10T22:48:34.874Z" }, + { url = "https://files.pythonhosted.org/packages/e7/9f/513e661a80b0db9b6be5ce525d6cc86339c04dfc8d75f577b775e5ac5cf1/clickhouse_driver-0.2.10-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:19dd1de015d98dd1559d14ef05de2b6a0560c98b77ef160b3b99632a87fc8212", size = 211779, upload-time = "2025-11-10T22:48:36.873Z" }, + { url = "https://files.pythonhosted.org/packages/1c/6e/842610028ca39c826865402d46b7d7f499a9a249de219edfce889c0e025d/clickhouse_driver-0.2.10-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b6f35a9ee7f7a8ce3483764c3bc2d23c8be1c5ce3aef537b1a3cebe59fdb0c4d", size = 205709, upload-time = "2025-11-10T22:48:38.404Z" }, + { url = "https://files.pythonhosted.org/packages/c6/94/ddbcda962f7ca36cbcf7ded105f68f99b261dc29b9c28ca2eaec70382f66/clickhouse_driver-0.2.10-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:888ab59b2cccda24680cfbaeb723fd8922c6148b9a43ad4cf067fef55959f19f", size = 1032732, upload-time = "2025-11-10T22:48:40.047Z" }, + { url = "https://files.pythonhosted.org/packages/f6/1d/9d378af127ca1d35b734c965a9ec26318253f07d2a7eaa4a5643210fe327/clickhouse_driver-0.2.10-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fbf5d692ee4df241e82d200a195dc2ddbe7fbf490ebd185fbd9da32478245399", size = 1085199, upload-time = "2025-11-10T22:48:41.784Z" }, + { url = "https://files.pythonhosted.org/packages/3c/38/d65aedbe40e08a085fe3c2fcdcfcc0cec084d2e838e653c1ed4408771d9a/clickhouse_driver-0.2.10-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2f1d42ffcdc5b77346403e7ac49639a48c2fb58767a3e55657bd40e36290e9f0", size = 1089153, upload-time = "2025-11-10T22:48:43.283Z" }, + { url = "https://files.pythonhosted.org/packages/ef/e3/e60fbcd5ec1458da9fe313984527e9ce5f95636c178bd2d08d6257c42c30/clickhouse_driver-0.2.10-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74b36dfb79311bcf1ba6edde926908a46778a5e9db6302f126a799550f1fb807", size = 1023508, upload-time = "2025-11-10T22:48:44.83Z" }, + { url = "https://files.pythonhosted.org/packages/9b/80/345be27d8011bcbd2fd3437d15b0e387369e2a8a8b73a7704af25bb6e90b/clickhouse_driver-0.2.10-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8c49d4b6619ce9237817185a41db6645f1557f7a77f2a822029ded1041179d55", size = 995994, upload-time = "2025-11-10T22:48:46.35Z" }, + { url = "https://files.pythonhosted.org/packages/0c/76/de011c4460a2b80e517c9a5f1b80a9fe3937e2987989e9776a79dc0a1e99/clickhouse_driver-0.2.10-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:503bbcbfedd65840489dadf3d0a2ac391888828b8f82579e6ec08efb1f362659", size = 1043865, upload-time = "2025-11-10T22:48:47.924Z" }, + { url = "https://files.pythonhosted.org/packages/5d/f4/264b6bb95488eebd79565372c8fbe397df2aac1478224629ebdc229eab00/clickhouse_driver-0.2.10-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:64aa403194bf4d3bdbecc2f8412ca85f4b9a35ed8dc228f23061a9889ce18dc4", size = 1038468, upload-time = "2025-11-10T22:48:50.706Z" }, + { url = "https://files.pythonhosted.org/packages/ec/95/01b3cc32ba060132ce9183f7af9059995fed2ded8d41865e86193f17ce30/clickhouse_driver-0.2.10-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20b16b066760cfcc6a8a5342e91585a84ba22152f83421030edd3582b6e420e3", size = 998721, upload-time = "2025-11-10T22:48:52.924Z" }, + { url = "https://files.pythonhosted.org/packages/85/d4/21e3203f8d22ad32224b0623ad2772103bb3a05ce367d6b27e78e118ea2f/clickhouse_driver-0.2.10-cp314-cp314-win32.whl", hash = "sha256:5ac6eed651dd6320a50338ff331fea93d20ed13dec27c7c7bfab71f8db3c76bb", size = 192639, upload-time = "2025-11-10T22:48:54.729Z" }, + { url = "https://files.pythonhosted.org/packages/ac/6b/1e87eb25614c0477fdadd5cf0b49675bc91cfcae95a10cbb83e3a688b01b/clickhouse_driver-0.2.10-cp314-cp314-win_amd64.whl", hash = "sha256:9f17746188833162e06e6af595e6a41c2ed09c7714b96860217c696fdb7689cf", size = 206586, upload-time = "2025-11-10T22:48:56.002Z" }, + { url = "https://files.pythonhosted.org/packages/1a/49/ad110cb8e92f9bef684048d621aba291313e312640b5b51ebcae40f20f17/clickhouse_driver-0.2.10-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:190e284f97fb06c30d88b12402666c0ec2a81ea35ba2019cdbc7e284db8ae505", size = 191126, upload-time = "2025-11-10T22:49:39.824Z" }, + { url = "https://files.pythonhosted.org/packages/48/24/c49669b05d514261ab3f6d6b48d3aaa8c38e23e2cf4499b3c6cefc741424/clickhouse_driver-0.2.10-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d5b32d0824ecd348ba1f11d9df7d7e09134e11a5ca001e283cbe953bc9baf48", size = 216482, upload-time = "2025-11-10T22:49:41.378Z" }, + { url = "https://files.pythonhosted.org/packages/63/b6/c10cf67f8a65fb8919a8276241678d5580b0922cd5f612c4f9ed0dc2099f/clickhouse_driver-0.2.10-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14d6fed705c798d10c2426634a4856fb36702b7dbb786e363edad710972e2b47", size = 218823, upload-time = "2025-11-10T22:49:42.863Z" }, + { url = "https://files.pythonhosted.org/packages/11/77/4ec0e8d1d7a64a196d559448c541af0f75e23cd72d5ac5b3064d4b6aa02f/clickhouse_driver-0.2.10-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5b9c74b9895ad8a313154a274374d113efef08ddfb911af5f23bc6a881c4a0c4", size = 192798, upload-time = "2025-11-10T22:49:44.262Z" }, + { url = "https://files.pythonhosted.org/packages/d7/64/6d8ea99c03e99aaf8dfe87961fd2e5baedc72d0a289cab1c5138acbe2d1b/clickhouse_driver-0.2.10-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cb0bbad7b79ecb41f5f348528b6b0c46850d741669dd453f5fa633a8f3eff855", size = 190729, upload-time = "2025-11-10T22:49:45.635Z" }, + { url = "https://files.pythonhosted.org/packages/40/7d/9abdd95b0da0dcf6dc644336459f132575bfbdee1a4ba377195c2032c03a/clickhouse_driver-0.2.10-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68e96e04282d126486b3820391a8ebf1d7c32b61e5fcbd701aeeda79017349e5", size = 216933, upload-time = "2025-11-10T22:49:47.474Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a4/33d4b6f1650847280265756e4d54f94730cdac082ab3f9e6518ba97502bf/clickhouse_driver-0.2.10-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0fd9f72fcfe86e0fef0681cd124325714e92e96ad1fd675dfbeaccdfb7bd2f64", size = 219670, upload-time = "2025-11-10T22:49:49.401Z" }, + { url = "https://files.pythonhosted.org/packages/d6/c0/320b7cb5e2b6ab73e10ca6f1c5d0a2f04b42dc3acb689533d102d9f3f5e4/clickhouse_driver-0.2.10-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:e24582110f3d532b35e106583981bea0b7a3b10167c8a890a7b6ea5c7c6ce6d6", size = 192945, upload-time = "2025-11-10T22:49:51.168Z" }, +] + +[[package]] +name = "clickhouse-sqlalchemy" +version = "0.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asynch" }, + { name = "clickhouse-driver" }, + { name = "requests" }, + { name = "sqlalchemy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2d/b9/801073bb20edd4efc5e7240ea318b755867fb0d62acb374daafc35419b39/clickhouse-sqlalchemy-0.3.2.tar.gz", hash = "sha256:267f3a9a1d0d186eb99a41895a684922d31125cea21702cd7dc73af1ccdd10e7", size = 45206, upload-time = "2024-06-12T12:08:58.044Z" } + [[package]] name = "colorama" version = "0.4.6" @@ -467,7 +628,7 @@ wheels = [ [[package]] name = "jetbase" -version = "0.17.2" +version = "0.18.0" source = { editable = "." } dependencies = [ { name = "packaging" }, @@ -478,6 +639,9 @@ dependencies = [ ] [package.optional-dependencies] +clickhouse = [ + { name = "clickhouse-sqlalchemy" }, +] databricks = [ { name = "databricks-sqlalchemy" }, ] @@ -488,6 +652,7 @@ snowflake = [ [package.dev-dependencies] dev = [ + { name = "clickhouse-sqlalchemy" }, { name = "cryptography" }, { name = "psycopg2-binary" }, { name = "pymysql" }, @@ -499,6 +664,7 @@ dev = [ [package.metadata] requires-dist = [ + { name = "clickhouse-sqlalchemy", marker = "extra == 'clickhouse'", specifier = ">=0.3.0" }, { name = "cryptography", marker = "extra == 'snowflake'", specifier = ">=46.0.3" }, { name = "databricks-sqlalchemy", marker = "extra == 'databricks'", specifier = ">=2.0.1" }, { name = "packaging", specifier = ">=25.0" }, @@ -508,10 +674,11 @@ requires-dist = [ { name = "tomli", specifier = ">=2.0.2" }, { name = "typer", specifier = ">=0.12.3" }, ] -provides-extras = ["snowflake", "databricks"] +provides-extras = ["snowflake", "databricks", "clickhouse"] [package.metadata.requires-dev] dev = [ + { name = "clickhouse-sqlalchemy", specifier = ">=0.3.0" }, { name = "cryptography", specifier = ">=46.0.3" }, { name = "psycopg2-binary", specifier = ">=2.9.11" }, { name = "pymysql", specifier = ">=1.1.2" }, @@ -530,6 +697,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/31/b4/b9b800c45527aadd64d5b442f9b932b00648617eb5d63d2c7a6587b7cafc/jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", size = 20256, upload-time = "2022-06-17T18:00:10.251Z" }, ] +[[package]] +name = "leb128" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a4/3c/ef6fe994b4b45d84187fea994f124173d587f4f8ab0641693ef269e80f56/leb128-1.0.9.tar.gz", hash = "sha256:8f8b0e2216ba8a318e2897360d9a34d88e2c968656fcb7c7bbb1aef31010f1c6", size = 26710, upload-time = "2026-01-09T08:29:39.261Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/f6/62cd379fe8527c6d685013ebed11c85fd4fced125bde9b3c80ebd5759850/leb128-1.0.9-py2.py3-none-any.whl", hash = "sha256:fef16ef20aca33dfdd2f4841d8004ec4acb7ed8545b63a7bc1183292c9a3e594", size = 3700, upload-time = "2026-01-09T08:29:37.446Z" }, +] + [[package]] name = "lz4" version = "4.4.5" @@ -1377,6 +1553,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl", hash = "sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1", size = 348521, upload-time = "2025-12-13T17:45:33.889Z" }, ] +[[package]] +name = "tzlocal" +version = "5.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "tzdata", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8b/2e/c14812d3d4d9cd1773c6be938f89e5735a1f11a9f184ac3639b93cef35d5/tzlocal-5.3.1.tar.gz", hash = "sha256:cceffc7edecefea1f595541dbd6e990cb1ea3d19bf01b2809f362a03dd7921fd", size = 30761, upload-time = "2025-03-05T21:17:41.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl", hash = "sha256:eb1a66c3ef5847adf7a834f1be0800581b683b5608e74f86ecbcef8ab91bb85d", size = 18026, upload-time = "2025-03-05T21:17:39.857Z" }, +] + [[package]] name = "urllib3" version = "2.6.3" @@ -1385,3 +1573,91 @@ sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6 wheels = [ { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, ] + +[[package]] +name = "zstd" +version = "1.5.7.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/49/62/b9c075ad664e7c4cbb3d8d2be7c246506abe1bc7f778eb58d260ef9538c8/zstd-1.5.7.3.tar.gz", hash = "sha256:403e5205f4ac04b92e6b0cda654be2f51de268228a0db0067bc087faacf2f495", size = 672559, upload-time = "2026-01-08T16:24:43.361Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8b/54/95fe3f714a4a0c2befc1f5734deb2706c635481feff4e5497ace0f307fef/zstd-1.5.7.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:76f3535616887a1a38e8c6d0de693a23c5bb1f190651eb20d96bfc8e4ab706a0", size = 267642, upload-time = "2026-01-08T16:46:57.829Z" }, + { url = "https://files.pythonhosted.org/packages/0f/af/e88d733bf7dac8bcb0f90e90f9ea2163909e873e37aaf90617e7e5ed34d8/zstd-1.5.7.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:67507937e8e4c2a8dfed8e7fa77f4043ec9e6e831a5faebf0f99138b1a25ccbd", size = 230964, upload-time = "2026-01-08T16:46:59.277Z" }, + { url = "https://files.pythonhosted.org/packages/ac/7a/9e8b541b5799bb699e70d6f0c4fa5a0607c9229634209e9662f4a6a8a6ce/zstd-1.5.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:bd0a2309c524608ce7b940abcc9f8eb5447c6ea2c834a630e0081211ab9d40ec", size = 1540287, upload-time = "2026-01-08T17:39:27.789Z" }, + { url = "https://files.pythonhosted.org/packages/4b/1e/d0fe5f8e860c39f50831889c499fbf91a5bfdb8adcd148d35f1f7a3e7ea7/zstd-1.5.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:2b497306580d544406b5414c8485c4037a9283ad2ca6ae4ccdf3732c9563141d", size = 1619041, upload-time = "2026-01-08T17:39:23.305Z" }, + { url = "https://files.pythonhosted.org/packages/10/bd/b9b381edad8cfdca944cd15025932c6b0edacc5164ed67b603b4d8a38f84/zstd-1.5.7.3-cp310-cp310-manylinux_2_4_i686.whl", hash = "sha256:e9939a98ea946d1f9e8f9fecc940ae939b8e9e5ef9d71b104f7843567d764f30", size = 300166, upload-time = "2026-01-10T11:12:23.088Z" }, + { url = "https://files.pythonhosted.org/packages/a7/a8/9b6f65a3bd7fb54148bceadf9a5a9a869b64454c9e15b6f1362160594785/zstd-1.5.7.3-cp310-cp310-manylinux_2_4_x86_64.whl", hash = "sha256:d32c0fe8f6b805b7cbeaade462b094a843e84d893d8c6f66ab705e8777cc1850", size = 304165, upload-time = "2026-01-10T11:22:59.825Z" }, + { url = "https://files.pythonhosted.org/packages/f9/22/2fb52f1d288bb5e8176108a4bdbc25484fc05cc902cdf5c99cf604aba979/zstd-1.5.7.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_24_i686.whl", hash = "sha256:8aa33b1ef24602b2ef1e8aa67ea3c8f821854a4dbf70c3c8c46b96b54b6ceb5d", size = 1525903, upload-time = "2026-01-08T17:39:26.4Z" }, + { url = "https://files.pythonhosted.org/packages/b4/be/26451e696c2cc5f604eb872408a4e0ddc64478e45928897c755b2ab0330c/zstd-1.5.7.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1bd69fa9c4c97fd04206c919dedbf9f75f544ebb77880db51a13c1e3802cd655", size = 2095723, upload-time = "2026-01-08T17:39:30.473Z" }, + { url = "https://files.pythonhosted.org/packages/01/1a/43ee13d01e367eb5bb2dead554e2fb3931e4f2d4a45a7642601e44b138b1/zstd-1.5.7.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:aee96742a64ede2e35dc0316ef0cd1e50089e889ce77e82ca8edf40174a1439c", size = 2132397, upload-time = "2026-01-08T17:39:24.739Z" }, + { url = "https://files.pythonhosted.org/packages/00/d7/5497d54dadb172ee148820aff1551cb189344522c207bc83f073f8a85a59/zstd-1.5.7.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5ac207573d2815a51f4f4fd4e255408396491729a01f690b9f5fb672d39e5610", size = 2124660, upload-time = "2026-01-08T17:39:29.146Z" }, + { url = "https://files.pythonhosted.org/packages/98/89/665c5fac2da24c129ef403f65c2d8e9b08142b97b02ab7daa3a44cddeca7/zstd-1.5.7.3-cp310-cp310-win32.whl", hash = "sha256:04e62e4f9eba79699d072d3c96731ed4aff99f1d334eb967489b091186a6078f", size = 150362, upload-time = "2026-01-08T17:09:29.33Z" }, + { url = "https://files.pythonhosted.org/packages/53/2e/cae4878efd693ddfb712577eee4ac37dd4c0fe757054c4ee3479530b416f/zstd-1.5.7.3-cp310-cp310-win_amd64.whl", hash = "sha256:0794b23b9950af240888087d2bd5943aa4be67273ba32cdafabdc5704778b90e", size = 167580, upload-time = "2026-01-08T17:09:30.639Z" }, + { url = "https://files.pythonhosted.org/packages/93/f9/9908234f86aafb48edd5fe630b41488c3acd8a4edbfbc921a7a6db1ab8b4/zstd-1.5.7.3-cp310-cp310-win_arm64.whl", hash = "sha256:7827fd4901f3e71a7a755d26719549658f08e04fdf0870a952ed08e71b484435", size = 157239, upload-time = "2026-01-08T16:43:01.449Z" }, + { url = "https://files.pythonhosted.org/packages/75/0d/8c89c0d010b58c21a7865a239790bb1c6822029c053b1ded858d6b573e3a/zstd-1.5.7.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a3c1781a24e2ced2c0ddee11d45b1f04018b03615eeb622a62eca4d56d3358a", size = 267641, upload-time = "2026-01-08T16:30:50.812Z" }, + { url = "https://files.pythonhosted.org/packages/a3/6d/155d8c344d96eca2a5a003a5ddd63373a5f13591fd5cf2b9490250d6805a/zstd-1.5.7.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a6c7c81056362b60a04baa34632e713d596662a860ec34efd8e9b109c10e6ec7", size = 230962, upload-time = "2026-01-08T16:30:49.155Z" }, + { url = "https://files.pythonhosted.org/packages/c8/c7/ab93916a26eb58cd501ad701974c31b4bc67a7f6abd6c24bef8fe4d7649b/zstd-1.5.7.3-cp311-cp311-manylinux_2_14_x86_64.whl", hash = "sha256:e564f34a55effc7d654eb293468edc80b64d476b0f899f82760ecd8323223ff5", size = 304166, upload-time = "2026-01-10T11:17:45.697Z" }, + { url = "https://files.pythonhosted.org/packages/c2/54/27a7040a360019a4602343e3c98c0c0a140f382186002c01e1992fd21837/zstd-1.5.7.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:fbc49a57188184931d5e3c9f1133cad7eea5a370a9e9418fb8122d58c14340a5", size = 1540288, upload-time = "2026-01-08T17:50:26.913Z" }, + { url = "https://files.pythonhosted.org/packages/96/93/4a4d4edd1b2e809e0ebbb16000404bdcc9a09743c04ee1661442c9581b75/zstd-1.5.7.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:d121d3e63722819e1fe5effbcd9628d8a7cfea0cddabcc5bb37ea861a6a83424", size = 1619134, upload-time = "2026-01-08T17:50:32.324Z" }, + { url = "https://files.pythonhosted.org/packages/31/6b/cd6f0a7f4f0d98e4110aa77763cf3e85f594d983ea9ca3d64cc0cee10684/zstd-1.5.7.3-cp311-cp311-manylinux_2_4_i686.whl", hash = "sha256:621f2e7ca8e9eb52a83eb9c91ec3cd283d87591bf75cc658de486b65f44742c7", size = 300166, upload-time = "2026-01-10T11:12:27.938Z" }, + { url = "https://files.pythonhosted.org/packages/05/3f/c717e0d15127d04b7fa58ba9b4c56e8b88b803048b9766cd9d158dbb22ea/zstd-1.5.7.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_24_i686.whl", hash = "sha256:c1950fcae690ba32d0f31702b335c548fb42547821565925e48576afdad774a5", size = 1525776, upload-time = "2026-01-08T17:50:35.518Z" }, + { url = "https://files.pythonhosted.org/packages/3e/a2/1813cd787d1a2f9ab8e8a90d28dcbc8e8098997dd04de38897ea8e75dd08/zstd-1.5.7.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bac4f0d03da69115878bedbfa03c4a3f64364e8396b432028c4ce0f05141a0fb", size = 2096057, upload-time = "2026-01-08T17:50:33.984Z" }, + { url = "https://files.pythonhosted.org/packages/36/ce/f5a3c7c12de458dd9ce15c484d627fe5412b60c155da23dacb5fcf08d9d5/zstd-1.5.7.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:da0ab134b7fd28023dedf013751ca850de300a090eb11f689d2a1c178c87d9dc", size = 2132659, upload-time = "2026-01-08T17:50:29.534Z" }, + { url = "https://files.pythonhosted.org/packages/f1/66/151f9546498bfd8971a0b6ad67d87c26d7a0df17d57f724da674f3778666/zstd-1.5.7.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b9923175842ee8f7602ec9cc578f5fc396896f0e8460d3ac9a5adc3cea77244e", size = 2124811, upload-time = "2026-01-08T17:50:37.612Z" }, + { url = "https://files.pythonhosted.org/packages/6a/34/4d2dbb36cb2373d3f115c047cb901b64f89de0703d10779da39de9453812/zstd-1.5.7.3-cp311-cp311-win32.whl", hash = "sha256:0612b604948d7b58aecc6788c7ceb53c5f21d94a155bb6ea9bd0f54ffa43725d", size = 150363, upload-time = "2026-01-08T17:11:02.392Z" }, + { url = "https://files.pythonhosted.org/packages/d9/de/f53687e0dd8c0d0ebfaed9ae88f6a96a1a0388ae7424b469e74bb17ac57d/zstd-1.5.7.3-cp311-cp311-win_amd64.whl", hash = "sha256:5b7f8c81b2bd3b62c0345242247d484cafa4b518d59d18619813d9225af5c5c3", size = 167577, upload-time = "2026-01-08T17:11:03.356Z" }, + { url = "https://files.pythonhosted.org/packages/f2/58/d4a6a902e229e953ed273fe9b78587ed31f57567aa68d3e34af6056e42af/zstd-1.5.7.3-cp311-cp311-win_arm64.whl", hash = "sha256:ea112e3acd9e1765adca35df7b54ac75b36194290f64ea03a3a59664209c8527", size = 157238, upload-time = "2026-01-08T16:36:06.25Z" }, + { url = "https://files.pythonhosted.org/packages/aa/ed/5a3bf2e29dc56d4cc7619929bb51f0c758de6d02967cc73c5d8755a862c0/zstd-1.5.7.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:01a39efb0eeab7cc45cb308618233b624b0840d5e16dcf85456b6cca0592f203", size = 268124, upload-time = "2026-01-08T16:29:57.091Z" }, + { url = "https://files.pythonhosted.org/packages/e2/1d/efc2074ac90af938e78f2ed4004639fe24f294d9086c5280f8d9a02b9897/zstd-1.5.7.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7a8e8838cf35fa3987bfe1958584cc22e1797efce8e155a63544b4144fc671f8", size = 230988, upload-time = "2026-01-08T16:29:55.604Z" }, + { url = "https://files.pythonhosted.org/packages/2a/52/178393b8d70e23fba67f42dfce4663e4e8a30867110168beb490a36d4639/zstd-1.5.7.3-cp312-cp312-manylinux_2_14_i686.whl", hash = "sha256:f3920ac1d1cc7e9f252f3e29f217fe3cd36f2191bb3dbcae826c29e189b7ad54", size = 300207, upload-time = "2026-01-10T11:26:58.351Z" }, + { url = "https://files.pythonhosted.org/packages/6a/7a/8dcd86a2efb2ed3f9dae39545a05d3c7ed26c7678330786ce4a44cd8b099/zstd-1.5.7.3-cp312-cp312-manylinux_2_14_x86_64.whl", hash = "sha256:143f9062953fb5590cbd47c1040d357336742c79696bf90b6d5b835279a68304", size = 304154, upload-time = "2026-01-10T11:17:40.91Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ce/0c96905ab01ffe0e53a3cec8132123b82db26bd583a71608029bcc789ebc/zstd-1.5.7.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36d1fd8647e47e1f21b345e192f1a279e925678c23dad8236b547d04456cd699", size = 2162222, upload-time = "2026-01-08T18:02:22.762Z" }, + { url = "https://files.pythonhosted.org/packages/11/c4/db4807d6a68b4628c74fd379de7e3c67ec34f19a2a80ac246b3837cde6cb/zstd-1.5.7.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f1538db419afa62773cf534fc7f3009ff59ecf55ecee4e889587ac2ef0010ed8", size = 2201732, upload-time = "2026-01-08T18:02:20.835Z" }, + { url = "https://files.pythonhosted.org/packages/c5/99/c19a3c0f5580ff9c33a74f06d98d6060ed1fa6bd09b55aed9be852ec191f/zstd-1.5.7.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c5efd16adb092e2a547a7d51cfdaf6fd5680528227684c5bafc7669ab4a55f41", size = 2096459, upload-time = "2026-01-08T18:02:25.336Z" }, + { url = "https://files.pythonhosted.org/packages/23/fd/02eac30419475dbe50212c119043a2d0698a0cbc756da85fd3fd9abddf42/zstd-1.5.7.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:39b3438e64637d80a5b1860526903b92020acb9bae9ceb5adffd9838c1441328", size = 2125442, upload-time = "2026-01-08T18:02:17.715Z" }, + { url = "https://files.pythonhosted.org/packages/bb/43/3a16ff0a8c913bb9825379db1bd533c75c57c2d2f31dd9111aa9b53711f4/zstd-1.5.7.3-cp312-cp312-win32.whl", hash = "sha256:cbf48c53461e224ffc2490cfe5120a1ff40d14c84d2b512c6d6d99fc91685cf3", size = 150367, upload-time = "2026-01-08T17:03:40.178Z" }, + { url = "https://files.pythonhosted.org/packages/46/83/b85875d7428e63dfa9247e41d17fac611443c774f7892f8643bd4164a6b2/zstd-1.5.7.3-cp312-cp312-win_amd64.whl", hash = "sha256:943a189910f2fea997462e3e4d7fbf727a06d231ef801ebee557b1c87568981c", size = 167604, upload-time = "2026-01-08T17:03:41.355Z" }, + { url = "https://files.pythonhosted.org/packages/37/42/cf291e26804de2f55500cdac93f5e9fa6267cf315def8aa402529bae3a87/zstd-1.5.7.3-cp312-cp312-win_arm64.whl", hash = "sha256:85c4d508f8109afa7c51c4960626c3325af2cf1e442c6c36ebfea15d04757e3f", size = 157241, upload-time = "2026-01-08T16:47:34.615Z" }, + { url = "https://files.pythonhosted.org/packages/21/7c/f2fe6e09b9d064873ebd384f2692b9fcad3d8e9412298dfb09a935aec77d/zstd-1.5.7.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b2455e56f1d265dacbd450510b8c2f632a5d8d92c23282e7723fb04af37001a2", size = 268133, upload-time = "2026-01-08T17:31:54.616Z" }, + { url = "https://files.pythonhosted.org/packages/14/8d/0a1e49844ed82c7ab0f66dce5e0dd822742fc7e9d04f147032db33740840/zstd-1.5.7.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3486dc4f1b4e52bb059f8eec1f31daa3e540062c0f522f221782cf132a8bc9a8", size = 231005, upload-time = "2026-01-08T17:31:55.885Z" }, + { url = "https://files.pythonhosted.org/packages/3b/24/0ab682096da2411f83236a10c89423f26859a65431660e460e2d637b5628/zstd-1.5.7.3-cp313-cp313-manylinux_2_14_i686.whl", hash = "sha256:1cb47bf10ffcb6a782edacfe758da2c94879f7e89c6628feb3f1254daf8cc596", size = 300230, upload-time = "2026-01-08T16:30:52.654Z" }, + { url = "https://files.pythonhosted.org/packages/36/2e/3ff0d28ea8d6b9bd931af7477fad082b99633cb7901cdd657dcb7ecfee11/zstd-1.5.7.3-cp313-cp313-manylinux_2_14_x86_64.whl", hash = "sha256:07b1378d1230ddeea8773f99d7518a3060e6468c76edd502057cb795fe278d7e", size = 297097, upload-time = "2026-01-08T16:49:41.211Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ef/25c15570fb6b06a4a03bd054afa2d084df687ac10e336b703139acc77182/zstd-1.5.7.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ee34317f013e3405108f5baea53502159809cfc4510598d614257525500c70d", size = 2162274, upload-time = "2026-01-08T17:35:24.464Z" }, + { url = "https://files.pythonhosted.org/packages/f1/24/fd16ba9e9be877a2194f05462ae77dcb62c8f90c4ecc186d9ee71e9bdc9f/zstd-1.5.7.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c19127ca2c79855376a34a2d7a6969408094b25c1f44485b0373eba4be851b98", size = 2201877, upload-time = "2026-01-08T17:35:28.596Z" }, + { url = "https://files.pythonhosted.org/packages/85/ef/73c37a81ac36429bb1bbb69c8ac43f3a154cfab739dce6424d28f95301c3/zstd-1.5.7.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2e79cae70dd08cb247391312463085c624c0302e8c860d13f87f4c76502d8202", size = 2096535, upload-time = "2026-01-08T17:35:30.001Z" }, + { url = "https://files.pythonhosted.org/packages/d3/1f/859a8049634e444feb6855347d5e558c1280d87b0bc6385f13cd3d95dbe6/zstd-1.5.7.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0e83e91e5daf89037c737f5529da0f80da80a78a6ad0b1d70a09860eb267dea4", size = 2125473, upload-time = "2026-01-08T17:35:26.596Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5c/e7b8aa8eea46f032891ecef187f1d469e20f9ddf0d10607e9523b3d306a1/zstd-1.5.7.3-cp313-cp313-win32.whl", hash = "sha256:2283f3bb910c028e1b9fe76b834016012ab021025a0ea197e27a1333f85e3031", size = 150370, upload-time = "2026-01-08T17:18:12.899Z" }, + { url = "https://files.pythonhosted.org/packages/50/2b/ba558ff87ba7f6c29e3a9b1c3b3e95338146aee7250b10807229d412a9c4/zstd-1.5.7.3-cp313-cp313-win_amd64.whl", hash = "sha256:3ad5fe4c36bab5dfa5a4b8d050bd07c50c1e69f94d381bc65337ab14cd69e5b1", size = 167602, upload-time = "2026-01-08T17:18:13.858Z" }, + { url = "https://files.pythonhosted.org/packages/f7/7d/4a5c9813fafad2949d42deee3857d7ecc8caf369bbf82a88b60519200083/zstd-1.5.7.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e878172b0eb69ac2edc6576eb862e00747c7c25e638fb354630a1ea7cfddf49", size = 157239, upload-time = "2026-01-08T16:42:28.885Z" }, + { url = "https://files.pythonhosted.org/packages/0c/67/5fcec6bbf8aab4aeb26e3cbe8cc9fa2f323dd143d066e313b134b8c28dc8/zstd-1.5.7.3-cp313-cp313t-manylinux_2_14_x86_64.whl", hash = "sha256:7e0a7e94d5b63b4cacf2396079ca9584d11f49f87cb4e5aa21f126a8f6b83446", size = 297302, upload-time = "2026-01-08T16:36:49.027Z" }, + { url = "https://files.pythonhosted.org/packages/1e/d9/854b2643b677d22c914e352691cc46fea875867863fb453814fabaa9cc38/zstd-1.5.7.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:5412c86c34cbaf6906433ef3f2c96c407f208782f06cd3e5f01f066788adb3b8", size = 268245, upload-time = "2026-01-08T16:43:39.347Z" }, + { url = "https://files.pythonhosted.org/packages/7d/b7/97f8c206efd27df3dc7ebe2bf2d69193a67d5de024726b15c2b79ddace30/zstd-1.5.7.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f94246befb1e473211a298c96e5768f3c63eaad814ac14d160d79ae9858e1d03", size = 230992, upload-time = "2026-01-08T16:43:37.79Z" }, + { url = "https://files.pythonhosted.org/packages/8d/d9/e2771b6144f3b2a26daaf6bb40c233ef887fce03627e7825e11a674ced65/zstd-1.5.7.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:31050e17a1a546fb82c90eee8ee3c30d22b9d0594b5937e69d38b7a5084af2a2", size = 2162418, upload-time = "2026-01-08T18:09:00.35Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a5/871ac984f6b8bad512104747e55eb3b65bd89342715e030522e9cbe3b1c7/zstd-1.5.7.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ba8ec5dfd48c86d19f880713246f85d09ee06e8cd17141956258650878000d6", size = 2202154, upload-time = "2026-01-08T18:08:57.748Z" }, + { url = "https://files.pythonhosted.org/packages/a7/5d/828157d6fe7f72d5c5473231a575e98e4e2c861d65a8acdd0e7200588ff6/zstd-1.5.7.3-cp314-cp314-manylinux_2_14_i686.whl", hash = "sha256:3005540ba406157f3e205c998709ab5f8e68b390c658c7c238eb8986092089d5", size = 300205, upload-time = "2026-01-08T16:29:58.595Z" }, + { url = "https://files.pythonhosted.org/packages/12/71/09617dcd1d3be40fc43f210f6d99c2011861db9c8e1a444a571e1022716e/zstd-1.5.7.3-cp314-cp314-manylinux_2_14_x86_64.whl", hash = "sha256:3934b54a3b7df039fcd4cf7b0f0a38c86ce44d26321255ffc3fac73d6cdcc59d", size = 304148, upload-time = "2026-01-08T16:41:47.079Z" }, + { url = "https://files.pythonhosted.org/packages/8d/c2/6abdab0a1b0b1326bd53fa187568630d78a01bd3734e035360869d80a52b/zstd-1.5.7.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e9230cd3e9153e2bed16f332558f8f3f7d869f4d15e8fa3f9c360bfa163a8b4a", size = 2096739, upload-time = "2026-01-08T18:09:03.943Z" }, + { url = "https://files.pythonhosted.org/packages/66/7b/3867d0279bab7d0a69fdc06403e4d23f7e6a8f54530ef6626bcf09a19d62/zstd-1.5.7.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5bffba70af539f14f9df5367b1add9119f14d5e35b658aef7b765417ea461e0e", size = 2125551, upload-time = "2026-01-08T18:09:02.133Z" }, + { url = "https://files.pythonhosted.org/packages/87/f3/75566c4d29ab144ac4e1c915e4f58ce239cbe5ae4f8376fb56edf4114866/zstd-1.5.7.3-cp314-cp314-win32.whl", hash = "sha256:a006e70c88ab67bb56989e11d820adc7601a6a7ad5558b3c6c690b19a1dadc5b", size = 153519, upload-time = "2026-01-08T17:20:15.507Z" }, + { url = "https://files.pythonhosted.org/packages/ff/22/6c42f636f92e74cda4acfeab0e64dd4a3db3a07d5f5723ae885b8155c85a/zstd-1.5.7.3-cp314-cp314-win_amd64.whl", hash = "sha256:cb4957c330c7b94b0546c7b9529723b49e865608683b9503a251fe793da9d4db", size = 171454, upload-time = "2026-01-08T17:20:17.124Z" }, + { url = "https://files.pythonhosted.org/packages/79/71/ff79a965e040d90de1cabb842ef22ef4475ef37cae81be3646cbb9c7a9b4/zstd-1.5.7.3-cp314-cp314-win_arm64.whl", hash = "sha256:a785426081ab7cafe4522876ac771d701766deea9a6d8352e87744da00e6637f", size = 163084, upload-time = "2026-01-08T16:37:52.448Z" }, + { url = "https://files.pythonhosted.org/packages/5f/46/56453790f9b7859e5593b767361adb2662318c55c3e4af0fffa1d389a2a5/zstd-1.5.7.3-cp314-cp314t-manylinux_2_14_i686.whl", hash = "sha256:b52ef154793be0399befd742328ec6f5dff95154248d6d18dd65851cf22a1a5f", size = 300364, upload-time = "2026-01-10T11:12:15.545Z" }, + { url = "https://files.pythonhosted.org/packages/4e/9e/501836085c9c6672effc0bc11d0383b439d414edd033958209bb93c68ac3/zstd-1.5.7.3-cp314-cp314t-manylinux_2_14_x86_64.whl", hash = "sha256:8024a8ba9156b1b2e64e69d147df5ddedeaed107f9da02a3428fd7baf3e5b920", size = 304338, upload-time = "2026-01-10T11:12:03.378Z" }, + { url = "https://files.pythonhosted.org/packages/fb/ee/b71a41ae810b429b909b4d68c9bd6decc4bca1407cac8d157b9470a654e2/zstd-1.5.7.3-cp315-cp315-manylinux_2_14_i686.whl", hash = "sha256:31ac7fbacca4759aad4b6abc13bbc05e68788e9e85a968255f7624b3b8db31df", size = 300146, upload-time = "2026-01-08T16:56:10.452Z" }, + { url = "https://files.pythonhosted.org/packages/93/24/3925528355ededa372951f10e85bec9870e3f4d325b04cfb6d9707ba7dec/zstd-1.5.7.3-cp315-cp315-manylinux_2_14_x86_64.whl", hash = "sha256:d03b2927c5843ded4d1319836a33a9c21675d2f86f916a2f234a060d4c67d87c", size = 304202, upload-time = "2026-01-08T16:35:34.94Z" }, + { url = "https://files.pythonhosted.org/packages/8d/37/2ed92c824e2f8ecff1a5f699677277a4d46ce9d527800aadf5f867455ccd/zstd-1.5.7.3-cp315-cp315t-manylinux_2_14_i686.whl", hash = "sha256:5dfbf2564eb574fc1f45613ecf28036a82533c3dd70e7bb1c9854168c638da7a", size = 300404, upload-time = "2026-01-08T16:24:41.593Z" }, + { url = "https://files.pythonhosted.org/packages/92/77/a152dde083129c3eee60c3bc83963b8c747112afe375b3d6d4a96fa15427/zstd-1.5.7.3-cp315-cp315t-manylinux_2_14_x86_64.whl", hash = "sha256:7f2f5776b902f41daf7b63e75a9384b0d7c855f824f14dabefc67814b8fa5611", size = 304333, upload-time = "2026-01-08T16:25:49.196Z" }, + { url = "https://files.pythonhosted.org/packages/64/ad/f6588943c9fde34a28f1b0448a8ac824b2ebe341f7af56ff035d0489338d/zstd-1.5.7.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:2b9ec4d5ba8c170d3fdf21ae5da3c15eaea2beef9c419a5f3274a6f9e03c412a", size = 260091, upload-time = "2026-01-08T17:14:18.143Z" }, + { url = "https://files.pythonhosted.org/packages/7a/6a/6d2d3b9b7bad0124c684b7b77621ee6bdc3fc220a580f002014cf0a8f558/zstd-1.5.7.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a7ab69fc4d90eeb64b98a567751f8e48373f4bcf301597fca344b8e8342e1d5e", size = 221149, upload-time = "2026-01-08T17:14:17.168Z" }, + { url = "https://files.pythonhosted.org/packages/90/8d/ad4d3c24293c70d8ae9c80e06b2da2922048933f9a00f35d18df5166346a/zstd-1.5.7.3-pp310-pypy310_pp73-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:da70f0918bf739bc75d7770410c9b94ea0dcb6f02d7ef70598b464bd5fcb193a", size = 326792, upload-time = "2026-01-08T17:12:35.38Z" }, + { url = "https://files.pythonhosted.org/packages/ed/37/98c3dd075935b5a7a1806837db343c1a37e6726c53db93c27aa4d7e5e86c/zstd-1.5.7.3-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3dd5c069d0409284f1963b0b6b119f21b1da9e22a503e88933eb0696249d87d3", size = 322283, upload-time = "2026-01-08T17:12:32.042Z" }, + { url = "https://files.pythonhosted.org/packages/97/96/20fd30bd330529b4ad8420f4ba9030b80b971499be75d37c39306cdeb038/zstd-1.5.7.3-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:46ca4a075f36f118e2ce07ba07d9ece7aeda193cea6f50b82aaee635df7b5fc2", size = 311551, upload-time = "2026-01-08T17:12:33.683Z" }, + { url = "https://files.pythonhosted.org/packages/51/b5/001cc10b6a221e4e5fb4ec19ff49d6dcc028f97a5ce53a8ef5cee67ac409/zstd-1.5.7.3-pp310-pypy310_pp73-manylinux_2_14_x86_64.whl", hash = "sha256:4a521cb7615fc61bfe9514bea182e224894b5987fc7843b6d6da20a61206ef24", size = 317071, upload-time = "2026-01-08T16:30:35.427Z" }, + { url = "https://files.pythonhosted.org/packages/41/81/75bdf0e4515c74094adff7e5119f4d50bc9af20359b78c04f8f6cac3f59c/zstd-1.5.7.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:71ea22c953a164f34eb4b8c2c3b97eaa22da6a75296ea80b3ba4473187f15046", size = 167655, upload-time = "2026-01-08T16:55:06.572Z" }, + { url = "https://files.pythonhosted.org/packages/04/b8/d13d584867d5eb1bc607877a870858e02a256d4706a4274e475413a000aa/zstd-1.5.7.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:76c49ea969bc08389ea59155cea7c5dea224522ffc62f443f3c0a915f5fd184d", size = 260025, upload-time = "2026-01-08T16:57:45.739Z" }, + { url = "https://files.pythonhosted.org/packages/16/a1/1e5faf75bedfd2bfccfb83e18736b115bed6e348504bd21800cd8f30dcea/zstd-1.5.7.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:6b1a638ff3dfce8f4cb1203c662fb5606dd99b4a62c5ddc4c406d2d1326bcfdd", size = 221038, upload-time = "2026-01-08T17:16:32.005Z" }, + { url = "https://files.pythonhosted.org/packages/b7/2c/0fe74d8b2029eef8000bc71aac5b3e5b55d00581238711cf627814183ea3/zstd-1.5.7.3-pp311-pypy311_pp73-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5e96a5cb100a0edc162935227f2d9784b1031ce4a8a83e96e66eae2673c10143", size = 326792, upload-time = "2026-01-08T16:57:35.631Z" }, + { url = "https://files.pythonhosted.org/packages/96/e0/2c7f081f3524f872128ff31bea2acb6b21cb1dacccef920eb6a1a77a87c6/zstd-1.5.7.3-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bda0bbf3a9553720cd33f1f85940a259656c7ffba4be717ff82b7f062052188", size = 322283, upload-time = "2026-01-08T16:57:36.759Z" }, + { url = "https://files.pythonhosted.org/packages/c9/a7/3bebfcc18d66b90bc7b506a61b2ff4af5ee1b0b16e784ea644afa06241c5/zstd-1.5.7.3-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac36e4022422f6e49b3f07bdbb8a964fd348223d3dc9c82ad5398a4f0432a719", size = 311553, upload-time = "2026-01-08T16:57:38.465Z" }, + { url = "https://files.pythonhosted.org/packages/41/75/8a791cae2c98e5e44a158e15db50d21b7ec0b37aeaffa68d151bc8ffb6d6/zstd-1.5.7.3-pp311-pypy311_pp73-manylinux_2_14_x86_64.whl", hash = "sha256:fa4d760a220541b18ce732a3a2cf7547ea05afc76d05b3b39edebfeb721f6079", size = 317071, upload-time = "2026-01-08T16:36:07.47Z" }, + { url = "https://files.pythonhosted.org/packages/2f/25/b6624e6b08d515242154436c9d06fb20b790d300ac82e84f3c4c133e25e1/zstd-1.5.7.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:a69e60146bf8aaa6a0e6c9a94a7c5f3133d68091e2e5c5a3c5ababf71fd5ec7a", size = 167654, upload-time = "2026-01-08T17:00:56.667Z" }, +]