philiprehberger-result
Rust-inspired Result type for Python with pattern matching and type-safe error handling.
Installation
pip install philiprehberger-result
Usage
Basic Result
from philiprehberger_result import Ok, Err, Result
def divide(a: float, b: float) -> Result[float, str]:
if b == 0:
return Err("division by zero")
return Ok(a / b)
result = divide(10, 2)
print(result.unwrap()) # 5.0
result = divide(10, 0)
print(result.unwrap_or(0.0)) # 0.0
Pattern Matching (Python 3.10+)
match divide(10, 3):
case Ok(value):
print(f"Result: {value}")
case Err(error):
print(f"Error: {error}")
Chaining
result = (
Ok(10)
.map(lambda x: x * 2)
.flat_map(lambda x: Ok(x + 1) if x < 100 else Err("too large"))
)
Fallback with or_else
result = Err("not found").or_else(lambda e: Ok("default"))
# Ok("default")
Serialization
Ok(42).to_dict() # {"ok": 42}
Err("x").to_dict() # {"err": "x"}
Try/Catch Wrapping
from philiprehberger_result import try_catch
result = try_catch(lambda: int("not a number"))
# Err(ValueError("invalid literal..."))
Async Support
from philiprehberger_result import try_catch_async
result = await try_catch_async(fetch_data)
Collecting Results
from philiprehberger_result import all_ok
results = [Ok(1), Ok(2), Ok(3)]
combined = all_ok(results) # Ok([1, 2, 3])
results = [Ok(1), Err("fail"), Ok(3)]
combined = all_ok(results) # Err("fail")
Batch Mapping
from philiprehberger_result import map_batch
results = [Ok(1), Ok(2), Ok(3)]
mapped = map_batch(results, lambda x: x * 10) # Ok([10, 20, 30])
results = [Ok(1), Err("fail"), Ok(3)]
mapped = map_batch(results, lambda x: x * 10) # Err("fail")
Flattening Nested Results
nested = Ok(Ok(42))
flat = nested.flatten() # Ok(42)
nested = Ok(Err("inner error"))
flat = nested.flatten() # Err("inner error")
outer_err = Err("outer")
flat = outer_err.flatten() # Err("outer")
Transpose nested results
from philiprehberger_result import transpose
transpose(Ok(Ok(5))) # Ok(5)
transpose(Ok(Err("bad"))) # Err("bad")
transpose(Err("outer")) # Err("outer")
# Method form:
Ok(Ok(5)).transpose() # Ok(5)
Ok(Err("bad")).transpose() # Err("bad")
Unlike flatten(), transpose() collapses both inner branches and raises
TypeError if the inner value is not itself a Result.
Combining Multiple Results
from philiprehberger_result import combine
result = combine(Ok(1), Ok("hello"), Ok(True))
# Ok((1, "hello", True))
result = combine(Ok(1), Err("fail"), Ok(3))
# Err("fail")
Collecting Results from Iterables
from philiprehberger_result import collect
results = [Ok(1), Ok(2), Ok(3)]
collected = collect(results) # Ok([1, 2, 3])
results = [Ok(1), Err("fail"), Ok(3)]
collected = collect(results) # Err("fail")
Adding Error Context
result = Err("not found").with_context("loading config")
# Err("loading config: not found")
ok_result = Ok(42).with_context("ignored for Ok")
# Ok(42)
Partitioning
from philiprehberger_result import Ok, Err, partition
oks, errs = partition([Ok(1), Err("a"), Ok(2), Err("b"), Ok(3)])
# oks == [1, 2, 3]
# errs == ["a", "b"]
Unlike collect(), partition() does not short-circuit on the first Err —
it walks the entire iterable and returns both lists.
Side-effect taps
from philiprehberger_result import Ok, Err
Ok(5).tap(lambda v: print(f"got {v}"))
# prints "got 5", returns Ok(5)
Err("boom").tap_err(lambda e: print(f"error: {e}"))
# prints "error: boom", returns Err("boom")
# Mismatched variants are no-ops:
Err("boom").tap(lambda v: print(v)) # does nothing, returns Err("boom")
Ok(5).tap_err(lambda e: print(e)) # does nothing, returns Ok(5)
API
| Function / Class | Description |
|---|---|
Ok(value) |
Success variant — wraps a value |
Err(error) |
Error variant — wraps an error |
.is_ok() / .is_err() |
Type check |
.unwrap() |
Get value or raise |
.unwrap_or(default) |
Get value or return default |
.unwrap_err() |
Get error or raise |
.map(fn) |
Transform Ok value |
.map_err(fn) |
Transform Err value |
.flat_map(fn) |
Chain Result-returning functions |
.or_else(fn) |
Fallback on Err, pass-through on Ok |
.flatten() |
Flatten nested Results: Ok(Ok(v)) -> Ok(v) |
.transpose() / transpose(result) |
Collapse nested Result: Ok(Ok(v)) -> Ok(v), Ok(Err(e)) -> Err(e), Err(e) -> Err(e) |
.match(ok=fn, err=fn) |
Pattern dispatch |
.to_dict() |
Serialize to {"ok": v} or {"err": e} |
ok(value) / err(error) |
Shorthand constructors |
try_catch(fn) |
Wrap callable in Result |
try_catch_async(fn) |
Async version |
from_awaitable(aw) |
Wrap awaitable in Result |
all_ok(results) |
Collect list of Results into Result of list |
map_batch(results, fn) |
Apply fn to all Ok values; short-circuit on first Err |
combine(*results) |
Merge multiple Results into Ok(tuple) or first Err |
collect(iterable) |
Convert iterable of Results into Result of list or first Err |
partition(results) |
Split iterable of Results into (oks, errs) lists without short-circuiting |
.with_context(msg) |
Wrap Err with context string; pass-through on Ok |
Ok.tap(fn) / Err.tap(fn) |
Call fn(value) on Ok for side effects; no-op on Err; returns self |
Ok.tap_err(fn) / Err.tap_err(fn) |
Call fn(error) on Err for side effects; no-op on Ok; returns self |
Development
pip install -e .
python -m pytest tests/ -v
Support
If you find this project useful:
License
Release files for philiprehberger-result 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| philiprehberger_result-0.6.0.tar.gz | 196.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| philiprehberger_result-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 203.7 kB
Release files / philiprehberger_result-0.6.0.tar.gz
| Download URL | philiprehberger_result-0.6.0.tar.gz |
|---|---|
| Size | 196.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8253a6f157a0c8ede583df727e4d09e7c03dfea11b221a91cbfdb882e85855c5
|
|
BLAKE2b-256 checksum How to use checksums |
fc5d0ff0641bf89b2b402f6a4361927a2a663c92e035186af32895a30edd0df4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / philiprehberger_result-0.6.0-py3-none-any.whl
| Download URL | philiprehberger_result-0.6.0-py3-none-any.whl |
|---|---|
| Size | 6.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8f3fdd0af50a87c4f7f10cd95f27eb234797cb12e0066e90cb84ae0118d17a75
|
|
BLAKE2b-256 checksum How to use checksums |
fdc2406cdbed92eb0e55026f1b8133ed6d88f328e1addb35ecef4216dd45cffe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|