Drop optional dependencies of Spack (#43081)
Remove dependency on `importlib_metadata` and `pkg_resources`, which can be problematic if the version in PYTHONPATH is incompatible with the interpreter Spack is running under.
This commit is contained in:
parent
bca4d37d76
commit
c090bc5ebe
2 changed files with 31 additions and 48 deletions
|
@ -12,7 +12,6 @@
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
import warnings
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import Any, Callable, Iterable, List, Tuple
|
from typing import Any, Callable, Iterable, List, Tuple
|
||||||
|
|
||||||
|
@ -847,43 +846,25 @@ def __repr__(self):
|
||||||
def get_entry_points(*, group: str):
|
def get_entry_points(*, group: str):
|
||||||
"""Wrapper for ``importlib.metadata.entry_points``
|
"""Wrapper for ``importlib.metadata.entry_points``
|
||||||
|
|
||||||
Adapted from https://github.com/HypothesisWorks/hypothesis/blob/0a90ed6edf56319149956c7321d4110078a5c228/hypothesis-python/src/hypothesis/entry_points.py
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
group (str): the group of entry points to select
|
group: entry points to select
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
EntryPoints for ``group``
|
EntryPoints for ``group`` or empty list if unsupported
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
try:
|
import importlib.metadata # type: ignore # novermin
|
||||||
from importlib import metadata as importlib_metadata # type: ignore # novermin
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import importlib_metadata # type: ignore # mypy thinks this is a redefinition
|
return []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
entry_points = importlib_metadata.entry_points(group=group)
|
return importlib.metadata.entry_points(group=group)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# Prior to Python 3.10, entry_points accepted no parameters and always
|
# Prior to Python 3.10, entry_points accepted no parameters and always
|
||||||
# returned a dictionary of entry points, keyed by group. See
|
# returned a dictionary of entry points, keyed by group. See
|
||||||
# https://docs.python.org/3/library/importlib.metadata.html#entry-points
|
# https://docs.python.org/3/library/importlib.metadata.html#entry-points
|
||||||
entry_points = importlib_metadata.entry_points().get(group, [])
|
return importlib.metadata.entry_points().get(group, [])
|
||||||
yield from entry_points
|
|
||||||
except ImportError:
|
|
||||||
# But if we're not on Python >= 3.8 and the importlib_metadata backport
|
|
||||||
# is not installed, we fall back to pkg_resources anyway.
|
|
||||||
try:
|
|
||||||
import pkg_resources # type: ignore
|
|
||||||
except ImportError:
|
|
||||||
warnings.warn(
|
|
||||||
"Under Python <= 3.7, Spack requires either the importlib_metadata "
|
|
||||||
"or setuptools package in order to load extensions via entrypoints.",
|
|
||||||
ImportWarning,
|
|
||||||
)
|
|
||||||
yield from ()
|
|
||||||
else:
|
|
||||||
yield from pkg_resources.iter_entry_points(group)
|
|
||||||
|
|
||||||
|
|
||||||
def load_module_from_file(module_name, module_path):
|
def load_module_from_file(module_name, module_path):
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
import llnl.util.lang
|
||||||
|
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.extensions
|
import spack.extensions
|
||||||
|
|
||||||
|
@ -64,24 +66,12 @@ def entry_points(group=None):
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def mock_entry_points(tmp_path, monkeypatch):
|
def mock_get_entry_points(tmp_path, monkeypatch):
|
||||||
entry_points = entry_points_factory(tmp_path)
|
entry_points = entry_points_factory(tmp_path)
|
||||||
try:
|
monkeypatch.setattr(llnl.util.lang, "get_entry_points", entry_points)
|
||||||
try:
|
|
||||||
import importlib.metadata as importlib_metadata # type: ignore # novermin
|
|
||||||
except ImportError:
|
|
||||||
import importlib_metadata
|
|
||||||
monkeypatch.setattr(importlib_metadata, "entry_points", entry_points)
|
|
||||||
except ImportError:
|
|
||||||
try:
|
|
||||||
import pkg_resources # type: ignore
|
|
||||||
except ImportError:
|
|
||||||
return
|
|
||||||
monkeypatch.setattr(pkg_resources, "iter_entry_points", entry_points)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.version_info[:2] < (3, 8), reason="Python>=3.8 required")
|
def test_spack_entry_point_config(tmp_path, mock_get_entry_points):
|
||||||
def test_spack_entry_point_config(tmp_path, mock_entry_points):
|
|
||||||
"""Test config scope entry point"""
|
"""Test config scope entry point"""
|
||||||
config_paths = dict(spack.config.config_paths_from_entry_points())
|
config_paths = dict(spack.config.config_paths_from_entry_points())
|
||||||
config_path = config_paths.get("plugin-mypackage_config")
|
config_path = config_paths.get("plugin-mypackage_config")
|
||||||
|
@ -94,8 +84,7 @@ def test_spack_entry_point_config(tmp_path, mock_entry_points):
|
||||||
assert config.get("config:install_tree:root", scope="plugin-mypackage_config") == "/spam/opt"
|
assert config.get("config:install_tree:root", scope="plugin-mypackage_config") == "/spam/opt"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.version_info[:2] < (3, 8), reason="Python>=3.8 required")
|
def test_spack_entry_point_extension(tmp_path, mock_get_entry_points):
|
||||||
def test_spack_entry_point_extension(tmp_path, mock_entry_points):
|
|
||||||
"""Test config scope entry point"""
|
"""Test config scope entry point"""
|
||||||
my_ext = tmp_path / "spack/spack-myext"
|
my_ext = tmp_path / "spack/spack-myext"
|
||||||
extensions = spack.extensions.get_extension_paths()
|
extensions = spack.extensions.get_extension_paths()
|
||||||
|
@ -110,3 +99,16 @@ def test_spack_entry_point_extension(tmp_path, mock_entry_points):
|
||||||
assert os.path.samefile(root, my_ext)
|
assert os.path.samefile(root, my_ext)
|
||||||
module = spack.extensions.get_module("spam")
|
module = spack.extensions.get_module("spam")
|
||||||
assert module is not None
|
assert module is not None
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(sys.version_info[:2] < (3, 8), reason="Python>=3.8 required")
|
||||||
|
def test_llnl_util_lang_get_entry_points(tmp_path, monkeypatch):
|
||||||
|
import importlib.metadata # type: ignore # novermin
|
||||||
|
|
||||||
|
monkeypatch.setattr(importlib.metadata, "entry_points", entry_points_factory(tmp_path))
|
||||||
|
|
||||||
|
entry_points = list(llnl.util.lang.get_entry_points(group="spack.config"))
|
||||||
|
assert isinstance(entry_points[0], MockConfigEntryPoint)
|
||||||
|
|
||||||
|
entry_points = list(llnl.util.lang.get_entry_points(group="spack.extensions"))
|
||||||
|
assert isinstance(entry_points[0], MockExtensionsEntryPoint)
|
||||||
|
|
Loading…
Reference in a new issue