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]