Skip to content

Commit d65bd69

Browse files
authored
[airflow] Add unsafe fix for module moved cases (AIR312) (#18363)
<!-- 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 AIR312 ## Test Plan <!-- How was it tested? --> The existing test fixtures have been updated
1 parent c713e76 commit d65bd69

File tree

3 files changed

+659
-233
lines changed

3 files changed

+659
-233
lines changed

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

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,49 +7,71 @@
77
from airflow.operators.datetime import BranchDateTimeOperator
88
from airflow.operators.empty import EmptyOperator
99
from airflow.operators.latest_only import LatestOnlyOperator
10+
from airflow.operators.trigger_dagrun import TriggerDagRunOperator
11+
from airflow.operators.weekday import BranchDayOfWeekOperator
12+
from airflow.sensors.date_time import DateTimeSensor
13+
14+
FSHook()
15+
PackageIndexHook()
16+
SubprocessHook()
17+
18+
BashOperator()
19+
BranchDateTimeOperator()
20+
TriggerDagRunOperator()
21+
EmptyOperator()
22+
23+
LatestOnlyOperator()
24+
BranchDayOfWeekOperator()
25+
DateTimeSensor()
26+
1027
from airflow.operators.python import (
1128
BranchPythonOperator,
1229
PythonOperator,
1330
PythonVirtualenvOperator,
1431
ShortCircuitOperator,
1532
)
16-
from airflow.operators.trigger_dagrun import TriggerDagRunOperator
17-
from airflow.operators.weekday import BranchDayOfWeekOperator
18-
from airflow.sensors.date_time import DateTimeSensor, DateTimeSensorAsync
33+
from airflow.sensors.date_time import DateTimeSensorAsync
1934
from airflow.sensors.external_task import (
2035
ExternalTaskMarker,
2136
ExternalTaskSensor,
22-
37+
)
38+
from airflow.sensors.time_sensor import (
39+
TimeSensor,
40+
TimeSensorAsync,
2341
)
2442
from airflow.sensors.filesystem import FileSensor
25-
from airflow.sensors.time_delta import TimeDeltaSensor, TimeDeltaSensorAsync
26-
from airflow.sensors.time_sensor import TimeSensor, TimeSensorAsync
43+
44+
BranchPythonOperator()
45+
PythonOperator()
46+
PythonVirtualenvOperator()
47+
ShortCircuitOperator()
48+
DateTimeSensorAsync()
49+
ExternalTaskMarker()
50+
ExternalTaskSensor()
51+
FileSensor()
52+
TimeSensor()
53+
TimeSensorAsync()
54+
55+
from airflow.sensors.time_delta import (
56+
TimeDeltaSensor,
57+
TimeDeltaSensorAsync,
58+
)
2759
from airflow.sensors.weekday import DayOfWeekSensor
28-
from airflow.triggers.external_task import DagStateTrigger, WorkflowTrigger
60+
from airflow.triggers.external_task import (
61+
DagStateTrigger,
62+
WorkflowTrigger,
63+
)
2964
from airflow.triggers.file import FileTrigger
30-
from airflow.triggers.temporal import DateTimeTrigger, TimeDeltaTrigger
31-
32-
FSHook()
33-
PackageIndexHook()
34-
SubprocessHook()
35-
BashOperator()
36-
BranchDateTimeOperator()
37-
TriggerDagRunOperator()
38-
EmptyOperator()
39-
LatestOnlyOperator()
40-
(
41-
BranchPythonOperator(),
42-
PythonOperator(),
43-
PythonVirtualenvOperator(),
44-
ShortCircuitOperator(),
65+
from airflow.triggers.temporal import (
66+
DateTimeTrigger,
67+
TimeDeltaTrigger,
4568
)
46-
BranchDayOfWeekOperator()
47-
DateTimeSensor(), DateTimeSensorAsync()
48-
ExternalTaskMarker(), ExternalTaskSensor()
49-
FileSensor()
50-
TimeSensor(), TimeSensorAsync()
51-
TimeDeltaSensor(), TimeDeltaSensorAsync()
69+
70+
TimeDeltaSensor()
71+
TimeDeltaSensorAsync()
5272
DayOfWeekSensor()
53-
DagStateTrigger(), WorkflowTrigger()
73+
DagStateTrigger()
74+
WorkflowTrigger()
5475
FileTrigger()
55-
DateTimeTrigger(), TimeDeltaTrigger()
76+
DateTimeTrigger()
77+
TimeDeltaTrigger()

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

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
use crate::importer::ImportRequest;
2-
3-
use crate::rules::airflow::helpers::{ProviderReplacement, is_guarded_by_try_except};
4-
use crate::{Edit, Fix, FixAvailability, Violation};
1+
use crate::checkers::ast::Checker;
2+
use crate::rules::airflow::helpers::{
3+
ProviderReplacement, generate_import_edit, generate_remove_and_runtime_import_edit,
4+
is_guarded_by_try_except,
5+
};
6+
use crate::{FixAvailability, Violation};
57
use ruff_macros::{ViolationMetadata, derive_message_formats};
68
use ruff_python_ast::name::QualifiedName;
79
use ruff_python_ast::{Expr, ExprAttribute};
810
use ruff_python_semantic::Modules;
911
use ruff_text_size::Ranged;
1012
use ruff_text_size::TextRange;
1113

12-
use crate::checkers::ast::Checker;
13-
1414
/// ## What it does
1515
/// Checks for uses of Airflow functions and values that have been moved to its providers
1616
/// but still have a compatibility layer (e.g., `apache-airflow-providers-standard`).
@@ -302,22 +302,17 @@ fn check_names_moved_to_provider(checker: &Checker, expr: &Expr, ranged: TextRan
302302
if is_guarded_by_try_except(expr, module, name, checker.semantic()) {
303303
return;
304304
}
305+
let mut diagnostic = checker.report_diagnostic(
306+
Airflow3SuggestedToMoveToProvider {
307+
deprecated: qualified_name,
308+
replacement: replacement.clone(),
309+
},
310+
ranged,
311+
);
305312

306-
checker
307-
.report_diagnostic(
308-
Airflow3SuggestedToMoveToProvider {
309-
deprecated: qualified_name,
310-
replacement: replacement.clone(),
311-
},
312-
ranged.range(),
313-
)
314-
.try_set_fix(|| {
315-
let (import_edit, binding) = checker.importer().get_or_import_symbol(
316-
&ImportRequest::import_from(module, name),
317-
expr.start(),
318-
checker.semantic(),
319-
)?;
320-
let replacement_edit = Edit::range_replacement(binding, ranged.range());
321-
Ok(Fix::safe_edits(import_edit, [replacement_edit]))
322-
});
313+
if let Some(fix) = generate_import_edit(expr, checker, module, name, ranged)
314+
.or_else(|| generate_remove_and_runtime_import_edit(expr, checker, module, name))
315+
{
316+
diagnostic.set_fix(fix);
317+
}
323318
}

0 commit comments

Comments
 (0)