Merge remote-tracking branch 'upstream/develop' into develop

This commit is contained in:
Romain Dorgueil
2018-10-29 07:23:58 +01:00
34 changed files with 231 additions and 208 deletions

View File

@ -1,2 +1,3 @@
include *.txt
include bonobo/bonobo.svg
recursive-include bonobo *.py-tpl

View File

@ -120,7 +120,7 @@ watch-$(SPHINX_SOURCEDIR): ##
$(SPHINX_AUTOBUILD) $(SPHINX_SOURCEDIR) $(shell mktemp -d)
format: ## Reformats the whole codebase using our standards (requires black and isort).
black -l 120 --skip-string-normalization .
black -l 120 .
isort -rc -o mondrian -o whistle -y .
medikit: # Checks installed medikit version and updates it if it is outdated.

View File

@ -87,7 +87,7 @@ def on_make_generate(event):
makefile.add_target(
'format',
'''
black -l 120 --skip-string-normalization .
black -l 120 .
isort -rc -o mondrian -o whistle -y .
''',
phony=True,

View File

@ -17,11 +17,19 @@ environment:
PYTHON_ARCH: "64"
- PYTHON: "C:\\Python36"
PYTHON_VERSION: "3.6.1"
PYTHON_VERSION: "3.6.7"
PYTHON_ARCH: "32"
- PYTHON: "C:\\Python36-x64"
PYTHON_VERSION: "3.6.1"
PYTHON_VERSION: "3.6.7"
PYTHON_ARCH: "64"
- PYTHON: "C:\\Python37"
PYTHON_VERSION: "3.7.1"
PYTHON_ARCH: "32"
- PYTHON: "C:\\Python37-x64"
PYTHON_VERSION: "3.7.1"
PYTHON_ARCH: "64"
build: false

View File

@ -16,11 +16,11 @@ import timeit
def j1(d):
return {'prepend': 'foo', **d, 'append': 'bar'}
return {"prepend": "foo", **d, "append": "bar"}
def k1(**d):
return {'prepend': 'foo', **d, 'append': 'bar'}
return {"prepend": "foo", **d, "append": "bar"}
def j2(d):
@ -39,17 +39,17 @@ def k3(**d):
return None
if __name__ == '__main__':
if __name__ == "__main__":
import timeit
with open('person.json') as f:
with open("person.json") as f:
json_data = json.load(f)
for i in 1, 2, 3:
print(
'j{}'.format(i), timeit.timeit("j{}({!r})".format(i, json_data), setup="from __main__ import j{}".format(i))
"j{}".format(i), timeit.timeit("j{}({!r})".format(i, json_data), setup="from __main__ import j{}".format(i))
)
print(
'k{}'.format(i),
"k{}".format(i),
timeit.timeit("k{}(**{!r})".format(i, json_data), setup="from __main__ import k{}".format(i)),
)

View File

@ -2,48 +2,48 @@ import os
from jinja2 import DictLoader, Environment
__path__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__), '..'))
__path__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__), ".."))
apidoc_root = 'docs/reference/api'
apidoc_root = "docs/reference/api"
class Module:
def __init__(self, name, title=None, *, automodule_options=None):
self.name = name
self.title = title or ' '.join(map(str.title, self.name.split('.')[1:]))
self.title = title or " ".join(map(str.title, self.name.split(".")[1:]))
self.automodule_options = automodule_options or list()
def __repr__(self):
return '<{} ({})>'.format(self.title, self.name)
return "<{} ({})>".format(self.title, self.name)
def asdict(self):
return {'name': self.name, 'title': self.title, 'automodule_options': self.automodule_options}
return {"name": self.name, "title": self.title, "automodule_options": self.automodule_options}
def get_path(self):
return os.path.join(__path__, apidoc_root, *self.name.split('.')) + '.rst'
return os.path.join(__path__, apidoc_root, *self.name.split(".")) + ".rst"
modules = [
Module('bonobo', title='Bonobo'),
Module('bonobo.config'),
Module('bonobo.constants', automodule_options=['no-members']),
Module('bonobo.execution'),
Module('bonobo.execution.contexts'),
Module('bonobo.execution.events'),
Module('bonobo.execution.strategies'),
Module('bonobo.util'),
Module("bonobo", title="Bonobo"),
Module("bonobo.config"),
Module("bonobo.constants", automodule_options=["no-members"]),
Module("bonobo.execution"),
Module("bonobo.execution.contexts"),
Module("bonobo.execution.events"),
Module("bonobo.execution.strategies"),
Module("bonobo.util"),
]
def underlined_filter(txt, chr):
return txt + '\n' + chr * len(txt)
return txt + "\n" + chr * len(txt)
env = Environment(
loader=DictLoader(
{
'module': '''
"module": """
{{ (':mod:`'~title~' <'~name~'>`') | underlined('=') }}
.. currentmodule:: {{ name }}
@ -52,15 +52,15 @@ env = Environment(
.. automodule:: {{ name }}
{% for opt in automodule_options %} :{{ opt }}:{{ "\n" }}{% endfor %}
'''[
"""[
1:-1
]
+ '\n'
+ "\n"
}
)
)
env.filters['underlined'] = underlined_filter
env.filters["underlined"] = underlined_filter
for module in modules:
with open(module.get_path(), 'w+') as f:
f.write(env.get_template('module').render(module.asdict()))
with open(module.get_path(), "w+") as f:
f.write(env.get_template("module").render(module.asdict()))

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,6 @@ All objects in this module are considered very safe to use, and backward compati
to another is maximal.
"""
from bonobo.execution.strategies import create_strategy
from bonobo.nodes import *
from bonobo.nodes import __all__ as _all_nodes
@ -187,7 +186,7 @@ def get_examples_path(*pathsegments):
import os
import pathlib
return str(pathlib.Path(os.path.dirname(__file__), 'examples', *pathsegments))
return str(pathlib.Path(os.path.dirname(__file__), "examples", *pathsegments))
@api.register
@ -196,3 +195,4 @@ def open_examples_fs(*pathsegments):
api.register_group(get_argument_parser, parse_args)

View File

@ -1 +1 @@
__version__ = '0.6.3'
__version__ = "0.6.3"

1
bonobo/bonobo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@ -4,10 +4,11 @@ import runpy
import sys
from contextlib import contextmanager
from mondrian import humanizer
import bonobo.util.environ
from bonobo.util import get_name
from bonobo.util.environ import get_argument_parser, parse_args
from mondrian import humanizer
class BaseCommand:

View File

@ -1,8 +1,9 @@
from mondrian import humanizer
import bonobo
from bonobo.commands import BaseCommand
from bonobo.registry import READER, WRITER, default_registry
from bonobo.util.resolvers import _resolve_options, _resolve_transformations
from mondrian import humanizer
class ConvertCommand(BaseCommand):

View File

@ -1,9 +1,9 @@
import os
from jinja2 import Environment, FileSystemLoader
from mondrian import humanizer
from bonobo.commands import BaseCommand
from mondrian import humanizer
class InitCommand(BaseCommand):
@ -31,16 +31,12 @@ class InitCommand(BaseCommand):
with open(filename, "w+") as f:
f.write(template.render(name=name))
print(
humanizer.Success(
"Generated {} using template {!r}.".format(filename, template_name)
)
)
print(humanizer.Success("Generated {} using template {!r}.".format(filename, template_name)))
def create_package(self, *, filename):
_, ext = os.path.splitext(filename)
if ext != '':
raise ValueError('Package names should not have an extension.')
if ext != "":
raise ValueError("Package names should not have an extension.")
try:
import medikit.commands
@ -60,16 +56,16 @@ class InitCommand(BaseCommand):
print(
humanizer.Success(
'Package "{}" has been created.'.format(package_name),
'',
"",
"Install it...",
'',
"",
" $ `pip install --editable {}`".format(filename),
'',
"",
"Then maybe run the example...",
'',
"",
" $ `python -m {}`".format(package_name),
'',
"Enjoy!"
"",
"Enjoy!",
)
)

View File

@ -1,6 +1,7 @@
from bonobo.commands import BaseCommand
from mondrian import humanizer
from bonobo.commands import BaseCommand
def get_versions(*, all=False, quiet=None):
import bonobo

View File

@ -5,7 +5,7 @@ configurable transformations, either class-based or function-based.
"""
from bonobo.config.configurables import Configurable
from bonobo.config.functools import transformation_factory
from bonobo.config.functools import transformation_factory, partial
from bonobo.config.options import Method, Option
from bonobo.config.processors import ContextProcessor, use_context, use_context_processor, use_raw_input, use_no_input
from bonobo.config.services import Container, Exclusive, Service, use, create_container
@ -23,6 +23,7 @@ __all__ = [
"Option",
"Service",
"create_container",
"partial",
"requires",
"transformation_factory",
"use",

View File

@ -1,6 +1,9 @@
import functools
import itertools
from bonobo.config.services import use
from bonobo.util import get_name
def transformation_factory(f):
@functools.wraps(f)
@ -14,3 +17,11 @@ def transformation_factory(f):
_transformation_factory._partial = True
return _transformation_factory
class partial(functools.partial):
@property
def __name__(self):
return get_name(self.func)
def using(self, *service_names):
return use(*service_names)(self)

View File

@ -1,4 +1,4 @@
from collections import Iterable
from collections.abc import Iterable
from contextlib import contextmanager
from functools import partial
from inspect import signature

View File

@ -68,7 +68,7 @@ class Container(dict):
if len(args) == 1:
if len(kwargs):
raise ValueError(
'You can either use {} with one positional argument or with keyword arguments, not both.'.format(
"You can either use {} with one positional argument or with keyword arguments, not both.".format(
cls.__name__
)
)

View File

@ -127,8 +127,7 @@ class CsvWriter(FileWriter, CsvHandler):
)
context.writer(values)
else:
for arg in values:
context.writer(ensure_tuple(arg))
context.writer(ensure_tuple(values))
return NOT_MODIFIED

View File

@ -134,7 +134,7 @@ def BagType(typename, fields, *, verbose=False, module=None):
if type(name) is not str:
raise TypeError("Type names and field names must be strings, got {name!r}".format(name=name))
if not isinstance(name, 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))

View File

@ -6,7 +6,7 @@ import warnings
from contextlib import contextmanager
__escape_decoder = codecs.getdecoder("unicode_escape")
__posix_variable = re.compile("\$\{[^\}]*\}")
__posix_variable = re.compile(r"\$\{[^\}]*\}")
def parse_var(var):

View File

@ -24,7 +24,7 @@ def sweeten_errors():
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 = re.sub(r"^ \$ (.*)", term.lightblack(" $ ") + term.reset("\\1"), arg)
return (arg, length)

View File

@ -1,2 +1,2 @@
CLEAR_EOL = "\033[0K"
MOVE_CURSOR_UP = '\033[{}A'.format
MOVE_CURSOR_UP = "\033[{}A".format

View File

@ -12,13 +12,13 @@ def get_path():
def update_context(app, pagename, templatename, context, doctree):
context['alabaster_version'] = version.__version__
context["alabaster_version"] = version.__version__
def setup(app):
# add_html_theme is new in Sphinx 1.6+
if hasattr(app, 'add_html_theme'):
if hasattr(app, "add_html_theme"):
theme_path = os.path.abspath(os.path.dirname(__file__))
app.add_html_theme('alabaster', theme_path)
app.connect('html-page-context', update_context)
return {'version': version.__version__, 'parallel_read_safe': True}
app.add_html_theme("alabaster", theme_path)
app.connect("html-page-context", update_context)
return {"version": version.__version__, "parallel_read_safe": True}

View File

@ -1,2 +1,2 @@
__version_info__ = (0, 7, 10)
__version__ = '.'.join(map(str, __version_info__))
__version__ = ".".join(map(str, __version_info__))

View File

@ -7,43 +7,43 @@ import sys
import bonobo
sys.path.insert(0, os.path.abspath('..'))
sys.path.insert(0, os.path.abspath('_themes'))
sys.path.insert(0, os.path.abspath(".."))
sys.path.insert(0, os.path.abspath("_themes"))
# -- General configuration ------------------------------------------------
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.ifconfig',
'sphinx.ext.viewcode',
'sphinx.ext.graphviz',
'sphinx_sitemap',
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
"sphinx.ext.doctest",
"sphinx.ext.intersphinx",
"sphinx.ext.todo",
"sphinx.ext.coverage",
"sphinx.ext.ifconfig",
"sphinx.ext.viewcode",
"sphinx.ext.graphviz",
"sphinx_sitemap",
]
site_url = 'http://docs.bonobo-project.org/en/master/'
site_url = "http://docs.bonobo-project.org/en/master/"
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
templates_path = ["_templates"]
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
source_suffix = ".rst"
# The master toctree document.
master_doc = 'index'
master_doc = "index"
# General information about the project.
project = 'Bonobo'
author = 'Romain Dorgueil'
copyright = '2012-{}, {}'.format(datetime.datetime.now().year, author)
project = "Bonobo"
author = "Romain Dorgueil"
copyright = "2012-{}, {}".format(datetime.datetime.now().year, author)
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@ -60,14 +60,14 @@ language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
autoclass_content = 'both'
autodoc_member_order = 'groupwise'
autodoc_default_flags = ['members', 'undoc-members', 'show-inheritance']
autoclass_content = "both"
autodoc_member_order = "groupwise"
autodoc_default_flags = ["members", "undoc-members", "show-inheritance"]
add_module_names = False
pygments_style = 'sphinx'
pygments_style = "sphinx"
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
@ -77,56 +77,56 @@ todo_include_todos = True
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
html_theme = "alabaster"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
html_theme_options = {
'github_user': 'python-bonobo',
'github_repo': 'bonobo',
'github_button': 'true',
'github_banner': 'true',
'show_powered_by': 'false',
'show_related': 'true',
"github_user": "python-bonobo",
"github_repo": "bonobo",
"github_button": "true",
"github_banner": "true",
"show_powered_by": "false",
"show_related": "true",
}
html_sidebars = {
'index': [
'sidebarlogo.html',
'navigation.html',
'localtoc.html',
'sidebarintro.html',
'sourcelink.html',
'searchbox.html',
'sidebarinfos.html',
"index": [
"sidebarlogo.html",
"navigation.html",
"localtoc.html",
"sidebarintro.html",
"sourcelink.html",
"searchbox.html",
"sidebarinfos.html",
],
'**': [
'sidebarlogo.html',
'navigation.html',
'localtoc.html',
'relations.html',
'sourcelink.html',
'searchbox.html',
'sidebarinfos.html',
"**": [
"sidebarlogo.html",
"navigation.html",
"localtoc.html",
"relations.html",
"sourcelink.html",
"searchbox.html",
"sidebarinfos.html",
],
}
html_theme_path = ['_themes']
html_additional_pages = {'index': 'index.html'}
html_theme_path = ["_themes"]
html_additional_pages = {"index": "index.html"}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_static_path = ["_static"]
html_show_sphinx = False
graphviz_output_format = 'svg'
graphviz_output_format = "svg"
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'Bonobodoc'
htmlhelp_basename = "Bonobodoc"
# -- Options for LaTeX output ---------------------------------------------
@ -148,13 +148,13 @@ latex_elements = {
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [(master_doc, 'Bonobo.tex', 'Bonobo Documentation', 'Romain Dorgueil', 'manual')]
latex_documents = [(master_doc, "Bonobo.tex", "Bonobo Documentation", "Romain Dorgueil", "manual")]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [(master_doc, 'bonobo', 'Bonobo Documentation', [author], 1)]
man_pages = [(master_doc, "bonobo", "Bonobo Documentation", [author], 1)]
# -- Options for Texinfo output -------------------------------------------
@ -164,12 +164,12 @@ man_pages = [(master_doc, 'bonobo', 'Bonobo Documentation', [author], 1)]
texinfo_documents = [
(
master_doc,
'Bonobo',
'Bonobo Documentation',
"Bonobo",
"Bonobo Documentation",
author,
'Bonobo',
'One line description of project.',
'Miscellaneous',
"Bonobo",
"One line description of project.",
"Miscellaneous",
)
]
@ -191,14 +191,14 @@ epub_copyright = copyright
# epub_uid = ''
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
epub_exclude_files = ["search.html"]
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
'django': ('https://docs.djangoproject.com/en/2.0/', 'https://docs.djangoproject.com/en/2.0/_objects/'),
'fs': ('https://docs.pyfilesystem.org/en/latest/', None),
'python': ('https://docs.python.org/3', None),
'requests': ('http://docs.python-requests.org/en/master/', None),
"django": ("https://docs.djangoproject.com/en/2.0/", "https://docs.djangoproject.com/en/2.0/_objects/"),
"fs": ("https://docs.pyfilesystem.org/en/latest/", None),
"python": ("https://docs.python.org/3", None),
"requests": ("http://docs.python-requests.org/en/master/", None),
}
rst_epilog = """

View File

@ -89,7 +89,7 @@ of your python interpreter.
.. note:: Once again, we use `develop` here. New features should go to `develop`, while bugfixes can go to `master`.
If you can't find the "source" directory, try trunning this:
If you can't find the "source" directory, try running this:
.. code-block:: shell-session
@ -122,7 +122,7 @@ Preview versions
----------------
Sometimes, there are pre-versions available (before a major release, for example). By default, pip does not target
pre-versions to avoid accidental upgrades to a potentially instable software, but you can easily opt-in:
pre-versions to avoid accidental upgrades to a potentially unstable version, but you can easily opt-in:
.. code-block:: shell-session
@ -135,10 +135,10 @@ Supported platforms
Linux, OSX and other Unixes
---------------------------
Bonobo test suite runs continuously on Linux, and core developpers use both OSX and Linux machines. Also, there are jobs
Bonobo test suite runs continuously on Linux, and core developers use both OSX and Linux machines. Also, there are jobs
running on production linux machines everyday, so the support for those platforms should be quite excellent.
If you're using some esotheric UNIX machine, there can be surprises (although we're not aware, yet). We do not support
If you're using some esoteric UNIX machine, there can be surprises (although we're not aware, yet). We do not support
officially those platforms, but if you can actually fix the problems on those systems, we'll be glad to integrate
your patches (as long as it is tested, for both existing linux environments and your strange systems).

View File

@ -20,7 +20,6 @@ jinja2==2.10
markupsafe==1.0
more-itertools==4.3.0
packaging==17.1
pathlib2==2.3.2
pluggy==0.7.1
poyo==0.4.1
py==1.5.4

View File

@ -23,7 +23,6 @@ requests==2.19.1
semantic-version==2.6.0
six==1.11.0
stevedore==1.29.0
typing==3.6.4
unidecode==1.0.22
urllib3==1.23
websocket-client==0.48.0

View File

@ -21,7 +21,6 @@ requests==2.19.1
six==1.11.0
sqlalchemy==1.2.10
stevedore==1.29.0
typing==3.6.4
unidecode==1.0.22
urllib3==1.23
whistle==1.0.1

View File

@ -19,7 +19,6 @@ pytz==2018.5
requests==2.19.1
six==1.11.0
stevedore==1.29.0
typing==3.6.4
unidecode==1.0.22
urllib3==1.23
whistle==1.0.1

105
setup.py
View File

@ -2,10 +2,11 @@
# All changes will be overriden.
# Edit Projectfile and run “make update” (or “medikit update”) to regenerate.
from setuptools import setup, find_packages
from codecs import open
from os import path
from setuptools import find_packages, setup
here = path.abspath(path.dirname(__file__))
# Py3 compatibility hacks, borrowed from IPython.
@ -20,76 +21,88 @@ except NameError:
# Get the long description from the README file
try:
with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
with open(path.join(here, "README.rst"), encoding="utf-8") as f:
long_description = f.read()
except:
long_description = ''
long_description = ""
# Get the classifiers from the classifiers file
tolines = lambda c: list(filter(None, map(lambda s: s.strip(), c.split('\n'))))
tolines = lambda c: list(filter(None, map(lambda s: s.strip(), c.split("\n"))))
try:
with open(path.join(here, 'classifiers.txt'), encoding='utf-8') as f:
with open(path.join(here, "classifiers.txt"), encoding="utf-8") as f:
classifiers = tolines(f.read())
except:
classifiers = []
version_ns = {}
try:
execfile(path.join(here, 'bonobo/_version.py'), version_ns)
execfile(path.join(here, "bonobo/_version.py"), version_ns)
except EnvironmentError:
version = 'dev'
version = "dev"
else:
version = version_ns.get('__version__', 'dev')
version = version_ns.get("__version__", "dev")
setup(
author='Romain Dorgueil',
author_email='romain@dorgueil.net',
data_files=[('share/jupyter/nbextensions/bonobo-jupyter', [
'bonobo/contrib/jupyter/static/extension.js',
'bonobo/contrib/jupyter/static/index.js',
'bonobo/contrib/jupyter/static/index.js.map'
])],
description=(
'Bonobo, a simple, modern and atomic extract-transform-load toolkit for '
'python 3.5+.'),
license='Apache License, Version 2.0',
name='bonobo',
python_requires='>=3.5',
author="Romain Dorgueil",
author_email="romain@dorgueil.net",
data_files=[
(
"share/jupyter/nbextensions/bonobo-jupyter",
[
"bonobo/contrib/jupyter/static/extension.js",
"bonobo/contrib/jupyter/static/index.js",
"bonobo/contrib/jupyter/static/index.js.map",
],
)
],
description=("Bonobo, a simple, modern and atomic extract-transform-load toolkit for " "python 3.5+."),
license="Apache License, Version 2.0",
name="bonobo",
python_requires=">=3.5",
version=version,
long_description=long_description,
classifiers=classifiers,
packages=find_packages(exclude=['ez_setup', 'example', 'test']),
packages=find_packages(exclude=["ez_setup", "example", "test"]),
include_package_data=True,
install_requires=[
'cached-property (~= 1.4)', 'fs (~= 2.0)', 'graphviz (>= 0.8, < 0.9)',
'jinja2 (~= 2.9)', 'mondrian (~= 0.8)', 'packaging (~= 17.0)',
'psutil (~= 5.4)', 'python-slugify (~= 1.2.0)', 'requests (~= 2.0)',
'stevedore (~= 1.27)', 'whistle (~= 1.0)'
"cached-property (~= 1.4)",
"fs (~= 2.0)",
"graphviz (>= 0.8, < 0.9)",
"jinja2 (~= 2.9)",
"mondrian (~= 0.8)",
"packaging (~= 17.0)",
"psutil (~= 5.4)",
"python-slugify (~= 1.2.0)",
"requests (~= 2.0)",
"stevedore (~= 1.27)",
"whistle (~= 1.0)",
],
extras_require={
'dev': [
'cookiecutter (>= 1.5, < 1.6)', 'coverage (~= 4.4)',
'pytest (~= 3.4)', 'pytest-cov (~= 2.5)',
'pytest-timeout (>= 1, < 2)', 'sphinx (~= 1.7)',
'sphinx-sitemap (>= 0.2, < 0.3)'
"dev": [
"cookiecutter (>= 1.5, < 1.6)",
"coverage (~= 4.4)",
"pytest (~= 3.4)",
"pytest-cov (~= 2.5)",
"pytest-timeout (>= 1, < 2)",
"sphinx (~= 1.7)",
"sphinx-sitemap (>= 0.2, < 0.3)",
],
'docker': ['bonobo-docker (~= 0.6.0a1)'],
'jupyter': ['ipywidgets (~= 6.0)', 'jupyter (~= 1.0)'],
'sqlalchemy': ['bonobo-sqlalchemy (~= 0.6.0a1)']
"docker": ["bonobo-docker (~= 0.6.0a1)"],
"jupyter": ["ipywidgets (~= 6.0)", "jupyter (~= 1.0)"],
"sqlalchemy": ["bonobo-sqlalchemy (~= 0.6.0a1)"],
},
entry_points={
'bonobo.commands': [
'convert = bonobo.commands.convert:ConvertCommand',
'download = bonobo.commands.download:DownloadCommand',
'examples = bonobo.commands.examples:ExamplesCommand',
'init = bonobo.commands.init:InitCommand',
'inspect = bonobo.commands.inspect:InspectCommand',
'run = bonobo.commands.run:RunCommand',
'version = bonobo.commands.version:VersionCommand'
"bonobo.commands": [
"convert = bonobo.commands.convert:ConvertCommand",
"download = bonobo.commands.download:DownloadCommand",
"examples = bonobo.commands.examples:ExamplesCommand",
"init = bonobo.commands.init:InitCommand",
"inspect = bonobo.commands.inspect:InspectCommand",
"run = bonobo.commands.run:RunCommand",
"version = bonobo.commands.version:VersionCommand",
],
'console_scripts': ['bonobo = bonobo.commands:entrypoint']
"console_scripts": ["bonobo = bonobo.commands:entrypoint"],
},
url='https://www.bonobo-project.org/',
download_url='https://github.com/python-bonobo/bonobo/tarball/{version}'.
format(version=version),
url="https://www.bonobo-project.org/",
download_url="https://github.com/python-bonobo/bonobo/tarball/{version}".format(version=version),
)

View File

@ -131,20 +131,20 @@ def test_requires():
def test_constructor():
c1 = Container(foo='foo', bar='bar')
c1 = Container(foo="foo", bar="bar")
assert 2 == len(c1)
c2 = Container({'foo': 'foo', 'bar': 'bar'})
c2 = Container({"foo": "foo", "bar": "bar"})
assert 2 == len(c2)
assert c1['foo'] == c2['foo']
assert c1['bar'] == c2['bar']
assert c1["foo"] == c2["foo"]
assert c1["bar"] == c2["bar"]
with pytest.raises(ValueError):
Container({'bar': 'bar'}, foo='foo')
Container({"bar": "bar"}, foo="foo")
@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

View File

@ -63,9 +63,9 @@ class CsvReaderTest(Csv, ReaderTest, TestCase):
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()
@ -100,10 +100,10 @@ class CsvWriterTest(Csv, WriterTest, TestCase):
@incontext()
def test_nofields_multiple_args(self, context):
# multiple args are iterated onto and flattened in output
context.write_sync((L1, L2), (L3, L4))
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):
@ -111,18 +111,10 @@ class CsvWriterTest(Csv, WriterTest, TestCase):
with pytest.raises(TypeError):
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.stop()
assert self.readlines() == ("a,hey", "i,have,more,values", "c,see")
@incontext()
def test_nofields_empty_args(self, context):
# empty calls are ignored
context.write_sync(EMPTY, EMPTY, EMPTY)
context.stop()
assert self.readlines() == ()
assert self.readlines() == ('', '', '')