A Python library providing a Result type for elegant error handling, inspired by Rust's Result type.
Project description
safe-result
A Python package for elegant error handling, inspired by Rust's Result type.
Installation
uv pip install "git+https://github.com/overflowy/safe-result"
Overview
safe-result provides type-safe objects that represent either success (Ok) or failure (Err). This approach enables more explicit error handling without relying on try/catch blocks, making your code more predictable and easier to reason about.
Key features:
- Type-safe result handling with generics support
- Type guards to safely access result values
- Decorators to automatically wrap function returns in
Resultobjects - Pattern matching support for elegant error handling
- Built-in traceback capture for comprehensive error information
Usage
Basic Usage
from safe_result import Err, Ok, Result, ok
def divide(a: int, b: int) -> Result[float, ZeroDivisionError]:
if b == 0:
return Err(ZeroDivisionError("Cannot divide by zero")) # Failure case
return Ok(a / b) # Success case
# Function signature clearly communicates potential failure modes
foo = divide(10, 0) # -> Result[float, ZeroDivisionError]
# Type checking will prevent unsafe access to the value
bar = 1 + foo.value
# ^^^^^^^^^ Pylance/mypy indicates error:
# "Operator '+' not supported for types 'Literal[1]' and 'float | None'"
# Safe access pattern using the type guard function
if ok(foo): # Verifies foo is an Ok result and enables type narrowing
bar = 1 + foo.value # Safe! - type system knows the value is a float here
else:
# Handle error case with full type information about the error
print(f"Error: {foo.error}")
Using the Decorators
The safe decorator automatically wraps function returns in an Ok or Err object. Any exception is caught and wrapped in an Err result.
from safe_result import Err, Ok, ok, safe
@safe
def divide(a: int, b: int) -> float:
return a / b
# Return type is inferred as Result[float, Exception]
foo = divide(10, 0)
if ok(foo):
print(f"Result: {foo.value}")
else:
print(f"Error: {foo}") # -> Err(division by zero)
print(f"Error type: {type(foo.error)}") # -> <class 'ZeroDivisionError'>
# Python's pattern matching provides elegant error handling
match foo:
case Ok(value):
bar = 1 + value
case Err(ZeroDivisionError):
print("Cannot divide by zero")
case Err(TypeError):
print("Type mismatch in operation")
case Err(ValueError):
print("Invalid value provided")
case _ as e:
print(f"Unexpected error: {e}")
The safe_with decorator provides more precise control by specifying which exception types to catch, improving type hints and safety.
from safe_result import ok, safe_with
@safe_with(ZeroDivisionError)
def divide(a: int, b: int) -> float:
return a / b
foo = divide(10, 0) # -> Result[float, ZeroDivisionError]
if not ok(foo):
print(f"Error: {foo}") # -> Err(division by zero)
print(f"Error type: {type(foo.error)}") # -> <class 'ZeroDivisionError'>
# Other exceptions are not caught, maintaining expected behavior
# foo = divide(10, "2") # Will raise a TypeError since it's not handled by the decorator
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file safe_result-2.1.0.tar.gz.
File metadata
- Download URL: safe_result-2.1.0.tar.gz
- Upload date:
- Size: 13.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d3ba3e7b3ff3a98fb2a65c4ad1ea58a72a0dd27160d39d3c2a82b2c4688f16c5
|
|
| MD5 |
e6f7bb66ec237b93041c0cbbfa12520b
|
|
| BLAKE2b-256 |
331aaf1db2a661876459a800335f7f01713583683372f95a223961a9b7a9f65c
|
File details
Details for the file safe_result-2.1.0-py3-none-any.whl.
File metadata
- Download URL: safe_result-2.1.0-py3-none-any.whl
- Upload date:
- Size: 4.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bbd1a07e8082830e63749a4c3ff1450f25139cb9eea78a30fa1e82398850dbef
|
|
| MD5 |
5cefb3c9a52ea247baf17f4fa1d97298
|
|
| BLAKE2b-256 |
550a996f383de742ffd261d5a8c306bfc5d8340b6a3528f7cd5fae59d8e9a8fc
|