Tekay37
Tekay37

Reputation: 559

How do I embed the version from pyproject.toml so my package can use it?

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?

Upvotes: 5

Views: 2113

Answers (2)

sinoroc
sinoroc

Reputation: 22438

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.

Upvotes: 2

You can try add this to __init__:

from ._version import version as __version__

source

Upvotes: -3

Related Questions