Some thoughts come to mind in catching up on this thread (thanks for the ping @CAM-Gerlach!).
First off, the stdlib documentation for importlib.metadata
has room for a lot of improvements. It shouldn’t be called Using importlib.metadata
. The subject is probably complex enough for a Diataxis-like approach, with much clearer separation between how-to and reference guides. It also needs to be much more precise in its language, defining the basic terminology and objects involved, etc. For example, what does “package” refer to in this sentence, an importable package/module, or a distribution?
Let’s say you wanted to get the version string for a package you’ve installed using
pip
.
I don’t even think “distribution” is defined in the docs.
It seems to me that maybe we need a higher level API which helps with this distinction. It’s too easy to not fully understand the differences between importable packages and distribution packages, and it’s also easy to get misled when maybe the majority of your use of importlib.metadata.version()
gives you what you want, then you get an error, and now you don’t trust the API so you fall back to package.__version__
. It would be subtle and take some thinking to come up with the right abstraction and API.
Using
__version__
certainly has substantial value in specific scenarios, such as troubleshooting, development/editable installs, and quick interactive use.
I think we need to keep in mind there are two use cases for __version__
. One is on the producer side (more below) and one is on the consumer side (i.e. inspecting and acting on import foo; foo.__version__
. My recommendations above about writing better docs and an API is for the consumer side.
This is a totally understandable confusion, given the lack of definition in the stdlib docs as mentioned above.
I do this, and then pull this into the distribution version via my pyproject.toml
:
[project]
dynamic = ['version']
[tool.pdm]
version = {from = 'src/public/__init__.py'}
I mostly like this, except that I do sometimes forget to bump __init__.py
. I also sometimes forget to git tag
my releases, so I’m not sure that approach would be any better
PEP 396 was written in a different era so it shouldn’t be revived. But maybe analyzing the problem in terms of API consumers vs library producers would lead to a better understanding about what, if anything still needs to be done to make the overall experience easier to understand and use.