mirror of https://github.com/astral-sh/uv
636 lines
27 KiB
TOML
636 lines
27 KiB
TOML
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance
|
|
# with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
[build-system]
|
|
# build dependencies should be fixed - including all transitive dependencies. This way we can ensure
|
|
# reproducibility of the build and make sure that any future releases of any dependencies will not
|
|
# break the build of released airflow sources in the future.
|
|
# The dependencies can be automatically upgraded by running:
|
|
# pre-commit run --hook-stage manual update-build-dependencies --all-files
|
|
requires = [
|
|
"GitPython==3.1.43",
|
|
"gitdb==4.0.11",
|
|
"hatchling==1.25.0",
|
|
"packaging==24.1",
|
|
"pathspec==0.12.1",
|
|
"pluggy==1.5.0",
|
|
"smmap==5.0.1",
|
|
"tomli==2.0.1; python_version < '3.11'",
|
|
"trove-classifiers==2024.7.2",
|
|
]
|
|
build-backend = "hatchling.build"
|
|
|
|
[project]
|
|
name = "apache-airflow"
|
|
description = "Programmatically author, schedule and monitor data pipelines"
|
|
readme = { file = "generated/PYPI_README.md", content-type = "text/markdown" }
|
|
license-files.globs = ["LICENSE", "3rd-party-licenses/*.txt"]
|
|
requires-python = "~=3.8,<3.13"
|
|
authors = [
|
|
{ name = "Apache Software Foundation", email = "dev@airflow.apache.org" },
|
|
]
|
|
maintainers = [
|
|
{ name = "Apache Software Foundation", email="dev@airflow.apache.org" },
|
|
]
|
|
keywords = [ "airflow", "orchestration", "workflow", "dag", "pipelines", "automation", "data" ]
|
|
classifiers = [
|
|
"Development Status :: 5 - Production/Stable",
|
|
"Environment :: Console",
|
|
"Environment :: Web Environment",
|
|
"Framework :: Apache Airflow",
|
|
"Intended Audience :: Developers",
|
|
"Intended Audience :: System Administrators",
|
|
"License :: OSI Approved :: Apache Software License",
|
|
"Programming Language :: Python :: 3.8",
|
|
"Programming Language :: Python :: 3.9",
|
|
"Programming Language :: Python :: 3.10",
|
|
"Programming Language :: Python :: 3.11",
|
|
"Programming Language :: Python :: 3.12",
|
|
"Topic :: System :: Monitoring",
|
|
]
|
|
|
|
dynamic = ["version", "optional-dependencies", "dependencies"]
|
|
|
|
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
# !!! YOU MIGHT BE SURPRISED NOT SEEING THE DEPENDENCIES AS `project.dependencies` !!!!!!!!!
|
|
# !!! AND EXTRAS AS `project.optional-dependencies` !!!!!!!!!
|
|
# !!! THEY ARE marked as `dynamic` GENERATED by `hatch_build.py` !!!!!!!!!
|
|
# !!! SEE COMMENTS BELOW TO FIND WHERE DEPENDENCIES ARE MAINTAINED !!!!!!!!!
|
|
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
#
|
|
# !!!!!! Those providers are defined in `hatch_build.py` and should be maintained there !!!!!!!
|
|
#
|
|
# Those extras are available as regular core airflow extras - they install optional features of Airflow.
|
|
#
|
|
# START CORE EXTRAS HERE
|
|
#
|
|
# aiobotocore, apache-atlas, apache-webhdfs, async, cgroups, cloudpickle, deprecated-api, github-
|
|
# enterprise, google-auth, graphviz, kerberos, ldap, leveldb, otel, pandas, password, pydantic,
|
|
# rabbitmq, s3fs, saml, sentry, statsd, uv, virtualenv
|
|
#
|
|
# END CORE EXTRAS HERE
|
|
#
|
|
# The ``devel`` extras are not available in the released packages. They are only available when you install
|
|
# Airflow from sources in ``editable`` installation - i.e. one that you are usually using to contribute to
|
|
# Airflow. They provide tools such as ``pytest`` and ``mypy`` for general purpose development and testing.
|
|
#
|
|
# START DEVEL EXTRAS HERE
|
|
#
|
|
# devel, devel-all-dbs, devel-ci, devel-debuggers, devel-devscripts, devel-duckdb, devel-hadoop,
|
|
# devel-mypy, devel-sentry, devel-static-checks, devel-tests
|
|
#
|
|
# END DEVEL EXTRAS HERE
|
|
#
|
|
# Those extras are bundles dynamically generated from other extras.
|
|
#
|
|
# START BUNDLE EXTRAS HERE
|
|
#
|
|
# all, all-core, all-dbs, devel-all, devel-ci
|
|
#
|
|
# END BUNDLE EXTRAS HERE
|
|
#
|
|
# The ``doc`` extras are not available in the released packages. They are only available when you install
|
|
# Airflow from sources in ``editable`` installation - i.e. one that you are usually using to contribute to
|
|
# Airflow. They provide tools needed when you want to build Airflow documentation (note that you also need
|
|
# ``devel`` extras installed for airflow and providers in order to build documentation for airflow and
|
|
# provider packages respectively). The ``doc`` package is enough to build regular documentation, where
|
|
# ``doc_gen`` is needed to generate ER diagram we have describing our database.
|
|
#
|
|
# START DOC EXTRAS HERE
|
|
#
|
|
# doc, doc-gen
|
|
#
|
|
# END DOC EXTRAS HERE
|
|
#
|
|
# The `deprecated` extras are deprecated extras from Airflow 1 that will be removed in future versions.
|
|
#
|
|
# START DEPRECATED EXTRAS HERE
|
|
#
|
|
# atlas, aws, azure, cassandra, crypto, druid, gcp, gcp-api, hdfs, hive, kubernetes, mssql, pinot, s3,
|
|
# spark, webhdfs, winrm
|
|
#
|
|
# END DEPRECATED EXTRAS HERE
|
|
#
|
|
# !!!!!! Those providers are defined in the `airflow/providers/<provider>/provider.yaml` files !!!!!!!
|
|
#
|
|
# Those extras are available as regular Airflow extras, they install provider packages in standard builds
|
|
# or dependencies that are necessary to enable the feature in editable build.
|
|
# START PROVIDER EXTRAS HERE
|
|
#
|
|
# airbyte, alibaba, amazon, apache.beam, apache.cassandra, apache.drill, apache.druid, apache.flink,
|
|
# apache.hdfs, apache.hive, apache.iceberg, apache.impala, apache.kafka, apache.kylin, apache.livy,
|
|
# apache.pig, apache.pinot, apache.spark, apprise, arangodb, asana, atlassian.jira, celery, cloudant,
|
|
# cncf.kubernetes, cohere, common.compat, common.io, common.sql, databricks, datadog, dbt.cloud,
|
|
# dingding, discord, docker, elasticsearch, exasol, fab, facebook, ftp, github, google, grpc,
|
|
# hashicorp, http, imap, influxdb, jdbc, jenkins, microsoft.azure, microsoft.mssql, microsoft.psrp,
|
|
# microsoft.winrm, mongo, mysql, neo4j, odbc, openai, openfaas, openlineage, opensearch, opsgenie,
|
|
# oracle, pagerduty, papermill, pgvector, pinecone, postgres, presto, qdrant, redis, salesforce,
|
|
# samba, segment, sendgrid, sftp, singularity, slack, smtp, snowflake, sqlite, ssh, tableau, tabular,
|
|
# telegram, teradata, trino, vertica, weaviate, yandex, ydb, zendesk
|
|
#
|
|
# END PROVIDER EXTRAS HERE
|
|
|
|
[project.scripts]
|
|
airflow = "airflow.__main__:main"
|
|
[project.urls]
|
|
"Bug Tracker" = "https://github.com/apache/airflow/issues"
|
|
Documentation = "https://airflow.apache.org/docs/"
|
|
Downloads = "https://archive.apache.org/dist/airflow/"
|
|
Homepage = "https://airflow.apache.org/"
|
|
"Release Notes" = "https://airflow.apache.org/docs/apache-airflow/stable/release_notes.html"
|
|
"Slack Chat" = "https://s.apache.org/airflow-slack"
|
|
"Source Code" = "https://github.com/apache/airflow"
|
|
Twitter = "https://twitter.com/ApacheAirflow"
|
|
YouTube = "https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/"
|
|
|
|
[tool.hatch.envs.default]
|
|
python = "3.8"
|
|
platforms = ["linux", "macos"]
|
|
description = "Default environment with Python 3.8 for maximum compatibility"
|
|
features = []
|
|
|
|
[tool.hatch.envs.airflow-38]
|
|
python = "3.8"
|
|
platforms = ["linux", "macos"]
|
|
description = "Environment with Python 3.8. No devel installed."
|
|
features = []
|
|
|
|
[tool.hatch.envs.airflow-39]
|
|
python = "3.9"
|
|
platforms = ["linux", "macos"]
|
|
description = "Environment with Python 3.9. No devel installed."
|
|
features = []
|
|
|
|
[tool.hatch.envs.airflow-310]
|
|
python = "3.10"
|
|
platforms = ["linux", "macos"]
|
|
description = "Environment with Python 3.10. No devel installed."
|
|
features = []
|
|
|
|
[tool.hatch.envs.airflow-311]
|
|
python = "3.11"
|
|
platforms = ["linux", "macos"]
|
|
description = "Environment with Python 3.11. No devel installed"
|
|
features = []
|
|
|
|
[tool.hatch.envs.airflow-312]
|
|
python = "3.12"
|
|
platforms = ["linux", "macos"]
|
|
description = "Environment with Python 3.12. No devel installed"
|
|
features = []
|
|
|
|
|
|
[tool.hatch.version]
|
|
path = "airflow/__init__.py"
|
|
|
|
[tool.hatch.build.targets.wheel.hooks.custom]
|
|
path = "./hatch_build.py"
|
|
|
|
[tool.hatch.build.hooks.custom]
|
|
path = "./hatch_build.py"
|
|
|
|
[tool.hatch.build.targets.custom]
|
|
path = "./hatch_build.py"
|
|
|
|
[tool.hatch.build.targets.sdist]
|
|
include = [
|
|
"/airflow",
|
|
"/airflow/git_version"
|
|
]
|
|
exclude = [
|
|
"/airflow/providers/",
|
|
"/airflow/www/node_modules/"
|
|
]
|
|
artifacts = [
|
|
"/airflow/www/static/dist/",
|
|
"/airflow/git_version",
|
|
"/generated/",
|
|
]
|
|
|
|
|
|
[tool.hatch.build.targets.wheel]
|
|
include = [
|
|
"/airflow",
|
|
]
|
|
exclude = [
|
|
"/airflow/providers/",
|
|
]
|
|
artifacts = [
|
|
"/airflow/www/static/dist/",
|
|
"/airflow/git_version"
|
|
]
|
|
|
|
## black settings ##
|
|
[tool.black]
|
|
line-length = 110
|
|
target-version = ['py38', 'py39', 'py310', 'py311', 'py312']
|
|
|
|
|
|
## ruff settings ##
|
|
[tool.ruff]
|
|
target-version = "py38"
|
|
line-length = 110
|
|
extend-exclude = [
|
|
".eggs",
|
|
"*/_vendor/*",
|
|
# The files generated by stubgen aren't 100% valid syntax it turns out, and we don't ship them, so we can
|
|
# ignore them in ruff
|
|
"airflow/providers/common/sql/*/*.pyi",
|
|
"tests/dags/test_imports.py",
|
|
]
|
|
|
|
namespace-packages = ["airflow/providers"]
|
|
|
|
[tool.ruff.lint]
|
|
typing-modules = ["airflow.typing_compat"]
|
|
extend-select = [
|
|
# Enable entire ruff rule section
|
|
"I", # Missing required import (auto-fixable)
|
|
"UP", # Pyupgrade
|
|
"ASYNC", # subset of flake8-async rules
|
|
"ISC", # Checks for implicit literal string concatenation (auto-fixable)
|
|
"TCH", # Rules around TYPE_CHECKING blocks
|
|
"G", # flake8-logging-format rules
|
|
"LOG", # flake8-logging rules, most of them autofixable
|
|
"PT", # flake8-pytest-style rules
|
|
"TID25", # flake8-tidy-imports rules
|
|
"E", # pycodestyle rules
|
|
"W", # pycodestyle rules
|
|
# Per rule enables
|
|
"RUF006", # Checks for asyncio dangling task
|
|
"RUF015", # Checks for unnecessary iterable allocation for first element
|
|
"RUF019", # Checks for unnecessary key check
|
|
"RUF100", # Unused noqa (auto-fixable)
|
|
# We ignore more pydocstyle than we enable, so be more selective at what we enable
|
|
"D1",
|
|
"D2",
|
|
"D213", # Conflicts with D212. Both can not be enabled.
|
|
"D3",
|
|
"D400",
|
|
"D401",
|
|
"D402",
|
|
"D403",
|
|
"D412",
|
|
"D419",
|
|
"PGH004", # Use specific rule codes when using noqa
|
|
"PGH005", # Invalid unittest.mock.Mock methods/attributes/properties
|
|
"S101", # Checks use `assert` outside the test cases, test cases should be added into the exclusions
|
|
"B004", # Checks for use of hasattr(x, "__call__") and replaces it with callable(x)
|
|
"B006", # Checks for uses of mutable objects as function argument defaults.
|
|
"B007", # Checks for unused variables in the loop
|
|
"B017", # Checks for pytest.raises context managers that catch Exception or BaseException.
|
|
"B019", # Use of functools.lru_cache or functools.cache on methods can lead to memory leaks
|
|
"B028", # No explicit stacklevel keyword argument found
|
|
"TRY002", # Prohibit use of `raise Exception`, use specific exceptions instead.
|
|
]
|
|
ignore = [
|
|
"D100", # Unwanted; Docstring at the top of every file.
|
|
"D102", # TODO: Missing docstring in public method
|
|
"D103", # TODO: Missing docstring in public function
|
|
"D104", # Unwanted; Docstring at the top of every `__init__.py` file.
|
|
"D105", # Unwanted; See https://lists.apache.org/thread/8jbg1dd2lr2cfydtqbjxsd6pb6q2wkc3
|
|
"D107", # Unwanted; Docstring in every constructor is unnecessary if the class has a docstring.
|
|
"D203",
|
|
"D212", # Conflicts with D213. Both can not be enabled.
|
|
"D214",
|
|
"D215",
|
|
"E731", # Do not assign a lambda expression, use a def
|
|
"TCH003", # Do not move imports from stdlib to TYPE_CHECKING block
|
|
"PT004", # Fixture does not return anything, add leading underscore
|
|
"PT005", # Fixture returns a value, remove leading underscore
|
|
"PT006", # Wrong type of names in @pytest.mark.parametrize
|
|
"PT007", # Wrong type of values in @pytest.mark.parametrize
|
|
"PT011", # pytest.raises() is too broad, set the match parameter
|
|
"PT019", # fixture without value is injected as parameter, use @pytest.mark.usefixtures instead
|
|
# Rules below explicitly set off which could overlap with Ruff's formatter
|
|
# as it recommended by https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
|
|
# Except ISC rules
|
|
"W191",
|
|
"E111",
|
|
"E114",
|
|
"E117",
|
|
"D206",
|
|
"D300",
|
|
"Q000",
|
|
"Q001",
|
|
"Q002",
|
|
"Q003",
|
|
"COM812",
|
|
"COM819",
|
|
"E501", # Formatted code may exceed the line length, leading to line-too-long (E501) errors.
|
|
]
|
|
unfixable = [
|
|
# PT022 replace empty `yield` to empty `return`. Might be fixed with a combination of PLR1711
|
|
# In addition, it can't do anything with invalid typing annotations, protected by mypy.
|
|
"PT022",
|
|
]
|
|
|
|
[tool.ruff.format]
|
|
docstring-code-format = true
|
|
|
|
[tool.ruff.lint.isort]
|
|
required-imports = ["from __future__ import annotations"]
|
|
combine-as-imports = true
|
|
|
|
[tool.ruff.lint.per-file-ignores]
|
|
"airflow/__init__.py" = ["F401", "TCH004"]
|
|
"airflow/models/__init__.py" = ["F401", "TCH004"]
|
|
"airflow/models/sqla_models.py" = ["F401"]
|
|
|
|
# The test_python.py is needed because adding __future__.annotations breaks runtime checks that are
|
|
# needed for the test to work
|
|
"tests/decorators/test_python.py" = ["I002"]
|
|
|
|
# The Pydantic representations of SqlAlchemy Models are not parsed well with Pydantic
|
|
# when __future__.annotations is used so we need to skip them from upgrading
|
|
# Pydantic also require models to be imported during execution
|
|
"airflow/serialization/pydantic/*.py" = ["I002", "UP007", "TCH001"]
|
|
|
|
# Ignore pydoc style from these
|
|
"*.pyi" = ["D"]
|
|
"scripts/*" = ["D", "PT"] # In addition ignore pytest specific rules
|
|
"docs/*" = ["D"]
|
|
"provider_packages/*" = ["D"]
|
|
"*/example_dags/*" = ["D"]
|
|
"chart/*" = ["D"]
|
|
"dev/*" = ["D"]
|
|
# In addition, ignore in tests
|
|
# TID253: Banned top level imports, e.g. pandas, numpy
|
|
# S101: Use `assert`
|
|
# TRY002: Use `raise Exception`
|
|
"dev/perf/*" = ["TID253"]
|
|
"dev/check_files.py" = ["S101"]
|
|
"dev/breeze/tests/*" = ["TID253", "S101", "TRY002"]
|
|
"tests/*" = ["D", "TID253", "S101", "TRY002"]
|
|
"docker_tests/*" = ["D", "TID253", "S101", "TRY002"]
|
|
"kubernetes_tests/*" = ["D", "TID253", "S101", "TRY002"]
|
|
"helm_tests/*" = ["D", "TID253", "S101", "TRY002"]
|
|
|
|
# All of the modules which have an extra license header (i.e. that we copy from another project) need to
|
|
# ignore E402 -- module level import not at top level
|
|
"scripts/ci/pre_commit/*.py" = ["E402"]
|
|
"airflow/api/auth/backend/kerberos_auth.py" = ["E402"]
|
|
"airflow/security/kerberos.py" = ["E402"]
|
|
"airflow/security/utils.py" = ["E402"]
|
|
"tests/providers/common/io/xcom/test_backend.py" = ["E402"]
|
|
"tests/providers/elasticsearch/log/elasticmock/__init__.py" = ["E402"]
|
|
"tests/providers/elasticsearch/log/elasticmock/utilities/__init__.py" = ["E402"]
|
|
"tests/providers/google/cloud/hooks/vertex_ai/test_batch_prediction_job.py" = ["E402"]
|
|
"tests/providers/google/cloud/hooks/vertex_ai/test_hyperparameter_tuning_job.py" = ["E402"]
|
|
"tests/providers/google/cloud/hooks/vertex_ai/test_auto_ml.py" = ["E402"]
|
|
"tests/providers/google/cloud/hooks/vertex_ai/test_custom_job.py" = ["E402"]
|
|
"tests/providers/google/cloud/hooks/vertex_ai/test_dataset.py" = ["E402"]
|
|
"tests/providers/google/cloud/hooks/vertex_ai/test_endpoint_service.py" = ["E402"]
|
|
"tests/providers/google/cloud/hooks/vertex_ai/test_generative_model.py" = ["E402"]
|
|
"tests/providers/google/cloud/hooks/vertex_ai/test_model_service.py" = ["E402"]
|
|
"tests/providers/google/cloud/hooks/vertex_ai/test_pipeline_job.py" = ["E402"]
|
|
"tests/providers/google/cloud/hooks/vertex_ai/test_prediction_service.py" = ["E402"]
|
|
"tests/providers/google/cloud/links/test_translate.py" = ["E402"]
|
|
"tests/providers/google/cloud/operators/test_automl.py"= ["E402"]
|
|
"tests/providers/google/cloud/operators/test_vertex_ai.py" = ["E402"]
|
|
"tests/providers/google/cloud/operators/vertex_ai/test_generative_model.py" = ["E402"]
|
|
"tests/providers/google/cloud/triggers/test_vertex_ai.py" = ["E402"]
|
|
"tests/providers/openai/hooks/test_openai.py" = ["E402"]
|
|
"tests/providers/openai/operators/test_openai.py" = ["E402"]
|
|
"tests/providers/qdrant/hooks/test_qdrant.py" = ["E402"]
|
|
"tests/providers/qdrant/operators/test_qdrant.py" = ["E402"]
|
|
"tests/providers/snowflake/operators/test_snowflake_sql.py" = ["E402"]
|
|
"tests/providers/yandex/*/*.py" = ["E402"]
|
|
|
|
# All the modules which do not follow B028 yet: https://docs.astral.sh/ruff/rules/no-explicit-stacklevel/
|
|
"helm_tests/airflow_aux/test_basic_helm_chart.py" = ["B028"]
|
|
|
|
# https://github.com/apache/airflow/issues/39252
|
|
"airflow/providers/amazon/aws/hooks/eks.py" = ["W605"]
|
|
|
|
# Test compat imports banned imports to allow testing against older airflow versions
|
|
"tests/test_utils/compat.py" = ["TID251", "F401"]
|
|
|
|
[tool.ruff.lint.flake8-tidy-imports]
|
|
# Disallow all relative imports.
|
|
ban-relative-imports = "all"
|
|
# Ban certain modules from being imported at module level, instead requiring
|
|
# that they're imported lazily (e.g., within a function definition).
|
|
banned-module-level-imports = ["numpy", "pandas"]
|
|
|
|
[tool.ruff.lint.flake8-tidy-imports.banned-api]
|
|
# Direct import from the airflow package modules and constraints
|
|
"airflow.AirflowException".msg = "Use airflow.exceptions.AirflowException instead."
|
|
"airflow.Dataset".msg = "Use airflow.datasets.Dataset instead."
|
|
"airflow.PY36".msg = "Use sys.version_info >= (3, 6) instead."
|
|
"airflow.PY37".msg = "Use sys.version_info >= (3, 7) instead."
|
|
"airflow.PY38".msg = "Use sys.version_info >= (3, 8) instead."
|
|
"airflow.PY39".msg = "Use sys.version_info >= (3, 9) instead."
|
|
"airflow.PY310".msg = "Use sys.version_info >= (3, 10) instead."
|
|
"airflow.PY311".msg = "Use sys.version_info >= (3, 11) instead."
|
|
"airflow.PY312".msg = "Use sys.version_info >= (3, 12) instead."
|
|
# Deprecated imports
|
|
"airflow.models.baseoperator.BaseOperatorLink".msg = "Use airflow.models.baseoperatorlink.BaseOperatorLink"
|
|
"airflow.models.errors.ImportError".msg = "Use airflow.models.errors.ParseImportError"
|
|
"airflow.models.ImportError".msg = "Use airflow.models.errors.ParseImportError"
|
|
# Deprecated in Python 3.11, Pending Removal in Python 3.15: https://github.com/python/cpython/issues/90817
|
|
# Deprecation warning in Python 3.11 also recommends using locale.getencoding but it available in Python 3.11
|
|
"locale.getdefaultlocale".msg = "Use locale.setlocale() and locale.getlocale() instead."
|
|
# Deprecated in Python 3.12: https://github.com/python/cpython/issues/103857
|
|
"datetime.datetime.utcnow".msg = "Use airflow.utils.timezone.utcnow or datetime.datetime.now(tz=datetime.timezone.utc)"
|
|
"datetime.datetime.utcfromtimestamp".msg = "Use airflow.utils.timezone.from_timestamp or datetime.datetime.fromtimestamp(tz=datetime.timezone.utc)"
|
|
# Deprecated in Python 3.12: https://github.com/python/cpython/issues/94309
|
|
"typing.Hashable".msg = "Use collections.abc.Hashable"
|
|
"typing.Sized".msg = "Use collections.abc.Sized"
|
|
# Uses deprecated in Python 3.12 `datetime.datetime.utcfromtimestamp`
|
|
"pendulum.from_timestamp".msg = "Use airflow.utils.timezone.from_timestamp"
|
|
# Flask deprecations, worthwhile to keep it until we migrate to Flask 3.0+
|
|
"flask._app_ctx_stack".msg = "Deprecated in Flask 2.2, removed in Flask 3.0"
|
|
"flask._request_ctx_stack".msg = "Deprecated in Flask 2.2, removed in Flask 3.0"
|
|
"flask.escape".msg = "Use markupsafe.escape instead. Deprecated in Flask 2.3, removed in Flask 3.0"
|
|
"flask.Markup".msg = "Use markupsafe.Markup instead. Deprecated in Flask 2.3, removed in Flask 3.0"
|
|
"flask.signals_available".msg = "Signals are always available. Deprecated in Flask 2.3, removed in Flask 3.0"
|
|
# Use root logger by a mistake / IDE autosuggestion
|
|
# If for some reason root logger required it could obtained by logging.getLogger("root")
|
|
"logging.debug".msg = "Instantiate new `logger = logging.getLogger(__name__)` and use it instead of root logger"
|
|
"logging.info".msg = "Instantiate new `logger = logging.getLogger(__name__)` and use it instead of root logger"
|
|
"logging.warning".msg = "Instantiate new `logger = logging.getLogger(__name__)` and use it instead of root logger"
|
|
"logging.error".msg = "Instantiate new `logger = logging.getLogger(__name__)` and use it instead of root logger"
|
|
"logging.exception".msg = "Instantiate new `logger = logging.getLogger(__name__)` and use it instead of root logger"
|
|
"logging.fatal".msg = "Instantiate new `logger = logging.getLogger(__name__)` and use it instead of root logger"
|
|
"logging.critical".msg = "Instantiate new `logger = logging.getLogger(__name__)` and use it instead of root logger"
|
|
"logging.log".msg = "Instantiate new `logger = logging.getLogger(__name__)` and use it instead of root logger"
|
|
# unittest related restrictions
|
|
"unittest.TestCase".msg = "Use pytest compatible classes: https://docs.pytest.org/en/stable/getting-started.html#group-multiple-tests-in-a-class"
|
|
"unittest.skip".msg = "Use `pytest.mark.skip` instead: https://docs.pytest.org/en/stable/reference/reference.html#marks"
|
|
"unittest.skipIf".msg = "Use `pytest.mark.skipif` instead: https://docs.pytest.org/en/stable/reference/reference.html#marks"
|
|
"unittest.skipUnless".msg = "Use `pytest.mark.skipif` instead: https://docs.pytest.org/en/stable/reference/reference.html#marks"
|
|
"unittest.expectedFailure".msg = "Use `pytest.mark.xfail` instead: https://docs.pytest.org/en/stable/reference/reference.html#marks"
|
|
# Moved in SQLAlchemy 2.0
|
|
"sqlalchemy.ext.declarative.declarative_base".msg = "Use `sqlalchemy.orm.declarative_base`. Moved in SQLAlchemy 2.0"
|
|
"sqlalchemy.ext.declarative.as_declarative".msg = "Use `sqlalchemy.orm.as_declarative`. Moved in SQLAlchemy 2.0"
|
|
"sqlalchemy.ext.declarative.has_inherited_table".msg = "Use `sqlalchemy.orm.has_inherited_table`. Moved in SQLAlchemy 2.0"
|
|
"sqlalchemy.ext.declarative.synonym_for".msg = "Use `sqlalchemy.orm.synonym_for`. Moved in SQLAlchemy 2.0"
|
|
|
|
[tool.ruff.lint.flake8-type-checking]
|
|
exempt-modules = ["typing", "typing_extensions"]
|
|
|
|
[tool.ruff.lint.flake8-pytest-style]
|
|
mark-parentheses = false
|
|
fixture-parentheses = false
|
|
|
|
## pytest settings ##
|
|
[tool.pytest.ini_options]
|
|
addopts = [
|
|
"-rasl",
|
|
"--verbosity=2",
|
|
# Disable `flaky` plugin for pytest. This plugin conflicts with `rerunfailures` because provide the same marker.
|
|
"-p", "no:flaky",
|
|
# Disable `nose` builtin plugin for pytest. This feature is deprecated in 7.2 and will be removed in pytest>=8
|
|
"-p", "no:nose",
|
|
# Disable support of a legacy `LocalPath` in favor of stdlib `pathlib.Path`.
|
|
"-p", "no:legacypath",
|
|
# Disable warnings summary, because we use our warning summary.
|
|
"--disable-warnings",
|
|
"--asyncio-mode=strict",
|
|
]
|
|
norecursedirs = [
|
|
".eggs",
|
|
"airflow",
|
|
"tests/_internals",
|
|
"tests/dags_with_system_exit",
|
|
"tests/test_utils",
|
|
"tests/dags_corrupted",
|
|
"tests/dags",
|
|
"tests/system/providers/google/cloud/dataproc/resources",
|
|
"tests/system/providers/google/cloud/gcs/resources",
|
|
]
|
|
log_level = "INFO"
|
|
filterwarnings = [
|
|
"error::pytest.PytestCollectionWarning",
|
|
"error::pytest.PytestReturnNotNoneWarning",
|
|
# Avoid building cartesian product which might impact performance
|
|
"error:SELECT statement has a cartesian product between FROM:sqlalchemy.exc.SAWarning:airflow",
|
|
'error:Coercing Subquery object into a select\(\) for use in IN\(\):sqlalchemy.exc.SAWarning:airflow',
|
|
'error:Class.*will not make use of SQL compilation caching',
|
|
"ignore::DeprecationWarning:flask_appbuilder.filemanager",
|
|
"ignore::DeprecationWarning:flask_appbuilder.widgets",
|
|
# FAB do not support SQLAclhemy 2
|
|
"ignore::sqlalchemy.exc.MovedIn20Warning:flask_appbuilder",
|
|
# https://github.com/dpgaspar/Flask-AppBuilder/issues/2194
|
|
"ignore::DeprecationWarning:marshmallow_sqlalchemy.convert",
|
|
# https://github.com/dpgaspar/Flask-AppBuilder/pull/1940
|
|
"ignore::DeprecationWarning:flask_sqlalchemy",
|
|
# https://github.com/dpgaspar/Flask-AppBuilder/pull/1903
|
|
"ignore::DeprecationWarning:apispec.utils",
|
|
# Connexion 2 use different deprecated objects, this should be resolved into Connexion 3
|
|
# https://github.com/spec-first/connexion/pull/1536
|
|
'ignore::DeprecationWarning:connexion.spec',
|
|
'ignore:jsonschema\.RefResolver:DeprecationWarning:connexion.json_schema',
|
|
'ignore:jsonschema\.exceptions\.RefResolutionError:DeprecationWarning:connexion.json_schema',
|
|
'ignore:Accessing jsonschema\.draft4_format_checker:DeprecationWarning:connexion.decorators.validation',
|
|
]
|
|
# We cannot add warnings from the airflow package into `filterwarnings`,
|
|
# because it invokes import airflow before we set up test environment which breaks the tests.
|
|
# Instead of that, we use a separate parameter and dynamically add it into `filterwarnings` marker.
|
|
forbidden_warnings = [
|
|
"airflow.exceptions.RemovedInAirflow3Warning",
|
|
"airflow.utils.context.AirflowContextDeprecationWarning",
|
|
"airflow.exceptions.AirflowProviderDeprecationWarning",
|
|
]
|
|
python_files = [
|
|
"test_*.py",
|
|
"example_*.py",
|
|
]
|
|
testpaths = [
|
|
"tests",
|
|
]
|
|
# Keep temporary directories (created by `tmp_path`) for 2 recent runs only failed tests.
|
|
tmp_path_retention_count = "2"
|
|
tmp_path_retention_policy = "failed"
|
|
|
|
|
|
## coverage.py settings ##
|
|
[tool.coverage.run]
|
|
branch = true
|
|
relative_files = true
|
|
source = ["airflow"]
|
|
omit = [
|
|
"airflow/_vendor/**",
|
|
"airflow/contrib/**",
|
|
"airflow/example_dags/**",
|
|
"airflow/migrations/**",
|
|
"airflow/providers/**/example_dags/**",
|
|
"airflow/www/node_modules/**",
|
|
"airflow/providers/google/ads/_vendor/**",
|
|
]
|
|
|
|
[tool.coverage.report]
|
|
skip_empty = true
|
|
exclude_also = [
|
|
"def __repr__",
|
|
"raise AssertionError",
|
|
"raise NotImplementedError",
|
|
"if __name__ == .__main__.:",
|
|
"@(abc\\.)?abstractmethod",
|
|
"@(typing(_extensions)?\\.)?overload",
|
|
"if (typing(_extensions)?\\.)?TYPE_CHECKING:"
|
|
]
|
|
|
|
|
|
## mypy settings ##
|
|
[tool.mypy]
|
|
ignore_missing_imports = true
|
|
no_implicit_optional = true
|
|
warn_redundant_casts = true
|
|
warn_unused_ignores = false
|
|
plugins = [
|
|
"dev/mypy/plugin/decorators.py",
|
|
"dev/mypy/plugin/outputs.py",
|
|
]
|
|
pretty = true
|
|
show_error_codes = true
|
|
disable_error_code = [
|
|
"annotation-unchecked",
|
|
]
|
|
|
|
[[tool.mypy.overrides]]
|
|
module="airflow.config_templates.default_webserver_config"
|
|
disable_error_code = [
|
|
"var-annotated",
|
|
]
|
|
|
|
[[tool.mypy.overrides]]
|
|
module="airflow.migrations.*"
|
|
ignore_errors = true
|
|
|
|
[[tool.mypy.overrides]]
|
|
module="airflow.*._vendor.*"
|
|
ignore_errors = true
|
|
|
|
[[tool.mypy.overrides]]
|
|
module= [
|
|
"google.cloud.*",
|
|
"azure.*",
|
|
]
|
|
no_implicit_optional = false
|
|
|
|
[[tool.mypy.overrides]]
|
|
module=[
|
|
"referencing.*",
|
|
# Beam has some old type annotations, and they introduced an error recently with bad signature of
|
|
# a function. This is captured in https://github.com/apache/beam/issues/29927
|
|
# and we should remove this exclusion when it is fixed.
|
|
"apache_beam.*"
|
|
]
|
|
ignore_errors = true
|