Skip to content

pynumaflow-lite: Drop Python 3.10 and add Python 3.15 to the supported versions. - #387

Merged
BulkBeing merged 2 commits into
mainfrom
pynumaflow-lite-py311
Oct 10, 2026
Merged

BulkBeing merged 2 commits into
mainfrom
pynumaflow-lite-py311

Conversation

@BulkBeing

@BulkBeing BulkBeing commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor
  • Set requires-python to >=3.11 and ruff target-version to py311.
  • Use typing.Self for aenter return types and drop from __future__ import annotations in the stubs.
  • Use PyBaseExceptionGroup directly in combine_errors. The fallback for versions without BaseExceptionGroup is no longer necessary.
  • Use uv to install Python in CI and test on 3.11 to 3.15.
  • Move Dockerfile base images to slim-trixie.
  • Update ruff, maturin, and GitHub Actions versions.
  • Drops timeout parameter in wait_ready(timeout=10). Python >= 3.11 has asyncio.timeout(10). Passing timeout to async functions is considered as a bad practice https://docs.astral.sh/ruff/rules/async-function-with-timeout/

Drop Python 3.10 and add Python 3.15 to the supported versions.

- Set requires-python to >=3.11 and ruff target-version to py311.
- Use typing.Self for __aenter__ return types and drop
  `from __future__ import annotations` in the stubs.
- Use PyBaseExceptionGroup directly in combine_errors. The fallback
  for versions without BaseExceptionGroup is no longer necessary.
- Use uv to install Python in CI and test on 3.11 to 3.15.
- Move Dockerfile base images to slim-trixie.
- Update ruff, maturin, and GitHub Actions versions.

Signed-off-by: Sreekanth <prsreekanth920@gmail.com>
@codecov

codecov Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.99%. Comparing base (295aaaf) to head (10aaec2).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #387   +/-   ##
=======================================
  Coverage   92.99%   92.99%           
=======================================
  Files          68       68           
  Lines        3656     3656           
  Branches      236      236           
=======================================
  Hits         3400     3400           
  Misses        190      190           
  Partials       66       66           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Python 3.10 is EOL, so this raises the floor to 3.11 and cleans up the
things we were carrying only for 3.10.

The biggest change is how readiness works. Previously `wait_ready()`
took a `timeout` argument that was enforced in Rust, and `async with
server:` quietly used a 30 second default. That isn't how asyncio APIs
work: the caller owns cancellation, and the idiomatic way to bound an
await is `asyncio.timeout()`, which is available now that 3.11 is our
minimum. So `wait_ready()` no longer takes any arguments and polls
until the server is ready. pyo3-async-runtimes drops the Rust future
when the Python future is cancelled, so an expired `asyncio.timeout()`
really stops the polling loop instead of leaving it running behind us.

Removing the fixed 30s from `__aenter__` meant it needed another way to
avoid hanging forever when the server can't start. It now waits for
whichever comes first: the server becoming ready, or the server task
exiting. A startup failure (a bad socket path, for example) is raised
immediately, instead of after 30 seconds of polling a server that is
already dead.

The five async server wrappers (map, batchmap, mapstream, sink,
sourcetransform) were copies of each other that differed only in their
Rust core type, their handler annotation, and the name in error
messages. Rather than write the new `__aenter__` logic five times, they
now share a private `_AsyncServer` base class.

This is a breaking change to `wait_ready()`, but the package hasn't
been published yet, so now is the time to do it.

Smaller 3.11 cleanups:

  - `combine_errors` uses `PyBaseExceptionGroup` directly. The
    first-error-only fallback for interpreters without exception
    groups is gone.
  - `__aenter__` is annotated as returning `Self`.
  - `datetime.UTC` instead of `timezone.utc`.
  - Drop `from __future__ import annotations` from the stubs, where it
    has no effect.
  - CI no longer tests or builds wheels for 3.10.
  - Example images move from Debian bullseye (EOL) to trixie.

Signed-off-by: Sreekanth <prsreekanth920@gmail.com>
@BulkBeing
BulkBeing marked this pull request as ready for review October 10, 2026 13:09
@BulkBeing
BulkBeing merged commit fb9c066 into main Oct 10, 2026
25 checks passed
@BulkBeing
BulkBeing deleted the pynumaflow-lite-py311 branch October 10, 2026 16:08
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.

2 participants