Source code for datalad_core.constraints.basic

from __future__ import annotations

from collections.abc import (
    Mapping,
)
from typing import Any

from datalad_core.constraints.constraint import Constraint


[docs] class NoConstraint(Constraint): """A constraint that represents no constraints""" @property def input_synopsis(self): return ''
[docs] def __call__(self, value): return value
[docs] class EnsureChoice(Constraint): """Ensure an input is element of a set of possible values""" def __init__(self, *values: Any): self._choices = tuple(values) super().__init__() @property def choices(self) -> tuple[Any]: """Returns the possible choice values""" return self._choices
[docs] def __call__(self, value): if value not in self.choices: self.raise_for( value, 'is not one of {allowed}', allowed=self.choices, ) return value
@property def input_synopsis(self): return f'one of {{{",".join([repr(c) for c in self.choices])}}}'
class EnsureMappingtHasKeys(Constraint): """Ensure a mapping has all given keys""" def __init__(self, required_keys: tuple | list): self._required_keys = required_keys @property def input_synopsis(self): return ( 'mapping with required keys {self._required_keys!r}' if self._required_keys else 'mapping' ) def __call__(self, value: Any) -> dict: if not isinstance(value, Mapping): self.raise_for( value, 'not a mapping', ) missing = tuple(a for a in self._required_keys if a not in value) if missing: self.raise_for( value, 'missing keys {missing!r}', missing=missing, ) return value