Skip to content

Commit 0c29e25

Browse files
authored
[airflow] Add unsafe fix for module moved cases (AIR311) (#18366)
<!-- Thank you for contributing to Ruff/ty! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? (Please prefix with `[ty]` for ty pull requests.) - Does this pull request include references to any relevant issues? --> ## Summary <!-- What's the purpose of the change? What does it do, and why? --> Follow up on #18093 and apply it to AIR311 --- Rules fixed * `airflow.models.datasets.expand_alias_to_datasets` → `airflow.models.asset.expand_alias_to_assets` * `airflow.models.baseoperatorlink.BaseOperatorLink` → `airflow.sdk.BaseOperatorLink` ## Test Plan <!-- How was it tested? --> The existing test fixtures have been updated
1 parent b5b6b65 commit 0c29e25

File tree

3 files changed

+533
-330
lines changed

3 files changed

+533
-330
lines changed

crates/ruff_linter/resources/test/fixtures/airflow/AIR311_names.py

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,12 @@
99
expand_alias_to_datasets,
1010
)
1111
from airflow.datasets.metadata import Metadata
12-
from airflow.decorators import dag, setup, task, task_group, teardown
13-
from airflow.io.path import ObjectStoragePath
14-
from airflow.io.storage import attach
15-
from airflow.models import DAG as DAGFromModel
16-
from airflow.models import (
17-
Connection,
18-
Variable,
12+
from airflow.decorators import (
13+
dag,
14+
setup,
15+
task,
16+
task_group,
1917
)
20-
from airflow.models.baseoperator import chain, chain_linear, cross_downstream
21-
from airflow.models.baseoperatorlink import BaseOperatorLink
22-
from airflow.models.dag import DAG as DAGFromDag
23-
from airflow.timetables.datasets import DatasetOrTimeSchedule
24-
from airflow.utils.dag_parsing_context import get_parsing_context
2518

2619
# airflow
2720
DatasetFromRoot()
@@ -39,9 +32,22 @@
3932
task()
4033
task_group()
4134
setup()
35+
from airflow.decorators import teardown
36+
from airflow.io.path import ObjectStoragePath
37+
from airflow.io.storage import attach
38+
from airflow.models import DAG as DAGFromModel
39+
from airflow.models import (
40+
Connection,
41+
Variable,
42+
)
43+
from airflow.models.baseoperator import chain, chain_linear, cross_downstream
44+
from airflow.models.baseoperatorlink import BaseOperatorLink
45+
from airflow.models.dag import DAG as DAGFromDag
46+
47+
# airflow.decorators
4248
teardown()
4349

44-
# airflow.io
50+
# # airflow.io
4551
ObjectStoragePath()
4652
attach()
4753

@@ -60,6 +66,9 @@
6066

6167
# airflow.models.dag
6268
DAGFromDag()
69+
from airflow.timetables.datasets import DatasetOrTimeSchedule
70+
from airflow.utils.dag_parsing_context import get_parsing_context
71+
6372
# airflow.timetables.datasets
6473
DatasetOrTimeSchedule()
6574

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

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::checkers::ast::Checker;
2-
use crate::importer::ImportRequest;
2+
use crate::rules::airflow::helpers::{Replacement, is_airflow_builtin_or_provider};
33
use crate::rules::airflow::helpers::{
4-
Replacement, is_airflow_builtin_or_provider, is_guarded_by_try_except,
4+
generate_import_edit, generate_remove_and_runtime_import_edit, is_guarded_by_try_except,
55
};
66
use crate::{Edit, Fix, FixAvailability, Violation};
77
use ruff_macros::{ViolationMetadata, derive_message_formats};
@@ -211,7 +211,7 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
211211
name: "AssetAny",
212212
},
213213
"expand_alias_to_datasets" => Replacement::AutoImport {
214-
module: "airflow.sdk",
214+
module: "airflow.models.asset",
215215
name: "expand_alias_to_assets",
216216
},
217217
_ => return,
@@ -256,7 +256,7 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
256256
name: (*rest).to_string(),
257257
},
258258
["airflow", "models", "baseoperatorlink", "BaseOperatorLink"] => Replacement::AutoImport {
259-
module: "airflow.sdk.definitions.baseoperatorlink",
259+
module: "airflow.sdk",
260260
name: "BaseOperatorLink",
261261
},
262262
// airflow.model..DAG
@@ -301,22 +301,16 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
301301
if is_guarded_by_try_except(expr, module, name, checker.semantic()) {
302302
return;
303303
}
304-
305-
checker
306-
.report_diagnostic(
307-
Airflow3SuggestedUpdate {
308-
deprecated: qualified_name.to_string(),
309-
replacement: replacement.clone(),
310-
},
311-
range,
312-
)
313-
.try_set_fix(|| {
314-
let (import_edit, binding) = checker.importer().get_or_import_symbol(
315-
&ImportRequest::import_from(module, name),
316-
expr.start(),
317-
checker.semantic(),
318-
)?;
319-
let replacement_edit = Edit::range_replacement(binding, range);
320-
Ok(Fix::safe_edits(import_edit, [replacement_edit]))
321-
});
304+
let mut diagnostic = checker.report_diagnostic(
305+
Airflow3SuggestedUpdate {
306+
deprecated: qualified_name.to_string(),
307+
replacement: replacement.clone(),
308+
},
309+
range,
310+
);
311+
if let Some(fix) = generate_import_edit(expr, checker, module, name, range)
312+
.or_else(|| generate_remove_and_runtime_import_edit(expr, checker, module, name))
313+
{
314+
diagnostic.set_fix(fix);
315+
}
322316
}

0 commit comments

Comments
 (0)