Expression

raw JSON →
5.6.0 verified Fri May 01 auth: no python

A functional programming library for Python 3.10+ providing immutable data structures like Option, Result, Try, and pipe operators. Version 5.6.0 is the latest, with active maintenance and frequent releases.

pip install expression
error ModuleNotFoundError: No module named 'expression'
cause Package not installed. Or conflicting module name if user created a file named expression.py.
fix
Run 'pip install expression'. Delete any local file named expression.py.
error AttributeError: module 'expression' has no attribute 'Option'
cause Using old import path from expression.core, or installed an older version (<5.0.0).
fix
Upgrade to latest: 'pip install --upgrade expression', and import from 'from expression import Option'.
error TypeError: 'Result' object is not callable
cause Calling Result as a function instead of using Result.Ok/Error constructors.
fix
Use Result.Ok(value) or Result.Error(error). Do not call Result(value).
breaking v5.0.0 moved all core types to top-level imports (e.g., from expression import Option). Old imports from expression.core will break.
fix Replace 'from expression.core import ...' with 'from expression import ...'. For Try, use 'from expression import try_' as a function.
breaking The Try type was replaced by the try_ function in v5.0.0. The class-based Try is gone.
fix Use 'try_' to wrap a callable. See quickstart for pattern.
gotcha Option and Result are not ordinary Python booleans. Do not use if option: to check for Some/Nothing; use option.match or pattern matching introduced in later versions.
fix Use Option.match() or match statement (Python 3.10+): match option: case Option.Some(v): ... case Option.Nothing(): ...
deprecated The pipe function supports starpipe (|>) operator style, but mixing pipe and starpipe can cause type errors. Prefer one style consistently.
fix Use either pipe(x, f, g) or x |> f |> g, but not both in the same chain.
gotcha The expression package name conflicts with the 'expression' string. Avoid shadowing by importing with alias or using full qualified name.
fix Import as 'from expression import ...' and do not name any variable 'expression'.

Basic usage of Option, Result, and pipe operator.

from expression import Option, Result, pipe

# Option example
def safe_divide(a: float, b: float) -> Option[float]:
    if b == 0:
        return Option.Nothing()
    return Option.Some(a / b)

# Pipe usage
result = pipe(
    Option.Some(10),
    lambda x: x.map(lambda v: v * 2),
    lambda x: x.bind(lambda v: safe_divide(v, 3))
)
print(result)  # Option.Some(6.666...)

# Result example
def fetch_user(id: int) -> Result[str, str]:
    if id > 0:
        return Result.Ok(f"User {id}")
    return Result.Error("Invalid ID")

user = fetch_user(1).map(lambda u: u.upper())
print(user)