Skip to content

feat!: support Python 3.11-3.15, dropping 3.9 and 3.10 - #24

Merged
hampsterx merged 2 commits into
masterfrom
feat/python-311-315
Oct 19, 2026
Merged

hampsterx merged 2 commits into
masterfrom
feat/python-311-315

Conversation

@hampsterx

@hampsterx hampsterx commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Supported Python is now 3.11-3.15: requires-python = ">=3.11", classifiers for 3.11-3.15, and the CI and publish test matrices run all five. 3.15.0 is released and the compiled dependencies (cryptography, pydantic-core, pandas, numpy) ship cp315 wheels.
  • ruff, black and mypy target 3.11, the new floor.
  • Black moves to 26.5.1 (pre-commit rev and the [dev] cap >=26.5,<26.6 together). It was held at 25.9.0 only because later releases need 3.10+; 26.5.1 carries the CVE-2026-32274 and CVE-2026-31900 fixes. Black 26 reflows one .format() call in tests/test_import_footprint.py.
  • coerce_rows passes strict=False to zip(): B905 fires at the py311 target, and False is zip()'s default, so behaviour is unchanged.
  • Guidance that only protected the 3.9 floor is gone (the PEP 604 quirk in AGENTS.md, the black and Dependabot caveats, a single-with test comment). pyupgrade (UP) stays off: the code still spells Optional/List, and enabling it is a ~250-site annotation rewrite of its own.

Docs: updated

Backwards compatibility

Breaking for anyone on Python 3.9 or 3.10: pip will not resolve this release there and stays on the last 3.9-compatible version. No API change. The next tag should be a minor bump, not a patch.

Review

External (Codex, GLM-5.2) on b7ccefd: 0 applied, 1 noted (GLM: no test pins coerce_rows truncation on a cell/column count mismatch; declined, the behaviour is preserved rather than intended), re-reviewed after fixes on 28c5f6c: clean.
Analysis pass on 28c5f6c: APPROVE, 1 applied (black 26.5.1), re-run yes.
Deferred from the analysis pass:

  • mention pyproject.toml:36: extras floors are unreachable on the new range (pandas>=1.3 has no 3.11 wheels, 1.5 is the first) and CI never installs the extras (mention)
  • mention snowflake_sql_api/types.py:183: no test pins the mismatch behaviour; strict=True still passes the suite (mention)

Written after review: the Backwards compatibility section.

Changes

 .github/dependabot.yml         |  8 ++++----
 .github/workflows/ci.yml       |  2 +-
 .github/workflows/publish.yml  |  2 +-
 .pre-commit-config.yaml        |  7 +++----
 AGENTS.md                      | 11 +----------
 CONTRIBUTING.md                |  2 +-
 docs/getting-started.md        |  2 +-
 pyproject.toml                 | 36 +++++++++++++++++-------------------
 snowflake_sql_api/types.py     |  5 ++++-
 tests/test_import_footprint.py |  4 +---
 tests/test_testing.py          |  2 --
 11 files changed, 34 insertions(+), 47 deletions(-)

Test plan

  • pre-commit run --all-files clean (ruff, black 26.5.1, mypy)
  • coverage run -m pytest on 3.11 and 3.14: 194 passed, 5 skipped, 94%
  • Same suite plus black, mypy and ruff on a local 3.15.0 build (setup-python's): 194 passed, 94%
  • CI matrix 3.11-3.15 green (lint + five test legs)
  • No visual effect.

Moves the supported range up to the current CPython releases. 3.15.0 is out
and every compiled dependency (cryptography, pydantic-core, pandas, numpy)
ships cp315 wheels, so the CI and publish matrices now run 3.11-3.15.

With 3.9 gone, the notes that existed only to protect it are removed: the
PEP 604 quirk in AGENTS.md, the black-runs-on-3.9 caveats on the dev cap,
pre-commit rev and Dependabot ignore, and the single-`with` test comment.
ruff, black and mypy now target 3.11.

The py311 ruff target enables B905 at the one `zip()` in coerce_rows; it
takes strict=False to keep today's behaviour for a row whose cell count
differs from the column count. Enabling pyupgrade (UP) is left out: the
code still spells Optional/List, and that is a ~250-site rewrite of its own.
25.9.0 was held only because later black needs Python 3.10+. It predates
the 26.3.x security fixes, and with Dependabot security updates off for
this repo nothing else would raise them. The hook rev and the [dev] cap
move together; black 26 reflows one .format() call in a test.
@coderabbitai

coderabbitai Bot commented Oct 19, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 32 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9a6d2940-1707-462c-ab8d-6a1b1e9d3316
📥 Commits

Reviewing files that changed from the base of the PR and between ac4854d and 28c5f6c.

📒 Files selected for processing: 11
  • .github/dependabot.yml
  • .github/workflows/ci.yml
  • .github/workflows/publish.yml
  • .pre-commit-config.yaml
  • AGENTS.md
  • CONTRIBUTING.md
  • docs/getting-started.md
  • pyproject.toml
  • snowflake_sql_api/types.py
  • tests/test_import_footprint.py
  • tests/test_testing.py
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hampsterx
hampsterx merged commit af00371 into master Oct 19, 2026
7 checks passed
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.

1 participant