diff --git a/.gitignore b/.gitignore index ff539a80b..ec1512698 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ cover/ .mypy_cache .tmp .venv +.venv-* docs/_build .mcp.json .serena diff --git a/benchmarks/README.md b/benchmarks/README.md index 7e2bf2291..c2c8bcf74 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -41,6 +41,10 @@ The benchmark is a non-packaged member of the repository's uv workspace and runs It shares the root `uv.lock` with PyAthena, which it uses from the workspace checkout. Locally and in CI, its virtual environment is `benchmarks/.venv`, separate from the root `.venv`. On the EC2 instance, the dedicated checkout's root `/opt/pyathena/.venv` holds the benchmark environment. +The `polars1` and `polars2` dependency groups select Polars 1.x or 2.x, which PolarsCursor reads with different code paths. +The environments above have `polars1`; a second environment beside each, `benchmarks/.venv-polars2` or `/opt/pyathena/.venv-polars2`, has `polars2`. +The root `pyproject.toml` declares both groups and the root `dev` group as conflicting, so `uv.lock` resolves each of them separately. +The benchmark's default dependency groups include `polars1`; a sync with `--no-default-groups` needs `--group polars1` or `--group polars2`, or it installs whichever Polars version the lock resolves without them. The root `uv build -v` still builds only PyAthena, including a wheel built from its sdist. Benchmark dependencies do not become PyAthena runtime dependencies, and `uv sync --group dev` at the root does not install them. @@ -51,7 +55,7 @@ just benchmark lint just benchmark test ``` -The recipes select `benchmarks/.venv` and Python 3.12, and sync that environment from the locked workspace. +The recipes select `benchmarks/.venv` and Python 3.12, and sync that environment from the locked workspace; `just benchmark test` also runs the tests in `benchmarks/.venv-polars2`. The tests use local data, fake AWS clients, and child processes. They do not execute Athena queries or create AWS resources. `just benchmark format` formats the benchmark separately from the parent project. @@ -67,6 +71,13 @@ export UV_PROJECT_ENVIRONMENT="$PWD/.venv" UV_PYTHON=3.12 uv run --locked python -m pyathena_bench plan --suite single --scale small ``` +To run a command with Polars 2.x, select the second environment and its group: + +```bash +UV_PROJECT_ENVIRONMENT="$PWD/.venv-polars2" uv run --locked --no-group polars1 --group polars2 \ + python -m pyathena_bench plan --suite single --scale small --family polars +``` + For local AWS access, configure the profile and region in the repository root's gitignored `.env` file: ```dotenv @@ -117,7 +128,7 @@ As the results location, it removes leftovers by itself, but reports must be rec The deployment identity needs permission to create these resources and pass the instance role. Use an immutable, remotely accessible commit that contains this directory and the root `uv.lock`. -Bootstrap checks out that commit, installs pinned uv and Python versions, and runs `uv sync --locked --no-dev` for the benchmark into `/opt/pyathena/.venv`. +Bootstrap checks out that commit, installs pinned uv and Python versions, and syncs the benchmark with `uv sync --locked`: with the `polars1` group into `/opt/pyathena/.venv`, and with the `polars2` group into `/opt/pyathena/.venv-polars2`. It signals setup completion to CloudFormation but does not prepare data or start measurements. The EC2 commands use `--no-sync` to reuse this verified environment; they do not revalidate the lockfile on every invocation. @@ -365,6 +376,9 @@ With `--split-pages`, a job whose single trial needs at least that many pages be `--chunksize` keeps only the given chunk sizes, with 0 for reads without chunks, in `plan`, `run`, and `jobs`; `jobs` passes it to each job and adds it to the job ID. `jobs` accepts `--warmups` and `--repetitions` too; with either option, every job that is not split carries both values as arguments, so one queue can combine jobs with different trial counts under one stored configuration. `queue --jobs` accepts several job files, rejects duplicate job IDs, and orders the combined jobs as `jobs` orders one selection. +`jobs --environment polars2` runs the selected jobs with Polars 2.x: each job names the environment, and its ID ends with `-polars2`, so one queue can hold the same cases for both Polars versions. +A worker runs such a job with the interpreter of `.venv-polars2` beside its own environment, and refuses to start if a job's environment is missing on its host; start the worker from the default environment, whose interpreter runs the other jobs. +Select the families that use Polars, `polars` and `sqla_polars`, for this environment. Deploy a new stack with the fleet size under its own name; changing `FleetSize` on an existing stack does not wait for the added hosts to finish bootstrap. `QueueName` names the queue that every host consumes: after bootstrap, each host starts a worker with the stack's results location from its user data, also written to `results-location.txt` next to `stack-id.txt`, and the worker waits until a queue of that name is published; this includes the hosts that the group launches later to replace interrupted Spot Instances. diff --git a/benchmarks/cloudformation/benchmark.yaml b/benchmarks/cloudformation/benchmark.yaml index 83be5d6ab..d85fe3804 100644 --- a/benchmarks/cloudformation/benchmark.yaml +++ b/benchmarks/cloudformation/benchmark.yaml @@ -361,7 +361,8 @@ Resources: git -C /opt/pyathena checkout --detach ${GitCommit} export UV_PYTHON_INSTALL_DIR=/opt/uv-python uv python install ${PythonVersion} - uv sync --directory /opt/pyathena/benchmarks --locked --no-dev --python ${PythonVersion} + uv sync --directory /opt/pyathena/benchmarks --locked --no-default-groups --group polars1 --python ${PythonVersion} + UV_PROJECT_ENVIRONMENT=/opt/pyathena/.venv-polars2 uv sync --directory /opt/pyathena/benchmarks --locked --no-default-groups --group polars2 --python ${PythonVersion} chmod -R a+rX /opt/uv-python chown -R ec2-user:ec2-user /opt/pyathena printf '%s\n' '${AWS::StackId}' > /opt/pyathena/benchmarks/stack-id.txt diff --git a/benchmarks/pyathena_bench/__main__.py b/benchmarks/pyathena_bench/__main__.py index 54bbb7161..8eba7fe68 100644 --- a/benchmarks/pyathena_bench/__main__.py +++ b/benchmarks/pyathena_bench/__main__.py @@ -33,6 +33,7 @@ from pyathena_bench.config import Settings, read_json from pyathena_bench.fleet import ( API_FAMILIES, + ENVIRONMENTS, Filters, Queue, SpotInterruptionError, @@ -85,6 +86,11 @@ def parser() -> argparse.ArgumentParser: help="Run each repetition as a separate job when one trial needs this many " "GetQueryResults pages", ) + command.add_argument( + "--environment", + choices=ENVIRONMENTS, + help="Virtual environment beside the default one that runs the jobs", + ) else: command.add_argument("--suite", choices=SUITES, required=True) command.add_argument("--shape", choices=SHAPES, default="flat") @@ -293,6 +299,7 @@ def main(argv: list[str] | None = None) -> int: filters, args.split_pages, explicit_trials=bool(overrides), + environment=args.environment, ) sys.stdout.write(json.dumps(jobs, indent=1) + "\n") elif args.command in {"plan", "run"}: diff --git a/benchmarks/pyathena_bench/fleet.py b/benchmarks/pyathena_bench/fleet.py index bbc4c588b..e15715440 100644 --- a/benchmarks/pyathena_bench/fleet.py +++ b/benchmarks/pyathena_bench/fleet.py @@ -57,6 +57,9 @@ QUIESCE_RETRIES = 10 # Times a worker quiesces its own failed job while Athena only throttles it. QUIESCE_ROUNDS = 3 +# Virtual environments that a job can name, each synced with the dependency group of +# the same name beside the default environment, which has the polars1 group. +ENVIRONMENTS = ("polars2",) @dataclass(frozen=True) @@ -134,11 +137,14 @@ def merge_jobs(job_lists: Iterable[list[dict[str, Any]]]) -> list[dict[str, Any] All jobs, ordered as :func:`expand_jobs` orders one list. Raises: - ValueError: If job IDs are not unique. + ValueError: If job IDs are not unique, or a job names an unknown environment. """ jobs = [job for jobs in job_lists for job in jobs] if len({j["id"] for j in jobs}) != len(jobs): raise ValueError("Job IDs must be unique") + unknown = [j["id"] for j in jobs if j.get("environment") not in (None, *ENVIRONMENTS)] + if unknown: + raise ValueError(f"Jobs name an unknown environment: {', '.join(unknown)}") return sorted(jobs, key=job_order) @@ -150,6 +156,7 @@ def expand_jobs( filters: Filters, split_pages: int | None = None, explicit_trials: bool = False, + environment: str | None = None, ) -> list[dict[str, Any]]: """Split a selection into independent ``run`` invocations. @@ -172,6 +179,8 @@ def expand_jobs( explicit_trials: Whether jobs that are not split carry the warmups and repetitions of ``settings`` as arguments, so a queue can mix trial counts under one stored configuration. + environment: One of ``ENVIRONMENTS`` that runs the jobs, which their IDs + name, or None for the default environment. Returns: Job dictionaries ordered with API-heavy jobs first and longer jobs earlier. @@ -246,9 +255,29 @@ def expand_jobs( ) if not jobs: raise ValueError("No cases match the selected filters") + if environment: + for job in jobs: + job["id"] += f"-{environment}" + job["environment"] = environment return sorted(jobs, key=job_order) +def interpreter(environment: str | None) -> Path: + """Return the Python interpreter that runs a job. + + Args: + environment: The job's environment, a virtual environment named + ``.venv-`` beside the one of this process, or None for + this process's interpreter. + + Returns: + Path of the interpreter. + """ + if environment is None: + return Path(sys.executable) + return Path(sys.prefix).with_name(f".venv-{environment}") / "bin" / "python" + + def now() -> str: """Return the current UTC time in ISO 8601 format. @@ -666,7 +695,8 @@ def run_job( ends, so no trial process outlives it. Args: - job: Job dictionary. + job: Job dictionary, whose environment selects the interpreter (see + :func:`interpreter`). workdir: Directory with the queue's ``config.toml`` and ``manifest.json``. output: New output directory for this attempt. resume: Output directories of earlier attempts whose completed trials @@ -679,7 +709,8 @@ def run_job( """ (workdir / "logs").mkdir(parents=True, exist_ok=True) command = [ - sys.executable, "-m", "pyathena_bench", "--config", str(workdir / "config.toml"), + str(interpreter(job.get("environment"))), "-m", "pyathena_bench", + "--config", str(workdir / "config.toml"), "run", "--manifest", str(workdir / "manifest.json"), "--out", str(output), "--checkpoint", checkpoint, *job["args"], ] # fmt: skip @@ -1211,7 +1242,8 @@ def work( Raises: ValueError: If the queue has not been completely published and - ``wait`` is false, or a job needs more API slots than ``api_slots``. + ``wait`` is false, a job needs more API slots than ``api_slots``, + or a job's environment does not exist on this host. SpotInterruptionError: After an interruption notice, once the running attempt's records are uploaded and its claim is released as interrupted, or once the attempt of a failed job ends, if the notice arrived while @@ -1240,6 +1272,9 @@ def notice() -> bool: too_wide = [j["id"] for j in jobs if j["api_heavy"] and j.get("api_weight", 1) > api_slots] if too_wide: raise ValueError(f"Jobs need more than {api_slots} API slots: {', '.join(too_wide)}") + missing = [j["id"] for j in jobs if not interpreter(j.get("environment")).exists()] + if missing: + raise ValueError(f"Jobs need an environment missing on this host: {', '.join(missing)}") if settle is None: settings = Settings.load(workdir / "config.toml") diff --git a/benchmarks/pyproject.toml b/benchmarks/pyproject.toml index fd225236c..b899c184e 100644 --- a/benchmarks/pyproject.toml +++ b/benchmarks/pyproject.toml @@ -23,12 +23,15 @@ dependencies = [ [tool.uv] package = false +default-groups = ["test", "polars1"] [tool.uv.sources] pyathena = { workspace = true } [dependency-groups] -dev = ["pytest>=8", "pytest-asyncio>=1", "mypy", "types-psutil", "cfn-lint>=1"] +test = ["pytest>=8", "pytest-asyncio>=1", "mypy", "types-psutil", "cfn-lint>=1"] +polars1 = ["polars>=1.39.0,<2"] +polars2 = ["polars>=2,<3"] [tool.pytest.ini_options] testpaths = ["tests"] @@ -37,7 +40,7 @@ asyncio_mode = "auto" [tool.ruff] extend = "../pyproject.toml" -exclude = [".venv"] +exclude = [".venv", ".venv-*"] target-version = "py312" [tool.mypy] diff --git a/benchmarks/tests/test_cloudformation.py b/benchmarks/tests/test_cloudformation.py index f3bfaafd2..44bc7fb18 100644 --- a/benchmarks/tests/test_cloudformation.py +++ b/benchmarks/tests/test_cloudformation.py @@ -187,4 +187,9 @@ def test_hosts_start_the_queue_worker_and_expose_their_tags(): ) assert variables["Results"] == template["Outputs"]["Results"]["Value"] assert "systemctl enable --now pyathena-bench-worker.service" in user_data + # Jobs of the polars2 environment run the interpreter beside the worker's environment. + assert ( + "UV_PROJECT_ENVIRONMENT=/opt/pyathena/.venv-polars2 uv sync --directory " + "/opt/pyathena/benchmarks --locked --no-default-groups --group polars2" + ) in user_data assert template["Parameters"]["QueueName"]["Default"] == "" diff --git a/benchmarks/tests/test_fleet.py b/benchmarks/tests/test_fleet.py index f41ffc230..0e72ae697 100644 --- a/benchmarks/tests/test_fleet.py +++ b/benchmarks/tests/test_fleet.py @@ -148,6 +148,22 @@ def test_row_cursor_jobs_are_split_by_arraysize_and_marked_api_heavy(self): assert jobs[0]["pages"] >= jobs[-1]["pages"] assert jobs[0]["args"][-2:] == ["--arraysize", "100"] + def test_jobs_of_another_environment_are_named_and_marked_for_it(self): + jobs = expand_jobs( + SETTINGS, + ["single"], + ["small"], + ["flat"], + Filters(family=["polars"], api=["sync"], transport=["unload"], output_kind="native"), + environment="polars2", + ) + # The suffix keeps the claims, done markers, and results apart from the default's. + assert [(j["id"], j["environment"]) for j in jobs] == [ + ("single-small-flat-polars-sync-unload-native-polars2", "polars2") + ] + default = expand_jobs(SETTINGS, ["single"], ["small"], ["flat"], Filters(family=["polars"])) + assert not any("environment" in j for j in default) + def test_dataframe_chunk_variants_share_one_job(self): jobs = expand_jobs( SETTINGS, @@ -398,6 +414,11 @@ def test_duplicate_ids_across_lists_are_rejected(self): with pytest.raises(ValueError, match="unique"): merge_jobs([[job("a")], [job("a")]]) + def test_unknown_environments_are_rejected_before_publishing(self): + known = {**job("b"), "environment": "polars2"} + with pytest.raises(ValueError, match=r"unknown environment: c$"): + merge_jobs([[job("a"), known], [{**job("c"), "environment": "polars3"}]]) + METADATA = { "instance-id": "i-123", @@ -491,6 +512,14 @@ def test_jobs_command_carries_trial_overrides(self, tmp_path, capsys): jobs = json.loads(capsys.readouterr().out) assert [j["args"][-4:] for j in jobs] == [["--warmups", "1", "--repetitions", "3"]] + def test_jobs_command_selects_the_environment(self, tmp_path, capsys): + config = tmp_path / "config.toml" + config.write_text("[scales]\nsmall = 10000\n") + argv = ["--config", str(config), "jobs", "--suite", "single", "--scale", "small"] + assert main([*argv, "--family", "polars", "--environment", "polars2"]) == 0 + jobs = json.loads(capsys.readouterr().out) + assert {j["environment"] for j in jobs} == {"polars2"} + def test_plan_honors_arraysize_filter_and_repetition_overrides(self, tmp_path, capsys): config = tmp_path / "config.toml" config.write_text("[scales]\nsmall = 10000\n") @@ -610,6 +639,17 @@ def test_trial_evidence_reads_reported_queries_and_trial_prefixes(self, tmp_path assert trial_evidence(tmp_path) == ({"a"}, ("s3://b/runs/r/trials/t1/",)) assert trial_evidence(tmp_path / "missing") == (set(), ()) + def test_jobs_of_a_missing_environment_stop_the_worker_before_claiming( + self, tmp_path, monkeypatch + ): + monkeypatch.setattr("pyathena_bench.fleet.sys.prefix", str(tmp_path / ".venv")) + _, queue = queue_with( + [job("default"), {**job("other"), "environment": "polars2"}], tmp_path + ) + with pytest.raises(ValueError, match=r"environment missing on this host: other$"): + work(queue, tmp_path / "w", api_slots=1, runner=lambda *a: 0, settle=no_queries) + assert not queue.names("claims") + def test_jobs_wider_than_the_api_slots_stop_the_worker_before_claiming(self, tmp_path): _, queue = queue_with([job("wide", heavy=True, api_weight=11)], tmp_path) with pytest.raises(ValueError, match="more than 10 API slots"): @@ -1154,15 +1194,22 @@ def wait(self, timeout=None): class TestRunJob: - def test_resumes_writes_checkpoints_and_interrupts_with_sigint(self, tmp_path, monkeypatch): - processes = [] + @pytest.fixture + def processes(self, monkeypatch): + """Return the fake orchestrator processes that ``run_job()`` starts.""" + started = [] def popen(command, stdout, stderr, start_new_session): - processes.append(FakeProcess(command, stdout, stderr, start_new_session)) - return processes[-1] + started.append(FakeProcess(command, stdout, stderr, start_new_session)) + return started[-1] - killed = [] monkeypatch.setattr("pyathena_bench.fleet.subprocess.Popen", popen) + return started + + def test_resumes_writes_checkpoints_and_interrupts_with_sigint( + self, tmp_path, monkeypatch, processes + ): + killed = [] monkeypatch.setattr( "pyathena_bench.fleet.os.killpg", lambda pid, signum: killed.append((pid, signum)) ) @@ -1189,6 +1236,25 @@ def popen(command, stdout, stderr, start_new_session): assert killed == [(4321, signal.SIGKILL)] assert (tmp_path / "logs" / "a-attempt-2.log").exists() + def test_a_job_of_another_environment_runs_its_interpreter( + self, tmp_path, monkeypatch, processes + ): + monkeypatch.setattr("pyathena_bench.fleet.os.killpg", lambda pid, signum: None) + monkeypatch.setattr("pyathena_bench.fleet.sys.prefix", str(tmp_path / ".venv")) + # A set event stops the fake process at once. + stop = threading.Event() + stop.set() + run_job( + {"id": "a", "args": [], "environment": "polars2"}, + tmp_path, + tmp_path / "results" / "a" / "attempt-1", + [], + stop, + "s3://bucket/fleet/q/results/a/attempt-1/", + ) + [process] = processes + assert process.command[0] == str(tmp_path / ".venv-polars2" / "bin" / "python") + class TestWork: def test_expired_claims_are_taken_over_and_live_ones_left(self, tmp_path): diff --git a/justfile b/justfile index 6a856d044..8a9ddb82c 100644 --- a/justfile +++ b/justfile @@ -85,8 +85,11 @@ _docs-lint: _docs-format: mise exec -- markdownlint-cli2 --fix -# Benchmark workspace member with its own Python 3.12 environment -BENCHMARK_UV := "UV_PROJECT_ENVIRONMENT='" + justfile_directory() + "/benchmarks/.venv' UV_PYTHON=3.12 uv run --directory benchmarks --locked" +# Benchmark workspace member with its own Python 3.12 environments: benchmarks/.venv +# with Polars 1.x, and benchmarks/.venv-polars2 with Polars 2.x +BENCHMARK_RUN := "UV_PYTHON=3.12 uv run --directory benchmarks --locked" +BENCHMARK_UV := "UV_PROJECT_ENVIRONMENT='" + justfile_directory() + "/benchmarks/.venv' " + BENCHMARK_RUN +BENCHMARK_UV_POLARS2 := "UV_PROJECT_ENVIRONMENT='" + justfile_directory() + "/benchmarks/.venv-polars2' " + BENCHMARK_RUN + " --no-group polars1 --group polars2" # Standalone benchmark checks; these do not execute Athena queries benchmark target="lint": @@ -104,6 +107,7 @@ _benchmark-lint: _benchmark-test: _benchmark-lint {{BENCHMARK_UV}} pytest + {{BENCHMARK_UV_POLARS2}} pytest # Install development tools tool: diff --git a/pyproject.toml b/pyproject.toml index 5ebc49443..931872bcb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,9 +92,6 @@ dev = [ "sqlalchemy[asyncio]>=2.0.0", "pandas>=3.0.0", "pyarrow>=22.0.0", - # pyarrow 26.0.0 is the first release with Python 3.15 wheels; without this, - # the lock keeps the version that the benchmarks' awswrangler allows. - "pyarrow>=26.0.0; python_version >= '3.15'", "polars>=1.39.0", # Python 3.14 and later, including the newest version that pull requests test, # use Polars 2; Polars 1.x Series methods return None on Python 3.15 @@ -140,6 +137,20 @@ source = "vcs" [tool.hatch.build.hooks.vcs] version-file = "pyathena/_version.py" +[tool.uv] +# pyarrow 26.0.0 is the first release with Python 3.15 wheels; without this, every +# resolution of the lock keeps the version that the benchmarks' awswrangler allows. +constraint-dependencies = ["pyarrow>=26.0.0; python_version >= '3.15'"] +# The benchmark measures PolarsCursor in one environment per Polars major version; +# the root development group pins Polars by Python version instead. +conflicts = [ + [ + { package = "pyathena", group = "dev" }, + { package = "pyathena-benchmarks", group = "polars1" }, + { package = "pyathena-benchmarks", group = "polars2" }, + ], +] + [tool.uv.workspace] members = ["benchmarks"] diff --git a/uv.lock b/uv.lock index 8dc272a66..c260e09c0 100644 --- a/uv.lock +++ b/uv.lock @@ -1,29 +1,32 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.11" resolution-markers = [ "python_full_version >= '3.15' and sys_platform == 'win32'", - "python_full_version == '3.14.*' and sys_platform == 'win32'", "python_full_version >= '3.15' and sys_platform == 'emscripten'", - "python_full_version == '3.14.*' and sys_platform == 'emscripten'", "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", "python_full_version < '3.12' and sys_platform == 'win32'", "python_full_version < '3.12' and sys_platform == 'emscripten'", "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] +conflicts = [[ + { package = "pyathena", group = "dev" }, + { package = "pyathena-benchmarks", group = "polars1" }, + { package = "pyathena-benchmarks", group = "polars2" }, +]] [manifest] members = [ "pyathena", "pyathena-benchmarks", ] +constraints = [{ name = "pyarrow", marker = "python_full_version >= '3.15'", specifier = ">=26.0.0" }] [[package]] name = "accessible-pygments" @@ -51,15 +54,15 @@ name = "awswrangler" version = "3.17.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "boto3" }, - { name = "botocore" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or python_full_version >= '3.15'" }, - { name = "numpy", version = "2.5.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' and python_full_version < '3.15'" }, - { name = "packaging" }, - { name = "pandas" }, - { name = "pyarrow", version = "25.0.1", source = { registry = "https://pypi.org/simple" } }, - { name = "setuptools", marker = "python_full_version >= '3.12' and python_full_version < '3.15'" }, - { name = "typing-extensions" }, + { name = "boto3", marker = "python_full_version < '3.15' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "botocore", marker = "python_full_version < '3.15' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "numpy", version = "2.5.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15') or (python_full_version < '3.12' and extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (python_full_version < '3.12' and extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (python_full_version < '3.12' and extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev') or (python_full_version >= '3.15' and extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (python_full_version >= '3.15' and extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (python_full_version >= '3.15' and extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "packaging", marker = "python_full_version < '3.15' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "pandas", marker = "python_full_version < '3.15' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "pyarrow", version = "25.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.15' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "setuptools", marker = "(python_full_version >= '3.12' and python_full_version < '3.15') or (python_full_version < '3.12' and extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (python_full_version < '3.12' and extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (python_full_version < '3.12' and extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev') or (python_full_version >= '3.15' and extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (python_full_version >= '3.15' and extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (python_full_version >= '3.15' and extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "typing-extensions", marker = "python_full_version < '3.15' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fc/34/bc4d3ec4f613bf4920fe479879fcdb278b0c7667b24b2cd06e6c841b3f29/awswrangler-3.17.1.tar.gz", hash = "sha256:cc9735a854446c2ccfa25a87295078036361fc170a01c0246e4cf30d4739a2d1", size = 277708, upload-time = "2026-08-03T11:57:35.66Z" } wheels = [ @@ -830,17 +833,14 @@ version = "2.5.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.15' and sys_platform == 'win32'", - "python_full_version == '3.14.*' and sys_platform == 'win32'", "python_full_version >= '3.15' and sys_platform == 'emscripten'", - "python_full_version == '3.14.*' and sys_platform == 'emscripten'", "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] sdist = { url = "https://files.pythonhosted.org/packages/13/01/11703282db468b85f6f7b8c7f22d058de5970d5c7e60a3a8aaa313c3de36/numpy-2.5.3.tar.gz", hash = "sha256:df2d5874ff183595a4ba404edd04f6bd9b5505c1d7708573f6a6c17489a67563", size = 20791231, upload-time = "2026-09-06T16:27:47.073Z" } wheels = [ @@ -925,10 +925,10 @@ name = "pandas" version = "3.0.6" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "numpy", version = "2.5.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "numpy", version = "2.5.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, { name = "python-dateutil" }, - { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, + { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e2/17/d7b106e05bfa642e8694451e7d3d759c6a241c5386a5d962e4f66c047e06/pandas-3.0.6.tar.gz", hash = "sha256:66b07ef7315a31bfe1089cd3d71a7de781c9dca986762d0b4fe7c0ef17465d10", size = 4667686, upload-time = "2026-09-17T23:23:18.345Z" } wheels = [ @@ -1005,18 +1005,21 @@ name = "polars" version = "1.44.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", "python_full_version < '3.12' and sys_platform == 'win32'", "python_full_version < '3.12' and sys_platform == 'emscripten'", "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "polars-runtime-32", version = "1.44.2", source = { registry = "https://pypi.org/simple" } }, + { name = "polars-runtime-32", version = "1.44.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.14' and extra == 'group-8-pyathena-dev') or extra == 'group-19-pyathena-benchmarks-polars1' or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a4/15/e8541eefc22fbc7ca89bcb5112298a153729f73cfbc0cf6a668e509f975c/polars-1.44.2.tar.gz", hash = "sha256:86c8e26b6c2de8c8d344bb910b74dfc47b118ac3fe0f19b44909467990a0b281", size = 766272, upload-time = "2026-09-09T07:42:08.859Z" } wheels = [ @@ -1029,14 +1032,20 @@ version = "2.0.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.15' and sys_platform == 'win32'", - "python_full_version == '3.14.*' and sys_platform == 'win32'", "python_full_version >= '3.15' and sys_platform == 'emscripten'", - "python_full_version == '3.14.*' and sys_platform == 'emscripten'", "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version < '3.12' and sys_platform == 'win32'", + "python_full_version < '3.12' and sys_platform == 'emscripten'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "polars-runtime-32", version = "2.0.0", source = { registry = "https://pypi.org/simple" } }, + { name = "polars-runtime-32", version = "2.0.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.14' and extra != 'group-19-pyathena-benchmarks-polars1') or extra == 'group-19-pyathena-benchmarks-polars2' or (extra != 'group-19-pyathena-benchmarks-polars1' and extra != 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8e/e9/001f371ec6a1bb54893f599ceebd56e6144fed4091f09f09fec0021a9276/polars-2.0.0.tar.gz", hash = "sha256:62da109e27a19a9d36657ee25dc035c9d3f87e7bd610526fe467dc37ea7dc115", size = 778215, upload-time = "2026-10-06T11:51:29.679Z" } wheels = [ @@ -1048,12 +1057,15 @@ name = "polars-runtime-32" version = "1.44.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", "python_full_version < '3.12' and sys_platform == 'win32'", "python_full_version < '3.12' and sys_platform == 'emscripten'", "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", @@ -1076,11 +1088,17 @@ version = "2.0.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.15' and sys_platform == 'win32'", - "python_full_version == '3.14.*' and sys_platform == 'win32'", "python_full_version >= '3.15' and sys_platform == 'emscripten'", - "python_full_version == '3.14.*' and sys_platform == 'emscripten'", "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version < '3.12' and sys_platform == 'win32'", + "python_full_version < '3.12' and sys_platform == 'emscripten'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] sdist = { url = "https://files.pythonhosted.org/packages/34/ad/dbb6f6d7070867951532bcfe5e6a648d8777b416b18cddabc07030404e8c/polars_runtime_32-2.0.0.tar.gz", hash = "sha256:b5f9afcc742b4a67eabd2c680ff0f12eb02ede9b4bf807bffabd6dbb9a58d5c7", size = 3591339, upload-time = "2026-10-06T11:51:31.076Z" } wheels = [ @@ -1130,12 +1148,9 @@ resolution-markers = [ "python_full_version == '3.14.*' and sys_platform == 'win32'", "python_full_version == '3.14.*' and sys_platform == 'emscripten'", "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'emscripten'", - "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", "python_full_version < '3.12' and sys_platform == 'win32'", "python_full_version < '3.12' and sys_platform == 'emscripten'", "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", @@ -1257,15 +1272,15 @@ aiosqlalchemy = [ { name = "sqlalchemy", extra = ["asyncio"] }, ] arrow = [ - { name = "pyarrow", version = "25.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.15'" }, - { name = "pyarrow", version = "26.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.15'" }, + { name = "pyarrow", version = "25.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.15' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "pyarrow", version = "26.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.15' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, ] pandas = [ { name = "pandas" }, ] polars = [ - { name = "polars", version = "1.44.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.14'" }, - { name = "polars", version = "2.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.14'" }, + { name = "polars", version = "1.44.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.14' and extra == 'group-8-pyathena-dev') or extra == 'group-19-pyathena-benchmarks-polars1' or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "polars", version = "2.0.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.14' and extra != 'group-19-pyathena-benchmarks-polars1') or extra == 'group-19-pyathena-benchmarks-polars2' or (extra != 'group-19-pyathena-benchmarks-polars1' and extra != 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev')" }, ] sqlalchemy = [ { name = "sqlalchemy" }, @@ -1279,10 +1294,10 @@ dev = [ { name = "mypy" }, { name = "myst-parser" }, { name = "pandas" }, - { name = "polars", version = "1.44.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.14'" }, - { name = "polars", version = "2.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.14'" }, - { name = "pyarrow", version = "25.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.15'" }, - { name = "pyarrow", version = "26.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.15'" }, + { name = "polars", version = "1.44.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.14' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "polars", version = "2.0.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.14' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev')" }, + { name = "pyarrow", version = "25.0.1", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.15' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "pyarrow", version = "26.0.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.15' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev')" }, { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-cov" }, @@ -1293,7 +1308,7 @@ dev = [ { name = "sphinx-design" }, { name = "sphinx-multiversion" }, { name = "sphinxext-opengraph" }, - { name = "sqlalchemy", extra = ["asyncio"] }, + { name = "sqlalchemy", extra = ["asyncio"], marker = "(extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra != 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev') or (extra != 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev')" }, ] [package.metadata] @@ -1323,7 +1338,6 @@ dev = [ { name = "polars", marker = "python_full_version < '3.14'", specifier = "<2.0.0" }, { name = "polars", marker = "python_full_version >= '3.14'", specifier = ">=2.0.0" }, { name = "pyarrow", specifier = ">=22.0.0" }, - { name = "pyarrow", marker = "python_full_version >= '3.15'", specifier = ">=26.0.0" }, { name = "pytest", specifier = ">=3.5" }, { name = "pytest-asyncio" }, { name = "pytest-cov" }, @@ -1341,16 +1355,23 @@ dev = [ name = "pyathena-benchmarks" version = "0.1.0" source = { virtual = "benchmarks" } +default-groups = ["polars1", "test"] dependencies = [ - { name = "awswrangler", marker = "python_full_version < '3.15'" }, - { name = "polars", version = "1.44.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.14'" }, - { name = "polars", version = "2.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.14'" }, + { name = "awswrangler", marker = "python_full_version < '3.15' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "polars", version = "1.44.2", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.14' and extra == 'group-8-pyathena-dev') or extra == 'group-19-pyathena-benchmarks-polars1' or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, + { name = "polars", version = "2.0.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.14' and extra != 'group-19-pyathena-benchmarks-polars1') or extra == 'group-19-pyathena-benchmarks-polars2' or (extra != 'group-19-pyathena-benchmarks-polars1' and extra != 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev')" }, { name = "psutil" }, { name = "pyathena", extra = ["arrow", "pandas", "polars", "sqlalchemy"] }, ] [package.dev-dependencies] -dev = [ +polars1 = [ + { name = "polars", version = "1.44.2", source = { registry = "https://pypi.org/simple" } }, +] +polars2 = [ + { name = "polars", version = "2.0.0", source = { registry = "https://pypi.org/simple" } }, +] +test = [ { name = "cfn-lint" }, { name = "mypy" }, { name = "pytest" }, @@ -1367,7 +1388,9 @@ requires-dist = [ ] [package.metadata.requires-dev] -dev = [ +polars1 = [{ name = "polars", specifier = ">=1.39.0,<2" }] +polars2 = [{ name = "polars", specifier = ">=2,<3" }] +test = [ { name = "cfn-lint", specifier = ">=1" }, { name = "mypy" }, { name = "pytest", specifier = ">=8" }, @@ -1389,7 +1412,7 @@ name = "pytest" version = "9.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "sys_platform == 'win32' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, @@ -1406,7 +1429,7 @@ version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" } wheels = [ @@ -1418,7 +1441,7 @@ name = "pytest-cov" version = "6.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "coverage", extra = ["toml"] }, + { name = "coverage", extra = ["toml"], marker = "(extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra != 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev') or (extra != 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev')" }, { name = "pytest" }, ] sdist = { url = "https://files.pythonhosted.org/packages/be/45/9b538de8cef30e17c7b45ef42f538a94889ed6a16f2387a6c89e73220651/pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0", size = 66945, upload-time = "2024-10-29T20:13:35.363Z" } @@ -1869,7 +1892,7 @@ name = "sqlalchemy" version = "2.0.46" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-19-pyathena-benchmarks-polars2') or (extra == 'group-19-pyathena-benchmarks-polars1' and extra == 'group-8-pyathena-dev') or (extra == 'group-19-pyathena-benchmarks-polars2' and extra == 'group-8-pyathena-dev')" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/06/aa/9ce0f3e7a9829ead5c8ce549392f33a12c4555a6c0609bb27d882e9c7ddf/sqlalchemy-2.0.46.tar.gz", hash = "sha256:cf36851ee7219c170bb0793dbc3da3e80c582e04a5437bc601bfe8c85c9216d7", size = 9865393, upload-time = "2026-01-21T18:03:45.119Z" }