Skip to main content

A rust-like result type for Python

Project description

Build status Coverage

A simple Result type for Python 3 inspired by Rust.

The idea is that a Result value can be either Ok(value) or Err(error), with a way to differentiate between the two. It will change code like this:

def get_user_by_email(email):
    """
    Return the user instance or an error message.
    """
    if not user_exists(email):
        return None, 'User does not exist'
    if not user_active(email):
        return None, 'User is inactive'
    user = get_user(email)
    return user, None

user, reason = get_user_by_email('ueli@example.com')
if user is None:
    raise RuntimeError('Could not fetch user: %s' % reason)
else:
    do_something(user)

To something like this:

from result import Ok, Err

def get_user_by_email(email):
    """
    Return the user instance or an error message.
    """
    if not user_exists(email):
        return Err('User does not exist')
    if not user_active(email):
        return Err('User is inactive')
    user = get_user(email)
    return Ok(user)

user_result = get_user_by_email(email)
if user_result.is_ok():
    do_something(user_result.value)
else:
    raise RuntimeError('Could not fetch user: %s' user_result.value)

As this is Python and not Rust, you will lose some of the advantages that it brings, like elegant combinations with the match statement. On the other side, you don’t have to return semantically unclear tuples anymore.

Not all methods (https://doc.rust-lang.org/std/result/enum.Result.html) have been implemented, only the ones that make sense in the Python context. You still don’t get any type safety, but some easier handling of types that can be OK or not, without resorting to custom exceptions.

API

Creating an instance:

>>> from result import Ok, Err
>>> res1 = Ok('yay')
>>> res2 = Err('nay')

Or through the class methods:

>>> from result import Result
>>> res1 = Result.Ok('yay')
>>> res2 = Result.Err('nay')

Checking whether a result is ok or not:

>>> res = Ok('yay')
>>> res.is_ok()
True
>>> res.is_err()
False

Convert a Result to the value or None:

>>> res1 = Ok('yay')
>>> res2 = Err('nay')
>>> res1.ok()
'yay'
>>> res2.ok()
None

Convert a Result to the error or None:

>>> res1 = Ok('yay')
>>> res2 = Err('nay')
>>> res1.err()
None
>>> res2.err()
'nay'

Access the value directly, without any other checks:

>>> res1 = Ok('yay')
>>> res2 = Err('nay')
>>> res1.value
'yay'
>>> res2.value
'nay'

Note that this is a property, you cannot assign to it. Results are immutable.

For your convenience, simply creating an Ok result without value is the same as using True:

>>> res1 = Result.Ok()
>>> res1.value
True
>>> res2 = Ok()
>>> res2.value
True

The unwrap method returns the value if Ok, otherwise it raises an UnwrapError:

>>> res1 = Ok('yay')
>>> res2 = Err('nay')
>>> res1.unwrap()
'yay'
>>> res2.unwrap()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\project\result\result.py", line 107, in unwrap
    return self.expect("Called `Result.unwrap()` on an `Err` value")
File "C:\project\result\result.py", line 101, in expect
    raise UnwrapError(message)
result.result.UnwrapError: Called `Result.unwrap()` on an `Err` value

A custom error message can be displayed instead by using expect:

>>> res1 = Ok('yay')
>>> res2 = Err('nay')
>>> res1.expect('not ok')
'yay'
>>> res2.expect('not ok')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\project\result\result.py", line 101, in expect
    raise UnwrapError(message)
result.result.UnwrapError: not ok

A default value can be returned instead by using unwrap_or:

>>> res1 = Ok('yay')
>>> res2 = Err('nay')
>>> res1.unwrap_or('default')
'yay'
>>> res2.unwrap_or('default')
'default'

License

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

result-0.4.0.tar.gz (4.7 kB view details)

Uploaded Source

Built Distribution

result-0.4.0-py3-none-any.whl (5.2 kB view details)

Uploaded Python 3

File details

Details for the file result-0.4.0.tar.gz.

File metadata

  • Download URL: result-0.4.0.tar.gz
  • Upload date:
  • Size: 4.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.9.0 requests-toolbelt/0.9.1 tqdm/4.28.1 CPython/3.7.3

File hashes

Hashes for result-0.4.0.tar.gz
Algorithm Hash digest
SHA256 2e3d086e0dad69b8bd3f34939822872a6b5ea4e7f7ba437182cbc0417d1d4379
MD5 cf2614a18a6ba60cdb467bd879e004a8
BLAKE2b-256 d8b06e709c3692e22c1ba3d3697434b05a8d5887519646aff394d4a2b08c533e

See more details on using hashes here.

File details

Details for the file result-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: result-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 5.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.9.0 requests-toolbelt/0.9.1 tqdm/4.28.1 CPython/3.7.3

File hashes

Hashes for result-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 582c6c464b188ad9f13bc1cacc67d02502ed77b92acbcda9bc541c6cb049a2f9
MD5 9217ad5b9198cba7f5758985fad47d72
BLAKE2b-256 cb1c2046b5cf6640d20b7d1b2d1307a02ecd565a2ecd83c274db9da7f0ccc872

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page