feat(AIR302): extend the following rules (#15015)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions

## Summary


Airflow 3.0 removes various deprecated functions, members, modules, and
other values. They have been deprecated in 2.x, but the removal causes
incompatibilities that we want to detect. This PR deprecates the
following names.

* `airflow.api_connexion.security.requires_access_dataset` →
`airflow.api_connexion.security.requires_access_asset`
* `airflow.auth.managers.base_auth_manager.is_authorized_dataset` →
`airflow.auth.managers.base_auth_manager.is_authorized_asset`
* `airflow.auth.managers.models.resource_details.DatasetDetails` →
`airflow.auth.managers.models.resource_details.AssetDetails`
* `airflow.lineage.hook.DatasetLineageInfo` →
`airflow.lineage.hook.AssetLineageInfo`
* `airflow.security.permissions.RESOURCE_DATASET` →
`airflow.security.permissions.RESOURCE_ASSET`
* `airflow.www.auth.has_access_dataset` →
`airflow.www.auth.has_access_dataset.has_access_asset`
* remove `airflow.datasets.DatasetAliasEvent`
* `airflow.datasets.Dataset` → `airflow.sdk.definitions.asset.Asset`
* `airflow.Dataset` → `airflow.sdk.definitions.asset.Asset`
* `airflow.datasets.DatasetAlias` →
`airflow.sdk.definitions.asset.AssetAlias`
* `airflow.datasets.DatasetAll` →
`airflow.sdk.definitions.asset.AssetAll`
* `airflow.datasets.DatasetAny` →
`airflow.sdk.definitions.asset.AssetAny`
* `airflow.datasets.metadata` → `airflow.sdk.definitions.asset.metadata`
* `airflow.datasets.expand_alias_to_datasets` →
`airflow.sdk.definitions.asset.expand_alias_to_assets`
* `airflow.datasets.manager.dataset_manager` → `airflow.assets.manager`
* `airflow.datasets.manager.resolve_dataset_manager` →
`airflow.assets.resolve_asset_manager`
* `airflow.datasets.manager.DatasetManager` →
`airflow.assets.AssetManager`
* `airflow.listeners.spec.dataset.on_dataset_created` →
`airflow.listeners.spec.asset.on_asset_created`
* `airflow.listeners.spec.dataset.on_dataset_changed` →
`airflow.listeners.spec.asset.on_asset_changed`
* `airflow.timetables.simple.DatasetTriggeredTimetable` →
`airflow.timetables.simple.AssetTriggeredTimetable`
* `airflow.timetables.datasets.DatasetOrTimeSchedule` →
`airflow.timetables.assets.AssetOrTimeSchedule`
*
`airflow.providers.amazon.auth_manager.avp.entities.AvpEntities.DATASET`
→ `airflow.providers.amazon.auth_manager.avp.entities.AvpEntities.ASSET`
* `airflow.providers.amazon.aws.datasets.s3.create_dataset` →
`airflow.providers.amazon.aws.assets.s3.create_asset`
*
`airflow.providers.amazon.aws.datasets.s3.convert_dataset_to_openlineage`
→
`airflow.providers.amazon.aws.datasets.s3.convert_dataset_to_openlineage`
* `airflow.providers.amazon.aws.datasets.s3.sanitize_uri` →
`airflow.providers.amazon.aws.assets.s3.sanitize_uri`
*
`airflow.providers.common.io.datasets.file.convert_dataset_to_openlineage`
→ `airflow.providers.common.io.assets.file.convert_asset_to_openlineage`
* `airflow.providers.common.io.datasets.file.sanitize_uri` →
`airflow.providers.common.io.assets.file.sanitize_uri`
* `airflow.providers.common.io.datasets.file.create_dataset` →
`airflow.providers.common.io.assets.file.create_asset`
* `airflow.providers.google.datasets.bigquery.sanitize_uri` →
`airflow.providers.google.assets.bigquery.sanitize_uri`
* `airflow.providers.google.datasets.gcs.create_dataset` →
`airflow.providers.google.assets.gcs.create_asset`
* `airflow.providers.google.datasets.gcs.sanitize_uri` →
`airflow.providers.google.assets.gcs.sanitize_uri`
* `airflow.providers.google.datasets.gcs.convert_dataset_to_openlineage`
→ `airflow.providers.google.assets.gcs.convert_asset_to_openlineage`
*
`airflow.providers.fab.auth_manager.fab_auth_manager.is_authorized_dataset`
→
`airflow.providers.fab.auth_manager.fab_auth_manager.is_authorized_asset`
* `airflow.providers.openlineage.utils.utils.DatasetInfo` →
`airflow.providers.openlineage.utils.utils.AssetInfo`
* `airflow.providers.openlineage.utils.utils.translate_airflow_dataset`
→ `airflow.providers.openlineage.utils.utils.translate_airflow_asset`
* `airflow.providers.postgres.datasets.postgres.sanitize_uri` →
`airflow.providers.postgres.assets.postgres.sanitize_uri`
* `airflow.providers.mysql.datasets.mysql.sanitize_uri` →
`airflow.providers.mysql.assets.mysql.sanitize_uri`
* `airflow.providers.trino.datasets.trino.sanitize_uri` →
`airflow.providers.trino.assets.trino.sanitize_uri`

In additional to the newly added rules above, the message for
`airflow.contrib.*` and `airflow.subdag.*` has been extended,
`airflow.sensors.external_task.ExternalTaskSensorLink` error has been
fixed and the test fixture has been reorganized

## Test Plan

A test fixture is included in the PR.
This commit is contained in:
Wei Lee 2024-12-17 16:32:48 +09:00 committed by GitHub
parent e22718f25f
commit 867a8f9497
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 1191 additions and 550 deletions

View file

@ -1,36 +1,80 @@
from airflow import PY36, PY37, PY38, PY39, PY310, PY311, PY312
from airflow.triggers.external_task import TaskStateTrigger
from airflow.api_connexion.security import requires_access
from airflow import (
PY36,
PY37,
PY38,
PY39,
PY310,
PY311,
PY312,
Dataset as DatasetFromRoot,
)
from airflow.api_connexion.security import requires_access, requires_access_dataset
from airflow.auth.managers.base_auth_manager import is_authorized_dataset
from airflow.auth.managers.models.resource_details import DatasetDetails
from airflow.configuration import (
as_dict,
get,
getboolean,
getfloat,
getint,
has_option,
remove_option,
as_dict,
set,
)
from airflow.contrib.aws_athena_hook import AWSAthenaHook
from airflow.metrics.validators import AllowListValidator
from airflow.metrics.validators import BlockListValidator
from airflow.operators.subdag import SubDagOperator
from airflow.sensors.external_task import ExternalTaskSensorLink
from airflow.datasets import (
Dataset,
DatasetAlias,
DatasetAliasEvent,
DatasetAll,
DatasetAny,
expand_alias_to_datasets,
)
from airflow.datasets.metadata import Metadata
from airflow.datasets.manager import (
DatasetManager,
dataset_manager,
resolve_dataset_manager,
)
from airflow.lineage.hook import DatasetLineageInfo
from airflow.listeners.spec.dataset import on_dataset_changed, on_dataset_created
from airflow.metrics.validators import AllowListValidator, BlockListValidator
from airflow.operators import dummy_operator
from airflow.operators.bash_operator import BashOperator
from airflow.operators.branch_operator import BaseBranchOperator
from airflow.operators.dummy import EmptyOperator, DummyOperator
from airflow.operators import dummy_operator
from airflow.operators.dummy import DummyOperator, EmptyOperator
from airflow.operators.email_operator import EmailOperator
from airflow.operators.subdag import SubDagOperator
from airflow.providers.amazon.auth_manager.avp.entities import AvpEntities
from airflow.providers.amazon.aws.datasets import s3
from airflow.providers.common.io.datasets import file as common_io_file
from airflow.providers.fab.auth_manager import fab_auth_manager
from airflow.providers.google.datasets import bigquery, gcs
from airflow.providers.mysql.datasets import mysql
from airflow.providers.openlineage.utils.utils import (
DatasetInfo,
translate_airflow_dataset,
)
from airflow.providers.postgres.datasets import postgres
from airflow.providers.trino.datasets import trino
from airflow.secrets.local_filesystem import get_connection, load_connections
from airflow.security.permissions import RESOURCE_DATASET
from airflow.sensors.base_sensor_operator import BaseSensorOperator
from airflow.sensors.date_time_sensor import DateTimeSensor
from airflow.sensors.external_task import (
ExternalTaskSensorLink as ExternalTaskSensorLinkFromExternalTask,
)
from airflow.sensors.external_task_sensor import (
ExternalTaskMarker,
ExternalTaskSensor,
ExternalTaskSensorLink,
ExternalTaskSensorLink as ExternalTaskSensorLinkFromExternalTaskSensor,
)
from airflow.sensors.time_delta_sensor import TimeDeltaSensor
from airflow.secrets.local_filesystem import get_connection, load_connections
from airflow.timetables.datasets import DatasetOrTimeSchedule
from airflow.timetables.simple import DatasetTriggeredTimetable
from airflow.triggers.external_task import TaskStateTrigger
from airflow.utils import dates
from airflow.utils.dag_cycle_tester import test_cycle
from airflow.utils.dates import (
date_range,
datetime_to_nano,
@ -44,70 +88,168 @@ from airflow.utils.decorators import apply_defaults
from airflow.utils.file import TemporaryDirectory, mkdirs
from airflow.utils.helpers import chain, cross_downstream
from airflow.utils.state import SHUTDOWN, terminating_states
from airflow.utils.dag_cycle_tester import test_cycle
from airflow.utils.trigger_rule import TriggerRule
from airflow.www.auth import has_access
from airflow.www.auth import has_access, has_access_dataset
from airflow.www.utils import get_sensitive_variables_fields, should_hide_value_for_key
# airflow root
PY36, PY37, PY38, PY39, PY310, PY311, PY312
DatasetFromRoot
# airflow.api_connexion.security
requires_access, requires_access_dataset
# airflow.auth.managers
is_authorized_dataset
DatasetDetails
# airflow.configuration
get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
# airflow.contrib.*
AWSAthenaHook
TaskStateTrigger
requires_access
# airflow.datasets
Dataset
DatasetAlias
DatasetAliasEvent
DatasetAll
DatasetAny
expand_alias_to_datasets
Metadata
AllowListValidator
BlockListValidator
# airflow.datasets.manager
DatasetManager, dataset_manager, resolve_dataset_manager
# airflow.lineage.hook
DatasetLineageInfo
# airflow.listeners.spec.dataset
on_dataset_changed, on_dataset_created
# airflow.metrics.validators
AllowListValidator, BlockListValidator
# airflow.operators.dummy_operator
dummy_operator.EmptyOperator
dummy_operator.DummyOperator
# airflow.operators.bash_operator
BashOperator
# airflow.operators.branch_operator
BaseBranchOperator
# airflow.operators.dummy
EmptyOperator, DummyOperator
# airflow.operators.email_operator
EmailOperator
# airflow.operators.subdag.*
SubDagOperator
# airflow.providers.amazon
AvpEntities.DATASET
s3.create_dataset
s3.convert_dataset_to_openlineage
s3.sanitize_uri
# airflow.providers.common.io
common_io_file.convert_dataset_to_openlineage
common_io_file.create_dataset
common_io_file.sanitize_uri
# airflow.providers.fab
fab_auth_manager.is_authorized_dataset
# airflow.providers.google
bigquery.sanitize_uri
gcs.create_dataset
gcs.sanitize_uri
gcs.convert_dataset_to_openlineage
# airflow.providers.mysql
mysql.sanitize_uri
# airflow.providers.openlineage
DatasetInfo, translate_airflow_dataset
# airflow.providers.postgres
postgres.sanitize_uri
# airflow.providers.trino
trino.sanitize_uri
# airflow.secrets
get_connection, load_connections
# airflow.security.permissions
RESOURCE_DATASET
# airflow.sensors.base_sensor_operator
BaseSensorOperator
# airflow.sensors.date_time_sensor
DateTimeSensor
# airflow.sensors.external_task
ExternalTaskSensorLinkFromExternalTask
# airflow.sensors.external_task_sensor
ExternalTaskMarker
ExternalTaskSensor
ExternalTaskSensorLinkFromExternalTaskSensor
# airflow.sensors.time_delta_sensor
TimeDeltaSensor
# airflow.timetables
DatasetOrTimeSchedule
DatasetTriggeredTimetable
# airflow.triggers.external_task
TaskStateTrigger
# airflow.utils.date
dates.date_range
dates.days_ago
date_range
days_ago
infer_time_unit
parse_execution_date
round_time
scale_time_units
infer_time_unit
# This one was not deprecated.
datetime_to_nano
dates.datetime_to_nano
get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
get_connection, load_connections
ExternalTaskSensorLink
BashOperator
BaseBranchOperator
EmptyOperator, DummyOperator
dummy_operator.EmptyOperator
dummy_operator.DummyOperator
EmailOperator
BaseSensorOperator
DateTimeSensor
(ExternalTaskMarker, ExternalTaskSensor, ExternalTaskSensorLink)
TimeDeltaSensor
# airflow.utils.dag_cycle_tester
test_cycle
# airflow.utils.decorators
apply_defaults
TemporaryDirectory
mkdirs
# airflow.utils.file
TemporaryDirectory, mkdirs
chain
cross_downstream
# airflow.utils.helpers
chain, cross_downstream
SHUTDOWN
terminating_states
# airflow.utils.state
SHUTDOWN, terminating_states
# airflow.utils.trigger_rule
TriggerRule.DUMMY
TriggerRule.NONE_FAILED_OR_SKIPPED
test_cycle
# airflow.www.auth
has_access
has_access_dataset
# airflow.www.utils
get_sensitive_variables_fields, should_hide_value_for_key

View file

@ -160,15 +160,23 @@ fn removed_name(checker: &mut Checker, expr: &Expr, ranged: impl Ranged) {
.semantic()
.resolve_qualified_name(expr)
.and_then(|qualname| match qualname.segments() {
["airflow", "triggers", "external_task", "TaskStateTrigger"] => {
Some((qualname.to_string(), Replacement::None))
}
["airflow", "api_connexion", "security", "requires_access"] => Some((
qualname.to_string(),
Replacement::Name(
"airflow.api_connexion.security.requires_access_*".to_string(),
),
)),
["airflow", "api_connexion", "security", "requires_access_dataset"] => Some((
qualname.to_string(),
Replacement::Name("airflow.api_connexion.security.requires_access_asset".to_string()),
)),
["airflow", "triggers", "external_task", "TaskStateTrigger"] => {
Some((qualname.to_string(), Replacement::None))
}
["airflow", "security", "permissions", "RESOURCE_DATASET"] => Some((
qualname.to_string(),
Replacement::Name("airflow.security.permissions.RESOURCE_ASSET".to_string()),
)),
// airflow.PY\d{1,2}
["airflow", "PY36"] => Some((
qualname.to_string(),
@ -231,8 +239,22 @@ fn removed_name(checker: &mut Checker, expr: &Expr, ranged: impl Ranged) {
qualname.to_string(),
Replacement::Name("airflow.configuration.conf.set".to_string()),
)),
// airflow.auth.managers
["airflow", "auth", "managers", "models", "resource_details", "DatasetDetails"] => Some((
qualname.to_string(),
Replacement::Name("airflow.auth.managers.models.resource_details.AssetDetails".to_string()),
)),
["airflow", "auth", "managers", "base_auth_manager", "is_authorized_dataset"] => Some((
qualname.to_string(),
Replacement::Name("airflow.auth.managers.base_auth_manager.is_authorized_asset".to_string()),
)),
// airflow.contrib.*
["airflow", "contrib", ..] => Some((qualname.to_string(), Replacement::None)),
["airflow", "contrib", ..] => Some((qualname.to_string(),
Replacement::Message(
"The whole `airflow.contrib` module has been removed."
.to_string(),
),
)),
// airflow.metrics.validators
["airflow", "metrics", "validators", "AllowListValidator"] => Some((
qualname.to_string(),
@ -246,13 +268,86 @@ fn removed_name(checker: &mut Checker, expr: &Expr, ranged: impl Ranged) {
"airflow.metrics.validators.PatternBlockListValidator".to_string(),
),
)),
// airflow.operators
["airflow", "operators", "subdag", ..] => {
// airflow.datasets
["airflow", "Dataset"] => Some((
qualname.to_string(),
Replacement::Name("airflow.sdk.definitions.asset.Asset".to_string()),
)),
["airflow", "datasets", "DatasetAliasEvent"] => {
Some((qualname.to_string(), Replacement::None))
}
["airflow.sensors.external_task.ExternalTaskSensorLink"] => Some((
["airflow", "datasets", "Dataset"] => Some((
qualname.to_string(),
Replacement::Name("airflow.sensors.external_task.ExternalDagLin".to_string()),
Replacement::Name("airflow.sdk.definitions.asset.Asset".to_string()),
)),
["airflow", "datasets", "DatasetAlias"] => Some((
qualname.to_string(),
Replacement::Name("airflow.sdk.definitions.asset.AssetAlias".to_string()),
)),
["airflow", "datasets", "DatasetAll"] => Some((
qualname.to_string(),
Replacement::Name("airflow.sdk.definitions.asset.AssetAll".to_string()),
)),
["airflow", "datasets", "DatasetAny"] => Some((
qualname.to_string(),
Replacement::Name("airflow.sdk.definitions.asset.AssetAny".to_string()),
)),
["airflow", "datasets", "expand_alias_to_datasets"] => Some((
qualname.to_string(),
Replacement::Name("airflow.sdk.definitions.asset.expand_alias_to_assets".to_string()),
)),
["airflow", "datasets", "metadata", "Metadata"] => Some((
qualname.to_string(),
Replacement::Name("airflow.sdk.definitions.asset.metadata.Metadata".to_string()),
)),
// airflow.datasets.manager
["airflow", "datasets", "manager", "dataset_manager"] => Some((
qualname.to_string(),
Replacement::Name("airflow.assets.manager".to_string()),
)),
["airflow", "datasets", "manager", "resolve_dataset_manager"] => Some((
qualname.to_string(),
Replacement::Name("airflow.assets.resolve_asset_manager".to_string()),
)),
["airflow", "datasets.manager", "DatasetManager"] => Some((
qualname.to_string(),
Replacement::Name("airflow.assets.AssetManager".to_string()),
)),
// airflow.listeners.spec
["airflow", "listeners", "spec", "dataset", "on_dataset_created"] => Some((
qualname.to_string(),
Replacement::Name("airflow.listeners.spec.asset.on_asset_created".to_string()),
)),
["airflow", "listeners", "spec", "dataset", "on_dataset_changed"] => Some((
qualname.to_string(),
Replacement::Name("airflow.listeners.spec.asset.on_asset_changed".to_string()),
)),
// airflow.timetables
["airflow", "timetables", "datasets", "DatasetOrTimeSchedule"] => Some((
qualname.to_string(),
Replacement::Name("airflow.timetables.assets.AssetOrTimeSchedule".to_string()),
)),
["airflow", "timetables", "simple", "DatasetTriggeredTimetable"] => Some((
qualname.to_string(),
Replacement::Name("airflow.timetables.simple.AssetTriggeredTimetable".to_string()),
)),
// airflow.lineage.hook
["airflow", "lineage", "hook", "DatasetLineageInfo"] => Some((
qualname.to_string(),
Replacement::Name("airflow.lineage.hook.AssetLineageInfo".to_string()),
)),
// airflow.operators
["airflow", "operators", "subdag", ..] => {
Some((
qualname.to_string(),
Replacement::Message(
"The whole `airflow.subdag` module has been removed.".to_string(),
),
))
},
["airflow", "sensors", "external_task", "ExternalTaskSensorLink"] => Some((
qualname.to_string(),
Replacement::Name("airflow.sensors.external_task.ExternalDagLink".to_string()),
)),
["airflow", "operators", "bash_operator", "BashOperator"] => Some((
qualname.to_string(),
@ -305,7 +400,7 @@ fn removed_name(checker: &mut Checker, expr: &Expr, ranged: impl Ranged) {
["airflow", "sensors", "external_task_sensor", "ExternalTaskSensorLink"] => Some((
qualname.to_string(),
Replacement::Name(
"airflow.sensors.external_task.ExternalTaskSensorLink".to_string(),
"airflow.sensors.external_task.ExternalDagLink".to_string(),
),
)),
["airflow", "sensors", "time_delta_sensor", "TimeDeltaSensor"] => Some((
@ -354,7 +449,6 @@ fn removed_name(checker: &mut Checker, expr: &Expr, ranged: impl Ranged) {
qualname.to_string(),
Replacement::Name("pendulum.today('UTC').add(days=-N, ...)".to_string()),
)),
// airflow.utils.helpers
["airflow", "utils", "helpers", "chain"] => Some((
qualname.to_string(),
@ -394,6 +488,10 @@ fn removed_name(checker: &mut Checker, expr: &Expr, ranged: impl Ranged) {
qualname.to_string(),
Replacement::Name("airflow.www.auth.has_access_*".to_string()),
)),
["airflow", "www", "auth", "has_access_dataset"] => Some((
qualname.to_string(),
Replacement::Name("airflow.www.auth.has_access_dataset.has_access_asset".to_string()),
)),
["airflow", "www", "utils", "get_sensitive_variables_fields"] => Some((
qualname.to_string(),
Replacement::Name(
@ -407,6 +505,82 @@ fn removed_name(checker: &mut Checker, expr: &Expr, ranged: impl Ranged) {
"airflow.utils.log.secrets_masker.should_hide_value_for_key".to_string(),
),
)),
// airflow.providers.amazon
["airflow", "providers", "amazon", "aws", "datasets", "s3", "create_dataset"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.amazon.aws.assets.s3.create_asset".to_string()),
)),
["airflow", "providers", "amazon", "aws", "datasets", "s3", "convert_dataset_to_openlineage"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.amazon.aws.assets.s3.convert_asset_to_openlineage".to_string()),
)),
["airflow", "providers", "amazon", "aws", "datasets", "s3", "sanitize_uri"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.amazon.aws.assets.s3.sanitize_uri".to_string()),
)),
["airflow", "providers", "amazon", "auth_manager", "avp", "entities", "AvpEntities", "DATASET"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.amazon.auth_manager.avp.entities.AvpEntities.ASSET".to_string()),
)),
// airflow.providers.common.io
["airflow", "providers", "common", "io", "datasets", "file", "create_dataset"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.common.io.assets.file.create_asset".to_string()),
)),
["airflow", "providers", "common", "io", "datasets", "file", "convert_dataset_to_openlineage"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.common.io.assets.file.convert_asset_to_openlineage".to_string()),
)),
["airflow", "providers", "common", "io", "datasets", "file", "sanitize_uri"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.common.io.assets.file.sanitize_uri".to_string()),
)),
// airflow.providers.fab
["airflow", "providers", "fab", "auth_manager", "fab_auth_manager", "is_authorized_dataset"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.fab.auth_manager.fab_auth_manager.is_authorized_asset".to_string()),
)),
// airflow.providers.google
["airflow", "providers", "google", "datasets", "bigquery", "create_dataset"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.google.assets.bigquery.create_asset".to_string()),
)),
["airflow", "providers", "google", "datasets", "gcs", "create_dataset"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.google.assets.gcs.create_asset".to_string()),
)),
["airflow", "providers", "google", "datasets", "gcs", "convert_dataset_to_openlineage"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.google.assets.gcs.convert_asset_to_openlineage".to_string()),
)),
["airflow", "providers", "google", "datasets", "gcs", "sanitize_uri"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.google.assets.gcs.sanitize_uri".to_string()),
)),
// airflow.providers.mysql
["airflow", "providers", "mysql", "datasets", "mysql", "sanitize_uri"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.mysql.assets.mysql.sanitize_uri".to_string()),
)),
// airflow.providers.postgres
["airflow", "providers", "postgres", "datasets", "postgres", "sanitize_uri"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.postgres.assets.postgres.sanitize_uri".to_string()),
)),
// airflow.providers.openlineage
["airflow", "providers", "openlineage", "utils", "utils", "DatasetInfo"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.openlineage.utils.utils.AssetInfo".to_string()),
)),
["airflow", "providers", "openlineage", "utils", "utils", "translate_airflow_dataset"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.openlineage.utils.utils.translate_airflow_asset".to_string()),
)),
// airflow.providers.trino
["airflow", "providers", "trino", "datasets", "trino", "sanitize_uri"] => Some((
qualname.to_string(),
Replacement::Name("airflow.providers.trino.assets.trino.sanitize_uri".to_string()),
)),
_ => None,
});
if let Some((deprecated, replacement)) = result {