codekingpro/portable-devtools
114k
1import collections.abc2import functools3 4 5# from jaraco.functools 3.56def pass_none(func):7 """8 Wrap func so it's not called if its first param is None9 10 >>> print_text = pass_none(print)11 >>> print_text('text')12 text13 >>> print_text(None)14 """15 16 @functools.wraps(func)17 def wrapper(param, *args, **kwargs):18 if param is not None:19 return func(param, *args, **kwargs)20 21 return wrapper22 23 24# from jaraco.functools 4.025@functools.singledispatch26def _splat_inner(args, func):27 """Splat args to func."""28 return func(*args)29 30 31@_splat_inner.register32def _(args: collections.abc.Mapping, func):33 """Splat kargs to func as kwargs."""34 return func(**args)35 36 37def splat(func):38 """39 Wrap func to expect its parameters to be passed positionally in a tuple.40 41 Has a similar effect to that of ``itertools.starmap`` over42 simple ``map``.43 44 >>> import itertools, operator45 >>> pairs = [(-1, 1), (0, 2)]46 >>> _ = tuple(itertools.starmap(print, pairs))47 -1 148 0 249 >>> _ = tuple(map(splat(print), pairs))50 -1 151 0 252 53 The approach generalizes to other iterators that don't have a "star"54 equivalent, such as a "starfilter".55 56 >>> list(filter(splat(operator.add), pairs))57 [(0, 2)]58 59 Splat also accepts a mapping argument.60 61 >>> def is_nice(msg, code):62 ... return "smile" in msg or code == 063 >>> msgs = [64 ... dict(msg='smile!', code=20),65 ... dict(msg='error :(', code=1),66 ... dict(msg='unknown', code=0),67 ... ]68 >>> for msg in filter(splat(is_nice), msgs):69 ... print(msg)70 {'msg': 'smile!', 'code': 20}71 {'msg': 'unknown', 'code': 0}72 """73 return functools.wraps(func)(functools.partial(_splat_inner, func=func))74 