| import collections.abc |
| import functools |
|
|
|
|
| |
| def pass_none(func): |
| """ |
| Wrap func so it's not called if its first param is None |
| |
| >>> print_text = pass_none(print) |
| >>> print_text('text') |
| text |
| >>> print_text(None) |
| """ |
|
|
| @functools.wraps(func) |
| def wrapper(param, *args, **kwargs): |
| if param is not None: |
| return func(param, *args, **kwargs) |
|
|
| return wrapper |
|
|
|
|
| |
| @functools.singledispatch |
| def _splat_inner(args, func): |
| """Splat args to func.""" |
| return func(*args) |
|
|
|
|
| @_splat_inner.register |
| def _(args: collections.abc.Mapping, func): |
| """Splat kargs to func as kwargs.""" |
| return func(**args) |
|
|
|
|
| def splat(func): |
| """ |
| Wrap func to expect its parameters to be passed positionally in a tuple. |
| |
| Has a similar effect to that of ``itertools.starmap`` over |
| simple ``map``. |
| |
| >>> import itertools, operator |
| >>> pairs = [(-1, 1), (0, 2)] |
| >>> _ = tuple(itertools.starmap(print, pairs)) |
| -1 1 |
| 0 2 |
| >>> _ = tuple(map(splat(print), pairs)) |
| -1 1 |
| 0 2 |
| |
| The approach generalizes to other iterators that don't have a "star" |
| equivalent, such as a "starfilter". |
| |
| >>> list(filter(splat(operator.add), pairs)) |
| [(0, 2)] |
| |
| Splat also accepts a mapping argument. |
| |
| >>> def is_nice(msg, code): |
| ... return "smile" in msg or code == 0 |
| >>> msgs = [ |
| ... dict(msg='smile!', code=20), |
| ... dict(msg='error :(', code=1), |
| ... dict(msg='unknown', code=0), |
| ... ] |
| >>> for msg in filter(splat(is_nice), msgs): |
| ... print(msg) |
| {'msg': 'smile!', 'code': 20} |
| {'msg': 'unknown', 'code': 0} |
| """ |
| return functools.wraps(func)(functools.partial(_splat_inner, func=func)) |
|
|