Python's argparse
module action to define CLI version with a delayed
call to importlib.metadata.version
only when --version
argument
is passed.
When you use importlib.metadata
for adding the version to a CLI utility,
you need to import importlib.metadata
and call
importlib.metadata.version("<your-package>")
at initialization time.
If you only want to execute other parts of the CLI
(eg. like passing the option --help
), importlib.metadata
will be
imported too even when is not needed at all.
The problem is easily fixed by this module.
import argparse
from importlib_metadata_argparse_version import ImportlibMetadataVersionAction
parser = argparse.ArgumentParser()
parser.add_argument(
"-v", "--version",
action=ImportlibMetadataVersionAction,
version_from="your-package-name",
)
This is a rough equivalent to something like:
import argparse
import importlib.metadata
parser = argparse.ArgumentParser()
parser.add_argument(
"-v", "--version",
action="version",
version=importlib_metadata.version("your-package-name"),
)
...but with the difference that importlib.metadata
will only be
imported when you call --version
, so it is more efficient.
When using ImportlibMetadataVersionAction
the version
kwarg
accepts %(version)s
as a placeholder like %(prog)s
. So you
can write something like this to display the program name before the
version:
parser.add_argument(
"-v", "--version",
action=ImportlibMetadataVersionAction,
version_from="your-package-name",
version="%(prog)s %(version)s",
)
# or
parser.version = "%(prog)s %(version)s"
parser.add_argument(
"-v", "--version",
action=ImportlibMetadataVersionAction,
version_from="your-package-name",
)
And the version
kwarg becomes optional, being "%(version)s"
the default value.
The argument version_from
can be ommitted and the package name
will be inferred from the caller package location:
parser.add_argument(
"-v", "--version",
action=ImportlibMetadataVersionAction,
)
If you forget to define the kwarg version_from
in the argument or the
inferred package name is not found, an exception will be raised at
initialization time. Python's argparse
built-in "version"
action raises
an AttributeError
only when you call your program with --version
, which
is unsafe because could lead you to forget to define the version
passing
the error unnoticed until you test it manually.