Skip to content

Commit 125ded9

Browse files
committed
Moves all types to .pyi files
1 parent 12b4715 commit 125ded9

File tree

9 files changed

+81
-166
lines changed

9 files changed

+81
-166
lines changed

returns/do_notation.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,18 @@
11
# -*- coding: utf-8 -*-
22

33
from functools import wraps
4-
from typing import Callable
54

65
from returns.primitives.exceptions import UnwrapFailedError
7-
from returns.primitives.types import MonadType
86

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

12-
13-
def do_notation(
14-
function: Callable[..., MonadType],
15-
) -> Callable[..., MonadType]:
8+
def do_notation(function):
169
"""
1710
Decorator to enable 'do-notation' context.
1811
1912
Should be used for series of computations that rely on ``.unwrap`` method.
2013
"""
2114
@wraps(function)
22-
def decorator(*args, **kwargs) -> MonadType:
15+
def decorator(*args, **kwargs):
2316
try:
2417
return function(*args, **kwargs)
2518
except UnwrapFailedError as exc:

returns/do_notation.pyi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ from typing import Callable
55
from returns.primitives.types import MonadType
66

77

8+
# Typing decorators is not an easy task, see:
9+
# https://github.com/python/mypy/issues/3157
10+
811
def do_notation(
912
function: Callable[..., MonadType],
1013
) -> Callable[..., MonadType]:

returns/either.py

Lines changed: 20 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,32 @@
11
# -*- coding: utf-8 -*-
22

3-
from abc import ABCMeta, abstractmethod
4-
from typing import Any, Callable, Generic, NoReturn, TypeVar, Union
5-
6-
from typing_extensions import final
3+
from abc import ABCMeta
74

85
from returns.primitives.exceptions import UnwrapFailedError
9-
from returns.primitives.monad import Monad, NewValueType, ValueType
10-
from returns.primitives.types import MonadType
11-
12-
_ErrorType = TypeVar('_ErrorType')
13-
14-
15-
# That's the most ugly part.
16-
# We need to express `Either` with two type parameters and
17-
# Left and Right with just one parameter.
18-
# And that's how we do it. Any other and more cleaner ways are appreciated.
19-
class Either(Generic[ValueType, _ErrorType], metaclass=ABCMeta):
20-
"""
21-
Represents a calculation that may either fail or succeed.
6+
from returns.primitives.monad import Monad
227

23-
An alternative to using exceptions.
24-
'Either' (or its alias 'Result') is an abstract type and should not
25-
be instantiated directly. Instead use 'Right' (or its alias 'Success')
26-
and 'Left' (or its alias 'Failure').
27-
"""
28-
29-
_inner_value: Union[ValueType, _ErrorType]
30-
31-
@abstractmethod
32-
def unwrap(self) -> ValueType: # pragma: no cover
33-
"""
34-
Custom magic method to unwrap inner value from monad.
358

36-
Should be redefined for ones that actually have values.
37-
And for ones that raise an exception for no values.
38-
"""
39-
raise NotImplementedError()
9+
class Either(Monad, metaclass=ABCMeta):
10+
"""Base class for Left and Right."""
4011

4112

42-
@final
43-
class Left(Either[Any, _ErrorType], Monad[_ErrorType]):
13+
class Left(Either):
4414
"""
4515
Represents a calculation which has failed.
4616
4717
It should contain an error code or message.
4818
To help with readability you may alternatively use the alias 'Failure'.
4919
"""
5020

51-
def __init__(self, inner_value: _ErrorType) -> None:
52-
"""
53-
Wraps the given value in the Container.
54-
55-
'value' is any arbitrary value of any type including functions.
56-
"""
57-
object.__setattr__(self, '_inner_value', inner_value)
58-
59-
def fmap(self, function) -> 'Left[_ErrorType]':
21+
def fmap(self, function):
6022
"""Returns the 'Left' instance that was used to call the method."""
6123
return self
6224

63-
def bind(self, function) -> 'Left[_ErrorType]':
25+
def bind(self, function):
6426
"""Returns the 'Left' instance that was used to call the method."""
6527
return self
6628

67-
def efmap(
68-
self,
69-
function: Callable[[_ErrorType], NewValueType],
70-
) -> 'Right[NewValueType]':
29+
def efmap(self, function):
7130
"""
7231
Applies function to the inner value.
7332
@@ -78,7 +37,7 @@ def efmap(
7837
"""
7938
return Right(function(self._inner_value))
8039

81-
def ebind(self, function: Callable[[_ErrorType], MonadType]) -> MonadType:
40+
def ebind(self, function):
8241
"""
8342
Applies 'function' to the result of a previous calculation.
8443
@@ -87,39 +46,27 @@ def ebind(self, function: Callable[[_ErrorType], MonadType]) -> MonadType:
8746
"""
8847
return function(self._inner_value)
8948

90-
def value_or(self, default_value: NewValueType) -> NewValueType:
49+
def value_or(self, default_value):
9150
"""Returns the value if we deal with 'Right' or default if 'Left'."""
9251
return default_value
9352

94-
def unwrap(self) -> NoReturn:
53+
def unwrap(self):
9554
"""Raises an exception, since it does not have a value inside."""
9655
raise UnwrapFailedError(self)
9756

98-
def failure(self) -> _ErrorType:
57+
def failure(self):
9958
"""Unwraps inner error value from failed monad."""
10059
return self._inner_value
10160

10261

103-
@final
104-
class Right(Either[ValueType, Any], Monad[ValueType]):
62+
class Right(Either):
10563
"""
10664
Represents a calculation which has succeeded and contains the result.
10765
10866
To help with readability you may alternatively use the alias 'Success'.
10967
"""
11068

111-
def __init__(self, inner_value: ValueType) -> None:
112-
"""
113-
Wraps the given value in the Container.
114-
115-
'value' is any arbitrary value of any type including functions.
116-
"""
117-
object.__setattr__(self, '_inner_value', inner_value)
118-
119-
def fmap(
120-
self,
121-
function: Callable[[ValueType], NewValueType],
122-
) -> 'Right[NewValueType]':
69+
def fmap(self, function):
12370
"""
12471
Applies function to the inner value.
12572
@@ -130,10 +77,7 @@ def fmap(
13077
"""
13178
return Right(function(self._inner_value))
13279

133-
def bind(
134-
self,
135-
function: Callable[[ValueType], MonadType],
136-
) -> MonadType:
80+
def bind(self, function):
13781
"""
13882
Applies 'function' to the result of a previous calculation.
13983
@@ -142,23 +86,23 @@ def bind(
14286
"""
14387
return function(self._inner_value)
14488

145-
def efmap(self, function) -> 'Right[ValueType]':
89+
def efmap(self, function):
14690
"""Returns the 'Right' instance that was used to call the method."""
14791
return self
14892

149-
def ebind(self, function) -> 'Right[ValueType]':
93+
def ebind(self, function):
15094
"""Returns the 'Right' instance that was used to call the method."""
15195
return self
15296

153-
def value_or(self, default_value: NewValueType) -> ValueType:
97+
def value_or(self, default_value):
15498
"""Returns the value if we deal with 'Right' or default if 'Left'."""
15599
return self._inner_value
156100

157-
def unwrap(self) -> ValueType:
101+
def unwrap(self):
158102
"""Returns the unwrapped value from the inside of this monad."""
159103
return self._inner_value
160104

161-
def failure(self) -> NoReturn:
105+
def failure(self):
162106
"""Raises an exception, since it does not have an error inside."""
163107
raise UnwrapFailedError(self)
164108

returns/either.pyi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ _MonadType = TypeVar('_MonadType', bound=Union['Monad', 'Either'])
1414
_ErrorType = TypeVar('_ErrorType')
1515

1616

17+
# That's the ugliest part.
18+
# We need to express `Either` with two type parameters and
19+
# Left and Right with just one parameter.
20+
# And that's how we do it. Any other and more cleaner ways are appreciated.
1721
class Either(Generic[ValueType, _ErrorType], metaclass=ABCMeta):
1822
_inner_value: Union[ValueType, _ErrorType]
1923

returns/functions.py

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

33
from functools import wraps
4-
from typing import Callable, TypeVar
54

65
from returns.either import Either, Failure, Success
76
from returns.primitives.exceptions import UnwrapFailedError
87
from returns.primitives.types import MonadType
98

10-
_ReturnType = TypeVar('_ReturnType')
119

12-
13-
def is_successful(monad: MonadType) -> bool:
10+
def is_successful(monad):
1411
"""Determins if a monad was a success or not."""
1512
try:
1613
monad.unwrap()
@@ -20,17 +17,15 @@ def is_successful(monad: MonadType) -> bool:
2017
return True
2118

2219

23-
def safe(
24-
function: Callable[..., _ReturnType],
25-
) -> Callable[..., Either[_ReturnType, Exception]]:
20+
def safe(function):
2621
"""
2722
Decorator to covert exception throwing function to 'Either' monad.
2823
2924
Show be used with care, since it only catches 'Exception' subclasses.
3025
It does not catch 'BaseException' subclasses.
3126
"""
3227
@wraps(function)
33-
def decorator(*args, **kwargs) -> Either[_ReturnType, Exception]:
28+
def decorator(*args, **kwargs):
3429
try:
3530
return Success(function(*args, **kwargs))
3631
except Exception as exc:

0 commit comments

Comments
 (0)