Generalize tuplize decorator to cast(...) decorator.

This commit is contained in:
Romain Dorgueil
2017-12-27 14:21:50 +01:00
parent f64e6e3c76
commit 464d08a4a2
5 changed files with 40 additions and 29 deletions

View File

@ -1,4 +1,4 @@
from bonobo.util.collections import ensure_tuple, sortedlist, tuplize from bonobo.util.collections import cast, ensure_tuple, sortedlist, tuplize
from bonobo.util.compat import deprecated, deprecated_alias from bonobo.util.compat import deprecated, deprecated_alias
from bonobo.util.inspect import ( from bonobo.util.inspect import (
inspect_node, inspect_node,
@ -16,6 +16,7 @@ from bonobo.util.objects import (get_name, get_attribute_or_create, ValueHolder)
# Bonobo's util API # Bonobo's util API
__all__ = [ __all__ = [
'ValueHolder', 'ValueHolder',
'cast',
'deprecated', 'deprecated',
'deprecated_alias', 'deprecated_alias',
'ensure_tuple', 'ensure_tuple',

View File

@ -2,6 +2,7 @@ from bonobo.util import get_name
class ApiHelper: class ApiHelper:
# TODO __all__ kwarg only
def __init__(self, __all__): def __init__(self, __all__):
self.__all__ = __all__ self.__all__ = __all__
@ -13,7 +14,8 @@ class ApiHelper:
from inspect import signature from inspect import signature
parameters = list(signature(x).parameters) parameters = list(signature(x).parameters)
required_parameters = {'plugins', 'services', 'strategy'} required_parameters = {'plugins', 'services', 'strategy'}
assert parameters[0] == 'graph', 'First parameter of a graph api function must be "graph".' assert len(parameters) > 0 and parameters[
0] == 'graph', 'First parameter of a graph api function must be "graph".'
assert required_parameters.intersection( assert required_parameters.intersection(
parameters parameters
) == required_parameters, 'Graph api functions must define the following parameters: ' + ', '.join( ) == required_parameters, 'Graph api functions must define the following parameters: ' + ', '.join(

View File

@ -26,31 +26,36 @@ def ensure_tuple(tuple_or_mixed, *, cls=tuple):
if isinstance(tuple_or_mixed, tuple): if isinstance(tuple_or_mixed, tuple):
return tuple.__new__(cls, tuple_or_mixed) return tuple.__new__(cls, tuple_or_mixed)
return tuple.__new__(cls, (tuple_or_mixed, )) return tuple.__new__(cls, (tuple_or_mixed,))
def tuplize(generator): def cast(type_):
""" def _wrap_cast(f):
Decorates a generator and make it a tuple-returning function. As a side effect, it can also decorate any @functools.wraps(f)
iterator-returning function to force return value to be a tuple. def _wrapped_cast(*args, **kwargs):
nonlocal f, type_
return type_(f(*args, **kwargs))
>>> tuplized_lambda = tuplize(lambda: [1, 2, 3]) return _wrapped_cast
>>> tuplized_lambda()
(1, 2, 3)
>>> @tuplize return _wrap_cast
... def my_generator():
... yield 1
... yield 2
... yield 3
...
>>> my_generator()
(1, 2, 3)
"""
@functools.wraps(generator) tuplize = cast(tuple)
def tuplized(*args, **kwargs): tuplize.__doc__ = """
return tuple(generator(*args, **kwargs)) Decorates a generator and make it a tuple-returning function. As a side effect, it can also decorate any
iterator-returning function to force return value to be a tuple.
return tuplized >>> tuplized_lambda = tuplize(lambda: [1, 2, 3])
>>> tuplized_lambda()
(1, 2, 3)
>>> @tuplize
... def my_generator():
... yield 1
... yield 2
... yield 3
...
>>> my_generator()
(1, 2, 3)
"""

View File

@ -8,7 +8,7 @@ import os
import runpy import runpy
import bonobo import bonobo
from bonobo.util.collections import tuplize from bonobo.util import cast
class _RequiredModule: class _RequiredModule:
@ -61,7 +61,7 @@ def _resolve_options(options=None):
return dict() return dict()
@tuplize @cast(tuple)
def _resolve_transformations(transformations): def _resolve_transformations(transformations):
""" """
Resolve a collection of strings into the matching python objects, defaulting to bonobo namespace if no package is provided. Resolve a collection of strings into the matching python objects, defaulting to bonobo namespace if no package is provided.

View File

@ -1,5 +1,7 @@
import pytest
from bonobo.util import sortedlist, ensure_tuple from bonobo.util import sortedlist, ensure_tuple
from bonobo.util.collections import tuplize from bonobo.util.collections import tuplize, cast
def test_sortedlist(): def test_sortedlist():
@ -12,12 +14,13 @@ def test_sortedlist():
def test_ensure_tuple(): def test_ensure_tuple():
assert ensure_tuple('a') == ('a', ) assert ensure_tuple('a') == ('a',)
assert ensure_tuple(('a', )) == ('a', ) assert ensure_tuple(('a',)) == ('a',)
assert ensure_tuple(()) is () assert ensure_tuple(()) is ()
def test_tuplize(): @pytest.mark.parametrize('tuplize', [tuplize, cast(tuple)])
def test_tuplize(tuplize):
tuplized_lambda = tuplize(lambda: [1, 2, 3]) tuplized_lambda = tuplize(lambda: [1, 2, 3])
assert tuplized_lambda() == (1, 2, 3) assert tuplized_lambda() == (1, 2, 3)