Compare commits

...

10 Commits

5 changed files with 399 additions and 318 deletions

View File

@@ -1,7 +1,8 @@
from __future__ import annotations
from datetime import datetime from datetime import datetime
import pendulum import pendulum
from airflow.decorators import dag, task from airflow.decorators import dag, task
from airflow.models import DAG from airflow.models import DAG
from airflow.models.baseoperator import BaseOperator from airflow.models.baseoperator import BaseOperator
@@ -13,30 +14,22 @@ from airflow.utils.context import get_current_context
def access_invalid_key_in_context(**context): def access_invalid_key_in_context(**context):
print("access invalid key", context["conf"]) print("access invalid key", context["conf"])
print("access invalid key", context.get("conf"))
@task @task
def access_invalid_key_task_out_of_dag(**context): def access_invalid_key_task_out_of_dag(**context):
print("access invalid key", context["conf"])
print("access invalid key", context.get("conf")) print("access invalid key", context.get("conf"))
@dag(
schedule=None,
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
catchup=False,
tags=[""],
)
def invalid_dag():
@task()
def access_invalid_key_task(**context):
print("access invalid key", context.get("conf"))
task1 = PythonOperator( @task
task_id="task1", def access_invalid_argument_task_out_of_dag(
python_callable=access_invalid_key_in_context, execution_date, tomorrow_ds, logical_date, **context
) ):
access_invalid_key_task() >> task1 print("execution date", execution_date)
access_invalid_key_task_out_of_dag() print("access invalid key", context.get("conf"))
invalid_dag()
@task @task
def print_config(**context): def print_config(**context):
@@ -56,31 +49,9 @@ def print_config(**context):
yesterday_ds = context["yesterday_ds"] yesterday_ds = context["yesterday_ds"]
yesterday_ds_nodash = context["yesterday_ds_nodash"] 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 @task
def print_config(): def print_config_with_get_current_context():
context = get_current_context() context = get_current_context()
execution_date = context["execution_date"] execution_date = context["execution_date"]
next_ds = context["next_ds"] next_ds = context["next_ds"]
@@ -94,8 +65,74 @@ def print_config():
yesterday_ds = context["yesterday_ds"] yesterday_ds = context["yesterday_ds"]
yesterday_ds_nodash = context["yesterday_ds_nodash"] yesterday_ds_nodash = context["yesterday_ds_nodash"]
@task(task_id="print_the_context")
def print_context(ds=None, **kwargs):
"""Print the Airflow context and ds variable from the context."""
print(ds)
print(kwargs.get("tomorrow_ds"))
c = get_current_context()
c.get("execution_date")
@dag(
schedule=None,
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
catchup=False,
tags=[""],
)
def invalid_dag():
@task()
def access_invalid_key_task(**context):
print("access invalid key", context.get("conf"))
@task()
def access_invalid_key_explicit_task(execution_date):
print(execution_date)
task1 = PythonOperator(
task_id="task1",
python_callable=access_invalid_key_in_context,
)
access_invalid_key_task() >> task1
access_invalid_key_explicit_task()
access_invalid_argument_task_out_of_dag()
access_invalid_key_task_out_of_dag()
print_config()
print_config_with_get_current_context()
print_context()
invalid_dag()
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"],
}
class CustomOperator(BaseOperator): class CustomOperator(BaseOperator):
def execute(self, context): def execute(self, next_ds, context):
execution_date = context["execution_date"] execution_date = context["execution_date"]
next_ds = context["next_ds"] next_ds = context["next_ds"]
next_ds_nodash = context["next_ds_nodash"] next_ds_nodash = context["next_ds_nodash"]
@@ -108,18 +145,6 @@ class CustomOperator(BaseOperator):
yesterday_ds = context["yesterday_ds"] yesterday_ds = context["yesterday_ds"]
yesterday_ds_nodash = context["yesterday_ds_nodash"] yesterday_ds_nodash = context["yesterday_ds_nodash"]
@task
def access_invalid_argument_task_out_of_dag(execution_date, tomorrow_ds, logical_date, **context):
print("execution date", execution_date)
print("access invalid key", context.get("conf"))
@task(task_id="print_the_context")
def print_context(ds=None, **kwargs):
"""Print the Airflow context and ds variable from the context."""
print(ds)
print(kwargs.get("tomorrow_ds"))
c = get_current_context()
c.get("execution_date")
class CustomOperatorNew(BaseOperator): class CustomOperatorNew(BaseOperator):
def execute(self, context): def execute(self, context):

View File

@@ -176,7 +176,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
pyupgrade::rules::use_pep646_unpack(checker, subscript); pyupgrade::rules::use_pep646_unpack(checker, subscript);
} }
if checker.enabled(Rule::Airflow3Removal) { if checker.enabled(Rule::Airflow3Removal) {
airflow::rules::removed_in_3(checker, expr); airflow::rules::airflow_3_removal_expr(checker, expr);
} }
pandas_vet::rules::subscript(checker, value, expr); pandas_vet::rules::subscript(checker, value, expr);
} }
@@ -227,7 +227,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
refurb::rules::regex_flag_alias(checker, expr); refurb::rules::regex_flag_alias(checker, expr);
} }
if checker.enabled(Rule::Airflow3Removal) { if checker.enabled(Rule::Airflow3Removal) {
airflow::rules::removed_in_3(checker, expr); airflow::rules::airflow_3_removal_expr(checker, expr);
} }
if checker.enabled(Rule::Airflow3MovedToProvider) { if checker.enabled(Rule::Airflow3MovedToProvider) {
airflow::rules::moved_to_provider_in_3(checker, expr); airflow::rules::moved_to_provider_in_3(checker, expr);
@@ -311,7 +311,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
} }
} }
if checker.enabled(Rule::Airflow3Removal) { if checker.enabled(Rule::Airflow3Removal) {
airflow::rules::removed_in_3(checker, expr); airflow::rules::airflow_3_removal_expr(checker, expr);
} }
if checker.enabled(Rule::MixedCaseVariableInGlobalScope) { if checker.enabled(Rule::MixedCaseVariableInGlobalScope) {
if matches!(checker.semantic.current_scope().kind, ScopeKind::Module) { if matches!(checker.semantic.current_scope().kind, ScopeKind::Module) {
@@ -449,7 +449,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
flake8_pyi::rules::bytestring_attribute(checker, expr); flake8_pyi::rules::bytestring_attribute(checker, expr);
} }
if checker.enabled(Rule::Airflow3Removal) { if checker.enabled(Rule::Airflow3Removal) {
airflow::rules::removed_in_3(checker, expr); airflow::rules::airflow_3_removal_expr(checker, expr);
} }
} }
Expr::Call( Expr::Call(
@@ -1150,7 +1150,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
ruff::rules::unnecessary_regular_expression(checker, call); ruff::rules::unnecessary_regular_expression(checker, call);
} }
if checker.enabled(Rule::Airflow3Removal) { if checker.enabled(Rule::Airflow3Removal) {
airflow::rules::removed_in_3(checker, expr); airflow::rules::airflow_3_removal_expr(checker, expr);
} }
if checker.enabled(Rule::UnnecessaryCastToInt) { if checker.enabled(Rule::UnnecessaryCastToInt) {
ruff::rules::unnecessary_cast_to_int(checker, call); ruff::rules::unnecessary_cast_to_int(checker, call);

View File

@@ -377,7 +377,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
flake8_pytest_style::rules::parameter_with_default_argument(checker, function_def); flake8_pytest_style::rules::parameter_with_default_argument(checker, function_def);
} }
if checker.enabled(Rule::Airflow3Removal) { if checker.enabled(Rule::Airflow3Removal) {
airflow::rules::removed_in_3_function_def(checker, function_def); airflow::rules::airflow_3_removal_function_def(checker, function_def);
} }
if checker.enabled(Rule::NonPEP695GenericFunction) { if checker.enabled(Rule::NonPEP695GenericFunction) {
pyupgrade::rules::non_pep695_generic_function(checker, function_def); pyupgrade::rules::non_pep695_generic_function(checker, function_def);

View File

@@ -80,7 +80,7 @@ enum Replacement {
} }
/// AIR302 /// AIR302
pub(crate) fn removed_in_3(checker: &mut Checker, expr: &Expr) { pub(crate) fn airflow_3_removal_expr(checker: &mut Checker, expr: &Expr) {
if !checker.semantic().seen_module(Modules::AIRFLOW) { if !checker.semantic().seen_module(Modules::AIRFLOW) {
return; return;
} }
@@ -117,7 +117,10 @@ pub(crate) fn removed_in_3(checker: &mut Checker, expr: &Expr) {
} }
/// AIR302 /// AIR302
pub(crate) fn removed_in_3_function_def(checker: &mut Checker, function_def: &StmtFunctionDef) { pub(crate) fn airflow_3_removal_function_def(
checker: &mut Checker,
function_def: &StmtFunctionDef,
) {
if !checker.semantic().seen_module(Modules::AIRFLOW) { if !checker.semantic().seen_module(Modules::AIRFLOW) {
return; return;
} }
@@ -154,7 +157,9 @@ const REMOVED_CONTEXT_KEYS: [&str; 12] = [
/// pass /// pass
/// ``` /// ```
fn check_function_parameters(checker: &mut Checker, function_def: &StmtFunctionDef) { fn check_function_parameters(checker: &mut Checker, function_def: &StmtFunctionDef) {
if !is_airflow_task(function_def, checker.semantic()) { if !is_airflow_task(function_def, checker.semantic())
&& !is_execute_method_inherits_from_airflow_operator(function_def, checker.semantic())
{
return; return;
} }
@@ -1076,3 +1081,35 @@ fn is_airflow_task(function_def: &StmtFunctionDef, semantic: &SemanticModel) ->
}) })
}) })
} }
/// Check it's "execute" method inherits from Airflow base operator
///
/// For example:
///
/// ```python
/// from airflow.models.baseoperator import BaseOperator
///
/// class CustomOperator(BaseOperator):
/// def execute(self):
/// pass
/// ```
fn is_execute_method_inherits_from_airflow_operator(
function_def: &StmtFunctionDef,
semantic: &SemanticModel,
) -> bool {
if function_def.name.as_str() != "execute" {
return false;
}
let ScopeKind::Class(class_def) = semantic.current_scope().kind else {
return false;
};
class_def.bases().iter().any(|class_base| {
semantic
.resolve_qualified_name(class_base)
.is_some_and(|qualified_name| {
matches!(qualified_name.segments(), ["airflow", .., "BaseOperator"])
})
})
}

View File

@@ -1,319 +1,338 @@
--- ---
source: crates/ruff_linter/src/rules/airflow/mod.rs source: crates/ruff_linter/src/rules/airflow/mod.rs
snapshot_kind: text
--- ---
AIR302_context.py:19:45: AIR302 `conf` is removed in Airflow 3.0 AIR302_context.py:22:41: AIR302 `conf` is removed in Airflow 3.0
| |
17 | @task 20 | @task
18 | def access_invalid_key_task_out_of_dag(**context): 21 | def access_invalid_key_task_out_of_dag(**context):
19 | print("access invalid key", context.get("conf")) 22 | print("access invalid key", context["conf"])
| ^^^^^^ AIR302
23 | print("access invalid key", context.get("conf"))
|
AIR302_context.py:23:45: AIR302 `conf` is removed in Airflow 3.0
|
21 | def access_invalid_key_task_out_of_dag(**context):
22 | print("access invalid key", context["conf"])
23 | print("access invalid key", context.get("conf"))
| ^^^^^^ AIR302 | ^^^^^^ AIR302
20 |
21 | @dag(
| |
AIR302_context.py:30:49: AIR302 `conf` is removed in Airflow 3.0 AIR302_context.py:28:5: AIR302 `execution_date` is removed in Airflow 3.0
| |
28 | @task() 26 | @task
29 | def access_invalid_key_task(**context): 27 | def access_invalid_argument_task_out_of_dag(
30 | print("access invalid key", context.get("conf")) 28 | execution_date, tomorrow_ds, logical_date, **context
| ^^^^^^ AIR302 | ^^^^^^^^^^^^^^ AIR302
31 | 29 | ):
32 | task1 = PythonOperator( 30 | print("execution date", execution_date)
| |
AIR302_context.py:47:30: AIR302 `execution_date` is removed in Airflow 3.0 AIR302_context.py:28:21: AIR302 `tomorrow_ds` is removed in Airflow 3.0
| |
46 | # Removed usage - should trigger violations 26 | @task
47 | execution_date = context["execution_date"] 27 | def access_invalid_argument_task_out_of_dag(
28 | execution_date, tomorrow_ds, logical_date, **context
| ^^^^^^^^^^^ AIR302
29 | ):
30 | print("execution date", execution_date)
|
AIR302_context.py:31:45: AIR302 `conf` is removed in Airflow 3.0
|
29 | ):
30 | print("execution date", execution_date)
31 | print("access invalid key", context.get("conf"))
| ^^^^^^ AIR302
|
AIR302_context.py:40:30: AIR302 `execution_date` is removed in Airflow 3.0
|
39 | # Removed usage - should trigger violations
40 | execution_date = context["execution_date"]
| ^^^^^^^^^^^^^^^^ AIR302 | ^^^^^^^^^^^^^^^^ AIR302
48 | next_ds = context["next_ds"] 41 | next_ds = context["next_ds"]
49 | next_ds_nodash = context["next_ds_nodash"] 42 | next_ds_nodash = context["next_ds_nodash"]
| |
AIR302_context.py:48:23: AIR302 `next_ds` is removed in Airflow 3.0 AIR302_context.py:41:23: AIR302 `next_ds` is removed in Airflow 3.0
| |
46 | # Removed usage - should trigger violations 39 | # Removed usage - should trigger violations
47 | execution_date = context["execution_date"] 40 | execution_date = context["execution_date"]
48 | next_ds = context["next_ds"] 41 | next_ds = context["next_ds"]
| ^^^^^^^^^ AIR302 | ^^^^^^^^^ AIR302
49 | next_ds_nodash = context["next_ds_nodash"] 42 | next_ds_nodash = context["next_ds_nodash"]
50 | next_execution_date = context["next_execution_date"] 43 | next_execution_date = context["next_execution_date"]
| |
AIR302_context.py:49:30: AIR302 `next_ds_nodash` is removed in Airflow 3.0 AIR302_context.py:42:30: AIR302 `next_ds_nodash` is removed in Airflow 3.0
| |
47 | execution_date = context["execution_date"] 40 | execution_date = context["execution_date"]
48 | next_ds = context["next_ds"] 41 | next_ds = context["next_ds"]
49 | next_ds_nodash = context["next_ds_nodash"] 42 | next_ds_nodash = context["next_ds_nodash"]
| ^^^^^^^^^^^^^^^^ AIR302 | ^^^^^^^^^^^^^^^^ AIR302
50 | next_execution_date = context["next_execution_date"] 43 | next_execution_date = context["next_execution_date"]
51 | prev_ds = context["prev_ds"] 44 | prev_ds = context["prev_ds"]
| |
AIR302_context.py:50:35: AIR302 `next_execution_date` is removed in Airflow 3.0 AIR302_context.py:43:35: AIR302 `next_execution_date` is removed in Airflow 3.0
| |
48 | next_ds = context["next_ds"] 41 | next_ds = context["next_ds"]
49 | next_ds_nodash = context["next_ds_nodash"] 42 | next_ds_nodash = context["next_ds_nodash"]
50 | next_execution_date = context["next_execution_date"] 43 | next_execution_date = context["next_execution_date"]
| ^^^^^^^^^^^^^^^^^^^^^ AIR302 | ^^^^^^^^^^^^^^^^^^^^^ AIR302
51 | prev_ds = context["prev_ds"] 44 | prev_ds = context["prev_ds"]
52 | prev_ds_nodash = context["prev_ds_nodash"] 45 | prev_ds_nodash = context["prev_ds_nodash"]
| |
AIR302_context.py:51:23: AIR302 `prev_ds` is removed in Airflow 3.0 AIR302_context.py:44:23: AIR302 `prev_ds` is removed in Airflow 3.0
| |
49 | next_ds_nodash = context["next_ds_nodash"] 42 | next_ds_nodash = context["next_ds_nodash"]
50 | next_execution_date = context["next_execution_date"] 43 | next_execution_date = context["next_execution_date"]
51 | prev_ds = context["prev_ds"] 44 | prev_ds = context["prev_ds"]
| ^^^^^^^^^ AIR302 | ^^^^^^^^^ AIR302
52 | prev_ds_nodash = context["prev_ds_nodash"] 45 | prev_ds_nodash = context["prev_ds_nodash"]
53 | prev_execution_date = context["prev_execution_date"] 46 | prev_execution_date = context["prev_execution_date"]
| |
AIR302_context.py:52:30: AIR302 `prev_ds_nodash` is removed in Airflow 3.0 AIR302_context.py:45:30: AIR302 `prev_ds_nodash` is removed in Airflow 3.0
| |
50 | next_execution_date = context["next_execution_date"] 43 | next_execution_date = context["next_execution_date"]
51 | prev_ds = context["prev_ds"] 44 | prev_ds = context["prev_ds"]
52 | prev_ds_nodash = context["prev_ds_nodash"] 45 | prev_ds_nodash = context["prev_ds_nodash"]
| ^^^^^^^^^^^^^^^^ AIR302 | ^^^^^^^^^^^^^^^^ AIR302
53 | prev_execution_date = context["prev_execution_date"] 46 | prev_execution_date = context["prev_execution_date"]
54 | prev_execution_date_success = context["prev_execution_date_success"] 47 | prev_execution_date_success = context["prev_execution_date_success"]
| |
AIR302_context.py:53:35: AIR302 `prev_execution_date` is removed in Airflow 3.0 AIR302_context.py:46:35: AIR302 `prev_execution_date` is removed in Airflow 3.0
| |
51 | prev_ds = context["prev_ds"] 44 | prev_ds = context["prev_ds"]
52 | prev_ds_nodash = context["prev_ds_nodash"] 45 | prev_ds_nodash = context["prev_ds_nodash"]
53 | prev_execution_date = context["prev_execution_date"] 46 | prev_execution_date = context["prev_execution_date"]
| ^^^^^^^^^^^^^^^^^^^^^ AIR302 | ^^^^^^^^^^^^^^^^^^^^^ AIR302
54 | prev_execution_date_success = context["prev_execution_date_success"] 47 | prev_execution_date_success = context["prev_execution_date_success"]
55 | tomorrow_ds = context["tomorrow_ds"] 48 | tomorrow_ds = context["tomorrow_ds"]
| |
AIR302_context.py:54:43: AIR302 `prev_execution_date_success` is removed in Airflow 3.0 AIR302_context.py:47:43: AIR302 `prev_execution_date_success` is removed in Airflow 3.0
| |
52 | prev_ds_nodash = context["prev_ds_nodash"] 45 | prev_ds_nodash = context["prev_ds_nodash"]
53 | prev_execution_date = context["prev_execution_date"] 46 | prev_execution_date = context["prev_execution_date"]
54 | prev_execution_date_success = context["prev_execution_date_success"] 47 | prev_execution_date_success = context["prev_execution_date_success"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
55 | tomorrow_ds = context["tomorrow_ds"] 48 | tomorrow_ds = context["tomorrow_ds"]
56 | yesterday_ds = context["yesterday_ds"] 49 | yesterday_ds = context["yesterday_ds"]
| |
AIR302_context.py:55:27: AIR302 `tomorrow_ds` is removed in Airflow 3.0 AIR302_context.py:48:27: AIR302 `tomorrow_ds` is removed in Airflow 3.0
| |
53 | prev_execution_date = context["prev_execution_date"] 46 | prev_execution_date = context["prev_execution_date"]
54 | prev_execution_date_success = context["prev_execution_date_success"] 47 | prev_execution_date_success = context["prev_execution_date_success"]
55 | tomorrow_ds = context["tomorrow_ds"] 48 | tomorrow_ds = context["tomorrow_ds"]
| ^^^^^^^^^^^^^ AIR302 | ^^^^^^^^^^^^^ AIR302
56 | yesterday_ds = context["yesterday_ds"] 49 | yesterday_ds = context["yesterday_ds"]
57 | yesterday_ds_nodash = context["yesterday_ds_nodash"] 50 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
| |
AIR302_context.py:56:28: AIR302 `yesterday_ds` is removed in Airflow 3.0 AIR302_context.py:49:28: AIR302 `yesterday_ds` is removed in Airflow 3.0
| |
54 | prev_execution_date_success = context["prev_execution_date_success"] 47 | prev_execution_date_success = context["prev_execution_date_success"]
55 | tomorrow_ds = context["tomorrow_ds"] 48 | tomorrow_ds = context["tomorrow_ds"]
56 | yesterday_ds = context["yesterday_ds"] 49 | yesterday_ds = context["yesterday_ds"]
| ^^^^^^^^^^^^^^ AIR302 | ^^^^^^^^^^^^^^ AIR302
57 | yesterday_ds_nodash = context["yesterday_ds_nodash"] 50 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
| |
AIR302_context.py:57:35: AIR302 `yesterday_ds_nodash` is removed in Airflow 3.0 AIR302_context.py:50:35: AIR302 `yesterday_ds_nodash` is removed in Airflow 3.0
| |
55 | tomorrow_ds = context["tomorrow_ds"] 48 | tomorrow_ds = context["tomorrow_ds"]
56 | yesterday_ds = context["yesterday_ds"] 49 | yesterday_ds = context["yesterday_ds"]
57 | yesterday_ds_nodash = context["yesterday_ds_nodash"] 50 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
| ^^^^^^^^^^^^^^^^^^^^^ AIR302 | ^^^^^^^^^^^^^^^^^^^^^ AIR302
58 |
59 | with DAG(
| |
AIR302_context.py:61:5: AIR302 [*] `schedule_interval` is removed in Airflow 3.0 AIR302_context.py:56:30: AIR302 `execution_date` is removed in Airflow 3.0
| |
59 | with DAG( 54 | def print_config_with_get_current_context():
60 | dag_id="example_dag", 55 | context = get_current_context()
61 | schedule_interval="@daily", 56 | execution_date = context["execution_date"]
| ^^^^^^^^^^^^^^^^^ AIR302 | ^^^^^^^^^^^^^^^^ AIR302
62 | start_date=datetime(2023, 1, 1), 57 | next_ds = context["next_ds"]
63 | template_searchpath=["/templates"], 58 | next_ds_nodash = context["next_ds_nodash"]
| |
= help: Use `schedule` instead
AIR302_context.py:57:23: AIR302 `next_ds` is removed in Airflow 3.0
|
55 | context = get_current_context()
56 | execution_date = context["execution_date"]
57 | next_ds = context["next_ds"]
| ^^^^^^^^^ AIR302
58 | next_ds_nodash = context["next_ds_nodash"]
59 | next_execution_date = context["next_execution_date"]
|
AIR302_context.py:58:30: AIR302 `next_ds_nodash` is removed in Airflow 3.0
|
56 | execution_date = context["execution_date"]
57 | next_ds = context["next_ds"]
58 | next_ds_nodash = context["next_ds_nodash"]
| ^^^^^^^^^^^^^^^^ AIR302
59 | next_execution_date = context["next_execution_date"]
60 | prev_ds = context["prev_ds"]
|
AIR302_context.py:59:35: AIR302 `next_execution_date` is removed in Airflow 3.0
|
57 | next_ds = context["next_ds"]
58 | next_ds_nodash = context["next_ds_nodash"]
59 | next_execution_date = context["next_execution_date"]
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
60 | prev_ds = context["prev_ds"]
61 | prev_ds_nodash = context["prev_ds_nodash"]
|
AIR302_context.py:60:23: AIR302 `prev_ds` is removed in Airflow 3.0
|
58 | next_ds_nodash = context["next_ds_nodash"]
59 | next_execution_date = context["next_execution_date"]
60 | prev_ds = context["prev_ds"]
| ^^^^^^^^^ AIR302
61 | prev_ds_nodash = context["prev_ds_nodash"]
62 | prev_execution_date = context["prev_execution_date"]
|
AIR302_context.py:61:30: AIR302 `prev_ds_nodash` is removed in Airflow 3.0
|
59 | next_execution_date = context["next_execution_date"]
60 | prev_ds = context["prev_ds"]
61 | prev_ds_nodash = context["prev_ds_nodash"]
| ^^^^^^^^^^^^^^^^ AIR302
62 | prev_execution_date = context["prev_execution_date"]
63 | prev_execution_date_success = context["prev_execution_date_success"]
|
AIR302_context.py:62:35: AIR302 `prev_execution_date` is removed in Airflow 3.0
|
60 | prev_ds = context["prev_ds"]
61 | prev_ds_nodash = context["prev_ds_nodash"]
62 | prev_execution_date = context["prev_execution_date"]
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
63 | prev_execution_date_success = context["prev_execution_date_success"]
64 | tomorrow_ds = context["tomorrow_ds"]
|
AIR302_context.py:63:43: AIR302 `prev_execution_date_success` is removed in Airflow 3.0
|
61 | prev_ds_nodash = context["prev_ds_nodash"]
62 | prev_execution_date = context["prev_execution_date"]
63 | prev_execution_date_success = context["prev_execution_date_success"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
64 | tomorrow_ds = context["tomorrow_ds"]
65 | yesterday_ds = context["yesterday_ds"]
|
AIR302_context.py:64:27: AIR302 `tomorrow_ds` is removed in Airflow 3.0
|
62 | prev_execution_date = context["prev_execution_date"]
63 | prev_execution_date_success = context["prev_execution_date_success"]
64 | tomorrow_ds = context["tomorrow_ds"]
| ^^^^^^^^^^^^^ AIR302
65 | yesterday_ds = context["yesterday_ds"]
66 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
|
AIR302_context.py:65:28: AIR302 `yesterday_ds` is removed in Airflow 3.0
|
63 | prev_execution_date_success = context["prev_execution_date_success"]
64 | tomorrow_ds = context["tomorrow_ds"]
65 | yesterday_ds = context["yesterday_ds"]
| ^^^^^^^^^^^^^^ AIR302
66 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
|
AIR302_context.py:66:35: AIR302 `yesterday_ds_nodash` is removed in Airflow 3.0
|
64 | tomorrow_ds = context["tomorrow_ds"]
65 | yesterday_ds = context["yesterday_ds"]
66 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
|
AIR302_context.py:73:22: AIR302 `tomorrow_ds` is removed in Airflow 3.0
|
71 | """Print the Airflow context and ds variable from the context."""
72 | print(ds)
73 | print(kwargs.get("tomorrow_ds"))
| ^^^^^^^^^^^^^ AIR302
74 | c = get_current_context()
75 | c.get("execution_date")
|
AIR302_context.py:75:11: AIR302 `execution_date` is removed in Airflow 3.0
|
73 | print(kwargs.get("tomorrow_ds"))
74 | c = get_current_context()
75 | c.get("execution_date")
| ^^^^^^^^^^^^^^^^ AIR302
|
AIR302_context.py:87:49: AIR302 `conf` is removed in Airflow 3.0
|
85 | @task()
86 | def access_invalid_key_task(**context):
87 | print("access invalid key", context.get("conf"))
| ^^^^^^ AIR302
88 |
89 | @task()
|
AIR302_context.py:90:42: AIR302 `execution_date` is removed in Airflow 3.0
|
89 | @task()
90 | def access_invalid_key_explicit_task(execution_date):
| ^^^^^^^^^^^^^^ AIR302
91 | print(execution_date)
|
AIR302_context.py:111:5: AIR302 [*] `schedule_interval` is removed in Airflow 3.0
|
109 | with DAG(
110 | dag_id="example_dag",
111 | schedule_interval="@daily",
| ^^^^^^^^^^^^^^^^^ AIR302
112 | start_date=datetime(2023, 1, 1),
113 | template_searchpath=["/templates"],
|
= help: Use `schedule` instead
Safe fix Safe fix
58 58 | 108 108 |
59 59 | with DAG( 109 109 | with DAG(
60 60 | dag_id="example_dag", 110 110 | dag_id="example_dag",
61 |- schedule_interval="@daily", 111 |- schedule_interval="@daily",
61 |+ schedule="@daily", 111 |+ schedule="@daily",
62 62 | start_date=datetime(2023, 1, 1), 112 112 | start_date=datetime(2023, 1, 1),
63 63 | template_searchpath=["/templates"], 113 113 | template_searchpath=["/templates"],
64 64 | ) as dag: 114 114 | ) as dag:
AIR302_context.py:65:13: AIR302 `airflow.operators.dummy.DummyOperator` is removed in Airflow 3.0 AIR302_context.py:115:13: AIR302 `airflow.operators.dummy.DummyOperator` is removed in Airflow 3.0
|
63 | template_searchpath=["/templates"],
64 | ) as dag:
65 | task1 = DummyOperator(
| ^^^^^^^^^^^^^ AIR302
66 | task_id="task1",
67 | params={
|
= help: Use `airflow.operators.empty.EmptyOperator` instead
AIR302_context.py:85:30: AIR302 `execution_date` is removed in Airflow 3.0
|
83 | def print_config():
84 | context = get_current_context()
85 | execution_date = context["execution_date"]
| ^^^^^^^^^^^^^^^^ AIR302
86 | next_ds = context["next_ds"]
87 | next_ds_nodash = context["next_ds_nodash"]
|
AIR302_context.py:86:23: AIR302 `next_ds` is removed in Airflow 3.0
|
84 | context = get_current_context()
85 | execution_date = context["execution_date"]
86 | next_ds = context["next_ds"]
| ^^^^^^^^^ AIR302
87 | next_ds_nodash = context["next_ds_nodash"]
88 | next_execution_date = context["next_execution_date"]
|
AIR302_context.py:87:30: AIR302 `next_ds_nodash` is removed in Airflow 3.0
|
85 | execution_date = context["execution_date"]
86 | next_ds = context["next_ds"]
87 | next_ds_nodash = context["next_ds_nodash"]
| ^^^^^^^^^^^^^^^^ AIR302
88 | next_execution_date = context["next_execution_date"]
89 | prev_ds = context["prev_ds"]
|
AIR302_context.py:88:35: AIR302 `next_execution_date` is removed in Airflow 3.0
|
86 | next_ds = context["next_ds"]
87 | next_ds_nodash = context["next_ds_nodash"]
88 | next_execution_date = context["next_execution_date"]
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
89 | prev_ds = context["prev_ds"]
90 | prev_ds_nodash = context["prev_ds_nodash"]
|
AIR302_context.py:89:23: AIR302 `prev_ds` is removed in Airflow 3.0
|
87 | next_ds_nodash = context["next_ds_nodash"]
88 | next_execution_date = context["next_execution_date"]
89 | prev_ds = context["prev_ds"]
| ^^^^^^^^^ AIR302
90 | prev_ds_nodash = context["prev_ds_nodash"]
91 | prev_execution_date = context["prev_execution_date"]
|
AIR302_context.py:90:30: AIR302 `prev_ds_nodash` is removed in Airflow 3.0
|
88 | next_execution_date = context["next_execution_date"]
89 | prev_ds = context["prev_ds"]
90 | prev_ds_nodash = context["prev_ds_nodash"]
| ^^^^^^^^^^^^^^^^ AIR302
91 | prev_execution_date = context["prev_execution_date"]
92 | prev_execution_date_success = context["prev_execution_date_success"]
|
AIR302_context.py:91:35: AIR302 `prev_execution_date` is removed in Airflow 3.0
|
89 | prev_ds = context["prev_ds"]
90 | prev_ds_nodash = context["prev_ds_nodash"]
91 | prev_execution_date = context["prev_execution_date"]
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
92 | prev_execution_date_success = context["prev_execution_date_success"]
93 | tomorrow_ds = context["tomorrow_ds"]
|
AIR302_context.py:92:43: AIR302 `prev_execution_date_success` is removed in Airflow 3.0
|
90 | prev_ds_nodash = context["prev_ds_nodash"]
91 | prev_execution_date = context["prev_execution_date"]
92 | prev_execution_date_success = context["prev_execution_date_success"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
93 | tomorrow_ds = context["tomorrow_ds"]
94 | yesterday_ds = context["yesterday_ds"]
|
AIR302_context.py:93:27: AIR302 `tomorrow_ds` is removed in Airflow 3.0
|
91 | prev_execution_date = context["prev_execution_date"]
92 | prev_execution_date_success = context["prev_execution_date_success"]
93 | tomorrow_ds = context["tomorrow_ds"]
| ^^^^^^^^^^^^^ AIR302
94 | yesterday_ds = context["yesterday_ds"]
95 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
|
AIR302_context.py:94:28: AIR302 `yesterday_ds` is removed in Airflow 3.0
|
92 | prev_execution_date_success = context["prev_execution_date_success"]
93 | tomorrow_ds = context["tomorrow_ds"]
94 | yesterday_ds = context["yesterday_ds"]
| ^^^^^^^^^^^^^^ AIR302
95 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
|
AIR302_context.py:95:35: AIR302 `yesterday_ds_nodash` is removed in Airflow 3.0
|
93 | tomorrow_ds = context["tomorrow_ds"]
94 | yesterday_ds = context["yesterday_ds"]
95 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
96 |
97 | class CustomOperator(BaseOperator):
|
AIR302_context.py:112:45: AIR302 `execution_date` is removed in Airflow 3.0
| |
111 | @task 113 | template_searchpath=["/templates"],
112 | def access_invalid_argument_task_out_of_dag(execution_date, tomorrow_ds, logical_date, **context): 114 | ) as dag:
| ^^^^^^^^^^^^^^ AIR302 115 | task1 = DummyOperator(
113 | print("execution date", execution_date) | ^^^^^^^^^^^^^ AIR302
114 | print("access invalid key", context.get("conf")) 116 | task_id="task1",
117 | params={
| |
= help: Use `airflow.operators.empty.EmptyOperator` instead
AIR302_context.py:112:61: AIR302 `tomorrow_ds` is removed in Airflow 3.0 AIR302_context.py:135:23: AIR302 `next_ds` is removed in Airflow 3.0
| |
111 | @task 134 | class CustomOperator(BaseOperator):
112 | def access_invalid_argument_task_out_of_dag(execution_date, tomorrow_ds, logical_date, **context): 135 | def execute(self, next_ds, context):
| ^^^^^^^^^^^ AIR302 | ^^^^^^^ AIR302
113 | print("execution date", execution_date) 136 | execution_date = context["execution_date"]
114 | print("access invalid key", context.get("conf")) 137 | next_ds = context["next_ds"]
|
AIR302_context.py:114:45: AIR302 `conf` is removed in Airflow 3.0
|
112 | def access_invalid_argument_task_out_of_dag(execution_date, tomorrow_ds, logical_date, **context):
113 | print("execution date", execution_date)
114 | print("access invalid key", context.get("conf"))
| ^^^^^^ AIR302
115 |
116 | @task(task_id="print_the_context")
|
AIR302_context.py:120:22: AIR302 `tomorrow_ds` is removed in Airflow 3.0
|
118 | """Print the Airflow context and ds variable from the context."""
119 | print(ds)
120 | print(kwargs.get("tomorrow_ds"))
| ^^^^^^^^^^^^^ AIR302
121 | c = get_current_context()
122 | c.get("execution_date")
|
AIR302_context.py:122:11: AIR302 `execution_date` is removed in Airflow 3.0
|
120 | print(kwargs.get("tomorrow_ds"))
121 | c = get_current_context()
122 | c.get("execution_date")
| ^^^^^^^^^^^^^^^^ AIR302
123 |
124 | class CustomOperatorNew(BaseOperator):
| |