From e013e05393a9caefd382837061788be4315a8fae Mon Sep 17 00:00:00 2001 From: Eldar Mamedov Date: Tue, 3 Dec 2024 00:20:56 +0400 Subject: [PATCH 1/5] Bind composite error types --- returns/result.py | 4 ++-- typesafety/test_result/test_construct_success.yml | 15 +++++++++++++++ typesafety/test_result/test_result_type_cast.yml | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/returns/result.py b/returns/result.py index 293ede7e4..05060695a 100644 --- a/returns/result.py +++ b/returns/result.py @@ -119,9 +119,9 @@ def bind( self, function: Callable[ [_ValueType], - Kind2['Result', _NewValueType, _ErrorType], + Kind2['Result', _NewValueType, _ErrorType | _NewErrorType], ], - ) -> 'Result[_NewValueType, _ErrorType]': + ) -> 'Result[_NewValueType, _ErrorType | _NewErrorType]': """ Composes successful container with a function that returns a container. diff --git a/typesafety/test_result/test_construct_success.yml b/typesafety/test_result/test_construct_success.yml index fddfde3dd..f9a27fd97 100644 --- a/typesafety/test_result/test_construct_success.yml +++ b/typesafety/test_result/test_construct_success.yml @@ -65,3 +65,18 @@ from returns.result import Success reveal_type(Success(1).unwrap()) # N: Revealed type is "builtins.int" + + +- case: success_bind_composite_error + disable_cache: false + main: | + from returns.result import Success, Result + + def returns_value_error(param: int) -> Result[str, ValueError]: + ... + + def returns_key_error(param: str) -> Result[str, KeyError]: + ... + + first: Result[int, Exception] = Success(1) + reveal_type(first.bind(returns_value_error).bind(returns_key_error)) # N: Revealed type is "returns.result.Result[builtins.str, Union[builtins.Exception, builtins.ValueError, builtins.KeyError]]" diff --git a/typesafety/test_result/test_result_type_cast.yml b/typesafety/test_result/test_result_type_cast.yml index f2fce9df7..92d78e502 100644 --- a/typesafety/test_result/test_result_type_cast.yml +++ b/typesafety/test_result/test_result_type_cast.yml @@ -109,7 +109,7 @@ first: Result[int, Exception] second = first.bind(test) - reveal_type(second) # N: Revealed type is "returns.result.Result[builtins.int, builtins.Exception]" + reveal_type(second) # N: Revealed type is "returns.result.Result[builtins.int, Union[builtins.Exception, builtins.ValueError]]" - case: result_correct_usage From c9fdf6ac267487a46f36aa60d504fdf452fe998a Mon Sep 17 00:00:00 2001 From: Eldar Mamedov Date: Tue, 3 Dec 2024 00:33:05 +0400 Subject: [PATCH 2/5] Bind composite error types, failure bind --- typesafety/test_result/test_construct_failure.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/typesafety/test_result/test_construct_failure.yml b/typesafety/test_result/test_construct_failure.yml index f51e3837a..a9ce7a9cc 100644 --- a/typesafety/test_result/test_construct_failure.yml +++ b/typesafety/test_result/test_construct_failure.yml @@ -24,3 +24,18 @@ from returns.result import Failure reveal_type(Failure(1).failure()) # N: Revealed type is "builtins.int" + + +- case: failure_bind_composite_error + disable_cache: false + main: | + from returns.result import Success, Failure, Result + + def first_function(value: int) -> Result[str, ValueError]: + ... + + def second_function(value: str) -> Result[bool, KeyError]: + ... + + result = Failure(0).bind(first_function).bind(second_function) + reveal_type(result) # N: Revealed type is "returns.result.Result[builtins.bool, Union[builtins.int, builtins.ValueError, builtins.KeyError]]" From e1ee71fe14dbd46e764d57b7dc1c944976cc6383 Mon Sep 17 00:00:00 2001 From: Eldar Mamedov Date: Fri, 6 Dec 2024 19:54:01 +0400 Subject: [PATCH 3/5] Bind composite error types for ResultLike objects: FutureResult, IOResult, RequiresContextIOResult, RequiresContextResult --- returns/context/requires_context_ioresult.py | 8 +-- returns/context/requires_context_result.py | 62 ++++++++++++------- returns/future.py | 8 +-- returns/io.py | 4 +- .../test_requires_context_ioresult.yml | 16 +++++ .../test_requires_context_result.yml | 16 +++++ .../test_future_result_base.yml | 56 +++++++++++++++++ .../test_construct_iofailure.yml | 14 +++++ .../test_construct_iosucess.yml | 15 +++++ .../test_ioresult_typecast.yml | 2 +- .../test_result/test_construct_failure.yml | 6 +- 11 files changed, 170 insertions(+), 37 deletions(-) diff --git a/returns/context/requires_context_ioresult.py b/returns/context/requires_context_ioresult.py index b976c17e0..97d671150 100644 --- a/returns/context/requires_context_ioresult.py +++ b/returns/context/requires_context_ioresult.py @@ -249,11 +249,11 @@ def bind( Kind3[ RequiresContextIOResult, _NewValueType, - _ErrorType, + _ErrorType | _NewErrorType, _EnvType, ], ], - ) -> RequiresContextIOResult[_NewValueType, _ErrorType, _EnvType]: + ) -> RequiresContextIOResult[_NewValueType, _ErrorType | _NewErrorType, _EnvType]: """ Composes this container with a function returning the same type. @@ -293,8 +293,8 @@ def bind( def bind_result( self, - function: Callable[[_ValueType], Result[_NewValueType, _ErrorType]], - ) -> RequiresContextIOResult[_NewValueType, _ErrorType, _EnvType]: + function: Callable[[_ValueType], Result[_NewValueType, _ErrorType | _NewErrorType]], + ) -> RequiresContextIOResult[_NewValueType, _ErrorType | _NewErrorType, _EnvType]: """ Binds ``Result`` returning function to the current container. diff --git a/returns/context/requires_context_result.py b/returns/context/requires_context_result.py index 285a5d37a..874161b5c 100644 --- a/returns/context/requires_context_result.py +++ b/returns/context/requires_context_result.py @@ -13,23 +13,23 @@ from returns.context.requires_context import RequiresContext # Context: -_EnvType = TypeVar('_EnvType', contravariant=True) -_NewEnvType = TypeVar('_NewEnvType') +_EnvType = TypeVar("_EnvType", contravariant=True) +_NewEnvType = TypeVar("_NewEnvType") # Result: -_ValueType = TypeVar('_ValueType', covariant=True) -_NewValueType = TypeVar('_NewValueType') -_ErrorType = TypeVar('_ErrorType', covariant=True) -_NewErrorType = TypeVar('_NewErrorType') +_ValueType = TypeVar("_ValueType", covariant=True) +_NewValueType = TypeVar("_NewValueType") +_ErrorType = TypeVar("_ErrorType", covariant=True) +_NewErrorType = TypeVar("_NewErrorType") # Helpers: -_FirstType = TypeVar('_FirstType') +_FirstType = TypeVar("_FirstType") @final class RequiresContextResult( # type: ignore[type-var] BaseContainer, - SupportsKind3['RequiresContextResult', _ValueType, _ErrorType, _EnvType], + SupportsKind3["RequiresContextResult", _ValueType, _ErrorType, _EnvType], reader_result.ReaderResultBasedN[_ValueType, _ErrorType, _EnvType], ): """ @@ -167,7 +167,8 @@ def swap(self) -> RequiresContextResult[_ErrorType, _ValueType, _EnvType]: return RequiresContextResult(lambda deps: self(deps).swap()) def map( - self, function: Callable[[_ValueType], _NewValueType], + self, + function: Callable[[_ValueType], _NewValueType], ) -> RequiresContextResult[_NewValueType, _ErrorType, _EnvType]: """ Composes successful container with a pure function. @@ -232,11 +233,11 @@ def bind( Kind3[ RequiresContextResult, _NewValueType, - _ErrorType, + _ErrorType | _NewErrorType, _EnvType, ], ], - ) -> RequiresContextResult[_NewValueType, _ErrorType, _EnvType]: + ) -> RequiresContextResult[_NewValueType, _ErrorType | _NewErrorType, _EnvType]: """ Composes this container with a function returning the same type. @@ -274,8 +275,10 @@ def bind( def bind_result( self, - function: Callable[[_ValueType], Result[_NewValueType, _ErrorType]], - ) -> RequiresContextResult[_NewValueType, _ErrorType, _EnvType]: + function: Callable[ + [_ValueType], Result[_NewValueType, _ErrorType | _NewErrorType] + ], + ) -> RequiresContextResult[_NewValueType, _ErrorType | _NewErrorType, _EnvType]: """ Binds ``Result`` returning function to current container. @@ -338,7 +341,8 @@ def bind_context( ) def alt( - self, function: Callable[[_ErrorType], _NewErrorType], + self, + function: Callable[[_ErrorType], _NewErrorType], ) -> RequiresContextResult[_ValueType, _NewErrorType, _EnvType]: """ Composes failed container with a pure function. @@ -455,7 +459,8 @@ def ask(cls) -> RequiresContextResult[_EnvType, _ErrorType, _EnvType]: @classmethod def from_result( - cls, inner_value: Result[_NewValueType, _NewErrorType], + cls, + inner_value: Result[_NewValueType, _NewErrorType], ) -> RequiresContextResult[_NewValueType, _NewErrorType, NoDeps]: """ Creates new container with ``Result`` as a unit value. @@ -481,7 +486,8 @@ def from_result( def from_typecast( cls, inner_value: RequiresContext[ - Result[_NewValueType, _NewErrorType], _EnvType, + Result[_NewValueType, _NewErrorType], + _EnvType, ], ) -> RequiresContextResult[_NewValueType, _NewErrorType, _EnvType]: """ @@ -510,7 +516,8 @@ def from_typecast( @classmethod def from_context( - cls, inner_value: RequiresContext[_NewValueType, _NewEnvType], + cls, + inner_value: RequiresContext[_NewValueType, _NewEnvType], ) -> RequiresContextResult[_NewValueType, Any, _NewEnvType]: """ Creates new container from ``RequiresContext`` as a success unit. @@ -528,7 +535,8 @@ def from_context( @classmethod def from_failed_context( - cls, inner_value: RequiresContext[_NewValueType, _NewEnvType], + cls, + inner_value: RequiresContext[_NewValueType, _NewEnvType], ) -> RequiresContextResult[Any, _NewValueType, _NewEnvType]: """ Creates new container from ``RequiresContext`` as a failure unit. @@ -548,7 +556,9 @@ def from_failed_context( def from_result_context( cls, inner_value: RequiresContextResult[ - _NewValueType, _NewErrorType, _NewEnvType, + _NewValueType, + _NewErrorType, + _NewEnvType, ], ) -> RequiresContextResult[_NewValueType, _NewErrorType, _NewEnvType]: """ @@ -572,7 +582,8 @@ def from_result_context( @classmethod def from_value( - cls, inner_value: _FirstType, + cls, + inner_value: _FirstType, ) -> RequiresContextResult[_FirstType, Any, NoDeps]: """ Creates new container with ``Success(inner_value)`` as a unit value. @@ -588,7 +599,8 @@ def from_value( @classmethod def from_failure( - cls, inner_value: _FirstType, + cls, + inner_value: _FirstType, ) -> RequiresContextResult[Any, _FirstType, NoDeps]: """ Creates new container with ``Failure(inner_value)`` as a unit value. @@ -607,7 +619,9 @@ def from_failure( #: Alias for a popular case when ``Result`` has ``Exception`` as error type. RequiresContextResultE: TypeAlias = RequiresContextResult[ - _ValueType, Exception, _EnvType, + _ValueType, + Exception, + _EnvType, ] #: Alias to save you some typing. Uses original name from Haskell. @@ -615,5 +629,7 @@ def from_failure( #: Alias to save you some typing. Has ``Exception`` as error type. ReaderResultE: TypeAlias = RequiresContextResult[ - _ValueType, Exception, _EnvType, + _ValueType, + Exception, + _EnvType, ] diff --git a/returns/future.py b/returns/future.py index 9195fef6d..0493d3b4e 100644 --- a/returns/future.py +++ b/returns/future.py @@ -757,9 +757,9 @@ def bind( self, function: Callable[ [_ValueType], - Kind2['FutureResult', _NewValueType, _ErrorType], + Kind2['FutureResult', _NewValueType, _ErrorType | _NewErrorType], ], - ) -> 'FutureResult[_NewValueType, _ErrorType]': + ) -> 'FutureResult[_NewValueType, _ErrorType | _NewErrorType]': """ Applies 'function' to the result of a previous calculation. @@ -795,9 +795,9 @@ def bind_async( self, function: Callable[ [_ValueType], - Awaitable[Kind2['FutureResult', _NewValueType, _ErrorType]], + Awaitable[Kind2['FutureResult', _NewValueType, _ErrorType | _NewErrorType]], ], - ) -> 'FutureResult[_NewValueType, _ErrorType]': + ) -> 'FutureResult[_NewValueType, _ErrorType | _NewErrorType]': """ Composes a container and ``async`` function returning container. diff --git a/returns/io.py b/returns/io.py index 3cb4cb59d..3864e7d11 100644 --- a/returns/io.py +++ b/returns/io.py @@ -437,9 +437,9 @@ def bind( self, function: Callable[ [_ValueType], - Kind2['IOResult', _NewValueType, _ErrorType], + Kind2['IOResult', _NewValueType, _ErrorType | _NewErrorType], ], - ) -> 'IOResult[_NewValueType, _ErrorType]': + ) -> 'IOResult[_NewValueType, _ErrorType | _NewErrorType]': """ Composes successful container with a function that returns a container. diff --git a/typesafety/test_context/test_requires_context_ioresult/test_requires_context_ioresult.yml b/typesafety/test_context/test_requires_context_ioresult/test_requires_context_ioresult.yml index b85df53fd..c69ed2cbd 100644 --- a/typesafety/test_context/test_requires_context_ioresult/test_requires_context_ioresult.yml +++ b/typesafety/test_context/test_requires_context_ioresult/test_requires_context_ioresult.yml @@ -164,3 +164,19 @@ first: RequiresContextIOResult[float, bool, int] reveal_type(first.modify_env(int)('1')) # N: Revealed type is "returns.io.IOResult[builtins.float, builtins.bool]" + + +- case: requires_context_ioresult_bind_composite_error + disable_cache: false + main: | + from returns.context import RequiresContextIOResult + + x: RequiresContextIOResult[int, float, str] + + def first_function(param: int) -> RequiresContextIOResult[bool, ValueError, str]: + ... + + def second_function(param: bool) -> RequiresContextIOResult[bool, KeyError, str]: + ... + + reveal_type(x.bind(first_function).bind(second_function)) # N: Revealed type is "returns.context.requires_context_ioresult.RequiresContextIOResult[builtins.bool, Union[builtins.float, builtins.ValueError, builtins.KeyError], builtins.str]" diff --git a/typesafety/test_context/test_requires_context_result/test_requires_context_result.yml b/typesafety/test_context/test_requires_context_result/test_requires_context_result.yml index 5b7a7ba25..b069a75aa 100644 --- a/typesafety/test_context/test_requires_context_result/test_requires_context_result.yml +++ b/typesafety/test_context/test_requires_context_result/test_requires_context_result.yml @@ -122,3 +122,19 @@ first: RequiresContextResult[float, bool, int] reveal_type(first.modify_env(int)('1')) # N: Revealed type is "returns.result.Result[builtins.float, builtins.bool]" + + +- case: requires_context_result_bind_composite_error + disable_cache: false + main: | + from returns.context import RequiresContextResult + + x: RequiresContextResult[int, float, str] + + def first_function(param: int) -> RequiresContextResult[bool, ValueError, str]: + ... + + def second_function(param: bool) -> RequiresContextResult[bool, KeyError, str]: + ... + + reveal_type(x.bind(first_function).bind(second_function)) # N: Revealed type is "returns.context.requires_context_result.RequiresContextResult[builtins.bool, Union[builtins.float, builtins.ValueError, builtins.KeyError], builtins.str]" diff --git a/typesafety/test_future/test_future_result_container/test_future_result_base.yml b/typesafety/test_future/test_future_result_container/test_future_result_base.yml index 436d369de..7cd12215f 100644 --- a/typesafety/test_future/test_future_result_container/test_future_result_base.yml +++ b/typesafety/test_future/test_future_result_container/test_future_result_base.yml @@ -155,3 +155,59 @@ first: FutureResult[int, str] reveal_type(first.lash(bind)) # N: Revealed type is "returns.future.FutureResult[builtins.int, builtins.float]" + + +- case: future_success_result_async_composite_error + disable_cache: false + main: | + from returns.future import FutureResult, FutureSuccess + + def returns_value_error(value: int) -> FutureResult[str, ValueError]: + ... + def returns_key_error(value: str) -> FutureResult[bool, KeyError]: + ... + + result = FutureSuccess(0).bind(returns_value_error).bind(returns_key_error) + reveal_type(result) # N: Revealed type is "returns.future.FutureResult[builtins.bool, Union[Any, builtins.ValueError, builtins.KeyError]]" + + +- case: future_failure_result_async_composite_error + disable_cache: false + main: | + from returns.future import FutureResult, FutureFailure + + def returns_value_error(value: int) -> FutureResult[str, ValueError]: + ... + def returns_key_error(value: str) -> FutureResult[bool, KeyError]: + ... + + result = FutureFailure(0).bind(returns_value_error).bind(returns_key_error) + reveal_type(result) # N: Revealed type is "returns.future.FutureResult[builtins.bool, Union[builtins.int, builtins.ValueError, builtins.KeyError]]" + + +- case: future_success_result_bind_async_composite_error + disable_cache: false + main: | + from returns.future import FutureResult, FutureSuccess + + async def returns_value_error(value: int) -> FutureResult[str, ValueError]: + ... + async def returns_key_error(value: str) -> FutureResult[bool, KeyError]: + ... + + result = FutureSuccess(0).bind_async(returns_value_error).bind_async(returns_key_error) + reveal_type(result) # N: Revealed type is "returns.future.FutureResult[builtins.bool, Union[Any, builtins.ValueError, builtins.KeyError]]" + + +- case: future_failure_result_bind_async_composite_error + disable_cache: false + main: | + from returns.future import FutureResult, FutureFailure + + async def returns_value_error(value: int) -> FutureResult[str, ValueError]: + ... + async def returns_key_error(value: str) -> FutureResult[bool, KeyError]: + ... + + result = FutureFailure(0).bind_async(returns_value_error).bind_async(returns_key_error) + reveal_type(result) # N: Revealed type is "returns.future.FutureResult[builtins.bool, Union[builtins.int, builtins.ValueError, builtins.KeyError]]" \ No newline at end of file diff --git a/typesafety/test_io/test_ioresult_container/test_construct_iofailure.yml b/typesafety/test_io/test_ioresult_container/test_construct_iofailure.yml index be0ddb86d..b34567aa2 100644 --- a/typesafety/test_io/test_ioresult_container/test_construct_iofailure.yml +++ b/typesafety/test_io/test_ioresult_container/test_construct_iofailure.yml @@ -24,3 +24,17 @@ from returns.io import IOFailure reveal_type(IOFailure(1).failure()) # N: Revealed type is "returns.io.IO[builtins.int]" + + +- case: iofailure_bind_composite_error + disable_cache: false + main: | + from returns.io import IOFailure, IOResult + + def returns_value_error(value: int) -> IOResult[str, ValueError]: + ... + def returns_key_error(value: str) -> IOResult[bool, KeyError]: + ... + + result = IOFailure(0).bind(returns_value_error).bind(returns_key_error) + reveal_type(result) # N: Revealed type is "returns.io.IOResult[builtins.bool, Union[builtins.int, builtins.ValueError, builtins.KeyError]]" \ No newline at end of file diff --git a/typesafety/test_io/test_ioresult_container/test_construct_iosucess.yml b/typesafety/test_io/test_ioresult_container/test_construct_iosucess.yml index daacece42..eb7323d4c 100644 --- a/typesafety/test_io/test_ioresult_container/test_construct_iosucess.yml +++ b/typesafety/test_io/test_ioresult_container/test_construct_iosucess.yml @@ -68,3 +68,18 @@ from returns.io import IOSuccess reveal_type(IOSuccess(1).unwrap()) # N: Revealed type is "returns.io.IO[builtins.int]" + + +- case: iosuccess_bind_composite_error + disable_cache: false + main: | + from returns.io import IOSuccess, IOResult + + def returns_value_error(param: int) -> IOResult[str, ValueError]: + ... + def returns_key_error(param: str) -> IOResult[str, KeyError]: + ... + + first: IOResult[int, Exception] = IOSuccess(1) + result = first.bind(returns_value_error).bind(returns_key_error) + reveal_type(result) # N: Revealed type is "returns.io.IOResult[builtins.str, Union[builtins.Exception, builtins.ValueError, builtins.KeyError]]" \ No newline at end of file diff --git a/typesafety/test_io/test_ioresult_container/test_ioresult_typecast.yml b/typesafety/test_io/test_ioresult_container/test_ioresult_typecast.yml index 148747ca5..071d7bc17 100644 --- a/typesafety/test_io/test_ioresult_container/test_ioresult_typecast.yml +++ b/typesafety/test_io/test_ioresult_container/test_ioresult_typecast.yml @@ -91,7 +91,7 @@ first: IOResult[int, Exception] second = first.bind(test) - reveal_type(second) # N: Revealed type is "returns.io.IOResult[builtins.int, builtins.Exception]" + reveal_type(second) # N: Revealed type is "returns.io.IOResult[builtins.int, Union[builtins.Exception, builtins.ValueError]]" - case: ioresult_correct_usage diff --git a/typesafety/test_result/test_construct_failure.yml b/typesafety/test_result/test_construct_failure.yml index a9ce7a9cc..158d7a88b 100644 --- a/typesafety/test_result/test_construct_failure.yml +++ b/typesafety/test_result/test_construct_failure.yml @@ -29,13 +29,13 @@ - case: failure_bind_composite_error disable_cache: false main: | - from returns.result import Success, Failure, Result + from returns.result import Failure, Result - def first_function(value: int) -> Result[str, ValueError]: + def returns_value_error(value: int) -> Result[str, ValueError]: ... def second_function(value: str) -> Result[bool, KeyError]: ... - result = Failure(0).bind(first_function).bind(second_function) + result = Failure(0).bind(returns_value_error).bind(second_function) reveal_type(result) # N: Revealed type is "returns.result.Result[builtins.bool, Union[builtins.int, builtins.ValueError, builtins.KeyError]]" From aa24defd570a38cbcda934d2d0d5d35cd7d000c1 Mon Sep 17 00:00:00 2001 From: Eldar Mamedov Date: Sat, 7 Dec 2024 11:05:49 +0400 Subject: [PATCH 4/5] Fix formatting --- returns/context/requires_context_ioresult.py | 12 ++++++--- returns/context/requires_context_result.py | 26 +++++++++++--------- returns/future.py | 4 ++- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/returns/context/requires_context_ioresult.py b/returns/context/requires_context_ioresult.py index 97d671150..781e60a58 100644 --- a/returns/context/requires_context_ioresult.py +++ b/returns/context/requires_context_ioresult.py @@ -253,7 +253,9 @@ def bind( _EnvType, ], ], - ) -> RequiresContextIOResult[_NewValueType, _ErrorType | _NewErrorType, _EnvType]: + ) -> RequiresContextIOResult[ + _NewValueType, _ErrorType | _NewErrorType, _EnvType, + ]: """ Composes this container with a function returning the same type. @@ -293,8 +295,12 @@ def bind( def bind_result( self, - function: Callable[[_ValueType], Result[_NewValueType, _ErrorType | _NewErrorType]], - ) -> RequiresContextIOResult[_NewValueType, _ErrorType | _NewErrorType, _EnvType]: + function: Callable[ + [_ValueType], Result[_NewValueType, _ErrorType | _NewErrorType], + ], + ) -> RequiresContextIOResult[ + _NewValueType, _ErrorType | _NewErrorType, _EnvType, + ]: """ Binds ``Result`` returning function to the current container. diff --git a/returns/context/requires_context_result.py b/returns/context/requires_context_result.py index 874161b5c..aeb4956de 100644 --- a/returns/context/requires_context_result.py +++ b/returns/context/requires_context_result.py @@ -13,23 +13,23 @@ from returns.context.requires_context import RequiresContext # Context: -_EnvType = TypeVar("_EnvType", contravariant=True) -_NewEnvType = TypeVar("_NewEnvType") +_EnvType = TypeVar('_EnvType', contravariant=True) +_NewEnvType = TypeVar('_NewEnvType') # Result: -_ValueType = TypeVar("_ValueType", covariant=True) -_NewValueType = TypeVar("_NewValueType") -_ErrorType = TypeVar("_ErrorType", covariant=True) -_NewErrorType = TypeVar("_NewErrorType") +_ValueType = TypeVar('_ValueType', covariant=True) +_NewValueType = TypeVar('_NewValueType') +_ErrorType = TypeVar('_ErrorType', covariant=True) +_NewErrorType = TypeVar('_NewErrorType') # Helpers: -_FirstType = TypeVar("_FirstType") +_FirstType = TypeVar('_FirstType') @final class RequiresContextResult( # type: ignore[type-var] BaseContainer, - SupportsKind3["RequiresContextResult", _ValueType, _ErrorType, _EnvType], + SupportsKind3['RequiresContextResult', _ValueType, _ErrorType, _EnvType], reader_result.ReaderResultBasedN[_ValueType, _ErrorType, _EnvType], ): """ @@ -237,7 +237,9 @@ def bind( _EnvType, ], ], - ) -> RequiresContextResult[_NewValueType, _ErrorType | _NewErrorType, _EnvType]: + ) -> RequiresContextResult[ + _NewValueType, _ErrorType | _NewErrorType, _EnvType, + ]: """ Composes this container with a function returning the same type. @@ -276,9 +278,11 @@ def bind( def bind_result( self, function: Callable[ - [_ValueType], Result[_NewValueType, _ErrorType | _NewErrorType] + [_ValueType], Result[_NewValueType, _ErrorType | _NewErrorType], ], - ) -> RequiresContextResult[_NewValueType, _ErrorType | _NewErrorType, _EnvType]: + ) -> RequiresContextResult[ + _NewValueType, _ErrorType | _NewErrorType, _EnvType, + ]: """ Binds ``Result`` returning function to current container. diff --git a/returns/future.py b/returns/future.py index 0493d3b4e..6d35abedb 100644 --- a/returns/future.py +++ b/returns/future.py @@ -795,7 +795,9 @@ def bind_async( self, function: Callable[ [_ValueType], - Awaitable[Kind2['FutureResult', _NewValueType, _ErrorType | _NewErrorType]], + Awaitable[ + Kind2['FutureResult', _NewValueType, _ErrorType | _NewErrorType] + ], ], ) -> 'FutureResult[_NewValueType, _ErrorType | _NewErrorType]': """ From 46480799c9ffddf1100dd443fc5ea42b877d5ef7 Mon Sep 17 00:00:00 2001 From: Eldar Mamedov Date: Sun, 8 Dec 2024 15:23:06 +0400 Subject: [PATCH 5/5] Union error type on IOResult.bind_result --- returns/io.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/returns/io.py b/returns/io.py index 3864e7d11..409093091 100644 --- a/returns/io.py +++ b/returns/io.py @@ -464,9 +464,9 @@ def bind_result( self, function: Callable[ [_ValueType], - Result[_NewValueType, _ErrorType], + Result[_NewValueType, _ErrorType | _NewErrorType], ], - ) -> 'IOResult[_NewValueType, _ErrorType]': + ) -> 'IOResult[_NewValueType, _ErrorType | _NewErrorType]': """ Composes successful container with a function that returns a container.