Skip to content

Commit

Permalink
feat: support precedent passing var len args/kwargs by >> and <<
Browse files Browse the repository at this point in the history
  • Loading branch information
hoishing committed Feb 9, 2023
1 parent d541ebf commit 9b8f04e
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 10 deletions.
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# pipable

> pseudo pipe operation in python
[![ci-badge]][ci-url] [![coverage-badge]][coverage-url] [![pypi-badge]][pypi-url] ![py-ver-badge] [![MIT-badge]][MIT-url] [![black-badge]][black-url]

[![ci-badge]][ci-url] [![coverage-badge]][coverage-url] [![pypi-badge]][pypi-url] [![py-version]][py-url] [![MIT-badge]][MIT-url] [![black-badge]][black-url]
> pipe operation in python
🔗 [source code](https://github.com/hoishing/pipable)

Expand Down Expand Up @@ -80,7 +80,7 @@ Pipe operation is a handy feature in functional programming. It allows us to:

However it's still a missing feature in Python as of 2023. This package try to mimic pipe operation by overriding the bitwise-or operator, and turn any function into pipable partial.

There are packages, such as [pipe 2][pipe] take the similar approach. It works great with iterables, and create pipe as iterator, ie. open pipe). However, I simply want to take preceding expression as an input argument of the current function then execute it, ie. close pipe. It leads to the creation of this package.
There are packages, such as [pipe] take the similar approach. It works great with iterables, and create pipe as iterator, ie. open pipe). However, I simply want to take preceding expression as an input argument of the current function then execute it, ie. close pipe. It leads to the creation of this package.

## FAQ

Expand All @@ -99,8 +99,8 @@ Can I create open pipe?

`Pipe` only create closed pipe, ie. execute the function after piping with the `|` operator. You may consider other solutions such as:

- [pipe][pipe], which create open pipe for iterators
- [Coconut][coconut], a python variant that embrace functional programming
- [pipe], which create open pipe for iterators
- [Coconut], a python variant that embrace functional programming

---

Expand All @@ -124,8 +124,11 @@ def wrapper(first, others):

## Need Help?

Open a [github issue](https://github.com/hoishing/pipable/issues) or ping me on [Twitter](https://twitter.com/hoishing) ![](https://api.iconify.design/logos/twitter.svg?width=20)
Open a [github issue] or ping me on [Twitter ![twitter-icon]][Twitter]

[github issue]: https://github.com/hoishing/pipable/issues
[Twitter]: https://twitter.com/hoishing
[twitter-icon]: https://api.iconify.design/logos/twitter.svg?width=20
[ci-badge]: https://github.com/hoishing/pipable/actions/workflows/ci.yml/badge.svg
[ci-url]: https://github.com/hoishing/pipable/actions/workflows/ci.yml
[coverage-badge]: https://hoishing.github.io/pipable/assets/coverage-badge.svg
Expand All @@ -136,7 +139,6 @@ Open a [github issue](https://github.com/hoishing/pipable/issues) or ping me on
[pypi-url]: https://pypi.org/project/pipable/
[black-badge]: https://img.shields.io/badge/code%20style-black-000000.svg
[black-url]: https://github.com/psf/black
[py-version]: https://img.shields.io/pypi/pyversions/pipable
[py-url]: https://python.org
[py-ver-badge]: https://img.shields.io/pypi/pyversions/pipable
[pipe]: https://pypi.org/project/pipe
[coconut]: https://github.com/evhub/coconut
[Coconut]: https://github.com/evhub/coconut
10 changes: 9 additions & 1 deletion pipable/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
turn it into an infix function that take the output of previous expression as the first argument of the current function.
"""

from typing import Callable, Any
from typing import Callable, Any, Iterable
from functools import partial


Expand All @@ -29,6 +29,14 @@ def __ror__(self, precedent: Any):
# return partial(self.func, precedent)
return self.pipe(precedent)

def __rrshift__(self, precedent: Iterable):
"""override the builit-in `>>` operator, pass precedent as destructured iterable to the pipe"""
return self.pipe(*precedent)

def __rlshift__(self, precedent: dict):
"""override the builit-in `>>=` operator, pass as destructured dict to the pipe"""
return self.pipe(**precedent)

def __call__(self, *args, **kwargs):
"""replace arguments of the pipable partial"""
return Pipe(self.pipe.func, *args, **kwargs)
22 changes: 22 additions & 0 deletions tests/test_destructure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from pipable import Pipe
import pytest


# == fixture ==
@Pipe
def kebab(*args):
return "-".join(args)


@Pipe
def concat(**kwargs):
return ", ".join([f"{k}-{v}" for k, v in kwargs.items()])


# == test ==
def test_iterable_precedent():
assert ["a", "b"] >> kebab == "a-b"


def test_dict_precedent():
assert dict(b="boy", c="cat") << concat == "b-boy, c-cat"

0 comments on commit 9b8f04e

Please sign in to comment.