diff --git a/crates/ruff_linter/resources/test/fixtures/airflow/AIR302_context.py b/crates/ruff_linter/resources/test/fixtures/airflow/AIR302_context.py index afbe57e8301060..e58bddcf15859c 100644 --- a/crates/ruff_linter/resources/test/fixtures/airflow/AIR302_context.py +++ b/crates/ruff_linter/resources/test/fixtures/airflow/AIR302_context.py @@ -1,4 +1,9 @@ -from airflow.decorators import task +from airflow.models import DAG +from airflow.operators.dummy import DummyOperator +from datetime import datetime +from airflow.plugins_manager import AirflowPlugin +from airflow.decorators import task, get_current_context +from airflow.models.baseoperator import BaseOperator @task def print_config(**context): @@ -17,3 +22,57 @@ def print_config(**context): tomorrow_ds = context["tomorrow_ds"] yesterday_ds = context["yesterday_ds"] yesterday_ds_nodash = context["yesterday_ds_nodash"] + +with DAG( + dag_id="example_dag", + schedule_interval="@daily", + start_date=datetime(2023, 1, 1), + template_searchpath=["/templates"], +) as dag: + task1 = DummyOperator( + task_id="task1", + params={ + # Removed variables in template + "execution_date": "{{ execution_date }}", + "next_ds": "{{ next_ds }}", + "prev_ds": "{{ prev_ds }}" + }, + ) + +class CustomMacrosPlugin(AirflowPlugin): + name = "custom_macros" + macros = { + "execution_date_macro": lambda context: context["execution_date"], + "next_ds_macro": lambda context: context["next_ds"] + } + +@task +def print_config(): + context = get_current_context() + execution_date = context["execution_date"] + next_ds = context["next_ds"] + next_ds_nodash = context["next_ds_nodash"] + next_execution_date = context["next_execution_date"] + prev_ds = context["prev_ds"] + prev_ds_nodash = context["prev_ds_nodash"] + prev_execution_date = context["prev_execution_date"] + prev_execution_date_success = context["prev_execution_date_success"] + tomorrow_ds = context["tomorrow_ds"] + yesterday_ds = context["yesterday_ds"] + yesterday_ds_nodash = context["yesterday_ds_nodash"] + +class CustomOperator(BaseOperator): + def execute(self, context): + execution_date = context["execution_date"] + next_ds = context["next_ds"] + next_ds_nodash = context["next_ds_nodash"] + next_execution_date = context["next_execution_date"] + prev_ds = context["prev_ds"] + prev_ds_nodash = context["prev_ds_nodash"] + prev_execution_date = context["prev_execution_date"] + prev_execution_date_success = context["prev_execution_date_success"] + tomorrow_ds = context["tomorrow_ds"] + yesterday_ds = context["yesterday_ds"] + yesterday_ds_nodash = context["yesterday_ds_nodash"] + + 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 882b45795d1921..1901a1ef9a7798 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 @@ -15,6 +15,7 @@ enum Replacement { None, Name(&'static str), Message(&'static str), + ContextRemovalMessage(&'static str), } /// ## What it does @@ -44,7 +45,6 @@ enum Replacement { pub(crate) struct Airflow3Removal { deprecated: String, replacement: Replacement, - is_context_variable: bool, } impl Violation for Airflow3Removal { @@ -55,7 +55,6 @@ impl Violation for Airflow3Removal { let Airflow3Removal { deprecated, replacement, - is_context_variable, } = self; match replacement { Replacement::None => format!("`{deprecated}` is removed in Airflow 3.0"), @@ -63,11 +62,10 @@ impl Violation for Airflow3Removal { format!("`{deprecated}` is removed in Airflow 3.0") } Replacement::Message(message) => { - if *is_context_variable { - format!("`{deprecated}` {message}") - } else { - format!("`{deprecated}` is removed in Airflow 3.0; {message}") - } + format!("`{deprecated}` is removed in Airflow 3.0; {message}") + } + Replacement::ContextRemovalMessage(message) => { + format!("`{deprecated}` {message}") } } } @@ -95,7 +93,6 @@ fn diagnostic_for_argument( Some(name) => Replacement::Name(name), None => Replacement::None, }, - is_context_variable: false, }, keyword .arg @@ -213,7 +210,6 @@ fn removed_method(checker: &mut Checker, expr: &Expr) { Airflow3Removal { deprecated: attr.to_string(), replacement, - is_context_variable: false, }, attr.range(), )); @@ -651,7 +647,6 @@ fn removed_name(checker: &mut Checker, expr: &Expr, ranged: impl Ranged) { Airflow3Removal { deprecated, replacement, - is_context_variable: false, }, ranged.range(), )); @@ -667,31 +662,32 @@ fn extract_name_from_slice(slice: &Expr) -> Option { } pub(crate) fn removed_context_variable(checker: &mut Checker, expr: &Expr) { + const REMOVED_CONTEXT_KEYS: [&str; 12] = [ + "conf", + "execution_date", + "next_ds", + "next_ds_nodash", + "next_execution_date", + "prev_ds", + "prev_ds_nodash", + "prev_execution_date", + "prev_execution_date_success", + "tomorrow_ds", + "yesterday_ds", + "yesterday_ds_nodash", + ]; + if let Expr::Subscript(ExprSubscript { value, slice, .. }) = expr { if let Expr::Name(ExprName { id, .. }) = &**value { if id.as_str() == "context" { if let Some(key) = extract_name_from_slice(slice) { - const REMOVED_CONTEXT_KEYS: [&str; 11] = [ - "execution_date", - "next_ds", - "next_ds_nodash", - "next_execution_date", - "prev_ds", - "prev_ds_nodash", - "prev_execution_date", - "prev_execution_date_success", - "tomorrow_ds", - "yesterday_ds", - "yesterday_ds_nodash", - ]; if REMOVED_CONTEXT_KEYS.contains(&key.as_str()) { checker.diagnostics.push(Diagnostic::new( Airflow3Removal { deprecated: key, - replacement: Replacement::Message( - "is removed in the Airflow context in Airflow 3.0", + replacement: Replacement::ContextRemovalMessage( + "is removed in Airflow 3.0.", ), - is_context_variable: true, }, slice.range(), )); @@ -700,6 +696,23 @@ pub(crate) fn removed_context_variable(checker: &mut Checker, expr: &Expr) { } } } + + if let Expr::StringLiteral(ExprStringLiteral { value, .. }) = expr { + let value_str = value.to_string(); + for key in REMOVED_CONTEXT_KEYS { + if value_str.contains(&format!("{{{{ {key} }}}}")) { + checker.diagnostics.push(Diagnostic::new( + Airflow3Removal { + deprecated: key.to_string(), + replacement: Replacement::ContextRemovalMessage( + "is removed in Airflow 3.0.", + ), + }, + expr.range(), + )); + } + } + } } /// AIR302 diff --git a/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR302_AIR302_context.py.snap b/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR302_AIR302_context.py.snap index 257237a9d27963..cc54b75e726d9c 100644 --- a/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR302_AIR302_context.py.snap +++ b/crates/ruff_linter/src/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR302_AIR302_context.py.snap @@ -2,108 +2,377 @@ source: crates/ruff_linter/src/rules/airflow/mod.rs snapshot_kind: text --- -AIR302_context.py:9:30: AIR302 `execution_date` is removed in the Airflow context in Airflow 3.0 +AIR302_context.py:14:30: AIR302 `execution_date` is removed in Airflow 3.0. | - 8 | # Removed usage - should trigger violations - 9 | execution_date = context["execution_date"] +13 | # Removed usage - should trigger violations +14 | execution_date = context["execution_date"] | ^^^^^^^^^^^^^^^^ AIR302 -10 | next_ds = context["next_ds"] -11 | next_ds_nodash = context["next_ds_nodash"] +15 | next_ds = context["next_ds"] +16 | next_ds_nodash = context["next_ds_nodash"] | -AIR302_context.py:10:23: AIR302 `next_ds` is removed in the Airflow context in Airflow 3.0 +AIR302_context.py:15:23: AIR302 `next_ds` is removed in Airflow 3.0. | - 8 | # Removed usage - should trigger violations - 9 | execution_date = context["execution_date"] -10 | next_ds = context["next_ds"] +13 | # Removed usage - should trigger violations +14 | execution_date = context["execution_date"] +15 | next_ds = context["next_ds"] | ^^^^^^^^^ AIR302 -11 | next_ds_nodash = context["next_ds_nodash"] -12 | next_execution_date = context["next_execution_date"] +16 | next_ds_nodash = context["next_ds_nodash"] +17 | next_execution_date = context["next_execution_date"] | -AIR302_context.py:11:30: AIR302 `next_ds_nodash` is removed in the Airflow context in Airflow 3.0 +AIR302_context.py:16:30: AIR302 `next_ds_nodash` is removed in Airflow 3.0. | - 9 | execution_date = context["execution_date"] -10 | next_ds = context["next_ds"] -11 | next_ds_nodash = context["next_ds_nodash"] +14 | execution_date = context["execution_date"] +15 | next_ds = context["next_ds"] +16 | next_ds_nodash = context["next_ds_nodash"] | ^^^^^^^^^^^^^^^^ AIR302 -12 | next_execution_date = context["next_execution_date"] -13 | prev_ds = context["prev_ds"] +17 | next_execution_date = context["next_execution_date"] +18 | prev_ds = context["prev_ds"] | -AIR302_context.py:12:35: AIR302 `next_execution_date` is removed in the Airflow context in Airflow 3.0 +AIR302_context.py:17:35: AIR302 `next_execution_date` is removed in Airflow 3.0. | -10 | next_ds = context["next_ds"] -11 | next_ds_nodash = context["next_ds_nodash"] -12 | next_execution_date = context["next_execution_date"] +15 | next_ds = context["next_ds"] +16 | next_ds_nodash = context["next_ds_nodash"] +17 | next_execution_date = context["next_execution_date"] | ^^^^^^^^^^^^^^^^^^^^^ AIR302 -13 | prev_ds = context["prev_ds"] -14 | prev_ds_nodash = context["prev_ds_nodash"] +18 | prev_ds = context["prev_ds"] +19 | prev_ds_nodash = context["prev_ds_nodash"] | -AIR302_context.py:13:23: AIR302 `prev_ds` is removed in the Airflow context in Airflow 3.0 +AIR302_context.py:18:23: AIR302 `prev_ds` is removed in Airflow 3.0. | -11 | next_ds_nodash = context["next_ds_nodash"] -12 | next_execution_date = context["next_execution_date"] -13 | prev_ds = context["prev_ds"] +16 | next_ds_nodash = context["next_ds_nodash"] +17 | next_execution_date = context["next_execution_date"] +18 | prev_ds = context["prev_ds"] | ^^^^^^^^^ AIR302 -14 | prev_ds_nodash = context["prev_ds_nodash"] -15 | prev_execution_date = context["prev_execution_date"] +19 | prev_ds_nodash = context["prev_ds_nodash"] +20 | prev_execution_date = context["prev_execution_date"] | -AIR302_context.py:14:30: AIR302 `prev_ds_nodash` is removed in the Airflow context in Airflow 3.0 +AIR302_context.py:19:30: AIR302 `prev_ds_nodash` is removed in Airflow 3.0. | -12 | next_execution_date = context["next_execution_date"] -13 | prev_ds = context["prev_ds"] -14 | prev_ds_nodash = context["prev_ds_nodash"] +17 | next_execution_date = context["next_execution_date"] +18 | prev_ds = context["prev_ds"] +19 | prev_ds_nodash = context["prev_ds_nodash"] | ^^^^^^^^^^^^^^^^ AIR302 -15 | prev_execution_date = context["prev_execution_date"] -16 | prev_execution_date_success = context["prev_execution_date_success"] +20 | prev_execution_date = context["prev_execution_date"] +21 | prev_execution_date_success = context["prev_execution_date_success"] | -AIR302_context.py:15:35: AIR302 `prev_execution_date` is removed in the Airflow context in Airflow 3.0 +AIR302_context.py:20:35: AIR302 `prev_execution_date` is removed in Airflow 3.0. | -13 | prev_ds = context["prev_ds"] -14 | prev_ds_nodash = context["prev_ds_nodash"] -15 | prev_execution_date = context["prev_execution_date"] +18 | prev_ds = context["prev_ds"] +19 | prev_ds_nodash = context["prev_ds_nodash"] +20 | prev_execution_date = context["prev_execution_date"] | ^^^^^^^^^^^^^^^^^^^^^ AIR302 -16 | prev_execution_date_success = context["prev_execution_date_success"] -17 | tomorrow_ds = context["tomorrow_ds"] +21 | prev_execution_date_success = context["prev_execution_date_success"] +22 | tomorrow_ds = context["tomorrow_ds"] | -AIR302_context.py:16:43: AIR302 `prev_execution_date_success` is removed in the Airflow context in Airflow 3.0 +AIR302_context.py:21:43: AIR302 `prev_execution_date_success` is removed in Airflow 3.0. | -14 | prev_ds_nodash = context["prev_ds_nodash"] -15 | prev_execution_date = context["prev_execution_date"] -16 | prev_execution_date_success = context["prev_execution_date_success"] +19 | prev_ds_nodash = context["prev_ds_nodash"] +20 | prev_execution_date = context["prev_execution_date"] +21 | prev_execution_date_success = context["prev_execution_date_success"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302 -17 | tomorrow_ds = context["tomorrow_ds"] -18 | yesterday_ds = context["yesterday_ds"] +22 | tomorrow_ds = context["tomorrow_ds"] +23 | yesterday_ds = context["yesterday_ds"] | -AIR302_context.py:17:27: AIR302 `tomorrow_ds` is removed in the Airflow context in Airflow 3.0 +AIR302_context.py:22:27: AIR302 `tomorrow_ds` is removed in Airflow 3.0. | -15 | prev_execution_date = context["prev_execution_date"] -16 | prev_execution_date_success = context["prev_execution_date_success"] -17 | tomorrow_ds = context["tomorrow_ds"] +20 | prev_execution_date = context["prev_execution_date"] +21 | prev_execution_date_success = context["prev_execution_date_success"] +22 | tomorrow_ds = context["tomorrow_ds"] | ^^^^^^^^^^^^^ AIR302 -18 | yesterday_ds = context["yesterday_ds"] -19 | yesterday_ds_nodash = context["yesterday_ds_nodash"] +23 | yesterday_ds = context["yesterday_ds"] +24 | yesterday_ds_nodash = context["yesterday_ds_nodash"] | -AIR302_context.py:18:28: AIR302 `yesterday_ds` is removed in the Airflow context in Airflow 3.0 +AIR302_context.py:23:28: AIR302 `yesterday_ds` is removed in Airflow 3.0. | -16 | prev_execution_date_success = context["prev_execution_date_success"] -17 | tomorrow_ds = context["tomorrow_ds"] -18 | yesterday_ds = context["yesterday_ds"] +21 | prev_execution_date_success = context["prev_execution_date_success"] +22 | tomorrow_ds = context["tomorrow_ds"] +23 | yesterday_ds = context["yesterday_ds"] | ^^^^^^^^^^^^^^ AIR302 -19 | yesterday_ds_nodash = context["yesterday_ds_nodash"] +24 | yesterday_ds_nodash = context["yesterday_ds_nodash"] | -AIR302_context.py:19:35: AIR302 `yesterday_ds_nodash` is removed in the Airflow context in Airflow 3.0 +AIR302_context.py:24:35: AIR302 `yesterday_ds_nodash` is removed in Airflow 3.0. | -17 | tomorrow_ds = context["tomorrow_ds"] -18 | yesterday_ds = context["yesterday_ds"] -19 | yesterday_ds_nodash = context["yesterday_ds_nodash"] +22 | tomorrow_ds = context["tomorrow_ds"] +23 | yesterday_ds = context["yesterday_ds"] +24 | yesterday_ds_nodash = context["yesterday_ds_nodash"] | ^^^^^^^^^^^^^^^^^^^^^ AIR302 +25 | +26 | with DAG( + | + +AIR302_context.py:28:5: AIR302 [*] `schedule_interval` is removed in Airflow 3.0 + | +26 | with DAG( +27 | dag_id="example_dag", +28 | schedule_interval="@daily", + | ^^^^^^^^^^^^^^^^^ AIR302 +29 | start_date=datetime(2023, 1, 1), +30 | template_searchpath=["/templates"], + | + = help: Use `schedule` instead + +ℹ Safe fix +25 25 | +26 26 | with DAG( +27 27 | dag_id="example_dag", +28 |- schedule_interval="@daily", + 28 |+ schedule="@daily", +29 29 | start_date=datetime(2023, 1, 1), +30 30 | template_searchpath=["/templates"], +31 31 | ) as dag: + +AIR302_context.py:32:13: AIR302 `airflow.operators.dummy.DummyOperator` is removed in Airflow 3.0 + | +30 | template_searchpath=["/templates"], +31 | ) as dag: +32 | task1 = DummyOperator( + | ^^^^^^^^^^^^^ AIR302 +33 | task_id="task1", +34 | params={ + | + = help: Use `airflow.operators.empty.EmptyOperator` instead + +AIR302_context.py:45:57: AIR302 `execution_date` is removed in Airflow 3.0. + | +43 | name = "custom_macros" +44 | macros = { +45 | "execution_date_macro": lambda context: context["execution_date"], + | ^^^^^^^^^^^^^^^^ AIR302 +46 | "next_ds_macro": lambda context: context["next_ds"] +47 | } + | + +AIR302_context.py:46:50: AIR302 `next_ds` is removed in Airflow 3.0. + | +44 | macros = { +45 | "execution_date_macro": lambda context: context["execution_date"], +46 | "next_ds_macro": lambda context: context["next_ds"] + | ^^^^^^^^^ AIR302 +47 | } + | + +AIR302_context.py:52:30: AIR302 `execution_date` is removed in Airflow 3.0. + | +50 | def print_config(): +51 | context = get_current_context() +52 | execution_date = context["execution_date"] + | ^^^^^^^^^^^^^^^^ AIR302 +53 | next_ds = context["next_ds"] +54 | next_ds_nodash = context["next_ds_nodash"] + | + +AIR302_context.py:53:23: AIR302 `next_ds` is removed in Airflow 3.0. + | +51 | context = get_current_context() +52 | execution_date = context["execution_date"] +53 | next_ds = context["next_ds"] + | ^^^^^^^^^ AIR302 +54 | next_ds_nodash = context["next_ds_nodash"] +55 | next_execution_date = context["next_execution_date"] + | + +AIR302_context.py:54:30: AIR302 `next_ds_nodash` is removed in Airflow 3.0. + | +52 | execution_date = context["execution_date"] +53 | next_ds = context["next_ds"] +54 | next_ds_nodash = context["next_ds_nodash"] + | ^^^^^^^^^^^^^^^^ AIR302 +55 | next_execution_date = context["next_execution_date"] +56 | prev_ds = context["prev_ds"] + | + +AIR302_context.py:55:35: AIR302 `next_execution_date` is removed in Airflow 3.0. + | +53 | next_ds = context["next_ds"] +54 | next_ds_nodash = context["next_ds_nodash"] +55 | next_execution_date = context["next_execution_date"] + | ^^^^^^^^^^^^^^^^^^^^^ AIR302 +56 | prev_ds = context["prev_ds"] +57 | prev_ds_nodash = context["prev_ds_nodash"] + | + +AIR302_context.py:56:23: AIR302 `prev_ds` is removed in Airflow 3.0. + | +54 | next_ds_nodash = context["next_ds_nodash"] +55 | next_execution_date = context["next_execution_date"] +56 | prev_ds = context["prev_ds"] + | ^^^^^^^^^ AIR302 +57 | prev_ds_nodash = context["prev_ds_nodash"] +58 | prev_execution_date = context["prev_execution_date"] + | + +AIR302_context.py:57:30: AIR302 `prev_ds_nodash` is removed in Airflow 3.0. + | +55 | next_execution_date = context["next_execution_date"] +56 | prev_ds = context["prev_ds"] +57 | prev_ds_nodash = context["prev_ds_nodash"] + | ^^^^^^^^^^^^^^^^ AIR302 +58 | prev_execution_date = context["prev_execution_date"] +59 | prev_execution_date_success = context["prev_execution_date_success"] + | + +AIR302_context.py:58:35: AIR302 `prev_execution_date` is removed in Airflow 3.0. + | +56 | prev_ds = context["prev_ds"] +57 | prev_ds_nodash = context["prev_ds_nodash"] +58 | prev_execution_date = context["prev_execution_date"] + | ^^^^^^^^^^^^^^^^^^^^^ AIR302 +59 | prev_execution_date_success = context["prev_execution_date_success"] +60 | tomorrow_ds = context["tomorrow_ds"] + | + +AIR302_context.py:59:43: AIR302 `prev_execution_date_success` is removed in Airflow 3.0. + | +57 | prev_ds_nodash = context["prev_ds_nodash"] +58 | prev_execution_date = context["prev_execution_date"] +59 | prev_execution_date_success = context["prev_execution_date_success"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302 +60 | tomorrow_ds = context["tomorrow_ds"] +61 | yesterday_ds = context["yesterday_ds"] + | + +AIR302_context.py:60:27: AIR302 `tomorrow_ds` is removed in Airflow 3.0. + | +58 | prev_execution_date = context["prev_execution_date"] +59 | prev_execution_date_success = context["prev_execution_date_success"] +60 | tomorrow_ds = context["tomorrow_ds"] + | ^^^^^^^^^^^^^ AIR302 +61 | yesterday_ds = context["yesterday_ds"] +62 | yesterday_ds_nodash = context["yesterday_ds_nodash"] + | + +AIR302_context.py:61:28: AIR302 `yesterday_ds` is removed in Airflow 3.0. + | +59 | prev_execution_date_success = context["prev_execution_date_success"] +60 | tomorrow_ds = context["tomorrow_ds"] +61 | yesterday_ds = context["yesterday_ds"] + | ^^^^^^^^^^^^^^ AIR302 +62 | yesterday_ds_nodash = context["yesterday_ds_nodash"] + | + +AIR302_context.py:62:35: AIR302 `yesterday_ds_nodash` is removed in Airflow 3.0. + | +60 | tomorrow_ds = context["tomorrow_ds"] +61 | yesterday_ds = context["yesterday_ds"] +62 | yesterday_ds_nodash = context["yesterday_ds_nodash"] + | ^^^^^^^^^^^^^^^^^^^^^ AIR302 +63 | +64 | class CustomOperator(BaseOperator): + | + +AIR302_context.py:66:34: AIR302 `execution_date` is removed in Airflow 3.0. + | +64 | class CustomOperator(BaseOperator): +65 | def execute(self, context): +66 | execution_date = context["execution_date"] + | ^^^^^^^^^^^^^^^^ AIR302 +67 | next_ds = context["next_ds"] +68 | next_ds_nodash = context["next_ds_nodash"] + | + +AIR302_context.py:67:27: AIR302 `next_ds` is removed in Airflow 3.0. + | +65 | def execute(self, context): +66 | execution_date = context["execution_date"] +67 | next_ds = context["next_ds"] + | ^^^^^^^^^ AIR302 +68 | next_ds_nodash = context["next_ds_nodash"] +69 | next_execution_date = context["next_execution_date"] + | + +AIR302_context.py:68:34: AIR302 `next_ds_nodash` is removed in Airflow 3.0. + | +66 | execution_date = context["execution_date"] +67 | next_ds = context["next_ds"] +68 | next_ds_nodash = context["next_ds_nodash"] + | ^^^^^^^^^^^^^^^^ AIR302 +69 | next_execution_date = context["next_execution_date"] +70 | prev_ds = context["prev_ds"] + | + +AIR302_context.py:69:39: AIR302 `next_execution_date` is removed in Airflow 3.0. + | +67 | next_ds = context["next_ds"] +68 | next_ds_nodash = context["next_ds_nodash"] +69 | next_execution_date = context["next_execution_date"] + | ^^^^^^^^^^^^^^^^^^^^^ AIR302 +70 | prev_ds = context["prev_ds"] +71 | prev_ds_nodash = context["prev_ds_nodash"] + | + +AIR302_context.py:70:27: AIR302 `prev_ds` is removed in Airflow 3.0. + | +68 | next_ds_nodash = context["next_ds_nodash"] +69 | next_execution_date = context["next_execution_date"] +70 | prev_ds = context["prev_ds"] + | ^^^^^^^^^ AIR302 +71 | prev_ds_nodash = context["prev_ds_nodash"] +72 | prev_execution_date = context["prev_execution_date"] + | + +AIR302_context.py:71:34: AIR302 `prev_ds_nodash` is removed in Airflow 3.0. + | +69 | next_execution_date = context["next_execution_date"] +70 | prev_ds = context["prev_ds"] +71 | prev_ds_nodash = context["prev_ds_nodash"] + | ^^^^^^^^^^^^^^^^ AIR302 +72 | prev_execution_date = context["prev_execution_date"] +73 | prev_execution_date_success = context["prev_execution_date_success"] + | + +AIR302_context.py:72:39: AIR302 `prev_execution_date` is removed in Airflow 3.0. + | +70 | prev_ds = context["prev_ds"] +71 | prev_ds_nodash = context["prev_ds_nodash"] +72 | prev_execution_date = context["prev_execution_date"] + | ^^^^^^^^^^^^^^^^^^^^^ AIR302 +73 | prev_execution_date_success = context["prev_execution_date_success"] +74 | tomorrow_ds = context["tomorrow_ds"] + | + +AIR302_context.py:73:47: AIR302 `prev_execution_date_success` is removed in Airflow 3.0. + | +71 | prev_ds_nodash = context["prev_ds_nodash"] +72 | prev_execution_date = context["prev_execution_date"] +73 | prev_execution_date_success = context["prev_execution_date_success"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302 +74 | tomorrow_ds = context["tomorrow_ds"] +75 | yesterday_ds = context["yesterday_ds"] + | + +AIR302_context.py:74:31: AIR302 `tomorrow_ds` is removed in Airflow 3.0. + | +72 | prev_execution_date = context["prev_execution_date"] +73 | prev_execution_date_success = context["prev_execution_date_success"] +74 | tomorrow_ds = context["tomorrow_ds"] + | ^^^^^^^^^^^^^ AIR302 +75 | yesterday_ds = context["yesterday_ds"] +76 | yesterday_ds_nodash = context["yesterday_ds_nodash"] + | + +AIR302_context.py:75:32: AIR302 `yesterday_ds` is removed in Airflow 3.0. + | +73 | prev_execution_date_success = context["prev_execution_date_success"] +74 | tomorrow_ds = context["tomorrow_ds"] +75 | yesterday_ds = context["yesterday_ds"] + | ^^^^^^^^^^^^^^ AIR302 +76 | yesterday_ds_nodash = context["yesterday_ds_nodash"] + | + +AIR302_context.py:76:39: AIR302 `yesterday_ds_nodash` is removed in Airflow 3.0. + | +74 | tomorrow_ds = context["tomorrow_ds"] +75 | yesterday_ds = context["yesterday_ds"] +76 | yesterday_ds_nodash = context["yesterday_ds_nodash"] + | ^^^^^^^^^^^^^^^^^^^^^ AIR302 |