From e013e05393a9caefd382837061788be4315a8fae Mon Sep 17 00:00:00 2001 From: Eldar Mamedov Date: Tue, 3 Dec 2024 00:20:56 +0400 Subject: [PATCH 1/2] 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/2] 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]]"