Skip to content

Commit a2f302d

Browse files
authored
Issue deprecation warning for plugins registering ti_deps (#45742)
This is removed in Airflow3 via #45713
1 parent a5726a5 commit a2f302d

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

airflow/plugins_manager.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import os
2828
import sys
2929
import types
30+
import warnings
3031
from pathlib import Path
3132
from typing import TYPE_CHECKING, Any, Iterable
3233

@@ -431,6 +432,17 @@ def initialize_ti_deps_plugins():
431432
registered_ti_dep_classes = {}
432433

433434
for plugin in plugins:
435+
if not plugin.ti_deps:
436+
continue
437+
438+
from airflow.exceptions import RemovedInAirflow3Warning
439+
440+
warnings.warn(
441+
"Using custom `ti_deps` on operators has been removed in Airflow 3.0",
442+
RemovedInAirflow3Warning,
443+
stacklevel=1,
444+
)
445+
434446
registered_ti_dep_classes.update(
435447
{qualname(ti_dep.__class__): ti_dep.__class__ for ti_dep in plugin.ti_deps}
436448
)

tests/plugins/test_plugins_manager.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import pytest
3030

31+
from airflow.exceptions import RemovedInAirflow3Warning
3132
from airflow.hooks.base import BaseHook
3233
from airflow.listeners.listener import get_listener_manager
3334
from airflow.plugins_manager import AirflowPlugin
@@ -174,6 +175,11 @@ def clean_plugins(self):
174175

175176
plugins_manager.loaded_plugins = set()
176177
plugins_manager.plugins = []
178+
yield
179+
plugins_manager.loaded_plugins = set()
180+
181+
plugins_manager.registered_ti_dep_classes = None
182+
plugins_manager.plugins = None
177183

178184
def test_no_log_when_no_plugins(self, caplog):
179185
with mock_plugin_manager(plugins=[]):
@@ -270,6 +276,17 @@ class AirflowAdminMenuLinksPlugin(AirflowPlugin):
270276
),
271277
]
272278

279+
def test_deprecate_ti_deps(self):
280+
class DeprecatedTIDeps(AirflowPlugin):
281+
name = "ti_deps"
282+
283+
ti_deps = [mock.MagicMock()]
284+
285+
with mock_plugin_manager(plugins=[DeprecatedTIDeps()]), pytest.warns(RemovedInAirflow3Warning):
286+
from airflow import plugins_manager
287+
288+
plugins_manager.initialize_ti_deps_plugins()
289+
273290
def test_should_not_warning_about_fab_plugins(self, caplog):
274291
class AirflowAdminViewsPlugin(AirflowPlugin):
275292
name = "test_admin_views_plugin"

tests/serialization/test_dag_serialization.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,21 @@ def timetable_plugin(monkeypatch):
408408
)
409409

410410

411+
@pytest.fixture
412+
def custom_ti_dep(monkeypatch):
413+
"""Patch plugins manager to always and only return our custom timetable."""
414+
from test_plugin import CustomTestTriggerRule
415+
416+
from airflow import plugins_manager
417+
418+
monkeypatch.setattr(plugins_manager, "initialize_ti_deps_plugins", lambda: None)
419+
monkeypatch.setattr(
420+
plugins_manager,
421+
"registered_ti_dep_classes",
422+
{"test_plugin.CustomTestTriggerRule": CustomTestTriggerRule},
423+
)
424+
425+
411426
# TODO: (potiuk) - AIP-44 - check why this test hangs
412427
@pytest.mark.skip_if_database_isolation_mode
413428
class TestStringifiedDAGs:
@@ -430,6 +445,7 @@ def setup_test_cases(self):
430445
)
431446

432447
@pytest.mark.db_test
448+
@pytest.mark.filterwarnings("ignore::airflow.exceptions.RemovedInAirflow3Warning")
433449
def test_serialization(self):
434450
"""Serialization and deserialization should work for every DAG and Operator."""
435451
dags = collect_dags()
@@ -539,6 +555,7 @@ def sorted_serialized_dag(dag_dict: dict):
539555
return actual, expected
540556

541557
@pytest.mark.db_test
558+
@pytest.mark.filterwarnings("ignore::airflow.exceptions.RemovedInAirflow3Warning")
542559
def test_deserialization_across_process(self):
543560
"""A serialized DAG can be deserialized in another process."""
544561

@@ -1596,6 +1613,7 @@ def test_deps_sorted(self):
15961613
"airflow.ti_deps.deps.trigger_rule_dep.TriggerRuleDep",
15971614
]
15981615

1616+
@pytest.mark.filterwarnings("ignore::airflow.exceptions.RemovedInAirflow3Warning")
15991617
def test_error_on_unregistered_ti_dep_serialization(self):
16001618
# trigger rule not registered through the plugin system will not be serialized
16011619
class DummyTriggerRule(BaseTIDep):
@@ -1634,6 +1652,8 @@ def test_error_on_unregistered_ti_dep_deserialization(self):
16341652
SerializedBaseOperator.deserialize_operator(serialize_op)
16351653

16361654
@pytest.mark.db_test
1655+
@pytest.mark.usefixtures("custom_ti_dep")
1656+
@pytest.mark.filterwarnings("ignore::airflow.exceptions.RemovedInAirflow3Warning")
16371657
def test_serialize_and_deserialize_custom_ti_deps(self):
16381658
from test_plugin import CustomTestTriggerRule
16391659

0 commit comments

Comments
 (0)