Skip to content

Commit c4debda

Browse files
committed
-
1 parent aee808e commit c4debda

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

source_py3/python_toolbox/cute_iter_tools.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -369,32 +369,44 @@ def _call_until_exception(function, exception):
369369
raise StopIteration
370370

371371

372-
def get_single_if_any(iterable,
373-
exception_on_multiple=Exception('More than one value '
374-
'not allowed.')):
372+
def get_single_if_any(iterable, *,
373+
exception_on_multiple=True, none_on_multiple=False):
375374
'''
376375
Get the single item of `iterable`, if any.
377376
378-
If `iterable` has one item, return it. If it's empty, return `None`. If it has
379-
more than one item, raise an exception. (Unless
380-
`exception_on_multiple=None`.)
377+
Default behavior: Get the first item from `iterable`, and ensure it doesn't
378+
have any more items (raise an exception if it does.)
379+
380+
If you pass in `exception_on_multiple=False`: If `iterable` has more than
381+
one item, an exception won't be raised. The first value will be returned.
382+
383+
If you pass in `none_on_multiple=True`: If `iterable` has more than one
384+
item, `None` will be returned regardless of the value of the first item.
385+
Note that passing `none_on_multiple=True` causes the
386+
`exception_on_multiple` argument to be ignored. (This is a bit ugly but I
387+
made it that way so you wouldn't have to manually pass
388+
`exception_on_multiple=False` in this case.)
381389
'''
382-
assert isinstance(exception_on_multiple, Exception) or \
383-
exception_on_multiple is None
390+
if none_on_multiple:
391+
exception_on_multiple = False
384392
iterator = iter(iterable)
385393
try:
386394
first_item = next(iterator)
387395
except StopIteration:
388396
return None
389397
else:
390-
if exception_on_multiple:
398+
if exception_on_multiple or none_on_multiple:
391399
try:
392400
second_item = next(iterator)
393401
except StopIteration:
394402
return first_item
395403
else:
396-
raise exception_on_multiple
397-
else: # not exception_on_multiple
404+
if none_on_multiple:
405+
return None
406+
else:
407+
assert exception_on_multiple
408+
raise Exception('More than one value not allowed.')
409+
else:
398410
return first_item
399411

400412

source_py3/test_python_toolbox/test_cute_iter_tools/test_get_single_if_any.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,7 @@ def test_get_single_if_any():
2222
with cute_testing.RaiseAssertor():
2323
get_single_if_any('gee')
2424

25-
assert get_single_if_any('gee', exception_on_multiple=None) == 'g'
25+
assert get_single_if_any('gee', exception_on_multiple=False) == 'g'
26+
assert get_single_if_any('gee', none_on_multiple=True) is None
27+
assert get_single_if_any('gee', none_on_multiple=True,
28+
exception_on_multiple=False) is None

0 commit comments

Comments
 (0)