1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
from typing import Iterable, Sequence, TYPE_CHECKING
import click
from click import Context, Parameter
from .common import join_param_labels
if TYPE_CHECKING:
from ._core import Constraint
def default_constraint_error(params: Iterable[Parameter], desc: str) -> str:
return (
'the following constraint on parameters [%s] was not satisfied: %s'
% (join_param_labels(params), desc)
)
class ConstraintViolated(click.UsageError):
def __init__(
self, message: str,
ctx: Context,
constraint: 'Constraint',
params: Sequence[click.Parameter]
):
super().__init__(message, ctx=ctx)
self.ctx = ctx
self.constraint = constraint
self.params = params
@classmethod
def default(
cls,
desc: str,
ctx: Context,
constraint: 'Constraint',
params: Sequence[Parameter],
) -> 'ConstraintViolated':
return ConstraintViolated(
default_constraint_error(params, desc),
ctx=ctx, constraint=constraint, params=params,
)
class UnsatisfiableConstraint(Exception):
"""Raised if a constraint cannot be satisfied by a group of parameters
independently from their values at runtime; e.g. ``mutually_exclusive`` cannot
be satisfied if multiple of the parameters are required."""
def __init__(
self, constraint: 'Constraint', params: Iterable[Parameter], reason: str
):
self.constraint = constraint
self.params = params
self.reason = reason
param_names = join_param_labels(params)
message = (f"\nthe constraint {constraint}\n"
f"defined on parameters [{param_names}]\n"
f"cannot be satisfied because {reason}")
super().__init__(message)
|