• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# from more_itertools 9.0
2def only(iterable, default=None, too_long=None):
3    """If *iterable* has only one item, return it.
4    If it has zero items, return *default*.
5    If it has more than one item, raise the exception given by *too_long*,
6    which is ``ValueError`` by default.
7    >>> only([], default='missing')
8    'missing'
9    >>> only([1])
10    1
11    >>> only([1, 2])  # doctest: +IGNORE_EXCEPTION_DETAIL
12    Traceback (most recent call last):
13    ...
14    ValueError: Expected exactly one item in iterable, but got 1, 2,
15     and perhaps more.'
16    >>> only([1, 2], too_long=TypeError)  # doctest: +IGNORE_EXCEPTION_DETAIL
17    Traceback (most recent call last):
18    ...
19    TypeError
20    Note that :func:`only` attempts to advance *iterable* twice to ensure there
21    is only one item.  See :func:`spy` or :func:`peekable` to check
22    iterable contents less destructively.
23    """
24    it = iter(iterable)
25    first_value = next(it, default)
26
27    try:
28        second_value = next(it)
29    except StopIteration:
30        pass
31    else:
32        msg = (
33            'Expected exactly one item in iterable, but got {!r}, {!r}, '
34            'and perhaps more.'.format(first_value, second_value)
35        )
36        raise too_long or ValueError(msg)
37
38    return first_value
39