Skip to main content

compose-operator

This module allows adding function composition with the | operator to any function, method, class, or other callable.

compose is used for the function composition. wrapt is used to add the operator as transparently and unintrusively as possible. This ensures that:

  1. The | composition operator does not interfere at runtime with any introspection, other operators, and (optionally) Python 3.10’s | type union operator.

  2. |-composed functions still work with signature introspection, method binding, pickling, and so on.

Versioning

This library’s version numbers follow the SemVer 2.0.0 specification.

Installation

pip install compose-operator

Usage

Basics

Import composable:

>>> from compose_operator import composable

A simple inline composition:

>>> stringify_as_integer = composable(int) | str
>>> stringify_as_integer(12.3)
'12'

Naturally, the result of | on a composable function is also composable, so you can chain it:

>>> (composable(int) | str | list)(12.3)
['1', '2']

You can also use composable as a decorator:

>>> @composable
... def my_stringify(thing):
...     return f'hello {thing}'
...
>>> stringify_as_integer = int | my_stringify
>>> stringify_as_integer(12.3)
'hello 12'

composable is “sticky”

composable will stick to callable return values, so it works out-of-the-box with currying, partial application, and so on:

>>> import functools
>>> import operator
>>> import toolz
>>>
>>> partial = composable(functools.partial)
>>> add1 = partial(operator.add, 1)
>>> (add1 | str)(2)
'3'
>>> curry = composable(toolz.curry)
>>> add = curry(operator.add)
>>> (add(2) | float)(2)
4.0

composable also sticks to the results of method binding, so if you make a composable method, or assign a function composed with the | operator as a method, it “just works”:

>>> class Adder:
...     def __init__(self, value):
...         self._value = value
...
...     @composable
...     def add(self, thing):
...         return thing + self._value
...
...     add_then_stringify = add | str
...
>>> adder = Adder(42)
>>> (adder.add | str)(8)
'50'
>>> adder.add_then_stringify(9)
'51'

Composable Classes

If you want to decorate a class so that the class is composable, use @composable_constructor - that way, normal class functionality such as | for type unions still works:

>>> from compose_operator import composable_constructor
>>>
>>> from dataclasses import dataclass
>>>
>>> @composable_constructor
... @dataclass
... class MyClass:
...     x: int
...
>>> isinstance(1, int | MyClass)
True
>>> isinstance("hello!", int | MyClass)
False
>>> isinstance(MyClass(0), int | MyClass)
True
>>> (operator.add | MyClass)(3, 2)
MyClass(x=5)

composable takes precedence over composable_constructor, so you can still force | to do composition instead of type union if you need to:

>>> (composable(int) | MyClass)("6")
MyClass(x=6)
>>> (int | composable(MyClass))("7")
MyClass(x=7)

Composable Callable Objects

If you are defining a class with a __call__ method, you can make its instances automatically composable by using composable_instances:

>>> from compose_operator import composable_instances
>>>
>>> @composable_instances
... class Greeter:
...     def __init__(self, target):
...         self._target = target
...     def __call__(self):
...         return f"Hello, {self._target}!"
...
>>> world_greeter = Greeter("world")
>>> world_greeter()
'Hello, world!'
>>> (world_greeter | list)()
['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']

Metadata

Release files for compose-operator 1.0.3

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

Source distribution (sdist)

Source distribution for compose-operator 1.0.3
File Size Uploaded
compose-operator-1.0.3.tar.gz 4.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for compose-operator 1.0.3
File Interpreter ABI Platform
compose_operator-1.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 10.0 kB

Release files / compose-operator-1.0.3.tar.gz

Download URL compose-operator-1.0.3.tar.gz
Size 4.9 kB
Tags Source
SHA-256 checksum
How to use checksums
22d6847897543c01672ac3107472dc454e81cfcf46fe6d42c15cca52796564c3
BLAKE2b-256 checksum
How to use checksums
424c2fd84e289c0715ed498aac900c51081f096def084c75bb45b631826b117f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.5

Release files / compose_operator-1.0.3-py3-none-any.whl

Download URL compose_operator-1.0.3-py3-none-any.whl
Size 5.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
102bc9525d50e3ca9f294aa6f143b7c2c406a7809914559ec628cc319deefa21
BLAKE2b-256 checksum
How to use checksums
6d58865c86ed667ea462ad07a621e99094719198c43bb847f216832ab37c75ac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.5

Release history Release notifications | RSS feed

This release

1.0.3 This release

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

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