diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index b1988fcd1061f..ba5d0a4456077 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -292,6 +292,11 @@ repos:
- --ignore-words=docs/spelling_wordlist.txt
- --skip=airflow/providers/*/*.rst,airflow/www/*.log,docs/*/commits.rst,docs/apache-airflow/tutorial/pipeline_example.csv,*.min.js,*.lock,INTHEWILD.md
- --exclude-file=.codespellignorelines
+ - repo: https://github.com/abravalheri/validate-pyproject
+ rev: v0.14
+ hooks:
+ - id: validate-pyproject
+ name: Validate pyproject.toml
- repo: local
# Note that this is the 2nd "local" repo group in the .pre-commit-config.yaml file. This is because
# we try to minimise the number of passes that must happen in order to apply some of the changes
diff --git a/STATIC_CODE_CHECKS.rst b/STATIC_CODE_CHECKS.rst
index a6fbb5b93bfcc..be446735cbd13 100644
--- a/STATIC_CODE_CHECKS.rst
+++ b/STATIC_CODE_CHECKS.rst
@@ -359,6 +359,8 @@ require Breeze Docker image to be built locally.
+-----------------------------------------------------------+--------------------------------------------------------------+---------+
| update-version | Update version to the latest version in the documentation | |
+-----------------------------------------------------------+--------------------------------------------------------------+---------+
+| validate-pyproject | Validate pyproject.toml | |
++-----------------------------------------------------------+--------------------------------------------------------------+---------+
| yamllint | Check YAML files with yamllint | |
+-----------------------------------------------------------+--------------------------------------------------------------+---------+
diff --git a/dev/breeze/src/airflow_breeze/pre_commit_ids.py b/dev/breeze/src/airflow_breeze/pre_commit_ids.py
index a9f797e84ce0f..a083ee15ea5be 100644
--- a/dev/breeze/src/airflow_breeze/pre_commit_ids.py
+++ b/dev/breeze/src/airflow_breeze/pre_commit_ids.py
@@ -125,5 +125,6 @@
"update-supported-versions",
"update-vendored-in-k8s-json-schema",
"update-version",
+ "validate-pyproject",
"yamllint",
]
diff --git a/images/breeze/output-commands-hash.txt b/images/breeze/output-commands-hash.txt
index 92905b64e49ae..666a12b13d92a 100644
--- a/images/breeze/output-commands-hash.txt
+++ b/images/breeze/output-commands-hash.txt
@@ -64,7 +64,7 @@ setup:version:be116d90a21c2afe01087f7609774e1e
setup:fd391bab5277ad3aca65987a84144d51
shell:1462cde6f7e11a73cb42d4eec93c598e
start-airflow:d4815dea2cfc0af7038697c1d9a13996
-static-checks:d643498c1537236f20c475c0036f1a30
+static-checks:19926b8fcea5784b28d4a0d99865363c
testing:docker-compose-tests:a4dfe7dadbe3e95fdf2b8d2107f7e208
testing:helm-tests:0669be17b744ba057adbf38681bd8e68
testing:integration-tests:e745af9dd595adaa6f17ef02fbaae3b5
diff --git a/images/breeze/output_static-checks.svg b/images/breeze/output_static-checks.svg
index aff980e81db24..f694d823b7722 100644
--- a/images/breeze/output_static-checks.svg
+++ b/images/breeze/output_static-checks.svg
@@ -332,7 +332,7 @@
│update-local-yml-file | update-migration-references | │
│update-providers-dependencies | update-spelling-wordlist-to-be-sorted | │
│update-supported-versions | update-vendored-in-k8s-json-schema | update-version |│
-│yamllint) │
+│validate-pyproject | yamllint) │
│--show-diff-on-failure-sShow diff for files modified by the checks.│
│--initialize-environmentInitialize environment before running checks.│
│--max-initialization-attemptsMaximum number of attempts to initialize environment before giving up.│
diff --git a/pyproject.toml b/pyproject.toml
index 1732edc78fb1e..38d80503b8f56 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -16,7 +16,7 @@
# under the License.
[tool.black]
line-length = 110
-target-version = ['py37', 'py38', 'py39', 'py310']
+target-version = ['py38', 'py39', 'py310', 'py311']
# Editable installs are currently broken using setuptools 64.0.0 and above. The problem is tracked in
# https://github.com/pypa/setuptools/issues/3548. We're also discussing how we could potentially fix
@@ -28,10 +28,8 @@ target-version = ['py37', 'py38', 'py39', 'py310']
requires = ['setuptools==67.2.0']
build-backend = "setuptools.build_meta"
-[project]
-requires-python = ">=3.8"
-
[tool.ruff]
+target-version = "py38"
typing-modules = ["airflow.typing_compat"]
line-length = 110
extend-exclude = [