1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
"""
Represents the base interfaces for types that do fearless async operations.
This type means that ``Future`` cannot fail.
Don't use this type for async that can. Instead, use
:class:`returns.interfaces.specific.future_result.FutureResultBasedN` type.
"""
from __future__ import annotations
from abc import abstractmethod
from collections.abc import Awaitable, Callable, Generator
from typing import TYPE_CHECKING, Any, Generic, TypeVar
from typing_extensions import Never
from returns.interfaces.specific import io
from returns.primitives.hkt import KindN
if TYPE_CHECKING:
from returns.future import Future # noqa: WPS433
_FirstType = TypeVar('_FirstType')
_SecondType = TypeVar('_SecondType')
_ThirdType = TypeVar('_ThirdType')
_UpdatedType = TypeVar('_UpdatedType')
_FutureLikeType = TypeVar('_FutureLikeType', bound='FutureLikeN')
_AsyncFutureType = TypeVar('_AsyncFutureType', bound='AwaitableFutureN')
class FutureLikeN(io.IOLikeN[_FirstType, _SecondType, _ThirdType]):
"""
Base type for ones that does look like ``Future``.
But at the time this is not a real ``Future`` and cannot be awaited.
"""
__slots__ = ()
@abstractmethod
def bind_future(
self: _FutureLikeType,
function: Callable[[_FirstType], Future[_UpdatedType]],
) -> KindN[_FutureLikeType, _UpdatedType, _SecondType, _ThirdType]:
"""Allows to bind ``Future`` returning function over a container."""
@abstractmethod
def bind_async_future(
self: _FutureLikeType,
function: Callable[[_FirstType], Awaitable[Future[_UpdatedType]]],
) -> KindN[_FutureLikeType, _UpdatedType, _SecondType, _ThirdType]:
"""Allows to bind async ``Future`` returning function over container."""
@abstractmethod
def bind_async(
self: _FutureLikeType,
function: Callable[
[_FirstType],
Awaitable[
KindN[_FutureLikeType, _UpdatedType, _SecondType, _ThirdType],
],
],
) -> KindN[_FutureLikeType, _UpdatedType, _SecondType, _ThirdType]:
"""Binds async function returning the same type of container."""
@abstractmethod
def bind_awaitable(
self: _FutureLikeType,
function: Callable[[_FirstType], Awaitable[_UpdatedType]],
) -> KindN[_FutureLikeType, _UpdatedType, _SecondType, _ThirdType]:
"""Allows to bind async function over container."""
@classmethod
@abstractmethod
def from_future(
cls: type[_FutureLikeType],
inner_value: Future[_UpdatedType],
) -> KindN[_FutureLikeType, _UpdatedType, _SecondType, _ThirdType]:
"""Unit method to create new containers from successful ``Future``."""
#: Type alias for kinds with one type argument.
FutureLike1 = FutureLikeN[_FirstType, Never, Never]
#: Type alias for kinds with two type arguments.
FutureLike2 = FutureLikeN[_FirstType, _SecondType, Never]
#: Type alias for kinds with three type arguments.
FutureLike3 = FutureLikeN[_FirstType, _SecondType, _ThirdType]
class AwaitableFutureN(Generic[_FirstType, _SecondType, _ThirdType]):
"""
Type that provides the required API for ``Future`` to be async.
Should not be used directly. Use ``FutureBasedN`` instead.
"""
__slots__ = ()
@abstractmethod
def __await__(
self: _AsyncFutureType,
) -> Generator[
Any,
Any,
io.IOLikeN[_FirstType, _SecondType, _ThirdType],
]:
"""Magic method to allow ``await`` expression."""
@abstractmethod
async def awaitable(
self: _AsyncFutureType,
) -> io.IOLikeN[_FirstType, _SecondType, _ThirdType]:
"""Underling logic under ``await`` expression."""
#: Type alias for kinds with one type argument.
AsyncFuture1 = AwaitableFutureN[_FirstType, Never, Never]
#: Type alias for kinds with two type arguments.
AsyncFuture2 = AwaitableFutureN[_FirstType, _SecondType, Never]
#: Type alias for kinds with three type arguments.
AsyncFuture3 = AwaitableFutureN[_FirstType, _SecondType, _ThirdType]
class FutureBasedN(
FutureLikeN[_FirstType, _SecondType, _ThirdType],
AwaitableFutureN[_FirstType, _SecondType, _ThirdType],
):
"""
Base type for real ``Future`` objects.
They can be awaited.
"""
__slots__ = ()
#: Type alias for kinds with one type argument.
FutureBased1 = FutureBasedN[_FirstType, Never, Never]
#: Type alias for kinds with two type arguments.
FutureBased2 = FutureBasedN[_FirstType, _SecondType, Never]
#: Type alias for kinds with three type arguments.
FutureBased3 = FutureBasedN[_FirstType, _SecondType, _ThirdType]
|