Functional programming library providing type-safe containers for error handling, side effects, and composable operations with monadic patterns.
npx @tessl/cli install tessl/pypi-returns@0.26.0Make your functions return something meaningful, typed, and safe! Returns is a comprehensive functional programming library for Python that enables developers to write safer, more meaningful, and typed code through monadic patterns and railway-oriented programming. It offers primitives like Maybe, Result, IO, and Future containers for handling optional values, error cases, side effects, and asynchronous operations with full type safety enforced by mypy.
pip install returnsWith mypy support:
pip install returns[compatible-mypy]Basic imports:
from returns.result import Result, Success, Failure
from returns.maybe import Maybe, Some, Nothing
from returns.io import IO, IOResult
from returns.future import Future, FutureResultCommon utilities:
from returns.functions import identity, compose
from returns.pipeline import flow, pipe
from returns.pointfree import bind, map_from returns.result import Success, Failure, safe
from returns.maybe import Some, Nothing, maybe
from returns.pipeline import flow
# Result type for operations that can fail
@safe
def divide(a: int, b: int) -> float:
return a / b
result = divide(10, 2) # Success(5.0)
result = divide(10, 0) # Failure(ZeroDivisionError(...))
# Maybe type for handling None values
@maybe
def find_user(user_id: int) -> dict | None:
return {"id": user_id, "name": "John"} if user_id > 0 else None
user = find_user(1) # Some({"id": 1, "name": "John"})
user = find_user(-1) # Nothing
# Functional composition with pipeline
result = flow(
10,
lambda x: x * 2, # 20
lambda x: x + 5, # 25
lambda x: Success(x) # Success(25)
)
# Chaining operations with bind
from returns.pointfree import bind
def double(x: int) -> Success[int]:
return Success(x * 2)
def add_five(x: int) -> Success[int]:
return Success(x + 5)
result = Success(10).bind(double).bind(add_five) # Success(25)Returns follows functional programming principles with a focus on:
Essential monadic containers for type-safe error handling, optional values, side effects, and async operations. These form the foundation of functional programming patterns in Python.
class Result[T, E]:
"""Container for operations that can succeed or fail"""
def bind(self, func: Callable[[T], Result[U, E]]) -> Result[U, E]: ...
def map(self, func: Callable[[T], U]) -> Result[U, E]: ...
class Maybe[T]:
"""Container for optional values"""
def bind(self, func: Callable[[T], Maybe[U]]) -> Maybe[U]: ...
def map(self, func: Callable[[T], U]) -> Maybe[U]: ...
class IO[T]:
"""Container for impure operations"""
def bind(self, func: Callable[[T], IO[U]]) -> IO[U]: ...
def map(self, func: Callable[[T], U]) -> IO[U]: ...
class Future[T]:
"""Container for async operations"""
async def bind(self, func: Callable[[T], Future[U]]) -> Future[U]: ...
async def map(self, func: Callable[[T], U]) -> Future[U]: ...Context-dependent computations using the Reader monad pattern for dependency injection and environment passing without explicit parameter threading.
class RequiresContext[T, Deps]:
"""Reader monad for dependency injection"""
def __call__(self, deps: Deps) -> T: ...
def bind(self, func: Callable[[T], RequiresContext[U, Deps]]) -> RequiresContext[U, Deps]: ...
class RequiresContextResult[T, E, Deps]:
"""Reader + Result combination"""
def __call__(self, deps: Deps) -> Result[T, E]: ...Core functional programming utilities for composition, transformation, and pipeline construction that enable declarative programming patterns.
def identity(value: T) -> T: ...
def compose(first: Callable[[T], U], second: Callable[[U], V]) -> Callable[[T], V]: ...
def flow(instance: T, *functions: Callable) -> Any: ...
def pipe(*functions: Callable) -> Callable: ...Point-free style functions that enable composition without explicitly naming intermediate values, supporting functional programming idioms.
def bind(func: Callable[[T], Container[U]]) -> Callable[[Container[T]], Container[U]]: ...
def map_(func: Callable[[T], U]) -> Callable[[Container[T]], Container[U]]: ...
def alt(func: Callable[[E], F]) -> Callable[[Container[T, E]], Container[T, F]]: ...Containers and utilities for handling asynchronous operations with type safety and composable error handling in concurrent environments.
class Future[T]:
"""Async container for operations that don't fail"""
async def awaitable(self) -> T: ...
class FutureResult[T, E]:
"""Async container for operations that can fail"""
async def awaitable(self) -> Result[T, E]: ...Utilities for working with iterables of containers, providing declarative approaches to collection processing with type-safe error propagation.
class Fold:
"""Declarative iterable processing"""
@staticmethod
def loop(iterable: Iterable[Container[T]], acc: Container[U], func: Callable) -> Container[U]: ...
@staticmethod
def collect(iterable: Iterable[Container[T]], acc: Container[List[T]]) -> Container[List[T]]: ...Utilities for converting between different container types and integrating with external libraries and legacy code.
def result_to_maybe(result: Result[T, E]) -> Maybe[T]: ...
def maybe_to_result(maybe: Maybe[T], default_error: E = None) -> Result[T, E]: ...
def flatten(container: Container[Container[T]]) -> Container[T]: ...Integration tools for testing frameworks (pytest, hypothesis), static analysis (mypy), and development workflows with functional containers.
# Pytest integration
from returns.contrib.pytest import ReturnsAsserts
# Hypothesis strategies
from returns.contrib.hypothesis import get_strategiesCommon utility functions for container manipulation, conditional creation, and state checking that simplify working with container collections.
def cond(condition: bool, success_value: T, failure_value: E) -> Result[T, E]: ...
def partition(containers: Iterable[Result[T, E]]) -> tuple[list[T], list[E]]: ...
def unwrap_or_failure(container: Result[T, E], default_failure: F) -> T | F: ...Utilities for converting recursive functions into iterative ones to avoid stack overflow errors, enabling safe recursion in Python.
class Trampoline[T]:
"""Container for tail-call optimized recursion"""
def run(self) -> T: ...
def bind(self, func: Callable[[T], Trampoline[U]]) -> Trampoline[U]: ...
def trampoline(func: Callable[..., Trampoline[T]]) -> Callable[..., T]: ...Escape hatch utilities for breaking out of the functional programming world when interfacing with legacy code or at application boundaries.
def unsafe_perform_io(container: IO[T]) -> T:
"""Execute IO container and extract value (unsafe!)"""Core type definitions used across the library:
from typing import TypeVar, Generic, Callable, Awaitable
T = TypeVar('T') # Success type
E = TypeVar('E') # Error type
U = TypeVar('U') # Mapped type
Deps = TypeVar('Deps') # Dependencies type
# Common type aliases
ResultE[T] = Result[T, Exception]
IOResultE[T] = IOResult[T, Exception]
FutureResultE[T] = FutureResult[T, Exception]
NoDeps = Any # No dependencies marker