Big refactoring, way simpler management of transformations. Early branch for upcoming version 0.2.
This commit is contained in:
@ -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',
|
||||
]
|
||||
|
||||
|
||||
@ -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
22
bonobo/util/objects.py
Normal 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
|
||||
@ -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])
|
||||
@ -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()
|
||||
|
||||
@ -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')
|
||||
|
||||
Reference in New Issue
Block a user