Drop Python 3.9 support

Python 3.9 reached its official End-of-Life (EOL) on October 31, 2025
https://devguide.python.org/versions/

PiperOrigin-RevId: 854341311
This commit is contained in:
Jie Luo 2026-01-09 14:18:02 -08:00 committed by Copybara-Service
parent 0262bd688a
commit bbc9dd9e8a
10 changed files with 26 additions and 107 deletions

View file

@ -28,7 +28,7 @@ jobs:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
type: [ Pure, C++]
version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
include:
- type: Pure
targets: //python/... //python:python_version_test
@ -37,10 +37,6 @@ jobs:
targets: //python/... //python:python_version_test
flags: --define=use_fast_cpp_protos=true
# Test using WORKSPACE with our oldest support Python version.
- version: "3.9"
nobzlmod: true
# Our 3.9 image has non-hermetic issues and can't be rebuilt. Use the old version.
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/python:7.6.1-3.9-12e21b8dda91028bc14212a3ab582c7c4d149fac
- version: "3.10"
- version: "3.11"
continuous-only: true

View file

@ -142,25 +142,21 @@ jobs:
# a single wheel. As a result we can just test the oldest and newest
# supported Python versions and assume this gives us sufficient test
# coverage.
- { os: ubuntu-latest, python-version: "3.9", architecture: x64, type: 'binary' }
- { os: macos-14, python-version: "3.9", architecture: arm64, type: 'binary' }
- { os: ubuntu-latest, python-version: "3.13", architecture: x64, type: 'binary' }
- { os: macos-14, python-version: "3.13", architecture: arm64, type: 'binary' }
- { os: ubuntu-latest, python-version: "3.9", architecture: x64, type: 'source'}
- { os: macos-14, python-version: "3.9", architecture: arm64, type: 'source', continuous-only: true }
- { os: ubuntu-latest, python-version: "3.13", architecture: x64, type: 'source'}
- { os: macos-14, python-version: "3.13", architecture: arm64, type: 'source', continuous-only: true }
- { os: ubuntu-latest, python-version: "3.10", architecture: x64, type: 'binary' }
- { os: macos-14, python-version: "3.10", architecture: arm64, type: 'binary' }
- { os: ubuntu-latest, python-version: "3.14", architecture: x64, type: 'binary' }
- { os: macos-14, python-version: "3.14", architecture: arm64, type: 'binary' }
- { os: ubuntu-latest, python-version: "3.10", architecture: x64, type: 'source'}
- { os: macos-14, python-version: "3.10", architecture: arm64, type: 'source', continuous-only: true }
- { os: ubuntu-latest, python-version: "3.14", architecture: x64, type: 'source', continuous-only: true }
- { os: macos-14, python-version: "3.14", architecture: arm64, type: 'source', continuous-only: true }
# Windows uses the full API up until Python 3.10.
- { os: windows-2022, python-version: "3.9", architecture: x86, type: 'binary', continuous-only: true }
- { os: windows-2022, python-version: "3.10", architecture: x86, type: 'binary', continuous-only: true }
- { os: windows-2022, python-version: "3.11", architecture: x86, type: 'binary', continuous-only: true }
- { os: windows-2022, python-version: "3.12", architecture: x86, type: 'binary', continuous-only: true }
- { os: windows-2022, python-version: "3.13", architecture: x86, type: 'binary', continuous-only: true }
- { os: windows-2022, python-version: "3.14", architecture: x86, type: 'binary', continuous-only: true }
- { os: windows-2022, python-version: "3.9", architecture: x64, type: 'binary' }
- { os: windows-2022, python-version: "3.10", architecture: x64, type: 'binary', continuous-only: true }
- { os: windows-2022, python-version: "3.11", architecture: x64, type: 'binary', continuous-only: true }
- { os: windows-2022, python-version: "3.12", architecture: x64, type: 'binary', continuous-only: true }
@ -237,7 +233,7 @@ jobs:
strategy:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
python-version: ["3.9", "3.13", "3.14"]
python-version: ["3.10", "3.14"] # oldest + newest versions
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request_target' }}
steps:

View file

@ -139,11 +139,11 @@ register_toolchains("//bazel/private/toolchains/prebuilt:all")
register_toolchains("//bazel/private/toolchains:all")
SUPPORTED_PYTHON_VERSIONS = [
"3.9",
"3.10",
"3.11",
"3.12",
"3.13",
"3.14",
]
# TODO: Replace system_python with hermetic_python.
@ -331,18 +331,8 @@ archive_override(
# Python headers for release
python_headers = use_extension("//python/dist:python_downloads.bzl", "python_headers", dev_dependency = True)
python_headers.source_archive(
sha256 = "df796b2dc8ef085edae2597a41c1c0a63625ebd92487adaef2fed22b567873e8",
version = "3.9.0",
)
python_headers.nuget_package(
cpu = "i686",
sha256 = "229abecbe49dc08fe5709e0b31e70edfb3b88f23335ebfc2904c44f940fd59b6",
version = "3.9.0",
)
python_headers.nuget_package(
cpu = "x86-64",
sha256 = "6af58a733e7dfbfcdd50d55788134393d6ffe7ab8270effbf724bdb786558832",
version = "3.9.0",
sha256 = "c4e0cbad57c90690cb813fb4663ef670b4d0f587d8171e2c42bd4c9245bd2758",
version = "3.10.0",
)
python_headers.nuget_package(
cpu = "i686",
@ -357,8 +347,6 @@ python_headers.nuget_package(
use_repo(
python_headers,
"nuget_python_i686_3.10.0",
"nuget_python_i686_3.9.0",
"nuget_python_x86-64_3.10.0",
"nuget_python_x86-64_3.9.0",
"python-3.9.0",
"python-3.10.0",
)

View file

@ -150,7 +150,7 @@ def protobuf_deps():
if not native.existing_rule("system_python"):
system_python(
name = "system_python",
minimum_python_version = "3.9",
minimum_python_version = "3.10",
)
if not native.existing_rule("rules_jvm_external"):
@ -204,18 +204,8 @@ def protobuf_deps():
# Python Downloads
python_source_archive(
version = "3.9.0",
sha256 = "df796b2dc8ef085edae2597a41c1c0a63625ebd92487adaef2fed22b567873e8",
)
python_nuget_package(
version = "3.9.0",
cpu = "i686",
sha256 = "229abecbe49dc08fe5709e0b31e70edfb3b88f23335ebfc2904c44f940fd59b6",
)
python_nuget_package(
version = "3.9.0",
cpu = "x86-64",
sha256 = "6af58a733e7dfbfcdd50d55788134393d6ffe7ab8270effbf724bdb786558832",
version = "3.10.0",
sha256 = "c4e0cbad57c90690cb813fb4663ef670b4d0f587d8171e2c42bd4c9245bd2758",
)
python_nuget_package(
version = "3.10.0",

View file

@ -5,7 +5,6 @@
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
load("@bazel_skylib//lib:selects.bzl", "selects")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "string_flag")
load("//python:build_targets.bzl", "build_targets")
load("//python:py_extension.bzl", "py_extension")
@ -21,7 +20,6 @@ package(
)
LIMITED_API_FLAG_SELECT = {
":limited_api_3.9": ["-DPy_LIMITED_API=0x03090000"],
":limited_api_3.10": ["-DPy_LIMITED_API=0x030a0000"],
"//conditions:default": [],
}
@ -43,39 +41,13 @@ string_flag(
)
config_setting(
name = "limited_api_3.9",
name = "limited_api_3.10",
flag_values = {
":limited_api": "True",
":python_version": "39",
":python_version": "310",
},
)
config_setting(
name = "full_api_3.9_win32",
flag_values = {
":limited_api": "False",
":python_version": "39",
},
values = {"cpu": "win32"},
)
config_setting(
name = "full_api_3.9_win64",
flag_values = {
":limited_api": "False",
":python_version": "39",
},
values = {"cpu": "win64"},
)
selects.config_setting_group(
name = "full_api_3.9",
match_any = [
"full_api_3.9_win32",
":full_api_3.9_win64",
],
)
config_setting(
name = "limited_api_3.10_win32",
flag_values = {
@ -94,14 +66,6 @@ config_setting(
values = {"cpu": "win64"},
)
selects.config_setting_group(
name = "limited_api_3.10",
match_any = [
":limited_api_3.10_win32",
":limited_api_3.10_win64",
],
)
_message_target_compatible_with = {
"@platforms//os:windows": ["@platforms//:incompatible"],
"@system_python//:none": ["@platforms//:incompatible"],

View file

@ -328,7 +328,6 @@ genrule(
py_wheel(
name = "binary_wheel",
abi = select({
"//python:full_api_3.9": "cp39",
"//conditions:default": "abi3",
}),
author = "protobuf@googlegroups.com",
@ -336,7 +335,6 @@ py_wheel(
classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
@ -362,15 +360,13 @@ py_wheel(
":windows_x86_64": "win_amd64",
"//conditions:default": "any",
}),
python_requires = ">=3.9",
python_requires = ">=3.10",
# LINT.IfChange(python_tag)
python_tag = selects.with_or({
("//python:limited_api_3.9", "//python:full_api_3.9"): "cp39",
"//python:limited_api_3.10": "cp310",
"//conditions:default": "cp" + SYSTEM_PYTHON_VERSION,
}),
# LINT.ThenChange(
# :full_api_version,
# :limited_api_wheels,
# )
strip_path_prefixes = [
@ -399,7 +395,6 @@ py_wheel(
classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
@ -413,7 +408,7 @@ py_wheel(
homepage = "https://developers.google.com/protocol-buffers/",
license = "3-Clause BSD License",
platform = "any",
python_requires = ">=3.9",
python_requires = ">=3.10",
python_tag = "py3",
strip_path_prefixes = [
"python/",
@ -466,12 +461,6 @@ py_dist(
"win32",
"win64",
],
# Windows needs version-specific wheels until 3.10.
# LINT.IfChange(full_api_version)
full_api_versions = [
"39",
],
# LINT.ThenChange(:python_tag)
# Limited API: these wheels will satisfy any Python version >= the
# given version.
#
@ -482,10 +471,10 @@ py_dist(
limited_api_wheels = {
"win32": "310",
"win64": "310",
"linux-x86_64": "39",
"linux-aarch_64": "39",
"linux-s390_64": "39",
"osx-universal2": "39",
"linux-x86_64": "310",
"linux-aarch_64": "310",
"linux-s390_64": "310",
"osx-universal2": "310",
},
# LINT.ThenChange(:python_tag)
pure_python_wheel = ":pure_python_wheel",

View file

@ -71,7 +71,6 @@ setup(
classifiers=[
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
@ -89,5 +88,5 @@ setup(
extra_link_args=extra_link_args,
)
],
python_requires='>=3.9',
python_requires='>=3.10',
)

View file

@ -268,7 +268,7 @@ system_python = repository_rule(
implementation = _system_python_impl,
local = True,
attrs = {
"minimum_python_version": attr.string(default = "3.9"),
"minimum_python_version": attr.string(default = "3.10"),
},
)

View file

@ -30,7 +30,6 @@ setup(
# These Python versions should match the protobuf package:
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',

View file

@ -28,9 +28,7 @@ def py_extension(name, srcs, copts, deps = [], **kwargs):
linkshared = True,
linkstatic = True,
deps = deps + select({
"//python:limited_api_3.9": ["@python-3.9.0//:python_headers"],
"//python:full_api_3.9_win32": ["@nuget_python_i686_3.9.0//:python_full_api"],
"//python:full_api_3.9_win64": ["@nuget_python_x86-64_3.9.0//:python_full_api"],
"//python:limited_api_3.10": ["@python-3.10.0//:python_headers"],
"//python:limited_api_3.10_win32": ["@nuget_python_i686_3.10.0//:python_limited_api"],
"//python:limited_api_3.10_win64": ["@nuget_python_x86-64_3.10.0//:python_limited_api"],
"//conditions:default": ["@system_python//:python_headers"],