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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## v9.0.2

### Fixed

- fix #1184: in case setuptools-scm is a indirect dependency and no pyproject.toml section exists - don't infer the version


## v9.0.1

Expand Down
9 changes: 6 additions & 3 deletions src/setuptools_scm/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ def from_file(
dist_name: str | None = None,
missing_file_ok: bool = False,
missing_section_ok: bool = False,
pyproject_data: PyProjectData | None = None,
**kwargs: Any,
) -> Configuration:
"""
Expand All @@ -291,9 +292,10 @@ def from_file(
"""

try:
pyproject_data = _read_pyproject(
Path(name), missing_section_ok=missing_section_ok
)
if pyproject_data is None:
pyproject_data = _read_pyproject(
Path(name), missing_section_ok=missing_section_ok
)
except FileNotFoundError:
if missing_file_ok:
log.warning("File %s not found, using empty configuration", name)
Expand All @@ -303,6 +305,7 @@ def from_file(
project={},
section={},
is_required=False,
section_present=False,
)
else:
raise
Expand Down
7 changes: 6 additions & 1 deletion src/setuptools_scm/_integration/pyproject_reading.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class PyProjectData(NamedTuple):
project: TOML_RESULT
section: TOML_RESULT
is_required: bool
section_present: bool

@property
def project_name(self) -> str | None:
Expand Down Expand Up @@ -55,6 +56,7 @@ def read_pyproject(

try:
section = defn.get("tool", {})[tool_name]
section_present = True
except LookupError as e:
if not is_required and not missing_section_ok:
# Enhanced error message that mentions both configuration options
Expand All @@ -69,9 +71,12 @@ def read_pyproject(
error = f"{path} does not contain a tool.{tool_name} section"
log.warning("toml section missing %r", error, exc_info=True)
section = {}
section_present = False

project = defn.get("project", {})
return PyProjectData(path, tool_name, project, section, is_required)
return PyProjectData(
path, tool_name, project, section, is_required, section_present
)


def get_args_for_pyproject(
Expand Down
16 changes: 15 additions & 1 deletion src/setuptools_scm/_integration/setuptools.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import warnings

from pathlib import Path
from typing import Any
from typing import Callable

Expand Down Expand Up @@ -149,8 +150,21 @@ def infer_version(dist: setuptools.Distribution) -> None:
if dist_name == "setuptools-scm":
return

# Check if setuptools-scm is configured before proceeding
try:
config = _config.Configuration.from_file(dist_name=dist_name)
from .pyproject_reading import read_pyproject

pyproject_data = read_pyproject(Path("pyproject.toml"), missing_section_ok=True)
# Only proceed if setuptools-scm is either in build_requires or has a tool section
if not pyproject_data.is_required and not pyproject_data.section_present:
return # No setuptools-scm configuration, silently return
except (FileNotFoundError, LookupError):
return # No pyproject.toml or other issues, silently return

try:
config = _config.Configuration.from_file(
dist_name=dist_name, pyproject_data=pyproject_data
)
except LookupError as e:
log.info(e, exc_info=True)
else:
Expand Down
119 changes: 119 additions & 0 deletions testing/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,125 @@ def test_integration_function_call_order(
)


def test_infer_version_with_build_requires_no_tool_section(
wd: WorkDir, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test that infer_version works when setuptools-scm is in build_requires but no [tool.setuptools_scm] section"""
if sys.version_info < (3, 11):
pytest.importorskip("tomli")

# Set up a git repository with a tag
wd.commit_testfile("test")
wd("git tag 1.0.0")
monkeypatch.chdir(wd.cwd)

# Create a pyproject.toml file with setuptools_scm in build-system.requires but NO [tool.setuptools_scm] section
pyproject_content = """
[build-system]
requires = ["setuptools>=80", "setuptools_scm>=8"]
build-backend = "setuptools.build_meta"

[project]
name = "test-package-infer-version"
dynamic = ["version"]
"""
wd.write("pyproject.toml", pyproject_content)

import setuptools

from setuptools_scm._integration.setuptools import infer_version

# Create distribution
dist = setuptools.Distribution({"name": "test-package-infer-version"})

# Call infer_version - this should work because setuptools_scm is in build-system.requires
infer_version(dist)

# Verify that version was set
assert dist.metadata.version is not None
assert dist.metadata.version == "1.0.0"

# Verify that the marker was set
assert getattr(dist, "_setuptools_scm_version_set_by_infer", False) is True


def test_infer_version_with_build_requires_dash_variant_no_tool_section(
wd: WorkDir, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test that infer_version works when setuptools-scm (dash variant) is in build_requires but no [tool.setuptools_scm] section"""
if sys.version_info < (3, 11):
pytest.importorskip("tomli")

# Set up a git repository with a tag
wd.commit_testfile("test")
wd("git tag 1.0.0")
monkeypatch.chdir(wd.cwd)

# Create a pyproject.toml file with setuptools-scm (dash variant) in build-system.requires but NO [tool.setuptools_scm] section
pyproject_content = """
[build-system]
requires = ["setuptools>=80", "setuptools-scm>=8"]
build-backend = "setuptools.build_meta"

[project]
name = "test-package-infer-version-dash"
dynamic = ["version"]
"""
wd.write("pyproject.toml", pyproject_content)

import setuptools

from setuptools_scm._integration.setuptools import infer_version

# Create distribution
dist = setuptools.Distribution({"name": "test-package-infer-version-dash"})

# Call infer_version - this should work because setuptools-scm is in build-system.requires
infer_version(dist)

# Verify that version was set
assert dist.metadata.version is not None
assert dist.metadata.version == "1.0.0"

# Verify that the marker was set
assert getattr(dist, "_setuptools_scm_version_set_by_infer", False) is True


def test_infer_version_without_build_requires_no_tool_section_silently_returns(
wd: WorkDir, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test that infer_version silently returns when setuptools-scm is NOT in build_requires and no [tool.setuptools_scm] section"""
if sys.version_info < (3, 11):
pytest.importorskip("tomli")

# Set up a git repository with a tag
wd.commit_testfile("test")
wd("git tag 1.0.0")
monkeypatch.chdir(wd.cwd)

# Create a pyproject.toml file WITHOUT setuptools_scm in build-system.requires and NO [tool.setuptools_scm] section
pyproject_content = """
[build-system]
requires = ["setuptools>=80", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "test-package-no-scm"
dynamic = ["version"]
"""
wd.write("pyproject.toml", pyproject_content)

import setuptools

from setuptools_scm._integration.setuptools import infer_version

# Create distribution
dist = setuptools.Distribution({"name": "test-package-no-scm"})

infer_version(dist)
assert dist.metadata.version is None


def test_version_keyword_no_scm_dependency_works(
wd: WorkDir, monkeypatch: pytest.MonkeyPatch
) -> None:
Expand Down
Loading