Skip to content

Commit

Permalink
chore(typing): solve some mypy strict errors in meiga module (#61)
Browse files Browse the repository at this point in the history
* chore(typing): solve some mypy strict errors in meiga module

* chore(typing): solve mypy error on get_args_list
  • Loading branch information
acostapazo authored May 13, 2023
1 parent 11a9eef commit b3ac895
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 64 deletions.
7 changes: 3 additions & 4 deletions meiga/alias.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 5 additions & 5 deletions meiga/assertions/assert_failure.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
10 changes: 5 additions & 5 deletions meiga/assertions/assert_success.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 2 additions & 2 deletions meiga/decorators/early_return.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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]:
Expand Down
4 changes: 2 additions & 2 deletions meiga/decorators/to_result.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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]:
Expand Down
6 changes: 3 additions & 3 deletions meiga/deprecation.py
Original file line number Diff line number Diff line change
@@ -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:
Expand All @@ -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:
Expand Down
11 changes: 8 additions & 3 deletions meiga/error.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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,))
11 changes: 8 additions & 3 deletions meiga/handlers.py
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
7 changes: 5 additions & 2 deletions meiga/misc.py
Original file line number Diff line number Diff line change
@@ -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)
75 changes: 40 additions & 35 deletions meiga/result.py
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -119,21 +121,22 @@ 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.
"""
if not self._is_success:
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:
"""
Expand Down Expand Up @@ -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.
"""
Expand All @@ -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.
"""
Expand All @@ -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.
"""
Expand All @@ -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
"""
Expand All @@ -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
Expand All @@ -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
Expand All @@ -263,17 +268,17 @@ 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
"""
self._inner_transformer = transformer

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.
"""
Expand All @@ -285,4 +290,4 @@ def transform(
)
transformer = self._inner_transformer

return transformer(self)
return cast(R, transformer(self))

0 comments on commit b3ac895

Please sign in to comment.