File: _group.py

package info (click to toggle)
python-cyclopts 3.12.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,288 kB
  • sloc: python: 11,445; makefile: 24
file content (48 lines) | stat: -rw-r--r-- 1,726 bytes parent folder | download | duplicates (2)
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
from typing import TYPE_CHECKING, Optional

if TYPE_CHECKING:
    from cyclopts.argument import ArgumentCollection


class LimitedChoice:
    def __init__(self, min: int = 0, max: Optional[int] = None):
        """Group validator that limits the number of selections per group.

        Commonly used for enforcing mutually-exclusive parameters (default behavior).

        Parameters
        ----------
        min: int
            The minimum (inclusive) number of CLI parameters allowed.
        max: Optional[int]
            The maximum (inclusive) number of CLI parameters allowed.
            Defaults to ``1`` if ``min==0``, ``min`` otherwise.
        """
        self.min = min
        self.max = (self.min or 1) if max is None else max
        if self.max < self.min:
            raise ValueError("max must be >=min.")

    def __call__(self, argument_collection: "ArgumentCollection"):
        argument_collection = argument_collection.filter_by(value_set=True)
        n_arguments = len(argument_collection)

        if self.min <= n_arguments <= self.max:
            return  # Happy path

        offenders = "{" + ", ".join(a.name for a in argument_collection) + "}"
        if self.min == 0 and self.max == 1:
            raise ValueError(f"Mutually exclusive arguments: {offenders}")
        else:
            raise ValueError(
                f"Received {n_arguments} arguments: {offenders}. Only [{self.min}, {self.max}] choices may be specified."
            )


class MutuallyExclusive(LimitedChoice):
    def __init__(self):
        """Alias for :class:`LimitedChoice` to make intentions more obvious.

        Only 1 argument in the group can be supplied a value.
        """
        super().__init__()