Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ incremental in minor, bugfixes only are patches.
See [0Ver](https://0ver.org/).


## 1.0.0 WIP

### Misc

- *Breaking*: Remove `success_type` and `failure_type` fields from `IOResult`, `Maybe` and `Result` types

## 0.22.0

### Features
Expand Down
18 changes: 9 additions & 9 deletions returns/_internal/futures/_future_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async def async_bind(
) -> Result[_NewValueType, _ErrorType]:
"""Async binds a container over a value."""
container = await inner_value
if isinstance(container, Result.success_type):
if isinstance(container, Success):
return (await dekind(function(container.unwrap())))._inner_value
return container # type: ignore[return-value]

Expand All @@ -58,7 +58,7 @@ async def async_bind_awaitable(
) -> Result[_NewValueType, _ErrorType]:
"""Async binds a coroutine over a value."""
container = await inner_value
if isinstance(container, Result.success_type):
if isinstance(container, Success):
return Result.from_value(await function(container.unwrap()))
return container # type: ignore[return-value]

Expand All @@ -72,7 +72,7 @@ async def async_bind_async(
) -> Result[_NewValueType, _ErrorType]:
"""Async binds a coroutine with container over a value."""
container = await inner_value
if isinstance(container, Result.success_type):
if isinstance(container, Success):
return await dekind(await function(container.unwrap()))._inner_value
return container # type: ignore[return-value]

Expand All @@ -91,7 +91,7 @@ async def async_bind_ioresult(
) -> Result[_NewValueType, _ErrorType]:
"""Async binds a container returning ``IOResult`` over a value."""
container = await inner_value
if isinstance(container, Result.success_type):
if isinstance(container, Success):
return function(container.unwrap())._inner_value
return container # type: ignore[return-value]

Expand All @@ -102,7 +102,7 @@ async def async_bind_io(
) -> Result[_NewValueType, _ErrorType]:
"""Async binds a container returning ``IO`` over a value."""
container = await inner_value
if isinstance(container, Result.success_type):
if isinstance(container, Success):
return Success(function(container.unwrap())._inner_value)
return container # type: ignore[return-value]

Expand All @@ -113,7 +113,7 @@ async def async_bind_future(
) -> Result[_NewValueType, _ErrorType]:
"""Async binds a container returning ``IO`` over a value."""
container = await inner_value
if isinstance(container, Result.success_type):
if isinstance(container, Success):
return await async_from_success(function(container.unwrap()))
return container # type: ignore[return-value]

Expand All @@ -124,7 +124,7 @@ async def async_bind_async_future(
) -> Result[_NewValueType, _ErrorType]:
"""Async binds a container returning ``IO`` over a value."""
container = await inner_value
if isinstance(container, Result.success_type):
if isinstance(container, Success):
return await async_from_success(await function(container.unwrap()))
return container # type: ignore[return-value]

Expand All @@ -135,7 +135,7 @@ async def async_alt(
) -> Result[_ValueType, _NewErrorType]:
"""Async alts a function over a value."""
container = await inner_value
if isinstance(container, Result.success_type):
if isinstance(container, Success):
return container
return Failure(function(container.failure()))

Expand All @@ -149,7 +149,7 @@ async def async_lash(
) -> Result[_ValueType, _NewErrorType]:
"""Async lashes a function returning a container over a value."""
container = await inner_value
if isinstance(container, Result.success_type):
if isinstance(container, Success):
return container
return (await dekind(function(container.failure())))._inner_value

Expand Down
4 changes: 2 additions & 2 deletions returns/_internal/futures/_reader_future_result.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import TYPE_CHECKING, Awaitable, Callable, TypeVar

from returns.primitives.hkt import Kind3, dekind
from returns.result import Result
from returns.result import Result, Success

if TYPE_CHECKING:
from returns.context import RequiresContextFutureResult # noqa: F401
Expand Down Expand Up @@ -29,7 +29,7 @@ async def async_bind_async(
) -> Result[_NewValueType, _ErrorType]:
"""Async binds a coroutine with container over a value."""
inner_value = await container(deps)._inner_value
if isinstance(inner_value, Result.success_type):
if isinstance(inner_value, Success):
return await dekind(
await function(inner_value.unwrap()),
)(deps)._inner_value
Expand Down
2 changes: 1 addition & 1 deletion returns/context/requires_context_ioresult.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ def bind_result(
.. code:: python

>>> from returns.context import RequiresContextIOResult
>>> from returns.result import Success, Failure, Result
>>> from returns.result import Failure, Result, Success
>>> from returns.io import IOSuccess, IOFailure

>>> def function(num: int) -> Result[int, str]:
Expand Down
4 changes: 2 additions & 2 deletions returns/context/requires_context_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def apply(
.. code:: python

>>> from returns.context import RequiresContextResult
>>> from returns.result import Success, Failure, Result
>>> from returns.result import Failure, Success

>>> def transform(arg: str) -> str:
... return arg + 'b'
Expand All @@ -217,7 +217,7 @@ def apply(

>>> assert isinstance(RequiresContextResult.from_value('a').apply(
... RequiresContextResult.from_failure(transform),
... )(...), Result.failure_type) is True
... )(...), Failure) is True

"""
return RequiresContextResult(
Expand Down
2 changes: 1 addition & 1 deletion returns/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def not_(function: Callable[_FuncParams, bool]) -> Callable[_FuncParams, bool]:
>>> from returns.result import Result, Success, Failure

>>> def is_successful(result_container: Result[float, int]) -> bool:
... return isinstance(result_container, Result.success_type)
... return isinstance(result_container, Success)

>>> assert not_(is_successful)(Success(1.0)) is False
>>> assert not_(is_successful)(Failure(1)) is True
Expand Down
4 changes: 2 additions & 2 deletions returns/future.py
Original file line number Diff line number Diff line change
Expand Up @@ -1478,7 +1478,7 @@ def future_safe(

>>> import anyio
>>> from returns.future import future_safe
>>> from returns.io import IOSuccess, IOResult
>>> from returns.io import IOFailure, IOSuccess

>>> @future_safe
... async def might_raise(arg: int) -> float:
Expand All @@ -1488,7 +1488,7 @@ def future_safe(
>>> assert anyio.run(might_raise(2).awaitable) == IOSuccess(0.5)
>>> assert isinstance(
... anyio.run(might_raise(0).awaitable),
... IOResult.failure_type,
... IOFailure,
... )

Similar to :func:`returns.io.impure_safe` and :func:`returns.result.safe`
Expand Down
20 changes: 4 additions & 16 deletions returns/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
TYPE_CHECKING,
Any,
Callable,
ClassVar,
Generator,
Iterator,
List,
Optional,
Type,
TypeVar,
Union,
final,
Expand Down Expand Up @@ -342,12 +340,6 @@ class IOResult( # type: ignore[type-var]
_inner_value: Result[_ValueType, _ErrorType]
__match_args__ = ('_inner_value',)

# These two are required for projects like `classes`:
#: Success type that is used to represent the successful computation.
success_type: ClassVar[Type['IOSuccess']]
#: Failure type that is used to represent the failed computation.
failure_type: ClassVar[Type['IOFailure']]

#: Typesafe equality comparison with other `IOResult` objects.
equals = container_equality

Expand Down Expand Up @@ -441,9 +433,9 @@ def apply(
>>> assert IOFailure('a').apply(IOFailure('b')) == IOFailure('a')

"""
if isinstance(self, self.failure_type):
if isinstance(self, IOFailure):
return self
if isinstance(container, self.success_type):
if isinstance(container, IOSuccess):
return self.from_result(
self._inner_value.map(
container.unwrap()._inner_value, # noqa: WPS437
Expand Down Expand Up @@ -757,7 +749,7 @@ def from_result(
>>> assert IOResult.from_result(Failure(2)) == IOFailure(2)

"""
if isinstance(inner_value, inner_value.success_type):
if isinstance(inner_value, Success):
return IOSuccess(inner_value._inner_value) # noqa: WPS437
return IOFailure(inner_value._inner_value) # type: ignore[arg-type] # noqa: WPS437, E501

Expand Down Expand Up @@ -884,13 +876,9 @@ def lash(self, function):
"""Does nothing for ``IOSuccess``."""
return self


IOResult.success_type = IOSuccess
IOResult.failure_type = IOFailure


# Aliases:


#: Alias for a popular case when ``IOResult`` has ``Exception`` as error type.
IOResultE = IOResult[_ValueType, Exception]

Expand Down
13 changes: 1 addition & 12 deletions returns/maybe.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
Iterator,
NoReturn,
Optional,
Type,
TypeVar,
Union,
final,
Expand Down Expand Up @@ -55,13 +54,6 @@ class Maybe( # type: ignore[type-var]
#: Alias for `Nothing`
empty: ClassVar['Maybe[Any]']

# These two are required for projects like `classes`:

#: Success type that is used to represent the successful computation.
success_type: ClassVar[Type['Some']]
#: Failure type that is used to represent the failed computation.
failure_type: ClassVar[Type['_Nothing']]

#: Typesafe equality comparison with other `Result` objects.
equals = container_equality

Expand Down Expand Up @@ -431,7 +423,7 @@ def map(self, function):

def apply(self, container):
"""Calls a wrapped function in a container on this container."""
if isinstance(container, self.success_type):
if isinstance(container, Some):
return self.map(container.unwrap()) # type: ignore
return container

Expand All @@ -452,9 +444,6 @@ def failure(self):
raise UnwrapFailedError(self)


Maybe.success_type = Some
Maybe.failure_type = _Nothing

#: Public unit value of protected :class:`~_Nothing` type.
Nothing: Maybe[NoReturn] = _Nothing()
Maybe.empty = Nothing
Expand Down
20 changes: 5 additions & 15 deletions returns/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
TYPE_CHECKING,
Any,
Callable,
ClassVar,
Generator,
Iterator,
List,
Expand Down Expand Up @@ -60,12 +59,6 @@ class Result( # type: ignore[type-var]
_inner_value: Union[_ValueType, _ErrorType]
_trace: Optional[List[FrameInfo]]

# These two are required for projects like `classes`:
#: Success type that is used to represent the successful computation.
success_type: ClassVar[Type['Success']]
#: Failure type that is used to represent the failed computation.
failure_type: ClassVar[Type['Failure']]

#: Typesafe equality comparison with other `Result` objects.
equals = container_equality

Expand Down Expand Up @@ -453,7 +446,7 @@ def lash(self, function):

def apply(self, container):
"""Calls a wrapped function in a container on this container."""
if isinstance(container, self.success_type):
if isinstance(container, Success):
return self.map(container.unwrap())
return container

Expand All @@ -474,9 +467,6 @@ def failure(self) -> NoReturn:
raise UnwrapFailedError(self)


Result.success_type = Success
Result.failure_type = Failure

# Aliases:

#: Alias for a popular case when ``Result`` has ``Exception`` as error type.
Expand Down Expand Up @@ -524,27 +514,27 @@ def safe( # type: ignore # noqa: WPS234, C901

.. code:: python

>>> from returns.result import Result, Success, safe
>>> from returns.result import Failure, Success, safe

>>> @safe
... def might_raise(arg: int) -> float:
... return 1 / arg

>>> assert might_raise(1) == Success(1.0)
>>> assert isinstance(might_raise(0), Result.failure_type)
>>> assert isinstance(might_raise(0), Failure)

You can also use it with explicit exception types as the first argument:

.. code:: python

>>> from returns.result import Result, Success, safe
>>> from returns.result import Failure, Success, safe

>>> @safe(exceptions=(ZeroDivisionError,))
... def might_raise(arg: int) -> float:
... return 1 / arg

>>> assert might_raise(1) == Success(1.0)
>>> assert isinstance(might_raise(0), Result.failure_type)
>>> assert isinstance(might_raise(0), Failure)

In this case, only exceptions that are explicitly
listed are going to be caught.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest

from returns.future import FutureResult, future_safe
from returns.io import IOResult, IOSuccess
from returns.io import IOFailure, IOSuccess


@future_safe
Expand All @@ -24,4 +24,4 @@ async def test_future_safe_decorator_failure():
future_instance = _coro(0)

assert isinstance(future_instance, FutureResult)
assert isinstance(await future_instance, IOResult.failure_type)
assert isinstance(await future_instance, IOFailure)
7 changes: 0 additions & 7 deletions tests/test_io/test_ioresult_container/test_ioresult_base.py

This file was deleted.

7 changes: 0 additions & 7 deletions tests/test_maybe/test_maybe_base.py

This file was deleted.

7 changes: 0 additions & 7 deletions tests/test_result/test_result_base.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,3 @@
container: IO[str]

reveal_type(IOResult.from_failed_io(container)) # N: Revealed type is "returns.io.IOResult[Any, builtins.str]"


- case: ioresult_success_type
disable_cache: false
main: |
from returns.io import IOResult

reveal_type(IOResult.success_type) # N: Revealed type is "Type[returns.io.IOSuccess[Any]]"


- case: ioresult_failure_type
disable_cache: false
main: |
from returns.io import IOResult

reveal_type(IOResult.failure_type) # N: Revealed type is "Type[returns.io.IOFailure[Any]]"
Loading