Skip to main content

optional_dependencies

Construct Checks for Optional Dependencies

Installation

PyPI version PyPI platforms

pip install optional_dependencies

Documentation

High-Level API

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 the enum.Enum base class OptionalDependencyEnum for enumerating the optional dependencies.

A constructed OptionalDependencyEnum enum.Enum has members that are the package names with values that are either a packaging.Version or a NOT_INSTALLED sentinel value.

As an example:

# Note that `auto` is a convenience re-export of enum.auto
from optional_dependencies import OptionalDependencyEnum, auto


class OptDeps(OptionalDependencyEnum):
    PACKAGING = auto()
    THIS_IS_NOT_INSTALLED = auto()


OptDeps.PACKAGING
# <OptDeps.PACKAGING: <Version('...')>>

OptDeps.PACKAGING.installed
# True

OptDeps.PACKAGING.version
# <Version('...')>

OptDeps.THIS_IS_NOT_INSTALLED
# <OptDeps.THIS_IS_NOT_A_PACKAGE: <InstalledState.NOT_INSTALLED: False>>

enum.auto on a OptionalDependencyEnum passes version parsing to packaging.utils.canonicalize_name then importlib.metadata.version then packaging.version.parse. If the package cannot be found then it is considered InstalledState.NOT_INSTALLED

Every member stays its own member, whatever its value. This matters because those values collide readily: any two dependencies that are both missing share the NOT_INSTALLED sentinel, and distributions released together share a version number. A plain enum.Enum folds equal-valued members into aliases of whichever was declared first, which would make OptDeps.SECOND.installed report the first package's state.

class OptDeps(OptionalDependencyEnum):
    NOT_A_PACKAGE = auto()
    ALSO_NOT_A_PACKAGE = auto()


OptDeps.ALSO_NOT_A_PACKAGE.name
# 'ALSO_NOT_A_PACKAGE'

OptDeps.NOT_A_PACKAGE is OptDeps.ALSO_NOT_A_PACKAGE
# False

InstalledState.NOT_INSTALLED is an enum.Enum member that has a truthy value of False. This can be useful for boolean checks, as packaging.Version always has a truthy value of True.

if not OptDeps.THIS_IS_NOT_INSTALLED:
    print("NOT_INSTALLED has a truthy value of False")
# NOT_INSTALLED has a truthy value of False

if OptDeps.PACKAGING:  # truthy value of `True`
    print(OptDeps.PACKAGING)
# OptDeps.PACKAGING

Low-Level API

Sometimes the high-level API is insufficient to determine whether an optional dependency is present. For example, this can sometimes happen with compiled packages, where the package appears to be installed, but something is wrong. In these 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: a regularized form of importlib.util.find_spec.

  • optional_dependencies.utils.get_version(pkg_name: str, /) -> Version | Literal[InstalledState.NOT_INSTALLED]: for getting the packaging.Version of a package if it is installed, or returning NOT_INSTALLED otherwise.

  • optional_dependencies.utils.chain_checks(version: Version, /, *checks: bool): for chaining checks together and ensuring the returned value is still a packaging.Version or NOT_INSTALLED.

As a pseudo-code example of a package with c-compiled code that :

from optional_dependencies.utils import is_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 correctly
chain_checks(get_version("package2"), is_installed("package2.subpackage"))
# <InstalledState.NOT_INSTALLED: False>

The low-level API can be used with OptionalDependencyEnum

class OptDeps(OptionalDependencyEnum):
    PACKAGING = auto()
    THIS_IS_NOT_INSTALLED = chain_checks(
        get_version("package2"), is_installed("package2.subpackage")
    )

Citation

DOI

If you found this library to be useful and want to support the development and maintenance of lower-level code libraries for the scientific community, please consider citing this work.

Development

codecov Actions Status

We welcome contributions!

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

optional_dependencies-0.4.1.tar.gz (85.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

optional_dependencies-0.4.1-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

Details for the file optional_dependencies-0.4.1.tar.gz.

File metadata

  • Download URL: optional_dependencies-0.4.1.tar.gz
  • Upload date:
  • Size: 85.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for optional_dependencies-0.4.1.tar.gz
Algorithm Hash digest
SHA256 8f71acbef015b08945e78fa531630290375d089d06de1d475567634991cb8160
MD5 3a96f9f4d311e74a1a28b6389298076d
BLAKE2b-256 a1428344ac009b7ba239b5bd82387aa5ab459dd7f706b80d73692ca6e31a2c95

See more details on using hashes here.

Provenance

The following attestation bundles were made for optional_dependencies-0.4.1.tar.gz:

Publisher: cd.yml on GalacticDynamics/optional_dependencies

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file optional_dependencies-0.4.1-py3-none-any.whl.

File metadata

File hashes

Hashes for optional_dependencies-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f1ceb198a9154f6bdbf6295df663b4b91edebe5dc3d8678c03df3fbb985c1545
MD5 6152a5b955e13a27132c18ca248529bf
BLAKE2b-256 65a37810502242eba30a288c0e79c5a395c1ec6ed41a4eab6e5b3c8e3cf4ee20

See more details on using hashes here.

Provenance

The following attestation bundles were made for optional_dependencies-0.4.1-py3-none-any.whl:

Publisher: cd.yml on GalacticDynamics/optional_dependencies

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page