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
thresult-0.9.25.tar.gz
(7.1 kB
view details)
Built Distribution
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 |