Skip to content

Commit 8833484

Browse files
authored
[airflow] Move AIR302 to AIR301 and AIR303 to AIR302 (#17151)
## Summary Following up the discussion in #14626 (comment), we're to reorganize airflow rules. Before this discussion happens, we combine required changes and suggested changes in to one single error code. This PR first rename the original error code to the new error code as we discussed. We will gradually extract suggested changes out of AIR301 and AIR302 to AIR311 and AIR312 in the following PRs ## Test Plan Except for file, error code rename, the test case should work as it used to be.
1 parent adeba3d commit 8833484

20 files changed

+750
-754
lines changed

crates/ruff_linter/src/codes.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1069,8 +1069,8 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
10691069
// airflow
10701070
(Airflow, "001") => (RuleGroup::Stable, rules::airflow::rules::AirflowVariableNameTaskIdMismatch),
10711071
(Airflow, "002") => (RuleGroup::Preview, rules::airflow::rules::AirflowDagNoScheduleArgument),
1072-
(Airflow, "302") => (RuleGroup::Preview, rules::airflow::rules::Airflow3Removal),
1073-
(Airflow, "303") => (RuleGroup::Preview, rules::airflow::rules::Airflow3MovedToProvider),
1072+
(Airflow, "301") => (RuleGroup::Preview, rules::airflow::rules::Airflow3Removal),
1073+
(Airflow, "302") => (RuleGroup::Preview, rules::airflow::rules::Airflow3MovedToProvider),
10741074

10751075
// perflint
10761076
(Perflint, "101") => (RuleGroup::Stable, rules::perflint::rules::UnnecessaryListCast),

crates/ruff_linter/src/rules/airflow/mod.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ mod tests {
1515

1616
#[test_case(Rule::AirflowVariableNameTaskIdMismatch, Path::new("AIR001.py"))]
1717
#[test_case(Rule::AirflowDagNoScheduleArgument, Path::new("AIR002.py"))]
18-
#[test_case(Rule::Airflow3Removal, Path::new("AIR302_args.py"))]
19-
#[test_case(Rule::Airflow3Removal, Path::new("AIR302_names.py"))]
20-
#[test_case(Rule::Airflow3Removal, Path::new("AIR302_names_try.py"))]
21-
#[test_case(Rule::Airflow3Removal, Path::new("AIR302_class_attribute.py"))]
22-
#[test_case(Rule::Airflow3Removal, Path::new("AIR302_airflow_plugin.py"))]
23-
#[test_case(Rule::Airflow3Removal, Path::new("AIR302_context.py"))]
24-
#[test_case(Rule::Airflow3MovedToProvider, Path::new("AIR303.py"))]
18+
#[test_case(Rule::Airflow3Removal, Path::new("AIR301_args.py"))]
19+
#[test_case(Rule::Airflow3Removal, Path::new("AIR301_names.py"))]
20+
#[test_case(Rule::Airflow3Removal, Path::new("AIR301_names_try.py"))]
21+
#[test_case(Rule::Airflow3Removal, Path::new("AIR301_class_attribute.py"))]
22+
#[test_case(Rule::Airflow3Removal, Path::new("AIR301_airflow_plugin.py"))]
23+
#[test_case(Rule::Airflow3Removal, Path::new("AIR301_context.py"))]
24+
#[test_case(Rule::Airflow3MovedToProvider, Path::new("AIR302.py"))]
2525
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
2626
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
2727
let diagnostics = test_path(

crates/ruff_linter/src/rules/airflow/rules/dag_schedule_argument.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub(crate) fn dag_no_schedule_argument(checker: &Checker, expr: &Expr) {
7777
// If there's a schedule keyword argument, we are good.
7878
// This includes the canonical 'schedule', and the deprecated 'timetable'
7979
// and 'schedule_interval'. Usages of deprecated schedule arguments are
80-
// covered by AIR302.
80+
// covered by AIR301.
8181
if ["schedule", "schedule_interval", "timetable"]
8282
.iter()
8383
.any(|a| arguments.find_keyword(a).is_some())

crates/ruff_linter/src/rules/airflow/rules/moved_to_provider_in_3.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ impl Violation for Airflow3MovedToProvider {
8282
}
8383
}
8484

85-
/// AIR303
85+
/// AIR302
8686
pub(crate) fn moved_to_provider_in_3(checker: &Checker, expr: &Expr) {
8787
if !checker.semantic().seen_module(Modules::AIRFLOW) {
8888
return;

crates/ruff_linter/src/rules/airflow/rules/removal_in_3.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl Violation for Airflow3Removal {
7777
}
7878
}
7979

80-
/// AIR302
80+
/// AIR301
8181
pub(crate) fn airflow_3_removal_expr(checker: &Checker, expr: &Expr) {
8282
if !checker.semantic().seen_module(Modules::AIRFLOW) {
8383
return;
@@ -114,7 +114,7 @@ pub(crate) fn airflow_3_removal_expr(checker: &Checker, expr: &Expr) {
114114
}
115115
}
116116

117-
/// AIR302
117+
/// AIR301
118118
pub(crate) fn airflow_3_removal_function_def(checker: &Checker, function_def: &StmtFunctionDef) {
119119
if !checker.semantic().seen_module(Modules::AIRFLOW) {
120120
return;
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,42 @@
11
---
22
source: crates/ruff_linter/src/rules/airflow/mod.rs
3-
snapshot_kind: text
43
---
5-
AIR302_airflow_plugin.py:7:5: AIR302 `operators` is removed in Airflow 3.0; This extension should just be imported as a regular python module.
4+
AIR301_airflow_plugin.py:7:5: AIR301 `operators` is removed in Airflow 3.0; This extension should just be imported as a regular python module.
65
|
76
5 | name = "test_plugin"
87
6 | # --- Invalid extensions start
98
7 | operators = [PluginOperator]
10-
| ^^^^^^^^^ AIR302
9+
| ^^^^^^^^^ AIR301
1110
8 | sensors = [PluginSensorOperator]
1211
9 | hooks = [PluginHook]
1312
|
1413

15-
AIR302_airflow_plugin.py:8:5: AIR302 `sensors` is removed in Airflow 3.0; This extension should just be imported as a regular python module.
14+
AIR301_airflow_plugin.py:8:5: AIR301 `sensors` is removed in Airflow 3.0; This extension should just be imported as a regular python module.
1615
|
1716
6 | # --- Invalid extensions start
1817
7 | operators = [PluginOperator]
1918
8 | sensors = [PluginSensorOperator]
20-
| ^^^^^^^ AIR302
19+
| ^^^^^^^ AIR301
2120
9 | hooks = [PluginHook]
2221
10 | executors = [PluginExecutor]
2322
|
2423

25-
AIR302_airflow_plugin.py:9:5: AIR302 `hooks` is removed in Airflow 3.0; This extension should just be imported as a regular python module.
24+
AIR301_airflow_plugin.py:9:5: AIR301 `hooks` is removed in Airflow 3.0; This extension should just be imported as a regular python module.
2625
|
2726
7 | operators = [PluginOperator]
2827
8 | sensors = [PluginSensorOperator]
2928
9 | hooks = [PluginHook]
30-
| ^^^^^ AIR302
29+
| ^^^^^ AIR301
3130
10 | executors = [PluginExecutor]
3231
11 | # --- Invalid extensions end
3332
|
3433

35-
AIR302_airflow_plugin.py:10:5: AIR302 `executors` is removed in Airflow 3.0; This extension should just be imported as a regular python module.
34+
AIR301_airflow_plugin.py:10:5: AIR301 `executors` is removed in Airflow 3.0; This extension should just be imported as a regular python module.
3635
|
3736
8 | sensors = [PluginSensorOperator]
3837
9 | hooks = [PluginHook]
3938
10 | executors = [PluginExecutor]
40-
| ^^^^^^^^^ AIR302
39+
| ^^^^^^^^^ AIR301
4140
11 | # --- Invalid extensions end
4241
12 | macros = [plugin_macro]
4342
|
+40-40
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
---
22
source: crates/ruff_linter/src/rules/airflow/mod.rs
33
---
4-
AIR302_args.py:20:39: AIR302 [*] `schedule_interval` is removed in Airflow 3.0
4+
AIR301_args.py:20:39: AIR301 [*] `schedule_interval` is removed in Airflow 3.0
55
|
66
18 | DAG(dag_id="class_schedule", schedule="@hourly")
77
19 |
88
20 | DAG(dag_id="class_schedule_interval", schedule_interval="@hourly")
9-
| ^^^^^^^^^^^^^^^^^ AIR302
9+
| ^^^^^^^^^^^^^^^^^ AIR301
1010
21 |
1111
22 | DAG(dag_id="class_timetable", timetable=NullTimetable())
1212
|
@@ -22,12 +22,12 @@ AIR302_args.py:20:39: AIR302 [*] `schedule_interval` is removed in Airflow 3.0
2222
22 22 | DAG(dag_id="class_timetable", timetable=NullTimetable())
2323
23 23 |
2424

25-
AIR302_args.py:22:31: AIR302 [*] `timetable` is removed in Airflow 3.0
25+
AIR301_args.py:22:31: AIR301 [*] `timetable` is removed in Airflow 3.0
2626
|
2727
20 | DAG(dag_id="class_schedule_interval", schedule_interval="@hourly")
2828
21 |
2929
22 | DAG(dag_id="class_timetable", timetable=NullTimetable())
30-
| ^^^^^^^^^ AIR302
30+
| ^^^^^^^^^ AIR301
3131
|
3232
= help: Use `schedule` instead
3333

@@ -41,20 +41,20 @@ AIR302_args.py:22:31: AIR302 [*] `timetable` is removed in Airflow 3.0
4141
24 24 |
4242
25 25 | def sla_callback(*arg, **kwargs):
4343

44-
AIR302_args.py:29:34: AIR302 `sla_miss_callback` is removed in Airflow 3.0
44+
AIR301_args.py:29:34: AIR301 `sla_miss_callback` is removed in Airflow 3.0
4545
|
4646
29 | DAG(dag_id="class_sla_callback", sla_miss_callback=sla_callback)
47-
| ^^^^^^^^^^^^^^^^^ AIR302
47+
| ^^^^^^^^^^^^^^^^^ AIR301
4848
30 |
4949
31 | DAG(dag_id="class_fail_stop", fail_stop=True)
5050
|
5151

52-
AIR302_args.py:31:31: AIR302 [*] `fail_stop` is removed in Airflow 3.0
52+
AIR301_args.py:31:31: AIR301 [*] `fail_stop` is removed in Airflow 3.0
5353
|
5454
29 | DAG(dag_id="class_sla_callback", sla_miss_callback=sla_callback)
5555
30 |
5656
31 | DAG(dag_id="class_fail_stop", fail_stop=True)
57-
| ^^^^^^^^^ AIR302
57+
| ^^^^^^^^^ AIR301
5858
32 |
5959
33 | DAG(dag_id="class_default_view", default_view="dag_default_view")
6060
|
@@ -70,30 +70,30 @@ AIR302_args.py:31:31: AIR302 [*] `fail_stop` is removed in Airflow 3.0
7070
33 33 | DAG(dag_id="class_default_view", default_view="dag_default_view")
7171
34 34 |
7272

73-
AIR302_args.py:33:34: AIR302 `default_view` is removed in Airflow 3.0
73+
AIR301_args.py:33:34: AIR301 `default_view` is removed in Airflow 3.0
7474
|
7575
31 | DAG(dag_id="class_fail_stop", fail_stop=True)
7676
32 |
7777
33 | DAG(dag_id="class_default_view", default_view="dag_default_view")
78-
| ^^^^^^^^^^^^ AIR302
78+
| ^^^^^^^^^^^^ AIR301
7979
34 |
8080
35 | DAG(dag_id="class_orientation", orientation="BT")
8181
|
8282

83-
AIR302_args.py:35:33: AIR302 `orientation` is removed in Airflow 3.0
83+
AIR301_args.py:35:33: AIR301 `orientation` is removed in Airflow 3.0
8484
|
8585
33 | DAG(dag_id="class_default_view", default_view="dag_default_view")
8686
34 |
8787
35 | DAG(dag_id="class_orientation", orientation="BT")
88-
| ^^^^^^^^^^^ AIR302
88+
| ^^^^^^^^^^^ AIR301
8989
36 |
9090
37 | allow_future_exec_dates_dag = DAG(dag_id="class_allow_future_exec_dates")
9191
|
9292

93-
AIR302_args.py:46:6: AIR302 [*] `schedule_interval` is removed in Airflow 3.0
93+
AIR301_args.py:46:6: AIR301 [*] `schedule_interval` is removed in Airflow 3.0
9494
|
9595
46 | @dag(schedule_interval="0 * * * *")
96-
| ^^^^^^^^^^^^^^^^^ AIR302
96+
| ^^^^^^^^^^^^^^^^^ AIR301
9797
47 | def decorator_schedule_interval():
9898
48 | pass
9999
|
@@ -109,10 +109,10 @@ AIR302_args.py:46:6: AIR302 [*] `schedule_interval` is removed in Airflow 3.0
109109
48 48 | pass
110110
49 49 |
111111

112-
AIR302_args.py:51:6: AIR302 [*] `timetable` is removed in Airflow 3.0
112+
AIR301_args.py:51:6: AIR301 [*] `timetable` is removed in Airflow 3.0
113113
|
114114
51 | @dag(timetable=NullTimetable())
115-
| ^^^^^^^^^ AIR302
115+
| ^^^^^^^^^ AIR301
116116
52 | def decorator_timetable():
117117
53 | pass
118118
|
@@ -128,20 +128,20 @@ AIR302_args.py:51:6: AIR302 [*] `timetable` is removed in Airflow 3.0
128128
53 53 | pass
129129
54 54 |
130130

131-
AIR302_args.py:56:6: AIR302 `sla_miss_callback` is removed in Airflow 3.0
131+
AIR301_args.py:56:6: AIR301 `sla_miss_callback` is removed in Airflow 3.0
132132
|
133133
56 | @dag(sla_miss_callback=sla_callback)
134-
| ^^^^^^^^^^^^^^^^^ AIR302
134+
| ^^^^^^^^^^^^^^^^^ AIR301
135135
57 | def decorator_sla_callback():
136136
58 | pass
137137
|
138138

139-
AIR302_args.py:64:39: AIR302 [*] `execution_date` is removed in Airflow 3.0
139+
AIR301_args.py:64:39: AIR301 [*] `execution_date` is removed in Airflow 3.0
140140
|
141141
62 | def decorator_deprecated_operator_args():
142142
63 | trigger_dagrun_op = trigger_dagrun.TriggerDagRunOperator(
143143
64 | task_id="trigger_dagrun_op1", execution_date="2024-12-04"
144-
| ^^^^^^^^^^^^^^ AIR302
144+
| ^^^^^^^^^^^^^^ AIR301
145145
65 | )
146146
66 | trigger_dagrun_op2 = TriggerDagRunOperator(
147147
|
@@ -157,12 +157,12 @@ AIR302_args.py:64:39: AIR302 [*] `execution_date` is removed in Airflow 3.0
157157
66 66 | trigger_dagrun_op2 = TriggerDagRunOperator(
158158
67 67 | task_id="trigger_dagrun_op2", execution_date="2024-12-04"
159159

160-
AIR302_args.py:67:39: AIR302 [*] `execution_date` is removed in Airflow 3.0
160+
AIR301_args.py:67:39: AIR301 [*] `execution_date` is removed in Airflow 3.0
161161
|
162162
65 | )
163163
66 | trigger_dagrun_op2 = TriggerDagRunOperator(
164164
67 | task_id="trigger_dagrun_op2", execution_date="2024-12-04"
165-
| ^^^^^^^^^^^^^^ AIR302
165+
| ^^^^^^^^^^^^^^ AIR301
166166
68 | )
167167
|
168168
= help: Use `logical_date` instead
@@ -177,11 +177,11 @@ AIR302_args.py:67:39: AIR302 [*] `execution_date` is removed in Airflow 3.0
177177
69 69 |
178178
70 70 | branch_dt_op = datetime.BranchDateTimeOperator(
179179

180-
AIR302_args.py:71:33: AIR302 [*] `use_task_execution_day` is removed in Airflow 3.0
180+
AIR301_args.py:71:33: AIR301 [*] `use_task_execution_day` is removed in Airflow 3.0
181181
|
182182
70 | branch_dt_op = datetime.BranchDateTimeOperator(
183183
71 | task_id="branch_dt_op", use_task_execution_day=True, task_concurrency=5
184-
| ^^^^^^^^^^^^^^^^^^^^^^ AIR302
184+
| ^^^^^^^^^^^^^^^^^^^^^^ AIR301
185185
72 | )
186186
73 | branch_dt_op2 = BranchDateTimeOperator(
187187
|
@@ -197,11 +197,11 @@ AIR302_args.py:71:33: AIR302 [*] `use_task_execution_day` is removed in Airflow
197197
73 73 | branch_dt_op2 = BranchDateTimeOperator(
198198
74 74 | task_id="branch_dt_op2",
199199

200-
AIR302_args.py:71:62: AIR302 [*] `task_concurrency` is removed in Airflow 3.0
200+
AIR301_args.py:71:62: AIR301 [*] `task_concurrency` is removed in Airflow 3.0
201201
|
202202
70 | branch_dt_op = datetime.BranchDateTimeOperator(
203203
71 | task_id="branch_dt_op", use_task_execution_day=True, task_concurrency=5
204-
| ^^^^^^^^^^^^^^^^ AIR302
204+
| ^^^^^^^^^^^^^^^^ AIR301
205205
72 | )
206206
73 | branch_dt_op2 = BranchDateTimeOperator(
207207
|
@@ -217,12 +217,12 @@ AIR302_args.py:71:62: AIR302 [*] `task_concurrency` is removed in Airflow 3.0
217217
73 73 | branch_dt_op2 = BranchDateTimeOperator(
218218
74 74 | task_id="branch_dt_op2",
219219

220-
AIR302_args.py:75:9: AIR302 [*] `use_task_execution_day` is removed in Airflow 3.0
220+
AIR301_args.py:75:9: AIR301 [*] `use_task_execution_day` is removed in Airflow 3.0
221221
|
222222
73 | branch_dt_op2 = BranchDateTimeOperator(
223223
74 | task_id="branch_dt_op2",
224224
75 | use_task_execution_day=True,
225-
| ^^^^^^^^^^^^^^^^^^^^^^ AIR302
225+
| ^^^^^^^^^^^^^^^^^^^^^^ AIR301
226226
76 | sla=timedelta(seconds=10),
227227
77 | )
228228
|
@@ -238,57 +238,57 @@ AIR302_args.py:75:9: AIR302 [*] `use_task_execution_day` is removed in Airflow 3
238238
77 77 | )
239239
78 78 |
240240

241-
AIR302_args.py:76:9: AIR302 `sla` is removed in Airflow 3.0
241+
AIR301_args.py:76:9: AIR301 `sla` is removed in Airflow 3.0
242242
|
243243
74 | task_id="branch_dt_op2",
244244
75 | use_task_execution_day=True,
245245
76 | sla=timedelta(seconds=10),
246-
| ^^^ AIR302
246+
| ^^^ AIR301
247247
77 | )
248248
|
249249

250-
AIR302_args.py:98:15: AIR302 `filename_template` is removed in Airflow 3.0
250+
AIR301_args.py:98:15: AIR301 `filename_template` is removed in Airflow 3.0
251251
|
252252
97 | # deprecated filename_template argument in FileTaskHandler
253253
98 | S3TaskHandler(filename_template="/tmp/test")
254-
| ^^^^^^^^^^^^^^^^^ AIR302
254+
| ^^^^^^^^^^^^^^^^^ AIR301
255255
99 | HdfsTaskHandler(filename_template="/tmp/test")
256256
100 | ElasticsearchTaskHandler(filename_template="/tmp/test")
257257
|
258258

259-
AIR302_args.py:99:17: AIR302 `filename_template` is removed in Airflow 3.0
259+
AIR301_args.py:99:17: AIR301 `filename_template` is removed in Airflow 3.0
260260
|
261261
97 | # deprecated filename_template argument in FileTaskHandler
262262
98 | S3TaskHandler(filename_template="/tmp/test")
263263
99 | HdfsTaskHandler(filename_template="/tmp/test")
264-
| ^^^^^^^^^^^^^^^^^ AIR302
264+
| ^^^^^^^^^^^^^^^^^ AIR301
265265
100 | ElasticsearchTaskHandler(filename_template="/tmp/test")
266266
101 | GCSTaskHandler(filename_template="/tmp/test")
267267
|
268268

269-
AIR302_args.py:100:26: AIR302 `filename_template` is removed in Airflow 3.0
269+
AIR301_args.py:100:26: AIR301 `filename_template` is removed in Airflow 3.0
270270
|
271271
98 | S3TaskHandler(filename_template="/tmp/test")
272272
99 | HdfsTaskHandler(filename_template="/tmp/test")
273273
100 | ElasticsearchTaskHandler(filename_template="/tmp/test")
274-
| ^^^^^^^^^^^^^^^^^ AIR302
274+
| ^^^^^^^^^^^^^^^^^ AIR301
275275
101 | GCSTaskHandler(filename_template="/tmp/test")
276276
|
277277

278-
AIR302_args.py:101:16: AIR302 `filename_template` is removed in Airflow 3.0
278+
AIR301_args.py:101:16: AIR301 `filename_template` is removed in Airflow 3.0
279279
|
280280
99 | HdfsTaskHandler(filename_template="/tmp/test")
281281
100 | ElasticsearchTaskHandler(filename_template="/tmp/test")
282282
101 | GCSTaskHandler(filename_template="/tmp/test")
283-
| ^^^^^^^^^^^^^^^^^ AIR302
283+
| ^^^^^^^^^^^^^^^^^ AIR301
284284
102 |
285285
103 | FabAuthManager(None)
286286
|
287287

288-
AIR302_args.py:103:15: AIR302 `appbuilder` is removed in Airflow 3.0; The constructor takes no parameter now
288+
AIR301_args.py:103:15: AIR301 `appbuilder` is removed in Airflow 3.0; The constructor takes no parameter now
289289
|
290290
101 | GCSTaskHandler(filename_template="/tmp/test")
291291
102 |
292292
103 | FabAuthManager(None)
293-
| ^^^^^^ AIR302
293+
| ^^^^^^ AIR301
294294
|

0 commit comments

Comments
 (0)