Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# Changelog

## v8.2.1
## v8.3.0

### Fixed

- fix #1013: use modern importlib_metadata in all cases to dedup distribution objects that must shadow based on pythonpath priority
starting with python 3.10 this is part of python itself

## v8.2.1 (yanked due to legacy python issues)

### Fixed

Expand Down
17 changes: 15 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ build-backend = "_own_version_helper:build_meta"
requires = [
"setuptools>=61",
'tomli<=2.0.2; python_version < "3.11"',
'importlib-metadata>=4.6; python_version < "3.10"',
]
backend-path = [
".",
Expand Down Expand Up @@ -43,9 +44,10 @@ dynamic = [
dependencies = [
"packaging>=20",
# https://github.com/pypa/setuptools-scm/issues/1112 - re-pin in a breaking release
"setuptools", # >=61",
"setuptools", # >= 61",
'tomli>=1; python_version < "3.11"',
'typing-extensions; python_version < "3.10"',
'importlib-metadata>=4.6; python_version < "3.10"',
]
[project.optional-dependencies]
docs = [
Expand All @@ -69,38 +71,49 @@ test = [
]
toml = [
]

[project.urls]
documentation = "https://setuptools-scm.readthedocs.io/"
repository = "https://github.com/pypa/setuptools-scm/"

[project.entry-points."distutils.setup_keywords"]
use_scm_version = "setuptools_scm._integration.setuptools:version_keyword"

[project.entry-points."pipx.run"]
setuptools-scm = "setuptools_scm._cli:main"
setuptools_scm = "setuptools_scm._cli:main"

[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.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"

[project.entry-points."setuptools_scm.files_command_fallback"]
".git_archival.txt" = "setuptools_scm._file_finders.git:git_archive_find_files"
".hg_archival.txt" = "setuptools_scm._file_finders.hg:hg_archive_find_files"

[project.entry-points."setuptools_scm.local_scheme"]
dirty-tag = "setuptools_scm.version:get_local_dirty_tag"
no-local-version = "setuptools_scm.version:get_no_local_node"
node-and-date = "setuptools_scm.version:get_local_node_and_date"
node-and-timestamp = "setuptools_scm.version:get_local_node_and_timestamp"

[project.entry-points."setuptools_scm.parse_scm"]
".git" = "setuptools_scm.git:parse"
".hg" = "setuptools_scm.hg:parse"

[project.entry-points."setuptools_scm.parse_scm_fallback"]
".git_archival.txt" = "setuptools_scm.git:parse_archival"
".hg_archival.txt" = "setuptools_scm.hg:parse_archival"
PKG-INFO = "setuptools_scm.fallbacks:parse_pkginfo"
"pyproject.toml" = "setuptools_scm.fallbacks:fallback_version"
"setup.py" = "setuptools_scm.fallbacks:fallback_version"

[project.entry-points."setuptools_scm.version_scheme"]
"calver-by-date" = "setuptools_scm.version:calver_by_date"
"guess-next-dev" = "setuptools_scm.version:guess_next_dev_version"
Expand Down Expand Up @@ -133,7 +146,7 @@ order-by-type = true
ignore = ["PP305", "GH103", "GH212", "MY100", "PC111", "PC160", "PC170", "PC180", "PC901"]

[tool.pytest.ini_options]
minversion = "7"
minversion = "8"
testpaths = ["testing"]
filterwarnings = [
"error",
Expand Down
35 changes: 5 additions & 30 deletions src/setuptools_scm/_entrypoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,12 @@
from ._config import Configuration
from ._config import ParseFunction


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)

def entry_points(group: str) -> EntryPoints:
return EntryPoints(legacy_entry_points()[group])

from importlib_metadata import EntryPoint as EntryPoint
from importlib_metadata import entry_points as entry_points
else:
from importlib.metadata import EntryPoints
from importlib.metadata import entry_points
from importlib.metadata import EntryPoint as EntryPoint
from importlib.metadata import entry_points as entry_points


log = _log.log.getChild("entrypoints")
Expand All @@ -61,15 +43,8 @@ def version_from_entrypoint(
return None


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 iter(res)


def _get_ep(group: str, name: str) -> Any | None:
for ep in iter_entry_points(group, name):
for ep in entry_points(group=group, name=name):
log.debug("ep found: %s", ep.name)
return ep.load()
return None
Expand Down
13 changes: 7 additions & 6 deletions src/setuptools_scm/_file_finders/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from __future__ import annotations

import itertools
import os

from typing import TYPE_CHECKING
from typing import Callable

from .. import _log
from .. import _types as _t
from .._entrypoints import iter_entry_points
from .._entrypoints import EntryPoint
from .._entrypoints import entry_points
from .pathtools import norm_real

if TYPE_CHECKING:
Expand Down Expand Up @@ -102,10 +102,11 @@ def is_toplevel_acceptable(toplevel: str | None) -> TypeGuard[str]:


def find_files(path: _t.PathT = "") -> list[str]:
for ep in itertools.chain(
iter_entry_points("setuptools_scm.files_command"),
iter_entry_points("setuptools_scm.files_command_fallback"),
):
eps: list[EntryPoint] = [
*entry_points(group="setuptools_scm.files_command"),
*entry_points(group="setuptools_scm.files_command_fallback"),
]
for ep in eps:
command: Callable[[_t.PathT], list[str]] = ep.load()
res: list[str] = command(path)
if res:
Expand Down
3 changes: 1 addition & 2 deletions src/setuptools_scm/discover.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,9 @@ def iter_matching_entrypoints(
"""

log.debug("looking for ep %s in %s", entrypoint, root)
from ._entrypoints import iter_entry_points

for wd in walk_potential_roots(root, config.search_parent_directories):
for ep in iter_entry_points(entrypoint):
for ep in _entrypoints.entry_points(group=entrypoint):
if ep.value in _BLOCKED_EP_TARGETS:
continue
if match_entrypoint(wd, ep.name):
Expand Down
7 changes: 3 additions & 4 deletions src/setuptools_scm/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,10 @@ def callable_or_entrypoint(group: str, callable_or_name: str | Any) -> Any:

if callable(callable_or_name):
return callable_or_name
from ._entrypoints import iter_entry_points

for ep in iter_entry_points(group, callable_or_name):
log.debug("ep found: %s", ep.name)
return ep.load()
from ._entrypoints import _get_ep

return _get_ep(group, callable_or_name)


def tag_to_version(
Expand Down
Loading