Skip to content

Read the package version from installed metadata - #200

Open
vahid-ahmadi wants to merge 2 commits into
mainfrom
fix-version-metadata
Open

vahid-ahmadi wants to merge 2 commits into
mainfrom
fix-version-metadata

Conversation

@vahid-ahmadi

Copy link
Copy Markdown
Contributor

microimpute/__init__.py hardcoded __version__ = "1.1.2" while pyproject.toml declared 3.1.1 — two major versions apart, because .github/bump_version.py only rewrites pyproject.toml.

Reading from importlib.metadata gives one source of truth, so the two cannot drift again:

>>> import microimpute; microimpute.__version__
'3.1.1'

Falls back to "unknown" when running from a source tree with no install.

Worth fixing ahead of the JOSS submission in the paper PR: a reviewer checks that the archived release version matches the software, and microimpute.__version__ was reporting the wrong one.

@vercel

vercel Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
microimpute-dashboard Ready Ready Preview Sep 21, 2026 12:29pm UTC

@vahid-ahmadi

Copy link
Copy Markdown
Contributor Author

Reviewed with a fresh pass. The bug is real — origin/main's __init__.py declares __version__ = "1.1.2" while pyproject.toml says 3.1.1 — and the fix works: installed, import microimpute; print(microimpute.__version__) gives 3.1.1. The PackageNotFoundError branch is reached correctly from an uninstalled source tree.

To do

  • "unknown" is not a PEP 440 version and will crash consumers. From a clean uninstalled tree (after rm -rf microimpute.egg-info) __version__ is 'unknown', so any consumer doing packaging.version.parse(microimpute.__version__) or a >= comparison raises InvalidVersion. Use "0.0.0+unknown", which parses, or fall back to reading version from pyproject.toml.
  • No test at all. Nothing asserts __version__ is non-empty, matches pyproject.toml, or that the fallback branch is reached — which is exactly the regression class this PR exists to fix. Add one asserting microimpute.__version__ == importlib.metadata.version("microimpute"), and a monkeypatch test for the PackageNotFoundError path.

Optional

  • The # Python 3.8+ comment is misleading — requires-python is >=3.12,<3.15, so the guard reads as if it supported versions the package does not.
  • Worth a one-line comment that a stale *.egg-info in a developer checkout silently supplies a wrong version. I hit this by accident: a leftover microimpute.egg-info on sys.path made importlib.metadata.distribution("microimpute") resolve to it, reporting a version built from an older pyproject.toml.

Not this PR's fault

The Lint failure is inherited from main — ruff format --check . reports the same five untouched docs files here as on main. #218 fixes it; nothing needed here.

vahid-ahmadi and others added 2 commits September 21, 2026 13:27
__init__.py carried a hardcoded 1.1.2 while pyproject.toml was at 3.1.1, two
major versions apart, because the version bump script only updates
pyproject.toml. Reading from importlib.metadata means there is one source of
truth and the two cannot drift again.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The fallback was 'unknown', which packaging.version.parse rejects, so a
consumer comparing versions would raise InvalidVersion in exactly the
uninstalled-source-tree case the fallback exists for. Now 0.0.0+unknown.

Adds the tests the PR was missing: that __version__ matches the
installed distribution, that both it and the fallback parse, and that
the fallback branch is reached when the distribution is absent.

Drops the '# Python 3.8+' comment, which named versions this package
does not support (requires-python is >=3.12,<3.15).
@vahid-ahmadi

Copy link
Copy Markdown
Contributor Author

Rebased onto current main, which carries #218's lint repair — the Lint failure here was that shared one, not anything in this branch.

Also addressed the review points:

  • The fallback is now "0.0.0+unknown" rather than "unknown". The old value is not PEP 440, so packaging.version.parse(microimpute.__version__) raised InvalidVersion in exactly the uninstalled-source-tree case the fallback exists for.
  • Added tests/test_version.py: that __version__ matches the installed distribution, that both it and the fallback parse, and that the fallback branch is reached when the distribution is absent. The PR had no test at all, which is the same regression class it fixes.
  • Dropped the # Python 3.8+ comment, which named versions this package does not support (requires-python is >=3.12,<3.15).

ruff format --check clean on 77 files, version resolves to 3.1.3 on the rebased head.

This branch was successfully deployed

1 active deployment
Preview — 2edf0f6d Deployed Sep 21, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant