Skip to content

Commit 263dc5b

Browse files
committed
a few fixes and tests
1 parent ac3b6e1 commit 263dc5b

File tree

5 files changed

+71
-36
lines changed

5 files changed

+71
-36
lines changed

src/setuptools_scm/_config.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ def _check_tag_regex(value: str | Pattern[str] | None) -> Pattern[str]:
4141

4242
group_names = regex.groupindex.keys()
4343
if regex.groups == 0 or (regex.groups > 1 and "version" not in group_names):
44-
warnings.warn(
45-
"Expected tag_regex to contain a single match group or a group named"
44+
raise ValueError(
45+
f"Expected tag_regex '{regex.pattern}' to contain a single match group or a group named"
4646
" 'version' to identify the version part of any tag."
4747
)
4848

@@ -105,6 +105,9 @@ class Configuration:
105105

106106
parent: _t.PathT | None = None
107107

108+
def __post_init__(self):
109+
self.tag_regex = _check_tag_regex(self.tag_regex)
110+
108111
@property
109112
def absolute_root(self) -> str:
110113
return _check_absolute_root(self.root, self.relative_to)
@@ -139,13 +142,11 @@ def from_data(
139142
given configuration data
140143
create a config instance after validating tag regex/version class
141144
"""
142-
tag_regex = _check_tag_regex(data.pop("tag_regex", None))
143145
version_cls = _validate_version_cls(
144146
data.pop("version_cls", None), data.pop("normalize", True)
145147
)
146148
return cls(
147149
relative_to,
148150
version_cls=version_cls,
149-
tag_regex=tag_regex,
150151
**data,
151152
)

src/setuptools_scm/_entrypoints.py

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from typing import Callable
66
from typing import cast
77
from typing import Iterator
8-
from typing import overload
98
from typing import TYPE_CHECKING
109

1110
from . import _log
@@ -106,34 +105,20 @@ def _iter_version_schemes(
106105
yield scheme_value
107106

108107

109-
@overload
110108
def _call_version_scheme(
111109
version: version.ScmVersion,
112110
entrypoint: str,
113111
given_value: _t.VERSION_SCHEMES,
114-
default: str,
115-
) -> str:
116-
...
117-
118-
119-
@overload
120-
def _call_version_scheme(
121-
version: version.ScmVersion,
122-
entrypoint: str,
123-
given_value: _t.VERSION_SCHEMES,
124-
default: None,
125-
) -> str | None:
126-
...
127-
128-
129-
def _call_version_scheme(
130-
version: version.ScmVersion,
131-
entrypoint: str,
132-
given_value: _t.VERSION_SCHEMES,
133-
default: str | None,
112+
default: str | None = None,
134113
) -> str | None:
114+
found_any_implementation = False
135115
for scheme in _iter_version_schemes(entrypoint, given_value):
116+
found_any_implementation = True
136117
result = scheme(version)
137118
if result is not None:
138119
return result
139-
return default
120+
if not found_any_implementation:
121+
raise ValueError(f'Couldn\'t find any implementations for entrypoint "{entrypoint}" with value "{given_value}".')
122+
if default is not None:
123+
return default
124+
raise ValueError(f'None of the "{entrypoint}" entrypoints matching "{given_value}" returned a value.')

src/setuptools_scm/version.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,21 @@ def _parse_version_tag(
5555
log.debug(
5656
"key %s data %s, %s, %r", key, match.groupdict(), match.groups(), full
5757
)
58-
result = _TagDict(
59-
version=match.group(key),
60-
prefix=full[: match.start(key)],
61-
suffix=full[match.end(key) :],
62-
)
6358

64-
log.debug("tag %r parsed to %r", tag, result)
65-
assert result["version"]
66-
return result
59+
if version := match.group(key):
60+
result = _TagDict(
61+
version=version,
62+
prefix=full[: match.start(key)],
63+
suffix=full[match.end(key) :],
64+
)
65+
66+
log.debug("tag %r parsed to %r", tag, result)
67+
return result
68+
69+
raise ValueError(
70+
f'The tag_regex "{config.tag_regex.pattern}" matched tag "{tag}", however the matched'
71+
' group has no value.'
72+
)
6773
else:
6874
log.debug("tag %r did not parse", tag)
6975

@@ -428,8 +434,9 @@ def format_version(version: ScmVersion) -> str:
428434
if version.preformatted:
429435
assert isinstance(version.tag, str)
430436
return version.tag
437+
431438
main_version = _entrypoints._call_version_scheme(
432-
version, "setuptools_scm.version_scheme", version.config.version_scheme, None
439+
version, "setuptools_scm.version_scheme", version.config.version_scheme
433440
)
434441
log.debug("version %s", main_version)
435442
assert main_version is not None

testing/test_config.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,14 @@ def test_config_overrides(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> No
9797

9898
assert pristine.root != overridden.root
9999
assert pristine.fallback_root != overridden.fallback_root
100+
101+
@pytest.mark.parametrize(
102+
"tag_regex", [
103+
r".*",
104+
r"(.+)(.+)",
105+
r"((.*))",
106+
]
107+
)
108+
def test_config_bad_regex(tag_regex: str) -> None:
109+
with pytest.raises(ValueError, match=f"Expected tag_regex '{re.escape(tag_regex)}' to contain a single match group or a group named 'version' to identify the version part of any tag."):
110+
Configuration(tag_regex=tag_regex)

testing/test_version.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ def test_tag_regex1(tag: str, expected: str) -> None:
189189
assert result.tag.public == expected
190190

191191

192+
def test_regex_match_but_no_version() -> None:
193+
with pytest.raises(ValueError, match=r'The tag_regex "\(\?P<version>\)\.\*" matched tag "v1", however the matched group has no value'):
194+
meta("v1", config=replace(c, tag_regex="(?P<version>).*"))
195+
192196
@pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/471")
193197
def test_version_bump_bad() -> None:
194198
class YikesVersion:
@@ -410,3 +414,30 @@ def __repr__(self) -> str:
410414

411415
assert isinstance(scm_version.tag, MyVersion)
412416
assert str(scm_version.tag) == "Custom 1.0.0-foo"
417+
418+
@pytest.mark.parametrize(
419+
"config_key", ["version_scheme", "local_scheme"]
420+
)
421+
def test_no_matching_entrypoints(config_key: str) -> None:
422+
version = meta(
423+
"1.0",
424+
config=replace(
425+
c,
426+
**{
427+
config_key:"nonexistant"
428+
}
429+
),
430+
)
431+
with pytest.raises(ValueError, match=r'Couldn\'t find any implementations for entrypoint "setuptools_scm\..*?" with value "nonexistant"'):
432+
format_version(version)
433+
434+
def test_all_entrypoints_return_none() -> None:
435+
version = meta(
436+
"1.0",
437+
config=replace(
438+
c,
439+
version_scheme=lambda v: None,
440+
),
441+
)
442+
with pytest.raises(ValueError, match=r'None of the "setuptools_scm.version_scheme" entrypoints matching .*? returned a value.'):
443+
format_version(version)

0 commit comments

Comments
 (0)