Skip to content

Commit

Permalink
Working on .pyi types
Browse files Browse the repository at this point in the history
  • Loading branch information
sobolevn committed Feb 2, 2019
1 parent 125ded9 commit 24df71b
Show file tree
Hide file tree
Showing 38 changed files with 423 additions and 387 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Expand Up @@ -3,6 +3,14 @@
We follow Semantic Versions since the `0.1.0` release.


## Version 0.4.0

### Features

- Moves all types to `.pyi` files
- Renames all classes according to new naming pattern


## Version 0.3.1

### Bugfixes
Expand All @@ -27,7 +35,7 @@ The project is renamed to `returns` and moved to `dry-python` org.
- Adds `Maybe` monad
- Adds immutability and `__slots__` to all monads
- Adds methods to work with failures
- Adds `safe` decorator to convert exceptions to `Either` monad
- Adds `safe` decorator to convert exceptions to `Result` monad
- Adds `is_successful()` function to detect if your result is a success
- Adds `failure()` method to unwrap values from failed monads

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Expand Up @@ -9,7 +9,7 @@ you will need to get familiar with these concepts:

Here are some practical examples of what we are doing here:

- https://medium.com/@rnesytov/using-either-monad-in-python-b6eac698dff5
- https://medium.com/@rnesytov/using-Result-monad-in-python-b6eac698dff5
- https://www.morozov.is/2018/09/08/monad-laws-in-ruby.html


Expand Down
29 changes: 5 additions & 24 deletions README.md
Expand Up @@ -3,7 +3,7 @@
[![wemake.services](https://img.shields.io/badge/%20-wemake.services-green.svg?label=%20&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC%2FxhBQAAAAFzUkdCAK7OHOkAAAAbUExURQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP%2F%2F%2F5TvxDIAAAAIdFJOUwAjRA8xXANAL%2Bv0SAAAADNJREFUGNNjYCAIOJjRBdBFWMkVQeGzcHAwksJnAPPZGOGAASzPzAEHEGVsLExQwE7YswCb7AFZSF3bbAAAAABJRU5ErkJggg%3D%3D)](https://wemake.services) [![Build Status](https://travis-ci.org/dry-python/returns.svg?branch=master)](https://travis-ci.org/dry-python/returns) [![Coverage Status](https://coveralls.io/repos/github/dry-python/returns/badge.svg?branch=master)](https://coveralls.io/github/dry-python/returns?branch=master) [![Documentation Status](https://readthedocs.org/projects/returns/badge/?version=latest)](https://returns.readthedocs.io/en/latest/?badge=latest) [![Python Version](https://img.shields.io/pypi/pyversions/returns.svg)](https://pypi.org/project/returns/) [![wemake-python-styleguide](https://img.shields.io/badge/style-wemake-000000.svg)](https://github.com/wemake-services/wemake-python-styleguide)


Make your functions return something meaningful and safe!
Make your functions return something meaningful, typed, and safe!


## Features
Expand All @@ -21,27 +21,17 @@ Make your functions return something meaningful and safe!
pip install returns
```

## Why?

## What's inside?
TODO: example with `requests` and `json`

We have several the most iconic monads inside:

- [Result, Failure, and Success](https://returns.readthedocs.io/en/latest/pages/either.html) (also known as `Either`, `Left`, and `Right`)
- [Maybe, Some, and Nothing](https://returns.readthedocs.io/en/latest/pages/maybe.html)

We also care about code readability and developer experience,
so we have included some useful features to make your life easier:

- [Do notation](https://returns.readthedocs.io/en/latest/pages/do-notation.html)
- [Helper functions](https://returns.readthedocs.io/en/latest/pages/functions.html)


## Example
## Pipeline example


```python
from returns.do_notation import do_notation
from returns.either import Result, Success, Failure
from returns.result import Result, Success, Failure

class CreateAccountAndUser(object):
"""Creates new Account-User pair."""
Expand All @@ -59,12 +49,3 @@ class CreateAccountAndUser(object):
```

We are [covering what's going on in this example](https://returns.readthedocs.io/en/latest/pages/do-notation.html) in the docs.


## Inspirations

This module is heavily based on:

- [dry-rb/dry-monads](https://github.com/dry-rb/dry-monads)
- [Ø](https://github.com/dbrattli/OSlash)
- [pymonad](https://bitbucket.org/jason_delaat/pymonad)
2 changes: 1 addition & 1 deletion docs/conf.py
Expand Up @@ -31,7 +31,7 @@ def _get_project_meta():

pkg_meta = _get_project_meta()
project = pkg_meta['name']
copyright = '2019, wemake.services' # noqa: A001
copySuccess = '2019, wemake.services' # noqa: A001
author = 'wemake.services'

# The short X.Y version
Expand Down
11 changes: 10 additions & 1 deletion docs/index.rst
@@ -1,5 +1,14 @@
.. mdinclude:: ../README.md

Inspirations
------------

This module is heavily based on:

- `dry-rb/dry-monads <https://github.com/dry-rb/dry-monads>`_
- `Ø <https://github.com/dbrattli/OSlash>`_
- `pymonad <https://bitbucket.org/jason_delaat/pymonad>`_

Contents
--------

Expand All @@ -9,7 +18,7 @@ Contents

pages/monad.rst
pages/maybe.rst
pages/either.rst
pages/Result.rst
pages/do-notation.rst
pages/functions.rst

Expand Down
10 changes: 5 additions & 5 deletions docs/pages/do-notation.rst
Expand Up @@ -26,7 +26,7 @@ Here's the code to illustrate the task.
.. code:: python
from returns.do_notation import do_notation
from returns.either import Result, Success, Failure
from returns.result import Result, Success, Failure
class CreateAccountAndUser(object):
Expand Down Expand Up @@ -138,21 +138,21 @@ Limitations
-----------

There's one limitation in typing
that we are facing right now
that we are facing Success now
due to `mypy issue <https://github.com/python/mypy/issues/3157>`_:

.. code:: python
from returns.do_notation import do_notation
from returns.either import Success
from returns.result import Success
@do_notation
def function(param: int) -> Success[int]:
return Success(param)
reveal_type(function)
# Actual => def (*Any, **Any) -> returns.either.Right*[builtins.int]
# Expected => def (int) -> returns.either.Right*[builtins.int]
# Actual => def (*Any, **Any) -> returns.result.Success*[builtins.int]
# Expected => def (int) -> returns.result.Success*[builtins.int]
This effect can be reduced with the help of `Design by Contract <https://en.wikipedia.org/wiki/Design_by_contract>`_
with these implementations:
Expand Down
10 changes: 5 additions & 5 deletions docs/pages/either.rst
@@ -1,4 +1,4 @@
Either
Result
======

Also known as ``Result``.
Expand All @@ -13,9 +13,9 @@ and ``Failure`` indicates that something has failed.

.. code:: python
from returns.either import Result, Success, Failure
from returns.result import Result, Success, Failure
def find_user(user_id: int) -> Either['User', str]:
def find_user(user_id: int) -> Result['User', str]:
user = User.objects.filter(id=user_id)
if user.exists():
return Success(user[0])
Expand All @@ -36,7 +36,7 @@ and other ``None`` exception-friends.
API Reference
-------------

.. autoclasstree:: returns.either
.. autoclasstree:: returns.result

.. automodule:: returns.either
.. automodule:: returns.result
:members:
6 changes: 3 additions & 3 deletions docs/pages/functions.rst
Expand Up @@ -9,12 +9,12 @@ is_successful
:func:`is_succesful <returns.functions.is_successful>` is used to
tell whether or not your monad is a success.
We treat only treat monads that does not throw as a successful ones,
basically: :class:`Right <returns.either.Right>`
basically: :class:`Success <returns.result.Success>`
and :class:`Some <returns.maybe.Some>`.

.. code:: python
from returns.either import Success, Failure
from returns.result import Success, Failure
from returns.functions import is_successful
from returns.maybe import Some, Nothing
Expand All @@ -29,7 +29,7 @@ safe

:func:`safe <returns.functions.safe>` is used to convert
regular functions that can throw exceptions to functions
that return :class:`Either <returns.either.Either>` monad.
that return :class:`Result <returns.result.Result>` monad.

.. code:: python
Expand Down
18 changes: 9 additions & 9 deletions docs/pages/monad.rst
Expand Up @@ -47,13 +47,13 @@ is used to literally bind two different monads together.

.. code:: python
from returns.either import Either, Success
from returns.result import Result, Success
def make_http_call(user_id: int) -> Either[int, str]:
def make_http_call(user_id: int) -> Result[int, str]:
...
result = Success(1).bind(make_http_call)
# => Will be equal to either Success[int] or Failure[str]
# => Will be equal to Result Success[int] or Failure[str]
So, the rule is: whenever you have some impure functions,
it should return a monad instead.
Expand All @@ -63,7 +63,7 @@ to use monads with pure functions.

.. code:: python
from returns.either import Success
from returns.result import Success
def double(state: int) -> int:
return state * 2
Expand All @@ -87,7 +87,7 @@ during the pipeline execution:

.. code:: python
from returns.either import Failure
from returns.result import Failure
def double(state: int) -> float:
return state * 2.0
Expand All @@ -96,13 +96,13 @@ during the pipeline execution:
# => Will be equal to Success(2.0)
``ebind`` can return any monad you want.
It can also fix your flow and get on the right track again:
It can also fix your flow and get on the Success track again:

.. code:: python
from returns.either import Either, Failure, Success
from returns.result import Result, Failure, Success
def fix(state: Exception) -> Either[int, Exception]:
def fix(state: Exception) -> Result[int, Exception]:
if isinstance(state, ZeroDivisionError):
return Success(0)
return Failure(state)
Expand All @@ -123,7 +123,7 @@ inner state of monads into a regular types:

.. code:: python
from returns.either import Failure, Success
from returns.result import Failure, Success
Success(1).value_or(None)
# => 1
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
@@ -1,7 +1,7 @@
[tool.poetry]
name = "returns"
version = "0.3.1"
description = "Make your functions return something meaningful and safe!"
description = "Make your functions return something meaningful, typed, and safe!"
license = "MIT"

authors = [
Expand Down
2 changes: 1 addition & 1 deletion returns/do_notation.pyi
Expand Up @@ -4,10 +4,10 @@ from typing import Callable

from returns.primitives.types import MonadType


# Typing decorators is not an easy task, see:
# https://github.com/python/mypy/issues/3157


def do_notation(
function: Callable[..., MonadType],
) -> Callable[..., MonadType]:
Expand Down
100 changes: 0 additions & 100 deletions returns/either.pyi

This file was deleted.

0 comments on commit 24df71b

Please sign in to comment.