From 51c8507731ef1c40c5e736d2047465d219946d8c Mon Sep 17 00:00:00 2001
From: Dev-iL <6509619+Dev-iL@users.noreply.github.com>
Date: Wed, 11 Mar 2026 12:21:40 +0200
Subject: [PATCH 01/26] Update python version exclusion to 3.15
---
airflow-core/pyproject.toml | 11 +++--
airflow-ctl-tests/pyproject.toml | 2 +-
airflow-ctl/pyproject.toml | 9 ++---
airflow-e2e-tests/pyproject.toml | 2 +-
chart/pyproject.toml | 2 +-
clients/python/pyproject.toml | 2 +-
dev/breeze/doc/images/output_run.svg | 20 +++++-----
.../output_testing_core-integration-tests.svg | 20 +++++-----
.../doc/images/output_testing_core-tests.svg | 36 ++++++++---------
.../images/output_testing_providers-tests.svg | 40 +++++++++----------
...output_testing_python-api-client-tests.svg | 16 ++++----
.../images/output_testing_system-tests.svg | 20 +++++-----
dev/breeze/pyproject.toml | 3 +-
dev/pyproject.toml | 2 +-
docker-stack-docs/pyproject.toml | 2 +-
docker-tests/pyproject.toml | 2 +-
helm-tests/pyproject.toml | 2 +-
kubernetes-tests/pyproject.toml | 2 +-
performance/pyproject.toml | 2 +-
providers-summary-docs/pyproject.toml | 2 +-
pyproject.toml | 2 +-
task-sdk-integration-tests/pyproject.toml | 2 +-
task-sdk/pyproject.toml | 8 ++--
23 files changed, 103 insertions(+), 106 deletions(-)
diff --git a/airflow-core/pyproject.toml b/airflow-core/pyproject.toml
index c853c7de833f8..41692d692bee8 100644
--- a/airflow-core/pyproject.toml
+++ b/airflow-core/pyproject.toml
@@ -36,12 +36,11 @@ description = "Core packages for Apache Airflow, schedule and API server"
readme = { file = "README.md", content-type = "text/markdown" }
license = "Apache-2.0"
license-files = ["LICENSE", "NOTICE"]
-# We know that it will take a while before we can support Python 3.14 because of all our dependencies
-# It takes about 4-7 months after Python release before we can support it, so we limit it to <3.14
-# proactively. This way we also have a chance to test it with Python 3.14 and bump the upper binding
-# and manually mark providers that do not support it yet with !-3.14 - until they support it - which will
-# also exclude resolving uv workspace dependencies for those providers.
-requires-python = ">=3.10,!=3.14"
+# Supporting new Python releases typically takes 4-7 months due to all our dependencies.
+# We proactively exclude the next major version to avoid dependency conflicts, then test it and
+# bump the upper binding once ready. Providers that don't support it yet are marked with
+# != constraint - until they support it - which also excludes resolving uv workspace dependencies.
+requires-python = ">=3.10,!=3.15"
authors = [
{ name = "Apache Software Foundation", email = "dev@airflow.apache.org" },
]
diff --git a/airflow-ctl-tests/pyproject.toml b/airflow-ctl-tests/pyproject.toml
index 6f6ccd16424ed..be43fb4cf5c1d 100644
--- a/airflow-ctl-tests/pyproject.toml
+++ b/airflow-ctl-tests/pyproject.toml
@@ -33,7 +33,7 @@ description = "Airflow CTL tests for Apache Airflow"
classifiers = [
"Private :: Do Not Upload",
]
-requires-python = ">=3.10,!=3.14"
+requires-python = ">=3.10,!=3.15"
authors = [
{ name = "Apache Software Foundation", email = "dev@airflow.apache.org" },
]
diff --git a/airflow-ctl/pyproject.toml b/airflow-ctl/pyproject.toml
index fec7206a23092..1fc37efc1668f 100644
--- a/airflow-ctl/pyproject.toml
+++ b/airflow-ctl/pyproject.toml
@@ -22,11 +22,10 @@ description = "Apache Airflow command line tool for communicating with an Apache
readme = { file = "README.md", content-type = "text/markdown" }
license = "Apache-2.0"
license-files = ["LICENSE", "NOTICE"]
-# We do not want to upper-bind Python version, as we do not know if we will support Python 3.14+
-# out-of-the box. Airflow-ctl is a small tool that does not have many dependencies and does not use
-# sophisticated features of Python, so it should work with Python 3.14+ once all it's dependencies are
-# updated to support it.
-requires-python = ">=3.10,!=3.14"
+# We do not want to upper-bind Python version unnecessarily. Airflow-ctl is a small tool with
+# minimal dependencies and does not use sophisticated Python features, so it should work with
+# new Python versions once all dependencies are updated to support them.
+requires-python = ">=3.10,!=3.15"
dependencies = [
# TODO there could be still missing deps such as airflow-core
"argcomplete>=1.10",
diff --git a/airflow-e2e-tests/pyproject.toml b/airflow-e2e-tests/pyproject.toml
index 20cc5bcad55c6..882a6e176f914 100644
--- a/airflow-e2e-tests/pyproject.toml
+++ b/airflow-e2e-tests/pyproject.toml
@@ -32,7 +32,7 @@ description = "E2E tests for Apache Airflow"
classifiers = [
"Private :: Do Not Upload",
]
-requires-python = ">=3.10,!=3.14"
+requires-python = ">=3.10,!=3.15"
authors = [
{ name = "Apache Software Foundation", email = "dev@airflow.apache.org" },
]
diff --git a/chart/pyproject.toml b/chart/pyproject.toml
index f8d2eed8bbabc..165b37ff86089 100644
--- a/chart/pyproject.toml
+++ b/chart/pyproject.toml
@@ -29,7 +29,7 @@ build-backend = "hatchling.build"
[project]
name = "apache-airflow-helm-chart"
description = "Programmatically author, schedule and monitor data pipelines"
-requires-python = ">=3.10,!=3.14"
+requires-python = ">=3.10,!=3.15"
authors = [
{ name = "Apache Software Foundation", email = "dev@airflow.apache.org" },
]
diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml
index 628f36e13d66f..b75d01f6aeb63 100644
--- a/clients/python/pyproject.toml
+++ b/clients/python/pyproject.toml
@@ -33,7 +33,7 @@ description = "Apache Airflow API (Stable)"
readme = "README.md"
license = "Apache-2.0"
license-files = ["LICENSE", "NOTICE"]
-requires-python = ">=3.10,!=3.14"
+requires-python = ">=3.10,!=3.15"
authors = [
{ name = "Apache Software Foundation", email = "dev@airflow.apache.org" },
]
diff --git a/dev/breeze/doc/images/output_run.svg b/dev/breeze/doc/images/output_run.svg
index d317e3f6ab0c4..7d29c0b125923 100644
--- a/dev/breeze/doc/images/output_run.svg
+++ b/dev/breeze/doc/images/output_run.svg
@@ -206,7 +206,7 @@
Run a command in the Breeze environment without entering the interactive shell.
-┌─ Command execution ──────────────────────────────────────────────────────────────────────────────────────────────────┐
+╭─ Command execution ──────────────────────────────────────────────────────────────────────────────────────────────────╮
│--python -pPython major/minor version used in Airflow image for images. [default: 3.10](>3.10< | 3.11 │
│| 3.12 | 3.13)│
│--backend -bDatabase backend to use. Default is 'sqlite'. If 'none' is chosen, Breeze will start with an│
@@ -224,32 +224,32 @@
│--forward-ports Forward ports to host (for accessing Airflow UI/API from host machine).│
│--tty Whether to allocate pseudo-tty when running docker command (useful for prek and CI to │
│force-enable it). [default: auto](auto | enabled | disabled)│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Build CI image (before running command) ────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Build CI image (before running command) ────────────────────────────────────────────────────────────────────────────╮
│--force-build Force image build no matter if it is determined as needed.│
│--platform Platform for Airflow image. (linux/amd64 | linux/arm64 | linux/x86_64 | linux/aarch64)│
│--github-repository -gGitHub repository used to pull, push run images. [default: apache/airflow](TEXT)│
│--builder Buildx builder used to perform `docker buildx build` commands. [default: autodetect]│
│(TEXT)│
│--use-uv/--no-use-uvUse uv instead of pip as packaging tool to build the image. [default: use-uv]│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Docker Compose project management ──────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Docker Compose project management ──────────────────────────────────────────────────────────────────────────────────╮
│--project-nameName of the docker-compose project to bring down. The `docker-compose` is for legacy breeze project │
│name and you can use `breeze down --project-name docker-compose` to stop all containers belonging to│
│it. [default: breeze](breeze | prek | docker-compose)│
│--docker-host Optional - docker host to use when running docker commands. When set, the `--builder` option is │
│ignored when building images. (TEXT)│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Other options ──────────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Other options ──────────────────────────────────────────────────────────────────────────────────────────────────────╮
│--forward-credentials -fForward local credentials to container when running.│
│--skip-image-upgrade-checkSkip checking if the CI image is up to date.│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────╮
│--answer -aForce answer to questions. (y | n | q | yes | no | quit)│
│--dry-run-DIf dry-run is set, commands are only printed, not executed.│
│--verbose-vPrint verbose information about performed steps.│
│--help -hShow this message and exit.│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
diff --git a/dev/breeze/doc/images/output_testing_core-integration-tests.svg b/dev/breeze/doc/images/output_testing_core-integration-tests.svg
index 7d7005cd5b4fd..48b02e8905b32 100644
--- a/dev/breeze/doc/images/output_testing_core-integration-tests.svg
+++ b/dev/breeze/doc/images/output_testing_core-integration-tests.svg
@@ -218,14 +218,14 @@
Run the specified integration tests.
-┌─ Test options ───────────────────────────────────────────────────────────────────────────────────────────────────────┐
+╭─ Test options ───────────────────────────────────────────────────────────────────────────────────────────────────────╮
│--test-timeout Test timeout in seconds. Set the pytest setup, execution and teardown timeouts to this│
│value [default: 60](INTEGER RANGE x>=0)│
│--enable-coverage Enable coverage capturing for tests in the form of XML files│
│--collect-only Collect tests only, do not run them.│
│--db-reset/--no-db-reset-dReset DB when entering the container. [default: no-db-reset]│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Test environment ───────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Test environment ───────────────────────────────────────────────────────────────────────────────────────────────────╮
│--backend -bDatabase backend to use. Default is 'sqlite'. If 'none' is chosen, │
│Breeze will start with an invalid database configuration — no │
│database will be available, and any attempt to run Airflow will │
@@ -248,24 +248,24 @@
│--forward-credentials -fForward local credentials to container when running.│
│--force-sa-warnings/--no-force-sa-warningsEnable `sqlalchemy.exc.MovedIn20Warning` during the tests runs. │
│[default: force-sa-warnings]│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Integration tests ──────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Integration tests ──────────────────────────────────────────────────────────────────────────────────────────────────╮
│--integrationCore Integrations to enable when running (can be more than one). (all | all-testable | kerberos | │
│keycloak | otel | redis | statsd)│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Advanced flag for tests command ────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Advanced flag for tests command ────────────────────────────────────────────────────────────────────────────────────╮
│--github-repository -gGitHub repository used to pull, push run images. [default: apache/airflow](TEXT)│
│--mount-sources Choose scope of local sources that should be mounted, skipped, or removed (default =│
│selected). [default: selected](selected | all | skip | remove | tests | │
│providers-and-tests)│
│--skip-docker-compose-downSkips running docker-compose down after tests│
│--keep-env-variables Do not clear environment variables that might have side effect while running tests│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────╮
│--dry-run-DIf dry-run is set, commands are only printed, not executed.│
│--verbose-vPrint verbose information about performed steps.│
│--help -hShow this message and exit.│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
diff --git a/dev/breeze/doc/images/output_testing_core-tests.svg b/dev/breeze/doc/images/output_testing_core-tests.svg
index 85fff03630191..36b6c897d2156 100644
--- a/dev/breeze/doc/images/output_testing_core-tests.svg
+++ b/dev/breeze/doc/images/output_testing_core-tests.svg
@@ -389,7 +389,7 @@
Run all (default) or specified core unit tests.
-┌─ Select test types to run (tests can also be selected by command args individually) ─────────────────────────────────┐
+╭─ Select test types to run (tests can also be selected by command args individually) ─────────────────────────────────╮
│--test-type Type of tests to run for core test group [default: All](All | All-Long | │
│All-Quarantined | All-Postgres | All-MySQL | API | Always | CLI | Core | Other | │
│Serialization)│
@@ -398,19 +398,19 @@
│Serialization)│
│--excluded-parallel-test-typesSpace separated list of core test types that will be excluded from parallel tes │
│runs. [default: ""](API | Always | CLI | Core | Other | Serialization)│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Test options ───────────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Test options ───────────────────────────────────────────────────────────────────────────────────────────────────────╮
│--test-timeout Test timeout in seconds. Set the pytest setup, execution and teardown timeouts to this│
│value [default: 60](INTEGER RANGE x>=0)│
│--enable-coverage Enable coverage capturing for tests in the form of XML files│
│--collect-only Collect tests only, do not run them.│
│--db-reset/--no-db-reset-dReset DB when entering the container. [default: no-db-reset]│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Selectively run DB or non-DB tests ─────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Selectively run DB or non-DB tests ─────────────────────────────────────────────────────────────────────────────────╮
│--run-db-tests-onlyOnly runs tests that require a database│
│--skip-db-tests Skip tests that require a database│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Test environment ───────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Test environment ───────────────────────────────────────────────────────────────────────────────────────────────────╮
│--backend -bDatabase backend to use. Default is 'sqlite'. If 'none' is chosen, │
│Breeze will start with an invalid database configuration — no │
│database will be available, and any attempt to run Airflow will │
@@ -433,8 +433,8 @@
│--forward-credentials -fForward local credentials to container when running.│
│--force-sa-warnings/--no-force-sa-warningsEnable `sqlalchemy.exc.MovedIn20Warning` during the tests runs. │
│[default: force-sa-warnings]│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Options for parallel test commands ─────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Options for parallel test commands ─────────────────────────────────────────────────────────────────────────────────╮
│--run-in-parallel Run the operation in parallel on all or selected subset of parameters.│
│--use-xdist Use xdist plugin for pytest│
│--parallelism Maximum number of processes to use while running the operation in parallel. [default: 4]│
@@ -445,22 +445,22 @@
│--total-test-timeout Total test timeout in seconds. This is the maximum time parallel tests will run. If there│
│is an underlying pytest command that hangs, the process will be stop with system exit │
│after that time. This should give a chance to upload logs as artifacts on CI. (INTEGER)│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Upgrading/downgrading/removing selected packages ───────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Upgrading/downgrading/removing selected packages ───────────────────────────────────────────────────────────────────╮
│--upgrade-boto Remove aiobotocore and upgrade botocore and boto to the latest version.│
│--upgrade-sqlalchemy Upgrade SQLAlchemy to the latest version.│
│--downgrade-sqlalchemyDowngrade SQLAlchemy to minimum supported version.│
│--downgrade-pendulum Downgrade Pendulum to minimum supported version.│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Advanced flag for tests command ────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Advanced flag for tests command ────────────────────────────────────────────────────────────────────────────────────╮
│--github-repository -gGitHub repository used to pull, push run images. [default: apache/airflow](TEXT)│
│--mount-sources Choose scope of local sources that should be mounted, skipped, or removed (default =│
│selected). [default: selected](selected | all | skip | remove | tests | │
│providers-and-tests)│
│--skip-docker-compose-downSkips running docker-compose down after tests│
│--keep-env-variables Do not clear environment variables that might have side effect while running tests│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Advanced flag for installing airflow in container ──────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Advanced flag for installing airflow in container ──────────────────────────────────────────────────────────────────╮
│--airflow-constraints-reference Constraint reference to use for airflow installation │
│(used in calculated constraints URL). (TEXT)│
│--clean-airflow-installation Clean the airflow installation before installing version │
@@ -488,12 +488,12 @@
│pre-release --use-airflow-version) │
│--use-distributions-from-dist Install all found distributions (--distribution-format│
│determines type) from 'dist' folder when entering breeze.│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────╮
│--dry-run-DIf dry-run is set, commands are only printed, not executed.│
│--verbose-vPrint verbose information about performed steps.│
│--help -hShow this message and exit.│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
diff --git a/dev/breeze/doc/images/output_testing_providers-tests.svg b/dev/breeze/doc/images/output_testing_providers-tests.svg
index 66a36f2cb8bdc..640602d550a9b 100644
--- a/dev/breeze/doc/images/output_testing_providers-tests.svg
+++ b/dev/breeze/doc/images/output_testing_providers-tests.svg
@@ -416,7 +416,7 @@
Run all (default) or specified Providers unit tests.
-┌─ Select test types to run (tests can also be selected by command args individually) ─────────────────────────────────┐
+╭─ Select test types to run (tests can also be selected by command args individually) ─────────────────────────────────╮
│--test-type Type of test to run. You can also optionally specify tests of which providers should│
│be run: `Providers[airbyte,http]` or excluded from the full test suite: │
│`Providers[-amazon,google]` [default: All](All | All-Long | All-Quarantined | │
@@ -426,19 +426,19 @@
│`Providers[airbyte,http]`. (TEXT)│
│--excluded-parallel-test-typesSpace separated list of provider test types that will be excluded from parallel tes │
│runs. You can for example `Providers[airbyte,http]`. (TEXT)│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Test options ───────────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Test options ───────────────────────────────────────────────────────────────────────────────────────────────────────╮
│--test-timeout Test timeout in seconds. Set the pytest setup, execution and teardown timeouts to this│
│value [default: 60](INTEGER RANGE x>=0)│
│--enable-coverage Enable coverage capturing for tests in the form of XML files│
│--collect-only Collect tests only, do not run them.│
│--db-reset/--no-db-reset-dReset DB when entering the container. [default: no-db-reset]│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Selectively run DB or non-DB tests ─────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Selectively run DB or non-DB tests ─────────────────────────────────────────────────────────────────────────────────╮
│--run-db-tests-onlyOnly runs tests that require a database│
│--skip-db-tests Skip tests that require a database│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Test environment ───────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Test environment ───────────────────────────────────────────────────────────────────────────────────────────────────╮
│--backend -bDatabase backend to use. Default is 'sqlite'. If 'none' is chosen, │
│Breeze will start with an invalid database configuration — no │
│database will be available, and any attempt to run Airflow will │
@@ -461,8 +461,8 @@
│--forward-credentials -fForward local credentials to container when running.│
│--force-sa-warnings/--no-force-sa-warningsEnable `sqlalchemy.exc.MovedIn20Warning` during the tests runs. │
│[default: force-sa-warnings]│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Options for parallel test commands ─────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Options for parallel test commands ─────────────────────────────────────────────────────────────────────────────────╮
│--run-in-parallel Run the operation in parallel on all or selected subset of parameters.│
│--use-xdist Use xdist plugin for pytest│
│--parallelism Maximum number of processes to use while running the operation in parallel. [default: 4]│
@@ -473,22 +473,22 @@
│--total-test-timeout Total test timeout in seconds. This is the maximum time parallel tests will run. If there│
│is an underlying pytest command that hangs, the process will be stop with system exit │
│after that time. This should give a chance to upload logs as artifacts on CI. (INTEGER)│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Upgrading/downgrading/removing selected packages ───────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Upgrading/downgrading/removing selected packages ───────────────────────────────────────────────────────────────────╮
│--upgrade-boto Remove aiobotocore and upgrade botocore and boto to the latest version.│
│--upgrade-sqlalchemy Upgrade SQLAlchemy to the latest version.│
│--downgrade-sqlalchemyDowngrade SQLAlchemy to minimum supported version.│
│--downgrade-pendulum Downgrade Pendulum to minimum supported version.│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Advanced flag for tests command ────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Advanced flag for tests command ────────────────────────────────────────────────────────────────────────────────────╮
│--github-repository -gGitHub repository used to pull, push run images. [default: apache/airflow](TEXT)│
│--mount-sources Choose scope of local sources that should be mounted, skipped, or removed (default =│
│selected). [default: selected](selected | all | skip | remove | tests | │
│providers-and-tests)│
│--skip-docker-compose-downSkips running docker-compose down after tests│
│--keep-env-variables Do not clear environment variables that might have side effect while running tests│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Advanced flag for installing airflow in container ──────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Advanced flag for installing airflow in container ──────────────────────────────────────────────────────────────────╮
│--airflow-constraints-reference Constraint reference to use for airflow installation │
│(used in calculated constraints URL). (TEXT)│
│--clean-airflow-installation Clean the airflow installation before installing version │
@@ -516,20 +516,20 @@
│pre-release --use-airflow-version) │
│--use-distributions-from-dist Install all found distributions (--distribution-format│
│determines type) from 'dist' folder when entering breeze.│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Advanced flag for provider tests command ───────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Advanced flag for provider tests command ───────────────────────────────────────────────────────────────────────────╮
│--excluded-providers JSON-string of dictionary containing excluded providers per python version │
│({'3.12': ['provider']}) (TEXT)│
│--providers-constraints-locationLocation of providers constraints to use (remote URL or local context file). │
│(TEXT)│
│--providers-skip-constraints Do not use constraints when installing providers.│
│--skip-providers Space-separated list of provider ids to skip when running tests (TEXT)│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────╮
│--dry-run-DIf dry-run is set, commands are only printed, not executed.│
│--verbose-vPrint verbose information about performed steps.│
│--help -hShow this message and exit.│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
diff --git a/dev/breeze/doc/images/output_testing_python-api-client-tests.svg b/dev/breeze/doc/images/output_testing_python-api-client-tests.svg
index b1d556ee8943e..036b8b3ded46d 100644
--- a/dev/breeze/doc/images/output_testing_python-api-client-tests.svg
+++ b/dev/breeze/doc/images/output_testing_python-api-client-tests.svg
@@ -197,19 +197,19 @@
Run python api client tests.
-┌─ Advanced flag for tests command ────────────────────────────────────────────────────────────────────────────────────┐
+╭─ Advanced flag for tests command ────────────────────────────────────────────────────────────────────────────────────╮
│--github-repository -gGitHub repository used to pull, push run images. [default: apache/airflow](TEXT)│
│--skip-docker-compose-downSkips running docker-compose down after tests│
│--keep-env-variables Do not clear environment variables that might have side effect while running tests│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Test options ───────────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Test options ───────────────────────────────────────────────────────────────────────────────────────────────────────╮
│--test-timeout Test timeout in seconds. Set the pytest setup, execution and teardown timeouts to this│
│value [default: 60](INTEGER RANGE x>=0)│
│--enable-coverage Enable coverage capturing for tests in the form of XML files│
│--collect-only Collect tests only, do not run them.│
│--db-reset/--no-db-reset-dReset DB when entering the container. [default: no-db-reset]│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Test environment ───────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Test environment ───────────────────────────────────────────────────────────────────────────────────────────────────╮
│--backend -bDatabase backend to use. Default is 'sqlite'. If 'none' is chosen, │
│Breeze will start with an invalid database configuration — no │
│database will be available, and any attempt to run Airflow will │
@@ -232,12 +232,12 @@
│--forward-credentials -fForward local credentials to container when running.│
│--force-sa-warnings/--no-force-sa-warningsEnable `sqlalchemy.exc.MovedIn20Warning` during the tests runs. │
│[default: force-sa-warnings]│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────╮
│--dry-run-DIf dry-run is set, commands are only printed, not executed.│
│--verbose-vPrint verbose information about performed steps.│
│--help -hShow this message and exit.│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
diff --git a/dev/breeze/doc/images/output_testing_system-tests.svg b/dev/breeze/doc/images/output_testing_system-tests.svg
index 47a4640eea52c..0458695ef0367 100644
--- a/dev/breeze/doc/images/output_testing_system-tests.svg
+++ b/dev/breeze/doc/images/output_testing_system-tests.svg
@@ -293,14 +293,14 @@
Run the specified system tests.
-┌─ Test options ───────────────────────────────────────────────────────────────────────────────────────────────────────┐
+╭─ Test options ───────────────────────────────────────────────────────────────────────────────────────────────────────╮
│--test-timeout Test timeout in seconds. Set the pytest setup, execution and teardown timeouts to this│
│value [default: 60](INTEGER RANGE x>=0)│
│--enable-coverage Enable coverage capturing for tests in the form of XML files│
│--collect-only Collect tests only, do not run them.│
│--db-reset/--no-db-reset-dReset DB when entering the container. [default: no-db-reset]│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Test environment ───────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Test environment ───────────────────────────────────────────────────────────────────────────────────────────────────╮
│--backend -bDatabase backend to use. Default is 'sqlite'. If 'none' is chosen, │
│Breeze will start with an invalid database configuration — no │
│database will be available, and any attempt to run Airflow will │
@@ -323,16 +323,16 @@
│--forward-credentials -fForward local credentials to container when running.│
│--force-sa-warnings/--no-force-sa-warningsEnable `sqlalchemy.exc.MovedIn20Warning` during the tests runs. │
│[default: force-sa-warnings]│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Advanced flag for tests command ────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Advanced flag for tests command ────────────────────────────────────────────────────────────────────────────────────╮
│--github-repository -gGitHub repository used to pull, push run images. [default: apache/airflow](TEXT)│
│--mount-sources Choose scope of local sources that should be mounted, skipped, or removed (default =│
│selected). [default: selected](selected | all | skip | remove | tests | │
│providers-and-tests)│
│--skip-docker-compose-downSkips running docker-compose down after tests│
│--keep-env-variables Do not clear environment variables that might have side effect while running tests│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Advanced flag for installing airflow in container ──────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Advanced flag for installing airflow in container ──────────────────────────────────────────────────────────────────╮
│--airflow-constraints-reference Constraint reference to use for airflow installation │
│(used in calculated constraints URL). (TEXT)│
│--clean-airflow-installation Clean the airflow installation before installing version │
@@ -360,12 +360,12 @@
│pre-release --use-airflow-version) │
│--use-distributions-from-dist Install all found distributions (--distribution-format│
│determines type) from 'dist' folder when entering breeze.│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-┌─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────┐
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+╭─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────╮
│--dry-run-DIf dry-run is set, commands are only printed, not executed.│
│--verbose-vPrint verbose information about performed steps.│
│--help -hShow this message and exit.│
-└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
diff --git a/dev/breeze/pyproject.toml b/dev/breeze/pyproject.toml
index fe101e7313346..6dbec94bd767d 100644
--- a/dev/breeze/pyproject.toml
+++ b/dev/breeze/pyproject.toml
@@ -39,8 +39,9 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
]
-requires-python = ">=3.10,!=3.14"
+requires-python = ">=3.10,!=3.15"
dependencies = [
"black>=26.1.0",
diff --git a/dev/pyproject.toml b/dev/pyproject.toml
index 2424c37c34ffa..bf800439604ab 100644
--- a/dev/pyproject.toml
+++ b/dev/pyproject.toml
@@ -33,7 +33,7 @@ description = "Development tools for Apache Airflow"
classifiers = [
"Private :: Do Not Upload",
]
-requires-python = ">=3.10,!=3.14"
+requires-python = ">=3.10,!=3.15"
authors = [
{ name = "Apache Software Foundation", email = "dev@airflow.apache.org" },
]
diff --git a/docker-stack-docs/pyproject.toml b/docker-stack-docs/pyproject.toml
index 33b5189a0397d..44b23765ae047 100644
--- a/docker-stack-docs/pyproject.toml
+++ b/docker-stack-docs/pyproject.toml
@@ -29,7 +29,7 @@ build-backend = "hatchling.build"
[project]
name = "docker-stack"
description = "Programmatically author, schedule and monitor data pipelines"
-requires-python = ">=3.10,!=3.14"
+requires-python = ">=3.10,!=3.15"
authors = [
{ name = "Apache Software Foundation", email = "dev@airflow.apache.org" },
]
diff --git a/docker-tests/pyproject.toml b/docker-tests/pyproject.toml
index 4c40c7644fde4..ee1ca5779e652 100644
--- a/docker-tests/pyproject.toml
+++ b/docker-tests/pyproject.toml
@@ -33,7 +33,7 @@ description = "Docker tests for Apache Airflow"
classifiers = [
"Private :: Do Not Upload",
]
-requires-python = ">=3.10,!=3.14"
+requires-python = ">=3.10,!=3.15"
authors = [
{ name = "Apache Software Foundation", email = "dev@airflow.apache.org" },
]
diff --git a/helm-tests/pyproject.toml b/helm-tests/pyproject.toml
index 65629fbe69123..1802e5c57cfa3 100644
--- a/helm-tests/pyproject.toml
+++ b/helm-tests/pyproject.toml
@@ -33,7 +33,7 @@ description = "Helm tests for Apache Airflow"
classifiers = [
"Private :: Do Not Upload",
]
-requires-python = ">=3.10,!=3.14"
+requires-python = ">=3.10,!=3.15"
authors = [
{ name = "Apache Software Foundation", email = "dev@airflow.apache.org" },
]
diff --git a/kubernetes-tests/pyproject.toml b/kubernetes-tests/pyproject.toml
index 2ed8a9b4c73aa..22b680d91bd9e 100644
--- a/kubernetes-tests/pyproject.toml
+++ b/kubernetes-tests/pyproject.toml
@@ -31,7 +31,7 @@ description = "Kubernetes tests for Apache Airflow"
classifiers = [
"Private :: Do Not Upload",
]
-requires-python = ">=3.10,!=3.14"
+requires-python = ">=3.10,!=3.15"
authors = [
{ name = "Apache Software Foundation", email = "dev@airflow.apache.org" },
]
diff --git a/performance/pyproject.toml b/performance/pyproject.toml
index 35a3e0846b3b4..f8f58af4c230f 100644
--- a/performance/pyproject.toml
+++ b/performance/pyproject.toml
@@ -21,7 +21,7 @@ build-backend = "flit_core.buildapi"
[project]
name = "apache-airflow-performance"
version = "0.1.0"
-requires-python = ">=3.10,!=3.14"
+requires-python = ">=3.10,!=3.15"
description = "Performance testing utilities and DAGs for Apache Airflow"
readme = { file = "README.md", content-type = "text/markdown" }
license = "Apache-2.0"
diff --git a/providers-summary-docs/pyproject.toml b/providers-summary-docs/pyproject.toml
index 4725370279a45..16145b4462577 100644
--- a/providers-summary-docs/pyproject.toml
+++ b/providers-summary-docs/pyproject.toml
@@ -29,7 +29,7 @@ build-backend = "hatchling.build"
[project]
name = "apache-airflow-providers"
description = "Programmatically author, schedule and monitor data pipelines"
-requires-python = ">=3.10,!=3.14"
+requires-python = ">=3.10,!=3.15"
authors = [
{ name = "Apache Software Foundation", email = "dev@airflow.apache.org" },
]
diff --git a/pyproject.toml b/pyproject.toml
index b4a5b024cf63e..270b339844325 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -32,7 +32,7 @@ description = "Programmatically author, schedule and monitor data pipelines"
readme = { file = "generated/PYPI_README.md", content-type = "text/markdown" }
license = "Apache-2.0"
license-files = ["LICENSE", "NOTICE"]
-requires-python = ">=3.10,!=3.14"
+requires-python = ">=3.10,!=3.15"
authors = [
{ name = "Apache Software Foundation", email = "dev@airflow.apache.org" },
]
diff --git a/task-sdk-integration-tests/pyproject.toml b/task-sdk-integration-tests/pyproject.toml
index d743e095cad01..cf0966bc08d63 100644
--- a/task-sdk-integration-tests/pyproject.toml
+++ b/task-sdk-integration-tests/pyproject.toml
@@ -33,7 +33,7 @@ description = "Task SDK integration tests for Apache Airflow"
classifiers = [
"Private :: Do Not Upload",
]
-requires-python = ">=3.10,!=3.14"
+requires-python = ">=3.10,!=3.15"
authors = [
{ name = "Apache Software Foundation", email = "dev@airflow.apache.org" },
]
diff --git a/task-sdk/pyproject.toml b/task-sdk/pyproject.toml
index bd0382b9a899c..4cc0f15c09726 100644
--- a/task-sdk/pyproject.toml
+++ b/task-sdk/pyproject.toml
@@ -22,11 +22,9 @@ description = "Python Task SDK for Apache Airflow DAG Authors"
readme = { file = "README.md", content-type = "text/markdown" }
license = "Apache-2.0"
license-files = ["LICENSE", "NOTICE"]
-# We know that it will take a while before we can support Python 3.14 because of all our dependencies
-# in all our providers - and usually it will take a while before we can support it for majority of
-# providers, so we proactively limit it to <3.14.
-# It takes about 4-7 months after Python release before we can support it
-requires-python = ">=3.10,!=3.14"
+# Supporting new Python releases typically takes 4-7 months due to all our provider dependencies.
+# We proactively limit the version to allow time for all dependencies to update.
+requires-python = ">=3.10,!=3.15"
authors = [
{name="Apache Software Foundation", email="dev@airflow.apache.org"},
From 4d64fb294cfd14730d44cf6ee038ce477151535f Mon Sep 17 00:00:00 2001
From: Dev-iL <6509619+Dev-iL@users.noreply.github.com>
Date: Wed, 11 Mar 2026 13:11:53 +0200
Subject: [PATCH 02/26] Add 3.14 metadata version classifiers and related
constants
---
airflow-core/docs/installation/prerequisites.rst | 2 +-
airflow-core/pyproject.toml | 1 +
airflow-core/src/airflow/typing_compat.py | 1 +
airflow-ctl/docs/installation/prerequisites.rst | 4 ++--
chart/pyproject.toml | 1 +
clients/python/pyproject.toml | 1 +
dev/breeze/src/airflow_breeze/global_constants.py | 12 +++++++++---
docker-stack-docs/pyproject.toml | 1 +
providers-summary-docs/pyproject.toml | 1 +
providers/airbyte/pyproject.toml | 1 +
providers/alibaba/pyproject.toml | 1 +
providers/amazon/pyproject.toml | 1 +
providers/apache/beam/pyproject.toml | 1 +
providers/apache/cassandra/pyproject.toml | 1 +
providers/apache/drill/pyproject.toml | 1 +
providers/apache/druid/pyproject.toml | 1 +
providers/apache/flink/pyproject.toml | 1 +
providers/apache/hdfs/pyproject.toml | 1 +
providers/apache/hive/pyproject.toml | 1 +
providers/apache/iceberg/pyproject.toml | 1 +
providers/apache/impala/pyproject.toml | 1 +
providers/apache/kafka/pyproject.toml | 1 +
providers/apache/kylin/pyproject.toml | 1 +
providers/apache/livy/pyproject.toml | 1 +
providers/apache/pig/pyproject.toml | 1 +
providers/apache/pinot/pyproject.toml | 1 +
providers/apache/spark/pyproject.toml | 1 +
providers/apache/tinkerpop/pyproject.toml | 1 +
providers/apprise/pyproject.toml | 1 +
providers/arangodb/pyproject.toml | 1 +
providers/asana/pyproject.toml | 1 +
providers/atlassian/jira/pyproject.toml | 1 +
providers/celery/pyproject.toml | 1 +
providers/cloudant/pyproject.toml | 1 +
providers/cncf/kubernetes/pyproject.toml | 1 +
providers/cohere/pyproject.toml | 1 +
providers/common/ai/pyproject.toml | 1 +
providers/common/compat/pyproject.toml | 1 +
providers/common/io/pyproject.toml | 1 +
providers/common/messaging/pyproject.toml | 1 +
providers/common/sql/pyproject.toml | 1 +
providers/databricks/pyproject.toml | 1 +
providers/datadog/pyproject.toml | 1 +
providers/dbt/cloud/pyproject.toml | 1 +
providers/dingding/pyproject.toml | 1 +
providers/discord/pyproject.toml | 1 +
providers/docker/pyproject.toml | 1 +
providers/edge3/pyproject.toml | 1 +
providers/elasticsearch/pyproject.toml | 1 +
providers/exasol/pyproject.toml | 1 +
providers/fab/pyproject.toml | 1 +
providers/facebook/pyproject.toml | 1 +
providers/ftp/pyproject.toml | 1 +
providers/git/pyproject.toml | 1 +
providers/github/pyproject.toml | 1 +
providers/google/pyproject.toml | 1 +
providers/grpc/pyproject.toml | 1 +
providers/hashicorp/pyproject.toml | 1 +
providers/http/pyproject.toml | 1 +
providers/imap/pyproject.toml | 1 +
providers/influxdb/pyproject.toml | 1 +
providers/informatica/pyproject.toml | 1 +
providers/jdbc/pyproject.toml | 1 +
providers/jenkins/pyproject.toml | 1 +
providers/keycloak/pyproject.toml | 1 +
providers/microsoft/azure/pyproject.toml | 1 +
providers/microsoft/mssql/pyproject.toml | 1 +
providers/microsoft/psrp/pyproject.toml | 1 +
providers/microsoft/winrm/pyproject.toml | 1 +
providers/mongo/pyproject.toml | 1 +
providers/mysql/pyproject.toml | 1 +
providers/neo4j/pyproject.toml | 1 +
providers/odbc/pyproject.toml | 1 +
providers/openai/pyproject.toml | 1 +
providers/openfaas/pyproject.toml | 1 +
providers/openlineage/pyproject.toml | 1 +
providers/opensearch/pyproject.toml | 1 +
providers/opsgenie/pyproject.toml | 1 +
providers/oracle/pyproject.toml | 1 +
providers/pagerduty/pyproject.toml | 1 +
providers/papermill/pyproject.toml | 1 +
providers/pgvector/pyproject.toml | 1 +
providers/pinecone/pyproject.toml | 1 +
providers/postgres/pyproject.toml | 1 +
providers/presto/pyproject.toml | 1 +
providers/qdrant/pyproject.toml | 1 +
providers/redis/pyproject.toml | 1 +
providers/salesforce/pyproject.toml | 1 +
providers/samba/pyproject.toml | 1 +
providers/segment/pyproject.toml | 1 +
providers/sendgrid/pyproject.toml | 1 +
providers/sftp/pyproject.toml | 1 +
providers/singularity/pyproject.toml | 1 +
providers/slack/pyproject.toml | 1 +
providers/smtp/pyproject.toml | 1 +
providers/snowflake/pyproject.toml | 1 +
providers/sqlite/pyproject.toml | 1 +
providers/ssh/pyproject.toml | 1 +
providers/standard/pyproject.toml | 1 +
providers/tableau/pyproject.toml | 1 +
providers/telegram/pyproject.toml | 1 +
providers/teradata/pyproject.toml | 1 +
providers/trino/pyproject.toml | 1 +
providers/vertica/pyproject.toml | 1 +
providers/weaviate/pyproject.toml | 1 +
providers/yandex/pyproject.toml | 1 +
providers/ydb/pyproject.toml | 1 +
providers/zendesk/pyproject.toml | 1 +
pyproject.toml | 1 +
.../ci/testing/get_min_airflow_version_for_python.py | 2 +-
.../test_get_min_airflow_version_for_python.py | 4 ++--
task-sdk/pyproject.toml | 1 +
112 files changed, 122 insertions(+), 9 deletions(-)
diff --git a/airflow-core/docs/installation/prerequisites.rst b/airflow-core/docs/installation/prerequisites.rst
index 17dd6a2e7e6d1..359450d3eeb09 100644
--- a/airflow-core/docs/installation/prerequisites.rst
+++ b/airflow-core/docs/installation/prerequisites.rst
@@ -20,7 +20,7 @@ Prerequisites
Airflow® is tested with:
-* Python: 3.10, 3.11, 3.12, 3.13
+* Python: 3.10, 3.11, 3.12, 3.13, 3.14
* Databases:
diff --git a/airflow-core/pyproject.toml b/airflow-core/pyproject.toml
index 41692d692bee8..d184d67347186 100644
--- a/airflow-core/pyproject.toml
+++ b/airflow-core/pyproject.toml
@@ -59,6 +59,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
diff --git a/airflow-core/src/airflow/typing_compat.py b/airflow-core/src/airflow/typing_compat.py
index 31b6e6ecaa5a0..1f9fd0b217f12 100644
--- a/airflow-core/src/airflow/typing_compat.py
+++ b/airflow-core/src/airflow/typing_compat.py
@@ -29,4 +29,5 @@
if sys.version_info >= (3, 11):
from typing import Self, Unpack, assert_never
else:
+ # TODO: Remove once Python 3.10 support is dropped (EOL 2026)
from typing_extensions import Self, Unpack, assert_never
diff --git a/airflow-ctl/docs/installation/prerequisites.rst b/airflow-ctl/docs/installation/prerequisites.rst
index b01ff4c3cc41b..9d2efa3641c06 100644
--- a/airflow-ctl/docs/installation/prerequisites.rst
+++ b/airflow-ctl/docs/installation/prerequisites.rst
@@ -69,8 +69,6 @@ use cases. Simply install them to make them available:
Python Version Compatibility
----------------------------
``airflowctl`` is compatible with versions of Python 3.10 through Python 3.14.
-Currently, Python 3.14 is not supported. Thanks for your understanding!
-We will work on adding support for Python 3.14.
.. list-table::
:widths: 15 85
@@ -87,4 +85,6 @@ We will work on adding support for Python 3.14.
* - 3.13
- Yes
* - 3.14
+ - Yes
+ * - 3.15
- No
diff --git a/chart/pyproject.toml b/chart/pyproject.toml
index 165b37ff86089..fc903a8c070ee 100644
--- a/chart/pyproject.toml
+++ b/chart/pyproject.toml
@@ -48,6 +48,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
"Topic :: System :: Monitoring",
]
diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml
index b75d01f6aeb63..36d4fc8db1d69 100644
--- a/clients/python/pyproject.toml
+++ b/clients/python/pyproject.toml
@@ -53,6 +53,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
diff --git a/dev/breeze/src/airflow_breeze/global_constants.py b/dev/breeze/src/airflow_breeze/global_constants.py
index 1a02b7a0d6906..1b6fb1d4668e1 100644
--- a/dev/breeze/src/airflow_breeze/global_constants.py
+++ b/dev/breeze/src/airflow_breeze/global_constants.py
@@ -49,7 +49,7 @@
APACHE_AIRFLOW_GITHUB_REPOSITORY = "apache/airflow"
# Checked before putting in build cache
-ALLOWED_PYTHON_MAJOR_MINOR_VERSIONS = ["3.10", "3.11", "3.12", "3.13"]
+ALLOWED_PYTHON_MAJOR_MINOR_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14"]
DEFAULT_PYTHON_MAJOR_MINOR_VERSION = ALLOWED_PYTHON_MAJOR_MINOR_VERSIONS[0]
DEFAULT_PYTHON_MAJOR_MINOR_VERSION_FOR_IMAGES = ALLOWED_PYTHON_MAJOR_MINOR_VERSIONS[0]
@@ -441,7 +441,7 @@ def all_ctl_test_packages() -> list[str]:
ALLOWED_USE_AIRFLOW_VERSIONS = ["none", "wheel", "sdist"]
-ALL_HISTORICAL_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
+ALL_HISTORICAL_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
GITHUB_REPO_BRANCH_PATTERN = r"^([^/]+)/([^/:]+):([^:]+)$"
PR_NUMBER_PATTERN = r"^\d+$"
@@ -492,7 +492,7 @@ def get_default_platform_machine() -> str:
# All python versions include all past python versions available in previous branches
# Even if we remove them from the main version. This is needed to make sure we can cherry-pick
# changes from main to the previous branch.
-ALL_PYTHON_MAJOR_MINOR_VERSIONS = ["3.10", "3.11", "3.12", "3.13"]
+ALL_PYTHON_MAJOR_MINOR_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14"]
CURRENT_PYTHON_MAJOR_MINOR_VERSIONS = ALL_PYTHON_MAJOR_MINOR_VERSIONS
# All versions we can run against (Need to include versions for main branch and the current release branch)
ALLOWED_POSTGRES_VERSIONS = ["13", "14", "15", "16", "17", "18"]
@@ -513,6 +513,8 @@ def get_default_platform_machine() -> str:
PYTHON_3_8_TO_3_11 = ["3.8", "3.9", "3.10", "3.11"]
PYTHON_3_8_TO_3_12 = ["3.8", "3.9", "3.10", "3.11", "3.12"]
PYTHON_3_9_TO_3_12 = ["3.9", "3.10", "3.11", "3.12"]
+PYTHON_3_10_TO_3_13 = ["3.10", "3.11", "3.12", "3.13"]
+PYTHON_3_10_TO_3_14 = ["3.10", "3.11", "3.12", "3.13", "3.14"]
AIRFLOW_PYTHON_COMPATIBILITY_MATRIX = {
@@ -566,6 +568,9 @@ def get_default_platform_machine() -> str:
"2.10.4": PYTHON_3_8_TO_3_12,
"2.10.5": PYTHON_3_8_TO_3_12,
"2.11.0": PYTHON_3_9_TO_3_12,
+ "3.0.0": PYTHON_3_9_TO_3_12,
+ "3.1.0": PYTHON_3_10_TO_3_13,
+ "3.2.0": PYTHON_3_10_TO_3_14,
}
DB_RESET = False
@@ -819,6 +824,7 @@ def get_airflow_extras():
"3.11": "3.11.15",
"3.12": "3.12.13",
"3.13": "3.13.12",
+ "3.14": "3.14.3",
}
# Number of slices for low dep tests
diff --git a/docker-stack-docs/pyproject.toml b/docker-stack-docs/pyproject.toml
index 44b23765ae047..5bbfe5891adee 100644
--- a/docker-stack-docs/pyproject.toml
+++ b/docker-stack-docs/pyproject.toml
@@ -48,6 +48,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
"Topic :: System :: Monitoring",
]
diff --git a/providers-summary-docs/pyproject.toml b/providers-summary-docs/pyproject.toml
index 16145b4462577..65a55b60823e7 100644
--- a/providers-summary-docs/pyproject.toml
+++ b/providers-summary-docs/pyproject.toml
@@ -48,6 +48,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
diff --git a/providers/airbyte/pyproject.toml b/providers/airbyte/pyproject.toml
index 073cec5b5c2f9..529c322636b9f 100644
--- a/providers/airbyte/pyproject.toml
+++ b/providers/airbyte/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/alibaba/pyproject.toml b/providers/alibaba/pyproject.toml
index dfb918523f45c..7eca192bb32c9 100644
--- a/providers/alibaba/pyproject.toml
+++ b/providers/alibaba/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/amazon/pyproject.toml b/providers/amazon/pyproject.toml
index b478343e297fc..13327be2971f1 100644
--- a/providers/amazon/pyproject.toml
+++ b/providers/amazon/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/beam/pyproject.toml b/providers/apache/beam/pyproject.toml
index a4483508aa5f0..4f63f43f09e11 100644
--- a/providers/apache/beam/pyproject.toml
+++ b/providers/apache/beam/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/cassandra/pyproject.toml b/providers/apache/cassandra/pyproject.toml
index 0d216ae9ecf05..43dc076e2c4c8 100644
--- a/providers/apache/cassandra/pyproject.toml
+++ b/providers/apache/cassandra/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/drill/pyproject.toml b/providers/apache/drill/pyproject.toml
index 5dbf926d88736..debcde47de347 100644
--- a/providers/apache/drill/pyproject.toml
+++ b/providers/apache/drill/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/druid/pyproject.toml b/providers/apache/druid/pyproject.toml
index 2c1147e1c3b51..56c2ed8d8de5c 100644
--- a/providers/apache/druid/pyproject.toml
+++ b/providers/apache/druid/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/flink/pyproject.toml b/providers/apache/flink/pyproject.toml
index f625f12bf5513..f79ea56df3086 100644
--- a/providers/apache/flink/pyproject.toml
+++ b/providers/apache/flink/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/hdfs/pyproject.toml b/providers/apache/hdfs/pyproject.toml
index 423cd0bba6775..55a50b1d5d503 100644
--- a/providers/apache/hdfs/pyproject.toml
+++ b/providers/apache/hdfs/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/hive/pyproject.toml b/providers/apache/hive/pyproject.toml
index d6aa77652c821..907ead716b823 100644
--- a/providers/apache/hive/pyproject.toml
+++ b/providers/apache/hive/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/iceberg/pyproject.toml b/providers/apache/iceberg/pyproject.toml
index 9535cebdcbea4..07050e8a6bcfa 100644
--- a/providers/apache/iceberg/pyproject.toml
+++ b/providers/apache/iceberg/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/impala/pyproject.toml b/providers/apache/impala/pyproject.toml
index 472cd66c84b02..49f16ea3dc77f 100644
--- a/providers/apache/impala/pyproject.toml
+++ b/providers/apache/impala/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/kafka/pyproject.toml b/providers/apache/kafka/pyproject.toml
index 20fd34ac1c4bf..7a2e20966a98c 100644
--- a/providers/apache/kafka/pyproject.toml
+++ b/providers/apache/kafka/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/kylin/pyproject.toml b/providers/apache/kylin/pyproject.toml
index 7948de0d5bd9c..0205db7cad2e8 100644
--- a/providers/apache/kylin/pyproject.toml
+++ b/providers/apache/kylin/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/livy/pyproject.toml b/providers/apache/livy/pyproject.toml
index 9a013b15034b8..25765cd066784 100644
--- a/providers/apache/livy/pyproject.toml
+++ b/providers/apache/livy/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/pig/pyproject.toml b/providers/apache/pig/pyproject.toml
index 3d690cf86b5bf..f5d1297844e22 100644
--- a/providers/apache/pig/pyproject.toml
+++ b/providers/apache/pig/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/pinot/pyproject.toml b/providers/apache/pinot/pyproject.toml
index 3554e6f815fb1..cc41e68c8446f 100644
--- a/providers/apache/pinot/pyproject.toml
+++ b/providers/apache/pinot/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/spark/pyproject.toml b/providers/apache/spark/pyproject.toml
index 5fdb1bddfaaa7..3936e2c46f457 100644
--- a/providers/apache/spark/pyproject.toml
+++ b/providers/apache/spark/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apache/tinkerpop/pyproject.toml b/providers/apache/tinkerpop/pyproject.toml
index 718e3f730fb75..a90322b500d05 100644
--- a/providers/apache/tinkerpop/pyproject.toml
+++ b/providers/apache/tinkerpop/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/apprise/pyproject.toml b/providers/apprise/pyproject.toml
index 885d0b4578059..8c6e2ac50e0d9 100644
--- a/providers/apprise/pyproject.toml
+++ b/providers/apprise/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/arangodb/pyproject.toml b/providers/arangodb/pyproject.toml
index 5d8ba7558c341..af98480e2a997 100644
--- a/providers/arangodb/pyproject.toml
+++ b/providers/arangodb/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/asana/pyproject.toml b/providers/asana/pyproject.toml
index ddcc1a5ecd045..d270c3bdf2408 100644
--- a/providers/asana/pyproject.toml
+++ b/providers/asana/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/atlassian/jira/pyproject.toml b/providers/atlassian/jira/pyproject.toml
index 2ac4ce548efa0..165f655eb6baf 100644
--- a/providers/atlassian/jira/pyproject.toml
+++ b/providers/atlassian/jira/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/celery/pyproject.toml b/providers/celery/pyproject.toml
index 19f1e6e45eb95..5a3d361917b36 100644
--- a/providers/celery/pyproject.toml
+++ b/providers/celery/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/cloudant/pyproject.toml b/providers/cloudant/pyproject.toml
index 13dda7f612fe6..34e23244353c5 100644
--- a/providers/cloudant/pyproject.toml
+++ b/providers/cloudant/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/cncf/kubernetes/pyproject.toml b/providers/cncf/kubernetes/pyproject.toml
index f5a37c64be4c2..aacb53988b89a 100644
--- a/providers/cncf/kubernetes/pyproject.toml
+++ b/providers/cncf/kubernetes/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/cohere/pyproject.toml b/providers/cohere/pyproject.toml
index b311a5c8b4e56..218c99df092f5 100644
--- a/providers/cohere/pyproject.toml
+++ b/providers/cohere/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/common/ai/pyproject.toml b/providers/common/ai/pyproject.toml
index 6e1cbe50f56df..203497e401dd3 100644
--- a/providers/common/ai/pyproject.toml
+++ b/providers/common/ai/pyproject.toml
@@ -56,6 +56,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/common/compat/pyproject.toml b/providers/common/compat/pyproject.toml
index a4b0eaf10463c..007283651ab3f 100644
--- a/providers/common/compat/pyproject.toml
+++ b/providers/common/compat/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/common/io/pyproject.toml b/providers/common/io/pyproject.toml
index 52dbfd6f97c54..93d3f221c267d 100644
--- a/providers/common/io/pyproject.toml
+++ b/providers/common/io/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/common/messaging/pyproject.toml b/providers/common/messaging/pyproject.toml
index 16bd83b89bba1..0ad007eb90c10 100644
--- a/providers/common/messaging/pyproject.toml
+++ b/providers/common/messaging/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/common/sql/pyproject.toml b/providers/common/sql/pyproject.toml
index a08c1ac3fd2db..715fe3b77a0cf 100644
--- a/providers/common/sql/pyproject.toml
+++ b/providers/common/sql/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/databricks/pyproject.toml b/providers/databricks/pyproject.toml
index a755ba6b5803e..a58c321b6ecf0 100644
--- a/providers/databricks/pyproject.toml
+++ b/providers/databricks/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/datadog/pyproject.toml b/providers/datadog/pyproject.toml
index 56c5b1673ddda..ee05ad91d45d6 100644
--- a/providers/datadog/pyproject.toml
+++ b/providers/datadog/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/dbt/cloud/pyproject.toml b/providers/dbt/cloud/pyproject.toml
index 78fc7a1569357..f73ec29cdc758 100644
--- a/providers/dbt/cloud/pyproject.toml
+++ b/providers/dbt/cloud/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/dingding/pyproject.toml b/providers/dingding/pyproject.toml
index 2b55fe3133b87..f3c8ef43453cd 100644
--- a/providers/dingding/pyproject.toml
+++ b/providers/dingding/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/discord/pyproject.toml b/providers/discord/pyproject.toml
index 2f531c5454fa7..ecf5fcab12c26 100644
--- a/providers/discord/pyproject.toml
+++ b/providers/discord/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/docker/pyproject.toml b/providers/docker/pyproject.toml
index 187c51df8c737..0ee53bc5f1bec 100644
--- a/providers/docker/pyproject.toml
+++ b/providers/docker/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/edge3/pyproject.toml b/providers/edge3/pyproject.toml
index 2b234b8c2440c..defc6eed03f33 100644
--- a/providers/edge3/pyproject.toml
+++ b/providers/edge3/pyproject.toml
@@ -56,6 +56,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/elasticsearch/pyproject.toml b/providers/elasticsearch/pyproject.toml
index fa502cc07dc97..cbfb6576ade9b 100644
--- a/providers/elasticsearch/pyproject.toml
+++ b/providers/elasticsearch/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/exasol/pyproject.toml b/providers/exasol/pyproject.toml
index aeaf39e8fb514..97a43e08d3f6d 100644
--- a/providers/exasol/pyproject.toml
+++ b/providers/exasol/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/fab/pyproject.toml b/providers/fab/pyproject.toml
index 11a4bada9c063..e85153f5e77fe 100644
--- a/providers/fab/pyproject.toml
+++ b/providers/fab/pyproject.toml
@@ -56,6 +56,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/facebook/pyproject.toml b/providers/facebook/pyproject.toml
index 6405c2e7bb83e..23117738e4449 100644
--- a/providers/facebook/pyproject.toml
+++ b/providers/facebook/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/ftp/pyproject.toml b/providers/ftp/pyproject.toml
index e36fa2e914cd6..db5dc98704abf 100644
--- a/providers/ftp/pyproject.toml
+++ b/providers/ftp/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/git/pyproject.toml b/providers/git/pyproject.toml
index d4ea3afdab30f..a4de69b39e072 100644
--- a/providers/git/pyproject.toml
+++ b/providers/git/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/github/pyproject.toml b/providers/github/pyproject.toml
index 501a5da8a665c..f52e6c8dd744e 100644
--- a/providers/github/pyproject.toml
+++ b/providers/github/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/google/pyproject.toml b/providers/google/pyproject.toml
index 3159b4ce712e2..18ec71decaf85 100644
--- a/providers/google/pyproject.toml
+++ b/providers/google/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/grpc/pyproject.toml b/providers/grpc/pyproject.toml
index 702de427a8f60..86f05b6c104c3 100644
--- a/providers/grpc/pyproject.toml
+++ b/providers/grpc/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/hashicorp/pyproject.toml b/providers/hashicorp/pyproject.toml
index dc20d0e6e5c49..5b97367c20467 100644
--- a/providers/hashicorp/pyproject.toml
+++ b/providers/hashicorp/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/http/pyproject.toml b/providers/http/pyproject.toml
index 0260e850eb4bf..0cf6f5a424e1b 100644
--- a/providers/http/pyproject.toml
+++ b/providers/http/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/imap/pyproject.toml b/providers/imap/pyproject.toml
index ca6397edb2c73..86bb20fbd7803 100644
--- a/providers/imap/pyproject.toml
+++ b/providers/imap/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/influxdb/pyproject.toml b/providers/influxdb/pyproject.toml
index 0cbd71d03188e..1536a7e3cf14e 100644
--- a/providers/influxdb/pyproject.toml
+++ b/providers/influxdb/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/informatica/pyproject.toml b/providers/informatica/pyproject.toml
index 63602b3dfd2ae..1d1c9d2b1cf49 100644
--- a/providers/informatica/pyproject.toml
+++ b/providers/informatica/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/jdbc/pyproject.toml b/providers/jdbc/pyproject.toml
index 3217d510a91f7..52af0df250c72 100644
--- a/providers/jdbc/pyproject.toml
+++ b/providers/jdbc/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/jenkins/pyproject.toml b/providers/jenkins/pyproject.toml
index e3dd747fa6a64..f584367218ac8 100644
--- a/providers/jenkins/pyproject.toml
+++ b/providers/jenkins/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/keycloak/pyproject.toml b/providers/keycloak/pyproject.toml
index 4e666b5ac6c0e..56a709bf6addf 100644
--- a/providers/keycloak/pyproject.toml
+++ b/providers/keycloak/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/microsoft/azure/pyproject.toml b/providers/microsoft/azure/pyproject.toml
index 37f5021c84cc2..c98b5e4ed5d00 100644
--- a/providers/microsoft/azure/pyproject.toml
+++ b/providers/microsoft/azure/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/microsoft/mssql/pyproject.toml b/providers/microsoft/mssql/pyproject.toml
index df7fd82483ab4..ceb6f21d94cd8 100644
--- a/providers/microsoft/mssql/pyproject.toml
+++ b/providers/microsoft/mssql/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/microsoft/psrp/pyproject.toml b/providers/microsoft/psrp/pyproject.toml
index 4f9d07f32fa3a..ff5619b65c2ab 100644
--- a/providers/microsoft/psrp/pyproject.toml
+++ b/providers/microsoft/psrp/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/microsoft/winrm/pyproject.toml b/providers/microsoft/winrm/pyproject.toml
index e0efa272e09fc..b39a575c5db1d 100644
--- a/providers/microsoft/winrm/pyproject.toml
+++ b/providers/microsoft/winrm/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/mongo/pyproject.toml b/providers/mongo/pyproject.toml
index 1949f0f7a6002..f7b044d4355ba 100644
--- a/providers/mongo/pyproject.toml
+++ b/providers/mongo/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/mysql/pyproject.toml b/providers/mysql/pyproject.toml
index 60655b5c01049..0aa75c7fa2526 100644
--- a/providers/mysql/pyproject.toml
+++ b/providers/mysql/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/neo4j/pyproject.toml b/providers/neo4j/pyproject.toml
index 7292daac7a582..4eaa887d0a17d 100644
--- a/providers/neo4j/pyproject.toml
+++ b/providers/neo4j/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/odbc/pyproject.toml b/providers/odbc/pyproject.toml
index 8e3f0fcc71658..1e241dfcb6c0c 100644
--- a/providers/odbc/pyproject.toml
+++ b/providers/odbc/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/openai/pyproject.toml b/providers/openai/pyproject.toml
index 45796c89ddcef..a24bab2746f68 100644
--- a/providers/openai/pyproject.toml
+++ b/providers/openai/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/openfaas/pyproject.toml b/providers/openfaas/pyproject.toml
index 362c73714720f..81c5233a3f955 100644
--- a/providers/openfaas/pyproject.toml
+++ b/providers/openfaas/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/openlineage/pyproject.toml b/providers/openlineage/pyproject.toml
index 890dc5fc37766..9b073162cde61 100644
--- a/providers/openlineage/pyproject.toml
+++ b/providers/openlineage/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/opensearch/pyproject.toml b/providers/opensearch/pyproject.toml
index e35b21ae58f7b..6cf4a15d5057b 100644
--- a/providers/opensearch/pyproject.toml
+++ b/providers/opensearch/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/opsgenie/pyproject.toml b/providers/opsgenie/pyproject.toml
index de136fedf0cca..492b0206f71ab 100644
--- a/providers/opsgenie/pyproject.toml
+++ b/providers/opsgenie/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/oracle/pyproject.toml b/providers/oracle/pyproject.toml
index 82f1ea783b025..47aaff1845a23 100644
--- a/providers/oracle/pyproject.toml
+++ b/providers/oracle/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/pagerduty/pyproject.toml b/providers/pagerduty/pyproject.toml
index 9fa324f1d38e8..e953834437347 100644
--- a/providers/pagerduty/pyproject.toml
+++ b/providers/pagerduty/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/papermill/pyproject.toml b/providers/papermill/pyproject.toml
index 41f86e12964a4..21cdcae71efe7 100644
--- a/providers/papermill/pyproject.toml
+++ b/providers/papermill/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/pgvector/pyproject.toml b/providers/pgvector/pyproject.toml
index 71785b11b5082..f314af93a8baf 100644
--- a/providers/pgvector/pyproject.toml
+++ b/providers/pgvector/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/pinecone/pyproject.toml b/providers/pinecone/pyproject.toml
index df055f3a774be..e424699785fb4 100644
--- a/providers/pinecone/pyproject.toml
+++ b/providers/pinecone/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/postgres/pyproject.toml b/providers/postgres/pyproject.toml
index 922aa70c68db2..8db04c9bc90dd 100644
--- a/providers/postgres/pyproject.toml
+++ b/providers/postgres/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/presto/pyproject.toml b/providers/presto/pyproject.toml
index 55884872563b4..cadf0d84be2aa 100644
--- a/providers/presto/pyproject.toml
+++ b/providers/presto/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/qdrant/pyproject.toml b/providers/qdrant/pyproject.toml
index 3e52bc9a32683..fc4320f126686 100644
--- a/providers/qdrant/pyproject.toml
+++ b/providers/qdrant/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/redis/pyproject.toml b/providers/redis/pyproject.toml
index d6c3bd46ec499..ce61ba09b7f89 100644
--- a/providers/redis/pyproject.toml
+++ b/providers/redis/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/salesforce/pyproject.toml b/providers/salesforce/pyproject.toml
index 8af3ace68e2a1..49bfc2514d5c9 100644
--- a/providers/salesforce/pyproject.toml
+++ b/providers/salesforce/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/samba/pyproject.toml b/providers/samba/pyproject.toml
index 0cb09047b7b06..40f1db8d3a6a9 100644
--- a/providers/samba/pyproject.toml
+++ b/providers/samba/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/segment/pyproject.toml b/providers/segment/pyproject.toml
index f758ba0fc6f5d..a9b4b266f5694 100644
--- a/providers/segment/pyproject.toml
+++ b/providers/segment/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/sendgrid/pyproject.toml b/providers/sendgrid/pyproject.toml
index 75a1211d55294..6b104fc2ba31e 100644
--- a/providers/sendgrid/pyproject.toml
+++ b/providers/sendgrid/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/sftp/pyproject.toml b/providers/sftp/pyproject.toml
index 0b5094b8a2e2e..b54428fcc7e9f 100644
--- a/providers/sftp/pyproject.toml
+++ b/providers/sftp/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/singularity/pyproject.toml b/providers/singularity/pyproject.toml
index f9a0bb94b6b0d..453b3ec511e47 100644
--- a/providers/singularity/pyproject.toml
+++ b/providers/singularity/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/slack/pyproject.toml b/providers/slack/pyproject.toml
index 3092429744fda..2ac852c245175 100644
--- a/providers/slack/pyproject.toml
+++ b/providers/slack/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/smtp/pyproject.toml b/providers/smtp/pyproject.toml
index d8dbc9532d712..3197c12e95829 100644
--- a/providers/smtp/pyproject.toml
+++ b/providers/smtp/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/snowflake/pyproject.toml b/providers/snowflake/pyproject.toml
index 167941cc564b9..b3a8d85e5d5f5 100644
--- a/providers/snowflake/pyproject.toml
+++ b/providers/snowflake/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/sqlite/pyproject.toml b/providers/sqlite/pyproject.toml
index 6b9863c70b995..03b32e2a66221 100644
--- a/providers/sqlite/pyproject.toml
+++ b/providers/sqlite/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/ssh/pyproject.toml b/providers/ssh/pyproject.toml
index 753ca8e48171a..b5559b7d1dd03 100644
--- a/providers/ssh/pyproject.toml
+++ b/providers/ssh/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/standard/pyproject.toml b/providers/standard/pyproject.toml
index 0b20194009ebd..8a54de4aaaab3 100644
--- a/providers/standard/pyproject.toml
+++ b/providers/standard/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/tableau/pyproject.toml b/providers/tableau/pyproject.toml
index 3542eb1486178..98ff8ff248966 100644
--- a/providers/tableau/pyproject.toml
+++ b/providers/tableau/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/telegram/pyproject.toml b/providers/telegram/pyproject.toml
index fd453d3c74117..6e09cef7875cc 100644
--- a/providers/telegram/pyproject.toml
+++ b/providers/telegram/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/teradata/pyproject.toml b/providers/teradata/pyproject.toml
index fbb30e05367f6..b59bbcba790c6 100644
--- a/providers/teradata/pyproject.toml
+++ b/providers/teradata/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/trino/pyproject.toml b/providers/trino/pyproject.toml
index fbf5aeeb806d2..d1bef23f7adb3 100644
--- a/providers/trino/pyproject.toml
+++ b/providers/trino/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/vertica/pyproject.toml b/providers/vertica/pyproject.toml
index d5c7bf6e69a66..68a9bb7d1ea22 100644
--- a/providers/vertica/pyproject.toml
+++ b/providers/vertica/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/weaviate/pyproject.toml b/providers/weaviate/pyproject.toml
index 3d82964308dcc..9233e75c59ab5 100644
--- a/providers/weaviate/pyproject.toml
+++ b/providers/weaviate/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/yandex/pyproject.toml b/providers/yandex/pyproject.toml
index fc54c98c19559..a571727d2bd10 100644
--- a/providers/yandex/pyproject.toml
+++ b/providers/yandex/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/ydb/pyproject.toml b/providers/ydb/pyproject.toml
index 51ae7654ac05b..1a22ba4e630dc 100644
--- a/providers/ydb/pyproject.toml
+++ b/providers/ydb/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/providers/zendesk/pyproject.toml b/providers/zendesk/pyproject.toml
index 7396bc5a80dbe..923ff944bc023 100644
--- a/providers/zendesk/pyproject.toml
+++ b/providers/zendesk/pyproject.toml
@@ -49,6 +49,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
requires-python = ">=3.10"
diff --git a/pyproject.toml b/pyproject.toml
index 270b339844325..8edb60e7f6533 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -51,6 +51,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
diff --git a/scripts/ci/testing/get_min_airflow_version_for_python.py b/scripts/ci/testing/get_min_airflow_version_for_python.py
index ae404935c7d97..02fc844db43d3 100644
--- a/scripts/ci/testing/get_min_airflow_version_for_python.py
+++ b/scripts/ci/testing/get_min_airflow_version_for_python.py
@@ -21,7 +21,7 @@
MIN_AIRFLOW_VERSION_BY_PYTHON = {
"3.10": "2.11.0",
"3.13": "3.1.0",
- # "3.14": "3.2.0",
+ "3.14": "3.2.0",
}
diff --git a/scripts/tests/ci/testing/test_get_min_airflow_version_for_python.py b/scripts/tests/ci/testing/test_get_min_airflow_version_for_python.py
index 4b7d1429182d5..b6f9bf239ddb8 100644
--- a/scripts/tests/ci/testing/test_get_min_airflow_version_for_python.py
+++ b/scripts/tests/ci/testing/test_get_min_airflow_version_for_python.py
@@ -49,8 +49,8 @@ def min_airflow_module():
("3.10", "2.11.0"),
("3.12", "2.11.0"),
("3.13", "3.1.0"),
- ("3.14", "3.1.0"),
- ("3.15", "3.1.0"),
+ ("3.14", "3.2.0"),
+ ("3.15", "3.2.0"),
],
)
def test_get_min_airflow_version_for_python_is_monotonic(
diff --git a/task-sdk/pyproject.toml b/task-sdk/pyproject.toml
index 4cc0f15c09726..697e2774b3c4a 100644
--- a/task-sdk/pyproject.toml
+++ b/task-sdk/pyproject.toml
@@ -44,6 +44,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: System :: Monitoring",
]
dependencies = [
From ad94588ee01c37b700b5613866c990a295cbf7dd Mon Sep 17 00:00:00 2001
From: Dev-iL <6509619+Dev-iL@users.noreply.github.com>
Date: Fri, 13 Mar 2026 14:50:52 +0200
Subject: [PATCH 03/26] Assorted workarounds to fix breeze image building
- constraints are skipped entirely
- greenlet pin updated
---
Dockerfile.ci | 11 ++++++++++-
airflow-core/pyproject.toml | 6 ++++--
airflow-core/tests/unit/always/test_example_dags.py | 3 +++
.../unit/api_fastapi/common/test_http_access_log.py | 2 +-
dev/breeze/tests/test_selective_checks.py | 7 ++++++-
providers/apache/cassandra/docs/index.rst | 3 ++-
providers/apache/cassandra/pyproject.toml | 3 ++-
scripts/docker/common.sh | 10 +++++++++-
scripts/pyproject.toml | 3 ++-
9 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/Dockerfile.ci b/Dockerfile.ci
index 5d86908a01467..1ecc1f00b7045 100644
--- a/Dockerfile.ci
+++ b/Dockerfile.ci
@@ -750,7 +750,15 @@ function common::get_constraints_location() {
echo
echo "${COLOR_BLUE}Downloading constraints from ${AIRFLOW_CONSTRAINTS_LOCATION} to ${HOME}/constraints.txt ${COLOR_RESET}"
echo
- curl -sSf -o "${HOME}/constraints.txt" "${AIRFLOW_CONSTRAINTS_LOCATION}"
+ if ! curl -sSf -o "${HOME}/constraints.txt" "${AIRFLOW_CONSTRAINTS_LOCATION}"; then
+ echo
+ echo "${COLOR_YELLOW}Constraints file not found at ${AIRFLOW_CONSTRAINTS_LOCATION} (new Python version being bootstrapped?).${COLOR_RESET}"
+ echo "${COLOR_YELLOW}Falling back to no-constraints installation.${COLOR_RESET}"
+ echo
+ AIRFLOW_CONSTRAINTS_LOCATION=""
+ # Create an empty constraints file so --constraint flag still works
+ touch "${HOME}/constraints.txt"
+ fi
else
echo
echo "${COLOR_BLUE}Copying constraints from ${AIRFLOW_CONSTRAINTS_LOCATION} to ${HOME}/constraints.txt ${COLOR_RESET}"
@@ -1729,6 +1737,7 @@ ENV AIRFLOW_REPO=${AIRFLOW_REPO}\
AIRFLOW_VERSION_SPECIFICATION="" \
PIP_PROGRESS_BAR=${PIP_PROGRESS_BAR} \
ADDITIONAL_PIP_INSTALL_FLAGS=${ADDITIONAL_PIP_INSTALL_FLAGS} \
+ INCLUDE_PRE_RELEASE="true" \
CASS_DRIVER_BUILD_CONCURRENCY=${CASS_DRIVER_BUILD_CONCURRENCY} \
CASS_DRIVER_NO_CYTHON=${CASS_DRIVER_NO_CYTHON}
diff --git a/airflow-core/pyproject.toml b/airflow-core/pyproject.toml
index d184d67347186..6ae6ce45ba657 100644
--- a/airflow-core/pyproject.toml
+++ b/airflow-core/pyproject.toml
@@ -103,7 +103,8 @@ dependencies = [
"jinja2>=3.1.5",
"jsonschema>=4.19.1",
"lazy-object-proxy>=1.2.0",
- 'libcst >=1.8.2',
+ 'libcst >=1.8.2; python_version < "3.14"',
+ 'libcst >=1.8.6; python_version >= "3.14"',
"linkify-it-py>=2.0.0",
"lockfile>=0.12.2",
"methodtools>=0.4.7",
@@ -173,7 +174,8 @@ dependencies = [
"async" = [
"eventlet>=0.37.0",
"gevent>=25.4.1",
- "greenlet>=3.1.0",
+ "greenlet>=3.1.0; python_version < '3.14'",
+ "greenlet>=3.3.2; python_version >= '3.14'",
"greenback>=1.2.1",
]
"graphviz" = [
diff --git a/airflow-core/tests/unit/always/test_example_dags.py b/airflow-core/tests/unit/always/test_example_dags.py
index b2fca80e8700d..995436b73bc42 100644
--- a/airflow-core/tests/unit/always/test_example_dags.py
+++ b/airflow-core/tests/unit/always/test_example_dags.py
@@ -66,6 +66,9 @@
IGNORE_EXAMPLE_DAGS: tuple[str, ...] = (
# These example dags require suspended providers, eg: google dataflow dependent on the Apache Beam provider,
# but it's in the suspended list, we can't import the dag
+ # Ray uses pydantic v1 internally, which fails to infer types in Python 3.14.
+ # TODO: remove once ray releases a version with Python 3.14 support.
+ "providers/google/tests/system/google/cloud/ray/example_ray_job.py",
"providers/google/tests/system/google/cloud/dataflow/example_dataflow_go.py",
"providers/google/tests/system/google/cloud/dataflow/example_dataflow_java_streaming.py",
"providers/google/tests/system/google/cloud/dataflow/example_dataflow_native_java.py",
diff --git a/airflow-core/tests/unit/api_fastapi/common/test_http_access_log.py b/airflow-core/tests/unit/api_fastapi/common/test_http_access_log.py
index 3547fdf22adc2..5e7e9e6e760d3 100644
--- a/airflow-core/tests/unit/api_fastapi/common/test_http_access_log.py
+++ b/airflow-core/tests/unit/api_fastapi/common/test_http_access_log.py
@@ -123,7 +123,7 @@ async def lifespan_app(scope, receive, send):
import asyncio
with structlog.testing.capture_logs() as logs:
- asyncio.get_event_loop().run_until_complete(middleware({"type": "lifespan"}, None, None))
+ asyncio.run(middleware({"type": "lifespan"}, None, None))
assert logs == []
diff --git a/dev/breeze/tests/test_selective_checks.py b/dev/breeze/tests/test_selective_checks.py
index 1aadcff374939..d1813b509187e 100644
--- a/dev/breeze/tests/test_selective_checks.py
+++ b/dev/breeze/tests/test_selective_checks.py
@@ -1324,7 +1324,12 @@ def test_excluded_providers():
)
assert_outputs_are_printed(
{
- "excluded-providers-as-string": json.dumps({}),
+ "excluded-providers-as-string": json.dumps(
+ {
+ "3.14": [
+ ],
+ }
+ ),
},
str(stderr),
)
diff --git a/providers/apache/cassandra/docs/index.rst b/providers/apache/cassandra/docs/index.rst
index 305452217c26e..92cfb9ef5f136 100644
--- a/providers/apache/cassandra/docs/index.rst
+++ b/providers/apache/cassandra/docs/index.rst
@@ -101,7 +101,8 @@ PIP package Version required
========================================== ==================================================================
``apache-airflow`` ``>=2.11.0``
``apache-airflow-providers-common-compat`` ``>=1.8.0``
-``cassandra-driver`` ``>=3.29.3; python_version >= "3.13"``
+``cassandra-driver`` ``>=3.30.0; python_version >= "3.14"``
+``cassandra-driver`` ``>=3.29.3; python_version >= "3.13" and python_version < "3.14"``
``cassandra-driver`` ``>=3.29.2; python_version >= "3.12" and python_version < "3.13"``
``cassandra-driver`` ``>=3.29.1; python_version < "3.12"``
========================================== ==================================================================
diff --git a/providers/apache/cassandra/pyproject.toml b/providers/apache/cassandra/pyproject.toml
index 43dc076e2c4c8..4da918a42b2a6 100644
--- a/providers/apache/cassandra/pyproject.toml
+++ b/providers/apache/cassandra/pyproject.toml
@@ -61,7 +61,8 @@ requires-python = ">=3.10"
dependencies = [
"apache-airflow>=2.11.0",
"apache-airflow-providers-common-compat>=1.8.0",
- "cassandra-driver>=3.29.3; python_version >= '3.13'",
+ "cassandra-driver>=3.30.0; python_version >= '3.14'",
+ "cassandra-driver>=3.29.3; python_version >= '3.13' and python_version < '3.14'",
"cassandra-driver>=3.29.2; python_version >= '3.12' and python_version < '3.13'",
"cassandra-driver>=3.29.1; python_version < '3.12'",
]
diff --git a/scripts/docker/common.sh b/scripts/docker/common.sh
index 66a3b61e865e1..6a941bdc34354 100644
--- a/scripts/docker/common.sh
+++ b/scripts/docker/common.sh
@@ -117,7 +117,15 @@ function common::get_constraints_location() {
echo
echo "${COLOR_BLUE}Downloading constraints from ${AIRFLOW_CONSTRAINTS_LOCATION} to ${HOME}/constraints.txt ${COLOR_RESET}"
echo
- curl -sSf -o "${HOME}/constraints.txt" "${AIRFLOW_CONSTRAINTS_LOCATION}"
+ if ! curl -sSf -o "${HOME}/constraints.txt" "${AIRFLOW_CONSTRAINTS_LOCATION}"; then
+ echo
+ echo "${COLOR_YELLOW}Constraints file not found at ${AIRFLOW_CONSTRAINTS_LOCATION} (new Python version being bootstrapped?).${COLOR_RESET}"
+ echo "${COLOR_YELLOW}Falling back to no-constraints installation.${COLOR_RESET}"
+ echo
+ AIRFLOW_CONSTRAINTS_LOCATION=""
+ # Create an empty constraints file so --constraint flag still works
+ touch "${HOME}/constraints.txt"
+ fi
else
echo
echo "${COLOR_BLUE}Copying constraints from ${AIRFLOW_CONSTRAINTS_LOCATION} to ${HOME}/constraints.txt ${COLOR_RESET}"
diff --git a/scripts/pyproject.toml b/scripts/pyproject.toml
index bbcc8749bd21d..14221baf18269 100644
--- a/scripts/pyproject.toml
+++ b/scripts/pyproject.toml
@@ -45,7 +45,8 @@ version = "0.0.1"
dependencies = [
"astor>=0.8.1",
"jsonschema>=4.19.1",
- "libcst>=1.1.0",
+ "libcst>=1.1.0; python_version < '3.14'",
+ "libcst>=1.8.6; python_version >= '3.14'",
"packaging>=25.0",
"python-dateutil>=2.8.2",
"pyyaml>=6.0.3",
From e66a3b09fdd0ffe88d825853ea3ba8f67f7cd815 Mon Sep 17 00:00:00 2001
From: Dev-iL <6509619+Dev-iL@users.noreply.github.com>
Date: Sat, 14 Mar 2026 17:44:40 +0200
Subject: [PATCH 04/26] Limit no-constraints fallback to bootstrap builds
---
Dockerfile | 29 ++++++++++++++++++++++++++++-
Dockerfile.ci | 31 +++++++++++++++++++++++++------
scripts/docker/common.sh | 31 +++++++++++++++++++++++++------
3 files changed, 78 insertions(+), 13 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index c7d0b8c9f1812..db08779031d6c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -810,7 +810,34 @@ function common::get_constraints_location() {
echo
echo "${COLOR_BLUE}Downloading constraints from ${AIRFLOW_CONSTRAINTS_LOCATION} to ${HOME}/constraints.txt ${COLOR_RESET}"
echo
- curl -sSf -o "${HOME}/constraints.txt" "${AIRFLOW_CONSTRAINTS_LOCATION}"
+ local http_code
+ if http_code=$(curl -sS -L -o "${HOME}/constraints.txt" -w "%{http_code}" "${AIRFLOW_CONSTRAINTS_LOCATION}"); then
+ if [[ ${http_code} == "200" ]]; then
+ return
+ fi
+ if [[ ${http_code} == "404" \
+ && ${ALLOW_MISSING_PREVIOUS_CONSTRAINTS_FILE:="false"} == "true" \
+ && ${AIRFLOW_FALLBACK_NO_CONSTRAINTS_INSTALLATION:="false"} == "true" ]]; then
+ echo
+ echo "${COLOR_YELLOW}Constraints file not found at ${AIRFLOW_CONSTRAINTS_LOCATION}.${COLOR_RESET}"
+ echo "${COLOR_YELLOW}Using an empty constraints file because bootstrap mode was explicitly enabled.${COLOR_RESET}"
+ echo
+ AIRFLOW_CONSTRAINTS_LOCATION=""
+ : > "${HOME}/constraints.txt"
+ return
+ fi
+ echo
+ echo "${COLOR_RED}Failed to download constraints from ${AIRFLOW_CONSTRAINTS_LOCATION} (HTTP ${http_code}).${COLOR_RESET}"
+ if [[ ${http_code} == "404" ]]; then
+ echo "${COLOR_RED}Only bootstrap builds should set both ALLOW_MISSING_PREVIOUS_CONSTRAINTS_FILE=true and AIRFLOW_FALLBACK_NO_CONSTRAINTS_INSTALLATION=true.${COLOR_RESET}"
+ fi
+ echo
+ return 1
+ fi
+ echo
+ echo "${COLOR_RED}Failed to download constraints from ${AIRFLOW_CONSTRAINTS_LOCATION}.${COLOR_RESET}"
+ echo
+ return 1
else
echo
echo "${COLOR_BLUE}Copying constraints from ${AIRFLOW_CONSTRAINTS_LOCATION} to ${HOME}/constraints.txt ${COLOR_RESET}"
diff --git a/Dockerfile.ci b/Dockerfile.ci
index 1ecc1f00b7045..4a040450d8f4a 100644
--- a/Dockerfile.ci
+++ b/Dockerfile.ci
@@ -750,15 +750,34 @@ function common::get_constraints_location() {
echo
echo "${COLOR_BLUE}Downloading constraints from ${AIRFLOW_CONSTRAINTS_LOCATION} to ${HOME}/constraints.txt ${COLOR_RESET}"
echo
- if ! curl -sSf -o "${HOME}/constraints.txt" "${AIRFLOW_CONSTRAINTS_LOCATION}"; then
+ local http_code
+ if http_code=$(curl -sS -L -o "${HOME}/constraints.txt" -w "%{http_code}" "${AIRFLOW_CONSTRAINTS_LOCATION}"); then
+ if [[ ${http_code} == "200" ]]; then
+ return
+ fi
+ if [[ ${http_code} == "404" \
+ && ${ALLOW_MISSING_PREVIOUS_CONSTRAINTS_FILE:="false"} == "true" \
+ && ${AIRFLOW_FALLBACK_NO_CONSTRAINTS_INSTALLATION:="false"} == "true" ]]; then
+ echo
+ echo "${COLOR_YELLOW}Constraints file not found at ${AIRFLOW_CONSTRAINTS_LOCATION}.${COLOR_RESET}"
+ echo "${COLOR_YELLOW}Using an empty constraints file because bootstrap mode was explicitly enabled.${COLOR_RESET}"
+ echo
+ AIRFLOW_CONSTRAINTS_LOCATION=""
+ : > "${HOME}/constraints.txt"
+ return
+ fi
echo
- echo "${COLOR_YELLOW}Constraints file not found at ${AIRFLOW_CONSTRAINTS_LOCATION} (new Python version being bootstrapped?).${COLOR_RESET}"
- echo "${COLOR_YELLOW}Falling back to no-constraints installation.${COLOR_RESET}"
+ echo "${COLOR_RED}Failed to download constraints from ${AIRFLOW_CONSTRAINTS_LOCATION} (HTTP ${http_code}).${COLOR_RESET}"
+ if [[ ${http_code} == "404" ]]; then
+ echo "${COLOR_RED}Only bootstrap builds should set both ALLOW_MISSING_PREVIOUS_CONSTRAINTS_FILE=true and AIRFLOW_FALLBACK_NO_CONSTRAINTS_INSTALLATION=true.${COLOR_RESET}"
+ fi
echo
- AIRFLOW_CONSTRAINTS_LOCATION=""
- # Create an empty constraints file so --constraint flag still works
- touch "${HOME}/constraints.txt"
+ return 1
fi
+ echo
+ echo "${COLOR_RED}Failed to download constraints from ${AIRFLOW_CONSTRAINTS_LOCATION}.${COLOR_RESET}"
+ echo
+ return 1
else
echo
echo "${COLOR_BLUE}Copying constraints from ${AIRFLOW_CONSTRAINTS_LOCATION} to ${HOME}/constraints.txt ${COLOR_RESET}"
diff --git a/scripts/docker/common.sh b/scripts/docker/common.sh
index 6a941bdc34354..b34ee6f21df19 100644
--- a/scripts/docker/common.sh
+++ b/scripts/docker/common.sh
@@ -117,15 +117,34 @@ function common::get_constraints_location() {
echo
echo "${COLOR_BLUE}Downloading constraints from ${AIRFLOW_CONSTRAINTS_LOCATION} to ${HOME}/constraints.txt ${COLOR_RESET}"
echo
- if ! curl -sSf -o "${HOME}/constraints.txt" "${AIRFLOW_CONSTRAINTS_LOCATION}"; then
+ local http_code
+ if http_code=$(curl -sS -L -o "${HOME}/constraints.txt" -w "%{http_code}" "${AIRFLOW_CONSTRAINTS_LOCATION}"); then
+ if [[ ${http_code} == "200" ]]; then
+ return
+ fi
+ if [[ ${http_code} == "404" \
+ && ${ALLOW_MISSING_PREVIOUS_CONSTRAINTS_FILE:="false"} == "true" \
+ && ${AIRFLOW_FALLBACK_NO_CONSTRAINTS_INSTALLATION:="false"} == "true" ]]; then
+ echo
+ echo "${COLOR_YELLOW}Constraints file not found at ${AIRFLOW_CONSTRAINTS_LOCATION}.${COLOR_RESET}"
+ echo "${COLOR_YELLOW}Using an empty constraints file because bootstrap mode was explicitly enabled.${COLOR_RESET}"
+ echo
+ AIRFLOW_CONSTRAINTS_LOCATION=""
+ : > "${HOME}/constraints.txt"
+ return
+ fi
echo
- echo "${COLOR_YELLOW}Constraints file not found at ${AIRFLOW_CONSTRAINTS_LOCATION} (new Python version being bootstrapped?).${COLOR_RESET}"
- echo "${COLOR_YELLOW}Falling back to no-constraints installation.${COLOR_RESET}"
+ echo "${COLOR_RED}Failed to download constraints from ${AIRFLOW_CONSTRAINTS_LOCATION} (HTTP ${http_code}).${COLOR_RESET}"
+ if [[ ${http_code} == "404" ]]; then
+ echo "${COLOR_RED}Only bootstrap builds should set both ALLOW_MISSING_PREVIOUS_CONSTRAINTS_FILE=true and AIRFLOW_FALLBACK_NO_CONSTRAINTS_INSTALLATION=true.${COLOR_RESET}"
+ fi
echo
- AIRFLOW_CONSTRAINTS_LOCATION=""
- # Create an empty constraints file so --constraint flag still works
- touch "${HOME}/constraints.txt"
+ return 1
fi
+ echo
+ echo "${COLOR_RED}Failed to download constraints from ${AIRFLOW_CONSTRAINTS_LOCATION}.${COLOR_RESET}"
+ echo
+ return 1
else
echo
echo "${COLOR_BLUE}Copying constraints from ${AIRFLOW_CONSTRAINTS_LOCATION} to ${HOME}/constraints.txt ${COLOR_RESET}"
From e165508a0250dd87bcaa0ea69abd086b546bca36 Mon Sep 17 00:00:00 2001
From: Dev-iL <6509619+Dev-iL@users.noreply.github.com>
Date: Sat, 14 Mar 2026 12:31:39 +0200
Subject: [PATCH 05/26] Handle first constraints generation for new Python
versions
---
...elease-management_generate-constraints.svg | 36 ++++-
...elease-management_generate-constraints.txt | 2 +-
.../commands/release_management_commands.py | 11 ++
.../release_management_commands_config.py | 1 +
.../src/airflow_breeze/params/shell_params.py | 6 +
.../tests/test_release_management_commands.py | 52 +++++++
dev/breeze/tests/test_shell_params.py | 8 +
.../in_container/run_generate_constraints.py | 67 +++++++--
scripts/pyproject.toml | 3 +-
.../tests/scripts/in_container/__init__.py | 16 ++
.../test_run_generate_constraints.py | 139 ++++++++++++++++++
11 files changed, 322 insertions(+), 19 deletions(-)
create mode 100644 dev/breeze/tests/test_release_management_commands.py
create mode 100644 scripts/tests/scripts/in_container/__init__.py
create mode 100644 scripts/tests/scripts/in_container/test_run_generate_constraints.py
diff --git a/dev/breeze/doc/images/output_release-management_generate-constraints.svg b/dev/breeze/doc/images/output_release-management_generate-constraints.svg
index 46cfb481b7801..adabb4c14fb74 100644
--- a/dev/breeze/doc/images/output_release-management_generate-constraints.svg
+++ b/dev/breeze/doc/images/output_release-management_generate-constraints.svg
@@ -1,4 +1,4 @@
-