Skip to content

Support Python 3.15 - #1164

Merged
laughingman7743 merged 3 commits into
masterfrom
feat/python-3-15
Oct 14, 2026
Merged

laughingman7743 merged 3 commits into
masterfrom
feat/python-3-15

Conversation

@laughingman7743

@laughingman7743 laughingman7743 commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

WHAT

Declare and test CPython 3.15.

  • Add the Programming Language :: Python :: 3.15 classifier, the py315 tox environments and gh-actions mapping, and 3.15 in the Test workflow's PYTHON_VERSIONS.
    Pull requests and the scheduled run test the newest version, so they now run on 3.15 instead of 3.14.
  • Extend the actions/setup-python step in test-suite.yaml, which 3.13 and 3.14 already use, to 3.15.
  • List 3.15 in README.md and docs/introduction.md.
  • Make the development lock installable on 3.15:
    • greenlet 3.3.2 → 3.5.6 (3.3.2 has no cp315 wheel; its source build failed locally on macOS).
    • coverage 7.6.10 → 7.16.2 and MarkupSafe 3.0.2 → 3.0.4 (the locked versions have no cp315 wheels, so their C extensions were compiled from source).
    • typing-extensions 4.12.2 → 4.16.0 (4.12.2 fails at import because 3.15 removed typing.no_type_check_decorator).
    • pyarrow 26.0.0 for Python 3.15 only; 25.0.1 stays for 3.11–3.14.
      Released awswrangler (a benchmarks dependency) caps pyarrow<26.0.0, and 26.0.0 is the first pyarrow with cp315 wheels.
      The benchmarks' awswrangler dependency now carries python_version < '3.15' (benchmarks run on 3.12), and the dev group requires pyarrow>=26.0.0 on 3.15 so the lock forks pyarrow by Python version.
      Both markers can go once an awswrangler release allows pyarrow 26 (feat: support Python 3.15 aws/aws-sdk-pandas#3511 was merged on 2026-10-14 and has not been released yet).
    • Polars: the dev group already locks Polars 2.0.0 on Python 3.14 and later (Read CSV results through fsspec for Polars 2.0 #1169); the comment now notes that 3.15 needs it, because Polars 1.x Series methods such as is_null() return None on 3.15 (_is_empty_method is not True on Python 3.15 pola-rs/polars#29419) and the fix is released only in 2.0.0.
  • test_contain_special_character_query_with_parameter accepts ValueError as well as TypeError: on 3.15, %-formatting a query that contains a % without a mapping key (such as LIKE '%str%') together with parameters raises ValueError: format requires a parenthesised mapping key instead of TypeError.
    The formatter passes this exception through unchanged, so callers on 3.15 see ValueError.

Runtime requirements in [project] and the extras do not change.
The lock was written with uv 0.12.5 and keeps lock revision 3, which the uv version pinned by the benchmark stack also reads.

WHY

Closes #1163.
CPython 3.15.0 has been released; with the current lock, uv sync --group dev on 3.15 fails while building greenlet and pyarrow from source (observed on macOS arm64).

TEST

Tested commit: bffd354 (rebased onto a618cd5, which includes #1169) unless noted (macOS arm64, CPython 3.15.0 installed by uv 0.13.1)

  • uv sync --locked --group dev -p 3.15: Polars 2.0.0, pyarrow 26.0.0, greenlet 3.5.6; installs from wheels except pytest-dependency (sdist only for every release) and PyYAML (no cp315 wheel for any release; its C extension is optional).
  • just lint on 3.15 (ruff, mypy, cfn-lint, license headers): passed.
  • uv lock --check with uv 0.12.5 and 0.13.1: passed.
  • just benchmark test (Python 3.12): 235 passed, 1 skipped. just scripts: 112 passed. just docs lint: 0 errors.
  • On 3.15 (AWS): tests/pyathena/polars, tests/pyathena/aio/polars, TestCursor::test_contain_special_character_query_with_parameter, and TestArrowCursor::test_complex_unload_as_polars: 156 passed.
  • Before the rebase, Test run 38560114057 at 9d405b8 (all versions) passed every job except test / run (3.15), which failed only the Polars 1.x and ValueError cases that this PR and Read CSV results through fsspec for Polars 2.0 #1169 address.
  • Full AWS suites at bffd354: Test run 38579872984 (pull request, Python 3.15) and dispatched run 38581528226 (Python 3.11–3.14): test, test-sqla, and test-sqla-async all passed on every version.

🤖 Generated with Claude Code

Comment thread pyproject.toml
"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'",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-review round one (implementation behavior) — CLEAN

Base 6ea5587dde5aae5a5066a91da1f1231803d471e0, head ba621c1548e760ccbecaff9fd278de3b04e19343.

Covered: pyproject.toml (classifier, dev-group pyarrow marker, tox envlist/gh-actions), benchmarks/pyproject.toml (awswrangler marker), uv.lock (greenlet 3.5.6, typing-extensions 4.16.0, pyarrow forked 25.0.1 / 26.0.0 at 3.15), test.yaml PYTHON_VERSIONS, test-suite.yaml setup-python condition, README.md, docs/introduction.md.

  • No runtime code or [project] requirement changes, so DB API, converter, and filesystem behavior are unchanged for 3.11–3.14 users.
  • Grepped pyathena/ for APIs removed or changed by 3.15 (open() without encoding under UTF-8 mode, get_event_loop, event-loop policies, utcnow, locale): none used.
  • The awswrangler marker only affects the benchmark environment on 3.15; benchmarks run on 3.12 (BENCHMARK_UV sets UV_PYTHON=3.12; README and the bootstrap pin 3.12), and adapters.py imports awswrangler at module level only there.
  • greenlet 3.5.6 ships cp311/cp312 manylinux aarch64/x86_64 wheels, so the Graviton benchmark host and CI keep binary installs.
  • Validation: just lint on 3.15 (mypy 1.14.0 via its pure wheel), just benchmark test 217 passed / 1 skipped, just scripts 112 passed, uv lock --check with uv 0.12.5 and 0.13.1.

Comment thread uv.lock
{ url = "https://files.pythonhosted.org/packages/50/69/b3f2416725621e9f112e74e8470793d5b5995f146f596f133678a633b77e/coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2", size = 248737, upload-time = "2024-12-26T16:58:45.919Z" },
{ url = "https://files.pythonhosted.org/packages/3c/6e/fe899fb937657db6df31cc3e61c6968cb56d36d7326361847440a430152e/coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312", size = 211611, upload-time = "2024-12-26T16:58:47.883Z" },
{ url = "https://files.pythonhosted.org/packages/1c/55/52f5e66142a9d7bc93a15192eba7a78513d2abf6b3558d77b4ca32f5f424/coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d", size = 212781, upload-time = "2024-12-26T16:58:50.822Z" },
version = "7.16.2"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-review round two (claims and operations) — FINDINGS, repaired in 9d405b8

Base 6ea5587dde5aae5a5066a91da1f1231803d471e0, head ba621c1548e760ccbecaff9fd278de3b04e19343.

Claims checked: pyarrow cp315 wheels start at 26.0.0 (PyPI); every released awswrangler caps pyarrow<26 (3.17.0 <25, 3.17.1 <26); aws/aws-sdk-pandas#3511 merged 2026-10-14T09:35Z with 3.17.1 still latest on PyPI; typing_extensions 4.12.2 import failure on 3.15 (observed AttributeError: typing.no_type_check_decorator); PR/scheduled runs use [last] of PYTHON_VERSIONS; lock stays at revision 3; runtime requirements unchanged.

Findings:

  1. The PR claimed a 3.15 install used wheels except pure-Python sdists. Comparing the installed environment with the lock showed coverage 7.6.10 and MarkupSafe 3.0.2 compiled C extensions from source (no cp315 wheels), and --cov runs in every CI suite. Repaired by locking coverage 7.16.2 and MarkupSafe 3.0.4 (this line); remaining sdists are pytest-dependency (sdist-only for all releases) and PyYAML (no cp315 wheel for any release, optional C extension).
  2. "greenlet 3.3.2's sdist fails to build on 3.15" was observed only on macOS arm64 ('cstdlib' file not found); narrowed the PR body and Support Python 3.15 #1163 to that observation.

Repair validation on 3.15: just lint passed; pytest --cov pyathena tests/pyathena/test_parser.py tests/pyathena/test_formatter.py 105 passed; just benchmark test 217 passed / 1 skipped. AWS suites on 3.11–3.15 are in Test run 38560114057.

# Every supported version, oldest first; keep in sync with the
# pyproject.toml classifiers.
PYTHON_VERSIONS: '["3.11", "3.12", "3.13", "3.14"]'
PYTHON_VERSIONS: '["3.11", "3.12", "3.13", "3.14", "3.15"]'

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent review (relayed) — CLEAN

Reviewer: Codex CLI 0.162.1, model gpt-6-astra, model_reasoning_effort=high, sandbox read-only; session 01a13a46-70f8-7ea2-a682-b1d486cff58e.
Base 6ea5587dde5aae5a5066a91da1f1231803d471e0, head 9d405b8d68da5c0cd9dad5e50225475b34875a8a, detached snapshot worktree (unchanged after the review).
Constraints: review only (no edits, builds, tests, or GitHub access); the prompt omitted the PR number, description, commit messages, and prior findings. Static review with public package-metadata lookups; nothing was executed.

Reviewer output:

Surfaces covered:

  • Runtime dependencies, extras, and requires-python: unchanged.
  • Lock forks and dependency markers: pyarrow remains 25.0.1 on 3.11–3.14 and selects 26.0.0 on 3.15. NumPy selections remain consistent. The awswrangler dependency branches for 3.15 are unreachable because its parent dependency excludes that version.
  • Benchmark environment: Python 3.12 still includes awswrangler 3.17.1 and pyarrow 25.0.1. Shared lock upgrades also affect older environments: coverage 7.6.10 → 7.16.2, greenlet 3.3.2 → 3.5.6, MarkupSafe 3.0.2 → 3.0.4, and typing-extensions 4.12.2 → 4.16.0. Their Python requirements still permit 3.11.
  • CI and tox: traced version selection through both workflows, interpreter setup, just tox, all three tox environments, and release-workflow reuse. Python 3.15 is included.
  • Listings and tests: checked classifiers, README, documentation, benchmark configuration, and searches for supported-version assertions; no stale version set found.
  • Added comments: confirmed against pyarrow release metadata and awswrangler metadata.
  • Runtime compatibility: inspected datetime parsing, text encoding, imports, typing/introspection, and concurrency paths against the Python 3.15 changes. No concrete required runtime repair identified.

CLEAN

No actionable findings in 6ea5587d..9d405b8d. This is a static review with public metadata verification; installation, builds, tests, and AWS execution were not performed.

laughingman7743 and others added 3 commits October 14, 2026 23:13
Declare and test CPython 3.15: add the classifier, the py315 tox
environments, the Test workflow version list, and the setup-python
workaround that 3.13 and 3.14 already use.

Make the development lock installable on 3.15. greenlet 3.3.2 and
pyarrow 25.0.1 have no cp315 wheels, and typing_extensions 4.12.2 fails
at import because 3.15 removed typing.no_type_check_decorator. Released
awswrangler caps pyarrow below 26.0.0, so the benchmarks dependency is
limited to Python < 3.15 and the dev group requires pyarrow 26.0.0 on
3.15, which forks pyarrow by Python version in the lock.

Closes #1163

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
coverage 7.6.10 and MarkupSafe 3.0.2 have no cp315 wheels, so a 3.15
environment compiled their C extensions from source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Python 3.15 raises ValueError instead of TypeError when a % without a
mapping key meets a parameter mapping, so the test accepts either.

The dev group already tests Polars 2 on Python 3.14 and later; Polars
1.x Series methods return None on Python 3.15 (pola-rs/polars#29419), so
3.15 needs it as well.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

def test_contain_special_character_query_with_parameter(self, cursor):
# Python 3.15 raises ValueError instead of TypeError for a % without a mapping key.
pytest.raises(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-review of the changes after the first reviews and of the rebase (both perspectives): CLEAN

Old range 6ea5587dde5aae5a5066a91da1f1231803d471e0..9d405b8d68da5c0cd9dad5e50225475b34875a8a (reviewed), new range a618cd57..bffd35492274be1bc6c39b491aeb4b0b23696115, compared with git range-diff. The new base includes #1169 (Polars 2 on Python 3.14 and later), #1167, #1166, and #1165.

Changes since the reviewed head:

  • test_contain_special_character_query_with_parameter now accepts (TypeError, ValueError). CI run 38560114057 failed on 3.15 with ValueError: format requires a parenthesised mapping key; locally, 3.12 raises TypeError: not enough arguments for format string and 3.15 raises ValueError for the same expression. DefaultParameterFormatter.format() does not catch either, so the test now asserts what Python raises. The formatter code is unchanged.
  • Support Python 3.15 #1164's own polars>=2.0.0; python_version >= '3.15' marker was dropped in favor of Read CSV results through fsspec for Polars 2.0 #1169's >= '3.14' marker; the comment now also gives the 3.15 reason (_is_empty_method is not True on Python 3.15 pola-rs/polars#29419, fixed only in 2.0.0; reproduced locally: Series.is_null() returns None on 3.15 with Polars 1.44.2).
  • uv.lock was regenerated from the new base with uv 0.12.5 (revision 3). The package versions that differ from the base are the same set as before the rebase (greenlet 3.5.6, typing-extensions 4.16.0, coverage 7.16.2, MarkupSafe 3.0.4, pyarrow 26.0.0 for 3.15); the rest is fork-marker text.

Behavior perspective: no runtime code changes; on 3.15, Polars 2.0.0 and pyarrow 26.0.0 are locked. The upstream runtime changes (#1165 S3File parts, #1167 PandasCursor rows) are covered by the full CI on 3.15 to follow.
Claims perspective: the PR body now drops the dependency note on #1168 and the obsolete Polars 3.15 marker, and records the post-rebase evidence.
Validation at bffd354: uv lock --check (uv 0.12.5 and 0.13.1), just lint on 3.15, just benchmark test 235 passed / 1 skipped, just scripts 112 passed, just docs lint; on 3.15 (AWS) the Polars suites plus the formatter and Arrow as_polars tests: 156 passed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent follow-up review (relayed): CLEAN

Reviewer: Codex CLI 0.162.1, model gpt-6-astra, model_reasoning_effort=high, sandbox read-only; session 01a13ac7-07b9-7621-b40e-0e34457523cf.
Scope: a618cd57..bffd35492274be1bc6c39b491aeb4b0b23696115 with the range-diff against the reviewed 6ea5587d..9d405b8d; detached snapshot unchanged after the review. The prompt described the change and the new base, without the PR description, commit messages, or author conclusions. Static review only.

Reviewer output:

Surfaces covered:

  • Supplied full diff and range comparison; CI version selection, tox configuration, classifiers, and support documentation.
  • tests/pyathena/test_cursor.py:635: accepting (TypeError, ValueError) is appropriately scoped. The unchanged formatter delegates to %; the existing 3.15 failure log confirms ValueError at that operation. Escaped-percent success cases remain intact.
  • pyproject.toml:99 and uv.lock: the comment matches the retained markers. Polars resolves to 1.44.2 below 3.14 and 2.0.0 on ≥3.14; PyArrow resolves to 25.0.1 below 3.15 and 26.0.0 on ≥3.15. Root, extras, benchmark edges, and runtime-package forks agree.
  • Dependency upgrades: checked release metadata and wheel availability for greenlet 3.5.6, typing-extensions 4.16.0, coverage 7.16.2, and MarkupSafe 3.0.4.
  • Base changes in 6ea5587d..a618cd57: Polars CSV/map compatibility and associated tests, pandas row iteration, bounded multipart uploads, and benchmark quiescing. No additional actionable 3.15 interaction identified.

CLEAN — no actionable findings in the follow-up scope.

Read-only inspection, including existing log evidence; no builds, tests, installs, edits, or GitHub writes performed. This does not establish runtime success at the current head.

@laughingman7743
laughingman7743 marked this pull request as ready for review October 14, 2026 14:22
@laughingman7743
laughingman7743 merged commit 301ae52 into master Oct 14, 2026
30 checks passed
@laughingman7743
laughingman7743 deleted the feat/python-3-15 branch October 14, 2026 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Python 3.15

1 participant