Example #1
0
 def get_fact_result(self) -> Result[str, Exception]:
     """Return a Result for a cat fact."""
     return (
         Result.of(
             requests.get,
             "https://cat-fact.herokuapp.com/facts/random",
             # this is the default, but sometimes the type checker wants us
             # to make it explicit. See python/mypy#3737 for deets.
             catch=Exception,
         )
         .and_then(lambda resp: Result.of(resp.json))
         .map(
             lambda parsed: t.cast(
                 str, parsed.get("text", "Unexpected cat fact format!")
             )
         )
     )
Example #2
0
    def test_collect_short_circuits(self) -> None:
        """Ensure collect does not iterate after an err is reached."""
        until_err: t.List[Result[int, str]] = [Ok(1), Ok(2), Err("no")]

        def _iterable() -> t.Iterable[Result[int, str]]:
            yield from until_err
            # If we continue iterating after the err, we will raise a
            # runtime Error.
            assert False, "Result.collect() did not short circuit on err!"

        assert Result.collect(_iterable()) == Err("no")
Example #3
0
 def get_fact(self) -> str:
     """Get a cat fact!"""
     return (
         # Create a Result from making our GET request.
         # Now we can start chaining!
         Result.of(
             requests.get, "https://cat-fact.herokuapp.com/facts/random"
         )
         # Let's first consider the success path.
         # If we got a response, it should be JSON, so let's try to parse
         .and_then(lambda resp: Result.of(resp.json))
         # If we successfully parsed JSON, we must have a dict, so let's
         # grab our cat fact, or a useful message.
         .map(
             lambda parsed: t.cast(
                 str, parsed.get("text", "Unexpected cat fact format!")
             )
         )
         # From here, all we need to do to consider the error case is
         # convert our Err type (which for Result.of() is any exception
         # that was raised) into the expected return type, which we
         # do by passing the error to `str()`
         .unwrap_or_else(str)
     )
Example #4
0
 def test_result_cannot_be_instantiated(self) -> None:
     """Result cannot be instantiated"""
     with pytest.raises(NotImplementedError):
         r: Result[str, str] = Result("a")
         assert r
Example #5
0
 def test_ok_if(self, predicate: t.Callable, val: t.Any,
                exp: Result) -> None:
     """Test constructing based on some predicate."""
     assert Result.ok_if(predicate, val) == exp
Example #6
0
 def test_collect(self, iterable: t.Iterable[Result[int, str]],
                  exp: Result[int, str]) -> None:
     """Test collecting an iterable of results into a single result."""
     assert Result.collect(iterable) == exp
Example #7
0
    def test_of_with_kwargs(self) -> None:
        """Test getting a result from a callable with args."""
        def foo(a: int, b: str = None) -> t.Optional[str]:
            return b

        assert Result.of(foo, 1, b="a").unwrap() == "a"
Example #8
0
 def test_of_with_args(self) -> None:
     """Test getting a result from a callable with args."""
     assert Result.of(lambda x: bool(x > 0), 1).unwrap() is True
Example #9
0
 def test_of(self, fn: t.Callable, exp: Result) -> None:
     """Test getting a result from a callable."""
     if exp.is_err():
         assert isinstance(Result.of(fn).unwrap_err(), exp.unwrap_err())
     else:
         assert Result.of(fn) == exp