The version in my project is stored in pyproject.toml
:
[tool.poetry]
name = "package_name"
version = "1.2.3"
# ...
I now want to have a __version__
in package_name/__init__.py
as well and the general suggestion seems to be:
import importlib_metadata
__version__ = importlib_metadata.version('package_name')
But that doesn't work for me. The moment I run my unittests I get this error:
importlib_metadata.PackageNotFoundError: No package metadata was found for package_name
How can I make this work during development?
Having a __version__
attribute in the import package (i.e. in package_name/__init__.py
) is an outdated practice. The current best practice is to rely on the distribution package's metadata with the help of importlib.metadata
from Python's standard library.
So for example if in my application I want to get the version string for your library, instead of writing this in my application:
import package_name # Your library's "import package" name
version = package_name.__version__
I would write this:
import importlib.metadata
lib_name = "package_name" # Your library's "distribution package" name
lib_version = importlib.metadata.version(lib_name)
For this to work I need to be sure that your library package_name
is correctly installed.
Now if in my application I want to show my application's own version string, it is the same principle:
import importlib.metadata
app_name = "my-app-name" # My app's "distribution package" name
app_version = importlib.metadata.version(app_name)
lib_name = "package_name" # Your library's "distribution package" name
lib_version = importlib.metadata.version(lib_name)
print(f"This is {app_name} version {app_version}, it uses {lib_name} version {lib_version}.")
As mentioned earlier I have to make sure that all the distribution packages (application and libraries) are correctly installed. So-called "editable" installations are perfectly fine.
If my application is managed by Poetry, then Poetry installs my application as editable anyway. The important thing to keep in mind is that it is necessary to re-install after every modification in the relevant parts of pyproject.toml
. If I modify the version string of my application in pyproject.toml
(or with poetry version
) then I need to re-run poetry install
for the new version string to be installed in the metadata and take effect, even if I'm still actively developping the project.