This is an automated email from the ASF dual-hosted git repository.

amoghdesai pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 009de2e945d Moving entry_point utilities to shared module_loading 
module (#59971)
009de2e945d is described below

commit 009de2e945d4cf56e18ede8a552d97373865042c
Author: Amogh Desai <[email protected]>
AuthorDate: Fri Jan 2 20:50:15 2026 +0530

    Moving entry_point utilities to shared module_loading module (#59971)
---
 airflow-core/src/airflow/utils/entry_points.py     | 51 ++++------------------
 shared/module_loading/pyproject.toml               |  1 +
 .../src/airflow_shared/module_loading/__init__.py  | 44 ++++++++++++++++++-
 .../tests/module_loading}/test_entry_points.py     |  4 +-
 task-sdk/pyproject.toml                            |  3 ++
 5 files changed, 57 insertions(+), 46 deletions(-)

diff --git a/airflow-core/src/airflow/utils/entry_points.py 
b/airflow-core/src/airflow/utils/entry_points.py
index 11b0ff2e7b6..dac8e3b868b 100644
--- a/airflow-core/src/airflow/utils/entry_points.py
+++ b/airflow-core/src/airflow/utils/entry_points.py
@@ -14,48 +14,13 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-from __future__ import annotations
-
-import functools
-import logging
-import sys
-from collections import defaultdict
-from collections.abc import Iterator
-
-if sys.version_info >= (3, 12):
-    from importlib import metadata
-else:
-    import importlib_metadata as metadata
-
-log = logging.getLogger(__name__)
-
-EPnD = tuple[metadata.EntryPoint, metadata.Distribution]
-
+"""Re-export entry_points utilities from shared library for backward 
compatibility."""
 
[email protected]
-def _get_grouped_entry_points() -> dict[str, list[EPnD]]:
-    mapping: dict[str, list[EPnD]] = defaultdict(list)
-    for dist in metadata.distributions():
-        try:
-            for e in dist.entry_points:
-                mapping[e.group].append((e, dist))
-        except Exception as e:
-            log.warning("Error when retrieving package metadata (skipping it): 
%s, %s", dist, e)
-    return mapping
-
-
-def entry_points_with_dist(group: str) -> Iterator[EPnD]:
-    """
-    Retrieve entry points of the given group.
-
-    This is like the ``entry_points()`` function from ``importlib.metadata``,
-    except it also returns the distribution the entry point was loaded from.
-
-    Note that this may return multiple distributions to the same package if 
they
-    are loaded from different ``sys.path`` entries. The caller site should
-    implement appropriate deduplication logic if needed.
+from __future__ import annotations
 
-    :param group: Filter results to only this entrypoint group
-    :return: Generator of (EntryPoint, Distribution) objects for the specified 
groups
-    """
-    return iter(_get_grouped_entry_points()[group])
+from airflow._shared.module_loading import (
+    EPnD as EPnD,
+    _get_grouped_entry_points as _get_grouped_entry_points,
+    entry_points_with_dist as entry_points_with_dist,
+    metadata as metadata,
+)
diff --git a/shared/module_loading/pyproject.toml 
b/shared/module_loading/pyproject.toml
index a063506355e..84a25aa0f57 100644
--- a/shared/module_loading/pyproject.toml
+++ b/shared/module_loading/pyproject.toml
@@ -24,6 +24,7 @@ classifiers = [
 ]
 
 dependencies = [
+    'importlib_metadata>=6.5;python_version<"3.12"',
 ]
 
 [dependency-groups]
diff --git 
a/shared/module_loading/src/airflow_shared/module_loading/__init__.py 
b/shared/module_loading/src/airflow_shared/module_loading/__init__.py
index dc732ab4002..07022cbf487 100644
--- a/shared/module_loading/src/airflow_shared/module_loading/__init__.py
+++ b/shared/module_loading/src/airflow_shared/module_loading/__init__.py
@@ -17,11 +17,24 @@
 # under the License.
 from __future__ import annotations
 
+import functools
+import logging
 import pkgutil
-from collections.abc import Callable
+import sys
+from collections import defaultdict
+from collections.abc import Callable, Iterator
 from importlib import import_module
 from typing import TYPE_CHECKING
 
+if sys.version_info >= (3, 12):
+    from importlib import metadata
+else:
+    import importlib_metadata as metadata
+
+log = logging.getLogger(__name__)
+
+EPnD = tuple[metadata.EntryPoint, metadata.Distribution]
+
 if TYPE_CHECKING:
     from types import ModuleType
 
@@ -89,3 +102,32 @@ def is_valid_dotpath(path: str) -> bool:
     pattern = r"^[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*$"
 
     return bool(re.match(pattern, path))
+
+
[email protected]
+def _get_grouped_entry_points() -> dict[str, list[EPnD]]:
+    mapping: dict[str, list[EPnD]] = defaultdict(list)
+    for dist in metadata.distributions():
+        try:
+            for e in dist.entry_points:
+                mapping[e.group].append((e, dist))
+        except Exception as e:
+            log.warning("Error when retrieving package metadata (skipping it): 
%s, %s", dist, e)
+    return mapping
+
+
+def entry_points_with_dist(group: str) -> Iterator[EPnD]:
+    """
+    Retrieve entry points of the given group.
+
+    This is like the ``entry_points()`` function from ``importlib.metadata``,
+    except it also returns the distribution the entry point was loaded from.
+
+    Note that this may return multiple distributions to the same package if 
they
+    are loaded from different ``sys.path`` entries. The caller site should
+    implement appropriate deduplication logic if needed.
+
+    :param group: Filter results to only this entrypoint group
+    :return: Generator of (EntryPoint, Distribution) objects for the specified 
groups
+    """
+    return iter(_get_grouped_entry_points()[group])
diff --git a/airflow-core/tests/unit/utils/test_entry_points.py 
b/shared/module_loading/tests/module_loading/test_entry_points.py
similarity index 92%
rename from airflow-core/tests/unit/utils/test_entry_points.py
rename to shared/module_loading/tests/module_loading/test_entry_points.py
index d1a7f0fc5b6..87b9f15b76e 100644
--- a/airflow-core/tests/unit/utils/test_entry_points.py
+++ b/shared/module_loading/tests/module_loading/test_entry_points.py
@@ -20,7 +20,7 @@ from __future__ import annotations
 from collections.abc import Iterable
 from unittest import mock
 
-from airflow.utils.entry_points import entry_points_with_dist, metadata
+from airflow_shared.module_loading import entry_points_with_dist, metadata
 
 
 class MockDistribution:
@@ -41,7 +41,7 @@ class MockMetadata:
         ]
 
 
[email protected]("airflow.utils.entry_points.metadata", MockMetadata())
[email protected]("airflow_shared.module_loading.metadata", MockMetadata())
 def test_entry_points_with_dist():
     entries = list(entry_points_with_dist("group_x"))
 
diff --git a/task-sdk/pyproject.toml b/task-sdk/pyproject.toml
index 7c26f1babb5..91991509710 100644
--- a/task-sdk/pyproject.toml
+++ b/task-sdk/pyproject.toml
@@ -77,6 +77,9 @@ dependencies = [
     "packaging>=24.0",
     "typing-extensions>=4.14.1",
     # End of shared configuration dependencies
+    # Start of shared module-loading dependencies
+    'importlib_metadata>=6.5;python_version<"3.12"',
+    # End of shared module-loading dependencies
 ]
 
 [project.optional-dependencies]

Reply via email to