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.