diff --git a/crates/ruff_linter/resources/test/fixtures/airflow/AIR301_names.py b/crates/ruff_linter/resources/test/fixtures/airflow/AIR301_names.py index bd9606b91819e..ccab278a0fc18 100644 --- a/crates/ruff_linter/resources/test/fixtures/airflow/AIR301_names.py +++ b/crates/ruff_linter/resources/test/fixtures/airflow/AIR301_names.py @@ -9,9 +9,7 @@ PY311, PY312, ) -from airflow.api_connexion.security import requires_access, requires_access_dataset -from airflow.auth.managers.base_auth_manager import is_authorized_dataset -from airflow.auth.managers.models.resource_details import DatasetDetails +from airflow.api_connexion.security import requires_access from airflow.configuration import ( as_dict, get, @@ -24,32 +22,13 @@ ) from airflow.contrib.aws_athena_hook import AWSAthenaHook from airflow.datasets import DatasetAliasEvent -from airflow.datasets.manager import ( - DatasetManager, - dataset_manager, - resolve_dataset_manager, -) from airflow.hooks.base_hook import BaseHook -from airflow.lineage.hook import DatasetLineageInfo -from airflow.listeners.spec.dataset import on_dataset_changed, on_dataset_created -from airflow.metrics.validators import AllowListValidator, BlockListValidator from airflow.operators.subdag import SubDagOperator -from airflow.providers.amazon.aws.auth_manager.avp.entities import AvpEntities -from airflow.providers.amazon.aws.datasets import s3 -from airflow.providers.common.io.datasets import file as common_io_file -from airflow.providers.fab.auth_manager import fab_auth_manager -from airflow.providers.google.datasets import bigquery, gcs from airflow.providers.mysql.datasets import mysql -from airflow.providers.openlineage.utils.utils import ( - DatasetInfo, - translate_airflow_dataset, -) from airflow.providers.postgres.datasets import postgres from airflow.providers.trino.datasets import trino -from airflow.secrets.local_filesystem import LocalFilesystemBackend, load_connections -from airflow.security.permissions import RESOURCE_DATASET +from airflow.secrets.local_filesystem import LocalFilesystemBackend from airflow.sensors.base_sensor_operator import BaseSensorOperator -from airflow.timetables.simple import DatasetTriggeredTimetable from airflow.triggers.external_task import TaskStateTrigger from airflow.utils import dates from airflow.utils.dag_cycle_tester import test_cycle @@ -70,19 +49,15 @@ from airflow.utils.log import secrets_masker from airflow.utils.state import SHUTDOWN, terminating_states from airflow.utils.trigger_rule import TriggerRule -from airflow.www.auth import has_access, has_access_dataset +from airflow.www.auth import has_access from airflow.www.utils import get_sensitive_variables_fields, should_hide_value_for_key # airflow root PY36, PY37, PY38, PY39, PY310, PY311, PY312 -DatasetFromRoot() # airflow.api_connexion.security -requires_access, requires_access_dataset +requires_access -# airflow.auth.managers -is_authorized_dataset -DatasetDetails() # airflow.configuration get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set @@ -95,76 +70,17 @@ # airflow.datasets DatasetAliasEvent() -# airflow.datasets.manager -DatasetManager() -dataset_manager -resolve_dataset_manager # airflow.hooks BaseHook() -# airflow.lineage.hook -DatasetLineageInfo() - -# airflow.listeners.spec.dataset -on_dataset_changed -on_dataset_created - -# airflow.metrics.validators -AllowListValidator() -BlockListValidator() - - -# airflow.operators.branch_operator -BaseBranchOperator() - -# airflow.operators.dagrun_operator -TriggerDagRunLink() -TriggerDagRunOperator() - -# airflow.operators.email_operator -EmailOperator() - -# airflow.operators.latest_only_operator -LatestOnlyOperator() - -# airflow.operators.python_operator -BranchPythonOperator() -PythonOperator() -PythonVirtualenvOperator() -ShortCircuitOperator() # airflow.operators.subdag.* SubDagOperator() -# airflow.providers.amazon -AvpEntities.DATASET -s3.create_dataset -s3.convert_dataset_to_openlineage -s3.sanitize_uri - -# airflow.providers.common.io -common_io_file.convert_dataset_to_openlineage -common_io_file.create_dataset -common_io_file.sanitize_uri - -# airflow.providers.fab -fab_auth_manager.is_authorized_dataset - -# airflow.providers.google -bigquery.sanitize_uri - -gcs.create_dataset -gcs.sanitize_uri -gcs.convert_dataset_to_openlineage - # airflow.providers.mysql mysql.sanitize_uri -# airflow.providers.openlineage -DatasetInfo() -translate_airflow_dataset - # airflow.providers.postgres postgres.sanitize_uri @@ -174,18 +90,12 @@ # airflow.secrets # get_connection LocalFilesystemBackend() -load_connections -# airflow.security.permissions -RESOURCE_DATASET # airflow.sensors.base_sensor_operator BaseSensorOperator() -# airflow.timetables -DatasetTriggeredTimetable() - # airflow.triggers.external_task TaskStateTrigger() @@ -233,9 +143,9 @@ TriggerRule.DUMMY TriggerRule.NONE_FAILED_OR_SKIPPED + # airflow.www.auth has_access -has_access_dataset # airflow.www.utils get_sensitive_variables_fields diff --git a/crates/ruff_linter/resources/test/fixtures/airflow/AIR301_names_fix.py b/crates/ruff_linter/resources/test/fixtures/airflow/AIR301_names_fix.py new file mode 100644 index 0000000000000..d7c9414c5a75c --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/airflow/AIR301_names_fix.py @@ -0,0 +1,45 @@ +from __future__ import annotations + +from airflow.api_connexion.security import requires_access_dataset +from airflow.auth.managers.models.resource_details import ( + DatasetDetails, + is_authorized_dataset, +) +from airflow.datasets.manager import ( + DatasetManager, + dataset_manager, + resolve_dataset_manager, +) +from airflow.lineage.hook import DatasetLineageInfo +from airflow.metrics.validators import AllowListValidator, BlockListValidator +from airflow.secrets.local_filesystm import load_connections +from airflow.security.permissions import RESOURCE_DATASET +from airflow.www.auth import has_access_dataset + +requires_access_dataset() + +DatasetDetails() +is_authorized_dataset() + +DatasetManager() +dataset_manager() +resolve_dataset_manager() + +DatasetLineageInfo() + +AllowListValidator() +BlockListValidator() + +load_connections() + +RESOURCE_DATASET + +has_access_dataset() + +from airflow.listeners.spec.dataset import ( + on_dataset_changed, + on_dataset_created, +) + +on_dataset_created() +on_dataset_changed() diff --git a/crates/ruff_linter/resources/test/fixtures/airflow/AIR301_provider_names_fix.py b/crates/ruff_linter/resources/test/fixtures/airflow/AIR301_provider_names_fix.py new file mode 100644 index 0000000000000..99b77a7ebe181 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/airflow/AIR301_provider_names_fix.py @@ -0,0 +1,54 @@ +from __future__ import annotations + +from airflow.providers.amazon.aws.auth_manager.avp.entities.AvpEntities import DATASET +from airflow.providers.amazon.aws.datasets.s3 import ( + convert_dataset_to_openlineage as s3_convert_dataset_to_openlineage, +) +from airflow.providers.amazon.aws.datasets.s3 import create_dataset as s3_create_dataset +from airflow.providers.common.io.dataset.file import ( + convert_dataset_to_openlineage as io_convert_dataset_to_openlineage, +) +from airflow.providers.common.io.dataset.file import create_dataset as io_create_dataset +from airflow.providers.fab.auth_manager.fab_auth_manager import is_authorized_dataset as fab_is_authorized_dataset +from airflow.providers.google.datasets.bigquery import ( + create_dataset as bigquery_create_dataset, +) +from airflow.providers.google.datasets.gcs import ( + convert_dataset_to_openlineage as gcs_convert_dataset_to_openlineage, +) +from airflow.providers.google.datasets.gcs import create_dataset as gcs_create_dataset +from airflow.providers.openlineage.utils.utils import ( + DatasetInfo, + translate_airflow_dataset, +) + +DATASET + +s3_create_dataset() +s3_convert_dataset_to_openlineage() + +io_create_dataset() +io_convert_dataset_to_openlineage() + +fab_is_authorized_dataset() + +# airflow.providers.google.datasets.bigquery +bigquery_create_dataset() +# airflow.providers.google.datasets.gcs +gcs_create_dataset() +gcs_convert_dataset_to_openlineage() +# airflow.providers.openlineage.utils.utils +DatasetInfo() +translate_airflow_dataset() +# +# airflow.secrets.local_filesystem +load_connections() +# +# airflow.security.permissions +RESOURCE_DATASET + +# airflow.timetables +DatasetTriggeredTimetable() +# +# airflow.www.auth +has_access_dataset diff --git a/crates/ruff_linter/src/rules/airflow/mod.rs b/crates/ruff_linter/src/rules/airflow/mod.rs index 69a35b5dd3d26..744712b5d144e 100644 --- a/crates/ruff_linter/src/rules/airflow/mod.rs +++ b/crates/ruff_linter/src/rules/airflow/mod.rs @@ -17,6 +17,8 @@ mod tests { #[test_case(Rule::AirflowDagNoScheduleArgument, Path::new("AIR002.py"))] #[test_case(Rule::Airflow3Removal, Path::new("AIR301_args.py"))] #[test_case(Rule::Airflow3Removal, Path::new("AIR301_names.py"))] + #[test_case(Rule::Airflow3Removal, Path::new("AIR301_names_fix.py"))] + #[test_case(Rule::Airflow3Removal, Path::new("AIR301_provider_names_fix.py"))] #[test_case(Rule::Airflow3Removal, Path::new("AIR301_names_try.py"))] #[test_case(Rule::Airflow3Removal, Path::new("AIR301_class_attribute.py"))] #[test_case(Rule::Airflow3Removal, Path::new("AIR301_airflow_plugin.py"))] diff --git a/crates/ruff_linter/src/rules/airflow/rules/removal_in_3.rs b/crates/ruff_linter/src/rules/airflow/rules/removal_in_3.rs index b73bb11e519cc..a70403510323d 100644 --- a/crates/ruff_linter/src/rules/airflow/rules/removal_in_3.rs +++ b/crates/ruff_linter/src/rules/airflow/rules/removal_in_3.rs @@ -582,14 +582,16 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) { // airflow.auth.managers ["airflow", "auth", "managers", "models", "resource_details", "DatasetDetails"] => { - Replacement::Name( - "airflow.api_fastapi.auth.managers.models.resource_details.AssetDetails", - ) + Replacement::AutoImport { + module: "airflow.api_fastapi.auth.managers.models.resource_details", + name: "AssetDetails", + } } ["airflow", "auth", "managers", "base_auth_manager", "is_authorized_dataset"] => { - Replacement::Name( - "airflow.api_fastapi.auth.managers.base_auth_manager.is_authorized_asset", - ) + Replacement::AutoImport { + module: "airflow.api_fastapi.auth.managers.base_auth_manager", + name: "is_authorized_asset", + } } // airflow.configuration @@ -606,9 +608,18 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) { // airflow.datasets.manager ["airflow", "datasets", "manager", rest] => match *rest { - "DatasetManager" => Replacement::Name("airflow.assets.manager.AssetManager"), - "dataset_manager" => Replacement::Name("airflow.assets.manager.asset_manager"), - "resolve_dataset_manager" => Replacement::Name("airflow.assets.resolve_asset_manager"), + "DatasetManager" => Replacement::AutoImport { + module: "airflow.assets.manager", + name: "AssetManager", + }, + "dataset_manager" => Replacement::AutoImport { + module: "airflow.assets.manager", + name: "asset_manager", + }, + "resolve_dataset_manager" => Replacement::AutoImport { + module: "airflow.assets.manager", + name: "resolve_asset_manager", + }, _ => return, }, // airflow.datasets @@ -620,30 +631,35 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) { } // airflow.lineage.hook - ["airflow", "lineage", "hook", "DatasetLineageInfo"] => { - Replacement::Name("airflow.lineage.hook.AssetLineageInfo") - } + ["airflow", "lineage", "hook", "DatasetLineageInfo"] => Replacement::AutoImport { + module: "airflow.lineage.hook", + name: "AssetLineageInfo", + }, // airflow.listeners.spec // TODO: this is removed ["airflow", "listeners", "spec", "dataset", rest] => match *rest { - "on_dataset_created" => { - Replacement::Name("airflow.listeners.spec.asset.on_asset_created") - } - "on_dataset_changed" => { - Replacement::Name("airflow.listeners.spec.asset.on_asset_changed") - } + "on_dataset_created" => Replacement::AutoImport { + module: "airflow.listeners.spec.asset", + name: "on_asset_created", + }, + "on_dataset_changed" => Replacement::AutoImport { + module: "airflow.listeners.spec.asset", + name: "on_asset_changed", + }, _ => return, }, // airflow.metrics.validators ["airflow", "metrics", "validators", rest] => match *rest { - "AllowListValidator" => { - Replacement::Name("airflow.metrics.validators.PatternAllowListValidator") - } - "BlockListValidator" => { - Replacement::Name("airflow.metrics.validators.PatternBlockListValidator") - } + "AllowListValidator" => Replacement::AutoImport { + module: "airflow.metrics.validators", + name: "PatternAllowListValidator", + }, + "BlockListValidator" => Replacement::AutoImport { + module: "airflow.metrics.validators", + name: "PatternBlockListValidator", + }, _ => return, }, @@ -658,14 +674,16 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) { } // airflow.secrets - ["airflow", "secrets", "local_filesystem", "load_connections"] => { - Replacement::Name("airflow.secrets.local_filesystem.load_connections_dict") - } + ["airflow", "secrets", "local_filesystem", "load_connections"] => Replacement::AutoImport { + module: "airflow.secrets.local_filesystem", + name: "load_connections_dict", + }, // airflow.security - ["airflow", "security", "permissions", "RESOURCE_DATASET"] => { - Replacement::Name("airflow.security.permissions.RESOURCE_ASSET") - } + ["airflow", "security", "permissions", "RESOURCE_DATASET"] => Replacement::AutoImport { + module: "airflow.security.permissions", + name: "RESOURCE_ASSET", + }, // airflow.sensors ["airflow", "sensors", "base_sensor_operator", "BaseSensorOperator"] => { @@ -674,7 +692,10 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) { // airflow.timetables ["airflow", "timetables", "simple", "DatasetTriggeredTimetable"] => { - Replacement::Name("airflow.timetables.simple.AssetTriggeredTimetable") + Replacement::AutoImport { + module: "airflow.timetables.simple", + name: "AssetTriggeredTimetable", + } } // airflow.triggers @@ -733,9 +754,10 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) { ["airflow", "www", "auth", "has_access"] => { Replacement::Name("airflow.www.auth.has_access_*") } - ["airflow", "www", "auth", "has_access_dataset"] => { - Replacement::Name("airflow.www.auth.has_access_dataset") - } + ["airflow", "www", "auth", "has_access_dataset"] => Replacement::AutoImport { + module: "airflow.www.auth", + name: "has_access_asset", + }, ["airflow", "www", "utils", "get_sensitive_variables_fields"] => { Replacement::Name("airflow.utils.log.secrets_masker.get_sensitive_variables_fields") } @@ -744,31 +766,38 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) { } // airflow.providers.amazon - ["airflow", "providers", "amazon", "aws", rest @ ..] => match &rest { - ["datasets", "s3", "create_dataset"] => { - Replacement::Name("airflow.providers.amazon.aws.assets.s3.create_asset") - } - ["datasets", "s3", "convert_dataset_to_openlineage"] => Replacement::Name( - "airflow.providers.amazon.aws.assets.s3.convert_asset_to_openlineage", - ), - ["datasets", "s3", "sanitize_uri"] => { + ["airflow", "providers", "amazon", "aws", "datasets", "s3", rest] => match *rest { + "create_dataset" => Replacement::AutoImport { + module: "airflow.providers.amazon.aws.assets.s3", + name: "create_asset", + }, + "convert_dataset_to_openlineage" => Replacement::AutoImport { + module: "airflow.providers.amazon.aws.assets.s3", + name: "convert_asset_to_openlineage", + }, + "sanitize_uri" => { Replacement::Name("airflow.providers.amazon.aws.assets.s3.sanitize_uri") } - ["auth_manager", "avp", "entities", "AvpEntities", "DATASET"] => Replacement::Name( - "airflow.providers.amazon.aws.auth_manager.avp.entities.AvpEntities.ASSET", - ), _ => return, }, + ["airflow", "providers", "amazon", "aws", "auth_manager", "avp", "entities", "AvpEntities", "DATASET"] => { + Replacement::AutoImport { + module: "airflow.providers.amazon.aws.auth_manager.avp.entities.AvpEntities", + name: "ASSET", + } + } // airflow.providers.common.io // airflow.providers.common.io.datasets.file ["airflow", "providers", "common", "io", "datasets", "file", rest] => match *rest { - "create_dataset" => { - Replacement::Name("airflow.providers.common.io.assets.file.create_asset") - } - "convert_dataset_to_openlineage" => Replacement::Name( - "airflow.providers.common.io.assets.file.convert_asset_to_openlineage", - ), + "create_dataset" => Replacement::AutoImport { + module: "airflow.providers.common.io.assets.file", + name: "create_asset", + }, + "convert_dataset_to_openlineage" => Replacement::AutoImport { + module: "airflow.providers.common.io.assets.file", + name: "convert_asset_to_openlineage", + }, "sanitize_uri" => { Replacement::Name("airflow.providers.common.io.assets.file.sanitize_uri") } @@ -777,23 +806,27 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) { // airflow.providers.fab ["airflow", "providers", "fab", "auth_manager", "fab_auth_manager", "is_authorized_dataset"] => { - Replacement::Name( - "airflow.providers.fab.auth_manager.fab_auth_manager.is_authorized_asset", - ) + Replacement::AutoImport { + module: "airflow.providers.fab.auth_manager.fab_auth_manager", + name: "is_authorized_asset", + } } // airflow.providers.google // airflow.providers.google.datasets ["airflow", "providers", "google", "datasets", rest @ ..] => match &rest { - ["bigquery", "create_dataset"] => { - Replacement::Name("airflow.providers.google.assets.bigquery.create_asset") - } - ["gcs", "create_dataset"] => { - Replacement::Name("airflow.providers.google.assets.gcs.create_asset") - } - ["gcs", "convert_dataset_to_openlineage"] => Replacement::Name( - "airflow.providers.google.assets.gcs.convert_asset_to_openlineage", - ), + ["bigquery", "create_dataset"] => Replacement::AutoImport { + module: "airflow.providers.google.assets.bigquery", + name: "create_asset", + }, + ["gcs", "create_dataset"] => Replacement::AutoImport { + module: "airflow.providers.google.assets.gcs", + name: "create_asset", + }, + ["gcs", "convert_dataset_to_openlineage"] => Replacement::AutoImport { + module: "airflow.providers.google.assets.gcs", + name: "convert_asset_to_openlineage", + }, ["gcs", "sanitize_uri"] => { Replacement::Name("airflow.providers.google.assets.gcs.sanitize_uri") } @@ -813,13 +846,15 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) { // airflow.providers.openlineage // airflow.providers.openlineage.utils.utils ["airflow", "providers", "openlineage", "utils", "utils", rest] => match *rest { - "DatasetInfo" => { - Replacement::Name("airflow.providers.openlineage.utils.utils.AssetInfo") - } + "DatasetInfo" => Replacement::AutoImport { + module: "airflow.providers.openlineage.utils.utils", + name: "AssetInfo", + }, - "translate_airflow_dataset" => Replacement::Name( - "airflow.providers.openlineage.utils.utils.translate_airflow_asset", - ), + "translate_airflow_dataset" => Replacement::AutoImport { + module: "airflow.providers.openlineage.utils.utils", + name: "translate_airflow_asset", + }, _ => return, }, diff --git a/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR301_AIR301_class_attribute.py.snap b/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR301_AIR301_class_attribute.py.snap index 7d69175385d0b..0ae63a796b112 100644 --- a/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR301_AIR301_class_attribute.py.snap +++ b/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR301_AIR301_class_attribute.py.snap @@ -163,7 +163,7 @@ AIR301_class_attribute.py:39:25: AIR301 [*] `iter_dataset_aliases` is removed in 41 41 | # airflow.datasets.manager 42 42 | dm = DatasetManager() -AIR301_class_attribute.py:42:6: AIR301 `airflow.datasets.manager.DatasetManager` is removed in Airflow 3.0 +AIR301_class_attribute.py:42:6: AIR301 [*] `airflow.datasets.manager.DatasetManager` is removed in Airflow 3.0 | 41 | # airflow.datasets.manager 42 | dm = DatasetManager() @@ -173,6 +173,24 @@ AIR301_class_attribute.py:42:6: AIR301 `airflow.datasets.manager.DatasetManager` | = help: Use `airflow.assets.manager.AssetManager` instead +ℹ Safe fix +19 19 | from airflow.providers_manager import ProvidersManager +20 20 | from airflow.secrets.base_secrets import BaseSecretsBackend +21 21 | from airflow.secrets.local_filesystem import LocalFilesystemBackend + 22 |+from airflow.assets.manager import AssetManager +22 23 | +23 24 | # airflow.Dataset +24 25 | dataset_from_root = DatasetFromRoot() +-------------------------------------------------------------------------------- +39 40 | any_to_test_method_call.iter_dataset_aliases() +40 41 | +41 42 | # airflow.datasets.manager +42 |-dm = DatasetManager() + 43 |+dm = AssetManager() +43 44 | dm.register_dataset_change() +44 45 | dm.create_datasets() +45 46 | dm.notify_dataset_created() + AIR301_class_attribute.py:43:4: AIR301 [*] `register_dataset_change` is removed in Airflow 3.0 | 41 | # airflow.datasets.manager @@ -277,7 +295,7 @@ AIR301_class_attribute.py:47:4: AIR301 [*] `notify_dataset_alias_created` is rem 49 49 | # airflow.lineage.hook 50 50 | dl_info = DatasetLineageInfo() -AIR301_class_attribute.py:50:11: AIR301 `airflow.lineage.hook.DatasetLineageInfo` is removed in Airflow 3.0 +AIR301_class_attribute.py:50:11: AIR301 [*] `airflow.lineage.hook.DatasetLineageInfo` is removed in Airflow 3.0 | 49 | # airflow.lineage.hook 50 | dl_info = DatasetLineageInfo() @@ -286,6 +304,25 @@ AIR301_class_attribute.py:50:11: AIR301 `airflow.lineage.hook.DatasetLineageInfo | = help: Use `airflow.lineage.hook.AssetLineageInfo` instead +ℹ Safe fix +9 9 | DatasetAny, +10 10 | ) +11 11 | from airflow.datasets.manager import DatasetManager +12 |-from airflow.lineage.hook import DatasetLineageInfo, HookLineageCollector + 12 |+from airflow.lineage.hook import DatasetLineageInfo, HookLineageCollector, AssetLineageInfo +13 13 | from airflow.providers.amazon.auth_manager.aws_auth_manager import AwsAuthManager +14 14 | from airflow.providers.apache.beam.hooks import BeamHook, NotAir302HookError +15 15 | from airflow.providers.google.cloud.secrets.secret_manager import ( +-------------------------------------------------------------------------------- +47 47 | dm.notify_dataset_alias_created() +48 48 | +49 49 | # airflow.lineage.hook +50 |-dl_info = DatasetLineageInfo() + 50 |+dl_info = AssetLineageInfo() +51 51 | dl_info.dataset +52 52 | +53 53 | hlc = HookLineageCollector() + AIR301_class_attribute.py:51:9: AIR301 [*] `dataset` is removed in Airflow 3.0 | 49 | # airflow.lineage.hook diff --git a/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR301_AIR301_names.py.snap b/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR301_AIR301_names.py.snap index 0943b18e5980d..8c58bcb351eff 100644 --- a/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR301_AIR301_names.py.snap +++ b/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR301_AIR301_names.py.snap @@ -1,741 +1,437 @@ --- source: crates/ruff_linter/src/rules/airflow/mod.rs --- -AIR301_names.py:77:1: AIR301 `airflow.PY36` is removed in Airflow 3.0 +AIR301_names.py:56:1: AIR301 `airflow.PY36` is removed in Airflow 3.0 | -76 | # airflow root -77 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 +55 | # airflow root +56 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 | ^^^^ AIR301 -78 | DatasetFromRoot() +57 | +58 | # airflow.api_connexion.security | = help: Use `sys.version_info` instead -AIR301_names.py:77:7: AIR301 `airflow.PY37` is removed in Airflow 3.0 +AIR301_names.py:56:7: AIR301 `airflow.PY37` is removed in Airflow 3.0 | -76 | # airflow root -77 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 +55 | # airflow root +56 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 | ^^^^ AIR301 -78 | DatasetFromRoot() +57 | +58 | # airflow.api_connexion.security | = help: Use `sys.version_info` instead -AIR301_names.py:77:13: AIR301 `airflow.PY38` is removed in Airflow 3.0 +AIR301_names.py:56:13: AIR301 `airflow.PY38` is removed in Airflow 3.0 | -76 | # airflow root -77 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 +55 | # airflow root +56 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 | ^^^^ AIR301 -78 | DatasetFromRoot() +57 | +58 | # airflow.api_connexion.security | = help: Use `sys.version_info` instead -AIR301_names.py:77:19: AIR301 `airflow.PY39` is removed in Airflow 3.0 +AIR301_names.py:56:19: AIR301 `airflow.PY39` is removed in Airflow 3.0 | -76 | # airflow root -77 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 +55 | # airflow root +56 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 | ^^^^ AIR301 -78 | DatasetFromRoot() +57 | +58 | # airflow.api_connexion.security | = help: Use `sys.version_info` instead -AIR301_names.py:77:25: AIR301 `airflow.PY310` is removed in Airflow 3.0 +AIR301_names.py:56:25: AIR301 `airflow.PY310` is removed in Airflow 3.0 | -76 | # airflow root -77 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 +55 | # airflow root +56 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 | ^^^^^ AIR301 -78 | DatasetFromRoot() +57 | +58 | # airflow.api_connexion.security | = help: Use `sys.version_info` instead -AIR301_names.py:77:32: AIR301 `airflow.PY311` is removed in Airflow 3.0 +AIR301_names.py:56:32: AIR301 `airflow.PY311` is removed in Airflow 3.0 | -76 | # airflow root -77 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 +55 | # airflow root +56 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 | ^^^^^ AIR301 -78 | DatasetFromRoot() +57 | +58 | # airflow.api_connexion.security | = help: Use `sys.version_info` instead -AIR301_names.py:77:39: AIR301 `airflow.PY312` is removed in Airflow 3.0 +AIR301_names.py:56:39: AIR301 `airflow.PY312` is removed in Airflow 3.0 | -76 | # airflow root -77 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 +55 | # airflow root +56 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 | ^^^^^ AIR301 -78 | DatasetFromRoot() +57 | +58 | # airflow.api_connexion.security | = help: Use `sys.version_info` instead -AIR301_names.py:81:1: AIR301 `airflow.api_connexion.security.requires_access` is removed in Airflow 3.0 +AIR301_names.py:59:1: AIR301 `airflow.api_connexion.security.requires_access` is removed in Airflow 3.0 | -80 | # airflow.api_connexion.security -81 | requires_access, requires_access_dataset +58 | # airflow.api_connexion.security +59 | requires_access | ^^^^^^^^^^^^^^^ AIR301 -82 | -83 | # airflow.auth.managers | = help: Use `airflow.api_connexion.security.requires_access_*` instead -AIR301_names.py:81:18: AIR301 [*] `airflow.api_connexion.security.requires_access_dataset` is removed in Airflow 3.0 - | -80 | # airflow.api_connexion.security -81 | requires_access, requires_access_dataset - | ^^^^^^^^^^^^^^^^^^^^^^^ AIR301 -82 | -83 | # airflow.auth.managers - | - = help: Use `airflow.api_connexion.security.requires_access_asset` instead - -ℹ Safe fix -9 9 | PY311, -10 10 | PY312, -11 11 | ) -12 |-from airflow.api_connexion.security import requires_access, requires_access_dataset - 12 |+from airflow.api_connexion.security import requires_access, requires_access_dataset, requires_access_asset -13 13 | from airflow.auth.managers.base_auth_manager import is_authorized_dataset -14 14 | from airflow.auth.managers.models.resource_details import DatasetDetails -15 15 | from airflow.configuration import ( --------------------------------------------------------------------------------- -78 78 | DatasetFromRoot() -79 79 | -80 80 | # airflow.api_connexion.security -81 |-requires_access, requires_access_dataset - 81 |+requires_access, requires_access_asset -82 82 | -83 83 | # airflow.auth.managers -84 84 | is_authorized_dataset - -AIR301_names.py:84:1: AIR301 `airflow.auth.managers.base_auth_manager.is_authorized_dataset` is removed in Airflow 3.0 - | -83 | # airflow.auth.managers -84 | is_authorized_dataset - | ^^^^^^^^^^^^^^^^^^^^^ AIR301 -85 | DatasetDetails() - | - = help: Use `airflow.api_fastapi.auth.managers.base_auth_manager.is_authorized_asset` instead - -AIR301_names.py:85:1: AIR301 `airflow.auth.managers.models.resource_details.DatasetDetails` is removed in Airflow 3.0 - | -83 | # airflow.auth.managers -84 | is_authorized_dataset -85 | DatasetDetails() - | ^^^^^^^^^^^^^^ AIR301 -86 | -87 | # airflow.configuration - | - = help: Use `airflow.api_fastapi.auth.managers.models.resource_details.AssetDetails` instead - -AIR301_names.py:88:1: AIR301 `airflow.configuration.get` is removed in Airflow 3.0 +AIR301_names.py:63:1: AIR301 `airflow.configuration.get` is removed in Airflow 3.0 | -87 | # airflow.configuration -88 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set +62 | # airflow.configuration +63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set | ^^^ AIR301 | = help: Use `airflow.configuration.conf.get` instead -AIR301_names.py:88:6: AIR301 `airflow.configuration.getboolean` is removed in Airflow 3.0 +AIR301_names.py:63:6: AIR301 `airflow.configuration.getboolean` is removed in Airflow 3.0 | -87 | # airflow.configuration -88 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set +62 | # airflow.configuration +63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set | ^^^^^^^^^^ AIR301 | = help: Use `airflow.configuration.conf.getboolean` instead -AIR301_names.py:88:18: AIR301 `airflow.configuration.getfloat` is removed in Airflow 3.0 +AIR301_names.py:63:18: AIR301 `airflow.configuration.getfloat` is removed in Airflow 3.0 | -87 | # airflow.configuration -88 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set +62 | # airflow.configuration +63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set | ^^^^^^^^ AIR301 | = help: Use `airflow.configuration.conf.getfloat` instead -AIR301_names.py:88:28: AIR301 `airflow.configuration.getint` is removed in Airflow 3.0 +AIR301_names.py:63:28: AIR301 `airflow.configuration.getint` is removed in Airflow 3.0 | -87 | # airflow.configuration -88 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set +62 | # airflow.configuration +63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set | ^^^^^^ AIR301 | = help: Use `airflow.configuration.conf.getint` instead -AIR301_names.py:88:36: AIR301 `airflow.configuration.has_option` is removed in Airflow 3.0 +AIR301_names.py:63:36: AIR301 `airflow.configuration.has_option` is removed in Airflow 3.0 | -87 | # airflow.configuration -88 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set +62 | # airflow.configuration +63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set | ^^^^^^^^^^ AIR301 | = help: Use `airflow.configuration.conf.has_option` instead -AIR301_names.py:88:48: AIR301 `airflow.configuration.remove_option` is removed in Airflow 3.0 +AIR301_names.py:63:48: AIR301 `airflow.configuration.remove_option` is removed in Airflow 3.0 | -87 | # airflow.configuration -88 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set +62 | # airflow.configuration +63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set | ^^^^^^^^^^^^^ AIR301 | = help: Use `airflow.configuration.conf.remove_option` instead -AIR301_names.py:88:63: AIR301 `airflow.configuration.as_dict` is removed in Airflow 3.0 +AIR301_names.py:63:63: AIR301 `airflow.configuration.as_dict` is removed in Airflow 3.0 | -87 | # airflow.configuration -88 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set +62 | # airflow.configuration +63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set | ^^^^^^^ AIR301 | = help: Use `airflow.configuration.conf.as_dict` instead -AIR301_names.py:88:72: AIR301 `airflow.configuration.set` is removed in Airflow 3.0 +AIR301_names.py:63:72: AIR301 `airflow.configuration.set` is removed in Airflow 3.0 | -87 | # airflow.configuration -88 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set +62 | # airflow.configuration +63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set | ^^^ AIR301 | = help: Use `airflow.configuration.conf.set` instead -AIR301_names.py:92:1: AIR301 `airflow.contrib.aws_athena_hook.AWSAthenaHook` is removed in Airflow 3.0; The whole `airflow.contrib` module has been removed. +AIR301_names.py:67:1: AIR301 `airflow.contrib.aws_athena_hook.AWSAthenaHook` is removed in Airflow 3.0; The whole `airflow.contrib` module has been removed. | -91 | # airflow.contrib.* -92 | AWSAthenaHook() +66 | # airflow.contrib.* +67 | AWSAthenaHook() | ^^^^^^^^^^^^^ AIR301 | -AIR301_names.py:96:1: AIR301 `airflow.datasets.DatasetAliasEvent` is removed in Airflow 3.0 +AIR301_names.py:71:1: AIR301 `airflow.datasets.DatasetAliasEvent` is removed in Airflow 3.0 | -95 | # airflow.datasets -96 | DatasetAliasEvent() +70 | # airflow.datasets +71 | DatasetAliasEvent() | ^^^^^^^^^^^^^^^^^ AIR301 -97 | -98 | # airflow.datasets.manager | -AIR301_names.py:99:1: AIR301 `airflow.datasets.manager.DatasetManager` is removed in Airflow 3.0 - | - 98 | # airflow.datasets.manager - 99 | DatasetManager() - | ^^^^^^^^^^^^^^ AIR301 -100 | dataset_manager -101 | resolve_dataset_manager - | - = help: Use `airflow.assets.manager.AssetManager` instead - -AIR301_names.py:100:1: AIR301 `airflow.datasets.manager.dataset_manager` is removed in Airflow 3.0 - | - 98 | # airflow.datasets.manager - 99 | DatasetManager() -100 | dataset_manager - | ^^^^^^^^^^^^^^^ AIR301 -101 | resolve_dataset_manager - | - = help: Use `airflow.assets.manager.asset_manager` instead - -AIR301_names.py:101:1: AIR301 `airflow.datasets.manager.resolve_dataset_manager` is removed in Airflow 3.0 - | - 99 | DatasetManager() -100 | dataset_manager -101 | resolve_dataset_manager - | ^^^^^^^^^^^^^^^^^^^^^^^ AIR301 -102 | -103 | # airflow.hooks - | - = help: Use `airflow.assets.resolve_asset_manager` instead - -AIR301_names.py:104:1: AIR301 `airflow.hooks.base_hook.BaseHook` is removed in Airflow 3.0 - | -103 | # airflow.hooks -104 | BaseHook() - | ^^^^^^^^ AIR301 -105 | -106 | # airflow.lineage.hook - | - = help: Use `airflow.hooks.base.BaseHook` instead - -AIR301_names.py:107:1: AIR301 `airflow.lineage.hook.DatasetLineageInfo` is removed in Airflow 3.0 - | -106 | # airflow.lineage.hook -107 | DatasetLineageInfo() - | ^^^^^^^^^^^^^^^^^^ AIR301 -108 | -109 | # airflow.listeners.spec.dataset - | - = help: Use `airflow.lineage.hook.AssetLineageInfo` instead - -AIR301_names.py:110:1: AIR301 `airflow.listeners.spec.dataset.on_dataset_changed` is removed in Airflow 3.0 - | -109 | # airflow.listeners.spec.dataset -110 | on_dataset_changed - | ^^^^^^^^^^^^^^^^^^ AIR301 -111 | on_dataset_created - | - = help: Use `airflow.listeners.spec.asset.on_asset_changed` instead - -AIR301_names.py:111:1: AIR301 `airflow.listeners.spec.dataset.on_dataset_created` is removed in Airflow 3.0 - | -109 | # airflow.listeners.spec.dataset -110 | on_dataset_changed -111 | on_dataset_created - | ^^^^^^^^^^^^^^^^^^ AIR301 -112 | -113 | # airflow.metrics.validators - | - = help: Use `airflow.listeners.spec.asset.on_asset_created` instead - -AIR301_names.py:114:1: AIR301 `airflow.metrics.validators.AllowListValidator` is removed in Airflow 3.0 - | -113 | # airflow.metrics.validators -114 | AllowListValidator() - | ^^^^^^^^^^^^^^^^^^ AIR301 -115 | BlockListValidator() - | - = help: Use `airflow.metrics.validators.PatternAllowListValidator` instead - -AIR301_names.py:115:1: AIR301 `airflow.metrics.validators.BlockListValidator` is removed in Airflow 3.0 - | -113 | # airflow.metrics.validators -114 | AllowListValidator() -115 | BlockListValidator() - | ^^^^^^^^^^^^^^^^^^ AIR301 - | - = help: Use `airflow.metrics.validators.PatternBlockListValidator` instead - -AIR301_names.py:138:1: AIR301 `airflow.operators.subdag.SubDagOperator` is removed in Airflow 3.0; The whole `airflow.subdag` module has been removed. - | -137 | # airflow.operators.subdag.* -138 | SubDagOperator() - | ^^^^^^^^^^^^^^ AIR301 -139 | -140 | # airflow.providers.amazon - | - -AIR301_names.py:141:13: AIR301 `airflow.providers.amazon.aws.auth_manager.avp.entities.AvpEntities.DATASET` is removed in Airflow 3.0 - | -140 | # airflow.providers.amazon -141 | AvpEntities.DATASET - | ^^^^^^^ AIR301 -142 | s3.create_dataset -143 | s3.convert_dataset_to_openlineage - | - = help: Use `airflow.providers.amazon.aws.auth_manager.avp.entities.AvpEntities.ASSET` instead - -AIR301_names.py:142:4: AIR301 `airflow.providers.amazon.aws.datasets.s3.create_dataset` is removed in Airflow 3.0 - | -140 | # airflow.providers.amazon -141 | AvpEntities.DATASET -142 | s3.create_dataset - | ^^^^^^^^^^^^^^ AIR301 -143 | s3.convert_dataset_to_openlineage -144 | s3.sanitize_uri - | - = help: Use `airflow.providers.amazon.aws.assets.s3.create_asset` instead - -AIR301_names.py:143:4: AIR301 `airflow.providers.amazon.aws.datasets.s3.convert_dataset_to_openlineage` is removed in Airflow 3.0 - | -141 | AvpEntities.DATASET -142 | s3.create_dataset -143 | s3.convert_dataset_to_openlineage - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301 -144 | s3.sanitize_uri - | - = help: Use `airflow.providers.amazon.aws.assets.s3.convert_asset_to_openlineage` instead - -AIR301_names.py:144:4: AIR301 `airflow.providers.amazon.aws.datasets.s3.sanitize_uri` is removed in Airflow 3.0 - | -142 | s3.create_dataset -143 | s3.convert_dataset_to_openlineage -144 | s3.sanitize_uri - | ^^^^^^^^^^^^ AIR301 -145 | -146 | # airflow.providers.common.io - | - = help: Use `airflow.providers.amazon.aws.assets.s3.sanitize_uri` instead - -AIR301_names.py:147:16: AIR301 `airflow.providers.common.io.datasets.file.convert_dataset_to_openlineage` is removed in Airflow 3.0 - | -146 | # airflow.providers.common.io -147 | common_io_file.convert_dataset_to_openlineage - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301 -148 | common_io_file.create_dataset -149 | common_io_file.sanitize_uri - | - = help: Use `airflow.providers.common.io.assets.file.convert_asset_to_openlineage` instead - -AIR301_names.py:148:16: AIR301 `airflow.providers.common.io.datasets.file.create_dataset` is removed in Airflow 3.0 - | -146 | # airflow.providers.common.io -147 | common_io_file.convert_dataset_to_openlineage -148 | common_io_file.create_dataset - | ^^^^^^^^^^^^^^ AIR301 -149 | common_io_file.sanitize_uri - | - = help: Use `airflow.providers.common.io.assets.file.create_asset` instead - -AIR301_names.py:149:16: AIR301 `airflow.providers.common.io.datasets.file.sanitize_uri` is removed in Airflow 3.0 - | -147 | common_io_file.convert_dataset_to_openlineage -148 | common_io_file.create_dataset -149 | common_io_file.sanitize_uri - | ^^^^^^^^^^^^ AIR301 -150 | -151 | # airflow.providers.fab - | - = help: Use `airflow.providers.common.io.assets.file.sanitize_uri` instead - -AIR301_names.py:152:18: AIR301 `airflow.providers.fab.auth_manager.fab_auth_manager.is_authorized_dataset` is removed in Airflow 3.0 - | -151 | # airflow.providers.fab -152 | fab_auth_manager.is_authorized_dataset - | ^^^^^^^^^^^^^^^^^^^^^ AIR301 -153 | -154 | # airflow.providers.google - | - = help: Use `airflow.providers.fab.auth_manager.fab_auth_manager.is_authorized_asset` instead - -AIR301_names.py:157:5: AIR301 `airflow.providers.google.datasets.gcs.create_dataset` is removed in Airflow 3.0 - | -155 | bigquery.sanitize_uri -156 | -157 | gcs.create_dataset - | ^^^^^^^^^^^^^^ AIR301 -158 | gcs.sanitize_uri -159 | gcs.convert_dataset_to_openlineage - | - = help: Use `airflow.providers.google.assets.gcs.create_asset` instead - -AIR301_names.py:158:5: AIR301 `airflow.providers.google.datasets.gcs.sanitize_uri` is removed in Airflow 3.0 - | -157 | gcs.create_dataset -158 | gcs.sanitize_uri - | ^^^^^^^^^^^^ AIR301 -159 | gcs.convert_dataset_to_openlineage - | - = help: Use `airflow.providers.google.assets.gcs.sanitize_uri` instead - -AIR301_names.py:159:5: AIR301 `airflow.providers.google.datasets.gcs.convert_dataset_to_openlineage` is removed in Airflow 3.0 - | -157 | gcs.create_dataset -158 | gcs.sanitize_uri -159 | gcs.convert_dataset_to_openlineage - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301 -160 | -161 | # airflow.providers.mysql - | - = help: Use `airflow.providers.google.assets.gcs.convert_asset_to_openlineage` instead - -AIR301_names.py:162:7: AIR301 `airflow.providers.mysql.datasets.mysql.sanitize_uri` is removed in Airflow 3.0 - | -161 | # airflow.providers.mysql -162 | mysql.sanitize_uri - | ^^^^^^^^^^^^ AIR301 -163 | -164 | # airflow.providers.openlineage - | - = help: Use `airflow.providers.mysql.assets.mysql.sanitize_uri` instead - -AIR301_names.py:165:1: AIR301 `airflow.providers.openlineage.utils.utils.DatasetInfo` is removed in Airflow 3.0 - | -164 | # airflow.providers.openlineage -165 | DatasetInfo() - | ^^^^^^^^^^^ AIR301 -166 | translate_airflow_dataset - | - = help: Use `airflow.providers.openlineage.utils.utils.AssetInfo` instead - -AIR301_names.py:166:1: AIR301 `airflow.providers.openlineage.utils.utils.translate_airflow_dataset` is removed in Airflow 3.0 - | -164 | # airflow.providers.openlineage -165 | DatasetInfo() -166 | translate_airflow_dataset - | ^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301 -167 | -168 | # airflow.providers.postgres - | - = help: Use `airflow.providers.openlineage.utils.utils.translate_airflow_asset` instead - -AIR301_names.py:169:10: AIR301 `airflow.providers.postgres.datasets.postgres.sanitize_uri` is removed in Airflow 3.0 - | -168 | # airflow.providers.postgres -169 | postgres.sanitize_uri - | ^^^^^^^^^^^^ AIR301 -170 | -171 | # airflow.providers.trino - | - = help: Use `airflow.providers.postgres.assets.postgres.sanitize_uri` instead +AIR301_names.py:75:1: AIR301 `airflow.hooks.base_hook.BaseHook` is removed in Airflow 3.0 + | +74 | # airflow.hooks +75 | BaseHook() + | ^^^^^^^^ AIR301 + | + = help: Use `airflow.hooks.base.BaseHook` instead -AIR301_names.py:172:7: AIR301 `airflow.providers.trino.datasets.trino.sanitize_uri` is removed in Airflow 3.0 - | -171 | # airflow.providers.trino -172 | trino.sanitize_uri - | ^^^^^^^^^^^^ AIR301 -173 | -174 | # airflow.secrets - | - = help: Use `airflow.providers.trino.assets.trino.sanitize_uri` instead +AIR301_names.py:79:1: AIR301 `airflow.operators.subdag.SubDagOperator` is removed in Airflow 3.0; The whole `airflow.subdag` module has been removed. + | +78 | # airflow.operators.subdag.* +79 | SubDagOperator() + | ^^^^^^^^^^^^^^ AIR301 +80 | +81 | # airflow.providers.mysql + | -AIR301_names.py:177:1: AIR301 `airflow.secrets.local_filesystem.load_connections` is removed in Airflow 3.0 - | -175 | # get_connection -176 | LocalFilesystemBackend() -177 | load_connections - | ^^^^^^^^^^^^^^^^ AIR301 -178 | -179 | # airflow.security.permissions - | - = help: Use `airflow.secrets.local_filesystem.load_connections_dict` instead +AIR301_names.py:82:7: AIR301 `airflow.providers.mysql.datasets.mysql.sanitize_uri` is removed in Airflow 3.0 + | +81 | # airflow.providers.mysql +82 | mysql.sanitize_uri + | ^^^^^^^^^^^^ AIR301 +83 | +84 | # airflow.providers.postgres + | + = help: Use `airflow.providers.mysql.assets.mysql.sanitize_uri` instead -AIR301_names.py:180:1: AIR301 `airflow.security.permissions.RESOURCE_DATASET` is removed in Airflow 3.0 - | -179 | # airflow.security.permissions -180 | RESOURCE_DATASET - | ^^^^^^^^^^^^^^^^ AIR301 -181 | -182 | # airflow.sensors.base_sensor_operator - | - = help: Use `airflow.security.permissions.RESOURCE_ASSET` instead +AIR301_names.py:85:10: AIR301 `airflow.providers.postgres.datasets.postgres.sanitize_uri` is removed in Airflow 3.0 + | +84 | # airflow.providers.postgres +85 | postgres.sanitize_uri + | ^^^^^^^^^^^^ AIR301 +86 | +87 | # airflow.providers.trino + | + = help: Use `airflow.providers.postgres.assets.postgres.sanitize_uri` instead -AIR301_names.py:183:1: AIR301 `airflow.sensors.base_sensor_operator.BaseSensorOperator` is removed in Airflow 3.0 - | -182 | # airflow.sensors.base_sensor_operator -183 | BaseSensorOperator() - | ^^^^^^^^^^^^^^^^^^ AIR301 - | - = help: Use `airflow.sdk.bases.sensor.BaseSensorOperator` instead +AIR301_names.py:88:7: AIR301 `airflow.providers.trino.datasets.trino.sanitize_uri` is removed in Airflow 3.0 + | +87 | # airflow.providers.trino +88 | trino.sanitize_uri + | ^^^^^^^^^^^^ AIR301 +89 | +90 | # airflow.secrets + | + = help: Use `airflow.providers.trino.assets.trino.sanitize_uri` instead -AIR301_names.py:187:1: AIR301 `airflow.timetables.simple.DatasetTriggeredTimetable` is removed in Airflow 3.0 - | -186 | # airflow.timetables -187 | DatasetTriggeredTimetable() - | ^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301 -188 | -189 | # airflow.triggers.external_task - | - = help: Use `airflow.timetables.simple.AssetTriggeredTimetable` instead +AIR301_names.py:96:1: AIR301 `airflow.sensors.base_sensor_operator.BaseSensorOperator` is removed in Airflow 3.0 + | +95 | # airflow.sensors.base_sensor_operator +96 | BaseSensorOperator() + | ^^^^^^^^^^^^^^^^^^ AIR301 + | + = help: Use `airflow.sdk.bases.sensor.BaseSensorOperator` instead -AIR301_names.py:190:1: AIR301 `airflow.triggers.external_task.TaskStateTrigger` is removed in Airflow 3.0 +AIR301_names.py:100:1: AIR301 `airflow.triggers.external_task.TaskStateTrigger` is removed in Airflow 3.0 | -189 | # airflow.triggers.external_task -190 | TaskStateTrigger() + 99 | # airflow.triggers.external_task +100 | TaskStateTrigger() | ^^^^^^^^^^^^^^^^ AIR301 -191 | -192 | # airflow.utils.date +101 | +102 | # airflow.utils.date | -AIR301_names.py:193:7: AIR301 `airflow.utils.dates.date_range` is removed in Airflow 3.0 +AIR301_names.py:103:7: AIR301 `airflow.utils.dates.date_range` is removed in Airflow 3.0 | -192 | # airflow.utils.date -193 | dates.date_range +102 | # airflow.utils.date +103 | dates.date_range | ^^^^^^^^^^ AIR301 -194 | dates.days_ago +104 | dates.days_ago | -AIR301_names.py:194:7: AIR301 `airflow.utils.dates.days_ago` is removed in Airflow 3.0 +AIR301_names.py:104:7: AIR301 `airflow.utils.dates.days_ago` is removed in Airflow 3.0 | -192 | # airflow.utils.date -193 | dates.date_range -194 | dates.days_ago +102 | # airflow.utils.date +103 | dates.date_range +104 | dates.days_ago | ^^^^^^^^ AIR301 -195 | -196 | date_range +105 | +106 | date_range | = help: Use `pendulum.today('UTC').add(days=-N, ...)` instead -AIR301_names.py:196:1: AIR301 `airflow.utils.dates.date_range` is removed in Airflow 3.0 +AIR301_names.py:106:1: AIR301 `airflow.utils.dates.date_range` is removed in Airflow 3.0 | -194 | dates.days_ago -195 | -196 | date_range +104 | dates.days_ago +105 | +106 | date_range | ^^^^^^^^^^ AIR301 -197 | days_ago -198 | infer_time_unit +107 | days_ago +108 | infer_time_unit | -AIR301_names.py:197:1: AIR301 `airflow.utils.dates.days_ago` is removed in Airflow 3.0 +AIR301_names.py:107:1: AIR301 `airflow.utils.dates.days_ago` is removed in Airflow 3.0 | -196 | date_range -197 | days_ago +106 | date_range +107 | days_ago | ^^^^^^^^ AIR301 -198 | infer_time_unit -199 | parse_execution_date +108 | infer_time_unit +109 | parse_execution_date | = help: Use `pendulum.today('UTC').add(days=-N, ...)` instead -AIR301_names.py:198:1: AIR301 `airflow.utils.dates.infer_time_unit` is removed in Airflow 3.0 +AIR301_names.py:108:1: AIR301 `airflow.utils.dates.infer_time_unit` is removed in Airflow 3.0 | -196 | date_range -197 | days_ago -198 | infer_time_unit +106 | date_range +107 | days_ago +108 | infer_time_unit | ^^^^^^^^^^^^^^^ AIR301 -199 | parse_execution_date -200 | round_time +109 | parse_execution_date +110 | round_time | -AIR301_names.py:199:1: AIR301 `airflow.utils.dates.parse_execution_date` is removed in Airflow 3.0 +AIR301_names.py:109:1: AIR301 `airflow.utils.dates.parse_execution_date` is removed in Airflow 3.0 | -197 | days_ago -198 | infer_time_unit -199 | parse_execution_date +107 | days_ago +108 | infer_time_unit +109 | parse_execution_date | ^^^^^^^^^^^^^^^^^^^^ AIR301 -200 | round_time -201 | scale_time_units +110 | round_time +111 | scale_time_units | -AIR301_names.py:200:1: AIR301 `airflow.utils.dates.round_time` is removed in Airflow 3.0 +AIR301_names.py:110:1: AIR301 `airflow.utils.dates.round_time` is removed in Airflow 3.0 | -198 | infer_time_unit -199 | parse_execution_date -200 | round_time +108 | infer_time_unit +109 | parse_execution_date +110 | round_time | ^^^^^^^^^^ AIR301 -201 | scale_time_units +111 | scale_time_units | -AIR301_names.py:201:1: AIR301 `airflow.utils.dates.scale_time_units` is removed in Airflow 3.0 +AIR301_names.py:111:1: AIR301 `airflow.utils.dates.scale_time_units` is removed in Airflow 3.0 | -199 | parse_execution_date -200 | round_time -201 | scale_time_units +109 | parse_execution_date +110 | round_time +111 | scale_time_units | ^^^^^^^^^^^^^^^^ AIR301 -202 | -203 | # This one was not deprecated. +112 | +113 | # This one was not deprecated. | -AIR301_names.py:208:1: AIR301 `airflow.utils.dag_cycle_tester.test_cycle` is removed in Airflow 3.0 +AIR301_names.py:118:1: AIR301 `airflow.utils.dag_cycle_tester.test_cycle` is removed in Airflow 3.0 | -207 | # airflow.utils.dag_cycle_tester -208 | test_cycle +117 | # airflow.utils.dag_cycle_tester +118 | test_cycle | ^^^^^^^^^^ AIR301 | -AIR301_names.py:212:1: AIR301 `airflow.utils.db.create_session` is removed in Airflow 3.0 +AIR301_names.py:122:1: AIR301 `airflow.utils.db.create_session` is removed in Airflow 3.0 | -211 | # airflow.utils.db -212 | create_session +121 | # airflow.utils.db +122 | create_session | ^^^^^^^^^^^^^^ AIR301 -213 | -214 | # airflow.utils.decorators +123 | +124 | # airflow.utils.decorators | -AIR301_names.py:215:1: AIR301 `airflow.utils.decorators.apply_defaults` is removed in Airflow 3.0; `apply_defaults` is now unconditionally done and can be safely removed. +AIR301_names.py:125:1: AIR301 `airflow.utils.decorators.apply_defaults` is removed in Airflow 3.0; `apply_defaults` is now unconditionally done and can be safely removed. | -214 | # airflow.utils.decorators -215 | apply_defaults +124 | # airflow.utils.decorators +125 | apply_defaults | ^^^^^^^^^^^^^^ AIR301 -216 | -217 | # airflow.utils.file +126 | +127 | # airflow.utils.file | -AIR301_names.py:218:1: AIR301 `airflow.utils.file.TemporaryDirectory` is removed in Airflow 3.0 +AIR301_names.py:128:1: AIR301 `airflow.utils.file.TemporaryDirectory` is removed in Airflow 3.0 | -217 | # airflow.utils.file -218 | TemporaryDirectory() +127 | # airflow.utils.file +128 | TemporaryDirectory() | ^^^^^^^^^^^^^^^^^^ AIR301 -219 | mkdirs +129 | mkdirs | = help: Use `tempfile.TemporaryDirectory` instead -AIR301_names.py:219:1: AIR301 `airflow.utils.file.mkdirs` is removed in Airflow 3.0 +AIR301_names.py:129:1: AIR301 `airflow.utils.file.mkdirs` is removed in Airflow 3.0 | -217 | # airflow.utils.file -218 | TemporaryDirectory() -219 | mkdirs +127 | # airflow.utils.file +128 | TemporaryDirectory() +129 | mkdirs | ^^^^^^ AIR301 -220 | -221 | # airflow.utils.helpers +130 | +131 | # airflow.utils.helpers | = help: Use `pathlib.Path({path}).mkdir` instead -AIR301_names.py:222:1: AIR301 `airflow.utils.helpers.chain` is removed in Airflow 3.0 +AIR301_names.py:132:1: AIR301 `airflow.utils.helpers.chain` is removed in Airflow 3.0 | -221 | # airflow.utils.helpers -222 | helper_chain +131 | # airflow.utils.helpers +132 | helper_chain | ^^^^^^^^^^^^ AIR301 -223 | helper_cross_downstream +133 | helper_cross_downstream | = help: Use `airflow.sdk.chain` instead -AIR301_names.py:223:1: AIR301 `airflow.utils.helpers.cross_downstream` is removed in Airflow 3.0 +AIR301_names.py:133:1: AIR301 `airflow.utils.helpers.cross_downstream` is removed in Airflow 3.0 | -221 | # airflow.utils.helpers -222 | helper_chain -223 | helper_cross_downstream +131 | # airflow.utils.helpers +132 | helper_chain +133 | helper_cross_downstream | ^^^^^^^^^^^^^^^^^^^^^^^ AIR301 -224 | -225 | # airflow.utils.log +134 | +135 | # airflow.utils.log | = help: Use `airflow.sdk.cross_downstream` instead -AIR301_names.py:226:1: AIR301 `airflow.utils.log.secrets_masker` is removed in Airflow 3.0 +AIR301_names.py:136:1: AIR301 `airflow.utils.log.secrets_masker` is removed in Airflow 3.0 | -225 | # airflow.utils.log -226 | secrets_masker +135 | # airflow.utils.log +136 | secrets_masker | ^^^^^^^^^^^^^^ AIR301 -227 | -228 | # airflow.utils.state +137 | +138 | # airflow.utils.state | = help: Use `airflow.sdk.execution_time.secrets_masker` instead -AIR301_names.py:229:1: AIR301 `airflow.utils.state.SHUTDOWN` is removed in Airflow 3.0 +AIR301_names.py:139:1: AIR301 `airflow.utils.state.SHUTDOWN` is removed in Airflow 3.0 | -228 | # airflow.utils.state -229 | SHUTDOWN +138 | # airflow.utils.state +139 | SHUTDOWN | ^^^^^^^^ AIR301 -230 | terminating_states +140 | terminating_states | -AIR301_names.py:230:1: AIR301 `airflow.utils.state.terminating_states` is removed in Airflow 3.0 +AIR301_names.py:140:1: AIR301 `airflow.utils.state.terminating_states` is removed in Airflow 3.0 | -228 | # airflow.utils.state -229 | SHUTDOWN -230 | terminating_states +138 | # airflow.utils.state +139 | SHUTDOWN +140 | terminating_states | ^^^^^^^^^^^^^^^^^^ AIR301 -231 | -232 | # airflow.utils.trigger_rule +141 | +142 | # airflow.utils.trigger_rule | -AIR301_names.py:233:13: AIR301 `airflow.utils.trigger_rule.TriggerRule.DUMMY` is removed in Airflow 3.0 +AIR301_names.py:143:13: AIR301 `airflow.utils.trigger_rule.TriggerRule.DUMMY` is removed in Airflow 3.0 | -232 | # airflow.utils.trigger_rule -233 | TriggerRule.DUMMY +142 | # airflow.utils.trigger_rule +143 | TriggerRule.DUMMY | ^^^^^ AIR301 -234 | TriggerRule.NONE_FAILED_OR_SKIPPED +144 | TriggerRule.NONE_FAILED_OR_SKIPPED | -AIR301_names.py:234:13: AIR301 `airflow.utils.trigger_rule.TriggerRule.NONE_FAILED_OR_SKIPPED` is removed in Airflow 3.0 +AIR301_names.py:144:13: AIR301 `airflow.utils.trigger_rule.TriggerRule.NONE_FAILED_OR_SKIPPED` is removed in Airflow 3.0 | -232 | # airflow.utils.trigger_rule -233 | TriggerRule.DUMMY -234 | TriggerRule.NONE_FAILED_OR_SKIPPED +142 | # airflow.utils.trigger_rule +143 | TriggerRule.DUMMY +144 | TriggerRule.NONE_FAILED_OR_SKIPPED | ^^^^^^^^^^^^^^^^^^^^^^ AIR301 -235 | -236 | # airflow.www.auth | -AIR301_names.py:237:1: AIR301 `airflow.www.auth.has_access` is removed in Airflow 3.0 +AIR301_names.py:148:1: AIR301 `airflow.www.auth.has_access` is removed in Airflow 3.0 | -236 | # airflow.www.auth -237 | has_access +147 | # airflow.www.auth +148 | has_access | ^^^^^^^^^^ AIR301 -238 | has_access_dataset +149 | +150 | # airflow.www.utils | = help: Use `airflow.www.auth.has_access_*` instead -AIR301_names.py:238:1: AIR301 `airflow.www.auth.has_access_dataset` is removed in Airflow 3.0 - | -236 | # airflow.www.auth -237 | has_access -238 | has_access_dataset - | ^^^^^^^^^^^^^^^^^^ AIR301 -239 | -240 | # airflow.www.utils - | - = help: Use `airflow.www.auth.has_access_dataset` instead - -AIR301_names.py:241:1: AIR301 `airflow.www.utils.get_sensitive_variables_fields` is removed in Airflow 3.0 +AIR301_names.py:151:1: AIR301 `airflow.www.utils.get_sensitive_variables_fields` is removed in Airflow 3.0 | -240 | # airflow.www.utils -241 | get_sensitive_variables_fields +150 | # airflow.www.utils +151 | get_sensitive_variables_fields | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301 -242 | should_hide_value_for_key +152 | should_hide_value_for_key | = help: Use `airflow.utils.log.secrets_masker.get_sensitive_variables_fields` instead -AIR301_names.py:242:1: AIR301 `airflow.www.utils.should_hide_value_for_key` is removed in Airflow 3.0 +AIR301_names.py:152:1: AIR301 `airflow.www.utils.should_hide_value_for_key` is removed in Airflow 3.0 | -240 | # airflow.www.utils -241 | get_sensitive_variables_fields -242 | should_hide_value_for_key +150 | # airflow.www.utils +151 | get_sensitive_variables_fields +152 | should_hide_value_for_key | ^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301 | = help: Use `airflow.utils.log.secrets_masker.should_hide_value_for_key` instead diff --git a/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR301_AIR301_names_fix.py.snap b/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR301_AIR301_names_fix.py.snap new file mode 100644 index 0000000000000..ff6982d49ad41 --- /dev/null +++ b/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR301_AIR301_names_fix.py.snap @@ -0,0 +1,325 @@ +--- +source: crates/ruff_linter/src/rules/airflow/mod.rs +--- +AIR301_names_fix.py:19:1: AIR301 [*] `airflow.api_connexion.security.requires_access_dataset` is removed in Airflow 3.0 + | +17 | from airflow.www.auth import has_access_dataset +18 | +19 | requires_access_dataset() + | ^^^^^^^^^^^^^^^^^^^^^^^ AIR301 +20 | +21 | DatasetDetails() + | + = help: Use `airflow.api_connexion.security.requires_access_asset` instead + +ℹ Safe fix +1 1 | from __future__ import annotations +2 2 | +3 |-from airflow.api_connexion.security import requires_access_dataset + 3 |+from airflow.api_connexion.security import requires_access_dataset, requires_access_asset +4 4 | from airflow.auth.managers.models.resource_details import ( +5 5 | DatasetDetails, +6 6 | is_authorized_dataset, +-------------------------------------------------------------------------------- +16 16 | from airflow.security.permissions import RESOURCE_DATASET +17 17 | from airflow.www.auth import has_access_dataset +18 18 | +19 |-requires_access_dataset() + 19 |+requires_access_asset() +20 20 | +21 21 | DatasetDetails() +22 22 | is_authorized_dataset() + +AIR301_names_fix.py:21:1: AIR301 [*] `airflow.auth.managers.models.resource_details.DatasetDetails` is removed in Airflow 3.0 + | +19 | requires_access_dataset() +20 | +21 | DatasetDetails() + | ^^^^^^^^^^^^^^ AIR301 +22 | is_authorized_dataset() + | + = help: Use `airflow.api_fastapi.auth.managers.models.resource_details.AssetDetails` instead + +ℹ Safe fix +15 15 | from airflow.secrets.local_filesystm import load_connections +16 16 | from airflow.security.permissions import RESOURCE_DATASET +17 17 | from airflow.www.auth import has_access_dataset + 18 |+from airflow.api_fastapi.auth.managers.models.resource_details import AssetDetails +18 19 | +19 20 | requires_access_dataset() +20 21 | +21 |-DatasetDetails() + 22 |+AssetDetails() +22 23 | is_authorized_dataset() +23 24 | +24 25 | DatasetManager() + +AIR301_names_fix.py:24:1: AIR301 [*] `airflow.datasets.manager.DatasetManager` is removed in Airflow 3.0 + | +22 | is_authorized_dataset() +23 | +24 | DatasetManager() + | ^^^^^^^^^^^^^^ AIR301 +25 | dataset_manager() +26 | resolve_dataset_manager() + | + = help: Use `airflow.assets.manager.AssetManager` instead + +ℹ Safe fix +15 15 | from airflow.secrets.local_filesystm import load_connections +16 16 | from airflow.security.permissions import RESOURCE_DATASET +17 17 | from airflow.www.auth import has_access_dataset + 18 |+from airflow.assets.manager import AssetManager +18 19 | +19 20 | requires_access_dataset() +20 21 | +21 22 | DatasetDetails() +22 23 | is_authorized_dataset() +23 24 | +24 |-DatasetManager() + 25 |+AssetManager() +25 26 | dataset_manager() +26 27 | resolve_dataset_manager() +27 28 | + +AIR301_names_fix.py:25:1: AIR301 [*] `airflow.datasets.manager.dataset_manager` is removed in Airflow 3.0 + | +24 | DatasetManager() +25 | dataset_manager() + | ^^^^^^^^^^^^^^^ AIR301 +26 | resolve_dataset_manager() + | + = help: Use `airflow.assets.manager.asset_manager` instead + +ℹ Safe fix +15 15 | from airflow.secrets.local_filesystm import load_connections +16 16 | from airflow.security.permissions import RESOURCE_DATASET +17 17 | from airflow.www.auth import has_access_dataset + 18 |+from airflow.assets.manager import asset_manager +18 19 | +19 20 | requires_access_dataset() +20 21 | +-------------------------------------------------------------------------------- +22 23 | is_authorized_dataset() +23 24 | +24 25 | DatasetManager() +25 |-dataset_manager() + 26 |+asset_manager() +26 27 | resolve_dataset_manager() +27 28 | +28 29 | DatasetLineageInfo() + +AIR301_names_fix.py:26:1: AIR301 [*] `airflow.datasets.manager.resolve_dataset_manager` is removed in Airflow 3.0 + | +24 | DatasetManager() +25 | dataset_manager() +26 | resolve_dataset_manager() + | ^^^^^^^^^^^^^^^^^^^^^^^ AIR301 +27 | +28 | DatasetLineageInfo() + | + = help: Use `airflow.assets.manager.resolve_asset_manager` instead + +ℹ Safe fix +15 15 | from airflow.secrets.local_filesystm import load_connections +16 16 | from airflow.security.permissions import RESOURCE_DATASET +17 17 | from airflow.www.auth import has_access_dataset + 18 |+from airflow.assets.manager import resolve_asset_manager +18 19 | +19 20 | requires_access_dataset() +20 21 | +-------------------------------------------------------------------------------- +23 24 | +24 25 | DatasetManager() +25 26 | dataset_manager() +26 |-resolve_dataset_manager() + 27 |+resolve_asset_manager() +27 28 | +28 29 | DatasetLineageInfo() +29 30 | + +AIR301_names_fix.py:28:1: AIR301 [*] `airflow.lineage.hook.DatasetLineageInfo` is removed in Airflow 3.0 + | +26 | resolve_dataset_manager() +27 | +28 | DatasetLineageInfo() + | ^^^^^^^^^^^^^^^^^^ AIR301 +29 | +30 | AllowListValidator() + | + = help: Use `airflow.lineage.hook.AssetLineageInfo` instead + +ℹ Safe fix +10 10 | dataset_manager, +11 11 | resolve_dataset_manager, +12 12 | ) +13 |-from airflow.lineage.hook import DatasetLineageInfo + 13 |+from airflow.lineage.hook import DatasetLineageInfo, AssetLineageInfo +14 14 | from airflow.metrics.validators import AllowListValidator, BlockListValidator +15 15 | from airflow.secrets.local_filesystm import load_connections +16 16 | from airflow.security.permissions import RESOURCE_DATASET +-------------------------------------------------------------------------------- +25 25 | dataset_manager() +26 26 | resolve_dataset_manager() +27 27 | +28 |-DatasetLineageInfo() + 28 |+AssetLineageInfo() +29 29 | +30 30 | AllowListValidator() +31 31 | BlockListValidator() + +AIR301_names_fix.py:30:1: AIR301 [*] `airflow.metrics.validators.AllowListValidator` is removed in Airflow 3.0 + | +28 | DatasetLineageInfo() +29 | +30 | AllowListValidator() + | ^^^^^^^^^^^^^^^^^^ AIR301 +31 | BlockListValidator() + | + = help: Use `airflow.metrics.validators.PatternAllowListValidator` instead + +ℹ Safe fix +11 11 | resolve_dataset_manager, +12 12 | ) +13 13 | from airflow.lineage.hook import DatasetLineageInfo +14 |-from airflow.metrics.validators import AllowListValidator, BlockListValidator + 14 |+from airflow.metrics.validators import AllowListValidator, BlockListValidator, PatternAllowListValidator +15 15 | from airflow.secrets.local_filesystm import load_connections +16 16 | from airflow.security.permissions import RESOURCE_DATASET +17 17 | from airflow.www.auth import has_access_dataset +-------------------------------------------------------------------------------- +27 27 | +28 28 | DatasetLineageInfo() +29 29 | +30 |-AllowListValidator() + 30 |+PatternAllowListValidator() +31 31 | BlockListValidator() +32 32 | +33 33 | load_connections() + +AIR301_names_fix.py:31:1: AIR301 [*] `airflow.metrics.validators.BlockListValidator` is removed in Airflow 3.0 + | +30 | AllowListValidator() +31 | BlockListValidator() + | ^^^^^^^^^^^^^^^^^^ AIR301 +32 | +33 | load_connections() + | + = help: Use `airflow.metrics.validators.PatternBlockListValidator` instead + +ℹ Safe fix +11 11 | resolve_dataset_manager, +12 12 | ) +13 13 | from airflow.lineage.hook import DatasetLineageInfo +14 |-from airflow.metrics.validators import AllowListValidator, BlockListValidator + 14 |+from airflow.metrics.validators import AllowListValidator, BlockListValidator, PatternBlockListValidator +15 15 | from airflow.secrets.local_filesystm import load_connections +16 16 | from airflow.security.permissions import RESOURCE_DATASET +17 17 | from airflow.www.auth import has_access_dataset +-------------------------------------------------------------------------------- +28 28 | DatasetLineageInfo() +29 29 | +30 30 | AllowListValidator() +31 |-BlockListValidator() + 31 |+PatternBlockListValidator() +32 32 | +33 33 | load_connections() +34 34 | + +AIR301_names_fix.py:35:1: AIR301 [*] `airflow.security.permissions.RESOURCE_DATASET` is removed in Airflow 3.0 + | +33 | load_connections() +34 | +35 | RESOURCE_DATASET + | ^^^^^^^^^^^^^^^^ AIR301 +36 | +37 | has_access_dataset() + | + = help: Use `airflow.security.permissions.RESOURCE_ASSET` instead + +ℹ Safe fix +13 13 | from airflow.lineage.hook import DatasetLineageInfo +14 14 | from airflow.metrics.validators import AllowListValidator, BlockListValidator +15 15 | from airflow.secrets.local_filesystm import load_connections +16 |-from airflow.security.permissions import RESOURCE_DATASET + 16 |+from airflow.security.permissions import RESOURCE_DATASET, RESOURCE_ASSET +17 17 | from airflow.www.auth import has_access_dataset +18 18 | +19 19 | requires_access_dataset() +-------------------------------------------------------------------------------- +32 32 | +33 33 | load_connections() +34 34 | +35 |-RESOURCE_DATASET + 35 |+RESOURCE_ASSET +36 36 | +37 37 | has_access_dataset() +38 38 | + +AIR301_names_fix.py:37:1: AIR301 [*] `airflow.www.auth.has_access_dataset` is removed in Airflow 3.0 + | +35 | RESOURCE_DATASET +36 | +37 | has_access_dataset() + | ^^^^^^^^^^^^^^^^^^ AIR301 +38 | +39 | from airflow.listeners.spec.dataset import ( + | + = help: Use `airflow.www.auth.has_access_asset` instead + +ℹ Safe fix +14 14 | from airflow.metrics.validators import AllowListValidator, BlockListValidator +15 15 | from airflow.secrets.local_filesystm import load_connections +16 16 | from airflow.security.permissions import RESOURCE_DATASET +17 |-from airflow.www.auth import has_access_dataset + 17 |+from airflow.www.auth import has_access_dataset, has_access_asset +18 18 | +19 19 | requires_access_dataset() +20 20 | +-------------------------------------------------------------------------------- +34 34 | +35 35 | RESOURCE_DATASET +36 36 | +37 |-has_access_dataset() + 37 |+has_access_asset() +38 38 | +39 39 | from airflow.listeners.spec.dataset import ( +40 40 | on_dataset_changed, + +AIR301_names_fix.py:44:1: AIR301 [*] `airflow.listeners.spec.dataset.on_dataset_created` is removed in Airflow 3.0 + | +42 | ) +43 | +44 | on_dataset_created() + | ^^^^^^^^^^^^^^^^^^ AIR301 +45 | on_dataset_changed() + | + = help: Use `airflow.listeners.spec.asset.on_asset_created` instead + +ℹ Safe fix +40 40 | on_dataset_changed, +41 41 | on_dataset_created, +42 42 | ) + 43 |+from airflow.listeners.spec.asset import on_asset_created +43 44 | +44 |-on_dataset_created() + 45 |+on_asset_created() +45 46 | on_dataset_changed() + +AIR301_names_fix.py:45:1: AIR301 [*] `airflow.listeners.spec.dataset.on_dataset_changed` is removed in Airflow 3.0 + | +44 | on_dataset_created() +45 | on_dataset_changed() + | ^^^^^^^^^^^^^^^^^^ AIR301 + | + = help: Use `airflow.listeners.spec.asset.on_asset_changed` instead + +ℹ Safe fix +40 40 | on_dataset_changed, +41 41 | on_dataset_created, +42 42 | ) + 43 |+from airflow.listeners.spec.asset import on_asset_changed +43 44 | +44 45 | on_dataset_created() +45 |-on_dataset_changed() + 46 |+on_asset_changed() diff --git a/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR301_AIR301_provider_names_fix.py.snap b/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR301_AIR301_provider_names_fix.py.snap new file mode 100644 index 0000000000000..6b986b413fd04 --- /dev/null +++ b/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR301_AIR301_provider_names_fix.py.snap @@ -0,0 +1,254 @@ +--- +source: crates/ruff_linter/src/rules/airflow/mod.rs +--- +AIR301_provider_names_fix.py:25:1: AIR301 [*] `airflow.providers.amazon.aws.auth_manager.avp.entities.AvpEntities.DATASET` is removed in Airflow 3.0 + | +23 | ) +24 | +25 | DATASET + | ^^^^^^^ AIR301 +26 | +27 | s3_create_dataset() + | + = help: Use `airflow.providers.amazon.aws.auth_manager.avp.entities.AvpEntities.ASSET` instead + +ℹ Safe fix +1 1 | from __future__ import annotations +2 2 | +3 |-from airflow.providers.amazon.aws.auth_manager.avp.entities.AvpEntities import DATASET + 3 |+from airflow.providers.amazon.aws.auth_manager.avp.entities.AvpEntities import DATASET, ASSET +4 4 | from airflow.providers.amazon.aws.datasets.s3 import ( +5 5 | convert_dataset_to_openlineage as s3_convert_dataset_to_openlineage, +6 6 | ) +-------------------------------------------------------------------------------- +22 22 | translate_airflow_dataset, +23 23 | ) +24 24 | +25 |-DATASET + 25 |+ASSET +26 26 | +27 27 | s3_create_dataset() +28 28 | s3_convert_dataset_to_openlineage() + +AIR301_provider_names_fix.py:27:1: AIR301 [*] `airflow.providers.amazon.aws.datasets.s3.create_dataset` is removed in Airflow 3.0 + | +25 | DATASET +26 | +27 | s3_create_dataset() + | ^^^^^^^^^^^^^^^^^ AIR301 +28 | s3_convert_dataset_to_openlineage() + | + = help: Use `airflow.providers.amazon.aws.assets.s3.create_asset` instead + +ℹ Safe fix +21 21 | DatasetInfo, +22 22 | translate_airflow_dataset, +23 23 | ) + 24 |+from airflow.providers.amazon.aws.assets.s3 import create_asset +24 25 | +25 26 | DATASET +26 27 | +27 |-s3_create_dataset() + 28 |+create_asset() +28 29 | s3_convert_dataset_to_openlineage() +29 30 | +30 31 | io_create_dataset() + +AIR301_provider_names_fix.py:28:1: AIR301 [*] `airflow.providers.amazon.aws.datasets.s3.convert_dataset_to_openlineage` is removed in Airflow 3.0 + | +27 | s3_create_dataset() +28 | s3_convert_dataset_to_openlineage() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301 +29 | +30 | io_create_dataset() + | + = help: Use `airflow.providers.amazon.aws.assets.s3.convert_asset_to_openlineage` instead + +ℹ Safe fix +21 21 | DatasetInfo, +22 22 | translate_airflow_dataset, +23 23 | ) + 24 |+from airflow.providers.amazon.aws.assets.s3 import convert_asset_to_openlineage +24 25 | +25 26 | DATASET +26 27 | +27 28 | s3_create_dataset() +28 |-s3_convert_dataset_to_openlineage() + 29 |+convert_asset_to_openlineage() +29 30 | +30 31 | io_create_dataset() +31 32 | io_convert_dataset_to_openlineage() + +AIR301_provider_names_fix.py:33:1: AIR301 [*] `airflow.providers.fab.auth_manager.fab_auth_manager.is_authorized_dataset` is removed in Airflow 3.0 + | +31 | io_convert_dataset_to_openlineage() +32 | +33 | fab_is_authorized_dataset() + | ^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301 +34 | +35 | # airflow.providers.google.datasets.bigquery + | + = help: Use `airflow.providers.fab.auth_manager.fab_auth_manager.is_authorized_asset` instead + +ℹ Safe fix +9 9 | convert_dataset_to_openlineage as io_convert_dataset_to_openlineage, +10 10 | ) +11 11 | from airflow.providers.common.io.dataset.file import create_dataset as io_create_dataset +12 |-from airflow.providers.fab.auth_manager.fab_auth_manager import is_authorized_dataset as fab_is_authorized_dataset + 12 |+from airflow.providers.fab.auth_manager.fab_auth_manager import is_authorized_dataset as fab_is_authorized_dataset, is_authorized_asset +13 13 | from airflow.providers.google.datasets.bigquery import ( +14 14 | create_dataset as bigquery_create_dataset, +15 15 | ) +-------------------------------------------------------------------------------- +30 30 | io_create_dataset() +31 31 | io_convert_dataset_to_openlineage() +32 32 | +33 |-fab_is_authorized_dataset() + 33 |+is_authorized_asset() +34 34 | +35 35 | # airflow.providers.google.datasets.bigquery +36 36 | bigquery_create_dataset() + +AIR301_provider_names_fix.py:36:1: AIR301 [*] `airflow.providers.google.datasets.bigquery.create_dataset` is removed in Airflow 3.0 + | +35 | # airflow.providers.google.datasets.bigquery +36 | bigquery_create_dataset() + | ^^^^^^^^^^^^^^^^^^^^^^^ AIR301 +37 | # airflow.providers.google.datasets.gcs +38 | gcs_create_dataset() + | + = help: Use `airflow.providers.google.assets.bigquery.create_asset` instead + +ℹ Safe fix +21 21 | DatasetInfo, +22 22 | translate_airflow_dataset, +23 23 | ) + 24 |+from airflow.providers.google.assets.bigquery import create_asset +24 25 | +25 26 | DATASET +26 27 | +-------------------------------------------------------------------------------- +33 34 | fab_is_authorized_dataset() +34 35 | +35 36 | # airflow.providers.google.datasets.bigquery +36 |-bigquery_create_dataset() + 37 |+create_asset() +37 38 | # airflow.providers.google.datasets.gcs +38 39 | gcs_create_dataset() +39 40 | gcs_convert_dataset_to_openlineage() + +AIR301_provider_names_fix.py:38:1: AIR301 [*] `airflow.providers.google.datasets.gcs.create_dataset` is removed in Airflow 3.0 + | +36 | bigquery_create_dataset() +37 | # airflow.providers.google.datasets.gcs +38 | gcs_create_dataset() + | ^^^^^^^^^^^^^^^^^^ AIR301 +39 | gcs_convert_dataset_to_openlineage() +40 | # airflow.providers.openlineage.utils.utils + | + = help: Use `airflow.providers.google.assets.gcs.create_asset` instead + +ℹ Safe fix +21 21 | DatasetInfo, +22 22 | translate_airflow_dataset, +23 23 | ) + 24 |+from airflow.providers.google.assets.gcs import create_asset +24 25 | +25 26 | DATASET +26 27 | +-------------------------------------------------------------------------------- +35 36 | # airflow.providers.google.datasets.bigquery +36 37 | bigquery_create_dataset() +37 38 | # airflow.providers.google.datasets.gcs +38 |-gcs_create_dataset() + 39 |+create_asset() +39 40 | gcs_convert_dataset_to_openlineage() +40 41 | # airflow.providers.openlineage.utils.utils +41 42 | DatasetInfo() + +AIR301_provider_names_fix.py:39:1: AIR301 [*] `airflow.providers.google.datasets.gcs.convert_dataset_to_openlineage` is removed in Airflow 3.0 + | +37 | # airflow.providers.google.datasets.gcs +38 | gcs_create_dataset() +39 | gcs_convert_dataset_to_openlineage() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301 +40 | # airflow.providers.openlineage.utils.utils +41 | DatasetInfo() + | + = help: Use `airflow.providers.google.assets.gcs.convert_asset_to_openlineage` instead + +ℹ Safe fix +21 21 | DatasetInfo, +22 22 | translate_airflow_dataset, +23 23 | ) + 24 |+from airflow.providers.google.assets.gcs import convert_asset_to_openlineage +24 25 | +25 26 | DATASET +26 27 | +-------------------------------------------------------------------------------- +36 37 | bigquery_create_dataset() +37 38 | # airflow.providers.google.datasets.gcs +38 39 | gcs_create_dataset() +39 |-gcs_convert_dataset_to_openlineage() + 40 |+convert_asset_to_openlineage() +40 41 | # airflow.providers.openlineage.utils.utils +41 42 | DatasetInfo() +42 43 | translate_airflow_dataset() + +AIR301_provider_names_fix.py:41:1: AIR301 [*] `airflow.providers.openlineage.utils.utils.DatasetInfo` is removed in Airflow 3.0 + | +39 | gcs_convert_dataset_to_openlineage() +40 | # airflow.providers.openlineage.utils.utils +41 | DatasetInfo() + | ^^^^^^^^^^^ AIR301 +42 | translate_airflow_dataset() +43 | # + | + = help: Use `airflow.providers.openlineage.utils.utils.AssetInfo` instead + +ℹ Safe fix +20 20 | from airflow.providers.openlineage.utils.utils import ( +21 21 | DatasetInfo, +22 22 | translate_airflow_dataset, + 23 |+AssetInfo, +23 24 | ) +24 25 | +25 26 | DATASET +-------------------------------------------------------------------------------- +38 39 | gcs_create_dataset() +39 40 | gcs_convert_dataset_to_openlineage() +40 41 | # airflow.providers.openlineage.utils.utils +41 |-DatasetInfo() + 42 |+AssetInfo() +42 43 | translate_airflow_dataset() +43 44 | # +44 45 | # airflow.secrets.local_filesystem + +AIR301_provider_names_fix.py:42:1: AIR301 [*] `airflow.providers.openlineage.utils.utils.translate_airflow_dataset` is removed in Airflow 3.0 + | +40 | # airflow.providers.openlineage.utils.utils +41 | DatasetInfo() +42 | translate_airflow_dataset() + | ^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301 +43 | # +44 | # airflow.secrets.local_filesystem + | + = help: Use `airflow.providers.openlineage.utils.utils.translate_airflow_asset` instead + +ℹ Safe fix +20 20 | from airflow.providers.openlineage.utils.utils import ( +21 21 | DatasetInfo, +22 22 | translate_airflow_dataset, + 23 |+translate_airflow_asset, +23 24 | ) +24 25 | +25 26 | DATASET +-------------------------------------------------------------------------------- +39 40 | gcs_convert_dataset_to_openlineage() +40 41 | # airflow.providers.openlineage.utils.utils +41 42 | DatasetInfo() +42 |-translate_airflow_dataset() + 43 |+translate_airflow_asset() +43 44 | # +44 45 | # airflow.secrets.local_filesystem +45 46 | load_connections()