Skip to content

[#40250] Remove support for Python 3.10 - #40413

Merged
jrmccluskey merged 1 commit into
apache:masterfrom
parvarh26:remove-python-3-10-support-40250
Oct 8, 2026
Merged

jrmccluskey merged 1 commit into
apache:masterfrom
parvarh26:remove-python-3-10-support-40250

Conversation

@parvarh26

Copy link
Copy Markdown
Contributor

Fixes #40250

Motivation & Context

Python 3.10 officially reached End-of-Life (EOL) on October 1, 2026.
Following Apache Beam's established policy of dropping EOL Python runtimes,
this PR removes all support for Python 3.10 and shifts the minimum supported
Python version to 3.11.

This mirrors the pattern established by PR #36665 (Python 3.9 removal).

Changes Made

SDK Core:

  • sdks/python/setup.py: Updated python_requires='>=3.11', removed 3.10
    PyPI classifier, renamed p310_ml_test to p311_ml_test
  • sdks/python/apache_beam/__init__.py: Updated runtime version warning
    threshold to <= 10 (now warns for Python 3.10 and below)
  • sdks/python/pyproject.toml: Updated target-version = "py311" for Ruff/Black

Build & Gradle Infrastructure:

  • gradle.properties: Updated python_versions=3.11,3.12,3.13,3.14
  • sdks/python/build.gradle: Removed 3.10-specific cibuildwheel version
    conditional (unified to 3.4.0)
  • sdks/python/tox.ini: Removed py310 from envlist and all test targets
  • build.gradle.kts (root): Removed py310 PreCommit/PostCommit task blocks;
    migrated integration tests and coverage to py311
  • sdks/python/test-suites/tox/py311/build.gradle: Migrated all dependency
    compatibility tasks from the py310 suite

Dataflow Runner:

  • apiclient.py: Updated _PYTHON_VERSIONS_SUPPORTED_BY_DATAFLOW to
    ['3.11', '3.12', '3.13', '3.14']
  • apiclient_test.py: Updated tests to verify 3.10 is now rejected and 3.11
    is the new minimum accepted version on Dataflow

GitHub Actions CI/CD (~60+ workflow files):

  • All PreCommit workflows: replaced 3.10 matrix entries with 3.11
  • All PostCommit workflows: shifted default pythonVersion to 3.11
  • All LoadTests / PerformanceTests: updated -PpythonVersion=3.11

Documentation:

  • CHANGES.md: Added breaking change entry under [2.78.0] - Unreleased
  • website/.../environments.md: Updated container image tag references to 3.11
  • website/.../python-sdk-image-build.md: Updated SDK container tag listings

Verification

  • Full codebase audit benchmarked against merged PR Remove Python 3.9 support from Apache Beam #36665 (Python 3.9 removal)
  • All critical version gates confirmed updated via git grep
  • Working tree is clean: nothing to commit
  • 113 files changed, 456 insertions(+), 482 deletions(-)

Checklist

  • Mention the appropriate issue in your description (fixes #40250).
  • Update CHANGES.md with noteworthy changes.
  • If this contribution is large, please file an Apache
    Individual Contributor License Agreement.

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Assigning reviewers:

R: @shunping for label python.
R: @damccorm for label build.
R: @shunping for label website.

This pull request likely touches a core component ("core" label). Please review with scrutiny.

Note: If you would like to opt out of this review, comment assign to next reviewer.

Available commands:

  • stop reviewer notifications - opt out of the automated review tooling
  • remind me after tests pass - tag the comment author after tests pass
  • waiting on author - shift the attention set back to the author (any comment or push by the author will return the attention set to the reviewers)

The PR bot will only process comments in the main thread (not review comments).

@damccorm

damccorm commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

R: @jrmccluskey

Could you please take a look?

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Stopping reviewer notifications for this pull request: review requested by someone other than the bot, ceding control. If you'd like to restart, comment assign set of reviewers

@jrmccluskey

Copy link
Copy Markdown
Contributor

R: @jrmccluskey

Could you please take a look?

Ack, just to set expectations this will be reviewed as early as tomorrow

@jrmccluskey
jrmccluskey self-requested a review October 5, 2026 13:44
@shunping

shunping commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator

I'll step back from this review since @jrmccluskey will be handling it. Thanks!

@shunping
shunping removed their request for review October 5, 2026 13:54
@parvarh26
parvarh26 force-pushed the remove-python-3-10-support-40250 branch 2 times, most recently from 8ac3237 to a2f9cb0 Compare October 5, 2026 21:07
@codecov

codecov Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 59.78%. Comparing base (69bdf5f) to head (2e174bf).
⚠️ Report is 56 commits behind head on master.

Files with missing lines Patch % Lines
sdks/python/setup.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master   #40413      +/-   ##
============================================
+ Coverage     59.04%   59.78%   +0.74%     
+ Complexity    15624    13922    -1702     
============================================
  Files          2797     2586     -211     
  Lines        280750   260764   -19986     
  Branches      12488    11243    -1245     
============================================
- Hits         165764   155898    -9866     
+ Misses       108540    98855    -9685     
+ Partials       6446     6011     -435     
Flag Coverage Δ
go 28.35% <ø> (-0.79%) ⬇️
java 65.27% <ø> (-0.17%) ⬇️
python 79.62% <66.66%> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jrmccluskey jrmccluskey left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should also make the changes outlined in #36774

I'm a little nervous about the workflow changes here being untested in the repo (actions configured strictly via the workflow yaml files do not run the new version of the workflow for security reasons.) My main concern is the ML test dependency set, but the others also have the inherent issue of not necessarily being known to be green until merging unless a PR is opened within the Beam repo directly. Verification of local test runs via gradle commands for workflows not requiring secrets would suffice.

Comment on lines +4 to +29
@@ -26,191 +26,4 @@ applyPythonNature()
// Required to setup a Python 3 virtualenv and task names.
pythonVersion = '3.10'

def posargs = project.findProperty("posargs") ?: ""

apply from: "../common.gradle"

toxTask "testPy310CloudCoverage", "py310-cloudcoverage", "${posargs}"
test.dependsOn "testPy310CloudCoverage"
project.tasks.register("preCommitPyCoverage") {
dependsOn = ["testPy310CloudCoverage"]
}

// Dep Postcommit runs test suites that evaluate compatibility of particular
// dependencies. Each suite is exercised on at most one python version.
//
// Should still leave at least one version in PreCommit unless the marked tests
// are also exercised by existing PreCommit
// e.g. pyarrow and pandas also run on PreCommit Dataframe and Coverage
project.tasks.register("postCommitPyDep") {}

// Create a test task for supported major versions of pyarrow.
// Keep in sync with [testenv:py{310,311}-pyarrow-...] in tox.ini
// (versions released in roughly the last 1-2 years).

toxTask "testPy310pyarrow-17", "py310-pyarrow-17", "${posargs}"
test.dependsOn "testPy310pyarrow-17"
postCommitPyDep.dependsOn "testPy310pyarrow-17"

toxTask "testPy310pyarrow-18", "py310-pyarrow-18", "${posargs}"
test.dependsOn "testPy310pyarrow-18"
postCommitPyDep.dependsOn "testPy310pyarrow-18"

toxTask "testPy310pyarrow-19", "py310-pyarrow-19", "${posargs}"
test.dependsOn "testPy310pyarrow-19"
postCommitPyDep.dependsOn "testPy310pyarrow-19"

toxTask "testPy310pyarrow-20", "py310-pyarrow-20", "${posargs}"
test.dependsOn "testPy310pyarrow-20"
postCommitPyDep.dependsOn "testPy310pyarrow-20"

toxTask "testPy310pyarrow-21", "py310-pyarrow-21", "${posargs}"
test.dependsOn "testPy310pyarrow-21"
postCommitPyDep.dependsOn "testPy310pyarrow-21"

toxTask "testPy310pyarrow-22", "py310-pyarrow-22", "${posargs}"
test.dependsOn "testPy310pyarrow-22"
postCommitPyDep.dependsOn "testPy310pyarrow-22"

toxTask "testPy310pyarrow-23", "py310-pyarrow-23", "${posargs}"
test.dependsOn "testPy310pyarrow-23"
postCommitPyDep.dependsOn "testPy310pyarrow-23"

toxTask "testPy310pyarrow-24", "py310-pyarrow-24", "${posargs}"
test.dependsOn "testPy310pyarrow-24"
postCommitPyDep.dependsOn "testPy310pyarrow-24"

toxTask "testPy310pyarrow-25", "py310-pyarrow-25", "${posargs}"
test.dependsOn "testPy310pyarrow-25"
postCommitPyDep.dependsOn "testPy310pyarrow-25"

// Create a test task for each supported minor version of pandas
toxTask "testPy310pandas-14", "py310-pandas-14", "${posargs}"
test.dependsOn "testPy310pandas-14"
postCommitPyDep.dependsOn "testPy310pandas-14"

toxTask "testPy310pandas-15", "py310-pandas-15", "${posargs}"
test.dependsOn "testPy310pandas-15"
postCommitPyDep.dependsOn "testPy310pandas-15"

toxTask "testPy310pandas-20", "py310-pandas-20", "${posargs}"
test.dependsOn "testPy310pandas-20"
postCommitPyDep.dependsOn "testPy310pandas-20"

// TODO(https://github.com/apache/beam/issues/31192): Add below suites
// after dependency compat tests suite switches to Python 3.9 or we add
// Python 2.2 support.

// toxTask "testPy310pandas-21", "py310-pandas-21", "${posargs}"
// test.dependsOn "testPy310pandas-21"
// postCommitPyDep.dependsOn "testPy310pandas-21"

// toxTask "testPy310pandas-22", "py310-pandas-22", "${posargs}"
// test.dependsOn "testPy310pandas-22"
// postCommitPyDep.dependsOn "testPy310pandas-22"

// TODO(https://github.com/apache/beam/issues/30908): Revise what are we testing

// Create a test task for each minor version of pytorch

toxTask "testPy310pytorch-111", "py310-pytorch-111", "${posargs}"
test.dependsOn "testPy310pytorch-111"
postCommitPyDep.dependsOn "testPy310pytorch-111"

toxTask "testPy310pytorch-112", "py310-pytorch-112", "${posargs}"
test.dependsOn "testPy310pytorch-112"
postCommitPyDep.dependsOn "testPy310pytorch-112"

toxTask "testPy310pytorch-113", "py310-pytorch-113", "${posargs}"
test.dependsOn "testPy310pytorch-113"
postCommitPyDep.dependsOn "testPy310pytorch-113"

// run on precommit
toxTask "testPy310pytorch-200", "py310-pytorch-200", "${posargs}"
test.dependsOn "testPy310pytorch-200"
postCommitPyDep.dependsOn "testPy310pytorch-200"

toxTask "testPy310tft-113", "py310-tft-113", "${posargs}"
test.dependsOn "testPy310tft-113"
postCommitPyDep.dependsOn "testPy310tft-113"

// TODO(https://github.com/apache/beam/issues/25796) - uncomment onnx tox task once onnx supports protobuf 4.x.x
// Create a test task for each minor version of onnx
// toxTask "testPy310onnx-113", "py310-onnx-113", "${posargs}"
// test.dependsOn "testPy310onnx-113"
// postCommitPyDep.dependsOn "testPy310onnx-113"

// Create a test task for each minor version of tensorflow
toxTask "testPy310tensorflow-212", "py310-tensorflow-212", "${posargs}"
test.dependsOn "testPy310tensorflow-212"
postCommitPyDep.dependsOn "testPy310tensorflow-212"

// Create a test task for each minor version of transformers
toxTask "testPy310transformers-428", "py310-transformers-428", "${posargs}"
test.dependsOn "testPy310transformers-428"
postCommitPyDep.dependsOn "testPy310transformers-428"

toxTask "testPy310transformers-447", "py310-transformers-447", "${posargs}"
test.dependsOn "testPy310transformers-447"
postCommitPyDep.dependsOn "testPy310transformers-447"

toxTask "testPy310transformers-latest", "py310-transformers-latest", "${posargs}"
test.dependsOn "testPy310transformers-latest"
postCommitPyDep.dependsOn "testPy310transformers-latest"

toxTask "testPy310embeddingsMLTransform", "py310-embeddings", "${posargs}"
test.dependsOn "testPy310embeddingsMLTransform"
postCommitPyDep.dependsOn "testPy310embeddingsMLTransform"

// Part of MLTransform embeddings test suite but requires tensorflow hub, which we need to test on
// mutliple versions so keeping this suite separate.
toxTask "testPy310TensorflowHubEmbeddings-014", "py310-TFHubEmbeddings-014", "${posargs}"
test.dependsOn "testPy310TensorflowHubEmbeddings-014"
postCommitPyDep.dependsOn "testPy310TensorflowHubEmbeddings-014"

toxTask "testPy310TensorflowHubEmbeddings-015", "py310-TFHubEmbeddings-015", "${posargs}"
test.dependsOn "testPy310TensorflowHubEmbeddings-015"
postCommitPyDep.dependsOn "testPy310TensorflowHubEmbeddings-015"

toxTask "whitespacelint", "whitespacelint", "${posargs}"

task archiveFilesToLint(type: Zip) {
archiveFileName = "files-to-whitespacelint.zip"
destinationDirectory = file("$buildDir/dist")

from ("$rootProject.projectDir") {
include "**/*.md"
include "**/build.gradle"
include '**/build.gradle.kts'
exclude '**/build/**' // intermediate build directory
exclude 'website/www/site/themes/docsy/**' // fork to google/docsy
exclude "**/node_modules/*"
exclude "**/.gogradle/*"
}
}

task unpackFilesToLint(type: Copy) {
from zipTree("$buildDir/dist/files-to-whitespacelint.zip")
into "$buildDir/files-to-whitespacelint"
}

whitespacelint.dependsOn archiveFilesToLint, unpackFilesToLint
unpackFilesToLint.dependsOn archiveFilesToLint
archiveFilesToLint.dependsOn cleanPython

toxTask "jest", "jest", "${posargs}"

toxTask "eslint", "eslint", "${posargs}"

task copyTsSource(type: Copy) {
from ("$rootProject.projectDir") {
include "sdks/python/apache_beam/runners/interactive/extensions/**/*"
exclude "sdks/python/apache_beam/runners/interactive/extensions/**/lib/*"
exclude "sdks/python/apache_beam/runners/interactive/extensions/**/node_modules/*"
}
into "$buildDir/ts"
}

jest.dependsOn copyTsSource
eslint.dependsOn copyTsSource
copyTsSource.dependsOn cleanPython
apply from: "../common.gradle" No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This can just be deleted outright, but in a follow-up PR. Leave the configuration here for now so PR checks using the old workflows can still execute properly here

Comment thread sdks/python/setup.py
Comment on lines +608 to 609
'p311_ml_test': [
'datatable',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This isn't particularly useful without an additional run-through evaluating what ML dependencies we can install on 3.11 and test

Comment thread CHANGES.md Outdated
## Breaking Changes

* X behavior was changed ([#X](https://github.com/apache/beam/issues/X)).
* Support for Python 3.10 was removed following its end-of-life ([#40250](https://github.com/apache/beam/issues/40250)).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Slide this down to deprecations

@parvarh26
parvarh26 force-pushed the remove-python-3-10-support-40250 branch from a2f9cb0 to f449812 Compare October 7, 2026 05:58
@parvarh26

Copy link
Copy Markdown
Contributor Author

Hi @jrmccluskey,

Thank you for the thorough review and guidance! I have addressed all requested changes in commit f449812:

  1. Applied Move DataflowRunnerTest.java references to Python 3.10 containers #36774 changes (DataflowRunnerTest.java): Updated the Python SDK harness container override URLs from python3.10 to python3.11 across DataflowRunnerTest.java (testApplySdkEnvironmentOverrides, testApplySdkEnvironmentOverridesByDefault, testApplySdkEnvironmentOverridesRcByDefault).
  2. CHANGES.md: Moved the Python 3.10 EOL removal bullet from ## Breaking Changes down to ## Deprecations.
  3. sdks/python/setup.py: Preserved the existing configuration without introducing unevaluated ML dependency sets.
  4. sdks/python/test-suites/tox/py310/build.gradle: Restored the py310 tasks so existing PR checks using the old workflows can continue to execute cleanly.

Please let me know if anything else needs adjusting!

@jrmccluskey jrmccluskey left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We're also missing the updates in https://github.com/apache/beam/tree/master/.github/actions (see the 3.9 PR for the specific changes.) BeamModulePluginGroovy also needs updates that mirror the old PR, I think that's the root cause of the setupVirtualenv failures on some configured workflows.

@parvarh26

Copy link
Copy Markdown
Contributor Author

Hi @jrmccluskey,

Thank you for pinpointing the exact root cause! I have updated both .github/actions and BeamModulePlugin.groovy mirroring the Python 3.9 deprecation pattern:

  1. buildSrc/.../BeamModulePlugin.groovy:

    • Updated project.ext.pythonVersion default fallback from '3.10' to '3.11'.
    • Updated project.ext.minPythonVersion from 10 to 11.
    • This resolves the setupVirtualenv failures where unconfigured tasks were attempting to invoke python3.10.
  2. .github/actions/setup-environment-action/action.yml:

    • Shifted fallback python-version default from '3.10' to '3.11'.
    • Updated cache key sanitization default from 310 to 311.
  3. .github/actions/setup-default-test-properties/test-properties.json:

    • Shifted LOWEST_SUPPORTED, LOAD_TEST_PYTHON_VERSION, CHICAGO_TAXI_EXAMPLE_FLINK_PYTHON_VERSION, and DEFAULT_INTERPRETER to 3.11 / python3.11.
    • Removed 3.10 across ALL_SUPPORTED_VERSIONS, CROSS_LANGUAGE_VALIDATES_RUNNER_PYTHON_VERSIONS, and VALIDATES_CONTAINER_DATAFLOW_PYTHON_VERSIONS.
  4. .github/workflows/load-tests-pipeline-options/*.txt:

    • Updated container image references across all 24 load test configuration files from beam_python3.10_sdk:latest to beam_python3.11_sdk:latest.

All updates have been bundled into the signed commit 30e4d33 and pushed to the PR branch. Checks are now re-running against the new configuration.

@jrmccluskey

Copy link
Copy Markdown
Contributor

I see that the Python 3.11 ML test suite is actually looking for a p311_ml_test extras configuration, duplicate the p310 definition for now and I will just take an action item forward to audit what can be moved. Ideally the ml_test extras definition would be more universal, but that is a problem to deal with later.

@parvarh26
parvarh26 force-pushed the remove-python-3-10-support-40250 branch from 30e4d33 to 2e174bf Compare October 8, 2026 02:45
@parvarh26

Copy link
Copy Markdown
Contributor Author

Hi @jrmccluskey,

Done! Duplicated the p310_ml_test definition to p311_ml_test in sdks/python/setup.py while keeping both intact.
Pushed the update—thanks for taking the follow-up action item on the ML dependencies!

@jrmccluskey jrmccluskey left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, thank you!

@jrmccluskey
jrmccluskey merged commit debfa0e into apache:master Oct 8, 2026
131 of 133 checks passed
@parvarh26

Copy link
Copy Markdown
Contributor Author

Thank you @jrmccluskey for the review, guidance, and for merging! Really enjoyed working through this with you. Looking forward to contributing more to Beam! 🚀

@parvarh26
parvarh26 deleted the remove-python-3-10-support-40250 branch October 8, 2026 19:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task]: Remove support for Python 3.10

4 participants