- Notifications
You must be signed in to change notification settings - Fork1
Construct Checks for Optional Dependencies
License
GalacticDynamics/optional_dependencies
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
pip install optional_dependencies
This package allows for easy construction of checks for optional dependencies.As every Python project can have its own unique set of optional dependencies,optional_dependencies
provides theenum.Enum
base classOptionalDependencyEnum
for enumerating the optional dependencies.
A constructedOptionalDependencyEnum
enum.Enum
has members thatare the package names with values that are either apackaging.Version
or aNOT_INSTALLED
sentinel value.
As an example:
# Note that `auto` is a convenience re-export of enum.autofromoptional_dependenciesimportOptionalDependencyEnum,autoclassOptDeps(OptionalDependencyEnum):PACKAGING=auto()THIS_IS_NOT_INSTALLED=auto()OptDeps.PACKAGING# <OptDeps.PACKAGING: <Version('...')>>OptDeps.PACKAGING.installed# TrueOptDeps.PACKAGING.version# <Version('...')>OptDeps.THIS_IS_NOT_INSTALLED# <OptDeps.THIS_IS_NOT_A_PACKAGE: <InstalledState.NOT_INSTALLED: False>>
enum.auto
on aOptionalDependencyEnum
passes version parsing topackaging.utils.canonicalize_name
thenimportlib.metadata.version
thenpackaging.version.parse
. If the package cannot be foundthen it is consideredInstalledState.NOT_INSTALLED
InstalledState.NOT_INSTALLED
is anenum.Enum
member that has atruthy value ofFalse
. This can be useful for boolean checks, aspackaging.Version
always has a truthy value ofTrue
.
ifnotOptDeps.THIS_IS_NOT_INSTALLED:print("NOT_INSTALLED has a truthy value of False")# NOT_INSTALLED has a truthy value of FalseifOptDeps.PACKAGING:# truthy value of `True`print(OptDeps.PACKAGING)# OptDeps.PACKAGING
Sometimes the high-level API is insufficient to determine whether an optionaldependency is present. For example, this can sometimes happen with compiledpackages, where the package appears to be installed, but something is wrong. Inthese cases you can customize the enum members using the low-level API.
The low-level functions are:
optional_dependencies.utils.is_installed(pkg_name: str, /) -> bool
: aregularized form ofimportlib.util.find_spec
.optional_dependencies.utils.get_version(pkg_name: str, /) -> Version | Literal[InstalledState.NOT_INSTALLED]
:for getting thepackaging.Version
of a package if it isinstalled, or returningNOT_INSTALLED
otherwise.optional_dependencies.utils.chain_checks(version: Version, /, *checks: bool)
:for chaining checks together and ensuring the returned value is still apackaging.Version
orNOT_INSTALLED
.
As a pseudo-code example of a package with c-compiled code that :
fromoptional_dependencies.utilsimportis_installed,get_version,chain_checks# A subpackage needs to be checked.chain_checks(get_version("package1"),is_installed("package1.subpackage"))# <Version('...')># This package is not installed correctlychain_checks(get_version("package2"),is_installed("package2.subpackage"))# <InstalledState.NOT_INSTALLED: False>
The low-level API can be used withOptionalDependencyEnum
classOptDeps(OptionalDependencyEnum):PACKAGING=auto()THIS_IS_NOT_INSTALLED=chain_checks(get_version("package2"),is_installed("package2.subpackage") )
If you found this library to be useful and want to support the development andmaintenance of lower-level code libraries for the scientific community, pleaseconsider citing this work.
We welcome contributions!
About
Construct Checks for Optional Dependencies