Skip to content

feat: support Python 3.10-3.14, drop EOL 3.8/3.9#512

Open
deanq wants to merge 5 commits into
mainfrom
deanquinanola/sls-265-runpod-python-drop-eol-python-3839-support-310314
Open

feat: support Python 3.10-3.14, drop EOL 3.8/3.9#512
deanq wants to merge 5 commits into
mainfrom
deanquinanola/sls-265-runpod-python-drop-eol-python-3839-support-310314

Conversation

@deanq

@deanq deanq commented Jun 18, 2026

Copy link
Copy Markdown
Member

Summary

runpod-python declared support for Python 3.8/3.9 — both end-of-life and receiving no security patches — and the declared range was inconsistent across files. This aligns the package to a supported, tested range of Python 3.10–3.14.

Python support schedule (as of 2026-06-18)

Version EOL Status
3.8 2024-10-07 EOL
3.9 2025-10-31 EOL
3.10 2026-10-31 Security-only (EOL in ~4 months)
3.11 2027-10-31 Supported
3.12 2028-10-31 Supported
3.13 2029-10-31 Supported
3.14 2030-10-31 Supported (GA Oct 2025)

Changes

  • pyproject.tomlrequires-python = ">=3.10"; classifiers 3.10–3.14
  • setup.pypython_requires=">=3.10"
  • .github/workflows/ci.yml — test matrix ["3.10", "3.11", "3.12", "3.13", "3.14"]
  • README.md, ARCHITECTURE.md — reflect the new support range

Why floor at 3.10, not 3.11

3.10 reaches EOL 2026-10-31, but the GPU/ML base-image ecosystem still ships 3.10/3.11, and the SDK floor caps what serverless workers can run. Holding at 3.10 avoids stranding those workers. Planned follow-up: bump floor to 3.11 after 3.10 EOL (Q4 2026).

Out of scope (follow-up)

The runpod project create CLI still offers 3.8/3.9 in its version picker (runpod/cli/groups/project/commands.py). That selector is gated by RunPod GPU base-image availability — a separate axis from the SDK runtime — so it needs base-image verification before changing.

Test plan

  • make quality-check passes locally: 478 passed, coverage 94.39% (gate 90%)
  • CI matrix exercises 3.10–3.14

@promptless

promptless Bot commented Jun 18, 2026

Copy link
Copy Markdown

Promptless prepared a documentation update related to this change.

Triggered by runpod-python PR #512 (drop EOL Python 3.8/3.9, support Python 3.10–3.14).

The Python SDK install page (serverless/sdks.mdx) didn't state any Python version requirement, so we added a note that the Python SDK requires Python 3.10 or higher to match this change. The CLI version picker and base-image Python options were intentionally left unchanged, since those are gated by a separate axis.

Review: Document Python 3.10+ requirement for the Python SDK

@deanq deanq force-pushed the deanquinanola/sls-265-runpod-python-drop-eol-python-3839-support-310314 branch from adbd903 to 68ff3cc Compare June 18, 2026 17:20
@deanq deanq changed the base branch from main to deanquinanola/sls-268-fix-flaky-tests June 18, 2026 17:20
@deanq deanq requested a review from Copilot June 18, 2026 20:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR aligns runpod-python’s declared and tested Python version support by dropping EOL Python 3.8/3.9 and standardizing the project on Python 3.10–3.14 across packaging metadata, CI, and documentation.

Changes:

  • Bumped packaging metadata (pyproject.toml, setup.py) to >=3.10 and updated Trove classifiers to 3.10–3.14.
  • Expanded the GitHub Actions CI test matrix to run on Python 3.10–3.14.
  • Updated docs to reflect the new minimum supported Python version.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
setup.py Raises python_requires to >=3.10.
README.md Updates installation docs to state Python 3.10+ requirement.
pyproject.toml Sets requires-python = ">=3.10" and updates classifiers to 3.10–3.14.
ARCHITECTURE.md Updates documented Python support range for runpod/serverless/.
.github/workflows/ci.yml Expands test matrix to include Python 3.13 and 3.14.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ARCHITECTURE.md Outdated
deanq added 2 commits June 18, 2026 13:31
Python 3.8 (EOL 2024-10) and 3.9 (EOL 2025-10) are end-of-life;
advertising support for them was a false security claim. Raise the
supported floor to 3.10 and declare/test through 3.14.

- requires-python / python_requires: >=3.10
- classifiers: 3.10-3.14
- CI test matrix: 3.10, 3.11, 3.12, 3.13, 3.14
- README / ARCHITECTURE: reflect new support range

Floor stays at 3.10 (not 3.11) because GPU/ML base images still ship
3.10/3.11; plan a 3.10->3.11 bump after 3.10 EOL (2026-10).

Refs SLS-265
Adding 3.14 to the CI matrix surfaced a collection error: nest_asyncio
(a test-only dependency) calls the deprecated asyncio.get_event_loop_policy,
and pytest's -W error promoted the DeprecationWarning to a hard error,
interrupting collection of test_worker.py. The SDK runtime does not use
that API, so this is purely test infrastructure.

Move the warnings config from addopts (-W error) into a filterwarnings
list so an ignore for this specific third-party message takes precedence
while all other warnings remain errors.

Refs SLS-265
@deanq deanq force-pushed the deanquinanola/sls-265-runpod-python-drop-eol-python-3839-support-310314 branch from bf0aab2 to f950a4b Compare June 18, 2026 20:31
@deanq deanq changed the base branch from deanquinanola/sls-268-fix-flaky-tests to main June 18, 2026 20:31
@deanq deanq closed this Jun 18, 2026
@deanq deanq reopened this Jun 18, 2026
deanq added 3 commits June 18, 2026 14:43
nest_asyncio.apply() ran at import and globally patched asyncio; on
Python 3.14 the patched loop breaks current_task(), so asyncio.timeout
(used by asyncio.wait_for in the GPU fitness check) raised "Timeout
should be used inside a task" and failed collection/run for any test
touching it. The SDK runtime itself is 3.14-clean (plain asyncio.run
provides the task context).

- Remove nest_asyncio entirely and drop it from test deps. Convert the
  worker test classes from IsolatedAsyncioTestCase to TestCase: their
  bodies call runpod.serverless.start() synchronously (as production
  does), so run_worker's internal asyncio.run() no longer nests inside a
  running loop and needs no patching.
- Stub run_fitness_checks in TestRunWorker.setUp so unit tests don't run
  real GPU/memory probes (covered by test_modules/test_fitness/).
- test_download_files_from_urls: assert the set of requested URLs, not
  positional call order, since downloads run in parallel threads.

Refs SLS-265
The backoff dependency calls asyncio.iscoroutinefunction in its
on_exception decorator; Python 3.14 deprecates it (removal in 3.16).
The SDK's own code uses inspect.iscoroutinefunction, and at runtime this
is only a warning. Filter it (alongside the existing get_event_loop_policy
ignore) so warnings-as-errors doesn't fail the suite until backoff updates.

Refs SLS-265
Addresses Copilot review: the Python support range was changed without
updating the document's Last Updated header.

Refs SLS-265
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