Giter VIP home page Giter VIP logo

option's Introduction

Option

CircleCI

Rust-like Option and Result types in Python, slotted and fully typed.

An Option type represents an optional value, every Option is either Some and contains Some value, or NONE

A Result type represents a value that might be an error. Every Result is either Ok and contains a success value, or Err and contains an error value.

Using an Option type forces you to deal with None values in your code and increase type safety.

Using a Result type simplifies error handling and reduces try except blocks.

Quick Start

from option import Result, Option, Ok, Err
from requests import get


def call_api(url, params) -> Result[dict, int]:
    result = get(url, params)
    code = result.status_code
    if code == 200:
        return Ok(result.json())
    return Err(code)


def calculate(url, params) -> Option[int]:
    return call_api(url, params).ok().map(len)


dict_len = calculate('https://example.com', {})

Install

Option can be installed from PyPi:

pip install option

Documentation

The documentation lives at https://mat1g3r.github.io/option/

License

MIT

option's People

Contributors

dependabot[bot] avatar mat1g3r avatar saaketp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

option's Issues

Rationale behind `Result::{map_err,map}` func sig?

Love the python module! It makes my small codebase extremely simple and makes error handling much more sane!

What?

Though, I'm unable to get around the fact that Result.map_err has the effective func sig of:

map_err :: Result<T, E> -> (E -> F) -> Result<T, E | F>

The original return type is Result<T, E> | Result<T, F>.

I think it should just be Result<T, F>

Why?

My opinion, if it's Result::Ok, then map_err is no-op; the data (under user's scope) is only T, and we should be able to cast:
return typing.cast(Result[T, F], self)

If it's Result::Err, wouldn't it forcefully go through fn and become F?

In the end, both branches yields Result<T, F>, there is no possibility of E for error type.

The same argument applies for Result::map as well.

Why is this relevant?

I'm trying to implement an equivalence of ? operator in Rust:

E = TypeVar('E', bound=BaseException)
T = TypeVar('T')
def err_into(result: Result[T, E]) -> Result[T, str]:
    # TYPE ERR: E@result is invariant: E@err_into cannot be assigned to `str`
    return result.map_err(lambda e: str(e))

Typed Return Type for `flatmap` contradicts documentation

The documentation for flatmap states: "This is different than Option.map() because the result of the callback isn’t wrapped in a new Option." This test verifies that behavior:

    def test_flatmap_some():
        assert_that(option.Some(4).flatmap(lambda x: x + 1), equal_to(5))

However, the return type of the function is specified to be Option[U].

What is the expected behavior flatmap?

Surprising behavior for option.Option.Some(None)

I was learning this package to use in my own work. I was surprised by the behavior of this test:

    def test_ctor_some_but_none():
        sut = option.Some(None)
        # assert_that(sut.is_none)
        assert_that(sut.is_some)

I'll be the first to admit that I do not fully understand the expectations for an Option type, but I expected option.Some(None) to behave similarly to option.maybe(None).

What is the reason for this choice?

Introduce a safe eval function

Hi there - I love this little library, but I think some utility functions would really be beneficial for migrating exception code to using results.

Some thoughts, similar to the dry-returns library, we should introduce a safe function for a following use case:

Imagine refactoring this piece of (very hypothetical code):

def foo(a, b, c):
    try:
        a(b, c)
    except ZeroDivisionError:
        raise ValueError("cannot divide by zero")
    except Exception:
        raise TypeError("What?")

It can be very easily refactored with the introduction of safe function:

from functools import wraps
from option.result import Result

def _safe(func):
    @wraps(func)
    def safe_chain(*args, **kwargs):
        z = Result.Ok(func)
        try:
            return z.map(lambda x: x(*args, **kwargs))
        except Exception as e:  # noqa
            return Result.Err(e)
    return safe_chain

then refactoring foo becomes:

def foo(a, b, c):
  a = _safe(a)
  rval = a(b, c)
  if rval.is_ok:
      return rval
  if rval.unwrap_err() is ZeroDivisionError:
      return Result.Err("cannot divide by zero")
  else:
      return Result.Err("what?")

This works very well for languages that do not support try/except for control flows, which is something that can be mapped to non-Turing complete language subsets such as Starlark.

Thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.