From 39623f8d40fc8db6ec3859b3cc2e9927aa2d85ab Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Fri, 6 Dec 2024 18:34:48 +0800 Subject: [PATCH] [airflow]: extend removed names (AIR302) (#14804) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Airflow 3.0 removes various deprecated functions, members, modules, and other values. They have been deprecated in 2.x, but the removal causes incompatibilities that we want to detect. This PR deprecates the following names. The full list of rules we will extend https://github.com/apache/airflow/issues/44556 #### package * `airflow.contrib.*` #### module * `airflow.operators.subdag.*` #### class * `airflow.sensors.external_task.ExternalTaskSensorLink` → `airflow.sensors.external_task.ExternalDagLin` * `airflow.operators.bash_operator.BashOperator` → `airflow.operators.bash.BashOperator` * `airflow.operators.branch_operator.BaseBranchOperator` → `airflow.operators.branch.BaseBranchOperator` * `airflow.operators.dummy.EmptyOperator` → `airflow.operators.empty.EmptyOperator` * `airflow.operators.dummy.DummyOperator` → `airflow.operators.empty.EmptyOperator` * `airflow.operators.dummy_operator.EmptyOperator` → `airflow.operators.empty.EmptyOperator` * `airflow.operators.dummy_operator.DummyOperator` → `airflow.operators.empty.EmptyOperator` * `airflow.operators.email_operator.EmailOperator` → `airflow.operators.email.EmailOperator` * `airflow.sensors.base_sensor_operator.BaseSensorOperator` → `airflow.sensors.base.BaseSensorOperator` * `airflow.sensors.date_time_sensor.DateTimeSensor` → `airflow.sensors.date_time.DateTimeSensor` * `airflow.sensors.external_task_sensor.ExternalTaskMarker` → `airflow.sensors.external_task.ExternalTaskMarker` * `airflow.sensors.external_task_sensor.ExternalTaskSensor` → `airflow.sensors.external_task.ExternalTaskSensor` * `airflow.sensors.external_task_sensor.ExternalTaskSensorLink` → `airflow.sensors.external_task.ExternalTaskSensorLink` * `airflow.sensors.time_delta_sensor.TimeDeltaSensor` → `airflow.sensors.time_delta.TimeDeltaSensor` #### function * `airflow.utils.decorators.apply_defaults` * `airflow.www.utils.get_sensitive_variables_fields` → `airflow.utils.log.secrets_masker.get_sensitive_variables_fields` * `airflow.www.utils.should_hide_value_for_key` → `airflow.utils.log.secrets_masker.should_hide_value_for_key` * `airflow.configuration.get` → `airflow.configuration.conf.get` * `airflow.configuration.getboolean` → `airflow.configuration.conf.getboolean` * `airflow.configuration.getfloat` → `airflow.configuration.conf.getfloat` * `airflow.configuration.getint` → `airflow.configuration.conf.getint` * `airflow.configuration.has_option` → `airflow.configuration.conf.has_option` * `airflow.configuration.remove_option` → `airflow.configuration.conf.remove_option` * `airflow.configuration.as_dict` → `airflow.configuration.conf.as_dict` * `airflow.configuration.set` → `airflow.configuration.conf.set` * `airflow.secrets.local_filesystem.load_connections` → `airflow.secrets.local_filesystem.load_connections_dict` * `airflow.secrets.local_filesystem.get_connection` → `airflow.secrets.local_filesystem.load_connections_dict` * `airflow.utils.helpers.chain` → `airflow.models.baseoperator.chain` * `airflow.utils.helpers.cross_downstream` → `airflow.models.baseoperator.cross_downstream` #### attribute * in `airflow.utils.trigger_rule.TriggerRule` * `DUMMY` * `NONE_FAILED_OR_SKIPPED` #### constant / variable * `airflow.PY\d\d` --- .../test/fixtures/airflow/AIR302_names.py | 67 ++- .../src/rules/airflow/rules/removal_in_3.rs | 196 ++++++- ...irflow__tests__AIR302_AIR302_names.py.snap | 555 +++++++++++++++--- 3 files changed, 721 insertions(+), 97 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/airflow/AIR302_names.py b/crates/ruff_linter/resources/test/fixtures/airflow/AIR302_names.py index 63205874a8e2d..ac67ff25cb840 100644 --- a/crates/ruff_linter/resources/test/fixtures/airflow/AIR302_names.py +++ b/crates/ruff_linter/resources/test/fixtures/airflow/AIR302_names.py @@ -1,8 +1,35 @@ +from airflow import PY36, PY37, PY38, PY39, PY310, PY311, PY312 from airflow.triggers.external_task import TaskStateTrigger -from airflow.www.auth import has_access from airflow.api_connexion.security import requires_access +from airflow.configuration import ( + get, + getboolean, + getfloat, + getint, + has_option, + remove_option, + as_dict, + set, +) +from airflow.contrib.aws_athena_hook import AWSAthenaHook from airflow.metrics.validators import AllowListValidator from airflow.metrics.validators import BlockListValidator +from airflow.operators.subdag import SubDagOperator +from airflow.sensors.external_task import ExternalTaskSensorLink +from airflow.operators.bash_operator import BashOperator +from airflow.operators.branch_operator import BaseBranchOperator +from airflow.operators.dummy import EmptyOperator, DummyOperator +from airflow.operators import dummy_operator +from airflow.operators.email_operator import EmailOperator +from airflow.sensors.base_sensor_operator import BaseSensorOperator +from airflow.sensors.date_time_sensor import DateTimeSensor +from airflow.sensors.external_task_sensor import ( + ExternalTaskMarker, + ExternalTaskSensor, + ExternalTaskSensorLink, +) +from airflow.sensors.time_delta_sensor import TimeDeltaSensor +from airflow.secrets.local_filesystem import get_connection, load_connections from airflow.utils import dates from airflow.utils.dates import ( date_range, @@ -13,20 +40,27 @@ round_time, scale_time_units, ) +from airflow.utils.decorators import apply_defaults from airflow.utils.file import TemporaryDirectory, mkdirs +from airflow.utils.helpers import chain, cross_downstream from airflow.utils.state import SHUTDOWN, terminating_states from airflow.utils.dag_cycle_tester import test_cycle +from airflow.utils.trigger_rule import TriggerRule +from airflow.www.auth import has_access +from airflow.www.utils import get_sensitive_variables_fields, should_hide_value_for_key +PY36, PY37, PY38, PY39, PY310, PY311, PY312 +AWSAthenaHook TaskStateTrigger - -has_access requires_access AllowListValidator BlockListValidator +SubDagOperator + dates.date_range dates.days_ago @@ -42,11 +76,38 @@ datetime_to_nano dates.datetime_to_nano +get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set + +get_connection, load_connections + + +ExternalTaskSensorLink +BashOperator +BaseBranchOperator +EmptyOperator, DummyOperator +dummy_operator.EmptyOperator +dummy_operator.DummyOperator +EmailOperator +BaseSensorOperator +DateTimeSensor +(ExternalTaskMarker, ExternalTaskSensor, ExternalTaskSensorLink) +TimeDeltaSensor + +apply_defaults + TemporaryDirectory mkdirs +chain +cross_downstream + SHUTDOWN terminating_states +TriggerRule.DUMMY +TriggerRule.NONE_FAILED_OR_SKIPPED test_cycle + +has_access +get_sensitive_variables_fields, should_hide_value_for_key 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 3f450a7978c81..ccc83a90dc253 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 @@ -10,6 +10,7 @@ use crate::checkers::ast::Checker; enum Replacement { None, Name(String), + Message(String), } /// ## What it does @@ -53,6 +54,9 @@ impl Violation for Airflow3Removal { Replacement::Name(name) => { format!("`{deprecated}` is removed in Airflow 3.0; use `{name}` instead") } + Replacement::Message(message) => { + format!("`{deprecated}` is removed in Airflow 3.0; {message}") + } } } } @@ -106,16 +110,76 @@ fn removed_name(checker: &mut Checker, expr: &Expr, ranged: impl Ranged) { ["airflow", "triggers", "external_task", "TaskStateTrigger"] => { Some((qualname.to_string(), Replacement::None)) } - ["airflow", "www", "auth", "has_access"] => Some(( - qualname.to_string(), - Replacement::Name("airflow.www.auth.has_access_*".to_string()), - )), ["airflow", "api_connexion", "security", "requires_access"] => Some(( qualname.to_string(), Replacement::Name( "airflow.api_connexion.security.requires_access_*".to_string(), ), )), + // airflow.PY\d{1,2} + ["airflow", "PY36"] => Some(( + qualname.to_string(), + Replacement::Name("sys.version_info".to_string()), + )), + ["airflow", "PY37"] => Some(( + qualname.to_string(), + Replacement::Name("sys.version_info".to_string()), + )), + ["airflow", "PY38"] => Some(( + qualname.to_string(), + Replacement::Name("sys.version_info".to_string()), + )), + ["airflow", "PY39"] => Some(( + qualname.to_string(), + Replacement::Name("sys.version_info".to_string()), + )), + ["airflow", "PY310"] => Some(( + qualname.to_string(), + Replacement::Name("sys.version_info".to_string()), + )), + ["airflow", "PY311"] => Some(( + qualname.to_string(), + Replacement::Name("sys.version_info".to_string()), + )), + ["airflow", "PY312"] => Some(( + qualname.to_string(), + Replacement::Name("sys.version_info".to_string()), + )), + // airflow.configuration + ["airflow", "configuration", "get"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.configuration.conf.get".to_string()), + )), + ["airflow", "configuration", "getboolean"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.configuration.conf.getboolean".to_string()), + )), + ["airflow", "configuration", "getfloat"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.configuration.conf.getfloat".to_string()), + )), + ["airflow", "configuration", "getint"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.configuration.conf.getint".to_string()), + )), + ["airflow", "configuration", "has_option"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.configuration.conf.has_option".to_string()), + )), + ["airflow", "configuration", "remove_option"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.configuration.conf.remove_option".to_string()), + )), + ["airflow", "configuration", "as_dict"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.configuration.conf.as_dict".to_string()), + )), + ["airflow", "configuration", "set"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.configuration.conf.set".to_string()), + )), + // airflow.contrib.* + ["airflow", "contrib", ..] => Some((qualname.to_string(), Replacement::None)), // airflow.metrics.validators ["airflow", "metrics", "validators", "AllowListValidator"] => Some(( qualname.to_string(), @@ -129,6 +193,85 @@ fn removed_name(checker: &mut Checker, expr: &Expr, ranged: impl Ranged) { "airflow.metrics.validators.PatternBlockListValidator".to_string(), ), )), + // airflow.operators + ["airflow", "operators", "subdag", ..] => { + Some((qualname.to_string(), Replacement::None)) + } + ["airflow.sensors.external_task.ExternalTaskSensorLink"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.sensors.external_task.ExternalDagLin".to_string()), + )), + ["airflow", "operators", "bash_operator", "BashOperator"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.operators.bash.BashOperator".to_string()), + )), + ["airflow", "operators", "branch_operator", "BaseBranchOperator"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.operators.branch.BaseBranchOperator".to_string()), + )), + ["airflow", "operators", " dummy", "EmptyOperator"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.operators.empty.EmptyOperator".to_string()), + )), + ["airflow", "operators", "dummy", "DummyOperator"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.operators.empty.EmptyOperator".to_string()), + )), + ["airflow", "operators", "dummy_operator", "EmptyOperator"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.operators.empty.EmptyOperator".to_string()), + )), + ["airflow", "operators", "dummy_operator", "DummyOperator"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.operators.empty.EmptyOperator".to_string()), + )), + ["airflow", "operators", "email_operator", "EmailOperator"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.operators.email.EmailOperator".to_string()), + )), + ["airflow", "sensors", "base_sensor_operator", "BaseSensorOperator"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.sensors.base.BaseSensorOperator".to_string()), + )), + ["airflow", "sensors", "date_time_sensor", "DateTimeSensor"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.sensors.date_time.DateTimeSensor".to_string()), + )), + ["airflow", "sensors", "external_task_sensor", "ExternalTaskMarker"] => Some(( + qualname.to_string(), + Replacement::Name( + "airflow.sensors.external_task.ExternalTaskMarker".to_string(), + ), + )), + ["airflow", "sensors", "external_task_sensor", "ExternalTaskSensor"] => Some(( + qualname.to_string(), + Replacement::Name( + "airflow.sensors.external_task.ExternalTaskSensor".to_string(), + ), + )), + ["airflow", "sensors", "external_task_sensor", "ExternalTaskSensorLink"] => Some(( + qualname.to_string(), + Replacement::Name( + "airflow.sensors.external_task.ExternalTaskSensorLink".to_string(), + ), + )), + ["airflow", "sensors", "time_delta_sensor", "TimeDeltaSensor"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.sensors.time_delta.TimeDeltaSensor".to_string()), + )), + // airflow.secrets + ["airflow", "secrets", "local_filesystem", "load_connections"] => Some(( + qualname.to_string(), + Replacement::Name( + "airflow.secrets.local_filesystem.load_connections_dict".to_string(), + ), + )), + ["airflow", "secrets", "local_filesystem", "get_connection"] => Some(( + qualname.to_string(), + Replacement::Name( + "airflow.secrets.local_filesystem.load_connections_dict".to_string(), + ), + )), // airflow.utils.dates ["airflow", "utils", "dates", "date_range"] => Some(( qualname.to_string(), @@ -158,6 +301,16 @@ fn removed_name(checker: &mut Checker, expr: &Expr, ranged: impl Ranged) { qualname.to_string(), Replacement::Name("pendulum.today('UTC').add(days=-N, ...)".to_string()), )), + + // airflow.utils.helpers + ["airflow", "utils", "helpers", "chain"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.models.baseoperator.chain".to_string()), + )), + ["airflow", "utils", "helpers", "cross_downstream"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.models.baseoperator.cross_downstream".to_string()), + )), // airflow.utils.state ["airflow", "utils", "state", "SHUTDOWN"] => { Some((qualname.to_string(), Replacement::None)) @@ -165,13 +318,42 @@ fn removed_name(checker: &mut Checker, expr: &Expr, ranged: impl Ranged) { ["airflow", "utils", "state", "terminating_states"] => { Some((qualname.to_string(), Replacement::None)) } - // airflow.uilts - ["airflow", "utils", "dag_cycle_tester", "test_cycle"] => { + // airflow.utils.trigger_rule + ["airflow", "utils", "trigger_rule", "TriggerRule", "DUMMY"] => { Some((qualname.to_string(), Replacement::None)) } - ["airflow", "utils", "decorators", "apply_defaults"] => { + ["airflow", "utils", "trigger_rule", "TriggerRule", "NONE_FAILED_OR_SKIPPED"] => { Some((qualname.to_string(), Replacement::None)) } + // airflow.uilts + ["airflow", "utils", "dag_cycle_tester", "test_cycle"] => { + Some((qualname.to_string(), Replacement::None)) + } + ["airflow", "utils", "decorators", "apply_defaults"] => Some(( + qualname.to_string(), + Replacement::Message( + "`apply_defaults` is now unconditionally done and can be safely removed." + .to_string(), + ), + )), + // airflow.www + ["airflow", "www", "auth", "has_access"] => Some(( + qualname.to_string(), + Replacement::Name("airflow.www.auth.has_access_*".to_string()), + )), + ["airflow", "www", "utils", "get_sensitive_variables_fields"] => Some(( + qualname.to_string(), + Replacement::Name( + "airflow.utils.log.secrets_masker.get_sensitive_variables_fields" + .to_string(), + ), + )), + ["airflow", "www", "utils", "should_hide_value_for_key"] => Some(( + qualname.to_string(), + Replacement::Name( + "airflow.utils.log.secrets_masker.should_hide_value_for_key".to_string(), + ), + )), _ => None, }); if let Some((deprecated, replacement)) = result { diff --git a/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR302_AIR302_names.py.snap b/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR302_AIR302_names.py.snap index 13ff8b0fd3f7c..ffed2cf1e5f36 100644 --- a/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR302_AIR302_names.py.snap +++ b/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR302_AIR302_names.py.snap @@ -2,156 +2,537 @@ source: crates/ruff_linter/src/rules/airflow/mod.rs snapshot_kind: text --- -AIR302_names.py:21:1: AIR302 `airflow.triggers.external_task.TaskStateTrigger` is removed in Airflow 3.0 +AIR302_names.py:52:1: AIR302 `airflow.PY36` is removed in Airflow 3.0; use `sys.version_info` instead | -21 | TaskStateTrigger - | ^^^^^^^^^^^^^^^^ AIR302 +50 | from airflow.www.utils import get_sensitive_variables_fields, should_hide_value_for_key +51 | +52 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 + | ^^^^ AIR302 +53 | +54 | AWSAthenaHook | -AIR302_names.py:24:1: AIR302 `airflow.www.auth.has_access` is removed in Airflow 3.0; use `airflow.www.auth.has_access_*` instead +AIR302_names.py:52:7: AIR302 `airflow.PY37` is removed in Airflow 3.0; use `sys.version_info` instead | -24 | has_access - | ^^^^^^^^^^ AIR302 -25 | requires_access +50 | from airflow.www.utils import get_sensitive_variables_fields, should_hide_value_for_key +51 | +52 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 + | ^^^^ AIR302 +53 | +54 | AWSAthenaHook + | + +AIR302_names.py:52:13: AIR302 `airflow.PY38` is removed in Airflow 3.0; use `sys.version_info` instead + | +50 | from airflow.www.utils import get_sensitive_variables_fields, should_hide_value_for_key +51 | +52 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 + | ^^^^ AIR302 +53 | +54 | AWSAthenaHook + | + +AIR302_names.py:52:19: AIR302 `airflow.PY39` is removed in Airflow 3.0; use `sys.version_info` instead + | +50 | from airflow.www.utils import get_sensitive_variables_fields, should_hide_value_for_key +51 | +52 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 + | ^^^^ AIR302 +53 | +54 | AWSAthenaHook + | + +AIR302_names.py:52:25: AIR302 `airflow.PY310` is removed in Airflow 3.0; use `sys.version_info` instead + | +50 | from airflow.www.utils import get_sensitive_variables_fields, should_hide_value_for_key +51 | +52 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 + | ^^^^^ AIR302 +53 | +54 | AWSAthenaHook + | + +AIR302_names.py:52:32: AIR302 `airflow.PY311` is removed in Airflow 3.0; use `sys.version_info` instead + | +50 | from airflow.www.utils import get_sensitive_variables_fields, should_hide_value_for_key +51 | +52 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 + | ^^^^^ AIR302 +53 | +54 | AWSAthenaHook + | + +AIR302_names.py:52:39: AIR302 `airflow.PY312` is removed in Airflow 3.0; use `sys.version_info` instead + | +50 | from airflow.www.utils import get_sensitive_variables_fields, should_hide_value_for_key +51 | +52 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 + | ^^^^^ AIR302 +53 | +54 | AWSAthenaHook + | + +AIR302_names.py:54:1: AIR302 `airflow.contrib.aws_athena_hook.AWSAthenaHook` is removed in Airflow 3.0 + | +52 | PY36, PY37, PY38, PY39, PY310, PY311, PY312 +53 | +54 | AWSAthenaHook + | ^^^^^^^^^^^^^ AIR302 +55 | TaskStateTrigger | -AIR302_names.py:25:1: AIR302 `airflow.api_connexion.security.requires_access` is removed in Airflow 3.0; use `airflow.api_connexion.security.requires_access_*` instead +AIR302_names.py:55:1: AIR302 `airflow.triggers.external_task.TaskStateTrigger` is removed in Airflow 3.0 | -24 | has_access -25 | requires_access +54 | AWSAthenaHook +55 | TaskStateTrigger + | ^^^^^^^^^^^^^^^^ AIR302 +56 | +57 | requires_access + | + +AIR302_names.py:57:1: AIR302 `airflow.api_connexion.security.requires_access` is removed in Airflow 3.0; use `airflow.api_connexion.security.requires_access_*` instead + | +55 | TaskStateTrigger +56 | +57 | requires_access | ^^^^^^^^^^^^^^^ AIR302 -26 | -27 | AllowListValidator +58 | +59 | AllowListValidator | -AIR302_names.py:27:1: AIR302 `airflow.metrics.validators.AllowListValidator` is removed in Airflow 3.0; use `airflow.metrics.validators.PatternAllowListValidator` instead +AIR302_names.py:59:1: AIR302 `airflow.metrics.validators.AllowListValidator` is removed in Airflow 3.0; use `airflow.metrics.validators.PatternAllowListValidator` instead | -25 | requires_access -26 | -27 | AllowListValidator +57 | requires_access +58 | +59 | AllowListValidator | ^^^^^^^^^^^^^^^^^^ AIR302 -28 | BlockListValidator +60 | BlockListValidator | -AIR302_names.py:28:1: AIR302 `airflow.metrics.validators.BlockListValidator` is removed in Airflow 3.0; use `airflow.metrics.validators.PatternBlockListValidator` instead +AIR302_names.py:60:1: AIR302 `airflow.metrics.validators.BlockListValidator` is removed in Airflow 3.0; use `airflow.metrics.validators.PatternBlockListValidator` instead | -27 | AllowListValidator -28 | BlockListValidator +59 | AllowListValidator +60 | BlockListValidator | ^^^^^^^^^^^^^^^^^^ AIR302 -29 | -30 | dates.date_range +61 | +62 | SubDagOperator | -AIR302_names.py:30:7: AIR302 `airflow.utils.dates.date_range` is removed in Airflow 3.0; use `airflow.timetables.` instead +AIR302_names.py:62:1: AIR302 `airflow.operators.subdag.SubDagOperator` is removed in Airflow 3.0 + | +60 | BlockListValidator +61 | +62 | SubDagOperator + | ^^^^^^^^^^^^^^ AIR302 +63 | +64 | dates.date_range | -28 | BlockListValidator -29 | -30 | dates.date_range + +AIR302_names.py:64:7: AIR302 `airflow.utils.dates.date_range` is removed in Airflow 3.0; use `airflow.timetables.` instead + | +62 | SubDagOperator +63 | +64 | dates.date_range | ^^^^^^^^^^ AIR302 -31 | dates.days_ago +65 | dates.days_ago | -AIR302_names.py:31:7: AIR302 `airflow.utils.dates.days_ago` is removed in Airflow 3.0; use `pendulum.today('UTC').add(days=-N, ...)` instead +AIR302_names.py:65:7: AIR302 `airflow.utils.dates.days_ago` is removed in Airflow 3.0; use `pendulum.today('UTC').add(days=-N, ...)` instead | -30 | dates.date_range -31 | dates.days_ago +64 | dates.date_range +65 | dates.days_ago | ^^^^^^^^ AIR302 -32 | -33 | date_range +66 | +67 | date_range | -AIR302_names.py:33:1: AIR302 `airflow.utils.dates.date_range` is removed in Airflow 3.0; use `airflow.timetables.` instead +AIR302_names.py:67:1: AIR302 `airflow.utils.dates.date_range` is removed in Airflow 3.0; use `airflow.timetables.` instead | -31 | dates.days_ago -32 | -33 | date_range +65 | dates.days_ago +66 | +67 | date_range | ^^^^^^^^^^ AIR302 -34 | days_ago -35 | parse_execution_date +68 | days_ago +69 | parse_execution_date | -AIR302_names.py:34:1: AIR302 `airflow.utils.dates.days_ago` is removed in Airflow 3.0; use `pendulum.today('UTC').add(days=-N, ...)` instead +AIR302_names.py:68:1: AIR302 `airflow.utils.dates.days_ago` is removed in Airflow 3.0; use `pendulum.today('UTC').add(days=-N, ...)` instead | -33 | date_range -34 | days_ago +67 | date_range +68 | days_ago | ^^^^^^^^ AIR302 -35 | parse_execution_date -36 | round_time +69 | parse_execution_date +70 | round_time | -AIR302_names.py:35:1: AIR302 `airflow.utils.dates.parse_execution_date` is removed in Airflow 3.0 +AIR302_names.py:69:1: AIR302 `airflow.utils.dates.parse_execution_date` is removed in Airflow 3.0 | -33 | date_range -34 | days_ago -35 | parse_execution_date +67 | date_range +68 | days_ago +69 | parse_execution_date | ^^^^^^^^^^^^^^^^^^^^ AIR302 -36 | round_time -37 | scale_time_units +70 | round_time +71 | scale_time_units | -AIR302_names.py:36:1: AIR302 `airflow.utils.dates.round_time` is removed in Airflow 3.0 +AIR302_names.py:70:1: AIR302 `airflow.utils.dates.round_time` is removed in Airflow 3.0 | -34 | days_ago -35 | parse_execution_date -36 | round_time +68 | days_ago +69 | parse_execution_date +70 | round_time | ^^^^^^^^^^ AIR302 -37 | scale_time_units -38 | infer_time_unit +71 | scale_time_units +72 | infer_time_unit | -AIR302_names.py:37:1: AIR302 `airflow.utils.dates.scale_time_units` is removed in Airflow 3.0 +AIR302_names.py:71:1: AIR302 `airflow.utils.dates.scale_time_units` is removed in Airflow 3.0 | -35 | parse_execution_date -36 | round_time -37 | scale_time_units +69 | parse_execution_date +70 | round_time +71 | scale_time_units | ^^^^^^^^^^^^^^^^ AIR302 -38 | infer_time_unit +72 | infer_time_unit | -AIR302_names.py:38:1: AIR302 `airflow.utils.dates.infer_time_unit` is removed in Airflow 3.0 +AIR302_names.py:72:1: AIR302 `airflow.utils.dates.infer_time_unit` is removed in Airflow 3.0 | -36 | round_time -37 | scale_time_units -38 | infer_time_unit +70 | round_time +71 | scale_time_units +72 | infer_time_unit | ^^^^^^^^^^^^^^^ AIR302 | -AIR302_names.py:45:1: AIR302 `airflow.utils.file.TemporaryDirectory` is removed in Airflow 3.0 +AIR302_names.py:79:1: AIR302 `airflow.configuration.get` is removed in Airflow 3.0; use `airflow.configuration.conf.get` instead + | +77 | dates.datetime_to_nano +78 | +79 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set + | ^^^ AIR302 +80 | +81 | get_connection, load_connections + | + +AIR302_names.py:79:6: AIR302 `airflow.configuration.getboolean` is removed in Airflow 3.0; use `airflow.configuration.conf.getboolean` instead + | +77 | dates.datetime_to_nano +78 | +79 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set + | ^^^^^^^^^^ AIR302 +80 | +81 | get_connection, load_connections + | + +AIR302_names.py:79:18: AIR302 `airflow.configuration.getfloat` is removed in Airflow 3.0; use `airflow.configuration.conf.getfloat` instead + | +77 | dates.datetime_to_nano +78 | +79 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set + | ^^^^^^^^ AIR302 +80 | +81 | get_connection, load_connections + | + +AIR302_names.py:79:28: AIR302 `airflow.configuration.getint` is removed in Airflow 3.0; use `airflow.configuration.conf.getint` instead + | +77 | dates.datetime_to_nano +78 | +79 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set + | ^^^^^^ AIR302 +80 | +81 | get_connection, load_connections + | + +AIR302_names.py:79:36: AIR302 `airflow.configuration.has_option` is removed in Airflow 3.0; use `airflow.configuration.conf.has_option` instead + | +77 | dates.datetime_to_nano +78 | +79 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set + | ^^^^^^^^^^ AIR302 +80 | +81 | get_connection, load_connections + | + +AIR302_names.py:79:48: AIR302 `airflow.configuration.remove_option` is removed in Airflow 3.0; use `airflow.configuration.conf.remove_option` instead + | +77 | dates.datetime_to_nano +78 | +79 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set + | ^^^^^^^^^^^^^ AIR302 +80 | +81 | get_connection, load_connections + | + +AIR302_names.py:79:63: AIR302 `airflow.configuration.as_dict` is removed in Airflow 3.0; use `airflow.configuration.conf.as_dict` instead + | +77 | dates.datetime_to_nano +78 | +79 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set + | ^^^^^^^ AIR302 +80 | +81 | get_connection, load_connections + | + +AIR302_names.py:79:72: AIR302 `airflow.configuration.set` is removed in Airflow 3.0; use `airflow.configuration.conf.set` instead + | +77 | dates.datetime_to_nano +78 | +79 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set + | ^^^ AIR302 +80 | +81 | get_connection, load_connections + | + +AIR302_names.py:81:1: AIR302 `airflow.secrets.local_filesystem.get_connection` is removed in Airflow 3.0; use `airflow.secrets.local_filesystem.load_connections_dict` instead | -43 | dates.datetime_to_nano -44 | -45 | TemporaryDirectory +79 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set +80 | +81 | get_connection, load_connections + | ^^^^^^^^^^^^^^ AIR302 + | + +AIR302_names.py:81:17: AIR302 `airflow.secrets.local_filesystem.load_connections` is removed in Airflow 3.0; use `airflow.secrets.local_filesystem.load_connections_dict` instead + | +79 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set +80 | +81 | get_connection, load_connections + | ^^^^^^^^^^^^^^^^ AIR302 + | + +AIR302_names.py:84:1: AIR302 `airflow.sensors.external_task_sensor.ExternalTaskSensorLink` is removed in Airflow 3.0; use `airflow.sensors.external_task.ExternalTaskSensorLink` instead + | +84 | ExternalTaskSensorLink + | ^^^^^^^^^^^^^^^^^^^^^^ AIR302 +85 | BashOperator +86 | BaseBranchOperator + | + +AIR302_names.py:85:1: AIR302 `airflow.operators.bash_operator.BashOperator` is removed in Airflow 3.0; use `airflow.operators.bash.BashOperator` instead + | +84 | ExternalTaskSensorLink +85 | BashOperator + | ^^^^^^^^^^^^ AIR302 +86 | BaseBranchOperator +87 | EmptyOperator, DummyOperator + | + +AIR302_names.py:86:1: AIR302 `airflow.operators.branch_operator.BaseBranchOperator` is removed in Airflow 3.0; use `airflow.operators.branch.BaseBranchOperator` instead + | +84 | ExternalTaskSensorLink +85 | BashOperator +86 | BaseBranchOperator | ^^^^^^^^^^^^^^^^^^ AIR302 -46 | mkdirs +87 | EmptyOperator, DummyOperator +88 | dummy_operator.EmptyOperator | -AIR302_names.py:46:1: AIR302 `airflow.utils.file.mkdirs` is removed in Airflow 3.0; use `pendulum.today('UTC').add(days=-N, ...)` instead +AIR302_names.py:87:16: AIR302 `airflow.operators.dummy.DummyOperator` is removed in Airflow 3.0; use `airflow.operators.empty.EmptyOperator` instead | -45 | TemporaryDirectory -46 | mkdirs - | ^^^^^^ AIR302 -47 | -48 | SHUTDOWN +85 | BashOperator +86 | BaseBranchOperator +87 | EmptyOperator, DummyOperator + | ^^^^^^^^^^^^^ AIR302 +88 | dummy_operator.EmptyOperator +89 | dummy_operator.DummyOperator | -AIR302_names.py:48:1: AIR302 `airflow.utils.state.SHUTDOWN` is removed in Airflow 3.0 +AIR302_names.py:88:16: AIR302 `airflow.operators.dummy_operator.EmptyOperator` is removed in Airflow 3.0; use `airflow.operators.empty.EmptyOperator` instead | -46 | mkdirs -47 | -48 | SHUTDOWN - | ^^^^^^^^ AIR302 -49 | terminating_states +86 | BaseBranchOperator +87 | EmptyOperator, DummyOperator +88 | dummy_operator.EmptyOperator + | ^^^^^^^^^^^^^ AIR302 +89 | dummy_operator.DummyOperator +90 | EmailOperator | -AIR302_names.py:49:1: AIR302 `airflow.utils.state.terminating_states` is removed in Airflow 3.0 +AIR302_names.py:89:16: AIR302 `airflow.operators.dummy_operator.DummyOperator` is removed in Airflow 3.0; use `airflow.operators.empty.EmptyOperator` instead | -48 | SHUTDOWN -49 | terminating_states +87 | EmptyOperator, DummyOperator +88 | dummy_operator.EmptyOperator +89 | dummy_operator.DummyOperator + | ^^^^^^^^^^^^^ AIR302 +90 | EmailOperator +91 | BaseSensorOperator + | + +AIR302_names.py:90:1: AIR302 `airflow.operators.email_operator.EmailOperator` is removed in Airflow 3.0; use `airflow.operators.email.EmailOperator` instead + | +88 | dummy_operator.EmptyOperator +89 | dummy_operator.DummyOperator +90 | EmailOperator + | ^^^^^^^^^^^^^ AIR302 +91 | BaseSensorOperator +92 | DateTimeSensor + | + +AIR302_names.py:91:1: AIR302 `airflow.sensors.base_sensor_operator.BaseSensorOperator` is removed in Airflow 3.0; use `airflow.sensors.base.BaseSensorOperator` instead + | +89 | dummy_operator.DummyOperator +90 | EmailOperator +91 | BaseSensorOperator | ^^^^^^^^^^^^^^^^^^ AIR302 +92 | DateTimeSensor +93 | (ExternalTaskMarker, ExternalTaskSensor, ExternalTaskSensorLink) | -AIR302_names.py:52:1: AIR302 `airflow.utils.dag_cycle_tester.test_cycle` is removed in Airflow 3.0 +AIR302_names.py:92:1: AIR302 `airflow.sensors.date_time_sensor.DateTimeSensor` is removed in Airflow 3.0; use `airflow.sensors.date_time.DateTimeSensor` instead | -52 | test_cycle - | ^^^^^^^^^^ AIR302 +90 | EmailOperator +91 | BaseSensorOperator +92 | DateTimeSensor + | ^^^^^^^^^^^^^^ AIR302 +93 | (ExternalTaskMarker, ExternalTaskSensor, ExternalTaskSensorLink) +94 | TimeDeltaSensor + | + +AIR302_names.py:93:2: AIR302 `airflow.sensors.external_task_sensor.ExternalTaskMarker` is removed in Airflow 3.0; use `airflow.sensors.external_task.ExternalTaskMarker` instead + | +91 | BaseSensorOperator +92 | DateTimeSensor +93 | (ExternalTaskMarker, ExternalTaskSensor, ExternalTaskSensorLink) + | ^^^^^^^^^^^^^^^^^^ AIR302 +94 | TimeDeltaSensor + | + +AIR302_names.py:93:22: AIR302 `airflow.sensors.external_task_sensor.ExternalTaskSensor` is removed in Airflow 3.0; use `airflow.sensors.external_task.ExternalTaskSensor` instead + | +91 | BaseSensorOperator +92 | DateTimeSensor +93 | (ExternalTaskMarker, ExternalTaskSensor, ExternalTaskSensorLink) + | ^^^^^^^^^^^^^^^^^^ AIR302 +94 | TimeDeltaSensor | + +AIR302_names.py:93:42: AIR302 `airflow.sensors.external_task_sensor.ExternalTaskSensorLink` is removed in Airflow 3.0; use `airflow.sensors.external_task.ExternalTaskSensorLink` instead + | +91 | BaseSensorOperator +92 | DateTimeSensor +93 | (ExternalTaskMarker, ExternalTaskSensor, ExternalTaskSensorLink) + | ^^^^^^^^^^^^^^^^^^^^^^ AIR302 +94 | TimeDeltaSensor + | + +AIR302_names.py:94:1: AIR302 `airflow.sensors.time_delta_sensor.TimeDeltaSensor` is removed in Airflow 3.0; use `airflow.sensors.time_delta.TimeDeltaSensor` instead + | +92 | DateTimeSensor +93 | (ExternalTaskMarker, ExternalTaskSensor, ExternalTaskSensorLink) +94 | TimeDeltaSensor + | ^^^^^^^^^^^^^^^ AIR302 +95 | +96 | apply_defaults + | + +AIR302_names.py:96:1: AIR302 `airflow.utils.decorators.apply_defaults` is removed in Airflow 3.0; `apply_defaults` is now unconditionally done and can be safely removed. + | +94 | TimeDeltaSensor +95 | +96 | apply_defaults + | ^^^^^^^^^^^^^^ AIR302 +97 | +98 | TemporaryDirectory + | + +AIR302_names.py:98:1: AIR302 `airflow.utils.file.TemporaryDirectory` is removed in Airflow 3.0 + | +96 | apply_defaults +97 | +98 | TemporaryDirectory + | ^^^^^^^^^^^^^^^^^^ AIR302 +99 | mkdirs + | + +AIR302_names.py:99:1: AIR302 `airflow.utils.file.mkdirs` is removed in Airflow 3.0; use `pendulum.today('UTC').add(days=-N, ...)` instead + | + 98 | TemporaryDirectory + 99 | mkdirs + | ^^^^^^ AIR302 +100 | +101 | chain + | + +AIR302_names.py:101:1: AIR302 `airflow.utils.helpers.chain` is removed in Airflow 3.0; use `airflow.models.baseoperator.chain` instead + | + 99 | mkdirs +100 | +101 | chain + | ^^^^^ AIR302 +102 | cross_downstream + | + +AIR302_names.py:102:1: AIR302 `airflow.utils.helpers.cross_downstream` is removed in Airflow 3.0; use `airflow.models.baseoperator.cross_downstream` instead + | +101 | chain +102 | cross_downstream + | ^^^^^^^^^^^^^^^^ AIR302 +103 | +104 | SHUTDOWN + | + +AIR302_names.py:104:1: AIR302 `airflow.utils.state.SHUTDOWN` is removed in Airflow 3.0 + | +102 | cross_downstream +103 | +104 | SHUTDOWN + | ^^^^^^^^ AIR302 +105 | terminating_states + | + +AIR302_names.py:105:1: AIR302 `airflow.utils.state.terminating_states` is removed in Airflow 3.0 + | +104 | SHUTDOWN +105 | terminating_states + | ^^^^^^^^^^^^^^^^^^ AIR302 +106 | +107 | TriggerRule.DUMMY + | + +AIR302_names.py:107:13: AIR302 `airflow.utils.trigger_rule.TriggerRule.DUMMY` is removed in Airflow 3.0 + | +105 | terminating_states +106 | +107 | TriggerRule.DUMMY + | ^^^^^ AIR302 +108 | TriggerRule.NONE_FAILED_OR_SKIPPED + | + +AIR302_names.py:108:13: AIR302 `airflow.utils.trigger_rule.TriggerRule.NONE_FAILED_OR_SKIPPED` is removed in Airflow 3.0 + | +107 | TriggerRule.DUMMY +108 | TriggerRule.NONE_FAILED_OR_SKIPPED + | ^^^^^^^^^^^^^^^^^^^^^^ AIR302 +109 | +110 | test_cycle + | + +AIR302_names.py:110:1: AIR302 `airflow.utils.dag_cycle_tester.test_cycle` is removed in Airflow 3.0 + | +108 | TriggerRule.NONE_FAILED_OR_SKIPPED +109 | +110 | test_cycle + | ^^^^^^^^^^ AIR302 +111 | +112 | has_access + | + +AIR302_names.py:112:1: AIR302 `airflow.www.auth.has_access` is removed in Airflow 3.0; use `airflow.www.auth.has_access_*` instead + | +110 | test_cycle +111 | +112 | has_access + | ^^^^^^^^^^ AIR302 +113 | get_sensitive_variables_fields, should_hide_value_for_key + | + +AIR302_names.py:113:1: AIR302 `airflow.www.utils.get_sensitive_variables_fields` is removed in Airflow 3.0; use `airflow.utils.log.secrets_masker.get_sensitive_variables_fields` instead + | +112 | has_access +113 | get_sensitive_variables_fields, should_hide_value_for_key + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302 + | + +AIR302_names.py:113:33: AIR302 `airflow.www.utils.should_hide_value_for_key` is removed in Airflow 3.0; use `airflow.utils.log.secrets_masker.should_hide_value_for_key` instead + | +112 | has_access +113 | get_sensitive_variables_fields, should_hide_value_for_key + | ^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302 + |