-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/transform #60
Changes from 3 commits
f75b197
5c148bc
e3ae56f
9123f8d
0647073
e514efe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
TS = TypeVar("TS") # Success Type | ||
TF = TypeVar("TF") # Failure Type | ||
TEF = TypeVar("TEF") # External Failure Type | ||
R = TypeVar("R") # Recast expected type | ||
|
||
|
||
class Result(Generic[TS, TF]): | ||
|
@@ -21,7 +22,12 @@ class Result(Generic[TS, TF]): | |
|
||
__id__ = "__meiga_result_identifier__" | ||
__match_args__ = ("_value_success", "_value_failure") | ||
__slots__ = ("_value_success", "_value_failure", "_is_success") | ||
__slots__ = ( | ||
"_value_success", | ||
"_value_failure", | ||
"_is_success", | ||
"_inner_transformer", | ||
) | ||
|
||
def __init__( | ||
self, | ||
|
@@ -31,6 +37,7 @@ def __init__( | |
self._value_success = success | ||
self._value_failure = failure | ||
self._assert_values() | ||
self._inner_transformer: Union[Callable[[Result], Any], None] = None | ||
|
||
def __repr__(self) -> str: | ||
status = "failure" | ||
|
@@ -219,11 +226,11 @@ def handle( | |
|
||
return self | ||
|
||
def map(self, transform: Callable) -> None: | ||
def map(self, mapper: Callable) -> None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pretty sure one cannot use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mypy has pretty tame defaults, to the point that I myself prefer to run it with Tho forcing this on an unprepared codebase will result in a ton of unexpected red squiggles. Currently counting 33 on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ohh thank you for this advice. |
||
""" | ||
Returns a transformed result applying transform function applied to encapsulated value if this instance represents success or failure | ||
""" | ||
new_value = transform(self.value) | ||
new_value = mapper(self.value) | ||
self.set_value(new_value) | ||
|
||
def assert_success( | ||
|
@@ -255,3 +262,21 @@ def assert_failure( | |
) | ||
|
||
value = property(get_value) | ||
|
||
def set_transformer(self, transformer: Callable[["Result"], Any]): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to work
|
||
""" | ||
Set a Callable transformer to be used with the `transform` method | ||
""" | ||
self._inner_transformer = transformer | ||
|
||
def transform(self, expected_type: Union[Type[R], None] = None) -> R: # noqa | ||
""" | ||
Transform the result with set transformer (Use `set_transformer` function to define it) | ||
""" | ||
if not self._inner_transformer: | ||
raise RuntimeError( | ||
"Result object cannot be transformed as no transformer have been set yet. " | ||
"Use result.set_transformer(callable) to add your transformer callable method" | ||
) | ||
|
||
return self._inner_transformer(self) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import pytest | ||
|
||
from meiga import Result, Success | ||
|
||
|
||
def transformer(result: Result): | ||
return result.value | ||
|
||
|
||
@pytest.mark.unit | ||
def test_should_set_transformer_an_return_transformed_value(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. * |
||
result = Success("Hi") | ||
result.set_transformer(transformer) | ||
|
||
recast_result = result.transform() | ||
|
||
assert recast_result == "Hi" | ||
|
||
|
||
@pytest.mark.unit | ||
def test_should_set_transformer_an_return_transformed_value_with_expected_type(): | ||
result = Success("Hi") | ||
result.set_transformer(transformer) | ||
|
||
recast_result = result.transform(expected_type=str) | ||
|
||
assert recast_result == "Hi" | ||
|
||
|
||
@pytest.mark.unit | ||
def test_should_raise_an_error_when_transform_method_is_not_set(): | ||
result = Success("Hi") | ||
|
||
with pytest.raises(RuntimeError): | ||
result.transform() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional
here and intransform()
, since it is already imported?Result[TS, TF]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Union[Callable[[Result], Any], None]
is equivalent toOptional[Callable[[Result], Any],]
. In fact, I think that newer syntax is recommendedCallable[[Result], Any] | None
. To fully adopt the newer Python syntax while maintaining backwards compatibility, I'm considering adding thefrom __future__ import annotations
statement to meigas's code. This statement enables the use of forward references in annotations, allowing you to refer to classes and types that haven't been defined yet.