From 1780e505f698e9c9eb6e29398a209298444d432a Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Tue, 9 May 2023 12:41:02 +0200 Subject: move setuptools integration to private subpackage --- CHANGELOG.rst | 1 + pyproject.toml | 4 +- src/setuptools_scm/_entrypoints.py | 9 +-- src/setuptools_scm/_integration/setuptools.py | 105 ++++++++++++++++++++++++++ src/setuptools_scm/integration.py | 104 ------------------------- testing/test_integration.py | 2 +- 6 files changed, 113 insertions(+), 112 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 72efc1c..1b2d806 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,6 +14,7 @@ breaking * unify distance=None and distance=0 they should mean the same and where hiding dirty states that are now explicitly dirty * depend on later importlib for the full selectable api +* move setuptools integration code to private sub-package features -------- diff --git a/pyproject.toml b/pyproject.toml index 86a7402..264789a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,11 +61,11 @@ toml = [ [project.urls] repository = "https://github.com/pypa/setuptools_scm/" [project.entry-points."distutils.setup_keywords"] -use_scm_version = "setuptools_scm.integration:version_keyword" +use_scm_version = "setuptools_scm._integration.setuptools:version_keyword" [project.entry-points."setuptools.file_finders"] setuptools_scm = "setuptools_scm._file_finders:find_files" [project.entry-points."setuptools.finalize_distribution_options"] -setuptools_scm = "setuptools_scm.integration:infer_version" +setuptools_scm = "setuptools_scm._integration.setuptools:infer_version" [project.entry-points."setuptools_scm.files_command"] ".git" = "setuptools_scm._file_finders.git:git_find_files" ".hg" = "setuptools_scm._file_finders.hg:hg_find_files" diff --git a/src/setuptools_scm/_entrypoints.py b/src/setuptools_scm/_entrypoints.py index 01b48b1..62a18e1 100644 --- a/src/setuptools_scm/_entrypoints.py +++ b/src/setuptools_scm/_entrypoints.py @@ -79,10 +79,9 @@ def _get_ep(group: str, name: str) -> Any | None: return None -def _get_from_object_reference_str(path: str) -> Any | None: - ep: EntrypointProtocol = EntryPoint( - path, path, None - ) # type: ignore [no-untyped-call] +def _get_from_object_reference_str(path: str, group: str) -> Any | None: + # todo: remove for importlib native spelling + ep: EntrypointProtocol = EntryPoint(path, path, group) try: return ep.load() except (AttributeError, ModuleNotFoundError): @@ -100,7 +99,7 @@ def _iter_version_schemes( scheme_value = cast( "_t.VERSION_SCHEMES", _get_ep(entrypoint, scheme_value) - or _get_from_object_reference_str(scheme_value), + or _get_from_object_reference_str(scheme_value, entrypoint), ) if isinstance(scheme_value, (list, tuple)): diff --git a/src/setuptools_scm/_integration/setuptools.py b/src/setuptools_scm/_integration/setuptools.py index 6e04148..94981d7 100644 --- a/src/setuptools_scm/_integration/setuptools.py +++ b/src/setuptools_scm/_integration/setuptools.py @@ -1,6 +1,17 @@ from __future__ import annotations +import logging import os +import warnings +from typing import Any +from typing import Callable + +import setuptools + +from .. import _config +from .._version_cls import _validate_version_cls + +log = logging.getLogger(__name__) def read_dist_name_from_setup_cfg( @@ -13,3 +24,97 @@ def read_dist_name_from_setup_cfg( parser.read([input], encoding="utf-8") dist_name = parser.get("metadata", "name", fallback=None) return dist_name + + +def _warn_on_old_setuptools(_version: str = setuptools.__version__) -> None: + if int(_version.split(".")[0]) < 61: + warnings.warn( + RuntimeWarning( + f""" +ERROR: setuptools=={_version} is used in combination with setuptools_scm>=8.x + +Your build configuration is incomplete and previously worked by accident! +setuptools_scm requires setuptools>=61 + +Suggested workaround if applicable: + - migrating from the deprecated setup_requires mechanism to pep517/518 + and using a pyproject.toml to declare build dependencies + which are reliably pre-installed before running the build tools +""" + ) + ) + + +def _assign_version( + dist: setuptools.Distribution, config: _config.Configuration +) -> None: + from .. import _get_version, _version_missing + + maybe_version = _get_version(config) + + if maybe_version is None: + _version_missing(config) + else: + assert dist.metadata.version is None + dist.metadata.version = maybe_version + + +_warn_on_old_setuptools() + + +def version_keyword( + dist: setuptools.Distribution, + keyword: str, + value: bool | dict[str, Any] | Callable[[], dict[str, Any]], +) -> None: + if not value: + return + elif value is True: + value = {} + elif callable(value): + value = value() + assert ( + "dist_name" not in value + ), "dist_name may not be specified in the setup keyword " + dist_name: str | None = dist.metadata.name + if dist.metadata.version is not None: + warnings.warn(f"version of {dist_name} already set") + return + log.debug( + "version keyword %r", + vars(dist.metadata), + ) + log.debug("dist %s %s", id(dist), id(dist.metadata)) + + if dist_name is None: + dist_name = read_dist_name_from_setup_cfg() + version_cls = value.pop("version_cls", None) + normalize = value.pop("normalize", True) + final_version = _validate_version_cls(version_cls, normalize) + config = _config.Configuration( + dist_name=dist_name, version_cls=final_version, **value + ) + _assign_version(dist, config) + + +def infer_version(dist: setuptools.Distribution) -> None: + log.debug( + "finalize hook %r", + vars(dist.metadata), + ) + log.debug("dist %s %s", id(dist), id(dist.metadata)) + if dist.metadata.version is not None: + return # metadata already added by hook + dist_name = dist.metadata.name + if dist_name is None: + dist_name = read_dist_name_from_setup_cfg() + if not os.path.isfile("pyproject.toml"): + return + if dist_name == "setuptools_scm": + return + try: + config = _config.Configuration.from_file(dist_name=dist_name) + except LookupError as e: + log.exception(e) + else: + _assign_version(dist, config) diff --git a/src/setuptools_scm/integration.py b/src/setuptools_scm/integration.py index 42ea95d..2583f47 100644 --- a/src/setuptools_scm/integration.py +++ b/src/setuptools_scm/integration.py @@ -1,116 +1,12 @@ from __future__ import annotations import logging -import os import textwrap -import warnings from pathlib import Path -from typing import Any -from typing import Callable -from typing import TYPE_CHECKING -import setuptools - -from . import _get_version from . import _types as _t -from . import _version_missing -from . import Configuration -from ._integration.setuptools import ( - read_dist_name_from_setup_cfg as _read_dist_name_from_setup_cfg, -) -from ._version_cls import _validate_version_cls log = logging.getLogger(__name__) -if TYPE_CHECKING: - pass - - -def _warn_on_old_setuptools(_version: str = setuptools.__version__) -> None: - if int(_version.split(".")[0]) < 61: - warnings.warn( - RuntimeWarning( - f""" -ERROR: setuptools=={_version} is used in combination with setuptools_scm>=8.x - -Your build configuration is incomplete and previously worked by accident! -setuptools_scm requires setuptools>=61 - -Suggested workaround if applicable: - - migrating from the deprecated setup_requires mechanism to pep517/518 - and using a pyproject.toml to declare build dependencies - which are reliably pre-installed before running the build tools -""" - ) - ) - - -_warn_on_old_setuptools() - - -def _assign_version(dist: setuptools.Distribution, config: Configuration) -> None: - maybe_version = _get_version(config) - - if maybe_version is None: - _version_missing(config) - else: - assert dist.metadata.version is None - dist.metadata.version = maybe_version - - -def version_keyword( - dist: setuptools.Distribution, - keyword: str, - value: bool | dict[str, Any] | Callable[[], dict[str, Any]], -) -> None: - if not value: - return - elif value is True: - value = {} - elif callable(value): - value = value() - assert ( - "dist_name" not in value - ), "dist_name may not be specified in the setup keyword " - dist_name: str | None = dist.metadata.name - if dist.metadata.version is not None: - warnings.warn(f"version of {dist_name} already set") - return - log.debug( - "version keyword %r", - vars(dist.metadata), - ) - log.debug("dist %s %s", id(dist), id(dist.metadata)) - - if dist_name is None: - dist_name = _read_dist_name_from_setup_cfg() - version_cls = value.pop("version_cls", None) - normalize = value.pop("normalize", True) - final_version = _validate_version_cls(version_cls, normalize) - config = Configuration(dist_name=dist_name, version_cls=final_version, **value) - _assign_version(dist, config) - - -def infer_version(dist: setuptools.Distribution) -> None: - log.debug( - "finalize hook %r", - vars(dist.metadata), - ) - log.debug("dist %s %s", id(dist), id(dist.metadata)) - if dist.metadata.version is not None: - return # metadata already added by hook - dist_name = dist.metadata.name - if dist_name is None: - dist_name = _read_dist_name_from_setup_cfg() - if not os.path.isfile("pyproject.toml"): - return - if dist_name == "setuptools_scm": - return - try: - config = Configuration.from_file(dist_name=dist_name) - except LookupError as e: - log.exception(e) - else: - _assign_version(dist, config) def data_from_mime(path: _t.PathT) -> dict[str, str]: diff --git a/testing/test_integration.py b/testing/test_integration.py index 06cc95c..9844272 100644 --- a/testing/test_integration.py +++ b/testing/test_integration.py @@ -10,8 +10,8 @@ import setuptools_scm._integration.setuptools from .wd_wrapper import WorkDir from setuptools_scm import PRETEND_KEY from setuptools_scm import PRETEND_KEY_NAMED +from setuptools_scm._integration.setuptools import _warn_on_old_setuptools from setuptools_scm._run_cmd import run -from setuptools_scm.integration import _warn_on_old_setuptools @pytest.fixture -- cgit v1.2.1 From 2e1ada5f75b74ea181c786550e9e858c02c66547 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Tue, 9 May 2023 12:52:35 +0200 Subject: typing fixup --- testing/test_regressions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/test_regressions.py b/testing/test_regressions.py index 018f37e..44cc3c0 100644 --- a/testing/test_regressions.py +++ b/testing/test_regressions.py @@ -90,7 +90,7 @@ def test_case_mismatch_on_windows_git(tmp_path: Path) -> None: def test_entrypoints_load() -> None: - d = distribution("setuptools-scm") # type: ignore [no-untyped-call] + d = distribution("setuptools-scm") eps = d.entry_points failed: list[tuple[EntryPoint, Exception]] = [] -- cgit v1.2.1