Skip to content

Commit

Permalink
refactor(AIR302): refactor regex usage
Browse files Browse the repository at this point in the history
  • Loading branch information
Lee-W committed Dec 25, 2024
1 parent e179b0a commit cbde476
Show file tree
Hide file tree
Showing 6 changed files with 330 additions and 294 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from airflow.datasets.manager import DatasetManager
from airflow.lineage.hook import DatasetLineageInfo, HookLineageCollector
from airflow.providers.amazon.auth_manager.aws_auth_manager import AwsAuthManager
from airflow.providers.apache.beam.hooks import BeamHook, NotAir302HookError
from airflow.providers.google.cloud.secrets.secret_manager import (
CloudSecretManagerBackend,
)
from airflow.providers.hashicorp.secrets.vault import NotAir302SecretError, VaultBackend
from airflow.providers_manager import ProvidersManager
from airflow.secrets.base_secrets import BaseSecretsBackend

dm = DatasetManager()
dm.register_dataset_change()
dm.create_datasets()
dm.notify_dataset_created()
dm.notify_dataset_changed()
dm.notify_dataset_alias_created()

hlc = HookLineageCollector()
hlc.create_dataset()
hlc.add_input_dataset()
hlc.add_output_dataset()
hlc.collected_datasets()

aam = AwsAuthManager()
aam.is_authorized_dataset()

pm = ProvidersManager()
pm.initialize_providers_asset_uri_resources()
pm.dataset_factories

base_secret_backend = BaseSecretsBackend()
base_secret_backend.get_conn_uri()
base_secret_backend.get_connections()

csm_backend = CloudSecretManagerBackend()
csm_backend.get_conn_uri()
csm_backend.get_connections()

vault_backend = VaultBackend()
vault_backend.get_conn_uri()
vault_backend.get_connections()

not_an_error = NotAir302SecretError()
not_an_error.get_conn_uri()

beam_hook = BeamHook()
beam_hook.get_conn_uri()

not_an_error = NotAir302HookError()
not_an_error.get_conn_uri()

provider_manager = ProvidersManager()
provider_manager.dataset_factories
provider_manager.dataset_uri_handlers
provider_manager.dataset_to_openlineage_converters

dl_info = DatasetLineageInfo()
dl_info.dataset
65 changes: 0 additions & 65 deletions crates/ruff_linter/resources/test/fixtures/airflow/AIR302_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,68 +269,3 @@

# airflow.www.utils
get_sensitive_variables_fields, should_hide_value_for_key


# methods

from airflow.datasets.manager import DatasetManager

dm = DatasetManager()
dm.register_dataset_change()
dm.create_datasets()
dm.notify_dataset_created()
dm.notify_dataset_changed()
dm.notify_dataset_alias_created()


from airflow.lineage.hook import HookLineageCollector

hlc = HookLineageCollector()
hlc.create_dataset()
hlc.add_input_dataset()
hlc.add_output_dataset()
hlc.collected_datasets()

from airflow.providers.amazon.auth_manager.aws_auth_manager import AwsAuthManager

aam = AwsAuthManager()
aam.is_authorized_dataset()

from airflow.providers_manager import ProvidersManager

pm = ProvidersManager()
pm.initialize_providers_asset_uri_resources()
pm.dataset_factories


from airflow.secrets.base_secrets import BaseSecretsBackend

base_secret_backend = BaseSecretsBackend()
base_secret_backend.get_conn_uri()
base_secret_backend.get_connections()

from airflow.providers.google.cloud.secrets.secret_manager import (
CloudSecretManagerBackend,
)

csm_backend = CloudSecretManagerBackend()
csm_backend.get_conn_uri()
csm_backend.get_connections()

from airflow.providers.hashicorp.secrets.vault import VaultBackend

vault_backend = VaultBackend()
vault_backend.get_conn_uri()
vault_backend.get_connections()

from airflow.providers_manager import ProvidersManager

provider_manager = ProvidersManager()
provider_manager.dataset_factories
provider_manager.dataset_uri_handlers
provider_manager.dataset_to_openlineage_converters

from airflow.lineage.hook import DatasetLineageInfo

dl_info = DatasetLineageInfo()
dl_info.dataset
1 change: 1 addition & 0 deletions crates/ruff_linter/src/rules/airflow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod tests {
#[test_case(Rule::AirflowDagNoScheduleArgument, Path::new("AIR301.py"))]
#[test_case(Rule::Airflow3Removal, Path::new("AIR302_args.py"))]
#[test_case(Rule::Airflow3Removal, Path::new("AIR302_names.py"))]
#[test_case(Rule::Airflow3Removal, Path::new("AIR302_class_attribute.py"))]
#[test_case(Rule::Airflow3MovedToProvider, Path::new("AIR303.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
Expand Down
66 changes: 50 additions & 16 deletions crates/ruff_linter/src/rules/airflow/rules/removal_in_3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,58 @@ use ruff_python_ast::{name::QualifiedName, Arguments, Expr, ExprAttribute, ExprC
use ruff_python_semantic::analyze::typing;
use ruff_python_semantic::Modules;
use ruff_text_size::Ranged;
use std::sync::LazyLock;

use crate::checkers::ast::Checker;
use regex::Regex;

static SECRET_BACKEND_REGEX: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"airflow\..*secrets\.\w+\.\w+Backend").unwrap());
fn is_airflow_secret_backend(qualname: &QualifiedName) -> bool {
match qualname.segments() {
["airflow", "secrets", rest @ ..] => {
if let Some(last_element) = rest.last() {
last_element.ends_with("Backend")
} else {
false
}
}

["airflow", "providers", rest @ ..] => {
// Ensure 'operators' exists somewhere in the middle
if let (Some(pos), Some(last_element)) =
(rest.iter().position(|&s| s == "secrets"), rest.last())
{
pos + 1 < rest.len() && last_element.ends_with("Backend") // Check that 'operators' is not the last element
} else {
false
}
}

static AIRFLOW_HOOK_REGEX: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"airflow\..*hooks\.\w+\.\w+Hook").unwrap());
_ => false,
}
}

fn is_airflow_hook(qualname: &QualifiedName) -> bool {
match qualname.segments() {
["airflow", "hooks", rest @ ..] => {
if let Some(last_element) = rest.last() {
last_element.ends_with("Hook")
} else {
false
}
}

["airflow", "providers", rest @ ..] => {
// Ensure 'operators' exists somewhere in the middle
if let (Some(pos), Some(last_element)) =
(rest.iter().position(|&s| s == "hooks"), rest.last())
{
pos + 1 < rest.len() && last_element.ends_with("Hook")
} else {
false
}
}

_ => false,
}
}

#[derive(Debug, Eq, PartialEq)]
enum Replacement {
Expand Down Expand Up @@ -172,14 +214,6 @@ fn removed_class_attribute(checker: &mut Checker, expr: &Expr) {
return;
};

// checker.diagnostics.push(Diagnostic::new(
// Airflow3Removal {
// deprecated: qualname.to_string(),
// replacement: Replacement::Name("te"),
// },
// attr.range(),
// ));

let replacement = match *qualname.segments() {
["airflow", "providers_manager", "ProvidersManager"] => match attr.as_str() {
"dataset_factories" => Some(Replacement::Name("asset_factories")),
Expand Down Expand Up @@ -252,12 +286,12 @@ fn removed_method(checker: &mut Checker, expr: &Expr) {
"iter_dataset_aliases" => Some(Replacement::Name("iter_asset_aliases")),
&_ => None,
},
_ if SECRET_BACKEND_REGEX.is_match(&qualname.segments().join(".")) => match attr.as_str() {
_ if is_airflow_secret_backend(&qualname) => match attr.as_str() {
"get_conn_uri" => Some(Replacement::Name("get_conn_value")),
"get_connections" => Some(Replacement::Name("get_connection")),
&_ => None,
},
_ if AIRFLOW_HOOK_REGEX.is_match(&qualname.segments().join(".")) => match attr.as_str() {
_ if is_airflow_hook(&qualname) => match attr.as_str() {
"get_connections" => Some(Replacement::Name("get_connection")),
&_ => None,
},
Expand Down
Loading

0 comments on commit cbde476

Please sign in to comment.