TangledHub Result
Project description
thresult
Overview
TangledHub library for handling returned values from functions/methods and handling errors.
Licencing
thresult is licensed under the BSD license. Check the LICENSE file for details
Installation
pip install thresult
Testing
docker-compose build thresult-test ; docker-compose run --rm thresult-test
Building
docker-compose build thresult-build ; docker-compose run --rm thresult-build
Publish
docker-compose build thresult-publish ; docker-compose run --rm -e PYPI_USERNAME=__token__ -e PYPI_PASSWORD=__SECRET__ thresult-publish
Run examples from Docker
docker run -it -v $PWD/examples:/code -v $PWD:/deps/thresult -e PYTHONPATH=/deps python:3.10 /bin/bash
cd /code
python -B traceback_0.py
python -B traceback_1.py
python -B traceback_2.py
python -B traceback_3.py
Usage
thresult provides type system for handling values and exceptions in Python. Expressions can return value of type Result and variables can hold value of type Result. Result can be Ok or Err. Ok type has attribute v and Err type has attribute e. If some expression doesn't rise exception, it will return Ok type where v attribute will be result of expression. If error occurs, Err type will be returned, and e attribute of that type will contain error message. Custom types can be created, and they must extend Result, Ok or Err type.
Example when returned value is Ok type
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
r: Result = f(1.0, 20.0) # r is Ok[<class 'float'>] object
Example when returned value is Err type
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
# divide with 0.0 will not rise exception,
# object type Err[<class 'Exception'>] is returned
r: Result = f(1.0, 0.0) # r is Err[<class 'Exception'>] object
To obtain a value from Ok or Err type
- structural pattern matching
- unwrap()
- unwrap_value()
- unwrap_or(v: Any)
There are different ways to handle exceptions
Obtain a value from Ok or Err type with structural pattern matching
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
r: Result = f(1.0, 0.0)
match r:
case Ok(v):
print('Ok, value: ', v)
case Err(e):
print('Err, error: ', e) # float division by zero
Using structural pattern matching to handle exceptions.
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
match f(1.0, 0.0):
case Ok(v):
print('Ok, value: ', v)
case Err(e):
print('Err, error: ', e) # float division by zero
Using unwrap to handle exceptions. In case of error, exception is thrown.
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
r: Result = f(1.0, 0.0)
z: float = r.unwrap() # ZeroDivisionError: float division by zero
Using unwrap_value to handle exceptions. In case of error, unwrap_value returns error message and doesn't terminate program.
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
r: Result = f(1.0, 0.0)
v: str = r.unwrap_value()
# v will contain error message, float division by zero
Using unwrap_or to handle exceptions. In case of error, unwrap_or returns value passed as argument and doesn't terminate program. In this example it is 0.0.
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
r: Result = f(1.0, 0.0)
v: float = r.unwrap_or(0.0)
# v will contain value 0.0
Obtain a value from Ok type using structural pattern matching.
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
r: Result = f(1.0, 10.0)
match r:
case Ok(v):
# v holds value of division operation - 0.1
print('Ok, value: ', v)
case Err(e):
print('Err, error: ', e)
Obtain a value from Ok type using structural pattern matching.
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
match f(1.0, 10.0):
case Ok(v):
# v holds value of division operation - 0.1
print('Ok, value: ', v)
case Err(e):
print('Err, error: ', e)
Obtain a value from Ok type using unwrap method on variable. Variable holds a value of Ok type.
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
r: Result = f(1.0, 10.0)
v: float = r.unwrap() # v is 0.1
Obtain a value from Ok type using unwrap method on expression. Expression returns a value of Ok type.
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
v: float = (f(1.0, 10.0)).unwrap() # v is 0.1
Obtain a value from Ok type using unwrap_value method on variable. Variable holds a value of Ok type. If value is Ok type, unwrap_value has no effects, it is same as unwrap method.
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
r: Result = f(1.0, 10.0)
v: float = r.unwrap_value() # v is 0.1
Obtain a value from Ok type using unwrap method on expression. Expression returns a value of Ok type. If value is Ok type, unwrap_value has no effects, it is same as unwrap method.
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
v: float = (f(1.0, 10.0)).unwrap_value() # v is 0.1
Obtain a value from Ok type using unwrap_or method on variable. Variable holds a value of Ok type. If value is Ok type, unwrap_or has no effects, it is same as unwrap or unwrap_value method.
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
r: Result = f(1.0, 10.0)
v: float = r.unwrap_or(10.1) # v is 0.1
Obtain a value from Ok type using unwrap_or method on expression. Expression returns a value of Ok type. If value is Ok type, unwrap_or has no effects, it is same as unwrap or unwrap_value method.
from thresult import Result, Ok, Err
def f(a: float, b: float) -> Result[float, Exception]:
try:
r: float = a / b
res = Ok[float](r)
except Exception as e:
res = Err[Exception](e)
return res
v: float = (f(1.0, 10.0)).unwrap_or(10.1) # v is 0.1
thresult provides type checking
from thresult import Result, Ok, Err
class A:
pass
a = A()
at: Ok[A] = Ok[A](a)
at: Ok[A] = Ok[A](4) # TypeError: Got <class 'int'> but expected <class 'A'>
create custom types by extending Ok and Err
from thresult import Result, Ok, Err
class AOk(Ok):
pass
class AErr(Err):
pass
CustomResult: type = AOk[float] | AErr[str]
r: CustomResult = AOk[int](5)
v: int = r.unwrap_value() # v holds value of 5
Using decorators to obtain Ok type
from thresult import Result, Ok, Err
@Result[float, str]
def f(n: float):
return 1/n
v = f(10.0) # Ok[<class 'float'>]
f: float = v.unwrap() # 0.1
Using decorators to obtain Err type
from thresult import Result, Ok, Err
@Result[float, str]
def f(n: float):
return 1 / n
v = f(0.0)
m: str = v.unwrap_value() # float division by zero
Using decorators to obtain Ok Custom result type
from thresult import Result, Ok, Err
# custom result type
CustomResult: type = Ok[float] | Err[str]
@CustomResult[float, str]
def f(n: float):
return 1 / n
v = f(10.0) # Ok[<class 'float'>]
f: float = v.unwrap() # 0.1
Using decorators to obtain Ok Custom result type Using unwrap_value
from thresult import Result, Ok, Err
# custom result type
CustomResult: type = Ok[float] | Err[str]
@CustomResult[float, str]
def f(n: float):
return 1 / n
v = f(10.0) # Ok[<class 'float'>]
f: float = v.unwrap_value() # 0.1
Using decorators to obtain Ok Custom result type Using unwrap_or
from thresult import Result, Ok, Err
# custom result type
CustomResult: type = Ok[float] | Err[str]
@CustomResult[float, str]
def f(n: float):
return 1 / n
v = f(10.0) # Ok[<class 'float'>]
f: float = v.unwrap_or(10.1) # 0.1
Using decorators to obtain Err Custom result type
from thresult import Result, Ok, Err
CustomResult: type = Ok[float] | Err[str]
@CustomResult[float, str]
def f(n: float):
return 1 / n
v = f(0.0) # Err[<class 'str'>]
# panic: raising exception
f: float = v.unwrap() # ZeroDivisionError: float division by zero
Using decorators to obtain Err Custom result type
from thresult import Result, Ok, Err
CustomResult: type = Ok[float] | Err[str]
@CustomResult[float, str]
def f(n: float):
return 1 / n
v = f(0.0) # Err[<class 'str'>]
# doesn't panic, returns exception's message as string
f: float = v.unwrap_value() # string value: float division by zero
Using decorators to obtain Err. Custom result type Using unwrap_or()
from thresult import Result, Ok, Err
CustomResult: type = Ok[float] | Err[str]
@CustomResult[float, 'str']
def f(n: float):
return 1 / n
v = f(0.0) # Err[<class 'str'>]
# doesn't panic, returns custom exception's message as string
f: float = v.unwrap_or('Zero division: Custom message') # string value: Zero division: Custom message
Using decorators to obtain Ok. Custom result type and custom Ok type
from thresult import Result, Ok, Err
class CustomOk(Ok):
pass
class CustomErr(Err):
pass
CustomResult: type = CustomOk[float] | CustomErr[str]
@CustomResult[float, str]
def f(n: float):
return 1 / n
v = f(10.0) # Ok[<class 'float'>]
Using decorators to obtain Ok. Custom result type and custom Ok type. Obtain value with unwrap
from thresult import Result, Ok, Err
class CustomOk(Ok):
pass
class CustomErr(Err):
pass
CustomResult: type = CustomOk[float] | CustomErr[str]
@CustomResult[float, str]
def f(n: float):
return 1 / n
v = f(10.0) # Ok[<class 'float'>]
r: float = v.unwrap() # 0.1
Using decorators to obtain Ok. Custom result type and custom Ok type. Obtain value with unwrap_value
from thresult import Result, Ok, Err
class CustomOk(Ok):
pass
class CustomErr(Err):
pass
CustomResult: type = CustomOk[float] | CustomErr[str]
@CustomResult[float, str]
def f(n: float):
return 1 / n
v = f(10.0) # Ok[<class 'float'>]
r: float = v.unwrap_value() # 0.1
Using decorators to obtain Ok. Custom result type and custom Ok type. Obtain value with unwrap_or
from thresult import Result, Ok, Err
class CustomOk(Ok):
pass
class CustomErr(Err):
pass
CustomResult: type = CustomOk[float] | CustomErr[str]
@CustomResult[float, str]
def f(n: float):
return 1 / n
v = f(10.0) # Ok[<class 'float'>]
r: float = v.unwrap_or(10.1) # 0.1
Using decorators to obtain Err. Custom result type and custom Err type
from thresult import Result, Ok, Err
class CustomOk(Ok):
pass
class CustomErr(Err):
pass
CustomResult: type = CustomOk[float] | CustomErr[str]
@CustomResult[float, str]
def f(n: float):
return 1 / n
v = f(0.0) # Err[<class 'str'>]
Using decorators to obtain Err. Custom result type and custom Err type. Handling exceptions using unwrap
from thresult import Result, Ok, Err
class CustomOk(Ok):
pass
class CustomErr(Err):
pass
CustomResult: type = CustomOk[float] | CustomErr[str]
@CustomResult[float, str]
def f(n: float):
return 1 / n
v = f(0.0) # Err[<class 'str'>]
try:
v.unwrap()
except ZeroDivisionError as e:
pass
Using decorators to obtain Err. Custom result type and custom Err type. Handling exceptions using unwrap_value
from thresult import Result, Ok, Err
class CustomOk(Ok):
pass
class CustomErr(Err):
pass
CustomResult: type = CustomOk[float] | CustomErr[str]
@CustomResult[float, str]
def f(n: float):
return 1 / n
v = f(0.0) # Err[<class 'str'>]
message: str = v.unwrap_value() # float division by zero
Using decorators to obtain Err. Custom result type and custom Err type. Handling exceptions using unwrap_or
from thresult import Result, Ok, Err
class CustomOk(Ok):
pass
class CustomErr(Err):
pass
CustomResult: type = CustomOk[float] | CustomErr[str]
@CustomResult[float, str]
def f(n: float):
return 1 / n
v = f(0.0) # Err[<class 'str'>]
message: str = v.unwrap_or('Custom message') # Custom message
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
Hashes for thresult-0.9.5.1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0709de78598df45f96b2fdbb9e37b29e8c380137f49c2d5fadfe9720ef6d6ca4 |
|
MD5 | 8f457d04b1694cf56f67c8825c327eb1 |
|
BLAKE2b-256 | ee9a0867d1ce76813645352f4732dea0a0009afb8bc7c065ac4a64a2638236c8 |