mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 18:58:04 +00:00
[airflow
] Get rid of Replacement::Name
and replace them with Replacement::AutoImport
for enabling auto fixing (AIR301
, AIR311
) (#17941)
<!-- Thank you for contributing to Ruff! 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? - Does this pull request include references to any relevant issues? --> ## Summary <!-- What's the purpose of the change? What does it do, and why? --> Similiar to https://github.com/astral-sh/ruff/pull/17941. `Replacement::Name` was designed for linting only. Now, we also want to fix the user code. It would be easier to replace it with a better AutoImport struct whenever possible. On the other hand, `AIR301` and `AIR311` contain attribute changes that can still use a struct like `Replacement::Name`. To reduce the confusion, I also updated it as `Replacement::AttrName` Some of the original `Replacement::Name` has been replaced as `Replacement::Message` as they're not directly mapping and the message has now been moved to `help` ## Test Plan <!-- How was it tested? --> The test fixtures have been updated
This commit is contained in:
parent
1e4377c9c6
commit
2e94d37275
7 changed files with 443 additions and 360 deletions
|
@ -24,9 +24,6 @@ from airflow.contrib.aws_athena_hook import AWSAthenaHook
|
|||
from airflow.datasets import DatasetAliasEvent
|
||||
from airflow.hooks.base_hook import BaseHook
|
||||
from airflow.operators.subdag import SubDagOperator
|
||||
from airflow.providers.mysql.datasets import mysql
|
||||
from airflow.providers.postgres.datasets import postgres
|
||||
from airflow.providers.trino.datasets import trino
|
||||
from airflow.secrets.local_filesystem import LocalFilesystemBackend
|
||||
from airflow.sensors.base_sensor_operator import BaseSensorOperator
|
||||
from airflow.triggers.external_task import TaskStateTrigger
|
||||
|
@ -78,14 +75,6 @@ BaseHook()
|
|||
# airflow.operators.subdag.*
|
||||
SubDagOperator()
|
||||
|
||||
# airflow.providers.mysql
|
||||
mysql.sanitize_uri
|
||||
|
||||
# airflow.providers.postgres
|
||||
postgres.sanitize_uri
|
||||
|
||||
# airflow.providers.trino
|
||||
trino.sanitize_uri
|
||||
|
||||
# airflow.secrets
|
||||
# get_connection
|
||||
|
@ -155,3 +144,18 @@ should_hide_value_for_key
|
|||
from airflow.operators.python import get_current_context
|
||||
|
||||
get_current_context()
|
||||
|
||||
# airflow.providers.mysql
|
||||
from airflow.providers.mysql.datasets.mysql import sanitize_uri
|
||||
|
||||
sanitize_uri
|
||||
|
||||
# airflow.providers.postgres
|
||||
from airflow.providers.postgres.datasets.postgres import sanitize_uri
|
||||
|
||||
sanitize_uri
|
||||
|
||||
# airflow.providers.trino
|
||||
from airflow.providers.trino.datasets.trino import sanitize_uri
|
||||
|
||||
sanitize_uri
|
||||
|
|
|
@ -8,13 +8,20 @@ use ruff_python_semantic::SemanticModel;
|
|||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub(crate) enum Replacement {
|
||||
// There's no replacement or suggestion other than removal
|
||||
None,
|
||||
Name(&'static str),
|
||||
// The attribute name of a class has been changed.
|
||||
AttrName(&'static str),
|
||||
// Additional information. Used when there's replacement but they're not direct mapping.
|
||||
Message(&'static str),
|
||||
// Symbols updated in Airflow 3 with replacement
|
||||
// e.g., `airflow.datasets.Dataset` to `airflow.sdk.Asset`
|
||||
AutoImport {
|
||||
module: &'static str,
|
||||
name: &'static str,
|
||||
},
|
||||
// Symbols updated in Airflow 3 with only module changed. Used when we want to match multiple names.
|
||||
// e.g., `airflow.configuration.as_dict | get` to `airflow.configuration.conf.as_dict | get`
|
||||
SourceModuleMoved {
|
||||
module: &'static str,
|
||||
name: String,
|
||||
|
|
|
@ -57,28 +57,27 @@ impl Violation for Airflow3Removal {
|
|||
} = self;
|
||||
match replacement {
|
||||
Replacement::None
|
||||
| Replacement::Name(_)
|
||||
| Replacement::AttrName(_)
|
||||
| Replacement::Message(_)
|
||||
| Replacement::AutoImport { module: _, name: _ }
|
||||
| Replacement::SourceModuleMoved { module: _, name: _ } => {
|
||||
format!("`{deprecated}` is removed in Airflow 3.0")
|
||||
}
|
||||
Replacement::Message(message) => {
|
||||
format!("`{deprecated}` is removed in Airflow 3.0; {message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fix_title(&self) -> Option<String> {
|
||||
let Airflow3Removal { replacement, .. } = self;
|
||||
match replacement {
|
||||
Replacement::Name(name) => Some(format!("Use `{name}` instead")),
|
||||
Replacement::None => None,
|
||||
Replacement::AttrName(name) => Some(format!("Use `{name}` instead")),
|
||||
Replacement::Message(message) => Some((*message).to_string()),
|
||||
Replacement::AutoImport { module, name } => {
|
||||
Some(format!("Use `{module}.{name}` instead"))
|
||||
}
|
||||
Replacement::SourceModuleMoved { module, name } => {
|
||||
Some(format!("Use `{module}.{name}` instead"))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -278,22 +277,22 @@ fn check_class_attribute(checker: &Checker, attribute_expr: &ExprAttribute) {
|
|||
|
||||
let replacement = match *qualname.segments() {
|
||||
["airflow", "providers_manager", "ProvidersManager"] => match attr.as_str() {
|
||||
"dataset_factories" => Replacement::Name("asset_factories"),
|
||||
"dataset_uri_handlers" => Replacement::Name("asset_uri_handlers"),
|
||||
"dataset_factories" => Replacement::AttrName("asset_factories"),
|
||||
"dataset_uri_handlers" => Replacement::AttrName("asset_uri_handlers"),
|
||||
"dataset_to_openlineage_converters" => {
|
||||
Replacement::Name("asset_to_openlineage_converters")
|
||||
Replacement::AttrName("asset_to_openlineage_converters")
|
||||
}
|
||||
_ => return,
|
||||
},
|
||||
["airflow", "lineage", "hook", "DatasetLineageInfo"] => match attr.as_str() {
|
||||
"dataset" => Replacement::Name("asset"),
|
||||
"dataset" => Replacement::AttrName("asset"),
|
||||
_ => return,
|
||||
},
|
||||
_ => return,
|
||||
};
|
||||
|
||||
// Create the `Fix` first to avoid cloning `Replacement`.
|
||||
let fix = if let Replacement::Name(name) = replacement {
|
||||
let fix = if let Replacement::AttrName(name) = replacement {
|
||||
Some(Fix::safe_edit(Edit::range_replacement(
|
||||
name.to_string(),
|
||||
attr.range(),
|
||||
|
@ -466,52 +465,52 @@ fn check_method(checker: &Checker, call_expr: &ExprCall) {
|
|||
|
||||
let replacement = match qualname.segments() {
|
||||
["airflow", "datasets", "manager", "DatasetManager"] => match attr.as_str() {
|
||||
"register_dataset_change" => Replacement::Name("register_asset_change"),
|
||||
"create_datasets" => Replacement::Name("create_assets"),
|
||||
"notify_dataset_created" => Replacement::Name("notify_asset_created"),
|
||||
"notify_dataset_changed" => Replacement::Name("notify_asset_changed"),
|
||||
"notify_dataset_alias_created" => Replacement::Name("notify_asset_alias_created"),
|
||||
"register_dataset_change" => Replacement::AttrName("register_asset_change"),
|
||||
"create_datasets" => Replacement::AttrName("create_assets"),
|
||||
"notify_dataset_created" => Replacement::AttrName("notify_asset_created"),
|
||||
"notify_dataset_changed" => Replacement::AttrName("notify_asset_changed"),
|
||||
"notify_dataset_alias_created" => Replacement::AttrName("notify_asset_alias_created"),
|
||||
_ => return,
|
||||
},
|
||||
["airflow", "lineage", "hook", "HookLineageCollector"] => match attr.as_str() {
|
||||
"create_dataset" => Replacement::Name("create_asset"),
|
||||
"add_input_dataset" => Replacement::Name("add_input_asset"),
|
||||
"add_output_dataset" => Replacement::Name("add_output_asset"),
|
||||
"collected_datasets" => Replacement::Name("collected_assets"),
|
||||
"create_dataset" => Replacement::AttrName("create_asset"),
|
||||
"add_input_dataset" => Replacement::AttrName("add_input_asset"),
|
||||
"add_output_dataset" => Replacement::AttrName("add_output_asset"),
|
||||
"collected_datasets" => Replacement::AttrName("collected_assets"),
|
||||
_ => return,
|
||||
},
|
||||
["airflow", "providers", "amazon", "auth_manager", "aws_auth_manager", "AwsAuthManager"] => {
|
||||
match attr.as_str() {
|
||||
"is_authorized_dataset" => Replacement::Name("is_authorized_asset"),
|
||||
"is_authorized_dataset" => Replacement::AttrName("is_authorized_asset"),
|
||||
_ => return,
|
||||
}
|
||||
}
|
||||
["airflow", "providers_manager", "ProvidersManager"] => match attr.as_str() {
|
||||
"initialize_providers_dataset_uri_resources" => {
|
||||
Replacement::Name("initialize_providers_asset_uri_resources")
|
||||
Replacement::AttrName("initialize_providers_asset_uri_resources")
|
||||
}
|
||||
_ => return,
|
||||
},
|
||||
["airflow", "secrets", "local_filesystem", "LocalFilesystemBackend"] => match attr.as_str()
|
||||
{
|
||||
"get_connections" => Replacement::Name("get_connection"),
|
||||
"get_connections" => Replacement::AttrName("get_connection"),
|
||||
_ => return,
|
||||
},
|
||||
["airflow", "datasets", ..] | ["airflow", "Dataset"] => match attr.as_str() {
|
||||
"iter_datasets" => Replacement::Name("iter_assets"),
|
||||
"iter_dataset_aliases" => Replacement::Name("iter_asset_aliases"),
|
||||
"iter_datasets" => Replacement::AttrName("iter_assets"),
|
||||
"iter_dataset_aliases" => Replacement::AttrName("iter_asset_aliases"),
|
||||
_ => return,
|
||||
},
|
||||
segments => {
|
||||
if is_airflow_secret_backend(segments) {
|
||||
match attr.as_str() {
|
||||
"get_conn_uri" => Replacement::Name("get_conn_value"),
|
||||
"get_connections" => Replacement::Name("get_connection"),
|
||||
"get_conn_uri" => Replacement::AttrName("get_conn_value"),
|
||||
"get_connections" => Replacement::AttrName("get_connection"),
|
||||
_ => return,
|
||||
}
|
||||
} else if is_airflow_hook(segments) {
|
||||
match attr.as_str() {
|
||||
"get_connections" => Replacement::Name("get_connection"),
|
||||
"get_connections" => Replacement::AttrName("get_connection"),
|
||||
_ => return,
|
||||
}
|
||||
} else {
|
||||
|
@ -520,7 +519,7 @@ fn check_method(checker: &Checker, call_expr: &ExprCall) {
|
|||
}
|
||||
};
|
||||
// Create the `Fix` first to avoid cloning `Replacement`.
|
||||
let fix = if let Replacement::Name(name) = replacement {
|
||||
let fix = if let Replacement::AttrName(name) = replacement {
|
||||
Some(Fix::safe_edit(Edit::range_replacement(
|
||||
name.to_string(),
|
||||
attr.range(),
|
||||
|
@ -566,12 +565,12 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
let replacement = match qualified_name.segments() {
|
||||
// airflow.PY\d{1,2}
|
||||
["airflow", "PY36" | "PY37" | "PY38" | "PY39" | "PY310" | "PY311" | "PY312"] => {
|
||||
Replacement::Name("sys.version_info")
|
||||
Replacement::Message("Use `sys.version_info` instead")
|
||||
}
|
||||
|
||||
// airflow.api_connexion.security
|
||||
["airflow", "api_connexion", "security", "requires_access"] => {
|
||||
Replacement::Name("airflow.api_connexion.security.requires_access_*")
|
||||
Replacement::Message("Use `airflow.api_connexion.security.requires_access_*` instead")
|
||||
}
|
||||
["airflow", "api_connexion", "security", "requires_access_dataset"] => {
|
||||
Replacement::AutoImport {
|
||||
|
@ -626,9 +625,10 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
["airflow", "datasets", "DatasetAliasEvent"] => Replacement::None,
|
||||
|
||||
// airflow.hooks
|
||||
["airflow", "hooks", "base_hook", "BaseHook"] => {
|
||||
Replacement::Name("airflow.hooks.base.BaseHook")
|
||||
}
|
||||
["airflow", "hooks", "base_hook", "BaseHook"] => Replacement::AutoImport {
|
||||
module: "airflow.hooks.base",
|
||||
name: "BaseHook",
|
||||
},
|
||||
|
||||
// airflow.lineage.hook
|
||||
["airflow", "lineage", "hook", "DatasetLineageInfo"] => Replacement::AutoImport {
|
||||
|
@ -664,9 +664,10 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
},
|
||||
|
||||
// airflow.notifications
|
||||
["airflow", "notifications", "basenotifier", "BaseNotifier"] => {
|
||||
Replacement::Name("airflow.sdk.BaseNotifier")
|
||||
}
|
||||
["airflow", "notifications", "basenotifier", "BaseNotifier"] => Replacement::AutoImport {
|
||||
module: "airflow.sdk",
|
||||
name: "BaseNotifier",
|
||||
},
|
||||
|
||||
// airflow.operators
|
||||
["airflow", "operators", "subdag", ..] => {
|
||||
|
@ -691,7 +692,10 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
|
||||
// airflow.sensors
|
||||
["airflow", "sensors", "base_sensor_operator", "BaseSensorOperator"] => {
|
||||
Replacement::Name("airflow.sdk.bases.sensor.BaseSensorOperator")
|
||||
Replacement::AutoImport {
|
||||
module: "airflow.sdk.bases.sensor",
|
||||
name: "BaseSensorOperator",
|
||||
}
|
||||
}
|
||||
|
||||
// airflow.timetables
|
||||
|
@ -720,23 +724,36 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
|
||||
// airflow.utils.dates
|
||||
["dates", "date_range"] => Replacement::None,
|
||||
["dates", "days_ago"] => Replacement::Name("pendulum.today('UTC').add(days=-N, ...)"),
|
||||
["dates", "days_ago"] => {
|
||||
Replacement::Message("Use `pendulum.today('UTC').add(days=-N, ...)` instead")
|
||||
}
|
||||
["dates", "parse_execution_date" | "round_time" | "scale_time_units" | "infer_time_unit"] => {
|
||||
Replacement::None
|
||||
}
|
||||
|
||||
// airflow.utils.file
|
||||
["file", "TemporaryDirectory"] => Replacement::Name("tempfile.TemporaryDirectory"),
|
||||
["file", "mkdirs"] => Replacement::Name("pathlib.Path({path}).mkdir"),
|
||||
["file", "TemporaryDirectory"] => Replacement::AutoImport {
|
||||
module: "tempfile",
|
||||
name: "TemporaryDirectory",
|
||||
},
|
||||
["file", "mkdirs"] => Replacement::Message("Use `pathlib.Path({path}).mkdir` instead"),
|
||||
|
||||
// airflow.utils.helpers
|
||||
["helpers", "chain"] => Replacement::Name("airflow.sdk.chain"),
|
||||
["helpers", "cross_downstream"] => Replacement::Name("airflow.sdk.cross_downstream"),
|
||||
["helpers", "chain"] => Replacement::AutoImport {
|
||||
module: "airflow.sdk",
|
||||
name: "chain",
|
||||
},
|
||||
["helpers", "cross_downstream"] => Replacement::AutoImport {
|
||||
module: "airflow.sdk",
|
||||
name: "cross_downstream",
|
||||
},
|
||||
|
||||
// TODO: update it as SourceModuleMoved
|
||||
// airflow.utils.log.secrets_masker
|
||||
["log", "secrets_masker"] => {
|
||||
Replacement::Name("airflow.sdk.execution_time.secrets_masker")
|
||||
}
|
||||
["log", "secrets_masker"] => Replacement::AutoImport {
|
||||
module: "airflow.sdk.execution_time",
|
||||
name: "secrets_masker",
|
||||
},
|
||||
|
||||
// airflow.utils.state
|
||||
["state", "SHUTDOWN" | "terminating_states"] => Replacement::None,
|
||||
|
@ -751,18 +768,20 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
// airflow.www
|
||||
// TODO: www has been removed
|
||||
["airflow", "www", "auth", "has_access"] => {
|
||||
Replacement::Name("airflow.www.auth.has_access_*")
|
||||
Replacement::Message("Use `airflow.www.auth.has_access_*` instead")
|
||||
}
|
||||
["airflow", "www", "auth", "has_access_dataset"] => Replacement::AutoImport {
|
||||
module: "airflow.www.auth",
|
||||
name: "has_access_asset",
|
||||
},
|
||||
["airflow", "www", "utils", "get_sensitive_variables_fields"] => {
|
||||
Replacement::Name("airflow.utils.log.secrets_masker.get_sensitive_variables_fields")
|
||||
}
|
||||
["airflow", "www", "utils", "should_hide_value_for_key"] => {
|
||||
Replacement::Name("airflow.utils.log.secrets_masker.should_hide_value_for_key")
|
||||
}
|
||||
["airflow", "www", "utils", "get_sensitive_variables_fields"] => Replacement::AutoImport {
|
||||
module: "airflow.utils.log.secrets_masker",
|
||||
name: "get_sensitive_variables_fields",
|
||||
},
|
||||
["airflow", "www", "utils", "should_hide_value_for_key"] => Replacement::AutoImport {
|
||||
module: "airflow.utils.log.secrets_masker",
|
||||
name: "should_hide_value_for_key",
|
||||
},
|
||||
|
||||
// airflow.providers.amazon
|
||||
["airflow", "providers", "amazon", "aws", "datasets", "s3", rest] => match *rest {
|
||||
|
@ -774,9 +793,10 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
module: "airflow.providers.amazon.aws.assets.s3",
|
||||
name: "convert_asset_to_openlineage",
|
||||
},
|
||||
"sanitize_uri" => {
|
||||
Replacement::Name("airflow.providers.amazon.aws.assets.s3.sanitize_uri")
|
||||
}
|
||||
"sanitize_uri" => Replacement::AutoImport {
|
||||
module: "airflow.providers.amazon.aws.assets.s3",
|
||||
name: "sanitize_uri",
|
||||
},
|
||||
_ => return,
|
||||
},
|
||||
["airflow", "providers", "amazon", "aws", "auth_manager", "avp", "entities", "AvpEntities", "DATASET"] => {
|
||||
|
@ -797,9 +817,10 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
module: "airflow.providers.common.io.assets.file",
|
||||
name: "convert_asset_to_openlineage",
|
||||
},
|
||||
"sanitize_uri" => {
|
||||
Replacement::Name("airflow.providers.common.io.assets.file.sanitize_uri")
|
||||
}
|
||||
"sanitize_uri" => Replacement::AutoImport {
|
||||
module: "airflow.providers.common.io.assets.file",
|
||||
name: "sanitize_uri",
|
||||
},
|
||||
_ => return,
|
||||
},
|
||||
|
||||
|
@ -826,20 +847,28 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
module: "airflow.providers.google.assets.gcs",
|
||||
name: "convert_asset_to_openlineage",
|
||||
},
|
||||
["gcs", "sanitize_uri"] => {
|
||||
Replacement::Name("airflow.providers.google.assets.gcs.sanitize_uri")
|
||||
}
|
||||
["gcs", "sanitize_uri"] => Replacement::AutoImport {
|
||||
module: "airflow.providers.google.assets.gcs",
|
||||
name: "sanitize_uri",
|
||||
},
|
||||
|
||||
_ => return,
|
||||
},
|
||||
|
||||
// airflow.providers.mysql
|
||||
["airflow", "providers", "mysql", "datasets", "mysql", "sanitize_uri"] => {
|
||||
Replacement::Name("airflow.providers.mysql.assets.mysql.sanitize_uri")
|
||||
Replacement::AutoImport {
|
||||
module: "airflow.providers.mysql.assets.mysql",
|
||||
name: "sanitize_uri",
|
||||
}
|
||||
}
|
||||
|
||||
// airflow.providers.postgres
|
||||
["airflow", "providers", "postgres", "datasets", "postgres", "sanitize_uri"] => {
|
||||
Replacement::Name("airflow.providers.postgres.assets.postgres.sanitize_uri")
|
||||
Replacement::AutoImport {
|
||||
module: "airflow.providers.postgres.assets.postgres",
|
||||
name: "sanitize_uri",
|
||||
}
|
||||
}
|
||||
|
||||
// airflow.providers.openlineage
|
||||
|
@ -859,7 +888,10 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
|
||||
// airflow.providers.trino
|
||||
["airflow", "providers", "trino", "datasets", "trino", "sanitize_uri"] => {
|
||||
Replacement::Name("airflow.providers.trino.assets.trino.sanitize_uri")
|
||||
Replacement::AutoImport {
|
||||
module: "airflow.providers.trino.assets.trino",
|
||||
name: "sanitize_uri",
|
||||
}
|
||||
}
|
||||
|
||||
_ => return,
|
||||
|
@ -949,7 +981,7 @@ fn diagnostic_for_argument(
|
|||
Airflow3Removal {
|
||||
deprecated: deprecated.to_string(),
|
||||
replacement: match replacement {
|
||||
Some(name) => Replacement::Name(name),
|
||||
Some(name) => Replacement::AttrName(name),
|
||||
None => Replacement::None,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -53,7 +53,8 @@ impl Violation for Airflow3SuggestedUpdate {
|
|||
} = self;
|
||||
match replacement {
|
||||
Replacement::None
|
||||
| Replacement::Name(_)
|
||||
| Replacement::AttrName(_)
|
||||
| Replacement::Message(_)
|
||||
| Replacement::AutoImport { module: _, name: _ }
|
||||
| Replacement::SourceModuleMoved { module: _, name: _ } => {
|
||||
format!(
|
||||
|
@ -61,27 +62,21 @@ impl Violation for Airflow3SuggestedUpdate {
|
|||
It still works in Airflow 3.0 but is expected to be removed in a future version."
|
||||
)
|
||||
}
|
||||
Replacement::Message(message) => {
|
||||
format!(
|
||||
"`{deprecated}` is removed in Airflow 3.0; \
|
||||
It still works in Airflow 3.0 but is expected to be removed in a future version.; \
|
||||
{message}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fix_title(&self) -> Option<String> {
|
||||
let Airflow3SuggestedUpdate { replacement, .. } = self;
|
||||
match replacement {
|
||||
Replacement::Name(name) => Some(format!("Use `{name}` instead")),
|
||||
Replacement::None => None,
|
||||
Replacement::AttrName(name) => Some(format!("Use `{name}` instead")),
|
||||
Replacement::Message(message) => Some((*message).to_string()),
|
||||
Replacement::AutoImport { module, name } => {
|
||||
Some(format!("Use `{module}.{name}` instead"))
|
||||
}
|
||||
Replacement::SourceModuleMoved { module, name } => {
|
||||
Some(format!("Use `{module}.{name}` instead"))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +121,7 @@ fn diagnostic_for_argument(
|
|||
Airflow3SuggestedUpdate {
|
||||
deprecated: deprecated.to_string(),
|
||||
replacement: match replacement {
|
||||
Some(name) => Replacement::Name(name),
|
||||
Some(name) => Replacement::AttrName(name),
|
||||
None => Replacement::None,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/airflow/mod.rs
|
||||
---
|
||||
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.
|
||||
AIR301_airflow_plugin.py:7:5: AIR301 `operators` is removed in Airflow 3.0
|
||||
|
|
||||
5 | name = "test_plugin"
|
||||
6 | # --- Invalid extensions start
|
||||
|
@ -10,8 +10,9 @@ AIR301_airflow_plugin.py:7:5: AIR301 `operators` is removed in Airflow 3.0; This
|
|||
8 | sensors = [PluginSensorOperator]
|
||||
9 | hooks = [PluginHook]
|
||||
|
|
||||
= help: This extension should just be imported as a regular python module.
|
||||
|
||||
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.
|
||||
AIR301_airflow_plugin.py:8:5: AIR301 `sensors` is removed in Airflow 3.0
|
||||
|
|
||||
6 | # --- Invalid extensions start
|
||||
7 | operators = [PluginOperator]
|
||||
|
@ -20,8 +21,9 @@ AIR301_airflow_plugin.py:8:5: AIR301 `sensors` is removed in Airflow 3.0; This e
|
|||
9 | hooks = [PluginHook]
|
||||
10 | executors = [PluginExecutor]
|
||||
|
|
||||
= help: This extension should just be imported as a regular python module.
|
||||
|
||||
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.
|
||||
AIR301_airflow_plugin.py:9:5: AIR301 `hooks` is removed in Airflow 3.0
|
||||
|
|
||||
7 | operators = [PluginOperator]
|
||||
8 | sensors = [PluginSensorOperator]
|
||||
|
@ -30,8 +32,9 @@ AIR301_airflow_plugin.py:9:5: AIR301 `hooks` is removed in Airflow 3.0; This ext
|
|||
10 | executors = [PluginExecutor]
|
||||
11 | # --- Invalid extensions end
|
||||
|
|
||||
= help: This extension should just be imported as a regular python module.
|
||||
|
||||
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.
|
||||
AIR301_airflow_plugin.py:10:5: AIR301 `executors` is removed in Airflow 3.0
|
||||
|
|
||||
8 | sensors = [PluginSensorOperator]
|
||||
9 | hooks = [PluginHook]
|
||||
|
@ -40,3 +43,4 @@ AIR301_airflow_plugin.py:10:5: AIR301 `executors` is removed in Airflow 3.0; Thi
|
|||
11 | # --- Invalid extensions end
|
||||
12 | macros = [plugin_macro]
|
||||
|
|
||||
= help: This extension should just be imported as a regular python module.
|
||||
|
|
|
@ -258,10 +258,11 @@ AIR301_args.py:90:16: AIR301 `filename_template` is removed in Airflow 3.0
|
|||
92 | FabAuthManager(None)
|
||||
|
|
||||
|
||||
AIR301_args.py:92:15: AIR301 `appbuilder` is removed in Airflow 3.0; The constructor takes no parameter now
|
||||
AIR301_args.py:92:15: AIR301 `appbuilder` is removed in Airflow 3.0
|
||||
|
|
||||
90 | GCSTaskHandler(filename_template="/tmp/test")
|
||||
91 |
|
||||
92 | FabAuthManager(None)
|
||||
| ^^^^^^ AIR301
|
||||
|
|
||||
= help: The constructor takes no parameter now
|
||||
|
|
|
@ -1,448 +1,488 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/airflow/mod.rs
|
||||
---
|
||||
AIR301_names.py:56:1: AIR301 `airflow.PY36` is removed in Airflow 3.0
|
||||
AIR301_names.py:53:1: AIR301 `airflow.PY36` is removed in Airflow 3.0
|
||||
|
|
||||
55 | # airflow root
|
||||
56 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
52 | # airflow root
|
||||
53 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
| ^^^^ AIR301
|
||||
57 |
|
||||
58 | # airflow.api_connexion.security
|
||||
54 |
|
||||
55 | # airflow.api_connexion.security
|
||||
|
|
||||
= help: Use `sys.version_info` instead
|
||||
|
||||
AIR301_names.py:56:7: AIR301 `airflow.PY37` is removed in Airflow 3.0
|
||||
AIR301_names.py:53:7: AIR301 `airflow.PY37` is removed in Airflow 3.0
|
||||
|
|
||||
55 | # airflow root
|
||||
56 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
52 | # airflow root
|
||||
53 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
| ^^^^ AIR301
|
||||
57 |
|
||||
58 | # airflow.api_connexion.security
|
||||
54 |
|
||||
55 | # airflow.api_connexion.security
|
||||
|
|
||||
= help: Use `sys.version_info` instead
|
||||
|
||||
AIR301_names.py:56:13: AIR301 `airflow.PY38` is removed in Airflow 3.0
|
||||
AIR301_names.py:53:13: AIR301 `airflow.PY38` is removed in Airflow 3.0
|
||||
|
|
||||
55 | # airflow root
|
||||
56 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
52 | # airflow root
|
||||
53 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
| ^^^^ AIR301
|
||||
57 |
|
||||
58 | # airflow.api_connexion.security
|
||||
54 |
|
||||
55 | # airflow.api_connexion.security
|
||||
|
|
||||
= help: Use `sys.version_info` instead
|
||||
|
||||
AIR301_names.py:56:19: AIR301 `airflow.PY39` is removed in Airflow 3.0
|
||||
AIR301_names.py:53:19: AIR301 `airflow.PY39` is removed in Airflow 3.0
|
||||
|
|
||||
55 | # airflow root
|
||||
56 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
52 | # airflow root
|
||||
53 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
| ^^^^ AIR301
|
||||
57 |
|
||||
58 | # airflow.api_connexion.security
|
||||
54 |
|
||||
55 | # airflow.api_connexion.security
|
||||
|
|
||||
= help: Use `sys.version_info` instead
|
||||
|
||||
AIR301_names.py:56:25: AIR301 `airflow.PY310` is removed in Airflow 3.0
|
||||
AIR301_names.py:53:25: AIR301 `airflow.PY310` is removed in Airflow 3.0
|
||||
|
|
||||
55 | # airflow root
|
||||
56 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
52 | # airflow root
|
||||
53 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
| ^^^^^ AIR301
|
||||
57 |
|
||||
58 | # airflow.api_connexion.security
|
||||
54 |
|
||||
55 | # airflow.api_connexion.security
|
||||
|
|
||||
= help: Use `sys.version_info` instead
|
||||
|
||||
AIR301_names.py:56:32: AIR301 `airflow.PY311` is removed in Airflow 3.0
|
||||
AIR301_names.py:53:32: AIR301 `airflow.PY311` is removed in Airflow 3.0
|
||||
|
|
||||
55 | # airflow root
|
||||
56 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
52 | # airflow root
|
||||
53 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
| ^^^^^ AIR301
|
||||
57 |
|
||||
58 | # airflow.api_connexion.security
|
||||
54 |
|
||||
55 | # airflow.api_connexion.security
|
||||
|
|
||||
= help: Use `sys.version_info` instead
|
||||
|
||||
AIR301_names.py:56:39: AIR301 `airflow.PY312` is removed in Airflow 3.0
|
||||
AIR301_names.py:53:39: AIR301 `airflow.PY312` is removed in Airflow 3.0
|
||||
|
|
||||
55 | # airflow root
|
||||
56 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
52 | # airflow root
|
||||
53 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
| ^^^^^ AIR301
|
||||
57 |
|
||||
58 | # airflow.api_connexion.security
|
||||
54 |
|
||||
55 | # airflow.api_connexion.security
|
||||
|
|
||||
= help: Use `sys.version_info` instead
|
||||
|
||||
AIR301_names.py:59:1: AIR301 `airflow.api_connexion.security.requires_access` is removed in Airflow 3.0
|
||||
AIR301_names.py:56:1: AIR301 `airflow.api_connexion.security.requires_access` is removed in Airflow 3.0
|
||||
|
|
||||
58 | # airflow.api_connexion.security
|
||||
59 | requires_access
|
||||
55 | # airflow.api_connexion.security
|
||||
56 | requires_access
|
||||
| ^^^^^^^^^^^^^^^ AIR301
|
||||
|
|
||||
= help: Use `airflow.api_connexion.security.requires_access_*` instead
|
||||
|
||||
AIR301_names.py:63:1: AIR301 `airflow.configuration.get` is removed in Airflow 3.0
|
||||
AIR301_names.py:60:1: AIR301 `airflow.configuration.get` is removed in Airflow 3.0
|
||||
|
|
||||
62 | # airflow.configuration
|
||||
63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
59 | # airflow.configuration
|
||||
60 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
| ^^^ AIR301
|
||||
|
|
||||
= help: Use `airflow.configuration.conf.get` instead
|
||||
|
||||
AIR301_names.py:63:6: AIR301 `airflow.configuration.getboolean` is removed in Airflow 3.0
|
||||
AIR301_names.py:60:6: AIR301 `airflow.configuration.getboolean` is removed in Airflow 3.0
|
||||
|
|
||||
62 | # airflow.configuration
|
||||
63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
59 | # airflow.configuration
|
||||
60 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
| ^^^^^^^^^^ AIR301
|
||||
|
|
||||
= help: Use `airflow.configuration.conf.getboolean` instead
|
||||
|
||||
AIR301_names.py:63:18: AIR301 `airflow.configuration.getfloat` is removed in Airflow 3.0
|
||||
AIR301_names.py:60:18: AIR301 `airflow.configuration.getfloat` is removed in Airflow 3.0
|
||||
|
|
||||
62 | # airflow.configuration
|
||||
63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
59 | # airflow.configuration
|
||||
60 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
| ^^^^^^^^ AIR301
|
||||
|
|
||||
= help: Use `airflow.configuration.conf.getfloat` instead
|
||||
|
||||
AIR301_names.py:63:28: AIR301 `airflow.configuration.getint` is removed in Airflow 3.0
|
||||
AIR301_names.py:60:28: AIR301 `airflow.configuration.getint` is removed in Airflow 3.0
|
||||
|
|
||||
62 | # airflow.configuration
|
||||
63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
59 | # airflow.configuration
|
||||
60 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
| ^^^^^^ AIR301
|
||||
|
|
||||
= help: Use `airflow.configuration.conf.getint` instead
|
||||
|
||||
AIR301_names.py:63:36: AIR301 `airflow.configuration.has_option` is removed in Airflow 3.0
|
||||
AIR301_names.py:60:36: AIR301 `airflow.configuration.has_option` is removed in Airflow 3.0
|
||||
|
|
||||
62 | # airflow.configuration
|
||||
63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
59 | # airflow.configuration
|
||||
60 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
| ^^^^^^^^^^ AIR301
|
||||
|
|
||||
= help: Use `airflow.configuration.conf.has_option` instead
|
||||
|
||||
AIR301_names.py:63:48: AIR301 `airflow.configuration.remove_option` is removed in Airflow 3.0
|
||||
AIR301_names.py:60:48: AIR301 `airflow.configuration.remove_option` is removed in Airflow 3.0
|
||||
|
|
||||
62 | # airflow.configuration
|
||||
63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
59 | # airflow.configuration
|
||||
60 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
| ^^^^^^^^^^^^^ AIR301
|
||||
|
|
||||
= help: Use `airflow.configuration.conf.remove_option` instead
|
||||
|
||||
AIR301_names.py:63:63: AIR301 `airflow.configuration.as_dict` is removed in Airflow 3.0
|
||||
AIR301_names.py:60:63: AIR301 `airflow.configuration.as_dict` is removed in Airflow 3.0
|
||||
|
|
||||
62 | # airflow.configuration
|
||||
63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
59 | # airflow.configuration
|
||||
60 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
| ^^^^^^^ AIR301
|
||||
|
|
||||
= help: Use `airflow.configuration.conf.as_dict` instead
|
||||
|
||||
AIR301_names.py:63:72: AIR301 `airflow.configuration.set` is removed in Airflow 3.0
|
||||
AIR301_names.py:60:72: AIR301 `airflow.configuration.set` is removed in Airflow 3.0
|
||||
|
|
||||
62 | # airflow.configuration
|
||||
63 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
59 | # airflow.configuration
|
||||
60 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
|
||||
| ^^^ AIR301
|
||||
|
|
||||
= help: Use `airflow.configuration.conf.set` instead
|
||||
|
||||
AIR301_names.py:67:1: AIR301 `airflow.contrib.aws_athena_hook.AWSAthenaHook` is removed in Airflow 3.0; The whole `airflow.contrib` module has been removed.
|
||||
AIR301_names.py:64:1: AIR301 `airflow.contrib.aws_athena_hook.AWSAthenaHook` is removed in Airflow 3.0
|
||||
|
|
||||
66 | # airflow.contrib.*
|
||||
67 | AWSAthenaHook()
|
||||
63 | # airflow.contrib.*
|
||||
64 | AWSAthenaHook()
|
||||
| ^^^^^^^^^^^^^ AIR301
|
||||
|
|
||||
= help: The whole `airflow.contrib` module has been removed.
|
||||
|
||||
AIR301_names.py:71:1: AIR301 `airflow.datasets.DatasetAliasEvent` is removed in Airflow 3.0
|
||||
AIR301_names.py:68:1: AIR301 `airflow.datasets.DatasetAliasEvent` is removed in Airflow 3.0
|
||||
|
|
||||
70 | # airflow.datasets
|
||||
71 | DatasetAliasEvent()
|
||||
67 | # airflow.datasets
|
||||
68 | DatasetAliasEvent()
|
||||
| ^^^^^^^^^^^^^^^^^ AIR301
|
||||
|
|
||||
|
||||
AIR301_names.py:75:1: AIR301 `airflow.hooks.base_hook.BaseHook` is removed in Airflow 3.0
|
||||
AIR301_names.py:72:1: AIR301 `airflow.hooks.base_hook.BaseHook` is removed in Airflow 3.0
|
||||
|
|
||||
74 | # airflow.hooks
|
||||
75 | BaseHook()
|
||||
71 | # airflow.hooks
|
||||
72 | BaseHook()
|
||||
| ^^^^^^^^ AIR301
|
||||
|
|
||||
= help: Use `airflow.hooks.base.BaseHook` instead
|
||||
|
||||
AIR301_names.py:79:1: AIR301 `airflow.operators.subdag.SubDagOperator` is removed in Airflow 3.0; The whole `airflow.subdag` module has been removed.
|
||||
AIR301_names.py:76:1: AIR301 `airflow.operators.subdag.SubDagOperator` is removed in Airflow 3.0
|
||||
|
|
||||
78 | # airflow.operators.subdag.*
|
||||
79 | SubDagOperator()
|
||||
75 | # airflow.operators.subdag.*
|
||||
76 | SubDagOperator()
|
||||
| ^^^^^^^^^^^^^^ AIR301
|
||||
80 |
|
||||
81 | # airflow.providers.mysql
|
||||
|
|
||||
= help: The whole `airflow.subdag` module has been removed.
|
||||
|
||||
AIR301_names.py:82:7: AIR301 `airflow.providers.mysql.datasets.mysql.sanitize_uri` is removed in Airflow 3.0
|
||||
AIR301_names.py:85:1: AIR301 `airflow.sensors.base_sensor_operator.BaseSensorOperator` is removed in Airflow 3.0
|
||||
|
|
||||
81 | # airflow.providers.mysql
|
||||
82 | mysql.sanitize_uri
|
||||
| ^^^^^^^^^^^^ AIR301
|
||||
83 |
|
||||
84 | # airflow.providers.postgres
|
||||
|
|
||||
= help: Use `airflow.providers.mysql.assets.mysql.sanitize_uri` instead
|
||||
|
||||
AIR301_names.py:85:10: AIR301 `airflow.providers.postgres.datasets.postgres.sanitize_uri` is removed in Airflow 3.0
|
||||
|
|
||||
84 | # airflow.providers.postgres
|
||||
85 | postgres.sanitize_uri
|
||||
| ^^^^^^^^^^^^ AIR301
|
||||
86 |
|
||||
87 | # airflow.providers.trino
|
||||
|
|
||||
= help: Use `airflow.providers.postgres.assets.postgres.sanitize_uri` instead
|
||||
|
||||
AIR301_names.py:88:7: AIR301 `airflow.providers.trino.datasets.trino.sanitize_uri` is removed in Airflow 3.0
|
||||
|
|
||||
87 | # airflow.providers.trino
|
||||
88 | trino.sanitize_uri
|
||||
| ^^^^^^^^^^^^ AIR301
|
||||
89 |
|
||||
90 | # airflow.secrets
|
||||
|
|
||||
= help: Use `airflow.providers.trino.assets.trino.sanitize_uri` instead
|
||||
|
||||
AIR301_names.py:96:1: AIR301 `airflow.sensors.base_sensor_operator.BaseSensorOperator` is removed in Airflow 3.0
|
||||
|
|
||||
95 | # airflow.sensors.base_sensor_operator
|
||||
96 | BaseSensorOperator()
|
||||
84 | # airflow.sensors.base_sensor_operator
|
||||
85 | BaseSensorOperator()
|
||||
| ^^^^^^^^^^^^^^^^^^ AIR301
|
||||
|
|
||||
= help: Use `airflow.sdk.bases.sensor.BaseSensorOperator` instead
|
||||
|
||||
AIR301_names.py:100:1: AIR301 `airflow.triggers.external_task.TaskStateTrigger` is removed in Airflow 3.0
|
||||
AIR301_names.py:89:1: AIR301 `airflow.triggers.external_task.TaskStateTrigger` is removed in Airflow 3.0
|
||||
|
|
||||
88 | # airflow.triggers.external_task
|
||||
89 | TaskStateTrigger()
|
||||
| ^^^^^^^^^^^^^^^^ AIR301
|
||||
90 |
|
||||
91 | # airflow.utils.date
|
||||
|
|
||||
|
||||
AIR301_names.py:92:7: AIR301 `airflow.utils.dates.date_range` is removed in Airflow 3.0
|
||||
|
|
||||
91 | # airflow.utils.date
|
||||
92 | dates.date_range
|
||||
| ^^^^^^^^^^ AIR301
|
||||
93 | dates.days_ago
|
||||
|
|
||||
|
||||
AIR301_names.py:93:7: AIR301 `airflow.utils.dates.days_ago` is removed in Airflow 3.0
|
||||
|
|
||||
91 | # airflow.utils.date
|
||||
92 | dates.date_range
|
||||
93 | dates.days_ago
|
||||
| ^^^^^^^^ AIR301
|
||||
94 |
|
||||
95 | date_range
|
||||
|
|
||||
= help: Use `pendulum.today('UTC').add(days=-N, ...)` instead
|
||||
|
||||
AIR301_names.py:95:1: AIR301 `airflow.utils.dates.date_range` is removed in Airflow 3.0
|
||||
|
|
||||
93 | dates.days_ago
|
||||
94 |
|
||||
95 | date_range
|
||||
| ^^^^^^^^^^ AIR301
|
||||
96 | days_ago
|
||||
97 | infer_time_unit
|
||||
|
|
||||
|
||||
AIR301_names.py:96:1: AIR301 `airflow.utils.dates.days_ago` is removed in Airflow 3.0
|
||||
|
|
||||
95 | date_range
|
||||
96 | days_ago
|
||||
| ^^^^^^^^ AIR301
|
||||
97 | infer_time_unit
|
||||
98 | parse_execution_date
|
||||
|
|
||||
= help: Use `pendulum.today('UTC').add(days=-N, ...)` instead
|
||||
|
||||
AIR301_names.py:97:1: AIR301 `airflow.utils.dates.infer_time_unit` is removed in Airflow 3.0
|
||||
|
|
||||
95 | date_range
|
||||
96 | days_ago
|
||||
97 | infer_time_unit
|
||||
| ^^^^^^^^^^^^^^^ AIR301
|
||||
98 | parse_execution_date
|
||||
99 | round_time
|
||||
|
|
||||
|
||||
AIR301_names.py:98:1: AIR301 `airflow.utils.dates.parse_execution_date` is removed in Airflow 3.0
|
||||
|
|
||||
99 | # airflow.triggers.external_task
|
||||
100 | TaskStateTrigger()
|
||||
96 | days_ago
|
||||
97 | infer_time_unit
|
||||
98 | parse_execution_date
|
||||
| ^^^^^^^^^^^^^^^^^^^^ AIR301
|
||||
99 | round_time
|
||||
100 | scale_time_units
|
||||
|
|
||||
|
||||
AIR301_names.py:99:1: AIR301 `airflow.utils.dates.round_time` is removed in Airflow 3.0
|
||||
|
|
||||
97 | infer_time_unit
|
||||
98 | parse_execution_date
|
||||
99 | round_time
|
||||
| ^^^^^^^^^^ AIR301
|
||||
100 | scale_time_units
|
||||
|
|
||||
|
||||
AIR301_names.py:100:1: AIR301 `airflow.utils.dates.scale_time_units` is removed in Airflow 3.0
|
||||
|
|
||||
98 | parse_execution_date
|
||||
99 | round_time
|
||||
100 | scale_time_units
|
||||
| ^^^^^^^^^^^^^^^^ AIR301
|
||||
101 |
|
||||
102 | # airflow.utils.date
|
||||
102 | # This one was not deprecated.
|
||||
|
|
||||
|
||||
AIR301_names.py:103:7: AIR301 `airflow.utils.dates.date_range` is removed in Airflow 3.0
|
||||
AIR301_names.py:107:1: AIR301 `airflow.utils.dag_cycle_tester.test_cycle` is removed in Airflow 3.0
|
||||
|
|
||||
102 | # airflow.utils.date
|
||||
103 | dates.date_range
|
||||
| ^^^^^^^^^^ AIR301
|
||||
104 | dates.days_ago
|
||||
|
|
||||
|
||||
AIR301_names.py:104:7: AIR301 `airflow.utils.dates.days_ago` is removed in Airflow 3.0
|
||||
|
|
||||
102 | # airflow.utils.date
|
||||
103 | dates.date_range
|
||||
104 | dates.days_ago
|
||||
| ^^^^^^^^ AIR301
|
||||
105 |
|
||||
106 | date_range
|
||||
|
|
||||
= help: Use `pendulum.today('UTC').add(days=-N, ...)` instead
|
||||
|
||||
AIR301_names.py:106:1: AIR301 `airflow.utils.dates.date_range` is removed in Airflow 3.0
|
||||
|
|
||||
104 | dates.days_ago
|
||||
105 |
|
||||
106 | date_range
|
||||
106 | # airflow.utils.dag_cycle_tester
|
||||
107 | test_cycle
|
||||
| ^^^^^^^^^^ AIR301
|
||||
107 | days_ago
|
||||
108 | infer_time_unit
|
||||
|
|
||||
|
||||
AIR301_names.py:107:1: AIR301 `airflow.utils.dates.days_ago` is removed in Airflow 3.0
|
||||
AIR301_names.py:111:1: AIR301 `airflow.utils.db.create_session` is removed in Airflow 3.0
|
||||
|
|
||||
106 | date_range
|
||||
107 | days_ago
|
||||
| ^^^^^^^^ AIR301
|
||||
108 | infer_time_unit
|
||||
109 | parse_execution_date
|
||||
|
|
||||
= help: Use `pendulum.today('UTC').add(days=-N, ...)` instead
|
||||
|
||||
AIR301_names.py:108:1: AIR301 `airflow.utils.dates.infer_time_unit` is removed in Airflow 3.0
|
||||
|
|
||||
106 | date_range
|
||||
107 | days_ago
|
||||
108 | infer_time_unit
|
||||
| ^^^^^^^^^^^^^^^ AIR301
|
||||
109 | parse_execution_date
|
||||
110 | round_time
|
||||
|
|
||||
|
||||
AIR301_names.py:109:1: AIR301 `airflow.utils.dates.parse_execution_date` is removed in Airflow 3.0
|
||||
|
|
||||
107 | days_ago
|
||||
108 | infer_time_unit
|
||||
109 | parse_execution_date
|
||||
| ^^^^^^^^^^^^^^^^^^^^ AIR301
|
||||
110 | round_time
|
||||
111 | scale_time_units
|
||||
|
|
||||
|
||||
AIR301_names.py:110:1: AIR301 `airflow.utils.dates.round_time` is removed in Airflow 3.0
|
||||
|
|
||||
108 | infer_time_unit
|
||||
109 | parse_execution_date
|
||||
110 | round_time
|
||||
| ^^^^^^^^^^ AIR301
|
||||
111 | scale_time_units
|
||||
|
|
||||
|
||||
AIR301_names.py:111:1: AIR301 `airflow.utils.dates.scale_time_units` is removed in Airflow 3.0
|
||||
|
|
||||
109 | parse_execution_date
|
||||
110 | round_time
|
||||
111 | scale_time_units
|
||||
| ^^^^^^^^^^^^^^^^ AIR301
|
||||
110 | # airflow.utils.db
|
||||
111 | create_session
|
||||
| ^^^^^^^^^^^^^^ AIR301
|
||||
112 |
|
||||
113 | # This one was not deprecated.
|
||||
113 | # airflow.utils.decorators
|
||||
|
|
||||
|
||||
AIR301_names.py:118:1: AIR301 `airflow.utils.dag_cycle_tester.test_cycle` is removed in Airflow 3.0
|
||||
AIR301_names.py:114:1: AIR301 `airflow.utils.decorators.apply_defaults` is removed in Airflow 3.0
|
||||
|
|
||||
117 | # airflow.utils.dag_cycle_tester
|
||||
118 | test_cycle
|
||||
| ^^^^^^^^^^ AIR301
|
||||
|
|
||||
|
||||
AIR301_names.py:122:1: AIR301 `airflow.utils.db.create_session` is removed in Airflow 3.0
|
||||
|
|
||||
121 | # airflow.utils.db
|
||||
122 | create_session
|
||||
113 | # airflow.utils.decorators
|
||||
114 | apply_defaults
|
||||
| ^^^^^^^^^^^^^^ AIR301
|
||||
123 |
|
||||
124 | # airflow.utils.decorators
|
||||
115 |
|
||||
116 | # airflow.utils.file
|
||||
|
|
||||
= help: `apply_defaults` is now unconditionally done and can be safely removed.
|
||||
|
||||
AIR301_names.py:125:1: AIR301 `airflow.utils.decorators.apply_defaults` is removed in Airflow 3.0; `apply_defaults` is now unconditionally done and can be safely removed.
|
||||
AIR301_names.py:117:1: AIR301 `airflow.utils.file.TemporaryDirectory` is removed in Airflow 3.0
|
||||
|
|
||||
124 | # airflow.utils.decorators
|
||||
125 | apply_defaults
|
||||
| ^^^^^^^^^^^^^^ AIR301
|
||||
126 |
|
||||
127 | # airflow.utils.file
|
||||
|
|
||||
|
||||
AIR301_names.py:128:1: AIR301 `airflow.utils.file.TemporaryDirectory` is removed in Airflow 3.0
|
||||
|
|
||||
127 | # airflow.utils.file
|
||||
128 | TemporaryDirectory()
|
||||
116 | # airflow.utils.file
|
||||
117 | TemporaryDirectory()
|
||||
| ^^^^^^^^^^^^^^^^^^ AIR301
|
||||
129 | mkdirs
|
||||
118 | mkdirs
|
||||
|
|
||||
= help: Use `tempfile.TemporaryDirectory` instead
|
||||
|
||||
AIR301_names.py:129:1: AIR301 `airflow.utils.file.mkdirs` is removed in Airflow 3.0
|
||||
AIR301_names.py:118:1: AIR301 `airflow.utils.file.mkdirs` is removed in Airflow 3.0
|
||||
|
|
||||
127 | # airflow.utils.file
|
||||
128 | TemporaryDirectory()
|
||||
129 | mkdirs
|
||||
116 | # airflow.utils.file
|
||||
117 | TemporaryDirectory()
|
||||
118 | mkdirs
|
||||
| ^^^^^^ AIR301
|
||||
130 |
|
||||
131 | # airflow.utils.helpers
|
||||
119 |
|
||||
120 | # airflow.utils.helpers
|
||||
|
|
||||
= help: Use `pathlib.Path({path}).mkdir` instead
|
||||
|
||||
AIR301_names.py:132:1: AIR301 `airflow.utils.helpers.chain` is removed in Airflow 3.0
|
||||
AIR301_names.py:121:1: AIR301 [*] `airflow.utils.helpers.chain` is removed in Airflow 3.0
|
||||
|
|
||||
131 | # airflow.utils.helpers
|
||||
132 | helper_chain
|
||||
120 | # airflow.utils.helpers
|
||||
121 | helper_chain
|
||||
| ^^^^^^^^^^^^ AIR301
|
||||
133 | helper_cross_downstream
|
||||
122 | helper_cross_downstream
|
||||
|
|
||||
= help: Use `airflow.sdk.chain` instead
|
||||
|
||||
AIR301_names.py:133:1: AIR301 `airflow.utils.helpers.cross_downstream` is removed in Airflow 3.0
|
||||
ℹ Safe fix
|
||||
48 48 | from airflow.utils.trigger_rule import TriggerRule
|
||||
49 49 | from airflow.www.auth import has_access
|
||||
50 50 | from airflow.www.utils import get_sensitive_variables_fields, should_hide_value_for_key
|
||||
51 |+from airflow.sdk import chain
|
||||
51 52 |
|
||||
52 53 | # airflow root
|
||||
53 54 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
--------------------------------------------------------------------------------
|
||||
118 119 | mkdirs
|
||||
119 120 |
|
||||
120 121 | # airflow.utils.helpers
|
||||
121 |-helper_chain
|
||||
122 |+chain
|
||||
122 123 | helper_cross_downstream
|
||||
123 124 |
|
||||
124 125 | # airflow.utils.log
|
||||
|
||||
AIR301_names.py:122:1: AIR301 [*] `airflow.utils.helpers.cross_downstream` is removed in Airflow 3.0
|
||||
|
|
||||
131 | # airflow.utils.helpers
|
||||
132 | helper_chain
|
||||
133 | helper_cross_downstream
|
||||
120 | # airflow.utils.helpers
|
||||
121 | helper_chain
|
||||
122 | helper_cross_downstream
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ AIR301
|
||||
134 |
|
||||
135 | # airflow.utils.log
|
||||
123 |
|
||||
124 | # airflow.utils.log
|
||||
|
|
||||
= help: Use `airflow.sdk.cross_downstream` instead
|
||||
|
||||
AIR301_names.py:136:1: AIR301 `airflow.utils.log.secrets_masker` is removed in Airflow 3.0
|
||||
ℹ Safe fix
|
||||
48 48 | from airflow.utils.trigger_rule import TriggerRule
|
||||
49 49 | from airflow.www.auth import has_access
|
||||
50 50 | from airflow.www.utils import get_sensitive_variables_fields, should_hide_value_for_key
|
||||
51 |+from airflow.sdk import cross_downstream
|
||||
51 52 |
|
||||
52 53 | # airflow root
|
||||
53 54 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
|
||||
--------------------------------------------------------------------------------
|
||||
119 120 |
|
||||
120 121 | # airflow.utils.helpers
|
||||
121 122 | helper_chain
|
||||
122 |-helper_cross_downstream
|
||||
123 |+cross_downstream
|
||||
123 124 |
|
||||
124 125 | # airflow.utils.log
|
||||
125 126 | secrets_masker
|
||||
|
||||
AIR301_names.py:125:1: AIR301 `airflow.utils.log.secrets_masker` is removed in Airflow 3.0
|
||||
|
|
||||
135 | # airflow.utils.log
|
||||
136 | secrets_masker
|
||||
124 | # airflow.utils.log
|
||||
125 | secrets_masker
|
||||
| ^^^^^^^^^^^^^^ AIR301
|
||||
137 |
|
||||
138 | # airflow.utils.state
|
||||
126 |
|
||||
127 | # airflow.utils.state
|
||||
|
|
||||
= help: Use `airflow.sdk.execution_time.secrets_masker` instead
|
||||
|
||||
AIR301_names.py:139:1: AIR301 `airflow.utils.state.SHUTDOWN` is removed in Airflow 3.0
|
||||
AIR301_names.py:128:1: AIR301 `airflow.utils.state.SHUTDOWN` is removed in Airflow 3.0
|
||||
|
|
||||
138 | # airflow.utils.state
|
||||
139 | SHUTDOWN
|
||||
127 | # airflow.utils.state
|
||||
128 | SHUTDOWN
|
||||
| ^^^^^^^^ AIR301
|
||||
140 | terminating_states
|
||||
129 | terminating_states
|
||||
|
|
||||
|
||||
AIR301_names.py:140:1: AIR301 `airflow.utils.state.terminating_states` is removed in Airflow 3.0
|
||||
AIR301_names.py:129:1: AIR301 `airflow.utils.state.terminating_states` is removed in Airflow 3.0
|
||||
|
|
||||
138 | # airflow.utils.state
|
||||
139 | SHUTDOWN
|
||||
140 | terminating_states
|
||||
127 | # airflow.utils.state
|
||||
128 | SHUTDOWN
|
||||
129 | terminating_states
|
||||
| ^^^^^^^^^^^^^^^^^^ AIR301
|
||||
141 |
|
||||
142 | # airflow.utils.trigger_rule
|
||||
130 |
|
||||
131 | # airflow.utils.trigger_rule
|
||||
|
|
||||
|
||||
AIR301_names.py:143:13: AIR301 `airflow.utils.trigger_rule.TriggerRule.DUMMY` is removed in Airflow 3.0
|
||||
AIR301_names.py:132:13: AIR301 `airflow.utils.trigger_rule.TriggerRule.DUMMY` is removed in Airflow 3.0
|
||||
|
|
||||
142 | # airflow.utils.trigger_rule
|
||||
143 | TriggerRule.DUMMY
|
||||
131 | # airflow.utils.trigger_rule
|
||||
132 | TriggerRule.DUMMY
|
||||
| ^^^^^ AIR301
|
||||
144 | TriggerRule.NONE_FAILED_OR_SKIPPED
|
||||
133 | TriggerRule.NONE_FAILED_OR_SKIPPED
|
||||
|
|
||||
|
||||
AIR301_names.py:144:13: AIR301 `airflow.utils.trigger_rule.TriggerRule.NONE_FAILED_OR_SKIPPED` is removed in Airflow 3.0
|
||||
AIR301_names.py:133:13: AIR301 `airflow.utils.trigger_rule.TriggerRule.NONE_FAILED_OR_SKIPPED` is removed in Airflow 3.0
|
||||
|
|
||||
142 | # airflow.utils.trigger_rule
|
||||
143 | TriggerRule.DUMMY
|
||||
144 | TriggerRule.NONE_FAILED_OR_SKIPPED
|
||||
131 | # airflow.utils.trigger_rule
|
||||
132 | TriggerRule.DUMMY
|
||||
133 | TriggerRule.NONE_FAILED_OR_SKIPPED
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ AIR301
|
||||
|
|
||||
|
||||
AIR301_names.py:148:1: AIR301 `airflow.www.auth.has_access` is removed in Airflow 3.0
|
||||
AIR301_names.py:137:1: AIR301 `airflow.www.auth.has_access` is removed in Airflow 3.0
|
||||
|
|
||||
147 | # airflow.www.auth
|
||||
148 | has_access
|
||||
136 | # airflow.www.auth
|
||||
137 | has_access
|
||||
| ^^^^^^^^^^ AIR301
|
||||
149 |
|
||||
150 | # airflow.www.utils
|
||||
138 |
|
||||
139 | # airflow.www.utils
|
||||
|
|
||||
= help: Use `airflow.www.auth.has_access_*` instead
|
||||
|
||||
AIR301_names.py:151:1: AIR301 `airflow.www.utils.get_sensitive_variables_fields` is removed in Airflow 3.0
|
||||
AIR301_names.py:140:1: AIR301 `airflow.www.utils.get_sensitive_variables_fields` is removed in Airflow 3.0
|
||||
|
|
||||
150 | # airflow.www.utils
|
||||
151 | get_sensitive_variables_fields
|
||||
139 | # airflow.www.utils
|
||||
140 | get_sensitive_variables_fields
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301
|
||||
152 | should_hide_value_for_key
|
||||
141 | should_hide_value_for_key
|
||||
|
|
||||
= help: Use `airflow.utils.log.secrets_masker.get_sensitive_variables_fields` instead
|
||||
|
||||
AIR301_names.py:152:1: AIR301 `airflow.www.utils.should_hide_value_for_key` is removed in Airflow 3.0
|
||||
AIR301_names.py:141:1: AIR301 `airflow.www.utils.should_hide_value_for_key` is removed in Airflow 3.0
|
||||
|
|
||||
150 | # airflow.www.utils
|
||||
151 | get_sensitive_variables_fields
|
||||
152 | should_hide_value_for_key
|
||||
139 | # airflow.www.utils
|
||||
140 | get_sensitive_variables_fields
|
||||
141 | should_hide_value_for_key
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301
|
||||
153 |
|
||||
154 | # airflow.operators.python
|
||||
142 |
|
||||
143 | # airflow.operators.python
|
||||
|
|
||||
= help: Use `airflow.utils.log.secrets_masker.should_hide_value_for_key` instead
|
||||
|
||||
AIR301_names.py:157:1: AIR301 `airflow.operators.python.get_current_context` is removed in Airflow 3.0
|
||||
AIR301_names.py:146:1: AIR301 `airflow.operators.python.get_current_context` is removed in Airflow 3.0
|
||||
|
|
||||
155 | from airflow.operators.python import get_current_context
|
||||
156 |
|
||||
157 | get_current_context()
|
||||
144 | from airflow.operators.python import get_current_context
|
||||
145 |
|
||||
146 | get_current_context()
|
||||
| ^^^^^^^^^^^^^^^^^^^ AIR301
|
||||
147 |
|
||||
148 | # airflow.providers.mysql
|
||||
|
|
||||
= help: Use `airflow.sdk.get_current_context` instead
|
||||
|
||||
AIR301_names.py:151:1: AIR301 `airflow.providers.mysql.datasets.mysql.sanitize_uri` is removed in Airflow 3.0
|
||||
|
|
||||
149 | from airflow.providers.mysql.datasets.mysql import sanitize_uri
|
||||
150 |
|
||||
151 | sanitize_uri
|
||||
| ^^^^^^^^^^^^ AIR301
|
||||
152 |
|
||||
153 | # airflow.providers.postgres
|
||||
|
|
||||
= help: Use `airflow.providers.mysql.assets.mysql.sanitize_uri` instead
|
||||
|
||||
AIR301_names.py:156:1: AIR301 `airflow.providers.postgres.datasets.postgres.sanitize_uri` is removed in Airflow 3.0
|
||||
|
|
||||
154 | from airflow.providers.postgres.datasets.postgres import sanitize_uri
|
||||
155 |
|
||||
156 | sanitize_uri
|
||||
| ^^^^^^^^^^^^ AIR301
|
||||
157 |
|
||||
158 | # airflow.providers.trino
|
||||
|
|
||||
= help: Use `airflow.providers.postgres.assets.postgres.sanitize_uri` instead
|
||||
|
||||
AIR301_names.py:161:1: AIR301 `airflow.providers.trino.datasets.trino.sanitize_uri` is removed in Airflow 3.0
|
||||
|
|
||||
159 | from airflow.providers.trino.datasets.trino import sanitize_uri
|
||||
160 |
|
||||
161 | sanitize_uri
|
||||
| ^^^^^^^^^^^^ AIR301
|
||||
|
|
||||
= help: Use `airflow.providers.trino.assets.trino.sanitize_uri` instead
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue