From b3ac895b0e2d074d3bb6eeb245b0072d9b22643a Mon Sep 17 00:00:00 2001 From: acostapazo Date: Sat, 13 May 2023 15:37:12 +0200 Subject: [PATCH] chore(typing): solve some mypy strict errors in meiga module (#61) * chore(typing): solve some mypy strict errors in meiga module * chore(typing): solve mypy error on get_args_list --- meiga/alias.py | 7 ++- meiga/assertions/assert_failure.py | 10 ++-- meiga/assertions/assert_success.py | 10 ++-- meiga/decorators/early_return.py | 4 +- meiga/decorators/to_result.py | 4 +- meiga/deprecation.py | 6 +-- meiga/error.py | 11 +++-- meiga/handlers.py | 11 +++-- meiga/misc.py | 7 ++- meiga/result.py | 75 ++++++++++++++++-------------- 10 files changed, 81 insertions(+), 64 deletions(-) diff --git a/meiga/alias.py b/meiga/alias.py index 4e9442d..5410eb1 100644 --- a/meiga/alias.py +++ b/meiga/alias.py @@ -18,9 +18,8 @@ def __init__(self, error: TF = cast(TF, Error())) -> None: super().__init__(failure=error) -isSuccess: Result = Success() -isFailure: Result = Failure() -NotImplementedMethodError: Result = isFailure - BoolResult = Result[bool, Error] AnyResult = Result[Any, Error] +isSuccess: BoolResult = Success() +isFailure: BoolResult = Failure() +NotImplementedMethodError: BoolResult = isFailure diff --git a/meiga/assertions/assert_failure.py b/meiga/assertions/assert_failure.py index 4a1bd37..011de34 100644 --- a/meiga/assertions/assert_failure.py +++ b/meiga/assertions/assert_failure.py @@ -1,13 +1,13 @@ -from typing import TYPE_CHECKING, Any, Optional, Type +from typing import TYPE_CHECKING, Any, Type, Union if TYPE_CHECKING: # pragma: no cover - from meiga.result import Result + from meiga.result import TF, TS, Result def assert_failure( - result: "Result", - value_is_instance_of: Optional[Type] = None, - value_is_equal_to: Optional[Any] = None, + result: "Result[TS, TF]", + value_is_instance_of: Union[Type[Any], None] = None, + value_is_equal_to: Union[Any, None] = None, ) -> None: assert ( result.is_failure diff --git a/meiga/assertions/assert_success.py b/meiga/assertions/assert_success.py index 5ebb147..5662561 100644 --- a/meiga/assertions/assert_success.py +++ b/meiga/assertions/assert_success.py @@ -1,13 +1,13 @@ -from typing import TYPE_CHECKING, Any, Optional, Type +from typing import TYPE_CHECKING, Any, Type, Union if TYPE_CHECKING: # pragma: no cover - from meiga.result import Result + from meiga.result import TF, TS, Result def assert_success( - result: "Result", - value_is_instance_of: Optional[Type] = None, - value_is_equal_to: Optional[Any] = None, + result: "Result[TS, TF]", + value_is_instance_of: Union[Type[Any], None] = None, + value_is_equal_to: Union[Any, None] = None, ) -> None: assert ( result.is_success diff --git a/meiga/decorators/early_return.py b/meiga/decorators/early_return.py index f5e45ca..4ddf89f 100644 --- a/meiga/decorators/early_return.py +++ b/meiga/decorators/early_return.py @@ -1,6 +1,6 @@ import sys from functools import wraps -from typing import Callable, TypeVar, cast +from typing import Any, Callable, TypeVar, cast if sys.version_info < (3, 10): # pragma: no cover from typing_extensions import ParamSpec @@ -16,7 +16,7 @@ from meiga.result import Result P = ParamSpec("P") -R = TypeVar("R", bound=Result) +R = TypeVar("R", bound=Result[Any, Any]) def early_return(func: Callable[P, R]) -> Callable[P, R]: diff --git a/meiga/decorators/to_result.py b/meiga/decorators/to_result.py index f0f2c06..9e3ea54 100644 --- a/meiga/decorators/to_result.py +++ b/meiga/decorators/to_result.py @@ -1,6 +1,6 @@ import sys from functools import wraps -from typing import Callable, TypeVar, cast +from typing import Any, Callable, TypeVar, cast if sys.version_info < (3, 10): # pragma: no cover from typing_extensions import ParamSpec @@ -14,7 +14,7 @@ from meiga.result import Result P = ParamSpec("P") -R = TypeVar("R", bound=Result) +R = TypeVar("R", bound=Result[Any, Any]) def to_result(func: Callable[P, R]) -> Callable[P, R]: diff --git a/meiga/deprecation.py b/meiga/deprecation.py index 3435d96..87aa635 100644 --- a/meiga/deprecation.py +++ b/meiga/deprecation.py @@ -1,10 +1,10 @@ -from typing import Dict, Union +from typing import Any, Dict, Union from meiga.handlers import OnFailureHandler, OnSuccessHandler def get_on_success_handler_from_deprecated_args( - kwargs: Dict, + kwargs: Dict[Any, Any], ) -> Union[OnSuccessHandler, None]: on_success = kwargs.get("on_success") if on_success: @@ -13,7 +13,7 @@ def get_on_success_handler_from_deprecated_args( def get_on_failure_handler_from_deprecated_args( - kwargs: Dict, + kwargs: Dict[Any, Any], ) -> Union[OnFailureHandler, None]: on_failure = kwargs.get("on_failure") if on_failure: diff --git a/meiga/error.py b/meiga/error.py index 1768e95..56b72f3 100644 --- a/meiga/error.py +++ b/meiga/error.py @@ -1,8 +1,13 @@ +from typing import Any, Union + + class Error(Exception): - def __init__(self): + message: Union[str, None] + + def __init__(self) -> None: self.message = None - def __eq__(self, other) -> bool: + def __eq__(self, other: Any) -> bool: if isinstance(other, self.__class__): return True return False @@ -17,5 +22,5 @@ def __repr__(self) -> str: return f"{self.__class__.__name__}{suffix}" - def __hash__(self): + def __hash__(self) -> int: return hash((self.message,)) diff --git a/meiga/handlers.py b/meiga/handlers.py index 20a08d1..d67dc02 100644 --- a/meiga/handlers.py +++ b/meiga/handlers.py @@ -1,14 +1,19 @@ -from typing import Callable, Iterable, Optional +from typing import TYPE_CHECKING, Any, Callable, Iterable, Union from meiga.misc import get_args_list +if TYPE_CHECKING: # pragma: no cover + from meiga.result import TF, TS, Result + class Handler: - def __init__(self, func: Callable[..., None], args: Optional[Iterable] = None): + def __init__( + self, func: Callable[..., None], args: Union[Iterable[Any], None] = None + ) -> None: self.func = func self.args = args - def execute(self, result) -> None: + def execute(self, result: "Result[TS, TF]") -> None: if self.args is not None: failure_args = get_args_list(self.args) if result.__id__ in failure_args: diff --git a/meiga/misc.py b/meiga/misc.py index 8ca8266..4810699 100644 --- a/meiga/misc.py +++ b/meiga/misc.py @@ -1,6 +1,9 @@ -def get_args_list(args): +from typing import Any, List, cast + + +def get_args_list(args: Any) -> List[Any]: if isinstance(args, tuple): list_args = list(args) else: list_args = [args] - return list_args + return cast(List[Any], list_args) diff --git a/meiga/result.py b/meiga/result.py index 51f7d24..edef922 100644 --- a/meiga/result.py +++ b/meiga/result.py @@ -1,4 +1,6 @@ -from typing import Any, Callable, Generic, Optional, Type, TypeVar, Union, cast +from __future__ import annotations + +from typing import Any, Callable, Generic, TypeVar, Union, cast from meiga.assertions import assert_failure, assert_success from meiga.deprecation import ( @@ -31,13 +33,13 @@ class Result(Generic[TS, TF]): def __init__( self, - success: Union[TS, Type[NoGivenValue]] = NoGivenValue, - failure: Union[TF, Type[NoGivenValue]] = NoGivenValue, + success: TS | type[NoGivenValue] = NoGivenValue, + failure: TF | type[NoGivenValue] = NoGivenValue, ) -> None: self._value_success = success self._value_failure = failure self._assert_values() - self._inner_transformer: Union[Callable[[Result[TS, TF]], Any], None] = None + self._inner_transformer: Callable[[Result[TS, TF]], Any] | None = None def __repr__(self) -> str: status = "failure" @@ -84,13 +86,13 @@ def _assert_values(self) -> None: self._is_success = True return None - def get_value(self) -> Union[TS, TF]: + def get_value(self) -> TS | TF: if self._is_success: return cast(TS, self._value_success) else: return cast(TF, self._value_failure) - def set_value(self, value) -> None: + def set_value(self, value: Any) -> None: if self._is_success: self._value_success = value else: @@ -119,7 +121,7 @@ def reraise(self) -> None: raise self.value return None - def unwrap(self) -> Union[TS, None]: + def unwrap(self) -> TS | None: """ Returns the encapsulated value if this instance is a success or None if it is failure. """ @@ -127,13 +129,14 @@ def unwrap(self) -> Union[TS, None]: return None return cast(TS, self.value) - def unwrap_or(self, failure_value: TEF) -> Union[TS, TEF]: + def unwrap_or(self, failure_value: TEF) -> TS | TEF: """ Returns the encapsulated value if this instance is a success or the selected failure_value if it is failure. """ if not self._is_success: return failure_value - return self.value + + return cast(Union[TS, TEF], self.value) def unwrap_or_return(self, return_value_on_failure: Any = None) -> TS: """ @@ -162,12 +165,12 @@ def unwrap_or_raise(self) -> TS: def unwrap_or_else( self, - on_failure_handler: Optional[ - OnFailureHandler - ] = None, # Default has to be None to be compatible with deprecated signature - failure_value: Optional[TEF] = None, - **kwargs, # Deprecated parameter [on_failure, failure_args] - ) -> Union[TS, TEF]: + on_failure_handler: ( + OnFailureHandler | None + ) = None, # Default has to be None to be compatible with deprecated signature + failure_value: TEF | None = None, + **kwargs: dict[Any, Any], # Deprecated parameter [on_failure, failure_args] + ) -> TS | TEF: """ Returns the encapsulated value if this instance is a success or execute the `on_failure_handler` when it is failure. """ @@ -183,11 +186,11 @@ def unwrap_or_else( def unwrap_and( self, - on_success_handler: Optional[ - OnSuccessHandler - ] = None, # Default has to be None to be compatible with deprecated signature - **kwargs, # Deprecated parameter [on_success, success_args] - ) -> Union[TS, None]: + on_success_handler: ( + OnSuccessHandler | None + ) = None, # Default has to be None to be compatible with deprecated signature + **kwargs: dict[Any, Any], # Deprecated parameter [on_success, success_args] + ) -> TS | None: """ Returns the encapsulated value if this instance is a success and execute the `on_success_handler` when it is success. """ @@ -198,15 +201,17 @@ def unwrap_and( on_success_handler = get_on_success_handler_from_deprecated_args(kwargs) if on_success_handler: on_success_handler.execute(self) - return self.value + return cast(TS, self.value) return None def handle( self, - on_success_handler: Optional[OnSuccessHandler] = None, - on_failure_handler: Optional[OnFailureHandler] = None, - **kwargs, # Deprecated parameter [on_success, on_failure, success_args, failure_args] - ) -> "Result": + on_success_handler: OnSuccessHandler | None = None, + on_failure_handler: OnFailureHandler | None = None, + **kwargs: dict[ + Any, Any + ], # Deprecated parameter [on_success, on_failure, success_args, failure_args] + ) -> Result[TS, TF]: """ Returns itself and execute the `on_success_handler` when the instance is a success and the `on_failure_handler` when it is failure. """ @@ -226,7 +231,7 @@ def handle( return self - def map(self, mapper: Callable[[Union[TS, TF]], Any]) -> None: + def map(self, mapper: Callable[[TS | TF], Any]) -> None: """ Returns a transformed result applying transform function applied to encapsulated value if this instance represents success or failure """ @@ -235,8 +240,8 @@ def map(self, mapper: Callable[[Union[TS, TF]], Any]) -> None: def assert_success( self, - value_is_instance_of: Optional[Type] = None, - value_is_equal_to: Optional[Any] = None, + value_is_instance_of: type[Any] | None = None, + value_is_equal_to: Any | None = None, ) -> None: """ Assert if result is a Success @@ -249,8 +254,8 @@ def assert_success( def assert_failure( self, - value_is_instance_of: Optional[Type] = None, - value_is_equal_to: Optional[Any] = None, + value_is_instance_of: type[Any] | None = None, + value_is_equal_to: Any | None = None, ) -> None: """ Assert if result is a Failure @@ -263,7 +268,7 @@ def assert_failure( value = property(get_value) - def set_transformer(self, transformer: Callable[["Result[TS, TF]"], Any]): + def set_transformer(self, transformer: Callable[[Result[TS, TF]], Any]) -> None: """ Set a Callable transformer to be used with the `transform` method """ @@ -271,9 +276,9 @@ def set_transformer(self, transformer: Callable[["Result[TS, TF]"], Any]): def transform( self, - transformer: Union[Callable[["Result"], Any], None] = None, - expected_type: Union[Type[R], None] = None, - ) -> R: # noqa + transformer: Callable[[Result[TS, TF]], Any] | None = None, + expected_type: type[R] | None = None, # noqa + ) -> R: """ Transform the result with a transformer function. You can give the transformer callable or use the set_transformer function to pre-set the callable to be used. """ @@ -285,4 +290,4 @@ def transform( ) transformer = self._inner_transformer - return transformer(self) + return cast(R, transformer(self))