A high-performance, type-safe Result type for Python, inspired by Rust.
Project description
pyresult
A high-performance, type-safe Result type for Python, inspired by Rust.
pyresult provides a robust and ergonomic way to handle operations that can either succeed (Ok) or fail (Err), eliminating the ambiguity of returning None or raising exceptions for expected errors.
This library is built with two core principles:
- Maximum Performance: The core logic is compiled to a native C extension using Mypyc, removing Python's interpreter overhead and delivering C-level speed.
- Absolute Type Safety: It is designed to pass
mypy --strictchecks, ensuring that your error-handling logic is sound and free of type-related bugs.
Core Philosophy
In many functions, errors are an expected possibility. Traditional Python error handling often relies on returning None (which can be ambiguous) or raising exceptions (which can be costly and verbose for control flow). pyresult offers a better way: a function returns a Result object, which is either an Ok containing a success value or an Err containing an error value. This makes the possibility of an error explicit in the function's type signature, forcing the caller to handle it gracefully.
Key Features
- Blazing Fast: Compiled with Mypyc for performance that rivals native C code.
- Type-Safe by Design: Fully annotated and validated with
mypy --strict. - Zero Dependencies: Relies only on the Python standard library.
- Ergonomic API: Provides a fluent, chainable interface for elegant error handling.
- Drop-in & Easy to Use: A simple and intuitive API that is easy to adopt in any project.
Installation
You can install pyresult directly from PyPI:
pip install py-pyresult
Or, install it directly from the GitHub repository:
pip install git+https://github.com/imsf04/py-pyresult.git
Quick Start
Here is a simple example of how to use pyresult:
from pyresult.result import Ok, Err, Result
def divide(a: int, b: int) -> Result[float, str]:
"""
A function that returns a Result: Ok(float) on success, or Err(str) on failure.
"""
if b == 0:
return Err("Cannot divide by zero")
return Ok(a / b)
# --- Example 1: Successful division ---
res1 = divide(10, 2)
if res1.is_ok:
# The operation was a success, we can safely unwrap the value.
value = res1.unwrap()
print(f"Success! Result is {value}") # Output: Success! Result is 5.0
# --- Example 2: Failed division ---
res2 = divide(10, 0)
if res2.is_err:
# The operation failed. We can get the error.
error_message = res2.unwrap_err()
print(f"Error: {error_message}") # Output: Error: Cannot divide by zero
# --- Example 3: Using the chainable API ---
result = divide(20, 2)
(result.map(lambda x: x - 5) # Ok(10.0) -> Ok(5.0)
.and_then(lambda x: Ok(x * 2)) # Ok(5.0) -> Ok(10.0)
.map_err(lambda e: f"Error: {e}")
)
print(result.unwrap_or(0.0)) # Output: 10.0
API Reference
Checking for Success or Failure
res.is_ok(property): ReturnsTrueif the result isOk.res.is_err(property): ReturnsTrueif the result isErr.
Extracting Values
res.ok() -> Optional[T]: Returns the value if the result isOk, otherwiseNone.res.err() -> Optional[E]: Returns the error if the result isErr, otherwiseNone.res.unwrap() -> T: Returns the value ifOk, but panics (raises anException) ifErr. Only use when you are certain of success.res.unwrap_err() -> E: Returns the error ifErr, but panics ifOk.res.unwrap_or(default: T) -> T: Returns the value ifOk, ordefaultifErr.res.unwrap_or_else(op: Callable[[E], T]) -> T: Returns the value ifOk, or computes it from a function ifErr.
Transforming Values
res.map(op: Callable[[T], U]) -> Result[U, E]: Maps aResult[T, E]toResult[U, E]by applying a function to a containedOkvalue, leaving anErrvalue untouched.res.map_err(op: Callable[[E], F]) -> Result[T, F]: Maps aResult[T, E]toResult[T, F]by applying a function to a containedErrvalue, leaving anOkvalue untouched.
Chaining Operations
res.and_then(op: Callable[[T], Result[U, E]]) -> Result[U, E]: Callsopif the result isOk, otherwise returns theErrvalue ofres. This is useful for chaining operations that might fail.res.or_else(op: Callable[[E], Result[T, F]]) -> Result[T, F]: Callsopif the result isErr, otherwise returns theOkvalue ofres. This is useful for handling an error by trying an alternative operation.
Checking Contents
res.contains(value: T) -> bool: ReturnsTrueif the result is anOkvalue containing the given value.res.contains_err(error_value: E) -> bool: ReturnsTrueif the result is anErrvalue containing the given error.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
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 py_pyresult-1.0.0.tar.gz.
File metadata
- Download URL: py_pyresult-1.0.0.tar.gz
- Upload date:
- Size: 5.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f416a85f9b16caa61a9107a6456a624c8bf6f42132c97488bb281d22113500f
|
|
| MD5 |
002c3bfc393f1caaba7689c4d3f01170
|
|
| BLAKE2b-256 |
d6108684335147f414f70801e9cb0a1bcf79a8ed1a5a8aebb8345637ffd6f7f9
|
File details
Details for the file py_pyresult-1.0.0-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: py_pyresult-1.0.0-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 38.6 kB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25345e7c42aa3d11255e13c03d5d0053a45ac45e2b54e3bba47dd8c275677d6a
|
|
| MD5 |
510f3c4610877a3b4a1ab0c88ca7135b
|
|
| BLAKE2b-256 |
5fa8edd021b3cd992726ad014eb7f129290d83aa3fd1b553d3d7f378b10133b5
|