From 699313a055a116f07a4dd4a1f4b3fa136a58e8e3 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Thu, 21 Sep 2023 22:21:21 +0200 Subject: [PATCH 1/2] fix #918: remove the need for importlib_metadata in general (broke python<=3.9) --- CHANGELOG.rst | 5 +++ pyproject.toml | 3 -- src/setuptools_scm/_entrypoints.py | 56 +++++++++++++++--------------- src/setuptools_scm/discover.py | 2 +- 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index cc663fdd..14dfe14d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,8 @@ +v8.0.3 +====== + +* fix #918 for good - remove external importlib-metadata to avoid source only loop + v8.0.2 ====== diff --git a/pyproject.toml b/pyproject.toml index 983789f9..9a792b4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,11 +3,9 @@ [build-system] build-backend = "_own_version_helper" requires = [ - 'importlib-metadata>=4.6; python_version < "3.10"', "rich", "setuptools>=61", 'tomli; python_version < "3.11"', - 'typing_extensions; python_version < "3.8"', ] backend-path = [ ".", @@ -42,7 +40,6 @@ dynamic = [ "version", ] dependencies = [ - 'importlib-metadata>=4.6; python_version < "3.10"', "packaging>=20", "setuptools", 'tomli>=1; python_version < "3.11"', diff --git a/src/setuptools_scm/_entrypoints.py b/src/setuptools_scm/_entrypoints.py index 3cb95900..be6fdddd 100644 --- a/src/setuptools_scm/_entrypoints.py +++ b/src/setuptools_scm/_entrypoints.py @@ -6,7 +6,6 @@ from typing import cast from typing import Iterator from typing import overload -from typing import Protocol from typing import TYPE_CHECKING from . import _log @@ -17,15 +16,32 @@ from ._config import Configuration, ParseFunction -log = _log.log.getChild("entrypoints") +from importlib.metadata import EntryPoint as EntryPoint + + +if sys.version_info[:2] < (3, 10): + from importlib.metadata import entry_points as legacy_entry_points + + class EntryPoints: + _groupdata: list[EntryPoint] + + def __init__(self, groupdata: list[EntryPoint]) -> None: + self._groupdata = groupdata + + def select(self, name: str) -> EntryPoints: + return EntryPoints([x for x in self._groupdata if x.name == name]) + def __iter__(self) -> Iterator[EntryPoint]: + return iter(self._groupdata) -class EntrypointProtocol(Protocol): - name: str - value: str + def entry_points(group: str) -> EntryPoints: + return EntryPoints(legacy_entry_points()[group]) - def load(self) -> Any: - pass +else: + from importlib.metadata import entry_points, EntryPoints + + +log = _log.log.getChild("entrypoints") def version_from_entrypoint( @@ -43,27 +59,11 @@ def version_from_entrypoint( return None -if sys.version_info[:2] < (3, 10): - from importlib_metadata import entry_points - from importlib_metadata import EntryPoint -else: - from importlib.metadata import entry_points - from importlib.metadata import EntryPoint - - -def iter_entry_points( - group: str, name: str | None = None -) -> Iterator[EntrypointProtocol]: - eps = entry_points(group=group) - res = ( - eps - if name is None - else eps.select( # type: ignore [no-untyped-call] - name=name, - ) - ) +def iter_entry_points(group: str, name: str | None = None) -> Iterator[EntryPoint]: + eps: EntryPoints = entry_points(group=group) + res = eps if name is None else eps.select(name=name) - return cast(Iterator[EntrypointProtocol], iter(res)) + return iter(res) def _get_ep(group: str, name: str) -> Any | None: @@ -76,7 +76,7 @@ def _get_ep(group: str, name: str) -> Any | None: def _get_from_object_reference_str(path: str, group: str) -> Any | None: # todo: remove for importlib native spelling - ep: EntrypointProtocol = EntryPoint(path, path, group) + ep = EntryPoint(path, path, group) try: return ep.load() except (AttributeError, ModuleNotFoundError): diff --git a/src/setuptools_scm/discover.py b/src/setuptools_scm/discover.py index 8bf3899c..b12b2f12 100644 --- a/src/setuptools_scm/discover.py +++ b/src/setuptools_scm/discover.py @@ -47,7 +47,7 @@ def match_entrypoint(root: _t.PathT, name: str) -> bool: def iter_matching_entrypoints( root: _t.PathT, entrypoint: str, config: Configuration -) -> Iterable[_entrypoints.EntrypointProtocol]: +) -> Iterable[_entrypoints.EntryPoint]: """ Consider different entry-points in ``root`` and optionally its parents. :param root: File path. From 26fc10495f135987fcce1316398fe6857c90444c Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Fri, 22 Sep 2023 09:59:40 +0200 Subject: [PATCH 2/2] fix #926: ensure version file is mypy safe on python3.8gi --- CHANGELOG.rst | 1 + src/setuptools_scm/_integration/dump_version.py | 6 ++++-- testing/test_basic_api.py | 2 +- testing/test_functions.py | 6 +++++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 14dfe14d..6e9212d0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,7 @@ v8.0.3 ====== * fix #918 for good - remove external importlib-metadata to avoid source only loop +* fix #926: ensure mypy on python3.8 works with the version file v8.0.2 ====== diff --git a/src/setuptools_scm/_integration/dump_version.py b/src/setuptools_scm/_integration/dump_version.py index 1dd280b9..36790fa8 100644 --- a/src/setuptools_scm/_integration/dump_version.py +++ b/src/setuptools_scm/_integration/dump_version.py @@ -15,10 +15,12 @@ ".py": """\ # file generated by setuptools_scm # don't change, don't track in version control -from __future__ import annotations +TYPE_CHECKING = False +if TYPE_CHECKING: + from typing import Tuple __version__ = version = {version!r} # type: str -__version_tuple__ = version_tuple = {version_tuple!r} # type: tuple[int | str, ...] +__version_tuple__ = version_tuple = {version_tuple!r} # type: Tuple[int | str, ...] """, ".txt": "{version}", } diff --git a/testing/test_basic_api.py b/testing/test_basic_api.py index 95afa0f3..3af099a3 100644 --- a/testing/test_basic_api.py +++ b/testing/test_basic_api.py @@ -182,7 +182,7 @@ def read(name: str) -> str: assert lines[-2:] == [ "__version__ = version = '1.0.dev42' # type: str", "__version_tuple__ = version_tuple = (1, 0, 'dev42')" - " # type: tuple[int | str, ...]", + " # type: Tuple[int | str, ...]", ] version = "1.0.1+g4ac9d2c" diff --git a/testing/test_functions.py b/testing/test_functions.py index f7a74812..afa45d3b 100644 --- a/testing/test_functions.py +++ b/testing/test_functions.py @@ -137,7 +137,11 @@ def test_dump_version_mypy(tmp_path: Path) -> None: if mypy is None: pytest.skip("mypy not found") dump_a_version(tmp_path) - subprocess.run([mypy, "--strict", "VERSION.py"], cwd=tmp_path, check=True) + subprocess.run( + [mypy, "--python-version=3.8", "--strict", "VERSION.py"], + cwd=tmp_path, + check=True, + ) def test_dump_version_flake8(tmp_path: Path) -> None: