You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by ka...@apache.org on 2020/11/07 20:18:17 UTC
[airflow] branch v1-10-stable updated: Deprecate importing Hooks
from plugin-created module (#12133)
This is an automated email from the ASF dual-hosted git repository.
kaxilnaik pushed a commit to branch v1-10-stable
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v1-10-stable by this push:
new 321bf6b Deprecate importing Hooks from plugin-created module (#12133)
321bf6b is described below
commit 321bf6ba0d776a34468831342c615f838d97c28d
Author: Ash Berlin-Taylor <as...@firemirror.com>
AuthorDate: Sat Nov 7 20:17:25 2020 +0000
Deprecate importing Hooks from plugin-created module (#12133)
Closes #9506
---
airflow/hooks/__init__.py | 6 ++++++
airflow/plugins_manager.py | 18 +++++++++++-------
tests/plugins/test_plugins_manager_www.py | 30 +++++++++++++++++++++++++-----
3 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/airflow/hooks/__init__.py b/airflow/hooks/__init__.py
index 1f1c40f..745edf8 100644
--- a/airflow/hooks/__init__.py
+++ b/airflow/hooks/__init__.py
@@ -22,6 +22,8 @@ import os as _os
import sys
+PY37 = sys.version_info >= (3, 7)
+
# ------------------------------------------------------------------------
#
# #TODO #FIXME Airflow 2.0
@@ -77,6 +79,10 @@ def _integrate_plugins():
from airflow.plugins_manager import hooks_modules
for hooks_module in hooks_modules:
sys.modules[hooks_module.__name__] = hooks_module
+
+ if not PY37:
+ from pep562 import Pep562
+ hooks_module = Pep562(hooks_module.__name__)
globals()[hooks_module._name] = hooks_module
##########################################################
diff --git a/airflow/plugins_manager.py b/airflow/plugins_manager.py
index 5b86fd1..80099b2 100644
--- a/airflow/plugins_manager.py
+++ b/airflow/plugins_manager.py
@@ -209,10 +209,12 @@ plugins = load_entrypoint_plugins(
)
-def make_deprecated_module(name, objects, plugin):
- name = name.lower()
+def make_deprecated_module(kind, plugin, objects=None):
+ name = 'airflow.{}.{}'.format(kind, plugin.name)
module = imp.new_module(name)
module._name = name.split('.')[-1]
+ if objects is None:
+ objects = getattr(plugin, kind)
module._objects = objects
objects = {o.__name__: o for o in objects}
@@ -236,12 +238,12 @@ def make_deprecated_module(name, objects, plugin):
correct_import_name = '.'.join((obj.__module__, obj_name))
warnings.warn(
- "Importing '{}' from under 'airflow.operators.*' has been deprecated and should be directly "
+ "Importing '{}' from under 'airflow.{}.*' has been deprecated and should be directly "
"imported as '{}' instead.\n"
"\n"
"Support for importing from within the airflow namespace for plugins will be dropped entirely "
"in Airflow 2.0. See <http://airflow.apache.org/docs/stable/howto/custom-operator.html>.".format(
- attrname, correct_import_name
+ attrname, kind, correct_import_name
),
category=FutureWarning,
stacklevel=stacklevel
@@ -292,11 +294,13 @@ during deserialization
for p in plugins:
operators_modules.append(
- make_deprecated_module('airflow.operators.' + p.name, p.operators + p.sensors, p))
+ make_deprecated_module('operators', p, p.operators + p.sensors))
sensors_modules.append(
- make_deprecated_module('airflow.sensors.' + p.name, p.sensors, p)
+ make_deprecated_module('sensors', p)
+ )
+ hooks_modules.append(
+ make_deprecated_module('hooks', p)
)
- hooks_modules.append(make_module('airflow.hooks.' + p.name, p.hooks))
executors_modules.append(
make_module('airflow.executors.' + p.name, p.executors))
macros_modules.append(make_module('airflow.macros.' + p.name, p.macros))
diff --git a/tests/plugins/test_plugins_manager_www.py b/tests/plugins/test_plugins_manager_www.py
index dd21f65..656f8b1 100644
--- a/tests/plugins/test_plugins_manager_www.py
+++ b/tests/plugins/test_plugins_manager_www.py
@@ -22,7 +22,7 @@ from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
-import unittest
+import six
from mock import MagicMock, PropertyMock
from flask.blueprints import Blueprint
@@ -37,19 +37,39 @@ from airflow.www.app import create_app
from tests.plugins.test_plugin import MockPluginA, MockPluginB, MockPluginC
+if six.PY2:
+ # Need `assertWarns` back-ported from unittest2
+ import unittest2 as unittest
+else:
+ import unittest
-class PluginsTest(unittest.TestCase):
+class PluginsTest(unittest.TestCase):
def test_operators(self):
- from airflow.operators.test_plugin import PluginOperator
+ with self.assertWarnsRegex(
+ FutureWarning, r"'PluginOperator' from under 'airflow.operators.*'"
+ ):
+ from airflow.operators.test_plugin import PluginOperator
self.assertTrue(issubclass(PluginOperator, BaseOperator))
+ with self.assertWarnsRegex(
+ FutureWarning, r"'PluginSensorOperator' from under 'airflow.operators.*'"
+ ):
+ from airflow.operators.test_plugin import PluginSensorOperator
+ self.assertTrue(issubclass(PluginSensorOperator, BaseSensorOperator))
+
def test_sensors(self):
- from airflow.sensors.test_plugin import PluginSensorOperator
+ with self.assertWarnsRegex(
+ FutureWarning, r"'PluginSensorOperator' from under 'airflow.sensors.*'"
+ ):
+ from airflow.sensors.test_plugin import PluginSensorOperator
self.assertTrue(issubclass(PluginSensorOperator, BaseSensorOperator))
def test_hooks(self):
- from airflow.hooks.test_plugin import PluginHook
+ with self.assertWarnsRegex(
+ FutureWarning, r"'PluginHook' from under 'airflow.hooks.*'"
+ ):
+ from airflow.hooks.test_plugin import PluginHook
self.assertTrue(issubclass(PluginHook, BaseHook))
def test_executors(self):