Skip to content
Snippets Groups Projects
Commit 2c78c758 authored by Piotr Maślanka's avatar Piotr Maślanka
Browse files

v2.14.18 - added `transform_result` and `transform_arguments`

parent 774fda2b
No related branches found
Tags v2.14.18
No related merge requests found
# v2.14.18 # v2.14.18
* added `transform_result` and `transform_arguments`
Decorators Decorators
========== ==========
.. autofunction:: satella.coding.decorators.transform_result
.. autofunction:: satella.coding.decorators.transforms_arguments
.. autofunction:: satella.coding.decorators.retry .. autofunction:: satella.coding.decorators.retry
.. autofunction:: satella.coding.decorators.memoize .. autofunction:: satella.coding.decorators.memoize
......
__version__ = '2.14.18_a1' __version__ = '2.14.18'
from .arguments import auto_adapt_to_methods, attach_arguments, for_argument, \ from .arguments import auto_adapt_to_methods, attach_arguments, for_argument, \
execute_before, copy_arguments, replace_argument_if execute_before, copy_arguments, replace_argument_if, transform_result, \
transform_arguments
from .decorators import wraps, chain_functions, has_keys, short_none, memoize, return_as_list, \ from .decorators import wraps, chain_functions, has_keys, short_none, memoize, return_as_list, \
default_return default_return
from .flow_control import loop_while, queue_get from .flow_control import loop_while, queue_get
from .preconditions import postcondition, precondition from .preconditions import postcondition, precondition
from .retry_dec import retry from .retry_dec import retry
__all__ = ['retry', __all__ = ['retry', 'transform_result', 'transform_arguments',
'execute_before', 'postcondition', 'precondition', 'wraps', 'queue_get', 'execute_before', 'postcondition', 'precondition', 'wraps', 'queue_get',
'chain_functions', 'has_keys', 'short_none', 'auto_adapt_to_methods', 'chain_functions', 'has_keys', 'short_none', 'auto_adapt_to_methods',
'attach_arguments', 'for_argument', 'loop_while', 'memoize', 'attach_arguments', 'for_argument', 'loop_while', 'memoize',
......
...@@ -17,6 +17,59 @@ def _NOP(x): ...@@ -17,6 +17,59 @@ def _NOP(x):
return x return x
def transform_result(expr: str):
"""
A decorator transforming the result value of a function by a Python expression.
The result is feeded as the local variable "x", while arguments are fed as if they were
expressed as arguments, eg:
>>> @transform_result('x*a')
>>> def square(a):
>>> return a
:param expr: Python string expression
"""
def outer(fun):
@wraps(fun)
def inner(*args, **kwargs):
a = fun(*args, **kwargs)
local = get_arguments(fun, *args, *kwargs)
local['x'] = a
return eval(expr, globals(), local)
return inner
return outer
def transform_arguments(**expressions: str):
"""
A decorator transforming the arguments of a function prior to it's execution.
The arguments are always bound as if they were available in the function.
The expressions always operate on "old" arguments
>>> @transform_arguments(a='a*a')
>>> def square(a):
>>> return a
:param expressions: Python strings that are meant to be evaluated
"""
def outer(fun):
@wraps(fun)
def inner(*args, **kwargs):
old_args = get_arguments(fun, *args, *kwargs)
new_args = {}
for arg, arg_value in expressions.items():
new_args[arg] = eval(arg_value, globals(), old_args)
for new_arg in old_args:
if new_arg not in new_args:
new_args[new_arg] = old_args[new_arg]
return call_with_arguments(fun, new_args)
return inner
return outer
def execute_before(callable_: tp.Callable) -> tp.Callable: def execute_before(callable_: tp.Callable) -> tp.Callable:
""" """
Wrapper to create wrappers which execute callable before function launch. Wrapper to create wrappers which execute callable before function launch.
......
...@@ -7,7 +7,7 @@ from satella.coding import wraps, chain_functions, postcondition, \ ...@@ -7,7 +7,7 @@ from satella.coding import wraps, chain_functions, postcondition, \
log_exceptions, queue_get, precondition, short_none log_exceptions, queue_get, precondition, short_none
from satella.coding.decorators import auto_adapt_to_methods, attach_arguments, \ from satella.coding.decorators import auto_adapt_to_methods, attach_arguments, \
execute_before, loop_while, memoize, copy_arguments, replace_argument_if, \ execute_before, loop_while, memoize, copy_arguments, replace_argument_if, \
retry, return_as_list, default_return retry, return_as_list, default_return, transform_result, transform_arguments
from satella.coding.predicates import x from satella.coding.predicates import x
from satella.exceptions import PreconditionError from satella.exceptions import PreconditionError
...@@ -16,6 +16,20 @@ logger = logging.getLogger(__name__) ...@@ -16,6 +16,20 @@ logger = logging.getLogger(__name__)
class TestDecorators(unittest.TestCase): class TestDecorators(unittest.TestCase):
def test_transform_arguments(self):
@transform_arguments(a='a*a')
def square(a):
return a
self.assertEqual(square(4), 16)
def test_transform_result(self):
@transform_result('x*a')
def square(a):
return a
self.assertEqual(square(4), 16)
def test_default_returns(self): def test_default_returns(self):
@default_return(6) @default_return(6)
def returns(v): def returns(v):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment