-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[airflow] Add lint rule to show error for removed context variables in airflow #15144
base: main
Are you sure you want to change the base?
[airflow] Add lint rule to show error for removed context variables in airflow #15144
Conversation
|
89ed2ce
to
c3fb996
Compare
...rc/rules/airflow/snapshots/ruff_linter__rules__airflow__tests__AIR302_AIR302_context.py.snap
Outdated
Show resolved
Hide resolved
5c96f89
to
5103ef7
Compare
crates/ruff_linter/resources/test/fixtures/airflow/AIR302_context.py
Outdated
Show resolved
Hide resolved
d580a4b
to
c0a34d3
Compare
62de813
to
fb8b300
Compare
Going to focus on reviewing this PR instead of #15240 for now as I think this one supersedes the other one but please correct me if I'm wrong. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for working on this. I've a couple of doubts which I've highlighted in the review comments and #15240 (comment).
Thank you for updating the PR, I plan on looking at it later today. |
4975421
to
ffee139
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good, can you update the PR description to include all the checks that are being done? I'm mainly looking for all the structural matching that's being done here, not specific symbols or variables that's being checked. I'm having a hard time keeping track of them :)
Please re-request for review when it's ready :) |
2fec3ae
to
c82abcf
Compare
c82abcf
to
7825256
Compare
add lint rule to show error for removed context variables in airflow
7825256
to
c2c37b8
Compare
I fix the CI failure. I think it's ready for review now. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for updating the PR description with the patterns that are being checked here, it's helpful as a reference when reviewing.
Regarding 1, 2, 3 pattern, do they need to be in function / method which has the @task
decorator or can they be in any function / method?
I think we're pretty close to finishing this up, thank you for your patience!
AIR302_context.py:109:5: AIR302 `execution_date` is removed in Airflow 3.0 | ||
| | ||
108 | @task | ||
109 | def access_invalid_argument_task_out_of_dag(execution_date, **context): | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302 | ||
110 | print("execution date", execution_date) | ||
111 | print("access invalid key", context.get("conf")) | ||
| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be highlighting the wrong range. I think you meant to highlight the parameter execution_date
?
Can we add more test cases to check functions with multiple parameters which has both deprecated and non-deprecated parameters?
AIR302_context.py:58:5: AIR302 [*] `schedule_interval` is removed in Airflow 3.0 | ||
| | ||
56 | with DAG( | ||
57 | dag_id="example_dag", | ||
58 | schedule_interval="@daily", | ||
| ^^^^^^^^^^^^^^^^^ AIR302 | ||
59 | start_date=datetime(2023, 1, 1), | ||
60 | template_searchpath=["/templates"], | ||
| | ||
= help: Use `schedule` instead | ||
|
||
ℹ Safe fix | ||
55 55 | | ||
56 56 | with DAG( | ||
57 57 | dag_id="example_dag", | ||
58 |- schedule_interval="@daily", | ||
58 |+ schedule="@daily", | ||
59 59 | start_date=datetime(2023, 1, 1), | ||
60 60 | template_searchpath=["/templates"], | ||
61 61 | ) as dag: | ||
|
||
AIR302_context.py:62:13: AIR302 `airflow.operators.dummy.DummyOperator` is removed in Airflow 3.0 | ||
| | ||
60 | template_searchpath=["/templates"], | ||
61 | ) as dag: | ||
62 | task1 = DummyOperator( | ||
| ^^^^^^^^^^^^^ AIR302 | ||
63 | task_id="task1", | ||
64 | params={ | ||
| | ||
= help: Use `airflow.operators.empty.EmptyOperator` instead |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these related to the changes made in this PR? This is fine, I just want to confirm.
} | ||
|
||
for removed_key in REMOVED_CONTEXT_KEYS { | ||
if let Some(argument) = call_expr.arguments.find_argument_value(removed_key, 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we can use 0 as the default value here. What would happen if it's a positional parameter which is expected to be at position 1 or 2? This will return incorrect argument.
I think we should also add test cases where there are multiple arguments that are deprecated in the same function intermixed with non-deprecated arguments.
let is_named_context = value.as_name_expr().is_some_and(|name| { | ||
matches!(name.id.as_str(), "context" | "kwargs") || name.id.as_str().starts_with("**") | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the **
check is for? I only see **
being used in parameter in the tests and PR description but this is checking the call function and not the function parameter. Did you meant to look at the definition of value
and check that instead? If so, I think that will require adding functionality to get the parameter definition for the binding which would be something like:
fn find_parameter(semantic: &SemanticModel, name: &ast::ExprName) -> Option<ast::AnyParameterRef> {
let binding_id = semantic.only_binding(name_expr)?;
let binding = semantic.binding(binding_id);
let ast::StmtFunctionDef { parameters, .. } = binding.statement(semantic)?.as_function_def_stmt()?;
parameters
.iter()
.find(|parameter| parameter.name().range() == binding.range())
}
11 | def access_invalid_key_in_context(**context): | ||
12 | print("access invalid key", context["conf"]) | ||
| ^^^^^^ AIR302 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function doesn't have the @task
decorator but the diagnostics is being raised here, is this correct?
/// Checks for the use of deprecated Airflow context variables. | ||
/// | ||
/// The function handles context keys accessed: | ||
/// - Directly using `context["key"]` or context.get("key"). | ||
/// - Using `.get()` with variables derived from `get_current_context()`. | ||
/// - In custom operators, task decorators, and within templates or macros. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to update the documentation for this function as it's only checking subscript expressions?
Summary
Airflow 3.0 removes a set of deprecated context variables that were phased out in 2.x. This PR introduces lint rules to detect usage of these removed variables in various patterns, helping identify incompatibilities. The removed context variables include:
Detected Patterns and Examples
The linter now flags the use of removed context variables in the following scenarios:
Direct Subscript Access
.get("key")
Method CallsVariables Assigned from
get_current_context()
If a variable is assigned from
get_current_context()
and then used to access a removed key:Function Parameters in
@task
-Decorated FunctionsParameters named after removed context variables in functions decorated with
@task
are flagged:Removed Keys in Task Decorator
kwargs
and Other ScenariosOther similar patterns where removed context variables appear (e.g., as part of
kwargs
in a@task
function) are also detected.Test Plan
Test fixtures covering various patterns of deprecated context usage are included in this PR. For example:
Ruff will emit
AIR302
diagnostics for each deprecated usage, with suggestions when applicable, aiding in code migration to Airflow 3.0.related: apache/airflow#44409, apache/airflow#41641