Skip to content

Commit

Permalink
Version 0.7.0 release
Browse files Browse the repository at this point in the history
  • Loading branch information
sobolevn committed Jun 11, 2019
1 parent a5d2059 commit 3014ecc
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 12 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
We follow Semantic Versions since the `0.1.0` release.


## WIP
## 0.7.0

### Features

Expand Down
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ class FetchUserProfile(object):
return self._parse_json(response)

@safe
@impure
def _make_request(self, user_id: int) -> requests.Response:
response = requests.get('/api/users/{0}'.format(user_id))
response.raise_for_status()
Expand Down Expand Up @@ -148,21 +147,23 @@ that might happen in this particular case:
- `Failure[JsonDecodeException]`

And we can work with each of them precisely.
It is a good practice to create `enum` classes or `Union` types
with all the possible errors.
It is a good practice to create `Enum` classes or `Union` types
with a list of all the possible errors.


## IO marker

But is that all we can improve?
Let's look at `FetchUserProfile` from another angle.
All its methods looks like regular ones:
All its methods look like regular ones:
it is impossible to tell whether they are pure or impure from the first sight.

It leads to a very important consequence:
*we start to mix pure and impure code together*.
We should not do that!

And suffer really bad when testing / reusing it.
When these two concepts are mixed
we suffer really bad when testing or reusing it.
Almost everything should be pure by default.
And we should explicitly mark impure parts of the program.

Expand Down Expand Up @@ -194,8 +195,8 @@ class FetchUserProfile(object):

@safe
def _parse_json(
self,
io_response: IO[requests.Response],
self,
io_response: IO[requests.Response],
) -> IO['UserProfile']:
return io_response.map(lambda response: response.json())
```
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "returns"
version = "0.6.0"
version = "0.7.0"
description = "Make your functions return something meaningful, typed, and safe!"
license = "MIT"

Expand Down
13 changes: 11 additions & 2 deletions returns/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@


class IO(GenericContainerOneSlot[_ValueType]):
"""Explicit marker for impure function results."""
"""
Explicit marker for impure function results.
We call it "marker" since once it is marked, it cannot be unmarked.
``IO`` is also a container.
But, it is different in a way
that it cannot be unwrapped / rescued / fixed.
There's no way to directly get its internal value.
"""

def map(self, function): # noqa: A003
"""
Expand All @@ -35,7 +44,7 @@ def bind(self, function):

def impure(function):
"""
Decorator to mark function that it returns IO container.
Decorator to mark function that it returns :py:class:`IO` container.
Supports both async and regular functions.
"""
Expand Down
2 changes: 1 addition & 1 deletion returns/unsafe.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

def unsafe_perform_io(wrapped_in_io):
"""
Compatibility utility and escape mechanism from IO world.
Compatibility utility and escape mechanism from ``IO`` world.
Just unwraps the internal value
from :py:class:`IO <returns.io.IO>` container.
Expand Down

0 comments on commit 3014ecc

Please sign in to comment.