mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 10:58:28 +00:00

At a high level, this PR adds a smattering of new tests that effectively snapshot the output of `uv lock` for a selection of "ecosystem" projects. That is, real Python projects for which we expect `uv` to work well with. The main idea with these tests is to get a better idea of how changes in `uv` impact the lock files of real world projects. For example, we're hoping that these tests will help give us data for how #5733 differs from #5887. This has already revealed some bugs. Namely, re-running `uv lock` for a second time will produce a different lock file for some projects. So to prioritize getting the tests added, for those projects, we don't do the deterministic checking.
635 lines
27 KiB
TOML
635 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
|