Skip to main content
Archived

This project has been archived by its maintainers, and is no longer receiving any updates.

Build Status Stable Version Coverage Python License

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.

Metadata

Release files for thresult 0.9.25

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for thresult 0.9.25
File Size Uploaded
thresult-0.9.25.tar.gz 7.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for thresult 0.9.25
File Interpreter ABI Platform
thresult-0.9.25-py3-none-any.whl Python 3 none any Details

Total release size: 13.8 kB

Release files / thresult-0.9.25.tar.gz

Download URL thresult-0.9.25.tar.gz
Size 7.1 kB
Tags Source
SHA-256 checksum
How to use checksums
eb2e8a6b169c2fc7b70965e08d3ea8737296a62f4008a656de866ef0820a95c7
BLAKE2b-256 checksum
How to use checksums
9793a13c429a8f2cdcb5433d20985b79e0d618f83bf94e442b0fc7ac7f1f38ee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.2.2 CPython/3.11.0 Linux/5.4.109+

Release files / thresult-0.9.25-py3-none-any.whl

Download URL thresult-0.9.25-py3-none-any.whl
Size 6.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
763a30824a32aa62b30c0418e4c91b2c8391be259c3b6fce2bbb0781483d91ff
BLAKE2b-256 checksum
How to use checksums
4de1b73408fdb352d97c162d030f23c17c105b09eead9e41020ac45c2c483f5b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.2.2 CPython/3.11.0 Linux/5.4.109+
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page