Skip to content

Commit bcdbd24

Browse files
committed
fix(version): unshadow the resolver's fallback binding; test all branches
Completes #196 for current main: - _resolve_version bound the name `version` twice (importlib's function, then the _version.py string) — runtime-correct but mypy-illegal; use distinct names and drop a stale type-ignore. - tests/test_version_resolution.py covers every branch: metadata present, metadata missing -> setuptools_scm _version.py, nothing available -> "unknown" sentinel, and the module __getattr__. - omit the setuptools_scm-GENERATED src/rustfava/_version.py from coverage: the new version_file config makes builds emit it locally, and a generated file's unexecuted branches were failing the 100% gate. 566 passed, coverage 100.00%, mypy clean.
1 parent ce1a714 commit bcdbd24

3 files changed

Lines changed: 69 additions & 5 deletions

File tree

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ testpaths = ["tests"]
189189
[tool.coverage.run]
190190
branch = true
191191
omit = [
192+
# setuptools_scm-generated at build time (issue #191); not source code
193+
"src/rustfava/_version.py",
192194
"src/rustfava/beans/types.py",
193195
"src/rustfava/ext/auto_commit.py",
194196
# Rustledger integration - new code with many error handling paths

src/rustfava/__init__.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ def _resolve_version() -> str:
3232
previously 500'd the help page, see issue #191).
3333
"""
3434
try:
35-
from importlib.metadata import version
35+
from importlib.metadata import version as metadata_version
3636

37-
return version("rustfava")
38-
except Exception: # noqa: BLE001 - any metadata failure falls through
37+
return metadata_version("rustfava")
38+
except Exception: # noqa: BLE001, S110 - any metadata failure falls through
3939
pass
4040
try:
41-
from ._version import version # type: ignore[import-not-found]
41+
from ._version import version as scm_version
4242

43-
return version
43+
return str(scm_version)
4444
except Exception: # noqa: BLE001
4545
return "unknown"
4646

tests/test_version_resolution.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
"""Version resolution never raises, whatever the packaging situation.
2+
3+
Regression coverage for https://github.com/rustledger/rustfava/issues/191 —
4+
packaged builds (PyInstaller sidecar, ``.deb``) ship the source without
5+
``*.dist-info`` metadata, and the help page 500'd with
6+
``PackageNotFoundError`` on the unguarded ``importlib.metadata.version``
7+
call. ``rustfava._resolve_version`` falls back to the setuptools_scm-generated
8+
``_version.py`` and finally to a sentinel.
9+
"""
10+
11+
from __future__ import annotations
12+
13+
import importlib.metadata
14+
import sys
15+
import types
16+
17+
import pytest
18+
19+
import rustfava
20+
21+
22+
@pytest.fixture
23+
def no_dist_metadata(monkeypatch: pytest.MonkeyPatch) -> None:
24+
"""Make the ``importlib.metadata`` lookup fail like a packaged build."""
25+
26+
def raise_not_found(_name: str) -> str:
27+
raise importlib.metadata.PackageNotFoundError
28+
29+
monkeypatch.setattr(importlib.metadata, "version", raise_not_found)
30+
31+
32+
def test_installed_wheel_reports_metadata_version() -> None:
33+
"""The normal path: dist-info metadata is present (this test env)."""
34+
version = rustfava._resolve_version()
35+
assert version
36+
assert version != "unknown"
37+
38+
39+
@pytest.mark.usefixtures("no_dist_metadata")
40+
def test_falls_back_to_scm_version_file(
41+
monkeypatch: pytest.MonkeyPatch,
42+
) -> None:
43+
"""No metadata, but the setuptools_scm version file is bundled."""
44+
fake = types.ModuleType("rustfava._version")
45+
fake.version = "1.2.3+packaged" # type: ignore[attr-defined]
46+
monkeypatch.setitem(sys.modules, "rustfava._version", fake)
47+
assert rustfava._resolve_version() == "1.2.3+packaged"
48+
49+
50+
@pytest.mark.usefixtures("no_dist_metadata")
51+
def test_falls_back_to_sentinel_when_nothing_available(
52+
monkeypatch: pytest.MonkeyPatch,
53+
) -> None:
54+
"""Neither metadata nor a version file: a sentinel, never an exception."""
55+
monkeypatch.setitem(sys.modules, "rustfava._version", None)
56+
assert rustfava._resolve_version() == "unknown"
57+
58+
59+
def test_module_getattr_serves_version_and_rejects_others() -> None:
60+
assert rustfava.__version__ == rustfava._resolve_version()
61+
with pytest.raises(AttributeError):
62+
_ = rustfava.no_such_attribute

0 commit comments

Comments
 (0)