Source code for returns.interfaces.specific.future

"""
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 typing import (
    TYPE_CHECKING,
    Any,
    Awaitable,
    Callable,
    Generator,
    Generic,
    NoReturn,
    Type,
    TypeVar,
)

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')
_FutureBasedType = TypeVar('_FutureBasedType', bound='FutureBasedN')


[docs]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. """
[docs] @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."""
[docs] @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."""
[docs] @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."""
[docs] @abstractmethod def bind_awaitable( self: _FutureLikeType, function: Callable[[_FirstType], Awaitable[_UpdatedType]], ) -> KindN[_FutureLikeType, _UpdatedType, _SecondType, _ThirdType]: """Allows to bind async function over container."""
[docs] @classmethod @abstractmethod def from_future( cls: Type[_FutureLikeType], # noqa: N805 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, NoReturn, NoReturn] #: Type alias for kinds with two type arguments. FutureLike2 = FutureLikeN[_FirstType, _SecondType, NoReturn] #: Type alias for kinds with three type arguments. FutureLike3 = FutureLikeN[_FirstType, _SecondType, _ThirdType]
[docs]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. """ @abstractmethod def __await__(self: _AsyncFutureType) -> Generator[ Any, Any, io.IOLikeN[_FirstType, _SecondType, _ThirdType], ]: """Magic method to allow ``await`` expression."""
[docs] @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, NoReturn, NoReturn] #: Type alias for kinds with two type arguments. AsyncFuture2 = AwaitableFutureN[_FirstType, _SecondType, NoReturn] #: Type alias for kinds with three type arguments. AsyncFuture3 = AwaitableFutureN[_FirstType, _SecondType, _ThirdType]
[docs]class FutureBasedN( FutureLikeN[_FirstType, _SecondType, _ThirdType], AwaitableFutureN[_FirstType, _SecondType, _ThirdType], ): """ Base type for real ``Future`` objects. They can be awaited. """
#: Type alias for kinds with one type argument. FutureBased1 = FutureBasedN[_FirstType, NoReturn, NoReturn] #: Type alias for kinds with two type arguments. FutureBased2 = FutureBasedN[_FirstType, _SecondType, NoReturn] #: Type alias for kinds with three type arguments. FutureBased3 = FutureBasedN[_FirstType, _SecondType, _ThirdType]