Generalize tuplize decorator to cast(...) decorator.
This commit is contained in:
@ -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',
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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)
|
||||||
|
"""
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user