Hey.
I’m having a bit of a hard time finding a proper solution for the following:
I’m writing a package, which needs to find out its own version, which I don’t want to have hard-coded (at least not manually, what would be okay is, if setuptools_scm writes the version to a file, bu only for builds - i.e. I don’t want it hardcoded within my git history).
setuptools and setuptools_scm are used for building and the whole thing is in git.
Oh and, while setuptools_scm is a build dependency, I would rather have it only an optional runtime dependency.
Last but not least, if my git repo has local changes (like since the the most recent tag) I’d like to have that reflected in the version.
What seems recommended is using importlib.metadata.version("my-project"), but as far as I understand this has numerous downsides:
- At least if I look at it first (and it succeeds), I’ll never see any local changes reflected in the version - at least not since the last install (including an
--editableone). - Consider I have an e.g. system-wide installation of a build of the package, but my code is executed from some working copy, it seems
importlib.metadata.version()would simply take the system-wide installation (or wherever it finds one).
So my idea was to use setuptools_scm’s:
[tool.setuptools_scm]
version_file = "src/my_project/_version.py"
which would of course only be included when I actually build the package (including an --editable one), but then I can be sure that it’s actually “my” true version, right?
With that I’d have something like:
try:
from ._version import __version__
except ModuleNotFoundError:
pass
I ignore when it’s not found, cause that might simply be the case when I’m running from my git working area without an --editable installation.
Now how to get the dynamic determination of the version via setuptools_scm?
I thought about doing something like the following before falling back to using _version.py (it has to be that order, because if my git working dir is also an --editable, _version.py would exist):
if WITH_SETUPTOOLS_SCM:
try:
__version__ = setuptools_scm.get_version(root="../..", relative_to=__file__)
print(f"from git {__version__}")
except LookupError:
pass
First I try importing setuptools_scm, if that succeeds (indicated by WITH_SETUPTOOLS_SCM) I try get_version.
The problems I can’t really think of a solution are the following:
- If
setuptools_scmisn’t available (at runtime), I won’t notice if it falls back to using_version.pyin an--editableinstall. I could perhaps try to check for a../../.gitbut that seems brittle. - While very unlikely, but if for some reason the
../..of an actual e.g. system-wide installation would contain a(nother).git, I might pick up the wrong version.
Maybe there are even other issues I don’t see.
Any ideas how this could be done properly?
Thanks,
Philippe