Skip to content

Commit 8666fd3

Browse files
committed
Closes #148, closes #135, closes #145
1 parent 796ea8c commit 8666fd3

File tree

15 files changed

+506
-62
lines changed

15 files changed

+506
-62
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,20 @@ incremental in minor, bugfixes only are patches.
66
See (0Ver)[https://0ver.org/].
77

88

9+
## 0.11.0 WIP
10+
11+
### Features
12+
13+
- Adds `tap` function
14+
- Now `pipe` allows to pipe 8 steps
15+
16+
### Misc
17+
18+
- Now all methods have doctests
19+
- Updates docs about `Success` and `_Success`, `Failure` and `_Failure`
20+
- Updates docs about `@pipeline`
21+
22+
923
## 0.10.0
1024

1125
### Features

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ Make your functions return something meaningful, typed, and safe!
1414
- Provides a bunch of primitives to write declarative business logic
1515
- Enforces better architecture
1616
- Fully typed with annotations and checked with `mypy`, [PEP561 compatible](https://www.python.org/dev/peps/pep-0561/)
17+
- Has a bunch of helpers for better composition
1718
- Pythonic and pleasant to write and to read (!)
1819
- Support functions and coroutines, framework agnostic
20+
- Easy to start: has lots of docs, tests, and tutorials
1921

2022

2123
## Installation

docs/pages/container.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ or we can fix the situation.
116116
S3 --> S5
117117
S5 --> S7
118118

119-
F2 -- Map Failure --> F4
119+
F2 -- Alt --> F4
120120
F4 --> F6
121121
F6 --> F8
122122

docs/pages/functions.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,23 @@ but how can we do it inversevely?
5252
That's it.
5353

5454

55+
tap
56+
---
57+
58+
We need ``tap()`` function to easily compose values
59+
with functions that does not return.
60+
For example you sometimes need to ``print()`` values inside your :ref:`pipe`:
61+
62+
.. code:: python
63+
64+
from returns.functions import tap
65+
66+
result = tap(print)(1) # will print and return 1
67+
# => prints 1
68+
assert result == 1
69+
# => True
70+
71+
5572
raise_exception
5673
---------------
5774

poetry.lock

Lines changed: 23 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@ typing-extensions = "^3.7"
4646

4747
[tool.poetry.dev-dependencies]
4848
mypy = "^0.720"
49-
wemake-python-styleguide = "^0.12.3"
49+
wemake-python-styleguide = "^0.12.4"
5050
flake8-pytest = "^1.3"
5151
flake8-pytest-style = "^0.1.3"
5252
flake8-pyi = "^19.3"
53-
nitpick = "^0.20.0"
53+
nitpick = "^0.21.0"
5454

5555
safety = "^1.8"
5656

returns/converters.py

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,42 @@
1313
def result_to_maybe(
1414
result_container: Result[_ValueType, _ErrorType],
1515
) -> Maybe[_ValueType]:
16-
"""Converts ``Result`` container to ``Maybe`` container."""
16+
"""
17+
Converts ``Result`` container to ``Maybe`` container.
18+
19+
.. code:: python
20+
21+
>>> from returns.maybe import Some, Nothing
22+
>>> from returns.result import Failure, Success
23+
>>> result_to_maybe(Success(1)) == Some(1)
24+
True
25+
>>> result_to_maybe(Failure(1)) == Nothing
26+
True
27+
>>> result_to_maybe(Success(None)) == Nothing
28+
True
29+
30+
"""
1731
return Maybe.new(result_container.value_or(None))
1832

1933

2034
def maybe_to_result(
2135
maybe_container: Maybe[_ValueType],
2236
) -> Result[_ValueType, None]:
23-
"""Converts ``Maybe`` container to ``Result`` container."""
37+
"""
38+
Converts ``Maybe`` container to ``Result`` container.
39+
40+
.. code:: python
41+
42+
>>> from returns.maybe import Some, Nothing
43+
>>> from returns.result import Failure, Success
44+
>>> maybe_to_result(Nothing) == Failure(None)
45+
True
46+
>>> maybe_to_result(Some(1)) == Success(1)
47+
True
48+
>>> maybe_to_result(Some(None)) == Failure(None)
49+
True
50+
51+
"""
2452
inner_value = maybe_container.value_or(None)
2553
if inner_value is not None:
2654
return Success(inner_value)
@@ -45,5 +73,20 @@ def join(
4573

4674

4775
def join(container):
48-
"""Joins two nested containers together."""
76+
"""
77+
Joins two nested containers together.
78+
79+
.. code:: python
80+
81+
>>> from returns.maybe import Some
82+
>>> from returns.result import Success
83+
>>> from returns.io import IO
84+
>>> join(IO(IO(1))) == IO(1)
85+
True
86+
>>> join(Some(Some(1))) == Some(1)
87+
True
88+
>>> join(Success(Success(1))) == Success(1)
89+
True
90+
91+
"""
4992
return container._inner_value # noqa: WPS437

returns/functions.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22

3-
from typing import Callable, NoReturn, TypeVar
3+
from typing import Any, Callable, NoReturn, TypeVar
44

55
from returns.generated.box import _box as box # noqa: F401, WPS436
66

@@ -22,7 +22,6 @@ def compose(
2222
2323
.. code:: python
2424
25-
>>> from returns.functions import compose
2625
>>> compose(float, int)('123.5')
2726
123
2827
@@ -32,6 +31,32 @@ def compose(
3231
return lambda argument: second(first(argument))
3332

3433

34+
def tap(
35+
function: Callable[[_FirstType], Any],
36+
) -> Callable[[_FirstType], _FirstType]:
37+
"""
38+
Allows to apply some function and return an argument, instead of a result.
39+
40+
Is usefull for side-effects like ``print()``, ``logger.log``, etc.
41+
42+
.. code:: python
43+
44+
>>> tap(print)(1)
45+
1
46+
1
47+
>>> tap(lambda _: 1)(2)
48+
2
49+
50+
See also:
51+
- https://github.com/dry-python/returns/issues/145
52+
53+
"""
54+
def decorator(argument_to_return: _FirstType) -> _FirstType:
55+
function(argument_to_return)
56+
return argument_to_return
57+
return decorator
58+
59+
3560
def raise_exception(exception: Exception) -> NoReturn:
3661
"""
3762
Helper function to raise exceptions as a function.
@@ -41,7 +66,6 @@ def raise_exception(exception: Exception) -> NoReturn:
4166
4267
.. code:: python
4368
44-
>>> from returns.functions import raise_exception
4569
>>> from returns.result import Failure, Result
4670
>>> # Some operation result:
4771
>>> user: Result[int, ValueError] = Failure(ValueError('boom'))

returns/generated/pipe.pyi

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ _T5 = TypeVar('_T5')
1010
_T6 = TypeVar('_T6')
1111
_T7 = TypeVar('_T7')
1212
_T8 = TypeVar('_T8')
13+
_T9 = TypeVar('_T9')
1314

1415

1516
@overload
@@ -87,3 +88,18 @@ def _pipe(
8788
p8: Callable[[_T7], _T8],
8889
) -> _T8:
8990
...
91+
92+
93+
@overload # noqa: WPS211
94+
def _pipe(
95+
p1: _T1,
96+
p2: Callable[[_T1], _T2],
97+
p3: Callable[[_T2], _T3],
98+
p4: Callable[[_T3], _T4],
99+
p5: Callable[[_T4], _T5],
100+
p6: Callable[[_T5], _T6],
101+
p7: Callable[[_T6], _T7],
102+
p8: Callable[[_T7], _T8],
103+
p9: Callable[[_T8], _T9],
104+
) -> _T9:
105+
...

returns/io.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ def map( # noqa: A003
4646
and returns a new IO object containing the result.
4747
'function' should accept a single "normal" (non-container) argument
4848
and return a non-container result.
49+
50+
.. code:: python
51+
52+
>>> def mappable(string: str) -> str:
53+
... return string + 'b'
54+
...
55+
>>> IO('a').map(mappable) == IO('ab')
56+
True
57+
4958
"""
5059
return IO(function(self._inner_value))
5160

@@ -57,6 +66,15 @@ def bind(
5766
5867
'function' should accept a single "normal" (non-container) argument
5968
and return IO type object.
69+
70+
.. code:: python
71+
72+
>>> def bindable(string: str) -> IO[str]:
73+
... return IO(string + 'b')
74+
...
75+
>>> IO('a').bind(bindable) == IO('ab')
76+
True
77+
6078
"""
6179
return function(self._inner_value)
6280

@@ -75,7 +93,6 @@ def lift(
7593
7694
.. code:: python
7795
78-
>>> from returns.io import IO
7996
>>> def example(argument: int) -> float:
8097
... return argument / 2 # not exactly IO action!
8198
...

0 commit comments

Comments
 (0)