[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:
Wei Lee 2025-05-14 23:10:15 +08:00 committed by GitHub
parent 1e4377c9c6
commit 2e94d37275
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 443 additions and 360 deletions

View file

@ -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

View file

@ -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,

View file

@ -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,
},
},

View file

@ -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,
},
},

View file

@ -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.

View file

@ -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

View file

@ -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