Beispiel #1
0
    def compose(first, second):
        name = '{0} | {1}'.format(get_name(first), get_name(second))

        def composite(*args, **kwargs):
            with pipe_exception_handler('pipe | ' + name):
                return second(first(*args, **kwargs))
        return set_name(name, composite)
Beispiel #2
0
    def compose(first, second):
        name = lambda: '{0} ?| {1}'.format(get_name(first), get_name(second))

        def composite(*args, **kwargs):
            result = first(*args, **kwargs)
            return None if result is None else second(result)
        return set_name(name, composite)
Beispiel #3
0
def unless(exception_class_or_tuple, func, *args, **kwargs):
    """
    When `exception_class_or_tuple` occurs while executing `func`, it will
    be caught and ``None`` will be returned.

    >>> f = where(X > 10) | list | unless(IndexError, X[0])
    >>> f([5, 8, 12, 4])
    12
    >>> f([1, 2, 3])
    None
    """
    @pipe_util
    @auto_string_formatter
    @data_structure_builder
    def construct_unless(function):
        # a wrapper so we can re-use the decorators
        def _unless(*args, **kwargs):
            try:
                return function(*args, **kwargs)
            except exception_class_or_tuple:
                pass
        return _unless

    name = 'unless(%s, %s)' % (exception_class_or_tuple, ', '.join(
        filter(None, (get_name(func), repr_args(*args, **kwargs)))))

    return set_name(name, construct_unless(func, *args, **kwargs))
Beispiel #4
0
    def compose(first, second):
        name = lambda: '{0} | {1}'.format(get_name(first), get_name(second))

        def composite(*args, **kwargs):
            return second(first(*args, **kwargs))

        return set_name(name, composite)
Beispiel #5
0
    def compose(first, second):
        name = lambda: '{0} ?| {1}'.format(get_name(first), get_name(second))

        def composite(*args, **kwargs):
            result = first(*args, **kwargs)
            return None if result is None else second(result)
        return set_name(name, composite)
Beispiel #6
0
def unless(exception_class_or_tuple, func, *args, **kwargs):
    """
    When `exception_class_or_tuple` occurs while executing `func`, it will
    be caught and ``None`` will be returned.

    >>> f = where(X > 10) | list | unless(IndexError, X[0])
    >>> f([5, 8, 12, 4])
    12
    >>> f([1, 2, 3])
    None
    """
    @pipe_util
    @auto_string_formatter
    @data_structure_builder
    def construct_unless(function):
        # a wrapper so we can re-use the decorators
        def _unless(*args, **kwargs):
            try:
                return function(*args, **kwargs)
            except exception_class_or_tuple:
                pass

        return _unless

    name = lambda: 'unless(%s, %s)' % (exception_class_or_tuple, ', '.join(
        filter(None, (get_name(func), repr_args(*args, **kwargs)))))

    return set_name(name, construct_unless(func, *args, **kwargs))
Beispiel #7
0
    def compose(first, second):
        name = '{0} | {1}'.format(get_name(first), get_name(second))

        def composite(*args, **kwargs):
            with pipe_exception_handler('pipe | ' + name):
                return second(first(*args, **kwargs))

        return set_name(name, composite)
Beispiel #8
0
    def compose(first, second):
        name = '{0} ?| {1}'.format(get_name(first), get_name(second))

        def composite(*args, **kwargs):
            with pipe_exception_handler('maybe ?| ' + name):
                result = first(*args, **kwargs)
                return None if result is None else second(result)
        return set_name(name, composite)
Beispiel #9
0
    def compose(first, second):
        name = '{0} ?| {1}'.format(get_name(first), get_name(second))

        def composite(*args, **kwargs):
            with pipe_exception_handler('maybe ?| ' + name):
                result = first(*args, **kwargs)
                return None if result is None else second(result)

        return set_name(name, composite)
Beispiel #10
0
def take_first(count):
    """
    Assumes an iterable on the input, returns an iterable with first `count`
    items from the input (or possibly less, if there isn't that many).

    >>> xrange(9000) > where(X % 100 == 0) | take_first(5) | tuple
    (0, 100, 200, 300, 400)

    """
    def _take_first(iterable):
        return islice(iterable, count)
    return pipe | set_name('take_first(%s)' % count, _take_first)
Beispiel #11
0
def drop_first(count):
    """
    Assumes an iterable on the input, returns an iterable with identical items
    except for the first `count`.

    >>> xrange(10) > drop_first(5) | tuple
    (5, 6, 7, 8, 9)
    """
    def _drop_first(iterable):
        g = (x for x in xrange(1, count + 1))
        return dropwhile(lambda i: unless(StopIteration, g.next)(), iterable)
    return pipe | set_name('drop_first(%s)' % count, _drop_first)
Beispiel #12
0
def StringFormatter(template):

    f = text_type(template).format

    def format(content):
        if isinstance(content, dict):
            return f(**content)
        if _iterable(content):
            return f(*content)
        return f(content)

    return set_name(lambda: "format('%s')" % template[:20], format)
Beispiel #13
0
def StringFormatter(template):

    f = text_type(template).format

    def format(content):
        if isinstance(content, dict):
            return f(**content)
        if _iterable(content):
            return f(*content)
        return f(content)

    return set_name(lambda: "format('%s')" % template[:20], format)
Beispiel #14
0
def drop_first(count):
    """
    Assumes an iterable on the input, returns an iterable with identical items
    except for the first `count`.

    >>> xrange(10) > drop_first(5) | tuple
    (5, 6, 7, 8, 9)
    """
    def _drop_first(iterable):
        g = (x for x in xrange(1, count + 1))
        return dropwhile(lambda i: unless(StopIteration, g.next)(), iterable)

    return pipe | set_name('drop_first(%s)' % count, _drop_first)
Beispiel #15
0
    def pipe_util_wrapper(function, *args, **kwargs):
        if isinstance(function, XObject):
            function = ~function

        function_name = get_name(function)

        if args or kwargs:
            function = xcurry(function, *args, **kwargs)

        name = '%s(%s)' % (func.__name__, ', '.join(
            filter(None, (function_name, repr_args(*args, **kwargs)))))

        return pipe | set_name(name, func(function))
Beispiel #16
0
def take_first(count):
    """
    Assumes an iterable on the input, returns an iterable with first `count`
    items from the input (or possibly less, if there isn't that many).

    >>> range(9000) > where(X % 100 == 0) | take_first(5) | tuple
    (0, 100, 200, 300, 400)

    """
    def _take_first(iterable):
        return islice(iterable, count)

    return pipe | set_name('take_first(%s)' % count, _take_first)
Beispiel #17
0
def xpartial(func, *xargs, **xkwargs):
    """
    Like :func:`functools.partial`, but can take an :class:`XObject`
    placeholder that will be replaced with the first positional argument
    when the partially applied function is called.

    Useful when the function's positional arguments' order doesn't fit your
    situation, e.g.:

    >>> reverse_range = xpartial(range, X, 0, -1)
    >>> reverse_range(5)
    [5, 4, 3, 2, 1]

    It can also be used to transform the positional argument to a keyword
    argument, which can come in handy inside a *pipe*::

        xpartial(objects.get, id=X)

    Also the XObjects are evaluated, which can be used for some sort of
    destructuring of the argument::

        xpartial(somefunc, name=X.name, number=X.contacts['number'])

    Lastly, unlike :func:`functools.partial`, this creates a regular function
    which will bind to classes (like the ``curry`` function from
    ``django.utils.functional``).
    """
    any_x = any(
        isinstance(a, XObject) for a in xargs + tuple(xkwargs.values()))
    use = lambda x, value: (~x)(value) if isinstance(x, XObject) else x

    @wraps(func, assigned=filter(partial(hasattr, func), WRAPPER_ASSIGNMENTS))
    def xpartially_applied(*func_args, **func_kwargs):
        if any_x:
            if not func_args:
                raise ValueError(
                    'Function "%s" partially applied with an '
                    'X placeholder but called with no positional arguments.' %
                    get_name(func))
            first = func_args[0]
            rest = func_args[1:]
            args = tuple(use(x, first) for x in xargs) + rest
            kwargs = dict((k, use(x, first)) for k, x in dict_items(xkwargs))
            kwargs.update(func_kwargs)
        else:
            args = xargs + func_args
            kwargs = dict(xkwargs, **func_kwargs)
        return func(*args, **kwargs)

    name = lambda: '%s(%s)' % (get_name(func), repr_args(*xargs, **xkwargs))
    return set_name(name, xpartially_applied)
Beispiel #18
0
def xpartial(func, *xargs, **xkwargs):
    """
    Like :func:`functools.partial`, but can take an :class:`XObject`
    placeholder that will be replaced with the first positional argument
    when the partially applied function is called.

    Useful when the function's positional arguments' order doesn't fit your
    situation, e.g.:

    >>> reverse_range = xpartial(range, X, 0, -1)
    >>> reverse_range(5)
    [5, 4, 3, 2, 1]

    It can also be used to transform the positional argument to a keyword
    argument, which can come in handy inside a *pipe*::

        xpartial(objects.get, id=X)

    Also the XObjects are evaluated, which can be used for some sort of
    destructuring of the argument::

        xpartial(somefunc, name=X.name, number=X.contacts['number'])

    Lastly, unlike :func:`functools.partial`, this creates a regular function
    which will bind to classes (like the ``curry`` function from
    ``django.utils.functional``).
    """
    any_x = any(isinstance(a, XObject) for a in xargs + tuple(xkwargs.values()))
    use = lambda x, value: (~x)(value) if isinstance(x, XObject) else x

    @wraps(func)
    def xpartially_applied(*func_args, **func_kwargs):
        if any_x:
            if not func_args:
                raise ValueError('Function "%s" partially applied with an '
                    'X placeholder but called with no positional arguments.'
                    % get_name(func))
            first = func_args[0]
            rest = func_args[1:]
            args = tuple(use(x, first) for x in xargs) + rest
            kwargs = dict((k, use(x, first)) for k, x in dict_items(xkwargs))
            kwargs.update(func_kwargs)
        else:
            args = xargs + func_args
            kwargs = dict(xkwargs, **func_kwargs)
        return func(*args, **kwargs)

    name = lambda: '%s(%s)' % (get_name(func), repr_args(*xargs, **xkwargs))
    return set_name(name, xpartially_applied)
Beispiel #19
0
    def pipe_util_wrapper(function, *args, **kwargs):
        if isinstance(function, XObject):
            function = ~function

        original_function = function

        if args or kwargs:
            function = xpartial(function, *args, **kwargs)

        name = lambda: '%s(%s)' % (get_name(func), ', '.join(
            filter(None, (get_name(original_function), repr_args(*args, **kwargs)))))

        f = func(function)

        result = pipe | set_name(name, f)

        # if the util defines an 'attrs' mapping, copy it as attributes
        # to the result
        attrs = getattr(f, 'attrs', {})
        for k, v in dict_items(attrs):
            setattr(result, k, v)

        return result
Beispiel #20
0
    def compose(first, second):
        name = lambda: '{0} | {1}'.format(get_name(first), get_name(second))

        def composite(*args, **kwargs):
            return second(first(*args, **kwargs))
        return set_name(name, composite)
Beispiel #21
0
 def bind(self, name, func):
     set_name(name, func)
     return XObject((self._func | func) if self._func else (pipe | func))
Beispiel #22
0
 def __invert__(self):
     return self._func or set_name('X', lambda x: x)
Beispiel #23
0
 def __init__(self, func=None):
     self._func = func
     set_name(lambda: get_name(func) if func else 'X', self)
Beispiel #24
0
 def bind(self, name, func):
     set_name(name, func)
     return XObject((self._func | func) if self._func else (pipe | func))
Beispiel #25
0
 def __invert__(self):
     return self._func or set_name('X', lambda x: x)
Beispiel #26
0
 def __init__(self, func=None):
     self._func = func
     set_name(lambda: get_name(func) if func else 'X', self)