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.inspect import (
inspect_node,
@ -16,6 +16,7 @@ from bonobo.util.objects import (get_name, get_attribute_or_create, ValueHolder)
# Bonobo's util API
__all__ = [
'ValueHolder',
'cast',
'deprecated',
'deprecated_alias',
'ensure_tuple',

View File

@ -2,6 +2,7 @@ from bonobo.util import get_name
class ApiHelper:
# TODO __all__ kwarg only
def __init__(self, __all__):
self.__all__ = __all__
@ -13,7 +14,8 @@ class ApiHelper:
from inspect import signature
parameters = list(signature(x).parameters)
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(
parameters
) == 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):
return tuple.__new__(cls, tuple_or_mixed)
return tuple.__new__(cls, (tuple_or_mixed, ))
return tuple.__new__(cls, (tuple_or_mixed,))
def tuplize(generator):
"""
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.
def cast(type_):
def _wrap_cast(f):
@functools.wraps(f)
def _wrapped_cast(*args, **kwargs):
nonlocal f, type_
return type_(f(*args, **kwargs))
>>> tuplized_lambda = tuplize(lambda: [1, 2, 3])
>>> tuplized_lambda()
(1, 2, 3)
return _wrapped_cast
>>> @tuplize
... def my_generator():
... yield 1
... yield 2
... yield 3
...
>>> my_generator()
(1, 2, 3)
return _wrap_cast
"""
@functools.wraps(generator)
def tuplized(*args, **kwargs):
return tuple(generator(*args, **kwargs))
tuplize = cast(tuple)
tuplize.__doc__ = """
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 bonobo
from bonobo.util.collections import tuplize
from bonobo.util import cast
class _RequiredModule:
@ -61,7 +61,7 @@ def _resolve_options(options=None):
return dict()
@tuplize
@cast(tuple)
def _resolve_transformations(transformations):
"""
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.collections import tuplize
from bonobo.util.collections import tuplize, cast
def test_sortedlist():
@ -12,12 +14,13 @@ def test_sortedlist():
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 ()
def test_tuplize():
@pytest.mark.parametrize('tuplize', [tuplize, cast(tuple)])
def test_tuplize(tuplize):
tuplized_lambda = tuplize(lambda: [1, 2, 3])
assert tuplized_lambda() == (1, 2, 3)