Skip to main content

function-pipes

PyPI License Copy and Paste

Fast, type-hinted python equivalent for R pipes.

This decorator only relies on the standard library, so can just be copied into a project as a single file.

Why is this needed?

Various languages have versions of a 'pipe' syntax, where a value can be passed through a succession of different functions before returning the final value.

This means you can avoid syntax like the below, where the sequence is hard to read (especially if extra arguments are introduced).

a = c(b(a(value)))

In Python, there is not a good built-in way of doing this, and other attempts at a pipe do not play nice with type hinting.

This library has a very simple API, and does the fiddly bits behind the scenes to keep the pipe fast.

The pipe

There is a pipe, function which expects a value and then a list of callables.

from function_pipes import pipe

value = pipe(5, lambda x: x + 2, str)
value == "7"

No special form for extra arguments, small special case for functions that don't return a value

There is no bespoke syntax for passing in extra arguments or moving where the pipe's current value is placed - just use a lambda. This is a well understood approach, that is compatible with type hinting. In the above, value will be recognised as a string, but the x is understood as an int.

There is a small bit of bespoke syntax for when you want to pass something through a function, but that function doesn't return the result to the next function. Here the pipe_bridge function will wrap another function, pass the function into it, and continue onwards. The following will print 7, before passing the value on.

from function_pipes import pipe, pipe_bridge

value = pipe(5, lambda x: x + 2, pipe_bridge(print), str)
value == "7"

Merging functions to use later

There is also a pipeline, which given a set of functions will return a function which a value can be passed into. Where possible based on other hints, this will hint the input and output variable types.

from function_pipes import pipeline

func = pipeline(lambda x: x + 2, str)
func(5) == "7"

Optimising use of pipes

There's work behind the scenes to minimise the overhead of using the pipe, but it is still adding a function call. If you want the readability of the pipe and the speed of the native ugly approach you can use the @fast_pipes decorator. This rewrites the function it is called on to expand out the pipe and any lambdas into the fastest native equivalent.

e.g. These two functions should have equivalent AST trees:

@fast_pipes
def function_that_has_a_pipe(v: int) -> str:
    value = pipe(v, a, lambda x: b(x, foo="other_input"), c)
    return pipe
def function_that_has_a_pipe(v: int) -> str:
    value = c(b(a(v),foo="other_input"))
    return pipe

This version of the function is solving three versions of the same puzzle at the same time:

  • The type hinting is unpacking the structure when it is being written.
  • The pipe function solves the problem in standard python.
  • The fast_pipes decorator is rewriting the AST tree to get the same outcome faster.

But to the user, it all looks the same - pipes!

There is a limit of 20 functions that can be passed to a pipe or pipeline. If you really want to do more, you could chain multiple pipelines together.

Install

You can install from pip: python -m pip install function-pipes

Or you can copy the function directly into your projects.

Development

This project comes with a Dockerfile and devcontainer that should get a good environment set up.

The actual code is generated from src/function_pipes/pipes.jinja-py using jinja to generate the code and the seperate versions with and without use of paramspec.

Use make to regenerate the files. The number of allowed arguments is specified in Makefile.

There is a test suite that does checks for equivalence between this syntax and the raw syntax, as well as checking that fast_pipes and other optimisations are faster.

This can be run with script/test.

Metadata

Release files for function-pipes 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for function-pipes 0.1.0
File Size Uploaded
function-pipes-0.1.0.tar.gz 16.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for function-pipes 0.1.0
File Interpreter ABI Platform
function_pipes-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 35.5 kB

Release files / function-pipes-0.1.0.tar.gz

Download URL function-pipes-0.1.0.tar.gz
Size 16.3 kB
Tags Source
SHA-256 checksum
How to use checksums
0d5e7f38129a8603d22e933477fc1adb26a0f130d84b98b84986c26dbefb4ab3
BLAKE2b-256 checksum
How to use checksums
81544f224dc838dfdb5c9aac37fd79b12cdbb8478a4492a49bf37fe38d3c7f30
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.14 CPython/3.10.2 Linux/5.13.0-1031-azure

Release files / function_pipes-0.1.0-py3-none-any.whl

Download URL function_pipes-0.1.0-py3-none-any.whl
Size 19.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a3b57e50a154de1d3b69ff94decf7e84832d1e2e87b682b26f44cedc51ba5fab
BLAKE2b-256 checksum
How to use checksums
3b91e44c566872128fc4c4fe4d756a176e661a230597203d772738cdc15d3e6c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.14 CPython/3.10.2 Linux/5.13.0-1031-azure

Release history Release notifications | RSS feed

0.1.2

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page