diff --git a/pyproject.toml b/pyproject.toml index 6da73cd..e4ad27b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,16 +25,12 @@ dependencies = [] dynamic = ["readme"] [project.optional-dependencies] -mypy = [ - "types-setuptools", - "types-pkg-resources", -] +mypy = [] test = [ "pytest", "pytest-cov", "pytest-mock", "httpretty", - "types-setuptools", ] [project.urls] diff --git a/src/mxdev/config.py b/src/mxdev/config.py index bf8e3f7..eb0bbfd 100644 --- a/src/mxdev/config.py +++ b/src/mxdev/config.py @@ -68,7 +68,7 @@ def __init__( if line: self.ignore_keys.append(line) - def is_ns_member(name): + def is_ns_member(name) -> bool: for hook in hooks: if name.startswith(hook.namespace): return True diff --git a/src/mxdev/entry_points.py b/src/mxdev/entry_points.py new file mode 100644 index 0000000..d48ea34 --- /dev/null +++ b/src/mxdev/entry_points.py @@ -0,0 +1,27 @@ +# this is a helper to load entrypoints with importlib, since pkg_resources +# is deprecated. In Python 3.12 an API incompatible change was introduced, +# so this code is that ugly now. +from importlib.metadata import entry_points + + +try: + # do we have Python 3.12+? + from importlib.metadata import EntryPoints # type: ignore # noqa: F401 + + HAS_IMPORTLIB_ENTRYPOINTS = True +except ImportError: + HAS_IMPORTLIB_ENTRYPOINTS = False + + +def load_eps_by_group(group: str) -> list: + if HAS_IMPORTLIB_ENTRYPOINTS: + eps = entry_points(group=group) # type: ignore + else: + eps_base = entry_points() + if group not in eps_base: + return [] + eps = eps_base[group] + # XXX: for some reasons entry points are loaded twice. not sure if this + # is a glitch when installing with uv or something related to + # importlib.metadata.entry_points + return list(eps) # type: ignore diff --git a/src/mxdev/hooks.py b/src/mxdev/hooks.py index 153a8d7..a5de768 100644 --- a/src/mxdev/hooks.py +++ b/src/mxdev/hooks.py @@ -1,9 +1,18 @@ +from .entry_points import load_eps_by_group from .state import State -from pkg_resources import iter_entry_points import typing +try: + # do we have Python 3.12+ + from importlib.metadata import EntryPoints # type: ignore # noqa: F401 + + HAS_IMPORTLIB_ENTRYPOINTS = True +except ImportError: + HAS_IMPORTLIB_ENTRYPOINTS = False + + class Hook: """Entry point for hooking into mxdev.""" @@ -18,11 +27,12 @@ def write(self, state: State) -> None: def load_hooks() -> list: - return [ep.load()() for ep in iter_entry_points("mxdev") if ep.name == "hook"] + return [ep.load()() for ep in load_eps_by_group("mxdev") if ep.name == "hook"] def read_hooks(state: State, hooks: typing.List[Hook]) -> None: for hook in hooks: + breakpoint() hook.read(state) diff --git a/src/mxdev/tests/test_common.py b/src/mxdev/tests/test_common.py index 5fa6de9..d96a744 100644 --- a/src/mxdev/tests/test_common.py +++ b/src/mxdev/tests/test_common.py @@ -143,8 +143,7 @@ def test_WorkingCopies_process(mocker, caplog): def test_WorkingCopies_checkout(mocker, caplog, tmpdir): caplog.set_level(logging.INFO) - class SysExit(Exception): - ... + class SysExit(Exception): ... class Exit: def __call__(self, code): diff --git a/src/mxdev/vcs/common.py b/src/mxdev/vcs/common.py index f4a5106..46f6b0c 100644 --- a/src/mxdev/vcs/common.py +++ b/src/mxdev/vcs/common.py @@ -1,7 +1,8 @@ +from ..entry_points import load_eps_by_group + import abc import logging import os -import pkg_resources import platform import queue import re @@ -93,20 +94,16 @@ def should_update(self, **kwargs) -> bool: return update @abc.abstractmethod - def checkout(self, **kwargs) -> typing.Union[str, None]: - ... + def checkout(self, **kwargs) -> typing.Union[str, None]: ... @abc.abstractmethod - def status(self, **kwargs) -> typing.Union[typing.Tuple[str, str], str]: - ... + def status(self, **kwargs) -> typing.Union[typing.Tuple[str, str], str]: ... @abc.abstractmethod - def matches(self) -> bool: - ... + def matches(self) -> bool: ... @abc.abstractmethod - def update(self, **kwargs) -> typing.Union[str, None]: - ... + def update(self, **kwargs) -> typing.Union[str, None]: ... def yesno( @@ -151,12 +148,12 @@ def get_workingcopytypes() -> typing.Dict[str, typing.Type[BaseWorkingCopy]]: return _workingcopytypes group = "mxdev.workingcopytypes" addons = {} - for entrypoint in pkg_resources.iter_entry_points(group=group): + for entrypoint in load_eps_by_group(group): key = entrypoint.name workingcopytype = entrypoint.load() if not entrypoint.dist: continue - if entrypoint.dist.project_name == "mxdev": + if entrypoint.dist.name == "mxdev": _workingcopytypes[key] = workingcopytype continue if key in addons: