Tangled Result
Project description
thresult
Python Result library for handling returned values (Result, Ok, Err) from functions/methods and handling errors. It is error handling library which is alternative to try/except style of programming.
It is inspired by great Rust Result, Ok, Err types.
Installation
pip install thresult
Simple Usage
Traditional try-except example
def div(x: float, y: float) -> float:
z: float = x / y
return z
z0: float = div(1.0, 2.0) # 0.5
z1: float = div(1.0, 0.0) # raises "ZeroDivisionError: division by zero" exception
Unwrapping Result as Context Manager
from thresult import Result
@Result
def div(x: float, y: float) -> float:
z: float = x / y
return z
try:
with div(1.0, 0.0) as z:
# unreachable
r: float = z
except ZeroDivisionError as e:
# exception happened
pass
Unwrapping Result in unwrap Context Manager
from thresult import Result, unwrap
@Result
def f(x: float, y: float) -> float:
z: float = x / y
return z
try:
with unwrap():
# unreachable
r: float = f(1, 0)
except ZeroDivisionError as e:
# exception happened
raise e
Pattern-matching Result using match-case
from thresult import Result, Ok, Err
@Result
def div(x: float, y: float) -> float:
# can raise "ZeroDivisionError: division by zero" exception
z: float = x / y
return z
r: Result = div(1.0, 2.0) # Ok[float](0.5)
match r:
case Ok(v):
assert v == 0.5
case Err(e):
# unreachable
# "ZeroDivisionError: division by zero"
assert isinstance(e, ZeroDivisionError)
In-place pattern-matching Result using walrus operator and match-case
@Result
def div(x: float, y: float) -> float:
# can raise "ZeroDivisionError: division by zero" exception
z: float = x / y
return z
match r := div(1.0, 2.0): # Ok[float](0.5)
case Ok(v):
assert v == 0.5
case Err(e):
# unreachable
# "ZeroDivisionError: division by zero"
assert isinstance(e, ZeroDivisionError)
Advanced Usage
Unwrapping Result[float, ZeroDivisionError] as Context Manager
from thresult import Result, Ok, Err
@Result[float, ZeroDivisionError]
def div(x: float, y: float) -> float:
z: float = x / y
return z
try:
with div(1.0, 0.0) as z:
# unreachable
pass
except ZeroDivisionError as e:
# exception happened
pass
Manually create Result value, and Structural Pattern Matching
from thresult import Result, Ok, Err
def div(x: float, y: float) -> Result[float, ZeroDivisionError]:
res: Result[float, ZeroDivisionError]
try:
# can raise "ZeroDivisionError: division by zero" exception
z: float = x / y
res = Ok[float](z)
except ZeroDivisionError as e:
res = Err[ZeroDivisionError](e)
return res
r0: Result = div(1.0, 2.0) # Ok
r1: Result = div(1.0, 0.0) # Err
match r0:
case Ok(v):
print('Ok, value:', v)
case Err(e):
print('Err, error:', e) # "ZeroDivisionError: division by zero"
match r1:
case Ok(v):
print('Ok, value:', v)
case Err(e):
print('Err, error:', e) # "ZeroDivisionError: division by zero"
z0: float = r0.unwrap() # 0.5
z1: float = r1.unwrap_or(float('inf')) # inf
z1: float = r1.unwrap() # raises "ZeroDivisionError: division by zero" exception
Decorate function with Result, and Structural Pattern Matching
from thresult import Result, Ok, Err
@Result[float, ZeroDivisionError]
def div(x: float, y: float) -> float:
# can raise "ZeroDivisionError: division by zero" exception
z: float = x / y
return z
r0: Result = div(1.0, 2.0) # Ok
r1: Result = div(1.0, 0.0) # Err
match r0:
case Ok(v):
print('Ok, value:', v)
case Err(e):
print('Err, error:', e) # "ZeroDivisionError: division by zero"
match r1:
case Ok(v):
print('Ok, value:', v)
case Err(e):
print('Err, error:', e) # "ZeroDivisionError: division by zero"
z0: float = r0.unwrap() # 0.5
z1: float = r1.unwrap_or(float('inf')) # inf
z1: float = r1.unwrap() # raises "ZeroDivisionError: division by zero" exception
Run / Develop Cycle
docker run --rm -it -v $PWD/thresult:/code -w /code python:3.11-alpine python -B result.py
Testing
docker-compose build thresult-test ; docker-compose run --rm -v $PWD:/test thresult-test
Coverage
docker-compose build thresult-coverage ; docker-compose run --rm -v $PWD:/test thresult-coverage
Building
docker-compose build thresult-build ; docker-compose run --rm thresult-build
Licensing
thresult is licensed under the BSD 3 license.
Check the LICENSE 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 thresult-0.9.25.tar.gz.
File metadata
- Download URL: thresult-0.9.25.tar.gz
- Upload date:
- Size: 7.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.2.2 CPython/3.11.0 Linux/5.4.109+
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb2e8a6b169c2fc7b70965e08d3ea8737296a62f4008a656de866ef0820a95c7
|
|
| MD5 |
195ea0abcd51f63135a546924568a3c5
|
|
| BLAKE2b-256 |
9793a13c429a8f2cdcb5433d20985b79e0d618f83bf94e442b0fc7ac7f1f38ee
|
File details
Details for the file thresult-0.9.25-py3-none-any.whl.
File metadata
- Download URL: thresult-0.9.25-py3-none-any.whl
- Upload date:
- Size: 6.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.2.2 CPython/3.11.0 Linux/5.4.109+
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
763a30824a32aa62b30c0418e4c91b2c8391be259c3b6fce2bbb0781483d91ff
|
|
| MD5 |
41f69ac1a3a6529956111ba7d2593628
|
|
| BLAKE2b-256 |
4de1b73408fdb352d97c162d030f23c17c105b09eead9e41020ac45c2c483f5b
|