Source code for omnipath.constants._constants

from abc import ABC, ABCMeta
from enum import Enum, EnumMeta, unique
from typing import Any, Callable
from functools import wraps


def _pretty_raise_enum(cls: EnumMeta, fun: Callable) -> Callable:
    @wraps(fun)
    def wrapper(*args, **kwargs) -> Enum:
        try:
            return fun(*args, **kwargs)
        except ValueError as e:
            _cls, value, *_ = args
            e.args = (cls._format(value),)
            raise e

    if not issubclass(cls, ErrorFormatter):
        raise TypeError(f"Class `{cls}` must be subtype of `ErrorFormatter`.")
    elif not len(cls.__members__):
        # empty enum, for class hierarchy
        return fun

    return wrapper


class NoValue(Enum):
    """Enumeration which hides its :attr:`value`."""

    def __repr__(self):
        return f"<{self.__class__.__name__}.{self.name}>"


class ErrorFormatter(ABC):  # noqa: D101
    __error_format__ = "Invalid value `{}` for `{}`. Valid options are: `{}`."

    @classmethod
    def _format(cls, value: Any) -> str:
        """Format the error message for invalid ``value``."""
        return cls.__error_format__.format(
            value, cls.__name__, [m.value for m in cls.__members__.values()]
        )


class FormatterMeta(EnumMeta, ABCMeta):  # noqa: D101
    def __call__(cls, *args, **kw):  # noqa: D102
        if getattr(cls, "__error_format__", None) is None:
            raise TypeError(
                f"Can't instantiate class `{cls.__name__}` "
                f"without `__error_format__` class attribute."
            )
        return super().__call__(*args, **kw)

    def __new__(cls, clsname, superclasses, attributedict):  # noqa: D102
        res = super().__new__(cls, clsname, superclasses, attributedict)
        res.__new__ = _pretty_raise_enum(res, res.__new__)
        return res


class PrettyEnumMixin(ErrorFormatter, NoValue, metaclass=FormatterMeta):
    """Enum mixin that pretty prints when user uses invalid value."""

    @property
    def s(self) -> str:
        """Return the :attr:`value` as :class:`str`."""
        return str(self.value)


[docs]@unique class License(PrettyEnumMixin): """License types.""" ACADEMIC = "academic" #: Academic license. COMMERCIAL = "commercial" #: Commercial license. NON_PROFIT = "non_profit" #: Non-profit license. FOR_PROFIT = "for_profit" #: For-profit license. IGNORE = "ignore" #: Ignore the license type.
[docs]@unique class InteractionDataset(PrettyEnumMixin): """ Available interaction datasets in [OmniPath]_. See :mod:`omnipath.interactions` for more information. """ COLLECTRI = "collectri" DOROTHEA = "dorothea" KINASE_EXTRA = "kinaseextra" LIGREC_EXTRA = "ligrecextra" LNCRNA_MRNA = "lncrna_mrna" MIRNA_TARGET = "mirnatarget" OMNIPATH = "omnipath" PATHWAY_EXTRA = "pathwayextra" SMALL_MOLECULE = "small_molecule" TF_MIRNA = "tf_mirna" TF_REGULONS = "tfregulons" TF_TARGET = "tf_target"
[docs]@unique class Organism(PrettyEnumMixin): """Organism types.""" HUMAN = "human" #: NCIB taxonomy id ``9606``. MOUSE = "mouse" #: NCIB taxonomy id ``10090``. RAT = "rat" #: NCIB taxonomy id ``10116``. def __new__(cls, value: str): # noqa: D102 obj = object.__new__(cls) obj._code = {"human": 9606, "rat": 10116, "mouse": 10090}[value] return obj @property def code(self) -> int: """Return the code for this organism.""" return self._code
__all__ = [ License, Organism, InteractionDataset, ]