diff --git a/bonobo/__init__.py b/bonobo/__init__.py index 2a9515f..d605183 100644 --- a/bonobo/__init__.py +++ b/bonobo/__init__.py @@ -7,17 +7,50 @@ import sys -assert (sys.version_info >= (3, 5)), 'Python 3.5+ is required to use Bonobo.' +assert sys.version_info >= (3, 5), "Python 3.5+ is required to use Bonobo." from bonobo._api import ( - run, inspect, Graph, create_strategy, open_fs, CsvReader, CsvWriter, FileReader, FileWriter, Filter, FixedWindow, - Format, JsonReader, JsonWriter, LdjsonReader, LdjsonWriter, Limit, OrderFields, PickleReader, PickleWriter, - PrettyPrinter, RateLimited, Rename, SetFields, Tee, UnpackItems, count, identity, noop, create_reader, - create_writer, get_examples_path, open_examples_fs, get_argument_parser, parse_args, __all__, __doc__ + run, + inspect, + Graph, + create_strategy, + open_fs, + CsvReader, + CsvWriter, + FileReader, + FileWriter, + Filter, + FixedWindow, + Format, + JsonReader, + JsonWriter, + LdjsonReader, + LdjsonWriter, + Limit, + OrderFields, + PickleReader, + PickleWriter, + PrettyPrinter, + RateLimited, + Rename, + SetFields, + Tee, + UnpackItems, + count, + identity, + noop, + create_reader, + create_writer, + get_examples_path, + open_examples_fs, + get_argument_parser, + parse_args, + __all__, + __doc__, ) from bonobo._version import __version__ -__all__ = ['__version__'] + __all__ +__all__ = ["__version__"] + __all__ __logo__ = '' __doc__ = __doc__ __version__ = __version__ @@ -32,10 +65,8 @@ def _repr_html_(): '
{}'
- '{}'.format(self.graphviz._repr_svg_(), html.escape(repr(self)))
+ return "{}".format(self.graphviz._repr_svg_(), html.escape(repr(self)))
except (ExecutableNotFound, FileNotFoundError) as exc:
- return '{}: {}'.format(type(exc).__name__, str(exc))
+ return "{}: {}".format(type(exc).__name__, str(exc))
def _resolve_index(self, mixed):
"""
@@ -182,10 +209,10 @@ class Graph:
if mixed in self.nodes:
return self.nodes.index(mixed)
- raise ValueError('Cannot find node matching {!r}.'.format(mixed))
+ raise ValueError("Cannot find node matching {!r}.".format(mixed))
def _get_graphviz_node_id(graph, i):
escaped_index = str(i)
escaped_name = json.dumps(get_name(graph[i]))
- return '{{{} [label={}]}}'.format(escaped_index, escaped_name)
+ return "{{{} [label={}]}}".format(escaped_index, escaped_name)
diff --git a/bonobo/structs/inputs.py b/bonobo/structs/inputs.py
index 2731000..f0277b1 100644
--- a/bonobo/structs/inputs.py
+++ b/bonobo/structs/inputs.py
@@ -70,7 +70,7 @@ class Input(Queue, Readable, Writable):
# Check we are actually able to receive data.
if self._writable_runlevel < 1:
- raise InactiveWritableError('Cannot put() on an inactive {}.'.format(Writable.__name__))
+ raise InactiveWritableError("Cannot put() on an inactive {}.".format(Writable.__name__))
if data == END:
self._writable_runlevel -= 1
@@ -85,7 +85,7 @@ class Input(Queue, Readable, Writable):
def get(self, block=True, timeout=None):
if not self.alive:
- raise InactiveReadableError('Cannot get() on an inactive {}.'.format(Readable.__name__))
+ raise InactiveReadableError("Cannot get() on an inactive {}.".format(Readable.__name__))
data = Queue.get(self, block, timeout)
@@ -94,7 +94,7 @@ class Input(Queue, Readable, Writable):
if not self.alive:
raise InactiveReadableError(
- 'Cannot get() on an inactive {} (runlevel just reached 0).'.format(Readable.__name__)
+ "Cannot get() on an inactive {} (runlevel just reached 0).".format(Readable.__name__)
)
return self.get(block, timeout)
diff --git a/bonobo/structs/tokens.py b/bonobo/structs/tokens.py
index 9b8f151..3edf773 100644
--- a/bonobo/structs/tokens.py
+++ b/bonobo/structs/tokens.py
@@ -3,7 +3,7 @@ class Token:
self.__name__ = name
def __repr__(self):
- return '<{}>'.format(self.__name__)
+ return "<{}>".format(self.__name__)
class Flag(Token):
diff --git a/bonobo/util/__init__.py b/bonobo/util/__init__.py
index 894d053..881fada 100644
--- a/bonobo/util/__init__.py
+++ b/bonobo/util/__init__.py
@@ -16,25 +16,25 @@ from bonobo.util.inspect import (
istuple,
istype,
)
-from bonobo.util.objects import (get_name, get_attribute_or_create, ValueHolder)
+from bonobo.util.objects import get_name, get_attribute_or_create, ValueHolder
# Bonobo's util API
__all__ = [
- 'ValueHolder',
- 'cast',
- 'deprecated',
- 'deprecated_alias',
- 'ensure_tuple',
- 'get_attribute_or_create',
- 'get_name',
- 'inspect_node',
- 'isconfigurable',
- 'isconfigurabletype',
- 'iscontextprocessor',
- 'isdict',
- 'ismethod',
- 'isoption',
- 'istype',
- 'sortedlist',
- 'tuplize',
+ "ValueHolder",
+ "cast",
+ "deprecated",
+ "deprecated_alias",
+ "ensure_tuple",
+ "get_attribute_or_create",
+ "get_name",
+ "inspect_node",
+ "isconfigurable",
+ "isconfigurabletype",
+ "iscontextprocessor",
+ "isdict",
+ "ismethod",
+ "isoption",
+ "istype",
+ "sortedlist",
+ "tuplize",
]
diff --git a/bonobo/util/api.py b/bonobo/util/api.py
index 7bfba02..37754ee 100644
--- a/bonobo/util/api.py
+++ b/bonobo/util/api.py
@@ -12,14 +12,14 @@ class ApiHelper:
if graph:
# This function must comply to the "graph" API interface, meaning it can bahave like bonobo.run.
from inspect import signature
+
parameters = list(signature(x).parameters)
- required_parameters = {'plugins', 'services', 'strategy'}
- 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(
- sorted(required_parameters)
+ required_parameters = {"plugins", "services", "strategy"}
+ 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(sorted(required_parameters))
)
self.__all__.append(get_name(x))
diff --git a/bonobo/util/bags.py b/bonobo/util/bags.py
index fd31d06..c0d221e 100644
--- a/bonobo/util/bags.py
+++ b/bonobo/util/bags.py
@@ -71,16 +71,18 @@ class {typename}(tuple):
{field_defs}
'''
-_field_template = '''\
+_field_template = """\
{name} = _property(_itemgetter({index:d}), doc={doc!r})
-'''.strip('\n')
-
-_reserved = frozenset(
- ['_', '_cls', '_attrs', '_fields', 'get', '_asdict', '_replace', '_make', 'self', '_self', 'tuple'] + dir(tuple)
+""".strip(
+ "\n"
)
-_multiple_underscores_pattern = re.compile('__+')
-_slugify_allowed_chars_pattern = re.compile(r'[^a-z0-9_]+', flags=re.IGNORECASE)
+_reserved = frozenset(
+ ["_", "_cls", "_attrs", "_fields", "get", "_asdict", "_replace", "_make", "self", "_self", "tuple"] + dir(tuple)
+)
+
+_multiple_underscores_pattern = re.compile("__+")
+_slugify_allowed_chars_pattern = re.compile(r"[^a-z0-9_]+", flags=re.IGNORECASE)
def _uniquify(f):
@@ -90,13 +92,13 @@ def _uniquify(f):
def _uniquified(x):
nonlocal f, seen
x = str(x)
- v = v0 = _multiple_underscores_pattern.sub('_', f(x))
+ v = v0 = _multiple_underscores_pattern.sub("_", f(x))
i = 0
# if last character is not "allowed", let's start appending indexes right from the first iteration
if len(x) and _slugify_allowed_chars_pattern.match(x[-1]):
- v = '{}{}'.format(v0, i)
+ v = "{}{}".format(v0, i)
while v in seen:
- v = '{}{}'.format(v0, i)
+ v = "{}{}".format(v0, i)
i += 1
seen.add(v)
return v
@@ -106,13 +108,13 @@ def _uniquify(f):
def _make_valid_attr_name(x):
if iskeyword(x):
- x = '_' + x
+ x = "_" + x
if x.isidentifier():
return x
- x = slugify(x, separator='_', regex_pattern=_slugify_allowed_chars_pattern)
+ x = slugify(x, separator="_", regex_pattern=_slugify_allowed_chars_pattern)
if x.isidentifier():
return x
- x = '_' + x
+ x = "_" + x
if x.isidentifier():
return x
raise ValueError(x)
@@ -124,23 +126,23 @@ def BagType(typename, fields, *, verbose=False, module=None):
attrs = tuple(map(_uniquify(_make_valid_attr_name), fields))
if type(fields) is str:
- raise TypeError('BagType does not support providing fields as a string.')
+ raise TypeError("BagType does not support providing fields as a string.")
fields = list(map(str, fields))
typename = str(typename)
for i, name in enumerate([typename] + fields):
if type(name) is not str:
- raise TypeError('Type names and field names must be strings, got {name!r}'.format(name=name))
+ raise TypeError("Type names and field names must be strings, got {name!r}".format(name=name))
if not i:
if not name.isidentifier():
- raise ValueError('Type names must be valid identifiers: {name!r}'.format(name=name))
+ raise ValueError("Type names must be valid identifiers: {name!r}".format(name=name))
if iskeyword(name):
- raise ValueError('Type names cannot be a keyword: {name!r}'.format(name=name))
+ raise ValueError("Type names cannot be a keyword: {name!r}".format(name=name))
seen = set()
for name in fields:
if name in seen:
- raise ValueError('Encountered duplicate field name: {name!r}'.format(name=name))
+ raise ValueError("Encountered duplicate field name: {name!r}".format(name=name))
seen.add(name)
# Fill-in the class template
@@ -150,21 +152,24 @@ def BagType(typename, fields, *, verbose=False, module=None):
attrs=attrs,
num_fields=len(fields),
arg_list=repr(attrs).replace("'", "")[1:-1],
- repr_fmt=', '.join(('%r' if isinstance(fields[index], int) else '{name}=%r').format(name=name)
- for index, name in enumerate(attrs)),
- field_defs='\n'.join(
+ repr_fmt=", ".join(
+ ("%r" if isinstance(fields[index], int) else "{name}=%r").format(name=name)
+ for index, name in enumerate(attrs)
+ ),
+ field_defs="\n".join(
_field_template.format(
index=index,
name=name,
- doc='Alias for ' +
- ('field #{}'.format(index) if isinstance(fields[index], int) else repr(fields[index]))
- ) for index, name in enumerate(attrs)
- )
+ doc="Alias for "
+ + ("field #{}".format(index) if isinstance(fields[index], int) else repr(fields[index])),
+ )
+ for index, name in enumerate(attrs)
+ ),
)
# Execute the template string in a temporary namespace and support
# tracing utilities by setting a value for frame.f_globals['__name__']
- namespace = dict(__name__='namedtuple_%s' % typename)
+ namespace = dict(__name__="namedtuple_%s" % typename)
exec(class_definition, namespace)
result = namespace[typename]
result._source = class_definition
@@ -178,7 +183,7 @@ def BagType(typename, fields, *, verbose=False, module=None):
# specified a particular module.
if module is None:
try:
- module = sys._getframe(1).f_globals.get('__name__', '__main__')
+ module = sys._getframe(1).f_globals.get("__name__", "__main__")
except (AttributeError, ValueError):
pass
if module is not None:
diff --git a/bonobo/util/collections.py b/bonobo/util/collections.py
index 1234142..9133e09 100644
--- a/bonobo/util/collections.py
+++ b/bonobo/util/collections.py
@@ -25,7 +25,7 @@ def _with_length_check(f):
if length is not None:
if length != len(result):
raise TypeError(
- 'Length check failed, expected {} fields but got {}: {!r}.'.format(length, len(result), result)
+ "Length check failed, expected {} fields but got {}: {!r}.".format(length, len(result), result)
)
return result
@@ -54,7 +54,7 @@ def ensure_tuple(tuple_or_mixed, *, cls=None):
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 cast(type_):
diff --git a/bonobo/util/compat.py b/bonobo/util/compat.py
index 4a62742..56e313f 100644
--- a/bonobo/util/compat.py
+++ b/bonobo/util/compat.py
@@ -5,13 +5,13 @@ import warnings
def deprecated_alias(alias, func):
@functools.wraps(func)
def new_func(*args, **kwargs):
- warnings.simplefilter('always', DeprecationWarning) # turn off filter
+ warnings.simplefilter("always", DeprecationWarning) # turn off filter
warnings.warn(
"Call to deprecated function alias {}, use {} instead.".format(alias, func.__name__),
category=DeprecationWarning,
- stacklevel=2
+ stacklevel=2,
)
- warnings.simplefilter('default', DeprecationWarning) # reset filter
+ warnings.simplefilter("default", DeprecationWarning) # reset filter
return func(*args, **kwargs)
return new_func
@@ -24,11 +24,11 @@ def deprecated(func):
@functools.wraps(func)
def new_func(*args, **kwargs):
- warnings.simplefilter('always', DeprecationWarning) # turn off filter
+ warnings.simplefilter("always", DeprecationWarning) # turn off filter
warnings.warn(
"Call to deprecated function {}.".format(func.__name__), category=DeprecationWarning, stacklevel=2
)
- warnings.simplefilter('default', DeprecationWarning) # reset filter
+ warnings.simplefilter("default", DeprecationWarning) # reset filter
return func(*args, **kwargs)
return new_func
diff --git a/bonobo/util/envelopes.py b/bonobo/util/envelopes.py
index 04f8080..d888342 100644
--- a/bonobo/util/envelopes.py
+++ b/bonobo/util/envelopes.py
@@ -1,8 +1,8 @@
from bonobo.structs.tokens import Flag
-F_INHERIT = Flag('Inherit')
+F_INHERIT = Flag("Inherit")
-F_NOT_MODIFIED = Flag('NotModified')
+F_NOT_MODIFIED = Flag("NotModified")
F_NOT_MODIFIED.must_be_first = True
F_NOT_MODIFIED.must_be_last = True
F_NOT_MODIFIED.allows_data = False
diff --git a/bonobo/util/environ.py b/bonobo/util/environ.py
index 980d1db..b1a6635 100644
--- a/bonobo/util/environ.py
+++ b/bonobo/util/environ.py
@@ -5,12 +5,12 @@ import re
import warnings
from contextlib import contextmanager
-__escape_decoder = codecs.getdecoder('unicode_escape')
-__posix_variable = re.compile('\$\{[^\}]*\}')
+__escape_decoder = codecs.getdecoder("unicode_escape")
+__posix_variable = re.compile("\$\{[^\}]*\}")
def parse_var(var):
- name, value = var.split('=', 1)
+ name, value = var.split("=", 1)
def decode_escaped(escaped):
return __escape_decoder(escaped)[0]
@@ -29,15 +29,15 @@ def load_env_from_file(filename):
Read an env file into a collection of (name, value) tuples.
"""
if not os.path.exists(filename):
- raise FileNotFoundError('Environment file {} does not exist.'.format(filename))
+ raise FileNotFoundError("Environment file {} does not exist.".format(filename))
with open(filename) as f:
for lineno, line in enumerate(f):
line = line.strip()
- if not line or line.startswith('#'):
+ if not line or line.startswith("#"):
continue
- if '=' not in line:
- raise SyntaxError('Invalid environment file syntax in {} at line {}.'.format(filename, lineno + 1))
+ if "=" not in line:
+ raise SyntaxError("Invalid environment file syntax in {} at line {}.".format(filename, lineno + 1))
name, value = parse_var(line)
@@ -64,10 +64,10 @@ def get_argument_parser(parser=None):
global _parser
_parser = parser
- _parser.add_argument('--default-env-file', '-E', action='append')
- _parser.add_argument('--default-env', action='append')
- _parser.add_argument('--env-file', action='append')
- _parser.add_argument('--env', '-e', action='append')
+ _parser.add_argument("--default-env-file", "-E", action="append")
+ _parser.add_argument("--default-env", action="append")
+ _parser.add_argument("--env-file", action="append")
+ _parser.add_argument("--env", "-e", action="append")
return _parser
@@ -89,10 +89,11 @@ def parse_args(mixed=None):
global _parser
if _parser is not None:
warnings.warn(
- 'You are calling bonobo.parse_args() without a parser argument, but it looks like you created a parser before. You probably want to pass your parser to this call, or if creating a new parser here is really what you want to do, please create a new one explicitely to silence this warning.'
+ "You are calling bonobo.parse_args() without a parser argument, but it looks like you created a parser before. You probably want to pass your parser to this call, or if creating a new parser here is really what you want to do, please create a new one explicitely to silence this warning."
)
# use the api from bonobo namespace, in case a command patched it.
import bonobo
+
mixed = bonobo.get_argument_parser()
if isinstance(mixed, argparse.ArgumentParser):
@@ -117,14 +118,14 @@ def parse_args(mixed=None):
# env-file sets something.)
try:
# Set default environment
- for name, value in map(parse_var, options.pop('default_env', []) or []):
+ for name, value in map(parse_var, options.pop("default_env", []) or []):
if not name in os.environ:
if not name in _backup:
_backup[name] = os.environ.get(name, None)
os.environ[name] = value
# Read and set default environment from file(s)
- for filename in options.pop('default_env_file', []) or []:
+ for filename in options.pop("default_env_file", []) or []:
for name, value in load_env_from_file(filename):
if not name in os.environ:
if not name in _backup:
@@ -132,14 +133,14 @@ def parse_args(mixed=None):
os.environ[name] = value
# Read and set environment from file(s)
- for filename in options.pop('env_file', []) or []:
+ for filename in options.pop("env_file", []) or []:
for name, value in load_env_from_file(filename):
if not name in _backup:
_backup[name] = os.environ.get(name, None)
os.environ[name] = value
# Set environment
- for name, value in map(parse_var, options.pop('env', []) or []):
+ for name, value in map(parse_var, options.pop("env", []) or []):
if not name in _backup:
_backup[name] = os.environ.get(name, None)
os.environ[name] = value
diff --git a/bonobo/util/errors.py b/bonobo/util/errors.py
index a24ce94..a14ebdd 100644
--- a/bonobo/util/errors.py
+++ b/bonobo/util/errors.py
@@ -15,36 +15,32 @@ def sweeten_errors():
except Exception as exc:
SPACES = 2
w = term.white
- prefix = w('║' + ' ' * (SPACES - 1))
- suffix = w(' ' * (SPACES - 1) + '║')
+ prefix = w("║" + " " * (SPACES - 1))
+ suffix = w(" " * (SPACES - 1) + "║")
- pre_re = re.compile('([^`]*)`([^`]*)`([^`]*)')
+ pre_re = re.compile("([^`]*)`([^`]*)`([^`]*)")
def format_arg(arg):
- length = len(pre_re.sub('\\1\\2\\3', arg))
+ length = len(pre_re.sub("\\1\\2\\3", arg))
- arg = pre_re.sub(w('\\1') + term.bold('\\2') + w('\\3'), arg)
- arg = re.sub('^ \$ (.*)', term.lightblack(' $ ') + term.reset('\\1'), arg)
+ arg = pre_re.sub(w("\\1") + term.bold("\\2") + w("\\3"), arg)
+ arg = re.sub("^ \$ (.*)", term.lightblack(" $ ") + term.reset("\\1"), arg)
return (arg, length)
def f(*args):
- return ''.join(args)
+ return "".join(args)
term_width, term_height = term.get_size()
line_length = min(80, term_width)
for arg in exc.args:
line_length = max(min(line_length, len(arg) + 2 * SPACES), 120)
- print(f(w('╔' + '═' * (line_length - 2) + '╗')))
+ print(f(w("╔" + "═" * (line_length - 2) + "╗")))
for i, arg in enumerate(exc.args):
if i == 1:
- print(f(
- prefix,
- ' ' * (line_length - 2 * SPACES),
- suffix,
- ))
+ print(f(prefix, " " * (line_length - 2 * SPACES), suffix))
arg_formatted, arg_length = format_arg(arg)
if not i:
@@ -52,17 +48,17 @@ def sweeten_errors():
print(
f(
prefix,
- term.red_bg(term.bold(' ' + type(exc).__name__ + ' ')),
- ' ',
+ term.red_bg(term.bold(" " + type(exc).__name__ + " ")),
+ " ",
w(arg_formatted),
- ' ' * (line_length - (arg_length + 3 + len(type(exc).__name__) + 2 * SPACES)),
+ " " * (line_length - (arg_length + 3 + len(type(exc).__name__) + 2 * SPACES)),
suffix,
)
)
else:
# other lines
- print(f(prefix, arg_formatted + ' ' * (line_length - arg_length - 2 * SPACES), suffix))
+ print(f(prefix, arg_formatted + " " * (line_length - arg_length - 2 * SPACES), suffix))
- print(f(w('╚' + '═' * (line_length - 2) + '╝')))
+ print(f(w("╚" + "═" * (line_length - 2) + "╝")))
- logging.getLogger().debug('This error was caused by the following exception chain.', exc_info=exc_info())
+ logging.getLogger().debug("This error was caused by the following exception chain.", exc_info=exc_info())
diff --git a/bonobo/util/inspect.py b/bonobo/util/inspect.py
index a7f27c4..da74144 100644
--- a/bonobo/util/inspect.py
+++ b/bonobo/util/inspect.py
@@ -9,6 +9,7 @@ def isconfigurable(mixed):
:return: bool
"""
from bonobo.config.configurables import Configurable
+
return isinstance(mixed, Configurable)
@@ -32,7 +33,7 @@ def isconfigurabletype(mixed, *, strict=False):
if isinstance(mixed, PartiallyConfigured):
return True
- if hasattr(mixed, '_partial') and mixed._partial:
+ if hasattr(mixed, "_partial") and mixed._partial:
return True
return False
@@ -47,6 +48,7 @@ def isoption(mixed):
"""
from bonobo.config.options import Option
+
return isinstance(mixed, Option)
@@ -58,6 +60,7 @@ def ismethod(mixed):
:return: bool
"""
from bonobo.config.options import Method
+
return isinstance(mixed, Method)
@@ -69,6 +72,7 @@ def iscontextprocessor(x):
:return: bool
"""
from bonobo.config.processors import ContextProcessor
+
return isinstance(x, ContextProcessor)
@@ -102,15 +106,7 @@ def istuple(mixed):
return isinstance(mixed, tuple)
-ConfigurableInspection = namedtuple(
- 'ConfigurableInspection', [
- 'type',
- 'instance',
- 'options',
- 'processors',
- 'partial',
- ]
-)
+ConfigurableInspection = namedtuple("ConfigurableInspection", ["type", "instance", "options", "processors", "partial"])
ConfigurableInspection.__enter__ = lambda self: self
ConfigurableInspection.__exit__ = lambda *exc_details: None
@@ -134,17 +130,11 @@ def inspect_node(mixed, *, _partial=None):
inst, typ = None, mixed
elif isconfigurable(mixed):
inst, typ = mixed, type(mixed)
- elif hasattr(mixed, 'func'):
+ elif hasattr(mixed, "func"):
return inspect_node(mixed.func, _partial=(mixed.args, mixed.keywords))
else:
raise TypeError(
- 'Not a Configurable, nor a Configurable instance and not even a partially configured Configurable. Check your inputs.'
+ "Not a Configurable, nor a Configurable instance and not even a partially configured Configurable. Check your inputs."
)
- return ConfigurableInspection(
- typ,
- inst,
- list(typ.__options__),
- list(typ.__processors__),
- _partial,
- )
+ return ConfigurableInspection(typ, inst, list(typ.__options__), list(typ.__processors__), _partial)
diff --git a/bonobo/util/objects.py b/bonobo/util/objects.py
index f3ffa5e..847b10d 100644
--- a/bonobo/util/objects.py
+++ b/bonobo/util/objects.py
@@ -11,7 +11,7 @@ class Wrapper:
@property
def __name__(self):
- return getattr(self.wrapped, '__name__', getattr(type(self.wrapped), '__name__', repr(self.wrapped)))
+ return getattr(self.wrapped, "__name__", getattr(type(self.wrapped), "__name__", repr(self.wrapped)))
name = __name__
@@ -142,10 +142,10 @@ class ValueHolder:
return divmod(other, self._value)
def __pow__(self, other):
- return self._value**other
+ return self._value ** other
def __rpow__(self, other):
- return other**self._value
+ return other ** self._value
def __ipow__(self, other):
self._value **= other
diff --git a/bonobo/util/pkgs.py b/bonobo/util/pkgs.py
index e4de1b6..fc6ac18 100644
--- a/bonobo/util/pkgs.py
+++ b/bonobo/util/pkgs.py
@@ -4,5 +4,5 @@ from packaging.utils import canonicalize_name
bonobo_packages = {}
for p in pkg_resources.working_set:
name = canonicalize_name(p.project_name)
- if name.startswith('bonobo'):
+ if name.startswith("bonobo"):
bonobo_packages[name] = p
diff --git a/bonobo/util/resolvers.py b/bonobo/util/resolvers.py
index 5cf2738..f49acad 100644
--- a/bonobo/util/resolvers.py
+++ b/bonobo/util/resolvers.py
@@ -23,8 +23,8 @@ class _ModulesRegistry(dict):
def require(self, name):
if name not in self:
- bits = name.split('.')
- filename = os.path.join(self.pathname, *bits[:-1], bits[-1] + '.py')
+ bits = name.split(".")
+ filename = os.path.join(self.pathname, *bits[:-1], bits[-1] + ".py")
self[name] = _RequiredModule(runpy.run_path(filename, run_name=name))
return self[name]
@@ -37,7 +37,7 @@ def _parse_option(option):
:return: tuple
"""
try:
- key, val = option.split('=', 1)
+ key, val = option.split("=", 1)
except ValueError:
return option, True
@@ -75,7 +75,7 @@ def _resolve_transformations(transformations):
transformations = transformations or []
for t in transformations:
try:
- mod, attr = t.split(':', 1)
+ mod, attr = t.split(":", 1)
yield getattr(registry.require(mod), attr)
except ValueError:
yield getattr(bonobo, t)
diff --git a/bonobo/util/statistics.py b/bonobo/util/statistics.py
index dce2714..62a5075 100644
--- a/bonobo/util/statistics.py
+++ b/bonobo/util/statistics.py
@@ -10,8 +10,8 @@ class WithStatistics:
return ((name, self.statistics[name]) for name in self.statistics_names)
def get_statistics_as_string(self, *args, **kwargs):
- stats = tuple('{0}={1}'.format(name, cnt) for name, cnt in self.get_statistics(*args, **kwargs) if cnt > 0)
- return (kwargs.get('prefix', '') + ' '.join(stats)) if len(stats) else ''
+ stats = tuple("{0}={1}".format(name, cnt) for name, cnt in self.get_statistics(*args, **kwargs) if cnt > 0)
+ return (kwargs.get("prefix", "") + " ".join(stats)) if len(stats) else ""
def increment(self, name, *, amount=1):
self.statistics[name] += amount
@@ -35,4 +35,4 @@ class Timer:
return self.__finish - self.__start
def __str__(self):
- return str(int(self.duration * 1000) / 1000.0) + 's'
+ return str(int(self.duration * 1000) / 1000.0) + "s"
diff --git a/bonobo/util/term.py b/bonobo/util/term.py
index 2fa02ce..389f02f 100644
--- a/bonobo/util/term.py
+++ b/bonobo/util/term.py
@@ -1,2 +1,2 @@
-CLEAR_EOL = '\033[0K'
-MOVE_CURSOR_UP = lambda n: '\033[{}A'.format(n)
+CLEAR_EOL = "\033[0K"
+MOVE_CURSOR_UP = lambda n: "\033[{}A".format(n)
diff --git a/bonobo/util/testing.py b/bonobo/util/testing.py
index f7b5108..13554f8 100644
--- a/bonobo/util/testing.py
+++ b/bonobo/util/testing.py
@@ -26,20 +26,20 @@ def optional_contextmanager(cm, *, ignore=False):
class FilesystemTester:
- def __init__(self, extension='txt', mode='w', *, input_data=''):
+ def __init__(self, extension="txt", mode="w", *, input_data=""):
self.extension = extension
self.input_data = input_data
self.mode = mode
def get_services_for_reader(self, tmpdir):
- fs, filename = open_fs(tmpdir), 'input.' + self.extension
+ fs, filename = open_fs(tmpdir), "input." + self.extension
with fs.open(filename, self.mode) as fp:
fp.write(self.input_data)
- return fs, filename, {'fs': fs}
+ return fs, filename, {"fs": fs}
def get_services_for_writer(self, tmpdir):
- fs, filename = open_fs(tmpdir), 'output.' + self.extension
- return fs, filename, {'fs': fs}
+ fs, filename = open_fs(tmpdir), "output." + self.extension
+ return fs, filename, {"fs": fs}
class QueueList(list):
@@ -60,7 +60,7 @@ class BufferingContext:
return self.buffer
def get_buffer_args_as_dicts(self):
- return [row._asdict() if hasattr(row, '_asdict') else dict(row) for row in self.buffer]
+ return [row._asdict() if hasattr(row, "_asdict") else dict(row) for row in self.buffer]
class BufferingNodeExecutionContext(BufferingContext, NodeExecutionContext):
@@ -106,43 +106,37 @@ def runner_entrypoint(args):
@runner
def runner_module(args):
""" Run bonobo using the bonobo.__main__ file, which is equivalent as doing "python -m bonobo ..."."""
- with patch.object(sys, 'argv', ['bonobo', *args]):
- return runpy.run_path(__main__.__file__, run_name='__main__')
+ with patch.object(sys, "argv", ["bonobo", *args]):
+ return runpy.run_path(__main__.__file__, run_name="__main__")
-all_runners = pytest.mark.parametrize('runner', [runner_entrypoint, runner_module])
+all_runners = pytest.mark.parametrize("runner", [runner_entrypoint, runner_module])
all_environ_targets = pytest.mark.parametrize(
- 'target', [
- (get_examples_path('environ.py'), ),
- (
- '-m',
- 'bonobo.examples.environ',
- ),
- ]
+ "target", [(get_examples_path("environ.py"),), ("-m", "bonobo.examples.environ")]
)
@all_runners
@all_environ_targets
-class EnvironmentTestCase():
+class EnvironmentTestCase:
def run_quiet(self, runner, *args):
- return runner('run', '--quiet', *args)
+ return runner("run", "--quiet", *args)
def run_environ(self, runner, *args, environ=None):
- _environ = {'PATH': '/usr/bin'}
+ _environ = {"PATH": "/usr/bin"}
if environ:
_environ.update(environ)
- with patch.dict('os.environ', _environ, clear=True):
+ with patch.dict("os.environ", _environ, clear=True):
out, err = self.run_quiet(runner, *args)
- assert 'SECRET' not in os.environ
- assert 'PASSWORD' not in os.environ
- if 'PATH' in _environ:
- assert 'PATH' in os.environ
- assert os.environ['PATH'] == _environ['PATH']
+ assert "SECRET" not in os.environ
+ assert "PASSWORD" not in os.environ
+ if "PATH" in _environ:
+ assert "PATH" in os.environ
+ assert os.environ["PATH"] == _environ["PATH"]
- assert err == ''
- return dict(map(lambda line: line.split(' ', 1), filter(None, out.split('\n'))))
+ assert err == ""
+ return dict(map(lambda line: line.split(" ", 1), filter(None, out.split("\n"))))
class StaticNodeTest:
@@ -202,8 +196,8 @@ class ReaderTest(ConfigurableNodeTest):
ReaderNodeType = None
- extension = 'txt'
- input_data = ''
+ extension = "txt"
+ input_data = ""
@property
def NodeType(self):
@@ -216,12 +210,12 @@ class ReaderTest(ConfigurableNodeTest):
self.tmpdir = tmpdir
def get_create_args(self, *args):
- return (self.filename, ) + args
+ return (self.filename,) + args
def test_customizable_output_type_transform_not_a_type(self):
context = self.NodeExecutionContextType(
self.create(*self.get_create_args(), output_type=str.upper, **self.get_create_kwargs()),
- services=self.services
+ services=self.services,
)
with pytest.raises(TypeError):
context.start()
@@ -229,9 +223,9 @@ class ReaderTest(ConfigurableNodeTest):
def test_customizable_output_type_transform_not_a_tuple(self):
context = self.NodeExecutionContextType(
self.create(
- *self.get_create_args(), output_type=type('UpperString', (str, ), {}), **self.get_create_kwargs()
+ *self.get_create_args(), output_type=type("UpperString", (str,), {}), **self.get_create_kwargs()
),
- services=self.services
+ services=self.services,
)
with pytest.raises(TypeError):
context.start()
@@ -242,8 +236,8 @@ class WriterTest(ConfigurableNodeTest):
WriterNodeType = None
- extension = 'txt'
- input_data = ''
+ extension = "txt"
+ input_data = ""
@property
def NodeType(self):
@@ -256,7 +250,7 @@ class WriterTest(ConfigurableNodeTest):
self.tmpdir = tmpdir
def get_create_args(self, *args):
- return (self.filename, ) + args
+ return (self.filename,) + args
def readlines(self):
with self.fs.open(self.filename) as fp:
diff --git a/tests/commands/test_clibasics.py b/tests/commands/test_clibasics.py
index 1fc292b..780af9c 100644
--- a/tests/commands/test_clibasics.py
+++ b/tests/commands/test_clibasics.py
@@ -6,20 +6,14 @@ from bonobo.util.testing import all_runners
def test_entrypoint():
commands = {}
- for command in pkg_resources.iter_entry_points('bonobo.commands'):
+ for command in pkg_resources.iter_entry_points("bonobo.commands"):
commands[command.name] = command
- assert not {
- 'convert',
- 'init',
- 'inspect',
- 'run',
- 'version',
- }.difference(set(commands))
+ assert not {"convert", "init", "inspect", "run", "version"}.difference(set(commands))
@all_runners
def test_no_command(runner):
_, err, exc = runner(catch_errors=True)
assert type(exc) == SystemExit
- assert 'error: the following arguments are required: command' in err
\ No newline at end of file
+ assert "error: the following arguments are required: command" in err
diff --git a/tests/commands/test_convert.py b/tests/commands/test_convert.py
index d61d8c5..d6c2f96 100644
--- a/tests/commands/test_convert.py
+++ b/tests/commands/test_convert.py
@@ -8,10 +8,10 @@ from bonobo.util.testing import all_runners
@all_runners
def test_convert(runner, tmpdir):
- csv_content = 'id;name\n1;Romain'
- tmpdir.join('in.csv').write(csv_content)
+ csv_content = "id;name\n1;Romain"
+ tmpdir.join("in.csv").write(csv_content)
with change_working_directory(tmpdir):
- runner('convert', 'in.csv', 'out.csv')
+ runner("convert", "in.csv", "out.csv")
- assert tmpdir.join('out.csv').read().strip() == csv_content
+ assert tmpdir.join("out.csv").read().strip() == csv_content
diff --git a/tests/commands/test_download.py b/tests/commands/test_download.py
index 83b0ef4..2591c30 100644
--- a/tests/commands/test_download.py
+++ b/tests/commands/test_download.py
@@ -9,7 +9,7 @@ from bonobo.util.testing import all_runners
@all_runners
def test_download_works_for_examples(runner):
- expected_bytes = b'hello world'
+ expected_bytes = b"hello world"
class MockResponse(object):
def __init__(self):
@@ -27,12 +27,13 @@ def test_download_works_for_examples(runner):
fout = io.BytesIO()
fout.close = lambda: None
- with patch('bonobo.commands.download._open_url') as mock_open_url, \
- patch('bonobo.commands.download.open') as mock_open:
+ with patch("bonobo.commands.download._open_url") as mock_open_url, patch(
+ "bonobo.commands.download.open"
+ ) as mock_open:
mock_open_url.return_value = MockResponse()
mock_open.return_value = fout
- runner('download', 'examples/datasets/coffeeshops.txt')
- expected_url = EXAMPLES_BASE_URL + 'datasets/coffeeshops.txt'
+ runner("download", "examples/datasets/coffeeshops.txt")
+ expected_url = EXAMPLES_BASE_URL + "datasets/coffeeshops.txt"
mock_open_url.assert_called_once_with(expected_url)
assert fout.getvalue() == expected_bytes
@@ -41,4 +42,4 @@ def test_download_works_for_examples(runner):
@all_runners
def test_download_fails_non_example(runner):
with pytest.raises(ValueError):
- runner('download', 'something/entirely/different.txt')
\ No newline at end of file
+ runner("download", "something/entirely/different.txt")
diff --git a/tests/commands/test_init.py b/tests/commands/test_init.py
index 626f5e8..c7f95d2 100644
--- a/tests/commands/test_init.py
+++ b/tests/commands/test_init.py
@@ -8,22 +8,22 @@ from bonobo.util.testing import all_runners
@all_runners
def test_init_file(runner, tmpdir):
- target = tmpdir.join('foo.py')
+ target = tmpdir.join("foo.py")
target_filename = str(target)
- runner('init', target_filename)
+ runner("init", target_filename)
assert os.path.exists(target_filename)
- out, err = runner('run', target_filename)
- assert out.replace('\n', ' ').strip() == 'Hello World'
+ out, err = runner("run", target_filename)
+ assert out.replace("\n", " ").strip() == "Hello World"
assert not err
@all_runners
-@pytest.mark.parametrize('template', InitCommand.TEMPLATES)
+@pytest.mark.parametrize("template", InitCommand.TEMPLATES)
def test_init_file_templates(runner, template, tmpdir):
- target = tmpdir.join('foo.py')
+ target = tmpdir.join("foo.py")
target_filename = str(target)
- runner('init', target_filename)
+ runner("init", target_filename)
assert os.path.exists(target_filename)
- out, err = runner('run', target_filename)
+ out, err = runner("run", target_filename)
assert not err
diff --git a/tests/commands/test_run.py b/tests/commands/test_run.py
index 69e4f94..da6666a 100644
--- a/tests/commands/test_run.py
+++ b/tests/commands/test_run.py
@@ -7,42 +7,42 @@ from bonobo.util.testing import all_runners
@all_runners
def test_run(runner):
- out, err = runner('run', '--quiet', get_examples_path('types/strings.py'))
- out = out.split('\n')
- assert out[0].startswith('Foo ')
- assert out[1].startswith('Bar ')
- assert out[2].startswith('Baz ')
+ out, err = runner("run", "--quiet", get_examples_path("types/strings.py"))
+ out = out.split("\n")
+ assert out[0].startswith("Foo ")
+ assert out[1].startswith("Bar ")
+ assert out[2].startswith("Baz ")
@all_runners
def test_run_module(runner):
- out, err = runner('run', '--quiet', '-m', 'bonobo.examples.types.strings')
- out = out.split('\n')
- assert out[0].startswith('Foo ')
- assert out[1].startswith('Bar ')
- assert out[2].startswith('Baz ')
+ out, err = runner("run", "--quiet", "-m", "bonobo.examples.types.strings")
+ out = out.split("\n")
+ assert out[0].startswith("Foo ")
+ assert out[1].startswith("Bar ")
+ assert out[2].startswith("Baz ")
@all_runners
def test_run_path(runner):
- out, err = runner('run', '--quiet', get_examples_path('types'))
- out = out.split('\n')
- assert out[0].startswith('Foo ')
- assert out[1].startswith('Bar ')
- assert out[2].startswith('Baz ')
+ out, err = runner("run", "--quiet", get_examples_path("types"))
+ out = out.split("\n")
+ assert out[0].startswith("Foo ")
+ assert out[1].startswith("Bar ")
+ assert out[2].startswith("Baz ")
@all_runners
def test_install_requirements_for_dir(runner):
- dirname = get_examples_path('types')
- with patch('bonobo.commands.run._install_requirements') as install_mock:
- runner('run', '--install', dirname)
- install_mock.assert_called_once_with(os.path.join(dirname, 'requirements.txt'))
+ dirname = get_examples_path("types")
+ with patch("bonobo.commands.run._install_requirements") as install_mock:
+ runner("run", "--install", dirname)
+ install_mock.assert_called_once_with(os.path.join(dirname, "requirements.txt"))
@all_runners
def test_install_requirements_for_file(runner):
- dirname = get_examples_path('types')
- with patch('bonobo.commands.run._install_requirements') as install_mock:
- runner('run', '--install', os.path.join(dirname, 'strings.py'))
- install_mock.assert_called_once_with(os.path.join(dirname, 'requirements.txt'))
+ dirname = get_examples_path("types")
+ with patch("bonobo.commands.run._install_requirements") as install_mock:
+ runner("run", "--install", os.path.join(dirname, "strings.py"))
+ install_mock.assert_called_once_with(os.path.join(dirname, "requirements.txt"))
diff --git a/tests/commands/test_run_environ.py b/tests/commands/test_run_environ.py
index 3fee6e1..a7ae113 100644
--- a/tests/commands/test_run_environ.py
+++ b/tests/commands/test_run_environ.py
@@ -5,103 +5,104 @@ from bonobo.util.testing import EnvironmentTestCase
@pytest.fixture
def env1(tmpdir):
- env_file = tmpdir.join('.env_one')
- env_file.write('\n'.join((
- 'SECRET=unknown',
- 'PASSWORD=sweet',
- 'PATH=first',
- )))
+ env_file = tmpdir.join(".env_one")
+ env_file.write("\n".join(("SECRET=unknown", "PASSWORD=sweet", "PATH=first")))
return str(env_file)
@pytest.fixture
def env2(tmpdir):
- env_file = tmpdir.join('.env_two')
- env_file.write('\n'.join((
- 'PASSWORD=bitter',
- "PATH='second'",
- )))
+ env_file = tmpdir.join(".env_two")
+ env_file.write("\n".join(("PASSWORD=bitter", "PATH='second'")))
return str(env_file)
class TestDefaultEnvFile(EnvironmentTestCase):
def test_run_with_default_env_file(self, runner, target, env1):
- env = self.run_environ(runner, *target, '--default-env-file', env1)
- assert env.get('SECRET') == 'unknown'
- assert env.get('PASSWORD') == 'sweet'
- assert env.get('PATH') == '/usr/bin'
+ env = self.run_environ(runner, *target, "--default-env-file", env1)
+ assert env.get("SECRET") == "unknown"
+ assert env.get("PASSWORD") == "sweet"
+ assert env.get("PATH") == "/usr/bin"
def test_run_with_multiple_default_env_files(self, runner, target, env1, env2):
- env = self.run_environ(runner, *target, '--default-env-file', env1, '--default-env-file', env2)
- assert env.get('SECRET') == 'unknown'
- assert env.get('PASSWORD') == 'sweet'
- assert env.get('PATH') == '/usr/bin'
+ env = self.run_environ(runner, *target, "--default-env-file", env1, "--default-env-file", env2)
+ assert env.get("SECRET") == "unknown"
+ assert env.get("PASSWORD") == "sweet"
+ assert env.get("PATH") == "/usr/bin"
- env = self.run_environ(runner, *target, '--default-env-file', env2, '--default-env-file', env1)
- assert env.get('SECRET') == 'unknown'
- assert env.get('PASSWORD') == 'bitter'
- assert env.get('PATH') == '/usr/bin'
+ env = self.run_environ(runner, *target, "--default-env-file", env2, "--default-env-file", env1)
+ assert env.get("SECRET") == "unknown"
+ assert env.get("PASSWORD") == "bitter"
+ assert env.get("PATH") == "/usr/bin"
class TestEnvFile(EnvironmentTestCase):
def test_run_with_file(self, runner, target, env1):
- env = self.run_environ(runner, *target, '--env-file', env1)
- assert env.get('SECRET') == 'unknown'
- assert env.get('PASSWORD') == 'sweet'
- assert env.get('PATH') == 'first'
+ env = self.run_environ(runner, *target, "--env-file", env1)
+ assert env.get("SECRET") == "unknown"
+ assert env.get("PASSWORD") == "sweet"
+ assert env.get("PATH") == "first"
def test_run_with_multiple_files(self, runner, target, env1, env2):
- env = self.run_environ(runner, *target, '--env-file', env1, '--env-file', env2)
- assert env.get('SECRET') == 'unknown'
- assert env.get('PASSWORD') == 'bitter'
- assert env.get('PATH') == 'second'
+ env = self.run_environ(runner, *target, "--env-file", env1, "--env-file", env2)
+ assert env.get("SECRET") == "unknown"
+ assert env.get("PASSWORD") == "bitter"
+ assert env.get("PATH") == "second"
- env = self.run_environ(runner, *target, '--env-file', env2, '--env-file', env1)
- assert env.get('SECRET') == 'unknown'
- assert env.get('PASSWORD') == 'sweet'
- assert env.get('PATH') == 'first'
+ env = self.run_environ(runner, *target, "--env-file", env2, "--env-file", env1)
+ assert env.get("SECRET") == "unknown"
+ assert env.get("PASSWORD") == "sweet"
+ assert env.get("PATH") == "first"
class TestEnvFileCombinations(EnvironmentTestCase):
def test_run_with_both_env_files(self, runner, target, env1, env2):
- env = self.run_environ(runner, *target, '--default-env-file', env1, '--env-file', env2)
- assert env.get('SECRET') == 'unknown'
- assert env.get('PASSWORD') == 'bitter'
- assert env.get('PATH') == 'second'
+ env = self.run_environ(runner, *target, "--default-env-file", env1, "--env-file", env2)
+ assert env.get("SECRET") == "unknown"
+ assert env.get("PASSWORD") == "bitter"
+ assert env.get("PATH") == "second"
def test_run_with_both_env_files_then_overrides(self, runner, target, env1, env2):
env = self.run_environ(
- runner, *target, '--default-env-file', env1, '--env-file', env2, '--env', 'PASSWORD=mine', '--env',
- 'SECRET=s3cr3t'
+ runner,
+ *target,
+ "--default-env-file",
+ env1,
+ "--env-file",
+ env2,
+ "--env",
+ "PASSWORD=mine",
+ "--env",
+ "SECRET=s3cr3t"
)
- assert env.get('SECRET') == 's3cr3t'
- assert env.get('PASSWORD') == 'mine'
- assert env.get('PATH') == 'second'
+ assert env.get("SECRET") == "s3cr3t"
+ assert env.get("PASSWORD") == "mine"
+ assert env.get("PATH") == "second"
class TestEnvVars(EnvironmentTestCase):
def test_run_no_env(self, runner, target):
- env = self.run_environ(runner, *target, environ={'USER': 'romain'})
- assert env.get('USER') == 'romain'
+ env = self.run_environ(runner, *target, environ={"USER": "romain"})
+ assert env.get("USER") == "romain"
def test_run_env(self, runner, target):
- env = self.run_environ(runner, *target, '--env', 'USER=serious', environ={'USER': 'romain'})
- assert env.get('USER') == 'serious'
+ env = self.run_environ(runner, *target, "--env", "USER=serious", environ={"USER": "romain"})
+ assert env.get("USER") == "serious"
def test_run_env_mixed(self, runner, target):
- env = self.run_environ(runner, *target, '--env', 'ONE=1', '--env', 'TWO="2"', environ={'USER': 'romain'})
- assert env.get('USER') == 'romain'
- assert env.get('ONE') == '1'
- assert env.get('TWO') == '2'
+ env = self.run_environ(runner, *target, "--env", "ONE=1", "--env", 'TWO="2"', environ={"USER": "romain"})
+ assert env.get("USER") == "romain"
+ assert env.get("ONE") == "1"
+ assert env.get("TWO") == "2"
def test_run_default_env(self, runner, target):
- env = self.run_environ(runner, *target, '--default-env', 'USER=clown')
- assert env.get('USER') == 'clown'
+ env = self.run_environ(runner, *target, "--default-env", "USER=clown")
+ assert env.get("USER") == "clown"
- env = self.run_environ(runner, *target, '--default-env', 'USER=clown', environ={'USER': 'romain'})
- assert env.get('USER') == 'romain'
+ env = self.run_environ(runner, *target, "--default-env", "USER=clown", environ={"USER": "romain"})
+ assert env.get("USER") == "romain"
env = self.run_environ(
- runner, *target, '--env', 'USER=serious', '--default-env', 'USER=clown', environ={'USER': 'romain'}
+ runner, *target, "--env", "USER=serious", "--default-env", "USER=clown", environ={"USER": "romain"}
)
- assert env.get('USER') == 'serious'
+ assert env.get("USER") == "serious"
diff --git a/tests/commands/test_version.py b/tests/commands/test_version.py
index 1ee893f..35acae5 100644
--- a/tests/commands/test_version.py
+++ b/tests/commands/test_version.py
@@ -4,17 +4,17 @@ from bonobo.util.testing import all_runners
@all_runners
def test_version(runner):
- out, err = runner('version')
+ out, err = runner("version")
out = out.strip()
- assert out.startswith('bonobo ')
+ assert out.startswith("bonobo ")
assert __version__ in out
- out, err = runner('version', '-q')
+ out, err = runner("version", "-q")
out = out.strip()
- assert out.startswith('bonobo ')
+ assert out.startswith("bonobo ")
assert __version__ in out
- out, err = runner('version', '-qq')
+ out, err = runner("version", "-qq")
out = out.strip()
- assert not out.startswith('bonobo ')
- assert __version__ in out
\ No newline at end of file
+ assert not out.startswith("bonobo ")
+ assert __version__ in out
diff --git a/tests/config/test_configurables.py b/tests/config/test_configurables.py
index bee501e..ef6a1f1 100644
--- a/tests/config/test_configurables.py
+++ b/tests/config/test_configurables.py
@@ -11,7 +11,7 @@ class NoOptConfigurable(Configurable):
class MyConfigurable(Configurable):
required_str = Option(str)
- default_str = Option(str, default='foo')
+ default_str = Option(str, default="foo")
integer = Option(int, required=False)
@@ -20,7 +20,7 @@ class MyHarderConfigurable(MyConfigurable):
class MyBetterConfigurable(MyConfigurable):
- required_str = Option(str, required=False, default='kaboom')
+ required_str = Option(str, required=False, default="kaboom")
class MyConfigurableUsingPositionalOptions(MyConfigurable):
@@ -35,7 +35,7 @@ def test_missing_required_option_error():
with pytest.raises(TypeError) as exc:
MyConfigurable(_final=True)
- assert exc.match('missing 1 required option:')
+ assert exc.match("missing 1 required option:")
def test_missing_required_options_error():
@@ -44,29 +44,29 @@ def test_missing_required_options_error():
with pytest.raises(TypeError) as exc:
MyHarderConfigurable(_final=True)
- assert exc.match('missing 2 required options:')
+ assert exc.match("missing 2 required options:")
def test_extraneous_option_error():
with pytest.raises(TypeError) as exc:
- MyConfigurable(required_str='foo', hello='world')
- assert exc.match('got 1 unexpected option:')
+ MyConfigurable(required_str="foo", hello="world")
+ assert exc.match("got 1 unexpected option:")
def test_extraneous_options_error():
with pytest.raises(TypeError) as exc:
- MyConfigurable(required_str='foo', hello='world', acme='corp')
- assert exc.match('got 2 unexpected options:')
+ MyConfigurable(required_str="foo", hello="world", acme="corp")
+ assert exc.match("got 2 unexpected options:")
def test_defaults():
- o = MyConfigurable(required_str='hello')
+ o = MyConfigurable(required_str="hello")
with inspect_node(o) as ni:
assert not ni.partial
- assert o.required_str == 'hello'
- assert o.default_str == 'foo'
+ assert o.required_str == "hello"
+ assert o.default_str == "foo"
assert o.integer is None
@@ -76,30 +76,30 @@ def test_str_type_factory():
with inspect_node(o) as ni:
assert not ni.partial
- assert o.required_str == '42'
- assert o.default_str == 'foo'
+ assert o.required_str == "42"
+ assert o.default_str == "foo"
assert o.integer is None
def test_int_type_factory():
- o = MyConfigurable(required_str='yo', default_str='bar', integer='42')
+ o = MyConfigurable(required_str="yo", default_str="bar", integer="42")
with inspect_node(o) as ni:
assert not ni.partial
- assert o.required_str == 'yo'
- assert o.default_str == 'bar'
+ assert o.required_str == "yo"
+ assert o.default_str == "bar"
assert o.integer == 42
def test_bool_type_factory():
- o = MyHarderConfigurable(required_str='yes', also_required='True')
+ o = MyHarderConfigurable(required_str="yes", also_required="True")
with inspect_node(o) as ni:
assert not ni.partial
- assert o.required_str == 'yes'
- assert o.default_str == 'foo'
+ assert o.required_str == "yes"
+ assert o.default_str == "foo"
assert o.integer is None
assert o.also_required is True
@@ -110,22 +110,22 @@ def test_option_resolution_order():
with inspect_node(o) as ni:
assert not ni.partial
- assert o.required_str == 'kaboom'
- assert o.default_str == 'foo'
+ assert o.required_str == "kaboom"
+ assert o.default_str == "foo"
assert o.integer is None
def test_option_positional():
- o = MyConfigurableUsingPositionalOptions('1', '2', '3', required_str='hello')
+ o = MyConfigurableUsingPositionalOptions("1", "2", "3", required_str="hello")
with inspect_node(o) as ni:
assert not ni.partial
- assert o.first == '1'
- assert o.second == '2'
- assert o.third == '3'
- assert o.required_str == 'hello'
- assert o.default_str == 'foo'
+ assert o.first == "1"
+ assert o.second == "2"
+ assert o.third == "3"
+ assert o.required_str == "hello"
+ assert o.default_str == "foo"
assert o.integer is None
diff --git a/tests/config/test_methods.py b/tests/config/test_methods.py
index b5c3a45..9e87c15 100644
--- a/tests/config/test_methods.py
+++ b/tests/config/test_methods.py
@@ -50,10 +50,7 @@ def test_define_with_decorator():
calls = []
def my_handler(*args, **kwargs):
- calls.append((
- args,
- kwargs,
- ))
+ calls.append((args, kwargs))
Concrete = MethodBasedConfigurable(my_handler)
@@ -64,7 +61,7 @@ def test_define_with_decorator():
assert ci.type == MethodBasedConfigurable
assert ci.partial
- t = Concrete('foo', bar='baz')
+ t = Concrete("foo", bar="baz")
assert callable(t.handler)
assert len(calls) == 0
@@ -75,15 +72,12 @@ def test_define_with_decorator():
def test_late_binding_method_decoration():
calls = []
- @MethodBasedConfigurable(foo='foo')
+ @MethodBasedConfigurable(foo="foo")
def Concrete(*args, **kwargs):
- calls.append((
- args,
- kwargs,
- ))
+ calls.append((args, kwargs))
assert callable(Concrete.handler)
- t = Concrete(bar='baz')
+ t = Concrete(bar="baz")
assert callable(t.handler)
assert len(calls) == 0
@@ -95,12 +89,9 @@ def test_define_with_argument():
calls = []
def concrete_handler(*args, **kwargs):
- calls.append((
- args,
- kwargs,
- ))
+ calls.append((args, kwargs))
- t = MethodBasedConfigurable(concrete_handler, 'foo', bar='baz')
+ t = MethodBasedConfigurable(concrete_handler, "foo", bar="baz")
assert callable(t.handler)
assert len(calls) == 0
t()
@@ -112,12 +103,9 @@ def test_define_with_inheritance():
class Inheriting(MethodBasedConfigurable):
def handler(self, *args, **kwargs):
- calls.append((
- args,
- kwargs,
- ))
+ calls.append((args, kwargs))
- t = Inheriting('foo', bar='baz')
+ t = Inheriting("foo", bar="baz")
assert callable(t.handler)
assert len(calls) == 0
t()
@@ -132,13 +120,10 @@ def test_inheritance_then_decorate():
@Inheriting
def Concrete(*args, **kwargs):
- calls.append((
- args,
- kwargs,
- ))
+ calls.append((args, kwargs))
assert callable(Concrete.handler)
- t = Concrete('foo', bar='baz')
+ t = Concrete("foo", bar="baz")
assert callable(t.handler)
assert len(calls) == 0
t()
diff --git a/tests/config/test_methods_partial.py b/tests/config/test_methods_partial.py
index e45f11d..d9d6e35 100644
--- a/tests/config/test_methods_partial.py
+++ b/tests/config/test_methods_partial.py
@@ -12,11 +12,11 @@ class Bobby(Configurable):
@ContextProcessor
def think(self, context):
- yield 'different'
+ yield "different"
def __call__(self, think, *args, **kwargs):
- self.handler('1', *args, **kwargs)
- self.handler2('2', *args, **kwargs)
+ self.handler("1", *args, **kwargs)
+ self.handler2("2", *args, **kwargs)
def test_partial():
@@ -40,7 +40,7 @@ def test_partial():
assert len(ci.options) == 4
assert len(ci.processors) == 1
assert ci.partial
- assert ci.partial[0] == (f1, )
+ assert ci.partial[0] == (f1,)
assert not len(ci.partial[1])
# instanciate a more complete partial instance ...
@@ -53,13 +53,10 @@ def test_partial():
assert len(ci.options) == 4
assert len(ci.processors) == 1
assert ci.partial
- assert ci.partial[0] == (
- f1,
- f2,
- )
+ assert ci.partial[0] == (f1, f2)
assert not len(ci.partial[1])
- c = C('foo')
+ c = C("foo")
with inspect_node(c) as ci:
assert ci.type == Bobby
diff --git a/tests/config/test_processors.py b/tests/config/test_processors.py
index c6b3c9a..0417ada 100644
--- a/tests/config/test_processors.py
+++ b/tests/config/test_processors.py
@@ -1,7 +1,7 @@
from operator import attrgetter
from bonobo.config import Configurable
-from bonobo.config.processors import ContextProcessor, resolve_processors, ContextCurrifier, use_context_processor
+from bonobo.config.processors import ContextCurrifier, ContextProcessor, resolve_processors, use_context_processor
class CP1(Configurable):
@@ -11,11 +11,11 @@ class CP1(Configurable):
@ContextProcessor
def a(self):
- yield 'this is A'
+ yield "this is A"
@ContextProcessor
def b(self, a):
- yield a.upper()[:-1] + 'b'
+ yield a.upper()[:-1] + "b"
def __call__(self, a, b):
return a, b
@@ -46,20 +46,20 @@ class CP3(CP2):
def get_all_processors_names(cls):
- return list(map(attrgetter('__name__'), resolve_processors(cls)))
+ return list(map(attrgetter("__name__"), resolve_processors(cls)))
def test_inheritance_and_ordering():
- assert get_all_processors_names(CP1) == ['c', 'a', 'b']
- assert get_all_processors_names(CP2) == ['c', 'a', 'b', 'f', 'e', 'd']
- assert get_all_processors_names(CP3) == ['c', 'a', 'b', 'f', 'e', 'd', 'c', 'b']
+ assert get_all_processors_names(CP1) == ["c", "a", "b"]
+ assert get_all_processors_names(CP2) == ["c", "a", "b", "f", "e", "d"]
+ assert get_all_processors_names(CP3) == ["c", "a", "b", "f", "e", "d", "c", "b"]
def test_setup_teardown():
o = CP1()
stack = ContextCurrifier(o)
stack.setup()
- assert o(*stack.args) == ('this is A', 'THIS IS b')
+ assert o(*stack.args) == ("this is A", "THIS IS b")
stack.teardown()
@@ -71,4 +71,4 @@ def test_processors_on_func():
def node(context):
pass
- assert get_all_processors_names(node) == ['cp']
+ assert get_all_processors_names(node) == ["cp"]
diff --git a/tests/config/test_services.py b/tests/config/test_services.py
index 078832c..ffb815b 100644
--- a/tests/config/test_services.py
+++ b/tests/config/test_services.py
@@ -4,11 +4,11 @@ import time
import pytest
from bonobo.config import Configurable, Container, Exclusive, Service, use
-from bonobo.config.services import validate_service_name, create_container
+from bonobo.config.services import create_container, validate_service_name
from bonobo.util import get_name
-class PrinterInterface():
+class PrinterInterface:
def print(self, *args):
raise NotImplementedError()
@@ -18,46 +18,43 @@ class ConcretePrinter(PrinterInterface):
self.prefix = prefix
def print(self, *args):
- return ';'.join((self.prefix, *args))
+ return ";".join((self.prefix, *args))
-SERVICES = Container(
- printer0=ConcretePrinter(prefix='0'),
- printer1=ConcretePrinter(prefix='1'),
-)
+SERVICES = Container(printer0=ConcretePrinter(prefix="0"), printer1=ConcretePrinter(prefix="1"))
class MyServiceDependantConfigurable(Configurable):
- printer = Service(PrinterInterface, )
+ printer = Service(PrinterInterface)
def __call__(self, *args, printer: PrinterInterface):
return printer.print(*args)
def test_service_name_validator():
- assert validate_service_name('foo') == 'foo'
- assert validate_service_name('foo.bar') == 'foo.bar'
- assert validate_service_name('Foo') == 'Foo'
- assert validate_service_name('Foo.Bar') == 'Foo.Bar'
- assert validate_service_name('Foo.a0') == 'Foo.a0'
+ assert validate_service_name("foo") == "foo"
+ assert validate_service_name("foo.bar") == "foo.bar"
+ assert validate_service_name("Foo") == "Foo"
+ assert validate_service_name("Foo.Bar") == "Foo.Bar"
+ assert validate_service_name("Foo.a0") == "Foo.a0"
with pytest.raises(ValueError):
- validate_service_name('foo.0')
+ validate_service_name("foo.0")
with pytest.raises(ValueError):
- validate_service_name('0.foo')
+ validate_service_name("0.foo")
def test_service_dependency():
- o = MyServiceDependantConfigurable(printer='printer0')
+ o = MyServiceDependantConfigurable(printer="printer0")
- assert o('foo', 'bar', printer=SERVICES.get('printer0')) == '0;foo;bar'
- assert o('bar', 'baz', printer=SERVICES.get('printer1')) == '1;bar;baz'
- assert o('foo', 'bar', **SERVICES.kwargs_for(o)) == '0;foo;bar'
+ assert o("foo", "bar", printer=SERVICES.get("printer0")) == "0;foo;bar"
+ assert o("bar", "baz", printer=SERVICES.get("printer1")) == "1;bar;baz"
+ assert o("foo", "bar", **SERVICES.kwargs_for(o)) == "0;foo;bar"
def test_service_dependency_unavailable():
- o = MyServiceDependantConfigurable(printer='printer2')
+ o = MyServiceDependantConfigurable(printer="printer2")
with pytest.raises(KeyError):
SERVICES.kwargs_for(o)
@@ -72,15 +69,15 @@ class VCR:
def test_exclusive():
vcr = VCR()
- vcr.append('hello')
+ vcr.append("hello")
def record(prefix, vcr=vcr):
with Exclusive(vcr):
for i in range(5):
- vcr.append(' '.join((prefix, str(i))))
+ vcr.append(" ".join((prefix, str(i))))
time.sleep(0.05)
- threads = [threading.Thread(target=record, args=(str(i), )) for i in range(5)]
+ threads = [threading.Thread(target=record, args=(str(i),)) for i in range(5)]
for thread in threads:
thread.start()
@@ -90,8 +87,32 @@ def test_exclusive():
thread.join()
assert vcr.tape == [
- 'hello', '0 0', '0 1', '0 2', '0 3', '0 4', '1 0', '1 1', '1 2', '1 3', '1 4', '2 0', '2 1', '2 2', '2 3',
- '2 4', '3 0', '3 1', '3 2', '3 3', '3 4', '4 0', '4 1', '4 2', '4 3', '4 4'
+ "hello",
+ "0 0",
+ "0 1",
+ "0 2",
+ "0 3",
+ "0 4",
+ "1 0",
+ "1 1",
+ "1 2",
+ "1 3",
+ "1 4",
+ "2 0",
+ "2 1",
+ "2 2",
+ "2 3",
+ "2 4",
+ "3 0",
+ "3 1",
+ "3 2",
+ "3 3",
+ "3 4",
+ "4 0",
+ "4 1",
+ "4 2",
+ "4 3",
+ "4 4",
]
@@ -100,28 +121,25 @@ def test_requires():
services = Container(output=vcr.append)
- @use('output')
+ @use("output")
def append(out, x):
out(x)
svcargs = services.kwargs_for(append)
assert len(svcargs) == 1
- assert svcargs['output'] == vcr.append
+ assert svcargs["output"] == vcr.append
-@pytest.mark.parametrize('services', [None, {}])
+@pytest.mark.parametrize("services", [None, {}])
def test_create_container_empty_values(services):
c = create_container(services)
assert len(c) == 2
- assert 'fs' in c and get_name(c['fs']) == 'OSFS'
- assert 'http' in c and get_name(c['http']) == 'requests'
+ assert "fs" in c and get_name(c["fs"]) == "OSFS"
+ assert "http" in c and get_name(c["http"]) == "requests"
def test_create_container_override():
- c = create_container({
- 'http': 'http',
- 'fs': 'fs',
- })
+ c = create_container({"http": "http", "fs": "fs"})
assert len(c) == 2
- assert 'fs' in c and c['fs'] == 'fs'
- assert 'http' in c and c['http'] == 'http'
+ assert "fs" in c and c["fs"] == "fs"
+ assert "http" in c and c["http"] == "http"
diff --git a/tests/examples/test_example_change_some_fields.py b/tests/examples/test_example_change_some_fields.py
index 8fd5ff0..33655c2 100644
--- a/tests/examples/test_example_change_some_fields.py
+++ b/tests/examples/test_example_change_some_fields.py
@@ -5,22 +5,22 @@ from bonobo.config import use_raw_input
from bonobo.execution.contexts import GraphExecutionContext
from bonobo.util.bags import BagType
-Extracted = namedtuple('Extracted', ['id', 'name', 'value'])
-ExtractedBT = BagType('ExtractedBT', ['id', 'name', 'value'])
+Extracted = namedtuple("Extracted", ["id", "name", "value"])
+ExtractedBT = BagType("ExtractedBT", ["id", "name", "value"])
def extract_nt():
- yield Extracted(id=1, name='Guido', value='.py')
- yield Extracted(id=2, name='Larry', value='.pl')
- yield Extracted(id=3, name='Dennis', value='.c')
- yield Extracted(id=4, name='Yukihiro', value='.rb')
+ yield Extracted(id=1, name="Guido", value=".py")
+ yield Extracted(id=2, name="Larry", value=".pl")
+ yield Extracted(id=3, name="Dennis", value=".c")
+ yield Extracted(id=4, name="Yukihiro", value=".rb")
def extract_bt():
- yield ExtractedBT(id=1, name='Guido', value='.py')
- yield ExtractedBT(id=2, name='Larry', value='.pl')
- yield ExtractedBT(id=3, name='Dennis', value='.c')
- yield ExtractedBT(id=4, name='Yukihiro', value='.rb')
+ yield ExtractedBT(id=1, name="Guido", value=".py")
+ yield ExtractedBT(id=2, name="Larry", value=".pl")
+ yield ExtractedBT(id=3, name="Dennis", value=".c")
+ yield ExtractedBT(id=4, name="Yukihiro", value=".rb")
def transform_using_args(id, name, value):
@@ -53,10 +53,18 @@ def test_execution():
with GraphExecutionContext(graph) as context:
context.run_until_complete()
- assert result_args == [(2, 'Guido', 'guido.py'), (4, 'Larry', 'larry.pl'), (6, 'Dennis', 'dennis.c'),
- (8, 'Yukihiro', 'yukihiro.rb')]
+ assert result_args == [
+ (2, "Guido", "guido.py"),
+ (4, "Larry", "larry.pl"),
+ (6, "Dennis", "dennis.c"),
+ (8, "Yukihiro", "yukihiro.rb"),
+ ]
- assert result_nt == [(1, 'GUIDO', '.py'), (2, 'LARRY', '.pl'), (3, 'DENNIS', '.c'), (4, 'YUKIHIRO', '.rb')]
+ assert result_nt == [(1, "GUIDO", ".py"), (2, "LARRY", ".pl"), (3, "DENNIS", ".c"), (4, "YUKIHIRO", ".rb")]
- assert result_bt == [(2, 'Guido', 'guido.py'), (4, 'Larry', 'larry.pl'), (6, 'Dennis', 'dennis.c'),
- (8, 'Yukihiro', 'yukihiro.rb')]
+ assert result_bt == [
+ (2, "Guido", "guido.py"),
+ (4, "Larry", "larry.pl"),
+ (6, "Dennis", "dennis.c"),
+ (8, "Yukihiro", "yukihiro.rb"),
+ ]
diff --git a/tests/execution/contexts/test_execution_contexts_graph.py b/tests/execution/contexts/test_execution_contexts_graph.py
index e297c31..155936e 100644
--- a/tests/execution/contexts/test_execution_contexts_graph.py
+++ b/tests/execution/contexts/test_execution_contexts_graph.py
@@ -1,14 +1,14 @@
from bonobo import Graph
-from bonobo.constants import EMPTY, BEGIN, END
+from bonobo.constants import BEGIN, EMPTY, END
from bonobo.execution.contexts import GraphExecutionContext
def raise_an_error(*args, **kwargs):
- raise Exception('Careful, man, there\'s a beverage here!')
+ raise Exception("Careful, man, there's a beverage here!")
def raise_an_unrecoverrable_error(*args, **kwargs):
- raise Exception('You are entering a world of pain!')
+ raise Exception("You are entering a world of pain!")
def test_lifecycle_of_empty_graph():
diff --git a/tests/execution/contexts/test_execution_contexts_node.py b/tests/execution/contexts/test_execution_contexts_node.py
index ca9de41..6b694e4 100644
--- a/tests/execution/contexts/test_execution_contexts_node.py
+++ b/tests/execution/contexts/test_execution_contexts_node.py
@@ -6,131 +6,131 @@ from bonobo import Graph
from bonobo.constants import EMPTY
from bonobo.execution.contexts.node import NodeExecutionContext, split_token
from bonobo.execution.strategies import NaiveStrategy
-from bonobo.util.envelopes import F_NOT_MODIFIED, F_INHERIT
-from bonobo.util.testing import BufferingNodeExecutionContext, BufferingGraphExecutionContext
+from bonobo.util.envelopes import F_INHERIT, F_NOT_MODIFIED
+from bonobo.util.testing import BufferingGraphExecutionContext, BufferingNodeExecutionContext
def test_node_string():
def f():
- return 'foo'
+ return "foo"
with BufferingNodeExecutionContext(f) as context:
context.write_sync(EMPTY)
output = context.get_buffer()
assert len(output) == 1
- assert output[0] == ('foo', )
+ assert output[0] == ("foo",)
def g():
- yield 'foo'
- yield 'bar'
+ yield "foo"
+ yield "bar"
with BufferingNodeExecutionContext(g) as context:
context.write_sync(EMPTY)
output = context.get_buffer()
assert len(output) == 2
- assert output[0] == ('foo', )
- assert output[1] == ('bar', )
+ assert output[0] == ("foo",)
+ assert output[1] == ("bar",)
def test_node_bytes():
def f():
- return b'foo'
+ return b"foo"
with BufferingNodeExecutionContext(f) as context:
context.write_sync(EMPTY)
output = context.get_buffer()
assert len(output) == 1
- assert output[0] == (b'foo', )
+ assert output[0] == (b"foo",)
def g():
- yield b'foo'
- yield b'bar'
+ yield b"foo"
+ yield b"bar"
with BufferingNodeExecutionContext(g) as context:
context.write_sync(EMPTY)
output = context.get_buffer()
assert len(output) == 2
- assert output[0] == (b'foo', )
- assert output[1] == (b'bar', )
+ assert output[0] == (b"foo",)
+ assert output[1] == (b"bar",)
def test_node_dict():
def f():
- return {'id': 1, 'name': 'foo'}
+ return {"id": 1, "name": "foo"}
with BufferingNodeExecutionContext(f) as context:
context.write_sync(EMPTY)
output = context.get_buffer()
assert len(output) == 1
- assert output[0] == ({'id': 1, 'name': 'foo'}, )
+ assert output[0] == ({"id": 1, "name": "foo"},)
def g():
- yield {'id': 1, 'name': 'foo'}
- yield {'id': 2, 'name': 'bar'}
+ yield {"id": 1, "name": "foo"}
+ yield {"id": 2, "name": "bar"}
with BufferingNodeExecutionContext(g) as context:
context.write_sync(EMPTY)
output = context.get_buffer()
assert len(output) == 2
- assert output[0] == ({'id': 1, 'name': 'foo'}, )
- assert output[1] == ({'id': 2, 'name': 'bar'}, )
+ assert output[0] == ({"id": 1, "name": "foo"},)
+ assert output[1] == ({"id": 2, "name": "bar"},)
def test_node_dict_chained():
strategy = NaiveStrategy(GraphExecutionContextType=BufferingGraphExecutionContext)
def f():
- return {'id': 1, 'name': 'foo'}
+ return {"id": 1, "name": "foo"}
def uppercase_name(values):
- return {**values, 'name': values['name'].upper()}
+ return {**values, "name": values["name"].upper()}
graph = Graph(f, uppercase_name)
context = strategy.execute(graph)
output = context.get_buffer()
assert len(output) == 1
- assert output[0] == ({'id': 1, 'name': 'FOO'}, )
+ assert output[0] == ({"id": 1, "name": "FOO"},)
def g():
- yield {'id': 1, 'name': 'foo'}
- yield {'id': 2, 'name': 'bar'}
+ yield {"id": 1, "name": "foo"}
+ yield {"id": 2, "name": "bar"}
graph = Graph(g, uppercase_name)
context = strategy.execute(graph)
output = context.get_buffer()
assert len(output) == 2
- assert output[0] == ({'id': 1, 'name': 'FOO'}, )
- assert output[1] == ({'id': 2, 'name': 'BAR'}, )
+ assert output[0] == ({"id": 1, "name": "FOO"},)
+ assert output[1] == ({"id": 2, "name": "BAR"},)
def test_node_tuple():
def f():
- return 'foo', 'bar'
+ return "foo", "bar"
with BufferingNodeExecutionContext(f) as context:
context.write_sync(EMPTY)
output = context.get_buffer()
assert len(output) == 1
- assert output[0] == ('foo', 'bar')
+ assert output[0] == ("foo", "bar")
def g():
- yield 'foo', 'bar'
- yield 'foo', 'baz'
+ yield "foo", "bar"
+ yield "foo", "baz"
with BufferingNodeExecutionContext(g) as context:
context.write_sync(EMPTY)
output = context.get_buffer()
assert len(output) == 2
- assert output[0] == ('foo', 'bar')
- assert output[1] == ('foo', 'baz')
+ assert output[0] == ("foo", "bar")
+ assert output[1] == ("foo", "baz")
def test_node_tuple_chained():
@@ -140,50 +140,50 @@ def test_node_tuple_chained():
return tuple(map(str.upper, args))
def f():
- return 'foo', 'bar'
+ return "foo", "bar"
graph = Graph(f, uppercase)
context = strategy.execute(graph)
output = context.get_buffer()
assert len(output) == 1
- assert output[0] == ('FOO', 'BAR')
+ assert output[0] == ("FOO", "BAR")
def g():
- yield 'foo', 'bar'
- yield 'foo', 'baz'
+ yield "foo", "bar"
+ yield "foo", "baz"
graph = Graph(g, uppercase)
context = strategy.execute(graph)
output = context.get_buffer()
assert len(output) == 2
- assert output[0] == ('FOO', 'BAR')
- assert output[1] == ('FOO', 'BAZ')
+ assert output[0] == ("FOO", "BAR")
+ assert output[1] == ("FOO", "BAZ")
def test_node_tuple_dict():
def f():
- return 'foo', 'bar', {'id': 1}
+ return "foo", "bar", {"id": 1}
with BufferingNodeExecutionContext(f) as context:
context.write_sync(EMPTY)
output = context.get_buffer()
assert len(output) == 1
- assert output[0] == ('foo', 'bar', {'id': 1})
+ assert output[0] == ("foo", "bar", {"id": 1})
def g():
- yield 'foo', 'bar', {'id': 1}
- yield 'foo', 'baz', {'id': 2}
+ yield "foo", "bar", {"id": 1}
+ yield "foo", "baz", {"id": 2}
with BufferingNodeExecutionContext(g) as context:
context.write_sync(EMPTY)
output = context.get_buffer()
assert len(output) == 2
- assert output[0] == ('foo', 'bar', {'id': 1})
- assert output[1] == ('foo', 'baz', {'id': 2})
+ assert output[0] == ("foo", "bar", {"id": 1})
+ assert output[1] == ("foo", "baz", {"id": 2})
def test_node_lifecycle_natural():
@@ -229,9 +229,9 @@ def test_node_lifecycle_with_kill():
def test_split_token():
with pytest.deprecated_call():
- assert split_token(('foo', 'bar')) == (set(), ('foo', 'bar'))
+ assert split_token(("foo", "bar")) == (set(), ("foo", "bar"))
assert split_token(()) == (set(), ())
- assert split_token('') == (set(), ('', ))
+ assert split_token("") == (set(), ("",))
def test_split_token_duplicate():
@@ -247,17 +247,17 @@ def test_split_token_duplicate():
def test_split_token_not_modified():
with pytest.deprecated_call():
with pytest.raises(ValueError):
- split_token((F_NOT_MODIFIED, 'foo', 'bar'))
+ split_token((F_NOT_MODIFIED, "foo", "bar"))
with pytest.raises(ValueError):
split_token((F_NOT_MODIFIED, F_INHERIT))
with pytest.raises(ValueError):
split_token((F_INHERIT, F_NOT_MODIFIED))
assert split_token(F_NOT_MODIFIED) == ({F_NOT_MODIFIED}, ())
- assert split_token((F_NOT_MODIFIED, )) == ({F_NOT_MODIFIED}, ())
+ assert split_token((F_NOT_MODIFIED,)) == ({F_NOT_MODIFIED}, ())
def test_split_token_inherit():
with pytest.deprecated_call():
assert split_token(F_INHERIT) == ({F_INHERIT}, ())
- assert split_token((F_INHERIT, )) == ({F_INHERIT}, ())
- assert split_token((F_INHERIT, 'foo', 'bar')) == ({F_INHERIT}, ('foo', 'bar'))
+ assert split_token((F_INHERIT,)) == ({F_INHERIT}, ())
+ assert split_token((F_INHERIT, "foo", "bar")) == ({F_INHERIT}, ("foo", "bar"))
diff --git a/tests/execution/test_events.py b/tests/execution/test_events.py
index 6fbc405..0c94299 100644
--- a/tests/execution/test_events.py
+++ b/tests/execution/test_events.py
@@ -6,9 +6,9 @@ from bonobo.execution import events
def test_names():
# This test looks useless, but as it's becoming the pliugin API, I want to make sure that nothing changes here, or
# notice it otherwise.
- for name in 'start', 'started', 'tick', 'stop', 'stopped', 'kill':
+ for name in "start", "started", "tick", "stop", "stopped", "kill":
event_name = getattr(events, name.upper())
- assert event_name == '.'.join(('execution', name))
+ assert event_name == ".".join(("execution", name))
def test_event_object():
diff --git a/tests/ext/test_ods.py b/tests/ext/test_ods.py
index a07ae81..65ff180 100644
--- a/tests/ext/test_ods.py
+++ b/tests/ext/test_ods.py
@@ -14,16 +14,11 @@ class ResponseMock:
return {}
else:
self.count += 1
- return {
- 'records': self.json_value,
- }
+ return {"records": self.json_value}
def test_read_from_opendatasoft_api():
- extract = OpenDataSoftAPI(dataset='test-a-set')
- with patch('requests.get', return_value=ResponseMock([
- {'fields': {'foo': 'bar'}},
- {'fields': {'foo': 'zab'}},
- ])):
- for line in extract('http://example.com/', ValueHolder(0)):
- assert 'foo' in line
+ extract = OpenDataSoftAPI(dataset="test-a-set")
+ with patch("requests.get", return_value=ResponseMock([{"fields": {"foo": "bar"}}, {"fields": {"foo": "zab"}}])):
+ for line in extract("http://example.com/", ValueHolder(0)):
+ assert "foo" in line
diff --git a/tests/features/test_inherit.py b/tests/features/test_inherit.py
index 63c6a5d..7b4db7d 100644
--- a/tests/features/test_inherit.py
+++ b/tests/features/test_inherit.py
@@ -1,27 +1,24 @@
from bonobo.util.envelopes import AppendingEnvelope
from bonobo.util.testing import BufferingNodeExecutionContext
-messages = [
- ('Hello', ),
- ('Goodbye', ),
-]
+messages = [("Hello",), ("Goodbye",)]
def append(*args):
- return AppendingEnvelope('!')
+ return AppendingEnvelope("!")
def test_inherit():
with BufferingNodeExecutionContext(append) as context:
context.write_sync(*messages)
- assert context.get_buffer() == list(map(lambda x: x + ('!', ), messages))
+ assert context.get_buffer() == list(map(lambda x: x + ("!",), messages))
def test_inherit_bag_tuple():
with BufferingNodeExecutionContext(append) as context:
- context.set_input_fields(['message'])
+ context.set_input_fields(["message"])
context.write_sync(*messages)
- assert context.get_output_fields() == ('message', '0')
- assert context.get_buffer() == list(map(lambda x: x + ('!', ), messages))
+ assert context.get_output_fields() == ("message", "0")
+ assert context.get_buffer() == list(map(lambda x: x + ("!",), messages))
diff --git a/tests/features/test_not_modified.py b/tests/features/test_not_modified.py
index 63b27d8..8d753da 100644
--- a/tests/features/test_not_modified.py
+++ b/tests/features/test_not_modified.py
@@ -7,10 +7,7 @@ def useless(*args, **kwargs):
def test_not_modified():
- input_messages = [
- ('foo', 'bar'),
- ('foo', 'baz'),
- ]
+ input_messages = [("foo", "bar"), ("foo", "baz")]
with BufferingNodeExecutionContext(useless) as context:
context.write_sync(*input_messages)
diff --git a/tests/nodes/io/test_csv.py b/tests/nodes/io/test_csv.py
index f862ca7..3173768 100644
--- a/tests/nodes/io/test_csv.py
+++ b/tests/nodes/io/test_csv.py
@@ -6,13 +6,14 @@ import pytest
from bonobo import CsvReader, CsvWriter
from bonobo.constants import EMPTY
-from bonobo.util.testing import FilesystemTester, BufferingNodeExecutionContext, WriterTest, ConfigurableNodeTest, \
- ReaderTest
+from bonobo.util.testing import (
+ BufferingNodeExecutionContext, ConfigurableNodeTest, FilesystemTester, ReaderTest, WriterTest
+)
-csv_tester = FilesystemTester('csv')
-csv_tester.input_data = 'a,b,c\na foo,b foo,c foo\na bar,b bar,c bar'
+csv_tester = FilesystemTester("csv")
+csv_tester.input_data = "a,b,c\na foo,b foo,c foo\na bar,b bar,c bar"
-defaults = {'lineterminator': '\n'}
+defaults = {"lineterminator": "\n"}
incontext = ConfigurableNodeTest.incontext
@@ -23,15 +24,10 @@ def test_read_csv_from_file_kwargs(tmpdir):
with BufferingNodeExecutionContext(CsvReader(filename, **defaults), services=services) as context:
context.write_sync(EMPTY)
- assert context.get_buffer_args_as_dicts() == [{
- 'a': 'a foo',
- 'b': 'b foo',
- 'c': 'c foo',
- }, {
- 'a': 'a bar',
- 'b': 'b bar',
- 'c': 'c bar',
- }]
+ assert context.get_buffer_args_as_dicts() == [
+ {"a": "a foo", "b": "b foo", "c": "c foo"},
+ {"a": "a bar", "b": "b bar", "c": "c bar"},
+ ]
###
@@ -40,86 +36,66 @@ def test_read_csv_from_file_kwargs(tmpdir):
class Csv:
- extension = 'csv'
+ extension = "csv"
ReaderNodeType = CsvReader
WriterNodeType = CsvWriter
-L1, L2, L3, L4 = ('a', 'hey'), ('b', 'bee'), ('c', 'see'), ('d', 'dee')
-LL = ('i', 'have', 'more', 'values')
+L1, L2, L3, L4 = ("a", "hey"), ("b", "bee"), ("c", "see"), ("d", "dee")
+LL = ("i", "have", "more", "values")
class CsvReaderTest(Csv, ReaderTest, TestCase):
- input_data = '\n'.join((
- 'id,name',
- '1,John Doe',
- '2,Jane Doe',
- ',DPR',
- '42,Elon Musk',
- ))
+ input_data = "\n".join(("id,name", "1,John Doe", "2,Jane Doe", ",DPR", "42,Elon Musk"))
def check_output(self, context, *, prepend=None):
out = context.get_buffer()
- assert out == (prepend or list()) + [
- ('1', 'John Doe'),
- ('2', 'Jane Doe'),
- ('', 'DPR'),
- ('42', 'Elon Musk'),
- ]
+ assert out == (prepend or list()) + [("1", "John Doe"), ("2", "Jane Doe"), ("", "DPR"), ("42", "Elon Musk")]
@incontext()
def test_nofields(self, context):
context.write_sync(EMPTY)
context.stop()
self.check_output(context)
- assert context.get_output_fields() == ('id', 'name')
+ assert context.get_output_fields() == ("id", "name")
@incontext(output_type=tuple)
def test_output_type(self, context):
context.write_sync(EMPTY)
context.stop()
- self.check_output(context, prepend=[('id', 'name')])
+ self.check_output(context, prepend=[("id", "name")])
- @incontext(
- output_fields=(
- 'x',
- 'y',
- ), skip=1
- )
+ @incontext(output_fields=("x", "y"), skip=1)
def test_output_fields(self, context):
context.write_sync(EMPTY)
context.stop()
self.check_output(context)
- assert context.get_output_fields() == ('x', 'y')
+ assert context.get_output_fields() == ("x", "y")
@incontext(quoting=QUOTE_ALL)
def test_quoting(self, context):
context.write_sync(EMPTY)
context.stop()
self.check_output(context)
- assert context.get_output_fields() == ('id', 'name')
+ assert context.get_output_fields() == ("id", "name")
class CsvWriterTest(Csv, WriterTest, TestCase):
@incontext()
def test_fields(self, context):
- context.set_input_fields(['foo', 'bar'])
- context.write_sync(('a', 'b'), ('c', 'd'))
+ context.set_input_fields(["foo", "bar"])
+ context.write_sync(("a", "b"), ("c", "d"))
context.stop()
- assert self.readlines() == (
- 'foo,bar',
- 'a,b',
- 'c,d',
- )
+ assert self.readlines() == ("foo,bar", "a,b", "c,d")
@incontext()
def test_fields_from_type(self, context):
- context.set_input_type(namedtuple('Point', 'x y'))
+ context.set_input_type(namedtuple("Point", "x y"))
context.write_sync((1, 2), (3, 4))
context.stop()
- assert self.readlines() == ('x,y', '1,2', '3,4')
+ assert self.readlines() == ("x,y", "1,2", "3,4")
@incontext()
def test_nofields_multiple_args(self, context):
@@ -127,30 +103,21 @@ class CsvWriterTest(Csv, WriterTest, TestCase):
context.write_sync((L1, L2), (L3, L4))
context.stop()
- assert self.readlines() == (
- 'a,hey',
- 'b,bee',
- 'c,see',
- 'd,dee',
- )
+ assert self.readlines() == ("a,hey", "b,bee", "c,see", "d,dee")
@incontext()
def test_nofields_multiple_args_length_mismatch(self, context):
# if length of input vary, then we get a TypeError (unrecoverable)
with pytest.raises(TypeError):
- context.write_sync((L1, L2), (L3, ))
+ context.write_sync((L1, L2), (L3,))
@incontext()
def test_nofields_single_arg(self, context):
# single args are just dumped, shapes can vary.
- context.write_sync((L1, ), (LL, ), (L3, ))
+ context.write_sync((L1,), (LL,), (L3,))
context.stop()
- assert self.readlines() == (
- 'a,hey',
- 'i,have,more,values',
- 'c,see',
- )
+ assert self.readlines() == ("a,hey", "i,have,more,values", "c,see")
@incontext()
def test_nofields_empty_args(self, context):
diff --git a/tests/nodes/io/test_file.py b/tests/nodes/io/test_file.py
index ee8548b..a3e3172 100644
--- a/tests/nodes/io/test_file.py
+++ b/tests/nodes/io/test_file.py
@@ -5,26 +5,23 @@ from bonobo.constants import EMPTY
from bonobo.execution.contexts.node import NodeExecutionContext
from bonobo.util.testing import BufferingNodeExecutionContext, FilesystemTester
-txt_tester = FilesystemTester('txt')
-txt_tester.input_data = 'Hello\nWorld\n'
+txt_tester = FilesystemTester("txt")
+txt_tester.input_data = "Hello\nWorld\n"
def test_file_writer_contextless(tmpdir):
fs, filename, services = txt_tester.get_services_for_writer(tmpdir)
with FileWriter(path=filename).open(fs) as fp:
- fp.write('Yosh!')
+ fp.write("Yosh!")
with fs.open(filename) as fp:
- assert fp.read() == 'Yosh!'
+ assert fp.read() == "Yosh!"
@pytest.mark.parametrize(
- 'lines,output',
- [
- (('ACME', ), 'ACME'), # one line...
- (('Foo', 'Bar', 'Baz'), 'Foo\nBar\nBaz'), # more than one line...
- ]
+ "lines,output",
+ [(("ACME",), "ACME"), (("Foo", "Bar", "Baz"), "Foo\nBar\nBaz")], # one line... # more than one line...
)
def test_file_writer_in_context(tmpdir, lines, output):
fs, filename, services = txt_tester.get_services_for_writer(tmpdir)
@@ -44,5 +41,5 @@ def test_file_reader(tmpdir):
output = context.get_buffer()
assert len(output) == 2
- assert output[0] == ('Hello', )
- assert output[1] == ('World', )
+ assert output[0] == ("Hello",)
+ assert output[1] == ("World",)
diff --git a/tests/nodes/io/test_json.py b/tests/nodes/io/test_json.py
index c2caedd..fac797f 100644
--- a/tests/nodes/io/test_json.py
+++ b/tests/nodes/io/test_json.py
@@ -4,14 +4,13 @@ from unittest import TestCase
import pytest
-from bonobo import JsonReader, JsonWriter
-from bonobo import LdjsonReader, LdjsonWriter
+from bonobo import JsonReader, JsonWriter, LdjsonReader, LdjsonWriter
from bonobo.constants import EMPTY
-from bonobo.util.testing import WriterTest, ReaderTest, ConfigurableNodeTest
+from bonobo.util.testing import ConfigurableNodeTest, ReaderTest, WriterTest
-FOOBAR = {'foo': 'bar'}
-OD_ABC = OrderedDict((('a', 'A'), ('b', 'B'), ('c', 'C')))
-FOOBAZ = {'foo': 'baz'}
+FOOBAR = {"foo": "bar"}
+OD_ABC = OrderedDict((("a", "A"), ("b", "B"), ("c", "C")))
+FOOBAZ = {"foo": "baz"}
incontext = ConfigurableNodeTest.incontext
@@ -21,7 +20,7 @@ incontext = ConfigurableNodeTest.incontext
class Json:
- extension = 'json'
+ extension = "json"
ReaderNodeType = JsonReader
WriterNodeType = JsonWriter
@@ -34,88 +33,61 @@ class JsonReaderDictsTest(Json, ReaderTest, TestCase):
context.write_sync(EMPTY)
context.stop()
- assert context.get_buffer() == [
- ({
- "foo": "bar"
- }, ),
- ({
- "baz": "boz"
- }, ),
- ]
+ assert context.get_buffer() == [({"foo": "bar"},), ({"baz": "boz"},)]
class JsonReaderListsTest(Json, ReaderTest, TestCase):
- input_data = '[[1,2,3],\n[4,5,6]]'
+ input_data = "[[1,2,3],\n[4,5,6]]"
@incontext()
def test_nofields(self, context):
context.write_sync(EMPTY)
context.stop()
- assert context.get_buffer() == [
- ([1, 2, 3], ),
- ([4, 5, 6], ),
- ]
+ assert context.get_buffer() == [([1, 2, 3],), ([4, 5, 6],)]
@incontext(output_type=tuple)
def test_output_type(self, context):
context.write_sync(EMPTY)
context.stop()
- assert context.get_buffer() == [
- ([1, 2, 3], ),
- ([4, 5, 6], ),
- ]
+ assert context.get_buffer() == [([1, 2, 3],), ([4, 5, 6],)]
class JsonReaderStringsTest(Json, ReaderTest, TestCase):
- input_data = '[' + ',\n'.join(map(json.dumps, ('foo', 'bar', 'baz'))) + ']'
+ input_data = "[" + ",\n".join(map(json.dumps, ("foo", "bar", "baz"))) + "]"
@incontext()
def test_nofields(self, context):
context.write_sync(EMPTY)
context.stop()
- assert context.get_buffer() == [
- ('foo', ),
- ('bar', ),
- ('baz', ),
- ]
+ assert context.get_buffer() == [("foo",), ("bar",), ("baz",)]
@incontext(output_type=tuple)
def test_output_type(self, context):
context.write_sync(EMPTY)
context.stop()
- assert context.get_buffer() == [
- ('foo', ),
- ('bar', ),
- ('baz', ),
- ]
+ assert context.get_buffer() == [("foo",), ("bar",), ("baz",)]
class JsonWriterTest(Json, WriterTest, TestCase):
@incontext()
def test_fields(self, context):
- context.set_input_fields(['foo', 'bar'])
- context.write_sync(('a', 'b'), ('c', 'd'))
+ context.set_input_fields(["foo", "bar"])
+ context.write_sync(("a", "b"), ("c", "d"))
context.stop()
- assert self.readlines() == (
- '[{"foo": "a", "bar": "b"},',
- '{"foo": "c", "bar": "d"}]',
- )
+ assert self.readlines() == ('[{"foo": "a", "bar": "b"},', '{"foo": "c", "bar": "d"}]')
@incontext()
def test_fields_from_type(self, context):
- context.set_input_type(namedtuple('Point', 'x y'))
+ context.set_input_type(namedtuple("Point", "x y"))
context.write_sync((1, 2), (3, 4))
context.stop()
- assert self.readlines() == (
- '[{"x": 1, "y": 2},',
- '{"x": 3, "y": 4}]',
- )
+ assert self.readlines() == ('[{"x": 1, "y": 2},', '{"x": 3, "y": 4}]')
@incontext()
def test_nofields_multiple_args(self, context):
@@ -144,11 +116,7 @@ class JsonWriterTest(Json, WriterTest, TestCase):
context.write_sync(FOOBAR, OD_ABC, FOOBAZ)
context.stop()
- assert self.readlines() == (
- '[{"foo": "bar"},',
- '{"a": "A", "b": "B", "c": "C"},',
- '{"foo": "baz"}]',
- )
+ assert self.readlines() == ('[{"foo": "bar"},', '{"a": "A", "b": "B", "c": "C"},', '{"foo": "baz"}]')
@incontext()
def test_nofields_empty_args(self, context):
@@ -156,7 +124,7 @@ class JsonWriterTest(Json, WriterTest, TestCase):
context.write_sync(EMPTY, EMPTY, EMPTY)
context.stop()
- assert self.readlines() == ('[]', )
+ assert self.readlines() == ("[]",)
###
@@ -165,7 +133,7 @@ class JsonWriterTest(Json, WriterTest, TestCase):
class Ldjson:
- extension = 'ldjson'
+ extension = "ldjson"
ReaderNodeType = LdjsonReader
WriterNodeType = LdjsonWriter
@@ -178,85 +146,61 @@ class LdjsonReaderDictsTest(Ldjson, ReaderTest, TestCase):
context.write_sync(EMPTY)
context.stop()
- assert context.get_buffer() == [
- ({
- "foo": "bar"
- }, ),
- ({
- "baz": "boz"
- }, ),
- ]
+ assert context.get_buffer() == [({"foo": "bar"},), ({"baz": "boz"},)]
class LdjsonReaderListsTest(Ldjson, ReaderTest, TestCase):
- input_data = '[1,2,3]\n[4,5,6]'
+ input_data = "[1,2,3]\n[4,5,6]"
@incontext()
def test_nofields(self, context):
context.write_sync(EMPTY)
context.stop()
- assert context.get_buffer() == [
- ([1, 2, 3], ),
- ([4, 5, 6], ),
- ]
+ assert context.get_buffer() == [([1, 2, 3],), ([4, 5, 6],)]
@incontext(output_type=tuple)
def test_output_type(self, context):
context.write_sync(EMPTY)
context.stop()
- assert context.get_buffer() == [
- ([1, 2, 3], ),
- ([4, 5, 6], ),
- ]
+ assert context.get_buffer() == [([1, 2, 3],), ([4, 5, 6],)]
class LdjsonReaderStringsTest(Ldjson, ReaderTest, TestCase):
- input_data = '\n'.join(map(json.dumps, ('foo', 'bar', 'baz')))
+ input_data = "\n".join(map(json.dumps, ("foo", "bar", "baz")))
@incontext()
def test_nofields(self, context):
context.write_sync(EMPTY)
context.stop()
- assert context.get_buffer() == [
- ('foo', ),
- ('bar', ),
- ('baz', ),
- ]
+ assert context.get_buffer() == [("foo",), ("bar",), ("baz",)]
@incontext(output_type=tuple)
def test_output_type(self, context):
context.write_sync(EMPTY)
context.stop()
- assert context.get_buffer() == [
- ('foo', ),
- ('bar', ),
- ('baz', ),
- ]
+ assert context.get_buffer() == [("foo",), ("bar",), ("baz",)]
class LdjsonWriterTest(Ldjson, WriterTest, TestCase):
@incontext()
def test_fields(self, context):
- context.set_input_fields(['foo', 'bar'])
- context.write_sync(('a', 'b'), ('c', 'd'))
+ context.set_input_fields(["foo", "bar"])
+ context.write_sync(("a", "b"), ("c", "d"))
context.stop()
assert self.readlines() == ('{"foo": "a", "bar": "b"}', '{"foo": "c", "bar": "d"}')
@incontext()
def test_fields_from_type(self, context):
- context.set_input_type(namedtuple('Point', 'x y'))
+ context.set_input_type(namedtuple("Point", "x y"))
context.write_sync((1, 2), (3, 4))
context.stop()
- assert self.readlines() == (
- '{"x": 1, "y": 2}',
- '{"x": 3, "y": 4}',
- )
+ assert self.readlines() == ('{"x": 1, "y": 2}', '{"x": 3, "y": 4}')
@incontext()
def test_nofields_multiple_args(self, context):
@@ -285,11 +229,7 @@ class LdjsonWriterTest(Ldjson, WriterTest, TestCase):
context.write_sync(FOOBAR, OD_ABC, FOOBAZ)
context.stop()
- assert self.readlines() == (
- '{"foo": "bar"}',
- '{"a": "A", "b": "B", "c": "C"}',
- '{"foo": "baz"}',
- )
+ assert self.readlines() == ('{"foo": "bar"}', '{"a": "A", "b": "B", "c": "C"}', '{"foo": "baz"}')
@incontext()
def test_nofields_empty_args(self, context):
diff --git a/tests/nodes/io/test_pickle.py b/tests/nodes/io/test_pickle.py
index 0662848..3e4745d 100644
--- a/tests/nodes/io/test_pickle.py
+++ b/tests/nodes/io/test_pickle.py
@@ -7,21 +7,21 @@ from bonobo.constants import EMPTY
from bonobo.execution.contexts.node import NodeExecutionContext
from bonobo.util.testing import BufferingNodeExecutionContext, FilesystemTester
-pickle_tester = FilesystemTester('pkl', mode='wb')
-pickle_tester.input_data = pickle.dumps([['a', 'b', 'c'], ['a foo', 'b foo', 'c foo'], ['a bar', 'b bar', 'c bar']])
+pickle_tester = FilesystemTester("pkl", mode="wb")
+pickle_tester.input_data = pickle.dumps([["a", "b", "c"], ["a foo", "b foo", "c foo"], ["a bar", "b bar", "c bar"]])
def test_write_pickled_dict_to_file(tmpdir):
fs, filename, services = pickle_tester.get_services_for_writer(tmpdir)
with NodeExecutionContext(PickleWriter(filename), services=services) as context:
- context.write_sync({'foo': 'bar'}, {'foo': 'baz', 'ignore': 'this'})
+ context.write_sync({"foo": "bar"}, {"foo": "baz", "ignore": "this"})
- with fs.open(filename, 'rb') as fp:
- assert pickle.loads(fp.read()) == {'foo': 'bar'}
+ with fs.open(filename, "rb") as fp:
+ assert pickle.loads(fp.read()) == {"foo": "bar"}
with pytest.raises(AttributeError):
- getattr(context, 'file')
+ getattr(context, "file")
def test_read_pickled_list_from_file(tmpdir):
@@ -31,8 +31,5 @@ def test_read_pickled_list_from_file(tmpdir):
context.write_sync(EMPTY)
output = context.get_buffer()
- assert context.get_output_fields() == ('a', 'b', 'c')
- assert output == [
- ('a foo', 'b foo', 'c foo'),
- ('a bar', 'b bar', 'c bar'),
- ]
+ assert context.get_output_fields() == ("a", "b", "c")
+ assert output == [("a foo", "b foo", "c foo"), ("a bar", "b bar", "c bar")]
diff --git a/tests/nodes/test_basics.py b/tests/nodes/test_basics.py
index 4b6a8be..d977653 100644
--- a/tests/nodes/test_basics.py
+++ b/tests/nodes/test_basics.py
@@ -5,9 +5,9 @@ from unittest.mock import MagicMock
import pytest
import bonobo
-from bonobo.constants import NOT_MODIFIED, EMPTY
-from bonobo.util import ensure_tuple, ValueHolder
-from bonobo.util.testing import BufferingNodeExecutionContext, StaticNodeTest, ConfigurableNodeTest
+from bonobo.constants import EMPTY, NOT_MODIFIED
+from bonobo.util import ValueHolder, ensure_tuple
+from bonobo.util.testing import BufferingNodeExecutionContext, ConfigurableNodeTest, StaticNodeTest
class CountTest(StaticNodeTest, TestCase):
@@ -26,7 +26,7 @@ class CountTest(StaticNodeTest, TestCase):
def test_execution(self):
with self.execute() as context:
context.write_sync(*([EMPTY] * 42))
- assert context.get_buffer() == [(42, )]
+ assert context.get_buffer() == [(42,)]
class IdentityTest(StaticNodeTest, TestCase):
@@ -81,14 +81,14 @@ def test_tee():
tee = bonobo.Tee(inner)
results = []
for i in range(10):
- results.append(tee('foo'))
+ results.append(tee("foo"))
assert results == [NOT_MODIFIED] * 10
assert len(inner.mock_calls) == 10
def test_noop():
- assert bonobo.noop(1, 2, 3, 4, foo='bar') == NOT_MODIFIED
+ assert bonobo.noop(1, 2, 3, 4, foo="bar") == NOT_MODIFIED
def test_fixedwindow():
@@ -98,21 +98,18 @@ def test_fixedwindow():
with BufferingNodeExecutionContext(bonobo.FixedWindow(2)) as context:
context.write_sync(*range(9))
- assert context.get_buffer() == [(0, 1), (2, 3), (4, 5), (6, 7), (
- 8,
- None,
- )]
+ assert context.get_buffer() == [(0, 1), (2, 3), (4, 5), (6, 7), (8, None)]
with BufferingNodeExecutionContext(bonobo.FixedWindow(1)) as context:
context.write_sync(*range(3))
- assert context.get_buffer() == [(0, ), (1, ), (2, )]
+ assert context.get_buffer() == [(0,), (1,), (2,)]
def test_methodcaller():
- with BufferingNodeExecutionContext(methodcaller('swapcase')) as context:
- context.write_sync('aaa', 'bBb', 'CcC')
- assert context.get_buffer() == list(map(ensure_tuple, ['AAA', 'BbB', 'cCc']))
+ with BufferingNodeExecutionContext(methodcaller("swapcase")) as context:
+ context.write_sync("aaa", "bBb", "CcC")
+ assert context.get_buffer() == list(map(ensure_tuple, ["AAA", "BbB", "cCc"]))
- with BufferingNodeExecutionContext(methodcaller('zfill', 5)) as context:
- context.write_sync('a', 'bb', 'ccc')
- assert context.get_buffer() == list(map(ensure_tuple, ['0000a', '000bb', '00ccc']))
+ with BufferingNodeExecutionContext(methodcaller("zfill", 5)) as context:
+ context.write_sync("a", "bb", "ccc")
+ assert context.get_buffer() == list(map(ensure_tuple, ["0000a", "000bb", "00ccc"]))
diff --git a/tests/nodes/test_casts.py b/tests/nodes/test_casts.py
index 3eb3621..e8696eb 100644
--- a/tests/nodes/test_casts.py
+++ b/tests/nodes/test_casts.py
@@ -8,11 +8,11 @@ from bonobo.util.bags import BagType
from bonobo.util.envelopes import Envelope
from bonobo.util.testing import BufferingNodeExecutionContext
-MyTuple = namedtuple('MyTuple', ['a', 'b', 'c'])
-MyBag = BagType('MyBag', ['a', 'b', 'c'])
+MyTuple = namedtuple("MyTuple", ["a", "b", "c"])
+MyBag = BagType("MyBag", ["a", "b", "c"])
-class MyCustomType():
+class MyCustomType:
def __init__(self, *args):
self.args = args
@@ -20,16 +20,19 @@ class MyCustomType():
return MyBag(*self.args)
-@pytest.mark.parametrize(['factory', 'expected', 'expected_item0'], [
- [lambda: (1, 2, 3), tuple, int],
- [lambda: Envelope((1, 2, 3)), tuple, int],
- [lambda: MyTuple(1, 2, 3), MyTuple, int],
- [lambda: Envelope(MyTuple(1, 2, 3)), MyTuple, int],
- [lambda: MyBag(1, 2, 3), MyBag, int],
- [lambda: Envelope(MyBag(1, 2, 3)), MyBag, int],
- [lambda: MyCustomType(1, 2, 3), tuple, MyCustomType],
- [lambda: Envelope(MyCustomType(1, 2, 3)), tuple, MyCustomType],
-])
+@pytest.mark.parametrize(
+ ["factory", "expected", "expected_item0"],
+ [
+ [lambda: (1, 2, 3), tuple, int],
+ [lambda: Envelope((1, 2, 3)), tuple, int],
+ [lambda: MyTuple(1, 2, 3), MyTuple, int],
+ [lambda: Envelope(MyTuple(1, 2, 3)), MyTuple, int],
+ [lambda: MyBag(1, 2, 3), MyBag, int],
+ [lambda: Envelope(MyBag(1, 2, 3)), MyBag, int],
+ [lambda: MyCustomType(1, 2, 3), tuple, MyCustomType],
+ [lambda: Envelope(MyCustomType(1, 2, 3)), tuple, MyCustomType],
+ ],
+)
def test_casts_after_output(factory: Callable, expected, expected_item0):
def transform():
yield factory()
diff --git a/tests/plugins/test_console.py b/tests/plugins/test_console.py
index 543d341..3a7eb3b 100644
--- a/tests/plugins/test_console.py
+++ b/tests/plugins/test_console.py
@@ -1,10 +1,11 @@
from unittest.mock import MagicMock
+from whistle import EventDispatcher
+
import bonobo
from bonobo.execution import events
from bonobo.execution.contexts.graph import GraphExecutionContext
from bonobo.plugins.console import ConsoleOutputPlugin
-from whistle import EventDispatcher
def test_register_unregister():
diff --git a/tests/structs/test_graphs.py b/tests/structs/test_graphs.py
index 51321ae..fbca00c 100644
--- a/tests/structs/test_graphs.py
+++ b/tests/structs/test_graphs.py
@@ -1,7 +1,7 @@
-import pytest
-
from unittest.mock import sentinel
+import pytest
+
from bonobo.constants import BEGIN
from bonobo.structs.graphs import Graph
@@ -48,24 +48,14 @@ def test_graph_add_chain():
def test_graph_topological_sort():
g = Graph()
- g.add_chain(
- sentinel.a1,
- sentinel.a2,
- sentinel.a3,
- _input=None,
- _output=None,
- )
+ g.add_chain(sentinel.a1, sentinel.a2, sentinel.a3, _input=None, _output=None)
assert g.topologically_sorted_indexes == (0, 1, 2)
assert g[0] == sentinel.a1
assert g[1] == sentinel.a2
assert g[2] == sentinel.a3
- g.add_chain(
- sentinel.b1,
- sentinel.b2,
- _output=sentinel.a2,
- )
+ g.add_chain(sentinel.b1, sentinel.b2, _output=sentinel.a2)
assert g.topologically_sorted_indexes[-2:] == (1, 2)
assert g.topologically_sorted_indexes.index(3) < g.topologically_sorted_indexes.index(4)
diff --git a/tests/structs/test_inputs.py b/tests/structs/test_inputs.py
index d2ce827..c398ca5 100644
--- a/tests/structs/test_inputs.py
+++ b/tests/structs/test_inputs.py
@@ -19,7 +19,7 @@ from queue import Empty
import pytest
from bonobo.constants import BEGIN, END
-from bonobo.errors import InactiveWritableError, InactiveReadableError
+from bonobo.errors import InactiveReadableError, InactiveWritableError
from bonobo.structs.inputs import Input
@@ -29,22 +29,22 @@ def test_input_runlevels():
# Before BEGIN, noone should be able to write in an Input queue.
assert not q.alive
with pytest.raises(InactiveWritableError):
- q.put('hello, unborn queue.')
+ q.put("hello, unborn queue.")
# Begin
q.put(BEGIN)
assert q.alive and q._runlevel == 1
- q.put('foo')
+ q.put("foo")
# Second Begin
q.put(BEGIN)
assert q.alive and q._runlevel == 2
- q.put('bar')
+ q.put("bar")
q.put(END)
# FIFO
- assert q.get() == 'foo'
- assert q.get() == 'bar'
+ assert q.get() == "foo"
+ assert q.get() == "bar"
# self.assertEqual(q.alive, False) XXX queue don't know it's dead yet, but it is ...
# Async get raises Empty (End is not returned)
@@ -53,14 +53,14 @@ def test_input_runlevels():
assert q.alive
# Before killing, let's slide some data in.
- q.put('baz')
+ q.put("baz")
# Now kill the queue...
q.put(END)
with pytest.raises(InactiveWritableError):
- q.put('foo')
+ q.put("foo")
# Still can get remaining data
- assert q.get() == 'baz'
+ assert q.get() == "baz"
with pytest.raises(InactiveReadableError):
q.get()
diff --git a/tests/structs/test_tokens.py b/tests/structs/test_tokens.py
index 6bd9bee..0a222b3 100644
--- a/tests/structs/test_tokens.py
+++ b/tests/structs/test_tokens.py
@@ -2,5 +2,5 @@ from bonobo.structs.tokens import Token
def test_token_repr():
- t = Token('Acme')
- assert repr(t) == '