Skip to content

Commit

Permalink
actionpack#141: "introduces partial Actions" (#142)
Browse files Browse the repository at this point in the history
* refactors RetryPolicy.enact

* adds test

* adds partialaction function
  • Loading branch information
withtwoemms committed Oct 10, 2022
1 parent d51e983 commit c1c7ec0
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 11 deletions.
4 changes: 3 additions & 1 deletion actionpack/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from actionpack.action import Action
from actionpack.procedure import Procedure
from actionpack.procedure import KeyedProcedure
from actionpack.action import partialaction


__all__ = [
'Action',
'Procedure',
'KeyedProcedure'
'KeyedProcedure',
'partialaction'
]
6 changes: 6 additions & 0 deletions actionpack/action.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from __future__ import annotations
from functools import partialmethod
from oslash import Left
from oslash import Right
from oslash.either import Either
Expand Down Expand Up @@ -86,6 +87,11 @@ def instruction():
return instance


def partialaction(name, parent: ActionType, **kwargs):
partial__init__ = partialmethod(parent.__init__, **kwargs)
return type(name, (parent,), {'__init__': partial__init__})


class Action(Generic[Name, Outcome], metaclass=ActionType):

_name: Optional[Name] = None
Expand Down
14 changes: 4 additions & 10 deletions actionpack/actions/retry_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,16 @@ def validate(self) -> RetryPolicy:
finally:
return self

def enact(self, with_delay: int = 0, counter: int = 0) -> Outcome:
initial_attempt = self.action.perform()
if self.should_record:
self.attempts.append(initial_attempt)
if initial_attempt.successful:
return initial_attempt.value

for _tally in tally(self.max_retries):
def enact(self, with_delay: int = 0, counter: int = -1) -> Outcome:
for _tally in tally(1 + self.max_retries):
sleep(with_delay)
counter += _tally
self.retries = counter
retry = self.action.perform()
if self.should_record:
self.attempts.append(retry)
if retry.successful:
return retry.value
elif self.should_record:
self.attempts.append(retry)

raise RetryPolicy.Expired(f'Max retries exceeded: {self.max_retries}.')

Expand Down
11 changes: 11 additions & 0 deletions tests/actionpack/test_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from unittest import TestCase

from actionpack import Action
from actionpack import partialaction
from actionpack.action import Result
from actionpack.utils import pickleable
from tests.actionpack import FakeAction
Expand Down Expand Up @@ -46,6 +47,16 @@ def test_Action_can_raise_exception(self):
with self.assertRaises(type(self.exception)):
FakeAction(instruction_provider=self.raise_failure).perform(should_raise=True)

def test_can_create_partial_Action(self):
some_result_value = 'success!'
instruction_provider = lambda: some_result_value
FakeActionWithInstruction = partialaction(
'FakeActionWithInstruction',
FakeAction,
instruction_provider=instruction_provider
)
self.assertEqual(FakeActionWithInstruction().perform().value, some_result_value)

def test_can_determine_if_Result_was_successful(self):
success = FakeAction().perform()
failure = FakeAction(instruction_provider=self.raise_failure).perform()
Expand Down

0 comments on commit c1c7ec0

Please sign in to comment.