Big refactoring, way simpler management of transformations. Early branch for upcoming version 0.2.

This commit is contained in:
Romain Dorgueil
2017-01-17 22:45:10 +01:00
parent b6e84c66e3
commit 8532520aae
41 changed files with 627 additions and 433 deletions

View File

@ -5,13 +5,10 @@ from pprint import pprint as _pprint
import blessings
from .helpers import run, console_run, jupyter_run
from .helpers import console_run, jupyter_run
from .tokens import NOT_MODIFIED
from .options import Configurable, Option
__all__ = [
'Configurable',
'Option',
'NOT_MODIFIED',
'console_run',
'jupyter_run',
@ -19,7 +16,6 @@ __all__ = [
'log',
'noop',
'pprint',
'run',
'tee',
]

View File

@ -1,25 +1,12 @@
def run(*chain, plugins=None, strategy=None):
from bonobo import Graph, ThreadPoolExecutorStrategy
if len(chain) == 1 and isinstance(chain[0], Graph):
graph = chain[0]
elif len(chain) >= 1:
graph = Graph()
graph.add_chain(*chain)
else:
raise RuntimeError('Empty chain.')
executor = (strategy or ThreadPoolExecutorStrategy)()
return executor.execute(graph, plugins=plugins or [])
def console_run(*chain, output=True, plugins=None, strategy=None):
from bonobo import run
from bonobo.ext.console import ConsoleOutputPlugin
return run(*chain, plugins=(plugins or []) + [ConsoleOutputPlugin()] if output else [], strategy=strategy)
def jupyter_run(*chain, plugins=None, strategy=None):
from bonobo import run
from bonobo.ext.jupyter import JupyterOutputPlugin
return run(*chain, plugins=(plugins or []) + [JupyterOutputPlugin()], strategy=strategy)

22
bonobo/util/objects.py Normal file
View File

@ -0,0 +1,22 @@
def get_name(mixed):
try:
return mixed.__name__
except AttributeError:
return type(mixed).__name__
class Wrapper:
def __init__(self, wrapped):
self.wrapped = wrapped
@property
def __name__(self):
return getattr(self.wrapped, '__name__', getattr(type(self.wrapped), '__name__', repr(self.wrapped)))
name = __name__
class ValueHolder:
def __init__(self, value, *, type=None):
self.value = value
self.type = type

View File

@ -1,61 +0,0 @@
class Option:
def __init__(self, type=None, *, required=False, default=None):
self.name = None
self.type = type
self.required = required
self.default = default
def __get__(self, inst, typ):
return inst.__options_values__.get(self.name, self.default)
def __set__(self, inst, value):
inst.__options_values__[self.name] = self.type(value) if self.type else value
class ConfigurableMeta(type):
def __init__(cls, what, bases=None, dict=None):
super().__init__(what, bases, dict)
cls.__options__ = {}
for typ in cls.__mro__:
for name, value in typ.__dict__.items():
if isinstance(value, Option):
if not value.name:
value.name = name
if not name in cls.__options__:
cls.__options__[name] = value
class Configurable(metaclass=ConfigurableMeta):
"""
Generic class for configurable objects. Configurable objects have a dictionary of "options" descriptors that defines
the configuration schema of the type.
"""
def __init__(self, **kwargs):
self.__options_values__ = {}
missing = set()
for name, option in type(self).__options__.items():
if option.required and not option.name in kwargs:
missing.add(name)
if len(missing):
raise TypeError(
'{}() missing {} required option{}: {}.'.format(
type(self).__name__,
len(missing), 's' if len(missing) > 1 else '', ', '.join(map(repr, sorted(missing)))
)
)
extraneous = set(kwargs.keys()) - set(type(self).__options__.keys())
if len(extraneous):
raise TypeError(
'{}() got {} unexpected option{}: {}.'.format(
type(self).__name__,
len(extraneous), 's' if len(extraneous) > 1 else '', ', '.join(map(repr, sorted(extraneous)))
)
)
for name, value in kwargs.items():
setattr(self, name, kwargs[name])

View File

@ -1,9 +1,9 @@
from unittest.mock import MagicMock
from bonobo.core.contexts import ComponentExecutionContext
from bonobo.context.execution import NodeExecutionContext
class CapturingComponentExecutionContext(ComponentExecutionContext):
def __init__(self, component, parent):
super().__init__(component, parent)
class CapturingNodeExecutionContext(NodeExecutionContext):
def __init__(self, wrapped, parent):
super().__init__(wrapped, parent)
self.send = MagicMock()

View File

@ -11,8 +11,4 @@ class Token:
BEGIN = Token('Begin')
END = Token('End')
NEW = Token('New')
RUNNING = Token('Running')
TERMINATED = Token('Terminated')
NOT_MODIFIED = Token('NotModified')